Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

clk: qcom: apss-ipq5424: Add ipq5424 apss clock controller

CPU on Qualcomm ipq5424 is clocked by huayra PLL with RCG support.
Add support for the APSS PLL, RCG and clock enable for ipq5424.
The PLL, RCG register space are clubbed. Hence adding new APSS driver
for both PLL and RCG/CBC control. Also the L3 cache has a separate pll
and needs to be scaled along with the CPU and is modeled as an ICC clock.

[ Removed clock notifier, moved L3 pll to icc-clk, used existing
alpha pll structure ]

Co-developed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20250811090954.2854440-3-quic_varada@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Sricharan Ramabadhran and committed by
Bjorn Andersson
5bf83c54 fa5b839b

+275
+9
drivers/clk/qcom/Kconfig
··· 187 187 Say Y if you want to support CPU frequency scaling on ipq based 188 188 devices. 189 189 190 + config IPQ_APSS_5424 191 + tristate "IPQ APSS Clock Controller" 192 + select IPQ_APSS_PLL 193 + default y if IPQ_GCC_5424 194 + help 195 + Support for APSS Clock controller on Qualcom IPQ5424 platform. 196 + Say Y if you want to support CPU frequency scaling on ipq based 197 + devices. 198 + 190 199 config IPQ_APSS_6018 191 200 tristate "IPQ APSS Clock Controller" 192 201 select IPQ_APSS_PLL
+1
drivers/clk/qcom/Makefile
··· 29 29 obj-$(CONFIG_CLK_X1P42100_GPUCC) += gpucc-x1p42100.o 30 30 obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o 31 31 obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o 32 + obj-$(CONFIG_IPQ_APSS_5424) += apss-ipq5424.o 32 33 obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o 33 34 obj-$(CONFIG_IPQ_CMN_PLL) += ipq-cmn-pll.o 34 35 obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
+265
drivers/clk/qcom/apss-ipq5424.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. 5 + */ 6 + 7 + #include <linux/clk.h> 8 + #include <linux/clk-provider.h> 9 + #include <linux/err.h> 10 + #include <linux/interconnect-provider.h> 11 + #include <linux/kernel.h> 12 + #include <linux/module.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/regmap.h> 15 + 16 + #include <dt-bindings/arm/qcom,ids.h> 17 + #include <dt-bindings/clock/qcom,apss-ipq.h> 18 + #include <dt-bindings/interconnect/qcom,ipq5424.h> 19 + 20 + #include "clk-alpha-pll.h" 21 + #include "clk-branch.h" 22 + #include "clk-rcg.h" 23 + #include "clk-regmap.h" 24 + #include "common.h" 25 + 26 + enum { 27 + DT_XO, 28 + DT_CLK_REF, 29 + }; 30 + 31 + enum { 32 + P_XO, 33 + P_GPLL0, 34 + P_APSS_PLL_EARLY, 35 + P_L3_PLL, 36 + }; 37 + 38 + struct apss_clk { 39 + struct notifier_block cpu_clk_notifier; 40 + struct clk_hw *hw; 41 + struct device *dev; 42 + struct clk *l3_clk; 43 + }; 44 + 45 + static const struct alpha_pll_config apss_pll_config = { 46 + .l = 0x3b, 47 + .config_ctl_val = 0x08200920, 48 + .config_ctl_hi_val = 0x05008001, 49 + .config_ctl_hi1_val = 0x04000000, 50 + .user_ctl_val = 0xf, 51 + }; 52 + 53 + static struct clk_alpha_pll ipq5424_apss_pll = { 54 + .offset = 0x0, 55 + .config = &apss_pll_config, 56 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290], 57 + .flags = SUPPORTS_DYNAMIC_UPDATE, 58 + .clkr = { 59 + .enable_reg = 0x0, 60 + .enable_mask = BIT(0), 61 + .hw.init = &(struct clk_init_data){ 62 + .name = "apss_pll", 63 + .parent_data = &(const struct clk_parent_data) { 64 + .index = DT_XO, 65 + }, 66 + .num_parents = 1, 67 + .ops = &clk_alpha_pll_huayra_ops, 68 + }, 69 + }, 70 + }; 71 + 72 + static const struct clk_parent_data parents_apss_silver_clk_src[] = { 73 + { .index = DT_XO }, 74 + { .index = DT_CLK_REF }, 75 + { .hw = &ipq5424_apss_pll.clkr.hw }, 76 + }; 77 + 78 + static const struct parent_map parents_apss_silver_clk_src_map[] = { 79 + { P_XO, 0 }, 80 + { P_GPLL0, 4 }, 81 + { P_APSS_PLL_EARLY, 5 }, 82 + }; 83 + 84 + static const struct freq_tbl ftbl_apss_clk_src[] = { 85 + F(816000000, P_APSS_PLL_EARLY, 1, 0, 0), 86 + F(1416000000, P_APSS_PLL_EARLY, 1, 0, 0), 87 + F(1800000000, P_APSS_PLL_EARLY, 1, 0, 0), 88 + { } 89 + }; 90 + 91 + static struct clk_rcg2 apss_silver_clk_src = { 92 + .cmd_rcgr = 0x0080, 93 + .freq_tbl = ftbl_apss_clk_src, 94 + .hid_width = 5, 95 + .parent_map = parents_apss_silver_clk_src_map, 96 + .clkr.hw.init = &(struct clk_init_data) { 97 + .name = "apss_silver_clk_src", 98 + .parent_data = parents_apss_silver_clk_src, 99 + .num_parents = ARRAY_SIZE(parents_apss_silver_clk_src), 100 + .ops = &clk_rcg2_ops, 101 + .flags = CLK_SET_RATE_PARENT, 102 + }, 103 + }; 104 + 105 + static struct clk_branch apss_silver_core_clk = { 106 + .halt_reg = 0x008c, 107 + .clkr = { 108 + .enable_reg = 0x008c, 109 + .enable_mask = BIT(0), 110 + .hw.init = &(struct clk_init_data) { 111 + .name = "apss_silver_core_clk", 112 + .parent_hws = (const struct clk_hw *[]) { 113 + &apss_silver_clk_src.clkr.hw 114 + }, 115 + .num_parents = 1, 116 + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 117 + .ops = &clk_branch2_ops, 118 + }, 119 + }, 120 + }; 121 + 122 + static const struct alpha_pll_config l3_pll_config = { 123 + .l = 0x29, 124 + .config_ctl_val = 0x08200920, 125 + .config_ctl_hi_val = 0x05008001, 126 + .config_ctl_hi1_val = 0x04000000, 127 + .user_ctl_val = 0xf, 128 + }; 129 + 130 + static struct clk_alpha_pll ipq5424_l3_pll = { 131 + .offset = 0x10000, 132 + .config = &l3_pll_config, 133 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290], 134 + .flags = SUPPORTS_DYNAMIC_UPDATE, 135 + .clkr = { 136 + .enable_reg = 0x0, 137 + .enable_mask = BIT(0), 138 + .hw.init = &(struct clk_init_data) { 139 + .name = "l3_pll", 140 + .parent_data = &(const struct clk_parent_data) { 141 + .index = DT_XO, 142 + }, 143 + .num_parents = 1, 144 + .ops = &clk_alpha_pll_huayra_ops, 145 + }, 146 + }, 147 + }; 148 + 149 + static const struct clk_parent_data parents_l3_clk_src[] = { 150 + { .index = DT_XO }, 151 + { .index = DT_CLK_REF }, 152 + { .hw = &ipq5424_l3_pll.clkr.hw }, 153 + }; 154 + 155 + static const struct parent_map parents_l3_clk_src_map[] = { 156 + { P_XO, 0 }, 157 + { P_GPLL0, 4 }, 158 + { P_L3_PLL, 5 }, 159 + }; 160 + 161 + static const struct freq_tbl ftbl_l3_clk_src[] = { 162 + F(816000000, P_L3_PLL, 1, 0, 0), 163 + F(984000000, P_L3_PLL, 1, 0, 0), 164 + F(1272000000, P_L3_PLL, 1, 0, 0), 165 + { } 166 + }; 167 + 168 + static struct clk_rcg2 l3_clk_src = { 169 + .cmd_rcgr = 0x10080, 170 + .freq_tbl = ftbl_l3_clk_src, 171 + .hid_width = 5, 172 + .parent_map = parents_l3_clk_src_map, 173 + .clkr.hw.init = &(struct clk_init_data) { 174 + .name = "l3_clk_src", 175 + .parent_data = parents_l3_clk_src, 176 + .num_parents = ARRAY_SIZE(parents_l3_clk_src), 177 + .ops = &clk_rcg2_ops, 178 + .flags = CLK_SET_RATE_PARENT, 179 + }, 180 + }; 181 + 182 + static struct clk_branch l3_core_clk = { 183 + .halt_reg = 0x1008c, 184 + .clkr = { 185 + .enable_reg = 0x1008c, 186 + .enable_mask = BIT(0), 187 + .hw.init = &(struct clk_init_data) { 188 + .name = "l3_clk", 189 + .parent_hws = (const struct clk_hw *[]) { 190 + &l3_clk_src.clkr.hw 191 + }, 192 + .num_parents = 1, 193 + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 194 + .ops = &clk_branch2_ops, 195 + }, 196 + }, 197 + }; 198 + 199 + static const struct regmap_config apss_ipq5424_regmap_config = { 200 + .reg_bits = 32, 201 + .reg_stride = 4, 202 + .val_bits = 32, 203 + .max_register = 0x20000, 204 + .fast_io = true, 205 + }; 206 + 207 + static struct clk_regmap *apss_ipq5424_clks[] = { 208 + [APSS_PLL_EARLY] = &ipq5424_apss_pll.clkr, 209 + [APSS_SILVER_CLK_SRC] = &apss_silver_clk_src.clkr, 210 + [APSS_SILVER_CORE_CLK] = &apss_silver_core_clk.clkr, 211 + [L3_PLL] = &ipq5424_l3_pll.clkr, 212 + [L3_CLK_SRC] = &l3_clk_src.clkr, 213 + [L3_CORE_CLK] = &l3_core_clk.clkr, 214 + }; 215 + 216 + static struct clk_alpha_pll *ipa5424_apss_plls[] = { 217 + &ipq5424_l3_pll, 218 + &ipq5424_apss_pll, 219 + }; 220 + 221 + static struct qcom_cc_driver_data ipa5424_apss_driver_data = { 222 + .alpha_plls = ipa5424_apss_plls, 223 + .num_alpha_plls = ARRAY_SIZE(ipa5424_apss_plls), 224 + }; 225 + 226 + #define IPQ_APPS_PLL_ID (5424 * 3) /* some unique value */ 227 + 228 + static const struct qcom_icc_hws_data icc_ipq5424_cpu_l3[] = { 229 + { MASTER_CPU, SLAVE_L3, L3_CORE_CLK }, 230 + }; 231 + 232 + static const struct qcom_cc_desc apss_ipq5424_desc = { 233 + .config = &apss_ipq5424_regmap_config, 234 + .clks = apss_ipq5424_clks, 235 + .num_clks = ARRAY_SIZE(apss_ipq5424_clks), 236 + .icc_hws = icc_ipq5424_cpu_l3, 237 + .num_icc_hws = ARRAY_SIZE(icc_ipq5424_cpu_l3), 238 + .icc_first_node_id = IPQ_APPS_PLL_ID, 239 + .driver_data = &ipa5424_apss_driver_data, 240 + }; 241 + 242 + static int apss_ipq5424_probe(struct platform_device *pdev) 243 + { 244 + return qcom_cc_probe(pdev, &apss_ipq5424_desc); 245 + } 246 + 247 + static const struct of_device_id apss_ipq5424_match_table[] = { 248 + { .compatible = "qcom,ipq5424-apss-clk" }, 249 + { } 250 + }; 251 + MODULE_DEVICE_TABLE(of, apss_ipq5424_match_table); 252 + 253 + static struct platform_driver apss_ipq5424_driver = { 254 + .probe = apss_ipq5424_probe, 255 + .driver = { 256 + .name = "apss-ipq5424-clk", 257 + .of_match_table = apss_ipq5424_match_table, 258 + .sync_state = icc_sync_state, 259 + }, 260 + }; 261 + 262 + module_platform_driver(apss_ipq5424_driver); 263 + 264 + MODULE_DESCRIPTION("QCOM APSS IPQ5424 CLK Driver"); 265 + MODULE_LICENSE("GPL");