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

Commit a3753f09 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: clock-generic: Reorganize divider clock parameters"

parents adb176a8 33e003cd
Loading
Loading
Loading
Loading
+29 −29
Original line number Diff line number Diff line
@@ -285,23 +285,19 @@ struct clk_mux_ops mux_reg_ops = {

/* ==================== Divider clock ==================== */

static long __div_round_rate(struct clk *c, unsigned long rate, int *best_div)
static long __div_round_rate(struct div_data *data, unsigned long rate,
	struct clk *parent, unsigned int *best_div)
{
	struct div_clk *d = to_div_clk(c);
	unsigned int div, min_div, max_div, rrate_div = 1;
	unsigned long p_rrate, rrate = 0;

	rate = max(rate, 1UL);

	if (!d->ops || !d->ops->set_div)
		min_div = max_div = d->div;
	else {
		min_div = max(d->min_div, 1U);
		max_div = min(d->max_div, (unsigned int) (ULONG_MAX / rate));
	}
	min_div = max(data->min_div, 1U);
	max_div = min(data->max_div, (unsigned int) (ULONG_MAX / rate));

	for (div = min_div; div <= max_div; div++) {
		p_rrate = clk_round_rate(c->parent, rate * div);
		p_rrate = clk_round_rate(parent, rate * div);
		if (IS_ERR_VALUE(p_rrate))
			break;

@@ -322,7 +318,7 @@ static long __div_round_rate(struct clk *c, unsigned long rate, int *best_div)
		if (p_rrate < rate)
			break;

		if (rrate <= rate + d->rate_margin)
		if (rrate <= rate + data->rate_margin)
			break;
	}

@@ -336,7 +332,9 @@ static long __div_round_rate(struct clk *c, unsigned long rate, int *best_div)

static long div_round_rate(struct clk *c, unsigned long rate)
{
	return __div_round_rate(c, rate, NULL);
	struct div_clk *d = to_div_clk(c);

	return __div_round_rate(&d->data, rate, c->parent, NULL);
}

static int div_set_rate(struct clk *c, unsigned long rate)
@@ -344,8 +342,9 @@ static int div_set_rate(struct clk *c, unsigned long rate)
	struct div_clk *d = to_div_clk(c);
	int div, rc = 0;
	long rrate, old_prate;
	struct div_data *data = &d->data;

	rrate = __div_round_rate(c, rate, &div);
	rrate = __div_round_rate(data, rate, c->parent, &div);
	if (rrate != rate)
		return -EINVAL;

@@ -355,7 +354,7 @@ static int div_set_rate(struct clk *c, unsigned long rate)
	 * !d->ops and return an error. __div_round_rate() ensures div ==
	 * d->div if !d->ops.
	 */
	if (div > d->div)
	if (div > data->div)
		rc = d->ops->set_div(d, div);
	if (rc)
		return rc;
@@ -365,12 +364,12 @@ static int div_set_rate(struct clk *c, unsigned long rate)
	if (rc)
		goto set_rate_fail;

	if (div < d->div)
	if (div < data->div)
		rc = d->ops->set_div(d, div);
	if (rc)
		goto div_dec_fail;

	d->div = div;
	data->div = div;

	return 0;

@@ -378,8 +377,8 @@ div_dec_fail:
	WARN(clk_set_rate(c->parent, old_prate),
		"Set rate failed for %s. Also in bad state!\n", c->dbg_name);
set_rate_fail:
	if (div > d->div)
		WARN(d->ops->set_div(d, d->div),
	if (div > data->div)
		WARN(d->ops->set_div(d, data->div),
			"Set rate failed for %s. Also in bad state!\n",
			c->dbg_name);
	return rc;
@@ -403,11 +402,16 @@ static void div_disable(struct clk *c)
static enum handoff div_handoff(struct clk *c)
{
	struct div_clk *d = to_div_clk(c);
	unsigned int div = d->data.div;

	if (d->ops && d->ops->get_div)
		d->div = max(d->ops->get_div(d), 1);
	d->div = max(d->div, 1U);
	c->rate = clk_get_rate(c->parent) / d->div;
		div = max(d->ops->get_div(d), 1);
	div = max(div, 1U);
	c->rate = clk_get_rate(c->parent) / div;

	if (!d->ops || !d->ops->set_div)
		d->data.min_div = d->data.max_div = div;
	d->data.div = div;

	if (d->en_mask && d->ops && d->ops->is_enabled)
		return d->ops->is_enabled(d)
@@ -443,12 +447,8 @@ static long __slave_div_round_rate(struct clk *c, unsigned long rate,

	rate = max(rate, 1UL);

	if (!d->ops || !d->ops->set_div)
		min_div = max_div = d->div;
	else {
		min_div = d->min_div;
		max_div = d->max_div;
	}
	min_div = d->data.min_div;
	max_div = d->data.max_div;

	p_rate = clk_get_rate(c->parent);
	div = p_rate / rate;
@@ -475,20 +475,20 @@ static int slave_div_set_rate(struct clk *c, unsigned long rate)
	if (rrate != rate)
		return -EINVAL;

	if (div == d->div)
	if (div == d->data.div)
		return 0;

	/*
	 * For fixed divider clock we don't want to return an error if the
	 * requested rate matches the achievable rate. So, don't check for
	 * !d->ops and return an error. __slave_div_round_rate() ensures
	 * div == d->div if !d->ops.
	 * div == d->data.div if !d->ops.
	 */
	rc = d->ops->set_div(d, div);
	if (rc)
		return rc;

	d->div = div;
	d->data.div = div;

	return 0;
}
+5 −3
Original line number Diff line number Diff line
@@ -22,9 +22,11 @@ extern struct clk_div_ops clk_div_ops_kpss_div2;

#define DEFINE_KPSS_DIV2_CLK(clk_name, _parent, _offset, _lf_tree) \
static struct div_clk clk_name = {		\
	.data = {				\
		.div = 2,			\
		.min_div = 2,			\
		.max_div = 2,			\
	},					\
	.ops = &clk_div_ops_kpss_div2,		\
	.offset = _offset,			\
	.mask = 0x3,				\
+70 −32
Original line number Diff line number Diff line
@@ -686,7 +686,7 @@ int div_prepare(struct clk *c)
{
	struct div_clk *div = to_div_clk(c);
	/* Restore the divider's value */
	return div->ops->set_div(div, div->div);
	return div->ops->set_div(div, div->data.div);
}

int mux_prepare(struct clk *c)
@@ -1451,8 +1451,10 @@ struct dsi_pll_vco_clk dsi_vco_clk_8226 = {
};

struct div_clk analog_postdiv_clk_8226 = {
	.data = {
		.max_div = 255,
		.min_div = 1,
	},
	.ops = &analog_postdiv_ops,
	.c = {
		.parent = &dsi_vco_clk_8226.c,
@@ -1465,7 +1467,9 @@ struct div_clk analog_postdiv_clk_8226 = {

struct div_clk indirect_path_div2_clk_8226 = {
	.ops = &fixed_2div_ops,
	.data = {
		.div = 2,
	},
	.c = {
		.parent = &analog_postdiv_clk_8226.c,
		.dbg_name = "indirect_path_div2_clk",
@@ -1476,8 +1480,10 @@ struct div_clk indirect_path_div2_clk_8226 = {
};

struct div_clk pixel_clk_src_8226 = {
	.data = {
		.max_div = 255,
		.min_div = 1,
	},
	.ops = &digital_postdiv_ops,
	.c = {
		.parent = &dsi_vco_clk_8226.c,
@@ -1505,8 +1511,10 @@ struct mux_clk byte_mux_8226 = {

struct div_clk byte_clk_src_8226 = {
	.ops = &fixed_4div_ops,
	.data = {
		.min_div = 4,
		.max_div = 4,
	},
	.c = {
		.parent = &byte_mux_8226.c,
		.dbg_name = "byte_clk_src",
@@ -1544,8 +1552,10 @@ struct dsi_pll_vco_clk dsi_vco_clk_8084 = {
};

struct div_clk analog_postdiv_clk_8084 = {
	.data = {
		.max_div = 255,
		.min_div = 1,
	},
	.ops = &analog_postdiv_ops,
	.c = {
		.parent = &dsi_vco_clk_8084.c,
@@ -1558,7 +1568,9 @@ struct div_clk analog_postdiv_clk_8084 = {

struct div_clk indirect_path_div2_clk_8084 = {
	.ops = &fixed_2div_ops,
	.data = {
		.div = 2,
	},
	.c = {
		.parent = &analog_postdiv_clk_8084.c,
		.dbg_name = "indirect_path_div2_clk",
@@ -1569,8 +1581,10 @@ struct div_clk indirect_path_div2_clk_8084 = {
};

struct div_clk pixel_clk_src_8084 = {
	.data = {
		.max_div = 255,
		.min_div = 1,
	},
	.ops = &digital_postdiv_ops,
	.c = {
		.parent = &dsi_vco_clk_8084.c,
@@ -1598,8 +1612,10 @@ struct mux_clk byte_mux_8084 = {

struct div_clk byte_clk_src_8084 = {
	.ops = &fixed_4div_ops,
	.data = {
		.min_div = 4,
		.max_div = 4,
	},
	.c = {
		.parent = &byte_mux_8084.c,
		.dbg_name = "byte_clk_src",
@@ -1637,8 +1653,10 @@ struct dsi_pll_vco_clk dsi_vco_clk_8974 = {
};

struct div_clk analog_postdiv_clk_8974 = {
	.data = {
		.max_div = 255,
		.min_div = 1,
	},
	.ops = &analog_postdiv_ops,
	.c = {
		.parent = &dsi_vco_clk_8974.c,
@@ -1651,7 +1669,9 @@ struct div_clk analog_postdiv_clk_8974 = {

struct div_clk indirect_path_div2_clk_8974 = {
	.ops = &fixed_2div_ops,
	.data = {
		.div = 2,
	},
	.c = {
		.parent = &analog_postdiv_clk_8974.c,
		.dbg_name = "indirect_path_div2_clk",
@@ -1662,8 +1682,10 @@ struct div_clk indirect_path_div2_clk_8974 = {
};

struct div_clk pixel_clk_src_8974 = {
	.data = {
		.max_div = 255,
		.min_div = 1,
	},
	.ops = &digital_postdiv_ops,
	.c = {
		.parent = &dsi_vco_clk_8974.c,
@@ -1691,8 +1713,10 @@ struct mux_clk byte_mux_8974 = {

struct div_clk byte_clk_src_8974 = {
	.ops = &fixed_4div_ops,
	.data = {
		.min_div = 4,
		.max_div = 4,
	},
	.c = {
		.parent = &byte_mux_8974.c,
		.dbg_name = "byte_clk_src",
@@ -2067,10 +2091,10 @@ static unsigned long edp_mainlink_get_rate(struct clk *c)

	if (pclk->ops->get_rate) {
		rate = pclk->ops->get_rate(pclk);
		rate /= mclk->div;
		rate /= mclk->data.div;
	}

	pr_debug("%s: rate=%d div=%d\n", __func__, (int)rate, mclk->div);
	pr_debug("%s: rate=%d div=%d\n", __func__, (int)rate, mclk->data.div);

	return rate;
}
@@ -2080,7 +2104,9 @@ static struct clk_div_ops fixed_5div_ops; /* null ops */

struct div_clk edp_mainlink_clk_src = {
	.ops = &fixed_5div_ops,
	.data = {
		.div = 5,
	},
	.c = {
		.parent = &edp_vco_clk.c,
		.dbg_name = "edp_mainlink_clk_src",
@@ -2138,8 +2164,10 @@ static struct clk_div_ops edp_pixel_ops = {
};

struct div_clk edp_pixel_clk_src = {
	.data = {
		.max_div = 2,
		.min_div = 1,
	},
	.ops = &edp_pixel_ops,
	.c = {
		.parent = &edp_vco_clk.c,
@@ -2287,7 +2315,9 @@ static struct hdmi_pll_vco_clk hdmi_vco_clk = {
};

static struct div_clk hdmipll_div1_clk = {
	.data = {
		.div = 1,
	},
	.c = {
		.parent = &hdmi_vco_clk.c,
		.dbg_name = "hdmipll_div1_clk",
@@ -2298,7 +2328,9 @@ static struct div_clk hdmipll_div1_clk = {
};

static struct div_clk hdmipll_div2_clk = {
	.data = {
		.div = 2,
	},
	.c = {
		.parent = &hdmi_vco_clk.c,
		.dbg_name = "hdmipll_div2_clk",
@@ -2309,7 +2341,9 @@ static struct div_clk hdmipll_div2_clk = {
};

static struct div_clk hdmipll_div4_clk = {
	.data = {
		.div = 4,
	},
	.c = {
		.parent = &hdmi_vco_clk.c,
		.dbg_name = "hdmipll_div4_clk",
@@ -2320,7 +2354,9 @@ static struct div_clk hdmipll_div4_clk = {
};

static struct div_clk hdmipll_div6_clk = {
	.data = {
		.div = 6,
	},
	.c = {
		.parent = &hdmi_vco_clk.c,
		.dbg_name = "hdmipll_div6_clk",
@@ -2389,7 +2425,9 @@ static struct mux_clk hdmipll_mux_clk = {
};

struct div_clk hdmipll_clk_src = {
	.data = {
		.div = 5,
	},
	.c = {
		.parent = &hdmipll_mux_clk.c,
		.dbg_name = "hdmipll_clk_src",
+15 −6
Original line number Diff line number Diff line
@@ -80,11 +80,16 @@ struct clk_div_ops {
	void (*disable)(struct div_clk *clk);
};

struct div_clk {
struct div_data {
	unsigned int div;
	unsigned int min_div;
	unsigned int max_div;
	unsigned long rate_margin;
};

struct div_clk {
	struct div_data data;

	/* Optional */
	struct clk_div_ops *ops;

@@ -114,7 +119,9 @@ extern struct clk_ops clk_ops_ext;

#define DEFINE_FIXED_DIV_CLK(clk_name, _div, _parent) \
static struct div_clk clk_name = {	\
	.data = {				\
		.div = _div,			\
	},					\
	.c = {					\
		.parent = _parent,		\
		.dbg_name = #clk_name,		\
@@ -125,7 +132,9 @@ static struct div_clk clk_name = { \

#define DEFINE_FIXED_SLAVE_DIV_CLK(clk_name, _div, _parent) \
static struct div_clk clk_name = {	\
	.data = {				\
		.div = _div,			\
	},					\
	.c = {					\
		.parent = _parent,		\
		.dbg_name = #clk_name,		\