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

Commit e70b432e authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: qcom: clk-rcg2: correct set rate handling for FORCE_ENABLE_RCG"

parents 1b8e6871 eb448596
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -158,6 +158,7 @@ struct clk_rcg2 {
	struct clk_regmap	clkr;
	u8			flags;
#define FORCE_ENABLE_RCG	BIT(0)
#define HW_CLK_CTRL_MODE	BIT(1)
};

#define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)
+48 −44
Original line number Diff line number Diff line
@@ -64,16 +64,6 @@ static struct freq_tbl cxo_f = {
	.n = 0,
};

static void update_src_map(struct clk_hw *hw)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
	int i, num_parents = clk_hw_get_num_parents(hw);

	for (i = 0; i < num_parents; i++)
		if (!rcg->parent_map[i].cfg)
			cxo_f.src = rcg->parent_map[i].src;
}

static int clk_rcg2_is_enabled(struct clk_hw *hw)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
@@ -187,6 +177,16 @@ static int clk_rcg2_clear_force_enable(struct clk_hw *hw)
					CMD_ROOT_EN, 0);
}

static bool clk_rcg2_is_force_enabled(struct clk_hw *hw)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
	u32 val = 0;

	regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG, &val);

	return val & CMD_ROOT_EN;
}

static int prepare_enable_rcg_srcs(struct clk *curr, struct clk *new)
{
	int rc = 0;
@@ -259,6 +259,7 @@ clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
	const struct freq_tbl *f_curr;
	u32 cfg, src, hid_div, m = 0, n = 0, mode = 0, mask;
	unsigned long rrate = 0;

	regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
	src = cfg;
@@ -296,7 +297,16 @@ clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
		hid_div &= mask;
	}

	return calc_rate(parent_rate, m, n, mode, hid_div);
	rrate = calc_rate(parent_rate, m, n, mode, hid_div);

	/*
	 * Check to cover the case when the RCG has been initialized to a
	 * non-CXO frequency before the clock driver has taken control of it.
	 */
	if (rcg->enable_safe_config && !rcg->current_freq)
		rcg->current_freq = rrate;

	return rrate;
}

static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
@@ -418,6 +428,8 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
	cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
	if (rcg->mnd_width && f->n && (f->m != f->n))
		cfg |= CFG_MODE_DUAL_EDGE;
	if (rcg->flags & HW_CLK_CTRL_MODE)
		cfg |= CFG_HW_CLK_CTRL_MASK;

	return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
					mask, cfg);
@@ -502,6 +514,7 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
	const struct freq_tbl *f, *f_curr;
	int ret, curr_src_index, new_src_index;
	struct clk_hw *curr_src = NULL, *new_src = NULL;
	bool force_enabled = false;

	switch (policy) {
	case FLOOR:
@@ -517,12 +530,6 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
	if (!f)
		return -EINVAL;

	/*
	 * Set the correct source value for CXO as per
	 * as per defined parent map.
	 */
	update_src_map(hw);

	/*
	 * Return if the RCG is currently disabled. This configuration update
	 * will happen as part of the RCG enable sequence.
@@ -559,6 +566,10 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,

		/* The RCG could currently be disabled. Enable its parents. */
		ret = prepare_enable_rcg_srcs(curr_src->clk, new_src->clk);
		if (ret)
			return ret;
		force_enabled = clk_rcg2_is_force_enabled(hw);
		if (!force_enabled)
			clk_rcg2_set_force_enable(hw);
	}

@@ -567,6 +578,7 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
		return ret;

	if (rcg->flags & FORCE_ENABLE_RCG) {
		if (!force_enabled)
			clk_rcg2_clear_force_enable(hw);
		disable_unprepare_rcg_srcs(curr_src->clk, new_src->clk);
	}
@@ -605,17 +617,10 @@ static int clk_rcg2_enable(struct clk_hw *hw)
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
	unsigned long rate;
	const struct freq_tbl *f;
	int ret;

	/*
	 * Set the correct source value for CXO as per
	 * as per defined parent map.
	 */
	update_src_map(hw);

	if (rcg->flags & FORCE_ENABLE_RCG) {
	if (rcg->flags & FORCE_ENABLE_RCG)
		clk_rcg2_set_force_enable(hw);
		return 0;
	}

	if (!rcg->enable_safe_config)
		return 0;
@@ -642,30 +647,27 @@ static int clk_rcg2_enable(struct clk_hw *hw)
	if (rate == cxo_f.freq)
		f = &cxo_f;

	if (!(rcg->flags & FORCE_ENABLE_RCG))
		clk_rcg2_set_force_enable(hw);
	clk_rcg2_configure(rcg, f);

	ret = clk_rcg2_configure(rcg, f);

	if (!(rcg->flags & FORCE_ENABLE_RCG))
		clk_rcg2_clear_force_enable(hw);

	return 0;
	return ret;
}

static void clk_rcg2_disable(struct clk_hw *hw)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
	int ret;

	/*
	 * Set the correct source value for CXO as per
	 * as per defined parent map.
	 */
	update_src_map(hw);

	if (rcg->flags & FORCE_ENABLE_RCG) {
	if (!rcg->enable_safe_config) {
		if (rcg->flags & FORCE_ENABLE_RCG)
			clk_rcg2_clear_force_enable(hw);
		return;
	}

	if (!rcg->enable_safe_config)
		return;
	/*
	 * Park the RCG at a safe configuration - sourced off the CXO. This is
	 * needed for 2 reasons: In the case of RCGs sourcing PSCBCs, due to a
@@ -683,7 +685,9 @@ static void clk_rcg2_disable(struct clk_hw *hw)
	 * online. Therefore, the RCG can safely be switched.
	 */
	clk_rcg2_set_force_enable(hw);
	clk_rcg2_configure(rcg, &cxo_f);
	ret = clk_rcg2_configure(rcg, &cxo_f);
	if (ret)
		pr_err("%s: CXO configuration failed\n", clk_hw_get_name(hw));
	clk_rcg2_clear_force_enable(hw);
}

+1 −1
Original line number Diff line number Diff line
@@ -37,8 +37,8 @@ static DEFINE_VDD_REGULATORS(vdd_cx_ao, VDD_NUM, 1, vdd_corner);
static DEFINE_VDD_REGULATORS(vdd_mm, VDD_NUM, 1, vdd_corner);

enum {
	P_AUD_REF_CLK,
	P_BI_TCXO,
	P_AUD_REF_CLK,
	P_CORE_BI_PLL_TEST_SE,
	P_GPLL0_OUT_EVEN,
	P_GPLL0_OUT_MAIN,