summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/dsi/dsi_host.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi_host.c')
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c69
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,