From: Yu Zhang <[email protected]>
The TRANS_HSYNC register programming and dual-link hsync halving is
placed inside the is_vid_mode() guard, so it only runs for video mode.
Command mode dual-link DSI also needs this:
1. Without TRANS_HSYNC written, the hardware retains an inconsistent
state, leading to errors on modeset:
[drm] *ERROR* mismatch in hw.pipe_mode.crtc_hsync_start
(expected 2762, found 1380)
2. The hsync_start/end are not halved for each link, so the hardware
stores per-link values while the software expects full values.
Fix this by moving the dual-link hsync halving and TRANS_HSYNC write
outside the is_vid_mode() guard, making them unconditional for all
DSI modes.
Fixes: d1aeb5f399d9 ("drm/i915/icl: Configure DSI transcoder timings")
Cc: [email protected]
Signed-off-by: Yu Zhang <[email protected]>
---
drivers/gpu/drm/i915/display/icl_dsi.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c
b/drivers/gpu/drm/i915/display/icl_dsi.c
index 951f30a64..c667d5941 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -950,7 +950,6 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder
*encoder,
HACTIVE(hactive - 1) | HTOTAL(htotal - 1));
}
- /* TRANS_HSYNC register to be programmed only for video mode */
if (is_vid_mode(intel_dsi)) {
if (intel_dsi->video_mode == NON_BURST_SYNC_PULSE) {
/* BSPEC: hsync size should be atleast 16 pixels */
@@ -961,18 +960,18 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder
*encoder,
if (hback_porch < 16)
drm_err(display->drm, "hback porch < 16 pixels\n");
+ }
- if (intel_dsi->dual_link) {
- hsync_start /= 2;
- hsync_end /= 2;
- }
+ if (intel_dsi->dual_link) {
+ hsync_start /= 2;
+ hsync_end /= 2;
+ }
- for_each_dsi_port(port, intel_dsi->ports) {
- dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(display,
- TRANS_HSYNC(display, dsi_trans),
- HSYNC_START(hsync_start - 1) |
HSYNC_END(hsync_end - 1));
- }
+ for_each_dsi_port(port, intel_dsi->ports) {
+ dsi_trans = dsi_port_to_transcoder(port);
+ intel_de_write(display,
+ TRANS_HSYNC(display, dsi_trans),
+ HSYNC_START(hsync_start - 1) |
HSYNC_END(hsync_end - 1));
}
/* program TRANS_VTOTAL register */
--
2.43.0