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

Commit a3188dea authored by Venkata Prahlad Valluru's avatar Venkata Prahlad Valluru Committed by Nirmal Abraham
Browse files

clk: qcom: mdss: update dsi 12nm clock driver



Add 12nm clock to mdss clocks. Fix regmap parameters.
Move clock commit to set_rate. Set divider values to
registers instead of setting them during prepare call.

Change-Id: I4eec349875e392dd707d0ac93f906428ca4b97e3
Signed-off-by: default avatarVenkata Prahlad Valluru <vvalluru@codeaurora.org>
Signed-off-by: default avatarNirmal Abraham <nabrah@codeaurora.org>
parent 0c0b80d0
Loading
Loading
Loading
Loading
+88 −30
Original line number Diff line number Diff line
@@ -15,17 +15,31 @@
#define DSI_PLL_POLL_MAX_READS                  15
#define DSI_PLL_POLL_TIMEOUT_US                 1000

static void __mdss_dsi_get_pll_vco_cntrl(u64 target_freq, u32 post_div_mux,
	u32 *vco_cntrl, u32 *cpbias_cntrl);

int pixel_div_set_div(void *context, unsigned int reg,
			unsigned int div)
{
	struct mdss_pll_resources *pll = context;
	void __iomem *pll_base = pll->pll_base;
	int rc;
	char data = 0;
	struct dsi_pll_db *pdb;

	pdb = (struct dsi_pll_db *)pll->priv;
	rc = mdss_pll_resource_enable(pll, true);
	if (rc) {
		pr_err("Failed to enable mdss dsi pll resources\n");
		return rc;
	}

	/* Programming during vco_prepare. Keep this value */
	pdb->param.pixel_divhf = (div - 1);
	data = ((div - 1) & 0x7f);
	MDSS_PLL_REG_W(pll_base, DSIPHY_SSC9, data);
	pdb->param.pixel_divhf = data;

	mdss_pll_resource_enable(pll, false);
	pr_debug("ndx=%d div=%d divhf=%d\n",
			pll->index, div, pdb->param.pixel_divhf);

@@ -37,6 +51,7 @@ int pixel_div_get_div(void *context, unsigned int reg,
{
	int rc;
	struct mdss_pll_resources *pll = context;
	u32 val = 0;

	if (is_gdsc_disabled(pll))
		return 0;
@@ -47,8 +62,9 @@ int pixel_div_get_div(void *context, unsigned int reg,
		return rc;
	}

	*div = (MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SSC9) & 0x7F);
	pr_debug("pixel_div = %d\n", (*div+1));
	val = (MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SSC9) & 0x7F);
	*div = val + 1;
	pr_debug("pixel_div = %d\n", (*div));

	mdss_pll_resource_enable(pll, false);

@@ -59,13 +75,30 @@ int set_post_div_mux_sel(void *context, unsigned int reg,
			unsigned int sel)
{
	struct mdss_pll_resources *pll = context;
	void __iomem *pll_base = pll->pll_base;
	struct dsi_pll_db *pdb;
	u64 target_freq = 0;
	u32 vco_cntrl = 0, cpbias_cntrl = 0;
	char data = 0;

	pdb = (struct dsi_pll_db *)pll->priv;

	/* Programming during vco_prepare. Keep this value */
	pdb->param.post_div_mux = sel;

	target_freq = div_u64(pll->vco_current_rate,
		BIT(pdb->param.post_div_mux));
	__mdss_dsi_get_pll_vco_cntrl(target_freq, pdb->param.post_div_mux,
		&vco_cntrl, &cpbias_cntrl);

	data = ((vco_cntrl & 0x3f) | BIT(6));
	MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_CTRL, data);
	pr_debug("%s: vco_cntrl 0x%x\n", __func__, vco_cntrl);

	data = ((cpbias_cntrl & 0x1) << 6) | BIT(4);
	MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL, data);
	pr_debug("%s: cpbias_cntrl 0x%x\n", __func__, cpbias_cntrl);

	pr_debug("ndx=%d post_div_mux_sel=%d p_div=%d\n",
			pll->index, sel, (u32) BIT(sel));

@@ -90,6 +123,7 @@ int get_post_div_mux_sel(void *context, unsigned int reg,

	vco_cntrl = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_PLL_VCO_CTRL);
	vco_cntrl &= 0x30;
	pr_debug("%s: vco_cntrl 0x%x\n", __func__, vco_cntrl);

	cpbias_cntrl = MDSS_PLL_REG_R(pll->pll_base,
		DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL);
@@ -112,6 +146,7 @@ int get_post_div_mux_sel(void *context, unsigned int reg,
	}

	mdss_pll_resource_enable(pll, false);
	pr_debug("%s: sel = %d\n", __func__, *sel);

	return 0;
}
@@ -120,16 +155,24 @@ int set_gp_mux_sel(void *context, unsigned int reg,
			unsigned int sel)
{
	struct mdss_pll_resources *pll = context;
	struct dsi_pll_db *pdb;
	void __iomem *pll_base = pll->pll_base;
	char data = 0;
	int rc;

	pdb = (struct dsi_pll_db *)pll->priv;
	rc = mdss_pll_resource_enable(pll, true);
	if (rc) {
		pr_err("Failed to enable mdss dsi pll resources\n");
		return rc;
	}

	/* Programming during vco_prepare. Keep this value */
	pdb->param.gp_div_mux = sel;
	data = ((sel & 0x7) << 5) | 0x5;
	MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CTRL, data);

	pr_debug("ndx=%d gp_div_mux_sel=%d gp_cntrl=%d\n",
			pll->index, sel, (u32) BIT(sel));

	mdss_pll_resource_enable(pll, false);
	return 0;
}

@@ -175,7 +218,9 @@ static bool pll_is_pll_locked_12nm(struct mdss_pll_resources *pll,
			pr_err("DSI PLL ndx=%d status=%x failed to Lock\n",
				pll->index, status);
		pll_locked = false;
		pr_debug("%s: not locked\n", __func__);
	} else {
		pr_debug("%s: locked\n", __func__);
		pll_locked = true;
	}

@@ -542,13 +587,13 @@ static void mdss_dsi_pll_12nm_calc_reg(struct mdss_pll_resources *pll,
{
	struct dsi_pll_param *param = &pdb->param;
	u64 target_freq = 0;
	u32 post_div_mux = 0;

	get_post_div_mux_sel(pll, 0, &post_div_mux);
	target_freq = div_u64(pll->vco_current_rate,
		BIT(pdb->param.post_div_mux));
		BIT(post_div_mux));

	param->hsfreqrange = __mdss_dsi_get_hsfreqrange(target_freq);
	__mdss_dsi_get_pll_vco_cntrl(target_freq, param->post_div_mux,
		&param->vco_cntrl, &param->cpbias_cntrl);
	param->osc_freq_target = __mdss_dsi_get_osc_freq_target(target_freq);
	param->m_div = (u32) __mdss_dsi_pll_get_m_div(pll->vco_current_rate);
	param->fsm_ovr_ctrl = __mdss_dsi_get_fsm_ovr_ctrl(target_freq);
@@ -707,9 +752,6 @@ static void pll_db_commit_12nm(struct mdss_pll_resources *pll,
	data = ((param->hsfreqrange & 0x7f) | BIT(7));
	MDSS_PLL_REG_W(pll_base, DSIPHY_HS_FREQ_RAN_SEL, data);

	data = ((param->vco_cntrl & 0x3f) | BIT(6));
	MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_CTRL, data);

	data = (param->osc_freq_target & 0x7f);
	MDSS_PLL_REG_W(pll_base, DSIPHY_SLEWRATE_DDL_CYC_FRQ_ADJ_0, data);

@@ -733,15 +775,6 @@ static void pll_db_commit_12nm(struct mdss_pll_resources *pll,
	data = ((param->gmp_cntrl & 0x3) << 4);
	MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_GMP_CTRL_DIG_TST, data);

	data = ((param->cpbias_cntrl & 0x1) << 6) | BIT(4);
	MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL, data);

	data = ((param->gp_div_mux & 0x7) << 5) | 0x5;
	MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CTRL, data);

	data = (param->pixel_divhf & 0x7f);
	MDSS_PLL_REG_W(pll_base, DSIPHY_SSC9, data);

	MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_ANA_PROG_CTRL, 0x03);
	MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_ANA_TST_LOCK_ST_OVR_CTRL, 0x50);
	MDSS_PLL_REG_W(pll_base,
@@ -779,6 +812,14 @@ int pll_vco_set_rate_12nm(struct clk_hw *hw, unsigned long rate,

	pll->vco_current_rate = rate;
	pll->vco_ref_clk_rate = vco->ref_clk_rate;

	mdss_dsi_pll_12nm_calc_reg(pll, pdb);
	if (pll->ssc_en)
		mdss_dsi_pll_12nm_calc_ssc(pll, pdb);

	/* commit DSI vco  */
	pll_db_commit_12nm(pll, pdb);

error:
	return rc;
}
@@ -791,9 +832,13 @@ static unsigned long pll_vco_get_rate_12nm(struct clk_hw *hw)
	u64 ref_clk = vco->ref_clk_rate;
	int rc;
	struct mdss_pll_resources *pll = vco->priv;
	u32 post_div_mux;
	u32 cpbias_cntrl = 0;

	if (is_gdsc_disabled(pll))
	if (is_gdsc_disabled(pll)) {
		pr_err("%s:gdsc disabled\n", __func__);
		return 0;
	}

	rc = mdss_pll_resource_enable(pll, true);
	if (rc) {
@@ -811,6 +856,16 @@ static unsigned long pll_vco_get_rate_12nm(struct clk_hw *hw)
	m_div_11_6 &= 0x3f;
	pr_debug("m_div_11_6 = 0x%x\n", m_div_11_6);

	post_div_mux = MDSS_PLL_REG_R(pll->pll_base,
			DSIPHY_PLL_VCO_CTRL);

	pr_debug("post_div_mux = 0x%x\n", post_div_mux);

	cpbias_cntrl = MDSS_PLL_REG_R(pll->pll_base,
		DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL);
	cpbias_cntrl = ((cpbias_cntrl >> 6) & 0x1);
	pr_debug("cpbias_cntrl = 0x%x\n", cpbias_cntrl);

	m_div = ((m_div_11_6 << 6) | (m_div_5_0));

	vco_rate = div_u64((ref_clk * m_div), 4);
@@ -845,12 +900,22 @@ unsigned long vco_12nm_recalc_rate(struct clk_hw *hw,
	struct mdss_pll_resources *pll = vco->priv;
	unsigned long rate = 0;
	int rc;
	struct dsi_pll_db *pdb;

	pdb = (struct dsi_pll_db *)pll->priv;

	if (!pll && is_gdsc_disabled(pll)) {
		pr_err("gdsc disabled\n");
		return 0;
	}

	if (pll->vco_current_rate != 0) {
		rate = pll_vco_get_rate_12nm(hw);
		pr_debug("%s:returning vco rate = %lld\n", __func__,
				pll->vco_current_rate);
		return rate;
	}

	rc = mdss_pll_resource_enable(pll, true);
	if (rc) {
		pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
@@ -861,6 +926,7 @@ unsigned long vco_12nm_recalc_rate(struct clk_hw *hw,
		pll->handoff_resources = true;
		pll->pll_on = true;
		rate = pll_vco_get_rate_12nm(hw);
		pr_debug("%s: pll locked. rate %lu\n", __func__, rate);
	} else {
		mdss_pll_resource_enable(pll, false);
	}
@@ -921,15 +987,7 @@ int pll_vco_prepare_12nm(struct clk_hw *hw)
			goto end;
	}

	mdss_dsi_pll_12nm_calc_reg(pll, pdb);
	if (pll->ssc_en)
		mdss_dsi_pll_12nm_calc_ssc(pll, pdb);

	/* commit DSI vco  */
	pll_db_commit_12nm(pll, pdb);

	rc = dsi_pll_enable(hw);

error:
	if (rc) {
		mdss_pll_resource_enable(pll, false);
+24 −20
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ static const struct clk_ops clk_ops_vco_12nm = {
	.round_rate = pll_vco_round_rate_12nm,
	.prepare = pll_vco_prepare_12nm,
	.unprepare = pll_vco_unprepare_12nm,
	.enable = pll_vco_enable_12nm,
};

static struct regmap_bus pclk_div_regmap_bus = {
@@ -206,8 +207,8 @@ static struct clk_fixed_factor dsi0pll_post_div32 = {

static struct clk_regmap_mux dsi0pll_post_div_mux = {
	.reg = DSIPHY_PLL_VCO_CTRL,
	.shift = 4,
	.width = 2,
	.shift = 0,
	.width = 3,
	.clkr = {
		.hw.init = &(struct clk_init_data){
			.name = "dsi0pll_post_div_mux",
@@ -298,8 +299,8 @@ static struct clk_fixed_factor dsi1pll_post_div32 = {

static struct clk_regmap_mux dsi1pll_post_div_mux = {
	.reg = DSIPHY_PLL_VCO_CTRL,
	.shift = 4,
	.width = 2,
	.shift = 0,
	.width = 3,
	.clkr = {
		.hw.init = &(struct clk_init_data){
			.name = "dsi1pll_post_div_mux",
@@ -390,7 +391,7 @@ static struct clk_fixed_factor dsi0pll_gp_div32 = {

static struct clk_regmap_mux dsi0pll_gp_div_mux = {
	.reg = DSIPHY_PLL_CTRL,
	.shift = 5,
	.shift = 0,
	.width = 3,
	.clkr = {
		.hw.init = &(struct clk_init_data){
@@ -482,7 +483,7 @@ static struct clk_fixed_factor dsi1pll_gp_div32 = {

static struct clk_regmap_mux dsi1pll_gp_div_mux = {
	.reg = DSIPHY_PLL_CTRL,
	.shift = 5,
	.shift = 0,
	.width = 3,
	.clkr = {
		.hw.init = &(struct clk_init_data){
@@ -506,11 +507,12 @@ static struct clk_regmap_div dsi0pll_pclk_src = {
	.width = 6,
	.clkr = {
		.hw.init = &(struct clk_init_data){
			.name = "dsi0pll_pclk_src",
			.name = "dsi0_phy_pll_out_dsiclk",
			.parent_names = (const char *[]){
					"dsi0pll_gp_div_mux"},
			.num_parents = 1,
			.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
			.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
					CLK_SET_RATE_NO_REPARENT),
			.ops = &clk_regmap_div_ops,
		},
	},
@@ -522,11 +524,12 @@ static struct clk_regmap_div dsi1pll_pclk_src = {
	.width = 6,
	.clkr = {
		.hw.init = &(struct clk_init_data){
			.name = "dsi1pll_pclk_src",
			.name = "dsi1_phy_pll_out_dsiclk",
			.parent_names = (const char *[]){
					"dsi1pll_gp_div_mux"},
			.num_parents = 1,
			.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
			.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
					CLK_SET_RATE_NO_REPARENT),
			.ops = &clk_regmap_div_ops,
		},
	},
@@ -536,10 +539,11 @@ static struct clk_fixed_factor dsi0pll_byte_clk_src = {
	.div = 4,
	.mult = 1,
	.hw.init = &(struct clk_init_data){
		.name = "dsi0pll_byte_clk_src",
		.name = "dsi0_phy_pll_out_byteclk",
		.parent_names = (const char *[]){"dsi0pll_post_div_mux"},
		.num_parents = 1,
		.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
		.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
				CLK_SET_RATE_NO_REPARENT),
		.ops = &clk_fixed_factor_ops,
	},
};
@@ -548,15 +552,15 @@ static struct clk_fixed_factor dsi1pll_byte_clk_src = {
	.div = 4,
	.mult = 1,
	.hw.init = &(struct clk_init_data){
		.name = "dsi1pll_byte_clk_src",
		.name = "dsi1_phy_pll_out_byteclk",
		.parent_names = (const char *[]){"dsi1pll_post_div_mux"},
		.num_parents = 1,
		.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
		.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
				CLK_SET_RATE_NO_REPARENT),
		.ops = &clk_fixed_factor_ops,
	},
};


static struct clk_hw *mdss_dsi_pllcc_12nm[] = {
	[VCO_CLK_0] = &dsi0pll_vco_clk.hw,
	[POST_DIV1_0_CLK] = &dsi0pll_post_div1.hw,
@@ -598,14 +602,14 @@ int dsi_pll_clock_register_12nm(struct platform_device *pdev,
				  struct mdss_pll_resources *pll_res)
{
	int rc = 0, ndx, i;
	struct clk *clk;
	struct clk *clk = NULL;
	struct clk_onecell_data *clk_data;
	int num_clks = ARRAY_SIZE(mdss_dsi_pllcc_12nm);
	struct regmap *rmap;
	struct dsi_pll_db *pdb;

	if (!pdev || !pdev->dev.of_node ||
		!pll_res || !pll_res->pll_base || !pll_res->phy_base) {
		!pll_res || !pll_res->pll_base) {
		pr_err("Invalid params\n");
		return -EINVAL;
	}
@@ -637,7 +641,7 @@ int dsi_pll_clock_register_12nm(struct platform_device *pdev,
	clk_data->clk_num = num_clks;

	/* Establish client data */
	if (ndx == 0) {
	if (pll_res->index == 0) {
		rmap = devm_regmap_init(&pdev->dev, &post_div_mux_regmap_bus,
				pll_res, &dsi_pll_12nm_config);
		dsi0pll_post_div_mux.clkr.regmap = rmap;
@@ -700,8 +704,8 @@ int dsi_pll_clock_register_12nm(struct platform_device *pdev,
				of_clk_src_onecell_get, clk_data);
	}
	if (!rc) {
		pr_info("Registered DSI PLL ndx=%d,clocks successfully\n", ndx);

		pr_info("Registered DSI PLL ndx=%d, clocks successfully\n",
				pll_res->index);
		return rc;
	}
clk_register_fail:
+3 −1
Original line number Diff line number Diff line
@@ -128,7 +128,9 @@ static int mdss_pll_resource_parse(struct platform_device *pdev,
		pll_res->pll_interface_type = MDSS_DP_PLL_14NM;
		pll_res->target_id = MDSS_PLL_TARGET_SDM660;
		pll_res->revision = 2;
	} else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_28lpm"))
	} else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_12nm"))
		pll_res->pll_interface_type = MDSS_DSI_PLL_12NM;
	else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_28lpm"))
		pll_res->pll_interface_type = MDSS_DSI_PLL_28LPM;
	else
		goto err;
+3 −2
Original line number Diff line number Diff line
@@ -219,7 +219,8 @@ static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res)
		return true;
	}
	if ((pll_res->target_id == MDSS_PLL_TARGET_SDM660) ||
			(pll_res->pll_interface_type == MDSS_DSI_PLL_28LPM))
			(pll_res->pll_interface_type == MDSS_DSI_PLL_28LPM) ||
			(pll_res->pll_interface_type == MDSS_DSI_PLL_12NM))
		ret = ((readl_relaxed(pll_res->gdsc_base + 0x4) & BIT(31)) &&
		(!(readl_relaxed(pll_res->gdsc_base) & BIT(0)))) ? false : true;
	else