1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for Renesas Versaclock 3
5 * Copyright (C) 2023 Renesas Electronics Corp.
8 #include <linux/clk-provider.h>
10 #include <linux/limits.h>
11 #include <linux/module.h>
12 #include <linux/regmap.h>
14 #define NUM_CONFIG_REGISTERS 37
16 #define VC3_GENERAL_CTR 0x0
17 #define VC3_GENERAL_CTR_DIV1_SRC_SEL BIT(3)
18 #define VC3_GENERAL_CTR_PLL3_REFIN_SEL BIT(2)
20 #define VC3_PLL3_M_DIVIDER 0x3
21 #define VC3_PLL3_M_DIV1 BIT(7)
22 #define VC3_PLL3_M_DIV2 BIT(6)
23 #define VC3_PLL3_M_DIV(n) ((n) & GENMASK(5, 0))
25 #define VC3_PLL3_N_DIVIDER 0x4
26 #define VC3_PLL3_LOOP_FILTER_N_DIV_MSB 0x5
28 #define VC3_PLL3_CHARGE_PUMP_CTRL 0x6
29 #define VC3_PLL3_CHARGE_PUMP_CTRL_OUTDIV3_SRC_SEL BIT(7)
31 #define VC3_PLL1_CTRL_OUTDIV5 0x7
32 #define VC3_PLL1_CTRL_OUTDIV5_PLL1_MDIV_DOUBLER BIT(7)
34 #define VC3_PLL1_M_DIVIDER 0x8
35 #define VC3_PLL1_M_DIV1 BIT(7)
36 #define VC3_PLL1_M_DIV2 BIT(6)
37 #define VC3_PLL1_M_DIV(n) ((n) & GENMASK(5, 0))
39 #define VC3_PLL1_VCO_N_DIVIDER 0x9
40 #define VC3_PLL1_LOOP_FILTER_N_DIV_MSB 0x0a
42 #define VC3_OUT_DIV1_DIV2_CTRL 0xf
44 #define VC3_PLL2_FB_INT_DIV_MSB 0x10
45 #define VC3_PLL2_FB_INT_DIV_LSB 0x11
46 #define VC3_PLL2_FB_FRC_DIV_MSB 0x12
47 #define VC3_PLL2_FB_FRC_DIV_LSB 0x13
49 #define VC3_PLL2_M_DIVIDER 0x1a
50 #define VC3_PLL2_MDIV_DOUBLER BIT(7)
51 #define VC3_PLL2_M_DIV1 BIT(6)
52 #define VC3_PLL2_M_DIV2 BIT(5)
53 #define VC3_PLL2_M_DIV(n) ((n) & GENMASK(4, 0))
55 #define VC3_OUT_DIV3_DIV4_CTRL 0x1b
57 #define VC3_PLL_OP_CTRL 0x1c
58 #define VC3_PLL_OP_CTRL_PLL2_REFIN_SEL 6
60 #define VC3_OUTPUT_CTR 0x1d
61 #define VC3_OUTPUT_CTR_DIV4_SRC_SEL BIT(3)
63 #define VC3_SE2_CTRL_REG0 0x1f
64 #define VC3_SE2_CTRL_REG0_SE2_CLK_SEL BIT(6)
66 #define VC3_SE3_DIFF1_CTRL_REG 0x21
67 #define VC3_SE3_DIFF1_CTRL_REG_SE3_CLK_SEL BIT(6)
69 #define VC3_DIFF1_CTRL_REG 0x22
70 #define VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL BIT(7)
72 #define VC3_DIFF2_CTRL_REG 0x23
73 #define VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL BIT(7)
75 #define VC3_SE1_DIV4_CTRL 0x24
76 #define VC3_SE1_DIV4_CTRL_SE1_CLK_SEL BIT(3)
78 #define VC3_PLL1_VCO_MIN 300000000UL
79 #define VC3_PLL1_VCO_MAX 600000000UL
81 #define VC3_PLL2_VCO_MIN 400000000UL
82 #define VC3_PLL2_VCO_MAX 1200000000UL
84 #define VC3_PLL3_VCO_MIN 300000000UL
85 #define VC3_PLL3_VCO_MAX 800000000UL
87 #define VC3_2_POW_16 (U16_MAX + 1)
88 #define VC3_DIV_MASK(width) ((1 << (width)) - 1)
138 struct vc3_clk_data
{
143 struct vc3_pfd_data
{
150 struct vc3_pll_data
{
154 unsigned long vco_min
;
155 unsigned long vco_max
;
158 struct vc3_div_data
{
160 const struct clk_div_table
*table
;
168 struct regmap
*regmap
;
175 static const struct clk_div_table div1_divs
[] = {
176 { .val
= 0, .div
= 1, }, { .val
= 1, .div
= 4, },
177 { .val
= 2, .div
= 5, }, { .val
= 3, .div
= 6, },
178 { .val
= 4, .div
= 2, }, { .val
= 5, .div
= 8, },
179 { .val
= 6, .div
= 10, }, { .val
= 7, .div
= 12, },
180 { .val
= 8, .div
= 4, }, { .val
= 9, .div
= 16, },
181 { .val
= 10, .div
= 20, }, { .val
= 11, .div
= 24, },
182 { .val
= 12, .div
= 8, }, { .val
= 13, .div
= 32, },
183 { .val
= 14, .div
= 40, }, { .val
= 15, .div
= 48, },
187 static const struct clk_div_table div245_divs
[] = {
188 { .val
= 0, .div
= 1, }, { .val
= 1, .div
= 3, },
189 { .val
= 2, .div
= 5, }, { .val
= 3, .div
= 10, },
190 { .val
= 4, .div
= 2, }, { .val
= 5, .div
= 6, },
191 { .val
= 6, .div
= 10, }, { .val
= 7, .div
= 20, },
192 { .val
= 8, .div
= 4, }, { .val
= 9, .div
= 12, },
193 { .val
= 10, .div
= 20, }, { .val
= 11, .div
= 40, },
194 { .val
= 12, .div
= 5, }, { .val
= 13, .div
= 15, },
195 { .val
= 14, .div
= 25, }, { .val
= 15, .div
= 50, },
199 static const struct clk_div_table div3_divs
[] = {
200 { .val
= 0, .div
= 1, }, { .val
= 1, .div
= 3, },
201 { .val
= 2, .div
= 5, }, { .val
= 3, .div
= 10, },
202 { .val
= 4, .div
= 2, }, { .val
= 5, .div
= 6, },
203 { .val
= 6, .div
= 10, }, { .val
= 7, .div
= 20, },
204 { .val
= 8, .div
= 4, }, { .val
= 9, .div
= 12, },
205 { .val
= 10, .div
= 20, }, { .val
= 11, .div
= 40, },
206 { .val
= 12, .div
= 8, }, { .val
= 13, .div
= 24, },
207 { .val
= 14, .div
= 40, }, { .val
= 15, .div
= 80, },
211 static struct clk_hw
*clk_out
[6];
213 static unsigned char vc3_pfd_mux_get_parent(struct clk_hw
*hw
)
215 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
216 const struct vc3_clk_data
*pfd_mux
= vc3
->data
;
219 regmap_read(vc3
->regmap
, pfd_mux
->offs
, &src
);
221 return !!(src
& pfd_mux
->bitmsk
);
224 static int vc3_pfd_mux_set_parent(struct clk_hw
*hw
, u8 index
)
226 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
227 const struct vc3_clk_data
*pfd_mux
= vc3
->data
;
229 regmap_update_bits(vc3
->regmap
, pfd_mux
->offs
, pfd_mux
->bitmsk
,
230 index
? pfd_mux
->bitmsk
: 0);
234 static const struct clk_ops vc3_pfd_mux_ops
= {
235 .determine_rate
= clk_hw_determine_rate_no_reparent
,
236 .set_parent
= vc3_pfd_mux_set_parent
,
237 .get_parent
= vc3_pfd_mux_get_parent
,
240 static unsigned long vc3_pfd_recalc_rate(struct clk_hw
*hw
,
241 unsigned long parent_rate
)
243 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
244 const struct vc3_pfd_data
*pfd
= vc3
->data
;
245 unsigned int prediv
, premul
;
249 regmap_read(vc3
->regmap
, pfd
->offs
, &prediv
);
250 if (pfd
->num
== VC3_PFD1
) {
251 /* The bypass_prediv is set, PLL fed from Ref_in directly. */
252 if (prediv
& pfd
->mdiv1_bitmsk
) {
253 /* check doubler is set or not */
254 regmap_read(vc3
->regmap
, VC3_PLL1_CTRL_OUTDIV5
, &premul
);
255 if (premul
& VC3_PLL1_CTRL_OUTDIV5_PLL1_MDIV_DOUBLER
)
259 mdiv
= VC3_PLL1_M_DIV(prediv
);
260 } else if (pfd
->num
== VC3_PFD2
) {
261 /* The bypass_prediv is set, PLL fed from Ref_in directly. */
262 if (prediv
& pfd
->mdiv1_bitmsk
) {
263 regmap_read(vc3
->regmap
, VC3_PLL2_M_DIVIDER
, &premul
);
264 /* check doubler is set or not */
265 if (premul
& VC3_PLL2_MDIV_DOUBLER
)
270 mdiv
= VC3_PLL2_M_DIV(prediv
);
272 /* The bypass_prediv is set, PLL fed from Ref_in directly. */
273 if (prediv
& pfd
->mdiv1_bitmsk
)
276 mdiv
= VC3_PLL3_M_DIV(prediv
);
279 if (prediv
& pfd
->mdiv2_bitmsk
)
280 rate
= parent_rate
/ 2;
282 rate
= parent_rate
/ mdiv
;
287 static long vc3_pfd_round_rate(struct clk_hw
*hw
, unsigned long rate
,
288 unsigned long *parent_rate
)
290 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
291 const struct vc3_pfd_data
*pfd
= vc3
->data
;
294 /* PLL cannot operate with input clock above 50 MHz. */
298 /* CLKIN within range of PLL input, feed directly to PLL. */
299 if (*parent_rate
<= 50000000)
302 idiv
= DIV_ROUND_UP(*parent_rate
, rate
);
303 if (pfd
->num
== VC3_PFD1
|| pfd
->num
== VC3_PFD3
) {
311 return *parent_rate
/ idiv
;
314 static int vc3_pfd_set_rate(struct clk_hw
*hw
, unsigned long rate
,
315 unsigned long parent_rate
)
317 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
318 const struct vc3_pfd_data
*pfd
= vc3
->data
;
322 /* CLKIN within range of PLL input, feed directly to PLL. */
323 if (parent_rate
<= 50000000) {
324 regmap_update_bits(vc3
->regmap
, pfd
->offs
, pfd
->mdiv1_bitmsk
,
326 regmap_update_bits(vc3
->regmap
, pfd
->offs
, pfd
->mdiv2_bitmsk
, 0);
330 idiv
= DIV_ROUND_UP(parent_rate
, rate
);
331 /* We have dedicated div-2 predivider. */
333 regmap_update_bits(vc3
->regmap
, pfd
->offs
, pfd
->mdiv2_bitmsk
,
335 regmap_update_bits(vc3
->regmap
, pfd
->offs
, pfd
->mdiv1_bitmsk
, 0);
337 if (pfd
->num
== VC3_PFD1
)
338 div
= VC3_PLL1_M_DIV(idiv
);
339 else if (pfd
->num
== VC3_PFD2
)
340 div
= VC3_PLL2_M_DIV(idiv
);
342 div
= VC3_PLL3_M_DIV(idiv
);
344 regmap_write(vc3
->regmap
, pfd
->offs
, div
);
350 static const struct clk_ops vc3_pfd_ops
= {
351 .recalc_rate
= vc3_pfd_recalc_rate
,
352 .round_rate
= vc3_pfd_round_rate
,
353 .set_rate
= vc3_pfd_set_rate
,
356 static unsigned long vc3_pll_recalc_rate(struct clk_hw
*hw
,
357 unsigned long parent_rate
)
359 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
360 const struct vc3_pll_data
*pll
= vc3
->data
;
361 u32 div_int
, div_frc
, val
;
364 regmap_read(vc3
->regmap
, pll
->int_div_msb_offs
, &val
);
365 div_int
= (val
& GENMASK(2, 0)) << 8;
366 regmap_read(vc3
->regmap
, pll
->int_div_lsb_offs
, &val
);
369 if (pll
->num
== VC3_PLL2
) {
370 regmap_read(vc3
->regmap
, VC3_PLL2_FB_FRC_DIV_MSB
, &val
);
372 regmap_read(vc3
->regmap
, VC3_PLL2_FB_FRC_DIV_LSB
, &val
);
374 rate
= (parent_rate
*
375 (div_int
* VC3_2_POW_16
+ div_frc
) / VC3_2_POW_16
);
377 rate
= parent_rate
* div_int
;
383 static long vc3_pll_round_rate(struct clk_hw
*hw
, unsigned long rate
,
384 unsigned long *parent_rate
)
386 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
387 const struct vc3_pll_data
*pll
= vc3
->data
;
390 if (rate
< pll
->vco_min
)
392 if (rate
> pll
->vco_max
)
395 vc3
->div_int
= rate
/ *parent_rate
;
397 if (pll
->num
== VC3_PLL2
) {
398 if (vc3
->div_int
> 0x7ff)
399 rate
= *parent_rate
* 0x7ff;
401 /* Determine best fractional part, which is 16 bit wide */
402 div_frc
= rate
% *parent_rate
;
403 div_frc
*= BIT(16) - 1;
404 do_div(div_frc
, *parent_rate
);
406 vc3
->div_frc
= (u32
)div_frc
;
407 rate
= (*parent_rate
*
408 (vc3
->div_int
* VC3_2_POW_16
+ div_frc
) / VC3_2_POW_16
);
410 rate
= *parent_rate
* vc3
->div_int
;
416 static int vc3_pll_set_rate(struct clk_hw
*hw
, unsigned long rate
,
417 unsigned long parent_rate
)
419 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
420 const struct vc3_pll_data
*pll
= vc3
->data
;
423 regmap_read(vc3
->regmap
, pll
->int_div_msb_offs
, &val
);
424 val
= (val
& 0xf8) | ((vc3
->div_int
>> 8) & 0x7);
425 regmap_write(vc3
->regmap
, pll
->int_div_msb_offs
, val
);
426 regmap_write(vc3
->regmap
, pll
->int_div_lsb_offs
, vc3
->div_int
& 0xff);
428 if (pll
->num
== VC3_PLL2
) {
429 regmap_write(vc3
->regmap
, VC3_PLL2_FB_FRC_DIV_MSB
,
431 regmap_write(vc3
->regmap
, VC3_PLL2_FB_FRC_DIV_LSB
,
432 vc3
->div_frc
& 0xff);
438 static const struct clk_ops vc3_pll_ops
= {
439 .recalc_rate
= vc3_pll_recalc_rate
,
440 .round_rate
= vc3_pll_round_rate
,
441 .set_rate
= vc3_pll_set_rate
,
444 static unsigned char vc3_div_mux_get_parent(struct clk_hw
*hw
)
446 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
447 const struct vc3_clk_data
*div_mux
= vc3
->data
;
450 regmap_read(vc3
->regmap
, div_mux
->offs
, &src
);
452 return !!(src
& div_mux
->bitmsk
);
455 static int vc3_div_mux_set_parent(struct clk_hw
*hw
, u8 index
)
457 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
458 const struct vc3_clk_data
*div_mux
= vc3
->data
;
460 regmap_update_bits(vc3
->regmap
, div_mux
->offs
, div_mux
->bitmsk
,
461 index
? div_mux
->bitmsk
: 0);
466 static const struct clk_ops vc3_div_mux_ops
= {
467 .determine_rate
= clk_hw_determine_rate_no_reparent
,
468 .set_parent
= vc3_div_mux_set_parent
,
469 .get_parent
= vc3_div_mux_get_parent
,
472 static unsigned int vc3_get_div(const struct clk_div_table
*table
,
473 unsigned int val
, unsigned long flag
)
475 const struct clk_div_table
*clkt
;
477 for (clkt
= table
; clkt
->div
; clkt
++)
478 if (clkt
->val
== val
)
484 static unsigned long vc3_div_recalc_rate(struct clk_hw
*hw
,
485 unsigned long parent_rate
)
487 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
488 const struct vc3_div_data
*div_data
= vc3
->data
;
491 regmap_read(vc3
->regmap
, div_data
->offs
, &val
);
492 val
>>= div_data
->shift
;
493 val
&= VC3_DIV_MASK(div_data
->width
);
495 return divider_recalc_rate(hw
, parent_rate
, val
, div_data
->table
,
496 div_data
->flags
, div_data
->width
);
499 static long vc3_div_round_rate(struct clk_hw
*hw
, unsigned long rate
,
500 unsigned long *parent_rate
)
502 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
503 const struct vc3_div_data
*div_data
= vc3
->data
;
504 unsigned int bestdiv
;
506 /* if read only, just return current value */
507 if (div_data
->flags
& CLK_DIVIDER_READ_ONLY
) {
508 regmap_read(vc3
->regmap
, div_data
->offs
, &bestdiv
);
509 bestdiv
>>= div_data
->shift
;
510 bestdiv
&= VC3_DIV_MASK(div_data
->width
);
511 bestdiv
= vc3_get_div(div_data
->table
, bestdiv
, div_data
->flags
);
512 return DIV_ROUND_UP(*parent_rate
, bestdiv
);
515 return divider_round_rate(hw
, rate
, parent_rate
, div_data
->table
,
516 div_data
->width
, div_data
->flags
);
519 static int vc3_div_set_rate(struct clk_hw
*hw
, unsigned long rate
,
520 unsigned long parent_rate
)
522 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
523 const struct vc3_div_data
*div_data
= vc3
->data
;
526 value
= divider_get_val(rate
, parent_rate
, div_data
->table
,
527 div_data
->width
, div_data
->flags
);
528 regmap_update_bits(vc3
->regmap
, div_data
->offs
,
529 VC3_DIV_MASK(div_data
->width
) << div_data
->shift
,
530 value
<< div_data
->shift
);
534 static const struct clk_ops vc3_div_ops
= {
535 .recalc_rate
= vc3_div_recalc_rate
,
536 .round_rate
= vc3_div_round_rate
,
537 .set_rate
= vc3_div_set_rate
,
540 static int vc3_clk_mux_determine_rate(struct clk_hw
*hw
,
541 struct clk_rate_request
*req
)
546 ret
= clk_mux_determine_rate_flags(hw
, req
, CLK_SET_RATE_PARENT
);
548 /* The below check is equivalent to (best_parent_rate/rate) */
549 if (req
->best_parent_rate
>= req
->rate
) {
550 frc
= DIV_ROUND_CLOSEST_ULL(req
->best_parent_rate
,
553 return clk_mux_determine_rate_flags(hw
, req
,
554 CLK_SET_RATE_PARENT
);
562 static unsigned char vc3_clk_mux_get_parent(struct clk_hw
*hw
)
564 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
565 const struct vc3_clk_data
*clk_mux
= vc3
->data
;
568 regmap_read(vc3
->regmap
, clk_mux
->offs
, &val
);
570 return !!(val
& clk_mux
->bitmsk
);
573 static int vc3_clk_mux_set_parent(struct clk_hw
*hw
, u8 index
)
575 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
576 const struct vc3_clk_data
*clk_mux
= vc3
->data
;
578 regmap_update_bits(vc3
->regmap
, clk_mux
->offs
,
579 clk_mux
->bitmsk
, index
? clk_mux
->bitmsk
: 0);
583 static const struct clk_ops vc3_clk_mux_ops
= {
584 .determine_rate
= vc3_clk_mux_determine_rate
,
585 .set_parent
= vc3_clk_mux_set_parent
,
586 .get_parent
= vc3_clk_mux_get_parent
,
589 static bool vc3_regmap_is_writeable(struct device
*dev
, unsigned int reg
)
594 static const struct regmap_config vc3_regmap_config
= {
597 .cache_type
= REGCACHE_RBTREE
,
598 .max_register
= 0x24,
599 .writeable_reg
= vc3_regmap_is_writeable
,
602 static struct vc3_hw_data clk_div
[5];
604 static const struct clk_parent_data pfd_mux_parent_data
[] = {
606 { .hw
= &clk_div
[VC3_DIV2
].hw
}
609 static struct vc3_hw_data clk_pfd_mux
[] = {
611 .data
= &(struct vc3_clk_data
) {
612 .offs
= VC3_PLL_OP_CTRL
,
613 .bitmsk
= BIT(VC3_PLL_OP_CTRL_PLL2_REFIN_SEL
)
615 .hw
.init
= &(struct clk_init_data
){
617 .ops
= &vc3_pfd_mux_ops
,
618 .parent_data
= pfd_mux_parent_data
,
620 .flags
= CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT
624 .data
= &(struct vc3_clk_data
) {
625 .offs
= VC3_GENERAL_CTR
,
626 .bitmsk
= BIT(VC3_GENERAL_CTR_PLL3_REFIN_SEL
)
628 .hw
.init
= &(struct clk_init_data
){
630 .ops
= &vc3_pfd_mux_ops
,
631 .parent_data
= pfd_mux_parent_data
,
633 .flags
= CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT
638 static struct vc3_hw_data clk_pfd
[] = {
640 .data
= &(struct vc3_pfd_data
) {
642 .offs
= VC3_PLL1_M_DIVIDER
,
643 .mdiv1_bitmsk
= VC3_PLL1_M_DIV1
,
644 .mdiv2_bitmsk
= VC3_PLL1_M_DIV2
646 .hw
.init
= &(struct clk_init_data
){
649 .parent_data
= &(const struct clk_parent_data
) {
653 .flags
= CLK_SET_RATE_PARENT
657 .data
= &(struct vc3_pfd_data
) {
659 .offs
= VC3_PLL2_M_DIVIDER
,
660 .mdiv1_bitmsk
= VC3_PLL2_M_DIV1
,
661 .mdiv2_bitmsk
= VC3_PLL2_M_DIV2
663 .hw
.init
= &(struct clk_init_data
){
666 .parent_hws
= (const struct clk_hw
*[]) {
667 &clk_pfd_mux
[VC3_PFD2_MUX
].hw
670 .flags
= CLK_SET_RATE_PARENT
674 .data
= &(struct vc3_pfd_data
) {
676 .offs
= VC3_PLL3_M_DIVIDER
,
677 .mdiv1_bitmsk
= VC3_PLL3_M_DIV1
,
678 .mdiv2_bitmsk
= VC3_PLL3_M_DIV2
680 .hw
.init
= &(struct clk_init_data
){
683 .parent_hws
= (const struct clk_hw
*[]) {
684 &clk_pfd_mux
[VC3_PFD3_MUX
].hw
687 .flags
= CLK_SET_RATE_PARENT
692 static struct vc3_hw_data clk_pll
[] = {
694 .data
= &(struct vc3_pll_data
) {
696 .int_div_msb_offs
= VC3_PLL1_LOOP_FILTER_N_DIV_MSB
,
697 .int_div_lsb_offs
= VC3_PLL1_VCO_N_DIVIDER
,
698 .vco_min
= VC3_PLL1_VCO_MIN
,
699 .vco_max
= VC3_PLL1_VCO_MAX
701 .hw
.init
= &(struct clk_init_data
){
704 .parent_hws
= (const struct clk_hw
*[]) {
705 &clk_pfd
[VC3_PFD1
].hw
708 .flags
= CLK_SET_RATE_PARENT
712 .data
= &(struct vc3_pll_data
) {
714 .int_div_msb_offs
= VC3_PLL2_FB_INT_DIV_MSB
,
715 .int_div_lsb_offs
= VC3_PLL2_FB_INT_DIV_LSB
,
716 .vco_min
= VC3_PLL2_VCO_MIN
,
717 .vco_max
= VC3_PLL2_VCO_MAX
719 .hw
.init
= &(struct clk_init_data
){
722 .parent_hws
= (const struct clk_hw
*[]) {
723 &clk_pfd
[VC3_PFD2
].hw
726 .flags
= CLK_SET_RATE_PARENT
730 .data
= &(struct vc3_pll_data
) {
732 .int_div_msb_offs
= VC3_PLL3_LOOP_FILTER_N_DIV_MSB
,
733 .int_div_lsb_offs
= VC3_PLL3_N_DIVIDER
,
734 .vco_min
= VC3_PLL3_VCO_MIN
,
735 .vco_max
= VC3_PLL3_VCO_MAX
737 .hw
.init
= &(struct clk_init_data
){
740 .parent_hws
= (const struct clk_hw
*[]) {
741 &clk_pfd
[VC3_PFD3
].hw
744 .flags
= CLK_SET_RATE_PARENT
749 static const struct clk_parent_data div_mux_parent_data
[][2] = {
751 { .hw
= &clk_pll
[VC3_PLL1
].hw
},
755 { .hw
= &clk_pll
[VC3_PLL2
].hw
},
756 { .hw
= &clk_pll
[VC3_PLL3
].hw
}
759 { .hw
= &clk_pll
[VC3_PLL2
].hw
},
764 static struct vc3_hw_data clk_div_mux
[] = {
766 .data
= &(struct vc3_clk_data
) {
767 .offs
= VC3_GENERAL_CTR
,
768 .bitmsk
= VC3_GENERAL_CTR_DIV1_SRC_SEL
770 .hw
.init
= &(struct clk_init_data
){
772 .ops
= &vc3_div_mux_ops
,
773 .parent_data
= div_mux_parent_data
[VC3_DIV1_MUX
],
775 .flags
= CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT
779 .data
= &(struct vc3_clk_data
) {
780 .offs
= VC3_PLL3_CHARGE_PUMP_CTRL
,
781 .bitmsk
= VC3_PLL3_CHARGE_PUMP_CTRL_OUTDIV3_SRC_SEL
783 .hw
.init
= &(struct clk_init_data
){
785 .ops
= &vc3_div_mux_ops
,
786 .parent_data
= div_mux_parent_data
[VC3_DIV3_MUX
],
788 .flags
= CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT
792 .data
= &(struct vc3_clk_data
) {
793 .offs
= VC3_OUTPUT_CTR
,
794 .bitmsk
= VC3_OUTPUT_CTR_DIV4_SRC_SEL
796 .hw
.init
= &(struct clk_init_data
){
798 .ops
= &vc3_div_mux_ops
,
799 .parent_data
= div_mux_parent_data
[VC3_DIV4_MUX
],
801 .flags
= CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT
806 static struct vc3_hw_data clk_div
[] = {
808 .data
= &(struct vc3_div_data
) {
809 .offs
= VC3_OUT_DIV1_DIV2_CTRL
,
813 .flags
= CLK_DIVIDER_READ_ONLY
815 .hw
.init
= &(struct clk_init_data
){
818 .parent_hws
= (const struct clk_hw
*[]) {
819 &clk_div_mux
[VC3_DIV1_MUX
].hw
822 .flags
= CLK_SET_RATE_PARENT
826 .data
= &(struct vc3_div_data
) {
827 .offs
= VC3_OUT_DIV1_DIV2_CTRL
,
828 .table
= div245_divs
,
831 .flags
= CLK_DIVIDER_READ_ONLY
833 .hw
.init
= &(struct clk_init_data
){
836 .parent_hws
= (const struct clk_hw
*[]) {
837 &clk_pll
[VC3_PLL1
].hw
840 .flags
= CLK_SET_RATE_PARENT
844 .data
= &(struct vc3_div_data
) {
845 .offs
= VC3_OUT_DIV3_DIV4_CTRL
,
849 .flags
= CLK_DIVIDER_READ_ONLY
851 .hw
.init
= &(struct clk_init_data
){
854 .parent_hws
= (const struct clk_hw
*[]) {
855 &clk_div_mux
[VC3_DIV3_MUX
].hw
858 .flags
= CLK_SET_RATE_PARENT
862 .data
= &(struct vc3_div_data
) {
863 .offs
= VC3_OUT_DIV3_DIV4_CTRL
,
864 .table
= div245_divs
,
867 .flags
= CLK_DIVIDER_READ_ONLY
869 .hw
.init
= &(struct clk_init_data
){
872 .parent_hws
= (const struct clk_hw
*[]) {
873 &clk_div_mux
[VC3_DIV4_MUX
].hw
876 .flags
= CLK_SET_RATE_PARENT
880 .data
= &(struct vc3_div_data
) {
881 .offs
= VC3_PLL1_CTRL_OUTDIV5
,
882 .table
= div245_divs
,
885 .flags
= CLK_DIVIDER_READ_ONLY
887 .hw
.init
= &(struct clk_init_data
){
890 .parent_hws
= (const struct clk_hw
*[]) {
891 &clk_pll
[VC3_PLL3
].hw
894 .flags
= CLK_SET_RATE_PARENT
899 static struct vc3_hw_data clk_mux
[] = {
901 .data
= &(struct vc3_clk_data
) {
902 .offs
= VC3_DIFF2_CTRL_REG
,
903 .bitmsk
= VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL
905 .hw
.init
= &(struct clk_init_data
){
907 .ops
= &vc3_clk_mux_ops
,
908 .parent_hws
= (const struct clk_hw
*[]) {
909 &clk_div
[VC3_DIV1
].hw
,
910 &clk_div
[VC3_DIV3
].hw
913 .flags
= CLK_SET_RATE_PARENT
917 .data
= &(struct vc3_clk_data
) {
918 .offs
= VC3_DIFF1_CTRL_REG
,
919 .bitmsk
= VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL
921 .hw
.init
= &(struct clk_init_data
){
923 .ops
= &vc3_clk_mux_ops
,
924 .parent_hws
= (const struct clk_hw
*[]) {
925 &clk_div
[VC3_DIV1
].hw
,
926 &clk_div
[VC3_DIV3
].hw
929 .flags
= CLK_SET_RATE_PARENT
933 .data
= &(struct vc3_clk_data
) {
934 .offs
= VC3_SE3_DIFF1_CTRL_REG
,
935 .bitmsk
= VC3_SE3_DIFF1_CTRL_REG_SE3_CLK_SEL
937 .hw
.init
= &(struct clk_init_data
){
939 .ops
= &vc3_clk_mux_ops
,
940 .parent_hws
= (const struct clk_hw
*[]) {
941 &clk_div
[VC3_DIV2
].hw
,
942 &clk_div
[VC3_DIV4
].hw
945 .flags
= CLK_SET_RATE_PARENT
949 .data
= &(struct vc3_clk_data
) {
950 .offs
= VC3_SE2_CTRL_REG0
,
951 .bitmsk
= VC3_SE2_CTRL_REG0_SE2_CLK_SEL
953 .hw
.init
= &(struct clk_init_data
){
955 .ops
= &vc3_clk_mux_ops
,
956 .parent_hws
= (const struct clk_hw
*[]) {
957 &clk_div
[VC3_DIV5
].hw
,
958 &clk_div
[VC3_DIV4
].hw
961 .flags
= CLK_SET_RATE_PARENT
965 .data
= &(struct vc3_clk_data
) {
966 .offs
= VC3_SE1_DIV4_CTRL
,
967 .bitmsk
= VC3_SE1_DIV4_CTRL_SE1_CLK_SEL
969 .hw
.init
= &(struct clk_init_data
){
971 .ops
= &vc3_clk_mux_ops
,
972 .parent_hws
= (const struct clk_hw
*[]) {
973 &clk_div
[VC3_DIV5
].hw
,
974 &clk_div
[VC3_DIV4
].hw
977 .flags
= CLK_SET_RATE_PARENT
982 static struct clk_hw
*vc3_of_clk_get(struct of_phandle_args
*clkspec
,
985 unsigned int idx
= clkspec
->args
[0];
986 struct clk_hw
**clkout_hw
= data
;
988 if (idx
>= ARRAY_SIZE(clk_out
)) {
989 pr_err("invalid clk index %u for provider %pOF\n", idx
, clkspec
->np
);
990 return ERR_PTR(-EINVAL
);
993 return clkout_hw
[idx
];
996 static int vc3_probe(struct i2c_client
*client
)
998 struct device
*dev
= &client
->dev
;
999 u8 settings
[NUM_CONFIG_REGISTERS
];
1000 struct regmap
*regmap
;
1004 regmap
= devm_regmap_init_i2c(client
, &vc3_regmap_config
);
1006 return dev_err_probe(dev
, PTR_ERR(regmap
),
1007 "failed to allocate register map\n");
1009 ret
= of_property_read_u8_array(dev
->of_node
, "renesas,settings",
1010 settings
, ARRAY_SIZE(settings
));
1013 * A raw settings array was specified in the DT. Write the
1014 * settings to the device immediately.
1016 for (i
= 0; i
< NUM_CONFIG_REGISTERS
; i
++) {
1017 ret
= regmap_write(regmap
, i
, settings
[i
]);
1019 dev_err(dev
, "error writing to chip (%i)\n", ret
);
1023 } else if (ret
== -EOVERFLOW
) {
1024 dev_err(&client
->dev
, "EOVERFLOW reg settings. ARRAY_SIZE: %zu\n",
1025 ARRAY_SIZE(settings
));
1029 /* Register pfd muxes */
1030 for (i
= 0; i
< ARRAY_SIZE(clk_pfd_mux
); i
++) {
1031 clk_pfd_mux
[i
].regmap
= regmap
;
1032 ret
= devm_clk_hw_register(dev
, &clk_pfd_mux
[i
].hw
);
1034 return dev_err_probe(dev
, ret
, "%s failed\n",
1035 clk_pfd_mux
[i
].hw
.init
->name
);
1038 /* Register pfd's */
1039 for (i
= 0; i
< ARRAY_SIZE(clk_pfd
); i
++) {
1040 clk_pfd
[i
].regmap
= regmap
;
1041 ret
= devm_clk_hw_register(dev
, &clk_pfd
[i
].hw
);
1043 return dev_err_probe(dev
, ret
, "%s failed\n",
1044 clk_pfd
[i
].hw
.init
->name
);
1047 /* Register pll's */
1048 for (i
= 0; i
< ARRAY_SIZE(clk_pll
); i
++) {
1049 clk_pll
[i
].regmap
= regmap
;
1050 ret
= devm_clk_hw_register(dev
, &clk_pll
[i
].hw
);
1052 return dev_err_probe(dev
, ret
, "%s failed\n",
1053 clk_pll
[i
].hw
.init
->name
);
1056 /* Register divider muxes */
1057 for (i
= 0; i
< ARRAY_SIZE(clk_div_mux
); i
++) {
1058 clk_div_mux
[i
].regmap
= regmap
;
1059 ret
= devm_clk_hw_register(dev
, &clk_div_mux
[i
].hw
);
1061 return dev_err_probe(dev
, ret
, "%s failed\n",
1062 clk_div_mux
[i
].hw
.init
->name
);
1065 /* Register dividers */
1066 for (i
= 0; i
< ARRAY_SIZE(clk_div
); i
++) {
1067 clk_div
[i
].regmap
= regmap
;
1068 ret
= devm_clk_hw_register(dev
, &clk_div
[i
].hw
);
1070 return dev_err_probe(dev
, ret
, "%s failed\n",
1071 clk_div
[i
].hw
.init
->name
);
1074 /* Register clk muxes */
1075 for (i
= 0; i
< ARRAY_SIZE(clk_mux
); i
++) {
1076 clk_mux
[i
].regmap
= regmap
;
1077 ret
= devm_clk_hw_register(dev
, &clk_mux
[i
].hw
);
1079 return dev_err_probe(dev
, ret
, "%s failed\n",
1080 clk_mux
[i
].hw
.init
->name
);
1083 /* Register clk outputs */
1084 for (i
= 0; i
< ARRAY_SIZE(clk_out
); i
++) {
1105 return dev_err_probe(dev
, -EINVAL
, "invalid clk output %d\n", i
);
1109 clk_out
[i
] = devm_clk_hw_register_fixed_factor_index(dev
,
1110 name
, 0, CLK_SET_RATE_PARENT
, 1, 1);
1112 clk_out
[i
] = devm_clk_hw_register_fixed_factor_parent_hw(dev
,
1113 name
, &clk_mux
[i
].hw
, CLK_SET_RATE_PARENT
, 1, 1);
1115 if (IS_ERR(clk_out
[i
]))
1116 return PTR_ERR(clk_out
[i
]);
1119 ret
= devm_of_clk_add_hw_provider(dev
, vc3_of_clk_get
, clk_out
);
1121 return dev_err_probe(dev
, ret
, "unable to add clk provider\n");
1126 static const struct of_device_id dev_ids
[] = {
1127 { .compatible
= "renesas,5p35023" },
1130 MODULE_DEVICE_TABLE(of
, dev_ids
);
1132 static struct i2c_driver vc3_driver
= {
1135 .of_match_table
= of_match_ptr(dev_ids
),
1139 module_i2c_driver(vc3_driver
);
1141 MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
1142 MODULE_DESCRIPTION("Renesas VersaClock 3 driver");
1143 MODULE_LICENSE("GPL");