From patchwork Tue Jul 22 16:36:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: ECC workaround From: Nemesa Garg X-Patchwork-Id: 665165 Message-Id: <20250722163647.3300595-1-nemesa.garg@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: Nemesa Garg Date: Tue, 22 Jul 2025 22:06:47 +0530 Signed-off-by: Nemesa Garg --- .../drm/i915/display/intel_display_types.h | 3 ++ drivers/gpu/drm/i915/display/skl_scaler.c | 37 +++++++++++++++++++ drivers/gpu/drm/i915/display/skl_scaler.h | 2 + 3 files changed, 42 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index ce45261c4a8f..5e2fffd0252d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1471,6 +1471,9 @@ struct intel_crtc { #endif bool vblank_psr_notify; + + struct delayed_work ecc_work; + int ecc_scaler_id; }; struct intel_plane_error { diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 4cc55f4e1f9f..2d0a4fc5f2cf 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -132,6 +132,18 @@ static void skl_scaler_max_dst_size(struct intel_crtc *crtc, } } +static void skl_scaler_ecc_unmask_work(struct work_struct *work) +{ + struct delayed_work *delayed_work = to_delayed_work(work); + struct intel_crtc *crtc = + container_of(delayed_work, struct intel_crtc, ecc_work); + + struct intel_display *display = to_intel_display(crtc); + + intel_de_write_fw(display, SKL_PS_ECC_STAT(crtc->pipe, crtc->ecc_scaler_id), 1); + intel_de_write(display, XELPD_DISPLAY_ERR_FATAL_MASK, 0); +} + enum drm_mode_status skl_scaler_mode_valid(struct intel_display *display, const struct drm_display_mode *mode, @@ -762,6 +774,8 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state) crtc_state->scaler_state.scaler_id < 0)) return; + skl_scaler_ecc_mask(crtc_state); + drm_rect_init(&src, 0, 0, drm_rect_width(&crtc_state->pipe_src) << 16, drm_rect_height(&crtc_state->pipe_src) << 16); @@ -773,6 +787,7 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state) uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false); id = scaler_state->scaler_id; + crtc->ecc_scaler_id = id; ps_ctrl = PS_SCALER_EN | PS_BINDING_PIPE | scaler_state->scalers[id].mode | skl_scaler_get_filter_select(crtc_state->hw.scaling_filter); @@ -792,6 +807,12 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state) PS_WIN_XPOS(x) | PS_WIN_YPOS(y)); intel_de_write_fw(display, SKL_PS_WIN_SZ(pipe, id), PS_WIN_XSIZE(width) | PS_WIN_YSIZE(height)); + + if (DISPLAY_VER(display) == 13) { + INIT_DELAYED_WORK(&crtc->ecc_work, skl_scaler_ecc_unmask_work); + schedule_delayed_work(&crtc->ecc_work, + usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 1)); + } } void @@ -938,3 +959,19 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state) else scaler_state->scaler_users &= ~(1 << SKL_CRTC_INDEX); } + +void skl_scaler_ecc_mask(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + + intel_de_write(display, XELPD_DISPLAY_ERR_FATAL_MASK, ~0); +} + +u32 intel_get_frame_time_us(const struct intel_crtc_state *crtc_state) +{ + if (!crtc_state->hw.active) + return 0; + + return DIV_ROUND_UP(1000 * 1000, + drm_mode_vrefresh(&crtc_state->hw.adjusted_mode)); +} diff --git a/drivers/gpu/drm/i915/display/skl_scaler.h b/drivers/gpu/drm/i915/display/skl_scaler.h index 692716dd7616..7b8fecf0dc70 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.h +++ b/drivers/gpu/drm/i915/display/skl_scaler.h @@ -44,4 +44,6 @@ skl_scaler_mode_valid(struct intel_display *display, enum intel_output_format output_format, int num_joined_pipes); +void skl_scaler_ecc_mask(const struct intel_crtc_state *crtc_state); +u32 intel_get_frame_time_us(const struct intel_crtc_state *crtc_state); #endif