1
0

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
This commit is contained in:
Stephen Boyd
2025-07-21 10:26:31 -07:00
7 changed files with 70 additions and 48 deletions

View File

@@ -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 = {

View File

@@ -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);
}

View File

@@ -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,
};

View File

@@ -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");

View File

@@ -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");

View File

@@ -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");

View File

@@ -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_ */