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

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
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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;
};