1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
3 * Copyright (C) Sunplus Technology Co., Ltd.
6 #include <linux/module.h>
7 #include <linux/clk-provider.h>
9 #include <linux/bitfield.h>
10 #include <linux/slab.h>
12 #include <linux/err.h>
13 #include <linux/platform_device.h>
15 #include <dt-bindings/clock/sunplus,sp7021-clkc.h>
17 /* speical div_width values for PLLTV/PLLA */
21 /* PLLTV parameters */
33 #define MASK_SEL_FRA GENMASK(1, 1)
34 #define MASK_SDM_MOD GENMASK(2, 2)
35 #define MASK_PH_SEL GENMASK(4, 4)
36 #define MASK_NFRA GENMASK(12, 6)
37 #define MASK_DIVR GENMASK(8, 7)
38 #define MASK_DIVN GENMASK(7, 0)
39 #define MASK_DIVM GENMASK(14, 8)
41 /* HIWORD_MASK FIELD_PREP */
42 #define HWM_FIELD_PREP(mask, value) \
45 (_m << 16) | FIELD_PREP(_m, value); \
51 spinlock_t lock
; /* lock for reg */
54 int pd_bit
; /* power down bit idx */
55 int bp_bit
; /* bypass bit idx */
56 unsigned long brate
; /* base rate, TODO: replace brate with muldiv */
57 u32 p
[P_MAX
]; /* for hold PLLTV/PLLA parameters */
60 #define to_sp_pll(_hw) container_of(_hw, struct sp_pll, hw)
62 struct sp_clk_gate_info
{
63 u16 reg
; /* reg_index_shift */
64 u16 ext_parent
; /* parent is extclk */
67 static const struct sp_clk_gate_info sp_clk_gates
[] = {
135 #define F_27M (27 * _M)
137 /*********************************** PLL_TV **********************************/
139 /* TODO: set proper FVCO range */
140 #define FVCO_MIN (100 * _M)
141 #define FVCO_MAX (200 * _M)
143 #define F_MIN (FVCO_MIN / 8)
144 #define F_MAX (FVCO_MAX)
146 static long plltv_integer_div(struct sp_pll
*clk
, unsigned long freq
)
148 /* valid m values: 27M must be divisible by m */
149 static const u32 m_table
[] = {
150 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32
153 unsigned long fvco
, nf
;
156 freq
= clamp(freq
, F_MIN
, F_MAX
);
159 for (r
= 0; r
<= 3; r
++) {
161 if (fvco
<= FVCO_MAX
)
166 for (m
= 0; m
< ARRAY_SIZE(m_table
); m
++) {
167 nf
= fvco
* m_table
[m
];
169 if ((n
* F_27M
) == nf
)
172 if (m
>= ARRAY_SIZE(m_table
)) {
177 /* save parameters */
181 clk
->p
[DIVM
] = m_table
[m
];
186 pr_err("%s: %s freq:%lu not found a valid setting\n",
187 __func__
, clk_hw_get_name(&clk
->hw
), freq
);
192 /* parameters for PLLTV fractional divider */
193 static const u32 pt
[][5] = {
194 /* conventional fractional */
197 5, /* 5 * p0 (nint) */
199 F_27M
, /* F_27M / p0 */
205 54, /* 5.4 * p0 (nint) */
207 F_27M
/ 10, /* F_27M / p0 */
212 static const u32 sdm_mod_vals
[] = { 91, 55 };
214 static long plltv_fractional_div(struct sp_pll
*clk
, unsigned long freq
)
218 u32 df_quotient_min
= 210000000;
219 u32 df_remainder_min
= 0;
220 unsigned long fvco
, nf
, f
, fout
= 0;
223 freq
= clamp(freq
, F_MIN
, F_MAX
);
226 for (r
= 0; r
<= 3; r
++) {
228 if (fvco
<= FVCO_MAX
)
234 for (ph
= ARRAY_SIZE(pt
) - 1; ph
>= 0; ph
--) {
235 const u32
*pp
= pt
[ph
];
238 for (sdm
= 0; sdm
< ARRAY_SIZE(sdm_mod_vals
); sdm
++) {
239 u32 mod
= sdm_mod_vals
[sdm
];
242 for (m
= 1; m
<= 32; m
++) {
243 u32 df
; /* diff freq */
244 u32 df_quotient
, df_remainder
;
254 nfra
= (((nf
% pp
[3]) * mod
* pp
[4]) + (F_27M
/ 2)) / F_27M
;
256 u32 df0
= f
* (nint
+ pp
[2]) / pp
[0];
257 u32 df1
= f
* (mod
- nfra
) / mod
/ pp
[4];
261 df
= f
* (nint
) / pp
[0];
264 df_quotient
= df
/ m
;
265 df_remainder
= ((df
% m
) * 1000) / m
;
267 if (freq
> df_quotient
) {
268 df_quotient
= freq
- df_quotient
- 1;
269 df_remainder
= 1000 - df_remainder
;
271 df_quotient
= df_quotient
- freq
;
274 if (df_quotient_min
> df_quotient
||
275 (df_quotient_min
== df_quotient
&&
276 df_remainder_min
> df_remainder
)) {
277 /* found a closer freq, save parameters */
279 clk
->p
[SDM_MOD
] = sdm
;
286 df_quotient_min
= df_quotient
;
287 df_remainder_min
= df_remainder
;
294 pr_err("%s: %s freq:%lu not found a valid setting\n",
295 __func__
, clk_hw_get_name(&clk
->hw
), freq
);
302 static long plltv_div(struct sp_pll
*clk
, unsigned long freq
)
305 return plltv_fractional_div(clk
, freq
);
307 return plltv_integer_div(clk
, freq
);
310 static int plltv_set_rate(struct sp_pll
*clk
)
315 r0
= BIT(clk
->bp_bit
+ 16);
316 r0
|= HWM_FIELD_PREP(MASK_SEL_FRA
, clk
->p
[SEL_FRA
]);
317 r0
|= HWM_FIELD_PREP(MASK_SDM_MOD
, clk
->p
[SDM_MOD
]);
318 r0
|= HWM_FIELD_PREP(MASK_PH_SEL
, clk
->p
[PH_SEL
]);
319 r0
|= HWM_FIELD_PREP(MASK_NFRA
, clk
->p
[NFRA
]);
321 r1
= HWM_FIELD_PREP(MASK_DIVR
, clk
->p
[DIVR
]);
323 r2
= HWM_FIELD_PREP(MASK_DIVN
, clk
->p
[DIVN
] - 1);
324 r2
|= HWM_FIELD_PREP(MASK_DIVM
, clk
->p
[DIVM
] - 1);
326 spin_lock_irqsave(&clk
->lock
, flags
);
327 writel(r0
, clk
->reg
);
328 writel(r1
, clk
->reg
+ 4);
329 writel(r2
, clk
->reg
+ 8);
330 spin_unlock_irqrestore(&clk
->lock
, flags
);
335 /*********************************** PLL_A ***********************************/
337 /* from Q628_PLLs_REG_setting.xlsx */
338 static const struct {
374 static int plla_set_rate(struct sp_pll
*clk
)
376 const u32
*pp
= pa
[clk
->p
[0]].regs
;
380 spin_lock_irqsave(&clk
->lock
, flags
);
381 for (i
= 0; i
< ARRAY_SIZE(pa
->regs
); i
++)
382 writel(0xffff0000 | pp
[i
], clk
->reg
+ (i
* 4));
383 spin_unlock_irqrestore(&clk
->lock
, flags
);
388 static long plla_round_rate(struct sp_pll
*clk
, unsigned long rate
)
390 int i
= ARRAY_SIZE(pa
);
393 if (rate
>= pa
[i
].rate
)
401 /********************************** SP_PLL ***********************************/
403 static long sp_pll_calc_div(struct sp_pll
*clk
, unsigned long rate
)
406 u32 max
= 1 << clk
->div_width
;
408 fbdiv
= DIV_ROUND_CLOSEST(rate
, clk
->brate
);
415 static long sp_pll_round_rate(struct clk_hw
*hw
, unsigned long rate
,
416 unsigned long *prate
)
418 struct sp_pll
*clk
= to_sp_pll(hw
);
421 if (rate
== *prate
) {
422 ret
= *prate
; /* bypass */
423 } else if (clk
->div_width
== DIV_A
) {
424 ret
= plla_round_rate(clk
, rate
);
425 } else if (clk
->div_width
== DIV_TV
) {
426 ret
= plltv_div(clk
, rate
);
430 ret
= sp_pll_calc_div(clk
, rate
) * clk
->brate
;
436 static unsigned long sp_pll_recalc_rate(struct clk_hw
*hw
,
439 struct sp_pll
*clk
= to_sp_pll(hw
);
440 u32 reg
= readl(clk
->reg
);
443 if (reg
& BIT(clk
->bp_bit
)) {
444 ret
= prate
; /* bypass */
445 } else if (clk
->div_width
== DIV_A
) {
446 ret
= pa
[clk
->p
[0]].rate
;
447 } else if (clk
->div_width
== DIV_TV
) {
450 r
= FIELD_GET(MASK_DIVR
, readl(clk
->reg
+ 4));
451 reg2
= readl(clk
->reg
+ 8);
452 m
= FIELD_GET(MASK_DIVM
, reg2
) + 1;
454 if (reg
& MASK_SEL_FRA
) {
455 /* fractional divider */
456 u32 sdm
= FIELD_GET(MASK_SDM_MOD
, reg
);
457 u32 ph
= FIELD_GET(MASK_PH_SEL
, reg
);
458 u32 nfra
= FIELD_GET(MASK_NFRA
, reg
);
459 const u32
*pp
= pt
[ph
];
460 unsigned long r0
, r1
;
463 r0
= ret
* (pp
[1] + pp
[2]) / pp
[0];
464 r1
= ret
* (sdm_mod_vals
[sdm
] - nfra
) / sdm_mod_vals
[sdm
] / pp
[4];
467 /* integer divider */
468 u32 n
= FIELD_GET(MASK_DIVN
, reg2
) + 1;
470 ret
= (prate
/ m
* n
) >> r
;
473 u32 fbdiv
= ((reg
>> clk
->div_shift
) & ((1 << clk
->div_width
) - 1)) + 1;
475 ret
= clk
->brate
* fbdiv
;
481 static int sp_pll_set_rate(struct clk_hw
*hw
, unsigned long rate
,
484 struct sp_pll
*clk
= to_sp_pll(hw
);
488 reg
= BIT(clk
->bp_bit
+ 16); /* HIWORD_MASK */
491 reg
|= BIT(clk
->bp_bit
); /* bypass */
492 } else if (clk
->div_width
== DIV_A
) {
493 return plla_set_rate(clk
);
494 } else if (clk
->div_width
== DIV_TV
) {
495 return plltv_set_rate(clk
);
496 } else if (clk
->div_width
) {
497 u32 fbdiv
= sp_pll_calc_div(clk
, rate
);
498 u32 mask
= GENMASK(clk
->div_shift
+ clk
->div_width
- 1, clk
->div_shift
);
501 reg
|= ((fbdiv
- 1) << clk
->div_shift
) & mask
;
504 spin_lock_irqsave(&clk
->lock
, flags
);
505 writel(reg
, clk
->reg
);
506 spin_unlock_irqrestore(&clk
->lock
, flags
);
511 static int sp_pll_enable(struct clk_hw
*hw
)
513 struct sp_pll
*clk
= to_sp_pll(hw
);
515 writel(BIT(clk
->pd_bit
+ 16) | BIT(clk
->pd_bit
), clk
->reg
);
520 static void sp_pll_disable(struct clk_hw
*hw
)
522 struct sp_pll
*clk
= to_sp_pll(hw
);
524 writel(BIT(clk
->pd_bit
+ 16), clk
->reg
);
527 static int sp_pll_is_enabled(struct clk_hw
*hw
)
529 struct sp_pll
*clk
= to_sp_pll(hw
);
531 return readl(clk
->reg
) & BIT(clk
->pd_bit
);
534 static const struct clk_ops sp_pll_ops
= {
535 .enable
= sp_pll_enable
,
536 .disable
= sp_pll_disable
,
537 .is_enabled
= sp_pll_is_enabled
,
538 .round_rate
= sp_pll_round_rate
,
539 .recalc_rate
= sp_pll_recalc_rate
,
540 .set_rate
= sp_pll_set_rate
543 static const struct clk_ops sp_pll_sub_ops
= {
544 .enable
= sp_pll_enable
,
545 .disable
= sp_pll_disable
,
546 .is_enabled
= sp_pll_is_enabled
,
547 .recalc_rate
= sp_pll_recalc_rate
,
550 static struct clk_hw
*sp_pll_register(struct device
*dev
, const char *name
,
551 const struct clk_parent_data
*parent_data
,
552 void __iomem
*reg
, int pd_bit
, int bp_bit
,
553 unsigned long brate
, int shift
, int width
,
558 struct clk_init_data initd
= {
560 .parent_data
= parent_data
,
561 .ops
= (bp_bit
>= 0) ? &sp_pll_ops
: &sp_pll_sub_ops
,
567 pll
= devm_kzalloc(dev
, sizeof(*pll
), GFP_KERNEL
);
569 return ERR_PTR(-ENOMEM
);
571 pll
->hw
.init
= &initd
;
573 pll
->pd_bit
= pd_bit
;
574 pll
->bp_bit
= bp_bit
;
576 pll
->div_shift
= shift
;
577 pll
->div_width
= width
;
578 spin_lock_init(&pll
->lock
);
581 ret
= devm_clk_hw_register(dev
, hw
);
588 #define PLLA_CTL (pll_base + 0x1c)
589 #define PLLE_CTL (pll_base + 0x30)
590 #define PLLF_CTL (pll_base + 0x34)
591 #define PLLTV_CTL (pll_base + 0x38)
593 static int sp7021_clk_probe(struct platform_device
*pdev
)
595 static const u32 sp_clken
[] = {
596 0x67ef, 0x03ff, 0xff03, 0xfff0, 0x0004, /* G0.1~5 */
597 0x0000, 0x8000, 0xffff, 0x0040, 0x0000, /* G0.6~10 */
599 static struct clk_parent_data pd_ext
, pd_sys
, pd_e
;
600 struct device
*dev
= &pdev
->dev
;
601 void __iomem
*clk_base
, *pll_base
, *sys_base
;
602 struct clk_hw_onecell_data
*clk_data
;
606 clk_base
= devm_platform_ioremap_resource(pdev
, 0);
607 if (IS_ERR(clk_base
))
608 return PTR_ERR(clk_base
);
609 pll_base
= devm_platform_ioremap_resource(pdev
, 1);
610 if (IS_ERR(pll_base
))
611 return PTR_ERR(pll_base
);
612 sys_base
= devm_platform_ioremap_resource(pdev
, 2);
613 if (IS_ERR(sys_base
))
614 return PTR_ERR(sys_base
);
616 /* enable default clks */
617 for (i
= 0; i
< ARRAY_SIZE(sp_clken
); i
++)
618 writel((sp_clken
[i
] << 16) | sp_clken
[i
], clk_base
+ i
* 4);
620 clk_data
= devm_kzalloc(dev
, struct_size(clk_data
, hws
, CLK_MAX
),
624 clk_data
->num
= CLK_MAX
;
630 hws
[PLL_A
] = sp_pll_register(dev
, "plla", &pd_ext
, PLLA_CTL
,
631 11, 12, 27000000, 0, DIV_A
, 0);
632 if (IS_ERR(hws
[PLL_A
]))
633 return PTR_ERR(hws
[PLL_A
]);
635 hws
[PLL_E
] = sp_pll_register(dev
, "plle", &pd_ext
, PLLE_CTL
,
636 6, 2, 50000000, 0, 0, 0);
637 if (IS_ERR(hws
[PLL_E
]))
638 return PTR_ERR(hws
[PLL_E
]);
639 pd_e
.hw
= hws
[PLL_E
];
640 hws
[PLL_E_2P5
] = sp_pll_register(dev
, "plle_2p5", &pd_e
, PLLE_CTL
,
641 13, -1, 2500000, 0, 0, 0);
642 if (IS_ERR(hws
[PLL_E_2P5
]))
643 return PTR_ERR(hws
[PLL_E_2P5
]);
644 hws
[PLL_E_25
] = sp_pll_register(dev
, "plle_25", &pd_e
, PLLE_CTL
,
645 12, -1, 25000000, 0, 0, 0);
646 if (IS_ERR(hws
[PLL_E_25
]))
647 return PTR_ERR(hws
[PLL_E_25
]);
648 hws
[PLL_E_112P5
] = sp_pll_register(dev
, "plle_112p5", &pd_e
, PLLE_CTL
,
649 11, -1, 112500000, 0, 0, 0);
650 if (IS_ERR(hws
[PLL_E_112P5
]))
651 return PTR_ERR(hws
[PLL_E_112P5
]);
653 hws
[PLL_F
] = sp_pll_register(dev
, "pllf", &pd_ext
, PLLF_CTL
,
654 0, 10, 13500000, 1, 4, 0);
655 if (IS_ERR(hws
[PLL_F
]))
656 return PTR_ERR(hws
[PLL_F
]);
658 hws
[PLL_TV
] = sp_pll_register(dev
, "plltv", &pd_ext
, PLLTV_CTL
,
659 0, 15, 27000000, 0, DIV_TV
, 0);
660 if (IS_ERR(hws
[PLL_TV
]))
661 return PTR_ERR(hws
[PLL_TV
]);
662 hws
[PLL_TV_A
] = devm_clk_hw_register_divider(dev
, "plltv_a", "plltv", 0,
664 CLK_DIVIDER_POWER_OF_TWO
,
665 &to_sp_pll(hws
[PLL_TV
])->lock
);
666 if (IS_ERR(hws
[PLL_TV_A
]))
667 return PTR_ERR(hws
[PLL_TV_A
]);
669 /* system clock, should not be disabled */
670 hws
[PLL_SYS
] = sp_pll_register(dev
, "pllsys", &pd_ext
, sys_base
,
671 10, 9, 13500000, 0, 4, CLK_IS_CRITICAL
);
672 if (IS_ERR(hws
[PLL_SYS
]))
673 return PTR_ERR(hws
[PLL_SYS
]);
674 pd_sys
.hw
= hws
[PLL_SYS
];
677 for (i
= 0; i
< ARRAY_SIZE(sp_clk_gates
); i
++) {
679 u32 j
= sp_clk_gates
[i
].reg
;
680 struct clk_parent_data
*pd
= sp_clk_gates
[i
].ext_parent
? &pd_ext
: &pd_sys
;
682 sprintf(name
, "%02d_0x%02x", i
, j
);
683 hws
[i
] = devm_clk_hw_register_gate_parent_data(dev
, name
, pd
, 0,
684 clk_base
+ (j
>> 4) * 4,
686 CLK_GATE_HIWORD_MASK
,
689 return PTR_ERR(hws
[i
]);
692 return devm_of_clk_add_hw_provider(dev
, of_clk_hw_onecell_get
, clk_data
);
695 static const struct of_device_id sp7021_clk_dt_ids
[] = {
696 { .compatible
= "sunplus,sp7021-clkc" },
699 MODULE_DEVICE_TABLE(of
, sp7021_clk_dt_ids
);
701 static struct platform_driver sp7021_clk_driver
= {
702 .probe
= sp7021_clk_probe
,
704 .name
= "sp7021-clk",
705 .of_match_table
= sp7021_clk_dt_ids
,
708 module_platform_driver(sp7021_clk_driver
);
710 MODULE_AUTHOR("Sunplus Technology");
711 MODULE_LICENSE("GPL");
712 MODULE_DESCRIPTION("Clock driver for Sunplus SP7021 SoC");