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:
@@ -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 = {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
Reference in New Issue
Block a user