From 4f8a13e1c2c2927e393755f703104e33907cdb4f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 27 Sep 2020 21:12:11 +0200 Subject: [PATCH 1/9] clk: uniphier: use semicolons rather than commas to separate statements Replace commas with semicolons. What is done is essentially described by the following Coccinelle semantic patch (http://coccinelle.lip6.fr/): // @@ expression e1,e2; @@ e1 -, +; e2 ... when any // Signed-off-by: Julia Lawall Link: https://lore.kernel.org/r/1601233948-11629-2-git-send-email-Julia.Lawall@inria.fr Signed-off-by: Stephen Boyd --- drivers/clk/uniphier/clk-uniphier-cpugear.c | 2 +- drivers/clk/uniphier/clk-uniphier-mux.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/uniphier/clk-uniphier-cpugear.c b/drivers/clk/uniphier/clk-uniphier-cpugear.c index 1a33a08abf2f..a2f01a4da127 100644 --- a/drivers/clk/uniphier/clk-uniphier-cpugear.c +++ b/drivers/clk/uniphier/clk-uniphier-cpugear.c @@ -90,7 +90,7 @@ struct clk_hw *uniphier_clk_register_cpugear(struct device *dev, init.ops = &uniphier_clk_cpugear_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = data->parent_names; - init.num_parents = data->num_parents, + init.num_parents = data->num_parents; gear->regmap = regmap; gear->regbase = data->regbase; diff --git a/drivers/clk/uniphier/clk-uniphier-mux.c b/drivers/clk/uniphier/clk-uniphier-mux.c index c0f4631601e2..462c84321b2d 100644 --- a/drivers/clk/uniphier/clk-uniphier-mux.c +++ b/drivers/clk/uniphier/clk-uniphier-mux.c @@ -70,7 +70,7 @@ struct clk_hw *uniphier_clk_register_mux(struct device *dev, init.ops = &uniphier_clk_mux_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = data->parent_names; - init.num_parents = data->num_parents, + init.num_parents = data->num_parents; mux->regmap = regmap; mux->reg = data->reg; From 39443a27cb78abc1425830e9f305d7cc0f4ad7ae Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 27 Sep 2020 21:12:19 +0200 Subject: [PATCH 2/9] clk: mvebu: ap80x-cpu: use semicolons rather than commas to separate statements Replace commas with semicolons. What is done is essentially described by the following Coccinelle semantic patch (http://coccinelle.lip6.fr/): // @@ expression e1,e2; @@ e1 -, +; e2 ... when any // Signed-off-by: Julia Lawall Link: https://lore.kernel.org/r/1601233948-11629-10-git-send-email-Julia.Lawall@inria.fr Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap-cpu-clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c index 6b394302c76a..b4259b60dcfd 100644 --- a/drivers/clk/mvebu/ap-cpu-clk.c +++ b/drivers/clk/mvebu/ap-cpu-clk.c @@ -197,7 +197,7 @@ static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate, stable_bit = BIT(clk->pll_regs->ratio_state_offset + clk->cluster * - clk->pll_regs->ratio_state_cluster_offset), + clk->pll_regs->ratio_state_cluster_offset); ret = regmap_read_poll_timeout(clk->pll_cr_base, clk->pll_regs->ratio_state_reg, reg, reg & stable_bit, STATUS_POLL_PERIOD_US, From 3270ee14557b583e9aa852d1bb413fc71ce1f0e0 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 27 Sep 2020 21:12:20 +0200 Subject: [PATCH 3/9] clk: meson: use semicolons rather than commas to separate statements Replace commas with semicolons. What is done is essentially described by the following Coccinelle semantic patch (http://coccinelle.lip6.fr/): // @@ expression e1,e2; @@ e1 -, +; e2 ... when any // Signed-off-by: Julia Lawall Link: https://lore.kernel.org/r/1601233948-11629-11-git-send-email-Julia.Lawall@inria.fr Signed-off-by: Stephen Boyd --- drivers/clk/meson/meson-aoclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c index bf8bea675d24..3a6d84cd6601 100644 --- a/drivers/clk/meson/meson-aoclk.c +++ b/drivers/clk/meson/meson-aoclk.c @@ -57,7 +57,7 @@ int meson_aoclkc_probe(struct platform_device *pdev) rstc->data = data; rstc->regmap = regmap; rstc->reset.ops = &meson_aoclk_reset_ops; - rstc->reset.nr_resets = data->num_reset, + rstc->reset.nr_resets = data->num_reset; rstc->reset.of_node = dev->of_node; ret = devm_reset_controller_register(dev, &rstc->reset); if (ret) { From 86378cf646d323d0ce0ac734d444f4d80fd9e43f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Oct 2020 11:59:47 +0300 Subject: [PATCH 4/9] clk: axi-clkgen: Add support for fractional dividers The axi-clkgen has (optional) fractional dividers on the output clock divider and feedback clock divider path. Utilizing the fractional dividers allows for a better resolution of the output clock, being able to synthesize more frequencies. Rework the driver support to support the fractional register fields, both for setting a new rate as well as reading back the current rate from the hardware. For setting the rate if no perfect divider settings were found in non-fractional mode try again in fractional mode and see if better settings can be found. This appears to be the recommended mode of operation. Signed-off-by: Lars-Peter Clausen Signed-off-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20201001085948.21412-1-alexandru.ardelean@analog.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-axi-clkgen.c | 182 +++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 52 deletions(-) diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 96f351785b41..1df03cc6d089 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -27,8 +27,10 @@ #define AXI_CLKGEN_V2_DRP_STATUS_BUSY BIT(16) +#define MMCM_REG_CLKOUT5_2 0x07 #define MMCM_REG_CLKOUT0_1 0x08 #define MMCM_REG_CLKOUT0_2 0x09 +#define MMCM_REG_CLKOUT6_2 0x13 #define MMCM_REG_CLK_FB1 0x14 #define MMCM_REG_CLK_FB2 0x15 #define MMCM_REG_CLK_DIV 0x16 @@ -40,6 +42,7 @@ #define MMCM_CLKOUT_NOCOUNT BIT(6) +#define MMCM_CLK_DIV_DIVIDE BIT(11) #define MMCM_CLK_DIV_NOCOUNT BIT(12) struct axi_clkgen { @@ -107,6 +110,8 @@ static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout, unsigned long d, d_min, d_max, _d_min, _d_max; unsigned long m, m_min, m_max; unsigned long f, dout, best_f, fvco; + unsigned long fract_shift = 0; + unsigned long fvco_min_fract, fvco_max_fract; fin /= 1000; fout /= 1000; @@ -119,42 +124,89 @@ static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout, d_min = max_t(unsigned long, DIV_ROUND_UP(fin, fpfd_max), 1); d_max = min_t(unsigned long, fin / fpfd_min, 80); - m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min, fin) * d_min, 1); - m_max = min_t(unsigned long, fvco_max * d_max / fin, 64); +again: + fvco_min_fract = fvco_min << fract_shift; + fvco_max_fract = fvco_max << fract_shift; + + m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min_fract, fin) * d_min, 1); + m_max = min_t(unsigned long, fvco_max_fract * d_max / fin, 64 << fract_shift); for (m = m_min; m <= m_max; m++) { - _d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max)); - _d_max = min(d_max, fin * m / fvco_min); + _d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max_fract)); + _d_max = min(d_max, fin * m / fvco_min_fract); for (d = _d_min; d <= _d_max; d++) { fvco = fin * m / d; dout = DIV_ROUND_CLOSEST(fvco, fout); - dout = clamp_t(unsigned long, dout, 1, 128); + dout = clamp_t(unsigned long, dout, 1, 128 << fract_shift); f = fvco / dout; if (abs(f - fout) < abs(best_f - fout)) { best_f = f; *best_d = d; - *best_m = m; - *best_dout = dout; + *best_m = m << (3 - fract_shift); + *best_dout = dout << (3 - fract_shift); if (best_f == fout) return; } } } + + /* Lets see if we find a better setting in fractional mode */ + if (fract_shift == 0) { + fract_shift = 3; + goto again; + } } -static void axi_clkgen_calc_clk_params(unsigned int divider, unsigned int *low, - unsigned int *high, unsigned int *edge, unsigned int *nocount) -{ - if (divider == 1) - *nocount = 1; - else - *nocount = 0; +struct axi_clkgen_div_params { + unsigned int low; + unsigned int high; + unsigned int edge; + unsigned int nocount; + unsigned int frac_en; + unsigned int frac; + unsigned int frac_wf_f; + unsigned int frac_wf_r; + unsigned int frac_phase; +}; - *high = divider / 2; - *edge = divider % 2; - *low = divider - *high; +static void axi_clkgen_calc_clk_params(unsigned int divider, + unsigned int frac_divider, struct axi_clkgen_div_params *params) +{ + + memset(params, 0x0, sizeof(*params)); + + if (divider == 1) { + params->nocount = 1; + return; + } + + if (frac_divider == 0) { + params->high = divider / 2; + params->edge = divider % 2; + params->low = divider - params->high; + } else { + params->frac_en = 1; + params->frac = frac_divider; + + params->high = divider / 2; + params->edge = divider % 2; + params->low = params->high; + + if (params->edge == 0) { + params->high--; + params->frac_wf_r = 1; + } + + if (params->edge == 0 || frac_divider == 1) + params->low--; + if (((params->edge == 0) ^ (frac_divider == 1)) || + (divider == 2 && frac_divider == 1)) + params->frac_wf_f = 1; + + params->frac_phase = params->edge * 4 + frac_divider / 2; + } } static void axi_clkgen_write(struct axi_clkgen *axi_clkgen, @@ -246,15 +298,28 @@ static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw) return container_of(clk_hw, struct axi_clkgen, clk_hw); } +static void axi_clkgen_set_div(struct axi_clkgen *axi_clkgen, + unsigned int reg1, unsigned int reg2, unsigned int reg3, + struct axi_clkgen_div_params *params) +{ + axi_clkgen_mmcm_write(axi_clkgen, reg1, + (params->high << 6) | params->low, 0xefff); + axi_clkgen_mmcm_write(axi_clkgen, reg2, + (params->frac << 12) | (params->frac_en << 11) | + (params->frac_wf_r << 10) | (params->edge << 7) | + (params->nocount << 6), 0x7fff); + if (reg3 != 0) { + axi_clkgen_mmcm_write(axi_clkgen, reg3, + (params->frac_phase << 11) | (params->frac_wf_f << 10), 0x3c00); + } +} + static int axi_clkgen_set_rate(struct clk_hw *clk_hw, unsigned long rate, unsigned long parent_rate) { struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); unsigned int d, m, dout; - unsigned int nocount; - unsigned int high; - unsigned int edge; - unsigned int low; + struct axi_clkgen_div_params params; uint32_t filter; uint32_t lock; @@ -269,21 +334,18 @@ static int axi_clkgen_set_rate(struct clk_hw *clk_hw, filter = axi_clkgen_lookup_filter(m - 1); lock = axi_clkgen_lookup_lock(m - 1); - axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount); - axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_1, - (high << 6) | low, 0xefff); - axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_2, - (edge << 7) | (nocount << 6), 0x03ff); + axi_clkgen_calc_clk_params(dout >> 3, dout & 0x7, ¶ms); + axi_clkgen_set_div(axi_clkgen, MMCM_REG_CLKOUT0_1, MMCM_REG_CLKOUT0_2, + MMCM_REG_CLKOUT5_2, ¶ms); - axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount); + axi_clkgen_calc_clk_params(d, 0, ¶ms); axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_DIV, - (edge << 13) | (nocount << 12) | (high << 6) | low, 0x3fff); + (params.edge << 13) | (params.nocount << 12) | + (params.high << 6) | params.low, 0x3fff); - axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount); - axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB1, - (high << 6) | low, 0xefff); - axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB2, - (edge << 7) | (nocount << 6), 0x03ff); + axi_clkgen_calc_clk_params(m >> 3, m & 0x7, ¶ms); + axi_clkgen_set_div(axi_clkgen, MMCM_REG_CLK_FB1, MMCM_REG_CLK_FB2, + MMCM_REG_CLKOUT6_2, ¶ms); axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK1, lock & 0x3ff, 0x3ff); axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK2, @@ -313,35 +375,51 @@ static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate, return min_t(unsigned long long, tmp, LONG_MAX); } +static unsigned int axi_clkgen_get_div(struct axi_clkgen *axi_clkgen, + unsigned int reg1, unsigned int reg2) +{ + unsigned int val1, val2; + unsigned int div; + + axi_clkgen_mmcm_read(axi_clkgen, reg2, &val2); + if (val2 & MMCM_CLKOUT_NOCOUNT) + return 8; + + axi_clkgen_mmcm_read(axi_clkgen, reg1, &val1); + + div = (val1 & 0x3f) + ((val1 >> 6) & 0x3f); + div <<= 3; + + if (val2 & MMCM_CLK_DIV_DIVIDE) { + if ((val2 & BIT(7)) && (val2 & 0x7000) != 0x1000) + div += 8; + else + div += 16; + + div += (val2 >> 12) & 0x7; + } + + return div; +} + static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw, unsigned long parent_rate) { struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); unsigned int d, m, dout; - unsigned int reg; unsigned long long tmp; + unsigned int val; - axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_2, ®); - if (reg & MMCM_CLKOUT_NOCOUNT) { - dout = 1; - } else { - axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, ®); - dout = (reg & 0x3f) + ((reg >> 6) & 0x3f); - } + dout = axi_clkgen_get_div(axi_clkgen, MMCM_REG_CLKOUT0_1, + MMCM_REG_CLKOUT0_2); + m = axi_clkgen_get_div(axi_clkgen, MMCM_REG_CLK_FB1, + MMCM_REG_CLK_FB2); - axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, ®); - if (reg & MMCM_CLK_DIV_NOCOUNT) + axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, &val); + if (val & MMCM_CLK_DIV_NOCOUNT) d = 1; else - d = (reg & 0x3f) + ((reg >> 6) & 0x3f); - - axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB2, ®); - if (reg & MMCM_CLKOUT_NOCOUNT) { - m = 1; - } else { - axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, ®); - m = (reg & 0x3f) + ((reg >> 6) & 0x3f); - } + d = (val & 0x3f) + ((val >> 6) & 0x3f); if (d == 0 || dout == 0) return 0; From a3947209d380cfcbd081597954fe6ee254e9681f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Oct 2020 11:59:48 +0300 Subject: [PATCH 5/9] clk: axi-clkgen: Set power bits for fractional mode Using the fractional dividers requires some additional power bits to be set. The fractional power bits are not documented and the current heuristic for setting them seems be insufficient for some cases. Just always set all the fractional power bits when in fractional mode. Signed-off-by: Lars-Peter Clausen Signed-off-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20201001085948.21412-2-alexandru.ardelean@analog.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-axi-clkgen.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 1df03cc6d089..14d803e6af62 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -37,6 +37,7 @@ #define MMCM_REG_LOCK1 0x18 #define MMCM_REG_LOCK2 0x19 #define MMCM_REG_LOCK3 0x1a +#define MMCM_REG_POWER 0x28 #define MMCM_REG_FILTER1 0x4e #define MMCM_REG_FILTER2 0x4f @@ -320,6 +321,7 @@ static int axi_clkgen_set_rate(struct clk_hw *clk_hw, struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); unsigned int d, m, dout; struct axi_clkgen_div_params params; + uint32_t power = 0; uint32_t filter; uint32_t lock; @@ -331,6 +333,11 @@ static int axi_clkgen_set_rate(struct clk_hw *clk_hw, if (d == 0 || dout == 0 || m == 0) return -EINVAL; + if ((dout & 0x7) != 0 || (m & 0x7) != 0) + power |= 0x9800; + + axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_POWER, power, 0x9800); + filter = axi_clkgen_lookup_filter(m - 1); lock = axi_clkgen_lookup_lock(m - 1); From e9501b975a9efb499f2ecbe3374d433b25c5b4f4 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Wed, 16 Sep 2020 11:03:10 +0800 Subject: [PATCH 6/9] clk: qoriq: modify MAX_PLL_DIV to 32 On LS2088A, Watchdog need clk divided by 32, so modify MAX_PLL_DIV to 32 Signed-off-by: Zhao Qiang Link: https://lore.kernel.org/r/20200916030311.17280-1-qiang.zhao@nxp.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-qoriq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 5942e9874bc0..46101c6a20f2 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -31,7 +31,7 @@ #define CGA_PLL4 4 /* only on clockgen-1.0, which lacks CGB */ #define CGB_PLL1 4 #define CGB_PLL2 5 -#define MAX_PLL_DIV 16 +#define MAX_PLL_DIV 32 struct clockgen_pll_div { struct clk *clk; From 9ba9ad8f5be0ff6af87ed23e4d872f4eb422b525 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Sun, 20 Sep 2020 14:03:35 +0300 Subject: [PATCH 7/9] clk: baikal-t1: Mark Ethernet PLL as critical We've discovered that disabling the so called Ethernet PLL causes reset of the devices consuming its outgoing clock. The resets happen automatically even if each underlying clock gate is turned off. Due to that we can't disable the Ethernet PLL until the kernel is prepared for the corresponding resets. So for now just mark the PLL clock provider as critical. Signed-off-by: Serge Semin Cc: Alexey Malahov Cc: linux-mips@vger.kernel.org Link: https://lore.kernel.org/r/20200920110335.18034-1-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd --- drivers/clk/baikal-t1/clk-ccu-pll.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/clk/baikal-t1/clk-ccu-pll.c b/drivers/clk/baikal-t1/clk-ccu-pll.c index 1eec8c0b8f50..2445d4b12baf 100644 --- a/drivers/clk/baikal-t1/clk-ccu-pll.c +++ b/drivers/clk/baikal-t1/clk-ccu-pll.c @@ -51,11 +51,13 @@ struct ccu_pll_info { }; /* - * Mark as critical all PLLs except Ethernet one. CPU and DDR PLLs are sources - * of CPU cores and DDR controller reference clocks, due to which they - * obviously shouldn't be ever gated. SATA and PCIe PLLs are the parents of - * APB-bus and DDR controller AXI-bus clocks. If they are gated the system will - * be unusable. + * Alas we have to mark all PLLs as critical. CPU and DDR PLLs are sources of + * CPU cores and DDR controller reference clocks, due to which they obviously + * shouldn't be ever gated. SATA and PCIe PLLs are the parents of APB-bus and + * DDR controller AXI-bus clocks. If they are gated the system will be + * unusable. Moreover disabling SATA and Ethernet PLLs causes automatic reset + * of the corresponding subsystems. So until we aren't ready to re-initialize + * all the devices consuming those PLLs, they will be marked as critical too. */ static const struct ccu_pll_info pll_info[] = { CCU_PLL_INFO(CCU_CPU_PLL, "cpu_pll", "ref_clk", CCU_CPU_PLL_BASE, @@ -67,7 +69,7 @@ static const struct ccu_pll_info pll_info[] = { CCU_PLL_INFO(CCU_PCIE_PLL, "pcie_pll", "ref_clk", CCU_PCIE_PLL_BASE, CLK_IS_CRITICAL), CCU_PLL_INFO(CCU_ETH_PLL, "eth_pll", "ref_clk", CCU_ETH_PLL_BASE, - CLK_SET_RATE_GATE) + CLK_IS_CRITICAL | CLK_SET_RATE_GATE) }; struct ccu_pll_data { From 6487649ee8b81d6c3a4eb7f17505f7fe397fdca3 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Tue, 22 Sep 2020 20:47:15 +0200 Subject: [PATCH 8/9] clk: pxa: Constify static struct clk_ops Constify a couple of static struct clk_ops that are not modified. Their only usage is inside the macros and their address is passed to clk_register_composite() which takes pointers to const struct clk_ops. This allows the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200922184715.1854-1-rikard.falkeborn@gmail.com Signed-off-by: Stephen Boyd --- drivers/clk/pxa/clk-pxa.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/pxa/clk-pxa.h b/drivers/clk/pxa/clk-pxa.h index f131d2834af4..5768e0f728ce 100644 --- a/drivers/clk/pxa/clk-pxa.h +++ b/drivers/clk/pxa/clk-pxa.h @@ -19,11 +19,11 @@ #define MUX_RO_RATE_RO_OPS(name, clk_name) \ static struct clk_hw name ## _mux_hw; \ static struct clk_hw name ## _rate_hw; \ - static struct clk_ops name ## _mux_ops = { \ + static const struct clk_ops name ## _mux_ops = { \ .get_parent = name ## _get_parent, \ .set_parent = dummy_clk_set_parent, \ }; \ - static struct clk_ops name ## _rate_ops = { \ + static const struct clk_ops name ## _rate_ops = { \ .recalc_rate = name ## _get_rate, \ }; \ static struct clk * __init clk_register_ ## name(void) \ @@ -38,7 +38,7 @@ #define RATE_RO_OPS(name, clk_name) \ static struct clk_hw name ## _rate_hw; \ - static const struct clk_ops name ## _rate_ops = { \ + static const struct clk_ops name ## _rate_ops = { \ .recalc_rate = name ## _get_rate, \ }; \ static struct clk * __init clk_register_ ## name(void) \ @@ -53,7 +53,7 @@ #define RATE_OPS(name, clk_name) \ static struct clk_hw name ## _rate_hw; \ - static struct clk_ops name ## _rate_ops = { \ + static const struct clk_ops name ## _rate_ops = { \ .recalc_rate = name ## _get_rate, \ .set_rate = name ## _set_rate, \ .determine_rate = name ## _determine_rate, \ From 07c565b42a04f38c49c3b09f89917cdf282c4743 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 26 Sep 2020 01:39:14 +0200 Subject: [PATCH 9/9] clk: mmp2: Fix the display clock divider base The LCD clock dividers are apparently based on one. No datasheet, determined empirically, but seems to be confirmed by line 19 of lcd.fth in OLPC laptop's Open Firmware [1]: h# 00000700 value pmua-disp-clk-sel \ PLL1 / 7 -> 113.86 MHz [1] https://raw.githubusercontent.com/quozl/openfirmware/65a08a73b2cac/cpu/arm/olpc/lcd.fth Signed-off-by: Lubomir Rintel Link: https://lore.kernel.org/r/20200925233914.227786-1-lkundrak@v3.sk Signed-off-by: Stephen Boyd --- drivers/clk/mmp/clk-of-mmp2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c index 67208aea94c5..0839fb2049e9 100644 --- a/drivers/clk/mmp/clk-of-mmp2.c +++ b/drivers/clk/mmp/clk-of-mmp2.c @@ -347,9 +347,9 @@ static struct mmp_param_mux_clk mmp3_apmu_mux_clks[] = { }; static struct mmp_param_div_clk apmu_div_clks[] = { - {0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, 0, &disp0_lock}, + {0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, CLK_DIVIDER_ONE_BASED, &disp0_lock}, {0, "disp0_sphy_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 15, 5, 0, &disp0_lock}, - {0, "disp1_div", "disp1_mux", CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4, 0, &disp1_lock}, + {0, "disp1_div", "disp1_mux", CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4, CLK_DIVIDER_ONE_BASED, &disp1_lock}, {0, "ccic0_sphy_div", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock}, {0, "ccic1_sphy_div", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 10, 5, 0, &ccic1_lock}, };