From 47ad90921586dbe1f37dab3f4352df8e42d2fa30 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 19 Dec 2024 19:14:13 -0300 Subject: [PATCH 001/284] drm/i915/dmc_wl: Use enum values for enable_dmc_wl Currently, after sanitization, enable_dmc_wl will behave like a boolean parameter (enabled vs disabled). However, in upcoming changes, we will allow more values for debugging purposes. For that, let's make the sanitized value an enumeration. Signed-off-by: Gustavo Sousa Reviewed-by: Dnyaneshwar Bhadane Link: https://patchwork.freedesktop.org/patch/msgid/20241219221429.109668-2-gustavo.sousa@intel.com Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/display/intel_dmc_wl.c | 29 ++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 02de3ae150749..0850a7d866cc8 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -50,6 +50,15 @@ #define DMC_WAKELOCK_CTL_TIMEOUT_US 5000 #define DMC_WAKELOCK_HOLD_TIME 50 +/* + * Possible non-negative values for the enable_dmc_wl param. + */ +enum { + ENABLE_DMC_WL_DISABLED, + ENABLE_DMC_WL_ENABLED, + ENABLE_DMC_WL_MAX, +}; + struct intel_dmc_wl_range { u32 start; u32 end; @@ -270,12 +279,20 @@ static bool __intel_dmc_wl_supported(struct intel_display *display) static void intel_dmc_wl_sanitize_param(struct intel_display *display) { - if (!HAS_DMC_WAKELOCK(display)) - display->params.enable_dmc_wl = 0; - else if (display->params.enable_dmc_wl >= 0) - display->params.enable_dmc_wl = !!display->params.enable_dmc_wl; - else - display->params.enable_dmc_wl = DISPLAY_VER(display) >= 30; + if (!HAS_DMC_WAKELOCK(display)) { + display->params.enable_dmc_wl = ENABLE_DMC_WL_DISABLED; + } else if (display->params.enable_dmc_wl < 0) { + if (DISPLAY_VER(display) >= 30) + display->params.enable_dmc_wl = ENABLE_DMC_WL_ENABLED; + else + display->params.enable_dmc_wl = ENABLE_DMC_WL_DISABLED; + } else if (display->params.enable_dmc_wl >= ENABLE_DMC_WL_MAX) { + display->params.enable_dmc_wl = ENABLE_DMC_WL_ENABLED; + } + + drm_WARN_ON(display->drm, + display->params.enable_dmc_wl < 0 || + display->params.enable_dmc_wl >= ENABLE_DMC_WL_MAX); drm_dbg_kms(display->drm, "Sanitized enable_dmc_wl value: %d\n", display->params.enable_dmc_wl); From 81a1d1f5d275547f51849e14401264f0e8147bd8 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 19 Dec 2024 19:14:14 -0300 Subject: [PATCH 002/284] drm/i915/dmc_wl: Show description string for enable_dmc_wl We already provide the value resulting from sanitization of enable_dmc_wl in dmesg, however the reader will need to either have the meanings memorized or look them up in the parameter's documentation. Let's make things easier by providing a short human-readable name for the parameter in dmesg. Signed-off-by: Gustavo Sousa Reviewed-by: Dnyaneshwar Bhadane Link: https://patchwork.freedesktop.org/patch/msgid/20241219221429.109668-3-gustavo.sousa@intel.com Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/display/intel_dmc_wl.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 0850a7d866cc8..af07eaa3a8210 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -279,6 +279,8 @@ static bool __intel_dmc_wl_supported(struct intel_display *display) static void intel_dmc_wl_sanitize_param(struct intel_display *display) { + const char *desc; + if (!HAS_DMC_WAKELOCK(display)) { display->params.enable_dmc_wl = ENABLE_DMC_WL_DISABLED; } else if (display->params.enable_dmc_wl < 0) { @@ -294,8 +296,20 @@ static void intel_dmc_wl_sanitize_param(struct intel_display *display) display->params.enable_dmc_wl < 0 || display->params.enable_dmc_wl >= ENABLE_DMC_WL_MAX); - drm_dbg_kms(display->drm, "Sanitized enable_dmc_wl value: %d\n", - display->params.enable_dmc_wl); + switch (display->params.enable_dmc_wl) { + case ENABLE_DMC_WL_DISABLED: + desc = "disabled"; + break; + case ENABLE_DMC_WL_ENABLED: + desc = "enabled"; + break; + default: + desc = "unknown"; + break; + } + + drm_dbg_kms(display->drm, "Sanitized enable_dmc_wl value: %d (%s)\n", + display->params.enable_dmc_wl, desc); } void intel_dmc_wl_init(struct intel_display *display) From a56d1e380d7475c154c39b08a3793a73e015589f Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 19 Dec 2024 19:14:15 -0300 Subject: [PATCH 003/284] drm/i915/dmc_wl: Allow enable_dmc_wl=2 to mean "match any register" When debugging issues that might be related to the DMC wakelock code, it is sometimes useful to compare runs when we match any register offset vs the regular case. If issues disappear when we take the wakelock for any register, it might indicate that we are missing some offset to be tracked. Support matching any register offset with enable_dmc_wl=2. Signed-off-by: Gustavo Sousa Reviewed-by: Dnyaneshwar Bhadane Link: https://patchwork.freedesktop.org/patch/msgid/20241219221429.109668-4-gustavo.sousa@intel.com Signed-off-by: Matt Roper --- .../gpu/drm/i915/display/intel_display_params.c | 2 +- drivers/gpu/drm/i915/display/intel_dmc_wl.c | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_params.c b/drivers/gpu/drm/i915/display/intel_display_params.c index f92e4640a613c..f0f388f38fa7d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_params.c +++ b/drivers/gpu/drm/i915/display/intel_display_params.c @@ -130,7 +130,7 @@ intel_display_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400, intel_display_param_named_unsafe(enable_dmc_wl, int, 0400, "Enable DMC wakelock " - "(-1=use per-chip default, 0=disabled, 1=enabled) " + "(-1=use per-chip default, 0=disabled, 1=enabled, 2=match any register) " "Default: -1"); __maybe_unused diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index af07eaa3a8210..d442a150b3274 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -56,6 +56,7 @@ enum { ENABLE_DMC_WL_DISABLED, ENABLE_DMC_WL_ENABLED, + ENABLE_DMC_WL_ANY_REGISTER, ENABLE_DMC_WL_MAX, }; @@ -239,10 +240,15 @@ static bool intel_dmc_wl_reg_in_range(i915_reg_t reg, return false; } -static bool intel_dmc_wl_check_range(i915_reg_t reg, u32 dc_state) +static bool intel_dmc_wl_check_range(struct intel_display *display, + i915_reg_t reg, + u32 dc_state) { const struct intel_dmc_wl_range *ranges; + if (display->params.enable_dmc_wl == ENABLE_DMC_WL_ANY_REGISTER) + return true; + /* * Check that the offset is in one of the ranges for which * registers are powered off during DC states. @@ -303,6 +309,9 @@ static void intel_dmc_wl_sanitize_param(struct intel_display *display) case ENABLE_DMC_WL_ENABLED: desc = "enabled"; break; + case ENABLE_DMC_WL_ANY_REGISTER: + desc = "match any register"; + break; default: desc = "unknown"; break; @@ -429,7 +438,8 @@ void intel_dmc_wl_get(struct intel_display *display, i915_reg_t reg) spin_lock_irqsave(&wl->lock, flags); - if (i915_mmio_reg_valid(reg) && !intel_dmc_wl_check_range(reg, wl->dc_state)) + if (i915_mmio_reg_valid(reg) && + !intel_dmc_wl_check_range(display, reg, wl->dc_state)) goto out_unlock; if (!wl->enabled) { @@ -461,7 +471,8 @@ void intel_dmc_wl_put(struct intel_display *display, i915_reg_t reg) spin_lock_irqsave(&wl->lock, flags); - if (i915_mmio_reg_valid(reg) && !intel_dmc_wl_check_range(reg, wl->dc_state)) + if (i915_mmio_reg_valid(reg) && + !intel_dmc_wl_check_range(display, reg, wl->dc_state)) goto out_unlock; if (WARN_RATELIMIT(!refcount_read(&wl->refcount), From 34e47bdbad0353acaf1eeecea64ffa711061b65c Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 19 Dec 2024 19:14:16 -0300 Subject: [PATCH 004/284] drm/i915/dmc_wl: Allow enable_dmc_wl=3 to mean "always locked" When debugging issues that might be related to the DMC wakelock code, it might be useful to compare runs with the lock acquired while DC states are enabled vs the regular case. If issues disappear with the former, it might be a symptom of something wrong in our code. Support having this "always locked" behavior with enable_dmc_wl=3. Signed-off-by: Gustavo Sousa Reviewed-by: Dnyaneshwar Bhadane Link: https://patchwork.freedesktop.org/patch/msgid/20241219221429.109668-5-gustavo.sousa@intel.com Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/display/intel_display_params.c | 2 +- drivers/gpu/drm/i915/display/intel_dmc_wl.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_params.c b/drivers/gpu/drm/i915/display/intel_display_params.c index f0f388f38fa7d..c4f1ab43fc0c8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_params.c +++ b/drivers/gpu/drm/i915/display/intel_display_params.c @@ -130,7 +130,7 @@ intel_display_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400, intel_display_param_named_unsafe(enable_dmc_wl, int, 0400, "Enable DMC wakelock " - "(-1=use per-chip default, 0=disabled, 1=enabled, 2=match any register) " + "(-1=use per-chip default, 0=disabled, 1=enabled, 2=match any register, 3=always locked) " "Default: -1"); __maybe_unused diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index d442a150b3274..1bdc08e6aa452 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -57,6 +57,7 @@ enum { ENABLE_DMC_WL_DISABLED, ENABLE_DMC_WL_ENABLED, ENABLE_DMC_WL_ANY_REGISTER, + ENABLE_DMC_WL_ALWAYS_LOCKED, ENABLE_DMC_WL_MAX, }; @@ -312,6 +313,9 @@ static void intel_dmc_wl_sanitize_param(struct intel_display *display) case ENABLE_DMC_WL_ANY_REGISTER: desc = "match any register"; break; + case ENABLE_DMC_WL_ALWAYS_LOCKED: + desc = "always locked"; + break; default: desc = "unknown"; break; @@ -332,7 +336,8 @@ void intel_dmc_wl_init(struct intel_display *display) INIT_DELAYED_WORK(&wl->work, intel_dmc_wl_work); spin_lock_init(&wl->lock); - refcount_set(&wl->refcount, 0); + refcount_set(&wl->refcount, + display->params.enable_dmc_wl == ENABLE_DMC_WL_ALWAYS_LOCKED ? 1 : 0); } /* Must only be called as part of enabling dynamic DC states. */ From e995bb4adc728345d6c988efff36f4933e662703 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 7 Jan 2025 20:22:40 +0200 Subject: [PATCH 005/284] drm/i915/gvt: store virtual_dp_monitor_edid in rodata The virtual DP EDID isn't modified. Add const modifier to store it in rodata. Reviewed-by: Nemesa Garg Reviewed-by: Zhi Wang Link: https://patchwork.freedesktop.org/patch/msgid/20250107182240.1765311-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gvt/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index 95570cabdf276..c98dfcc3d0de5 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -97,7 +97,7 @@ int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe) return 0; } -static unsigned char virtual_dp_monitor_edid[GVT_EDID_NUM][EDID_SIZE] = { +static const unsigned char virtual_dp_monitor_edid[GVT_EDID_NUM][EDID_SIZE] = { { /* EDID with 1024x768 as its resolution */ /*Header*/ From 3566784817aeb1a733c95953998a29adc386d2ff Mon Sep 17 00:00:00 2001 From: Ravi Kumar Vodapalli Date: Thu, 9 Jan 2025 01:32:10 +0530 Subject: [PATCH 006/284] drm/i915/display: Update DBUF_TRACKER_STATE_SERVICE only on appropriate platforms The bspec only asks the driver to reprogram the DBUF_CTL's DBUF_TRACKER_STATE_SERVICE field to 0x8 on DG2 and platforms with display version 12. All other platforms should avoid reprogramming this register at driver init. Although we've been accidentally reprogramming DBUF_CTL on platforms where the spec does not ask us to, that mistake has been harmless so far because the value being programmed by the driver happened to match the hardware's default settings. So, update DBUF_TRACKER_STATE_SERVICE field to 0x8 only for 1. display version 12 2. DG2. Other platforms unless stated should use their default value. Bspec: 49213 Signed-off-by: Ravi Kumar Vodapalli Reviewed-by: Jonathan Cavitt Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20250108200210.1815229-1-ravi.kumar.vodapalli@intel.com [mattrope: Tweaked patch subject to accurately reflect content] Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/display/intel_display_power.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index d3b8453a1705f..8e86fcbcc189b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1126,9 +1126,6 @@ static void gen12_dbuf_slices_config(struct intel_display *display) { enum dbuf_slice slice; - if (display->platform.alderlake_p) - return; - for_each_dbuf_slice(display, slice) intel_de_rmw(display, DBUF_CTL_S(slice), DBUF_TRACKER_STATE_SERVICE_MASK, @@ -1681,7 +1678,7 @@ static void icl_display_core_init(struct intel_display *display, /* 4. Enable CDCLK. */ intel_cdclk_init_hw(display); - if (DISPLAY_VER(display) >= 12) + if (DISPLAY_VER(display) == 12 || display->platform.dg2) gen12_dbuf_slices_config(display); /* 5. Enable DBUF. */ From 3ac197e4d7ada579a1a8fed36f7f27eb1c231dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 19 Dec 2024 15:08:20 +0200 Subject: [PATCH 007/284] drm/i915/scaler: Extract skl_scaler_min_src_size() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SKL_MIN_*SRC_* defines just make things hard to read. Get rid of them and introduce an easy to read function in their place. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241219130827.22830-2-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/skl_scaler.c | 25 ++++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index ae21fce534dcf..8b5b7993a4928 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -76,9 +76,7 @@ static u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited) return ((phase >> 2) & PS_PHASE_MASK) | trip; } -#define SKL_MIN_SRC_W 8 #define SKL_MAX_SRC_W 4096 -#define SKL_MIN_SRC_H 8 #define SKL_MAX_SRC_H 4096 #define SKL_MIN_DST_W 8 #define SKL_MAX_DST_W 4096 @@ -96,8 +94,18 @@ static u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited) #define MTL_MAX_SRC_H 8192 #define MTL_MAX_DST_W 8192 #define MTL_MAX_DST_H 8192 -#define SKL_MIN_YUV_420_SRC_W 16 -#define SKL_MIN_YUV_420_SRC_H 16 + +static void skl_scaler_min_src_size(const struct drm_format_info *format, + u64 modifier, int *min_w, int *min_h) +{ + if (format && intel_format_info_is_yuv_semiplanar(format, modifier)) { + *min_w = 16; + *min_h = 16; + } else { + *min_w = 8; + *min_h = 8; + } +} static int skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, @@ -163,15 +171,8 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, return 0; } - if (format && intel_format_info_is_yuv_semiplanar(format, modifier) && - (src_h < SKL_MIN_YUV_420_SRC_H || src_w < SKL_MIN_YUV_420_SRC_W)) { - drm_dbg_kms(display->drm, - "Planar YUV: src dimensions not met\n"); - return -EINVAL; - } + skl_scaler_min_src_size(format, modifier, &min_src_w, &min_src_h); - min_src_w = SKL_MIN_SRC_W; - min_src_h = SKL_MIN_SRC_H; min_dst_w = SKL_MIN_DST_W; min_dst_h = SKL_MIN_DST_H; From 24c095f6958acebefabee4aad20ee5a98cfb46fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 19 Dec 2024 15:08:21 +0200 Subject: [PATCH 008/284] drm/i915/scaler: Extract skl_scaler_max_src_size() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SKL_MAX_SRC_* defines just make things hard to read. Get rid of them and introduce an easy to read function in their place. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241219130827.22830-3-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/skl_scaler.c | 37 +++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 8b5b7993a4928..d6bef65788674 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -76,22 +76,14 @@ static u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited) return ((phase >> 2) & PS_PHASE_MASK) | trip; } -#define SKL_MAX_SRC_W 4096 -#define SKL_MAX_SRC_H 4096 #define SKL_MIN_DST_W 8 #define SKL_MAX_DST_W 4096 #define SKL_MIN_DST_H 8 #define SKL_MAX_DST_H 4096 -#define ICL_MAX_SRC_W 5120 -#define ICL_MAX_SRC_H 4096 #define ICL_MAX_DST_W 5120 #define ICL_MAX_DST_H 4096 -#define TGL_MAX_SRC_W 5120 -#define TGL_MAX_SRC_H 8192 #define TGL_MAX_DST_W 8192 #define TGL_MAX_DST_H 8192 -#define MTL_MAX_SRC_W 4096 -#define MTL_MAX_SRC_H 8192 #define MTL_MAX_DST_W 8192 #define MTL_MAX_DST_H 8192 @@ -107,6 +99,26 @@ static void skl_scaler_min_src_size(const struct drm_format_info *format, } } +static void skl_scaler_max_src_size(struct intel_crtc *crtc, + int *max_w, int *max_h) +{ + struct intel_display *display = to_intel_display(crtc); + + if (DISPLAY_VER(display) >= 14) { + *max_w = 4096; + *max_h = 8192; + } else if (DISPLAY_VER(display) >= 12) { + *max_w = 5120; + *max_h = 8192; + } else if (DISPLAY_VER(display) == 11) { + *max_w = 5120; + *max_h = 4096; + } else { + *max_w = 4096; + *max_h = 4096; + } +} + static int skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, unsigned int scaler_user, int *scaler_id, @@ -172,28 +184,21 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, } skl_scaler_min_src_size(format, modifier, &min_src_w, &min_src_h); + skl_scaler_max_src_size(crtc, &max_src_w, &max_src_h); min_dst_w = SKL_MIN_DST_W; min_dst_h = SKL_MIN_DST_H; if (DISPLAY_VER(display) < 11) { - max_src_w = SKL_MAX_SRC_W; - max_src_h = SKL_MAX_SRC_H; max_dst_w = SKL_MAX_DST_W; max_dst_h = SKL_MAX_DST_H; } else if (DISPLAY_VER(display) < 12) { - max_src_w = ICL_MAX_SRC_W; - max_src_h = ICL_MAX_SRC_H; max_dst_w = ICL_MAX_DST_W; max_dst_h = ICL_MAX_DST_H; } else if (DISPLAY_VER(display) < 14) { - max_src_w = TGL_MAX_SRC_W; - max_src_h = TGL_MAX_SRC_H; max_dst_w = TGL_MAX_DST_W; max_dst_h = TGL_MAX_DST_H; } else { - max_src_w = MTL_MAX_SRC_W; - max_src_h = MTL_MAX_SRC_H; max_dst_w = MTL_MAX_DST_W; max_dst_h = MTL_MAX_DST_H; } From 9313b0bee09b6fdff4fb087090e57e44fcfd4ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 19 Dec 2024 15:08:22 +0200 Subject: [PATCH 009/284] drm/i915/scaler: Extract skl_scaler_min_dst_size() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SKL_MIN_DST_* defines just make things hard to read. Get rid of them and introduce an easy to read function in their place. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241219130827.22830-4-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/skl_scaler.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index d6bef65788674..cabbf4860cb38 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -76,9 +76,7 @@ static u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited) return ((phase >> 2) & PS_PHASE_MASK) | trip; } -#define SKL_MIN_DST_W 8 #define SKL_MAX_DST_W 4096 -#define SKL_MIN_DST_H 8 #define SKL_MAX_DST_H 4096 #define ICL_MAX_DST_W 5120 #define ICL_MAX_DST_H 4096 @@ -119,6 +117,12 @@ static void skl_scaler_max_src_size(struct intel_crtc *crtc, } } +static void skl_scaler_min_dst_size(int *min_w, int *min_h) +{ + *min_w = 8; + *min_h = 8; +} + static int skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, unsigned int scaler_user, int *scaler_id, @@ -186,8 +190,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, skl_scaler_min_src_size(format, modifier, &min_src_w, &min_src_h); skl_scaler_max_src_size(crtc, &max_src_w, &max_src_h); - min_dst_w = SKL_MIN_DST_W; - min_dst_h = SKL_MIN_DST_H; + skl_scaler_min_dst_size(&min_dst_w, &min_dst_h); if (DISPLAY_VER(display) < 11) { max_dst_w = SKL_MAX_DST_W; From c5877587a2a93de3ebf0cb981f02ed3d2fee3ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 19 Dec 2024 15:08:23 +0200 Subject: [PATCH 010/284] drm/i915/scaler: Extract skl_scaler_max_dst_size() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SKL_MAX_DST_* defines just make things hard to read. Get rid of them and introduce an easy to read function in their place. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241219130827.22830-5-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/skl_scaler.c | 44 +++++++++++------------ 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index cabbf4860cb38..0bc82a047510e 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -76,15 +76,6 @@ static u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited) return ((phase >> 2) & PS_PHASE_MASK) | trip; } -#define SKL_MAX_DST_W 4096 -#define SKL_MAX_DST_H 4096 -#define ICL_MAX_DST_W 5120 -#define ICL_MAX_DST_H 4096 -#define TGL_MAX_DST_W 8192 -#define TGL_MAX_DST_H 8192 -#define MTL_MAX_DST_W 8192 -#define MTL_MAX_DST_H 8192 - static void skl_scaler_min_src_size(const struct drm_format_info *format, u64 modifier, int *min_w, int *min_h) { @@ -123,6 +114,26 @@ static void skl_scaler_min_dst_size(int *min_w, int *min_h) *min_h = 8; } +static void skl_scaler_max_dst_size(struct intel_crtc *crtc, + int *max_w, int *max_h) +{ + struct intel_display *display = to_intel_display(crtc); + + if (DISPLAY_VER(display) >= 14) { + *max_w = 8192; + *max_h = 8192; + } else if (DISPLAY_VER(display) >= 12) { + *max_w = 8192; + *max_h = 8192; + } else if (DISPLAY_VER(display) == 11) { + *max_w = 5120; + *max_h = 4096; + } else { + *max_w = 4096; + *max_h = 4096; + } +} + static int skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, unsigned int scaler_user, int *scaler_id, @@ -191,20 +202,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, skl_scaler_max_src_size(crtc, &max_src_w, &max_src_h); skl_scaler_min_dst_size(&min_dst_w, &min_dst_h); - - if (DISPLAY_VER(display) < 11) { - max_dst_w = SKL_MAX_DST_W; - max_dst_h = SKL_MAX_DST_H; - } else if (DISPLAY_VER(display) < 12) { - max_dst_w = ICL_MAX_DST_W; - max_dst_h = ICL_MAX_DST_H; - } else if (DISPLAY_VER(display) < 14) { - max_dst_w = TGL_MAX_DST_W; - max_dst_h = TGL_MAX_DST_H; - } else { - max_dst_w = MTL_MAX_DST_W; - max_dst_h = MTL_MAX_DST_H; - } + skl_scaler_max_dst_size(crtc, &max_dst_w, &max_dst_h); /* range checks */ if (src_w < min_src_w || src_h < min_src_h || From d4dbabd4251a93f98f8f4e72ad57f35adbd08e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 19 Dec 2024 15:08:24 +0200 Subject: [PATCH 011/284] drm/i915/scaler: Nuke redundant code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tgl+ and mtl+ numbers in skl_scaler_max_dst_size() are identical. Combine them to a single piece of code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241219130827.22830-6-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/skl_scaler.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 0bc82a047510e..cbc71e44fcbbd 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -119,10 +119,7 @@ static void skl_scaler_max_dst_size(struct intel_crtc *crtc, { struct intel_display *display = to_intel_display(crtc); - if (DISPLAY_VER(display) >= 14) { - *max_w = 8192; - *max_h = 8192; - } else if (DISPLAY_VER(display) >= 12) { + if (DISPLAY_VER(display) >= 12) { *max_w = 8192; *max_h = 8192; } else if (DISPLAY_VER(display) == 11) { From 3040274f7e2b651a4e65082b57b7174a49bcc593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 19 Dec 2024 15:08:25 +0200 Subject: [PATCH 012/284] drm/i915/scaler: Pimp scaler debugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include the standard "[CRTC:...]" information in the scaler debugs to make life easier. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241219130827.22830-7-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/skl_scaler.c | 25 +++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index cbc71e44fcbbd..f6d76ef1a8543 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -166,7 +166,8 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, if (DISPLAY_VER(display) >= 9 && crtc_state->hw.enable && need_scaler && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { drm_dbg_kms(display->drm, - "Pipe/Plane scaling not supported with IF-ID mode\n"); + "[CRTC:%d:%s] scaling not supported with IF-ID mode\n", + crtc->base.base.id, crtc->base.name); return -EINVAL; } @@ -186,8 +187,9 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, scaler_state->scalers[*scaler_id].in_use = false; drm_dbg_kms(display->drm, - "scaler_user index %u.%u: " + "[CRTC:%d:%s] scaler_user index %u.%u: " "Staged freeing scaler id %d scaler_users = 0x%x\n", + crtc->base.base.id, crtc->base.name, crtc->pipe, scaler_user, *scaler_id, scaler_state->scaler_users); *scaler_id = -1; @@ -207,8 +209,9 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, src_w > max_src_w || src_h > max_src_h || dst_w > max_dst_w || dst_h > max_dst_h) { drm_dbg_kms(display->drm, - "scaler_user index %u.%u: src %ux%u dst %ux%u " + "[CRTC:%d:%s] scaler_user index %u.%u: src %ux%u dst %ux%u " "size is out of scaler range\n", + crtc->base.base.id, crtc->base.name, crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h); return -EINVAL; @@ -224,16 +227,18 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, */ if (pipe_src_w > max_dst_w || pipe_src_h > max_dst_h) { drm_dbg_kms(display->drm, - "scaler_user index %u.%u: pipe src size %ux%u " + "[CRTC:%d:%s] scaler_user index %u.%u: pipe src size %ux%u " "is out of scaler range\n", + crtc->base.base.id, crtc->base.name, crtc->pipe, scaler_user, pipe_src_w, pipe_src_h); return -EINVAL; } /* mark this plane as a scaler user in crtc_state */ scaler_state->scaler_users |= (1 << scaler_user); - drm_dbg_kms(display->drm, "scaler_user index %u.%u: " + drm_dbg_kms(display->drm, "[CRTC:%d:%s] scaler_user index %u.%u: " "staged scaling request for %ux%u->%ux%u scaler_users = 0x%x\n", + crtc->base.base.id, crtc->base.name, crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h, scaler_state->scaler_users); @@ -421,8 +426,8 @@ static int intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_stat if (hscale < 0 || vscale < 0) { drm_dbg_kms(display->drm, - "Scaler %d doesn't support required plane scaling\n", - *scaler_id); + "[CRTC:%d:%s] scaler %d doesn't support required plane scaling\n", + crtc->base.base.id, crtc->base.name, *scaler_id); drm_rect_debug_print("src: ", src, true); drm_rect_debug_print("dst: ", dst, false); @@ -430,7 +435,8 @@ static int intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_stat } } - drm_dbg_kms(display->drm, "Attached scaler id %u.%u to %s:%d\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] attached scaler id %u.%u to %s:%d\n", + crtc->base.base.id, crtc->base.name, crtc->pipe, *scaler_id, name, idx); scaler_state->scalers[*scaler_id].mode = mode; @@ -530,7 +536,8 @@ int intel_atomic_setup_scalers(struct intel_atomic_state *state, /* fail if required scalers > available scalers */ if (num_scalers_need > crtc->num_scalers) { drm_dbg_kms(display->drm, - "Too many scaling requests %d > %d\n", + "[CRTC:%d:%s] too many scaling requests %d > %d\n", + crtc->base.base.id, crtc->base.name, num_scalers_need, crtc->num_scalers); return -EINVAL; } From 49b14a1256a365f288abcd438750cd102a9dadb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 19 Dec 2024 15:08:26 +0200 Subject: [PATCH 013/284] drm/i915/scaler: s/excdeed/exceed/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix typo s/excdeed/exceed/ Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241219130827.22830-8-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/skl_scaler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index f6d76ef1a8543..79739357162c8 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -64,7 +64,7 @@ static u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited) /* * Hardware initial phase limited to [-0.5:1.5]. * Since the max hardware scale factor is 3.0, we - * should never actually excdeed 1.0 here. + * should never actually exceed 1.0 here. */ WARN_ON(phase < -0x8000 || phase > 0x18000); From c0eac88092642e49be3b5d47eb5d5a963199b024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 19 Dec 2024 15:08:27 +0200 Subject: [PATCH 014/284] drm/i915/scaler: Add scaler tracepoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add some tracpoints around skl+ scaler programming to help with debugging. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241219130827.22830-9-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- .../drm/i915/display/intel_display_trace.h | 99 +++++++++++++++++++ drivers/gpu/drm/i915/display/skl_scaler.c | 8 ++ 2 files changed, 107 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h index 338b9f7b20b8a..54a6e2a46b828 100644 --- a/drivers/gpu/drm/i915/display/intel_display_trace.h +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -489,6 +489,105 @@ TRACE_EVENT(intel_plane_disable_arm, __entry->frame, __entry->scanline) ); +TRACE_EVENT(intel_plane_scaler_update_arm, + TP_PROTO(struct intel_plane *plane, + int scaler_id, int x, int y, int w, int h), + TP_ARGS(plane, scaler_id, x, y, w, h), + + TP_STRUCT__entry( + __string(dev, __dev_name_kms(plane)) + __field(char, pipe_name) + __field(int, scaler_id) + __field(u32, frame) + __field(u32, scanline) + __field(int, x) + __field(int, y) + __field(int, w) + __field(int, h) + __string(name, plane->base.name) + ), + + TP_fast_assign( + struct intel_display *display = to_intel_display(plane); + struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); + __assign_str(dev); + __assign_str(name); + __entry->pipe_name = pipe_name(crtc->pipe); + __entry->scaler_id = scaler_id; + __entry->frame = intel_crtc_get_vblank_counter(crtc); + __entry->scanline = intel_get_crtc_scanline(crtc); + __entry->x = x; + __entry->y = y; + __entry->w = w; + __entry->h = h; + ), + + TP_printk("dev %s, pipe %c, scaler %d, plane %s, frame=%u, scanline=%u, " DRM_RECT_FMT, + __get_str(dev), __entry->pipe_name, __entry->scaler_id, + __get_str(name), __entry->frame, __entry->scanline, + __entry->w, __entry->h, __entry->x, __entry->y) +); + +TRACE_EVENT(intel_pipe_scaler_update_arm, + TP_PROTO(struct intel_crtc *crtc, int scaler_id, + int x, int y, int w, int h), + TP_ARGS(crtc, scaler_id, x, y, w, h), + + TP_STRUCT__entry( + __string(dev, __dev_name_kms(crtc)) + __field(char, pipe_name) + __field(int, scaler_id) + __field(u32, frame) + __field(u32, scanline) + __field(int, x) + __field(int, y) + __field(int, w) + __field(int, h) + ), + + TP_fast_assign( + __assign_str(dev); + __entry->pipe_name = pipe_name(crtc->pipe); + __entry->scaler_id = scaler_id; + __entry->frame = intel_crtc_get_vblank_counter(crtc); + __entry->scanline = intel_get_crtc_scanline(crtc); + __entry->x = x; + __entry->y = y; + __entry->w = w; + __entry->h = h; + ), + + TP_printk("dev %s, pipe %c, scaler %d frame=%u, scanline=%u, " DRM_RECT_FMT, + __get_str(dev), __entry->pipe_name, __entry->scaler_id, + __entry->frame, __entry->scanline, + __entry->w, __entry->h, __entry->x, __entry->y) +); + +TRACE_EVENT(intel_scaler_disable_arm, + TP_PROTO(struct intel_crtc *crtc, int scaler_id), + TP_ARGS(crtc, scaler_id), + + TP_STRUCT__entry( + __string(dev, __dev_name_kms(crtc)) + __field(char, pipe_name) + __field(int, scaler_id) + __field(u32, frame) + __field(u32, scanline) + ), + + TP_fast_assign( + __assign_str(dev); + __entry->pipe_name = pipe_name(crtc->pipe); + __entry->scaler_id = scaler_id; + __entry->frame = intel_crtc_get_vblank_counter(crtc); + __entry->scanline = intel_get_crtc_scanline(crtc); + ), + + TP_printk("dev %s, pipe %c, scaler %d, frame=%u, scanline=%u", + __get_str(dev), __entry->pipe_name, __entry->scaler_id, + __entry->frame, __entry->scanline) +); + TRACE_EVENT(intel_fbc_activate, TP_PROTO(struct intel_plane *plane), TP_ARGS(plane), diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 79739357162c8..a11e09a15e238 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -6,6 +6,7 @@ #include "i915_drv.h" #include "i915_reg.h" #include "intel_de.h" +#include "intel_display_trace.h" #include "intel_display_types.h" #include "intel_fb.h" #include "skl_scaler.h" @@ -706,6 +707,8 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state) ps_ctrl = PS_SCALER_EN | PS_BINDING_PIPE | scaler_state->scalers[id].mode | skl_scaler_get_filter_select(crtc_state->hw.scaling_filter, 0); + trace_intel_pipe_scaler_update_arm(crtc, id, x, y, width, height); + skl_scaler_setup_filter(display, pipe, id, 0, crtc_state->hw.scaling_filter); @@ -770,6 +773,9 @@ skl_program_plane_scaler(struct intel_plane *plane, ps_ctrl = PS_SCALER_EN | PS_BINDING_PLANE(plane->id) | scaler->mode | skl_scaler_get_filter_select(plane_state->hw.scaling_filter, 0); + trace_intel_plane_scaler_update_arm(plane, scaler_id, + crtc_x, crtc_y, crtc_w, crtc_h); + skl_scaler_setup_filter(display, pipe, scaler_id, 0, plane_state->hw.scaling_filter); @@ -788,6 +794,8 @@ static void skl_detach_scaler(struct intel_crtc *crtc, int id) { struct intel_display *display = to_intel_display(crtc); + trace_intel_scaler_disable_arm(crtc, id); + intel_de_write_fw(display, SKL_PS_CTRL(crtc->pipe, id), 0); intel_de_write_fw(display, SKL_PS_WIN_POS(crtc->pipe, id), 0); intel_de_write_fw(display, SKL_PS_WIN_SZ(crtc->pipe, id), 0); From a1c666ddfc0a31173c21efee980e2eefae8bad14 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Wed, 13 Nov 2024 14:37:00 +0800 Subject: [PATCH 015/284] MAINTAINERS: switch my mail address for GVT driver I won't be able to use intel account, so this switches address to my gmail account. Cc: Zhi Wang Cc: Zhiyuan Lv Cc: James Wu Cc: Zhenyu Wang Signed-off-by: Zhenyu Wang Acked-by: Rodrigo Vivi Acked-by: Zhi Wang Link: https://patchwork.freedesktop.org/patch/msgid/20241113063700.4460-1-zhenyuw@linux.intel.com Signed-off-by: Rodrigo Vivi --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 63118f36e76e9..25c683a92162b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11554,7 +11554,7 @@ F: drivers/gpio/gpio-tangier.c F: drivers/gpio/gpio-tangier.h INTEL GVT-g DRIVERS (Intel GPU Virtualization) -M: Zhenyu Wang +M: Zhenyu Wang M: Zhi Wang L: intel-gvt-dev@lists.freedesktop.org L: intel-gfx@lists.freedesktop.org From 57af0c0f3b3bad8669dbcdb6b1d31b1537c614ad Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 22 Dec 2024 00:20:41 +0000 Subject: [PATCH 016/284] drm/i915/gvt: Remove intel_gvt_ggtt_h2g<->index intel_gvt_ggtt_h2g_index() and intel_gvt_ggtt_index_g2h() were added in 2016 by commit 2707e4446688 ("drm/i915/gvt: vGPU graphics memory virtualization") but haven't been used. Remove them. They were the only users of intel_gvt_ggtt_gmadr_g2h() and intel_gvt_ggtt_gmadr_h2g(). Remove them. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Zhenyu Wang Link: https://patchwork.freedesktop.org/patch/msgid/20241222002043.173080-2-linux@treblig.org Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gvt/gtt.c | 66 ---------------------------------- drivers/gpu/drm/i915/gvt/gvt.h | 6 ---- 2 files changed, 72 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 1bce1493b86ff..464fb17e82ee7 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -71,72 +71,6 @@ bool intel_gvt_ggtt_validate_range(struct intel_vgpu *vgpu, u64 addr, u32 size) return false; } -/* translate a guest gmadr to host gmadr */ -int intel_gvt_ggtt_gmadr_g2h(struct intel_vgpu *vgpu, u64 g_addr, u64 *h_addr) -{ - struct drm_i915_private *i915 = vgpu->gvt->gt->i915; - - if (drm_WARN(&i915->drm, !vgpu_gmadr_is_valid(vgpu, g_addr), - "invalid guest gmadr %llx\n", g_addr)) - return -EACCES; - - if (vgpu_gmadr_is_aperture(vgpu, g_addr)) - *h_addr = vgpu_aperture_gmadr_base(vgpu) - + (g_addr - vgpu_aperture_offset(vgpu)); - else - *h_addr = vgpu_hidden_gmadr_base(vgpu) - + (g_addr - vgpu_hidden_offset(vgpu)); - return 0; -} - -/* translate a host gmadr to guest gmadr */ -int intel_gvt_ggtt_gmadr_h2g(struct intel_vgpu *vgpu, u64 h_addr, u64 *g_addr) -{ - struct drm_i915_private *i915 = vgpu->gvt->gt->i915; - - if (drm_WARN(&i915->drm, !gvt_gmadr_is_valid(vgpu->gvt, h_addr), - "invalid host gmadr %llx\n", h_addr)) - return -EACCES; - - if (gvt_gmadr_is_aperture(vgpu->gvt, h_addr)) - *g_addr = vgpu_aperture_gmadr_base(vgpu) - + (h_addr - gvt_aperture_gmadr_base(vgpu->gvt)); - else - *g_addr = vgpu_hidden_gmadr_base(vgpu) - + (h_addr - gvt_hidden_gmadr_base(vgpu->gvt)); - return 0; -} - -int intel_gvt_ggtt_index_g2h(struct intel_vgpu *vgpu, unsigned long g_index, - unsigned long *h_index) -{ - u64 h_addr; - int ret; - - ret = intel_gvt_ggtt_gmadr_g2h(vgpu, g_index << I915_GTT_PAGE_SHIFT, - &h_addr); - if (ret) - return ret; - - *h_index = h_addr >> I915_GTT_PAGE_SHIFT; - return 0; -} - -int intel_gvt_ggtt_h2g_index(struct intel_vgpu *vgpu, unsigned long h_index, - unsigned long *g_index) -{ - u64 g_addr; - int ret; - - ret = intel_gvt_ggtt_gmadr_h2g(vgpu, h_index << I915_GTT_PAGE_SHIFT, - &g_addr); - if (ret) - return ret; - - *g_index = g_addr >> I915_GTT_PAGE_SHIFT; - return 0; -} - #define gtt_type_is_entry(type) \ (type > GTT_TYPE_INVALID && type < GTT_TYPE_PPGTT_ENTRY \ && type != GTT_TYPE_PPGTT_PTE_ENTRY \ diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 2c95aeef4e415..8580c6d057e79 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -531,12 +531,6 @@ int intel_gvt_set_edid(struct intel_vgpu *vgpu, int port_num); gvt_gmadr_is_hidden(gvt, gmadr)) bool intel_gvt_ggtt_validate_range(struct intel_vgpu *vgpu, u64 addr, u32 size); -int intel_gvt_ggtt_gmadr_g2h(struct intel_vgpu *vgpu, u64 g_addr, u64 *h_addr); -int intel_gvt_ggtt_gmadr_h2g(struct intel_vgpu *vgpu, u64 h_addr, u64 *g_addr); -int intel_gvt_ggtt_index_g2h(struct intel_vgpu *vgpu, unsigned long g_index, - unsigned long *h_index); -int intel_gvt_ggtt_h2g_index(struct intel_vgpu *vgpu, unsigned long h_index, - unsigned long *g_index); void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu, bool primary); From 35bdd1060a04e234e85bb7494d505d2bbdcabd58 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 22 Dec 2024 00:20:42 +0000 Subject: [PATCH 017/284] drm/i915/gvt: Remove unused intel_vgpu_decode_sprite_plane intel_vgpu_decode_sprite_plane() was added in 2017 by commit 9f31d1063b43 ("drm/i915/gvt: Add framebuffer decoder support") but has remained unused. Remove it. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Zhenyu Wang Link: https://patchwork.freedesktop.org/patch/msgid/20241222002043.173080-3-linux@treblig.org Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gvt/fb_decoder.c | 117 -------------------------- drivers/gpu/drm/i915/gvt/fb_decoder.h | 2 - 2 files changed, 119 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c b/drivers/gpu/drm/i915/gvt/fb_decoder.c index 15cce973e1ae1..f9f7ef131371f 100644 --- a/drivers/gpu/drm/i915/gvt/fb_decoder.c +++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c @@ -398,120 +398,3 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu, plane->y_hot = vgpu_vreg_t(vgpu, vgtif_reg(cursor_y_hot)); return 0; } - -#define SPRITE_FORMAT_NUM (1 << 3) - -static const struct pixel_format sprite_pixel_formats[SPRITE_FORMAT_NUM] = { - [0x0] = {DRM_FORMAT_YUV422, 16, "YUV 16-bit 4:2:2 packed"}, - [0x1] = {DRM_FORMAT_XRGB2101010, 32, "RGB 32-bit 2:10:10:10"}, - [0x2] = {DRM_FORMAT_XRGB8888, 32, "RGB 32-bit 8:8:8:8"}, - [0x4] = {DRM_FORMAT_AYUV, 32, - "YUV 32-bit 4:4:4 packed (8:8:8:8 MSB-X:Y:U:V)"}, -}; - -/** - * intel_vgpu_decode_sprite_plane - Decode sprite plane - * @vgpu: input vgpu - * @plane: sprite plane to save decoded info - * This function is called for decoding plane - * - * Returns: - * 0 on success, non-zero if failed. - */ -int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu, - struct intel_vgpu_sprite_plane_format *plane) -{ - u32 val, fmt; - u32 color_order, yuv_order; - int drm_format; - int pipe; - - pipe = get_active_pipe(vgpu); - if (pipe >= I915_MAX_PIPES) - return -ENODEV; - - val = vgpu_vreg_t(vgpu, SPRCTL(pipe)); - plane->enabled = !!(val & SPRITE_ENABLE); - if (!plane->enabled) - return -ENODEV; - - plane->tiled = !!(val & SPRITE_TILED); - color_order = !!(val & SPRITE_RGB_ORDER_RGBX); - yuv_order = (val & SPRITE_YUV_ORDER_MASK) >> - _SPRITE_YUV_ORDER_SHIFT; - - fmt = (val & SPRITE_FORMAT_MASK) >> _SPRITE_FMT_SHIFT; - if (!sprite_pixel_formats[fmt].bpp) { - gvt_vgpu_err("Non-supported pixel format (0x%x)\n", fmt); - return -EINVAL; - } - plane->hw_format = fmt; - plane->bpp = sprite_pixel_formats[fmt].bpp; - drm_format = sprite_pixel_formats[fmt].drm_format; - - /* Order of RGB values in an RGBxxx buffer may be ordered RGB or - * BGR depending on the state of the color_order field - */ - if (!color_order) { - if (drm_format == DRM_FORMAT_XRGB2101010) - drm_format = DRM_FORMAT_XBGR2101010; - else if (drm_format == DRM_FORMAT_XRGB8888) - drm_format = DRM_FORMAT_XBGR8888; - } - - if (drm_format == DRM_FORMAT_YUV422) { - switch (yuv_order) { - case 0: - drm_format = DRM_FORMAT_YUYV; - break; - case 1: - drm_format = DRM_FORMAT_UYVY; - break; - case 2: - drm_format = DRM_FORMAT_YVYU; - break; - case 3: - drm_format = DRM_FORMAT_VYUY; - break; - default: - /* yuv_order has only 2 bits */ - break; - } - } - - plane->drm_format = drm_format; - - plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK; - if (!vgpu_gmadr_is_valid(vgpu, plane->base)) - return -EINVAL; - - plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base); - if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) { - gvt_vgpu_err("Translate sprite plane gma 0x%x to gpa fail\n", - plane->base); - return -EINVAL; - } - - plane->stride = vgpu_vreg_t(vgpu, SPRSTRIDE(pipe)) & - _SPRITE_STRIDE_MASK; - - val = vgpu_vreg_t(vgpu, SPRSIZE(pipe)); - plane->height = (val & _SPRITE_SIZE_HEIGHT_MASK) >> - _SPRITE_SIZE_HEIGHT_SHIFT; - plane->width = (val & _SPRITE_SIZE_WIDTH_MASK) >> - _SPRITE_SIZE_WIDTH_SHIFT; - plane->height += 1; /* raw height is one minus the real value */ - plane->width += 1; /* raw width is one minus the real value */ - - val = vgpu_vreg_t(vgpu, SPRPOS(pipe)); - plane->x_pos = (val & _SPRITE_POS_X_MASK) >> _SPRITE_POS_X_SHIFT; - plane->y_pos = (val & _SPRITE_POS_Y_MASK) >> _SPRITE_POS_Y_SHIFT; - - val = vgpu_vreg_t(vgpu, SPROFFSET(pipe)); - plane->x_offset = (val & _SPRITE_OFFSET_START_X_MASK) >> - _SPRITE_OFFSET_START_X_SHIFT; - plane->y_offset = (val & _SPRITE_OFFSET_START_Y_MASK) >> - _SPRITE_OFFSET_START_Y_SHIFT; - - return 0; -} diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.h b/drivers/gpu/drm/i915/gvt/fb_decoder.h index fa6503900c842..436d43c0087b3 100644 --- a/drivers/gpu/drm/i915/gvt/fb_decoder.h +++ b/drivers/gpu/drm/i915/gvt/fb_decoder.h @@ -156,7 +156,5 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu, struct intel_vgpu_primary_plane_format *plane); int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu, struct intel_vgpu_cursor_plane_format *plane); -int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu, - struct intel_vgpu_sprite_plane_format *plane); #endif From 4e19eabc7e5c03da09a53fc05caecab3aa18ee0d Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 22 Dec 2024 00:20:43 +0000 Subject: [PATCH 018/284] drm/i915/gvt: Remove unused intel_gvt_in_force_nonpriv_whitelist The last use of intel_gvt_in_force_nonpriv_whitelist() was removed in 2020 by commit 02dd2b12a685 ("drm/i915/gvt: unify lri cmd handler and mmio handlers") Remove it. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Zhenyu Wang Link: https://patchwork.freedesktop.org/patch/msgid/20241222002043.173080-4-linux@treblig.org Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gvt/handlers.c | 17 ----------------- drivers/gpu/drm/i915/gvt/mmio.h | 3 --- 2 files changed, 20 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 241cff0fc6836..ee473b45d1e4a 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -3118,23 +3118,6 @@ int intel_vgpu_mask_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, return 0; } -/** - * intel_gvt_in_force_nonpriv_whitelist - if a mmio is in whitelist to be - * force-nopriv register - * - * @gvt: a GVT device - * @offset: register offset - * - * Returns: - * True if the register is in force-nonpriv whitelist; - * False if outside; - */ -bool intel_gvt_in_force_nonpriv_whitelist(struct intel_gvt *gvt, - unsigned int offset) -{ - return in_whitelist(offset); -} - /** * intel_vgpu_mmio_reg_rw - emulate tracked mmio registers * @vgpu: a vGPU diff --git a/drivers/gpu/drm/i915/gvt/mmio.h b/drivers/gpu/drm/i915/gvt/mmio.h index 32ebacb078e8a..3dc912aba80b3 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.h +++ b/drivers/gpu/drm/i915/gvt/mmio.h @@ -96,9 +96,6 @@ int intel_vgpu_default_mmio_read(struct intel_vgpu *vgpu, unsigned int offset, int intel_vgpu_default_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes); -bool intel_gvt_in_force_nonpriv_whitelist(struct intel_gvt *gvt, - unsigned int offset); - int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset, void *pdata, unsigned int bytes, bool is_read); From 4f7fad42aa1aefc2baca7ef91d955fbe6f133e28 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 10 Jan 2025 09:46:39 -0500 Subject: [PATCH 019/284] drm/i915/guc/slpc: Allow GuC SLPC default strategies on MTL+ The Balancer and DCC strategies were left off on a fear that these strategies would conflict with the i915's waitboost. However, on MTL and Beyond these strategies are only active in certain conditions where the system is TDP limited. So, they don't conflict, but help the waitboost by guaranteeing a bit more of GT frequency. Without these strategies we were likely leaving some performance behind on some scenarios. With this change in place, the enabling/disabling of DCC and Balancer will now be chosen by GuC, on a platform/GT basis. v2: - Fix typos and be clear on GuC decision on platform basis (Vinay) - Limit change to MTL and beyond, where GuC started to take TDP limit into consideration. v3: Fix compilation. Actually amend the changes... Reviewed-by: Vinay Belgaumkar Link: https://patchwork.freedesktop.org/patch/msgid/20250110144640.1032250-1-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 22 ++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index 706fffca698b6..1f8e6f7c2c678 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -357,21 +357,29 @@ static u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc) GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER); } -static void slpc_shared_data_reset(struct slpc_shared_data *data) +static void slpc_shared_data_reset(struct intel_guc_slpc *slpc) { - memset(data, 0, sizeof(struct slpc_shared_data)); + struct drm_i915_private *i915 = slpc_to_i915(slpc); + struct slpc_shared_data *data = slpc->vaddr; + memset(data, 0, sizeof(struct slpc_shared_data)); data->header.size = sizeof(struct slpc_shared_data); /* Enable only GTPERF task, disable others */ slpc_mem_set_enabled(data, SLPC_PARAM_TASK_ENABLE_GTPERF, SLPC_PARAM_TASK_DISABLE_GTPERF); - slpc_mem_set_disabled(data, SLPC_PARAM_TASK_ENABLE_BALANCER, - SLPC_PARAM_TASK_DISABLE_BALANCER); + /* + * Don't allow balancer related algorithms on platforms before + * Xe_LPG, where GuC started to restrict it to TDP limited scenarios. + */ + if (GRAPHICS_VER_FULL(i915) < IP_VER(12, 70)) { + slpc_mem_set_disabled(data, SLPC_PARAM_TASK_ENABLE_BALANCER, + SLPC_PARAM_TASK_DISABLE_BALANCER); - slpc_mem_set_disabled(data, SLPC_PARAM_TASK_ENABLE_DCC, - SLPC_PARAM_TASK_DISABLE_DCC); + slpc_mem_set_disabled(data, SLPC_PARAM_TASK_ENABLE_DCC, + SLPC_PARAM_TASK_DISABLE_DCC); + } } /** @@ -686,7 +694,7 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) GEM_BUG_ON(!slpc->vma); - slpc_shared_data_reset(slpc->vaddr); + slpc_shared_data_reset(slpc); ret = slpc_reset(slpc); if (unlikely(ret < 0)) { From e0b0c6d2076d2b94122218259202030faaaac61d Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 10 Jan 2025 09:46:40 -0500 Subject: [PATCH 020/284] drm/i915/guc/slpc: Print more SLPC debug status information Let's peek on the Balancer and DCC status, now that we are using the default strategies. v2: fix identation v3: fix typo (Vinay) Reviewed-by: Vinay Belgaumkar Link: https://patchwork.freedesktop.org/patch/msgid/20250110144640.1032250-2-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index 1f8e6f7c2c678..1a0e1a412fdb0 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -799,6 +799,23 @@ int intel_guc_slpc_print_info(struct intel_guc_slpc *slpc, struct drm_printer *p drm_printf(p, "\tSLPC state: %s\n", slpc_get_state_string(slpc)); drm_printf(p, "\tGTPERF task active: %s\n", str_yes_no(slpc_tasks->status & SLPC_GTPERF_TASK_ENABLED)); + drm_printf(p, "\tDCC enabled: %s\n", + str_yes_no(slpc_tasks->status & + SLPC_DCC_TASK_ENABLED)); + drm_printf(p, "\tDCC in: %s\n", + str_yes_no(slpc_tasks->status & SLPC_IN_DCC)); + drm_printf(p, "\tBalancer enabled: %s\n", + str_yes_no(slpc_tasks->status & + SLPC_BALANCER_ENABLED)); + drm_printf(p, "\tIBC enabled: %s\n", + str_yes_no(slpc_tasks->status & + SLPC_IBC_TASK_ENABLED)); + drm_printf(p, "\tBalancer IA LMT enabled: %s\n", + str_yes_no(slpc_tasks->status & + SLPC_BALANCER_IA_LMT_ENABLED)); + drm_printf(p, "\tBalancer IA LMT active: %s\n", + str_yes_no(slpc_tasks->status & + SLPC_BALANCER_IA_LMT_ACTIVE)); drm_printf(p, "\tMax freq: %u MHz\n", slpc_decode_max_freq(slpc)); drm_printf(p, "\tMin freq: %u MHz\n", From ed3a892e5e3d6b3f6eeb76db7c92a968aeb52f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 29 Nov 2024 08:50:11 +0200 Subject: [PATCH 021/284] drm/i915/fb: Relax clear color alignment to 64 bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mesa changed its clear color alignment from 4k to 64 bytes without informing the kernel side about the change. This is now likely to cause framebuffer creation to fail. The only thing we do with the clear color buffer in i915 is: 1. map a single page 2. read out bytes 16-23 from said page 3. unmap the page So the only requirement we really have is that those 8 bytes are all contained within one page. Thus we can deal with the Mesa regression by reducing the alignment requiment from 4k to the same 64 bytes in the kernel. We could even go as low as 32 bytes, but IIRC 64 bytes is the hardware requirement on the 3D engine side so matching that seems sensible. Note that the Mesa alignment chages were partially undone so the regression itself was already fixed on userspace side. Cc: stable@vger.kernel.org Cc: Sagar Ghuge Cc: Nanley Chery Reported-by: Xi Ruoyao Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13057 Closes: https://lore.kernel.org/all/45a5bba8de009347262d86a4acb27169d9ae0d9f.camel@xry111.site/ Link: https://gitlab.freedesktop.org/mesa/mesa/-/commit/17f97a69c13832a6c1b0b3aad45b06f07d4b852f Link: https://gitlab.freedesktop.org/mesa/mesa/-/commit/888f63cf1baf34bc95e847a30a041dc7798edddb Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241129065014.8363-2-ville.syrjala@linux.intel.com Tested-by: Xi Ruoyao Reviewed-by: José Roberto de Souza --- drivers/gpu/drm/i915/display/intel_fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 6a7060889f40e..223c4218c019d 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1694,7 +1694,7 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * * arithmetic related to alignment and offset calculation. */ if (is_gen12_ccs_cc_plane(&fb->base, i)) { - if (IS_ALIGNED(fb->base.offsets[i], PAGE_SIZE)) + if (IS_ALIGNED(fb->base.offsets[i], 64)) continue; else return -EINVAL; From 0bd39e303ee705c4b0549e2826c42c1d7b849898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 29 Nov 2024 08:50:12 +0200 Subject: [PATCH 022/284] drm/i915/fb: Add debug spew for misaligned CC plane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're currently failing to provide any debug output when the user passes in a misaligned offset for the clear color plane. Add some debugs prints to make debugging actually possible. Cc: Sagar Ghuge Cc: Nanley Chery Cc: Xi Ruoyao Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241129065014.8363-3-ville.syrjala@linux.intel.com Reviewed-by: José Roberto de Souza --- drivers/gpu/drm/i915/display/intel_fb.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 223c4218c019d..e478d412785e3 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1694,10 +1694,14 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * * arithmetic related to alignment and offset calculation. */ if (is_gen12_ccs_cc_plane(&fb->base, i)) { - if (IS_ALIGNED(fb->base.offsets[i], 64)) - continue; - else + if (!IS_ALIGNED(fb->base.offsets[i], 64)) { + drm_dbg_kms(&i915->drm, + "fb misaligned clear color plane %d offset (0x%x)\n", + i, fb->base.offsets[i]); return -EINVAL; + } + + continue; } intel_fb_plane_dims(fb, i, &width, &height); From b9ec6793355647bcbcecb21ef6cd179469d3f191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 29 Nov 2024 08:50:13 +0200 Subject: [PATCH 023/284] drm/i915/fb: Check that the clear color fits within the BO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure the user supplied offset[] for the clear color plane fits within the actual BO. Note that we use tile units to track the size here. All the other color/aux planes are already being checked correctly. Cc: Sagar Ghuge Cc: Nanley Chery Cc: Xi Ruoyao Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241129065014.8363-4-ville.syrjala@linux.intel.com Reviewed-by: José Roberto de Souza --- drivers/gpu/drm/i915/display/intel_fb.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index e478d412785e3..9f7f1b9f32750 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1694,6 +1694,8 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * * arithmetic related to alignment and offset calculation. */ if (is_gen12_ccs_cc_plane(&fb->base, i)) { + unsigned int end; + if (!IS_ALIGNED(fb->base.offsets[i], 64)) { drm_dbg_kms(&i915->drm, "fb misaligned clear color plane %d offset (0x%x)\n", @@ -1701,6 +1703,14 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * return -EINVAL; } + if (check_add_overflow(fb->base.offsets[i], 64, &end)) { + drm_dbg_kms(&i915->drm, + "fb bad clear color plane %d offset (0x%x)\n", + i, fb->base.offsets[i]); + return -EINVAL; + } + + max_size = max(max_size, DIV_ROUND_UP(end, tile_size)); continue; } From 1b242ceec53627a93129ee076b94f8eb321e5a79 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 8 Jan 2025 16:04:13 +0200 Subject: [PATCH 024/284] drm/i915/audio: convert to struct intel_display Going forward, struct intel_display will be the main display device structure. Convert intel_audio.[ch] to it, as much as possible anyway. Do some minor checkpatch fixes while at it. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/4ddcc2e704fc6b1592a878c80e15fadd82c63550.1736345025.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_audio.c | 413 +++++++++--------- drivers/gpu/drm/i915/display/intel_audio.h | 14 +- drivers/gpu/drm/i915/display/intel_cdclk.c | 5 +- .../drm/i915/display/intel_display_driver.c | 10 +- drivers/gpu/drm/xe/display/xe_display.c | 2 +- 5 files changed, 226 insertions(+), 218 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index ce8a4319a63c5..8c26e0e7c2cd6 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -188,15 +188,15 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = { * WA_14020863754: Implement Audio Workaround * Corner case with Min Hblank Fix can cause audio hang */ -static bool needs_wa_14020863754(struct drm_i915_private *i915) +static bool needs_wa_14020863754(struct intel_display *display) { - return (DISPLAY_VER(i915) == 20 || IS_BATTLEMAGE(i915)); + return DISPLAY_VER(display) == 20 || display->platform.battlemage; } /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; int i; @@ -206,17 +206,17 @@ static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_sta break; } - if (DISPLAY_VER(i915) < 12 && adjusted_mode->crtc_clock > 148500) + if (DISPLAY_VER(display) < 12 && adjusted_mode->crtc_clock > 148500) i = ARRAY_SIZE(hdmi_audio_clock); if (i == ARRAY_SIZE(hdmi_audio_clock)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "HDMI audio pixel clock setting for %d not found, falling back to defaults\n", adjusted_mode->crtc_clock); i = 1; } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Configuring HDMI audio for pixel clock %d (0x%08x)\n", hdmi_audio_clock[i].clock, hdmi_audio_clock[i].config); @@ -251,11 +251,11 @@ static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state, } /* ELD buffer size in dwords */ -static int g4x_eld_buffer_size(struct drm_i915_private *i915) +static int g4x_eld_buffer_size(struct intel_display *display) { u32 tmp; - tmp = intel_de_read(i915, G4X_AUD_CNTL_ST); + tmp = intel_de_read(display, G4X_AUD_CNTL_ST); return REG_FIELD_GET(G4X_ELD_BUFFER_SIZE_MASK, tmp); } @@ -263,33 +263,33 @@ static int g4x_eld_buffer_size(struct drm_i915_private *i915) static void g4x_audio_codec_get_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); u32 *eld = (u32 *)crtc_state->eld; int eld_buffer_size, len, i; u32 tmp; - tmp = intel_de_read(i915, G4X_AUD_CNTL_ST); + tmp = intel_de_read(display, G4X_AUD_CNTL_ST); if ((tmp & G4X_ELD_VALID) == 0) return; - intel_de_rmw(i915, G4X_AUD_CNTL_ST, G4X_ELD_ADDRESS_MASK, 0); + intel_de_rmw(display, G4X_AUD_CNTL_ST, G4X_ELD_ADDRESS_MASK, 0); - eld_buffer_size = g4x_eld_buffer_size(i915); + eld_buffer_size = g4x_eld_buffer_size(display); len = min_t(int, sizeof(crtc_state->eld) / 4, eld_buffer_size); for (i = 0; i < len; i++) - eld[i] = intel_de_read(i915, G4X_HDMIW_HDMIEDID); + eld[i] = intel_de_read(display, G4X_HDMIW_HDMIEDID); } static void g4x_audio_codec_disable(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); /* Invalidate ELD */ - intel_de_rmw(i915, G4X_AUD_CNTL_ST, + intel_de_rmw(display, G4X_AUD_CNTL_ST, G4X_ELD_VALID, 0); intel_crtc_wait_for_next_vblank(crtc); @@ -300,28 +300,28 @@ static void g4x_audio_codec_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const u32 *eld = (const u32 *)crtc_state->eld; int eld_buffer_size, len, i; intel_crtc_wait_for_next_vblank(crtc); - intel_de_rmw(i915, G4X_AUD_CNTL_ST, + intel_de_rmw(display, G4X_AUD_CNTL_ST, G4X_ELD_VALID | G4X_ELD_ADDRESS_MASK, 0); - eld_buffer_size = g4x_eld_buffer_size(i915); + eld_buffer_size = g4x_eld_buffer_size(display); len = min(drm_eld_size(crtc_state->eld) / 4, eld_buffer_size); for (i = 0; i < len; i++) - intel_de_write(i915, G4X_HDMIW_HDMIEDID, eld[i]); + intel_de_write(display, G4X_HDMIW_HDMIEDID, eld[i]); for (; i < eld_buffer_size; i++) - intel_de_write(i915, G4X_HDMIW_HDMIEDID, 0); + intel_de_write(display, G4X_HDMIW_HDMIEDID, 0); - drm_WARN_ON(&i915->drm, - (intel_de_read(i915, G4X_AUD_CNTL_ST) & G4X_ELD_ADDRESS_MASK) != 0); + drm_WARN_ON(display->drm, + (intel_de_read(display, G4X_AUD_CNTL_ST) & G4X_ELD_ADDRESS_MASK) != 0); - intel_de_rmw(i915, G4X_AUD_CNTL_ST, + intel_de_rmw(display, G4X_AUD_CNTL_ST, 0, G4X_ELD_VALID); } @@ -329,11 +329,11 @@ static void hsw_dp_audio_config_update(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; /* Enable time stamps. Let HW calculate Maud/Naud values */ - intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder), + intel_de_rmw(display, HSW_AUD_CFG(cpu_transcoder), AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK | AUD_CONFIG_UPPER_N_MASK | @@ -347,8 +347,8 @@ static void hsw_hdmi_audio_config_update(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); - struct i915_audio_component *acomp = i915->display.audio.component; + struct intel_display *display = to_intel_display(encoder); + struct i915_audio_component *acomp = display->audio.component; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum port port = encoder->port; int n, rate; @@ -356,7 +356,7 @@ hsw_hdmi_audio_config_update(struct intel_encoder *encoder, rate = acomp ? acomp->aud_sample_rate[port] : 0; - tmp = intel_de_read(i915, HSW_AUD_CFG(cpu_transcoder)); + tmp = intel_de_read(display, HSW_AUD_CFG(cpu_transcoder)); tmp &= ~AUD_CONFIG_N_VALUE_INDEX; tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; tmp &= ~AUD_CONFIG_N_PROG_ENABLE; @@ -364,25 +364,25 @@ hsw_hdmi_audio_config_update(struct intel_encoder *encoder, n = audio_config_hdmi_get_n(crtc_state, rate); if (n != 0) { - drm_dbg_kms(&i915->drm, "using N %d\n", n); + drm_dbg_kms(display->drm, "using N %d\n", n); tmp &= ~AUD_CONFIG_N_MASK; tmp |= AUD_CONFIG_N(n); tmp |= AUD_CONFIG_N_PROG_ENABLE; } else { - drm_dbg_kms(&i915->drm, "using automatic N\n"); + drm_dbg_kms(display->drm, "using automatic N\n"); } - intel_de_write(i915, HSW_AUD_CFG(cpu_transcoder), tmp); + intel_de_write(display, HSW_AUD_CFG(cpu_transcoder), tmp); /* * Let's disable "Enable CTS or M Prog bit" * and let HW calculate the value */ - tmp = intel_de_read(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder)); + tmp = intel_de_read(display, HSW_AUD_M_CTS_ENABLE(cpu_transcoder)); tmp &= ~AUD_M_CTS_M_PROG_ENABLE; tmp &= ~AUD_M_CTS_M_VALUE_INDEX; - intel_de_write(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp); + intel_de_write(display, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp); } static void @@ -399,14 +399,14 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; - mutex_lock(&i915->display.audio.mutex); + mutex_lock(&display->audio.mutex); /* Disable timestamps */ - intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder), + intel_de_rmw(display, HSW_AUD_CFG(cpu_transcoder), AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_UPPER_N_MASK | AUD_CONFIG_LOWER_N_MASK, @@ -415,26 +415,26 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder, AUD_CONFIG_N_VALUE_INDEX : 0)); /* Invalidate ELD */ - intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD, + intel_de_rmw(display, HSW_AUD_PIN_ELD_CP_VLD, AUDIO_ELD_VALID(cpu_transcoder), 0); intel_crtc_wait_for_next_vblank(crtc); intel_crtc_wait_for_next_vblank(crtc); /* Disable audio presence detect */ - intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD, + intel_de_rmw(display, HSW_AUD_PIN_ELD_CP_VLD, AUDIO_OUTPUT_ENABLE(cpu_transcoder), 0); - if (needs_wa_14020863754(i915)) - intel_de_rmw(i915, AUD_CHICKENBIT_REG3, DACBE_DISABLE_MIN_HBLANK_FIX, 0); + if (needs_wa_14020863754(display)) + intel_de_rmw(display, AUD_CHICKENBIT_REG3, DACBE_DISABLE_MIN_HBLANK_FIX, 0); - mutex_unlock(&i915->display.audio.mutex); + mutex_unlock(&display->audio.mutex); } static unsigned int calc_hblank_early_prog(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); unsigned int link_clks_available, link_clks_required; unsigned int tu_data, tu_line, link_clks_active; unsigned int h_active, h_total, hblank_delta, pixel_clk; @@ -446,13 +446,13 @@ static unsigned int calc_hblank_early_prog(struct intel_encoder *encoder, h_total = crtc_state->hw.adjusted_mode.crtc_htotal; pixel_clk = crtc_state->hw.adjusted_mode.crtc_clock; vdsc_bppx16 = crtc_state->dsc.compressed_bpp_x16; - cdclk = i915->display.cdclk.hw.cdclk; + cdclk = display->cdclk.hw.cdclk; /* fec= 0.972261, using rounding multiplier of 1000000 */ fec_coeff = 972261; link_clk = crtc_state->port_clock; lanes = crtc_state->lane_count; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "h_active = %u link_clk = %u : lanes = %u vdsc_bpp = " FXP_Q4_FMT " cdclk = %u\n", h_active, link_clk, lanes, FXP_Q4_ARGS(vdsc_bppx16), cdclk); @@ -497,19 +497,19 @@ static unsigned int calc_samples_room(const struct intel_crtc_state *crtc_state) static void enable_audio_dsc_wa(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; unsigned int hblank_early_prog, samples_room; unsigned int val; - if (DISPLAY_VER(i915) < 11) + if (DISPLAY_VER(display) < 11) return; - val = intel_de_read(i915, AUD_CONFIG_BE); + val = intel_de_read(display, AUD_CONFIG_BE); - if (DISPLAY_VER(i915) == 11) + if (DISPLAY_VER(display) == 11) val |= HBLANK_EARLY_ENABLE_ICL(cpu_transcoder); - else if (DISPLAY_VER(i915) >= 12) + else if (DISPLAY_VER(display) >= 12) val |= HBLANK_EARLY_ENABLE_TGL(cpu_transcoder); if (crtc_state->dsc.compression_enable && @@ -536,34 +536,34 @@ static void enable_audio_dsc_wa(struct intel_encoder *encoder, val |= NUMBER_SAMPLES_PER_LINE(cpu_transcoder, 0x0); } - intel_de_write(i915, AUD_CONFIG_BE, val); + intel_de_write(display, AUD_CONFIG_BE, val); } static void hsw_audio_codec_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - mutex_lock(&i915->display.audio.mutex); + mutex_lock(&display->audio.mutex); /* Enable Audio WA for 4k DSC usecases */ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP)) enable_audio_dsc_wa(encoder, crtc_state); - if (needs_wa_14020863754(i915)) - intel_de_rmw(i915, AUD_CHICKENBIT_REG3, 0, DACBE_DISABLE_MIN_HBLANK_FIX); + if (needs_wa_14020863754(display)) + intel_de_rmw(display, AUD_CHICKENBIT_REG3, 0, DACBE_DISABLE_MIN_HBLANK_FIX); /* Enable audio presence detect */ - intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD, + intel_de_rmw(display, HSW_AUD_PIN_ELD_CP_VLD, 0, AUDIO_OUTPUT_ENABLE(cpu_transcoder)); intel_crtc_wait_for_next_vblank(crtc); /* Invalidate ELD */ - intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD, + intel_de_rmw(display, HSW_AUD_PIN_ELD_CP_VLD, AUDIO_ELD_VALID(cpu_transcoder), 0); /* @@ -574,18 +574,20 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder, /* Enable timestamps */ hsw_audio_config_update(encoder, crtc_state); - mutex_unlock(&i915->display.audio.mutex); + mutex_unlock(&display->audio.mutex); } struct ibx_audio_regs { i915_reg_t hdmiw_hdmiedid, aud_config, aud_cntl_st, aud_cntrl_st2; }; -static void ibx_audio_regs_init(struct drm_i915_private *i915, +static void ibx_audio_regs_init(struct intel_display *display, enum pipe pipe, struct ibx_audio_regs *regs) { - if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { + struct drm_i915_private *i915 = to_i915(display->drm); + + if (display->platform.valleyview || display->platform.cherryview) { regs->hdmiw_hdmiedid = VLV_HDMIW_HDMIEDID(pipe); regs->aud_config = VLV_AUD_CFG(pipe); regs->aud_cntl_st = VLV_AUD_CNTL_ST(pipe); @@ -607,21 +609,21 @@ static void ibx_audio_codec_disable(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); enum port port = encoder->port; enum pipe pipe = crtc->pipe; struct ibx_audio_regs regs; - if (drm_WARN_ON(&i915->drm, port == PORT_A)) + if (drm_WARN_ON(display->drm, port == PORT_A)) return; - ibx_audio_regs_init(i915, pipe, ®s); + ibx_audio_regs_init(display, pipe, ®s); - mutex_lock(&i915->display.audio.mutex); + mutex_lock(&display->audio.mutex); /* Disable timestamps */ - intel_de_rmw(i915, regs.aud_config, + intel_de_rmw(display, regs.aud_config, AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_UPPER_N_MASK | AUD_CONFIG_LOWER_N_MASK, @@ -630,10 +632,10 @@ static void ibx_audio_codec_disable(struct intel_encoder *encoder, AUD_CONFIG_N_VALUE_INDEX : 0)); /* Invalidate ELD */ - intel_de_rmw(i915, regs.aud_cntrl_st2, + intel_de_rmw(display, regs.aud_cntrl_st2, IBX_ELD_VALID(port), 0); - mutex_unlock(&i915->display.audio.mutex); + mutex_unlock(&display->audio.mutex); intel_crtc_wait_for_next_vblank(crtc); intel_crtc_wait_for_next_vblank(crtc); @@ -643,23 +645,23 @@ static void ibx_audio_codec_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum port port = encoder->port; enum pipe pipe = crtc->pipe; struct ibx_audio_regs regs; - if (drm_WARN_ON(&i915->drm, port == PORT_A)) + if (drm_WARN_ON(display->drm, port == PORT_A)) return; intel_crtc_wait_for_next_vblank(crtc); - ibx_audio_regs_init(i915, pipe, ®s); + ibx_audio_regs_init(display, pipe, ®s); - mutex_lock(&i915->display.audio.mutex); + mutex_lock(&display->audio.mutex); /* Invalidate ELD */ - intel_de_rmw(i915, regs.aud_cntrl_st2, + intel_de_rmw(display, regs.aud_cntrl_st2, IBX_ELD_VALID(port), 0); /* @@ -668,7 +670,7 @@ static void ibx_audio_codec_enable(struct intel_encoder *encoder, */ /* Enable timestamps */ - intel_de_rmw(i915, regs.aud_config, + intel_de_rmw(display, regs.aud_config, AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE | AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, @@ -676,7 +678,7 @@ static void ibx_audio_codec_enable(struct intel_encoder *encoder, AUD_CONFIG_N_VALUE_INDEX : audio_config_hdmi_pixel_clock(crtc_state))); - mutex_unlock(&i915->display.audio.mutex); + mutex_unlock(&display->audio.mutex); } void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state) @@ -693,14 +695,14 @@ bool intel_audio_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct drm_connector *connector = conn_state->connector; const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; mutex_lock(&connector->eld_mutex); if (!connector->eld[0]) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Bogus ELD on [CONNECTOR:%d:%s]\n", connector->base.id, connector->name); mutex_unlock(&connector->eld_mutex); @@ -729,8 +731,9 @@ void intel_audio_codec_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *i915 = to_i915(encoder->base.dev); - struct i915_audio_component *acomp = i915->display.audio.component; + struct i915_audio_component *acomp = display->audio.component; struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_connector *connector = to_intel_connector(conn_state->connector); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; @@ -740,26 +743,27 @@ void intel_audio_codec_enable(struct intel_encoder *encoder, if (!crtc_state->has_audio) return; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s][ENCODER:%d:%s] Enable audio codec on [CRTC:%d:%s], %u bytes ELD\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s][ENCODER:%d:%s] Enable audio codec on [CRTC:%d:%s], %u bytes ELD\n", connector->base.base.id, connector->base.name, encoder->base.base.id, encoder->base.name, crtc->base.base.id, crtc->base.name, drm_eld_size(crtc_state->eld)); - if (i915->display.funcs.audio) - i915->display.funcs.audio->audio_codec_enable(encoder, + if (display->funcs.audio) + display->funcs.audio->audio_codec_enable(encoder, crtc_state, conn_state); - mutex_lock(&i915->display.audio.mutex); + mutex_lock(&display->audio.mutex); - audio_state = &i915->display.audio.state[cpu_transcoder]; + audio_state = &display->audio.state[cpu_transcoder]; audio_state->encoder = encoder; BUILD_BUG_ON(sizeof(audio_state->eld) != sizeof(crtc_state->eld)); memcpy(audio_state->eld, crtc_state->eld, sizeof(audio_state->eld)); - mutex_unlock(&i915->display.audio.mutex); + mutex_unlock(&display->audio.mutex); if (acomp && acomp->base.audio_ops && acomp->base.audio_ops->pin_eld_notify) { @@ -788,8 +792,9 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *i915 = to_i915(encoder->base.dev); - struct i915_audio_component *acomp = i915->display.audio.component; + struct i915_audio_component *acomp = display->audio.component; struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); struct intel_connector *connector = to_intel_connector(old_conn_state->connector); enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; @@ -799,24 +804,25 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, if (!old_crtc_state->has_audio) return; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s][ENCODER:%d:%s] Disable audio codec on [CRTC:%d:%s]\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s][ENCODER:%d:%s] Disable audio codec on [CRTC:%d:%s]\n", connector->base.base.id, connector->base.name, encoder->base.base.id, encoder->base.name, crtc->base.base.id, crtc->base.name); - if (i915->display.funcs.audio) - i915->display.funcs.audio->audio_codec_disable(encoder, + if (display->funcs.audio) + display->funcs.audio->audio_codec_disable(encoder, old_crtc_state, old_conn_state); - mutex_lock(&i915->display.audio.mutex); + mutex_lock(&display->audio.mutex); - audio_state = &i915->display.audio.state[cpu_transcoder]; + audio_state = &display->audio.state[cpu_transcoder]; audio_state->encoder = NULL; memset(audio_state->eld, 0, sizeof(audio_state->eld)); - mutex_unlock(&i915->display.audio.mutex); + mutex_unlock(&display->audio.mutex); if (acomp && acomp->base.audio_ops && acomp->base.audio_ops->pin_eld_notify) { @@ -833,30 +839,30 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, static void intel_acomp_get_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; struct intel_audio_state *audio_state; - mutex_lock(&i915->display.audio.mutex); + mutex_lock(&display->audio.mutex); - audio_state = &i915->display.audio.state[cpu_transcoder]; + audio_state = &display->audio.state[cpu_transcoder]; if (audio_state->encoder) memcpy(crtc_state->eld, audio_state->eld, sizeof(audio_state->eld)); - mutex_unlock(&i915->display.audio.mutex); + mutex_unlock(&display->audio.mutex); } void intel_audio_codec_get_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); if (!crtc_state->has_audio) return; - if (i915->display.funcs.audio) - i915->display.funcs.audio->audio_codec_get_config(encoder, crtc_state); + if (display->funcs.audio) + display->funcs.audio->audio_codec_get_config(encoder, crtc_state); } static const struct intel_audio_funcs g4x_audio_funcs = { @@ -879,17 +885,19 @@ static const struct intel_audio_funcs hsw_audio_funcs = { /** * intel_audio_hooks_init - Set up chip specific audio hooks - * @i915: device private + * @display: display device */ -void intel_audio_hooks_init(struct drm_i915_private *i915) +void intel_audio_hooks_init(struct intel_display *display) { - if (IS_G4X(i915)) - i915->display.funcs.audio = &g4x_audio_funcs; - else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915) || + struct drm_i915_private *i915 = to_i915(display->drm); + + if (display->platform.g4x) + display->funcs.audio = &g4x_audio_funcs; + else if (display->platform.valleyview || display->platform.cherryview || HAS_PCH_CPT(i915) || HAS_PCH_IBX(i915)) - i915->display.funcs.audio = &ibx_audio_funcs; - else if (IS_HASWELL(i915) || DISPLAY_VER(i915) >= 8) - i915->display.funcs.audio = &hsw_audio_funcs; + display->funcs.audio = &ibx_audio_funcs; + else if (display->platform.haswell || DISPLAY_VER(display) >= 8) + display->funcs.audio = &hsw_audio_funcs; } struct aud_ts_cdclk_m_n { @@ -897,10 +905,10 @@ struct aud_ts_cdclk_m_n { u16 n; }; -void intel_audio_cdclk_change_pre(struct drm_i915_private *i915) +void intel_audio_cdclk_change_pre(struct intel_display *display) { - if (DISPLAY_VER(i915) >= 13) - intel_de_rmw(i915, AUD_TS_CDCLK_M, AUD_TS_CDCLK_M_EN, 0); + if (DISPLAY_VER(display) >= 13) + intel_de_rmw(display, AUD_TS_CDCLK_M, AUD_TS_CDCLK_M_EN, 0); } static void get_aud_ts_cdclk_m_n(int refclk, int cdclk, struct aud_ts_cdclk_m_n *aud_ts) @@ -909,16 +917,18 @@ static void get_aud_ts_cdclk_m_n(int refclk, int cdclk, struct aud_ts_cdclk_m_n aud_ts->n = cdclk * aud_ts->m / 24000; } -void intel_audio_cdclk_change_post(struct drm_i915_private *i915) +void intel_audio_cdclk_change_post(struct intel_display *display) { struct aud_ts_cdclk_m_n aud_ts; - if (DISPLAY_VER(i915) >= 13) { - get_aud_ts_cdclk_m_n(i915->display.cdclk.hw.ref, i915->display.cdclk.hw.cdclk, &aud_ts); + if (DISPLAY_VER(display) >= 13) { + get_aud_ts_cdclk_m_n(display->cdclk.hw.ref, + display->cdclk.hw.cdclk, &aud_ts); - intel_de_write(i915, AUD_TS_CDCLK_N, aud_ts.n); - intel_de_write(i915, AUD_TS_CDCLK_M, aud_ts.m | AUD_TS_CDCLK_M_EN); - drm_dbg_kms(&i915->drm, "aud_ts_cdclk set to M=%u, N=%u\n", aud_ts.m, aud_ts.n); + intel_de_write(display, AUD_TS_CDCLK_N, aud_ts.n); + intel_de_write(display, AUD_TS_CDCLK_M, aud_ts.m | AUD_TS_CDCLK_M_EN); + drm_dbg_kms(display->drm, "aud_ts_cdclk set to M=%u, N=%u\n", + aud_ts.m, aud_ts.n); } } @@ -943,9 +953,10 @@ static int glk_force_audio_cdclk_commit(struct intel_atomic_state *state, return drm_atomic_commit(&state->base); } -static void glk_force_audio_cdclk(struct drm_i915_private *i915, +static void glk_force_audio_cdclk(struct intel_display *display, bool enable) { + struct drm_i915_private *i915 = to_i915(display->drm); struct drm_modeset_acquire_ctx ctx; struct drm_atomic_state *state; struct intel_crtc *crtc; @@ -956,8 +967,8 @@ static void glk_force_audio_cdclk(struct drm_i915_private *i915, return; drm_modeset_acquire_init(&ctx, 0); - state = drm_atomic_state_alloc(&i915->drm); - if (drm_WARN_ON(&i915->drm, !state)) + state = drm_atomic_state_alloc(display->drm); + if (drm_WARN_ON(display->drm, !state)) return; state->acquire_ctx = &ctx; @@ -972,7 +983,7 @@ static void glk_force_audio_cdclk(struct drm_i915_private *i915, goto retry; } - drm_WARN_ON(&i915->drm, ret); + drm_WARN_ON(display->drm, ret); drm_atomic_state_put(state); @@ -983,7 +994,6 @@ static void glk_force_audio_cdclk(struct drm_i915_private *i915, int intel_audio_min_cdclk(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *dev_priv = to_i915(display->drm); int min_cdclk = 0; if (!crtc_state->has_audio) @@ -1000,7 +1010,7 @@ int intel_audio_min_cdclk(const struct intel_crtc_state *crtc_state) if (DISPLAY_VER(display) == 10) { /* Display WA #1145: glk */ min_cdclk = max(min_cdclk, 316800); - } else if (DISPLAY_VER(display) == 9 || IS_BROADWELL(dev_priv)) { + } else if (DISPLAY_VER(display) == 9 || display->platform.broadwell) { /* Display WA #1144: skl,bxt */ min_cdclk = max(min_cdclk, 432000); } @@ -1020,7 +1030,7 @@ int intel_audio_min_cdclk(const struct intel_crtc_state *crtc_state) * 270 | 320 or higher * 162 | 200 or higher" */ - if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && + if ((display->platform.valleyview || display->platform.cherryview) && intel_crtc_has_dp_encoder(crtc_state)) min_cdclk = max(min_cdclk, crtc_state->port_clock); @@ -1038,21 +1048,21 @@ static unsigned long i915_audio_component_get_power(struct device *kdev) wakeref = intel_display_power_get(i915, POWER_DOMAIN_AUDIO_PLAYBACK); - if (i915->display.audio.power_refcount++ == 0) { - if (DISPLAY_VER(i915) >= 9) { - intel_de_write(i915, AUD_FREQ_CNTRL, - i915->display.audio.freq_cntrl); - drm_dbg_kms(&i915->drm, + if (display->audio.power_refcount++ == 0) { + if (DISPLAY_VER(display) >= 9) { + intel_de_write(display, AUD_FREQ_CNTRL, + display->audio.freq_cntrl); + drm_dbg_kms(display->drm, "restored AUD_FREQ_CNTRL to 0x%x\n", - i915->display.audio.freq_cntrl); + display->audio.freq_cntrl); } /* Force CDCLK to 2*BCLK as long as we need audio powered. */ - if (IS_GEMINILAKE(i915)) - glk_force_audio_cdclk(i915, true); + if (display->platform.geminilake) + glk_force_audio_cdclk(display, true); - if (DISPLAY_VER(i915) >= 10) - intel_de_rmw(i915, AUD_PIN_BUF_CTL, + if (DISPLAY_VER(display) >= 10) + intel_de_rmw(display, AUD_PIN_BUF_CTL, 0, AUD_PIN_BUF_ENABLE); } @@ -1067,9 +1077,9 @@ static void i915_audio_component_put_power(struct device *kdev, intel_wakeref_t wakeref = (intel_wakeref_t)cookie; /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */ - if (--i915->display.audio.power_refcount == 0) - if (IS_GEMINILAKE(i915)) - glk_force_audio_cdclk(i915, false); + if (--display->audio.power_refcount == 0) + if (display->platform.geminilake) + glk_force_audio_cdclk(display, false); intel_display_power_put(i915, POWER_DOMAIN_AUDIO_PLAYBACK, wakeref); } @@ -1078,10 +1088,9 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, bool enable) { struct intel_display *display = to_intel_display(kdev); - struct drm_i915_private *i915 = to_i915(display->drm); unsigned long cookie; - if (DISPLAY_VER(i915) < 9) + if (DISPLAY_VER(display) < 9) return; cookie = i915_audio_component_get_power(kdev); @@ -1090,12 +1099,12 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, * Enable/disable generating the codec wake signal, overriding the * internal logic to generate the codec wake to controller. */ - intel_de_rmw(i915, HSW_AUD_CHICKENBIT, + intel_de_rmw(display, HSW_AUD_CHICKENBIT, SKL_AUD_CODEC_WAKE_SIGNAL, 0); usleep_range(1000, 1500); if (enable) { - intel_de_rmw(i915, HSW_AUD_CHICKENBIT, + intel_de_rmw(display, HSW_AUD_CHICKENBIT, 0, SKL_AUD_CODEC_WAKE_SIGNAL); usleep_range(1000, 1500); } @@ -1107,12 +1116,11 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, static int i915_audio_component_get_cdclk_freq(struct device *kdev) { struct intel_display *display = to_intel_display(kdev); - struct drm_i915_private *i915 = to_i915(display->drm); - if (drm_WARN_ON_ONCE(&i915->drm, !HAS_DDI(i915))) + if (drm_WARN_ON_ONCE(display->drm, !HAS_DDI(display))) return -ENODEV; - return i915->display.cdclk.hw.cdclk; + return display->cdclk.hw.cdclk; } /* @@ -1124,7 +1132,7 @@ static int i915_audio_component_get_cdclk_freq(struct device *kdev) * will get the right intel_encoder with port matched * Non-MST & (cpu_transcoder < 0): get the right intel_encoder with port matched */ -static struct intel_audio_state *find_audio_state(struct drm_i915_private *i915, +static struct intel_audio_state *find_audio_state(struct intel_display *display, int port, int cpu_transcoder) { /* MST */ @@ -1132,11 +1140,11 @@ static struct intel_audio_state *find_audio_state(struct drm_i915_private *i915, struct intel_audio_state *audio_state; struct intel_encoder *encoder; - if (drm_WARN_ON(&i915->drm, - cpu_transcoder >= ARRAY_SIZE(i915->display.audio.state))) + if (drm_WARN_ON(display->drm, + cpu_transcoder >= ARRAY_SIZE(display->audio.state))) return NULL; - audio_state = &i915->display.audio.state[cpu_transcoder]; + audio_state = &display->audio.state[cpu_transcoder]; encoder = audio_state->encoder; if (encoder && encoder->port == port && @@ -1148,11 +1156,11 @@ static struct intel_audio_state *find_audio_state(struct drm_i915_private *i915, if (cpu_transcoder > 0) return NULL; - for_each_cpu_transcoder(i915, cpu_transcoder) { + for_each_cpu_transcoder(display, cpu_transcoder) { struct intel_audio_state *audio_state; struct intel_encoder *encoder; - audio_state = &i915->display.audio.state[cpu_transcoder]; + audio_state = &display->audio.state[cpu_transcoder]; encoder = audio_state->encoder; if (encoder && encoder->port == port && @@ -1167,23 +1175,23 @@ static int i915_audio_component_sync_audio_rate(struct device *kdev, int port, int cpu_transcoder, int rate) { struct intel_display *display = to_intel_display(kdev); - struct drm_i915_private *i915 = to_i915(display->drm); - struct i915_audio_component *acomp = i915->display.audio.component; + struct i915_audio_component *acomp = display->audio.component; const struct intel_audio_state *audio_state; struct intel_encoder *encoder; struct intel_crtc *crtc; unsigned long cookie; int err = 0; - if (!HAS_DDI(i915)) + if (!HAS_DDI(display)) return 0; cookie = i915_audio_component_get_power(kdev); - mutex_lock(&i915->display.audio.mutex); + mutex_lock(&display->audio.mutex); - audio_state = find_audio_state(i915, port, cpu_transcoder); + audio_state = find_audio_state(display, port, cpu_transcoder); if (!audio_state) { - drm_dbg_kms(&i915->drm, "Not valid for port %c\n", port_name(port)); + drm_dbg_kms(display->drm, "Not valid for port %c\n", + port_name(port)); err = -ENODEV; goto unlock; } @@ -1200,7 +1208,7 @@ static int i915_audio_component_sync_audio_rate(struct device *kdev, int port, hsw_audio_config_update(encoder, crtc->config); unlock: - mutex_unlock(&i915->display.audio.mutex); + mutex_unlock(&display->audio.mutex); i915_audio_component_put_power(kdev, cookie); return err; } @@ -1210,16 +1218,16 @@ static int i915_audio_component_get_eld(struct device *kdev, int port, unsigned char *buf, int max_bytes) { struct intel_display *display = to_intel_display(kdev); - struct drm_i915_private *i915 = to_i915(display->drm); const struct intel_audio_state *audio_state; int ret = 0; - mutex_lock(&i915->display.audio.mutex); + mutex_lock(&display->audio.mutex); - audio_state = find_audio_state(i915, port, cpu_transcoder); + audio_state = find_audio_state(display, port, cpu_transcoder); if (!audio_state) { - drm_dbg_kms(&i915->drm, "Not valid for port %c\n", port_name(port)); - mutex_unlock(&i915->display.audio.mutex); + drm_dbg_kms(display->drm, "Not valid for port %c\n", + port_name(port)); + mutex_unlock(&display->audio.mutex); return -EINVAL; } @@ -1231,7 +1239,7 @@ static int i915_audio_component_get_eld(struct device *kdev, int port, memcpy(buf, eld, min(max_bytes, ret)); } - mutex_unlock(&i915->display.audio.mutex); + mutex_unlock(&display->audio.mutex); return ret; } @@ -1249,26 +1257,25 @@ static int i915_audio_component_bind(struct device *drv_kdev, struct device *hda_kdev, void *data) { struct intel_display *display = to_intel_display(drv_kdev); - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_audio_component *acomp = data; int i; - if (drm_WARN_ON(&i915->drm, acomp->base.ops || acomp->base.dev)) + if (drm_WARN_ON(display->drm, acomp->base.ops || acomp->base.dev)) return -EEXIST; - if (drm_WARN_ON(&i915->drm, + if (drm_WARN_ON(display->drm, !device_link_add(hda_kdev, drv_kdev, DL_FLAG_STATELESS))) return -ENOMEM; - drm_modeset_lock_all(&i915->drm); + drm_modeset_lock_all(display->drm); acomp->base.ops = &i915_audio_component_ops; acomp->base.dev = drv_kdev; BUILD_BUG_ON(MAX_PORTS != I915_MAX_PORTS); for (i = 0; i < ARRAY_SIZE(acomp->aud_sample_rate); i++) acomp->aud_sample_rate[i] = 0; - i915->display.audio.component = acomp; - drm_modeset_unlock_all(&i915->drm); + display->audio.component = acomp; + drm_modeset_unlock_all(display->drm); return 0; } @@ -1277,20 +1284,20 @@ static void i915_audio_component_unbind(struct device *drv_kdev, struct device *hda_kdev, void *data) { struct intel_display *display = to_intel_display(drv_kdev); - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_audio_component *acomp = data; - drm_modeset_lock_all(&i915->drm); + drm_modeset_lock_all(display->drm); acomp->base.ops = NULL; acomp->base.dev = NULL; - i915->display.audio.component = NULL; - drm_modeset_unlock_all(&i915->drm); + display->audio.component = NULL; + drm_modeset_unlock_all(display->drm); device_link_remove(hda_kdev, drv_kdev); - if (i915->display.audio.power_refcount) - drm_err(&i915->drm, "audio power refcount %d after unbind\n", - i915->display.audio.power_refcount); + if (display->audio.power_refcount) + drm_err(display->drm, + "audio power refcount %d after unbind\n", + display->audio.power_refcount); } static const struct component_ops i915_audio_component_bind_ops = { @@ -1309,7 +1316,7 @@ static const struct component_ops i915_audio_component_bind_ops = { /** * i915_audio_component_init - initialize and register the audio component - * @i915: i915 device instance + * @display: display device * * This will register with the component framework a child component which * will bind dynamically to the snd_hda_intel driver's corresponding master @@ -1323,93 +1330,97 @@ static const struct component_ops i915_audio_component_bind_ops = { * We ignore any error during registration and continue with reduced * functionality (i.e. without HDMI audio). */ -static void i915_audio_component_init(struct drm_i915_private *i915) +static void i915_audio_component_init(struct intel_display *display) { u32 aud_freq, aud_freq_init; - if (DISPLAY_VER(i915) >= 9) { - aud_freq_init = intel_de_read(i915, AUD_FREQ_CNTRL); + if (DISPLAY_VER(display) >= 9) { + aud_freq_init = intel_de_read(display, AUD_FREQ_CNTRL); - if (DISPLAY_VER(i915) >= 12) + if (DISPLAY_VER(display) >= 12) aud_freq = AUD_FREQ_GEN12; else aud_freq = aud_freq_init; /* use BIOS provided value for TGL and RKL unless it is a known bad value */ - if ((IS_TIGERLAKE(i915) || IS_ROCKETLAKE(i915)) && + if ((display->platform.tigerlake || display->platform.rocketlake) && aud_freq_init != AUD_FREQ_TGL_BROKEN) aud_freq = aud_freq_init; - drm_dbg_kms(&i915->drm, "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n", + drm_dbg_kms(display->drm, + "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n", aud_freq, aud_freq_init); - i915->display.audio.freq_cntrl = aud_freq; + display->audio.freq_cntrl = aud_freq; } /* init with current cdclk */ - intel_audio_cdclk_change_post(i915); + intel_audio_cdclk_change_post(display); } -static void i915_audio_component_register(struct drm_i915_private *i915) +static void i915_audio_component_register(struct intel_display *display) { int ret; - ret = component_add_typed(i915->drm.dev, + ret = component_add_typed(display->drm->dev, &i915_audio_component_bind_ops, I915_COMPONENT_AUDIO); if (ret < 0) { - drm_err(&i915->drm, + drm_err(display->drm, "failed to add audio component (%d)\n", ret); /* continue with reduced functionality */ return; } - i915->display.audio.component_registered = true; + display->audio.component_registered = true; } /** * i915_audio_component_cleanup - deregister the audio component - * @i915: i915 device instance + * @display: display device * * Deregisters the audio component, breaking any existing binding to the * corresponding snd_hda_intel driver's master component. */ -static void i915_audio_component_cleanup(struct drm_i915_private *i915) +static void i915_audio_component_cleanup(struct intel_display *display) { - if (!i915->display.audio.component_registered) + if (!display->audio.component_registered) return; - component_del(i915->drm.dev, &i915_audio_component_bind_ops); - i915->display.audio.component_registered = false; + component_del(display->drm->dev, &i915_audio_component_bind_ops); + display->audio.component_registered = false; } /** * intel_audio_init() - Initialize the audio driver either using * component framework or using lpe audio bridge - * @i915: the i915 drm device private data + * @display: display device * */ -void intel_audio_init(struct drm_i915_private *i915) +void intel_audio_init(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); + if (intel_lpe_audio_init(i915) < 0) - i915_audio_component_init(i915); + i915_audio_component_init(display); } -void intel_audio_register(struct drm_i915_private *i915) +void intel_audio_register(struct intel_display *display) { - if (!i915->display.audio.lpe.platdev) - i915_audio_component_register(i915); + if (!display->audio.lpe.platdev) + i915_audio_component_register(display); } /** * intel_audio_deinit() - deinitialize the audio driver - * @i915: the i915 drm device private data - * + * @display: display device */ -void intel_audio_deinit(struct drm_i915_private *i915) +void intel_audio_deinit(struct intel_display *display) { - if (i915->display.audio.lpe.platdev != NULL) + struct drm_i915_private *i915 = to_i915(display->drm); + + if (display->audio.lpe.platdev) intel_lpe_audio_teardown(i915); else - i915_audio_component_cleanup(i915); + i915_audio_component_cleanup(display); } diff --git a/drivers/gpu/drm/i915/display/intel_audio.h b/drivers/gpu/drm/i915/display/intel_audio.h index 1bafc155434a9..ad49eefa7182c 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.h +++ b/drivers/gpu/drm/i915/display/intel_audio.h @@ -9,11 +9,11 @@ #include struct drm_connector_state; -struct drm_i915_private; struct intel_crtc_state; +struct intel_display; struct intel_encoder; -void intel_audio_hooks_init(struct drm_i915_private *dev_priv); +void intel_audio_hooks_init(struct intel_display *display); bool intel_audio_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state); @@ -25,12 +25,12 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, const struct drm_connector_state *old_conn_state); void intel_audio_codec_get_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state); -void intel_audio_cdclk_change_pre(struct drm_i915_private *dev_priv); -void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv); +void intel_audio_cdclk_change_pre(struct intel_display *display); +void intel_audio_cdclk_change_post(struct intel_display *display); int intel_audio_min_cdclk(const struct intel_crtc_state *crtc_state); -void intel_audio_init(struct drm_i915_private *dev_priv); -void intel_audio_register(struct drm_i915_private *i915); -void intel_audio_deinit(struct drm_i915_private *dev_priv); +void intel_audio_init(struct intel_display *display); +void intel_audio_register(struct intel_display *display); +void intel_audio_deinit(struct intel_display *display); void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state); #endif /* __INTEL_AUDIO_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index c7a603589412b..bee90b06995ab 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2521,7 +2521,6 @@ static void intel_set_cdclk(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe, const char *context) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder; if (!intel_cdclk_changed(&display->cdclk.hw, cdclk_config)) @@ -2538,7 +2537,7 @@ static void intel_set_cdclk(struct intel_display *display, intel_psr_pause(intel_dp); } - intel_audio_cdclk_change_pre(dev_priv); + intel_audio_cdclk_change_pre(display); /* * Lock aux/gmbus while we change cdclk in case those @@ -2568,7 +2567,7 @@ static void intel_set_cdclk(struct intel_display *display, intel_psr_resume(intel_dp); } - intel_audio_cdclk_change_post(dev_priv); + intel_audio_cdclk_change_post(display); if (drm_WARN(display->drm, intel_cdclk_changed(&display->cdclk.hw, cdclk_config), diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 1aa0b298c278d..73ea0e906014e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -197,7 +197,7 @@ void intel_display_driver_early_probe(struct intel_display *display) intel_dkl_phy_init(i915); intel_color_init_hooks(display); intel_init_cdclk_hooks(display); - intel_audio_hooks_init(i915); + intel_audio_hooks_init(display); intel_dpll_init_clock_hook(i915); intel_init_display_hooks(i915); intel_fdi_init_hook(i915); @@ -546,11 +546,11 @@ void intel_display_driver_register(struct intel_display *display) intel_opregion_register(display); intel_acpi_video_register(display); - intel_audio_init(i915); + intel_audio_init(display); intel_display_driver_enable_user_access(display); - intel_audio_register(i915); + intel_audio_register(display); intel_display_debugfs_register(i915); @@ -638,8 +638,6 @@ void intel_display_driver_remove_nogem(struct intel_display *display) void intel_display_driver_unregister(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (!HAS_DISPLAY(display)) return; @@ -654,7 +652,7 @@ void intel_display_driver_unregister(struct intel_display *display) intel_display_driver_disable_user_access(display); - intel_audio_deinit(i915); + intel_audio_deinit(display); drm_atomic_helper_shutdown(display->drm); diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index b3921dbc52ff6..96ba9595bf2ac 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -216,7 +216,7 @@ void xe_display_fini(struct xe_device *xe) intel_hpd_poll_fini(xe); intel_hdcp_component_fini(display); - intel_audio_deinit(xe); + intel_audio_deinit(display); } void xe_display_register(struct xe_device *xe) From 2b85c4feeeb73984dc676f7fdbcff71e82a1dbab Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 8 Jan 2025 16:04:14 +0200 Subject: [PATCH 025/284] drm/i915/audio: convert LPE audio to struct intel_display Going forward, struct intel_display will be the main display device structure. Convert intel_lpe_audio.[ch] to it. Do some minor checkpatch fixes while at it. TODO: Not sure if irq_set_chip_data(irq, dev_priv); is used. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/f04dd028cd8869cdfb9ab9eb6aceed8ff8e7ddcd.1736345025.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_audio.c | 14 +-- .../gpu/drm/i915/display/intel_lpe_audio.c | 118 +++++++++--------- .../gpu/drm/i915/display/intel_lpe_audio.h | 18 +-- drivers/gpu/drm/i915/i915_irq.c | 6 +- 4 files changed, 77 insertions(+), 79 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 8c26e0e7c2cd6..241e5d3904dca 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -732,7 +732,6 @@ void intel_audio_codec_enable(struct intel_encoder *encoder, const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct i915_audio_component *acomp = display->audio.component; struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_connector *connector = to_intel_connector(conn_state->connector); @@ -774,7 +773,7 @@ void intel_audio_codec_enable(struct intel_encoder *encoder, (int)port, (int)cpu_transcoder); } - intel_lpe_audio_notify(i915, cpu_transcoder, port, crtc_state->eld, + intel_lpe_audio_notify(display, cpu_transcoder, port, crtc_state->eld, crtc_state->port_clock, intel_crtc_has_dp_encoder(crtc_state)); } @@ -793,7 +792,6 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, const struct drm_connector_state *old_conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct i915_audio_component *acomp = display->audio.component; struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); struct intel_connector *connector = to_intel_connector(old_conn_state->connector); @@ -833,7 +831,7 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, (int)port, (int)cpu_transcoder); } - intel_lpe_audio_notify(i915, cpu_transcoder, port, NULL, 0, false); + intel_lpe_audio_notify(display, cpu_transcoder, port, NULL, 0, false); } static void intel_acomp_get_config(struct intel_encoder *encoder, @@ -1399,9 +1397,7 @@ static void i915_audio_component_cleanup(struct intel_display *display) */ void intel_audio_init(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (intel_lpe_audio_init(i915) < 0) + if (intel_lpe_audio_init(display) < 0) i915_audio_component_init(display); } @@ -1417,10 +1413,8 @@ void intel_audio_register(struct intel_display *display) */ void intel_audio_deinit(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (display->audio.lpe.platdev) - intel_lpe_audio_teardown(i915); + intel_lpe_audio_teardown(display); else i915_audio_component_cleanup(display); } diff --git a/drivers/gpu/drm/i915/display/intel_lpe_audio.c b/drivers/gpu/drm/i915/display/intel_lpe_audio.c index f11626176fe2c..59551c8414c2d 100644 --- a/drivers/gpu/drm/i915/display/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/display/intel_lpe_audio.c @@ -77,12 +77,12 @@ #include "intel_lpe_audio.h" #include "intel_pci_config.h" -#define HAS_LPE_AUDIO(dev_priv) ((dev_priv)->display.audio.lpe.platdev != NULL) +#define HAS_LPE_AUDIO(display) ((display)->audio.lpe.platdev) static struct platform_device * -lpe_audio_platdev_create(struct drm_i915_private *dev_priv) +lpe_audio_platdev_create(struct intel_display *display) { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); struct platform_device_info pinfo = {}; struct resource *rsc; struct platform_device *platdev; @@ -98,7 +98,8 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv) return ERR_PTR(-ENOMEM); } - rsc[0].start = rsc[0].end = dev_priv->display.audio.lpe.irq; + rsc[0].start = display->audio.lpe.irq; + rsc[0].end = display->audio.lpe.irq; rsc[0].flags = IORESOURCE_IRQ; rsc[0].name = "hdmi-lpe-audio-irq"; @@ -109,7 +110,7 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv) rsc[1].flags = IORESOURCE_MEM; rsc[1].name = "hdmi-lpe-audio-mmio"; - pinfo.parent = dev_priv->drm.dev; + pinfo.parent = display->drm->dev; pinfo.name = "hdmi-lpe-audio"; pinfo.id = -1; pinfo.res = rsc; @@ -118,8 +119,8 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv) pinfo.size_data = sizeof(*pdata); pinfo.dma_mask = DMA_BIT_MASK(32); - pdata->num_pipes = INTEL_NUM_PIPES(dev_priv); - pdata->num_ports = IS_CHERRYVIEW(dev_priv) ? 3 : 2; /* B,C,D or B,C */ + pdata->num_pipes = INTEL_NUM_PIPES(display); + pdata->num_ports = display->platform.cherryview ? 3 : 2; /* B,C,D or B,C */ pdata->port[0].pipe = -1; pdata->port[1].pipe = -1; pdata->port[2].pipe = -1; @@ -130,7 +131,7 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv) kfree(pdata); if (IS_ERR(platdev)) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Failed to allocate LPE audio platform device\n"); return platdev; } @@ -140,7 +141,7 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv) return platdev; } -static void lpe_audio_platdev_destroy(struct drm_i915_private *dev_priv) +static void lpe_audio_platdev_destroy(struct intel_display *display) { /* XXX Note that platform_device_register_full() allocates a dma_mask * and never frees it. We can't free it here as we cannot guarantee @@ -150,7 +151,7 @@ static void lpe_audio_platdev_destroy(struct drm_i915_private *dev_priv) * than us fiddle with its internals. */ - platform_device_unregister(dev_priv->display.audio.lpe.platdev); + platform_device_unregister(display->audio.lpe.platdev); } static void lpe_audio_irq_unmask(struct irq_data *d) @@ -167,11 +168,12 @@ static struct irq_chip lpe_audio_irqchip = { .irq_unmask = lpe_audio_irq_unmask, }; -static int lpe_audio_irq_init(struct drm_i915_private *dev_priv) +static int lpe_audio_irq_init(struct intel_display *display) { - int irq = dev_priv->display.audio.lpe.irq; + struct drm_i915_private *dev_priv = to_i915(display->drm); + int irq = display->audio.lpe.irq; - drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv)); + drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv)); irq_set_chip_and_handler_name(irq, &lpe_audio_irqchip, handle_simple_irq, @@ -180,11 +182,11 @@ static int lpe_audio_irq_init(struct drm_i915_private *dev_priv) return irq_set_chip_data(irq, dev_priv); } -static bool lpe_audio_detect(struct drm_i915_private *dev_priv) +static bool lpe_audio_detect(struct intel_display *display) { int lpe_present = false; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (display->platform.valleyview || display->platform.cherryview) { static const struct pci_device_id atom_hdaudio_ids[] = { /* Baytrail */ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0f04)}, @@ -194,7 +196,7 @@ static bool lpe_audio_detect(struct drm_i915_private *dev_priv) }; if (!pci_dev_present(atom_hdaudio_ids)) { - drm_info(&dev_priv->drm, + drm_info(display->drm, "HDaudio controller not detected, using LPE audio instead\n"); lpe_present = true; } @@ -202,34 +204,34 @@ static bool lpe_audio_detect(struct drm_i915_private *dev_priv) return lpe_present; } -static int lpe_audio_setup(struct drm_i915_private *dev_priv) +static int lpe_audio_setup(struct intel_display *display) { int ret; - dev_priv->display.audio.lpe.irq = irq_alloc_desc(0); - if (dev_priv->display.audio.lpe.irq < 0) { - drm_err(&dev_priv->drm, "Failed to allocate IRQ desc: %d\n", - dev_priv->display.audio.lpe.irq); - ret = dev_priv->display.audio.lpe.irq; + display->audio.lpe.irq = irq_alloc_desc(0); + if (display->audio.lpe.irq < 0) { + drm_err(display->drm, "Failed to allocate IRQ desc: %d\n", + display->audio.lpe.irq); + ret = display->audio.lpe.irq; goto err; } - drm_dbg(&dev_priv->drm, "irq = %d\n", dev_priv->display.audio.lpe.irq); + drm_dbg(display->drm, "irq = %d\n", display->audio.lpe.irq); - ret = lpe_audio_irq_init(dev_priv); + ret = lpe_audio_irq_init(display); if (ret) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Failed to initialize irqchip for lpe audio: %d\n", ret); goto err_free_irq; } - dev_priv->display.audio.lpe.platdev = lpe_audio_platdev_create(dev_priv); + display->audio.lpe.platdev = lpe_audio_platdev_create(display); - if (IS_ERR(dev_priv->display.audio.lpe.platdev)) { - ret = PTR_ERR(dev_priv->display.audio.lpe.platdev); - drm_err(&dev_priv->drm, + if (IS_ERR(display->audio.lpe.platdev)) { + ret = PTR_ERR(display->audio.lpe.platdev); + drm_err(display->drm, "Failed to create lpe audio platform device: %d\n", ret); goto err_free_irq; @@ -238,54 +240,54 @@ static int lpe_audio_setup(struct drm_i915_private *dev_priv) /* enable chicken bit; at least this is required for Dell Wyse 3040 * with DP outputs (but only sometimes by some reason!) */ - intel_de_write(dev_priv, VLV_AUD_CHICKEN_BIT_REG, + intel_de_write(display, VLV_AUD_CHICKEN_BIT_REG, VLV_CHICKEN_BIT_DBG_ENABLE); return 0; err_free_irq: - irq_free_desc(dev_priv->display.audio.lpe.irq); + irq_free_desc(display->audio.lpe.irq); err: - dev_priv->display.audio.lpe.irq = -1; - dev_priv->display.audio.lpe.platdev = NULL; + display->audio.lpe.irq = -1; + display->audio.lpe.platdev = NULL; return ret; } /** * intel_lpe_audio_irq_handler() - forwards the LPE audio irq - * @dev_priv: the i915 drm device private data + * @display: display device * * the LPE Audio irq is forwarded to the irq handler registered by LPE audio * driver. */ -void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv) +void intel_lpe_audio_irq_handler(struct intel_display *display) { int ret; - if (!HAS_LPE_AUDIO(dev_priv)) + if (!HAS_LPE_AUDIO(display)) return; - ret = generic_handle_irq(dev_priv->display.audio.lpe.irq); + ret = generic_handle_irq(display->audio.lpe.irq); if (ret) - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "error handling LPE audio irq: %d\n", ret); } /** * intel_lpe_audio_init() - detect and setup the bridge between HDMI LPE Audio * driver and i915 - * @dev_priv: the i915 drm device private data + * @display: display device * * Return: 0 if successful. non-zero if detection or * llocation/initialization fails */ -int intel_lpe_audio_init(struct drm_i915_private *dev_priv) +int intel_lpe_audio_init(struct intel_display *display) { int ret = -ENODEV; - if (lpe_audio_detect(dev_priv)) { - ret = lpe_audio_setup(dev_priv); + if (lpe_audio_detect(display)) { + ret = lpe_audio_setup(display); if (ret < 0) - drm_err(&dev_priv->drm, + drm_err(display->drm, "failed to setup LPE Audio bridge\n"); } return ret; @@ -294,27 +296,27 @@ int intel_lpe_audio_init(struct drm_i915_private *dev_priv) /** * intel_lpe_audio_teardown() - destroy the bridge between HDMI LPE * audio driver and i915 - * @dev_priv: the i915 drm device private data + * @display: display device * * release all the resources for LPE audio <-> i915 bridge. */ -void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv) +void intel_lpe_audio_teardown(struct intel_display *display) { - if (!HAS_LPE_AUDIO(dev_priv)) + if (!HAS_LPE_AUDIO(display)) return; - lpe_audio_platdev_destroy(dev_priv); + lpe_audio_platdev_destroy(display); - irq_free_desc(dev_priv->display.audio.lpe.irq); + irq_free_desc(display->audio.lpe.irq); - dev_priv->display.audio.lpe.irq = -1; - dev_priv->display.audio.lpe.platdev = NULL; + display->audio.lpe.irq = -1; + display->audio.lpe.platdev = NULL; } /** * intel_lpe_audio_notify() - notify lpe audio event * audio driver and i915 - * @dev_priv: the i915 drm device private data + * @display: display device * @cpu_transcoder: CPU transcoder * @port: port * @eld : ELD data @@ -323,7 +325,7 @@ void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv) * * Notify lpe audio driver of eld change. */ -void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, +void intel_lpe_audio_notify(struct intel_display *display, enum transcoder cpu_transcoder, enum port port, const void *eld, int ls_clock, bool dp_output) { @@ -332,15 +334,15 @@ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, struct intel_hdmi_lpe_audio_port_pdata *ppdata; u32 audio_enable; - if (!HAS_LPE_AUDIO(dev_priv)) + if (!HAS_LPE_AUDIO(display)) return; - pdata = dev_get_platdata(&dev_priv->display.audio.lpe.platdev->dev); + pdata = dev_get_platdata(&display->audio.lpe.platdev->dev); ppdata = &pdata->port[port - PORT_B]; spin_lock_irqsave(&pdata->lpe_audio_slock, irqflags); - audio_enable = intel_de_read(dev_priv, VLV_AUD_PORT_EN_DBG(port)); + audio_enable = intel_de_read(display, VLV_AUD_PORT_EN_DBG(port)); if (eld != NULL) { memcpy(ppdata->eld, eld, HDMI_MAX_ELD_BYTES); @@ -349,7 +351,7 @@ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, ppdata->dp_output = dp_output; /* Unmute the amp for both DP and HDMI */ - intel_de_write(dev_priv, VLV_AUD_PORT_EN_DBG(port), + intel_de_write(display, VLV_AUD_PORT_EN_DBG(port), audio_enable & ~VLV_AMP_MUTE); } else { memset(ppdata->eld, 0, HDMI_MAX_ELD_BYTES); @@ -358,12 +360,12 @@ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, ppdata->dp_output = false; /* Mute the amp for both DP and HDMI */ - intel_de_write(dev_priv, VLV_AUD_PORT_EN_DBG(port), + intel_de_write(display, VLV_AUD_PORT_EN_DBG(port), audio_enable | VLV_AMP_MUTE); } if (pdata->notify_audio_lpe) - pdata->notify_audio_lpe(dev_priv->display.audio.lpe.platdev, port - PORT_B); + pdata->notify_audio_lpe(display->audio.lpe.platdev, port - PORT_B); spin_unlock_irqrestore(&pdata->lpe_audio_slock, irqflags); } diff --git a/drivers/gpu/drm/i915/display/intel_lpe_audio.h b/drivers/gpu/drm/i915/display/intel_lpe_audio.h index 2c5fcb6e1fd0a..5234e11fd6627 100644 --- a/drivers/gpu/drm/i915/display/intel_lpe_audio.h +++ b/drivers/gpu/drm/i915/display/intel_lpe_audio.h @@ -10,27 +10,27 @@ enum port; enum transcoder; -struct drm_i915_private; +struct intel_display; #ifdef I915 -int intel_lpe_audio_init(struct drm_i915_private *dev_priv); -void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv); -void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv); -void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, +int intel_lpe_audio_init(struct intel_display *display); +void intel_lpe_audio_teardown(struct intel_display *display); +void intel_lpe_audio_irq_handler(struct intel_display *display); +void intel_lpe_audio_notify(struct intel_display *display, enum transcoder cpu_transcoder, enum port port, const void *eld, int ls_clock, bool dp_output); #else -static inline int intel_lpe_audio_init(struct drm_i915_private *dev_priv) +static inline int intel_lpe_audio_init(struct intel_display *display) { return -ENODEV; } -static inline void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv) +static inline void intel_lpe_audio_teardown(struct intel_display *display) { } -static inline void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv) +static inline void intel_lpe_audio_irq_handler(struct intel_display *display) { } -static inline void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, +static inline void intel_lpe_audio_notify(struct intel_display *display, enum transcoder cpu_transcoder, enum port port, const void *eld, int ls_clock, bool dp_output) { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7920ad9585ae6..202eb1b6ae54d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -207,6 +207,7 @@ static void ivb_parity_work(struct work_struct *work) static irqreturn_t valleyview_irq_handler(int irq, void *arg) { struct drm_i915_private *dev_priv = arg; + struct intel_display *display = &dev_priv->display; irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) @@ -260,7 +261,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) if (iir & (I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT)) - intel_lpe_audio_irq_handler(dev_priv); + intel_lpe_audio_irq_handler(display); /* * VLV_IIR is single buffered, and reflects the level @@ -293,6 +294,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) static irqreturn_t cherryview_irq_handler(int irq, void *arg) { struct drm_i915_private *dev_priv = arg; + struct intel_display *display = &dev_priv->display; irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) @@ -343,7 +345,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) if (iir & (I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT | I915_LPE_PIPE_C_INTERRUPT)) - intel_lpe_audio_irq_handler(dev_priv); + intel_lpe_audio_irq_handler(display); /* * VLV_IIR is single buffered, and reflects the level From 90322277a3f1ddf5740aac703e92ef99c7a45f32 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 8 Jan 2025 16:04:15 +0200 Subject: [PATCH 026/284] drm/i915/audio: rename function prefixes from i915 to intel The intel prefix is more accurate for display stuff. Rename. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/5e67f6fc5a441a9512d7855d86ce7868cc992212.1736345025.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_audio.c | 82 +++++++++++----------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 241e5d3904dca..4b1f46815ad5f 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -1035,7 +1035,7 @@ int intel_audio_min_cdclk(const struct intel_crtc_state *crtc_state) return min_cdclk; } -static unsigned long i915_audio_component_get_power(struct device *kdev) +static unsigned long intel_audio_component_get_power(struct device *kdev) { struct intel_display *display = to_intel_display(kdev); struct drm_i915_private *i915 = to_i915(display->drm); @@ -1067,8 +1067,8 @@ static unsigned long i915_audio_component_get_power(struct device *kdev) return (unsigned long)wakeref; } -static void i915_audio_component_put_power(struct device *kdev, - unsigned long cookie) +static void intel_audio_component_put_power(struct device *kdev, + unsigned long cookie) { struct intel_display *display = to_intel_display(kdev); struct drm_i915_private *i915 = to_i915(display->drm); @@ -1082,8 +1082,8 @@ static void i915_audio_component_put_power(struct device *kdev, intel_display_power_put(i915, POWER_DOMAIN_AUDIO_PLAYBACK, wakeref); } -static void i915_audio_component_codec_wake_override(struct device *kdev, - bool enable) +static void intel_audio_component_codec_wake_override(struct device *kdev, + bool enable) { struct intel_display *display = to_intel_display(kdev); unsigned long cookie; @@ -1091,7 +1091,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, if (DISPLAY_VER(display) < 9) return; - cookie = i915_audio_component_get_power(kdev); + cookie = intel_audio_component_get_power(kdev); /* * Enable/disable generating the codec wake signal, overriding the @@ -1107,11 +1107,11 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, usleep_range(1000, 1500); } - i915_audio_component_put_power(kdev, cookie); + intel_audio_component_put_power(kdev, cookie); } /* Get CDCLK in kHz */ -static int i915_audio_component_get_cdclk_freq(struct device *kdev) +static int intel_audio_component_get_cdclk_freq(struct device *kdev) { struct intel_display *display = to_intel_display(kdev); @@ -1169,8 +1169,8 @@ static struct intel_audio_state *find_audio_state(struct intel_display *display, return NULL; } -static int i915_audio_component_sync_audio_rate(struct device *kdev, int port, - int cpu_transcoder, int rate) +static int intel_audio_component_sync_audio_rate(struct device *kdev, int port, + int cpu_transcoder, int rate) { struct intel_display *display = to_intel_display(kdev); struct i915_audio_component *acomp = display->audio.component; @@ -1183,7 +1183,7 @@ static int i915_audio_component_sync_audio_rate(struct device *kdev, int port, if (!HAS_DDI(display)) return 0; - cookie = i915_audio_component_get_power(kdev); + cookie = intel_audio_component_get_power(kdev); mutex_lock(&display->audio.mutex); audio_state = find_audio_state(display, port, cpu_transcoder); @@ -1207,13 +1207,13 @@ static int i915_audio_component_sync_audio_rate(struct device *kdev, int port, unlock: mutex_unlock(&display->audio.mutex); - i915_audio_component_put_power(kdev, cookie); + intel_audio_component_put_power(kdev, cookie); return err; } -static int i915_audio_component_get_eld(struct device *kdev, int port, - int cpu_transcoder, bool *enabled, - unsigned char *buf, int max_bytes) +static int intel_audio_component_get_eld(struct device *kdev, int port, + int cpu_transcoder, bool *enabled, + unsigned char *buf, int max_bytes) { struct intel_display *display = to_intel_display(kdev); const struct intel_audio_state *audio_state; @@ -1241,18 +1241,18 @@ static int i915_audio_component_get_eld(struct device *kdev, int port, return ret; } -static const struct drm_audio_component_ops i915_audio_component_ops = { - .owner = THIS_MODULE, - .get_power = i915_audio_component_get_power, - .put_power = i915_audio_component_put_power, - .codec_wake_override = i915_audio_component_codec_wake_override, - .get_cdclk_freq = i915_audio_component_get_cdclk_freq, - .sync_audio_rate = i915_audio_component_sync_audio_rate, - .get_eld = i915_audio_component_get_eld, +static const struct drm_audio_component_ops intel_audio_component_ops = { + .owner = THIS_MODULE, + .get_power = intel_audio_component_get_power, + .put_power = intel_audio_component_put_power, + .codec_wake_override = intel_audio_component_codec_wake_override, + .get_cdclk_freq = intel_audio_component_get_cdclk_freq, + .sync_audio_rate = intel_audio_component_sync_audio_rate, + .get_eld = intel_audio_component_get_eld, }; -static int i915_audio_component_bind(struct device *drv_kdev, - struct device *hda_kdev, void *data) +static int intel_audio_component_bind(struct device *drv_kdev, + struct device *hda_kdev, void *data) { struct intel_display *display = to_intel_display(drv_kdev); struct i915_audio_component *acomp = data; @@ -1267,7 +1267,7 @@ static int i915_audio_component_bind(struct device *drv_kdev, return -ENOMEM; drm_modeset_lock_all(display->drm); - acomp->base.ops = &i915_audio_component_ops; + acomp->base.ops = &intel_audio_component_ops; acomp->base.dev = drv_kdev; BUILD_BUG_ON(MAX_PORTS != I915_MAX_PORTS); for (i = 0; i < ARRAY_SIZE(acomp->aud_sample_rate); i++) @@ -1278,8 +1278,8 @@ static int i915_audio_component_bind(struct device *drv_kdev, return 0; } -static void i915_audio_component_unbind(struct device *drv_kdev, - struct device *hda_kdev, void *data) +static void intel_audio_component_unbind(struct device *drv_kdev, + struct device *hda_kdev, void *data) { struct intel_display *display = to_intel_display(drv_kdev); struct i915_audio_component *acomp = data; @@ -1298,9 +1298,9 @@ static void i915_audio_component_unbind(struct device *drv_kdev, display->audio.power_refcount); } -static const struct component_ops i915_audio_component_bind_ops = { - .bind = i915_audio_component_bind, - .unbind = i915_audio_component_unbind, +static const struct component_ops intel_audio_component_bind_ops = { + .bind = intel_audio_component_bind, + .unbind = intel_audio_component_unbind, }; #define AUD_FREQ_TMODE_SHIFT 14 @@ -1313,7 +1313,7 @@ static const struct component_ops i915_audio_component_bind_ops = { #define AUD_FREQ_TGL_BROKEN (AUD_FREQ_8T | AUD_FREQ_PULLCLKS(2) | AUD_FREQ_BCLK_96M) /** - * i915_audio_component_init - initialize and register the audio component + * intel_audio_component_init - initialize and register the audio component * @display: display device * * This will register with the component framework a child component which @@ -1328,7 +1328,7 @@ static const struct component_ops i915_audio_component_bind_ops = { * We ignore any error during registration and continue with reduced * functionality (i.e. without HDMI audio). */ -static void i915_audio_component_init(struct intel_display *display) +static void intel_audio_component_init(struct intel_display *display) { u32 aud_freq, aud_freq_init; @@ -1356,12 +1356,12 @@ static void i915_audio_component_init(struct intel_display *display) intel_audio_cdclk_change_post(display); } -static void i915_audio_component_register(struct intel_display *display) +static void intel_audio_component_register(struct intel_display *display) { int ret; ret = component_add_typed(display->drm->dev, - &i915_audio_component_bind_ops, + &intel_audio_component_bind_ops, I915_COMPONENT_AUDIO); if (ret < 0) { drm_err(display->drm, @@ -1374,18 +1374,18 @@ static void i915_audio_component_register(struct intel_display *display) } /** - * i915_audio_component_cleanup - deregister the audio component + * intel_audio_component_cleanup - deregister the audio component * @display: display device * * Deregisters the audio component, breaking any existing binding to the * corresponding snd_hda_intel driver's master component. */ -static void i915_audio_component_cleanup(struct intel_display *display) +static void intel_audio_component_cleanup(struct intel_display *display) { if (!display->audio.component_registered) return; - component_del(display->drm->dev, &i915_audio_component_bind_ops); + component_del(display->drm->dev, &intel_audio_component_bind_ops); display->audio.component_registered = false; } @@ -1398,13 +1398,13 @@ static void i915_audio_component_cleanup(struct intel_display *display) void intel_audio_init(struct intel_display *display) { if (intel_lpe_audio_init(display) < 0) - i915_audio_component_init(display); + intel_audio_component_init(display); } void intel_audio_register(struct intel_display *display) { if (!display->audio.lpe.platdev) - i915_audio_component_register(display); + intel_audio_component_register(display); } /** @@ -1416,5 +1416,5 @@ void intel_audio_deinit(struct intel_display *display) if (display->audio.lpe.platdev) intel_lpe_audio_teardown(display); else - i915_audio_component_cleanup(display); + intel_audio_component_cleanup(display); } From 778c29fca7557baa514dd0cf6efaa654845edf60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:50 +0200 Subject: [PATCH 027/284] drm/i915: Extract intel_crtc_vblank_delay() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the vblank delay computation into a separate function. We'll need more logic here soon and we don't want to pollute intel_crtc_compute_config() with low level details. We'll use HAS_DSB() to determine if any delay might be required or not because delayed vblank only really exists for the purposes of the DSB. It also doesn't event exists on any pre-tgl platforms, which also don't have DSB. I was midly tempted to check for the enable_dsb modparam here actually, but as that can be changed dynamically via debugfs we'd need to either reconfigure it on the fly or force a modeset. Neither will happen currently, so we'll just assume DSB may be used of the platform supports it. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-2-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 24 +++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 4271da219b410..5530bcf32b87a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2610,16 +2610,29 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state) return 0; } -static bool intel_crtc_needs_wa_14015401596(struct intel_crtc_state *crtc_state) +static bool intel_crtc_needs_wa_14015401596(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; return intel_vrr_possible(crtc_state) && crtc_state->has_psr && - adjusted_mode->crtc_vblank_start == adjusted_mode->crtc_vdisplay && IS_DISPLAY_VER(display, 13, 14); } +static int intel_crtc_vblank_delay(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + int vblank_delay = 0; + + if (!HAS_DSB(display)) + return 0; + + /* Wa_14015401596 */ + if (intel_crtc_needs_wa_14015401596(crtc_state)) + vblank_delay = max(vblank_delay, 1); + + return vblank_delay; +} + static int intel_crtc_compute_config(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -2629,9 +2642,8 @@ static int intel_crtc_compute_config(struct intel_atomic_state *state, &crtc_state->hw.adjusted_mode; int ret; - /* Wa_14015401596 */ - if (intel_crtc_needs_wa_14015401596(crtc_state)) - adjusted_mode->crtc_vblank_start += 1; + adjusted_mode->crtc_vblank_start += + intel_crtc_vblank_delay(crtc_state); ret = intel_dpll_crtc_compute_clock(state, crtc); if (ret) From 4745ef7a173f4c9182099870c627de309c07b204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:51 +0200 Subject: [PATCH 028/284] drm/i915: Check vblank delay validity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure we have enough vblank for the computed vblank delay. Supposedly we'd reject things anyway later if this gets violated, but it seems nicer to do some basic sanity checks early just so we can be sure the basic relationship vblank_end > vblank_start always holds. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-3-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 31 +++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5530bcf32b87a..f5d2eacce119b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2633,17 +2633,40 @@ static int intel_crtc_vblank_delay(const struct intel_crtc_state *crtc_state) return vblank_delay; } -static int intel_crtc_compute_config(struct intel_atomic_state *state, - struct intel_crtc *crtc) +static int intel_crtc_compute_vblank_delay(struct intel_atomic_state *state, + struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; + int vblank_delay, max_vblank_delay; + + vblank_delay = intel_crtc_vblank_delay(crtc_state); + max_vblank_delay = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start - 1; + + if (vblank_delay > max_vblank_delay) { + drm_dbg_kms(display->drm, "[CRTC:%d:%s] vblank delay (%d) exceeds max (%d)\n", + crtc->base.base.id, crtc->base.name, vblank_delay, max_vblank_delay); + return -EINVAL; + } + + adjusted_mode->crtc_vblank_start += vblank_delay; + + return 0; +} + +static int intel_crtc_compute_config(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); int ret; - adjusted_mode->crtc_vblank_start += - intel_crtc_vblank_delay(crtc_state); + ret = intel_crtc_compute_vblank_delay(state, crtc); + if (ret) + return ret; ret = intel_dpll_crtc_compute_clock(state, crtc); if (ret) From 51e7f44027a184f5f9048caa0d7e29eebdd9a5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:52 +0200 Subject: [PATCH 029/284] drm/i915: Fix include order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include the headers in the correct alphabetical order. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-4-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 70088e355055d..66f9ce2b4486f 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -7,9 +7,9 @@ #include "i915_reg.h" #include "intel_de.h" #include "intel_display_types.h" +#include "intel_dp.h" #include "intel_vrr.h" #include "intel_vrr_regs.h" -#include "intel_dp.h" #define FIXED_POINT_PRECISION 100 #define CMRR_PRECISION_TOLERANCE 10 From b7eeed399b2851b140119e4866cabaaf1cba182d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:53 +0200 Subject: [PATCH 030/284] drm/i915: Introduce intel_vrr_{vmin,vmax}_vtotal() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ICL/TGL vmin/vmax/flipline won't actually match the vtotal values (currently they do, but that is wrong and needs to be fixed). Add a few helpers that will compute the actual vtotal values for us. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-5-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dsb.c | 2 +- drivers/gpu/drm/i915/display/intel_vblank.c | 4 ++-- drivers/gpu/drm/i915/display/intel_vrr.c | 11 +++++++++++ drivers/gpu/drm/i915/display/intel_vrr.h | 2 ++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index e6f8fc743fb40..fcb8bf9cb3132 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -140,7 +140,7 @@ static int dsb_vtotal(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc); if (pre_commit_is_vrr_active(state, crtc)) - return crtc_state->vrr.vmax; + return intel_vrr_vmax_vtotal(crtc_state); else return intel_mode_vtotal(&crtc_state->hw.adjusted_mode); } diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index a95fb3349eba7..6f0e0c64187da 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -523,8 +523,8 @@ void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state, drm_WARN_ON(display->drm, (mode_flags & I915_MODE_FLAG_VRR) == 0); - adjusted_mode.crtc_vtotal = crtc_state->vrr.vmax; - adjusted_mode.crtc_vblank_end = crtc_state->vrr.vmax; + adjusted_mode.crtc_vtotal = intel_vrr_vmax_vtotal(crtc_state); + adjusted_mode.crtc_vblank_end = intel_vrr_vmax_vtotal(crtc_state); adjusted_mode.crtc_vblank_start = intel_vrr_vmin_vblank_start(crtc_state); vmax_vblank_start = intel_vrr_vmax_vblank_start(crtc_state); } else { diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 66f9ce2b4486f..2e9c286bb0799 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -102,6 +102,17 @@ static int intel_vrr_vblank_exit_length(const struct intel_crtc_state *crtc_stat return crtc_state->vrr.pipeline_full + crtc_state->framestart_delay + 1; } +int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state) +{ + /* Min vblank actually determined by flipline that is always >=vmin+1 */ + return crtc_state->vrr.vmin + 1; +} + +int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) +{ + return crtc_state->vrr.vmax; +} + int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state) { /* Min vblank actually determined by flipline that is always >=vmin+1 */ diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index b3b45c6750207..75db88ae9cc44 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -26,6 +26,8 @@ void intel_vrr_send_push(const struct intel_crtc_state *crtc_state); bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state); void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state); void intel_vrr_get_config(struct intel_crtc_state *crtc_state); +int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state); +int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state); int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state); int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state); From c14f66c6e46728db2cf314725e68655ac2f499dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:54 +0200 Subject: [PATCH 031/284] drm/i915: Move framestart/etc. state dump to a better spot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try to dump all the important stuff relating to the display timings in one spot. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-6-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_crtc_state_dump.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 1faef60be4728..9d930ff862cfb 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -250,9 +250,6 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, str_enabled_disabled(pipe_config->enable_psr2_sel_fetch)); } - drm_printf(&p, "framestart delay: %d, MSA timing delay: %d\n", - pipe_config->framestart_delay, pipe_config->msa_timing_delay); - drm_printf(&p, "audio: %i, infoframes: %i, infoframes enabled: 0x%x\n", pipe_config->has_audio, pipe_config->has_infoframe, pipe_config->infoframes.enable); @@ -286,6 +283,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_print_hex_dump(&p, "ELD: ", pipe_config->eld, drm_eld_size(pipe_config->eld)); + drm_printf(&p, "framestart delay: %d, MSA timing delay: %d\n", + pipe_config->framestart_delay, pipe_config->msa_timing_delay); + drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, pipeline full: %d, guardband: %d flipline: %d, vmin vblank: %d, vmax vblank: %d\n", str_yes_no(pipe_config->vrr.enable), pipe_config->vrr.vmin, pipe_config->vrr.vmax, From af14b81e9f04b35d578627f6305d87010d0ef0ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:55 +0200 Subject: [PATCH 032/284] drm/i915: Include the vblank delay in the state dump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While one can look at the crtc timings to determine the actual vblank dealy, it seems nicer to provide a more human readable dump of it to ease our lives. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-7-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_crtc_state_dump.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 9d930ff862cfb..27ce34df84829 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -283,7 +283,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_print_hex_dump(&p, "ELD: ", pipe_config->eld, drm_eld_size(pipe_config->eld)); - drm_printf(&p, "framestart delay: %d, MSA timing delay: %d\n", + drm_printf(&p, "vblank delay: %d, framestart delay: %d, MSA timing delay: %d\n", + pipe_config->hw.adjusted_mode.crtc_vblank_start - + pipe_config->hw.adjusted_mode.crtc_vdisplay, pipe_config->framestart_delay, pipe_config->msa_timing_delay); drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, pipeline full: %d, guardband: %d flipline: %d, vmin vblank: %d, vmax vblank: %d\n", From 97b6a2eef43f8dac2f36cfde2d813eb2b5edd26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:56 +0200 Subject: [PATCH 033/284] drm/i915/vrr: Improve VRR state dump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dump the calculated vmin/vmax vtotal values in addition to the raw vmin/vmax/flipline values. Makes it much easier to see what kind of scanline values we should be expecting from the hardware. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-8-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- .../gpu/drm/i915/display/intel_crtc_state_dump.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 27ce34df84829..97e3cdccda01d 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -288,13 +288,14 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, pipe_config->hw.adjusted_mode.crtc_vdisplay, pipe_config->framestart_delay, pipe_config->msa_timing_delay); - drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, pipeline full: %d, guardband: %d flipline: %d, vmin vblank: %d, vmax vblank: %d\n", + drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d\n", str_yes_no(pipe_config->vrr.enable), - pipe_config->vrr.vmin, pipe_config->vrr.vmax, - pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband, - pipe_config->vrr.flipline, - intel_vrr_vmin_vblank_start(pipe_config), - intel_vrr_vmax_vblank_start(pipe_config)); + pipe_config->vrr.vmin, pipe_config->vrr.vmax, pipe_config->vrr.flipline, + pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband); + + drm_printf(&p, "vrr: vmin vblank: %d, vmax vblank: %d, vmin vtotal: %d, vmax vtotal: %d\n", + intel_vrr_vmin_vblank_start(pipe_config), intel_vrr_vmax_vblank_start(pipe_config), + intel_vrr_vmin_vtotal(pipe_config), intel_vrr_vmax_vtotal(pipe_config)); drm_printf(&p, "requested mode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&pipe_config->hw.mode)); From ab684293168c7c817fc6089f290496cd6bfeec0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:57 +0200 Subject: [PATCH 034/284] drm/i915: Include the scanline offset in the state dump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When looking at raw hardware scanline numbers it's helpful to remember what the offset between the hardware values and our more human readable numbers should be. Include that in the state dump. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-9-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_crtc_state_dump.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 97e3cdccda01d..1fbaa67e2fea7 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -10,6 +10,7 @@ #include "intel_crtc_state_dump.h" #include "intel_display_types.h" #include "intel_hdmi.h" +#include "intel_vblank.h" #include "intel_vdsc.h" #include "intel_vrr.h" @@ -283,6 +284,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_print_hex_dump(&p, "ELD: ", pipe_config->eld, drm_eld_size(pipe_config->eld)); + drm_printf(&p, "scanline offset: %d\n", + intel_crtc_scanline_offset(pipe_config)); + drm_printf(&p, "vblank delay: %d, framestart delay: %d, MSA timing delay: %d\n", pipe_config->hw.adjusted_mode.crtc_vblank_start - pipe_config->hw.adjusted_mode.crtc_vdisplay, From 730ac786e869b1a98323f354e1d005cfc4d99fe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:58 +0200 Subject: [PATCH 035/284] drm/i915: Extract intel_mode_vblank_delay() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract the code that computes the hardware centric view of the vblank delay into a helper. We'll need a slightly different variant for VRR soon. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-10-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dsb.c | 3 +-- drivers/gpu/drm/i915/display/intel_vblank.c | 8 ++++++-- drivers/gpu/drm/i915/display/intel_vblank.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index fcb8bf9cb3132..d755825edb352 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -130,8 +130,7 @@ pre_commit_crtc_state(struct intel_atomic_state *state, static int dsb_vblank_delay(const struct intel_crtc_state *crtc_state) { - return intel_mode_vblank_start(&crtc_state->hw.adjusted_mode) - - intel_mode_vdisplay(&crtc_state->hw.adjusted_mode); + return intel_mode_vblank_delay(&crtc_state->hw.adjusted_mode); } static int dsb_vtotal(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index 6f0e0c64187da..ee33a49d98736 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -597,6 +597,11 @@ int intel_mode_vtotal(const struct drm_display_mode *mode) return vtotal; } +int intel_mode_vblank_delay(const struct drm_display_mode *mode) +{ + return intel_mode_vblank_start(mode) - intel_mode_vdisplay(mode); +} + void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *new_crtc_state, struct intel_vblank_evade_ctx *evade) @@ -653,8 +658,7 @@ void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, */ if (intel_color_uses_dsb(new_crtc_state) || new_crtc_state->update_m_n || new_crtc_state->update_lrr) - evade->min -= intel_mode_vblank_start(adjusted_mode) - - intel_mode_vdisplay(adjusted_mode); + evade->min -= intel_mode_vblank_delay(adjusted_mode); } /* must be called with vblank interrupt already enabled! */ diff --git a/drivers/gpu/drm/i915/display/intel_vblank.h b/drivers/gpu/drm/i915/display/intel_vblank.h index 6d73362569826..12c8e1f829a46 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.h +++ b/drivers/gpu/drm/i915/display/intel_vblank.h @@ -24,6 +24,7 @@ int intel_mode_vdisplay(const struct drm_display_mode *mode); int intel_mode_vblank_start(const struct drm_display_mode *mode); int intel_mode_vblank_end(const struct drm_display_mode *mode); int intel_mode_vtotal(const struct drm_display_mode *mode); +int intel_mode_vblank_delay(const struct drm_display_mode *mode); void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *new_crtc_state, From a18bd2f32c6960bc5446db3d6d4e4b31267c863c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:59 +0200 Subject: [PATCH 036/284] drm/i915: Consolidate intel_pre_commit_crtc_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have approximately two copies of pre_commit_crtc_state(), one in the DSB code, the other in the vblank evasion code. Combine them into one. The slight difference between the two is that vblank evasion doesn't have a full atomic state (when called from the legacy cursor code), so it gets the old and new crtc state passed in by hand. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-11-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dsb.c | 37 +++++++------------- drivers/gpu/drm/i915/display/intel_vblank.c | 38 +++++++++++++++------ drivers/gpu/drm/i915/display/intel_vblank.h | 5 +++ 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index d755825edb352..673f757037859 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -109,25 +109,6 @@ static bool pre_commit_is_vrr_active(struct intel_atomic_state *state, return old_crtc_state->vrr.enable && !intel_crtc_vrr_disabling(state, crtc); } -static const struct intel_crtc_state * -pre_commit_crtc_state(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - const struct intel_crtc_state *old_crtc_state = - intel_atomic_get_old_crtc_state(state, crtc); - const struct intel_crtc_state *new_crtc_state = - intel_atomic_get_new_crtc_state(state, crtc); - - /* - * During fastsets/etc. the transcoder is still - * running with the old timings at this point. - */ - if (intel_crtc_needs_modeset(new_crtc_state)) - return new_crtc_state; - else - return old_crtc_state; -} - static int dsb_vblank_delay(const struct intel_crtc_state *crtc_state) { return intel_mode_vblank_delay(&crtc_state->hw.adjusted_mode); @@ -136,7 +117,8 @@ static int dsb_vblank_delay(const struct intel_crtc_state *crtc_state) static int dsb_vtotal(struct intel_atomic_state *state, struct intel_crtc *crtc) { - const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc); + const struct intel_crtc_state *crtc_state = + intel_pre_commit_crtc_state(state, crtc); if (pre_commit_is_vrr_active(state, crtc)) return intel_vrr_vmax_vtotal(crtc_state); @@ -147,7 +129,8 @@ static int dsb_vtotal(struct intel_atomic_state *state, static int dsb_dewake_scanline_start(struct intel_atomic_state *state, struct intel_crtc *crtc) { - const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc); + const struct intel_crtc_state *crtc_state = + intel_pre_commit_crtc_state(state, crtc); struct drm_i915_private *i915 = to_i915(state->base.dev); unsigned int latency = skl_watermark_max_latency(i915, 0); @@ -158,7 +141,8 @@ static int dsb_dewake_scanline_start(struct intel_atomic_state *state, static int dsb_dewake_scanline_end(struct intel_atomic_state *state, struct intel_crtc *crtc) { - const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc); + const struct intel_crtc_state *crtc_state = + intel_pre_commit_crtc_state(state, crtc); return intel_mode_vdisplay(&crtc_state->hw.adjusted_mode); } @@ -166,7 +150,8 @@ static int dsb_dewake_scanline_end(struct intel_atomic_state *state, static int dsb_scanline_to_hw(struct intel_atomic_state *state, struct intel_crtc *crtc, int scanline) { - const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc); + const struct intel_crtc_state *crtc_state = + intel_pre_commit_crtc_state(state, crtc); int vtotal = dsb_vtotal(state, crtc); return (scanline + vtotal - intel_crtc_scanline_offset(crtc_state)) % vtotal; @@ -531,7 +516,8 @@ void intel_dsb_vblank_evade(struct intel_atomic_state *state, struct intel_dsb *dsb) { struct intel_crtc *crtc = dsb->crtc; - const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc); + const struct intel_crtc_state *crtc_state = + intel_pre_commit_crtc_state(state, crtc); /* FIXME calibrate sensibly */ int latency = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 20); int vblank_delay = dsb_vblank_delay(crtc_state); @@ -623,7 +609,8 @@ void intel_dsb_wait_vblank_delay(struct intel_atomic_state *state, struct intel_dsb *dsb) { struct intel_crtc *crtc = dsb->crtc; - const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc); + const struct intel_crtc_state *crtc_state = + intel_pre_commit_crtc_state(state, crtc); int usecs = intel_scanlines_to_usecs(&crtc_state->hw.adjusted_mode, dsb_vblank_delay(crtc_state)) + 1; diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index ee33a49d98736..3cf3cff0687a5 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -602,6 +602,32 @@ int intel_mode_vblank_delay(const struct drm_display_mode *mode) return intel_mode_vblank_start(mode) - intel_mode_vdisplay(mode); } +static const struct intel_crtc_state * +pre_commit_crtc_state(const struct intel_crtc_state *old_crtc_state, + const struct intel_crtc_state *new_crtc_state) +{ + /* + * During fastsets/etc. the transcoder is still + * running with the old timings at this point. + */ + if (intel_crtc_needs_modeset(new_crtc_state)) + return new_crtc_state; + else + return old_crtc_state; +} + +const struct intel_crtc_state * +intel_pre_commit_crtc_state(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + const struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); + const struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + + return pre_commit_crtc_state(old_crtc_state, new_crtc_state); +} + void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *new_crtc_state, struct intel_vblank_evade_ctx *evade) @@ -617,16 +643,8 @@ void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, display->platform.cherryview) && intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI); - /* - * During fastsets/etc. the transcoder is still - * running with the old timings at this point. - * - * TODO: maybe just use the active timings here? - */ - if (intel_crtc_needs_modeset(new_crtc_state)) - crtc_state = new_crtc_state; - else - crtc_state = old_crtc_state; + /* TODO: maybe just use the active timings here? */ + crtc_state = pre_commit_crtc_state(old_crtc_state, new_crtc_state); adjusted_mode = &crtc_state->hw.adjusted_mode; diff --git a/drivers/gpu/drm/i915/display/intel_vblank.h b/drivers/gpu/drm/i915/display/intel_vblank.h index 12c8e1f829a46..21fbb08d61d5d 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.h +++ b/drivers/gpu/drm/i915/display/intel_vblank.h @@ -11,6 +11,7 @@ struct drm_crtc; struct drm_display_mode; +struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; @@ -43,4 +44,8 @@ void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state, bool vrr_enable); int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state); +const struct intel_crtc_state * +intel_pre_commit_crtc_state(struct intel_atomic_state *state, + struct intel_crtc *crtc); + #endif /* __INTEL_VBLANK_H__ */ From 047d9b28a56a95044f47b54ddad71e69809ecdb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:00 +0200 Subject: [PATCH 037/284] drm/i915: Extract intel_crtc_active_timings() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declutter intel_crtc_update_active_timings() a bit by moving the code that determines the timings into a separate function. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-12-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vblank.c | 33 ++++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index 3cf3cff0687a5..2a99bde457dbd 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -507,6 +507,23 @@ void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc) wait_for_pipe_scanline_moving(crtc, true); } +static void intel_crtc_active_timings(struct drm_display_mode *mode, + int *vmax_vblank_start, + const struct intel_crtc_state *crtc_state, + bool vrr_enable) +{ + drm_mode_init(mode, &crtc_state->hw.adjusted_mode); + *vmax_vblank_start = 0; + + if (!vrr_enable) + return; + + mode->crtc_vtotal = intel_vrr_vmax_vtotal(crtc_state); + mode->crtc_vblank_end = intel_vrr_vmax_vtotal(crtc_state); + mode->crtc_vblank_start = intel_vrr_vmin_vblank_start(crtc_state); + *vmax_vblank_start = intel_vrr_vmax_vblank_start(crtc_state); +} + void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state, bool vrr_enable) { @@ -517,19 +534,13 @@ void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state, int vmax_vblank_start = 0; unsigned long irqflags; - drm_mode_init(&adjusted_mode, &crtc_state->hw.adjusted_mode); - - if (vrr_enable) { - drm_WARN_ON(display->drm, - (mode_flags & I915_MODE_FLAG_VRR) == 0); + intel_crtc_active_timings(&adjusted_mode, &vmax_vblank_start, + crtc_state, vrr_enable); - adjusted_mode.crtc_vtotal = intel_vrr_vmax_vtotal(crtc_state); - adjusted_mode.crtc_vblank_end = intel_vrr_vmax_vtotal(crtc_state); - adjusted_mode.crtc_vblank_start = intel_vrr_vmin_vblank_start(crtc_state); - vmax_vblank_start = intel_vrr_vmax_vblank_start(crtc_state); - } else { + if (vrr_enable) + drm_WARN_ON(display->drm, (mode_flags & I915_MODE_FLAG_VRR) == 0); + else mode_flags &= ~I915_MODE_FLAG_VRR; - } /* * Belts and suspenders locking to guarantee everyone sees 100% From 67badd015cba8d25fc88bf13cc49d8f7c377d547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:01 +0200 Subject: [PATCH 038/284] drm/i915/vrr: Introduce intel_vrr_vblank_delay() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a VRR specific function for determining the current vblank delay. Currently thus will give the same answer as intel_mode_vblank_delay() but that will change later. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-13-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dsb.c | 18 ++++++++++++++---- drivers/gpu/drm/i915/display/intel_vblank.c | 7 ++++++- drivers/gpu/drm/i915/display/intel_vrr.c | 6 ++++++ drivers/gpu/drm/i915/display/intel_vrr.h | 1 + 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 673f757037859..89d3496bcbdbd 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -109,9 +109,16 @@ static bool pre_commit_is_vrr_active(struct intel_atomic_state *state, return old_crtc_state->vrr.enable && !intel_crtc_vrr_disabling(state, crtc); } -static int dsb_vblank_delay(const struct intel_crtc_state *crtc_state) +static int dsb_vblank_delay(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - return intel_mode_vblank_delay(&crtc_state->hw.adjusted_mode); + const struct intel_crtc_state *crtc_state = + intel_pre_commit_crtc_state(state, crtc); + + if (pre_commit_is_vrr_active(state, crtc)) + return intel_vrr_vblank_delay(crtc_state); + else + return intel_mode_vblank_delay(&crtc_state->hw.adjusted_mode); } static int dsb_vtotal(struct intel_atomic_state *state, @@ -520,10 +527,11 @@ void intel_dsb_vblank_evade(struct intel_atomic_state *state, intel_pre_commit_crtc_state(state, crtc); /* FIXME calibrate sensibly */ int latency = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 20); - int vblank_delay = dsb_vblank_delay(crtc_state); int start, end; if (pre_commit_is_vrr_active(state, crtc)) { + int vblank_delay = intel_vrr_vblank_delay(crtc_state); + end = intel_vrr_vmin_vblank_start(crtc_state); start = end - vblank_delay - latency; intel_dsb_wait_scanline_out(state, dsb, start, end); @@ -532,6 +540,8 @@ void intel_dsb_vblank_evade(struct intel_atomic_state *state, start = end - vblank_delay - latency; intel_dsb_wait_scanline_out(state, dsb, start, end); } else { + int vblank_delay = intel_mode_vblank_delay(&crtc_state->hw.adjusted_mode); + end = intel_mode_vblank_start(&crtc_state->hw.adjusted_mode); start = end - vblank_delay - latency; intel_dsb_wait_scanline_out(state, dsb, start, end); @@ -612,7 +622,7 @@ void intel_dsb_wait_vblank_delay(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state = intel_pre_commit_crtc_state(state, crtc); int usecs = intel_scanlines_to_usecs(&crtc_state->hw.adjusted_mode, - dsb_vblank_delay(crtc_state)) + 1; + dsb_vblank_delay(state, crtc)) + 1; intel_dsb_wait_usec(dsb, usecs); } diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index 2a99bde457dbd..fb80e0bef08a1 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -647,6 +647,7 @@ void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); const struct intel_crtc_state *crtc_state; const struct drm_display_mode *adjusted_mode; + int vblank_delay; evade->crtc = crtc; @@ -668,8 +669,12 @@ void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, evade->vblank_start = intel_vrr_vmin_vblank_start(crtc_state); else evade->vblank_start = intel_vrr_vmax_vblank_start(crtc_state); + + vblank_delay = intel_vrr_vblank_delay(crtc_state); } else { evade->vblank_start = intel_mode_vblank_start(adjusted_mode); + + vblank_delay = intel_mode_vblank_delay(adjusted_mode); } /* FIXME needs to be calibrated sensibly */ @@ -687,7 +692,7 @@ void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, */ if (intel_color_uses_dsb(new_crtc_state) || new_crtc_state->update_m_n || new_crtc_state->update_lrr) - evade->min -= intel_mode_vblank_delay(adjusted_mode); + evade->min -= vblank_delay; } /* must be called with vblank interrupt already enabled! */ diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 2e9c286bb0799..05da10919ba86 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -75,6 +75,12 @@ intel_vrr_check_modeset(struct intel_atomic_state *state) } } +int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state) +{ + return crtc_state->hw.adjusted_mode.crtc_vblank_start - + crtc_state->hw.adjusted_mode.crtc_vdisplay; +} + /* * Without VRR registers get latched at: * vblank_start diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index 75db88ae9cc44..8e8961adce392 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -30,5 +30,6 @@ int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state); int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state); int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state); int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state); +int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state); #endif /* __INTEL_VRR_H__ */ From 758736b0df3a55915014e54065d87e35cbfae7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:02 +0200 Subject: [PATCH 039/284] drm/i915/vrr: Drop the extra vmin adjustment for ADL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently only ICL/TGL need the annoying vmin adjustment. On ADL+ we can program flipline==vmin and the hardware actually respects that properly. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-14-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 37 +++++++++++++++++------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 05da10919ba86..0f0c50265fc1b 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -81,6 +81,19 @@ int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state) crtc_state->hw.adjusted_mode.crtc_vdisplay; } +static int intel_vrr_flipline_offset(struct intel_display *display) +{ + /* ICL/TGL hardware imposes flipline>=vmin+1 */ + return DISPLAY_VER(display) < 13 ? 1 : 0; +} + +static int intel_vrr_vmin_flipline(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + + return crtc_state->vrr.vmin + intel_vrr_flipline_offset(display); +} + /* * Without VRR registers get latched at: * vblank_start @@ -110,8 +123,8 @@ static int intel_vrr_vblank_exit_length(const struct intel_crtc_state *crtc_stat int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state) { - /* Min vblank actually determined by flipline that is always >=vmin+1 */ - return crtc_state->vrr.vmin + 1; + /* Min vblank actually determined by flipline */ + return intel_vrr_vmin_flipline(crtc_state); } int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) @@ -121,8 +134,8 @@ int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state) { - /* Min vblank actually determined by flipline that is always >=vmin+1 */ - return crtc_state->vrr.vmin + 1 - intel_vrr_vblank_exit_length(crtc_state); + /* Min vblank actually determined by flipline */ + return intel_vrr_vmin_flipline(crtc_state) - intel_vrr_vblank_exit_length(crtc_state); } int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state) @@ -219,15 +232,17 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, if (vmin >= vmax) return; + crtc_state->vrr.vmin = vmin; + crtc_state->vrr.vmax = vmax; + + crtc_state->vrr.flipline = crtc_state->vrr.vmin; + /* * flipline determines the min vblank length the hardware will - * generate, and flipline>=vmin+1, hence we reduce vmin by one - * to make sure we can get the actual min vblank length. + * generate, and on ICL/TGL flipline>=vmin+1, hence we reduce + * vmin by one to make sure we can get the actual min vblank length. */ - crtc_state->vrr.vmin = vmin - 1; - crtc_state->vrr.vmax = vmax; - - crtc_state->vrr.flipline = crtc_state->vrr.vmin + 1; + crtc_state->vrr.vmin -= intel_vrr_flipline_offset(display); /* * When panel is VRR capable and userspace has @@ -272,7 +287,7 @@ void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state) if (DISPLAY_VER(display) >= 13) { crtc_state->vrr.guardband = - crtc_state->vrr.vmin + 1 - adjusted_mode->crtc_vblank_start; + crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start; } else { crtc_state->vrr.pipeline_full = min(255, crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start - From b6e4f92a21e35ca8bd7b21b4b5866da59dd51c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:03 +0200 Subject: [PATCH 040/284] drm/i915/vrr: Fix vmin/vmax/flipline on TGL when using vblank delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out that TGL needs its vmin/vmax/flipline adjusted based on the vblank delay, otherwise the hardware pushes the vtotals further out. Make it so. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-15-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 32 +++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 0f0c50265fc1b..1110f0e65e885 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -117,30 +117,41 @@ static int intel_vrr_vblank_exit_length(const struct intel_crtc_state *crtc_stat if (DISPLAY_VER(display) >= 13) return crtc_state->vrr.guardband; else - /* The hw imposes the extra scanline before frame start */ + /* hardware imposes one extra scanline somewhere */ return crtc_state->vrr.pipeline_full + crtc_state->framestart_delay + 1; } int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); + /* Min vblank actually determined by flipline */ - return intel_vrr_vmin_flipline(crtc_state); + if (DISPLAY_VER(display) >= 13) + return intel_vrr_vmin_flipline(crtc_state); + else + return intel_vrr_vmin_flipline(crtc_state) + + intel_vrr_vblank_delay(crtc_state); } int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) { - return crtc_state->vrr.vmax; + struct intel_display *display = to_intel_display(crtc_state); + + if (DISPLAY_VER(display) >= 13) + return crtc_state->vrr.vmax; + else + return crtc_state->vrr.vmax + + intel_vrr_vblank_delay(crtc_state); } int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state) { - /* Min vblank actually determined by flipline */ - return intel_vrr_vmin_flipline(crtc_state) - intel_vrr_vblank_exit_length(crtc_state); + return intel_vrr_vmin_vtotal(crtc_state) - intel_vrr_vblank_exit_length(crtc_state); } int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state) { - return crtc_state->vrr.vmax - intel_vrr_vblank_exit_length(crtc_state); + return intel_vrr_vmax_vtotal(crtc_state) - intel_vrr_vblank_exit_length(crtc_state); } static bool @@ -289,9 +300,18 @@ void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state) crtc_state->vrr.guardband = crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start; } else { + /* hardware imposes one extra scanline somewhere */ crtc_state->vrr.pipeline_full = min(255, crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start - crtc_state->framestart_delay - 1); + + /* + * vmin/vmax/flipline also need to be adjusted by + * the vblank delay to maintain correct vtotals. + */ + crtc_state->vrr.vmin -= intel_vrr_vblank_delay(crtc_state); + crtc_state->vrr.vmax -= intel_vrr_vblank_delay(crtc_state); + crtc_state->vrr.flipline -= intel_vrr_vblank_delay(crtc_state); } } From 8b85eadabd0902bde4562c493f4e1068a0c80c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:04 +0200 Subject: [PATCH 041/284] drm/i915/vrr: Add extra vblank delay to estimates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ICL/TGL the VRR hardware injects an extra scanline just after vactive. This essentically behaves the same as an extra line of vblank delay, except it only appears in this one specific spot. Consider our DSB interrupt signalling scheme: 1. arm the update 2. wait for undelayed vblank (or rather safe window with VRR) 3. wait for enough usecs to get past the delayed vblank 4. signal interrupt to indicate that arming has latched If step 2 waits for end of vactive step 3 needs to account for the extra one scanline, or else we risk signalling the interrupt before the delayed vblank has actually elapsed. So include the extra scanline in our vblank delay estimates. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-16-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 33 +++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 1110f0e65e885..b5e30bfe17916 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -75,12 +75,33 @@ intel_vrr_check_modeset(struct intel_atomic_state *state) } } -int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state) +static int intel_vrr_real_vblank_delay(const struct intel_crtc_state *crtc_state) { return crtc_state->hw.adjusted_mode.crtc_vblank_start - crtc_state->hw.adjusted_mode.crtc_vdisplay; } +static int intel_vrr_extra_vblank_delay(struct intel_display *display) +{ + /* + * On ICL/TGL VRR hardware inserts one extra scanline + * just after vactive, which pushes the vmin decision + * boundary ahead accordingly. We'll include the extra + * scanline in our vblank delay estimates to make sure + * that we never underestimate how long we have until + * the delayed vblank has passed. + */ + return DISPLAY_VER(display) < 13 ? 1 : 0; +} + +int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + + return intel_vrr_real_vblank_delay(crtc_state) + + intel_vrr_extra_vblank_delay(display); +} + static int intel_vrr_flipline_offset(struct intel_display *display) { /* ICL/TGL hardware imposes flipline>=vmin+1 */ @@ -130,7 +151,7 @@ int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state) return intel_vrr_vmin_flipline(crtc_state); else return intel_vrr_vmin_flipline(crtc_state) + - intel_vrr_vblank_delay(crtc_state); + intel_vrr_real_vblank_delay(crtc_state); } int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) @@ -141,7 +162,7 @@ int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) return crtc_state->vrr.vmax; else return crtc_state->vrr.vmax + - intel_vrr_vblank_delay(crtc_state); + intel_vrr_real_vblank_delay(crtc_state); } int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state) @@ -309,9 +330,9 @@ void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state) * vmin/vmax/flipline also need to be adjusted by * the vblank delay to maintain correct vtotals. */ - crtc_state->vrr.vmin -= intel_vrr_vblank_delay(crtc_state); - crtc_state->vrr.vmax -= intel_vrr_vblank_delay(crtc_state); - crtc_state->vrr.flipline -= intel_vrr_vblank_delay(crtc_state); + crtc_state->vrr.vmin -= intel_vrr_real_vblank_delay(crtc_state); + crtc_state->vrr.vmax -= intel_vrr_real_vblank_delay(crtc_state); + crtc_state->vrr.flipline -= intel_vrr_real_vblank_delay(crtc_state); } } From fd95e73debdffd77febc0f0b4b304378856a5e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:05 +0200 Subject: [PATCH 042/284] drm/i915/vrr: Plumb the DSB into intel_vrr_send_push() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plumb the DSB down into intel_vrr_send_push() so that we can perform the opration on the DSB. TRANS_PUSH, being a transcoder register, needs non-posted writes to make it through. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-17-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_crtc.c | 2 +- drivers/gpu/drm/i915/display/intel_vrr.c | 14 +++++++++++--- drivers/gpu/drm/i915/display/intel_vrr.h | 4 +++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index c910168602d28..3e8b52eaac277 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -714,7 +714,7 @@ void intel_pipe_update_end(struct intel_atomic_state *state, * which would cause the next frame to terminate already at vmin * vblank start instead of vmax vblank start. */ - intel_vrr_send_push(new_crtc_state); + intel_vrr_send_push(NULL, new_crtc_state); local_irq_enable(); diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index b5e30bfe17916..b268a0a01cd12 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -390,7 +390,8 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state) crtc_state->vrr.flipline - 1); } -void intel_vrr_send_push(const struct intel_crtc_state *crtc_state) +void intel_vrr_send_push(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; @@ -398,8 +399,15 @@ void intel_vrr_send_push(const struct intel_crtc_state *crtc_state) if (!crtc_state->vrr.enable) return; - intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), - TRANS_PUSH_EN | TRANS_PUSH_SEND); + if (dsb) + intel_dsb_nonpost_start(dsb); + + intel_de_write_dsb(display, dsb, + TRANS_PUSH(display, cpu_transcoder), + TRANS_PUSH_EN | TRANS_PUSH_SEND); + + if (dsb) + intel_dsb_nonpost_end(dsb); } bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index 8e8961adce392..899cbf40f880c 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -12,6 +12,7 @@ struct drm_connector_state; struct intel_atomic_state; struct intel_connector; struct intel_crtc_state; +struct intel_dsb; bool intel_vrr_is_capable(struct intel_connector *connector); bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh); @@ -22,7 +23,8 @@ void intel_vrr_compute_config(struct intel_crtc_state *crtc_state, void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state); void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state); void intel_vrr_enable(const struct intel_crtc_state *crtc_state); -void intel_vrr_send_push(const struct intel_crtc_state *crtc_state); +void intel_vrr_send_push(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state); bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state); void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state); void intel_vrr_get_config(struct intel_crtc_state *crtc_state); From 73900dce57e40bcced9af4518051ab9dabb9aea9 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 14 Jan 2025 14:28:57 +0200 Subject: [PATCH 043/284] drm/xe/dp: Enable DP tunneling Enable the DP tunneling functionality in the xe driver. v2: Keep using IS_ENABLED() for kconfig options. (Jani) Cc: Jani Nikula Reviewed-by: Suraj Kandpal Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250114122857.1050090-1-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_tunnel.h | 5 +++-- drivers/gpu/drm/xe/Kconfig | 14 ++++++++++++++ drivers/gpu/drm/xe/Makefile | 3 +++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h index e9314cf25a193..7f0f720e8dcad 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h @@ -20,7 +20,8 @@ struct intel_dp; struct intel_encoder; struct intel_link_bw_limits; -#if IS_ENABLED(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915) +#if (IS_ENABLED(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915)) || \ + (IS_ENABLED(CONFIG_DRM_XE_DP_TUNNEL) && !defined(I915)) int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx); void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp); @@ -127,6 +128,6 @@ intel_dp_tunnel_mgr_init(struct intel_display *display) static inline void intel_dp_tunnel_mgr_cleanup(struct intel_display *display) {} -#endif /* CONFIG_DRM_I915_DP_TUNNEL */ +#endif /* CONFIG_DRM_I915_DP_TUNNEL || CONFIG_DRM_XE_DP_TUNNEL */ #endif /* __INTEL_DP_TUNNEL_H__ */ diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig index b51a2bde73e29..50cf80df51900 100644 --- a/drivers/gpu/drm/xe/Kconfig +++ b/drivers/gpu/drm/xe/Kconfig @@ -59,6 +59,20 @@ config DRM_XE_DISPLAY help Disable this option only if you want to compile out display support. +config DRM_XE_DP_TUNNEL + bool "Enable DP tunnel support" + depends on DRM_XE + depends on USB4 + select DRM_DISPLAY_DP_TUNNEL + default y + help + Choose this option to detect DP tunnels and enable the Bandwidth + Allocation mode for such tunnels. This allows using the maximum + resolution allowed by the link BW on all displays sharing the + link BW, for instance on a Thunderbolt link. + + If in doubt say "Y". + config DRM_XE_FORCE_PROBE string "Force probe xe for selected Intel hardware IDs" depends on DRM_XE diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 5c97ad6ed7385..81f63258a7e19 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -301,6 +301,9 @@ ifeq ($(CONFIG_DEBUG_FS),y) i915-display/intel_pipe_crc.o endif +xe-$(CONFIG_DRM_XE_DP_TUNNEL) += \ + i915-display/intel_dp_tunnel.o + obj-$(CONFIG_DRM_XE) += xe.o obj-$(CONFIG_DRM_XE_KUNIT_TEST) += tests/ From e35ecd95ecf28478c6aeac1ab480bbc033dae9c9 Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Bhadane Date: Wed, 18 Dec 2024 01:43:00 +0530 Subject: [PATCH 044/284] drm/i915/display: Add MTL subplatforms definition Separate MTL-U platform PCI ids in one define macro. Add the MTL U/ARL U as subplatform member in MTL platform description structure to use display.platform. from intel_display structure instead of IS_() in display code path. v2: - Club ARL-u in MTL and identify ARL-u as MTL-u subplatform(Jani) Signed-off-by: Dnyaneshwar Bhadane Reviewed-by: Suraj Kandpal Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20241217201301.3593054-2-dnyaneshwar.bhadane@intel.com --- drivers/gpu/drm/i915/display/intel_display_device.c | 13 +++++++++++++ drivers/gpu/drm/i915/display/intel_display_device.h | 1 + include/drm/intel/pciids.h | 7 +++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 68cb7f9b9ef35..738ae522c8f4f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1357,6 +1357,12 @@ static const struct intel_display_device_info xe2_hpd_display = { BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4), }; +static const u16 mtl_u_ids[] = { + INTEL_MTL_U_IDS(ID), + INTEL_ARL_U_IDS(ID), + 0 +}; + /* * Do not initialize the .info member of the platform desc for GMD ID based * platforms. Their display will be probed automatically based on the IP version @@ -1364,6 +1370,13 @@ static const struct intel_display_device_info xe2_hpd_display = { */ static const struct platform_desc mtl_desc = { PLATFORM(meteorlake), + .subplatforms = (const struct subplatform_desc[]) { + { + SUBPLATFORM(meteorlake, u), + .pciidlist = mtl_u_ids, + }, + {}, + } }; static const struct platform_desc lnl_desc = { diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 9a333d9e66010..5853472bb9c22 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -96,6 +96,7 @@ struct pci_dev; func(dg2_g12) \ /* Display ver 14 (based on GMD ID) */ \ func(meteorlake) \ + func(meteorlake_u) \ /* Display ver 20 (based on GMD ID) */ \ func(lunarlake) \ /* Display ver 14.1 (based on GMD ID) */ \ diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h index c6518b0992cf3..46b05fa1f9030 100644 --- a/include/drm/intel/pciids.h +++ b/include/drm/intel/pciids.h @@ -811,9 +811,12 @@ INTEL_ARL_S_IDS(MACRO__, ## __VA_ARGS__) /* MTL */ -#define INTEL_MTL_IDS(MACRO__, ...) \ +#define INTEL_MTL_U_IDS(MACRO__, ...) \ MACRO__(0x7D40, ## __VA_ARGS__), \ - MACRO__(0x7D45, ## __VA_ARGS__), \ + MACRO__(0x7D45, ## __VA_ARGS__) + +#define INTEL_MTL_IDS(MACRO__, ...) \ + INTEL_MTL_U_IDS(MACRO__, ## __VA_ARGS__), \ MACRO__(0x7D55, ## __VA_ARGS__), \ MACRO__(0x7D60, ## __VA_ARGS__), \ MACRO__(0x7DD5, ## __VA_ARGS__) From 3630a47b700e65066d3c9a3b6a58af5bfca812e9 Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Bhadane Date: Wed, 18 Dec 2024 01:43:01 +0530 Subject: [PATCH 045/284] drm/i915/cx0_phy: Update HDMI TMDS C20 algorithm value In the C20 algorithm for HDMI TMDS, certain fields have been updated in the BSpec to set values for SRAM_GENERIC__TX_CNTX_CFG_1, such as tx_misc and dac_ctrl_range for Xe2LPD, Xe2HPD and MTL/ARL. This patch covers fields that need to be set based on the platform type. Some ARLs SoCs cannot be directly distinguished by their GMD version Id, Specifically to set value of tx_misc, so PCI Host Bridge IDs are used for differentiation. v2: - Relocate defines and Restructure the code(Jani) v3: - Replace conditions with display.platform. (jani) - Move host bridge check to new function (Jani) v4: - Identify/Replace arrowlake_u as meteorlake_u(Jani) Bspec:74165,74491 Signed-off-by: Dnyaneshwar Bhadane Reviewed-by: Suraj Kandpal Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20241217201301.3593054-3-dnyaneshwar.bhadane@intel.com --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 48 +++++++++++++++---- .../gpu/drm/i915/display/intel_cx0_phy_regs.h | 6 +++ .../drm/i915/display/intel_display_device.h | 11 +++++ 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 5ebc90d210d47..857262fcbac9f 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -2173,9 +2173,47 @@ static void intel_c10pll_dump_hw_state(struct intel_display *display, i + 2, hw_state->pll[i + 2], i + 3, hw_state->pll[i + 3]); } -static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state) +/* + * Some ARLs SoCs have the same drm PCI IDs, so need a helper to differentiate based + * on the host bridge device ID to get the correct txx_mics value. + */ +static bool is_arrowlake_s_by_host_bridge(void) +{ + struct pci_dev *pdev = NULL; + u16 host_bridge_pci_dev_id; + + while ((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, pdev))) + host_bridge_pci_dev_id = pdev->device; + + return pdev && IS_ARROWLAKE_S_BY_HOST_BRIDGE_ID(host_bridge_pci_dev_id); +} + +static u16 intel_c20_hdmi_tmds_tx_cgf_1(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); + u16 tx_misc; + u16 tx_dcc_cal_dac_ctrl_range = 8; + u16 tx_term_ctrl = 2; + + if (DISPLAY_VER(display) >= 20) { + tx_misc = 5; + tx_term_ctrl = 4; + } else if (display->platform.battlemage) { + tx_misc = 0; + } else if (display->platform.meteorlake_u || + is_arrowlake_s_by_host_bridge()) { + tx_misc = 3; + } else { + tx_misc = 7; + } + + return (C20_PHY_TX_MISC(tx_misc) | + C20_PHY_TX_DCC_CAL_RANGE(tx_dcc_cal_dac_ctrl_range) | + C20_PHY_TX_DCC_BYPASS | C20_PHY_TX_TERM_CTL(tx_term_ctrl)); +} + +static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state) +{ struct intel_c20pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c20; u64 datarate; u64 mpll_tx_clk_div; @@ -2185,7 +2223,6 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state) u64 mpll_multiplier; u64 mpll_fracn_quot; u64 mpll_fracn_rem; - u16 tx_misc; u8 mpllb_ana_freq_vco; u8 mpll_div_multiplier; @@ -2205,11 +2242,6 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state) mpll_div_multiplier = min_t(u8, div64_u64((vco_freq * 16 + (datarate >> 1)), datarate), 255); - if (DISPLAY_VER(display) >= 20) - tx_misc = 0x5; - else - tx_misc = 0x0; - if (vco_freq <= DATARATE_3000000000) mpllb_ana_freq_vco = MPLLB_ANA_FREQ_VCO_3; else if (vco_freq <= DATARATE_3500000000) @@ -2221,7 +2253,7 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state) pll_state->clock = crtc_state->port_clock; pll_state->tx[0] = 0xbe88; - pll_state->tx[1] = 0x9800 | C20_PHY_TX_MISC(tx_misc); + pll_state->tx[1] = intel_c20_hdmi_tmds_tx_cgf_1(crtc_state); pll_state->tx[2] = 0x0000; pll_state->cmn[0] = 0x0500; pll_state->cmn[1] = 0x0005; diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h index 4dc6e179a7741..a47fd1aef9f0f 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h @@ -294,6 +294,12 @@ #define C20_PHY_TX_RATE REG_GENMASK(2, 0) #define C20_PHY_TX_MISC_MASK REG_GENMASK16(7, 0) #define C20_PHY_TX_MISC(val) REG_FIELD_PREP16(C20_PHY_TX_MISC_MASK, (val)) +#define C20_PHY_TX_DCC_CAL_RANGE_MASK REG_GENMASK16(11, 8) +#define C20_PHY_TX_DCC_CAL_RANGE(val) \ + REG_FIELD_PREP16(C20_PHY_TX_DCC_CAL_RANGE_MASK, (val)) +#define C20_PHY_TX_DCC_BYPASS REG_BIT(12) +#define C20_PHY_TX_TERM_CTL_MASK REG_GENMASK16(15, 13) +#define C20_PHY_TX_TERM_CTL(val) REG_FIELD_PREP16(C20_PHY_TX_TERM_CTL_MASK, (val)) #define PHY_C20_A_CMN_CNTX_CFG(i915, idx) \ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_CMN_CNTX_CFG : _MTL_C20_A_CMN_CNTX_CFG) - (idx)) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 5853472bb9c22..a7b5ce69cf17d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -234,6 +234,17 @@ struct intel_display_platforms { (drm_WARN_ON(__to_intel_display(__display)->drm, INTEL_DISPLAY_STEP(__display) == STEP_NONE), \ INTEL_DISPLAY_STEP(__display) >= (since) && INTEL_DISPLAY_STEP(__display) < (until)) +#define ARLS_HOST_BRIDGE_PCI_ID1 0x7D1C +#define ARLS_HOST_BRIDGE_PCI_ID2 0x7D2D +#define ARLS_HOST_BRIDGE_PCI_ID3 0x7D2E +#define ARLS_HOST_BRIDGE_PCI_ID4 0x7D2F + +#define IS_ARROWLAKE_S_BY_HOST_BRIDGE_ID(id) \ + (((id) == ARLS_HOST_BRIDGE_PCI_ID1) || \ + ((id) == ARLS_HOST_BRIDGE_PCI_ID2) || \ + ((id) == ARLS_HOST_BRIDGE_PCI_ID3) || \ + ((id) == ARLS_HOST_BRIDGE_PCI_ID4)) + struct intel_display_runtime_info { struct intel_display_ip_ver { u16 ver; From 605a33e765890e4f1345315afc25268d4ae0fb7c Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Tue, 17 Dec 2024 14:07:23 +0530 Subject: [PATCH 046/284] drm/i915/hdcp: Fix Repeater authentication during topology change When topology changes, before beginning a new HDCP authentication by sending AKE_init message we need to first authenticate only the repeater. Only after repeater authentication failure, it makes sense to start a new HDCP authentication. Even though it made sense to not enable HDCP directly from check_link and schedule it for later, repeater authentication needs to be done immediately. --v2 -Fix comment grammatical errors [Ankit] Fixes: 47ef55a8b784 ("drm/i915/hdcp: Don't enable HDCP2.2 directly from check_link") Signed-off-by: Suraj Kandpal Reviewed-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20241217083723.2883317-1-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_hdcp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 7464b44c8bb36..c60b22aaa819e 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2188,6 +2188,19 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) drm_dbg_kms(display->drm, "HDCP2.2 Downstream topology change\n"); + + ret = hdcp2_authenticate_repeater_topology(connector); + if (!ret) { + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_ENABLED, + true); + goto out; + } + + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] Repeater topology auth failed.(%d)\n", + connector->base.base.id, connector->base.name, + ret); } else { drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 link failed, retrying auth\n", From 3abe2824e1af16580ae669a037892eb9e7ad3d54 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 10 Jan 2025 10:11:30 +0530 Subject: [PATCH 047/284] drm/i915/dsc: Use helper to calculate range_bpg_offset We get range_bpg_offset for different bpps based on linear-interpolation from values given for nearby bpps. Use a helper to get these values. Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Reviewed-by: Krzysztof Karas Link: https://patchwork.freedesktop.org/patch/msgid/20250110044131.3162682-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_vdsc.c | 59 ++++++++++++----------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index b355c479eda37..df07090c84eb8 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -66,6 +66,13 @@ intel_vdsc_set_min_max_qp(struct drm_dsc_config *vdsc_cfg, int buf, intel_lookup_range_max_qp(bpc, buf, bpp, vdsc_cfg->native_420); } +static int +get_range_bpg_offset(int bpp_low, int offset_low, int bpp_high, int offset_high, int bpp) +{ + return offset_low + DIV_ROUND_UP((offset_high - offset_low) * (bpp - bpp_low), + (bpp_low - bpp_high)); +} + /* * We are using the method provided in DSC 1.2a C-Model in codec_main.c * Above method use a common formula to derive values for any combination of DSC @@ -83,7 +90,7 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg) int qp_bpc_modifier = (bpc - 8) * 2; int uncompressed_bpg_rate; int first_line_bpg_offset; - u32 res, buf_i, bpp_i; + u32 buf_i, bpp_i; if (vdsc_cfg->slice_height >= 8) first_line_bpg_offset = @@ -163,23 +170,19 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg) intel_vdsc_set_min_max_qp(vdsc_cfg, buf_i, bpp_i); /* Calculate range_bpg_offset */ - if (bpp <= 8) { + if (bpp <= 8) range_bpg_offset = ofs_und4[buf_i]; - } else if (bpp <= 10) { - res = DIV_ROUND_UP(((bpp - 8) * - (ofs_und5[buf_i] - ofs_und4[buf_i])), 2); - range_bpg_offset = ofs_und4[buf_i] + res; - } else if (bpp <= 12) { - res = DIV_ROUND_UP(((bpp - 10) * - (ofs_und6[buf_i] - ofs_und5[buf_i])), 2); - range_bpg_offset = ofs_und5[buf_i] + res; - } else if (bpp <= 16) { - res = DIV_ROUND_UP(((bpp - 12) * - (ofs_und8[buf_i] - ofs_und6[buf_i])), 4); - range_bpg_offset = ofs_und6[buf_i] + res; - } else { + else if (bpp <= 10) + range_bpg_offset = get_range_bpg_offset(8, ofs_und4[buf_i], + 10, ofs_und5[buf_i], bpp); + else if (bpp <= 12) + range_bpg_offset = get_range_bpg_offset(10, ofs_und5[buf_i], + 12, ofs_und6[buf_i], bpp); + else if (bpp <= 16) + range_bpg_offset = get_range_bpg_offset(12, ofs_und6[buf_i], + 16, ofs_und8[buf_i], bpp); + else range_bpg_offset = ofs_und8[buf_i]; - } vdsc_cfg->rc_range_params[buf_i].range_bpg_offset = range_bpg_offset & DSC_RANGE_BPG_OFFSET_MASK; @@ -215,21 +218,19 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg) intel_vdsc_set_min_max_qp(vdsc_cfg, buf_i, bpp_i); /* Calculate range_bpg_offset */ - if (bpp <= 6) { + if (bpp <= 6) range_bpg_offset = ofs_und6[buf_i]; - } else if (bpp <= 8) { - res = DIV_ROUND_UP(((bpp - 6) * - (ofs_und8[buf_i] - ofs_und6[buf_i])), 2); - range_bpg_offset = ofs_und6[buf_i] + res; - } else if (bpp <= 12) { - range_bpg_offset = ofs_und8[buf_i]; - } else if (bpp <= 15) { - res = DIV_ROUND_UP(((bpp - 12) * - (ofs_und15[buf_i] - ofs_und12[buf_i])), 3); - range_bpg_offset = ofs_und12[buf_i] + res; - } else { + else if (bpp <= 8) + range_bpg_offset = get_range_bpg_offset(6, ofs_und6[buf_i], + 8, ofs_und8[buf_i], bpp); + else if (bpp <= 12) + range_bpg_offset = get_range_bpg_offset(8, ofs_und8[buf_i], + 12, ofs_und12[buf_i], bpp); + else if (bpp <= 15) + range_bpg_offset = get_range_bpg_offset(12, ofs_und12[buf_i], + 15, ofs_und15[buf_i], bpp); + else range_bpg_offset = ofs_und15[buf_i]; - } vdsc_cfg->rc_range_params[buf_i].range_bpg_offset = range_bpg_offset & DSC_RANGE_BPG_OFFSET_MASK; From 0d69fc7a023b8a979fc8b2bd9cd0754a24abf99d Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 10 Jan 2025 10:11:31 +0530 Subject: [PATCH 048/284] drm/i915/dsc: Remove old comment about DSC 444 support DSC with YCbCr420 is now supported, so remove the comment mentioning support for only 444 format. Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20250110044131.3162682-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_vdsc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index df07090c84eb8..1e8f71fb30945 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -124,7 +124,6 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg) vdsc_cfg->slice_height - 1); } - /* Our hw supports only 444 modes as of today */ if (bpp >= 12) vdsc_cfg->initial_offset = 2048; else if (bpp >= 10) From 58b7cd603db38d16350d380df70dbce468e99101 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 13 Jan 2025 17:38:56 -0300 Subject: [PATCH 049/284] drm/i915/display: Use display MMIO functions in intel_display_irq.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of MMIO accesses from intel_display_irq.c are currently done via uncore_*() functions instead of the display-specific ones, namely intel_de_*(). Because of that, DMC wakelock ends up being ignored and some invalid MMIO accesses are performed while display is in dynamic DC states. Thus, update the display IRQ code to use the intel_de_*() MMIO functions. After this change, we are left with some IRQ-specific functions that still use the unwrapped uncore_*() functions (i.e. gen2_irq_init, gen3_irq_reset and gen2_assert_iir_is_zero). We will deal with them in an upcoming change. Reviewed-by: Jouni Högander Signed-off-by: Gustavo Sousa Link: https://patchwork.freedesktop.org/patch/msgid/20250113204306.112266-2-gustavo.sousa@intel.com --- .../gpu/drm/i915/display/intel_display_irq.c | 222 ++++++++++-------- 1 file changed, 121 insertions(+), 101 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 069043f9d8945..9662368a651d6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -44,6 +44,7 @@ intel_handle_vblank(struct drm_i915_private *dev_priv, enum pipe pipe) void ilk_update_display_irq(struct drm_i915_private *dev_priv, u32 interrupt_mask, u32 enabled_irq_mask) { + struct intel_display *display = &dev_priv->display; u32 new_val; lockdep_assert_held(&dev_priv->irq_lock); @@ -56,8 +57,8 @@ void ilk_update_display_irq(struct drm_i915_private *dev_priv, if (new_val != dev_priv->irq_mask && !drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) { dev_priv->irq_mask = new_val; - intel_uncore_write(&dev_priv->uncore, DEIMR, dev_priv->irq_mask); - intel_uncore_posting_read(&dev_priv->uncore, DEIMR); + intel_de_write(display, DEIMR, dev_priv->irq_mask); + intel_de_posting_read(display, DEIMR); } } @@ -80,6 +81,7 @@ void ilk_disable_display_irq(struct drm_i915_private *i915, u32 bits) void bdw_update_port_irq(struct drm_i915_private *dev_priv, u32 interrupt_mask, u32 enabled_irq_mask) { + struct intel_display *display = &dev_priv->display; u32 new_val; u32 old_val; @@ -90,15 +92,15 @@ void bdw_update_port_irq(struct drm_i915_private *dev_priv, if (drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) return; - old_val = intel_uncore_read(&dev_priv->uncore, GEN8_DE_PORT_IMR); + old_val = intel_de_read(display, GEN8_DE_PORT_IMR); new_val = old_val; new_val &= ~interrupt_mask; new_val |= (~enabled_irq_mask & interrupt_mask); if (new_val != old_val) { - intel_uncore_write(&dev_priv->uncore, GEN8_DE_PORT_IMR, new_val); - intel_uncore_posting_read(&dev_priv->uncore, GEN8_DE_PORT_IMR); + intel_de_write(display, GEN8_DE_PORT_IMR, new_val); + intel_de_posting_read(display, GEN8_DE_PORT_IMR); } } @@ -113,6 +115,7 @@ static void bdw_update_pipe_irq(struct drm_i915_private *dev_priv, enum pipe pipe, u32 interrupt_mask, u32 enabled_irq_mask) { + struct intel_display *display = &dev_priv->display; u32 new_val; lockdep_assert_held(&dev_priv->irq_lock); @@ -128,9 +131,8 @@ static void bdw_update_pipe_irq(struct drm_i915_private *dev_priv, if (new_val != dev_priv->display.irq.de_irq_mask[pipe]) { dev_priv->display.irq.de_irq_mask[pipe] = new_val; - intel_uncore_write(&dev_priv->uncore, GEN8_DE_PIPE_IMR(pipe), - dev_priv->display.irq.de_irq_mask[pipe]); - intel_uncore_posting_read(&dev_priv->uncore, GEN8_DE_PIPE_IMR(pipe)); + intel_de_write(display, GEN8_DE_PIPE_IMR(pipe), display->irq.de_irq_mask[pipe]); + intel_de_posting_read(display, GEN8_DE_PIPE_IMR(pipe)); } } @@ -156,7 +158,8 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, u32 interrupt_mask, u32 enabled_irq_mask) { - u32 sdeimr = intel_uncore_read(&dev_priv->uncore, SDEIMR); + struct intel_display *display = &dev_priv->display; + u32 sdeimr = intel_de_read(display, SDEIMR); sdeimr &= ~interrupt_mask; sdeimr |= (~enabled_irq_mask & interrupt_mask); @@ -168,8 +171,8 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, if (drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) return; - intel_uncore_write(&dev_priv->uncore, SDEIMR, sdeimr); - intel_uncore_posting_read(&dev_priv->uncore, SDEIMR); + intel_de_write(display, SDEIMR, sdeimr); + intel_de_posting_read(display, SDEIMR); } void ibx_enable_display_interrupt(struct drm_i915_private *i915, u32 bits) @@ -229,6 +232,7 @@ u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv, void i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 status_mask) { + struct intel_display *display = &dev_priv->display; i915_reg_t reg = PIPESTAT(dev_priv, pipe); u32 enable_mask; @@ -245,13 +249,14 @@ void i915_enable_pipestat(struct drm_i915_private *dev_priv, dev_priv->display.irq.pipestat_irq_mask[pipe] |= status_mask; enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); - intel_uncore_write(&dev_priv->uncore, reg, enable_mask | status_mask); - intel_uncore_posting_read(&dev_priv->uncore, reg); + intel_de_write(display, reg, enable_mask | status_mask); + intel_de_posting_read(display, reg); } void i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 status_mask) { + struct intel_display *display = &dev_priv->display; i915_reg_t reg = PIPESTAT(dev_priv, pipe); u32 enable_mask; @@ -268,8 +273,8 @@ void i915_disable_pipestat(struct drm_i915_private *dev_priv, dev_priv->display.irq.pipestat_irq_mask[pipe] &= ~status_mask; enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); - intel_uncore_write(&dev_priv->uncore, reg, enable_mask | status_mask); - intel_uncore_posting_read(&dev_priv->uncore, reg); + intel_de_write(display, reg, enable_mask | status_mask); + intel_de_posting_read(display, reg); } static bool i915_has_legacy_blc_interrupt(struct intel_display *display) @@ -373,55 +378,58 @@ static void flip_done_handler(struct drm_i915_private *i915, static void hsw_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { + struct intel_display *display = &dev_priv->display; + display_pipe_crc_irq_handler(dev_priv, pipe, - intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_HSW(pipe)), + intel_de_read(display, PIPE_CRC_RES_HSW(pipe)), 0, 0, 0, 0); } static void ivb_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { + struct intel_display *display = &dev_priv->display; + display_pipe_crc_irq_handler(dev_priv, pipe, - intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_1_IVB(pipe)), - intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_2_IVB(pipe)), - intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_3_IVB(pipe)), - intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_4_IVB(pipe)), - intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_5_IVB(pipe))); + intel_de_read(display, PIPE_CRC_RES_1_IVB(pipe)), + intel_de_read(display, PIPE_CRC_RES_2_IVB(pipe)), + intel_de_read(display, PIPE_CRC_RES_3_IVB(pipe)), + intel_de_read(display, PIPE_CRC_RES_4_IVB(pipe)), + intel_de_read(display, PIPE_CRC_RES_5_IVB(pipe))); } static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { + struct intel_display *display = &dev_priv->display; u32 res1, res2; if (DISPLAY_VER(dev_priv) >= 3) - res1 = intel_uncore_read(&dev_priv->uncore, - PIPE_CRC_RES_RES1_I915(dev_priv, pipe)); + res1 = intel_de_read(display, PIPE_CRC_RES_RES1_I915(dev_priv, pipe)); else res1 = 0; if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) - res2 = intel_uncore_read(&dev_priv->uncore, - PIPE_CRC_RES_RES2_G4X(dev_priv, pipe)); + res2 = intel_de_read(display, PIPE_CRC_RES_RES2_G4X(dev_priv, pipe)); else res2 = 0; display_pipe_crc_irq_handler(dev_priv, pipe, - intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RED(dev_priv, pipe)), - intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_GREEN(dev_priv, pipe)), - intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_BLUE(dev_priv, pipe)), + intel_de_read(display, PIPE_CRC_RES_RED(dev_priv, pipe)), + intel_de_read(display, PIPE_CRC_RES_GREEN(dev_priv, pipe)), + intel_de_read(display, PIPE_CRC_RES_BLUE(dev_priv, pipe)), res1, res2); } static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; enum pipe pipe; for_each_pipe(dev_priv, pipe) { - intel_uncore_write(&dev_priv->uncore, - PIPESTAT(dev_priv, pipe), - PIPESTAT_INT_STATUS_MASK | - PIPE_FIFO_UNDERRUN_STATUS); + intel_de_write(display, + PIPESTAT(dev_priv, pipe), + PIPESTAT_INT_STATUS_MASK | PIPE_FIFO_UNDERRUN_STATUS); dev_priv->display.irq.pipestat_irq_mask[pipe] = 0; } @@ -430,6 +438,7 @@ static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { + struct intel_display *display = &dev_priv->display; enum pipe pipe; spin_lock(&dev_priv->irq_lock); @@ -474,7 +483,7 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, continue; reg = PIPESTAT(dev_priv, pipe); - pipe_stats[pipe] = intel_uncore_read(&dev_priv->uncore, reg) & status_mask; + pipe_stats[pipe] = intel_de_read(display, reg) & status_mask; enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); /* @@ -487,8 +496,8 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, * an interrupt is still pending. */ if (pipe_stats[pipe]) { - intel_uncore_write(&dev_priv->uncore, reg, pipe_stats[pipe]); - intel_uncore_write(&dev_priv->uncore, reg, enable_mask); + intel_de_write(display, reg, pipe_stats[pipe]); + intel_de_write(display, reg, enable_mask); } } spin_unlock(&dev_priv->irq_lock); @@ -605,7 +614,7 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) for_each_pipe(dev_priv, pipe) drm_dbg(&dev_priv->drm, " pipe %c FDI IIR: 0x%08x\n", pipe_name(pipe), - intel_uncore_read(&dev_priv->uncore, FDI_RX_IIR(pipe))); + intel_de_read(display, FDI_RX_IIR(pipe))); } if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE)) @@ -624,7 +633,8 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) static void ivb_err_int_handler(struct drm_i915_private *dev_priv) { - u32 err_int = intel_uncore_read(&dev_priv->uncore, GEN7_ERR_INT); + struct intel_display *display = &dev_priv->display; + u32 err_int = intel_de_read(display, GEN7_ERR_INT); enum pipe pipe; if (err_int & ERR_INT_POISON) @@ -642,12 +652,13 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv) } } - intel_uncore_write(&dev_priv->uncore, GEN7_ERR_INT, err_int); + intel_de_write(display, GEN7_ERR_INT, err_int); } static void cpt_serr_int_handler(struct drm_i915_private *dev_priv) { - u32 serr_int = intel_uncore_read(&dev_priv->uncore, SERR_INT); + struct intel_display *display = &dev_priv->display; + u32 serr_int = intel_de_read(display, SERR_INT); enum pipe pipe; if (serr_int & SERR_INT_POISON) @@ -657,7 +668,7 @@ static void cpt_serr_int_handler(struct drm_i915_private *dev_priv) if (serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pipe)) intel_pch_fifo_underrun_irq_handler(dev_priv, pipe); - intel_uncore_write(&dev_priv->uncore, SERR_INT, serr_int); + intel_de_write(display, SERR_INT, serr_int); } static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) @@ -691,7 +702,7 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) for_each_pipe(dev_priv, pipe) drm_dbg(&dev_priv->drm, " pipe %c FDI IIR: 0x%08x\n", pipe_name(pipe), - intel_uncore_read(&dev_priv->uncore, FDI_RX_IIR(pipe))); + intel_de_read(display, FDI_RX_IIR(pipe))); } if (pch_iir & SDE_ERROR_CPT) @@ -732,7 +743,7 @@ void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) /* check event from PCH */ if (de_iir & DE_PCH_EVENT) { - u32 pch_iir = intel_uncore_read(&dev_priv->uncore, SDEIIR); + u32 pch_iir = intel_de_read(display, SDEIIR); if (HAS_PCH_CPT(dev_priv)) cpt_irq_handler(dev_priv, pch_iir); @@ -740,7 +751,7 @@ void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) ibx_irq_handler(dev_priv, pch_iir); /* should clear PCH hotplug event before clear CPU irq */ - intel_uncore_write(&dev_priv->uncore, SDEIIR, pch_iir); + intel_de_write(display, SDEIIR, pch_iir); } if (DISPLAY_VER(dev_priv) == 5 && de_iir & DE_PCU_EVENT) @@ -766,8 +777,7 @@ void ivb_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) struct intel_dp *intel_dp = enc_to_intel_dp(encoder); u32 psr_iir; - psr_iir = intel_uncore_rmw(&dev_priv->uncore, - EDP_PSR_IIR, 0, 0); + psr_iir = intel_de_rmw(display, EDP_PSR_IIR, 0, 0); intel_psr_irq_handler(intel_dp, psr_iir); break; } @@ -789,12 +799,12 @@ void ivb_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) /* check event from PCH */ if (!HAS_PCH_NOP(dev_priv) && (de_iir & DE_PCH_EVENT_IVB)) { - u32 pch_iir = intel_uncore_read(&dev_priv->uncore, SDEIIR); + u32 pch_iir = intel_de_read(display, SDEIIR); cpt_irq_handler(dev_priv, pch_iir); /* clear PCH hotplug event before clear CPU irq */ - intel_uncore_write(&dev_priv->uncore, SDEIIR, pch_iir); + intel_de_write(display, SDEIIR, pch_iir); } } @@ -925,8 +935,7 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) } if (iir & XELPDP_RM_TIMEOUT) { - u32 val = intel_uncore_read(&dev_priv->uncore, - RM_TIMEOUT_REG_CAPTURE); + u32 val = intel_de_read(display, RM_TIMEOUT_REG_CAPTURE); drm_warn(&dev_priv->drm, "Register Access Timeout = 0x%x\n", val); found = true; } @@ -949,7 +958,7 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) else iir_reg = EDP_PSR_IIR; - psr_iir = intel_uncore_rmw(&dev_priv->uncore, iir_reg, 0, 0); + psr_iir = intel_de_rmw(display, iir_reg, 0, 0); if (psr_iir) found = true; @@ -969,6 +978,7 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, u32 te_trigger) { + struct intel_display *display = &dev_priv->display; enum pipe pipe = INVALID_PIPE; enum transcoder dsi_trans; enum port port; @@ -978,8 +988,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, * Incase of dual link, TE comes from DSI_1 * this is to check if dual link is enabled */ - val = intel_uncore_read(&dev_priv->uncore, - TRANS_DDI_FUNC_CTL2(dev_priv, TRANSCODER_DSI_0)); + val = intel_de_read(display, TRANS_DDI_FUNC_CTL2(dev_priv, TRANSCODER_DSI_0)); val &= PORT_SYNC_MODE_ENABLE; /* @@ -991,7 +1000,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, dsi_trans = (port == PORT_A) ? TRANSCODER_DSI_0 : TRANSCODER_DSI_1; /* Check if DSI configured in command mode */ - val = intel_uncore_read(&dev_priv->uncore, DSI_TRANS_FUNC_CONF(dsi_trans)); + val = intel_de_read(display, DSI_TRANS_FUNC_CONF(dsi_trans)); val = val & OP_MODE_MASK; if (val != CMD_MODE_NO_GATE && val != CMD_MODE_TE_GATE) { @@ -1000,8 +1009,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, } /* Get PIPE for handling VBLANK event */ - val = intel_uncore_read(&dev_priv->uncore, - TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans)); + val = intel_de_read(display, TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans)); switch (val & TRANS_DDI_EDP_INPUT_MASK) { case TRANS_DDI_EDP_INPUT_A_ON: pipe = PIPE_A; @@ -1021,7 +1029,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, /* clear TE in dsi IIR */ port = (te_trigger & DSI1_TE) ? PORT_B : PORT_A; - intel_uncore_rmw(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), 0, 0); + intel_de_rmw(display, DSI_INTR_IDENT_REG(port), 0, 0); } static u32 gen8_de_pipe_flip_done_mask(struct drm_i915_private *i915) @@ -1034,10 +1042,11 @@ static u32 gen8_de_pipe_flip_done_mask(struct drm_i915_private *i915) static void gen8_read_and_ack_pch_irqs(struct drm_i915_private *i915, u32 *pch_iir, u32 *pica_iir) { + struct intel_display *display = &i915->display; u32 pica_ier = 0; *pica_iir = 0; - *pch_iir = intel_de_read(i915, SDEIIR); + *pch_iir = intel_de_read(display, SDEIIR); if (!*pch_iir) return; @@ -1049,15 +1058,15 @@ static void gen8_read_and_ack_pch_irqs(struct drm_i915_private *i915, u32 *pch_i if (*pch_iir & SDE_PICAINTERRUPT) { drm_WARN_ON(&i915->drm, INTEL_PCH_TYPE(i915) < PCH_MTL); - pica_ier = intel_de_rmw(i915, PICAINTERRUPT_IER, ~0, 0); - *pica_iir = intel_de_read(i915, PICAINTERRUPT_IIR); - intel_de_write(i915, PICAINTERRUPT_IIR, *pica_iir); + pica_ier = intel_de_rmw(display, PICAINTERRUPT_IER, ~0, 0); + *pica_iir = intel_de_read(display, PICAINTERRUPT_IIR); + intel_de_write(display, PICAINTERRUPT_IIR, *pica_iir); } - intel_de_write(i915, SDEIIR, *pch_iir); + intel_de_write(display, SDEIIR, *pch_iir); if (pica_ier) - intel_de_write(i915, PICAINTERRUPT_IER, pica_ier); + intel_de_write(display, PICAINTERRUPT_IER, pica_ier); } void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) @@ -1069,9 +1078,9 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) drm_WARN_ON_ONCE(&dev_priv->drm, !HAS_DISPLAY(dev_priv)); if (master_ctl & GEN8_DE_MISC_IRQ) { - iir = intel_uncore_read(&dev_priv->uncore, GEN8_DE_MISC_IIR); + iir = intel_de_read(display, GEN8_DE_MISC_IIR); if (iir) { - intel_uncore_write(&dev_priv->uncore, GEN8_DE_MISC_IIR, iir); + intel_de_write(display, GEN8_DE_MISC_IIR, iir); gen8_de_misc_irq_handler(dev_priv, iir); } else { drm_err_ratelimited(&dev_priv->drm, @@ -1080,9 +1089,9 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) } if (DISPLAY_VER(dev_priv) >= 11 && (master_ctl & GEN11_DE_HPD_IRQ)) { - iir = intel_uncore_read(&dev_priv->uncore, GEN11_DE_HPD_IIR); + iir = intel_de_read(display, GEN11_DE_HPD_IIR); if (iir) { - intel_uncore_write(&dev_priv->uncore, GEN11_DE_HPD_IIR, iir); + intel_de_write(display, GEN11_DE_HPD_IIR, iir); gen11_hpd_irq_handler(dev_priv, iir); } else { drm_err_ratelimited(&dev_priv->drm, @@ -1091,11 +1100,11 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) } if (master_ctl & GEN8_DE_PORT_IRQ) { - iir = intel_uncore_read(&dev_priv->uncore, GEN8_DE_PORT_IIR); + iir = intel_de_read(display, GEN8_DE_PORT_IIR); if (iir) { bool found = false; - intel_uncore_write(&dev_priv->uncore, GEN8_DE_PORT_IIR, iir); + intel_de_write(display, GEN8_DE_PORT_IIR, iir); if (iir & gen8_de_port_aux_mask(dev_priv)) { intel_dp_aux_irq_handler(display); @@ -1148,14 +1157,14 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) continue; - iir = intel_uncore_read(&dev_priv->uncore, GEN8_DE_PIPE_IIR(pipe)); + iir = intel_de_read(display, GEN8_DE_PIPE_IIR(pipe)); if (!iir) { drm_err_ratelimited(&dev_priv->drm, "The master control interrupt lied (DE PIPE)!\n"); continue; } - intel_uncore_write(&dev_priv->uncore, GEN8_DE_PIPE_IIR(pipe), iir); + intel_de_write(display, GEN8_DE_PIPE_IIR(pipe), iir); if (iir & GEN8_PIPE_VBLANK) intel_handle_vblank(dev_priv, pipe); @@ -1221,14 +1230,15 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl) { + struct intel_display *display = &i915->display; u32 iir; if (!(master_ctl & GEN11_GU_MISC_IRQ)) return 0; - iir = intel_de_read(i915, GEN11_GU_MISC_IIR); + iir = intel_de_read(display, GEN11_GU_MISC_IIR); if (likely(iir)) - intel_de_write(i915, GEN11_GU_MISC_IIR, iir); + intel_de_write(display, GEN11_GU_MISC_IIR, iir); return iir; } @@ -1243,6 +1253,7 @@ void gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir) void gen11_display_irq_handler(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; u32 disp_ctl; disable_rpm_wakeref_asserts(&i915->runtime_pm); @@ -1250,17 +1261,18 @@ void gen11_display_irq_handler(struct drm_i915_private *i915) * GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ * for the display related bits. */ - disp_ctl = intel_de_read(i915, GEN11_DISPLAY_INT_CTL); + disp_ctl = intel_de_read(display, GEN11_DISPLAY_INT_CTL); - intel_de_write(i915, GEN11_DISPLAY_INT_CTL, 0); + intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0); gen8_de_irq_handler(i915, disp_ctl); - intel_de_write(i915, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); + intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); enable_rpm_wakeref_asserts(&i915->runtime_pm); } static void i915gm_irq_cstate_wa_enable(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; lockdep_assert_held(&i915->drm.vblank_time_lock); /* @@ -1270,15 +1282,18 @@ static void i915gm_irq_cstate_wa_enable(struct drm_i915_private *i915) * only when vblank/CRC interrupts are actually enabled. */ if (i915->display.irq.vblank_enabled++ == 0) - intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); + intel_de_write(display, SCPD0, + _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); } static void i915gm_irq_cstate_wa_disable(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; lockdep_assert_held(&i915->drm.vblank_time_lock); if (--i915->display.irq.vblank_enabled == 0) - intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); + intel_de_write(display, SCPD0, + _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); } void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable) @@ -1398,7 +1413,7 @@ void ilk_disable_vblank(struct drm_crtc *crtc) static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc, bool enable) { - struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); + struct intel_display *display = to_intel_display(intel_crtc); enum port port; if (!(intel_crtc->mode_flags & @@ -1411,10 +1426,9 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc, else port = PORT_A; - intel_uncore_rmw(&dev_priv->uncore, DSI_INTR_MASK_REG(port), DSI_TE_EVENT, - enable ? 0 : DSI_TE_EVENT); + intel_de_rmw(display, DSI_INTR_MASK_REG(port), DSI_TE_EVENT, enable ? 0 : DSI_TE_EVENT); - intel_uncore_rmw(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), 0, 0); + intel_de_rmw(display, DSI_INTR_IDENT_REG(port), 0, 0); return true; } @@ -1483,15 +1497,16 @@ void bdw_disable_vblank(struct drm_crtc *_crtc) static void _vlv_display_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; if (IS_CHERRYVIEW(dev_priv)) - intel_uncore_write(uncore, DPINVGTT, DPINVGTT_STATUS_MASK_CHV); + intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_CHV); else - intel_uncore_write(uncore, DPINVGTT, DPINVGTT_STATUS_MASK_VLV); + intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_VLV); i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0); - intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT(dev_priv), 0, 0); + intel_de_rmw(display, PORT_HOTPLUG_STAT(dev_priv), 0, 0); i9xx_pipestat_irq_reset(dev_priv); @@ -1507,10 +1522,11 @@ void vlv_display_irq_reset(struct drm_i915_private *dev_priv) void i9xx_display_irq_reset(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; + if (I915_HAS_HOTPLUG(i915)) { i915_hotplug_interrupt_update(i915, 0xffffffff, 0); - intel_uncore_rmw(&i915->uncore, - PORT_HOTPLUG_STAT(i915), 0, 0); + intel_de_rmw(display, PORT_HOTPLUG_STAT(i915), 0, 0); } i9xx_pipestat_irq_reset(i915); @@ -1552,14 +1568,15 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) void gen8_display_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; enum pipe pipe; if (!HAS_DISPLAY(dev_priv)) return; - intel_uncore_write(uncore, EDP_PSR_IMR, 0xffffffff); - intel_uncore_write(uncore, EDP_PSR_IIR, 0xffffffff); + intel_de_write(display, EDP_PSR_IMR, 0xffffffff); + intel_de_write(display, EDP_PSR_IIR, 0xffffffff); for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, @@ -1572,6 +1589,7 @@ void gen8_display_irq_reset(struct drm_i915_private *dev_priv) void gen11_display_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; enum pipe pipe; u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | @@ -1580,7 +1598,7 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) if (!HAS_DISPLAY(dev_priv)) return; - intel_uncore_write(uncore, GEN11_DISPLAY_INT_CTL, 0); + intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0); if (DISPLAY_VER(dev_priv) >= 12) { enum transcoder trans; @@ -1592,16 +1610,16 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) if (!intel_display_power_is_enabled(dev_priv, domain)) continue; - intel_uncore_write(uncore, - TRANS_PSR_IMR(dev_priv, trans), - 0xffffffff); - intel_uncore_write(uncore, - TRANS_PSR_IIR(dev_priv, trans), - 0xffffffff); + intel_de_write(display, + TRANS_PSR_IMR(dev_priv, trans), + 0xffffffff); + intel_de_write(display, + TRANS_PSR_IIR(dev_priv, trans), + 0xffffffff); } } else { - intel_uncore_write(uncore, EDP_PSR_IMR, 0xffffffff); - intel_uncore_write(uncore, EDP_PSR_IIR, 0xffffffff); + intel_de_write(display, EDP_PSR_IMR, 0xffffffff); + intel_de_write(display, EDP_PSR_IIR, 0xffffffff); } for_each_pipe(dev_priv, pipe) @@ -1890,23 +1908,25 @@ static void icp_irq_postinstall(struct drm_i915_private *dev_priv) void gen11_de_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; + if (!HAS_DISPLAY(dev_priv)) return; gen8_de_irq_postinstall(dev_priv); - intel_uncore_write(&dev_priv->uncore, GEN11_DISPLAY_INT_CTL, - GEN11_DISPLAY_IRQ_ENABLE); + intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); } void dg1_de_irq_postinstall(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; + if (!HAS_DISPLAY(i915)) return; gen8_de_irq_postinstall(i915); - intel_uncore_write(&i915->uncore, GEN11_DISPLAY_INT_CTL, - GEN11_DISPLAY_IRQ_ENABLE); + intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); } void intel_display_irq_init(struct drm_i915_private *i915) From 6d531e350572163f5e3ec832710d459d1232c3cb Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 13 Jan 2025 17:38:57 -0300 Subject: [PATCH 050/284] drm/i915/display: Wrap IRQ-specific uncore functions The current display IRQ code calls some IRQ-specific helpers that use intel_uncore_*() MMIO functions instead of the display-specific ones. Wrap those helpers to ensure that the proper display-specific hooks (currently only DMC wakelock handling) are called. v2: - Move functions to intel_display_irq.c instead of having them in intel_de.h. (Jani) Cc: Jani Nikula Reviewed-by: Luca Coelho Signed-off-by: Gustavo Sousa Link: https://patchwork.freedesktop.org/patch/msgid/20250113204306.112266-3-gustavo.sousa@intel.com --- .../gpu/drm/i915/display/intel_display_irq.c | 128 ++++++++++++------ 1 file changed, 83 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 9662368a651d6..d9734fcd0d45b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -15,6 +15,7 @@ #include "intel_display_irq.h" #include "intel_display_trace.h" #include "intel_display_types.h" +#include "intel_dmc_wl.h" #include "intel_dp_aux.h" #include "intel_dsb.h" #include "intel_fdi_regs.h" @@ -25,6 +26,46 @@ #include "intel_pmdemand.h" #include "intel_psr.h" #include "intel_psr_regs.h" +#include "intel_uncore.h" + +static void +intel_display_irq_regs_init(struct intel_display *display, struct i915_irq_regs regs, + u32 imr_val, u32 ier_val) +{ + intel_dmc_wl_get(display, regs.imr); + intel_dmc_wl_get(display, regs.ier); + intel_dmc_wl_get(display, regs.iir); + + gen2_irq_init(to_intel_uncore(display->drm), regs, imr_val, ier_val); + + intel_dmc_wl_put(display, regs.iir); + intel_dmc_wl_put(display, regs.ier); + intel_dmc_wl_put(display, regs.imr); +} + +static void +intel_display_irq_regs_reset(struct intel_display *display, struct i915_irq_regs regs) +{ + intel_dmc_wl_get(display, regs.imr); + intel_dmc_wl_get(display, regs.ier); + intel_dmc_wl_get(display, regs.iir); + + gen2_irq_reset(to_intel_uncore(display->drm), regs); + + intel_dmc_wl_put(display, regs.iir); + intel_dmc_wl_put(display, regs.ier); + intel_dmc_wl_put(display, regs.imr); +} + +static void +intel_display_irq_regs_assert_irr_is_zero(struct intel_display *display, i915_reg_t reg) +{ + intel_dmc_wl_get(display, reg); + + gen2_assert_iir_is_zero(to_intel_uncore(display->drm), reg); + + intel_dmc_wl_put(display, reg); +} static void intel_handle_vblank(struct drm_i915_private *dev_priv, enum pipe pipe) @@ -1498,7 +1539,6 @@ void bdw_disable_vblank(struct drm_crtc *_crtc) static void _vlv_display_irq_reset(struct drm_i915_private *dev_priv) { struct intel_display *display = &dev_priv->display; - struct intel_uncore *uncore = &dev_priv->uncore; if (IS_CHERRYVIEW(dev_priv)) intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_CHV); @@ -1510,7 +1550,7 @@ static void _vlv_display_irq_reset(struct drm_i915_private *dev_priv) i9xx_pipestat_irq_reset(dev_priv); - gen2_irq_reset(uncore, VLV_IRQ_REGS); + intel_display_irq_regs_reset(display, VLV_IRQ_REGS); dev_priv->irq_mask = ~0u; } @@ -1534,8 +1574,7 @@ void i9xx_display_irq_reset(struct drm_i915_private *i915) void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) { - struct intel_uncore *uncore = &dev_priv->uncore; - + struct intel_display *display = &dev_priv->display; u32 pipestat_mask; u32 enable_mask; enum pipe pipe; @@ -1563,13 +1602,12 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) dev_priv->irq_mask = ~enable_mask; - gen2_irq_init(uncore, VLV_IRQ_REGS, dev_priv->irq_mask, enable_mask); + intel_display_irq_regs_init(display, VLV_IRQ_REGS, dev_priv->irq_mask, enable_mask); } void gen8_display_irq_reset(struct drm_i915_private *dev_priv) { struct intel_display *display = &dev_priv->display; - struct intel_uncore *uncore = &dev_priv->uncore; enum pipe pipe; if (!HAS_DISPLAY(dev_priv)) @@ -1581,16 +1619,15 @@ void gen8_display_irq_reset(struct drm_i915_private *dev_priv) for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) - gen2_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe)); + intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); - gen2_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS); - gen2_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS); + intel_display_irq_regs_reset(display, GEN8_DE_PORT_IRQ_REGS); + intel_display_irq_regs_reset(display, GEN8_DE_MISC_IRQ_REGS); } void gen11_display_irq_reset(struct drm_i915_private *dev_priv) { struct intel_display *display = &dev_priv->display; - struct intel_uncore *uncore = &dev_priv->uncore; enum pipe pipe; u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); @@ -1625,24 +1662,24 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) - gen2_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe)); + intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); - gen2_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS); - gen2_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS); + intel_display_irq_regs_reset(display, GEN8_DE_PORT_IRQ_REGS); + intel_display_irq_regs_reset(display, GEN8_DE_MISC_IRQ_REGS); if (DISPLAY_VER(dev_priv) >= 14) - gen2_irq_reset(uncore, PICAINTERRUPT_IRQ_REGS); + intel_display_irq_regs_reset(display, PICAINTERRUPT_IRQ_REGS); else - gen2_irq_reset(uncore, GEN11_DE_HPD_IRQ_REGS); + intel_display_irq_regs_reset(display, GEN11_DE_HPD_IRQ_REGS); if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - gen2_irq_reset(uncore, SDE_IRQ_REGS); + intel_display_irq_regs_reset(display, SDE_IRQ_REGS); } void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, u8 pipe_mask) { - struct intel_uncore *uncore = &dev_priv->uncore; + struct intel_display *display = &dev_priv->display; u32 extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN | gen8_de_pipe_flip_done_mask(dev_priv); enum pipe pipe; @@ -1655,9 +1692,9 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, } for_each_pipe_masked(dev_priv, pipe, pipe_mask) - gen2_irq_init(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe), - dev_priv->display.irq.de_irq_mask[pipe], - ~dev_priv->display.irq.de_irq_mask[pipe] | extra_ier); + intel_display_irq_regs_init(display, GEN8_DE_PIPE_IRQ_REGS(pipe), + dev_priv->display.irq.de_irq_mask[pipe], + ~dev_priv->display.irq.de_irq_mask[pipe] | extra_ier); spin_unlock_irq(&dev_priv->irq_lock); } @@ -1665,7 +1702,7 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, u8 pipe_mask) { - struct intel_uncore *uncore = &dev_priv->uncore; + struct intel_display *display = &dev_priv->display; enum pipe pipe; spin_lock_irq(&dev_priv->irq_lock); @@ -1676,7 +1713,7 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, } for_each_pipe_masked(dev_priv, pipe, pipe_mask) - gen2_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe)); + intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); spin_unlock_irq(&dev_priv->irq_lock); @@ -1697,7 +1734,7 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, */ static void ibx_irq_postinstall(struct drm_i915_private *dev_priv) { - struct intel_uncore *uncore = &dev_priv->uncore; + struct intel_display *display = &dev_priv->display; u32 mask; if (HAS_PCH_NOP(dev_priv)) @@ -1710,7 +1747,7 @@ static void ibx_irq_postinstall(struct drm_i915_private *dev_priv) else mask = SDE_GMBUS_CPT; - gen2_irq_init(uncore, SDE_IRQ_REGS, ~mask, 0xffffffff); + intel_display_irq_regs_init(display, SDE_IRQ_REGS, ~mask, 0xffffffff); } void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv) @@ -1743,7 +1780,7 @@ void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv) void ilk_de_irq_postinstall(struct drm_i915_private *i915) { - struct intel_uncore *uncore = &i915->uncore; + struct intel_display *display = &i915->display; u32 display_mask, extra_mask; if (DISPLAY_VER(i915) >= 7) { @@ -1767,7 +1804,7 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915) } if (IS_HASWELL(i915)) { - gen2_assert_iir_is_zero(uncore, EDP_PSR_IIR); + intel_display_irq_regs_assert_irr_is_zero(display, EDP_PSR_IIR); display_mask |= DE_EDP_PSR_INT_HSW; } @@ -1778,8 +1815,8 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915) ibx_irq_postinstall(i915); - gen2_irq_init(uncore, DE_IRQ_REGS, i915->irq_mask, - display_mask | extra_mask); + intel_display_irq_regs_init(display, DE_IRQ_REGS, i915->irq_mask, + display_mask | extra_mask); } static void mtp_irq_postinstall(struct drm_i915_private *i915); @@ -1788,7 +1825,6 @@ static void icp_irq_postinstall(struct drm_i915_private *i915); void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) { struct intel_display *display = &dev_priv->display; - struct intel_uncore *uncore = &dev_priv->uncore; u32 de_pipe_masked = gen8_de_pipe_fault_mask(dev_priv) | GEN8_PIPE_CDCLK_CRC_DONE; @@ -1854,11 +1890,11 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) if (!intel_display_power_is_enabled(dev_priv, domain)) continue; - gen2_assert_iir_is_zero(uncore, - TRANS_PSR_IIR(dev_priv, trans)); + intel_display_irq_regs_assert_irr_is_zero(display, + TRANS_PSR_IIR(dev_priv, trans)); } } else { - gen2_assert_iir_is_zero(uncore, EDP_PSR_IIR); + intel_display_irq_regs_assert_irr_is_zero(display, EDP_PSR_IIR); } for_each_pipe(dev_priv, pipe) { @@ -1866,44 +1902,46 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) - gen2_irq_init(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe), - dev_priv->display.irq.de_irq_mask[pipe], - de_pipe_enables); + intel_display_irq_regs_init(display, GEN8_DE_PIPE_IRQ_REGS(pipe), + dev_priv->display.irq.de_irq_mask[pipe], + de_pipe_enables); } - gen2_irq_init(uncore, GEN8_DE_PORT_IRQ_REGS, ~de_port_masked, de_port_enables); - gen2_irq_init(uncore, GEN8_DE_MISC_IRQ_REGS, ~de_misc_masked, de_misc_masked); + intel_display_irq_regs_init(display, GEN8_DE_PORT_IRQ_REGS, ~de_port_masked, + de_port_enables); + intel_display_irq_regs_init(display, GEN8_DE_MISC_IRQ_REGS, ~de_misc_masked, + de_misc_masked); if (IS_DISPLAY_VER(dev_priv, 11, 13)) { u32 de_hpd_masked = 0; u32 de_hpd_enables = GEN11_DE_TC_HOTPLUG_MASK | GEN11_DE_TBT_HOTPLUG_MASK; - gen2_irq_init(uncore, GEN11_DE_HPD_IRQ_REGS, ~de_hpd_masked, - de_hpd_enables); + intel_display_irq_regs_init(display, GEN11_DE_HPD_IRQ_REGS, ~de_hpd_masked, + de_hpd_enables); } } static void mtp_irq_postinstall(struct drm_i915_private *i915) { - struct intel_uncore *uncore = &i915->uncore; + struct intel_display *display = &i915->display; u32 sde_mask = SDE_GMBUS_ICP | SDE_PICAINTERRUPT; u32 de_hpd_mask = XELPDP_AUX_TC_MASK; u32 de_hpd_enables = de_hpd_mask | XELPDP_DP_ALT_HOTPLUG_MASK | XELPDP_TBT_HOTPLUG_MASK; - gen2_irq_init(uncore, PICAINTERRUPT_IRQ_REGS, ~de_hpd_mask, - de_hpd_enables); + intel_display_irq_regs_init(display, PICAINTERRUPT_IRQ_REGS, ~de_hpd_mask, + de_hpd_enables); - gen2_irq_init(uncore, SDE_IRQ_REGS, ~sde_mask, 0xffffffff); + intel_display_irq_regs_init(display, SDE_IRQ_REGS, ~sde_mask, 0xffffffff); } static void icp_irq_postinstall(struct drm_i915_private *dev_priv) { - struct intel_uncore *uncore = &dev_priv->uncore; + struct intel_display *display = &dev_priv->display; u32 mask = SDE_GMBUS_ICP; - gen2_irq_init(uncore, SDE_IRQ_REGS, ~mask, 0xffffffff); + intel_display_irq_regs_init(display, SDE_IRQ_REGS, ~mask, 0xffffffff); } void gen11_de_irq_postinstall(struct drm_i915_private *dev_priv) From 9983fd3c8dc315e0e4869d4522787163de57e0e9 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 13 Jan 2025 17:38:58 -0300 Subject: [PATCH 051/284] drm/i915/dmc_wl: Track pipe interrupt registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pipe interrupt registers live in their respective pipes' power wells, which are below PG0. That means that they must also be tracked as registers that are powered-off during dynamic DC states. There are probably more ranges that we need to track down and add to the powered_off_ranges. However, let's make this change only about pipe interrupt registers to fix some vblank timeouts observed due to the DMC wakelock not being taken for those registers. In the future, we might want to replace powered_off_ranges with a new table to represent registers in PG0, which should be probably easier to maintain. Any register not belonging to that table should be considered powered off during dynamic DC states and, as such, requiring the DMC wakelock for access. Bspec: 72519, 71583 Reviewed-by: Jouni Högander Signed-off-by: Gustavo Sousa Link: https://patchwork.freedesktop.org/patch/msgid/20250113204306.112266-4-gustavo.sousa@intel.com --- drivers/gpu/drm/i915/display/intel_dmc_wl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 1bdc08e6aa452..43884740f8ead 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -67,6 +67,7 @@ struct intel_dmc_wl_range { }; static const struct intel_dmc_wl_range powered_off_ranges[] = { + { .start = 0x44400, .end = 0x4447f }, /* PIPE interrupt registers */ { .start = 0x60000, .end = 0x7ffff }, {}, }; From 38f039f45964425d0d345e930ec1de53ab9b9c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 9 Oct 2024 21:21:59 +0300 Subject: [PATCH 052/284] drm/i915: Allow async flips with render compression on TGL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looks like CCS + async flips has been a thing for a while now. Enable this for TGL+ render compression modifiers. Note that we can't update AUX_DIST during async flips we must check to make sure it remains unchanged. We also can't do clear color. Supposedly there was some attempt to make it work, but apparently the issues only got ironed out in MTL. For now we'll not worry about it and refuse async flips with clear color modifiers. Bspec claims that media compression doesn't support async flips. Based on a quick test it does seem to work to some degree, but perhaps it has issues as well. Let's trust the spec here and continue to refuse async flips + media compression. Bspec: 49250,49251,49252,49253 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241009182207.22900-2-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_display.c | 14 +++++++++++++- .../gpu/drm/i915/display/skl_universal_plane.c | 17 ++++++++++------- .../gpu/drm/i915/display/skl_universal_plane.h | 3 +++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index f5d2eacce119b..9c2db307a6600 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6554,6 +6554,9 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in case I915_FORMAT_MOD_Y_TILED: case I915_FORMAT_MOD_Yf_TILED: case I915_FORMAT_MOD_4_TILED: + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: + case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS: + case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS: case I915_FORMAT_MOD_4_TILED_BMG_CCS: case I915_FORMAT_MOD_4_TILED_LNL_CCS: break; @@ -6565,7 +6568,8 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in return -EINVAL; } - if (new_plane_state->hw.fb->format->num_planes > 1) { + if (intel_format_info_is_yuv_semiplanar(new_plane_state->hw.fb->format, + new_plane_state->hw.fb->modifier)) { drm_dbg_kms(&i915->drm, "[PLANE:%d:%s] Planar formats do not support async flips\n", plane->base.base.id, plane->base.name); @@ -6611,6 +6615,14 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in return -EINVAL; } + if (skl_plane_aux_dist(old_plane_state, 0) != + skl_plane_aux_dist(new_plane_state, 0)) { + drm_dbg_kms(&i915->drm, + "[PLANE:%d:%s] AUX_DIST cannot be changed in async flip\n", + plane->base.base.id, plane->base.name); + return -EINVAL; + } + if (!drm_rect_equals(&old_plane_state->uapi.src, &new_plane_state->uapi.src) || !drm_rect_equals(&old_plane_state->uapi.dst, &new_plane_state->uapi.dst)) { drm_dbg_kms(&i915->drm, diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index ff9764cac1e71..00ee7dfdeb5b8 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -541,15 +541,18 @@ static u32 tgl_plane_min_alignment(struct intel_plane *plane, if (IS_ALDERLAKE_P(i915) && HAS_ASYNC_FLIPS(i915)) return mult * 16 * 1024; return mult * 4 * 1024; - case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: - case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: - case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS: case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS: - case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC: case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS: - case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC: + if (IS_ALDERLAKE_P(i915) && HAS_ASYNC_FLIPS(i915)) + return mult * 16 * 1024; + fallthrough; + case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: + case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS: case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS: + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: + case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC: + case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC: case I915_FORMAT_MOD_4_TILED_BMG_CCS: case I915_FORMAT_MOD_4_TILED_LNL_CCS: /* @@ -1229,8 +1232,8 @@ static u32 skl_plane_surf(const struct intel_plane_state *plane_state, return plane_surf; } -static u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state, - int color_plane) +u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state, + int color_plane) { struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); const struct drm_framebuffer *fb = plane_state->hw.fb; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.h b/drivers/gpu/drm/i915/display/skl_universal_plane.h index 541489479135d..18b41d13f0bde 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.h +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.h @@ -37,4 +37,7 @@ bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv, u8 icl_hdr_plane_mask(void); bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id); +u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state, + int color_plane); + #endif From e2bd89d1aec61bf70a99731333cedae0881447b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 9 Oct 2024 21:22:00 +0300 Subject: [PATCH 053/284] drm/i915: Allow async flips with compression on ICL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently ICL can do async flips with CCS. In fact it already seems to work on GLK, but apparently can lead to underruns there so we'll only enable it for ICL. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241009182207.22900-3-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_display.c | 21 +++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9c2db307a6600..210d52dc33fcf 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6549,7 +6549,26 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in return -EINVAL; } break; - + case I915_FORMAT_MOD_Y_TILED_CCS: + case I915_FORMAT_MOD_Yf_TILED_CCS: + /* + * Display WA #0731: skl + * WaDisableRCWithAsyncFlip: skl + * "When render decompression is enabled, hardware + * internally converts the Async flips to Sync flips." + * + * Display WA #1159: glk + * "Async flip with render compression may result in + * intermittent underrun corruption." + */ + if (DISPLAY_VER(i915) < 11) { + drm_dbg_kms(&i915->drm, + "[PLANE:%d:%s] Modifier 0x%llx does not support async flip on display ver %d\n", + plane->base.base.id, plane->base.name, + new_plane_state->hw.fb->modifier, DISPLAY_VER(i915)); + return -EINVAL; + } + break; case I915_FORMAT_MOD_X_TILED: case I915_FORMAT_MOD_Y_TILED: case I915_FORMAT_MOD_Yf_TILED: From 7cc1e19703a553eda5f463cbe1fb011877ad16c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 9 Oct 2024 21:22:01 +0300 Subject: [PATCH 054/284] drm/i915: Introduce plane->can_async_flip() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the "does this modifier support async flips?" check to be handled by the platform specific plane code instead of having a big mess in common code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241009182207.22900-4-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/i9xx_plane.c | 9 +++ .../gpu/drm/i915/display/intel_atomic_plane.c | 5 ++ .../gpu/drm/i915/display/intel_atomic_plane.h | 1 + drivers/gpu/drm/i915/display/intel_display.c | 53 +----------- .../drm/i915/display/intel_display_types.h | 1 + .../drm/i915/display/skl_universal_plane.c | 80 +++++++++++++++++++ 6 files changed, 97 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 48e657a80a16d..c46277e0d67d3 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -673,6 +673,11 @@ vlv_primary_disable_flip_done(struct intel_plane *plane) spin_unlock_irq(&i915->irq_lock); } +static bool i9xx_plane_can_async_flip(u64 modifier) +{ + return modifier == I915_FORMAT_MOD_X_TILED; +} + static bool i9xx_plane_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { @@ -959,19 +964,23 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) plane->async_flip = vlv_primary_async_flip; plane->enable_flip_done = vlv_primary_enable_flip_done; plane->disable_flip_done = vlv_primary_disable_flip_done; + plane->can_async_flip = i9xx_plane_can_async_flip; } else if (IS_BROADWELL(dev_priv)) { plane->need_async_flip_toggle_wa = true; plane->async_flip = g4x_primary_async_flip; plane->enable_flip_done = bdw_primary_enable_flip_done; plane->disable_flip_done = bdw_primary_disable_flip_done; + plane->can_async_flip = i9xx_plane_can_async_flip; } else if (DISPLAY_VER(dev_priv) >= 7) { plane->async_flip = g4x_primary_async_flip; plane->enable_flip_done = ivb_primary_enable_flip_done; plane->disable_flip_done = ivb_primary_disable_flip_done; + plane->can_async_flip = i9xx_plane_can_async_flip; } else if (DISPLAY_VER(dev_priv) >= 5) { plane->async_flip = g4x_primary_async_flip; plane->enable_flip_done = ilk_primary_enable_flip_done; plane->disable_flip_done = ilk_primary_disable_flip_done; + plane->can_async_flip = i9xx_plane_can_async_flip; } modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X); diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 612e9b0ec14ab..5e0e074968671 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -156,6 +156,11 @@ bool intel_plane_needs_physical(struct intel_plane *plane) DISPLAY_INFO(i915)->cursor_needs_physical; } +bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier) +{ + return plane->can_async_flip && plane->can_async_flip(modifier); +} + unsigned int intel_adjusted_rate(const struct drm_rect *src, const struct drm_rect *dst, unsigned int rate) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 0f982f452ff39..fb87b3353ab0d 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -19,6 +19,7 @@ struct intel_plane; struct intel_plane_state; enum plane_id; +bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier); unsigned int intel_adjusted_rate(const struct drm_rect *src, const struct drm_rect *dst, unsigned int rate); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 210d52dc33fcf..5ae0dea7b245c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6528,58 +6528,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (!plane->async_flip) continue; - /* - * FIXME: This check is kept generic for all platforms. - * Need to verify this for all gen9 platforms to enable - * this selectively if required. - */ - switch (new_plane_state->hw.fb->modifier) { - case DRM_FORMAT_MOD_LINEAR: - /* - * FIXME: Async on Linear buffer is supported on ICL as - * but with additional alignment and fbc restrictions - * need to be taken care of. These aren't applicable for - * gen12+. - */ - if (DISPLAY_VER(i915) < 12) { - drm_dbg_kms(&i915->drm, - "[PLANE:%d:%s] Modifier 0x%llx does not support async flip on display ver %d\n", - plane->base.base.id, plane->base.name, - new_plane_state->hw.fb->modifier, DISPLAY_VER(i915)); - return -EINVAL; - } - break; - case I915_FORMAT_MOD_Y_TILED_CCS: - case I915_FORMAT_MOD_Yf_TILED_CCS: - /* - * Display WA #0731: skl - * WaDisableRCWithAsyncFlip: skl - * "When render decompression is enabled, hardware - * internally converts the Async flips to Sync flips." - * - * Display WA #1159: glk - * "Async flip with render compression may result in - * intermittent underrun corruption." - */ - if (DISPLAY_VER(i915) < 11) { - drm_dbg_kms(&i915->drm, - "[PLANE:%d:%s] Modifier 0x%llx does not support async flip on display ver %d\n", - plane->base.base.id, plane->base.name, - new_plane_state->hw.fb->modifier, DISPLAY_VER(i915)); - return -EINVAL; - } - break; - case I915_FORMAT_MOD_X_TILED: - case I915_FORMAT_MOD_Y_TILED: - case I915_FORMAT_MOD_Yf_TILED: - case I915_FORMAT_MOD_4_TILED: - case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: - case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS: - case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS: - case I915_FORMAT_MOD_4_TILED_BMG_CCS: - case I915_FORMAT_MOD_4_TILED_LNL_CCS: - break; - default: + if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->modifier)) { drm_dbg_kms(&i915->drm, "[PLANE:%d:%s] Modifier 0x%llx does not support async flip\n", plane->base.base.id, plane->base.name, diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 8271e50e36447..083eb86f09040 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1474,6 +1474,7 @@ struct intel_plane { unsigned int (*max_stride)(struct intel_plane *plane, u32 pixel_format, u64 modifier, unsigned int rotation); + bool (*can_async_flip)(u64 modifier); /* Write all non-self arming plane registers */ void (*update_noarm)(struct intel_dsb *dsb, struct intel_plane *plane, diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 00ee7dfdeb5b8..2679b446ab2b5 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -516,6 +516,79 @@ skl_plane_max_stride(struct intel_plane *plane, max_pixels, max_bytes); } +static bool tgl_plane_can_async_flip(u64 modifier) +{ + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_4_TILED: + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: + case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS: + case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS: + case I915_FORMAT_MOD_4_TILED_BMG_CCS: + case I915_FORMAT_MOD_4_TILED_LNL_CCS: + return true; + case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: + case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS: + case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS: + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: + case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC: + case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC: + return false; + default: + return false; + } +} + +static bool icl_plane_can_async_flip(u64 modifier) +{ + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + /* + * FIXME: Async on Linear buffer is supported on ICL + * but with additional alignment and fbc restrictions + * need to be taken care of. + */ + return false; + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Yf_TILED: + case I915_FORMAT_MOD_Y_TILED_CCS: + case I915_FORMAT_MOD_Yf_TILED_CCS: + return true; + default: + return false; + } +} + +static bool skl_plane_can_async_flip(u64 modifier) +{ + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + return false; + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Yf_TILED: + return true; + case I915_FORMAT_MOD_Y_TILED_CCS: + case I915_FORMAT_MOD_Yf_TILED_CCS: + /* + * Display WA #0731: skl + * WaDisableRCWithAsyncFlip: skl + * "When render decompression is enabled, hardware + * internally converts the Async flips to Sync flips." + * + * Display WA #1159: glk + * "Async flip with render compression may result in + * intermittent underrun corruption." + */ + return false; + default: + return false; + } +} + static u32 tgl_plane_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) @@ -2679,6 +2752,13 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, plane->async_flip = skl_plane_async_flip; plane->enable_flip_done = skl_plane_enable_flip_done; plane->disable_flip_done = skl_plane_disable_flip_done; + + if (DISPLAY_VER(dev_priv) >= 12) + plane->can_async_flip = tgl_plane_can_async_flip; + else if (DISPLAY_VER(dev_priv) == 11) + plane->can_async_flip = icl_plane_can_async_flip; + else + plane->can_async_flip = skl_plane_can_async_flip; } if (DISPLAY_VER(dev_priv) >= 11) From 2f4c92166ed53d46b4ad66b7cffb1350dec8c0b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 9 Oct 2024 21:22:02 +0300 Subject: [PATCH 055/284] drm/i915: Use plane->can_async_flip() for alignment exceptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Async flips often require bigger alignment that sync flips. Currently we have HAS_ASYNC_FLIPS() checks strewn about to inidcate that async flips are generally supported and thus we want more alignment. Switch that over to using intel_plane_can_async_flip() so that we can handle these in a slightly less messy way. Currently we don't have cases where async flips would require different alignment for different modifiers on the same plane. We'll also move the HAS_ASYNC_FLIPS() check to the plane init code so that we can still use that as a quick way to disable the async flips workarounds for testing purposes. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241009182207.22900-5-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/i9xx_plane.c | 55 +++++++++---------- .../drm/i915/display/skl_universal_plane.c | 21 ++++--- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index c46277e0d67d3..d05a12434f013 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -780,12 +780,11 @@ static unsigned int vlv_primary_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + if (intel_plane_can_async_flip(plane, fb->modifier)) + return 256 * 1024; switch (fb->modifier) { case I915_FORMAT_MOD_X_TILED: - if (HAS_ASYNC_FLIPS(i915)) - return 256 * 1024; return 4 * 1024; case DRM_FORMAT_MOD_LINEAR: return 128 * 1024; @@ -799,13 +798,11 @@ static unsigned int g4x_primary_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + if (intel_plane_can_async_flip(plane, fb->modifier)) + return 256 * 1024; switch (fb->modifier) { case I915_FORMAT_MOD_X_TILED: - if (HAS_ASYNC_FLIPS(i915)) - return 256 * 1024; - return 4 * 1024; case DRM_FORMAT_MOD_LINEAR: return 4 * 1024; default: @@ -960,27 +957,29 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) plane->get_hw_state = i9xx_plane_get_hw_state; plane->check_plane = i9xx_plane_check; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - plane->async_flip = vlv_primary_async_flip; - plane->enable_flip_done = vlv_primary_enable_flip_done; - plane->disable_flip_done = vlv_primary_disable_flip_done; - plane->can_async_flip = i9xx_plane_can_async_flip; - } else if (IS_BROADWELL(dev_priv)) { - plane->need_async_flip_toggle_wa = true; - plane->async_flip = g4x_primary_async_flip; - plane->enable_flip_done = bdw_primary_enable_flip_done; - plane->disable_flip_done = bdw_primary_disable_flip_done; - plane->can_async_flip = i9xx_plane_can_async_flip; - } else if (DISPLAY_VER(dev_priv) >= 7) { - plane->async_flip = g4x_primary_async_flip; - plane->enable_flip_done = ivb_primary_enable_flip_done; - plane->disable_flip_done = ivb_primary_disable_flip_done; - plane->can_async_flip = i9xx_plane_can_async_flip; - } else if (DISPLAY_VER(dev_priv) >= 5) { - plane->async_flip = g4x_primary_async_flip; - plane->enable_flip_done = ilk_primary_enable_flip_done; - plane->disable_flip_done = ilk_primary_disable_flip_done; - plane->can_async_flip = i9xx_plane_can_async_flip; + if (HAS_ASYNC_FLIPS(dev_priv)) { + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + plane->async_flip = vlv_primary_async_flip; + plane->enable_flip_done = vlv_primary_enable_flip_done; + plane->disable_flip_done = vlv_primary_disable_flip_done; + plane->can_async_flip = i9xx_plane_can_async_flip; + } else if (IS_BROADWELL(dev_priv)) { + plane->need_async_flip_toggle_wa = true; + plane->async_flip = g4x_primary_async_flip; + plane->enable_flip_done = bdw_primary_enable_flip_done; + plane->disable_flip_done = bdw_primary_disable_flip_done; + plane->can_async_flip = i9xx_plane_can_async_flip; + } else if (DISPLAY_VER(dev_priv) >= 7) { + plane->async_flip = g4x_primary_async_flip; + plane->enable_flip_done = ivb_primary_enable_flip_done; + plane->disable_flip_done = ivb_primary_disable_flip_done; + plane->can_async_flip = i9xx_plane_can_async_flip; + } else if (DISPLAY_VER(dev_priv) >= 5) { + plane->async_flip = g4x_primary_async_flip; + plane->enable_flip_done = ilk_primary_enable_flip_done; + plane->disable_flip_done = ilk_primary_disable_flip_done; + plane->can_async_flip = i9xx_plane_can_async_flip; + } } modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X); diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 2679b446ab2b5..474522f64b414 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -601,25 +601,24 @@ static u32 tgl_plane_min_alignment(struct intel_plane *plane, if (intel_fb_is_ccs_aux_plane(fb, color_plane)) return mult * 4 * 1024; + /* + * FIXME ADL sees GGTT/DMAR faults with async + * flips unless we align to 16k at least. + * Figure out what's going on here... + */ + if (IS_ALDERLAKE_P(i915) && + intel_plane_can_async_flip(plane, fb->modifier)) + return mult * 16 * 1024; + switch (fb->modifier) { case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_X_TILED: case I915_FORMAT_MOD_Y_TILED: case I915_FORMAT_MOD_4_TILED: - /* - * FIXME ADL sees GGTT/DMAR faults with async - * flips unless we align to 16k at least. - * Figure out what's going on here... - */ - if (IS_ALDERLAKE_P(i915) && HAS_ASYNC_FLIPS(i915)) - return mult * 16 * 1024; return mult * 4 * 1024; case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS: case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS: - if (IS_ALDERLAKE_P(i915) && HAS_ASYNC_FLIPS(i915)) - return mult * 16 * 1024; - fallthrough; case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS: case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS: @@ -2747,7 +2746,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, plane->get_hw_state = skl_plane_get_hw_state; plane->check_plane = skl_plane_check; - if (plane_id == PLANE_1) { + if (HAS_ASYNC_FLIPS(dev_priv) && plane_id == PLANE_1) { plane->need_async_flip_toggle_wa = IS_DISPLAY_VER(dev_priv, 9, 10); plane->async_flip = skl_plane_async_flip; plane->enable_flip_done = skl_plane_enable_flip_done; From d851663664a3515dc1272fc7ef35a6e0db467b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 9 Oct 2024 21:22:03 +0300 Subject: [PATCH 056/284] drm/i915: Reuse vlv_primary_min_alignment() for sprites as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename vlv_primary_min_alignment() to vlv_plane_min_alignment() and use it to replace vlv_sprite_min_alignment() since the behaviour is now identical when the plane init doesn't set up any async flips stuff. Technically VLV/CHV sprites do support async flips, so this also makes us a bit more future proof if/when we extend async flip support to more than one plane. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241009182207.22900-6-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/i9xx_plane.c | 8 ++++---- drivers/gpu/drm/i915/display/i9xx_plane.h | 4 ++++ drivers/gpu/drm/i915/display/intel_sprite.c | 17 +---------------- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index d05a12434f013..ed171fbf8720c 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -776,9 +776,9 @@ i8xx_plane_max_stride(struct intel_plane *plane, return 8 * 1024; } -static unsigned int vlv_primary_min_alignment(struct intel_plane *plane, - const struct drm_framebuffer *fb, - int color_plane) +unsigned int vlv_plane_min_alignment(struct intel_plane *plane, + const struct drm_framebuffer *fb, + int color_plane) { if (intel_plane_can_async_flip(plane, fb->modifier)) return 256 * 1024; @@ -939,7 +939,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) } if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - plane->min_alignment = vlv_primary_min_alignment; + plane->min_alignment = vlv_plane_min_alignment; else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) plane->min_alignment = g4x_primary_min_alignment; else if (DISPLAY_VER(dev_priv) == 4) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.h b/drivers/gpu/drm/i915/display/i9xx_plane.h index 0ca12d1e68393..457f4bccf1062 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.h +++ b/drivers/gpu/drm/i915/display/i9xx_plane.h @@ -9,6 +9,7 @@ #include enum pipe; +struct drm_framebuffer; struct drm_i915_private; struct intel_crtc; struct intel_initial_plane_config; @@ -19,6 +20,9 @@ struct intel_plane_state; unsigned int i965_plane_max_stride(struct intel_plane *plane, u32 pixel_format, u64 modifier, unsigned int rotation); +unsigned int vlv_plane_min_alignment(struct intel_plane *plane, + const struct drm_framebuffer *fb, + int colot_plane); int i9xx_check_plane_surface(struct intel_plane_state *plane_state); struct intel_plane * diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index e6fadcef58e06..13996d7059ad1 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -253,21 +253,6 @@ int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state, return DIV_ROUND_UP(pixel_rate * num, den); } -static unsigned int vlv_sprite_min_alignment(struct intel_plane *plane, - const struct drm_framebuffer *fb, - int color_plane) -{ - switch (fb->modifier) { - case I915_FORMAT_MOD_X_TILED: - return 4 * 1024; - case DRM_FORMAT_MOD_LINEAR: - return 128 * 1024; - default: - MISSING_CASE(fb->modifier); - return 0; - } -} - static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) { u32 sprctl = 0; @@ -1616,7 +1601,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane->get_hw_state = vlv_sprite_get_hw_state; plane->check_plane = vlv_sprite_check; plane->max_stride = i965_plane_max_stride; - plane->min_alignment = vlv_sprite_min_alignment; + plane->min_alignment = vlv_plane_min_alignment; plane->min_cdclk = vlv_plane_min_cdclk; if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { From 8e1096fd03b6c0e3e668cc2e4f0edbdc7de8fa01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 9 Oct 2024 21:22:04 +0300 Subject: [PATCH 057/284] drm/i915: Disable scanout VT-d workaround for TGL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TGL+ should no longer need any VT-d scanout workarounds. Don't apply any. Not 100% sure whether pre-SNB might also suffer from this. The workaround did originate on SNB but who knows if it was just never caught before that. Not that I ever managed to enable VT-d any older hardware. Last time I tried on my ILK it ate the disk! Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241009182207.22900-7-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5ae0dea7b245c..15f298d0424ae 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8743,5 +8743,5 @@ void intel_hpd_poll_fini(struct drm_i915_private *i915) bool intel_scanout_needs_vtd_wa(struct drm_i915_private *i915) { - return DISPLAY_VER(i915) >= 6 && i915_vtd_active(i915); + return IS_DISPLAY_VER(i915, 6, 11) && i915_vtd_active(i915); } From e7dfd7c60e402e658238d25c8da4f8645e45b982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 9 Oct 2024 21:22:05 +0300 Subject: [PATCH 058/284] drm/i915: Nuke ADL pre-production Wa_22011186057 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wa_22011186057 (some CCS problem) only affected ADL A-stepping, which I presume is pre-production hw. Drop the dead code. Bspec: 54369 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241009182207.22900-8-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/skl_universal_plane.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 474522f64b414..4bede904e1b52 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2615,10 +2615,6 @@ skl_plane_disable_flip_done(struct intel_plane *plane) static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915, enum pipe pipe, enum plane_id plane_id) { - /* Wa_22011186057 */ - if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0)) - return false; - if (DISPLAY_VER(i915) >= 11) return true; @@ -2640,10 +2636,6 @@ static bool tgl_plane_has_mc_ccs(struct drm_i915_private *i915, (IS_TIGERLAKE(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_D0))) return false; - /* Wa_22011186057 */ - if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0)) - return false; - return plane_id < PLANE_6; } From 71ca4715151e033c16427b8cfaa9b5393dd6a010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 9 Oct 2024 21:22:06 +0300 Subject: [PATCH 059/284] drm/i915: Relocate xe AUX hack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the xe AUX neutering out from skl_get_plane_caps() into the caller so that it'll be easier to refactor skl_get_plane_caps() into a more readable shape. This isn't really hardware specific anyway, and just some kind of bug/misfeature of xe. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241009182207.22900-9-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- .../gpu/drm/i915/display/skl_universal_plane.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 4bede904e1b52..aa8a38c0ca3c4 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2652,9 +2652,6 @@ static u8 skl_get_plane_caps(struct drm_i915_private *i915, if (HAS_4TILE(display)) caps |= INTEL_PLANE_CAP_TILING_4; - if (!IS_ENABLED(I915) && !HAS_FLAT_CCS(i915)) - return caps; - if (skl_plane_has_rc_ccs(i915, pipe, plane_id)) { caps |= INTEL_PLANE_CAP_CCS_RC; if (DISPLAY_VER(display) >= 12) @@ -2683,6 +2680,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, const u32 *formats; int num_formats; int ret; + u8 caps; plane = intel_plane_alloc(); if (IS_ERR(plane)) @@ -2774,8 +2772,15 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, else plane_type = DRM_PLANE_TYPE_OVERLAY; - modifiers = intel_fb_plane_get_modifiers(dev_priv, - skl_get_plane_caps(dev_priv, pipe, plane_id)); + caps = skl_get_plane_caps(dev_priv, pipe, plane_id); + + /* FIXME: xe has problems with AUX */ + if (!IS_ENABLED(I915) && !HAS_FLAT_CCS(dev_priv)) + caps &= ~(INTEL_PLANE_CAP_CCS_RC | + INTEL_PLANE_CAP_CCS_RC_CC | + INTEL_PLANE_CAP_CCS_MC); + + modifiers = intel_fb_plane_get_modifiers(dev_priv, caps); ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 0, plane_funcs, From 6f7c813c88aed90ca342a76ef4cdc078d6210e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 10 Oct 2024 19:46:17 +0300 Subject: [PATCH 060/284] drm/i915: Carve up skl_get_plane_caps() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split skl_get_plane_caps() into four variants: skl_plane_caps(), glk_plane_caps(), icl_plane_caps(), tgl_plane_caps(). Makes it easier to figure out what is actually going on there. v2: skl_plane_caps() should return u8 not bool Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241010164617.10280-1-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- .../drm/i915/display/skl_universal_plane.c | 81 +++++++++++++------ 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index aa8a38c0ca3c4..450dd8c64e0c4 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2615,48 +2615,74 @@ skl_plane_disable_flip_done(struct intel_plane *plane) static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915, enum pipe pipe, enum plane_id plane_id) { - if (DISPLAY_VER(i915) >= 11) - return true; - - if (IS_GEMINILAKE(i915)) - return pipe != PIPE_C; - return pipe != PIPE_C && (plane_id == PLANE_1 || plane_id == PLANE_2); } +static u8 skl_plane_caps(struct drm_i915_private *i915, + enum pipe pipe, enum plane_id plane_id) +{ + u8 caps = INTEL_PLANE_CAP_TILING_X | + INTEL_PLANE_CAP_TILING_Y | + INTEL_PLANE_CAP_TILING_Yf; + + if (skl_plane_has_rc_ccs(i915, pipe, plane_id)) + caps |= INTEL_PLANE_CAP_CCS_RC; + + return caps; +} + +static bool glk_plane_has_rc_ccs(struct drm_i915_private *i915, + enum pipe pipe) +{ + return pipe != PIPE_C; +} + +static u8 glk_plane_caps(struct drm_i915_private *i915, + enum pipe pipe, enum plane_id plane_id) +{ + u8 caps = INTEL_PLANE_CAP_TILING_X | + INTEL_PLANE_CAP_TILING_Y | + INTEL_PLANE_CAP_TILING_Yf; + + if (glk_plane_has_rc_ccs(i915, pipe)) + caps |= INTEL_PLANE_CAP_CCS_RC; + + return caps; +} + +static u8 icl_plane_caps(struct drm_i915_private *i915, + enum pipe pipe, enum plane_id plane_id) +{ + return INTEL_PLANE_CAP_TILING_X | + INTEL_PLANE_CAP_TILING_Y | + INTEL_PLANE_CAP_TILING_Yf | + INTEL_PLANE_CAP_CCS_RC; +} + static bool tgl_plane_has_mc_ccs(struct drm_i915_private *i915, enum plane_id plane_id) { - if (DISPLAY_VER(i915) < 12) - return false; - /* Wa_14010477008 */ if (IS_DG1(i915) || IS_ROCKETLAKE(i915) || - (IS_TIGERLAKE(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_D0))) + (IS_TIGERLAKE(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_D0))) return false; return plane_id < PLANE_6; } -static u8 skl_get_plane_caps(struct drm_i915_private *i915, - enum pipe pipe, enum plane_id plane_id) +static u8 tgl_plane_caps(struct drm_i915_private *i915, + enum pipe pipe, enum plane_id plane_id) { struct intel_display *display = &i915->display; - u8 caps = INTEL_PLANE_CAP_TILING_X; + u8 caps = INTEL_PLANE_CAP_TILING_X | + INTEL_PLANE_CAP_CCS_RC | + INTEL_PLANE_CAP_CCS_RC_CC; - if (DISPLAY_VER(display) < 13 || display->platform.alderlake_p) - caps |= INTEL_PLANE_CAP_TILING_Y; - if (DISPLAY_VER(display) < 12) - caps |= INTEL_PLANE_CAP_TILING_Yf; if (HAS_4TILE(display)) caps |= INTEL_PLANE_CAP_TILING_4; - - if (skl_plane_has_rc_ccs(i915, pipe, plane_id)) { - caps |= INTEL_PLANE_CAP_CCS_RC; - if (DISPLAY_VER(display) >= 12) - caps |= INTEL_PLANE_CAP_CCS_RC_CC; - } + else + caps |= INTEL_PLANE_CAP_TILING_Y; if (tgl_plane_has_mc_ccs(i915, plane_id)) caps |= INTEL_PLANE_CAP_CCS_MC; @@ -2772,7 +2798,14 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, else plane_type = DRM_PLANE_TYPE_OVERLAY; - caps = skl_get_plane_caps(dev_priv, pipe, plane_id); + if (DISPLAY_VER(dev_priv) >= 12) + caps = tgl_plane_caps(dev_priv, pipe, plane_id); + else if (DISPLAY_VER(dev_priv) == 11) + caps = icl_plane_caps(dev_priv, pipe, plane_id); + else if (DISPLAY_VER(dev_priv) == 10) + caps = glk_plane_caps(dev_priv, pipe, plane_id); + else + caps = skl_plane_caps(dev_priv, pipe, plane_id); /* FIXME: xe has problems with AUX */ if (!IS_ENABLED(I915) && !HAS_FLAT_CCS(dev_priv)) From 2499212e21601740ed7d5563563f39cf7e7d833a Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Fri, 17 Jan 2025 09:42:48 +0530 Subject: [PATCH 061/284] drm/i915/hdcp: Use correct function to check if encoder is HDMI Use intel_encoder_is_hdmi function which was recently introduced to see if encoder is HDMI or not. --v2 -Add Fixes tag [Jani] Fixes: 6a3691ca4799 ("drm/i915/hdcp: Disable HDCP Line Rekeying for HDCP2.2 on HDMI") Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250117041247.1084381-1-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_hdcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index c60b22aaa819e..1bab7c34a7942 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -41,7 +41,7 @@ intel_hdcp_adjust_hdcp_line_rekeying(struct intel_encoder *encoder, u32 rekey_bit = 0; /* Here we assume HDMI is in TMDS mode of operation */ - if (encoder->type != INTEL_OUTPUT_HDMI) + if (!intel_encoder_is_hdmi(encoder)) return; if (DISPLAY_VER(display) >= 30) { From 67a98f7e27baf8c22483ec4873a8d8efdf71b55d Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Fri, 6 Dec 2024 19:20:32 +0100 Subject: [PATCH 062/284] drm/xe/display: Re-use display vmas when possible i915 has this really nice, infrastructure where everything becomes complicated, GGTT needs eviction, etc.. Lets not do that, and make the dumbest possible interface instead. Try to retrieve the VMA from old_plane_state, or intel_fbdev if kernel fb. Link: https://patchwork.freedesktop.org/patch/msgid/20241206182032.196307-1-dev@lankhorst.se Signed-off-by: Maarten Lankhorst Reviewed-by: Animesh Manna Tested-by: Jani Saarinen --- .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_pin.c | 3 +- drivers/gpu/drm/i915/display/intel_fb_pin.h | 3 +- drivers/gpu/drm/i915/display/intel_fbdev.c | 5 ++ drivers/gpu/drm/i915/display/intel_fbdev.h | 8 ++++ .../gpu/drm/xe/compat-i915-headers/i915_vma.h | 3 ++ drivers/gpu/drm/xe/display/xe_fb_pin.c | 48 +++++++++++++++++-- 8 files changed, 65 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 5e0e074968671..c558143f4f824 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -1135,7 +1135,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, if (!obj) return 0; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 57cf8f46a4589..ae7243ad6e0ca 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -865,7 +865,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, if (ret) goto out_free; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) goto out_free; diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index d3a86f9c6bc86..dd3ac7f98dfcc 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -252,7 +252,8 @@ intel_plane_fb_min_phys_alignment(const struct intel_plane_state *plane_state) return plane->min_alignment(plane, fb, 0); } -int intel_plane_pin_fb(struct intel_plane_state *plane_state) +int intel_plane_pin_fb(struct intel_plane_state *plane_state, + const struct intel_plane_state *old_plane_state) { struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); const struct intel_framebuffer *fb = diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h index ac0319b53af08..0fc6d90446381 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.h +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h @@ -23,7 +23,8 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags); -int intel_plane_pin_fb(struct intel_plane_state *plane_state); +int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, + const struct intel_plane_state *old_plane_state); void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state); #endif diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 00852ff5b2470..6c08081333976 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -695,3 +695,8 @@ struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) return to_intel_framebuffer(fbdev->helper.fb); } + +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return fbdev ? fbdev->vma : NULL; +} diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h index 08de2d5b34338..24a3434558cb6 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.h +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h @@ -17,6 +17,8 @@ struct intel_framebuffer; void intel_fbdev_setup(struct drm_i915_private *dev_priv); void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous); struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev); + #else static inline void intel_fbdev_setup(struct drm_i915_private *dev_priv) { @@ -30,6 +32,12 @@ static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbd { return NULL; } + +static inline struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return NULL; +} + #endif #endif /* __INTEL_FBDEV_H__ */ diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h index bdae8392e1253..4465c40f81341 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h @@ -10,6 +10,8 @@ #include "xe_ggtt_types.h" +#include + /* We don't want these from i915_drm.h in case of Xe */ #undef I915_TILING_X #undef I915_TILING_Y @@ -19,6 +21,7 @@ struct xe_bo; struct i915_vma { + refcount_t ref; struct xe_bo *bo, *dpt; struct xe_ggtt_node *node; }; diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 9fa51b84737ca..25ce032bb293f 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -9,6 +9,7 @@ #include "intel_dpt.h" #include "intel_fb.h" #include "intel_fb_pin.h" +#include "intel_fbdev.h" #include "xe_bo.h" #include "xe_device.h" #include "xe_ggtt.h" @@ -287,6 +288,7 @@ static struct i915_vma *__xe_pin_fb_vma(const struct intel_framebuffer *fb, if (!vma) return ERR_PTR(-ENODEV); + refcount_set(&vma->ref, 1); if (IS_DGFX(to_xe_device(bo->ttm.base.dev)) && intel_fb_rc_ccs_cc_plane(&fb->base) >= 0 && !(bo->flags & XE_BO_FLAG_NEEDS_CPU_ACCESS)) { @@ -347,6 +349,9 @@ static void __xe_unpin_fb_vma(struct i915_vma *vma) { u8 tile_id = vma->node->ggtt->tile->id; + if (!refcount_dec_and_test(&vma->ref)) + return; + if (vma->dpt) xe_bo_unpin_map_no_vm(vma->dpt); else if (!xe_ggtt_node_allocated(vma->bo->ggtt_node[tile_id]) || @@ -377,25 +382,58 @@ void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags) __xe_unpin_fb_vma(vma); } -int intel_plane_pin_fb(struct intel_plane_state *plane_state) +static bool reuse_vma(struct intel_plane_state *new_plane_state, + const struct intel_plane_state *old_plane_state) { - struct drm_framebuffer *fb = plane_state->hw.fb; + struct intel_framebuffer *fb = to_intel_framebuffer(new_plane_state->hw.fb); + struct xe_device *xe = to_xe_device(fb->base.dev); + struct i915_vma *vma; + + if (old_plane_state->hw.fb == new_plane_state->hw.fb && + !memcmp(&old_plane_state->view.gtt, + &new_plane_state->view.gtt, + sizeof(new_plane_state->view.gtt))) { + vma = old_plane_state->ggtt_vma; + goto found; + } + + if (fb == intel_fbdev_framebuffer(xe->display.fbdev.fbdev)) { + vma = intel_fbdev_vma_pointer(xe->display.fbdev.fbdev); + if (vma) + goto found; + } + + return false; + +found: + refcount_inc(&vma->ref); + new_plane_state->ggtt_vma = vma; + return true; +} + +int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, + const struct intel_plane_state *old_plane_state) +{ + struct drm_framebuffer *fb = new_plane_state->hw.fb; struct drm_gem_object *obj = intel_fb_bo(fb); struct xe_bo *bo = gem_to_xe_bo(obj); struct i915_vma *vma; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane); u64 phys_alignment = plane->min_alignment(plane, fb, 0); + if (reuse_vma(new_plane_state, old_plane_state)) + return 0; + /* We reject creating !SCANOUT fb's, so this is weird.. */ drm_WARN_ON(bo->ttm.base.dev, !(bo->flags & XE_BO_FLAG_SCANOUT)); - vma = __xe_pin_fb_vma(intel_fb, &plane_state->view.gtt, phys_alignment); + vma = __xe_pin_fb_vma(intel_fb, &new_plane_state->view.gtt, phys_alignment); if (IS_ERR(vma)) return PTR_ERR(vma); - plane_state->ggtt_vma = vma; + new_plane_state->ggtt_vma = vma; return 0; } From a20dea718fca0a474ad5773bdc6504d6f5727322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 9 Jan 2025 12:35:29 +0200 Subject: [PATCH 063/284] drm/i915/psr: Add new function for writing sink panel replay enable bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to DP/eDP specification only DP_PANEL_REPLAY_ENABLE has to be set prior link training. For this purpose add a new function which sets this bit on sink side if Panel Replay is supported by the sink and the source. Signed-off-by: Jouni Högander Reviewed-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250109103532.2093356-2-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 7 +++++++ drivers/gpu/drm/i915/display/intel_psr.h | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 0b021acb330f4..266b811bd8390 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -827,6 +827,13 @@ void intel_psr_enable_sink(struct intel_dp *intel_dp, drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0); } +void intel_psr_panel_replay_enable_sink(struct intel_dp *intel_dp) +{ + if (CAN_PANEL_REPLAY(intel_dp)) + drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG, + DP_PANEL_REPLAY_ENABLE); +} + static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index 956be263c09e3..3b2643b83e061 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -30,6 +30,7 @@ bool intel_psr_needs_aux_io_power(struct intel_encoder *encoder, void intel_psr_init_dpcd(struct intel_dp *intel_dp); void intel_psr_enable_sink(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); +void intel_psr_panel_replay_enable_sink(struct intel_dp *intel_dp); void intel_psr_pre_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc); void intel_psr_post_plane_update(struct intel_atomic_state *state, From 68f3a505b367656a2db05406a62dc43fb0c50034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 9 Jan 2025 12:35:30 +0200 Subject: [PATCH 064/284] drm/i915/psr: Enable Panel Replay on sink always when it's supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we are configuring Panel Replay on sink when it get's enabled. This means we need to do full modeset when enabling Panel Replay. This is required as DP specification is saying sink Panel Replay needs to be configured before link training. Avoid full modeset by enabling Panel Replay on sink always when it's supported by the sink and the source. Signed-off-by: Jouni Högander Reviewed-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250109103532.2093356-3-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index acb986bc1f33a..3693b36b9336a 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2927,8 +2927,7 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, crtc_state); /* Panel replay has to be enabled in sink dpcd before link training. */ - if (crtc_state->has_panel_replay) - intel_psr_enable_sink(enc_to_intel_dp(encoder), crtc_state); + intel_psr_panel_replay_enable_sink(enc_to_intel_dp(encoder)); if (DISPLAY_VER(display) >= 14) mtl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); From 4917c46411164dd1aa22611577ab751cb66e04b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 9 Jan 2025 12:35:31 +0200 Subject: [PATCH 065/284] drm/i915/psr: Make intel_psr_enable_sink as local static function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Intel_psr_enable_sink is not used outside intel_psr.c. Convert it as local static function. Signed-off-by: Jouni Högander Reviewed-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250109103532.2093356-4-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 4 ++-- drivers/gpu/drm/i915/display/intel_psr.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 266b811bd8390..797199ba1cbfe 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -814,8 +814,8 @@ static void intel_psr_enable_sink_alpm(struct intel_dp *intel_dp, drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val); } -void intel_psr_enable_sink(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) +static void intel_psr_enable_sink(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { intel_psr_enable_sink_alpm(intel_dp, crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index 3b2643b83e061..5f1671d02d765 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -28,8 +28,6 @@ bool intel_encoder_can_psr(struct intel_encoder *encoder); bool intel_psr_needs_aux_io_power(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void intel_psr_init_dpcd(struct intel_dp *intel_dp); -void intel_psr_enable_sink(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); void intel_psr_panel_replay_enable_sink(struct intel_dp *intel_dp); void intel_psr_pre_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc); From edbfa38ffa822ab2fe6848a61b339f27a34c4b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 9 Jan 2025 12:35:32 +0200 Subject: [PATCH 066/284] drm/i915/psr: Allow changing Panel Replay mode without full modeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we are forcing full modeset if Panel Replay mode is changed. This is not necessary as long as we are not changing sink PANEL REPLAY ENABLE bit in PANEL REPLAY ENABLE AND CONFIGURATION 1 register. This can be achieved by entering Panel Replay inactive mode (Live Frame mode) when Panel Replay is disabled and keep PANEL REPLAY ENABLE bit in PANEL REPLAY ENABLE AND CONFIGURATION 1 enabled always if panel is just supporting Panel Replay. Signed-off-by: Jouni Högander Reviewed-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250109103532.2093356-5-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 14 ----------- drivers/gpu/drm/i915/display/intel_psr.c | 25 +++++++++++++------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 15f298d0424ae..e63619da2e62b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5673,20 +5673,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_CSC(output_csc); } - /* - * Panel replay has to be enabled before link training. PSR doesn't have - * this requirement -> check these only if using panel replay - */ - if (current_config->active_planes && - (current_config->has_panel_replay || - pipe_config->has_panel_replay)) { - PIPE_CONF_CHECK_BOOL(has_psr); - PIPE_CONF_CHECK_BOOL(has_sel_update); - PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch); - PIPE_CONF_CHECK_BOOL(enable_psr2_su_region_et); - PIPE_CONF_CHECK_BOOL(has_panel_replay); - } - PIPE_CONF_CHECK_BOOL(double_wide); if (dev_priv->display.dpll.mgr) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 797199ba1cbfe..aa6ff057b54c8 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1998,18 +1998,25 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp, if (!psr_interrupt_error_check(intel_dp)) return; - if (intel_dp->psr.panel_replay_enabled) { + if (intel_dp->psr.panel_replay_enabled) drm_dbg_kms(display->drm, "Enabling Panel Replay\n"); - } else { + else drm_dbg_kms(display->drm, "Enabling PSR%s\n", intel_dp->psr.sel_update_enabled ? "2" : "1"); - /* - * Panel replay has to be enabled before link training: doing it - * only for PSR here. - */ - intel_psr_enable_sink(intel_dp, crtc_state); - } + /* + * Enabling here only for PSR. Panel Replay enable bit is already + * written at this point. See + * intel_psr_panel_replay_enable_sink. Modifiers/options: + * - Selective Update + * - Region Early Transport + * - Selective Update Region Scanline Capture + * - VSC_SDP_CRC + * - HPD on different Errors + * - CRC verification + * are written for PSR and Panel Replay here. + */ + intel_psr_enable_sink(intel_dp, crtc_state); if (intel_dp_is_edp(intel_dp)) intel_snps_phy_update_psr_power_state(&dig_port->base, true); @@ -2815,6 +2822,8 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, needs_to_disable |= new_crtc_state->has_sel_update != psr->sel_update_enabled; needs_to_disable |= new_crtc_state->enable_psr2_su_region_et != psr->su_region_et_enabled; + needs_to_disable |= new_crtc_state->has_panel_replay != + psr->panel_replay_enabled; needs_to_disable |= DISPLAY_VER(i915) < 11 && new_crtc_state->wm_level_disabled; From 2218704997979fbf11765281ef752f07c5cf25bb Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 10 Dec 2024 09:31:02 +0100 Subject: [PATCH 067/284] drm/xe: Remove double pageflip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is already handled below in the code by fixup_initial_plane_config. Fixes: a8153627520a ("drm/i915: Try to relocate the BIOS fb to the start of ggtt") Cc: Ville Syrjälä Reviewed-by: Vinod Govindapillai Reviewed-by: Lucas De Marchi Link: https://patchwork.freedesktop.org/patch/msgid/20241210083111.230484-3-dev@lankhorst.se Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_plane_initial.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c b/drivers/gpu/drm/xe/display/xe_plane_initial.c index 2eb9633f163a7..2a2f250fa495d 100644 --- a/drivers/gpu/drm/xe/display/xe_plane_initial.c +++ b/drivers/gpu/drm/xe/display/xe_plane_initial.c @@ -194,8 +194,6 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, to_intel_plane(crtc->base.primary); struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); - struct intel_crtc_state *crtc_state = - to_intel_crtc_state(crtc->base.state); struct drm_framebuffer *fb; struct i915_vma *vma; @@ -241,14 +239,6 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); plane_config->vma = vma; - - /* - * Flip to the newly created mapping ASAP, so we can re-use the - * first part of GGTT for WOPCM, prevent flickering, and prevent - * the lookup of sysmem scratch pages. - */ - plane->check_plane(crtc_state, plane_state); - plane->async_flip(NULL, plane, crtc_state, plane_state, true); return; nofb: From 8a2392fec5b4b96d738feb6ecef02b9958bb64b1 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 17 Jan 2025 17:38:43 +0200 Subject: [PATCH 068/284] drm/xe/dp: Fix non-display builds with DP tunnelling incorrectly enabled Code for the DP tunnelling functionality in the xe driver can be built only if the display code is also built, adjust the kconfig dependency accordingly. Cc: Suraj Kandpal Fixes: 73900dce57e4 ("drm/xe/dp: Enable DP tunneling") Reported-by: Lucas De Marchi Reviewed-by: Suraj Kandpal Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250117153843.1312303-1-imre.deak@intel.com --- drivers/gpu/drm/xe/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig index 50cf80df51900..99219c16e8aac 100644 --- a/drivers/gpu/drm/xe/Kconfig +++ b/drivers/gpu/drm/xe/Kconfig @@ -61,7 +61,7 @@ config DRM_XE_DISPLAY config DRM_XE_DP_TUNNEL bool "Enable DP tunnel support" - depends on DRM_XE + depends on DRM_XE_DISPLAY depends on USB4 select DRM_DISPLAY_DP_TUNNEL default y From c5303240e01919ea9cd3a2e198c3a25686a99552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Jan 2025 22:16:30 +0200 Subject: [PATCH 069/284] drm/i915: Keep TRANS_VBLANK.vblank_start==0 on ADL+ even when doing LRR updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_set_transcoder_timings() will set TRANS_VBLANK.vblank_start to 0 for clarity on ADL+ (non-DSI) because the hardware no longer uses that value. Do the same in intel_set_transcoder_timings_lrr() to make sure the registers stay consistent even when doing LRR timing updates. Cc: Paz Zcharya Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250116201637.22486-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e63619da2e62b..34b8a54f95a30 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2923,6 +2923,14 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc crtc_vblank_start = adjusted_mode->crtc_vblank_start; crtc_vblank_end = adjusted_mode->crtc_vblank_end; + if (DISPLAY_VER(dev_priv) >= 13) { + /* + * VBLANK_START not used by hw, just clear it + * to make it stand out in register dumps. + */ + crtc_vblank_start = 1; + } + drm_WARN_ON(&dev_priv->drm, adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE); /* From 880426962795b763f209a0b7fcd5df815664aaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Jan 2025 22:16:31 +0200 Subject: [PATCH 070/284] drm/i915: Handle interlaced modes in intel_set_transcoder_timings_lrr() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I want to start using intel_set_transcoder_timings_lrr() also for fixing up the vblank delay during boot. To that end make sure it can cope with interlaced modes as well. Note that we have soft-defeatured interlaced modes on tgl+ so technically this is dead code, but if we ever have the need to bring interlaced support back it seems better to handle this. Cc: Paz Zcharya Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250116201637.22486-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 34b8a54f95a30..29879ad0ed568 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2923,6 +2923,12 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc crtc_vblank_start = adjusted_mode->crtc_vblank_start; crtc_vblank_end = adjusted_mode->crtc_vblank_end; + if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { + /* the chip adds 2 halflines automatically */ + crtc_vtotal -= 1; + crtc_vblank_end -= 1; + } + if (DISPLAY_VER(dev_priv) >= 13) { /* * VBLANK_START not used by hw, just clear it @@ -2931,8 +2937,6 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc crtc_vblank_start = 1; } - drm_WARN_ON(&dev_priv->drm, adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE); - /* * The hardware actually ignores TRANS_VBLANK.VBLANK_END in DP mode. * But let's write it anyway to keep the state checker happy. From d6d4dc22d50312132ea312f1074e4367e219254c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Jan 2025 22:16:32 +0200 Subject: [PATCH 071/284] drm/i915: Update TRANS_SET_CONTEXT_LATENCY during LRR updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update TRANS_SET_CONTEXT_LATENCY in intel_set_transcoder_timings_lrr() as well. While for actual LRR updates this should not change, I want to reuse this code to also sanitize the vblank delay during boot, and in that case we do need to update this. Cc: Paz Zcharya Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250116201637.22486-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 29879ad0ed568..e6501143ab7cf 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2930,6 +2930,10 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc } if (DISPLAY_VER(dev_priv) >= 13) { + intel_de_write(dev_priv, + TRANS_SET_CONTEXT_LATENCY(dev_priv, cpu_transcoder), + crtc_vblank_start - crtc_vdisplay); + /* * VBLANK_START not used by hw, just clear it * to make it stand out in register dumps. From 1f1b673cec361b4ab20b817340f74e75d070f312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Jan 2025 22:16:33 +0200 Subject: [PATCH 072/284] drm/i915: Warn if someone tries to use intel_set_transcoder_timings*() on DSI outputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_set_transcoder_timings*() aren't currently suitable for DSI. Warn if someone accidentally calls them in such cases. Cc: Paz Zcharya Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250116201637.22486-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e6501143ab7cf..d0989a85e59c9 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2837,6 +2837,8 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta u32 crtc_vdisplay, crtc_vtotal, crtc_vblank_start, crtc_vblank_end; int vsyncshift = 0; + drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)); + /* We need to be careful not to changed the adjusted mode, for otherwise * the hw state checker will get angry at the mismatch. */ crtc_vdisplay = adjusted_mode->crtc_vdisplay; @@ -2918,6 +2920,8 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; u32 crtc_vdisplay, crtc_vtotal, crtc_vblank_start, crtc_vblank_end; + drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)); + crtc_vdisplay = adjusted_mode->crtc_vdisplay; crtc_vtotal = adjusted_mode->crtc_vtotal; crtc_vblank_start = adjusted_mode->crtc_vblank_start; From ff118b4f0c05ee55e049db2beefbbd2f43298fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Jan 2025 22:16:34 +0200 Subject: [PATCH 073/284] drm/i915: Extract lrr_params_changed() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the "do we actually need a LRR update?" checks into a small helper for clarity. Cc: Paz Zcharya Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250116201637.22486-6-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d0989a85e59c9..b5e38137ef4d6 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6067,6 +6067,13 @@ static int intel_modeset_checks(struct intel_atomic_state *state) return 0; } +static bool lrr_params_changed(const struct drm_display_mode *old_adjusted_mode, + const struct drm_display_mode *new_adjusted_mode) +{ + return old_adjusted_mode->crtc_vblank_end != new_adjusted_mode->crtc_vblank_end || + old_adjusted_mode->crtc_vtotal != new_adjusted_mode->crtc_vtotal; +} + static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_state, struct intel_crtc_state *new_crtc_state) { @@ -6087,8 +6094,8 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta &new_crtc_state->dp_m_n)) new_crtc_state->update_m_n = false; - if ((old_crtc_state->hw.adjusted_mode.crtc_vtotal == new_crtc_state->hw.adjusted_mode.crtc_vtotal && - old_crtc_state->hw.adjusted_mode.crtc_vblank_end == new_crtc_state->hw.adjusted_mode.crtc_vblank_end)) + if (!lrr_params_changed(&old_crtc_state->hw.adjusted_mode, + &new_crtc_state->hw.adjusted_mode)) new_crtc_state->update_lrr = false; if (intel_crtc_needs_modeset(new_crtc_state)) From 42fdbe94b69ceed77622e58b33701546f49283a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Jan 2025 22:16:35 +0200 Subject: [PATCH 074/284] drm/i915: Allow fastboot to fix up the vblank delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GOP might not agree with our idea of what the vblank delay should be. Reuse the LRR codepaths to fix that up via a fastset. The relevant registers aren't actually double buffered so this is a little bit dodgy. While I've not seen any real issues from frobbing these live, let's limit this to just the fastboot case (by only allowing it when old_crtc_state->inherited==true). Cc: Paz Zcharya Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250116201637.22486-7-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 26 +++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b5e38137ef4d6..950505c942243 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5358,6 +5358,19 @@ pipe_config_cx0pll_mismatch(struct drm_printer *p, bool fastset, intel_cx0pll_dump_hw_state(display, b); } +static bool allow_vblank_delay_fastset(const struct intel_crtc_state *old_crtc_state) +{ + struct intel_display *display = to_intel_display(old_crtc_state); + + /* + * Allow fastboot to fix up vblank delay (handled via LRR + * codepaths), a bit dodgy as the registers aren't + * double buffered but seems to be working more or less... + */ + return HAS_LRR(display) && old_crtc_state->inherited && + !intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI); +} + bool intel_pipe_config_compare(const struct intel_crtc_state *current_config, const struct intel_crtc_state *pipe_config, @@ -5490,7 +5503,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(name.crtc_hsync_start); \ PIPE_CONF_CHECK_I(name.crtc_hsync_end); \ PIPE_CONF_CHECK_I(name.crtc_vdisplay); \ - PIPE_CONF_CHECK_I(name.crtc_vblank_start); \ + if (!fastset || !allow_vblank_delay_fastset(current_config)) \ + PIPE_CONF_CHECK_I(name.crtc_vblank_start); \ PIPE_CONF_CHECK_I(name.crtc_vsync_start); \ PIPE_CONF_CHECK_I(name.crtc_vsync_end); \ if (!fastset || !pipe_config->update_lrr) { \ @@ -6070,7 +6084,8 @@ static int intel_modeset_checks(struct intel_atomic_state *state) static bool lrr_params_changed(const struct drm_display_mode *old_adjusted_mode, const struct drm_display_mode *new_adjusted_mode) { - return old_adjusted_mode->crtc_vblank_end != new_adjusted_mode->crtc_vblank_end || + return old_adjusted_mode->crtc_vblank_start != new_adjusted_mode->crtc_vblank_start || + old_adjusted_mode->crtc_vblank_end != new_adjusted_mode->crtc_vblank_end || old_adjusted_mode->crtc_vtotal != new_adjusted_mode->crtc_vtotal; } @@ -6084,11 +6099,14 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta if (old_crtc_state->vrr.in_range != new_crtc_state->vrr.in_range) new_crtc_state->update_lrr = false; - if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true)) + if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true)) { drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] fastset requirement not met, forcing full modeset\n", crtc->base.base.id, crtc->base.name); - else + } else { + if (allow_vblank_delay_fastset(old_crtc_state)) + new_crtc_state->update_lrr = true; new_crtc_state->uapi.mode_changed = false; + } if (intel_compare_link_m_n(&old_crtc_state->dp_m_n, &new_crtc_state->dp_m_n)) From aee21ab36e142c10fa6b56694b9d160fb5a49abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Jan 2025 22:16:36 +0200 Subject: [PATCH 075/284] drm/i915/dsb: Add support for triggering VRR push with DSB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have at least two options for how to do the TRANS_PUSH_SEND + commit completion signalling with the DSB: Option A) 1. trigger TRANS_PUSH_SEND 2. wait for "safe window" 3. signal the interrupt In this cases step 2 should not do anything if we were already between vmin and vmax decision boundaries. Otherwise we'll wait until the next start of the vblank period. Option B) 1. wait for "safe window" 2. trigger TRANS_PUSH_SEND 3. signal the interrupt This option is perhaps a bit less racy, but if we do somehow screw up and the wait is a nop but the push gets deferred until the next frame then we'll end up completing the commit a frame too early. So for now I'm leaning towards option A since losing the race won't have any drastic consequences. To deal with the race we can give the DSB a bit more time to start step 2 before the hardware has started the vblank termination properly. Often times it seems to be fast enough to make it in time even without any extra vblank delay (the push is issued somewhere within a scanline and it latches on the next scanline). v2: Use intel_vrr_possible() to determine if we need some vblank delay (also avoids adding it for DSI which doens't actually program the transcoder registers correctly for it) Cc: Paz Zcharya Signed-off-by: Ville Syrjälä Reviewed-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250116201637.22486-8-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 950505c942243..68d932d9f5c53 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2630,6 +2630,14 @@ static int intel_crtc_vblank_delay(const struct intel_crtc_state *crtc_state) if (intel_crtc_needs_wa_14015401596(crtc_state)) vblank_delay = max(vblank_delay, 1); + /* + * Add a minimal vblank delay to make sure the push + * doesn't race with the "wait for safe window" used + * for frame completion with DSB. + */ + if (intel_vrr_possible(crtc_state)) + vblank_delay = max(vblank_delay, 1); + return vblank_delay; } @@ -7727,6 +7735,8 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, intel_crtc_planes_update_arm(new_crtc_state->dsb_commit, state, crtc); + intel_vrr_send_push(new_crtc_state->dsb_commit, new_crtc_state); + if (!new_crtc_state->dsb_color_vblank) { intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, 1); intel_dsb_wait_vblank_delay(state, new_crtc_state->dsb_commit); From 83db7bf1781dab848adf1280ee45bb4f93b52f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Jan 2025 22:16:37 +0200 Subject: [PATCH 076/284] drm/i915/dsb: Allow DSB to perform commits when VRR is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we know how to issue the push with the DSB we can allow the DSB to drive the commits even when VRR is active. Cc: Paz Zcharya Signed-off-by: Ville Syrjälä Reviewed-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250116201637.22486-9-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 68d932d9f5c53..10550bc0778e3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7694,7 +7694,6 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, /* FIXME deal with everything */ new_crtc_state->use_dsb = new_crtc_state->update_planes && - !new_crtc_state->vrr.enable && !new_crtc_state->do_async_flip && !new_crtc_state->has_psr && !new_crtc_state->scaler_state.scaler_users && From 6f71507415841d1a6d38118e5fa0eaf0caab9c17 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 21 Jan 2025 06:52:03 -0800 Subject: [PATCH 077/284] drm/i915/backlight: Return immediately when scale() finds invalid parameters The scale() functions detects invalid parameters, but continues its calculations anyway. This causes bad results if negative values are used for unsigned operations. Worst case, a division by 0 error will be seen if source_min == source_max. On top of that, after v6.13, the sequence of WARN_ON() followed by clamp() may result in a build error with gcc 13.x. drivers/gpu/drm/i915/display/intel_backlight.c: In function 'scale': include/linux/compiler_types.h:542:45: error: call to '__compiletime_assert_415' declared with attribute error: clamp() low limit source_min greater than high limit source_max This happens if the compiler decides to rearrange the code as follows. if (source_min > source_max) { WARN(..); /* Do the clamp() knowing that source_min > source_max */ source_val = clamp(source_val, source_min, source_max); } else { /* Do the clamp knowing that source_min <= source_max */ source_val = clamp(source_val, source_min, source_max); } Fix the problem by evaluating the return values from WARN_ON and returning immediately after a warning. While at it, fix divide by zero error seen if source_min == source_max. Analyzed-by: Linus Torvalds Suggested-by: Linus Torvalds Suggested-by: David Laight Cc: David Laight Cc: Jani Nikula Cc: Andy Shevchenko Signed-off-by: Guenter Roeck Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20250121145203.2851237-1-linux@roeck-us.net Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_backlight.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index fc1e517e074a3..7e6ce905bdafa 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -41,8 +41,9 @@ static u32 scale(u32 source_val, { u64 target_val; - WARN_ON(source_min > source_max); - WARN_ON(target_min > target_max); + if (WARN_ON(source_min >= source_max) || + WARN_ON(target_min > target_max)) + return target_min; /* defensive */ source_val = clamp(source_val, source_min, source_max); From c132ec36fc28d58ba7e28b0f66651a9310e0d61a Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 17 Jan 2025 10:37:13 +0530 Subject: [PATCH 078/284] drm/i915/dp: Correct max compressed bpp bounds by using link bpp While setting the bounds for compressed bpp, we ensure that the compressed bpp is less than the pipe bpp. This causes an issue with the 420 output format, where the effective link bpp (or output bpp) is half that of the pipe bpp. Therefore instead of using pipe bpp, use the output bpp to set the bounds for the compressed bpp. v2: Use identifier output_bpp instead of link_bpp (Imre) Signed-off-by: Ankit Nautiyal Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250117050713.152012-1-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f1f3b1bb1e89b..9ec23860b593d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2068,9 +2068,10 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp, int timeslots) { int i, ret; + int output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); /* Compressed BPP should be less than the Input DSC bpp */ - dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1); + dsc_max_bpp = min(dsc_max_bpp, output_bpp - 1); for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) { if (valid_dsc_bpp[i] < dsc_min_bpp) @@ -2111,6 +2112,7 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); u8 bppx16_incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd); + int output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); u16 compressed_bppx16; u8 bppx16_step; int ret; @@ -2121,7 +2123,7 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, bppx16_step = 16 / bppx16_incr; /* Compressed BPP should be less than the Input DSC bpp */ - dsc_max_bpp = min(dsc_max_bpp << 4, (pipe_bpp << 4) - bppx16_step); + dsc_max_bpp = min(dsc_max_bpp << 4, (output_bpp << 4) - bppx16_step); dsc_min_bpp = dsc_min_bpp << 4; for (compressed_bppx16 = dsc_max_bpp; From 1abf834951fb039f24819283b7abd9f8309852b0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 8 Jan 2025 17:19:12 +0200 Subject: [PATCH 079/284] drm/i915/dp_mst: Fix error handling while adding a connector After an error during adding an MST connector the MST port and the intel_connector object could be leaked, fix this up. Reviewed-by: Rodrigo Vivi Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250108151916.491113-2-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 0c44fc7dd86ce..85aafdf573e80 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1717,11 +1717,8 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, ret = drm_connector_dynamic_init(display->drm, connector, &mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort, NULL); - if (ret) { - drm_dp_mst_put_port_malloc(port); - intel_connector_free(intel_connector); - return NULL; - } + if (ret) + goto err_put_port; intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port); intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector); @@ -1736,12 +1733,12 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, ret = drm_connector_attach_encoder(&intel_connector->base, enc); if (ret) - goto err; + goto err_cleanup_connector; } ret = mst_topology_add_connector_properties(intel_dp, connector, pathprop); if (ret) - goto err; + goto err_cleanup_connector; ret = intel_dp_hdcp_init(dig_port, intel_connector); if (ret) @@ -1750,8 +1747,12 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, return connector; -err: +err_cleanup_connector: drm_connector_cleanup(connector); +err_put_port: + drm_dp_mst_put_port_malloc(port); + intel_connector_free(intel_connector); + return NULL; } From d49b485d1be3cb1b3b719cf4031f879dbc26c633 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 8 Jan 2025 17:19:13 +0200 Subject: [PATCH 080/284] drm/i915/dp_mst: Use intel_connector vs. drm_connector pointer in intel_dp_mst.c Follow the canonical way in intel_dp_mst.c, referencing a connector only via a struct intel_connector pointer and naming this pointer 'connector' instead of 'intel_connector', the only exception being the casting of a drm_connector function parameter pointer to intel_connector, calling the drm_connector pointer _connector. Suggested-by: Jani Nikula Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250108151916.491113-3-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 180 ++++++++++---------- 1 file changed, 88 insertions(+), 92 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 85aafdf573e80..c4da16631d43e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -943,33 +943,32 @@ mst_connector_atomic_topology_check(struct intel_connector *connector, } static int -mst_connector_atomic_check(struct drm_connector *connector, +mst_connector_atomic_check(struct drm_connector *_connector, struct drm_atomic_state *_state) { struct intel_atomic_state *state = to_intel_atomic_state(_state); - struct intel_connector *intel_connector = - to_intel_connector(connector); + struct intel_connector *connector = to_intel_connector(_connector); int ret; - ret = intel_digital_connector_atomic_check(connector, &state->base); + ret = intel_digital_connector_atomic_check(&connector->base, &state->base); if (ret) return ret; - ret = mst_connector_atomic_topology_check(intel_connector, state); + ret = mst_connector_atomic_topology_check(connector, state); if (ret) return ret; - if (intel_connector_needs_modeset(state, connector)) { + if (intel_connector_needs_modeset(state, &connector->base)) { ret = intel_dp_tunnel_atomic_check_state(state, - intel_connector->mst_port, - intel_connector); + connector->mst_port, + connector); if (ret) return ret; } return drm_dp_atomic_release_time_slots(&state->base, - &intel_connector->mst_port->mst_mgr, - intel_connector->port); + &connector->mst_port->mst_mgr, + connector->port); } static void mst_stream_disable(struct intel_atomic_state *state, @@ -1349,23 +1348,23 @@ static bool mst_stream_initial_fastset_check(struct intel_encoder *encoder, return intel_dp_initial_fastset_check(primary_encoder, crtc_state); } -static int mst_connector_get_ddc_modes(struct drm_connector *connector) +static int mst_connector_get_ddc_modes(struct drm_connector *_connector) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_dp *intel_dp = intel_connector->mst_port; + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector->base.dev); + struct intel_dp *intel_dp = connector->mst_port; const struct drm_edid *drm_edid; int ret; - if (drm_connector_is_unregistered(connector)) - return intel_connector_update_modes(connector, NULL); + if (drm_connector_is_unregistered(&connector->base)) + return intel_connector_update_modes(&connector->base, NULL); if (!intel_display_driver_check_access(display)) - return drm_edid_connector_add_modes(connector); + return drm_edid_connector_add_modes(&connector->base); - drm_edid = drm_dp_mst_edid_read(connector, &intel_dp->mst_mgr, intel_connector->port); + drm_edid = drm_dp_mst_edid_read(&connector->base, &intel_dp->mst_mgr, connector->port); - ret = intel_connector_update_modes(connector, drm_edid); + ret = intel_connector_update_modes(&connector->base, drm_edid); drm_edid_free(drm_edid); @@ -1373,32 +1372,29 @@ static int mst_connector_get_ddc_modes(struct drm_connector *connector) } static int -mst_connector_late_register(struct drm_connector *connector) +mst_connector_late_register(struct drm_connector *_connector) { - struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_connector *connector = to_intel_connector(_connector); int ret; - ret = drm_dp_mst_connector_late_register(connector, - intel_connector->port); + ret = drm_dp_mst_connector_late_register(&connector->base, connector->port); if (ret < 0) return ret; - ret = intel_connector_register(connector); + ret = intel_connector_register(&connector->base); if (ret < 0) - drm_dp_mst_connector_early_unregister(connector, - intel_connector->port); + drm_dp_mst_connector_early_unregister(&connector->base, connector->port); return ret; } static void -mst_connector_early_unregister(struct drm_connector *connector) +mst_connector_early_unregister(struct drm_connector *_connector) { - struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_connector *connector = to_intel_connector(_connector); - intel_connector_unregister(connector); - drm_dp_mst_connector_early_unregister(connector, - intel_connector->port); + intel_connector_unregister(&connector->base); + drm_dp_mst_connector_early_unregister(&connector->base, connector->port); } static const struct drm_connector_funcs mst_connector_funcs = { @@ -1412,23 +1408,25 @@ static const struct drm_connector_funcs mst_connector_funcs = { .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; -static int mst_connector_get_modes(struct drm_connector *connector) +static int mst_connector_get_modes(struct drm_connector *_connector) { - return mst_connector_get_ddc_modes(connector); + struct intel_connector *connector = to_intel_connector(_connector); + + return mst_connector_get_ddc_modes(&connector->base); } static int -mst_connector_mode_valid_ctx(struct drm_connector *connector, +mst_connector_mode_valid_ctx(struct drm_connector *_connector, struct drm_display_mode *mode, struct drm_modeset_acquire_ctx *ctx, enum drm_mode_status *status) { - struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *dev_priv = to_i915(connector->dev); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_dp *intel_dp = intel_connector->mst_port; + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector->base.dev); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_dp *intel_dp = connector->mst_port; struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; - struct drm_dp_mst_port *port = intel_connector->port; + struct drm_dp_mst_port *port = connector->port; const int min_bpp = 18; int max_dotclk = display->cdclk.max_dotclk_freq; int max_rate, mode_rate, max_lanes, max_link_clock; @@ -1439,7 +1437,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, int target_clock = mode->clock; int num_joined_pipes; - if (drm_connector_is_unregistered(connector)) { + if (drm_connector_is_unregistered(&connector->base)) { *status = MODE_ERROR; return 0; } @@ -1477,7 +1475,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, * corresponding link capabilities of the sink) in case the * stream is uncompressed for it by the last branch device. */ - num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, intel_connector, + num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector, mode->hdisplay, target_clock); max_dotclk *= num_joined_pipes; @@ -1491,14 +1489,14 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, return 0; } - if (intel_dp_has_dsc(intel_connector)) { + if (intel_dp_has_dsc(connector)) { /* * TBD pass the connector BPC, * for now U8_MAX so that max BPC on that platform would be picked */ - int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_connector, U8_MAX); + int pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, U8_MAX); - if (drm_dp_sink_supports_fec(intel_connector->dp.fec_capability)) { + if (drm_dp_sink_supports_fec(connector->dp.fec_capability)) { dsc_max_compressed_bpp = intel_dp_dsc_get_max_compressed_bpp(display, max_link_clock, @@ -1509,7 +1507,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, INTEL_OUTPUT_FORMAT_RGB, pipe_bpp, 64); dsc_slice_count = - intel_dp_dsc_get_slice_count(intel_connector, + intel_dp_dsc_get_slice_count(connector, target_clock, mode->hdisplay, num_joined_pipes); @@ -1533,39 +1531,39 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, } static struct drm_encoder * -mst_connector_atomic_best_encoder(struct drm_connector *connector, +mst_connector_atomic_best_encoder(struct drm_connector *_connector, struct drm_atomic_state *state) { - struct drm_connector_state *connector_state = drm_atomic_get_new_connector_state(state, - connector); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_dp *intel_dp = intel_connector->mst_port; + struct intel_connector *connector = to_intel_connector(_connector); + struct drm_connector_state *connector_state = + drm_atomic_get_new_connector_state(state, &connector->base); + struct intel_dp *intel_dp = connector->mst_port; struct intel_crtc *crtc = to_intel_crtc(connector_state->crtc); return &intel_dp->mst_encoders[crtc->pipe]->base.base; } static int -mst_connector_detect_ctx(struct drm_connector *connector, +mst_connector_detect_ctx(struct drm_connector *_connector, struct drm_modeset_acquire_ctx *ctx, bool force) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_dp *intel_dp = intel_connector->mst_port; + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector->base.dev); + struct intel_dp *intel_dp = connector->mst_port; if (!intel_display_device_enabled(display)) return connector_status_disconnected; - if (drm_connector_is_unregistered(connector)) + if (drm_connector_is_unregistered(&connector->base)) return connector_status_disconnected; if (!intel_display_driver_check_access(display)) - return connector->status; + return connector->base.status; - intel_dp_flush_connector_commits(intel_connector); + intel_dp_flush_connector_commits(connector); - return drm_dp_mst_detect_port(connector, ctx, &intel_dp->mst_mgr, - intel_connector->port); + return drm_dp_mst_detect_port(&connector->base, ctx, &intel_dp->mst_mgr, + connector->port); } static const struct drm_connector_helper_funcs mst_connector_helper_funcs = { @@ -1601,29 +1599,30 @@ static bool mst_connector_get_hw_state(struct intel_connector *connector) } static int mst_topology_add_connector_properties(struct intel_dp *intel_dp, - struct drm_connector *connector, + struct drm_connector *_connector, const char *pathprop) { struct intel_display *display = to_intel_display(intel_dp); + struct intel_connector *connector = to_intel_connector(_connector); - drm_object_attach_property(&connector->base, + drm_object_attach_property(&connector->base.base, display->drm->mode_config.path_property, 0); - drm_object_attach_property(&connector->base, + drm_object_attach_property(&connector->base.base, display->drm->mode_config.tile_property, 0); - intel_attach_force_audio_property(connector); - intel_attach_broadcast_rgb_property(connector); + intel_attach_force_audio_property(&connector->base); + intel_attach_broadcast_rgb_property(&connector->base); /* * Reuse the prop from the SST connector because we're * not allowed to create new props after device registration. */ - connector->max_bpc_property = + connector->base.max_bpc_property = intel_dp->attached_connector->base.max_bpc_property; - if (connector->max_bpc_property) - drm_connector_attach_max_bpc_property(connector, 6, 12); + if (connector->base.max_bpc_property) + drm_connector_attach_max_bpc_property(&connector->base, 6, 12); - return drm_connector_set_path_property(connector, pathprop); + return drm_connector_set_path_property(&connector->base, pathprop); } static void @@ -1696,62 +1695,59 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct intel_connector *intel_connector; - struct drm_connector *connector; + struct intel_connector *connector; enum pipe pipe; int ret; - intel_connector = intel_connector_alloc(); - if (!intel_connector) + connector = intel_connector_alloc(); + if (!connector) return NULL; - connector = &intel_connector->base; - - intel_connector->get_hw_state = mst_connector_get_hw_state; - intel_connector->sync_state = intel_dp_connector_sync_state; - intel_connector->mst_port = intel_dp; - intel_connector->port = port; + connector->get_hw_state = mst_connector_get_hw_state; + connector->sync_state = intel_dp_connector_sync_state; + connector->mst_port = intel_dp; + connector->port = port; drm_dp_mst_get_port_malloc(port); - intel_dp_init_modeset_retry_work(intel_connector); + intel_dp_init_modeset_retry_work(connector); - ret = drm_connector_dynamic_init(display->drm, connector, &mst_connector_funcs, + ret = drm_connector_dynamic_init(display->drm, &connector->base, &mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort, NULL); if (ret) goto err_put_port; - intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port); - intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector); - intel_connector->dp.dsc_hblank_expansion_quirk = - detect_dsc_hblank_expansion_quirk(intel_connector); + connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port); + intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, connector); + connector->dp.dsc_hblank_expansion_quirk = + detect_dsc_hblank_expansion_quirk(connector); - drm_connector_helper_add(connector, &mst_connector_helper_funcs); + drm_connector_helper_add(&connector->base, &mst_connector_helper_funcs); for_each_pipe(display, pipe) { struct drm_encoder *enc = &intel_dp->mst_encoders[pipe]->base.base; - ret = drm_connector_attach_encoder(&intel_connector->base, enc); + ret = drm_connector_attach_encoder(&connector->base, enc); if (ret) goto err_cleanup_connector; } - ret = mst_topology_add_connector_properties(intel_dp, connector, pathprop); + ret = mst_topology_add_connector_properties(intel_dp, &connector->base, pathprop); if (ret) goto err_cleanup_connector; - ret = intel_dp_hdcp_init(dig_port, intel_connector); + ret = intel_dp_hdcp_init(dig_port, connector); if (ret) drm_dbg_kms(display->drm, "[%s:%d] HDCP MST init failed, skipping.\n", - connector->name, connector->base.id); + connector->base.name, connector->base.base.id); - return connector; + return &connector->base; err_cleanup_connector: - drm_connector_cleanup(connector); + drm_connector_cleanup(&connector->base); err_put_port: drm_dp_mst_put_port_malloc(port); - intel_connector_free(intel_connector); + intel_connector_free(connector); return NULL; } From ae1e7fba27c9f68dfcaa0f527ee38dda013e566c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 8 Jan 2025 17:19:14 +0200 Subject: [PATCH 081/284] drm/i915/dp_mst: Simplify using to_intel_display() passing it an intel_connector pointer Simplify the use of to_intel_display() in intel_dp_mst.c passing it the already available intel_connector pointer, instead of looking up a drm_device pointer for the same purpose. Suggested-by: Jani Nikula Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250108151916.491113-4-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index c4da16631d43e..84538aa695c23 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1351,7 +1351,7 @@ static bool mst_stream_initial_fastset_check(struct intel_encoder *encoder, static int mst_connector_get_ddc_modes(struct drm_connector *_connector) { struct intel_connector *connector = to_intel_connector(_connector); - struct intel_display *display = to_intel_display(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_dp *intel_dp = connector->mst_port; const struct drm_edid *drm_edid; int ret; @@ -1422,7 +1422,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, enum drm_mode_status *status) { struct intel_connector *connector = to_intel_connector(_connector); - struct intel_display *display = to_intel_display(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_dp *intel_dp = connector->mst_port; struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; @@ -1548,7 +1548,7 @@ mst_connector_detect_ctx(struct drm_connector *_connector, struct drm_modeset_acquire_ctx *ctx, bool force) { struct intel_connector *connector = to_intel_connector(_connector); - struct intel_display *display = to_intel_display(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_dp *intel_dp = connector->mst_port; if (!intel_display_device_enabled(display)) From 6aeaa55ae7683f7046fa362d57788f7fc1111e47 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 8 Jan 2025 17:19:15 +0200 Subject: [PATCH 082/284] drm/i915/dp_mst: Simplify getting a drm_device pointer needed by to_i915() Simplify getting a drm_device pointer when using to_i915() in intel_dp_mst.c from the already available intel_display object, instead of getting it from a DRM KMS object. While at it rename dev_priv to i915, following the driver's standard terminology. Suggested-by: Jani Nikula Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250108151916.491113-5-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 84538aa695c23..afc843fd53930 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1423,7 +1423,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, { struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_dp *intel_dp = connector->mst_port; struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; struct drm_dp_mst_port *port = connector->port; @@ -1442,7 +1442,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, return 0; } - *status = intel_cpu_transcoder_mode_valid(dev_priv, mode); + *status = intel_cpu_transcoder_mode_valid(i915, mode); if (*status != MODE_OK) return 0; @@ -1526,7 +1526,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, return 0; } - *status = intel_mode_valid_max_plane_size(dev_priv, mode, num_joined_pipes); + *status = intel_mode_valid_max_plane_size(i915, mode, num_joined_pipes); return 0; } From b9360d1751ec9397ab9e4fdea24a749d8fc19c91 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 8 Jan 2025 17:19:16 +0200 Subject: [PATCH 083/284] drm/i915/dp_mst: Use intel_display::platform.alderlake_p instead of IS_ALDERLAKE_P() Use the driver's standard intel_display::platform.alderlake_p instead of IS_ALDERLAKE_P(). Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250108151916.491113-6-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index afc843fd53930..fbfc756368b87 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1219,11 +1219,10 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, static void enable_bs_jitter_was(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); u32 clear = 0; u32 set = 0; - if (!IS_ALDERLAKE_P(i915)) + if (!display->platform.alderlake_p) return; if (!IS_DISPLAY_STEP(display, STEP_D0, STEP_FOREVER)) From 5947642004bfd56436ce63d3e65d517b5be52549 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 20 Jan 2025 09:51:17 +0530 Subject: [PATCH 084/284] drm/i915/display: Add support for SNPS PHY HDMI PLL algorithm for DG2 Add helpers to calculate the necessary parameters for configuring the HDMI PLL for SNPS MPLLB and C10 PHY. The pll parameters are computed for desired pixel clock, curve data and other inputs used for interpolation and finally stored in the pll_state. Currently the helper is used to compute PLLs for DG2 SNPS PHY. Support for computing Plls for C10 PHY is added in subsequent patches. v2: -Used kernel types instead of C99 types. (Jani) -Fixed styling issues and renamed few variables to more meaningful names. (Jani) -Added Xe make file changes. (Jani) -Fixed build errors reported by kernel test robot v3: -Renamed helper to align with file name. (Jani) v4: -Removed erroraneous comment, and added Bspec# as part of trailer. (Suraj) -Fixed warning flagged by kernel test robot. Bspec: 54032 Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Acked-by: Jani Nikula Tested-by: Khaled Almahallawy Link: https://patchwork.freedesktop.org/patch/msgid/20250120042122.1029481-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + .../drm/i915/display/intel_snps_hdmi_pll.c | 288 ++++++++++++++++++ .../drm/i915/display/intel_snps_hdmi_pll.h | 15 + drivers/gpu/drm/xe/Makefile | 1 + 4 files changed, 305 insertions(+) create mode 100644 drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c create mode 100644 drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 3dda9f0eda82b..4caa8e30bc983 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -346,6 +346,7 @@ i915-y += \ display/intel_pps.o \ display/intel_qp_tables.o \ display/intel_sdvo.o \ + display/intel_snps_hdmi_pll.o \ display/intel_snps_phy.o \ display/intel_tv.o \ display/intel_vdsc.o \ diff --git a/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c new file mode 100644 index 0000000000000..0e52578ef181a --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2025 Synopsys, Inc., Intel Corporation + */ + +#include + +#include "intel_display_types.h" +#include "intel_snps_phy.h" +#include "intel_snps_phy_regs.h" +#include "intel_snps_hdmi_pll.h" + +#define INTEL_SNPS_PHY_HDMI_4999MHZ 4999999900ULL +#define INTEL_SNPS_PHY_HDMI_16GHZ 16000000000ULL +#define INTEL_SNPS_PHY_HDMI_9999MHZ (2 * INTEL_SNPS_PHY_HDMI_4999MHZ) + +#define CURVE0_MULTIPLIER 1000000000 +#define CURVE1_MULTIPLIER 100 +#define CURVE2_MULTIPLIER 1000000000000ULL + +struct pll_output_params { + u32 ssc_up_spread; + u32 mpll_div5_en; + u32 hdmi_div; + u32 ana_cp_int; + u32 ana_cp_prop; + u32 refclk_postscalar; + u32 tx_clk_div; + u32 fracn_quot; + u32 fracn_rem; + u32 fracn_den; + u32 fracn_en; + u32 pmix_en; + u32 multiplier; + int mpll_ana_v2i; + int ana_freq_vco; +}; + +static s64 interp(s64 x, s64 x1, s64 x2, s64 y1, s64 y2) +{ + s64 dydx; + + dydx = DIV_ROUND_UP_ULL((y2 - y1) * 100000, (x2 - x1)); + + return (y1 + DIV_ROUND_UP_ULL(dydx * (x - x1), 100000)); +} + +static void get_ana_cp_int_prop(u32 vco_clk, + u32 refclk_postscalar, + int mpll_ana_v2i, + int c, int a, + const u64 curve_freq_hz[2][8], + const u64 curve_0[2][8], + const u64 curve_1[2][8], + const u64 curve_2[2][8], + u32 *ana_cp_int, + u32 *ana_cp_prop) +{ + u64 vco_div_refclk_float; + u64 curve_0_interpolated; + u64 curve_2_interpolated; + u64 curve_1_interpolated; + u64 curve_2_scaled1; + u64 curve_2_scaled2; + u64 adjusted_vco_clk1; + u64 adjusted_vco_clk2; + u64 curve_2_scaled_int; + u64 interpolated_product; + u64 scaled_interpolated_sqrt; + u64 scaled_vco_div_refclk1; + u64 scaled_vco_div_refclk2; + u64 ana_cp_int_temp; + u64 temp; + + vco_div_refclk_float = vco_clk * DIV_ROUND_DOWN_ULL(1000000000000ULL, refclk_postscalar); + + /* Interpolate curve values at the target vco_clk frequency */ + curve_0_interpolated = interp(vco_clk, curve_freq_hz[c][a], curve_freq_hz[c][a + 1], + curve_0[c][a], curve_0[c][a + 1]); + + curve_2_interpolated = interp(vco_clk, curve_freq_hz[c][a], curve_freq_hz[c][a + 1], + curve_2[c][a], curve_2[c][a + 1]); + + curve_1_interpolated = interp(vco_clk, curve_freq_hz[c][a], curve_freq_hz[c][a + 1], + curve_1[c][a], curve_1[c][a + 1]); + + curve_1_interpolated = DIV_ROUND_DOWN_ULL(curve_1_interpolated, CURVE1_MULTIPLIER); + + /* + * Scale curve_2_interpolated based on mpll_ana_v2i, for integer part + * ana_cp_int and for the proportional part ana_cp_prop + */ + temp = curve_2_interpolated * (4 - mpll_ana_v2i); + curve_2_scaled1 = DIV_ROUND_DOWN_ULL(temp, 16000); + curve_2_scaled2 = DIV_ROUND_DOWN_ULL(temp, 160); + + /* Scale vco_div_refclk for ana_cp_int */ + scaled_vco_div_refclk1 = 112008301 * DIV_ROUND_DOWN_ULL(vco_div_refclk_float, 100000); + + adjusted_vco_clk1 = CURVE2_MULTIPLIER * + DIV_ROUND_DOWN_ULL(scaled_vco_div_refclk1, (curve_0_interpolated * + DIV_ROUND_DOWN_ULL(curve_1_interpolated, CURVE0_MULTIPLIER))); + + ana_cp_int_temp = + DIV_ROUND_CLOSEST_ULL(DIV_ROUND_DOWN_ULL(adjusted_vco_clk1, curve_2_scaled1), + CURVE2_MULTIPLIER); + + *ana_cp_int = max(1, min(ana_cp_int_temp, 127)); + + curve_2_scaled_int = curve_2_scaled1 * (*ana_cp_int); + + interpolated_product = curve_1_interpolated * + (curve_2_scaled_int * DIV_ROUND_DOWN_ULL(curve_0_interpolated, + CURVE0_MULTIPLIER)); + + scaled_interpolated_sqrt = + int_sqrt(DIV_ROUND_UP_ULL(interpolated_product, vco_div_refclk_float) * + DIV_ROUND_DOWN_ULL(1000000000000ULL, 55)); + + /* Scale vco_div_refclk for ana_cp_int */ + scaled_vco_div_refclk2 = DIV_ROUND_UP_ULL(vco_div_refclk_float, 1000000); + adjusted_vco_clk2 = 1460281 * DIV_ROUND_UP_ULL(scaled_interpolated_sqrt * + scaled_vco_div_refclk2, + curve_1_interpolated); + + *ana_cp_prop = DIV_ROUND_UP_ULL(adjusted_vco_clk2, curve_2_scaled2); + *ana_cp_prop = max(1, min(*ana_cp_prop, 127)); +} + +static void compute_hdmi_tmds_pll(u64 pixel_clock, u32 refclk, + u32 ref_range, + u32 ana_cp_int_gs, + u32 ana_cp_prop_gs, + const u64 curve_freq_hz[2][8], + const u64 curve_0[2][8], + const u64 curve_1[2][8], + const u64 curve_2[2][8], + u32 prescaler_divider, + struct pll_output_params *pll_params) +{ + u64 datarate = pixel_clock * 10000; + u32 ssc_up_spread = 1; + u32 mpll_div5_en = 1; + u32 hdmi_div = 1; + u32 ana_cp_int; + u32 ana_cp_prop; + u32 refclk_postscalar = refclk >> prescaler_divider; + u32 tx_clk_div; + u64 vco_clk; + u64 vco_clk_do_div; + u32 vco_div_refclk_integer; + u32 vco_div_refclk_fracn; + u32 fracn_quot; + u32 fracn_rem; + u32 fracn_den; + u32 fracn_en; + u32 pmix_en; + u32 multiplier; + int mpll_ana_v2i; + int ana_freq_vco = 0; + int c, a = 0; + int i; + + /* Select appropriate v2i point */ + if (datarate <= INTEL_SNPS_PHY_HDMI_9999MHZ) { + mpll_ana_v2i = 2; + tx_clk_div = ilog2(DIV_ROUND_DOWN_ULL(INTEL_SNPS_PHY_HDMI_9999MHZ, datarate)); + } else { + mpll_ana_v2i = 3; + tx_clk_div = ilog2(DIV_ROUND_DOWN_ULL(INTEL_SNPS_PHY_HDMI_16GHZ, datarate)); + } + vco_clk = (datarate << tx_clk_div) >> 1; + + vco_div_refclk_integer = DIV_ROUND_DOWN_ULL(vco_clk, refclk_postscalar); + vco_clk_do_div = do_div(vco_clk, refclk_postscalar); + vco_div_refclk_fracn = DIV_ROUND_DOWN_ULL(vco_clk_do_div << 32, refclk_postscalar); + + fracn_quot = vco_div_refclk_fracn >> 16; + fracn_rem = vco_div_refclk_fracn & 0xffff; + fracn_rem = fracn_rem - (fracn_rem >> 15); + fracn_den = 0xffff; + fracn_en = (fracn_quot != 0 || fracn_rem != 0) ? 1 : 0; + pmix_en = fracn_en; + multiplier = (vco_div_refclk_integer - 16) * 2; + /* Curve selection for ana_cp_* calculations. One curve hardcoded per v2i range */ + c = mpll_ana_v2i - 2; + + /* Find the right segment of the table */ + for (i = 0; i < 8; i += 2) { + if (vco_clk <= curve_freq_hz[c][i + 1]) { + a = i; + ana_freq_vco = 3 - (a >> 1); + break; + } + } + + get_ana_cp_int_prop(vco_clk, refclk_postscalar, mpll_ana_v2i, c, a, + curve_freq_hz, curve_0, curve_1, curve_2, + &ana_cp_int, &ana_cp_prop); + + pll_params->ssc_up_spread = ssc_up_spread; + pll_params->mpll_div5_en = mpll_div5_en; + pll_params->hdmi_div = hdmi_div; + pll_params->ana_cp_int = ana_cp_int; + pll_params->refclk_postscalar = refclk_postscalar; + pll_params->tx_clk_div = tx_clk_div; + pll_params->fracn_quot = fracn_quot; + pll_params->fracn_rem = fracn_rem; + pll_params->fracn_den = fracn_den; + pll_params->fracn_en = fracn_en; + pll_params->pmix_en = pmix_en; + pll_params->multiplier = multiplier; + pll_params->ana_cp_prop = ana_cp_prop; + pll_params->mpll_ana_v2i = mpll_ana_v2i; + pll_params->ana_freq_vco = ana_freq_vco; +} + +void intel_snps_hdmi_pll_compute_mpllb(struct intel_mpllb_state *pll_state, u64 pixel_clock) +{ + /* x axis frequencies. One curve in each array per v2i point */ + static const u64 dg2_curve_freq_hz[2][8] = { + { 2500000000ULL, 3000000000ULL, 3000000000ULL, 3500000000ULL, 3500000000ULL, + 4000000000ULL, 4000000000ULL, 5000000000ULL }, + { 4000000000ULL, 4600000000ULL, 4601000000ULL, 5400000000ULL, 5401000000ULL, + 6600000000ULL, 6601000000ULL, 8001000000ULL } + }; + + /* y axis heights multiplied with 1000000000 */ + static const u64 dg2_curve_0[2][8] = { + { 34149871, 39803269, 36034544, 40601014, 35646940, 40016109, 35127987, 41889522 }, + { 70000000, 78770454, 70451838, 80427119, 70991400, 84230173, 72945921, 87064218 } + }; + + /* Multiplied with 100 */ + static const u64 dg2_curve_1[2][8] = { + { 85177000000000ULL, 79385227160000ULL, 95672603580000ULL, 88857207160000ULL, + 109379790900000ULL, 103528193900000ULL, 131941242400000ULL, 117279000000000ULL }, + { 60255000000000ULL, 55569000000000ULL, 72036000000000ULL, 69509000000000ULL, + 81785000000000ULL, 731030000000000ULL, 96591000000000ULL, 69077000000000ULL } + }; + + /* Multiplied with 1000000000000 */ + static const u64 dg2_curve_2[2][8] = { + { 2186930000ULL, 2835287134ULL, 2395395343ULL, 2932270687ULL, 2351887545ULL, + 2861031697ULL, 2294149152ULL, 3091730000ULL }, + { 4560000000ULL, 5570000000ULL, 4610000000ULL, 5770000000ULL, 4670000000ULL, + 6240000000ULL, 4890000000ULL, 6600000000ULL } + }; + + struct pll_output_params pll_params; + u32 refclk = 100000000; + u32 prescaler_divider = 1; + u32 ref_range = 3; + u32 ana_cp_int_gs = 64; + u32 ana_cp_prop_gs = 124; + + compute_hdmi_tmds_pll(pixel_clock, refclk, ref_range, ana_cp_int_gs, ana_cp_prop_gs, + dg2_curve_freq_hz, dg2_curve_0, dg2_curve_1, dg2_curve_2, + prescaler_divider, &pll_params); + + pll_state->clock = pixel_clock; + pll_state->ref_control = + REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, ref_range); + pll_state->mpllb_cp = + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, pll_params.ana_cp_int) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, pll_params.ana_cp_prop) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, ana_cp_int_gs) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, ana_cp_prop_gs); + pll_state->mpllb_div = + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, pll_params.mpll_div5_en) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, pll_params.tx_clk_div) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, pll_params.pmix_en) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, pll_params.mpll_ana_v2i) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, pll_params.ana_freq_vco); + pll_state->mpllb_div2 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, prescaler_divider) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, pll_params.multiplier) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, pll_params.hdmi_div); + pll_state->mpllb_fracn1 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, pll_params.fracn_en) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, pll_params.fracn_den); + pll_state->mpllb_fracn2 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, pll_params.fracn_quot) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, pll_params.fracn_rem); + pll_state->mpllb_sscen = + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, pll_params.ssc_up_spread); +} diff --git a/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.h b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.h new file mode 100644 index 0000000000000..70b7023c11356 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2025 Synopsys, Inc., Intel Corporation + */ + +#ifndef __INTEL_SNPS_HDMI_PLL_H__ +#define __INTEL_SNPS_HDMI_PLL_H__ + +#include + +struct intel_mpllb_state; + +void intel_snps_hdmi_pll_compute_mpllb(struct intel_mpllb_state *pll_state, u64 pixel_clock); + +#endif /* __INTEL_SNPS_HDMI_PLL_H__ */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 81f63258a7e19..f639c9d750234 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -262,6 +262,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_psr.o \ i915-display/intel_qp_tables.o \ i915-display/intel_quirks.o \ + i915-display/intel_snps_hdmi_pll.o \ i915-display/intel_snps_phy.o \ i915-display/intel_tc.o \ i915-display/intel_vblank.o \ From 560de03d15c06a3c17b20733a5b200ac0f78ae40 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 20 Jan 2025 09:51:18 +0530 Subject: [PATCH 085/284] drm/i915/snps_phy: Use HDMI PLL algorithm for DG2 Try SNPS_PHY HDMI alogorithm, if there are no pre-computed tables. Also get rid of the helper to get rate for HDMI snps phy, as we no longer depend only on pre-computed tables. v2: -Prefer pre-computed tables over computed values from algorithm. (Jani) Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Acked-by: Jani Nikula Tested-by: Khaled Almahallawy Link: https://patchwork.freedesktop.org/patch/msgid/20250120042122.1029481-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_hdmi.c | 2 - drivers/gpu/drm/i915/display/intel_snps_phy.c | 37 +++++-------------- drivers/gpu/drm/i915/display/intel_snps_phy.h | 1 - 3 files changed, 9 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index ed29dd0ccef0f..a0133713725be 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1918,8 +1918,6 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, */ if (DISPLAY_VER(display) >= 14) return intel_cx0_phy_check_hdmi_link_rate(hdmi, clock); - else if (IS_DG2(dev_priv)) - return intel_snps_phy_check_hdmi_link_rate(clock); return MODE_OK; } diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index 41fe26dc200b3..ec3c0ea2f4cbc 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -11,6 +11,7 @@ #include "intel_ddi_buf_trans.h" #include "intel_de.h" #include "intel_display_types.h" +#include "intel_snps_hdmi_pll.h" #include "intel_snps_phy.h" #include "intel_snps_phy_regs.h" @@ -1788,24 +1789,9 @@ intel_mpllb_tables_get(struct intel_crtc_state *crtc_state, int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); const struct intel_mpllb_state * const *tables; int i; - if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { - if (intel_snps_phy_check_hdmi_link_rate(crtc_state->port_clock) - != MODE_OK) { - /* - * FIXME: Can only support fixed HDMI frequencies - * until we have a proper algorithm under a valid - * license. - */ - drm_dbg_kms(&i915->drm, "Can't support HDMI link rate %d\n", - crtc_state->port_clock); - return -EINVAL; - } - } - tables = intel_mpllb_tables_get(crtc_state, encoder); if (!tables) return -EINVAL; @@ -1817,6 +1803,14 @@ int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state, } } + /* For HDMI PLLs try SNPS PHY algorithm, if there are no precomputed tables */ + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { + intel_snps_hdmi_pll_compute_mpllb(&crtc_state->dpll_hw_state.mpllb, + crtc_state->port_clock); + + return 0; + } + return -EINVAL; } @@ -1982,19 +1976,6 @@ void intel_mpllb_readout_hw_state(struct intel_encoder *encoder, pll_state->mpllb_div &= ~SNPS_PHY_MPLLB_FORCE_EN; } -int intel_snps_phy_check_hdmi_link_rate(int clock) -{ - const struct intel_mpllb_state * const *tables = dg2_hdmi_tables; - int i; - - for (i = 0; tables[i]; i++) { - if (clock == tables[i]->clock) - return MODE_OK; - } - - return MODE_CLOCK_RANGE; -} - void intel_mpllb_state_verify(struct intel_atomic_state *state, struct intel_crtc *crtc) { diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.h b/drivers/gpu/drm/i915/display/intel_snps_phy.h index bc08b92a7cd96..1dd564ed9fa8a 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.h +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.h @@ -30,7 +30,6 @@ void intel_mpllb_readout_hw_state(struct intel_encoder *encoder, int intel_mpllb_calc_port_clock(struct intel_encoder *encoder, const struct intel_mpllb_state *pll_state); -int intel_snps_phy_check_hdmi_link_rate(int clock); void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void intel_mpllb_state_verify(struct intel_atomic_state *state, From 18176f56942a596c5d03ed69ef30ad72f67a7edc Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 22 Jan 2025 21:58:50 +0530 Subject: [PATCH 086/284] drm/i915/cx0_phy_regs: Add C10 registers bits Add C10 register bits to be used for computing HDMI PLLs with algorithm. v2: Add bspec reference. (Suraj) v3: Use REG_BIT8 like other reg bits/masks. (Jani) Bspec: 74166 Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Acked-by: Jani Nikula Tested-by: Khaled Almahallawy Link: https://patchwork.freedesktop.org/patch/msgid/20250122162850.1861410-1-ankit.k.nautiyal@intel.com --- .../gpu/drm/i915/display/intel_cx0_phy_regs.h | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h index a47fd1aef9f0f..5794ece42e921 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h @@ -214,10 +214,34 @@ /* C10 Vendor Registers */ #define PHY_C10_VDR_PLL(idx) (0xC00 + (idx)) +#define C10_PLL0_SSC_EN REG_BIT8(0) +#define C10_PLL0_DIVCLK_EN REG_BIT8(1) +#define C10_PLL0_DIV5CLK_EN REG_BIT8(2) +#define C10_PLL0_WORDDIV2_EN REG_BIT8(3) #define C10_PLL0_FRACEN REG_BIT8(4) +#define C10_PLL0_PMIX_EN REG_BIT8(5) +#define C10_PLL0_ANA_FREQ_VCO_MASK REG_GENMASK8(7, 6) +#define C10_PLL1_DIV_MULTIPLIER_MASK REG_GENMASK8(7, 0) +#define C10_PLL2_MULTIPLIERL_MASK REG_GENMASK8(7, 0) #define C10_PLL3_MULTIPLIERH_MASK REG_GENMASK8(3, 0) +#define C10_PLL8_SSC_UP_SPREAD REG_BIT8(5) +#define C10_PLL9_FRACN_DENL_MASK REG_GENMASK8(7, 0) +#define C10_PLL10_FRACN_DENH_MASK REG_GENMASK8(7, 0) +#define C10_PLL11_FRACN_QUOT_L_MASK REG_GENMASK8(7, 0) +#define C10_PLL12_FRACN_QUOT_H_MASK REG_GENMASK8(7, 0) +#define C10_PLL13_FRACN_REM_L_MASK REG_GENMASK8(7, 0) +#define C10_PLL14_FRACN_REM_H_MASK REG_GENMASK8(7, 0) #define C10_PLL15_TXCLKDIV_MASK REG_GENMASK8(2, 0) #define C10_PLL15_HDMIDIV_MASK REG_GENMASK8(5, 3) +#define C10_PLL15_PIXELCLKDIV_MASK REG_GENMASK8(7, 6) +#define C10_PLL16_ANA_CPINT REG_GENMASK8(6, 0) +#define C10_PLL16_ANA_CPINTGS_L REG_BIT8(7) +#define C10_PLL17_ANA_CPINTGS_H_MASK REG_GENMASK8(5, 0) +#define C10_PLL17_ANA_CPPROP_L_MASK REG_GENMASK8(7, 6) +#define C10_PLL18_ANA_CPPROP_H_MASK REG_GENMASK8(4, 0) +#define C10_PLL18_ANA_CPPROPGS_L_MASK REG_GENMASK8(7, 5) +#define C10_PLL19_ANA_CPPROPGS_H_MASK REG_GENMASK8(3, 0) +#define C10_PLL19_ANA_V2I_MASK REG_GENMASK8(5, 4) #define PHY_C10_VDR_CMN(idx) (0xC20 + (idx)) #define C10_CMN0_REF_RANGE REG_FIELD_PREP(REG_GENMASK(4, 0), 1) From 82ecaae2360776dcd0b9abf9ae6b947c28025931 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 20 Jan 2025 09:51:20 +0530 Subject: [PATCH 087/284] drm/i915/intel_snps_hdmi_pll: Compute C10 HDMI PLLs with algorithm Add support for computing C10 HDMI PLLS using the HDMI PLL algorithm. v2: Fix styling issues. (Jani) v3: Rename function to align with filename. (Jani) v4: Add Bspec reference. (Suraj) Bspec: 74166 Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Acked-by: Jani Nikula Tested-by: Khaled Almahallawy Link: https://patchwork.freedesktop.org/patch/msgid/20250120042122.1029481-5-ankit.k.nautiyal@intel.com --- .../drm/i915/display/intel_snps_hdmi_pll.c | 76 +++++++++++++++++++ .../drm/i915/display/intel_snps_hdmi_pll.h | 2 + 2 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c index 0e52578ef181a..c6321dafef4f3 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c +++ b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c @@ -5,6 +5,7 @@ #include +#include "intel_cx0_phy_regs.h" #include "intel_display_types.h" #include "intel_snps_phy.h" #include "intel_snps_phy_regs.h" @@ -286,3 +287,78 @@ void intel_snps_hdmi_pll_compute_mpllb(struct intel_mpllb_state *pll_state, u64 pll_state->mpllb_sscen = REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, pll_params.ssc_up_spread); } + +void intel_snps_hdmi_pll_compute_c10pll(struct intel_c10pll_state *pll_state, u64 pixel_clock) +{ + /* x axis frequencies. One curve in each array per v2i point */ + static const u64 c10_curve_freq_hz[2][8] = { + { 2500000000ULL, 3000000000ULL, 3000000000ULL, 3500000000ULL, 3500000000ULL, + 4000000000ULL, 4000000000ULL, 5000000000ULL }, + { 4000000000ULL, 4600000000ULL, 4601000000ULL, 5400000000ULL, 5401000000ULL, + 6600000000ULL, 6601000000ULL, 8001000000ULL } + }; + + /* y axis heights multiplied with 1000000000 */ + static const u64 c10_curve_0[2][8] = { + { 41174500, 48605500, 42973700, 49433100, 42408600, 47681900, 40297400, 49131400 }, + { 82056800, 94420700, 82323400, 96370600, 81273300, 98630100, 81728700, 99105700} + }; + + static const u64 c10_curve_1[2][8] = { + { 73300000000000ULL, 66000000000000ULL, 83100000000000ULL, 75300000000000ULL, + 99700000000000ULL, 92300000000000ULL, 125000000000000ULL, 110000000000000ULL }, + { 53700000000000ULL, 47700000000000ULL, 62200000000000ULL, 54400000000000ULL, + 75100000000000ULL, 63400000000000ULL, 90600000000000ULL, 76300000000000ULL } + }; + + /* Multiplied with 1000000000000 */ + static const u64 c10_curve_2[2][8] = { + { 2415790000ULL, 3136460000ULL, 2581990000ULL, 3222670000ULL, 2529330000ULL, + 3042020000ULL, 2336970000ULL, 3191460000ULL}, + { 4808390000ULL, 5994250000ULL, 4832730000ULL, 6193730000ULL, 4737700000ULL, + 6428750000ULL, 4779200000ULL, 6479340000ULL } + }; + + struct pll_output_params pll_params; + u32 refclk = 38400000; + u32 prescaler_divider = 0; + u32 ref_range = 1; + u32 ana_cp_int_gs = 30; + u32 ana_cp_prop_gs = 28; + + compute_hdmi_tmds_pll(pixel_clock, refclk, ref_range, + ana_cp_int_gs, ana_cp_prop_gs, + c10_curve_freq_hz, c10_curve_0, + c10_curve_1, c10_curve_2, prescaler_divider, + &pll_params); + + pll_state->tx = 0x10; + pll_state->cmn = 0x1; + pll_state->pll[0] = REG_FIELD_PREP(C10_PLL0_DIV5CLK_EN, pll_params.mpll_div5_en) | + REG_FIELD_PREP(C10_PLL0_FRACEN, pll_params.fracn_en) | + REG_FIELD_PREP(C10_PLL0_PMIX_EN, pll_params.pmix_en) | + REG_FIELD_PREP(C10_PLL0_ANA_FREQ_VCO_MASK, pll_params.ana_freq_vco); + pll_state->pll[2] = REG_FIELD_PREP(C10_PLL2_MULTIPLIERL_MASK, pll_params.multiplier); + pll_state->pll[3] = REG_FIELD_PREP(C10_PLL3_MULTIPLIERH_MASK, pll_params.multiplier >> 8); + pll_state->pll[8] = REG_FIELD_PREP(C10_PLL8_SSC_UP_SPREAD, pll_params.ssc_up_spread); + pll_state->pll[9] = REG_FIELD_PREP(C10_PLL9_FRACN_DENL_MASK, pll_params.fracn_den); + pll_state->pll[10] = REG_FIELD_PREP(C10_PLL10_FRACN_DENH_MASK, pll_params.fracn_den >> 8); + pll_state->pll[11] = REG_FIELD_PREP(C10_PLL11_FRACN_QUOT_L_MASK, pll_params.fracn_quot); + pll_state->pll[12] = REG_FIELD_PREP(C10_PLL12_FRACN_QUOT_H_MASK, + pll_params.fracn_quot >> 8); + + pll_state->pll[13] = REG_FIELD_PREP(C10_PLL13_FRACN_REM_L_MASK, pll_params.fracn_rem); + pll_state->pll[14] = REG_FIELD_PREP(C10_PLL14_FRACN_REM_H_MASK, pll_params.fracn_rem >> 8); + pll_state->pll[15] = REG_FIELD_PREP(C10_PLL15_TXCLKDIV_MASK, pll_params.tx_clk_div) | + REG_FIELD_PREP(C10_PLL15_HDMIDIV_MASK, pll_params.hdmi_div); + pll_state->pll[16] = REG_FIELD_PREP(C10_PLL16_ANA_CPINT, pll_params.ana_cp_int) | + REG_FIELD_PREP(C10_PLL16_ANA_CPINTGS_L, ana_cp_int_gs); + pll_state->pll[17] = REG_FIELD_PREP(C10_PLL17_ANA_CPINTGS_H_MASK, ana_cp_int_gs >> 1) | + REG_FIELD_PREP(C10_PLL17_ANA_CPPROP_L_MASK, pll_params.ana_cp_prop); + pll_state->pll[18] = + REG_FIELD_PREP(C10_PLL18_ANA_CPPROP_H_MASK, pll_params.ana_cp_prop >> 2) | + REG_FIELD_PREP(C10_PLL18_ANA_CPPROPGS_L_MASK, ana_cp_prop_gs); + + pll_state->pll[19] = REG_FIELD_PREP(C10_PLL19_ANA_CPPROPGS_H_MASK, ana_cp_prop_gs >> 3) | + REG_FIELD_PREP(C10_PLL19_ANA_V2I_MASK, pll_params.mpll_ana_v2i); +} diff --git a/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.h b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.h index 70b7023c11356..aac70c4bb0f8f 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.h +++ b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.h @@ -8,8 +8,10 @@ #include +struct intel_c10pll_state; struct intel_mpllb_state; void intel_snps_hdmi_pll_compute_mpllb(struct intel_mpllb_state *pll_state, u64 pixel_clock); +void intel_snps_hdmi_pll_compute_c10pll(struct intel_c10pll_state *pll_state, u64 pixel_clock); #endif /* __INTEL_SNPS_HDMI_PLL_H__ */ From 1efd5384277eb71fce20922579061cd3acdb07cf Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 20 Jan 2025 09:51:21 +0530 Subject: [PATCH 088/284] drm/i915/cx0_phy: Use HDMI PLL algorithm for C10 PHY Try HDMI PLL alogorithm for C10 PHY, if there are no pre-computed tables. Also get rid of the helpers to get rate for HDMI for C10/20 PHY, as we no longer depend only on pre-computed tables. Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Acked-by: Jani Nikula Tested-by: Khaled Almahallawy Link: https://patchwork.freedesktop.org/patch/msgid/20250120042122.1029481-6-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 49 +++++--------------- drivers/gpu/drm/i915/display/intel_cx0_phy.h | 1 - drivers/gpu/drm/i915/display/intel_hdmi.c | 10 ---- 3 files changed, 11 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 857262fcbac9f..39c98549ac4ea 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -18,6 +18,7 @@ #include "intel_hdmi.h" #include "intel_panel.h" #include "intel_psr.h" +#include "intel_snps_hdmi_pll.h" #include "intel_tc.h" #define MB_WRITE_COMMITTED true @@ -2003,19 +2004,6 @@ static const struct intel_c20pll_state * const mtl_c20_hdmi_tables[] = { NULL, }; -static int intel_c10_phy_check_hdmi_link_rate(int clock) -{ - const struct intel_c10pll_state * const *tables = mtl_c10_hdmi_tables; - int i; - - for (i = 0; tables[i]; i++) { - if (clock == tables[i]->clock) - return MODE_OK; - } - - return MODE_CLOCK_RANGE; -} - static const struct intel_c10pll_state * const * intel_c10pll_tables_get(struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) @@ -2077,6 +2065,16 @@ static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state, } } + /* For HDMI PLLs try SNPS PHY algorithm, if there are no precomputed tables */ + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { + intel_snps_hdmi_pll_compute_c10pll(&crtc_state->dpll_hw_state.cx0pll.c10, + crtc_state->port_clock); + intel_c10pll_update_pll(crtc_state, encoder); + crtc_state->dpll_hw_state.cx0pll.use_c10 = true; + + return 0; + } + return -EINVAL; } @@ -2281,31 +2279,6 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state) return 0; } -static int intel_c20_phy_check_hdmi_link_rate(int clock) -{ - const struct intel_c20pll_state * const *tables = mtl_c20_hdmi_tables; - int i; - - for (i = 0; tables[i]; i++) { - if (clock == tables[i]->clock) - return MODE_OK; - } - - if (clock >= 25175 && clock <= 594000) - return MODE_OK; - - return MODE_CLOCK_RANGE; -} - -int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock) -{ - struct intel_digital_port *dig_port = hdmi_to_dig_port(hdmi); - - if (intel_encoder_is_c10phy(&dig_port->base)) - return intel_c10_phy_check_hdmi_link_rate(clock); - return intel_c20_phy_check_hdmi_link_rate(clock); -} - static const struct intel_c20pll_state * const * intel_c20_pll_tables_get(struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h index 7111688826849..573fa7d3e88fe 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h @@ -41,7 +41,6 @@ bool intel_cx0pll_compare_hw_state(const struct intel_cx0pll_state *a, const struct intel_cx0pll_state *b); void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); -int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock); int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder); #endif /* __INTEL_CX0_PHY_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index a0133713725be..95584b61cf088 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1909,16 +1909,6 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, if (intel_encoder_is_tc(encoder) && clock > 500000 && clock < 532800) return MODE_CLOCK_RANGE; - /* - * SNPS PHYs' MPLLB table-based programming can only handle a fixed - * set of link rates. - * - * FIXME: We will hopefully get an algorithmic way of programming - * the MPLLB for HDMI in the future. - */ - if (DISPLAY_VER(display) >= 14) - return intel_cx0_phy_check_hdmi_link_rate(hdmi, clock); - return MODE_OK; } From c156ef573efe4230ef3dc1ff2ec0038fe0eb217f Mon Sep 17 00:00:00 2001 From: Nitin Gote Date: Mon, 20 Jan 2025 13:45:10 +0530 Subject: [PATCH 089/284] drm/i915/gt: fix typos in i915/gt files. Fix all typos in files under drm/i915/gt reported by codespell tool. v2: Fix grammar mistake in comment. v3: Correct typo in commit log. Signed-off-by: Nitin Gote Reviewed-by: Krzysztof Niemiec Link: https://patchwork.freedesktop.org/patch/msgid/20250120081517.3237326-2-nitin.r.gote@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/gen2_engine_cs.c | 2 +- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 8 ++++---- drivers/gpu/drm/i915/gt/intel_engine_types.h | 4 ++-- drivers/gpu/drm/i915/gt/intel_gt_irq.c | 2 +- drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 2 +- drivers/gpu/drm/i915/gt/intel_migrate.c | 4 ++-- drivers/gpu/drm/i915/gt/intel_mocs.c | 2 +- drivers/gpu/drm/i915/gt/intel_reset.c | 2 +- drivers/gpu/drm/i915/gt/intel_ring_submission.c | 2 +- drivers/gpu/drm/i915/gt/intel_rps_types.h | 4 ++-- drivers/gpu/drm/i915/gt/intel_sa_media.c | 2 +- drivers/gpu/drm/i915/gt/intel_sseu.c | 2 +- drivers/gpu/drm/i915/gt/intel_workarounds.c | 2 +- drivers/gpu/drm/i915/gt/selftest_execlists.c | 2 +- drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 2 +- drivers/gpu/drm/i915/gt/selftest_lrc.c | 2 +- drivers/gpu/drm/i915/gt/selftest_rc6.c | 2 +- drivers/gpu/drm/i915/gt/selftest_rps.c | 2 +- drivers/gpu/drm/i915/gt/shaders/README | 6 +++--- drivers/gpu/drm/i915/gt/shaders/clear_kernel/hsw.asm | 2 +- drivers/gpu/drm/i915/gt/shaders/clear_kernel/ivb.asm | 2 +- drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h | 4 ++-- drivers/gpu/drm/i915/gt/uc/intel_guc.c | 2 +- drivers/gpu/drm/i915/gt/uc/intel_guc.h | 2 +- drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 2 +- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 4 ++-- drivers/gpu/drm/i915/gt/uc/intel_uc.c | 2 +- drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c | 2 +- 28 files changed, 38 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/gen2_engine_cs.c b/drivers/gpu/drm/i915/gt/gen2_engine_cs.c index 4904d0f4162c6..8116fd5987e2b 100644 --- a/drivers/gpu/drm/i915/gt/gen2_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/gen2_engine_cs.c @@ -179,7 +179,7 @@ u32 *gen5_emit_breadcrumb(struct i915_request *rq, u32 *cs) return __gen2_emit_breadcrumb(rq, cs, 8, 8); } -/* Just userspace ABI convention to limit the wa batch bo to a resonable size */ +/* Just userspace ABI convention to limit the wa batch bo to a reasonable size */ #define I830_BATCH_LIMIT SZ_256K #define I830_TLB_ENTRIES (2) #define I830_WA_SIZE max(I830_TLB_ENTRIES * SZ_4K, I830_BATCH_LIMIT) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 4d30a86016f24..ec136eb12d48b 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -308,7 +308,7 @@ u32 intel_engine_context_size(struct intel_gt *gt, u8 class) /* * There is a discrepancy here between the size reported * by the register and the size of the context layout - * in the docs. Both are described as authorative! + * in the docs. Both are described as authoritative! * * The discrepancy is on the order of a few cachelines, * but the total is under one page (4k), which is our @@ -845,7 +845,7 @@ static void engine_mask_apply_compute_fuses(struct intel_gt *gt) * Note that we have a catch-22 situation where we need to be able to access * the blitter forcewake domain to read the engine fuses, but at the same time * we need to know which engines are available on the system to know which - * forcewake domains are present. We solve this by intializing the forcewake + * forcewake domains are present. We solve this by initializing the forcewake * domains based on the full engine mask in the platform capabilities before * calling this function and pruning the domains for fused-off engines * afterwards. @@ -1411,7 +1411,7 @@ create_ggtt_bind_context(struct intel_engine_cs *engine) /* * MI_UPDATE_GTT can insert up to 511 PTE entries and there could be multiple - * bind requets at a time so get a bigger ring. + * bind requests at a time so get a bigger ring. */ return intel_engine_create_pinned_context(engine, engine->gt->vm, SZ_512K, I915_GEM_HWS_GGTT_BIND_ADDR, @@ -1533,7 +1533,7 @@ int intel_engines_init(struct intel_gt *gt) /** * intel_engine_cleanup_common - cleans up the engine state created by - * the common initiailizers. + * the common initializers. * @engine: Engine to cleanup. * * This cleans up everything created by the common helpers. diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h index fe1f85e5dda33..155b6255a63ea 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h @@ -237,7 +237,7 @@ struct intel_engine_execlists { */ struct i915_request * const *active; /** - * @inflight: the set of contexts submitted and acknowleged by HW + * @inflight: the set of contexts submitted and acknowledged by HW * * The set of inflight contexts is managed by reading CS events * from the HW. On a context-switch event (not preemption), we @@ -260,7 +260,7 @@ struct intel_engine_execlists { unsigned int port_mask; /** - * @virtual: Queue of requets on a virtual engine, sorted by priority. + * @virtual: Queue of requests on a virtual engine, sorted by priority. * Each RB entry is a struct i915_priolist containing a list of requests * of the same priority. */ diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c index 1240d44eeb858..75e802e10be24 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c @@ -480,7 +480,7 @@ void gen8_gt_irq_postinstall(struct intel_gt *gt) gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(1), ~gt_interrupts[1], gt_interrupts[1]); /* * RPS interrupts will get enabled/disabled on demand when RPS itself - * is enabled/disabled. Same wil be the case for GuC interrupts. + * is enabled/disabled. Same will be the case for GuC interrupts. */ gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(2), gt->pm_imr, gt->pm_ier); gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(3), ~gt_interrupts[3], gt_interrupts[3]); diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c index b8912bd6c08ed..aab20d6466f5e 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c @@ -239,7 +239,7 @@ static u32 rw_with_mcr_steering_fw(struct intel_gt *gt, * to remain in multicast mode for reads. There's no real * downside to this, so we'll just go ahead and do so on all * platforms; we'll only clear the multicast bit from the mask - * when exlicitly doing a write operation. + * when explicitly doing a write operation. */ if (rw_flag == FW_REG_WRITE) mcr_mask |= GEN11_MCR_MULTICAST; diff --git a/drivers/gpu/drm/i915/gt/intel_migrate.c b/drivers/gpu/drm/i915/gt/intel_migrate.c index 6f7af40771353..aff5aca591e6e 100644 --- a/drivers/gpu/drm/i915/gt/intel_migrate.c +++ b/drivers/gpu/drm/i915/gt/intel_migrate.c @@ -304,7 +304,7 @@ struct intel_context *intel_migrate_create_context(struct intel_migrate *m) struct intel_context *ce; /* - * We randomly distribute contexts across the engines upon constrction, + * We randomly distribute contexts across the engines upon construction, * as they all share the same pinned vm, and so in order to allow * multiple blits to run in parallel, we must construct each blit * to use a different range of the vm for its GTT. This has to be @@ -646,7 +646,7 @@ calculate_chunk_sz(struct drm_i915_private *i915, bool src_is_lmem, * When CHUNK_SZ is passed all the pages upto CHUNK_SZ * will be taken for the blt. in Flat-ccs supported * platform Smem obj will have more pages than required - * for main meory hence limit it to the required size + * for main memory hence limit it to the required size * for main memory */ return min_t(u64, bytes_to_cpy, CHUNK_SZ); diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c index d791d63d49b49..cf41d325712eb 100644 --- a/drivers/gpu/drm/i915/gt/intel_mocs.c +++ b/drivers/gpu/drm/i915/gt/intel_mocs.c @@ -675,7 +675,7 @@ void intel_mocs_init(struct intel_gt *gt) __init_mocs_table(gt->uncore, &table, global_mocs_offset()); /* - * Initialize the L3CC table as part of mocs initalization to make + * Initialize the L3CC table as part of mocs initialization to make * sure the LNCFCMOCSx registers are programmed for the subsequent * memory transactions including guc transactions */ diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index c2fe3fc78e76e..33b55c581552c 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -1098,7 +1098,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt) dma_fence_default_wait(fence, false, MAX_SCHEDULE_TIMEOUT); dma_fence_put(fence); - /* Restart iteration after droping lock */ + /* Restart iteration after dropping lock */ spin_lock(&timelines->lock); tl = list_entry(&timelines->active_list, typeof(*tl), link); } diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c index 32f3b52a183af..f0b75986afb96 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c @@ -236,7 +236,7 @@ static int xcs_resume(struct intel_engine_cs *engine) /* * In case of resets fails because engine resumes from * incorrect RING_HEAD and then GPU may be then fed - * to invalid instrcutions, which may lead to unrecoverable + * to invalid instructions, which may lead to unrecoverable * hang. So at first write doesn't succeed then try again. */ ENGINE_WRITE_FW(engine, RING_HEAD, ring->head); diff --git a/drivers/gpu/drm/i915/gt/intel_rps_types.h b/drivers/gpu/drm/i915/gt/intel_rps_types.h index 6507fa3f6d1e8..5135b90a2a40c 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps_types.h +++ b/drivers/gpu/drm/i915/gt/intel_rps_types.h @@ -40,7 +40,7 @@ enum { /** * struct intel_rps_freq_caps - rps freq capabilities * @rp0_freq: non-overclocked max frequency - * @rp1_freq: "less than" RP0 power/freqency + * @rp1_freq: "less than" RP0 power/frequency * @min_freq: aka RPn, minimum frequency * * Freq caps exposed by HW, values are in "hw units" and intel_gpu_freq() @@ -90,7 +90,7 @@ struct intel_rps { u8 boost_freq; /* Frequency to request when wait boosting */ u8 idle_freq; /* Frequency to request when we are idle */ u8 efficient_freq; /* AKA RPe. Pre-determined balanced frequency */ - u8 rp1_freq; /* "less than" RP0 power/freqency */ + u8 rp1_freq; /* "less than" RP0 power/frequency */ u8 rp0_freq; /* Non-overclocked max frequency. */ u16 gpll_ref_freq; /* vlv/chv GPLL reference frequency */ diff --git a/drivers/gpu/drm/i915/gt/intel_sa_media.c b/drivers/gpu/drm/i915/gt/intel_sa_media.c index 8c1dbcbcbc4f5..2945526d52d12 100644 --- a/drivers/gpu/drm/i915/gt/intel_sa_media.c +++ b/drivers/gpu/drm/i915/gt/intel_sa_media.c @@ -27,7 +27,7 @@ int intel_sa_mediagt_setup(struct intel_gt *gt, phys_addr_t phys_addr, /* * Standalone media shares the general MMIO space with the primary - * GT. We'll re-use the primary GT's mapping. + * GT. We'll reuse the primary GT's mapping. */ uncore->regs = intel_uncore_regs(&i915->uncore); if (drm_WARN_ON(&i915->drm, uncore->regs == NULL)) diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.c b/drivers/gpu/drm/i915/gt/intel_sseu.c index c8fadf58d8361..e4538dd726c8b 100644 --- a/drivers/gpu/drm/i915/gt/intel_sseu.c +++ b/drivers/gpu/drm/i915/gt/intel_sseu.c @@ -687,7 +687,7 @@ u32 intel_sseu_make_rpcs(struct intel_gt *gt, * According to documentation software must consider the configuration * as 2x4x8 and hardware will translate this to 1x8x8. * - * Furthemore, even though SScount is three bits, maximum documented + * Furthermore, even though SScount is three bits, maximum documented * value for it is four. From this some rules/restrictions follow: * * 1. diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index 570c918781899..3ea9b06de1bed 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -1318,7 +1318,7 @@ xehp_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal) * We'll do our default/implicit steering based on GSLICE (in the * sliceid field) and DSS (in the subsliceid field). If we can * find overlap between the valid MSLICE and/or LNCF values with - * a suitable GSLICE, then we can just re-use the default value and + * a suitable GSLICE, then we can just reuse the default value and * skip and explicit steering at runtime. * * We only need to look for overlap between GSLICE/MSLICE/LNCF to find diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c index 222ca7c449519..07bc0bbee20fd 100644 --- a/drivers/gpu/drm/i915/gt/selftest_execlists.c +++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c @@ -53,7 +53,7 @@ static int wait_for_submit(struct intel_engine_cs *engine, if (i915_request_completed(rq)) /* that was quick! */ return 0; - /* Wait until the HW has acknowleged the submission (or err) */ + /* Wait until the HW has acknowledged the submission (or err) */ intel_engine_flush_submission(engine); if (!READ_ONCE(engine->execlists.pending[0]) && is_active(rq)) return 0; diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c index 9ce8ff1c04fe5..d99061735c58a 100644 --- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c +++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c @@ -548,7 +548,7 @@ static int igt_reset_fail_engine(void *arg) struct intel_engine_cs *engine; enum intel_engine_id id; - /* Check that we can recover from engine-reset failues */ + /* Check that we can recover from engine-reset failures */ if (!intel_has_reset_engine(gt)) return 0; diff --git a/drivers/gpu/drm/i915/gt/selftest_lrc.c b/drivers/gpu/drm/i915/gt/selftest_lrc.c index e17b8777d21dc..22e750108c5f9 100644 --- a/drivers/gpu/drm/i915/gt/selftest_lrc.c +++ b/drivers/gpu/drm/i915/gt/selftest_lrc.c @@ -63,7 +63,7 @@ static int wait_for_submit(struct intel_engine_cs *engine, if (i915_request_completed(rq)) /* that was quick! */ return 0; - /* Wait until the HW has acknowleged the submission (or err) */ + /* Wait until the HW has acknowledged the submission (or err) */ intel_engine_flush_submission(engine); if (!READ_ONCE(engine->execlists.pending[0]) && is_active(rq)) return 0; diff --git a/drivers/gpu/drm/i915/gt/selftest_rc6.c b/drivers/gpu/drm/i915/gt/selftest_rc6.c index 1aa1446c8fb09..b272a7d44599f 100644 --- a/drivers/gpu/drm/i915/gt/selftest_rc6.c +++ b/drivers/gpu/drm/i915/gt/selftest_rc6.c @@ -211,7 +211,7 @@ int live_rc6_ctx_wa(void *arg) i915_reset_engine_count(error, engine); const u32 *res; - /* Use a sacrifical context */ + /* Use a sacrificial context */ ce = intel_context_create(engine); if (IS_ERR(ce)) { err = PTR_ERR(ce); diff --git a/drivers/gpu/drm/i915/gt/selftest_rps.c b/drivers/gpu/drm/i915/gt/selftest_rps.c index c207a4fb03bf4..78c03e6c0861b 100644 --- a/drivers/gpu/drm/i915/gt/selftest_rps.c +++ b/drivers/gpu/drm/i915/gt/selftest_rps.c @@ -22,7 +22,7 @@ #include "selftests/igt_spinner.h" #include "selftests/librapl.h" -/* Try to isolate the impact of cstates from determing frequency response */ +/* Try to isolate the impact of cstates from determining frequency response */ #define CPU_LATENCY 0 /* -1 to disable pm_qos, 0 to disable cstates */ static void dummy_rps_work(struct work_struct *wrk) diff --git a/drivers/gpu/drm/i915/gt/shaders/README b/drivers/gpu/drm/i915/gt/shaders/README index e7e96d7073c7e..22f8dabed4349 100644 --- a/drivers/gpu/drm/i915/gt/shaders/README +++ b/drivers/gpu/drm/i915/gt/shaders/README @@ -10,7 +10,7 @@ i915/gt/shaders/clear_kernel directory. The generated .c files should never be modified directly. Instead, any modification needs to be done on the on their respective ASM files and build instructions below -needes to be followed. +needs to be followed. Building ======== @@ -24,7 +24,7 @@ on building. Please make sure your Mesa tool is compiled with "-Dtools=intel" and "-Ddri-drivers=i965", and run this script from IGT source root directory" -The instructions bellow assume: +The instructions below assume: * IGT gpu tools source code is located on your home directory (~) as ~/igt * Mesa source code is located on your home directory (~) as ~/mesa and built under the ~/mesa/build directory @@ -43,4 +43,4 @@ igt $ ./scripts/generate_clear_kernel.sh -g ivb \ ~/igt/lib/i915/shaders/clear_kernel/hsw.asm ~ $ cd ~/igt igt $ ./scripts/generate_clear_kernel.sh -g hsw \ - -m ~/mesa/build/src/intel/tools/i965_asm \ No newline at end of file + -m ~/mesa/build/src/intel/tools/i965_asm diff --git a/drivers/gpu/drm/i915/gt/shaders/clear_kernel/hsw.asm b/drivers/gpu/drm/i915/gt/shaders/clear_kernel/hsw.asm index 5fdf384bb6213..6c0c89daf96cd 100644 --- a/drivers/gpu/drm/i915/gt/shaders/clear_kernel/hsw.asm +++ b/drivers/gpu/drm/i915/gt/shaders/clear_kernel/hsw.asm @@ -24,7 +24,7 @@ mov(1) f0.1<1>UW g1.2<0,1,0>UW { align1 1N }; * DW 1.4 - Rsvd (intended for context ID) * DW 1.5 - [31:16]:SliceCount, [15:0]:SubSlicePerSliceCount * DW 1.6 - Rsvd MBZ (intended for Enable Wait on Total Thread Count) - * DW 1.7 - Rsvd MBZ (inteded for Total Thread Count) + * DW 1.7 - Rsvd MBZ (intended for Total Thread Count) * * Binding Table * diff --git a/drivers/gpu/drm/i915/gt/shaders/clear_kernel/ivb.asm b/drivers/gpu/drm/i915/gt/shaders/clear_kernel/ivb.asm index 97c7ac9e38549..27c28e63d6cc3 100644 --- a/drivers/gpu/drm/i915/gt/shaders/clear_kernel/ivb.asm +++ b/drivers/gpu/drm/i915/gt/shaders/clear_kernel/ivb.asm @@ -24,7 +24,7 @@ mov(1) f0.1<1>UW g1.2<0,1,0>UW { align1 1N }; * DW 1.4 - Rsvd (intended for context ID) * DW 1.5 - [31:16]:SliceCount, [15:0]:SubSlicePerSliceCount * DW 1.6 - Rsvd MBZ (intended for Enable Wait on Total Thread Count) - * DW 1.7 - Rsvd MBZ (inteded for Total Thread Count) + * DW 1.7 - Rsvd MBZ (intended for Total Thread Count) * * Binding Table * diff --git a/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h b/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h index 1fc0c17b12309..803c0379d97d7 100644 --- a/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h +++ b/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h @@ -81,7 +81,7 @@ struct guc_debug_capture_list { * * intel_guc_capture module uses these structures to maintain static * tables (per unique platform) that consists of lists of registers - * (offsets, names, flags,...) that are used at the ADS regisration + * (offsets, names, flags,...) that are used at the ADS registration * time as well as during runtime processing and reporting of error- * capture states generated by GuC just prior to engine reset events. */ @@ -200,7 +200,7 @@ struct intel_guc_state_capture { * dynamically allocate new nodes when receiving the G2H notification * because the event handlers for all G2H event-processing is called * by the ct processing worker queue and when that queue is being - * processed, there is no absoluate guarantee that we are not in the + * processed, there is no absolute guarantee that we are not in the * midst of a GT reset operation (which doesn't allow allocations). */ struct list_head cachelist; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c index 5949ff0b0161f..9df80c325fc14 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c @@ -690,7 +690,7 @@ int intel_guc_suspend(struct intel_guc *guc) * H2G MMIO command completes. * * Don't abort on a failure code from the GuC. Keep going and do the - * clean up in santize() and re-initialisation on resume and hopefully + * clean up in sanitize() and re-initialisation on resume and hopefully * the error here won't be problematic. */ ret = intel_guc_send_mmio(guc, action, ARRAY_SIZE(action), NULL, 0); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 57b9031327767..053780f562c1a 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -295,7 +295,7 @@ struct intel_guc { */ struct work_struct dead_guc_worker; /** - * @last_dead_guc_jiffies: timestamp of previous 'dead guc' occurrance + * @last_dead_guc_jiffies: timestamp of previous 'dead guc' occurrence * used to prevent a fundamentally broken system from continuously * reloading the GuC. */ diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h index 4ce6e2332a63f..eded00f0c7e16 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h @@ -408,7 +408,7 @@ enum guc_capture_type { GUC_CAPTURE_LIST_TYPE_MAX, }; -/* Class indecies for capture_class and capture_instance arrays */ +/* Class indices for capture_class and capture_instance arrays */ enum { GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE = 0, GUC_CAPTURE_LIST_CLASS_VIDEO = 1, diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 12f1ba7ca9c19..3b1333a24a899 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -1223,7 +1223,7 @@ __extend_last_switch(struct intel_guc *guc, u64 *prev_start, u32 new_start) * determine validity of these values. Instead we read the values multiple times * until they are consistent. In test runs, 3 attempts results in consistent * values. The upper bound is set to 6 attempts and may need to be tuned as per - * any new occurences. + * any new occurrences. */ static void __get_engine_usage_record(struct intel_engine_cs *engine, u32 *last_in, u32 *id, u32 *total) @@ -2995,7 +2995,7 @@ static int __guc_context_pin(struct intel_context *ce, /* * GuC context gets pinned in guc_request_alloc. See that function for - * explaination of why. + * explanation of why. */ return lrc_pin(ce, engine, vaddr); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c index 5b8080ec5315b..90ba1b0b4c9d2 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c @@ -512,7 +512,7 @@ static int __uc_init_hw(struct intel_uc *uc) ERR_PTR(ret), attempts); } - /* Did we succeded or run out of retries? */ + /* Did we succeed or run out of retries? */ if (ret) goto err_log_capture; diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c index 26fdc392fce6c..83801c9924882 100644 --- a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c +++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c @@ -64,7 +64,7 @@ static int intel_hang_guc(void *arg) old_beat = engine->props.heartbeat_interval_ms; ret = intel_engine_set_heartbeat(engine, BEAT_INTERVAL); if (ret) { - gt_err(gt, "Failed to boost heatbeat interval: %pe\n", ERR_PTR(ret)); + gt_err(gt, "Failed to boost heartbeat interval: %pe\n", ERR_PTR(ret)); goto err; } From 61d9f028936b895d955e6d704055f5d64e6a8e0c Mon Sep 17 00:00:00 2001 From: Nitin Gote Date: Mon, 20 Jan 2025 13:45:11 +0530 Subject: [PATCH 090/284] drm/i915/gvt: fix typos in i915/gvt files Fix all typos in files under drm/i915/gvt reported by codespell tool. v2: Correct comment styling. Signed-off-by: Nitin Gote Reviewed-by: Krzysztof Niemiec Link: https://patchwork.freedesktop.org/patch/msgid/20250120081517.3237326-3-nitin.r.gote@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 15 ++++++++------- drivers/gpu/drm/i915/gvt/dmabuf.c | 2 +- drivers/gpu/drm/i915/gvt/edid.c | 2 +- drivers/gpu/drm/i915/gvt/gtt.c | 2 +- drivers/gpu/drm/i915/gvt/gvt.h | 8 +++++--- drivers/gpu/drm/i915/gvt/handlers.c | 6 +++--- drivers/gpu/drm/i915/gvt/kvmgt.c | 2 +- drivers/gpu/drm/i915/gvt/mmio_context.c | 6 +++--- drivers/gpu/drm/i915/gvt/scheduler.c | 11 ++++++----- drivers/gpu/drm/i915/gvt/vgpu.c | 6 +++--- 10 files changed, 32 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 6439c8e91a8d1..f25ee2953baf5 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -1906,7 +1906,7 @@ static int perform_bb_shadow(struct parser_exec_state *s) s->vgpu->gtt.ggtt_mm : s->workload->shadow_mm; unsigned long start_offset = 0; - /* get the start gm address of the batch buffer */ + /* Get the start gm address of the batch buffer */ gma = get_gma_bb_from_cmd(s, 1); if (gma == INTEL_GVT_INVALID_ADDR) return -EFAULT; @@ -1921,15 +1921,16 @@ static int perform_bb_shadow(struct parser_exec_state *s) bb->ppgtt = (s->buf_addr_type == GTT_BUFFER) ? false : true; - /* the start_offset stores the batch buffer's start gma's - * offset relative to page boundary. so for non-privileged batch + /* + * The start_offset stores the batch buffer's start gma's + * offset relative to page boundary. So for non-privileged batch * buffer, the shadowed gem object holds exactly the same page - * layout as original gem object. This is for the convience of + * layout as original gem object. This is for the convenience of * replacing the whole non-privilged batch buffer page to this - * shadowed one in PPGTT at the same gma address. (this replacing + * shadowed one in PPGTT at the same gma address. (This replacing * action is not implemented yet now, but may be necessary in * future). - * for prileged batch buffer, we just change start gma address to + * For prileged batch buffer, we just change start gma address to * that of shadowed page. */ if (bb->ppgtt) @@ -1976,7 +1977,7 @@ static int perform_bb_shadow(struct parser_exec_state *s) /* * ip_va saves the virtual address of the shadow batch buffer, while * ip_gma saves the graphics address of the original batch buffer. - * As the shadow batch buffer is just a copy from the originial one, + * As the shadow batch buffer is just a copy from the original one, * it should be right to use shadow batch buffer'va and original batch * buffer's gma in pair. After all, we don't want to pin the shadow * buffer here (too early). diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c index 9efc3ca0ce820..4f599af766b09 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.c +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c @@ -436,7 +436,7 @@ int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args) dmabuf_obj_get(dmabuf_obj); } ret = 0; - gvt_dbg_dpy("vgpu%d: re-use dmabuf_obj ref %d, id %d\n", + gvt_dbg_dpy("vgpu%d: reuse dmabuf_obj ref %d, id %d\n", vgpu->id, kref_read(&dmabuf_obj->kref), gfx_plane_info->dmabuf_id); mutex_unlock(&vgpu->dmabuf_lock); diff --git a/drivers/gpu/drm/i915/gvt/edid.c b/drivers/gpu/drm/i915/gvt/edid.c index 0a357ca42db1b..89147d33168c0 100644 --- a/drivers/gpu/drm/i915/gvt/edid.c +++ b/drivers/gpu/drm/i915/gvt/edid.c @@ -298,7 +298,7 @@ static int gmbus3_mmio_read(struct intel_vgpu *vgpu, unsigned int offset, int byte_count = byte_left; u32 reg_data = 0; - /* Data can only be recevied if previous settings correct */ + /* Data can only be received if previous settings correct */ if (vgpu_vreg_t(vgpu, PCH_GMBUS1) & GMBUS_SLAVE_READ) { if (byte_left <= 0) { memcpy(p_data, &vgpu_vreg(vgpu, offset), bytes); diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 464fb17e82ee7..2fa7ca19ba5d2 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1193,7 +1193,7 @@ static int ppgtt_populate_shadow_entry(struct intel_vgpu *vgpu, gvt_vdbg_mm("shadow 64K gtt entry\n"); /* * The layout of 64K page is special, the page size is - * controlled by uper PDE. To be simple, we always split + * controlled by upper PDE. To be simple, we always split * 64K page to smaller 4K pages in shadow PT. */ return split_64KB_gtt_entry(vgpu, spt, index, &se); diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 8580c6d057e79..01d890999f256 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -452,8 +452,10 @@ void intel_vgpu_free_resource(struct intel_vgpu *vgpu); void intel_vgpu_write_fence(struct intel_vgpu *vgpu, u32 fence, u64 value); -/* Macros for easily accessing vGPU virtual/shadow register. - Explicitly seperate use for typed MMIO reg or real offset.*/ +/* + * Macros for easily accessing vGPU virtual/shadow register. + * Explicitly separate use for typed MMIO reg or real offset. + */ #define vgpu_vreg_t(vgpu, reg) \ (*(u32 *)(vgpu->mmio.vreg + i915_mmio_reg_offset(reg))) #define vgpu_vreg(vgpu, offset) \ @@ -696,7 +698,7 @@ static inline void intel_gvt_mmio_set_cmd_write_patch( * @offset: register offset * * Returns: - * True if GPU commmand write to an MMIO should be patched + * True if GPU command write to an MMIO should be patched. */ static inline bool intel_gvt_mmio_is_cmd_write_patch( struct intel_gvt *gvt, unsigned int offset) diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index ee473b45d1e4a..4efee6797873a 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -689,11 +689,11 @@ static void vgpu_update_refresh_rate(struct intel_vgpu *vgpu) u32 new_rate = 0; u32 *old_rate = &(intel_vgpu_port(vgpu, vgpu->display.port_num)->vrefresh_k); - /* Calcuate pixel clock by (ls_clk * M / N) */ + /* Calculate pixel clock by (ls_clk * M / N) */ pixel_clk = div_u64(mul_u32_u32(link_m, dp_br), link_n); pixel_clk *= MSEC_PER_SEC; - /* Calcuate refresh rate by (pixel_clk / (h_total * v_total)) */ + /* Calculate refresh rate by (pixel_clk / (h_total * v_total)) */ new_rate = DIV64_U64_ROUND_CLOSEST(mul_u64_u32_shr(pixel_clk, MSEC_PER_SEC, 0), mul_u32_u32(htotal + 1, vtotal + 1)); if (*old_rate != new_rate) @@ -2001,7 +2001,7 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, * vGPU reset, it's set on D0->D3 on PCI config write, and cleared after * vGPU reset if in resuming. * In S0ix exit, the device power state also transite from D3 to D0 as - * S3 resume, but no vGPU reset (triggered by QEMU devic model). After + * S3 resume, but no vGPU reset (triggered by QEMU device model). After * S0ix exit, all engines continue to work. However the d3_entered * remains set which will break next vGPU reset logic (miss the expected * PPGTT invalidation). diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index b27ff77bfb501..69830a5c49d3f 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -142,7 +142,7 @@ static int gvt_pin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn, int ret; /* - * We pin the pages one-by-one to avoid allocating a big arrary + * We pin the pages one-by-one to avoid allocating a big array * on stack to hold pfns. */ for (npage = 0; npage < total_pages; npage++) { diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c index 273db14fd5fc6..2f72088433671 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_context.c +++ b/drivers/gpu/drm/i915/gvt/mmio_context.c @@ -53,7 +53,7 @@ struct engine_mmio { u32 value; }; -/* Raw offset is appened to each line for convenience. */ +/* Raw offset is append to each line for convenience. */ static struct engine_mmio gen8_engine_mmio_list[] __cacheline_aligned = { {RCS0, RING_MODE_GEN7(RENDER_RING_BASE), 0xffff, false}, /* 0x229c */ {RCS0, GEN9_CTX_PREEMPT_REG, 0x0, false}, /* 0x2248 */ @@ -576,8 +576,8 @@ void intel_gvt_switch_mmio(struct intel_vgpu *pre, /** * We are using raw mmio access wrapper to improve the - * performace for batch mmio read/write, so we need - * handle forcewake mannually. + * performance for batch mmio read/write, so we need + * handle forcewake manually. */ intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL); switch_mmio(pre, next, engine); diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 23f2cc397ec96..6e87c10bc4542 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -77,7 +77,7 @@ static void update_shadow_pdps(struct intel_vgpu_workload *workload) } /* - * when populating shadow ctx from guest, we should not overrride oa related + * When populating shadow ctx from guest, we should not override oa related * registers, so that they will not be overlapped by guest oa configs. Thus * made it possible to capture oa data from host for both host and guests. */ @@ -528,9 +528,10 @@ static int prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) int ret; list_for_each_entry(bb, &workload->shadow_bb, list) { - /* For privilge batch buffer and not wa_ctx, the bb_start_cmd_va + /* + * For privilege batch buffer and not wa_ctx, the bb_start_cmd_va * is only updated into ring_scan_buffer, not real ring address - * allocated in later copy_workload_to_ring_buffer. pls be noted + * allocated in later copy_workload_to_ring_buffer. Please be noted * shadow_ring_buffer_va is now pointed to real ring buffer va * in copy_workload_to_ring_buffer. */ @@ -546,7 +547,7 @@ static int prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) * here, rather than switch to shadow bb's gma * address, we directly use original batch buffer's * gma address, and send original bb to hardware - * directly + * directly. */ if (!bb->ppgtt) { i915_gem_ww_ctx_init(&ww, false); @@ -1774,7 +1775,7 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, } /** - * intel_vgpu_queue_workload - Qeue a vGPU workload + * intel_vgpu_queue_workload - Queue a vGPU workload * @workload: the workload to queue in */ void intel_vgpu_queue_workload(struct intel_vgpu_workload *workload) diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index 63c751ca41196..11260392234a8 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c @@ -78,7 +78,7 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu) * vGPU type name is defined as GVTg_Vx_y which contains the physical GPU * generation type (e.g V4 as BDW server, V5 as SKL server). * - * Depening on the physical SKU resource, we might see vGPU types like + * Depending on the physical SKU resource, we might see vGPU types like * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create different types of * vGPU on same physical GPU depending on available resource. Each vGPU * type will have a different number of avail_instance to indicate how @@ -417,7 +417,7 @@ int intel_gvt_create_vgpu(struct intel_vgpu *vgpu, * the whole vGPU to default state as when it is created. This vGPU function * is required both for functionary and security concerns.The ultimate goal * of vGPU FLR is that reuse a vGPU instance by virtual machines. When we - * assign a vGPU to a virtual machine we must isse such reset first. + * assign a vGPU to a virtual machine we must issue such reset first. * * Full GT Reset and Per-Engine GT Reset are soft reset flow for GPU engines * (Render, Blitter, Video, Video Enhancement). It is defined by GPU Spec. @@ -428,7 +428,7 @@ int intel_gvt_create_vgpu(struct intel_vgpu *vgpu, * * The parameter dev_level is to identify if we will do DMLR or GT reset. * The parameter engine_mask is to specific the engines that need to be - * resetted. If value ALL_ENGINES is given for engine_mask, it means + * reset. If value ALL_ENGINES is given for engine_mask, it means * the caller requests a full GT reset that we will reset all virtual * GPU engines. For FLR, engine_mask is ignored. */ From 54296aa4cfe71800a68342decc7176b7e1779713 Mon Sep 17 00:00:00 2001 From: Nitin Gote Date: Mon, 20 Jan 2025 13:45:12 +0530 Subject: [PATCH 091/284] drm/i915/gem: fix typos in i915/gem files Fix all typos in files under drm/i915/gem reported by codespell tool. v2: Codespell won't catch it, but it should be "user defined" and not "use defined". Signed-off-by: Nitin Gote Reviewed-by: Krzysztof Niemiec Link: https://patchwork.freedesktop.org/patch/msgid/20250120081517.3237326-4-nitin.r.gote@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 6 +++--- drivers/gpu/drm/i915/gem/i915_gem_context_types.h | 6 +++--- drivers/gpu/drm/i915/gem/i915_gem_domain.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 4 ++-- drivers/gpu/drm/i915/gem/i915_gem_region.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 4 ++-- drivers/gpu/drm/i915/gem/i915_gem_tiling.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 2 +- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 2 +- drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index c0543c35cd6ac..ab1af978911b5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -238,7 +238,7 @@ static int proto_context_set_persistence(struct drm_i915_private *i915, * * However, if we cannot reset an engine by itself, we cannot * cleanup a hanging persistent context without causing - * colateral damage, and we should not pretend we can by + * collateral damage, and we should not pretend we can by * exposing the interface. */ if (!intel_has_reset_engine(to_gt(i915))) @@ -1589,7 +1589,7 @@ static int __context_set_persistence(struct i915_gem_context *ctx, bool state) * * However, if we cannot reset an engine by itself, we cannot * cleanup a hanging persistent context without causing - * colateral damage, and we should not pretend we can by + * collateral damage, and we should not pretend we can by * exposing the interface. */ if (!intel_has_reset_engine(to_gt(ctx->i915))) @@ -2328,7 +2328,7 @@ finalize_create_context_locked(struct drm_i915_file_private *file_priv, /* * One for the xarray and one for the caller. We need to grab - * the reference *prior* to making the ctx visble to userspace + * the reference *prior* to making the ctx visible to userspace * in gem_context_register(), as at any point after that * userspace can try to race us with another thread destroying * the context under our feet. diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h index b6d97da63d1fa..67ac2586a0f3f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h @@ -245,9 +245,9 @@ struct i915_gem_context { * Execbuf uses the I915_EXEC_RING_MASK as an index into this * array to select which HW context + engine to execute on. For * the default array, the user_ring_map[] is used to translate - * the legacy uABI onto the approprate index (e.g. both + * the legacy uABI onto the appropriate index (e.g. both * I915_EXEC_DEFAULT and I915_EXEC_RENDER select the same - * context, and I915_EXEC_BSD is weird). For a use defined + * context, and I915_EXEC_BSD is weird). For a user defined * array, execbuf uses I915_EXEC_RING_MASK as a plain index. * * User defined by I915_CONTEXT_PARAM_ENGINE (when the @@ -276,7 +276,7 @@ struct i915_gem_context { * @vm: unique address space (GTT) * * In full-ppgtt mode, each context has its own address space ensuring - * complete seperation of one client from all others. + * complete separation of one client from all others. * * In other modes, this is a NULL pointer with the expectation that * the caller uses the shared global GTT. diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c index 3770828f2eaf2..ee55caca67a11 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@ -276,7 +276,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, * For objects created by userspace through GEM_CREATE with pat_index * set by set_pat extension, simply return 0 here without touching * the cache setting, because such objects should have an immutable - * cache setting by desgin and always managed by userspace. + * cache setting by design and always managed by userspace. */ if (i915_gem_object_has_cache_level(obj, cache_level)) return 0; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index f151640c1d13c..c8107502190d2 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -303,7 +303,7 @@ struct i915_execbuffer { struct intel_gt_buffer_pool_node *batch_pool; /** pool node for batch buffer */ /** - * Indicate either the size of the hastable used to resolve + * Indicate either the size of the hashtable used to resolve * relocation handles, or if negative that we are using a direct * index into the execobj[]. */ @@ -2543,7 +2543,7 @@ static int eb_pin_timeline(struct i915_execbuffer *eb, struct intel_context *ce, /* * Error path, cannot use intel_context_timeline_lock as - * that is user interruptable and this clean up step + * that is user interruptible and this clean up step * must be done. */ mutex_lock(&ce->timeline->mutex); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c index b09b74a2448b5..636768d0f57eb 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_region.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c @@ -82,7 +82,7 @@ __i915_gem_object_create_region(struct intel_memory_region *mem, /* * Anything smaller than the min_page_size can't be freely inserted into - * the GTT, due to alignemnt restrictions. For such special objects, + * the GTT, due to alignment restrictions. For such special objects, * make sure we force memcpy based suspend-resume. In the future we can * revisit this, either by allowing special mis-aligned objects in the * migration path, or by mapping all of LMEM upfront using cheap 1G diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c index 9117e94228440..aec41f0f098f6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c @@ -25,7 +25,7 @@ static bool swap_available(void) static bool can_release_pages(struct drm_i915_gem_object *obj) { - /* Consider only shrinkable ojects. */ + /* Consider only shrinkable objects. */ if (!i915_gem_object_is_shrinkable(obj)) return false; @@ -261,7 +261,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww, * i915_gem_shrink_all - Shrink buffer object caches completely * @i915: i915 device * - * This is a simple wraper around i915_gem_shrink() to aggressively shrink all + * This is a simple wrapper around i915_gem_shrink() to aggressively shrink all * caches completely. It also first waits for and retires all outstanding * requests to also be able to release backing storage for active objects. * diff --git a/drivers/gpu/drm/i915/gem/i915_gem_tiling.c b/drivers/gpu/drm/i915/gem/i915_gem_tiling.c index d9eb84c1d2f11..5ac23ff3feff2 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_tiling.c @@ -39,7 +39,7 @@ * Since neither of this applies for new tiling layouts on modern platforms like * W, Ys and Yf tiling GEM only allows object tiling to be set to X or Y tiled. * Anything else can be handled in userspace entirely without the kernel's - * invovlement. + * involvement. */ /** diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 10d8673641f74..1f48149688684 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -994,7 +994,7 @@ void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj) * If we need to place an LMEM resource which doesn't need CPU * access then we should try not to victimize mappable objects * first, since we likely end up stealing more of the mappable - * portion. And likewise when we try to find space for a mappble + * portion. And likewise when we try to find space for a mappable * object, we know not to ever victimize objects that don't * occupy any mappable pages. */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c index 041dab543b78e..2f6b33edb9c9f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c @@ -603,7 +603,7 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, * sequence, where at the end we can do the move for real. * * The special case here is when the dst_mem is TTM_PL_SYSTEM, - * which doens't require any kind of move, so it should be safe + * which doesn't require any kind of move, so it should be safe * to skip all the below and call ttm_bo_move_null() here, where * the caller in __i915_ttm_get_pages() will take care of the * rest, since we should have a valid ttm_tt. diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 84d41e6ccf056..bd08605a1611f 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1781,7 +1781,7 @@ static int igt_tmpfs_fallback(void *arg) /* * Make sure that we don't burst into a ball of flames upon falling back - * to tmpfs, which we rely on if on the off-chance we encouter a failure + * to tmpfs, which we rely on if on the off-chance we encounter a failure * when setting up gemfs. */ diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c index 99a9ade739562..804f74084bd4f 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -1342,7 +1342,7 @@ static int igt_mmap_migrate(void *arg) } /* - * Allocate in the mappable portion, should be no suprises here. + * Allocate in the mappable portion, should be no surprises here. */ err = __igt_mmap_migrate(mixed, ARRAY_SIZE(mixed), mr, 0); if (err) From 5fe543ce678aeaa6298eca9fe49ea1eaea024a6b Mon Sep 17 00:00:00 2001 From: Nitin Gote Date: Mon, 20 Jan 2025 13:45:13 +0530 Subject: [PATCH 092/284] drm/i915/pxp: fix typos in i915/pxp files Fix all typos in files under drm/i915/pxp reported by codespell tool. Signed-off-by: Nitin Gote Reviewed-by: Krzysztof Niemiec Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20250120081517.3237326-5-nitin.r.gote@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h | 2 +- drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h index 329b4fcdc0405..929c20e98300c 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h @@ -41,7 +41,7 @@ struct pxp43_huc_auth_out { /* PXP-Input-Packet: Init PXP session */ struct pxp43_create_arb_in { struct pxp_cmd_header header; - /* header.stream_id fields for vesion 4.3 of Init PXP session: */ + /* header.stream_id fields for version 4.3 of Init PXP session: */ #define PXP43_INIT_SESSION_VALID BIT(0) #define PXP43_INIT_SESSION_APPTYPE BIT(1) #define PXP43_INIT_SESSION_APPID GENMASK(17, 2) diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h index 07864b584cf4c..febdbcd8d61e4 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h @@ -21,7 +21,7 @@ struct drm_i915_private; */ struct intel_pxp { /** - * @ctrl_gt: poiner to the tile that owns the controls for PXP subsystem assets that + * @ctrl_gt: pointer to the tile that owns the controls for PXP subsystem assets that * the VDBOX, the KCR engine (and GSC CS depending on the platform) */ struct intel_gt *ctrl_gt; From accc7f5bf230864eec84b249104cb8649c993a62 Mon Sep 17 00:00:00 2001 From: Nitin Gote Date: Mon, 20 Jan 2025 13:45:14 +0530 Subject: [PATCH 093/284] drm/i915/selftests: fix typos in i915/selftests files Fix all typos in files under drm/i915/selftests reported by codespell tool. v2: Fix commenting style Signed-off-by: Nitin Gote Reviewed-by: Krzysztof Niemiec Link: https://patchwork.freedesktop.org/patch/msgid/20250120081517.3237326-6-nitin.r.gote@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/selftests/i915_gem.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 21 ++++++++++++------- drivers/gpu/drm/i915/selftests/i915_vma.c | 15 ++++++++----- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/selftests/i915_gem.c b/drivers/gpu/drm/i915/selftests/i915_gem.c index 0727492576be2..e817d233df615 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem.c @@ -80,7 +80,7 @@ static void simulate_hibernate(struct drm_i915_private *i915) wakeref = intel_runtime_pm_get(&i915->runtime_pm); /* - * As a final sting in the tail, invalidate stolen. Under a real S4, + * As a final string in the tail, invalidate stolen. Under a real S4, * stolen is lost and needs to be refilled on resume. However, under * CI we merely do S4-device testing (as full S4 is too unreliable * for automated testing across a cluster), so to simulate the effect diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 5c397a2df70e2..5816d515203a2 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -287,7 +287,8 @@ static int lowlevel_hole(struct i915_address_space *vm, GEM_BUG_ON(count * BIT_ULL(aligned_size) > vm->total); GEM_BUG_ON(hole_start + count * BIT_ULL(aligned_size) > hole_end); - /* Ignore allocation failures (i.e. don't report them as + /* + * Ignore allocation failures (i.e. don't report them as * a test failure) as we are purposefully allocating very * large objects without checking that we have sufficient * memory. We expect to hit -ENOMEM. @@ -446,7 +447,8 @@ static int fill_hole(struct i915_address_space *vm, list_add(&obj->st_link, &objects); - /* Align differing sized objects against the edges, and + /* + * Align differing sized objects against the edges, and * check we don't walk off into the void when binding * them into the GTT. */ @@ -831,7 +833,8 @@ static int drunk_hole(struct i915_address_space *vm, return -ENOMEM; GEM_BUG_ON(!order); - /* Ignore allocation failures (i.e. don't report them as + /* + * Ignore allocation failures (i.e. don't report them as * a test failure) as we are purposefully allocating very * large objects without checking that we have sufficient * memory. We expect to hit -ENOMEM. @@ -964,7 +967,7 @@ static int __shrink_hole(struct i915_address_space *vm, break; if (igt_timeout(end_time, - "%s timed out at ofset %llx [%llx - %llx]\n", + "%s timed out at offset %llx [%llx - %llx]\n", __func__, addr, hole_start, hole_end)) { err = -EINTR; break; @@ -1011,7 +1014,7 @@ static int shrink_boom(struct i915_address_space *vm, /* * Catch the case which shrink_hole seems to miss. The setup here * requires invoking the shrinker as we do the alloc_pt/alloc_pd, while - * ensuring that all vma assiocated with the respective pd/pdp are + * ensuring that all vma associated with the respective pd/pdp are * unpinned at the time. */ @@ -1537,9 +1540,10 @@ static int igt_gtt_reserve(void *arg) u64 total; int err = -ENODEV; - /* i915_gem_gtt_reserve() tries to reserve the precise range + /* + * i915_gem_gtt_reserve() tries to reserve the precise range * for the node, and evicts if it has to. So our test checks that - * it can give us the requsted space and prevent overlaps. + * it can give us the requested space and prevent overlaps. */ /* Start by filling the GGTT */ @@ -1743,7 +1747,8 @@ static int igt_gtt_insert(void *arg) u64 total; int err = -ENODEV; - /* i915_gem_gtt_insert() tries to allocate some free space in the GTT + /* + * i915_gem_gtt_insert() tries to allocate some free space in the GTT * to the node, evicting if required. */ diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c index 71b52d5efef42..7c4111e60f2ec 100644 --- a/drivers/gpu/drm/i915/selftests/i915_vma.c +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c @@ -159,7 +159,8 @@ static int igt_vma_create(void *arg) LIST_HEAD(objects); int err = -ENOMEM; - /* Exercise creating many vma amonst many objections, checking the + /* + * Exercise creating many vma amongst many objections, checking the * vma creation and lookup routines. */ @@ -292,7 +293,8 @@ static int igt_vma_pin1(void *arg) VALID(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)), #if !IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) - /* Misusing BIAS is a programming error (it is not controllable + /* + * Misusing BIAS is a programming error (it is not controllable * from userspace) so when debugging is enabled, it explodes. * However, the tests are still quite interesting for checking * variable start, end and size. @@ -312,7 +314,8 @@ static int igt_vma_pin1(void *arg) struct i915_vma *vma; int err = -EINVAL; - /* Exercise all the weird and wonderful i915_vma_pin requests, + /* + * Exercise all the weird and wonderful i915_vma_pin requests, * focusing on error handling of boundary conditions. */ @@ -577,7 +580,8 @@ static int igt_vma_rotate_remap(void *arg) const unsigned int max_pages = 64; int err = -ENOMEM; - /* Create VMA for many different combinations of planes and check + /* + * Create VMA for many different combinations of planes and check * that the page layout within the rotated VMA match our expectations. */ @@ -804,7 +808,8 @@ static int igt_vma_partial(void *arg) struct i915_vma *vma; int err = -ENOMEM; - /* Create lots of different VMA for the object and check that + /* + * Create lots of different VMA for the object and check that * we are returned the same VMA when we later request the same range. */ From 5b056be1f2d6d9ec3c61cc7b6e4c2cebd094f9f9 Mon Sep 17 00:00:00 2001 From: Nitin Gote Date: Mon, 20 Jan 2025 13:45:15 +0530 Subject: [PATCH 094/284] drm/i915/soc: fix typos in i915/soc files Fix all typos in files under drm/i915/soc reported by codespell tool. Signed-off-by: Nitin Gote Reviewed-by: Krzysztof Niemiec Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20250120081517.3237326-7-nitin.r.gote@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/soc/intel_pch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/soc/intel_pch.c b/drivers/gpu/drm/i915/soc/intel_pch.c index 842db43e46c0f..9f7c9dbc178eb 100644 --- a/drivers/gpu/drm/i915/soc/intel_pch.c +++ b/drivers/gpu/drm/i915/soc/intel_pch.c @@ -243,7 +243,7 @@ void intel_detect_pch(struct drm_i915_private *dev_priv) * underneath. This is a requirement from virtualization team. * * In some virtualized environments (e.g. XEN), there is irrelevant - * ISA bridge in the system. To work reliably, we should scan trhough + * ISA bridge in the system. To work reliably, we should scan through * all the ISA bridge devices and check for the first match, instead * of only checking the first one. */ From c55af0065207472ce96492e282d566c3415f3288 Mon Sep 17 00:00:00 2001 From: Nitin Gote Date: Mon, 20 Jan 2025 13:45:16 +0530 Subject: [PATCH 095/284] drm/i915/display: fix typos in i915/display files Fix all typos in files under drm/i915/display reported by codespell tool. v2: - Include british and american spelling, as those are not typos. - Fix commenting style. v3: Fix "In case" wrongly capitalized and also fix comment style. Signed-off-by: Nitin Gote Reviewed-by: Krzysztof Niemiec Link: https://patchwork.freedesktop.org/patch/msgid/20250120081517.3237326-8-nitin.r.gote@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/dvo_ns2501.c | 2 +- drivers/gpu/drm/i915/display/i9xx_wm.c | 6 +-- drivers/gpu/drm/i915/display/icl_dsi.c | 4 +- drivers/gpu/drm/i915/display/intel_audio.c | 4 +- drivers/gpu/drm/i915/display/intel_cdclk.c | 2 +- drivers/gpu/drm/i915/display/intel_color.c | 2 +- drivers/gpu/drm/i915/display/intel_crt.c | 6 ++- drivers/gpu/drm/i915/display/intel_crtc.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_ddi.c | 4 +- drivers/gpu/drm/i915/display/intel_display.c | 8 ++-- .../drm/i915/display/intel_display_debugfs.c | 2 +- .../drm/i915/display/intel_display_power.c | 4 +- .../i915/display/intel_display_power_well.h | 4 +- .../drm/i915/display/intel_display_types.h | 4 +- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- .../drm/i915/display/intel_dp_link_training.c | 4 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 4 +- drivers/gpu/drm/i915/display/intel_dp_test.c | 4 +- .../gpu/drm/i915/display/intel_dp_tunnel.c | 2 +- drivers/gpu/drm/i915/display/intel_dpio_phy.c | 2 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 2 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 2 +- drivers/gpu/drm/i915/display/intel_dsb.c | 2 +- drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 2 +- drivers/gpu/drm/i915/display/intel_dvo_dev.h | 2 +- drivers/gpu/drm/i915/display/intel_fdi.c | 2 +- .../drm/i915/display/intel_fifo_underrun.c | 2 +- .../gpu/drm/i915/display/intel_frontbuffer.c | 2 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 8 ++-- drivers/gpu/drm/i915/display/intel_hotplug.c | 6 +-- .../gpu/drm/i915/display/intel_hotplug_irq.c | 2 +- drivers/gpu/drm/i915/display/intel_link_bw.c | 2 +- drivers/gpu/drm/i915/display/intel_overlay.c | 20 +++++--- drivers/gpu/drm/i915/display/intel_pmdemand.c | 2 +- drivers/gpu/drm/i915/display/intel_pps.c | 5 +- drivers/gpu/drm/i915/display/intel_psr.c | 8 ++-- drivers/gpu/drm/i915/display/intel_sdvo.c | 4 +- .../gpu/drm/i915/display/intel_sdvo_regs.h | 2 +- drivers/gpu/drm/i915/display/intel_snps_phy.c | 2 +- drivers/gpu/drm/i915/display/intel_vblank.c | 2 +- drivers/gpu/drm/i915/display/intel_vdsc.c | 2 +- drivers/gpu/drm/i915/display/skl_scaler.c | 48 +++++++++---------- .../drm/i915/display/skl_universal_plane.c | 4 +- drivers/gpu/drm/i915/display/skl_watermark.c | 4 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 2 +- drivers/gpu/drm/i915/display/vlv_dsi_pll.c | 2 +- 47 files changed, 112 insertions(+), 103 deletions(-) diff --git a/drivers/gpu/drm/i915/display/dvo_ns2501.c b/drivers/gpu/drm/i915/display/dvo_ns2501.c index 686393dfbbf53..04005cdd0461a 100644 --- a/drivers/gpu/drm/i915/display/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/display/dvo_ns2501.c @@ -517,7 +517,7 @@ static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo) * Even if not, the detection bit of the 2501 is unreliable as * it only works for some display types. * It is even more unreliable as the PLL must be active for - * allowing reading from the chiop. + * allowing reading from the chip. */ return connector_status_connected; } diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index db78c1e6b0a37..497850a6ac811 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -446,7 +446,7 @@ static const struct intel_watermark_params i845_wm_info = { * @latency: Memory wakeup latency in 0.1us units * * Compute the watermark using the method 1 or "small buffer" - * formula. The caller may additonally add extra cachelines + * formula. The caller may additionally add extra cachelines * to account for TLB misses and clock crossings. * * This method is concerned with the short term drain rate @@ -493,7 +493,7 @@ static unsigned int intel_wm_method1(unsigned int pixel_rate, * @latency: Memory wakeup latency in 0.1us units * * Compute the watermark using the method 2 or "large buffer" - * formula. The caller may additonally add extra cachelines + * formula. The caller may additionally add extra cachelines * to account for TLB misses and clock crossings. * * This method is concerned with the long term drain rate @@ -1562,7 +1562,7 @@ static int vlv_compute_fifo(struct intel_crtc_state *crtc_state) /* * When enabling sprite0 after sprite1 has already been enabled * we tend to get an underrun unless sprite0 already has some - * FIFO space allcoated. Hence we always allocate at least one + * FIFO space allocated. Hence we always allocate at least one * cacheline for sprite0 whenever sprite1 is enabled. * * All other plane enable sequences appear immune to this problem. diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index c977b74f82f0b..3bedaf1454b19 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -243,7 +243,7 @@ static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) for_each_dsi_phy(phy, intel_dsi->phys) { /* * Program voltage swing and pre-emphasis level values as per - * table in BSPEC under DDI buffer programing + * table in BSPEC under DDI buffer programming. */ mask = SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK; val = SCALING_MODE_SEL(0x2) | TAP2_DISABLE | TAP3_DISABLE | @@ -961,7 +961,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, for_each_dsi_port(port, intel_dsi->ports) { dsi_trans = dsi_port_to_transcoder(port); /* - * FIXME: Programing this by assuming progressive mode, since + * FIXME: Programming this by assuming progressive mode, since * non-interlaced info from VBT is not saved inside * struct drm_display_mode. * For interlace mode: program required pixel minus 2 diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 4b1f46815ad5f..113d763e6ef3b 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -567,7 +567,7 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder, AUDIO_ELD_VALID(cpu_transcoder), 0); /* - * The audio componenent is used to convey the ELD + * The audio component is used to convey the ELD * instead using of the hardware ELD buffer. */ @@ -665,7 +665,7 @@ static void ibx_audio_codec_enable(struct intel_encoder *encoder, IBX_ELD_VALID(port), 0); /* - * The audio componenent is used to convey the ELD + * The audio component is used to convey the ELD * instead using of the hardware ELD buffer. */ diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index bee90b06995ab..b520231833b79 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2250,7 +2250,7 @@ static void bxt_sanitize_cdclk(struct intel_display *display) /* * Let's ignore the pipe field, since BIOS could have configured the - * dividers both synching to an active pipe, or asynchronously + * dividers both syncing to an active pipe, or asynchronously * (PIPE_NONE). */ cdctl &= ~bxt_cdclk_cd2x_pipe(display, INVALID_PIPE); diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 2f51eccdb27aa..8400a97f7e434 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -998,7 +998,7 @@ static void skl_color_commit_noarm(struct intel_dsb *dsb, * output all black (until CSC_MODE is rearmed and properly latched). * Once PSR exit (and proper register latching) has occurred the * danger is over. Thus when PSR is enabled the CSC coeff/offset - * register programming will be peformed from skl_color_commit_arm() + * register programming will be performed from skl_color_commit_arm() * which is called after PSR exit. */ if (!crtc_state->has_psr) diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index 4634d3fd9f201..bc724dc5b4eaf 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -745,8 +745,10 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe) transconf | TRANSCONF_FORCE_BORDER); intel_de_posting_read(display, TRANSCONF(display, cpu_transcoder)); - /* Wait for next Vblank to substitue - * border color for Color info */ + /* + * Wait for next Vblank to substitute + * border color for Color info. + */ intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, pipe)); st00 = intel_de_read8(display, _VGA_MSR_WRITE); status = ((st00 & (1 << 4)) != 0) ? diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 3e8b52eaac277..e69b28779ac55 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -96,7 +96,7 @@ u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state) struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); /* - * From Gen 11, In case of dsi cmd mode, frame counter wouldnt + * From Gen 11, in case of dsi cmd mode, frame counter wouldn't * have updated at the beginning of TE, if we want to use * the hw counter, then we would find it updated in only * the next TE, hence switching to sw counter. diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index ae7243ad6e0ca..48c3d212f690c 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -680,7 +680,7 @@ static void i9xx_cursor_update_arm(struct intel_dsb *dsb, * CURPOS. * * On other platforms CURPOS always requires the - * CURBASE write to arm the update. Additonally + * CURBASE write to arm the update. Additionally * a write to any of the cursor register will cancel * an already armed cursor update. Thus leaving out * the CURBASE write after CURPOS could lead to a diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 3693b36b9336a..05df8f9864912 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2984,7 +2984,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, * - crtc_state will be the state of the first stream to be activated on this * port, and it may not be the same stream that will be deactivated last, but * each stream should have a state that is identical when it comes to the DP - * link parameteres + * link parameters. */ static void intel_ddi_pre_enable(struct intel_atomic_state *state, struct intel_encoder *encoder, @@ -3284,7 +3284,7 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, * be deactivated on this port, and it may not be the same * stream that was activated last, but each stream * should have a state that is identical when it comes to - * the DP link parameteres + * the DP link parameters */ if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 10550bc0778e3..7d68d652c1bc9 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1013,7 +1013,7 @@ static void intel_async_flip_vtd_wa(struct drm_i915_private *i915, { if (DISPLAY_VER(i915) == 9) { /* - * "Plane N strech max must be programmed to 11b (x1) + * "Plane N stretch max must be programmed to 11b (x1) * when Async flips are enabled on that plane." */ intel_de_rmw(i915, CHICKEN_PIPESL_1(pipe), @@ -3592,7 +3592,7 @@ static void ilk_get_pfit_config(struct intel_crtc_state *crtc_state) REG_FIELD_GET(PF_WIN_YSIZE_MASK, size)); /* - * We currently do not free assignements of panel fitters on + * We currently do not free assignments of panel fitters on * ivb/hsw (since we don't use the higher upscaling modes which * differentiates them) so just WARN about this case for now. */ @@ -4292,7 +4292,7 @@ int intel_dotclock_calculate(int link_freq, /* * The calculation for the data clock -> pixel clock is: * pixel_clock = ((m/n)*(link_clock * nr_lanes))/bpp - * But we want to avoid losing precison if possible, so: + * But we want to avoid losing precision if possible, so: * pixel_clock = ((m * link_clock * nr_lanes)/(n*bpp)) * * and for link freq (10kbs units) -> pixel clock it is: @@ -6433,7 +6433,7 @@ static void kill_joiner_secondaries(struct intel_atomic_state *state, * the intel_crtc_enable_flip_done() function. * * As soon as the surface address register is written, flip done interrupt is - * generated and the requested events are sent to the usersapce in the interrupt + * generated and the requested events are sent to the userspace in the interrupt * handler itself. The timestamp and sequence sent during the flip done event * correspond to the last vblank and have no relation to the actual time when * the flip done event was sent. diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index f1d76484025ad..926f09c350840 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -940,7 +940,7 @@ static int i915_lpsp_capability_show(struct seq_file *m, void *data) /* * Actually TGL can drive LPSP on port till DDI_C * but there is no physical connected DDI_C on TGL sku's, - * even driver is not initilizing DDI_C port for gen12. + * even driver is not initializing DDI_C port for gen12. */ lpsp_capable = encoder->port <= PORT_B; else if (DISPLAY_VER(i915) == 11) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 8e86fcbcc189b..14ae60749f02c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -842,7 +842,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, * block right away if this is the last reference. * * This function is only for the power domain code's internal use to suppress wakeref - * tracking when the correspondig debug kconfig option is disabled, should not + * tracking when the corresponding debug kconfig option is disabled, should not * be used otherwise. */ void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, @@ -1733,7 +1733,7 @@ static void icl_display_core_uninit(struct intel_display *display) gen9_disable_dc_states(display); intel_dmc_disable_program(display); - /* 1. Disable all display engine functions -> aready done */ + /* 1. Disable all display engine functions -> already done */ /* 2. Disable DBUF */ gen9_dbuf_disable(display); diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.h b/drivers/gpu/drm/i915/display/intel_display_power_well.h index 338379dae44c2..ec8e508d0593d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.h +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.h @@ -60,7 +60,7 @@ struct i915_power_well_instance { /* unique identifier for this power well */ enum i915_power_well_id id; /* - * Arbitraty data associated with this power well. Platform and power + * Arbitrary data associated with this power well. Platform and power * well specific. */ union { @@ -77,7 +77,7 @@ struct i915_power_well_instance { struct { /* * request/status flag index in the power well - * constrol/status registers. + * control/status registers. */ u8 idx; } hsw; diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 083eb86f09040..96429201b8a01 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -732,7 +732,7 @@ struct intel_crtc_scaler_state { * * intel_atomic_setup_scalers will setup available scalers to users * requesting scalers. It will gracefully fail if request exceeds - * avilability. + * availability. */ #define SKL_CRTC_INDEX 31 unsigned scaler_users; @@ -1113,7 +1113,7 @@ struct intel_crtc_state { u16 su_y_granularity; /* - * Frequence the dpll for the port should run at. Differs from the + * Frequency the dpll for the port should run at. Differs from the * adjusted dotclock e.g. for DP or 10/12bpc hdmi mode. This is also * already multiplied by pixel_multiplier. */ diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 9ec23860b593d..c239008658a81 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1075,7 +1075,7 @@ static bool source_can_output(struct intel_dp *intel_dp, /* * No YCbCr output support on gmch platforms. * Also, ILK doesn't seem capable of DP YCbCr output. - * The displayed image is severly corrupted. SNB+ is fine. + * The displayed image is severely corrupted. SNB+ is fine. */ return !HAS_GMCH(display) && !display->platform.ironlake; diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 8b1977cfec503..9cb22baafeebb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -783,7 +783,7 @@ intel_dp_prepare_link_train(struct intel_dp *intel_dp, /* * WaEdpLinkRateDataReload * - * Parade PS8461E MUX (used on varius TGL+ laptops) needs + * Parade PS8461E MUX (used on various TGL+ laptops) needs * to snoop the link rates reported by the sink when we * use LINK_RATE_SET in order to operate in jitter cleaning * mode (as opposed to redriver mode). Unfortunately it @@ -1629,7 +1629,7 @@ void intel_dp_start_link_train(struct intel_atomic_state *state, /* * Ignore the link failure in CI * - * In fixed enviroments like CI, sometimes unexpected long HPDs are + * In fixed environments like CI, sometimes unexpected long HPDs are * generated by the displays. If ignore_long_hpd flag is set, such long * HPDs are ignored. And probably as a consequence of these ignored * long HPDs, subsequent link trainings are failed resulting into CI diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index fbfc756368b87..7c1de9aeeacc5 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -837,7 +837,7 @@ static int intel_dp_mst_check_bw(struct intel_atomic_state *state, * @state must be recomputed with the updated @limits. * * Returns: - * - 0 if the confugration is valid + * - 0 if the configuration is valid * - %-EAGAIN, if the configuration is invalid and @limits got updated * with fallback values with which the configuration of all CRTCs in * @state must be recomputed @@ -2052,7 +2052,7 @@ bool intel_dp_mst_crtc_needs_modeset(struct intel_atomic_state *state, * @intel_dp: DP port object * * Prepare an MST link for topology probing, programming the target - * link parameters to DPCD. This step is a requirement of the enumaration + * link parameters to DPCD. This step is a requirement of the enumeration * of path resources during probing. */ void intel_dp_mst_prepare_probe(struct intel_dp *intel_dp) diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c index 380b359b04208..614b90d6938f1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.c +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -257,7 +257,7 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, /* * FIXME: Ideally pattern should come from DPCD 0x250. As * current firmware of DPR-100 could not set it, so hardcoding - * now for complaince test. + * now for compliance test. */ drm_dbg_kms(display->drm, "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n"); @@ -275,7 +275,7 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, /* * FIXME: Ideally pattern should come from DPCD 0x24A. As * current firmware of DPR-100 could not set it, so hardcoding - * now for complaince test. + * now for compliance test. */ drm_dbg_kms(display->drm, "Set HBR2 compliance Phy Test Pattern\n"); diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c index 589872babdd71..280f302967e37 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c @@ -647,7 +647,7 @@ void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state, * @state must be recomputed with the updated @limits. * * Returns: - * - 0 if the confugration is valid + * - 0 if the configuration is valid * - %-EAGAIN, if the configuration is invalid and @limits got updated * with fallback values with which the configuration of all CRTCs in * @state must be recomputed diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c index 52a36a2281e60..5f88702818d31 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c @@ -40,7 +40,7 @@ * VLV, CHV and BXT have slightly peculiar display PHYs for driving DP/HDMI * ports. DPIO is the name given to such a display PHY. These PHYs * don't follow the standard programming model using direct MMIO - * registers, and instead their registers must be accessed trough IOSF + * registers, and instead their registers must be accessed through IOSF * sideband. VLV has one such PHY for driving ports B and C, and CHV * adds another PHY for driving port D. Each PHY responds to specific * IOSF-SB port. diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index d86cc9ffd4acd..b8fa04d3cd5c5 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -4372,7 +4372,7 @@ void intel_shared_dpll_init(struct drm_i915_private *i915) * calling intel_shared_dpll_swap_state(). * * Returns: - * 0 on success, negative error code on falure. + * 0 on success, negative error code on failure. */ int intel_compute_shared_dplls(struct intel_atomic_state *state, struct intel_crtc *crtc, diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index 6af325b8e27dd..3eee768743045 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -318,7 +318,7 @@ struct dpll_info { const struct intel_shared_dpll_funcs *funcs; /** - * @id: unique indentifier for this DPLL + * @id: unique identifier for this DPLL */ enum intel_dpll_id id; diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 89d3496bcbdbd..2f2812c239725 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -821,7 +821,7 @@ void intel_dsb_irq_handler(struct intel_display *display, if (crtc->dsb_event) { /* - * Update vblank counter/timestmap in case it + * Update vblank counter/timestamp in case it * hasn't been done yet for this frame. */ drm_crtc_accurate_vblank_count(&crtc->base); diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c index b2b78f39cfd31..7b2ffd14ae6ee 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c @@ -582,7 +582,7 @@ static const fn_mipi_elem_exec exec_elem[] = { /* * MIPI Sequence from VBT #53 parsing logic - * We have already separated each seqence during bios parsing + * We have already separated each sequence during bios parsing * Following is generic execution function for any sequence */ diff --git a/drivers/gpu/drm/i915/display/intel_dvo_dev.h b/drivers/gpu/drm/i915/display/intel_dvo_dev.h index 4bf476656b8cd..3be1a16cac20a 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo_dev.h +++ b/drivers/gpu/drm/i915/display/intel_dvo_dev.h @@ -57,7 +57,7 @@ struct intel_dvo_dev_ops { * Turn on/off output. * * Because none of our dvo drivers support an intermediate power levels, - * we don't expose this in the interfac. + * we don't expose this in the interface. */ void (*dpms)(struct intel_dvo_device *dvo, bool enable); diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 37cdfa9c692a0..3e8d6d8af7802 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -390,7 +390,7 @@ static int intel_fdi_atomic_check_bw(struct intel_atomic_state *state, * @state must be recomputed with the updated @limits. * * Returns: - * - 0 if the confugration is valid + * - 0 if the configuration is valid * - %-EAGAIN, if the configuration is invalid and @limits got updated * with fallback values with which the configuration of all CRTCs * in @state must be recomputed diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c index cda1daf4cdea4..18fcdbe1248ac 100644 --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c @@ -290,7 +290,7 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, } /** - * intel_set_cpu_fifo_underrun_reporting - set cpu fifo underrrun reporting state + * intel_set_cpu_fifo_underrun_reporting - set cpu fifo underrun reporting state * @dev_priv: i915 device instance * @pipe: (CPU) pipe to set state for * @enable: whether underruns should be reported or not diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 6ed5f726ee600..26128c610cb4a 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -227,7 +227,7 @@ static void intel_frontbuffer_flush_work(struct work_struct *work) * @front: GEM object to flush * * This function is targeted for our dirty callback for queueing flush when - * dma fence is signales + * dma fence is signals */ void intel_frontbuffer_queue_flush(struct intel_frontbuffer *front) { diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 1bab7c34a7942..7cc0399b2a5d9 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -353,7 +353,7 @@ static bool hdcp_key_loadable(struct intel_display *display) /* * Another req for hdcp key loadability is enabled state of pll for - * cdclk. Without active crtc we wont land here. So we are assuming that + * cdclk. Without active crtc we won't land here. So we are assuming that * cdclk is already on. */ @@ -1550,9 +1550,9 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) * with a 50ms delay if not hdcp2 capable for DP/DPMST encoders * (dock decides to stop advertising hdcp2 capability for some reason). * The reason being that during suspend resume dock usually keeps the - * HDCP2 registers inaccesible causing AUX error. This wouldn't be a + * HDCP2 registers inaccessible causing AUX error. This wouldn't be a * big problem if the userspace just kept retrying with some delay while - * it continues to play low value content but most userpace applications + * it continues to play low value content but most userspace applications * end up throwing an error when it receives one from KMD. This makes * sure we give the dock and the sink devices to complete its power cycle * and then try HDCP authentication. The values of 10 and delay of 50ms @@ -2573,7 +2573,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, /* * During the HDCP encryption session if Type change is requested, - * disable the HDCP and reenable it with new TYPE value. + * disable the HDCP and re-enable it with new TYPE value. */ if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED || diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index 3adc791d3776e..c0d48f651dabd 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -806,7 +806,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) * of the powerwells. * * Since this function can get called in contexts where we're already holding - * dev->mode_config.mutex, we do the actual hotplug enabling in a seperate + * dev->mode_config.mutex, we do the actual hotplug enabling in a separate * worker. * * Also see: intel_hpd_init() and intel_hpd_poll_disable(). @@ -823,7 +823,7 @@ void intel_hpd_poll_enable(struct drm_i915_private *dev_priv) /* * We might already be holding dev->mode_config.mutex, so do this in a - * seperate worker + * separate worker * As well, there's no issue if we race here since we always reschedule * this worker anyway */ @@ -844,7 +844,7 @@ void intel_hpd_poll_enable(struct drm_i915_private *dev_priv) * of the powerwells. * * Since this function can get called in contexts where we're already holding - * dev->mode_config.mutex, we do the actual hotplug enabling in a seperate + * dev->mode_config.mutex, we do the actual hotplug enabling in a separate * worker. * * Also used during driver init to initialize connector->polled diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c index 476ac88087e0e..2137ac7b882a2 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c @@ -197,7 +197,7 @@ void i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv, * @bits: bits to enable * NOTE: the HPD enable bits are modified both inside and outside * of an interrupt context. To avoid that read-modify-write cycles - * interfer, these bits are protected by a spinlock. Since this + * interfere, these bits are protected by a spinlock. Since this * function is usually not called from a context where the lock is * held already, this function acquires the lock itself. A non-locking * version is also available. diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c index 29705c1591190..f4d60e77aa18a 100644 --- a/drivers/gpu/drm/i915/display/intel_link_bw.c +++ b/drivers/gpu/drm/i915/display/intel_link_bw.c @@ -221,7 +221,7 @@ assert_link_limit_change_valid(struct intel_display *display, * limits in @new_limits if there is a BW limitation. * * Returns: - * - 0 if the confugration is valid + * - 0 if the configuration is valid * - %-EAGAIN, if the configuration is invalid and @new_limits got updated * with fallback values with which the configuration of all CRTCs * in @state must be recomputed diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index ca30fff618769..bbb0db33740e9 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -46,7 +46,8 @@ /* Limits for overlay size. According to intel doc, the real limits are: * Y width: 4095, UV width (planar): 2047, Y height: 2047, * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use - * the mininum of both. */ + * the minimum of both. + */ #define IMAGE_MAX_WIDTH 2048 #define IMAGE_MAX_HEIGHT 2046 /* 2 * 1023 */ /* on 830 and 845 these large limits result in the card hanging */ @@ -408,10 +409,12 @@ static int intel_overlay_off(struct intel_overlay *overlay) drm_WARN_ON(display->drm, !overlay->active); - /* According to intel docs the overlay hw may hang (when switching + /* + * According to intel docs the overlay hw may hang (when switching * off) without loading the filter coeffs. It is however unclear whether * this applies to the disabling of the overlay or to the switching off - * of the hw. Do it in both cases */ + * of the hw. Do it in both cases. + */ flip_addr |= OFC_UPDATE; rq = alloc_request(overlay, intel_overlay_off_tail); @@ -442,16 +445,19 @@ static int intel_overlay_off(struct intel_overlay *overlay) return i915_active_wait(&overlay->last_flip); } -/* recover from an interruption due to a signal - * We have to be careful not to repeat work forever an make forward progess. */ +/* + * Recover from an interruption due to a signal. + * We have to be careful not to repeat work forever an make forward progress. + */ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) { return i915_active_wait(&overlay->last_flip); } -/* Wait for pending overlay flip and release old frame. +/* + * Wait for pending overlay flip and release old frame. * Needs to be called before the overlay register are changed - * via intel_overlay_(un)map_regs + * via intel_overlay_(un)map_regs. */ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) { diff --git a/drivers/gpu/drm/i915/display/intel_pmdemand.c b/drivers/gpu/drm/i915/display/intel_pmdemand.c index 975520322136e..63301a01906cc 100644 --- a/drivers/gpu/drm/i915/display/intel_pmdemand.c +++ b/drivers/gpu/drm/i915/display/intel_pmdemand.c @@ -609,7 +609,7 @@ intel_pmdemand_program_params(struct intel_display *display, goto unlock; drm_dbg_kms(display->drm, - "initate pmdemand request values: (0x%x 0x%x)\n", + "initiate pmdemand request values: (0x%x 0x%x)\n", mod_reg1, mod_reg2); intel_de_rmw(display, XELPDP_INITIATE_PMDEMAND_REQUEST(1), 0, diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index eb35f0249f2bd..c0f65749a3f6a 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -1501,8 +1501,9 @@ static void pps_init_delays_vbt(struct intel_dp *intel_dp, if (!pps_delays_valid(vbt)) return; - /* On Toshiba Satellite P50-C-18C system the VBT T12 delay - * of 500ms appears to be too short. Ocassionally the panel + /* + * On Toshiba Satellite P50-C-18C system the VBT T12 delay + * of 500ms appears to be too short. Occasionally the panel * just fails to power back on. Increasing the delay to 800ms * seems sufficient to avoid this problem. */ diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index aa6ff057b54c8..2bdb6c9c22835 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -154,7 +154,7 @@ * * Unfortunately CHICKEN_TRANS itself seems to be double buffered * and thus won't latch until the first vblank. So with DC states - * enabled the register effctively uses the reset value during DC5 + * enabled the register effectively uses the reset value during DC5 * exit+PSR exit sequence, and thus the bit does nothing until * latched by the vblank that it was trying to prevent from being * generated in the first place. So we should probably call this @@ -171,7 +171,7 @@ * CHICKEN_PIPESL_1[15]/HSW_UNMASK_VBL_TO_REGS_IN_SRD (hsw): * * On BDW without this bit is no vblanks whatsoever are - * generated after PSR exit. On HSW this has no apparant effect. + * generated after PSR exit. On HSW this has no apparent effect. * WaPsrDPRSUnmaskVBlankInSRD says to set this. * * The rest of the bits are more self-explanatory and/or @@ -185,7 +185,7 @@ * has_psr + has_panel_replay: Panel Replay * has_psr + has_panel_replay + has_sel_update: Panel Replay Selective Update * - * Description of some intel_psr varibles. enabled, panel_replay_enabled, + * Description of some intel_psr variables. enabled, panel_replay_enabled, * sel_update_enabled * * enabled (alone): PSR1 @@ -1050,7 +1050,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) }; /* * Still using the default IO_BUFFER_WAKE and FAST_WAKE, see - * comments bellow for more information + * comments below for more information */ int tmp; diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index 498b35ec4e0f4..c78da5a2b5594 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -1741,8 +1741,8 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, * pixel multiplier readout is tricky: Only on i915g/gm it is stored in * the sdvo port register, on all other platforms it is part of the dpll * state. Since the general pipe state readout happens before the - * encoder->get_config we so already have a valid pixel multplier on all - * other platfroms. + * encoder->get_config we so already have a valid pixel multiplier on all + * other platforms. */ if (IS_I915G(dev_priv) || IS_I915GM(dev_priv)) { pipe_config->pixel_multiplier = diff --git a/drivers/gpu/drm/i915/display/intel_sdvo_regs.h b/drivers/gpu/drm/i915/display/intel_sdvo_regs.h index 54f099abefeb0..56c4551abefd4 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/display/intel_sdvo_regs.h @@ -244,7 +244,7 @@ struct intel_sdvo_set_target_input_args { * Takes a struct intel_sdvo_output_flags of which outputs are targeted by * future output commands. * - * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12], + * Affected commands include SET_OUTPUT_TIMINGS_PART[12], * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE. */ #define SDVO_CMD_SET_TARGET_OUTPUT 0x11 diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index ec3c0ea2f4cbc..353221d3e29fc 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -522,7 +522,7 @@ static const struct intel_mpllb_state dg2_hdmi_148_5 = { REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1), }; -/* values in the below table are calculted using the algo */ +/* values in the below table are calculated using the algo */ static const struct intel_mpllb_state dg2_hdmi_25200 = { .clock = 25200, .ref_control = diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index fb80e0bef08a1..4efd4f7d497ab 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -369,7 +369,7 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc, /* * Already exiting vblank? If so, shift our position - * so it looks like we're already apporaching the full + * so it looks like we're already approaching the full * vblank end. This should make the generated timestamp * more or less match when the active portion will start. */ diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 1e8f71fb30945..932435a7f88d6 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -106,7 +106,7 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg) * According to DSC 1.2 spec in Section 4.1 if native_420 is set: * -second_line_bpg_offset is 12 in general and equal to 2*(slice_height-1) if slice * height < 8. - * -second_line_offset_adj is 512 as shown by emperical values to yield best chroma + * -second_line_offset_adj is 512 as shown by empirical values to yield best chroma * preservation in second line. * -nsl_bpg_offset is calculated as second_line_offset/slice_height -1 then rounded * up to 16 fractional bits, we left shift second line offset by 11 to preserve 11 diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index a11e09a15e238..515196e03b937 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -585,31 +585,31 @@ static u16 glk_nearest_filter_coef(int t) * The letter represents the filter tap (D is the center tap) and the number * represents the coefficient set for a phase (0-16). * - * +------------+------------------------+------------------------+ - * |Index value | Data value coeffient 1 | Data value coeffient 2 | - * +------------+------------------------+------------------------+ - * | 00h | B0 | A0 | - * +------------+------------------------+------------------------+ - * | 01h | D0 | C0 | - * +------------+------------------------+------------------------+ - * | 02h | F0 | E0 | - * +------------+------------------------+------------------------+ - * | 03h | A1 | G0 | - * +------------+------------------------+------------------------+ - * | 04h | C1 | B1 | - * +------------+------------------------+------------------------+ - * | ... | ... | ... | - * +------------+------------------------+------------------------+ - * | 38h | B16 | A16 | - * +------------+------------------------+------------------------+ - * | 39h | D16 | C16 | - * +------------+------------------------+------------------------+ - * | 3Ah | F16 | C16 | - * +------------+------------------------+------------------------+ - * | 3Bh | Reserved | G16 | - * +------------+------------------------+------------------------+ + * +------------+--------------------------+--------------------------+ + * |Index value | Data value coefficient 1 | Data value coefficient 2 | + * +------------+--------------------------+--------------------------+ + * | 00h | B0 | A0 | + * +------------+--------------------------+--------------------------+ + * | 01h | D0 | C0 | + * +------------+--------------------------+--------------------------+ + * | 02h | F0 | E0 | + * +------------+--------------------------+--------------------------+ + * | 03h | A1 | G0 | + * +------------+--------------------------+--------------------------+ + * | 04h | C1 | B1 | + * +------------+--------------------------+--------------------------+ + * | ... | ... | ... | + * +------------+--------------------------+--------------------------+ + * | 38h | B16 | A16 | + * +------------+--------------------------+--------------------------+ + * | 39h | D16 | C16 | + * +------------+--------------------------+--------------------------+ + * | 3Ah | F16 | C16 | + * +------------+--------------------------+--------------------------+ + * | 3Bh | Reserved | G16 | + * +------------+--------------------------+--------------------------+ * - * To enable nearest-neighbor scaling: program scaler coefficents with + * To enable nearest-neighbor scaling: program scaler coefficients with * the center tap (Dxx) values set to 1 and all other values set to 0 as per * SCALER_COEFFICIENT_FORMAT * diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 450dd8c64e0c4..301ad3a22c4c6 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1099,7 +1099,7 @@ static u32 skl_plane_ctl_rotate(unsigned int rotate) break; /* * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr - * while i915 HW rotation is clockwise, thats why this swapping. + * while i915 HW rotation is clockwise, that's why this swapping. */ case DRM_MODE_ROTATE_90: return PLANE_CTL_ROTATE_270; @@ -2997,7 +2997,7 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, /* * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr - * while i915 HW rotation is clockwise, thats why this swapping. + * while i915 HW rotation is clockwise, that's why this swapping. */ switch (val & PLANE_CTL_ROTATE_MASK) { case PLANE_CTL_ROTATE_0: diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index f4458d1185b3a..2bc6251e93d6b 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -584,7 +584,7 @@ u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *i915, /* * Per plane DDB entry can in a really worst case be on multiple slices - * but single entry is anyway contigious. + * but single entry is anyway contiguous. */ while (start_slice <= end_slice) { slice_mask |= BIT(start_slice); @@ -3204,7 +3204,7 @@ adjust_wm_latency(struct drm_i915_private *i915, * WaWmMemoryReadLatency * * punit doesn't take into account the read latency so we need - * to add proper adjustement to each valid level we retrieve + * to add proper adjustment to each valid level we retrieve * from the punit when level 0 response data is 0us. */ if (wm[0] == 0) { diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index d49e9b3c76279..0333c4d9b7030 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -59,7 +59,7 @@ static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count, 8 * 100), lane_count); } -/* return pixels equvalent to txbyteclkhs */ +/* return pixels equivalent to txbyteclkhs */ static u16 pixels_from_txbyteclkhs(u16 clk_hs, int bpp, int lane_count, u16 burst_mode_ratio) { diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c index 59a50647f2c3c..ac69eaece0fda 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c @@ -459,7 +459,7 @@ static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port, /* * rx divider value needs to be updated in the - * two differnt bit fields in the register hence splitting the + * two different bit fields in the register hence splitting the * rx divider value accordingly */ rx_div_lower = rx_div & RX_DIVIDER_BIT_1_2; From 381ab12d483ea30af4ca52db51d23c947f2904c1 Mon Sep 17 00:00:00 2001 From: Nitin Gote Date: Mon, 20 Jan 2025 13:45:17 +0530 Subject: [PATCH 096/284] drm/i915: fix typos in drm/i915 files Fix all typos in files under drm/i915 reported by codespell tool. v2: Fix commenting style. v3: "in case" should be capitalized and fix comment style. Signed-off-by: Nitin Gote Reviewed-by: Krzysztof Niemiec Link: https://patchwork.freedesktop.org/patch/msgid/20250120081517.3237326-9-nitin.r.gote@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_driver.c | 2 +- drivers/gpu/drm/i915/i915_gem.c | 6 +++--- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/i915_module.c | 2 +- drivers/gpu/drm/i915/i915_perf.c | 19 ++++++++++++------- drivers/gpu/drm/i915/i915_pmu.h | 2 +- drivers/gpu/drm/i915/i915_reg.h | 7 ++++--- drivers/gpu/drm/i915/i915_request.c | 2 +- drivers/gpu/drm/i915/i915_request.h | 4 ++-- drivers/gpu/drm/i915/i915_vma.c | 8 ++++---- drivers/gpu/drm/i915/intel_clock_gating.c | 2 +- drivers/gpu/drm/i915/intel_gvt.c | 2 +- drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 2 +- drivers/gpu/drm/i915/intel_runtime_pm.c | 2 +- drivers/gpu/drm/i915/intel_runtime_pm.h | 2 +- drivers/gpu/drm/i915/intel_uncore.c | 2 +- 16 files changed, 36 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index c2ae37d6b94d5..91a7748f44926 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1130,7 +1130,7 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation) * leave the device in D0 on those platforms and hope the BIOS will * power down the device properly. The issue was seen on multiple old * GENs with different BIOS vendors, so having an explicit blacklist - * is inpractical; apply the workaround on everything pre GEN6. The + * is impractical; apply the workaround on everything pre GEN6. The * platforms where the issue was seen: * Lenovo Thinkpad X301, X61s, X60, T60, X41 * Fujitsu FSC S7110 diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 070ab65469879..8c8d43451f35e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1146,11 +1146,11 @@ int i915_gem_init(struct drm_i915_private *dev_priv) int ret; /* - * In the proccess of replacing cache_level with pat_index a tricky + * In the process of replacing cache_level with pat_index a tricky * dependency is created on the definition of the enum i915_cache_level. - * in case this enum is changed, PTE encode would be broken. + * In case this enum is changed, PTE encode would be broken. * Add a WARNING here. And remove when we completely quit using this - * enum + * enum. */ BUILD_BUG_ON(I915_CACHE_NONE != 0 || I915_CACHE_LLC != 1 || diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 202eb1b6ae54d..f98e5cc14724b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1233,7 +1233,7 @@ int intel_irq_install(struct drm_i915_private *dev_priv) } /** - * intel_irq_uninstall - finilizes all irq handling + * intel_irq_uninstall - finalizes all irq handling * @dev_priv: i915 device instance * * This stops interrupt and hotplug handling and unregisters and frees all diff --git a/drivers/gpu/drm/i915/i915_module.c b/drivers/gpu/drm/i915/i915_module.c index 7ed6d70389af9..2f88970cc0a93 100644 --- a/drivers/gpu/drm/i915/i915_module.c +++ b/drivers/gpu/drm/i915/i915_module.c @@ -24,7 +24,7 @@ static int i915_check_nomodeset(void) bool use_kms = true; /* - * Enable KMS by default, unless explicitly overriden by + * Enable KMS by default, unless explicitly overridden by * either the i915.modeset parameter or by the * nomodeset boot option. */ diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 2406cda75b7b4..eb7b4e21b1246 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -548,7 +548,8 @@ static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream) bool pollin; u32 partial_report_size; - /* We have to consider the (unlikely) possibility that read() errors + /* + * We have to consider the (unlikely) possibility that read() errors * could result in an OA buffer reset which might reset the head and * tail state. */ @@ -557,7 +558,8 @@ static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream) hw_tail = stream->perf->ops.oa_hw_tail_read(stream); hw_tail -= gtt_offset; - /* The tail pointer increases in 64 byte increments, not in report_size + /* + * The tail pointer increases in 64 byte increments, not in report_size * steps. Also the report size may not be a power of 2. Compute * potentially partially landed report in the OA buffer */ @@ -569,8 +571,9 @@ static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream) tail = hw_tail; - /* Walk the stream backward until we find a report with report - * id and timestmap not at 0. Since the circular buffer pointers + /* + * Walk the stream backward until we find a report with report + * id and timestamp not at 0. Since the circular buffer pointers * progress by increments of 64 bytes and that reports can be up * to 256 bytes long, we can't tell whether a report has fully * landed in memory before the report id and timestamp of the @@ -3849,7 +3852,7 @@ i915_perf_open_ioctl_locked(struct i915_perf *perf, } /* - * Asking for SSEU configuration is a priviliged operation. + * Asking for SSEU configuration is a privileged operation. */ if (props->has_sseu) privileged_op = true; @@ -4478,14 +4481,16 @@ static bool gen12_is_valid_mux_addr(struct i915_perf *perf, u32 addr) static u32 mask_reg_value(u32 reg, u32 val) { - /* HALF_SLICE_CHICKEN2 is programmed with a the + /* + * HALF_SLICE_CHICKEN2 is programmed with a the * WaDisableSTUnitPowerOptimization workaround. Make sure the value * programmed by userspace doesn't change this. */ if (REG_EQUAL(reg, HALF_SLICE_CHICKEN2)) val = val & ~_MASKED_BIT_ENABLE(GEN8_ST_PO_DISABLE); - /* WAIT_FOR_RC6_EXIT has only one bit fullfilling the function + /* + * WAIT_FOR_RC6_EXIT has only one bit fulfilling the function * indicated by its name and a bunch of selection fields used by OA * configs. */ diff --git a/drivers/gpu/drm/i915/i915_pmu.h b/drivers/gpu/drm/i915/i915_pmu.h index 8e66d63d0c9f9..0ec78c2b4f203 100644 --- a/drivers/gpu/drm/i915/i915_pmu.h +++ b/drivers/gpu/drm/i915/i915_pmu.h @@ -103,7 +103,7 @@ struct i915_pmu { /** * @timer_last: * - * Timestmap of the previous timer invocation. + * Timestamp of the previous timer invocation. */ ktime_t timer_last; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 765e6c0528fb0..b9e2aa1c6f8af 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -84,7 +84,7 @@ * Try to name registers according to the specs. If the register name changes in * the specs from platform to another, stick to the original name. * - * Try to re-use existing register macro definitions. Only add new macros for + * Try to reuse existing register macro definitions. Only add new macros for * new register offsets, or when the register contents have changed enough to * warrant a full redefinition. * @@ -492,8 +492,9 @@ #define MBUS_ABOX_BT_CREDIT_POOL1_MASK (0x1F << 0) #define MBUS_ABOX_BT_CREDIT_POOL1(x) ((x) << 0) -/* Make render/texture TLB fetches lower priorty than associated data - * fetches. This is not turned on by default +/* + * Make render/texture TLB fetches lower priority than associated data + * fetches. This is not turned on by default. */ #define MI_ARB_RENDER_TLB_LOW_PRIORITY (1 << 15) diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 8f62cfa23fb76..f8c584ce3295e 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -473,7 +473,7 @@ static bool __request_in_flight(const struct i915_request *signal) * to avoid tearing.] * * Note that the read of *execlists->active may race with the promotion - * of execlists->pending[] to execlists->inflight[], overwritting + * of execlists->pending[] to execlists->inflight[], overwriting * the value at *execlists->active. This is fine. The promotion implies * that we received an ACK from the HW, and so the context is not * stuck -- if we do not see ourselves in *active, the inflight status diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 0ac55b2e4223e..5f7e8138ec146 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -161,7 +161,7 @@ enum { * parent-child relationship (parallel submission, multi-lrc) that * hit an error while generating requests in the execbuf IOCTL. * Indicates this request should be skipped as another request in - * submission / relationship encoutered an error. + * submission / relationship encountered an error. */ I915_FENCE_FLAG_SKIP_PARALLEL, @@ -187,7 +187,7 @@ enum { * RCU lookup of it that may race against reallocation of the struct * from the slab freelist. We intentionally do not zero the structure on * allocation so that the lookup can use the dangling pointers (and is - * cogniscent that those pointers may be wrong). Instead, everything that + * cognisant that those pointers may be wrong). Instead, everything that * needs to be initialised must be done so explicitly. * * The requests are reference counted. diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 776f8cc51b2fc..61b49007ecd48 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -778,8 +778,8 @@ bool i915_gem_valid_gtt_space(struct i915_vma *vma, unsigned long color) * @flags: mask of PIN_* flags to use * * First we try to allocate some free space that meets the requirements for - * the VMA. Failiing that, if the flags permit, it will evict an old VMA, - * preferrably the oldest idle entry to make room for the new VMA. + * the VMA. Failing that, if the flags permit, it will evict an old VMA, + * preferably the oldest idle entry to make room for the new VMA. * * Returns: * 0 on success, negative error code otherwise. @@ -877,7 +877,7 @@ i915_vma_insert(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, * objects which need to be tightly packed into the low 32bits. * * Note that we assume that GGTT are limited to 4GiB for the - * forseeable future. See also i915_ggtt_offset(). + * foreseeable future. See also i915_ggtt_offset(). */ if (upper_32_bits(end - 1) && vma->page_sizes.sg > I915_GTT_PAGE_SIZE && @@ -1001,7 +1001,7 @@ rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset, /* * The DE ignores the PTEs for the padding tiles, the sg entry - * here is just a conenience to indicate how many padding PTEs + * here is just a convenience to indicate how many padding PTEs * to insert at this spot. */ sg_set_page(sg, NULL, left, 0); diff --git a/drivers/gpu/drm/i915/intel_clock_gating.c b/drivers/gpu/drm/i915/intel_clock_gating.c index f76642886569e..387b264001690 100644 --- a/drivers/gpu/drm/i915/intel_clock_gating.c +++ b/drivers/gpu/drm/i915/intel_clock_gating.c @@ -682,7 +682,7 @@ static void i85x_init_clock_gating(struct drm_i915_private *i915) * Have FBC ignore 3D activity since we use software * render tracking, and otherwise a pure 3D workload * (even if it just renders a single frame and then does - * abosultely nothing) would not allow FBC to recompress + * absolutely nothing) would not allow FBC to recompress * until a 2D blit occurs. */ intel_uncore_write(&i915->uncore, SCPD0, diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c index a5383a2bc64b9..dae9dce7d1b3d 100644 --- a/drivers/gpu/drm/i915/intel_gvt.c +++ b/drivers/gpu/drm/i915/intel_gvt.c @@ -265,7 +265,7 @@ void intel_gvt_driver_remove(struct drm_i915_private *dev_priv) } /** - * intel_gvt_resume - GVT resume routine wapper + * intel_gvt_resume - GVT resume routine wrapper * * @dev_priv: drm i915 private * * diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c index ee1cd2126f97b..04076316e1397 100644 --- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c +++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c @@ -1260,7 +1260,7 @@ static int iterate_bxt_mmio(struct intel_gvt_mmio_table_iter *iter) /** * intel_gvt_iterate_mmio_table - Iterate the GVT MMIO table - * @iter: the interator + * @iter: the iterator * * This function is called for iterating the GVT MMIO table when i915 is * taking the snapshot of the HW and GVT is building MMIO tracking table. diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 1a47ecfd3fd87..8d9f4c410546e 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -375,7 +375,7 @@ void intel_runtime_pm_enable(struct intel_runtime_pm *rpm) * leave the device suspended skipping the driver's suspend handlers * if the device was already runtime suspended. This is needed due to * the difference in our runtime and system suspend sequence and - * becaue the HDA driver may require us to enable the audio power + * because the HDA driver may require us to enable the audio power * domain during system suspend. */ dev_pm_set_driver_flags(kdev, DPM_FLAG_NO_DIRECT_COMPLETE); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.h b/drivers/gpu/drm/i915/intel_runtime_pm.h index e22669d61e954..7428bd8fa67f4 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.h +++ b/drivers/gpu/drm/i915/intel_runtime_pm.h @@ -31,7 +31,7 @@ struct drm_printer; * it can be changed with the standard runtime PM files from sysfs. * * The irqs_disabled variable becomes true exactly after we disable the IRQs and - * goes back to false exactly before we reenable the IRQs. We use this variable + * goes back to false exactly before we re-enable the IRQs. We use this variable * to check if someone is trying to enable/disable IRQs while they're supposed * to be disabled. This shouldn't happen and we'll print some error messages in * case it happens. diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index eed4937c3ff30..04ef628e208b3 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -2477,7 +2477,7 @@ static int sanity_check_mmio_access(struct intel_uncore *uncore) /* * Sanitycheck that MMIO access to the device is working properly. If - * the CPU is unable to communcate with a PCI device, BAR reads will + * the CPU is unable to communicate with a PCI device, BAR reads will * return 0xFFFFFFFF. Let's make sure the device isn't in this state * before we start trying to access registers. * From 8c27c4e90e3670970f51bf35051c58bf5b05ed49 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Mon, 20 Jan 2025 22:52:02 +0530 Subject: [PATCH 097/284] drm/i915/scaler: Add and compute scaling factors Add scaling factors to scaler_state for a particular scaler user. These factors will be used later to compute scaler prefill latency. Currently, only plane scaling factors are stored, but the same members can later be extended to store pipe scaling factors as well. --v2: - Rephrase commit message. [Ankit] - Corrects typos. [Ankit] Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250120172209.188488-2-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 2 ++ drivers/gpu/drm/i915/display/skl_scaler.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 96429201b8a01..cb51b7936f933 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -711,6 +711,8 @@ struct intel_initial_plane_config { struct intel_scaler { u32 mode; bool in_use; + int hscale; + int vscale; }; struct intel_crtc_scaler_state { diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 515196e03b937..b960cba31043c 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -434,6 +434,9 @@ static int intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_stat return -EINVAL; } + + scaler_state->scalers[*scaler_id].hscale = hscale; + scaler_state->scalers[*scaler_id].vscale = vscale; } drm_dbg_kms(display->drm, "[CRTC:%d:%s] attached scaler id %u.%u to %s:%d\n", From f42da9aa863eaea4e37865959ed81a60c3df72b5 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Mon, 20 Jan 2025 22:52:03 +0530 Subject: [PATCH 098/284] drm/i915/scaler: Use crtc_state to setup plane or pipe scaler Pass crtc_state to intel_atomic_setup_scaler, this will help to check if pch_pfit enabled or not and also will be useful to pass scaler_state with the same which will be used later to store hscale and vscale values. -- v2: - Fix typos. (Ankit) Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250120172209.188488-3-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/skl_scaler.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index b960cba31043c..24514cb3c6059 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -319,13 +319,15 @@ static int intel_allocate_scaler(struct intel_crtc_scaler_state *scaler_state, return -1; } -static int intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state, +static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, int num_scalers_need, struct intel_crtc *crtc, const char *name, int idx, struct intel_plane_state *plane_state, int *scaler_id) { struct intel_display *display = to_intel_display(crtc); + struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 mode; @@ -455,7 +457,7 @@ static int setup_crtc_scaler(struct intel_atomic_state *state, struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state; - return intel_atomic_setup_scaler(scaler_state, + return intel_atomic_setup_scaler(crtc_state, hweight32(scaler_state->scaler_users), crtc, "CRTC", crtc->base.base.id, NULL, &scaler_state->scaler_id); @@ -490,7 +492,7 @@ static int setup_plane_scaler(struct intel_atomic_state *state, if (IS_ERR(plane_state)) return PTR_ERR(plane_state); - return intel_atomic_setup_scaler(scaler_state, + return intel_atomic_setup_scaler(crtc_state, hweight32(scaler_state->scaler_users), crtc, "PLANE", plane->base.base.id, plane_state, &plane_state->scaler_id); From cabb162f7b7d2a012c80ecc13e5e75c0d01d6dde Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Mon, 20 Jan 2025 22:52:04 +0530 Subject: [PATCH 099/284] drm/i915/scaler: Refactor max_scale computation Refactor max scaling factor computation into a reusable function for scalers. --v2: - Add missing comment. [Ankit] Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250120172209.188488-4-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/skl_scaler.c | 70 +++++++++++++---------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 24514cb3c6059..3465f7878ed5b 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -319,6 +319,44 @@ static int intel_allocate_scaler(struct intel_crtc_scaler_state *scaler_state, return -1; } +static void +calculate_max_scale(struct intel_crtc *crtc, + bool is_yuv_semiplanar, + int scaler_id, + int *max_hscale, int *max_vscale) +{ + struct intel_display *display = to_intel_display(crtc); + + /* + * FIXME: When two scalers are needed, but only one of + * them needs to downscale, we should make sure that + * the one that needs downscaling support is assigned + * as the first scaler, so we don't reject downscaling + * unnecessarily. + */ + + if (DISPLAY_VER(display) >= 14) { + /* + * On versions 14 and up, only the first + * scaler supports a vertical scaling factor + * of more than 1.0, while a horizontal + * scaling factor of 3.0 is supported. + */ + *max_hscale = 0x30000 - 1; + + if (scaler_id == 0) + *max_vscale = 0x30000 - 1; + else + *max_vscale = 0x10000; + } else if (DISPLAY_VER(display) >= 10 || !is_yuv_semiplanar) { + *max_hscale = 0x30000 - 1; + *max_vscale = 0x30000 - 1; + } else { + *max_hscale = 0x20000 - 1; + *max_vscale = 0x20000 - 1; + } +} + static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, int num_scalers_need, struct intel_crtc *crtc, const char *name, int idx, @@ -388,35 +426,9 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, const struct drm_rect *dst = &plane_state->uapi.dst; int hscale, vscale, max_vscale, max_hscale; - /* - * FIXME: When two scalers are needed, but only one of - * them needs to downscale, we should make sure that - * the one that needs downscaling support is assigned - * as the first scaler, so we don't reject downscaling - * unnecessarily. - */ - - if (DISPLAY_VER(display) >= 14) { - /* - * On versions 14 and up, only the first - * scaler supports a vertical scaling factor - * of more than 1.0, while a horizontal - * scaling factor of 3.0 is supported. - */ - max_hscale = 0x30000 - 1; - if (*scaler_id == 0) - max_vscale = 0x30000 - 1; - else - max_vscale = 0x10000; - - } else if (DISPLAY_VER(display) >= 10 || - !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) { - max_hscale = 0x30000 - 1; - max_vscale = 0x30000 - 1; - } else { - max_hscale = 0x20000 - 1; - max_vscale = 0x20000 - 1; - } + calculate_max_scale(crtc, + intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier), + *scaler_id, &max_hscale, &max_vscale); /* * FIXME: We should change the if-else block above to From 9217f9aaef62236da37f6e915047352d114eff77 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 21 Jan 2025 23:28:56 +0530 Subject: [PATCH 100/284] drm/i915/scaler: Compute scaling factors for pipe scaler Compute scaling factors and scaler user for pipe scaler if particular scaler user is pipe scaler. --v2: - Fix typos. [Ankit] - Remove FIXME tag. [Ankit] - Should be common hscale, vscale instead of local one to avoid garbage overwritten. --v3: - Separate out max_scaling information. [Ankit] - Use max_hscale and max_vscale info instead of INT_MAX. [Ankit] --v4: - Add Suggested changes reported by Dan Carpenter. Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250121175856.447245-1-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/skl_scaler.c | 39 +++++++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 3465f7878ed5b..54f9adba4ac06 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -368,6 +368,8 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, &crtc_state->scaler_state; struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 mode; + int hscale = 0; + int vscale = 0; if (*scaler_id < 0) *scaler_id = intel_allocate_scaler(scaler_state, crtc); @@ -416,15 +418,11 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, mode = SKL_PS_SCALER_MODE_DYN; } - /* - * FIXME: we should also check the scaler factors for pfit, so - * this shouldn't be tied directly to planes. - */ if (plane_state && plane_state->hw.fb) { const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_rect *src = &plane_state->uapi.src; const struct drm_rect *dst = &plane_state->uapi.dst; - int hscale, vscale, max_vscale, max_hscale; + int max_hscale, max_vscale; calculate_max_scale(crtc, intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier), @@ -448,11 +446,38 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, return -EINVAL; } + } + + if (crtc_state->pch_pfit.enabled) { + struct drm_rect src; + int max_hscale, max_vscale; + + drm_rect_init(&src, 0, 0, + drm_rect_width(&crtc_state->pipe_src) << 16, + drm_rect_height(&crtc_state->pipe_src) << 16); + + calculate_max_scale(crtc, 0, *scaler_id, + &max_hscale, &max_vscale); - scaler_state->scalers[*scaler_id].hscale = hscale; - scaler_state->scalers[*scaler_id].vscale = vscale; + hscale = drm_rect_calc_hscale(&src, &crtc_state->pch_pfit.dst, + 0, max_hscale); + vscale = drm_rect_calc_vscale(&src, &crtc_state->pch_pfit.dst, + 0, max_vscale); + + if (hscale < 0 || vscale < 0) { + drm_dbg_kms(display->drm, + "Scaler %d doesn't support required pipe scaling\n", + *scaler_id); + drm_rect_debug_print("src: ", &src, true); + drm_rect_debug_print("dst: ", &crtc_state->pch_pfit.dst, false); + + return -EINVAL; + } } + scaler_state->scalers[*scaler_id].hscale = hscale; + scaler_state->scalers[*scaler_id].vscale = vscale; + drm_dbg_kms(display->drm, "[CRTC:%d:%s] attached scaler id %u.%u to %s:%d\n", crtc->base.base.id, crtc->base.name, crtc->pipe, *scaler_id, name, idx); From 65599f65b4f1538f335ef4ae7612302a4183cb5e Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Mon, 20 Jan 2025 22:52:06 +0530 Subject: [PATCH 101/284] drm/i915/scaler: Limit pipe scaler downscaling factors for YUV420 Limit downscaling to less than 1.5 (source/destination) in the horizontal direction and 1.0 in the vertical direction, When configured for Pipe YUV 420 encoding for port output. Bspec: 50441, 7490, 69901 Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250120172209.188488-6-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/skl_scaler.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 54f9adba4ac06..c8bf6fd92ce8d 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -459,6 +459,16 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, calculate_max_scale(crtc, 0, *scaler_id, &max_hscale, &max_vscale); + /* + * When configured for Pipe YUV 420 encoding for port output, + * limit downscaling to less than 1.5 (source/destination) in + * the horizontal direction and 1.0 in the vertical direction. + */ + if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) { + max_hscale = 0x18000 - 1; + max_vscale = 0x10000; + } + hscale = drm_rect_calc_hscale(&src, &crtc_state->pch_pfit.dst, 0, max_hscale); vscale = drm_rect_calc_vscale(&src, &crtc_state->pch_pfit.dst, From 9159b622ad629e6415467130dad39dd83e7b6324 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Mon, 20 Jan 2025 22:52:07 +0530 Subject: [PATCH 102/284] drm/i915/scaler: Check if vblank is sufficient for scaler High refresh rate panels which may have small line times and vblank sizes, Check if vblank size is sufficient for enabled scaler users. --v2: - Use hweight* family of functions for counting bits. [Jani] - Update precision handling for hscale and vscale. [Ankit] - Consider chroma downscaling factor during latency calculation. [Ankit] - Replace function name from scaler_prefill_time to scaler_prefill_latency. --v3: - hscale_k and vscale_k values are already left shifted by 16, after multiplying by 1000, those need to be right shifted to 16. [Ankit] - Replace YCBCR444 to YCBCR420. [Ankit] - Divide by 1000 * 1000 in end to get correct precision. [Ankit] - Initialise latency to 0 to avoid any garbage. --v4: - Elaborate commit message and add Bspec number. [Ankit] - Improvise latency calculation. [Ankit] - Use ceiling value for down scaling factor when less than 1 as per bspec. [Ankit] - Correct linetime calculation. [Ankit] - Consider cdclk prefill adjustment while prefill computation.[Ankit] --v5: - Add Bspec link in commit message trailer. [Ankit] - Correct hscale, vscale data type. - Use intel_crtc_compute_min_cdclk. [Ankit] --v6: - Update FIXME comment. - Use cdclk_state->logical.cdclk instead of intel_crtc_compute_min_cdclk. [Ankit] --v7: - Handle error return from cdclk_prefill_adjustment. [Ankit] - Avoid incorrect round off for linetime. [Ankit] - Correct precision. [Ankit] --v8: - Remove redundancy calculation added from previous patch. [Ankit] Bspec: 70151 Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250120172209.188488-7-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/skl_watermark.c | 53 +++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 2bc6251e93d6b..a2580112b50bc 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -2292,6 +2292,56 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state, return 0; } +static int +cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct intel_atomic_state *state = + to_intel_atomic_state(crtc_state->uapi.state); + const struct intel_cdclk_state *cdclk_state; + + cdclk_state = intel_atomic_get_cdclk_state(state); + if (IS_ERR(cdclk_state)) { + drm_WARN_ON(display->drm, PTR_ERR(cdclk_state)); + return 1; + } + + return min(1, DIV_ROUND_UP(crtc_state->pixel_rate, + 2 * cdclk_state->logical.cdclk)); +} + +static int +scaler_prefill_latency(const struct intel_crtc_state *crtc_state) +{ + const struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; + int num_scaler_users = hweight32(scaler_state->scaler_users); + int scaler_prefill_latency = 0; + int linetime = DIV_ROUND_UP(1000 * crtc_state->hw.adjusted_mode.htotal, + crtc_state->hw.adjusted_mode.clock); + + if (!num_scaler_users) + return scaler_prefill_latency; + + scaler_prefill_latency = 4 * linetime; + + if (num_scaler_users > 1) { + u64 hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].hscale, 1000) >> 16); + u64 vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].vscale, 1000) >> 16); + int chroma_downscaling_factor = + crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 2 : 1; + int latency; + + latency = DIV_ROUND_UP_ULL((4 * linetime * hscale_k * vscale_k * + chroma_downscaling_factor), 1000000); + scaler_prefill_latency += latency; + } + + scaler_prefill_latency *= cdclk_prefill_adjustment(crtc_state); + + return intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, scaler_prefill_latency); +} + static bool skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state, int wm0_lines, int latency) @@ -2299,9 +2349,10 @@ skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - /* FIXME missing scaler and DSC pre-fill time */ + /* FIXME missing DSC pre-fill time */ return crtc_state->framestart_delay + intel_usecs_to_scanlines(adjusted_mode, latency) + + scaler_prefill_latency(crtc_state) + wm0_lines > adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vblank_start; } From a9b14af999b058ee9371d3d8fa02245339da7302 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Mon, 20 Jan 2025 22:52:08 +0530 Subject: [PATCH 103/284] drm/i915/dsc: Check if vblank is sufficient for dsc prefill High refresh rate panels which may have small line times and vblank sizes, Check if vblank size is sufficient for dsc prefill latency. --v2: - Consider chroma downscaling factor in latency calculation. [Ankit] - Replace with appropriate function name. --v3: - Remove FIXME tag.[Ankit] - Replace Ycbcr444 to Ycbcr420.[Ankit] - Correct precision. [Ankit] - Use some local valiables like linetime_factor and latency to adjust precision. - Declare latency to 0 initially to avoid returning any garbage values. - Account for second scaler downscaling factor as well. [Ankit] --v4: - Improvise hscale and vscale calculation. [Ankit] - Use appropriate name for number of scaler users. [Ankit] - Update commit message and rebase. - Add linetime and cdclk prefill adjustment calculation. [Ankit] --v5: - Update bspec link in trailer. [Ankit] - Correct hscale, vscale datatype. [Ankit] - Use intel_crtc_compute_min_cdclk. [Ankit] --v6: - Use cdclk_state->logical.cdclk instead of intel_crtc_compute_min_cdclk. [Ankit] --v7: - Fix linetime calculation. [Ankit] - Reduce redandancy use of variables. [Ankit] - Fix typos. [Ankit] - Update calculation for precision. [Ankit] --v8: - Initialise variable to return garbage later. [Ankit] - Initialise few variables to use at local loop, where it is used. [Ankit] Bspec: 70151 Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250120172209.188488-8-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/skl_watermark.c | 33 +++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index a2580112b50bc..45fe4aaeb450e 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -2310,6 +2310,37 @@ cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state) 2 * cdclk_state->logical.cdclk)); } +static int +dsc_prefill_latency(const struct intel_crtc_state *crtc_state) +{ + const struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; + int linetime = DIV_ROUND_UP(1000 * crtc_state->hw.adjusted_mode.htotal, + crtc_state->hw.adjusted_mode.clock); + int num_scaler_users = hweight32(scaler_state->scaler_users); + int chroma_downscaling_factor = + crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 2 : 1; + u32 dsc_prefill_latency = 0; + + if (!crtc_state->dsc.compression_enable || !num_scaler_users) + return dsc_prefill_latency; + + dsc_prefill_latency = DIV_ROUND_UP(15 * linetime * chroma_downscaling_factor, 10); + + for (int i = 0; i < num_scaler_users; i++) { + u64 hscale_k, vscale_k; + + hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[i].hscale, 1000) >> 16); + vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[i].vscale, 1000) >> 16); + dsc_prefill_latency = DIV_ROUND_UP_ULL(dsc_prefill_latency * hscale_k * vscale_k, + 1000000); + } + + dsc_prefill_latency *= cdclk_prefill_adjustment(crtc_state); + + return intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, dsc_prefill_latency); +} + static int scaler_prefill_latency(const struct intel_crtc_state *crtc_state) { @@ -2349,10 +2380,10 @@ skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - /* FIXME missing DSC pre-fill time */ return crtc_state->framestart_delay + intel_usecs_to_scanlines(adjusted_mode, latency) + scaler_prefill_latency(crtc_state) + + dsc_prefill_latency(crtc_state) + wm0_lines > adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vblank_start; } From b5d97b2db08f0143202bed897874e6563c0310ab Mon Sep 17 00:00:00 2001 From: Nemesa Garg Date: Thu, 26 Dec 2024 11:36:32 +0530 Subject: [PATCH 104/284] drm/i915/display: Add WA_14018221282 It was observed that the first write to DKL PHY DP Mode register was not taking effect, hence rewrite this register. v2: Rename function [Mitul] v3: Rename function [Jani] v4: Add check for display ver 13 [Matt] Co-developed-by: Vandita Kulkarni Signed-off-by: Vandita Kulkarni Signed-off-by: Nemesa Garg Reviewed-by: Mika Kahola Signed-off-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20241226060632.213790-1-nemesa.garg@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 05df8f9864912..dc319f37b1be9 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2120,10 +2120,21 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) encoder->disable_clock(encoder); } +static void +tgl_dkl_phy_check_and_rewrite(struct drm_i915_private *dev_priv, + enum tc_port tc_port, u32 ln0, u32 ln1) +{ + if (ln0 != intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 0))) + intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 0), ln0); + if (ln1 != intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 1))) + intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 1), ln1); +} + static void icl_program_mg_dp_mode(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); enum tc_port tc_port = intel_encoder_to_tc(&dig_port->base); u32 ln0, ln1, pin_assignment; @@ -2201,6 +2212,10 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port, if (DISPLAY_VER(dev_priv) >= 12) { intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 0), ln0); intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 1), ln1); + /* WA_14018221282 */ + if (IS_DISPLAY_VER(display, 12, 13)) + tgl_dkl_phy_check_and_rewrite(dev_priv, tc_port, ln0, ln1); + } else { intel_de_write(dev_priv, MG_DP_MODE(0, tc_port), ln0); intel_de_write(dev_priv, MG_DP_MODE(1, tc_port), ln1); From d33847a0fe83b04718ac4d7715d128001161b221 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 22 Jan 2025 11:00:23 +0530 Subject: [PATCH 105/284] drm/i915/cx0: Set ssc_enabled for c20 too ssc_enabled does not get set for c20 phy. We makes sure we set ssc_enabled for both c10 and c20. Bspec: 74491 Signed-off-by: Suraj Kandpal Reviewed-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250122053022.1544881-1-suraj.kandpal@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20250122053022.1544881-1-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 39c98549ac4ea..144d4311c0e8b 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -2021,21 +2021,27 @@ intel_c10pll_tables_get(struct intel_crtc_state *crtc_state, return NULL; } -static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state, +static void intel_cx0pll_update_ssc(struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); struct intel_cx0pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll; - int i; if (intel_crtc_has_dp_encoder(crtc_state)) { if (intel_panel_use_ssc(display)) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - pll_state->ssc_enabled = (intel_dp->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5); } } +} + +static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state, + struct intel_encoder *encoder) +{ + struct intel_display *display = to_intel_display(encoder); + struct intel_cx0pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll; + int i; if (pll_state->ssc_enabled) return; @@ -2058,6 +2064,7 @@ static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state, for (i = 0; tables[i]; i++) { if (crtc_state->port_clock == tables[i]->clock) { crtc_state->dpll_hw_state.cx0pll.c10 = *tables[i]; + intel_cx0pll_update_ssc(crtc_state, encoder); intel_c10pll_update_pll(crtc_state, encoder); crtc_state->dpll_hw_state.cx0pll.use_c10 = true; @@ -2327,6 +2334,7 @@ static int intel_c20pll_calc_state(struct intel_crtc_state *crtc_state, for (i = 0; tables[i]; i++) { if (crtc_state->port_clock == tables[i]->clock) { crtc_state->dpll_hw_state.cx0pll.c20 = *tables[i]; + intel_cx0pll_update_ssc(crtc_state, encoder); crtc_state->dpll_hw_state.cx0pll.use_c10 = false; return 0; } From f14d81b7102bdbf062f90b3910e986850f5f86c2 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Fri, 24 Jan 2025 14:38:14 -0300 Subject: [PATCH 106/284] drm/i915/cmtg: Disable the CMTG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CMTG is a timing generator that runs in parallel with transcoders timing generators and can be used as a reference for synchronization. We have observed that we are inheriting from GOP a display configuration with the CMTG enabled. Because our driver doesn't currently implement any CMTG sequences, the CMTG ends up still enabled after our driver takes over. We need to make sure that the CMTG is not enabled if we are not going to use it. For that, let's add a partial implementation in our driver that only cares about disabling the CMTG if it was found enabled during initial hardware readout. In the future, we can also implement sequences for using the CMTG if that becomes a needed feature. For now, we only deal with cases when it is possible to disable the CMTG without requiring a modeset. For earlier display versions, we simply skip if we find the CMTG enabled and we can't disable it without a proper modeset. In the future, we need to properly handle that case. v2: - DG2 does not have the CMTG. Update HAS_CMTG() accordingly. - Update logic to force disabling of CMTG only for initial commit. v3: - Add missing changes for v2 that were staged but not committed. v4: - Avoid if/else duplication in intel_cmtg_dump_state() by using "n/a" for CMTG B enabled/disabled string for platforms without it. (Jani) - Prefer intel_cmtg_readout_hw_state() over intel_cmtg_readout_state(). (Jani) - Use display struct instead of i915 as first parameter for TRANS_DDI_FUNC_CTL2(). (Jani) - Fewer continuation lines in variable declaration/initialization for better readability. (Jani) - Coding style improvements. (Jani) - Use drm_dbg_kms() instead of drm_info() for logging the disabling of the CMTG. - Make struct intel_cmtg_state entirely private to intel_cmtg.c. v5: - Do the disable sequence as part of the sanitization step after hardware readout instead of initial modeset commit. (Jani) - Adapt to commit 15133582465f ("drm/i915/display: convert global state to struct intel_display") by using a display struct instead of i915 as argument for intel_atomic_global_obj_init(). v6: - Do not track CMTG state as a global state. (Ville) - Simplify the driver logic by only disabling the CMTG only on cases when a modeset is not required. (Ville) v7: - Remove the call to drm_WARN_ON() when checking intel_cmtg_disable_requires_modeset() and use a FIXME in the comment instead. - Remove the !HAS_CMTG() guard from intel_cmtg_get_config(), which is static and its caller is already protected by that same condition. - Also take the opportunity to put some Bspec references in the commit trailers section. v8: - Use HAS_TRANSCODER() instead of intel_crtc_for_pipe(). (Ville) - Ensure transcoder power well is enabled before reading TRANS_DDI_FUNC_CTL2. (Ville) Bspec: 68915, 49262 Cc: Jani Nikula Reviewed-by: Ville Syrjälä Signed-off-by: Gustavo Sousa Link: https://patchwork.freedesktop.org/patch/msgid/20250124173956.46534-1-gustavo.sousa@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/intel_cmtg.c | 190 ++++++++++++++++++ drivers/gpu/drm/i915/display/intel_cmtg.h | 13 ++ .../gpu/drm/i915/display/intel_cmtg_regs.h | 21 ++ .../drm/i915/display/intel_display_device.h | 1 + .../drm/i915/display/intel_modeset_setup.c | 3 + drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/xe/Makefile | 1 + 8 files changed, 231 insertions(+) create mode 100644 drivers/gpu/drm/i915/display/intel_cmtg.c create mode 100644 drivers/gpu/drm/i915/display/intel_cmtg.h create mode 100644 drivers/gpu/drm/i915/display/intel_cmtg_regs.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 4caa8e30bc983..ed05b131ed3ab 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -231,6 +231,7 @@ i915-y += \ display/intel_bo.o \ display/intel_bw.o \ display/intel_cdclk.o \ + display/intel_cmtg.o \ display/intel_color.o \ display/intel_combo_phy.o \ display/intel_connector.o \ diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c b/drivers/gpu/drm/i915/display/intel_cmtg.c new file mode 100644 index 0000000000000..6b6fb82009f52 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright (C) 2025 Intel Corporation + */ + +#include +#include + +#include +#include + +#include "i915_drv.h" +#include "i915_reg.h" +#include "intel_crtc.h" +#include "intel_cmtg.h" +#include "intel_cmtg_regs.h" +#include "intel_de.h" +#include "intel_display_device.h" +#include "intel_display_power.h" + +/** + * DOC: Common Primary Timing Generator (CMTG) + * + * The CMTG is a timing generator that runs in parallel to transcoders timing + * generators (TG) to provide a synchronization mechanism where CMTG acts as + * primary and transcoders TGs act as secondary to the CMTG. The CMTG outputs + * its TG start and frame sync signals to the transcoders that are configured + * as secondary, which use those signals to synchronize their own timing with + * the CMTG's. + * + * The CMTG can be used only with eDP or MIPI command mode and supports the + * following use cases: + * + * - Dual eDP: The CMTG can be used to keep two eDP TGs in sync when on a + * dual eDP configuration (with or without PSR/PSR2 enabled). + * + * - Single eDP as secondary: It is also possible to use a single eDP + * configuration with the transcoder TG as secondary to the CMTG. That would + * allow a flow that would not require a modeset on the existing eDP when a + * new eDP is added for a dual eDP configuration with CMTG. + * + * - DC6v: In DC6v, the transcoder might be off but the CMTG keeps running to + * maintain frame timings. When exiting DC6v, the transcoder TG then is + * synced back the CMTG. + * + * Currently, the driver does not use the CMTG, but we need to make sure that + * we disable it in case we inherit a display configuration with it enabled. + */ + +/* + * We describe here only the minimum data required to allow us to properly + * disable the CMTG if necessary. + */ +struct intel_cmtg_config { + bool cmtg_a_enable; + /* + * Xe2_LPD adds a second CMTG that can be used for dual eDP async mode. + */ + bool cmtg_b_enable; + bool trans_a_secondary; + bool trans_b_secondary; +}; + +static bool intel_cmtg_has_cmtg_b(struct intel_display *display) +{ + return DISPLAY_VER(display) >= 20; +} + +static bool intel_cmtg_has_clock_sel(struct intel_display *display) +{ + return DISPLAY_VER(display) >= 14; +} + +static void intel_cmtg_dump_config(struct intel_display *display, + struct intel_cmtg_config *cmtg_config) +{ + drm_dbg_kms(display->drm, + "CMTG readout: CMTG A: %s, CMTG B: %s, Transcoder A secondary: %s, Transcoder B secondary: %s\n", + str_enabled_disabled(cmtg_config->cmtg_a_enable), + intel_cmtg_has_cmtg_b(display) ? str_enabled_disabled(cmtg_config->cmtg_b_enable) : "n/a", + str_yes_no(cmtg_config->trans_a_secondary), + str_yes_no(cmtg_config->trans_b_secondary)); +} + +static bool intel_cmtg_transcoder_is_secondary(struct intel_display *display, + enum transcoder trans) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + enum intel_display_power_domain power_domain; + intel_wakeref_t wakeref; + u32 val = 0; + + if (!HAS_TRANSCODER(display, trans)) + return false; + + power_domain = POWER_DOMAIN_TRANSCODER(trans); + + with_intel_display_power_if_enabled(i915, power_domain, wakeref) + val = intel_de_read(display, TRANS_DDI_FUNC_CTL2(display, trans)); + + return val & CMTG_SECONDARY_MODE; +} + +static void intel_cmtg_get_config(struct intel_display *display, + struct intel_cmtg_config *cmtg_config) +{ + u32 val; + + val = intel_de_read(display, TRANS_CMTG_CTL_A); + cmtg_config->cmtg_a_enable = val & CMTG_ENABLE; + + if (intel_cmtg_has_cmtg_b(display)) { + val = intel_de_read(display, TRANS_CMTG_CTL_B); + cmtg_config->cmtg_b_enable = val & CMTG_ENABLE; + } + + cmtg_config->trans_a_secondary = intel_cmtg_transcoder_is_secondary(display, TRANSCODER_A); + cmtg_config->trans_b_secondary = intel_cmtg_transcoder_is_secondary(display, TRANSCODER_B); +} + +static bool intel_cmtg_disable_requires_modeset(struct intel_display *display, + struct intel_cmtg_config *cmtg_config) +{ + if (DISPLAY_VER(display) >= 20) + return false; + + return cmtg_config->trans_a_secondary || cmtg_config->trans_b_secondary; +} + +static void intel_cmtg_disable(struct intel_display *display, + struct intel_cmtg_config *cmtg_config) +{ + u32 clk_sel_clr = 0; + u32 clk_sel_set = 0; + + if (cmtg_config->trans_a_secondary) + intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, TRANSCODER_A), + CMTG_SECONDARY_MODE, 0); + + if (cmtg_config->trans_b_secondary) + intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, TRANSCODER_B), + CMTG_SECONDARY_MODE, 0); + + if (cmtg_config->cmtg_a_enable) { + drm_dbg_kms(display->drm, "Disabling CMTG A\n"); + intel_de_rmw(display, TRANS_CMTG_CTL_A, CMTG_ENABLE, 0); + clk_sel_clr |= CMTG_CLK_SEL_A_MASK; + clk_sel_set |= CMTG_CLK_SEL_A_DISABLED; + } + + if (cmtg_config->cmtg_b_enable) { + drm_dbg_kms(display->drm, "Disabling CMTG B\n"); + intel_de_rmw(display, TRANS_CMTG_CTL_B, CMTG_ENABLE, 0); + clk_sel_clr |= CMTG_CLK_SEL_B_MASK; + clk_sel_set |= CMTG_CLK_SEL_B_DISABLED; + } + + if (intel_cmtg_has_clock_sel(display) && clk_sel_clr) + intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, clk_sel_set); +} + +/* + * Read out CMTG configuration and, on platforms that allow disabling it without + * a modeset, do it. + * + * This function must be called before any port PLL is disabled in the general + * sanitization process, because we need whatever port PLL that is providing the + * clock for CMTG to be on before accessing CMTG registers. + */ +void intel_cmtg_sanitize(struct intel_display *display) +{ + struct intel_cmtg_config cmtg_config = {}; + + if (!HAS_CMTG(display)) + return; + + intel_cmtg_get_config(display, &cmtg_config); + intel_cmtg_dump_config(display, &cmtg_config); + + /* + * FIXME: The driver is not prepared to handle cases where a modeset is + * required for disabling the CMTG: we need a proper way of tracking + * CMTG state and do the right syncronization with respect to triggering + * the modeset as part of the disable sequence. + */ + if (intel_cmtg_disable_requires_modeset(display, &cmtg_config)) + return; + + intel_cmtg_disable(display, &cmtg_config); +} diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.h b/drivers/gpu/drm/i915/display/intel_cmtg.h new file mode 100644 index 0000000000000..ba62199adaa21 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_cmtg.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright (C) 2025 Intel Corporation + */ + +#ifndef __INTEL_CMTG_H__ +#define __INTEL_CMTG_H__ + +struct intel_display; + +void intel_cmtg_sanitize(struct intel_display *display); + +#endif /* __INTEL_CMTG_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_cmtg_regs.h b/drivers/gpu/drm/i915/display/intel_cmtg_regs.h new file mode 100644 index 0000000000000..668e41d65e862 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_cmtg_regs.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright (C) 2025 Intel Corporation + */ + +#ifndef __INTEL_CMTG_REGS_H__ +#define __INTEL_CMTG_REGS_H__ + +#include "i915_reg_defs.h" + +#define CMTG_CLK_SEL _MMIO(0x46160) +#define CMTG_CLK_SEL_A_MASK REG_GENMASK(31, 29) +#define CMTG_CLK_SEL_A_DISABLED REG_FIELD_PREP(CMTG_CLK_SEL_A_MASK, 0) +#define CMTG_CLK_SEL_B_MASK REG_GENMASK(15, 13) +#define CMTG_CLK_SEL_B_DISABLED REG_FIELD_PREP(CMTG_CLK_SEL_B_MASK, 0) + +#define TRANS_CMTG_CTL_A _MMIO(0x6fa88) +#define TRANS_CMTG_CTL_B _MMIO(0x6fb88) +#define CMTG_ENABLE REG_BIT(31) + +#endif /* __INTEL_CMTG_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index a7b5ce69cf17d..fc33791f02b9d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -146,6 +146,7 @@ struct intel_display_platforms { #define HAS_BIGJOINER(__display) (DISPLAY_VER(__display) >= 11 && HAS_DSC(__display)) #define HAS_CDCLK_CRAWL(__display) (DISPLAY_INFO(__display)->has_cdclk_crawl) #define HAS_CDCLK_SQUASH(__display) (DISPLAY_INFO(__display)->has_cdclk_squash) +#define HAS_CMTG(__display) (!(__display)->platform.dg2 && DISPLAY_VER(__display) >= 13) #define HAS_CUR_FBC(__display) (!HAS_GMCH(__display) && IS_DISPLAY_VER(__display, 7, 13)) #define HAS_D12_PLANE_MINIMIZATION(__display) ((__display)->platform.rocketlake || (__display)->platform.alderlake_s) #define HAS_DBUF_OVERLAP_DETECTION(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dbuf_overlap_detection) diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 9a2bea19f17b7..10cdfdad82e4f 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -15,6 +15,7 @@ #include "i9xx_wm.h" #include "intel_atomic.h" #include "intel_bw.h" +#include "intel_cmtg.h" #include "intel_color.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" @@ -978,6 +979,8 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, intel_pch_sanitize(i915); + intel_cmtg_sanitize(display); + /* * intel_sanitize_plane_mapping() may need to do vblank * waits, so we need vblank interrupts restored beforehand. diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b9e2aa1c6f8af..03da51b03fb90 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3566,6 +3566,7 @@ enum skl_power_gate { #define _TRANS_DDI_FUNC_CTL2_DSI1 0x6bc04 #define TRANS_DDI_FUNC_CTL2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _TRANS_DDI_FUNC_CTL2_A) #define PORT_SYNC_MODE_ENABLE REG_BIT(4) +#define CMTG_SECONDARY_MODE REG_BIT(3) #define PORT_SYNC_MODE_MASTER_SELECT_MASK REG_GENMASK(2, 0) #define PORT_SYNC_MODE_MASTER_SELECT(x) REG_FIELD_PREP(PORT_SYNC_MODE_MASTER_SELECT_MASK, (x)) diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index f639c9d750234..3a243c4ea79b5 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -199,6 +199,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_bios.o \ i915-display/intel_bw.o \ i915-display/intel_cdclk.o \ + i915-display/intel_cmtg.o \ i915-display/intel_color.o \ i915-display/intel_combo_phy.o \ i915-display/intel_connector.o \ From 2e0727c347467775a2dfa7d850a3a029f3212e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Thu, 17 Oct 2024 10:57:24 +0300 Subject: [PATCH 107/284] drm/i915/lspcon: do not hardcode settle timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid hardcoding the LSPCON settle timeout because it takes a longer time on certain chips made by certain vendors. Use the function that already exists to determine the timeout. Reviewed-by: Ankit Nautiyal Signed-off-by: Giedrius Statkevičius Link: https://patchwork.freedesktop.org/patch/msgid/20241017075725.207384-1-giedriuswork@gmail.com Acked-by: Simona Vetter Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/display/drm_dp_dual_mode_helper.c | 4 ++-- drivers/gpu/drm/i915/display/intel_lspcon.c | 3 ++- include/drm/display/drm_dp_dual_mode_helper.h | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c index c491e3203bf11..4c350c7f51446 100644 --- a/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c +++ b/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c @@ -486,16 +486,16 @@ EXPORT_SYMBOL(drm_lspcon_get_mode); * @dev: &drm_device to use * @adapter: I2C-over-aux adapter * @mode: required mode of operation + * @time_out: LSPCON mode change settle timeout * * Returns: * 0 on success, -error on failure/timeout */ int drm_lspcon_set_mode(const struct drm_device *dev, struct i2c_adapter *adapter, - enum drm_lspcon_mode mode) + enum drm_lspcon_mode mode, int time_out) { u8 data = 0; int ret; - int time_out = 200; enum drm_lspcon_mode current_mode; if (mode == DRM_LSPCON_MODE_PCON) diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index d75dd17fad323..0c8bf477c2fbb 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -212,7 +212,8 @@ static int lspcon_change_mode(struct intel_lspcon *lspcon, return 0; } - err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, ddc, mode); + err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, ddc, mode, + lspcon_get_mode_settle_timeout(lspcon)); if (err < 0) { drm_err(display->drm, "LSPCON mode change failed\n"); return err; diff --git a/include/drm/display/drm_dp_dual_mode_helper.h b/include/drm/display/drm_dp_dual_mode_helper.h index 7ee482265087c..7ac6969db935f 100644 --- a/include/drm/display/drm_dp_dual_mode_helper.h +++ b/include/drm/display/drm_dp_dual_mode_helper.h @@ -117,5 +117,5 @@ const char *drm_dp_get_dual_mode_type_name(enum drm_dp_dual_mode_type type); int drm_lspcon_get_mode(const struct drm_device *dev, struct i2c_adapter *adapter, enum drm_lspcon_mode *current_mode); int drm_lspcon_set_mode(const struct drm_device *dev, struct i2c_adapter *adapter, - enum drm_lspcon_mode reqd_mode); + enum drm_lspcon_mode reqd_mode, int time_out); #endif From 35e1aacfe536d6e8d8d440cd7155366da2541ad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Dec 2024 19:36:47 +0200 Subject: [PATCH 108/284] drm/i915: Drop 64bpp YUV formats from ICL+ SDR planes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'm seeing underruns with these 64bpp YUV formats on TGL. The weird details: - only happens on pipe B/C/D SDR planes, pipe A SDR planes seem fine, as do all HDR planes - somehow CDCLK related, higher CDCLK allows for bigger plane with these formats without underruns. With 300MHz CDCLK I can only go up to 1200 pixels wide or so, with 650MHz even a 3840 pixel wide plane was OK - ICL and ADL so far appear unaffected So not really sure what's the deal with this, but bspec does state "64-bit formats supported only on the HDR planes" so let's just drop these formats from the SDR planes. We already disallow 64bpp RGB formats. Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241218173650.19782-2-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/skl_universal_plane.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 301ad3a22c4c6..ba5db553c3742 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -106,8 +106,6 @@ static const u32 icl_sdr_y_plane_formats[] = { DRM_FORMAT_Y216, DRM_FORMAT_XYUV8888, DRM_FORMAT_XVYU2101010, - DRM_FORMAT_XVYU12_16161616, - DRM_FORMAT_XVYU16161616, }; static const u32 icl_sdr_uv_plane_formats[] = { @@ -134,8 +132,6 @@ static const u32 icl_sdr_uv_plane_formats[] = { DRM_FORMAT_Y216, DRM_FORMAT_XYUV8888, DRM_FORMAT_XVYU2101010, - DRM_FORMAT_XVYU12_16161616, - DRM_FORMAT_XVYU16161616, }; static const u32 icl_hdr_plane_formats[] = { From 9548f4f4bd80d1abbbae3024fdb6a4b2e9a1690a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Dec 2024 19:36:48 +0200 Subject: [PATCH 109/284] drm/i915: Drop the extra "plane" from tracepoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Out plane names already include the "plane" part (or "primary","sprite","cursor" in some cases). Don't duplicate that in the tracepoints as that leadst to weird stuff like "plane plane 1A". Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241218173650.19782-3-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/intel_display_trace.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h index 54a6e2a46b828..989d6f0f3c42a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_trace.h +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -397,7 +397,7 @@ TRACE_EVENT(intel_plane_async_flip, __entry->async_flip = async_flip; ), - TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u, async_flip=%s", + TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, async_flip=%s", __get_str(dev), __entry->pipe_name, __get_str(name), __entry->frame, __entry->scanline, str_yes_no(__entry->async_flip)) ); @@ -426,7 +426,7 @@ TRACE_EVENT(intel_plane_update_noarm, memcpy(__entry->dst, &plane->base.state->dst, sizeof(__entry->dst)); ), - TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT, + TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT, __get_str(dev), __entry->pipe_name, __get_str(name), __entry->frame, __entry->scanline, DRM_RECT_FP_ARG((const struct drm_rect *)__entry->src), @@ -457,7 +457,7 @@ TRACE_EVENT(intel_plane_update_arm, memcpy(__entry->dst, &plane->base.state->dst, sizeof(__entry->dst)); ), - TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT, + TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT, __get_str(dev), __entry->pipe_name, __get_str(name), __entry->frame, __entry->scanline, DRM_RECT_FP_ARG((const struct drm_rect *)__entry->src), @@ -484,7 +484,7 @@ TRACE_EVENT(intel_plane_disable_arm, __entry->scanline = intel_get_crtc_scanline(crtc); ), - TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u", + TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u", __get_str(dev), __entry->pipe_name, __get_str(name), __entry->frame, __entry->scanline) ); @@ -611,7 +611,7 @@ TRACE_EVENT(intel_fbc_activate, __entry->scanline = intel_get_crtc_scanline(crtc); ), - TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u", + TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u", __get_str(dev), __entry->pipe_name, __get_str(name), __entry->frame, __entry->scanline) ); @@ -639,7 +639,7 @@ TRACE_EVENT(intel_fbc_deactivate, __entry->scanline = intel_get_crtc_scanline(crtc); ), - TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u", + TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u", __get_str(dev), __entry->pipe_name, __get_str(name), __entry->frame, __entry->scanline) ); @@ -667,7 +667,7 @@ TRACE_EVENT(intel_fbc_nuke, __entry->scanline = intel_get_crtc_scanline(crtc); ), - TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u", + TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u", __get_str(dev), __entry->pipe_name, __get_str(name), __entry->frame, __entry->scanline) ); From 8cebc86c8275417e03945557bc33a4c9fc8e7824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Dec 2024 19:36:49 +0200 Subject: [PATCH 110/284] drm/i915: Pass the plane state explicitly to tracepoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the plane->state pointer in the tracepoints is incorrect as technically a different state could already have been swapped in (though in reality that is currently prevented by the stall hacks in the commit machinery). But let's not leave such footguns lying around when we can just pass in the correct state by hand. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241218173650.19782-4-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- .../gpu/drm/i915/display/intel_atomic_plane.c | 4 +-- .../drm/i915/display/intel_display_trace.h | 25 ++++++++++--------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index c558143f4f824..651f81ed85abc 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -772,7 +772,7 @@ void intel_plane_update_noarm(struct intel_dsb *dsb, { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - trace_intel_plane_update_noarm(plane, crtc); + trace_intel_plane_update_noarm(plane_state, crtc); if (plane->update_noarm) plane->update_noarm(dsb, plane, crtc_state, plane_state); @@ -802,7 +802,7 @@ void intel_plane_update_arm(struct intel_dsb *dsb, return; } - trace_intel_plane_update_arm(plane, crtc); + trace_intel_plane_update_arm(plane_state, crtc); plane->update_arm(dsb, plane, crtc_state, plane_state); } diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h index 989d6f0f3c42a..4fe65452e5554 100644 --- a/drivers/gpu/drm/i915/display/intel_display_trace.h +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -21,6 +21,7 @@ #include "intel_vblank.h" #define __dev_name_display(display) dev_name((display)->drm->dev) +#define __dev_name_drm(obj) dev_name((obj)->dev->dev) #define __dev_name_kms(obj) dev_name((obj)->base.dev->dev) /* @@ -403,17 +404,17 @@ TRACE_EVENT(intel_plane_async_flip, ); TRACE_EVENT(intel_plane_update_noarm, - TP_PROTO(struct intel_plane *plane, struct intel_crtc *crtc), - TP_ARGS(plane, crtc), + TP_PROTO(const struct intel_plane_state *plane_state, struct intel_crtc *crtc), + TP_ARGS(plane_state, crtc), TP_STRUCT__entry( - __string(dev, __dev_name_kms(plane)) + __string(dev, __dev_name_drm(plane_state->uapi.plane)) __field(char, pipe_name) __field(u32, frame) __field(u32, scanline) __array(int, src, 4) __array(int, dst, 4) - __string(name, plane->base.name) + __string(name, plane_state->uapi.plane->name) ), TP_fast_assign( @@ -422,8 +423,8 @@ TRACE_EVENT(intel_plane_update_noarm, __entry->pipe_name = pipe_name(crtc->pipe); __entry->frame = intel_crtc_get_vblank_counter(crtc); __entry->scanline = intel_get_crtc_scanline(crtc); - memcpy(__entry->src, &plane->base.state->src, sizeof(__entry->src)); - memcpy(__entry->dst, &plane->base.state->dst, sizeof(__entry->dst)); + memcpy(__entry->src, &plane_state->uapi.src, sizeof(__entry->src)); + memcpy(__entry->dst, &plane_state->uapi.dst, sizeof(__entry->dst)); ), TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT, @@ -434,17 +435,17 @@ TRACE_EVENT(intel_plane_update_noarm, ); TRACE_EVENT(intel_plane_update_arm, - TP_PROTO(struct intel_plane *plane, struct intel_crtc *crtc), - TP_ARGS(plane, crtc), + TP_PROTO(const struct intel_plane_state *plane_state, struct intel_crtc *crtc), + TP_ARGS(plane_state, crtc), TP_STRUCT__entry( - __string(dev, __dev_name_kms(plane)) + __string(dev, __dev_name_drm(plane_state->uapi.plane)) __field(char, pipe_name) __field(u32, frame) __field(u32, scanline) __array(int, src, 4) __array(int, dst, 4) - __string(name, plane->base.name) + __string(name, plane_state->uapi.plane->name) ), TP_fast_assign( @@ -453,8 +454,8 @@ TRACE_EVENT(intel_plane_update_arm, __entry->pipe_name = pipe_name(crtc->pipe); __entry->frame = intel_crtc_get_vblank_counter(crtc); __entry->scanline = intel_get_crtc_scanline(crtc); - memcpy(__entry->src, &plane->base.state->src, sizeof(__entry->src)); - memcpy(__entry->dst, &plane->base.state->dst, sizeof(__entry->dst)); + memcpy(__entry->src, &plane_state->uapi.src, sizeof(__entry->src)); + memcpy(__entry->dst, &plane_state->uapi.dst, sizeof(__entry->dst)); ), TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT, From 55f16199c2a95c7c1833daf8c6f2701cc7098023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Dec 2024 19:36:50 +0200 Subject: [PATCH 111/284] drm/i915: Include pixel format in plane tracepoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make debugging a bit easier by including the pixel format in the plane tracepoints. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241218173650.19782-5-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/intel_display_trace.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h index 4fe65452e5554..9e85670b91e3b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_trace.h +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -412,6 +412,7 @@ TRACE_EVENT(intel_plane_update_noarm, __field(char, pipe_name) __field(u32, frame) __field(u32, scanline) + __field(u32, format) __array(int, src, 4) __array(int, dst, 4) __string(name, plane_state->uapi.plane->name) @@ -423,13 +424,14 @@ TRACE_EVENT(intel_plane_update_noarm, __entry->pipe_name = pipe_name(crtc->pipe); __entry->frame = intel_crtc_get_vblank_counter(crtc); __entry->scanline = intel_get_crtc_scanline(crtc); + __entry->format = plane_state->hw.fb->format->format; memcpy(__entry->src, &plane_state->uapi.src, sizeof(__entry->src)); memcpy(__entry->dst, &plane_state->uapi.dst, sizeof(__entry->dst)); ), - TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT, + TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, format=%p4cc, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT, __get_str(dev), __entry->pipe_name, __get_str(name), - __entry->frame, __entry->scanline, + __entry->frame, __entry->scanline, &__entry->format, DRM_RECT_FP_ARG((const struct drm_rect *)__entry->src), DRM_RECT_ARG((const struct drm_rect *)__entry->dst)) ); @@ -443,6 +445,7 @@ TRACE_EVENT(intel_plane_update_arm, __field(char, pipe_name) __field(u32, frame) __field(u32, scanline) + __field(u32, format) __array(int, src, 4) __array(int, dst, 4) __string(name, plane_state->uapi.plane->name) @@ -454,13 +457,14 @@ TRACE_EVENT(intel_plane_update_arm, __entry->pipe_name = pipe_name(crtc->pipe); __entry->frame = intel_crtc_get_vblank_counter(crtc); __entry->scanline = intel_get_crtc_scanline(crtc); + __entry->format = plane_state->hw.fb->format->format; memcpy(__entry->src, &plane_state->uapi.src, sizeof(__entry->src)); memcpy(__entry->dst, &plane_state->uapi.dst, sizeof(__entry->dst)); ), - TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT, + TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, format=%p4cc, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT, __get_str(dev), __entry->pipe_name, __get_str(name), - __entry->frame, __entry->scanline, + __entry->frame, __entry->scanline, &__entry->format, DRM_RECT_FP_ARG((const struct drm_rect *)__entry->src), DRM_RECT_ARG((const struct drm_rect *)__entry->dst)) ); From 8305d47333d8e178890ae4990c7f0c8dbf5f4ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 27 Jan 2025 23:30:55 +0200 Subject: [PATCH 112/284] drm/i915: Give i915 and xe each their own display tracepoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we just define the display tracepoints with TRACE_SYSTEM i915. However the code gets included separately in i915 and xe, and now both modules are competing for the same tracepoints. Apparently whichever module is loaded first gets the tracepoints and the other guy is left with nothing. Give each module its own set of display tracepoints so that things work even when both modules are loaded. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250127213055.640-1-ville.syrjala@linux.intel.com Reviewed-by: Lucas De Marchi Reviewed-by: Jonathan Cavitt --- drivers/gpu/drm/i915/display/intel_display_trace.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h index 9e85670b91e3b..27ebc32cb61a5 100644 --- a/drivers/gpu/drm/i915/display/intel_display_trace.h +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -4,7 +4,11 @@ */ #undef TRACE_SYSTEM +#ifdef I915 #define TRACE_SYSTEM i915 +#else +#define TRACE_SYSTEM xe +#endif #if !defined(__INTEL_DISPLAY_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ) #define __INTEL_DISPLAY_TRACE_H__ From 2dbbbc1740388a8bc4a8237de0b009eecec8f998 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Thu, 30 Jan 2025 10:46:04 +0530 Subject: [PATCH 113/284] drm/i915/vrr: Add crtc_state dump for vrr.vsync params Add crtc_state dump for vrr.vsync_{start/end} params to track the state correctly. --v2: - remove vrr_ pretext and use space instead of underscore (Jani). --v3: - Rebase to latest drm-tip. Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250130051609.1796524-2-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_crtc_state_dump.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 1fbaa67e2fea7..36076e8d639bc 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -292,10 +292,11 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, pipe_config->hw.adjusted_mode.crtc_vdisplay, pipe_config->framestart_delay, pipe_config->msa_timing_delay); - drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d\n", + drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n", str_yes_no(pipe_config->vrr.enable), pipe_config->vrr.vmin, pipe_config->vrr.vmax, pipe_config->vrr.flipline, - pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband); + pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband, + pipe_config->vrr.vsync_start, pipe_config->vrr.vsync_end); drm_printf(&p, "vrr: vmin vblank: %d, vmax vblank: %d, vmin vtotal: %d, vmax vtotal: %d\n", intel_vrr_vmin_vblank_start(pipe_config), intel_vrr_vmax_vblank_start(pipe_config), From 387f269e56eafa461a314a30b4e7f85625b2cba6 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Thu, 30 Jan 2025 10:46:05 +0530 Subject: [PATCH 114/284] drm/i915/vrr: Compute vrr.vsync_{start, end} during full modeset vrr.vsync_{start,end} computation should not depend on crtc_state->vrr.enable. --v1: - Explain commit message more clearly [Jani] - Instead of tweaking to fastset use vrr.flipline while computing AS_SDP. --v2: - Correct computation of vrr.vsync_start/end should not depend on vrr.enable.[ville] - vrr enable disable requirement should not obstruct by SDP enable disable requirements. [Ville] --v3: - Create separate patch for crtc_state_dump [Ankit]. --v4: - Update commit message and header [Ankit]. Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250130051609.1796524-3-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_vrr.c | 25 ++++++++++-------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index b268a0a01cd12..adb51609d0a31 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -299,7 +299,7 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, crtc_state->mode_flags |= I915_MODE_FLAG_VRR; } - if (intel_dp->as_sdp_supported && crtc_state->vrr.enable) { + if (HAS_AS_SDP(display)) { crtc_state->vrr.vsync_start = (crtc_state->hw.adjusted_mode.crtc_vtotal - crtc_state->hw.adjusted_mode.vsync_start); @@ -388,6 +388,12 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state) trans_vrr_ctl(crtc_state)); intel_de_write(display, TRANS_VRR_FLIPLINE(display, cpu_transcoder), crtc_state->vrr.flipline - 1); + + if (HAS_AS_SDP(display)) + intel_de_write(display, + TRANS_VRR_VSYNC(display, cpu_transcoder), + VRR_VSYNC_END(crtc_state->vrr.vsync_end) | + VRR_VSYNC_START(crtc_state->vrr.vsync_start)); } void intel_vrr_send_push(struct intel_dsb *dsb, @@ -432,12 +438,6 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state) intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), TRANS_PUSH_EN); - if (HAS_AS_SDP(display)) - intel_de_write(display, - TRANS_VRR_VSYNC(display, cpu_transcoder), - VRR_VSYNC_END(crtc_state->vrr.vsync_end) | - VRR_VSYNC_START(crtc_state->vrr.vsync_start)); - if (crtc_state->cmrr.enable) { intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), VRR_CTL_VRR_ENABLE | VRR_CTL_CMRR_ENABLE | @@ -462,10 +462,6 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state) TRANS_VRR_STATUS(display, cpu_transcoder), VRR_STATUS_VRR_EN_LIVE, 1000); intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), 0); - - if (HAS_AS_SDP(display)) - intel_de_write(display, - TRANS_VRR_VSYNC(display, cpu_transcoder), 0); } void intel_vrr_get_config(struct intel_crtc_state *crtc_state) @@ -505,10 +501,6 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) TRANS_VRR_VMAX(display, cpu_transcoder)) + 1; crtc_state->vrr.vmin = intel_de_read(display, TRANS_VRR_VMIN(display, cpu_transcoder)) + 1; - } - - if (crtc_state->vrr.enable) { - crtc_state->mode_flags |= I915_MODE_FLAG_VRR; if (HAS_AS_SDP(display)) { trans_vrr_vsync = @@ -520,4 +512,7 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) REG_FIELD_GET(VRR_VSYNC_END_MASK, trans_vrr_vsync); } } + + if (crtc_state->vrr.enable) + crtc_state->mode_flags |= I915_MODE_FLAG_VRR; } From c5806862543ff6c2ad242409fcdf0667eac26dae Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Thu, 30 Jan 2025 10:46:06 +0530 Subject: [PATCH 115/284] drm/i915/dp: fix the Adaptive sync Operation mode for SDP Currently we support Adaptive sync operation mode with dynamic frame rate, but instead the operation mode with fixed rate is set. This was initially set correctly in the earlier version of changes but later got changed, while defining a macro for the same. Fixes: a5bd5991cb8a ("drm/i915/display: Compute AS SDP parameters") Cc: Mitul Golani Cc: Ankit Nautiyal Cc: Jani Nikula Reviewed-by: Mitul Golani Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250130051609.1796524-4-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index c239008658a81..0aeb2d188d80a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2831,7 +2831,6 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC); - /* Currently only DP_AS_SDP_AVT_FIXED_VTOTAL mode supported */ as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC; as_sdp->length = 0x9; as_sdp->duration_incr_ms = 0; @@ -2842,7 +2841,7 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, as_sdp->target_rr = drm_mode_vrefresh(adjusted_mode); as_sdp->target_rr_divider = true; } else { - as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL; + as_sdp->mode = DP_AS_SDP_AVT_DYNAMIC_VTOTAL; as_sdp->vtotal = adjusted_mode->vtotal; as_sdp->target_rr = 0; } From 6218bd2e649ab3bcd097d7903dd4b93baa21c73d Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Thu, 30 Jan 2025 10:46:07 +0530 Subject: [PATCH 116/284] drm/i915/dp: Compute as_sdp.vtotal based on vrr timings Compute as_sdp.vtotal based on minimum vtotal calculated during vrr computation. --v2: - make a separate patch and update to vmin only [Ankit]. --v3: - Update vtotal to vmin for cmrr case as well [Ankit]. --v4: - update vtotal with wrapper function of vmin [Ville] Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250130051609.1796524-5-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0aeb2d188d80a..c9ddf6eb2b254 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2834,15 +2834,14 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC; as_sdp->length = 0x9; as_sdp->duration_incr_ms = 0; + as_sdp->vtotal = intel_vrr_vmin_vtotal(crtc_state); if (crtc_state->cmrr.enable) { as_sdp->mode = DP_AS_SDP_FAVT_TRR_REACHED; - as_sdp->vtotal = adjusted_mode->vtotal; as_sdp->target_rr = drm_mode_vrefresh(adjusted_mode); as_sdp->target_rr_divider = true; } else { as_sdp->mode = DP_AS_SDP_AVT_DYNAMIC_VTOTAL; - as_sdp->vtotal = adjusted_mode->vtotal; as_sdp->target_rr = 0; } } From 08277aa5d5a44befd71717de35b956f55e1e8401 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Thu, 30 Jan 2025 10:46:08 +0530 Subject: [PATCH 117/284] drm/i915/dp: Compute as_sdp based on if vrr possible Adaptive sync sdp param computation, we can configure during full modeset as well when sink is having vrr support, where it doesn't need dependency on vrr.enable status and can also match vrr enable/disable fastset requirement. --v2: - Separate the change from as_sdp.vtotal. [Ankit] Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250130051609.1796524-6-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index c9ddf6eb2b254..dac56fd17a218 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2826,7 +2826,7 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - if (!crtc_state->vrr.enable || !intel_dp->as_sdp_supported) + if (!intel_vrr_possible(crtc_state) || !intel_dp->as_sdp_supported) return; crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC); From e9bb15cdf5c40996bd7b17ecb69fb317629b8efc Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Thu, 30 Jan 2025 10:46:09 +0530 Subject: [PATCH 118/284] drm/i915/display: Move as sdp params change to fastset as_sdp param changes from vrr to cmrr should happen to fastset. Changing as_sdp params should not trigger any modeset. Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250130051609.1796524-7-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 7d68d652c1bc9..60867b5b03ec4 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5752,10 +5752,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_INFOFRAME(avi); PIPE_CONF_CHECK_INFOFRAME(spd); PIPE_CONF_CHECK_INFOFRAME(hdmi); - if (!fastset) + if (!fastset) { PIPE_CONF_CHECK_INFOFRAME(drm); + PIPE_CONF_CHECK_DP_AS_SDP(as_sdp); + } PIPE_CONF_CHECK_DP_VSC_SDP(vsc); - PIPE_CONF_CHECK_DP_AS_SDP(as_sdp); PIPE_CONF_CHECK_X(sync_mode_slaves_mask); PIPE_CONF_CHECK_I(master_transcoder); From 8486de873730683a4b04815aa707d2e4e1028792 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 29 Jan 2025 16:46:33 +0200 Subject: [PATCH 119/284] drm/i915/dp: constify struct link_config_limits pointers The limits get passed around, but are only modified in a few places. Constify the pointers elsewhere so it's easier to follow where they can be modified. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/6ab2f68eef7849aca18e82ad788e44e9f82b576e.1738161945.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 18 +++++++++--------- drivers/gpu/drm/i915/display/intel_dp.h | 2 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index dac56fd17a218..6b64ea7750980 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1941,7 +1941,7 @@ static bool is_bw_sufficient_for_dsc_config(u16 compressed_bppx16, u32 link_cloc static int dsc_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, - struct link_config_limits *limits, + const struct link_config_limits *limits, u16 compressed_bppx16, int timeslots) { @@ -2061,7 +2061,7 @@ static int dsc_src_max_compressed_bpp(struct intel_dp *intel_dp) static int icl_dsc_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, - struct link_config_limits *limits, + const struct link_config_limits *limits, int dsc_max_bpp, int dsc_min_bpp, int pipe_bpp, @@ -2104,7 +2104,7 @@ static int xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, const struct intel_connector *connector, struct intel_crtc_state *pipe_config, - struct link_config_limits *limits, + const struct link_config_limits *limits, int dsc_max_bpp, int dsc_min_bpp, int pipe_bpp, @@ -2153,7 +2153,7 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, const struct intel_connector *connector, struct intel_crtc_state *pipe_config, - struct link_config_limits *limits, + const struct link_config_limits *limits, int pipe_bpp, int timeslots) { @@ -2185,7 +2185,7 @@ int intel_dp_dsc_min_src_input_bpc(void) } static -bool is_dsc_pipe_bpp_sufficient(struct link_config_limits *limits, +bool is_dsc_pipe_bpp_sufficient(const struct link_config_limits *limits, int pipe_bpp) { return pipe_bpp >= limits->pipe.min_bpp && @@ -2194,7 +2194,7 @@ bool is_dsc_pipe_bpp_sufficient(struct link_config_limits *limits, static int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp, - struct link_config_limits *limits) + const struct link_config_limits *limits) { struct intel_display *display = to_intel_display(intel_dp); int forced_bpp; @@ -2220,7 +2220,7 @@ int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp, static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, - struct link_config_limits *limits, + const struct link_config_limits *limits, int timeslots) { const struct intel_connector *connector = @@ -2270,7 +2270,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, - struct link_config_limits *limits) + const struct link_config_limits *limits) { struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = @@ -2335,7 +2335,7 @@ static void intel_dp_fec_compute_config(struct intel_dp *intel_dp, int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, - struct link_config_limits *limits, + const struct link_config_limits *limits, int timeslots, bool compute_pipe_bpp) { diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index ca49f0a05da59..ffc27f8ad2269 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -75,7 +75,7 @@ int intel_dp_compute_config(struct intel_encoder *encoder, int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, - struct link_config_limits *limits, + const struct link_config_limits *limits, int timeslots, bool recompute_pipe_bpp); void intel_dp_audio_compute_config(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 7c1de9aeeacc5..1d5788babcff8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -363,7 +363,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, int max_bpp, int min_bpp, - struct link_config_limits *limits, + const struct link_config_limits *limits, struct drm_connector_state *conn_state, int step, bool dsc) { @@ -388,7 +388,7 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, static int mst_stream_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, - struct link_config_limits *limits) + const struct link_config_limits *limits) { /* * FIXME: allocate the BW according to link_bpp, which in the case of @@ -404,7 +404,7 @@ static int mst_stream_compute_link_config(struct intel_dp *intel_dp, static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, - struct link_config_limits *limits) + const struct link_config_limits *limits) { struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = to_intel_connector(conn_state->connector); From bb322c6fa16f97951d75dba46b9ef0cb2cfcb2d5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 29 Jan 2025 16:46:34 +0200 Subject: [PATCH 120/284] drm/i915/dp: change the order of intel_dp_mtp_tu_compute_config() params Pointers first, bpp params in min, max, step. This is slightly more natural to follow. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/ea9669edc5973cdbca92aeb4e168850015e9d1bb.1738161945.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 8 +++----- drivers/gpu/drm/i915/display/intel_dp_mst.h | 3 +-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 6b64ea7750980..4fe274105c1dd 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2643,9 +2643,9 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, if (!ret && intel_dp_is_uhbr(pipe_config)) ret = intel_dp_mtp_tu_compute_config(intel_dp, pipe_config, + conn_state, pipe_config->pipe_bpp, pipe_config->pipe_bpp, - conn_state, 0, false); if (ret) dsc_needed = true; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 1d5788babcff8..1cb2b8fac296d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -211,9 +211,8 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, - int max_bpp, int min_bpp, struct drm_connector_state *conn_state, - int step, bool dsc) + int min_bpp, int max_bpp, int step, bool dsc) { struct intel_display *display = to_intel_display(intel_dp); struct drm_atomic_state *state = crtc_state->uapi.state; @@ -380,9 +379,8 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, mst_state->pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock, crtc_state->lane_count); - return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, - max_bpp, min_bpp, - conn_state, step, dsc); + return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state, + min_bpp, max_bpp, step, dsc); } static int mst_stream_compute_link_config(struct intel_dp *intel_dp, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h index c6bdc1d190a4a..a713a1c10154a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h @@ -33,8 +33,7 @@ bool intel_dp_mst_verify_dpcd_state(struct intel_dp *intel_dp); int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, - int max_bpp, int min_bpp, struct drm_connector_state *conn_state, - int step, bool dsc); + int min_bpp, int max_bpp, int step, bool dsc); #endif /* __INTEL_DP_MST_H__ */ From f3ee4d5b4392081427cd9c97432fbdfecfae26f5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 29 Jan 2025 16:46:35 +0200 Subject: [PATCH 121/284] drm/i915/mst: change where lane_count and port_clock are set Semantically mst_stream_find_vcpi_slots_for_bpp() does not seem like the place to make decisions about lane_count and port_clock. Move them to the callers, and remove the limits parameter that becomes unused. This leads to slight duplication, but a) this makes further refactoring easier, and b) also the SST code sets link parameters in different places for uncompressed and compressed paths. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/101ce3fc6afff55d966336f3ab72090317750f82.1738161945.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 1cb2b8fac296d..6ba35f6852826 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -362,7 +362,6 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, int max_bpp, int min_bpp, - const struct link_config_limits *limits, struct drm_connector_state *conn_state, int step, bool dsc) { @@ -373,9 +372,6 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, if (IS_ERR(mst_state)) return PTR_ERR(mst_state); - crtc_state->lane_count = limits->max_lane_count; - crtc_state->port_clock = limits->max_rate; - mst_state->pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock, crtc_state->lane_count); @@ -388,6 +384,9 @@ static int mst_stream_compute_link_config(struct intel_dp *intel_dp, struct drm_connector_state *conn_state, const struct link_config_limits *limits) { + crtc_state->lane_count = limits->max_lane_count; + crtc_state->port_clock = limits->max_rate; + /* * FIXME: allocate the BW according to link_bpp, which in the case of * YUV420 is only half of the pipe bpp value. @@ -395,7 +394,6 @@ static int mst_stream_compute_link_config(struct intel_dp *intel_dp, return mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, fxp_q4_to_int(limits->link.max_bpp_x16), fxp_q4_to_int(limits->link.min_bpp_x16), - limits, conn_state, 2 * 3, false); } @@ -453,8 +451,11 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, min_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(display, min_compressed_bpp, crtc_state->pipe_bpp); + crtc_state->lane_count = limits->max_lane_count; + crtc_state->port_clock = limits->max_rate; + return mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, max_compressed_bpp, - min_compressed_bpp, limits, + min_compressed_bpp, conn_state, 1, true); } From 8c271e4d1172a9ebce172aea15edfb222836c57a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 29 Jan 2025 16:46:36 +0200 Subject: [PATCH 122/284] drm/i915/mst: handle mst pbn_div in intel_dp_mtp_tu_compute_config() Move mst_state->pbn_div calculation to intel_dp_mtp_tu_compute_config() to allow further refactoring. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/0cc1b507601c9964ebae7d50b1f90b1ce00acb11.1738161945.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 31 ++++++++++----------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 6ba35f6852826..e596a77270705 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -216,15 +216,25 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); struct drm_atomic_state *state = crtc_state->uapi.state; + struct drm_dp_mst_topology_state *mst_state = NULL; struct intel_connector *connector = to_intel_connector(conn_state->connector); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - fixed20_12 pbn_div; + bool is_mst = intel_dp->is_mst; int bpp, slots = -EINVAL; int dsc_slice_count = 0; int max_dpt_bpp; + if (is_mst) { + mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr); + if (IS_ERR(mst_state)) + return PTR_ERR(mst_state); + + mst_state->pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock, + crtc_state->lane_count); + } + if (dsc) { if (!intel_dp_supports_fec(intel_dp, connector, crtc_state)) return -EINVAL; @@ -232,9 +242,6 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, crtc_state->fec_enable = !intel_dp_is_uhbr(crtc_state); } - pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock, - crtc_state->lane_count); - max_dpt_bpp = intel_dp_mst_max_dpt_bpp(crtc_state, dsc); if (max_bpp > max_dpt_bpp) { drm_dbg_kms(display->drm, "Limiting bpp to max DPT bpp (%d -> %d)\n", @@ -270,7 +277,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, link_bpp_x16, &crtc_state->dp_m_n); - if (intel_dp->is_mst) { + if (is_mst) { int remote_bw_overhead; int remote_tu; fixed20_12 pbn; @@ -295,7 +302,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, pbn.full = dfixed_const(intel_dp_mst_calc_pbn(adjusted_mode->crtc_clock, link_bpp_x16, remote_bw_overhead)); - remote_tu = DIV_ROUND_UP(pbn.full, pbn_div.full); + remote_tu = DIV_ROUND_UP(pbn.full, mst_state->pbn_div.full); /* * Aligning the TUs ensures that symbols consisting of multiple @@ -313,7 +320,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, * allocated for the whole path and the TUs allocated for the * first branch device's link also applies here. */ - pbn.full = remote_tu * pbn_div.full; + pbn.full = remote_tu * mst_state->pbn_div.full; drm_WARN_ON(display->drm, remote_tu < crtc_state->dp_m_n.tu); crtc_state->dp_m_n.tu = remote_tu; @@ -365,16 +372,6 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, struct drm_connector_state *conn_state, int step, bool dsc) { - struct drm_atomic_state *state = crtc_state->uapi.state; - struct drm_dp_mst_topology_state *mst_state; - - mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr); - if (IS_ERR(mst_state)) - return PTR_ERR(mst_state); - - mst_state->pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock, - crtc_state->lane_count); - return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state, min_bpp, max_bpp, step, dsc); } From 6e2e27c20dcfc8229954001bbb206ab4ecdc27d5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 29 Jan 2025 16:46:37 +0200 Subject: [PATCH 123/284] drm/i915/mst: remove unnecessary mst_stream_find_vcpi_slots_for_bpp() mst_stream_find_vcpi_slots_for_bpp() has become a thin wrapper that merely juggles parameters around. Remove it. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/abdd205087dc2ab0bdae09d7374d5f262f605aba.1738161945.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 23 ++++++--------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index e596a77270705..825c525959217 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -366,16 +366,6 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, return 0; } -static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, - struct intel_crtc_state *crtc_state, - int max_bpp, int min_bpp, - struct drm_connector_state *conn_state, - int step, bool dsc) -{ - return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state, - min_bpp, max_bpp, step, dsc); -} - static int mst_stream_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, @@ -388,10 +378,10 @@ static int mst_stream_compute_link_config(struct intel_dp *intel_dp, * FIXME: allocate the BW according to link_bpp, which in the case of * YUV420 is only half of the pipe bpp value. */ - return mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, - fxp_q4_to_int(limits->link.max_bpp_x16), - fxp_q4_to_int(limits->link.min_bpp_x16), - conn_state, 2 * 3, false); + return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state, + fxp_q4_to_int(limits->link.min_bpp_x16), + fxp_q4_to_int(limits->link.max_bpp_x16), + 2 * 3, false); } static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, @@ -451,9 +441,8 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, crtc_state->lane_count = limits->max_lane_count; crtc_state->port_clock = limits->max_rate; - return mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, max_compressed_bpp, - min_compressed_bpp, - conn_state, 1, true); + return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state, + min_compressed_bpp, max_compressed_bpp, 1, true); } static int mst_stream_update_slots(struct intel_dp *intel_dp, From 31c726562849831b4c7f98d2fb267974b9390527 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 29 Jan 2025 16:46:38 +0200 Subject: [PATCH 124/284] drm/i915/mst: use min_array() and max_array() instead of hand-rolling Improve code clarity by using existing min_array() and max_array() helpers to find the lowest and highest values in an array. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/62a104535c01c667a99ec209c3218a13355568cf.1738161945.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 825c525959217..ed7640728b226 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -391,7 +391,7 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = to_intel_connector(conn_state->connector); - int i, num_bpc; + int num_bpc; u8 dsc_bpc[3] = {}; int min_bpp, max_bpp, sink_min_bpp, sink_max_bpp; int min_compressed_bpp, max_compressed_bpp; @@ -405,15 +405,8 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, drm_dbg_kms(display->drm, "DSC Source supported min bpp %d max bpp %d\n", min_bpp, max_bpp); - sink_max_bpp = dsc_bpc[0] * 3; - sink_min_bpp = sink_max_bpp; - - for (i = 1; i < num_bpc; i++) { - if (sink_min_bpp > dsc_bpc[i] * 3) - sink_min_bpp = dsc_bpc[i] * 3; - if (sink_max_bpp < dsc_bpc[i] * 3) - sink_max_bpp = dsc_bpc[i] * 3; - } + sink_min_bpp = min_array(dsc_bpc, num_bpc) * 3; + sink_max_bpp = max_array(dsc_bpc, num_bpc) * 3; drm_dbg_kms(display->drm, "DSC Sink supported min bpp %d max bpp %d\n", sink_min_bpp, sink_max_bpp); From a67221b5eb8d59fb7e1f0df3ef9945b6a0f32cca Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 31 Jan 2025 09:43:42 +0530 Subject: [PATCH 125/284] drm/i915/dp: Return min bpc supported by source instead of 0 Currently, intel_dp_dsc_max_src_input_bpc can return 0 for platforms not supporting DSC, which could theoretically cause issues in clamp() due to a low limit being greater than the high limit. Instead, return the minimum bpc supported by the source to prevent such issues. Reported-by: Linux Kernel Functional Testing Closes: https://lore.kernel.org/all/CA+G9fYtNfM399_=_ff81zeRJv=0+z7oFJfPGmJgTp6yrJmU+1w@mail.gmail.com/ Fixes: 160672b86b0d ("drm/i915/dp: Use clamp for pipe_bpp limits with DSC") Cc: Suraj Kandpal Cc: Jani Nikula Cc: Rodrigo Vivi Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Tested-by: Chaitanya Kumar Borah Link: https://patchwork.freedesktop.org/patch/msgid/20250131041342.3086716-1-ankit.k.nautiyal@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4fe274105c1dd..00aba97631a9b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1791,7 +1791,7 @@ int intel_dp_dsc_max_src_input_bpc(struct intel_display *display) if (DISPLAY_VER(display) == 11) return 10; - return 0; + return intel_dp_dsc_min_src_input_bpc(); } int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector, From 56b0337d429356c3b9ecc36a03023c8cc856b196 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:49:54 +0200 Subject: [PATCH 126/284] drm/i915/dp: Iterate DSC BPP from high to low on all platforms Commit 1c56e9a39833 ("drm/i915/dp: Get optimal link config to have best compressed bpp") tries to find the best compressed bpp for the link. However, it iterates from max to min bpp on display 13+, and from min to max on other platforms. This presumably leads to minimum compressed bpp always being chosen on display 11-12. Iterate from high to low on all platforms to actually use the best possible compressed bpp. Fixes: 1c56e9a39833 ("drm/i915/dp: Get optimal link config to have best compressed bpp") Cc: Ankit Nautiyal Cc: Imre Deak Cc: # v6.7+ Reviewed-by: Imre Deak Reviewed-by: Ankit Nautiyal Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/3bba67923cbcd13a59d26ef5fa4bb042b13c8a9b.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 00aba97631a9b..f2c4afc5997c2 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2073,11 +2073,10 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp, /* Compressed BPP should be less than the Input DSC bpp */ dsc_max_bpp = min(dsc_max_bpp, output_bpp - 1); - for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) { - if (valid_dsc_bpp[i] < dsc_min_bpp) + for (i = ARRAY_SIZE(valid_dsc_bpp) - 1; i >= 0; i--) { + if (valid_dsc_bpp[i] < dsc_min_bpp || + valid_dsc_bpp[i] > dsc_max_bpp) continue; - if (valid_dsc_bpp[i] > dsc_max_bpp) - break; ret = dsc_compute_link_config(intel_dp, pipe_config, From dc9ea8777c8b999f6a7e9eb974b2f7ae5e643d9b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sat, 1 Feb 2025 01:28:15 +0200 Subject: [PATCH 127/284] drm/i915/dp: Add intel_dp_dsc_bpp_step_x16() helper to get DSC BPP precision Add a platform independent helper for getting the supported DSC BPP step for the link. v2: Use fxp_q4_from_int(1) (Imre) Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250131232815.2046237-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f2c4afc5997c2..43c6f0ad0c011 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2054,6 +2054,21 @@ static int dsc_src_max_compressed_bpp(struct intel_dp *intel_dp) return 27; } +/* + * Note: for pre-13 display you still need to check the validity of each step. + */ +static int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector) +{ + struct intel_display *display = to_intel_display(connector); + u8 incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd); + + if (DISPLAY_VER(display) < 14 || !incr) + return fxp_q4_from_int(1); + + /* fxp q4 */ + return fxp_q4_from_int(1) / incr; +} + /* * From a list of valid compressed bpps try different compressed bpp and find a * suitable link configuration that can support it. @@ -2110,16 +2125,12 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, int timeslots) { struct intel_display *display = to_intel_display(intel_dp); - u8 bppx16_incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd); int output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); u16 compressed_bppx16; u8 bppx16_step; int ret; - if (DISPLAY_VER(display) < 14 || bppx16_incr <= 1) - bppx16_step = 16; - else - bppx16_step = 16 / bppx16_incr; + bppx16_step = intel_dp_dsc_bpp_step_x16(connector); /* Compressed BPP should be less than the Input DSC bpp */ dsc_max_bpp = min(dsc_max_bpp << 4, (output_bpp << 4) - bppx16_step); From 2e74748c4c0249930c8edcf5ae7b6e5c8c391f7a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:49:56 +0200 Subject: [PATCH 128/284] drm/i915/dp: Rename some variables in xelpd_dsc_compute_link_config() Use the _x16 suffix for all .4 fixed point variables. Drop compressed_ prefix, as it's implied from the precision suffix. As dsc_min_bpp and dsc_max_bpp change domain from int to .4 in the middle of the function, they remain the same for now. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/91dd6ef53683b624a978101cca7322ea3e5e2f7b.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 43c6f0ad0c011..e2d252e15ce98 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2126,31 +2126,28 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); int output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); - u16 compressed_bppx16; - u8 bppx16_step; + int bpp_x16, bpp_step_x16; int ret; - bppx16_step = intel_dp_dsc_bpp_step_x16(connector); + bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); /* Compressed BPP should be less than the Input DSC bpp */ - dsc_max_bpp = min(dsc_max_bpp << 4, (output_bpp << 4) - bppx16_step); + dsc_max_bpp = min(dsc_max_bpp << 4, (output_bpp << 4) - bpp_step_x16); dsc_min_bpp = dsc_min_bpp << 4; - for (compressed_bppx16 = dsc_max_bpp; - compressed_bppx16 >= dsc_min_bpp; - compressed_bppx16 -= bppx16_step) { + for (bpp_x16 = dsc_max_bpp; bpp_x16 >= dsc_min_bpp; bpp_x16 -= bpp_step_x16) { if (intel_dp->force_dsc_fractional_bpp_en && - !fxp_q4_to_frac(compressed_bppx16)) + !fxp_q4_to_frac(bpp_x16)) continue; ret = dsc_compute_link_config(intel_dp, pipe_config, limits, - compressed_bppx16, + bpp_x16, timeslots); if (ret == 0) { - pipe_config->dsc.compressed_bpp_x16 = compressed_bppx16; + pipe_config->dsc.compressed_bpp_x16 = bpp_x16; if (intel_dp->force_dsc_fractional_bpp_en && - fxp_q4_to_frac(compressed_bppx16)) + fxp_q4_to_frac(bpp_x16)) drm_dbg_kms(display->drm, "Forcing DSC fractional bpp\n"); From 99f4cb4fb222b42703b43551d55c9ec2520d9d5b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:49:57 +0200 Subject: [PATCH 129/284] drm/i915/dp: Pass .4 BPP values to {icl,xelpd}_dsc_compute_link_config() Try to keep the variables in the same domain a bit longer to reduce juggling between integers and .4 fixed point. Change parameter order to min, max while at it. For now, keep the juggling in dsc_compute_compressed_bpp() ensure min/max will always have 0 fractional part. To be fixed later. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/e72f153fd28755e41ee8c5a7b9e6de257c3b27ac.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index e2d252e15ce98..0e941307f399a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2077,8 +2077,8 @@ static int icl_dsc_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, const struct link_config_limits *limits, - int dsc_max_bpp, - int dsc_min_bpp, + int min_bpp_x16, + int max_bpp_x16, int pipe_bpp, int timeslots) { @@ -2086,11 +2086,11 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp, int output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); /* Compressed BPP should be less than the Input DSC bpp */ - dsc_max_bpp = min(dsc_max_bpp, output_bpp - 1); + max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp - 1)); for (i = ARRAY_SIZE(valid_dsc_bpp) - 1; i >= 0; i--) { - if (valid_dsc_bpp[i] < dsc_min_bpp || - valid_dsc_bpp[i] > dsc_max_bpp) + if (valid_dsc_bpp[i] < fxp_q4_to_int(min_bpp_x16) || + valid_dsc_bpp[i] > fxp_q4_to_int(max_bpp_x16)) continue; ret = dsc_compute_link_config(intel_dp, @@ -2119,8 +2119,8 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, const struct intel_connector *connector, struct intel_crtc_state *pipe_config, const struct link_config_limits *limits, - int dsc_max_bpp, - int dsc_min_bpp, + int min_bpp_x16, + int max_bpp_x16, int pipe_bpp, int timeslots) { @@ -2132,10 +2132,9 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); /* Compressed BPP should be less than the Input DSC bpp */ - dsc_max_bpp = min(dsc_max_bpp << 4, (output_bpp << 4) - bpp_step_x16); - dsc_min_bpp = dsc_min_bpp << 4; + max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp) - bpp_step_x16); - for (bpp_x16 = dsc_max_bpp; bpp_x16 >= dsc_min_bpp; bpp_x16 -= bpp_step_x16) { + for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { if (intel_dp->force_dsc_fractional_bpp_en && !fxp_q4_to_frac(bpp_x16)) continue; @@ -2168,6 +2167,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int dsc_min_bpp; int dsc_max_bpp; + int min_bpp_x16, max_bpp_x16; int dsc_joiner_max_bpp; int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); @@ -2178,11 +2178,15 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, num_joined_pipes); dsc_max_bpp = min(dsc_joiner_max_bpp, fxp_q4_to_int(limits->link.max_bpp_x16)); + /* FIXME: remove the round trip via integers */ + min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp); + max_bpp_x16 = fxp_q4_from_int(dsc_max_bpp); + if (DISPLAY_VER(display) >= 13) return xelpd_dsc_compute_link_config(intel_dp, connector, pipe_config, limits, - dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots); + min_bpp_x16, max_bpp_x16, pipe_bpp, timeslots); return icl_dsc_compute_link_config(intel_dp, pipe_config, limits, - dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots); + min_bpp_x16, max_bpp_x16, pipe_bpp, timeslots); } int intel_dp_dsc_min_src_input_bpc(void) From a38619fc93ade0d5531f88b990825fbf50a79071 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:49:58 +0200 Subject: [PATCH 130/284] drm/i915/dp: Move max DSC BPP reduction one level higher Now that {icl,xelpd}_dsc_compute_link_config() take .4 fixed point as parameter, move the common max DSC BPP reduction one level higher. Use intel_dp_dsc_bpp_step() to compute the step, and pass on to both platform specific functions. (Though it's unused for now in icl_dsc_compute_link_config()). We can drop the pipe_bpp and connector parameters. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/62fa7f18ea49dce24c5d0ee7b2f0cbde9e2b609c.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 32 +++++++++++-------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0e941307f399a..898846d61c637 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2079,14 +2079,10 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp, const struct link_config_limits *limits, int min_bpp_x16, int max_bpp_x16, - int pipe_bpp, + int bpp_step_x16, int timeslots) { int i, ret; - int output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); - - /* Compressed BPP should be less than the Input DSC bpp */ - max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp - 1)); for (i = ARRAY_SIZE(valid_dsc_bpp) - 1; i >= 0; i--) { if (valid_dsc_bpp[i] < fxp_q4_to_int(min_bpp_x16) || @@ -2116,24 +2112,17 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp, */ static int xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, - const struct intel_connector *connector, struct intel_crtc_state *pipe_config, const struct link_config_limits *limits, int min_bpp_x16, int max_bpp_x16, - int pipe_bpp, + int bpp_step_x16, int timeslots) { struct intel_display *display = to_intel_display(intel_dp); - int output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); - int bpp_x16, bpp_step_x16; + int bpp_x16; int ret; - bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); - - /* Compressed BPP should be less than the Input DSC bpp */ - max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp) - bpp_step_x16); - for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { if (intel_dp->force_dsc_fractional_bpp_en && !fxp_q4_to_frac(bpp_x16)) @@ -2165,9 +2154,10 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; + int output_bpp; int dsc_min_bpp; int dsc_max_bpp; - int min_bpp_x16, max_bpp_x16; + int min_bpp_x16, max_bpp_x16, bpp_step_x16; int dsc_joiner_max_bpp; int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); @@ -2182,11 +2172,17 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp); max_bpp_x16 = fxp_q4_from_int(dsc_max_bpp); + bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); + + /* Compressed BPP should be less than the Input DSC bpp */ + output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); + max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp) - bpp_step_x16); + if (DISPLAY_VER(display) >= 13) - return xelpd_dsc_compute_link_config(intel_dp, connector, pipe_config, limits, - min_bpp_x16, max_bpp_x16, pipe_bpp, timeslots); + return xelpd_dsc_compute_link_config(intel_dp, pipe_config, limits, + min_bpp_x16, max_bpp_x16, bpp_step_x16, timeslots); return icl_dsc_compute_link_config(intel_dp, pipe_config, limits, - min_bpp_x16, max_bpp_x16, pipe_bpp, timeslots); + min_bpp_x16, max_bpp_x16, bpp_step_x16, timeslots); } int intel_dp_dsc_min_src_input_bpc(void) From c791c7ebd00ffb91512f387f3ca31f92195c06ea Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:49:59 +0200 Subject: [PATCH 131/284] drm/i915/dp: Change icl_dsc_compute_link_config() DSC BPP iteration Instead of iterating the valid BPP array directly, switch to the same approach as xelpd_dsc_compute_link_config(), with a separate function to check if the DSC BPP is valid. This prepares us for unifying the platform specific functions. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/bc1972391041a3ba84b3f68b9c0605ae142611e0.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 33 +++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 898846d61c637..a299b69309dc6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2069,6 +2069,26 @@ static int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector) return fxp_q4_from_int(1) / incr; } +/* Note: This is not universally usable! */ +static bool intel_dp_dsc_valid_bpp(struct intel_dp *intel_dp, int bpp_x16) +{ + struct intel_display *display = to_intel_display(intel_dp); + int i; + + if (DISPLAY_VER(display) >= 13) + return true; + + if (fxp_q4_to_frac(bpp_x16)) + return false; + + for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) { + if (fxp_q4_to_int(bpp_x16) == valid_dsc_bpp[i]) + return true; + } + + return false; +} + /* * From a list of valid compressed bpps try different compressed bpp and find a * suitable link configuration that can support it. @@ -2082,21 +2102,20 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp, int bpp_step_x16, int timeslots) { - int i, ret; + int bpp_x16; + int ret; - for (i = ARRAY_SIZE(valid_dsc_bpp) - 1; i >= 0; i--) { - if (valid_dsc_bpp[i] < fxp_q4_to_int(min_bpp_x16) || - valid_dsc_bpp[i] > fxp_q4_to_int(max_bpp_x16)) + for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { + if (!intel_dp_dsc_valid_bpp(intel_dp, bpp_x16)) continue; ret = dsc_compute_link_config(intel_dp, pipe_config, limits, - valid_dsc_bpp[i] << 4, + bpp_x16, timeslots); if (ret == 0) { - pipe_config->dsc.compressed_bpp_x16 = - fxp_q4_from_int(valid_dsc_bpp[i]); + pipe_config->dsc.compressed_bpp_x16 = bpp_x16; return 0; } } From 206914ca6529ea08b2ccb060948959fa837f3f19 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:50:00 +0200 Subject: [PATCH 132/284] drm/i915/dp: Move force_dsc_fractional_bpp_en check to intel_dp_dsc_valid_bpp() Add the fractional DSC BPP force check to intel_dp_dsc_valid_bpp(), and use that in xelpd_dsc_compute_link_config(). This is another step closer towards unifying the platform specific functions. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/2d8cdfef422dc2229d3ead2201bff4a321cbbdd3.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a299b69309dc6..2feb686f64194 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2075,8 +2075,12 @@ static bool intel_dp_dsc_valid_bpp(struct intel_dp *intel_dp, int bpp_x16) struct intel_display *display = to_intel_display(intel_dp); int i; - if (DISPLAY_VER(display) >= 13) + if (DISPLAY_VER(display) >= 13) { + if (intel_dp->force_dsc_fractional_bpp_en && !fxp_q4_to_frac(bpp_x16)) + return false; + return true; + } if (fxp_q4_to_frac(bpp_x16)) return false; @@ -2143,9 +2147,9 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, int ret; for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { - if (intel_dp->force_dsc_fractional_bpp_en && - !fxp_q4_to_frac(bpp_x16)) + if (!intel_dp_dsc_valid_bpp(intel_dp, bpp_x16)) continue; + ret = dsc_compute_link_config(intel_dp, pipe_config, limits, From 9e276d220a650def051a3981a8dfb86c5c23a892 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:50:01 +0200 Subject: [PATCH 133/284] drm/i915/dp: Unify DSC link config functions {icl,xelpd}_dsc_compute_link_config() are now effectively the same, and can be unified to a single platform independent function. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/ca41ebb287fc51e1257d3c2b2790edf2cd661ab3.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 49 +++---------------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 2feb686f64194..023466f24f381 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2094,47 +2094,11 @@ static bool intel_dp_dsc_valid_bpp(struct intel_dp *intel_dp, int bpp_x16) } /* - * From a list of valid compressed bpps try different compressed bpp and find a - * suitable link configuration that can support it. + * Find the max compressed BPP we can find a link configuration for. The BPPs to + * try depend on the source (platform) and sink. */ static int -icl_dsc_compute_link_config(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - const struct link_config_limits *limits, - int min_bpp_x16, - int max_bpp_x16, - int bpp_step_x16, - int timeslots) -{ - int bpp_x16; - int ret; - - for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { - if (!intel_dp_dsc_valid_bpp(intel_dp, bpp_x16)) - continue; - - ret = dsc_compute_link_config(intel_dp, - pipe_config, - limits, - bpp_x16, - timeslots); - if (ret == 0) { - pipe_config->dsc.compressed_bpp_x16 = bpp_x16; - return 0; - } - } - - return -EINVAL; -} - -/* - * From XE_LPD onwards we supports compression bpps in steps of 1 up to - * uncompressed bpp-1. So we start from max compressed bpp and see if any - * link configuration is able to support that compressed bpp, if not we - * step down and check for lower compressed bpp. - */ -static int -xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, +do_dsc_compute_compressed_bpp(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, const struct link_config_limits *limits, int min_bpp_x16, @@ -2201,11 +2165,8 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp) - bpp_step_x16); - if (DISPLAY_VER(display) >= 13) - return xelpd_dsc_compute_link_config(intel_dp, pipe_config, limits, - min_bpp_x16, max_bpp_x16, bpp_step_x16, timeslots); - return icl_dsc_compute_link_config(intel_dp, pipe_config, limits, - min_bpp_x16, max_bpp_x16, bpp_step_x16, timeslots); + return do_dsc_compute_compressed_bpp(intel_dp, pipe_config, limits, + min_bpp_x16, max_bpp_x16, bpp_step_x16, timeslots); } int intel_dp_dsc_min_src_input_bpc(void) From df64948ec2cecb1dc0747072aca23621ebf80be9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:50:02 +0200 Subject: [PATCH 134/284] drm/i915/dp: Inline do_dsc_compute_compressed_bpp() With just the one platform independent loop left in do_dsc_compute_compressed_bpp(), we don't really need the extra function that is simply becoming increasingly hard to even figure out a decent name for. Just merge the whole thing to dsc_compute_compressed_bpp(). Good riddance to the short lived do_dsc_compute_compressed_bpp(). Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/91ae42cbdffe4938a665667955c577f887b92b9d.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 60 ++++++++++--------------- 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 023466f24f381..8175ac0eb8025 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2097,41 +2097,6 @@ static bool intel_dp_dsc_valid_bpp(struct intel_dp *intel_dp, int bpp_x16) * Find the max compressed BPP we can find a link configuration for. The BPPs to * try depend on the source (platform) and sink. */ -static int -do_dsc_compute_compressed_bpp(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - const struct link_config_limits *limits, - int min_bpp_x16, - int max_bpp_x16, - int bpp_step_x16, - int timeslots) -{ - struct intel_display *display = to_intel_display(intel_dp); - int bpp_x16; - int ret; - - for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { - if (!intel_dp_dsc_valid_bpp(intel_dp, bpp_x16)) - continue; - - ret = dsc_compute_link_config(intel_dp, - pipe_config, - limits, - bpp_x16, - timeslots); - if (ret == 0) { - pipe_config->dsc.compressed_bpp_x16 = bpp_x16; - if (intel_dp->force_dsc_fractional_bpp_en && - fxp_q4_to_frac(bpp_x16)) - drm_dbg_kms(display->drm, - "Forcing DSC fractional bpp\n"); - - return 0; - } - } - return -EINVAL; -} - static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, const struct intel_connector *connector, struct intel_crtc_state *pipe_config, @@ -2147,6 +2112,8 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, int min_bpp_x16, max_bpp_x16, bpp_step_x16; int dsc_joiner_max_bpp; int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); + int bpp_x16; + int ret; dsc_min_bpp = fxp_q4_to_int_roundup(limits->link.min_bpp_x16); @@ -2165,8 +2132,27 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp) - bpp_step_x16); - return do_dsc_compute_compressed_bpp(intel_dp, pipe_config, limits, - min_bpp_x16, max_bpp_x16, bpp_step_x16, timeslots); + for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { + if (!intel_dp_dsc_valid_bpp(intel_dp, bpp_x16)) + continue; + + ret = dsc_compute_link_config(intel_dp, + pipe_config, + limits, + bpp_x16, + timeslots); + if (ret == 0) { + pipe_config->dsc.compressed_bpp_x16 = bpp_x16; + if (intel_dp->force_dsc_fractional_bpp_en && + fxp_q4_to_frac(bpp_x16)) + drm_dbg_kms(display->drm, + "Forcing DSC fractional bpp\n"); + + return 0; + } + } + + return -EINVAL; } int intel_dp_dsc_min_src_input_bpc(void) From 73ef9abb239bcf2b4ed68d808e0935a4e0ee251b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:50:03 +0200 Subject: [PATCH 135/284] drm/i915/dp: Simplify input BPP checks in intel_dp_dsc_compute_pipe_bpp() Drop the extra local variables and simplify the conditions. We don't have to try to special case the loop condition and break in the validity checks. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/5559b14d6af4e001677f23454d6bd8b3606b3d7a.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 8175ac0eb8025..22b69c02c13eb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2202,8 +2202,6 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, { const struct intel_connector *connector = to_intel_connector(conn_state->connector); - int dsc_max_bpp; - int dsc_min_bpp; u8 dsc_bpc[3] = {}; int forced_bpp, pipe_bpp; int num_bpc, i, ret; @@ -2219,9 +2217,6 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, } } - dsc_max_bpp = limits->pipe.max_bpp; - dsc_min_bpp = limits->pipe.min_bpp; - /* * Get the maximum DSC bpc that will be supported by any valid * link configuration and compressed bpp. @@ -2229,10 +2224,9 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, dsc_bpc); for (i = 0; i < num_bpc; i++) { pipe_bpp = dsc_bpc[i] * 3; - if (pipe_bpp < dsc_min_bpp) - break; - if (pipe_bpp > dsc_max_bpp) + if (pipe_bpp < limits->pipe.min_bpp || pipe_bpp > limits->pipe.max_bpp) continue; + ret = dsc_compute_compressed_bpp(intel_dp, connector, pipe_config, limits, pipe_bpp, timeslots); if (ret == 0) { From b3f5c960146ab24afe56436389b2dc5cf44e7a36 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:50:04 +0200 Subject: [PATCH 136/284] drm/i915/dp: Use int for compressed BPP in dsc_compute_link_config() Just use ints unless there are actual reasons to do otherwise. Here, there are not. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/b8f9aebc4e40afeed3d723f98cae96c9c927a480.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 22b69c02c13eb..27f066ad40737 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1926,7 +1926,7 @@ static bool intel_dp_dsc_supports_format(const struct intel_connector *connector return drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd, sink_dsc_format); } -static bool is_bw_sufficient_for_dsc_config(u16 compressed_bppx16, u32 link_clock, +static bool is_bw_sufficient_for_dsc_config(int dsc_bpp_x16, u32 link_clock, u32 lane_count, u32 mode_clock, enum intel_output_format output_format, int timeslots) @@ -1934,7 +1934,7 @@ static bool is_bw_sufficient_for_dsc_config(u16 compressed_bppx16, u32 link_cloc u32 available_bw, required_bw; available_bw = (link_clock * lane_count * timeslots * 16) / 8; - required_bw = compressed_bppx16 * (intel_dp_mode_to_fec_clock(mode_clock)); + required_bw = dsc_bpp_x16 * (intel_dp_mode_to_fec_clock(mode_clock)); return available_bw > required_bw; } @@ -1942,7 +1942,7 @@ static bool is_bw_sufficient_for_dsc_config(u16 compressed_bppx16, u32 link_cloc static int dsc_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, const struct link_config_limits *limits, - u16 compressed_bppx16, + int dsc_bpp_x16, int timeslots) { const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; @@ -1957,7 +1957,7 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp, for (lane_count = limits->min_lane_count; lane_count <= limits->max_lane_count; lane_count <<= 1) { - if (!is_bw_sufficient_for_dsc_config(compressed_bppx16, link_rate, + if (!is_bw_sufficient_for_dsc_config(dsc_bpp_x16, link_rate, lane_count, adjusted_mode->clock, pipe_config->output_format, timeslots)) From 2056f0ad806272363fa7d3754317ef2380c112a1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:50:05 +0200 Subject: [PATCH 137/284] drm/i915/dp: Drop compute_pipe_bpp parameter from intel_dp_dsc_compute_config() The parameter is basically just a proxy for whether the function is being called for DP SST or DP MST. We can figure this out from crtc state. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/82a4b84711b1416bb3382f5d8383fe65ab88159a.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 14 ++++++-------- drivers/gpu/drm/i915/display/intel_dp.h | 3 +-- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 27f066ad40737..adfd1b6d148d1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2307,8 +2307,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, const struct link_config_limits *limits, - int timeslots, - bool compute_pipe_bpp) + int timeslots) { struct intel_display *display = to_intel_display(intel_dp); const struct intel_connector *connector = @@ -2316,6 +2315,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); + bool is_mst = intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST); int ret; intel_dp_fec_compute_config(intel_dp, pipe_config); @@ -2324,12 +2324,10 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, return -EINVAL; /* - * compute pipe bpp is set to false for DP MST DSC case - * and compressed_bpp is calculated same time once - * vpci timeslots are allocated, because overall bpp - * calculation procedure is bit different for MST case. + * Link parameters, pipe bpp and compressed bpp have already been + * figured out for DP MST DSC. */ - if (compute_pipe_bpp) { + if (!is_mst) { if (intel_dp_is_edp(intel_dp)) ret = intel_edp_dsc_compute_pipe_bpp(intel_dp, pipe_config, conn_state, limits); @@ -2640,7 +2638,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, return -EINVAL; ret = intel_dp_dsc_compute_config(intel_dp, pipe_config, - conn_state, &limits, 64, true); + conn_state, &limits, 64); if (ret < 0) return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index ffc27f8ad2269..9189db4c25946 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -76,8 +76,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, const struct link_config_limits *limits, - int timeslots, - bool recompute_pipe_bpp); + int timeslots); void intel_dp_audio_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index ed7640728b226..04b840070fdb9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -657,7 +657,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, ret = intel_dp_dsc_compute_config(intel_dp, pipe_config, conn_state, &limits, - pipe_config->dp_m_n.tu, false); + pipe_config->dp_m_n.tu); } if (ret) From cf92a9d4f01d8d63013dc0bdf1fc63ad4f6e7334 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:50:06 +0200 Subject: [PATCH 138/284] drm/i915/dp: Pass connector state all the way to dsc_compute_link_config() Going forward, we'll need the connector state in dsc_compute_link_config(). Pass it along through the chain. Maintain the same parameter order where relevant. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/645d950a80df5fd4441d69aba4893ab263b3e555.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index adfd1b6d148d1..e287c3d043394 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1941,6 +1941,7 @@ static bool is_bw_sufficient_for_dsc_config(int dsc_bpp_x16, u32 link_clock, static int dsc_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state, const struct link_config_limits *limits, int dsc_bpp_x16, int timeslots) @@ -2098,13 +2099,14 @@ static bool intel_dp_dsc_valid_bpp(struct intel_dp *intel_dp, int bpp_x16) * try depend on the source (platform) and sink. */ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, - const struct intel_connector *connector, struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state, const struct link_config_limits *limits, int pipe_bpp, int timeslots) { struct intel_display *display = to_intel_display(intel_dp); + const struct intel_connector *connector = to_intel_connector(conn_state->connector); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int output_bpp; int dsc_min_bpp; @@ -2138,6 +2140,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, ret = dsc_compute_link_config(intel_dp, pipe_config, + conn_state, limits, bpp_x16, timeslots); @@ -2209,7 +2212,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, limits); if (forced_bpp) { - ret = dsc_compute_compressed_bpp(intel_dp, connector, pipe_config, + ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, limits, forced_bpp, timeslots); if (ret == 0) { pipe_config->pipe_bpp = forced_bpp; @@ -2227,7 +2230,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, if (pipe_bpp < limits->pipe.min_bpp || pipe_bpp > limits->pipe.max_bpp) continue; - ret = dsc_compute_compressed_bpp(intel_dp, connector, pipe_config, + ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, limits, pipe_bpp, timeslots); if (ret == 0) { pipe_config->pipe_bpp = pipe_bpp; From 67782bf6e8a6289996bbc3ce7138c30ff72ee458 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Jan 2025 14:50:07 +0200 Subject: [PATCH 139/284] drm/i915/mst: Convert intel_dp_mtp_tu_compute_config() to .4 format Move towards always using the fxp q4 or .4 fixed point format for compressed bpp. We'll need to pass the more accurate bpp to this function later on. Always use _x16 naming for variables that are in .4 fixed point for clarity. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/887306a47ce4550226f5d54178f667a52840a11c.1738327620.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 4 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 52 ++++++++++++--------- drivers/gpu/drm/i915/display/intel_dp_mst.h | 2 +- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index e287c3d043394..e9a9f1f8d353b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2616,8 +2616,8 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, ret = intel_dp_mtp_tu_compute_config(intel_dp, pipe_config, conn_state, - pipe_config->pipe_bpp, - pipe_config->pipe_bpp, + fxp_q4_from_int(pipe_config->pipe_bpp), + fxp_q4_from_int(pipe_config->pipe_bpp), 0, false); if (ret) dsc_needed = true; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 04b840070fdb9..7e58b9464a243 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -212,7 +212,7 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, - int min_bpp, int max_bpp, int step, bool dsc) + int min_bpp_x16, int max_bpp_x16, int bpp_step_x16, bool dsc) { struct intel_display *display = to_intel_display(intel_dp); struct drm_atomic_state *state = crtc_state->uapi.state; @@ -222,9 +222,14 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; bool is_mst = intel_dp->is_mst; - int bpp, slots = -EINVAL; + int bpp_x16, slots = -EINVAL; int dsc_slice_count = 0; - int max_dpt_bpp; + int max_dpt_bpp_x16; + + /* shouldn't happen, sanity check */ + drm_WARN_ON(display->drm, !dsc && (fxp_q4_to_frac(min_bpp_x16) || + fxp_q4_to_frac(max_bpp_x16) || + fxp_q4_to_frac(bpp_step_x16))); if (is_mst) { mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr); @@ -242,15 +247,15 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, crtc_state->fec_enable = !intel_dp_is_uhbr(crtc_state); } - max_dpt_bpp = intel_dp_mst_max_dpt_bpp(crtc_state, dsc); - if (max_bpp > max_dpt_bpp) { - drm_dbg_kms(display->drm, "Limiting bpp to max DPT bpp (%d -> %d)\n", - max_bpp, max_dpt_bpp); - max_bpp = max_dpt_bpp; + max_dpt_bpp_x16 = fxp_q4_from_int(intel_dp_mst_max_dpt_bpp(crtc_state, dsc)); + if (max_bpp_x16 > max_dpt_bpp_x16) { + drm_dbg_kms(display->drm, "Limiting bpp to max DPT bpp (" FXP_Q4_FMT " -> " FXP_Q4_FMT ")\n", + FXP_Q4_ARGS(max_bpp_x16), FXP_Q4_ARGS(max_dpt_bpp_x16)); + max_bpp_x16 = max_dpt_bpp_x16; } - drm_dbg_kms(display->drm, "Looking for slots in range min bpp %d max bpp %d\n", - min_bpp, max_bpp); + drm_dbg_kms(display->drm, "Looking for slots in range min bpp " FXP_Q4_FMT " max bpp " FXP_Q4_FMT "\n", + FXP_Q4_ARGS(min_bpp_x16), FXP_Q4_ARGS(max_bpp_x16)); if (dsc) { dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, crtc_state); @@ -261,14 +266,15 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, } } - for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) { + for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { int local_bw_overhead; int link_bpp_x16; - drm_dbg_kms(display->drm, "Trying bpp %d\n", bpp); + drm_dbg_kms(display->drm, "Trying bpp " FXP_Q4_FMT "\n", FXP_Q4_ARGS(bpp_x16)); - link_bpp_x16 = fxp_q4_from_int(dsc ? bpp : - intel_dp_output_bpp(crtc_state->output_format, bpp)); + link_bpp_x16 = dsc ? bpp_x16 : + fxp_q4_from_int(intel_dp_output_bpp(crtc_state->output_format, + fxp_q4_to_int(bpp_x16))); local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, false, dsc_slice_count, link_bpp_x16); @@ -356,12 +362,12 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, } if (!dsc) - crtc_state->pipe_bpp = bpp; + crtc_state->pipe_bpp = fxp_q4_to_int(bpp_x16); else - crtc_state->dsc.compressed_bpp_x16 = fxp_q4_from_int(bpp); + crtc_state->dsc.compressed_bpp_x16 = bpp_x16; - drm_dbg_kms(display->drm, "Got %d slots for pipe bpp %d dsc %d\n", - slots, bpp, dsc); + drm_dbg_kms(display->drm, "Got %d slots for pipe bpp " FXP_Q4_FMT " dsc %d\n", + slots, FXP_Q4_ARGS(bpp_x16), dsc); return 0; } @@ -379,9 +385,9 @@ static int mst_stream_compute_link_config(struct intel_dp *intel_dp, * YUV420 is only half of the pipe bpp value. */ return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state, - fxp_q4_to_int(limits->link.min_bpp_x16), - fxp_q4_to_int(limits->link.max_bpp_x16), - 2 * 3, false); + limits->link.min_bpp_x16, + limits->link.max_bpp_x16, + fxp_q4_from_int(2 * 3), false); } static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, @@ -435,7 +441,9 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, crtc_state->port_clock = limits->max_rate; return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state, - min_compressed_bpp, max_compressed_bpp, 1, true); + fxp_q4_from_int(min_compressed_bpp), + fxp_q4_from_int(max_compressed_bpp), + fxp_q4_from_int(1), true); } static int mst_stream_update_slots(struct intel_dp *intel_dp, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h index a713a1c10154a..c1bbfeb02ca9e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h @@ -34,6 +34,6 @@ bool intel_dp_mst_verify_dpcd_state(struct intel_dp *intel_dp); int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, - int min_bpp, int max_bpp, int step, bool dsc); + int min_bpp_x16, int max_bpp_x16, int bpp_step_x16, bool dsc); #endif /* __INTEL_DP_MST_H__ */ From 71be802005074a4cc2297e4a1da1ca268d9c6b49 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 3 Feb 2025 17:58:58 -0300 Subject: [PATCH 140/284] drm/i915/dmc_wl: Track INITIATE_PM_DMD_REQ for DC5 The Bspec has been updated to include INITIATE_PM_DMD_REQ in the set of register offsets that require the DMC wakelock for access during DC5. Update our table accordingly. Bspec: 71583 Reviewed-by: Luca Coelho Link: https://patchwork.freedesktop.org/patch/msgid/20250203205941.251754-1-gustavo.sousa@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_dmc_wl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 43884740f8ead..86ba159b683c7 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -102,6 +102,7 @@ static const struct intel_dmc_wl_range xe3lpd_dc5_dc6_dmc_ranges[] = { { .start = 0x42088 }, /* CHICKEN_MISC_3 */ { .start = 0x46160 }, /* CMTG_CLK_SEL */ { .start = 0x8f000, .end = 0x8ffff }, /* Main DMC registers */ + { .start = 0x45230 }, /* INITIATE_PM_DMD_REQ */ {}, }; From a5ebe00c2ace15634c02e3c64f1b28253553495b Mon Sep 17 00:00:00 2001 From: Arun R Murthy Date: Wed, 22 Jan 2025 11:25:42 +0530 Subject: [PATCH 141/284] drm/i915/dp: Guarantee a minimum HBlank time Mandate a minimum Hblank symbol cycle count between BlankingStart and BlankingEnd in 8b/10b MST and 128b/132b mode. v2: Affine calculation/updation of min HBlank to dp_mst (Jani) v3: moved min_hblank from struct intel_dp to intel_crtc_state (Jani) v4: use max/min functions, change intel_xx *intel_xx to intel_xx *xx (Jani) Limit hblank to 511 and accommodate BS/BE in calculated value (Srikanth) v5: Some spelling corrections (Suraj) v6: Removed DP2.1 in comment as this is applicable for both DP2.1 and DP1.4 (Suraj) v7: crtc_state holds the logical values and the register value computation is moved to mst_enable() (Jani) v8: Limit max hblank to 0x10, disable min_hblank on mst_disable (Jani) Bspec: 74379 Signed-off-by: Arun R Murthy Reviewed-by: Suraj Kandpal Acked-by: Jani Nikula Signed-off-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20250122-hblank-v9-1-90afda006685@intel.com --- .../drm/i915/display/intel_crtc_state_dump.c | 1 + .../drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_dp_mst.c | 53 ++++++++++++++++++- drivers/gpu/drm/i915/i915_reg.h | 4 ++ 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 36076e8d639bc..ecd0d9853c60f 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -249,6 +249,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, str_enabled_disabled(pipe_config->has_sel_update), str_enabled_disabled(pipe_config->has_panel_replay), str_enabled_disabled(pipe_config->enable_psr2_sel_fetch)); + drm_printf(&p, "minimum HBlank: %d\n", pipe_config->min_hblank); } drm_printf(&p, "audio: %i, infoframes: %i, infoframes enabled: 0x%x\n", diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index cb51b7936f933..f1a9ab4ae85a6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1097,6 +1097,7 @@ struct intel_crtc_state { int max_link_bpp_x16; /* in 1/16 bpp units */ int pipe_bpp; /* in 1 bpp units */ + int min_hblank; struct intel_link_m_n dp_m_n; /* m2_n2 for eDP downclock */ diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 7e58b9464a243..b8f4618d59839 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -209,6 +209,28 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec num_joined_pipes); } +static void intel_dp_mst_compute_min_hblank(struct intel_crtc_state *crtc_state, + struct intel_connector *connector, + int bpp_x16) +{ + struct intel_encoder *encoder = connector->encoder; + struct intel_display *display = to_intel_display(encoder); + const struct drm_display_mode *adjusted_mode = + &crtc_state->hw.adjusted_mode; + int symbol_size = intel_dp_is_uhbr(crtc_state) ? 32 : 8; + int hblank; + + if (DISPLAY_VER(display) < 20) + return; + + /* Calculate min Hblank Link Layer Symbol Cycle Count for 8b/10b MST & 128b/132b */ + hblank = DIV_ROUND_UP((DIV_ROUND_UP + (adjusted_mode->htotal - adjusted_mode->hdisplay, 4) * bpp_x16), + symbol_size); + + crtc_state->min_hblank = hblank; +} + int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, @@ -278,6 +300,9 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, false, dsc_slice_count, link_bpp_x16); + + intel_dp_mst_compute_min_hblank(crtc_state, connector, link_bpp_x16); + intel_dp_mst_compute_m_n(crtc_state, local_bw_overhead, link_bpp_x16, @@ -967,6 +992,7 @@ static void mst_stream_disable(struct intel_atomic_state *state, struct intel_dp *intel_dp = to_primary_dp(encoder); struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + enum transcoder trans = old_crtc_state->cpu_transcoder; drm_dbg_kms(display->drm, "active links %d\n", intel_dp->active_mst_links); @@ -977,6 +1003,8 @@ static void mst_stream_disable(struct intel_atomic_state *state, intel_hdcp_disable(intel_mst->connector); intel_dp_sink_disable_decompression(state, connector, old_crtc_state); + + intel_de_write(display, DP_MIN_HBLANK_CTL(trans), 0x00); } static void mst_stream_post_disable(struct intel_atomic_state *state, @@ -1249,7 +1277,7 @@ static void mst_stream_enable(struct intel_atomic_state *state, enum transcoder trans = pipe_config->cpu_transcoder; bool first_mst_stream = intel_dp->active_mst_links == 1; struct intel_crtc *pipe_crtc; - int ret, i; + int ret, i, min_hblank; drm_WARN_ON(display->drm, pipe_config->has_pch_encoder); @@ -1264,6 +1292,29 @@ static void mst_stream_enable(struct intel_atomic_state *state, TRANS_DP2_VFREQ_PIXEL_CLOCK(crtc_clock_hz & 0xffffff)); } + if (DISPLAY_VER(display) >= 20) { + /* + * adjust the BlankingStart/BlankingEnd framing control from + * the calculated value + */ + min_hblank = pipe_config->min_hblank - 2; + + /* Maximum value to be programmed is limited to 0x10 */ + min_hblank = min(0x10, min_hblank); + + /* + * Minimum hblank accepted for 128b/132b would be 5 and for + * 8b/10b would be 3 symbol count + */ + if (intel_dp_is_uhbr(pipe_config)) + min_hblank = max(min_hblank, 5); + else + min_hblank = max(min_hblank, 3); + + intel_de_write(display, DP_MIN_HBLANK_CTL(trans), + min_hblank); + } + enable_bs_jitter_was(pipe_config); intel_ddi_enable_transcoder_func(encoder, pipe_config); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 03da51b03fb90..670cd2371f947 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3198,6 +3198,10 @@ #define _TRANS_DP2_VFREQLOW_D 0x630a8 #define TRANS_DP2_VFREQLOW(trans) _MMIO_TRANS(trans, _TRANS_DP2_VFREQLOW_A, _TRANS_DP2_VFREQLOW_B) +#define _DP_MIN_HBLANK_CTL_A 0x600ac +#define _DP_MIN_HBLANK_CTL_B 0x610ac +#define DP_MIN_HBLANK_CTL(trans) _MMIO_TRANS(trans, _DP_MIN_HBLANK_CTL_A, _DP_MIN_HBLANK_CTL_B) + /* SNB eDP training params */ /* SNB A-stepping */ #define EDP_LINK_TRAIN_400MV_0DB_SNB_A (0x38 << 22) From b5ee4c2852d381a8f5351231561aa2faed474fe4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 17:37:17 +0200 Subject: [PATCH 142/284] drm/i915/mst: fix INT_MAX to .4 fixed point conversion mistake intel_dp_mtp_tu_compute_config() conversion to use .4 fixed point didn't take into account that intel_dp_mst_max_dpt_bpp() may return INT_MAX when the transport limitation is not relevant. Converting INT_MAX to .4 fixed point results in -1.0, which then gets used as if it were a real max BPP value: i915 0000:00:02.0: [drm:intel_dp_mtp_tu_compute_config [i915]] Limiting bpp to max DPT bpp (24.0000 -> -1.0000) i915 0000:00:02.0: [drm:intel_dp_mtp_tu_compute_config [i915]] Looking for slots in range min bpp 18.0000 max bpp -1.0000 Just return 0 for "no max DPT BPP", and handle it explicitly. Fixes: 67782bf6e8a6 ("drm/i915/mst: Convert intel_dp_mtp_tu_compute_config() to .4 format") Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13624 Cc: Imre Deak Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250204153717.2996923-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index b8f4618d59839..ff3ae5db4b54d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -111,7 +111,7 @@ static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state, &crtc_state->hw.adjusted_mode; if (!intel_dp_is_uhbr(crtc_state) || DISPLAY_VER(display) >= 20 || !dsc) - return INT_MAX; + return 0; /* * DSC->DPT interface width: @@ -270,7 +270,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, } max_dpt_bpp_x16 = fxp_q4_from_int(intel_dp_mst_max_dpt_bpp(crtc_state, dsc)); - if (max_bpp_x16 > max_dpt_bpp_x16) { + if (max_dpt_bpp_x16 && max_bpp_x16 > max_dpt_bpp_x16) { drm_dbg_kms(display->drm, "Limiting bpp to max DPT bpp (" FXP_Q4_FMT " -> " FXP_Q4_FMT ")\n", FXP_Q4_ARGS(max_bpp_x16), FXP_Q4_ARGS(max_dpt_bpp_x16)); max_bpp_x16 = max_dpt_bpp_x16; From a40e718d34d3d02c781c295466b013415f68c4f1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 17:49:25 +0200 Subject: [PATCH 143/284] drm/i915/dp: Fix potential infinite loop in 128b/132b SST Passing 0 as the step only works when there are other reasons to break out of the BPP loop in intel_dp_mtp_tu_compute_config(). Otherwise, an infinite loop might occur. Fix it by explicitly checking for 0 step. Fixes: ef0a0757bbea ("drm/i915/dp: compute config for 128b/132b SST w/o DSC") Reported-by: Imre Deak Closes: https://lore.kernel.org/r/Z6I0knh2Kt5T0JrT@ideak-desk.fi.intel.com Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250204154925.3001781-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index ff3ae5db4b54d..cc6e4ca375193 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -378,6 +378,10 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, break; } + + /* Allow using zero step to indicate one try */ + if (!bpp_step_x16) + break; } if (slots < 0) { From ebac36ea8ad55b7c08ceaef0e3fa408c8cffacc6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Feb 2025 18:08:34 +0200 Subject: [PATCH 144/284] drm/i915/dp: Add support for DP UHBR SST DSC Drop the UHBR limitation from DP SST DSC, and handle SST DSC bandwidth computation for UHBR using intel_dp_mtp_tu_compute_config(). Cc: Imre Deak Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250203160834.2708027-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 35 +++++++++++++++++++------ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index e9a9f1f8d353b..09211ae38d96e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1958,15 +1958,37 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp, for (lane_count = limits->min_lane_count; lane_count <= limits->max_lane_count; lane_count <<= 1) { - if (!is_bw_sufficient_for_dsc_config(dsc_bpp_x16, link_rate, - lane_count, adjusted_mode->clock, - pipe_config->output_format, - timeslots)) - continue; + /* + * FIXME: intel_dp_mtp_tu_compute_config() requires + * ->lane_count and ->port_clock set before we know + * they'll work. If we end up failing altogether, + * they'll remain in crtc state. This shouldn't matter, + * as we'd then bail out from compute config, but it's + * just ugly. + */ pipe_config->lane_count = lane_count; pipe_config->port_clock = link_rate; + if (drm_dp_is_uhbr_rate(link_rate)) { + int ret; + + ret = intel_dp_mtp_tu_compute_config(intel_dp, + pipe_config, + conn_state, + dsc_bpp_x16, + dsc_bpp_x16, + 0, true); + if (ret) + continue; + } else { + if (!is_bw_sufficient_for_dsc_config(dsc_bpp_x16, link_rate, + lane_count, adjusted_mode->clock, + pipe_config->output_format, + timeslots)) + continue; + } + return 0; } } @@ -2493,9 +2515,6 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp, limits->min_rate = intel_dp_min_link_rate(intel_dp); limits->max_rate = intel_dp_max_link_rate(intel_dp); - /* FIXME 128b/132b SST+DSC support missing */ - if (!is_mst && dsc) - limits->max_rate = min(limits->max_rate, 810000); limits->min_rate = min(limits->min_rate, limits->max_rate); limits->min_lane_count = intel_dp_min_lane_count(intel_dp); From bdcdb913c2d36447ea49d33774e5d6093c55d6f7 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Fri, 24 Jan 2025 16:12:34 -0300 Subject: [PATCH 145/284] drm/i915/dmc_wl: Do not check for DMC payload Enabling and disabling of DMC wakelock is already coupled with enabling and disabling of dynamic DC states, which already depend on the DMC being properly loaded. As such, we do not need to check if we already have a DMC payload parsed in __intel_dmc_wl_supported(). Furthermore, the presence of such a check causes inconsistencies in the refcount if the following sequence of events happen: 1. A call to one of the register accessors from intel_de.h is done before the DMC payload is parsed. That causes intel_dmc_wl_get() to be called. Suppose the register offset qualifies as needing the wakelock. In normal circumstances, the refcount would be incremented, but, because __intel_dmc_wl_supported() returns false, the refcount is untouched. 2. In a separate worker thread, the DMC firmware is parsed. Parsing of the DMC payload is finished before the corresponding intel_dmc_wl_put() from (1) is called. 3. When in the context of (1), intel_dmc_wl_put() gets called, now we have __intel_dmc_wl_supported() returning true and we hit the warning, because the code doesn't expect a zero refcount. Let's remove that check, since it is unnecessary and causes the inconsistency illustrated above. Reviewed-by: Krzysztof Karas Reviewed-by: Luca Coelho Link: https://patchwork.freedesktop.org/patch/msgid/20250124191250.56833-1-gustavo.sousa@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_dmc_wl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 86ba159b683c7..7e2ce0c2f6c39 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -10,7 +10,6 @@ #include "i915_drv.h" #include "i915_reg.h" #include "intel_de.h" -#include "intel_dmc.h" #include "intel_dmc_regs.h" #include "intel_dmc_wl.h" @@ -283,7 +282,7 @@ static bool intel_dmc_wl_check_range(struct intel_display *display, static bool __intel_dmc_wl_supported(struct intel_display *display) { - return display->params.enable_dmc_wl && intel_dmc_has_payload(display); + return display->params.enable_dmc_wl; } static void intel_dmc_wl_sanitize_param(struct intel_display *display) From 082795b2c67f264d1ec30cde723b7f24c448bfa7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 15:58:38 +0200 Subject: [PATCH 146/284] drm/i915/hdmi: move declarations for hsw_read/write_infoframe() to the right place The functions are located in intel_hdmi.c, put the declarations in intel_hdmi.h. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/e8cd28a3c46f06b9654df8b7990e1e6a1d9e18c1.1738677489.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_hdmi.h | 9 +++++++++ drivers/gpu/drm/i915/display/intel_lspcon.h | 8 -------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h index 38deaeb302a2f..d237fe08c3e63 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.h +++ b/drivers/gpu/drm/i915/display/intel_hdmi.h @@ -62,4 +62,13 @@ int intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state, int hdmi_max_slices, int hdmi_throughput); int intel_hdmi_dsc_get_slice_height(int vactive); +void hsw_write_infoframe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + unsigned int type, + const void *frame, ssize_t len); +void hsw_read_infoframe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + unsigned int type, + void *frame, ssize_t len); + #endif /* __INTEL_HDMI_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index e19e10492b051..47f9ae77b328a 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -35,13 +35,5 @@ u32 lspcon_infoframes_enabled(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config); u32 intel_lspcon_infoframes_enabled(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config); -void hsw_write_infoframe(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - unsigned int type, - const void *frame, ssize_t len); -void hsw_read_infoframe(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - unsigned int type, - void *frame, ssize_t len); #endif /* __INTEL_LSPCON_H__ */ From 34176697bda3066de583deb5e569e2d77d5dc7f0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 15:58:39 +0200 Subject: [PATCH 147/284] drm/i915/lspcon: add intel_lspcon_active() and use it Hide the direct lspcon->active use behind intel_lspcon_active(). Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/3eabe0cb07a84c63119ea893e149de410b4356b0.1738677489.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_ddi.c | 6 +++--- drivers/gpu/drm/i915/display/intel_dp.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_lspcon.c | 7 +++++++ drivers/gpu/drm/i915/display/intel_lspcon.h | 1 + 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index dc319f37b1be9..3e85ef281f1e1 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3025,7 +3025,7 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, /* FIXME precompute everything properly */ /* FIXME how do we turn infoframes off again? */ - if (dig_port->lspcon.active && intel_dp_has_hdmi_sink(&dig_port->dp)) + if (intel_lspcon_active(dig_port) && intel_dp_has_hdmi_sink(&dig_port->dp)) dig_port->set_infoframes(encoder, crtc_state->has_infoframe, crtc_state, conn_state); @@ -3381,7 +3381,7 @@ static void intel_ddi_enable_dp(struct intel_atomic_state *state, drm_connector_update_privacy_screen(conn_state); intel_edp_backlight_on(crtc_state, conn_state); - if (!dig_port->lspcon.active || intel_dp_has_hdmi_sink(&dig_port->dp)) + if (!intel_lspcon_active(dig_port) || intel_dp_has_hdmi_sink(&dig_port->dp)) intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); trans_port_sync_stop_link_train(state, encoder, crtc_state); @@ -4082,7 +4082,7 @@ static void intel_ddi_read_func_ctl_dp_sst(struct intel_encoder *encoder, intel_de_read(display, dp_tp_ctl_reg(encoder, crtc_state)) & DP_TP_CTL_FEC_ENABLE; - if (dig_port->lspcon.active && intel_dp_has_hdmi_sink(&dig_port->dp)) + if (intel_lspcon_active(dig_port) && intel_dp_has_hdmi_sink(&dig_port->dp)) crtc_state->infoframes.enable |= intel_lspcon_infoframes_enabled(encoder, crtc_state); else diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 09211ae38d96e..860f246aeb061 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3519,9 +3519,10 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode) ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, mode); } else { + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp); - lspcon_resume(dp_to_dig_port(intel_dp)); + lspcon_resume(dig_port); /* Write the source OUI as early as possible */ intel_dp_init_source_oui(intel_dp); @@ -3537,7 +3538,7 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode) msleep(1); } - if (ret == 1 && lspcon->active) + if (ret == 1 && intel_lspcon_active(dig_port)) lspcon_wait_pcon_mode(lspcon); } @@ -5588,7 +5589,7 @@ intel_dp_update_420(struct intel_dp *intel_dp) intel_dp->downstream_ports); /* on-board LSPCON always assumed to support 4:4:4->4:2:0 conversion */ intel_dp->dfp.ycbcr_444_to_420 = - dp_to_dig_port(intel_dp)->lspcon.active || + intel_lspcon_active(dp_to_dig_port(intel_dp)) || drm_dp_downstream_444_to_420_conversion(intel_dp->dpcd, intel_dp->downstream_ports); intel_dp->dfp.rgb_to_ycbcr = diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 0c8bf477c2fbb..e54aad8a5f7fb 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -689,6 +689,13 @@ bool lspcon_init(struct intel_digital_port *dig_port) return true; } +bool intel_lspcon_active(struct intel_digital_port *dig_port) +{ + struct intel_lspcon *lspcon = &dig_port->lspcon; + + return lspcon->active; +} + u32 intel_lspcon_infoframes_enabled(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) { diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index 47f9ae77b328a..4c8ba3ddbac49 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -16,6 +16,7 @@ struct intel_encoder; struct intel_lspcon; bool lspcon_init(struct intel_digital_port *dig_port); +bool intel_lspcon_active(struct intel_digital_port *dig_port); void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon); void lspcon_resume(struct intel_digital_port *dig_port); void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon); From ab945e9a4e73e8eb3f54ea34dffd22eb70696c03 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 15:58:40 +0200 Subject: [PATCH 148/284] drm/i915/lspcon: change signature of lspcon_detect_hdr_capability() Switch from struct intel_lspcon to struct intel_digital_port to unify, and return the value so the caller doesn't have to look at lspcon->hdr_detected directly. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/6f249f5c537a16a6762faddffd6a95cbf61cf077.1738677489.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 4 +--- drivers/gpu/drm/i915/display/intel_lspcon.c | 5 ++++- drivers/gpu/drm/i915/display/intel_lspcon.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 860f246aeb061..3b2a20553f938 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5863,7 +5863,6 @@ intel_dp_connector_register(struct drm_connector *connector) struct intel_display *display = to_intel_display(connector->dev); struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct intel_lspcon *lspcon = &dig_port->lspcon; int ret; ret = intel_connector_register(connector); @@ -5886,8 +5885,7 @@ intel_dp_connector_register(struct drm_connector *connector) * efficiently and streamlined. */ if (lspcon_init(dig_port)) { - lspcon_detect_hdr_capability(lspcon); - if (lspcon->hdr_supported) + if (lspcon_detect_hdr_capability(dig_port)) drm_connector_attach_hdr_output_metadata_property(connector); } diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index e54aad8a5f7fb..2dd2b700b0f3a 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -121,8 +121,9 @@ static u32 get_hdr_status_reg(struct intel_lspcon *lspcon) return DPCD_PARADE_LSPCON_HDR_STATUS; } -void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon) +bool lspcon_detect_hdr_capability(struct intel_digital_port *dig_port) { + struct intel_lspcon *lspcon = &dig_port->lspcon; struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); struct intel_display *display = to_intel_display(intel_dp); u8 hdr_caps; @@ -138,6 +139,8 @@ void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon) drm_dbg_kms(display->drm, "LSPCON capable of HDR\n"); lspcon->hdr_supported = true; } + + return lspcon->hdr_supported; } static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon) diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index 4c8ba3ddbac49..18cc15e5221d6 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -17,7 +17,7 @@ struct intel_lspcon; bool lspcon_init(struct intel_digital_port *dig_port); bool intel_lspcon_active(struct intel_digital_port *dig_port); -void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon); +bool lspcon_detect_hdr_capability(struct intel_digital_port *dig_port); void lspcon_resume(struct intel_digital_port *dig_port); void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon); void lspcon_write_infoframe(struct intel_encoder *encoder, From 295e276a6af6fadfe31c1afe27a2c670e4f9cbc3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 15:58:41 +0200 Subject: [PATCH 149/284] drm/i915/lspcon: change signature of lspcon_wait_pcon_mode() Switch from struct intel_lspcon to struct intel_digital_port to unify. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/84a00791d3d7ee4e34c1224ef7471918546635aa.1738677489.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 3 +-- drivers/gpu/drm/i915/display/intel_lspcon.c | 4 +++- drivers/gpu/drm/i915/display/intel_lspcon.h | 4 +--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3b2a20553f938..e4676339c3eab 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3520,7 +3520,6 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode) ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, mode); } else { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp); lspcon_resume(dig_port); @@ -3539,7 +3538,7 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode) } if (ret == 1 && intel_lspcon_active(dig_port)) - lspcon_wait_pcon_mode(lspcon); + lspcon_wait_pcon_mode(dig_port); } if (ret != 1) diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 2dd2b700b0f3a..45b63fea3642e 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -656,8 +656,10 @@ u32 lspcon_infoframes_enabled(struct intel_encoder *encoder, return val; } -void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon) +void lspcon_wait_pcon_mode(struct intel_digital_port *dig_port) { + struct intel_lspcon *lspcon = &dig_port->lspcon; + lspcon_wait_mode(lspcon, DRM_LSPCON_MODE_PCON); } diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index 18cc15e5221d6..20581af1ddb2d 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -8,18 +8,16 @@ #include -struct drm_connector; struct drm_connector_state; struct intel_crtc_state; struct intel_digital_port; struct intel_encoder; -struct intel_lspcon; bool lspcon_init(struct intel_digital_port *dig_port); bool intel_lspcon_active(struct intel_digital_port *dig_port); bool lspcon_detect_hdr_capability(struct intel_digital_port *dig_port); void lspcon_resume(struct intel_digital_port *dig_port); -void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon); +void lspcon_wait_pcon_mode(struct intel_digital_port *dig_port); void lspcon_write_infoframe(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, unsigned int type, From 9b98776490ac28c150811f4fa4f88b81a4c97aa5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 15:58:42 +0200 Subject: [PATCH 150/284] drm/i915/lspcon: remove dp_to_lspcon(), hide enc_to_intel_lspcon() There are no users left for dp_to_lspcon(), remove it. The only two users of enc_to_intel_lspcon() are in intel_lspcon.c, so hide it there. v2: Rebase Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/ea14ba07b88ba5ed65d832c89a3415b7a91edea9.1738677489.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_types.h | 12 ------------ drivers/gpu/drm/i915/display/intel_lspcon.c | 5 +++++ 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index f1a9ab4ae85a6..37b1a216b13b7 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1983,24 +1983,12 @@ static inline bool intel_encoder_is_hdmi(struct intel_encoder *encoder) } } -static inline struct intel_lspcon * -enc_to_intel_lspcon(struct intel_encoder *encoder) -{ - return &enc_to_dig_port(encoder)->lspcon; -} - static inline struct intel_digital_port * dp_to_dig_port(struct intel_dp *intel_dp) { return container_of(intel_dp, struct intel_digital_port, dp); } -static inline struct intel_lspcon * -dp_to_lspcon(struct intel_dp *intel_dp) -{ - return &dp_to_dig_port(intel_dp)->lspcon; -} - static inline struct intel_digital_port * hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) { diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 45b63fea3642e..02c22a981fe1a 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -55,6 +55,11 @@ #define LSPCON_PARADE_AVI_IF_KICKOFF (1 << 7) #define LSPCON_PARADE_AVI_IF_DATA_SIZE 32 +static struct intel_lspcon *enc_to_intel_lspcon(struct intel_encoder *encoder) +{ + return &enc_to_dig_port(encoder)->lspcon; +} + static struct intel_dp *lspcon_to_intel_dp(struct intel_lspcon *lspcon) { struct intel_digital_port *dig_port = From 8de6a113ad210194e22211f90f224904e407a4a0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 15:58:43 +0200 Subject: [PATCH 151/284] drm/i915/lspcon: rename interfaces to intel_lspcon_* to unify Rename all the main functions to have intel_lspcon_ prefix. Keep the infoframes hooks named lspcon_ for now, and grouped together, as there'd be a clash with intel_lspcon_infoframes_enabled(). Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/15e8c4133aee89181e6776a44e58f2573cfe23f2.1738677489.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 10 +++++----- drivers/gpu/drm/i915/display/intel_lspcon.c | 10 +++++----- drivers/gpu/drm/i915/display/intel_lspcon.h | 14 ++++++++------ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index e4676339c3eab..7127cda648287 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3521,7 +3521,7 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode) } else { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - lspcon_resume(dig_port); + intel_lspcon_resume(dig_port); /* Write the source OUI as early as possible */ intel_dp_init_source_oui(intel_dp); @@ -3538,7 +3538,7 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode) } if (ret == 1 && intel_lspcon_active(dig_port)) - lspcon_wait_pcon_mode(dig_port); + intel_lspcon_wait_pcon_mode(dig_port); } if (ret != 1) @@ -5388,7 +5388,7 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) if (drm_WARN_ON(display->drm, intel_dp_is_edp(intel_dp))) return connector_status_connected; - lspcon_resume(dig_port); + intel_lspcon_resume(dig_port); if (!intel_dp_get_dpcd(intel_dp)) return connector_status_disconnected; @@ -5883,8 +5883,8 @@ intel_dp_connector_register(struct drm_connector *connector) * ToDo: Clean this up to handle lspcon init and resume more * efficiently and streamlined. */ - if (lspcon_init(dig_port)) { - if (lspcon_detect_hdr_capability(dig_port)) + if (intel_lspcon_init(dig_port)) { + if (intel_lspcon_detect_hdr_capability(dig_port)) drm_connector_attach_hdr_output_metadata_property(connector); } diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 02c22a981fe1a..63c1afa30b05d 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -126,7 +126,7 @@ static u32 get_hdr_status_reg(struct intel_lspcon *lspcon) return DPCD_PARADE_LSPCON_HDR_STATUS; } -bool lspcon_detect_hdr_capability(struct intel_digital_port *dig_port) +bool intel_lspcon_detect_hdr_capability(struct intel_digital_port *dig_port) { struct intel_lspcon *lspcon = &dig_port->lspcon; struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); @@ -661,14 +661,14 @@ u32 lspcon_infoframes_enabled(struct intel_encoder *encoder, return val; } -void lspcon_wait_pcon_mode(struct intel_digital_port *dig_port) +void intel_lspcon_wait_pcon_mode(struct intel_digital_port *dig_port) { struct intel_lspcon *lspcon = &dig_port->lspcon; lspcon_wait_mode(lspcon, DRM_LSPCON_MODE_PCON); } -bool lspcon_init(struct intel_digital_port *dig_port) +bool intel_lspcon_init(struct intel_digital_port *dig_port) { struct intel_display *display = to_intel_display(dig_port); struct intel_dp *intel_dp = &dig_port->dp; @@ -714,7 +714,7 @@ u32 intel_lspcon_infoframes_enabled(struct intel_encoder *encoder, return dig_port->infoframes_enabled(encoder, pipe_config); } -void lspcon_resume(struct intel_digital_port *dig_port) +void intel_lspcon_resume(struct intel_digital_port *dig_port) { struct intel_display *display = to_intel_display(dig_port); struct intel_lspcon *lspcon = &dig_port->lspcon; @@ -724,7 +724,7 @@ void lspcon_resume(struct intel_digital_port *dig_port) return; if (!lspcon->active) { - if (!lspcon_init(dig_port)) { + if (!intel_lspcon_init(dig_port)) { drm_err(display->drm, "LSPCON init failed on port %c\n", port_name(dig_port->base.port)); return; diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index 20581af1ddb2d..41d142a5c4403 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -13,11 +13,15 @@ struct intel_crtc_state; struct intel_digital_port; struct intel_encoder; -bool lspcon_init(struct intel_digital_port *dig_port); +bool intel_lspcon_init(struct intel_digital_port *dig_port); bool intel_lspcon_active(struct intel_digital_port *dig_port); -bool lspcon_detect_hdr_capability(struct intel_digital_port *dig_port); -void lspcon_resume(struct intel_digital_port *dig_port); -void lspcon_wait_pcon_mode(struct intel_digital_port *dig_port); +bool intel_lspcon_detect_hdr_capability(struct intel_digital_port *dig_port); +void intel_lspcon_resume(struct intel_digital_port *dig_port); +void intel_lspcon_wait_pcon_mode(struct intel_digital_port *dig_port); +u32 intel_lspcon_infoframes_enabled(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config); + +/* digital port infoframes hooks */ void lspcon_write_infoframe(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, unsigned int type, @@ -32,7 +36,5 @@ void lspcon_set_infoframes(struct intel_encoder *encoder, const struct drm_connector_state *conn_state); u32 lspcon_infoframes_enabled(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config); -u32 intel_lspcon_infoframes_enabled(struct intel_encoder *encoder, - const struct intel_crtc_state *pipe_config); #endif /* __INTEL_LSPCON_H__ */ From bb68ce5daf1ac73222afbe3f8fa7ad6edd150c72 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 15:42:26 +0200 Subject: [PATCH 152/284] drm/i915/display: convert intel_ddi_buf_trans.c to struct intel_display Going forward, struct intel_display is the main device data structure for display. Switch to it. For MISSING_CASE(), log the PCI ID instead of the platform to get rid of the i915_drv.h dependency. Reviewed-by: Rodrigo Vivi Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20250204134228.2934744-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_ddi_buf_trans.c | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c index 9389b295036e4..a238be5bc4550 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c @@ -3,13 +3,13 @@ * Copyright © 2020 Intel Corporation */ -#include "i915_drv.h" +#include "i915_utils.h" +#include "intel_cx0_phy.h" #include "intel_ddi.h" #include "intel_ddi_buf_trans.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_dp.h" -#include "intel_cx0_phy.h" /* HDMI/DVI modes ignore everything but the last 2 items. So we share * them for both DP and FDI transports, allowing those ports to @@ -1407,10 +1407,10 @@ tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, int *n_entries) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); if (crtc_state->port_clock > 270000) { - if (IS_TIGERLAKE_UY(dev_priv)) { + if (display->platform.tigerlake_uy) { return intel_get_buf_trans(&tgl_uy_combo_phy_trans_dp_hbr2, n_entries); } else { @@ -1709,59 +1709,67 @@ mtl_get_c20_buf_trans(struct intel_encoder *encoder, void intel_ddi_buf_trans_init(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (DISPLAY_VER(i915) >= 14) { + if (DISPLAY_VER(display) >= 14) { if (intel_encoder_is_c10phy(encoder)) encoder->get_buf_trans = mtl_get_c10_buf_trans; else encoder->get_buf_trans = mtl_get_c20_buf_trans; - } else if (IS_DG2(i915)) { + } else if (display->platform.dg2) { encoder->get_buf_trans = dg2_get_snps_buf_trans; - } else if (IS_ALDERLAKE_P(i915)) { + } else if (display->platform.alderlake_p) { if (intel_encoder_is_combo(encoder)) encoder->get_buf_trans = adlp_get_combo_buf_trans; else encoder->get_buf_trans = adlp_get_dkl_buf_trans; - } else if (IS_ALDERLAKE_S(i915)) { + } else if (display->platform.alderlake_s) { encoder->get_buf_trans = adls_get_combo_buf_trans; - } else if (IS_ROCKETLAKE(i915)) { + } else if (display->platform.rocketlake) { encoder->get_buf_trans = rkl_get_combo_buf_trans; - } else if (IS_DG1(i915)) { + } else if (display->platform.dg1) { encoder->get_buf_trans = dg1_get_combo_buf_trans; - } else if (DISPLAY_VER(i915) >= 12) { + } else if (DISPLAY_VER(display) >= 12) { if (intel_encoder_is_combo(encoder)) encoder->get_buf_trans = tgl_get_combo_buf_trans; else encoder->get_buf_trans = tgl_get_dkl_buf_trans; - } else if (DISPLAY_VER(i915) == 11) { - if (IS_JASPERLAKE(i915)) + } else if (DISPLAY_VER(display) == 11) { + if (display->platform.jasperlake) encoder->get_buf_trans = jsl_get_combo_buf_trans; - else if (IS_ELKHARTLAKE(i915)) + else if (display->platform.elkhartlake) encoder->get_buf_trans = ehl_get_combo_buf_trans; else if (intel_encoder_is_combo(encoder)) encoder->get_buf_trans = icl_get_combo_buf_trans; else encoder->get_buf_trans = icl_get_mg_buf_trans; - } else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { + } else if (display->platform.geminilake || display->platform.broxton) { encoder->get_buf_trans = bxt_get_buf_trans; - } else if (IS_COMETLAKE_ULX(i915) || IS_COFFEELAKE_ULX(i915) || IS_KABYLAKE_ULX(i915)) { + } else if (display->platform.cometlake_ulx || + display->platform.coffeelake_ulx || + display->platform.kabylake_ulx) { encoder->get_buf_trans = kbl_y_get_buf_trans; - } else if (IS_COMETLAKE_ULT(i915) || IS_COFFEELAKE_ULT(i915) || IS_KABYLAKE_ULT(i915)) { + } else if (display->platform.cometlake_ult || + display->platform.coffeelake_ult || + display->platform.kabylake_ult) { encoder->get_buf_trans = kbl_u_get_buf_trans; - } else if (IS_COMETLAKE(i915) || IS_COFFEELAKE(i915) || IS_KABYLAKE(i915)) { + } else if (display->platform.cometlake || + display->platform.coffeelake || + display->platform.kabylake) { encoder->get_buf_trans = kbl_get_buf_trans; - } else if (IS_SKYLAKE_ULX(i915)) { + } else if (display->platform.skylake_ulx) { encoder->get_buf_trans = skl_y_get_buf_trans; - } else if (IS_SKYLAKE_ULT(i915)) { + } else if (display->platform.skylake_ult) { encoder->get_buf_trans = skl_u_get_buf_trans; - } else if (IS_SKYLAKE(i915)) { + } else if (display->platform.skylake) { encoder->get_buf_trans = skl_get_buf_trans; - } else if (IS_BROADWELL(i915)) { + } else if (display->platform.broadwell) { encoder->get_buf_trans = bdw_get_buf_trans; - } else if (IS_HASWELL(i915)) { + } else if (display->platform.haswell) { encoder->get_buf_trans = hsw_get_buf_trans; } else { - MISSING_CASE(INTEL_INFO(i915)->platform); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); + + MISSING_CASE(pdev->device); } } From f0453266763841585e6f7d9cb9cd3db18fbb5dbe Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 15:42:27 +0200 Subject: [PATCH 153/284] drm/i915/cdclk: switch to new platform checks Switch the IS_() checks to display->platform., and drop a number of struct drm_i915_private pointers in the process. While at it, replace /* NOOP */; with ; /* NOOP */ to avoid a checkpatch warning on misleading indentation. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20250204134228.2934744-2-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_cdclk.c | 159 +++++++++------------ 1 file changed, 68 insertions(+), 91 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index b520231833b79..753ba3e3a0b71 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -314,27 +314,26 @@ static unsigned int intel_hpll_vco(struct intel_display *display) [4] = 2666667, [5] = 4266667, }; - struct drm_i915_private *dev_priv = to_i915(display->drm); const unsigned int *vco_table; unsigned int vco; u8 tmp = 0; /* FIXME other chipsets? */ - if (IS_GM45(dev_priv)) + if (display->platform.gm45) vco_table = ctg_vco; - else if (IS_G45(dev_priv)) + else if (display->platform.g45) vco_table = elk_vco; - else if (IS_I965GM(dev_priv)) + else if (display->platform.i965gm) vco_table = cl_vco; - else if (IS_PINEVIEW(dev_priv)) + else if (display->platform.pineview) vco_table = pnv_vco; - else if (IS_G33(dev_priv)) + else if (display->platform.g33) vco_table = blb_vco; else return 0; - tmp = intel_de_read(display, - IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv) ? HPLLVCO_MOBILE : HPLLVCO); + tmp = intel_de_read(display, display->platform.pineview || + display->platform.mobile ? HPLLVCO_MOBILE : HPLLVCO); vco = vco_table[tmp & 0x7]; if (vco == 0) @@ -508,7 +507,6 @@ static void gm45_get_cdclk(struct intel_display *display, static void hsw_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 lcpll = intel_de_read(display, LCPLL_CTL); u32 freq = lcpll & LCPLL_CLK_FREQ_MASK; @@ -518,7 +516,7 @@ static void hsw_get_cdclk(struct intel_display *display, cdclk_config->cdclk = 450000; else if (freq == LCPLL_CLK_FREQ_450) cdclk_config->cdclk = 450000; - else if (IS_HASWELL_ULT(dev_priv)) + else if (display->platform.haswell_ult) cdclk_config->cdclk = 337500; else cdclk_config->cdclk = 540000; @@ -535,7 +533,7 @@ static int vlv_calc_cdclk(struct intel_display *display, int min_cdclk) * Not sure what's wrong. For now use 200MHz only when all pipes * are off. */ - if (IS_VALLEYVIEW(dev_priv) && min_cdclk > freq_320) + if (display->platform.valleyview && min_cdclk > freq_320) return 400000; else if (min_cdclk > 266667) return freq_320; @@ -549,7 +547,7 @@ static u8 vlv_calc_voltage_level(struct intel_display *display, int cdclk) { struct drm_i915_private *dev_priv = to_i915(display->drm); - if (IS_VALLEYVIEW(dev_priv)) { + if (display->platform.valleyview) { if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */ return 2; else if (cdclk >= 266667) @@ -585,7 +583,7 @@ static void vlv_get_cdclk(struct intel_display *display, vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT)); - if (IS_VALLEYVIEW(dev_priv)) + if (display->platform.valleyview) cdclk_config->voltage_level = (val & DSPFREQGUAR_MASK) >> DSPFREQGUAR_SHIFT; else @@ -598,14 +596,14 @@ static void vlv_program_pfi_credits(struct intel_display *display) struct drm_i915_private *dev_priv = to_i915(display->drm); unsigned int credits, default_credits; - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) default_credits = PFI_CREDIT(12); else default_credits = PFI_CREDIT(8); if (display->cdclk.hw.cdclk >= dev_priv->czclk_freq) { /* CHV suggested value is 31 or 63 */ - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) credits = PFI_CREDIT_63; else credits = PFI_CREDIT(15); @@ -1142,7 +1140,7 @@ static void skl_set_cdclk(struct intel_display *display, * minimum 308MHz CDCLK. */ drm_WARN_ON_ONCE(display->drm, - IS_SKYLAKE(dev_priv) && vco == 8640000); + display->platform.skylake && vco == 8640000); ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, SKL_CDCLK_PREPARE_FOR_CHANGE, @@ -1662,10 +1660,9 @@ static void icl_readout_refclk(struct intel_display *display, static void bxt_de_pll_readout(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val, ratio; - if (IS_DG2(dev_priv)) + if (display->platform.dg2) cdclk_config->ref = 38400; else if (DISPLAY_VER(display) >= 11) icl_readout_refclk(display, cdclk_config); @@ -2057,11 +2054,9 @@ static bool cdclk_compute_crawl_and_squash_midpoint(struct intel_display *displa static bool pll_enable_wa_needed(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - return (DISPLAY_VERx100(display) == 2000 || DISPLAY_VERx100(display) == 1400 || - IS_DG2(dev_priv)) && + display->platform.dg2) && display->cdclk.hw.vco > 0; } @@ -2069,7 +2064,6 @@ static u32 bxt_cdclk_ctl(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { - struct drm_i915_private *i915 = to_i915(display->drm); int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u16 waveform; @@ -2084,7 +2078,7 @@ static u32 bxt_cdclk_ctl(struct intel_display *display, * Disable SSA Precharge when CD clock frequency < 500 MHz, * enable otherwise. */ - if ((IS_GEMINILAKE(i915) || IS_BROXTON(i915)) && + if ((display->platform.geminilake || display->platform.broxton) && cdclk >= 500000) val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE; @@ -2144,8 +2138,8 @@ static void bxt_set_cdclk(struct intel_display *display, * mailbox communication, skip * this step. */ - if (DISPLAY_VER(display) >= 14 || IS_DG2(dev_priv)) - /* NOOP */; + if (DISPLAY_VER(display) >= 14 || display->platform.dg2) + ; /* NOOP */ else if (DISPLAY_VER(display) >= 11) ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, SKL_CDCLK_PREPARE_FOR_CHANGE, @@ -2186,7 +2180,7 @@ static void bxt_set_cdclk(struct intel_display *display, * NOOP - No Pcode communication needed for * Display versions 14 and beyond */; - else if (DISPLAY_VER(display) >= 11 && !IS_DG2(dev_priv)) + else if (DISPLAY_VER(display) >= 11 && !display->platform.dg2) ret = snb_pcode_write(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, cdclk_config->voltage_level); if (DISPLAY_VER(display) < 11) { @@ -2318,9 +2312,7 @@ static void bxt_cdclk_uninit_hw(struct intel_display *display) */ void intel_cdclk_init_hw(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (DISPLAY_VER(display) >= 10 || IS_BROXTON(i915)) + if (DISPLAY_VER(display) >= 10 || display->platform.broxton) bxt_cdclk_init_hw(display); else if (DISPLAY_VER(display) == 9) skl_cdclk_init_hw(display); @@ -2335,9 +2327,7 @@ void intel_cdclk_init_hw(struct intel_display *display) */ void intel_cdclk_uninit_hw(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (DISPLAY_VER(display) >= 10 || IS_BROXTON(i915)) + if (DISPLAY_VER(display) >= 10 || display->platform.broxton) bxt_cdclk_uninit_hw(display); else if (DISPLAY_VER(display) == 9) skl_cdclk_uninit_hw(display); @@ -2438,10 +2428,8 @@ static bool intel_cdclk_can_cd2x_update(struct intel_display *display, const struct intel_cdclk_config *a, const struct intel_cdclk_config *b) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - /* Older hw doesn't have the capability */ - if (DISPLAY_VER(display) < 10 && !IS_BROXTON(dev_priv)) + if (DISPLAY_VER(display) < 10 && !display->platform.broxton) return false; /* @@ -2495,7 +2483,7 @@ static void intel_pcode_notify(struct intel_display *display, int ret; u32 update_mask = 0; - if (!IS_DG2(i915)) + if (!display->platform.dg2) return; update_mask = DISPLAY_TO_PCODE_UPDATE_MASK(cdclk, active_pipe_count, voltage_level); @@ -2681,7 +2669,6 @@ void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(display->drm); const struct intel_cdclk_state *old_cdclk_state = intel_atomic_get_old_cdclk_state(state); const struct intel_cdclk_state *new_cdclk_state = @@ -2693,7 +2680,7 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state) &new_cdclk_state->actual)) return; - if (IS_DG2(i915)) + if (display->platform.dg2) intel_cdclk_pcode_pre_notify(state); if (new_cdclk_state->disable_pipes) { @@ -2735,7 +2722,6 @@ void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(display->drm); const struct intel_cdclk_state *old_cdclk_state = intel_atomic_get_old_cdclk_state(state); const struct intel_cdclk_state *new_cdclk_state = @@ -2746,7 +2732,7 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state) &new_cdclk_state->actual)) return; - if (IS_DG2(i915)) + if (display->platform.dg2) intel_cdclk_pcode_post_notify(state); if (!new_cdclk_state->disable_pipes && @@ -2770,12 +2756,10 @@ static int intel_cdclk_ppc(struct intel_display *display, bool double_wide) /* max pixel rate as % of CDCLK (not accounting for PPC) */ static int intel_cdclk_guardband(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (DISPLAY_VER(display) >= 9 || - IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) + display->platform.broadwell || display->platform.haswell) return 100; - else if (IS_CHERRYVIEW(dev_priv)) + else if (display->platform.cherryview) return 95; else return 90; @@ -2878,7 +2862,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state) * by changing the cd2x divider (see glk_cdclk_table[]) and * thus a full modeset won't be needed then. */ - if (IS_GEMINILAKE(dev_priv) && cdclk_state->active_pipes && + if (display->platform.geminilake && cdclk_state->active_pipes && !is_power_of_2(cdclk_state->active_pipes)) min_cdclk = max(min_cdclk, 2 * 96000); @@ -3232,7 +3216,6 @@ static bool intel_cdclk_need_serialize(struct intel_display *display, const struct intel_cdclk_state *old_cdclk_state, const struct intel_cdclk_state *new_cdclk_state) { - struct drm_i915_private *i915 = to_i915(display->drm); bool power_well_cnt_changed = hweight8(old_cdclk_state->active_pipes) != hweight8(new_cdclk_state->active_pipes); bool cdclk_changed = intel_cdclk_changed(&old_cdclk_state->actual, @@ -3241,7 +3224,7 @@ static bool intel_cdclk_need_serialize(struct intel_display *display, * We need to poke hw for gen >= 12, because we notify PCode if * pipe power well count changes. */ - return cdclk_changed || (IS_DG2(i915) && power_well_cnt_changed); + return cdclk_changed || (display->platform.dg2 && power_well_cnt_changed); } int intel_modeset_calc_cdclk(struct intel_atomic_state *state) @@ -3376,11 +3359,9 @@ static int intel_compute_max_dotclk(struct intel_display *display) */ void intel_update_max_cdclk(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (DISPLAY_VER(display) >= 30) { display->cdclk.max_cdclk_freq = 691200; - } else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) { + } else if (display->platform.jasperlake || display->platform.elkhartlake) { if (display->cdclk.hw.ref == 24000) display->cdclk.max_cdclk_freq = 552000; else @@ -3390,9 +3371,9 @@ void intel_update_max_cdclk(struct intel_display *display) display->cdclk.max_cdclk_freq = 648000; else display->cdclk.max_cdclk_freq = 652800; - } else if (IS_GEMINILAKE(dev_priv)) { + } else if (display->platform.geminilake) { display->cdclk.max_cdclk_freq = 316800; - } else if (IS_BROXTON(dev_priv)) { + } else if (display->platform.broxton) { display->cdclk.max_cdclk_freq = 624000; } else if (DISPLAY_VER(display) == 9) { u32 limit = intel_de_read(display, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK; @@ -3416,7 +3397,7 @@ void intel_update_max_cdclk(struct intel_display *display) max_cdclk = 308571; display->cdclk.max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco); - } else if (IS_BROADWELL(dev_priv)) { + } else if (display->platform.broadwell) { /* * FIXME with extra cooling we can allow * 540 MHz for ULX and 675 Mhz for ULT. @@ -3425,15 +3406,15 @@ void intel_update_max_cdclk(struct intel_display *display) */ if (intel_de_read(display, FUSE_STRAP) & HSW_CDCLK_LIMIT) display->cdclk.max_cdclk_freq = 450000; - else if (IS_BROADWELL_ULX(dev_priv)) + else if (display->platform.broadwell_ulx) display->cdclk.max_cdclk_freq = 450000; - else if (IS_BROADWELL_ULT(dev_priv)) + else if (display->platform.broadwell_ult) display->cdclk.max_cdclk_freq = 540000; else display->cdclk.max_cdclk_freq = 675000; - } else if (IS_CHERRYVIEW(dev_priv)) { + } else if (display->platform.cherryview) { display->cdclk.max_cdclk_freq = 320000; - } else if (IS_VALLEYVIEW(dev_priv)) { + } else if (display->platform.valleyview) { display->cdclk.max_cdclk_freq = 400000; } else { /* otherwise assume cdclk is fixed */ @@ -3457,8 +3438,6 @@ void intel_update_max_cdclk(struct intel_display *display) */ void intel_update_cdclk(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - intel_cdclk_get_cdclk(display, &display->cdclk.hw); /* @@ -3467,7 +3446,7 @@ void intel_update_cdclk(struct intel_display *display) * of cdclk that generates 4MHz reference clock freq which is used to * generate GMBus clock. This will vary with the cdclk freq. */ - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (display->platform.valleyview || display->platform.cherryview) intel_de_write(display, GMBUSFREQ_VLV, DIV_ROUND_UP(display->cdclk.hw.cdclk, 1000)); } @@ -3561,7 +3540,7 @@ u32 intel_read_rawclk(struct intel_display *display) freq = cnp_rawclk(display); else if (HAS_PCH_SPLIT(dev_priv)) freq = pch_rawclk(display); - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + else if (display->platform.valleyview || display->platform.cherryview) freq = vlv_hrawclk(display); else if (DISPLAY_VER(display) >= 3) freq = i9xx_hrawclk(display); @@ -3742,8 +3721,6 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (DISPLAY_VER(display) >= 30) { display->funcs.cdclk = &xe3lpd_cdclk_funcs; display->cdclk.table = xe3lpd_cdclk_table; @@ -3756,80 +3733,80 @@ void intel_init_cdclk_hooks(struct intel_display *display) } else if (DISPLAY_VER(display) >= 14) { display->funcs.cdclk = &rplu_cdclk_funcs; display->cdclk.table = mtl_cdclk_table; - } else if (IS_DG2(dev_priv)) { + } else if (display->platform.dg2) { display->funcs.cdclk = &tgl_cdclk_funcs; display->cdclk.table = dg2_cdclk_table; - } else if (IS_ALDERLAKE_P(dev_priv)) { + } else if (display->platform.alderlake_p) { /* Wa_22011320316:adl-p[a0] */ - if (IS_ALDERLAKE_P(dev_priv) && IS_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) { + if (display->platform.alderlake_p && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) { display->cdclk.table = adlp_a_step_cdclk_table; display->funcs.cdclk = &tgl_cdclk_funcs; - } else if (IS_RAPTORLAKE_U(dev_priv)) { + } else if (display->platform.alderlake_p_raptorlake_u) { display->cdclk.table = rplu_cdclk_table; display->funcs.cdclk = &rplu_cdclk_funcs; } else { display->cdclk.table = adlp_cdclk_table; display->funcs.cdclk = &tgl_cdclk_funcs; } - } else if (IS_ROCKETLAKE(dev_priv)) { + } else if (display->platform.rocketlake) { display->funcs.cdclk = &tgl_cdclk_funcs; display->cdclk.table = rkl_cdclk_table; } else if (DISPLAY_VER(display) >= 12) { display->funcs.cdclk = &tgl_cdclk_funcs; display->cdclk.table = icl_cdclk_table; - } else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) { + } else if (display->platform.jasperlake || display->platform.elkhartlake) { display->funcs.cdclk = &ehl_cdclk_funcs; display->cdclk.table = icl_cdclk_table; } else if (DISPLAY_VER(display) >= 11) { display->funcs.cdclk = &icl_cdclk_funcs; display->cdclk.table = icl_cdclk_table; - } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + } else if (display->platform.geminilake || display->platform.broxton) { display->funcs.cdclk = &bxt_cdclk_funcs; - if (IS_GEMINILAKE(dev_priv)) + if (display->platform.geminilake) display->cdclk.table = glk_cdclk_table; else display->cdclk.table = bxt_cdclk_table; } else if (DISPLAY_VER(display) == 9) { display->funcs.cdclk = &skl_cdclk_funcs; - } else if (IS_BROADWELL(dev_priv)) { + } else if (display->platform.broadwell) { display->funcs.cdclk = &bdw_cdclk_funcs; - } else if (IS_HASWELL(dev_priv)) { + } else if (display->platform.haswell) { display->funcs.cdclk = &hsw_cdclk_funcs; - } else if (IS_CHERRYVIEW(dev_priv)) { + } else if (display->platform.cherryview) { display->funcs.cdclk = &chv_cdclk_funcs; - } else if (IS_VALLEYVIEW(dev_priv)) { + } else if (display->platform.valleyview) { display->funcs.cdclk = &vlv_cdclk_funcs; - } else if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) { + } else if (display->platform.sandybridge || display->platform.ivybridge) { display->funcs.cdclk = &fixed_400mhz_cdclk_funcs; - } else if (IS_IRONLAKE(dev_priv)) { + } else if (display->platform.ironlake) { display->funcs.cdclk = &ilk_cdclk_funcs; - } else if (IS_GM45(dev_priv)) { + } else if (display->platform.gm45) { display->funcs.cdclk = &gm45_cdclk_funcs; - } else if (IS_G45(dev_priv)) { + } else if (display->platform.g45) { display->funcs.cdclk = &g33_cdclk_funcs; - } else if (IS_I965GM(dev_priv)) { + } else if (display->platform.i965gm) { display->funcs.cdclk = &i965gm_cdclk_funcs; - } else if (IS_I965G(dev_priv)) { + } else if (display->platform.i965g) { display->funcs.cdclk = &fixed_400mhz_cdclk_funcs; - } else if (IS_PINEVIEW(dev_priv)) { + } else if (display->platform.pineview) { display->funcs.cdclk = &pnv_cdclk_funcs; - } else if (IS_G33(dev_priv)) { + } else if (display->platform.g33) { display->funcs.cdclk = &g33_cdclk_funcs; - } else if (IS_I945GM(dev_priv)) { + } else if (display->platform.i945gm) { display->funcs.cdclk = &i945gm_cdclk_funcs; - } else if (IS_I945G(dev_priv)) { + } else if (display->platform.i945g) { display->funcs.cdclk = &fixed_400mhz_cdclk_funcs; - } else if (IS_I915GM(dev_priv)) { + } else if (display->platform.i915gm) { display->funcs.cdclk = &i915gm_cdclk_funcs; - } else if (IS_I915G(dev_priv)) { + } else if (display->platform.i915g) { display->funcs.cdclk = &i915g_cdclk_funcs; - } else if (IS_I865G(dev_priv)) { + } else if (display->platform.i865g) { display->funcs.cdclk = &i865g_cdclk_funcs; - } else if (IS_I85X(dev_priv)) { + } else if (display->platform.i85x) { display->funcs.cdclk = &i85x_cdclk_funcs; - } else if (IS_I845G(dev_priv)) { + } else if (display->platform.i845g) { display->funcs.cdclk = &i845g_cdclk_funcs; - } else if (IS_I830(dev_priv)) { + } else if (display->platform.i830) { display->funcs.cdclk = &i830_cdclk_funcs; } From 76a677c51097057365564c7ac775ed6c1f117a86 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 15:42:28 +0200 Subject: [PATCH 154/284] drm/i915/cx0: convert to struct intel_display based platform checks Switch the IS_() checks to display->platform., and drop a number of struct drm_i915_private pointers in the process. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20250204134228.2934744-3-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 48b0b9755b2b5..0ff76ef10d4bc 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -34,13 +34,13 @@ bool intel_encoder_is_c10phy(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - if (IS_PANTHERLAKE(i915) && phy == PHY_A) + if (display->platform.pantherlake && phy == PHY_A) return true; - if ((IS_LUNARLAKE(i915) || IS_METEORLAKE(i915)) && phy < PHY_C) + if ((display->platform.lunarlake || display->platform.meteorlake) && phy < PHY_C) return true; return false; @@ -3216,12 +3216,11 @@ void intel_mtl_pll_enable(struct intel_encoder *encoder, static u8 cx0_power_control_disable_val(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); if (intel_encoder_is_c10phy(encoder)) return CX0_P2PG_STATE_DISABLE; - if ((IS_BATTLEMAGE(i915) && encoder->port == PORT_A) || + if ((display->platform.battlemage && encoder->port == PORT_A) || (DISPLAY_VER(display) >= 30 && encoder->type == INTEL_OUTPUT_EDP)) return CX0_P2PG_STATE_DISABLE; From d0fcbf81fc798d47c2a62d246a4786d11d050310 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 15:24:23 +0200 Subject: [PATCH 155/284] drm/i915/backlight: convert to use struct intel_display Going forward, struct intel_display will be the main display data structure. Convert as much as possible of backlight code to use it. There are some stragglers mainly around PCH checks. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20250204132423.2910978-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_backlight.c | 494 +++++++++--------- 1 file changed, 260 insertions(+), 234 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 7e6ce905bdafa..477b21af71a4f 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -104,20 +104,20 @@ u32 intel_backlight_invert_pwm_level(struct intel_connector *connector, u32 val) void intel_backlight_set_pwm_level(const struct drm_connector_state *conn_state, u32 val) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] set backlight PWM = %d\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] set backlight PWM = %d\n", connector->base.base.id, connector->base.name, val); panel->backlight.pwm_funcs->set(conn_state, val); } u32 intel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; - drm_WARN_ON_ONCE(&i915->drm, + drm_WARN_ON_ONCE(display->drm, panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0); val = scale(val, panel->backlight.min, panel->backlight.max, @@ -145,32 +145,33 @@ u32 intel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) static u32 lpt_get_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); - return intel_de_read(i915, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK; + return intel_de_read(display, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK; } static u32 pch_get_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); - return intel_de_read(i915, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; + return intel_de_read(display, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; } static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 val; - val = intel_de_read(i915, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; - if (DISPLAY_VER(i915) < 4) + val = intel_de_read(display, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; + if (DISPLAY_VER(display) < 4) val >>= 1; if (panel->backlight.combination_mode) { + struct pci_dev *pdev = to_pci_dev(display->drm->dev); u8 lbpc; - pci_read_config_byte(to_pci_dev(i915->drm.dev), LBPC, &lbpc); + pci_read_config_byte(pdev, LBPC, &lbpc); val *= lbpc; } @@ -179,20 +180,20 @@ static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unuse static u32 vlv_get_backlight(struct intel_connector *connector, enum pipe pipe) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); - if (drm_WARN_ON(&i915->drm, pipe != PIPE_A && pipe != PIPE_B)) + if (drm_WARN_ON(display->drm, pipe != PIPE_A && pipe != PIPE_B)) return 0; - return intel_de_read(i915, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; + return intel_de_read(display, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; } static u32 bxt_get_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; - return intel_de_read(i915, BXT_BLC_PWM_DUTY(panel->backlight.controller)); + return intel_de_read(display, BXT_BLC_PWM_DUTY(panel->backlight.controller)); } static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe unused) @@ -207,69 +208,70 @@ static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe un static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); u32 val; - val = intel_de_read(i915, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; - intel_de_write(i915, BLC_PWM_PCH_CTL2, val | level); + val = intel_de_read(display, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; + intel_de_write(display, BLC_PWM_PCH_CTL2, val | level); } static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); u32 tmp; - tmp = intel_de_read(i915, BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; - intel_de_write(i915, BLC_PWM_CPU_CTL, tmp | level); + tmp = intel_de_read(display, BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + intel_de_write(display, BLC_PWM_CPU_CTL, tmp | level); } static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 tmp, mask; - drm_WARN_ON(&i915->drm, panel->backlight.pwm_level_max == 0); + drm_WARN_ON(display->drm, panel->backlight.pwm_level_max == 0); if (panel->backlight.combination_mode) { + struct pci_dev *pdev = to_pci_dev(display->drm->dev); u8 lbpc; lbpc = level * 0xfe / panel->backlight.pwm_level_max + 1; level /= lbpc; - pci_write_config_byte(to_pci_dev(i915->drm.dev), LBPC, lbpc); + pci_write_config_byte(pdev, LBPC, lbpc); } - if (DISPLAY_VER(i915) == 4) { + if (DISPLAY_VER(display) == 4) { mask = BACKLIGHT_DUTY_CYCLE_MASK; } else { level <<= 1; mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV; } - tmp = intel_de_read(i915, BLC_PWM_CTL) & ~mask; - intel_de_write(i915, BLC_PWM_CTL, tmp | level); + tmp = intel_de_read(display, BLC_PWM_CTL) & ~mask; + intel_de_write(display, BLC_PWM_CTL, tmp | level); } static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe; u32 tmp; - tmp = intel_de_read(i915, VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK; - intel_de_write(i915, VLV_BLC_PWM_CTL(pipe), tmp | level); + tmp = intel_de_read(display, VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK; + intel_de_write(display, VLV_BLC_PWM_CTL(pipe), tmp | level); } static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; - intel_de_write(i915, BXT_BLC_PWM_DUTY(panel->backlight.controller), level); + intel_de_write(display, BXT_BLC_PWM_DUTY(panel->backlight.controller), level); } static void ext_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level) @@ -284,10 +286,10 @@ static void intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] set backlight level = %d\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] set backlight level = %d\n", connector->base.base.id, connector->base.name, level); panel->backlight.funcs->set(conn_state, level); @@ -300,7 +302,7 @@ void intel_backlight_set_acpi(const struct drm_connector_state *conn_state, u32 user_level, u32 user_max) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 hw_level; @@ -313,9 +315,9 @@ void intel_backlight_set_acpi(const struct drm_connector_state *conn_state, if (!panel->backlight.present || !conn_state->crtc) return; - mutex_lock(&i915->display.backlight.lock); + mutex_lock(&display->backlight.lock); - drm_WARN_ON(&i915->drm, panel->backlight.max == 0); + drm_WARN_ON(display->drm, panel->backlight.max == 0); hw_level = clamp_user_to_hw(connector, user_level, user_max); panel->backlight.level = hw_level; @@ -329,13 +331,13 @@ void intel_backlight_set_acpi(const struct drm_connector_state *conn_state, if (panel->backlight.enabled) intel_panel_actually_set_backlight(conn_state, hw_level); - mutex_unlock(&i915->display.backlight.lock); + mutex_unlock(&display->backlight.lock); } static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); u32 tmp; intel_backlight_set_pwm_level(old_conn_state, level); @@ -348,26 +350,26 @@ static void lpt_disable_backlight(const struct drm_connector_state *old_conn_sta * This needs rework if we need to add support for CPU PWM on PCH split * platforms. */ - tmp = intel_de_read(i915, BLC_PWM_CPU_CTL2); + tmp = intel_de_read(display, BLC_PWM_CPU_CTL2); if (tmp & BLM_PWM_ENABLE) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] CPU backlight was enabled, disabling\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] CPU backlight was enabled, disabling\n", connector->base.base.id, connector->base.name); - intel_de_write(i915, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); + intel_de_write(display, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); } - intel_de_rmw(i915, BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE, 0); + intel_de_rmw(display, BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE, 0); } static void pch_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) { struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); intel_backlight_set_pwm_level(old_conn_state, val); - intel_de_rmw(i915, BLC_PWM_CPU_CTL2, BLM_PWM_ENABLE, 0); + intel_de_rmw(display, BLC_PWM_CPU_CTL2, BLM_PWM_ENABLE, 0); - intel_de_rmw(i915, BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE, 0); + intel_de_rmw(display, BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE, 0); } static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) @@ -377,48 +379,49 @@ static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_st static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) { - struct drm_i915_private *i915 = to_i915(old_conn_state->connector->dev); + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + struct intel_display *display = to_intel_display(connector); intel_backlight_set_pwm_level(old_conn_state, val); - intel_de_rmw(i915, BLC_PWM_CTL2, BLM_PWM_ENABLE, 0); + intel_de_rmw(display, BLC_PWM_CTL2, BLM_PWM_ENABLE, 0); } static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) { struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe; intel_backlight_set_pwm_level(old_conn_state, val); - intel_de_rmw(i915, VLV_BLC_PWM_CTL2(pipe), BLM_PWM_ENABLE, 0); + intel_de_rmw(display, VLV_BLC_PWM_CTL2(pipe), BLM_PWM_ENABLE, 0); } static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) { struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; intel_backlight_set_pwm_level(old_conn_state, val); - intel_de_rmw(i915, BXT_BLC_PWM_CTL(panel->backlight.controller), + intel_de_rmw(display, BXT_BLC_PWM_CTL(panel->backlight.controller), BXT_BLC_PWM_ENABLE, 0); if (panel->backlight.controller == 1) - intel_de_rmw(i915, UTIL_PIN_CTL, UTIL_PIN_ENABLE, 0); + intel_de_rmw(display, UTIL_PIN_CTL, UTIL_PIN_ENABLE, 0); } static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) { struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; intel_backlight_set_pwm_level(old_conn_state, val); - intel_de_rmw(i915, BXT_BLC_PWM_CTL(panel->backlight.controller), + intel_de_rmw(display, BXT_BLC_PWM_CTL(panel->backlight.controller), BXT_BLC_PWM_ENABLE, 0); } @@ -436,7 +439,7 @@ static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn void intel_backlight_disable(const struct drm_connector_state *old_conn_state) { struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; if (!panel->backlight.present) @@ -448,49 +451,51 @@ void intel_backlight_disable(const struct drm_connector_state *old_conn_state) * backlight. This will leave the backlight on unnecessarily when * another client is not activated. */ - if (i915->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] Skipping backlight disable on vga switch\n", + if (display->drm->switch_power_state == DRM_SWITCH_POWER_CHANGING) { + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Skipping backlight disable on vga switch\n", connector->base.base.id, connector->base.name); return; } - mutex_lock(&i915->display.backlight.lock); + mutex_lock(&display->backlight.lock); if (panel->backlight.device) panel->backlight.device->props.power = BACKLIGHT_POWER_OFF; panel->backlight.enabled = false; panel->backlight.funcs->disable(old_conn_state, 0); - mutex_unlock(&i915->display.backlight.lock); + mutex_unlock(&display->backlight.lock); } static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct intel_display *display = to_intel_display(connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; u32 pch_ctl1, pch_ctl2; - pch_ctl1 = intel_de_read(i915, BLC_PWM_PCH_CTL1); + pch_ctl1 = intel_de_read(display, BLC_PWM_PCH_CTL1); if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] PCH backlight already enabled\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] PCH backlight already enabled\n", connector->base.base.id, connector->base.name); pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; - intel_de_write(i915, BLC_PWM_PCH_CTL1, pch_ctl1); + intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1); } if (HAS_PCH_LPT(i915)) - intel_de_rmw(i915, SOUTH_CHICKEN2, LPT_PWM_GRANULARITY, + intel_de_rmw(display, SOUTH_CHICKEN2, LPT_PWM_GRANULARITY, panel->backlight.alternate_pwm_increment ? LPT_PWM_GRANULARITY : 0); else - intel_de_rmw(i915, SOUTH_CHICKEN1, SPT_PWM_GRANULARITY, + intel_de_rmw(display, SOUTH_CHICKEN1, SPT_PWM_GRANULARITY, panel->backlight.alternate_pwm_increment ? SPT_PWM_GRANULARITY : 0); pch_ctl2 = panel->backlight.pwm_level_max << 16; - intel_de_write(i915, BLC_PWM_PCH_CTL2, pch_ctl2); + intel_de_write(display, BLC_PWM_PCH_CTL2, pch_ctl2); pch_ctl1 = 0; if (panel->backlight.active_low_pwm) @@ -500,9 +505,9 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, if (HAS_PCH_LPT(i915)) pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE; - intel_de_write(i915, BLC_PWM_PCH_CTL1, pch_ctl1); - intel_de_posting_read(i915, BLC_PWM_PCH_CTL1); - intel_de_write(i915, BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); + intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1); + intel_de_posting_read(display, BLC_PWM_PCH_CTL1); + intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); /* This won't stick until the above enable. */ intel_backlight_set_pwm_level(conn_state, level); @@ -512,63 +517,66 @@ static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 cpu_ctl2, pch_ctl1, pch_ctl2; - cpu_ctl2 = intel_de_read(i915, BLC_PWM_CPU_CTL2); + cpu_ctl2 = intel_de_read(display, BLC_PWM_CPU_CTL2); if (cpu_ctl2 & BLM_PWM_ENABLE) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] CPU backlight already enabled\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] CPU backlight already enabled\n", connector->base.base.id, connector->base.name); cpu_ctl2 &= ~BLM_PWM_ENABLE; - intel_de_write(i915, BLC_PWM_CPU_CTL2, cpu_ctl2); + intel_de_write(display, BLC_PWM_CPU_CTL2, cpu_ctl2); } - pch_ctl1 = intel_de_read(i915, BLC_PWM_PCH_CTL1); + pch_ctl1 = intel_de_read(display, BLC_PWM_PCH_CTL1); if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] PCH backlight already enabled\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] PCH backlight already enabled\n", connector->base.base.id, connector->base.name); pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; - intel_de_write(i915, BLC_PWM_PCH_CTL1, pch_ctl1); + intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1); } if (cpu_transcoder == TRANSCODER_EDP) cpu_ctl2 = BLM_TRANSCODER_EDP; else cpu_ctl2 = BLM_PIPE(cpu_transcoder); - intel_de_write(i915, BLC_PWM_CPU_CTL2, cpu_ctl2); - intel_de_posting_read(i915, BLC_PWM_CPU_CTL2); - intel_de_write(i915, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); + intel_de_write(display, BLC_PWM_CPU_CTL2, cpu_ctl2); + intel_de_posting_read(display, BLC_PWM_CPU_CTL2); + intel_de_write(display, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); /* This won't stick until the above enable. */ intel_backlight_set_pwm_level(conn_state, level); pch_ctl2 = panel->backlight.pwm_level_max << 16; - intel_de_write(i915, BLC_PWM_PCH_CTL2, pch_ctl2); + intel_de_write(display, BLC_PWM_PCH_CTL2, pch_ctl2); pch_ctl1 = 0; if (panel->backlight.active_low_pwm) pch_ctl1 |= BLM_PCH_POLARITY; - intel_de_write(i915, BLC_PWM_PCH_CTL1, pch_ctl1); - intel_de_posting_read(i915, BLC_PWM_PCH_CTL1); - intel_de_write(i915, BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); + intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1); + intel_de_posting_read(display, BLC_PWM_PCH_CTL1); + intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); } static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 ctl, freq; - ctl = intel_de_read(i915, BLC_PWM_CTL); + ctl = intel_de_read(display, BLC_PWM_CTL); if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] backlight already enabled\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] backlight already enabled\n", connector->base.base.id, connector->base.name); - intel_de_write(i915, BLC_PWM_CTL, 0); + intel_de_write(display, BLC_PWM_CTL, 0); } freq = panel->backlight.pwm_level_max; @@ -578,11 +586,11 @@ static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state, ctl = freq << 17; if (panel->backlight.combination_mode) ctl |= BLM_LEGACY_MODE; - if (IS_PINEVIEW(i915) && panel->backlight.active_low_pwm) + if (display->platform.pineview && panel->backlight.active_low_pwm) ctl |= BLM_POLARITY_PNV; - intel_de_write(i915, BLC_PWM_CTL, ctl); - intel_de_posting_read(i915, BLC_PWM_CTL); + intel_de_write(display, BLC_PWM_CTL, ctl); + intel_de_posting_read(display, BLC_PWM_CTL); /* XXX: combine this into above write? */ intel_backlight_set_pwm_level(conn_state, level); @@ -592,25 +600,26 @@ static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state, * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2 * that has backlight. */ - if (DISPLAY_VER(i915) == 2) - intel_de_write(i915, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE); + if (DISPLAY_VER(display) == 2) + intel_de_write(display, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE); } static void i965_enable_backlight(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe; u32 ctl, ctl2, freq; - ctl2 = intel_de_read(i915, BLC_PWM_CTL2); + ctl2 = intel_de_read(display, BLC_PWM_CTL2); if (ctl2 & BLM_PWM_ENABLE) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] backlight already enabled\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] backlight already enabled\n", connector->base.base.id, connector->base.name); ctl2 &= ~BLM_PWM_ENABLE; - intel_de_write(i915, BLC_PWM_CTL2, ctl2); + intel_de_write(display, BLC_PWM_CTL2, ctl2); } freq = panel->backlight.pwm_level_max; @@ -618,16 +627,16 @@ static void i965_enable_backlight(const struct intel_crtc_state *crtc_state, freq /= 0xff; ctl = freq << 16; - intel_de_write(i915, BLC_PWM_CTL, ctl); + intel_de_write(display, BLC_PWM_CTL, ctl); ctl2 = BLM_PIPE(pipe); if (panel->backlight.combination_mode) ctl2 |= BLM_COMBINATION_MODE; if (panel->backlight.active_low_pwm) ctl2 |= BLM_POLARITY_I965; - intel_de_write(i915, BLC_PWM_CTL2, ctl2); - intel_de_posting_read(i915, BLC_PWM_CTL2); - intel_de_write(i915, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); + intel_de_write(display, BLC_PWM_CTL2, ctl2); + intel_de_posting_read(display, BLC_PWM_CTL2); + intel_de_write(display, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); intel_backlight_set_pwm_level(conn_state, level); } @@ -636,21 +645,22 @@ static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; u32 ctl, ctl2; - ctl2 = intel_de_read(i915, VLV_BLC_PWM_CTL2(pipe)); + ctl2 = intel_de_read(display, VLV_BLC_PWM_CTL2(pipe)); if (ctl2 & BLM_PWM_ENABLE) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] backlight already enabled\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] backlight already enabled\n", connector->base.base.id, connector->base.name); ctl2 &= ~BLM_PWM_ENABLE; - intel_de_write(i915, VLV_BLC_PWM_CTL2(pipe), ctl2); + intel_de_write(display, VLV_BLC_PWM_CTL2(pipe), ctl2); } ctl = panel->backlight.pwm_level_max << 16; - intel_de_write(i915, VLV_BLC_PWM_CTL(pipe), ctl); + intel_de_write(display, VLV_BLC_PWM_CTL(pipe), ctl); /* XXX: combine this into above write? */ intel_backlight_set_pwm_level(conn_state, level); @@ -658,47 +668,49 @@ static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, ctl2 = 0; if (panel->backlight.active_low_pwm) ctl2 |= BLM_POLARITY_I965; - intel_de_write(i915, VLV_BLC_PWM_CTL2(pipe), ctl2); - intel_de_posting_read(i915, VLV_BLC_PWM_CTL2(pipe)); - intel_de_write(i915, VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE); + intel_de_write(display, VLV_BLC_PWM_CTL2(pipe), ctl2); + intel_de_posting_read(display, VLV_BLC_PWM_CTL2(pipe)); + intel_de_write(display, VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE); } static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; u32 pwm_ctl, val; /* Controller 1 uses the utility pin. */ if (panel->backlight.controller == 1) { - val = intel_de_read(i915, UTIL_PIN_CTL); + val = intel_de_read(display, UTIL_PIN_CTL); if (val & UTIL_PIN_ENABLE) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] utility pin already enabled\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] utility pin already enabled\n", connector->base.base.id, connector->base.name); val &= ~UTIL_PIN_ENABLE; - intel_de_write(i915, UTIL_PIN_CTL, val); + intel_de_write(display, UTIL_PIN_CTL, val); } val = 0; if (panel->backlight.util_pin_active_low) val |= UTIL_PIN_POLARITY; - intel_de_write(i915, UTIL_PIN_CTL, + intel_de_write(display, UTIL_PIN_CTL, val | UTIL_PIN_PIPE(pipe) | UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE); } - pwm_ctl = intel_de_read(i915, BXT_BLC_PWM_CTL(panel->backlight.controller)); + pwm_ctl = intel_de_read(display, BXT_BLC_PWM_CTL(panel->backlight.controller)); if (pwm_ctl & BXT_BLC_PWM_ENABLE) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] backlight already enabled\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] backlight already enabled\n", connector->base.base.id, connector->base.name); pwm_ctl &= ~BXT_BLC_PWM_ENABLE; - intel_de_write(i915, BXT_BLC_PWM_CTL(panel->backlight.controller), + intel_de_write(display, BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl); } - intel_de_write(i915, BXT_BLC_PWM_FREQ(panel->backlight.controller), + intel_de_write(display, BXT_BLC_PWM_FREQ(panel->backlight.controller), panel->backlight.pwm_level_max); intel_backlight_set_pwm_level(conn_state, level); @@ -707,9 +719,9 @@ static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state, if (panel->backlight.active_low_pwm) pwm_ctl |= BXT_BLC_PWM_POLARITY; - intel_de_write(i915, BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl); - intel_de_posting_read(i915, BXT_BLC_PWM_CTL(panel->backlight.controller)); - intel_de_write(i915, BXT_BLC_PWM_CTL(panel->backlight.controller), + intel_de_write(display, BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl); + intel_de_posting_read(display, BXT_BLC_PWM_CTL(panel->backlight.controller)); + intel_de_write(display, BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl | BXT_BLC_PWM_ENABLE); } @@ -717,19 +729,19 @@ static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 pwm_ctl; - pwm_ctl = intel_de_read(i915, BXT_BLC_PWM_CTL(panel->backlight.controller)); + pwm_ctl = intel_de_read(display, BXT_BLC_PWM_CTL(panel->backlight.controller)); if (pwm_ctl & BXT_BLC_PWM_ENABLE) { - drm_dbg_kms(&i915->drm, "backlight already enabled\n"); + drm_dbg_kms(display->drm, "backlight already enabled\n"); pwm_ctl &= ~BXT_BLC_PWM_ENABLE; - intel_de_write(i915, BXT_BLC_PWM_CTL(panel->backlight.controller), + intel_de_write(display, BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl); } - intel_de_write(i915, BXT_BLC_PWM_FREQ(panel->backlight.controller), + intel_de_write(display, BXT_BLC_PWM_FREQ(panel->backlight.controller), panel->backlight.pwm_level_max); intel_backlight_set_pwm_level(conn_state, level); @@ -738,9 +750,9 @@ static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state, if (panel->backlight.active_low_pwm) pwm_ctl |= BXT_BLC_PWM_POLARITY; - intel_de_write(i915, BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl); - intel_de_posting_read(i915, BXT_BLC_PWM_CTL(panel->backlight.controller)); - intel_de_write(i915, BXT_BLC_PWM_CTL(panel->backlight.controller), + intel_de_write(display, BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl); + intel_de_posting_read(display, BXT_BLC_PWM_CTL(panel->backlight.controller)); + intel_de_write(display, BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl | BXT_BLC_PWM_ENABLE); } @@ -782,37 +794,37 @@ void intel_backlight_enable(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; if (!panel->backlight.present) return; - drm_dbg_kms(&i915->drm, "pipe %c\n", pipe_name(pipe)); + drm_dbg_kms(display->drm, "pipe %c\n", pipe_name(pipe)); - mutex_lock(&i915->display.backlight.lock); + mutex_lock(&display->backlight.lock); __intel_backlight_enable(crtc_state, conn_state); - mutex_unlock(&i915->display.backlight.lock); + mutex_unlock(&display->backlight.lock); } #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) static u32 intel_panel_get_backlight(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 val = 0; - mutex_lock(&i915->display.backlight.lock); + mutex_lock(&display->backlight.lock); if (panel->backlight.enabled) val = panel->backlight.funcs->get(connector, intel_connector_get_pipe(connector)); - mutex_unlock(&i915->display.backlight.lock); + mutex_unlock(&display->backlight.lock); - drm_dbg_kms(&i915->drm, "get backlight PWM = %d\n", val); + drm_dbg_kms(display->drm, "get backlight PWM = %d\n", val); return val; } @@ -831,16 +843,16 @@ static void intel_panel_set_backlight(const struct drm_connector_state *conn_sta u32 user_level, u32 user_max) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 hw_level; if (!panel->backlight.present) return; - mutex_lock(&i915->display.backlight.lock); + mutex_lock(&display->backlight.lock); - drm_WARN_ON(&i915->drm, panel->backlight.max == 0); + drm_WARN_ON(display->drm, panel->backlight.max == 0); hw_level = scale_user_to_hw(connector, user_level, user_max); panel->backlight.level = hw_level; @@ -848,18 +860,18 @@ static void intel_panel_set_backlight(const struct drm_connector_state *conn_sta if (panel->backlight.enabled) intel_panel_actually_set_backlight(conn_state, hw_level); - mutex_unlock(&i915->display.backlight.lock); + mutex_unlock(&display->backlight.lock); } static int intel_backlight_device_update_status(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; - drm_modeset_lock(&i915->drm.mode_config.connection_mutex, NULL); + drm_modeset_lock(&display->drm->mode_config.connection_mutex, NULL); - drm_dbg_kms(&i915->drm, "updating intel_backlight, brightness=%d/%d\n", + drm_dbg_kms(display->drm, "updating intel_backlight, brightness=%d/%d\n", bd->props.brightness, bd->props.max_brightness); intel_panel_set_backlight(connector->base.state, bd->props.brightness, bd->props.max_brightness); @@ -880,7 +892,7 @@ static int intel_backlight_device_update_status(struct backlight_device *bd) bd->props.power = BACKLIGHT_POWER_OFF; } - drm_modeset_unlock(&i915->drm.mode_config.connection_mutex); + drm_modeset_unlock(&display->drm->mode_config.connection_mutex); return 0; } @@ -888,6 +900,7 @@ static int intel_backlight_device_update_status(struct backlight_device *bd) static int intel_backlight_device_get_brightness(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); + struct intel_display *display = to_intel_display(connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); intel_wakeref_t wakeref; int ret = 0; @@ -895,13 +908,13 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd) with_intel_runtime_pm(&i915->runtime_pm, wakeref) { u32 hw_level; - drm_modeset_lock(&i915->drm.mode_config.connection_mutex, NULL); + drm_modeset_lock(&display->drm->mode_config.connection_mutex, NULL); hw_level = intel_panel_get_backlight(connector); ret = scale_hw_to_user(connector, hw_level, bd->props.max_brightness); - drm_modeset_unlock(&i915->drm.mode_config.connection_mutex); + drm_modeset_unlock(&display->drm->mode_config.connection_mutex); } return ret; @@ -914,7 +927,7 @@ static const struct backlight_ops intel_backlight_device_ops = { int intel_backlight_device_register(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; struct backlight_properties props; struct backlight_device *bd; @@ -930,7 +943,8 @@ int intel_backlight_device_register(struct intel_connector *connector) WARN_ON(panel->backlight.max == 0); if (!acpi_video_backlight_use_native()) { - drm_info(&i915->drm, "Skipping intel_backlight registration\n"); + drm_info(display->drm, + "Skipping intel_backlight registration\n"); return 0; } @@ -967,7 +981,8 @@ int intel_backlight_device_register(struct intel_connector *connector) */ kfree(name); name = kasprintf(GFP_KERNEL, "card%d-%s-backlight", - i915->drm.primary->index, connector->base.name); + display->drm->primary->index, + connector->base.name); if (!name) return -ENOMEM; } @@ -975,7 +990,7 @@ int intel_backlight_device_register(struct intel_connector *connector) &intel_backlight_device_ops, &props); if (IS_ERR(bd)) { - drm_err(&i915->drm, + drm_err(display->drm, "[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n", connector->base.base.id, connector->base.name, name, PTR_ERR(bd)); ret = PTR_ERR(bd); @@ -984,7 +999,7 @@ int intel_backlight_device_register(struct intel_connector *connector) panel->backlight.device = bd; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] backlight device %s registered\n", connector->base.base.id, connector->base.name, name); @@ -1011,9 +1026,9 @@ void intel_backlight_device_unregister(struct intel_connector *connector) */ static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); - return DIV_ROUND_CLOSEST(KHz(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq), + return DIV_ROUND_CLOSEST(KHz(DISPLAY_RUNTIME_INFO(display)->rawclk_freq), pwm_freq_hz); } @@ -1073,9 +1088,9 @@ static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) */ static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); - return DIV_ROUND_CLOSEST(KHz(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq), + return DIV_ROUND_CLOSEST(KHz(DISPLAY_RUNTIME_INFO(display)->rawclk_freq), pwm_freq_hz * 128); } @@ -1089,13 +1104,13 @@ static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) */ static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); int clock; - if (IS_PINEVIEW(i915)) - clock = KHz(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq); + if (display->platform.pineview) + clock = KHz(DISPLAY_RUNTIME_INFO(display)->rawclk_freq); else - clock = KHz(i915->display.cdclk.hw.cdclk); + clock = KHz(display->cdclk.hw.cdclk); return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32); } @@ -1107,13 +1122,13 @@ static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) */ static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); int clock; - if (IS_G4X(i915)) - clock = KHz(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq); + if (display->platform.g4x) + clock = KHz(DISPLAY_RUNTIME_INFO(display)->rawclk_freq); else - clock = KHz(i915->display.cdclk.hw.cdclk); + clock = KHz(display->cdclk.hw.cdclk); return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128); } @@ -1125,17 +1140,17 @@ static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) */ static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); int mul, clock; - if ((intel_de_read(i915, CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) { - if (IS_CHERRYVIEW(i915)) + if ((intel_de_read(display, CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) { + if (display->platform.cherryview) clock = KHz(19200); else clock = MHz(25); mul = 16; } else { - clock = KHz(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq); + clock = KHz(DISPLAY_RUNTIME_INFO(display)->rawclk_freq); mul = 128; } @@ -1144,16 +1159,16 @@ static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) static u16 get_vbt_pwm_freq(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); u16 pwm_freq_hz = connector->panel.vbt.backlight.pwm_freq_hz; if (pwm_freq_hz) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "VBT defined backlight frequency %u Hz\n", pwm_freq_hz); } else { pwm_freq_hz = 200; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "default backlight frequency %u Hz\n", pwm_freq_hz); } @@ -1163,20 +1178,20 @@ static u16 get_vbt_pwm_freq(struct intel_connector *connector) static u32 get_backlight_max_vbt(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u16 pwm_freq_hz = get_vbt_pwm_freq(connector); u32 pwm; if (!panel->backlight.pwm_funcs->hz_to_pwm) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "backlight frequency conversion not supported\n"); return 0; } pwm = panel->backlight.pwm_funcs->hz_to_pwm(connector, pwm_freq_hz); if (!pwm) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "backlight frequency conversion failed\n"); return 0; } @@ -1189,11 +1204,11 @@ static u32 get_backlight_max_vbt(struct intel_connector *connector) */ static u32 get_backlight_min_vbt(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; int min; - drm_WARN_ON(&i915->drm, panel->backlight.pwm_level_max == 0); + drm_WARN_ON(display->drm, panel->backlight.pwm_level_max == 0); /* * XXX: If the vbt value is 255, it makes min equal to max, which leads @@ -1204,7 +1219,7 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector) */ min = clamp_t(int, connector->panel.vbt.backlight.min_brightness, 0, 64); if (min != connector->panel.vbt.backlight.min_brightness) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "clamping VBT min backlight %d/255 to %d/255\n", connector->panel.vbt.backlight.min_brightness, min); } @@ -1215,24 +1230,25 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector) static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused) { + struct intel_display *display = to_intel_display(connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; u32 cpu_ctl2, pch_ctl1, pch_ctl2, val; bool alt, cpu_mode; if (HAS_PCH_LPT(i915)) - alt = intel_de_read(i915, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY; + alt = intel_de_read(display, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY; else - alt = intel_de_read(i915, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY; + alt = intel_de_read(display, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY; panel->backlight.alternate_pwm_increment = alt; - pch_ctl1 = intel_de_read(i915, BLC_PWM_PCH_CTL1); + pch_ctl1 = intel_de_read(display, BLC_PWM_PCH_CTL1); panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; - pch_ctl2 = intel_de_read(i915, BLC_PWM_PCH_CTL2); + pch_ctl2 = intel_de_read(display, BLC_PWM_PCH_CTL2); panel->backlight.pwm_level_max = pch_ctl2 >> 16; - cpu_ctl2 = intel_de_read(i915, BLC_PWM_CPU_CTL2); + cpu_ctl2 = intel_de_read(display, BLC_PWM_CPU_CTL2); if (!panel->backlight.pwm_level_max) panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); @@ -1251,19 +1267,19 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus if (cpu_mode) { val = pch_get_backlight(connector, unused); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "CPU backlight register was enabled, switching to PCH override\n"); /* Write converted CPU PWM value to PCH override register */ lpt_set_backlight(connector->base.state, val); - intel_de_write(i915, BLC_PWM_PCH_CTL1, + intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE); - intel_de_write(i915, BLC_PWM_CPU_CTL2, + intel_de_write(display, BLC_PWM_CPU_CTL2, cpu_ctl2 & ~BLM_PWM_ENABLE); } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Using native PCH PWM for backlight control\n", connector->base.base.id, connector->base.name); @@ -1272,14 +1288,14 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 cpu_ctl2, pch_ctl1, pch_ctl2; - pch_ctl1 = intel_de_read(i915, BLC_PWM_PCH_CTL1); + pch_ctl1 = intel_de_read(display, BLC_PWM_PCH_CTL1); panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; - pch_ctl2 = intel_de_read(i915, BLC_PWM_PCH_CTL2); + pch_ctl2 = intel_de_read(display, BLC_PWM_PCH_CTL2); panel->backlight.pwm_level_max = pch_ctl2 >> 16; if (!panel->backlight.pwm_level_max) @@ -1290,11 +1306,11 @@ static int pch_setup_backlight(struct intel_connector *connector, enum pipe unus panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); - cpu_ctl2 = intel_de_read(i915, BLC_PWM_CPU_CTL2); + cpu_ctl2 = intel_de_read(display, BLC_PWM_CPU_CTL2); panel->backlight.pwm_enabled = (cpu_ctl2 & BLM_PWM_ENABLE) && (pch_ctl1 & BLM_PCH_PWM_ENABLE); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Using native PCH PWM for backlight control\n", connector->base.base.id, connector->base.name); @@ -1303,16 +1319,16 @@ static int pch_setup_backlight(struct intel_connector *connector, enum pipe unus static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 ctl, val; - ctl = intel_de_read(i915, BLC_PWM_CTL); + ctl = intel_de_read(display, BLC_PWM_CTL); - if (DISPLAY_VER(i915) == 2 || IS_I915GM(i915) || IS_I945GM(i915)) + if (DISPLAY_VER(display) == 2 || display->platform.i915gm || display->platform.i945gm) panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE; - if (IS_PINEVIEW(i915)) + if (display->platform.pineview) panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV; panel->backlight.pwm_level_max = ctl >> 17; @@ -1336,7 +1352,7 @@ static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unu panel->backlight.pwm_enabled = val != 0; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Using native PWM for backlight control\n", connector->base.base.id, connector->base.name); @@ -1345,15 +1361,15 @@ static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unu static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 ctl, ctl2; - ctl2 = intel_de_read(i915, BLC_PWM_CTL2); + ctl2 = intel_de_read(display, BLC_PWM_CTL2); panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE; panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; - ctl = intel_de_read(i915, BLC_PWM_CTL); + ctl = intel_de_read(display, BLC_PWM_CTL); panel->backlight.pwm_level_max = ctl >> 16; if (!panel->backlight.pwm_level_max) @@ -1369,7 +1385,7 @@ static int i965_setup_backlight(struct intel_connector *connector, enum pipe unu panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Using native PWM for backlight control\n", connector->base.base.id, connector->base.name); @@ -1378,17 +1394,17 @@ static int i965_setup_backlight(struct intel_connector *connector, enum pipe unu static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 ctl, ctl2; - if (drm_WARN_ON(&i915->drm, pipe != PIPE_A && pipe != PIPE_B)) + if (drm_WARN_ON(display->drm, pipe != PIPE_A && pipe != PIPE_B)) return -ENODEV; - ctl2 = intel_de_read(i915, VLV_BLC_PWM_CTL2(pipe)); + ctl2 = intel_de_read(display, VLV_BLC_PWM_CTL2(pipe)); panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; - ctl = intel_de_read(i915, VLV_BLC_PWM_CTL(pipe)); + ctl = intel_de_read(display, VLV_BLC_PWM_CTL(pipe)); panel->backlight.pwm_level_max = ctl >> 16; if (!panel->backlight.pwm_level_max) @@ -1401,7 +1417,7 @@ static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Using native PWM for backlight control (on pipe %c)\n", connector->base.base.id, connector->base.name, pipe_name(pipe)); @@ -1411,25 +1427,25 @@ static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe static int bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 pwm_ctl, val; panel->backlight.controller = connector->panel.vbt.backlight.controller; - pwm_ctl = intel_de_read(i915, + pwm_ctl = intel_de_read(display, BXT_BLC_PWM_CTL(panel->backlight.controller)); /* Controller 1 uses the utility pin. */ if (panel->backlight.controller == 1) { - val = intel_de_read(i915, UTIL_PIN_CTL); + val = intel_de_read(display, UTIL_PIN_CTL); panel->backlight.util_pin_active_low = val & UTIL_PIN_POLARITY; } panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; panel->backlight.pwm_level_max = - intel_de_read(i915, BXT_BLC_PWM_FREQ(panel->backlight.controller)); + intel_de_read(display, BXT_BLC_PWM_FREQ(panel->backlight.controller)); if (!panel->backlight.pwm_level_max) panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); @@ -1441,7 +1457,7 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Using native PWM for backlight control (controller=%d)\n", connector->base.base.id, connector->base.name, panel->backlight.controller); @@ -1449,8 +1465,10 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) return 0; } -static int cnp_num_backlight_controllers(struct drm_i915_private *i915) +static int cnp_num_backlight_controllers(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); + if (INTEL_PCH_TYPE(i915) >= PCH_MTL) return 2; @@ -1463,15 +1481,17 @@ static int cnp_num_backlight_controllers(struct drm_i915_private *i915) return 1; } -static bool cnp_backlight_controller_is_valid(struct drm_i915_private *i915, int controller) +static bool cnp_backlight_controller_is_valid(struct intel_display *display, int controller) { - if (controller < 0 || controller >= cnp_num_backlight_controllers(i915)) + struct drm_i915_private *i915 = to_i915(display->drm); + + if (controller < 0 || controller >= cnp_num_backlight_controllers(display)) return false; if (controller == 1 && INTEL_PCH_TYPE(i915) >= PCH_ICP && INTEL_PCH_TYPE(i915) <= PCH_ADP) - return intel_de_read(i915, SOUTH_CHICKEN1) & ICP_SECOND_PPS_IO_SELECT; + return intel_de_read(display, SOUTH_CHICKEN1) & ICP_SECOND_PPS_IO_SELECT; return true; } @@ -1479,7 +1499,7 @@ static bool cnp_backlight_controller_is_valid(struct drm_i915_private *i915, int static int cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 pwm_ctl; @@ -1488,19 +1508,20 @@ cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) * controller. ICP+ can have two controllers, depending on pin muxing. */ panel->backlight.controller = connector->panel.vbt.backlight.controller; - if (!cnp_backlight_controller_is_valid(i915, panel->backlight.controller)) { - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] Invalid backlight controller %d, assuming 0\n", + if (!cnp_backlight_controller_is_valid(display, panel->backlight.controller)) { + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] Invalid backlight controller %d, assuming 0\n", connector->base.base.id, connector->base.name, panel->backlight.controller); panel->backlight.controller = 0; } - pwm_ctl = intel_de_read(i915, + pwm_ctl = intel_de_read(display, BXT_BLC_PWM_CTL(panel->backlight.controller)); panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; panel->backlight.pwm_level_max = - intel_de_read(i915, BXT_BLC_PWM_FREQ(panel->backlight.controller)); + intel_de_read(display, BXT_BLC_PWM_FREQ(panel->backlight.controller)); if (!panel->backlight.pwm_level_max) panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); @@ -1512,7 +1533,7 @@ cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Using native PCH PWM for backlight control (controller=%d)\n", connector->base.base.id, connector->base.name, panel->backlight.controller); @@ -1523,22 +1544,25 @@ cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) static int ext_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; const char *desc; u32 level; /* Get the right PWM chip for DSI backlight according to VBT */ if (connector->panel.vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) { - panel->backlight.pwm = pwm_get(i915->drm.dev, "pwm_pmic_backlight"); + panel->backlight.pwm = pwm_get(display->drm->dev, + "pwm_pmic_backlight"); desc = "PMIC"; } else { - panel->backlight.pwm = pwm_get(i915->drm.dev, "pwm_soc_backlight"); + panel->backlight.pwm = pwm_get(display->drm->dev, + "pwm_soc_backlight"); desc = "SoC"; } if (IS_ERR(panel->backlight.pwm)) { - drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to get the %s PWM chip\n", + drm_err(display->drm, + "[CONNECTOR:%d:%s] Failed to get the %s PWM chip\n", connector->base.base.id, connector->base.name, desc); panel->backlight.pwm = NULL; return -ENODEV; @@ -1556,7 +1580,8 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector, level = intel_backlight_invert_pwm_level(connector, level); panel->backlight.pwm_enabled = true; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] PWM already enabled at freq %ld, VBT freq %d, level %d\n", + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] PWM already enabled at freq %ld, VBT freq %d, level %d\n", connector->base.base.id, connector->base.name, NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period, get_vbt_pwm_freq(connector), level); @@ -1566,7 +1591,7 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector, NSEC_PER_SEC / get_vbt_pwm_freq(connector); } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Using %s PWM for backlight control\n", connector->base.base.id, connector->base.name, desc); @@ -1632,17 +1657,17 @@ void intel_backlight_update(struct intel_atomic_state *state, const struct drm_connector_state *conn_state) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; if (!panel->backlight.present) return; - mutex_lock(&i915->display.backlight.lock); + mutex_lock(&display->backlight.lock); if (!panel->backlight.enabled) __intel_backlight_enable(crtc_state, conn_state); - mutex_unlock(&i915->display.backlight.lock); + mutex_unlock(&display->backlight.lock); } int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe) @@ -1793,13 +1818,14 @@ void intel_backlight_init_funcs(struct intel_panel *panel) { struct intel_connector *connector = container_of(panel, struct intel_connector, panel); + struct intel_display *display = to_intel_display(connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI && intel_dsi_dcs_init_backlight_funcs(connector) == 0) return; - if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { + if (display->platform.geminilake || display->platform.broxton) { panel->backlight.pwm_funcs = &bxt_pwm_funcs; } else if (INTEL_PCH_TYPE(i915) >= PCH_CNP) { panel->backlight.pwm_funcs = &cnp_pwm_funcs; @@ -1810,13 +1836,13 @@ void intel_backlight_init_funcs(struct intel_panel *panel) panel->backlight.pwm_funcs = &spt_pwm_funcs; } else if (HAS_PCH_SPLIT(i915)) { panel->backlight.pwm_funcs = &pch_pwm_funcs; - } else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { + } else if (display->platform.valleyview || display->platform.cherryview) { if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) { panel->backlight.pwm_funcs = &ext_pwm_funcs; } else { panel->backlight.pwm_funcs = &vlv_pwm_funcs; } - } else if (DISPLAY_VER(i915) == 4) { + } else if (DISPLAY_VER(display) == 4) { panel->backlight.pwm_funcs = &i965_pwm_funcs; } else { panel->backlight.pwm_funcs = &i9xx_pwm_funcs; @@ -1826,7 +1852,7 @@ void intel_backlight_init_funcs(struct intel_panel *panel) if (intel_dp_aux_init_backlight_funcs(connector) == 0) return; - if (!intel_has_quirk(&i915->display, QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK)) + if (!intel_has_quirk(display, QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK)) connector->panel.backlight.power = intel_pps_backlight_power; } From aa0a9861bf5157c51cda8191813d1b52374d5c78 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Feb 2025 16:05:18 +0200 Subject: [PATCH 156/284] drm/i915/psr: clarify intel_psr_pre_plane_update() conditions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the conditions easier to follow. We don't do anything for !psr->enabled, so hoist psr->enabled check higher, avoiding all the checks when !psr->enabled. Stop the bitwise OR abuse on booleans by removing the temporary variable altogether. v2: Rebase Cc: Jouni Högander Cc: Suraj Kandpal Reviewed-by: Jouni Högander # v1 Link: https://patchwork.freedesktop.org/patch/msgid/20250204140518.2971530-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_psr.c | 46 +++++++++++------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 2bdb6c9c22835..861e50ceef859 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2804,34 +2804,30 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, old_crtc_state->uapi.encoder_mask) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_psr *psr = &intel_dp->psr; - bool needs_to_disable = false; mutex_lock(&psr->lock); - /* - * Reasons to disable: - * - PSR disabled in new state - * - All planes will go inactive - * - Changing between PSR versions - * - Region Early Transport changing - * - Display WA #1136: skl, bxt - */ - needs_to_disable |= intel_crtc_needs_modeset(new_crtc_state); - needs_to_disable |= !new_crtc_state->has_psr; - needs_to_disable |= !new_crtc_state->active_planes; - needs_to_disable |= new_crtc_state->has_sel_update != psr->sel_update_enabled; - needs_to_disable |= new_crtc_state->enable_psr2_su_region_et != - psr->su_region_et_enabled; - needs_to_disable |= new_crtc_state->has_panel_replay != - psr->panel_replay_enabled; - needs_to_disable |= DISPLAY_VER(i915) < 11 && - new_crtc_state->wm_level_disabled; - - if (psr->enabled && needs_to_disable) - intel_psr_disable_locked(intel_dp); - else if (psr->enabled && new_crtc_state->wm_level_disabled) - /* Wa_14015648006 */ - wm_optimization_wa(intel_dp, new_crtc_state); + if (psr->enabled) { + /* + * Reasons to disable: + * - PSR disabled in new state + * - All planes will go inactive + * - Changing between PSR versions + * - Region Early Transport changing + * - Display WA #1136: skl, bxt + */ + if (intel_crtc_needs_modeset(new_crtc_state) || + !new_crtc_state->has_psr || + !new_crtc_state->active_planes || + new_crtc_state->has_sel_update != psr->sel_update_enabled || + new_crtc_state->enable_psr2_su_region_et != psr->su_region_et_enabled || + new_crtc_state->has_panel_replay != psr->panel_replay_enabled || + (DISPLAY_VER(i915) < 11 && new_crtc_state->wm_level_disabled)) + intel_psr_disable_locked(intel_dp); + else if (new_crtc_state->wm_level_disabled) + /* Wa_14015648006 */ + wm_optimization_wa(intel_dp, new_crtc_state); + } mutex_unlock(&psr->lock); } From 241d8312131e66f31754659bd49169e1822ac1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 22 Jan 2025 17:17:51 +0200 Subject: [PATCH 157/284] drm/i915: Move VT-d alignment into plane->min_alignment() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we don't account for the VT-d alignment w/a in plane->min_alignment() which means that panning inside a larger framebuffer can still cause the plane SURF to be misaligned. Fix the issue by moving the VT-d alignment w/a into plane->min_alignment() itself (for the affected platforms). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250122151755.6928-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/i9xx_plane.c | 10 ++++++++++ drivers/gpu/drm/i915/display/intel_cursor.c | 5 +++++ drivers/gpu/drm/i915/display/intel_fb_pin.c | 8 -------- drivers/gpu/drm/i915/display/intel_sprite.c | 5 +++++ drivers/gpu/drm/i915/display/skl_universal_plane.c | 4 ++++ 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index ed171fbf8720c..19cc34babef35 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -780,9 +780,14 @@ unsigned int vlv_plane_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { + struct drm_i915_private *i915 = to_i915(plane->base.dev); + if (intel_plane_can_async_flip(plane, fb->modifier)) return 256 * 1024; + if (intel_scanout_needs_vtd_wa(i915)) + return 256 * 1024; + switch (fb->modifier) { case I915_FORMAT_MOD_X_TILED: return 4 * 1024; @@ -798,9 +803,14 @@ static unsigned int g4x_primary_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { + struct drm_i915_private *i915 = to_i915(plane->base.dev); + if (intel_plane_can_async_flip(plane, fb->modifier)) return 256 * 1024; + if (intel_scanout_needs_vtd_wa(i915)) + return 256 * 1024; + switch (fb->modifier) { case I915_FORMAT_MOD_X_TILED: case DRM_FORMAT_MOD_LINEAR: diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 48c3d212f690c..ed8e653645390 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -372,6 +372,11 @@ static unsigned int i9xx_cursor_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { + struct drm_i915_private *i915 = to_i915(plane->base.dev); + + if (intel_scanout_needs_vtd_wa(i915)) + return 256 * 1024; + return 4 * 1024; /* physical for i915/i945 */ } diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index dd3ac7f98dfcc..2b9ad46eaef7f 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -126,14 +126,6 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, if (drm_WARN_ON(dev, alignment && !is_power_of_2(alignment))) return ERR_PTR(-EINVAL); - /* Note that the w/a also requires 64 PTE of padding following the - * bo. We currently fill all unused PTE with the shadow page and so - * we should always have valid PTE following the scanout preventing - * the VT-d warning. - */ - if (intel_scanout_needs_vtd_wa(dev_priv) && alignment < 256 * 1024) - alignment = 256 * 1024; - /* * Global gtt pte registers are special registers which actually forward * writes to a chunk of system memory. Which means that there is no risk diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index 13996d7059ad1..d63e71fe469ed 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -980,6 +980,11 @@ static unsigned int g4x_sprite_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { + struct drm_i915_private *i915 = to_i915(plane->base.dev); + + if (intel_scanout_needs_vtd_wa(i915)) + return 256 * 1024; + return 4 * 1024; } diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index ba5db553c3742..d4774abbf462a 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -645,6 +645,10 @@ static u32 skl_plane_min_alignment(struct intel_plane *plane, if (color_plane != 0) return 4 * 1024; + /* + * VT-d needs at least 256k alignment, + * but that's already covered below. + */ switch (fb->modifier) { case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_X_TILED: From 2ffa4878512d429eecffe4ef786cbf102a8b8165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 22 Jan 2025 17:17:52 +0200 Subject: [PATCH 158/284] drm/i915: Use more optimal VTd alignment for planes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Depending on the platform and/or plane type we can get away with a bit less alignment in the VT-d w/a. Reduce the numbers accordingly. Note that it's not actually clear in VLV/CHV need this w/a, and if they do we don't actually know what kind of alignment is sufficient. Leave the 256k alignment in place for now, but toss in a FIXME. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250122151755.6928-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/i9xx_plane.c | 1 + drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_sprite.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 19cc34babef35..65a2eb9e92c40 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -785,6 +785,7 @@ unsigned int vlv_plane_min_alignment(struct intel_plane *plane, if (intel_plane_can_async_flip(plane, fb->modifier)) return 256 * 1024; + /* FIXME undocumented so not sure what's actually needed */ if (intel_scanout_needs_vtd_wa(i915)) return 256 * 1024; diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index ed8e653645390..cbeea9d965174 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -375,7 +375,7 @@ static unsigned int i9xx_cursor_min_alignment(struct intel_plane *plane, struct drm_i915_private *i915 = to_i915(plane->base.dev); if (intel_scanout_needs_vtd_wa(i915)) - return 256 * 1024; + return 64 * 1024; return 4 * 1024; /* physical for i915/i945 */ } diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index d63e71fe469ed..af121c720b89d 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -983,7 +983,7 @@ static unsigned int g4x_sprite_min_alignment(struct intel_plane *plane, struct drm_i915_private *i915 = to_i915(plane->base.dev); if (intel_scanout_needs_vtd_wa(i915)) - return 256 * 1024; + return 128 * 1024; return 4 * 1024; } From 44a34dec43e8f214913e16204525d7253acc1891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 22 Jan 2025 17:17:53 +0200 Subject: [PATCH 159/284] drm/i915: Calculate the VT-d guard size in the display code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently i915_gem_object_pin_to_display_plane() uses i915_gem_object_get_tile_row_size() to calculate the tile row size for the VT-d guard w/a. That's not really proper since i915_gem_object_get_tile_row_size() only works for fenced BOs, nor does it take rotation into account. Remedy the situation by calculating the VT-d guard size in the display code where we have more information readily available. Although the default guard size (168 PTEs now) should cover the more typical fb size use cases anyway, and only very large Y/Yf-tiled framebuffers might have tile row size that exceeds it. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250122151755.6928-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_fb.c | 33 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_fb.h | 3 ++ drivers/gpu/drm/i915/display/intel_fb_pin.c | 12 ++++++- drivers/gpu/drm/i915/display/intel_fb_pin.h | 1 + drivers/gpu/drm/i915/display/intel_fbdev.c | 2 ++ drivers/gpu/drm/i915/display/intel_overlay.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_domain.c | 15 ++------- drivers/gpu/drm/i915/gem/i915_gem_object.h | 2 +- drivers/gpu/drm/xe/display/xe_fb_pin.c | 1 + drivers/gpu/drm/xe/display/xe_plane_initial.c | 2 +- 10 files changed, 57 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 9f7f1b9f32750..ea8c8a99c5c7e 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1761,6 +1761,39 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * return 0; } +unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb, + const struct intel_fb_view *view, + unsigned int rotation) +{ + struct drm_i915_private *i915 = to_i915(fb->dev); + unsigned int vtd_guard; + int color_plane; + + if (!intel_scanout_needs_vtd_wa(i915)) + return 0; + + vtd_guard = 168; + + for (color_plane = 0; color_plane < fb->format->num_planes; color_plane++) { + unsigned int stride, tile; + + if (intel_fb_is_ccs_aux_plane(fb, color_plane) || + is_gen12_ccs_cc_plane(fb, color_plane)) + continue; + + stride = view->color_plane[color_plane].mapping_stride; + + if (drm_rotation_90_or_270(rotation)) + tile = intel_tile_height(fb, color_plane); + else + tile = intel_tile_width_bytes(fb, color_plane); + + vtd_guard = max(vtd_guard, DIV_ROUND_UP(stride, tile)); + } + + return vtd_guard; +} + static void intel_plane_remap_gtt(struct intel_plane_state *plane_state) { struct drm_i915_private *i915 = diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index d78993e5eb629..026e9f7f98f7d 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -83,6 +83,9 @@ bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb); int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb); void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotation, struct intel_fb_view *view); +unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb, + const struct intel_fb_view *view, + unsigned int rotation); int intel_plane_compute_gtt(struct intel_plane_state *plane_state); int intel_framebuffer_init(struct intel_framebuffer *ifb, diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index 2b9ad46eaef7f..204e7e3e48cac 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -107,6 +107,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, const struct i915_gtt_view *view, unsigned int alignment, unsigned int phys_alignment, + unsigned int vtd_guard, bool uses_fence, unsigned long *out_flags) { @@ -162,7 +163,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, goto err; vma = i915_gem_object_pin_to_display_plane(obj, &ww, alignment, - view, pinctl); + vtd_guard, view, pinctl); if (IS_ERR(vma)) { ret = PTR_ERR(vma); goto err_unpin; @@ -244,6 +245,14 @@ intel_plane_fb_min_phys_alignment(const struct intel_plane_state *plane_state) return plane->min_alignment(plane, fb, 0); } +static unsigned int +intel_plane_fb_vtd_guard(const struct intel_plane_state *plane_state) +{ + return intel_fb_view_vtd_guard(plane_state->hw.fb, + &plane_state->view, + plane_state->hw.rotation); +} + int intel_plane_pin_fb(struct intel_plane_state *plane_state, const struct intel_plane_state *old_plane_state) { @@ -256,6 +265,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state, vma = intel_fb_pin_to_ggtt(&fb->base, &plane_state->view.gtt, intel_plane_fb_min_alignment(plane_state), intel_plane_fb_min_phys_alignment(plane_state), + intel_plane_fb_vtd_guard(plane_state), intel_plane_uses_fence(plane_state), &plane_state->flags); if (IS_ERR(vma)) diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h index 0fc6d90446381..01770dbba2e08 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.h +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h @@ -18,6 +18,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, const struct i915_gtt_view *view, unsigned int alignment, unsigned int phys_alignment, + unsigned int vtd_guard, bool uses_fence, unsigned long *out_flags); diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 6c08081333976..833cded53d370 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -228,6 +228,8 @@ static int intelfb_create(struct drm_fb_helper *helper, */ vma = intel_fb_pin_to_ggtt(&fb->base, &view, fb->min_alignment, 0, + intel_fb_view_vtd_guard(&fb->base, &fb->normal_view, + DRM_MODE_ROTATE_0), false, &flags); if (IS_ERR(vma)) { ret = PTR_ERR(vma); diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index bbb0db33740e9..4d00db86131b6 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -778,7 +778,7 @@ static struct i915_vma *intel_overlay_pin_fb(struct drm_i915_gem_object *new_bo) retry: ret = i915_gem_object_lock(new_bo, &ww); if (!ret) { - vma = i915_gem_object_pin_to_display_plane(new_bo, &ww, 0, + vma = i915_gem_object_pin_to_display_plane(new_bo, &ww, 0, 0, NULL, PIN_MAPPABLE); ret = PTR_ERR_OR_ZERO(vma); } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c index ee55caca67a11..75a143d996e0e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@ -18,8 +18,6 @@ #include "i915_gem_object_frontbuffer.h" #include "i915_vma.h" -#define VTD_GUARD (168u * I915_GTT_PAGE_SIZE) /* 168 or tile-row PTE padding */ - static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj) { struct drm_i915_private *i915 = to_i915(obj->base.dev); @@ -424,7 +422,7 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, struct i915_vma * i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, struct i915_gem_ww_ctx *ww, - u32 alignment, + u32 alignment, unsigned int guard, const struct i915_gtt_view *view, unsigned int flags) { @@ -453,15 +451,8 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, return ERR_PTR(ret); /* VT-d may overfetch before/after the vma, so pad with scratch */ - if (intel_scanout_needs_vtd_wa(i915)) { - unsigned int guard = VTD_GUARD; - - if (i915_gem_object_is_tiled(obj)) - guard = max(guard, - i915_gem_object_get_tile_row_size(obj)); - - flags |= PIN_OFFSET_GUARD | guard; - } + if (guard) + flags |= PIN_OFFSET_GUARD | (guard * I915_GTT_PAGE_SIZE); /* * As the user may map the buffer once pinned in the display plane diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index bb713e096db28..a5f34542135ce 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -776,7 +776,7 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write); struct i915_vma * __must_check i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, struct i915_gem_ww_ctx *ww, - u32 alignment, + u32 alignment, unsigned int guard, const struct i915_gtt_view *view, unsigned int flags); diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 25ce032bb293f..11a6b996d739b 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -369,6 +369,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, const struct i915_gtt_view *view, unsigned int alignment, unsigned int phys_alignment, + unsigned int vtd_guard, bool uses_fence, unsigned long *out_flags) { diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c b/drivers/gpu/drm/xe/display/xe_plane_initial.c index 2a2f250fa495d..25c80dd6d3863 100644 --- a/drivers/gpu/drm/xe/display/xe_plane_initial.c +++ b/drivers/gpu/drm/xe/display/xe_plane_initial.c @@ -215,7 +215,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, plane_state->uapi.rotation, &plane_state->view); vma = intel_fb_pin_to_ggtt(fb, &plane_state->view.gtt, - 0, 0, false, &plane_state->flags); + 0, 0, 0, false, &plane_state->flags); if (IS_ERR(vma)) goto nofb; From 4d291c441bbc78805e6a4775383bd5a6f53d2e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 22 Jan 2025 17:17:54 +0200 Subject: [PATCH 160/284] drm/i915: Use per-plane VT-d guard numbers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bspec lists different VT-d guard numbers (the number of dummy padding PTEs) for different platforms and plane types. Use those instead of just assuming the max glk+ number for everything. This could avoid a bit of overhead on older platforms due to reduced padding, and it makes it easier to cross check with the spec. Note that VLV/CHV do not document this w/a at all, so not sure if it's actually needed or not. Nor do we actually know how much padding is required if it is needed. For now use the same 128 PTEs that we use for snb-bdw primary planes. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250122151755.6928-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/i9xx_plane.c | 4 ++++ drivers/gpu/drm/i915/display/intel_cursor.c | 3 +++ .../drm/i915/display/intel_display_types.h | 2 ++ drivers/gpu/drm/i915/display/intel_fb.c | 23 +++++++++++++++---- drivers/gpu/drm/i915/display/intel_sprite.c | 10 ++++++++ .../drm/i915/display/skl_universal_plane.c | 3 +++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 65a2eb9e92c40..bd3f8db137007 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -958,6 +958,10 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) else plane->min_alignment = i9xx_plane_min_alignment; + /* FIXME undocumented for VLV/CHV so not sure what's actually needed */ + if (intel_scanout_needs_vtd_wa(dev_priv)) + plane->vtd_guard = 128; + if (IS_I830(dev_priv) || IS_I845G(dev_priv)) { plane->update_arm = i830_plane_update_arm; } else { diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index cbeea9d965174..6a1035a22b0a3 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -1019,6 +1019,9 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, else cursor->min_alignment = i9xx_cursor_min_alignment; + if (intel_scanout_needs_vtd_wa(dev_priv)) + cursor->vtd_guard = 2; + cursor->update_arm = i9xx_cursor_update_arm; cursor->disable_arm = i9xx_cursor_disable_arm; cursor->get_hw_state = i9xx_cursor_get_hw_state; diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 37b1a216b13b7..d8a3d4d6aedf8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -144,6 +144,7 @@ struct intel_framebuffer { struct i915_address_space *dpt_vm; unsigned int min_alignment; + unsigned int vtd_guard; }; enum intel_hotplug_state { @@ -1448,6 +1449,7 @@ struct intel_plane { enum plane_id id; enum pipe pipe; bool need_async_flip_toggle_wa; + u8 vtd_guard; u32 frontbuffer_bit; struct { diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index ea8c8a99c5c7e..d9328877cc6db 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1660,6 +1660,22 @@ static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb) return min_alignment; } +static unsigned int intel_fb_vtd_guard(const struct drm_framebuffer *fb) +{ + struct drm_i915_private *i915 = to_i915(fb->dev); + struct intel_plane *plane; + unsigned int vtd_guard = 0; + + for_each_intel_plane(&i915->drm, plane) { + if (!drm_plane_has_format(&plane->base, fb->format->format, fb->modifier)) + continue; + + vtd_guard = max_t(unsigned int, vtd_guard, plane->vtd_guard); + } + + return vtd_guard; +} + int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb) { struct drm_gem_object *obj = intel_fb_bo(&fb->base); @@ -1757,6 +1773,7 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * } fb->min_alignment = intel_fb_min_alignment(&fb->base); + fb->vtd_guard = intel_fb_vtd_guard(&fb->base); return 0; } @@ -1765,15 +1782,13 @@ unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb, const struct intel_fb_view *view, unsigned int rotation) { - struct drm_i915_private *i915 = to_i915(fb->dev); unsigned int vtd_guard; int color_plane; - if (!intel_scanout_needs_vtd_wa(i915)) + vtd_guard = to_intel_framebuffer(fb)->vtd_guard; + if (!vtd_guard) return 0; - vtd_guard = 168; - for (color_plane = 0; color_plane < fb->format->num_planes; color_plane++) { unsigned int stride, tile; diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index af121c720b89d..a6b27798fdc3f 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -1609,6 +1609,10 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane->min_alignment = vlv_plane_min_alignment; plane->min_cdclk = vlv_plane_min_cdclk; + /* FIXME undocumented for VLV/CHV so not sure what's actually needed */ + if (intel_scanout_needs_vtd_wa(dev_priv)) + plane->vtd_guard = 128; + if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { formats = chv_pipe_b_sprite_formats; num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats); @@ -1635,6 +1639,9 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane->min_alignment = g4x_sprite_min_alignment; + if (intel_scanout_needs_vtd_wa(dev_priv)) + plane->vtd_guard = 64; + formats = snb_sprite_formats; num_formats = ARRAY_SIZE(snb_sprite_formats); @@ -1649,6 +1656,9 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane->min_alignment = g4x_sprite_min_alignment; plane->min_cdclk = g4x_sprite_min_cdclk; + if (intel_scanout_needs_vtd_wa(dev_priv)) + plane->vtd_guard = 64; + if (IS_SANDYBRIDGE(dev_priv)) { formats = snb_sprite_formats; num_formats = ARRAY_SIZE(snb_sprite_formats); diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index d4774abbf462a..ee93361bba097 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2750,6 +2750,9 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, else plane->min_alignment = skl_plane_min_alignment; + if (intel_scanout_needs_vtd_wa(dev_priv)) + plane->vtd_guard = DISPLAY_VER(dev_priv) >= 10 ? 168 : 136; + if (DISPLAY_VER(dev_priv) >= 11) { plane->update_noarm = icl_plane_update_noarm; plane->update_arm = icl_plane_update_arm; From badff5fed9ce968b22ae2d4c4239e2f3223987b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 22 Jan 2025 17:17:55 +0200 Subject: [PATCH 161/284] drm/i915/fbdev: Use fb->normal_view.gtt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Grab the GTT view for the fbdev fb pinning from fb->normal_view.gtt instead of having and extra one on the stack. Seems safer in case we ever put any new information into normal GTT views. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250122151755.6928-6-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_fbdev.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 833cded53d370..301b5fd301a23 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -177,9 +177,6 @@ static int intelfb_create(struct drm_fb_helper *helper, struct intel_framebuffer *fb = ifbdev->fb; struct drm_device *dev = helper->dev; struct drm_i915_private *dev_priv = to_i915(dev); - const struct i915_gtt_view view = { - .type = I915_GTT_VIEW_NORMAL, - }; intel_wakeref_t wakeref; struct fb_info *info; struct i915_vma *vma; @@ -226,7 +223,7 @@ static int intelfb_create(struct drm_fb_helper *helper, * This also validates that any existing fb inherited from the * BIOS is suitable for own access. */ - vma = intel_fb_pin_to_ggtt(&fb->base, &view, + vma = intel_fb_pin_to_ggtt(&fb->base, &fb->normal_view.gtt, fb->min_alignment, 0, intel_fb_view_vtd_guard(&fb->base, &fb->normal_view, DRM_MODE_ROTATE_0), From 93ecd4fbad16c90a9aded8e599a4ef75dada9f82 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 6 Feb 2025 02:17:26 +0200 Subject: [PATCH 162/284] drm/i915/dp_mst: Fix getting display pointer in intel_dp_mst_compute_min_hblank() The MST intel_connector::encoder pointer is NULL if the connector hasn't been enabled before, so it can't be used to retrieve the display pointer. Use instead the crtc_state and drop the unused connector parameter. v2: Use the crtc_state and drop the unused connector parameter. Fixes: a5ebe00c2ace ("drm/i915/dp: Guarantee a minimum HBlank time") Reported-and-tested-by: Khaled Almahallawy Closes: https://lore.kernel.org/all/16754ee4cd21d99c1e81c5953134b496dd07630f.camel@intel.com Reviewed-by: Khaled Almahallawy #v1 Cc: Arun R Murthy Cc: Suraj Kandpal Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250206001726.3021787-1-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index cc6e4ca375193..2324ca8f60962 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -210,11 +210,9 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec } static void intel_dp_mst_compute_min_hblank(struct intel_crtc_state *crtc_state, - struct intel_connector *connector, int bpp_x16) { - struct intel_encoder *encoder = connector->encoder; - struct intel_display *display = to_intel_display(encoder); + struct intel_display *display = to_intel_display(crtc_state); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; int symbol_size = intel_dp_is_uhbr(crtc_state) ? 32 : 8; @@ -301,7 +299,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, false, dsc_slice_count, link_bpp_x16); - intel_dp_mst_compute_min_hblank(crtc_state, connector, link_bpp_x16); + intel_dp_mst_compute_min_hblank(crtc_state, link_bpp_x16); intel_dp_mst_compute_m_n(crtc_state, local_bw_overhead, From 5dfc37a6b77bf6beedbd30d70184b54e1a08ccac Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 6 Feb 2025 12:02:46 +0530 Subject: [PATCH 163/284] drm/dp: Add eDP 1.5 bit definition Add the eDP revision bit value for 1.5. Spec: eDPv1.5 Table 16-5 Signed-off-by: Suraj Kandpal Reviewed-by: Arun R Murthy Tested-by: Ben Kao Acked-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20250206063253.2827017-2-suraj.kandpal@intel.com --- include/drm/display/drm_dp.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index a6f8b098c56f1..76162ad3b1521 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -996,6 +996,7 @@ # define DP_EDP_14 0x03 # define DP_EDP_14a 0x04 /* eDP 1.4a */ # define DP_EDP_14b 0x05 /* eDP 1.4b */ +# define DP_EDP_15 0x06 /* eDP 1.5 */ #define DP_EDP_GENERAL_CAP_1 0x701 # define DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP (1 << 0) From 9ee1855644254ef0e80b1c376f3d4b18a4528060 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 6 Feb 2025 12:02:47 +0530 Subject: [PATCH 164/284] drm/dp: Increase eDP display control capability size Increase the eDP display control capability size to take into account the general capability register 703 and 704 that have recently been added. Signed-off-by: Suraj Kandpal Reviewed-by: Arun R Murthy Acked-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20250206063253.2827017-3-suraj.kandpal@intel.com --- include/drm/display/drm_dp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 76162ad3b1521..4449819e6ed70 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -1656,7 +1656,7 @@ enum drm_dp_phy { #define DP_RECEIVER_CAP_SIZE 0xf #define DP_DSC_RECEIVER_CAP_SIZE 0x10 /* DSC Capabilities 0x60 through 0x6F */ #define EDP_PSR_RECEIVER_CAP_SIZE 2 -#define EDP_DISPLAY_CTL_CAP_SIZE 3 +#define EDP_DISPLAY_CTL_CAP_SIZE 5 #define DP_LTTPR_COMMON_CAP_SIZE 8 #define DP_LTTPR_PHY_CAP_SIZE 3 From 9535c6a4c61cc0da28b9c9986aad200f1e1019e4 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 6 Feb 2025 12:02:48 +0530 Subject: [PATCH 165/284] drm/i915/backlight: Use proper interface based on eDP version eDP is supposed to use VESA interface when using revision 1.5 and above, use Intel interface for backlight control otherwise. Add check to use correct interface. Signed-off-by: Suraj Kandpal Tested-by: Ben Kao Reviewed-by: Arun R Murthy Link: https://patchwork.freedesktop.org/patch/msgid/20250206063253.2827017-4-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index c846ef4acf5b2..09e82f24d0302 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -604,6 +604,7 @@ static const struct intel_panel_bl_funcs intel_dp_vesa_bl_funcs = { int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) { struct intel_display *display = to_intel_display(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); struct drm_device *dev = connector->base.dev; struct intel_panel *panel = &connector->panel; bool try_intel_interface = false, try_vesa_interface = false; @@ -640,6 +641,10 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) break; } + /* For eDP 1.5 and above we are supposed to use VESA interface for brightness control */ + if (intel_dp->edp_dpcd[0] >= DP_EDP_15) + try_vesa_interface = true; + /* * Since Intel has their own backlight control interface, the majority of machines out there * using DPCD backlight controls with Intel GPUs will be using this interface as opposed to @@ -653,7 +658,8 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) * backlight interface at all. This means that the only sensible way for us to detect both * interfaces is to probe for Intel's first, and VESA's second. */ - if (try_intel_interface && intel_dp_aux_supports_hdr_backlight(connector)) { + if (try_intel_interface && intel_dp_aux_supports_hdr_backlight(connector) && + intel_dp->edp_dpcd[0] <= DP_EDP_14b) { drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Using Intel proprietary eDP backlight controls\n", connector->base.base.id, connector->base.name); panel->backlight.funcs = &intel_dp_hdr_bl_funcs; From 64481497924d8055fa7d6e60948ca899fe341cb6 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 6 Feb 2025 12:02:49 +0530 Subject: [PATCH 166/284] drm/i915/backlight: Check Luminance based brightness control for VESA Check if we are capable of controlling brightness via luminance which is dependent on PANEL_LUMINANCE_CONTROL_CAPABLE bit being set on EDP_GENERAL_CAPABILITY_2 register. --v2 -Prefer using luminance rather than nits [Jani] -Fix commit message --v3 -Fix the bit name used in commit message [Arun] -Use correct edp_dpcd[] to check the capability [Arun] Signed-off-by: Suraj Kandpal Tested-by: Ben Kao Reviewed-by: Arun R Murthy Link: https://patchwork.freedesktop.org/patch/msgid/20250206063253.2827017-5-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index d8a3d4d6aedf8..6a82c6ade549b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -413,6 +413,7 @@ struct intel_panel { union { struct { struct drm_edp_backlight_info info; + bool luminance_control_support; } vesa; struct { bool sdr_uses_aux; diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index 09e82f24d0302..2599aa39b21df 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -575,6 +575,15 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector) { struct intel_display *display = to_intel_display(connector); struct intel_dp *intel_dp = intel_attached_dp(connector); + struct intel_panel *panel = &connector->panel; + + if ((intel_dp->edp_dpcd[3] & DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE)) { + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] AUX Luminance Based Backlight Control Supported!\n", + connector->base.base.id, connector->base.name); + panel->backlight.edp.vesa.luminance_control_support = true; + return true; + } if (drm_edp_backlight_supported(intel_dp->edp_dpcd)) { drm_dbg_kms(display->drm, From 3f8a009a794eac8f5b7fac0242d321cc4581303d Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 6 Feb 2025 12:02:50 +0530 Subject: [PATCH 167/284] drm/i915/backlight: Modify function to get VESA brightness in Nits Modify vesa_get_brightness function to take into account luminance_control_support and based on that read the appropriate register and return the value. --v2 -Changes since we now use luminance instead of nits Signed-off-by: Suraj Kandpal Tested-by: Ben Kao Reviewed-by: Arun R Murthy Link: https://patchwork.freedesktop.org/patch/msgid/20250206063253.2827017-6-suraj.kandpal@intel.com --- .../drm/i915/display/intel_dp_aux_backlight.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index 2599aa39b21df..ca5fc40fa13af 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -451,6 +451,26 @@ intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pi /* VESA backlight callbacks */ static u32 intel_dp_aux_vesa_get_backlight(struct intel_connector *connector, enum pipe unused) { + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + struct intel_panel *panel = &connector->panel; + u8 buf[3]; + u32 val = 0; + int ret; + + if (panel->backlight.edp.vesa.luminance_control_support) { + ret = drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, buf, + sizeof(buf)); + if (ret < 0) { + drm_err(intel_dp->aux.drm_dev, + "[CONNECTOR:%d:%s] Failed to read Luminance from DPCD\n", + connector->base.base.id, connector->base.name); + return 0; + } + + val |= buf[0] | buf[1] << 8 | buf[2] << 16; + return val / 1000; + } + return connector->panel.backlight.level; } From b68074efcfcf7d8226ddb0b1326298671a04a3f7 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 6 Feb 2025 12:02:51 +0530 Subject: [PATCH 168/284] drm/i915/backlight: Add function to change brightness in nits for VESA Create a function that fills in the value for PANEL_TARGET_LUMINANCE_VALUE which helps in changing the luminance in nits using VESA interface. --v2 -Prefer using luminance over nits [Jani] Signed-off-by: Suraj Kandpal Tested-by: Ben Kao Reviewed-by: Arun R Murthy Link: https://patchwork.freedesktop.org/patch/msgid/20250206063253.2827017-7-suraj.kandpal@intel.com --- .../drm/i915/display/intel_dp_aux_backlight.c | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index ca5fc40fa13af..b0640b5128b1c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -474,6 +474,31 @@ static u32 intel_dp_aux_vesa_get_backlight(struct intel_connector *connector, en return connector->panel.backlight.level; } +static int +intel_dp_aux_vesa_set_luminance(struct intel_connector *connector, u32 level) +{ + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + u8 buf[3]; + int ret; + + level = level * 1000; + level &= 0xffffff; + buf[0] = (level & 0x0000ff); + buf[1] = (level & 0x00ff00) >> 8; + buf[2] = (level & 0xff0000) >> 16; + + ret = drm_dp_dpcd_write(&intel_dp->aux, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, + buf, sizeof(buf)); + if (ret != sizeof(buf)) { + drm_err(intel_dp->aux.drm_dev, + "%s: Failed to set VESA Aux Luminance: %d\n", + intel_dp->aux.name, ret); + return -EINVAL; + } else { + return 0; + } +} + static void intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u32 level) { @@ -481,6 +506,11 @@ intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u3 struct intel_panel *panel = &connector->panel; struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + if (panel->backlight.edp.vesa.luminance_control_support) { + if (!intel_dp_aux_vesa_set_luminance(connector, level)) + return; + } + if (!panel->backlight.edp.vesa.info.aux_set) { const u32 pwm_level = intel_backlight_level_to_pwm(connector, level); From 8d502933ac20afe97ec36fa8f0fd39bfee631b60 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 6 Feb 2025 12:02:52 +0530 Subject: [PATCH 169/284] drm/i915/backlight: Setup nits based luminance via VESA Modify backlight setup function for VESA interface to take into account the nits based luminance. --v2 -Prefer using luminance over nits [Jani] Signed-off-by: Suraj Kandpal Tested-by: Ben Kao Reviewed-by: Arun R Murthy Link: https://patchwork.freedesktop.org/patch/msgid/20250206063253.2827017-8-suraj.kandpal@intel.com --- .../drm/i915/display/intel_dp_aux_backlight.c | 99 +++++++++++-------- 1 file changed, 59 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index b0640b5128b1c..301a4dfdfbe5f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -560,56 +560,75 @@ static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe) { struct intel_display *display = to_intel_display(connector); + struct drm_luminance_range_info *luminance_range = + &connector->base.display_info.luminance_range; struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_panel *panel = &connector->panel; u16 current_level; u8 current_mode; int ret; - ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info, - panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd, - ¤t_level, ¤t_mode); - if (ret < 0) - return ret; - - drm_dbg_kms(display->drm, - "[CONNECTOR:%d:%s] AUX VESA backlight enable is controlled through %s\n", - connector->base.base.id, connector->base.name, - dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_enable)); - drm_dbg_kms(display->drm, - "[CONNECTOR:%d:%s] AUX VESA backlight level is controlled through %s\n", - connector->base.base.id, connector->base.name, - dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_set)); - - if (!panel->backlight.edp.vesa.info.aux_set || !panel->backlight.edp.vesa.info.aux_enable) { - ret = panel->backlight.pwm_funcs->setup(connector, pipe); - if (ret < 0) { - drm_err(display->drm, - "[CONNECTOR:%d:%s] Failed to setup PWM backlight controls for eDP backlight: %d\n", - connector->base.base.id, connector->base.name, ret); - return ret; - } - } - - if (panel->backlight.edp.vesa.info.aux_set) { - panel->backlight.max = panel->backlight.edp.vesa.info.max; - panel->backlight.min = 0; - if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { - panel->backlight.level = current_level; - panel->backlight.enabled = panel->backlight.level != 0; + if (panel->backlight.edp.vesa.luminance_control_support) { + if (luminance_range->max_luminance) { + panel->backlight.max = luminance_range->max_luminance; + panel->backlight.min = luminance_range->min_luminance; } else { - panel->backlight.level = panel->backlight.max; - panel->backlight.enabled = false; + panel->backlight.max = 512; + panel->backlight.min = 0; } + panel->backlight.level = intel_dp_aux_vesa_get_backlight(connector, 0); + panel->backlight.enabled = panel->backlight.level != 0; + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] AUX VESA Nits backlight level is controlled through DPCD\n", + connector->base.base.id, connector->base.name); } else { - panel->backlight.max = panel->backlight.pwm_level_max; - panel->backlight.min = panel->backlight.pwm_level_min; - if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_PWM) { - panel->backlight.level = panel->backlight.pwm_funcs->get(connector, pipe); - panel->backlight.enabled = panel->backlight.pwm_enabled; + ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info, + panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd, + ¤t_level, ¤t_mode); + if (ret < 0) + return ret; + + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] AUX VESA backlight enable is controlled through %s\n", + connector->base.base.id, connector->base.name, + dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_enable)); + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] AUX VESA backlight level is controlled through %s\n", + connector->base.base.id, connector->base.name, + dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_set)); + + if (!panel->backlight.edp.vesa.info.aux_set || + !panel->backlight.edp.vesa.info.aux_enable) { + ret = panel->backlight.pwm_funcs->setup(connector, pipe); + if (ret < 0) { + drm_err(display->drm, + "[CONNECTOR:%d:%s] Failed to setup PWM backlight controls for eDP backlight: %d\n", + connector->base.base.id, connector->base.name, ret); + return ret; + } + } + + if (panel->backlight.edp.vesa.info.aux_set) { + panel->backlight.max = panel->backlight.edp.vesa.info.max; + panel->backlight.min = 0; + if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { + panel->backlight.level = current_level; + panel->backlight.enabled = panel->backlight.level != 0; + } else { + panel->backlight.level = panel->backlight.max; + panel->backlight.enabled = false; + } } else { - panel->backlight.level = panel->backlight.max; - panel->backlight.enabled = false; + panel->backlight.max = panel->backlight.pwm_level_max; + panel->backlight.min = panel->backlight.pwm_level_min; + if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_PWM) { + panel->backlight.level = + panel->backlight.pwm_funcs->get(connector, pipe); + panel->backlight.enabled = panel->backlight.pwm_enabled; + } else { + panel->backlight.level = panel->backlight.max; + panel->backlight.enabled = false; + } } } From a5efc8dcfe710fd63a0557d3512e8ff753c2e283 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 6 Feb 2025 12:02:53 +0530 Subject: [PATCH 170/284] drm/i915/backlight: Enable nits based luminance Enable nits based luminance by writing the PANEL_LUMINANCE_CONTROL bit and set the correct register to change brightness. Signed-off-by: Suraj Kandpal Tested-by: Ben Kao Reviewed-by: Arun R Murthy Link: https://patchwork.freedesktop.org/patch/msgid/20250206063253.2827017-9-suraj.kandpal@intel.com --- .../gpu/drm/i915/display/intel_dp_aux_backlight.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index 301a4dfdfbe5f..f53c8355d5bea 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -527,6 +527,18 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state, struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_panel *panel = &connector->panel; struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + int ret; + + if (panel->backlight.edp.vesa.luminance_control_support) { + ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, + DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE); + + if (ret == 1) + return; + + if (!intel_dp_aux_vesa_set_luminance(connector, level)) + return; + } if (!panel->backlight.edp.vesa.info.aux_enable) { u32 pwm_level; @@ -550,6 +562,9 @@ static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state struct intel_panel *panel = &connector->panel; struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + if (panel->backlight.edp.vesa.luminance_control_support) + return; + drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info); if (!panel->backlight.edp.vesa.info.aux_enable) From faa5259b1ea0f6237c1b8ff24aa3ce4b6faa2890 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Thu, 6 Feb 2025 10:20:00 +0530 Subject: [PATCH 171/284] drm/i915/display: Skip state checker for AS SDP infoframe enable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid full modeset by skipping infoframe.enable check when toggling AS SDP while enabling VRR, preventing full modeset while pipe config changes. --v2: - Add check for exclude_infoframe. (Ankit) - Update commit message. (Ankit) --v3: - Optimise PIPE_CONF_CHECK for infoframes.enable. [Ankit] Signed-off-by: Mitul Golani Reviewed-by: Jouni Högander Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250206045001.2919360-2-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 60867b5b03ec4..b68ccf12c439c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5388,6 +5388,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, struct drm_i915_private *dev_priv = to_i915(current_config->uapi.crtc->dev); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct drm_printer p; + u32 exclude_infoframes = 0; bool ret = true; if (fastset) @@ -5743,11 +5744,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(min_voltage_level); if (current_config->has_psr || pipe_config->has_psr) - PIPE_CONF_CHECK_X_WITH_MASK(infoframes.enable, - ~intel_hdmi_infoframe_enable(DP_SDP_VSC)); - else - PIPE_CONF_CHECK_X(infoframes.enable); + exclude_infoframes |= intel_hdmi_infoframe_enable(DP_SDP_VSC); + + if (current_config->vrr.enable || pipe_config->vrr.enable) + exclude_infoframes |= intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC); + PIPE_CONF_CHECK_X_WITH_MASK(infoframes.enable, ~exclude_infoframes); PIPE_CONF_CHECK_X(infoframes.gcp); PIPE_CONF_CHECK_INFOFRAME(avi); PIPE_CONF_CHECK_INFOFRAME(spd); From 19214cd74716891be6fcc0fd90c634b3963d5ed2 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Thu, 6 Feb 2025 10:20:01 +0530 Subject: [PATCH 172/284] Revert "drm/i915/dp: Compute as_sdp based on if vrr possible" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 08277aa5d5a44befd71717de35b956f55e1e8401. Compute AS SDP params only when VRR is enabled to maintain PSR exclusivity. Signed-off-by: Mitul Golani Reviewed-by: Jouni Högander Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250206045001.2919360-3-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7127cda648287..7463478eef92d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2817,7 +2817,7 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - if (!intel_vrr_possible(crtc_state) || !intel_dp->as_sdp_supported) + if (!crtc_state->vrr.enable || !intel_dp->as_sdp_supported) return; crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC); From 9e35a4edb837627849063d61d46968bfc691c484 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 6 Feb 2025 18:46:24 +0200 Subject: [PATCH 173/284] drm/i915/dp_mst: Fix disabling the minimum HBlank time Disable the minimum HBlank time only on LNL+, where this functionality and corresponding register exists. Bspec: 74379 Fixes: a5ebe00c2ace ("drm/i915/dp: Guarantee a minimum HBlank time") Cc: Arun R Murthy Cc: Suraj Kandpal Reviewed-by: Suraj Kandpal Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250206164624.3185280-1-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 2324ca8f60962..411b7322d460b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1006,7 +1006,8 @@ static void mst_stream_disable(struct intel_atomic_state *state, intel_dp_sink_disable_decompression(state, connector, old_crtc_state); - intel_de_write(display, DP_MIN_HBLANK_CTL(trans), 0x00); + if (DISPLAY_VER(display) >= 20) + intel_de_write(display, DP_MIN_HBLANK_CTL(trans), 0); } static void mst_stream_post_disable(struct intel_atomic_state *state, From 2c569b955e02d06c97fa23b6fa367583e4fca1c8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 7 Feb 2025 12:41:10 +0200 Subject: [PATCH 174/284] drm/i915/hdcp: Move HDCP debugfs to intel_hdcp.c Continue with placing debugfs next to the implementation. intel_connector_info() still needs intel_hdcp_info(), so we'll need to expose that too. Cc: Suraj Kandpal Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/c118e992673f6b054aacaff0e1850fcea329e000.1738924826.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_debugfs.c | 74 +---------------- drivers/gpu/drm/i915/display/intel_hdcp.c | 82 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_hdcp.h | 4 + 3 files changed, 88 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 926f09c350840..e547ea66657de 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -213,38 +213,6 @@ static void intel_panel_info(struct seq_file *m, intel_seq_print_mode(m, 2, fixed_mode); } -static void intel_hdcp_info(struct seq_file *m, - struct intel_connector *intel_connector, - bool remote_req) -{ - bool hdcp_cap = false, hdcp2_cap = false; - - if (!intel_connector->hdcp.shim) { - seq_puts(m, "No Connector Support"); - goto out; - } - - if (remote_req) { - intel_hdcp_get_remote_capability(intel_connector, - &hdcp_cap, - &hdcp2_cap); - } else { - hdcp_cap = intel_hdcp_get_capability(intel_connector); - hdcp2_cap = intel_hdcp2_get_capability(intel_connector); - } - - if (hdcp_cap) - seq_puts(m, "HDCP1.4 "); - if (hdcp2_cap) - seq_puts(m, "HDCP2.2 "); - - if (!hdcp_cap && !hdcp2_cap) - seq_puts(m, "None"); - -out: - seq_puts(m, "\n"); -} - static void intel_dp_info(struct seq_file *m, struct intel_connector *connector) { struct intel_encoder *intel_encoder = intel_attached_encoder(connector); @@ -309,12 +277,7 @@ static void intel_connector_info(struct seq_file *m, break; } - seq_puts(m, "\tHDCP version: "); - if (intel_connector->mst_port) { - intel_hdcp_info(m, intel_connector, true); - seq_puts(m, "\tMST Hub HDCP version: "); - } - intel_hdcp_info(m, intel_connector, false); + intel_hdcp_info(m, intel_connector); seq_printf(m, "\tmax bpc: %u\n", connector->display_info.bpc); @@ -893,33 +856,6 @@ void intel_display_debugfs_register(struct drm_i915_private *i915) intel_display_debugfs_params(display); } -static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data) -{ - struct intel_connector *connector = m->private; - struct drm_i915_private *i915 = to_i915(connector->base.dev); - int ret; - - ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex); - if (ret) - return ret; - - if (!connector->base.encoder || - connector->base.status != connector_status_connected) { - ret = -ENODEV; - goto out; - } - - seq_printf(m, "%s:%d HDCP version: ", connector->base.name, - connector->base.base.id); - intel_hdcp_info(m, connector, false); - -out: - drm_modeset_unlock(&i915->drm.mode_config.connection_mutex); - - return ret; -} -DEFINE_SHOW_ATTRIBUTE(i915_hdcp_sink_capability); - static int i915_lpsp_capability_show(struct seq_file *m, void *data) { struct intel_connector *connector = m->private; @@ -1401,18 +1337,12 @@ void intel_connector_debugfs_add(struct intel_connector *connector) return; intel_drrs_connector_debugfs_add(connector); + intel_hdcp_connector_debugfs_add(connector); intel_pps_connector_debugfs_add(connector); intel_psr_connector_debugfs_add(connector); intel_alpm_lobf_debugfs_add(connector); intel_dp_link_training_debugfs_add(connector); - if (connector_type == DRM_MODE_CONNECTOR_DisplayPort || - connector_type == DRM_MODE_CONNECTOR_HDMIA || - connector_type == DRM_MODE_CONNECTOR_HDMIB) { - debugfs_create_file("i915_hdcp_sink_capability", 0444, root, - connector, &i915_hdcp_sink_capability_fops); - } - if (DISPLAY_VER(i915) >= 11 && ((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst_port) || connector_type == DRM_MODE_CONNECTOR_eDP)) { diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 7cc0399b2a5d9..718d8bad77a03 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -9,6 +9,7 @@ */ #include +#include #include #include @@ -2731,3 +2732,84 @@ void intel_hdcp_handle_cp_irq(struct intel_connector *connector) queue_delayed_work(i915->unordered_wq, &hdcp->check_work, 0); } + +static void __intel_hdcp_info(struct seq_file *m, struct intel_connector *intel_connector, + bool remote_req) +{ + bool hdcp_cap = false, hdcp2_cap = false; + + if (!intel_connector->hdcp.shim) { + seq_puts(m, "No Connector Support"); + goto out; + } + + if (remote_req) { + intel_hdcp_get_remote_capability(intel_connector, + &hdcp_cap, + &hdcp2_cap); + } else { + hdcp_cap = intel_hdcp_get_capability(intel_connector); + hdcp2_cap = intel_hdcp2_get_capability(intel_connector); + } + + if (hdcp_cap) + seq_puts(m, "HDCP1.4 "); + if (hdcp2_cap) + seq_puts(m, "HDCP2.2 "); + + if (!hdcp_cap && !hdcp2_cap) + seq_puts(m, "None"); + +out: + seq_puts(m, "\n"); +} + +void intel_hdcp_info(struct seq_file *m, struct intel_connector *connector) +{ + seq_puts(m, "\tHDCP version: "); + if (connector->mst_port) { + __intel_hdcp_info(m, connector, true); + seq_puts(m, "\tMST Hub HDCP version: "); + } + __intel_hdcp_info(m, connector, false); +} + +static int intel_hdcp_sink_capability_show(struct seq_file *m, void *data) +{ + struct intel_connector *connector = m->private; + struct drm_i915_private *i915 = to_i915(connector->base.dev); + int ret; + + ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex); + if (ret) + return ret; + + if (!connector->base.encoder || + connector->base.status != connector_status_connected) { + ret = -ENODEV; + goto out; + } + + seq_printf(m, "%s:%d HDCP version: ", connector->base.name, + connector->base.base.id); + __intel_hdcp_info(m, connector, false); + +out: + drm_modeset_unlock(&i915->drm.mode_config.connection_mutex); + + return ret; +} +DEFINE_SHOW_ATTRIBUTE(intel_hdcp_sink_capability); + +void intel_hdcp_connector_debugfs_add(struct intel_connector *connector) +{ + struct dentry *root = connector->base.debugfs_entry; + int connector_type = connector->base.connector_type; + + if (connector_type == DRM_MODE_CONNECTOR_DisplayPort || + connector_type == DRM_MODE_CONNECTOR_HDMIA || + connector_type == DRM_MODE_CONNECTOR_HDMIB) { + debugfs_create_file("i915_hdcp_sink_capability", 0444, root, + connector, &intel_hdcp_sink_capability_fops); + } +} diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h index d99830cfb7984..76bd3996f6364 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h @@ -19,6 +19,7 @@ struct intel_digital_port; struct intel_display; struct intel_encoder; struct intel_hdcp_shim; +struct seq_file; enum port; enum transcoder; @@ -48,4 +49,7 @@ void intel_hdcp_component_fini(struct intel_display *display); void intel_hdcp_cleanup(struct intel_connector *connector); void intel_hdcp_handle_cp_irq(struct intel_connector *connector); +void intel_hdcp_info(struct seq_file *m, struct intel_connector *connector); +void intel_hdcp_connector_debugfs_add(struct intel_connector *connector); + #endif /* __INTEL_HDCP_H__ */ From 3a178c1a23ee9841722a898a8245f1a9429b65e5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 7 Feb 2025 12:41:11 +0200 Subject: [PATCH 175/284] drm/i915/hdcp: rename intel_connector to connector Follow the current convention of naming struct intel_connector pointers connector. Cc: Suraj Kandpal Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/8f43542a8f0ce0ec5725b769c077d3cea723bde0.1738924826.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_hdcp.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 718d8bad77a03..9880192adfe9a 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2733,23 +2733,21 @@ void intel_hdcp_handle_cp_irq(struct intel_connector *connector) queue_delayed_work(i915->unordered_wq, &hdcp->check_work, 0); } -static void __intel_hdcp_info(struct seq_file *m, struct intel_connector *intel_connector, +static void __intel_hdcp_info(struct seq_file *m, struct intel_connector *connector, bool remote_req) { bool hdcp_cap = false, hdcp2_cap = false; - if (!intel_connector->hdcp.shim) { + if (!connector->hdcp.shim) { seq_puts(m, "No Connector Support"); goto out; } if (remote_req) { - intel_hdcp_get_remote_capability(intel_connector, - &hdcp_cap, - &hdcp2_cap); + intel_hdcp_get_remote_capability(connector, &hdcp_cap, &hdcp2_cap); } else { - hdcp_cap = intel_hdcp_get_capability(intel_connector); - hdcp2_cap = intel_hdcp2_get_capability(intel_connector); + hdcp_cap = intel_hdcp_get_capability(connector); + hdcp2_cap = intel_hdcp2_get_capability(connector); } if (hdcp_cap) From d4e51a45f1964b50fac8e1ae8cc12aaa8dd8c87d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 7 Feb 2025 12:41:12 +0200 Subject: [PATCH 176/284] drm/i915/hdcp: Convert platform checks to use display->platform Prefer display->platform. over IS_(i915), and reducate struct drm_i915_private usages while at it. Cc: Suraj Kandpal Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/58bad1e888a57a014acbaae67ccddd4f895091a7.1738924826.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_hdcp.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 9880192adfe9a..3d83db793baf3 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -343,7 +343,7 @@ static bool hdcp_key_loadable(struct intel_display *display) * On HSW and BDW, Display HW loads the Key as soon as Display resumes. * On all BXT+, SW can load the keys only when the PW#1 is turned on. */ - if (IS_HASWELL(i915) || IS_BROADWELL(i915)) + if (display->platform.haswell || display->platform.broadwell) id = HSW_DISP_PW_GLOBAL; else id = SKL_DISP_PW_1; @@ -382,7 +382,7 @@ static int intel_hdcp_load_keys(struct intel_display *display) * On HSW and BDW HW loads the HDCP1.4 Key when Display comes * out of reset. So if Key is not already loaded, its an error state. */ - if (IS_HASWELL(i915) || IS_BROADWELL(i915)) + if (display->platform.haswell || display->platform.broadwell) if (!(intel_de_read(display, HDCP_KEY_STATUS) & HDCP_KEY_LOAD_DONE)) return -ENXIO; @@ -394,7 +394,7 @@ static int intel_hdcp_load_keys(struct intel_display *display) * process from other platforms. These platforms use the GT Driver * Mailbox interface. */ - if (DISPLAY_VER(display) == 9 && !IS_BROXTON(i915)) { + if (DISPLAY_VER(display) == 9 && !display->platform.broxton) { ret = snb_pcode_write(&i915->uncore, SKL_PCODE_LOAD_HDCP_KEYS, 1); if (ret) { drm_err(display->drm, @@ -2339,18 +2339,16 @@ static int initialize_hdcp_port_data(struct intel_connector *connector, static bool is_hdcp2_supported(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (intel_hdcp_gsc_cs_required(display)) return true; if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP)) return false; - return (DISPLAY_VER(display) >= 10 || - IS_KABYLAKE(i915) || - IS_COFFEELAKE(i915) || - IS_COMETLAKE(i915)); + return DISPLAY_VER(display) >= 10 || + display->platform.kabylake || + display->platform.coffeelake || + display->platform.cometlake; } void intel_hdcp_component_init(struct intel_display *display) @@ -2775,10 +2773,10 @@ void intel_hdcp_info(struct seq_file *m, struct intel_connector *connector) static int intel_hdcp_sink_capability_show(struct seq_file *m, void *data) { struct intel_connector *connector = m->private; - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); int ret; - ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex); + ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); if (ret) return ret; @@ -2793,7 +2791,7 @@ static int intel_hdcp_sink_capability_show(struct seq_file *m, void *data) __intel_hdcp_info(m, connector, false); out: - drm_modeset_unlock(&i915->drm.mode_config.connection_mutex); + drm_modeset_unlock(&display->drm->mode_config.connection_mutex); return ret; } From 7d94a9a1c461674df3fc17ed31a05de6eae63263 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 7 Feb 2025 12:58:38 +0200 Subject: [PATCH 177/284] drm/i915/hdcp: Make some functions static With the debugfs implementation moved next to the implementation, we no longer need to expose some of the functions. Make them static. Cc: Suraj Kandpal Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20250207105838.179805-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_hdcp.c | 10 +++++----- drivers/gpu/drm/i915/display/intel_hdcp.h | 6 ------ 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 3d83db793baf3..1aa4c0fd216f8 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -209,7 +209,7 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port *dig_port, } /* Is HDCP1.4 capable on Platform and Sink */ -bool intel_hdcp_get_capability(struct intel_connector *connector) +static bool intel_hdcp_get_capability(struct intel_connector *connector) { struct intel_digital_port *dig_port; const struct intel_hdcp_shim *shim = connector->hdcp.shim; @@ -265,7 +265,7 @@ static bool intel_hdcp2_prerequisite(struct intel_connector *connector) } /* Is HDCP2.2 capable on Platform and Sink */ -bool intel_hdcp2_get_capability(struct intel_connector *connector) +static bool intel_hdcp2_get_capability(struct intel_connector *connector) { struct intel_hdcp *hdcp = &connector->hdcp; bool capable = false; @@ -279,9 +279,9 @@ bool intel_hdcp2_get_capability(struct intel_connector *connector) return capable; } -void intel_hdcp_get_remote_capability(struct intel_connector *connector, - bool *hdcp_capable, - bool *hdcp2_capable) +static void intel_hdcp_get_remote_capability(struct intel_connector *connector, + bool *hdcp_capable, + bool *hdcp2_capable) { struct intel_hdcp *hdcp = &connector->hdcp; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h index 76bd3996f6364..3a79055510518 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h @@ -21,7 +21,6 @@ struct intel_encoder; struct intel_hdcp_shim; struct seq_file; enum port; -enum transcoder; void intel_hdcp_atomic_check(struct drm_connector *connector, struct drm_connector_state *old_state, @@ -39,11 +38,6 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); bool is_hdcp_supported(struct intel_display *display, enum port port); -bool intel_hdcp_get_capability(struct intel_connector *connector); -bool intel_hdcp2_get_capability(struct intel_connector *connector); -void intel_hdcp_get_remote_capability(struct intel_connector *connector, - bool *hdcp_capable, - bool *hdcp2_capable); void intel_hdcp_component_init(struct intel_display *display); void intel_hdcp_component_fini(struct intel_display *display); void intel_hdcp_cleanup(struct intel_connector *connector); From 3eb1b39820d0602aa822463618651d4106618f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:22 +0200 Subject: [PATCH 178/284] drm/i915: Pass intel_display to intel_scanout_needs_vtd_wa() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that intel_scanout_needs_vtd_wa() is no longer used from the gem code we can convert it to take struct intel_display. which will help with converting the low level plane code over as well. Cc: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/i9xx_plane.c | 11 ++++++----- drivers/gpu/drm/i915/display/intel_cursor.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_display.c | 6 ++++-- drivers/gpu/drm/i915/display/intel_display.h | 2 +- drivers/gpu/drm/i915/display/intel_sprite.c | 10 +++++----- drivers/gpu/drm/i915/display/skl_universal_plane.c | 3 ++- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index bd3f8db137007..110ad49884be4 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -780,13 +780,13 @@ unsigned int vlv_plane_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); if (intel_plane_can_async_flip(plane, fb->modifier)) return 256 * 1024; /* FIXME undocumented so not sure what's actually needed */ - if (intel_scanout_needs_vtd_wa(i915)) + if (intel_scanout_needs_vtd_wa(display)) return 256 * 1024; switch (fb->modifier) { @@ -804,12 +804,12 @@ static unsigned int g4x_primary_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); if (intel_plane_can_async_flip(plane, fb->modifier)) return 256 * 1024; - if (intel_scanout_needs_vtd_wa(i915)) + if (intel_scanout_needs_vtd_wa(display)) return 256 * 1024; switch (fb->modifier) { @@ -865,6 +865,7 @@ static const struct drm_plane_funcs i8xx_plane_funcs = { struct intel_plane * intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) { + struct intel_display *display = &dev_priv->display; struct intel_plane *plane; const struct drm_plane_funcs *plane_funcs; unsigned int supported_rotations; @@ -959,7 +960,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) plane->min_alignment = i9xx_plane_min_alignment; /* FIXME undocumented for VLV/CHV so not sure what's actually needed */ - if (intel_scanout_needs_vtd_wa(dev_priv)) + if (intel_scanout_needs_vtd_wa(display)) plane->vtd_guard = 128; if (IS_I830(dev_priv) || IS_I845G(dev_priv)) { diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 6a1035a22b0a3..791557b99d945 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -372,9 +372,9 @@ static unsigned int i9xx_cursor_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); - if (intel_scanout_needs_vtd_wa(i915)) + if (intel_scanout_needs_vtd_wa(display)) return 64 * 1024; return 4 * 1024; /* physical for i915/i945 */ @@ -989,6 +989,7 @@ struct intel_plane * intel_cursor_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) { + struct intel_display *display = &dev_priv->display; struct intel_plane *cursor; int ret, zpos; u64 *modifiers; @@ -1019,7 +1020,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, else cursor->min_alignment = i9xx_cursor_min_alignment; - if (intel_scanout_needs_vtd_wa(dev_priv)) + if (intel_scanout_needs_vtd_wa(display)) cursor->vtd_guard = 2; cursor->update_arm = i9xx_cursor_update_arm; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b68ccf12c439c..993ffd2187405 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8784,7 +8784,9 @@ void intel_hpd_poll_fini(struct drm_i915_private *i915) drm_connector_list_iter_end(&conn_iter); } -bool intel_scanout_needs_vtd_wa(struct drm_i915_private *i915) +bool intel_scanout_needs_vtd_wa(struct intel_display *display) { - return IS_DISPLAY_VER(i915, 6, 11) && i915_vtd_active(i915); + struct drm_i915_private *i915 = to_i915(display->drm); + + return IS_DISPLAY_VER(display, 6, 11) && i915_vtd_active(i915); } diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 49a246feb1ae4..793c9d30c582c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -596,7 +596,7 @@ bool assert_port_valid(struct drm_i915_private *i915, enum port port); unlikely(__ret_warn_on); \ }) -bool intel_scanout_needs_vtd_wa(struct drm_i915_private *i915); +bool intel_scanout_needs_vtd_wa(struct intel_display *display); int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state); #endif diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index a6b27798fdc3f..d873c3ea5fa6b 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -980,9 +980,9 @@ static unsigned int g4x_sprite_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); - if (intel_scanout_needs_vtd_wa(i915)) + if (intel_scanout_needs_vtd_wa(display)) return 128 * 1024; return 4 * 1024; @@ -1610,7 +1610,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane->min_cdclk = vlv_plane_min_cdclk; /* FIXME undocumented for VLV/CHV so not sure what's actually needed */ - if (intel_scanout_needs_vtd_wa(dev_priv)) + if (intel_scanout_needs_vtd_wa(display)) plane->vtd_guard = 128; if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { @@ -1639,7 +1639,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane->min_alignment = g4x_sprite_min_alignment; - if (intel_scanout_needs_vtd_wa(dev_priv)) + if (intel_scanout_needs_vtd_wa(display)) plane->vtd_guard = 64; formats = snb_sprite_formats; @@ -1656,7 +1656,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane->min_alignment = g4x_sprite_min_alignment; plane->min_cdclk = g4x_sprite_min_cdclk; - if (intel_scanout_needs_vtd_wa(dev_priv)) + if (intel_scanout_needs_vtd_wa(display)) plane->vtd_guard = 64; if (IS_SANDYBRIDGE(dev_priv)) { diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index ee93361bba097..e166e1915afa1 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2697,6 +2697,7 @@ struct intel_plane * skl_universal_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe, enum plane_id plane_id) { + struct intel_display *display = &dev_priv->display; const struct drm_plane_funcs *plane_funcs; struct intel_plane *plane; enum drm_plane_type plane_type; @@ -2750,7 +2751,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, else plane->min_alignment = skl_plane_min_alignment; - if (intel_scanout_needs_vtd_wa(dev_priv)) + if (intel_scanout_needs_vtd_wa(display)) plane->vtd_guard = DISPLAY_VER(dev_priv) >= 10 ? 168 : 136; if (DISPLAY_VER(dev_priv) >= 11) { From 2bb9476795dea15efc3e53170839e548a1ba8bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:23 +0200 Subject: [PATCH 179/284] drm/i915: Decouple i915_gem_dumb_create() from the display a bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the device argument as drm_device to intel_plane_fb_max_stride() to decouple i915_gem_dumb_create() vs. the display code a bit. xe currently doesn't even call this, but it probably should... v2: s/dev/drm/ (Jani) Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 6 ++++-- drivers/gpu/drm/i915/display/intel_display.h | 2 +- drivers/gpu/drm/i915/display/intel_fb.c | 4 ++-- drivers/gpu/drm/i915/gem/i915_gem_create.c | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 993ffd2187405..397fc4581b4a3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -713,13 +713,15 @@ void intel_add_fb_offsets(int *x, int *y, *y += state->view.color_plane[color_plane].y; } -u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv, +u32 intel_plane_fb_max_stride(struct drm_device *drm, u32 pixel_format, u64 modifier) { + struct intel_display *display = to_intel_display(drm); + struct drm_i915_private *dev_priv = to_i915(drm); struct intel_crtc *crtc; struct intel_plane *plane; - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return 0; /* diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 793c9d30c582c..e594492bade71 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -421,7 +421,7 @@ void intel_link_compute_m_n(u16 bpp, int nlanes, int pixel_clock, int link_clock, int bw_overhead, struct intel_link_m_n *m_n); -u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv, +u32 intel_plane_fb_max_stride(struct drm_device *drm, u32 pixel_format, u64 modifier); enum drm_mode_status intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index d9328877cc6db..42c46376daae0 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1895,7 +1895,7 @@ u32 intel_fb_max_stride(struct drm_i915_private *dev_priv, */ if (DISPLAY_VER(dev_priv) < 4 || intel_fb_is_ccs_modifier(modifier) || intel_fb_modifier_uses_dpt(dev_priv, modifier)) - return intel_plane_fb_max_stride(dev_priv, pixel_format, modifier); + return intel_plane_fb_max_stride(&dev_priv->drm, pixel_format, modifier); else if (DISPLAY_VER(dev_priv) >= 7) return 256 * 1024; else @@ -1909,7 +1909,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) unsigned int tile_width; if (is_surface_linear(fb, color_plane)) { - unsigned int max_stride = intel_plane_fb_max_stride(dev_priv, + unsigned int max_stride = intel_plane_fb_max_stride(&dev_priv->drm, fb->format->format, fb->modifier); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c index 19156ba4b9ef4..c3e6a325872d5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c @@ -193,7 +193,7 @@ i915_gem_dumb_create(struct drm_file *file, args->pitch = ALIGN(args->width * cpp, 64); /* align stride to page size so that we can remap */ - if (args->pitch > intel_plane_fb_max_stride(to_i915(dev), format, + if (args->pitch > intel_plane_fb_max_stride(dev, format, DRM_FORMAT_MOD_LINEAR)) args->pitch = ALIGN(args->pitch, 4096); From 429dd9a60d690c8dd8452785c71cc151e5012825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:24 +0200 Subject: [PATCH 180/284] drm/i915: Decouple intel_fb_bo.h interfaces from driver specific types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the intel_fb_bo.h interfaces operated purely in base drm_ types so that each driver (i915 and xe) doesn't have to know about each other, or the display stuff. v2: s/dev/drm/ (Jani) Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_fb.c | 5 ++--- drivers/gpu/drm/i915/display/intel_fb_bo.c | 5 +++-- drivers/gpu/drm/i915/display/intel_fb_bo.h | 8 ++++---- drivers/gpu/drm/xe/display/intel_fb_bo.c | 7 ++++--- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 42c46376daae0..872c3fd62846c 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -2126,7 +2126,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, int ret = -EINVAL; int i; - ret = intel_fb_bo_framebuffer_init(intel_fb, obj, mode_cmd); + ret = intel_fb_bo_framebuffer_init(fb, obj, mode_cmd); if (ret) return ret; @@ -2242,9 +2242,8 @@ intel_user_framebuffer_create(struct drm_device *dev, struct drm_framebuffer *fb; struct drm_gem_object *obj; struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd; - struct drm_i915_private *i915 = to_i915(dev); - obj = intel_fb_bo_lookup_valid_bo(i915, filp, &mode_cmd); + obj = intel_fb_bo_lookup_valid_bo(dev, filp, &mode_cmd); if (IS_ERR(obj)) return ERR_CAST(obj); diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.c b/drivers/gpu/drm/i915/display/intel_fb_bo.c index 810ca6ff86401..ecc95beaf6df4 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.c +++ b/drivers/gpu/drm/i915/display/intel_fb_bo.c @@ -16,7 +16,7 @@ void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj) /* Nothing to do for i915 */ } -int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, +int intel_fb_bo_framebuffer_init(struct drm_framebuffer *fb, struct drm_gem_object *_obj, struct drm_mode_fb_cmd2 *mode_cmd) { @@ -76,10 +76,11 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, } struct drm_gem_object * -intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, +intel_fb_bo_lookup_valid_bo(struct drm_device *drm, struct drm_file *filp, const struct drm_mode_fb_cmd2 *mode_cmd) { + struct drm_i915_private *i915 = to_i915(drm); struct drm_i915_gem_object *obj; obj = i915_gem_object_lookup(filp, mode_cmd->handles[0]); diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.h b/drivers/gpu/drm/i915/display/intel_fb_bo.h index e71acd1bcb242..eefcb05a99f0a 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.h +++ b/drivers/gpu/drm/i915/display/intel_fb_bo.h @@ -6,20 +6,20 @@ #ifndef __INTEL_FB_BO_H__ #define __INTEL_FB_BO_H__ +struct drm_device; struct drm_file; +struct drm_framebuffer; struct drm_gem_object; -struct drm_i915_private; struct drm_mode_fb_cmd2; -struct intel_framebuffer; void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj); -int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, +int intel_fb_bo_framebuffer_init(struct drm_framebuffer *fb, struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); struct drm_gem_object * -intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, +intel_fb_bo_lookup_valid_bo(struct drm_device *drm, struct drm_file *filp, const struct drm_mode_fb_cmd2 *user_mode_cmd); diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.c b/drivers/gpu/drm/xe/display/intel_fb_bo.c index 4d209ebc26c2a..3f8e8d31e8005 100644 --- a/drivers/gpu/drm/xe/display/intel_fb_bo.c +++ b/drivers/gpu/drm/xe/display/intel_fb_bo.c @@ -24,7 +24,7 @@ void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj) xe_bo_put(bo); } -int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, +int intel_fb_bo_framebuffer_init(struct drm_framebuffer *fb, struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd) { @@ -68,10 +68,11 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, return ret; } -struct drm_gem_object *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, +struct drm_gem_object *intel_fb_bo_lookup_valid_bo(struct drm_device *drm, struct drm_file *filp, const struct drm_mode_fb_cmd2 *mode_cmd) { + struct xe_device *xe = to_xe_device(drm); struct xe_bo *bo; struct drm_gem_object *gem = drm_gem_object_lookup(filp, mode_cmd->handles[0]); @@ -80,7 +81,7 @@ struct drm_gem_object *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915 bo = gem_to_xe_bo(gem); /* Require vram placement or dma-buf import */ - if (IS_DGFX(i915) && + if (IS_DGFX(xe) && !xe_bo_can_migrate(bo, XE_PL_VRAM0) && bo->ttm.type != ttm_bo_type_sg) { drm_gem_object_put(gem); From b2479f7231d8b16c8cabf4ac1804204f6071728b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:25 +0200 Subject: [PATCH 181/284] drm/i915: Convert intel_crtc.c to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct intel_display will replace struct drm_i915_private as the main thing for display code. Convert intel_crtc.c code to use it. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-5-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/g4x_dp.c | 4 +- drivers/gpu/drm/i915/display/g4x_hdmi.c | 3 +- drivers/gpu/drm/i915/display/intel_audio.c | 3 +- drivers/gpu/drm/i915/display/intel_crtc.c | 57 ++++++++++--------- drivers/gpu/drm/i915/display/intel_crtc.h | 7 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +- .../drm/i915/display/intel_display_driver.c | 2 +- drivers/gpu/drm/i915/display/intel_sdvo.c | 3 +- 8 files changed, 42 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 56353377466c7..434de337814c2 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -224,7 +224,7 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp, * 2. Program DP PLL enable */ if (IS_IRONLAKE(dev_priv)) - intel_wait_for_vblank_if_active(dev_priv, !crtc->pipe); + intel_wait_for_vblank_if_active(display, !crtc->pipe); intel_dp->DP |= DP_PLL_ENABLE; @@ -471,7 +471,7 @@ intel_dp_link_down(struct intel_encoder *encoder, intel_de_write(display, intel_dp->output_reg, intel_dp->DP); intel_de_posting_read(display, intel_dp->output_reg); - intel_wait_for_vblank_if_active(dev_priv, PIPE_A); + intel_wait_for_vblank_if_active(display, PIPE_A); intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); } diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 98e6a931042fd..3aaa7f9e9210e 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -384,6 +384,7 @@ static void intel_disable_hdmi(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); @@ -426,7 +427,7 @@ static void intel_disable_hdmi(struct intel_atomic_state *state, intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); - intel_wait_for_vblank_if_active(dev_priv, PIPE_A); + intel_wait_for_vblank_if_active(display, PIPE_A); intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); } diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 113d763e6ef3b..f145f83346ca3 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -954,13 +954,12 @@ static int glk_force_audio_cdclk_commit(struct intel_atomic_state *state, static void glk_force_audio_cdclk(struct intel_display *display, bool enable) { - struct drm_i915_private *i915 = to_i915(display->drm); struct drm_modeset_acquire_ctx ctx; struct drm_atomic_state *state; struct intel_crtc *crtc; int ret; - crtc = intel_first_crtc(i915); + crtc = intel_first_crtc(display); if (!crtc) return; diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index e69b28779ac55..da2d6aeb20721 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -45,9 +45,9 @@ static void assert_vblank_disabled(struct drm_crtc *crtc) drm_crtc_vblank_put(crtc); } -struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915) +struct intel_crtc *intel_first_crtc(struct intel_display *display) { - return to_intel_crtc(drm_crtc_from_index(&i915->drm, 0)); + return to_intel_crtc(drm_crtc_from_index(display->drm, 0)); } struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display, @@ -68,10 +68,9 @@ void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc) drm_crtc_wait_one_vblank(&crtc->base); } -void intel_wait_for_vblank_if_active(struct drm_i915_private *i915, +void intel_wait_for_vblank_if_active(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &i915->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); if (crtc->active) @@ -93,7 +92,7 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc) u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); /* * From Gen 11, in case of dsi cmd mode, frame counter wouldn't @@ -109,13 +108,13 @@ u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state) * On i965gm the hardware frame counter reads * zero when the TV encoder is enabled :( */ - if (IS_I965GM(dev_priv) && + if (display->platform.i965gm && (crtc_state->output_types & BIT(INTEL_OUTPUT_TVOUT))) return 0; - if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) + if (DISPLAY_VER(display) >= 5 || display->platform.g4x) return 0xffffffff; /* full 32 bit counter */ - else if (DISPLAY_VER(dev_priv) >= 3) + else if (DISPLAY_VER(display) >= 3) return 0xffffff; /* only 24 bits of frame count */ else return 0; /* Gen2 doesn't have a hardware frame counter */ @@ -142,8 +141,8 @@ void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state) void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct intel_display *display = to_intel_display(crtc); /* * Should really happen exactly when we disable the pipe @@ -304,8 +303,9 @@ static const struct drm_crtc_funcs i8xx_crtc_funcs = { .get_vblank_timestamp = intel_crtc_get_vblank_timestamp, }; -int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) +int intel_crtc_init(struct intel_display *display, enum pipe pipe) { + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_plane *primary, *cursor; const struct drm_crtc_funcs *funcs; struct intel_crtc *crtc; @@ -316,9 +316,9 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) return PTR_ERR(crtc); crtc->pipe = pipe; - crtc->num_scalers = DISPLAY_RUNTIME_INFO(dev_priv)->num_scalers[pipe]; + crtc->num_scalers = DISPLAY_RUNTIME_INFO(display)->num_scalers[pipe]; - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) primary = skl_universal_plane_create(dev_priv, pipe, PLANE_1); else primary = intel_primary_plane_create(dev_priv, pipe); @@ -330,7 +330,7 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) intel_init_fifo_underrun_reporting(dev_priv, crtc, false); - for_each_sprite(dev_priv, pipe, sprite) { + for_each_sprite(display, pipe, sprite) { struct intel_plane *plane; if (DISPLAY_VER(dev_priv) >= 9) @@ -351,32 +351,34 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) } crtc->plane_ids_mask |= BIT(cursor->id); - if (HAS_GMCH(dev_priv)) { - if (IS_CHERRYVIEW(dev_priv) || - IS_VALLEYVIEW(dev_priv) || IS_G4X(dev_priv)) + if (HAS_GMCH(display)) { + if (display->platform.cherryview || + display->platform.valleyview || + display->platform.g4x) funcs = &g4x_crtc_funcs; - else if (DISPLAY_VER(dev_priv) == 4) + else if (DISPLAY_VER(display) == 4) funcs = &i965_crtc_funcs; - else if (IS_I945GM(dev_priv) || IS_I915GM(dev_priv)) + else if (display->platform.i945gm || + display->platform.i915gm) funcs = &i915gm_crtc_funcs; - else if (DISPLAY_VER(dev_priv) == 3) + else if (DISPLAY_VER(display) == 3) funcs = &i915_crtc_funcs; else funcs = &i8xx_crtc_funcs; } else { - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) funcs = &bdw_crtc_funcs; else funcs = &ilk_crtc_funcs; } - ret = drm_crtc_init_with_planes(&dev_priv->drm, &crtc->base, + ret = drm_crtc_init_with_planes(display->drm, &crtc->base, &primary->base, &cursor->base, funcs, "pipe %c", pipe_name(pipe)); if (ret) goto fail; - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) drm_crtc_create_scaling_filter_property(&crtc->base, BIT(DRM_SCALING_FILTER_DEFAULT) | BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR)); @@ -387,7 +389,7 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) cpu_latency_qos_add_request(&crtc->vblank_pm_qos, PM_QOS_DEFAULT_VALUE); - drm_WARN_ON(&dev_priv->drm, drm_crtc_index(&crtc->base) != crtc->pipe); + drm_WARN_ON(display->drm, drm_crtc_index(&crtc->base) != crtc->pipe); return 0; @@ -512,7 +514,7 @@ int intel_scanlines_to_usecs(const struct drm_display_mode *adjusted_mode, void intel_pipe_update_start(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc_state *new_crtc_state = @@ -546,7 +548,7 @@ void intel_pipe_update_start(struct intel_atomic_state *state, intel_vblank_evade_init(old_crtc_state, new_crtc_state, &evade); - if (drm_WARN_ON(&dev_priv->drm, drm_crtc_vblank_get(&crtc->base))) + if (drm_WARN_ON(display->drm, drm_crtc_vblank_get(&crtc->base))) goto irq_disable; /* @@ -649,6 +651,7 @@ void intel_crtc_prepare_vblank_event(struct intel_crtc_state *crtc_state, void intel_pipe_update_end(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; @@ -666,7 +669,7 @@ void intel_pipe_update_end(struct intel_atomic_state *state, * Incase of mipi dsi command mode, we need to set frame update * request for every commit. */ - if (DISPLAY_VER(dev_priv) >= 11 && + if (DISPLAY_VER(display) >= 11 && intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI)) icl_dsi_frame_update(new_crtc_state); @@ -723,7 +726,7 @@ void intel_pipe_update_end(struct intel_atomic_state *state, if (crtc->debug.start_vbl_count && crtc->debug.start_vbl_count != end_vbl_count) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n", pipe_name(pipe), crtc->debug.start_vbl_count, end_vbl_count, diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h index de54ae1deedf9..8c14ff8b391ea 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.h +++ b/drivers/gpu/drm/i915/display/intel_crtc.h @@ -13,7 +13,6 @@ enum pipe; struct drm_device; struct drm_display_mode; struct drm_file; -struct drm_i915_private; struct drm_pending_vblank_event; struct intel_atomic_state; struct intel_crtc; @@ -38,7 +37,7 @@ void intel_crtc_arm_vblank_event(struct intel_crtc_state *crtc_state); void intel_crtc_prepare_vblank_event(struct intel_crtc_state *crtc_state, struct drm_pending_vblank_event **event); u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state); -int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe); +int intel_crtc_init(struct intel_display *display, enum pipe pipe); int intel_crtc_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc); @@ -52,10 +51,10 @@ void intel_pipe_update_start(struct intel_atomic_state *state, void intel_pipe_update_end(struct intel_atomic_state *state, struct intel_crtc *crtc); void intel_wait_for_vblank_workers(struct intel_atomic_state *state); -struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915); +struct intel_crtc *intel_first_crtc(struct intel_display *display); struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display, enum pipe pipe); -void intel_wait_for_vblank_if_active(struct drm_i915_private *i915, +void intel_wait_for_vblank_if_active(struct intel_display *display, enum pipe pipe); void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 397fc4581b4a3..9ab1680cb2d39 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -717,7 +717,6 @@ u32 intel_plane_fb_max_stride(struct drm_device *drm, u32 pixel_format, u64 modifier) { struct intel_display *display = to_intel_display(drm); - struct drm_i915_private *dev_priv = to_i915(drm); struct intel_crtc *crtc; struct intel_plane *plane; @@ -729,7 +728,7 @@ u32 intel_plane_fb_max_stride(struct drm_device *drm, * the highest stride limits of them all, * if in case pipe A is disabled, use the first pipe from pipe_mask. */ - crtc = intel_first_crtc(dev_priv); + crtc = intel_first_crtc(display); if (!crtc) return 0; diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index c4120a8346980..d448672fdfa4f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -442,7 +442,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) INTEL_NUM_PIPES(display) > 1 ? "s" : ""); for_each_pipe(display, pipe) { - ret = intel_crtc_init(i915, pipe); + ret = intel_crtc_init(display, pipe); if (ret) goto err_mode_config; } diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index c78da5a2b5594..44452ed69fff4 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -1838,6 +1838,7 @@ static void intel_disable_sdvo(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); @@ -1873,7 +1874,7 @@ static void intel_disable_sdvo(struct intel_atomic_state *state, temp &= ~SDVO_ENABLE; intel_sdvo_write_sdvox(intel_sdvo, temp); - intel_wait_for_vblank_if_active(dev_priv, PIPE_A); + intel_wait_for_vblank_if_active(display, PIPE_A); intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); } From e3da9834e4728fb4ed4d87f5892e78d47498f2e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:26 +0200 Subject: [PATCH 182/284] drm/i915: Convert intel_fb.c to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct intel_display will replace struct drm_i915_private as the main thing for display code. Convert the fb code to use it. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-6-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/i9xx_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb.c | 250 +++++++++--------- drivers/gpu/drm/i915/display/intel_fb.h | 11 +- drivers/gpu/drm/i915/display/intel_fb_bo.c | 13 +- drivers/gpu/drm/i915/display/intel_sprite.c | 2 +- .../drm/i915/display/skl_universal_plane.c | 4 +- 7 files changed, 146 insertions(+), 138 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 110ad49884be4..5c4652f662cba 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -998,7 +998,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) } } - modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X); + modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X); if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 791557b99d945..9c9cded729aff 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -1035,7 +1035,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, if (IS_I845G(dev_priv) || IS_I865G(dev_priv) || HAS_CUR_FBC(dev_priv)) cursor->cursor.size = ~0; - modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_NONE); + modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_NONE); ret = drm_universal_plane_init(&dev_priv->drm, &cursor->base, 0, &intel_cursor_plane_funcs, diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 872c3fd62846c..5af93235057c6 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -20,7 +20,7 @@ #include "intel_fb_bo.h" #include "intel_frontbuffer.h" -#define check_array_bounds(i915, a, i) drm_WARN_ON(&(i915)->drm, (i) >= ARRAY_SIZE(a)) +#define check_array_bounds(display, a, i) drm_WARN_ON((display)->drm, (i) >= ARRAY_SIZE(a)) /* * From the Sky Lake PRM: @@ -539,11 +539,13 @@ static bool check_modifier_display_ver_range(const struct intel_modifier_desc *m display_ver_from <= md->display_ver.until; } -static bool plane_has_modifier(struct drm_i915_private *i915, +static bool plane_has_modifier(struct intel_display *display, u8 plane_caps, const struct intel_modifier_desc *md) { - if (!IS_DISPLAY_VER(i915, md->display_ver.from, md->display_ver.until)) + struct drm_i915_private *i915 = to_i915(display->drm); + + if (!IS_DISPLAY_VER(display, md->display_ver.from, md->display_ver.until)) return false; if (!plane_caps_contain_all(plane_caps, md->plane_caps)) @@ -570,14 +572,14 @@ static bool plane_has_modifier(struct drm_i915_private *i915, /** * intel_fb_plane_get_modifiers: Get the modifiers for the given platform and plane capabilities - * @i915: i915 device instance + * @display: display instance * @plane_caps: capabilities for the plane the modifiers are queried for * * Returns: - * Returns the list of modifiers allowed by the @i915 platform and @plane_caps. + * Returns the list of modifiers allowed by the @display platform and @plane_caps. * The caller must free the returned buffer. */ -u64 *intel_fb_plane_get_modifiers(struct drm_i915_private *i915, +u64 *intel_fb_plane_get_modifiers(struct intel_display *display, u8 plane_caps) { u64 *list, *p; @@ -585,17 +587,17 @@ u64 *intel_fb_plane_get_modifiers(struct drm_i915_private *i915, int i; for (i = 0; i < ARRAY_SIZE(intel_modifiers); i++) { - if (plane_has_modifier(i915, plane_caps, &intel_modifiers[i])) + if (plane_has_modifier(display, plane_caps, &intel_modifiers[i])) count++; } list = kmalloc_array(count, sizeof(*list), GFP_KERNEL); - if (drm_WARN_ON(&i915->drm, !list)) + if (drm_WARN_ON(display->drm, !list)) return NULL; p = list; for (i = 0; i < ARRAY_SIZE(intel_modifiers); i++) { - if (plane_has_modifier(i915, plane_caps, &intel_modifiers[i])) + if (plane_has_modifier(display, plane_caps, &intel_modifiers[i])) *p++ = intel_modifiers[i].modifier; } *p++ = DRM_FORMAT_MOD_INVALID; @@ -751,33 +753,34 @@ static unsigned int gen12_ccs_aux_stride(struct intel_framebuffer *fb, int ccs_p int skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane) { const struct intel_modifier_desc *md = lookup_modifier(fb->modifier); - struct drm_i915_private *i915 = to_i915(fb->dev); + struct intel_display *display = to_intel_display(fb->dev); if (md->ccs.packed_aux_planes | md->ccs.planar_aux_planes) return main_to_ccs_plane(fb, main_plane); - else if (DISPLAY_VER(i915) < 11 && + else if (DISPLAY_VER(display) < 11 && format_is_yuv_semiplanar(md, fb->format)) return 1; else return 0; } -unsigned int intel_tile_size(const struct drm_i915_private *i915) +unsigned int intel_tile_size(struct intel_display *display) { - return DISPLAY_VER(i915) == 2 ? 2048 : 4096; + return DISPLAY_VER(display) == 2 ? 2048 : 4096; } unsigned int intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane) { - struct drm_i915_private *dev_priv = to_i915(fb->dev); + struct intel_display *display = to_intel_display(fb->dev); + struct drm_i915_private *i915 = to_i915(display->drm); unsigned int cpp = fb->format->cpp[color_plane]; switch (fb->modifier) { case DRM_FORMAT_MOD_LINEAR: - return intel_tile_size(dev_priv); + return intel_tile_size(display); case I915_FORMAT_MOD_X_TILED: - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) return 128; else return 512; @@ -807,7 +810,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane) return 64; fallthrough; case I915_FORMAT_MOD_Y_TILED: - if (DISPLAY_VER(dev_priv) == 2 || HAS_128_BYTE_Y_TILING(dev_priv)) + if (DISPLAY_VER(display) == 2 || HAS_128_BYTE_Y_TILING(i915)) return 128; else return 512; @@ -838,7 +841,9 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane) unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane) { - return intel_tile_size(to_i915(fb->dev)) / + struct intel_display *display = to_intel_display(fb->dev); + + return intel_tile_size(display) / intel_tile_width_bytes(fb, color_plane); } @@ -890,15 +895,17 @@ intel_fb_align_height(const struct drm_framebuffer *fb, return ALIGN(height, tile_height); } -bool intel_fb_modifier_uses_dpt(struct drm_i915_private *i915, u64 modifier) +bool intel_fb_modifier_uses_dpt(struct intel_display *display, u64 modifier) { - return HAS_DPT(i915) && modifier != DRM_FORMAT_MOD_LINEAR; + return HAS_DPT(display) && modifier != DRM_FORMAT_MOD_LINEAR; } bool intel_fb_uses_dpt(const struct drm_framebuffer *fb) { - return to_i915(fb->dev)->display.params.enable_dpt && - intel_fb_modifier_uses_dpt(to_i915(fb->dev), fb->modifier); + struct intel_display *display = to_intel_display(fb->dev); + + return display->params.enable_dpt && + intel_fb_modifier_uses_dpt(display, fb->modifier); } void intel_fb_plane_get_subsampling(int *hsub, int *vsub, @@ -1007,16 +1014,16 @@ static u32 intel_adjust_aligned_offset(int *x, int *y, unsigned int pitch, u32 old_offset, u32 new_offset) { - struct drm_i915_private *i915 = to_i915(fb->dev); + struct intel_display *display = to_intel_display(fb->dev); unsigned int cpp = fb->format->cpp[color_plane]; - drm_WARN_ON(&i915->drm, new_offset > old_offset); + drm_WARN_ON(display->drm, new_offset > old_offset); if (!is_surface_linear(fb, color_plane)) { unsigned int tile_size, tile_width, tile_height; unsigned int pitch_tiles; - tile_size = intel_tile_size(i915); + tile_size = intel_tile_size(display); intel_tile_dims(fb, color_plane, &tile_width, &tile_height); if (drm_rotation_90_or_270(rotation)) { @@ -1066,7 +1073,7 @@ u32 intel_plane_adjust_aligned_offset(int *x, int *y, * used. This is why the user has to pass in the pitch since it * is specified in the rotated orientation. */ -static u32 intel_compute_aligned_offset(struct drm_i915_private *i915, +static u32 intel_compute_aligned_offset(struct intel_display *display, int *x, int *y, const struct drm_framebuffer *fb, int color_plane, @@ -1081,7 +1088,7 @@ static u32 intel_compute_aligned_offset(struct drm_i915_private *i915, unsigned int tile_size, tile_width, tile_height; unsigned int tile_rows, tiles, pitch_tiles; - tile_size = intel_tile_size(i915); + tile_size = intel_tile_size(display); intel_tile_dims(fb, color_plane, &tile_width, &tile_height); if (drm_rotation_90_or_270(rotation)) { @@ -1125,14 +1132,14 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y, const struct intel_plane_state *state, int color_plane) { + struct intel_display *display = to_intel_display(state); struct intel_plane *plane = to_intel_plane(state->uapi.plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); const struct drm_framebuffer *fb = state->hw.fb; unsigned int rotation = state->hw.rotation; unsigned int pitch = state->view.color_plane[color_plane].mapping_stride; unsigned int alignment = plane->min_alignment(plane, fb, color_plane); - return intel_compute_aligned_offset(i915, x, y, fb, color_plane, + return intel_compute_aligned_offset(display, x, y, fb, color_plane, pitch, rotation, alignment); } @@ -1141,16 +1148,16 @@ static int intel_fb_offset_to_xy(int *x, int *y, const struct drm_framebuffer *fb, int color_plane) { - struct drm_i915_private *i915 = to_i915(fb->dev); + struct intel_display *display = to_intel_display(fb->dev); unsigned int height, alignment, unused; if (fb->modifier != DRM_FORMAT_MOD_LINEAR) - alignment = intel_tile_size(i915); + alignment = intel_tile_size(display); else alignment = 0; if (alignment != 0 && fb->offsets[color_plane] % alignment) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Misaligned offset 0x%08x for color plane %d\n", fb->offsets[color_plane], color_plane); return -EINVAL; @@ -1162,7 +1169,7 @@ static int intel_fb_offset_to_xy(int *x, int *y, /* Catch potential overflows early */ if (check_add_overflow(mul_u32_u32(height, fb->pitches[color_plane]), fb->offsets[color_plane], &unused)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Bad offset 0x%08x or pitch %d for color plane %d\n", fb->offsets[color_plane], fb->pitches[color_plane], color_plane); @@ -1182,7 +1189,7 @@ static int intel_fb_offset_to_xy(int *x, int *y, static int intel_fb_check_ccs_xy(const struct drm_framebuffer *fb, int ccs_plane, int x, int y) { - struct drm_i915_private *i915 = to_i915(fb->dev); + struct intel_display *display = to_intel_display(fb->dev); const struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); int main_plane; int hsub, vsub; @@ -1216,13 +1223,12 @@ static int intel_fb_check_ccs_xy(const struct drm_framebuffer *fb, int ccs_plane * x/y offsets must match between CCS and the main surface. */ if (main_x != ccs_x || main_y != ccs_y) { - drm_dbg_kms(&i915->drm, - "Bad CCS x/y (main %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n", - main_x, main_y, - ccs_x, ccs_y, - intel_fb->normal_view.color_plane[main_plane].x, - intel_fb->normal_view.color_plane[main_plane].y, - x, y); + drm_dbg_kms(display->drm, + "Bad CCS x/y (main %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n", + main_x, main_y, ccs_x, ccs_y, + intel_fb->normal_view.color_plane[main_plane].x, + intel_fb->normal_view.color_plane[main_plane].y, + x, y); return -EINVAL; } @@ -1231,8 +1237,8 @@ static int intel_fb_check_ccs_xy(const struct drm_framebuffer *fb, int ccs_plane static bool intel_plane_can_remap(const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; int i; @@ -1246,7 +1252,7 @@ static bool intel_plane_can_remap(const struct intel_plane_state *plane_state) * Would also need to deal with the fence POT alignment * and gen2 2KiB GTT tile size. */ - if (DISPLAY_VER(i915) < 4) + if (DISPLAY_VER(display) < 4) return false; /* @@ -1258,7 +1264,7 @@ static bool intel_plane_can_remap(const struct intel_plane_state *plane_state) /* Linear needs a page aligned stride for remapping */ if (fb->modifier == DRM_FORMAT_MOD_LINEAR) { - unsigned int alignment = intel_tile_size(i915) - 1; + unsigned int alignment = intel_tile_size(display) - 1; for (i = 0; i < fb->format->num_planes; i++) { if (fb->pitches[i] & alignment) @@ -1271,9 +1277,9 @@ static bool intel_plane_can_remap(const struct intel_plane_state *plane_state) bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb) { - struct drm_i915_private *i915 = to_i915(fb->base.dev); + struct intel_display *display = to_intel_display(fb->base.dev); - return (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14) && + return (display->platform.alderlake_p || DISPLAY_VER(display) >= 14) && intel_fb_uses_dpt(&fb->base); } @@ -1318,12 +1324,13 @@ static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state) static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int color_plane, int plane_width, int *x, int *y) { + struct intel_display *display = to_intel_display(fb->base.dev); struct drm_gem_object *obj = intel_fb_bo(&fb->base); int ret; ret = intel_fb_offset_to_xy(x, y, &fb->base, color_plane); if (ret) { - drm_dbg_kms(fb->base.dev, + drm_dbg_kms(display->drm, "bad fb plane %d offset: 0x%x\n", color_plane, fb->base.offsets[color_plane]); return ret; @@ -1344,7 +1351,7 @@ static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int co */ if (color_plane == 0 && intel_bo_is_tiled(obj) && (*x + plane_width) * fb->base.format->cpp[color_plane] > fb->base.pitches[color_plane]) { - drm_dbg_kms(fb->base.dev, + drm_dbg_kms(display->drm, "bad fb plane %d offset: 0x%x\n", color_plane, fb->base.offsets[color_plane]); return -EINVAL; @@ -1355,11 +1362,11 @@ static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int co static u32 calc_plane_aligned_offset(const struct intel_framebuffer *fb, int color_plane, int *x, int *y) { - struct drm_i915_private *i915 = to_i915(fb->base.dev); - unsigned int tile_size = intel_tile_size(i915); + struct intel_display *display = to_intel_display(fb->base.dev); + unsigned int tile_size = intel_tile_size(display); u32 offset; - offset = intel_compute_aligned_offset(i915, x, y, &fb->base, color_plane, + offset = intel_compute_aligned_offset(display, x, y, &fb->base, color_plane, fb->base.pitches[color_plane], DRM_MODE_ROTATE_0, tile_size); @@ -1410,10 +1417,10 @@ plane_view_scanout_stride(const struct intel_framebuffer *fb, int color_plane, unsigned int tile_width, unsigned int src_stride_tiles, unsigned int dst_stride_tiles) { - struct drm_i915_private *i915 = to_i915(fb->base.dev); + struct intel_display *display = to_intel_display(fb->base.dev); unsigned int stride_tiles; - if ((IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14) && + if ((display->platform.alderlake_p || DISPLAY_VER(display) >= 14) && src_stride_tiles < dst_stride_tiles) stride_tiles = src_stride_tiles; else @@ -1443,23 +1450,23 @@ plane_view_linear_tiles(const struct intel_framebuffer *fb, int color_plane, const struct fb_plane_view_dims *dims, int x, int y) { - struct drm_i915_private *i915 = to_i915(fb->base.dev); + struct intel_display *display = to_intel_display(fb->base.dev); unsigned int size; size = (y + dims->height) * fb->base.pitches[color_plane] + x * fb->base.format->cpp[color_plane]; - return DIV_ROUND_UP(size, intel_tile_size(i915)); + return DIV_ROUND_UP(size, intel_tile_size(display)); } -#define assign_chk_ovf(i915, var, val) ({ \ - drm_WARN_ON(&(i915)->drm, overflows_type(val, var)); \ +#define assign_chk_ovf(display, var, val) ({ \ + drm_WARN_ON((display)->drm, overflows_type(val, var)); \ (var) = (val); \ }) -#define assign_bfld_chk_ovf(i915, var, val) ({ \ +#define assign_bfld_chk_ovf(display, var, val) ({ \ (var) = (val); \ - drm_WARN_ON(&(i915)->drm, (var) != (val)); \ + drm_WARN_ON((display)->drm, (var) != (val)); \ (var); \ }) @@ -1468,38 +1475,38 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p u32 obj_offset, u32 gtt_offset, int x, int y, struct intel_fb_view *view) { - struct drm_i915_private *i915 = to_i915(fb->base.dev); + struct intel_display *display = to_intel_display(fb->base.dev); struct intel_remapped_plane_info *remap_info = &view->gtt.remapped.plane[color_plane]; struct i915_color_plane_view *color_plane_info = &view->color_plane[color_plane]; unsigned int tile_width = dims->tile_width; unsigned int tile_height = dims->tile_height; - unsigned int tile_size = intel_tile_size(i915); + unsigned int tile_size = intel_tile_size(display); struct drm_rect r; u32 size = 0; - assign_bfld_chk_ovf(i915, remap_info->offset, obj_offset); + assign_bfld_chk_ovf(display, remap_info->offset, obj_offset); if (intel_fb_is_gen12_ccs_aux_plane(&fb->base, color_plane)) { remap_info->linear = 1; - assign_chk_ovf(i915, remap_info->size, + assign_chk_ovf(display, remap_info->size, plane_view_linear_tiles(fb, color_plane, dims, x, y)); } else { remap_info->linear = 0; - assign_chk_ovf(i915, remap_info->src_stride, + assign_chk_ovf(display, remap_info->src_stride, plane_view_src_stride_tiles(fb, color_plane, dims)); - assign_chk_ovf(i915, remap_info->width, + assign_chk_ovf(display, remap_info->width, plane_view_width_tiles(fb, color_plane, dims, x)); - assign_chk_ovf(i915, remap_info->height, + assign_chk_ovf(display, remap_info->height, plane_view_height_tiles(fb, color_plane, dims, y)); } if (view->gtt.type == I915_GTT_VIEW_ROTATED) { - drm_WARN_ON(&i915->drm, remap_info->linear); - check_array_bounds(i915, view->gtt.rotated.plane, color_plane); + drm_WARN_ON(display->drm, remap_info->linear); + check_array_bounds(display, view->gtt.rotated.plane, color_plane); - assign_chk_ovf(i915, remap_info->dst_stride, + assign_chk_ovf(display, remap_info->dst_stride, plane_view_dst_stride_tiles(fb, color_plane, remap_info->height)); /* rotate the x/y offsets to match the GTT view */ @@ -1520,9 +1527,9 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p /* rotate the tile dimensions to match the GTT view */ swap(tile_width, tile_height); } else { - drm_WARN_ON(&i915->drm, view->gtt.type != I915_GTT_VIEW_REMAPPED); + drm_WARN_ON(display->drm, view->gtt.type != I915_GTT_VIEW_REMAPPED); - check_array_bounds(i915, view->gtt.remapped.plane, color_plane); + check_array_bounds(display, view->gtt.remapped.plane, color_plane); if (view->gtt.remapped.plane_alignment) { u32 aligned_offset = ALIGN(gtt_offset, @@ -1556,7 +1563,7 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p dst_stride = plane_view_dst_stride_tiles(fb, color_plane, dst_stride); - assign_chk_ovf(i915, remap_info->dst_stride, dst_stride); + assign_chk_ovf(display, remap_info->dst_stride, dst_stride); color_plane_info->mapping_stride = dst_stride * tile_width * fb->base.format->cpp[color_plane]; @@ -1614,20 +1621,23 @@ calc_plane_normal_size(const struct intel_framebuffer *fb, int color_plane, return tiles; } -static void intel_fb_view_init(struct drm_i915_private *i915, struct intel_fb_view *view, +static void intel_fb_view_init(struct intel_display *display, + struct intel_fb_view *view, enum i915_gtt_view_type view_type) { memset(view, 0, sizeof(*view)); view->gtt.type = view_type; if (view_type == I915_GTT_VIEW_REMAPPED && - (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14)) + (display->platform.alderlake_p || DISPLAY_VER(display) >= 14)) view->gtt.remapped.plane_alignment = SZ_2M / PAGE_SIZE; } bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb) { - if (DISPLAY_VER(to_i915(fb->base.dev)) >= 13) + struct intel_display *display = to_intel_display(fb->base.dev); + + if (DISPLAY_VER(display) >= 13) return false; return fb->base.modifier == I915_FORMAT_MOD_Y_TILED || @@ -1636,11 +1646,11 @@ bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb) static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb) { - struct drm_i915_private *i915 = to_i915(fb->dev); + struct intel_display *display = to_intel_display(fb->dev); struct intel_plane *plane; unsigned int min_alignment = 0; - for_each_intel_plane(&i915->drm, plane) { + for_each_intel_plane(display->drm, plane) { unsigned int plane_min_alignment; if (!drm_plane_has_format(&plane->base, fb->format->format, fb->modifier)) @@ -1648,7 +1658,7 @@ static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb) plane_min_alignment = plane->min_alignment(plane, fb, 0); - drm_WARN_ON(&i915->drm, plane_min_alignment && + drm_WARN_ON(display->drm, plane_min_alignment && !is_power_of_2(plane_min_alignment)); if (intel_plane_needs_physical(plane)) @@ -1662,11 +1672,11 @@ static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb) static unsigned int intel_fb_vtd_guard(const struct drm_framebuffer *fb) { - struct drm_i915_private *i915 = to_i915(fb->dev); + struct intel_display *display = to_intel_display(fb->dev); struct intel_plane *plane; unsigned int vtd_guard = 0; - for_each_intel_plane(&i915->drm, plane) { + for_each_intel_plane(display->drm, plane) { if (!drm_plane_has_format(&plane->base, fb->format->format, fb->modifier)) continue; @@ -1676,25 +1686,25 @@ static unsigned int intel_fb_vtd_guard(const struct drm_framebuffer *fb) return vtd_guard; } -int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb) +int intel_fill_fb_info(struct intel_display *display, struct intel_framebuffer *fb) { struct drm_gem_object *obj = intel_fb_bo(&fb->base); u32 gtt_offset_rotated = 0; u32 gtt_offset_remapped = 0; unsigned int max_size = 0; int i, num_planes = fb->base.format->num_planes; - unsigned int tile_size = intel_tile_size(i915); + unsigned int tile_size = intel_tile_size(display); - intel_fb_view_init(i915, &fb->normal_view, I915_GTT_VIEW_NORMAL); + intel_fb_view_init(display, &fb->normal_view, I915_GTT_VIEW_NORMAL); - drm_WARN_ON(&i915->drm, + drm_WARN_ON(display->drm, intel_fb_supports_90_270_rotation(fb) && intel_fb_needs_pot_stride_remap(fb)); if (intel_fb_supports_90_270_rotation(fb)) - intel_fb_view_init(i915, &fb->rotated_view, I915_GTT_VIEW_ROTATED); + intel_fb_view_init(display, &fb->rotated_view, I915_GTT_VIEW_ROTATED); if (intel_fb_needs_pot_stride_remap(fb)) - intel_fb_view_init(i915, &fb->remapped_view, I915_GTT_VIEW_REMAPPED); + intel_fb_view_init(display, &fb->remapped_view, I915_GTT_VIEW_REMAPPED); for (i = 0; i < num_planes; i++) { struct fb_plane_view_dims view_dims; @@ -1713,14 +1723,14 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * unsigned int end; if (!IS_ALIGNED(fb->base.offsets[i], 64)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "fb misaligned clear color plane %d offset (0x%x)\n", i, fb->base.offsets[i]); return -EINVAL; } if (check_add_overflow(fb->base.offsets[i], 64, &end)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "fb bad clear color plane %d offset (0x%x)\n", i, fb->base.offsets[i]); return -EINVAL; @@ -1766,7 +1776,7 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * } if (mul_u32_u32(max_size, tile_size) > obj->size) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "fb too big for bo (need %llu bytes, have %zu bytes)\n", mul_u32_u32(max_size, tile_size), obj->size); return -EINVAL; @@ -1811,8 +1821,7 @@ unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb, static void intel_plane_remap_gtt(struct intel_plane_state *plane_state) { - struct drm_i915_private *i915 = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); struct drm_framebuffer *fb = plane_state->hw.fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); unsigned int rotation = plane_state->hw.rotation; @@ -1821,7 +1830,7 @@ static void intel_plane_remap_gtt(struct intel_plane_state *plane_state) unsigned int src_w, src_h; u32 gtt_offset = 0; - intel_fb_view_init(i915, &plane_state->view, + intel_fb_view_init(display, &plane_state->view, drm_rotation_90_or_270(rotation) ? I915_GTT_VIEW_ROTATED : I915_GTT_VIEW_REMAPPED); @@ -1830,7 +1839,7 @@ static void intel_plane_remap_gtt(struct intel_plane_state *plane_state) src_w = drm_rect_width(&plane_state->uapi.src) >> 16; src_h = drm_rect_height(&plane_state->uapi.src) >> 16; - drm_WARN_ON(&i915->drm, intel_fb_is_ccs_modifier(fb->modifier)); + drm_WARN_ON(display->drm, intel_fb_is_ccs_modifier(fb->modifier)); /* Make src coordinates relative to the viewport */ drm_rect_translate(&plane_state->uapi.src, @@ -1884,7 +1893,7 @@ void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotatio } static -u32 intel_fb_max_stride(struct drm_i915_private *dev_priv, +u32 intel_fb_max_stride(struct intel_display *display, u32 pixel_format, u64 modifier) { /* @@ -1893,10 +1902,10 @@ u32 intel_fb_max_stride(struct drm_i915_private *dev_priv, * * The new CCS hash mode makes remapping impossible */ - if (DISPLAY_VER(dev_priv) < 4 || intel_fb_is_ccs_modifier(modifier) || - intel_fb_modifier_uses_dpt(dev_priv, modifier)) - return intel_plane_fb_max_stride(&dev_priv->drm, pixel_format, modifier); - else if (DISPLAY_VER(dev_priv) >= 7) + if (DISPLAY_VER(display) < 4 || intel_fb_is_ccs_modifier(modifier) || + intel_fb_modifier_uses_dpt(display, modifier)) + return intel_plane_fb_max_stride(display->drm, pixel_format, modifier); + else if (DISPLAY_VER(display) >= 7) return 256 * 1024; else return 128 * 1024; @@ -1905,11 +1914,11 @@ u32 intel_fb_max_stride(struct drm_i915_private *dev_priv, static unsigned int intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) { - struct drm_i915_private *dev_priv = to_i915(fb->dev); + struct intel_display *display = to_intel_display(fb->dev); unsigned int tile_width; if (is_surface_linear(fb, color_plane)) { - unsigned int max_stride = intel_plane_fb_max_stride(&dev_priv->drm, + unsigned int max_stride = intel_plane_fb_max_stride(display->drm, fb->format->format, fb->modifier); @@ -1919,7 +1928,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) */ if (fb->pitches[color_plane] > max_stride && !intel_fb_is_ccs_modifier(fb->modifier)) - return intel_tile_size(dev_priv); + return intel_tile_size(display); else return 64; } @@ -1930,7 +1939,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) * On TGL the surface stride must be 4 tile aligned, mapped by * one 64 byte cacheline on the CCS AUX surface. */ - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) tile_width *= 4; /* * Display WA #0531: skl,bxt,kbl,glk @@ -1941,7 +1950,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) * require the entire fb to accommodate that to avoid * potential runtime errors at plane configuration time. */ - else if ((DISPLAY_VER(dev_priv) == 9 || IS_GEMINILAKE(dev_priv)) && + else if ((DISPLAY_VER(display) == 9 || display->platform.geminilake) && color_plane == 0 && fb->width > 3840) tile_width *= 4; } @@ -1950,6 +1959,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) static int intel_plane_check_stride(const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; @@ -1971,7 +1981,7 @@ static int intel_plane_check_stride(const struct intel_plane_state *plane_state) fb->modifier, rotation); if (stride > max_stride) { - drm_dbg_kms(plane->base.dev, + drm_dbg_kms(display->drm, "[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n", fb->base.id, stride, plane->base.base.id, plane->base.name, max_stride); @@ -2120,7 +2130,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd) { - struct drm_i915_private *dev_priv = to_i915(obj->dev); + struct intel_display *display = to_intel_display(obj->dev); struct drm_framebuffer *fb = &intel_fb->base; u32 max_stride; int ret = -EINVAL; @@ -2137,19 +2147,19 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, } ret = -EINVAL; - if (!drm_any_plane_has_format(&dev_priv->drm, + if (!drm_any_plane_has_format(display->drm, mode_cmd->pixel_format, mode_cmd->modifier[0])) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "unsupported pixel format %p4cc / modifier 0x%llx\n", &mode_cmd->pixel_format, mode_cmd->modifier[0]); goto err_frontbuffer_put; } - max_stride = intel_fb_max_stride(dev_priv, mode_cmd->pixel_format, + max_stride = intel_fb_max_stride(display, mode_cmd->pixel_format, mode_cmd->modifier[0]); if (mode_cmd->pitches[0] > max_stride) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "%s pitch (%u) must be at most %d\n", mode_cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR ? "tiled" : "linear", @@ -2159,26 +2169,25 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, /* FIXME need to adjust LINOFF/TILEOFF accordingly. */ if (mode_cmd->offsets[0] != 0) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "plane 0 offset (0x%08x) must be 0\n", mode_cmd->offsets[0]); goto err_frontbuffer_put; } - drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd); + drm_helper_mode_fill_fb_struct(display->drm, fb, mode_cmd); for (i = 0; i < fb->format->num_planes; i++) { unsigned int stride_alignment; if (mode_cmd->handles[i] != mode_cmd->handles[0]) { - drm_dbg_kms(&dev_priv->drm, "bad plane %d handle\n", - i); + drm_dbg_kms(display->drm, "bad plane %d handle\n", i); goto err_frontbuffer_put; } stride_alignment = intel_fb_stride_alignment(fb, i); if (fb->pitches[i] & (stride_alignment - 1)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "plane %d pitch (%d) must be at least %u byte aligned\n", i, fb->pitches[i], stride_alignment); goto err_frontbuffer_put; @@ -2188,10 +2197,9 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, unsigned int ccs_aux_stride = gen12_ccs_aux_stride(intel_fb, i); if (fb->pitches[i] != ccs_aux_stride) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "ccs aux plane %d pitch (%d) must be %d\n", - i, - fb->pitches[i], ccs_aux_stride); + i, fb->pitches[i], ccs_aux_stride); goto err_frontbuffer_put; } } @@ -2199,7 +2207,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, fb->obj[i] = obj; } - ret = intel_fill_fb_info(dev_priv, intel_fb); + ret = intel_fill_fb_info(display, intel_fb); if (ret) goto err_frontbuffer_put; @@ -2208,7 +2216,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, vm = intel_dpt_create(intel_fb); if (IS_ERR(vm)) { - drm_dbg_kms(&dev_priv->drm, "failed to create DPT\n"); + drm_dbg_kms(display->drm, "failed to create DPT\n"); ret = PTR_ERR(vm); goto err_frontbuffer_put; } @@ -2216,9 +2224,9 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, intel_fb->dpt_vm = vm; } - ret = drm_framebuffer_init(&dev_priv->drm, fb, &intel_fb_funcs); + ret = drm_framebuffer_init(display->drm, fb, &intel_fb_funcs); if (ret) { - drm_err(&dev_priv->drm, "framebuffer init failed %d\n", ret); + drm_err(display->drm, "framebuffer init failed %d\n", ret); goto err_free_dpt; } diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 026e9f7f98f7d..e6ef1783e351d 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -13,9 +13,8 @@ struct drm_device; struct drm_file; struct drm_framebuffer; struct drm_gem_object; -struct drm_i915_gem_object; -struct drm_i915_private; struct drm_mode_fb_cmd2; +struct intel_display; struct intel_fb_view; struct intel_framebuffer; struct intel_plane; @@ -41,7 +40,7 @@ bool intel_fb_is_tile4_modifier(u64 modifier); bool intel_fb_is_ccs_aux_plane(const struct drm_framebuffer *fb, int color_plane); int intel_fb_rc_ccs_cc_plane(const struct drm_framebuffer *fb); -u64 *intel_fb_plane_get_modifiers(struct drm_i915_private *i915, +u64 *intel_fb_plane_get_modifiers(struct intel_display *display, u8 plane_caps); bool intel_fb_plane_supports_modifier(struct intel_plane *plane, u64 modifier); @@ -58,7 +57,7 @@ int main_to_ccs_plane(const struct drm_framebuffer *fb, int main_plane); int skl_ccs_to_main_plane(const struct drm_framebuffer *fb, int ccs_plane); int skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane); -unsigned int intel_tile_size(const struct drm_i915_private *i915); +unsigned int intel_tile_size(struct intel_display *display); unsigned int intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane); unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane); unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_plane); @@ -80,7 +79,7 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y, bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb); bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb); -int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb); +int intel_fill_fb_info(struct intel_display *display, struct intel_framebuffer *fb); void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotation, struct intel_fb_view *view); unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb, @@ -99,7 +98,7 @@ intel_user_framebuffer_create(struct drm_device *dev, struct drm_file *filp, const struct drm_mode_fb_cmd2 *user_mode_cmd); -bool intel_fb_modifier_uses_dpt(struct drm_i915_private *i915, u64 modifier); +bool intel_fb_modifier_uses_dpt(struct intel_display *display, u64 modifier); bool intel_fb_uses_dpt(const struct drm_framebuffer *fb); unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier); diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.c b/drivers/gpu/drm/i915/display/intel_fb_bo.c index ecc95beaf6df4..3d338a7283546 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.c +++ b/drivers/gpu/drm/i915/display/intel_fb_bo.c @@ -8,6 +8,7 @@ #include "gem/i915_gem_object.h" #include "i915_drv.h" +#include "intel_display_types.h" #include "intel_fb.h" #include "intel_fb_bo.h" @@ -21,7 +22,7 @@ int intel_fb_bo_framebuffer_init(struct drm_framebuffer *fb, struct drm_mode_fb_cmd2 *mode_cmd) { struct drm_i915_gem_object *obj = to_intel_bo(_obj); - struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct intel_display *display = to_intel_display(obj->base.dev); unsigned int tiling, stride; i915_gem_object_lock(obj, NULL); @@ -36,7 +37,7 @@ int intel_fb_bo_framebuffer_init(struct drm_framebuffer *fb, */ if (tiling != I915_TILING_NONE && tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "tiling_mode doesn't match fb modifier\n"); return -EINVAL; } @@ -44,7 +45,7 @@ int intel_fb_bo_framebuffer_init(struct drm_framebuffer *fb, if (tiling == I915_TILING_X) { mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED; } else if (tiling == I915_TILING_Y) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "No Y tiling for legacy addfb\n"); return -EINVAL; } @@ -54,9 +55,9 @@ int intel_fb_bo_framebuffer_init(struct drm_framebuffer *fb, * gen2/3 display engine uses the fence if present, * so the tiling mode must match the fb modifier exactly. */ - if (DISPLAY_VER(i915) < 4 && + if (DISPLAY_VER(display) < 4 && tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "tiling_mode must match fb modifier exactly on gen2/3\n"); return -EINVAL; } @@ -66,7 +67,7 @@ int intel_fb_bo_framebuffer_init(struct drm_framebuffer *fb, * the fb pitch and fence stride match. */ if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] != stride) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "pitch (%d) must match tiling stride (%d)\n", mode_cmd->pitches[0], stride); return -EINVAL; diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index d873c3ea5fa6b..ee7839eb4099d 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -1685,7 +1685,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane->id = PLANE_SPRITE0 + sprite; plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id); - modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X); + modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X); ret = drm_universal_plane_init(display->drm, &plane->base, 0, plane_funcs, diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index e166e1915afa1..a871450150d93 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2817,7 +2817,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, INTEL_PLANE_CAP_CCS_RC_CC | INTEL_PLANE_CAP_CCS_MC); - modifiers = intel_fb_plane_get_modifiers(dev_priv, caps); + modifiers = intel_fb_plane_get_modifiers(display, caps); ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 0, plane_funcs, @@ -2994,7 +2994,7 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, } if (!dev_priv->display.params.enable_dpt && - intel_fb_modifier_uses_dpt(dev_priv, fb->modifier)) { + intel_fb_modifier_uses_dpt(display, fb->modifier)) { drm_dbg_kms(&dev_priv->drm, "DPT disabled, skipping initial FB\n"); goto error; } From 5dcfda5cfa42616ca84c41aa090e17e7417a0f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:27 +0200 Subject: [PATCH 183/284] drm/i915: Convert intel_display_power_{get,put}*() to intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass intel_display to the display power stuff. These are spread all over the place so tend to hinder clean conversions of whole files. TODO: The gt part/unpark power domain shenanigans need some kind of more abstract interface... v2: Deal with cmtg Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/g4x_dp.c | 5 +- drivers/gpu/drm/i915/display/g4x_hdmi.c | 5 +- drivers/gpu/drm/i915/display/i9xx_plane.c | 5 +- drivers/gpu/drm/i915/display/icl_dsi.c | 11 +-- drivers/gpu/drm/i915/display/intel_audio.c | 6 +- drivers/gpu/drm/i915/display/intel_cdclk.c | 8 +- drivers/gpu/drm/i915/display/intel_cmtg.c | 3 +- drivers/gpu/drm/i915/display/intel_crt.c | 16 ++-- drivers/gpu/drm/i915/display/intel_cursor.c | 10 ++- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 13 ++- drivers/gpu/drm/i915/display/intel_ddi.c | 63 ++++++++------ drivers/gpu/drm/i915/display/intel_display.c | 53 +++++++----- .../drm/i915/display/intel_display_debugfs.c | 5 +- .../gpu/drm/i915/display/intel_display_irq.c | 10 +-- .../drm/i915/display/intel_display_power.c | 85 +++++++++---------- .../drm/i915/display/intel_display_power.h | 54 ++++++------ drivers/gpu/drm/i915/display/intel_dmc.c | 7 +- drivers/gpu/drm/i915/display/intel_dp.c | 7 +- drivers/gpu/drm/i915/display/intel_dp_aux.c | 5 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 55 +++++++----- drivers/gpu/drm/i915/display/intel_gmbus.c | 10 +-- drivers/gpu/drm/i915/display/intel_hdmi.c | 10 +-- drivers/gpu/drm/i915/display/intel_hotplug.c | 5 +- drivers/gpu/drm/i915/display/intel_lvds.c | 5 +- .../drm/i915/display/intel_modeset_setup.c | 6 +- drivers/gpu/drm/i915/display/intel_pipe_crc.c | 5 +- drivers/gpu/drm/i915/display/intel_pps.c | 18 ++-- drivers/gpu/drm/i915/display/intel_sprite.c | 17 ++-- drivers/gpu/drm/i915/display/intel_tc.c | 78 +++++++++-------- drivers/gpu/drm/i915/display/intel_vdsc.c | 5 +- drivers/gpu/drm/i915/display/intel_vga.c | 5 +- .../drm/i915/display/skl_universal_plane.c | 5 +- drivers/gpu/drm/i915/display/skl_watermark.c | 5 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 4 +- drivers/gpu/drm/i915/gt/intel_gt_pm.c | 6 +- 35 files changed, 312 insertions(+), 298 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 434de337814c2..7eb5b4915f2c2 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -305,12 +305,13 @@ bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv, static bool intel_dp_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); intel_wakeref_t wakeref; bool ret; - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); if (!wakeref) return false; @@ -318,7 +319,7 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, ret = g4x_dp_port_enabled(dev_priv, intel_dp->output_reg, encoder->port, pipe); - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 3aaa7f9e9210e..7f13cf9b1a2e3 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -66,19 +66,20 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder, static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); intel_wakeref_t wakeref; bool ret; - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); if (!wakeref) return false; ret = intel_sdvo_port_enabled(dev_priv, intel_hdmi->hdmi_reg, pipe); - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 5c4652f662cba..72699944768e8 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -681,6 +681,7 @@ static bool i9xx_plane_can_async_flip(u64 modifier) static bool i9xx_plane_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum intel_display_power_domain power_domain; enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; @@ -694,7 +695,7 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane, * display power wells. */ power_domain = POWER_DOMAIN_PIPE(plane->pipe); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; @@ -707,7 +708,7 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane, else *pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val); - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 3bedaf1454b19..d6a4114c3e0ba 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -387,13 +387,12 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder, static void get_dsi_io_power_domains(struct intel_dsi *intel_dsi) { struct intel_display *display = to_intel_display(&intel_dsi->base); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum port port; for_each_dsi_port(port, intel_dsi->ports) { drm_WARN_ON(display->drm, intel_dsi->io_wakeref[port]); intel_dsi->io_wakeref[port] = - intel_display_power_get(dev_priv, + intel_display_power_get(display, port == PORT_A ? POWER_DOMAIN_PORT_DDI_IO_A : POWER_DOMAIN_PORT_DDI_IO_B); @@ -1385,7 +1384,6 @@ static void gen11_dsi_disable_port(struct intel_encoder *encoder) static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; @@ -1393,7 +1391,7 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) intel_wakeref_t wakeref; wakeref = fetch_and_zero(&intel_dsi->io_wakeref[port]); - intel_display_power_put(dev_priv, + intel_display_power_put(display, port == PORT_A ? POWER_DOMAIN_PORT_DDI_IO_A : POWER_DOMAIN_PORT_DDI_IO_B, @@ -1697,7 +1695,6 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum transcoder dsi_trans; intel_wakeref_t wakeref; @@ -1705,7 +1702,7 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, bool ret = false; u32 tmp; - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); if (!wakeref) return false; @@ -1736,7 +1733,7 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, ret = tmp & TRANSCONF_ENABLE; } out: - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index f145f83346ca3..aaba438ab41e3 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -1037,13 +1037,12 @@ int intel_audio_min_cdclk(const struct intel_crtc_state *crtc_state) static unsigned long intel_audio_component_get_power(struct device *kdev) { struct intel_display *display = to_intel_display(kdev); - struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref; /* Catch potential impedance mismatches before they occur! */ BUILD_BUG_ON(sizeof(intel_wakeref_t) > sizeof(unsigned long)); - wakeref = intel_display_power_get(i915, POWER_DOMAIN_AUDIO_PLAYBACK); + wakeref = intel_display_power_get(display, POWER_DOMAIN_AUDIO_PLAYBACK); if (display->audio.power_refcount++ == 0) { if (DISPLAY_VER(display) >= 9) { @@ -1070,7 +1069,6 @@ static void intel_audio_component_put_power(struct device *kdev, unsigned long cookie) { struct intel_display *display = to_intel_display(kdev); - struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref = (intel_wakeref_t)cookie; /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */ @@ -1078,7 +1076,7 @@ static void intel_audio_component_put_power(struct device *kdev, if (display->platform.geminilake) glk_force_audio_cdclk(display, false); - intel_display_power_put(i915, POWER_DOMAIN_AUDIO_PLAYBACK, wakeref); + intel_display_power_put(display, POWER_DOMAIN_AUDIO_PLAYBACK, wakeref); } static void intel_audio_component_codec_wake_override(struct device *kdev, diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 753ba3e3a0b71..c6cfc57a0346c 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -656,7 +656,7 @@ static void vlv_set_cdclk(struct intel_display *display, * a system suspend. So grab the display core domain, which covers * the HW blocks needed for the following programming. */ - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE); + wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE); vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_CCK) | @@ -716,7 +716,7 @@ static void vlv_set_cdclk(struct intel_display *display, vlv_program_pfi_credits(display); - intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); } static void chv_set_cdclk(struct intel_display *display, @@ -745,7 +745,7 @@ static void chv_set_cdclk(struct intel_display *display, * a system suspend. So grab the display core domain, which covers * the HW blocks needed for the following programming. */ - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE); + wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE); vlv_punit_get(dev_priv); val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM); @@ -765,7 +765,7 @@ static void chv_set_cdclk(struct intel_display *display, vlv_program_pfi_credits(display); - intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); } static int bdw_calc_cdclk(int min_cdclk) diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c b/drivers/gpu/drm/i915/display/intel_cmtg.c index 6b6fb82009f52..07d7f4e8f60f1 100644 --- a/drivers/gpu/drm/i915/display/intel_cmtg.c +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c @@ -85,7 +85,6 @@ static void intel_cmtg_dump_config(struct intel_display *display, static bool intel_cmtg_transcoder_is_secondary(struct intel_display *display, enum transcoder trans) { - struct drm_i915_private *i915 = to_i915(display->drm); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; u32 val = 0; @@ -95,7 +94,7 @@ static bool intel_cmtg_transcoder_is_secondary(struct intel_display *display, power_domain = POWER_DOMAIN_TRANSCODER(trans); - with_intel_display_power_if_enabled(i915, power_domain, wakeref) + with_intel_display_power_if_enabled(display, power_domain, wakeref) val = intel_de_read(display, TRANS_DDI_FUNC_CTL2(display, trans)); return val & CMTG_SECONDARY_MODE; diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index bc724dc5b4eaf..fb1feda46b5b7 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -108,19 +108,18 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crt *crt = intel_encoder_to_crt(encoder); intel_wakeref_t wakeref; bool ret; - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); if (!wakeref) return false; ret = intel_crt_port_enabled(display, crt->adpa_reg, pipe); - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); return ret; } @@ -858,7 +857,6 @@ intel_crt_detect(struct drm_connector *connector, bool force) { struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector)); struct intel_encoder *encoder = &crt->base; struct drm_atomic_state *state; @@ -876,7 +874,7 @@ intel_crt_detect(struct drm_connector *connector, return connector->status; if (display->params.load_detect_test) { - wakeref = intel_display_power_get(dev_priv, encoder->power_domain); + wakeref = intel_display_power_get(display, encoder->power_domain); goto load_detect; } @@ -884,7 +882,7 @@ intel_crt_detect(struct drm_connector *connector, if (dmi_check_system(intel_spurious_crt_detect)) return connector_status_disconnected; - wakeref = intel_display_power_get(dev_priv, encoder->power_domain); + wakeref = intel_display_power_get(display, encoder->power_domain); if (I915_HAS_HOTPLUG(display)) { /* We can not rely on the HPD pin always being correctly wired @@ -941,7 +939,7 @@ intel_crt_detect(struct drm_connector *connector, } out: - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); return status; } @@ -959,7 +957,7 @@ static int intel_crt_get_modes(struct drm_connector *connector) if (!intel_display_driver_check_access(display)) return drm_edid_connector_add_modes(connector); - wakeref = intel_display_power_get(dev_priv, encoder->power_domain); + wakeref = intel_display_power_get(display, encoder->power_domain); ret = intel_crt_ddc_get_modes(connector, connector->ddc); if (ret || !IS_G4X(dev_priv)) @@ -970,7 +968,7 @@ static int intel_crt_get_modes(struct drm_connector *connector) ret = intel_crt_ddc_get_modes(connector, ddc); out: - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 9c9cded729aff..6a0d563174cf9 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -326,13 +326,14 @@ static void i845_cursor_disable_arm(struct intel_dsb *dsb, static bool i845_cursor_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; bool ret; power_domain = POWER_DOMAIN_PIPE(PIPE_A); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; @@ -340,7 +341,7 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane, *pipe = PIPE_A; - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } @@ -733,6 +734,7 @@ static void i9xx_cursor_disable_arm(struct intel_dsb *dsb, static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; @@ -745,7 +747,7 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, * display power wells. */ power_domain = POWER_DOMAIN_PIPE(plane->pipe); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; @@ -758,7 +760,7 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, else *pipe = REG_FIELD_GET(MCURSOR_PIPE_SEL_MASK, val); - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 0ff76ef10d4bc..4121d0d759bf2 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -73,10 +73,9 @@ static u8 intel_cx0_get_owned_lane_mask(struct intel_encoder *encoder) static void assert_dc_off(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); bool enabled; - enabled = intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF); + enabled = intel_display_power_is_enabled(display, POWER_DOMAIN_DC_OFF); drm_WARN_ON(display->drm, !enabled); } @@ -103,12 +102,12 @@ static void intel_cx0_program_msgbus_timer(struct intel_encoder *encoder) */ static intel_wakeref_t intel_cx0_phy_transaction_begin(struct intel_encoder *encoder) { - intel_wakeref_t wakeref; - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + intel_wakeref_t wakeref; intel_psr_pause(intel_dp); - wakeref = intel_display_power_get(i915, POWER_DOMAIN_DC_OFF); + wakeref = intel_display_power_get(display, POWER_DOMAIN_DC_OFF); intel_cx0_program_msgbus_timer(encoder); return wakeref; @@ -116,11 +115,11 @@ static intel_wakeref_t intel_cx0_phy_transaction_begin(struct intel_encoder *enc static void intel_cx0_phy_transaction_end(struct intel_encoder *encoder, intel_wakeref_t wakeref) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); intel_psr_resume(intel_dp); - intel_display_power_put(i915, POWER_DOMAIN_DC_OFF, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DC_OFF, wakeref); } static void intel_clear_response_ready_flag(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 3e85ef281f1e1..6b274b7a5c3f5 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -705,19 +705,20 @@ int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, enum transcoder cpu_transcoder, bool enable, u32 hdcp_mask) { + struct intel_display *display = to_intel_display(intel_encoder); struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); intel_wakeref_t wakeref; int ret = 0; - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, intel_encoder->power_domain); if (drm_WARN_ON(dev, !wakeref)) return -ENXIO; intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), hdcp_mask, enable ? hdcp_mask : 0); - intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref); + intel_display_power_put(display, intel_encoder->power_domain, wakeref); return ret; } @@ -734,7 +735,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) u32 ddi_mode; bool ret; - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); if (!wakeref) return false; @@ -775,7 +776,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) } out: - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); return ret; } @@ -794,7 +795,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, *pipe_mask = 0; *is_dp_mst = false; - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); if (!wakeref) return; @@ -831,7 +832,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, u32 port_mask, ddi_select, ddi_mode; intel_wakeref_t trans_wakeref; - trans_wakeref = intel_display_power_get_if_enabled(dev_priv, + trans_wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_TRANSCODER(cpu_transcoder)); if (!trans_wakeref) continue; @@ -846,7 +847,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); - intel_display_power_put(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder), + intel_display_power_put(display, POWER_DOMAIN_TRANSCODER(cpu_transcoder), trans_wakeref); if ((tmp & port_mask) != ddi_select) @@ -911,7 +912,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, encoder->base.base.id, encoder->base.name, tmp); } - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); } bool intel_ddi_get_hw_state(struct intel_encoder *encoder, @@ -963,23 +964,23 @@ static void main_link_aux_power_domain_get(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); enum intel_display_power_domain domain = intel_ddi_main_link_aux_domain(dig_port, crtc_state); - drm_WARN_ON(&i915->drm, dig_port->aux_wakeref); + drm_WARN_ON(display->drm, dig_port->aux_wakeref); if (domain == POWER_DOMAIN_INVALID) return; - dig_port->aux_wakeref = intel_display_power_get(i915, domain); + dig_port->aux_wakeref = intel_display_power_get(display, domain); } static void main_link_aux_power_domain_put(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); enum intel_display_power_domain domain = intel_ddi_main_link_aux_domain(dig_port, crtc_state); intel_wakeref_t wf; @@ -988,13 +989,13 @@ main_link_aux_power_domain_put(struct intel_digital_port *dig_port, if (!wf) return; - intel_display_power_put(i915, domain, wf); + intel_display_power_put(display, domain, wf); } static void intel_ddi_get_power_domains(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port; /* @@ -1002,15 +1003,15 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder, * happen since fake-MST encoders don't set their get_power_domains() * hook. */ - if (drm_WARN_ON(&dev_priv->drm, + if (drm_WARN_ON(display->drm, intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))) return; dig_port = enc_to_dig_port(encoder); if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { - drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); - dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + drm_WARN_ON(display->drm, dig_port->ddi_io_wakeref); + dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); } @@ -2721,6 +2722,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); @@ -2767,7 +2769,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, /* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */ if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); - dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); } @@ -2868,6 +2870,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; @@ -2896,7 +2899,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); - dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); } @@ -2963,6 +2966,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &dig_port->hdmi; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -2971,7 +2975,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, intel_ddi_enable_clock(encoder, crtc_state); drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); - dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); icl_program_mg_dp_mode(dig_port, crtc_state); @@ -3130,6 +3134,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_dp *intel_dp = &dig_port->dp; @@ -3181,7 +3186,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); if (wakeref) - intel_display_power_put(dev_priv, + intel_display_power_put(display, dig_port->ddi_io_power_domain, wakeref); @@ -3198,6 +3203,7 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &dig_port->hdmi; @@ -3216,7 +3222,7 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); if (wakeref) - intel_display_power_put(dev_priv, + intel_display_power_put(display, dig_port->ddi_io_power_domain, wakeref); @@ -3893,10 +3899,12 @@ static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp, static bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder) { + struct intel_display *display = &dev_priv->display; + if (cpu_transcoder == TRANSCODER_EDP) return false; - if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO_MMIO)) + if (!intel_display_power_is_enabled(display, POWER_DOMAIN_AUDIO_MMIO)) return false; return intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD) & @@ -3972,6 +3980,7 @@ static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *de static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); u32 transcoders = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); @@ -3985,7 +3994,7 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) intel_wakeref_t trans_wakeref; power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); - trans_wakeref = intel_display_power_get_if_enabled(dev_priv, + trans_wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!trans_wakeref) @@ -3995,7 +4004,7 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) crtc_state->cpu_transcoder) crtc_state->sync_mode_slaves_mask |= BIT(cpu_transcoder); - intel_display_power_put(dev_priv, power_domain, trans_wakeref); + intel_display_power_put(display, power_domain, trans_wakeref); } drm_WARN_ON(&dev_priv->drm, @@ -4610,13 +4619,13 @@ static int intel_ddi_compute_config_late(struct intel_encoder *encoder, static void intel_ddi_encoder_destroy(struct drm_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->dev); + struct intel_display *display = to_intel_display(encoder->dev); struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder)); intel_dp_encoder_flush_work(encoder); if (intel_encoder_is_tc(&dig_port->base)) intel_tc_port_cleanup(dig_port); - intel_display_power_flush_work(i915); + intel_display_power_flush_work(display); drm_encoder_cleanup(encoder); kfree(dig_port->hdcp_port_data.streams); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9ab1680cb2d39..2bc59dfa653d8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -432,13 +432,13 @@ void assert_transcoder(struct drm_i915_private *dev_priv, state = true; power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (wakeref) { u32 val = intel_de_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder)); cur_state = !!(val & TRANSCONF_ENABLE); - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); } else { cur_state = false; } @@ -2160,8 +2160,8 @@ static void get_crtc_power_domains(struct intel_crtc_state *crtc_state, void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state, struct intel_power_domain_mask *old_domains) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum intel_display_power_domain domain; struct intel_power_domain_mask domains, new_domains; @@ -2177,7 +2177,7 @@ void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state, POWER_DOMAIN_NUM); for_each_power_domain(domain, &new_domains) - intel_display_power_get_in_set(dev_priv, + intel_display_power_get_in_set(display, &crtc->enabled_power_domains, domain); } @@ -2185,7 +2185,9 @@ void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state, void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc, struct intel_power_domain_mask *domains) { - intel_display_power_put_mask_in_set(to_i915(crtc->base.dev), + struct intel_display *display = to_intel_display(crtc); + + intel_display_power_put_mask_in_set(display, &crtc->enabled_power_domains, domains); } @@ -3221,6 +3223,7 @@ bdw_get_pipe_misc_output_format(struct intel_crtc *crtc) static bool i9xx_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; @@ -3228,7 +3231,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, bool ret; power_domain = POWER_DOMAIN_PIPE(crtc->pipe); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; @@ -3322,7 +3325,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, ret = true; out: - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } @@ -3603,6 +3606,7 @@ static void ilk_get_pfit_config(struct intel_crtc_state *crtc_state) static bool ilk_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { + struct intel_display *display = to_intel_display(crtc); struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; @@ -3611,7 +3615,7 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, bool ret; power_domain = POWER_DOMAIN_PIPE(crtc->pipe); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; @@ -3676,7 +3680,7 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, ret = true; out: - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } @@ -3698,13 +3702,14 @@ static u8 joiner_pipes(struct drm_i915_private *i915) static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder) { + struct intel_display *display = &dev_priv->display; enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; u32 tmp = 0; power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); - with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) + with_intel_display_power_if_enabled(display, power_domain, wakeref) tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); @@ -3730,7 +3735,7 @@ static void enabled_uncompressed_joiner_pipes(struct intel_display *display, intel_wakeref_t wakeref; power_domain = POWER_DOMAIN_PIPE(pipe); - with_intel_display_power_if_enabled(i915, power_domain, wakeref) { + with_intel_display_power_if_enabled(display, power_domain, wakeref) { u32 tmp = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe)); if (tmp & UNCOMPRESSED_JOINER_PRIMARY) @@ -3760,7 +3765,7 @@ static void enabled_bigjoiner_pipes(struct intel_display *display, intel_wakeref_t wakeref; power_domain = intel_dsc_power_domain(crtc, (enum transcoder)pipe); - with_intel_display_power_if_enabled(i915, power_domain, wakeref) { + with_intel_display_power_if_enabled(display, power_domain, wakeref) { u32 tmp = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe)); if (!(tmp & BIG_JOINER_ENABLE)) @@ -3831,7 +3836,7 @@ static void enabled_ultrajoiner_pipes(struct drm_i915_private *i915, intel_wakeref_t wakeref; power_domain = intel_dsc_power_domain(crtc, (enum transcoder)pipe); - with_intel_display_power_if_enabled(i915, power_domain, wakeref) { + with_intel_display_power_if_enabled(display, power_domain, wakeref) { u32 tmp = intel_de_read(i915, ICL_PIPE_DSS_CTL1(pipe)); if (!(tmp & ULTRA_JOINER_ENABLE)) @@ -3977,6 +3982,7 @@ static u8 hsw_panel_transcoders(struct drm_i915_private *i915) static u8 hsw_enabled_transcoders(struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv); @@ -3996,7 +4002,7 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc) u32 tmp = 0; power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); - with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) + with_intel_display_power_if_enabled(display, power_domain, wakeref) tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); @@ -4081,6 +4087,7 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config, struct intel_display_power_domain_set *power_domain_set) { + struct intel_display *display = to_intel_display(crtc); struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); unsigned long enabled_transcoders; @@ -4099,7 +4106,7 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, */ pipe_config->cpu_transcoder = ffs(enabled_transcoders) - 1; - if (!intel_display_power_get_in_set_if_enabled(dev_priv, power_domain_set, + if (!intel_display_power_get_in_set_if_enabled(display, power_domain_set, POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder))) return false; @@ -4133,7 +4140,7 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, else cpu_transcoder = TRANSCODER_DSI_C; - if (!intel_display_power_get_in_set_if_enabled(dev_priv, power_domain_set, + if (!intel_display_power_get_in_set_if_enabled(display, power_domain_set, POWER_DOMAIN_TRANSCODER(cpu_transcoder))) continue; @@ -4186,7 +4193,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, bool active; u32 tmp; - if (!intel_display_power_get_in_set_if_enabled(dev_priv, &crtc->hw_readout_power_domains, + if (!intel_display_power_get_in_set_if_enabled(display, &crtc->hw_readout_power_domains, POWER_DOMAIN_PIPE(crtc->pipe))) return false; @@ -4238,7 +4245,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, pipe_config->ips_linetime = REG_FIELD_GET(HSW_IPS_LINETIME_MASK, tmp); - if (intel_display_power_get_in_set_if_enabled(dev_priv, &crtc->hw_readout_power_domains, + if (intel_display_power_get_in_set_if_enabled(display, &crtc->hw_readout_power_domains, POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe))) { if (DISPLAY_VER(dev_priv) >= 9) skl_scaler_get_config(pipe_config); @@ -4267,7 +4274,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, } out: - intel_display_power_put_all_in_set(dev_priv, &crtc->hw_readout_power_domains); + intel_display_power_put_all_in_set(display, &crtc->hw_readout_power_domains); return active; } @@ -7201,6 +7208,7 @@ static void intel_enable_crtc(struct intel_atomic_state *state, static void intel_pre_update_crtc(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); struct drm_i915_private *i915 = to_i915(state->base.dev); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); @@ -7235,7 +7243,7 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state, intel_fbc_update(state, crtc); - drm_WARN_ON(&i915->drm, !intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF)); + drm_WARN_ON(display->drm, !intel_display_power_is_enabled(display, POWER_DOMAIN_DC_OFF)); if (!modeset && intel_crtc_needs_color_update(new_crtc_state) && @@ -7756,6 +7764,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, static void intel_atomic_commit_tail(struct intel_atomic_state *state) { + struct intel_display *display = to_intel_display(state); struct drm_device *dev = state->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc_state *new_crtc_state, *old_crtc_state; @@ -7807,7 +7816,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * the CSC latched register values with the readout (see * skl_read_csc() and skl_color_commit_noarm()). */ - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DC_OFF); + wakeref = intel_display_power_get(display, POWER_DOMAIN_DC_OFF); for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { @@ -7965,7 +7974,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * Delay re-enabling DC states by 17 ms to avoid the off->on->off * toggling overhead at and above 60 FPS. */ - intel_display_power_put_async_delay(dev_priv, POWER_DOMAIN_DC_OFF, wakeref, 17); + intel_display_power_put_async_delay(display, POWER_DOMAIN_DC_OFF, wakeref, 17); intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); /* diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index e547ea66657de..89e5eea90be85 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -86,10 +86,11 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused) static int i915_sr_status(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_display *display = &dev_priv->display; intel_wakeref_t wakeref; bool sr_enabled = false; - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); + wakeref = intel_display_power_get(display, POWER_DOMAIN_INIT); if (DISPLAY_VER(dev_priv) >= 9) /* no global SR status; inspect per-plane WM */; @@ -105,7 +106,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) sr_enabled = intel_de_read(dev_priv, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref); + intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref); seq_printf(m, "self-refresh: %s\n", str_enabled_disabled(sr_enabled)); diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index d9734fcd0d45b..0f68b0a34ca95 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1617,7 +1617,7 @@ void gen8_display_irq_reset(struct drm_i915_private *dev_priv) intel_de_write(display, EDP_PSR_IIR, 0xffffffff); for_each_pipe(dev_priv, pipe) - if (intel_display_power_is_enabled(dev_priv, + if (intel_display_power_is_enabled(display, POWER_DOMAIN_PIPE(pipe))) intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); @@ -1644,7 +1644,7 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) enum intel_display_power_domain domain; domain = POWER_DOMAIN_TRANSCODER(trans); - if (!intel_display_power_is_enabled(dev_priv, domain)) + if (!intel_display_power_is_enabled(display, domain)) continue; intel_de_write(display, @@ -1660,7 +1660,7 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) } for_each_pipe(dev_priv, pipe) - if (intel_display_power_is_enabled(dev_priv, + if (intel_display_power_is_enabled(display, POWER_DOMAIN_PIPE(pipe))) intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); @@ -1887,7 +1887,7 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) enum intel_display_power_domain domain; domain = POWER_DOMAIN_TRANSCODER(trans); - if (!intel_display_power_is_enabled(dev_priv, domain)) + if (!intel_display_power_is_enabled(display, domain)) continue; intel_display_irq_regs_assert_irr_is_zero(display, @@ -1900,7 +1900,7 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) for_each_pipe(dev_priv, pipe) { dev_priv->display.irq.de_irq_mask[pipe] = ~de_pipe_masked; - if (intel_display_power_is_enabled(dev_priv, + if (intel_display_power_is_enabled(display, POWER_DOMAIN_PIPE(pipe))) intel_display_irq_regs_init(display, GEN8_DE_PIPE_IRQ_REGS(pipe), dev_priv->display.irq.de_irq_mask[pipe], diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 14ae60749f02c..cfc5c0b4f9072 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -224,7 +224,7 @@ static bool __intel_display_power_is_enabled(struct intel_display *display, /** * intel_display_power_is_enabled - check for a power domain - * @dev_priv: i915 device instance + * @display: display device instance * @domain: power domain to check * * This function can be used to check the hw power domain state. It is mostly @@ -239,10 +239,9 @@ static bool __intel_display_power_is_enabled(struct intel_display *display, * Returns: * True when the power domain is enabled, false otherwise. */ -bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, +bool intel_display_power_is_enabled(struct intel_display *display, enum intel_display_power_domain domain) { - struct intel_display *display = &dev_priv->display; struct i915_power_domains *power_domains = &display->power.domains; bool ret; @@ -500,7 +499,7 @@ __intel_display_power_get_domain(struct intel_display *display, /** * intel_display_power_get - grab a power domain reference - * @dev_priv: i915 device instance + * @display: display device instance * @domain: power domain to reference * * This function grabs a power domain reference for @domain and ensures that the @@ -510,10 +509,10 @@ __intel_display_power_get_domain(struct intel_display *display, * Any power domain reference obtained by this function must have a symmetric * call to intel_display_power_put() to release the reference again. */ -intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv, +intel_wakeref_t intel_display_power_get(struct intel_display *display, enum intel_display_power_domain domain) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; intel_wakeref_t wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); @@ -526,7 +525,7 @@ intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv, /** * intel_display_power_get_if_enabled - grab a reference for an enabled display power domain - * @dev_priv: i915 device instance + * @display: display device instance * @domain: power domain to reference * * This function grabs a power domain reference for @domain and ensures that the @@ -537,10 +536,10 @@ intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv, * call to intel_display_power_put() to release the reference again. */ intel_wakeref_t -intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, +intel_display_power_get_if_enabled(struct intel_display *display, enum intel_display_power_domain domain) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; intel_wakeref_t wakeref; bool is_enabled; @@ -696,7 +695,7 @@ intel_display_power_put_async_work(struct work_struct *work) /** * __intel_display_power_put_async - release a power domain reference asynchronously - * @i915: i915 device instance + * @display: display device instance * @domain: power domain to reference * @wakeref: wakeref acquired for the reference that is being released * @delay_ms: delay of powering down the power domain @@ -707,12 +706,12 @@ intel_display_power_put_async_work(struct work_struct *work) * The power down is delayed by @delay_ms if this is >= 0, or by a default * 100 ms otherwise. */ -void __intel_display_power_put_async(struct drm_i915_private *i915, +void __intel_display_power_put_async(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref, int delay_ms) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_runtime_pm *rpm = &i915->runtime_pm; intel_wakeref_t work_wakeref = intel_runtime_pm_get_raw(rpm); @@ -754,7 +753,7 @@ void __intel_display_power_put_async(struct drm_i915_private *i915, /** * intel_display_power_flush_work - flushes the async display power disabling work - * @i915: i915 device instance + * @display: display device instance * * Flushes any pending work that was scheduled by a preceding * intel_display_power_put_async() call, completing the disabling of the @@ -764,9 +763,9 @@ void __intel_display_power_put_async(struct drm_i915_private *i915, * function returns; to ensure that the work handler isn't running use * intel_display_power_flush_work_sync() instead. */ -void intel_display_power_flush_work(struct drm_i915_private *i915) +void intel_display_power_flush_work(struct intel_display *display) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_power_domain_mask async_put_mask; intel_wakeref_t work_wakeref; @@ -800,10 +799,9 @@ void intel_display_power_flush_work(struct drm_i915_private *i915) static void intel_display_power_flush_work_sync(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - intel_display_power_flush_work(i915); + intel_display_power_flush_work(display); cancel_async_put_work(power_domains, true); verify_async_put_domains_state(power_domains); @@ -814,7 +812,7 @@ intel_display_power_flush_work_sync(struct intel_display *display) #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) /** * intel_display_power_put - release a power domain reference - * @dev_priv: i915 device instance + * @display: display device instance * @domain: power domain to reference * @wakeref: wakeref acquired for the reference that is being released * @@ -822,11 +820,11 @@ intel_display_power_flush_work_sync(struct intel_display *display) * intel_display_power_get() and might power down the corresponding hardware * block right away if this is the last reference. */ -void intel_display_power_put(struct drm_i915_private *dev_priv, +void intel_display_power_put(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); __intel_display_power_put(display, domain); intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); @@ -834,7 +832,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, #else /** * intel_display_power_put_unchecked - release an unchecked power domain reference - * @dev_priv: i915 device instance + * @display: display device instance * @domain: power domain to reference * * This function drops the power domain reference obtained by @@ -845,10 +843,10 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, * tracking when the corresponding debug kconfig option is disabled, should not * be used otherwise. */ -void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, +void intel_display_power_put_unchecked(struct intel_display *display, enum intel_display_power_domain domain) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); __intel_display_power_put(display, domain); intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm); @@ -856,16 +854,15 @@ void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, #endif void -intel_display_power_get_in_set(struct drm_i915_private *i915, +intel_display_power_get_in_set(struct intel_display *display, struct intel_display_power_domain_set *power_domain_set, enum intel_display_power_domain domain) { - struct intel_display *display = &i915->display; intel_wakeref_t __maybe_unused wf; drm_WARN_ON(display->drm, test_bit(domain, power_domain_set->mask.bits)); - wf = intel_display_power_get(i915, domain); + wf = intel_display_power_get(display, domain); #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) power_domain_set->wakerefs[domain] = wf; #endif @@ -873,16 +870,15 @@ intel_display_power_get_in_set(struct drm_i915_private *i915, } bool -intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915, +intel_display_power_get_in_set_if_enabled(struct intel_display *display, struct intel_display_power_domain_set *power_domain_set, enum intel_display_power_domain domain) { - struct intel_display *display = &i915->display; intel_wakeref_t wf; drm_WARN_ON(display->drm, test_bit(domain, power_domain_set->mask.bits)); - wf = intel_display_power_get_if_enabled(i915, domain); + wf = intel_display_power_get_if_enabled(display, domain); if (!wf) return false; @@ -895,11 +891,10 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915, } void -intel_display_power_put_mask_in_set(struct drm_i915_private *i915, +intel_display_power_put_mask_in_set(struct intel_display *display, struct intel_display_power_domain_set *power_domain_set, struct intel_power_domain_mask *mask) { - struct intel_display *display = &i915->display; enum intel_display_power_domain domain; drm_WARN_ON(display->drm, @@ -911,7 +906,7 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915, #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) wf = fetch_and_zero(&power_domain_set->wakerefs[domain]); #endif - intel_display_power_put(i915, domain, wf); + intel_display_power_put(display, domain, wf); clear_bit(domain, power_domain_set->mask.bits); } } @@ -999,7 +994,7 @@ static u32 get_allowed_dc_mask(struct intel_display *display, int enable_dc) * intel_power_domains_init - initializes the power domain structures * @display: display device instance * - * Initializes the power domain structures for @dev_priv depending upon the + * Initializes the power domain structures for @display depending upon the * supported platform. */ int intel_power_domains_init(struct intel_display *display) @@ -1963,12 +1958,12 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume) */ drm_WARN_ON(display->drm, power_domains->init_wakeref); power_domains->init_wakeref = - intel_display_power_get(i915, POWER_DOMAIN_INIT); + intel_display_power_get(display, POWER_DOMAIN_INIT); /* Disable power support if the user asked so. */ if (!display->params.disable_power_well) { drm_WARN_ON(display->drm, power_domains->disable_wakeref); - display->power.domains.disable_wakeref = intel_display_power_get(i915, + display->power.domains.disable_wakeref = intel_display_power_get(display, POWER_DOMAIN_INIT); } intel_power_domains_sync_hw(display); @@ -1995,7 +1990,7 @@ void intel_power_domains_driver_remove(struct intel_display *display) /* Remove the refcount we took to keep power well support disabled. */ if (!display->params.disable_power_well) - intel_display_power_put(i915, POWER_DOMAIN_INIT, + intel_display_power_put(display, POWER_DOMAIN_INIT, fetch_and_zero(&display->power.domains.disable_wakeref)); intel_display_power_flush_work_sync(display); @@ -2051,11 +2046,10 @@ void intel_power_domains_sanitize_state(struct intel_display *display) */ void intel_power_domains_enable(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref __maybe_unused = fetch_and_zero(&display->power.domains.init_wakeref); - intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref); + intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref); intel_power_domains_verify_state(display); } @@ -2068,12 +2062,11 @@ void intel_power_domains_enable(struct intel_display *display) */ void intel_power_domains_disable(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; drm_WARN_ON(display->drm, power_domains->init_wakeref); power_domains->init_wakeref = - intel_display_power_get(i915, POWER_DOMAIN_INIT); + intel_display_power_get(display, POWER_DOMAIN_INIT); intel_power_domains_verify_state(display); } @@ -2091,12 +2084,11 @@ void intel_power_domains_disable(struct intel_display *display) */ void intel_power_domains_suspend(struct intel_display *display, bool s2idle) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; intel_wakeref_t wakeref __maybe_unused = fetch_and_zero(&power_domains->init_wakeref); - intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref); + intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref); /* * In case of suspend-to-idle (aka S0ix) on a DMC platform without DC9 @@ -2107,7 +2099,7 @@ void intel_power_domains_suspend(struct intel_display *display, bool s2idle) */ if (!(power_domains->allowed_dc_mask & DC_STATE_EN_DC9) && s2idle && intel_dmc_has_payload(display)) { - intel_display_power_flush_work(i915); + intel_display_power_flush_work(display); intel_power_domains_verify_state(display); return; } @@ -2117,10 +2109,10 @@ void intel_power_domains_suspend(struct intel_display *display, bool s2idle) * power wells if power domains must be deinitialized for suspend. */ if (!display->params.disable_power_well) - intel_display_power_put(i915, POWER_DOMAIN_INIT, + intel_display_power_put(display, POWER_DOMAIN_INIT, fetch_and_zero(&display->power.domains.disable_wakeref)); - intel_display_power_flush_work(i915); + intel_display_power_flush_work(display); intel_power_domains_verify_state(display); if (DISPLAY_VER(display) >= 11) @@ -2145,7 +2137,6 @@ void intel_power_domains_suspend(struct intel_display *display, bool s2idle) */ void intel_power_domains_resume(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; if (power_domains->display_core_suspended) { @@ -2154,7 +2145,7 @@ void intel_power_domains_resume(struct intel_display *display) } else { drm_WARN_ON(display->drm, power_domains->init_wakeref); power_domains->init_wakeref = - intel_display_power_get(i915, POWER_DOMAIN_INIT); + intel_display_power_get(display, POWER_DOMAIN_INIT); } intel_power_domains_verify_state(display); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 7b294eec44310..b5d67b6c73cff 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -184,88 +184,88 @@ void intel_display_power_resume(struct intel_display *display); void intel_display_power_set_target_dc_state(struct intel_display *display, u32 state); -bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, +bool intel_display_power_is_enabled(struct intel_display *display, enum intel_display_power_domain domain); -intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv, +intel_wakeref_t intel_display_power_get(struct intel_display *display, enum intel_display_power_domain domain); intel_wakeref_t -intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, +intel_display_power_get_if_enabled(struct intel_display *display, enum intel_display_power_domain domain); -void __intel_display_power_put_async(struct drm_i915_private *i915, +void __intel_display_power_put_async(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref, int delay_ms); -void intel_display_power_flush_work(struct drm_i915_private *i915); +void intel_display_power_flush_work(struct intel_display *display); #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) -void intel_display_power_put(struct drm_i915_private *dev_priv, +void intel_display_power_put(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref); static inline void -intel_display_power_put_async(struct drm_i915_private *i915, +intel_display_power_put_async(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref) { - __intel_display_power_put_async(i915, domain, wakeref, -1); + __intel_display_power_put_async(display, domain, wakeref, -1); } static inline void -intel_display_power_put_async_delay(struct drm_i915_private *i915, +intel_display_power_put_async_delay(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref, int delay_ms) { - __intel_display_power_put_async(i915, domain, wakeref, delay_ms); + __intel_display_power_put_async(display, domain, wakeref, delay_ms); } #else void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain); static inline void -intel_display_power_put(struct drm_i915_private *i915, +intel_display_power_put(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref) { - intel_display_power_put_unchecked(i915, domain); + intel_display_power_put_unchecked(display, domain); } static inline void -intel_display_power_put_async(struct drm_i915_private *i915, +intel_display_power_put_async(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref) { - __intel_display_power_put_async(i915, domain, INTEL_WAKEREF_DEF, -1); + __intel_display_power_put_async(display, domain, INTEL_WAKEREF_DEF, -1); } static inline void -intel_display_power_put_async_delay(struct drm_i915_private *i915, +intel_display_power_put_async_delay(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref, int delay_ms) { - __intel_display_power_put_async(i915, domain, INTEL_WAKEREF_DEF, delay_ms); + __intel_display_power_put_async(display, domain, INTEL_WAKEREF_DEF, delay_ms); } #endif void -intel_display_power_get_in_set(struct drm_i915_private *i915, +intel_display_power_get_in_set(struct intel_display *display, struct intel_display_power_domain_set *power_domain_set, enum intel_display_power_domain domain); bool -intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915, +intel_display_power_get_in_set_if_enabled(struct intel_display *display, struct intel_display_power_domain_set *power_domain_set, enum intel_display_power_domain domain); void -intel_display_power_put_mask_in_set(struct drm_i915_private *i915, +intel_display_power_put_mask_in_set(struct intel_display *display, struct intel_display_power_domain_set *power_domain_set, struct intel_power_domain_mask *mask); static inline void -intel_display_power_put_all_in_set(struct drm_i915_private *i915, +intel_display_power_put_all_in_set(struct intel_display *display, struct intel_display_power_domain_set *power_domain_set) { - intel_display_power_put_mask_in_set(i915, power_domain_set, &power_domain_set->mask); + intel_display_power_put_mask_in_set(display, power_domain_set, &power_domain_set->mask); } void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m); @@ -296,12 +296,12 @@ enum dbuf_slice { void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv, u8 req_slices); -#define with_intel_display_power(i915, domain, wf) \ - for ((wf) = intel_display_power_get((i915), (domain)); (wf); \ - intel_display_power_put_async((i915), (domain), (wf)), (wf) = NULL) +#define with_intel_display_power(display, domain, wf) \ + for ((wf) = intel_display_power_get((display), (domain)); (wf); \ + intel_display_power_put_async((display), (domain), (wf)), (wf) = NULL) -#define with_intel_display_power_if_enabled(i915, domain, wf) \ - for ((wf) = intel_display_power_get_if_enabled((i915), (domain)); (wf); \ - intel_display_power_put_async((i915), (domain), (wf)), (wf) = NULL) +#define with_intel_display_power_if_enabled(display, domain, wf) \ + for ((wf) = intel_display_power_get_if_enabled((display), (domain)); (wf); \ + intel_display_power_put_async((display), (domain), (wf)), (wf) = NULL) #endif /* __INTEL_DISPLAY_POWER_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 221d3abda7915..fa6944e55d955 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -992,19 +992,16 @@ static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw) static void intel_dmc_runtime_pm_get(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - drm_WARN_ON(display->drm, display->dmc.wakeref); - display->dmc.wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT); + display->dmc.wakeref = intel_display_power_get(display, POWER_DOMAIN_INIT); } static void intel_dmc_runtime_pm_put(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref __maybe_unused = fetch_and_zero(&display->dmc.wakeref); - intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref); + intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref); } static const char *dmc_fallback_path(struct intel_display *display) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7463478eef92d..0fb622c8110c3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5470,13 +5470,13 @@ void intel_digital_port_unlock(struct intel_encoder *encoder) */ bool intel_digital_port_connected_locked(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_glitch_free = intel_tc_port_handles_hpd_glitches(dig_port); bool is_connected = false; intel_wakeref_t wakeref; - with_intel_display_power(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref) { + with_intel_display_power(display, POWER_DOMAIN_DISPLAY_CORE, wakeref) { unsigned long wait_expires = jiffies + msecs_to_jiffies_timeout(4); do { @@ -6523,7 +6523,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, struct intel_dp *intel_dp = &dig_port->dp; struct intel_encoder *encoder = &dig_port->base; struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); enum port port = encoder->port; int type; @@ -6623,7 +6622,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, return true; fail: - intel_display_power_flush_work(dev_priv); + intel_display_power_flush_work(display); drm_connector_cleanup(&connector->base); return false; diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index 40c697476b729..ec27bbd70bcf0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -243,7 +243,6 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); i915_reg_t ch_ctl, ch_data[5]; u32 aux_clock_divider; enum intel_display_power_domain aux_domain; @@ -272,7 +271,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, aux_domain = intel_aux_power_domain(dig_port); - aux_wakeref = intel_display_power_get(i915, aux_domain); + aux_wakeref = intel_display_power_get(display, aux_domain); pps_wakeref = intel_pps_lock(intel_dp); /* @@ -432,7 +431,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, intel_pps_vdd_off_unlocked(intel_dp, false); intel_pps_unlock(intel_dp, pps_wakeref); - intel_display_power_put_async(i915, aux_domain, aux_wakeref); + intel_display_power_put_async(display, aux_domain, aux_wakeref); out_unlock: intel_digital_port_unlock(encoder); diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index b8fa04d3cd5c5..cb2ef317d219b 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -228,8 +228,10 @@ intel_tc_pll_enable_reg(struct drm_i915_private *i915, static void _intel_enable_shared_dpll(struct drm_i915_private *i915, struct intel_shared_dpll *pll) { + struct intel_display *display = &i915->display; + if (pll->info->power_domain) - pll->wakeref = intel_display_power_get(i915, pll->info->power_domain); + pll->wakeref = intel_display_power_get(display, pll->info->power_domain); pll->info->funcs->enable(i915, pll, &pll->state.hw_state); pll->on = true; @@ -238,11 +240,13 @@ static void _intel_enable_shared_dpll(struct drm_i915_private *i915, static void _intel_disable_shared_dpll(struct drm_i915_private *i915, struct intel_shared_dpll *pll) { + struct intel_display *display = &i915->display; + pll->info->funcs->disable(i915, pll); pll->on = false; if (pll->info->power_domain) - intel_display_power_put(i915, pll->info->power_domain, pll->wakeref); + intel_display_power_put(display, pll->info->power_domain, pll->wakeref); } /** @@ -525,12 +529,13 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *i915, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { + struct intel_display *display = &i915->display; struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx; const enum intel_dpll_id id = pll->info->id; intel_wakeref_t wakeref; u32 val; - wakeref = intel_display_power_get_if_enabled(i915, + wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_DISPLAY_CORE); if (!wakeref) return false; @@ -540,7 +545,7 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *i915, hw_state->fp0 = intel_de_read(i915, PCH_FP0(id)); hw_state->fp1 = intel_de_read(i915, PCH_FP1(id)); - intel_display_power_put(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); return val & DPLL_VCO_ENABLE; } @@ -747,12 +752,13 @@ static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *i915, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { + struct intel_display *display = &i915->display; struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw; const enum intel_dpll_id id = pll->info->id; intel_wakeref_t wakeref; u32 val; - wakeref = intel_display_power_get_if_enabled(i915, + wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_DISPLAY_CORE); if (!wakeref) return false; @@ -760,7 +766,7 @@ static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *i915, val = intel_de_read(i915, WRPLL_CTL(id)); hw_state->wrpll = val; - intel_display_power_put(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); return val & WRPLL_PLL_ENABLE; } @@ -769,11 +775,12 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *i915, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { + struct intel_display *display = &i915->display; struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw; intel_wakeref_t wakeref; u32 val; - wakeref = intel_display_power_get_if_enabled(i915, + wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_DISPLAY_CORE); if (!wakeref) return false; @@ -781,7 +788,7 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *i915, val = intel_de_read(i915, SPLL_CTL); hw_state->spll = val; - intel_display_power_put(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); return val & SPLL_PLL_ENABLE; } @@ -1425,6 +1432,7 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *i915, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { + struct intel_display *display = &i915->display; struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl; const struct skl_dpll_regs *regs = skl_dpll_regs; const enum intel_dpll_id id = pll->info->id; @@ -1432,7 +1440,7 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *i915, bool ret; u32 val; - wakeref = intel_display_power_get_if_enabled(i915, + wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_DISPLAY_CORE); if (!wakeref) return false; @@ -1454,7 +1462,7 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *i915, ret = true; out: - intel_display_power_put(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); return ret; } @@ -1463,6 +1471,7 @@ static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *i915, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { + struct intel_display *display = &i915->display; struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl; const struct skl_dpll_regs *regs = skl_dpll_regs; const enum intel_dpll_id id = pll->info->id; @@ -1470,7 +1479,7 @@ static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *i915, u32 val; bool ret; - wakeref = intel_display_power_get_if_enabled(i915, + wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_DISPLAY_CORE); if (!wakeref) return false; @@ -1488,7 +1497,7 @@ static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *i915, ret = true; out: - intel_display_power_put(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); return ret; } @@ -2172,7 +2181,7 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *i915, bxt_port_to_phy_channel(display, port, &phy, &ch); - wakeref = intel_display_power_get_if_enabled(i915, + wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_DISPLAY_CORE); if (!wakeref) return false; @@ -2234,7 +2243,7 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *i915, ret = true; out: - intel_display_power_put(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); return ret; } @@ -3541,6 +3550,7 @@ static bool mg_pll_get_hw_state(struct drm_i915_private *i915, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { + struct intel_display *display = &i915->display; struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; const enum intel_dpll_id id = pll->info->id; enum tc_port tc_port = icl_pll_id_to_tc_port(id); @@ -3550,7 +3560,7 @@ static bool mg_pll_get_hw_state(struct drm_i915_private *i915, i915_reg_t enable_reg = intel_tc_pll_enable_reg(i915, pll); - wakeref = intel_display_power_get_if_enabled(i915, + wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_DISPLAY_CORE); if (!wakeref) return false; @@ -3600,7 +3610,7 @@ static bool mg_pll_get_hw_state(struct drm_i915_private *i915, ret = true; out: - intel_display_power_put(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); return ret; } @@ -3608,6 +3618,7 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *i915, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { + struct intel_display *display = &i915->display; struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; const enum intel_dpll_id id = pll->info->id; enum tc_port tc_port = icl_pll_id_to_tc_port(id); @@ -3615,7 +3626,7 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *i915, bool ret = false; u32 val; - wakeref = intel_display_power_get_if_enabled(i915, + wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_DISPLAY_CORE); if (!wakeref) return false; @@ -3672,7 +3683,7 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *i915, ret = true; out: - intel_display_power_put(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); return ret; } @@ -3681,13 +3692,14 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *i915, struct intel_dpll_hw_state *dpll_hw_state, i915_reg_t enable_reg) { + struct intel_display *display = &i915->display; struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; const enum intel_dpll_id id = pll->info->id; intel_wakeref_t wakeref; bool ret = false; u32 val; - wakeref = intel_display_power_get_if_enabled(i915, + wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_DISPLAY_CORE); if (!wakeref) return false; @@ -3733,7 +3745,7 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *i915, ret = true; out: - intel_display_power_put(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); return ret; } @@ -4508,12 +4520,13 @@ bool intel_dpll_get_hw_state(struct drm_i915_private *i915, static void readout_dpll_hw_state(struct drm_i915_private *i915, struct intel_shared_dpll *pll) { + struct intel_display *display = &i915->display; struct intel_crtc *crtc; pll->on = intel_dpll_get_hw_state(i915, pll, &pll->state.hw_state); if (pll->on && pll->info->power_domain) - pll->wakeref = intel_display_power_get(i915, pll->info->power_domain); + pll->wakeref = intel_display_power_get(display, pll->info->power_domain); pll->state.pipe_mask = 0; for_each_intel_crtc(&i915->drm, crtc) { diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c index 807cf606e7a89..abf457e68ee99 100644 --- a/drivers/gpu/drm/i915/display/intel_gmbus.c +++ b/drivers/gpu/drm/i915/display/intel_gmbus.c @@ -761,11 +761,10 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) { struct intel_gmbus *bus = to_intel_gmbus(adapter); struct intel_display *display = bus->display; - struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref; int ret; - wakeref = intel_display_power_get(i915, POWER_DOMAIN_GMBUS); + wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); if (bus->force_bit) { ret = i2c_bit_algo.master_xfer(adapter, msgs, num); @@ -777,7 +776,7 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) bus->force_bit |= GMBUS_FORCE_BIT_RETRY; } - intel_display_power_put(i915, POWER_DOMAIN_GMBUS, wakeref); + intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); return ret; } @@ -786,7 +785,6 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter) { struct intel_gmbus *bus = to_intel_gmbus(adapter); struct intel_display *display = bus->display; - struct drm_i915_private *i915 = to_i915(display->drm); u8 cmd = DRM_HDCP_DDC_AKSV; u8 buf[DRM_HDCP_KSV_LEN] = {}; struct i2c_msg msgs[] = { @@ -806,7 +804,7 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter) intel_wakeref_t wakeref; int ret; - wakeref = intel_display_power_get(i915, POWER_DOMAIN_GMBUS); + wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); mutex_lock(&display->gmbus.mutex); /* @@ -817,7 +815,7 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter) ret = do_gmbus_xfer(adapter, msgs, ARRAY_SIZE(msgs), GMBUS_AKSV_SELECT); mutex_unlock(&display->gmbus.mutex); - intel_display_power_put(i915, POWER_DOMAIN_GMBUS, wakeref); + intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 95584b61cf088..0488999d079c2 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2491,14 +2491,13 @@ static bool intel_hdmi_set_edid(struct drm_connector *connector) { struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)); struct i2c_adapter *ddc = connector->ddc; intel_wakeref_t wakeref; const struct drm_edid *drm_edid; bool connected = false; - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); + wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); drm_edid = drm_edid_read_ddc(connector, ddc); @@ -2521,7 +2520,7 @@ intel_hdmi_set_edid(struct drm_connector *connector) connected = true; } - intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); + intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); cec_notifier_set_phys_addr(intel_hdmi->cec_notifier, connector->display_info.source_physical_address); @@ -2534,7 +2533,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) { struct intel_display *display = to_intel_display(connector->dev); enum drm_connector_status status = connector_status_disconnected; - struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)); struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base; intel_wakeref_t wakeref; @@ -2548,7 +2546,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) if (!intel_display_driver_check_access(display)) return connector->status; - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); + wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); if (DISPLAY_VER(display) >= 11 && !intel_digital_port_connected(encoder)) @@ -2560,7 +2558,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) status = connector_status_connected; out: - intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); + intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); if (status != connector_status_connected) cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier); diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index c0d48f651dabd..d2e0002c5dc38 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -732,6 +732,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) struct drm_i915_private *dev_priv = container_of(work, struct drm_i915_private, display.hotplug.poll_init_work); + struct intel_display *display = &dev_priv->display; struct drm_connector_list_iter conn_iter; struct intel_connector *connector; intel_wakeref_t wakeref; @@ -747,7 +748,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) * and so risk an endless loop of this same sequence. */ if (!enabled) { - wakeref = intel_display_power_get(dev_priv, + wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE); drm_WARN_ON(&dev_priv->drm, READ_ONCE(dev_priv->display.hotplug.poll_enabled)); @@ -789,7 +790,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) if (!enabled) { i915_hpd_poll_detect_connectors(dev_priv); - intel_display_power_put(dev_priv, + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); } diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 6ffd55c174456..761e0c6e6dd93 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -102,18 +102,19 @@ bool intel_lvds_port_enabled(struct drm_i915_private *i915, static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); intel_wakeref_t wakeref; bool ret; - wakeref = intel_display_power_get_if_enabled(i915, encoder->power_domain); + wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); if (!wakeref) return false; ret = intel_lvds_port_enabled(i915, lvds_encoder->reg, pipe); - intel_display_power_put(i915, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 10cdfdad82e4f..69373031c557b 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -177,7 +177,7 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc) intel_fbc_disable(crtc); intel_update_watermarks(i915); - intel_display_power_put_all_in_set(i915, &crtc->enabled_power_domains); + intel_display_power_put_all_in_set(display, &crtc->enabled_power_domains); cdclk_state->min_cdclk[pipe] = 0; cdclk_state->min_voltage_level[pipe] = 0; @@ -969,7 +969,7 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, struct intel_crtc *crtc; intel_wakeref_t wakeref; - wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT); + wakeref = intel_display_power_get(display, POWER_DOMAIN_INIT); intel_early_display_was(i915); intel_modeset_readout_hw_state(i915); @@ -1028,7 +1028,7 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, intel_modeset_put_crtc_power_domains(crtc, &put_domains); } - intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref); + intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref); intel_power_domains_sanitize_state(display); } diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c index 90efc6f64e525..10e26c3db946a 100644 --- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c @@ -582,6 +582,7 @@ int intel_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name, int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name) { struct intel_crtc *crtc = to_intel_crtc(_crtc); + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc; enum intel_display_power_domain power_domain; @@ -598,7 +599,7 @@ int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name) } power_domain = POWER_DOMAIN_PIPE(pipe); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) { drm_dbg_kms(&dev_priv->drm, "Trying to capture CRC while pipe is off\n"); @@ -628,7 +629,7 @@ int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name) if (!enable) intel_crtc_crc_setup_workarounds(crtc, false); - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index c0f65749a3f6a..ef6effaf82e06 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -65,13 +65,12 @@ static const char *pps_name(struct intel_dp *intel_dp) intel_wakeref_t intel_pps_lock(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); intel_wakeref_t wakeref; /* * See vlv_pps_reset_all() why we need a power domain reference here. */ - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE); + wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE); mutex_lock(&display->pps.mutex); return wakeref; @@ -81,10 +80,9 @@ intel_wakeref_t intel_pps_unlock(struct intel_dp *intel_dp, intel_wakeref_t wakeref) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); mutex_unlock(&display->pps.mutex); - intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref); + intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); return NULL; } @@ -741,7 +739,6 @@ static u32 ilk_get_pp_control(struct intel_dp *intel_dp) bool intel_pps_vdd_on_unlocked(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); u32 pp; i915_reg_t pp_stat_reg, pp_ctrl_reg; @@ -759,7 +756,7 @@ bool intel_pps_vdd_on_unlocked(struct intel_dp *intel_dp) return need_to_disable; drm_WARN_ON(display->drm, intel_dp->pps.vdd_wakeref); - intel_dp->pps.vdd_wakeref = intel_display_power_get(dev_priv, + intel_dp->pps.vdd_wakeref = intel_display_power_get(display, intel_aux_power_domain(dig_port)); pp_stat_reg = _pp_stat_reg(intel_dp); @@ -825,7 +822,6 @@ void intel_pps_vdd_on(struct intel_dp *intel_dp) static void intel_pps_vdd_off_sync_unlocked(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); u32 pp; i915_reg_t pp_stat_reg, pp_ctrl_reg; @@ -863,7 +859,7 @@ static void intel_pps_vdd_off_sync_unlocked(struct intel_dp *intel_dp) intel_dp_invalidate_source_oui(intel_dp); } - intel_display_power_put(dev_priv, + intel_display_power_put(display, intel_aux_power_domain(dig_port), fetch_and_zero(&intel_dp->pps.vdd_wakeref)); } @@ -1036,7 +1032,6 @@ void intel_pps_on(struct intel_dp *intel_dp) void intel_pps_off_unlocked(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); u32 pp; i915_reg_t pp_ctrl_reg; @@ -1074,7 +1069,7 @@ void intel_pps_off_unlocked(struct intel_dp *intel_dp) intel_dp_invalidate_source_oui(intel_dp); /* We got a reference when we enabled the VDD. */ - intel_display_power_put(dev_priv, + intel_display_power_put(display, intel_aux_power_domain(dig_port), fetch_and_zero(&intel_dp->pps.vdd_wakeref)); } @@ -1338,7 +1333,6 @@ void vlv_pps_port_disable(struct intel_encoder *encoder, static void pps_vdd_init(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); lockdep_assert_held(&display->pps.mutex); @@ -1357,7 +1351,7 @@ static void pps_vdd_init(struct intel_dp *intel_dp) dig_port->base.base.base.id, dig_port->base.base.name, pps_name(intel_dp)); drm_WARN_ON(display->drm, intel_dp->pps.vdd_wakeref); - intel_dp->pps.vdd_wakeref = intel_display_power_get(dev_priv, + intel_dp->pps.vdd_wakeref = intel_display_power_get(display, intel_aux_power_domain(dig_port)); } diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index ee7839eb4099d..d1b4b20af4a04 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -452,15 +452,14 @@ static bool vlv_sprite_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum intel_display_power_domain power_domain; enum plane_id plane_id = plane->id; intel_wakeref_t wakeref; bool ret; power_domain = POWER_DOMAIN_PIPE(plane->pipe); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; @@ -468,7 +467,7 @@ vlv_sprite_get_hw_state(struct intel_plane *plane, *pipe = plane->pipe; - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } @@ -884,13 +883,12 @@ ivb_sprite_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; bool ret; power_domain = POWER_DOMAIN_PIPE(plane->pipe); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; @@ -898,7 +896,7 @@ ivb_sprite_get_hw_state(struct intel_plane *plane, *pipe = plane->pipe; - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } @@ -1222,13 +1220,12 @@ g4x_sprite_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; bool ret; power_domain = POWER_DOMAIN_PIPE(plane->pipe); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; @@ -1236,7 +1233,7 @@ g4x_sprite_get_hw_state(struct intel_plane *plane, *pipe = plane->pipe; - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 13811244c82bb..e9e9ee5d345a2 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -187,11 +187,11 @@ bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port) static intel_wakeref_t __tc_cold_block(struct intel_tc_port *tc, enum intel_display_power_domain *domain) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); *domain = tc_phy_cold_off_domain(tc); - return intel_display_power_get(i915, *domain); + return intel_display_power_get(display, *domain); } static intel_wakeref_t @@ -211,9 +211,9 @@ static void __tc_cold_unblock(struct intel_tc_port *tc, enum intel_display_power_domain domain, intel_wakeref_t wakeref) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); - intel_display_power_put(i915, domain, wakeref); + intel_display_power_put(display, domain, wakeref); } static void @@ -230,21 +230,21 @@ tc_cold_unblock(struct intel_tc_port *tc, intel_wakeref_t wakeref) static void assert_display_core_power_enabled(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); - drm_WARN_ON(&i915->drm, - !intel_display_power_is_enabled(i915, POWER_DOMAIN_DISPLAY_CORE)); + drm_WARN_ON(display->drm, + !intel_display_power_is_enabled(display, POWER_DOMAIN_DISPLAY_CORE)); } static void assert_tc_cold_blocked(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); bool enabled; - enabled = intel_display_power_is_enabled(i915, + enabled = intel_display_power_is_enabled(display, tc_phy_cold_off_domain(tc)); - drm_WARN_ON(&i915->drm, !enabled); + drm_WARN_ON(display->drm, !enabled); } static enum intel_display_power_domain @@ -258,10 +258,10 @@ tc_port_power_domain(struct intel_tc_port *tc) static void assert_tc_port_power_enabled(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); - drm_WARN_ON(&i915->drm, - !intel_display_power_is_enabled(i915, tc_port_power_domain(tc))); + drm_WARN_ON(display->drm, + !intel_display_power_is_enabled(display, tc_port_power_domain(tc))); } static u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port) @@ -296,12 +296,13 @@ u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port) static int lnl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port) { + struct intel_display *display = to_intel_display(dig_port); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum tc_port tc_port = intel_encoder_to_tc(&dig_port->base); intel_wakeref_t wakeref; u32 val, pin_assignment; - with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref) + with_intel_display_power(display, POWER_DOMAIN_DISPLAY_CORE, wakeref) val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); pin_assignment = @@ -321,11 +322,11 @@ static int lnl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port) static int mtl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); intel_wakeref_t wakeref; u32 pin_mask; - with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref) + with_intel_display_power(display, POWER_DOMAIN_DISPLAY_CORE, wakeref) pin_mask = intel_tc_port_get_pin_assignment_mask(dig_port); switch (pin_mask) { @@ -342,11 +343,11 @@ static int mtl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port) static int intel_tc_port_get_max_lane_count(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); intel_wakeref_t wakeref; u32 lane_mask = 0; - with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref) + with_intel_display_power(display, POWER_DOMAIN_DISPLAY_CORE, wakeref) lane_mask = intel_tc_port_get_lane_mask(dig_port); switch (lane_mask) { @@ -488,6 +489,7 @@ icl_tc_phy_cold_off_domain(struct intel_tc_port *tc) static u32 icl_tc_phy_hpd_live_status(struct intel_tc_port *tc) { + struct intel_display *display = to_intel_display(tc->dig_port); struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; @@ -496,7 +498,7 @@ static u32 icl_tc_phy_hpd_live_status(struct intel_tc_port *tc) u32 pch_isr; u32 mask = 0; - with_intel_display_power(i915, tc_phy_cold_off_domain(tc), wakeref) { + with_intel_display_power(display, tc_phy_cold_off_domain(tc), wakeref) { fia_isr = intel_de_read(i915, PORT_TX_DFLEXDPSP(tc->phy_fia)); pch_isr = intel_de_read(i915, SDEISR); } @@ -730,11 +732,12 @@ tgl_tc_phy_cold_off_domain(struct intel_tc_port *tc) static void tgl_tc_phy_init(struct intel_tc_port *tc) { + struct intel_display *display = to_intel_display(tc->dig_port); struct drm_i915_private *i915 = tc_to_i915(tc); intel_wakeref_t wakeref; u32 val; - with_intel_display_power(i915, tc_phy_cold_off_domain(tc), wakeref) + with_intel_display_power(display, tc_phy_cold_off_domain(tc), wakeref) val = intel_de_read(i915, PORT_TX_DFLEXDPSP(FIA1)); drm_WARN_ON(&i915->drm, val == 0xffffffff); @@ -771,6 +774,7 @@ adlp_tc_phy_cold_off_domain(struct intel_tc_port *tc) static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) { + struct intel_display *display = to_intel_display(tc->dig_port); struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; enum hpd_pin hpd_pin = dig_port->base.hpd_pin; @@ -781,7 +785,7 @@ static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) u32 pch_isr; u32 mask = 0; - with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref) { + with_intel_display_power(display, POWER_DOMAIN_DISPLAY_CORE, wakeref) { cpu_isr = intel_de_read(i915, GEN11_DE_HPD_ISR); pch_isr = intel_de_read(i915, SDEISR); } @@ -851,22 +855,23 @@ static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) static void adlp_tc_phy_get_hw_state(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); enum intel_display_power_domain port_power_domain = tc_port_power_domain(tc); intel_wakeref_t port_wakeref; - port_wakeref = intel_display_power_get(i915, port_power_domain); + port_wakeref = intel_display_power_get(display, port_power_domain); tc->mode = tc_phy_get_current_mode(tc); if (tc->mode != TC_PORT_DISCONNECTED) tc->lock_wakeref = tc_cold_block(tc); - intel_display_power_put(i915, port_power_domain, port_wakeref); + intel_display_power_put(display, port_power_domain, port_wakeref); } static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) { + struct intel_display *display = to_intel_display(tc->dig_port); struct drm_i915_private *i915 = tc_to_i915(tc); enum intel_display_power_domain port_power_domain = tc_port_power_domain(tc); @@ -877,7 +882,7 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) return true; } - port_wakeref = intel_display_power_get(i915, port_power_domain); + port_wakeref = intel_display_power_get(display, port_power_domain); if (!adlp_tc_phy_take_ownership(tc, true) && !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { @@ -898,7 +903,7 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) goto out_unblock_tc_cold; - intel_display_power_put(i915, port_power_domain, port_wakeref); + intel_display_power_put(display, port_power_domain, port_wakeref); return true; @@ -907,19 +912,19 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) out_release_phy: adlp_tc_phy_take_ownership(tc, false); out_put_port_power: - intel_display_power_put(i915, port_power_domain, port_wakeref); + intel_display_power_put(display, port_power_domain, port_wakeref); return false; } static void adlp_tc_phy_disconnect(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); enum intel_display_power_domain port_power_domain = tc_port_power_domain(tc); intel_wakeref_t port_wakeref; - port_wakeref = intel_display_power_get(i915, port_power_domain); + port_wakeref = intel_display_power_get(display, port_power_domain); tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); @@ -934,7 +939,7 @@ static void adlp_tc_phy_disconnect(struct intel_tc_port *tc) MISSING_CASE(tc->mode); } - intel_display_power_put(i915, port_power_domain, port_wakeref); + intel_display_power_put(display, port_power_domain, port_wakeref); } static void adlp_tc_phy_init(struct intel_tc_port *tc) @@ -959,6 +964,7 @@ static const struct intel_tc_phy_ops adlp_tc_phy_ops = { */ static u32 xelpdp_tc_phy_hpd_live_status(struct intel_tc_port *tc) { + struct intel_display *display = to_intel_display(tc->dig_port); struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; enum hpd_pin hpd_pin = dig_port->base.hpd_pin; @@ -969,7 +975,7 @@ static u32 xelpdp_tc_phy_hpd_live_status(struct intel_tc_port *tc) u32 pch_isr; u32 mask = 0; - with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref) { + with_intel_display_power(display, POWER_DOMAIN_DISPLAY_CORE, wakeref) { pica_isr = intel_de_read(i915, PICAINTERRUPT_ISR); pch_isr = intel_de_read(i915, SDEISR); } @@ -1436,25 +1442,25 @@ static void tc_phy_init(struct intel_tc_port *tc) static void intel_tc_port_reset_mode(struct intel_tc_port *tc, int required_lanes, bool force_disconnect) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); struct intel_digital_port *dig_port = tc->dig_port; enum tc_port_mode old_tc_mode = tc->mode; - intel_display_power_flush_work(i915); + intel_display_power_flush_work(display); if (!intel_tc_cold_requires_aux_pw(dig_port)) { enum intel_display_power_domain aux_domain; bool aux_powered; aux_domain = intel_aux_power_domain(dig_port); - aux_powered = intel_display_power_is_enabled(i915, aux_domain); - drm_WARN_ON(&i915->drm, aux_powered); + aux_powered = intel_display_power_is_enabled(display, aux_domain); + drm_WARN_ON(display->drm, aux_powered); } tc_phy_disconnect(tc); if (!force_disconnect) tc_phy_connect(tc, required_lanes); - drm_dbg_kms(&i915->drm, "Port %s: TC port mode reset (%s -> %s)\n", + drm_dbg_kms(display->drm, "Port %s: TC port mode reset (%s -> %s)\n", tc->port_name, tc_port_mode_name(old_tc_mode), tc_port_mode_name(tc->mode)); diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 932435a7f88d6..6e7151346382d 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -962,6 +962,7 @@ static void intel_dsc_get_pps_config(struct intel_crtc_state *crtc_state) void intel_dsc_get_config(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; @@ -974,7 +975,7 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) power_domain = intel_dsc_power_domain(crtc, cpu_transcoder); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return; @@ -994,7 +995,7 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) intel_dsc_get_pps_config(crtc_state); out: - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); } static void intel_vdsc_dump_state(struct drm_printer *p, int indent, diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c index fd18dd07ae491..684b5d1bc87c1 100644 --- a/drivers/gpu/drm/i915/display/intel_vga.c +++ b/drivers/gpu/drm/i915/display/intel_vga.c @@ -59,7 +59,6 @@ void intel_vga_redisable_power_on(struct intel_display *display) void intel_vga_redisable(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref; /* @@ -71,13 +70,13 @@ void intel_vga_redisable(struct intel_display *display) * follow the "don't touch the power well if we don't need it" policy * the rest of the driver uses. */ - wakeref = intel_display_power_get_if_enabled(i915, POWER_DOMAIN_VGA); + wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_VGA); if (!wakeref) return; intel_vga_redisable_power_on(display); - intel_display_power_put(i915, POWER_DOMAIN_VGA, wakeref); + intel_display_power_put(display, POWER_DOMAIN_VGA, wakeref); } void intel_vga_reset_io_mem(struct intel_display *display) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index a871450150d93..3a60d6d49662b 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -922,6 +922,7 @@ static bool skl_plane_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum intel_display_power_domain power_domain; enum plane_id plane_id = plane->id; @@ -929,7 +930,7 @@ skl_plane_get_hw_state(struct intel_plane *plane, bool ret; power_domain = POWER_DOMAIN_PIPE(plane->pipe); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; @@ -937,7 +938,7 @@ skl_plane_get_hw_state(struct intel_plane *plane, *pipe = plane->pipe; - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 45fe4aaeb450e..1c4510d520e81 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -836,6 +836,7 @@ static void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, struct skl_ddb_entry *ddb_y, u16 *min_ddb, u16 *interim_ddb) { + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; @@ -843,7 +844,7 @@ static void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, enum plane_id plane_id; power_domain = POWER_DOMAIN_PIPE(pipe); - wakeref = intel_display_power_get_if_enabled(i915, power_domain); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return; @@ -855,7 +856,7 @@ static void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, &min_ddb[plane_id], &interim_ddb[plane_id]); - intel_display_power_put(i915, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); } struct dbuf_slice_conf_entry { diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index 0333c4d9b7030..bdbc7e95fcfa0 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -947,7 +947,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, drm_dbg_kms(display->drm, "\n"); - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); if (!wakeref) return false; @@ -1007,7 +1007,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, } out_put_power: - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); return active; } diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c index c08fdb65cc699..175fa2db05517 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c @@ -70,6 +70,7 @@ static int __gt_unpark(struct intel_wakeref *wf) { struct intel_gt *gt = container_of(wf, typeof(*gt), wakeref); struct drm_i915_private *i915 = gt->i915; + struct intel_display *display = &i915->display; GT_TRACE(gt, "\n"); @@ -84,7 +85,7 @@ static int __gt_unpark(struct intel_wakeref *wf) * Work around it by grabbing a GT IRQ power domain whilst there is any * GT activity, preventing any DC state transitions. */ - gt->awake = intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ); + gt->awake = intel_display_power_get(display, POWER_DOMAIN_GT_IRQ); GEM_BUG_ON(!gt->awake); intel_rc6_unpark(>->rc6); @@ -103,6 +104,7 @@ static int __gt_park(struct intel_wakeref *wf) struct intel_gt *gt = container_of(wf, typeof(*gt), wakeref); intel_wakeref_t wakeref = fetch_and_zero(>->awake); struct drm_i915_private *i915 = gt->i915; + struct intel_display *display = &i915->display; GT_TRACE(gt, "\n"); @@ -120,7 +122,7 @@ static int __gt_park(struct intel_wakeref *wf) /* Defer dropping the display power well for 100ms, it's slow! */ GEM_BUG_ON(!wakeref); - intel_display_power_put_async(i915, POWER_DOMAIN_GT_IRQ, wakeref); + intel_display_power_put_async(display, POWER_DOMAIN_GT_IRQ, wakeref); return 0; } From 880ed2d84db9a1d6c1f6c4dcd52b1cacf3eb7a69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:28 +0200 Subject: [PATCH 184/284] drm/i915: Convert i9xx_plane.c to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct intel_display will replace struct drm_i915_private as the main thing for display code. Convert the pre-skl primary plane code to use it. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-8-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/i9xx_plane.c | 240 +++++++++++----------- drivers/gpu/drm/i915/display/i9xx_plane.h | 6 +- drivers/gpu/drm/i915/display/intel_crtc.c | 2 +- 3 files changed, 122 insertions(+), 126 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 72699944768e8..c3ed903d55824 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -109,42 +109,42 @@ static bool i965_plane_format_mod_supported(struct drm_plane *_plane, } } -static bool i9xx_plane_has_fbc(struct drm_i915_private *dev_priv, +static bool i9xx_plane_has_fbc(struct intel_display *display, enum i9xx_plane_id i9xx_plane) { - if (!HAS_FBC(dev_priv)) + if (!HAS_FBC(display)) return false; - if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) + if (display->platform.broadwell || display->platform.haswell) return i9xx_plane == PLANE_A; /* tied to pipe A */ - else if (IS_IVYBRIDGE(dev_priv)) + else if (display->platform.ivybridge) return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B || i9xx_plane == PLANE_C; - else if (DISPLAY_VER(dev_priv) >= 4) + else if (DISPLAY_VER(display) >= 4) return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B; else return i9xx_plane == PLANE_A; } -static struct intel_fbc *i9xx_plane_fbc(struct drm_i915_private *dev_priv, +static struct intel_fbc *i9xx_plane_fbc(struct intel_display *display, enum i9xx_plane_id i9xx_plane) { - if (i9xx_plane_has_fbc(dev_priv, i9xx_plane)) - return dev_priv->display.fbc[INTEL_FBC_A]; + if (i9xx_plane_has_fbc(display, i9xx_plane)) + return display->fbc[INTEL_FBC_A]; else return NULL; } static bool i9xx_plane_has_windowing(struct intel_plane *plane) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) return i9xx_plane == PLANE_B; - else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) + else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) return false; - else if (DISPLAY_VER(dev_priv) == 4) + else if (DISPLAY_VER(display) == 4) return i9xx_plane == PLANE_C; else return i9xx_plane == PLANE_B || @@ -154,16 +154,15 @@ static bool i9xx_plane_has_windowing(struct intel_plane *plane) static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; u32 dspcntr; dspcntr = DISP_ENABLE; - if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) || - IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) + if (display->platform.g4x || display->platform.ironlake || + display->platform.sandybridge || display->platform.ivybridge) dspcntr |= DISP_TRICKLE_FEED_DISABLE; switch (fb->format->format) { @@ -211,7 +210,7 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, return 0; } - if (DISPLAY_VER(dev_priv) >= 4 && + if (DISPLAY_VER(display) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) dspcntr |= DISP_TILED; @@ -226,8 +225,8 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, int i9xx_check_plane_surface(struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; int src_x, src_y, src_w; u32 offset; @@ -245,12 +244,12 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) src_y = plane_state->uapi.src.y1 >> 16; /* Undocumented hardware limit on i965/g4x/vlv/chv */ - if (HAS_GMCH(dev_priv) && fb->format->cpp[0] == 8 && src_w > 2048) + if (HAS_GMCH(display) && fb->format->cpp[0] == 8 && src_w > 2048) return -EINVAL; intel_add_fb_offsets(&src_x, &src_y, plane_state, 0); - if (DISPLAY_VER(dev_priv) >= 4) + if (DISPLAY_VER(display) >= 4) offset = intel_plane_compute_aligned_offset(&src_x, &src_y, plane_state, 0); else @@ -267,13 +266,13 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) * Linear surfaces seem to work just fine, even on hsw/bdw * despite them not using the linear offset anymore. */ - if (DISPLAY_VER(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) { + if (DISPLAY_VER(display) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) { unsigned int alignment = plane->min_alignment(plane, fb, 0); int cpp = fb->format->cpp[0]; while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].mapping_stride) { if (offset == 0) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Unable to find suitable display surface offset due to X-tiling\n"); return -EINVAL; } @@ -291,7 +290,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) src_x << 16, src_y << 16); /* HSW/BDW do this automagically in hardware */ - if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) { + if (!display->platform.haswell && !display->platform.broadwell) { unsigned int rotation = plane_state->hw.rotation; int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; int src_h = drm_rect_height(&plane_state->uapi.src) >> 16; @@ -304,11 +303,11 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) } } - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { - drm_WARN_ON(&dev_priv->drm, src_x > 8191 || src_y > 4095); - } else if (DISPLAY_VER(dev_priv) >= 4 && + if (display->platform.haswell || display->platform.broadwell) { + drm_WARN_ON(display->drm, src_x > 8191 || src_y > 4095); + } else if (DISPLAY_VER(display) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) { - drm_WARN_ON(&dev_priv->drm, src_x > 4095 || src_y > 4095); + drm_WARN_ON(display->drm, src_x > 4095 || src_y > 4095); } plane_state->view.color_plane[0].offset = offset; @@ -354,8 +353,8 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state, static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 dspcntr = 0; if (crtc_state->gamma_enable) @@ -364,7 +363,7 @@ static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state) if (crtc_state->csc_enable) dspcntr |= DISP_PIPE_CSC_ENABLE; - if (DISPLAY_VER(dev_priv) < 5) + if (DISPLAY_VER(display) < 5) dspcntr |= DISP_PIPE_SEL(crtc->pipe); return dspcntr; @@ -422,13 +421,13 @@ static void i9xx_plane_update_noarm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; - intel_de_write_fw(dev_priv, DSPSTRIDE(dev_priv, i9xx_plane), + intel_de_write_fw(display, DSPSTRIDE(display, i9xx_plane), plane_state->view.color_plane[0].mapping_stride); - if (DISPLAY_VER(dev_priv) < 4) { + if (DISPLAY_VER(display) < 4) { int crtc_x = plane_state->uapi.dst.x1; int crtc_y = plane_state->uapi.dst.y1; int crtc_w = drm_rect_width(&plane_state->uapi.dst); @@ -439,9 +438,9 @@ static void i9xx_plane_update_noarm(struct intel_dsb *dsb, * generator but let's assume we still need to * program whatever is there. */ - intel_de_write_fw(dev_priv, DSPPOS(dev_priv, i9xx_plane), + intel_de_write_fw(display, DSPPOS(display, i9xx_plane), DISP_POS_Y(crtc_y) | DISP_POS_X(crtc_x)); - intel_de_write_fw(dev_priv, DSPSIZE(dev_priv, i9xx_plane), + intel_de_write_fw(display, DSPSIZE(display, i9xx_plane), DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1)); } } @@ -451,7 +450,7 @@ static void i9xx_plane_update_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; int x = plane_state->view.color_plane[0].x; int y = plane_state->view.color_plane[0].y; @@ -466,32 +465,32 @@ static void i9xx_plane_update_arm(struct intel_dsb *dsb, linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); - if (DISPLAY_VER(dev_priv) >= 4) + if (DISPLAY_VER(display) >= 4) dspaddr_offset = plane_state->view.color_plane[0].offset; else dspaddr_offset = linear_offset; - if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) { + if (display->platform.cherryview && i9xx_plane == PLANE_B) { int crtc_x = plane_state->uapi.dst.x1; int crtc_y = plane_state->uapi.dst.y1; int crtc_w = drm_rect_width(&plane_state->uapi.dst); int crtc_h = drm_rect_height(&plane_state->uapi.dst); - intel_de_write_fw(dev_priv, PRIMPOS(dev_priv, i9xx_plane), + intel_de_write_fw(display, PRIMPOS(display, i9xx_plane), PRIM_POS_Y(crtc_y) | PRIM_POS_X(crtc_x)); - intel_de_write_fw(dev_priv, PRIMSIZE(dev_priv, i9xx_plane), + intel_de_write_fw(display, PRIMSIZE(display, i9xx_plane), PRIM_HEIGHT(crtc_h - 1) | PRIM_WIDTH(crtc_w - 1)); - intel_de_write_fw(dev_priv, - PRIMCNSTALPHA(dev_priv, i9xx_plane), 0); + intel_de_write_fw(display, + PRIMCNSTALPHA(display, i9xx_plane), 0); } - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { - intel_de_write_fw(dev_priv, DSPOFFSET(dev_priv, i9xx_plane), + if (display->platform.haswell || display->platform.broadwell) { + intel_de_write_fw(display, DSPOFFSET(display, i9xx_plane), DISP_OFFSET_Y(y) | DISP_OFFSET_X(x)); - } else if (DISPLAY_VER(dev_priv) >= 4) { - intel_de_write_fw(dev_priv, DSPLINOFF(dev_priv, i9xx_plane), + } else if (DISPLAY_VER(display) >= 4) { + intel_de_write_fw(display, DSPLINOFF(display, i9xx_plane), linear_offset); - intel_de_write_fw(dev_priv, DSPTILEOFF(dev_priv, i9xx_plane), + intel_de_write_fw(display, DSPTILEOFF(display, i9xx_plane), DISP_OFFSET_Y(y) | DISP_OFFSET_X(x)); } @@ -500,13 +499,13 @@ static void i9xx_plane_update_arm(struct intel_dsb *dsb, * disabled. Try to make the plane enable atomic by writing * the control register just before the surface register. */ - intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr); + intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr); - if (DISPLAY_VER(dev_priv) >= 4) - intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), + if (DISPLAY_VER(display) >= 4) + intel_de_write_fw(display, DSPSURF(display, i9xx_plane), intel_plane_ggtt_offset(plane_state) + dspaddr_offset); else - intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane), + intel_de_write_fw(display, DSPADDR(display, i9xx_plane), intel_plane_ggtt_offset(plane_state) + dspaddr_offset); } @@ -529,7 +528,7 @@ static void i9xx_plane_disable_arm(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; u32 dspcntr; @@ -545,12 +544,12 @@ static void i9xx_plane_disable_arm(struct intel_dsb *dsb, */ dspcntr = i9xx_plane_ctl_crtc(crtc_state); - intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr); + intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr); - if (DISPLAY_VER(dev_priv) >= 4) - intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), 0); + if (DISPLAY_VER(display) >= 4) + intel_de_write_fw(display, DSPSURF(display, i9xx_plane), 0); else - intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane), 0); + intel_de_write_fw(display, DSPADDR(display, i9xx_plane), 0); } static void @@ -560,7 +559,7 @@ g4x_primary_async_flip(struct intel_dsb *dsb, const struct intel_plane_state *plane_state, bool async_flip) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); u32 dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state); u32 dspaddr_offset = plane_state->view.color_plane[0].offset; enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; @@ -568,9 +567,9 @@ g4x_primary_async_flip(struct intel_dsb *dsb, if (async_flip) dspcntr |= DISP_ASYNC_FLIP; - intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr); + intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr); - intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), + intel_de_write_fw(display, DSPSURF(display, i9xx_plane), intel_plane_ggtt_offset(plane_state) + dspaddr_offset); } @@ -581,11 +580,11 @@ vlv_primary_async_flip(struct intel_dsb *dsb, const struct intel_plane_state *plane_state, bool async_flip) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); u32 dspaddr_offset = plane_state->view.color_plane[0].offset; enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; - intel_de_write_fw(dev_priv, DSPADDR_VLV(dev_priv, i9xx_plane), + intel_de_write_fw(display, DSPADDR_VLV(display, i9xx_plane), intel_plane_ggtt_offset(plane_state) + dspaddr_offset); } @@ -682,7 +681,6 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum intel_display_power_domain power_domain; enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; intel_wakeref_t wakeref; @@ -699,11 +697,11 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane, if (!wakeref) return false; - val = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane)); + val = intel_de_read(display, DSPCNTR(display, i9xx_plane)); ret = val & DISP_ENABLE; - if (DISPLAY_VER(dev_priv) >= 5) + if (DISPLAY_VER(display) >= 5) *pipe = plane->pipe; else *pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val); @@ -864,9 +862,8 @@ static const struct drm_plane_funcs i8xx_plane_funcs = { }; struct intel_plane * -intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) +intel_primary_plane_create(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; struct intel_plane *plane; const struct drm_plane_funcs *plane_funcs; unsigned int supported_rotations; @@ -884,20 +881,20 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS * port is hooked to pipe B. Hence we want plane A feeding pipe B. */ - if (HAS_FBC(dev_priv) && DISPLAY_VER(dev_priv) < 4 && - INTEL_NUM_PIPES(dev_priv) == 2) + if (HAS_FBC(display) && DISPLAY_VER(display) < 4 && + INTEL_NUM_PIPES(display) == 2) plane->i9xx_plane = (enum i9xx_plane_id) !pipe; else plane->i9xx_plane = (enum i9xx_plane_id) pipe; plane->id = PLANE_PRIMARY; plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id); - intel_fbc_add_plane(i9xx_plane_fbc(dev_priv, plane->i9xx_plane), plane); + intel_fbc_add_plane(i9xx_plane_fbc(display, plane->i9xx_plane), plane); - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (display->platform.valleyview || display->platform.cherryview) { formats = vlv_primary_formats; num_formats = ARRAY_SIZE(vlv_primary_formats); - } else if (DISPLAY_VER(dev_priv) >= 4) { + } else if (DISPLAY_VER(display) >= 4) { /* * WaFP16GammaEnabling:ivb * "Workaround : When using the 64-bit format, the plane @@ -911,7 +908,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) * planes, so we choose not to expose fp16 on IVB primary * planes. HSW primary planes no longer have this problem. */ - if (IS_IVYBRIDGE(dev_priv)) { + if (display->platform.ivybridge) { formats = ivb_primary_formats; num_formats = ARRAY_SIZE(ivb_primary_formats); } else { @@ -923,39 +920,39 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) num_formats = ARRAY_SIZE(i8xx_primary_formats); } - if (DISPLAY_VER(dev_priv) >= 4) + if (DISPLAY_VER(display) >= 4) plane_funcs = &i965_plane_funcs; else plane_funcs = &i8xx_plane_funcs; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (display->platform.valleyview || display->platform.cherryview) plane->min_cdclk = vlv_plane_min_cdclk; - else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) + else if (display->platform.broadwell || display->platform.haswell) plane->min_cdclk = hsw_plane_min_cdclk; - else if (IS_IVYBRIDGE(dev_priv)) + else if (display->platform.ivybridge) plane->min_cdclk = ivb_plane_min_cdclk; else plane->min_cdclk = i9xx_plane_min_cdclk; - if (HAS_GMCH(dev_priv)) { - if (DISPLAY_VER(dev_priv) >= 4) + if (HAS_GMCH(display)) { + if (DISPLAY_VER(display) >= 4) plane->max_stride = i965_plane_max_stride; - else if (DISPLAY_VER(dev_priv) == 3) + else if (DISPLAY_VER(display) == 3) plane->max_stride = i915_plane_max_stride; else plane->max_stride = i8xx_plane_max_stride; } else { - if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) + if (display->platform.broadwell || display->platform.haswell) plane->max_stride = hsw_primary_max_stride; else plane->max_stride = ilk_primary_max_stride; } - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (display->platform.valleyview || display->platform.cherryview) plane->min_alignment = vlv_plane_min_alignment; - else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) + else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) plane->min_alignment = g4x_primary_min_alignment; - else if (DISPLAY_VER(dev_priv) == 4) + else if (DISPLAY_VER(display) == 4) plane->min_alignment = i965_plane_min_alignment; else plane->min_alignment = i9xx_plane_min_alignment; @@ -964,7 +961,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) if (intel_scanout_needs_vtd_wa(display)) plane->vtd_guard = 128; - if (IS_I830(dev_priv) || IS_I845G(dev_priv)) { + if (display->platform.i830 || display->platform.i845g) { plane->update_arm = i830_plane_update_arm; } else { plane->update_noarm = i9xx_plane_update_noarm; @@ -974,24 +971,24 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) plane->get_hw_state = i9xx_plane_get_hw_state; plane->check_plane = i9xx_plane_check; - if (HAS_ASYNC_FLIPS(dev_priv)) { - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (HAS_ASYNC_FLIPS(display)) { + if (display->platform.valleyview || display->platform.cherryview) { plane->async_flip = vlv_primary_async_flip; plane->enable_flip_done = vlv_primary_enable_flip_done; plane->disable_flip_done = vlv_primary_disable_flip_done; plane->can_async_flip = i9xx_plane_can_async_flip; - } else if (IS_BROADWELL(dev_priv)) { + } else if (display->platform.broadwell) { plane->need_async_flip_toggle_wa = true; plane->async_flip = g4x_primary_async_flip; plane->enable_flip_done = bdw_primary_enable_flip_done; plane->disable_flip_done = bdw_primary_disable_flip_done; plane->can_async_flip = i9xx_plane_can_async_flip; - } else if (DISPLAY_VER(dev_priv) >= 7) { + } else if (DISPLAY_VER(display) >= 7) { plane->async_flip = g4x_primary_async_flip; plane->enable_flip_done = ivb_primary_enable_flip_done; plane->disable_flip_done = ivb_primary_disable_flip_done; plane->can_async_flip = i9xx_plane_can_async_flip; - } else if (DISPLAY_VER(dev_priv) >= 5) { + } else if (DISPLAY_VER(display) >= 5) { plane->async_flip = g4x_primary_async_flip; plane->enable_flip_done = ilk_primary_enable_flip_done; plane->disable_flip_done = ilk_primary_disable_flip_done; @@ -1001,15 +998,15 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X); - if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) - ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, + if (DISPLAY_VER(display) >= 5 || display->platform.g4x) + ret = drm_universal_plane_init(display->drm, &plane->base, 0, plane_funcs, formats, num_formats, modifiers, DRM_PLANE_TYPE_PRIMARY, "primary %c", pipe_name(pipe)); else - ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, + ret = drm_universal_plane_init(display->drm, &plane->base, 0, plane_funcs, formats, num_formats, modifiers, @@ -1022,18 +1019,18 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) if (ret) goto fail; - if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { + if (display->platform.cherryview && pipe == PIPE_B) { supported_rotations = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | DRM_MODE_REFLECT_X; - } else if (DISPLAY_VER(dev_priv) >= 4) { + } else if (DISPLAY_VER(display) >= 4) { supported_rotations = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; } else { supported_rotations = DRM_MODE_ROTATE_0; } - if (DISPLAY_VER(dev_priv) >= 4) + if (DISPLAY_VER(display) >= 4) drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0, supported_rotations); @@ -1088,8 +1085,7 @@ void i9xx_get_initial_plane_config(struct intel_crtc *crtc, struct intel_initial_plane_config *plane_config) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(crtc); struct intel_plane *plane = to_intel_plane(crtc->base.primary); enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; enum pipe pipe; @@ -1102,21 +1098,21 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, if (!plane->get_hw_state(plane, &pipe)) return; - drm_WARN_ON(dev, pipe != crtc->pipe); + drm_WARN_ON(display->drm, pipe != crtc->pipe); intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); if (!intel_fb) { - drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n"); + drm_dbg_kms(display->drm, "failed to alloc fb\n"); return; } fb = &intel_fb->base; - fb->dev = dev; + fb->dev = display->drm; - val = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane)); + val = intel_de_read(display, DSPCNTR(display, i9xx_plane)); - if (DISPLAY_VER(dev_priv) >= 4) { + if (DISPLAY_VER(display) >= 4) { if (val & DISP_TILED) { plane_config->tiling = I915_TILING_X; fb->modifier = I915_FORMAT_MOD_X_TILED; @@ -1126,46 +1122,46 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, plane_config->rotation = DRM_MODE_ROTATE_180; } - if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B && - val & DISP_MIRROR) + if (display->platform.cherryview && + pipe == PIPE_B && val & DISP_MIRROR) plane_config->rotation |= DRM_MODE_REFLECT_X; pixel_format = val & DISP_FORMAT_MASK; fourcc = i9xx_format_to_fourcc(pixel_format); fb->format = drm_format_info(fourcc); - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { - offset = intel_de_read(dev_priv, - DSPOFFSET(dev_priv, i9xx_plane)); - base = intel_de_read(dev_priv, DSPSURF(dev_priv, i9xx_plane)) & DISP_ADDR_MASK; - } else if (DISPLAY_VER(dev_priv) >= 4) { + if (display->platform.haswell || display->platform.broadwell) { + offset = intel_de_read(display, + DSPOFFSET(display, i9xx_plane)); + base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK; + } else if (DISPLAY_VER(display) >= 4) { if (plane_config->tiling) - offset = intel_de_read(dev_priv, - DSPTILEOFF(dev_priv, i9xx_plane)); + offset = intel_de_read(display, + DSPTILEOFF(display, i9xx_plane)); else - offset = intel_de_read(dev_priv, - DSPLINOFF(dev_priv, i9xx_plane)); - base = intel_de_read(dev_priv, DSPSURF(dev_priv, i9xx_plane)) & DISP_ADDR_MASK; + offset = intel_de_read(display, + DSPLINOFF(display, i9xx_plane)); + base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK; } else { offset = 0; - base = intel_de_read(dev_priv, DSPADDR(dev_priv, i9xx_plane)); + base = intel_de_read(display, DSPADDR(display, i9xx_plane)); } plane_config->base = base; - drm_WARN_ON(&dev_priv->drm, offset != 0); + drm_WARN_ON(display->drm, offset != 0); - val = intel_de_read(dev_priv, PIPESRC(dev_priv, pipe)); + val = intel_de_read(display, PIPESRC(display, pipe)); fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1; fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1; - val = intel_de_read(dev_priv, DSPSTRIDE(dev_priv, i9xx_plane)); + val = intel_de_read(display, DSPSTRIDE(display, i9xx_plane)); fb->pitches[0] = val & 0xffffffc0; aligned_height = intel_fb_align_height(fb, 0, fb->height); plane_config->size = fb->pitches[0] * aligned_height; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", crtc->base.name, plane->base.name, fb->width, fb->height, fb->format->cpp[0] * 8, base, fb->pitches[0], @@ -1177,7 +1173,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc, const struct intel_initial_plane_config *plane_config) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_plane *plane = to_intel_plane(crtc->base.primary); const struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); @@ -1196,10 +1192,10 @@ bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc, if (plane_config->base == base) return false; - if (DISPLAY_VER(dev_priv) >= 4) - intel_de_write(dev_priv, DSPSURF(dev_priv, i9xx_plane), base); + if (DISPLAY_VER(display) >= 4) + intel_de_write(display, DSPSURF(display, i9xx_plane), base); else - intel_de_write(dev_priv, DSPADDR(dev_priv, i9xx_plane), base); + intel_de_write(display, DSPADDR(display, i9xx_plane), base); return true; } diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.h b/drivers/gpu/drm/i915/display/i9xx_plane.h index 457f4bccf1062..d90546d608559 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.h +++ b/drivers/gpu/drm/i915/display/i9xx_plane.h @@ -10,8 +10,8 @@ enum pipe; struct drm_framebuffer; -struct drm_i915_private; struct intel_crtc; +struct intel_display; struct intel_initial_plane_config; struct intel_plane; struct intel_plane_state; @@ -26,7 +26,7 @@ unsigned int vlv_plane_min_alignment(struct intel_plane *plane, int i9xx_check_plane_surface(struct intel_plane_state *plane_state); struct intel_plane * -intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe); +intel_primary_plane_create(struct intel_display *display, enum pipe pipe); void i9xx_get_initial_plane_config(struct intel_crtc *crtc, struct intel_initial_plane_config *plane_config); @@ -44,7 +44,7 @@ static inline int i9xx_check_plane_surface(struct intel_plane_state *plane_state return 0; } static inline struct intel_plane * -intel_primary_plane_create(struct drm_i915_private *dev_priv, int pipe) +intel_primary_plane_create(struct intel_display *display, int pipe) { return NULL; } diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index da2d6aeb20721..15e81f901aa11 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -321,7 +321,7 @@ int intel_crtc_init(struct intel_display *display, enum pipe pipe) if (DISPLAY_VER(display) >= 9) primary = skl_universal_plane_create(dev_priv, pipe, PLANE_1); else - primary = intel_primary_plane_create(dev_priv, pipe); + primary = intel_primary_plane_create(display, pipe); if (IS_ERR(primary)) { ret = PTR_ERR(primary); goto fail; From 9665025b57796f11ef0efac0116c2ec0f55091a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:29 +0200 Subject: [PATCH 185/284] drm/i915: Finish intel_sprite.c struct intel_display conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_sprite.c was partially converted to struct intel_display. Finish the job now that we can deal with the platform checks as well. And while at it we also move the 'display' variable declaration to be the first thing in most functions, consistency. We can actually do that now since intel_display() accepts the intel_plane and intel_plane_state types. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-9-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_crtc.c | 2 +- drivers/gpu/drm/i915/display/intel_sprite.c | 91 +++++++++------------ drivers/gpu/drm/i915/display/intel_sprite.h | 6 +- 3 files changed, 43 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 15e81f901aa11..7279e064a565c 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -336,7 +336,7 @@ int intel_crtc_init(struct intel_display *display, enum pipe pipe) if (DISPLAY_VER(dev_priv) >= 9) plane = skl_universal_plane_create(dev_priv, pipe, PLANE_2 + sprite); else - plane = intel_sprite_plane_create(dev_priv, pipe, sprite); + plane = intel_sprite_plane_create(display, pipe, sprite); if (IS_ERR(plane)) { ret = PTR_ERR(plane); goto fail; diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index d1b4b20af4a04..ab5bc8a08f0f5 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -66,8 +66,8 @@ static void i9xx_plane_linear_gamma(u16 gamma[8]) static void chv_sprite_update_csc(const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct intel_display *display = to_intel_display(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; enum plane_id plane_id = plane->id; /* @@ -138,8 +138,8 @@ chv_sprite_update_csc(const struct intel_plane_state *plane_state) static void vlv_sprite_update_clrc(const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct intel_display *display = to_intel_display(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; enum pipe pipe = plane->pipe; enum plane_id plane_id = plane->id; @@ -341,8 +341,8 @@ static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, static void vlv_sprite_update_gamma(const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct intel_display *display = to_intel_display(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; enum pipe pipe = plane->pipe; enum plane_id plane_id = plane->id; @@ -368,7 +368,7 @@ vlv_sprite_update_noarm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; enum plane_id plane_id = plane->id; int crtc_x = plane_state->uapi.dst.x1; @@ -390,8 +390,7 @@ vlv_sprite_update_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; enum plane_id plane_id = plane->id; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; @@ -404,7 +403,7 @@ vlv_sprite_update_arm(struct intel_dsb *dsb, linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); - if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) + if (display->platform.cherryview && pipe == PIPE_B) chv_sprite_update_csc(plane_state); if (key->flags) { @@ -440,7 +439,7 @@ vlv_sprite_disable_arm(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; enum plane_id plane_id = plane->id; @@ -645,19 +644,17 @@ static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; return fb->format->cpp[0] == 8 && - (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)); + (display->platform.ivybridge || display->platform.haswell); } static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; @@ -665,7 +662,7 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, sprctl = SPRITE_ENABLE; - if (IS_IVYBRIDGE(dev_priv)) + if (display->platform.ivybridge) sprctl |= SPRITE_TRICKLE_FEED_DISABLE; switch (fb->format->format) { @@ -754,8 +751,8 @@ static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state, static void ivb_sprite_update_gamma(const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct intel_display *display = to_intel_display(plane->base.dev); enum pipe pipe = plane->pipe; u16 gamma[18]; int i; @@ -787,8 +784,7 @@ ivb_sprite_update_noarm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; int crtc_x = plane_state->uapi.dst.x1; int crtc_y = plane_state->uapi.dst.y1; @@ -809,7 +805,7 @@ ivb_sprite_update_noarm(struct intel_dsb *dsb, SPRITE_POS_Y(crtc_y) | SPRITE_POS_X(crtc_x)); intel_de_write_fw(display, SPRSIZE(pipe), SPRITE_HEIGHT(crtc_h - 1) | SPRITE_WIDTH(crtc_w - 1)); - if (IS_IVYBRIDGE(dev_priv)) + if (display->platform.ivybridge) intel_de_write_fw(display, SPRSCALE(pipe), sprscale); } @@ -819,8 +815,7 @@ ivb_sprite_update_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; u32 sprsurf_offset = plane_state->view.color_plane[0].offset; @@ -841,7 +836,7 @@ ivb_sprite_update_arm(struct intel_dsb *dsb, /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET * register */ - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { + if (display->platform.haswell || display->platform.broadwell) { intel_de_write_fw(display, SPROFFSET(pipe), SPRITE_OFFSET_Y(y) | SPRITE_OFFSET_X(x)); } else { @@ -867,13 +862,12 @@ ivb_sprite_disable_arm(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; intel_de_write_fw(display, SPRCTL(pipe), 0); /* Disable the scaler */ - if (IS_IVYBRIDGE(dev_priv)) + if (display->platform.ivybridge) intel_de_write_fw(display, SPRSCALE(pipe), 0); intel_de_write_fw(display, SPRSURF(pipe), 0); } @@ -882,7 +876,7 @@ static bool ivb_sprite_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; bool ret; @@ -1002,8 +996,7 @@ static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; @@ -1011,7 +1004,7 @@ static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, dvscntr = DVS_ENABLE; - if (IS_SANDYBRIDGE(dev_priv)) + if (display->platform.sandybridge) dvscntr |= DVS_TRICKLE_FEED_DISABLE; switch (fb->format->format) { @@ -1072,8 +1065,8 @@ static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, static void g4x_sprite_update_gamma(const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct intel_display *display = to_intel_display(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; enum pipe pipe = plane->pipe; u16 gamma[8]; @@ -1102,8 +1095,8 @@ static void ilk_sprite_linear_gamma(u16 gamma[17]) static void ilk_sprite_update_gamma(const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct intel_display *display = to_intel_display(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; enum pipe pipe = plane->pipe; u16 gamma[17]; @@ -1132,7 +1125,7 @@ g4x_sprite_update_noarm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; int crtc_x = plane_state->uapi.dst.x1; int crtc_y = plane_state->uapi.dst.y1; @@ -1162,8 +1155,7 @@ g4x_sprite_update_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; u32 dvssurf_offset = plane_state->view.color_plane[0].offset; @@ -1195,7 +1187,7 @@ g4x_sprite_update_arm(struct intel_dsb *dsb, intel_de_write_fw(display, DVSSURF(pipe), intel_plane_ggtt_offset(plane_state) + dvssurf_offset); - if (IS_G4X(dev_priv)) + if (display->platform.g4x) g4x_sprite_update_gamma(plane_state); else ilk_sprite_update_gamma(plane_state); @@ -1206,7 +1198,7 @@ g4x_sprite_disable_arm(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; intel_de_write_fw(display, DVSCNTR(pipe), 0); @@ -1219,7 +1211,7 @@ static bool g4x_sprite_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; bool ret; @@ -1259,7 +1251,7 @@ static int g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(crtc_state); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_rect *src = &plane_state->uapi.src; const struct drm_rect *dst = &plane_state->uapi.dst; @@ -1325,9 +1317,7 @@ static int g4x_sprite_check(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(crtc_state); - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane_state); int min_scale = DRM_PLANE_NO_SCALING; int max_scale = DRM_PLANE_NO_SCALING; int ret; @@ -1336,7 +1326,7 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state, if (DISPLAY_VER(display) < 7) { min_scale = 1; max_scale = 16 << 16; - } else if (IS_IVYBRIDGE(dev_priv)) { + } else if (display->platform.ivybridge) { min_scale = 1; max_scale = 2 << 16; } @@ -1372,13 +1362,11 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state, int chv_plane_check_rotation(const struct intel_plane_state *plane_state) { - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane_state); unsigned int rotation = plane_state->hw.rotation; /* CHV ignores the mirror bit when the rotate bit is set :( */ - if (IS_CHERRYVIEW(dev_priv) && + if (display->platform.cherryview && rotation & DRM_MODE_ROTATE_180 && rotation & DRM_MODE_REFLECT_X) { drm_dbg_kms(display->drm, @@ -1580,10 +1568,9 @@ static const struct drm_plane_funcs vlv_sprite_funcs = { }; struct intel_plane * -intel_sprite_plane_create(struct drm_i915_private *dev_priv, +intel_sprite_plane_create(struct intel_display *display, enum pipe pipe, int sprite) { - struct intel_display *display = &dev_priv->display; struct intel_plane *plane; const struct drm_plane_funcs *plane_funcs; unsigned int supported_rotations; @@ -1596,7 +1583,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, if (IS_ERR(plane)) return plane; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (display->platform.valleyview || display->platform.cherryview) { plane->update_noarm = vlv_sprite_update_noarm; plane->update_arm = vlv_sprite_update_arm; plane->disable_arm = vlv_sprite_disable_arm; @@ -1610,7 +1597,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, if (intel_scanout_needs_vtd_wa(display)) plane->vtd_guard = 128; - if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { + if (display->platform.cherryview && pipe == PIPE_B) { formats = chv_pipe_b_sprite_formats; num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats); } else { @@ -1626,7 +1613,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane->get_hw_state = ivb_sprite_get_hw_state; plane->check_plane = g4x_sprite_check; - if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) { + if (display->platform.broadwell || display->platform.haswell) { plane->max_stride = hsw_sprite_max_stride; plane->min_cdclk = hsw_plane_min_cdclk; } else { @@ -1656,7 +1643,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, if (intel_scanout_needs_vtd_wa(display)) plane->vtd_guard = 64; - if (IS_SANDYBRIDGE(dev_priv)) { + if (display->platform.sandybridge) { formats = snb_sprite_formats; num_formats = ARRAY_SIZE(snb_sprite_formats); @@ -1669,7 +1656,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, } } - if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { + if (display->platform.cherryview && pipe == PIPE_B) { supported_rotations = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | DRM_MODE_REFLECT_X; diff --git a/drivers/gpu/drm/i915/display/intel_sprite.h b/drivers/gpu/drm/i915/display/intel_sprite.h index 531079979c05c..c33a2808da8c6 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.h +++ b/drivers/gpu/drm/i915/display/intel_sprite.h @@ -8,13 +8,13 @@ #include -struct drm_i915_private; struct intel_crtc_state; +struct intel_display; struct intel_plane_state; enum pipe; #ifdef I915 -struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, +struct intel_plane *intel_sprite_plane_create(struct intel_display *display, enum pipe pipe, int plane); int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); int chv_plane_check_rotation(const struct intel_plane_state *plane_state); @@ -26,7 +26,7 @@ int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state, int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); #else -static inline struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, +static inline struct intel_plane *intel_sprite_plane_create(struct intel_display *display, int pipe, int plane) { return NULL; From 69e79a3a3208fbc50cb1773bc18da405927b9f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:30 +0200 Subject: [PATCH 186/284] drm/i915: Convert intel_cursor.c to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct intel_display will replace struct drm_i915_private as the main thing for display code. Convert the cursor code to use it. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-10-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_crtc.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 136 +++++++++----------- drivers/gpu/drm/i915/display/intel_cursor.h | 4 +- 3 files changed, 66 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 7279e064a565c..2dc495659563e 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -344,7 +344,7 @@ int intel_crtc_init(struct intel_display *display, enum pipe pipe) crtc->plane_ids_mask |= BIT(plane->id); } - cursor = intel_cursor_plane_create(dev_priv, pipe); + cursor = intel_cursor_plane_create(display, pipe); if (IS_ERR(cursor)) { ret = PTR_ERR(cursor); goto fail; diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 6a0d563174cf9..4cd48d54164d6 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -35,11 +35,10 @@ static const u32 intel_cursor_formats[] = { static u32 intel_cursor_base(const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); u32 base; - if (DISPLAY_INFO(dev_priv)->cursor_needs_physical) + if (DISPLAY_INFO(display)->cursor_needs_physical) base = plane_state->phys_dma_addr; else base = intel_plane_ggtt_offset(plane_state); @@ -92,8 +91,7 @@ static bool intel_cursor_size_ok(const struct intel_plane_state *plane_state) static int intel_cursor_check_surface(struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); unsigned int rotation = plane_state->hw.rotation; int src_x, src_y; u32 offset; @@ -114,7 +112,7 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state) plane_state, 0); if (src_x != 0 || src_y != 0) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Arbitrary cursor panning not supported\n"); return -EINVAL; } @@ -127,7 +125,7 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state) src_x << 16, src_y << 16); /* ILK+ do this automagically in hardware */ - if (HAS_GMCH(dev_priv) && rotation & DRM_MODE_ROTATE_180) { + if (HAS_GMCH(display) && rotation & DRM_MODE_ROTATE_180) { const struct drm_framebuffer *fb = plane_state->hw.fb; int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; int src_h = drm_rect_height(&plane_state->uapi.src) >> 16; @@ -145,14 +143,14 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state) static int intel_check_cursor(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; - struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); const struct drm_rect src = plane_state->uapi.src; const struct drm_rect dst = plane_state->uapi.dst; int ret; if (fb && fb->modifier != DRM_FORMAT_MOD_LINEAR) { - drm_dbg_kms(&i915->drm, "cursor cannot be tiled\n"); + drm_dbg_kms(display->drm, "cursor cannot be tiled\n"); return -EINVAL; } @@ -233,8 +231,8 @@ static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state) static int i845_check_cursor(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; - struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); int ret; ret = intel_check_cursor(crtc_state, plane_state); @@ -247,14 +245,14 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state, /* Check for which cursor types we support */ if (!i845_cursor_size_ok(plane_state)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Cursor dimension %dx%d not supported\n", drm_rect_width(&plane_state->uapi.dst), drm_rect_height(&plane_state->uapi.dst)); return -EINVAL; } - drm_WARN_ON(&i915->drm, plane_state->uapi.visible && + drm_WARN_ON(display->drm, plane_state->uapi.visible && plane_state->view.color_plane[0].mapping_stride != fb->pitches[0]); switch (fb->pitches[0]) { @@ -264,7 +262,7 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state, case 2048: break; default: - drm_dbg_kms(&i915->drm, "Invalid cursor stride (%u)\n", + drm_dbg_kms(display->drm, "Invalid cursor stride (%u)\n", fb->pitches[0]); return -EINVAL; } @@ -280,7 +278,7 @@ static void i845_cursor_update_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); u32 cntl = 0, base = 0, pos = 0, size = 0; if (plane_state && plane_state->uapi.visible) { @@ -302,17 +300,17 @@ static void i845_cursor_update_arm(struct intel_dsb *dsb, if (plane->cursor.base != base || plane->cursor.size != size || plane->cursor.cntl != cntl) { - intel_de_write_fw(dev_priv, CURCNTR(dev_priv, PIPE_A), 0); - intel_de_write_fw(dev_priv, CURBASE(dev_priv, PIPE_A), base); - intel_de_write_fw(dev_priv, CURSIZE(dev_priv, PIPE_A), size); - intel_de_write_fw(dev_priv, CURPOS(dev_priv, PIPE_A), pos); - intel_de_write_fw(dev_priv, CURCNTR(dev_priv, PIPE_A), cntl); + intel_de_write_fw(display, CURCNTR(display, PIPE_A), 0); + intel_de_write_fw(display, CURBASE(display, PIPE_A), base); + intel_de_write_fw(display, CURSIZE(display, PIPE_A), size); + intel_de_write_fw(display, CURPOS(display, PIPE_A), pos); + intel_de_write_fw(display, CURCNTR(display, PIPE_A), cntl); plane->cursor.base = base; plane->cursor.size = size; plane->cursor.cntl = cntl; } else { - intel_de_write_fw(dev_priv, CURPOS(dev_priv, PIPE_A), pos); + intel_de_write_fw(display, CURPOS(display, PIPE_A), pos); } } @@ -327,7 +325,6 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; bool ret; @@ -337,7 +334,7 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane, if (!wakeref) return false; - ret = intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_A)) & CURSOR_ENABLE; + ret = intel_de_read(display, CURCNTR(display, PIPE_A)) & CURSOR_ENABLE; *pipe = PIPE_A; @@ -383,11 +380,11 @@ static unsigned int i9xx_cursor_min_alignment(struct intel_plane *plane, static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 cntl = 0; - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) return cntl; if (crtc_state->gamma_enable) @@ -396,7 +393,7 @@ static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state) if (crtc_state->csc_enable) cntl |= MCURSOR_PIPE_CSC_ENABLE; - if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) + if (DISPLAY_VER(display) < 5 && !display->platform.g4x) cntl |= MCURSOR_PIPE_SEL(crtc->pipe); return cntl; @@ -405,11 +402,10 @@ static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state) static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); u32 cntl = 0; - if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) + if (display->platform.sandybridge || display->platform.ivybridge) cntl |= MCURSOR_TRICKLE_FEED_DISABLE; switch (drm_rect_width(&plane_state->uapi.dst)) { @@ -431,7 +427,7 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state, cntl |= MCURSOR_ROTATE_180; /* Wa_22012358565:adl-p */ - if (DISPLAY_VER(dev_priv) == 13) + if (DISPLAY_VER(display) == 13) cntl |= MCURSOR_ARB_SLOTS(1); return cntl; @@ -439,8 +435,7 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state, static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); int width = drm_rect_width(&plane_state->uapi.dst); int height = drm_rect_height(&plane_state->uapi.dst); @@ -463,7 +458,7 @@ static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state) * cursor is not rotated. Everything else requires square * cursors. */ - if (HAS_CUR_FBC(dev_priv) && + if (HAS_CUR_FBC(display) && plane_state->hw.rotation & DRM_MODE_ROTATE_0) { if (height < 8 || height > width) return false; @@ -478,8 +473,8 @@ static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state) static int i9xx_check_cursor(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; enum pipe pipe = plane->pipe; int ret; @@ -494,19 +489,19 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state, /* Check for which cursor types we support */ if (!i9xx_cursor_size_ok(plane_state)) { - drm_dbg(&dev_priv->drm, + drm_dbg(display->drm, "Cursor dimension %dx%d not supported\n", drm_rect_width(&plane_state->uapi.dst), drm_rect_height(&plane_state->uapi.dst)); return -EINVAL; } - drm_WARN_ON(&dev_priv->drm, plane_state->uapi.visible && + drm_WARN_ON(display->drm, plane_state->uapi.visible && plane_state->view.color_plane[0].mapping_stride != fb->pitches[0]); if (fb->pitches[0] != drm_rect_width(&plane_state->uapi.dst) * fb->format->cpp[0]) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Invalid cursor stride (%u) (cursor width %d)\n", fb->pitches[0], drm_rect_width(&plane_state->uapi.dst)); @@ -523,9 +518,9 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state, * display power well must be turned off and on again. * Refuse the put the cursor into that compromised position. */ - if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_C && + if (display->platform.cherryview && pipe == PIPE_C && plane_state->uapi.visible && plane_state->uapi.dst.x1 < 0) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "CHV cursor C not allowed to straddle the left screen edge\n"); return -EINVAL; } @@ -539,7 +534,7 @@ static void i9xx_cursor_disable_sel_fetch_arm(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; if (!crtc_state->enable_psr2_sel_fetch) @@ -553,8 +548,7 @@ static void wa_16021440873(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); u32 ctl = plane_state->ctl; int et_y_position = drm_rect_height(&crtc_state->pipe_src) + 1; enum pipe pipe = plane->pipe; @@ -564,7 +558,7 @@ static void wa_16021440873(struct intel_dsb *dsb, intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), ctl); - intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(dev_priv, pipe), + intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(display, pipe), CURSOR_POS_Y(et_y_position)); } @@ -573,8 +567,7 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; if (!crtc_state->enable_psr2_sel_fetch) @@ -585,7 +578,7 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb, u32 val = intel_cursor_position(crtc_state, plane_state, true); - intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(dev_priv, pipe), val); + intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(display, pipe), val); } intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), plane_state->ctl); @@ -659,8 +652,7 @@ static void i9xx_cursor_update_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; u32 cntl = 0, base = 0, pos = 0, fbc_ctl = 0; @@ -698,7 +690,7 @@ static void i9xx_cursor_update_arm(struct intel_dsb *dsb, * the CURCNTR write arms the update. */ - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) skl_write_cursor_wm(dsb, plane, crtc_state); if (plane_state) @@ -709,18 +701,18 @@ static void i9xx_cursor_update_arm(struct intel_dsb *dsb, if (plane->cursor.base != base || plane->cursor.size != fbc_ctl || plane->cursor.cntl != cntl) { - if (HAS_CUR_FBC(dev_priv)) - intel_de_write_dsb(display, dsb, CUR_FBC_CTL(dev_priv, pipe), fbc_ctl); - intel_de_write_dsb(display, dsb, CURCNTR(dev_priv, pipe), cntl); - intel_de_write_dsb(display, dsb, CURPOS(dev_priv, pipe), pos); - intel_de_write_dsb(display, dsb, CURBASE(dev_priv, pipe), base); + if (HAS_CUR_FBC(display)) + intel_de_write_dsb(display, dsb, CUR_FBC_CTL(display, pipe), fbc_ctl); + intel_de_write_dsb(display, dsb, CURCNTR(display, pipe), cntl); + intel_de_write_dsb(display, dsb, CURPOS(display, pipe), pos); + intel_de_write_dsb(display, dsb, CURBASE(display, pipe), base); plane->cursor.base = base; plane->cursor.size = fbc_ctl; plane->cursor.cntl = cntl; } else { - intel_de_write_dsb(display, dsb, CURPOS(dev_priv, pipe), pos); - intel_de_write_dsb(display, dsb, CURBASE(dev_priv, pipe), base); + intel_de_write_dsb(display, dsb, CURPOS(display, pipe), pos); + intel_de_write_dsb(display, dsb, CURBASE(display, pipe), base); } } @@ -735,7 +727,6 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; bool ret; @@ -751,11 +742,11 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, if (!wakeref) return false; - val = intel_de_read(dev_priv, CURCNTR(dev_priv, plane->pipe)); + val = intel_de_read(display, CURCNTR(display, plane->pipe)); ret = val & MCURSOR_MODE_MASK; - if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) + if (DISPLAY_VER(display) >= 5 || display->platform.g4x) *pipe = plane->pipe; else *pipe = REG_FIELD_GET(MCURSOR_PIPE_SEL_MASK, val); @@ -797,7 +788,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, { struct intel_plane *plane = to_intel_plane(_plane); struct intel_crtc *crtc = to_intel_crtc(_crtc); - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); struct intel_plane_state *old_plane_state = to_intel_plane_state(plane->base.state); struct intel_plane_state *new_plane_state; @@ -901,7 +892,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, intel_psr_lock(crtc_state); - if (!drm_WARN_ON(&i915->drm, drm_crtc_vblank_get(&crtc->base))) { + if (!drm_WARN_ON(display->drm, drm_crtc_vblank_get(&crtc->base))) { /* * TODO: maybe check if we're still in PSR * and skip the vblank evasion entirely? @@ -967,8 +958,8 @@ static const struct drm_plane_funcs intel_cursor_plane_funcs = { static void intel_cursor_add_size_hints_property(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); - const struct drm_mode_config *config = &i915->drm.mode_config; + struct intel_display *display = to_intel_display(plane); + const struct drm_mode_config *config = &display->drm->mode_config; struct drm_plane_size_hint hints[4]; int size, max_size, num_hints = 0; @@ -976,7 +967,7 @@ static void intel_cursor_add_size_hints_property(struct intel_plane *plane) /* for simplicity only enumerate the supported square+POT sizes */ for (size = 64; size <= max_size; size *= 2) { - if (drm_WARN_ON(&i915->drm, num_hints >= ARRAY_SIZE(hints))) + if (drm_WARN_ON(display->drm, num_hints >= ARRAY_SIZE(hints))) break; hints[num_hints].width = size; @@ -988,10 +979,9 @@ static void intel_cursor_add_size_hints_property(struct intel_plane *plane) } struct intel_plane * -intel_cursor_plane_create(struct drm_i915_private *dev_priv, +intel_cursor_plane_create(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; struct intel_plane *cursor; int ret, zpos; u64 *modifiers; @@ -1005,7 +995,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, cursor->id = PLANE_CURSOR; cursor->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, cursor->id); - if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) { + if (display->platform.i845g || display->platform.i865g) { cursor->max_stride = i845_cursor_max_stride; cursor->min_alignment = i845_cursor_min_alignment; cursor->update_arm = i845_cursor_update_arm; @@ -1015,9 +1005,9 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, } else { cursor->max_stride = i9xx_cursor_max_stride; - if (IS_I830(dev_priv)) + if (display->platform.i830) cursor->min_alignment = i830_cursor_min_alignment; - else if (IS_I85X(dev_priv)) + else if (display->platform.i85x) cursor->min_alignment = i85x_cursor_min_alignment; else cursor->min_alignment = i9xx_cursor_min_alignment; @@ -1034,12 +1024,12 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, cursor->cursor.base = ~0; cursor->cursor.cntl = ~0; - if (IS_I845G(dev_priv) || IS_I865G(dev_priv) || HAS_CUR_FBC(dev_priv)) + if (display->platform.i845g || display->platform.i865g || HAS_CUR_FBC(display)) cursor->cursor.size = ~0; modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_NONE); - ret = drm_universal_plane_init(&dev_priv->drm, &cursor->base, + ret = drm_universal_plane_init(display->drm, &cursor->base, 0, &intel_cursor_plane_funcs, intel_cursor_formats, ARRAY_SIZE(intel_cursor_formats), @@ -1052,7 +1042,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, if (ret) goto fail; - if (DISPLAY_VER(dev_priv) >= 4) + if (DISPLAY_VER(display) >= 4) drm_plane_create_rotation_property(&cursor->base, DRM_MODE_ROTATE_0, DRM_MODE_ROTATE_0 | @@ -1060,10 +1050,10 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, intel_cursor_add_size_hints_property(cursor); - zpos = DISPLAY_RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1; + zpos = DISPLAY_RUNTIME_INFO(display)->num_sprites[pipe] + 1; drm_plane_create_zpos_immutable_property(&cursor->base, zpos); - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) drm_plane_enable_fb_damage_clips(&cursor->base); intel_plane_helper_add(cursor); diff --git a/drivers/gpu/drm/i915/display/intel_cursor.h b/drivers/gpu/drm/i915/display/intel_cursor.h index e2d9ec710a864..65a9e7eb88c2b 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.h +++ b/drivers/gpu/drm/i915/display/intel_cursor.h @@ -7,12 +7,12 @@ #define _INTEL_CURSOR_H_ enum pipe; -struct drm_i915_private; +struct intel_display; struct intel_plane; struct kthread_work; struct intel_plane * -intel_cursor_plane_create(struct drm_i915_private *dev_priv, +intel_cursor_plane_create(struct intel_display *display, enum pipe pipe); void intel_cursor_unpin_work(struct kthread_work *base); From a2ed9f8452479500023f386daa281887574f4b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:31 +0200 Subject: [PATCH 187/284] drm/i915: Convert skl_univeral_plane.c to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct intel_display will replace struct drm_i915_private as the main thing for display code. Convert the skl+ universal plane code to use it. Note that we still have two straggles in the form on HAS_FLAT_CCS() and the pxp stuff. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-11-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_crtc.c | 4 +- drivers/gpu/drm/i915/display/intel_display.c | 5 +- drivers/gpu/drm/i915/display/skl_scaler.c | 13 +- .../drm/i915/display/skl_universal_plane.c | 360 +++++++++--------- .../drm/i915/display/skl_universal_plane.h | 8 +- 5 files changed, 189 insertions(+), 201 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 2dc495659563e..89785da936039 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -319,7 +319,7 @@ int intel_crtc_init(struct intel_display *display, enum pipe pipe) crtc->num_scalers = DISPLAY_RUNTIME_INFO(display)->num_scalers[pipe]; if (DISPLAY_VER(display) >= 9) - primary = skl_universal_plane_create(dev_priv, pipe, PLANE_1); + primary = skl_universal_plane_create(display, pipe, PLANE_1); else primary = intel_primary_plane_create(display, pipe); if (IS_ERR(primary)) { @@ -334,7 +334,7 @@ int intel_crtc_init(struct intel_display *display, enum pipe pipe) struct intel_plane *plane; if (DISPLAY_VER(dev_priv) >= 9) - plane = skl_universal_plane_create(dev_priv, pipe, PLANE_2 + sprite); + plane = skl_universal_plane_create(display, pipe, PLANE_2 + sprite); else plane = intel_sprite_plane_create(display, pipe, sprite); if (IS_ERR(plane)) { diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2bc59dfa653d8..26b674909d19d 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4438,6 +4438,7 @@ static int icl_add_linked_planes(struct intel_atomic_state *state) static int icl_check_nv12_planes(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); @@ -4479,7 +4480,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, continue; for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, linked) { - if (!icl_is_nv12_y_plane(dev_priv, linked->id)) + if (!icl_is_nv12_y_plane(display, linked->id)) continue; if (crtc_state->active_planes & BIT(linked->id)) @@ -4524,7 +4525,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, linked_state->uapi.src = plane_state->uapi.src; linked_state->uapi.dst = plane_state->uapi.dst; - if (icl_is_hdr_plane(dev_priv, plane->id)) { + if (icl_is_hdr_plane(display, plane->id)) { if (linked->id == PLANE_7) plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL; else if (linked->id == PLANE_6) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index c8bf6fd92ce8d..3d24fa773094d 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -279,14 +279,14 @@ int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state) int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); struct drm_framebuffer *fb = plane_state->hw.fb; bool force_detach = !fb || !plane_state->uapi.visible; bool need_scaler = false; /* Pre-gen11 and SDR planes always need a scaler for planar formats. */ - if (!icl_is_hdr_plane(dev_priv, plane->id) && + if (!icl_is_hdr_plane(display, plane->id) && fb && intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) need_scaler = true; @@ -364,9 +364,7 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, int *scaler_id) { struct intel_display *display = to_intel_display(crtc); - struct intel_crtc_scaler_state *scaler_state = - &crtc_state->scaler_state; - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state; u32 mode; int hscale = 0; int vscale = 0; @@ -386,7 +384,7 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, if (DISPLAY_VER(display) == 9) { mode = SKL_PS_SCALER_MODE_NV12; - } else if (icl_is_hdr_plane(dev_priv, plane->id)) { + } else if (icl_is_hdr_plane(display, plane->id)) { /* * On gen11+'s HDR planes we only use the scaler for * scaling. They have a dedicated chroma upsampler, so @@ -782,7 +780,6 @@ skl_program_plane_scaler(struct intel_plane *plane, const struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; enum pipe pipe = plane->pipe; int scaler_id = plane_state->scaler_id; @@ -806,7 +803,7 @@ skl_program_plane_scaler(struct intel_plane *plane, /* TODO: handle sub-pixel coordinates */ if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && - !icl_is_hdr_plane(dev_priv, plane->id)) { + !icl_is_hdr_plane(display, plane->id)) { y_hphase = skl_scaler_calc_phase(1, hscale, false); y_vphase = skl_scaler_calc_phase(1, vscale, false); diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 3a60d6d49662b..f8d3a79a96ff6 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -233,21 +233,19 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha) } } -static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915) +static u8 icl_nv12_y_plane_mask(struct intel_display *display) { - struct intel_display *display = &i915->display; - if (DISPLAY_VER(display) >= 13 || HAS_D12_PLANE_MINIMIZATION(display)) return BIT(PLANE_4) | BIT(PLANE_5); else return BIT(PLANE_6) | BIT(PLANE_7); } -bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv, +bool icl_is_nv12_y_plane(struct intel_display *display, enum plane_id plane_id) { - return DISPLAY_VER(dev_priv) >= 11 && - icl_nv12_y_plane_mask(dev_priv) & BIT(plane_id); + return DISPLAY_VER(display) >= 11 && + icl_nv12_y_plane_mask(display) & BIT(plane_id); } u8 icl_hdr_plane_mask(void) @@ -255,9 +253,9 @@ u8 icl_hdr_plane_mask(void) return BIT(PLANE_1) | BIT(PLANE_2) | BIT(PLANE_3); } -bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id) +bool icl_is_hdr_plane(struct intel_display *display, enum plane_id plane_id) { - return DISPLAY_VER(dev_priv) >= 11 && + return DISPLAY_VER(display) >= 11 && icl_hdr_plane_mask() & BIT(plane_id); } @@ -589,7 +587,7 @@ static u32 tgl_plane_min_alignment(struct intel_plane *plane, const struct drm_framebuffer *fb, int color_plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); /* PLANE_SURF GGTT -> DPT alignment */ int mult = intel_fb_uses_dpt(fb) ? 512 : 1; @@ -602,7 +600,7 @@ static u32 tgl_plane_min_alignment(struct intel_plane *plane, * flips unless we align to 16k at least. * Figure out what's going on here... */ - if (IS_ALDERLAKE_P(i915) && + if (display->platform.alderlake_p && intel_plane_can_async_flip(plane, fb->modifier)) return mult * 16 * 1024; @@ -684,7 +682,7 @@ icl_program_input_csc(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; enum plane_id plane_id = plane->id; @@ -829,7 +827,7 @@ static void skl_write_plane_wm(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal; @@ -875,7 +873,7 @@ skl_plane_disable_arm(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; @@ -889,7 +887,7 @@ static void icl_plane_disable_sel_fetch_arm(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; if (!crtc_state->enable_psr2_sel_fetch) @@ -903,12 +901,11 @@ icl_plane_disable_arm(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; - if (icl_is_hdr_plane(dev_priv, plane_id)) + if (icl_is_hdr_plane(display, plane_id)) intel_de_write_dsb(display, dsb, PLANE_CUS_CTL(pipe, plane_id), 0); skl_write_plane_wm(dsb, plane, crtc_state); @@ -923,7 +920,6 @@ skl_plane_get_hw_state(struct intel_plane *plane, enum pipe *pipe) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum intel_display_power_domain power_domain; enum plane_id plane_id = plane->id; intel_wakeref_t wakeref; @@ -934,7 +930,7 @@ skl_plane_get_hw_state(struct intel_plane *plane, if (!wakeref) return false; - ret = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE; + ret = intel_de_read(display, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE; *pipe = plane->pipe; @@ -1155,10 +1151,10 @@ static u32 adlp_plane_ctl_arb_slots(const struct intel_plane_state *plane_state) static u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); u32 plane_ctl = 0; - if (DISPLAY_VER(dev_priv) >= 10) + if (DISPLAY_VER(display) >= 10) return plane_ctl; if (crtc_state->gamma_enable) @@ -1173,8 +1169,7 @@ static u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state) static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; @@ -1182,7 +1177,7 @@ static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, plane_ctl = PLANE_CTL_ENABLE; - if (DISPLAY_VER(dev_priv) < 10) { + if (DISPLAY_VER(display) < 10) { plane_ctl |= skl_plane_ctl_alpha(plane_state); plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; @@ -1197,7 +1192,7 @@ static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, plane_ctl |= skl_plane_ctl_tiling(fb->modifier); plane_ctl |= skl_plane_ctl_rotate(rotation & DRM_MODE_ROTATE_MASK); - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) plane_ctl |= icl_plane_ctl_flip(rotation & DRM_MODE_REFLECT_MASK); @@ -1207,7 +1202,7 @@ static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE; /* Wa_22012358565:adl-p */ - if (DISPLAY_VER(dev_priv) == 13) + if (DISPLAY_VER(display) == 13) plane_ctl |= adlp_plane_ctl_arb_slots(plane_state); return plane_ctl; @@ -1215,10 +1210,10 @@ static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); u32 plane_color_ctl = 0; - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) return plane_color_ctl; if (crtc_state->gamma_enable) @@ -1233,8 +1228,7 @@ static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state) static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); u32 plane_color_ctl = 0; @@ -1242,7 +1236,7 @@ static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state); - if (fb->format->is_yuv && !icl_is_hdr_plane(dev_priv, plane->id)) { + if (fb->format->is_yuv && !icl_is_hdr_plane(display, plane->id)) { switch (plane_state->hw.color_encoding) { case DRM_COLOR_YCBCR_BT709: plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709; @@ -1272,7 +1266,7 @@ static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, static u32 skl_surf_address(const struct intel_plane_state *plane_state, int color_plane) { - struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; u32 offset = plane_state->view.color_plane[color_plane].offset; @@ -1281,12 +1275,12 @@ static u32 skl_surf_address(const struct intel_plane_state *plane_state, * The DPT object contains only one vma, so the VMA's offset * within the DPT is always 0. */ - drm_WARN_ON(&i915->drm, plane_state->dpt_vma && + drm_WARN_ON(display->drm, plane_state->dpt_vma && intel_dpt_offset(plane_state->dpt_vma)); - drm_WARN_ON(&i915->drm, offset & 0x1fffff); + drm_WARN_ON(display->drm, offset & 0x1fffff); return offset >> 9; } else { - drm_WARN_ON(&i915->drm, offset & 0xfff); + drm_WARN_ON(display->drm, offset & 0xfff); return offset; } } @@ -1308,7 +1302,7 @@ static u32 skl_plane_surf(const struct intel_plane_state *plane_state, u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state, int color_plane) { - struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; int aux_plane = skl_main_to_aux_plane(fb, color_plane); u32 aux_dist; @@ -1319,7 +1313,7 @@ u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state, aux_dist = skl_surf_address(plane_state, aux_plane) - skl_surf_address(plane_state, color_plane); - if (DISPLAY_VER(i915) < 12) + if (DISPLAY_VER(display) < 12) aux_dist |= PLANE_AUX_STRIDE(skl_plane_stride(plane_state, aux_plane)); return aux_dist; @@ -1357,7 +1351,7 @@ static void icl_plane_csc_load_black(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; @@ -1394,7 +1388,7 @@ skl_plane_update_noarm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; u32 stride = skl_plane_stride(plane_state, 0); @@ -1425,8 +1419,7 @@ skl_plane_update_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; u32 x = plane_state->view.color_plane[0].x; @@ -1441,7 +1434,7 @@ skl_plane_update_arm(struct intel_dsb *dsb, crtc_state->async_flip_planes & BIT(plane->id)) plane_ctl |= PLANE_CTL_ASYNC_FLIP; - if (DISPLAY_VER(dev_priv) >= 10) + if (DISPLAY_VER(display) >= 10) plane_color_ctl = plane_state->color_ctl | glk_plane_color_ctl_crtc(crtc_state); @@ -1462,7 +1455,7 @@ skl_plane_update_arm(struct intel_dsb *dsb, PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) | PLANE_OFFSET_X(plane_state->view.color_plane[1].x)); - if (DISPLAY_VER(dev_priv) >= 10) + if (DISPLAY_VER(display) >= 10) intel_de_write_dsb(display, dsb, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl); @@ -1493,7 +1486,7 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_dsb *dsb, const struct intel_plane_state *plane_state, int color_plane) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; const struct drm_rect *clip; u32 val; @@ -1539,8 +1532,7 @@ icl_plane_update_noarm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; int color_plane = icl_plane_color_plane(plane_state); @@ -1588,18 +1580,18 @@ icl_plane_update_noarm(struct intel_dsb *dsb, } /* FLAT CCS doesn't need to program AUX_DIST */ - if (!HAS_FLAT_CCS(dev_priv) && DISPLAY_VER(dev_priv) < 20) + if (!HAS_FLAT_CCS(to_i915(display->drm)) && DISPLAY_VER(display) < 20) intel_de_write_dsb(display, dsb, PLANE_AUX_DIST(pipe, plane_id), skl_plane_aux_dist(plane_state, color_plane)); - if (icl_is_hdr_plane(dev_priv, plane_id)) + if (icl_is_hdr_plane(display, plane_id)) intel_de_write_dsb(display, dsb, PLANE_CUS_CTL(pipe, plane_id), plane_state->cus_ctl); intel_de_write_dsb(display, dsb, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl); - if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id)) + if (fb->format->is_yuv && icl_is_hdr_plane(display, plane_id)) icl_program_input_csc(dsb, plane, plane_state); skl_write_plane_wm(dsb, plane, crtc_state); @@ -1619,7 +1611,7 @@ static void icl_plane_update_sel_fetch_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; if (!crtc_state->enable_psr2_sel_fetch) @@ -1638,7 +1630,7 @@ icl_plane_update_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; int color_plane = icl_plane_color_plane(plane_state); @@ -1677,7 +1669,7 @@ skl_plane_async_flip(struct intel_dsb *dsb, const struct intel_plane_state *plane_state, bool async_flip) { - struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; u32 plane_ctl = plane_state->ctl, plane_surf; @@ -1713,8 +1705,7 @@ static bool intel_format_is_p01x(u32 format) static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; @@ -1723,7 +1714,7 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) && intel_fb_is_ccs_modifier(fb->modifier)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "RC support only with 0/180 degree rotation (%x)\n", rotation); return -EINVAL; @@ -1731,7 +1722,7 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, if (rotation & DRM_MODE_REFLECT_X && fb->modifier == DRM_FORMAT_MOD_LINEAR) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "horizontal flip is not supported with linear surface formats\n"); return -EINVAL; } @@ -1741,15 +1732,15 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, */ if (rotation & DRM_MODE_REFLECT_X && intel_fb_is_tile4_modifier(fb->modifier) && - DISPLAY_VER(dev_priv) >= 20) { - drm_dbg_kms(&dev_priv->drm, + DISPLAY_VER(display) >= 20) { + drm_dbg_kms(display->drm, "horizontal flip is not supported with tile4 surface formats\n"); return -EINVAL; } if (drm_rotation_90_or_270(rotation)) { if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Y/Yf tiling required for 90/270!\n"); return -EINVAL; } @@ -1760,7 +1751,7 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, */ switch (fb->format->format) { case DRM_FORMAT_RGB565: - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) break; fallthrough; case DRM_FORMAT_C8: @@ -1773,7 +1764,7 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, case DRM_FORMAT_Y216: case DRM_FORMAT_XVYU12_16161616: case DRM_FORMAT_XVYU16161616: - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Unsupported pixel format %p4cc for 90/270!\n", &fb->format->format); return -EINVAL; @@ -1787,16 +1778,16 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE && fb->modifier != DRM_FORMAT_MOD_LINEAR && fb->modifier != I915_FORMAT_MOD_X_TILED) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Y/Yf tiling not supported in IF-ID mode\n"); return -EINVAL; } /* Wa_1606054188:tgl,adl-s */ - if ((IS_ALDERLAKE_S(dev_priv) || IS_TIGERLAKE(dev_priv)) && + if ((display->platform.alderlake_s || display->platform.tigerlake) && plane_state->ckey.flags & I915_SET_COLORKEY_SOURCE && intel_format_is_p01x(fb->format->format)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Source color keying not supported with P01x formats\n"); return -EINVAL; } @@ -1807,8 +1798,7 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = - to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); int crtc_x = plane_state->uapi.dst.x1; int crtc_w = drm_rect_width(&plane_state->uapi.dst); int pipe_src_w = drm_rect_width(&crtc_state->pipe_src); @@ -1822,9 +1812,9 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s * than the cursor ending less than 4 pixels from the left edge of the * screen may cause FIFO underflow and display corruption. */ - if (DISPLAY_VER(dev_priv) == 10 && + if (DISPLAY_VER(display) == 10 && (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "requested plane X %s position %d invalid (valid range %d-%d)\n", crtc_x + crtc_w < 4 ? "end" : "start", crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x, @@ -1837,7 +1827,7 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state) { - struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; @@ -1847,14 +1837,14 @@ static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_s src_w & 3 && (rotation == DRM_MODE_ROTATE_270 || rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) { - drm_dbg_kms(&i915->drm, "src width must be multiple of 4 for rotated planar YUV\n"); + drm_dbg_kms(display->drm, "src width must be multiple of 4 for rotated planar YUV\n"); return -EINVAL; } return 0; } -static int skl_plane_max_scale(struct drm_i915_private *dev_priv, +static int skl_plane_max_scale(struct intel_display *display, const struct drm_framebuffer *fb) { /* @@ -1863,7 +1853,7 @@ static int skl_plane_max_scale(struct drm_i915_private *dev_priv, * the best case. * FIXME need to properly check this later. */ - if (DISPLAY_VER(dev_priv) >= 10 || + if (DISPLAY_VER(display) >= 10 || !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) return 0x30000 - 1; else @@ -1952,8 +1942,8 @@ skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state, int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state, int *x, int *y, u32 *offset) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; int aux_plane = skl_main_to_aux_plane(fb, 0); u32 aux_offset = plane_state->view.color_plane[aux_plane].offset; @@ -1962,7 +1952,7 @@ int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state, intel_add_fb_offsets(x, y, plane_state, 0); *offset = intel_plane_compute_aligned_offset(x, y, plane_state, 0); - if (drm_WARN_ON(&dev_priv->drm, alignment && !is_power_of_2(alignment))) + if (drm_WARN_ON(display->drm, alignment && !is_power_of_2(alignment))) return -EINVAL; /* @@ -1986,7 +1976,7 @@ int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state, while ((*x + w) * cpp > plane_state->view.color_plane[0].mapping_stride) { if (*offset == 0) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Unable to find suitable display surface offset due to X-tiling\n"); return -EINVAL; } @@ -2002,8 +1992,8 @@ int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state, static int skl_check_main_surface(struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; int x = plane_state->uapi.src.x1 >> 16; @@ -2019,7 +2009,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state) int ret; if (w > max_width || w < min_width || h > max_height || h < 1) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n", w, h, min_width, max_width, max_height); return -EINVAL; @@ -2046,16 +2036,16 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state) if (x != plane_state->view.color_plane[aux_plane].x || y != plane_state->view.color_plane[aux_plane].y) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Unable to find suitable display surface offset due to CCS\n"); return -EINVAL; } } - if (DISPLAY_VER(dev_priv) >= 13) - drm_WARN_ON(&dev_priv->drm, x > 65535 || y > 65535); + if (DISPLAY_VER(display) >= 13) + drm_WARN_ON(display->drm, x > 65535 || y > 65535); else - drm_WARN_ON(&dev_priv->drm, x > 8191 || y > 8191); + drm_WARN_ON(display->drm, x > 8191 || y > 8191); plane_state->view.color_plane[0].offset = offset; plane_state->view.color_plane[0].x = x; @@ -2073,8 +2063,8 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state) static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; int uv_plane = 1; @@ -2090,7 +2080,7 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) /* FIXME not quite sure how/if these apply to the chroma plane */ if (w > max_width || h > max_height) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "CbCr source size %dx%d too big (limit %dx%d)\n", w, h, max_width, max_height); return -EINVAL; @@ -2124,16 +2114,16 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) if (x != plane_state->view.color_plane[ccs_plane].x || y != plane_state->view.color_plane[ccs_plane].y) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Unable to find suitable display surface offset due to CCS\n"); return -EINVAL; } } - if (DISPLAY_VER(i915) >= 13) - drm_WARN_ON(&i915->drm, x > 65535 || y > 65535); + if (DISPLAY_VER(display) >= 13) + drm_WARN_ON(display->drm, x > 65535 || y > 65535); else - drm_WARN_ON(&i915->drm, x > 8191 || y > 8191); + drm_WARN_ON(display->drm, x > 8191 || y > 8191); plane_state->view.color_plane[uv_plane].offset = offset; plane_state->view.color_plane[uv_plane].x = x; @@ -2219,9 +2209,13 @@ static int skl_check_plane_surface(struct intel_plane_state *plane_state) static bool skl_fb_scalable(const struct drm_framebuffer *fb) { + struct intel_display *display; + if (!fb) return false; + display = to_intel_display(fb->dev); + switch (fb->format->format) { case DRM_FORMAT_C8: return false; @@ -2229,7 +2223,7 @@ static bool skl_fb_scalable(const struct drm_framebuffer *fb) case DRM_FORMAT_ARGB16161616F: case DRM_FORMAT_XBGR16161616F: case DRM_FORMAT_ABGR16161616F: - return DISPLAY_VER(to_i915(fb->dev)) >= 11; + return DISPLAY_VER(display) >= 11; default: return true; } @@ -2237,12 +2231,12 @@ static bool skl_fb_scalable(const struct drm_framebuffer *fb) static void check_protection(struct intel_plane_state *plane_state) { - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane_state); + struct drm_i915_private *i915 = to_i915(display->drm); const struct drm_framebuffer *fb = plane_state->hw.fb; struct drm_gem_object *obj = intel_fb_bo(fb); - if (DISPLAY_VER(i915) < 11) + if (DISPLAY_VER(display) < 11) return; plane_state->decrypt = intel_pxp_key_check(i915->pxp, obj, false) == 0; @@ -2253,8 +2247,8 @@ static void check_protection(struct intel_plane_state *plane_state) static int skl_plane_check(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; int min_scale = DRM_PLANE_NO_SCALING; int max_scale = DRM_PLANE_NO_SCALING; @@ -2267,7 +2261,7 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state, /* use scaler when colorkey is not required */ if (!plane_state->ckey.flags && skl_fb_scalable(fb)) { min_scale = 1; - max_scale = skl_plane_max_scale(dev_priv, fb); + max_scale = skl_plane_max_scale(display, fb); } ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, @@ -2302,12 +2296,12 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state, plane_state->ctl = skl_plane_ctl(crtc_state, plane_state); - if (DISPLAY_VER(dev_priv) >= 10) + if (DISPLAY_VER(display) >= 10) plane_state->color_ctl = glk_plane_color_ctl(crtc_state, plane_state); if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && - icl_is_hdr_plane(dev_priv, plane->id)) + icl_is_hdr_plane(display, plane->id)) /* Enable and use MPEG-2 chroma siting */ plane_state->cus_ctl = PLANE_CUS_ENABLE | PLANE_CUS_HPHASE_0 | @@ -2323,37 +2317,37 @@ static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe) return pipe - PIPE_A + INTEL_FBC_A; } -static bool skl_plane_has_fbc(struct drm_i915_private *i915, +static bool skl_plane_has_fbc(struct intel_display *display, enum intel_fbc_id fbc_id, enum plane_id plane_id) { - if ((DISPLAY_RUNTIME_INFO(i915)->fbc_mask & BIT(fbc_id)) == 0) + if ((DISPLAY_RUNTIME_INFO(display)->fbc_mask & BIT(fbc_id)) == 0) return false; - if (DISPLAY_VER(i915) >= 20) - return icl_is_hdr_plane(i915, plane_id); + if (DISPLAY_VER(display) >= 20) + return icl_is_hdr_plane(display, plane_id); else return plane_id == PLANE_1; } -static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv, +static struct intel_fbc *skl_plane_fbc(struct intel_display *display, enum pipe pipe, enum plane_id plane_id) { enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(pipe); - if (skl_plane_has_fbc(dev_priv, fbc_id, plane_id)) - return dev_priv->display.fbc[fbc_id]; + if (skl_plane_has_fbc(display, fbc_id, plane_id)) + return display->fbc[fbc_id]; else return NULL; } -static bool skl_plane_has_planar(struct drm_i915_private *dev_priv, +static bool skl_plane_has_planar(struct intel_display *display, enum pipe pipe, enum plane_id plane_id) { /* Display WA #0870: skl, bxt */ - if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.skylake || display->platform.broxton) return false; - if (DISPLAY_VER(dev_priv) == 9 && pipe == PIPE_C) + if (DISPLAY_VER(display) == 9 && pipe == PIPE_C) return false; if (plane_id != PLANE_1 && plane_id != PLANE_2) @@ -2362,11 +2356,11 @@ static bool skl_plane_has_planar(struct drm_i915_private *dev_priv, return true; } -static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv, +static const u32 *skl_get_plane_formats(struct intel_display *display, enum pipe pipe, enum plane_id plane_id, int *num_formats) { - if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { + if (skl_plane_has_planar(display, pipe, plane_id)) { *num_formats = ARRAY_SIZE(skl_planar_formats); return skl_planar_formats; } else { @@ -2375,11 +2369,11 @@ static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv, } } -static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv, +static const u32 *glk_get_plane_formats(struct intel_display *display, enum pipe pipe, enum plane_id plane_id, int *num_formats) { - if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { + if (skl_plane_has_planar(display, pipe, plane_id)) { *num_formats = ARRAY_SIZE(glk_planar_formats); return glk_planar_formats; } else { @@ -2388,14 +2382,14 @@ static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv, } } -static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv, +static const u32 *icl_get_plane_formats(struct intel_display *display, enum pipe pipe, enum plane_id plane_id, int *num_formats) { - if (icl_is_hdr_plane(dev_priv, plane_id)) { + if (icl_is_hdr_plane(display, plane_id)) { *num_formats = ARRAY_SIZE(icl_hdr_plane_formats); return icl_hdr_plane_formats; - } else if (icl_is_nv12_y_plane(dev_priv, plane_id)) { + } else if (icl_is_nv12_y_plane(display, plane_id)) { *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats); return icl_sdr_y_plane_formats; } else { @@ -2613,46 +2607,46 @@ skl_plane_disable_flip_done(struct intel_plane *plane) spin_unlock_irq(&i915->irq_lock); } -static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915, +static bool skl_plane_has_rc_ccs(struct intel_display *display, enum pipe pipe, enum plane_id plane_id) { return pipe != PIPE_C && (plane_id == PLANE_1 || plane_id == PLANE_2); } -static u8 skl_plane_caps(struct drm_i915_private *i915, +static u8 skl_plane_caps(struct intel_display *display, enum pipe pipe, enum plane_id plane_id) { u8 caps = INTEL_PLANE_CAP_TILING_X | INTEL_PLANE_CAP_TILING_Y | INTEL_PLANE_CAP_TILING_Yf; - if (skl_plane_has_rc_ccs(i915, pipe, plane_id)) + if (skl_plane_has_rc_ccs(display, pipe, plane_id)) caps |= INTEL_PLANE_CAP_CCS_RC; return caps; } -static bool glk_plane_has_rc_ccs(struct drm_i915_private *i915, +static bool glk_plane_has_rc_ccs(struct intel_display *display, enum pipe pipe) { return pipe != PIPE_C; } -static u8 glk_plane_caps(struct drm_i915_private *i915, +static u8 glk_plane_caps(struct intel_display *display, enum pipe pipe, enum plane_id plane_id) { u8 caps = INTEL_PLANE_CAP_TILING_X | INTEL_PLANE_CAP_TILING_Y | INTEL_PLANE_CAP_TILING_Yf; - if (glk_plane_has_rc_ccs(i915, pipe)) + if (glk_plane_has_rc_ccs(display, pipe)) caps |= INTEL_PLANE_CAP_CCS_RC; return caps; } -static u8 icl_plane_caps(struct drm_i915_private *i915, +static u8 icl_plane_caps(struct intel_display *display, enum pipe pipe, enum plane_id plane_id) { return INTEL_PLANE_CAP_TILING_X | @@ -2661,21 +2655,20 @@ static u8 icl_plane_caps(struct drm_i915_private *i915, INTEL_PLANE_CAP_CCS_RC; } -static bool tgl_plane_has_mc_ccs(struct drm_i915_private *i915, +static bool tgl_plane_has_mc_ccs(struct intel_display *display, enum plane_id plane_id) { /* Wa_14010477008 */ - if (IS_DG1(i915) || IS_ROCKETLAKE(i915) || - (IS_TIGERLAKE(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_D0))) + if (display->platform.dg1 || display->platform.rocketlake || + (display->platform.tigerlake && IS_DISPLAY_STEP(display, STEP_A0, STEP_D0))) return false; return plane_id < PLANE_6; } -static u8 tgl_plane_caps(struct drm_i915_private *i915, +static u8 tgl_plane_caps(struct intel_display *display, enum pipe pipe, enum plane_id plane_id) { - struct intel_display *display = &i915->display; u8 caps = INTEL_PLANE_CAP_TILING_X | INTEL_PLANE_CAP_CCS_RC | INTEL_PLANE_CAP_CCS_RC_CC; @@ -2685,7 +2678,7 @@ static u8 tgl_plane_caps(struct drm_i915_private *i915, else caps |= INTEL_PLANE_CAP_TILING_Y; - if (tgl_plane_has_mc_ccs(i915, plane_id)) + if (tgl_plane_has_mc_ccs(display, plane_id)) caps |= INTEL_PLANE_CAP_CCS_MC; if (DISPLAY_VER(display) >= 14 && display->platform.dgfx) @@ -2695,10 +2688,9 @@ static u8 tgl_plane_caps(struct drm_i915_private *i915, } struct intel_plane * -skl_universal_plane_create(struct drm_i915_private *dev_priv, +skl_universal_plane_create(struct intel_display *display, enum pipe pipe, enum plane_id plane_id) { - struct intel_display *display = &dev_priv->display; const struct drm_plane_funcs *plane_funcs; struct intel_plane *plane; enum drm_plane_type plane_type; @@ -2718,21 +2710,21 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, plane->id = plane_id; plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id); - intel_fbc_add_plane(skl_plane_fbc(dev_priv, pipe, plane_id), plane); + intel_fbc_add_plane(skl_plane_fbc(display, pipe, plane_id), plane); - if (DISPLAY_VER(dev_priv) >= 30) { + if (DISPLAY_VER(display) >= 30) { plane->max_width = xe3_plane_max_width; plane->max_height = icl_plane_max_height; plane->min_cdclk = icl_plane_min_cdclk; - } else if (DISPLAY_VER(dev_priv) >= 11) { + } else if (DISPLAY_VER(display) >= 11) { plane->min_width = icl_plane_min_width; - if (icl_is_hdr_plane(dev_priv, plane_id)) + if (icl_is_hdr_plane(display, plane_id)) plane->max_width = icl_hdr_plane_max_width; else plane->max_width = icl_sdr_plane_max_width; plane->max_height = icl_plane_max_height; plane->min_cdclk = icl_plane_min_cdclk; - } else if (DISPLAY_VER(dev_priv) >= 10) { + } else if (DISPLAY_VER(display) >= 10) { plane->max_width = glk_plane_max_width; plane->max_height = skl_plane_max_height; plane->min_cdclk = glk_plane_min_cdclk; @@ -2742,20 +2734,20 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, plane->min_cdclk = skl_plane_min_cdclk; } - if (DISPLAY_VER(dev_priv) >= 13) + if (DISPLAY_VER(display) >= 13) plane->max_stride = adl_plane_max_stride; else plane->max_stride = skl_plane_max_stride; - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) plane->min_alignment = tgl_plane_min_alignment; else plane->min_alignment = skl_plane_min_alignment; if (intel_scanout_needs_vtd_wa(display)) - plane->vtd_guard = DISPLAY_VER(dev_priv) >= 10 ? 168 : 136; + plane->vtd_guard = DISPLAY_VER(display) >= 10 ? 168 : 136; - if (DISPLAY_VER(dev_priv) >= 11) { + if (DISPLAY_VER(display) >= 11) { plane->update_noarm = icl_plane_update_noarm; plane->update_arm = icl_plane_update_arm; plane->disable_arm = icl_plane_disable_arm; @@ -2767,33 +2759,33 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, plane->get_hw_state = skl_plane_get_hw_state; plane->check_plane = skl_plane_check; - if (HAS_ASYNC_FLIPS(dev_priv) && plane_id == PLANE_1) { - plane->need_async_flip_toggle_wa = IS_DISPLAY_VER(dev_priv, 9, 10); + if (HAS_ASYNC_FLIPS(display) && plane_id == PLANE_1) { + plane->need_async_flip_toggle_wa = IS_DISPLAY_VER(display, 9, 10); plane->async_flip = skl_plane_async_flip; plane->enable_flip_done = skl_plane_enable_flip_done; plane->disable_flip_done = skl_plane_disable_flip_done; - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) plane->can_async_flip = tgl_plane_can_async_flip; - else if (DISPLAY_VER(dev_priv) == 11) + else if (DISPLAY_VER(display) == 11) plane->can_async_flip = icl_plane_can_async_flip; else plane->can_async_flip = skl_plane_can_async_flip; } - if (DISPLAY_VER(dev_priv) >= 11) - formats = icl_get_plane_formats(dev_priv, pipe, + if (DISPLAY_VER(display) >= 11) + formats = icl_get_plane_formats(display, pipe, plane_id, &num_formats); - else if (DISPLAY_VER(dev_priv) >= 10) - formats = glk_get_plane_formats(dev_priv, pipe, + else if (DISPLAY_VER(display) >= 10) + formats = glk_get_plane_formats(display, pipe, plane_id, &num_formats); else - formats = skl_get_plane_formats(dev_priv, pipe, + formats = skl_get_plane_formats(display, pipe, plane_id, &num_formats); - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) plane_funcs = &tgl_plane_funcs; - else if (DISPLAY_VER(dev_priv) == 11) + else if (DISPLAY_VER(display) == 11) plane_funcs = &icl_plane_funcs; else plane_funcs = &skl_plane_funcs; @@ -2803,24 +2795,24 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, else plane_type = DRM_PLANE_TYPE_OVERLAY; - if (DISPLAY_VER(dev_priv) >= 12) - caps = tgl_plane_caps(dev_priv, pipe, plane_id); - else if (DISPLAY_VER(dev_priv) == 11) - caps = icl_plane_caps(dev_priv, pipe, plane_id); - else if (DISPLAY_VER(dev_priv) == 10) - caps = glk_plane_caps(dev_priv, pipe, plane_id); + if (DISPLAY_VER(display) >= 12) + caps = tgl_plane_caps(display, pipe, plane_id); + else if (DISPLAY_VER(display) == 11) + caps = icl_plane_caps(display, pipe, plane_id); + else if (DISPLAY_VER(display) == 10) + caps = glk_plane_caps(display, pipe, plane_id); else - caps = skl_plane_caps(dev_priv, pipe, plane_id); + caps = skl_plane_caps(display, pipe, plane_id); /* FIXME: xe has problems with AUX */ - if (!IS_ENABLED(I915) && !HAS_FLAT_CCS(dev_priv)) + if (!IS_ENABLED(I915) && !HAS_FLAT_CCS(to_i915(display->drm))) caps &= ~(INTEL_PLANE_CAP_CCS_RC | INTEL_PLANE_CAP_CCS_RC_CC | INTEL_PLANE_CAP_CCS_MC); modifiers = intel_fb_plane_get_modifiers(display, caps); - ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, + ret = drm_universal_plane_init(display->drm, &plane->base, 0, plane_funcs, formats, num_formats, modifiers, plane_type, @@ -2832,14 +2824,14 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, if (ret) goto fail; - if (DISPLAY_VER(dev_priv) >= 13) + if (DISPLAY_VER(display) >= 13) supported_rotations = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; else supported_rotations = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) supported_rotations |= DRM_MODE_REFLECT_X; drm_plane_create_rotation_property(&plane->base, @@ -2848,7 +2840,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, supported_csc = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709); - if (DISPLAY_VER(dev_priv) >= 10) + if (DISPLAY_VER(display) >= 10) supported_csc |= BIT(DRM_COLOR_YCBCR_BT2020); drm_plane_create_color_properties(&plane->base, @@ -2866,10 +2858,10 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, drm_plane_create_zpos_immutable_property(&plane->base, plane_id); - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) drm_plane_enable_fb_damage_clips(&plane->base); - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) drm_plane_create_scaling_filter_property(&plane->base, BIT(DRM_SCALING_FILTER_DEFAULT) | BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR)); @@ -2890,8 +2882,6 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, { struct intel_display *display = to_intel_display(crtc); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane *plane = to_intel_plane(crtc->base.primary); enum plane_id plane_id = plane->id; enum pipe pipe; @@ -2905,35 +2895,35 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, if (!plane->get_hw_state(plane, &pipe)) return; - drm_WARN_ON(dev, pipe != crtc->pipe); + drm_WARN_ON(display->drm, pipe != crtc->pipe); if (crtc_state->joiner_pipes) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Unsupported joiner configuration for initial FB\n"); return; } intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); if (!intel_fb) { - drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n"); + drm_dbg_kms(display->drm, "failed to alloc fb\n"); return; } fb = &intel_fb->base; - fb->dev = dev; + fb->dev = display->drm; - val = intel_de_read(dev_priv, PLANE_CTL(pipe, plane_id)); + val = intel_de_read(display, PLANE_CTL(pipe, plane_id)); - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) pixel_format = val & PLANE_CTL_FORMAT_MASK_ICL; else pixel_format = val & PLANE_CTL_FORMAT_MASK_SKL; - if (DISPLAY_VER(dev_priv) >= 10) { + if (DISPLAY_VER(display) >= 10) { u32 color_ctl; - color_ctl = intel_de_read(dev_priv, PLANE_COLOR_CTL(pipe, plane_id)); + color_ctl = intel_de_read(display, PLANE_COLOR_CTL(pipe, plane_id)); alpha = REG_FIELD_GET(PLANE_COLOR_ALPHA_MASK, color_ctl); } else { alpha = REG_FIELD_GET(PLANE_CTL_ALPHA_MASK, val); @@ -2955,14 +2945,14 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, case PLANE_CTL_TILED_Y: plane_config->tiling = I915_TILING_Y; if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE) - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) fb->modifier = I915_FORMAT_MOD_4_TILED_MTL_RC_CCS; - else if (DISPLAY_VER(dev_priv) >= 12) + else if (DISPLAY_VER(display) >= 12) fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS; else fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS; else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE) - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) fb->modifier = I915_FORMAT_MOD_4_TILED_MTL_MC_CCS; else fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS; @@ -2994,9 +2984,9 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, goto error; } - if (!dev_priv->display.params.enable_dpt && + if (!display->params.enable_dpt && intel_fb_modifier_uses_dpt(display, fb->modifier)) { - drm_dbg_kms(&dev_priv->drm, "DPT disabled, skipping initial FB\n"); + drm_dbg_kms(display->drm, "DPT disabled, skipping initial FB\n"); goto error; } @@ -3019,24 +3009,24 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, break; } - if (DISPLAY_VER(dev_priv) >= 11 && val & PLANE_CTL_FLIP_HORIZONTAL) + if (DISPLAY_VER(display) >= 11 && val & PLANE_CTL_FLIP_HORIZONTAL) plane_config->rotation |= DRM_MODE_REFLECT_X; /* 90/270 degree rotation would require extra work */ if (drm_rotation_90_or_270(plane_config->rotation)) goto error; - base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & PLANE_SURF_ADDR_MASK; + base = intel_de_read(display, PLANE_SURF(pipe, plane_id)) & PLANE_SURF_ADDR_MASK; plane_config->base = base; - offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id)); - drm_WARN_ON(&dev_priv->drm, offset != 0); + offset = intel_de_read(display, PLANE_OFFSET(pipe, plane_id)); + drm_WARN_ON(display->drm, offset != 0); - val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id)); + val = intel_de_read(display, PLANE_SIZE(pipe, plane_id)); fb->height = REG_FIELD_GET(PLANE_HEIGHT_MASK, val) + 1; fb->width = REG_FIELD_GET(PLANE_WIDTH_MASK, val) + 1; - val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id)); + val = intel_de_read(display, PLANE_STRIDE(pipe, plane_id)); stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0); fb->pitches[0] = REG_FIELD_GET(PLANE_STRIDE__MASK, val) * stride_mult; @@ -3045,7 +3035,7 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, plane_config->size = fb->pitches[0] * aligned_height; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", crtc->base.name, plane->base.name, fb->width, fb->height, fb->format->cpp[0] * 8, base, fb->pitches[0], @@ -3061,7 +3051,7 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, bool skl_fixup_initial_plane_config(struct intel_crtc *crtc, const struct intel_initial_plane_config *plane_config) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_plane *plane = to_intel_plane(crtc->base.primary); const struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); @@ -3081,7 +3071,7 @@ bool skl_fixup_initial_plane_config(struct intel_crtc *crtc, if (plane_config->base == base) return false; - intel_de_write(i915, PLANE_SURF(pipe, plane_id), base); + intel_de_write(display, PLANE_SURF(pipe, plane_id), base); return true; } diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.h b/drivers/gpu/drm/i915/display/skl_universal_plane.h index 18b41d13f0bde..0ce240e9ca5ae 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.h +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.h @@ -8,8 +8,8 @@ #include -struct drm_i915_private; struct intel_crtc; +struct intel_display; struct intel_initial_plane_config; struct intel_plane_state; struct skl_ddb_entry; @@ -19,7 +19,7 @@ enum pipe; enum plane_id; struct intel_plane * -skl_universal_plane_create(struct drm_i915_private *dev_priv, +skl_universal_plane_create(struct intel_display *display, enum pipe pipe, enum plane_id plane_id); void skl_get_initial_plane_config(struct intel_crtc *crtc, @@ -32,10 +32,10 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha); int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state, int *x, int *y, u32 *offset); -bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv, +bool icl_is_nv12_y_plane(struct intel_display *display, enum plane_id plane_id); u8 icl_hdr_plane_mask(void); -bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id); +bool icl_is_hdr_plane(struct intel_display *display, enum plane_id plane_id); u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state, int color_plane); From 37bd8e1b9d0fcc44cafbcc2e08ee7812d21ac726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:32 +0200 Subject: [PATCH 188/284] drm/i915: Use DRM_RECT_FMT & co. for plane debugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch the plane debugs to use DRM_RECT_FMT & co. instead of drm_rect_debug_print() so that the debugs go on the same line. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-12-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_atomic_plane.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 651f81ed85abc..3a474652abaad 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -944,9 +944,9 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); if (hscale < 0 || vscale < 0) { - drm_dbg_kms(&i915->drm, "Invalid scaling of plane\n"); - drm_rect_debug_print("src: ", src, true); - drm_rect_debug_print("dst: ", dst, false); + drm_dbg_kms(&i915->drm, + "Invalid scaling of plane " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT "\n", + DRM_RECT_FP_ARG(src), DRM_RECT_ARG(dst)); return -ERANGE; } @@ -960,9 +960,8 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, if (!can_position && plane_state->uapi.visible && !drm_rect_equals(dst, clip)) { - drm_dbg_kms(&i915->drm, "Plane must cover entire CRTC\n"); - drm_rect_debug_print("dst: ", dst, false); - drm_rect_debug_print("clip: ", clip, false); + drm_dbg_kms(&i915->drm, "Plane (" DRM_RECT_FMT ") must cover entire CRTC (" DRM_RECT_FMT ")\n", + DRM_RECT_ARG(dst), DRM_RECT_ARG(clip)); return -EINVAL; } From 73a0d4b3672db15f5c8d4dac7c58a993b026ec7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Feb 2025 20:55:33 +0200 Subject: [PATCH 189/284] drm/i915: Pimp plane debugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include the standard "[PLANE:%d:s]" stuff in all plane debugs (or rather all I was able to find), to provide better information on which plane we're actually talking about. There are a few spots where we care about the CRTC as well, so include that where appropriate. Reviewed-by: Chaitanya Kumar Borah Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250206185533.32306-13-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/i9xx_plane.c | 18 ++++-- .../gpu/drm/i915/display/intel_atomic_plane.c | 17 ++++-- drivers/gpu/drm/i915/display/intel_cursor.c | 33 ++++++---- drivers/gpu/drm/i915/display/intel_display.c | 9 +-- .../drm/i915/display/skl_universal_plane.c | 60 ++++++++++++------- 5 files changed, 90 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index c3ed903d55824..aef8d8b7ea85f 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -244,8 +244,12 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) src_y = plane_state->uapi.src.y1 >> 16; /* Undocumented hardware limit on i965/g4x/vlv/chv */ - if (HAS_GMCH(display) && fb->format->cpp[0] == 8 && src_w > 2048) + if (HAS_GMCH(display) && fb->format->cpp[0] == 8 && src_w > 2048) { + drm_dbg_kms(display->drm, + "[PLANE:%d:%s] plane too wide (%d) for 64bpp\n", + plane->base.base.id, plane->base.name, src_w); return -EINVAL; + } intel_add_fb_offsets(&src_x, &src_y, plane_state, 0); @@ -273,7 +277,8 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].mapping_stride) { if (offset == 0) { drm_dbg_kms(display->drm, - "Unable to find suitable display surface offset due to X-tiling\n"); + "[PLANE:%d:%s] unable to find suitable display surface offset due to X-tiling\n", + plane->base.base.id, plane->base.name); return -EINVAL; } @@ -1162,10 +1167,11 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, plane_config->size = fb->pitches[0] * aligned_height; drm_dbg_kms(display->drm, - "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", - crtc->base.name, plane->base.name, fb->width, fb->height, - fb->format->cpp[0] * 8, base, fb->pitches[0], - plane_config->size); + "[CRTC:%d:%s][PLANE:%d:%s] with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", + crtc->base.base.id, crtc->base.name, + plane->base.base.id, plane->base.name, + fb->width, fb->height, fb->format->cpp[0] * 8, + base, fb->pitches[0], plane_config->size); plane_config->fb = intel_fb; } diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 3a474652abaad..8a49d87d9bd9c 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -926,6 +926,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, bool can_position) { struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); struct drm_framebuffer *fb = plane_state->hw.fb; struct drm_rect *src = &plane_state->uapi.src; struct drm_rect *dst = &plane_state->uapi.dst; @@ -945,7 +946,8 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); if (hscale < 0 || vscale < 0) { drm_dbg_kms(&i915->drm, - "Invalid scaling of plane " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT "\n", + "[PLANE:%d:%s] invalid scaling "DRM_RECT_FP_FMT " -> " DRM_RECT_FMT "\n", + plane->base.base.id, plane->base.name, DRM_RECT_FP_ARG(src), DRM_RECT_ARG(dst)); return -ERANGE; } @@ -960,7 +962,9 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, if (!can_position && plane_state->uapi.visible && !drm_rect_equals(dst, clip)) { - drm_dbg_kms(&i915->drm, "Plane (" DRM_RECT_FMT ") must cover entire CRTC (" DRM_RECT_FMT ")\n", + drm_dbg_kms(&i915->drm, + "[PLANE:%d:%s] plane (" DRM_RECT_FMT ") must cover entire CRTC (" DRM_RECT_FMT ")\n", + plane->base.base.id, plane->base.name, DRM_RECT_ARG(dst), DRM_RECT_ARG(clip)); return -EINVAL; } @@ -974,6 +978,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) { struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); const struct drm_framebuffer *fb = plane_state->hw.fb; struct drm_rect *src = &plane_state->uapi.src; u32 src_x, src_y, src_w, src_h, hsub, vsub; @@ -1029,13 +1034,17 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) hsub = vsub = max(hsub, vsub); if (src_x % hsub || src_w % hsub) { - drm_dbg_kms(&i915->drm, "src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n", + drm_dbg_kms(&i915->drm, + "[PLANE:%d:%s] src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n", + plane->base.base.id, plane->base.name, src_x, src_w, hsub, str_yes_no(rotated)); return -EINVAL; } if (src_y % vsub || src_h % vsub) { - drm_dbg_kms(&i915->drm, "src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n", + drm_dbg_kms(&i915->drm, + "[PLANE:%d:%s] src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n", + plane->base.base.id, plane->base.name, src_y, src_h, vsub, str_yes_no(rotated)); return -EINVAL; } diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 4cd48d54164d6..f31efac89e95a 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -92,6 +92,7 @@ static bool intel_cursor_size_ok(const struct intel_plane_state *plane_state) static int intel_cursor_check_surface(struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); unsigned int rotation = plane_state->hw.rotation; int src_x, src_y; u32 offset; @@ -113,7 +114,8 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state) if (src_x != 0 || src_y != 0) { drm_dbg_kms(display->drm, - "Arbitrary cursor panning not supported\n"); + "[PLANE:%d:%s] arbitrary cursor panning not supported\n", + plane->base.base.id, plane->base.name); return -EINVAL; } @@ -144,13 +146,15 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_rect src = plane_state->uapi.src; const struct drm_rect dst = plane_state->uapi.dst; int ret; if (fb && fb->modifier != DRM_FORMAT_MOD_LINEAR) { - drm_dbg_kms(display->drm, "cursor cannot be tiled\n"); + drm_dbg_kms(display->drm, "[PLANE:%d:%s] cursor cannot be tiled\n", + plane->base.base.id, plane->base.name); return -EINVAL; } @@ -232,6 +236,7 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); const struct drm_framebuffer *fb = plane_state->hw.fb; int ret; @@ -246,7 +251,8 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state, /* Check for which cursor types we support */ if (!i845_cursor_size_ok(plane_state)) { drm_dbg_kms(display->drm, - "Cursor dimension %dx%d not supported\n", + "[PLANE:%d:%s] cursor dimension %dx%d not supported\n", + plane->base.base.id, plane->base.name, drm_rect_width(&plane_state->uapi.dst), drm_rect_height(&plane_state->uapi.dst)); return -EINVAL; @@ -262,7 +268,8 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state, case 2048: break; default: - drm_dbg_kms(display->drm, "Invalid cursor stride (%u)\n", + drm_dbg_kms(display->drm, "[PLANE:%d:%s] invalid cursor stride (%u)\n", + plane->base.base.id, plane->base.name, fb->pitches[0]); return -EINVAL; } @@ -489,10 +496,11 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state, /* Check for which cursor types we support */ if (!i9xx_cursor_size_ok(plane_state)) { - drm_dbg(display->drm, - "Cursor dimension %dx%d not supported\n", - drm_rect_width(&plane_state->uapi.dst), - drm_rect_height(&plane_state->uapi.dst)); + drm_dbg_kms(display->drm, + "[PLANE:%d:%s] cursor dimension %dx%d not supported\n", + plane->base.base.id, plane->base.name, + drm_rect_width(&plane_state->uapi.dst), + drm_rect_height(&plane_state->uapi.dst)); return -EINVAL; } @@ -502,9 +510,9 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state, if (fb->pitches[0] != drm_rect_width(&plane_state->uapi.dst) * fb->format->cpp[0]) { drm_dbg_kms(display->drm, - "Invalid cursor stride (%u) (cursor width %d)\n", - fb->pitches[0], - drm_rect_width(&plane_state->uapi.dst)); + "[PLANE:%d:%s] invalid cursor stride (%u) (cursor width %d)\n", + plane->base.base.id, plane->base.name, + fb->pitches[0], drm_rect_width(&plane_state->uapi.dst)); return -EINVAL; } @@ -521,7 +529,8 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state, if (display->platform.cherryview && pipe == PIPE_C && plane_state->uapi.visible && plane_state->uapi.dst.x1 < 0) { drm_dbg_kms(display->drm, - "CHV cursor C not allowed to straddle the left screen edge\n"); + "[PLANE:%d:%s] cursor not allowed to straddle the left screen edge\n", + plane->base.base.id, plane->base.name); return -EINVAL; } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 26b674909d19d..97a0bf1c2dedc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4495,9 +4495,9 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, if (!linked_state) { drm_dbg_kms(&dev_priv->drm, - "Need %d free Y planes for planar YUV\n", + "[CRTC:%d:%s] need %d free Y planes for planar YUV\n", + crtc->base.base.id, crtc->base.name, hweight8(crtc_state->nv12_planes)); - return -EINVAL; } @@ -4512,8 +4512,9 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, crtc_state->data_rate_y[plane->id]; crtc_state->rel_data_rate[linked->id] = crtc_state->rel_data_rate_y[plane->id]; - drm_dbg_kms(&dev_priv->drm, "Using %s as Y plane for %s\n", - linked->base.name, plane->base.name); + drm_dbg_kms(&dev_priv->drm, "UV plane [PLANE:%d:%s] using [PLANE:%d:%s] as Y plane\n", + plane->base.base.id, plane->base.name, + linked->base.base.id, linked->base.name); /* Copy parameters to slave plane */ linked_state->ctl = plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index f8d3a79a96ff6..eb85d3d6cdc3c 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1706,6 +1706,7 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; @@ -1715,15 +1716,16 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) && intel_fb_is_ccs_modifier(fb->modifier)) { drm_dbg_kms(display->drm, - "RC support only with 0/180 degree rotation (%x)\n", - rotation); + "[PLANE:%d:%s] RC support only with 0/180 degree rotation (%x)\n", + plane->base.base.id, plane->base.name, rotation); return -EINVAL; } if (rotation & DRM_MODE_REFLECT_X && fb->modifier == DRM_FORMAT_MOD_LINEAR) { drm_dbg_kms(display->drm, - "horizontal flip is not supported with linear surface formats\n"); + "[PLANE:%d:%s] horizontal flip is not supported with linear surface formats\n", + plane->base.base.id, plane->base.name); return -EINVAL; } @@ -1734,14 +1736,16 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, intel_fb_is_tile4_modifier(fb->modifier) && DISPLAY_VER(display) >= 20) { drm_dbg_kms(display->drm, - "horizontal flip is not supported with tile4 surface formats\n"); + "[PLANE:%d:%s] horizontal flip is not supported with tile4 surface formats\n", + plane->base.base.id, plane->base.name); return -EINVAL; } if (drm_rotation_90_or_270(rotation)) { if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) { drm_dbg_kms(display->drm, - "Y/Yf tiling required for 90/270!\n"); + "[PLANE:%d:%s] Y/Yf tiling required for 90/270!\n", + plane->base.base.id, plane->base.name); return -EINVAL; } @@ -1765,8 +1769,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, case DRM_FORMAT_XVYU12_16161616: case DRM_FORMAT_XVYU16161616: drm_dbg_kms(display->drm, - "Unsupported pixel format %p4cc for 90/270!\n", - &fb->format->format); + "[PLANE:%d:%s] unsupported pixel format %p4cc for 90/270!\n", + plane->base.base.id, plane->base.name, &fb->format->format); return -EINVAL; default: break; @@ -1779,7 +1783,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, fb->modifier != DRM_FORMAT_MOD_LINEAR && fb->modifier != I915_FORMAT_MOD_X_TILED) { drm_dbg_kms(display->drm, - "Y/Yf tiling not supported in IF-ID mode\n"); + "[PLANE:%d:%s] Y/Yf tiling not supported in IF-ID mode\n", + plane->base.base.id, plane->base.name); return -EINVAL; } @@ -1788,7 +1793,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, plane_state->ckey.flags & I915_SET_COLORKEY_SOURCE && intel_format_is_p01x(fb->format->format)) { drm_dbg_kms(display->drm, - "Source color keying not supported with P01x formats\n"); + "[PLANE:%d:%s] source color keying not supported with P01x formats\n", + plane->base.base.id, plane->base.name); return -EINVAL; } @@ -1799,6 +1805,7 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s const struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); int crtc_x = plane_state->uapi.dst.x1; int crtc_w = drm_rect_width(&plane_state->uapi.dst); int pipe_src_w = drm_rect_width(&crtc_state->pipe_src); @@ -1815,7 +1822,8 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s if (DISPLAY_VER(display) == 10 && (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) { drm_dbg_kms(display->drm, - "requested plane X %s position %d invalid (valid range %d-%d)\n", + "[PLANE:%d:%s] requested plane X %s position %d invalid (valid range %d-%d)\n", + plane->base.base.id, plane->base.name, crtc_x + crtc_w < 4 ? "end" : "start", crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x, 4, pipe_src_w - 4); @@ -1828,6 +1836,7 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int rotation = plane_state->hw.rotation; int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; @@ -1837,7 +1846,9 @@ static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_s src_w & 3 && (rotation == DRM_MODE_ROTATE_270 || rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) { - drm_dbg_kms(display->drm, "src width must be multiple of 4 for rotated planar YUV\n"); + drm_dbg_kms(display->drm, + "[PLANE:%d:%s] src width must be multiple of 4 for rotated planar YUV\n", + plane->base.base.id, plane->base.name); return -EINVAL; } @@ -1977,7 +1988,8 @@ int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state, while ((*x + w) * cpp > plane_state->view.color_plane[0].mapping_stride) { if (*offset == 0) { drm_dbg_kms(display->drm, - "Unable to find suitable display surface offset due to X-tiling\n"); + "[PLANE:%d:%s] unable to find suitable display surface offset due to X-tiling\n", + plane->base.base.id, plane->base.name); return -EINVAL; } @@ -2010,7 +2022,8 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state) if (w > max_width || w < min_width || h > max_height || h < 1) { drm_dbg_kms(display->drm, - "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n", + "[PLANE:%d:%s] requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n", + plane->base.base.id, plane->base.name, w, h, min_width, max_width, max_height); return -EINVAL; } @@ -2037,7 +2050,8 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state) if (x != plane_state->view.color_plane[aux_plane].x || y != plane_state->view.color_plane[aux_plane].y) { drm_dbg_kms(display->drm, - "Unable to find suitable display surface offset due to CCS\n"); + "[PLANE:%d:%s] unable to find suitable display surface offset due to CCS\n", + plane->base.base.id, plane->base.name); return -EINVAL; } } @@ -2081,7 +2095,8 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) /* FIXME not quite sure how/if these apply to the chroma plane */ if (w > max_width || h > max_height) { drm_dbg_kms(display->drm, - "CbCr source size %dx%d too big (limit %dx%d)\n", + "[PLANE:%d:%s] CbCr source size %dx%d too big (limit %dx%d)\n", + plane->base.base.id, plane->base.name, w, h, max_width, max_height); return -EINVAL; } @@ -2115,7 +2130,8 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) if (x != plane_state->view.color_plane[ccs_plane].x || y != plane_state->view.color_plane[ccs_plane].y) { drm_dbg_kms(display->drm, - "Unable to find suitable display surface offset due to CCS\n"); + "[PLANE:%d:%s] unable to find suitable display surface offset due to CCS\n", + plane->base.base.id, plane->base.name); return -EINVAL; } } @@ -2899,7 +2915,8 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, if (crtc_state->joiner_pipes) { drm_dbg_kms(display->drm, - "Unsupported joiner configuration for initial FB\n"); + "[CRTC:%d:%s] Unsupported joiner configuration for initial FB\n", + crtc->base.base.id, crtc->base.name); return; } @@ -3036,10 +3053,11 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, plane_config->size = fb->pitches[0] * aligned_height; drm_dbg_kms(display->drm, - "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", - crtc->base.name, plane->base.name, fb->width, fb->height, - fb->format->cpp[0] * 8, base, fb->pitches[0], - plane_config->size); + "[CRTC:%d:%s][PLANE:%d:%s] with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", + crtc->base.base.id, crtc->base.name, + plane->base.base.id, plane->base.name, + fb->width, fb->height, fb->format->cpp[0] * 8, + base, fb->pitches[0], plane_config->size); plane_config->fb = intel_fb; return; From 4929402a747889f650745905433c26b27284efc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 11 Feb 2025 02:01:32 +0200 Subject: [PATCH 190/284] drm/i915: Fix CONFIG_DRM_I915_DEBUG_RUNTIME_PM=n build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looks like I missed one of myriad CONFIG_DRM_I915_DEBUG_RUNTIME_PM=n special cases when converting the intel_display_power_{get,put}() code to use struct intel_display. Only noticed after the fact when building a EXPERT=n kernel :/ Fixes: 5dcfda5cfa42 ("drm/i915: Convert intel_display_power_{get,put}*() to intel_display") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250211000135.6096-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_power.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index b5d67b6c73cff..1e4e113999fb4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -217,7 +217,7 @@ intel_display_power_put_async_delay(struct intel_display *display, __intel_display_power_put_async(display, domain, wakeref, delay_ms); } #else -void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, +void intel_display_power_put_unchecked(struct intel_display *display, enum intel_display_power_domain domain); static inline void From f2d236766f01ac56799070cc076518f5a7bdbbaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 11 Feb 2025 02:01:33 +0200 Subject: [PATCH 191/284] drm/i915: Continue intel_display_power struct intel_display conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the remaining intel_display_power.h interfaces to take struct intel_display instead of struct drm_i915_private. intel_display_power.c still has some internal uses due to i915->runtime_pm. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250211000135.6096-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- drivers/gpu/drm/i915/display/g4x_hdmi.c | 2 +- drivers/gpu/drm/i915/display/intel_ddi.c | 10 +++---- drivers/gpu/drm/i915/display/intel_display.c | 6 ++-- .../drm/i915/display/intel_display_debugfs.c | 3 +- .../drm/i915/display/intel_display_power.c | 30 +++++++------------ .../drm/i915/display/intel_display_power.h | 15 +++++----- .../i915/display/intel_display_power_well.c | 3 +- drivers/gpu/drm/i915/display/intel_tc.c | 12 ++++---- drivers/gpu/drm/i915/display/skl_watermark.c | 16 +++++----- drivers/gpu/drm/i915/display/skl_watermark.h | 3 +- 11 files changed, 46 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 7eb5b4915f2c2..d3b5ead188ba7 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -1389,7 +1389,7 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv, dig_port->max_lanes = 4; intel_encoder->type = INTEL_OUTPUT_DP; - intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port); + intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(display, port); if (IS_CHERRYVIEW(dev_priv)) { if (port == PORT_D) intel_encoder->pipe_mask = BIT(PIPE_C); diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 7f13cf9b1a2e3..9e1ca77673924 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -763,7 +763,7 @@ bool g4x_hdmi_init(struct drm_i915_private *dev_priv, intel_encoder->shutdown = intel_hdmi_encoder_shutdown; intel_encoder->type = INTEL_OUTPUT_HDMI; - intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port); + intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(display, port); intel_encoder->port = port; if (IS_CHERRYVIEW(dev_priv)) { if (port == PORT_D) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 6b274b7a5c3f5..b889aa68d3934 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -935,7 +935,7 @@ static enum intel_display_power_domain intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); /* * ICL+ HW requires corresponding AUX IOs to be powered up for PSR with @@ -951,8 +951,8 @@ intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port, * extra wells. */ if (intel_psr_needs_aux_io_power(&dig_port->base, crtc_state)) - return intel_display_power_aux_io_domain(i915, dig_port->aux_ch); - else if (DISPLAY_VER(i915) < 14 && + return intel_display_power_aux_io_domain(display, dig_port->aux_ch); + else if (DISPLAY_VER(display) < 14 && (intel_crtc_has_dp_encoder(crtc_state) || intel_encoder_is_tc(&dig_port->base))) return intel_aux_power_domain(dig_port); @@ -5257,7 +5257,7 @@ void intel_ddi_init(struct intel_display *display, encoder->get_power_domains = intel_ddi_get_power_domains; encoder->type = INTEL_OUTPUT_DDI; - encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port); + encoder->power_domain = intel_display_power_ddi_lanes_domain(display, port); encoder->port = port; encoder->cloneable = 0; encoder->pipe_mask = ~0; @@ -5408,7 +5408,7 @@ void intel_ddi_init(struct intel_display *display, } drm_WARN_ON(&dev_priv->drm, port > PORT_I); - dig_port->ddi_io_power_domain = intel_display_power_ddi_io_domain(dev_priv, port); + dig_port->ddi_io_power_domain = intel_display_power_ddi_io_domain(display, port); if (DISPLAY_VER(dev_priv) >= 11) { if (intel_encoder_is_tc(encoder)) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 97a0bf1c2dedc..e19fc44b43ea1 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2112,12 +2112,12 @@ enum tc_port intel_encoder_to_tc(struct intel_encoder *encoder) enum intel_display_power_domain intel_aux_power_domain(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); if (intel_tc_port_in_tbt_alt_mode(dig_port)) - return intel_display_power_tbt_aux_domain(i915, dig_port->aux_ch); + return intel_display_power_tbt_aux_domain(display, dig_port->aux_ch); - return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch); + return intel_display_power_legacy_aux_domain(display, dig_port->aux_ch); } static void get_crtc_power_domains(struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 89e5eea90be85..09a8f667366d6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -158,8 +158,9 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) static int i915_power_domain_info(struct seq_file *m, void *unused) { struct drm_i915_private *i915 = node_to_i915(m->private); + struct intel_display *display = &i915->display; - intel_display_power_debug(i915, m); + intel_display_power_debug(display, m); return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index cfc5c0b4f9072..d93f43d145a96 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1056,10 +1056,9 @@ static void gen9_dbuf_slice_set(struct intel_display *display, slice, str_enable_disable(enable)); } -void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv, +void gen9_dbuf_slices_update(struct intel_display *display, u8 req_slices) { - struct intel_display *display = &dev_priv->display; struct i915_power_domains *power_domains = &display->power.domains; u8 slice_mask = DISPLAY_INFO(display)->dbuf.slice_mask; enum dbuf_slice slice; @@ -1090,10 +1089,9 @@ void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv, static void gen9_dbuf_enable(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u8 slices_mask; - display->dbuf.enabled_slices = intel_enabled_dbuf_slices_mask(dev_priv); + display->dbuf.enabled_slices = intel_enabled_dbuf_slices_mask(display); slices_mask = BIT(DBUF_S1) | display->dbuf.enabled_slices; @@ -1104,14 +1102,12 @@ static void gen9_dbuf_enable(struct intel_display *display) * Just power up at least 1 slice, we will * figure out later which slices we have and what we need. */ - gen9_dbuf_slices_update(dev_priv, slices_mask); + gen9_dbuf_slices_update(display, slices_mask); } static void gen9_dbuf_disable(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - gen9_dbuf_slices_update(dev_priv, 0); + gen9_dbuf_slices_update(display, 0); if (DISPLAY_VER(display) >= 14) intel_pmdemand_program_dbuf(display, 0); @@ -2315,9 +2311,8 @@ void intel_display_power_resume(struct intel_display *display) } } -void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m) +void intel_display_power_debug(struct intel_display *display, struct seq_file *m) { - struct intel_display *display = &i915->display; struct i915_power_domains *power_domains = &display->power.domains; int i; @@ -2498,9 +2493,8 @@ intel_port_domains_for_port(struct intel_display *display, enum port port) } enum intel_display_power_domain -intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port) +intel_display_power_ddi_io_domain(struct intel_display *display, enum port port) { - struct intel_display *display = &i915->display; const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(display, port); if (drm_WARN_ON(display->drm, !domains || domains->ddi_io == POWER_DOMAIN_INVALID)) @@ -2510,9 +2504,8 @@ intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port) } enum intel_display_power_domain -intel_display_power_ddi_lanes_domain(struct drm_i915_private *i915, enum port port) +intel_display_power_ddi_lanes_domain(struct intel_display *display, enum port port) { - struct intel_display *display = &i915->display; const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(display, port); if (drm_WARN_ON(display->drm, !domains || domains->ddi_lanes == POWER_DOMAIN_INVALID)) @@ -2537,9 +2530,8 @@ intel_port_domains_for_aux_ch(struct intel_display *display, enum aux_ch aux_ch) } enum intel_display_power_domain -intel_display_power_aux_io_domain(struct drm_i915_private *i915, enum aux_ch aux_ch) +intel_display_power_aux_io_domain(struct intel_display *display, enum aux_ch aux_ch) { - struct intel_display *display = &i915->display; const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(display, aux_ch); if (drm_WARN_ON(display->drm, !domains || domains->aux_io == POWER_DOMAIN_INVALID)) @@ -2549,9 +2541,8 @@ intel_display_power_aux_io_domain(struct drm_i915_private *i915, enum aux_ch aux } enum intel_display_power_domain -intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch aux_ch) +intel_display_power_legacy_aux_domain(struct intel_display *display, enum aux_ch aux_ch) { - struct intel_display *display = &i915->display; const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(display, aux_ch); if (drm_WARN_ON(display->drm, !domains || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID)) @@ -2561,9 +2552,8 @@ intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch } enum intel_display_power_domain -intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch aux_ch) +intel_display_power_tbt_aux_domain(struct intel_display *display, enum aux_ch aux_ch) { - struct intel_display *display = &i915->display; const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(display, aux_ch); if (drm_WARN_ON(display->drm, !domains || domains->aux_tbt == POWER_DOMAIN_INVALID)) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 1e4e113999fb4..a3a5c1be8bab1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -13,7 +13,6 @@ enum aux_ch; enum port; -struct drm_i915_private; struct i915_power_well; struct intel_display; struct intel_encoder; @@ -268,18 +267,18 @@ intel_display_power_put_all_in_set(struct intel_display *display, intel_display_power_put_mask_in_set(display, power_domain_set, &power_domain_set->mask); } -void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m); +void intel_display_power_debug(struct intel_display *display, struct seq_file *m); enum intel_display_power_domain -intel_display_power_ddi_lanes_domain(struct drm_i915_private *i915, enum port port); +intel_display_power_ddi_lanes_domain(struct intel_display *display, enum port port); enum intel_display_power_domain -intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port); +intel_display_power_ddi_io_domain(struct intel_display *display, enum port port); enum intel_display_power_domain -intel_display_power_aux_io_domain(struct drm_i915_private *i915, enum aux_ch aux_ch); +intel_display_power_aux_io_domain(struct intel_display *display, enum aux_ch aux_ch); enum intel_display_power_domain -intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch aux_ch); +intel_display_power_legacy_aux_domain(struct intel_display *display, enum aux_ch aux_ch); enum intel_display_power_domain -intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch aux_ch); +intel_display_power_tbt_aux_domain(struct intel_display *display, enum aux_ch aux_ch); /* * FIXME: We should probably switch this to a 0-based scheme to be consistent @@ -293,7 +292,7 @@ enum dbuf_slice { I915_MAX_DBUF_SLICES }; -void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv, +void gen9_dbuf_slices_update(struct intel_display *display, u8 req_slices); #define with_intel_display_power(display, domain, wf) \ diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index f45a4f9ba23c6..367f8e8d9e738 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -962,8 +962,7 @@ static bool gen9_dc_off_power_well_enabled(struct intel_display *display, static void gen9_assert_dbuf_enabled(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - u8 hw_enabled_dbuf_slices = intel_enabled_dbuf_slices_mask(dev_priv); + u8 hw_enabled_dbuf_slices = intel_enabled_dbuf_slices_mask(display); u8 enabled_dbuf_slices = display->dbuf.enabled_slices; drm_WARN(display->drm, diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index e9e9ee5d345a2..b8d14ed8a56e2 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -177,11 +177,11 @@ bool intel_tc_port_handles_hpd_glitches(struct intel_digital_port *dig_port) */ bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_tc_port *tc = to_tc_port(dig_port); return tc_phy_cold_off_domain(tc) == - intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch); + intel_display_power_legacy_aux_domain(display, dig_port->aux_ch); } static intel_wakeref_t @@ -478,11 +478,11 @@ static void tc_phy_load_fia_params(struct intel_tc_port *tc, bool modular_fia) static enum intel_display_power_domain icl_tc_phy_cold_off_domain(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); struct intel_digital_port *dig_port = tc->dig_port; if (tc->legacy_port) - return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch); + return intel_display_power_legacy_aux_domain(display, dig_port->aux_ch); return POWER_DOMAIN_TC_COLD_OFF; } @@ -763,11 +763,11 @@ static const struct intel_tc_phy_ops tgl_tc_phy_ops = { static enum intel_display_power_domain adlp_tc_phy_cold_off_domain(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); struct intel_digital_port *dig_port = tc->dig_port; if (tc->mode != TC_PORT_TBT_ALT) - return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch); + return intel_display_power_legacy_aux_domain(display, dig_port->aux_ch); return POWER_DOMAIN_TC_COLD_OFF; } diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 1c4510d520e81..9e97fc7039031 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -52,13 +52,13 @@ struct skl_wm_params { u32 dbuf_block_size; }; -u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *i915) +u8 intel_enabled_dbuf_slices_mask(struct intel_display *display) { u8 enabled_slices = 0; enum dbuf_slice slice; - for_each_dbuf_slice(i915, slice) { - if (intel_de_read(i915, DBUF_CTL_S(slice)) & DBUF_POWER_STATE) + for_each_dbuf_slice(display, slice) { + if (intel_de_read(display, DBUF_CTL_S(slice)) & DBUF_POWER_STATE) enabled_slices |= BIT(slice); } @@ -3701,7 +3701,7 @@ void intel_dbuf_mbus_post_ddb_update(struct intel_atomic_state *state) void intel_dbuf_pre_plane_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_dbuf_state *new_dbuf_state = intel_atomic_get_new_dbuf_state(state); const struct intel_dbuf_state *old_dbuf_state = @@ -3719,12 +3719,12 @@ void intel_dbuf_pre_plane_update(struct intel_atomic_state *state) WARN_ON(!new_dbuf_state->base.changed); - gen9_dbuf_slices_update(i915, new_slices); + gen9_dbuf_slices_update(display, new_slices); } void intel_dbuf_post_plane_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_dbuf_state *new_dbuf_state = intel_atomic_get_new_dbuf_state(state); const struct intel_dbuf_state *old_dbuf_state = @@ -3742,7 +3742,7 @@ void intel_dbuf_post_plane_update(struct intel_atomic_state *state) WARN_ON(!new_dbuf_state->base.changed); - gen9_dbuf_slices_update(i915, new_slices); + gen9_dbuf_slices_update(display, new_slices); } static void skl_mbus_sanitize(struct drm_i915_private *i915) @@ -3875,7 +3875,7 @@ void intel_wm_state_verify(struct intel_atomic_state *state, skl_pipe_ddb_get_hw_state(crtc, hw->ddb, hw->ddb_y, hw->min_ddb, hw->interim_ddb); - hw_enabled_slices = intel_enabled_dbuf_slices_mask(i915); + hw_enabled_slices = intel_enabled_dbuf_slices_mask(display); if (DISPLAY_VER(i915) >= 11 && hw_enabled_slices != i915->display.dbuf.enabled_slices) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h index 8659f89427f23..c5547485225a3 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.h +++ b/drivers/gpu/drm/i915/display/skl_watermark.h @@ -17,12 +17,13 @@ struct intel_atomic_state; struct intel_bw_state; struct intel_crtc; struct intel_crtc_state; +struct intel_display; struct intel_plane; struct intel_plane_state; struct skl_pipe_wm; struct skl_wm_level; -u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *i915); +u8 intel_enabled_dbuf_slices_mask(struct intel_display *display); void intel_sagv_pre_plane_update(struct intel_atomic_state *state); void intel_sagv_post_plane_update(struct intel_atomic_state *state); From 7378c2dbf366ba4b0e01484abd211bb41dfa82b5 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 12 Feb 2025 13:15:35 +0530 Subject: [PATCH 192/284] drm/i915: Use intel_display wherever possible Use struct intel_display wherever possible in intel_display_debug_fs.c to reduce the use of drm_i915_private. While at it do the opportunistic display->platform.xx replacement. --v2 -Rebase --v3 -Don't use inline to_intel_display [Jani] -Don't use display debug fs as subject prefix [Jani] Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250212074542.3569452-2-suraj.kandpal@intel.com --- .../drm/i915/display/intel_display_debugfs.c | 168 +++++++++--------- 1 file changed, 86 insertions(+), 82 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 09a8f667366d6..251c172fc5c9a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -68,17 +68,17 @@ static int intel_display_caps(struct seq_file *m, void *data) static int i915_frontbuffer_tracking(struct seq_file *m, void *unused) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_display *display = node_to_intel_display(m->private); - spin_lock(&dev_priv->display.fb_tracking.lock); + spin_lock(&display->fb_tracking.lock); seq_printf(m, "FB tracking busy bits: 0x%08x\n", - dev_priv->display.fb_tracking.busy_bits); + display->fb_tracking.busy_bits); seq_printf(m, "FB tracking flip bits: 0x%08x\n", - dev_priv->display.fb_tracking.flip_bits); + display->fb_tracking.flip_bits); - spin_unlock(&dev_priv->display.fb_tracking.lock); + spin_unlock(&display->fb_tracking.lock); return 0; } @@ -86,25 +86,25 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused) static int i915_sr_status(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); - struct intel_display *display = &dev_priv->display; + struct intel_display *display = node_to_intel_display(m->private); intel_wakeref_t wakeref; bool sr_enabled = false; wakeref = intel_display_power_get(display, POWER_DOMAIN_INIT); - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) /* no global SR status; inspect per-plane WM */; else if (HAS_PCH_SPLIT(dev_priv)) - sr_enabled = intel_de_read(dev_priv, WM1_LP_ILK) & WM_LP_ENABLE; - else if (IS_I965GM(dev_priv) || IS_G4X(dev_priv) || - IS_I945G(dev_priv) || IS_I945GM(dev_priv)) - sr_enabled = intel_de_read(dev_priv, FW_BLC_SELF) & FW_BLC_SELF_EN; - else if (IS_I915GM(dev_priv)) - sr_enabled = intel_de_read(dev_priv, INSTPM) & INSTPM_SELF_EN; - else if (IS_PINEVIEW(dev_priv)) - sr_enabled = intel_de_read(dev_priv, DSPFW3(dev_priv)) & PINEVIEW_SELF_REFRESH_EN; - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - sr_enabled = intel_de_read(dev_priv, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; + sr_enabled = intel_de_read(display, WM1_LP_ILK) & WM_LP_ENABLE; + else if (display->platform.i965gm || display->platform.g4x || + display->platform.i945g || display->platform.i945gm) + sr_enabled = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN; + else if (display->platform.i915gm) + sr_enabled = intel_de_read(display, INSTPM) & INSTPM_SELF_EN; + else if (display->platform.pineview) + sr_enabled = intel_de_read(display, DSPFW3(dev_priv)) & PINEVIEW_SELF_REFRESH_EN; + else if (display->platform.valleyview || display->platform.cherryview) + sr_enabled = intel_de_read(display, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref); @@ -115,12 +115,12 @@ static int i915_sr_status(struct seq_file *m, void *unused) static int i915_gem_framebuffer_info(struct seq_file *m, void *data) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_display *display = node_to_intel_display(m->private); struct intel_framebuffer *fbdev_fb = NULL; struct drm_framebuffer *drm_fb; #ifdef CONFIG_DRM_FBDEV_EMULATION - fbdev_fb = intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev); + fbdev_fb = intel_fbdev_framebuffer(display->fbdev.fbdev); if (fbdev_fb) { seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", fbdev_fb->base.width, @@ -134,8 +134,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) } #endif - mutex_lock(&dev_priv->drm.mode_config.fb_lock); - drm_for_each_fb(drm_fb, &dev_priv->drm) { + mutex_lock(&display->drm->mode_config.fb_lock); + drm_for_each_fb(drm_fb, display->drm) { struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); if (fb == fbdev_fb) continue; @@ -150,7 +150,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) intel_bo_describe(m, intel_fb_bo(&fb->base)); seq_putc(m, '\n'); } - mutex_unlock(&dev_priv->drm.mode_config.fb_lock); + mutex_unlock(&display->drm->mode_config.fb_lock); return 0; } @@ -180,14 +180,14 @@ static void intel_encoder_info(struct seq_file *m, struct intel_crtc *crtc, struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_display *display = node_to_intel_display(m->private); struct drm_connector_list_iter conn_iter; struct drm_connector *connector; seq_printf(m, "\t[ENCODER:%d:%s]: connectors:\n", encoder->base.base.id, encoder->base.name); - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); drm_for_each_connector_iter(connector, &conn_iter) { const struct drm_connector_state *conn_state = connector->state; @@ -392,10 +392,10 @@ static void intel_plane_hw_info(struct seq_file *m, struct intel_plane *plane) static void intel_plane_info(struct seq_file *m, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_display *display = node_to_intel_display(m->private); struct intel_plane *plane; - for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { seq_printf(m, "\t[PLANE:%d:%s]: type=%s\n", plane->base.base.id, plane->base.name, plane_type(plane->base.type)); @@ -538,7 +538,7 @@ static void crtc_updates_add(struct intel_crtc *crtc) static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_display *display = node_to_intel_display(m->private); struct drm_printer p = drm_seq_file_printer(m); const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -572,7 +572,7 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) intel_vdsc_state_dump(&p, 1, crtc_state); - for_each_intel_encoder_mask(&dev_priv->drm, encoder, + for_each_intel_encoder_mask(display->drm, encoder, crtc_state->uapi.encoder_mask) intel_encoder_info(m, crtc, encoder); @@ -587,6 +587,7 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) static int i915_display_info(struct seq_file *m, void *unused) { + struct intel_display *display = node_to_intel_display(m->private); struct drm_i915_private *dev_priv = node_to_i915(m->private); struct intel_crtc *crtc; struct drm_connector *connector; @@ -595,22 +596,22 @@ static int i915_display_info(struct seq_file *m, void *unused) wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); - drm_modeset_lock_all(&dev_priv->drm); + drm_modeset_lock_all(display->drm); seq_printf(m, "CRTC info\n"); seq_printf(m, "---------\n"); - for_each_intel_crtc(&dev_priv->drm, crtc) + for_each_intel_crtc(display->drm, crtc) intel_crtc_info(m, crtc); seq_printf(m, "\n"); seq_printf(m, "Connector info\n"); seq_printf(m, "--------------\n"); - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); drm_for_each_connector_iter(connector, &conn_iter) intel_connector_info(m, connector); drm_connector_list_iter_end(&conn_iter); - drm_modeset_unlock_all(&dev_priv->drm); + drm_modeset_unlock_all(display->drm); intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); @@ -619,11 +620,11 @@ static int i915_display_info(struct seq_file *m, void *unused) static int i915_display_capabilities(struct seq_file *m, void *unused) { - struct drm_i915_private *i915 = node_to_i915(m->private); + struct intel_display *display = node_to_intel_display(m->private); struct drm_printer p = drm_seq_file_printer(m); - intel_display_device_info_print(DISPLAY_INFO(i915), - DISPLAY_RUNTIME_INFO(i915), &p); + intel_display_device_info_print(DISPLAY_INFO(display), + DISPLAY_RUNTIME_INFO(display), &p); return 0; } @@ -631,15 +632,16 @@ static int i915_display_capabilities(struct seq_file *m, void *unused) static int i915_shared_dplls_info(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_display *display = node_to_intel_display(m->private); struct drm_printer p = drm_seq_file_printer(m); struct intel_shared_dpll *pll; int i; - drm_modeset_lock_all(&dev_priv->drm); + drm_modeset_lock_all(display->drm); drm_printf(&p, "PLL refclks: non-SSC: %d kHz, SSC: %d kHz\n", - dev_priv->display.dpll.ref_clks.nssc, - dev_priv->display.dpll.ref_clks.ssc); + display->dpll.ref_clks.nssc, + display->dpll.ref_clks.ssc); for_each_shared_dpll(dev_priv, pll, i) { drm_printf(&p, "DPLL%i: %s, id: %i\n", pll->index, @@ -650,25 +652,25 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused) drm_printf(&p, " tracked hardware state:\n"); intel_dpll_dump_hw_state(dev_priv, &p, &pll->state.hw_state); } - drm_modeset_unlock_all(&dev_priv->drm); + drm_modeset_unlock_all(display->drm); return 0; } static int i915_ddb_info(struct seq_file *m, void *unused) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_display *display = node_to_intel_display(m->private); struct skl_ddb_entry *entry; struct intel_crtc *crtc; - if (DISPLAY_VER(dev_priv) < 9) + if (DISPLAY_VER(display) < 9) return -ENODEV; - drm_modeset_lock_all(&dev_priv->drm); + drm_modeset_lock_all(display->drm); seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size"); - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); enum pipe pipe = crtc->pipe; @@ -688,16 +690,16 @@ static int i915_ddb_info(struct seq_file *m, void *unused) entry->end, skl_ddb_entry_size(entry)); } - drm_modeset_unlock_all(&dev_priv->drm); + drm_modeset_unlock_all(display->drm); return 0; } static bool -intel_lpsp_power_well_enabled(struct drm_i915_private *i915, +intel_lpsp_power_well_enabled(struct intel_display *display, enum i915_power_well_id power_well_id) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref; bool is_enabled; @@ -711,15 +713,16 @@ intel_lpsp_power_well_enabled(struct drm_i915_private *i915, static int i915_lpsp_status(struct seq_file *m, void *unused) { + struct intel_display *display = node_to_intel_display(m->private); struct drm_i915_private *i915 = node_to_i915(m->private); bool lpsp_enabled = false; - if (DISPLAY_VER(i915) >= 13 || IS_DISPLAY_VER(i915, 9, 10)) { - lpsp_enabled = !intel_lpsp_power_well_enabled(i915, SKL_DISP_PW_2); - } else if (IS_DISPLAY_VER(i915, 11, 12)) { - lpsp_enabled = !intel_lpsp_power_well_enabled(i915, ICL_DISP_PW_3); + if (DISPLAY_VER(display) >= 13 || IS_DISPLAY_VER(display, 9, 10)) { + lpsp_enabled = !intel_lpsp_power_well_enabled(display, SKL_DISP_PW_2); + } else if (IS_DISPLAY_VER(display, 11, 12)) { + lpsp_enabled = !intel_lpsp_power_well_enabled(display, ICL_DISP_PW_3); } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { - lpsp_enabled = !intel_lpsp_power_well_enabled(i915, HSW_DISP_PW_GLOBAL); + lpsp_enabled = !intel_lpsp_power_well_enabled(display, HSW_DISP_PW_GLOBAL); } else { seq_puts(m, "LPSP: not supported\n"); return 0; @@ -732,13 +735,13 @@ static int i915_lpsp_status(struct seq_file *m, void *unused) static int i915_dp_mst_info(struct seq_file *m, void *unused) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_display *display = node_to_intel_display(m->private); struct intel_encoder *intel_encoder; struct intel_digital_port *dig_port; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); drm_for_each_connector_iter(connector, &conn_iter) { if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) continue; @@ -766,7 +769,7 @@ i915_fifo_underrun_reset_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { - struct drm_i915_private *dev_priv = filp->private_data; + struct intel_display *display = filp->private_data; struct intel_crtc *crtc; int ret; bool reset; @@ -778,7 +781,7 @@ i915_fifo_underrun_reset_write(struct file *filp, if (!reset) return cnt; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct drm_crtc_commit *commit; struct intel_crtc_state *crtc_state; @@ -795,7 +798,7 @@ i915_fifo_underrun_reset_write(struct file *filp, } if (!ret && crtc_state->hw.active) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Re-arming FIFO underruns on pipe %c\n", pipe_name(crtc->pipe)); @@ -808,7 +811,7 @@ i915_fifo_underrun_reset_write(struct file *filp, return ret; } - intel_fbc_reset_underrun(&dev_priv->display); + intel_fbc_reset_underrun(display); return cnt; } @@ -840,7 +843,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915) struct drm_minor *minor = i915->drm.primary; debugfs_create_file("i915_fifo_underrun_reset", 0644, minor->debugfs_root, - to_i915(minor->dev), &i915_fifo_underrun_reset_ops); + display, &i915_fifo_underrun_reset_ops); drm_debugfs_create_files(intel_display_debugfs_list, ARRAY_SIZE(intel_display_debugfs_list), @@ -861,8 +864,9 @@ void intel_display_debugfs_register(struct drm_i915_private *i915) static int i915_lpsp_capability_show(struct seq_file *m, void *data) { struct intel_connector *connector = m->private; - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_encoder *encoder = intel_attached_encoder(connector); + struct drm_i915_private *i915 = to_i915(connector->base.dev); int connector_type = connector->base.connector_type; bool lpsp_capable = false; @@ -872,19 +876,19 @@ static int i915_lpsp_capability_show(struct seq_file *m, void *data) if (connector->base.status != connector_status_connected) return -ENODEV; - if (DISPLAY_VER(i915) >= 13) + if (DISPLAY_VER(display) >= 13) lpsp_capable = encoder->port <= PORT_B; - else if (DISPLAY_VER(i915) >= 12) + else if (DISPLAY_VER(display) >= 12) /* * Actually TGL can drive LPSP on port till DDI_C * but there is no physical connected DDI_C on TGL sku's, * even driver is not initializing DDI_C port for gen12. */ lpsp_capable = encoder->port <= PORT_B; - else if (DISPLAY_VER(i915) == 11) + else if (DISPLAY_VER(display) == 11) lpsp_capable = (connector_type == DRM_MODE_CONNECTOR_DSI || connector_type == DRM_MODE_CONNECTOR_eDP); - else if (IS_DISPLAY_VER(i915, 9, 10)) + else if (IS_DISPLAY_VER(display, 9, 10)) lpsp_capable = (encoder->port == PORT_A && (connector_type == DRM_MODE_CONNECTOR_DSI || connector_type == DRM_MODE_CONNECTOR_eDP || @@ -901,7 +905,7 @@ DEFINE_SHOW_ATTRIBUTE(i915_lpsp_capability); static int i915_dsc_fec_support_show(struct seq_file *m, void *data) { struct intel_connector *connector = m->private; - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct drm_crtc *crtc; struct intel_dp *intel_dp; struct drm_modeset_acquire_ctx ctx; @@ -913,7 +917,7 @@ static int i915_dsc_fec_support_show(struct seq_file *m, void *data) do { try_again = false; - ret = drm_modeset_lock(&i915->drm.mode_config.connection_mutex, + ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex, &ctx); if (ret) { if (ret == -EDEADLK && !drm_modeset_backoff(&ctx)) { @@ -974,7 +978,7 @@ static ssize_t i915_dsc_fec_support_write(struct file *file, { struct seq_file *m = file->private_data; struct intel_connector *connector = m->private; - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_encoder *encoder = intel_attached_encoder(connector); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); bool dsc_enable = false; @@ -983,14 +987,14 @@ static ssize_t i915_dsc_fec_support_write(struct file *file, if (len == 0) return 0; - drm_dbg(&i915->drm, + drm_dbg(display->drm, "Copied %zu bytes from user to force DSC\n", len); ret = kstrtobool_from_user(ubuf, len, &dsc_enable); if (ret < 0) return ret; - drm_dbg(&i915->drm, "Got %s for DSC Enable\n", + drm_dbg(display->drm, "Got %s for DSC Enable\n", (dsc_enable) ? "true" : "false"); intel_dp->force_dsc_en = dsc_enable; @@ -1017,7 +1021,7 @@ static const struct file_operations i915_dsc_fec_support_fops = { static int i915_dsc_bpc_show(struct seq_file *m, void *data) { struct intel_connector *connector = m->private; - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_encoder *encoder = intel_attached_encoder(connector); struct drm_crtc *crtc; struct intel_crtc_state *crtc_state; @@ -1026,7 +1030,7 @@ static int i915_dsc_bpc_show(struct seq_file *m, void *data) if (!encoder) return -ENODEV; - ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex); + ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); if (ret) return ret; @@ -1039,7 +1043,7 @@ static int i915_dsc_bpc_show(struct seq_file *m, void *data) crtc_state = to_intel_crtc_state(crtc->state); seq_printf(m, "Input_BPC: %d\n", crtc_state->dsc.config.bits_per_component); -out: drm_modeset_unlock(&i915->drm.mode_config.connection_mutex); +out: drm_modeset_unlock(&display->drm->mode_config.connection_mutex); return ret; } @@ -1083,7 +1087,7 @@ static const struct file_operations i915_dsc_bpc_fops = { static int i915_dsc_output_format_show(struct seq_file *m, void *data) { struct intel_connector *connector = m->private; - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_encoder *encoder = intel_attached_encoder(connector); struct drm_crtc *crtc; struct intel_crtc_state *crtc_state; @@ -1092,7 +1096,7 @@ static int i915_dsc_output_format_show(struct seq_file *m, void *data) if (!encoder) return -ENODEV; - ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex); + ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); if (ret) return ret; @@ -1106,7 +1110,7 @@ static int i915_dsc_output_format_show(struct seq_file *m, void *data) seq_printf(m, "DSC_Output_Format: %s\n", intel_output_format_name(crtc_state->output_format)); -out: drm_modeset_unlock(&i915->drm.mode_config.connection_mutex); +out: drm_modeset_unlock(&display->drm->mode_config.connection_mutex); return ret; } @@ -1150,7 +1154,7 @@ static const struct file_operations i915_dsc_output_format_fops = { static int i915_dsc_fractional_bpp_show(struct seq_file *m, void *data) { struct intel_connector *connector = m->private; - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_encoder *encoder = intel_attached_encoder(connector); struct drm_crtc *crtc; struct intel_dp *intel_dp; @@ -1159,7 +1163,7 @@ static int i915_dsc_fractional_bpp_show(struct seq_file *m, void *data) if (!encoder) return -ENODEV; - ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex); + ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); if (ret) return ret; @@ -1174,7 +1178,7 @@ static int i915_dsc_fractional_bpp_show(struct seq_file *m, void *data) str_yes_no(intel_dp->force_dsc_fractional_bpp_en)); out: - drm_modeset_unlock(&i915->drm.mode_config.connection_mutex); + drm_modeset_unlock(&display->drm->mode_config.connection_mutex); return ret; } @@ -1185,8 +1189,8 @@ static ssize_t i915_dsc_fractional_bpp_write(struct file *file, { struct seq_file *m = file->private_data; struct intel_connector *connector = m->private; + struct intel_display *display = to_intel_display(connector); struct intel_encoder *encoder = intel_attached_encoder(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); bool dsc_fractional_bpp_enable = false; int ret; @@ -1194,14 +1198,14 @@ static ssize_t i915_dsc_fractional_bpp_write(struct file *file, if (len == 0) return 0; - drm_dbg(&i915->drm, + drm_dbg(display->drm, "Copied %zu bytes from user to force fractional bpp for DSC\n", len); ret = kstrtobool_from_user(ubuf, len, &dsc_fractional_bpp_enable); if (ret < 0) return ret; - drm_dbg(&i915->drm, "Got %s for DSC Fractional BPP Enable\n", + drm_dbg(display->drm, "Got %s for DSC Fractional BPP Enable\n", (dsc_fractional_bpp_enable) ? "true" : "false"); intel_dp->force_dsc_fractional_bpp_en = dsc_fractional_bpp_enable; @@ -1330,7 +1334,7 @@ static const struct file_operations i915_joiner_fops = { */ void intel_connector_debugfs_add(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct dentry *root = connector->base.debugfs_entry; int connector_type = connector->base.connector_type; @@ -1345,7 +1349,7 @@ void intel_connector_debugfs_add(struct intel_connector *connector) intel_alpm_lobf_debugfs_add(connector); intel_dp_link_training_debugfs_add(connector); - if (DISPLAY_VER(i915) >= 11 && + if (DISPLAY_VER(display) >= 11 && ((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst_port) || connector_type == DRM_MODE_CONNECTOR_eDP)) { debugfs_create_file("i915_dsc_fec_support", 0644, root, From e20d0d407667f5b32220d92e8e7c0ed01c31b2e6 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 12 Feb 2025 13:15:36 +0530 Subject: [PATCH 193/284] drm/i915/dpll: Change param to intel_display in for_each_shared_dpll Change the argument of for_each_shared_dpll to take intel_display which helps move as an ongoing effort to get rid off the dependency on drm_i915_private. Some opportunistic changes in intel_pch_refclk done too. --v2 -Prefer using &i915->display [Jani] Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250212074542.3569452-3-suraj.kandpal@intel.com --- .../drm/i915/display/intel_display_debugfs.c | 2 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 24 ++++++++----- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 6 ++-- .../gpu/drm/i915/display/intel_pch_refclk.c | 34 +++++++++---------- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 251c172fc5c9a..a250d4b4d11f7 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -643,7 +643,7 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused) display->dpll.ref_clks.nssc, display->dpll.ref_clks.ssc); - for_each_shared_dpll(dev_priv, pll, i) { + for_each_shared_dpll(display, pll, i) { drm_printf(&p, "DPLL%i: %s, id: %i\n", pll->index, pll->info->name, pll->info->id); drm_printf(&p, " pipe_mask: 0x%x, active: 0x%x, on: %s\n", diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index cb2ef317d219b..f79c16e6493c8 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -121,10 +121,11 @@ intel_atomic_duplicate_dpll_state(struct drm_i915_private *i915, struct intel_shared_dpll_state *shared_dpll) { struct intel_shared_dpll *pll; + struct intel_display *display = &i915->display; int i; /* Copy shared dpll state */ - for_each_shared_dpll(i915, pll, i) + for_each_shared_dpll(display, pll, i) shared_dpll[pll->index] = pll->state; } @@ -157,10 +158,11 @@ struct intel_shared_dpll * intel_get_shared_dpll_by_id(struct drm_i915_private *i915, enum intel_dpll_id id) { + struct intel_display *display = &i915->display; struct intel_shared_dpll *pll; int i; - for_each_shared_dpll(i915, pll, i) { + for_each_shared_dpll(display, pll, i) { if (pll->info->id == id) return pll; } @@ -344,12 +346,13 @@ void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state) static unsigned long intel_dpll_mask_all(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct intel_shared_dpll *pll; unsigned long dpll_mask = 0; int i; - for_each_shared_dpll(i915, pll, i) { - drm_WARN_ON(&i915->drm, dpll_mask & BIT(pll->info->id)); + for_each_shared_dpll(display, pll, i) { + drm_WARN_ON(display->drm, dpll_mask & BIT(pll->info->id)); dpll_mask |= BIT(pll->info->id); } @@ -513,7 +516,7 @@ static void intel_put_dpll(struct intel_atomic_state *state, */ void intel_shared_dpll_swap_state(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_shared_dpll_state *shared_dpll = state->shared_dpll; struct intel_shared_dpll *pll; int i; @@ -521,7 +524,7 @@ void intel_shared_dpll_swap_state(struct intel_atomic_state *state) if (!state->dpll_set) return; - for_each_shared_dpll(i915, pll, i) + for_each_shared_dpll(display, pll, i) swap(pll->state, shared_dpll[pll->index]); } @@ -4551,10 +4554,11 @@ void intel_dpll_update_ref_clks(struct drm_i915_private *i915) void intel_dpll_readout_hw_state(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct intel_shared_dpll *pll; int i; - for_each_shared_dpll(i915, pll, i) + for_each_shared_dpll(display, pll, i) readout_dpll_hw_state(i915, pll); } @@ -4578,10 +4582,11 @@ static void sanitize_dpll_state(struct drm_i915_private *i915, void intel_dpll_sanitize_state(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct intel_shared_dpll *pll; int i; - for_each_shared_dpll(i915, pll, i) + for_each_shared_dpll(display, pll, i) sanitize_dpll_state(i915, pll); } @@ -4728,10 +4733,11 @@ void intel_shared_dpll_state_verify(struct intel_atomic_state *state, void intel_shared_dpll_verify_disabled(struct intel_atomic_state *state) { + struct intel_display *display = to_intel_display(state); struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_shared_dpll *pll; int i; - for_each_shared_dpll(i915, pll, i) + for_each_shared_dpll(display, pll, i) verify_single_dpll_state(i915, pll, NULL, NULL); } diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index 3eee768743045..382bdf8f0b65d 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -30,9 +30,9 @@ #include "intel_display_power.h" #include "intel_wakeref.h" -#define for_each_shared_dpll(__i915, __pll, __i) \ - for ((__i) = 0; (__i) < (__i915)->display.dpll.num_shared_dpll && \ - ((__pll) = &(__i915)->display.dpll.shared_dplls[(__i)]) ; (__i)++) +#define for_each_shared_dpll(__display, __pll, __i) \ + for ((__i) = 0; (__i) < (__display)->dpll.num_shared_dpll && \ + ((__pll) = &(__display)->dpll.shared_dplls[(__i)]) ; (__i)++) enum tc_port; struct drm_i915_private; diff --git a/drivers/gpu/drm/i915/display/intel_pch_refclk.c b/drivers/gpu/drm/i915/display/intel_pch_refclk.c index 71471c1d7dc93..33467de3d1157 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_refclk.c +++ b/drivers/gpu/drm/i915/display/intel_pch_refclk.c @@ -505,7 +505,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) bool using_ssc_source = false; /* We need to take the global config into account */ - for_each_intel_encoder(&dev_priv->drm, encoder) { + for_each_intel_encoder(display->drm, encoder) { switch (encoder->type) { case INTEL_OUTPUT_LVDS: has_panel = true; @@ -522,7 +522,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) } if (HAS_PCH_IBX(dev_priv)) { - has_ck505 = dev_priv->display.vbt.display_clock_mode; + has_ck505 = display->vbt.display_clock_mode; can_ssc = has_ck505; } else { has_ck505 = false; @@ -530,10 +530,10 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) } /* Check if any DPLLs are using the SSC source */ - for_each_shared_dpll(dev_priv, pll, i) { + for_each_shared_dpll(display, pll, i) { u32 temp; - temp = intel_de_read(dev_priv, PCH_DPLL(pll->info->id)); + temp = intel_de_read(display, PCH_DPLL(pll->info->id)); if (!(temp & DPLL_VCO_ENABLE)) continue; @@ -545,7 +545,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) } } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n", has_panel, has_lvds, has_ck505, using_ssc_source); @@ -554,7 +554,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) * PCH B stepping, previous chipset stepping should be * ignoring this setting. */ - val = intel_de_read(dev_priv, PCH_DREF_CONTROL); + val = intel_de_read(display, PCH_DREF_CONTROL); /* As we must carefully and slowly disable/enable each source in turn, * compute the final state we want first and check if we need to @@ -614,8 +614,8 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) } /* Get SSC going before enabling the outputs */ - intel_de_write(dev_priv, PCH_DREF_CONTROL, val); - intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); + intel_de_write(display, PCH_DREF_CONTROL, val); + intel_de_posting_read(display, PCH_DREF_CONTROL); udelay(200); val &= ~DREF_CPU_SOURCE_OUTPUT_MASK; @@ -633,23 +633,23 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) val |= DREF_CPU_SOURCE_OUTPUT_DISABLE; } - intel_de_write(dev_priv, PCH_DREF_CONTROL, val); - intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); + intel_de_write(display, PCH_DREF_CONTROL, val); + intel_de_posting_read(display, PCH_DREF_CONTROL); udelay(200); } else { - drm_dbg_kms(&dev_priv->drm, "Disabling CPU source output\n"); + drm_dbg_kms(display->drm, "Disabling CPU source output\n"); val &= ~DREF_CPU_SOURCE_OUTPUT_MASK; /* Turn off CPU output */ val |= DREF_CPU_SOURCE_OUTPUT_DISABLE; - intel_de_write(dev_priv, PCH_DREF_CONTROL, val); - intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); + intel_de_write(display, PCH_DREF_CONTROL, val); + intel_de_posting_read(display, PCH_DREF_CONTROL); udelay(200); if (!using_ssc_source) { - drm_dbg_kms(&dev_priv->drm, "Disabling SSC source\n"); + drm_dbg_kms(display->drm, "Disabling SSC source\n"); /* Turn off the SSC source */ val &= ~DREF_SSC_SOURCE_MASK; @@ -658,13 +658,13 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) /* Turn off SSC1 */ val &= ~DREF_SSC1_ENABLE; - intel_de_write(dev_priv, PCH_DREF_CONTROL, val); - intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); + intel_de_write(display, PCH_DREF_CONTROL, val); + intel_de_posting_read(display, PCH_DREF_CONTROL); udelay(200); } } - drm_WARN_ON(&dev_priv->drm, val != final); + drm_WARN_ON(display->drm, val != final); } /* From bd867a00f752805699ea216e4d73aec088321699 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 12 Feb 2025 13:15:37 +0530 Subject: [PATCH 194/284] drm/i915/dpll: Use intel_display for dpll dump and compare hw state Let's use intel_display for dpll dump and compare hw state. This also helps elimanate drm_i915_private dependency from i915_shared_dplls_info in intel_display_debugfs.c --v2 -Fix commit message [Jani] Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250212074542.3569452-4-suraj.kandpal@intel.com --- .../gpu/drm/i915/display/intel_crtc_state_dump.c | 3 ++- drivers/gpu/drm/i915/display/intel_display.c | 8 ++++---- .../gpu/drm/i915/display/intel_display_debugfs.c | 3 +-- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 16 ++++++++-------- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index ecd0d9853c60f..599ddce96371f 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -176,6 +176,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, struct intel_atomic_state *state, const char *context) { + struct intel_display *display = to_intel_display(pipe_config); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); const struct intel_plane_state *plane_state; @@ -340,7 +341,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, pipe_config->ips_enabled, pipe_config->double_wide, pipe_config->has_drrs); - intel_dpll_dump_hw_state(i915, &p, &pipe_config->dpll_hw_state); + intel_dpll_dump_hw_state(display, &p, &pipe_config->dpll_hw_state); if (IS_CHERRYVIEW(i915)) drm_printf(&p, "cgm_mode: 0x%x gamma_mode: 0x%x gamma_enable: %d csc_enable: %d\n", diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e19fc44b43ea1..8d4b6c1a0dd98 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5348,14 +5348,14 @@ pipe_config_pll_mismatch(struct drm_printer *p, bool fastset, const struct intel_dpll_hw_state *a, const struct intel_dpll_hw_state *b) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); pipe_config_mismatch(p, fastset, crtc, name, " "); /* stupid -Werror=format-zero-length */ drm_printf(p, "expected:\n"); - intel_dpll_dump_hw_state(i915, p, a); + intel_dpll_dump_hw_state(display, p, a); drm_printf(p, "found:\n"); - intel_dpll_dump_hw_state(i915, p, b); + intel_dpll_dump_hw_state(display, p, b); } static void @@ -5495,7 +5495,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, } while (0) #define PIPE_CONF_CHECK_PLL(name) do { \ - if (!intel_dpll_compare_hw_state(dev_priv, ¤t_config->name, \ + if (!intel_dpll_compare_hw_state(display, ¤t_config->name, \ &pipe_config->name)) { \ pipe_config_pll_mismatch(&p, fastset, crtc, __stringify(name), \ ¤t_config->name, \ diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index a250d4b4d11f7..a646560f4f5b9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -631,7 +631,6 @@ static int i915_display_capabilities(struct seq_file *m, void *unused) static int i915_shared_dplls_info(struct seq_file *m, void *unused) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); struct intel_display *display = node_to_intel_display(m->private); struct drm_printer p = drm_seq_file_printer(m); struct intel_shared_dpll *pll; @@ -650,7 +649,7 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused) pll->state.pipe_mask, pll->active_mask, str_yes_no(pll->on)); drm_printf(&p, " tracked hardware state:\n"); - intel_dpll_dump_hw_state(dev_priv, &p, &pll->state.hw_state); + intel_dpll_dump_hw_state(display, &p, &pll->state.hw_state); } drm_modeset_unlock_all(display->drm); diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index f79c16e6493c8..f295d86070e95 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -4592,18 +4592,18 @@ void intel_dpll_sanitize_state(struct drm_i915_private *i915) /** * intel_dpll_dump_hw_state - dump hw_state - * @i915: i915 drm device + * @display: intel_display structure * @p: where to print the state to * @dpll_hw_state: hw state to be dumped * * Dumo out the relevant values in @dpll_hw_state. */ -void intel_dpll_dump_hw_state(struct drm_i915_private *i915, +void intel_dpll_dump_hw_state(struct intel_display *display, struct drm_printer *p, const struct intel_dpll_hw_state *dpll_hw_state) { - if (i915->display.dpll.mgr) { - i915->display.dpll.mgr->dump_hw_state(p, dpll_hw_state); + if (display->dpll.mgr) { + display->dpll.mgr->dump_hw_state(p, dpll_hw_state); } else { /* fallback for platforms that don't use the shared dpll * infrastructure @@ -4614,7 +4614,7 @@ void intel_dpll_dump_hw_state(struct drm_i915_private *i915, /** * intel_dpll_compare_hw_state - compare the two states - * @i915: i915 drm device + * @display: intel_display structure * @a: first DPLL hw state * @b: second DPLL hw state * @@ -4622,12 +4622,12 @@ void intel_dpll_dump_hw_state(struct drm_i915_private *i915, * * Returns: true if the states are equal, false if the differ */ -bool intel_dpll_compare_hw_state(struct drm_i915_private *i915, +bool intel_dpll_compare_hw_state(struct intel_display *display, const struct intel_dpll_hw_state *a, const struct intel_dpll_hw_state *b) { - if (i915->display.dpll.mgr) { - return i915->display.dpll.mgr->compare_hw_state(a, b); + if (display->dpll.mgr) { + return display->dpll.mgr->compare_hw_state(a, b); } else { /* fallback for platforms that don't use the shared dpll * infrastructure diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index 382bdf8f0b65d..42379494f347a 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -427,10 +427,10 @@ void intel_dpll_update_ref_clks(struct drm_i915_private *i915); void intel_dpll_readout_hw_state(struct drm_i915_private *i915); void intel_dpll_sanitize_state(struct drm_i915_private *i915); -void intel_dpll_dump_hw_state(struct drm_i915_private *i915, +void intel_dpll_dump_hw_state(struct intel_display *display, struct drm_printer *p, const struct intel_dpll_hw_state *dpll_hw_state); -bool intel_dpll_compare_hw_state(struct drm_i915_private *i915, +bool intel_dpll_compare_hw_state(struct intel_display *display, const struct intel_dpll_hw_state *a, const struct intel_dpll_hw_state *b); enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port); From 972259d93c69c4064a2bfce62c8db9ea6275074b Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 12 Feb 2025 13:15:38 +0530 Subject: [PATCH 195/284] drm/i915/dpll: Use intel_display possible in shared_dpll_mgr hooks We use intel_display for function hooks of shared_dpll_mgr and any function that gets called when we use for_each_shared_dpll. This also contains some opportunistic display->platform.xx changes all to reductate the use of drm_i915_private. --v2 -rebase --v3 -Don't use inline to_i915 [Jani] Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250212074542.3569452-5-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 130 +-- .../i915/display/intel_display_power_well.c | 3 +- drivers/gpu/drm/i915/display/intel_dkl_phy.c | 54 +- drivers/gpu/drm/i915/display/intel_dkl_phy.h | 9 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 792 +++++++++--------- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 10 +- .../drm/i915/display/intel_modeset_setup.c | 4 +- .../gpu/drm/i915/display/intel_pch_display.c | 43 +- 8 files changed, 517 insertions(+), 528 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index b889aa68d3934..ee1fb01c97955 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -358,10 +358,10 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, } } -static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv, +static int icl_calc_tbt_pll_link(struct intel_display *display, enum port port) { - u32 val = intel_de_read(dev_priv, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK; + u32 val = intel_de_read(display, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK; switch (val) { case DDI_CLK_SEL_NONE: @@ -1367,7 +1367,7 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); const struct intel_ddi_buf_trans *trans; int n_entries, ln; @@ -1376,17 +1376,17 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, return; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; for (ln = 0; ln < 2; ln++) { int level; - intel_dkl_phy_write(dev_priv, DKL_TX_PMD_LANE_SUS(tc_port, ln), 0); + intel_dkl_phy_write(display, DKL_TX_PMD_LANE_SUS(tc_port, ln), 0); level = intel_ddi_level(encoder, crtc_state, 2*ln+0); - intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL0(tc_port, ln), + intel_dkl_phy_rmw(display, DKL_TX_DPCNTL0(tc_port, ln), DKL_TX_PRESHOOT_COEFF_MASK | DKL_TX_DE_EMPAHSIS_COEFF_MASK | DKL_TX_VSWING_CONTROL_MASK, @@ -1396,7 +1396,7 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, level = intel_ddi_level(encoder, crtc_state, 2*ln+1); - intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL1(tc_port, ln), + intel_dkl_phy_rmw(display, DKL_TX_DPCNTL1(tc_port, ln), DKL_TX_PRESHOOT_COEFF_MASK | DKL_TX_DE_EMPAHSIS_COEFF_MASK | DKL_TX_VSWING_CONTROL_MASK, @@ -1404,10 +1404,10 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) | DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing)); - intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln), + intel_dkl_phy_rmw(display, DKL_TX_DPCNTL2(tc_port, ln), DKL_TX_DP20BITMODE, 0); - if (IS_ALDERLAKE_P(dev_priv)) { + if (display->platform.alderlake_p) { u32 val; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { @@ -1423,7 +1423,7 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(0); } - intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln), + intel_dkl_phy_rmw(display, DKL_TX_DPCNTL2(tc_port, ln), DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK | DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, val); @@ -1551,14 +1551,14 @@ static bool _icl_ddi_is_clock_enabled(struct drm_i915_private *i915, i915_reg_t } static struct intel_shared_dpll * -_icl_ddi_get_pll(struct drm_i915_private *i915, i915_reg_t reg, +_icl_ddi_get_pll(struct intel_display *display, i915_reg_t reg, u32 clk_sel_mask, u32 clk_sel_shift) { enum intel_dpll_id id; - id = (intel_de_read(i915, reg) & clk_sel_mask) >> clk_sel_shift; + id = (intel_de_read(display, reg) & clk_sel_mask) >> clk_sel_shift; - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } static void adls_ddi_enable_clock(struct intel_encoder *encoder, @@ -1597,10 +1597,10 @@ static bool adls_ddi_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *adls_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_get_pll(i915, ADLS_DPCLKA_CFGCR(phy), + return _icl_ddi_get_pll(display, ADLS_DPCLKA_CFGCR(phy), ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy), ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy)); } @@ -1641,10 +1641,10 @@ static bool rkl_ddi_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *rkl_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0, + return _icl_ddi_get_pll(display, ICL_DPCLKA_CFGCR0, RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy)); } @@ -1694,12 +1694,12 @@ static bool dg1_ddi_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); enum intel_dpll_id id; u32 val; - val = intel_de_read(i915, DG1_DPCLKA_CFGCR0(phy)); + val = intel_de_read(display, DG1_DPCLKA_CFGCR0(phy)); val &= DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy); val >>= DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy); id = val; @@ -1712,7 +1712,7 @@ static struct intel_shared_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder) if (phy >= PHY_C) id += DPLL_ID_DG1_DPLL2; - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder, @@ -1751,10 +1751,10 @@ static bool icl_ddi_combo_is_clock_enabled(struct intel_encoder *encoder) struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0, + return _icl_ddi_get_pll(display, ICL_DPCLKA_CFGCR0, ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy)); } @@ -1859,13 +1859,13 @@ static bool icl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *icl_ddi_tc_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); enum port port = encoder->port; enum intel_dpll_id id; u32 tmp; - tmp = intel_de_read(i915, DDI_CLK_SEL(port)); + tmp = intel_de_read(display, DDI_CLK_SEL(port)); switch (tmp & DDI_CLK_SEL_MASK) { case DDI_CLK_SEL_TBT_162: @@ -1884,12 +1884,12 @@ static struct intel_shared_dpll *icl_ddi_tc_get_pll(struct intel_encoder *encode return NULL; } - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder->base.dev); enum intel_dpll_id id; switch (encoder->port) { @@ -1907,7 +1907,7 @@ static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder) return NULL; } - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } static void skl_ddi_enable_clock(struct intel_encoder *encoder, @@ -1958,12 +1958,12 @@ static bool skl_ddi_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; enum intel_dpll_id id; u32 tmp; - tmp = intel_de_read(i915, DPLL_CTRL2); + tmp = intel_de_read(display, DPLL_CTRL2); /* * FIXME Not sure if the override affects both @@ -1975,7 +1975,7 @@ static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder) id = (tmp & DPLL_CTRL2_DDI_CLK_SEL_MASK(port)) >> DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port); - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } void hsw_ddi_enable_clock(struct intel_encoder *encoder, @@ -2009,12 +2009,12 @@ bool hsw_ddi_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; enum intel_dpll_id id; u32 tmp; - tmp = intel_de_read(i915, PORT_CLK_SEL(port)); + tmp = intel_de_read(display, PORT_CLK_SEL(port)); switch (tmp & PORT_CLK_SEL_MASK) { case PORT_CLK_SEL_WRPLL1: @@ -2042,7 +2042,7 @@ static struct intel_shared_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder) return NULL; } - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } void intel_ddi_enable_clock(struct intel_encoder *encoder, @@ -2122,13 +2122,13 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) } static void -tgl_dkl_phy_check_and_rewrite(struct drm_i915_private *dev_priv, +tgl_dkl_phy_check_and_rewrite(struct intel_display *display, enum tc_port tc_port, u32 ln0, u32 ln1) { - if (ln0 != intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 0))) - intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 0), ln0); - if (ln1 != intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 1))) - intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 1), ln1); + if (ln0 != intel_dkl_phy_read(display, DKL_DP_MODE(tc_port, 0))) + intel_dkl_phy_write(display, DKL_DP_MODE(tc_port, 0), ln0); + if (ln1 != intel_dkl_phy_read(display, DKL_DP_MODE(tc_port, 1))) + intel_dkl_phy_write(display, DKL_DP_MODE(tc_port, 1), ln1); } static void @@ -2136,24 +2136,23 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); enum tc_port tc_port = intel_encoder_to_tc(&dig_port->base); u32 ln0, ln1, pin_assignment; u8 width; - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) return; if (!intel_encoder_is_tc(&dig_port->base) || intel_tc_port_in_tbt_alt_mode(dig_port)) return; - if (DISPLAY_VER(dev_priv) >= 12) { - ln0 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 0)); - ln1 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 1)); + if (DISPLAY_VER(display) >= 12) { + ln0 = intel_dkl_phy_read(display, DKL_DP_MODE(tc_port, 0)); + ln1 = intel_dkl_phy_read(display, DKL_DP_MODE(tc_port, 1)); } else { - ln0 = intel_de_read(dev_priv, MG_DP_MODE(0, tc_port)); - ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port)); + ln0 = intel_de_read(display, MG_DP_MODE(0, tc_port)); + ln1 = intel_de_read(display, MG_DP_MODE(1, tc_port)); } ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); @@ -2165,7 +2164,7 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port, switch (pin_assignment) { case 0x0: - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, !intel_tc_port_in_legacy_mode(dig_port)); if (width == 1) { ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; @@ -2210,16 +2209,16 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port, MISSING_CASE(pin_assignment); } - if (DISPLAY_VER(dev_priv) >= 12) { - intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 0), ln0); - intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 1), ln1); + if (DISPLAY_VER(display) >= 12) { + intel_dkl_phy_write(display, DKL_DP_MODE(tc_port, 0), ln0); + intel_dkl_phy_write(display, DKL_DP_MODE(tc_port, 1), ln1); /* WA_14018221282 */ if (IS_DISPLAY_VER(display, 12, 13)) - tgl_dkl_phy_check_and_rewrite(dev_priv, tc_port, ln0, ln1); + tgl_dkl_phy_check_and_rewrite(display, tc_port, ln0, ln1); } else { - intel_de_write(dev_priv, MG_DP_MODE(0, tc_port), ln0); - intel_de_write(dev_priv, MG_DP_MODE(1, tc_port), ln1); + intel_de_write(display, MG_DP_MODE(0, tc_port), ln0); + intel_de_write(display, MG_DP_MODE(1, tc_port), ln1); } } @@ -3727,12 +3726,13 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); int ln; for (ln = 0; ln < 2; ln++) - intel_dkl_phy_rmw(i915, DKL_PCS_DW5(tc_port, ln), DKL_PCS_DW5_CORE_SOFTRESET, 0); + intel_dkl_phy_rmw(display, DKL_PCS_DW5(tc_port, ln), + DKL_PCS_DW5_CORE_SOFTRESET, 0); } static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, @@ -4253,21 +4253,21 @@ void intel_ddi_get_clock(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct intel_shared_dpll *pll) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum icl_port_dpll_id port_dpll_id = ICL_PORT_DPLL_DEFAULT; struct icl_port_dpll *port_dpll = &crtc_state->icl_port_dplls[port_dpll_id]; bool pll_active; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; port_dpll->pll = pll; - pll_active = intel_dpll_get_hw_state(i915, pll, &port_dpll->hw_state); - drm_WARN_ON(&i915->drm, !pll_active); + pll_active = intel_dpll_get_hw_state(display, pll, &port_dpll->hw_state); + drm_WARN_ON(display->drm, !pll_active); icl_set_active_port_dpll(crtc_state, port_dpll_id); - crtc_state->port_clock = intel_dpll_get_freq(i915, crtc_state->shared_dpll, + crtc_state->port_clock = intel_dpll_get_freq(display, crtc_state->shared_dpll, &crtc_state->dpll_hw_state); } @@ -4356,12 +4356,12 @@ static void icl_ddi_tc_get_clock(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct intel_shared_dpll *pll) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum icl_port_dpll_id port_dpll_id; struct icl_port_dpll *port_dpll; bool pll_active; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; if (icl_ddi_tc_pll_is_tbt(pll)) @@ -4372,15 +4372,15 @@ static void icl_ddi_tc_get_clock(struct intel_encoder *encoder, port_dpll = &crtc_state->icl_port_dplls[port_dpll_id]; port_dpll->pll = pll; - pll_active = intel_dpll_get_hw_state(i915, pll, &port_dpll->hw_state); - drm_WARN_ON(&i915->drm, !pll_active); + pll_active = intel_dpll_get_hw_state(display, pll, &port_dpll->hw_state); + drm_WARN_ON(display->drm, !pll_active); icl_set_active_port_dpll(crtc_state, port_dpll_id); if (icl_ddi_tc_pll_is_tbt(crtc_state->shared_dpll)) - crtc_state->port_clock = icl_calc_tbt_pll_link(i915, encoder->port); + crtc_state->port_clock = icl_calc_tbt_pll_link(display, encoder->port); else - crtc_state->port_clock = intel_dpll_get_freq(i915, crtc_state->shared_dpll, + crtc_state->port_clock = intel_dpll_get_freq(display, crtc_state->shared_dpll, &crtc_state->dpll_hw_state); } diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index 367f8e8d9e738..faf5ca1c706d2 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -507,7 +507,6 @@ static void icl_tc_phy_aux_power_well_enable(struct intel_display *display, struct i915_power_well *power_well) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum aux_ch aux_ch = icl_aux_pw_to_ch(power_well); struct intel_digital_port *dig_port = aux_ch_to_digital_port(display, aux_ch); const struct i915_power_well_regs *regs = power_well->desc->ops->regs; @@ -539,7 +538,7 @@ icl_tc_phy_aux_power_well_enable(struct intel_display *display, tc_port = TGL_AUX_PW_TO_TC_PORT(i915_power_well_instance(power_well)->hsw.idx); - if (wait_for(intel_dkl_phy_read(dev_priv, DKL_CMN_UC_DW_27(tc_port)) & + if (wait_for(intel_dkl_phy_read(display, DKL_CMN_UC_DW_27(tc_port)) & DKL_CMN_UC_DW27_UC_HEALTH, 1)) drm_warn(display->drm, "Timeout waiting TC uC health\n"); diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy.c b/drivers/gpu/drm/i915/display/intel_dkl_phy.c index b146b4c46943e..0920f78f182e9 100644 --- a/drivers/gpu/drm/i915/display/intel_dkl_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dkl_phy.c @@ -20,20 +20,20 @@ void intel_dkl_phy_init(struct drm_i915_private *i915) } static void -dkl_phy_set_hip_idx(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg) +dkl_phy_set_hip_idx(struct intel_display *display, struct intel_dkl_phy_reg reg) { enum tc_port tc_port = DKL_REG_TC_PORT(reg); - drm_WARN_ON(&i915->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS); + drm_WARN_ON(display->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS); - intel_de_write(i915, + intel_de_write(display, HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, reg.bank_idx)); } /** * intel_dkl_phy_read - read a Dekel PHY register - * @i915: i915 device instance + * @display: intel_display device instance * @reg: Dekel PHY register * * Read the @reg Dekel PHY register. @@ -41,42 +41,42 @@ dkl_phy_set_hip_idx(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg) * Returns the read value. */ u32 -intel_dkl_phy_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg) +intel_dkl_phy_read(struct intel_display *display, struct intel_dkl_phy_reg reg) { u32 val; - spin_lock(&i915->display.dkl.phy_lock); + spin_lock(&display->dkl.phy_lock); - dkl_phy_set_hip_idx(i915, reg); - val = intel_de_read(i915, DKL_REG_MMIO(reg)); + dkl_phy_set_hip_idx(display, reg); + val = intel_de_read(display, DKL_REG_MMIO(reg)); - spin_unlock(&i915->display.dkl.phy_lock); + spin_unlock(&display->dkl.phy_lock); return val; } /** * intel_dkl_phy_write - write a Dekel PHY register - * @i915: i915 device instance + * @display: intel_display device instance * @reg: Dekel PHY register * @val: value to write * * Write @val to the @reg Dekel PHY register. */ void -intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 val) +intel_dkl_phy_write(struct intel_display *display, struct intel_dkl_phy_reg reg, u32 val) { - spin_lock(&i915->display.dkl.phy_lock); + spin_lock(&display->dkl.phy_lock); - dkl_phy_set_hip_idx(i915, reg); - intel_de_write(i915, DKL_REG_MMIO(reg), val); + dkl_phy_set_hip_idx(display, reg); + intel_de_write(display, DKL_REG_MMIO(reg), val); - spin_unlock(&i915->display.dkl.phy_lock); + spin_unlock(&display->dkl.phy_lock); } /** * intel_dkl_phy_rmw - read-modify-write a Dekel PHY register - * @i915: i915 device instance + * @display: display device instance * @reg: Dekel PHY register * @clear: mask to clear * @set: mask to set @@ -85,30 +85,30 @@ intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, * this value back to the register if the value differs from the read one. */ void -intel_dkl_phy_rmw(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 clear, u32 set) +intel_dkl_phy_rmw(struct intel_display *display, struct intel_dkl_phy_reg reg, u32 clear, u32 set) { - spin_lock(&i915->display.dkl.phy_lock); + spin_lock(&display->dkl.phy_lock); - dkl_phy_set_hip_idx(i915, reg); - intel_de_rmw(i915, DKL_REG_MMIO(reg), clear, set); + dkl_phy_set_hip_idx(display, reg); + intel_de_rmw(display, DKL_REG_MMIO(reg), clear, set); - spin_unlock(&i915->display.dkl.phy_lock); + spin_unlock(&display->dkl.phy_lock); } /** * intel_dkl_phy_posting_read - do a posting read from a Dekel PHY register - * @i915: i915 device instance + * @display: display device instance * @reg: Dekel PHY register * * Read the @reg Dekel PHY register without returning the read value. */ void -intel_dkl_phy_posting_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg) +intel_dkl_phy_posting_read(struct intel_display *display, struct intel_dkl_phy_reg reg) { - spin_lock(&i915->display.dkl.phy_lock); + spin_lock(&display->dkl.phy_lock); - dkl_phy_set_hip_idx(i915, reg); - intel_de_posting_read(i915, DKL_REG_MMIO(reg)); + dkl_phy_set_hip_idx(display, reg); + intel_de_posting_read(display, DKL_REG_MMIO(reg)); - spin_unlock(&i915->display.dkl.phy_lock); + spin_unlock(&display->dkl.phy_lock); } diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy.h b/drivers/gpu/drm/i915/display/intel_dkl_phy.h index 5956ec3e940b1..1d96e6be657ca 100644 --- a/drivers/gpu/drm/i915/display/intel_dkl_phy.h +++ b/drivers/gpu/drm/i915/display/intel_dkl_phy.h @@ -11,15 +11,16 @@ #include "intel_dkl_phy_regs.h" struct drm_i915_private; +struct intel_display; void intel_dkl_phy_init(struct drm_i915_private *i915); u32 -intel_dkl_phy_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg); +intel_dkl_phy_read(struct intel_display *display, struct intel_dkl_phy_reg reg); void -intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 val); +intel_dkl_phy_write(struct intel_display *display, struct intel_dkl_phy_reg reg, u32 val); void -intel_dkl_phy_rmw(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 clear, u32 set); +intel_dkl_phy_rmw(struct intel_display *display, struct intel_dkl_phy_reg reg, u32 clear, u32 set); void -intel_dkl_phy_posting_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg); +intel_dkl_phy_posting_read(struct intel_display *display, struct intel_dkl_phy_reg reg); #endif /* __INTEL_DKL_PHY_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index f295d86070e95..16332c0635b01 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -65,7 +65,7 @@ struct intel_shared_dpll_funcs { * Hook for enabling the pll, called from intel_enable_shared_dpll() if * the pll is not already enabled. */ - void (*enable)(struct drm_i915_private *i915, + void (*enable)(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state); @@ -74,7 +74,7 @@ struct intel_shared_dpll_funcs { * only when it is safe to disable the pll, i.e., there are no more * tracked users for it. */ - void (*disable)(struct drm_i915_private *i915, + void (*disable)(struct intel_display *display, struct intel_shared_dpll *pll); /* @@ -82,7 +82,7 @@ struct intel_shared_dpll_funcs { * registers. This is used for initial hw state readout and state * verification after a mode set. */ - bool (*get_hw_state)(struct drm_i915_private *i915, + bool (*get_hw_state)(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state); @@ -90,7 +90,7 @@ struct intel_shared_dpll_funcs { * Hook for calculating the pll's output frequency based on its passed * in state. */ - int (*get_freq)(struct drm_i915_private *i915, + int (*get_freq)(struct intel_display *i915, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state); }; @@ -148,17 +148,16 @@ intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s) /** * intel_get_shared_dpll_by_id - get a DPLL given its id - * @i915: i915 device instance + * @display: intel_display device instance * @id: pll id * * Returns: * A pointer to the DPLL with @id */ struct intel_shared_dpll * -intel_get_shared_dpll_by_id(struct drm_i915_private *i915, +intel_get_shared_dpll_by_id(struct intel_display *display, enum intel_dpll_id id) { - struct intel_display *display = &i915->display; struct intel_shared_dpll *pll; int i; @@ -184,7 +183,7 @@ void assert_shared_dpll(struct drm_i915_private *i915, "asserting DPLL %s with no DPLL\n", str_on_off(state))) return; - cur_state = intel_dpll_get_hw_state(i915, pll, &hw_state); + cur_state = intel_dpll_get_hw_state(display, pll, &hw_state); INTEL_DISPLAY_STATE_WARN(display, cur_state != state, "%s assertion failure (expected %s, current %s)\n", pll->info->name, str_on_off(state), @@ -202,12 +201,12 @@ enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port) } static i915_reg_t -intel_combo_pll_enable_reg(struct drm_i915_private *i915, +intel_combo_pll_enable_reg(struct intel_display *display, struct intel_shared_dpll *pll) { - if (IS_DG1(i915)) + if (display->platform.dg1) return DG1_DPLL_ENABLE(pll->info->id); - else if ((IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) && + else if ((display->platform.jasperlake || display->platform.elkhartlake) && (pll->info->id == DPLL_ID_EHL_DPLL4)) return MG_PLL_ENABLE(0); @@ -215,36 +214,32 @@ intel_combo_pll_enable_reg(struct drm_i915_private *i915, } static i915_reg_t -intel_tc_pll_enable_reg(struct drm_i915_private *i915, +intel_tc_pll_enable_reg(struct intel_display *display, struct intel_shared_dpll *pll) { const enum intel_dpll_id id = pll->info->id; enum tc_port tc_port = icl_pll_id_to_tc_port(id); - if (IS_ALDERLAKE_P(i915)) + if (display->platform.alderlake_p) return ADLP_PORTTC_PLL_ENABLE(tc_port); return MG_PLL_ENABLE(tc_port); } -static void _intel_enable_shared_dpll(struct drm_i915_private *i915, +static void _intel_enable_shared_dpll(struct intel_display *display, struct intel_shared_dpll *pll) { - struct intel_display *display = &i915->display; - if (pll->info->power_domain) pll->wakeref = intel_display_power_get(display, pll->info->power_domain); - pll->info->funcs->enable(i915, pll, &pll->state.hw_state); + pll->info->funcs->enable(display, pll, &pll->state.hw_state); pll->on = true; } -static void _intel_disable_shared_dpll(struct drm_i915_private *i915, +static void _intel_disable_shared_dpll(struct intel_display *display, struct intel_shared_dpll *pll) { - struct intel_display *display = &i915->display; - - pll->info->funcs->disable(i915, pll); + pll->info->funcs->disable(display, pll); pll->on = false; if (pll->info->power_domain) @@ -259,42 +254,43 @@ static void _intel_disable_shared_dpll(struct drm_i915_private *i915, */ void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_shared_dpll *pll = crtc_state->shared_dpll; unsigned int pipe_mask = BIT(crtc->pipe); unsigned int old_mask; - if (drm_WARN_ON(&i915->drm, pll == NULL)) + if (drm_WARN_ON(display->drm, !pll)) return; - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); old_mask = pll->active_mask; - if (drm_WARN_ON(&i915->drm, !(pll->state.pipe_mask & pipe_mask)) || - drm_WARN_ON(&i915->drm, pll->active_mask & pipe_mask)) + if (drm_WARN_ON(display->drm, !(pll->state.pipe_mask & pipe_mask)) || + drm_WARN_ON(display->drm, pll->active_mask & pipe_mask)) goto out; pll->active_mask |= pipe_mask; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "enable %s (active 0x%x, on? %d) for [CRTC:%d:%s]\n", pll->info->name, pll->active_mask, pll->on, crtc->base.base.id, crtc->base.name); if (old_mask) { - drm_WARN_ON(&i915->drm, !pll->on); + drm_WARN_ON(display->drm, !pll->on); assert_shared_dpll_enabled(i915, pll); goto out; } - drm_WARN_ON(&i915->drm, pll->on); + drm_WARN_ON(display->drm, pll->on); - drm_dbg_kms(&i915->drm, "enabling %s\n", pll->info->name); + drm_dbg_kms(display->drm, "enabling %s\n", pll->info->name); - _intel_enable_shared_dpll(i915, pll); + _intel_enable_shared_dpll(display, pll); out: - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } /** @@ -305,48 +301,48 @@ void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state) */ void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_shared_dpll *pll = crtc_state->shared_dpll; unsigned int pipe_mask = BIT(crtc->pipe); /* PCH only available on ILK+ */ - if (DISPLAY_VER(i915) < 5) + if (DISPLAY_VER(display) < 5) return; if (pll == NULL) return; - mutex_lock(&i915->display.dpll.lock); - if (drm_WARN(&i915->drm, !(pll->active_mask & pipe_mask), + mutex_lock(&display->dpll.lock); + if (drm_WARN(display->drm, !(pll->active_mask & pipe_mask), "%s not used by [CRTC:%d:%s]\n", pll->info->name, crtc->base.base.id, crtc->base.name)) goto out; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "disable %s (active 0x%x, on? %d) for [CRTC:%d:%s]\n", pll->info->name, pll->active_mask, pll->on, crtc->base.base.id, crtc->base.name); assert_shared_dpll_enabled(i915, pll); - drm_WARN_ON(&i915->drm, !pll->on); + drm_WARN_ON(display->drm, !pll->on); pll->active_mask &= ~pipe_mask; if (pll->active_mask) goto out; - drm_dbg_kms(&i915->drm, "disabling %s\n", pll->info->name); + drm_dbg_kms(display->drm, "disabling %s\n", pll->info->name); - _intel_disable_shared_dpll(i915, pll); + _intel_disable_shared_dpll(display, pll); out: - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } static unsigned long -intel_dpll_mask_all(struct drm_i915_private *i915) +intel_dpll_mask_all(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_shared_dpll *pll; unsigned long dpll_mask = 0; int i; @@ -366,20 +362,20 @@ intel_find_shared_dpll(struct intel_atomic_state *state, const struct intel_dpll_hw_state *dpll_hw_state, unsigned long dpll_mask) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - unsigned long dpll_mask_all = intel_dpll_mask_all(i915); + struct intel_display *display = to_intel_display(crtc); + unsigned long dpll_mask_all = intel_dpll_mask_all(display); struct intel_shared_dpll_state *shared_dpll; struct intel_shared_dpll *unused_pll = NULL; enum intel_dpll_id id; shared_dpll = intel_atomic_get_shared_dpll_state(&state->base); - drm_WARN_ON(&i915->drm, dpll_mask & ~dpll_mask_all); + drm_WARN_ON(display->drm, dpll_mask & ~dpll_mask_all); for_each_set_bit(id, &dpll_mask, fls(dpll_mask_all)) { struct intel_shared_dpll *pll; - pll = intel_get_shared_dpll_by_id(i915, id); + pll = intel_get_shared_dpll_by_id(display, id); if (!pll) continue; @@ -393,7 +389,7 @@ intel_find_shared_dpll(struct intel_atomic_state *state, if (memcmp(dpll_hw_state, &shared_dpll[pll->index].hw_state, sizeof(*dpll_hw_state)) == 0) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] sharing existing %s (pipe mask 0x%x, active 0x%x)\n", crtc->base.base.id, crtc->base.name, pll->info->name, @@ -405,7 +401,7 @@ intel_find_shared_dpll(struct intel_atomic_state *state, /* Ok no matching timings, maybe there's a free one? */ if (unused_pll) { - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] allocated %s\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] allocated %s\n", crtc->base.base.id, crtc->base.name, unused_pll->info->name); return unused_pll; @@ -528,11 +524,10 @@ void intel_shared_dpll_swap_state(struct intel_atomic_state *state) swap(pll->state, shared_dpll[pll->index]); } -static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *i915, +static bool ibx_pch_dpll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - struct intel_display *display = &i915->display; struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx; const enum intel_dpll_id id = pll->info->id; intel_wakeref_t wakeref; @@ -543,10 +538,10 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *i915, if (!wakeref) return false; - val = intel_de_read(i915, PCH_DPLL(id)); + val = intel_de_read(display, PCH_DPLL(id)); hw_state->dpll = val; - hw_state->fp0 = intel_de_read(i915, PCH_FP0(id)); - hw_state->fp1 = intel_de_read(i915, PCH_FP1(id)); + hw_state->fp0 = intel_de_read(display, PCH_FP0(id)); + hw_state->fp1 = intel_de_read(display, PCH_FP1(id)); intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); @@ -566,23 +561,24 @@ static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *i915) "PCH refclk assertion failure, should be active but is disabled\n"); } -static void ibx_pch_dpll_enable(struct drm_i915_private *i915, +static void ibx_pch_dpll_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { + struct drm_i915_private *i915 = to_i915(display->drm); const struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx; const enum intel_dpll_id id = pll->info->id; /* PCH refclock must be enabled first */ ibx_assert_pch_refclk_enabled(i915); - intel_de_write(i915, PCH_FP0(id), hw_state->fp0); - intel_de_write(i915, PCH_FP1(id), hw_state->fp1); + intel_de_write(display, PCH_FP0(id), hw_state->fp0); + intel_de_write(display, PCH_FP1(id), hw_state->fp1); - intel_de_write(i915, PCH_DPLL(id), hw_state->dpll); + intel_de_write(display, PCH_DPLL(id), hw_state->dpll); /* Wait for the clocks to stabilize. */ - intel_de_posting_read(i915, PCH_DPLL(id)); + intel_de_posting_read(display, PCH_DPLL(id)); udelay(150); /* The pixel multiplier can only be updated once the @@ -590,18 +586,18 @@ static void ibx_pch_dpll_enable(struct drm_i915_private *i915, * * So write it again. */ - intel_de_write(i915, PCH_DPLL(id), hw_state->dpll); - intel_de_posting_read(i915, PCH_DPLL(id)); + intel_de_write(display, PCH_DPLL(id), hw_state->dpll); + intel_de_posting_read(display, PCH_DPLL(id)); udelay(200); } -static void ibx_pch_dpll_disable(struct drm_i915_private *i915, +static void ibx_pch_dpll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { const enum intel_dpll_id id = pll->info->id; - intel_de_write(i915, PCH_DPLL(id), 0); - intel_de_posting_read(i915, PCH_DPLL(id)); + intel_de_write(display, PCH_DPLL(id), 0); + intel_de_posting_read(display, PCH_DPLL(id)); udelay(200); } @@ -616,18 +612,19 @@ static int ibx_get_dpll(struct intel_atomic_state *state, struct intel_crtc *crtc, struct intel_encoder *encoder) { + struct intel_display *display = to_intel_display(state); + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_shared_dpll *pll; enum intel_dpll_id id; if (HAS_PCH_IBX(i915)) { /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ id = (enum intel_dpll_id) crtc->pipe; - pll = intel_get_shared_dpll_by_id(i915, id); + pll = intel_get_shared_dpll_by_id(display, id); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] using pre-allocated %s\n", crtc->base.base.id, crtc->base.name, pll->info->name); @@ -696,66 +693,67 @@ static const struct intel_dpll_mgr pch_pll_mgr = { .compare_hw_state = ibx_compare_hw_state, }; -static void hsw_ddi_wrpll_enable(struct drm_i915_private *i915, +static void hsw_ddi_wrpll_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw; const enum intel_dpll_id id = pll->info->id; - intel_de_write(i915, WRPLL_CTL(id), hw_state->wrpll); - intel_de_posting_read(i915, WRPLL_CTL(id)); + intel_de_write(display, WRPLL_CTL(id), hw_state->wrpll); + intel_de_posting_read(display, WRPLL_CTL(id)); udelay(20); } -static void hsw_ddi_spll_enable(struct drm_i915_private *i915, +static void hsw_ddi_spll_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw; - intel_de_write(i915, SPLL_CTL, hw_state->spll); - intel_de_posting_read(i915, SPLL_CTL); + intel_de_write(display, SPLL_CTL, hw_state->spll); + intel_de_posting_read(display, SPLL_CTL); udelay(20); } -static void hsw_ddi_wrpll_disable(struct drm_i915_private *i915, +static void hsw_ddi_wrpll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { + struct drm_i915_private *i915 = to_i915(display->drm); const enum intel_dpll_id id = pll->info->id; - intel_de_rmw(i915, WRPLL_CTL(id), WRPLL_PLL_ENABLE, 0); - intel_de_posting_read(i915, WRPLL_CTL(id)); + intel_de_rmw(display, WRPLL_CTL(id), WRPLL_PLL_ENABLE, 0); + intel_de_posting_read(display, WRPLL_CTL(id)); /* * Try to set up the PCH reference clock once all DPLLs * that depend on it have been shut down. */ - if (i915->display.dpll.pch_ssc_use & BIT(id)) + if (display->dpll.pch_ssc_use & BIT(id)) intel_init_pch_refclk(i915); } -static void hsw_ddi_spll_disable(struct drm_i915_private *i915, +static void hsw_ddi_spll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { + struct drm_i915_private *i915 = to_i915(display->drm); enum intel_dpll_id id = pll->info->id; - intel_de_rmw(i915, SPLL_CTL, SPLL_PLL_ENABLE, 0); - intel_de_posting_read(i915, SPLL_CTL); + intel_de_rmw(display, SPLL_CTL, SPLL_PLL_ENABLE, 0); + intel_de_posting_read(display, SPLL_CTL); /* * Try to set up the PCH reference clock once all DPLLs * that depend on it have been shut down. */ - if (i915->display.dpll.pch_ssc_use & BIT(id)) + if (display->dpll.pch_ssc_use & BIT(id)) intel_init_pch_refclk(i915); } -static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *i915, +static bool hsw_ddi_wrpll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - struct intel_display *display = &i915->display; struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw; const enum intel_dpll_id id = pll->info->id; intel_wakeref_t wakeref; @@ -766,7 +764,7 @@ static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *i915, if (!wakeref) return false; - val = intel_de_read(i915, WRPLL_CTL(id)); + val = intel_de_read(display, WRPLL_CTL(id)); hw_state->wrpll = val; intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); @@ -774,11 +772,10 @@ static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *i915, return val & WRPLL_PLL_ENABLE; } -static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *i915, +static bool hsw_ddi_spll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - struct intel_display *display = &i915->display; struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw; intel_wakeref_t wakeref; u32 val; @@ -788,7 +785,7 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *i915, if (!wakeref) return false; - val = intel_de_read(i915, SPLL_CTL); + val = intel_de_read(display, SPLL_CTL); hw_state->spll = val; intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref); @@ -1002,7 +999,7 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */, *r2_out = best.r2; } -static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *i915, +static int hsw_ddi_wrpll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { @@ -1014,8 +1011,8 @@ static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *i915, switch (wrpll & WRPLL_REF_MASK) { case WRPLL_REF_SPECIAL_HSW: /* Muxed-SSC for BDW, non-SSC for non-ULT HSW. */ - if (IS_HASWELL(i915) && !IS_HASWELL_ULT(i915)) { - refclk = i915->display.dpll.ref_clks.nssc; + if (display->platform.haswell && !display->platform.haswell_ult) { + refclk = display->dpll.ref_clks.nssc; break; } fallthrough; @@ -1025,7 +1022,7 @@ static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *i915, * code only cares about 5% accuracy, and spread is a max of * 0.5% downspread. */ - refclk = i915->display.dpll.ref_clks.ssc; + refclk = display->dpll.ref_clks.ssc; break; case WRPLL_REF_LCPLL: refclk = 2700000; @@ -1047,7 +1044,7 @@ static int hsw_ddi_wrpll_compute_dpll(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct hsw_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.hsw; @@ -1060,7 +1057,7 @@ hsw_ddi_wrpll_compute_dpll(struct intel_atomic_state *state, WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | WRPLL_DIVIDER_POST(p); - crtc_state->port_clock = hsw_ddi_wrpll_get_freq(i915, NULL, + crtc_state->port_clock = hsw_ddi_wrpll_get_freq(display, NULL, &crtc_state->dpll_hw_state); return 0; @@ -1100,7 +1097,7 @@ hsw_ddi_lcpll_compute_dpll(struct intel_crtc_state *crtc_state) static struct intel_shared_dpll * hsw_ddi_lcpll_get_dpll(struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); struct intel_shared_dpll *pll; enum intel_dpll_id pll_id; int clock = crtc_state->port_clock; @@ -1120,7 +1117,7 @@ hsw_ddi_lcpll_get_dpll(struct intel_crtc_state *crtc_state) return NULL; } - pll = intel_get_shared_dpll_by_id(i915, pll_id); + pll = intel_get_shared_dpll_by_id(display, pll_id); if (!pll) return NULL; @@ -1128,7 +1125,7 @@ hsw_ddi_lcpll_get_dpll(struct intel_crtc_state *crtc_state) return pll; } -static int hsw_ddi_lcpll_get_freq(struct drm_i915_private *i915, +static int hsw_ddi_lcpll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { @@ -1145,7 +1142,7 @@ static int hsw_ddi_lcpll_get_freq(struct drm_i915_private *i915, link_clock = 270000; break; default: - drm_WARN(&i915->drm, 1, "bad port clock sel\n"); + drm_WARN(display->drm, 1, "bad port clock sel\n"); break; } @@ -1180,7 +1177,7 @@ hsw_ddi_spll_get_dpll(struct intel_atomic_state *state, BIT(DPLL_ID_SPLL)); } -static int hsw_ddi_spll_get_freq(struct drm_i915_private *i915, +static int hsw_ddi_spll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { @@ -1198,7 +1195,7 @@ static int hsw_ddi_spll_get_freq(struct drm_i915_private *i915, link_clock = 270000; break; default: - drm_WARN(&i915->drm, 1, "bad spll freq\n"); + drm_WARN(display->drm, 1, "bad spll freq\n"); break; } @@ -1291,18 +1288,18 @@ static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = { .get_freq = hsw_ddi_spll_get_freq, }; -static void hsw_ddi_lcpll_enable(struct drm_i915_private *i915, +static void hsw_ddi_lcpll_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *hw_state) { } -static void hsw_ddi_lcpll_disable(struct drm_i915_private *i915, +static void hsw_ddi_lcpll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { } -static bool hsw_ddi_lcpll_get_hw_state(struct drm_i915_private *i915, +static bool hsw_ddi_lcpll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { @@ -1370,21 +1367,21 @@ static const struct skl_dpll_regs skl_dpll_regs[4] = { }, }; -static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *i915, +static void skl_ddi_pll_write_ctrl1(struct intel_display *display, struct intel_shared_dpll *pll, const struct skl_dpll_hw_state *hw_state) { const enum intel_dpll_id id = pll->info->id; - intel_de_rmw(i915, DPLL_CTRL1, + intel_de_rmw(display, DPLL_CTRL1, DPLL_CTRL1_HDMI_MODE(id) | DPLL_CTRL1_SSC(id) | DPLL_CTRL1_LINK_RATE_MASK(id), hw_state->ctrl1 << (id * 6)); - intel_de_posting_read(i915, DPLL_CTRL1); + intel_de_posting_read(display, DPLL_CTRL1); } -static void skl_ddi_pll_enable(struct drm_i915_private *i915, +static void skl_ddi_pll_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { @@ -1392,50 +1389,49 @@ static void skl_ddi_pll_enable(struct drm_i915_private *i915, const struct skl_dpll_regs *regs = skl_dpll_regs; const enum intel_dpll_id id = pll->info->id; - skl_ddi_pll_write_ctrl1(i915, pll, hw_state); + skl_ddi_pll_write_ctrl1(display, pll, hw_state); - intel_de_write(i915, regs[id].cfgcr1, hw_state->cfgcr1); - intel_de_write(i915, regs[id].cfgcr2, hw_state->cfgcr2); - intel_de_posting_read(i915, regs[id].cfgcr1); - intel_de_posting_read(i915, regs[id].cfgcr2); + intel_de_write(display, regs[id].cfgcr1, hw_state->cfgcr1); + intel_de_write(display, regs[id].cfgcr2, hw_state->cfgcr2); + intel_de_posting_read(display, regs[id].cfgcr1); + intel_de_posting_read(display, regs[id].cfgcr2); /* the enable bit is always bit 31 */ - intel_de_rmw(i915, regs[id].ctl, 0, LCPLL_PLL_ENABLE); + intel_de_rmw(display, regs[id].ctl, 0, LCPLL_PLL_ENABLE); - if (intel_de_wait_for_set(i915, DPLL_STATUS, DPLL_LOCK(id), 5)) - drm_err(&i915->drm, "DPLL %d not locked\n", id); + if (intel_de_wait_for_set(display, DPLL_STATUS, DPLL_LOCK(id), 5)) + drm_err(display->drm, "DPLL %d not locked\n", id); } -static void skl_ddi_dpll0_enable(struct drm_i915_private *i915, +static void skl_ddi_dpll0_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl; - skl_ddi_pll_write_ctrl1(i915, pll, hw_state); + skl_ddi_pll_write_ctrl1(display, pll, hw_state); } -static void skl_ddi_pll_disable(struct drm_i915_private *i915, +static void skl_ddi_pll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { const struct skl_dpll_regs *regs = skl_dpll_regs; const enum intel_dpll_id id = pll->info->id; /* the enable bit is always bit 31 */ - intel_de_rmw(i915, regs[id].ctl, LCPLL_PLL_ENABLE, 0); - intel_de_posting_read(i915, regs[id].ctl); + intel_de_rmw(display, regs[id].ctl, LCPLL_PLL_ENABLE, 0); + intel_de_posting_read(display, regs[id].ctl); } -static void skl_ddi_dpll0_disable(struct drm_i915_private *i915, +static void skl_ddi_dpll0_disable(struct intel_display *display, struct intel_shared_dpll *pll) { } -static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *i915, +static bool skl_ddi_pll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - struct intel_display *display = &i915->display; struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl; const struct skl_dpll_regs *regs = skl_dpll_regs; const enum intel_dpll_id id = pll->info->id; @@ -1450,17 +1446,17 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *i915, ret = false; - val = intel_de_read(i915, regs[id].ctl); + val = intel_de_read(display, regs[id].ctl); if (!(val & LCPLL_PLL_ENABLE)) goto out; - val = intel_de_read(i915, DPLL_CTRL1); + val = intel_de_read(display, DPLL_CTRL1); hw_state->ctrl1 = (val >> (id * 6)) & 0x3f; /* avoid reading back stale values if HDMI mode is not enabled */ if (val & DPLL_CTRL1_HDMI_MODE(id)) { - hw_state->cfgcr1 = intel_de_read(i915, regs[id].cfgcr1); - hw_state->cfgcr2 = intel_de_read(i915, regs[id].cfgcr2); + hw_state->cfgcr1 = intel_de_read(display, regs[id].cfgcr1); + hw_state->cfgcr2 = intel_de_read(display, regs[id].cfgcr2); } ret = true; @@ -1470,11 +1466,10 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *i915, return ret; } -static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *i915, +static bool skl_ddi_dpll0_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - struct intel_display *display = &i915->display; struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl; const struct skl_dpll_regs *regs = skl_dpll_regs; const enum intel_dpll_id id = pll->info->id; @@ -1490,11 +1485,11 @@ static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *i915, ret = false; /* DPLL0 is always enabled since it drives CDCLK */ - val = intel_de_read(i915, regs[id].ctl); - if (drm_WARN_ON(&i915->drm, !(val & LCPLL_PLL_ENABLE))) + val = intel_de_read(display, regs[id].ctl); + if (drm_WARN_ON(display->drm, !(val & LCPLL_PLL_ENABLE))) goto out; - val = intel_de_read(i915, DPLL_CTRL1); + val = intel_de_read(display, DPLL_CTRL1); hw_state->ctrl1 = (val >> (id * 6)) & 0x3f; ret = true; @@ -1744,12 +1739,12 @@ skl_ddi_calculate_wrpll(int clock, return 0; } -static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915, +static int skl_ddi_wrpll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl; - int ref_clock = i915->display.dpll.ref_clks.nssc; + int ref_clock = display->dpll.ref_clks.nssc; u32 p0, p1, p2, dco_freq; p0 = hw_state->cfgcr2 & DPLL_CFGCR2_PDIV_MASK; @@ -1776,7 +1771,7 @@ static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915, * Incorrect ASUS-Z170M BIOS setting, the HW seems to ignore bit#0, * handling it the same way as PDIV_7. */ - drm_dbg_kms(&i915->drm, "Invalid WRPLL PDIV divider value, fixing it.\n"); + drm_dbg_kms(display->drm, "Invalid WRPLL PDIV divider value, fixing it.\n"); fallthrough; case DPLL_CFGCR2_PDIV_7: p0 = 7; @@ -1810,7 +1805,7 @@ static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915, dco_freq += ((hw_state->cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * ref_clock / 0x8000; - if (drm_WARN_ON(&i915->drm, p0 == 0 || p1 == 0 || p2 == 0)) + if (drm_WARN_ON(display->drm, p0 == 0 || p1 == 0 || p2 == 0)) return 0; return dco_freq / (p0 * p1 * p2 * 5); @@ -1818,13 +1813,13 @@ static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915, static int skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); struct skl_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.skl; struct skl_wrpll_params wrpll_params = {}; int ret; ret = skl_ddi_calculate_wrpll(crtc_state->port_clock, - i915->display.dpll.ref_clks.nssc, &wrpll_params); + display->dpll.ref_clks.nssc, &wrpll_params); if (ret) return ret; @@ -1848,7 +1843,7 @@ static int skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state) DPLL_CFGCR2_PDIV(wrpll_params.pdiv) | wrpll_params.central_freq; - crtc_state->port_clock = skl_ddi_wrpll_get_freq(i915, NULL, + crtc_state->port_clock = skl_ddi_wrpll_get_freq(display, NULL, &crtc_state->dpll_hw_state); return 0; @@ -1892,7 +1887,7 @@ skl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state) return 0; } -static int skl_ddi_lcpll_get_freq(struct drm_i915_private *i915, +static int skl_ddi_lcpll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { @@ -1920,7 +1915,7 @@ static int skl_ddi_lcpll_get_freq(struct drm_i915_private *i915, link_clock = 270000; break; default: - drm_WARN(&i915->drm, 1, "Unsupported link rate\n"); + drm_WARN(display->drm, 1, "Unsupported link rate\n"); break; } @@ -1971,7 +1966,7 @@ static int skl_get_dpll(struct intel_atomic_state *state, return 0; } -static int skl_ddi_pll_get_freq(struct drm_i915_private *i915, +static int skl_ddi_pll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { @@ -1982,9 +1977,9 @@ static int skl_ddi_pll_get_freq(struct drm_i915_private *i915, * the internal shift for each field */ if (hw_state->ctrl1 & DPLL_CTRL1_HDMI_MODE(0)) - return skl_ddi_wrpll_get_freq(i915, pll, dpll_hw_state); + return skl_ddi_wrpll_get_freq(display, pll, dpll_hw_state); else - return skl_ddi_lcpll_get_freq(i915, pll, dpll_hw_state); + return skl_ddi_lcpll_get_freq(display, pll, dpll_hw_state); } static void skl_update_dpll_ref_clks(struct drm_i915_private *i915) @@ -2046,11 +2041,10 @@ static const struct intel_dpll_mgr skl_pll_mgr = { .compare_hw_state = skl_compare_hw_state, }; -static void bxt_ddi_pll_enable(struct drm_i915_private *i915, +static void bxt_ddi_pll_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { - struct intel_display *display = &i915->display; const struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt; enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */ enum dpio_phy phy; @@ -2060,120 +2054,119 @@ static void bxt_ddi_pll_enable(struct drm_i915_private *i915, bxt_port_to_phy_channel(display, port, &phy, &ch); /* Non-SSC reference */ - intel_de_rmw(i915, BXT_PORT_PLL_ENABLE(port), 0, PORT_PLL_REF_SEL); + intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), 0, PORT_PLL_REF_SEL); - if (IS_GEMINILAKE(i915)) { - intel_de_rmw(i915, BXT_PORT_PLL_ENABLE(port), + if (display->platform.geminilake) { + intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), 0, PORT_PLL_POWER_ENABLE); - if (wait_for_us((intel_de_read(i915, BXT_PORT_PLL_ENABLE(port)) & + if (wait_for_us((intel_de_read(display, BXT_PORT_PLL_ENABLE(port)) & PORT_PLL_POWER_STATE), 200)) - drm_err(&i915->drm, + drm_err(display->drm, "Power state not set for PLL:%d\n", port); } /* Disable 10 bit clock */ - intel_de_rmw(i915, BXT_PORT_PLL_EBB_4(phy, ch), + intel_de_rmw(display, BXT_PORT_PLL_EBB_4(phy, ch), PORT_PLL_10BIT_CLK_ENABLE, 0); /* Write P1 & P2 */ - intel_de_rmw(i915, BXT_PORT_PLL_EBB_0(phy, ch), + intel_de_rmw(display, BXT_PORT_PLL_EBB_0(phy, ch), PORT_PLL_P1_MASK | PORT_PLL_P2_MASK, hw_state->ebb0); /* Write M2 integer */ - intel_de_rmw(i915, BXT_PORT_PLL(phy, ch, 0), + intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 0), PORT_PLL_M2_INT_MASK, hw_state->pll0); /* Write N */ - intel_de_rmw(i915, BXT_PORT_PLL(phy, ch, 1), + intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 1), PORT_PLL_N_MASK, hw_state->pll1); /* Write M2 fraction */ - intel_de_rmw(i915, BXT_PORT_PLL(phy, ch, 2), + intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 2), PORT_PLL_M2_FRAC_MASK, hw_state->pll2); /* Write M2 fraction enable */ - intel_de_rmw(i915, BXT_PORT_PLL(phy, ch, 3), + intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 3), PORT_PLL_M2_FRAC_ENABLE, hw_state->pll3); /* Write coeff */ - temp = intel_de_read(i915, BXT_PORT_PLL(phy, ch, 6)); + temp = intel_de_read(display, BXT_PORT_PLL(phy, ch, 6)); temp &= ~PORT_PLL_PROP_COEFF_MASK; temp &= ~PORT_PLL_INT_COEFF_MASK; temp &= ~PORT_PLL_GAIN_CTL_MASK; temp |= hw_state->pll6; - intel_de_write(i915, BXT_PORT_PLL(phy, ch, 6), temp); + intel_de_write(display, BXT_PORT_PLL(phy, ch, 6), temp); /* Write calibration val */ - intel_de_rmw(i915, BXT_PORT_PLL(phy, ch, 8), + intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 8), PORT_PLL_TARGET_CNT_MASK, hw_state->pll8); - intel_de_rmw(i915, BXT_PORT_PLL(phy, ch, 9), + intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 9), PORT_PLL_LOCK_THRESHOLD_MASK, hw_state->pll9); - temp = intel_de_read(i915, BXT_PORT_PLL(phy, ch, 10)); + temp = intel_de_read(display, BXT_PORT_PLL(phy, ch, 10)); temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H; temp &= ~PORT_PLL_DCO_AMP_MASK; temp |= hw_state->pll10; - intel_de_write(i915, BXT_PORT_PLL(phy, ch, 10), temp); + intel_de_write(display, BXT_PORT_PLL(phy, ch, 10), temp); /* Recalibrate with new settings */ - temp = intel_de_read(i915, BXT_PORT_PLL_EBB_4(phy, ch)); + temp = intel_de_read(display, BXT_PORT_PLL_EBB_4(phy, ch)); temp |= PORT_PLL_RECALIBRATE; - intel_de_write(i915, BXT_PORT_PLL_EBB_4(phy, ch), temp); + intel_de_write(display, BXT_PORT_PLL_EBB_4(phy, ch), temp); temp &= ~PORT_PLL_10BIT_CLK_ENABLE; temp |= hw_state->ebb4; - intel_de_write(i915, BXT_PORT_PLL_EBB_4(phy, ch), temp); + intel_de_write(display, BXT_PORT_PLL_EBB_4(phy, ch), temp); /* Enable PLL */ - intel_de_rmw(i915, BXT_PORT_PLL_ENABLE(port), 0, PORT_PLL_ENABLE); - intel_de_posting_read(i915, BXT_PORT_PLL_ENABLE(port)); + intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), 0, PORT_PLL_ENABLE); + intel_de_posting_read(display, BXT_PORT_PLL_ENABLE(port)); - if (wait_for_us((intel_de_read(i915, BXT_PORT_PLL_ENABLE(port)) & PORT_PLL_LOCK), + if (wait_for_us((intel_de_read(display, BXT_PORT_PLL_ENABLE(port)) & PORT_PLL_LOCK), 200)) - drm_err(&i915->drm, "PLL %d not locked\n", port); + drm_err(display->drm, "PLL %d not locked\n", port); - if (IS_GEMINILAKE(i915)) { - temp = intel_de_read(i915, BXT_PORT_TX_DW5_LN(phy, ch, 0)); + if (display->platform.geminilake) { + temp = intel_de_read(display, BXT_PORT_TX_DW5_LN(phy, ch, 0)); temp |= DCC_DELAY_RANGE_2; - intel_de_write(i915, BXT_PORT_TX_DW5_GRP(phy, ch), temp); + intel_de_write(display, BXT_PORT_TX_DW5_GRP(phy, ch), temp); } /* * While we write to the group register to program all lanes at once we * can read only lane registers and we pick lanes 0/1 for that. */ - temp = intel_de_read(i915, BXT_PORT_PCS_DW12_LN01(phy, ch)); + temp = intel_de_read(display, BXT_PORT_PCS_DW12_LN01(phy, ch)); temp &= ~LANE_STAGGER_MASK; temp &= ~LANESTAGGER_STRAP_OVRD; temp |= hw_state->pcsdw12; - intel_de_write(i915, BXT_PORT_PCS_DW12_GRP(phy, ch), temp); + intel_de_write(display, BXT_PORT_PCS_DW12_GRP(phy, ch), temp); } -static void bxt_ddi_pll_disable(struct drm_i915_private *i915, +static void bxt_ddi_pll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */ - intel_de_rmw(i915, BXT_PORT_PLL_ENABLE(port), PORT_PLL_ENABLE, 0); - intel_de_posting_read(i915, BXT_PORT_PLL_ENABLE(port)); + intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), PORT_PLL_ENABLE, 0); + intel_de_posting_read(display, BXT_PORT_PLL_ENABLE(port)); - if (IS_GEMINILAKE(i915)) { - intel_de_rmw(i915, BXT_PORT_PLL_ENABLE(port), + if (display->platform.geminilake) { + intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), PORT_PLL_POWER_ENABLE, 0); - if (wait_for_us(!(intel_de_read(i915, BXT_PORT_PLL_ENABLE(port)) & + if (wait_for_us(!(intel_de_read(display, BXT_PORT_PLL_ENABLE(port)) & PORT_PLL_POWER_STATE), 200)) - drm_err(&i915->drm, + drm_err(display->drm, "Power state not reset for PLL:%d\n", port); } } -static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *i915, +static bool bxt_ddi_pll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - struct intel_display *display = &i915->display; struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt; enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */ intel_wakeref_t wakeref; @@ -2191,40 +2184,40 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *i915, ret = false; - val = intel_de_read(i915, BXT_PORT_PLL_ENABLE(port)); + val = intel_de_read(display, BXT_PORT_PLL_ENABLE(port)); if (!(val & PORT_PLL_ENABLE)) goto out; - hw_state->ebb0 = intel_de_read(i915, BXT_PORT_PLL_EBB_0(phy, ch)); + hw_state->ebb0 = intel_de_read(display, BXT_PORT_PLL_EBB_0(phy, ch)); hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK; - hw_state->ebb4 = intel_de_read(i915, BXT_PORT_PLL_EBB_4(phy, ch)); + hw_state->ebb4 = intel_de_read(display, BXT_PORT_PLL_EBB_4(phy, ch)); hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE; - hw_state->pll0 = intel_de_read(i915, BXT_PORT_PLL(phy, ch, 0)); + hw_state->pll0 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 0)); hw_state->pll0 &= PORT_PLL_M2_INT_MASK; - hw_state->pll1 = intel_de_read(i915, BXT_PORT_PLL(phy, ch, 1)); + hw_state->pll1 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 1)); hw_state->pll1 &= PORT_PLL_N_MASK; - hw_state->pll2 = intel_de_read(i915, BXT_PORT_PLL(phy, ch, 2)); + hw_state->pll2 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 2)); hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK; - hw_state->pll3 = intel_de_read(i915, BXT_PORT_PLL(phy, ch, 3)); + hw_state->pll3 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 3)); hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE; - hw_state->pll6 = intel_de_read(i915, BXT_PORT_PLL(phy, ch, 6)); + hw_state->pll6 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 6)); hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK | PORT_PLL_INT_COEFF_MASK | PORT_PLL_GAIN_CTL_MASK; - hw_state->pll8 = intel_de_read(i915, BXT_PORT_PLL(phy, ch, 8)); + hw_state->pll8 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 8)); hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK; - hw_state->pll9 = intel_de_read(i915, BXT_PORT_PLL(phy, ch, 9)); + hw_state->pll9 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 9)); hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK; - hw_state->pll10 = intel_de_read(i915, BXT_PORT_PLL(phy, ch, 10)); + hw_state->pll10 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 10)); hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H | PORT_PLL_DCO_AMP_MASK; @@ -2233,13 +2226,13 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *i915, * can read only lane registers. We configure all lanes the same way, so * here just read out lanes 0/1 and output a note if lanes 2/3 differ. */ - hw_state->pcsdw12 = intel_de_read(i915, + hw_state->pcsdw12 = intel_de_read(display, BXT_PORT_PCS_DW12_LN01(phy, ch)); - if (intel_de_read(i915, BXT_PORT_PCS_DW12_LN23(phy, ch)) != hw_state->pcsdw12) - drm_dbg(&i915->drm, + if (intel_de_read(display, BXT_PORT_PCS_DW12_LN23(phy, ch)) != hw_state->pcsdw12) + drm_dbg(display->drm, "lane stagger config different for lane 01 (%08x) and 23 (%08x)\n", hw_state->pcsdw12, - intel_de_read(i915, + intel_de_read(display, BXT_PORT_PCS_DW12_LN23(phy, ch))); hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD; @@ -2370,7 +2363,7 @@ static int bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state, return 0; } -static int bxt_ddi_pll_get_freq(struct drm_i915_private *i915, +static int bxt_ddi_pll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { @@ -2386,7 +2379,7 @@ static int bxt_ddi_pll_get_freq(struct drm_i915_private *i915, clock.p1 = REG_FIELD_GET(PORT_PLL_P1_MASK, hw_state->ebb0); clock.p2 = REG_FIELD_GET(PORT_PLL_P2_MASK, hw_state->ebb0); - return chv_calc_dpll_params(i915->display.dpll.ref_clks.nssc, &clock); + return chv_calc_dpll_params(display->dpll.ref_clks.nssc, &clock); } static int @@ -2402,7 +2395,7 @@ bxt_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state) static int bxt_ddi_hdmi_set_dpll_hw_state(struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); struct dpll clk_div = {}; int ret; @@ -2412,7 +2405,7 @@ bxt_ddi_hdmi_set_dpll_hw_state(struct intel_crtc_state *crtc_state) if (ret) return ret; - crtc_state->port_clock = bxt_ddi_pll_get_freq(i915, NULL, + crtc_state->port_clock = bxt_ddi_pll_get_freq(display, NULL, &crtc_state->dpll_hw_state); return 0; @@ -2437,17 +2430,17 @@ static int bxt_get_dpll(struct intel_atomic_state *state, struct intel_crtc *crtc, struct intel_encoder *encoder) { + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_shared_dpll *pll; enum intel_dpll_id id; /* 1:1 mapping between ports and PLLs */ id = (enum intel_dpll_id) encoder->port; - pll = intel_get_shared_dpll_by_id(i915, id); + pll = intel_get_shared_dpll_by_id(display, id); - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] using pre-allocated %s\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] using pre-allocated %s\n", crtc->base.base.id, crtc->base.name, pll->info->name); intel_reference_shared_dpll(state, crtc, @@ -2613,12 +2606,14 @@ static void icl_wrpll_params_populate(struct skl_wrpll_params *params, * Program half of the nominal DCO divider fraction value. */ static bool -ehl_combo_pll_div_frac_wa_needed(struct drm_i915_private *i915) +ehl_combo_pll_div_frac_wa_needed(struct intel_display *display) { - return ((IS_ELKHARTLAKE(i915) && - IS_DISPLAY_STEP(i915, STEP_B0, STEP_FOREVER)) || - IS_TIGERLAKE(i915) || IS_ALDERLAKE_S(i915) || IS_ALDERLAKE_P(i915)) && - i915->display.dpll.ref_clks.nssc == 38400; + return ((display->platform.elkhartlake && + IS_DISPLAY_STEP(display, STEP_B0, STEP_FOREVER)) || + display->platform.tigerlake || + display->platform.alderlake_s || + display->platform.alderlake_p) && + display->dpll.ref_clks.nssc == 38400; } struct icl_combo_pll_params { @@ -2765,7 +2760,7 @@ static int icl_calc_tbt_pll(struct intel_crtc_state *crtc_state, return 0; } -static int icl_ddi_tbt_pll_get_freq(struct drm_i915_private *i915, +static int icl_ddi_tbt_pll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { @@ -2773,14 +2768,14 @@ static int icl_ddi_tbt_pll_get_freq(struct drm_i915_private *i915, * The PLL outputs multiple frequencies at the same time, selection is * made at DDI clock mux level. */ - drm_WARN_ON(&i915->drm, 1); + drm_WARN_ON(display->drm, 1); return 0; } -static int icl_wrpll_ref_clock(struct drm_i915_private *i915) +static int icl_wrpll_ref_clock(struct intel_display *display) { - int ref_clock = i915->display.dpll.ref_clks.nssc; + int ref_clock = display->dpll.ref_clks.nssc; /* * For ICL+, the spec states: if reference frequency is 38.4, @@ -2796,8 +2791,8 @@ static int icl_calc_wrpll(struct intel_crtc_state *crtc_state, struct skl_wrpll_params *wrpll_params) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); - int ref_clock = icl_wrpll_ref_clock(i915); + struct intel_display *display = to_intel_display(crtc_state); + int ref_clock = icl_wrpll_ref_clock(display); u32 afe_clock = crtc_state->port_clock * 5; u32 dco_min = 7998000; u32 dco_max = 10000000; @@ -2836,12 +2831,12 @@ icl_calc_wrpll(struct intel_crtc_state *crtc_state, return 0; } -static int icl_ddi_combo_pll_get_freq(struct drm_i915_private *i915, +static int icl_ddi_combo_pll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; - int ref_clock = icl_wrpll_ref_clock(i915); + int ref_clock = icl_wrpll_ref_clock(display); u32 dco_fraction; u32 p0, p1, p2, dco_freq; @@ -2887,25 +2882,25 @@ static int icl_ddi_combo_pll_get_freq(struct drm_i915_private *i915, dco_fraction = (hw_state->cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >> DPLL_CFGCR0_DCO_FRACTION_SHIFT; - if (ehl_combo_pll_div_frac_wa_needed(i915)) + if (ehl_combo_pll_div_frac_wa_needed(display)) dco_fraction *= 2; dco_freq += (dco_fraction * ref_clock) / 0x8000; - if (drm_WARN_ON(&i915->drm, p0 == 0 || p1 == 0 || p2 == 0)) + if (drm_WARN_ON(display->drm, p0 == 0 || p1 == 0 || p2 == 0)) return 0; return dco_freq / (p0 * p1 * p2 * 5); } -static void icl_calc_dpll_state(struct drm_i915_private *i915, +static void icl_calc_dpll_state(struct intel_display *display, const struct skl_wrpll_params *pll_params, struct intel_dpll_hw_state *dpll_hw_state) { struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; u32 dco_fraction = pll_params->dco_fraction; - if (ehl_combo_pll_div_frac_wa_needed(i915)) + if (ehl_combo_pll_div_frac_wa_needed(display)) dco_fraction = DIV_ROUND_CLOSEST(dco_fraction, 2); hw_state->cfgcr0 = DPLL_CFGCR0_DCO_FRACTION(dco_fraction) | @@ -2916,13 +2911,13 @@ static void icl_calc_dpll_state(struct drm_i915_private *i915, DPLL_CFGCR1_KDIV(pll_params->kdiv) | DPLL_CFGCR1_PDIV(pll_params->pdiv); - if (DISPLAY_VER(i915) >= 12) + if (DISPLAY_VER(display) >= 12) hw_state->cfgcr1 |= TGL_DPLL_CFGCR1_CFSELOVRD_NORMAL_XTAL; else hw_state->cfgcr1 |= DPLL_CFGCR1_CENTRAL_FREQ_8400; - if (i915->display.vbt.override_afc_startup) - hw_state->div0 = TGL_DPLL0_DIV0_AFC_STARTUP(i915->display.vbt.override_afc_startup_val); + if (display->vbt.override_afc_startup) + hw_state->div0 = TGL_DPLL0_DIV0_AFC_STARTUP(display->vbt.override_afc_startup_val); } static int icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc, @@ -3209,7 +3204,7 @@ static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, return 0; } -static int icl_ddi_mg_pll_get_freq(struct drm_i915_private *i915, +static int icl_ddi_mg_pll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { @@ -3217,9 +3212,9 @@ static int icl_ddi_mg_pll_get_freq(struct drm_i915_private *i915, u32 m1, m2_int, m2_frac, div1, div2, ref_clock; u64 tmp; - ref_clock = i915->display.dpll.ref_clks.nssc; + ref_clock = display->dpll.ref_clks.nssc; - if (DISPLAY_VER(i915) >= 12) { + if (DISPLAY_VER(display) >= 12) { m1 = hw_state->mg_pll_div0 & DKL_PLL_DIV0_FBPREDIV_MASK; m1 = m1 >> DKL_PLL_DIV0_FBPREDIV_SHIFT; m2_int = hw_state->mg_pll_div0 & DKL_PLL_DIV0_FBDIV_INT_MASK; @@ -3324,7 +3319,7 @@ static void icl_update_active_dpll(struct intel_atomic_state *state, static int icl_compute_combo_phy_dpll(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct icl_port_dpll *port_dpll = @@ -3341,12 +3336,12 @@ static int icl_compute_combo_phy_dpll(struct intel_atomic_state *state, if (ret) return ret; - icl_calc_dpll_state(i915, &pll_params, &port_dpll->hw_state); + icl_calc_dpll_state(display, &pll_params, &port_dpll->hw_state); /* this is mainly for the fastset check */ icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_DEFAULT); - crtc_state->port_clock = icl_ddi_combo_pll_get_freq(i915, NULL, + crtc_state->port_clock = icl_ddi_combo_pll_get_freq(display, NULL, &port_dpll->hw_state); return 0; @@ -3416,7 +3411,7 @@ static int icl_get_combo_phy_dpll(struct intel_atomic_state *state, static int icl_compute_tc_phy_dplls(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_crtc_state *old_crtc_state = @@ -3431,7 +3426,7 @@ static int icl_compute_tc_phy_dplls(struct intel_atomic_state *state, if (ret) return ret; - icl_calc_dpll_state(i915, &pll_params, &port_dpll->hw_state); + icl_calc_dpll_state(display, &pll_params, &port_dpll->hw_state); port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY]; ret = icl_calc_mg_pll_state(crtc_state, &port_dpll->hw_state); @@ -3445,7 +3440,7 @@ static int icl_compute_tc_phy_dplls(struct intel_atomic_state *state, else icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_MG_PHY); - crtc_state->port_clock = icl_ddi_mg_pll_get_freq(i915, NULL, + crtc_state->port_clock = icl_ddi_mg_pll_get_freq(display, NULL, &port_dpll->hw_state); return 0; @@ -3549,11 +3544,10 @@ static void icl_put_dplls(struct intel_atomic_state *state, } } -static bool mg_pll_get_hw_state(struct drm_i915_private *i915, +static bool mg_pll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - struct intel_display *display = &i915->display; struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; const enum intel_dpll_id id = pll->info->id; enum tc_port tc_port = icl_pll_id_to_tc_port(id); @@ -3561,46 +3555,46 @@ static bool mg_pll_get_hw_state(struct drm_i915_private *i915, bool ret = false; u32 val; - i915_reg_t enable_reg = intel_tc_pll_enable_reg(i915, pll); + i915_reg_t enable_reg = intel_tc_pll_enable_reg(display, pll); wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_DISPLAY_CORE); if (!wakeref) return false; - val = intel_de_read(i915, enable_reg); + val = intel_de_read(display, enable_reg); if (!(val & PLL_ENABLE)) goto out; - hw_state->mg_refclkin_ctl = intel_de_read(i915, + hw_state->mg_refclkin_ctl = intel_de_read(display, MG_REFCLKIN_CTL(tc_port)); hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK; hw_state->mg_clktop2_coreclkctl1 = - intel_de_read(i915, MG_CLKTOP2_CORECLKCTL1(tc_port)); + intel_de_read(display, MG_CLKTOP2_CORECLKCTL1(tc_port)); hw_state->mg_clktop2_coreclkctl1 &= MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK; hw_state->mg_clktop2_hsclkctl = - intel_de_read(i915, MG_CLKTOP2_HSCLKCTL(tc_port)); + intel_de_read(display, MG_CLKTOP2_HSCLKCTL(tc_port)); hw_state->mg_clktop2_hsclkctl &= MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK | MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK | MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK | MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK; - hw_state->mg_pll_div0 = intel_de_read(i915, MG_PLL_DIV0(tc_port)); - hw_state->mg_pll_div1 = intel_de_read(i915, MG_PLL_DIV1(tc_port)); - hw_state->mg_pll_lf = intel_de_read(i915, MG_PLL_LF(tc_port)); - hw_state->mg_pll_frac_lock = intel_de_read(i915, + hw_state->mg_pll_div0 = intel_de_read(display, MG_PLL_DIV0(tc_port)); + hw_state->mg_pll_div1 = intel_de_read(display, MG_PLL_DIV1(tc_port)); + hw_state->mg_pll_lf = intel_de_read(display, MG_PLL_LF(tc_port)); + hw_state->mg_pll_frac_lock = intel_de_read(display, MG_PLL_FRAC_LOCK(tc_port)); - hw_state->mg_pll_ssc = intel_de_read(i915, MG_PLL_SSC(tc_port)); + hw_state->mg_pll_ssc = intel_de_read(display, MG_PLL_SSC(tc_port)); - hw_state->mg_pll_bias = intel_de_read(i915, MG_PLL_BIAS(tc_port)); + hw_state->mg_pll_bias = intel_de_read(display, MG_PLL_BIAS(tc_port)); hw_state->mg_pll_tdc_coldst_bias = - intel_de_read(i915, MG_PLL_TDC_COLDST_BIAS(tc_port)); + intel_de_read(display, MG_PLL_TDC_COLDST_BIAS(tc_port)); - if (i915->display.dpll.ref_clks.nssc == 38400) { + if (display->dpll.ref_clks.nssc == 38400) { hw_state->mg_pll_tdc_coldst_bias_mask = MG_PLL_TDC_COLDST_COLDSTART; hw_state->mg_pll_bias_mask = 0; } else { @@ -3617,11 +3611,10 @@ static bool mg_pll_get_hw_state(struct drm_i915_private *i915, return ret; } -static bool dkl_pll_get_hw_state(struct drm_i915_private *i915, +static bool dkl_pll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - struct intel_display *display = &i915->display; struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; const enum intel_dpll_id id = pll->info->id; enum tc_port tc_port = icl_pll_id_to_tc_port(id); @@ -3634,7 +3627,7 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *i915, if (!wakeref) return false; - val = intel_de_read(i915, intel_tc_pll_enable_reg(i915, pll)); + val = intel_de_read(display, intel_tc_pll_enable_reg(display, pll)); if (!(val & PLL_ENABLE)) goto out; @@ -3642,12 +3635,12 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *i915, * All registers read here have the same HIP_INDEX_REG even though * they are on different building blocks */ - hw_state->mg_refclkin_ctl = intel_dkl_phy_read(i915, + hw_state->mg_refclkin_ctl = intel_dkl_phy_read(display, DKL_REFCLKIN_CTL(tc_port)); hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK; hw_state->mg_clktop2_hsclkctl = - intel_dkl_phy_read(i915, DKL_CLKTOP2_HSCLKCTL(tc_port)); + intel_dkl_phy_read(display, DKL_CLKTOP2_HSCLKCTL(tc_port)); hw_state->mg_clktop2_hsclkctl &= MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK | MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK | @@ -3655,32 +3648,32 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *i915, MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK; hw_state->mg_clktop2_coreclkctl1 = - intel_dkl_phy_read(i915, DKL_CLKTOP2_CORECLKCTL1(tc_port)); + intel_dkl_phy_read(display, DKL_CLKTOP2_CORECLKCTL1(tc_port)); hw_state->mg_clktop2_coreclkctl1 &= MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK; - hw_state->mg_pll_div0 = intel_dkl_phy_read(i915, DKL_PLL_DIV0(tc_port)); + hw_state->mg_pll_div0 = intel_dkl_phy_read(display, DKL_PLL_DIV0(tc_port)); val = DKL_PLL_DIV0_MASK; - if (i915->display.vbt.override_afc_startup) + if (display->vbt.override_afc_startup) val |= DKL_PLL_DIV0_AFC_STARTUP_MASK; hw_state->mg_pll_div0 &= val; - hw_state->mg_pll_div1 = intel_dkl_phy_read(i915, DKL_PLL_DIV1(tc_port)); + hw_state->mg_pll_div1 = intel_dkl_phy_read(display, DKL_PLL_DIV1(tc_port)); hw_state->mg_pll_div1 &= (DKL_PLL_DIV1_IREF_TRIM_MASK | DKL_PLL_DIV1_TDC_TARGET_CNT_MASK); - hw_state->mg_pll_ssc = intel_dkl_phy_read(i915, DKL_PLL_SSC(tc_port)); + hw_state->mg_pll_ssc = intel_dkl_phy_read(display, DKL_PLL_SSC(tc_port)); hw_state->mg_pll_ssc &= (DKL_PLL_SSC_IREF_NDIV_RATIO_MASK | DKL_PLL_SSC_STEP_LEN_MASK | DKL_PLL_SSC_STEP_NUM_MASK | DKL_PLL_SSC_EN); - hw_state->mg_pll_bias = intel_dkl_phy_read(i915, DKL_PLL_BIAS(tc_port)); + hw_state->mg_pll_bias = intel_dkl_phy_read(display, DKL_PLL_BIAS(tc_port)); hw_state->mg_pll_bias &= (DKL_PLL_BIAS_FRAC_EN_H | DKL_PLL_BIAS_FBDIV_FRAC_MASK); hw_state->mg_pll_tdc_coldst_bias = - intel_dkl_phy_read(i915, DKL_PLL_TDC_COLDST_BIAS(tc_port)); + intel_dkl_phy_read(display, DKL_PLL_TDC_COLDST_BIAS(tc_port)); hw_state->mg_pll_tdc_coldst_bias &= (DKL_PLL_TDC_SSC_STEP_SIZE_MASK | DKL_PLL_TDC_FEED_FWD_GAIN_MASK); @@ -3690,12 +3683,11 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *i915, return ret; } -static bool icl_pll_get_hw_state(struct drm_i915_private *i915, +static bool icl_pll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state, i915_reg_t enable_reg) { - struct intel_display *display = &i915->display; struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; const enum intel_dpll_id id = pll->info->id; intel_wakeref_t wakeref; @@ -3707,41 +3699,41 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *i915, if (!wakeref) return false; - val = intel_de_read(i915, enable_reg); + val = intel_de_read(display, enable_reg); if (!(val & PLL_ENABLE)) goto out; - if (IS_ALDERLAKE_S(i915)) { - hw_state->cfgcr0 = intel_de_read(i915, ADLS_DPLL_CFGCR0(id)); - hw_state->cfgcr1 = intel_de_read(i915, ADLS_DPLL_CFGCR1(id)); - } else if (IS_DG1(i915)) { - hw_state->cfgcr0 = intel_de_read(i915, DG1_DPLL_CFGCR0(id)); - hw_state->cfgcr1 = intel_de_read(i915, DG1_DPLL_CFGCR1(id)); - } else if (IS_ROCKETLAKE(i915)) { - hw_state->cfgcr0 = intel_de_read(i915, + if (display->platform.alderlake_s) { + hw_state->cfgcr0 = intel_de_read(display, ADLS_DPLL_CFGCR0(id)); + hw_state->cfgcr1 = intel_de_read(display, ADLS_DPLL_CFGCR1(id)); + } else if (display->platform.dg1) { + hw_state->cfgcr0 = intel_de_read(display, DG1_DPLL_CFGCR0(id)); + hw_state->cfgcr1 = intel_de_read(display, DG1_DPLL_CFGCR1(id)); + } else if (display->platform.rocketlake) { + hw_state->cfgcr0 = intel_de_read(display, RKL_DPLL_CFGCR0(id)); - hw_state->cfgcr1 = intel_de_read(i915, + hw_state->cfgcr1 = intel_de_read(display, RKL_DPLL_CFGCR1(id)); - } else if (DISPLAY_VER(i915) >= 12) { - hw_state->cfgcr0 = intel_de_read(i915, + } else if (DISPLAY_VER(display) >= 12) { + hw_state->cfgcr0 = intel_de_read(display, TGL_DPLL_CFGCR0(id)); - hw_state->cfgcr1 = intel_de_read(i915, + hw_state->cfgcr1 = intel_de_read(display, TGL_DPLL_CFGCR1(id)); - if (i915->display.vbt.override_afc_startup) { - hw_state->div0 = intel_de_read(i915, TGL_DPLL0_DIV0(id)); + if (display->vbt.override_afc_startup) { + hw_state->div0 = intel_de_read(display, TGL_DPLL0_DIV0(id)); hw_state->div0 &= TGL_DPLL0_DIV0_AFC_STARTUP_MASK; } } else { - if ((IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) && + if ((display->platform.jasperlake || display->platform.elkhartlake) && id == DPLL_ID_EHL_DPLL4) { - hw_state->cfgcr0 = intel_de_read(i915, + hw_state->cfgcr0 = intel_de_read(display, ICL_DPLL_CFGCR0(4)); - hw_state->cfgcr1 = intel_de_read(i915, + hw_state->cfgcr1 = intel_de_read(display, ICL_DPLL_CFGCR1(4)); } else { - hw_state->cfgcr0 = intel_de_read(i915, + hw_state->cfgcr0 = intel_de_read(display, ICL_DPLL_CFGCR0(id)); - hw_state->cfgcr1 = intel_de_read(i915, + hw_state->cfgcr1 = intel_de_read(display, ICL_DPLL_CFGCR1(id)); } } @@ -3752,44 +3744,44 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *i915, return ret; } -static bool combo_pll_get_hw_state(struct drm_i915_private *i915, +static bool combo_pll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - i915_reg_t enable_reg = intel_combo_pll_enable_reg(i915, pll); + i915_reg_t enable_reg = intel_combo_pll_enable_reg(display, pll); - return icl_pll_get_hw_state(i915, pll, dpll_hw_state, enable_reg); + return icl_pll_get_hw_state(display, pll, dpll_hw_state, enable_reg); } -static bool tbt_pll_get_hw_state(struct drm_i915_private *i915, +static bool tbt_pll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - return icl_pll_get_hw_state(i915, pll, dpll_hw_state, TBT_PLL_ENABLE); + return icl_pll_get_hw_state(display, pll, dpll_hw_state, TBT_PLL_ENABLE); } -static void icl_dpll_write(struct drm_i915_private *i915, +static void icl_dpll_write(struct intel_display *display, struct intel_shared_dpll *pll, const struct icl_dpll_hw_state *hw_state) { const enum intel_dpll_id id = pll->info->id; i915_reg_t cfgcr0_reg, cfgcr1_reg, div0_reg = INVALID_MMIO_REG; - if (IS_ALDERLAKE_S(i915)) { + if (display->platform.alderlake_s) { cfgcr0_reg = ADLS_DPLL_CFGCR0(id); cfgcr1_reg = ADLS_DPLL_CFGCR1(id); - } else if (IS_DG1(i915)) { + } else if (display->platform.dg1) { cfgcr0_reg = DG1_DPLL_CFGCR0(id); cfgcr1_reg = DG1_DPLL_CFGCR1(id); - } else if (IS_ROCKETLAKE(i915)) { + } else if (display->platform.rocketlake) { cfgcr0_reg = RKL_DPLL_CFGCR0(id); cfgcr1_reg = RKL_DPLL_CFGCR1(id); - } else if (DISPLAY_VER(i915) >= 12) { + } else if (DISPLAY_VER(display) >= 12) { cfgcr0_reg = TGL_DPLL_CFGCR0(id); cfgcr1_reg = TGL_DPLL_CFGCR1(id); div0_reg = TGL_DPLL0_DIV0(id); } else { - if ((IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) && + if ((display->platform.jasperlake || display->platform.elkhartlake) && id == DPLL_ID_EHL_DPLL4) { cfgcr0_reg = ICL_DPLL_CFGCR0(4); cfgcr1_reg = ICL_DPLL_CFGCR1(4); @@ -3799,18 +3791,18 @@ static void icl_dpll_write(struct drm_i915_private *i915, } } - intel_de_write(i915, cfgcr0_reg, hw_state->cfgcr0); - intel_de_write(i915, cfgcr1_reg, hw_state->cfgcr1); - drm_WARN_ON_ONCE(&i915->drm, i915->display.vbt.override_afc_startup && + intel_de_write(display, cfgcr0_reg, hw_state->cfgcr0); + intel_de_write(display, cfgcr1_reg, hw_state->cfgcr1); + drm_WARN_ON_ONCE(display->drm, display->vbt.override_afc_startup && !i915_mmio_reg_valid(div0_reg)); - if (i915->display.vbt.override_afc_startup && + if (display->vbt.override_afc_startup && i915_mmio_reg_valid(div0_reg)) - intel_de_rmw(i915, div0_reg, + intel_de_rmw(display, div0_reg, TGL_DPLL0_DIV0_AFC_STARTUP_MASK, hw_state->div0); - intel_de_posting_read(i915, cfgcr1_reg); + intel_de_posting_read(display, cfgcr1_reg); } -static void icl_mg_pll_write(struct drm_i915_private *i915, +static void icl_mg_pll_write(struct intel_display *display, struct intel_shared_dpll *pll, const struct icl_dpll_hw_state *hw_state) { @@ -3822,38 +3814,38 @@ static void icl_mg_pll_write(struct drm_i915_private *i915, * during the calc/readout phase if the mask depends on some other HW * state like refclk, see icl_calc_mg_pll_state(). */ - intel_de_rmw(i915, MG_REFCLKIN_CTL(tc_port), + intel_de_rmw(display, MG_REFCLKIN_CTL(tc_port), MG_REFCLKIN_CTL_OD_2_MUX_MASK, hw_state->mg_refclkin_ctl); - intel_de_rmw(i915, MG_CLKTOP2_CORECLKCTL1(tc_port), + intel_de_rmw(display, MG_CLKTOP2_CORECLKCTL1(tc_port), MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK, hw_state->mg_clktop2_coreclkctl1); - intel_de_rmw(i915, MG_CLKTOP2_HSCLKCTL(tc_port), + intel_de_rmw(display, MG_CLKTOP2_HSCLKCTL(tc_port), MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK | MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK | MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK | MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK, hw_state->mg_clktop2_hsclkctl); - intel_de_write(i915, MG_PLL_DIV0(tc_port), hw_state->mg_pll_div0); - intel_de_write(i915, MG_PLL_DIV1(tc_port), hw_state->mg_pll_div1); - intel_de_write(i915, MG_PLL_LF(tc_port), hw_state->mg_pll_lf); - intel_de_write(i915, MG_PLL_FRAC_LOCK(tc_port), + intel_de_write(display, MG_PLL_DIV0(tc_port), hw_state->mg_pll_div0); + intel_de_write(display, MG_PLL_DIV1(tc_port), hw_state->mg_pll_div1); + intel_de_write(display, MG_PLL_LF(tc_port), hw_state->mg_pll_lf); + intel_de_write(display, MG_PLL_FRAC_LOCK(tc_port), hw_state->mg_pll_frac_lock); - intel_de_write(i915, MG_PLL_SSC(tc_port), hw_state->mg_pll_ssc); + intel_de_write(display, MG_PLL_SSC(tc_port), hw_state->mg_pll_ssc); - intel_de_rmw(i915, MG_PLL_BIAS(tc_port), + intel_de_rmw(display, MG_PLL_BIAS(tc_port), hw_state->mg_pll_bias_mask, hw_state->mg_pll_bias); - intel_de_rmw(i915, MG_PLL_TDC_COLDST_BIAS(tc_port), + intel_de_rmw(display, MG_PLL_TDC_COLDST_BIAS(tc_port), hw_state->mg_pll_tdc_coldst_bias_mask, hw_state->mg_pll_tdc_coldst_bias); - intel_de_posting_read(i915, MG_PLL_TDC_COLDST_BIAS(tc_port)); + intel_de_posting_read(display, MG_PLL_TDC_COLDST_BIAS(tc_port)); } -static void dkl_pll_write(struct drm_i915_private *i915, +static void dkl_pll_write(struct intel_display *display, struct intel_shared_dpll *pll, const struct icl_dpll_hw_state *hw_state) { @@ -3865,90 +3857,90 @@ static void dkl_pll_write(struct drm_i915_private *i915, * though on different building block */ /* All the registers are RMW */ - val = intel_dkl_phy_read(i915, DKL_REFCLKIN_CTL(tc_port)); + val = intel_dkl_phy_read(display, DKL_REFCLKIN_CTL(tc_port)); val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK; val |= hw_state->mg_refclkin_ctl; - intel_dkl_phy_write(i915, DKL_REFCLKIN_CTL(tc_port), val); + intel_dkl_phy_write(display, DKL_REFCLKIN_CTL(tc_port), val); - val = intel_dkl_phy_read(i915, DKL_CLKTOP2_CORECLKCTL1(tc_port)); + val = intel_dkl_phy_read(display, DKL_CLKTOP2_CORECLKCTL1(tc_port)); val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK; val |= hw_state->mg_clktop2_coreclkctl1; - intel_dkl_phy_write(i915, DKL_CLKTOP2_CORECLKCTL1(tc_port), val); + intel_dkl_phy_write(display, DKL_CLKTOP2_CORECLKCTL1(tc_port), val); - val = intel_dkl_phy_read(i915, DKL_CLKTOP2_HSCLKCTL(tc_port)); + val = intel_dkl_phy_read(display, DKL_CLKTOP2_HSCLKCTL(tc_port)); val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK | MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK | MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK | MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK); val |= hw_state->mg_clktop2_hsclkctl; - intel_dkl_phy_write(i915, DKL_CLKTOP2_HSCLKCTL(tc_port), val); + intel_dkl_phy_write(display, DKL_CLKTOP2_HSCLKCTL(tc_port), val); val = DKL_PLL_DIV0_MASK; - if (i915->display.vbt.override_afc_startup) + if (display->vbt.override_afc_startup) val |= DKL_PLL_DIV0_AFC_STARTUP_MASK; - intel_dkl_phy_rmw(i915, DKL_PLL_DIV0(tc_port), val, + intel_dkl_phy_rmw(display, DKL_PLL_DIV0(tc_port), val, hw_state->mg_pll_div0); - val = intel_dkl_phy_read(i915, DKL_PLL_DIV1(tc_port)); + val = intel_dkl_phy_read(display, DKL_PLL_DIV1(tc_port)); val &= ~(DKL_PLL_DIV1_IREF_TRIM_MASK | DKL_PLL_DIV1_TDC_TARGET_CNT_MASK); val |= hw_state->mg_pll_div1; - intel_dkl_phy_write(i915, DKL_PLL_DIV1(tc_port), val); + intel_dkl_phy_write(display, DKL_PLL_DIV1(tc_port), val); - val = intel_dkl_phy_read(i915, DKL_PLL_SSC(tc_port)); + val = intel_dkl_phy_read(display, DKL_PLL_SSC(tc_port)); val &= ~(DKL_PLL_SSC_IREF_NDIV_RATIO_MASK | DKL_PLL_SSC_STEP_LEN_MASK | DKL_PLL_SSC_STEP_NUM_MASK | DKL_PLL_SSC_EN); val |= hw_state->mg_pll_ssc; - intel_dkl_phy_write(i915, DKL_PLL_SSC(tc_port), val); + intel_dkl_phy_write(display, DKL_PLL_SSC(tc_port), val); - val = intel_dkl_phy_read(i915, DKL_PLL_BIAS(tc_port)); + val = intel_dkl_phy_read(display, DKL_PLL_BIAS(tc_port)); val &= ~(DKL_PLL_BIAS_FRAC_EN_H | DKL_PLL_BIAS_FBDIV_FRAC_MASK); val |= hw_state->mg_pll_bias; - intel_dkl_phy_write(i915, DKL_PLL_BIAS(tc_port), val); + intel_dkl_phy_write(display, DKL_PLL_BIAS(tc_port), val); - val = intel_dkl_phy_read(i915, DKL_PLL_TDC_COLDST_BIAS(tc_port)); + val = intel_dkl_phy_read(display, DKL_PLL_TDC_COLDST_BIAS(tc_port)); val &= ~(DKL_PLL_TDC_SSC_STEP_SIZE_MASK | DKL_PLL_TDC_FEED_FWD_GAIN_MASK); val |= hw_state->mg_pll_tdc_coldst_bias; - intel_dkl_phy_write(i915, DKL_PLL_TDC_COLDST_BIAS(tc_port), val); + intel_dkl_phy_write(display, DKL_PLL_TDC_COLDST_BIAS(tc_port), val); - intel_dkl_phy_posting_read(i915, DKL_PLL_TDC_COLDST_BIAS(tc_port)); + intel_dkl_phy_posting_read(display, DKL_PLL_TDC_COLDST_BIAS(tc_port)); } -static void icl_pll_power_enable(struct drm_i915_private *i915, +static void icl_pll_power_enable(struct intel_display *display, struct intel_shared_dpll *pll, i915_reg_t enable_reg) { - intel_de_rmw(i915, enable_reg, 0, PLL_POWER_ENABLE); + intel_de_rmw(display, enable_reg, 0, PLL_POWER_ENABLE); /* * The spec says we need to "wait" but it also says it should be * immediate. */ - if (intel_de_wait_for_set(i915, enable_reg, PLL_POWER_STATE, 1)) - drm_err(&i915->drm, "PLL %d Power not enabled\n", + if (intel_de_wait_for_set(display, enable_reg, PLL_POWER_STATE, 1)) + drm_err(display->drm, "PLL %d Power not enabled\n", pll->info->id); } -static void icl_pll_enable(struct drm_i915_private *i915, +static void icl_pll_enable(struct intel_display *display, struct intel_shared_dpll *pll, i915_reg_t enable_reg) { - intel_de_rmw(i915, enable_reg, 0, PLL_ENABLE); + intel_de_rmw(display, enable_reg, 0, PLL_ENABLE); /* Timeout is actually 600us. */ - if (intel_de_wait_for_set(i915, enable_reg, PLL_LOCK, 1)) - drm_err(&i915->drm, "PLL %d not locked\n", pll->info->id); + if (intel_de_wait_for_set(display, enable_reg, PLL_LOCK, 1)) + drm_err(display->drm, "PLL %d not locked\n", pll->info->id); } -static void adlp_cmtg_clock_gating_wa(struct drm_i915_private *i915, struct intel_shared_dpll *pll) +static void adlp_cmtg_clock_gating_wa(struct intel_display *display, struct intel_shared_dpll *pll) { u32 val; - if (!(IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0)) || + if (!(display->platform.alderlake_p && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) || pll->info->id != DPLL_ID_ICL_DPLL0) return; /* @@ -3962,22 +3954,22 @@ static void adlp_cmtg_clock_gating_wa(struct drm_i915_private *i915, struct inte * Instead of the usual place for workarounds we apply this one here, * since TRANS_CMTG_CHICKEN is only accessible while DPLL0 is enabled. */ - val = intel_de_read(i915, TRANS_CMTG_CHICKEN); - val = intel_de_rmw(i915, TRANS_CMTG_CHICKEN, ~0, DISABLE_DPT_CLK_GATING); - if (drm_WARN_ON(&i915->drm, val & ~DISABLE_DPT_CLK_GATING)) - drm_dbg_kms(&i915->drm, "Unexpected flags in TRANS_CMTG_CHICKEN: %08x\n", val); + val = intel_de_read(display, TRANS_CMTG_CHICKEN); + val = intel_de_rmw(display, TRANS_CMTG_CHICKEN, ~0, DISABLE_DPT_CLK_GATING); + if (drm_WARN_ON(display->drm, val & ~DISABLE_DPT_CLK_GATING)) + drm_dbg_kms(display->drm, "Unexpected flags in TRANS_CMTG_CHICKEN: %08x\n", val); } -static void combo_pll_enable(struct drm_i915_private *i915, +static void combo_pll_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; - i915_reg_t enable_reg = intel_combo_pll_enable_reg(i915, pll); + i915_reg_t enable_reg = intel_combo_pll_enable_reg(display, pll); - icl_pll_power_enable(i915, pll, enable_reg); + icl_pll_power_enable(display, pll, enable_reg); - icl_dpll_write(i915, pll, hw_state); + icl_dpll_write(display, pll, hw_state); /* * DVFS pre sequence would be here, but in our driver the cdclk code @@ -3985,22 +3977,22 @@ static void combo_pll_enable(struct drm_i915_private *i915, * nothing here. */ - icl_pll_enable(i915, pll, enable_reg); + icl_pll_enable(display, pll, enable_reg); - adlp_cmtg_clock_gating_wa(i915, pll); + adlp_cmtg_clock_gating_wa(display, pll); /* DVFS post sequence would be here. See the comment above. */ } -static void tbt_pll_enable(struct drm_i915_private *i915, +static void tbt_pll_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; - icl_pll_power_enable(i915, pll, TBT_PLL_ENABLE); + icl_pll_power_enable(display, pll, TBT_PLL_ENABLE); - icl_dpll_write(i915, pll, hw_state); + icl_dpll_write(display, pll, hw_state); /* * DVFS pre sequence would be here, but in our driver the cdclk code @@ -4008,24 +4000,24 @@ static void tbt_pll_enable(struct drm_i915_private *i915, * nothing here. */ - icl_pll_enable(i915, pll, TBT_PLL_ENABLE); + icl_pll_enable(display, pll, TBT_PLL_ENABLE); /* DVFS post sequence would be here. See the comment above. */ } -static void mg_pll_enable(struct drm_i915_private *i915, +static void mg_pll_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; - i915_reg_t enable_reg = intel_tc_pll_enable_reg(i915, pll); + i915_reg_t enable_reg = intel_tc_pll_enable_reg(display, pll); - icl_pll_power_enable(i915, pll, enable_reg); + icl_pll_power_enable(display, pll, enable_reg); - if (DISPLAY_VER(i915) >= 12) - dkl_pll_write(i915, pll, hw_state); + if (DISPLAY_VER(display) >= 12) + dkl_pll_write(display, pll, hw_state); else - icl_mg_pll_write(i915, pll, hw_state); + icl_mg_pll_write(display, pll, hw_state); /* * DVFS pre sequence would be here, but in our driver the cdclk code @@ -4033,12 +4025,12 @@ static void mg_pll_enable(struct drm_i915_private *i915, * nothing here. */ - icl_pll_enable(i915, pll, enable_reg); + icl_pll_enable(display, pll, enable_reg); /* DVFS post sequence would be here. See the comment above. */ } -static void icl_pll_disable(struct drm_i915_private *i915, +static void icl_pll_disable(struct intel_display *display, struct intel_shared_dpll *pll, i915_reg_t enable_reg) { @@ -4050,45 +4042,45 @@ static void icl_pll_disable(struct drm_i915_private *i915, * nothing here. */ - intel_de_rmw(i915, enable_reg, PLL_ENABLE, 0); + intel_de_rmw(display, enable_reg, PLL_ENABLE, 0); /* Timeout is actually 1us. */ - if (intel_de_wait_for_clear(i915, enable_reg, PLL_LOCK, 1)) - drm_err(&i915->drm, "PLL %d locked\n", pll->info->id); + if (intel_de_wait_for_clear(display, enable_reg, PLL_LOCK, 1)) + drm_err(display->drm, "PLL %d locked\n", pll->info->id); /* DVFS post sequence would be here. See the comment above. */ - intel_de_rmw(i915, enable_reg, PLL_POWER_ENABLE, 0); + intel_de_rmw(display, enable_reg, PLL_POWER_ENABLE, 0); /* * The spec says we need to "wait" but it also says it should be * immediate. */ - if (intel_de_wait_for_clear(i915, enable_reg, PLL_POWER_STATE, 1)) - drm_err(&i915->drm, "PLL %d Power not disabled\n", + if (intel_de_wait_for_clear(display, enable_reg, PLL_POWER_STATE, 1)) + drm_err(display->drm, "PLL %d Power not disabled\n", pll->info->id); } -static void combo_pll_disable(struct drm_i915_private *i915, +static void combo_pll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { - i915_reg_t enable_reg = intel_combo_pll_enable_reg(i915, pll); + i915_reg_t enable_reg = intel_combo_pll_enable_reg(display, pll); - icl_pll_disable(i915, pll, enable_reg); + icl_pll_disable(display, pll, enable_reg); } -static void tbt_pll_disable(struct drm_i915_private *i915, +static void tbt_pll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { - icl_pll_disable(i915, pll, TBT_PLL_ENABLE); + icl_pll_disable(display, pll, TBT_PLL_ENABLE); } -static void mg_pll_disable(struct drm_i915_private *i915, +static void mg_pll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { - i915_reg_t enable_reg = intel_tc_pll_enable_reg(i915, pll); + i915_reg_t enable_reg = intel_tc_pll_enable_reg(display, pll); - icl_pll_disable(i915, pll, enable_reg); + icl_pll_disable(display, pll, enable_reg); } static void icl_update_dpll_ref_clks(struct drm_i915_private *i915) @@ -4489,50 +4481,49 @@ void intel_update_active_dpll(struct intel_atomic_state *state, /** * intel_dpll_get_freq - calculate the DPLL's output frequency - * @i915: i915 device + * @display: intel_display device * @pll: DPLL for which to calculate the output frequency * @dpll_hw_state: DPLL state from which to calculate the output frequency * * Return the output frequency corresponding to @pll's passed in @dpll_hw_state. */ -int intel_dpll_get_freq(struct drm_i915_private *i915, +int intel_dpll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { - if (drm_WARN_ON(&i915->drm, !pll->info->funcs->get_freq)) + if (drm_WARN_ON(display->drm, !pll->info->funcs->get_freq)) return 0; - return pll->info->funcs->get_freq(i915, pll, dpll_hw_state); + return pll->info->funcs->get_freq(display, pll, dpll_hw_state); } /** * intel_dpll_get_hw_state - readout the DPLL's hardware state - * @i915: i915 device + * @display: intel_display device instance * @pll: DPLL for which to calculate the output frequency * @dpll_hw_state: DPLL's hardware state * * Read out @pll's hardware state into @dpll_hw_state. */ -bool intel_dpll_get_hw_state(struct drm_i915_private *i915, +bool intel_dpll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state) { - return pll->info->funcs->get_hw_state(i915, pll, dpll_hw_state); + return pll->info->funcs->get_hw_state(display, pll, dpll_hw_state); } -static void readout_dpll_hw_state(struct drm_i915_private *i915, +static void readout_dpll_hw_state(struct intel_display *display, struct intel_shared_dpll *pll) { - struct intel_display *display = &i915->display; struct intel_crtc *crtc; - pll->on = intel_dpll_get_hw_state(i915, pll, &pll->state.hw_state); + pll->on = intel_dpll_get_hw_state(display, pll, &pll->state.hw_state); if (pll->on && pll->info->power_domain) pll->wakeref = intel_display_power_get(display, pll->info->power_domain); pll->state.pipe_mask = 0; - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -4541,7 +4532,7 @@ static void readout_dpll_hw_state(struct drm_i915_private *i915, } pll->active_mask = pll->state.pipe_mask; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "%s hw state readout: pipe_mask 0x%x, on %i\n", pll->info->name, pll->state.pipe_mask, pll->on); } @@ -4552,42 +4543,40 @@ void intel_dpll_update_ref_clks(struct drm_i915_private *i915) i915->display.dpll.mgr->update_ref_clks(i915); } -void intel_dpll_readout_hw_state(struct drm_i915_private *i915) +void intel_dpll_readout_hw_state(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_shared_dpll *pll; int i; for_each_shared_dpll(display, pll, i) - readout_dpll_hw_state(i915, pll); + readout_dpll_hw_state(display, pll); } -static void sanitize_dpll_state(struct drm_i915_private *i915, +static void sanitize_dpll_state(struct intel_display *display, struct intel_shared_dpll *pll) { if (!pll->on) return; - adlp_cmtg_clock_gating_wa(i915, pll); + adlp_cmtg_clock_gating_wa(display, pll); if (pll->active_mask) return; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "%s enabled but not in use, disabling\n", pll->info->name); - _intel_disable_shared_dpll(i915, pll); + _intel_disable_shared_dpll(display, pll); } -void intel_dpll_sanitize_state(struct drm_i915_private *i915) +void intel_dpll_sanitize_state(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_shared_dpll *pll; int i; for_each_shared_dpll(display, pll, i) - sanitize_dpll_state(i915, pll); + sanitize_dpll_state(display, pll); } /** @@ -4637,17 +4626,16 @@ bool intel_dpll_compare_hw_state(struct intel_display *display, } static void -verify_single_dpll_state(struct drm_i915_private *i915, +verify_single_dpll_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_crtc *crtc, const struct intel_crtc_state *new_crtc_state) { - struct intel_display *display = &i915->display; struct intel_dpll_hw_state dpll_hw_state = {}; u8 pipe_mask; bool active; - active = intel_dpll_get_hw_state(i915, pll, &dpll_hw_state); + active = intel_dpll_get_hw_state(display, pll, &dpll_hw_state); if (!pll->info->always_on) { INTEL_DISPLAY_STATE_WARN(display, !pll->on && pll->active_mask, @@ -4703,14 +4691,13 @@ void intel_shared_dpll_state_verify(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (new_crtc_state->shared_dpll) - verify_single_dpll_state(i915, new_crtc_state->shared_dpll, + verify_single_dpll_state(display, new_crtc_state->shared_dpll, crtc, new_crtc_state); if (old_crtc_state->shared_dpll && @@ -4734,10 +4721,9 @@ void intel_shared_dpll_state_verify(struct intel_atomic_state *state, void intel_shared_dpll_verify_disabled(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_shared_dpll *pll; int i; for_each_shared_dpll(display, pll, i) - verify_single_dpll_state(i915, pll, NULL, NULL); + verify_single_dpll_state(display, pll, NULL, NULL); } diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index 42379494f347a..ebd0ed79d2b5e 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -390,7 +390,7 @@ struct intel_shared_dpll { /* shared dpll functions */ struct intel_shared_dpll * -intel_get_shared_dpll_by_id(struct drm_i915_private *i915, +intel_get_shared_dpll_by_id(struct intel_display *display, enum intel_dpll_id id); void assert_shared_dpll(struct drm_i915_private *i915, struct intel_shared_dpll *pll, @@ -413,10 +413,10 @@ void icl_set_active_port_dpll(struct intel_crtc_state *crtc_state, void intel_update_active_dpll(struct intel_atomic_state *state, struct intel_crtc *crtc, struct intel_encoder *encoder); -int intel_dpll_get_freq(struct drm_i915_private *i915, +int intel_dpll_get_freq(struct intel_display *display, const struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state); -bool intel_dpll_get_hw_state(struct drm_i915_private *i915, +bool intel_dpll_get_hw_state(struct intel_display *display, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *dpll_hw_state); void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state); @@ -424,8 +424,8 @@ void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state); void intel_shared_dpll_swap_state(struct intel_atomic_state *state); void intel_shared_dpll_init(struct drm_i915_private *i915); void intel_dpll_update_ref_clks(struct drm_i915_private *i915); -void intel_dpll_readout_hw_state(struct drm_i915_private *i915); -void intel_dpll_sanitize_state(struct drm_i915_private *i915); +void intel_dpll_readout_hw_state(struct intel_display *display); +void intel_dpll_sanitize_state(struct intel_display *display); void intel_dpll_dump_hw_state(struct intel_display *display, struct drm_printer *p, diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 69373031c557b..b4d1a18e9fd47 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -795,7 +795,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) pipe_name(pipe)); } - intel_dpll_readout_hw_state(i915); + intel_dpll_readout_hw_state(display); drm_connector_list_iter_begin(&i915->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { @@ -1014,7 +1014,7 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, intel_sanitize_all_crtcs(i915, ctx); - intel_dpll_sanitize_state(i915); + intel_dpll_sanitize_state(display); intel_wm_get_hw_state(i915); diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c index 8fa5a6334d10b..e874a577b7d12 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_display.c +++ b/drivers/gpu/drm/i915/display/intel_pch_display.c @@ -249,6 +249,7 @@ static void ilk_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_s static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; i915_reg_t reg; @@ -263,7 +264,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) if (HAS_PCH_CPT(dev_priv)) { reg = TRANS_CHICKEN2(pipe); - val = intel_de_read(dev_priv, reg); + val = intel_de_read(display, reg); /* * Workaround: Set the timing override bit * before enabling the pch transcoder. @@ -272,12 +273,12 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) /* Configure frame start delay to match the CPU */ val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK; val |= TRANS_CHICKEN2_FRAME_START_DELAY(crtc_state->framestart_delay - 1); - intel_de_write(dev_priv, reg, val); + intel_de_write(display, reg, val); } reg = PCH_TRANSCONF(pipe); - val = intel_de_read(dev_priv, reg); - pipeconf_val = intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)); + val = intel_de_read(display, reg); + pipeconf_val = intel_de_read(display, TRANSCONF(display, pipe)); if (HAS_PCH_IBX(dev_priv)) { /* Configure frame start delay to match the CPU */ @@ -307,9 +308,9 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) val |= TRANS_INTERLACE_PROGRESSIVE; } - intel_de_write(dev_priv, reg, val | TRANS_ENABLE); - if (intel_de_wait_for_set(dev_priv, reg, TRANS_STATE_ENABLE, 100)) - drm_err(&dev_priv->drm, "failed to enable transcoder %c\n", + intel_de_write(display, reg, val | TRANS_ENABLE); + if (intel_de_wait_for_set(display, reg, TRANS_STATE_ENABLE, 100)) + drm_err(display->drm, "failed to enable transcoder %c\n", pipe_name(pipe)); } @@ -383,15 +384,15 @@ void ilk_pch_enable(struct intel_atomic_state *state, if (HAS_PCH_CPT(dev_priv)) { u32 sel; - temp = intel_de_read(dev_priv, PCH_DPLL_SEL); + temp = intel_de_read(display, PCH_DPLL_SEL); temp |= TRANS_DPLL_ENABLE(pipe); sel = TRANS_DPLLB_SEL(pipe); if (crtc_state->shared_dpll == - intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B)) + intel_get_shared_dpll_by_id(display, DPLL_ID_PCH_PLL_B)) temp |= sel; else temp &= ~sel; - intel_de_write(dev_priv, PCH_DPLL_SEL, temp); + intel_de_write(display, PCH_DPLL_SEL, temp); } /* @@ -420,11 +421,12 @@ void ilk_pch_enable(struct intel_atomic_state *state, intel_crtc_has_dp_encoder(crtc_state)) { const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - u32 bpc = (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) >> 5; + u32 bpc = (intel_de_read(display, TRANSCONF(display, pipe)) + & TRANSCONF_BPC_MASK) >> 5; i915_reg_t reg = TRANS_DP_CTL(pipe); enum port port; - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~(TRANS_DP_PORT_SEL_MASK | TRANS_DP_VSYNC_ACTIVE_HIGH | TRANS_DP_HSYNC_ACTIVE_HIGH | @@ -438,10 +440,10 @@ void ilk_pch_enable(struct intel_atomic_state *state, temp |= TRANS_DP_VSYNC_ACTIVE_HIGH; port = intel_get_crtc_new_encoder(state, crtc_state)->port; - drm_WARN_ON(&dev_priv->drm, port < PORT_B || port > PORT_D); + drm_WARN_ON(display->drm, port < PORT_B || port > PORT_D); temp |= TRANS_DP_PORT_SEL(port); - intel_de_write(dev_priv, reg, temp); + intel_de_write(display, reg, temp); } ilk_enable_pch_transcoder(crtc_state); @@ -496,6 +498,7 @@ static void ilk_pch_clock_get(struct intel_crtc_state *crtc_state) void ilk_pch_get_config(struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_shared_dpll *pll; enum pipe pipe = crtc->pipe; @@ -503,12 +506,12 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state) bool pll_active; u32 tmp; - if ((intel_de_read(dev_priv, PCH_TRANSCONF(pipe)) & TRANS_ENABLE) == 0) + if ((intel_de_read(display, PCH_TRANSCONF(pipe)) & TRANS_ENABLE) == 0) return; crtc_state->has_pch_encoder = true; - tmp = intel_de_read(dev_priv, FDI_RX_CTL(pipe)); + tmp = intel_de_read(display, FDI_RX_CTL(pipe)); crtc_state->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >> FDI_DP_PORT_WIDTH_SHIFT) + 1; @@ -522,19 +525,19 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state) */ pll_id = (enum intel_dpll_id) pipe; } else { - tmp = intel_de_read(dev_priv, PCH_DPLL_SEL); + tmp = intel_de_read(display, PCH_DPLL_SEL); if (tmp & TRANS_DPLLB_SEL(pipe)) pll_id = DPLL_ID_PCH_PLL_B; else pll_id = DPLL_ID_PCH_PLL_A; } - crtc_state->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, pll_id); + crtc_state->shared_dpll = intel_get_shared_dpll_by_id(display, pll_id); pll = crtc_state->shared_dpll; - pll_active = intel_dpll_get_hw_state(dev_priv, pll, + pll_active = intel_dpll_get_hw_state(display, pll, &crtc_state->dpll_hw_state); - drm_WARN_ON(&dev_priv->drm, !pll_active); + drm_WARN_ON(display->drm, !pll_active); tmp = crtc_state->dpll_hw_state.i9xx.dpll; crtc_state->pixel_multiplier = From 24d687364cceb4d7547b73133c055560d2ee7d35 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 12 Feb 2025 13:15:39 +0530 Subject: [PATCH 196/284] drm/i915/dpll: Use intel_display for asserting pll Use intel_display instead of drm_i915_private to assert pll enabled and disabled and the corresponding changes needed to make that happen. Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250212074542.3569452-6-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 22 +++++++++---------- .../i915/display/intel_display_power_well.c | 10 ++++----- drivers/gpu/drm/i915/display/intel_dpll.c | 11 +++++----- drivers/gpu/drm/i915/display/intel_dpll.h | 5 +++-- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 9 +++----- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 2 +- drivers/gpu/drm/i915/display/intel_fdi.c | 16 ++++++-------- drivers/gpu/drm/i915/display/intel_fdi.h | 7 +++--- drivers/gpu/drm/i915/display/intel_lvds.c | 7 +++--- .../gpu/drm/i915/display/intel_pch_display.c | 2 +- drivers/gpu/drm/i915/display/vlv_dsi_pll.c | 12 +++++----- drivers/gpu/drm/i915/display/vlv_dsi_pll.h | 10 +++++---- 12 files changed, 55 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 8d4b6c1a0dd98..9557fa4bb89e1 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -518,7 +518,7 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) enum pipe pipe = crtc->pipe; u32 val; - drm_dbg_kms(&dev_priv->drm, "enabling pipe %c\n", pipe_name(pipe)); + drm_dbg_kms(display->drm, "enabling pipe %c\n", pipe_name(pipe)); assert_planes_disabled(crtc); @@ -529,15 +529,15 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) */ if (HAS_GMCH(dev_priv)) { if (intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI)) - assert_dsi_pll_enabled(dev_priv); + assert_dsi_pll_enabled(display); else - assert_pll_enabled(dev_priv, pipe); + assert_pll_enabled(display, pipe); } else { if (new_crtc_state->has_pch_encoder) { /* if driving the PCH, we need FDI enabled */ - assert_fdi_rx_pll_enabled(dev_priv, + assert_fdi_rx_pll_enabled(display, intel_crtc_pch_transcoder(crtc)); - assert_fdi_tx_pll_enabled(dev_priv, + assert_fdi_tx_pll_enabled(display, (enum pipe) cpu_transcoder); } /* FIXME: assert CPU port conditions for SNB+ */ @@ -545,21 +545,21 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) /* Wa_22012358565:adl-p */ if (DISPLAY_VER(dev_priv) == 13) - intel_de_rmw(dev_priv, PIPE_ARB_CTL(dev_priv, pipe), + intel_de_rmw(display, PIPE_ARB_CTL(display, pipe), 0, PIPE_ARB_USE_PROG_SLOTS); if (DISPLAY_VER(dev_priv) >= 14) { u32 clear = DP_DSC_INSERT_SF_AT_EOL_WA; u32 set = 0; - if (DISPLAY_VER(dev_priv) == 14) + if (DISPLAY_VER(display) == 14) set |= DP_FEC_BS_JITTER_WA; intel_de_rmw(display, CHICKEN_TRANS(display, cpu_transcoder), clear, set); } - val = intel_de_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder)); + val = intel_de_read(display, TRANSCONF(display, cpu_transcoder)); if (val & TRANSCONF_ENABLE) { /* we keep both pipes enabled on 830 */ drm_WARN_ON(&dev_priv->drm, !IS_I830(dev_priv)); @@ -567,16 +567,16 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) } /* Wa_1409098942:adlp+ */ - if (DISPLAY_VER(dev_priv) >= 13 && + if (DISPLAY_VER(display) >= 13 && new_crtc_state->dsc.compression_enable) { val &= ~TRANSCONF_PIXEL_COUNT_SCALING_MASK; val |= REG_FIELD_PREP(TRANSCONF_PIXEL_COUNT_SCALING_MASK, TRANSCONF_PIXEL_COUNT_SCALING_X4); } - intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), + intel_de_write(display, TRANSCONF(display, cpu_transcoder), val | TRANSCONF_ENABLE); - intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder)); + intel_de_posting_read(display, TRANSCONF(display, cpu_transcoder)); /* * Until the pipe starts PIPEDSL reads will return a stale value, diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index faf5ca1c706d2..6fbb94c8bfb3c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -1312,11 +1312,10 @@ static void vlv_dpio_cmn_power_well_enable(struct intel_display *display, static void vlv_dpio_cmn_power_well_disable(struct intel_display *display, struct i915_power_well *power_well) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; for_each_pipe(display, pipe) - assert_pll_disabled(dev_priv, pipe); + assert_pll_disabled(display, pipe); /* Assert common reset */ intel_de_rmw(display, DPIO_CTL, DPIO_CMNRST, 0); @@ -1498,7 +1497,6 @@ static void chv_dpio_cmn_power_well_enable(struct intel_display *display, static void chv_dpio_cmn_power_well_disable(struct intel_display *display, struct i915_power_well *power_well) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum i915_power_well_id id = i915_power_well_instance(power_well)->id; enum dpio_phy phy; @@ -1508,11 +1506,11 @@ static void chv_dpio_cmn_power_well_disable(struct intel_display *display, if (id == VLV_DISP_PW_DPIO_CMN_BC) { phy = DPIO_PHY0; - assert_pll_disabled(dev_priv, PIPE_A); - assert_pll_disabled(dev_priv, PIPE_B); + assert_pll_disabled(display, PIPE_A); + assert_pll_disabled(display, PIPE_B); } else { phy = DPIO_PHY1; - assert_pll_disabled(dev_priv, PIPE_C); + assert_pll_disabled(display, PIPE_C); } display->power.chv_phy_control &= ~PHY_COM_LANE_RESET_DEASSERT(phy); diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 3256b1293f7fc..cc19cd51ab4d9 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -2329,10 +2329,9 @@ void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe) } /* Only for pre-ILK configs */ -static void assert_pll(struct drm_i915_private *dev_priv, +static void assert_pll(struct intel_display *display, enum pipe pipe, bool state) { - struct intel_display *display = &dev_priv->display; bool cur_state; cur_state = intel_de_read(display, DPLL(display, pipe)) & DPLL_VCO_ENABLE; @@ -2341,12 +2340,12 @@ static void assert_pll(struct drm_i915_private *dev_priv, str_on_off(state), str_on_off(cur_state)); } -void assert_pll_enabled(struct drm_i915_private *i915, enum pipe pipe) +void assert_pll_enabled(struct intel_display *display, enum pipe pipe) { - assert_pll(i915, pipe, true); + assert_pll(display, pipe, true); } -void assert_pll_disabled(struct drm_i915_private *i915, enum pipe pipe) +void assert_pll_disabled(struct intel_display *display, enum pipe pipe) { - assert_pll(i915, pipe, false); + assert_pll(display, pipe, false); } diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h b/drivers/gpu/drm/i915/display/intel_dpll.h index a86a79408af0f..21d06cbd2ce75 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.h +++ b/drivers/gpu/drm/i915/display/intel_dpll.h @@ -13,6 +13,7 @@ struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_display; struct intel_dpll_hw_state; enum pipe; @@ -46,7 +47,7 @@ void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state); void vlv_crtc_clock_get(struct intel_crtc_state *crtc_state); void chv_crtc_clock_get(struct intel_crtc_state *crtc_state); -void assert_pll_enabled(struct drm_i915_private *i915, enum pipe pipe); -void assert_pll_disabled(struct drm_i915_private *i915, enum pipe pipe); +void assert_pll_enabled(struct intel_display *display, enum pipe pipe); +void assert_pll_disabled(struct intel_display *display, enum pipe pipe); #endif diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 16332c0635b01..2d909e6c0137a 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -171,11 +171,10 @@ intel_get_shared_dpll_by_id(struct intel_display *display, } /* For ILK+ */ -void assert_shared_dpll(struct drm_i915_private *i915, +void assert_shared_dpll(struct intel_display *display, struct intel_shared_dpll *pll, bool state) { - struct intel_display *display = &i915->display; bool cur_state; struct intel_dpll_hw_state hw_state; @@ -256,7 +255,6 @@ void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_shared_dpll *pll = crtc_state->shared_dpll; unsigned int pipe_mask = BIT(crtc->pipe); unsigned int old_mask; @@ -280,7 +278,7 @@ void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state) if (old_mask) { drm_WARN_ON(display->drm, !pll->on); - assert_shared_dpll_enabled(i915, pll); + assert_shared_dpll_enabled(display, pll); goto out; } drm_WARN_ON(display->drm, pll->on); @@ -303,7 +301,6 @@ void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_shared_dpll *pll = crtc_state->shared_dpll; unsigned int pipe_mask = BIT(crtc->pipe); @@ -325,7 +322,7 @@ void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state) pll->info->name, pll->active_mask, pll->on, crtc->base.base.id, crtc->base.name); - assert_shared_dpll_enabled(i915, pll); + assert_shared_dpll_enabled(display, pll); drm_WARN_ON(display->drm, !pll->on); pll->active_mask &= ~pipe_mask; diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index ebd0ed79d2b5e..b6f2cbce13e47 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -392,7 +392,7 @@ struct intel_shared_dpll { struct intel_shared_dpll * intel_get_shared_dpll_by_id(struct intel_display *display, enum intel_dpll_id id); -void assert_shared_dpll(struct drm_i915_private *i915, +void assert_shared_dpll(struct intel_display *display, struct intel_shared_dpll *pll, bool state); #define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 3e8d6d8af7802..9ebe80bfaab66 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -80,14 +80,13 @@ void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe) assert_fdi_rx(i915, pipe, false); } -void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915, +void assert_fdi_tx_pll_enabled(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &i915->display; bool cur_state; /* ILK FDI PLL is always enabled */ - if (IS_IRONLAKE(i915)) + if (display->platform.ironlake) return; /* On Haswell, DDI ports are responsible for the FDI PLL setup */ @@ -99,10 +98,9 @@ void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915, "FDI TX PLL assertion failure, should be active but is disabled\n"); } -static void assert_fdi_rx_pll(struct drm_i915_private *i915, +static void assert_fdi_rx_pll(struct intel_display *display, enum pipe pipe, bool state) { - struct intel_display *display = &i915->display; bool cur_state; cur_state = intel_de_read(display, FDI_RX_CTL(pipe)) & FDI_RX_PLL_ENABLE; @@ -111,14 +109,14 @@ static void assert_fdi_rx_pll(struct drm_i915_private *i915, str_on_off(state), str_on_off(cur_state)); } -void assert_fdi_rx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe) +void assert_fdi_rx_pll_enabled(struct intel_display *display, enum pipe pipe) { - assert_fdi_rx_pll(i915, pipe, true); + assert_fdi_rx_pll(display, pipe, true); } -void assert_fdi_rx_pll_disabled(struct drm_i915_private *i915, enum pipe pipe) +void assert_fdi_rx_pll_disabled(struct intel_display *display, enum pipe pipe) { - assert_fdi_rx_pll(i915, pipe, false); + assert_fdi_rx_pll(display, pipe, false); } void intel_fdi_link_train(struct intel_crtc *crtc, diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index 477ff0136934d..b5be09efb36f4 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -13,6 +13,7 @@ struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_display; struct intel_encoder; struct intel_link_bw_limits; @@ -41,8 +42,8 @@ void assert_fdi_tx_enabled(struct drm_i915_private *i915, enum pipe pipe); void assert_fdi_tx_disabled(struct drm_i915_private *i915, enum pipe pipe); void assert_fdi_rx_enabled(struct drm_i915_private *i915, enum pipe pipe); void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe); -void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe); -void assert_fdi_rx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe); -void assert_fdi_rx_pll_disabled(struct drm_i915_private *i915, enum pipe pipe); +void assert_fdi_tx_pll_enabled(struct intel_display *display, enum pipe pipe); +void assert_fdi_rx_pll_enabled(struct intel_display *display, enum pipe pipe); +void assert_fdi_rx_pll_disabled(struct intel_display *display, enum pipe pipe); #endif diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 761e0c6e6dd93..c6644e8013646 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -240,6 +240,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(state); struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -248,10 +249,10 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state, u32 temp; if (HAS_PCH_SPLIT(i915)) { - assert_fdi_rx_pll_disabled(i915, pipe); - assert_shared_dpll_disabled(i915, crtc_state->shared_dpll); + assert_fdi_rx_pll_disabled(display, pipe); + assert_shared_dpll_disabled(display, crtc_state->shared_dpll); } else { - assert_pll_disabled(i915, pipe); + assert_pll_disabled(display, pipe); } intel_lvds_pps_init_hw(i915, &lvds_encoder->init_pps); diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c index e874a577b7d12..75ff5592312fb 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_display.c +++ b/drivers/gpu/drm/i915/display/intel_pch_display.c @@ -256,7 +256,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) u32 val, pipeconf_val; /* Make sure PCH DPLL is enabled */ - assert_shared_dpll_enabled(dev_priv, crtc_state->shared_dpll); + assert_shared_dpll_enabled(display, crtc_state->shared_dpll); /* FDI must be feeding us bits for PCH ports */ assert_fdi_tx_enabled(dev_priv, pipe); diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c index ac69eaece0fda..2ed47e7d10511 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c @@ -590,9 +590,9 @@ void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) intel_de_write(display, MIPI_EOT_DISABLE(display, port), CLOCKSTOP); } -static void assert_dsi_pll(struct drm_i915_private *i915, bool state) +static void assert_dsi_pll(struct intel_display *display, bool state) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); bool cur_state; vlv_cck_get(i915); @@ -604,12 +604,12 @@ static void assert_dsi_pll(struct drm_i915_private *i915, bool state) str_on_off(state), str_on_off(cur_state)); } -void assert_dsi_pll_enabled(struct drm_i915_private *i915) +void assert_dsi_pll_enabled(struct intel_display *display) { - assert_dsi_pll(i915, true); + assert_dsi_pll(display, true); } -void assert_dsi_pll_disabled(struct drm_i915_private *i915) +void assert_dsi_pll_disabled(struct intel_display *display) { - assert_dsi_pll(i915, false); + assert_dsi_pll(display, false); } diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.h b/drivers/gpu/drm/i915/display/vlv_dsi_pll.h index fbe5113dbeb9f..a032cc2a2524f 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.h +++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.h @@ -11,6 +11,7 @@ enum port; struct drm_i915_private; struct intel_crtc_state; +struct intel_display; struct intel_encoder; int vlv_dsi_pll_compute(struct intel_encoder *encoder, @@ -33,13 +34,14 @@ u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port); #ifdef I915 -void assert_dsi_pll_enabled(struct drm_i915_private *i915); -void assert_dsi_pll_disabled(struct drm_i915_private *i915); +void assert_dsi_pll_enabled(struct intel_display *display); +void assert_dsi_pll_disabled(struct intel_display *display); #else -static inline void assert_dsi_pll_enabled(struct drm_i915_private *i915) +static inline void assert_dsi_pll_enabled(struct intel_display *display) { } -static inline void assert_dsi_pll_disabled(struct drm_i915_private *i915) + +static inline void assert_dsi_pll_disabled(struct intel_display *display) { } #endif From 65596167857fac39ec9e11ef52d2c51b46409bc7 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 12 Feb 2025 13:15:40 +0530 Subject: [PATCH 197/284] drm/i915/dpll: Use intel_display for update_refclk hook Use intel_display instead of drm_i915_private for update_refclk hook. Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250212074542.3569452-7-suraj.kandpal@intel.com --- .../drm/i915/display/intel_display_driver.c | 2 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 32 +++++++++---------- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index d448672fdfa4f..978f530c810e9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -453,7 +453,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) intel_update_czclk(i915); intel_display_driver_init_hw(display); - intel_dpll_update_ref_clks(i915); + intel_dpll_update_ref_clks(display); if (display->cdclk.max_cdclk_freq == 0) intel_update_max_cdclk(display); diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 2d909e6c0137a..124f590a15c09 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -109,7 +109,7 @@ struct intel_dpll_mgr { void (*update_active_dpll)(struct intel_atomic_state *state, struct intel_crtc *crtc, struct intel_encoder *encoder); - void (*update_ref_clks)(struct drm_i915_private *i915); + void (*update_ref_clks)(struct intel_display *display); void (*dump_hw_state)(struct drm_printer *p, const struct intel_dpll_hw_state *dpll_hw_state); bool (*compare_hw_state)(const struct intel_dpll_hw_state *a, @@ -1242,14 +1242,14 @@ static int hsw_get_dpll(struct intel_atomic_state *state, return 0; } -static void hsw_update_dpll_ref_clks(struct drm_i915_private *i915) +static void hsw_update_dpll_ref_clks(struct intel_display *display) { - i915->display.dpll.ref_clks.ssc = 135000; + display->dpll.ref_clks.ssc = 135000; /* Non-SSC is only used on non-ULT HSW. */ - if (intel_de_read(i915, FUSE_STRAP3) & HSW_REF_CLK_SELECT) - i915->display.dpll.ref_clks.nssc = 24000; + if (intel_de_read(display, FUSE_STRAP3) & HSW_REF_CLK_SELECT) + display->dpll.ref_clks.nssc = 24000; else - i915->display.dpll.ref_clks.nssc = 135000; + display->dpll.ref_clks.nssc = 135000; } static void hsw_dump_hw_state(struct drm_printer *p, @@ -1979,10 +1979,10 @@ static int skl_ddi_pll_get_freq(struct intel_display *display, return skl_ddi_lcpll_get_freq(display, pll, dpll_hw_state); } -static void skl_update_dpll_ref_clks(struct drm_i915_private *i915) +static void skl_update_dpll_ref_clks(struct intel_display *display) { /* No SSC ref */ - i915->display.dpll.ref_clks.nssc = i915->display.cdclk.hw.ref; + display->dpll.ref_clks.nssc = display->cdclk.hw.ref; } static void skl_dump_hw_state(struct drm_printer *p, @@ -2448,10 +2448,10 @@ static int bxt_get_dpll(struct intel_atomic_state *state, return 0; } -static void bxt_update_dpll_ref_clks(struct drm_i915_private *i915) +static void bxt_update_dpll_ref_clks(struct intel_display *display) { - i915->display.dpll.ref_clks.ssc = 100000; - i915->display.dpll.ref_clks.nssc = 100000; + display->dpll.ref_clks.ssc = 100000; + display->dpll.ref_clks.nssc = 100000; /* DSI non-SSC ref 19.2MHz */ } @@ -4080,10 +4080,10 @@ static void mg_pll_disable(struct intel_display *display, icl_pll_disable(display, pll, enable_reg); } -static void icl_update_dpll_ref_clks(struct drm_i915_private *i915) +static void icl_update_dpll_ref_clks(struct intel_display *display) { /* No SSC ref */ - i915->display.dpll.ref_clks.nssc = i915->display.cdclk.hw.ref; + display->dpll.ref_clks.nssc = display->cdclk.hw.ref; } static void icl_dump_hw_state(struct drm_printer *p, @@ -4534,10 +4534,10 @@ static void readout_dpll_hw_state(struct intel_display *display, pll->info->name, pll->state.pipe_mask, pll->on); } -void intel_dpll_update_ref_clks(struct drm_i915_private *i915) +void intel_dpll_update_ref_clks(struct intel_display *display) { - if (i915->display.dpll.mgr && i915->display.dpll.mgr->update_ref_clks) - i915->display.dpll.mgr->update_ref_clks(i915); + if (display->dpll.mgr && display->dpll.mgr->update_ref_clks) + display->dpll.mgr->update_ref_clks(display); } void intel_dpll_readout_hw_state(struct intel_display *display) diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index b6f2cbce13e47..3d988f17f31d1 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -423,7 +423,7 @@ void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state); void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state); void intel_shared_dpll_swap_state(struct intel_atomic_state *state); void intel_shared_dpll_init(struct drm_i915_private *i915); -void intel_dpll_update_ref_clks(struct drm_i915_private *i915); +void intel_dpll_update_ref_clks(struct intel_display *display); void intel_dpll_readout_hw_state(struct intel_display *display); void intel_dpll_sanitize_state(struct intel_display *display); From 7d7529582cc29ab06bb0b269f3364586abacff52 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 12 Feb 2025 13:15:41 +0530 Subject: [PATCH 198/284] drm/i915/dpll: Accept intel_display as argument for shared_dpll_init Use intel_display as an argument for intel_shared_dpll_init() and replace drm_i915_private in function wherever possible. While at it prefer using display->platform.xx over IS_PLATFORM. Initialize dpio_phy and dpio_channel since with IS_GEMINILAKE() and IS_BROXTON() compiler knows it will return false for xe but since display->platform.xx is a runtime check which means the compiler sees a potential path where uninitialized variables could be accessed and raises a warning. --v2 -Amend commit message to explain why some variables were initialized [Jani] Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250212074542.3569452-8-suraj.kandpal@intel.com --- .../drm/i915/display/intel_display_driver.c | 2 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 49 ++++++++++--------- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 3 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 978f530c810e9..852f1129a058d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -448,7 +448,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) } intel_plane_possible_crtcs_init(display); - intel_shared_dpll_init(i915); + intel_shared_dpll_init(display); intel_fdi_pll_freq_update(i915); intel_update_czclk(i915); diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 124f590a15c09..1c718748dacb3 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -2044,8 +2044,8 @@ static void bxt_ddi_pll_enable(struct intel_display *display, { const struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt; enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */ - enum dpio_phy phy; - enum dpio_channel ch; + enum dpio_phy phy = DPIO_PHY0; + enum dpio_channel ch = DPIO_CH0; u32 temp; bxt_port_to_phy_channel(display, port, &phy, &ch); @@ -4304,40 +4304,41 @@ static const struct intel_dpll_mgr adlp_pll_mgr = { /** * intel_shared_dpll_init - Initialize shared DPLLs - * @i915: i915 device + * @display: intel_display device * - * Initialize shared DPLLs for @i915. + * Initialize shared DPLLs for @display. */ -void intel_shared_dpll_init(struct drm_i915_private *i915) +void intel_shared_dpll_init(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); const struct intel_dpll_mgr *dpll_mgr = NULL; const struct dpll_info *dpll_info; int i; - mutex_init(&i915->display.dpll.lock); + mutex_init(&display->dpll.lock); - if (DISPLAY_VER(i915) >= 14 || IS_DG2(i915)) + if (DISPLAY_VER(display) >= 14 || display->platform.dg2) /* No shared DPLLs on DG2; port PLLs are part of the PHY */ dpll_mgr = NULL; - else if (IS_ALDERLAKE_P(i915)) + else if (display->platform.alderlake_p) dpll_mgr = &adlp_pll_mgr; - else if (IS_ALDERLAKE_S(i915)) + else if (display->platform.alderlake_s) dpll_mgr = &adls_pll_mgr; - else if (IS_DG1(i915)) + else if (display->platform.dg1) dpll_mgr = &dg1_pll_mgr; - else if (IS_ROCKETLAKE(i915)) + else if (display->platform.rocketlake) dpll_mgr = &rkl_pll_mgr; - else if (DISPLAY_VER(i915) >= 12) + else if (DISPLAY_VER(display) >= 12) dpll_mgr = &tgl_pll_mgr; - else if (IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) + else if (display->platform.jasperlake || display->platform.elkhartlake) dpll_mgr = &ehl_pll_mgr; - else if (DISPLAY_VER(i915) >= 11) + else if (DISPLAY_VER(display) >= 11) dpll_mgr = &icl_pll_mgr; - else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) + else if (display->platform.geminilake || display->platform.broxton) dpll_mgr = &bxt_pll_mgr; - else if (DISPLAY_VER(i915) == 9) + else if (DISPLAY_VER(display) == 9) dpll_mgr = &skl_pll_mgr; - else if (HAS_DDI(i915)) + else if (HAS_DDI(display)) dpll_mgr = &hsw_pll_mgr; else if (HAS_PCH_IBX(i915) || HAS_PCH_CPT(i915)) dpll_mgr = &pch_pll_mgr; @@ -4348,20 +4349,20 @@ void intel_shared_dpll_init(struct drm_i915_private *i915) dpll_info = dpll_mgr->dpll_info; for (i = 0; dpll_info[i].name; i++) { - if (drm_WARN_ON(&i915->drm, - i >= ARRAY_SIZE(i915->display.dpll.shared_dplls))) + if (drm_WARN_ON(display->drm, + i >= ARRAY_SIZE(display->dpll.shared_dplls))) break; /* must fit into unsigned long bitmask on 32bit */ - if (drm_WARN_ON(&i915->drm, dpll_info[i].id >= 32)) + if (drm_WARN_ON(display->drm, dpll_info[i].id >= 32)) break; - i915->display.dpll.shared_dplls[i].info = &dpll_info[i]; - i915->display.dpll.shared_dplls[i].index = i; + display->dpll.shared_dplls[i].info = &dpll_info[i]; + display->dpll.shared_dplls[i].index = i; } - i915->display.dpll.mgr = dpll_mgr; - i915->display.dpll.num_shared_dpll = i; + display->dpll.mgr = dpll_mgr; + display->dpll.num_shared_dpll = i; } /** diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index 3d988f17f31d1..caffb084830ce 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -35,7 +35,6 @@ ((__pll) = &(__display)->dpll.shared_dplls[(__i)]) ; (__i)++) enum tc_port; -struct drm_i915_private; struct drm_printer; struct intel_atomic_state; struct intel_crtc; @@ -422,7 +421,7 @@ bool intel_dpll_get_hw_state(struct intel_display *display, void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state); void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state); void intel_shared_dpll_swap_state(struct intel_atomic_state *state); -void intel_shared_dpll_init(struct drm_i915_private *i915); +void intel_shared_dpll_init(struct intel_display *display); void intel_dpll_update_ref_clks(struct intel_display *display); void intel_dpll_readout_hw_state(struct intel_display *display); void intel_dpll_sanitize_state(struct intel_display *display); From 4ce63ed330ff48cca1170464d4dabc7e75f663c9 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 12 Feb 2025 13:15:42 +0530 Subject: [PATCH 199/284] drm/i915/dpll: Replace all other leftover drm_i915_private Replace all other left over drm_i915_private with intel_display in dpll_mgr.c. --v2 -Don't use inline to_intel_display() [Jani] Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250212074542.3569452-9-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 100 +++++++++--------- 1 file changed, 49 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 1c718748dacb3..eb3df25a308cb 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -117,11 +117,10 @@ struct intel_dpll_mgr { }; static void -intel_atomic_duplicate_dpll_state(struct drm_i915_private *i915, +intel_atomic_duplicate_dpll_state(struct intel_display *display, struct intel_shared_dpll_state *shared_dpll) { struct intel_shared_dpll *pll; - struct intel_display *display = &i915->display; int i; /* Copy shared dpll state */ @@ -133,13 +132,14 @@ static struct intel_shared_dpll_state * intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s) { struct intel_atomic_state *state = to_intel_atomic_state(s); + struct intel_display *display = to_intel_display(state); drm_WARN_ON(s->dev, !drm_modeset_is_locked(&s->dev->mode_config.connection_mutex)); if (!state->dpll_set) { state->dpll_set = true; - intel_atomic_duplicate_dpll_state(to_i915(s->dev), + intel_atomic_duplicate_dpll_state(display, state->shared_dpll); } @@ -420,13 +420,13 @@ intel_reference_shared_dpll_crtc(const struct intel_crtc *crtc, const struct intel_shared_dpll *pll, struct intel_shared_dpll_state *shared_dpll_state) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - drm_WARN_ON(&i915->drm, (shared_dpll_state->pipe_mask & BIT(crtc->pipe)) != 0); + drm_WARN_ON(display->drm, (shared_dpll_state->pipe_mask & BIT(crtc->pipe)) != 0); shared_dpll_state->pipe_mask |= BIT(crtc->pipe); - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] reserving %s\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] reserving %s\n", crtc->base.base.id, crtc->base.name, pll->info->name); } @@ -459,13 +459,13 @@ intel_unreference_shared_dpll_crtc(const struct intel_crtc *crtc, const struct intel_shared_dpll *pll, struct intel_shared_dpll_state *shared_dpll_state) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - drm_WARN_ON(&i915->drm, (shared_dpll_state->pipe_mask & BIT(crtc->pipe)) == 0); + drm_WARN_ON(display->drm, (shared_dpll_state->pipe_mask & BIT(crtc->pipe)) == 0); shared_dpll_state->pipe_mask &= ~BIT(crtc->pipe); - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] releasing %s\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] releasing %s\n", crtc->base.base.id, crtc->base.name, pll->info->name); } @@ -545,9 +545,8 @@ static bool ibx_pch_dpll_get_hw_state(struct intel_display *display, return val & DPLL_VCO_ENABLE; } -static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *i915) +static void ibx_assert_pch_refclk_enabled(struct intel_display *display) { - struct intel_display *display = &i915->display; u32 val; bool enabled; @@ -562,12 +561,11 @@ static void ibx_pch_dpll_enable(struct intel_display *display, struct intel_shared_dpll *pll, const struct intel_dpll_hw_state *dpll_hw_state) { - struct drm_i915_private *i915 = to_i915(display->drm); const struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx; const enum intel_dpll_id id = pll->info->id; /* PCH refclock must be enabled first */ - ibx_assert_pch_refclk_enabled(i915); + ibx_assert_pch_refclk_enabled(display); intel_de_write(display, PCH_FP0(id), hw_state->fp0); intel_de_write(display, PCH_FP1(id), hw_state->fp1); @@ -1076,7 +1074,7 @@ hsw_ddi_wrpll_get_dpll(struct intel_atomic_state *state, static int hsw_ddi_lcpll_compute_dpll(struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); int clock = crtc_state->port_clock; switch (clock / 2) { @@ -1085,7 +1083,7 @@ hsw_ddi_lcpll_compute_dpll(struct intel_crtc_state *crtc_state) case 270000: return 0; default: - drm_dbg_kms(&i915->drm, "Invalid clock for DP: %d\n", + drm_dbg_kms(display->drm, "Invalid clock for DP: %d\n", clock); return -EINVAL; } @@ -2257,7 +2255,7 @@ static int bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state, struct dpll *clk_div) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); /* Calculate HDMI div */ /* @@ -2267,7 +2265,7 @@ bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state, if (!bxt_find_best_dpll(crtc_state, clk_div)) return -EINVAL; - drm_WARN_ON(&i915->drm, clk_div->m1 != 2); + drm_WARN_ON(display->drm, clk_div->m1 != 2); return 0; } @@ -2275,7 +2273,7 @@ bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state, static void bxt_ddi_dp_pll_dividers(struct intel_crtc_state *crtc_state, struct dpll *clk_div) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); int i; *clk_div = bxt_dp_clk_val[0]; @@ -2286,16 +2284,16 @@ static void bxt_ddi_dp_pll_dividers(struct intel_crtc_state *crtc_state, } } - chv_calc_dpll_params(i915->display.dpll.ref_clks.nssc, clk_div); + chv_calc_dpll_params(display->dpll.ref_clks.nssc, clk_div); - drm_WARN_ON(&i915->drm, clk_div->vco == 0 || + drm_WARN_ON(display->drm, clk_div->vco == 0 || clk_div->dot != crtc_state->port_clock); } static int bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state, const struct dpll *clk_div) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); struct bxt_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.bxt; int clock = crtc_state->port_clock; int vco = clk_div->vco; @@ -2319,7 +2317,7 @@ static int bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state, gain_ctl = 1; targ_cnt = 9; } else { - drm_err(&i915->drm, "Invalid VCO\n"); + drm_err(display->drm, "Invalid VCO\n"); return -EINVAL; } @@ -2702,9 +2700,9 @@ static const struct skl_wrpll_params tgl_tbt_pll_24MHz_values = { static int icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state, struct skl_wrpll_params *pll_params) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); const struct icl_combo_pll_params *params = - i915->display.dpll.ref_clks.nssc == 24000 ? + display->dpll.ref_clks.nssc == 24000 ? icl_dp_combo_pll_24MHz_values : icl_dp_combo_pll_19_2MHz_values; int clock = crtc_state->port_clock; @@ -2724,12 +2722,12 @@ static int icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state, static int icl_calc_tbt_pll(struct intel_crtc_state *crtc_state, struct skl_wrpll_params *pll_params) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); - if (DISPLAY_VER(i915) >= 12) { - switch (i915->display.dpll.ref_clks.nssc) { + if (DISPLAY_VER(display) >= 12) { + switch (display->dpll.ref_clks.nssc) { default: - MISSING_CASE(i915->display.dpll.ref_clks.nssc); + MISSING_CASE(display->dpll.ref_clks.nssc); fallthrough; case 19200: case 38400: @@ -2740,9 +2738,9 @@ static int icl_calc_tbt_pll(struct intel_crtc_state *crtc_state, break; } } else { - switch (i915->display.dpll.ref_clks.nssc) { + switch (display->dpll.ref_clks.nssc) { default: - MISSING_CASE(i915->display.dpll.ref_clks.nssc); + MISSING_CASE(display->dpll.ref_clks.nssc); fallthrough; case 19200: case 38400: @@ -3000,9 +2998,9 @@ static int icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc, static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, struct intel_dpll_hw_state *dpll_hw_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl; - int refclk_khz = i915->display.dpll.ref_clks.nssc; + int refclk_khz = display->dpll.ref_clks.nssc; int clock = crtc_state->port_clock; u32 dco_khz, m1div, m2div_int, m2div_rem, m2div_frac; u32 iref_ndiv, iref_trim, iref_pulse_w; @@ -3012,7 +3010,7 @@ static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, u64 tmp; bool use_ssc = false; bool is_dp = !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI); - bool is_dkl = DISPLAY_VER(i915) >= 12; + bool is_dkl = DISPLAY_VER(display) >= 12; int ret; ret = icl_mg_pll_find_divisors(clock, is_dp, use_ssc, &dco_khz, @@ -3110,8 +3108,8 @@ static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, DKL_PLL_DIV0_PROP_COEFF(prop_coeff) | DKL_PLL_DIV0_FBPREDIV(m1div) | DKL_PLL_DIV0_FBDIV_INT(m2div_int); - if (i915->display.vbt.override_afc_startup) { - u8 val = i915->display.vbt.override_afc_startup_val; + if (display->vbt.override_afc_startup) { + u8 val = display->vbt.override_afc_startup_val; hw_state->mg_pll_div0 |= DKL_PLL_DIV0_AFC_STARTUP(val); } @@ -3349,7 +3347,6 @@ static int icl_get_combo_phy_dpll(struct intel_atomic_state *state, struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct icl_port_dpll *port_dpll = @@ -3357,13 +3354,13 @@ static int icl_get_combo_phy_dpll(struct intel_atomic_state *state, enum port port = encoder->port; unsigned long dpll_mask; - if (IS_ALDERLAKE_S(i915)) { + if (display->platform.alderlake_s) { dpll_mask = BIT(DPLL_ID_DG1_DPLL3) | BIT(DPLL_ID_DG1_DPLL2) | BIT(DPLL_ID_ICL_DPLL1) | BIT(DPLL_ID_ICL_DPLL0); - } else if (IS_DG1(i915)) { + } else if (display->platform.dg1) { if (port == PORT_D || port == PORT_E) { dpll_mask = BIT(DPLL_ID_DG1_DPLL2) | @@ -3373,12 +3370,13 @@ static int icl_get_combo_phy_dpll(struct intel_atomic_state *state, BIT(DPLL_ID_DG1_DPLL0) | BIT(DPLL_ID_DG1_DPLL1); } - } else if (IS_ROCKETLAKE(i915)) { + } else if (display->platform.rocketlake) { dpll_mask = BIT(DPLL_ID_EHL_DPLL4) | BIT(DPLL_ID_ICL_DPLL1) | BIT(DPLL_ID_ICL_DPLL0); - } else if ((IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) && + } else if ((display->platform.jasperlake || + display->platform.elkhartlake) && port != PORT_A) { dpll_mask = BIT(DPLL_ID_EHL_DPLL4) | @@ -4383,10 +4381,10 @@ int intel_compute_shared_dplls(struct intel_atomic_state *state, struct intel_crtc *crtc, struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(state->base.dev); - const struct intel_dpll_mgr *dpll_mgr = i915->display.dpll.mgr; + struct intel_display *display = to_intel_display(state); + const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr; - if (drm_WARN_ON(&i915->drm, !dpll_mgr)) + if (drm_WARN_ON(display->drm, !dpll_mgr)) return -EINVAL; return dpll_mgr->compute_dplls(state, crtc, encoder); @@ -4416,10 +4414,10 @@ int intel_reserve_shared_dplls(struct intel_atomic_state *state, struct intel_crtc *crtc, struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(state->base.dev); - const struct intel_dpll_mgr *dpll_mgr = i915->display.dpll.mgr; + struct intel_display *display = to_intel_display(state); + const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr; - if (drm_WARN_ON(&i915->drm, !dpll_mgr)) + if (drm_WARN_ON(display->drm, !dpll_mgr)) return -EINVAL; return dpll_mgr->get_dplls(state, crtc, encoder); @@ -4439,8 +4437,8 @@ int intel_reserve_shared_dplls(struct intel_atomic_state *state, void intel_release_shared_dplls(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); - const struct intel_dpll_mgr *dpll_mgr = i915->display.dpll.mgr; + struct intel_display *display = to_intel_display(state); + const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr; /* * FIXME: this function is called for every platform having a @@ -4468,10 +4466,10 @@ void intel_update_active_dpll(struct intel_atomic_state *state, struct intel_crtc *crtc, struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); - const struct intel_dpll_mgr *dpll_mgr = i915->display.dpll.mgr; + struct intel_display *display = to_intel_display(encoder); + const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr; - if (drm_WARN_ON(&i915->drm, !dpll_mgr)) + if (drm_WARN_ON(display->drm, !dpll_mgr)) return; dpll_mgr->update_active_dpll(state, crtc, encoder); From a5b55c18509500993b1540365c4f45ea1976ce97 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 7 Feb 2025 12:17:36 +0200 Subject: [PATCH 200/284] drm/i915/pch: Make LPT LP a dedicated PCH type Add PCH type PCH_LPT_LP and rename PCH_LPT to PCH_LPT_H for consistency. Keep the existing HAS_PCH_LPT*() macros, but express them in terms of the PCH types instead of looking at the device IDs directly. This makes the PCH checks independent of the PCH device IDs. Reviewed-by: Nemesa Garg Link: https://patchwork.freedesktop.org/patch/msgid/777b63f50b10fba1d768af25870e81b33267bdc8.1738923308.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_backlight.c | 2 +- drivers/gpu/drm/i915/soc/intel_pch.c | 8 ++++---- drivers/gpu/drm/i915/soc/intel_pch.h | 14 ++++++-------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 477b21af71a4f..178dc6c8de80c 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -1829,7 +1829,7 @@ void intel_backlight_init_funcs(struct intel_panel *panel) panel->backlight.pwm_funcs = &bxt_pwm_funcs; } else if (INTEL_PCH_TYPE(i915) >= PCH_CNP) { panel->backlight.pwm_funcs = &cnp_pwm_funcs; - } else if (INTEL_PCH_TYPE(i915) >= PCH_LPT) { + } else if (INTEL_PCH_TYPE(i915) >= PCH_LPT_H) { if (HAS_PCH_LPT(i915)) panel->backlight.pwm_funcs = &lpt_pwm_funcs; else diff --git a/drivers/gpu/drm/i915/soc/intel_pch.c b/drivers/gpu/drm/i915/soc/intel_pch.c index 9f7c9dbc178eb..0370ccb6943c9 100644 --- a/drivers/gpu/drm/i915/soc/intel_pch.c +++ b/drivers/gpu/drm/i915/soc/intel_pch.c @@ -33,14 +33,14 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id) !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)); drm_WARN_ON(&dev_priv->drm, IS_HASWELL_ULT(dev_priv) || IS_BROADWELL_ULT(dev_priv)); - return PCH_LPT; + return PCH_LPT_H; case INTEL_PCH_LPT_LP_DEVICE_ID_TYPE: drm_dbg_kms(&dev_priv->drm, "Found LynxPoint LP PCH\n"); drm_WARN_ON(&dev_priv->drm, !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)); drm_WARN_ON(&dev_priv->drm, !IS_HASWELL_ULT(dev_priv) && !IS_BROADWELL_ULT(dev_priv)); - return PCH_LPT; + return PCH_LPT_LP; case INTEL_PCH_WPT_DEVICE_ID_TYPE: drm_dbg_kms(&dev_priv->drm, "Found WildcatPoint PCH\n"); drm_WARN_ON(&dev_priv->drm, @@ -48,7 +48,7 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id) drm_WARN_ON(&dev_priv->drm, IS_HASWELL_ULT(dev_priv) || IS_BROADWELL_ULT(dev_priv)); /* WPT is LPT compatible */ - return PCH_LPT; + return PCH_LPT_H; case INTEL_PCH_WPT_LP_DEVICE_ID_TYPE: drm_dbg_kms(&dev_priv->drm, "Found WildcatPoint LP PCH\n"); drm_WARN_ON(&dev_priv->drm, @@ -56,7 +56,7 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id) drm_WARN_ON(&dev_priv->drm, !IS_HASWELL_ULT(dev_priv) && !IS_BROADWELL_ULT(dev_priv)); /* WPT is LPT compatible */ - return PCH_LPT; + return PCH_LPT_LP; case INTEL_PCH_SPT_DEVICE_ID_TYPE: drm_dbg_kms(&dev_priv->drm, "Found SunrisePoint PCH\n"); drm_WARN_ON(&dev_priv->drm, diff --git a/drivers/gpu/drm/i915/soc/intel_pch.h b/drivers/gpu/drm/i915/soc/intel_pch.h index 89e89ede265db..bc926df14c456 100644 --- a/drivers/gpu/drm/i915/soc/intel_pch.h +++ b/drivers/gpu/drm/i915/soc/intel_pch.h @@ -19,7 +19,8 @@ enum intel_pch { PCH_NONE = 0, /* No PCH present */ PCH_IBX, /* Ibexpeak PCH */ PCH_CPT, /* Cougarpoint/Pantherpoint PCH */ - PCH_LPT, /* Lynxpoint/Wildcatpoint PCH */ + PCH_LPT_H, /* Lynxpoint/Wildcatpoint H PCH */ + PCH_LPT_LP, /* Lynxpoint/Wildcatpoint LP PCH */ PCH_SPT, /* Sunrisepoint/Kaby Lake PCH */ PCH_CNP, /* Cannon/Comet Lake PCH */ PCH_ICP, /* Ice Lake/Jasper Lake PCH */ @@ -72,13 +73,10 @@ enum intel_pch { #define HAS_PCH_ICP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_ICP) #define HAS_PCH_CNP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CNP) #define HAS_PCH_SPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_SPT) -#define HAS_PCH_LPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT) -#define HAS_PCH_LPT_LP(dev_priv) \ - (INTEL_PCH_ID(dev_priv) == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE || \ - INTEL_PCH_ID(dev_priv) == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE) -#define HAS_PCH_LPT_H(dev_priv) \ - (INTEL_PCH_ID(dev_priv) == INTEL_PCH_LPT_DEVICE_ID_TYPE || \ - INTEL_PCH_ID(dev_priv) == INTEL_PCH_WPT_DEVICE_ID_TYPE) +#define HAS_PCH_LPT_H(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT_H) +#define HAS_PCH_LPT_LP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT_LP) +#define HAS_PCH_LPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT_H || \ + INTEL_PCH_TYPE(dev_priv) == PCH_LPT_LP) #define HAS_PCH_CPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CPT) #define HAS_PCH_IBX(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_IBX) #define HAS_PCH_NOP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_NOP) From c2d55e709a867589d1d7669e964c3f7de2d62abb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 7 Feb 2025 12:17:37 +0200 Subject: [PATCH 201/284] drm/i915/pch: Hide PCH device IDs Only the PCH identification code needs the PCH device IDs, as all the PCH checks are now based on PCH type. Hide the PCH device IDs inside intel_pch.c. Remove the unused INTEL_PCH_ID() macro while at it. Reviewed-by: Nemesa Garg Link: https://patchwork.freedesktop.org/patch/msgid/d1ceb9fc461cf21e1b885a55293f593eba1458ea.1738923308.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/soc/intel_pch.c | 30 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/soc/intel_pch.h | 31 ---------------------------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/soc/intel_pch.c b/drivers/gpu/drm/i915/soc/intel_pch.c index 0370ccb6943c9..fa03b5068a193 100644 --- a/drivers/gpu/drm/i915/soc/intel_pch.c +++ b/drivers/gpu/drm/i915/soc/intel_pch.c @@ -7,6 +7,36 @@ #include "i915_utils.h" #include "intel_pch.h" +#define INTEL_PCH_DEVICE_ID_MASK 0xff80 +#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 +#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 +#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 +#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00 +#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 +#define INTEL_PCH_WPT_DEVICE_ID_TYPE 0x8c80 +#define INTEL_PCH_WPT_LP_DEVICE_ID_TYPE 0x9c80 +#define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 +#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 +#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA280 +#define INTEL_PCH_CNP_DEVICE_ID_TYPE 0xA300 +#define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80 +#define INTEL_PCH_CMP_DEVICE_ID_TYPE 0x0280 +#define INTEL_PCH_CMP2_DEVICE_ID_TYPE 0x0680 +#define INTEL_PCH_CMP_V_DEVICE_ID_TYPE 0xA380 +#define INTEL_PCH_ICP_DEVICE_ID_TYPE 0x3480 +#define INTEL_PCH_ICP2_DEVICE_ID_TYPE 0x3880 +#define INTEL_PCH_MCC_DEVICE_ID_TYPE 0x4B00 +#define INTEL_PCH_TGP_DEVICE_ID_TYPE 0xA080 +#define INTEL_PCH_TGP2_DEVICE_ID_TYPE 0x4380 +#define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80 +#define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80 +#define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180 +#define INTEL_PCH_ADP3_DEVICE_ID_TYPE 0x7A00 +#define INTEL_PCH_ADP4_DEVICE_ID_TYPE 0x5480 +#define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 +#define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000 +#define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */ + /* Map PCH device id to PCH type, or PCH_NONE if unknown. */ static enum intel_pch intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id) diff --git a/drivers/gpu/drm/i915/soc/intel_pch.h b/drivers/gpu/drm/i915/soc/intel_pch.h index bc926df14c456..635aea7a5539d 100644 --- a/drivers/gpu/drm/i915/soc/intel_pch.h +++ b/drivers/gpu/drm/i915/soc/intel_pch.h @@ -34,38 +34,7 @@ enum intel_pch { PCH_LNL, }; -#define INTEL_PCH_DEVICE_ID_MASK 0xff80 -#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 -#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 -#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 -#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00 -#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 -#define INTEL_PCH_WPT_DEVICE_ID_TYPE 0x8c80 -#define INTEL_PCH_WPT_LP_DEVICE_ID_TYPE 0x9c80 -#define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 -#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 -#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA280 -#define INTEL_PCH_CNP_DEVICE_ID_TYPE 0xA300 -#define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80 -#define INTEL_PCH_CMP_DEVICE_ID_TYPE 0x0280 -#define INTEL_PCH_CMP2_DEVICE_ID_TYPE 0x0680 -#define INTEL_PCH_CMP_V_DEVICE_ID_TYPE 0xA380 -#define INTEL_PCH_ICP_DEVICE_ID_TYPE 0x3480 -#define INTEL_PCH_ICP2_DEVICE_ID_TYPE 0x3880 -#define INTEL_PCH_MCC_DEVICE_ID_TYPE 0x4B00 -#define INTEL_PCH_TGP_DEVICE_ID_TYPE 0xA080 -#define INTEL_PCH_TGP2_DEVICE_ID_TYPE 0x4380 -#define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80 -#define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80 -#define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180 -#define INTEL_PCH_ADP3_DEVICE_ID_TYPE 0x7A00 -#define INTEL_PCH_ADP4_DEVICE_ID_TYPE 0x5480 -#define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 -#define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000 -#define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */ - #define INTEL_PCH_TYPE(dev_priv) ((dev_priv)->pch_type) -#define INTEL_PCH_ID(dev_priv) ((dev_priv)->pch_id) #define HAS_PCH_DG2(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_DG2) #define HAS_PCH_ADP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_ADP) #define HAS_PCH_DG1(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_DG1) From 46e2ffbdd2a0835ec3918606cd183b158c3f0e91 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 7 Feb 2025 12:17:38 +0200 Subject: [PATCH 202/284] drm/i915/pch: Remove unused i915->pch_id With the PCH checks based on PCH types instead of IDs, the i915->pch_id member has become unused. Remove it. Reviewed-by: Nemesa Garg Link: https://patchwork.freedesktop.org/patch/msgid/fac1c59800128e8f398e83d718a3a5dc235d0526.1738923308.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/soc/intel_pch.c | 4 ---- drivers/gpu/drm/xe/xe_device_types.h | 1 - 3 files changed, 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b96b8de12756e..ffc346379cc2c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -274,7 +274,6 @@ struct drm_i915_private { /* PCH chipset type */ enum intel_pch pch_type; - unsigned short pch_id; unsigned long gem_quirks; diff --git a/drivers/gpu/drm/i915/soc/intel_pch.c b/drivers/gpu/drm/i915/soc/intel_pch.c index fa03b5068a193..82dc7fbd1a3e9 100644 --- a/drivers/gpu/drm/i915/soc/intel_pch.c +++ b/drivers/gpu/drm/i915/soc/intel_pch.c @@ -286,13 +286,11 @@ void intel_detect_pch(struct drm_i915_private *dev_priv) pch_type = intel_pch_type(dev_priv, id); if (pch_type != PCH_NONE) { dev_priv->pch_type = pch_type; - dev_priv->pch_id = id; break; } else if (intel_is_virt_pch(id, pch->subsystem_vendor, pch->subsystem_device)) { intel_virt_detect_pch(dev_priv, &id, &pch_type); dev_priv->pch_type = pch_type; - dev_priv->pch_id = id; break; } } @@ -305,12 +303,10 @@ void intel_detect_pch(struct drm_i915_private *dev_priv) drm_dbg_kms(&dev_priv->drm, "Display disabled, reverting to NOP PCH\n"); dev_priv->pch_type = PCH_NOP; - dev_priv->pch_id = 0; } else if (!pch) { if (i915_run_as_guest() && HAS_DISPLAY(dev_priv)) { intel_virt_detect_pch(dev_priv, &id, &pch_type); dev_priv->pch_type = pch_type; - dev_priv->pch_id = id; } else { drm_dbg_kms(&dev_priv->drm, "No PCH found.\n"); } diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 8a7b159724135..17509d3c72d41 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -544,7 +544,6 @@ struct xe_device { */ struct intel_display display; enum intel_pch pch_type; - u16 pch_id; struct dram_info { bool wm_lv_0_adjust_needed; From 26b3a8b25e68da478965f3054e4e213a48519fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 8 Feb 2025 00:31:52 +0200 Subject: [PATCH 203/284] drm/i915/dsb: Move the +1 usec adjustment into dsb_wait_usec() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "wait usec" DSB command doesn't quite seem to able to guarantee that it always waits at least the specified amount of usecs. Some of that could be just because it supposedly just does some kind of dumb timestamp comparison internally. But I also see cases where two hardware timestamps sampled on each side of the "wait usec" command come out one less than expected. So it looks like we always need at least a +1 to guarantee that we never wait less than specified. Always apply that adjustment in dsb_wait_usec(). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250207223159.14132-2-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dsb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 2f2812c239725..f8bd6fad0c871 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -369,7 +369,8 @@ void intel_dsb_interrupt(struct intel_dsb *dsb) void intel_dsb_wait_usec(struct intel_dsb *dsb, int count) { - intel_dsb_emit(dsb, count, + /* +1 to make sure we never wait less time than asked for */ + intel_dsb_emit(dsb, count + 1, DSB_OPCODE_WAIT_USEC << DSB_OPCODE_SHIFT); } @@ -622,7 +623,7 @@ void intel_dsb_wait_vblank_delay(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state = intel_pre_commit_crtc_state(state, crtc); int usecs = intel_scanlines_to_usecs(&crtc_state->hw.adjusted_mode, - dsb_vblank_delay(state, crtc)) + 1; + dsb_vblank_delay(state, crtc)); intel_dsb_wait_usec(dsb, usecs); } From b47e345db9b1d9ea6657ad218ea31ed0bdcbd342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 8 Feb 2025 00:31:53 +0200 Subject: [PATCH 204/284] drm/i915/vrr: Don't send push for legacy cursor updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't really want legacy cursor updates to trigger VRR pushes because these can happen willy nilly and we generally want more precise control over the pushes. The fastpath in intel_legacy_cursor_update() doesn't send pushes, but if we punt to the full commit path (with the flip completion short circuited) we are currently sending pushes. Skip those as well so that they don't interfere with the push handling from normal commits. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250207223159.14132-3-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_crtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 89785da936039..a1694e54a6f1f 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -717,7 +717,8 @@ void intel_pipe_update_end(struct intel_atomic_state *state, * which would cause the next frame to terminate already at vmin * vblank start instead of vmax vblank start. */ - intel_vrr_send_push(NULL, new_crtc_state); + if (!state->base.legacy_cursor_update) + intel_vrr_send_push(NULL, new_crtc_state); local_irq_enable(); From 51385d68990cca5263ab9575edd5386f6e42a994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 8 Feb 2025 00:31:54 +0200 Subject: [PATCH 205/284] drm/i915/vrr: Account for TRANS_PUSH delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we send a push during vblank the TRANS_PUSH write happens at some point during a scanline, and the hardware picks it up on the next scanline. Thus there is up to one extra scanline of delay between the TRANS_PUSH write and the delayed vblank triggering. Account for that during intel_dsb_wait_vblank_delay() so that we are guaranteed to be past the delayed vblank before we trigger the completion interrupt for the commit. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250207223159.14132-4-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dsb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index f8bd6fad0c871..01e3bd385cacc 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -116,7 +116,13 @@ static int dsb_vblank_delay(struct intel_atomic_state *state, intel_pre_commit_crtc_state(state, crtc); if (pre_commit_is_vrr_active(state, crtc)) - return intel_vrr_vblank_delay(crtc_state); + /* + * When the push is sent during vblank it will trigger + * on the next scanline, hence we have up to one extra + * scanline until the delayed vblank occurs after + * TRANS_PUSH has been written. + */ + return intel_vrr_vblank_delay(crtc_state) + 1; else return intel_mode_vblank_delay(&crtc_state->hw.adjusted_mode); } From c9178dfba53ffd055c35f0daea9c35de89b45219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 8 Feb 2025 00:31:55 +0200 Subject: [PATCH 206/284] drm/i915/dsb: Compute use_dsb earlier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Skip all the commit completion interrupt stuff on the chained DSB when we don't take the full DSB path (ie. when the plane/pipe programming is done via MMIO). The commit completion will be done via the CPU side vblank interrupt. Currently this is just a redundant interrupt, so not a big deal. But in the future we'll be moving the TRANS_PUSH write into the chained DSB as well, and that we definitely don't want to do when it's also being done by the CPU from intel_pipe_update_end(). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250207223159.14132-5-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_color.c | 6 ++++-- drivers/gpu/drm/i915/display/intel_display.c | 15 +++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 8400a97f7e434..792cf7cef58a7 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1987,8 +1987,10 @@ void intel_color_prepare_commit(struct intel_atomic_state *state, display->funcs.color->load_luts(crtc_state); - intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank); - intel_dsb_interrupt(crtc_state->dsb_color_vblank); + if (crtc_state->use_dsb) { + intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank); + intel_dsb_interrupt(crtc_state->dsb_color_vblank); + } intel_dsb_finish(crtc_state->dsb_color_vblank); } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9557fa4bb89e1..7bb33b845e8cc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7687,12 +7687,6 @@ static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *s static void intel_atomic_dsb_prepare(struct intel_atomic_state *state, struct intel_crtc *crtc) -{ - intel_color_prepare_commit(state, crtc); -} - -static void intel_atomic_dsb_finish(struct intel_atomic_state *state, - struct intel_crtc *crtc) { const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); @@ -7715,6 +7709,15 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, !intel_crtc_needs_modeset(new_crtc_state) && !intel_crtc_needs_fastset(new_crtc_state); + intel_color_prepare_commit(state, crtc); +} + +static void intel_atomic_dsb_finish(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + if (!new_crtc_state->use_dsb && !new_crtc_state->dsb_color_vblank) return; From cdef53897cda82bc3261bf23acb0e8205ec8b19a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 8 Feb 2025 00:31:56 +0200 Subject: [PATCH 207/284] drm/i915/dsb: Introduce intel_dsb_poll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a function for emitting a DSB poll instruction. We'll allow the caller to specify the poll parameters. v2: s/wait/wait_us/ (Ankit) Reviewed-by: Ankit Nautiyal Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250207223159.14132-6-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_dsb.c | 19 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dsb.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 01e3bd385cacc..aba57ddfbb922 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -459,6 +459,25 @@ void intel_dsb_wait_scanline_out(struct intel_atomic_state *state, start, end); } +void intel_dsb_poll(struct intel_dsb *dsb, + i915_reg_t reg, u32 mask, u32 val, + int wait_us, int count) +{ + struct intel_crtc *crtc = dsb->crtc; + enum pipe pipe = crtc->pipe; + + intel_dsb_reg_write(dsb, DSB_POLLMASK(pipe, dsb->id), mask); + intel_dsb_reg_write(dsb, DSB_POLLFUNC(pipe, dsb->id), + DSB_POLL_ENABLE | + DSB_POLL_WAIT(wait_us) | DSB_POLL_COUNT(count)); + + intel_dsb_noop(dsb, 5); + + intel_dsb_emit(dsb, val, + (DSB_OPCODE_POLL << DSB_OPCODE_SHIFT) | + i915_mmio_reg_offset(reg)); +} + static void intel_dsb_align_tail(struct intel_dsb *dsb) { u32 aligned_tail, tail; diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h index da6df07a3c839..e843c52bf97c2 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.h +++ b/drivers/gpu/drm/i915/display/intel_dsb.h @@ -54,6 +54,9 @@ void intel_dsb_wait_scanline_out(struct intel_atomic_state *state, int lower, int upper); void intel_dsb_vblank_evade(struct intel_atomic_state *state, struct intel_dsb *dsb); +void intel_dsb_poll(struct intel_dsb *dsb, + i915_reg_t reg, u32 mask, u32 val, + int wait_us, int count); void intel_dsb_chain(struct intel_atomic_state *state, struct intel_dsb *dsb, struct intel_dsb *chained_dsb, From 44397dfe48c4fe8580e3fc27e260b4420d277191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 8 Feb 2025 00:31:57 +0200 Subject: [PATCH 208/284] drm/i915/vrr: Reorder the DSB "wait for safe window" vs. TRANS_PUSH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we trigger the push send first, then follow it with a "wait for safe window". That approach no longer works on PTL+ because triggering the push send immediately ends the safe window. On prior hardware the safe window extended past the push being sent (presumably all the way to the pipe's delayed vblank). In order to deal with the new hardware behaviour we must reverse the order of these two operations: first wait for safe window, then trigger the push. The only slight danger with this approach is that if we mess up the vblank evasion around the vmax decision boundary the push might get postponed until after the next frame's vactive. But assuming we don't mess up the vblank evasion this approach is completely safe. As a slight bonus we can perform the push after we've done the LUT writes as well, meaning we no longer have to worry about extending the vblank delay to provide enough time for LUT programming. Instead we will now depend on the vblank evasion at vmax decision boundary to guarantee this. However vblank delay (or framestart delay) is still the only way to provide extra time for the LUT programming in the non-VRR use cases. Let's assume we don't need anything extra for now, but eventually we should come up with some proper estimates on how long the LUT programming can take and configure the vblank delay accordingly for the non-VRR use cases. Reviewed-by: Ankit Nautiyal Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250207223159.14132-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_color.c | 2 ++ drivers/gpu/drm/i915/display/intel_display.c | 12 ++---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 792cf7cef58a7..4d8f6509cac4e 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -29,6 +29,7 @@ #include "intel_de.h" #include "intel_display_types.h" #include "intel_dsb.h" +#include "intel_vrr.h" struct intel_color_funcs { int (*color_check)(struct intel_atomic_state *state, @@ -1988,6 +1989,7 @@ void intel_color_prepare_commit(struct intel_atomic_state *state, display->funcs.color->load_luts(crtc_state); if (crtc_state->use_dsb) { + intel_vrr_send_push(crtc_state->dsb_color_vblank, crtc_state); intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank); intel_dsb_interrupt(crtc_state->dsb_color_vblank); } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 7bb33b845e8cc..9bb1bfe18aeef 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2633,14 +2633,6 @@ static int intel_crtc_vblank_delay(const struct intel_crtc_state *crtc_state) if (intel_crtc_needs_wa_14015401596(crtc_state)) vblank_delay = max(vblank_delay, 1); - /* - * Add a minimal vblank delay to make sure the push - * doesn't race with the "wait for safe window" used - * for frame completion with DSB. - */ - if (intel_vrr_possible(crtc_state)) - vblank_delay = max(vblank_delay, 1); - return vblank_delay; } @@ -7751,10 +7743,10 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, intel_crtc_planes_update_arm(new_crtc_state->dsb_commit, state, crtc); - intel_vrr_send_push(new_crtc_state->dsb_commit, new_crtc_state); - if (!new_crtc_state->dsb_color_vblank) { intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, 1); + + intel_vrr_send_push(new_crtc_state->dsb_commit, new_crtc_state); intel_dsb_wait_vblank_delay(state, new_crtc_state->dsb_commit); intel_dsb_interrupt(new_crtc_state->dsb_commit); } From c3571a239e108fe92adedd49ca3905d435093157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 10 Feb 2025 18:07:11 +0200 Subject: [PATCH 209/284] drm/i915/vrr: Check that the push send bit is clear after delayed vblank MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we don't do mailbox updates the push send bit should alwyas clear by the time the delay vblank fires and the flip completes. Check for that to make sure we haven't screwed up the sequencing/vblank evasion/etc. On the DSB path we should be able to guarantee this since we don't have to deal with any scheduler latencies and whatnot. I suppose unexpected DMA/memory latencies might be the only thing that might trip us up here. For the MMIO path we do always have a non-zero chance that vblank evasion fails (since we can't really guarantee anything about the scheduling behaviour). That could trip up this check, but that seems fine since we already print errors for other types of vblank evasion failures. Should the CPU vblank evasion actually fail, then the push send bit can still be set when the next commit happens. But both the DSB and MMIO paths should handle that situation gracefully. v2: Only check once instead of polling for two scanlines since we should now be guaranteed to be past the delayed vblank. Also check in the MMIO path for good measure v3: Skip the push send check when VRR is disabled. With joiner the secondary pipe's DSBs doen't have access to the transcoder registers, and so doing this check there triggers a reponse timeout error on the DSB. VRR is not currently allowed when using joiner, so this will prevent the bogus register access. Reviewed-by: Ankit Nautiyal Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250210160711.24010-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_color.c | 1 + drivers/gpu/drm/i915/display/intel_display.c | 4 +++ drivers/gpu/drm/i915/display/intel_vrr.c | 34 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_vrr.h | 2 ++ 4 files changed, 41 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 4d8f6509cac4e..cfe14162231db 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1991,6 +1991,7 @@ void intel_color_prepare_commit(struct intel_atomic_state *state, if (crtc_state->use_dsb) { intel_vrr_send_push(crtc_state->dsb_color_vblank, crtc_state); intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank); + intel_vrr_check_push_sent(crtc_state->dsb_color_vblank, crtc_state); intel_dsb_interrupt(crtc_state->dsb_color_vblank); } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9bb1bfe18aeef..50c91a6142fd4 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7748,6 +7748,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, intel_vrr_send_push(new_crtc_state->dsb_commit, new_crtc_state); intel_dsb_wait_vblank_delay(state, new_crtc_state->dsb_commit); + intel_vrr_check_push_sent(new_crtc_state->dsb_commit, new_crtc_state); intel_dsb_interrupt(new_crtc_state->dsb_commit); } } @@ -7898,6 +7899,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_crtc_disable_flip_done(state, crtc); intel_atomic_dsb_wait_commit(new_crtc_state); + + if (!state->base.legacy_cursor_update && !new_crtc_state->use_dsb) + intel_vrr_check_push_sent(NULL, new_crtc_state); } /* diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index adb51609d0a31..cac49319026da 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -416,6 +416,40 @@ void intel_vrr_send_push(struct intel_dsb *dsb, intel_dsb_nonpost_end(dsb); } +void intel_vrr_check_push_sent(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + + if (!crtc_state->vrr.enable) + return; + + /* + * Make sure the push send bit has cleared. This should + * already be the case as long as the caller makes sure + * this is called after the delayed vblank has occurred. + */ + if (dsb) { + int wait_us, count; + + wait_us = 2; + count = 1; + + /* + * If the bit hasn't cleared the DSB will + * raise the poll error interrupt. + */ + intel_dsb_poll(dsb, TRANS_PUSH(display, cpu_transcoder), + TRANS_PUSH_SEND, 0, wait_us, count); + } else { + if (intel_vrr_is_push_sent(crtc_state)) + drm_err(display->drm, "[CRTC:%d:%s] VRR push send still pending\n", + crtc->base.base.id, crtc->base.name); + } +} + bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index 899cbf40f880c..514822577e8a1 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -25,6 +25,8 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state) void intel_vrr_enable(const struct intel_crtc_state *crtc_state); void intel_vrr_send_push(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state); +void intel_vrr_check_push_sent(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state); bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state); void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state); void intel_vrr_get_config(struct intel_crtc_state *crtc_state); From f9f34d44c7d3cecd3e821d8a22d3fd88c972d0bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 8 Feb 2025 00:31:59 +0200 Subject: [PATCH 210/284] drm/i915/dsb: Decode DSB error interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Decode the DSB error interrupts into human readable form for easier debugging. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250207223159.14132-9-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dsb.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index aba57ddfbb922..db69b1c676f7a 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -860,7 +860,16 @@ void intel_dsb_irq_handler(struct intel_display *display, } errors = tmp & dsb_error_int_status(display); - if (errors) - drm_err(display->drm, "[CRTC:%d:%s] DSB %d error interrupt: 0x%x\n", - crtc->base.base.id, crtc->base.name, dsb_id, errors); + if (errors & DSB_ATS_FAULT_INT_STATUS) + drm_err(display->drm, "[CRTC:%d:%s] DSB %d ATS fault\n", + crtc->base.base.id, crtc->base.name, dsb_id); + if (errors & DSB_GTT_FAULT_INT_STATUS) + drm_err(display->drm, "[CRTC:%d:%s] DSB %d GTT fault\n", + crtc->base.base.id, crtc->base.name, dsb_id); + if (errors & DSB_RSPTIMEOUT_INT_STATUS) + drm_err(display->drm, "[CRTC:%d:%s] DSB %d response timeout\n", + crtc->base.base.id, crtc->base.name, dsb_id); + if (errors & DSB_POLL_ERR_INT_STATUS) + drm_err(display->drm, "[CRTC:%d:%s] DSB %d poll error\n", + crtc->base.base.id, crtc->base.name, dsb_id); } From 21da2507f3d5c50e7684ce9f28b7568c415ab8e2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:30 +0200 Subject: [PATCH 211/284] drm/i915/dp: convert g4x_dp.[ch] to struct intel display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of g4x_dp.[ch] to struct intel_display. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/89ce4f7e6aa31f3db6316537f54c5bc7df852322.1739378095.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/g4x_dp.c | 80 +++++++++---------- drivers/gpu/drm/i915/display/g4x_dp.h | 14 ++-- drivers/gpu/drm/i915/display/intel_display.c | 20 ++--- .../gpu/drm/i915/display/intel_pch_display.c | 2 +- drivers/gpu/drm/i915/display/intel_pps.c | 11 ++- 5 files changed, 61 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index d3b5ead188ba7..cfc796607a78e 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -51,28 +51,29 @@ static const struct dpll chv_dpll[] = { { .dot = 270000, .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 /* 27.0 */ }, }; -const struct dpll *vlv_get_dpll(struct drm_i915_private *i915) +const struct dpll *vlv_get_dpll(struct intel_display *display) { - return IS_CHERRYVIEW(i915) ? &chv_dpll[0] : &vlv_dpll[0]; + return display->platform.cherryview ? &chv_dpll[0] : &vlv_dpll[0]; } static void g4x_dp_set_clock(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); const struct dpll *divisor = NULL; int i, count = 0; - if (IS_G4X(dev_priv)) { + if (display->platform.g4x) { divisor = g4x_dpll; count = ARRAY_SIZE(g4x_dpll); } else if (HAS_PCH_SPLIT(dev_priv)) { divisor = pch_dpll; count = ARRAY_SIZE(pch_dpll); - } else if (IS_CHERRYVIEW(dev_priv)) { + } else if (display->platform.cherryview) { divisor = chv_dpll; count = ARRAY_SIZE(chv_dpll); - } else if (IS_VALLEYVIEW(dev_priv)) { + } else if (display->platform.valleyview) { divisor = vlv_dpll; count = ARRAY_SIZE(vlv_dpll); } @@ -129,7 +130,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder, /* Split out the IBX/CPU vs CPT settings */ - if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) { + if (display->platform.ivybridge && port == PORT_A) { if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) intel_dp->DP |= DP_SYNC_HS_HIGH; if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) @@ -148,7 +149,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder, pipe_config->enhanced_framing ? TRANS_DP_ENH_FRAMING : 0); } else { - if (IS_G4X(dev_priv) && pipe_config->limited_color_range) + if (display->platform.g4x && pipe_config->limited_color_range) intel_dp->DP |= DP_COLOR_RANGE_16_235; if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) @@ -160,7 +161,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder, if (pipe_config->enhanced_framing) intel_dp->DP |= DP_ENHANCED_FRAMING; - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) intel_dp->DP |= DP_PIPE_SEL_CHV(crtc->pipe); else intel_dp->DP |= DP_PIPE_SEL(crtc->pipe); @@ -180,9 +181,8 @@ static void assert_dp_port(struct intel_dp *intel_dp, bool state) } #define assert_dp_port_disabled(d) assert_dp_port((d), false) -static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state) +static void assert_edp_pll(struct intel_display *display, bool state) { - struct intel_display *display = &dev_priv->display; bool cur_state = intel_de_read(display, DP_A) & DP_PLL_ENABLE; INTEL_DISPLAY_STATE_WARN(display, cur_state != state, @@ -201,7 +201,7 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp, assert_transcoder_disabled(dev_priv, pipe_config->cpu_transcoder); assert_dp_port_disabled(intel_dp); - assert_edp_pll_disabled(dev_priv); + assert_edp_pll_disabled(display); drm_dbg_kms(display->drm, "enabling eDP PLL for clock %d\n", pipe_config->port_clock); @@ -223,7 +223,7 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp, * 1. Wait for the start of vertical blank on the enabled pipe going to FDI * 2. Program DP PLL enable */ - if (IS_IRONLAKE(dev_priv)) + if (display->platform.ironlake) intel_wait_for_vblank_if_active(display, !crtc->pipe); intel_dp->DP |= DP_PLL_ENABLE; @@ -242,7 +242,7 @@ static void ilk_edp_pll_off(struct intel_dp *intel_dp, assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder); assert_dp_port_disabled(intel_dp); - assert_edp_pll_enabled(dev_priv); + assert_edp_pll_enabled(display); drm_dbg_kms(display->drm, "disabling eDP PLL\n"); @@ -253,10 +253,9 @@ static void ilk_edp_pll_off(struct intel_dp *intel_dp, udelay(200); } -static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv, +static bool cpt_dp_port_selected(struct intel_display *display, enum port port, enum pipe *pipe) { - struct intel_display *display = &dev_priv->display; enum pipe p; for_each_pipe(display, p) { @@ -277,11 +276,11 @@ static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv, return false; } -bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv, +bool g4x_dp_port_enabled(struct intel_display *display, i915_reg_t dp_reg, enum port port, enum pipe *pipe) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); bool ret; u32 val; @@ -290,11 +289,11 @@ bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv, ret = val & DP_PORT_EN; /* asserts want to know the pipe even if the port is disabled */ - if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) + if (display->platform.ivybridge && port == PORT_A) *pipe = (val & DP_PIPE_SEL_MASK_IVB) >> DP_PIPE_SEL_SHIFT_IVB; else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) - ret &= cpt_dp_port_selected(dev_priv, port, pipe); - else if (IS_CHERRYVIEW(dev_priv)) + ret &= cpt_dp_port_selected(display, port, pipe); + else if (display->platform.cherryview) *pipe = (val & DP_PIPE_SEL_MASK_CHV) >> DP_PIPE_SEL_SHIFT_CHV; else *pipe = (val & DP_PIPE_SEL_MASK) >> DP_PIPE_SEL_SHIFT; @@ -306,7 +305,6 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); intel_wakeref_t wakeref; bool ret; @@ -316,7 +314,7 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, if (!wakeref) return false; - ret = g4x_dp_port_enabled(dev_priv, intel_dp->output_reg, + ret = g4x_dp_port_enabled(display, intel_dp->output_reg, encoder->port, pipe); intel_display_power_put(display, encoder->power_domain, wakeref); @@ -391,7 +389,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder, pipe_config->hw.adjusted_mode.flags |= flags; - if (IS_G4X(dev_priv) && tmp & DP_COLOR_RANGE_16_235) + if (display->platform.g4x && tmp & DP_COLOR_RANGE_16_235) pipe_config->limited_color_range = true; pipe_config->lane_count = @@ -433,7 +431,7 @@ intel_dp_link_down(struct intel_encoder *encoder, drm_dbg_kms(display->drm, "\n"); - if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) || + if ((display->platform.ivybridge && port == PORT_A) || (HAS_PCH_CPT(dev_priv) && port != PORT_A)) { intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT; intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE_CPT; @@ -479,7 +477,7 @@ intel_dp_link_down(struct intel_encoder *encoder, msleep(intel_dp->pps.panel_power_down_delay); - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (display->platform.valleyview || display->platform.cherryview) vlv_pps_port_disable(encoder, old_crtc_state); } @@ -682,7 +680,6 @@ static void intel_enable_dp(struct intel_atomic_state *state, const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); u32 dp_reg = intel_de_read(display, intel_dp->output_reg); intel_wakeref_t wakeref; @@ -691,7 +688,7 @@ static void intel_enable_dp(struct intel_atomic_state *state, return; with_intel_pps_lock(intel_dp, wakeref) { - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (display->platform.valleyview || display->platform.cherryview) vlv_pps_port_enable_unlocked(encoder, pipe_config); intel_dp_enable_port(intel_dp, pipe_config); @@ -701,10 +698,10 @@ static void intel_enable_dp(struct intel_atomic_state *state, intel_pps_vdd_off_unlocked(intel_dp, true); } - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (display->platform.valleyview || display->platform.cherryview) { unsigned int lane_mask = 0x0; - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) lane_mask = intel_dp_unused_lane_mask(pipe_config->lane_count); vlv_wait_port_ready(display, dp_to_dig_port(intel_dp), lane_mask); @@ -1264,7 +1261,6 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder) static void intel_dp_encoder_reset(struct drm_encoder *encoder) { struct intel_display *display = to_intel_display(encoder->dev); - struct drm_i915_private *dev_priv = to_i915(encoder->dev); struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder)); intel_dp->DP = intel_de_read(display, intel_dp->output_reg); @@ -1272,7 +1268,7 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder) intel_dp->reset_link_params = true; intel_dp_invalidate_source_oui(intel_dp); - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (display->platform.valleyview || display->platform.cherryview) vlv_pps_pipe_reset(intel_dp); intel_pps_encoder_reset(intel_dp); @@ -1283,10 +1279,10 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = { .destroy = intel_dp_encoder_destroy, }; -bool g4x_dp_init(struct drm_i915_private *dev_priv, +bool g4x_dp_init(struct intel_display *display, i915_reg_t output_reg, enum port port) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); const struct intel_bios_encoder_data *devdata; struct intel_digital_port *dig_port; struct intel_encoder *intel_encoder; @@ -1337,14 +1333,14 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv, intel_encoder->suspend = intel_dp_encoder_suspend; intel_encoder->suspend_complete = g4x_dp_suspend_complete; intel_encoder->shutdown = intel_dp_encoder_shutdown; - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable; intel_encoder->pre_enable = chv_pre_enable_dp; intel_encoder->enable = vlv_enable_dp; intel_encoder->disable = vlv_disable_dp; intel_encoder->post_disable = chv_post_disable_dp; intel_encoder->post_pll_disable = chv_dp_post_pll_disable; - } else if (IS_VALLEYVIEW(dev_priv)) { + } else if (display->platform.valleyview) { intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable; intel_encoder->pre_enable = vlv_pre_enable_dp; intel_encoder->enable = vlv_enable_dp; @@ -1359,24 +1355,24 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv, intel_encoder->audio_enable = g4x_dp_audio_enable; intel_encoder->audio_disable = g4x_dp_audio_disable; - if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) || + if ((display->platform.ivybridge && port == PORT_A) || (HAS_PCH_CPT(dev_priv) && port != PORT_A)) dig_port->dp.set_link_train = cpt_set_link_train; else dig_port->dp.set_link_train = g4x_set_link_train; - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) intel_encoder->set_signal_levels = chv_set_signal_levels; - else if (IS_VALLEYVIEW(dev_priv)) + else if (display->platform.valleyview) intel_encoder->set_signal_levels = vlv_set_signal_levels; - else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) + else if (display->platform.ivybridge && port == PORT_A) intel_encoder->set_signal_levels = ivb_cpu_edp_set_signal_levels; - else if (IS_SANDYBRIDGE(dev_priv) && port == PORT_A) + else if (display->platform.sandybridge && port == PORT_A) intel_encoder->set_signal_levels = snb_cpu_edp_set_signal_levels; else intel_encoder->set_signal_levels = g4x_set_signal_levels; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) || + if (display->platform.valleyview || display->platform.cherryview || (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) { dig_port->dp.preemph_max = intel_dp_preemph_max_3; dig_port->dp.voltage_max = intel_dp_voltage_max_3; @@ -1390,7 +1386,7 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv, intel_encoder->type = INTEL_OUTPUT_DP; intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(display, port); - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { if (port == PORT_D) intel_encoder->pipe_mask = BIT(PIPE_C); else diff --git a/drivers/gpu/drm/i915/display/g4x_dp.h b/drivers/gpu/drm/i915/display/g4x_dp.h index 839a251dc0695..0b28951b8365d 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.h +++ b/drivers/gpu/drm/i915/display/g4x_dp.h @@ -12,30 +12,30 @@ enum pipe; enum port; -struct drm_i915_private; struct intel_crtc_state; +struct intel_display; struct intel_dp; struct intel_encoder; #ifdef I915 -const struct dpll *vlv_get_dpll(struct drm_i915_private *i915); -bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv, +const struct dpll *vlv_get_dpll(struct intel_display *display); +bool g4x_dp_port_enabled(struct intel_display *display, i915_reg_t dp_reg, enum port port, enum pipe *pipe); -bool g4x_dp_init(struct drm_i915_private *dev_priv, +bool g4x_dp_init(struct intel_display *display, i915_reg_t output_reg, enum port port); #else -static inline const struct dpll *vlv_get_dpll(struct drm_i915_private *i915) +static inline const struct dpll *vlv_get_dpll(struct intel_display *display) { return NULL; } -static inline bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv, +static inline bool g4x_dp_port_enabled(struct intel_display *display, i915_reg_t dp_reg, int port, enum pipe *pipe) { return false; } -static inline bool g4x_dp_init(struct drm_i915_private *dev_priv, +static inline bool g4x_dp_init(struct intel_display *display, i915_reg_t output_reg, int port) { return false; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 50c91a6142fd4..33b8671ebf9bb 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8228,7 +8228,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) dpd_is_edp = intel_dp_is_port_edp(display, PORT_D); if (ilk_has_edp_a(dev_priv)) - g4x_dp_init(dev_priv, DP_A, PORT_A); + g4x_dp_init(display, DP_A, PORT_A); if (intel_de_read(dev_priv, PCH_HDMIB) & SDVO_DETECTED) { /* PCH SDVOB multiplex with HDMIB */ @@ -8236,7 +8236,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) if (!found) g4x_hdmi_init(dev_priv, PCH_HDMIB, PORT_B); if (!found && (intel_de_read(dev_priv, PCH_DP_B) & DP_DETECTED)) - g4x_dp_init(dev_priv, PCH_DP_B, PORT_B); + g4x_dp_init(display, PCH_DP_B, PORT_B); } if (intel_de_read(dev_priv, PCH_HDMIC) & SDVO_DETECTED) @@ -8246,10 +8246,10 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) g4x_hdmi_init(dev_priv, PCH_HDMID, PORT_D); if (intel_de_read(dev_priv, PCH_DP_C) & DP_DETECTED) - g4x_dp_init(dev_priv, PCH_DP_C, PORT_C); + g4x_dp_init(display, PCH_DP_C, PORT_C); if (intel_de_read(dev_priv, PCH_DP_D) & DP_DETECTED) - g4x_dp_init(dev_priv, PCH_DP_D, PORT_D); + g4x_dp_init(display, PCH_DP_D, PORT_D); } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { bool has_edp, has_port; @@ -8274,14 +8274,14 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) has_edp = intel_dp_is_port_edp(display, PORT_B); has_port = intel_bios_is_port_present(display, PORT_B); if (intel_de_read(dev_priv, VLV_DP_B) & DP_DETECTED || has_port) - has_edp &= g4x_dp_init(dev_priv, VLV_DP_B, PORT_B); + has_edp &= g4x_dp_init(display, VLV_DP_B, PORT_B); if ((intel_de_read(dev_priv, VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp) g4x_hdmi_init(dev_priv, VLV_HDMIB, PORT_B); has_edp = intel_dp_is_port_edp(display, PORT_C); has_port = intel_bios_is_port_present(display, PORT_C); if (intel_de_read(dev_priv, VLV_DP_C) & DP_DETECTED || has_port) - has_edp &= g4x_dp_init(dev_priv, VLV_DP_C, PORT_C); + has_edp &= g4x_dp_init(display, VLV_DP_C, PORT_C); if ((intel_de_read(dev_priv, VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp) g4x_hdmi_init(dev_priv, VLV_HDMIC, PORT_C); @@ -8292,7 +8292,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) */ has_port = intel_bios_is_port_present(display, PORT_D); if (intel_de_read(dev_priv, CHV_DP_D) & DP_DETECTED || has_port) - g4x_dp_init(dev_priv, CHV_DP_D, PORT_D); + g4x_dp_init(display, CHV_DP_D, PORT_D); if (intel_de_read(dev_priv, CHV_HDMID) & SDVO_DETECTED || has_port) g4x_hdmi_init(dev_priv, CHV_HDMID, PORT_D); } @@ -8319,7 +8319,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) } if (!found && IS_G4X(dev_priv)) - g4x_dp_init(dev_priv, DP_B, PORT_B); + g4x_dp_init(display, DP_B, PORT_B); } /* Before G4X SDVOC doesn't have its own detect register */ @@ -8337,11 +8337,11 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) g4x_hdmi_init(dev_priv, GEN4_HDMIC, PORT_C); } if (IS_G4X(dev_priv)) - g4x_dp_init(dev_priv, DP_C, PORT_C); + g4x_dp_init(display, DP_C, PORT_C); } if (IS_G4X(dev_priv) && (intel_de_read(dev_priv, DP_D) & DP_DETECTED)) - g4x_dp_init(dev_priv, DP_D, PORT_D); + g4x_dp_init(display, DP_D, PORT_D); if (SUPPORTS_TV(dev_priv)) intel_tv_init(display); diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c index 75ff5592312fb..98a6b57ac956b 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_display.c +++ b/drivers/gpu/drm/i915/display/intel_pch_display.c @@ -45,7 +45,7 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, enum pipe port_pipe; bool state; - state = g4x_dp_port_enabled(dev_priv, dp_reg, port, &port_pipe); + state = g4x_dp_port_enabled(display, dp_reg, port, &port_pipe); INTEL_DISPLAY_STATE_WARN(display, state && port_pipe == pipe, "PCH DP %c enabled on transcoder %c, should be disabled\n", diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index ef6effaf82e06..617ce49931726 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -134,7 +134,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) release_cl_override = display->platform.cherryview && !chv_phy_powergate_ch(display, phy, ch, true); - if (vlv_force_pll_on(dev_priv, pipe, vlv_get_dpll(dev_priv))) { + if (vlv_force_pll_on(dev_priv, pipe, vlv_get_dpll(display))) { drm_err(display->drm, "Failed to force on PLL for pipe %c!\n", pipe_name(pipe)); @@ -1225,11 +1225,10 @@ static void vlv_steal_power_sequencer(struct intel_display *display, static enum pipe vlv_active_pipe(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; enum pipe pipe; - if (g4x_dp_port_enabled(dev_priv, intel_dp->output_reg, + if (g4x_dp_port_enabled(display, intel_dp->output_reg, encoder->port, &pipe)) return pipe; @@ -1859,13 +1858,13 @@ void assert_pps_unlocked(struct intel_display *display, enum pipe pipe) intel_lvds_port_enabled(dev_priv, PCH_LVDS, &panel_pipe); break; case PANEL_PORT_SELECT_DPA: - g4x_dp_port_enabled(dev_priv, DP_A, PORT_A, &panel_pipe); + g4x_dp_port_enabled(display, DP_A, PORT_A, &panel_pipe); break; case PANEL_PORT_SELECT_DPC: - g4x_dp_port_enabled(dev_priv, PCH_DP_C, PORT_C, &panel_pipe); + g4x_dp_port_enabled(display, PCH_DP_C, PORT_C, &panel_pipe); break; case PANEL_PORT_SELECT_DPD: - g4x_dp_port_enabled(dev_priv, PCH_DP_D, PORT_D, &panel_pipe); + g4x_dp_port_enabled(display, PCH_DP_D, PORT_D, &panel_pipe); break; default: MISSING_CASE(port_sel); From a36e33edb239b2759de37c81d0e63b93e54fa5cb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:31 +0200 Subject: [PATCH 212/284] drm/i915/hdmi: convert g4x_hdmi.[ch] to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of g4x_hdmi.[ch] to struct intel_display. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/4fbaaa4cdab8ec020e5b3fb2f615b3c244c9da2d.1739378095.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/g4x_hdmi.c | 139 +++++++++---------- drivers/gpu/drm/i915/display/g4x_hdmi.h | 6 +- drivers/gpu/drm/i915/display/intel_display.c | 16 +-- 3 files changed, 79 insertions(+), 82 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 9e1ca77673924..6670cf101b9ae 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -27,8 +27,8 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(encoder); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; @@ -54,13 +54,13 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder, if (HAS_PCH_CPT(dev_priv)) hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe); - else if (IS_CHERRYVIEW(dev_priv)) + else if (display->platform.cherryview) hdmi_val |= SDVO_PIPE_SEL_CHV(crtc->pipe); else hdmi_val |= SDVO_PIPE_SEL(crtc->pipe); - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, hdmi_val); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, hdmi_val); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); } static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, @@ -132,6 +132,7 @@ static int g4x_hdmi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(encoder->base.dev); @@ -142,7 +143,7 @@ static int g4x_hdmi_compute_config(struct intel_encoder *encoder, return -EINVAL; } - if (IS_G4X(i915)) + if (display->platform.g4x) crtc_state->has_hdmi_sink = g4x_compute_has_hdmi_sink(state, crtc); else crtc_state->has_hdmi_sink = @@ -154,15 +155,15 @@ static int g4x_hdmi_compute_config(struct intel_encoder *encoder, static void intel_hdmi_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { + struct intel_display *display = to_intel_display(encoder); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); u32 tmp, flags = 0; int dotclock; pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); - tmp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg); + tmp = intel_de_read(display, intel_hdmi->hdmi_reg); if (tmp & SDVO_HSYNC_ACTIVE_HIGH) flags |= DRM_MODE_FLAG_PHSYNC; @@ -222,33 +223,32 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, static void g4x_hdmi_enable_port(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) { - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(encoder); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); u32 temp; - temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg); + temp = intel_de_read(display, intel_hdmi->hdmi_reg); temp |= SDVO_ENABLE; - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); } static void g4x_hdmi_audio_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder); if (!crtc_state->has_audio) return; - drm_WARN_ON(&i915->drm, !crtc_state->has_hdmi_sink); + drm_WARN_ON(display->drm, !crtc_state->has_hdmi_sink); /* Enable audio presence detect */ - intel_de_rmw(i915, hdmi->hdmi_reg, 0, HDMI_AUDIO_ENABLE); + intel_de_rmw(display, hdmi->hdmi_reg, 0, HDMI_AUDIO_ENABLE); intel_audio_codec_enable(encoder, crtc_state, conn_state); } @@ -257,7 +257,7 @@ static void g4x_hdmi_audio_disable(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder); if (!old_crtc_state->has_audio) @@ -266,7 +266,7 @@ static void g4x_hdmi_audio_disable(struct intel_encoder *encoder, intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state); /* Disable audio presence detect */ - intel_de_rmw(i915, hdmi->hdmi_reg, HDMI_AUDIO_ENABLE, 0); + intel_de_rmw(display, hdmi->hdmi_reg, HDMI_AUDIO_ENABLE, 0); } static void g4x_enable_hdmi(struct intel_atomic_state *state, @@ -282,12 +282,11 @@ static void ibx_enable_hdmi(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(encoder); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); u32 temp; - temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg); + temp = intel_de_read(display, intel_hdmi->hdmi_reg); temp |= SDVO_ENABLE; @@ -295,10 +294,10 @@ static void ibx_enable_hdmi(struct intel_atomic_state *state, * HW workaround, need to write this twice for issue * that may result in first write getting masked. */ - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); /* * HW workaround, need to toggle enable bit off and on @@ -309,18 +308,18 @@ static void ibx_enable_hdmi(struct intel_atomic_state *state, */ if (pipe_config->pipe_bpp > 24 && pipe_config->pixel_multiplier > 1) { - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, + intel_de_write(display, intel_hdmi->hdmi_reg, temp & ~SDVO_ENABLE); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); /* * HW workaround, need to write this twice for issue * that may result in first write getting masked. */ - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); } } @@ -329,14 +328,13 @@ static void cpt_enable_hdmi(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); enum pipe pipe = crtc->pipe; u32 temp; - temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg); + temp = intel_de_read(display, intel_hdmi->hdmi_reg); temp |= SDVO_ENABLE; @@ -351,24 +349,24 @@ static void cpt_enable_hdmi(struct intel_atomic_state *state, */ if (pipe_config->pipe_bpp > 24) { - intel_de_rmw(dev_priv, TRANS_CHICKEN1(pipe), + intel_de_rmw(display, TRANS_CHICKEN1(pipe), 0, TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE); temp &= ~SDVO_COLOR_FORMAT_MASK; temp |= SDVO_COLOR_FORMAT_8bpc; } - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); if (pipe_config->pipe_bpp > 24) { temp &= ~SDVO_COLOR_FORMAT_MASK; temp |= HDMI_COLOR_FORMAT_12bpc; - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); - intel_de_rmw(dev_priv, TRANS_CHICKEN1(pipe), + intel_de_rmw(display, TRANS_CHICKEN1(pipe), TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE, 0); } } @@ -386,19 +384,18 @@ static void intel_disable_hdmi(struct intel_atomic_state *state, const struct drm_connector_state *old_conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); struct intel_digital_port *dig_port = hdmi_to_dig_port(intel_hdmi); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); u32 temp; - temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg); + temp = intel_de_read(display, intel_hdmi->hdmi_reg); temp &= ~SDVO_ENABLE; - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); /* * HW workaround for IBX, we need to move the port @@ -419,14 +416,14 @@ static void intel_disable_hdmi(struct intel_atomic_state *state, * HW workaround, need to write this twice for issue * that may result in first write getting masked. */ - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); temp &= ~SDVO_ENABLE; - intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); - intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); + intel_de_write(display, intel_hdmi->hdmi_reg, temp); + intel_de_posting_read(display, intel_hdmi->hdmi_reg); intel_wait_for_vblank_if_active(display, PIPE_A); intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); @@ -544,8 +541,8 @@ static void chv_hdmi_post_disable(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(encoder); + struct drm_i915_private *dev_priv = to_i915(display->drm); vlv_dpio_get(dev_priv); @@ -614,7 +611,7 @@ intel_hdmi_hotplug(struct intel_encoder *encoder, int g4x_hdmi_connector_atomic_check(struct drm_connector *connector, struct drm_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->dev); + struct intel_display *display = to_intel_display(connector->dev); struct drm_connector_list_iter conn_iter; struct drm_connector *conn; int ret; @@ -623,7 +620,7 @@ int g4x_hdmi_connector_atomic_check(struct drm_connector *connector, if (ret) return ret; - if (!IS_G4X(i915)) + if (!display->platform.g4x) return 0; if (!intel_connector_needs_modeset(to_intel_atomic_state(state), connector)) @@ -637,7 +634,7 @@ int g4x_hdmi_connector_atomic_check(struct drm_connector *connector, * * See also g4x_compute_has_hdmi_sink(). */ - drm_connector_list_iter_begin(&i915->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); drm_for_each_connector_iter(conn, &conn_iter) { struct drm_connector_state *conn_state; struct drm_crtc_state *crtc_state; @@ -646,7 +643,7 @@ int g4x_hdmi_connector_atomic_check(struct drm_connector *connector, if (!connector_is_hdmi(conn)) continue; - drm_dbg_kms(&i915->drm, "Adding [CONNECTOR:%d:%s]\n", + drm_dbg_kms(display->drm, "Adding [CONNECTOR:%d:%s]\n", conn->base.id, conn->name); conn_state = drm_atomic_get_connector_state(state, conn); @@ -671,24 +668,24 @@ int g4x_hdmi_connector_atomic_check(struct drm_connector *connector, return ret; } -static bool is_hdmi_port_valid(struct drm_i915_private *i915, enum port port) +static bool is_hdmi_port_valid(struct intel_display *display, enum port port) { - if (IS_G4X(i915) || IS_VALLEYVIEW(i915)) + if (display->platform.g4x || display->platform.valleyview) return port == PORT_B || port == PORT_C; else return port == PORT_B || port == PORT_C || port == PORT_D; } -static bool assert_hdmi_port_valid(struct drm_i915_private *i915, enum port port) +static bool assert_hdmi_port_valid(struct intel_display *display, enum port port) { - return !drm_WARN(&i915->drm, !is_hdmi_port_valid(i915, port), + return !drm_WARN(display->drm, !is_hdmi_port_valid(display, port), "Platform does not support HDMI %c\n", port_name(port)); } -bool g4x_hdmi_init(struct drm_i915_private *dev_priv, +bool g4x_hdmi_init(struct intel_display *display, i915_reg_t hdmi_reg, enum port port) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); const struct intel_bios_encoder_data *devdata; struct intel_digital_port *dig_port; struct intel_encoder *intel_encoder; @@ -697,14 +694,14 @@ bool g4x_hdmi_init(struct drm_i915_private *dev_priv, if (!assert_port_valid(dev_priv, port)) return false; - if (!assert_hdmi_port_valid(dev_priv, port)) + if (!assert_hdmi_port_valid(display, port)) return false; devdata = intel_bios_encoder_data_lookup(display, port); /* FIXME bail? */ if (!devdata) - drm_dbg_kms(&dev_priv->drm, "No VBT child device for HDMI-%c\n", + drm_dbg_kms(display->drm, "No VBT child device for HDMI-%c\n", port_name(port)); dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL); @@ -723,7 +720,7 @@ bool g4x_hdmi_init(struct drm_i915_private *dev_priv, mutex_init(&dig_port->hdcp_mutex); - if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base, + if (drm_encoder_init(display->drm, &intel_encoder->base, &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS, "HDMI %c", port_name(port))) goto err_encoder_init; @@ -738,13 +735,13 @@ bool g4x_hdmi_init(struct drm_i915_private *dev_priv, } intel_encoder->get_hw_state = intel_hdmi_get_hw_state; intel_encoder->get_config = intel_hdmi_get_config; - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable; intel_encoder->pre_enable = chv_hdmi_pre_enable; intel_encoder->enable = vlv_enable_hdmi; intel_encoder->post_disable = chv_hdmi_post_disable; intel_encoder->post_pll_disable = chv_hdmi_post_pll_disable; - } else if (IS_VALLEYVIEW(dev_priv)) { + } else if (display->platform.valleyview) { intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable; intel_encoder->pre_enable = vlv_hdmi_pre_enable; intel_encoder->enable = vlv_enable_hdmi; @@ -765,7 +762,7 @@ bool g4x_hdmi_init(struct drm_i915_private *dev_priv, intel_encoder->type = INTEL_OUTPUT_HDMI; intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(display, port); intel_encoder->port = port; - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { if (port == PORT_D) intel_encoder->pipe_mask = BIT(PIPE_C); else @@ -780,7 +777,7 @@ bool g4x_hdmi_init(struct drm_i915_private *dev_priv, * to work on real hardware. And since g4x can send infoframes to * only one port anyway, nothing is lost by allowing it. */ - if (IS_G4X(dev_priv)) + if (display->platform.g4x) intel_encoder->cloneable |= BIT(INTEL_OUTPUT_HDMI); dig_port->hdmi.hdmi_reg = hdmi_reg; diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.h b/drivers/gpu/drm/i915/display/g4x_hdmi.h index a52e8986ec7ab..039d2bdba06c1 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.h +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.h @@ -13,15 +13,15 @@ enum port; struct drm_atomic_state; struct drm_connector; -struct drm_i915_private; +struct intel_display; #ifdef I915 -bool g4x_hdmi_init(struct drm_i915_private *dev_priv, +bool g4x_hdmi_init(struct intel_display *display, i915_reg_t hdmi_reg, enum port port); int g4x_hdmi_connector_atomic_check(struct drm_connector *connector, struct drm_atomic_state *state); #else -static inline bool g4x_hdmi_init(struct drm_i915_private *dev_priv, +static inline bool g4x_hdmi_init(struct intel_display *display, i915_reg_t hdmi_reg, int port) { return false; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 33b8671ebf9bb..a1edc3bb2e4dd 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8234,16 +8234,16 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) /* PCH SDVOB multiplex with HDMIB */ found = intel_sdvo_init(dev_priv, PCH_SDVOB, PORT_B); if (!found) - g4x_hdmi_init(dev_priv, PCH_HDMIB, PORT_B); + g4x_hdmi_init(display, PCH_HDMIB, PORT_B); if (!found && (intel_de_read(dev_priv, PCH_DP_B) & DP_DETECTED)) g4x_dp_init(display, PCH_DP_B, PORT_B); } if (intel_de_read(dev_priv, PCH_HDMIC) & SDVO_DETECTED) - g4x_hdmi_init(dev_priv, PCH_HDMIC, PORT_C); + g4x_hdmi_init(display, PCH_HDMIC, PORT_C); if (!dpd_is_edp && intel_de_read(dev_priv, PCH_HDMID) & SDVO_DETECTED) - g4x_hdmi_init(dev_priv, PCH_HDMID, PORT_D); + g4x_hdmi_init(display, PCH_HDMID, PORT_D); if (intel_de_read(dev_priv, PCH_DP_C) & DP_DETECTED) g4x_dp_init(display, PCH_DP_C, PORT_C); @@ -8276,14 +8276,14 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) if (intel_de_read(dev_priv, VLV_DP_B) & DP_DETECTED || has_port) has_edp &= g4x_dp_init(display, VLV_DP_B, PORT_B); if ((intel_de_read(dev_priv, VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp) - g4x_hdmi_init(dev_priv, VLV_HDMIB, PORT_B); + g4x_hdmi_init(display, VLV_HDMIB, PORT_B); has_edp = intel_dp_is_port_edp(display, PORT_C); has_port = intel_bios_is_port_present(display, PORT_C); if (intel_de_read(dev_priv, VLV_DP_C) & DP_DETECTED || has_port) has_edp &= g4x_dp_init(display, VLV_DP_C, PORT_C); if ((intel_de_read(dev_priv, VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp) - g4x_hdmi_init(dev_priv, VLV_HDMIC, PORT_C); + g4x_hdmi_init(display, VLV_HDMIC, PORT_C); if (IS_CHERRYVIEW(dev_priv)) { /* @@ -8294,7 +8294,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) if (intel_de_read(dev_priv, CHV_DP_D) & DP_DETECTED || has_port) g4x_dp_init(display, CHV_DP_D, PORT_D); if (intel_de_read(dev_priv, CHV_HDMID) & SDVO_DETECTED || has_port) - g4x_hdmi_init(dev_priv, CHV_HDMID, PORT_D); + g4x_hdmi_init(display, CHV_HDMID, PORT_D); } vlv_dsi_init(dev_priv); @@ -8315,7 +8315,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) if (!found && IS_G4X(dev_priv)) { drm_dbg_kms(&dev_priv->drm, "probing HDMI on SDVOB\n"); - g4x_hdmi_init(dev_priv, GEN4_HDMIB, PORT_B); + g4x_hdmi_init(display, GEN4_HDMIB, PORT_B); } if (!found && IS_G4X(dev_priv)) @@ -8334,7 +8334,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) if (IS_G4X(dev_priv)) { drm_dbg_kms(&dev_priv->drm, "probing HDMI on SDVOC\n"); - g4x_hdmi_init(dev_priv, GEN4_HDMIC, PORT_C); + g4x_hdmi_init(display, GEN4_HDMIC, PORT_C); } if (IS_G4X(dev_priv)) g4x_dp_init(display, DP_C, PORT_C); From a19c560eeb0fe62633807b6ffd29eeeb56c4b44d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:32 +0200 Subject: [PATCH 213/284] drm/i915/ips: convert hsw_ips.c to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of hsw_ips.c to struct intel_display. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/ebea40784fca6cfb4dbacec570bc9bef49393fc1.1739378095.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/hsw_ips.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c index d02c328bf902a..674a0e5f08584 100644 --- a/drivers/gpu/drm/i915/display/hsw_ips.c +++ b/drivers/gpu/drm/i915/display/hsw_ips.c @@ -36,7 +36,7 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state) if (display->ips.false_color) val |= IPS_FALSE_COLOR; - if (IS_BROADWELL(i915)) { + if (display->platform.broadwell) { drm_WARN_ON(display->drm, snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL, val | IPS_PCODE_CONTROL)); @@ -71,7 +71,7 @@ bool hsw_ips_disable(const struct intel_crtc_state *crtc_state) if (!crtc_state->ips_enabled) return need_vblank_wait; - if (IS_BROADWELL(i915)) { + if (display->platform.broadwell) { drm_WARN_ON(display->drm, snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL, 0)); /* @@ -96,7 +96,7 @@ bool hsw_ips_disable(const struct intel_crtc_state *crtc_state) static bool hsw_ips_need_disable(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = @@ -114,7 +114,7 @@ static bool hsw_ips_need_disable(struct intel_atomic_state *state, * * Disable IPS before we program the LUT. */ - if (IS_HASWELL(i915) && + if (display->platform.haswell && intel_crtc_needs_color_update(new_crtc_state) && new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) return true; @@ -137,7 +137,7 @@ bool hsw_ips_pre_update(struct intel_atomic_state *state, static bool hsw_ips_need_enable(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = @@ -155,7 +155,7 @@ static bool hsw_ips_need_enable(struct intel_atomic_state *state, * * Re-enable IPS after the LUT has been programmed. */ - if (IS_HASWELL(i915) && + if (display->platform.haswell && intel_crtc_needs_color_update(new_crtc_state) && new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) return true; @@ -194,7 +194,6 @@ static bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); /* IPS only exists on ULT machines and is tied to pipe A. */ if (!hsw_crtc_supports_ips(crtc)) @@ -213,7 +212,7 @@ static bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state * * Should measure whether using a lower cdclk w/o IPS */ - if (IS_BROADWELL(i915) && + if (display->platform.broadwell && crtc_state->pixel_rate > display->cdclk.max_cdclk_freq * 95 / 100) return false; @@ -222,9 +221,9 @@ static bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state int hsw_ips_min_cdclk(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); - if (!IS_BROADWELL(i915)) + if (!display->platform.broadwell) return 0; if (!hsw_crtc_state_ips_capable(crtc_state)) @@ -237,7 +236,7 @@ int hsw_ips_min_cdclk(const struct intel_crtc_state *crtc_state) int hsw_ips_compute_config(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); @@ -259,7 +258,7 @@ int hsw_ips_compute_config(struct intel_atomic_state *state, if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR))) return 0; - if (IS_BROADWELL(i915)) { + if (display->platform.broadwell) { const struct intel_cdclk_state *cdclk_state; cdclk_state = intel_atomic_get_cdclk_state(state); @@ -280,12 +279,11 @@ void hsw_ips_get_config(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); if (!hsw_crtc_supports_ips(crtc)) return; - if (IS_HASWELL(i915)) { + if (display->platform.haswell) { crtc_state->ips_enabled = intel_de_read(display, IPS_CTL) & IPS_ENABLE; } else { /* From 6a5c7ea5f4bb1aa72b419ef34a842c55e8608698 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:33 +0200 Subject: [PATCH 214/284] drm/i915/display: convert assert_transcoder*() to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert the assert_transcoder*() helpers to struct intel_display, allowing further conversions elsewhere. Do a few small opportunistic conversions right away. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/430c2f3c899bc98beeb6ba8608f841c9271d0971.1739378095.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/g4x_dp.c | 7 ++-- drivers/gpu/drm/i915/display/intel_display.c | 34 +++++++++----------- drivers/gpu/drm/i915/display/intel_display.h | 2 +- drivers/gpu/drm/i915/display/intel_dpll.c | 30 +++++++++-------- drivers/gpu/drm/i915/display/intel_fdi.c | 3 +- drivers/gpu/drm/i915/display/intel_tv.c | 3 +- 6 files changed, 38 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index cfc796607a78e..f50ab9a3f3e95 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -197,9 +197,8 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - assert_transcoder_disabled(dev_priv, pipe_config->cpu_transcoder); + assert_transcoder_disabled(display, pipe_config->cpu_transcoder); assert_dp_port_disabled(intel_dp); assert_edp_pll_disabled(display); @@ -237,10 +236,8 @@ static void ilk_edp_pll_off(struct intel_dp *intel_dp, const struct intel_crtc_state *old_crtc_state) { struct intel_display *display = to_intel_display(intel_dp); - struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder); + assert_transcoder_disabled(display, old_crtc_state->cpu_transcoder); assert_dp_port_disabled(intel_dp); assert_edp_pll_enabled(display); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a1edc3bb2e4dd..8fc099709a88e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -419,23 +419,22 @@ intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state) } } -void assert_transcoder(struct drm_i915_private *dev_priv, +void assert_transcoder(struct intel_display *display, enum transcoder cpu_transcoder, bool state) { - struct intel_display *display = &dev_priv->display; bool cur_state; enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; /* we keep both pipes enabled on 830 */ - if (IS_I830(dev_priv)) + if (display->platform.i830) state = true; power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); wakeref = intel_display_power_get_if_enabled(display, power_domain); if (wakeref) { - u32 val = intel_de_read(dev_priv, - TRANSCONF(dev_priv, cpu_transcoder)); + u32 val = intel_de_read(display, + TRANSCONF(display, cpu_transcoder)); cur_state = !!(val & TRANSCONF_ENABLE); intel_display_power_put(display, power_domain, wakeref); @@ -1968,8 +1967,8 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); if (!crtc_state->gmch_pfit.control) return; @@ -1978,18 +1977,18 @@ static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) * The panel fitter should only be adjusted whilst the pipe is disabled, * according to register description and PRM. */ - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)) & PFIT_ENABLE); - assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); + drm_WARN_ON(display->drm, + intel_de_read(display, PFIT_CONTROL(display)) & PFIT_ENABLE); + assert_transcoder_disabled(display, crtc_state->cpu_transcoder); - intel_de_write(dev_priv, PFIT_PGM_RATIOS(dev_priv), + intel_de_write(display, PFIT_PGM_RATIOS(display), crtc_state->gmch_pfit.pgm_ratios); - intel_de_write(dev_priv, PFIT_CONTROL(dev_priv), + intel_de_write(display, PFIT_CONTROL(display), crtc_state->gmch_pfit.control); /* Border color in case we don't scale up to the full screen. Black by * default, change to something else for debugging. */ - intel_de_write(dev_priv, BCLRPAT(dev_priv, crtc->pipe), 0); + intel_de_write(display, BCLRPAT(display, crtc->pipe), 0); } /* Prefer intel_encoder_is_combo() */ @@ -2300,17 +2299,16 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(old_crtc_state); if (!old_crtc_state->gmch_pfit.control) return; - assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder); + assert_transcoder_disabled(display, old_crtc_state->cpu_transcoder); - drm_dbg_kms(&dev_priv->drm, "disabling pfit, current: 0x%08x\n", - intel_de_read(dev_priv, PFIT_CONTROL(dev_priv))); - intel_de_write(dev_priv, PFIT_CONTROL(dev_priv), 0); + drm_dbg_kms(display->drm, "disabling pfit, current: 0x%08x\n", + intel_de_read(display, PFIT_CONTROL(display))); + intel_de_write(display, PFIT_CONTROL(display), 0); } static void i9xx_crtc_disable(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index e594492bade71..503e2ea1d0298 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -574,7 +574,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, void intel_hpd_poll_fini(struct drm_i915_private *i915); /* modesetting asserts */ -void assert_transcoder(struct drm_i915_private *dev_priv, +void assert_transcoder(struct intel_display *display, enum transcoder cpu_transcoder, bool state); #define assert_transcoder_enabled(d, t) assert_transcoder(d, t, true) #define assert_transcoder_disabled(d, t) assert_transcoder(d, t, false) diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index cc19cd51ab4d9..08a30e5aafcee 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1843,7 +1843,7 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state) enum pipe pipe = crtc->pipe; int i; - assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_disabled(display, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ if (i9xx_has_pps(dev_priv)) @@ -2024,7 +2024,7 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state) const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; enum pipe pipe = crtc->pipe; - assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_disabled(display, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ assert_pps_unlocked(display, pipe); @@ -2171,7 +2171,7 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state) const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; enum pipe pipe = crtc->pipe; - assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_disabled(display, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ assert_pps_unlocked(display, pipe); @@ -2253,36 +2253,38 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) { + struct intel_display *display = &dev_priv->display; u32 val; /* Make sure the pipe isn't still relying on us */ - assert_transcoder_disabled(dev_priv, (enum transcoder)pipe); + assert_transcoder_disabled(display, (enum transcoder)pipe); val = DPLL_INTEGRATED_REF_CLK_VLV | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; if (pipe != PIPE_A) val |= DPLL_INTEGRATED_CRI_CLK_VLV; - intel_de_write(dev_priv, DPLL(dev_priv, pipe), val); - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_write(display, DPLL(display, pipe), val); + intel_de_posting_read(display, DPLL(display, pipe)); } void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) { + struct intel_display *display = &dev_priv->display; enum dpio_channel ch = vlv_pipe_to_channel(pipe); enum dpio_phy phy = vlv_pipe_to_phy(pipe); u32 val; /* Make sure the pipe isn't still relying on us */ - assert_transcoder_disabled(dev_priv, (enum transcoder)pipe); + assert_transcoder_disabled(display, (enum transcoder)pipe); val = DPLL_SSC_REF_CLK_CHV | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; if (pipe != PIPE_A) val |= DPLL_INTEGRATED_CRI_CLK_VLV; - intel_de_write(dev_priv, DPLL(dev_priv, pipe), val); - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_write(display, DPLL(display, pipe), val); + intel_de_posting_read(display, DPLL(display, pipe)); vlv_dpio_get(dev_priv); @@ -2296,19 +2298,19 @@ void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) void i9xx_disable_pll(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; /* Don't disable pipe or pipe PLLs if needed */ - if (IS_I830(dev_priv)) + if (display->platform.i830) return; /* Make sure the pipe isn't still relying on us */ - assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_disabled(display, crtc_state->cpu_transcoder); - intel_de_write(dev_priv, DPLL(dev_priv, pipe), DPLL_VGA_MODE_DIS); - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_write(display, DPLL(display, pipe), DPLL_VGA_MODE_DIS); + intel_de_posting_read(display, DPLL(display, pipe)); } diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 9ebe80bfaab66..024d0c7e0a887 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -511,6 +511,7 @@ void intel_fdi_normal_train(struct intel_crtc *crtc) static void ilk_fdi_link_train(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc); struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = crtc->pipe; @@ -525,7 +526,7 @@ static void ilk_fdi_link_train(struct intel_crtc *crtc, intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK); /* FDI needs bits from pipe first */ - assert_transcoder_enabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_enabled(display, crtc_state->cpu_transcoder); /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit for train result */ diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c index 6e311dcc1a61e..d71994472d058 100644 --- a/drivers/gpu/drm/i915/display/intel_tv.c +++ b/drivers/gpu/drm/i915/display/intel_tv.c @@ -1436,7 +1436,6 @@ static void intel_tv_pre_enable(struct intel_atomic_state *state, const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct intel_tv *intel_tv = enc_to_tv(encoder); const struct intel_tv_connector_state *tv_conn_state = @@ -1543,7 +1542,7 @@ static void intel_tv_pre_enable(struct intel_atomic_state *state, intel_de_write(display, TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); - assert_transcoder_disabled(dev_priv, pipe_config->cpu_transcoder); + assert_transcoder_disabled(display, pipe_config->cpu_transcoder); /* Filter ctl must be set before TV_WIN_SIZE */ tv_filter_ctl = TV_AUTO_SCALE; From a40249ee7e6229f1ed56c7983993635d9064054b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:34 +0200 Subject: [PATCH 215/284] drm/i915/display: convert assert_port_valid() to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert the assert_port_valid() helper to struct intel_display, allowing further conversions elsewhere. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/e06ef0e2cc34d42918f3208362587a17ea34e28f.1739378095.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- drivers/gpu/drm/i915/display/g4x_hdmi.c | 2 +- drivers/gpu/drm/i915/display/intel_crt.c | 2 +- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/display/intel_display.c | 4 ++-- drivers/gpu/drm/i915/display/intel_display.h | 2 +- drivers/gpu/drm/i915/display/intel_dvo.c | 2 +- drivers/gpu/drm/i915/display/intel_sdvo.c | 3 ++- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index f50ab9a3f3e95..b6cb5c74a32e5 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -1286,7 +1286,7 @@ bool g4x_dp_init(struct intel_display *display, struct drm_encoder *encoder; struct intel_connector *intel_connector; - if (!assert_port_valid(dev_priv, port)) + if (!assert_port_valid(display, port)) return false; devdata = intel_bios_encoder_data_lookup(display, port); diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 6670cf101b9ae..5b2df1014c10a 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -691,7 +691,7 @@ bool g4x_hdmi_init(struct intel_display *display, struct intel_encoder *intel_encoder; struct intel_connector *intel_connector; - if (!assert_port_valid(dev_priv, port)) + if (!assert_port_valid(display, port)) return false; if (!assert_hdmi_port_valid(display, port)) diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index fb1feda46b5b7..53b2aa0f3d20f 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -1099,7 +1099,7 @@ void intel_crt_init(struct intel_display *display) connector->base.polled = connector->polled; if (HAS_DDI(display)) { - assert_port_valid(dev_priv, PORT_E); + assert_port_valid(display, PORT_E); crt->base.port = PORT_E; crt->base.get_config = hsw_crt_get_config; diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index ee1fb01c97955..db3f27468e8b0 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -5128,7 +5128,7 @@ void intel_ddi_init(struct intel_display *display, return; } - if (!assert_port_valid(dev_priv, port)) + if (!assert_port_valid(display, port)) return; if (port_in_use(dev_priv, port)) { diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 8fc099709a88e..d00b004567e83 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8187,9 +8187,9 @@ static bool intel_ddi_crt_present(struct drm_i915_private *dev_priv) return true; } -bool assert_port_valid(struct drm_i915_private *i915, enum port port) +bool assert_port_valid(struct intel_display *display, enum port port) { - return !drm_WARN(&i915->drm, !(DISPLAY_RUNTIME_INFO(i915)->port_mask & BIT(port)), + return !drm_WARN(display->drm, !(DISPLAY_RUNTIME_INFO(display)->port_mask & BIT(port)), "Platform does not support port %c\n", port_name(port)); } diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 503e2ea1d0298..9439da737f5bc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -579,7 +579,7 @@ void assert_transcoder(struct intel_display *display, #define assert_transcoder_enabled(d, t) assert_transcoder(d, t, true) #define assert_transcoder_disabled(d, t) assert_transcoder(d, t, false) -bool assert_port_valid(struct drm_i915_private *i915, enum port port); +bool assert_port_valid(struct intel_display *display, enum port port); /* * Use INTEL_DISPLAY_STATE_WARN(x) (rather than WARN() and WARN_ON()) for hw diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c index abf19dfd6d9d0..c4888e6f52a18 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo.c +++ b/drivers/gpu/drm/i915/display/intel_dvo.c @@ -524,7 +524,7 @@ void intel_dvo_init(struct drm_i915_private *i915) return; } - assert_port_valid(i915, intel_dvo->dev.port); + assert_port_valid(display, intel_dvo->dev.port); encoder->type = INTEL_OUTPUT_DVO; encoder->power_domain = POWER_DOMAIN_PORT_OTHER; diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index 44452ed69fff4..f7067696dec96 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -3386,11 +3386,12 @@ static bool assert_sdvo_port_valid(struct drm_i915_private *dev_priv, bool intel_sdvo_init(struct drm_i915_private *dev_priv, i915_reg_t sdvo_reg, enum port port) { + struct intel_display *display = &dev_priv->display; struct intel_encoder *intel_encoder; struct intel_sdvo *intel_sdvo; int i; - if (!assert_port_valid(dev_priv, port)) + if (!assert_port_valid(display, port)) return false; if (!assert_sdvo_port_valid(dev_priv, port)) From b97b429192191d73eeadea617df9b6db6422d05e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:35 +0200 Subject: [PATCH 216/284] drm/i915/hpd: drop dev_priv parameter from intel_hpd_pin_default() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function doesn't use the parameter for anything. Drop it. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/4347a0f71a1a8c515617cf06471486d9bbb4a026.1739378095.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- drivers/gpu/drm/i915/display/g4x_hdmi.c | 2 +- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/display/intel_hotplug.c | 4 +--- drivers/gpu/drm/i915/display/intel_hotplug.h | 3 +-- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index b6cb5c74a32e5..4b51a4e47f639 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -1393,7 +1393,7 @@ bool g4x_dp_init(struct intel_display *display, } intel_encoder->cloneable = 0; intel_encoder->port = port; - intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port); + intel_encoder->hpd_pin = intel_hpd_pin_default(port); dig_port->hpd_pulse = intel_dp_hpd_pulse; diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 5b2df1014c10a..1cd2e68e6ec56 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -771,7 +771,7 @@ bool g4x_hdmi_init(struct intel_display *display, intel_encoder->pipe_mask = ~0; } intel_encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG); - intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port); + intel_encoder->hpd_pin = intel_hpd_pin_default(port); /* * BSpec is unclear about HDMI+HDMI cloning on g4x, but it seems * to work on real hardware. And since g4x can send infoframes to diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index db3f27468e8b0..ea0d8db2cc71b 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -5364,7 +5364,7 @@ void intel_ddi_init(struct intel_display *display, else if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) encoder->hpd_pin = skl_hpd_pin(dev_priv, port); else - encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port); + encoder->hpd_pin = intel_hpd_pin_default(port); ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port)); diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index d2e0002c5dc38..9c935afc60aaf 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -82,15 +82,13 @@ /** * intel_hpd_pin_default - return default pin associated with certain port. - * @dev_priv: private driver data pointer * @port: the hpd port to get associated pin * * It is only valid and used by digital port encoder. * * Return pin that is associatade with @port. */ -enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv, - enum port port) +enum hpd_pin intel_hpd_pin_default(enum port port) { return HPD_PORT_A + port - PORT_A; } diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.h b/drivers/gpu/drm/i915/display/intel_hotplug.h index a17253ddec83a..d2ca9d2f1d393 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.h +++ b/drivers/gpu/drm/i915/display/intel_hotplug.h @@ -24,8 +24,7 @@ void intel_hpd_trigger_irq(struct intel_digital_port *dig_port); void intel_hpd_init(struct drm_i915_private *dev_priv); void intel_hpd_init_early(struct drm_i915_private *i915); void intel_hpd_cancel_work(struct drm_i915_private *dev_priv); -enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv, - enum port port); +enum hpd_pin intel_hpd_pin_default(enum port port); bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin); void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin); void intel_hpd_debugfs_register(struct drm_i915_private *i915); From 53ba0e1d6618366171091b1c1a316e753029757f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:36 +0200 Subject: [PATCH 217/284] drm/i915/display: convert intel_set_{cpu,pch}_fifo_underrun_reporting() to intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert intel_set_cpu_fifo_underrun_reporting() and intel_set_pch_fifo_underrun_reporting() to struct intel_display, along with some of the call chains from there. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/3b984d0183214d05d0cdecad35184ea8d89ae050.1739378095.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/g4x_dp.c | 8 +- drivers/gpu/drm/i915/display/g4x_hdmi.c | 8 +- drivers/gpu/drm/i915/display/intel_crt.c | 17 ++-- drivers/gpu/drm/i915/display/intel_ddi.c | 3 +- drivers/gpu/drm/i915/display/intel_display.c | 43 +++++----- .../drm/i915/display/intel_fifo_underrun.c | 84 +++++++++---------- .../drm/i915/display/intel_fifo_underrun.h | 7 +- drivers/gpu/drm/i915/display/intel_sdvo.c | 8 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 2 +- 9 files changed, 89 insertions(+), 91 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 4b51a4e47f639..0cb98cb043c6d 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -453,8 +453,8 @@ intel_dp_link_down(struct intel_encoder *encoder, * We get CPU/PCH FIFO underruns on the other pipe when * doing the workaround. Sweep them under the rug. */ - intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); + intel_set_cpu_fifo_underrun_reporting(display, PIPE_A, false); + intel_set_pch_fifo_underrun_reporting(display, PIPE_A, false); /* always enable with pattern 1 (as per spec) */ intel_dp->DP &= ~(DP_PIPE_SEL_MASK | DP_LINK_TRAIN_MASK); @@ -468,8 +468,8 @@ intel_dp_link_down(struct intel_encoder *encoder, intel_de_posting_read(display, intel_dp->output_reg); intel_wait_for_vblank_if_active(display, PIPE_A); - intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); + intel_set_cpu_fifo_underrun_reporting(display, PIPE_A, true); + intel_set_pch_fifo_underrun_reporting(display, PIPE_A, true); } msleep(intel_dp->pps.panel_power_down_delay); diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 1cd2e68e6ec56..089f1a4d77207 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -407,8 +407,8 @@ static void intel_disable_hdmi(struct intel_atomic_state *state, * We get CPU/PCH FIFO underruns on the other pipe when * doing the workaround. Sweep them under the rug. */ - intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); + intel_set_cpu_fifo_underrun_reporting(display, PIPE_A, false); + intel_set_pch_fifo_underrun_reporting(display, PIPE_A, false); temp &= ~SDVO_PIPE_SEL_MASK; temp |= SDVO_ENABLE | SDVO_PIPE_SEL(PIPE_A); @@ -426,8 +426,8 @@ static void intel_disable_hdmi(struct intel_atomic_state *state, intel_de_posting_read(display, intel_hdmi->hdmi_reg); intel_wait_for_vblank_if_active(display, PIPE_A); - intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); + intel_set_cpu_fifo_underrun_reporting(display, PIPE_A, true); + intel_set_pch_fifo_underrun_reporting(display, PIPE_A, true); } dig_port->set_infoframes(encoder, diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index 53b2aa0f3d20f..10c16ff25fe0d 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -250,11 +250,10 @@ static void hsw_disable_crt(struct intel_atomic_state *state, const struct drm_connector_state *old_conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); drm_WARN_ON(display->drm, !old_crtc_state->has_pch_encoder); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); + intel_set_pch_fifo_underrun_reporting(display, PIPE_A, false); } static void hsw_post_disable_crt(struct intel_atomic_state *state, @@ -264,7 +263,6 @@ static void hsw_post_disable_crt(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); intel_crtc_vblank_off(old_crtc_state); @@ -284,7 +282,7 @@ static void hsw_post_disable_crt(struct intel_atomic_state *state, drm_WARN_ON(display->drm, !old_crtc_state->has_pch_encoder); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); + intel_set_pch_fifo_underrun_reporting(display, PIPE_A, true); } static void hsw_pre_pll_enable_crt(struct intel_atomic_state *state, @@ -293,11 +291,10 @@ static void hsw_pre_pll_enable_crt(struct intel_atomic_state *state, const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); drm_WARN_ON(display->drm, !crtc_state->has_pch_encoder); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); + intel_set_pch_fifo_underrun_reporting(display, PIPE_A, false); } static void hsw_pre_enable_crt(struct intel_atomic_state *state, @@ -306,13 +303,12 @@ static void hsw_pre_enable_crt(struct intel_atomic_state *state, const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; drm_WARN_ON(display->drm, !crtc_state->has_pch_encoder); - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); + intel_set_cpu_fifo_underrun_reporting(display, pipe, false); hsw_fdi_link_train(encoder, crtc_state); @@ -325,7 +321,6 @@ static void hsw_enable_crt(struct intel_atomic_state *state, const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; @@ -343,8 +338,8 @@ static void hsw_enable_crt(struct intel_atomic_state *state, intel_crtc_wait_for_next_vblank(crtc); intel_crtc_wait_for_next_vblank(crtc); - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); + intel_set_cpu_fifo_underrun_reporting(display, pipe, true); + intel_set_pch_fifo_underrun_reporting(display, PIPE_A, true); } static void intel_enable_crt(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index ea0d8db2cc71b..3cb50a163bf97 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3009,13 +3009,14 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; drm_WARN_ON(&dev_priv->drm, crtc_state->has_pch_encoder); - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); + intel_set_cpu_fifo_underrun_reporting(display, pipe, true); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { intel_ddi_pre_enable_hdmi(state, encoder, crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d00b004567e83..42de7ffa078b5 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -774,6 +774,7 @@ void intel_plane_fixup_bitmasks(struct intel_crtc_state *crtc_state) void intel_plane_disable_noatomic(struct intel_crtc *crtc, struct intel_plane *plane) { + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -817,7 +818,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, * So disable underrun reporting before all the planes get disabled. */ if (DISPLAY_VER(dev_priv) == 2 && !crtc_state->active_planes) - intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false); + intel_set_cpu_fifo_underrun_reporting(display, crtc->pipe, false); intel_plane_disable_arm(NULL, plane, crtc_state); intel_crtc_wait_for_next_vblank(crtc); @@ -1305,6 +1306,7 @@ static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state, static void intel_pre_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); struct drm_i915_private *dev_priv = to_i915(state->base.dev); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); @@ -1406,7 +1408,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * vs. the old plane configuration. */ if (DISPLAY_VER(dev_priv) == 2 && planes_disabling(old_crtc_state, new_crtc_state)) - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); + intel_set_cpu_fifo_underrun_reporting(display, pipe, false); /* * WA for platforms where async address update enable bit @@ -1645,6 +1647,7 @@ static void ilk_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta static void ilk_crtc_enable(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -1663,8 +1666,8 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, * * Spurious PCH underruns also occur during PCH enabling. */ - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); - intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false); + intel_set_cpu_fifo_underrun_reporting(display, pipe, false); + intel_set_pch_fifo_underrun_reporting(display, pipe, false); ilk_configure_cpu_transcoder(new_crtc_state); @@ -1712,8 +1715,8 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, intel_crtc_wait_for_next_vblank(crtc); intel_crtc_wait_for_next_vblank(crtc); } - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); - intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); + intel_set_cpu_fifo_underrun_reporting(display, pipe, true); + intel_set_pch_fifo_underrun_reporting(display, pipe, true); } /* Display WA #1180: WaDisableScalarClockGating: glk */ @@ -1901,9 +1904,9 @@ void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state) static void ilk_crtc_disable(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; /* @@ -1911,8 +1914,8 @@ static void ilk_crtc_disable(struct intel_atomic_state *state, * pipe is already disabled, but FDI RX/TX is still enabled. * Happens at least with VGA+HDMI cloning. Suppress them. */ - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); - intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false); + intel_set_cpu_fifo_underrun_reporting(display, pipe, false); + intel_set_pch_fifo_underrun_reporting(display, pipe, false); intel_encoders_disable(state, crtc); @@ -1930,8 +1933,8 @@ static void ilk_crtc_disable(struct intel_atomic_state *state, if (old_crtc_state->has_pch_encoder) ilk_pch_post_disable(state, crtc); - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); - intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); + intel_set_cpu_fifo_underrun_reporting(display, pipe, true); + intel_set_pch_fifo_underrun_reporting(display, pipe, true); intel_disable_shared_dpll(old_crtc_state); } @@ -2211,6 +2214,7 @@ static void i9xx_configure_cpu_transcoder(const struct intel_crtc_state *crtc_st static void valleyview_crtc_enable(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -2233,7 +2237,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, crtc->active = true; - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); + intel_set_cpu_fifo_underrun_reporting(display, pipe, true); intel_encoders_pre_pll_enable(state, crtc); @@ -2259,6 +2263,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, static void i9xx_crtc_enable(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -2274,7 +2279,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, crtc->active = true; if (DISPLAY_VER(dev_priv) != 2) - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); + intel_set_cpu_fifo_underrun_reporting(display, pipe, true); intel_encoders_pre_enable(state, crtc); @@ -2349,7 +2354,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, intel_encoders_post_pll_disable(state, crtc); if (DISPLAY_VER(dev_priv) != 2) - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); + intel_set_cpu_fifo_underrun_reporting(display, pipe, false); if (!dev_priv->display.funcs.wm->initial_watermarks) intel_update_watermarks(dev_priv); @@ -7061,16 +7066,16 @@ static int intel_atomic_prepare_commit(struct intel_atomic_state *state) void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - if (DISPLAY_VER(dev_priv) != 2 || crtc_state->active_planes) - intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true); + if (DISPLAY_VER(display) != 2 || crtc_state->active_planes) + intel_set_cpu_fifo_underrun_reporting(display, crtc->pipe, true); if (crtc_state->has_pch_encoder) { enum pipe pch_transcoder = intel_crtc_pch_transcoder(crtc); - intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true); + intel_set_pch_fifo_underrun_reporting(display, pch_transcoder, true); } } @@ -7920,7 +7925,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * vs. the new plane configuration. */ if (DISPLAY_VER(dev_priv) == 2 && planes_enabling(old_crtc_state, new_crtc_state)) - intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true); + intel_set_cpu_fifo_underrun_reporting(display, crtc->pipe, true); intel_optimize_watermarks(state, crtc); } diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c index 18fcdbe1248ac..cf70dab4881b3 100644 --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c @@ -55,10 +55,9 @@ * The code also supports underrun detection on the PCH transcoder. */ -static bool ivb_can_enable_err_int(struct drm_device *dev) +static bool ivb_can_enable_err_int(struct intel_display *display) { - struct intel_display *display = to_intel_display(dev); - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc; enum pipe pipe; @@ -74,10 +73,9 @@ static bool ivb_can_enable_err_int(struct drm_device *dev) return true; } -static bool cpt_can_enable_serr_int(struct drm_device *dev) +static bool cpt_can_enable_serr_int(struct intel_display *display) { - struct intel_display *display = to_intel_display(dev); - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; struct intel_crtc *crtc; @@ -113,11 +111,11 @@ static void i9xx_check_fifo_underruns(struct intel_crtc *crtc) drm_err(&dev_priv->drm, "pipe %c underrun\n", pipe_name(crtc->pipe)); } -static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, +static void i9xx_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable, bool old) { - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); i915_reg_t reg = PIPESTAT(dev_priv, pipe); lockdep_assert_held(&dev_priv->irq_lock); @@ -135,10 +133,10 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, } } -static void ilk_set_fifo_underrun_reporting(struct drm_device *dev, +static void ilk_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable) { - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 bit = (pipe == PIPE_A) ? DE_PIPEA_FIFO_UNDERRUN : DE_PIPEB_FIFO_UNDERRUN; @@ -167,16 +165,16 @@ static void ivb_check_fifo_underruns(struct intel_crtc *crtc) drm_err(&dev_priv->drm, "fifo underrun on pipe %c\n", pipe_name(pipe)); } -static void ivb_set_fifo_underrun_reporting(struct drm_device *dev, +static void ivb_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable, bool old) { - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); if (enable) { intel_de_write(dev_priv, GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); - if (!ivb_can_enable_err_int(dev)) + if (!ivb_can_enable_err_int(display)) return; ilk_enable_display_irq(dev_priv, DE_ERR_INT_IVB); @@ -192,10 +190,10 @@ static void ivb_set_fifo_underrun_reporting(struct drm_device *dev, } } -static void bdw_set_fifo_underrun_reporting(struct drm_device *dev, +static void bdw_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable) { - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); if (enable) bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN); @@ -203,11 +201,11 @@ static void bdw_set_fifo_underrun_reporting(struct drm_device *dev, bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN); } -static void ibx_set_fifo_underrun_reporting(struct drm_device *dev, +static void ibx_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pch_transcoder, bool enable) { - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 bit = (pch_transcoder == PIPE_A) ? SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER; @@ -238,17 +236,17 @@ static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc) pipe_name(pch_transcoder)); } -static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, +static void cpt_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pch_transcoder, bool enable, bool old) { - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); if (enable) { intel_de_write(dev_priv, SERR_INT, SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); - if (!cpt_can_enable_serr_int(dev)) + if (!cpt_can_enable_serr_int(display)) return; ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT); @@ -264,11 +262,10 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, } } -static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, +static bool __intel_set_cpu_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable) { - struct intel_display *display = to_intel_display(dev); - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); bool old; @@ -277,21 +274,21 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, old = !crtc->cpu_fifo_underrun_disabled; crtc->cpu_fifo_underrun_disabled = !enable; - if (HAS_GMCH(dev_priv)) - i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old); - else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv)) - ilk_set_fifo_underrun_reporting(dev, pipe, enable); - else if (DISPLAY_VER(dev_priv) == 7) - ivb_set_fifo_underrun_reporting(dev, pipe, enable, old); - else if (DISPLAY_VER(dev_priv) >= 8) - bdw_set_fifo_underrun_reporting(dev, pipe, enable); + if (HAS_GMCH(display)) + i9xx_set_fifo_underrun_reporting(display, pipe, enable, old); + else if (display->platform.ironlake || display->platform.sandybridge) + ilk_set_fifo_underrun_reporting(display, pipe, enable); + else if (DISPLAY_VER(display) == 7) + ivb_set_fifo_underrun_reporting(display, pipe, enable, old); + else if (DISPLAY_VER(display) >= 8) + bdw_set_fifo_underrun_reporting(display, pipe, enable); return old; } /** * intel_set_cpu_fifo_underrun_reporting - set cpu fifo underrun reporting state - * @dev_priv: i915 device instance + * @display: display device instance * @pipe: (CPU) pipe to set state for * @enable: whether underruns should be reported or not * @@ -305,15 +302,15 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, * * Returns the previous state of underrun reporting. */ -bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, +bool intel_set_cpu_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable) { + struct drm_i915_private *dev_priv = to_i915(display->drm); unsigned long flags; bool ret; spin_lock_irqsave(&dev_priv->irq_lock, flags); - ret = __intel_set_cpu_fifo_underrun_reporting(&dev_priv->drm, pipe, - enable); + ret = __intel_set_cpu_fifo_underrun_reporting(display, pipe, enable); spin_unlock_irqrestore(&dev_priv->irq_lock, flags); return ret; @@ -321,7 +318,7 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, /** * intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state - * @dev_priv: i915 device instance + * @display: display device instance * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older) * @enable: whether underruns should be reported or not * @@ -333,13 +330,12 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, * * Returns the previous state of underrun reporting. */ -bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, +bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display, enum pipe pch_transcoder, bool enable) { - struct intel_display *display = &dev_priv->display; - struct intel_crtc *crtc = - intel_crtc_for_pipe(display, pch_transcoder); + struct drm_i915_private *dev_priv = to_i915(display->drm); + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pch_transcoder); unsigned long flags; bool old; @@ -358,11 +354,11 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, crtc->pch_fifo_underrun_disabled = !enable; if (HAS_PCH_IBX(dev_priv)) - ibx_set_fifo_underrun_reporting(&dev_priv->drm, + ibx_set_fifo_underrun_reporting(display, pch_transcoder, enable); else - cpt_set_fifo_underrun_reporting(&dev_priv->drm, + cpt_set_fifo_underrun_reporting(display, pch_transcoder, enable, old); @@ -394,7 +390,7 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, crtc->cpu_fifo_underrun_disabled) return; - if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) { + if (intel_set_cpu_fifo_underrun_reporting(display, pipe, false)) { trace_intel_cpu_fifo_underrun(display, pipe); drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe)); @@ -417,7 +413,7 @@ void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, { struct intel_display *display = &dev_priv->display; - if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, + if (intel_set_pch_fifo_underrun_reporting(display, pch_transcoder, false)) { trace_intel_pch_fifo_underrun(display, pch_transcoder); drm_err(&dev_priv->drm, "PCH transcoder %c FIFO underrun\n", diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.h b/drivers/gpu/drm/i915/display/intel_fifo_underrun.h index b00d8abebcf91..8302080c2313d 100644 --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.h +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.h @@ -8,15 +8,16 @@ #include +enum pipe; struct drm_i915_private; struct intel_crtc; -enum pipe; +struct intel_display; void intel_init_fifo_underrun_reporting(struct drm_i915_private *i915, struct intel_crtc *crtc, bool enable); -bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, +bool intel_set_cpu_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable); -bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, +bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display, enum pipe pch_transcoder, bool enable); void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index f7067696dec96..e32cdb1acc62d 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -1864,8 +1864,8 @@ static void intel_disable_sdvo(struct intel_atomic_state *state, * We get CPU/PCH FIFO underruns on the other pipe when * doing the workaround. Sweep them under the rug. */ - intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); + intel_set_cpu_fifo_underrun_reporting(display, PIPE_A, false); + intel_set_pch_fifo_underrun_reporting(display, PIPE_A, false); temp &= ~SDVO_PIPE_SEL_MASK; temp |= SDVO_ENABLE | SDVO_PIPE_SEL(PIPE_A); @@ -1875,8 +1875,8 @@ static void intel_disable_sdvo(struct intel_atomic_state *state, intel_sdvo_write_sdvox(intel_sdvo, temp); intel_wait_for_vblank_if_active(display, PIPE_A); - intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); + intel_set_cpu_fifo_underrun_reporting(display, PIPE_A, true); + intel_set_pch_fifo_underrun_reporting(display, PIPE_A, true); } } diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index bdbc7e95fcfa0..d5e135b7a254c 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -739,7 +739,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, intel_dsi_wait_panel_power_cycle(intel_dsi); - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); + intel_set_cpu_fifo_underrun_reporting(display, pipe, true); /* * The BIOS may leave the PLL in a wonky state where it doesn't From 3a9a1f89c27643cb5233051e5190bf7503380b9a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:37 +0200 Subject: [PATCH 218/284] drm/i915/sdvo: convert intel_sdvo.[ch] to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of intel_sdvo.[ch] to struct intel_display. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/2e79909f8a060d7ff1744911f8da9300eb1f225c.1739378095.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/g4x_hdmi.c | 3 +- drivers/gpu/drm/i915/display/intel_display.c | 6 +- .../gpu/drm/i915/display/intel_pch_display.c | 2 +- drivers/gpu/drm/i915/display/intel_sdvo.c | 281 +++++++++--------- drivers/gpu/drm/i915/display/intel_sdvo.h | 10 +- 5 files changed, 150 insertions(+), 152 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 089f1a4d77207..5c5eb3d621c8e 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -67,7 +67,6 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); intel_wakeref_t wakeref; bool ret; @@ -77,7 +76,7 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, if (!wakeref) return false; - ret = intel_sdvo_port_enabled(dev_priv, intel_hdmi->hdmi_reg, pipe); + ret = intel_sdvo_port_enabled(display, intel_hdmi->hdmi_reg, pipe); intel_display_power_put(display, encoder->power_domain, wakeref); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 42de7ffa078b5..ee241604a4265 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8235,7 +8235,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) if (intel_de_read(dev_priv, PCH_HDMIB) & SDVO_DETECTED) { /* PCH SDVOB multiplex with HDMIB */ - found = intel_sdvo_init(dev_priv, PCH_SDVOB, PORT_B); + found = intel_sdvo_init(display, PCH_SDVOB, PORT_B); if (!found) g4x_hdmi_init(display, PCH_HDMIB, PORT_B); if (!found && (intel_de_read(dev_priv, PCH_DP_B) & DP_DETECTED)) @@ -8314,7 +8314,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) if (intel_de_read(dev_priv, GEN3_SDVOB) & SDVO_DETECTED) { drm_dbg_kms(&dev_priv->drm, "probing SDVOB\n"); - found = intel_sdvo_init(dev_priv, GEN3_SDVOB, PORT_B); + found = intel_sdvo_init(display, GEN3_SDVOB, PORT_B); if (!found && IS_G4X(dev_priv)) { drm_dbg_kms(&dev_priv->drm, "probing HDMI on SDVOB\n"); @@ -8329,7 +8329,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) if (intel_de_read(dev_priv, GEN3_SDVOB) & SDVO_DETECTED) { drm_dbg_kms(&dev_priv->drm, "probing SDVOC\n"); - found = intel_sdvo_init(dev_priv, GEN3_SDVOC, PORT_C); + found = intel_sdvo_init(display, GEN3_SDVOC, PORT_C); } if (!found && (intel_de_read(dev_priv, GEN3_SDVOC) & SDVO_DETECTED)) { diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c index 98a6b57ac956b..1abe0a784570b 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_display.c +++ b/drivers/gpu/drm/i915/display/intel_pch_display.c @@ -65,7 +65,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, enum pipe port_pipe; bool state; - state = intel_sdvo_port_enabled(dev_priv, hdmi_reg, &port_pipe); + state = intel_sdvo_port_enabled(display, hdmi_reg, &port_pipe); INTEL_DISPLAY_STATE_WARN(display, state && port_pipe == pipe, "PCH HDMI %c enabled on transcoder %c, should be disabled\n", diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index e32cdb1acc62d..30f52a3091cd5 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -213,29 +213,29 @@ intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, */ static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) { - struct drm_device *dev = intel_sdvo->base.base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 bval = val, cval = val; int i; if (HAS_PCH_SPLIT(dev_priv)) { - intel_de_write(dev_priv, intel_sdvo->sdvo_reg, val); - intel_de_posting_read(dev_priv, intel_sdvo->sdvo_reg); + intel_de_write(display, intel_sdvo->sdvo_reg, val); + intel_de_posting_read(display, intel_sdvo->sdvo_reg); /* * HW workaround, need to write this twice for issue * that may result in first write getting masked. */ if (HAS_PCH_IBX(dev_priv)) { - intel_de_write(dev_priv, intel_sdvo->sdvo_reg, val); - intel_de_posting_read(dev_priv, intel_sdvo->sdvo_reg); + intel_de_write(display, intel_sdvo->sdvo_reg, val); + intel_de_posting_read(display, intel_sdvo->sdvo_reg); } return; } if (intel_sdvo->base.port == PORT_B) - cval = intel_de_read(dev_priv, GEN3_SDVOC); + cval = intel_de_read(display, GEN3_SDVOC); else - bval = intel_de_read(dev_priv, GEN3_SDVOB); + bval = intel_de_read(display, GEN3_SDVOB); /* * Write the registers twice for luck. Sometimes, @@ -243,17 +243,17 @@ static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) * The BIOS does this too. Yay, magic */ for (i = 0; i < 2; i++) { - intel_de_write(dev_priv, GEN3_SDVOB, bval); - intel_de_posting_read(dev_priv, GEN3_SDVOB); + intel_de_write(display, GEN3_SDVOB, bval); + intel_de_posting_read(display, GEN3_SDVOB); - intel_de_write(dev_priv, GEN3_SDVOC, cval); - intel_de_posting_read(dev_priv, GEN3_SDVOC); + intel_de_write(display, GEN3_SDVOC, cval); + intel_de_posting_read(display, GEN3_SDVOC); } } static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); struct i2c_msg msgs[] = { { .addr = intel_sdvo->target_addr, @@ -273,7 +273,7 @@ static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) if ((ret = i2c_transfer(intel_sdvo->i2c, msgs, 2)) == 2) return true; - drm_dbg_kms(&i915->drm, "i2c transfer returned %d\n", ret); + drm_dbg_kms(display->drm, "i2c transfer returned %d\n", ret); return false; } @@ -415,7 +415,7 @@ static const char *sdvo_cmd_name(u8 cmd) static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, const void *args, int args_len) { - struct drm_i915_private *dev_priv = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); const char *cmd_name; int i, pos = 0; char buffer[64]; @@ -436,10 +436,10 @@ static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, else BUF_PRINT("(%02X)", cmd); - drm_WARN_ON(&dev_priv->drm, pos >= sizeof(buffer) - 1); + drm_WARN_ON(display->drm, pos >= sizeof(buffer) - 1); #undef BUF_PRINT - drm_dbg_kms(&dev_priv->drm, "%s: W: %02X %s\n", SDVO_NAME(intel_sdvo), + drm_dbg_kms(display->drm, "%s: W: %02X %s\n", SDVO_NAME(intel_sdvo), cmd, buffer); } @@ -465,7 +465,7 @@ static bool __intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, const void *args, int args_len, bool unlocked) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); u8 *buf, status; struct i2c_msg *msgs; int i, ret = true; @@ -515,13 +515,13 @@ static bool __intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, else ret = __i2c_transfer(intel_sdvo->i2c, msgs, i+3); if (ret < 0) { - drm_dbg_kms(&i915->drm, "I2c transfer returned %d\n", ret); + drm_dbg_kms(display->drm, "I2c transfer returned %d\n", ret); ret = false; goto out; } if (ret != i+3) { /* failure in I2C transfer */ - drm_dbg_kms(&i915->drm, "I2c transfer returned %d/%d\n", ret, i+3); + drm_dbg_kms(display->drm, "I2c transfer returned %d/%d\n", ret, i + 3); ret = false; } @@ -540,7 +540,7 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, void *response, int response_len) { - struct drm_i915_private *dev_priv = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); const char *cmd_status; u8 retry = 15; /* 5 quick checks, followed by 10 long checks */ u8 status; @@ -605,15 +605,15 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, BUF_PRINT(" %02X", ((u8 *)response)[i]); } - drm_WARN_ON(&dev_priv->drm, pos >= sizeof(buffer) - 1); + drm_WARN_ON(display->drm, pos >= sizeof(buffer) - 1); #undef BUF_PRINT - drm_dbg_kms(&dev_priv->drm, "%s: R: %s\n", + drm_dbg_kms(display->drm, "%s: R: %s\n", SDVO_NAME(intel_sdvo), buffer); return true; log_fail: - drm_dbg_kms(&dev_priv->drm, "%s: R: ... failed %s\n", + drm_dbg_kms(display->drm, "%s: R: ... failed %s\n", SDVO_NAME(intel_sdvo), buffer); return false; } @@ -1009,7 +1009,7 @@ static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, unsigned int if_index, u8 tx_rate, const u8 *data, unsigned int length) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); u8 set_buf_index[2] = { if_index, 0 }; u8 hbuf_size, tmp[8]; int i; @@ -1022,7 +1022,7 @@ static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, if (!intel_sdvo_get_hbuf_size(intel_sdvo, &hbuf_size)) return false; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "writing sdvo hbuf: %i, length %u, hbuf_size: %i\n", if_index, length, hbuf_size); @@ -1049,7 +1049,7 @@ static ssize_t intel_sdvo_read_infoframe(struct intel_sdvo *intel_sdvo, unsigned int if_index, u8 *data, unsigned int length) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); u8 set_buf_index[2] = { if_index, 0 }; u8 hbuf_size, tx_rate, av_split; int i; @@ -1079,7 +1079,7 @@ static ssize_t intel_sdvo_read_infoframe(struct intel_sdvo *intel_sdvo, if (!intel_sdvo_get_hbuf_size(intel_sdvo, &hbuf_size)) return false; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "reading sdvo hbuf: %i, length %u, hbuf_size: %i\n", if_index, length, hbuf_size); @@ -1100,7 +1100,7 @@ static bool intel_sdvo_compute_avi_infoframe(struct intel_sdvo *intel_sdvo, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct drm_i915_private *dev_priv = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi; const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; @@ -1126,7 +1126,7 @@ static bool intel_sdvo_compute_avi_infoframe(struct intel_sdvo *intel_sdvo, HDMI_QUANTIZATION_RANGE_FULL); ret = hdmi_avi_infoframe_check(frame); - if (drm_WARN_ON(&dev_priv->drm, ret)) + if (drm_WARN_ON(display->drm, ret)) return false; return true; @@ -1135,7 +1135,7 @@ static bool intel_sdvo_compute_avi_infoframe(struct intel_sdvo *intel_sdvo, static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); u8 sdvo_data[HDMI_INFOFRAME_SIZE(AVI)]; const union hdmi_infoframe *frame = &crtc_state->infoframes.avi; ssize_t len; @@ -1144,12 +1144,12 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI)) == 0) return true; - if (drm_WARN_ON(&dev_priv->drm, + if (drm_WARN_ON(display->drm, frame->any.type != HDMI_INFOFRAME_TYPE_AVI)) return false; len = hdmi_infoframe_pack_only(frame, sdvo_data, sizeof(sdvo_data)); - if (drm_WARN_ON(&dev_priv->drm, len < 0)) + if (drm_WARN_ON(display->drm, len < 0)) return false; return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, @@ -1160,7 +1160,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, static void intel_sdvo_get_avi_infoframe(struct intel_sdvo *intel_sdvo, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); u8 sdvo_data[HDMI_INFOFRAME_SIZE(AVI)]; union hdmi_infoframe *frame = &crtc_state->infoframes.avi; ssize_t len; @@ -1172,7 +1172,7 @@ static void intel_sdvo_get_avi_infoframe(struct intel_sdvo *intel_sdvo, len = intel_sdvo_read_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, sdvo_data, sizeof(sdvo_data)); if (len < 0) { - drm_dbg_kms(&i915->drm, "failed to read AVI infoframe\n"); + drm_dbg_kms(display->drm, "failed to read AVI infoframe\n"); return; } else if (len == 0) { return; @@ -1183,12 +1183,12 @@ static void intel_sdvo_get_avi_infoframe(struct intel_sdvo *intel_sdvo, ret = hdmi_infoframe_unpack(frame, sdvo_data, len); if (ret) { - drm_dbg_kms(&i915->drm, "Failed to unpack AVI infoframe\n"); + drm_dbg_kms(display->drm, "Failed to unpack AVI infoframe\n"); return; } if (frame->any.type != HDMI_INFOFRAME_TYPE_AVI) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Found the wrong infoframe type 0x%x (expected 0x%02x)\n", frame->any.type, HDMI_INFOFRAME_TYPE_AVI); } @@ -1196,7 +1196,7 @@ static void intel_sdvo_get_avi_infoframe(struct intel_sdvo *intel_sdvo, static void intel_sdvo_get_eld(struct intel_sdvo *intel_sdvo, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); ssize_t len; u8 val; @@ -1212,7 +1212,7 @@ static void intel_sdvo_get_eld(struct intel_sdvo *intel_sdvo, len = intel_sdvo_read_infoframe(intel_sdvo, SDVO_HBUF_INDEX_ELD, crtc_state->eld, sizeof(crtc_state->eld)); if (len < 0) - drm_dbg_kms(&i915->drm, "failed to read ELD\n"); + drm_dbg_kms(display->drm, "failed to read ELD\n"); } static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo, @@ -1282,7 +1282,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, static int i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = to_i915(pipe_config->uapi.crtc->dev); + struct intel_display *display = to_intel_display(pipe_config); unsigned int dotclock = pipe_config->hw.adjusted_mode.crtc_clock; struct dpll *clock = &pipe_config->dpll; @@ -1303,7 +1303,7 @@ static int i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config) clock->m1 = 12; clock->m2 = 8; } else { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "SDVO TV clock out of range: %i\n", dotclock); return -EINVAL; } @@ -1359,6 +1359,7 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_sdvo_connector *intel_sdvo_connector = @@ -1366,13 +1367,13 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; struct drm_display_mode *mode = &pipe_config->hw.mode; - if (HAS_PCH_SPLIT(to_i915(encoder->base.dev))) { + if (HAS_PCH_SPLIT(i915)) { pipe_config->has_pch_encoder = true; if (!intel_fdi_compute_pipe_bpp(pipe_config)) return -EINVAL; } - drm_dbg_kms(&i915->drm, "forcing bpc to 8 for SDVO\n"); + drm_dbg_kms(display->drm, "forcing bpc to 8 for SDVO\n"); /* FIXME: Don't increase pipe_bpp */ pipe_config->pipe_bpp = 8*3; pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB; @@ -1451,7 +1452,7 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, if (!intel_sdvo_compute_avi_infoframe(intel_sdvo, pipe_config, conn_state)) { - drm_dbg_kms(&i915->drm, "bad AVI infoframe\n"); + drm_dbg_kms(display->drm, "bad AVI infoframe\n"); return -EINVAL; } @@ -1525,6 +1526,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(intel_encoder); struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; @@ -1570,7 +1572,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, intel_sdvo_get_dtd_from_mode(&output_dtd, mode); } if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) - drm_info(&dev_priv->drm, + drm_info(display->drm, "Setting output timings on %s failed\n", SDVO_NAME(intel_sdvo)); @@ -1600,13 +1602,13 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, if (IS_TV(intel_sdvo_connector) || IS_LVDS(intel_sdvo_connector)) input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags; if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) - drm_info(&dev_priv->drm, + drm_info(display->drm, "Setting input timings on %s failed\n", SDVO_NAME(intel_sdvo)); switch (crtc_state->pixel_multiplier) { default: - drm_WARN(&dev_priv->drm, 1, + drm_WARN(display->drm, 1, "unknown pixel multiplier specified\n"); fallthrough; case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; @@ -1617,14 +1619,14 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, return; /* Set the SDVO control regs. */ - if (DISPLAY_VER(dev_priv) >= 4) { + if (DISPLAY_VER(display) >= 4) { /* The real mode polarity is set by the SDVO commands, using * struct intel_sdvo_dtd. */ sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; - if (DISPLAY_VER(dev_priv) < 5) + if (DISPLAY_VER(display) < 5) sdvox |= SDVO_BORDER_ENABLE; } else { - sdvox = intel_de_read(dev_priv, intel_sdvo->sdvo_reg); + sdvox = intel_de_read(display, intel_sdvo->sdvo_reg); if (intel_sdvo->base.port == PORT_B) sdvox &= SDVOB_PRESERVE_MASK; else @@ -1637,10 +1639,10 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, else sdvox |= SDVO_PIPE_SEL(crtc->pipe); - if (DISPLAY_VER(dev_priv) >= 4) { + if (DISPLAY_VER(display) >= 4) { /* done in crtc_mode_set as the dpll_md reg must be written early */ - } else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) || - IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) { + } else if (display->platform.i945g || display->platform.i945gm || + display->platform.g33 || display->platform.pineview) { /* done in crtc_mode_set as it lives inside the dpll register */ } else { sdvox |= (crtc_state->pixel_multiplier - 1) @@ -1648,7 +1650,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, } if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL && - DISPLAY_VER(dev_priv) < 5) + DISPLAY_VER(display) < 5) sdvox |= SDVO_STALL_SELECT; intel_sdvo_write_sdvox(intel_sdvo, sdvox); } @@ -1665,17 +1667,18 @@ static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector) return active_outputs & intel_sdvo_connector->output_flag; } -bool intel_sdvo_port_enabled(struct drm_i915_private *dev_priv, +bool intel_sdvo_port_enabled(struct intel_display *display, i915_reg_t sdvo_reg, enum pipe *pipe) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val; - val = intel_de_read(dev_priv, sdvo_reg); + val = intel_de_read(display, sdvo_reg); /* asserts want to know the pipe even if the port is disabled */ if (HAS_PCH_CPT(dev_priv)) *pipe = (val & SDVO_PIPE_SEL_MASK_CPT) >> SDVO_PIPE_SEL_SHIFT_CPT; - else if (IS_CHERRYVIEW(dev_priv)) + else if (display->platform.cherryview) *pipe = (val & SDVO_PIPE_SEL_MASK_CHV) >> SDVO_PIPE_SEL_SHIFT_CHV; else *pipe = (val & SDVO_PIPE_SEL_MASK) >> SDVO_PIPE_SEL_SHIFT; @@ -1686,14 +1689,14 @@ bool intel_sdvo_port_enabled(struct drm_i915_private *dev_priv, static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_sdvo *intel_sdvo = to_sdvo(encoder); u16 active_outputs = 0; bool ret; intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs); - ret = intel_sdvo_port_enabled(dev_priv, intel_sdvo->sdvo_reg, pipe); + ret = intel_sdvo_port_enabled(display, intel_sdvo->sdvo_reg, pipe); return ret || active_outputs; } @@ -1701,8 +1704,7 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, static void intel_sdvo_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(encoder); struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_sdvo_dtd dtd; int encoder_pixel_multiplier = 0; @@ -1713,7 +1715,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, pipe_config->output_types |= BIT(INTEL_OUTPUT_SDVO); - sdvox = intel_de_read(dev_priv, intel_sdvo->sdvo_reg); + sdvox = intel_de_read(display, intel_sdvo->sdvo_reg); ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); if (!ret) { @@ -1721,7 +1723,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, * Some sdvo encoders are not spec compliant and don't * implement the mandatory get_timings function. */ - drm_dbg(&dev_priv->drm, "failed to retrieve SDVO DTD\n"); + drm_dbg_kms(display->drm, "failed to retrieve SDVO DTD\n"); pipe_config->quirks |= PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS; } else { if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) @@ -1744,7 +1746,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, * encoder->get_config we so already have a valid pixel multiplier on all * other platforms. */ - if (IS_I915G(dev_priv) || IS_I915GM(dev_priv)) { + if (display->platform.i915g || display->platform.i915gm) { pipe_config->pixel_multiplier = ((sdvox & SDVO_PORT_MULTIPLY_MASK) >> SDVO_PORT_MULTIPLY_SHIFT) + 1; @@ -1773,7 +1775,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, } } - drm_WARN(dev, + drm_WARN(display->drm, encoder_pixel_multiplier != pipe_config->pixel_multiplier, "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n", pipe_config->pixel_multiplier, encoder_pixel_multiplier); @@ -1849,7 +1851,7 @@ static void intel_disable_sdvo(struct intel_atomic_state *state, intel_sdvo_set_encoder_power_state(intel_sdvo, DRM_MODE_DPMS_OFF); - temp = intel_de_read(dev_priv, intel_sdvo->sdvo_reg); + temp = intel_de_read(display, intel_sdvo->sdvo_reg); temp &= ~SDVO_ENABLE; intel_sdvo_write_sdvox(intel_sdvo, temp); @@ -1900,8 +1902,7 @@ static void intel_enable_sdvo(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(encoder); struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(conn_state->connector); @@ -1911,7 +1912,7 @@ static void intel_enable_sdvo(struct intel_atomic_state *state, int i; bool success; - temp = intel_de_read(dev_priv, intel_sdvo->sdvo_reg); + temp = intel_de_read(display, intel_sdvo->sdvo_reg); temp |= SDVO_ENABLE; intel_sdvo_write_sdvox(intel_sdvo, temp); @@ -1926,7 +1927,7 @@ static void intel_enable_sdvo(struct intel_atomic_state *state, * a given it the status is a success, we succeeded. */ if (success && !input1) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "First %s output reported failure to sync\n", SDVO_NAME(intel_sdvo)); } @@ -1941,12 +1942,13 @@ static enum drm_mode_status intel_sdvo_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { + struct intel_display *display = to_intel_display(connector->dev); struct drm_i915_private *i915 = to_i915(connector->dev); struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector)); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); bool has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo_connector, connector->state); - int max_dotclk = i915->display.cdclk.max_dotclk_freq; + int max_dotclk = display->cdclk.max_dotclk_freq; enum drm_mode_status status; int clock = mode->clock; @@ -1982,14 +1984,15 @@ intel_sdvo_mode_valid(struct drm_connector *connector, static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); + BUILD_BUG_ON(sizeof(*caps) != 8); if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DEVICE_CAPS, caps, sizeof(*caps))) return false; - drm_dbg_kms(&i915->drm, "SDVO capabilities:\n" + drm_dbg_kms(display->drm, "SDVO capabilities:\n" " vendor_id: %d\n" " device_id: %d\n" " device_rev_id: %d\n" @@ -2031,17 +2034,17 @@ static u8 intel_sdvo_get_colorimetry_cap(struct intel_sdvo *intel_sdvo) static u16 intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo) { - struct drm_i915_private *dev_priv = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); u16 hotplug; - if (!I915_HAS_HOTPLUG(dev_priv)) + if (!I915_HAS_HOTPLUG(display)) return 0; /* * HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise * on the line. */ - if (IS_I945G(dev_priv) || IS_I945GM(dev_priv)) + if (display->platform.i945g || display->platform.i945gm) return 0; if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, @@ -2138,13 +2141,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector, bool force) { struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *i915 = to_i915(connector->dev); struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector)); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); enum drm_connector_status ret; u16 response; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); if (!intel_display_device_enabled(display)) @@ -2162,7 +2164,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) &response, 2)) return connector_status_unknown; - drm_dbg_kms(&i915->drm, "SDVO response %d %d [%x]\n", + drm_dbg_kms(display->drm, "SDVO response %d %d [%x]\n", response & 0xff, response >> 8, intel_sdvo_connector->output_flag); @@ -2301,7 +2303,6 @@ static int intel_sdvo_get_tv_modes(struct drm_connector *connector) { struct intel_display *display = to_intel_display(connector->dev); struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector)); - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); const struct drm_connector_state *conn_state = connector->state; @@ -2310,7 +2311,7 @@ static int intel_sdvo_get_tv_modes(struct drm_connector *connector) int num_modes = 0; int i; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); if (!intel_display_driver_check_access(display)) @@ -2352,9 +2353,9 @@ static int intel_sdvo_get_tv_modes(struct drm_connector *connector) static int intel_sdvo_get_lvds_modes(struct drm_connector *connector) { - struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_display *display = to_intel_display(connector->dev); - drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); return intel_panel_get_modes(to_intel_connector(connector)); @@ -2618,14 +2619,14 @@ static struct intel_sdvo_ddc * intel_sdvo_select_ddc_bus(struct intel_sdvo *sdvo, struct intel_sdvo_connector *connector) { - struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&sdvo->base); const struct sdvo_device_mapping *mapping; int ddc_bus; if (sdvo->base.port == PORT_B) - mapping = &dev_priv->display.vbt.sdvo_mappings[0]; + mapping = &display->vbt.sdvo_mappings[0]; else - mapping = &dev_priv->display.vbt.sdvo_mappings[1]; + mapping = &display->vbt.sdvo_mappings[1]; if (mapping->initialized) ddc_bus = (mapping->ddc_pin & 0xf0) >> 4; @@ -2642,14 +2643,13 @@ static void intel_sdvo_select_i2c_bus(struct intel_sdvo *sdvo) { struct intel_display *display = to_intel_display(&sdvo->base); - struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev); const struct sdvo_device_mapping *mapping; u8 pin; if (sdvo->base.port == PORT_B) - mapping = &dev_priv->display.vbt.sdvo_mappings[0]; + mapping = &display->vbt.sdvo_mappings[0]; else - mapping = &dev_priv->display.vbt.sdvo_mappings[1]; + mapping = &display->vbt.sdvo_mappings[1]; if (mapping->initialized && intel_gmbus_is_valid_pin(display, mapping->i2c_pin)) @@ -2657,7 +2657,7 @@ intel_sdvo_select_i2c_bus(struct intel_sdvo *sdvo) else pin = GMBUS_PIN_DPB; - drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] I2C pin %d, target addr 0x%x\n", + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] I2C pin %d, target addr 0x%x\n", sdvo->base.base.base.id, sdvo->base.base.name, pin, sdvo->target_addr); @@ -2687,15 +2687,15 @@ intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo) static u8 intel_sdvo_get_target_addr(struct intel_sdvo *sdvo) { - struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&sdvo->base); const struct sdvo_device_mapping *my_mapping, *other_mapping; if (sdvo->base.port == PORT_B) { - my_mapping = &dev_priv->display.vbt.sdvo_mappings[0]; - other_mapping = &dev_priv->display.vbt.sdvo_mappings[1]; + my_mapping = &display->vbt.sdvo_mappings[0]; + other_mapping = &display->vbt.sdvo_mappings[1]; } else { - my_mapping = &dev_priv->display.vbt.sdvo_mappings[1]; - other_mapping = &dev_priv->display.vbt.sdvo_mappings[0]; + my_mapping = &display->vbt.sdvo_mappings[1]; + other_mapping = &display->vbt.sdvo_mappings[0]; } /* If the BIOS described our SDVO device, take advantage of it. */ @@ -2731,7 +2731,7 @@ static int intel_sdvo_connector_init(struct intel_sdvo_connector *connector, struct intel_sdvo *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.base.dev); + struct intel_display *display = to_intel_display(&encoder->base); struct intel_sdvo_ddc *ddc = NULL; int ret; @@ -2756,7 +2756,7 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, intel_connector_attach_encoder(&connector->base, &encoder->base); if (ddc) - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] using %s\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] using %s\n", connector->base.base.base.id, connector->base.base.name, ddc->ddc.name); @@ -2799,14 +2799,14 @@ static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void) static bool intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, u16 type) { + struct intel_display *display = to_intel_display(&intel_sdvo->base); struct drm_encoder *encoder = &intel_sdvo->base.base; struct drm_connector *connector; struct intel_encoder *intel_encoder = to_intel_encoder(encoder); - struct drm_i915_private *i915 = to_i915(intel_encoder->base.dev); struct intel_connector *intel_connector; struct intel_sdvo_connector *intel_sdvo_connector; - drm_dbg_kms(&i915->drm, "initialising DVI type 0x%x\n", type); + drm_dbg_kms(display->drm, "initialising DVI type 0x%x\n", type); intel_sdvo_connector = intel_sdvo_connector_alloc(); if (!intel_sdvo_connector) @@ -2852,13 +2852,13 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, u16 type) static bool intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, u16 type) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); struct drm_encoder *encoder = &intel_sdvo->base.base; struct drm_connector *connector; struct intel_connector *intel_connector; struct intel_sdvo_connector *intel_sdvo_connector; - drm_dbg_kms(&i915->drm, "initialising TV type 0x%x\n", type); + drm_dbg_kms(display->drm, "initialising TV type 0x%x\n", type); intel_sdvo_connector = intel_sdvo_connector_alloc(); if (!intel_sdvo_connector) @@ -2892,13 +2892,13 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, u16 type) static bool intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, u16 type) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); struct drm_encoder *encoder = &intel_sdvo->base.base; struct drm_connector *connector; struct intel_connector *intel_connector; struct intel_sdvo_connector *intel_sdvo_connector; - drm_dbg_kms(&i915->drm, "initialising analog type 0x%x\n", type); + drm_dbg_kms(display->drm, "initialising analog type 0x%x\n", type); intel_sdvo_connector = intel_sdvo_connector_alloc(); if (!intel_sdvo_connector) @@ -2926,12 +2926,11 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, u16 type) { struct intel_display *display = to_intel_display(&intel_sdvo->base); struct drm_encoder *encoder = &intel_sdvo->base.base; - struct drm_i915_private *i915 = to_i915(encoder->dev); struct drm_connector *connector; struct intel_connector *intel_connector; struct intel_sdvo_connector *intel_sdvo_connector; - drm_dbg_kms(&i915->drm, "initialising LVDS type 0x%x\n", type); + drm_dbg_kms(display->drm, "initialising LVDS type 0x%x\n", type); intel_sdvo_connector = intel_sdvo_connector_alloc(); if (!intel_sdvo_connector) @@ -2961,12 +2960,12 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, u16 type) intel_panel_add_vbt_sdvo_fixed_mode(intel_connector); if (!intel_panel_preferred_fixed_mode(intel_connector)) { - mutex_lock(&i915->drm.mode_config.mutex); + mutex_lock(&display->drm->mode_config.mutex); intel_ddc_get_modes(connector, connector->ddc); intel_panel_add_edid_fixed_modes(intel_connector, false); - mutex_unlock(&i915->drm.mode_config.mutex); + mutex_unlock(&display->drm->mode_config.mutex); } intel_panel_init(intel_connector, NULL); @@ -3015,7 +3014,7 @@ static bool intel_sdvo_output_init(struct intel_sdvo *sdvo, u16 type) static bool intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); static const u16 probe_order[] = { SDVO_OUTPUT_TMDS0, SDVO_OUTPUT_TMDS1, @@ -3034,7 +3033,7 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo) flags = intel_sdvo_filter_output_flags(intel_sdvo->caps.output_flags); if (flags == 0) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "%s: Unknown SDVO output type (0x%04x)\n", SDVO_NAME(intel_sdvo), intel_sdvo->caps.output_flags); return false; @@ -3057,11 +3056,11 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo) static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo) { - struct drm_device *dev = intel_sdvo->base.base.dev; + struct intel_display *display = to_intel_display(&intel_sdvo->base); struct drm_connector *connector, *tmp; list_for_each_entry_safe(connector, tmp, - &dev->mode_config.connector_list, head) { + &display->drm->mode_config.connector_list, head) { if (intel_attached_encoder(to_intel_connector(connector)) == &intel_sdvo->base) { drm_connector_unregister(connector); intel_connector_destroy(connector); @@ -3073,7 +3072,7 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, struct intel_sdvo_connector *intel_sdvo_connector, int type) { - struct drm_device *dev = intel_sdvo->base.base.dev; + struct intel_display *display = to_intel_display(&intel_sdvo->base); struct intel_sdvo_tv_format format; u32 format_map, i; @@ -3098,7 +3097,7 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, intel_sdvo_connector->tv_format = - drm_property_create(dev, DRM_MODE_PROP_ENUM, + drm_property_create(display->drm, DRM_MODE_PROP_ENUM, "mode", intel_sdvo_connector->format_supported_num); if (!intel_sdvo_connector->tv_format) return false; @@ -3120,12 +3119,12 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ return false; \ intel_sdvo_connector->name = \ - drm_property_create_range(dev, 0, #name, 0, data_value[0]); \ + drm_property_create_range(display->drm, 0, #name, 0, data_value[0]); \ if (!intel_sdvo_connector->name) return false; \ state_assignment = response; \ drm_object_attach_property(&connector->base, \ intel_sdvo_connector->name, 0); \ - drm_dbg_kms(dev, #name ": max %d, default %d, current %d\n", \ + drm_dbg_kms(display->drm, #name ": max %d, default %d, current %d\n", \ data_value[0], data_value[1], response); \ } \ } while (0) @@ -3137,8 +3136,7 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, struct intel_sdvo_connector *intel_sdvo_connector, struct intel_sdvo_enhancements_reply enhancements) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); - struct drm_device *dev = intel_sdvo->base.base.dev; + struct intel_display *display = to_intel_display(&intel_sdvo->base); struct drm_connector *connector = &intel_sdvo_connector->base.base; struct drm_connector_state *conn_state = connector->state; struct intel_sdvo_connector_state *sdvo_state = @@ -3161,7 +3159,7 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, intel_sdvo_connector->max_hscan = data_value[0]; intel_sdvo_connector->left = - drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]); + drm_property_create_range(display->drm, 0, "left_margin", 0, data_value[0]); if (!intel_sdvo_connector->left) return false; @@ -3169,13 +3167,13 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, intel_sdvo_connector->left, 0); intel_sdvo_connector->right = - drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]); + drm_property_create_range(display->drm, 0, "right_margin", 0, data_value[0]); if (!intel_sdvo_connector->right) return false; drm_object_attach_property(&connector->base, intel_sdvo_connector->right, 0); - drm_dbg_kms(&i915->drm, "h_overscan: max %d, default %d, current %d\n", + drm_dbg_kms(display->drm, "h_overscan: max %d, default %d, current %d\n", data_value[0], data_value[1], response); } @@ -3194,7 +3192,7 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, intel_sdvo_connector->max_vscan = data_value[0]; intel_sdvo_connector->top = - drm_property_create_range(dev, 0, + drm_property_create_range(display->drm, 0, "top_margin", 0, data_value[0]); if (!intel_sdvo_connector->top) return false; @@ -3203,14 +3201,14 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, intel_sdvo_connector->top, 0); intel_sdvo_connector->bottom = - drm_property_create_range(dev, 0, + drm_property_create_range(display->drm, 0, "bottom_margin", 0, data_value[0]); if (!intel_sdvo_connector->bottom) return false; drm_object_attach_property(&connector->base, intel_sdvo_connector->bottom, 0); - drm_dbg_kms(&i915->drm, "v_overscan: max %d, default %d, current %d\n", + drm_dbg_kms(display->drm, "v_overscan: max %d, default %d, current %d\n", data_value[0], data_value[1], response); } @@ -3233,13 +3231,13 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, sdvo_state->tv.dot_crawl = response & 0x1; intel_sdvo_connector->dot_crawl = - drm_property_create_range(dev, 0, "dot_crawl", 0, 1); + drm_property_create_range(display->drm, 0, "dot_crawl", 0, 1); if (!intel_sdvo_connector->dot_crawl) return false; drm_object_attach_property(&connector->base, intel_sdvo_connector->dot_crawl, 0); - drm_dbg_kms(&i915->drm, "dot crawl: current %d\n", response); + drm_dbg_kms(display->drm, "dot crawl: current %d\n", response); } return true; @@ -3250,7 +3248,7 @@ intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo, struct intel_sdvo_connector *intel_sdvo_connector, struct intel_sdvo_enhancements_reply enhancements) { - struct drm_device *dev = intel_sdvo->base.base.dev; + struct intel_display *display = to_intel_display(&intel_sdvo->base); struct drm_connector *connector = &intel_sdvo_connector->base.base; u16 response, data_value[2]; @@ -3264,7 +3262,7 @@ intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo, static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, struct intel_sdvo_connector *intel_sdvo_connector) { - struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + struct intel_display *display = to_intel_display(&intel_sdvo->base); union { struct intel_sdvo_enhancements_reply reply; u16 response; @@ -3276,7 +3274,7 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, &enhancements, sizeof(enhancements)) || enhancements.response == 0) { - drm_dbg_kms(&i915->drm, "No enhancement is supported\n"); + drm_dbg_kms(display->drm, "No enhancement is supported\n"); return true; } @@ -3351,8 +3349,8 @@ static int intel_sdvo_init_ddc_proxy(struct intel_sdvo_ddc *ddc, struct intel_sdvo *sdvo, int ddc_bus) { - struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev); - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct intel_display *display = to_intel_display(&sdvo->base); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); ddc->sdvo = sdvo; ddc->ddc_bus = ddc_bus; @@ -3368,25 +3366,26 @@ intel_sdvo_init_ddc_proxy(struct intel_sdvo_ddc *ddc, return i2c_add_adapter(&ddc->ddc); } -static bool is_sdvo_port_valid(struct drm_i915_private *dev_priv, enum port port) +static bool is_sdvo_port_valid(struct intel_display *display, enum port port) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + if (HAS_PCH_SPLIT(dev_priv)) return port == PORT_B; else return port == PORT_B || port == PORT_C; } -static bool assert_sdvo_port_valid(struct drm_i915_private *dev_priv, - enum port port) +static bool assert_sdvo_port_valid(struct intel_display *display, enum port port) { - return !drm_WARN(&dev_priv->drm, !is_sdvo_port_valid(dev_priv, port), + return !drm_WARN(display->drm, !is_sdvo_port_valid(display, port), "Platform does not support SDVO %c\n", port_name(port)); } -bool intel_sdvo_init(struct drm_i915_private *dev_priv, +bool intel_sdvo_init(struct intel_display *display, i915_reg_t sdvo_reg, enum port port) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *intel_encoder; struct intel_sdvo *intel_sdvo; int i; @@ -3394,7 +3393,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, if (!assert_port_valid(display, port)) return false; - if (!assert_sdvo_port_valid(dev_priv, port)) + if (!assert_sdvo_port_valid(display, port)) return false; intel_sdvo = kzalloc(sizeof(*intel_sdvo), GFP_KERNEL); @@ -3407,7 +3406,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER; intel_encoder->port = port; - drm_encoder_init(&dev_priv->drm, &intel_encoder->base, + drm_encoder_init(display->drm, &intel_encoder->base, &intel_sdvo_enc_funcs, 0, "SDVO %c", port_name(port)); @@ -3421,7 +3420,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, u8 byte; if (!intel_sdvo_read_byte(intel_sdvo, i, &byte)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "No SDVO device found on %s\n", SDVO_NAME(intel_sdvo)); goto err; @@ -3459,7 +3458,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, } if (!intel_sdvo_output_setup(intel_sdvo)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "SDVO output failed to setup on %s\n", SDVO_NAME(intel_sdvo)); /* Output_setup can leave behind connectors! */ @@ -3496,7 +3495,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, &intel_sdvo->pixel_clock_max)) goto err_output; - drm_dbg_kms(&dev_priv->drm, "%s device VID/DID: %02X:%02X.%02X, " + drm_dbg_kms(display->drm, "%s device VID/DID: %02X:%02X.%02X, " "clock range %dMHz - %dMHz, " "num inputs: %d, " "output 1: %c, output 2: %c\n", diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.h b/drivers/gpu/drm/i915/display/intel_sdvo.h index d1815b4103d41..1a9e40fdd8a8f 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.h +++ b/drivers/gpu/drm/i915/display/intel_sdvo.h @@ -10,22 +10,22 @@ #include "i915_reg_defs.h" -struct drm_i915_private; enum pipe; enum port; +struct intel_display; #ifdef I915 -bool intel_sdvo_port_enabled(struct drm_i915_private *dev_priv, +bool intel_sdvo_port_enabled(struct intel_display *display, i915_reg_t sdvo_reg, enum pipe *pipe); -bool intel_sdvo_init(struct drm_i915_private *dev_priv, +bool intel_sdvo_init(struct intel_display *display, i915_reg_t reg, enum port port); #else -static inline bool intel_sdvo_port_enabled(struct drm_i915_private *dev_priv, +static inline bool intel_sdvo_port_enabled(struct intel_display *display, i915_reg_t sdvo_reg, enum pipe *pipe) { return false; } -static inline bool intel_sdvo_init(struct drm_i915_private *dev_priv, +static inline bool intel_sdvo_init(struct intel_display *display, i915_reg_t reg, enum port port) { return false; From a580ed17f3ba86bc1b031fca8ba53aab7f4f5d6e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:38 +0200 Subject: [PATCH 219/284] drm/i915/display: convert intel_cpu_transcoder_mode_valid() to intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert the intel_cpu_transcoder_mode_valid()() helper to struct intel_display, allowing further conversions elsewhere. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/f9246a00a2e7aabaffb86f863915a4307e1fd3f8.1739378095.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 4 ++-- drivers/gpu/drm/i915/display/intel_crt.c | 2 +- drivers/gpu/drm/i915/display/intel_display.c | 6 +++--- drivers/gpu/drm/i915/display/intel_display.h | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- drivers/gpu/drm/i915/display/intel_dvo.c | 6 +++--- drivers/gpu/drm/i915/display/intel_hdmi.c | 2 +- drivers/gpu/drm/i915/display/intel_lvds.c | 6 +++--- drivers/gpu/drm/i915/display/intel_sdvo.c | 3 +-- drivers/gpu/drm/i915/display/intel_tv.c | 3 +-- drivers/gpu/drm/i915/display/vlv_dsi.c | 6 +++--- 12 files changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index d6a4114c3e0ba..c2acf3151f2f8 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1460,10 +1460,10 @@ static void gen11_dsi_post_disable(struct intel_atomic_state *state, static enum drm_mode_status gen11_dsi_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct drm_i915_private *i915 = to_i915(connector->dev); + struct intel_display *display = to_intel_display(connector->dev); enum drm_mode_status status; - status = intel_cpu_transcoder_mode_valid(i915, mode); + status = intel_cpu_transcoder_mode_valid(display, mode); if (status != MODE_OK) return status; diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index 10c16ff25fe0d..c2945c6f8de51 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -360,7 +360,7 @@ intel_crt_mode_valid(struct drm_connector *connector, enum drm_mode_status status; int max_clock; - status = intel_cpu_transcoder_mode_valid(dev_priv, mode); + status = intel_cpu_transcoder_mode_valid(display, mode); if (status != MODE_OK) return status; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ee241604a4265..650f79b73ea4b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8463,14 +8463,14 @@ enum drm_mode_status intel_mode_valid(struct drm_device *dev, return MODE_OK; } -enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *dev_priv, +enum drm_mode_status intel_cpu_transcoder_mode_valid(struct intel_display *display, const struct drm_display_mode *mode) { /* * Additional transcoder timing limits, * excluding BXT/GLK DSI transcoders. */ - if (DISPLAY_VER(dev_priv) >= 5) { + if (DISPLAY_VER(display) >= 5) { if (mode->hdisplay < 64 || mode->htotal - mode->hdisplay < 32) return MODE_H_ILLEGAL; @@ -8489,7 +8489,7 @@ enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *de * Cantiga+ cannot handle modes with a hsync front porch of 0. * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw. */ - if ((DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) && + if ((DISPLAY_VER(display) >= 5 || display->platform.g4x) && mode->hsync_start == mode->hdisplay) return MODE_H_ILLEGAL; diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 9439da737f5bc..08e28ea179d29 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -428,7 +428,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, const struct drm_display_mode *mode, int num_joined_pipes); enum drm_mode_status -intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915, +intel_cpu_transcoder_mode_valid(struct intel_display *display, const struct drm_display_mode *mode); enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port); bool is_trans_port_sync_mode(const struct intel_crtc_state *state); diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0fb622c8110c3..fd5e4b5e69b8b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1407,7 +1407,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, bool dsc = false; int num_joined_pipes; - status = intel_cpu_transcoder_mode_valid(dev_priv, mode); + status = intel_cpu_transcoder_mode_valid(display, mode); if (status != MODE_OK) return status; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 411b7322d460b..235b2ae81ab63 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1481,7 +1481,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, return 0; } - *status = intel_cpu_transcoder_mode_valid(i915, mode); + *status = intel_cpu_transcoder_mode_valid(display, mode); if (*status != MODE_OK) return 0; diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c index c4888e6f52a18..0e5728dc09b2a 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo.c +++ b/drivers/gpu/drm/i915/display/intel_dvo.c @@ -219,16 +219,16 @@ static enum drm_mode_status intel_dvo_mode_valid(struct drm_connector *_connector, struct drm_display_mode *mode) { + struct intel_display *display = to_intel_display(_connector->dev); struct intel_connector *connector = to_intel_connector(_connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_dvo *intel_dvo = intel_attached_dvo(connector); const struct drm_display_mode *fixed_mode = intel_panel_fixed_mode(connector, mode); - int max_dotclk = to_i915(connector->base.dev)->display.cdclk.max_dotclk_freq; + int max_dotclk = display->cdclk.max_dotclk_freq; int target_clock = mode->clock; enum drm_mode_status status; - status = intel_cpu_transcoder_mode_valid(i915, mode); + status = intel_cpu_transcoder_mode_valid(display, mode); if (status != MODE_OK) return status; diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 0488999d079c2..0b451073c3771 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2023,7 +2023,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector, bool ycbcr_420_only; enum intel_output_format sink_format; - status = intel_cpu_transcoder_mode_valid(dev_priv, mode); + status = intel_cpu_transcoder_mode_valid(display, mode); if (status != MODE_OK) return status; diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index c6644e8013646..12bbd7ec9d81f 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -394,14 +394,14 @@ static enum drm_mode_status intel_lvds_mode_valid(struct drm_connector *_connector, struct drm_display_mode *mode) { + struct intel_display *display = to_intel_display(_connector->dev); struct intel_connector *connector = to_intel_connector(_connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); const struct drm_display_mode *fixed_mode = intel_panel_fixed_mode(connector, mode); - int max_pixclk = to_i915(connector->base.dev)->display.cdclk.max_dotclk_freq; + int max_pixclk = display->cdclk.max_dotclk_freq; enum drm_mode_status status; - status = intel_cpu_transcoder_mode_valid(i915, mode); + status = intel_cpu_transcoder_mode_valid(display, mode); if (status != MODE_OK) return status; diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index 30f52a3091cd5..efb439f1f6a03 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -1943,7 +1943,6 @@ intel_sdvo_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *i915 = to_i915(connector->dev); struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector)); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); @@ -1952,7 +1951,7 @@ intel_sdvo_mode_valid(struct drm_connector *connector, enum drm_mode_status status; int clock = mode->clock; - status = intel_cpu_transcoder_mode_valid(i915, mode); + status = intel_cpu_transcoder_mode_valid(display, mode); if (status != MODE_OK) return status; diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c index d71994472d058..5964d1279a41e 100644 --- a/drivers/gpu/drm/i915/display/intel_tv.c +++ b/drivers/gpu/drm/i915/display/intel_tv.c @@ -960,12 +960,11 @@ intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *i915 = to_i915(connector->dev); const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state); int max_dotclk = display->cdclk.max_dotclk_freq; enum drm_mode_status status; - status = intel_cpu_transcoder_mode_valid(i915, mode); + status = intel_cpu_transcoder_mode_valid(display, mode); if (status != MODE_OK) return status; diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index d5e135b7a254c..03ba63c0032b4 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -1543,12 +1543,12 @@ static const struct drm_encoder_funcs intel_dsi_funcs = { static enum drm_mode_status vlv_dsi_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct drm_i915_private *i915 = to_i915(connector->dev); + struct intel_display *display = to_intel_display(connector->dev); - if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { + if (display->platform.valleyview || display->platform.cherryview) { enum drm_mode_status status; - status = intel_cpu_transcoder_mode_valid(i915, mode); + status = intel_cpu_transcoder_mode_valid(display, mode); if (status != MODE_OK) return status; } From 010d150a9183b3e75ff50b96aa9df397423f8c12 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:39 +0200 Subject: [PATCH 220/284] drm/i915/display: convert intel_mode_valid_max_plane_size() to intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert the intel_mode_valid_max_plane_size() helper to struct intel_display, allowing further conversions elsewhere. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/6e7810c793ecc8ff6a31569830bf162156245668.1739378095.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 8 ++++---- drivers/gpu/drm/i915/display/intel_display.h | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 3 +-- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 +-- drivers/gpu/drm/i915/display/intel_dsi.c | 8 ++++---- drivers/gpu/drm/i915/display/intel_hdmi.c | 3 +-- 6 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 650f79b73ea4b..3b895a760d8b5 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8497,7 +8497,7 @@ enum drm_mode_status intel_cpu_transcoder_mode_valid(struct intel_display *displ } enum drm_mode_status -intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, +intel_mode_valid_max_plane_size(struct intel_display *display, const struct drm_display_mode *mode, int num_joined_pipes) { @@ -8507,7 +8507,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, * intel_mode_valid() should be * sufficient on older platforms. */ - if (DISPLAY_VER(dev_priv) < 9) + if (DISPLAY_VER(display) < 9) return MODE_OK; /* @@ -8515,10 +8515,10 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, * plane so let's not advertize modes that are * too big for that. */ - if (DISPLAY_VER(dev_priv) >= 30) { + if (DISPLAY_VER(display) >= 30) { plane_width_max = 6144 * num_joined_pipes; plane_height_max = 4800; - } else if (DISPLAY_VER(dev_priv) >= 11) { + } else if (DISPLAY_VER(display) >= 11) { plane_width_max = 5120 * num_joined_pipes; plane_height_max = 4320; } else { diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 08e28ea179d29..f702425df305f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -424,7 +424,7 @@ void intel_link_compute_m_n(u16 bpp, int nlanes, u32 intel_plane_fb_max_stride(struct drm_device *drm, u32 pixel_format, u64 modifier); enum drm_mode_status -intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, +intel_mode_valid_max_plane_size(struct intel_display *display, const struct drm_display_mode *mode, int num_joined_pipes); enum drm_mode_status diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index fd5e4b5e69b8b..bee8e107ac2e9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1396,7 +1396,6 @@ intel_dp_mode_valid(struct drm_connector *_connector, struct intel_display *display = to_intel_display(_connector->dev); struct intel_connector *connector = to_intel_connector(_connector); struct intel_dp *intel_dp = intel_attached_dp(connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); const struct drm_display_mode *fixed_mode; int target_clock = mode->clock; int max_rate, mode_rate, max_lanes, max_link_clock; @@ -1496,7 +1495,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, if (status != MODE_OK) return status; - return intel_mode_valid_max_plane_size(dev_priv, mode, num_joined_pipes); + return intel_mode_valid_max_plane_size(display, mode, num_joined_pipes); } bool intel_dp_source_supports_tps3(struct intel_display *display) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 235b2ae81ab63..7749a6ab47982 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1462,7 +1462,6 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, { struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(connector); - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_dp *intel_dp = connector->mst_port; struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; struct drm_dp_mst_port *port = connector->port; @@ -1565,7 +1564,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, return 0; } - *status = intel_mode_valid_max_plane_size(i915, mode, num_joined_pipes); + *status = intel_mode_valid_max_plane_size(display, mode, num_joined_pipes); return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c index 0be46c6c9611f..56a5a517496d0 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi.c +++ b/drivers/gpu/drm/i915/display/intel_dsi.c @@ -60,14 +60,14 @@ int intel_dsi_get_modes(struct drm_connector *connector) enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_display *display = to_intel_display(connector->dev); struct intel_connector *intel_connector = to_intel_connector(connector); const struct drm_display_mode *fixed_mode = intel_panel_fixed_mode(intel_connector, mode); - int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq; + int max_dotclk = display->cdclk.max_dotclk_freq; enum drm_mode_status status; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); status = intel_panel_mode_valid(intel_connector, mode); if (status != MODE_OK) @@ -76,7 +76,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector, if (fixed_mode->clock > max_dotclk) return MODE_CLOCK_HIGH; - return intel_mode_valid_max_plane_size(dev_priv, mode, 1); + return intel_mode_valid_max_plane_size(display, mode, 1); } struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi, diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 0b451073c3771..7ffc76a2ec1ed 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2015,7 +2015,6 @@ intel_hdmi_mode_valid(struct drm_connector *connector, { struct intel_display *display = to_intel_display(connector->dev); struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector)); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum drm_mode_status status; int clock = mode->clock; int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq; @@ -2068,7 +2067,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector, return status; } - return intel_mode_valid_max_plane_size(dev_priv, mode, 1); + return intel_mode_valid_max_plane_size(display, mode, 1); } bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state, From 82fafa7d58fb646bcac6a0155912eb153ea741d3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:40 +0200 Subject: [PATCH 221/284] drm/i915/dsi: convert platform checks to display->platform. style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are stragglers from a time the display->platform mechanism didn't exist. Finish the conversion. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/493e4c550f9c515e2e82df1afd8a74a24156e76e.1739378096.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index c2acf3151f2f8..0449a9d639d5f 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -345,7 +345,6 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; int afe_clk_khz; @@ -354,7 +353,7 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder, afe_clk_khz = afe_clk(encoder, crtc_state); - if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) { + if (display->platform.alderlake_s || display->platform.alderlake_p) { theo_word_clk = DIV_ROUND_UP(afe_clk_khz, 8 * DSI_MAX_ESC_CLK); act_word_clk = max(3, theo_word_clk + (theo_word_clk + 1) % 2); esc_clk_div_m = act_word_clk * 8; @@ -375,7 +374,7 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder, intel_de_posting_read(display, ICL_DPHY_ESC_CLK_DIV(port)); } - if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) { + if (display->platform.alderlake_s || display->platform.alderlake_p) { for_each_dsi_port(port, intel_dsi->ports) { intel_de_write(display, ADL_MIPIO_DW(port, 8), esc_clk_div_m_phy & TX_ESC_CLK_DIV_PHY); @@ -426,7 +425,6 @@ static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum phy phy; u32 tmp; @@ -451,7 +449,7 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) intel_de_write(display, ICL_PORT_TX_DW2_GRP(phy), tmp); /* For EHL, TGL, set latency optimization for PCS_DW1 lanes */ - if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv) || + if (display->platform.jasperlake || display->platform.elkhartlake || (DISPLAY_VER(display) >= 12)) { intel_de_rmw(display, ICL_PORT_PCS_DW1_AUX(phy), LATENCY_OPTIM_MASK, LATENCY_OPTIM_VAL(0)); @@ -533,7 +531,6 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; enum phy phy; @@ -563,7 +560,7 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder, } } - if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) { + if (display->platform.jasperlake || display->platform.elkhartlake) { for_each_dsi_phy(phy, intel_dsi->phys) intel_de_rmw(display, ICL_DPHY_CHKN(phy), 0, ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP); From 9e1673db9871deb2cb6281b81e1bf93fb46946b4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:41 +0200 Subject: [PATCH 222/284] drm/i915/combo-phy: convert intel_combo_phy.[ch] to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of intel_combo_phy.[ch] to struct intel_display, along with intel_phy_is_combo() in intel_display.c. Drive-by convert some drm_dbg() to drm_dbg_kms() while at it. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c2e0a6294a8eaa4c16632881edc4f2d23c576101.1739378096.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 6 +- .../gpu/drm/i915/display/intel_combo_phy.c | 180 +++++++++--------- .../gpu/drm/i915/display/intel_combo_phy.h | 8 +- drivers/gpu/drm/i915/display/intel_ddi.c | 4 +- drivers/gpu/drm/i915/display/intel_display.c | 14 +- drivers/gpu/drm/i915/display/intel_display.h | 2 +- .../drm/i915/display/intel_display_power.c | 5 +- .../i915/display/intel_display_power_well.c | 3 +- 8 files changed, 109 insertions(+), 113 deletions(-) diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 0449a9d639d5f..a3e6e14a5e77f 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -31,8 +31,8 @@ #include #include -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "icl_dsi.h" #include "icl_dsi_regs.h" #include "intel_atomic.h" @@ -413,12 +413,12 @@ static void gen11_dsi_enable_io_power(struct intel_encoder *encoder) static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum phy phy; for_each_dsi_phy(phy, intel_dsi->phys) - intel_combo_phy_power_up_lanes(dev_priv, phy, true, + intel_combo_phy_power_up_lanes(display, phy, true, intel_dsi->lane_count, false); } diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c index 4fbe2e3542ca8..17eea244cc833 100644 --- a/drivers/gpu/drm/i915/display/intel_combo_phy.c +++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c @@ -3,20 +3,20 @@ * Copyright © 2018 Intel Corporation */ -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_combo_phy.h" #include "intel_combo_phy_regs.h" #include "intel_de.h" #include "intel_display_types.h" -#define for_each_combo_phy(__dev_priv, __phy) \ +#define for_each_combo_phy(__display, __phy) \ for ((__phy) = PHY_A; (__phy) < I915_MAX_PHYS; (__phy)++) \ - for_each_if(intel_phy_is_combo(__dev_priv, __phy)) + for_each_if(intel_phy_is_combo(__display, __phy)) -#define for_each_combo_phy_reverse(__dev_priv, __phy) \ +#define for_each_combo_phy_reverse(__display, __phy) \ for ((__phy) = I915_MAX_PHYS; (__phy)-- > PHY_A;) \ - for_each_if(intel_phy_is_combo(__dev_priv, __phy)) + for_each_if(intel_phy_is_combo(__display, __phy)) enum { PROCMON_0_85V_DOT_0, @@ -53,11 +53,11 @@ static const struct icl_procmon { }; static const struct icl_procmon * -icl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy) +icl_get_procmon_ref_values(struct intel_display *display, enum phy phy) { u32 val; - val = intel_de_read(dev_priv, ICL_PORT_COMP_DW3(phy)); + val = intel_de_read(display, ICL_PORT_COMP_DW3(phy)); switch (val & (PROCESS_INFO_MASK | VOLTAGE_INFO_MASK)) { default: MISSING_CASE(val); @@ -75,57 +75,57 @@ icl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy) } } -static void icl_set_procmon_ref_values(struct drm_i915_private *dev_priv, +static void icl_set_procmon_ref_values(struct intel_display *display, enum phy phy) { const struct icl_procmon *procmon; - procmon = icl_get_procmon_ref_values(dev_priv, phy); + procmon = icl_get_procmon_ref_values(display, phy); - intel_de_rmw(dev_priv, ICL_PORT_COMP_DW1(phy), + intel_de_rmw(display, ICL_PORT_COMP_DW1(phy), (0xff << 16) | 0xff, procmon->dw1); - intel_de_write(dev_priv, ICL_PORT_COMP_DW9(phy), procmon->dw9); - intel_de_write(dev_priv, ICL_PORT_COMP_DW10(phy), procmon->dw10); + intel_de_write(display, ICL_PORT_COMP_DW9(phy), procmon->dw9); + intel_de_write(display, ICL_PORT_COMP_DW10(phy), procmon->dw10); } -static bool check_phy_reg(struct drm_i915_private *dev_priv, +static bool check_phy_reg(struct intel_display *display, enum phy phy, i915_reg_t reg, u32 mask, u32 expected_val) { - u32 val = intel_de_read(dev_priv, reg); + u32 val = intel_de_read(display, reg); if ((val & mask) != expected_val) { - drm_dbg(&dev_priv->drm, - "Combo PHY %c reg %08x state mismatch: " - "current %08x mask %08x expected %08x\n", - phy_name(phy), - reg.reg, val, mask, expected_val); + drm_dbg_kms(display->drm, + "Combo PHY %c reg %08x state mismatch: " + "current %08x mask %08x expected %08x\n", + phy_name(phy), + reg.reg, val, mask, expected_val); return false; } return true; } -static bool icl_verify_procmon_ref_values(struct drm_i915_private *dev_priv, +static bool icl_verify_procmon_ref_values(struct intel_display *display, enum phy phy) { const struct icl_procmon *procmon; bool ret; - procmon = icl_get_procmon_ref_values(dev_priv, phy); + procmon = icl_get_procmon_ref_values(display, phy); - ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy), + ret = check_phy_reg(display, phy, ICL_PORT_COMP_DW1(phy), (0xff << 16) | 0xff, procmon->dw1); - ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy), + ret &= check_phy_reg(display, phy, ICL_PORT_COMP_DW9(phy), -1U, procmon->dw9); - ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW10(phy), + ret &= check_phy_reg(display, phy, ICL_PORT_COMP_DW10(phy), -1U, procmon->dw10); return ret; } -static bool has_phy_misc(struct drm_i915_private *i915, enum phy phy) +static bool has_phy_misc(struct intel_display *display, enum phy phy) { /* * Some platforms only expect PHY_MISC to be programmed for PHY-A and @@ -136,32 +136,30 @@ static bool has_phy_misc(struct drm_i915_private *i915, enum phy phy) * that we program it for PHY A. */ - if (IS_ALDERLAKE_S(i915)) + if (display->platform.alderlake_s) return phy == PHY_A; - else if ((IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) || - IS_ROCKETLAKE(i915) || - IS_DG1(i915)) + else if ((display->platform.jasperlake || display->platform.elkhartlake) || + display->platform.rocketlake || + display->platform.dg1) return phy < PHY_C; return true; } -static bool icl_combo_phy_enabled(struct drm_i915_private *dev_priv, +static bool icl_combo_phy_enabled(struct intel_display *display, enum phy phy) { /* The PHY C added by EHL has no PHY_MISC register */ - if (!has_phy_misc(dev_priv, phy)) - return intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy)) & COMP_INIT; + if (!has_phy_misc(display, phy)) + return intel_de_read(display, ICL_PORT_COMP_DW0(phy)) & COMP_INIT; else - return !(intel_de_read(dev_priv, ICL_PHY_MISC(phy)) & + return !(intel_de_read(display, ICL_PHY_MISC(phy)) & ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN) && - (intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy)) & COMP_INIT); + (intel_de_read(display, ICL_PORT_COMP_DW0(phy)) & COMP_INIT); } -static bool ehl_vbt_ddi_d_present(struct drm_i915_private *i915) +static bool ehl_vbt_ddi_d_present(struct intel_display *display) { - struct intel_display *display = &i915->display; - bool ddi_a_present = intel_bios_is_port_present(display, PORT_A); bool ddi_d_present = intel_bios_is_port_present(display, PORT_D); bool dsi_present = intel_bios_is_dsi_present(display, NULL); @@ -181,13 +179,13 @@ static bool ehl_vbt_ddi_d_present(struct drm_i915_private *i915) * in the log and let the internal display win. */ if (ddi_d_present) - drm_err(&i915->drm, + drm_err(display->drm, "VBT claims to have both internal and external displays on PHY A. Configuring for internal.\n"); return false; } -static bool phy_is_master(struct drm_i915_private *dev_priv, enum phy phy) +static bool phy_is_master(struct intel_display *display, enum phy phy) { /* * Certain PHYs are connected to compensation resistors and act @@ -207,64 +205,64 @@ static bool phy_is_master(struct drm_i915_private *dev_priv, enum phy phy) */ if (phy == PHY_A) return true; - else if (IS_ALDERLAKE_S(dev_priv)) + else if (display->platform.alderlake_s) return phy == PHY_D; - else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) + else if (display->platform.dg1 || display->platform.rocketlake) return phy == PHY_C; return false; } -static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv, +static bool icl_combo_phy_verify_state(struct intel_display *display, enum phy phy) { bool ret = true; u32 expected_val = 0; - if (!icl_combo_phy_enabled(dev_priv, phy)) + if (!icl_combo_phy_enabled(display, phy)) return false; - if (DISPLAY_VER(dev_priv) >= 12) { - ret &= check_phy_reg(dev_priv, phy, ICL_PORT_TX_DW8_LN(0, phy), + if (DISPLAY_VER(display) >= 12) { + ret &= check_phy_reg(display, phy, ICL_PORT_TX_DW8_LN(0, phy), ICL_PORT_TX_DW8_ODCC_CLK_SEL | ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_MASK, ICL_PORT_TX_DW8_ODCC_CLK_SEL | ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_DIV2); - ret &= check_phy_reg(dev_priv, phy, ICL_PORT_PCS_DW1_LN(0, phy), + ret &= check_phy_reg(display, phy, ICL_PORT_PCS_DW1_LN(0, phy), DCC_MODE_SELECT_MASK, RUN_DCC_ONCE); } - ret &= icl_verify_procmon_ref_values(dev_priv, phy); + ret &= icl_verify_procmon_ref_values(display, phy); - if (phy_is_master(dev_priv, phy)) { - ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW8(phy), + if (phy_is_master(display, phy)) { + ret &= check_phy_reg(display, phy, ICL_PORT_COMP_DW8(phy), IREFGEN, IREFGEN); - if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) { - if (ehl_vbt_ddi_d_present(dev_priv)) + if (display->platform.jasperlake || display->platform.elkhartlake) { + if (ehl_vbt_ddi_d_present(display)) expected_val = ICL_PHY_MISC_MUX_DDID; - ret &= check_phy_reg(dev_priv, phy, ICL_PHY_MISC(phy), + ret &= check_phy_reg(display, phy, ICL_PHY_MISC(phy), ICL_PHY_MISC_MUX_DDID, expected_val); } } - ret &= check_phy_reg(dev_priv, phy, ICL_PORT_CL_DW5(phy), + ret &= check_phy_reg(display, phy, ICL_PORT_CL_DW5(phy), CL_POWER_DOWN_ENABLE, CL_POWER_DOWN_ENABLE); return ret; } -void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv, +void intel_combo_phy_power_up_lanes(struct intel_display *display, enum phy phy, bool is_dsi, int lane_count, bool lane_reversal) { u8 lane_mask; if (is_dsi) { - drm_WARN_ON(&dev_priv->drm, lane_reversal); + drm_WARN_ON(display->drm, lane_reversal); switch (lane_count) { case 1: @@ -302,28 +300,28 @@ void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv, } } - intel_de_rmw(dev_priv, ICL_PORT_CL_DW10(phy), + intel_de_rmw(display, ICL_PORT_CL_DW10(phy), PWR_DOWN_LN_MASK, lane_mask); } -static void icl_combo_phys_init(struct drm_i915_private *dev_priv) +static void icl_combo_phys_init(struct intel_display *display) { enum phy phy; - for_each_combo_phy(dev_priv, phy) { + for_each_combo_phy(display, phy) { const struct icl_procmon *procmon; u32 val; - if (icl_combo_phy_verify_state(dev_priv, phy)) + if (icl_combo_phy_verify_state(display, phy)) continue; - procmon = icl_get_procmon_ref_values(dev_priv, phy); + procmon = icl_get_procmon_ref_values(display, phy); - drm_dbg(&dev_priv->drm, - "Initializing combo PHY %c (Voltage/Process Info : %s)\n", - phy_name(phy), procmon->name); + drm_dbg_kms(display->drm, + "Initializing combo PHY %c (Voltage/Process Info : %s)\n", + phy_name(phy), procmon->name); - if (!has_phy_misc(dev_priv, phy)) + if (!has_phy_misc(display, phy)) goto skip_phy_misc; /* @@ -334,84 +332,84 @@ static void icl_combo_phys_init(struct drm_i915_private *dev_priv) * based on whether our VBT indicates the presence of any * "internal" child devices. */ - val = intel_de_read(dev_priv, ICL_PHY_MISC(phy)); - if ((IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) && + val = intel_de_read(display, ICL_PHY_MISC(phy)); + if ((display->platform.jasperlake || display->platform.elkhartlake) && phy == PHY_A) { val &= ~ICL_PHY_MISC_MUX_DDID; - if (ehl_vbt_ddi_d_present(dev_priv)) + if (ehl_vbt_ddi_d_present(display)) val |= ICL_PHY_MISC_MUX_DDID; } val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN; - intel_de_write(dev_priv, ICL_PHY_MISC(phy), val); + intel_de_write(display, ICL_PHY_MISC(phy), val); skip_phy_misc: - if (DISPLAY_VER(dev_priv) >= 12) { - val = intel_de_read(dev_priv, ICL_PORT_TX_DW8_LN(0, phy)); + if (DISPLAY_VER(display) >= 12) { + val = intel_de_read(display, ICL_PORT_TX_DW8_LN(0, phy)); val &= ~ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_MASK; val |= ICL_PORT_TX_DW8_ODCC_CLK_SEL; val |= ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_DIV2; - intel_de_write(dev_priv, ICL_PORT_TX_DW8_GRP(phy), val); + intel_de_write(display, ICL_PORT_TX_DW8_GRP(phy), val); - val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, phy)); + val = intel_de_read(display, ICL_PORT_PCS_DW1_LN(0, phy)); val &= ~DCC_MODE_SELECT_MASK; val |= RUN_DCC_ONCE; - intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), val); + intel_de_write(display, ICL_PORT_PCS_DW1_GRP(phy), val); } - icl_set_procmon_ref_values(dev_priv, phy); + icl_set_procmon_ref_values(display, phy); - if (phy_is_master(dev_priv, phy)) - intel_de_rmw(dev_priv, ICL_PORT_COMP_DW8(phy), + if (phy_is_master(display, phy)) + intel_de_rmw(display, ICL_PORT_COMP_DW8(phy), 0, IREFGEN); - intel_de_rmw(dev_priv, ICL_PORT_COMP_DW0(phy), 0, COMP_INIT); - intel_de_rmw(dev_priv, ICL_PORT_CL_DW5(phy), + intel_de_rmw(display, ICL_PORT_COMP_DW0(phy), 0, COMP_INIT); + intel_de_rmw(display, ICL_PORT_CL_DW5(phy), 0, CL_POWER_DOWN_ENABLE); } } -static void icl_combo_phys_uninit(struct drm_i915_private *dev_priv) +static void icl_combo_phys_uninit(struct intel_display *display) { enum phy phy; - for_each_combo_phy_reverse(dev_priv, phy) { + for_each_combo_phy_reverse(display, phy) { if (phy == PHY_A && - !icl_combo_phy_verify_state(dev_priv, phy)) { - if (IS_TIGERLAKE(dev_priv) || IS_DG1(dev_priv)) { + !icl_combo_phy_verify_state(display, phy)) { + if (display->platform.tigerlake || display->platform.dg1) { /* * A known problem with old ifwi: * https://gitlab.freedesktop.org/drm/intel/-/issues/2411 * Suppress the warning for CI. Remove ASAP! */ - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Combo PHY %c HW state changed unexpectedly\n", phy_name(phy)); } else { - drm_warn(&dev_priv->drm, + drm_warn(display->drm, "Combo PHY %c HW state changed unexpectedly\n", phy_name(phy)); } } - if (!has_phy_misc(dev_priv, phy)) + if (!has_phy_misc(display, phy)) goto skip_phy_misc; - intel_de_rmw(dev_priv, ICL_PHY_MISC(phy), 0, + intel_de_rmw(display, ICL_PHY_MISC(phy), 0, ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN); skip_phy_misc: - intel_de_rmw(dev_priv, ICL_PORT_COMP_DW0(phy), COMP_INIT, 0); + intel_de_rmw(display, ICL_PORT_COMP_DW0(phy), COMP_INIT, 0); } } -void intel_combo_phy_init(struct drm_i915_private *i915) +void intel_combo_phy_init(struct intel_display *display) { - icl_combo_phys_init(i915); + icl_combo_phys_init(display); } -void intel_combo_phy_uninit(struct drm_i915_private *i915) +void intel_combo_phy_uninit(struct intel_display *display) { - icl_combo_phys_uninit(i915); + icl_combo_phys_uninit(display); } diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.h b/drivers/gpu/drm/i915/display/intel_combo_phy.h index 660886f86c596..3f5dba78e5332 100644 --- a/drivers/gpu/drm/i915/display/intel_combo_phy.h +++ b/drivers/gpu/drm/i915/display/intel_combo_phy.h @@ -8,12 +8,12 @@ #include -struct drm_i915_private; enum phy; +struct intel_display; -void intel_combo_phy_init(struct drm_i915_private *dev_priv); -void intel_combo_phy_uninit(struct drm_i915_private *dev_priv); -void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv, +void intel_combo_phy_init(struct intel_display *display); +void intel_combo_phy_uninit(struct intel_display *display); +void intel_combo_phy_power_up_lanes(struct intel_display *display, enum phy phy, bool is_dsi, int lane_count, bool lane_reversal); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 3cb50a163bf97..69678220a8ca2 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2437,13 +2437,13 @@ static void intel_ddi_disable_fec(struct intel_encoder *encoder, static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); if (intel_encoder_is_combo(encoder)) { enum phy phy = intel_encoder_to_phy(encoder); - intel_combo_phy_power_up_lanes(i915, phy, false, + intel_combo_phy_power_up_lanes(display, phy, false, crtc_state->lane_count, dig_port->lane_reversal); } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3b895a760d8b5..6876962fdba0b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1995,17 +1995,17 @@ static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) } /* Prefer intel_encoder_is_combo() */ -bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy) +bool intel_phy_is_combo(struct intel_display *display, enum phy phy) { if (phy == PHY_NONE) return false; - else if (IS_ALDERLAKE_S(dev_priv)) + else if (display->platform.alderlake_s) return phy <= PHY_E; - else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) + else if (display->platform.dg1 || display->platform.rocketlake) return phy <= PHY_D; - else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) + else if (display->platform.jasperlake || display->platform.elkhartlake) return phy <= PHY_C; - else if (IS_ALDERLAKE_P(dev_priv) || IS_DISPLAY_VER(dev_priv, 11, 12)) + else if (display->platform.alderlake_p || IS_DISPLAY_VER(display, 11, 12)) return phy <= PHY_B; else /* @@ -2085,9 +2085,9 @@ enum phy intel_encoder_to_phy(struct intel_encoder *encoder) bool intel_encoder_is_combo(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - return intel_phy_is_combo(i915, intel_encoder_to_phy(encoder)); + return intel_phy_is_combo(display, intel_encoder_to_phy(encoder)); } bool intel_encoder_is_snps(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index f702425df305f..d4a7095887009 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -476,7 +476,7 @@ struct drm_display_mode * intel_encoder_current_mode(struct intel_encoder *encoder); void intel_encoder_get_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state); -bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy); +bool intel_phy_is_combo(struct intel_display *display, enum phy phy); bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy); bool intel_phy_is_snps(struct drm_i915_private *dev_priv, enum phy phy); enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index d93f43d145a96..396930937d985 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1651,7 +1651,7 @@ static void icl_display_core_init(struct intel_display *display, return; /* 2. Initialize all combo phys */ - intel_combo_phy_init(dev_priv); + intel_combo_phy_init(display); /* * 3. Enable Power Well 1 (PG1). @@ -1714,7 +1714,6 @@ static void icl_display_core_init(struct intel_display *display, static void icl_display_core_uninit(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; @@ -1747,7 +1746,7 @@ static void icl_display_core_uninit(struct intel_display *display) mutex_unlock(&power_domains->lock); /* 5. */ - intel_combo_phy_uninit(dev_priv); + intel_combo_phy_uninit(display); } static void chv_phy_control_init(struct intel_display *display) diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index 6fbb94c8bfb3c..5b60db597329c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -973,7 +973,6 @@ static void gen9_assert_dbuf_enabled(struct intel_display *display) void gen9_disable_dc_states(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_cdclk_config cdclk_config = {}; u32 old_state = power_domains->dc_state; @@ -1013,7 +1012,7 @@ void gen9_disable_dc_states(struct intel_display *display) * PHY's HW context for port B is lost after DC transitions, * so we need to restore it manually. */ - intel_combo_phy_init(dev_priv); + intel_combo_phy_init(display); } static void gen9_dc_off_power_well_enable(struct intel_display *display, From f414bb4f717ad5a9ff7ed374472b98200239a158 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:42 +0200 Subject: [PATCH 223/284] drm/i915/display: convert intel_fifo_underrun.[ch] to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of intel_fifo_underrun.[ch] to struct intel_display. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/682e667013e1726a6f2f78484b7e9618cee3b639.1739378096.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_crtc.c | 2 +- drivers/gpu/drm/i915/display/intel_display.c | 4 +- .../gpu/drm/i915/display/intel_display_irq.c | 18 ++-- .../drm/i915/display/intel_fifo_underrun.c | 93 ++++++++++--------- .../drm/i915/display/intel_fifo_underrun.h | 11 +-- .../drm/i915/display/intel_modeset_setup.c | 6 +- 6 files changed, 67 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index a1694e54a6f1f..d075f6d2961b0 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -328,7 +328,7 @@ int intel_crtc_init(struct intel_display *display, enum pipe pipe) } crtc->plane_ids_mask |= BIT(primary->id); - intel_init_fifo_underrun_reporting(dev_priv, crtc, false); + intel_init_fifo_underrun_reporting(display, crtc, false); for_each_sprite(display, pipe, sprite) { struct intel_plane *plane; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 6876962fdba0b..bb6e4f3b584a4 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7953,8 +7953,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) } /* Underruns don't always raise interrupts, so check manually */ - intel_check_cpu_fifo_underruns(dev_priv); - intel_check_pch_fifo_underruns(dev_priv); + intel_check_cpu_fifo_underruns(display); + intel_check_pch_fifo_underruns(display); if (state->modeset) intel_verify_planes(state); diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 0f68b0a34ca95..b8fcf74bd3acd 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -562,7 +562,7 @@ void i915_pipestat_irq_handler(struct drm_i915_private *dev_priv, i9xx_pipe_crc_irq_handler(dev_priv, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) - intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); + intel_cpu_fifo_underrun_irq_handler(display, pipe); } if (blc_event || (iir & I915_ASLE_INTERRUPT)) @@ -587,7 +587,7 @@ void i965_pipestat_irq_handler(struct drm_i915_private *dev_priv, i9xx_pipe_crc_irq_handler(dev_priv, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) - intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); + intel_cpu_fifo_underrun_irq_handler(display, pipe); } if (blc_event || (iir & I915_ASLE_INTERRUPT)) @@ -614,7 +614,7 @@ void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv, i9xx_pipe_crc_irq_handler(dev_priv, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) - intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); + intel_cpu_fifo_underrun_irq_handler(display, pipe); } if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) @@ -666,10 +666,10 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) "PCH transcoder CRC error interrupt\n"); if (pch_iir & SDE_TRANSA_FIFO_UNDER) - intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_A); + intel_pch_fifo_underrun_irq_handler(display, PIPE_A); if (pch_iir & SDE_TRANSB_FIFO_UNDER) - intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_B); + intel_pch_fifo_underrun_irq_handler(display, PIPE_B); } static void ivb_err_int_handler(struct drm_i915_private *dev_priv) @@ -683,7 +683,7 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv) for_each_pipe(dev_priv, pipe) { if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) - intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); + intel_cpu_fifo_underrun_irq_handler(display, pipe); if (err_int & ERR_INT_PIPE_CRC_DONE(pipe)) { if (IS_IVYBRIDGE(dev_priv)) @@ -707,7 +707,7 @@ static void cpt_serr_int_handler(struct drm_i915_private *dev_priv) for_each_pipe(dev_priv, pipe) if (serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pipe)) - intel_pch_fifo_underrun_irq_handler(dev_priv, pipe); + intel_pch_fifo_underrun_irq_handler(display, pipe); intel_de_write(display, SERR_INT, serr_int); } @@ -776,7 +776,7 @@ void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) flip_done_handler(dev_priv, pipe); if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe)) - intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); + intel_cpu_fifo_underrun_irq_handler(display, pipe); if (de_iir & DE_PIPE_CRC_DONE(pipe)) i9xx_pipe_crc_irq_handler(dev_priv, pipe); @@ -1228,7 +1228,7 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) hsw_pipe_crc_irq_handler(dev_priv, pipe); if (iir & GEN8_PIPE_FIFO_UNDERRUN) - intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); + intel_cpu_fifo_underrun_irq_handler(display, pipe); fault_errors = iir & gen8_de_pipe_fault_mask(dev_priv); if (fault_errors) diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c index cf70dab4881b3..14b00988a81f5 100644 --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c @@ -63,7 +63,7 @@ static bool ivb_can_enable_err_int(struct intel_display *display) lockdep_assert_held(&dev_priv->irq_lock); - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { crtc = intel_crtc_for_pipe(display, pipe); if (crtc->cpu_fifo_underrun_disabled) @@ -81,7 +81,7 @@ static bool cpt_can_enable_serr_int(struct intel_display *display) lockdep_assert_held(&dev_priv->irq_lock); - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { crtc = intel_crtc_for_pipe(display, pipe); if (crtc->pch_fifo_underrun_disabled) @@ -95,20 +95,20 @@ static void i9xx_check_fifo_underruns(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - i915_reg_t reg = PIPESTAT(dev_priv, crtc->pipe); + i915_reg_t reg = PIPESTAT(display, crtc->pipe); u32 enable_mask; lockdep_assert_held(&dev_priv->irq_lock); - if ((intel_de_read(dev_priv, reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0) + if ((intel_de_read(display, reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0) return; enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe); - intel_de_write(dev_priv, reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); - intel_de_posting_read(dev_priv, reg); + intel_de_write(display, reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); + intel_de_posting_read(display, reg); trace_intel_cpu_fifo_underrun(display, crtc->pipe); - drm_err(&dev_priv->drm, "pipe %c underrun\n", pipe_name(crtc->pipe)); + drm_err(display->drm, "pipe %c underrun\n", pipe_name(crtc->pipe)); } static void i9xx_set_fifo_underrun_reporting(struct intel_display *display, @@ -116,19 +116,19 @@ static void i9xx_set_fifo_underrun_reporting(struct intel_display *display, bool enable, bool old) { struct drm_i915_private *dev_priv = to_i915(display->drm); - i915_reg_t reg = PIPESTAT(dev_priv, pipe); + i915_reg_t reg = PIPESTAT(display, pipe); lockdep_assert_held(&dev_priv->irq_lock); if (enable) { u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); - intel_de_write(dev_priv, reg, + intel_de_write(display, reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); } else { - if (old && intel_de_read(dev_priv, reg) & PIPE_FIFO_UNDERRUN_STATUS) - drm_err(&dev_priv->drm, "pipe %c underrun\n", + if (old && intel_de_read(display, reg) & PIPE_FIFO_UNDERRUN_STATUS) + drm_err(display->drm, "pipe %c underrun\n", pipe_name(pipe)); } } @@ -151,18 +151,18 @@ static void ivb_check_fifo_underruns(struct intel_crtc *crtc) struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - u32 err_int = intel_de_read(dev_priv, GEN7_ERR_INT); + u32 err_int = intel_de_read(display, GEN7_ERR_INT); lockdep_assert_held(&dev_priv->irq_lock); if ((err_int & ERR_INT_FIFO_UNDERRUN(pipe)) == 0) return; - intel_de_write(dev_priv, GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); - intel_de_posting_read(dev_priv, GEN7_ERR_INT); + intel_de_write(display, GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); + intel_de_posting_read(display, GEN7_ERR_INT); trace_intel_cpu_fifo_underrun(display, pipe); - drm_err(&dev_priv->drm, "fifo underrun on pipe %c\n", pipe_name(pipe)); + drm_err(display->drm, "fifo underrun on pipe %c\n", pipe_name(pipe)); } static void ivb_set_fifo_underrun_reporting(struct intel_display *display, @@ -171,7 +171,7 @@ static void ivb_set_fifo_underrun_reporting(struct intel_display *display, { struct drm_i915_private *dev_priv = to_i915(display->drm); if (enable) { - intel_de_write(dev_priv, GEN7_ERR_INT, + intel_de_write(display, GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); if (!ivb_can_enable_err_int(display)) @@ -182,8 +182,8 @@ static void ivb_set_fifo_underrun_reporting(struct intel_display *display, ilk_disable_display_irq(dev_priv, DE_ERR_INT_IVB); if (old && - intel_de_read(dev_priv, GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) { - drm_err(&dev_priv->drm, + intel_de_read(display, GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) { + drm_err(display->drm, "uncleared fifo underrun on pipe %c\n", pipe_name(pipe)); } @@ -220,19 +220,19 @@ static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc) struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pch_transcoder = crtc->pipe; - u32 serr_int = intel_de_read(dev_priv, SERR_INT); + u32 serr_int = intel_de_read(display, SERR_INT); lockdep_assert_held(&dev_priv->irq_lock); if ((serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) == 0) return; - intel_de_write(dev_priv, SERR_INT, + intel_de_write(display, SERR_INT, SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); - intel_de_posting_read(dev_priv, SERR_INT); + intel_de_posting_read(display, SERR_INT); trace_intel_pch_fifo_underrun(display, pch_transcoder); - drm_err(&dev_priv->drm, "pch fifo underrun on pch transcoder %c\n", + drm_err(display->drm, "pch fifo underrun on pch transcoder %c\n", pipe_name(pch_transcoder)); } @@ -243,7 +243,7 @@ static void cpt_set_fifo_underrun_reporting(struct intel_display *display, struct drm_i915_private *dev_priv = to_i915(display->drm); if (enable) { - intel_de_write(dev_priv, SERR_INT, + intel_de_write(display, SERR_INT, SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); if (!cpt_can_enable_serr_int(display)) @@ -253,9 +253,9 @@ static void cpt_set_fifo_underrun_reporting(struct intel_display *display, } else { ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT); - if (old && intel_de_read(dev_priv, SERR_INT) & + if (old && intel_de_read(display, SERR_INT) & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "uncleared pch fifo underrun on pch transcoder %c\n", pipe_name(pch_transcoder)); } @@ -368,17 +368,16 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display, /** * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt - * @dev_priv: i915 device instance + * @display: display device instance * @pipe: (CPU) pipe to set state for * * This handles a CPU fifo underrun interrupt, generating an underrun warning * into dmesg if underrun reporting is enabled and then disables the underrun * interrupt to avoid an irq storm. */ -void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, +void intel_cpu_fifo_underrun_irq_handler(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); /* We may be called too early in init, thanks BIOS! */ @@ -386,63 +385,62 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, return; /* GMCH can't disable fifo underruns, filter them. */ - if (HAS_GMCH(dev_priv) && + if (HAS_GMCH(display) && crtc->cpu_fifo_underrun_disabled) return; if (intel_set_cpu_fifo_underrun_reporting(display, pipe, false)) { trace_intel_cpu_fifo_underrun(display, pipe); - drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe)); + drm_err(display->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe)); } - intel_fbc_handle_fifo_underrun_irq(&dev_priv->display); + intel_fbc_handle_fifo_underrun_irq(display); } /** * intel_pch_fifo_underrun_irq_handler - handle PCH fifo underrun interrupt - * @dev_priv: i915 device instance + * @display: display device instance * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older) * * This handles a PCH fifo underrun interrupt, generating an underrun warning * into dmesg if underrun reporting is enabled and then disables the underrun * interrupt to avoid an irq storm. */ -void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, +void intel_pch_fifo_underrun_irq_handler(struct intel_display *display, enum pipe pch_transcoder) { - struct intel_display *display = &dev_priv->display; - if (intel_set_pch_fifo_underrun_reporting(display, pch_transcoder, false)) { trace_intel_pch_fifo_underrun(display, pch_transcoder); - drm_err(&dev_priv->drm, "PCH transcoder %c FIFO underrun\n", + drm_err(display->drm, "PCH transcoder %c FIFO underrun\n", pipe_name(pch_transcoder)); } } /** * intel_check_cpu_fifo_underruns - check for CPU fifo underruns immediately - * @dev_priv: i915 device instance + * @display: display device instance * * Check for CPU fifo underruns immediately. Useful on IVB/HSW where the shared * error interrupt may have been disabled, and so CPU fifo underruns won't * necessarily raise an interrupt, and on GMCH platforms where underruns never * raise an interrupt. */ -void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv) +void intel_check_cpu_fifo_underruns(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc; spin_lock_irq(&dev_priv->irq_lock); - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { if (crtc->cpu_fifo_underrun_disabled) continue; - if (HAS_GMCH(dev_priv)) + if (HAS_GMCH(display)) i9xx_check_fifo_underruns(crtc); - else if (DISPLAY_VER(dev_priv) == 7) + else if (DISPLAY_VER(display) == 7) ivb_check_fifo_underruns(crtc); } @@ -451,19 +449,20 @@ void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv) /** * intel_check_pch_fifo_underruns - check for PCH fifo underruns immediately - * @dev_priv: i915 device instance + * @display: display device instance * * Check for PCH fifo underruns immediately. Useful on CPT/PPT where the shared * error interrupt may have been disabled, and so PCH fifo underruns won't * necessarily raise an interrupt. */ -void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv) +void intel_check_pch_fifo_underruns(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc; spin_lock_irq(&dev_priv->irq_lock); - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { if (crtc->pch_fifo_underrun_disabled) continue; @@ -474,10 +473,12 @@ void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv) spin_unlock_irq(&dev_priv->irq_lock); } -void intel_init_fifo_underrun_reporting(struct drm_i915_private *i915, +void intel_init_fifo_underrun_reporting(struct intel_display *display, struct intel_crtc *crtc, bool enable) { + struct drm_i915_private *i915 = to_i915(display->drm); + crtc->cpu_fifo_underrun_disabled = !enable; /* diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.h b/drivers/gpu/drm/i915/display/intel_fifo_underrun.h index 8302080c2313d..ebecc4347cfbf 100644 --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.h +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.h @@ -9,22 +9,21 @@ #include enum pipe; -struct drm_i915_private; struct intel_crtc; struct intel_display; -void intel_init_fifo_underrun_reporting(struct drm_i915_private *i915, +void intel_init_fifo_underrun_reporting(struct intel_display *display, struct intel_crtc *crtc, bool enable); bool intel_set_cpu_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable); bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display, enum pipe pch_transcoder, bool enable); -void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, +void intel_cpu_fifo_underrun_irq_handler(struct intel_display *display, enum pipe pipe); -void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, +void intel_pch_fifo_underrun_irq_handler(struct intel_display *display, enum pipe pch_transcoder); -void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv); -void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv); +void intel_check_cpu_fifo_underruns(struct intel_display *display); +void intel_check_pch_fifo_underruns(struct intel_display *display); #endif /* __INTEL_FIFO_UNDERRUN_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index b4d1a18e9fd47..a5a00b3ce98fa 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -454,8 +454,8 @@ static struct intel_connector *intel_encoder_find_connector(struct intel_encoder static void intel_sanitize_fifo_underrun_reporting(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); /* * We start out with underrun reporting disabled on active @@ -470,9 +470,9 @@ static void intel_sanitize_fifo_underrun_reporting(const struct intel_crtc_state * No protection against concurrent access is required - at * worst a fifo underrun happens which also sets this to false. */ - intel_init_fifo_underrun_reporting(i915, crtc, + intel_init_fifo_underrun_reporting(display, crtc, !crtc_state->hw.active && - !HAS_GMCH(i915)); + !HAS_GMCH(display)); } static bool intel_sanitize_crtc(struct intel_crtc *crtc, From ac6674bc94e91c25f5919efc91721264c00ab300 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Feb 2025 18:36:43 +0200 Subject: [PATCH 224/284] drm/i915/display: convert i915_pipestat_enable_mask() to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert i915_pipestat_enable_mask() to struct intel_display, allowing further conversions elsewhere. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/975b382c703cfb62f24643e40eac247b8e8bbea8.1739378096.git.jani.nikula@intel.com --- .../gpu/drm/i915/display/intel_display_irq.c | 19 ++++++++++--------- .../gpu/drm/i915/display/intel_display_irq.h | 5 +++-- .../drm/i915/display/intel_fifo_underrun.c | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index b8fcf74bd3acd..880eaed83cd5a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -226,29 +226,30 @@ void ibx_disable_display_interrupt(struct drm_i915_private *i915, u32 bits) ibx_display_interrupt_update(i915, bits, 0); } -u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv, +u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe) { - u32 status_mask = dev_priv->display.irq.pipestat_irq_mask[pipe]; + struct drm_i915_private *dev_priv = to_i915(display->drm); + u32 status_mask = display->irq.pipestat_irq_mask[pipe]; u32 enable_mask = status_mask << 16; lockdep_assert_held(&dev_priv->irq_lock); - if (DISPLAY_VER(dev_priv) < 5) + if (DISPLAY_VER(display) < 5) goto out; /* * On pipe A we don't support the PSR interrupt yet, * on pipe B and C the same bit MBZ. */ - if (drm_WARN_ON_ONCE(&dev_priv->drm, + if (drm_WARN_ON_ONCE(display->drm, status_mask & PIPE_A_PSR_STATUS_VLV)) return 0; /* * On pipe B and C we don't support the PSR interrupt yet, on pipe * A the same bit is for perf counters which we don't use either. */ - if (drm_WARN_ON_ONCE(&dev_priv->drm, + if (drm_WARN_ON_ONCE(display->drm, status_mask & PIPE_B_PSR_STATUS_VLV)) return 0; @@ -261,7 +262,7 @@ u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv, enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV; out: - drm_WARN_ONCE(&dev_priv->drm, + drm_WARN_ONCE(display->drm, enable_mask & ~PIPESTAT_INT_ENABLE_MASK || status_mask & ~PIPESTAT_INT_STATUS_MASK, "pipe %c: enable_mask=0x%x, status_mask=0x%x\n", @@ -288,7 +289,7 @@ void i915_enable_pipestat(struct drm_i915_private *dev_priv, return; dev_priv->display.irq.pipestat_irq_mask[pipe] |= status_mask; - enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); + enable_mask = i915_pipestat_enable_mask(display, pipe); intel_de_write(display, reg, enable_mask | status_mask); intel_de_posting_read(display, reg); @@ -312,7 +313,7 @@ void i915_disable_pipestat(struct drm_i915_private *dev_priv, return; dev_priv->display.irq.pipestat_irq_mask[pipe] &= ~status_mask; - enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); + enable_mask = i915_pipestat_enable_mask(display, pipe); intel_de_write(display, reg, enable_mask | status_mask); intel_de_posting_read(display, reg); @@ -525,7 +526,7 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, reg = PIPESTAT(dev_priv, pipe); pipe_stats[pipe] = intel_de_read(display, reg) & status_mask; - enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); + enable_mask = i915_pipestat_enable_mask(display, pipe); /* * Clear the PIPE*STAT regs before the IIR diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index b077712b7be1e..75ab38a0908e4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -11,8 +11,9 @@ #include "intel_display_limits.h" enum pipe; -struct drm_i915_private; struct drm_crtc; +struct drm_i915_private; +struct intel_display; void valleyview_enable_display_irqs(struct drm_i915_private *i915); void valleyview_disable_display_irqs(struct drm_i915_private *i915); @@ -64,7 +65,7 @@ void gen8_de_irq_postinstall(struct drm_i915_private *i915); void gen11_de_irq_postinstall(struct drm_i915_private *i915); void dg1_de_irq_postinstall(struct drm_i915_private *i915); -u32 i915_pipestat_enable_mask(struct drm_i915_private *i915, enum pipe pipe); +u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe); void i915_enable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask); void i915_disable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask); void i915_enable_asle_pipestat(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c index 14b00988a81f5..7a8fbff39be06 100644 --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c @@ -103,7 +103,7 @@ static void i9xx_check_fifo_underruns(struct intel_crtc *crtc) if ((intel_de_read(display, reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0) return; - enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe); + enable_mask = i915_pipestat_enable_mask(display, crtc->pipe); intel_de_write(display, reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); intel_de_posting_read(display, reg); @@ -121,7 +121,7 @@ static void i9xx_set_fifo_underrun_reporting(struct intel_display *display, lockdep_assert_held(&dev_priv->irq_lock); if (enable) { - u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); + u32 enable_mask = i915_pipestat_enable_mask(display, pipe); intel_de_write(display, reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); From 59f38b641ad004293611aac414f7fa55af29b51f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:47:52 +0200 Subject: [PATCH 225/284] drm/i915/psr: Use PSR2_MAN_TRK_CTL CFF bit only to send full update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are preparing for a change where only frontbuffer flush will use single full frame bit of a new register (SFF_CTL) available on LunarLake onwards. It shouldn't be necessary to have SFF bit set if CFF bit is set in PSR2_MAN_TRK_CTL -> removing setting it on all platforms as there is not reason to have it different on older platforms. v2: commit message improved Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-2-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 861e50ceef859..64e03d19cad5d 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2395,7 +2395,6 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, val |= man_trk_ctl_partial_frame_bit_get(display); if (full_update) { - val |= man_trk_ctl_single_full_frame_bit_get(display); val |= man_trk_ctl_continuos_full_frame(display); goto exit; } From 8e8cadfd88b44b4ffb658ae6d6ab3bc61cfd7f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:47:53 +0200 Subject: [PATCH 226/284] drm/i915/psr: Rename psr_force_hw_tracking_exit as intel_psr_force_update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit psr_force_hw_tracking_exit is misleading name as it is used for PSR1, PSR2 HW tracking and PSR2 selective fetch. Due to this rename it as intel_psr_force_update. Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-3-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 64e03d19cad5d..16d125f51ab05 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2324,7 +2324,7 @@ static u32 man_trk_ctl_continuos_full_frame(struct intel_display *display) PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME; } -static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) +static void intel_psr_force_update(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); enum transcoder cpu_transcoder = intel_dp->psr.transcoder; @@ -2869,7 +2869,7 @@ void intel_psr_post_plane_update(struct intel_atomic_state *state, /* Force a PSR exit when enabling CRC to avoid CRC timeouts */ if (crtc_state->crc_enabled && psr->enabled) - psr_force_hw_tracking_exit(intel_dp); + intel_psr_force_update(intel_dp); /* * Clear possible busy bits in case we have @@ -3266,10 +3266,10 @@ static void _psr_flush_handle(struct intel_dp *intel_dp) * continuous full frame is disabled, only a single full * frame is required */ - psr_force_hw_tracking_exit(intel_dp); + intel_psr_force_update(intel_dp); } } else { - psr_force_hw_tracking_exit(intel_dp); + intel_psr_force_update(intel_dp); if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits) queue_work(dev_priv->unordered_wq, &intel_dp->psr.work); From 005010f1f791a79d494ef83126425f587a4879cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:47:54 +0200 Subject: [PATCH 227/284] drm/i915/psr: Split setting sff and cff bits away from intel_psr_force_update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a clean-up and a preparation for adding own SFF and CFF registers for LunarLake onwards. Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-4-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 88 +++++++++--------------- 1 file changed, 31 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 16d125f51ab05..c0ba74c16d168 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2327,15 +2327,6 @@ static u32 man_trk_ctl_continuos_full_frame(struct intel_display *display) static void intel_psr_force_update(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - enum transcoder cpu_transcoder = intel_dp->psr.transcoder; - - if (intel_dp->psr.psr2_sel_fetch_enabled) - intel_de_write(display, - PSR2_MAN_TRK_CTL(display, cpu_transcoder), - man_trk_ctl_enable_bit_get(display) | - man_trk_ctl_partial_frame_bit_get(display) | - man_trk_ctl_single_full_frame_bit_get(display) | - man_trk_ctl_continuos_full_frame(display)); /* * Display WA #0884: skl+ @@ -3131,31 +3122,31 @@ static void intel_psr_work(struct work_struct *work) mutex_unlock(&intel_dp->psr.lock); } -static void _psr_invalidate_handle(struct intel_dp *intel_dp) +static void intel_psr_configure_full_frame_update(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); enum transcoder cpu_transcoder = intel_dp->psr.transcoder; - if (intel_dp->psr.psr2_sel_fetch_enabled) { - u32 val; + if (!intel_dp->psr.psr2_sel_fetch_enabled) + return; - if (intel_dp->psr.psr2_sel_fetch_cff_enabled) { - /* Send one update otherwise lag is observed in screen */ - intel_de_write(display, - CURSURFLIVE(display, intel_dp->psr.pipe), - 0); - return; + intel_de_write(display, + PSR2_MAN_TRK_CTL(display, cpu_transcoder), + man_trk_ctl_enable_bit_get(display) | + man_trk_ctl_partial_frame_bit_get(display) | + man_trk_ctl_single_full_frame_bit_get(display) | + man_trk_ctl_continuos_full_frame(display)); +} + +static void _psr_invalidate_handle(struct intel_dp *intel_dp) +{ + if (intel_dp->psr.psr2_sel_fetch_enabled) { + if (!intel_dp->psr.psr2_sel_fetch_cff_enabled) { + intel_dp->psr.psr2_sel_fetch_cff_enabled = true; + intel_psr_configure_full_frame_update(intel_dp); } - val = man_trk_ctl_enable_bit_get(display) | - man_trk_ctl_partial_frame_bit_get(display) | - man_trk_ctl_continuos_full_frame(display); - intel_de_write(display, - PSR2_MAN_TRK_CTL(display, cpu_transcoder), - val); - intel_de_write(display, - CURSURFLIVE(display, intel_dp->psr.pipe), 0); - intel_dp->psr.psr2_sel_fetch_cff_enabled = true; + intel_psr_force_update(intel_dp); } else { intel_psr_exit(intel_dp); } @@ -3236,44 +3227,27 @@ static void _psr_flush_handle(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); struct drm_i915_private *dev_priv = to_i915(display->drm); - enum transcoder cpu_transcoder = intel_dp->psr.transcoder; if (intel_dp->psr.psr2_sel_fetch_enabled) { if (intel_dp->psr.psr2_sel_fetch_cff_enabled) { /* can we turn CFF off? */ - if (intel_dp->psr.busy_frontbuffer_bits == 0) { - u32 val = man_trk_ctl_enable_bit_get(display) | - man_trk_ctl_partial_frame_bit_get(display) | - man_trk_ctl_single_full_frame_bit_get(display) | - man_trk_ctl_continuos_full_frame(display); - - /* - * Set psr2_sel_fetch_cff_enabled as false to allow selective - * updates. Still keep cff bit enabled as we don't have proper - * SU configuration in case update is sent for any reason after - * sff bit gets cleared by the HW on next vblank. - */ - intel_de_write(display, - PSR2_MAN_TRK_CTL(display, cpu_transcoder), - val); - intel_de_write(display, - CURSURFLIVE(display, intel_dp->psr.pipe), - 0); + if (intel_dp->psr.busy_frontbuffer_bits == 0) intel_dp->psr.psr2_sel_fetch_cff_enabled = false; - } - } else { - /* - * continuous full frame is disabled, only a single full - * frame is required - */ - intel_psr_force_update(intel_dp); } - } else { - intel_psr_force_update(intel_dp); - if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits) - queue_work(dev_priv->unordered_wq, &intel_dp->psr.work); + /* + * Still keep cff bit enabled as we don't have proper SU + * configuration in case update is sent for any reason after + * sff bit gets cleared by the HW on next vblank. + */ + intel_psr_configure_full_frame_update(intel_dp); } + + intel_psr_force_update(intel_dp); + + if (!intel_dp->psr.psr2_sel_fetch_enabled && !intel_dp->psr.active && + !intel_dp->psr.busy_frontbuffer_bits) + queue_work(dev_priv->unordered_wq, &intel_dp->psr.work); } /** From 3b5bf853e3093eec34dc080ab375c2bd0758995d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:47:55 +0200 Subject: [PATCH 228/284] drm/i915/psr: Add register definitions for SFF_CTL and CFF_CTL registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add register definitions for SFF_CTL and CFF_CTL registers. Name them as LNL_SFF_CTL and LNL_CFF_CTL. v2: use _MMIO_TRANS instead of _MMIO_TRANS2 Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-5-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr_regs.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h index 9ad7611506e88..795e6b9cc575c 100644 --- a/drivers/gpu/drm/i915/display/intel_psr_regs.h +++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h @@ -251,6 +251,16 @@ #define ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(14) #define ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(13) +#define _LNL_SFF_CTL_A 0x60918 +#define _LNL_SFF_CTL_B 0x61918 +#define LNL_SFF_CTL(tran) _MMIO_TRANS(tran, _LNL_SFF_CTL_A, _LNL_SFF_CTL_B) +#define LNL_SFF_CTL_SF_SINGLE_FULL_FRAME REG_BIT(1) + +#define _LNL_CFF_CTL_A 0x6091c +#define _LNL_CFF_CTL_B 0x6191c +#define LNL_CFF_CTL(tran) _MMIO_TRANS(tran, _LNL_CFF_CTL_A, _LNL_CFF_CTL_B) +#define LNL_CFF_CTL_SF_CONTINUOUS_FULL_FRAME REG_BIT(1) + /* PSR2 Early transport */ #define _PIPE_SRCSZ_ERLY_TPT_A 0x70074 #define _PIPE_SRCSZ_ERLY_TPT_B 0x71074 From 411ad63877bbfd74d05ce79bceca75c15a400236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:47:56 +0200 Subject: [PATCH 229/284] drm/i915/psr: Use SFF_CTL on invalidate/flush for LunarLake onwards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In LunarLake we have SFF_CTL register which contains SFF bit ored with respective SFF bit in PSR2_MAN_TRK_CTL register. Use this register instead of the bit in PSR2_MAN_TRK_CTL on frontbuffer tracking callbacks. This helps us avoiding taking psr mutex when performing atomic commit. We don't need to set the CFF bit as selective update configuration in PSR2_MAN_TRL_CTL is not overwritten anymore. I.e. we have valid configuration in PSR2_MAN_TRK_CTL and in plane SEL_FETCH_* registers when SFF bit gets cleared by the HW in case something triggers "frame change" event after SFF bit is cleared. Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-6-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index c0ba74c16d168..b5292f68d1009 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2359,7 +2359,7 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st struct intel_dp *intel_dp = enc_to_intel_dp(encoder); lockdep_assert_held(&intel_dp->psr.lock); - if (intel_dp->psr.psr2_sel_fetch_cff_enabled) + if (DISPLAY_VER(display) < 20 && intel_dp->psr.psr2_sel_fetch_cff_enabled) return; break; } @@ -3130,12 +3130,16 @@ static void intel_psr_configure_full_frame_update(struct intel_dp *intel_dp) if (!intel_dp->psr.psr2_sel_fetch_enabled) return; - intel_de_write(display, - PSR2_MAN_TRK_CTL(display, cpu_transcoder), - man_trk_ctl_enable_bit_get(display) | - man_trk_ctl_partial_frame_bit_get(display) | - man_trk_ctl_single_full_frame_bit_get(display) | - man_trk_ctl_continuos_full_frame(display)); + if (DISPLAY_VER(display) >= 20) + intel_de_write(display, LNL_SFF_CTL(cpu_transcoder), + LNL_SFF_CTL_SF_SINGLE_FULL_FRAME); + else + intel_de_write(display, + PSR2_MAN_TRK_CTL(display, cpu_transcoder), + man_trk_ctl_enable_bit_get(display) | + man_trk_ctl_partial_frame_bit_get(display) | + man_trk_ctl_single_full_frame_bit_get(display) | + man_trk_ctl_continuos_full_frame(display)); } static void _psr_invalidate_handle(struct intel_dp *intel_dp) @@ -3239,6 +3243,10 @@ static void _psr_flush_handle(struct intel_dp *intel_dp) * Still keep cff bit enabled as we don't have proper SU * configuration in case update is sent for any reason after * sff bit gets cleared by the HW on next vblank. + * + * NOTE: Setting cff bit is not needed for LunarLake onwards as + * we have own register for SFF bit and we are not overwriting + * existing SU configuration */ intel_psr_configure_full_frame_update(intel_dp); } From 1d1689ab0822942785769694cc29d150afaa7fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:47:57 +0200 Subject: [PATCH 230/284] drm/i915/psr: Allow writing PSR2_MAN_TRK_CTL using DSB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow writing PSR2_MAN_TRK_CTL using DSB by using intel_de_write_dsb. Do not check intel_dp->psr.lock being held when using DSB. This assertion doesn't make sense as in case of using DSB the actual write happens later and we are not taking intel_dp->psr.lock mutex over dsb commit. Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-7-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/display/intel_psr.c | 16 ++++++++++------ drivers/gpu/drm/i915/display/intel_psr.h | 4 +++- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index bb6e4f3b584a4..a5a0b4e60a7c0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7151,7 +7151,7 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state, intel_pipe_fastset(old_crtc_state, new_crtc_state); } - intel_psr2_program_trans_man_trk_ctl(new_crtc_state); + intel_psr2_program_trans_man_trk_ctl(NULL, new_crtc_state); intel_atomic_update_watermarks(state, crtc); } diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index b5292f68d1009..c805ff82e7002 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2344,7 +2344,8 @@ static void intel_psr_force_update(struct intel_dp *intel_dp) intel_de_write(display, CURSURFLIVE(display, intel_dp->psr.pipe), 0); } -void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state) +void intel_psr2_program_trans_man_trk_ctl(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -2358,20 +2359,23 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st crtc_state->uapi.encoder_mask) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - lockdep_assert_held(&intel_dp->psr.lock); + if (!dsb) + lockdep_assert_held(&intel_dp->psr.lock); + if (DISPLAY_VER(display) < 20 && intel_dp->psr.psr2_sel_fetch_cff_enabled) return; break; } - intel_de_write(display, PSR2_MAN_TRK_CTL(display, cpu_transcoder), - crtc_state->psr2_man_track_ctl); + intel_de_write_dsb(display, dsb, + PSR2_MAN_TRK_CTL(display, cpu_transcoder), + crtc_state->psr2_man_track_ctl); if (!crtc_state->enable_psr2_su_region_et) return; - intel_de_write(display, PIPE_SRCSZ_ERLY_TPT(crtc->pipe), - crtc_state->pipe_srcsz_early_tpt); + intel_de_write_dsb(display, dsb, PIPE_SRCSZ_ERLY_TPT(crtc->pipe), + crtc_state->pipe_srcsz_early_tpt); } static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index 5f1671d02d765..e6eba6633a92b 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -17,6 +17,7 @@ struct intel_crtc; struct intel_crtc_state; struct intel_display; struct intel_dp; +struct intel_dsb; struct intel_encoder; struct intel_plane; struct intel_plane_state; @@ -54,7 +55,8 @@ void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_stat bool intel_psr_enabled(struct intel_dp *intel_dp); int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc); -void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state); +void intel_psr2_program_trans_man_trk_ctl(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state); void intel_psr_pause(struct intel_dp *intel_dp); void intel_psr_resume(struct intel_dp *intel_dp); bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state); From e01cbca0ea603acd62dad647ec774e7a9e02a7a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:47:58 +0200 Subject: [PATCH 231/284] drm/i915/psr: Write PSR2_MAN_TRK_CTL on DSB commit as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add PSR2_MAN_TRK_CTL writing into DSB commit in intel_atomic_dsb_finish. Taking PSR lock over DSB commit is not needed because PSR2_MAN_TRK_CTL is now written only by DSB. Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-8-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a5a0b4e60a7c0..aea18c7ef63fc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7743,6 +7743,8 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, new_crtc_state); bdw_set_pipe_misc(new_crtc_state->dsb_commit, new_crtc_state); + intel_psr2_program_trans_man_trk_ctl(new_crtc_state->dsb_commit, + new_crtc_state); intel_crtc_planes_update_arm(new_crtc_state->dsb_commit, state, crtc); From 452c3fb857f8fe35544335d336eb6ee379ef9b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:47:59 +0200 Subject: [PATCH 232/284] drm/i915/display: Warn on use_dsb in non-dsb pipe update functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add drm_WARN_ON(use_dsb) into commit_pipe_{pre,post}_planes() and intel_pipe_update_{start,end}() as they are not supposed to get called on non-dsb updates. Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-9-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_crtc.c | 4 ++++ drivers/gpu/drm/i915/display/intel_display.c | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index d075f6d2961b0..5b2603ef2ff75 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -522,6 +522,8 @@ void intel_pipe_update_start(struct intel_atomic_state *state, struct intel_vblank_evade_ctx evade; int scanline; + drm_WARN_ON(display->drm, new_crtc_state->use_dsb); + intel_psr_lock(new_crtc_state); if (new_crtc_state->do_async_flip) { @@ -660,6 +662,8 @@ void intel_pipe_update_end(struct intel_atomic_state *state, ktime_t end_vbl_time = ktime_get(); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + drm_WARN_ON(display->drm, new_crtc_state->use_dsb); + if (new_crtc_state->do_async_flip) goto out; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index aea18c7ef63fc..00a552d75be2e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7136,11 +7136,13 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state, intel_atomic_get_new_crtc_state(state, crtc); bool modeset = intel_crtc_needs_modeset(new_crtc_state); + drm_WARN_ON(&dev_priv->drm, new_crtc_state->use_dsb); + /* * During modesets pipe configuration was programmed as the * CRTC was enabled. */ - if (!modeset && !new_crtc_state->use_dsb) { + if (!modeset) { if (intel_crtc_needs_color_update(new_crtc_state)) intel_color_commit_arm(NULL, new_crtc_state); @@ -7163,6 +7165,8 @@ static void commit_pipe_post_planes(struct intel_atomic_state *state, const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); + drm_WARN_ON(&dev_priv->drm, new_crtc_state->use_dsb); + /* * Disable the scaler(s) after the plane(s) so that we don't * get a catastrophic underrun even if the two operations From 20d6343bf4576674756067a0c59be49526cad072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:48:00 +0200 Subject: [PATCH 233/284] drm/i915/psr: Remove DSB_SKIP_WAITS_EN chicken bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have different approach on how flip is considered being complete. We are waiting for vblank on DSB and generate interrupt when it happens and this interrupt is considered as indication of completion -> we definitely do not want to skip vblank wait. Also not skipping scanline wait shouldn't cause any problems if we are in DEEP_SLEEP PIPEDSL register is returning 0 -> evasion does nothing and if we are not in DEEP_SLEEP evasion works same way as without PSR. v2: add comment explaining why we are not setting DSB_SKIP_WAITS_EN Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-10-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_dsb.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index db69b1c676f7a..4c067bf9ac4c3 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -170,17 +170,26 @@ static int dsb_scanline_to_hw(struct intel_atomic_state *state, return (scanline + vtotal - intel_crtc_scanline_offset(crtc_state)) % vtotal; } +/* + * Bspec suggests that we should always set DSB_SKIP_WAITS_EN. We have approach + * different from what is explained in Bspec on how flip is considered being + * complete. We are waiting for vblank in DSB and generate interrupt when it + * happens and this interrupt is considered as indication of completion -> we + * definitely do not want to skip vblank wait. We also have concern what comes + * to skipping vblank evasion. I.e. arming registers are latched before we have + * managed writing them. Due to these reasons we are not setting + * DSB_SKIP_WAITS_EN. + */ static u32 dsb_chicken(struct intel_atomic_state *state, struct intel_crtc *crtc) { if (pre_commit_is_vrr_active(state, crtc)) - return DSB_SKIP_WAITS_EN | - DSB_CTRL_WAIT_SAFE_WINDOW | + return DSB_CTRL_WAIT_SAFE_WINDOW | DSB_CTRL_NO_WAIT_VBLANK | DSB_INST_WAIT_SAFE_WINDOW | DSB_INST_NO_WAIT_VBLANK; else - return DSB_SKIP_WAITS_EN; + return 0; } static bool assert_dsb_has_room(struct intel_dsb *dsb) From 801d827d80f6d8a574dee0f87e367167e2b6d80b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:48:01 +0200 Subject: [PATCH 234/284] drm/i915/display: Evade scanline 0 as well if PSR1 or PSR2 is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PIPEDSL is reading as 0 when in SRDENT(PSR1) or DEEP_SLEEP(PSR2). On wake-up scanline counting starts from vblank_start - 1. We don't know if wake-up is already ongoing when evasion starts. In worst case PIPEDSL could start reading valid value right after checking the scanline. In this scenario we wouldn't have enough time to write all registers. To tackle this evade scanline 0 as well. As a drawback we have 1 frame delay in flip when waking up. v2: - use intel_dsb_emit_wait_dsl - add evasion of scanline 0 also for Panel Replay Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-11-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_dsb.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 4c067bf9ac4c3..9fc4003d15794 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -564,6 +564,18 @@ void intel_dsb_vblank_evade(struct intel_atomic_state *state, int latency = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 20); int start, end; + /* + * PIPEDSL is reading as 0 when in SRDENT(PSR1) or DEEP_SLEEP(PSR2). On + * wake-up scanline counting starts from vblank_start - 1. We don't know + * if wake-up is already ongoing when evasion starts. In worst case + * PIPEDSL could start reading valid value right after checking the + * scanline. In this scenario we wouldn't have enough time to write all + * registers. To tackle this evade scanline 0 as well. As a drawback we + * have 1 frame delay in flip when waking up. + */ + if (crtc_state->has_psr) + intel_dsb_emit_wait_dsl(dsb, DSB_OPCODE_WAIT_DSL_OUT, 0, 0); + if (pre_commit_is_vrr_active(state, crtc)) { int vblank_delay = intel_vrr_vblank_delay(crtc_state); From fa27fa48061afda49f939fcac6c480f0c4c1fcfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:48:02 +0200 Subject: [PATCH 235/284] drm/i915/psr: Add function for triggering "Frame Change" event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new function to trigger "Frame Change" event for ensuring we are waking up before vblank evasion. v2: dsb as a first parameter Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-12-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_psr.h | 3 +++ 2 files changed, 25 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index c805ff82e7002..427a7d1df1f99 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -44,6 +44,7 @@ #include "intel_psr.h" #include "intel_psr_regs.h" #include "intel_snps_phy.h" +#include "intel_vblank.h" #include "skl_universal_plane.h" /** @@ -2289,6 +2290,27 @@ bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state) return false; } +/** + * intel_psr_trigger_frame_change_event - Trigger "Frame Change" event + * @dsb: DSB context + * @state: the atomic state + * @crtc: the CRTC + * + * Generate PSR "Frame Change" event. + */ +void intel_psr_trigger_frame_change_event(struct intel_dsb *dsb, + struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + const struct intel_crtc_state *crtc_state = + intel_pre_commit_crtc_state(state, crtc); + struct intel_display *display = to_intel_display(crtc); + + if (crtc_state->has_psr) + intel_de_write_dsb(display, dsb, + CURSURFLIVE(display, crtc->pipe), 0); +} + static u32 man_trk_ctl_enable_bit_get(struct intel_display *display) { struct drm_i915_private *dev_priv = to_i915(display->drm); diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index e6eba6633a92b..a43a374cff550 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -64,6 +64,9 @@ bool intel_psr_link_ok(struct intel_dp *intel_dp); void intel_psr_lock(const struct intel_crtc_state *crtc_state); void intel_psr_unlock(const struct intel_crtc_state *crtc_state); +void intel_psr_trigger_frame_change_event(struct intel_dsb *dsb, + struct intel_atomic_state *state, + struct intel_crtc *crtc); void intel_psr_connector_debugfs_add(struct intel_connector *connector); void intel_psr_debugfs_register(struct intel_display *display); From ac76a51ddb5efb875c7c9ca87e002ff0aa4f63d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:48:03 +0200 Subject: [PATCH 236/284] drm/i915/display: Ensure we have "Frame Change" event in DSB commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We may have commit which doesn't have any non-arming plane register writes. In that case there aren't "Frame Change" event before DSB vblank evasion which hangs as PIPEDSL register is reading as 0 when PSR state is SRDENT(PSR1) or DEEP_SLEEP(PSR2). Handle this by ensuring "Frame Change" event at the begin of DSB commit if using PSR/PR. v3: dsb_commit as a first parameter v2: use intel_psr_trigger_frame_change_event Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-13-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 00a552d75be2e..dccdb20cc6d7b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7740,6 +7740,14 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, intel_crtc_planes_update_noarm(new_crtc_state->dsb_commit, state, crtc); + /* + * Ensure we have "Frame Change" event when PSR state is + * SRDENT(PSR1) or DEEP_SLEEP(PSR2). Otherwise DSB vblank + * evasion hangs as PIPEDSL is reading as 0. + */ + intel_psr_trigger_frame_change_event(new_crtc_state->dsb_commit, + state, crtc); + intel_dsb_vblank_evade(state, new_crtc_state->dsb_commit); if (intel_crtc_needs_color_update(new_crtc_state)) From bccb18c5617a8fb7f6cb2b6d93ae6f2657842929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 08:48:04 +0200 Subject: [PATCH 237/284] drm/i915/psr: Allow DSB usage when PSR is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now as we have correct PSR2_MAN_TRK_CTL handling in place we can allow DSB usage also when PSR is enabled for LunarLake onwards. v2: rebase Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20250213064804.2077127-14-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index dccdb20cc6d7b..e7f76306d4e68 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7687,6 +7687,7 @@ static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *s static void intel_atomic_dsb_prepare(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc_state *new_crtc_state = @@ -7702,7 +7703,7 @@ static void intel_atomic_dsb_prepare(struct intel_atomic_state *state, new_crtc_state->use_dsb = new_crtc_state->update_planes && !new_crtc_state->do_async_flip && - !new_crtc_state->has_psr && + (DISPLAY_VER(display) >= 20 || !new_crtc_state->has_psr) && !new_crtc_state->scaler_state.scaler_users && !old_crtc_state->scaler_state.scaler_users && !intel_crtc_needs_modeset(new_crtc_state) && From 76120b3a304aec28fef4910204b81a12db8974da Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:19:51 +0200 Subject: [PATCH 238/284] drm/i915/dsi: Use TRANS_DDI_FUNC_CTL's own port width macro The format of the port width field in the DDI_BUF_CTL and the TRANS_DDI_FUNC_CTL registers are different starting with MTL, where the x3 lane mode for HDMI FRL has a different encoding in the two registers. To account for this use the TRANS_DDI_FUNC_CTL's own port width macro. Cc: # v6.5+ Fixes: b66a8abaa48a ("drm/i915/display/mtl: Fill port width in DDI_BUF_/TRANS_DDI_FUNC_/PORT_BUF_CTL for HDMI") Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-2-imre.deak@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index a3e6e14a5e77f..c1b5be0f56032 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -805,8 +805,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder, /* select data lane width */ tmp = intel_de_read(display, TRANS_DDI_FUNC_CTL(display, dsi_trans)); - tmp &= ~DDI_PORT_WIDTH_MASK; - tmp |= DDI_PORT_WIDTH(intel_dsi->lane_count); + tmp &= ~TRANS_DDI_PORT_WIDTH_MASK; + tmp |= TRANS_DDI_PORT_WIDTH(intel_dsi->lane_count); /* select input pipe */ tmp &= ~TRANS_DDI_EDP_INPUT_MASK; From b2ecdabe46d23db275f94cd7c46ca414a144818b Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:19:52 +0200 Subject: [PATCH 239/284] drm/i915/ddi: Fix HDMI port width programming in DDI_BUF_CTL Fix the port width programming in the DDI_BUF_CTL register on MTLP+, where this had an off-by-one error. Cc: # v6.5+ Fixes: b66a8abaa48a ("drm/i915/display/mtl: Fill port width in DDI_BUF_/TRANS_DDI_FUNC_/PORT_BUF_CTL for HDMI") Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-3-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/i915_reg.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 69678220a8ca2..550e6ed6eaa1c 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3507,7 +3507,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(dev_priv, port), XELPDP_PORT_WIDTH_MASK | XELPDP_PORT_REVERSAL, port_buf); - buf_ctl |= DDI_PORT_WIDTH(lane_count); + buf_ctl |= DDI_PORT_WIDTH(crtc_state->lane_count); if (DISPLAY_VER(dev_priv) >= 20) buf_ctl |= XE2LPD_DDI_BUF_D2D_LINK_ENABLE; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 670cd2371f947..3eea191f20175 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3639,7 +3639,7 @@ enum skl_power_gate { #define DDI_BUF_IS_IDLE (1 << 7) #define DDI_BUF_CTL_TC_PHY_OWNERSHIP REG_BIT(6) #define DDI_A_4_LANES (1 << 4) -#define DDI_PORT_WIDTH(width) (((width) - 1) << 1) +#define DDI_PORT_WIDTH(width) (((width) == 3 ? 4 : ((width) - 1)) << 1) #define DDI_PORT_WIDTH_MASK (7 << 1) #define DDI_PORT_WIDTH_SHIFT 1 #define DDI_INIT_DISPLAY_DETECTED (1 << 0) From dcac00e4d6fdddadde1d5147d1f414f467356077 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:19:53 +0200 Subject: [PATCH 240/284] drm/i915/ddi: Make all the PORT_WIDTH macros work the same way Make the PORT_WIDTH macro of the XELPDP_PORT_CTL1 register work the same way as those used for the DDI_BUF_CTL and the TRANS_DDI_FUNC_CTL registers: accept a width parameter and convert it to the given register's encoding. v2: Robustify macro calls with parens. (Jani) Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-4-imre.deak@intel.com --- .../gpu/drm/i915/display/intel_cx0_phy_regs.h | 3 ++- drivers/gpu/drm/i915/display/intel_ddi.c | 22 ++----------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h index 4a3cf08007e31..960f7f778fb81 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h @@ -110,7 +110,8 @@ #define XELPDP_TCSS_POWER_REQUEST REG_BIT(5) #define XELPDP_TCSS_POWER_STATE REG_BIT(4) #define XELPDP_PORT_WIDTH_MASK REG_GENMASK(3, 1) -#define XELPDP_PORT_WIDTH(val) REG_FIELD_PREP(XELPDP_PORT_WIDTH_MASK, val) +#define XELPDP_PORT_WIDTH(width) REG_FIELD_PREP(XELPDP_PORT_WIDTH_MASK, \ + ((width) == 3 ? 4 : (width) - 1)) #define _XELPDP_PORT_BUF_CTL2(idx) _MMIO(_PICK_EVEN_2RANGES(idx, PORT_TC1, \ _XELPDP_PORT_BUF_CTL1_LN0_A, \ diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 550e6ed6eaa1c..977798cc73b75 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2525,23 +2525,6 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) OVERLAP_PIXELS_MASK, dss1); } -static u8 mtl_get_port_width(u8 lane_count) -{ - switch (lane_count) { - case 1: - return 0; - case 2: - return 1; - case 3: - return 4; - case 4: - return 3; - default: - MISSING_CASE(lane_count); - return 4; - } -} - static void mtl_ddi_enable_d2d(struct intel_encoder *encoder) { @@ -2575,7 +2558,7 @@ static void mtl_port_buf_ctl_program(struct intel_encoder *encoder, enum port port = encoder->port; u32 val = 0; - val |= XELPDP_PORT_WIDTH(mtl_get_port_width(crtc_state->lane_count)); + val |= XELPDP_PORT_WIDTH(crtc_state->lane_count); if (intel_dp_is_uhbr(crtc_state)) val |= XELPDP_PORT_BUF_PORT_DATA_40BIT; @@ -3496,10 +3479,9 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, buf_ctl |= DDI_A_4_LANES; if (DISPLAY_VER(dev_priv) >= 14) { - u8 lane_count = mtl_get_port_width(crtc_state->lane_count); u32 port_buf = 0; - port_buf |= XELPDP_PORT_WIDTH(lane_count); + port_buf |= XELPDP_PORT_WIDTH(crtc_state->lane_count); if (dig_port->lane_reversal) port_buf |= XELPDP_PORT_REVERSAL; From dc2b12b34fb8070b304a8725c4c4060058bc6ab7 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:19:54 +0200 Subject: [PATCH 241/284] drm/i915/ddi: Set missing TC DP PHY lane stagger delay in DDI_BUF_CTL Add the missing PHY lane stagger delay programming for ICL-ADL platforms on TypeC DP outputs. v2: (Jani) - Clarify code comment about lane stagger programming. - Robustify macro calls with parens. Bspec: 7534, 49533 Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-5-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 29 ++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 3 +++ 2 files changed, 32 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 977798cc73b75..bf1c16b496cdb 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -328,9 +328,32 @@ static u32 ddi_buf_phy_link_rate(int port_clock) } } +static int dp_phy_lane_stagger_delay(int port_clock) +{ + /* + * Return the number of symbol clocks delay used to stagger the + * assertion/desassertion of the port lane enables. The target delay + * time is 100 ns or greater, return the number of symbols specific to + * the provided port_clock (aka link clock) corresponding to this delay + * time, i.e. so that + * + * number_of_symbols * duration_of_one_symbol >= 100 ns + * + * The delay must be applied only on TypeC DP outputs, for everything else + * the delay must be set to 0. + * + * Return the number of link symbols per 100 ns: + * port_clock (10 kHz) -> bits / 100 us + * / symbol_size -> symbols / 100 us + * / 1000 -> symbols / 100 ns + */ + return DIV_ROUND_UP(port_clock, intel_dp_link_symbol_size(port_clock) * 1000); +} + static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); @@ -356,6 +379,12 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, if (!intel_tc_port_in_tbt_alt_mode(dig_port)) intel_dp->DP |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; } + + if (IS_DISPLAY_VER(display, 11, 13) && intel_encoder_is_tc(encoder)) { + int delay = dp_phy_lane_stagger_delay(crtc_state->port_clock); + + intel_dp->DP |= DDI_BUF_LANE_STAGGER_DELAY(delay); + } } static int icl_calc_tbt_pll_link(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3eea191f20175..50efaab3b5536 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3636,6 +3636,9 @@ enum skl_power_gate { #define DDI_BUF_PORT_DATA_20BIT REG_FIELD_PREP(DDI_BUF_PORT_DATA_MASK, 1) #define DDI_BUF_PORT_DATA_40BIT REG_FIELD_PREP(DDI_BUF_PORT_DATA_MASK, 2) #define DDI_BUF_PORT_REVERSAL (1 << 16) +#define DDI_BUF_LANE_STAGGER_DELAY_MASK REG_GENMASK(15, 8) +#define DDI_BUF_LANE_STAGGER_DELAY(symbols) REG_FIELD_PREP(DDI_BUF_LANE_STAGGER_DELAY_MASK, \ + (symbols)) #define DDI_BUF_IS_IDLE (1 << 7) #define DDI_BUF_CTL_TC_PHY_OWNERSHIP REG_BIT(6) #define DDI_A_4_LANES (1 << 4) From d6e6cb5980ed8ad09cdcf3669056564b29b07585 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:19:55 +0200 Subject: [PATCH 242/284] drm/i915/ddi: Simplify the port enabling via DDI_BUF_CTL In the past intel_digital_port::dp.prepare_link_retrain() could be called directly (vs. from a modeset) to retrain an enabled link. In that case the port had to be first disabled and then re-enabled. That changed with commit 2885d283cce5 ("drm/i915/dp: Retrain SST links via a modeset commit"), after which the only way prepare_link_retrain() can be called is from a modeset during link training when the port is still disabled. Simplify things accordingly, assuming the disabled port state. v2: Don't use drm_i915_private in intel_ddi_prepare_link_retrain(). (Jani) Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-6-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index bf1c16b496cdb..5d008c04ca2d2 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3761,8 +3761,8 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, * necessary disable and enable port */ dp_tp_ctl = intel_de_read(display, dp_tp_ctl_reg(encoder, crtc_state)); - if (dp_tp_ctl & DP_TP_CTL_ENABLE) - mtl_disable_ddi_buf(encoder, crtc_state); + + drm_WARN_ON(display->drm, dp_tp_ctl & DP_TP_CTL_ENABLE); /* 6.d Configure and enable DP_TP_CTL with link training pattern 1 selected */ dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; @@ -3801,30 +3801,16 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; - u32 dp_tp_ctl, ddi_buf_ctl; - bool wait = false; + u32 dp_tp_ctl; dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); - if (dp_tp_ctl & DP_TP_CTL_ENABLE) { - ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port)); - if (ddi_buf_ctl & DDI_BUF_CTL_ENABLE) { - intel_de_write(dev_priv, DDI_BUF_CTL(port), - ddi_buf_ctl & ~DDI_BUF_CTL_ENABLE); - wait = true; - } - - dp_tp_ctl &= ~DP_TP_CTL_ENABLE; - intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); - intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); - - if (wait) - intel_wait_ddi_buf_idle(dev_priv, port); - } + drm_WARN_ON(display->drm, dp_tp_ctl & DP_TP_CTL_ENABLE); dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) || From c729ff4598d023afb8f81de63e1363d4c2a7cd40 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:19:56 +0200 Subject: [PATCH 243/284] drm/i915/ddi: Simplify the port disabling via DDI_BUF_CTL A port can be disabled only via a modeset (or during HW state sanitization) when the port is enabled. Thus it's not required to check the port's enabled state before disabling it. In any case if the port happened to be disabled, the following disabling would be just a nop and waiting for the buffer's idle state should succeed. Simplify the disabling sequence accordingly. Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-7-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 5d008c04ca2d2..25be10e08b16a 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3077,17 +3077,12 @@ static void mtl_disable_ddi_buf(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; - u32 val; /* 3.b Clear DDI_CTL_DE Enable to 0. */ - val = intel_de_read(dev_priv, DDI_BUF_CTL(port)); - if (val & DDI_BUF_CTL_ENABLE) { - val &= ~DDI_BUF_CTL_ENABLE; - intel_de_write(dev_priv, DDI_BUF_CTL(port), val); + intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); - /* 3.c Poll for PORT_BUF_CTL Idle Status == 1, timeout after 100us */ - mtl_wait_ddi_buf_idle(dev_priv, port); - } + /* 3.c Poll for PORT_BUF_CTL Idle Status == 1, timeout after 100us */ + mtl_wait_ddi_buf_idle(dev_priv, port); /* 3.d Disable D2D Link */ mtl_ddi_disable_d2d_link(encoder); @@ -3104,15 +3099,8 @@ static void disable_ddi_buf(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; - bool wait = false; - u32 val; - val = intel_de_read(dev_priv, DDI_BUF_CTL(port)); - if (val & DDI_BUF_CTL_ENABLE) { - val &= ~DDI_BUF_CTL_ENABLE; - intel_de_write(dev_priv, DDI_BUF_CTL(port), val); - wait = true; - } + intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); if (intel_crtc_has_dp_encoder(crtc_state)) intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), @@ -3120,8 +3108,7 @@ static void disable_ddi_buf(struct intel_encoder *encoder, intel_ddi_disable_fec(encoder, crtc_state); - if (wait) - intel_wait_ddi_buf_idle(dev_priv, port); + intel_wait_ddi_buf_idle(dev_priv, port); } static void intel_disable_ddi_buf(struct intel_encoder *encoder, From 3c45d88d281ea87768007ab80c6d1400f6921b05 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:19:57 +0200 Subject: [PATCH 244/284] drm/i915/ddi: Simplify waiting for a port to get active/idle via DDI_BUF_CTL When waiting for a port to get active/idle there is no point in the complexity of specifying an exact timeout and for that the suitable wait API instead of just using the maximum timeout. The sequence in particular is not performance critical at all either and due to scheduling it's not guaranteed anyhow how long the wait will last at the given timescale. In the usual case where the wait succeeds the actual time waited does not change with the increased timeout. Simplify things accordingly, describing the bspec platform specific timeouts in code comments. v2: Clarify the rationale in the commit log. (Jani) Cc: Jani Nikula Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-8-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 78 +++++++++++------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 25be10e08b16a..c72d49c8a6f06 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -177,69 +177,63 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, trans->entries[level].hsw.trans2); } -static void mtl_wait_ddi_buf_idle(struct drm_i915_private *i915, enum port port) +static i915_reg_t intel_ddi_buf_status_reg(struct intel_display *display, enum port port) { - int ret; + struct drm_i915_private *i915 = to_i915(display->drm); - /* FIXME: find out why Bspec's 100us timeout is too short */ - ret = wait_for_us((intel_de_read(i915, XELPDP_PORT_BUF_CTL1(i915, port)) & - XELPDP_PORT_BUF_PHY_IDLE), 10000); - if (ret) - drm_err(&i915->drm, "Timeout waiting for DDI BUF %c to get idle\n", - port_name(port)); + if (DISPLAY_VER(display) >= 14) + return XELPDP_PORT_BUF_CTL1(i915, port); + else + return DDI_BUF_CTL(port); } void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, enum port port) { - if (IS_BROXTON(dev_priv)) { + struct intel_display *display = &dev_priv->display; + + /* + * Bspec's platform specific timeouts: + * MTL+ : 100 us + * BXT : fixed 16 us + * HSW-ADL: 8 us + * + * FIXME: MTL requires 10 ms based on tests, find out why 100 us is too short + */ + if (display->platform.broxton) { udelay(16); return; } - if (wait_for_us((intel_de_read(dev_priv, DDI_BUF_CTL(port)) & - DDI_BUF_IS_IDLE), 8)) - drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c to get idle\n", + static_assert(DDI_BUF_IS_IDLE == XELPDP_PORT_BUF_PHY_IDLE); + if (intel_de_wait_for_set(display, intel_ddi_buf_status_reg(display, port), + DDI_BUF_IS_IDLE, 10)) + drm_err(display->drm, "Timeout waiting for DDI BUF %c to get idle\n", port_name(port)); } static void intel_wait_ddi_buf_active(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; - int timeout_us; - int ret; - /* Wait > 518 usecs for DDI_BUF_CTL to be non idle */ - if (DISPLAY_VER(dev_priv) < 10) { + /* + * Bspec's platform specific timeouts: + * MTL+ : 10000 us + * DG2 : 1200 us + * TGL-ADL combo PHY: 1000 us + * TGL-ADL TypeC PHY: 3000 us + * HSW-ICL : fixed 518 us + */ + if (DISPLAY_VER(display) < 10) { usleep_range(518, 1000); return; } - if (DISPLAY_VER(dev_priv) >= 14) { - timeout_us = 10000; - } else if (IS_DG2(dev_priv)) { - timeout_us = 1200; - } else if (DISPLAY_VER(dev_priv) >= 12) { - if (intel_encoder_is_tc(encoder)) - timeout_us = 3000; - else - timeout_us = 1000; - } else { - timeout_us = 500; - } - - if (DISPLAY_VER(dev_priv) >= 14) - ret = _wait_for(!(intel_de_read(dev_priv, - XELPDP_PORT_BUF_CTL1(dev_priv, port)) & - XELPDP_PORT_BUF_PHY_IDLE), - timeout_us, 10, 10); - else - ret = _wait_for(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) & DDI_BUF_IS_IDLE), - timeout_us, 10, 10); - - if (ret) - drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c to get active\n", + static_assert(DDI_BUF_IS_IDLE == XELPDP_PORT_BUF_PHY_IDLE); + if (intel_de_wait_for_clear(display, intel_ddi_buf_status_reg(display, port), + DDI_BUF_IS_IDLE, 10)) + drm_err(display->drm, "Timeout waiting for DDI BUF %c to get active\n", port_name(port)); } @@ -3082,7 +3076,7 @@ static void mtl_disable_ddi_buf(struct intel_encoder *encoder, intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); /* 3.c Poll for PORT_BUF_CTL Idle Status == 1, timeout after 100us */ - mtl_wait_ddi_buf_idle(dev_priv, port); + intel_wait_ddi_buf_idle(dev_priv, port); /* 3.d Disable D2D Link */ mtl_ddi_disable_d2d_link(encoder); From 6ebf4419fc19a98690be552eb3d5a4279aa82e6c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:19:58 +0200 Subject: [PATCH 245/284] drm/i915/ddi: Move platform checks within mtl_ddi_enable/disable_d2d_link() The prefix of the mtl_ddi_enable_d2d() / mtl_ddi_disable_d2d_link() names show already what are the relevant platforms, so the corresponding platform check is a detail that can be hidden in the functions, do so. While at it rename mtl_ddi_disable_d2d_link() to mtl_ddi_disable_d2d() for symmetry with mtl_ddi_enable_d2d(). v2: s/mtl_ddi_disable_d2d_link/mtl_ddi_disable_d2d (Jani) Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-9-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index c72d49c8a6f06..ffb4936e6af99 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2556,6 +2556,9 @@ mtl_ddi_enable_d2d(struct intel_encoder *encoder) i915_reg_t reg; u32 set_bits, wait_bits; + if (DISPLAY_VER(dev_priv) < 14) + return; + if (DISPLAY_VER(dev_priv) >= 20) { reg = DDI_BUF_CTL(port); set_bits = XE2LPD_DDI_BUF_D2D_LINK_ENABLE; @@ -3043,13 +3046,16 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, } static void -mtl_ddi_disable_d2d_link(struct intel_encoder *encoder) +mtl_ddi_disable_d2d(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; i915_reg_t reg; u32 clr_bits, wait_bits; + if (DISPLAY_VER(dev_priv) < 14) + return; + if (DISPLAY_VER(dev_priv) >= 20) { reg = DDI_BUF_CTL(port); clr_bits = XE2LPD_DDI_BUF_D2D_LINK_ENABLE; @@ -3079,7 +3085,7 @@ static void mtl_disable_ddi_buf(struct intel_encoder *encoder, intel_wait_ddi_buf_idle(dev_priv, port); /* 3.d Disable D2D Link */ - mtl_ddi_disable_d2d_link(encoder); + mtl_ddi_disable_d2d(encoder); /* 3.e Disable DP_TP_CTL */ if (intel_crtc_has_dp_encoder(crtc_state)) { @@ -3428,8 +3434,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state); /* e. Enable D2D Link for C10/C20 Phy */ - if (DISPLAY_VER(dev_priv) >= 14) - mtl_ddi_enable_d2d(encoder); + mtl_ddi_enable_d2d(encoder); encoder->set_signal_levels(encoder, crtc_state); From 99037db545b5cca411182b312520d57c2f7a298b Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:19:59 +0200 Subject: [PATCH 246/284] drm/i915/ddi: Unify the platform specific functions disabling a port The functions disabling a port for MTL+ and earlier platforms only differ by an extra step on MTL+ (to disable the D2D link) and the point at which the port's idle state is waited for. Combine the two functions accounting for the above differences, removing the duplication. Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-10-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 43 ++++-------------------- 1 file changed, 7 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index ffb4936e6af99..a96b9b934d70b 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3072,58 +3072,29 @@ mtl_ddi_disable_d2d(struct intel_encoder *encoder) port_name(port)); } -static void mtl_disable_ddi_buf(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) +static void intel_disable_ddi_buf(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; - /* 3.b Clear DDI_CTL_DE Enable to 0. */ intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); - /* 3.c Poll for PORT_BUF_CTL Idle Status == 1, timeout after 100us */ - intel_wait_ddi_buf_idle(dev_priv, port); + if (DISPLAY_VER(display) >= 14) + intel_wait_ddi_buf_idle(dev_priv, port); - /* 3.d Disable D2D Link */ mtl_ddi_disable_d2d(encoder); - /* 3.e Disable DP_TP_CTL */ if (intel_crtc_has_dp_encoder(crtc_state)) { intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), DP_TP_CTL_ENABLE, 0); } -} - -static void disable_ddi_buf(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - enum port port = encoder->port; - - intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); - - if (intel_crtc_has_dp_encoder(crtc_state)) - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), - DP_TP_CTL_ENABLE, 0); intel_ddi_disable_fec(encoder, crtc_state); - intel_wait_ddi_buf_idle(dev_priv, port); -} - -static void intel_disable_ddi_buf(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - - if (DISPLAY_VER(dev_priv) >= 14) { - mtl_disable_ddi_buf(encoder, crtc_state); - - /* 3.f Disable DP_TP_CTL FEC Enable if it is needed */ - intel_ddi_disable_fec(encoder, crtc_state); - } else { - disable_ddi_buf(encoder, crtc_state); - } + if (DISPLAY_VER(display) < 14) + intel_wait_ddi_buf_idle(dev_priv, port); intel_ddi_wait_for_fec_status(encoder, crtc_state, false); } From a23592837c4517e393f001f0189aaadb34145e35 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:20:00 +0200 Subject: [PATCH 247/284] drm/i915/ddi: Add a helper to enable a port Add a helper to enable a port instead of open-coding it. While at it rename intel_disable_ddi_buf() to intel_ddi_buf_disable() for consistency. v2: (Jani) - s/intel_enable_ddi_buf/intel_ddi_buf_enable - s/intel_disable_ddi_buf/intel_ddi_buf_disable Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-11-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 40 +++++++++++------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index a96b9b934d70b..0a9ea34f0215a 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3072,7 +3072,18 @@ mtl_ddi_disable_d2d(struct intel_encoder *encoder) port_name(port)); } -static void intel_disable_ddi_buf(struct intel_encoder *encoder, +static void intel_ddi_buf_enable(struct intel_encoder *encoder, u32 buf_ctl) +{ + struct intel_display *display = to_intel_display(encoder); + enum port port = encoder->port; + + intel_de_write(display, DDI_BUF_CTL(port), buf_ctl | DDI_BUF_CTL_ENABLE); + intel_de_posting_read(display, DDI_BUF_CTL(port)); + + intel_wait_ddi_buf_active(encoder); +} + +static void intel_ddi_buf_disable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(encoder); @@ -3136,7 +3147,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, intel_ddi_disable_transcoder_clock(old_crtc_state); } - intel_disable_ddi_buf(encoder, old_crtc_state); + intel_ddi_buf_disable(encoder, old_crtc_state); intel_dp_sink_set_fec_ready(intel_dp, old_crtc_state, false); @@ -3185,7 +3196,7 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, if (DISPLAY_VER(dev_priv) < 12) intel_ddi_disable_transcoder_clock(old_crtc_state); - intel_disable_ddi_buf(encoder, old_crtc_state); + intel_ddi_buf_disable(encoder, old_crtc_state); if (DISPLAY_VER(dev_priv) >= 12) intel_ddi_disable_transcoder_clock(old_crtc_state); @@ -3392,7 +3403,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct drm_connector *connector = conn_state->connector; enum port port = encoder->port; - u32 buf_ctl; + u32 buf_ctl = 0; if (!intel_hdmi_handle_sink_scrambling(encoder, connector, crtc_state->hdmi_high_tmds_clock_ratio, @@ -3457,8 +3468,6 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, * is filled with lane count, already set in the crtc_state. * The same is required to be filled in PORT_BUF_CTL for C10/20 Phy. */ - buf_ctl = DDI_BUF_CTL_ENABLE; - if (dig_port->lane_reversal) buf_ctl |= DDI_BUF_PORT_REVERSAL; if (dig_port->ddi_a_4_lanes) @@ -3484,9 +3493,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, buf_ctl |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; } - intel_de_write(dev_priv, DDI_BUF_CTL(port), buf_ctl); - - intel_wait_ddi_buf_active(encoder); + intel_ddi_buf_enable(encoder, buf_ctl); } static void intel_ddi_enable(struct intel_atomic_state *state, @@ -3710,7 +3717,6 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, struct intel_display *display = to_intel_display(crtc_state); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; - enum port port = encoder->port; u32 dp_tp_ctl; /* @@ -3744,15 +3750,11 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, mtl_port_buf_ctl_program(encoder, crtc_state); /* 6.i Configure and enable DDI_CTL_DE to start sending valid data to port slice */ - intel_dp->DP |= DDI_BUF_CTL_ENABLE; if (DISPLAY_VER(display) >= 20) intel_dp->DP |= XE2LPD_DDI_BUF_D2D_LINK_ENABLE; - intel_de_write(display, DDI_BUF_CTL(port), intel_dp->DP); - intel_de_posting_read(display, DDI_BUF_CTL(port)); - - /* 6.j Poll for PORT_BUF_CTL Idle Status == 0, timeout after 100 us */ - intel_wait_ddi_buf_active(encoder); + intel_ddi_buf_enable(encoder, intel_dp->DP); + intel_dp->DP |= DDI_BUF_CTL_ENABLE; } static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, @@ -3762,7 +3764,6 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - enum port port = encoder->port; u32 dp_tp_ctl; dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); @@ -3785,11 +3786,8 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, (intel_tc_port_in_dp_alt_mode(dig_port) || intel_tc_port_in_legacy_mode(dig_port))) adlp_tbt_to_dp_alt_switch_wa(encoder); + intel_ddi_buf_enable(encoder, intel_dp->DP); intel_dp->DP |= DDI_BUF_CTL_ENABLE; - intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); - intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); - - intel_wait_ddi_buf_active(encoder); } static void intel_ddi_set_link_train(struct intel_dp *intel_dp, From 84a357bb0f7120e41620ee7aad3eeca233a4226c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 14 Feb 2025 16:20:01 +0200 Subject: [PATCH 248/284] drm/i915/ddi: Sanitize DDI_BUF_CTL register definitions Align the DDI_BUF_CTL register flag definitions with how this is done elsewhere. v2: Robustify macro calls with parens. (Jani) Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-12-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 50efaab3b5536..3a936a4aa2e88 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3625,27 +3625,29 @@ enum skl_power_gate { #define _DDI_BUF_CTL_B 0x64100 /* Known as DDI_CTL_DE in MTL+ */ #define DDI_BUF_CTL(port) _MMIO_PORT(port, _DDI_BUF_CTL_A, _DDI_BUF_CTL_B) -#define DDI_BUF_CTL_ENABLE (1 << 31) +#define DDI_BUF_CTL_ENABLE REG_BIT(31) #define XE2LPD_DDI_BUF_D2D_LINK_ENABLE REG_BIT(29) #define XE2LPD_DDI_BUF_D2D_LINK_STATE REG_BIT(28) -#define DDI_BUF_TRANS_SELECT(n) ((n) << 24) -#define DDI_BUF_EMP_MASK (0xf << 24) -#define DDI_BUF_PHY_LINK_RATE(r) ((r) << 20) +#define DDI_BUF_EMP_MASK REG_GENMASK(27, 24) +#define DDI_BUF_TRANS_SELECT(n) REG_FIELD_PREP(DDI_BUF_EMP_MASK, (n)) +#define DDI_BUF_PHY_LINK_RATE_MASK REG_GENMASK(23, 20) +#define DDI_BUF_PHY_LINK_RATE(r) REG_FIELD_PREP(DDI_BUF_PHY_LINK_RATE_MASK, (r)) #define DDI_BUF_PORT_DATA_MASK REG_GENMASK(19, 18) #define DDI_BUF_PORT_DATA_10BIT REG_FIELD_PREP(DDI_BUF_PORT_DATA_MASK, 0) #define DDI_BUF_PORT_DATA_20BIT REG_FIELD_PREP(DDI_BUF_PORT_DATA_MASK, 1) #define DDI_BUF_PORT_DATA_40BIT REG_FIELD_PREP(DDI_BUF_PORT_DATA_MASK, 2) -#define DDI_BUF_PORT_REVERSAL (1 << 16) +#define DDI_BUF_PORT_REVERSAL REG_BIT(16) #define DDI_BUF_LANE_STAGGER_DELAY_MASK REG_GENMASK(15, 8) #define DDI_BUF_LANE_STAGGER_DELAY(symbols) REG_FIELD_PREP(DDI_BUF_LANE_STAGGER_DELAY_MASK, \ (symbols)) -#define DDI_BUF_IS_IDLE (1 << 7) +#define DDI_BUF_IS_IDLE REG_BIT(7) #define DDI_BUF_CTL_TC_PHY_OWNERSHIP REG_BIT(6) -#define DDI_A_4_LANES (1 << 4) -#define DDI_PORT_WIDTH(width) (((width) == 3 ? 4 : ((width) - 1)) << 1) -#define DDI_PORT_WIDTH_MASK (7 << 1) +#define DDI_A_4_LANES REG_BIT(4) +#define DDI_PORT_WIDTH_MASK REG_GENMASK(3, 1) +#define DDI_PORT_WIDTH(width) REG_FIELD_PREP(DDI_PORT_WIDTH_MASK, \ + ((width) == 3 ? 4 : (width) - 1)) #define DDI_PORT_WIDTH_SHIFT 1 -#define DDI_INIT_DISPLAY_DETECTED (1 << 0) +#define DDI_INIT_DISPLAY_DETECTED REG_BIT(0) /* DDI Buffer Translations */ #define _DDI_BUF_TRANS_A 0x64E00 From 91077d1deb5374eb8be00fb391710f00e751dc4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Feb 2025 18:43:21 +0200 Subject: [PATCH 249/284] drm/i915: Make sure all planes in use by the joiner have their crtc included MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Any active plane needs to have its crtc included in the atomic state. For planes enabled via uapi that is all handler in the core. But when we use a plane for joiner the uapi code things the plane is disabled and therefore doesn't have a crtc. So we need to pull those in by hand. We do it first thing in intel_joiner_add_affected_crtcs() so that any newly added crtc will subsequently pull in all of its joined crtcs as well. The symptoms from failing to do this are: - duct tape in the form of commit 1d5b09f8daf8 ("drm/i915: Fix NULL ptr deref by checking new_crtc_state") - the plane's hw state will get overwritten by the disabled uapi state if it can't find the uapi counterpart plane in the atomic state from where it should copy the correct state Cc: stable@vger.kernel.org Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-2-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e7f76306d4e68..407cac30ee5fd 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6690,12 +6690,30 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state) { struct drm_i915_private *i915 = to_i915(state->base.dev); + const struct intel_plane_state *plane_state; struct intel_crtc_state *crtc_state; + struct intel_plane *plane; struct intel_crtc *crtc; u8 affected_pipes = 0; u8 modeset_pipes = 0; int i; + /* + * Any plane which is in use by the joiner needs its crtc. + * Pull those in first as this will not have happened yet + * if the plane remains disabled according to uapi. + */ + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { + crtc = to_intel_crtc(plane_state->hw.crtc); + if (!crtc) + continue; + + crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + } + + /* Now pull in all joined crtcs */ for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { affected_pipes |= crtc_state->joiner_pipes; if (intel_crtc_needs_modeset(crtc_state)) From 58456143cc849ebd2e338d28d64747179e220a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Feb 2025 18:43:22 +0200 Subject: [PATCH 250/284] Revert "drm/i915: Fix NULL ptr deref by checking new_crtc_state" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 1d5b09f8daf859247a1ea65b0d732a24d88980d8. Now that the root cause the missing crtc state has been fixed we can get rid of the duct tape. Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_atomic_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 8a49d87d9bd9c..f26b82b6821ad 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -1132,7 +1132,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, * This should only fail upon a hung GPU, in which case we * can safely continue. */ - if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state)) { + if (intel_crtc_needs_modeset(new_crtc_state)) { ret = add_dma_resv_fences(old_obj->resv, &new_plane_state->uapi); if (ret < 0) From 00c8e0dd3dcd7016584ca131d26a88e4fbabe001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Feb 2025 18:43:23 +0200 Subject: [PATCH 251/284] drm/i915: Rework joiner and Y plane dependency handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current code tries to handle joiner vs. Y planes completely independently. That does not really work since each pipe selects its Y planes completely independently, and any plane pulled into the state by one of the secondary pipes needs to have the plane on the primary pipe also included in the state (for the uapi state copy). The current code sometimes forgets to pull in planes that we need, leading to weird things like the Y<->UV plane link only getting torn down from one side but not the other. Remedy the situation by pulling in the exact same set planes on all the joined pipes. To calculate the set we simply look through each joined crtc and any plane in the state gets added to the set. However due to the way the Y plane selection works we may not be able to determine the set in one go. One plane on one pipe may pull in a Y plane, which may have to pull in another plane because it's not acting in the same role on another pipe, etc. The simple approach taken here is to keep looping and adding planes to the set until it stops growing. I suppose if we tracked more of this Y plane stuff in the crtc state rather than the plane state we might be able to do it in one go. But this works, and it's not going to loop for long anyway since we only have so many pipes and Y planes to consider. Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 104 ++++++++++--------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 407cac30ee5fd..4681da6cc74ef 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4405,31 +4405,6 @@ static bool check_single_encoder_cloning(struct intel_atomic_state *state, return true; } -static int icl_add_linked_planes(struct intel_atomic_state *state) -{ - struct intel_plane *plane, *linked; - struct intel_plane_state *plane_state, *linked_plane_state; - int i; - - for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - linked = plane_state->planar_linked_plane; - - if (!linked) - continue; - - linked_plane_state = intel_atomic_get_plane_state(state, linked); - if (IS_ERR(linked_plane_state)) - return PTR_ERR(linked_plane_state); - - drm_WARN_ON(state->base.dev, - linked_plane_state->planar_linked_plane != plane); - drm_WARN_ON(state->base.dev, - linked_plane_state->planar_slave == plane_state->planar_slave); - } - - return 0; -} - static int icl_check_nv12_planes(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -6180,44 +6155,75 @@ static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv) IS_IVYBRIDGE(dev_priv); } -static int intel_crtc_add_joiner_planes(struct intel_atomic_state *state, - struct intel_crtc *crtc, - struct intel_crtc *other) +static u8 intel_joiner_affected_planes(struct intel_atomic_state *state, + u8 joined_pipes) { - const struct intel_plane_state __maybe_unused *plane_state; + const struct intel_plane_state *plane_state; struct intel_plane *plane; - u8 plane_ids = 0; + u8 affected_planes = 0; int i; for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - if (plane->pipe == crtc->pipe) - plane_ids |= BIT(plane->id); + struct intel_plane *linked = plane_state->planar_linked_plane; + + if ((joined_pipes & BIT(plane->pipe)) == 0) + continue; + + affected_planes |= BIT(plane->id); + if (linked) + affected_planes |= BIT(linked->id); } - return intel_crtc_add_planes_to_state(state, other, plane_ids); + return affected_planes; } -static int intel_joiner_add_affected_planes(struct intel_atomic_state *state) +static int intel_joiner_add_affected_planes(struct intel_atomic_state *state, + u8 joined_pipes) { - struct drm_i915_private *i915 = to_i915(state->base.dev); - const struct intel_crtc_state *crtc_state; - struct intel_crtc *crtc; - int i; + u8 prev_affected_planes, affected_planes = 0; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { - struct intel_crtc *other; + /* + * We want all the joined pipes to have the same + * set of planes in the atomic state, to make sure + * state copying always works correctly, and the + * UV<->Y plane linkage is always up to date. + * Keep pulling planes in until we've determined + * the full set of affected planes. A bit complicated + * on account of each pipe being capable of selecting + * their own Y planes independently of the other pipes, + * and the selection being done from the set of + * inactive planes. + */ + do { + struct intel_crtc *crtc; - for_each_intel_crtc_in_pipe_mask(&i915->drm, other, - crtc_state->joiner_pipes) { + for_each_intel_crtc_in_pipe_mask(state->base.dev, crtc, joined_pipes) { int ret; - if (crtc == other) - continue; - - ret = intel_crtc_add_joiner_planes(state, crtc, other); + ret = intel_crtc_add_planes_to_state(state, crtc, affected_planes); if (ret) return ret; } + + prev_affected_planes = affected_planes; + affected_planes = intel_joiner_affected_planes(state, joined_pipes); + } while (affected_planes != prev_affected_planes); + + return 0; +} + +static int intel_add_affected_planes(struct intel_atomic_state *state) +{ + const struct intel_crtc_state *crtc_state; + struct intel_crtc *crtc; + int i; + + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + int ret; + + ret = intel_joiner_add_affected_planes(state, intel_crtc_joined_pipe_mask(crtc_state)); + if (ret) + return ret; } return 0; @@ -6232,11 +6238,7 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state) struct intel_crtc *crtc; int i, ret; - ret = icl_add_linked_planes(state); - if (ret) - return ret; - - ret = intel_joiner_add_affected_planes(state); + ret = intel_add_affected_planes(state); if (ret) return ret; From f709c06af881e4e2d5afd14e59aa08adbd9d2b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Feb 2025 18:43:24 +0200 Subject: [PATCH 252/284] drm/i915: s/planar_slave/is_y_plane/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bspec talks about Y planes, not planar slaves. Switch to using the same terminology to make life a bit less confusing. v2: Adjust some comments too (Maarten) Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-5-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_atomic_plane.c | 4 ++-- drivers/gpu/drm/i915/display/intel_display.c | 12 ++++++------ .../gpu/drm/i915/display/intel_display_debugfs.c | 6 +++--- drivers/gpu/drm/i915/display/intel_display_types.h | 13 +++---------- drivers/gpu/drm/i915/display/skl_universal_plane.c | 3 +-- drivers/gpu/drm/i915/display/skl_watermark.c | 4 ++-- 6 files changed, 17 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index f26b82b6821ad..71263fbf00472 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -841,7 +841,7 @@ void intel_crtc_planes_update_noarm(struct intel_dsb *dsb, /* TODO: for mailbox updates this should be skipped */ if (new_plane_state->uapi.visible || - new_plane_state->planar_slave) + new_plane_state->is_y_plane) intel_plane_update_noarm(dsb, plane, new_crtc_state, new_plane_state); } @@ -874,7 +874,7 @@ static void skl_crtc_planes_update_arm(struct intel_dsb *dsb, * would have to be called here as well. */ if (new_plane_state->uapi.visible || - new_plane_state->planar_slave) + new_plane_state->is_y_plane) intel_plane_update_arm(dsb, plane, new_crtc_state, new_plane_state); else intel_plane_disable_arm(dsb, plane, new_crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 4681da6cc74ef..4c07e0c99ec84 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4420,7 +4420,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, return 0; /* - * Destroy all old plane links and make the slave plane invisible + * Destroy all old plane links and make the Y plane invisible * in the crtc_state->active_planes mask. */ for_each_new_intel_plane_in_state(state, plane, plane_state, i) { @@ -4428,7 +4428,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, continue; plane_state->planar_linked_plane = NULL; - if (plane_state->planar_slave && !plane_state->uapi.visible) { + if (plane_state->is_y_plane && !plane_state->uapi.visible) { crtc_state->enabled_planes &= ~BIT(plane->id); crtc_state->active_planes &= ~BIT(plane->id); crtc_state->update_planes |= BIT(plane->id); @@ -4436,7 +4436,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, crtc_state->rel_data_rate[plane->id] = 0; } - plane_state->planar_slave = false; + plane_state->is_y_plane = false; } if (!crtc_state->nv12_planes) @@ -4473,7 +4473,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, plane_state->planar_linked_plane = linked; - linked_state->planar_slave = true; + linked_state->is_y_plane = true; linked_state->planar_linked_plane = plane; crtc_state->enabled_planes |= BIT(linked->id); crtc_state->active_planes |= BIT(linked->id); @@ -4486,7 +4486,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, plane->base.base.id, plane->base.name, linked->base.base.id, linked->base.name); - /* Copy parameters to slave plane */ + /* Copy parameters to Y plane */ linked_state->ctl = plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE; linked_state->color_ctl = plane_state->color_ctl; linked_state->view = plane_state->view; @@ -5820,7 +5820,7 @@ intel_verify_planes(struct intel_atomic_state *state) for_each_new_intel_plane_in_state(state, plane, plane_state, i) - assert_plane(plane, plane_state->planar_slave || + assert_plane(plane, plane_state->is_y_plane || plane_state->uapi.visible); } diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index a646560f4f5b9..9de7e512c0ab4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -330,8 +330,8 @@ static const char *plane_visibility(const struct intel_plane_state *plane_state) if (plane_state->uapi.visible) return "visible"; - if (plane_state->planar_slave) - return "planar-slave"; + if (plane_state->is_y_plane) + return "Y plane"; return "hidden"; } @@ -364,7 +364,7 @@ static void intel_plane_uapi_info(struct seq_file *m, struct intel_plane *plane) if (plane_state->planar_linked_plane) seq_printf(m, "\t\tplanar: Linked to [PLANE:%d:%s] as a %s\n", plane_state->planar_linked_plane->base.base.id, plane_state->planar_linked_plane->base.name, - plane_state->planar_slave ? "slave" : "master"); + plane_state->is_y_plane ? "Y plane" : "UV plane"); } static void intel_plane_hw_info(struct seq_file *m, struct intel_plane *plane) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 6a82c6ade549b..6c1c88ed0ba67 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -640,6 +640,9 @@ struct intel_plane_state { /* Plane state to display black pixels when pxp is borked */ bool force_black; + /* Acting as Y plane for another UV plane? */ + bool is_y_plane; + /* plane control register */ u32 ctl; @@ -679,16 +682,6 @@ struct intel_plane_state { */ struct intel_plane *planar_linked_plane; - /* - * planar_slave: - * If set don't update use the linked plane's state for updating - * this plane during atomic commit with the update_slave() callback. - * - * It's also used by the watermark code to ignore wm calculations on - * this plane. They're calculated by the linked plane's wm code. - */ - u32 planar_slave; - struct drm_intel_sprite_colorkey ckey; struct drm_rect psr2_sel_fetch_area; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index eb85d3d6cdc3c..4b8732ae65aa0 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1375,8 +1375,7 @@ static void icl_plane_csc_load_black(struct intel_dsb *dsb, static int icl_plane_color_plane(const struct intel_plane_state *plane_state) { - /* Program the UV plane on planar master */ - if (plane_state->planar_linked_plane && !plane_state->planar_slave) + if (plane_state->planar_linked_plane && !plane_state->is_y_plane) return 1; else return 0; diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 9e97fc7039031..10a1daad28eb1 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -2260,8 +2260,8 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state, struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane_id]; int ret; - /* Watermarks calculated in master */ - if (plane_state->planar_slave) + /* Watermarks calculated on UV plane */ + if (plane_state->is_y_plane) return 0; memset(wm, 0, sizeof(*wm)); From a33a6b2f0824387b97dfdf3549239e5d70a437df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Feb 2025 18:43:25 +0200 Subject: [PATCH 253/284] drm/i915: Extract unlink_nv12_plane() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the details of the nv12 plane unlinking to a small function to make the higher level code less messy. Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-6-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 32 +++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 4c07e0c99ec84..de5cb1cd3f888 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4405,6 +4405,24 @@ static bool check_single_encoder_cloning(struct intel_atomic_state *state, return true; } +static void unlink_nv12_plane(struct intel_crtc_state *crtc_state, + struct intel_plane_state *plane_state) +{ + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + plane_state->planar_linked_plane = NULL; + + if (plane_state->is_y_plane && !plane_state->uapi.visible) { + crtc_state->enabled_planes &= ~BIT(plane->id); + crtc_state->active_planes &= ~BIT(plane->id); + crtc_state->update_planes |= BIT(plane->id); + crtc_state->data_rate[plane->id] = 0; + crtc_state->rel_data_rate[plane->id] = 0; + } + + plane_state->is_y_plane = false; +} + static int icl_check_nv12_planes(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -4424,19 +4442,11 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, * in the crtc_state->active_planes mask. */ for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - if (plane->pipe != crtc->pipe || !plane_state->planar_linked_plane) + if (plane->pipe != crtc->pipe) continue; - plane_state->planar_linked_plane = NULL; - if (plane_state->is_y_plane && !plane_state->uapi.visible) { - crtc_state->enabled_planes &= ~BIT(plane->id); - crtc_state->active_planes &= ~BIT(plane->id); - crtc_state->update_planes |= BIT(plane->id); - crtc_state->data_rate[plane->id] = 0; - crtc_state->rel_data_rate[plane->id] = 0; - } - - plane_state->is_y_plane = false; + if (plane_state->planar_linked_plane) + unlink_nv12_plane(crtc_state, plane_state); } if (!crtc_state->nv12_planes) From 6a01df2f1b2a3b29721143729a3feff816bc0083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Feb 2025 18:43:26 +0200 Subject: [PATCH 254/284] drm/i915: Remove pointless visible check in unlink_nv12_plane() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit visible can't be true when is_y_plane is true. Replace the bogus check with an WARN_ON(). Flatten the function while at it. Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index de5cb1cd3f888..041a27af0e23b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4408,19 +4408,23 @@ static bool check_single_encoder_cloning(struct intel_atomic_state *state, static void unlink_nv12_plane(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); plane_state->planar_linked_plane = NULL; - if (plane_state->is_y_plane && !plane_state->uapi.visible) { - crtc_state->enabled_planes &= ~BIT(plane->id); - crtc_state->active_planes &= ~BIT(plane->id); - crtc_state->update_planes |= BIT(plane->id); - crtc_state->data_rate[plane->id] = 0; - crtc_state->rel_data_rate[plane->id] = 0; - } + if (!plane_state->is_y_plane) + return; + + drm_WARN_ON(display->drm, plane_state->uapi.visible); plane_state->is_y_plane = false; + + crtc_state->enabled_planes &= ~BIT(plane->id); + crtc_state->active_planes &= ~BIT(plane->id); + crtc_state->update_planes |= BIT(plane->id); + crtc_state->data_rate[plane->id] = 0; + crtc_state->rel_data_rate[plane->id] = 0; } static int icl_check_nv12_planes(struct intel_atomic_state *state, From a1a9d90e6681a14335be51f3de0ee66e2446ee52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Feb 2025 18:43:27 +0200 Subject: [PATCH 255/284] drm/i915: Extract link_nv12_planes() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the code linking the UV and Y planes together into a sensible function instead of having the code plastered inside the higher level loop. v2: Rebase due to intel_display changes Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-8-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 86 +++++++++++--------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 041a27af0e23b..71292e17f74a0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4405,6 +4405,54 @@ static bool check_single_encoder_cloning(struct intel_atomic_state *state, return true; } +static void link_nv12_planes(struct intel_crtc_state *crtc_state, + struct intel_plane_state *plane_state, + struct intel_plane_state *linked_state) +{ + struct intel_display *display = to_intel_display(plane_state); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + struct intel_plane *linked = to_intel_plane(linked_state->uapi.plane); + + drm_dbg_kms(display->drm, "UV plane [PLANE:%d:%s] using Y plane [PLANE:%d:%s]\n", + plane->base.base.id, plane->base.name, + linked->base.base.id, linked->base.name); + + plane_state->planar_linked_plane = linked; + + linked_state->is_y_plane = true; + linked_state->planar_linked_plane = plane; + + crtc_state->enabled_planes |= BIT(linked->id); + crtc_state->active_planes |= BIT(linked->id); + crtc_state->update_planes |= BIT(linked->id); + + crtc_state->data_rate[linked->id] = crtc_state->data_rate_y[plane->id]; + crtc_state->rel_data_rate[linked->id] = crtc_state->rel_data_rate_y[plane->id]; + + /* Copy parameters to Y plane */ + linked_state->ctl = plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE; + linked_state->color_ctl = plane_state->color_ctl; + linked_state->view = plane_state->view; + linked_state->decrypt = plane_state->decrypt; + + intel_plane_copy_hw_state(linked_state, plane_state); + linked_state->uapi.src = plane_state->uapi.src; + linked_state->uapi.dst = plane_state->uapi.dst; + + if (icl_is_hdr_plane(display, plane->id)) { + if (linked->id == PLANE_7) + plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL; + else if (linked->id == PLANE_6) + plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_6_ICL; + else if (linked->id == PLANE_5) + plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_5_RKL; + else if (linked->id == PLANE_4) + plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_4_RKL; + else + MISSING_CASE(linked->id); + } +} + static void unlink_nv12_plane(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { @@ -4485,43 +4533,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, return -EINVAL; } - plane_state->planar_linked_plane = linked; - - linked_state->is_y_plane = true; - linked_state->planar_linked_plane = plane; - crtc_state->enabled_planes |= BIT(linked->id); - crtc_state->active_planes |= BIT(linked->id); - crtc_state->update_planes |= BIT(linked->id); - crtc_state->data_rate[linked->id] = - crtc_state->data_rate_y[plane->id]; - crtc_state->rel_data_rate[linked->id] = - crtc_state->rel_data_rate_y[plane->id]; - drm_dbg_kms(&dev_priv->drm, "UV plane [PLANE:%d:%s] using [PLANE:%d:%s] as Y plane\n", - plane->base.base.id, plane->base.name, - linked->base.base.id, linked->base.name); - - /* Copy parameters to Y plane */ - linked_state->ctl = plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE; - linked_state->color_ctl = plane_state->color_ctl; - linked_state->view = plane_state->view; - linked_state->decrypt = plane_state->decrypt; - - intel_plane_copy_hw_state(linked_state, plane_state); - linked_state->uapi.src = plane_state->uapi.src; - linked_state->uapi.dst = plane_state->uapi.dst; - - if (icl_is_hdr_plane(display, plane->id)) { - if (linked->id == PLANE_7) - plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL; - else if (linked->id == PLANE_6) - plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_6_ICL; - else if (linked->id == PLANE_5) - plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_5_RKL; - else if (linked->id == PLANE_4) - plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_4_RKL; - else - MISSING_CASE(linked->id); - } + link_nv12_planes(crtc_state, plane_state, linked_state); } return 0; From c324dbd23149b86686b20a822c3fc75c9eddfff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Feb 2025 18:43:28 +0200 Subject: [PATCH 256/284] drm/i915: Rename the variables in icl_check_nv12_planes() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the this generic 'plane' vs 'linked' stuff is hard to follow. Rename the variables to use the y_plane vs. uv_plane terminology to make it clear which is which. v2: Rebase due to intel_display changes Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-9-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 103 ++++++++++--------- 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 71292e17f74a0..bb32c295667b1 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4406,50 +4406,56 @@ static bool check_single_encoder_cloning(struct intel_atomic_state *state, } static void link_nv12_planes(struct intel_crtc_state *crtc_state, - struct intel_plane_state *plane_state, - struct intel_plane_state *linked_state) + struct intel_plane_state *uv_plane_state, + struct intel_plane_state *y_plane_state) { - struct intel_display *display = to_intel_display(plane_state); - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct intel_plane *linked = to_intel_plane(linked_state->uapi.plane); + struct intel_display *display = to_intel_display(uv_plane_state); + struct intel_plane *uv_plane = to_intel_plane(uv_plane_state->uapi.plane); + struct intel_plane *y_plane = to_intel_plane(y_plane_state->uapi.plane); drm_dbg_kms(display->drm, "UV plane [PLANE:%d:%s] using Y plane [PLANE:%d:%s]\n", - plane->base.base.id, plane->base.name, - linked->base.base.id, linked->base.name); + uv_plane->base.base.id, uv_plane->base.name, + y_plane->base.base.id, y_plane->base.name); - plane_state->planar_linked_plane = linked; + uv_plane_state->planar_linked_plane = y_plane; - linked_state->is_y_plane = true; - linked_state->planar_linked_plane = plane; + y_plane_state->is_y_plane = true; + y_plane_state->planar_linked_plane = uv_plane; - crtc_state->enabled_planes |= BIT(linked->id); - crtc_state->active_planes |= BIT(linked->id); - crtc_state->update_planes |= BIT(linked->id); + crtc_state->enabled_planes |= BIT(y_plane->id); + crtc_state->active_planes |= BIT(y_plane->id); + crtc_state->update_planes |= BIT(y_plane->id); - crtc_state->data_rate[linked->id] = crtc_state->data_rate_y[plane->id]; - crtc_state->rel_data_rate[linked->id] = crtc_state->rel_data_rate_y[plane->id]; + crtc_state->data_rate[y_plane->id] = crtc_state->data_rate_y[uv_plane->id]; + crtc_state->rel_data_rate[y_plane->id] = crtc_state->rel_data_rate_y[uv_plane->id]; /* Copy parameters to Y plane */ - linked_state->ctl = plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE; - linked_state->color_ctl = plane_state->color_ctl; - linked_state->view = plane_state->view; - linked_state->decrypt = plane_state->decrypt; - - intel_plane_copy_hw_state(linked_state, plane_state); - linked_state->uapi.src = plane_state->uapi.src; - linked_state->uapi.dst = plane_state->uapi.dst; - - if (icl_is_hdr_plane(display, plane->id)) { - if (linked->id == PLANE_7) - plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL; - else if (linked->id == PLANE_6) - plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_6_ICL; - else if (linked->id == PLANE_5) - plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_5_RKL; - else if (linked->id == PLANE_4) - plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_4_RKL; - else - MISSING_CASE(linked->id); + y_plane_state->ctl = uv_plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE; + y_plane_state->color_ctl = uv_plane_state->color_ctl; + y_plane_state->view = uv_plane_state->view; + y_plane_state->decrypt = uv_plane_state->decrypt; + + intel_plane_copy_hw_state(y_plane_state, uv_plane_state); + y_plane_state->uapi.src = uv_plane_state->uapi.src; + y_plane_state->uapi.dst = uv_plane_state->uapi.dst; + + if (icl_is_hdr_plane(display, uv_plane->id)) { + switch (y_plane->id) { + case PLANE_7: + uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL; + break; + case PLANE_6: + uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_6_ICL; + break; + case PLANE_5: + uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_5_RKL; + break; + case PLANE_4: + uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_4_RKL; + break; + default: + MISSING_CASE(y_plane->id); + } } } @@ -4482,8 +4488,8 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - struct intel_plane *plane, *linked; struct intel_plane_state *plane_state; + struct intel_plane *plane; int i; if (DISPLAY_VER(dev_priv) < 11) @@ -4505,27 +4511,30 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, return 0; for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - struct intel_plane_state *linked_state = NULL; + struct intel_plane_state *y_plane_state = NULL; + struct intel_plane *y_plane; + + if (plane->pipe != crtc->pipe) + continue; - if (plane->pipe != crtc->pipe || - !(crtc_state->nv12_planes & BIT(plane->id))) + if ((crtc_state->nv12_planes & BIT(plane->id)) == 0) continue; - for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, linked) { - if (!icl_is_nv12_y_plane(display, linked->id)) + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, y_plane) { + if (!icl_is_nv12_y_plane(display, y_plane->id)) continue; - if (crtc_state->active_planes & BIT(linked->id)) + if (crtc_state->active_planes & BIT(y_plane->id)) continue; - linked_state = intel_atomic_get_plane_state(state, linked); - if (IS_ERR(linked_state)) - return PTR_ERR(linked_state); + y_plane_state = intel_atomic_get_plane_state(state, y_plane); + if (IS_ERR(y_plane_state)) + return PTR_ERR(y_plane_state); break; } - if (!linked_state) { + if (!y_plane_state) { drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s] need %d free Y planes for planar YUV\n", crtc->base.base.id, crtc->base.name, @@ -4533,7 +4542,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, return -EINVAL; } - link_nv12_planes(crtc_state, plane_state, linked_state); + link_nv12_planes(crtc_state, plane_state, y_plane_state); } return 0; From 778be378be2a0e0528dd1ea44ed3dc9804950fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Feb 2025 18:43:29 +0200 Subject: [PATCH 257/284] drm/i915: Move icl+ nv12 plane register mangling into skl_universal_plane.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try to keep all the low level skl+ universal plane register details inside skl_universal_plane.c instead of having them sprinkled all over the place. v2: Rebase due to intel_display changes Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-10-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 30 ++++------------- .../drm/i915/display/skl_universal_plane.c | 32 +++++++++++++++++++ .../drm/i915/display/skl_universal_plane.h | 3 ++ 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index bb32c295667b1..251fcce426943 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -123,7 +123,6 @@ #include "intel_wm.h" #include "skl_scaler.h" #include "skl_universal_plane.h" -#include "skl_universal_plane_regs.h" #include "skl_watermark.h" #include "vlv_dpio_phy_regs.h" #include "vlv_dsi.h" @@ -4430,33 +4429,16 @@ static void link_nv12_planes(struct intel_crtc_state *crtc_state, crtc_state->rel_data_rate[y_plane->id] = crtc_state->rel_data_rate_y[uv_plane->id]; /* Copy parameters to Y plane */ - y_plane_state->ctl = uv_plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE; - y_plane_state->color_ctl = uv_plane_state->color_ctl; - y_plane_state->view = uv_plane_state->view; - y_plane_state->decrypt = uv_plane_state->decrypt; - intel_plane_copy_hw_state(y_plane_state, uv_plane_state); y_plane_state->uapi.src = uv_plane_state->uapi.src; y_plane_state->uapi.dst = uv_plane_state->uapi.dst; - if (icl_is_hdr_plane(display, uv_plane->id)) { - switch (y_plane->id) { - case PLANE_7: - uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL; - break; - case PLANE_6: - uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_6_ICL; - break; - case PLANE_5: - uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_5_RKL; - break; - case PLANE_4: - uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_4_RKL; - break; - default: - MISSING_CASE(y_plane->id); - } - } + y_plane_state->ctl = uv_plane_state->ctl; + y_plane_state->color_ctl = uv_plane_state->color_ctl; + y_plane_state->view = uv_plane_state->view; + y_plane_state->decrypt = uv_plane_state->decrypt; + + icl_link_nv12_planes(uv_plane_state, y_plane_state); } static void unlink_nv12_plane(struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 4b8732ae65aa0..110f66dd5cf00 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2327,6 +2327,38 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state, return 0; } +void icl_link_nv12_planes(struct intel_plane_state *uv_plane_state, + struct intel_plane_state *y_plane_state) +{ + struct intel_display *display = to_intel_display(uv_plane_state); + struct intel_plane *uv_plane = to_intel_plane(uv_plane_state->uapi.plane); + struct intel_plane *y_plane = to_intel_plane(y_plane_state->uapi.plane); + + drm_WARN_ON(display->drm, icl_is_nv12_y_plane(display, uv_plane->id)); + drm_WARN_ON(display->drm, !icl_is_nv12_y_plane(display, y_plane->id)); + + y_plane_state->ctl |= PLANE_CTL_YUV420_Y_PLANE; + + if (icl_is_hdr_plane(display, uv_plane->id)) { + switch (y_plane->id) { + case PLANE_7: + uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL; + break; + case PLANE_6: + uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_6_ICL; + break; + case PLANE_5: + uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_5_RKL; + break; + case PLANE_4: + uv_plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_4_RKL; + break; + default: + MISSING_CASE(y_plane->id); + } + } +} + static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe) { return pipe - PIPE_A + INTEL_FBC_A; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.h b/drivers/gpu/drm/i915/display/skl_universal_plane.h index 0ce240e9ca5ae..5e2451c21eeb4 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.h +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.h @@ -32,6 +32,9 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha); int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state, int *x, int *y, u32 *offset); +void icl_link_nv12_planes(struct intel_plane_state *uv_plane_state, + struct intel_plane_state *y_plane_state); + bool icl_is_nv12_y_plane(struct intel_display *display, enum plane_id plane_id); u8 icl_hdr_plane_mask(void); From ab2b059467c94a5cb1869e238dd752127a45d122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Feb 2025 18:43:30 +0200 Subject: [PATCH 258/284] drm/i915: Relocate intel_atomic_check_planes() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move all the intel_atomic_check_planes() machinery into intel_atomic_plane.c in order to declutter intel_display.c. v2: Rebase due to intel_display changes Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-11-ville.syrjala@linux.intel.com --- .../gpu/drm/i915/display/intel_atomic_plane.c | 296 ++++++++++++++++++ .../gpu/drm/i915/display/intel_atomic_plane.h | 3 + drivers/gpu/drm/i915/display/intel_display.c | 295 ----------------- drivers/gpu/drm/i915/display/intel_display.h | 2 - 4 files changed, 299 insertions(+), 297 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 71263fbf00472..f58169763835b 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -52,6 +52,7 @@ #include "intel_fb.h" #include "intel_fb_pin.h" #include "skl_scaler.h" +#include "skl_universal_plane.h" #include "skl_watermark.h" static void intel_plane_state_reset(struct intel_plane_state *plane_state, @@ -1223,3 +1224,298 @@ void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_sta drm_vblank_work_init(&old_plane_state->unpin_work, old_plane_state->uapi.crtc, intel_cursor_unpin_work); } + +static void link_nv12_planes(struct intel_crtc_state *crtc_state, + struct intel_plane_state *uv_plane_state, + struct intel_plane_state *y_plane_state) +{ + struct intel_display *display = to_intel_display(uv_plane_state); + struct intel_plane *uv_plane = to_intel_plane(uv_plane_state->uapi.plane); + struct intel_plane *y_plane = to_intel_plane(y_plane_state->uapi.plane); + + drm_dbg_kms(display->drm, "UV plane [PLANE:%d:%s] using Y plane [PLANE:%d:%s]\n", + uv_plane->base.base.id, uv_plane->base.name, + y_plane->base.base.id, y_plane->base.name); + + uv_plane_state->planar_linked_plane = y_plane; + + y_plane_state->is_y_plane = true; + y_plane_state->planar_linked_plane = uv_plane; + + crtc_state->enabled_planes |= BIT(y_plane->id); + crtc_state->active_planes |= BIT(y_plane->id); + crtc_state->update_planes |= BIT(y_plane->id); + + crtc_state->data_rate[y_plane->id] = crtc_state->data_rate_y[uv_plane->id]; + crtc_state->rel_data_rate[y_plane->id] = crtc_state->rel_data_rate_y[uv_plane->id]; + + /* Copy parameters to Y plane */ + intel_plane_copy_hw_state(y_plane_state, uv_plane_state); + y_plane_state->uapi.src = uv_plane_state->uapi.src; + y_plane_state->uapi.dst = uv_plane_state->uapi.dst; + + y_plane_state->ctl = uv_plane_state->ctl; + y_plane_state->color_ctl = uv_plane_state->color_ctl; + y_plane_state->view = uv_plane_state->view; + y_plane_state->decrypt = uv_plane_state->decrypt; + + icl_link_nv12_planes(uv_plane_state, y_plane_state); +} + +static void unlink_nv12_plane(struct intel_crtc_state *crtc_state, + struct intel_plane_state *plane_state) +{ + struct intel_display *display = to_intel_display(plane_state); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + plane_state->planar_linked_plane = NULL; + + if (!plane_state->is_y_plane) + return; + + drm_WARN_ON(display->drm, plane_state->uapi.visible); + + plane_state->is_y_plane = false; + + crtc_state->enabled_planes &= ~BIT(plane->id); + crtc_state->active_planes &= ~BIT(plane->id); + crtc_state->update_planes |= BIT(plane->id); + crtc_state->data_rate[plane->id] = 0; + crtc_state->rel_data_rate[plane->id] = 0; +} + +static int icl_check_nv12_planes(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(state); + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + struct intel_plane_state *plane_state; + struct intel_plane *plane; + int i; + + if (DISPLAY_VER(dev_priv) < 11) + return 0; + + /* + * Destroy all old plane links and make the Y plane invisible + * in the crtc_state->active_planes mask. + */ + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { + if (plane->pipe != crtc->pipe) + continue; + + if (plane_state->planar_linked_plane) + unlink_nv12_plane(crtc_state, plane_state); + } + + if (!crtc_state->nv12_planes) + return 0; + + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { + struct intel_plane_state *y_plane_state = NULL; + struct intel_plane *y_plane; + + if (plane->pipe != crtc->pipe) + continue; + + if ((crtc_state->nv12_planes & BIT(plane->id)) == 0) + continue; + + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, y_plane) { + if (!icl_is_nv12_y_plane(display, y_plane->id)) + continue; + + if (crtc_state->active_planes & BIT(y_plane->id)) + continue; + + y_plane_state = intel_atomic_get_plane_state(state, y_plane); + if (IS_ERR(y_plane_state)) + return PTR_ERR(y_plane_state); + + break; + } + + if (!y_plane_state) { + drm_dbg_kms(&dev_priv->drm, + "[CRTC:%d:%s] need %d free Y planes for planar YUV\n", + crtc->base.base.id, crtc->base.name, + hweight8(crtc_state->nv12_planes)); + return -EINVAL; + } + + link_nv12_planes(crtc_state, plane_state, y_plane_state); + } + + return 0; +} + +static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state, + struct intel_crtc *crtc, + u8 plane_ids_mask) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_plane *plane; + + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { + struct intel_plane_state *plane_state; + + if ((plane_ids_mask & BIT(plane->id)) == 0) + continue; + + plane_state = intel_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_state)) + return PTR_ERR(plane_state); + } + + return 0; +} + +int intel_atomic_add_affected_planes(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + const struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); + const struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + + return intel_crtc_add_planes_to_state(state, crtc, + old_crtc_state->enabled_planes | + new_crtc_state->enabled_planes); +} + +static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv) +{ + /* See {hsw,vlv,ivb}_plane_ratio() */ + return IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv) || + IS_CHERRYVIEW(dev_priv) || IS_VALLEYVIEW(dev_priv) || + IS_IVYBRIDGE(dev_priv); +} + +static u8 intel_joiner_affected_planes(struct intel_atomic_state *state, + u8 joined_pipes) +{ + const struct intel_plane_state *plane_state; + struct intel_plane *plane; + u8 affected_planes = 0; + int i; + + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { + struct intel_plane *linked = plane_state->planar_linked_plane; + + if ((joined_pipes & BIT(plane->pipe)) == 0) + continue; + + affected_planes |= BIT(plane->id); + if (linked) + affected_planes |= BIT(linked->id); + } + + return affected_planes; +} + +static int intel_joiner_add_affected_planes(struct intel_atomic_state *state, + u8 joined_pipes) +{ + u8 prev_affected_planes, affected_planes = 0; + + /* + * We want all the joined pipes to have the same + * set of planes in the atomic state, to make sure + * state copying always works correctly, and the + * UV<->Y plane linkage is always up to date. + * Keep pulling planes in until we've determined + * the full set of affected planes. A bit complicated + * on account of each pipe being capable of selecting + * their own Y planes independently of the other pipes, + * and the selection being done from the set of + * inactive planes. + */ + do { + struct intel_crtc *crtc; + + for_each_intel_crtc_in_pipe_mask(state->base.dev, crtc, joined_pipes) { + int ret; + + ret = intel_crtc_add_planes_to_state(state, crtc, affected_planes); + if (ret) + return ret; + } + + prev_affected_planes = affected_planes; + affected_planes = intel_joiner_affected_planes(state, joined_pipes); + } while (affected_planes != prev_affected_planes); + + return 0; +} + +static int intel_add_affected_planes(struct intel_atomic_state *state) +{ + const struct intel_crtc_state *crtc_state; + struct intel_crtc *crtc; + int i; + + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + int ret; + + ret = intel_joiner_add_affected_planes(state, intel_crtc_joined_pipe_mask(crtc_state)); + if (ret) + return ret; + } + + return 0; +} + +int intel_atomic_check_planes(struct intel_atomic_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *old_crtc_state, *new_crtc_state; + struct intel_plane_state __maybe_unused *plane_state; + struct intel_plane *plane; + struct intel_crtc *crtc; + int i, ret; + + ret = intel_add_affected_planes(state); + if (ret) + return ret; + + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { + ret = intel_plane_atomic_check(state, plane); + if (ret) { + drm_dbg_atomic(&dev_priv->drm, + "[PLANE:%d:%s] atomic driver check failed\n", + plane->base.base.id, plane->base.name); + return ret; + } + } + + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { + u8 old_active_planes, new_active_planes; + + ret = icl_check_nv12_planes(state, crtc); + if (ret) + return ret; + + /* + * On some platforms the number of active planes affects + * the planes' minimum cdclk calculation. Add such planes + * to the state before we compute the minimum cdclk. + */ + if (!active_planes_affects_min_cdclk(dev_priv)) + continue; + + old_active_planes = old_crtc_state->active_planes & ~BIT(PLANE_CURSOR); + new_active_planes = new_crtc_state->active_planes & ~BIT(PLANE_CURSOR); + + if (hweight8(old_active_planes) == hweight8(new_active_planes)) + continue; + + ret = intel_crtc_add_planes_to_state(state, crtc, new_active_planes); + if (ret) + return ret; + } + + return 0; +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index fb87b3353ab0d..9dc0b8468c2e7 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -81,5 +81,8 @@ void intel_plane_helper_add(struct intel_plane *plane); bool intel_plane_needs_physical(struct intel_plane *plane); void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, struct intel_plane_state *new_plane_state); +int intel_atomic_add_affected_planes(struct intel_atomic_state *state, + struct intel_crtc *crtc); +int intel_atomic_check_planes(struct intel_atomic_state *state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 251fcce426943..45594a054256a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4404,132 +4404,6 @@ static bool check_single_encoder_cloning(struct intel_atomic_state *state, return true; } -static void link_nv12_planes(struct intel_crtc_state *crtc_state, - struct intel_plane_state *uv_plane_state, - struct intel_plane_state *y_plane_state) -{ - struct intel_display *display = to_intel_display(uv_plane_state); - struct intel_plane *uv_plane = to_intel_plane(uv_plane_state->uapi.plane); - struct intel_plane *y_plane = to_intel_plane(y_plane_state->uapi.plane); - - drm_dbg_kms(display->drm, "UV plane [PLANE:%d:%s] using Y plane [PLANE:%d:%s]\n", - uv_plane->base.base.id, uv_plane->base.name, - y_plane->base.base.id, y_plane->base.name); - - uv_plane_state->planar_linked_plane = y_plane; - - y_plane_state->is_y_plane = true; - y_plane_state->planar_linked_plane = uv_plane; - - crtc_state->enabled_planes |= BIT(y_plane->id); - crtc_state->active_planes |= BIT(y_plane->id); - crtc_state->update_planes |= BIT(y_plane->id); - - crtc_state->data_rate[y_plane->id] = crtc_state->data_rate_y[uv_plane->id]; - crtc_state->rel_data_rate[y_plane->id] = crtc_state->rel_data_rate_y[uv_plane->id]; - - /* Copy parameters to Y plane */ - intel_plane_copy_hw_state(y_plane_state, uv_plane_state); - y_plane_state->uapi.src = uv_plane_state->uapi.src; - y_plane_state->uapi.dst = uv_plane_state->uapi.dst; - - y_plane_state->ctl = uv_plane_state->ctl; - y_plane_state->color_ctl = uv_plane_state->color_ctl; - y_plane_state->view = uv_plane_state->view; - y_plane_state->decrypt = uv_plane_state->decrypt; - - icl_link_nv12_planes(uv_plane_state, y_plane_state); -} - -static void unlink_nv12_plane(struct intel_crtc_state *crtc_state, - struct intel_plane_state *plane_state) -{ - struct intel_display *display = to_intel_display(plane_state); - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - - plane_state->planar_linked_plane = NULL; - - if (!plane_state->is_y_plane) - return; - - drm_WARN_ON(display->drm, plane_state->uapi.visible); - - plane_state->is_y_plane = false; - - crtc_state->enabled_planes &= ~BIT(plane->id); - crtc_state->active_planes &= ~BIT(plane->id); - crtc_state->update_planes |= BIT(plane->id); - crtc_state->data_rate[plane->id] = 0; - crtc_state->rel_data_rate[plane->id] = 0; -} - -static int icl_check_nv12_planes(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); - struct intel_crtc_state *crtc_state = - intel_atomic_get_new_crtc_state(state, crtc); - struct intel_plane_state *plane_state; - struct intel_plane *plane; - int i; - - if (DISPLAY_VER(dev_priv) < 11) - return 0; - - /* - * Destroy all old plane links and make the Y plane invisible - * in the crtc_state->active_planes mask. - */ - for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - if (plane->pipe != crtc->pipe) - continue; - - if (plane_state->planar_linked_plane) - unlink_nv12_plane(crtc_state, plane_state); - } - - if (!crtc_state->nv12_planes) - return 0; - - for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - struct intel_plane_state *y_plane_state = NULL; - struct intel_plane *y_plane; - - if (plane->pipe != crtc->pipe) - continue; - - if ((crtc_state->nv12_planes & BIT(plane->id)) == 0) - continue; - - for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, y_plane) { - if (!icl_is_nv12_y_plane(display, y_plane->id)) - continue; - - if (crtc_state->active_planes & BIT(y_plane->id)) - continue; - - y_plane_state = intel_atomic_get_plane_state(state, y_plane); - if (IS_ERR(y_plane_state)) - return PTR_ERR(y_plane_state); - - break; - } - - if (!y_plane_state) { - drm_dbg_kms(&dev_priv->drm, - "[CRTC:%d:%s] need %d free Y planes for planar YUV\n", - crtc->base.base.id, crtc->base.name, - hweight8(crtc_state->nv12_planes)); - return -EINVAL; - } - - link_nv12_planes(crtc_state, plane_state, y_plane_state); - } - - return 0; -} - static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_state) { const struct drm_display_mode *pipe_mode = @@ -6130,175 +6004,6 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta new_crtc_state->update_pipe = true; } -static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state, - struct intel_crtc *crtc, - u8 plane_ids_mask) -{ - struct drm_i915_private *dev_priv = to_i915(state->base.dev); - struct intel_plane *plane; - - for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { - struct intel_plane_state *plane_state; - - if ((plane_ids_mask & BIT(plane->id)) == 0) - continue; - - plane_state = intel_atomic_get_plane_state(state, plane); - if (IS_ERR(plane_state)) - return PTR_ERR(plane_state); - } - - return 0; -} - -int intel_atomic_add_affected_planes(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - const struct intel_crtc_state *old_crtc_state = - intel_atomic_get_old_crtc_state(state, crtc); - const struct intel_crtc_state *new_crtc_state = - intel_atomic_get_new_crtc_state(state, crtc); - - return intel_crtc_add_planes_to_state(state, crtc, - old_crtc_state->enabled_planes | - new_crtc_state->enabled_planes); -} - -static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv) -{ - /* See {hsw,vlv,ivb}_plane_ratio() */ - return IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv) || - IS_CHERRYVIEW(dev_priv) || IS_VALLEYVIEW(dev_priv) || - IS_IVYBRIDGE(dev_priv); -} - -static u8 intel_joiner_affected_planes(struct intel_atomic_state *state, - u8 joined_pipes) -{ - const struct intel_plane_state *plane_state; - struct intel_plane *plane; - u8 affected_planes = 0; - int i; - - for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - struct intel_plane *linked = plane_state->planar_linked_plane; - - if ((joined_pipes & BIT(plane->pipe)) == 0) - continue; - - affected_planes |= BIT(plane->id); - if (linked) - affected_planes |= BIT(linked->id); - } - - return affected_planes; -} - -static int intel_joiner_add_affected_planes(struct intel_atomic_state *state, - u8 joined_pipes) -{ - u8 prev_affected_planes, affected_planes = 0; - - /* - * We want all the joined pipes to have the same - * set of planes in the atomic state, to make sure - * state copying always works correctly, and the - * UV<->Y plane linkage is always up to date. - * Keep pulling planes in until we've determined - * the full set of affected planes. A bit complicated - * on account of each pipe being capable of selecting - * their own Y planes independently of the other pipes, - * and the selection being done from the set of - * inactive planes. - */ - do { - struct intel_crtc *crtc; - - for_each_intel_crtc_in_pipe_mask(state->base.dev, crtc, joined_pipes) { - int ret; - - ret = intel_crtc_add_planes_to_state(state, crtc, affected_planes); - if (ret) - return ret; - } - - prev_affected_planes = affected_planes; - affected_planes = intel_joiner_affected_planes(state, joined_pipes); - } while (affected_planes != prev_affected_planes); - - return 0; -} - -static int intel_add_affected_planes(struct intel_atomic_state *state) -{ - const struct intel_crtc_state *crtc_state; - struct intel_crtc *crtc; - int i; - - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { - int ret; - - ret = intel_joiner_add_affected_planes(state, intel_crtc_joined_pipe_mask(crtc_state)); - if (ret) - return ret; - } - - return 0; -} - -static int intel_atomic_check_planes(struct intel_atomic_state *state) -{ - struct drm_i915_private *dev_priv = to_i915(state->base.dev); - struct intel_crtc_state *old_crtc_state, *new_crtc_state; - struct intel_plane_state __maybe_unused *plane_state; - struct intel_plane *plane; - struct intel_crtc *crtc; - int i, ret; - - ret = intel_add_affected_planes(state); - if (ret) - return ret; - - for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - ret = intel_plane_atomic_check(state, plane); - if (ret) { - drm_dbg_atomic(&dev_priv->drm, - "[PLANE:%d:%s] atomic driver check failed\n", - plane->base.base.id, plane->base.name); - return ret; - } - } - - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { - u8 old_active_planes, new_active_planes; - - ret = icl_check_nv12_planes(state, crtc); - if (ret) - return ret; - - /* - * On some platforms the number of active planes affects - * the planes' minimum cdclk calculation. Add such planes - * to the state before we compute the minimum cdclk. - */ - if (!active_planes_affects_min_cdclk(dev_priv)) - continue; - - old_active_planes = old_crtc_state->active_planes & ~BIT(PLANE_CURSOR); - new_active_planes = new_crtc_state->active_planes & ~BIT(PLANE_CURSOR); - - if (hweight8(old_active_planes) == hweight8(new_active_planes)) - continue; - - ret = intel_crtc_add_planes_to_state(state, crtc, new_active_planes); - if (ret) - return ret; - } - - return 0; -} - static int intel_atomic_check_crtcs(struct intel_atomic_state *state) { struct intel_crtc_state __maybe_unused *crtc_state; diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index d4a7095887009..188185ecd4c0a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -413,8 +413,6 @@ enum phy_fia { i) int intel_atomic_check(struct drm_device *dev, struct drm_atomic_state *state); -int intel_atomic_add_affected_planes(struct intel_atomic_state *state, - struct intel_crtc *crtc); u8 intel_calc_active_pipes(struct intel_atomic_state *state, u8 active_pipes); void intel_link_compute_m_n(u16 bpp, int nlanes, From dd6e5fee94b53f33ba61117827b89dd812a9c9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:09 +0200 Subject: [PATCH 259/284] drm/i915: Move modeset_retry stuff into intel_connector.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of the modeset retry stuff looks to be entirely generic, and so there doesn't seem to any reason to keep it in intel_dp.c. Move the generic bits into intel_connector.c. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- .../gpu/drm/i915/display/intel_connector.c | 39 ++++++++++++++++ .../gpu/drm/i915/display/intel_connector.h | 2 + drivers/gpu/drm/i915/display/intel_dp.c | 44 ++----------------- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- 4 files changed, 45 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index c65887870ddc2..4f54c9249a845 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -28,6 +28,7 @@ #include #include +#include #include "i915_drv.h" #include "intel_backlight.h" @@ -37,6 +38,44 @@ #include "intel_hdcp.h" #include "intel_panel.h" +static void intel_connector_modeset_retry_work_fn(struct work_struct *work) +{ + struct intel_connector *connector = container_of(work, typeof(*connector), + modeset_retry_work); + struct intel_display *display = to_intel_display(connector); + + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", connector->base.base.id, + connector->base.name); + + /* Grab the locks before changing connector property*/ + mutex_lock(&display->drm->mode_config.mutex); + /* Set connector link status to BAD and send a Uevent to notify + * userspace to do a modeset. + */ + drm_connector_set_link_status_property(&connector->base, + DRM_MODE_LINK_STATUS_BAD); + mutex_unlock(&display->drm->mode_config.mutex); + /* Send Hotplug uevent so userspace can reprobe */ + drm_kms_helper_connector_hotplug_event(&connector->base); + + drm_connector_put(&connector->base); +} + +void intel_connector_queue_modeset_retry_work(struct intel_connector *connector) +{ + struct drm_i915_private *i915 = to_i915(connector->base.dev); + + drm_connector_get(&connector->base); + if (!queue_work(i915->unordered_wq, &connector->modeset_retry_work)) + drm_connector_put(&connector->base); +} + +void intel_connector_init_modeset_retry_work(struct intel_connector *connector) +{ + INIT_WORK(&connector->modeset_retry_work, + intel_connector_modeset_retry_work_fn); +} + int intel_connector_init(struct intel_connector *connector) { struct intel_digital_connector_state *conn_state; diff --git a/drivers/gpu/drm/i915/display/intel_connector.h b/drivers/gpu/drm/i915/display/intel_connector.h index bafde3f11ff43..929646a639b2b 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.h +++ b/drivers/gpu/drm/i915/display/intel_connector.h @@ -33,5 +33,7 @@ void intel_attach_aspect_ratio_property(struct drm_connector *connector); void intel_attach_hdmi_colorspace_property(struct drm_connector *connector); void intel_attach_dp_colorspace_property(struct drm_connector *connector); void intel_attach_scaling_mode_property(struct drm_connector *connector); +void intel_connector_init_modeset_retry_work(struct intel_connector *connector); +void intel_connector_queue_modeset_retry_work(struct intel_connector *connector); #endif /* __INTEL_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index bee8e107ac2e9..55a2c8cbaa836 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3056,15 +3056,6 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder, intel_dp_is_uhbr(pipe_config); } -static void intel_dp_queue_modeset_retry_work(struct intel_connector *connector) -{ - struct drm_i915_private *i915 = to_i915(connector->base.dev); - - drm_connector_get(&connector->base); - if (!queue_work(i915->unordered_wq, &connector->modeset_retry_work)) - drm_connector_put(&connector->base); -} - void intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state, struct intel_encoder *encoder, @@ -3081,7 +3072,7 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state, intel_dp->needs_modeset_retry = true; if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { - intel_dp_queue_modeset_retry_work(intel_dp->attached_connector); + intel_connector_queue_modeset_retry_work(intel_dp->attached_connector); return; } @@ -3091,7 +3082,7 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state, continue; if (connector->mst_port == intel_dp) - intel_dp_queue_modeset_retry_work(connector); + intel_connector_queue_modeset_retry_work(connector); } } @@ -6485,35 +6476,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, return false; } -static void intel_dp_modeset_retry_work_fn(struct work_struct *work) -{ - struct intel_connector *connector = container_of(work, typeof(*connector), - modeset_retry_work); - struct intel_display *display = to_intel_display(connector); - - drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", connector->base.base.id, - connector->base.name); - - /* Grab the locks before changing connector property*/ - mutex_lock(&display->drm->mode_config.mutex); - /* Set connector link status to BAD and send a Uevent to notify - * userspace to do a modeset. - */ - drm_connector_set_link_status_property(&connector->base, - DRM_MODE_LINK_STATUS_BAD); - mutex_unlock(&display->drm->mode_config.mutex); - /* Send Hotplug uevent so userspace can reprobe */ - drm_kms_helper_connector_hotplug_event(&connector->base); - - drm_connector_put(&connector->base); -} - -void intel_dp_init_modeset_retry_work(struct intel_connector *connector) -{ - INIT_WORK(&connector->modeset_retry_work, - intel_dp_modeset_retry_work_fn); -} - bool intel_dp_init_connector(struct intel_digital_port *dig_port, struct intel_connector *connector) @@ -6526,7 +6488,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, int type; /* Initialize the work for modeset in case of link train failure */ - intel_dp_init_modeset_retry_work(connector); + intel_connector_init_modeset_retry_work(connector); if (drm_WARN(dev, dig_port->max_lanes < 1, "Not enough lanes (%d) for DP on [ENCODER:%d:%s]\n", diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 7749a6ab47982..c0c9a2a3aec07 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1747,7 +1747,7 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, connector->port = port; drm_dp_mst_get_port_malloc(port); - intel_dp_init_modeset_retry_work(connector); + intel_connector_init_modeset_retry_work(connector); ret = drm_connector_dynamic_init(display->drm, &connector->base, &mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort, NULL); From 78ecd904ee85f09360a8c4f1d15fb0a62ee4191e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:10 +0200 Subject: [PATCH 260/284] drm/i915: Always initialize connector->modeset_retry_work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we have all the necessary bits in intel_connector.c might as well always initialize the modeset_retry_work for every connector. Avoids yet another init function you have to remember to call. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_connector.c | 9 +++------ drivers/gpu/drm/i915/display/intel_connector.h | 1 - drivers/gpu/drm/i915/display/intel_display.c | 3 +-- drivers/gpu/drm/i915/display/intel_dp.c | 3 --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 -- 5 files changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index 4f54c9249a845..b1240be2ec6db 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -70,12 +70,6 @@ void intel_connector_queue_modeset_retry_work(struct intel_connector *connector) drm_connector_put(&connector->base); } -void intel_connector_init_modeset_retry_work(struct intel_connector *connector) -{ - INIT_WORK(&connector->modeset_retry_work, - intel_connector_modeset_retry_work_fn); -} - int intel_connector_init(struct intel_connector *connector) { struct intel_digital_connector_state *conn_state; @@ -95,6 +89,9 @@ int intel_connector_init(struct intel_connector *connector) intel_panel_init_alloc(connector); + INIT_WORK(&connector->modeset_retry_work, + intel_connector_modeset_retry_work_fn); + return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_connector.h b/drivers/gpu/drm/i915/display/intel_connector.h index 929646a639b2b..6d4a6b26d8f07 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.h +++ b/drivers/gpu/drm/i915/display/intel_connector.h @@ -33,7 +33,6 @@ void intel_attach_aspect_ratio_property(struct drm_connector *connector); void intel_attach_hdmi_colorspace_property(struct drm_connector *connector); void intel_attach_dp_colorspace_property(struct drm_connector *connector); void intel_attach_scaling_mode_property(struct drm_connector *connector); -void intel_connector_init_modeset_retry_work(struct intel_connector *connector); void intel_connector_queue_modeset_retry_work(struct intel_connector *connector); #endif /* __INTEL_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 45594a054256a..31feefb1bc294 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8544,8 +8544,7 @@ void intel_hpd_poll_fini(struct drm_i915_private *i915) /* Kill all the work that may have been queued by hpd. */ drm_connector_list_iter_begin(&i915->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { - if (connector->modeset_retry_work.func && - cancel_work_sync(&connector->modeset_retry_work)) + if (cancel_work_sync(&connector->modeset_retry_work)) drm_connector_put(&connector->base); if (connector->hdcp.shim) { cancel_delayed_work_sync(&connector->hdcp.check_work); diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 55a2c8cbaa836..0e501ec7e73a7 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6487,9 +6487,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, enum port port = encoder->port; int type; - /* Initialize the work for modeset in case of link train failure */ - intel_connector_init_modeset_retry_work(connector); - if (drm_WARN(dev, dig_port->max_lanes < 1, "Not enough lanes (%d) for DP on [ENCODER:%d:%s]\n", dig_port->max_lanes, encoder->base.base.id, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index c0c9a2a3aec07..faa261c8930c3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1747,8 +1747,6 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, connector->port = port; drm_dp_mst_get_port_malloc(port); - intel_connector_init_modeset_retry_work(connector); - ret = drm_connector_dynamic_init(display->drm, &connector->base, &mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort, NULL); if (ret) From 1562a536ff4289c10d44b6d79b2be3e070dc3973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 15 Feb 2025 20:52:44 +0200 Subject: [PATCH 261/284] drm/i915: Extract intel_connector_cancel_modeset_retry_work() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hide the implementation details of the modeset retry work better. v2: Include prototype and sort includes correctly (Jani) Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_connector.c | 6 ++++++ drivers/gpu/drm/i915/display/intel_connector.h | 1 + drivers/gpu/drm/i915/display/intel_display.c | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index b1240be2ec6db..358965fc7f553 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -70,6 +70,12 @@ void intel_connector_queue_modeset_retry_work(struct intel_connector *connector) drm_connector_put(&connector->base); } +void intel_connector_cancel_modeset_retry_work(struct intel_connector *connector) +{ + if (cancel_work_sync(&connector->modeset_retry_work)) + drm_connector_put(&connector->base); +} + int intel_connector_init(struct intel_connector *connector) { struct intel_digital_connector_state *conn_state; diff --git a/drivers/gpu/drm/i915/display/intel_connector.h b/drivers/gpu/drm/i915/display/intel_connector.h index 6d4a6b26d8f07..aafb25a814fa0 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.h +++ b/drivers/gpu/drm/i915/display/intel_connector.h @@ -34,5 +34,6 @@ void intel_attach_hdmi_colorspace_property(struct drm_connector *connector); void intel_attach_dp_colorspace_property(struct drm_connector *connector); void intel_attach_scaling_mode_property(struct drm_connector *connector); void intel_connector_queue_modeset_retry_work(struct intel_connector *connector); +void intel_connector_cancel_modeset_retry_work(struct intel_connector *connector); #endif /* __INTEL_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 31feefb1bc294..cc24edf4f01c3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -63,6 +63,7 @@ #include "intel_cdclk.h" #include "intel_clock_gating.h" #include "intel_color.h" +#include "intel_connector.h" #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" @@ -8544,8 +8545,7 @@ void intel_hpd_poll_fini(struct drm_i915_private *i915) /* Kill all the work that may have been queued by hpd. */ drm_connector_list_iter_begin(&i915->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { - if (cancel_work_sync(&connector->modeset_retry_work)) - drm_connector_put(&connector->base); + intel_connector_cancel_modeset_retry_work(connector); if (connector->hdcp.shim) { cancel_delayed_work_sync(&connector->hdcp.check_work); cancel_work_sync(&connector->hdcp.prop_work); From d9794afd23607aaf9275116f6b8580ddd3b7542a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:12 +0200 Subject: [PATCH 262/284] drm/i915: Extract intel_hdcp_cancel_works() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hide the annoying HDCP implementation details better by providing a intel_hdcp_cancel_works(). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 6 ++---- drivers/gpu/drm/i915/display/intel_hdcp.c | 9 +++++++++ drivers/gpu/drm/i915/display/intel_hdcp.h | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index cc24edf4f01c3..de03d507397bc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -93,6 +93,7 @@ #include "intel_fdi.h" #include "intel_fifo_underrun.h" #include "intel_frontbuffer.h" +#include "intel_hdcp.h" #include "intel_hdmi.h" #include "intel_hotplug.h" #include "intel_link_bw.h" @@ -8546,10 +8547,7 @@ void intel_hpd_poll_fini(struct drm_i915_private *i915) drm_connector_list_iter_begin(&i915->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { intel_connector_cancel_modeset_retry_work(connector); - if (connector->hdcp.shim) { - cancel_delayed_work_sync(&connector->hdcp.check_work); - cancel_work_sync(&connector->hdcp.prop_work); - } + intel_hdcp_cancel_works(connector); } drm_connector_list_iter_end(&conn_iter); } diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 1aa4c0fd216f8..5918519541141 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2615,6 +2615,15 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, _intel_hdcp_enable(state, encoder, crtc_state, conn_state); } +void intel_hdcp_cancel_works(struct intel_connector *connector) +{ + if (!connector->hdcp.shim) + return; + + cancel_delayed_work_sync(&connector->hdcp.check_work); + cancel_work_sync(&connector->hdcp.prop_work); +} + void intel_hdcp_component_fini(struct intel_display *display) { mutex_lock(&display->hdcp.hdcp_mutex); diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h index 3a79055510518..efe86808e17e5 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h @@ -33,6 +33,7 @@ void intel_hdcp_enable(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state); int intel_hdcp_disable(struct intel_connector *connector); +void intel_hdcp_cancel_works(struct intel_connector *connector); void intel_hdcp_update_pipe(struct intel_atomic_state *state, struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, From 13a8aca9b101a26a9da7f41c3e4ce7d6536981ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:13 +0200 Subject: [PATCH 263/284] drm/i915: Move intel_hpd_poll_fini() into intel_hotplug.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The name of intel_hpd_poll_fini() suggests that it should live in intel_hotplug.c. Make it so. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-6-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 16 ---------------- drivers/gpu/drm/i915/display/intel_display.h | 2 -- drivers/gpu/drm/i915/display/intel_hotplug.c | 16 ++++++++++++++++ drivers/gpu/drm/i915/display/intel_hotplug.h | 1 + 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index de03d507397bc..2784cdcb98417 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -63,7 +63,6 @@ #include "intel_cdclk.h" #include "intel_clock_gating.h" #include "intel_color.h" -#include "intel_connector.h" #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" @@ -93,7 +92,6 @@ #include "intel_fdi.h" #include "intel_fifo_underrun.h" #include "intel_frontbuffer.h" -#include "intel_hdcp.h" #include "intel_hdmi.h" #include "intel_hotplug.h" #include "intel_link_bw.h" @@ -8538,20 +8536,6 @@ void i830_disable_pipe(struct intel_display *display, enum pipe pipe) intel_de_posting_read(display, DPLL(display, pipe)); } -void intel_hpd_poll_fini(struct drm_i915_private *i915) -{ - struct intel_connector *connector; - struct drm_connector_list_iter conn_iter; - - /* Kill all the work that may have been queued by hpd. */ - drm_connector_list_iter_begin(&i915->drm, &conn_iter); - for_each_intel_connector_iter(connector, &conn_iter) { - intel_connector_cancel_modeset_retry_work(connector); - intel_hdcp_cancel_works(connector); - } - drm_connector_list_iter_end(&conn_iter); -} - bool intel_scanout_needs_vtd_wa(struct intel_display *display) { struct drm_i915_private *i915 = to_i915(display->drm); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 188185ecd4c0a..b18363c1d4721 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -569,8 +569,6 @@ enum drm_mode_status intel_mode_valid(struct drm_device *dev, int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, bool nonblock); -void intel_hpd_poll_fini(struct drm_i915_private *i915); - /* modesetting asserts */ void assert_transcoder(struct intel_display *display, enum transcoder cpu_transcoder, bool state); diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index 9c935afc60aaf..00d7b1ccf1900 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -28,8 +28,10 @@ #include "i915_drv.h" #include "i915_irq.h" +#include "intel_connector.h" #include "intel_display_power.h" #include "intel_display_types.h" +#include "intel_hdcp.h" #include "intel_hotplug.h" #include "intel_hotplug_irq.h" @@ -864,6 +866,20 @@ void intel_hpd_poll_disable(struct drm_i915_private *dev_priv) spin_unlock_irq(&dev_priv->irq_lock); } +void intel_hpd_poll_fini(struct drm_i915_private *i915) +{ + struct intel_connector *connector; + struct drm_connector_list_iter conn_iter; + + /* Kill all the work that may have been queued by hpd. */ + drm_connector_list_iter_begin(&i915->drm, &conn_iter); + for_each_intel_connector_iter(connector, &conn_iter) { + intel_connector_cancel_modeset_retry_work(connector); + intel_hdcp_cancel_works(connector); + } + drm_connector_list_iter_end(&conn_iter); +} + void intel_hpd_init_early(struct drm_i915_private *i915) { INIT_DELAYED_WORK(&i915->display.hotplug.hotplug_work, diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.h b/drivers/gpu/drm/i915/display/intel_hotplug.h index d2ca9d2f1d393..d6986902b0545 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.h +++ b/drivers/gpu/drm/i915/display/intel_hotplug.h @@ -16,6 +16,7 @@ enum port; void intel_hpd_poll_enable(struct drm_i915_private *dev_priv); void intel_hpd_poll_disable(struct drm_i915_private *dev_priv); +void intel_hpd_poll_fini(struct drm_i915_private *i915); enum intel_hotplug_state intel_encoder_hotplug(struct intel_encoder *encoder, struct intel_connector *connector); void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, From 7105bf946fc308d2cefd54e0fcaa748840d9a2d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:14 +0200 Subject: [PATCH 264/284] drm/i915: Move intel_plane_destroy() into intel_atomic_plane.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_atomic_plane.c (should rename it really) has become our standard place for generic plane code. Move intel_plane_destroy() there so it doesn't clutter intel_display.c. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-7-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_atomic_plane.c | 13 +++++++++++++ drivers/gpu/drm/i915/display/intel_atomic_plane.h | 1 + drivers/gpu/drm/i915/display/intel_display.c | 13 ------------- drivers/gpu/drm/i915/display/intel_display.h | 1 - 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index f58169763835b..aecff35d0ce22 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -93,6 +93,19 @@ void intel_plane_free(struct intel_plane *plane) kfree(plane); } +/** + * intel_plane_destroy - destroy a plane + * @plane: plane to destroy + * + * Common destruction function for all types of planes (primary, cursor, + * sprite). + */ +void intel_plane_destroy(struct drm_plane *plane) +{ + drm_plane_cleanup(plane); + kfree(to_intel_plane(plane)); +} + /** * intel_plane_duplicate_state - duplicate plane state * @plane: drm plane diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 9dc0b8468c2e7..d21eb7699dbdc 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -52,6 +52,7 @@ void intel_plane_disable_arm(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state); struct intel_plane *intel_plane_alloc(void); void intel_plane_free(struct intel_plane *plane); +void intel_plane_destroy(struct drm_plane *plane); struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane); void intel_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2784cdcb98417..80d375ed7d189 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7874,19 +7874,6 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, return 0; } -/** - * intel_plane_destroy - destroy a plane - * @plane: plane to destroy - * - * Common destruction function for all types of planes (primary, cursor, - * sprite). - */ -void intel_plane_destroy(struct drm_plane *plane) -{ - drm_plane_cleanup(plane); - kfree(to_intel_plane(plane)); -} - static u32 intel_encoder_possible_clones(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index b18363c1d4721..1b3c8f834a8e8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -448,7 +448,6 @@ bool intel_pipe_config_compare(const struct intel_crtc_state *current_config, const struct intel_crtc_state *pipe_config, bool fastset); -void intel_plane_destroy(struct drm_plane *plane); void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state); void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state); void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state); From 2be189c9e82d0e522a22f7c31fa5a217e5ec0a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:15 +0200 Subject: [PATCH 265/284] drm/i915: Relocate vlv_wait_port_ready() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While vlv_wait_port_ready() doens't directly talk to the VLV/CHV DPIO PHY, the signals it's looking for do come from the PHY. So it seems appropriate to relocate it into intel_dpio_phy.c. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-8-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 34 ------------------- drivers/gpu/drm/i915/display/intel_display.h | 3 -- drivers/gpu/drm/i915/display/intel_dpio_phy.c | 34 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dpio_phy.h | 8 +++++ 4 files changed, 42 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 80d375ed7d189..d83024c17c3cf 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -473,40 +473,6 @@ static void assert_planes_disabled(struct intel_crtc *crtc) assert_plane_disabled(plane); } -void vlv_wait_port_ready(struct intel_display *display, - struct intel_digital_port *dig_port, - unsigned int expected_mask) -{ - u32 port_mask; - i915_reg_t dpll_reg; - - switch (dig_port->base.port) { - default: - MISSING_CASE(dig_port->base.port); - fallthrough; - case PORT_B: - port_mask = DPLL_PORTB_READY_MASK; - dpll_reg = DPLL(display, 0); - break; - case PORT_C: - port_mask = DPLL_PORTC_READY_MASK; - dpll_reg = DPLL(display, 0); - expected_mask <<= 4; - break; - case PORT_D: - port_mask = DPLL_PORTD_READY_MASK; - dpll_reg = DPIO_PHY_STATUS; - break; - } - - if (intel_de_wait(display, dpll_reg, port_mask, expected_mask, 1000)) - drm_WARN(display->drm, 1, - "timed out waiting for [ENCODER:%d:%s] port ready: got 0x%x, expected 0x%x\n", - dig_port->base.base.base.id, dig_port->base.base.name, - intel_de_read(display, dpll_reg) & port_mask, - expected_mask); -} - void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) { struct intel_display *display = to_intel_display(new_crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 1b3c8f834a8e8..b6d1aa05309f3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -486,9 +486,6 @@ bool intel_encoder_is_tc(struct intel_encoder *encoder); enum tc_port intel_encoder_to_tc(struct intel_encoder *encoder); int ilk_get_lanes_required(int target_clock, int link_bw, int bpp); -void vlv_wait_port_ready(struct intel_display *display, - struct intel_digital_port *dig_port, - unsigned int expected_mask); bool intel_fuzzy_clock_check(int clock1, int clock2); diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c index 5f88702818d31..968b795206b3b 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c @@ -1156,3 +1156,37 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder, vlv_dpio_write(dev_priv, phy, VLV_PCS_DW1_GRP(ch), 0x00e00060); vlv_dpio_put(dev_priv); } + +void vlv_wait_port_ready(struct intel_display *display, + struct intel_digital_port *dig_port, + unsigned int expected_mask) +{ + u32 port_mask; + i915_reg_t dpll_reg; + + switch (dig_port->base.port) { + default: + MISSING_CASE(dig_port->base.port); + fallthrough; + case PORT_B: + port_mask = DPLL_PORTB_READY_MASK; + dpll_reg = DPLL(display, 0); + break; + case PORT_C: + port_mask = DPLL_PORTC_READY_MASK; + dpll_reg = DPLL(display, 0); + expected_mask <<= 4; + break; + case PORT_D: + port_mask = DPLL_PORTD_READY_MASK; + dpll_reg = DPIO_PHY_STATUS; + break; + } + + if (intel_de_wait(display, dpll_reg, port_mask, expected_mask, 1000)) + drm_WARN(display->drm, 1, + "timed out waiting for [ENCODER:%d:%s] port ready: got 0x%x, expected 0x%x\n", + dig_port->base.base.base.id, dig_port->base.base.name, + intel_de_read(display, dpll_reg) & port_mask, + expected_mask); +} diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.h b/drivers/gpu/drm/i915/display/intel_dpio_phy.h index a829391655464..15596407fe873 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.h +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.h @@ -72,6 +72,9 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void vlv_phy_reset_lanes(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state); +void vlv_wait_port_ready(struct intel_display *display, + struct intel_digital_port *dig_port, + unsigned int expected_mask); #else static inline void bxt_port_to_phy_channel(struct intel_display *display, enum port port, enum dpio_phy *phy, enum dpio_channel *ch) @@ -170,6 +173,11 @@ static inline void vlv_phy_reset_lanes(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state) { } +static inline void vlv_wait_port_ready(struct intel_display *display, + struct intel_digital_port *dig_port, + unsigned int expected_mask) +{ +} #endif #endif /* __INTEL_DPIO_PHY_H__ */ From 9fa560f70e249c937c7eddec019fd1c304bff135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:16 +0200 Subject: [PATCH 266/284] drm/i915: Simplify vlv_wait_port_ready() arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently vlv_wait_port_ready() takes the display+dig_port, but all it really needs is the encoder. The display can be dug out from therein. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-9-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- drivers/gpu/drm/i915/display/g4x_hdmi.c | 6 ++---- drivers/gpu/drm/i915/display/intel_dpio_phy.c | 10 +++++----- drivers/gpu/drm/i915/display/intel_dpio_phy.h | 6 ++---- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 0cb98cb043c6d..372c3683c193a 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -701,7 +701,7 @@ static void intel_enable_dp(struct intel_atomic_state *state, if (display->platform.cherryview) lane_mask = intel_dp_unused_lane_mask(pipe_config->lane_count); - vlv_wait_port_ready(display, dp_to_dig_port(intel_dp), lane_mask); + vlv_wait_port_ready(encoder, lane_mask); } intel_dp_set_power(intel_dp, DP_SET_POWER_D0); diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 5c5eb3d621c8e..d9d1304dcc368 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -479,7 +479,6 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { - struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); vlv_phy_pre_encoder_enable(encoder, pipe_config); @@ -495,7 +494,7 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state, g4x_hdmi_enable_port(encoder, pipe_config); - vlv_wait_port_ready(display, dig_port, 0x0); + vlv_wait_port_ready(encoder, 0x0); } static void vlv_hdmi_pre_pll_enable(struct intel_atomic_state *state, @@ -556,7 +555,6 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { - struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); chv_phy_pre_encoder_enable(encoder, pipe_config); @@ -571,7 +569,7 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state, g4x_hdmi_enable_port(encoder, pipe_config); - vlv_wait_port_ready(display, dig_port, 0x0); + vlv_wait_port_ready(encoder, 0x0); /* Second common lane will stay alive on its own now */ chv_phy_release_cl2_override(encoder); diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c index 968b795206b3b..429f895437890 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c @@ -1157,16 +1157,16 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder, vlv_dpio_put(dev_priv); } -void vlv_wait_port_ready(struct intel_display *display, - struct intel_digital_port *dig_port, +void vlv_wait_port_ready(struct intel_encoder *encoder, unsigned int expected_mask) { + struct intel_display *display = to_intel_display(encoder); u32 port_mask; i915_reg_t dpll_reg; - switch (dig_port->base.port) { + switch (encoder->port) { default: - MISSING_CASE(dig_port->base.port); + MISSING_CASE(encoder->port); fallthrough; case PORT_B: port_mask = DPLL_PORTB_READY_MASK; @@ -1186,7 +1186,7 @@ void vlv_wait_port_ready(struct intel_display *display, if (intel_de_wait(display, dpll_reg, port_mask, expected_mask, 1000)) drm_WARN(display->drm, 1, "timed out waiting for [ENCODER:%d:%s] port ready: got 0x%x, expected 0x%x\n", - dig_port->base.base.base.id, dig_port->base.base.name, + encoder->base.base.id, encoder->base.name, intel_de_read(display, dpll_reg) & port_mask, expected_mask); } diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.h b/drivers/gpu/drm/i915/display/intel_dpio_phy.h index 15596407fe873..35baede3d6ad0 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.h +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.h @@ -72,8 +72,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void vlv_phy_reset_lanes(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state); -void vlv_wait_port_ready(struct intel_display *display, - struct intel_digital_port *dig_port, +void vlv_wait_port_ready(struct intel_encoder *encoder, unsigned int expected_mask); #else static inline void bxt_port_to_phy_channel(struct intel_display *display, enum port port, @@ -173,8 +172,7 @@ static inline void vlv_phy_reset_lanes(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state) { } -static inline void vlv_wait_port_ready(struct intel_display *display, - struct intel_digital_port *dig_port, +static inline void vlv_wait_port_ready(struct intel_encoder *encoder, unsigned int expected_mask) { } From f04fb4090f4a4771a440a36f8c18e038c45ec2fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:17 +0200 Subject: [PATCH 267/284] drm/i915: Relocate intel_plane_uses_fence() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Relocate intel_plane_uses_fence() into intel_fb.c. Not sure that's the best place, but since this is mostly about the fb and vma I can't think of anything truly better right now. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-10-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 10 ---------- drivers/gpu/drm/i915/display/intel_display.h | 2 -- drivers/gpu/drm/i915/display/intel_fb.c | 10 ++++++++++ drivers/gpu/drm/i915/display/intel_fb.h | 1 + 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d83024c17c3cf..dc1ec1b94c400 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -636,16 +636,6 @@ unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info return size; } -bool intel_plane_uses_fence(const struct intel_plane_state *plane_state) -{ - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); - - return DISPLAY_VER(dev_priv) < 4 || - (plane->fbc && !plane_state->no_fbc_reason && - plane_state->view.gtt.type == I915_GTT_VIEW_NORMAL); -} - /* * Convert the x/y offsets into a linear offset. * Only valid with 0/180 degree rotation, which is fine since linear diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index b6d1aa05309f3..7b958e66a69c3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -524,8 +524,6 @@ void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state); int bdw_get_pipe_misc_bpp(struct intel_crtc *crtc); unsigned int intel_plane_fence_y_offset(const struct intel_plane_state *plane_state); -bool intel_plane_uses_fence(const struct intel_plane_state *plane_state); - struct intel_encoder * intel_get_crtc_new_encoder(const struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 5af93235057c6..5875af2b61e66 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1283,6 +1283,16 @@ bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb) intel_fb_uses_dpt(&fb->base); } +bool intel_plane_uses_fence(const struct intel_plane_state *plane_state) +{ + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + + return DISPLAY_VER(dev_priv) < 4 || + (plane->fbc && !plane_state->no_fbc_reason && + plane_state->view.gtt.type == I915_GTT_VIEW_NORMAL); +} + static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation) { if (drm_rotation_90_or_270(rotation)) diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index e6ef1783e351d..63728520eb062 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -77,6 +77,7 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y, int color_plane); bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb); +bool intel_plane_uses_fence(const struct intel_plane_state *plane_state); bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb); int intel_fill_fb_info(struct intel_display *display, struct intel_framebuffer *fb); From 2d017fea5bf5c7ebe0518e3e2b557b4dff474a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:18 +0200 Subject: [PATCH 268/284] drm/i915: Relocate intel_{rotation,remapped}_info_size() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move intel_{rotation,remapped}_info_size() into intel_fb.c as that seems a slightly better place than intel_display.c. I suppose these should live somewhere outside the display code as they are also used by the gem code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-11-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 36 -------------------- drivers/gpu/drm/i915/display/intel_display.h | 4 --- drivers/gpu/drm/i915/display/intel_fb.c | 36 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_fb.h | 5 +++ drivers/gpu/drm/i915/i915_vma.c | 2 +- 5 files changed, 42 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index dc1ec1b94c400..759f05a08e626 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -600,42 +600,6 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state) intel_wait_for_pipe_off(old_crtc_state); } -unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info) -{ - unsigned int size = 0; - int i; - - for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) - size += rot_info->plane[i].dst_stride * rot_info->plane[i].width; - - return size; -} - -unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info) -{ - unsigned int size = 0; - int i; - - for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) { - unsigned int plane_size; - - if (rem_info->plane[i].linear) - plane_size = rem_info->plane[i].size; - else - plane_size = rem_info->plane[i].dst_stride * rem_info->plane[i].height; - - if (plane_size == 0) - continue; - - if (rem_info->plane_alignment) - size = ALIGN(size, rem_info->plane_alignment); - - size += plane_size; - } - - return size; -} - /* * Convert the x/y offsets into a linear offset. * Only valid with 0/180 degree rotation, which is fine since linear diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 7b958e66a69c3..bd3b38632ef9d 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -59,8 +59,6 @@ struct intel_link_m_n; struct intel_plane; struct intel_plane_state; struct intel_power_domain_mask; -struct intel_remapped_info; -struct intel_rotation_info; struct pci_dev; struct work_struct; @@ -465,8 +463,6 @@ unsigned int intel_fb_xy_to_linear(int x, int y, int plane); void intel_add_fb_offsets(int *x, int *y, const struct intel_plane_state *state, int plane); -unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info); -unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info); bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv); void intel_encoder_destroy(struct drm_encoder *encoder); struct drm_display_mode * diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 5875af2b61e66..c1923b4c13d66 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1891,6 +1891,42 @@ static void intel_plane_remap_gtt(struct intel_plane_state *plane_state) } } +unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info) +{ + unsigned int size = 0; + int i; + + for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) + size += rot_info->plane[i].dst_stride * rot_info->plane[i].width; + + return size; +} + +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info) +{ + unsigned int size = 0; + int i; + + for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) { + unsigned int plane_size; + + if (rem_info->plane[i].linear) + plane_size = rem_info->plane[i].size; + else + plane_size = rem_info->plane[i].dst_stride * rem_info->plane[i].height; + + if (plane_size == 0) + continue; + + if (rem_info->plane_alignment) + size = ALIGN(size, rem_info->plane_alignment); + + size += plane_size; + } + + return size; +} + void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotation, struct intel_fb_view *view) { diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 63728520eb062..d04d9274bb712 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -19,6 +19,8 @@ struct intel_fb_view; struct intel_framebuffer; struct intel_plane; struct intel_plane_state; +struct intel_remapped_info; +struct intel_rotation_info; #define INTEL_PLANE_CAP_NONE 0 #define INTEL_PLANE_CAP_CCS_RC BIT(0) @@ -80,6 +82,9 @@ bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb); bool intel_plane_uses_fence(const struct intel_plane_state *plane_state); bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb); +unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info); +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info); + int intel_fill_fb_info(struct intel_display *display, struct intel_framebuffer *fb); void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotation, struct intel_fb_view *view); diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 61b49007ecd48..632e316f8b052 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -26,7 +26,7 @@ #include #include -#include "display/intel_display.h" +#include "display/intel_fb.h" #include "display/intel_frontbuffer.h" #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_object_frontbuffer.h" From 9ba19223a5db2a3efd0228f106506cf33b95873c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:19 +0200 Subject: [PATCH 269/284] drm/i915: Relocate some other plane fb related stuff into intel_fb.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move intel_fb_xy_to_linear() and intel_add_fb_offsets() These are technially sitting somewhere between plane vs. fb code, but we do have a bunch of code like that in intel_fb.c anyway. Might need to think about splitting intel_fb.c into pure fb vs. plane->fb related stuff somehow, but dunno if that's even feasible. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-12-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 31 -------------------- drivers/gpu/drm/i915/display/intel_display.h | 5 ---- drivers/gpu/drm/i915/display/intel_fb.c | 31 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_fb.h | 6 ++++ 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 759f05a08e626..ab33792c98402 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -600,37 +600,6 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state) intel_wait_for_pipe_off(old_crtc_state); } -/* - * Convert the x/y offsets into a linear offset. - * Only valid with 0/180 degree rotation, which is fine since linear - * offset is only used with linear buffers on pre-hsw and tiled buffers - * with gen2/3, and 90/270 degree rotations isn't supported on any of them. - */ -u32 intel_fb_xy_to_linear(int x, int y, - const struct intel_plane_state *state, - int color_plane) -{ - const struct drm_framebuffer *fb = state->hw.fb; - unsigned int cpp = fb->format->cpp[color_plane]; - unsigned int pitch = state->view.color_plane[color_plane].mapping_stride; - - return y * pitch + x * cpp; -} - -/* - * Add the x/y offsets derived from fb->offsets[] to the user - * specified plane src x/y offsets. The resulting x/y offsets - * specify the start of scanout from the beginning of the gtt mapping. - */ -void intel_add_fb_offsets(int *x, int *y, - const struct intel_plane_state *state, - int color_plane) - -{ - *x += state->view.color_plane[color_plane].x; - *y += state->view.color_plane[color_plane].y; -} - u32 intel_plane_fb_max_stride(struct drm_device *drm, u32 pixel_format, u64 modifier) { diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index bd3b38632ef9d..e58daefc978e3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -458,11 +458,6 @@ int vlv_get_cck_clock(struct drm_i915_private *dev_priv, int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv, const char *name, u32 reg); void intel_init_display_hooks(struct drm_i915_private *dev_priv); -unsigned int intel_fb_xy_to_linear(int x, int y, - const struct intel_plane_state *state, - int plane); -void intel_add_fb_offsets(int *x, int *y, - const struct intel_plane_state *state, int plane); bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv); void intel_encoder_destroy(struct drm_encoder *encoder); struct drm_display_mode * diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index c1923b4c13d66..b62dbb879fc29 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1938,6 +1938,37 @@ void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotatio *view = fb->normal_view; } +/* + * Convert the x/y offsets into a linear offset. + * Only valid with 0/180 degree rotation, which is fine since linear + * offset is only used with linear buffers on pre-hsw and tiled buffers + * with gen2/3, and 90/270 degree rotations isn't supported on any of them. + */ +u32 intel_fb_xy_to_linear(int x, int y, + const struct intel_plane_state *state, + int color_plane) +{ + const struct drm_framebuffer *fb = state->hw.fb; + unsigned int cpp = fb->format->cpp[color_plane]; + unsigned int pitch = state->view.color_plane[color_plane].mapping_stride; + + return y * pitch + x * cpp; +} + +/* + * Add the x/y offsets derived from fb->offsets[] to the user + * specified plane src x/y offsets. The resulting x/y offsets + * specify the start of scanout from the beginning of the gtt mapping. + */ +void intel_add_fb_offsets(int *x, int *y, + const struct intel_plane_state *state, + int color_plane) + +{ + *x += state->view.color_plane[color_plane].x; + *y += state->view.color_plane[color_plane].y; +} + static u32 intel_fb_max_stride(struct intel_display *display, u32 pixel_format, u64 modifier) diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index d04d9274bb712..46286a40e10ef 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -93,6 +93,12 @@ unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb, unsigned int rotation); int intel_plane_compute_gtt(struct intel_plane_state *plane_state); +unsigned int intel_fb_xy_to_linear(int x, int y, + const struct intel_plane_state *state, + int plane); +void intel_add_fb_offsets(int *x, int *y, + const struct intel_plane_state *state, int plane); + int intel_framebuffer_init(struct intel_framebuffer *ifb, struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); From 1bcba228535f8c551d6ffe355c347415a88c1dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Feb 2025 17:02:20 +0200 Subject: [PATCH 270/284] drm/i915: s/state/plane_state/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the canonical 'plane_state' name for function arguments where appropriate. Also do the s/int plane/int color_plane/ in couple of the function prototypes while at it. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250213150220.13580-13-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_fb.c | 32 ++++++++++++------------- drivers/gpu/drm/i915/display/intel_fb.h | 11 +++++---- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index b62dbb879fc29..2b0e0f220442f 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1049,13 +1049,13 @@ static u32 intel_adjust_aligned_offset(int *x, int *y, * the x/y offsets. */ u32 intel_plane_adjust_aligned_offset(int *x, int *y, - const struct intel_plane_state *state, + const struct intel_plane_state *plane_state, int color_plane, u32 old_offset, u32 new_offset) { - return intel_adjust_aligned_offset(x, y, state->hw.fb, color_plane, - state->hw.rotation, - state->view.color_plane[color_plane].mapping_stride, + return intel_adjust_aligned_offset(x, y, plane_state->hw.fb, color_plane, + plane_state->hw.rotation, + plane_state->view.color_plane[color_plane].mapping_stride, old_offset, new_offset); } @@ -1129,14 +1129,14 @@ static u32 intel_compute_aligned_offset(struct intel_display *display, } u32 intel_plane_compute_aligned_offset(int *x, int *y, - const struct intel_plane_state *state, + const struct intel_plane_state *plane_state, int color_plane) { - struct intel_display *display = to_intel_display(state); - struct intel_plane *plane = to_intel_plane(state->uapi.plane); - const struct drm_framebuffer *fb = state->hw.fb; - unsigned int rotation = state->hw.rotation; - unsigned int pitch = state->view.color_plane[color_plane].mapping_stride; + struct intel_display *display = to_intel_display(plane_state); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + const struct drm_framebuffer *fb = plane_state->hw.fb; + unsigned int rotation = plane_state->hw.rotation; + unsigned int pitch = plane_state->view.color_plane[color_plane].mapping_stride; unsigned int alignment = plane->min_alignment(plane, fb, color_plane); return intel_compute_aligned_offset(display, x, y, fb, color_plane, @@ -1945,12 +1945,12 @@ void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotatio * with gen2/3, and 90/270 degree rotations isn't supported on any of them. */ u32 intel_fb_xy_to_linear(int x, int y, - const struct intel_plane_state *state, + const struct intel_plane_state *plane_state, int color_plane) { - const struct drm_framebuffer *fb = state->hw.fb; + const struct drm_framebuffer *fb = plane_state->hw.fb; unsigned int cpp = fb->format->cpp[color_plane]; - unsigned int pitch = state->view.color_plane[color_plane].mapping_stride; + unsigned int pitch = plane_state->view.color_plane[color_plane].mapping_stride; return y * pitch + x * cpp; } @@ -1961,12 +1961,12 @@ u32 intel_fb_xy_to_linear(int x, int y, * specify the start of scanout from the beginning of the gtt mapping. */ void intel_add_fb_offsets(int *x, int *y, - const struct intel_plane_state *state, + const struct intel_plane_state *plane_state, int color_plane) { - *x += state->view.color_plane[color_plane].x; - *y += state->view.color_plane[color_plane].y; + *x += plane_state->view.color_plane[color_plane].x; + *y += plane_state->view.color_plane[color_plane].y; } static diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 46286a40e10ef..bdd76b3729578 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -71,11 +71,11 @@ void intel_fb_plane_get_subsampling(int *hsub, int *vsub, int color_plane); u32 intel_plane_adjust_aligned_offset(int *x, int *y, - const struct intel_plane_state *state, + const struct intel_plane_state *plane_state, int color_plane, u32 old_offset, u32 new_offset); u32 intel_plane_compute_aligned_offset(int *x, int *y, - const struct intel_plane_state *state, + const struct intel_plane_state *plane_state, int color_plane); bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb); @@ -94,10 +94,11 @@ unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb, int intel_plane_compute_gtt(struct intel_plane_state *plane_state); unsigned int intel_fb_xy_to_linear(int x, int y, - const struct intel_plane_state *state, - int plane); + const struct intel_plane_state *plane_state, + int color_plane); void intel_add_fb_offsets(int *x, int *y, - const struct intel_plane_state *state, int plane); + const struct intel_plane_state *plane_state, + int color_plane); int intel_framebuffer_init(struct intel_framebuffer *ifb, struct drm_gem_object *obj, From 63f39ad858cdf1f5f25489f31fb66adda2d1d33e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 17 Feb 2025 09:00:40 +0200 Subject: [PATCH 271/284] drm/i915: Add missing else to the if ladder in missing else MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The if ladder in gen8_de_pipe_fault_mask() was missing one else, add it. Doesn't actually matter since each if branch just returns directly. But the code is less confusing when you always do things the same way. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250217070047.953-2-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 880eaed83cd5a..d3ba8e2cf5a13 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -908,7 +908,7 @@ static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv) GEN9_PIPE_PLANE3_FAULT | GEN9_PIPE_PLANE2_FAULT | GEN9_PIPE_PLANE1_FAULT; - if (DISPLAY_VER(display) >= 13 || HAS_D12_PLANE_MINIMIZATION(display)) + else if (DISPLAY_VER(display) >= 13 || HAS_D12_PLANE_MINIMIZATION(display)) return GEN12_PIPEDMC_FAULT | GEN9_PIPE_CURSOR_FAULT | GEN11_PIPE_PLANE5_FAULT | From 32ed4660f1bd8ccac79a10c14f8f01db4f4db668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 17 Feb 2025 09:00:41 +0200 Subject: [PATCH 272/284] drm/i915: Introduce a minimal plane error state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I want to capture a little bit more information about the state of the plane upon faults. To that end introduce a small plane error state struct and provide per-plane vfuncs to read it out. For now we just stick the CTL, SURF, and SURFLIVE (if available) registers contents in there. v2: Use struct intel_display instead of dev_priv Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250217070047.953-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/i9xx_plane.c | 41 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_cursor.c | 26 ++++++++++++ .../drm/i915/display/intel_display_types.h | 7 ++++ drivers/gpu/drm/i915/display/intel_sprite.c | 36 ++++++++++++++++ .../drm/i915/display/skl_universal_plane.c | 12 ++++++ 5 files changed, 122 insertions(+) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index aef8d8b7ea85f..013295f66d56e 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -557,6 +557,40 @@ static void i9xx_plane_disable_arm(struct intel_dsb *dsb, intel_de_write_fw(display, DSPADDR(display, i9xx_plane), 0); } +static void g4x_primary_capture_error(struct intel_crtc *crtc, + struct intel_plane *plane, + struct intel_plane_error *error) +{ + struct intel_display *display = to_intel_display(plane); + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; + + error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane)); + error->surf = intel_de_read(display, DSPSURF(display, i9xx_plane)); + error->surflive = intel_de_read(display, DSPSURFLIVE(display, i9xx_plane)); +} + +static void i965_plane_capture_error(struct intel_crtc *crtc, + struct intel_plane *plane, + struct intel_plane_error *error) +{ + struct intel_display *display = to_intel_display(plane); + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; + + error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane)); + error->surf = intel_de_read(display, DSPSURF(display, i9xx_plane)); +} + +static void i8xx_plane_capture_error(struct intel_crtc *crtc, + struct intel_plane *plane, + struct intel_plane_error *error) +{ + struct intel_display *display = to_intel_display(plane); + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; + + error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane)); + error->surf = intel_de_read(display, DSPADDR(display, i9xx_plane)); +} + static void g4x_primary_async_flip(struct intel_dsb *dsb, struct intel_plane *plane, @@ -976,6 +1010,13 @@ intel_primary_plane_create(struct intel_display *display, enum pipe pipe) plane->get_hw_state = i9xx_plane_get_hw_state; plane->check_plane = i9xx_plane_check; + if (DISPLAY_VER(display) >= 5 || display->platform.g4x) + plane->capture_error = g4x_primary_capture_error; + else if (DISPLAY_VER(display) >= 4) + plane->capture_error = i965_plane_capture_error; + else + plane->capture_error = i8xx_plane_capture_error; + if (HAS_ASYNC_FLIPS(display)) { if (display->platform.valleyview || display->platform.cherryview) { plane->async_flip = vlv_primary_async_flip; diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index f31efac89e95a..3276a5b4a9b00 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -765,6 +765,27 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, return ret; } +static void g4x_cursor_capture_error(struct intel_crtc *crtc, + struct intel_plane *plane, + struct intel_plane_error *error) +{ + struct intel_display *display = to_intel_display(plane); + + error->ctl = intel_de_read(display, CURCNTR(display, crtc->pipe)); + error->surf = intel_de_read(display, CURBASE(display, crtc->pipe)); + error->surflive = intel_de_read(display, CURSURFLIVE(display, crtc->pipe)); +} + +static void i9xx_cursor_capture_error(struct intel_crtc *crtc, + struct intel_plane *plane, + struct intel_plane_error *error) +{ + struct intel_display *display = to_intel_display(plane); + + error->ctl = intel_de_read(display, CURCNTR(display, crtc->pipe)); + error->surf = intel_de_read(display, CURBASE(display, crtc->pipe)); +} + static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, u32 format, u64 modifier) { @@ -1030,6 +1051,11 @@ intel_cursor_plane_create(struct intel_display *display, cursor->check_plane = i9xx_check_cursor; } + if (DISPLAY_VER(display) >= 5 || display->platform.g4x) + cursor->capture_error = g4x_cursor_capture_error; + else + cursor->capture_error = i9xx_cursor_capture_error; + cursor->cursor.base = ~0; cursor->cursor.cntl = ~0; diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 6c1c88ed0ba67..a4e3f33f75eb3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1437,6 +1437,10 @@ struct intel_crtc { bool block_dc_for_vblank; }; +struct intel_plane_error { + u32 ctl, surf, surflive; +}; + struct intel_plane { struct drm_plane base; enum i9xx_plane_id i9xx_plane; @@ -1488,6 +1492,9 @@ struct intel_plane { void (*disable_arm)(struct intel_dsb *dsb, struct intel_plane *plane, const struct intel_crtc_state *crtc_state); + void (*capture_error)(struct intel_crtc *crtc, + struct intel_plane *plane, + struct intel_plane_error *error); bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe); int (*check_plane)(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index ab5bc8a08f0f5..1ad6c8a94b3d9 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -447,6 +447,17 @@ vlv_sprite_disable_arm(struct intel_dsb *dsb, intel_de_write_fw(display, SPSURF(pipe, plane_id), 0); } +static void vlv_sprite_capture_error(struct intel_crtc *crtc, + struct intel_plane *plane, + struct intel_plane_error *error) +{ + struct intel_display *display = to_intel_display(plane); + + error->ctl = intel_de_read(display, SPCNTR(crtc->pipe, plane->id)); + error->surf = intel_de_read(display, SPSURF(crtc->pipe, plane->id)); + error->surflive = intel_de_read(display, SPSURFLIVE(crtc->pipe, plane->id)); +} + static bool vlv_sprite_get_hw_state(struct intel_plane *plane, enum pipe *pipe) @@ -872,6 +883,17 @@ ivb_sprite_disable_arm(struct intel_dsb *dsb, intel_de_write_fw(display, SPRSURF(pipe), 0); } +static void ivb_sprite_capture_error(struct intel_crtc *crtc, + struct intel_plane *plane, + struct intel_plane_error *error) +{ + struct intel_display *display = to_intel_display(plane); + + error->ctl = intel_de_read(display, SPRCTL(crtc->pipe)); + error->surf = intel_de_read(display, SPRSURF(crtc->pipe)); + error->surflive = intel_de_read(display, SPRSURFLIVE(crtc->pipe)); +} + static bool ivb_sprite_get_hw_state(struct intel_plane *plane, enum pipe *pipe) @@ -1207,6 +1229,17 @@ g4x_sprite_disable_arm(struct intel_dsb *dsb, intel_de_write_fw(display, DVSSURF(pipe), 0); } +static void g4x_sprite_capture_error(struct intel_crtc *crtc, + struct intel_plane *plane, + struct intel_plane_error *error) +{ + struct intel_display *display = to_intel_display(plane); + + error->ctl = intel_de_read(display, DVSCNTR(crtc->pipe)); + error->surf = intel_de_read(display, DVSSURF(crtc->pipe)); + error->surflive = intel_de_read(display, DVSSURFLIVE(crtc->pipe)); +} + static bool g4x_sprite_get_hw_state(struct intel_plane *plane, enum pipe *pipe) @@ -1587,6 +1620,7 @@ intel_sprite_plane_create(struct intel_display *display, plane->update_noarm = vlv_sprite_update_noarm; plane->update_arm = vlv_sprite_update_arm; plane->disable_arm = vlv_sprite_disable_arm; + plane->capture_error = vlv_sprite_capture_error; plane->get_hw_state = vlv_sprite_get_hw_state; plane->check_plane = vlv_sprite_check; plane->max_stride = i965_plane_max_stride; @@ -1610,6 +1644,7 @@ intel_sprite_plane_create(struct intel_display *display, plane->update_noarm = ivb_sprite_update_noarm; plane->update_arm = ivb_sprite_update_arm; plane->disable_arm = ivb_sprite_disable_arm; + plane->capture_error = ivb_sprite_capture_error; plane->get_hw_state = ivb_sprite_get_hw_state; plane->check_plane = g4x_sprite_check; @@ -1634,6 +1669,7 @@ intel_sprite_plane_create(struct intel_display *display, plane->update_noarm = g4x_sprite_update_noarm; plane->update_arm = g4x_sprite_update_arm; plane->disable_arm = g4x_sprite_disable_arm; + plane->capture_error = g4x_sprite_capture_error; plane->get_hw_state = g4x_sprite_get_hw_state; plane->check_plane = g4x_sprite_check; plane->max_stride = g4x_sprite_max_stride; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 110f66dd5cf00..cd9762947f1de 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1661,6 +1661,17 @@ icl_plane_update_arm(struct intel_dsb *dsb, skl_plane_surf(plane_state, color_plane)); } +static void skl_plane_capture_error(struct intel_crtc *crtc, + struct intel_plane *plane, + struct intel_plane_error *error) +{ + struct intel_display *display = to_intel_display(plane); + + error->ctl = intel_de_read(display, PLANE_CTL(crtc->pipe, plane->id)); + error->surf = intel_de_read(display, PLANE_SURF(crtc->pipe, plane->id)); + error->surflive = intel_de_read(display, PLANE_SURFLIVE(crtc->pipe, plane->id)); +} + static void skl_plane_async_flip(struct intel_dsb *dsb, struct intel_plane *plane, @@ -2803,6 +2814,7 @@ skl_universal_plane_create(struct intel_display *display, plane->update_arm = skl_plane_update_arm; plane->disable_arm = skl_plane_disable_arm; } + plane->capture_error = skl_plane_capture_error; plane->get_hw_state = skl_plane_get_hw_state; plane->check_plane = skl_plane_check; From f13011a799996d770b19e941ec81e2354f24f8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 17 Feb 2025 09:00:42 +0200 Subject: [PATCH 273/284] drm/i915: Pimp display fault reporting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Decode the display faults a bit more extensively so that one doesn't have to translate the bitmask to planes/etc. manually. Also for plane faults we can read out a bit of state from the relevant plane(s) and dump that out. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250217070047.953-4-ville.syrjala@linux.intel.com --- .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 + .../gpu/drm/i915/display/intel_display_irq.c | 156 +++++++++++++++++- 3 files changed, 155 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index aecff35d0ce22..124cd9ddba0b9 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -682,7 +682,7 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ old_plane_state, new_plane_state); } -static struct intel_plane * +struct intel_plane * intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id) { struct drm_i915_private *i915 = to_i915(crtc->base.dev); diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index d21eb7699dbdc..65edd88d28a9c 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -19,6 +19,8 @@ struct intel_plane; struct intel_plane_state; enum plane_id; +struct intel_plane * +intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id); bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier); unsigned int intel_adjusted_rate(const struct drm_rect *src, const struct drm_rect *dst, diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index d3ba8e2cf5a13..8c73dc8723848 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -10,6 +10,7 @@ #include "i915_irq.h" #include "i915_reg.h" #include "icl_dsi_regs.h" +#include "intel_atomic_plane.h" #include "intel_crtc.h" #include "intel_de.h" #include "intel_display_irq.h" @@ -67,6 +68,52 @@ intel_display_irq_regs_assert_irr_is_zero(struct intel_display *display, i915_re intel_dmc_wl_put(display, reg); } +struct pipe_fault_handler { + bool (*handle)(struct intel_crtc *crtc, enum plane_id plane_id); + u32 fault; + enum plane_id plane_id; +}; + +static bool handle_plane_fault(struct intel_crtc *crtc, enum plane_id plane_id) +{ + struct intel_display *display = to_intel_display(crtc); + struct intel_plane_error error = {}; + struct intel_plane *plane; + + plane = intel_crtc_get_plane(crtc, plane_id); + if (!plane || !plane->capture_error) + return false; + + plane->capture_error(crtc, plane, &error); + + drm_err_ratelimited(display->drm, + "[CRTC:%d:%s][PLANE:%d:%s] fault (CTL=0x%x, SURF=0x%x, SURFLIVE=0x%x)\n", + crtc->base.base.id, crtc->base.name, + plane->base.base.id, plane->base.name, + error.ctl, error.surf, error.surflive); + + return true; +} + +static void intel_pipe_fault_irq_handler(struct intel_display *display, + const struct pipe_fault_handler *handlers, + enum pipe pipe, u32 fault_errors) +{ + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); + const struct pipe_fault_handler *handler; + + for (handler = handlers; handler && handler->fault; handler++) { + if ((fault_errors & handler->fault) == 0) + continue; + + if (handler->handle(crtc, handler->plane_id)) + fault_errors &= ~handler->fault; + } + + WARN_ONCE(fault_errors, "[CRTC:%d:%s] unreported faults 0x%x\n", + crtc->base.base.id, crtc->base.name, fault_errors); +} + static void intel_handle_vblank(struct drm_i915_private *dev_priv, enum pipe pipe) { @@ -947,6 +994,108 @@ static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv) GEN8_PIPE_PRIMARY_FAULT; } +static bool handle_plane_ats_fault(struct intel_crtc *crtc, enum plane_id plane_id) +{ + struct intel_display *display = to_intel_display(crtc); + + drm_err_ratelimited(display->drm, + "[CRTC:%d:%s] PLANE ATS fault\n", + crtc->base.base.id, crtc->base.name); + + return false; +} + +static bool handle_pipedmc_ats_fault(struct intel_crtc *crtc, enum plane_id plane_id) +{ + struct intel_display *display = to_intel_display(crtc); + + drm_err_ratelimited(display->drm, + "[CRTC:%d:%s] PIPEDMC ATS fault\n", + crtc->base.base.id, crtc->base.name); + + return false; +} + +static bool handle_pipedmc_fault(struct intel_crtc *crtc, enum plane_id plane_id) +{ + struct intel_display *display = to_intel_display(crtc); + + drm_err_ratelimited(display->drm, + "[CRTC:%d:%s] PIPEDMC fault\n", + crtc->base.base.id, crtc->base.name); + + return false; +} + +static const struct pipe_fault_handler mtl_pipe_fault_handlers[] = { + { .fault = MTL_PLANE_ATS_FAULT, .handle = handle_plane_ats_fault, }, + { .fault = MTL_PIPEDMC_ATS_FAULT, .handle = handle_pipedmc_ats_fault, }, + { .fault = GEN12_PIPEDMC_FAULT, .handle = handle_pipedmc_fault, }, + { .fault = GEN11_PIPE_PLANE5_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_5, }, + { .fault = GEN9_PIPE_PLANE4_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_4, }, + { .fault = GEN9_PIPE_PLANE3_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_3, }, + { .fault = GEN9_PIPE_PLANE2_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_2, }, + { .fault = GEN9_PIPE_PLANE1_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_1, }, + { .fault = GEN9_PIPE_CURSOR_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + {} +}; + +static const struct pipe_fault_handler tgl_pipe_fault_handlers[] = { + { .fault = GEN12_PIPEDMC_FAULT, .handle = handle_pipedmc_fault, }, + { .fault = GEN11_PIPE_PLANE7_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_7, }, + { .fault = GEN11_PIPE_PLANE6_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_6, }, + { .fault = GEN11_PIPE_PLANE5_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_5, }, + { .fault = GEN9_PIPE_PLANE4_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_4, }, + { .fault = GEN9_PIPE_PLANE3_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_3, }, + { .fault = GEN9_PIPE_PLANE2_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_2, }, + { .fault = GEN9_PIPE_PLANE1_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_1, }, + { .fault = GEN9_PIPE_CURSOR_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + {} +}; + +static const struct pipe_fault_handler icl_pipe_fault_handlers[] = { + { .fault = GEN11_PIPE_PLANE7_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_7, }, + { .fault = GEN11_PIPE_PLANE6_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_6, }, + { .fault = GEN11_PIPE_PLANE5_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_5, }, + { .fault = GEN9_PIPE_PLANE4_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_4, }, + { .fault = GEN9_PIPE_PLANE3_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_3, }, + { .fault = GEN9_PIPE_PLANE2_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_2, }, + { .fault = GEN9_PIPE_PLANE1_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_1, }, + { .fault = GEN9_PIPE_CURSOR_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + {} +}; + +static const struct pipe_fault_handler skl_pipe_fault_handlers[] = { + { .fault = GEN9_PIPE_PLANE4_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_4, }, + { .fault = GEN9_PIPE_PLANE3_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_3, }, + { .fault = GEN9_PIPE_PLANE2_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_2, }, + { .fault = GEN9_PIPE_PLANE1_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_1, }, + { .fault = GEN9_PIPE_CURSOR_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + {} +}; + +static const struct pipe_fault_handler bdw_pipe_fault_handlers[] = { + { .fault = GEN8_PIPE_SPRITE_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE0, }, + { .fault = GEN8_PIPE_PRIMARY_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_PRIMARY, }, + { .fault = GEN8_PIPE_CURSOR_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + {} +}; + +static const struct pipe_fault_handler * +gen8_pipe_fault_handlers(struct intel_display *display) +{ + if (DISPLAY_VER(display) >= 14) + return mtl_pipe_fault_handlers; + else if (DISPLAY_VER(display) >= 12) + return tgl_pipe_fault_handlers; + else if (DISPLAY_VER(display) >= 11) + return icl_pipe_fault_handlers; + else if (DISPLAY_VER(display) >= 9) + return skl_pipe_fault_handlers; + else + return bdw_pipe_fault_handlers; +} + static void intel_pmdemand_irq_handler(struct drm_i915_private *dev_priv) { wake_up_all(&dev_priv->display.pmdemand.waitqueue); @@ -1233,10 +1382,9 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) fault_errors = iir & gen8_de_pipe_fault_mask(dev_priv); if (fault_errors) - drm_err_ratelimited(&dev_priv->drm, - "Fault errors on pipe %c: 0x%08x\n", - pipe_name(pipe), - fault_errors); + intel_pipe_fault_irq_handler(display, + gen8_pipe_fault_handlers(display), + pipe, fault_errors); } if (HAS_PCH_SPLIT(dev_priv) && !HAS_PCH_NOP(dev_priv) && From 112a0317ebc601b4002c0c1ad0d500f72e26e514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 17 Feb 2025 09:00:43 +0200 Subject: [PATCH 274/284] drm/i915: Hook in display GTT faults for IVB/HSW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dump out the display fault information from the IVB/HSW error interrupt handler. Bspec: 8203 Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250217070047.953-5-ville.syrjala@linux.intel.com --- .../gpu/drm/i915/display/intel_display_irq.c | 46 +++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 11 +++++ 2 files changed, 57 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 8c73dc8723848..cd53008ab5908 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -720,6 +720,39 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) intel_pch_fifo_underrun_irq_handler(display, PIPE_B); } +static u32 ivb_err_int_pipe_fault_mask(enum pipe pipe) +{ + switch (pipe) { + case PIPE_A: + return ERR_INT_SPRITE_A_FAULT | + ERR_INT_PRIMARY_A_FAULT | + ERR_INT_CURSOR_A_FAULT; + case PIPE_B: + return ERR_INT_SPRITE_B_FAULT | + ERR_INT_PRIMARY_B_FAULT | + ERR_INT_CURSOR_B_FAULT; + case PIPE_C: + return ERR_INT_SPRITE_C_FAULT | + ERR_INT_PRIMARY_C_FAULT | + ERR_INT_CURSOR_C_FAULT; + default: + return 0; + } +} + +static const struct pipe_fault_handler ivb_pipe_fault_handlers[] = { + { .fault = ERR_INT_SPRITE_A_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE0, }, + { .fault = ERR_INT_PRIMARY_A_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_PRIMARY, }, + { .fault = ERR_INT_CURSOR_A_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + { .fault = ERR_INT_SPRITE_B_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE0, }, + { .fault = ERR_INT_PRIMARY_B_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_PRIMARY, }, + { .fault = ERR_INT_CURSOR_B_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + { .fault = ERR_INT_SPRITE_C_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE0, }, + { .fault = ERR_INT_PRIMARY_C_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_PRIMARY, }, + { .fault = ERR_INT_CURSOR_C_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + {} +}; + static void ivb_err_int_handler(struct drm_i915_private *dev_priv) { struct intel_display *display = &dev_priv->display; @@ -729,7 +762,15 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv) if (err_int & ERR_INT_POISON) drm_err(&dev_priv->drm, "Poison interrupt\n"); + if (err_int & ERR_INT_INVALID_GTT_PTE) + drm_err_ratelimited(display->drm, "Invalid GTT PTE\n"); + + if (err_int & ERR_INT_INVALID_PTE_DATA) + drm_err_ratelimited(display->drm, "Invalid PTE data\n"); + for_each_pipe(dev_priv, pipe) { + u32 fault_errors; + if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) intel_cpu_fifo_underrun_irq_handler(display, pipe); @@ -739,6 +780,11 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv) else hsw_pipe_crc_irq_handler(dev_priv, pipe); } + + fault_errors = err_int & ivb_err_int_pipe_fault_mask(pipe); + if (fault_errors) + intel_pipe_fault_irq_handler(display, ivb_pipe_fault_handlers, + pipe, fault_errors); } intel_de_write(display, GEN7_ERR_INT, err_int); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3a936a4aa2e88..b8756e5d2cae9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -374,6 +374,17 @@ #define GEN7_ERR_INT _MMIO(0x44040) #define ERR_INT_POISON (1 << 31) +#define ERR_INT_INVALID_GTT_PTE (1 << 29) +#define ERR_INT_INVALID_PTE_DATA (1 << 28) +#define ERR_INT_SPRITE_C_FAULT (1 << 23) +#define ERR_INT_PRIMARY_C_FAULT (1 << 22) +#define ERR_INT_CURSOR_C_FAULT (1 << 21) +#define ERR_INT_SPRITE_B_FAULT (1 << 20) +#define ERR_INT_PRIMARY_B_FAULT (1 << 19) +#define ERR_INT_CURSOR_B_FAULT (1 << 18) +#define ERR_INT_SPRITE_A_FAULT (1 << 17) +#define ERR_INT_PRIMARY_A_FAULT (1 << 16) +#define ERR_INT_CURSOR_A_FAULT (1 << 15) #define ERR_INT_MMIO_UNCLAIMED (1 << 13) #define ERR_INT_PIPE_CRC_DONE_C (1 << 8) #define ERR_INT_FIFO_UNDERRUN_C (1 << 6) From d2093831eafb8dc0e25915c377e86dd4920d5b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 17 Feb 2025 09:00:44 +0200 Subject: [PATCH 275/284] drm/i915: Hook in display GTT faults for ILK/SNB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hook up display GTT fault interrupts for ILK/SNB. Bspec: 8559 Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250217070047.953-6-ville.syrjala@linux.intel.com --- .../gpu/drm/i915/display/intel_display_irq.c | 56 ++++++++++++++++++- drivers/gpu/drm/i915/i915_reg.h | 10 ++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index cd53008ab5908..1fa44f6bf8805 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -844,6 +844,56 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) cpt_serr_int_handler(dev_priv); } +static u32 ilk_gtt_fault_pipe_fault_mask(enum pipe pipe) +{ + switch (pipe) { + case PIPE_A: + return GTT_FAULT_SPRITE_A_FAULT | + GTT_FAULT_PRIMARY_A_FAULT | + GTT_FAULT_CURSOR_A_FAULT; + case PIPE_B: + return GTT_FAULT_SPRITE_B_FAULT | + GTT_FAULT_PRIMARY_B_FAULT | + GTT_FAULT_CURSOR_B_FAULT; + default: + return 0; + } +} + +static const struct pipe_fault_handler ilk_pipe_fault_handlers[] = { + { .fault = GTT_FAULT_SPRITE_A_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE0, }, + { .fault = GTT_FAULT_SPRITE_B_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE0, }, + { .fault = GTT_FAULT_PRIMARY_A_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_PRIMARY, }, + { .fault = GTT_FAULT_PRIMARY_B_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_PRIMARY, }, + { .fault = GTT_FAULT_CURSOR_A_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + { .fault = GTT_FAULT_CURSOR_B_FAULT, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + {} +}; + +static void ilk_gtt_fault_irq_handler(struct intel_display *display) +{ + enum pipe pipe; + u32 gtt_fault; + + gtt_fault = intel_de_read(display, ILK_GTT_FAULT); + intel_de_write(display, ILK_GTT_FAULT, gtt_fault); + + if (gtt_fault & GTT_FAULT_INVALID_GTT_PTE) + drm_err_ratelimited(display->drm, "Invalid GTT PTE\n"); + + if (gtt_fault & GTT_FAULT_INVALID_PTE_DATA) + drm_err_ratelimited(display->drm, "Invalid PTE data\n"); + + for_each_pipe(display, pipe) { + u32 fault_errors; + + fault_errors = gtt_fault & ilk_gtt_fault_pipe_fault_mask(pipe); + if (fault_errors) + intel_pipe_fault_irq_handler(display, ilk_pipe_fault_handlers, + pipe, fault_errors); + } +} + void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) { struct intel_display *display = &dev_priv->display; @@ -862,6 +912,9 @@ void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) if (de_iir & DE_POISON) drm_err(&dev_priv->drm, "Poison interrupt\n"); + if (de_iir & DE_GTT_FAULT) + ilk_gtt_fault_irq_handler(display); + for_each_pipe(dev_priv, pipe) { if (de_iir & DE_PIPE_VBLANK(pipe)) intel_handle_vblank(dev_priv, pipe); @@ -1988,7 +2041,8 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915) DE_PLANE_FLIP_DONE_IVB(PLANE_A) | DE_DP_A_HOTPLUG_IVB); } else { - display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | + display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | + DE_PCH_EVENT | DE_GTT_FAULT | DE_AUX_CHANNEL_A | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | DE_POISON); extra_mask = (DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b8756e5d2cae9..5e91fcf40a0f6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -372,6 +372,16 @@ #define GEN7_MEDIA_MAX_REQ_COUNT _MMIO(0x4070) #define GEN7_GFX_MAX_REQ_COUNT _MMIO(0x4074) +#define ILK_GTT_FAULT _MMIO(0x44040) /* ilk/snb */ +#define GTT_FAULT_INVALID_GTT_PTE (1 << 7) +#define GTT_FAULT_INVALID_PTE_DATA (1 << 6) +#define GTT_FAULT_CURSOR_B_FAULT (1 << 5) +#define GTT_FAULT_CURSOR_A_FAULT (1 << 4) +#define GTT_FAULT_SPRITE_B_FAULT (1 << 3) +#define GTT_FAULT_SPRITE_A_FAULT (1 << 2) +#define GTT_FAULT_PRIMARY_B_FAULT (1 << 1) +#define GTT_FAULT_PRIMARY_A_FAULT (1 << 0) + #define GEN7_ERR_INT _MMIO(0x44040) #define ERR_INT_POISON (1 << 31) #define ERR_INT_INVALID_GTT_PTE (1 << 29) From 474e1cd6fe898d3c51aa3633ebab0581ff80ab7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 17 Feb 2025 09:00:45 +0200 Subject: [PATCH 276/284] drm/i915: Introduce i915_error_regs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce i915_error_regs as the EIR/EMR counterpart to the IIR/IMR/IER i915_irq_regs, and update the irq reset/postingstall to utilize them accordingly. v2: Include xe compat versions Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250217070047.953-7-ville.syrjala@linux.intel.com Acked-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_irq.c | 29 +++++++++++++++++++++-- drivers/gpu/drm/i915/i915_irq.h | 4 ++++ drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/i915_reg_defs.h | 8 +++++++ drivers/gpu/drm/xe/display/ext/i915_irq.c | 23 ++++++++++++++++++ 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f98e5cc14724b..bba0a0acf0ae8 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -120,6 +120,29 @@ void gen2_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs, intel_uncore_posting_read(uncore, regs.imr); } +void gen2_error_reset(struct intel_uncore *uncore, struct i915_error_regs regs) +{ + intel_uncore_write(uncore, regs.emr, 0xffffffff); + intel_uncore_posting_read(uncore, regs.emr); + + intel_uncore_write(uncore, regs.eir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.eir); + intel_uncore_write(uncore, regs.eir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.eir); +} + +void gen2_error_init(struct intel_uncore *uncore, struct i915_error_regs regs, + u32 emr_val) +{ + intel_uncore_write(uncore, regs.eir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.eir); + intel_uncore_write(uncore, regs.eir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.eir); + + intel_uncore_write(uncore, regs.emr, emr_val); + intel_uncore_posting_read(uncore, regs.emr); +} + /** * ivb_parity_work - Workqueue called when a parity error interrupt * occurred. @@ -867,6 +890,7 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv) i9xx_display_irq_reset(dev_priv); + gen2_error_reset(uncore, GEN2_ERROR_REGS); gen2_irq_reset(uncore, GEN2_IRQ_REGS); dev_priv->irq_mask = ~0u; } @@ -876,7 +900,7 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) struct intel_uncore *uncore = &dev_priv->uncore; u32 enable_mask; - intel_uncore_write(uncore, EMR, i9xx_error_mask(dev_priv)); + gen2_error_init(uncore, GEN2_ERROR_REGS, i9xx_error_mask(dev_priv)); dev_priv->irq_mask = ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | @@ -972,6 +996,7 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv) i9xx_display_irq_reset(dev_priv); + gen2_error_reset(uncore, GEN2_ERROR_REGS); gen2_irq_reset(uncore, GEN2_IRQ_REGS); dev_priv->irq_mask = ~0u; } @@ -1000,7 +1025,7 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv) struct intel_uncore *uncore = &dev_priv->uncore; u32 enable_mask; - intel_uncore_write(uncore, EMR, i965_error_mask(dev_priv)); + gen2_error_init(uncore, GEN2_ERROR_REGS, i965_error_mask(dev_priv)); dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h index 0457f6402e051..58789b264575c 100644 --- a/drivers/gpu/drm/i915/i915_irq.h +++ b/drivers/gpu/drm/i915/i915_irq.h @@ -47,4 +47,8 @@ void gen2_irq_reset(struct intel_uncore *uncore, struct i915_irq_regs regs); void gen2_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs, u32 imr_val, u32 ier_val); +void gen2_error_reset(struct intel_uncore *uncore, struct i915_error_regs regs); +void gen2_error_init(struct intel_uncore *uncore, struct i915_error_regs regs, + u32 emr_val); + #endif /* __I915_IRQ_H__ */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5e91fcf40a0f6..be1aab838be96 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -472,6 +472,9 @@ #define GM45_ERROR_CP_PRIV (1 << 3) #define I915_ERROR_MEMORY_REFRESH (1 << 1) #define I915_ERROR_INSTRUCTION (1 << 0) + +#define GEN2_ERROR_REGS I915_ERROR_REGS(EMR, EIR) + #define INSTPM _MMIO(0x20c0) #define INSTPM_SELF_EN (1 << 12) /* 915GM only */ #define INSTPM_AGPBUSY_INT_EN (1 << 11) /* gen3: when disabled, pending interrupts diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h b/drivers/gpu/drm/i915/i915_reg_defs.h index e251bcc0c89f5..94a8f902689e8 100644 --- a/drivers/gpu/drm/i915/i915_reg_defs.h +++ b/drivers/gpu/drm/i915/i915_reg_defs.h @@ -294,4 +294,12 @@ struct i915_irq_regs { #define I915_IRQ_REGS(_imr, _ier, _iir) \ ((const struct i915_irq_regs){ .imr = (_imr), .ier = (_ier), .iir = (_iir) }) +struct i915_error_regs { + i915_reg_t emr; + i915_reg_t eir; +}; + +#define I915_ERROR_REGS(_emr, _eir) \ + ((const struct i915_error_regs){ .emr = (_emr), .eir = (_eir) }) + #endif /* __I915_REG_DEFS__ */ diff --git a/drivers/gpu/drm/xe/display/ext/i915_irq.c b/drivers/gpu/drm/xe/display/ext/i915_irq.c index ac4cda2d81c7a..3c6bca66ddab6 100644 --- a/drivers/gpu/drm/xe/display/ext/i915_irq.c +++ b/drivers/gpu/drm/xe/display/ext/i915_irq.c @@ -51,6 +51,29 @@ void gen2_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs, intel_uncore_posting_read(uncore, regs.imr); } +void gen2_error_reset(struct intel_uncore *uncore, struct i915_error_regs regs) +{ + intel_uncore_write(uncore, regs.emr, 0xffffffff); + intel_uncore_posting_read(uncore, regs.emr); + + intel_uncore_write(uncore, regs.eir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.eir); + intel_uncore_write(uncore, regs.eir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.eir); +} + +void gen2_error_init(struct intel_uncore *uncore, struct i915_error_regs regs, + u32 emr_val) +{ + intel_uncore_write(uncore, regs.eir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.eir); + intel_uncore_write(uncore, regs.eir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.eir); + + intel_uncore_write(uncore, regs.emr, emr_val); + intel_uncore_posting_read(uncore, regs.emr); +} + bool intel_irqs_enabled(struct xe_device *xe) { return atomic_read(&xe->irq.enabled); From b6cfae8d9c71b6caed505de4f987862cf2f18c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 17 Feb 2025 09:00:46 +0200 Subject: [PATCH 277/284] drm/i915: Un-invert {i9xx,i965}_error_mask() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make life a bit more straightforward by removing the bitwise not from {i9xx,i965}_error_mask() and instead do it when feeding the value to gen2_error_init(). Make life a bit easier I think. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250217070047.953-8-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index bba0a0acf0ae8..da130e1b5cc1c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -838,10 +838,10 @@ static u32 i9xx_error_mask(struct drm_i915_private *i915) * so we just have to mask off all page table errors via EMR. */ if (HAS_FBC(i915)) - return ~I915_ERROR_MEMORY_REFRESH; + return I915_ERROR_MEMORY_REFRESH; else - return ~(I915_ERROR_PAGE_TABLE | - I915_ERROR_MEMORY_REFRESH); + return I915_ERROR_PAGE_TABLE | + I915_ERROR_MEMORY_REFRESH; } static void i9xx_error_irq_ack(struct drm_i915_private *dev_priv, @@ -900,7 +900,7 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) struct intel_uncore *uncore = &dev_priv->uncore; u32 enable_mask; - gen2_error_init(uncore, GEN2_ERROR_REGS, i9xx_error_mask(dev_priv)); + gen2_error_init(uncore, GEN2_ERROR_REGS, ~i9xx_error_mask(dev_priv)); dev_priv->irq_mask = ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | @@ -1011,13 +1011,13 @@ static u32 i965_error_mask(struct drm_i915_private *i915) * so we can always enable the page table errors. */ if (IS_G4X(i915)) - return ~(GM45_ERROR_PAGE_TABLE | - GM45_ERROR_MEM_PRIV | - GM45_ERROR_CP_PRIV | - I915_ERROR_MEMORY_REFRESH); + return GM45_ERROR_PAGE_TABLE | + GM45_ERROR_MEM_PRIV | + GM45_ERROR_CP_PRIV | + I915_ERROR_MEMORY_REFRESH; else - return ~(I915_ERROR_PAGE_TABLE | - I915_ERROR_MEMORY_REFRESH); + return I915_ERROR_PAGE_TABLE | + I915_ERROR_MEMORY_REFRESH; } static void i965_irq_postinstall(struct drm_i915_private *dev_priv) @@ -1025,7 +1025,7 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv) struct intel_uncore *uncore = &dev_priv->uncore; u32 enable_mask; - gen2_error_init(uncore, GEN2_ERROR_REGS, i965_error_mask(dev_priv)); + gen2_error_init(uncore, GEN2_ERROR_REGS, ~i965_error_mask(dev_priv)); dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | From c19f5a0341e0a54e61469218fd9419633db5c937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 17 Feb 2025 09:00:47 +0200 Subject: [PATCH 278/284] drm/i915: Hook up display fault interrupts for VLV/CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hook up the display fault irq handlers for VLV/CHV. Unfortunately the actual hardware doesn't agree with the spec on how DPINVGTT should behave. The docs claim that the status bits can be cleared by writing '1' to them, but in reality there doesn't seem to be any way to clear them. So we must disable and ignore any fault we've already seen in the past. The entire register does reset when the display power well goes down, so we can just always re-enable all the bits in irq postinstall without having to track the state beyond that. v2: Use intel_display instead of dev_priv Move xe gen2_error_{init,reset}() out Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250217070047.953-9-ville.syrjala@linux.intel.com --- .../gpu/drm/i915/display/intel_display_irq.c | 132 +++++++++++++++++- .../gpu/drm/i915/display/intel_display_irq.h | 3 + drivers/gpu/drm/i915/i915_irq.c | 14 ++ drivers/gpu/drm/i915/i915_reg.h | 10 ++ 4 files changed, 158 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 1fa44f6bf8805..99fb7fc7be394 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1784,6 +1784,114 @@ void bdw_disable_vblank(struct drm_crtc *_crtc) schedule_work(&display->irq.vblank_dc_work); } +static u32 vlv_dpinvgtt_pipe_fault_mask(enum pipe pipe) +{ + switch (pipe) { + case PIPE_A: + return SPRITEB_INVALID_GTT_STATUS | + SPRITEA_INVALID_GTT_STATUS | + PLANEA_INVALID_GTT_STATUS | + CURSORA_INVALID_GTT_STATUS; + case PIPE_B: + return SPRITED_INVALID_GTT_STATUS | + SPRITEC_INVALID_GTT_STATUS | + PLANEB_INVALID_GTT_STATUS | + CURSORB_INVALID_GTT_STATUS; + case PIPE_C: + return SPRITEF_INVALID_GTT_STATUS | + SPRITEE_INVALID_GTT_STATUS | + PLANEC_INVALID_GTT_STATUS | + CURSORC_INVALID_GTT_STATUS; + default: + return 0; + } +} + +static const struct pipe_fault_handler vlv_pipe_fault_handlers[] = { + { .fault = SPRITEB_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE1, }, + { .fault = SPRITEA_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE0, }, + { .fault = PLANEA_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_PRIMARY, }, + { .fault = CURSORA_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + { .fault = SPRITED_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE1, }, + { .fault = SPRITEC_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE0, }, + { .fault = PLANEB_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_PRIMARY, }, + { .fault = CURSORB_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + { .fault = SPRITEF_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE1, }, + { .fault = SPRITEE_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_SPRITE0, }, + { .fault = PLANEC_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_PRIMARY, }, + { .fault = CURSORC_INVALID_GTT_STATUS, .handle = handle_plane_fault, .plane_id = PLANE_CURSOR, }, + {} +}; + +static void vlv_page_table_error_irq_ack(struct intel_display *display, u32 *dpinvgtt) +{ + u32 status, enable, tmp; + + tmp = intel_de_read(display, DPINVGTT); + + enable = tmp >> 16; + status = tmp & 0xffff; + + /* + * Despite what the docs claim, the status bits seem to get + * stuck permanently (similar the old PGTBL_ER register), so + * we have to disable and ignore them once set. They do get + * reset if the display power well goes down, so no need to + * track the enable mask explicitly. + */ + *dpinvgtt = status & enable; + enable &= ~status; + + /* customary ack+disable then re-enable to guarantee an edge */ + intel_de_write(display, DPINVGTT, status); + intel_de_write(display, DPINVGTT, enable << 16); +} + +static void vlv_page_table_error_irq_handler(struct intel_display *display, u32 dpinvgtt) +{ + enum pipe pipe; + + for_each_pipe(display, pipe) { + u32 fault_errors; + + fault_errors = dpinvgtt & vlv_dpinvgtt_pipe_fault_mask(pipe); + if (fault_errors) + intel_pipe_fault_irq_handler(display, vlv_pipe_fault_handlers, + pipe, fault_errors); + } +} + +void vlv_display_error_irq_ack(struct intel_display *display, + u32 *eir, u32 *dpinvgtt) +{ + u32 emr; + + *eir = intel_de_read(display, VLV_EIR); + + if (*eir & VLV_ERROR_PAGE_TABLE) + vlv_page_table_error_irq_ack(display, dpinvgtt); + + intel_de_write(display, VLV_EIR, *eir); + + /* + * Toggle all EMR bits to make sure we get an edge + * in the ISR master error bit if we don't clear + * all the EIR bits. + */ + emr = intel_de_read(display, VLV_EMR); + intel_de_write(display, VLV_EMR, 0xffffffff); + intel_de_write(display, VLV_EMR, emr); +} + +void vlv_display_error_irq_handler(struct intel_display *display, + u32 eir, u32 dpinvgtt) +{ + drm_dbg(display->drm, "Master Error, EIR 0x%08x\n", eir); + + if (eir & VLV_ERROR_PAGE_TABLE) + vlv_page_table_error_irq_handler(display, dpinvgtt); +} + static void _vlv_display_irq_reset(struct drm_i915_private *dev_priv) { struct intel_display *display = &dev_priv->display; @@ -1793,6 +1901,9 @@ static void _vlv_display_irq_reset(struct drm_i915_private *dev_priv) else intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_VLV); + gen2_error_reset(to_intel_uncore(display->drm), + VLV_ERROR_REGS); + i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0); intel_de_rmw(display, PORT_HOTPLUG_STAT(dev_priv), 0, 0); @@ -1820,6 +1931,12 @@ void i9xx_display_irq_reset(struct drm_i915_private *i915) i9xx_pipestat_irq_reset(i915); } +static u32 vlv_error_mask(void) +{ + /* TODO enable other errors too? */ + return VLV_ERROR_PAGE_TABLE; +} + void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) { struct intel_display *display = &dev_priv->display; @@ -1830,6 +1947,18 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) if (!dev_priv->display.irq.vlv_display_irqs_enabled) return; + if (IS_CHERRYVIEW(dev_priv)) + intel_de_write(display, DPINVGTT, + DPINVGTT_STATUS_MASK_CHV | + DPINVGTT_EN_MASK_CHV); + else + intel_de_write(display, DPINVGTT, + DPINVGTT_STATUS_MASK_VLV | + DPINVGTT_EN_MASK_VLV); + + gen2_error_init(to_intel_uncore(display->drm), + VLV_ERROR_REGS, ~vlv_error_mask()); + pipestat_mask = PIPE_CRC_DONE_INTERRUPT_STATUS; i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); @@ -1840,7 +1969,8 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | I915_LPE_PIPE_A_INTERRUPT | - I915_LPE_PIPE_B_INTERRUPT; + I915_LPE_PIPE_B_INTERRUPT | + I915_MASTER_ERROR_INTERRUPT; if (IS_CHERRYVIEW(dev_priv)) enable_mask |= I915_DISPLAY_PIPE_C_EVENT_INTERRUPT | diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index 75ab38a0908e4..d9867cd0a220d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -76,6 +76,9 @@ void i915_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_ void i965_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); void valleyview_pipestat_irq_handler(struct drm_i915_private *i915, u32 pipe_stats[I915_MAX_PIPES]); +void vlv_display_error_irq_ack(struct intel_display *display, u32 *eir, u32 *dpinvgtt); +void vlv_display_error_irq_handler(struct intel_display *display, u32 eir, u32 dpinvgtt); + void intel_display_irq_init(struct drm_i915_private *i915); void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index da130e1b5cc1c..37ca4a35daf2f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -241,6 +241,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) do { u32 iir, gt_iir, pm_iir; + u32 eir = 0, dpinvgtt = 0; u32 pipe_stats[I915_MAX_PIPES] = {}; u32 hotplug_status = 0; u32 ier = 0; @@ -278,6 +279,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) if (iir & I915_DISPLAY_PORT_INTERRUPT) hotplug_status = i9xx_hpd_irq_ack(dev_priv); + if (iir & I915_MASTER_ERROR_INTERRUPT) + vlv_display_error_irq_ack(display, &eir, &dpinvgtt); + /* Call regardless, as some status bits might not be * signalled in IIR */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); @@ -304,6 +308,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) if (hotplug_status) i9xx_hpd_irq_handler(dev_priv, hotplug_status); + if (iir & I915_MASTER_ERROR_INTERRUPT) + vlv_display_error_irq_handler(display, eir, dpinvgtt); + valleyview_pipestat_irq_handler(dev_priv, pipe_stats); } while (0); @@ -328,6 +335,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) do { u32 master_ctl, iir; + u32 eir = 0, dpinvgtt = 0; u32 pipe_stats[I915_MAX_PIPES] = {}; u32 hotplug_status = 0; u32 ier = 0; @@ -361,6 +369,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) if (iir & I915_DISPLAY_PORT_INTERRUPT) hotplug_status = i9xx_hpd_irq_ack(dev_priv); + if (iir & I915_MASTER_ERROR_INTERRUPT) + vlv_display_error_irq_ack(display, &eir, &dpinvgtt); + /* Call regardless, as some status bits might not be * signalled in IIR */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); @@ -383,6 +394,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) if (hotplug_status) i9xx_hpd_irq_handler(dev_priv, hotplug_status); + if (iir & I915_MASTER_ERROR_INTERRUPT) + vlv_display_error_irq_handler(display, eir, dpinvgtt); + valleyview_pipestat_irq_handler(dev_priv, pipe_stats); } while (0); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index be1aab838be96..b31b26e9a6859 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -475,6 +475,16 @@ #define GEN2_ERROR_REGS I915_ERROR_REGS(EMR, EIR) +#define VLV_EIR _MMIO(VLV_DISPLAY_BASE + 0x20b0) +#define VLV_EMR _MMIO(VLV_DISPLAY_BASE + 0x20b4) +#define VLV_ESR _MMIO(VLV_DISPLAY_BASE + 0x20b8) +#define VLV_ERROR_GUNIT_TLB_DATA (1 << 6) +#define VLV_ERROR_GUNIT_TLB_PTE (1 << 5) +#define VLV_ERROR_PAGE_TABLE (1 << 4) +#define VLV_ERROR_CLAIM (1 << 0) + +#define VLV_ERROR_REGS I915_ERROR_REGS(VLV_EMR, VLV_EIR) + #define INSTPM _MMIO(0x20c0) #define INSTPM_SELF_EN (1 << 12) /* 915GM only */ #define INSTPM_AGPBUSY_INT_EN (1 << 11) /* gen3: when disabled, pending interrupts From a4ed5f3ab0ce2655a217cb214fb0603faeb64797 Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Tue, 18 Feb 2025 12:00:18 +0200 Subject: [PATCH 279/284] drm/i915/display: Drop crtc_state from C10/C20 pll programming For PLL programming for C10 and C20 we don't need to carry crtc_state but instead use only necessary parts of the crtc_state i.e. pll_state. This change is needed to PTL wa 14023648281 where we would need to otherwise pass an artificial crtc_state with majority of the struct members initialized as NULL. v2: Use err instead of val for error handling (Imre) Unify parameter order (Imre) v3: Fix misplaced port_clock, and is_dp in intel_c20_pll_program() call (Imre) Signed-off-by: Mika Kahola Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250218100019.740556-2-mika.kahola@intel.com --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 131 +++++++++++-------- 1 file changed, 74 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 4121d0d759bf2..8d6fd3f1ac13a 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -2020,13 +2020,12 @@ intel_c10pll_tables_get(struct intel_crtc_state *crtc_state, return NULL; } -static void intel_cx0pll_update_ssc(struct intel_crtc_state *crtc_state, - struct intel_encoder *encoder) +static void intel_cx0pll_update_ssc(struct intel_encoder *encoder, + struct intel_cx0pll_state *pll_state, bool is_dp) { struct intel_display *display = to_intel_display(encoder); - struct intel_cx0pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll; - if (intel_crtc_has_dp_encoder(crtc_state)) { + if (is_dp) { if (intel_panel_use_ssc(display)) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); pll_state->ssc_enabled = @@ -2035,11 +2034,10 @@ static void intel_cx0pll_update_ssc(struct intel_crtc_state *crtc_state, } } -static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state, - struct intel_encoder *encoder) +static void intel_c10pll_update_pll(struct intel_encoder *encoder, + struct intel_cx0pll_state *pll_state) { struct intel_display *display = to_intel_display(encoder); - struct intel_cx0pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll; int i; if (pll_state->ssc_enabled) @@ -2050,38 +2048,53 @@ static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state, pll_state->c10.pll[i] = 0; } +static int intel_c10pll_calc_state_from_table(struct intel_encoder *encoder, + const struct intel_c10pll_state * const *tables, + bool is_dp, int port_clock, + struct intel_cx0pll_state *pll_state) +{ + int i; + + for (i = 0; tables[i]; i++) { + if (port_clock == tables[i]->clock) { + pll_state->c10 = *tables[i]; + intel_cx0pll_update_ssc(encoder, pll_state, is_dp); + intel_c10pll_update_pll(encoder, pll_state); + pll_state->use_c10 = true; + + return 0; + } + } + + return -EINVAL; +} + static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) { const struct intel_c10pll_state * const *tables; - int i; + int err; tables = intel_c10pll_tables_get(crtc_state, encoder); if (!tables) return -EINVAL; - for (i = 0; tables[i]; i++) { - if (crtc_state->port_clock == tables[i]->clock) { - crtc_state->dpll_hw_state.cx0pll.c10 = *tables[i]; - intel_cx0pll_update_ssc(crtc_state, encoder); - intel_c10pll_update_pll(crtc_state, encoder); - crtc_state->dpll_hw_state.cx0pll.use_c10 = true; + err = intel_c10pll_calc_state_from_table(encoder, tables, + intel_crtc_has_dp_encoder(crtc_state), + crtc_state->port_clock, + &crtc_state->dpll_hw_state.cx0pll); - return 0; - } - } + if (err == 0 || !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + return err; /* For HDMI PLLs try SNPS PHY algorithm, if there are no precomputed tables */ - if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { - intel_snps_hdmi_pll_compute_c10pll(&crtc_state->dpll_hw_state.cx0pll.c10, - crtc_state->port_clock); - intel_c10pll_update_pll(crtc_state, encoder); - crtc_state->dpll_hw_state.cx0pll.use_c10 = true; - - return 0; - } + intel_snps_hdmi_pll_compute_c10pll(&crtc_state->dpll_hw_state.cx0pll.c10, + crtc_state->port_clock); + intel_c10pll_update_pll(encoder, + &crtc_state->dpll_hw_state.cx0pll); + crtc_state->dpll_hw_state.cx0pll.use_c10 = true; - return -EINVAL; + return 0; } static void intel_c10pll_readout_hw_state(struct intel_encoder *encoder, @@ -2111,10 +2124,9 @@ static void intel_c10pll_readout_hw_state(struct intel_encoder *encoder, } static void intel_c10_pll_program(struct intel_display *display, - const struct intel_crtc_state *crtc_state, - struct intel_encoder *encoder) + struct intel_encoder *encoder, + const struct intel_c10pll_state *pll_state) { - const struct intel_c10pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c10; int i; intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1), @@ -2333,7 +2345,9 @@ static int intel_c20pll_calc_state(struct intel_crtc_state *crtc_state, for (i = 0; tables[i]; i++) { if (crtc_state->port_clock == tables[i]->clock) { crtc_state->dpll_hw_state.cx0pll.c20 = *tables[i]; - intel_cx0pll_update_ssc(crtc_state, encoder); + intel_cx0pll_update_ssc(encoder, + &crtc_state->dpll_hw_state.cx0pll, + intel_crtc_has_dp_encoder(crtc_state)); crtc_state->dpll_hw_state.cx0pll.use_c10 = false; return 0; } @@ -2599,19 +2613,14 @@ static int intel_get_c20_custom_width(u32 clock, bool dp) } static void intel_c20_pll_program(struct intel_display *display, - const struct intel_crtc_state *crtc_state, - struct intel_encoder *encoder) + struct intel_encoder *encoder, + const struct intel_c20pll_state *pll_state, + bool is_dp, int port_clock) { - const struct intel_c20pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c20; - bool dp = false; u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder); - u32 clock = crtc_state->port_clock; bool cntx; int i; - if (intel_crtc_has_dp_encoder(crtc_state)) - dp = true; - /* 1. Read current context selection */ cntx = intel_cx0_read(encoder, INTEL_CX0_LANE0, PHY_C20_VDR_CUSTOM_SERDES_RATE) & BIT(0); @@ -2679,23 +2688,23 @@ static void intel_c20_pll_program(struct intel_display *display, /* 4. Program custom width to match the link protocol */ intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_WIDTH, PHY_C20_CUSTOM_WIDTH_MASK, - PHY_C20_CUSTOM_WIDTH(intel_get_c20_custom_width(clock, dp)), + PHY_C20_CUSTOM_WIDTH(intel_get_c20_custom_width(port_clock, is_dp)), MB_WRITE_COMMITTED); /* 5. For DP or 6. For HDMI */ - if (dp) { + if (is_dp) { intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE, BIT(6) | PHY_C20_CUSTOM_SERDES_MASK, - BIT(6) | PHY_C20_CUSTOM_SERDES(intel_c20_get_dp_rate(clock)), + BIT(6) | PHY_C20_CUSTOM_SERDES(intel_c20_get_dp_rate(port_clock)), MB_WRITE_COMMITTED); } else { intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE, BIT(7) | PHY_C20_CUSTOM_SERDES_MASK, - is_hdmi_frl(clock) ? BIT(7) : 0, + is_hdmi_frl(port_clock) ? BIT(7) : 0, MB_WRITE_COMMITTED); intel_cx0_write(encoder, INTEL_CX0_BOTH_LANES, PHY_C20_VDR_HDMI_RATE, - intel_c20_get_hdmi_rate(clock), + intel_c20_get_hdmi_rate(port_clock), MB_WRITE_COMMITTED); } @@ -2735,7 +2744,8 @@ static int intel_c10pll_calc_port_clock(struct intel_encoder *encoder, } static void intel_program_port_clock_ctl(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, + const struct intel_cx0pll_state *pll_state, + bool is_dp, int port_clock, bool lane_reversal) { struct intel_display *display = to_intel_display(encoder); @@ -2750,18 +2760,17 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder, val |= XELPDP_FORWARD_CLOCK_UNGATE; - if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && - is_hdmi_frl(crtc_state->port_clock)) + if (!is_dp && is_hdmi_frl(port_clock)) val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_DIV18CLK); else val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_MAXPCLK); /* TODO: HDMI FRL */ /* DP2.0 10G and 20G rates enable MPLLA*/ - if (crtc_state->port_clock == 1000000 || crtc_state->port_clock == 2000000) - val |= crtc_state->dpll_hw_state.cx0pll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0; + if (port_clock == 1000000 || port_clock == 2000000) + val |= pll_state->ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0; else - val |= crtc_state->dpll_hw_state.cx0pll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0; + val |= pll_state->ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0; intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE | @@ -2991,8 +3000,9 @@ static u32 intel_cx0_get_pclk_pll_ack(u8 lane_mask) return val; } -static void intel_cx0pll_enable(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) +static void __intel_cx0pll_enable(struct intel_encoder *encoder, + const struct intel_cx0pll_state *pll_state, + bool is_dp, int port_clock, int lane_count) { struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); @@ -3006,7 +3016,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder, * 1. Program PORT_CLOCK_CTL REGISTER to configure * clock muxes, gating and SSC */ - intel_program_port_clock_ctl(encoder, crtc_state, lane_reversal); + intel_program_port_clock_ctl(encoder, pll_state, is_dp, port_clock, lane_reversal); /* 2. Bring PHY out of reset. */ intel_cx0_phy_lane_reset(encoder, lane_reversal); @@ -3026,15 +3036,15 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder, /* 5. Program PHY internal PLL internal registers. */ if (intel_encoder_is_c10phy(encoder)) - intel_c10_pll_program(display, crtc_state, encoder); + intel_c10_pll_program(display, encoder, &pll_state->c10); else - intel_c20_pll_program(display, crtc_state, encoder); + intel_c20_pll_program(display, encoder, &pll_state->c20, is_dp, port_clock); /* * 6. Program the enabled and disabled owned PHY lane * transmitters over message bus */ - intel_cx0_program_phy_lane(encoder, crtc_state->lane_count, lane_reversal); + intel_cx0_program_phy_lane(encoder, lane_count, lane_reversal); /* * 7. Follow the Display Voltage Frequency Switching - Sequence @@ -3045,8 +3055,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder, * 8. Program DDI_CLK_VALFREQ to match intended DDI * clock frequency. */ - intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), - crtc_state->port_clock); + intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), port_clock); /* * 9. Set PORT_CLOCK_CTL register PCLK PLL Request @@ -3073,6 +3082,14 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder, intel_cx0_phy_transaction_end(encoder, wakeref); } +static void intel_cx0pll_enable(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + __intel_cx0pll_enable(encoder, &crtc_state->dpll_hw_state.cx0pll, + intel_crtc_has_dp_encoder(crtc_state), + crtc_state->port_clock, crtc_state->lane_count); +} + int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); From bf8531990380c83d29f6fa69bce147c2247ce719 Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Tue, 18 Feb 2025 12:00:19 +0200 Subject: [PATCH 280/284] drm/i915/display: Allow display PHYs to reset power state The dedicated display PHYs reset to a power state that blocks S0ix, increasing idle system power. After a system reset (cold boot, S3/4/5, warm reset) if a dedicated PHY is not being brought up shortly, use these steps to move the PHY to the lowest power state to save power. 1. Follow the PLL Enable Sequence, using any valid frequency such as DP 1.62 GHz. This brings lanes out of reset and enables the PLL to allow powerdown to be moved to the Disable state. 2. Follow PLL Disable Sequence. This moves powerdown to the Disable state and disables the PLL. v2: Rename WA function to more descriptive (Jani) For PTL, only port A needs this wa Add helpers to check presence of C10 phy and pll enabling (Imre) v3: Rename wa function (Imre) Check return value of C10 pll tables readout (Imre) Use PLL request to check pll enabling (Imre) v4: Move intel_cx0_pll_is_enabled() right after intel_cx0_pll_disable() (Imre) Add drm_WARN_ON() if C10 state cannot be calculated from the tables (Imre) v5: Add debug message on PLL enabling (Imre) Add check for intel_encoder_is_dig_port() (Imre) Signed-off-by: Mika Kahola Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250218100019.740556-3-mika.kahola@intel.com --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 61 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_cx0_phy.h | 1 + .../drm/i915/display/intel_display_reset.c | 2 + drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 3 + 4 files changed, 67 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 8d6fd3f1ac13a..22595766eac53 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -3294,6 +3294,16 @@ static void intel_cx0pll_disable(struct intel_encoder *encoder) intel_cx0_phy_transaction_end(encoder, wakeref); } +static bool intel_cx0_pll_is_enabled(struct intel_encoder *encoder) +{ + struct intel_display *display = to_intel_display(encoder); + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + u8 lane = dig_port->lane_reversal ? INTEL_CX0_LANE1 : INTEL_CX0_LANE0; + + return intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)) & + intel_cx0_get_pclk_pll_request(lane); +} + static void intel_mtl_tbt_pll_disable(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); @@ -3555,3 +3565,54 @@ void intel_cx0pll_state_verify(struct intel_atomic_state *state, else intel_c20pll_state_verify(new_crtc_state, crtc, encoder, &mpll_hw_state.c20); } + +/* + * WA 14022081154 + * The dedicated display PHYs reset to a power state that blocks S0ix, increasing idle + * system power. After a system reset (cold boot, S3/4/5, warm reset) if a dedicated + * PHY is not being brought up shortly, use these steps to move the PHY to the lowest + * power state to save power. For PTL the workaround is needed only for port A. Port B + * is not connected. + * + * 1. Follow the PLL Enable Sequence, using any valid frequency such as DP 1.62 GHz. + * This brings lanes out of reset and enables the PLL to allow powerdown to be moved + * to the Disable state. + * 2. Follow PLL Disable Sequence. This moves powerdown to the Disable state and disables the PLL. + */ +void intel_cx0_pll_power_save_wa(struct intel_display *display) +{ + struct intel_encoder *encoder; + + if (DISPLAY_VER(display) != 30) + return; + + for_each_intel_encoder(display->drm, encoder) { + struct intel_cx0pll_state pll_state = {}; + int port_clock = 162000; + + if (!intel_encoder_is_dig_port(encoder)) + continue; + + if (!intel_encoder_is_c10phy(encoder)) + continue; + + if (intel_cx0_pll_is_enabled(encoder)) + continue; + + if (intel_c10pll_calc_state_from_table(encoder, + mtl_c10_edp_tables, + true, port_clock, + &pll_state) < 0) { + drm_WARN_ON(display->drm, + "Unable to calc C10 state from the tables\n"); + continue; + } + + drm_dbg_kms(display->drm, + "[ENCODER:%d:%s] Applying power saving workaround on disabled PLL\n", + encoder->base.base.id, encoder->base.name); + + __intel_cx0pll_enable(encoder, &pll_state, true, port_clock, 4); + intel_cx0pll_disable(encoder); + } +} diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h index 573fa7d3e88fe..a8f811ca5e7bc 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h @@ -42,5 +42,6 @@ bool intel_cx0pll_compare_hw_state(const struct intel_cx0pll_state *a, void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder); +void intel_cx0_pll_power_save_wa(struct intel_display *display); #endif /* __INTEL_CX0_PHY_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index 093b386c95e83..a690968885bf6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -7,6 +7,7 @@ #include "i915_drv.h" #include "intel_clock_gating.h" +#include "intel_cx0_phy.h" #include "intel_display_driver.h" #include "intel_display_reset.h" #include "intel_display_types.h" @@ -116,6 +117,7 @@ void intel_display_reset_finish(struct drm_i915_private *i915) intel_pps_unlock_regs_wa(display); intel_display_driver_init_hw(display); intel_clock_gating_init(i915); + intel_cx0_pll_power_save_wa(display); intel_hpd_init(i915); ret = __intel_display_driver_resume(display, state, ctx); diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index eb3df25a308cb..c825a507b9051 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -27,6 +27,7 @@ #include "bxt_dpio_phy_regs.h" #include "i915_drv.h" #include "i915_reg.h" +#include "intel_cx0_phy.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_dkl_phy.h" @@ -4571,6 +4572,8 @@ void intel_dpll_sanitize_state(struct intel_display *display) struct intel_shared_dpll *pll; int i; + intel_cx0_pll_power_save_wa(display); + for_each_shared_dpll(display, pll, i) sanitize_dpll_state(display, pll); } From 89eb319aab83c76ffa5096d533bef3905e6e3051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 13 Feb 2025 13:16:28 +0200 Subject: [PATCH 281/284] drm/i915/psr: Fix drm_WARN_ON in intel_psr_disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently intel_psr_disable is dumping out warning if PSR is not supported. On monitor supporting only Panel Replay we are seeing this warning. Fix this by checking Panel Replay support as well. Signed-off-by: Jouni Högander Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20250213111628.2183753-1-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 427a7d1df1f99..4e938bad808cc 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2187,7 +2187,8 @@ void intel_psr_disable(struct intel_dp *intel_dp, if (!old_crtc_state->has_psr) return; - if (drm_WARN_ON(display->drm, !CAN_PSR(intel_dp))) + if (drm_WARN_ON(display->drm, !CAN_PSR(intel_dp) && + !CAN_PANEL_REPLAY(intel_dp))) return; mutex_lock(&intel_dp->psr.lock); From 8b4bbaf8ddc1f68f3ee96a706f65fdb1bcd9d355 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 18 Feb 2025 00:38:27 +0200 Subject: [PATCH 282/284] drm/i915/dp: Fix error handling during 128b/132b link training At the end of a 128b/132b link training sequence, the HW expects the transcoder training pattern to be set to TPS2 and from that to normal mode (disabling the training pattern). Transitioning from TPS1 directly to normal mode leaves the transcoder in a stuck state, resulting in page-flip timeouts later in the modeset sequence. Atm, in case of a failure during link training, the transcoder may be still set to output the TPS1 pattern. Later the transcoder is then set from TPS1 directly to normal mode in intel_dp_stop_link_train(), leading to modeset failures later as described above. Fix this by setting the training patter to TPS2, if the link training failed at any point. The clue in the specification about the above HW behavior is the explicit mention that TPS2 must be set after the link training sequence (and there isn't a similar requirement specified for the 8b/10b link training), see the Bspec links below. v2: Add bspec aspect/link to the commit log. (Jani) Bspec: 54128, 65448, 68849 Cc: stable@vger.kernel.org # v5.18+ Cc: Jani Nikula Signed-off-by: Imre Deak Acked-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250217223828.1166093-2-imre.deak@intel.com Signed-off-by: Rodrigo Vivi --- .../gpu/drm/i915/display/intel_dp_link_training.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 9cb22baafeebb..23799ed0876ba 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -1563,7 +1563,7 @@ intel_dp_128b132b_link_train(struct intel_dp *intel_dp, if (wait_for(intel_dp_128b132b_intra_hop(intel_dp, crtc_state) == 0, 500)) { lt_err(intel_dp, DP_PHY_DPRX, "128b/132b intra-hop not clear\n"); - return false; + goto out; } if (intel_dp_128b132b_lane_eq(intel_dp, crtc_state) && @@ -1575,6 +1575,19 @@ intel_dp_128b132b_link_train(struct intel_dp *intel_dp, passed ? "passed" : "failed", crtc_state->port_clock, crtc_state->lane_count); +out: + /* + * Ensure that the training pattern does get set to TPS2 even in case + * of a failure, as is the case at the end of a passing link training + * and what is expected by the transcoder. Leaving TPS1 set (and + * disabling the link train mode in DP_TP_CTL later from TPS1 directly) + * would result in a stuck transcoder HW state and flip-done timeouts + * later in the modeset sequence. + */ + if (!passed) + intel_dp_program_link_training_pattern(intel_dp, crtc_state, + DP_PHY_DPRX, DP_TRAINING_PATTERN_2); + return passed; } From 2ed653c7b843db0670136330480842d76cb65cd8 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 18 Feb 2025 00:38:28 +0200 Subject: [PATCH 283/284] drm/i915/dp: Fix disabling the transcoder function in 128b/132b mode During disabling the transcoder in DP 128b/132b mode (both in case of an MST master transcoder and in case of SST) the transcoder function must be first disabled without changing any other field in the register (in particular leaving the DDI port and mode select fields unchanged) and clearing the DDI port and mode select fields separately, later during the disabling sequences. Fix the sequence accordingly. Bspec: 54128, 65448, 68849 Cc: Jani Nikula Fixes: 79a6734cd56e ("drm/i915/ddi: disable trancoder port select for 128b/132b SST") Signed-off-by: Imre Deak Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250217223828.1166093-3-imre.deak@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_ddi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 0a9ea34f0215a..5fe6894307442 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -681,7 +681,6 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); u32 ctl; if (DISPLAY_VER(dev_priv) >= 11) @@ -701,8 +700,7 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK); if (DISPLAY_VER(dev_priv) >= 12) { - if (!intel_dp_mst_is_master_trans(crtc_state) || - (!is_mst && intel_dp_is_uhbr(crtc_state))) { + if (!intel_dp_mst_is_master_trans(crtc_state)) { ctl &= ~(TGL_TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK); } @@ -3134,7 +3132,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, intel_dp_set_power(intel_dp, DP_SET_POWER_D3); if (DISPLAY_VER(dev_priv) >= 12) { - if (is_mst) { + if (is_mst || intel_dp_is_uhbr(old_crtc_state)) { enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; intel_de_rmw(dev_priv, From 5b99dd12fe53c745b40191b9e7fe9a25653b4e7a Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 13 Feb 2025 13:55:42 +0530 Subject: [PATCH 284/284] drm/i915/hdcp: Create force_hdcp14 debug fs entry Testing HDCP 1.4 becomes tough since the only way our code comes to HDCP 1.4 pathway is if the monitor only supports HDCP 1.4 which becomes tough to find sometimes. Setting this debug_fs entry will force use to use the HDCP 1.4 path so that more robust HDCP 1.4 testing can take place. --v2 -Move the code to intel_hdcp.c [Jani] -Remove useless debug logging [Jani] -Remove Force_HDCP from the debug file [Jani] --v3 -Remove leftover debug loggings [Jani] Signed-off-by: Suraj Kandpal Reviewed-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250213082541.3772212-1-suraj.kandpal@intel.com --- .../drm/i915/display/intel_display_types.h | 2 + drivers/gpu/drm/i915/display/intel_hdcp.c | 76 ++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index a4e3f33f75eb3..4440521e3e9ee 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -496,6 +496,8 @@ struct intel_hdcp { enum transcoder cpu_transcoder; /* Only used for DP MST stream encryption */ enum transcoder stream_transcoder; + /* Used to force HDCP 1.4 bypassing HDCP 2.x */ + bool force_hdcp14; }; struct intel_connector { diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 5918519541141..7063e3f5c538d 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2472,13 +2472,16 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state, * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup * is capable of HDCP2.2, it is preferred to use HDCP2.2. */ - if (intel_hdcp2_get_capability(connector)) { + if (!hdcp->force_hdcp14 && intel_hdcp2_get_capability(connector)) { ret = _intel_hdcp2_enable(state, connector); if (!ret) check_link_interval = DRM_HDCP2_CHECK_PERIOD_MS; } + if (hdcp->force_hdcp14) + drm_dbg_kms(display->drm, "Forcing HDCP 1.4\n"); + /* * When HDCP2.2 fails and Content Type is not Type1, HDCP1.4 will * be attempted. @@ -2806,6 +2809,75 @@ static int intel_hdcp_sink_capability_show(struct seq_file *m, void *data) } DEFINE_SHOW_ATTRIBUTE(intel_hdcp_sink_capability); +static ssize_t intel_hdcp_force_14_write(struct file *file, + const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *m = file->private_data; + struct intel_connector *connector = m->private; + struct intel_hdcp *hdcp = &connector->hdcp; + bool force_hdcp14 = false; + int ret; + + if (len == 0) + return 0; + + ret = kstrtobool_from_user(ubuf, len, &force_hdcp14); + if (ret < 0) + return ret; + + hdcp->force_hdcp14 = force_hdcp14; + *offp += len; + + return len; +} + +static int intel_hdcp_force_14_show(struct seq_file *m, void *data) +{ + struct intel_connector *connector = m->private; + struct intel_display *display = to_intel_display(connector); + struct intel_encoder *encoder = intel_attached_encoder(connector); + struct intel_hdcp *hdcp = &connector->hdcp; + struct drm_crtc *crtc; + int ret; + + if (!encoder) + return -ENODEV; + + ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); + if (ret) + return ret; + + crtc = connector->base.state->crtc; + if (connector->base.status != connector_status_connected || !crtc) { + ret = -ENODEV; + goto out; + } + + seq_printf(m, "%s\n", + str_yes_no(hdcp->force_hdcp14)); +out: + drm_modeset_unlock(&display->drm->mode_config.connection_mutex); + + return ret; +} + +static int intel_hdcp_force_14_open(struct inode *inode, + struct file *file) +{ + return single_open(file, intel_hdcp_force_14_show, + inode->i_private); +} + +static const struct file_operations intel_hdcp_force_14_fops = { + .owner = THIS_MODULE, + .open = intel_hdcp_force_14_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = intel_hdcp_force_14_write +}; + void intel_hdcp_connector_debugfs_add(struct intel_connector *connector) { struct dentry *root = connector->base.debugfs_entry; @@ -2816,5 +2888,7 @@ void intel_hdcp_connector_debugfs_add(struct intel_connector *connector) connector_type == DRM_MODE_CONNECTOR_HDMIB) { debugfs_create_file("i915_hdcp_sink_capability", 0444, root, connector, &intel_hdcp_sink_capability_fops); + debugfs_create_file("i915_force_hdcp14", 0644, root, + connector, &intel_hdcp_force_14_fops); } }