Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/msm/dsi: Use existing per-interface slice count in DSC timing

When configuring the timing of DSI hosts (interfaces) in
dsi_timing_setup() all values written to registers are taking
bonded-mode into account by dividing the original mode width by 2
(half the data is sent over each of the two DSI hosts), but the full
width instead of the interface width is passed as hdisplay parameter to
dsi_update_dsc_timing().

Currently only msm_dsc_get_slices_per_intf() is called within
dsi_update_dsc_timing() with the `hdisplay` argument which clearly
documents that it wants the width of a single interface (which, again,
in bonded DSI mode is half the total width of the mode) resulting in all
subsequent values to be completely off.

However, as soon as we start to pass the halved hdisplay
into dsi_update_dsc_timing() we might as well discard
msm_dsc_get_slices_per_intf() since the value it calculates is already
available in dsc->slice_count which is per-interface by the current
design of MSM DPU/DSI implementations and their use of the DRM DSC
helpers.

Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration")
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com>
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Patchwork: https://patchwork.freedesktop.org/patch/637648/
Link: https://lore.kernel.org/r/20250217-drm-msm-initial-dualpipe-dsc-fixes-v3-1-913100d6103f@somainline.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

authored by

Marijn Suijten and committed by
Dmitry Baryshkov
14ad809c b39e7014

+4 -15
+4 -4
drivers/gpu/drm/msm/dsi/dsi_host.c
··· 834 834 dsi_write(msm_host, REG_DSI_CPHY_MODE_CTRL, BIT(0)); 835 835 } 836 836 837 - static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mode, u32 hdisplay) 837 + static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mode) 838 838 { 839 839 struct drm_dsc_config *dsc = msm_host->dsc; 840 840 u32 reg, reg_ctrl, reg_ctrl2; ··· 846 846 /* first calculate dsc parameters and then program 847 847 * compress mode registers 848 848 */ 849 - slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay); 849 + slice_per_intf = dsc->slice_count; 850 850 851 851 total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf; 852 852 bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */ ··· 979 979 980 980 if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { 981 981 if (msm_host->dsc) 982 - dsi_update_dsc_timing(msm_host, false, mode->hdisplay); 982 + dsi_update_dsc_timing(msm_host, false); 983 983 984 984 dsi_write(msm_host, REG_DSI_ACTIVE_H, 985 985 DSI_ACTIVE_H_START(ha_start) | ··· 1000 1000 DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); 1001 1001 } else { /* command mode */ 1002 1002 if (msm_host->dsc) 1003 - dsi_update_dsc_timing(msm_host, true, mode->hdisplay); 1003 + dsi_update_dsc_timing(msm_host, true); 1004 1004 1005 1005 /* image data and 1 byte write_memory_start cmd */ 1006 1006 if (!msm_host->dsc)
-11
drivers/gpu/drm/msm/msm_dsc_helper.h
··· 13 13 #include <drm/display/drm_dsc_helper.h> 14 14 15 15 /** 16 - * msm_dsc_get_slices_per_intf() - calculate number of slices per interface 17 - * @dsc: Pointer to drm dsc config struct 18 - * @intf_width: interface width in pixels 19 - * Returns: Integer representing the number of slices for the given interface 20 - */ 21 - static inline u32 msm_dsc_get_slices_per_intf(const struct drm_dsc_config *dsc, u32 intf_width) 22 - { 23 - return DIV_ROUND_UP(intf_width, dsc->slice_width); 24 - } 25 - 26 - /** 27 16 * msm_dsc_get_bytes_per_line() - calculate bytes per line 28 17 * @dsc: Pointer to drm dsc config struct 29 18 * Returns: Integer value representing bytes per line. DSI and DP need