drm/msm/dsi: Enable widebus for DSI
authorJessica Zhang <quic_jesszhan@quicinc.com>
Tue, 22 Aug 2023 17:42:07 +0000 (10:42 -0700)
committerDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Mon, 9 Oct 2023 09:17:46 +0000 (12:17 +0300)
DSI 6G v2.5.x+ supports a data-bus widen mode that allows DSI to send
48 bits of compressed data instead of 24.

Enable this mode whenever DSC is enabled for supported chipsets.

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/553762/
Link: https://lore.kernel.org/r/20230822-add-widebus-support-v4-4-9dc86083d6ea@quicinc.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
drivers/gpu/drm/msm/dsi/dsi.c
drivers/gpu/drm/msm/dsi/dsi.h
drivers/gpu/drm/msm/dsi/dsi_host.c

index 4cf424b3509f4a6a0b01b8af46b66b59540a1738..a35e15e3798960c322f4842fd98395115f02fcce 100644 (file)
@@ -19,7 +19,7 @@ struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
 
 bool msm_dsi_wide_bus_enabled(struct msm_dsi *msm_dsi)
 {
-       return false;
+       return msm_dsi_host_is_wide_bus_enabled(msm_dsi->host);
 }
 
 static int dsi_get_phy(struct msm_dsi *msm_dsi)
index bd3763a5d72340cd2c82d42f177cc02f35061ac0..d21867da78b8bae6a524732044961f7f6d3bf291 100644 (file)
@@ -134,6 +134,7 @@ int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
 void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct mipi_dsi_host *host);
 void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host);
 struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host);
+bool msm_dsi_host_is_wide_bus_enabled(struct mipi_dsi_host *host);
 
 /* dsi phy */
 struct msm_dsi_phy;
index 3d6fb708dc223e55d1d8cc8bb943285014fee98e..fd2201cb62db1fd9ceb1f8c352adf9e71600c81d 100644 (file)
@@ -710,6 +710,15 @@ static void dsi_ctrl_disable(struct msm_dsi_host *msm_host)
        dsi_write(msm_host, REG_DSI_CTRL, 0);
 }
 
+bool msm_dsi_host_is_wide_bus_enabled(struct mipi_dsi_host *host)
+{
+       struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+       return msm_host->dsc &&
+               (msm_host->cfg_hnd->major == MSM_DSI_VER_MAJOR_6G &&
+                msm_host->cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V2_5_0);
+}
+
 static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
                        struct msm_dsi_phy_shared_timings *phy_shared_timings, struct msm_dsi_phy *phy)
 {
@@ -753,10 +762,16 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
                data |= DSI_CMD_CFG1_INSERT_DCS_COMMAND;
                dsi_write(msm_host, REG_DSI_CMD_CFG1, data);
 
-               if (msm_host->cfg_hnd->major == MSM_DSI_VER_MAJOR_6G &&
-                   msm_host->cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3) {
+               if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
                        data = dsi_read(msm_host, REG_DSI_CMD_MODE_MDP_CTRL2);
-                       data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE;
+
+                       if (cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3)
+                               data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE;
+
+                       /* TODO: Allow for video-mode support once tested/fixed */
+                       if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
+                               data |= DSI_CMD_MODE_MDP_CTRL2_DATABUS_WIDEN;
+
                        dsi_write(msm_host, REG_DSI_CMD_MODE_MDP_CTRL2, data);
                }
        }
@@ -894,6 +909,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
        u32 hdisplay = mode->hdisplay;
        u32 wc;
        int ret;
+       bool wide_bus_enabled = msm_dsi_host_is_wide_bus_enabled(&msm_host->base);
 
        DBG("");
 
@@ -914,6 +930,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
 
        if (msm_host->dsc) {
                struct drm_dsc_config *dsc = msm_host->dsc;
+               u32 bytes_per_pclk;
 
                /* update dsc params with timing params */
                if (!dsc || !mode->hdisplay || !mode->vdisplay) {
@@ -937,7 +954,13 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
                 * pulse width same
                 */
                h_total -= hdisplay;
-               hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3);
+               if (wide_bus_enabled && !(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO))
+                       bytes_per_pclk = 6;
+               else
+                       bytes_per_pclk = 3;
+
+               hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), bytes_per_pclk);
+
                h_total += hdisplay;
                ha_end = ha_start + hdisplay;
        }