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 0xa
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)
131 VC3_SE1_MUX
= VC3_SE1
- 1,
132 VC3_SE2_MUX
= VC3_SE2
- 1,
133 VC3_SE3_MUX
= VC3_SE3
- 1,
134 VC3_DIFF1_MUX
= VC3_DIFF1
- 1,
135 VC3_DIFF2_MUX
= VC3_DIFF2
- 1,
138 struct vc3_clk_data
{
143 struct vc3_pfd_data
{
150 struct vc3_pll_data
{
151 unsigned long vco_min
;
152 unsigned long vco_max
;
158 struct vc3_div_data
{
159 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 u8
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 return regmap_update_bits(vc3
->regmap
, pfd_mux
->offs
, pfd_mux
->bitmsk
,
230 index
? pfd_mux
->bitmsk
: 0);
233 static const struct clk_ops vc3_pfd_mux_ops
= {
234 .determine_rate
= clk_hw_determine_rate_no_reparent
,
235 .set_parent
= vc3_pfd_mux_set_parent
,
236 .get_parent
= vc3_pfd_mux_get_parent
,
239 static unsigned long vc3_pfd_recalc_rate(struct clk_hw
*hw
,
240 unsigned long parent_rate
)
242 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
243 const struct vc3_pfd_data
*pfd
= vc3
->data
;
244 unsigned int prediv
, premul
;
248 regmap_read(vc3
->regmap
, pfd
->offs
, &prediv
);
249 if (pfd
->num
== VC3_PFD1
) {
250 /* The bypass_prediv is set, PLL fed from Ref_in directly. */
251 if (prediv
& pfd
->mdiv1_bitmsk
) {
252 /* check doubler is set or not */
253 regmap_read(vc3
->regmap
, VC3_PLL1_CTRL_OUTDIV5
, &premul
);
254 if (premul
& VC3_PLL1_CTRL_OUTDIV5_PLL1_MDIV_DOUBLER
)
258 mdiv
= VC3_PLL1_M_DIV(prediv
);
259 } else if (pfd
->num
== VC3_PFD2
) {
260 /* The bypass_prediv is set, PLL fed from Ref_in directly. */
261 if (prediv
& pfd
->mdiv1_bitmsk
) {
262 regmap_read(vc3
->regmap
, VC3_PLL2_M_DIVIDER
, &premul
);
263 /* check doubler is set or not */
264 if (premul
& VC3_PLL2_MDIV_DOUBLER
)
269 mdiv
= VC3_PLL2_M_DIV(prediv
);
271 /* The bypass_prediv is set, PLL fed from Ref_in directly. */
272 if (prediv
& pfd
->mdiv1_bitmsk
)
275 mdiv
= VC3_PLL3_M_DIV(prediv
);
278 if (prediv
& pfd
->mdiv2_bitmsk
)
279 rate
= parent_rate
/ 2;
281 rate
= parent_rate
/ mdiv
;
286 static long vc3_pfd_round_rate(struct clk_hw
*hw
, unsigned long rate
,
287 unsigned long *parent_rate
)
289 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
290 const struct vc3_pfd_data
*pfd
= vc3
->data
;
293 /* PLL cannot operate with input clock above 50 MHz. */
297 /* CLKIN within range of PLL input, feed directly to PLL. */
298 if (*parent_rate
<= 50000000)
301 idiv
= DIV_ROUND_UP(*parent_rate
, rate
);
302 if (pfd
->num
== VC3_PFD1
|| pfd
->num
== VC3_PFD3
) {
310 return *parent_rate
/ idiv
;
313 static int vc3_pfd_set_rate(struct clk_hw
*hw
, unsigned long rate
,
314 unsigned long parent_rate
)
316 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
317 const struct vc3_pfd_data
*pfd
= vc3
->data
;
321 /* CLKIN within range of PLL input, feed directly to PLL. */
322 if (parent_rate
<= 50000000) {
323 regmap_update_bits(vc3
->regmap
, pfd
->offs
, pfd
->mdiv1_bitmsk
,
325 regmap_update_bits(vc3
->regmap
, pfd
->offs
, pfd
->mdiv2_bitmsk
, 0);
329 idiv
= DIV_ROUND_UP(parent_rate
, rate
);
330 /* We have dedicated div-2 predivider. */
332 regmap_update_bits(vc3
->regmap
, pfd
->offs
, pfd
->mdiv2_bitmsk
,
334 regmap_update_bits(vc3
->regmap
, pfd
->offs
, pfd
->mdiv1_bitmsk
, 0);
336 if (pfd
->num
== VC3_PFD1
)
337 div
= VC3_PLL1_M_DIV(idiv
);
338 else if (pfd
->num
== VC3_PFD2
)
339 div
= VC3_PLL2_M_DIV(idiv
);
341 div
= VC3_PLL3_M_DIV(idiv
);
343 regmap_write(vc3
->regmap
, pfd
->offs
, div
);
349 static const struct clk_ops vc3_pfd_ops
= {
350 .recalc_rate
= vc3_pfd_recalc_rate
,
351 .round_rate
= vc3_pfd_round_rate
,
352 .set_rate
= vc3_pfd_set_rate
,
355 static unsigned long vc3_pll_recalc_rate(struct clk_hw
*hw
,
356 unsigned long parent_rate
)
358 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
359 const struct vc3_pll_data
*pll
= vc3
->data
;
360 u32 div_int
, div_frc
, val
;
363 regmap_read(vc3
->regmap
, pll
->int_div_msb_offs
, &val
);
364 div_int
= (val
& GENMASK(2, 0)) << 8;
365 regmap_read(vc3
->regmap
, pll
->int_div_lsb_offs
, &val
);
368 if (pll
->num
== VC3_PLL2
) {
369 regmap_read(vc3
->regmap
, VC3_PLL2_FB_FRC_DIV_MSB
, &val
);
371 regmap_read(vc3
->regmap
, VC3_PLL2_FB_FRC_DIV_LSB
, &val
);
373 rate
= (parent_rate
*
374 (div_int
* VC3_2_POW_16
+ div_frc
) / VC3_2_POW_16
);
376 rate
= parent_rate
* div_int
;
382 static long vc3_pll_round_rate(struct clk_hw
*hw
, unsigned long rate
,
383 unsigned long *parent_rate
)
385 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
386 const struct vc3_pll_data
*pll
= vc3
->data
;
389 if (rate
< pll
->vco_min
)
391 if (rate
> pll
->vco_max
)
394 vc3
->div_int
= rate
/ *parent_rate
;
396 if (pll
->num
== VC3_PLL2
) {
397 if (vc3
->div_int
> 0x7ff)
398 rate
= *parent_rate
* 0x7ff;
400 /* Determine best fractional part, which is 16 bit wide */
401 div_frc
= rate
% *parent_rate
;
402 div_frc
*= BIT(16) - 1;
404 vc3
->div_frc
= min_t(u64
, div64_ul(div_frc
, *parent_rate
), U16_MAX
);
405 rate
= (*parent_rate
*
406 (vc3
->div_int
* VC3_2_POW_16
+ vc3
->div_frc
) / VC3_2_POW_16
);
408 rate
= *parent_rate
* vc3
->div_int
;
414 static int vc3_pll_set_rate(struct clk_hw
*hw
, unsigned long rate
,
415 unsigned long parent_rate
)
417 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
418 const struct vc3_pll_data
*pll
= vc3
->data
;
421 regmap_read(vc3
->regmap
, pll
->int_div_msb_offs
, &val
);
422 val
= (val
& 0xf8) | ((vc3
->div_int
>> 8) & 0x7);
423 regmap_write(vc3
->regmap
, pll
->int_div_msb_offs
, val
);
424 regmap_write(vc3
->regmap
, pll
->int_div_lsb_offs
, vc3
->div_int
& 0xff);
426 if (pll
->num
== VC3_PLL2
) {
427 regmap_write(vc3
->regmap
, VC3_PLL2_FB_FRC_DIV_MSB
,
429 regmap_write(vc3
->regmap
, VC3_PLL2_FB_FRC_DIV_LSB
,
430 vc3
->div_frc
& 0xff);
436 static const struct clk_ops vc3_pll_ops
= {
437 .recalc_rate
= vc3_pll_recalc_rate
,
438 .round_rate
= vc3_pll_round_rate
,
439 .set_rate
= vc3_pll_set_rate
,
442 static u8
vc3_div_mux_get_parent(struct clk_hw
*hw
)
444 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
445 const struct vc3_clk_data
*div_mux
= vc3
->data
;
448 regmap_read(vc3
->regmap
, div_mux
->offs
, &src
);
450 return !!(src
& div_mux
->bitmsk
);
453 static int vc3_div_mux_set_parent(struct clk_hw
*hw
, u8 index
)
455 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
456 const struct vc3_clk_data
*div_mux
= vc3
->data
;
458 return regmap_update_bits(vc3
->regmap
, div_mux
->offs
, div_mux
->bitmsk
,
459 index
? div_mux
->bitmsk
: 0);
462 static const struct clk_ops vc3_div_mux_ops
= {
463 .determine_rate
= clk_hw_determine_rate_no_reparent
,
464 .set_parent
= vc3_div_mux_set_parent
,
465 .get_parent
= vc3_div_mux_get_parent
,
468 static unsigned int vc3_get_div(const struct clk_div_table
*table
,
469 unsigned int val
, unsigned long flag
)
471 const struct clk_div_table
*clkt
;
473 for (clkt
= table
; clkt
->div
; clkt
++)
474 if (clkt
->val
== val
)
480 static unsigned long vc3_div_recalc_rate(struct clk_hw
*hw
,
481 unsigned long parent_rate
)
483 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
484 const struct vc3_div_data
*div_data
= vc3
->data
;
487 regmap_read(vc3
->regmap
, div_data
->offs
, &val
);
488 val
>>= div_data
->shift
;
489 val
&= VC3_DIV_MASK(div_data
->width
);
491 return divider_recalc_rate(hw
, parent_rate
, val
, div_data
->table
,
492 div_data
->flags
, div_data
->width
);
495 static long vc3_div_round_rate(struct clk_hw
*hw
, unsigned long rate
,
496 unsigned long *parent_rate
)
498 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
499 const struct vc3_div_data
*div_data
= vc3
->data
;
500 unsigned int bestdiv
;
502 /* if read only, just return current value */
503 if (div_data
->flags
& CLK_DIVIDER_READ_ONLY
) {
504 regmap_read(vc3
->regmap
, div_data
->offs
, &bestdiv
);
505 bestdiv
>>= div_data
->shift
;
506 bestdiv
&= VC3_DIV_MASK(div_data
->width
);
507 bestdiv
= vc3_get_div(div_data
->table
, bestdiv
, div_data
->flags
);
508 return DIV_ROUND_UP(*parent_rate
, bestdiv
);
511 return divider_round_rate(hw
, rate
, parent_rate
, div_data
->table
,
512 div_data
->width
, div_data
->flags
);
515 static int vc3_div_set_rate(struct clk_hw
*hw
, unsigned long rate
,
516 unsigned long parent_rate
)
518 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
519 const struct vc3_div_data
*div_data
= vc3
->data
;
522 value
= divider_get_val(rate
, parent_rate
, div_data
->table
,
523 div_data
->width
, div_data
->flags
);
524 return regmap_update_bits(vc3
->regmap
, div_data
->offs
,
525 VC3_DIV_MASK(div_data
->width
) << div_data
->shift
,
526 value
<< div_data
->shift
);
529 static const struct clk_ops vc3_div_ops
= {
530 .recalc_rate
= vc3_div_recalc_rate
,
531 .round_rate
= vc3_div_round_rate
,
532 .set_rate
= vc3_div_set_rate
,
535 static int vc3_clk_mux_determine_rate(struct clk_hw
*hw
,
536 struct clk_rate_request
*req
)
540 if (clk_mux_determine_rate_flags(hw
, req
, CLK_SET_RATE_PARENT
)) {
541 /* The below check is equivalent to (best_parent_rate/rate) */
542 if (req
->best_parent_rate
>= req
->rate
) {
543 frc
= DIV_ROUND_CLOSEST_ULL(req
->best_parent_rate
,
546 return clk_mux_determine_rate_flags(hw
, req
,
547 CLK_SET_RATE_PARENT
);
554 static u8
vc3_clk_mux_get_parent(struct clk_hw
*hw
)
556 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
557 const struct vc3_clk_data
*clk_mux
= vc3
->data
;
560 regmap_read(vc3
->regmap
, clk_mux
->offs
, &val
);
562 return !!(val
& clk_mux
->bitmsk
);
565 static int vc3_clk_mux_set_parent(struct clk_hw
*hw
, u8 index
)
567 struct vc3_hw_data
*vc3
= container_of(hw
, struct vc3_hw_data
, hw
);
568 const struct vc3_clk_data
*clk_mux
= vc3
->data
;
570 return regmap_update_bits(vc3
->regmap
, clk_mux
->offs
, clk_mux
->bitmsk
,
571 index
? clk_mux
->bitmsk
: 0);
574 static const struct clk_ops vc3_clk_mux_ops
= {
575 .determine_rate
= vc3_clk_mux_determine_rate
,
576 .set_parent
= vc3_clk_mux_set_parent
,
577 .get_parent
= vc3_clk_mux_get_parent
,
580 static const struct regmap_config vc3_regmap_config
= {
583 .cache_type
= REGCACHE_MAPLE
,
584 .max_register
= 0x24,
587 static struct vc3_hw_data clk_div
[5];
589 static const struct clk_parent_data pfd_mux_parent_data
[] = {
591 { .hw
= &clk_div
[VC3_DIV2
].hw
}
594 static struct vc3_hw_data clk_pfd_mux
[] = {
596 .data
= &(struct vc3_clk_data
) {
597 .offs
= VC3_PLL_OP_CTRL
,
598 .bitmsk
= BIT(VC3_PLL_OP_CTRL_PLL2_REFIN_SEL
)
600 .hw
.init
= &(struct clk_init_data
) {
602 .ops
= &vc3_pfd_mux_ops
,
603 .parent_data
= pfd_mux_parent_data
,
605 .flags
= CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT
609 .data
= &(struct vc3_clk_data
) {
610 .offs
= VC3_GENERAL_CTR
,
611 .bitmsk
= BIT(VC3_GENERAL_CTR_PLL3_REFIN_SEL
)
613 .hw
.init
= &(struct clk_init_data
) {
615 .ops
= &vc3_pfd_mux_ops
,
616 .parent_data
= pfd_mux_parent_data
,
618 .flags
= CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT
623 static struct vc3_hw_data clk_pfd
[] = {
625 .data
= &(struct vc3_pfd_data
) {
627 .offs
= VC3_PLL1_M_DIVIDER
,
628 .mdiv1_bitmsk
= VC3_PLL1_M_DIV1
,
629 .mdiv2_bitmsk
= VC3_PLL1_M_DIV2
631 .hw
.init
= &(struct clk_init_data
) {
634 .parent_data
= &(const struct clk_parent_data
) {
638 .flags
= CLK_SET_RATE_PARENT
642 .data
= &(struct vc3_pfd_data
) {
644 .offs
= VC3_PLL2_M_DIVIDER
,
645 .mdiv1_bitmsk
= VC3_PLL2_M_DIV1
,
646 .mdiv2_bitmsk
= VC3_PLL2_M_DIV2
648 .hw
.init
= &(struct clk_init_data
) {
651 .parent_hws
= (const struct clk_hw
*[]) {
652 &clk_pfd_mux
[VC3_PFD2_MUX
].hw
655 .flags
= CLK_SET_RATE_PARENT
659 .data
= &(struct vc3_pfd_data
) {
661 .offs
= VC3_PLL3_M_DIVIDER
,
662 .mdiv1_bitmsk
= VC3_PLL3_M_DIV1
,
663 .mdiv2_bitmsk
= VC3_PLL3_M_DIV2
665 .hw
.init
= &(struct clk_init_data
) {
668 .parent_hws
= (const struct clk_hw
*[]) {
669 &clk_pfd_mux
[VC3_PFD3_MUX
].hw
672 .flags
= CLK_SET_RATE_PARENT
677 static struct vc3_hw_data clk_pll
[] = {
679 .data
= &(struct vc3_pll_data
) {
681 .int_div_msb_offs
= VC3_PLL1_LOOP_FILTER_N_DIV_MSB
,
682 .int_div_lsb_offs
= VC3_PLL1_VCO_N_DIVIDER
,
683 .vco_min
= VC3_PLL1_VCO_MIN
,
684 .vco_max
= VC3_PLL1_VCO_MAX
686 .hw
.init
= &(struct clk_init_data
) {
689 .parent_hws
= (const struct clk_hw
*[]) {
690 &clk_pfd
[VC3_PFD1
].hw
693 .flags
= CLK_SET_RATE_PARENT
697 .data
= &(struct vc3_pll_data
) {
699 .int_div_msb_offs
= VC3_PLL2_FB_INT_DIV_MSB
,
700 .int_div_lsb_offs
= VC3_PLL2_FB_INT_DIV_LSB
,
701 .vco_min
= VC3_PLL2_VCO_MIN
,
702 .vco_max
= VC3_PLL2_VCO_MAX
704 .hw
.init
= &(struct clk_init_data
) {
707 .parent_hws
= (const struct clk_hw
*[]) {
708 &clk_pfd
[VC3_PFD2
].hw
711 .flags
= CLK_SET_RATE_PARENT
715 .data
= &(struct vc3_pll_data
) {
717 .int_div_msb_offs
= VC3_PLL3_LOOP_FILTER_N_DIV_MSB
,
718 .int_div_lsb_offs
= VC3_PLL3_N_DIVIDER
,
719 .vco_min
= VC3_PLL3_VCO_MIN
,
720 .vco_max
= VC3_PLL3_VCO_MAX
722 .hw
.init
= &(struct clk_init_data
) {
725 .parent_hws
= (const struct clk_hw
*[]) {
726 &clk_pfd
[VC3_PFD3
].hw
729 .flags
= CLK_SET_RATE_PARENT
734 static const struct clk_parent_data div_mux_parent_data
[][2] = {
736 { .hw
= &clk_pll
[VC3_PLL1
].hw
},
740 { .hw
= &clk_pll
[VC3_PLL2
].hw
},
741 { .hw
= &clk_pll
[VC3_PLL3
].hw
}
744 { .hw
= &clk_pll
[VC3_PLL2
].hw
},
749 static struct vc3_hw_data clk_div_mux
[] = {
751 .data
= &(struct vc3_clk_data
) {
752 .offs
= VC3_GENERAL_CTR
,
753 .bitmsk
= VC3_GENERAL_CTR_DIV1_SRC_SEL
755 .hw
.init
= &(struct clk_init_data
) {
757 .ops
= &vc3_div_mux_ops
,
758 .parent_data
= div_mux_parent_data
[VC3_DIV1_MUX
],
760 .flags
= CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT
764 .data
= &(struct vc3_clk_data
) {
765 .offs
= VC3_PLL3_CHARGE_PUMP_CTRL
,
766 .bitmsk
= VC3_PLL3_CHARGE_PUMP_CTRL_OUTDIV3_SRC_SEL
768 .hw
.init
= &(struct clk_init_data
) {
770 .ops
= &vc3_div_mux_ops
,
771 .parent_data
= div_mux_parent_data
[VC3_DIV3_MUX
],
773 .flags
= CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT
777 .data
= &(struct vc3_clk_data
) {
778 .offs
= VC3_OUTPUT_CTR
,
779 .bitmsk
= VC3_OUTPUT_CTR_DIV4_SRC_SEL
781 .hw
.init
= &(struct clk_init_data
) {
783 .ops
= &vc3_div_mux_ops
,
784 .parent_data
= div_mux_parent_data
[VC3_DIV4_MUX
],
786 .flags
= CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT
791 static struct vc3_hw_data clk_div
[] = {
793 .data
= &(struct vc3_div_data
) {
794 .offs
= VC3_OUT_DIV1_DIV2_CTRL
,
798 .flags
= CLK_DIVIDER_READ_ONLY
800 .hw
.init
= &(struct clk_init_data
) {
803 .parent_hws
= (const struct clk_hw
*[]) {
804 &clk_div_mux
[VC3_DIV1_MUX
].hw
807 .flags
= CLK_SET_RATE_PARENT
811 .data
= &(struct vc3_div_data
) {
812 .offs
= VC3_OUT_DIV1_DIV2_CTRL
,
813 .table
= div245_divs
,
816 .flags
= CLK_DIVIDER_READ_ONLY
818 .hw
.init
= &(struct clk_init_data
) {
821 .parent_hws
= (const struct clk_hw
*[]) {
822 &clk_pll
[VC3_PLL1
].hw
825 .flags
= CLK_SET_RATE_PARENT
829 .data
= &(struct vc3_div_data
) {
830 .offs
= VC3_OUT_DIV3_DIV4_CTRL
,
834 .flags
= CLK_DIVIDER_READ_ONLY
836 .hw
.init
= &(struct clk_init_data
) {
839 .parent_hws
= (const struct clk_hw
*[]) {
840 &clk_div_mux
[VC3_DIV3_MUX
].hw
843 .flags
= CLK_SET_RATE_PARENT
847 .data
= &(struct vc3_div_data
) {
848 .offs
= VC3_OUT_DIV3_DIV4_CTRL
,
849 .table
= div245_divs
,
852 .flags
= CLK_DIVIDER_READ_ONLY
854 .hw
.init
= &(struct clk_init_data
) {
857 .parent_hws
= (const struct clk_hw
*[]) {
858 &clk_div_mux
[VC3_DIV4_MUX
].hw
861 .flags
= CLK_SET_RATE_PARENT
865 .data
= &(struct vc3_div_data
) {
866 .offs
= VC3_PLL1_CTRL_OUTDIV5
,
867 .table
= div245_divs
,
870 .flags
= CLK_DIVIDER_READ_ONLY
872 .hw
.init
= &(struct clk_init_data
) {
875 .parent_hws
= (const struct clk_hw
*[]) {
876 &clk_pll
[VC3_PLL3
].hw
879 .flags
= CLK_SET_RATE_PARENT
884 static struct vc3_hw_data clk_mux
[] = {
886 .data
= &(struct vc3_clk_data
) {
887 .offs
= VC3_SE1_DIV4_CTRL
,
888 .bitmsk
= VC3_SE1_DIV4_CTRL_SE1_CLK_SEL
890 .hw
.init
= &(struct clk_init_data
) {
892 .ops
= &vc3_clk_mux_ops
,
893 .parent_hws
= (const struct clk_hw
*[]) {
894 &clk_div
[VC3_DIV5
].hw
,
895 &clk_div
[VC3_DIV4
].hw
898 .flags
= CLK_SET_RATE_PARENT
902 .data
= &(struct vc3_clk_data
) {
903 .offs
= VC3_SE2_CTRL_REG0
,
904 .bitmsk
= VC3_SE2_CTRL_REG0_SE2_CLK_SEL
906 .hw
.init
= &(struct clk_init_data
) {
908 .ops
= &vc3_clk_mux_ops
,
909 .parent_hws
= (const struct clk_hw
*[]) {
910 &clk_div
[VC3_DIV5
].hw
,
911 &clk_div
[VC3_DIV4
].hw
914 .flags
= CLK_SET_RATE_PARENT
918 .data
= &(struct vc3_clk_data
) {
919 .offs
= VC3_SE3_DIFF1_CTRL_REG
,
920 .bitmsk
= VC3_SE3_DIFF1_CTRL_REG_SE3_CLK_SEL
922 .hw
.init
= &(struct clk_init_data
) {
924 .ops
= &vc3_clk_mux_ops
,
925 .parent_hws
= (const struct clk_hw
*[]) {
926 &clk_div
[VC3_DIV2
].hw
,
927 &clk_div
[VC3_DIV4
].hw
930 .flags
= CLK_SET_RATE_PARENT
934 .data
= &(struct vc3_clk_data
) {
935 .offs
= VC3_DIFF1_CTRL_REG
,
936 .bitmsk
= VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL
938 .hw
.init
= &(struct clk_init_data
) {
940 .ops
= &vc3_clk_mux_ops
,
941 .parent_hws
= (const struct clk_hw
*[]) {
942 &clk_div
[VC3_DIV1
].hw
,
943 &clk_div
[VC3_DIV3
].hw
946 .flags
= CLK_SET_RATE_PARENT
950 .data
= &(struct vc3_clk_data
) {
951 .offs
= VC3_DIFF2_CTRL_REG
,
952 .bitmsk
= VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL
954 .hw
.init
= &(struct clk_init_data
) {
956 .ops
= &vc3_clk_mux_ops
,
957 .parent_hws
= (const struct clk_hw
*[]) {
958 &clk_div
[VC3_DIV1
].hw
,
959 &clk_div
[VC3_DIV3
].hw
962 .flags
= CLK_SET_RATE_PARENT
967 static struct clk_hw
*vc3_of_clk_get(struct of_phandle_args
*clkspec
,
970 unsigned int idx
= clkspec
->args
[0];
971 struct clk_hw
**clkout_hw
= data
;
973 if (idx
>= ARRAY_SIZE(clk_out
)) {
974 pr_err("invalid clk index %u for provider %pOF\n", idx
, clkspec
->np
);
975 return ERR_PTR(-EINVAL
);
978 return clkout_hw
[idx
];
981 static int vc3_probe(struct i2c_client
*client
)
983 struct device
*dev
= &client
->dev
;
984 u8 settings
[NUM_CONFIG_REGISTERS
];
985 struct regmap
*regmap
;
989 regmap
= devm_regmap_init_i2c(client
, &vc3_regmap_config
);
991 return dev_err_probe(dev
, PTR_ERR(regmap
),
992 "failed to allocate register map\n");
994 ret
= of_property_read_u8_array(dev
->of_node
, "renesas,settings",
995 settings
, ARRAY_SIZE(settings
));
998 * A raw settings array was specified in the DT. Write the
999 * settings to the device immediately.
1001 for (i
= 0; i
< NUM_CONFIG_REGISTERS
; i
++) {
1002 ret
= regmap_write(regmap
, i
, settings
[i
]);
1004 dev_err(dev
, "error writing to chip (%i)\n", ret
);
1008 } else if (ret
== -EOVERFLOW
) {
1009 dev_err(&client
->dev
, "EOVERFLOW reg settings. ARRAY_SIZE: %zu\n",
1010 ARRAY_SIZE(settings
));
1014 /* Register pfd muxes */
1015 for (i
= 0; i
< ARRAY_SIZE(clk_pfd_mux
); i
++) {
1016 clk_pfd_mux
[i
].regmap
= regmap
;
1017 ret
= devm_clk_hw_register(dev
, &clk_pfd_mux
[i
].hw
);
1019 return dev_err_probe(dev
, ret
, "%s failed\n",
1020 clk_pfd_mux
[i
].hw
.init
->name
);
1023 /* Register pfd's */
1024 for (i
= 0; i
< ARRAY_SIZE(clk_pfd
); i
++) {
1025 clk_pfd
[i
].regmap
= regmap
;
1026 ret
= devm_clk_hw_register(dev
, &clk_pfd
[i
].hw
);
1028 return dev_err_probe(dev
, ret
, "%s failed\n",
1029 clk_pfd
[i
].hw
.init
->name
);
1032 /* Register pll's */
1033 for (i
= 0; i
< ARRAY_SIZE(clk_pll
); i
++) {
1034 clk_pll
[i
].regmap
= regmap
;
1035 ret
= devm_clk_hw_register(dev
, &clk_pll
[i
].hw
);
1037 return dev_err_probe(dev
, ret
, "%s failed\n",
1038 clk_pll
[i
].hw
.init
->name
);
1041 /* Register divider muxes */
1042 for (i
= 0; i
< ARRAY_SIZE(clk_div_mux
); i
++) {
1043 clk_div_mux
[i
].regmap
= regmap
;
1044 ret
= devm_clk_hw_register(dev
, &clk_div_mux
[i
].hw
);
1046 return dev_err_probe(dev
, ret
, "%s failed\n",
1047 clk_div_mux
[i
].hw
.init
->name
);
1050 /* Register dividers */
1051 for (i
= 0; i
< ARRAY_SIZE(clk_div
); i
++) {
1052 clk_div
[i
].regmap
= regmap
;
1053 ret
= devm_clk_hw_register(dev
, &clk_div
[i
].hw
);
1055 return dev_err_probe(dev
, ret
, "%s failed\n",
1056 clk_div
[i
].hw
.init
->name
);
1059 /* Register clk muxes */
1060 for (i
= 0; i
< ARRAY_SIZE(clk_mux
); i
++) {
1061 clk_mux
[i
].regmap
= regmap
;
1062 ret
= devm_clk_hw_register(dev
, &clk_mux
[i
].hw
);
1064 return dev_err_probe(dev
, ret
, "%s failed\n",
1065 clk_mux
[i
].hw
.init
->name
);
1068 /* Register clk outputs */
1069 for (i
= 0; i
< ARRAY_SIZE(clk_out
); i
++) {
1090 return dev_err_probe(dev
, -EINVAL
, "invalid clk output %d\n", i
);
1094 clk_out
[i
] = devm_clk_hw_register_fixed_factor_index(dev
,
1095 name
, 0, CLK_SET_RATE_PARENT
, 1, 1);
1097 clk_out
[i
] = devm_clk_hw_register_fixed_factor_parent_hw(dev
,
1098 name
, &clk_mux
[i
- 1].hw
, CLK_SET_RATE_PARENT
, 1, 1);
1100 if (IS_ERR(clk_out
[i
]))
1101 return PTR_ERR(clk_out
[i
]);
1104 ret
= devm_of_clk_add_hw_provider(dev
, vc3_of_clk_get
, clk_out
);
1106 return dev_err_probe(dev
, ret
, "unable to add clk provider\n");
1111 static const struct of_device_id dev_ids
[] = {
1112 { .compatible
= "renesas,5p35023" },
1115 MODULE_DEVICE_TABLE(of
, dev_ids
);
1117 static struct i2c_driver vc3_driver
= {
1120 .of_match_table
= of_match_ptr(dev_ids
),
1124 module_i2c_driver(vc3_driver
);
1126 MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
1127 MODULE_DESCRIPTION("Renesas VersaClock 3 driver");
1128 MODULE_LICENSE("GPL");