diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi_host.c')
| -rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_host.c | 69 | 
1 files changed, 35 insertions, 34 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 89aadd3b3202..18fa30e1e858 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -122,6 +122,7 @@ struct msm_dsi_host {  	struct clk *byte_intf_clk;  	unsigned long byte_clk_rate; +	unsigned long byte_intf_clk_rate;  	unsigned long pixel_clk_rate;  	unsigned long esc_clk_rate; @@ -398,7 +399,6 @@ int msm_dsi_runtime_resume(struct device *dev)  int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)  { -	unsigned long byte_intf_rate;  	int ret;  	DBG("Set clk rates: pclk=%d, byteclk=%lu", @@ -418,13 +418,7 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)  	}  	if (msm_host->byte_intf_clk) { -		/* For CPHY, byte_intf_clk is same as byte_clk */ -		if (msm_host->cphy_mode) -			byte_intf_rate = msm_host->byte_clk_rate; -		else -			byte_intf_rate = msm_host->byte_clk_rate / 2; - -		ret = clk_set_rate(msm_host->byte_intf_clk, byte_intf_rate); +		ret = clk_set_rate(msm_host->byte_intf_clk, msm_host->byte_intf_clk_rate);  		if (ret) {  			pr_err("%s: Failed to set rate byte intf clk, %d\n",  			       __func__, ret); @@ -570,9 +564,8 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)  	clk_disable_unprepare(msm_host->byte_clk);  } -static unsigned long dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bonded_dsi) +static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, bool is_bonded_dsi)  { -	struct drm_display_mode *mode = msm_host->mode;  	unsigned long pclk_rate;  	pclk_rate = mode->clock * 1000; @@ -589,11 +582,13 @@ static unsigned long dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bo  	return pclk_rate;  } -static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) +unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_dsi, +				    const struct drm_display_mode *mode)  { +	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);  	u8 lanes = msm_host->lanes;  	u32 bpp = dsi_get_bpp(msm_host->format); -	unsigned long pclk_rate = dsi_get_pclk_rate(msm_host, is_bonded_dsi); +	unsigned long pclk_rate = dsi_get_pclk_rate(mode, is_bonded_dsi);  	u64 pclk_bpp = (u64)pclk_rate * bpp;  	if (lanes == 0) { @@ -607,8 +602,14 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)  	else  		do_div(pclk_bpp, (8 * lanes)); -	msm_host->pixel_clk_rate = pclk_rate; -	msm_host->byte_clk_rate = pclk_bpp; +	return pclk_bpp; +} + +static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) +{ +	msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi); +	msm_host->byte_clk_rate = dsi_byte_clk_get_rate(&msm_host->base, is_bonded_dsi, +							msm_host->mode);  	DBG("pclk=%lu, bclk=%lu", msm_host->pixel_clk_rate,  				msm_host->byte_clk_rate); @@ -636,7 +637,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi)  	dsi_calc_pclk(msm_host, is_bonded_dsi); -	pclk_bpp = (u64)dsi_get_pclk_rate(msm_host, is_bonded_dsi) * bpp; +	pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi) * bpp;  	do_div(pclk_bpp, 8);  	msm_host->src_clk_rate = pclk_bpp; @@ -853,11 +854,12 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod  	 */  	slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width); -	/* If slice_per_pkt is greater than slice_per_intf +	/* +	 * If slice_count is greater than slice_per_intf  	 * then default to 1. This can happen during partial  	 * update.  	 */ -	if (slice_per_intf > dsc->slice_count) +	if (dsc->slice_count > slice_per_intf)  		dsc->slice_count = 1;  	total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf; @@ -987,7 +989,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)  		if (!msm_host->dsc)  			wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;  		else -			wc = mode->hdisplay / 2 + 1; +			wc = msm_host->dsc->slice_chunk_size * msm_host->dsc->slice_count + 1;  		dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,  			DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) | @@ -1883,8 +1885,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)  	msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL);  	if (!msm_host) { -		ret = -ENOMEM; -		goto fail; +		return -ENOMEM;  	}  	msm_host->pdev = pdev; @@ -1893,31 +1894,28 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)  	ret = dsi_host_parse_dt(msm_host);  	if (ret) {  		pr_err("%s: failed to parse dt\n", __func__); -		goto fail; +		return ret;  	}  	msm_host->ctrl_base = msm_ioremap_size(pdev, "dsi_ctrl", &msm_host->ctrl_size);  	if (IS_ERR(msm_host->ctrl_base)) {  		pr_err("%s: unable to map Dsi ctrl base\n", __func__); -		ret = PTR_ERR(msm_host->ctrl_base); -		goto fail; +		return PTR_ERR(msm_host->ctrl_base);  	}  	pm_runtime_enable(&pdev->dev);  	msm_host->cfg_hnd = dsi_get_config(msm_host);  	if (!msm_host->cfg_hnd) { -		ret = -EINVAL;  		pr_err("%s: get config failed\n", __func__); -		goto fail; +		return -EINVAL;  	}  	cfg = msm_host->cfg_hnd->cfg;  	msm_host->id = dsi_host_get_id(msm_host);  	if (msm_host->id < 0) { -		ret = msm_host->id;  		pr_err("%s: unable to identify DSI host index\n", __func__); -		goto fail; +		return msm_host->id;  	}  	/* fixup base address by io offset */ @@ -1927,19 +1925,18 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)  					    cfg->regulator_data,  					    &msm_host->supplies);  	if (ret) -		goto fail; +		return ret;  	ret = dsi_clk_init(msm_host);  	if (ret) {  		pr_err("%s: unable to initialize dsi clks\n", __func__); -		goto fail; +		return ret;  	}  	msm_host->rx_buf = devm_kzalloc(&pdev->dev, SZ_4K, GFP_KERNEL);  	if (!msm_host->rx_buf) { -		ret = -ENOMEM;  		pr_err("%s: alloc rx temp buf failed\n", __func__); -		goto fail; +		return -ENOMEM;  	}  	ret = devm_pm_opp_set_clkname(&pdev->dev, "byte"); @@ -1977,15 +1974,15 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)  	/* setup workqueue */  	msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0); +	if (!msm_host->workqueue) +		return -ENOMEM; +  	INIT_WORK(&msm_host->err_work, dsi_err_worker);  	msm_dsi->id = msm_host->id;  	DBG("Dsi Host %d initialized", msm_host->id);  	return 0; - -fail: -	return ret;  }  void msm_dsi_host_destroy(struct mipi_dsi_host *host) @@ -2391,6 +2388,10 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,  		goto unlock_ret;  	} +	msm_host->byte_intf_clk_rate = msm_host->byte_clk_rate; +	if (phy_shared_timings->byte_intf_clk_div_2) +		msm_host->byte_intf_clk_rate /= 2; +  	msm_dsi_sfpb_config(msm_host, true);  	ret = regulator_bulk_enable(msm_host->cfg_hnd->cfg->num_regulators,  |