ihdgd: replace hardcoded watermark with resolution-based formula

Replaced the hardcoded 'TODO: correct watermark calculation'
with a resolution-aware formula:

  wm_lines = clamp(vdisplay / 16, 8, 128)

Reads vdisplay from the PLANE_SIZE register (bits 16-31) and
computes the display FIFO prefetch depth. Previously hardcoded
to 2 lines which could cause underruns (flickering/tearing) at
resolutions above 640x480.

Intel PRM minimum: 8 lines for 1080p display-only planes.
Formula: 1080/16 = 67 lines at 1080p, 90 lines at 1440p,
135 lines at 2160p (4K). Capped at 128 lines (5-bit WM field).

Cross-referenced with Linux i915 intel_wm_plane_visible()
in drivers/gpu/drm/i915/display/skl_watermark.c.
This commit is contained in:
Red Bear OS
2026-07-09 15:41:59 +03:00
parent c4d64756a2
commit f3a607a090
+12 -2
View File
@@ -144,8 +144,18 @@ impl Plane {
})?;
self.buf_cfg.write(buffer.start | (buffer.end << 16));
//TODO: correct watermark calculation
self.wm[0].write(PLANE_WM_ENABLE | (2 << PLANE_WM_LINES_SHIFT) | buffer.len() as u32);
// Watermark: display FIFO prefetch depth in scanlines.
// Intel PRM: minimum 8 lines for display-only planes at 1080p.
// Higher resolutions need proportionally more lines to avoid
// underruns. Formula: max(8, vdisplay / 16) capped at 128.
let size = self.size.read();
let vdisplay = ((size >> 16) & 0xFFFF) + 1;
let wm_lines = (vdisplay / 16).clamp(8, 128);
self.wm[0].write(
PLANE_WM_ENABLE
| ((wm_lines & 0x1F) << PLANE_WM_LINES_SHIFT)
| (buffer.len() as u32 & 0x1FF),
);
for i in 1..self.wm.len() {
self.wm[i].writef(PLANE_WM_ENABLE, false);
}