Commit a910f251 authored by Icenowy Zheng's avatar Icenowy Zheng Committed by Maxime Ripard

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: default avatarIcenowy Zheng <icenowy@aosc.io>
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@bootlin.com>
parent 55de0f31
......@@ -95,7 +95,7 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
unsigned long n, m, k, p;
unsigned long n, m, k, p, rate;
u32 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 &= (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,
......@@ -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;
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate *= nkmp->fixed_post_div;
_nkmp.min_n = nkmp->n.min ?: 1;
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
_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);
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);
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,
......@@ -154,6 +165,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long flags;
u32 reg;
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate = rate * nkmp->fixed_post_div;
_nkmp.min_n = nkmp->n.min ?: 1;
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
_nkmp.min_k = nkmp->k.min ?: 1;
......
......@@ -34,6 +34,8 @@ struct ccu_nkmp {
struct ccu_div_internal m;
struct ccu_div_internal p;
unsigned int fixed_post_div;
struct ccu_common common;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment