[PATCH i-g-t v1 1/2] lib/igt_kms: Add platform-specific joiner exception mode handling
Sowmiya S <[email protected]> Thu, 23 Jul 2026 19:13:53 +0530
| Newsgroups | org.freedesktop.lists.igt-dev |
|---|---|
| Message-ID | <[email protected]> |
On NVL (display_ver=35), a higher max_dotclock causes modes like 6144x3456@60 to pass the standard igt_bigjoiner_possible() checks, yet the kernel still enables joiner for them. Introduce per-platform exception mode lists (e.g. nvl_joiner_exception_modes[]) dispatched via IS_NOVALAKE() in a new mode_needs_joiner_exception() helper, and wire it into igt_bigjoiner_possible(). Also add IS_NOVALAKE() to intel_chipset.h as a combined IS_NOVALAKE_S() || IS_NOVALAKE_P() macro. Signed-off-by: Sowmiya S <[email protected]> --- lib/igt_kms.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 2eefb773b..bfa6dfc0e 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -7058,6 +7058,52 @@ int intel_get_max_pipe_hdisplay(int drm_fd) HDISPLAY_5K_PER_PIPE; } +struct joiner_mode_exception { + uint16_t hdisplay, vdisplay; + uint32_t clock; +}; + +static bool match_joiner_exception(drmModeModeInfo *mode, + const struct joiner_mode_exception *list, + int count) +{ + for (int i = 0; i < count; i++) { + if (mode->hdisplay == list[i].hdisplay && + mode->vdisplay == list[i].vdisplay && + mode->clock == list[i].clock) + return true; + } + + return false; +} + +/* NVL: higher max_dotclock allows clocks that still need joiner */ +static const struct joiner_mode_exception nvl_joiner_exception_modes[] = { + { 6144, 3456, 1413390 }, /* 6144x3456@60Hz */ +}; + +/* + * mode_needs_joiner_exception - check if a mode requires joiner via explicit exception + * @drm_fd: drm file descriptor + * @mode: libdrm mode + * + * On some platforms, a higher max_dotclock means certain modes won't trigger + * the standard clock or hdisplay checks even though the kernel enables joiner + * for them. Each platform has its own exception list. + * + * Returns: True if the mode is a known joiner exception, else False. + */ +static bool mode_needs_joiner_exception(int drm_fd, drmModeModeInfo *mode) +{ + uint16_t dev_id = intel_get_drm_devid(drm_fd); + + if (IS_NOVALAKE_P(dev_id) || IS_NOVALAKE_S(dev_id)) + return match_joiner_exception(mode, nvl_joiner_exception_modes, + ARRAY_SIZE(nvl_joiner_exception_modes)); + + return false; +} + /** * igt_bigjoiner_possible: * @drm_fd: drm file descriptor @@ -7066,13 +7112,15 @@ int intel_get_max_pipe_hdisplay(int drm_fd) * * Bigjoiner is required when the requested mode exceeds single-pipe * platform limits, i.e. hdisplay is above the platform threshold or - * clock is above @max_dotclock. + * clock is above @max_dotclock. On NVL, the higher max_dotclock means + * some modes (e.g. 6144x3456@60) need an explicit exception check. * * Returns: True if mode requires Bigjoiner, else False. */ bool igt_bigjoiner_possible(int drm_fd, drmModeModeInfo *mode, int max_dotclock) { - return (mode->hdisplay > intel_get_max_pipe_hdisplay(drm_fd) || + return (mode_needs_joiner_exception(drm_fd, mode) || + mode->hdisplay > intel_get_max_pipe_hdisplay(drm_fd) || mode->clock > max_dotclock); } -- 2.43.0