Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cfa63688 authored by Chen-Yu Tsai's avatar Chen-Yu Tsai Committed by Maxime Ripard
Browse files

clk: sunxi: factors: Consolidate get_factors parameters into a struct



The .get_factors callback of factors_clk has 6 parameters. To extend
factors_clk in any way that requires adding parameters to .get_factors
would make that list even longer, not to mention changing all the
function declarations.

Do this once now and consolidate all the parameters into a struct.
Also drop the space before function pointer arguments, since checkpatch
complains.

Signed-off-by: default avatarChen-Yu Tsai <wens@csie.org>
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
parent 4cbeaebb
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -73,8 +73,13 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
				   unsigned long *parent_rate)
{
	struct clk_factors *factors = to_clk_factors(hw);
	factors->get_factors((u32 *)&rate, (u32)*parent_rate,
			     NULL, NULL, NULL, NULL);
	struct factors_request req = {
		.rate = rate,
		.parent_rate = *parent_rate,
	};

	factors->get_factors(&req);


	return rate;
}
@@ -120,13 +125,16 @@ static int clk_factors_determine_rate(struct clk_hw *hw,
static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
				unsigned long parent_rate)
{
	u8 n = 0, k = 0, m = 0, p = 0;
	struct factors_request req = {
		.rate = rate,
		.parent_rate = parent_rate,
	};
	u32 reg;
	struct clk_factors *factors = to_clk_factors(hw);
	const struct clk_factors_config *config = factors->config;
	unsigned long flags = 0;

	factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p);
	factors->get_factors(&req);

	if (factors->lock)
		spin_lock_irqsave(factors->lock, flags);
@@ -135,10 +143,10 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
	reg = readl(factors->reg);

	/* Set up the new factors - macros do not do anything if width is 0 */
	reg = FACTOR_SET(config->nshift, config->nwidth, reg, n);
	reg = FACTOR_SET(config->kshift, config->kwidth, reg, k);
	reg = FACTOR_SET(config->mshift, config->mwidth, reg, m);
	reg = FACTOR_SET(config->pshift, config->pwidth, reg, p);
	reg = FACTOR_SET(config->nshift, config->nwidth, reg, req.n);
	reg = FACTOR_SET(config->kshift, config->kwidth, reg, req.k);
	reg = FACTOR_SET(config->mshift, config->mwidth, reg, req.m);
	reg = FACTOR_SET(config->pshift, config->pwidth, reg, req.p);

	/* Apply them now */
	writel(reg, factors->reg);
+11 −2
Original line number Diff line number Diff line
@@ -19,12 +19,21 @@ struct clk_factors_config {
	u8 n_start;
};

struct factors_request {
	unsigned long rate;
	unsigned long parent_rate;
	u8 n;
	u8 k;
	u8 m;
	u8 p;
};

struct factors_data {
	int enable;
	int mux;
	int muxmask;
	const struct clk_factors_config *table;
	void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
	void (*getter)(struct factors_request *req);
	const char *name;
};

@@ -32,7 +41,7 @@ struct clk_factors {
	struct clk_hw hw;
	void __iomem *reg;
	const struct clk_factors_config *config;
	void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
	void (*get_factors)(struct factors_request *req);
	spinlock_t *lock;
	/* for cleanup */
	struct clk_mux *mux;
+7 −13
Original line number Diff line number Diff line
@@ -28,17 +28,16 @@
 * rate = (parent_rate >> p) / (m + 1);
 */

static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate,
				       u8 *n, u8 *k, u8 *m, u8 *p)
static void sun4i_a10_get_mod0_factors(struct factors_request *req)
{
	u8 div, calcm, calcp;

	/* These clocks can only divide, so we will never be able to achieve
	 * frequencies higher than the parent frequency */
	if (*freq > parent_rate)
		*freq = parent_rate;
	if (req->rate > req->parent_rate)
		req->rate = req->parent_rate;

	div = DIV_ROUND_UP(parent_rate, *freq);
	div = DIV_ROUND_UP(req->parent_rate, req->rate);

	if (div < 16)
		calcp = 0;
@@ -51,14 +50,9 @@ static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate,

	calcm = DIV_ROUND_UP(div, 1 << calcp);

	*freq = (parent_rate >> calcp) / calcm;

	/* we were called to round the frequency, we can now return */
	if (n == NULL)
		return;

	*m = calcm - 1;
	*p = calcp;
	req->rate = (req->parent_rate >> calcp) / calcm;
	req->m = calcm - 1;
	req->p = calcp;
}

/* user manual says "n" but it's really "p" */
+6 −12
Original line number Diff line number Diff line
@@ -26,8 +26,7 @@
 * rate = parent_rate / (m + 1);
 */

static void sun8i_a23_get_mbus_factors(u32 *freq, u32 parent_rate,
				       u8 *n, u8 *k, u8 *m, u8 *p)
static void sun8i_a23_get_mbus_factors(struct factors_request *req)
{
	u8 div;

@@ -35,21 +34,16 @@ static void sun8i_a23_get_mbus_factors(u32 *freq, u32 parent_rate,
	 * These clocks can only divide, so we will never be able to
	 * achieve frequencies higher than the parent frequency
	 */
	if (*freq > parent_rate)
		*freq = parent_rate;
	if (req->rate > req->parent_rate)
		req->rate = req->parent_rate;

	div = DIV_ROUND_UP(parent_rate, *freq);
	div = DIV_ROUND_UP(req->parent_rate, req->rate);

	if (div > 8)
		div = 8;

	*freq = parent_rate / div;

	/* we were called to round the frequency, we can now return */
	if (m == NULL)
		return;

	*m = div - 1;
	req->rate = req->parent_rate / div;
	req->m = div - 1;
}

static struct clk_factors_config sun8i_a23_mbus_config = {
+25 −52
Original line number Diff line number Diff line
@@ -32,15 +32,14 @@
 * p and m are named div1 and div2 in Allwinner's SDK
 */

static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate,
				       u8 *n_ret, u8 *k, u8 *m_ret, u8 *p_ret)
static void sun9i_a80_get_pll4_factors(struct factors_request *req)
{
	int n;
	int m = 1;
	int p = 1;

	/* Normalize value to a 6 MHz multiple (24 MHz / 4) */
	n = DIV_ROUND_UP(*freq, 6000000);
	n = DIV_ROUND_UP(req->rate, 6000000);

	/* If n is too large switch to steps of 12 MHz */
	if (n > 255) {
@@ -60,15 +59,10 @@ static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate,
	else if (n < 12)
		n = 12;

	*freq = ((24000000 * n) >> p) / (m + 1);

	/* we were called to round the frequency, we can now return */
	if (n_ret == NULL)
		return;

	*n_ret = n;
	*m_ret = m;
	*p_ret = p;
	req->rate = ((24000000 * n) >> p) / (m + 1);
	req->n = n;
	req->m = m;
	req->p = p;
}

static const struct clk_factors_config sun9i_a80_pll4_config = {
@@ -111,27 +105,21 @@ CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_se
 * rate = parent_rate / (m + 1);
 */

static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate,
				     u8 *n, u8 *k, u8 *m, u8 *p)
static void sun9i_a80_get_gt_factors(struct factors_request *req)
{
	u32 div;

	if (parent_rate < *freq)
		*freq = parent_rate;
	if (req->parent_rate < req->rate)
		req->rate = req->parent_rate;

	div = DIV_ROUND_UP(parent_rate, *freq);
	div = DIV_ROUND_UP(req->parent_rate, req->rate);

	/* maximum divider is 4 */
	if (div > 4)
		div = 4;

	*freq = parent_rate / div;

	/* we were called to round the frequency, we can now return */
	if (!m)
		return;

	*m = div;
	req->rate = req->parent_rate / div;
	req->m = div;
}

static const struct clk_factors_config sun9i_a80_gt_config = {
@@ -176,27 +164,21 @@ CLK_OF_DECLARE(sun9i_a80_gt, "allwinner,sun9i-a80-gt-clk", sun9i_a80_gt_setup);
 * rate = parent_rate >> p;
 */

static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate,
				      u8 *n, u8 *k, u8 *m, u8 *p)
static void sun9i_a80_get_ahb_factors(struct factors_request *req)
{
	u32 _p;

	if (parent_rate < *freq)
		*freq = parent_rate;
	if (req->parent_rate < req->rate)
		req->rate = req->parent_rate;

	_p = order_base_2(DIV_ROUND_UP(parent_rate, *freq));
	_p = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate));

	/* maximum p is 3 */
	if (_p > 3)
		_p = 3;

	*freq = parent_rate >> _p;

	/* we were called to round the frequency, we can now return */
	if (!p)
		return;

	*p = _p;
	req->rate = req->parent_rate >> _p;
	req->p = _p;
}

static const struct clk_factors_config sun9i_a80_ahb_config = {
@@ -262,31 +244,22 @@ CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_se
 * rate = (parent_rate >> p) / (m + 1);
 */

static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate,
				       u8 *n, u8 *k, u8 *m, u8 *p)
static void sun9i_a80_get_apb1_factors(struct factors_request *req)
{
	u32 div;
	u8 calcm, calcp;

	if (parent_rate < *freq)
		*freq = parent_rate;
	if (req->parent_rate < req->rate)
		req->rate = req->parent_rate;

	div = DIV_ROUND_UP(parent_rate, *freq);
	div = DIV_ROUND_UP(req->parent_rate, req->rate);

	/* Highest possible divider is 256 (p = 3, m = 31) */
	if (div > 256)
		div = 256;

	calcp = order_base_2(div);
	calcm = (parent_rate >> calcp) - 1;
	*freq = (parent_rate >> calcp) / (calcm + 1);

	/* we were called to round the frequency, we can now return */
	if (n == NULL)
		return;

	*m = calcm;
	*p = calcp;
	req->p = order_base_2(div);
	req->m = (req->parent_rate >> req->p) - 1;
	req->rate = (req->parent_rate >> req->p) / (req->m + 1);
}

static const struct clk_factors_config sun9i_a80_apb1_config = {
Loading