From: Tomi Valkeinen <[email protected]>

[ Upstream commit 478306edc23eec4f0ec24a46222485910c66212d ]

Use the crtc_* fields from drm_display_mode, instead of the "logical"
fields. This shouldn't change anything in practice, but afaiu the crtc_*
fields are the correct ones to use here.

Reviewed-by: Aradhya Bhatia <[email protected]>
Tested-by: Parth Pancholi <[email protected]>
Tested-by: Jayesh Choudhary <[email protected]>
Reviewed-by: Devarsh Thakkar <[email protected]>
Link: 
https://lore.kernel.org/r/[email protected]
Signed-off-by: Tomi Valkeinen <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---

LLM Generated explanations, may be completely bogus:

YES

Explanation

What changed
- drivers/gpu/drm/tidss/tidss_crtc.c:227 switches the pixel clock
  programmed into the VP from `mode->clock * 1000` to `mode->crtc_clock
  * 1000`. This ensures the CRTC gets the adjusted pixel rate after
  encoder/bridge modifications.
- drivers/gpu/drm/tidss/tidss_dispc.c updates all timing and size
  programming to use `crtc_*` fields instead of the “logical” ones:
  - Horizontal timings: `hfp/hsw/hbp` now computed from
    `crtc_hsync_start/crtc_hsync_end/crtc_hdisplay/crtc_htotal`.
  - Vertical timings: `vfp/vsw/vbp` now computed from
    `crtc_vsync_start/crtc_vsync_end/crtc_vdisplay/crtc_vtotal`.
  - Screen size register uses `crtc_hdisplay` and `crtc_vdisplay`.
  - The register writes affected include DISPC_VP_TIMING_H,
    DISPC_VP_TIMING_V, and DISPC_VP_SIZE_SCREEN.

Why it matters
- In DRM, the `crtc_*` fields represent the timings and pixel rate that
  the CRTC must actually program, after any adjustments by
  encoders/bridges (e.g., DSI DPI conversions, double-clocking, pixel
  repetition, burst modes).
- Using the non-crtc (“logical”) mode values can mismatch the VP’s clock
  and timing registers with the bridge’s expectations, causing real
  failures: sync lost, blank display, or unstable output. TIDSS
  explicitly handles sync-lost conditions elsewhere; wrong pixel
  clock/timings are a common source of such issues.
- The change aligns TIDSS with widespread practice across DRM drivers
  and with cadence DSI programming, which already relies on `crtc_*` for
  the DPI-to-DSI path. This improves correctness when using TIDSS with
  DSI/LVDS bridges that adjust the mode.

Backport suitability
- Bugfix: Corrects which mode members are used to program the hardware
  (functional correctness for any pipeline that adjusts the CRTC mode).
  It can solve user-visible issues (no display/sync lost) in such
  configurations.
- Small and contained: The diff is narrowly scoped to TIDSS VP clock and
  timing programming; no architectural changes.
- Low risk: Pure field substitution to the correct `crtc_*` members;
  widely used pattern in other DRM drivers. No API changes or cross-
  subsystem impact.
- No feature additions: Behavior remains the same for pipelines where
  `crtc_*` equals logical fields; improves only cases where they differ.
- Stable policy fit: Important correctness fix with minimal regression
  risk in a confined subsystem, and it does not touch core kernel or
  unrelated code.

Notes
- Mode validation in TIDSS still checks the logical mode; while that’s
  unchanged here, this patch alone is safe and beneficial. If needed,
  further adjustments to validate the effective CRTC requirements can be
  considered separately.

 drivers/gpu/drm/tidss/tidss_crtc.c  |  2 +-
 drivers/gpu/drm/tidss/tidss_dispc.c | 16 ++++++++--------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c 
b/drivers/gpu/drm/tidss/tidss_crtc.c
index a2f40a5c77030..17efd77ce7f23 100644
--- a/drivers/gpu/drm/tidss/tidss_crtc.c
+++ b/drivers/gpu/drm/tidss/tidss_crtc.c
@@ -225,7 +225,7 @@ static void tidss_crtc_atomic_enable(struct drm_crtc *crtc,
        tidss_runtime_get(tidss);
 
        r = dispc_vp_set_clk_rate(tidss->dispc, tcrtc->hw_videoport,
-                                 mode->clock * 1000);
+                                 mode->crtc_clock * 1000);
        if (r != 0)
                return;
 
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c 
b/drivers/gpu/drm/tidss/tidss_dispc.c
index c0277fa36425e..3f6cff2ab1b29 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -1215,13 +1215,13 @@ void dispc_vp_enable(struct dispc_device *dispc, u32 
hw_videoport,
 
        dispc_set_num_datalines(dispc, hw_videoport, fmt->data_width);
 
-       hfp = mode->hsync_start - mode->hdisplay;
-       hsw = mode->hsync_end - mode->hsync_start;
-       hbp = mode->htotal - mode->hsync_end;
+       hfp = mode->crtc_hsync_start - mode->crtc_hdisplay;
+       hsw = mode->crtc_hsync_end - mode->crtc_hsync_start;
+       hbp = mode->crtc_htotal - mode->crtc_hsync_end;
 
-       vfp = mode->vsync_start - mode->vdisplay;
-       vsw = mode->vsync_end - mode->vsync_start;
-       vbp = mode->vtotal - mode->vsync_end;
+       vfp = mode->crtc_vsync_start - mode->crtc_vdisplay;
+       vsw = mode->crtc_vsync_end - mode->crtc_vsync_start;
+       vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
 
        dispc_vp_write(dispc, hw_videoport, DISPC_VP_TIMING_H,
                       FLD_VAL(hsw - 1, 7, 0) |
@@ -1263,8 +1263,8 @@ void dispc_vp_enable(struct dispc_device *dispc, u32 
hw_videoport,
                       FLD_VAL(ivs, 12, 12));
 
        dispc_vp_write(dispc, hw_videoport, DISPC_VP_SIZE_SCREEN,
-                      FLD_VAL(mode->hdisplay - 1, 11, 0) |
-                      FLD_VAL(mode->vdisplay - 1, 27, 16));
+                      FLD_VAL(mode->crtc_hdisplay - 1, 11, 0) |
+                      FLD_VAL(mode->crtc_vdisplay - 1, 27, 16));
 
        VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 1, 0, 0);
 }
-- 
2.51.0

Reply via email to