diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/skl_watermark.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/skl_watermark.c | 312 |
1 files changed, 240 insertions, 72 deletions
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index d1670cc3eff2..1c7e6468f3e3 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -5,21 +5,23 @@ #include <drm/drm_blend.h> +#include "i915_drv.h" +#include "i915_fixed.h" +#include "i915_reg.h" +#include "i9xx_wm.h" #include "intel_atomic.h" #include "intel_atomic_plane.h" #include "intel_bw.h" +#include "intel_crtc.h" #include "intel_de.h" #include "intel_display.h" #include "intel_display_power.h" #include "intel_display_types.h" #include "intel_fb.h" -#include "skl_watermark.h" - -#include "i915_drv.h" -#include "i915_fixed.h" -#include "i915_reg.h" #include "intel_pcode.h" -#include "intel_pm.h" +#include "intel_wm.h" +#include "skl_watermark.h" +#include "skl_watermark_regs.h" static void skl_sagv_disable(struct drm_i915_private *i915); @@ -64,7 +66,7 @@ static bool skl_needs_memory_bw_wa(struct drm_i915_private *i915) static bool intel_has_sagv(struct drm_i915_private *i915) { - return DISPLAY_VER(i915) >= 9 && !IS_LP(i915) && + return HAS_SAGV(i915) && i915->display.sagv.status != I915_SAGV_NOT_CONTROLLED; } @@ -92,7 +94,7 @@ intel_sagv_block_time(struct drm_i915_private *i915) return val; } else if (DISPLAY_VER(i915) == 11) { return 10; - } else if (DISPLAY_VER(i915) == 9 && !IS_LP(i915)) { + } else if (HAS_SAGV(i915)) { return 30; } else { return 0; @@ -101,7 +103,7 @@ intel_sagv_block_time(struct drm_i915_private *i915) static void intel_sagv_init(struct drm_i915_private *i915) { - if (!intel_has_sagv(i915)) + if (!HAS_SAGV(i915)) i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED; /* @@ -359,7 +361,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) continue; /* Find the highest enabled wm level for this plane */ - for (level = ilk_wm_max_level(i915); + for (level = i915->display.wm.num_levels - 1; !wm->wm[level].enable; --level) { } @@ -410,6 +412,9 @@ static bool intel_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); + if (!i915->params.enable_sagv) + return false; + if (DISPLAY_VER(i915) >= 12) return tgl_crtc_can_enable_sagv(crtc_state); else @@ -704,16 +709,38 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, const struct skl_wm_level *result_prev, struct skl_wm_level *result /* out */); +static unsigned int skl_wm_latency(struct drm_i915_private *i915, int level, + const struct skl_wm_params *wp) +{ + unsigned int latency = i915->display.wm.skl_latency[level]; + + if (latency == 0) + return 0; + + /* + * WaIncreaseLatencyIPCEnabled: kbl,cfl + * Display WA #1141: kbl,cfl + */ + if ((IS_KABYLAKE(i915) || IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)) && + skl_watermark_ipc_enabled(i915)) + latency += 4; + + if (skl_needs_memory_bw_wa(i915) && wp && wp->x_tiled) + latency += 15; + + return latency; +} + static unsigned int skl_cursor_allocation(const struct intel_crtc_state *crtc_state, int num_active) { struct intel_plane *plane = to_intel_plane(crtc_state->uapi.crtc->cursor); struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); - int level, max_level = ilk_wm_max_level(i915); struct skl_wm_level wm = {}; int ret, min_ddb_alloc = 0; struct skl_wm_params wp; + int level; ret = skl_compute_wm_params(crtc_state, 256, drm_format_info(DRM_FORMAT_ARGB8888), @@ -722,8 +749,8 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state, crtc_state->pixel_rate, &wp, 0); drm_WARN_ON(&i915->drm, ret); - for (level = 0; level <= max_level; level++) { - unsigned int latency = i915->display.wm.skl_latency[level]; + for (level = 0; level < i915->display.wm.num_levels; level++) { + unsigned int latency = skl_wm_latency(i915, level, &wp); skl_compute_plane_wm(crtc_state, plane, level, latency, &wp, &wm, &wm); if (wm.min_ddb_alloc == U16_MAX) @@ -1407,16 +1434,22 @@ skl_check_nv12_wm_level(struct skl_wm_level *wm, struct skl_wm_level *uv_wm, } } -static bool icl_need_wm1_wa(struct drm_i915_private *i915, - enum plane_id plane_id) +static bool skl_need_wm_copy_wa(struct drm_i915_private *i915, int level, + const struct skl_plane_wm *wm) { /* * Wa_1408961008:icl, ehl * Wa_14012656716:tgl, adl - * Underruns with WM1+ disabled + * Wa_14017887344:icl + * Wa_14017868169:adl, tgl + * Due to some power saving optimizations, different subsystems + * like PSR, might still use even disabled wm level registers, + * for "reference", so lets keep at least the values sane. + * Considering amount of WA requiring us to do similar things, was + * decided to simply do it for all of the platforms, as those wm + * levels are disabled, this isn't going to do harm anyway. */ - return DISPLAY_VER(i915) == 11 || - (IS_DISPLAY_VER(i915, 12, 13) && plane_id == PLANE_CURSOR); + return level > 0 && !wm->wm[level].enable; } struct skl_plane_ddb_iter { @@ -1492,7 +1525,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, * Find the highest watermark level for which we can satisfy the block * requirement of active planes. */ - for (level = ilk_wm_max_level(i915); level >= 0; level--) { + for (level = i915->display.wm.num_levels - 1; level >= 0; level--) { blocks = 0; for_each_plane_id_on_crtc(crtc, plane_id) { const struct skl_plane_wm *wm = @@ -1568,7 +1601,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, * all levels as "enabled." Go back now and disable the ones * that aren't actually possible. */ - for (level++; level <= ilk_wm_max_level(i915); level++) { + for (level++; level < i915->display.wm.num_levels; level++) { for_each_plane_id_on_crtc(crtc, plane_id) { const struct skl_ddb_entry *ddb = &crtc_state->wm.skl.plane_ddb[plane_id]; @@ -1585,12 +1618,10 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, else skl_check_wm_level(&wm->wm[level], ddb); - if (icl_need_wm1_wa(i915, plane_id) && - level == 1 && !wm->wm[level].enable && - wm->wm[0].enable) { - wm->wm[level].blocks = wm->wm[0].blocks; - wm->wm[level].lines = wm->wm[0].lines; - wm->wm[level].ignore_lines = wm->wm[0].ignore_lines; + if (skl_need_wm_copy_wa(i915, level, wm)) { + wm->wm[level].blocks = wm->wm[level - 1].blocks; + wm->wm[level].lines = wm->wm[level - 1].lines; + wm->wm[level].ignore_lines = wm->wm[level - 1].ignore_lines; } } } @@ -1835,17 +1866,6 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, return; } - /* - * WaIncreaseLatencyIPCEnabled: kbl,cfl - * Display WA #1141: kbl,cfl - */ - if ((IS_KABYLAKE(i915) || IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)) && - skl_watermark_ipc_enabled(i915)) - latency += 4; - - if (skl_needs_memory_bw_wa(i915) && wp->x_tiled) - latency += 15; - method1 = skl_wm_method1(i915, wp->plane_pixel_rate, wp->cpp, latency, wp->dbuf_block_size); method2 = skl_wm_method2(wp->plane_pixel_rate, @@ -1967,12 +1987,12 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state, struct skl_wm_level *levels) { struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); - int level, max_level = ilk_wm_max_level(i915); struct skl_wm_level *result_prev = &levels[0]; + int level; - for (level = 0; level <= max_level; level++) { + for (level = 0; level < i915->display.wm.num_levels; level++) { struct skl_wm_level *result = &levels[level]; - unsigned int latency = i915->display.wm.skl_latency[level]; + unsigned int latency = skl_wm_latency(i915, level, wm_params); skl_compute_plane_wm(crtc_state, plane, level, latency, wm_params, result_prev, result); @@ -1992,7 +2012,8 @@ static void tgl_compute_sagv_wm(const struct intel_crtc_state *crtc_state, unsigned int latency = 0; if (i915->display.sagv.block_time_us) - latency = i915->display.sagv.block_time_us + i915->display.wm.skl_latency[0]; + latency = i915->display.sagv.block_time_us + + skl_wm_latency(i915, 0, wm_params); skl_compute_plane_wm(crtc_state, plane, 0, latency, wm_params, &levels[0], @@ -2184,6 +2205,117 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state, return 0; } +static bool +skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state, + int wm0_lines, int latency) +{ + const struct drm_display_mode *adjusted_mode = + &crtc_state->hw.adjusted_mode; + + /* FIXME missing scaler and DSC pre-fill time */ + return crtc_state->framestart_delay + + intel_usecs_to_scanlines(adjusted_mode, latency) + + wm0_lines > + adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vblank_start; +} + +static int skl_max_wm0_lines(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + enum plane_id plane_id; + int wm0_lines = 0; + + for_each_plane_id_on_crtc(crtc, plane_id) { + const struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; + + /* FIXME what about !skl_wm_has_lines() platforms? */ + wm0_lines = max_t(int, wm0_lines, wm->wm[0].lines); + } + + return wm0_lines; +} + +static int skl_max_wm_level_for_vblank(struct intel_crtc_state *crtc_state, + int wm0_lines) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + int level; + + for (level = i915->display.wm.num_levels - 1; level >= 0; level--) { + int latency; + + /* FIXME should we care about the latency w/a's? */ + latency = skl_wm_latency(i915, level, NULL); + if (latency == 0) + continue; + + /* FIXME is it correct to use 0 latency for wm0 here? */ + if (level == 0) + latency = 0; + + if (!skl_is_vblank_too_short(crtc_state, wm0_lines, latency)) + return level; + } + + return -EINVAL; +} + +static int skl_wm_check_vblank(struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + int wm0_lines, level; + + if (!crtc_state->hw.active) + return 0; + + wm0_lines = skl_max_wm0_lines(crtc_state); + + level = skl_max_wm_level_for_vblank(crtc_state, wm0_lines); + if (level < 0) + return level; + + /* + * PSR needs to toggle LATENCY_REPORTING_REMOVED_PIPE_* + * based on whether we're limited by the vblank duration. + */ + crtc_state->wm_level_disabled = level < i915->display.wm.num_levels - 1; + + for (level++; level < i915->display.wm.num_levels; level++) { + enum plane_id plane_id; + + for_each_plane_id_on_crtc(crtc, plane_id) { + struct skl_plane_wm *wm = + &crtc_state->wm.skl.optimal.planes[plane_id]; + + /* + * FIXME just clear enable or flag the entire + * thing as bad via min_ddb_alloc=U16_MAX? + */ + wm->wm[level].enable = false; + wm->uv_wm[level].enable = false; + } + } + + if (DISPLAY_VER(i915) >= 12 && + i915->display.sagv.block_time_us && + skl_is_vblank_too_short(crtc_state, wm0_lines, + i915->display.sagv.block_time_us)) { + enum plane_id plane_id; + + for_each_plane_id_on_crtc(crtc, plane_id) { + struct skl_plane_wm *wm = + &crtc_state->wm.skl.optimal.planes[plane_id]; + + wm->sagv.wm0.enable = false; + wm->sagv.trans_wm.enable = false; + } + } + + return 0; +} + static int skl_build_pipe_wm(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -2213,7 +2345,7 @@ static int skl_build_pipe_wm(struct intel_atomic_state *state, crtc_state->wm.skl.optimal = crtc_state->wm.skl.raw; - return 0; + return skl_wm_check_vblank(crtc_state); } static void skl_ddb_entry_write(struct drm_i915_private *i915, @@ -2248,7 +2380,6 @@ void skl_write_plane_wm(struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = to_i915(plane->base.dev); - int level, max_level = ilk_wm_max_level(i915); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal; @@ -2256,8 +2387,9 @@ void skl_write_plane_wm(struct intel_plane *plane, &crtc_state->wm.skl.plane_ddb[plane_id]; const struct skl_ddb_entry *ddb_y = &crtc_state->wm.skl.plane_ddb_y[plane_id]; + int level; - for (level = 0; level <= max_level; level++) + for (level = 0; level < i915->display.wm.num_levels; level++) skl_write_wm_level(i915, PLANE_WM(pipe, plane_id, level), skl_plane_wm_level(pipe_wm, plane_id, level)); @@ -2285,14 +2417,14 @@ void skl_write_cursor_wm(struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = to_i915(plane->base.dev); - int level, max_level = ilk_wm_max_level(i915); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal; const struct skl_ddb_entry *ddb = &crtc_state->wm.skl.plane_ddb[plane_id]; + int level; - for (level = 0; level <= max_level; level++) + for (level = 0; level < i915->display.wm.num_levels; level++) skl_write_wm_level(i915, CUR_WM(pipe, level), skl_plane_wm_level(pipe_wm, plane_id, level)); @@ -2324,9 +2456,9 @@ static bool skl_plane_wm_equals(struct drm_i915_private *i915, const struct skl_plane_wm *wm1, const struct skl_plane_wm *wm2) { - int level, max_level = ilk_wm_max_level(i915); + int level; - for (level = 0; level <= max_level; level++) { + for (level = 0; level < i915->display.wm.num_levels; level++) { /* * We don't check uv_wm as the hardware doesn't actually * use it. It only gets used for calculating the required @@ -2398,6 +2530,8 @@ skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state, return PTR_ERR(plane_state); new_crtc_state->update_planes |= BIT(plane_id); + new_crtc_state->async_flip_planes = 0; + new_crtc_state->do_async_flip = false; } return 0; @@ -2674,9 +2808,9 @@ static bool skl_plane_selected_wm_equals(struct intel_plane *plane, const struct skl_pipe_wm *new_pipe_wm) { struct drm_i915_private *i915 = to_i915(plane->base.dev); - int level, max_level = ilk_wm_max_level(i915); + int level; - for (level = 0; level <= max_level; level++) { + for (level = 0; level < i915->display.wm.num_levels; level++) { /* * We don't check uv_wm as the hardware doesn't actually * use it. It only gets used for calculating the required @@ -2755,6 +2889,8 @@ static int skl_wm_add_affected_planes(struct intel_atomic_state *state, return PTR_ERR(plane_state); new_crtc_state->update_planes |= BIT(plane_id); + new_crtc_state->async_flip_planes = 0; + new_crtc_state->do_async_flip = false; } return 0; @@ -2810,16 +2946,14 @@ static void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, { struct drm_i915_private *i915 = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - int level, max_level; enum plane_id plane_id; + int level; u32 val; - max_level = ilk_wm_max_level(i915); - for_each_plane_id_on_crtc(crtc, plane_id) { struct skl_plane_wm *wm = &out->planes[plane_id]; - for (level = 0; level <= max_level; level++) { + for (level = 0; level < i915->display.wm.num_levels; level++) { if (plane_id != PLANE_CURSOR) val = intel_de_read(i915, PLANE_WM(pipe, plane_id, level)); else @@ -2856,7 +2990,7 @@ static void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, } } -void skl_wm_get_hw_state(struct drm_i915_private *i915) +static void skl_wm_get_hw_state(struct drm_i915_private *i915) { struct intel_dbuf_state *dbuf_state = to_intel_dbuf_state(i915->display.dbuf.obj.state); @@ -2956,7 +3090,7 @@ static bool skl_dbuf_is_misconfigured(struct drm_i915_private *i915) return false; } -void skl_wm_sanitize(struct drm_i915_private *i915) +static void skl_wm_sanitize(struct drm_i915_private *i915) { struct intel_crtc *crtc; @@ -2992,6 +3126,12 @@ void skl_wm_sanitize(struct drm_i915_private *i915) } } +static void skl_wm_get_hw_state_and_sanitize(struct drm_i915_private *i915) +{ + skl_wm_get_hw_state(i915); + skl_wm_sanitize(i915); +} + void intel_wm_state_verify(struct intel_crtc *crtc, struct intel_crtc_state *new_crtc_state) { @@ -3002,9 +3142,9 @@ void intel_wm_state_verify(struct intel_crtc *crtc, struct skl_pipe_wm wm; } *hw; const struct skl_pipe_wm *sw_wm = &new_crtc_state->wm.skl.optimal; - int level, max_level = ilk_wm_max_level(i915); struct intel_plane *plane; u8 hw_enabled_slices; + int level; if (DISPLAY_VER(i915) < 9 || !new_crtc_state->hw.active) return; @@ -3031,7 +3171,7 @@ void intel_wm_state_verify(struct intel_crtc *crtc, const struct skl_wm_level *hw_wm_level, *sw_wm_level; /* Watermarks */ - for (level = 0; level <= max_level; level++) { + for (level = 0; level < i915->display.wm.num_levels; level++) { hw_wm_level = &hw->wm.planes[plane->id].wm[level]; sw_wm_level = skl_plane_wm_level(sw_wm, plane->id, level); @@ -3153,7 +3293,7 @@ void skl_watermark_ipc_init(struct drm_i915_private *i915) static void adjust_wm_latency(struct drm_i915_private *i915, - u16 wm[], int max_level, int read_latency) + u16 wm[], int num_levels, int read_latency) { bool wm_lv_0_adjust_needed = i915->dram_info.wm_lv_0_adjust_needed; int i, level; @@ -3163,12 +3303,12 @@ adjust_wm_latency(struct drm_i915_private *i915, * need to be disabled. We make sure to sanitize the values out * of the punit to satisfy this requirement. */ - for (level = 1; level <= max_level; level++) { + for (level = 1; level < num_levels; level++) { if (wm[level] == 0) { - for (i = level + 1; i <= max_level; i++) + for (i = level + 1; i < num_levels; i++) wm[i] = 0; - max_level = level - 1; + num_levels = level; break; } } @@ -3181,7 +3321,7 @@ adjust_wm_latency(struct drm_i915_private *i915, * from the punit when level 0 response data is 0us. */ if (wm[0] == 0) { - for (level = 0; level <= max_level; level++) + for (level = 0; level < num_levels; level++) wm[level] += read_latency; } @@ -3197,7 +3337,7 @@ adjust_wm_latency(struct drm_i915_private *i915, static void mtl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) { - int max_level = ilk_wm_max_level(i915); + int num_levels = i915->display.wm.num_levels; u32 val; val = intel_de_read(i915, MTL_LATENCY_LP0_LP1); @@ -3212,12 +3352,12 @@ static void mtl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) wm[4] = REG_FIELD_GET(MTL_LATENCY_LEVEL_EVEN_MASK, val); wm[5] = REG_FIELD_GET(MTL_LATENCY_LEVEL_ODD_MASK, val); - adjust_wm_latency(i915, wm, max_level, 6); + adjust_wm_latency(i915, wm, num_levels, 6); } static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) { - int max_level = ilk_wm_max_level(i915); + int num_levels = i915->display.wm.num_levels; int read_latency = DISPLAY_VER(i915) >= 12 ? 3 : 2; int mult = IS_DG2(i915) ? 2 : 1; u32 val; @@ -3249,11 +3389,16 @@ static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) wm[6] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_2_6_MASK, val) * mult; wm[7] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_3_7_MASK, val) * mult; - adjust_wm_latency(i915, wm, max_level, read_latency); + adjust_wm_latency(i915, wm, num_levels, read_latency); } static void skl_setup_wm_latency(struct drm_i915_private *i915) { + if (HAS_HW_SAGV_WM(i915)) + i915->display.wm.num_levels = 6; + else + i915->display.wm.num_levels = 8; + if (DISPLAY_VER(i915) >= 14) mtl_read_wm_latency(i915, i915->display.wm.skl_latency); else @@ -3264,6 +3409,7 @@ static void skl_setup_wm_latency(struct drm_i915_private *i915) static const struct intel_wm_funcs skl_wm_funcs = { .compute_global_watermarks = skl_compute_wm, + .get_hw_state = skl_wm_get_hw_state_and_sanitize, }; void skl_wm_init(struct drm_i915_private *i915) @@ -3541,13 +3687,35 @@ static const struct file_operations skl_watermark_ipc_status_fops = { .write = skl_watermark_ipc_status_write }; -void skl_watermark_ipc_debugfs_register(struct drm_i915_private *i915) +static int intel_sagv_status_show(struct seq_file *m, void *unused) +{ + struct drm_i915_private *i915 = m->private; + static const char * const sagv_status[] = { + [I915_SAGV_UNKNOWN] = "unknown", + [I915_SAGV_DISABLED] = "disabled", + [I915_SAGV_ENABLED] = "enabled", + [I915_SAGV_NOT_CONTROLLED] = "not controlled", + }; + + seq_printf(m, "SAGV available: %s\n", str_yes_no(intel_has_sagv(i915))); + seq_printf(m, "SAGV modparam: %s\n", str_enabled_disabled(i915->params.enable_sagv)); + seq_printf(m, "SAGV status: %s\n", sagv_status[i915->display.sagv.status]); + seq_printf(m, "SAGV block time: %d usec\n", i915->display.sagv.block_time_us); + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(intel_sagv_status); + +void skl_watermark_debugfs_register(struct drm_i915_private *i915) { struct drm_minor *minor = i915->drm.primary; - if (!HAS_IPC(i915)) - return; + if (HAS_IPC(i915)) + debugfs_create_file("i915_ipc_status", 0644, minor->debugfs_root, i915, + &skl_watermark_ipc_status_fops); - debugfs_create_file("i915_ipc_status", 0644, minor->debugfs_root, i915, - &skl_watermark_ipc_status_fops); + if (HAS_SAGV(i915)) + debugfs_create_file("i915_sagv_status", 0444, minor->debugfs_root, i915, + &intel_sagv_status_fops); } |