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, |