clk: sunxi-ng: Support fixed post-dividers on NKMP style clocks
On the new Allwinner H6 SoC, multiple PLL's are NMP style clocks (modelled as NKMP with no K) and have fixed post-dividers. Add fixed post divider support to the NKMP style clocks. Signed-off-by: Icenowy Zheng <icenowy@aosc.io> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
This commit is contained in:
parent
55de0f31df
commit
a910f251ee
|
@ -95,7 +95,7 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
|
||||||
unsigned long parent_rate)
|
unsigned long parent_rate)
|
||||||
{
|
{
|
||||||
struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
|
struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
|
||||||
unsigned long n, m, k, p;
|
unsigned long n, m, k, p, rate;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
reg = readl(nkmp->common.base + nkmp->common.reg);
|
reg = readl(nkmp->common.base + nkmp->common.reg);
|
||||||
|
@ -121,7 +121,11 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
|
||||||
p = reg >> nkmp->p.shift;
|
p = reg >> nkmp->p.shift;
|
||||||
p &= (1 << nkmp->p.width) - 1;
|
p &= (1 << nkmp->p.width) - 1;
|
||||||
|
|
||||||
return ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p);
|
rate = ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p);
|
||||||
|
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate /= nkmp->fixed_post_div;
|
||||||
|
|
||||||
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
|
static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
|
@ -130,6 +134,9 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
|
struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
|
||||||
struct _ccu_nkmp _nkmp;
|
struct _ccu_nkmp _nkmp;
|
||||||
|
|
||||||
|
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate *= nkmp->fixed_post_div;
|
||||||
|
|
||||||
_nkmp.min_n = nkmp->n.min ?: 1;
|
_nkmp.min_n = nkmp->n.min ?: 1;
|
||||||
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
|
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
|
||||||
_nkmp.min_k = nkmp->k.min ?: 1;
|
_nkmp.min_k = nkmp->k.min ?: 1;
|
||||||
|
@ -141,8 +148,12 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
|
|
||||||
ccu_nkmp_find_best(*parent_rate, rate, &_nkmp);
|
ccu_nkmp_find_best(*parent_rate, rate, &_nkmp);
|
||||||
|
|
||||||
return ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k,
|
rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k,
|
||||||
_nkmp.m, _nkmp.p);
|
_nkmp.m, _nkmp.p);
|
||||||
|
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate = rate / nkmp->fixed_post_div;
|
||||||
|
|
||||||
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
|
static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
|
@ -154,6 +165,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate = rate * nkmp->fixed_post_div;
|
||||||
|
|
||||||
_nkmp.min_n = nkmp->n.min ?: 1;
|
_nkmp.min_n = nkmp->n.min ?: 1;
|
||||||
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
|
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
|
||||||
_nkmp.min_k = nkmp->k.min ?: 1;
|
_nkmp.min_k = nkmp->k.min ?: 1;
|
||||||
|
|
|
@ -34,6 +34,8 @@ struct ccu_nkmp {
|
||||||
struct ccu_div_internal m;
|
struct ccu_div_internal m;
|
||||||
struct ccu_div_internal p;
|
struct ccu_div_internal p;
|
||||||
|
|
||||||
|
unsigned int fixed_post_div;
|
||||||
|
|
||||||
struct ccu_common common;
|
struct ccu_common common;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue