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

Commit 9d175983 authored by Kuogee Hsieh's avatar Kuogee Hsieh
Browse files

msm: mdss: add pll master/slave auto detection for 8996



Set up pll master/slave status base on both pll
GLBL_TEST_CTRL and CLKBUFLR_EN pll registers value.

Change-Id: Ic75e77d5fccb88613ebe435f97a39f5d745fb264
Signed-off-by: default avatarKuogee Hsieh <khsieh@codeaurora.org>
parent 861a4ae9
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -27,9 +27,6 @@ Optional properties:
- label:	       	A string used to describe the driver used.
- vcca-supply:		Phandle for vcca regulator device node.

- qcom,dsi-pll-slave:	indicates it is pll slave at split display case. Otherwise
			it is pll master.

- qcom,platform-supply-entries:	A node that lists the elements of the supply. There
				can be more than one instance of this binding,
				in which case the entry would be appended with
+74 −2
Original line number Diff line number Diff line
@@ -609,6 +609,76 @@ static void pll_db_commit_8996(void __iomem *pll_base,
	wmb();	/* make sure register committed */
}

/*
 * pll_source_finding:
 * Both GLBL_TEST_CTRL and CLKBUFLR_EN are configured
 * at mdss_dsi_8996_phy_config()
 */
static int pll_source_finding(struct mdss_pll_resources *pll)
{
	u32 clk_buf_en;
	u32 glbl_test_ctrl;

	glbl_test_ctrl = MDSS_PLL_REG_R(pll->pll_base,
				DSIPHY_CMN_GLBL_TEST_CTRL);
	clk_buf_en = MDSS_PLL_REG_R(pll->pll_base,
				DSIPHY_PLL_CLKBUFLR_EN);

	glbl_test_ctrl &= BIT(2);
	glbl_test_ctrl >>= 2;

	pr_debug("%s: pll=%d clk_buf_en=%x glbl_test_ctrl=%x\n",
		__func__, pll->index, clk_buf_en, glbl_test_ctrl);

	clk_buf_en &= (PLL_OUTPUT_RIGHT | PLL_OUTPUT_LEFT);

	if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) &&
			(clk_buf_en == PLL_OUTPUT_BOTH))
		return PLL_MASTER;

	if ((glbl_test_ctrl == PLL_SOURCE_FROM_RIGHT) &&
			(clk_buf_en == PLL_OUTPUT_NONE))
		return PLL_SLAVE;

	if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) &&
			(clk_buf_en == PLL_OUTPUT_RIGHT))
		return PLL_STANDALONE;

	pr_debug("%s: Error pll setup, clk_buf_en=%x glbl_test_ctrl=%x\n",
			__func__, clk_buf_en, glbl_test_ctrl);

	return PLL_UNKNOWN;
}

static void pll_source_setup(struct mdss_pll_resources *pll)
{
	int status;
	struct dsi_pll_db *pdb = (struct dsi_pll_db *)pll->priv;
	struct mdss_pll_resources *other;

	if (pdb->source_setup_done)
		return;

	pdb->source_setup_done++;

	status = pll_source_finding(pll);

	if (status == PLL_STANDALONE || status == PLL_UNKNOWN)
		return;

	other = pdb->next->pll;
	if (!other)
		return;

	pr_debug("%s: status=%d pll=%d other=%d\n", __func__,
			status, pll->index, other->index);

	if (status == PLL_MASTER)
		pll->slave = other;
	else
		other->slave = pll;
}

int pll_vco_set_rate_8996(struct clk *c, unsigned long rate)
{
	int rc;
@@ -629,8 +699,10 @@ int pll_vco_set_rate_8996(struct clk *c, unsigned long rate)
		return rc;
	}

	pr_debug("%s: ndx=%d base=%p rate=%lu\n", __func__,
				pll->index, pll->pll_base, rate);
	pll_source_setup(pll);

	pr_debug("%s: ndx=%d base=%p rate=%lu slave=%p\n", __func__,
				pll->index, pll->pll_base, rate, pll->slave);

	pll->vco_current_rate = rate;
	pll->vco_ref_clk_rate = vco->ref_clk_rate;
+9 −18
Original line number Diff line number Diff line
@@ -287,8 +287,8 @@ static struct clk_lookup mdss_dsi_pllcc_8996_1[] = {
int dsi_pll_clock_register_8996(struct platform_device *pdev,
				struct mdss_pll_resources *pll_res)
{
	int rc;
	static struct mdss_pll_resources *master_pll;
	int rc, ndx;
	struct dsi_pll_db *pdb;

	if (!pdev || !pdev->dev.of_node) {
		pr_err("Invalid input parameters\n");
@@ -300,27 +300,18 @@ int dsi_pll_clock_register_8996(struct platform_device *pdev,
		return -EPROBE_DEFER;
	}

	pr_err("ndx=%d is_slave=%d\n", pll_res->index, pll_res->is_slave);

	if (pll_res->index >= DSI_PLL_NUM) {
		pr_err("pll ndx=%d is NOT supported\n", pll_res->index);
		return -EINVAL;
	}

	if (!pll_res->is_slave) {
		/* master at split display or stand alone */
		pll_res->priv = &pll_db[pll_res->index];
		master_pll = pll_res;	/* keep master pll */
	} else {
		/* slave pll */
		if (!master_pll) {
			pr_err("No match PLL master found for ndx=%d\n",
							pll_res->index);
			return -EINVAL;
		}
		master_pll->slave = pll_res;
		return 0;	/* done for slave */
	}
	ndx = pll_res->index;
	pdb = &pll_db[ndx];
	pll_res->priv = pdb;
	pdb->pll = pll_res;
	ndx++;
	ndx %= DSI_PLL_NUM;
	pdb->next = &pll_db[ndx];

	/* Set clock source operations */

+22 −0
Original line number Diff line number Diff line
@@ -146,8 +146,30 @@ enum {
};

struct dsi_pll_db {
	struct dsi_pll_db *next;
	struct mdss_pll_resources *pll;
	struct dsi_pll_input in;
	struct dsi_pll_output out;
	int source_setup_done;
};

enum {
	PLL_OUTPUT_NONE,
	PLL_OUTPUT_RIGHT,
	PLL_OUTPUT_LEFT,
	PLL_OUTPUT_BOTH
};

enum {
	PLL_SOURCE_FROM_LEFT,
	PLL_SOURCE_FROM_RIGHT
};

enum {
	PLL_UNKNOWN,
	PLL_STANDALONE,
	PLL_SLAVE,
	PLL_MASTER
};

int pll_vco_set_rate_8996(struct clk *c, unsigned long rate);
+0 −3
Original line number Diff line number Diff line
@@ -222,9 +222,6 @@ static int mdss_pll_probe(struct platform_device *pdev)
		pll_res->index = 0;
	}

	pll_res->is_slave = of_property_read_bool(pdev->dev.of_node,
						"qcom,dsi-pll-slave");

	pll_base_reg = platform_get_resource_byname(pdev,
						IORESOURCE_MEM, "pll_base");
	if (!pll_base_reg) {
Loading