1 // SPDX-License-Identifier: GPL-2.0
3 * JZ47xx SoCs TCU clocks driver
4 * Copyright (C) 2019 Paul Cercueil <paul@crapouillou.net>
8 #include <linux/clk-provider.h>
9 #include <linux/clockchips.h>
10 #include <linux/mfd/ingenic-tcu.h>
11 #include <linux/mfd/syscon.h>
12 #include <linux/regmap.h>
13 #include <linux/slab.h>
14 #include <linux/syscore_ops.h>
16 #include <dt-bindings/clock/ingenic,tcu.h>
18 /* 8 channels max + watchdog + OST */
19 #define TCU_CLK_COUNT 10
22 #define pr_fmt(fmt) "ingenic-tcu-clk: " fmt
30 struct ingenic_soc_info
{
31 unsigned int num_channels
;
34 bool allow_missing_tcu_clk
;
37 struct ingenic_tcu_clk_info
{
38 struct clk_init_data init_data
;
43 struct ingenic_tcu_clk
{
46 struct ingenic_tcu
*tcu
;
47 const struct ingenic_tcu_clk_info
*info
;
51 const struct ingenic_soc_info
*soc_info
;
55 struct clk_hw_onecell_data
*clocks
;
58 static struct ingenic_tcu
*ingenic_tcu
;
60 static inline struct ingenic_tcu_clk
*to_tcu_clk(struct clk_hw
*hw
)
62 return container_of(hw
, struct ingenic_tcu_clk
, hw
);
65 static int ingenic_tcu_enable(struct clk_hw
*hw
)
67 struct ingenic_tcu_clk
*tcu_clk
= to_tcu_clk(hw
);
68 const struct ingenic_tcu_clk_info
*info
= tcu_clk
->info
;
69 struct ingenic_tcu
*tcu
= tcu_clk
->tcu
;
71 regmap_write(tcu
->map
, TCU_REG_TSCR
, BIT(info
->gate_bit
));
76 static void ingenic_tcu_disable(struct clk_hw
*hw
)
78 struct ingenic_tcu_clk
*tcu_clk
= to_tcu_clk(hw
);
79 const struct ingenic_tcu_clk_info
*info
= tcu_clk
->info
;
80 struct ingenic_tcu
*tcu
= tcu_clk
->tcu
;
82 regmap_write(tcu
->map
, TCU_REG_TSSR
, BIT(info
->gate_bit
));
85 static int ingenic_tcu_is_enabled(struct clk_hw
*hw
)
87 struct ingenic_tcu_clk
*tcu_clk
= to_tcu_clk(hw
);
88 const struct ingenic_tcu_clk_info
*info
= tcu_clk
->info
;
91 regmap_read(tcu_clk
->tcu
->map
, TCU_REG_TSR
, &value
);
93 return !(value
& BIT(info
->gate_bit
));
96 static bool ingenic_tcu_enable_regs(struct clk_hw
*hw
)
98 struct ingenic_tcu_clk
*tcu_clk
= to_tcu_clk(hw
);
99 const struct ingenic_tcu_clk_info
*info
= tcu_clk
->info
;
100 struct ingenic_tcu
*tcu
= tcu_clk
->tcu
;
101 bool enabled
= false;
104 * According to the programming manual, a timer channel's registers can
105 * only be accessed when the channel's stop bit is clear.
107 enabled
= !!ingenic_tcu_is_enabled(hw
);
108 regmap_write(tcu
->map
, TCU_REG_TSCR
, BIT(info
->gate_bit
));
113 static void ingenic_tcu_disable_regs(struct clk_hw
*hw
)
115 struct ingenic_tcu_clk
*tcu_clk
= to_tcu_clk(hw
);
116 const struct ingenic_tcu_clk_info
*info
= tcu_clk
->info
;
117 struct ingenic_tcu
*tcu
= tcu_clk
->tcu
;
119 regmap_write(tcu
->map
, TCU_REG_TSSR
, BIT(info
->gate_bit
));
122 static u8
ingenic_tcu_get_parent(struct clk_hw
*hw
)
124 struct ingenic_tcu_clk
*tcu_clk
= to_tcu_clk(hw
);
125 const struct ingenic_tcu_clk_info
*info
= tcu_clk
->info
;
126 unsigned int val
= 0;
129 ret
= regmap_read(tcu_clk
->tcu
->map
, info
->tcsr_reg
, &val
);
130 WARN_ONCE(ret
< 0, "Unable to read TCSR %d", tcu_clk
->idx
);
132 return ffs(val
& TCU_TCSR_PARENT_CLOCK_MASK
) - 1;
135 static int ingenic_tcu_set_parent(struct clk_hw
*hw
, u8 idx
)
137 struct ingenic_tcu_clk
*tcu_clk
= to_tcu_clk(hw
);
138 const struct ingenic_tcu_clk_info
*info
= tcu_clk
->info
;
142 was_enabled
= ingenic_tcu_enable_regs(hw
);
144 ret
= regmap_update_bits(tcu_clk
->tcu
->map
, info
->tcsr_reg
,
145 TCU_TCSR_PARENT_CLOCK_MASK
, BIT(idx
));
146 WARN_ONCE(ret
< 0, "Unable to update TCSR %d", tcu_clk
->idx
);
149 ingenic_tcu_disable_regs(hw
);
154 static unsigned long ingenic_tcu_recalc_rate(struct clk_hw
*hw
,
155 unsigned long parent_rate
)
157 struct ingenic_tcu_clk
*tcu_clk
= to_tcu_clk(hw
);
158 const struct ingenic_tcu_clk_info
*info
= tcu_clk
->info
;
159 unsigned int prescale
;
162 ret
= regmap_read(tcu_clk
->tcu
->map
, info
->tcsr_reg
, &prescale
);
163 WARN_ONCE(ret
< 0, "Unable to read TCSR %d", tcu_clk
->idx
);
165 prescale
= (prescale
& TCU_TCSR_PRESCALE_MASK
) >> TCU_TCSR_PRESCALE_LSB
;
167 return parent_rate
>> (prescale
* 2);
170 static u8
ingenic_tcu_get_prescale(unsigned long rate
, unsigned long req_rate
)
174 for (prescale
= 0; prescale
< 5; prescale
++)
175 if ((rate
>> (prescale
* 2)) <= req_rate
)
178 return 5; /* /1024 divider */
181 static int ingenic_tcu_determine_rate(struct clk_hw
*hw
,
182 struct clk_rate_request
*req
)
184 unsigned long rate
= req
->best_parent_rate
;
187 if (req
->rate
> rate
) {
192 prescale
= ingenic_tcu_get_prescale(rate
, req
->rate
);
194 req
->rate
= rate
>> (prescale
* 2);
198 static int ingenic_tcu_set_rate(struct clk_hw
*hw
, unsigned long req_rate
,
199 unsigned long parent_rate
)
201 struct ingenic_tcu_clk
*tcu_clk
= to_tcu_clk(hw
);
202 const struct ingenic_tcu_clk_info
*info
= tcu_clk
->info
;
203 u8 prescale
= ingenic_tcu_get_prescale(parent_rate
, req_rate
);
207 was_enabled
= ingenic_tcu_enable_regs(hw
);
209 ret
= regmap_update_bits(tcu_clk
->tcu
->map
, info
->tcsr_reg
,
210 TCU_TCSR_PRESCALE_MASK
,
211 prescale
<< TCU_TCSR_PRESCALE_LSB
);
212 WARN_ONCE(ret
< 0, "Unable to update TCSR %d", tcu_clk
->idx
);
215 ingenic_tcu_disable_regs(hw
);
220 static const struct clk_ops ingenic_tcu_clk_ops
= {
221 .get_parent
= ingenic_tcu_get_parent
,
222 .set_parent
= ingenic_tcu_set_parent
,
224 .recalc_rate
= ingenic_tcu_recalc_rate
,
225 .determine_rate
= ingenic_tcu_determine_rate
,
226 .set_rate
= ingenic_tcu_set_rate
,
228 .enable
= ingenic_tcu_enable
,
229 .disable
= ingenic_tcu_disable
,
230 .is_enabled
= ingenic_tcu_is_enabled
,
233 static const char * const ingenic_tcu_timer_parents
[] = {
234 [TCU_PARENT_PCLK
] = "pclk",
235 [TCU_PARENT_RTC
] = "rtc",
236 [TCU_PARENT_EXT
] = "ext",
239 #define DEF_TIMER(_name, _gate_bit, _tcsr) \
243 .parent_names = ingenic_tcu_timer_parents, \
244 .num_parents = ARRAY_SIZE(ingenic_tcu_timer_parents),\
245 .ops = &ingenic_tcu_clk_ops, \
246 .flags = CLK_SET_RATE_UNGATE, \
248 .gate_bit = _gate_bit, \
251 static const struct ingenic_tcu_clk_info ingenic_tcu_clk_info
[] = {
252 [TCU_CLK_TIMER0
] = DEF_TIMER("timer0", 0, TCU_REG_TCSRc(0)),
253 [TCU_CLK_TIMER1
] = DEF_TIMER("timer1", 1, TCU_REG_TCSRc(1)),
254 [TCU_CLK_TIMER2
] = DEF_TIMER("timer2", 2, TCU_REG_TCSRc(2)),
255 [TCU_CLK_TIMER3
] = DEF_TIMER("timer3", 3, TCU_REG_TCSRc(3)),
256 [TCU_CLK_TIMER4
] = DEF_TIMER("timer4", 4, TCU_REG_TCSRc(4)),
257 [TCU_CLK_TIMER5
] = DEF_TIMER("timer5", 5, TCU_REG_TCSRc(5)),
258 [TCU_CLK_TIMER6
] = DEF_TIMER("timer6", 6, TCU_REG_TCSRc(6)),
259 [TCU_CLK_TIMER7
] = DEF_TIMER("timer7", 7, TCU_REG_TCSRc(7)),
262 static const struct ingenic_tcu_clk_info ingenic_tcu_watchdog_clk_info
=
263 DEF_TIMER("wdt", 16, TCU_REG_WDT_TCSR
);
264 static const struct ingenic_tcu_clk_info ingenic_tcu_ost_clk_info
=
265 DEF_TIMER("ost", 15, TCU_REG_OST_TCSR
);
268 static int __init
ingenic_tcu_register_clock(struct ingenic_tcu
*tcu
,
269 unsigned int idx
, enum tcu_clk_parent parent
,
270 const struct ingenic_tcu_clk_info
*info
,
271 struct clk_hw_onecell_data
*clocks
)
273 struct ingenic_tcu_clk
*tcu_clk
;
276 tcu_clk
= kzalloc(sizeof(*tcu_clk
), GFP_KERNEL
);
280 tcu_clk
->hw
.init
= &info
->init_data
;
282 tcu_clk
->info
= info
;
285 /* Reset channel and clock divider, set default parent */
286 ingenic_tcu_enable_regs(&tcu_clk
->hw
);
287 regmap_update_bits(tcu
->map
, info
->tcsr_reg
, 0xffff, BIT(parent
));
288 ingenic_tcu_disable_regs(&tcu_clk
->hw
);
290 err
= clk_hw_register(NULL
, &tcu_clk
->hw
);
296 clocks
->hws
[idx
] = &tcu_clk
->hw
;
301 static const struct ingenic_soc_info jz4740_soc_info
= {
307 static const struct ingenic_soc_info jz4725b_soc_info
= {
313 static const struct ingenic_soc_info jz4770_soc_info
= {
316 .has_tcu_clk
= false,
319 static const struct ingenic_soc_info x1000_soc_info
= {
321 .has_ost
= false, /* X1000 has OST, but it not belong TCU */
323 .allow_missing_tcu_clk
= true,
326 static const struct of_device_id __maybe_unused ingenic_tcu_of_match
[] __initconst
= {
327 { .compatible
= "ingenic,jz4740-tcu", .data
= &jz4740_soc_info
, },
328 { .compatible
= "ingenic,jz4725b-tcu", .data
= &jz4725b_soc_info
, },
329 { .compatible
= "ingenic,jz4760-tcu", .data
= &jz4770_soc_info
, },
330 { .compatible
= "ingenic,jz4770-tcu", .data
= &jz4770_soc_info
, },
331 { .compatible
= "ingenic,x1000-tcu", .data
= &x1000_soc_info
, },
335 static int __init
ingenic_tcu_probe(struct device_node
*np
)
337 const struct of_device_id
*id
= of_match_node(ingenic_tcu_of_match
, np
);
338 struct ingenic_tcu
*tcu
;
343 map
= device_node_to_regmap(np
);
347 tcu
= kzalloc(sizeof(*tcu
), GFP_KERNEL
);
352 tcu
->soc_info
= id
->data
;
354 if (tcu
->soc_info
->has_tcu_clk
) {
355 tcu
->clk
= of_clk_get_by_name(np
, "tcu");
356 if (IS_ERR(tcu
->clk
)) {
357 ret
= PTR_ERR(tcu
->clk
);
360 * Old device trees for some SoCs did not include the
361 * TCU clock because this driver (incorrectly) didn't
362 * use it. In this case we complain loudly and attempt
363 * to continue without the clock, which might work if
364 * booting with workarounds like "clk_ignore_unused".
366 if (tcu
->soc_info
->allow_missing_tcu_clk
&& ret
== -EINVAL
) {
367 pr_warn("TCU clock missing from device tree, please update your device tree\n");
370 pr_crit("Cannot get TCU clock from device tree\n");
374 ret
= clk_prepare_enable(tcu
->clk
);
376 pr_crit("Unable to enable TCU clock\n");
382 tcu
->clocks
= kzalloc(struct_size(tcu
->clocks
, hws
, TCU_CLK_COUNT
),
386 goto err_clk_disable
;
389 tcu
->clocks
->num
= TCU_CLK_COUNT
;
391 for (i
= 0; i
< tcu
->soc_info
->num_channels
; i
++) {
392 ret
= ingenic_tcu_register_clock(tcu
, i
, TCU_PARENT_EXT
,
393 &ingenic_tcu_clk_info
[i
],
396 pr_crit("cannot register clock %d\n", i
);
397 goto err_unregister_timer_clocks
;
402 * We set EXT as the default parent clock for all the TCU clocks
403 * except for the watchdog one, where we set the RTC clock as the
404 * parent. Since the EXT and PCLK are much faster than the RTC clock,
405 * the watchdog would kick after a maximum time of 5s, and we might
406 * want a slower kicking time.
408 ret
= ingenic_tcu_register_clock(tcu
, TCU_CLK_WDT
, TCU_PARENT_RTC
,
409 &ingenic_tcu_watchdog_clk_info
,
412 pr_crit("cannot register watchdog clock\n");
413 goto err_unregister_timer_clocks
;
416 if (tcu
->soc_info
->has_ost
) {
417 ret
= ingenic_tcu_register_clock(tcu
, TCU_CLK_OST
,
419 &ingenic_tcu_ost_clk_info
,
422 pr_crit("cannot register ost clock\n");
423 goto err_unregister_watchdog_clock
;
427 ret
= of_clk_add_hw_provider(np
, of_clk_hw_onecell_get
, tcu
->clocks
);
429 pr_crit("cannot add OF clock provider\n");
430 goto err_unregister_ost_clock
;
437 err_unregister_ost_clock
:
438 if (tcu
->soc_info
->has_ost
)
439 clk_hw_unregister(tcu
->clocks
->hws
[i
+ 1]);
440 err_unregister_watchdog_clock
:
441 clk_hw_unregister(tcu
->clocks
->hws
[i
]);
442 err_unregister_timer_clocks
:
443 for (i
= 0; i
< tcu
->clocks
->num
; i
++)
444 if (tcu
->clocks
->hws
[i
])
445 clk_hw_unregister(tcu
->clocks
->hws
[i
]);
449 clk_disable_unprepare(tcu
->clk
);
458 static int __maybe_unused
tcu_pm_suspend(void)
460 struct ingenic_tcu
*tcu
= ingenic_tcu
;
463 clk_disable(tcu
->clk
);
468 static void __maybe_unused
tcu_pm_resume(void)
470 struct ingenic_tcu
*tcu
= ingenic_tcu
;
473 clk_enable(tcu
->clk
);
476 static struct syscore_ops __maybe_unused tcu_pm_ops
= {
477 .suspend
= tcu_pm_suspend
,
478 .resume
= tcu_pm_resume
,
481 static void __init
ingenic_tcu_init(struct device_node
*np
)
483 int ret
= ingenic_tcu_probe(np
);
486 pr_crit("Failed to initialize TCU clocks: %d\n", ret
);
488 if (IS_ENABLED(CONFIG_PM_SLEEP
))
489 register_syscore_ops(&tcu_pm_ops
);
492 CLK_OF_DECLARE_DRIVER(jz4740_cgu
, "ingenic,jz4740-tcu", ingenic_tcu_init
);
493 CLK_OF_DECLARE_DRIVER(jz4725b_cgu
, "ingenic,jz4725b-tcu", ingenic_tcu_init
);
494 CLK_OF_DECLARE_DRIVER(jz4760_cgu
, "ingenic,jz4760-tcu", ingenic_tcu_init
);
495 CLK_OF_DECLARE_DRIVER(jz4770_cgu
, "ingenic,jz4770-tcu", ingenic_tcu_init
);
496 CLK_OF_DECLARE_DRIVER(x1000_cgu
, "ingenic,x1000-tcu", ingenic_tcu_init
);