[PATCH] drm/i915/dsi: Fix command mode line time calculation
Jinman Ma <[email protected]>
| Newsgroups | gmane.linux.kernel,gmane.comp.freedesktop.xorg.drivers.intel,gmane.comp.video.dri.devel |
|---|---|
| Message-ID | <[email protected]> |
The command mode path in gen11_dsi_set_transcoder_timings() first truncates the AFE clock period to an integer number of nanoseconds, and then truncates the resulting line time to microseconds. At high link rates, 1000000 / afe_clk() can evaluate to zero. Even at lower rates, the successive integer divisions can make line_time_us zero. DIV_ROUND_UP(400, line_time_us) then triggers a divide error during the atomic commit and prevents i915 KMS from initializing. Calculate the line time directly in nanoseconds using 64-bit arithmetic. Use bits per pixel with the per-lane AFE bit clock and retain nanosecond precision until calculating how many lines are needed for 400 microseconds. Tested on a Huawei MateBook E with an Alder Lake-P GPU and a 2560x1600 dual-link DSI panel. The change prevents the divide error and allows KMS to reach the display manager. Signed-off-by: Jinman Ma <[email protected]> --- This does not completely fix the panel. After entering Plasma, the image still shows visible tearing or jitter, sometimes with an obvious offset between the two halves of the dual-link panel. Switching to a text console can also leave the panel black. I am continuing to investigate this as a separate timing or synchronization issue. Please let me know which additional i915 debug logs or register dumps would be most useful for the remaining issue. I'm pleasured to collect them. --- drivers/gpu/drm/i915/display/icl_dsi.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index ea0cdb782..c89e24de7 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -917,16 +917,19 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, if (is_vid_mode(intel_dsi)) { vtotal = adjusted_mode->crtc_vtotal; } else { - int bpp, line_time_us, byte_clk_period_ns; + u64 line_time_ns; + int bpp; if (crtc_state->dsc.compression_enable) bpp = fxp_q4_to_int(crtc_state->dsc.compressed_bpp_x16); else bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); - byte_clk_period_ns = 1000000 / afe_clk(encoder, crtc_state); - line_time_us = (htotal * (bpp / 8) * byte_clk_period_ns) / (1000 * intel_dsi->lane_count); - vtotal = vactive + DIV_ROUND_UP(400, line_time_us); + line_time_ns = DIV_ROUND_UP_ULL((u64)htotal * bpp * 1000000, + afe_clk(encoder, crtc_state) * + intel_dsi->lane_count); + vtotal = vactive + + DIV_ROUND_UP_ULL(400 * 1000, line_time_ns); } vsync_start = adjusted_mode->crtc_vsync_start; vsync_end = adjusted_mode->crtc_vsync_end; -- 2.55.0