1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 */
5
6 /*
7 * CMN PLL block expects the reference clock from on-board Wi-Fi block,
8 * and supplies fixed rate clocks as output to the networking hardware
9 * blocks and to GCC. The networking related blocks include PPE (packet
10 * process engine), the externally connected PHY or switch devices, and
11 * the PCS.
12 *
13 * On the IPQ9574 SoC, there are three clocks with 50 MHZ and one clock
14 * with 25 MHZ which are output from the CMN PLL to Ethernet PHY (or switch),
15 * and one clock with 353 MHZ to PPE. The other fixed rate output clocks
16 * are supplied to GCC (24 MHZ as XO and 32 KHZ as sleep clock), and to PCS
17 * with 31.25 MHZ.
18 *
19 * +---------+
20 * | GCC |
21 * +--+---+--+
22 * AHB CLK| |SYS CLK
23 * V V
24 * +-------+---+------+
25 * | +-------------> eth0-50mhz
26 * REF CLK | IPQ9574 |
27 * -------->+ +-------------> eth1-50mhz
28 * | CMN PLL block |
29 * | +-------------> eth2-50mhz
30 * | |
31 * +----+----+----+---+-------------> eth-25mhz
32 * | | |
33 * V V V
34 * GCC PCS NSS/PPE
35 */
36
37 #include <linux/bitfield.h>
38 #include <linux/clk-provider.h>
39 #include <linux/delay.h>
40 #include <linux/err.h>
41 #include <linux/mod_devicetable.h>
42 #include <linux/module.h>
43 #include <linux/platform_device.h>
44 #include <linux/pm_clock.h>
45 #include <linux/pm_runtime.h>
46 #include <linux/regmap.h>
47
48 #include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
49
50 #define CMN_PLL_REFCLK_SRC_SELECTION 0x28
51 #define CMN_PLL_REFCLK_SRC_DIV GENMASK(9, 8)
52
53 #define CMN_PLL_LOCKED 0x64
54 #define CMN_PLL_CLKS_LOCKED BIT(8)
55
56 #define CMN_PLL_POWER_ON_AND_RESET 0x780
57 #define CMN_ANA_EN_SW_RSTN BIT(6)
58
59 #define CMN_PLL_REFCLK_CONFIG 0x784
60 #define CMN_PLL_REFCLK_EXTERNAL BIT(9)
61 #define CMN_PLL_REFCLK_DIV GENMASK(8, 4)
62 #define CMN_PLL_REFCLK_INDEX GENMASK(3, 0)
63
64 #define CMN_PLL_CTRL 0x78c
65 #define CMN_PLL_CTRL_LOCK_DETECT_EN BIT(15)
66
67 #define CMN_PLL_DIVIDER_CTRL 0x794
68 #define CMN_PLL_DIVIDER_CTRL_FACTOR GENMASK(9, 0)
69
70 /**
71 * struct cmn_pll_fixed_output_clk - CMN PLL output clocks information
72 * @id: Clock specifier to be supplied
73 * @name: Clock name to be registered
74 * @rate: Clock rate
75 */
76 struct cmn_pll_fixed_output_clk {
77 unsigned int id;
78 const char *name;
79 unsigned long rate;
80 };
81
82 /**
83 * struct clk_cmn_pll - CMN PLL hardware specific data
84 * @regmap: hardware regmap.
85 * @hw: handle between common and hardware-specific interfaces
86 */
87 struct clk_cmn_pll {
88 struct regmap *regmap;
89 struct clk_hw hw;
90 };
91
92 #define CLK_PLL_OUTPUT(_id, _name, _rate) { \
93 .id = _id, \
94 .name = _name, \
95 .rate = _rate, \
96 }
97
98 #define to_clk_cmn_pll(_hw) container_of(_hw, struct clk_cmn_pll, hw)
99
100 static const struct regmap_config ipq_cmn_pll_regmap_config = {
101 .reg_bits = 32,
102 .reg_stride = 4,
103 .val_bits = 32,
104 .max_register = 0x7fc,
105 .fast_io = true,
106 };
107
108 static const struct cmn_pll_fixed_output_clk ipq9574_output_clks[] = {
109 CLK_PLL_OUTPUT(XO_24MHZ_CLK, "xo-24mhz", 24000000UL),
110 CLK_PLL_OUTPUT(SLEEP_32KHZ_CLK, "sleep-32khz", 32000UL),
111 CLK_PLL_OUTPUT(PCS_31P25MHZ_CLK, "pcs-31p25mhz", 31250000UL),
112 CLK_PLL_OUTPUT(NSS_1200MHZ_CLK, "nss-1200mhz", 1200000000UL),
113 CLK_PLL_OUTPUT(PPE_353MHZ_CLK, "ppe-353mhz", 353000000UL),
114 CLK_PLL_OUTPUT(ETH0_50MHZ_CLK, "eth0-50mhz", 50000000UL),
115 CLK_PLL_OUTPUT(ETH1_50MHZ_CLK, "eth1-50mhz", 50000000UL),
116 CLK_PLL_OUTPUT(ETH2_50MHZ_CLK, "eth2-50mhz", 50000000UL),
117 CLK_PLL_OUTPUT(ETH_25MHZ_CLK, "eth-25mhz", 25000000UL),
118 };
119
120 /*
121 * CMN PLL has the single parent clock, which supports the several
122 * possible parent clock rates, each parent clock rate is reflected
123 * by the specific reference index value in the hardware.
124 */
ipq_cmn_pll_find_freq_index(unsigned long parent_rate)125 static int ipq_cmn_pll_find_freq_index(unsigned long parent_rate)
126 {
127 int index = -EINVAL;
128
129 switch (parent_rate) {
130 case 25000000:
131 index = 3;
132 break;
133 case 31250000:
134 index = 4;
135 break;
136 case 40000000:
137 index = 6;
138 break;
139 case 48000000:
140 case 96000000:
141 /*
142 * Parent clock rate 48 MHZ and 96 MHZ take the same value
143 * of reference clock index. 96 MHZ needs the source clock
144 * divider to be programmed as 2.
145 */
146 index = 7;
147 break;
148 case 50000000:
149 index = 8;
150 break;
151 default:
152 break;
153 }
154
155 return index;
156 }
157
clk_cmn_pll_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)158 static unsigned long clk_cmn_pll_recalc_rate(struct clk_hw *hw,
159 unsigned long parent_rate)
160 {
161 struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
162 u32 val, factor;
163
164 /*
165 * The value of CMN_PLL_DIVIDER_CTRL_FACTOR is automatically adjusted
166 * by HW according to the parent clock rate.
167 */
168 regmap_read(cmn_pll->regmap, CMN_PLL_DIVIDER_CTRL, &val);
169 factor = FIELD_GET(CMN_PLL_DIVIDER_CTRL_FACTOR, val);
170
171 return parent_rate * 2 * factor;
172 }
173
clk_cmn_pll_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)174 static int clk_cmn_pll_determine_rate(struct clk_hw *hw,
175 struct clk_rate_request *req)
176 {
177 int ret;
178
179 /* Validate the rate of the single parent clock. */
180 ret = ipq_cmn_pll_find_freq_index(req->best_parent_rate);
181
182 return ret < 0 ? ret : 0;
183 }
184
185 /*
186 * This function is used to initialize the CMN PLL to enable the fixed
187 * rate output clocks. It is expected to be configured once.
188 */
clk_cmn_pll_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)189 static int clk_cmn_pll_set_rate(struct clk_hw *hw, unsigned long rate,
190 unsigned long parent_rate)
191 {
192 struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
193 int ret, index;
194 u32 val;
195
196 /*
197 * Configure the reference input clock selection as per the given
198 * parent clock. The output clock rates are always of fixed value.
199 */
200 index = ipq_cmn_pll_find_freq_index(parent_rate);
201 if (index < 0)
202 return index;
203
204 ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
205 CMN_PLL_REFCLK_INDEX,
206 FIELD_PREP(CMN_PLL_REFCLK_INDEX, index));
207 if (ret)
208 return ret;
209
210 /*
211 * Update the source clock rate selection and source clock
212 * divider as 2 when the parent clock rate is 96 MHZ.
213 */
214 if (parent_rate == 96000000) {
215 ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
216 CMN_PLL_REFCLK_DIV,
217 FIELD_PREP(CMN_PLL_REFCLK_DIV, 2));
218 if (ret)
219 return ret;
220
221 ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_SRC_SELECTION,
222 CMN_PLL_REFCLK_SRC_DIV,
223 FIELD_PREP(CMN_PLL_REFCLK_SRC_DIV, 0));
224 if (ret)
225 return ret;
226 }
227
228 /* Enable PLL locked detect. */
229 ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_CTRL,
230 CMN_PLL_CTRL_LOCK_DETECT_EN);
231 if (ret)
232 return ret;
233
234 /*
235 * Reset the CMN PLL block to ensure the updated configurations
236 * take effect.
237 */
238 ret = regmap_clear_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
239 CMN_ANA_EN_SW_RSTN);
240 if (ret)
241 return ret;
242
243 usleep_range(1000, 1200);
244 ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
245 CMN_ANA_EN_SW_RSTN);
246 if (ret)
247 return ret;
248
249 /* Stability check of CMN PLL output clocks. */
250 return regmap_read_poll_timeout(cmn_pll->regmap, CMN_PLL_LOCKED, val,
251 (val & CMN_PLL_CLKS_LOCKED),
252 100, 100 * USEC_PER_MSEC);
253 }
254
255 static const struct clk_ops clk_cmn_pll_ops = {
256 .recalc_rate = clk_cmn_pll_recalc_rate,
257 .determine_rate = clk_cmn_pll_determine_rate,
258 .set_rate = clk_cmn_pll_set_rate,
259 };
260
ipq_cmn_pll_clk_hw_register(struct platform_device * pdev)261 static struct clk_hw *ipq_cmn_pll_clk_hw_register(struct platform_device *pdev)
262 {
263 struct clk_parent_data pdata = { .index = 0 };
264 struct device *dev = &pdev->dev;
265 struct clk_init_data init = {};
266 struct clk_cmn_pll *cmn_pll;
267 struct regmap *regmap;
268 void __iomem *base;
269 int ret;
270
271 base = devm_platform_ioremap_resource(pdev, 0);
272 if (IS_ERR(base))
273 return ERR_CAST(base);
274
275 regmap = devm_regmap_init_mmio(dev, base, &ipq_cmn_pll_regmap_config);
276 if (IS_ERR(regmap))
277 return ERR_CAST(regmap);
278
279 cmn_pll = devm_kzalloc(dev, sizeof(*cmn_pll), GFP_KERNEL);
280 if (!cmn_pll)
281 return ERR_PTR(-ENOMEM);
282
283 init.name = "cmn_pll";
284 init.parent_data = &pdata;
285 init.num_parents = 1;
286 init.ops = &clk_cmn_pll_ops;
287
288 cmn_pll->hw.init = &init;
289 cmn_pll->regmap = regmap;
290
291 ret = devm_clk_hw_register(dev, &cmn_pll->hw);
292 if (ret)
293 return ERR_PTR(ret);
294
295 return &cmn_pll->hw;
296 }
297
ipq_cmn_pll_register_clks(struct platform_device * pdev)298 static int ipq_cmn_pll_register_clks(struct platform_device *pdev)
299 {
300 const struct cmn_pll_fixed_output_clk *fixed_clk;
301 struct clk_hw_onecell_data *hw_data;
302 struct device *dev = &pdev->dev;
303 struct clk_hw *cmn_pll_hw;
304 unsigned int num_clks;
305 struct clk_hw *hw;
306 int ret, i;
307
308 fixed_clk = ipq9574_output_clks;
309 num_clks = ARRAY_SIZE(ipq9574_output_clks);
310
311 hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks + 1),
312 GFP_KERNEL);
313 if (!hw_data)
314 return -ENOMEM;
315
316 /*
317 * Register the CMN PLL clock, which is the parent clock of
318 * the fixed rate output clocks.
319 */
320 cmn_pll_hw = ipq_cmn_pll_clk_hw_register(pdev);
321 if (IS_ERR(cmn_pll_hw))
322 return PTR_ERR(cmn_pll_hw);
323
324 /* Register the fixed rate output clocks. */
325 for (i = 0; i < num_clks; i++) {
326 hw = clk_hw_register_fixed_rate_parent_hw(dev, fixed_clk[i].name,
327 cmn_pll_hw, 0,
328 fixed_clk[i].rate);
329 if (IS_ERR(hw)) {
330 ret = PTR_ERR(hw);
331 goto unregister_fixed_clk;
332 }
333
334 hw_data->hws[fixed_clk[i].id] = hw;
335 }
336
337 /*
338 * Provide the CMN PLL clock. The clock rate of CMN PLL
339 * is configured to 12 GHZ by DT property assigned-clock-rates-u64.
340 */
341 hw_data->hws[CMN_PLL_CLK] = cmn_pll_hw;
342 hw_data->num = num_clks + 1;
343
344 ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data);
345 if (ret)
346 goto unregister_fixed_clk;
347
348 platform_set_drvdata(pdev, hw_data);
349
350 return 0;
351
352 unregister_fixed_clk:
353 while (i > 0)
354 clk_hw_unregister(hw_data->hws[fixed_clk[--i].id]);
355
356 return ret;
357 }
358
ipq_cmn_pll_clk_probe(struct platform_device * pdev)359 static int ipq_cmn_pll_clk_probe(struct platform_device *pdev)
360 {
361 struct device *dev = &pdev->dev;
362 int ret;
363
364 ret = devm_pm_runtime_enable(dev);
365 if (ret)
366 return ret;
367
368 ret = devm_pm_clk_create(dev);
369 if (ret)
370 return ret;
371
372 /*
373 * To access the CMN PLL registers, the GCC AHB & SYS clocks
374 * of CMN PLL block need to be enabled.
375 */
376 ret = pm_clk_add(dev, "ahb");
377 if (ret)
378 return dev_err_probe(dev, ret, "Fail to add AHB clock\n");
379
380 ret = pm_clk_add(dev, "sys");
381 if (ret)
382 return dev_err_probe(dev, ret, "Fail to add SYS clock\n");
383
384 ret = pm_runtime_resume_and_get(dev);
385 if (ret)
386 return ret;
387
388 /* Register CMN PLL clock and fixed rate output clocks. */
389 ret = ipq_cmn_pll_register_clks(pdev);
390 pm_runtime_put(dev);
391 if (ret)
392 return dev_err_probe(dev, ret,
393 "Fail to register CMN PLL clocks\n");
394
395 return 0;
396 }
397
ipq_cmn_pll_clk_remove(struct platform_device * pdev)398 static void ipq_cmn_pll_clk_remove(struct platform_device *pdev)
399 {
400 struct clk_hw_onecell_data *hw_data = platform_get_drvdata(pdev);
401 int i;
402
403 /*
404 * The clock with index CMN_PLL_CLK is unregistered by
405 * device management.
406 */
407 for (i = 0; i < hw_data->num; i++) {
408 if (i != CMN_PLL_CLK)
409 clk_hw_unregister(hw_data->hws[i]);
410 }
411 }
412
413 static const struct dev_pm_ops ipq_cmn_pll_pm_ops = {
414 SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
415 };
416
417 static const struct of_device_id ipq_cmn_pll_clk_ids[] = {
418 { .compatible = "qcom,ipq9574-cmn-pll", },
419 { }
420 };
421 MODULE_DEVICE_TABLE(of, ipq_cmn_pll_clk_ids);
422
423 static struct platform_driver ipq_cmn_pll_clk_driver = {
424 .probe = ipq_cmn_pll_clk_probe,
425 .remove = ipq_cmn_pll_clk_remove,
426 .driver = {
427 .name = "ipq_cmn_pll",
428 .of_match_table = ipq_cmn_pll_clk_ids,
429 .pm = &ipq_cmn_pll_pm_ops,
430 },
431 };
432 module_platform_driver(ipq_cmn_pll_clk_driver);
433
434 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ CMN PLL Driver");
435 MODULE_LICENSE("GPL");
436