[PATCH v2] [PATCH v2] drm/i915/dsi: Fix command mode line time calculation
Jinman Ma <[email protected]> Mon, 3 Aug 2026 23:42:21 +0800
| Newsgroups | org.freedesktop.lists.dri-devel,org.freedesktop.lists.intel-gfx,org.freedesktop.lists.intel-xe,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Thank you for the review. I verified both reported issues and addressed them in v2. For dual-link DSI configurations, intel_dsi->pclk and afe_clk() describe the per-link bandwidth, while the previous calculation used the full horizontal total. This made the calculated line time twice the actual per-link line time and provided only about half of the required 400 us vertical blanking interval. v2 now calculates the line time using a per-link horizontal total by dividing htotal by two for dual-link configurations. The second DIV_ROUND_UP_ULL() call also used line_time_ns, a u64 value, as its divisor. This does not match the macro's u32 divisor contract. v2 replaces it with DIV64_U64_ROUND_UP(), which supports a 64-bit numerator and divisor. The changes were tested on a Huawei MateBook E with a Tiger Lake GPU and a 2560x1600 RGB888 dual-link front-back command-mode DSI panel. Before v2, the driver programmed a vtotal below vsync_end and reported: i915 0000:00:02.0: [drm] *ERROR* Invalid vsync_end value i915 0000:00:02.0: [drm] *ERROR* [CRTC:171:pipe A] mismatch in hw.pipe_mode.crtc_vtotal (expected 1710, found 1622) With v2, the per-link line time is approximately 8.18 us. The driver requests 49 blanking lines, providing approximately 400.9 us of vertical blanking and programming vtotal to 1649. After a clean build and boot: - vtotal is programmed to 1649 - Invalid vsync_end is no longer reported - no divide error or kernel Oops occurs - no FIFO underrun, GPU hang, or atomic update failure is reported - the DSI connector and display pipe initialize successfully The existing modeset verification differences between the mode timings and command-mode transcoder timings remain unchanged and are outside the scope of this patch. Signed-off-by: Jinman Ma <[email protected]> --- Changes in v2: - Use the per-link htotal when calculating dual-link DSI line time. - Use DIV64_U64_ROUND_UP() when dividing by the u64 line_time_ns. - Preserve the existing bpp selection for compressed and uncompressed configurations. Testing notes: The corrected dual-link calculation removes the Invalid vsync_end error and provides the required 400 us vertical blanking interval. A slight intermittent display jitter is still visible, so the dual-link line-time error was not the sole cause of the previously reported jitter. TTY switching and suspend/resume can also leave the internal panel blank. These appear to involve separate fbcon and DSI command-mode resume paths and are not addressed by this patch. They will be reported and investigated separately. drivers/gpu/drm/i915/display/icl_dsi.c | 16 ++++++++++++---- 1 file changed, 12 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..0f942cc6e 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -917,16 +917,24 @@ 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; + int bpp; + u64 line_time_ns; + u16 link_htotal = htotal; + + if (intel_dsi->dual_link) + link_htotal /= 2; 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); + line_time_ns = + DIV_ROUND_UP_ULL((u64)link_htotal * bpp * 1000000, + afe_clk(encoder, crtc_state) * + intel_dsi->lane_count); - 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); + vtotal = vactive + + DIV64_U64_ROUND_UP(400000ULL, line_time_ns); } vsync_start = adjusted_mode->crtc_vsync_start; vsync_end = adjusted_mode->crtc_vsync_end; -- 2.55.0