diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/phy')
| -rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 83 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 190 | 
5 files changed, 225 insertions, 63 deletions
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 6ca6bfd4809b..8c65ef6968ca 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -5,6 +5,7 @@  #include <linux/clk-provider.h>  #include <linux/platform_device.h> +#include <dt-bindings/phy/phy.h>  #include "dsi_phy.h" @@ -461,6 +462,51 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,  	return 0;  } +int msm_dsi_cphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing, +	struct msm_dsi_phy_clk_request *clk_req) +{ +	const unsigned long bit_rate = clk_req->bitclk_rate; +	const unsigned long esc_rate = clk_req->escclk_rate; +	s32 ui, ui_x7; +	s32 tmax, tmin; +	s32 coeff = 1000; /* Precision, should avoid overflow */ +	s32 temp; + +	if (!bit_rate || !esc_rate) +		return -EINVAL; + +	ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000); +	ui_x7 = ui * 7; + +	temp = S_DIV_ROUND_UP(38 * coeff, ui_x7); +	tmin = max_t(s32, temp, 0); +	temp = (95 * coeff) / ui_x7; +	tmax = max_t(s32, temp, 0); +	timing->clk_prepare = linear_inter(tmax, tmin, 50, 0, false); + +	tmin = DIV_ROUND_UP(50 * coeff, ui_x7); +	tmax = 255; +	timing->hs_rqst = linear_inter(tmax, tmin, 1, 0, false); + +	tmin = DIV_ROUND_UP(100 * coeff, ui_x7) - 1; +	tmax = 255; +	timing->hs_exit = linear_inter(tmax, tmin, 10, 0, false); + +	tmin = 1; +	tmax = 32; +	timing->shared_timings.clk_post = linear_inter(tmax, tmin, 80, 0, false); + +	tmin = min_t(s32, 64, S_DIV_ROUND_UP(262 * coeff, ui_x7) - 1); +	tmax = 64; +	timing->shared_timings.clk_pre = linear_inter(tmax, tmin, 20, 0, false); + +	DBG("%d, %d, %d, %d, %d", +		timing->shared_timings.clk_pre, timing->shared_timings.clk_post, +		timing->clk_prepare, timing->hs_exit, timing->hs_rqst); + +	return 0; +} +  static int dsi_phy_regulator_init(struct msm_dsi_phy *phy)  {  	struct regulator_bulk_data *s = phy->supplies; @@ -593,6 +639,8 @@ static const struct of_device_id dsi_phy_dt_match[] = {  	  .data = &dsi_phy_7nm_cfgs },  	{ .compatible = "qcom,dsi-phy-7nm-8150",  	  .data = &dsi_phy_7nm_8150_cfgs }, +	{ .compatible = "qcom,sc7280-dsi-phy-7nm", +	  .data = &dsi_phy_7nm_7280_cfgs },  #endif  	{}  }; @@ -625,17 +673,13 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)  {  	struct msm_dsi_phy *phy;  	struct device *dev = &pdev->dev; -	const struct of_device_id *match; +	u32 phy_type;  	int ret;  	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);  	if (!phy)  		return -ENOMEM; -	match = of_match_node(dsi_phy_dt_match, dev->of_node); -	if (!match) -		return -ENODEV; -  	phy->provided_clocks = devm_kzalloc(dev,  			struct_size(phy->provided_clocks, hws, NUM_PROVIDED_CLKS),  			GFP_KERNEL); @@ -644,7 +688,10 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)  	phy->provided_clocks->num = NUM_PROVIDED_CLKS; -	phy->cfg = match->data; +	phy->cfg = of_device_get_match_data(&pdev->dev); +	if (!phy->cfg) +		return -ENODEV; +  	phy->pdev = pdev;  	phy->id = dsi_phy_get_id(phy); @@ -657,6 +704,8 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)  	phy->regulator_ldo_mode = of_property_read_bool(dev->of_node,  				"qcom,dsi-phy-regulator-ldo-mode"); +	if (!of_property_read_u32(dev->of_node, "phy-type", &phy_type)) +		phy->cphy_mode = (phy_type == PHY_TYPE_CPHY);  	phy->base = msm_ioremap_size(pdev, "dsi_phy", "DSI_PHY", &phy->base_size);  	if (IS_ERR(phy->base)) { @@ -754,7 +803,8 @@ void __exit msm_dsi_phy_driver_unregister(void)  }  int msm_dsi_phy_enable(struct msm_dsi_phy *phy, -			struct msm_dsi_phy_clk_request *clk_req) +			struct msm_dsi_phy_clk_request *clk_req, +			struct msm_dsi_phy_shared_timings *shared_timings)  {  	struct device *dev = &phy->pdev->dev;  	int ret; @@ -782,6 +832,9 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy,  		goto phy_en_fail;  	} +	memcpy(shared_timings, &phy->timing.shared_timings, +	       sizeof(*shared_timings)); +  	/*  	 * Resetting DSI PHY silently changes its PLL registers to reset status,  	 * which will confuse clock driver and result in wrong output rate of @@ -821,13 +874,6 @@ void msm_dsi_phy_disable(struct msm_dsi_phy *phy)  	dsi_phy_disable_resource(phy);  } -void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy, -			struct msm_dsi_phy_shared_timings *shared_timings) -{ -	memcpy(shared_timings, &phy->timing.shared_timings, -	       sizeof(*shared_timings)); -} -  void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,  			     enum msm_dsi_phy_usecase uc)  { @@ -835,6 +881,15 @@ void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,  		phy->usecase = uc;  } +/* Returns true if we have to clear DSI_LANE_CTRL.HS_REQ_SEL_PHY */ +bool msm_dsi_phy_set_continuous_clock(struct msm_dsi_phy *phy, bool enable) +{ +	if (!phy || !phy->cfg->ops.set_continuous_clock) +		return false; + +	return phy->cfg->ops.set_continuous_clock(phy, enable); +} +  int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy,  	struct clk **byte_clk_provider, struct clk **pixel_clk_provider)  { diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 5b0feef87127..b91303ada74f 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -24,6 +24,7 @@ struct msm_dsi_phy_ops {  	void (*disable)(struct msm_dsi_phy *phy);  	void (*save_pll_state)(struct msm_dsi_phy *phy);  	int (*restore_pll_state)(struct msm_dsi_phy *phy); +	bool (*set_continuous_clock)(struct msm_dsi_phy *phy, bool enable);  };  struct msm_dsi_phy_cfg { @@ -51,6 +52,7 @@ extern const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs;  extern const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs;  extern const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs;  extern const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs; +extern const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs;  struct msm_dsi_dphy_timing {  	u32 clk_zero; @@ -99,6 +101,7 @@ struct msm_dsi_phy {  	enum msm_dsi_phy_usecase usecase;  	bool regulator_ldo_mode; +	bool cphy_mode;  	struct clk_hw *vco_hw;  	bool pll_on; @@ -119,5 +122,7 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,  				struct msm_dsi_phy_clk_request *clk_req);  int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,  				struct msm_dsi_phy_clk_request *clk_req); +int msm_dsi_cphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing, +				struct msm_dsi_phy_clk_request *clk_req);  #endif /* __DSI_PHY_H__ */ diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index e46b10fc793a..d8128f50b0dd 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -84,7 +84,7 @@ struct dsi_pll_10nm {  #define to_pll_10nm(x)	container_of(x, struct dsi_pll_10nm, clk_hw)  /* - * Global list of private DSI PLL struct pointers. We need this for Dual DSI + * Global list of private DSI PLL struct pointers. We need this for bonded DSI   * mode, where the master PLL's clk_ops needs access the slave's private data   */  static struct dsi_pll_10nm *pll_10nm_list[DSI_MAX]; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index a34cf151c517..d13552b2213b 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -86,7 +86,7 @@ struct dsi_pll_14nm {  /*   * Private struct for N1/N2 post-divider clocks. These clocks are similar to   * the generic clk_divider class of clocks. The only difference is that it - * also sets the slave DSI PLL's post-dividers if in Dual DSI mode + * also sets the slave DSI PLL's post-dividers if in bonded DSI mode   */  struct dsi_pll_14nm_postdiv {  	struct clk_hw hw; @@ -102,7 +102,7 @@ struct dsi_pll_14nm_postdiv {  #define to_pll_14nm_postdiv(_hw) container_of(_hw, struct dsi_pll_14nm_postdiv, hw)  /* - * Global list of private DSI PLL struct pointers. We need this for Dual DSI + * Global list of private DSI PLL struct pointers. We need this for bonded DSI   * mode, where the master PLL's clk_ops needs access the slave's private data   */  static struct dsi_pll_14nm *pll_14nm_list[DSI_MAX]; @@ -658,7 +658,7 @@ static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,  	val |= value << shift;  	dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val); -	/* If we're master in dual DSI mode, then the slave PLL's post-dividers +	/* If we're master in bonded DSI mode, then the slave PLL's post-dividers  	 * follow the master's post dividers  	 */  	if (pll_14nm->phy->usecase == MSM_DSI_PHY_MASTER) { @@ -1050,7 +1050,7 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_660_cfgs = {  	.reg_cfg = {  		.num = 1,  		.regs = { -			{"vcca", 17000, 32}, +			{"vcca", 73400, 32},  		},  	},  	.ops = { diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index 7c23d4c47338..cb297b08458e 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -83,7 +83,7 @@ struct dsi_pll_7nm {  #define to_pll_7nm(x)	container_of(x, struct dsi_pll_7nm, clk_hw)  /* - * Global list of private DSI PLL struct pointers. We need this for Dual DSI + * Global list of private DSI PLL struct pointers. We need this for bonded DSI   * mode, where the master PLL's clk_ops needs access the slave's private data   */  static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX]; @@ -256,7 +256,7 @@ static void dsi_pll_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *confi  		  (config->frac_div_start & 0x30000) >> 16);  	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40);  	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); -	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, 0x10); /* TODO: 0x00 for CPHY */ +	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, pll->phy->cphy_mode ? 0x00 : 0x10);  	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, config->pll_clock_inverters);  } @@ -642,7 +642,8 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide  	/* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */  	hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, -					  CLK_SET_RATE_PARENT, 1, 8); +					  CLK_SET_RATE_PARENT, 1, +					  pll_7nm->phy->cphy_mode ? 7 : 8);  	if (IS_ERR(hw)) {  		ret = PTR_ERR(hw);  		goto fail; @@ -663,32 +664,47 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide  	snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id);  	snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id); -	hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, -					  0, 1, 4); +	if (pll_7nm->phy->cphy_mode) +		hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 2, 7); +	else +		hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 4);  	if (IS_ERR(hw)) {  		ret = PTR_ERR(hw);  		goto fail;  	} -	snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->phy->id); -	snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id); -	snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id); -	snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id); -	snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id); - -	hw = devm_clk_hw_register_mux(dev, clk_name, -				 ((const char *[]){ -				 parent, parent2, parent3, parent4 -				 }), 4, 0, pll_7nm->phy->base + -				 REG_DSI_7nm_PHY_CMN_CLK_CFG1, -				 0, 2, 0, NULL); -	if (IS_ERR(hw)) { -		ret = PTR_ERR(hw); -		goto fail; +	/* in CPHY mode, pclk_mux will always have post_out_div as parent +	 * don't register a pclk_mux clock and just use post_out_div instead +	 */ +	if (pll_7nm->phy->cphy_mode) { +		u32 data; + +		data = dsi_phy_read(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +		dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data | 3); + +		snprintf(parent, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id); +	} else { +		snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->phy->id); +		snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id); +		snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id); +		snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id); +		snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id); + +		hw = devm_clk_hw_register_mux(dev, clk_name, +					((const char *[]){ +					parent, parent2, parent3, parent4 +					}), 4, 0, pll_7nm->phy->base + +					REG_DSI_7nm_PHY_CMN_CLK_CFG1, +					0, 2, 0, NULL); +		if (IS_ERR(hw)) { +			ret = PTR_ERR(hw); +			goto fail; +		} + +		snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->phy->id);  	}  	snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_7nm->phy->id); -	snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->phy->id);  	/* PIX CLK DIV : DIV_CTRL_7_4*/  	hw = devm_clk_hw_register_divider(dev, clk_name, parent, @@ -813,15 +829,21 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,  	struct msm_dsi_dphy_timing *timing = &phy->timing;  	void __iomem *base = phy->base;  	bool less_than_1500_mhz; -	u32 vreg_ctrl_0, glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0; +	u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0; +	u32 glbl_pemph_ctrl_0; +	u32 glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0;  	u32 glbl_rescode_top_ctrl, glbl_rescode_bot_ctrl;  	u32 data;  	DBG(""); -	if (msm_dsi_dphy_timing_calc_v4(timing, clk_req)) { +	if (phy->cphy_mode) +		ret = msm_dsi_cphy_timing_calc_v4(timing, clk_req); +	else +		ret = msm_dsi_dphy_timing_calc_v4(timing, clk_req); +	if (ret) {  		DRM_DEV_ERROR(&phy->pdev->dev, -			"%s: D-PHY timing calculation failed\n", __func__); +			"%s: PHY timing calculation failed\n", __func__);  		return -EINVAL;  	} @@ -842,6 +864,10 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,  	/* Alter PHY configurations if data rate less than 1.5GHZ*/  	less_than_1500_mhz = (clk_req->bitclk_rate <= 1500000000); +	/* For C-PHY, no low power settings for lower clk rate */ +	if (phy->cphy_mode) +		less_than_1500_mhz = false; +  	if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {  		vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52;  		glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x00; @@ -856,6 +882,17 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,  		glbl_rescode_bot_ctrl = 0x3c;  	} +	if (phy->cphy_mode) { +		vreg_ctrl_0 = 0x51; +		vreg_ctrl_1 = 0x55; +		glbl_pemph_ctrl_0 = 0x11; +		lane_ctrl0 = 0x17; +	} else { +		vreg_ctrl_1 = 0x5c; +		glbl_pemph_ctrl_0 = 0x00; +		lane_ctrl0 = 0x1f; +	} +  	/* de-assert digital and pll power down */  	data = BIT(6) | BIT(5);  	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data); @@ -876,15 +913,22 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,  	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG0, 0x21);  	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG1, 0x84); +	if (phy->cphy_mode) +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_CTRL, BIT(6)); +  	/* Enable LDO */  	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_0, vreg_ctrl_0); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_1, 0x5c); +	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_1, vreg_ctrl_1); +  	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x00);  	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL,  		      glbl_str_swi_cal_sel_ctrl);  	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_HSTX_STR_CTRL_0,  		      glbl_hstx_str_ctrl_0); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_0, 0x00); +	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_0, +		      glbl_pemph_ctrl_0); +	if (phy->cphy_mode) +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_1, 0x01);  	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL,  		      glbl_rescode_top_ctrl);  	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL, @@ -894,10 +938,11 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,  	/* Remove power down from all blocks */  	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x7f); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, 0x1f); +	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, lane_ctrl0);  	/* Select full-rate mode */ -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_2, 0x40); +	if (!phy->cphy_mode) +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_2, 0x40);  	ret = dsi_7nm_set_usecase(phy);  	if (ret) { @@ -907,22 +952,36 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,  	}  	/* DSI PHY timings */ -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_1, timing->clk_zero); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_2, timing->clk_prepare); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_3, timing->clk_trail); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5, timing->hs_zero); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->hs_prepare); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7, timing->hs_trail); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_12, -		      timing->shared_timings.clk_pre); -	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_13, -		      timing->shared_timings.clk_post); +	if (phy->cphy_mode) { +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5, +			timing->shared_timings.clk_pre); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->clk_prepare); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7, +			timing->shared_timings.clk_post); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00); +	} else { +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_1, timing->clk_zero); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_2, timing->clk_prepare); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_3, timing->clk_trail); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5, timing->hs_zero); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->hs_prepare); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7, timing->hs_trail); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_12, +			timing->shared_timings.clk_pre); +		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_13, +			timing->shared_timings.clk_post); +	}  	/* DSI lane settings */  	dsi_phy_hw_v4_0_lane_settings(phy); @@ -932,6 +991,21 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,  	return 0;  } +static bool dsi_7nm_set_continuous_clock(struct msm_dsi_phy *phy, bool enable) +{ +	void __iomem *base = phy->base; +	u32 data; + +	data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1); +	if (enable) +		data |= BIT(5) | BIT(6); +	else +		data &= ~(BIT(5) | BIT(6)); +	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1, data); + +	return enable; +} +  static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)  {  	void __iomem *base = phy->base; @@ -972,6 +1046,7 @@ const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = {  		.pll_init = dsi_pll_7nm_init,  		.save_pll_state = dsi_7nm_pll_save_state,  		.restore_pll_state = dsi_7nm_pll_restore_state, +		.set_continuous_clock = dsi_7nm_set_continuous_clock,  	},  	.min_pll_rate = 600000000UL,  #ifdef CONFIG_64BIT @@ -998,9 +1073,36 @@ const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs = {  		.pll_init = dsi_pll_7nm_init,  		.save_pll_state = dsi_7nm_pll_save_state,  		.restore_pll_state = dsi_7nm_pll_restore_state, +		.set_continuous_clock = dsi_7nm_set_continuous_clock,  	},  	.min_pll_rate = 1000000000UL,  	.max_pll_rate = 3500000000UL,  	.io_start = { 0xae94400, 0xae96400 },  	.num_dsi_phy = 2,  }; + +const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs = { +	.has_phy_lane = true, +	.reg_cfg = { +		.num = 1, +		.regs = { +			{"vdds", 37550, 0}, +		}, +	}, +	.ops = { +		.enable = dsi_7nm_phy_enable, +		.disable = dsi_7nm_phy_disable, +		.pll_init = dsi_pll_7nm_init, +		.save_pll_state = dsi_7nm_pll_save_state, +		.restore_pll_state = dsi_7nm_pll_restore_state, +	}, +	.min_pll_rate = 600000000UL, +#ifdef CONFIG_64BIT +	.max_pll_rate = 5000000000ULL, +#else +	.max_pll_rate = ULONG_MAX, +#endif +	.io_start = { 0xae94400 }, +	.num_dsi_phy = 1, +	.quirks = DSI_PHY_7NM_QUIRK_V4_1, +};  | 
