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

Commit 6d8d5717 authored by Huaibin Yang's avatar Huaibin Yang Committed by Matt Wagantall
Browse files

clk: mdss: implement new pll re-locking sequence



The new sequence is intended to improve pll locking time. This patch
is to implement locking pll using stored codes and bypassing
calibration.

Change-Id: I1a26843b5d784984dff4fee0e17841cfc1be37cc
Signed-off-by: default avatarHuaibin Yang <huaibiny@codeaurora.org>
parent a6ce5303
Loading
Loading
Loading
Loading
+59 −10
Original line number Diff line number Diff line
@@ -167,6 +167,10 @@ static void pll_20nm_cache_trim_codes(struct mdss_pll_resources *dsi_pll_res)
		MDSS_PLL_REG_R(dsi_pll_res->pll_base,
			MMSS_DSI_PHY_PLL_CORE_VCO_TUNE);

	pr_debug("core_kvco_code=0x%x core_vco_turn=0x%x\n",
		dsi_pll_res->cache_pll_trim_codes[0],
		dsi_pll_res->cache_pll_trim_codes[1]);

	mdss_pll_resource_enable(dsi_pll_res, false);

	dsi_pll_res->reg_upd = true;
@@ -852,8 +856,15 @@ enum handoff pll_20nm_vco_handoff(struct clk *c)
		dsi_pll_res->pll_on = true;
		c->rate = pll_20nm_vco_get_rate(c);
		ret = HANDOFF_ENABLED_CLK;
		dsi_pll_res->vco_locking_rate = c->rate;
		dsi_pll_res->is_init_locked = true;
		pll_20nm_cache_trim_codes(dsi_pll_res);
		pr_debug("handoff vco_locking_rate=0x%llu\n",
			dsi_pll_res->vco_locking_rate);
	} else {
		mdss_pll_resource_enable(dsi_pll_res, false);
		dsi_pll_res->vco_locking_rate = 0;
		dsi_pll_res->is_init_locked = false;
	}

	return ret;
@@ -913,28 +924,41 @@ static void pll_20nm_config_vco_start(void __iomem *pll_base)
	MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x03);
}

static int pll_20nm_vco_init_lock(struct mdss_pll_resources *dsi_pll_res)
static void pll_20nm_config_bypass_cal(void __iomem *pll_base)
{
	MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL, 0xac);
	MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN, 0x28);
}

static int pll_20nm_vco_relock(struct mdss_pll_resources *dsi_pll_res)
{
	int rc = 0;
	struct mdss_pll_vco_calc vco_calc;

	pll_20nm_config_common_block(dsi_pll_res->pll_base);
	pll_20nm_config_loop_bw(dsi_pll_res->pll_base);
	pll_20nm_override_trim_codes(dsi_pll_res);
	pll_20nm_config_bypass_cal(dsi_pll_res->pll_base);
	pll_20nm_config_vco_start(dsi_pll_res->pll_base);

	pll_20nm_vco_rate_calc(&vco_calc, dsi_pll_res->vco_current_rate,
		dsi_pll_res->vco_ref_clk_rate);
	pll_20nm_config_vco_rate(dsi_pll_res->pll_base, &vco_calc);
	if (!pll_20nm_is_pll_locked(dsi_pll_res)) {
		pr_err("DSI PLL re-lock failed\n");
		rc = -EINVAL;
	}

	return rc;
}

static int pll_20nm_vco_init_lock(struct mdss_pll_resources *dsi_pll_res)
{
	int rc = 0;

	pll_20nm_config_resetsm(dsi_pll_res->pll_base);
	pll_20nm_config_vco_start(dsi_pll_res->pll_base);

	if (!pll_20nm_is_pll_locked(dsi_pll_res)) {
		pr_err("DSI PLL lock failed\n");
		pr_err("DSI PLL init lock failed\n");
		rc = -EINVAL;
		goto init_lock_err;
	}

	pr_debug("DSI PLL Lock success\n");
	pll_20nm_cache_trim_codes(dsi_pll_res);

init_lock_err:
@@ -944,13 +968,38 @@ init_lock_err:
int pll_20nm_vco_enable_seq(struct mdss_pll_resources *dsi_pll_res)
{
	int rc = 0;
	struct mdss_pll_vco_calc vco_calc;

	if (!dsi_pll_res) {
		pr_err("Invalid PLL resources\n");
		return -EINVAL;
	}

	pll_20nm_config_common_block(dsi_pll_res->pll_base);
	pll_20nm_config_loop_bw(dsi_pll_res->pll_base);

	pll_20nm_vco_rate_calc(&vco_calc, dsi_pll_res->vco_current_rate,
		dsi_pll_res->vco_ref_clk_rate);
	pll_20nm_config_vco_rate(dsi_pll_res->pll_base, &vco_calc);

	pr_debug("init lock=%d prev vco_rate=%llu, new vco_rate=%llu\n",
		dsi_pll_res->is_init_locked, dsi_pll_res->vco_locking_rate,
		dsi_pll_res->vco_current_rate);
	/*
	 * Run auto-lock sequence if it is either bootup initial
	 * locking or when the vco rate is changed. Otherwise, just
	 * use stored codes and bypass caliberation.
	 */
	if (!dsi_pll_res->is_init_locked || (dsi_pll_res->vco_locking_rate !=
			dsi_pll_res->vco_current_rate)) {
		rc = pll_20nm_vco_init_lock(dsi_pll_res);
		dsi_pll_res->is_init_locked = (rc) ? false : true;
	} else {
		rc = pll_20nm_vco_relock(dsi_pll_res);
	}

	dsi_pll_res->vco_locking_rate = (rc) ? 0 :
		dsi_pll_res->vco_current_rate;

	return rc;
}
+2 −0
Original line number Diff line number Diff line
@@ -62,7 +62,9 @@ struct mdss_pll_resources {
	void __iomem	*gdsc_base;
	void __iomem	*dyn_pll_base;

	bool	is_init_locked;
	s64	vco_current_rate;
	s64	vco_locking_rate;
	s64	vco_ref_clk_rate;

	/*