diff options
Diffstat (limited to 'target/linux/at91/patches-5.10/106-clk-at91-clk-sam9x60-pll-allow-runtime-changes-for-p.patch')
-rw-r--r-- | target/linux/at91/patches-5.10/106-clk-at91-clk-sam9x60-pll-allow-runtime-changes-for-p.patch | 510 |
1 files changed, 0 insertions, 510 deletions
diff --git a/target/linux/at91/patches-5.10/106-clk-at91-clk-sam9x60-pll-allow-runtime-changes-for-p.patch b/target/linux/at91/patches-5.10/106-clk-at91-clk-sam9x60-pll-allow-runtime-changes-for-p.patch deleted file mode 100644 index fa76cbb5a3..0000000000 --- a/target/linux/at91/patches-5.10/106-clk-at91-clk-sam9x60-pll-allow-runtime-changes-for-p.patch +++ /dev/null @@ -1,510 +0,0 @@ -From 6fe2927863de96edf35d8357712dbf83a489f556 Mon Sep 17 00:00:00 2001 -From: Claudiu Beznea <claudiu.beznea@microchip.com> -Date: Thu, 19 Nov 2020 17:43:12 +0200 -Subject: [PATCH 106/247] clk: at91: clk-sam9x60-pll: allow runtime changes for - pll - -Allow runtime frequency changes for PLLs registered with proper flags. -This is necessary for CPU PLL on SAMA7G5 which is used by DVFS. - -Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> -Link: https://lore.kernel.org/r/1605800597-16720-7-git-send-email-claudiu.beznea@microchip.com -Signed-off-by: Stephen Boyd <sboyd@kernel.org> ---- - drivers/clk/at91/clk-sam9x60-pll.c | 145 +++++++++++++++++++++++++---- - drivers/clk/at91/pmc.h | 4 +- - drivers/clk/at91/sam9x60.c | 22 ++++- - drivers/clk/at91/sama7g5.c | 67 +++++++++---- - 4 files changed, 197 insertions(+), 41 deletions(-) - ---- a/drivers/clk/at91/clk-sam9x60-pll.c -+++ b/drivers/clk/at91/clk-sam9x60-pll.c -@@ -229,6 +229,57 @@ static int sam9x60_frac_pll_set_rate(str - return sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true); - } - -+static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); -+ struct sam9x60_frac *frac = to_sam9x60_frac(core); -+ struct regmap *regmap = core->regmap; -+ unsigned long irqflags; -+ unsigned int val, cfrac, cmul; -+ long ret; -+ -+ ret = sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true); -+ if (ret <= 0) -+ return ret; -+ -+ spin_lock_irqsave(core->lock, irqflags); -+ -+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, -+ core->id); -+ regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val); -+ cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; -+ cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift; -+ -+ if (cmul == frac->mul && cfrac == frac->frac) -+ goto unlock; -+ -+ regmap_write(regmap, AT91_PMC_PLL_CTRL1, -+ (frac->mul << core->layout->mul_shift) | -+ (frac->frac << core->layout->frac_shift)); -+ -+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, -+ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, -+ AT91_PMC_PLL_UPDT_UPDATE | core->id); -+ -+ regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, -+ AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL, -+ AT91_PMC_PLL_CTRL0_ENLOCK | -+ AT91_PMC_PLL_CTRL0_ENPLL); -+ -+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, -+ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, -+ AT91_PMC_PLL_UPDT_UPDATE | core->id); -+ -+ while (!sam9x60_pll_ready(regmap, core->id)) -+ cpu_relax(); -+ -+unlock: -+ spin_unlock_irqrestore(core->lock, irqflags); -+ -+ return ret; -+} -+ - static const struct clk_ops sam9x60_frac_pll_ops = { - .prepare = sam9x60_frac_pll_prepare, - .unprepare = sam9x60_frac_pll_unprepare, -@@ -238,6 +289,15 @@ static const struct clk_ops sam9x60_frac - .set_rate = sam9x60_frac_pll_set_rate, - }; - -+static const struct clk_ops sam9x60_frac_pll_ops_chg = { -+ .prepare = sam9x60_frac_pll_prepare, -+ .unprepare = sam9x60_frac_pll_unprepare, -+ .is_prepared = sam9x60_frac_pll_is_prepared, -+ .recalc_rate = sam9x60_frac_pll_recalc_rate, -+ .round_rate = sam9x60_frac_pll_round_rate, -+ .set_rate = sam9x60_frac_pll_set_rate_chg, -+}; -+ - static int sam9x60_div_pll_prepare(struct clk_hw *hw) - { - struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); -@@ -384,6 +444,44 @@ static int sam9x60_div_pll_set_rate(stru - return 0; - } - -+static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); -+ struct sam9x60_div *div = to_sam9x60_div(core); -+ struct regmap *regmap = core->regmap; -+ unsigned long irqflags; -+ unsigned int val, cdiv; -+ -+ div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1; -+ -+ spin_lock_irqsave(core->lock, irqflags); -+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, -+ core->id); -+ regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); -+ cdiv = (val & core->layout->div_mask) >> core->layout->div_shift; -+ -+ /* Stop if nothing changed. */ -+ if (cdiv == div->div) -+ goto unlock; -+ -+ regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, -+ core->layout->div_mask, -+ (div->div << core->layout->div_shift)); -+ -+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, -+ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, -+ AT91_PMC_PLL_UPDT_UPDATE | core->id); -+ -+ while (!sam9x60_pll_ready(regmap, core->id)) -+ cpu_relax(); -+ -+unlock: -+ spin_unlock_irqrestore(core->lock, irqflags); -+ -+ return 0; -+} -+ - static const struct clk_ops sam9x60_div_pll_ops = { - .prepare = sam9x60_div_pll_prepare, - .unprepare = sam9x60_div_pll_unprepare, -@@ -393,17 +491,26 @@ static const struct clk_ops sam9x60_div_ - .set_rate = sam9x60_div_pll_set_rate, - }; - -+static const struct clk_ops sam9x60_div_pll_ops_chg = { -+ .prepare = sam9x60_div_pll_prepare, -+ .unprepare = sam9x60_div_pll_unprepare, -+ .is_prepared = sam9x60_div_pll_is_prepared, -+ .recalc_rate = sam9x60_div_pll_recalc_rate, -+ .round_rate = sam9x60_div_pll_round_rate, -+ .set_rate = sam9x60_div_pll_set_rate_chg, -+}; -+ - struct clk_hw * __init - sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, - const char *name, const char *parent_name, - struct clk_hw *parent_hw, u8 id, - const struct clk_pll_characteristics *characteristics, -- const struct clk_pll_layout *layout, bool critical) -+ const struct clk_pll_layout *layout, u32 flags) - { - struct sam9x60_frac *frac; - struct clk_hw *hw; - struct clk_init_data init; -- unsigned long parent_rate, flags; -+ unsigned long parent_rate, irqflags; - unsigned int val; - int ret; - -@@ -417,10 +524,12 @@ sam9x60_clk_register_frac_pll(struct reg - init.name = name; - init.parent_names = &parent_name; - init.num_parents = 1; -- init.ops = &sam9x60_frac_pll_ops; -- init.flags = CLK_SET_RATE_GATE; -- if (critical) -- init.flags |= CLK_IS_CRITICAL; -+ if (flags & CLK_SET_RATE_GATE) -+ init.ops = &sam9x60_frac_pll_ops; -+ else -+ init.ops = &sam9x60_frac_pll_ops_chg; -+ -+ init.flags = flags; - - frac->core.id = id; - frac->core.hw.init = &init; -@@ -429,7 +538,7 @@ sam9x60_clk_register_frac_pll(struct reg - frac->core.regmap = regmap; - frac->core.lock = lock; - -- spin_lock_irqsave(frac->core.lock, flags); -+ spin_lock_irqsave(frac->core.lock, irqflags); - if (sam9x60_pll_ready(regmap, id)) { - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_ID_MSK, id); -@@ -457,7 +566,7 @@ sam9x60_clk_register_frac_pll(struct reg - goto free; - } - } -- spin_unlock_irqrestore(frac->core.lock, flags); -+ spin_unlock_irqrestore(frac->core.lock, irqflags); - - hw = &frac->core.hw; - ret = clk_hw_register(NULL, hw); -@@ -469,7 +578,7 @@ sam9x60_clk_register_frac_pll(struct reg - return hw; - - free: -- spin_unlock_irqrestore(frac->core.lock, flags); -+ spin_unlock_irqrestore(frac->core.lock, irqflags); - kfree(frac); - return hw; - } -@@ -478,12 +587,12 @@ struct clk_hw * __init - sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, - const char *name, const char *parent_name, u8 id, - const struct clk_pll_characteristics *characteristics, -- const struct clk_pll_layout *layout, bool critical) -+ const struct clk_pll_layout *layout, u32 flags) - { - struct sam9x60_div *div; - struct clk_hw *hw; - struct clk_init_data init; -- unsigned long flags; -+ unsigned long irqflags; - unsigned int val; - int ret; - -@@ -497,11 +606,11 @@ sam9x60_clk_register_div_pll(struct regm - init.name = name; - init.parent_names = &parent_name; - init.num_parents = 1; -- init.ops = &sam9x60_div_pll_ops; -- init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | -- CLK_SET_RATE_PARENT; -- if (critical) -- init.flags |= CLK_IS_CRITICAL; -+ if (flags & CLK_SET_RATE_GATE) -+ init.ops = &sam9x60_div_pll_ops; -+ else -+ init.ops = &sam9x60_div_pll_ops_chg; -+ init.flags = flags; - - div->core.id = id; - div->core.hw.init = &init; -@@ -510,14 +619,14 @@ sam9x60_clk_register_div_pll(struct regm - div->core.regmap = regmap; - div->core.lock = lock; - -- spin_lock_irqsave(div->core.lock, flags); -+ spin_lock_irqsave(div->core.lock, irqflags); - - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_ID_MSK, id); - regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); - div->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val); - -- spin_unlock_irqrestore(div->core.lock, flags); -+ spin_unlock_irqrestore(div->core.lock, irqflags); - - hw = &div->core.hw; - ret = clk_hw_register(NULL, hw); ---- a/drivers/clk/at91/pmc.h -+++ b/drivers/clk/at91/pmc.h -@@ -190,14 +190,14 @@ struct clk_hw * __init - sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, - const char *name, const char *parent_name, u8 id, - const struct clk_pll_characteristics *characteristics, -- const struct clk_pll_layout *layout, bool critical); -+ const struct clk_pll_layout *layout, u32 flags); - - struct clk_hw * __init - sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, - const char *name, const char *parent_name, - struct clk_hw *parent_hw, u8 id, - const struct clk_pll_characteristics *characteristics, -- const struct clk_pll_layout *layout, bool critical); -+ const struct clk_pll_layout *layout, u32 flags); - - struct clk_hw * __init - at91_clk_register_programmable(struct regmap *regmap, const char *name, ---- a/drivers/clk/at91/sam9x60.c -+++ b/drivers/clk/at91/sam9x60.c -@@ -224,13 +224,24 @@ static void __init sam9x60_pmc_setup(str - hw = sam9x60_clk_register_frac_pll(regmap, &pmc_pll_lock, "pllack_fracck", - "mainck", sam9x60_pmc->chws[PMC_MAIN], - 0, &plla_characteristics, -- &pll_frac_layout, true); -+ &pll_frac_layout, -+ /* -+ * This feeds pllack_divck which -+ * feeds CPU. It should not be -+ * disabled. -+ */ -+ CLK_IS_CRITICAL | CLK_SET_RATE_GATE); - if (IS_ERR(hw)) - goto err_free; - - hw = sam9x60_clk_register_div_pll(regmap, &pmc_pll_lock, "pllack_divck", - "pllack_fracck", 0, &plla_characteristics, -- &pll_div_layout, true); -+ &pll_div_layout, -+ /* -+ * This feeds CPU. It should not -+ * be disabled. -+ */ -+ CLK_IS_CRITICAL | CLK_SET_RATE_GATE); - if (IS_ERR(hw)) - goto err_free; - -@@ -239,13 +250,16 @@ static void __init sam9x60_pmc_setup(str - hw = sam9x60_clk_register_frac_pll(regmap, &pmc_pll_lock, "upllck_fracck", - "main_osc", main_osc_hw, 1, - &upll_characteristics, -- &pll_frac_layout, false); -+ &pll_frac_layout, CLK_SET_RATE_GATE); - if (IS_ERR(hw)) - goto err_free; - - hw = sam9x60_clk_register_div_pll(regmap, &pmc_pll_lock, "upllck_divck", - "upllck_fracck", 1, &upll_characteristics, -- &pll_div_layout, false); -+ &pll_div_layout, -+ CLK_SET_RATE_GATE | -+ CLK_SET_PARENT_GATE | -+ CLK_SET_RATE_PARENT); - if (IS_ERR(hw)) - goto err_free; - ---- a/drivers/clk/at91/sama7g5.c -+++ b/drivers/clk/at91/sama7g5.c -@@ -95,15 +95,15 @@ static const struct clk_pll_layout pll_l - * @p: clock parent - * @l: clock layout - * @t: clock type -- * @f: true if clock is critical and cannot be disabled -+ * @f: clock flags - * @eid: export index in sama7g5->chws[] array - */ - static const struct { - const char *n; - const char *p; - const struct clk_pll_layout *l; -+ unsigned long f; - u8 t; -- u8 c; - u8 eid; - } sama7g5_plls[][PLL_ID_MAX] = { - [PLL_ID_CPU] = { -@@ -111,13 +111,18 @@ static const struct { - .p = "mainck", - .l = &pll_layout_frac, - .t = PLL_TYPE_FRAC, -- .c = 1, }, -+ /* -+ * This feeds cpupll_divpmcck which feeds CPU. It should -+ * not be disabled. -+ */ -+ .f = CLK_IS_CRITICAL, }, - - { .n = "cpupll_divpmcck", - .p = "cpupll_fracck", - .l = &pll_layout_divpmc, - .t = PLL_TYPE_DIV, -- .c = 1, -+ /* This feeds CPU. It should not be disabled. */ -+ .f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, - .eid = PMC_CPUPLL, }, - }, - -@@ -126,13 +131,22 @@ static const struct { - .p = "mainck", - .l = &pll_layout_frac, - .t = PLL_TYPE_FRAC, -- .c = 1, }, -+ /* -+ * This feeds syspll_divpmcck which may feed critial parts -+ * of the systems like timers. Therefore it should not be -+ * disabled. -+ */ -+ .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, - - { .n = "syspll_divpmcck", - .p = "syspll_fracck", - .l = &pll_layout_divpmc, - .t = PLL_TYPE_DIV, -- .c = 1, -+ /* -+ * This may feed critial parts of the systems like timers. -+ * Therefore it should not be disabled. -+ */ -+ .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, - .eid = PMC_SYSPLL, }, - }, - -@@ -141,55 +155,71 @@ static const struct { - .p = "mainck", - .l = &pll_layout_frac, - .t = PLL_TYPE_FRAC, -- .c = 1, }, -+ /* -+ * This feeds ddrpll_divpmcck which feeds DDR. It should not -+ * be disabled. -+ */ -+ .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, - - { .n = "ddrpll_divpmcck", - .p = "ddrpll_fracck", - .l = &pll_layout_divpmc, - .t = PLL_TYPE_DIV, -- .c = 1, }, -+ /* This feeds DDR. It should not be disabled. */ -+ .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, - }, - - [PLL_ID_IMG] = { - { .n = "imgpll_fracck", - .p = "mainck", - .l = &pll_layout_frac, -- .t = PLL_TYPE_FRAC, }, -+ .t = PLL_TYPE_FRAC, -+ .f = CLK_SET_RATE_GATE, }, - - { .n = "imgpll_divpmcck", - .p = "imgpll_fracck", - .l = &pll_layout_divpmc, -- .t = PLL_TYPE_DIV, }, -+ .t = PLL_TYPE_DIV, -+ .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | -+ CLK_SET_RATE_PARENT, }, - }, - - [PLL_ID_BAUD] = { - { .n = "baudpll_fracck", - .p = "mainck", - .l = &pll_layout_frac, -- .t = PLL_TYPE_FRAC, }, -+ .t = PLL_TYPE_FRAC, -+ .f = CLK_SET_RATE_GATE, }, - - { .n = "baudpll_divpmcck", - .p = "baudpll_fracck", - .l = &pll_layout_divpmc, -- .t = PLL_TYPE_DIV, }, -+ .t = PLL_TYPE_DIV, -+ .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | -+ CLK_SET_RATE_PARENT, }, - }, - - [PLL_ID_AUDIO] = { - { .n = "audiopll_fracck", - .p = "main_xtal", - .l = &pll_layout_frac, -- .t = PLL_TYPE_FRAC, }, -+ .t = PLL_TYPE_FRAC, -+ .f = CLK_SET_RATE_GATE, }, - - { .n = "audiopll_divpmcck", - .p = "audiopll_fracck", - .l = &pll_layout_divpmc, - .t = PLL_TYPE_DIV, -+ .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | -+ CLK_SET_RATE_PARENT, - .eid = PMC_AUDIOPMCPLL, }, - - { .n = "audiopll_diviock", - .p = "audiopll_fracck", - .l = &pll_layout_divio, - .t = PLL_TYPE_DIV, -+ .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | -+ CLK_SET_RATE_PARENT, - .eid = PMC_AUDIOIOPLL, }, - }, - -@@ -197,12 +227,15 @@ static const struct { - { .n = "ethpll_fracck", - .p = "main_xtal", - .l = &pll_layout_frac, -- .t = PLL_TYPE_FRAC, }, -+ .t = PLL_TYPE_FRAC, -+ .f = CLK_SET_RATE_GATE, }, - - { .n = "ethpll_divpmcck", - .p = "ethpll_fracck", - .l = &pll_layout_divpmc, -- .t = PLL_TYPE_DIV, }, -+ .t = PLL_TYPE_DIV, -+ .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | -+ CLK_SET_RATE_PARENT, }, - }, - }; - -@@ -890,7 +923,7 @@ static void __init sama7g5_pmc_setup(str - sama7g5_plls[i][j].p, parent_hw, i, - &pll_characteristics, - sama7g5_plls[i][j].l, -- sama7g5_plls[i][j].c); -+ sama7g5_plls[i][j].f); - break; - - case PLL_TYPE_DIV: -@@ -899,7 +932,7 @@ static void __init sama7g5_pmc_setup(str - sama7g5_plls[i][j].p, i, - &pll_characteristics, - sama7g5_plls[i][j].l, -- sama7g5_plls[i][j].c); -+ sama7g5_plls[i][j].f); - break; - - default: |