1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Clock driver for TI Davinci PSC controllers |
4 | * |
5 | * Copyright (C) 2017 David Lechner <david@lechnology.com> |
6 | * |
7 | * Based on: drivers/clk/keystone/gate.c |
8 | * Copyright (C) 2013 Texas Instruments. |
9 | * Murali Karicheri <m-karicheri2@ti.com> |
10 | * Santosh Shilimkar <santosh.shilimkar@ti.com> |
11 | * |
12 | * And: arch/arm/mach-davinci/psc.c |
13 | * Copyright (C) 2006 Texas Instruments. |
14 | */ |
15 | |
16 | #include <linux/clk-provider.h> |
17 | #include <linux/clk.h> |
18 | #include <linux/clk/davinci.h> |
19 | #include <linux/clkdev.h> |
20 | #include <linux/err.h> |
21 | #include <linux/of.h> |
22 | #include <linux/platform_device.h> |
23 | #include <linux/property.h> |
24 | #include <linux/pm_clock.h> |
25 | #include <linux/pm_domain.h> |
26 | #include <linux/regmap.h> |
27 | #include <linux/reset-controller.h> |
28 | #include <linux/slab.h> |
29 | #include <linux/types.h> |
30 | |
31 | #include "psc.h" |
32 | |
33 | /* PSC register offsets */ |
34 | #define EPCPR 0x070 |
35 | #define PTCMD 0x120 |
36 | #define PTSTAT 0x128 |
37 | #define PDSTAT(n) (0x200 + 4 * (n)) |
38 | #define PDCTL(n) (0x300 + 4 * (n)) |
39 | #define MDSTAT(n) (0x800 + 4 * (n)) |
40 | #define MDCTL(n) (0xa00 + 4 * (n)) |
41 | |
42 | /* PSC module states */ |
43 | enum davinci_lpsc_state { |
44 | LPSC_STATE_SWRSTDISABLE = 0, |
45 | LPSC_STATE_SYNCRST = 1, |
46 | LPSC_STATE_DISABLE = 2, |
47 | LPSC_STATE_ENABLE = 3, |
48 | }; |
49 | |
50 | #define MDSTAT_STATE_MASK GENMASK(5, 0) |
51 | #define MDSTAT_MCKOUT BIT(12) |
52 | #define PDSTAT_STATE_MASK GENMASK(4, 0) |
53 | #define MDCTL_FORCE BIT(31) |
54 | #define MDCTL_LRESET BIT(8) |
55 | #define PDCTL_EPCGOOD BIT(8) |
56 | #define PDCTL_NEXT BIT(0) |
57 | |
58 | struct davinci_psc_data { |
59 | struct clk_onecell_data clk_data; |
60 | struct genpd_onecell_data pm_data; |
61 | struct reset_controller_dev rcdev; |
62 | }; |
63 | |
64 | /** |
65 | * struct davinci_lpsc_clk - LPSC clock structure |
66 | * @dev: the device that provides this LPSC or NULL |
67 | * @hw: clk_hw for the LPSC |
68 | * @pm_domain: power domain for the LPSC |
69 | * @genpd_clk: clock reference owned by @pm_domain |
70 | * @regmap: PSC MMIO region |
71 | * @md: Module domain (LPSC module id) |
72 | * @pd: Power domain |
73 | * @flags: LPSC_* quirk flags |
74 | */ |
75 | struct davinci_lpsc_clk { |
76 | struct device *dev; |
77 | struct clk_hw hw; |
78 | struct generic_pm_domain pm_domain; |
79 | struct clk *genpd_clk; |
80 | struct regmap *regmap; |
81 | u32 md; |
82 | u32 pd; |
83 | u32 flags; |
84 | }; |
85 | |
86 | #define to_davinci_psc_data(x) container_of(x, struct davinci_psc_data, x) |
87 | #define to_davinci_lpsc_clk(x) container_of(x, struct davinci_lpsc_clk, x) |
88 | |
89 | /** |
90 | * best_dev_name - get the "best" device name. |
91 | * @dev: the device |
92 | * |
93 | * Returns the device tree compatible name if the device has a DT node, |
94 | * otherwise return the device name. This is mainly needed because clkdev |
95 | * lookups are limited to 20 chars for dev_id and when using device tree, |
96 | * dev_name(dev) is much longer than that. |
97 | */ |
98 | static inline const char *best_dev_name(struct device *dev) |
99 | { |
100 | const char *compatible; |
101 | |
102 | if (!of_property_read_string(np: dev->of_node, propname: "compatible" , out_string: &compatible)) |
103 | return compatible; |
104 | |
105 | return dev_name(dev); |
106 | } |
107 | |
108 | static void davinci_lpsc_config(struct davinci_lpsc_clk *lpsc, |
109 | enum davinci_lpsc_state next_state) |
110 | { |
111 | u32 epcpr, pdstat, mdstat, ptstat; |
112 | |
113 | regmap_write_bits(map: lpsc->regmap, MDCTL(lpsc->md), MDSTAT_STATE_MASK, |
114 | val: next_state); |
115 | |
116 | if (lpsc->flags & LPSC_FORCE) |
117 | regmap_write_bits(map: lpsc->regmap, MDCTL(lpsc->md), MDCTL_FORCE, |
118 | MDCTL_FORCE); |
119 | |
120 | regmap_read(map: lpsc->regmap, PDSTAT(lpsc->pd), val: &pdstat); |
121 | if ((pdstat & PDSTAT_STATE_MASK) == 0) { |
122 | regmap_write_bits(map: lpsc->regmap, PDCTL(lpsc->pd), PDCTL_NEXT, |
123 | PDCTL_NEXT); |
124 | |
125 | regmap_write(map: lpsc->regmap, PTCMD, BIT(lpsc->pd)); |
126 | |
127 | regmap_read_poll_timeout(lpsc->regmap, EPCPR, epcpr, |
128 | epcpr & BIT(lpsc->pd), 0, 0); |
129 | |
130 | regmap_write_bits(map: lpsc->regmap, PDCTL(lpsc->pd), PDCTL_EPCGOOD, |
131 | PDCTL_EPCGOOD); |
132 | } else { |
133 | regmap_write(map: lpsc->regmap, PTCMD, BIT(lpsc->pd)); |
134 | } |
135 | |
136 | regmap_read_poll_timeout(lpsc->regmap, PTSTAT, ptstat, |
137 | !(ptstat & BIT(lpsc->pd)), 0, 0); |
138 | |
139 | regmap_read_poll_timeout(lpsc->regmap, MDSTAT(lpsc->md), mdstat, |
140 | (mdstat & MDSTAT_STATE_MASK) == next_state, |
141 | 0, 0); |
142 | } |
143 | |
144 | static int davinci_lpsc_clk_enable(struct clk_hw *hw) |
145 | { |
146 | struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw); |
147 | |
148 | davinci_lpsc_config(lpsc, next_state: LPSC_STATE_ENABLE); |
149 | |
150 | return 0; |
151 | } |
152 | |
153 | static void davinci_lpsc_clk_disable(struct clk_hw *hw) |
154 | { |
155 | struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw); |
156 | |
157 | davinci_lpsc_config(lpsc, next_state: LPSC_STATE_DISABLE); |
158 | } |
159 | |
160 | static int davinci_lpsc_clk_is_enabled(struct clk_hw *hw) |
161 | { |
162 | struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw); |
163 | u32 mdstat; |
164 | |
165 | regmap_read(map: lpsc->regmap, MDSTAT(lpsc->md), val: &mdstat); |
166 | |
167 | return (mdstat & MDSTAT_MCKOUT) ? 1 : 0; |
168 | } |
169 | |
170 | static const struct clk_ops davinci_lpsc_clk_ops = { |
171 | .enable = davinci_lpsc_clk_enable, |
172 | .disable = davinci_lpsc_clk_disable, |
173 | .is_enabled = davinci_lpsc_clk_is_enabled, |
174 | }; |
175 | |
176 | static int davinci_psc_genpd_attach_dev(struct generic_pm_domain *pm_domain, |
177 | struct device *dev) |
178 | { |
179 | struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(pm_domain); |
180 | struct clk *clk; |
181 | int ret; |
182 | |
183 | /* |
184 | * pm_clk_remove_clk() will call clk_put(), so we have to use clk_get() |
185 | * to get the clock instead of using lpsc->hw.clk directly. |
186 | */ |
187 | clk = clk_get_sys(dev_id: best_dev_name(dev: lpsc->dev), con_id: clk_hw_get_name(hw: &lpsc->hw)); |
188 | if (IS_ERR(ptr: clk)) |
189 | return (PTR_ERR(ptr: clk)); |
190 | |
191 | ret = pm_clk_create(dev); |
192 | if (ret < 0) |
193 | goto fail_clk_put; |
194 | |
195 | ret = pm_clk_add_clk(dev, clk); |
196 | if (ret < 0) |
197 | goto fail_pm_clk_destroy; |
198 | |
199 | lpsc->genpd_clk = clk; |
200 | |
201 | return 0; |
202 | |
203 | fail_pm_clk_destroy: |
204 | pm_clk_destroy(dev); |
205 | fail_clk_put: |
206 | clk_put(clk); |
207 | |
208 | return ret; |
209 | } |
210 | |
211 | static void davinci_psc_genpd_detach_dev(struct generic_pm_domain *pm_domain, |
212 | struct device *dev) |
213 | { |
214 | struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(pm_domain); |
215 | |
216 | pm_clk_remove_clk(dev, clk: lpsc->genpd_clk); |
217 | pm_clk_destroy(dev); |
218 | |
219 | lpsc->genpd_clk = NULL; |
220 | } |
221 | |
222 | /** |
223 | * davinci_lpsc_clk_register - register LPSC clock |
224 | * @dev: the clocks's device or NULL |
225 | * @name: name of this clock |
226 | * @parent_name: name of clock's parent |
227 | * @regmap: PSC MMIO region |
228 | * @md: local PSC number |
229 | * @pd: power domain |
230 | * @flags: LPSC_* flags |
231 | */ |
232 | static struct davinci_lpsc_clk * |
233 | davinci_lpsc_clk_register(struct device *dev, const char *name, |
234 | const char *parent_name, struct regmap *regmap, |
235 | u32 md, u32 pd, u32 flags) |
236 | { |
237 | struct clk_init_data init; |
238 | struct davinci_lpsc_clk *lpsc; |
239 | int ret; |
240 | bool is_on; |
241 | |
242 | lpsc = kzalloc(size: sizeof(*lpsc), GFP_KERNEL); |
243 | if (!lpsc) |
244 | return ERR_PTR(error: -ENOMEM); |
245 | |
246 | init.name = name; |
247 | init.ops = &davinci_lpsc_clk_ops; |
248 | init.parent_names = (parent_name ? &parent_name : NULL); |
249 | init.num_parents = (parent_name ? 1 : 0); |
250 | init.flags = 0; |
251 | |
252 | if (flags & LPSC_ALWAYS_ENABLED) |
253 | init.flags |= CLK_IS_CRITICAL; |
254 | |
255 | if (flags & LPSC_SET_RATE_PARENT) |
256 | init.flags |= CLK_SET_RATE_PARENT; |
257 | |
258 | lpsc->dev = dev; |
259 | lpsc->regmap = regmap; |
260 | lpsc->hw.init = &init; |
261 | lpsc->md = md; |
262 | lpsc->pd = pd; |
263 | lpsc->flags = flags; |
264 | |
265 | ret = clk_hw_register(dev, hw: &lpsc->hw); |
266 | if (ret < 0) { |
267 | kfree(objp: lpsc); |
268 | return ERR_PTR(error: ret); |
269 | } |
270 | |
271 | /* for now, genpd is only registered when using device-tree */ |
272 | if (!dev || !dev->of_node) |
273 | return lpsc; |
274 | |
275 | /* genpd attach needs a way to look up this clock */ |
276 | ret = clk_hw_register_clkdev(&lpsc->hw, name, best_dev_name(dev)); |
277 | |
278 | lpsc->pm_domain.name = devm_kasprintf(dev, GFP_KERNEL, fmt: "%s: %s" , |
279 | best_dev_name(dev), name); |
280 | lpsc->pm_domain.attach_dev = davinci_psc_genpd_attach_dev; |
281 | lpsc->pm_domain.detach_dev = davinci_psc_genpd_detach_dev; |
282 | lpsc->pm_domain.flags = GENPD_FLAG_PM_CLK; |
283 | |
284 | is_on = davinci_lpsc_clk_is_enabled(hw: &lpsc->hw); |
285 | pm_genpd_init(genpd: &lpsc->pm_domain, NULL, is_off: is_on); |
286 | |
287 | return lpsc; |
288 | } |
289 | |
290 | static int davinci_lpsc_clk_reset(struct clk *clk, bool reset) |
291 | { |
292 | struct clk_hw *hw = __clk_get_hw(clk); |
293 | struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw); |
294 | u32 mdctl; |
295 | |
296 | if (IS_ERR_OR_NULL(ptr: lpsc)) |
297 | return -EINVAL; |
298 | |
299 | mdctl = reset ? 0 : MDCTL_LRESET; |
300 | regmap_write_bits(map: lpsc->regmap, MDCTL(lpsc->md), MDCTL_LRESET, val: mdctl); |
301 | |
302 | return 0; |
303 | } |
304 | |
305 | static int davinci_psc_reset_assert(struct reset_controller_dev *rcdev, |
306 | unsigned long id) |
307 | { |
308 | struct davinci_psc_data *psc = to_davinci_psc_data(rcdev); |
309 | struct clk *clk = psc->clk_data.clks[id]; |
310 | |
311 | return davinci_lpsc_clk_reset(clk, reset: true); |
312 | } |
313 | |
314 | static int davinci_psc_reset_deassert(struct reset_controller_dev *rcdev, |
315 | unsigned long id) |
316 | { |
317 | struct davinci_psc_data *psc = to_davinci_psc_data(rcdev); |
318 | struct clk *clk = psc->clk_data.clks[id]; |
319 | |
320 | return davinci_lpsc_clk_reset(clk, reset: false); |
321 | } |
322 | |
323 | static const struct reset_control_ops davinci_psc_reset_ops = { |
324 | .assert = davinci_psc_reset_assert, |
325 | .deassert = davinci_psc_reset_deassert, |
326 | }; |
327 | |
328 | static int davinci_psc_reset_of_xlate(struct reset_controller_dev *rcdev, |
329 | const struct of_phandle_args *reset_spec) |
330 | { |
331 | struct of_phandle_args clkspec = *reset_spec; /* discard const qualifier */ |
332 | struct clk *clk; |
333 | struct clk_hw *hw; |
334 | struct davinci_lpsc_clk *lpsc; |
335 | |
336 | /* the clock node is the same as the reset node */ |
337 | clk = of_clk_get_from_provider(clkspec: &clkspec); |
338 | if (IS_ERR(ptr: clk)) |
339 | return PTR_ERR(ptr: clk); |
340 | |
341 | hw = __clk_get_hw(clk); |
342 | lpsc = to_davinci_lpsc_clk(hw); |
343 | clk_put(clk); |
344 | |
345 | /* not all modules support local reset */ |
346 | if (!(lpsc->flags & LPSC_LOCAL_RESET)) |
347 | return -EINVAL; |
348 | |
349 | return lpsc->md; |
350 | } |
351 | |
352 | static const struct regmap_config davinci_psc_regmap_config = { |
353 | .reg_bits = 32, |
354 | .reg_stride = 4, |
355 | .val_bits = 32, |
356 | }; |
357 | |
358 | static struct davinci_psc_data * |
359 | __davinci_psc_register_clocks(struct device *dev, |
360 | const struct davinci_lpsc_clk_info *info, |
361 | int num_clks, |
362 | void __iomem *base) |
363 | { |
364 | struct davinci_psc_data *psc; |
365 | struct clk **clks; |
366 | struct generic_pm_domain **pm_domains; |
367 | struct regmap *regmap; |
368 | int i, ret; |
369 | |
370 | psc = kzalloc(size: sizeof(*psc), GFP_KERNEL); |
371 | if (!psc) |
372 | return ERR_PTR(error: -ENOMEM); |
373 | |
374 | clks = kmalloc_array(n: num_clks, size: sizeof(*clks), GFP_KERNEL); |
375 | if (!clks) { |
376 | ret = -ENOMEM; |
377 | goto err_free_psc; |
378 | } |
379 | |
380 | psc->clk_data.clks = clks; |
381 | psc->clk_data.clk_num = num_clks; |
382 | |
383 | /* |
384 | * init array with error so that of_clk_src_onecell_get() doesn't |
385 | * return NULL for gaps in the sparse array |
386 | */ |
387 | for (i = 0; i < num_clks; i++) |
388 | clks[i] = ERR_PTR(error: -ENOENT); |
389 | |
390 | pm_domains = kcalloc(n: num_clks, size: sizeof(*pm_domains), GFP_KERNEL); |
391 | if (!pm_domains) { |
392 | ret = -ENOMEM; |
393 | goto err_free_clks; |
394 | } |
395 | |
396 | psc->pm_data.domains = pm_domains; |
397 | psc->pm_data.num_domains = num_clks; |
398 | |
399 | regmap = regmap_init_mmio(dev, base, &davinci_psc_regmap_config); |
400 | if (IS_ERR(ptr: regmap)) { |
401 | ret = PTR_ERR(ptr: regmap); |
402 | goto err_free_pm_domains; |
403 | } |
404 | |
405 | for (; info->name; info++) { |
406 | struct davinci_lpsc_clk *lpsc; |
407 | |
408 | lpsc = davinci_lpsc_clk_register(dev, name: info->name, parent_name: info->parent, |
409 | regmap, md: info->md, pd: info->pd, |
410 | flags: info->flags); |
411 | if (IS_ERR(ptr: lpsc)) { |
412 | dev_warn(dev, "Failed to register %s (%ld)\n" , |
413 | info->name, PTR_ERR(lpsc)); |
414 | continue; |
415 | } |
416 | |
417 | clks[info->md] = lpsc->hw.clk; |
418 | pm_domains[info->md] = &lpsc->pm_domain; |
419 | } |
420 | |
421 | /* |
422 | * for now, a reset controller is only registered when there is a device |
423 | * to associate it with. |
424 | */ |
425 | if (!dev) |
426 | return psc; |
427 | |
428 | psc->rcdev.ops = &davinci_psc_reset_ops; |
429 | psc->rcdev.owner = THIS_MODULE; |
430 | psc->rcdev.dev = dev; |
431 | psc->rcdev.of_node = dev->of_node; |
432 | psc->rcdev.of_reset_n_cells = 1; |
433 | psc->rcdev.of_xlate = davinci_psc_reset_of_xlate; |
434 | psc->rcdev.nr_resets = num_clks; |
435 | |
436 | ret = devm_reset_controller_register(dev, rcdev: &psc->rcdev); |
437 | if (ret < 0) |
438 | dev_warn(dev, "Failed to register reset controller (%d)\n" , ret); |
439 | |
440 | return psc; |
441 | |
442 | err_free_pm_domains: |
443 | kfree(objp: pm_domains); |
444 | err_free_clks: |
445 | kfree(objp: clks); |
446 | err_free_psc: |
447 | kfree(objp: psc); |
448 | |
449 | return ERR_PTR(error: ret); |
450 | } |
451 | |
452 | int davinci_psc_register_clocks(struct device *dev, |
453 | const struct davinci_lpsc_clk_info *info, |
454 | u8 num_clks, |
455 | void __iomem *base) |
456 | { |
457 | struct davinci_psc_data *psc; |
458 | |
459 | psc = __davinci_psc_register_clocks(dev, info, num_clks, base); |
460 | if (IS_ERR(ptr: psc)) |
461 | return PTR_ERR(ptr: psc); |
462 | |
463 | for (; info->name; info++) { |
464 | const struct davinci_lpsc_clkdev_info *cdevs = info->cdevs; |
465 | struct clk *clk = psc->clk_data.clks[info->md]; |
466 | |
467 | if (!cdevs || IS_ERR_OR_NULL(ptr: clk)) |
468 | continue; |
469 | |
470 | for (; cdevs->con_id || cdevs->dev_id; cdevs++) |
471 | clk_register_clkdev(clk, cdevs->con_id, cdevs->dev_id); |
472 | } |
473 | |
474 | return 0; |
475 | } |
476 | |
477 | int of_davinci_psc_clk_init(struct device *dev, |
478 | const struct davinci_lpsc_clk_info *info, |
479 | u8 num_clks, |
480 | void __iomem *base) |
481 | { |
482 | struct device_node *node = dev->of_node; |
483 | struct davinci_psc_data *psc; |
484 | |
485 | psc = __davinci_psc_register_clocks(dev, info, num_clks, base); |
486 | if (IS_ERR(ptr: psc)) |
487 | return PTR_ERR(ptr: psc); |
488 | |
489 | of_genpd_add_provider_onecell(np: node, data: &psc->pm_data); |
490 | |
491 | of_clk_add_provider(np: node, clk_src_get: of_clk_src_onecell_get, data: &psc->clk_data); |
492 | |
493 | return 0; |
494 | } |
495 | |
496 | static const struct of_device_id davinci_psc_of_match[] = { |
497 | #ifdef CONFIG_ARCH_DAVINCI_DA850 |
498 | { .compatible = "ti,da850-psc0" , .data = &of_da850_psc0_init_data }, |
499 | { .compatible = "ti,da850-psc1" , .data = &of_da850_psc1_init_data }, |
500 | #endif |
501 | { } |
502 | }; |
503 | |
504 | static const struct platform_device_id davinci_psc_id_table[] = { |
505 | #ifdef CONFIG_ARCH_DAVINCI_DA830 |
506 | { .name = "da830-psc0" , .driver_data = (kernel_ulong_t)&da830_psc0_init_data }, |
507 | { .name = "da830-psc1" , .driver_data = (kernel_ulong_t)&da830_psc1_init_data }, |
508 | #endif |
509 | #ifdef CONFIG_ARCH_DAVINCI_DA850 |
510 | { .name = "da850-psc0" , .driver_data = (kernel_ulong_t)&da850_psc0_init_data }, |
511 | { .name = "da850-psc1" , .driver_data = (kernel_ulong_t)&da850_psc1_init_data }, |
512 | #endif |
513 | { } |
514 | }; |
515 | |
516 | static int davinci_psc_probe(struct platform_device *pdev) |
517 | { |
518 | struct device *dev = &pdev->dev; |
519 | const struct davinci_psc_init_data *init_data = NULL; |
520 | void __iomem *base; |
521 | int ret; |
522 | |
523 | init_data = device_get_match_data(dev); |
524 | if (!init_data && pdev->id_entry) |
525 | init_data = (void *)pdev->id_entry->driver_data; |
526 | |
527 | if (!init_data) { |
528 | dev_err(dev, "unable to find driver init data\n" ); |
529 | return -EINVAL; |
530 | } |
531 | |
532 | base = devm_platform_ioremap_resource(pdev, index: 0); |
533 | if (IS_ERR(ptr: base)) |
534 | return PTR_ERR(ptr: base); |
535 | |
536 | ret = devm_clk_bulk_get(dev, num_clks: init_data->num_parent_clks, |
537 | clks: init_data->parent_clks); |
538 | if (ret < 0) |
539 | return ret; |
540 | |
541 | return init_data->psc_init(dev, base); |
542 | } |
543 | |
544 | static struct platform_driver davinci_psc_driver = { |
545 | .probe = davinci_psc_probe, |
546 | .driver = { |
547 | .name = "davinci-psc-clk" , |
548 | .of_match_table = davinci_psc_of_match, |
549 | }, |
550 | .id_table = davinci_psc_id_table, |
551 | }; |
552 | |
553 | static int __init davinci_psc_driver_init(void) |
554 | { |
555 | return platform_driver_register(&davinci_psc_driver); |
556 | } |
557 | |
558 | /* has to be postcore_initcall because davinci_gpio depend on PSC clocks */ |
559 | postcore_initcall(davinci_psc_driver_init); |
560 | |