mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
drm/msm/dp: fix link bandwidth check when wide bus is enabled
msm_dp_display_mode_valid() halves the pixel clock when either YUV420 or
wide bus is in use, then uses that halved value both for the controller
pixel clock limit and for the DP link bandwidth check.
Only YUV420 halves the data crossing the link. Wide bus widens the
internal DPU to DP interface to two pixels per clock, halving the
controller clock. Every pixel is still transmitted, so the link
bandwidth requirement remains.
As a result, modes needing up to twice the available link bandwidth pass
validation. On the IMDT QCS8550 SBC (rev5 with CYPD6125), where DP runs
over USB-C alt mode where only two lanes are available, 3840x2160@60 was
accepted despite needing 9.6 Gbps against the 8.64 Gbps the link can
carry.
Use a separate link pixel clock that is only halved for YUV420 for the
bandwidth calculation, leaving the wide bus halving to apply solely to
the controller pixel clock limit. With this, 4k@60 is correctly rejected
and 4k@30 selected instead.
Fixes: df9cf852ca ("drm/msm/dp: account for widebus and yuv420 during mode validation")
Assisted-by: Claude:claude-opus-5
Signed-off-by: William Bright <william.bright@imd-tec.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/746145/
Link: https://lore.kernel.org/r/20260812-msm-dp-link-bw-v1-1-b0e3ce1190be@imd-tec.com
[DB: dropped useless comment]
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
This commit is contained in:
parent
6fbbf1e152
commit
58995b11df
|
|
@ -756,6 +756,7 @@ enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
|
|||
struct msm_dp_link_info *link_info;
|
||||
u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
|
||||
int mode_pclk_khz = mode->clock;
|
||||
int link_pclk_khz;
|
||||
bool is_yuv_420;
|
||||
|
||||
if (!dp || !mode_pclk_khz || !dp->connector) {
|
||||
|
|
@ -775,6 +776,8 @@ enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
|
|||
if (is_yuv_420 && !msm_dp_display->panel->vsc_sdp_supported)
|
||||
return MODE_NO_420;
|
||||
|
||||
link_pclk_khz = is_yuv_420 ? mode_pclk_khz / 2 : mode_pclk_khz;
|
||||
|
||||
if (is_yuv_420 || msm_dp_display->wide_bus_supported)
|
||||
mode_pclk_khz /= 2;
|
||||
|
||||
|
|
@ -786,9 +789,9 @@ enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
|
|||
mode_bpp = default_bpp;
|
||||
|
||||
mode_bpp = msm_dp_panel_get_mode_bpp(msm_dp_display->panel,
|
||||
mode_bpp, mode_pclk_khz);
|
||||
mode_bpp, link_pclk_khz);
|
||||
|
||||
mode_rate_khz = mode_pclk_khz * mode_bpp;
|
||||
mode_rate_khz = link_pclk_khz * mode_bpp;
|
||||
supported_rate_khz = link_info->num_lanes * link_info->rate * 8;
|
||||
|
||||
if (mode_rate_khz > supported_rate_khz)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user