diff options
| author | Stephen Boyd <sboyd@kernel.org> | 2025-07-21 10:26:31 -0700 |
|---|---|---|
| committer | Stephen Boyd <sboyd@kernel.org> | 2025-07-21 10:26:31 -0700 |
| commit | 0b4ff5bc7d75553e243de5e2baf867c9beb63bef (patch) | |
| tree | 16bb52dcb1f2d5c53125e18d1955185f28ee53fe | |
| parent | 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 (diff) | |
| parent | 80395c3b47577c12121d4e408e7b9478f7f88d02 (diff) | |
Merge tag 'sunxi-clk-for-6.17' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-allwinner
Pull Allwinner clk driver updates from Chen-Yu Tsai:
- Add Allwinner A523's missing PPU0 reset (both DT binding and
driver) The binding change is shared with the soc tree.
- Fix Allwinner V3s DE clock mux field width
- Stop passing rate change requests to parent for Allwinner V3s
DE clock
- Force and lock Allwinner V3s DE and TCON clocks to the same
parent, the video PLL
* tag 'sunxi-clk-for-6.17' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux:
clk: sunxi-ng: ccu_nm: convert from round_rate() to determine_rate()
clk: sunxi-ng: ccu_nkmp: convert from round_rate() to determine_rate()
clk: sunxi-ng: ccu_nk: convert from round_rate() to determine_rate()
clk: sunxi-ng: ccu_gate: convert from round_rate() to determine_rate()
clk: sunxi-ng: v3s: Assign the de and tcon clocks to the video pll
clk: sunxi-ng: v3s: Fix de clock definition
clk: sunxi-ng: sun55i-a523-r-ccu: Add missing PPU0 reset
dt-bindings: reset: sun55i-a523-r-ccu: Add missing PPU0 reset
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c | 1 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 22 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_gate.c | 14 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_nk.c | 14 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_nkmp.c | 23 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_nm.c | 43 | ||||
| -rw-r--r-- | include/dt-bindings/reset/sun55i-a523-r-ccu.h | 1 |
7 files changed, 70 insertions, 48 deletions
diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c index b5464d8083c8..70ce0ca0cb7d 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c @@ -204,6 +204,7 @@ static struct ccu_reset_map sun55i_a523_r_ccu_resets[] = { [RST_BUS_R_IR_RX] = { 0x1cc, BIT(16) }, [RST_BUS_R_RTC] = { 0x20c, BIT(16) }, [RST_BUS_R_CPUCFG] = { 0x22c, BIT(16) }, + [RST_BUS_R_PPU0] = { 0x1ac, BIT(16) }, }; static const struct sunxi_ccu_desc sun55i_a523_r_ccu_desc = { diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index 579a81bb46df..0c01aca4e19b 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c @@ -347,12 +347,13 @@ static SUNXI_CCU_GATE(dram_ohci_clk, "dram-ohci", "dram", static const char * const de_parents[] = { "pll-video", "pll-periph0" }; static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, - 0x104, 0, 4, 24, 2, BIT(31), - CLK_SET_RATE_PARENT); + 0x104, 0, 4, 24, 3, BIT(31), + CLK_SET_RATE_NO_REPARENT); static const char * const tcon_parents[] = { "pll-video" }; static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents, - 0x118, 0, 4, 24, 3, BIT(31), 0); + 0x118, 0, 4, 24, 3, BIT(31), + CLK_SET_RATE_NO_REPARENT); static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x130, BIT(31), 0); @@ -754,6 +755,21 @@ static int sun8i_v3s_ccu_probe(struct platform_device *pdev) val &= ~GENMASK(19, 16); writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG); + /* + * Assign the DE and TCON clock to the video PLL. Both clocks need to + * have the same parent for the units to work together. + */ + + val = readl(reg + de_clk.common.reg); + val &= ~GENMASK(de_clk.mux.shift + de_clk.mux.width - 1, + de_clk.mux.shift); + writel(val, reg + de_clk.common.reg); + + val = readl(reg + tcon_clk.common.reg); + val &= ~GENMASK(tcon_clk.mux.shift + tcon_clk.mux.width - 1, + tcon_clk.mux.shift); + writel(val, reg + tcon_clk.common.reg); + return devm_sunxi_ccu_probe(&pdev->dev, reg, desc); } diff --git a/drivers/clk/sunxi-ng/ccu_gate.c b/drivers/clk/sunxi-ng/ccu_gate.c index 474a9e8831f8..30673fe4e3c2 100644 --- a/drivers/clk/sunxi-ng/ccu_gate.c +++ b/drivers/clk/sunxi-ng/ccu_gate.c @@ -91,8 +91,8 @@ static unsigned long ccu_gate_recalc_rate(struct clk_hw *hw, return rate; } -static long ccu_gate_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int ccu_gate_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ccu_gate *cg = hw_to_ccu_gate(hw); int div = 1; @@ -101,14 +101,16 @@ static long ccu_gate_round_rate(struct clk_hw *hw, unsigned long rate, div = cg->common.prediv; if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { - unsigned long best_parent = rate; + unsigned long best_parent = req->rate; if (cg->common.features & CCU_FEATURE_ALL_PREDIV) best_parent *= div; - *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); + req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); } - return *prate / div; + req->rate = req->best_parent_rate / div; + + return 0; } static int ccu_gate_set_rate(struct clk_hw *hw, unsigned long rate, @@ -127,7 +129,7 @@ const struct clk_ops ccu_gate_ops = { .disable = ccu_gate_disable, .enable = ccu_gate_enable, .is_enabled = ccu_gate_is_enabled, - .round_rate = ccu_gate_round_rate, + .determine_rate = ccu_gate_determine_rate, .set_rate = ccu_gate_set_rate, .recalc_rate = ccu_gate_recalc_rate, }; diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c index 555e99de2cc6..5db748fbb5bd 100644 --- a/drivers/clk/sunxi-ng/ccu_nk.c +++ b/drivers/clk/sunxi-ng/ccu_nk.c @@ -92,26 +92,26 @@ static unsigned long ccu_nk_recalc_rate(struct clk_hw *hw, return rate; } -static long ccu_nk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ccu_nk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ccu_nk *nk = hw_to_ccu_nk(hw); struct _ccu_nk _nk; if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate *= nk->fixed_post_div; + req->rate *= nk->fixed_post_div; _nk.min_n = nk->n.min ?: 1; _nk.max_n = nk->n.max ?: 1 << nk->n.width; _nk.min_k = nk->k.min ?: 1; _nk.max_k = nk->k.max ?: 1 << nk->k.width; - rate = ccu_nk_find_best(*parent_rate, rate, &_nk); + req->rate = ccu_nk_find_best(req->best_parent_rate, req->rate, &_nk); if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate = rate / nk->fixed_post_div; + req->rate = req->rate / nk->fixed_post_div; - return rate; + return 0; } static int ccu_nk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -155,7 +155,7 @@ const struct clk_ops ccu_nk_ops = { .is_enabled = ccu_nk_is_enabled, .recalc_rate = ccu_nk_recalc_rate, - .round_rate = ccu_nk_round_rate, + .determine_rate = ccu_nk_determine_rate, .set_rate = ccu_nk_set_rate, }; EXPORT_SYMBOL_NS_GPL(ccu_nk_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index 6e03b69d4028..25efb5b37607 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -127,20 +127,20 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw, return rate; } -static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ccu_nkmp_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); struct _ccu_nkmp _nkmp; if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate *= nkmp->fixed_post_div; + req->rate *= nkmp->fixed_post_div; - if (nkmp->max_rate && rate > nkmp->max_rate) { - rate = nkmp->max_rate; + if (nkmp->max_rate && req->rate > nkmp->max_rate) { + req->rate = nkmp->max_rate; if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= nkmp->fixed_post_div; - return rate; + req->rate /= nkmp->fixed_post_div; + return 0; } _nkmp.min_n = nkmp->n.min ?: 1; @@ -152,12 +152,13 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, _nkmp.min_p = 1; _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); - rate = ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); + req->rate = ccu_nkmp_find_best(req->best_parent_rate, req->rate, + &_nkmp); if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate = rate / nkmp->fixed_post_div; + req->rate = req->rate / nkmp->fixed_post_div; - return rate; + return 0; } static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, @@ -227,7 +228,7 @@ const struct clk_ops ccu_nkmp_ops = { .is_enabled = ccu_nkmp_is_enabled, .recalc_rate = ccu_nkmp_recalc_rate, - .round_rate = ccu_nkmp_round_rate, + .determine_rate = ccu_nkmp_determine_rate, .set_rate = ccu_nkmp_set_rate, }; EXPORT_SYMBOL_NS_GPL(ccu_nkmp_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index a4e2243b8d6b..df01ed3b37a6 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c @@ -116,39 +116,39 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw, return rate; } -static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ccu_nm_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ccu_nm *nm = hw_to_ccu_nm(hw); struct _ccu_nm _nm; if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate *= nm->fixed_post_div; + req->rate *= nm->fixed_post_div; - if (rate < nm->min_rate) { - rate = nm->min_rate; + if (req->rate < nm->min_rate) { + req->rate = nm->min_rate; if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= nm->fixed_post_div; - return rate; + req->rate /= nm->fixed_post_div; + return 0; } - if (nm->max_rate && rate > nm->max_rate) { - rate = nm->max_rate; + if (nm->max_rate && req->rate > nm->max_rate) { + req->rate = nm->max_rate; if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= nm->fixed_post_div; - return rate; + req->rate /= nm->fixed_post_div; + return 0; } - if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) { + if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, req->rate)) { if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= nm->fixed_post_div; - return rate; + req->rate /= nm->fixed_post_div; + return 0; } - if (ccu_sdm_helper_has_rate(&nm->common, &nm->sdm, rate)) { + if (ccu_sdm_helper_has_rate(&nm->common, &nm->sdm, req->rate)) { if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= nm->fixed_post_div; - return rate; + req->rate /= nm->fixed_post_div; + return 0; } _nm.min_n = nm->n.min ?: 1; @@ -156,12 +156,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, _nm.min_m = 1; _nm.max_m = nm->m.max ?: 1 << nm->m.width; - rate = ccu_nm_find_best(&nm->common, *parent_rate, rate, &_nm); + req->rate = ccu_nm_find_best(&nm->common, req->best_parent_rate, + req->rate, &_nm); if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= nm->fixed_post_div; + req->rate /= nm->fixed_post_div; - return rate; + return 0; } static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate, @@ -233,7 +234,7 @@ const struct clk_ops ccu_nm_ops = { .is_enabled = ccu_nm_is_enabled, .recalc_rate = ccu_nm_recalc_rate, - .round_rate = ccu_nm_round_rate, + .determine_rate = ccu_nm_determine_rate, .set_rate = ccu_nm_set_rate, }; EXPORT_SYMBOL_NS_GPL(ccu_nm_ops, "SUNXI_CCU"); diff --git a/include/dt-bindings/reset/sun55i-a523-r-ccu.h b/include/dt-bindings/reset/sun55i-a523-r-ccu.h index dd6fbb372e19..eb31ae9958d6 100644 --- a/include/dt-bindings/reset/sun55i-a523-r-ccu.h +++ b/include/dt-bindings/reset/sun55i-a523-r-ccu.h @@ -21,5 +21,6 @@ #define RST_BUS_R_IR_RX 12 #define RST_BUS_R_RTC 13 #define RST_BUS_R_CPUCFG 14 +#define RST_BUS_R_PPU0 15 #endif /* _DT_BINDINGS_RST_SUN55I_A523_R_CCU_H_ */ |
