Эх сурвалжийг харах

disp: msm: dsi: Add support for C-PHY dynamic clock switch

This change adds support for C-PHY dynamic clock switch feature.
Also add support for phy ver 4.0 C-PHY timing parameters calculation
to be used for clock switch.

Change-Id: I8292860fd8c93a7ba7988ec8c44ea9683f45b6e6
Signed-off-by: Ritesh Kumar <[email protected]>
Signed-off-by: Harigovindan P <[email protected]>
Signed-off-by: Steve Cohen <[email protected]>
Harigovindan P 5 жил өмнө
parent
commit
662ac3ab89

+ 53 - 13
msm/dsi/dsi_display.c

@@ -3306,11 +3306,15 @@ static int dsi_display_clocks_init(struct dsi_display *display)
 	const char *mux_byte = "mux_byte", *mux_pixel = "mux_pixel";
 	const char *cphy_byte = "cphy_byte", *cphy_pixel = "cphy_pixel";
 	const char *shadow_byte = "shadow_byte", *shadow_pixel = "shadow_pixel";
+	const char *shadow_cphybyte = "shadow_cphybyte",
+		   *shadow_cphypixel = "shadow_cphypixel";
 	struct clk *dsi_clk;
 	struct dsi_clk_link_set *src = &display->clock_info.src_clks;
 	struct dsi_clk_link_set *mux = &display->clock_info.mux_clks;
 	struct dsi_clk_link_set *cphy = &display->clock_info.cphy_clks;
 	struct dsi_clk_link_set *shadow = &display->clock_info.shadow_clks;
+	struct dsi_clk_link_set *shadow_cphy =
+				&display->clock_info.shadow_cphy_clks;
 	struct dsi_dyn_clk_caps *dyn_clk_caps = &(display->panel->dyn_clk_caps);
 	char *dsi_clock_name;
 
@@ -3369,6 +3373,12 @@ static int dsi_display_clocks_init(struct dsi_display *display)
 				if (dsi_display_check_prefix(shadow_pixel,
 							clk_name))
 					shadow->pixel_clk = NULL;
+				if (dsi_display_check_prefix(shadow_cphybyte,
+							clk_name))
+					shadow_cphy->byte_clk = NULL;
+				if (dsi_display_check_prefix(shadow_cphypixel,
+							clk_name))
+					shadow_cphy->pixel_clk = NULL;
 
 				dyn_clk_caps->dyn_clk_support = false;
 			}
@@ -3413,6 +3423,16 @@ static int dsi_display_clocks_init(struct dsi_display *display)
 			shadow->pixel_clk = dsi_clk;
 			continue;
 		}
+
+		if (dsi_display_check_prefix(shadow_cphybyte, clk_name)) {
+			shadow_cphy->byte_clk = dsi_clk;
+			continue;
+		}
+
+		if (dsi_display_check_prefix(shadow_cphypixel, clk_name)) {
+			shadow_cphy->pixel_clk = dsi_clk;
+			continue;
+		}
 	}
 
 	return 0;
@@ -4278,12 +4298,12 @@ static int dsi_display_update_dsi_bitrate(struct dsi_display *display,
 			byte_intf_clk_div = host_cfg->byte_intf_clk_div;
 			do_div(byte_intf_clk_rate, byte_intf_clk_div);
 		} else {
-			do_div(bit_rate, bits_per_symbol);
-			bit_rate *= num_of_symbols;
-			bit_rate_per_lane = bit_rate;
-			do_div(bit_rate_per_lane, num_of_lanes);
-			byte_clk_rate = bit_rate_per_lane;
-			do_div(byte_clk_rate, 7);
+			bit_rate_per_lane = bit_clk_rate;
+			pclk_rate *= bits_per_symbol;
+			do_div(pclk_rate, num_of_symbols);
+			byte_clk_rate = bit_clk_rate;
+			do_div(byte_clk_rate, num_of_symbols);
+
 			/* For CPHY, byte_intf_clk is same as byte_clk */
 			byte_intf_clk_rate = byte_clk_rate;
 		}
@@ -4367,6 +4387,17 @@ static void _dsi_display_calc_pipe_delay(struct dsi_display *display,
 	delay->pll_delay = ((130 * esc_clk_rate_hz) / 1000000) * 2;
 }
 
+/*
+ * dsi_display_is_type_cphy - check if panel type is cphy
+ * @display: Pointer to private display structure
+ * Returns: True if panel type is cphy
+ */
+static inline bool dsi_display_is_type_cphy(struct dsi_display *display)
+{
+	return (display->panel->host_config.phy_type ==
+		DSI_PHY_TYPE_CPHY) ? true : false;
+}
+
 static int _dsi_display_dyn_update_clks(struct dsi_display *display,
 					struct link_clk_freq *bkp_freq)
 {
@@ -4374,17 +4405,26 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
 	u8 ctrl_version;
 	struct dsi_display_ctrl *m_ctrl, *ctrl;
 	struct dsi_dyn_clk_caps *dyn_clk_caps;
+	struct dsi_clk_link_set *parent_clk, *enable_clk;
 
 	m_ctrl = &display->ctrl[display->clk_master_idx];
 	dyn_clk_caps = &(display->panel->dyn_clk_caps);
 	ctrl_version = m_ctrl->ctrl->version;
 
-	dsi_clk_prepare_enable(&display->clock_info.src_clks);
+	if (dsi_display_is_type_cphy(display)) {
+		enable_clk = &display->clock_info.cphy_clks;
+		parent_clk = &display->clock_info.shadow_cphy_clks;
+	} else {
+		enable_clk = &display->clock_info.src_clks;
+		parent_clk = &display->clock_info.shadow_clks;
+	}
 
-	rc = dsi_clk_update_parent(&display->clock_info.shadow_clks,
-			      &display->clock_info.mux_clks);
+	dsi_clk_prepare_enable(enable_clk);
+
+	rc = dsi_clk_update_parent(parent_clk,
+				&display->clock_info.mux_clks);
 	if (rc) {
-		DSI_ERR("failed update mux parent to shadow\n");
+		DSI_ERR("failed to update mux parent\n");
 		goto exit;
 	}
 
@@ -4443,12 +4483,12 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
 	}
 
 defer_dfps_wait:
-	rc = dsi_clk_update_parent(&display->clock_info.src_clks,
-			      &display->clock_info.mux_clks);
+	rc = dsi_clk_update_parent(enable_clk,
+			&display->clock_info.mux_clks);
 	if (rc)
 		DSI_ERR("could not switch back to src clks %d\n", rc);
 
-	dsi_clk_disable_unprepare(&display->clock_info.src_clks);
+	dsi_clk_disable_unprepare(enable_clk);
 
 	return rc;
 

+ 3 - 1
msm/dsi/dsi_display.h

@@ -106,13 +106,15 @@ struct dsi_display_boot_param {
  * struct dsi_display_clk_info - dsi display clock source information
  * @src_clks:          Source clocks for DSI display.
  * @mux_clks:          Mux clocks used for DFPS.
- * @shadow_clks:       Used for DFPS.
+ * @shadow_clks:       Used for D-phy clock switch.
+ * @shadow_cphy_clks:  Used for C-phy clock switch.
  */
 struct dsi_display_clk_info {
 	struct dsi_clk_link_set src_clks;
 	struct dsi_clk_link_set mux_clks;
 	struct dsi_clk_link_set cphy_clks;
 	struct dsi_clk_link_set shadow_clks;
+	struct dsi_clk_link_set shadow_cphy_clks;
 };
 
 /**

+ 5 - 3
msm/dsi/dsi_phy_hw_v4_0.c

@@ -667,6 +667,8 @@ void dsi_phy_hw_v4_0_dyn_refresh_config(struct dsi_phy_hw *phy,
 					struct dsi_phy_cfg *cfg, bool is_master)
 {
 	u32 reg;
+	bool is_cphy = (cfg->phy_type == DSI_PHY_TYPE_CPHY) ?
+			true : false;
 
 	if (is_master) {
 		DSI_DYN_REF_REG_W(phy->dyn_pll_base, DSI_DYN_REFRESH_PLL_CTRL19,
@@ -692,7 +694,7 @@ void dsi_phy_hw_v4_0_dyn_refresh_config(struct dsi_phy_hw *phy,
 			  cfg->timing.lane_v4[12], cfg->timing.lane_v4[13]);
 		DSI_DYN_REF_REG_W(phy->dyn_pll_base, DSI_DYN_REFRESH_PLL_CTRL26,
 			  DSIPHY_CMN_CTRL_0, DSIPHY_CMN_LANE_CTRL0,
-			  0x7f, 0x1f);
+			  0x7f, is_cphy ? 0x17 : 0x1f);
 
 	} else {
 		reg = DSI_R32(phy, DSIPHY_CMN_CLK_CFG1);
@@ -727,7 +729,7 @@ void dsi_phy_hw_v4_0_dyn_refresh_config(struct dsi_phy_hw *phy,
 			  cfg->timing.lane_v4[13], 0x7f);
 		DSI_DYN_REF_REG_W(phy->dyn_pll_base, DSI_DYN_REFRESH_PLL_CTRL9,
 			  DSIPHY_CMN_LANE_CTRL0, DSIPHY_CMN_CTRL_2,
-			  0x1f, 0x40);
+			  is_cphy ? 0x17 : 0x1f, 0x40);
 		/*
 		 * fill with dummy register writes since controller will blindly
 		 * send these values to DSI PHY.
@@ -736,7 +738,7 @@ void dsi_phy_hw_v4_0_dyn_refresh_config(struct dsi_phy_hw *phy,
 		while (reg <= DSI_DYN_REFRESH_PLL_CTRL29) {
 			DSI_DYN_REF_REG_W(phy->dyn_pll_base, reg,
 				  DSIPHY_CMN_LANE_CTRL0, DSIPHY_CMN_CTRL_0,
-				  0x1f, 0x7f);
+				  is_cphy ? 0x17 : 0x1f, 0x7f);
 			reg += 0x4;
 		}
 

+ 234 - 14
msm/dsi/dsi_phy_timing_calc.c

@@ -37,6 +37,12 @@ static int calc_clk_prepare(struct dsi_phy_hw *phy,
 	s64 intermediate;
 	s64 clk_prep_actual;
 
+	t->rec_min = DIV_ROUND_UP((t->mipi_min * clk_params->bitclk_mbps),
+			(8 * clk_params->tlpx_numer_ns));
+	t->rec_max = rounddown(
+		mult_frac((t->mipi_max * clk_params->bitclk_mbps),
+			1, (8 * clk_params->tlpx_numer_ns)), 1);
+
 	dividend = ((t->rec_max - t->rec_min) *
 		clk_params->clk_prep_buf * multiplier);
 	temp  = roundup(div_s64(dividend, 100), multiplier);
@@ -622,6 +628,218 @@ error:
 	return rc;
 }
 
+/**
+ * calc_cphy_clk_prepare - calculates cphy_clk_prepare parameter for cphy.
+ */
+static int calc_cphy_clk_prepare(struct dsi_phy_hw *phy,
+			struct phy_clk_params *clk_params,
+			struct phy_timing_desc *desc)
+{
+	u64 multiplier = BIT(20);
+	struct timing_entry *t = &desc->clk_prepare;
+	int rc = 0;
+	u64 dividend, temp;
+
+	t->rec_min = DIV_ROUND_UP((t->mipi_min * clk_params->bitclk_mbps),
+			(7 * clk_params->tlpx_numer_ns));
+	t->rec_max = rounddown(
+		mult_frac((t->mipi_max * clk_params->bitclk_mbps),
+			1, (7 * clk_params->tlpx_numer_ns)), 1);
+
+	dividend = ((t->rec_max - t->rec_min) *
+		clk_params->clk_prep_buf * multiplier);
+	temp  = roundup(div_s64(dividend, 100), multiplier);
+	temp += (t->rec_min * multiplier);
+	t->rec = div_s64(temp, multiplier);
+
+	rc = dsi_phy_cmn_validate_and_set(t, "cphy_clk_prepare");
+
+	DSI_DEBUG("CPHY_CLK_PREPARE: rec_min=%d, rec_max=%d, reg_val=%d\n",
+		t->rec_min, t->rec_max, t->reg_value);
+
+	return rc;
+}
+
+/**
+ * calc_cphy_clk_pre - calculates cphy_clk_pre parameter for cphy.
+ */
+static int calc_cphy_clk_pre(struct dsi_phy_hw *phy,
+			struct phy_clk_params *clk_params,
+			struct phy_timing_desc *desc)
+{
+	u64 multiplier = BIT(20);
+	struct timing_entry *t = &desc->clk_pre;
+	int rc = 0;
+	u64 dividend, temp;
+
+	t->mipi_min = min(300 - 38 - mult_frac(7, clk_params->tlpx_numer_ns,
+			clk_params->bitclk_mbps),
+			mult_frac(448, clk_params->tlpx_numer_ns,
+			clk_params->bitclk_mbps));
+	t->mipi_max = mult_frac(448, clk_params->tlpx_numer_ns,
+			clk_params->bitclk_mbps);
+
+	t->rec_min = DIV_ROUND_UP((t->mipi_min * clk_params->bitclk_mbps),
+			(7 * clk_params->tlpx_numer_ns));
+	t->rec_max = rounddown(
+		mult_frac((t->mipi_max * clk_params->bitclk_mbps),
+			1, (7 * clk_params->tlpx_numer_ns)), 1);
+
+	dividend = ((t->rec_max - t->rec_min) * clk_params->clk_pre_buf
+			* multiplier);
+	temp  = roundup(div_s64(dividend, 100), multiplier);
+	temp += (t->rec_min * multiplier);
+	t->rec = div_s64(temp, multiplier);
+
+	rc = dsi_phy_cmn_validate_and_set(t, "cphy_clk_pre");
+
+	DSI_DEBUG("CPHY_CLK_PRE: rec_min=%d, rec_max=%d, reg_val=%d\n",
+		t->rec_min, t->rec_max, t->reg_value);
+
+	return rc;
+}
+
+/**
+ * calc_cphy_clk_post - calculates cphy_clk_post parameter for cphy.
+ */
+static int calc_cphy_clk_post(struct dsi_phy_hw *phy,
+			struct phy_clk_params *clk_params,
+			struct phy_timing_desc *desc)
+{
+	u64 multiplier = BIT(20);
+	struct timing_entry *t = &desc->clk_post;
+	int rc = 0;
+	u64 dividend, temp;
+
+	t->mipi_min = mult_frac(7, clk_params->tlpx_numer_ns,
+			clk_params->bitclk_mbps);
+	t->mipi_max = mult_frac(224, clk_params->tlpx_numer_ns,
+			clk_params->bitclk_mbps);
+
+	t->rec_min = DIV_ROUND_UP((t->mipi_min * clk_params->bitclk_mbps),
+			(7 * clk_params->tlpx_numer_ns));
+	t->rec_max = rounddown(
+		mult_frac((t->mipi_max * clk_params->bitclk_mbps),
+			  1, (7 * clk_params->tlpx_numer_ns)), 1);
+
+	dividend = ((t->rec_max - t->rec_min) * clk_params->clk_post_buf
+			* multiplier);
+	temp  = roundup(div_s64(dividend, 100), multiplier);
+	temp += (t->rec_min * multiplier);
+	t->rec = div_s64(temp, multiplier);
+
+	rc = dsi_phy_cmn_validate_and_set(t, "cphy_clk_post");
+
+	DSI_DEBUG("CPHY_CLK_POST: rec_min=%d, rec_max=%d, reg_val=%d\n",
+		t->rec_min, t->rec_max, t->reg_value);
+
+	return rc;
+}
+
+/**
+ * calc_cphy_hs_rqst - calculates cphy_hs_rqst parameter for cphy.
+ */
+static int calc_cphy_hs_rqst(struct dsi_phy_hw *phy,
+			struct phy_clk_params *clk_params,
+			struct phy_timing_desc *desc)
+{
+	u64 multiplier = BIT(20);
+	struct timing_entry *t = &desc->hs_rqst;
+	int rc = 0;
+	u64 dividend, temp;
+
+	t->rec_min = DIV_ROUND_UP(
+		((t->mipi_min * clk_params->bitclk_mbps) -
+		 (7 * clk_params->tlpx_numer_ns)),
+		(7 * clk_params->tlpx_numer_ns));
+
+	dividend = ((t->rec_max - t->rec_min) *
+		clk_params->hs_rqst_buf * multiplier);
+	temp  = roundup(div_s64(dividend, 100), multiplier);
+	temp += t->rec_min * multiplier;
+	t->rec = div_s64(temp, multiplier);
+
+	rc = dsi_phy_cmn_validate_and_set(t, "cphy_hs_rqst");
+
+	DSI_DEBUG("CPHY_HS_RQST: rec_min=%d, rec_max=%d, reg_val=%d\n",
+		t->rec_min, t->rec_max, t->reg_value);
+
+	return rc;
+}
+
+/**
+ * calc_cphy_hs_exit - calculates cphy_hs_exit parameter for cphy.
+ */
+static int calc_cphy_hs_exit(struct dsi_phy_hw *phy,
+			struct phy_clk_params *clk_params,
+			struct phy_timing_desc *desc)
+{
+	int rc = 0;
+	u64 multiplier = BIT(20);
+	u64 dividend, temp;
+	struct timing_entry *t = &desc->hs_exit;
+
+	t->rec_min = (DIV_ROUND_UP(
+			(t->mipi_min * clk_params->bitclk_mbps),
+			(7 * clk_params->tlpx_numer_ns)) - 1);
+
+	dividend = ((t->rec_max - t->rec_min) *
+		clk_params->hs_exit_buf * multiplier);
+	temp  = roundup(div_s64(dividend, 100), multiplier);
+	temp += t->rec_min * multiplier;
+	t->rec = div_s64(temp, multiplier);
+
+	rc = dsi_phy_cmn_validate_and_set(t, "cphy_hs_exit");
+
+	DSI_DEBUG("CPHY_HS_EXIT: rec_min=%d, rec_max=%d, reg_val=%d\n",
+		t->rec_min, t->rec_max, t->reg_value);
+
+	return rc;
+}
+
+/**
+ * dsi_phy_calc_cphy_timing_params - calculates cphy timing parameters
+ *					for a given bit clock
+ */
+static int dsi_phy_cmn_calc_cphy_timing_params(struct dsi_phy_hw *phy,
+	struct phy_clk_params *clk_params, struct phy_timing_desc *desc)
+{
+	int rc = 0;
+
+	rc = calc_cphy_clk_prepare(phy, clk_params, desc);
+	if (rc) {
+		DSI_ERR("clk_prepare calculations failed, rc=%d\n", rc);
+		goto error;
+	}
+
+	rc = calc_cphy_clk_pre(phy, clk_params, desc);
+	if (rc) {
+		DSI_ERR("clk_pre calculations failed, rc=%d\n", rc);
+		goto error;
+	}
+
+	rc = calc_cphy_clk_post(phy, clk_params, desc);
+	if (rc) {
+		DSI_ERR("clk_zero calculations failed, rc=%d\n", rc);
+		goto error;
+	}
+
+	rc = calc_cphy_hs_rqst(phy, clk_params, desc);
+	if (rc) {
+		DSI_ERR("hs_rqst calculations failed, rc=%d\n", rc);
+		goto error;
+	}
+
+	rc = calc_cphy_hs_exit(phy, clk_params, desc);
+	if (rc) {
+		DSI_ERR("hs_exit calculations failed, rc=%d\n", rc);
+		goto error;
+	}
+
+error:
+	return rc;
+}
+
 /**
  * calculate_timing_params() - calculates timing parameters.
  * @phy:      Pointer to DSI PHY hardware object.
@@ -648,6 +866,7 @@ int dsi_phy_hw_calculate_timing_params(struct dsi_phy_hw *phy,
 	u32 const hs_exit_spec_min = 100;
 	u32 const hs_exit_reco_max = 255;
 	u32 const hs_rqst_spec_min = 50;
+	u32 const hs_rqst_reco_max = 255;
 
 	/* local vars */
 	int rc = 0;
@@ -660,6 +879,8 @@ int dsi_phy_hw_calculate_timing_params(struct dsi_phy_hw *phy,
 	struct phy_clk_params clk_params = {0};
 	struct phy_timing_ops *ops = phy->ops.timing_ops;
 
+	u32 phy_type = host->phy_type;
+
 	memset(&desc, 0x0, sizeof(desc));
 	h_total = dsi_h_total_dce(mode);
 	v_total = DSI_V_TOTAL(mode);
@@ -680,8 +901,11 @@ int dsi_phy_hw_calculate_timing_params(struct dsi_phy_hw *phy,
 
 	if (use_mode_bit_clk)
 		x = mode->clk_rate_hz;
-	else
+	else {
 		x = mult_frac(v_total * h_total, inter_num, num_of_lanes);
+		if (phy_type == DSI_PHY_TYPE_CPHY)
+			x = mult_frac(x, 7, 16);
+	}
 	y = rounddown(x, 1);
 
 	clk_params.bitclk_mbps = rounddown(DIV_ROUND_UP_ULL(y, 1000000), 1);
@@ -699,35 +923,31 @@ int dsi_phy_hw_calculate_timing_params(struct dsi_phy_hw *phy,
 	desc.hs_exit.rec_max = hs_exit_reco_max;
 	desc.hs_rqst.mipi_min = hs_rqst_spec_min;
 	desc.hs_rqst_clk.mipi_min = hs_rqst_spec_min;
+	desc.hs_rqst.rec_max = hs_rqst_reco_max;
 
 	if (ops->get_default_phy_params) {
-		ops->get_default_phy_params(&clk_params);
+		ops->get_default_phy_params(&clk_params, phy_type);
 	} else {
 		rc = -EINVAL;
 		goto error;
 	}
 
-	desc.clk_prepare.rec_min = DIV_ROUND_UP(
-			(desc.clk_prepare.mipi_min * clk_params.bitclk_mbps),
-			(8 * clk_params.tlpx_numer_ns)
-			);
-
-	desc.clk_prepare.rec_max = rounddown(
-		mult_frac((desc.clk_prepare.mipi_max * clk_params.bitclk_mbps),
-			  1, (8 * clk_params.tlpx_numer_ns)),
-		1);
-
 	DSI_PHY_DBG(phy, "BIT CLOCK = %d, tlpx_numer_ns=%d, treot_ns=%d\n",
 	       clk_params.bitclk_mbps, clk_params.tlpx_numer_ns,
 	       clk_params.treot_ns);
-	rc = dsi_phy_cmn_calc_timing_params(phy, &clk_params, &desc);
+
+	if (phy_type == DSI_PHY_TYPE_CPHY)
+		rc = dsi_phy_cmn_calc_cphy_timing_params(phy, &clk_params,
+							&desc);
+	else
+		rc = dsi_phy_cmn_calc_timing_params(phy, &clk_params, &desc);
 	if (rc) {
 		DSI_PHY_ERR(phy, "Timing calc failed, rc=%d\n", rc);
 		goto error;
 	}
 
 	if (ops->update_timing_params) {
-		ops->update_timing_params(timing, &desc);
+		ops->update_timing_params(timing, &desc, phy_type);
 	} else {
 		rc = -EINVAL;
 		goto error;

+ 13 - 9
msm/dsi/dsi_phy_timing_calc.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _DSI_PHY_TIMING_CALC_H_
@@ -81,7 +81,8 @@ struct phy_clk_params {
  * Various Ops needed for auto-calculation of DSI PHY timing parameters.
  */
 struct phy_timing_ops {
-	void (*get_default_phy_params)(struct phy_clk_params *params);
+	void (*get_default_phy_params)(struct phy_clk_params *params,
+				       u32 phy_type);
 
 	int32_t (*calc_clk_zero)(s64 rec_temp1, s64 mult);
 
@@ -96,14 +97,15 @@ struct phy_timing_ops {
 			struct phy_timing_desc *desc);
 
 	void (*update_timing_params)(struct dsi_phy_per_lane_cfgs *timing,
-		struct phy_timing_desc *desc);
+		struct phy_timing_desc *desc, u32 phy_type);
 };
 
 #define roundup64(x, y) \
 	({ u64 _tmp = (x)+(y)-1; do_div(_tmp, y); _tmp * y; })
 
 /* DSI PHY timing functions for 14nm */
-void dsi_phy_hw_v2_0_get_default_phy_params(struct phy_clk_params *params);
+void dsi_phy_hw_v2_0_get_default_phy_params(struct phy_clk_params *params,
+					    u32 phy_type);
 
 int32_t dsi_phy_hw_v2_0_calc_clk_zero(s64 rec_temp1, s64 mult);
 
@@ -118,10 +120,11 @@ void dsi_phy_hw_v2_0_calc_hs_trail(struct phy_clk_params *clk_params,
 		struct phy_timing_desc *desc);
 
 void dsi_phy_hw_v2_0_update_timing_params(struct dsi_phy_per_lane_cfgs *timing,
-		struct phy_timing_desc *desc);
+		struct phy_timing_desc *desc, u32 phy_type);
 
 /* DSI PHY timing functions for 10nm */
-void dsi_phy_hw_v3_0_get_default_phy_params(struct phy_clk_params *params);
+void dsi_phy_hw_v3_0_get_default_phy_params(struct phy_clk_params *params,
+					    u32 phy_type);
 
 int32_t dsi_phy_hw_v3_0_calc_clk_zero(s64 rec_temp1, s64 mult);
 
@@ -136,10 +139,11 @@ void dsi_phy_hw_v3_0_calc_hs_trail(struct phy_clk_params *clk_params,
 		struct phy_timing_desc *desc);
 
 void dsi_phy_hw_v3_0_update_timing_params(struct dsi_phy_per_lane_cfgs *timing,
-		struct phy_timing_desc *desc);
+		struct phy_timing_desc *desc, u32 phy_type);
 
 /* DSI PHY timing functions for 7nm */
-void dsi_phy_hw_v4_0_get_default_phy_params(struct phy_clk_params *params);
+void dsi_phy_hw_v4_0_get_default_phy_params(struct phy_clk_params *params,
+					    u32 phy_type);
 
 int32_t dsi_phy_hw_v4_0_calc_clk_zero(s64 rec_temp1, s64 mult);
 
@@ -154,6 +158,6 @@ void dsi_phy_hw_v4_0_calc_hs_trail(struct phy_clk_params *clk_params,
 		struct phy_timing_desc *desc);
 
 void dsi_phy_hw_v4_0_update_timing_params(struct dsi_phy_per_lane_cfgs *timing,
-		struct phy_timing_desc *desc);
+		struct phy_timing_desc *desc, u32 phy_type);
 
 #endif /* _DSI_PHY_TIMING_CALC_H_ */

+ 4 - 3
msm/dsi/dsi_phy_timing_v2_0.c

@@ -1,11 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  */
 
 #include "dsi_phy_timing_calc.h"
 
-void dsi_phy_hw_v2_0_get_default_phy_params(struct phy_clk_params *params)
+void dsi_phy_hw_v2_0_get_default_phy_params(struct phy_clk_params *params,
+					    u32 phy_type)
 {
 	params->clk_prep_buf = 50;
 	params->clk_zero_buf = 2;
@@ -77,7 +78,7 @@ void dsi_phy_hw_v2_0_calc_hs_trail(struct phy_clk_params *clk_params,
 
 void dsi_phy_hw_v2_0_update_timing_params(
 	struct dsi_phy_per_lane_cfgs *timing,
-	struct phy_timing_desc *desc)
+	struct phy_timing_desc *desc, u32 phy_type)
 {
 	int i = 0;
 

+ 3 - 3
msm/dsi/dsi_phy_timing_v3_0.c

@@ -1,12 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  */
 
 #include "dsi_phy_timing_calc.h"
 
 void dsi_phy_hw_v3_0_get_default_phy_params(
-		struct phy_clk_params *params)
+		struct phy_clk_params *params, u32 phy_type)
 {
 	params->clk_prep_buf = 0;
 	params->clk_zero_buf = 0;
@@ -72,7 +72,7 @@ void dsi_phy_hw_v3_0_calc_hs_trail(struct phy_clk_params *clk_params,
 
 void dsi_phy_hw_v3_0_update_timing_params(
 	struct dsi_phy_per_lane_cfgs *timing,
-	struct phy_timing_desc *desc)
+	struct phy_timing_desc *desc, u32 phy_type)
 {
 	timing->lane_v3[0] = 0x00;
 	timing->lane_v3[1] = desc->clk_zero.reg_value;

+ 51 - 28
msm/dsi/dsi_phy_timing_v4_0.c

@@ -1,24 +1,32 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  */
 
 #include "dsi_phy_timing_calc.h"
 
 void dsi_phy_hw_v4_0_get_default_phy_params(
-		struct phy_clk_params *params)
+		struct phy_clk_params *params, u32 phy_type)
 {
-	params->clk_prep_buf = 50;
-	params->clk_zero_buf = 2;
-	params->clk_trail_buf = 30;
-	params->hs_prep_buf = 50;
-	params->hs_zero_buf = 10;
-	params->hs_trail_buf = 30;
-	params->hs_rqst_buf = 0;
-	params->hs_exit_buf = 10;
-	/* 1.25 is used in code for precision */
-	params->clk_pre_buf = 1;
-	params->clk_post_buf = 5;
+	if (phy_type == DSI_PHY_TYPE_CPHY) {
+		params->clk_prep_buf = 50;
+		params->clk_pre_buf = 20;
+		params->clk_post_buf = 80;
+		params->hs_rqst_buf = 1;
+		params->hs_exit_buf = 10;
+	} else {
+		params->clk_prep_buf = 50;
+		params->clk_zero_buf = 2;
+		params->clk_trail_buf = 30;
+		params->hs_prep_buf = 50;
+		params->hs_zero_buf = 10;
+		params->hs_trail_buf = 30;
+		params->hs_rqst_buf = 0;
+		params->hs_exit_buf = 10;
+		/* 1.25 is used in code for precision */
+		params->clk_pre_buf = 1;
+		params->clk_post_buf = 5;
+	}
 }
 
 int32_t dsi_phy_hw_v4_0_calc_clk_zero(s64 rec_temp1, s64 mult)
@@ -75,22 +83,37 @@ void dsi_phy_hw_v4_0_calc_hs_trail(struct phy_clk_params *clk_params,
 
 void dsi_phy_hw_v4_0_update_timing_params(
 	struct dsi_phy_per_lane_cfgs *timing,
-	struct phy_timing_desc *desc)
+	struct phy_timing_desc *desc, u32 phy_type)
 {
-	timing->lane_v4[0] = 0x00;
-	timing->lane_v4[1] = desc->clk_zero.reg_value;
-	timing->lane_v4[2] = desc->clk_prepare.reg_value;
-	timing->lane_v4[3] = desc->clk_trail.reg_value;
-	timing->lane_v4[4] = desc->hs_exit.reg_value;
-	timing->lane_v4[5] = desc->hs_zero.reg_value;
-	timing->lane_v4[6] = desc->hs_prepare.reg_value;
-	timing->lane_v4[7] = desc->hs_trail.reg_value;
-	timing->lane_v4[8] = desc->hs_rqst.reg_value;
-	timing->lane_v4[9] = 0x02;
-	timing->lane_v4[10] = 0x04;
-	timing->lane_v4[11] = 0x00;
-	timing->lane_v4[12] = desc->clk_pre.reg_value;
-	timing->lane_v4[13] = desc->clk_post.reg_value;
+	if (phy_type == DSI_PHY_TYPE_CPHY) {
+		timing->lane_v4[0] = 0x00;
+		timing->lane_v4[1] = 0x00;
+		timing->lane_v4[2] = 0x00;
+		timing->lane_v4[3] = 0x00;
+		timing->lane_v4[4] = desc->hs_exit.reg_value;
+		timing->lane_v4[5] = desc->clk_pre.reg_value;
+		timing->lane_v4[6] = desc->clk_prepare.reg_value;
+		timing->lane_v4[7] = desc->clk_post.reg_value;
+		timing->lane_v4[8] = desc->hs_rqst.reg_value;
+		timing->lane_v4[9] = 0x02;
+		timing->lane_v4[10] = 0x04;
+		timing->lane_v4[11] = 0x00;
+	} else {
+		timing->lane_v4[0] = 0x00;
+		timing->lane_v4[1] = desc->clk_zero.reg_value;
+		timing->lane_v4[2] = desc->clk_prepare.reg_value;
+		timing->lane_v4[3] = desc->clk_trail.reg_value;
+		timing->lane_v4[4] = desc->hs_exit.reg_value;
+		timing->lane_v4[5] = desc->hs_zero.reg_value;
+		timing->lane_v4[6] = desc->hs_prepare.reg_value;
+		timing->lane_v4[7] = desc->hs_trail.reg_value;
+		timing->lane_v4[8] = desc->hs_rqst.reg_value;
+		timing->lane_v4[9] = 0x02;
+		timing->lane_v4[10] = 0x04;
+		timing->lane_v4[11] = 0x00;
+		timing->lane_v4[12] = desc->clk_pre.reg_value;
+		timing->lane_v4[13] = desc->clk_post.reg_value;
+	}
 
 	DSI_DEBUG("[%d %d %d %d]\n", timing->lane_v4[0],
 		timing->lane_v4[1], timing->lane_v4[2], timing->lane_v4[3]);