Message ID | 20180717095617.12240-3-jbrunet@baylibre.com |
---|---|
State | New |
Headers | show |
Series | clk: meson: clk-pll driver update | expand |
On 17/07/2018 11:56, Jerome Brunet wrote: > Remove od parameters from pll clocks and add post dividers clocks > instead. Some clock, especially the one which feature several ods, > may provide output between those ods. Also, some drivers, such > as the hdmi driver, may require a more detailed control of the > clock dividers, compared to what CCF would perform automatically. > > One added benefit of removing ods is that it also greatly reduce the > size of the rate parameter tables. > > In the future, we could possibly take the predivider 'n' out of this > driver as well. To do so, we will need to understand the constraints > for the PLL to lock and whether or not it depends on the input clock > rate. > > Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> > --- > drivers/clk/meson/axg.c | 279 ++++++++++++++------------ > drivers/clk/meson/axg.h | 8 +- > drivers/clk/meson/clk-pll.c | 40 ++-- > drivers/clk/meson/clkc.h | 9 +- > drivers/clk/meson/gxbb.c | 474 +++++++++++++++++++++----------------------- > drivers/clk/meson/gxbb.h | 10 +- > drivers/clk/meson/meson8b.c | 148 +++++++------- > drivers/clk/meson/meson8b.h | 5 +- > 8 files changed, 480 insertions(+), 493 deletions(-) > > diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c > index 6d8976554656..572358062459 100644 > --- a/drivers/clk/meson/axg.c > +++ b/drivers/clk/meson/axg.c > @@ -22,7 +22,7 @@ > > static DEFINE_SPINLOCK(meson_clk_lock); > > -static struct clk_regmap axg_fixed_pll = { > +static struct clk_regmap axg_fixed_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_MPLL_CNTL, > @@ -39,11 +39,6 @@ static struct clk_regmap axg_fixed_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_MPLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_MPLL_CNTL2, > .shift = 0, > @@ -61,14 +56,29 @@ static struct clk_regmap axg_fixed_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "fixed_pll", > + .name = "fixed_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > }, > }; > > -static struct clk_regmap axg_sys_pll = { > +static struct clk_regmap axg_fixed_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_MPLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "fixed_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "fixed_pll_dco" }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap axg_sys_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_SYS_PLL_CNTL, > @@ -85,11 +95,6 @@ static struct clk_regmap axg_sys_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_SYS_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .l = { > .reg_off = HHI_SYS_PLL_CNTL, > .shift = 31, > @@ -102,7 +107,7 @@ static struct clk_regmap axg_sys_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "sys_pll", > + .name = "sys_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > @@ -110,94 +115,51 @@ static struct clk_regmap axg_sys_pll = { > }, > }; > > +static struct clk_regmap axg_sys_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_SYS_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sys_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "sys_pll_dco" }, > + .num_parents = 1, > + }, > +}; > + > static const struct pll_rate_table axg_gp0_pll_rate_table[] = { > - PLL_RATE(240000000, 40, 1, 2), > - PLL_RATE(246000000, 41, 1, 2), > - PLL_RATE(252000000, 42, 1, 2), > - PLL_RATE(258000000, 43, 1, 2), > - PLL_RATE(264000000, 44, 1, 2), > - PLL_RATE(270000000, 45, 1, 2), > - PLL_RATE(276000000, 46, 1, 2), > - PLL_RATE(282000000, 47, 1, 2), > - PLL_RATE(288000000, 48, 1, 2), > - PLL_RATE(294000000, 49, 1, 2), > - PLL_RATE(300000000, 50, 1, 2), > - PLL_RATE(306000000, 51, 1, 2), > - PLL_RATE(312000000, 52, 1, 2), > - PLL_RATE(318000000, 53, 1, 2), > - PLL_RATE(324000000, 54, 1, 2), > - PLL_RATE(330000000, 55, 1, 2), > - PLL_RATE(336000000, 56, 1, 2), > - PLL_RATE(342000000, 57, 1, 2), > - PLL_RATE(348000000, 58, 1, 2), > - PLL_RATE(354000000, 59, 1, 2), > - PLL_RATE(360000000, 60, 1, 2), > - PLL_RATE(366000000, 61, 1, 2), > - PLL_RATE(372000000, 62, 1, 2), > - PLL_RATE(378000000, 63, 1, 2), > - PLL_RATE(384000000, 64, 1, 2), > - PLL_RATE(390000000, 65, 1, 3), > - PLL_RATE(396000000, 66, 1, 3), > - PLL_RATE(402000000, 67, 1, 3), > - PLL_RATE(408000000, 68, 1, 3), > - PLL_RATE(480000000, 40, 1, 1), > - PLL_RATE(492000000, 41, 1, 1), > - PLL_RATE(504000000, 42, 1, 1), > - PLL_RATE(516000000, 43, 1, 1), > - PLL_RATE(528000000, 44, 1, 1), > - PLL_RATE(540000000, 45, 1, 1), > - PLL_RATE(552000000, 46, 1, 1), > - PLL_RATE(564000000, 47, 1, 1), > - PLL_RATE(576000000, 48, 1, 1), > - PLL_RATE(588000000, 49, 1, 1), > - PLL_RATE(600000000, 50, 1, 1), > - PLL_RATE(612000000, 51, 1, 1), > - PLL_RATE(624000000, 52, 1, 1), > - PLL_RATE(636000000, 53, 1, 1), > - PLL_RATE(648000000, 54, 1, 1), > - PLL_RATE(660000000, 55, 1, 1), > - PLL_RATE(672000000, 56, 1, 1), > - PLL_RATE(684000000, 57, 1, 1), > - PLL_RATE(696000000, 58, 1, 1), > - PLL_RATE(708000000, 59, 1, 1), > - PLL_RATE(720000000, 60, 1, 1), > - PLL_RATE(732000000, 61, 1, 1), > - PLL_RATE(744000000, 62, 1, 1), > - PLL_RATE(756000000, 63, 1, 1), > - PLL_RATE(768000000, 64, 1, 1), > - PLL_RATE(780000000, 65, 1, 1), > - PLL_RATE(792000000, 66, 1, 1), > - PLL_RATE(804000000, 67, 1, 1), > - PLL_RATE(816000000, 68, 1, 1), > - PLL_RATE(960000000, 40, 1, 0), > - PLL_RATE(984000000, 41, 1, 0), > - PLL_RATE(1008000000, 42, 1, 0), > - PLL_RATE(1032000000, 43, 1, 0), > - PLL_RATE(1056000000, 44, 1, 0), > - PLL_RATE(1080000000, 45, 1, 0), > - PLL_RATE(1104000000, 46, 1, 0), > - PLL_RATE(1128000000, 47, 1, 0), > - PLL_RATE(1152000000, 48, 1, 0), > - PLL_RATE(1176000000, 49, 1, 0), > - PLL_RATE(1200000000, 50, 1, 0), > - PLL_RATE(1224000000, 51, 1, 0), > - PLL_RATE(1248000000, 52, 1, 0), > - PLL_RATE(1272000000, 53, 1, 0), > - PLL_RATE(1296000000, 54, 1, 0), > - PLL_RATE(1320000000, 55, 1, 0), > - PLL_RATE(1344000000, 56, 1, 0), > - PLL_RATE(1368000000, 57, 1, 0), > - PLL_RATE(1392000000, 58, 1, 0), > - PLL_RATE(1416000000, 59, 1, 0), > - PLL_RATE(1440000000, 60, 1, 0), > - PLL_RATE(1464000000, 61, 1, 0), > - PLL_RATE(1488000000, 62, 1, 0), > - PLL_RATE(1512000000, 63, 1, 0), > - PLL_RATE(1536000000, 64, 1, 0), > - PLL_RATE(1560000000, 65, 1, 0), > - PLL_RATE(1584000000, 66, 1, 0), > - PLL_RATE(1608000000, 67, 1, 0), > - PLL_RATE(1632000000, 68, 1, 0), > + PLL_RATE(960000000, 40, 1), > + PLL_RATE(984000000, 41, 1), > + PLL_RATE(1008000000, 42, 1), > + PLL_RATE(1032000000, 43, 1), > + PLL_RATE(1056000000, 44, 1), > + PLL_RATE(1080000000, 45, 1), > + PLL_RATE(1104000000, 46, 1), > + PLL_RATE(1128000000, 47, 1), > + PLL_RATE(1152000000, 48, 1), > + PLL_RATE(1176000000, 49, 1), > + PLL_RATE(1200000000, 50, 1), > + PLL_RATE(1224000000, 51, 1), > + PLL_RATE(1248000000, 52, 1), > + PLL_RATE(1272000000, 53, 1), > + PLL_RATE(1296000000, 54, 1), > + PLL_RATE(1320000000, 55, 1), > + PLL_RATE(1344000000, 56, 1), > + PLL_RATE(1368000000, 57, 1), > + PLL_RATE(1392000000, 58, 1), > + PLL_RATE(1416000000, 59, 1), > + PLL_RATE(1440000000, 60, 1), > + PLL_RATE(1464000000, 61, 1), > + PLL_RATE(1488000000, 62, 1), > + PLL_RATE(1512000000, 63, 1), > + PLL_RATE(1536000000, 64, 1), > + PLL_RATE(1560000000, 65, 1), > + PLL_RATE(1584000000, 66, 1), > + PLL_RATE(1608000000, 67, 1), > + PLL_RATE(1632000000, 68, 1), > { /* sentinel */ }, > }; > > @@ -209,7 +171,7 @@ static const struct reg_sequence axg_gp0_init_regs[] = { > { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, > }; > > -static struct clk_regmap axg_gp0_pll = { > +static struct clk_regmap axg_gp0_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_GP0_PLL_CNTL, > @@ -226,11 +188,6 @@ static struct clk_regmap axg_gp0_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_GP0_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_GP0_PLL_CNTL1, > .shift = 0, > @@ -251,13 +208,29 @@ static struct clk_regmap axg_gp0_pll = { > .init_count = ARRAY_SIZE(axg_gp0_init_regs), > }, > .hw.init = &(struct clk_init_data){ > - .name = "gp0_pll", > + .name = "gp0_pll_dco", > .ops = &meson_clk_pll_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > }, > }; > > +static struct clk_regmap axg_gp0_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_GP0_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "gp0_pll", > + .ops = &clk_regmap_divider_ops, > + .parent_names = (const char *[]){ "gp0_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > static const struct reg_sequence axg_hifi_init_regs[] = { > { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 }, > { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be }, > @@ -266,7 +239,7 @@ static const struct reg_sequence axg_hifi_init_regs[] = { > { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 }, > }; > > -static struct clk_regmap axg_hifi_pll = { > +static struct clk_regmap axg_hifi_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_HIFI_PLL_CNTL, > @@ -283,11 +256,6 @@ static struct clk_regmap axg_hifi_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_HIFI_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_HIFI_PLL_CNTL5, > .shift = 0, > @@ -309,13 +277,29 @@ static struct clk_regmap axg_hifi_pll = { > .flags = CLK_MESON_PLL_ROUND_CLOSEST, > }, > .hw.init = &(struct clk_init_data){ > - .name = "hifi_pll", > + .name = "hifi_pll_dco", > .ops = &meson_clk_pll_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > }, > }; > > +static struct clk_regmap axg_hifi_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_HIFI_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hifi_pll", > + .ops = &clk_regmap_divider_ops, > + .parent_names = (const char *[]){ "hifi_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > static struct clk_fixed_factor axg_fclk_div2_div = { > .mult = 1, > .div = 2, > @@ -645,11 +629,9 @@ static struct clk_regmap axg_mpll3 = { > > static const struct pll_rate_table axg_pcie_pll_rate_table[] = { > { > - .rate = 100000000, > + .rate = 1600000000, > .m = 200, > .n = 3, > - .od = 1, > - .od2 = 3, > }, > { /* sentinel */ }, > }; > @@ -661,9 +643,10 @@ static const struct reg_sequence axg_pcie_init_regs[] = { > { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d }, > { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 }, > { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 }, > + { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, > }; > > -static struct clk_regmap axg_pcie_pll = { > +static struct clk_regmap axg_pcie_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_PCIE_PLL_CNTL, > @@ -680,16 +663,6 @@ static struct clk_regmap axg_pcie_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_PCIE_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > - .od2 = { > - .reg_off = HHI_PCIE_PLL_CNTL6, > - .shift = 6, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_PCIE_PLL_CNTL1, > .shift = 0, > @@ -710,13 +683,45 @@ static struct clk_regmap axg_pcie_pll = { > .init_count = ARRAY_SIZE(axg_pcie_init_regs), > }, > .hw.init = &(struct clk_init_data){ > - .name = "pcie_pll", > + .name = "pcie_pll_dco", > .ops = &meson_clk_pll_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > }, > }; > > +static struct clk_regmap axg_pcie_pll_od = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_PCIE_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pcie_pll_od", > + .ops = &clk_regmap_divider_ops, > + .parent_names = (const char *[]){ "pcie_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap axg_pcie_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_PCIE_PLL_CNTL6, > + .shift = 6, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pcie_pll", > + .ops = &clk_regmap_divider_ops, > + .parent_names = (const char *[]){ "pcie_pll_od" }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > static struct clk_regmap axg_pcie_mux = { > .data = &(struct clk_regmap_mux_data){ > .offset = HHI_PCIE_PLL_CNTL6, > @@ -1129,6 +1134,12 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = { > [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw, > [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw, > [CLKID_GEN_CLK] = &axg_gen_clk.hw, > + [CLKID_SYS_PLL_DCO] = &axg_sys_pll_dco.hw, > + [CLKID_FIXED_PLL_DCO] = &axg_fixed_pll_dco.hw, > + [CLKID_GP0_PLL_DCO] = &axg_gp0_pll_dco.hw, > + [CLKID_HIFI_PLL_DCO] = &axg_hifi_pll_dco.hw, > + [CLKID_PCIE_PLL_DCO] = &axg_pcie_pll_dco.hw, > + [CLKID_PCIE_PLL_OD] = &axg_pcie_pll_od.hw, > [NR_CLKS] = NULL, > }, > .num = NR_CLKS, > @@ -1207,6 +1218,8 @@ static struct clk_regmap *const axg_clk_regmaps[] = { > &axg_fclk_div4, > &axg_fclk_div5, > &axg_fclk_div7, > + &axg_pcie_pll_dco, > + &axg_pcie_pll_od, > &axg_pcie_pll, > &axg_pcie_mux, > &axg_pcie_ref, > @@ -1216,6 +1229,12 @@ static struct clk_regmap *const axg_clk_regmaps[] = { > &axg_gen_clk_sel, > &axg_gen_clk_div, > &axg_gen_clk, > + &axg_fixed_pll_dco, > + &axg_sys_pll_dco, > + &axg_gp0_pll_dco, > + &axg_hifi_pll_dco, > + &axg_pcie_pll_dco, > + &axg_pcie_pll_od, > }; > > static const struct of_device_id clkc_match_table[] = { > diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h > index 1d04144a1b2c..0431dabac629 100644 > --- a/drivers/clk/meson/axg.h > +++ b/drivers/clk/meson/axg.h > @@ -133,8 +133,14 @@ > #define CLKID_PCIE_REF 78 > #define CLKID_GEN_CLK_SEL 82 > #define CLKID_GEN_CLK_DIV 83 > +#define CLKID_SYS_PLL_DCO 85 > +#define CLKID_FIXED_PLL_DCO 86 > +#define CLKID_GP0_PLL_DCO 87 > +#define CLKID_HIFI_PLL_DCO 88 > +#define CLKID_PCIE_PLL_DCO 89 > +#define CLKID_PCIE_PLL_OD 90 > > -#define NR_CLKS 85 > +#define NR_CLKS 91 > > /* include the CLKIDs that have been made part of the DT binding */ > #include <dt-bindings/clock/axg-clkc.h> > diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c > index 8aaefe67025f..348a866f09eb 100644 > --- a/drivers/clk/meson/clk-pll.c > +++ b/drivers/clk/meson/clk-pll.c > @@ -11,15 +11,19 @@ > * In the most basic form, a Meson PLL is composed as follows: > * > * PLL > - * +------------------------------+ > - * | | > - * in -----[ /N ]---[ *M ]---[ >>OD ]----->> out > - * | ^ ^ | > - * +------------------------------+ > - * | | > - * FREF VCO > + * +--------------------------------+ > + * | | > + * | +--+ | > + * in >>-----[ /N ]--->| | +-----+ | > + * | | |------| DCO |---->> out > + * | +--------->| | +--v--+ | > + * | | +--+ | | > + * | | | | > + * | +--[ *(M + (F/Fmax) ]<--+ | > + * | | > + * +--------------------------------+ > * > - * out = in * (m + frac / frac_max) / (n << sum(ods)) > + * out = in * (m + frac / frac_max) / n > */ > > #include <linux/clk-provider.h> > @@ -46,7 +50,6 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate, > struct meson_clk_pll_data *pll) > { > u64 rate = (u64)parent_rate * pllt->m; > - unsigned int od = pllt->od + pllt->od2 + pllt->od3; > > if (frac && MESON_PARM_APPLICABLE(&pll->frac)) { > u64 frac_rate = (u64)parent_rate * frac; > @@ -55,7 +58,7 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate, > (1 << pll->frac.width)); > } > > - return DIV_ROUND_UP_ULL(rate, pllt->n << od); > + return DIV_ROUND_UP_ULL(rate, pllt->n); > } > > static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, > @@ -68,15 +71,6 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, > > pllt.n = meson_parm_read(clk->map, &pll->n); > pllt.m = meson_parm_read(clk->map, &pll->m); > - pllt.od = meson_parm_read(clk->map, &pll->od); > - > - pllt.od2 = MESON_PARM_APPLICABLE(&pll->od2) ? > - meson_parm_read(clk->map, &pll->od2) : > - 0; > - > - pllt.od3 = MESON_PARM_APPLICABLE(&pll->od3) ? > - meson_parm_read(clk->map, &pll->od3) : > - 0; > > frac = MESON_PARM_APPLICABLE(&pll->frac) ? > meson_parm_read(clk->map, &pll->frac) : > @@ -93,8 +87,6 @@ static u16 __pll_params_with_frac(unsigned long rate, > u16 frac_max = (1 << pll->frac.width); > u64 val = (u64)rate * pllt->n; > > - val <<= pllt->od + pllt->od2 + pllt->od3; > - > if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) > val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate); > else > @@ -242,13 +234,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, > > meson_parm_write(clk->map, &pll->n, pllt->n); > meson_parm_write(clk->map, &pll->m, pllt->m); > - meson_parm_write(clk->map, &pll->od, pllt->od); > - > - if (MESON_PARM_APPLICABLE(&pll->od2)) > - meson_parm_write(clk->map, &pll->od2, pllt->od2); > > - if (MESON_PARM_APPLICABLE(&pll->od3)) > - meson_parm_write(clk->map, &pll->od3, pllt->od3); > > if (MESON_PARM_APPLICABLE(&pll->frac)) { > frac = __pll_params_with_frac(rate, parent_rate, pllt, pll); > diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h > index c2ee37a78ceb..a2245e857f70 100644 > --- a/drivers/clk/meson/clkc.h > +++ b/drivers/clk/meson/clkc.h > @@ -47,17 +47,13 @@ struct pll_rate_table { > unsigned long rate; > u16 m; > u16 n; > - u16 od; > - u16 od2; > - u16 od3; > }; > > -#define PLL_RATE(_r, _m, _n, _od) \ > +#define PLL_RATE(_r, _m, _n) \ > { \ > .rate = (_r), \ > .m = (_m), \ > .n = (_n), \ > - .od = (_od), \ > } > > #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0) > @@ -67,9 +63,6 @@ struct meson_clk_pll_data { > struct parm m; > struct parm n; > struct parm frac; > - struct parm od; > - struct parm od2; > - struct parm od3; > struct parm l; > struct parm rst; > const struct reg_sequence *init_regs; > diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c > index 5ed34566917c..e2d94498f098 100644 > --- a/drivers/clk/meson/gxbb.c > +++ b/drivers/clk/meson/gxbb.c > @@ -19,163 +19,70 @@ > static DEFINE_SPINLOCK(meson_clk_lock); > > static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = { > - PLL_RATE(96000000, 32, 1, 3), > - PLL_RATE(99000000, 33, 1, 3), > - PLL_RATE(102000000, 34, 1, 3), > - PLL_RATE(105000000, 35, 1, 3), > - PLL_RATE(108000000, 36, 1, 3), > - PLL_RATE(111000000, 37, 1, 3), > - PLL_RATE(114000000, 38, 1, 3), > - PLL_RATE(117000000, 39, 1, 3), > - PLL_RATE(120000000, 40, 1, 3), > - PLL_RATE(123000000, 41, 1, 3), > - PLL_RATE(126000000, 42, 1, 3), > - PLL_RATE(129000000, 43, 1, 3), > - PLL_RATE(132000000, 44, 1, 3), > - PLL_RATE(135000000, 45, 1, 3), > - PLL_RATE(138000000, 46, 1, 3), > - PLL_RATE(141000000, 47, 1, 3), > - PLL_RATE(144000000, 48, 1, 3), > - PLL_RATE(147000000, 49, 1, 3), > - PLL_RATE(150000000, 50, 1, 3), > - PLL_RATE(153000000, 51, 1, 3), > - PLL_RATE(156000000, 52, 1, 3), > - PLL_RATE(159000000, 53, 1, 3), > - PLL_RATE(162000000, 54, 1, 3), > - PLL_RATE(165000000, 55, 1, 3), > - PLL_RATE(168000000, 56, 1, 3), > - PLL_RATE(171000000, 57, 1, 3), > - PLL_RATE(174000000, 58, 1, 3), > - PLL_RATE(177000000, 59, 1, 3), > - PLL_RATE(180000000, 60, 1, 3), > - PLL_RATE(183000000, 61, 1, 3), > - PLL_RATE(186000000, 62, 1, 3), > - PLL_RATE(192000000, 32, 1, 2), > - PLL_RATE(198000000, 33, 1, 2), > - PLL_RATE(204000000, 34, 1, 2), > - PLL_RATE(210000000, 35, 1, 2), > - PLL_RATE(216000000, 36, 1, 2), > - PLL_RATE(222000000, 37, 1, 2), > - PLL_RATE(228000000, 38, 1, 2), > - PLL_RATE(234000000, 39, 1, 2), > - PLL_RATE(240000000, 40, 1, 2), > - PLL_RATE(246000000, 41, 1, 2), > - PLL_RATE(252000000, 42, 1, 2), > - PLL_RATE(258000000, 43, 1, 2), > - PLL_RATE(264000000, 44, 1, 2), > - PLL_RATE(270000000, 45, 1, 2), > - PLL_RATE(276000000, 46, 1, 2), > - PLL_RATE(282000000, 47, 1, 2), > - PLL_RATE(288000000, 48, 1, 2), > - PLL_RATE(294000000, 49, 1, 2), > - PLL_RATE(300000000, 50, 1, 2), > - PLL_RATE(306000000, 51, 1, 2), > - PLL_RATE(312000000, 52, 1, 2), > - PLL_RATE(318000000, 53, 1, 2), > - PLL_RATE(324000000, 54, 1, 2), > - PLL_RATE(330000000, 55, 1, 2), > - PLL_RATE(336000000, 56, 1, 2), > - PLL_RATE(342000000, 57, 1, 2), > - PLL_RATE(348000000, 58, 1, 2), > - PLL_RATE(354000000, 59, 1, 2), > - PLL_RATE(360000000, 60, 1, 2), > - PLL_RATE(366000000, 61, 1, 2), > - PLL_RATE(372000000, 62, 1, 2), > - PLL_RATE(384000000, 32, 1, 1), > - PLL_RATE(396000000, 33, 1, 1), > - PLL_RATE(408000000, 34, 1, 1), > - PLL_RATE(420000000, 35, 1, 1), > - PLL_RATE(432000000, 36, 1, 1), > - PLL_RATE(444000000, 37, 1, 1), > - PLL_RATE(456000000, 38, 1, 1), > - PLL_RATE(468000000, 39, 1, 1), > - PLL_RATE(480000000, 40, 1, 1), > - PLL_RATE(492000000, 41, 1, 1), > - PLL_RATE(504000000, 42, 1, 1), > - PLL_RATE(516000000, 43, 1, 1), > - PLL_RATE(528000000, 44, 1, 1), > - PLL_RATE(540000000, 45, 1, 1), > - PLL_RATE(552000000, 46, 1, 1), > - PLL_RATE(564000000, 47, 1, 1), > - PLL_RATE(576000000, 48, 1, 1), > - PLL_RATE(588000000, 49, 1, 1), > - PLL_RATE(600000000, 50, 1, 1), > - PLL_RATE(612000000, 51, 1, 1), > - PLL_RATE(624000000, 52, 1, 1), > - PLL_RATE(636000000, 53, 1, 1), > - PLL_RATE(648000000, 54, 1, 1), > - PLL_RATE(660000000, 55, 1, 1), > - PLL_RATE(672000000, 56, 1, 1), > - PLL_RATE(684000000, 57, 1, 1), > - PLL_RATE(696000000, 58, 1, 1), > - PLL_RATE(708000000, 59, 1, 1), > - PLL_RATE(720000000, 60, 1, 1), > - PLL_RATE(732000000, 61, 1, 1), > - PLL_RATE(744000000, 62, 1, 1), > - PLL_RATE(768000000, 32, 1, 0), > - PLL_RATE(792000000, 33, 1, 0), > - PLL_RATE(816000000, 34, 1, 0), > - PLL_RATE(840000000, 35, 1, 0), > - PLL_RATE(864000000, 36, 1, 0), > - PLL_RATE(888000000, 37, 1, 0), > - PLL_RATE(912000000, 38, 1, 0), > - PLL_RATE(936000000, 39, 1, 0), > - PLL_RATE(960000000, 40, 1, 0), > - PLL_RATE(984000000, 41, 1, 0), > - PLL_RATE(1008000000, 42, 1, 0), > - PLL_RATE(1032000000, 43, 1, 0), > - PLL_RATE(1056000000, 44, 1, 0), > - PLL_RATE(1080000000, 45, 1, 0), > - PLL_RATE(1104000000, 46, 1, 0), > - PLL_RATE(1128000000, 47, 1, 0), > - PLL_RATE(1152000000, 48, 1, 0), > - PLL_RATE(1176000000, 49, 1, 0), > - PLL_RATE(1200000000, 50, 1, 0), > - PLL_RATE(1224000000, 51, 1, 0), > - PLL_RATE(1248000000, 52, 1, 0), > - PLL_RATE(1272000000, 53, 1, 0), > - PLL_RATE(1296000000, 54, 1, 0), > - PLL_RATE(1320000000, 55, 1, 0), > - PLL_RATE(1344000000, 56, 1, 0), > - PLL_RATE(1368000000, 57, 1, 0), > - PLL_RATE(1392000000, 58, 1, 0), > - PLL_RATE(1416000000, 59, 1, 0), > - PLL_RATE(1440000000, 60, 1, 0), > - PLL_RATE(1464000000, 61, 1, 0), > - PLL_RATE(1488000000, 62, 1, 0), > + PLL_RATE(768000000, 32, 1), > + PLL_RATE(792000000, 33, 1), > + PLL_RATE(816000000, 34, 1), > + PLL_RATE(840000000, 35, 1), > + PLL_RATE(864000000, 36, 1), > + PLL_RATE(888000000, 37, 1), > + PLL_RATE(912000000, 38, 1), > + PLL_RATE(936000000, 39, 1), > + PLL_RATE(960000000, 40, 1), > + PLL_RATE(984000000, 41, 1), > + PLL_RATE(1008000000, 42, 1), > + PLL_RATE(1032000000, 43, 1), > + PLL_RATE(1056000000, 44, 1), > + PLL_RATE(1080000000, 45, 1), > + PLL_RATE(1104000000, 46, 1), > + PLL_RATE(1128000000, 47, 1), > + PLL_RATE(1152000000, 48, 1), > + PLL_RATE(1176000000, 49, 1), > + PLL_RATE(1200000000, 50, 1), > + PLL_RATE(1224000000, 51, 1), > + PLL_RATE(1248000000, 52, 1), > + PLL_RATE(1272000000, 53, 1), > + PLL_RATE(1296000000, 54, 1), > + PLL_RATE(1320000000, 55, 1), > + PLL_RATE(1344000000, 56, 1), > + PLL_RATE(1368000000, 57, 1), > + PLL_RATE(1392000000, 58, 1), > + PLL_RATE(1416000000, 59, 1), > + PLL_RATE(1440000000, 60, 1), > + PLL_RATE(1464000000, 61, 1), > + PLL_RATE(1488000000, 62, 1), > { /* sentinel */ }, > }; > > static const struct pll_rate_table gxl_gp0_pll_rate_table[] = { > - PLL_RATE(504000000, 42, 1, 1), > - PLL_RATE(516000000, 43, 1, 1), > - PLL_RATE(528000000, 44, 1, 1), > - PLL_RATE(540000000, 45, 1, 1), > - PLL_RATE(552000000, 46, 1, 1), > - PLL_RATE(564000000, 47, 1, 1), > - PLL_RATE(576000000, 48, 1, 1), > - PLL_RATE(588000000, 49, 1, 1), > - PLL_RATE(600000000, 50, 1, 1), > - PLL_RATE(612000000, 51, 1, 1), > - PLL_RATE(624000000, 52, 1, 1), > - PLL_RATE(636000000, 53, 1, 1), > - PLL_RATE(648000000, 54, 1, 1), > - PLL_RATE(660000000, 55, 1, 1), > - PLL_RATE(672000000, 56, 1, 1), > - PLL_RATE(684000000, 57, 1, 1), > - PLL_RATE(696000000, 58, 1, 1), > - PLL_RATE(708000000, 59, 1, 1), > - PLL_RATE(720000000, 60, 1, 1), > - PLL_RATE(732000000, 61, 1, 1), > - PLL_RATE(744000000, 62, 1, 1), > - PLL_RATE(756000000, 63, 1, 1), > - PLL_RATE(768000000, 64, 1, 1), > - PLL_RATE(780000000, 65, 1, 1), > - PLL_RATE(792000000, 66, 1, 1), > + PLL_RATE(1008000000, 42, 1), > + PLL_RATE(1032000000, 43, 1), > + PLL_RATE(1056000000, 44, 1), > + PLL_RATE(1080000000, 45, 1), > + PLL_RATE(1104000000, 46, 1), > + PLL_RATE(1128000000, 47, 1), > + PLL_RATE(1152000000, 48, 1), > + PLL_RATE(1176000000, 49, 1), > + PLL_RATE(1200000000, 50, 1), > + PLL_RATE(1224000000, 51, 1), > + PLL_RATE(1248000000, 52, 1), > + PLL_RATE(1272000000, 53, 1), > + PLL_RATE(1296000000, 54, 1), > + PLL_RATE(1320000000, 55, 1), > + PLL_RATE(1344000000, 56, 1), > + PLL_RATE(1368000000, 57, 1), > + PLL_RATE(1392000000, 58, 1), > + PLL_RATE(1416000000, 59, 1), > + PLL_RATE(1440000000, 60, 1), > + PLL_RATE(1464000000, 61, 1), > + PLL_RATE(1488000000, 62, 1), > + PLL_RATE(1512000000, 63, 1), > + PLL_RATE(1536000000, 64, 1), > + PLL_RATE(1560000000, 65, 1), > + PLL_RATE(1584000000, 66, 1), > { /* sentinel */ }, > }; > > -static struct clk_regmap gxbb_fixed_pll = { > +static struct clk_regmap gxbb_fixed_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_MPLL_CNTL, > @@ -192,11 +99,6 @@ static struct clk_regmap gxbb_fixed_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_MPLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_MPLL_CNTL2, > .shift = 0, > @@ -214,7 +116,7 @@ static struct clk_regmap gxbb_fixed_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "fixed_pll", > + .name = "fixed_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > @@ -222,6 +124,21 @@ static struct clk_regmap gxbb_fixed_pll = { > }, > }; > > +static struct clk_regmap gxbb_fixed_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_MPLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "fixed_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "fixed_pll_dco" }, > + .num_parents = 1, > + }, > +}; > + > static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { > .mult = 2, > .div = 1, > @@ -233,7 +150,7 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { > }, > }; > > -static struct clk_regmap gxbb_hdmi_pll = { > +static struct clk_regmap gxbb_hdmi_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_HDMI_PLL_CNTL, > @@ -255,21 +172,6 @@ static struct clk_regmap gxbb_hdmi_pll = { > .shift = 0, > .width = 12, > }, > - .od = { > - .reg_off = HHI_HDMI_PLL_CNTL2, > - .shift = 16, > - .width = 2, > - }, > - .od2 = { > - .reg_off = HHI_HDMI_PLL_CNTL2, > - .shift = 22, > - .width = 2, > - }, > - .od3 = { > - .reg_off = HHI_HDMI_PLL_CNTL2, > - .shift = 18, > - .width = 2, > - }, > .l = { > .reg_off = HHI_HDMI_PLL_CNTL, > .shift = 31, > @@ -282,7 +184,7 @@ static struct clk_regmap gxbb_hdmi_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "hdmi_pll", > + .name = "hdmi_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "hdmi_pll_pre_mult" }, > .num_parents = 1, > @@ -290,70 +192,103 @@ static struct clk_regmap gxbb_hdmi_pll = { > }, > }; > > +static struct clk_regmap gxbb_hdmi_pll_od = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_HDMI_PLL_CNTL2, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdmi_pll_od", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "hdmi_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE, > + }, > +}; > + > +static struct clk_regmap gxbb_hdmi_pll_od2 = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_HDMI_PLL_CNTL2, > + .shift = 22, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdmi_pll_od2", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "hdmi_pll_od" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE, > + }, > +}; > + > +static struct clk_regmap gxbb_hdmi_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_HDMI_PLL_CNTL2, > + .shift = 18, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdmi_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "hdmi_pll_od2" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE, > + }, > +}; > + > +static struct clk_regmap gxl_hdmi_pll_od = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_HDMI_PLL_CNTL + 8, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdmi_pll_od", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "hdmi_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE, > + }, > +}; In my code, the GXL OD1 is at bit 21 > + > +static struct clk_regmap gxl_hdmi_pll_od2 = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_HDMI_PLL_CNTL + 8, > + .shift = 22, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdmi_pll_od2", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "hdmi_pll_od" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE, > + }, > +}; In my code, the GXL OD3 is at bit 23 > + > static struct clk_regmap gxl_hdmi_pll = { > - .data = &(struct meson_clk_pll_data){ > - .en = { > - .reg_off = HHI_HDMI_PLL_CNTL, > - .shift = 30, > - .width = 1, > - }, > - .m = { > - .reg_off = HHI_HDMI_PLL_CNTL, > - .shift = 0, > - .width = 9, > - }, > - .n = { > - .reg_off = HHI_HDMI_PLL_CNTL, > - .shift = 9, > - .width = 5, > - }, > - .frac = { > - /* > - * On gxl, there is a register shift due to > - * HHI_HDMI_PLL_CNTL1 which does not exist on gxbb, > - * so we compute the register offset based on the PLL > - * base to get it right > - */ > - .reg_off = HHI_HDMI_PLL_CNTL + 4, > - .shift = 0, > - .width = 12, > - }, > - .od = { > - .reg_off = HHI_HDMI_PLL_CNTL + 8, > - .shift = 21, > - .width = 2, > - }, > - .od2 = { > - .reg_off = HHI_HDMI_PLL_CNTL + 8, > - .shift = 23, > - .width = 2, > - }, > - .od3 = { > - .reg_off = HHI_HDMI_PLL_CNTL + 8, > - .shift = 19, > - .width = 2, > - }, > - .l = { > - .reg_off = HHI_HDMI_PLL_CNTL, > - .shift = 31, > - .width = 1, > - }, > - .rst = { > - .reg_off = HHI_HDMI_PLL_CNTL, > - .shift = 29, > - .width = 1, > - }, > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_HDMI_PLL_CNTL + 8, > + .shift = 18, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, In my code, the GXL OD3 is at bit 19 It's only a copy/paste error, the original code had the correct shifts. > }, > .hw.init = &(struct clk_init_data){ > .name = "hdmi_pll", > - .ops = &meson_clk_pll_ro_ops, > - .parent_names = (const char *[]){ "xtal" }, > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "hdmi_pll_od2" }, > .num_parents = 1, > .flags = CLK_GET_RATE_NOCACHE, > }, > }; > > -static struct clk_regmap gxbb_sys_pll = { > +static struct clk_regmap gxbb_sys_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_SYS_PLL_CNTL, > @@ -370,11 +305,6 @@ static struct clk_regmap gxbb_sys_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_SYS_PLL_CNTL, > - .shift = 10, > - .width = 2, > - }, > .l = { > .reg_off = HHI_SYS_PLL_CNTL, > .shift = 31, > @@ -387,7 +317,7 @@ static struct clk_regmap gxbb_sys_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "sys_pll", > + .name = "sys_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > @@ -395,13 +325,29 @@ static struct clk_regmap gxbb_sys_pll = { > }, > }; > > +static struct clk_regmap gxbb_sys_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_SYS_PLL_CNTL, > + .shift = 10, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sys_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "sys_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE, > + }, > +}; > + > static const struct reg_sequence gxbb_gp0_init_regs[] = { > { .reg = HHI_GP0_PLL_CNTL2, .def = 0x69c80000 }, > { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a5590c4 }, > { .reg = HHI_GP0_PLL_CNTL4, .def = 0x0000500d }, > }; > > -static struct clk_regmap gxbb_gp0_pll = { > +static struct clk_regmap gxbb_gp0_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_GP0_PLL_CNTL, > @@ -418,11 +364,6 @@ static struct clk_regmap gxbb_gp0_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_GP0_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .l = { > .reg_off = HHI_GP0_PLL_CNTL, > .shift = 31, > @@ -438,7 +379,7 @@ static struct clk_regmap gxbb_gp0_pll = { > .init_count = ARRAY_SIZE(gxbb_gp0_init_regs), > }, > .hw.init = &(struct clk_init_data){ > - .name = "gp0_pll", > + .name = "gp0_pll_dco", > .ops = &meson_clk_pll_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > @@ -454,7 +395,7 @@ static const struct reg_sequence gxl_gp0_init_regs[] = { > { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, > }; > > -static struct clk_regmap gxl_gp0_pll = { > +static struct clk_regmap gxl_gp0_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_GP0_PLL_CNTL, > @@ -471,11 +412,6 @@ static struct clk_regmap gxl_gp0_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_GP0_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_GP0_PLL_CNTL1, > .shift = 0, > @@ -496,7 +432,7 @@ static struct clk_regmap gxl_gp0_pll = { > .init_count = ARRAY_SIZE(gxl_gp0_init_regs), > }, > .hw.init = &(struct clk_init_data){ > - .name = "gp0_pll", > + .name = "gp0_pll_dco", > .ops = &meson_clk_pll_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > @@ -504,6 +440,22 @@ static struct clk_regmap gxl_gp0_pll = { > }, > }; > > +static struct clk_regmap gxbb_gp0_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_GP0_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "gp0_pll", > + .ops = &clk_regmap_divider_ops, > + .parent_names = (const char *[]){ "gp0_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, > + }, > +}; > + > static struct clk_fixed_factor gxbb_fclk_div2_div = { > .mult = 1, > .div = 2, > @@ -1961,6 +1913,12 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { > [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, > [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, > [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, > + [CLKID_FIXED_PLL_DCO] = &gxbb_fixed_pll_dco.hw, > + [CLKID_HDMI_PLL_DCO] = &gxbb_hdmi_pll_dco.hw, > + [CLKID_HDMI_PLL_OD] = &gxbb_hdmi_pll_od.hw, > + [CLKID_HDMI_PLL_OD2] = &gxbb_hdmi_pll_od2.hw, > + [CLKID_SYS_PLL_DCO] = &gxbb_sys_pll_dco.hw, > + [CLKID_GP0_PLL_DCO] = &gxbb_gp0_pll_dco.hw, > [NR_CLKS] = NULL, > }, > .num = NR_CLKS, > @@ -1976,7 +1934,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { > [CLKID_FCLK_DIV4] = &gxbb_fclk_div4.hw, > [CLKID_FCLK_DIV5] = &gxbb_fclk_div5.hw, > [CLKID_FCLK_DIV7] = &gxbb_fclk_div7.hw, > - [CLKID_GP0_PLL] = &gxl_gp0_pll.hw, > + [CLKID_GP0_PLL] = &gxbb_gp0_pll.hw, > [CLKID_MPEG_SEL] = &gxbb_mpeg_clk_sel.hw, > [CLKID_MPEG_DIV] = &gxbb_mpeg_clk_div.hw, > [CLKID_CLK81] = &gxbb_clk81.hw, > @@ -2126,19 +2084,29 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { > [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, > [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, > [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, > + [CLKID_FIXED_PLL_DCO] = &gxbb_fixed_pll_dco.hw, > + [CLKID_HDMI_PLL_DCO] = &gxbb_hdmi_pll_dco.hw, > + [CLKID_HDMI_PLL_OD] = &gxl_hdmi_pll_od.hw, > + [CLKID_HDMI_PLL_OD2] = &gxl_hdmi_pll_od2.hw, > + [CLKID_SYS_PLL_DCO] = &gxbb_sys_pll_dco.hw, > + [CLKID_GP0_PLL_DCO] = &gxl_gp0_pll_dco.hw, > [NR_CLKS] = NULL, > }, > .num = NR_CLKS, > }; > > static struct clk_regmap *const gxbb_clk_regmaps[] = { > - &gxbb_gp0_pll, > + &gxbb_gp0_pll_dco, > &gxbb_hdmi_pll, > + &gxbb_hdmi_pll_od, > + &gxbb_hdmi_pll_od2, > }; > > static struct clk_regmap *const gxl_clk_regmaps[] = { > - &gxl_gp0_pll, > + &gxl_gp0_pll_dco, > &gxl_hdmi_pll, > + &gxl_hdmi_pll_od, > + &gxl_hdmi_pll_od2, > }; > > static struct clk_regmap *const gx_clk_regmaps[] = { > @@ -2293,6 +2261,10 @@ static struct clk_regmap *const gx_clk_regmaps[] = { > &gxbb_gen_clk_sel, > &gxbb_gen_clk_div, > &gxbb_gen_clk, > + &gxbb_fixed_pll_dco, > + &gxbb_hdmi_pll_dco, > + &gxbb_sys_pll_dco, > + &gxbb_gp0_pll, > }; > > struct clkc_data { > diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h > index 20dfb1daf5b8..72bc077d9663 100644 > --- a/drivers/clk/meson/gxbb.h > +++ b/drivers/clk/meson/gxbb.h > @@ -159,8 +159,14 @@ > #define CLKID_VDEC_HEVC_DIV 155 > #define CLKID_GEN_CLK_SEL 157 > #define CLKID_GEN_CLK_DIV 158 > - > -#define NR_CLKS 160 > +#define CLKID_FIXED_PLL_DCO 160 > +#define CLKID_HDMI_PLL_DCO 161 > +#define CLKID_HDMI_PLL_OD 162 > +#define CLKID_HDMI_PLL_OD2 163 > +#define CLKID_SYS_PLL_DCO 164 > +#define CLKID_GP0_PLL_DCO 165 > + > +#define NR_CLKS 166 > > /* include the CLKIDs that have been made part of the DT binding */ > #include <dt-bindings/clock/gxbb-clkc.h> > diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c > index fd4c414893f5..17bcf0be56ba 100644 > --- a/drivers/clk/meson/meson8b.c > +++ b/drivers/clk/meson/meson8b.c > @@ -30,58 +30,21 @@ struct meson8b_clk_reset { > }; > > static const struct pll_rate_table sys_pll_rate_table[] = { > - PLL_RATE(312000000, 52, 1, 2), > - PLL_RATE(336000000, 56, 1, 2), > - PLL_RATE(360000000, 60, 1, 2), > - PLL_RATE(384000000, 64, 1, 2), > - PLL_RATE(408000000, 68, 1, 2), > - PLL_RATE(432000000, 72, 1, 2), > - PLL_RATE(456000000, 76, 1, 2), > - PLL_RATE(480000000, 80, 1, 2), > - PLL_RATE(504000000, 84, 1, 2), > - PLL_RATE(528000000, 88, 1, 2), > - PLL_RATE(552000000, 92, 1, 2), > - PLL_RATE(576000000, 96, 1, 2), > - PLL_RATE(600000000, 50, 1, 1), > - PLL_RATE(624000000, 52, 1, 1), > - PLL_RATE(648000000, 54, 1, 1), > - PLL_RATE(672000000, 56, 1, 1), > - PLL_RATE(696000000, 58, 1, 1), > - PLL_RATE(720000000, 60, 1, 1), > - PLL_RATE(744000000, 62, 1, 1), > - PLL_RATE(768000000, 64, 1, 1), > - PLL_RATE(792000000, 66, 1, 1), > - PLL_RATE(816000000, 68, 1, 1), > - PLL_RATE(840000000, 70, 1, 1), > - PLL_RATE(864000000, 72, 1, 1), > - PLL_RATE(888000000, 74, 1, 1), > - PLL_RATE(912000000, 76, 1, 1), > - PLL_RATE(936000000, 78, 1, 1), > - PLL_RATE(960000000, 80, 1, 1), > - PLL_RATE(984000000, 82, 1, 1), > - PLL_RATE(1008000000, 84, 1, 1), > - PLL_RATE(1032000000, 86, 1, 1), > - PLL_RATE(1056000000, 88, 1, 1), > - PLL_RATE(1080000000, 90, 1, 1), > - PLL_RATE(1104000000, 92, 1, 1), > - PLL_RATE(1128000000, 94, 1, 1), > - PLL_RATE(1152000000, 96, 1, 1), > - PLL_RATE(1176000000, 98, 1, 1), > - PLL_RATE(1200000000, 50, 1, 0), > - PLL_RATE(1224000000, 51, 1, 0), > - PLL_RATE(1248000000, 52, 1, 0), > - PLL_RATE(1272000000, 53, 1, 0), > - PLL_RATE(1296000000, 54, 1, 0), > - PLL_RATE(1320000000, 55, 1, 0), > - PLL_RATE(1344000000, 56, 1, 0), > - PLL_RATE(1368000000, 57, 1, 0), > - PLL_RATE(1392000000, 58, 1, 0), > - PLL_RATE(1416000000, 59, 1, 0), > - PLL_RATE(1440000000, 60, 1, 0), > - PLL_RATE(1464000000, 61, 1, 0), > - PLL_RATE(1488000000, 62, 1, 0), > - PLL_RATE(1512000000, 63, 1, 0), > - PLL_RATE(1536000000, 64, 1, 0), > + PLL_RATE(1200000000, 50, 1), > + PLL_RATE(1224000000, 51, 1), > + PLL_RATE(1248000000, 52, 1), > + PLL_RATE(1272000000, 53, 1), > + PLL_RATE(1296000000, 54, 1), > + PLL_RATE(1320000000, 55, 1), > + PLL_RATE(1344000000, 56, 1), > + PLL_RATE(1368000000, 57, 1), > + PLL_RATE(1392000000, 58, 1), > + PLL_RATE(1416000000, 59, 1), > + PLL_RATE(1440000000, 60, 1), > + PLL_RATE(1464000000, 61, 1), > + PLL_RATE(1488000000, 62, 1), > + PLL_RATE(1512000000, 63, 1), > + PLL_RATE(1536000000, 64, 1), > { /* sentinel */ }, > }; > > @@ -94,7 +57,7 @@ static struct clk_fixed_rate meson8b_xtal = { > }, > }; > > -static struct clk_regmap meson8b_fixed_pll = { > +static struct clk_regmap meson8b_fixed_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_MPLL_CNTL, > @@ -111,11 +74,6 @@ static struct clk_regmap meson8b_fixed_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_MPLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_MPLL_CNTL2, > .shift = 0, > @@ -133,7 +91,7 @@ static struct clk_regmap meson8b_fixed_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "fixed_pll", > + .name = "fixed_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > @@ -141,7 +99,23 @@ static struct clk_regmap meson8b_fixed_pll = { > }, > }; > > -static struct clk_regmap meson8b_vid_pll = { > +static struct clk_regmap meson8b_fixed_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_MPLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "fixed_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "fixed_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE, > + }, > +}; > + > +static struct clk_regmap meson8b_vid_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_VID_PLL_CNTL, > @@ -158,11 +132,6 @@ static struct clk_regmap meson8b_vid_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_VID_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .l = { > .reg_off = HHI_VID_PLL_CNTL, > .shift = 31, > @@ -175,7 +144,7 @@ static struct clk_regmap meson8b_vid_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "vid_pll", > + .name = "vid_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > @@ -183,7 +152,23 @@ static struct clk_regmap meson8b_vid_pll = { > }, > }; > > -static struct clk_regmap meson8b_sys_pll = { > +static struct clk_regmap meson8b_vid_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_VID_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vid_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "vid_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE, > + }, > +}; > + > +static struct clk_regmap meson8b_sys_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_SYS_PLL_CNTL, > @@ -200,11 +185,6 @@ static struct clk_regmap meson8b_sys_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_SYS_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .l = { > .reg_off = HHI_SYS_PLL_CNTL, > .shift = 31, > @@ -218,7 +198,7 @@ static struct clk_regmap meson8b_sys_pll = { > .table = sys_pll_rate_table, > }, > .hw.init = &(struct clk_init_data){ > - .name = "sys_pll", > + .name = "sys_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > @@ -226,6 +206,22 @@ static struct clk_regmap meson8b_sys_pll = { > }, > }; > > +static struct clk_regmap meson8b_sys_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_SYS_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sys_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "sys_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE, > + }, > +}; > + > static struct clk_fixed_factor meson8b_fclk_div2_div = { > .mult = 1, > .div = 2, > @@ -894,6 +890,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { > [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw, > [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw, > [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw, > + [CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw, > + [CLKID_PLL_VID_DCO] = &meson8b_vid_pll_dco.hw, > + [CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw, > [CLK_NR_CLKS] = NULL, > }, > .num = CLK_NR_CLKS, > @@ -1002,6 +1001,9 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { > &meson8b_nand_clk_sel, > &meson8b_nand_clk_div, > &meson8b_nand_clk_gate, > + &meson8b_fixed_pll_dco, > + &meson8b_vid_pll_dco, > + &meson8b_sys_pll_dco, > }; > > static const struct meson8b_clk_reset_line { > diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h > index 5d09412b5084..1c6fb180e6a2 100644 > --- a/drivers/clk/meson/meson8b.h > +++ b/drivers/clk/meson/meson8b.h > @@ -75,8 +75,11 @@ > #define CLKID_FCLK_DIV7_DIV 109 > #define CLKID_NAND_SEL 110 > #define CLKID_NAND_DIV 111 > +#define CLKID_PLL_FIXED_DCO 113 > +#define CLKID_PLL_VID_DCO 114 > +#define CLKID_PLL_SYS_DCO 115 > > -#define CLK_NR_CLKS 113 > +#define CLK_NR_CLKS 116 > > /* > * include the CLKID and RESETID that have > Apart the small mismatch in the OD GXL bit, this will make this simpler to move the DRM code to CCF : Acked-by: Neil Armstrong <narmstrong@baylibre.com>
On Thu, 2018-07-19 at 10:42 +0200, Neil Armstrong wrote: > > +static struct clk_regmap gxl_hdmi_pll_od = { > > + .data = &(struct clk_regmap_div_data){ > > + .offset = HHI_HDMI_PLL_CNTL + 8, > > + .shift = 16, > > + .width = 2, > > + .flags = CLK_DIVIDER_POWER_OF_TWO, > > + }, > > + .hw.init = &(struct clk_init_data){ > > + .name = "hdmi_pll_od", > > + .ops = &clk_regmap_divider_ro_ops, > > + .parent_names = (const char *[]){ "hdmi_pll_dco" }, > > + .num_parents = 1, > > + .flags = CLK_GET_RATE_NOCACHE, > > + }, > > +}; > > In my code, the GXL OD1 is at bit 21 > > > + > > +static struct clk_regmap gxl_hdmi_pll_od2 = { > > + .data = &(struct clk_regmap_div_data){ > > + .offset = HHI_HDMI_PLL_CNTL + 8, > > + .shift = 22, > > + .width = 2, > > + .flags = CLK_DIVIDER_POWER_OF_TWO, > > + }, > > + .hw.init = &(struct clk_init_data){ > > + .name = "hdmi_pll_od2", > > + .ops = &clk_regmap_divider_ro_ops, > > + .parent_names = (const char *[]){ "hdmi_pll_od" }, > > + .num_parents = 1, > > + .flags = CLK_GET_RATE_NOCACHE, > > + }, > > +}; > > > In my code, the GXL OD3 is at bit 23 > > > + > > static struct clk_regmap gxl_hdmi_pll = { > > - .data = &(struct meson_clk_pll_data){ > > - .en = { > > - .reg_off = HHI_HDMI_PLL_CNTL, > > - .shift = 30, > > - .width = 1, > > - }, > > - .m = { > > - .reg_off = HHI_HDMI_PLL_CNTL, > > - .shift = 0, > > - .width = 9, > > - }, > > - .n = { > > - .reg_off = HHI_HDMI_PLL_CNTL, > > - .shift = 9, > > - .width = 5, > > - }, > > - .frac = { > > - /* > > - * On gxl, there is a register shift due to > > - * HHI_HDMI_PLL_CNTL1 which does not exist on gxbb, > > - * so we compute the register offset based on the PLL > > - * base to get it right > > - */ > > - .reg_off = HHI_HDMI_PLL_CNTL + 4, > > - .shift = 0, > > - .width = 12, > > - }, > > - .od = { > > - .reg_off = HHI_HDMI_PLL_CNTL + 8, > > - .shift = 21, > > - .width = 2, > > - }, > > - .od2 = { > > - .reg_off = HHI_HDMI_PLL_CNTL + 8, > > - .shift = 23, > > - .width = 2, > > - }, > > - .od3 = { > > - .reg_off = HHI_HDMI_PLL_CNTL + 8, > > - .shift = 19, > > - .width = 2, > > - }, > > - .l = { > > - .reg_off = HHI_HDMI_PLL_CNTL, > > - .shift = 31, > > - .width = 1, > > - }, > > - .rst = { > > - .reg_off = HHI_HDMI_PLL_CNTL, > > - .shift = 29, > > - .width = 1, > > - }, > > + .data = &(struct clk_regmap_div_data){ > > + .offset = HHI_HDMI_PLL_CNTL + 8, > > + .shift = 18, > > + .width = 2, > > + .flags = CLK_DIVIDER_POWER_OF_TWO, > > > In my code, the GXL OD3 is at bit 19 > > It's only a copy/paste error, the original code had the correct shifts. Absolutely. Good catch.
Hi Jerome, On Tue, Jul 17, 2018 at 11:56 AM Jerome Brunet <jbrunet@baylibre.com> wrote: > > Remove od parameters from pll clocks and add post dividers clocks > instead. Some clock, especially the one which feature several ods, > may provide output between those ods. Also, some drivers, such > as the hdmi driver, may require a more detailed control of the > clock dividers, compared to what CCF would perform automatically. > > One added benefit of removing ods is that it also greatly reduce the > size of the rate parameter tables. > > In the future, we could possibly take the predivider 'n' out of this > driver as well. To do so, we will need to understand the constraints > for the PLL to lock and whether or not it depends on the input clock > rate. > > Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> > --- > drivers/clk/meson/axg.c | 279 ++++++++++++++------------ > drivers/clk/meson/axg.h | 8 +- > drivers/clk/meson/clk-pll.c | 40 ++-- > drivers/clk/meson/clkc.h | 9 +- > drivers/clk/meson/gxbb.c | 474 +++++++++++++++++++++----------------------- > drivers/clk/meson/gxbb.h | 10 +- > drivers/clk/meson/meson8b.c | 148 +++++++------- > drivers/clk/meson/meson8b.h | 5 +- > 8 files changed, 480 insertions(+), 493 deletions(-) > > diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c > index 6d8976554656..572358062459 100644 > --- a/drivers/clk/meson/axg.c > +++ b/drivers/clk/meson/axg.c > @@ -22,7 +22,7 @@ > > static DEFINE_SPINLOCK(meson_clk_lock); > > -static struct clk_regmap axg_fixed_pll = { > +static struct clk_regmap axg_fixed_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_MPLL_CNTL, > @@ -39,11 +39,6 @@ static struct clk_regmap axg_fixed_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_MPLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_MPLL_CNTL2, > .shift = 0, > @@ -61,14 +56,29 @@ static struct clk_regmap axg_fixed_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "fixed_pll", > + .name = "fixed_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > }, > }; > > -static struct clk_regmap axg_sys_pll = { > +static struct clk_regmap axg_fixed_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_MPLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "fixed_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "fixed_pll_dco" }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap axg_sys_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_SYS_PLL_CNTL, > @@ -85,11 +95,6 @@ static struct clk_regmap axg_sys_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_SYS_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .l = { > .reg_off = HHI_SYS_PLL_CNTL, > .shift = 31, > @@ -102,7 +107,7 @@ static struct clk_regmap axg_sys_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "sys_pll", > + .name = "sys_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > @@ -110,94 +115,51 @@ static struct clk_regmap axg_sys_pll = { > }, > }; > > +static struct clk_regmap axg_sys_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_SYS_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sys_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "sys_pll_dco" }, > + .num_parents = 1, > + }, > +}; > + > static const struct pll_rate_table axg_gp0_pll_rate_table[] = { > - PLL_RATE(240000000, 40, 1, 2), > - PLL_RATE(246000000, 41, 1, 2), > - PLL_RATE(252000000, 42, 1, 2), > - PLL_RATE(258000000, 43, 1, 2), > - PLL_RATE(264000000, 44, 1, 2), > - PLL_RATE(270000000, 45, 1, 2), > - PLL_RATE(276000000, 46, 1, 2), > - PLL_RATE(282000000, 47, 1, 2), > - PLL_RATE(288000000, 48, 1, 2), > - PLL_RATE(294000000, 49, 1, 2), > - PLL_RATE(300000000, 50, 1, 2), > - PLL_RATE(306000000, 51, 1, 2), > - PLL_RATE(312000000, 52, 1, 2), > - PLL_RATE(318000000, 53, 1, 2), > - PLL_RATE(324000000, 54, 1, 2), > - PLL_RATE(330000000, 55, 1, 2), > - PLL_RATE(336000000, 56, 1, 2), > - PLL_RATE(342000000, 57, 1, 2), > - PLL_RATE(348000000, 58, 1, 2), > - PLL_RATE(354000000, 59, 1, 2), > - PLL_RATE(360000000, 60, 1, 2), > - PLL_RATE(366000000, 61, 1, 2), > - PLL_RATE(372000000, 62, 1, 2), > - PLL_RATE(378000000, 63, 1, 2), > - PLL_RATE(384000000, 64, 1, 2), > - PLL_RATE(390000000, 65, 1, 3), > - PLL_RATE(396000000, 66, 1, 3), > - PLL_RATE(402000000, 67, 1, 3), > - PLL_RATE(408000000, 68, 1, 3), > - PLL_RATE(480000000, 40, 1, 1), > - PLL_RATE(492000000, 41, 1, 1), > - PLL_RATE(504000000, 42, 1, 1), > - PLL_RATE(516000000, 43, 1, 1), > - PLL_RATE(528000000, 44, 1, 1), > - PLL_RATE(540000000, 45, 1, 1), > - PLL_RATE(552000000, 46, 1, 1), > - PLL_RATE(564000000, 47, 1, 1), > - PLL_RATE(576000000, 48, 1, 1), > - PLL_RATE(588000000, 49, 1, 1), > - PLL_RATE(600000000, 50, 1, 1), > - PLL_RATE(612000000, 51, 1, 1), > - PLL_RATE(624000000, 52, 1, 1), > - PLL_RATE(636000000, 53, 1, 1), > - PLL_RATE(648000000, 54, 1, 1), > - PLL_RATE(660000000, 55, 1, 1), > - PLL_RATE(672000000, 56, 1, 1), > - PLL_RATE(684000000, 57, 1, 1), > - PLL_RATE(696000000, 58, 1, 1), > - PLL_RATE(708000000, 59, 1, 1), > - PLL_RATE(720000000, 60, 1, 1), > - PLL_RATE(732000000, 61, 1, 1), > - PLL_RATE(744000000, 62, 1, 1), > - PLL_RATE(756000000, 63, 1, 1), > - PLL_RATE(768000000, 64, 1, 1), > - PLL_RATE(780000000, 65, 1, 1), > - PLL_RATE(792000000, 66, 1, 1), > - PLL_RATE(804000000, 67, 1, 1), > - PLL_RATE(816000000, 68, 1, 1), > - PLL_RATE(960000000, 40, 1, 0), > - PLL_RATE(984000000, 41, 1, 0), > - PLL_RATE(1008000000, 42, 1, 0), > - PLL_RATE(1032000000, 43, 1, 0), > - PLL_RATE(1056000000, 44, 1, 0), > - PLL_RATE(1080000000, 45, 1, 0), > - PLL_RATE(1104000000, 46, 1, 0), > - PLL_RATE(1128000000, 47, 1, 0), > - PLL_RATE(1152000000, 48, 1, 0), > - PLL_RATE(1176000000, 49, 1, 0), > - PLL_RATE(1200000000, 50, 1, 0), > - PLL_RATE(1224000000, 51, 1, 0), > - PLL_RATE(1248000000, 52, 1, 0), > - PLL_RATE(1272000000, 53, 1, 0), > - PLL_RATE(1296000000, 54, 1, 0), > - PLL_RATE(1320000000, 55, 1, 0), > - PLL_RATE(1344000000, 56, 1, 0), > - PLL_RATE(1368000000, 57, 1, 0), > - PLL_RATE(1392000000, 58, 1, 0), > - PLL_RATE(1416000000, 59, 1, 0), > - PLL_RATE(1440000000, 60, 1, 0), > - PLL_RATE(1464000000, 61, 1, 0), > - PLL_RATE(1488000000, 62, 1, 0), > - PLL_RATE(1512000000, 63, 1, 0), > - PLL_RATE(1536000000, 64, 1, 0), > - PLL_RATE(1560000000, 65, 1, 0), > - PLL_RATE(1584000000, 66, 1, 0), > - PLL_RATE(1608000000, 67, 1, 0), > - PLL_RATE(1632000000, 68, 1, 0), > + PLL_RATE(960000000, 40, 1), > + PLL_RATE(984000000, 41, 1), > + PLL_RATE(1008000000, 42, 1), > + PLL_RATE(1032000000, 43, 1), > + PLL_RATE(1056000000, 44, 1), > + PLL_RATE(1080000000, 45, 1), > + PLL_RATE(1104000000, 46, 1), > + PLL_RATE(1128000000, 47, 1), > + PLL_RATE(1152000000, 48, 1), > + PLL_RATE(1176000000, 49, 1), > + PLL_RATE(1200000000, 50, 1), > + PLL_RATE(1224000000, 51, 1), > + PLL_RATE(1248000000, 52, 1), > + PLL_RATE(1272000000, 53, 1), > + PLL_RATE(1296000000, 54, 1), > + PLL_RATE(1320000000, 55, 1), > + PLL_RATE(1344000000, 56, 1), > + PLL_RATE(1368000000, 57, 1), > + PLL_RATE(1392000000, 58, 1), > + PLL_RATE(1416000000, 59, 1), > + PLL_RATE(1440000000, 60, 1), > + PLL_RATE(1464000000, 61, 1), > + PLL_RATE(1488000000, 62, 1), > + PLL_RATE(1512000000, 63, 1), > + PLL_RATE(1536000000, 64, 1), > + PLL_RATE(1560000000, 65, 1), > + PLL_RATE(1584000000, 66, 1), > + PLL_RATE(1608000000, 67, 1), > + PLL_RATE(1632000000, 68, 1), > { /* sentinel */ }, > }; > > @@ -209,7 +171,7 @@ static const struct reg_sequence axg_gp0_init_regs[] = { > { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, > }; > > -static struct clk_regmap axg_gp0_pll = { > +static struct clk_regmap axg_gp0_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_GP0_PLL_CNTL, > @@ -226,11 +188,6 @@ static struct clk_regmap axg_gp0_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_GP0_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_GP0_PLL_CNTL1, > .shift = 0, > @@ -251,13 +208,29 @@ static struct clk_regmap axg_gp0_pll = { > .init_count = ARRAY_SIZE(axg_gp0_init_regs), > }, > .hw.init = &(struct clk_init_data){ > - .name = "gp0_pll", > + .name = "gp0_pll_dco", > .ops = &meson_clk_pll_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > }, > }; > > +static struct clk_regmap axg_gp0_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_GP0_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "gp0_pll", > + .ops = &clk_regmap_divider_ops, > + .parent_names = (const char *[]){ "gp0_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > static const struct reg_sequence axg_hifi_init_regs[] = { > { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 }, > { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be }, > @@ -266,7 +239,7 @@ static const struct reg_sequence axg_hifi_init_regs[] = { > { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 }, > }; > > -static struct clk_regmap axg_hifi_pll = { > +static struct clk_regmap axg_hifi_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_HIFI_PLL_CNTL, > @@ -283,11 +256,6 @@ static struct clk_regmap axg_hifi_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_HIFI_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_HIFI_PLL_CNTL5, > .shift = 0, > @@ -309,13 +277,29 @@ static struct clk_regmap axg_hifi_pll = { > .flags = CLK_MESON_PLL_ROUND_CLOSEST, > }, > .hw.init = &(struct clk_init_data){ > - .name = "hifi_pll", > + .name = "hifi_pll_dco", > .ops = &meson_clk_pll_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > }, > }; > > +static struct clk_regmap axg_hifi_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_HIFI_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hifi_pll", > + .ops = &clk_regmap_divider_ops, > + .parent_names = (const char *[]){ "hifi_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > static struct clk_fixed_factor axg_fclk_div2_div = { > .mult = 1, > .div = 2, > @@ -645,11 +629,9 @@ static struct clk_regmap axg_mpll3 = { > > static const struct pll_rate_table axg_pcie_pll_rate_table[] = { > { > - .rate = 100000000, > + .rate = 1600000000, > .m = 200, > .n = 3, > - .od = 1, > - .od2 = 3, > }, > { /* sentinel */ }, > }; > @@ -661,9 +643,10 @@ static const struct reg_sequence axg_pcie_init_regs[] = { > { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d }, > { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 }, > { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 }, > + { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, > }; > > -static struct clk_regmap axg_pcie_pll = { > +static struct clk_regmap axg_pcie_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_PCIE_PLL_CNTL, > @@ -680,16 +663,6 @@ static struct clk_regmap axg_pcie_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_PCIE_PLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > - .od2 = { > - .reg_off = HHI_PCIE_PLL_CNTL6, > - .shift = 6, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_PCIE_PLL_CNTL1, > .shift = 0, > @@ -710,13 +683,45 @@ static struct clk_regmap axg_pcie_pll = { > .init_count = ARRAY_SIZE(axg_pcie_init_regs), > }, > .hw.init = &(struct clk_init_data){ > - .name = "pcie_pll", > + .name = "pcie_pll_dco", > .ops = &meson_clk_pll_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > }, > }; > > +static struct clk_regmap axg_pcie_pll_od = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_PCIE_PLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pcie_pll_od", > + .ops = &clk_regmap_divider_ops, > + .parent_names = (const char *[]){ "pcie_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap axg_pcie_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_PCIE_PLL_CNTL6, > + .shift = 6, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pcie_pll", > + .ops = &clk_regmap_divider_ops, > + .parent_names = (const char *[]){ "pcie_pll_od" }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > static struct clk_regmap axg_pcie_mux = { > .data = &(struct clk_regmap_mux_data){ > .offset = HHI_PCIE_PLL_CNTL6, > @@ -1129,6 +1134,12 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = { > [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw, > [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw, > [CLKID_GEN_CLK] = &axg_gen_clk.hw, > + [CLKID_SYS_PLL_DCO] = &axg_sys_pll_dco.hw, > + [CLKID_FIXED_PLL_DCO] = &axg_fixed_pll_dco.hw, > + [CLKID_GP0_PLL_DCO] = &axg_gp0_pll_dco.hw, > + [CLKID_HIFI_PLL_DCO] = &axg_hifi_pll_dco.hw, > + [CLKID_PCIE_PLL_DCO] = &axg_pcie_pll_dco.hw, > + [CLKID_PCIE_PLL_OD] = &axg_pcie_pll_od.hw, > [NR_CLKS] = NULL, > }, > .num = NR_CLKS, > @@ -1207,6 +1218,8 @@ static struct clk_regmap *const axg_clk_regmaps[] = { > &axg_fclk_div4, > &axg_fclk_div5, > &axg_fclk_div7, > + &axg_pcie_pll_dco, > + &axg_pcie_pll_od, > &axg_pcie_pll, > &axg_pcie_mux, > &axg_pcie_ref, > @@ -1216,6 +1229,12 @@ static struct clk_regmap *const axg_clk_regmaps[] = { > &axg_gen_clk_sel, > &axg_gen_clk_div, > &axg_gen_clk, > + &axg_fixed_pll_dco, > + &axg_sys_pll_dco, > + &axg_gp0_pll_dco, > + &axg_hifi_pll_dco, > + &axg_pcie_pll_dco, > + &axg_pcie_pll_od, > }; > > static const struct of_device_id clkc_match_table[] = { > diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h > index 1d04144a1b2c..0431dabac629 100644 > --- a/drivers/clk/meson/axg.h > +++ b/drivers/clk/meson/axg.h > @@ -133,8 +133,14 @@ > #define CLKID_PCIE_REF 78 > #define CLKID_GEN_CLK_SEL 82 > #define CLKID_GEN_CLK_DIV 83 > +#define CLKID_SYS_PLL_DCO 85 > +#define CLKID_FIXED_PLL_DCO 86 > +#define CLKID_GP0_PLL_DCO 87 > +#define CLKID_HIFI_PLL_DCO 88 > +#define CLKID_PCIE_PLL_DCO 89 > +#define CLKID_PCIE_PLL_OD 90 > > -#define NR_CLKS 85 > +#define NR_CLKS 91 > > /* include the CLKIDs that have been made part of the DT binding */ > #include <dt-bindings/clock/axg-clkc.h> > diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c > index 8aaefe67025f..348a866f09eb 100644 > --- a/drivers/clk/meson/clk-pll.c > +++ b/drivers/clk/meson/clk-pll.c > @@ -11,15 +11,19 @@ > * In the most basic form, a Meson PLL is composed as follows: > * > * PLL > - * +------------------------------+ > - * | | > - * in -----[ /N ]---[ *M ]---[ >>OD ]----->> out > - * | ^ ^ | > - * +------------------------------+ > - * | | > - * FREF VCO > + * +--------------------------------+ > + * | | > + * | +--+ | > + * in >>-----[ /N ]--->| | +-----+ | > + * | | |------| DCO |---->> out > + * | +--------->| | +--v--+ | > + * | | +--+ | | > + * | | | | > + * | +--[ *(M + (F/Fmax) ]<--+ | > + * | | > + * +--------------------------------+ > * > - * out = in * (m + frac / frac_max) / (n << sum(ods)) > + * out = in * (m + frac / frac_max) / n > */ > > #include <linux/clk-provider.h> > @@ -46,7 +50,6 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate, > struct meson_clk_pll_data *pll) > { > u64 rate = (u64)parent_rate * pllt->m; > - unsigned int od = pllt->od + pllt->od2 + pllt->od3; > > if (frac && MESON_PARM_APPLICABLE(&pll->frac)) { > u64 frac_rate = (u64)parent_rate * frac; > @@ -55,7 +58,7 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate, > (1 << pll->frac.width)); > } > > - return DIV_ROUND_UP_ULL(rate, pllt->n << od); > + return DIV_ROUND_UP_ULL(rate, pllt->n); > } > > static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, > @@ -68,15 +71,6 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, > > pllt.n = meson_parm_read(clk->map, &pll->n); > pllt.m = meson_parm_read(clk->map, &pll->m); > - pllt.od = meson_parm_read(clk->map, &pll->od); > - > - pllt.od2 = MESON_PARM_APPLICABLE(&pll->od2) ? > - meson_parm_read(clk->map, &pll->od2) : > - 0; > - > - pllt.od3 = MESON_PARM_APPLICABLE(&pll->od3) ? > - meson_parm_read(clk->map, &pll->od3) : > - 0; > > frac = MESON_PARM_APPLICABLE(&pll->frac) ? > meson_parm_read(clk->map, &pll->frac) : > @@ -93,8 +87,6 @@ static u16 __pll_params_with_frac(unsigned long rate, > u16 frac_max = (1 << pll->frac.width); > u64 val = (u64)rate * pllt->n; > > - val <<= pllt->od + pllt->od2 + pllt->od3; > - > if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) > val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate); > else > @@ -242,13 +234,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, > > meson_parm_write(clk->map, &pll->n, pllt->n); > meson_parm_write(clk->map, &pll->m, pllt->m); > - meson_parm_write(clk->map, &pll->od, pllt->od); > - > - if (MESON_PARM_APPLICABLE(&pll->od2)) > - meson_parm_write(clk->map, &pll->od2, pllt->od2); > > - if (MESON_PARM_APPLICABLE(&pll->od3)) > - meson_parm_write(clk->map, &pll->od3, pllt->od3); > > if (MESON_PARM_APPLICABLE(&pll->frac)) { > frac = __pll_params_with_frac(rate, parent_rate, pllt, pll); > diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h > index c2ee37a78ceb..a2245e857f70 100644 > --- a/drivers/clk/meson/clkc.h > +++ b/drivers/clk/meson/clkc.h > @@ -47,17 +47,13 @@ struct pll_rate_table { > unsigned long rate; > u16 m; > u16 n; > - u16 od; > - u16 od2; > - u16 od3; > }; > > -#define PLL_RATE(_r, _m, _n, _od) \ > +#define PLL_RATE(_r, _m, _n) \ > { \ > .rate = (_r), \ > .m = (_m), \ > .n = (_n), \ > - .od = (_od), \ > } > > #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0) > @@ -67,9 +63,6 @@ struct meson_clk_pll_data { > struct parm m; > struct parm n; > struct parm frac; > - struct parm od; > - struct parm od2; > - struct parm od3; > struct parm l; > struct parm rst; > const struct reg_sequence *init_regs; > diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c > index 5ed34566917c..e2d94498f098 100644 > --- a/drivers/clk/meson/gxbb.c > +++ b/drivers/clk/meson/gxbb.c > @@ -19,163 +19,70 @@ > static DEFINE_SPINLOCK(meson_clk_lock); > > static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = { > - PLL_RATE(96000000, 32, 1, 3), > - PLL_RATE(99000000, 33, 1, 3), > - PLL_RATE(102000000, 34, 1, 3), > - PLL_RATE(105000000, 35, 1, 3), > - PLL_RATE(108000000, 36, 1, 3), > - PLL_RATE(111000000, 37, 1, 3), > - PLL_RATE(114000000, 38, 1, 3), > - PLL_RATE(117000000, 39, 1, 3), > - PLL_RATE(120000000, 40, 1, 3), > - PLL_RATE(123000000, 41, 1, 3), > - PLL_RATE(126000000, 42, 1, 3), > - PLL_RATE(129000000, 43, 1, 3), > - PLL_RATE(132000000, 44, 1, 3), > - PLL_RATE(135000000, 45, 1, 3), > - PLL_RATE(138000000, 46, 1, 3), > - PLL_RATE(141000000, 47, 1, 3), > - PLL_RATE(144000000, 48, 1, 3), > - PLL_RATE(147000000, 49, 1, 3), > - PLL_RATE(150000000, 50, 1, 3), > - PLL_RATE(153000000, 51, 1, 3), > - PLL_RATE(156000000, 52, 1, 3), > - PLL_RATE(159000000, 53, 1, 3), > - PLL_RATE(162000000, 54, 1, 3), > - PLL_RATE(165000000, 55, 1, 3), > - PLL_RATE(168000000, 56, 1, 3), > - PLL_RATE(171000000, 57, 1, 3), > - PLL_RATE(174000000, 58, 1, 3), > - PLL_RATE(177000000, 59, 1, 3), > - PLL_RATE(180000000, 60, 1, 3), > - PLL_RATE(183000000, 61, 1, 3), > - PLL_RATE(186000000, 62, 1, 3), > - PLL_RATE(192000000, 32, 1, 2), > - PLL_RATE(198000000, 33, 1, 2), > - PLL_RATE(204000000, 34, 1, 2), > - PLL_RATE(210000000, 35, 1, 2), > - PLL_RATE(216000000, 36, 1, 2), > - PLL_RATE(222000000, 37, 1, 2), > - PLL_RATE(228000000, 38, 1, 2), > - PLL_RATE(234000000, 39, 1, 2), > - PLL_RATE(240000000, 40, 1, 2), > - PLL_RATE(246000000, 41, 1, 2), > - PLL_RATE(252000000, 42, 1, 2), > - PLL_RATE(258000000, 43, 1, 2), > - PLL_RATE(264000000, 44, 1, 2), > - PLL_RATE(270000000, 45, 1, 2), > - PLL_RATE(276000000, 46, 1, 2), > - PLL_RATE(282000000, 47, 1, 2), > - PLL_RATE(288000000, 48, 1, 2), > - PLL_RATE(294000000, 49, 1, 2), > - PLL_RATE(300000000, 50, 1, 2), > - PLL_RATE(306000000, 51, 1, 2), > - PLL_RATE(312000000, 52, 1, 2), > - PLL_RATE(318000000, 53, 1, 2), > - PLL_RATE(324000000, 54, 1, 2), > - PLL_RATE(330000000, 55, 1, 2), > - PLL_RATE(336000000, 56, 1, 2), > - PLL_RATE(342000000, 57, 1, 2), > - PLL_RATE(348000000, 58, 1, 2), > - PLL_RATE(354000000, 59, 1, 2), > - PLL_RATE(360000000, 60, 1, 2), > - PLL_RATE(366000000, 61, 1, 2), > - PLL_RATE(372000000, 62, 1, 2), > - PLL_RATE(384000000, 32, 1, 1), > - PLL_RATE(396000000, 33, 1, 1), > - PLL_RATE(408000000, 34, 1, 1), > - PLL_RATE(420000000, 35, 1, 1), > - PLL_RATE(432000000, 36, 1, 1), > - PLL_RATE(444000000, 37, 1, 1), > - PLL_RATE(456000000, 38, 1, 1), > - PLL_RATE(468000000, 39, 1, 1), > - PLL_RATE(480000000, 40, 1, 1), > - PLL_RATE(492000000, 41, 1, 1), > - PLL_RATE(504000000, 42, 1, 1), > - PLL_RATE(516000000, 43, 1, 1), > - PLL_RATE(528000000, 44, 1, 1), > - PLL_RATE(540000000, 45, 1, 1), > - PLL_RATE(552000000, 46, 1, 1), > - PLL_RATE(564000000, 47, 1, 1), > - PLL_RATE(576000000, 48, 1, 1), > - PLL_RATE(588000000, 49, 1, 1), > - PLL_RATE(600000000, 50, 1, 1), > - PLL_RATE(612000000, 51, 1, 1), > - PLL_RATE(624000000, 52, 1, 1), > - PLL_RATE(636000000, 53, 1, 1), > - PLL_RATE(648000000, 54, 1, 1), > - PLL_RATE(660000000, 55, 1, 1), > - PLL_RATE(672000000, 56, 1, 1), > - PLL_RATE(684000000, 57, 1, 1), > - PLL_RATE(696000000, 58, 1, 1), > - PLL_RATE(708000000, 59, 1, 1), > - PLL_RATE(720000000, 60, 1, 1), > - PLL_RATE(732000000, 61, 1, 1), > - PLL_RATE(744000000, 62, 1, 1), > - PLL_RATE(768000000, 32, 1, 0), > - PLL_RATE(792000000, 33, 1, 0), > - PLL_RATE(816000000, 34, 1, 0), > - PLL_RATE(840000000, 35, 1, 0), > - PLL_RATE(864000000, 36, 1, 0), > - PLL_RATE(888000000, 37, 1, 0), > - PLL_RATE(912000000, 38, 1, 0), > - PLL_RATE(936000000, 39, 1, 0), > - PLL_RATE(960000000, 40, 1, 0), > - PLL_RATE(984000000, 41, 1, 0), > - PLL_RATE(1008000000, 42, 1, 0), > - PLL_RATE(1032000000, 43, 1, 0), > - PLL_RATE(1056000000, 44, 1, 0), > - PLL_RATE(1080000000, 45, 1, 0), > - PLL_RATE(1104000000, 46, 1, 0), > - PLL_RATE(1128000000, 47, 1, 0), > - PLL_RATE(1152000000, 48, 1, 0), > - PLL_RATE(1176000000, 49, 1, 0), > - PLL_RATE(1200000000, 50, 1, 0), > - PLL_RATE(1224000000, 51, 1, 0), > - PLL_RATE(1248000000, 52, 1, 0), > - PLL_RATE(1272000000, 53, 1, 0), > - PLL_RATE(1296000000, 54, 1, 0), > - PLL_RATE(1320000000, 55, 1, 0), > - PLL_RATE(1344000000, 56, 1, 0), > - PLL_RATE(1368000000, 57, 1, 0), > - PLL_RATE(1392000000, 58, 1, 0), > - PLL_RATE(1416000000, 59, 1, 0), > - PLL_RATE(1440000000, 60, 1, 0), > - PLL_RATE(1464000000, 61, 1, 0), > - PLL_RATE(1488000000, 62, 1, 0), > + PLL_RATE(768000000, 32, 1), > + PLL_RATE(792000000, 33, 1), > + PLL_RATE(816000000, 34, 1), > + PLL_RATE(840000000, 35, 1), > + PLL_RATE(864000000, 36, 1), > + PLL_RATE(888000000, 37, 1), > + PLL_RATE(912000000, 38, 1), > + PLL_RATE(936000000, 39, 1), > + PLL_RATE(960000000, 40, 1), > + PLL_RATE(984000000, 41, 1), > + PLL_RATE(1008000000, 42, 1), > + PLL_RATE(1032000000, 43, 1), > + PLL_RATE(1056000000, 44, 1), > + PLL_RATE(1080000000, 45, 1), > + PLL_RATE(1104000000, 46, 1), > + PLL_RATE(1128000000, 47, 1), > + PLL_RATE(1152000000, 48, 1), > + PLL_RATE(1176000000, 49, 1), > + PLL_RATE(1200000000, 50, 1), > + PLL_RATE(1224000000, 51, 1), > + PLL_RATE(1248000000, 52, 1), > + PLL_RATE(1272000000, 53, 1), > + PLL_RATE(1296000000, 54, 1), > + PLL_RATE(1320000000, 55, 1), > + PLL_RATE(1344000000, 56, 1), > + PLL_RATE(1368000000, 57, 1), > + PLL_RATE(1392000000, 58, 1), > + PLL_RATE(1416000000, 59, 1), > + PLL_RATE(1440000000, 60, 1), > + PLL_RATE(1464000000, 61, 1), > + PLL_RATE(1488000000, 62, 1), > { /* sentinel */ }, > }; > > static const struct pll_rate_table gxl_gp0_pll_rate_table[] = { > - PLL_RATE(504000000, 42, 1, 1), > - PLL_RATE(516000000, 43, 1, 1), > - PLL_RATE(528000000, 44, 1, 1), > - PLL_RATE(540000000, 45, 1, 1), > - PLL_RATE(552000000, 46, 1, 1), > - PLL_RATE(564000000, 47, 1, 1), > - PLL_RATE(576000000, 48, 1, 1), > - PLL_RATE(588000000, 49, 1, 1), > - PLL_RATE(600000000, 50, 1, 1), > - PLL_RATE(612000000, 51, 1, 1), > - PLL_RATE(624000000, 52, 1, 1), > - PLL_RATE(636000000, 53, 1, 1), > - PLL_RATE(648000000, 54, 1, 1), > - PLL_RATE(660000000, 55, 1, 1), > - PLL_RATE(672000000, 56, 1, 1), > - PLL_RATE(684000000, 57, 1, 1), > - PLL_RATE(696000000, 58, 1, 1), > - PLL_RATE(708000000, 59, 1, 1), > - PLL_RATE(720000000, 60, 1, 1), > - PLL_RATE(732000000, 61, 1, 1), > - PLL_RATE(744000000, 62, 1, 1), > - PLL_RATE(756000000, 63, 1, 1), > - PLL_RATE(768000000, 64, 1, 1), > - PLL_RATE(780000000, 65, 1, 1), > - PLL_RATE(792000000, 66, 1, 1), > + PLL_RATE(1008000000, 42, 1), > + PLL_RATE(1032000000, 43, 1), > + PLL_RATE(1056000000, 44, 1), > + PLL_RATE(1080000000, 45, 1), > + PLL_RATE(1104000000, 46, 1), > + PLL_RATE(1128000000, 47, 1), > + PLL_RATE(1152000000, 48, 1), > + PLL_RATE(1176000000, 49, 1), > + PLL_RATE(1200000000, 50, 1), > + PLL_RATE(1224000000, 51, 1), > + PLL_RATE(1248000000, 52, 1), > + PLL_RATE(1272000000, 53, 1), > + PLL_RATE(1296000000, 54, 1), > + PLL_RATE(1320000000, 55, 1), > + PLL_RATE(1344000000, 56, 1), > + PLL_RATE(1368000000, 57, 1), > + PLL_RATE(1392000000, 58, 1), > + PLL_RATE(1416000000, 59, 1), > + PLL_RATE(1440000000, 60, 1), > + PLL_RATE(1464000000, 61, 1), > + PLL_RATE(1488000000, 62, 1), > + PLL_RATE(1512000000, 63, 1), > + PLL_RATE(1536000000, 64, 1), > + PLL_RATE(1560000000, 65, 1), > + PLL_RATE(1584000000, 66, 1), > { /* sentinel */ }, > }; > > -static struct clk_regmap gxbb_fixed_pll = { > +static struct clk_regmap gxbb_fixed_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_MPLL_CNTL, > @@ -192,11 +99,6 @@ static struct clk_regmap gxbb_fixed_pll = { > .shift = 9, > .width = 5, > }, > - .od = { > - .reg_off = HHI_MPLL_CNTL, > - .shift = 16, > - .width = 2, > - }, > .frac = { > .reg_off = HHI_MPLL_CNTL2, > .shift = 0, > @@ -214,7 +116,7 @@ static struct clk_regmap gxbb_fixed_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "fixed_pll", > + .name = "fixed_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "xtal" }, > .num_parents = 1, > @@ -222,6 +124,21 @@ static struct clk_regmap gxbb_fixed_pll = { > }, > }; > > +static struct clk_regmap gxbb_fixed_pll = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_MPLL_CNTL, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "fixed_pll", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "fixed_pll_dco" }, > + .num_parents = 1, > + }, > +}; > + > static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { > .mult = 2, > .div = 1, > @@ -233,7 +150,7 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { > }, > }; > > -static struct clk_regmap gxbb_hdmi_pll = { > +static struct clk_regmap gxbb_hdmi_pll_dco = { > .data = &(struct meson_clk_pll_data){ > .en = { > .reg_off = HHI_HDMI_PLL_CNTL, > @@ -255,21 +172,6 @@ static struct clk_regmap gxbb_hdmi_pll = { > .shift = 0, > .width = 12, > }, > - .od = { > - .reg_off = HHI_HDMI_PLL_CNTL2, > - .shift = 16, > - .width = 2, > - }, > - .od2 = { > - .reg_off = HHI_HDMI_PLL_CNTL2, > - .shift = 22, > - .width = 2, > - }, > - .od3 = { > - .reg_off = HHI_HDMI_PLL_CNTL2, > - .shift = 18, > - .width = 2, > - }, > .l = { > .reg_off = HHI_HDMI_PLL_CNTL, > .shift = 31, > @@ -282,7 +184,7 @@ static struct clk_regmap gxbb_hdmi_pll = { > }, > }, > .hw.init = &(struct clk_init_data){ > - .name = "hdmi_pll", > + .name = "hdmi_pll_dco", > .ops = &meson_clk_pll_ro_ops, > .parent_names = (const char *[]){ "hdmi_pll_pre_mult" }, > .num_parents = 1, > @@ -290,70 +192,103 @@ static struct clk_regmap gxbb_hdmi_pll = { > }, > }; > > +static struct clk_regmap gxbb_hdmi_pll_od = { > + .data = &(struct clk_regmap_div_data){ > + .offset = HHI_HDMI_PLL_CNTL2, > + .shift = 16, > + .width = 2, > + .flags = CLK_DIVIDER_POWER_OF_TWO, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdmi_pll_od", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_names = (const char *[]){ "hdmi_pll_dco" }, > + .num_parents = 1, > + .flags = CLK_GET_RATE_NOCACHE, why do we need CLK_GET_RATE_NOCACHE here? also, shouldn't all _od clocks use CLK_SET_RATE_PARENT? (this applies to all new _od clocks, not just this one) Regards Martin
On Sat, 2018-07-21 at 22:01 +0200, Martin Blumenstingl wrote: > > +static struct clk_regmap gxbb_hdmi_pll_od = { > > + .data = &(struct clk_regmap_div_data){ > > + .offset = HHI_HDMI_PLL_CNTL2, > > + .shift = 16, > > + .width = 2, > > + .flags = CLK_DIVIDER_POWER_OF_TWO, > > + }, > > + .hw.init = &(struct clk_init_data){ > > + .name = "hdmi_pll_od", > > + .ops = &clk_regmap_divider_ro_ops, > > + .parent_names = (const char *[]){ "hdmi_pll_dco" }, > > + .num_parents = 1, > > + .flags = CLK_GET_RATE_NOCACHE, > > why do we need CLK_GET_RATE_NOCACHE here? > also, shouldn't all _od clocks use CLK_SET_RATE_PARENT? > (this applies to all new _od clocks, not just this one) The goal was to retain the original behavior of the clock. The pll has CLK_GET_RATE_NOCACHE, which is why I put it again in the od dividers. Same goes for ro_ops For the particular case of the HDMI PLL, the display driver still set the pll parameters m, n and ods directly which justify CLK_GET_RATE_NOCACHE for now. Of course, the goal is to remove this flag someday. I think there has been some good progress in the DRM driver to reach this goal. If we think the use CLK_GET_RATE_NOCACHE is not justified for some other plls, I would prefer if it was addressed in another patchset. Regarding SET_RATE_PARENT, with the pll set with ro_ops, it does not change anything but, I agree, it would be better to set flag for the future. Cheers Jerome
Hi Jerome, On Sat, Jul 21, 2018 at 10:42 PM Jerome Brunet <jbrunet@baylibre.com> wrote: > > On Sat, 2018-07-21 at 22:01 +0200, Martin Blumenstingl wrote: > > > +static struct clk_regmap gxbb_hdmi_pll_od = { > > > + .data = &(struct clk_regmap_div_data){ > > > + .offset = HHI_HDMI_PLL_CNTL2, > > > + .shift = 16, > > > + .width = 2, > > > + .flags = CLK_DIVIDER_POWER_OF_TWO, > > > + }, > > > + .hw.init = &(struct clk_init_data){ > > > + .name = "hdmi_pll_od", > > > + .ops = &clk_regmap_divider_ro_ops, > > > + .parent_names = (const char *[]){ "hdmi_pll_dco" }, > > > + .num_parents = 1, > > > + .flags = CLK_GET_RATE_NOCACHE, > > > > why do we need CLK_GET_RATE_NOCACHE here? > > also, shouldn't all _od clocks use CLK_SET_RATE_PARENT? > > (this applies to all new _od clocks, not just this one) > > The goal was to retain the original behavior of the clock. > The pll has CLK_GET_RATE_NOCACHE, which is why I put it again in the od > dividers. Same goes for ro_ops I missed that - thanks for the explanation! > For the particular case of the HDMI PLL, the display driver still set the pll > parameters m, n and ods directly which justify CLK_GET_RATE_NOCACHE for now. > Of course, the goal is to remove this flag someday. I think there has been some > good progress in the DRM driver to reach this goal. > > If we think the use CLK_GET_RATE_NOCACHE is not justified for some other plls, I > would prefer if it was addressed in another patchset. now that the reason is clear to me: I fully agree! > Regarding SET_RATE_PARENT, with the pll set with ro_ops, it does not change > anything but, I agree, it would be better to set flag for the future. I see adding SET_RATE_PARENT will probably save a bit of headache later on when enabling the write operation of the PLL and then wondering why the frequency is not changed Regards Martin
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 6d8976554656..572358062459 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -22,7 +22,7 @@ static DEFINE_SPINLOCK(meson_clk_lock); -static struct clk_regmap axg_fixed_pll = { +static struct clk_regmap axg_fixed_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_MPLL_CNTL, @@ -39,11 +39,6 @@ static struct clk_regmap axg_fixed_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_MPLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_MPLL_CNTL2, .shift = 0, @@ -61,14 +56,29 @@ static struct clk_regmap axg_fixed_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "fixed_pll", + .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; -static struct clk_regmap axg_sys_pll = { +static struct clk_regmap axg_fixed_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_MPLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "fixed_pll_dco" }, + .num_parents = 1, + }, +}; + +static struct clk_regmap axg_sys_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_SYS_PLL_CNTL, @@ -85,11 +95,6 @@ static struct clk_regmap axg_sys_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 16, - .width = 2, - }, .l = { .reg_off = HHI_SYS_PLL_CNTL, .shift = 31, @@ -102,7 +107,7 @@ static struct clk_regmap axg_sys_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "sys_pll", + .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, @@ -110,94 +115,51 @@ static struct clk_regmap axg_sys_pll = { }, }; +static struct clk_regmap axg_sys_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "sys_pll_dco" }, + .num_parents = 1, + }, +}; + static const struct pll_rate_table axg_gp0_pll_rate_table[] = { - PLL_RATE(240000000, 40, 1, 2), - PLL_RATE(246000000, 41, 1, 2), - PLL_RATE(252000000, 42, 1, 2), - PLL_RATE(258000000, 43, 1, 2), - PLL_RATE(264000000, 44, 1, 2), - PLL_RATE(270000000, 45, 1, 2), - PLL_RATE(276000000, 46, 1, 2), - PLL_RATE(282000000, 47, 1, 2), - PLL_RATE(288000000, 48, 1, 2), - PLL_RATE(294000000, 49, 1, 2), - PLL_RATE(300000000, 50, 1, 2), - PLL_RATE(306000000, 51, 1, 2), - PLL_RATE(312000000, 52, 1, 2), - PLL_RATE(318000000, 53, 1, 2), - PLL_RATE(324000000, 54, 1, 2), - PLL_RATE(330000000, 55, 1, 2), - PLL_RATE(336000000, 56, 1, 2), - PLL_RATE(342000000, 57, 1, 2), - PLL_RATE(348000000, 58, 1, 2), - PLL_RATE(354000000, 59, 1, 2), - PLL_RATE(360000000, 60, 1, 2), - PLL_RATE(366000000, 61, 1, 2), - PLL_RATE(372000000, 62, 1, 2), - PLL_RATE(378000000, 63, 1, 2), - PLL_RATE(384000000, 64, 1, 2), - PLL_RATE(390000000, 65, 1, 3), - PLL_RATE(396000000, 66, 1, 3), - PLL_RATE(402000000, 67, 1, 3), - PLL_RATE(408000000, 68, 1, 3), - PLL_RATE(480000000, 40, 1, 1), - PLL_RATE(492000000, 41, 1, 1), - PLL_RATE(504000000, 42, 1, 1), - PLL_RATE(516000000, 43, 1, 1), - PLL_RATE(528000000, 44, 1, 1), - PLL_RATE(540000000, 45, 1, 1), - PLL_RATE(552000000, 46, 1, 1), - PLL_RATE(564000000, 47, 1, 1), - PLL_RATE(576000000, 48, 1, 1), - PLL_RATE(588000000, 49, 1, 1), - PLL_RATE(600000000, 50, 1, 1), - PLL_RATE(612000000, 51, 1, 1), - PLL_RATE(624000000, 52, 1, 1), - PLL_RATE(636000000, 53, 1, 1), - PLL_RATE(648000000, 54, 1, 1), - PLL_RATE(660000000, 55, 1, 1), - PLL_RATE(672000000, 56, 1, 1), - PLL_RATE(684000000, 57, 1, 1), - PLL_RATE(696000000, 58, 1, 1), - PLL_RATE(708000000, 59, 1, 1), - PLL_RATE(720000000, 60, 1, 1), - PLL_RATE(732000000, 61, 1, 1), - PLL_RATE(744000000, 62, 1, 1), - PLL_RATE(756000000, 63, 1, 1), - PLL_RATE(768000000, 64, 1, 1), - PLL_RATE(780000000, 65, 1, 1), - PLL_RATE(792000000, 66, 1, 1), - PLL_RATE(804000000, 67, 1, 1), - PLL_RATE(816000000, 68, 1, 1), - PLL_RATE(960000000, 40, 1, 0), - PLL_RATE(984000000, 41, 1, 0), - PLL_RATE(1008000000, 42, 1, 0), - PLL_RATE(1032000000, 43, 1, 0), - PLL_RATE(1056000000, 44, 1, 0), - PLL_RATE(1080000000, 45, 1, 0), - PLL_RATE(1104000000, 46, 1, 0), - PLL_RATE(1128000000, 47, 1, 0), - PLL_RATE(1152000000, 48, 1, 0), - PLL_RATE(1176000000, 49, 1, 0), - PLL_RATE(1200000000, 50, 1, 0), - PLL_RATE(1224000000, 51, 1, 0), - PLL_RATE(1248000000, 52, 1, 0), - PLL_RATE(1272000000, 53, 1, 0), - PLL_RATE(1296000000, 54, 1, 0), - PLL_RATE(1320000000, 55, 1, 0), - PLL_RATE(1344000000, 56, 1, 0), - PLL_RATE(1368000000, 57, 1, 0), - PLL_RATE(1392000000, 58, 1, 0), - PLL_RATE(1416000000, 59, 1, 0), - PLL_RATE(1440000000, 60, 1, 0), - PLL_RATE(1464000000, 61, 1, 0), - PLL_RATE(1488000000, 62, 1, 0), - PLL_RATE(1512000000, 63, 1, 0), - PLL_RATE(1536000000, 64, 1, 0), - PLL_RATE(1560000000, 65, 1, 0), - PLL_RATE(1584000000, 66, 1, 0), - PLL_RATE(1608000000, 67, 1, 0), - PLL_RATE(1632000000, 68, 1, 0), + PLL_RATE(960000000, 40, 1), + PLL_RATE(984000000, 41, 1), + PLL_RATE(1008000000, 42, 1), + PLL_RATE(1032000000, 43, 1), + PLL_RATE(1056000000, 44, 1), + PLL_RATE(1080000000, 45, 1), + PLL_RATE(1104000000, 46, 1), + PLL_RATE(1128000000, 47, 1), + PLL_RATE(1152000000, 48, 1), + PLL_RATE(1176000000, 49, 1), + PLL_RATE(1200000000, 50, 1), + PLL_RATE(1224000000, 51, 1), + PLL_RATE(1248000000, 52, 1), + PLL_RATE(1272000000, 53, 1), + PLL_RATE(1296000000, 54, 1), + PLL_RATE(1320000000, 55, 1), + PLL_RATE(1344000000, 56, 1), + PLL_RATE(1368000000, 57, 1), + PLL_RATE(1392000000, 58, 1), + PLL_RATE(1416000000, 59, 1), + PLL_RATE(1440000000, 60, 1), + PLL_RATE(1464000000, 61, 1), + PLL_RATE(1488000000, 62, 1), + PLL_RATE(1512000000, 63, 1), + PLL_RATE(1536000000, 64, 1), + PLL_RATE(1560000000, 65, 1), + PLL_RATE(1584000000, 66, 1), + PLL_RATE(1608000000, 67, 1), + PLL_RATE(1632000000, 68, 1), { /* sentinel */ }, }; @@ -209,7 +171,7 @@ static const struct reg_sequence axg_gp0_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, }; -static struct clk_regmap axg_gp0_pll = { +static struct clk_regmap axg_gp0_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_GP0_PLL_CNTL, @@ -226,11 +188,6 @@ static struct clk_regmap axg_gp0_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_GP0_PLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_GP0_PLL_CNTL1, .shift = 0, @@ -251,13 +208,29 @@ static struct clk_regmap axg_gp0_pll = { .init_count = ARRAY_SIZE(axg_gp0_init_regs), }, .hw.init = &(struct clk_init_data){ - .name = "gp0_pll", + .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; +static struct clk_regmap axg_gp0_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_GP0_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "gp0_pll_dco" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static const struct reg_sequence axg_hifi_init_regs[] = { { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 }, { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be }, @@ -266,7 +239,7 @@ static const struct reg_sequence axg_hifi_init_regs[] = { { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 }, }; -static struct clk_regmap axg_hifi_pll = { +static struct clk_regmap axg_hifi_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_HIFI_PLL_CNTL, @@ -283,11 +256,6 @@ static struct clk_regmap axg_hifi_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_HIFI_PLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_HIFI_PLL_CNTL5, .shift = 0, @@ -309,13 +277,29 @@ static struct clk_regmap axg_hifi_pll = { .flags = CLK_MESON_PLL_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ - .name = "hifi_pll", + .name = "hifi_pll_dco", .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; +static struct clk_regmap axg_hifi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HIFI_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "hifi_pll_dco" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static struct clk_fixed_factor axg_fclk_div2_div = { .mult = 1, .div = 2, @@ -645,11 +629,9 @@ static struct clk_regmap axg_mpll3 = { static const struct pll_rate_table axg_pcie_pll_rate_table[] = { { - .rate = 100000000, + .rate = 1600000000, .m = 200, .n = 3, - .od = 1, - .od2 = 3, }, { /* sentinel */ }, }; @@ -661,9 +643,10 @@ static const struct reg_sequence axg_pcie_init_regs[] = { { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d }, { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 }, { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 }, + { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, }; -static struct clk_regmap axg_pcie_pll = { +static struct clk_regmap axg_pcie_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_PCIE_PLL_CNTL, @@ -680,16 +663,6 @@ static struct clk_regmap axg_pcie_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_PCIE_PLL_CNTL, - .shift = 16, - .width = 2, - }, - .od2 = { - .reg_off = HHI_PCIE_PLL_CNTL6, - .shift = 6, - .width = 2, - }, .frac = { .reg_off = HHI_PCIE_PLL_CNTL1, .shift = 0, @@ -710,13 +683,45 @@ static struct clk_regmap axg_pcie_pll = { .init_count = ARRAY_SIZE(axg_pcie_init_regs), }, .hw.init = &(struct clk_init_data){ - .name = "pcie_pll", + .name = "pcie_pll_dco", .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; +static struct clk_regmap axg_pcie_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_PCIE_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_od", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "pcie_pll_dco" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap axg_pcie_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_PCIE_PLL_CNTL6, + .shift = 6, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "pcie_pll_od" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static struct clk_regmap axg_pcie_mux = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_PCIE_PLL_CNTL6, @@ -1129,6 +1134,12 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = { [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw, [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw, [CLKID_GEN_CLK] = &axg_gen_clk.hw, + [CLKID_SYS_PLL_DCO] = &axg_sys_pll_dco.hw, + [CLKID_FIXED_PLL_DCO] = &axg_fixed_pll_dco.hw, + [CLKID_GP0_PLL_DCO] = &axg_gp0_pll_dco.hw, + [CLKID_HIFI_PLL_DCO] = &axg_hifi_pll_dco.hw, + [CLKID_PCIE_PLL_DCO] = &axg_pcie_pll_dco.hw, + [CLKID_PCIE_PLL_OD] = &axg_pcie_pll_od.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -1207,6 +1218,8 @@ static struct clk_regmap *const axg_clk_regmaps[] = { &axg_fclk_div4, &axg_fclk_div5, &axg_fclk_div7, + &axg_pcie_pll_dco, + &axg_pcie_pll_od, &axg_pcie_pll, &axg_pcie_mux, &axg_pcie_ref, @@ -1216,6 +1229,12 @@ static struct clk_regmap *const axg_clk_regmaps[] = { &axg_gen_clk_sel, &axg_gen_clk_div, &axg_gen_clk, + &axg_fixed_pll_dco, + &axg_sys_pll_dco, + &axg_gp0_pll_dco, + &axg_hifi_pll_dco, + &axg_pcie_pll_dco, + &axg_pcie_pll_od, }; static const struct of_device_id clkc_match_table[] = { diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h index 1d04144a1b2c..0431dabac629 100644 --- a/drivers/clk/meson/axg.h +++ b/drivers/clk/meson/axg.h @@ -133,8 +133,14 @@ #define CLKID_PCIE_REF 78 #define CLKID_GEN_CLK_SEL 82 #define CLKID_GEN_CLK_DIV 83 +#define CLKID_SYS_PLL_DCO 85 +#define CLKID_FIXED_PLL_DCO 86 +#define CLKID_GP0_PLL_DCO 87 +#define CLKID_HIFI_PLL_DCO 88 +#define CLKID_PCIE_PLL_DCO 89 +#define CLKID_PCIE_PLL_OD 90 -#define NR_CLKS 85 +#define NR_CLKS 91 /* include the CLKIDs that have been made part of the DT binding */ #include <dt-bindings/clock/axg-clkc.h> diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 8aaefe67025f..348a866f09eb 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -11,15 +11,19 @@ * In the most basic form, a Meson PLL is composed as follows: * * PLL - * +------------------------------+ - * | | - * in -----[ /N ]---[ *M ]---[ >>OD ]----->> out - * | ^ ^ | - * +------------------------------+ - * | | - * FREF VCO + * +--------------------------------+ + * | | + * | +--+ | + * in >>-----[ /N ]--->| | +-----+ | + * | | |------| DCO |---->> out + * | +--------->| | +--v--+ | + * | | +--+ | | + * | | | | + * | +--[ *(M + (F/Fmax) ]<--+ | + * | | + * +--------------------------------+ * - * out = in * (m + frac / frac_max) / (n << sum(ods)) + * out = in * (m + frac / frac_max) / n */ #include <linux/clk-provider.h> @@ -46,7 +50,6 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate, struct meson_clk_pll_data *pll) { u64 rate = (u64)parent_rate * pllt->m; - unsigned int od = pllt->od + pllt->od2 + pllt->od3; if (frac && MESON_PARM_APPLICABLE(&pll->frac)) { u64 frac_rate = (u64)parent_rate * frac; @@ -55,7 +58,7 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate, (1 << pll->frac.width)); } - return DIV_ROUND_UP_ULL(rate, pllt->n << od); + return DIV_ROUND_UP_ULL(rate, pllt->n); } static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, @@ -68,15 +71,6 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, pllt.n = meson_parm_read(clk->map, &pll->n); pllt.m = meson_parm_read(clk->map, &pll->m); - pllt.od = meson_parm_read(clk->map, &pll->od); - - pllt.od2 = MESON_PARM_APPLICABLE(&pll->od2) ? - meson_parm_read(clk->map, &pll->od2) : - 0; - - pllt.od3 = MESON_PARM_APPLICABLE(&pll->od3) ? - meson_parm_read(clk->map, &pll->od3) : - 0; frac = MESON_PARM_APPLICABLE(&pll->frac) ? meson_parm_read(clk->map, &pll->frac) : @@ -93,8 +87,6 @@ static u16 __pll_params_with_frac(unsigned long rate, u16 frac_max = (1 << pll->frac.width); u64 val = (u64)rate * pllt->n; - val <<= pllt->od + pllt->od2 + pllt->od3; - if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate); else @@ -242,13 +234,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, meson_parm_write(clk->map, &pll->n, pllt->n); meson_parm_write(clk->map, &pll->m, pllt->m); - meson_parm_write(clk->map, &pll->od, pllt->od); - - if (MESON_PARM_APPLICABLE(&pll->od2)) - meson_parm_write(clk->map, &pll->od2, pllt->od2); - if (MESON_PARM_APPLICABLE(&pll->od3)) - meson_parm_write(clk->map, &pll->od3, pllt->od3); if (MESON_PARM_APPLICABLE(&pll->frac)) { frac = __pll_params_with_frac(rate, parent_rate, pllt, pll); diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index c2ee37a78ceb..a2245e857f70 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -47,17 +47,13 @@ struct pll_rate_table { unsigned long rate; u16 m; u16 n; - u16 od; - u16 od2; - u16 od3; }; -#define PLL_RATE(_r, _m, _n, _od) \ +#define PLL_RATE(_r, _m, _n) \ { \ .rate = (_r), \ .m = (_m), \ .n = (_n), \ - .od = (_od), \ } #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0) @@ -67,9 +63,6 @@ struct meson_clk_pll_data { struct parm m; struct parm n; struct parm frac; - struct parm od; - struct parm od2; - struct parm od3; struct parm l; struct parm rst; const struct reg_sequence *init_regs; diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 5ed34566917c..e2d94498f098 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -19,163 +19,70 @@ static DEFINE_SPINLOCK(meson_clk_lock); static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = { - PLL_RATE(96000000, 32, 1, 3), - PLL_RATE(99000000, 33, 1, 3), - PLL_RATE(102000000, 34, 1, 3), - PLL_RATE(105000000, 35, 1, 3), - PLL_RATE(108000000, 36, 1, 3), - PLL_RATE(111000000, 37, 1, 3), - PLL_RATE(114000000, 38, 1, 3), - PLL_RATE(117000000, 39, 1, 3), - PLL_RATE(120000000, 40, 1, 3), - PLL_RATE(123000000, 41, 1, 3), - PLL_RATE(126000000, 42, 1, 3), - PLL_RATE(129000000, 43, 1, 3), - PLL_RATE(132000000, 44, 1, 3), - PLL_RATE(135000000, 45, 1, 3), - PLL_RATE(138000000, 46, 1, 3), - PLL_RATE(141000000, 47, 1, 3), - PLL_RATE(144000000, 48, 1, 3), - PLL_RATE(147000000, 49, 1, 3), - PLL_RATE(150000000, 50, 1, 3), - PLL_RATE(153000000, 51, 1, 3), - PLL_RATE(156000000, 52, 1, 3), - PLL_RATE(159000000, 53, 1, 3), - PLL_RATE(162000000, 54, 1, 3), - PLL_RATE(165000000, 55, 1, 3), - PLL_RATE(168000000, 56, 1, 3), - PLL_RATE(171000000, 57, 1, 3), - PLL_RATE(174000000, 58, 1, 3), - PLL_RATE(177000000, 59, 1, 3), - PLL_RATE(180000000, 60, 1, 3), - PLL_RATE(183000000, 61, 1, 3), - PLL_RATE(186000000, 62, 1, 3), - PLL_RATE(192000000, 32, 1, 2), - PLL_RATE(198000000, 33, 1, 2), - PLL_RATE(204000000, 34, 1, 2), - PLL_RATE(210000000, 35, 1, 2), - PLL_RATE(216000000, 36, 1, 2), - PLL_RATE(222000000, 37, 1, 2), - PLL_RATE(228000000, 38, 1, 2), - PLL_RATE(234000000, 39, 1, 2), - PLL_RATE(240000000, 40, 1, 2), - PLL_RATE(246000000, 41, 1, 2), - PLL_RATE(252000000, 42, 1, 2), - PLL_RATE(258000000, 43, 1, 2), - PLL_RATE(264000000, 44, 1, 2), - PLL_RATE(270000000, 45, 1, 2), - PLL_RATE(276000000, 46, 1, 2), - PLL_RATE(282000000, 47, 1, 2), - PLL_RATE(288000000, 48, 1, 2), - PLL_RATE(294000000, 49, 1, 2), - PLL_RATE(300000000, 50, 1, 2), - PLL_RATE(306000000, 51, 1, 2), - PLL_RATE(312000000, 52, 1, 2), - PLL_RATE(318000000, 53, 1, 2), - PLL_RATE(324000000, 54, 1, 2), - PLL_RATE(330000000, 55, 1, 2), - PLL_RATE(336000000, 56, 1, 2), - PLL_RATE(342000000, 57, 1, 2), - PLL_RATE(348000000, 58, 1, 2), - PLL_RATE(354000000, 59, 1, 2), - PLL_RATE(360000000, 60, 1, 2), - PLL_RATE(366000000, 61, 1, 2), - PLL_RATE(372000000, 62, 1, 2), - PLL_RATE(384000000, 32, 1, 1), - PLL_RATE(396000000, 33, 1, 1), - PLL_RATE(408000000, 34, 1, 1), - PLL_RATE(420000000, 35, 1, 1), - PLL_RATE(432000000, 36, 1, 1), - PLL_RATE(444000000, 37, 1, 1), - PLL_RATE(456000000, 38, 1, 1), - PLL_RATE(468000000, 39, 1, 1), - PLL_RATE(480000000, 40, 1, 1), - PLL_RATE(492000000, 41, 1, 1), - PLL_RATE(504000000, 42, 1, 1), - PLL_RATE(516000000, 43, 1, 1), - PLL_RATE(528000000, 44, 1, 1), - PLL_RATE(540000000, 45, 1, 1), - PLL_RATE(552000000, 46, 1, 1), - PLL_RATE(564000000, 47, 1, 1), - PLL_RATE(576000000, 48, 1, 1), - PLL_RATE(588000000, 49, 1, 1), - PLL_RATE(600000000, 50, 1, 1), - PLL_RATE(612000000, 51, 1, 1), - PLL_RATE(624000000, 52, 1, 1), - PLL_RATE(636000000, 53, 1, 1), - PLL_RATE(648000000, 54, 1, 1), - PLL_RATE(660000000, 55, 1, 1), - PLL_RATE(672000000, 56, 1, 1), - PLL_RATE(684000000, 57, 1, 1), - PLL_RATE(696000000, 58, 1, 1), - PLL_RATE(708000000, 59, 1, 1), - PLL_RATE(720000000, 60, 1, 1), - PLL_RATE(732000000, 61, 1, 1), - PLL_RATE(744000000, 62, 1, 1), - PLL_RATE(768000000, 32, 1, 0), - PLL_RATE(792000000, 33, 1, 0), - PLL_RATE(816000000, 34, 1, 0), - PLL_RATE(840000000, 35, 1, 0), - PLL_RATE(864000000, 36, 1, 0), - PLL_RATE(888000000, 37, 1, 0), - PLL_RATE(912000000, 38, 1, 0), - PLL_RATE(936000000, 39, 1, 0), - PLL_RATE(960000000, 40, 1, 0), - PLL_RATE(984000000, 41, 1, 0), - PLL_RATE(1008000000, 42, 1, 0), - PLL_RATE(1032000000, 43, 1, 0), - PLL_RATE(1056000000, 44, 1, 0), - PLL_RATE(1080000000, 45, 1, 0), - PLL_RATE(1104000000, 46, 1, 0), - PLL_RATE(1128000000, 47, 1, 0), - PLL_RATE(1152000000, 48, 1, 0), - PLL_RATE(1176000000, 49, 1, 0), - PLL_RATE(1200000000, 50, 1, 0), - PLL_RATE(1224000000, 51, 1, 0), - PLL_RATE(1248000000, 52, 1, 0), - PLL_RATE(1272000000, 53, 1, 0), - PLL_RATE(1296000000, 54, 1, 0), - PLL_RATE(1320000000, 55, 1, 0), - PLL_RATE(1344000000, 56, 1, 0), - PLL_RATE(1368000000, 57, 1, 0), - PLL_RATE(1392000000, 58, 1, 0), - PLL_RATE(1416000000, 59, 1, 0), - PLL_RATE(1440000000, 60, 1, 0), - PLL_RATE(1464000000, 61, 1, 0), - PLL_RATE(1488000000, 62, 1, 0), + PLL_RATE(768000000, 32, 1), + PLL_RATE(792000000, 33, 1), + PLL_RATE(816000000, 34, 1), + PLL_RATE(840000000, 35, 1), + PLL_RATE(864000000, 36, 1), + PLL_RATE(888000000, 37, 1), + PLL_RATE(912000000, 38, 1), + PLL_RATE(936000000, 39, 1), + PLL_RATE(960000000, 40, 1), + PLL_RATE(984000000, 41, 1), + PLL_RATE(1008000000, 42, 1), + PLL_RATE(1032000000, 43, 1), + PLL_RATE(1056000000, 44, 1), + PLL_RATE(1080000000, 45, 1), + PLL_RATE(1104000000, 46, 1), + PLL_RATE(1128000000, 47, 1), + PLL_RATE(1152000000, 48, 1), + PLL_RATE(1176000000, 49, 1), + PLL_RATE(1200000000, 50, 1), + PLL_RATE(1224000000, 51, 1), + PLL_RATE(1248000000, 52, 1), + PLL_RATE(1272000000, 53, 1), + PLL_RATE(1296000000, 54, 1), + PLL_RATE(1320000000, 55, 1), + PLL_RATE(1344000000, 56, 1), + PLL_RATE(1368000000, 57, 1), + PLL_RATE(1392000000, 58, 1), + PLL_RATE(1416000000, 59, 1), + PLL_RATE(1440000000, 60, 1), + PLL_RATE(1464000000, 61, 1), + PLL_RATE(1488000000, 62, 1), { /* sentinel */ }, }; static const struct pll_rate_table gxl_gp0_pll_rate_table[] = { - PLL_RATE(504000000, 42, 1, 1), - PLL_RATE(516000000, 43, 1, 1), - PLL_RATE(528000000, 44, 1, 1), - PLL_RATE(540000000, 45, 1, 1), - PLL_RATE(552000000, 46, 1, 1), - PLL_RATE(564000000, 47, 1, 1), - PLL_RATE(576000000, 48, 1, 1), - PLL_RATE(588000000, 49, 1, 1), - PLL_RATE(600000000, 50, 1, 1), - PLL_RATE(612000000, 51, 1, 1), - PLL_RATE(624000000, 52, 1, 1), - PLL_RATE(636000000, 53, 1, 1), - PLL_RATE(648000000, 54, 1, 1), - PLL_RATE(660000000, 55, 1, 1), - PLL_RATE(672000000, 56, 1, 1), - PLL_RATE(684000000, 57, 1, 1), - PLL_RATE(696000000, 58, 1, 1), - PLL_RATE(708000000, 59, 1, 1), - PLL_RATE(720000000, 60, 1, 1), - PLL_RATE(732000000, 61, 1, 1), - PLL_RATE(744000000, 62, 1, 1), - PLL_RATE(756000000, 63, 1, 1), - PLL_RATE(768000000, 64, 1, 1), - PLL_RATE(780000000, 65, 1, 1), - PLL_RATE(792000000, 66, 1, 1), + PLL_RATE(1008000000, 42, 1), + PLL_RATE(1032000000, 43, 1), + PLL_RATE(1056000000, 44, 1), + PLL_RATE(1080000000, 45, 1), + PLL_RATE(1104000000, 46, 1), + PLL_RATE(1128000000, 47, 1), + PLL_RATE(1152000000, 48, 1), + PLL_RATE(1176000000, 49, 1), + PLL_RATE(1200000000, 50, 1), + PLL_RATE(1224000000, 51, 1), + PLL_RATE(1248000000, 52, 1), + PLL_RATE(1272000000, 53, 1), + PLL_RATE(1296000000, 54, 1), + PLL_RATE(1320000000, 55, 1), + PLL_RATE(1344000000, 56, 1), + PLL_RATE(1368000000, 57, 1), + PLL_RATE(1392000000, 58, 1), + PLL_RATE(1416000000, 59, 1), + PLL_RATE(1440000000, 60, 1), + PLL_RATE(1464000000, 61, 1), + PLL_RATE(1488000000, 62, 1), + PLL_RATE(1512000000, 63, 1), + PLL_RATE(1536000000, 64, 1), + PLL_RATE(1560000000, 65, 1), + PLL_RATE(1584000000, 66, 1), { /* sentinel */ }, }; -static struct clk_regmap gxbb_fixed_pll = { +static struct clk_regmap gxbb_fixed_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_MPLL_CNTL, @@ -192,11 +99,6 @@ static struct clk_regmap gxbb_fixed_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_MPLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_MPLL_CNTL2, .shift = 0, @@ -214,7 +116,7 @@ static struct clk_regmap gxbb_fixed_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "fixed_pll", + .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, @@ -222,6 +124,21 @@ static struct clk_regmap gxbb_fixed_pll = { }, }; +static struct clk_regmap gxbb_fixed_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_MPLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "fixed_pll_dco" }, + .num_parents = 1, + }, +}; + static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { .mult = 2, .div = 1, @@ -233,7 +150,7 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { }, }; -static struct clk_regmap gxbb_hdmi_pll = { +static struct clk_regmap gxbb_hdmi_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_HDMI_PLL_CNTL, @@ -255,21 +172,6 @@ static struct clk_regmap gxbb_hdmi_pll = { .shift = 0, .width = 12, }, - .od = { - .reg_off = HHI_HDMI_PLL_CNTL2, - .shift = 16, - .width = 2, - }, - .od2 = { - .reg_off = HHI_HDMI_PLL_CNTL2, - .shift = 22, - .width = 2, - }, - .od3 = { - .reg_off = HHI_HDMI_PLL_CNTL2, - .shift = 18, - .width = 2, - }, .l = { .reg_off = HHI_HDMI_PLL_CNTL, .shift = 31, @@ -282,7 +184,7 @@ static struct clk_regmap gxbb_hdmi_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "hdmi_pll", + .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "hdmi_pll_pre_mult" }, .num_parents = 1, @@ -290,70 +192,103 @@ static struct clk_regmap gxbb_hdmi_pll = { }, }; +static struct clk_regmap gxbb_hdmi_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL2, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_regmap gxbb_hdmi_pll_od2 = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL2, + .shift = 22, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od2", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_od" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_regmap gxbb_hdmi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL2, + .shift = 18, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_od2" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_regmap gxl_hdmi_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL + 8, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_regmap gxl_hdmi_pll_od2 = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL + 8, + .shift = 22, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od2", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_od" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + static struct clk_regmap gxl_hdmi_pll = { - .data = &(struct meson_clk_pll_data){ - .en = { - .reg_off = HHI_HDMI_PLL_CNTL, - .shift = 30, - .width = 1, - }, - .m = { - .reg_off = HHI_HDMI_PLL_CNTL, - .shift = 0, - .width = 9, - }, - .n = { - .reg_off = HHI_HDMI_PLL_CNTL, - .shift = 9, - .width = 5, - }, - .frac = { - /* - * On gxl, there is a register shift due to - * HHI_HDMI_PLL_CNTL1 which does not exist on gxbb, - * so we compute the register offset based on the PLL - * base to get it right - */ - .reg_off = HHI_HDMI_PLL_CNTL + 4, - .shift = 0, - .width = 12, - }, - .od = { - .reg_off = HHI_HDMI_PLL_CNTL + 8, - .shift = 21, - .width = 2, - }, - .od2 = { - .reg_off = HHI_HDMI_PLL_CNTL + 8, - .shift = 23, - .width = 2, - }, - .od3 = { - .reg_off = HHI_HDMI_PLL_CNTL + 8, - .shift = 19, - .width = 2, - }, - .l = { - .reg_off = HHI_HDMI_PLL_CNTL, - .shift = 31, - .width = 1, - }, - .rst = { - .reg_off = HHI_HDMI_PLL_CNTL, - .shift = 29, - .width = 1, - }, + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL + 8, + .shift = 18, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", - .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ "xtal" }, + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_od2" }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, }; -static struct clk_regmap gxbb_sys_pll = { +static struct clk_regmap gxbb_sys_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_SYS_PLL_CNTL, @@ -370,11 +305,6 @@ static struct clk_regmap gxbb_sys_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 10, - .width = 2, - }, .l = { .reg_off = HHI_SYS_PLL_CNTL, .shift = 31, @@ -387,7 +317,7 @@ static struct clk_regmap gxbb_sys_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "sys_pll", + .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, @@ -395,13 +325,29 @@ static struct clk_regmap gxbb_sys_pll = { }, }; +static struct clk_regmap gxbb_sys_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS_PLL_CNTL, + .shift = 10, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "sys_pll_dco" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + static const struct reg_sequence gxbb_gp0_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL2, .def = 0x69c80000 }, { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a5590c4 }, { .reg = HHI_GP0_PLL_CNTL4, .def = 0x0000500d }, }; -static struct clk_regmap gxbb_gp0_pll = { +static struct clk_regmap gxbb_gp0_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_GP0_PLL_CNTL, @@ -418,11 +364,6 @@ static struct clk_regmap gxbb_gp0_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_GP0_PLL_CNTL, - .shift = 16, - .width = 2, - }, .l = { .reg_off = HHI_GP0_PLL_CNTL, .shift = 31, @@ -438,7 +379,7 @@ static struct clk_regmap gxbb_gp0_pll = { .init_count = ARRAY_SIZE(gxbb_gp0_init_regs), }, .hw.init = &(struct clk_init_data){ - .name = "gp0_pll", + .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, @@ -454,7 +395,7 @@ static const struct reg_sequence gxl_gp0_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, }; -static struct clk_regmap gxl_gp0_pll = { +static struct clk_regmap gxl_gp0_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_GP0_PLL_CNTL, @@ -471,11 +412,6 @@ static struct clk_regmap gxl_gp0_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_GP0_PLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_GP0_PLL_CNTL1, .shift = 0, @@ -496,7 +432,7 @@ static struct clk_regmap gxl_gp0_pll = { .init_count = ARRAY_SIZE(gxl_gp0_init_regs), }, .hw.init = &(struct clk_init_data){ - .name = "gp0_pll", + .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, @@ -504,6 +440,22 @@ static struct clk_regmap gxl_gp0_pll = { }, }; +static struct clk_regmap gxbb_gp0_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_GP0_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "gp0_pll_dco" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + }, +}; + static struct clk_fixed_factor gxbb_fclk_div2_div = { .mult = 1, .div = 2, @@ -1961,6 +1913,12 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, + [CLKID_FIXED_PLL_DCO] = &gxbb_fixed_pll_dco.hw, + [CLKID_HDMI_PLL_DCO] = &gxbb_hdmi_pll_dco.hw, + [CLKID_HDMI_PLL_OD] = &gxbb_hdmi_pll_od.hw, + [CLKID_HDMI_PLL_OD2] = &gxbb_hdmi_pll_od2.hw, + [CLKID_SYS_PLL_DCO] = &gxbb_sys_pll_dco.hw, + [CLKID_GP0_PLL_DCO] = &gxbb_gp0_pll_dco.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -1976,7 +1934,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { [CLKID_FCLK_DIV4] = &gxbb_fclk_div4.hw, [CLKID_FCLK_DIV5] = &gxbb_fclk_div5.hw, [CLKID_FCLK_DIV7] = &gxbb_fclk_div7.hw, - [CLKID_GP0_PLL] = &gxl_gp0_pll.hw, + [CLKID_GP0_PLL] = &gxbb_gp0_pll.hw, [CLKID_MPEG_SEL] = &gxbb_mpeg_clk_sel.hw, [CLKID_MPEG_DIV] = &gxbb_mpeg_clk_div.hw, [CLKID_CLK81] = &gxbb_clk81.hw, @@ -2126,19 +2084,29 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, + [CLKID_FIXED_PLL_DCO] = &gxbb_fixed_pll_dco.hw, + [CLKID_HDMI_PLL_DCO] = &gxbb_hdmi_pll_dco.hw, + [CLKID_HDMI_PLL_OD] = &gxl_hdmi_pll_od.hw, + [CLKID_HDMI_PLL_OD2] = &gxl_hdmi_pll_od2.hw, + [CLKID_SYS_PLL_DCO] = &gxbb_sys_pll_dco.hw, + [CLKID_GP0_PLL_DCO] = &gxl_gp0_pll_dco.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, }; static struct clk_regmap *const gxbb_clk_regmaps[] = { - &gxbb_gp0_pll, + &gxbb_gp0_pll_dco, &gxbb_hdmi_pll, + &gxbb_hdmi_pll_od, + &gxbb_hdmi_pll_od2, }; static struct clk_regmap *const gxl_clk_regmaps[] = { - &gxl_gp0_pll, + &gxl_gp0_pll_dco, &gxl_hdmi_pll, + &gxl_hdmi_pll_od, + &gxl_hdmi_pll_od2, }; static struct clk_regmap *const gx_clk_regmaps[] = { @@ -2293,6 +2261,10 @@ static struct clk_regmap *const gx_clk_regmaps[] = { &gxbb_gen_clk_sel, &gxbb_gen_clk_div, &gxbb_gen_clk, + &gxbb_fixed_pll_dco, + &gxbb_hdmi_pll_dco, + &gxbb_sys_pll_dco, + &gxbb_gp0_pll, }; struct clkc_data { diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h index 20dfb1daf5b8..72bc077d9663 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h @@ -159,8 +159,14 @@ #define CLKID_VDEC_HEVC_DIV 155 #define CLKID_GEN_CLK_SEL 157 #define CLKID_GEN_CLK_DIV 158 - -#define NR_CLKS 160 +#define CLKID_FIXED_PLL_DCO 160 +#define CLKID_HDMI_PLL_DCO 161 +#define CLKID_HDMI_PLL_OD 162 +#define CLKID_HDMI_PLL_OD2 163 +#define CLKID_SYS_PLL_DCO 164 +#define CLKID_GP0_PLL_DCO 165 + +#define NR_CLKS 166 /* include the CLKIDs that have been made part of the DT binding */ #include <dt-bindings/clock/gxbb-clkc.h> diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index fd4c414893f5..17bcf0be56ba 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -30,58 +30,21 @@ struct meson8b_clk_reset { }; static const struct pll_rate_table sys_pll_rate_table[] = { - PLL_RATE(312000000, 52, 1, 2), - PLL_RATE(336000000, 56, 1, 2), - PLL_RATE(360000000, 60, 1, 2), - PLL_RATE(384000000, 64, 1, 2), - PLL_RATE(408000000, 68, 1, 2), - PLL_RATE(432000000, 72, 1, 2), - PLL_RATE(456000000, 76, 1, 2), - PLL_RATE(480000000, 80, 1, 2), - PLL_RATE(504000000, 84, 1, 2), - PLL_RATE(528000000, 88, 1, 2), - PLL_RATE(552000000, 92, 1, 2), - PLL_RATE(576000000, 96, 1, 2), - PLL_RATE(600000000, 50, 1, 1), - PLL_RATE(624000000, 52, 1, 1), - PLL_RATE(648000000, 54, 1, 1), - PLL_RATE(672000000, 56, 1, 1), - PLL_RATE(696000000, 58, 1, 1), - PLL_RATE(720000000, 60, 1, 1), - PLL_RATE(744000000, 62, 1, 1), - PLL_RATE(768000000, 64, 1, 1), - PLL_RATE(792000000, 66, 1, 1), - PLL_RATE(816000000, 68, 1, 1), - PLL_RATE(840000000, 70, 1, 1), - PLL_RATE(864000000, 72, 1, 1), - PLL_RATE(888000000, 74, 1, 1), - PLL_RATE(912000000, 76, 1, 1), - PLL_RATE(936000000, 78, 1, 1), - PLL_RATE(960000000, 80, 1, 1), - PLL_RATE(984000000, 82, 1, 1), - PLL_RATE(1008000000, 84, 1, 1), - PLL_RATE(1032000000, 86, 1, 1), - PLL_RATE(1056000000, 88, 1, 1), - PLL_RATE(1080000000, 90, 1, 1), - PLL_RATE(1104000000, 92, 1, 1), - PLL_RATE(1128000000, 94, 1, 1), - PLL_RATE(1152000000, 96, 1, 1), - PLL_RATE(1176000000, 98, 1, 1), - PLL_RATE(1200000000, 50, 1, 0), - PLL_RATE(1224000000, 51, 1, 0), - PLL_RATE(1248000000, 52, 1, 0), - PLL_RATE(1272000000, 53, 1, 0), - PLL_RATE(1296000000, 54, 1, 0), - PLL_RATE(1320000000, 55, 1, 0), - PLL_RATE(1344000000, 56, 1, 0), - PLL_RATE(1368000000, 57, 1, 0), - PLL_RATE(1392000000, 58, 1, 0), - PLL_RATE(1416000000, 59, 1, 0), - PLL_RATE(1440000000, 60, 1, 0), - PLL_RATE(1464000000, 61, 1, 0), - PLL_RATE(1488000000, 62, 1, 0), - PLL_RATE(1512000000, 63, 1, 0), - PLL_RATE(1536000000, 64, 1, 0), + PLL_RATE(1200000000, 50, 1), + PLL_RATE(1224000000, 51, 1), + PLL_RATE(1248000000, 52, 1), + PLL_RATE(1272000000, 53, 1), + PLL_RATE(1296000000, 54, 1), + PLL_RATE(1320000000, 55, 1), + PLL_RATE(1344000000, 56, 1), + PLL_RATE(1368000000, 57, 1), + PLL_RATE(1392000000, 58, 1), + PLL_RATE(1416000000, 59, 1), + PLL_RATE(1440000000, 60, 1), + PLL_RATE(1464000000, 61, 1), + PLL_RATE(1488000000, 62, 1), + PLL_RATE(1512000000, 63, 1), + PLL_RATE(1536000000, 64, 1), { /* sentinel */ }, }; @@ -94,7 +57,7 @@ static struct clk_fixed_rate meson8b_xtal = { }, }; -static struct clk_regmap meson8b_fixed_pll = { +static struct clk_regmap meson8b_fixed_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_MPLL_CNTL, @@ -111,11 +74,6 @@ static struct clk_regmap meson8b_fixed_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_MPLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_MPLL_CNTL2, .shift = 0, @@ -133,7 +91,7 @@ static struct clk_regmap meson8b_fixed_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "fixed_pll", + .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, @@ -141,7 +99,23 @@ static struct clk_regmap meson8b_fixed_pll = { }, }; -static struct clk_regmap meson8b_vid_pll = { +static struct clk_regmap meson8b_fixed_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_MPLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "fixed_pll_dco" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_regmap meson8b_vid_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_VID_PLL_CNTL, @@ -158,11 +132,6 @@ static struct clk_regmap meson8b_vid_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_VID_PLL_CNTL, - .shift = 16, - .width = 2, - }, .l = { .reg_off = HHI_VID_PLL_CNTL, .shift = 31, @@ -175,7 +144,7 @@ static struct clk_regmap meson8b_vid_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "vid_pll", + .name = "vid_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, @@ -183,7 +152,23 @@ static struct clk_regmap meson8b_vid_pll = { }, }; -static struct clk_regmap meson8b_sys_pll = { +static struct clk_regmap meson8b_vid_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VID_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "vid_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "vid_pll_dco" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_regmap meson8b_sys_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_SYS_PLL_CNTL, @@ -200,11 +185,6 @@ static struct clk_regmap meson8b_sys_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 16, - .width = 2, - }, .l = { .reg_off = HHI_SYS_PLL_CNTL, .shift = 31, @@ -218,7 +198,7 @@ static struct clk_regmap meson8b_sys_pll = { .table = sys_pll_rate_table, }, .hw.init = &(struct clk_init_data){ - .name = "sys_pll", + .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, @@ -226,6 +206,22 @@ static struct clk_regmap meson8b_sys_pll = { }, }; +static struct clk_regmap meson8b_sys_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "sys_pll_dco" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + static struct clk_fixed_factor meson8b_fclk_div2_div = { .mult = 1, .div = 2, @@ -894,6 +890,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw, [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw, [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw, + [CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw, + [CLKID_PLL_VID_DCO] = &meson8b_vid_pll_dco.hw, + [CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -1002,6 +1001,9 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { &meson8b_nand_clk_sel, &meson8b_nand_clk_div, &meson8b_nand_clk_gate, + &meson8b_fixed_pll_dco, + &meson8b_vid_pll_dco, + &meson8b_sys_pll_dco, }; static const struct meson8b_clk_reset_line { diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index 5d09412b5084..1c6fb180e6a2 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h @@ -75,8 +75,11 @@ #define CLKID_FCLK_DIV7_DIV 109 #define CLKID_NAND_SEL 110 #define CLKID_NAND_DIV 111 +#define CLKID_PLL_FIXED_DCO 113 +#define CLKID_PLL_VID_DCO 114 +#define CLKID_PLL_SYS_DCO 115 -#define CLK_NR_CLKS 113 +#define CLK_NR_CLKS 116 /* * include the CLKID and RESETID that have
Remove od parameters from pll clocks and add post dividers clocks instead. Some clock, especially the one which feature several ods, may provide output between those ods. Also, some drivers, such as the hdmi driver, may require a more detailed control of the clock dividers, compared to what CCF would perform automatically. One added benefit of removing ods is that it also greatly reduce the size of the rate parameter tables. In the future, we could possibly take the predivider 'n' out of this driver as well. To do so, we will need to understand the constraints for the PLL to lock and whether or not it depends on the input clock rate. Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> --- drivers/clk/meson/axg.c | 279 ++++++++++++++------------ drivers/clk/meson/axg.h | 8 +- drivers/clk/meson/clk-pll.c | 40 ++-- drivers/clk/meson/clkc.h | 9 +- drivers/clk/meson/gxbb.c | 474 +++++++++++++++++++++----------------------- drivers/clk/meson/gxbb.h | 10 +- drivers/clk/meson/meson8b.c | 148 +++++++------- drivers/clk/meson/meson8b.h | 5 +- 8 files changed, 480 insertions(+), 493 deletions(-) -- 2.14.4