From c02343249c26032afd4774052dad434b4b4dfdc2 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Tue, 16 Nov 2021 09:48:14 -0800 Subject: drm/i915/dg2: s/DISP_STEPPING/DISPLAY_STEPPING/ Commit cd0fcf5af791 ("drm/i915: rename DISP_STEPPING->DISPLAY_STEP and GT_STEPPING->GT_STEP") renamed all platforms' display stepping tests, but the DG2 patches were still in-flight at that time and did not incorporate the new naming scheme. Rename DG2's macro now for consistency with other platforms. Cc: Jani Nikula Signed-off-by: Matt Roper Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20211116174818.2128062-2-matthew.d.roper@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4f58e1456505..7185e0dc13c7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1595,7 +1595,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, (IS_SUBPLATFORM(__i915, INTEL_DG2, INTEL_SUBPLATFORM_##variant) && \ IS_GT_STEP(__i915, since, until)) -#define IS_DG2_DISP_STEP(__i915, since, until) \ +#define IS_DG2_DISPLAY_STEP(__i915, since, until) \ (IS_DG2(__i915) && \ IS_DISPLAY_STEP(__i915, since, until)) -- cgit v1.2.3-59-g8ed1b From f83974a408592dee672f9a4904cdc2149c6e161b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Dec 2021 15:57:09 +0200 Subject: drm/i915: split out intel_pm_types.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is far from ideal, but it reduces the i915_drv.h dependency from intel_display_types.h. Maybe in the future we'll need a better split. Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/c6c60d9a8f6dcd1fa2f4b187000c5bb6843a1371.1638366969.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/i915_drv.h | 64 +----------------- drivers/gpu/drm/i915/intel_pm_types.h | 76 ++++++++++++++++++++++ 3 files changed, 78 insertions(+), 63 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_pm_types.h (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 5f077e8cea33..14b4c3bb6030 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -47,6 +47,7 @@ #include #include "i915_drv.h" +#include "intel_pm_types.h" struct drm_printer; struct __intel_global_objs_state; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7185e0dc13c7..d109f3051a48 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -89,6 +89,7 @@ #include "intel_device_info.h" #include "intel_memory_region.h" #include "intel_pch.h" +#include "intel_pm_types.h" #include "intel_runtime_pm.h" #include "intel_step.h" #include "intel_uncore.h" @@ -732,69 +733,6 @@ struct intel_vbt_data { struct sdvo_device_mapping sdvo_mappings[2]; }; -enum intel_ddb_partitioning { - INTEL_DDB_PART_1_2, - INTEL_DDB_PART_5_6, /* IVB+ */ -}; - -struct ilk_wm_values { - u32 wm_pipe[3]; - u32 wm_lp[3]; - u32 wm_lp_spr[3]; - bool enable_fbc_wm; - enum intel_ddb_partitioning partitioning; -}; - -struct g4x_pipe_wm { - u16 plane[I915_MAX_PLANES]; - u16 fbc; -}; - -struct g4x_sr_wm { - u16 plane; - u16 cursor; - u16 fbc; -}; - -struct vlv_wm_ddl_values { - u8 plane[I915_MAX_PLANES]; -}; - -struct vlv_wm_values { - struct g4x_pipe_wm pipe[3]; - struct g4x_sr_wm sr; - struct vlv_wm_ddl_values ddl[3]; - u8 level; - bool cxsr; -}; - -struct g4x_wm_values { - struct g4x_pipe_wm pipe[2]; - struct g4x_sr_wm sr; - struct g4x_sr_wm hpll; - bool cxsr; - bool hpll_en; - bool fbc_en; -}; - -struct skl_ddb_entry { - u16 start, end; /* in number of blocks, 'end' is exclusive */ -}; - -static inline u16 skl_ddb_entry_size(const struct skl_ddb_entry *entry) -{ - return entry->end - entry->start; -} - -static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1, - const struct skl_ddb_entry *e2) -{ - if (e1->start == e2->start && e1->end == e2->end) - return true; - - return false; -} - struct i915_frontbuffer_tracking { spinlock_t lock; diff --git a/drivers/gpu/drm/i915/intel_pm_types.h b/drivers/gpu/drm/i915/intel_pm_types.h new file mode 100644 index 000000000000..211632f58751 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_pm_types.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2021 Intel Corporation + */ + +#ifndef __INTEL_PM_TYPES_H__ +#define __INTEL_PM_TYPES_H__ + +#include + +#include "display/intel_display.h" + +enum intel_ddb_partitioning { + INTEL_DDB_PART_1_2, + INTEL_DDB_PART_5_6, /* IVB+ */ +}; + +struct ilk_wm_values { + u32 wm_pipe[3]; + u32 wm_lp[3]; + u32 wm_lp_spr[3]; + bool enable_fbc_wm; + enum intel_ddb_partitioning partitioning; +}; + +struct g4x_pipe_wm { + u16 plane[I915_MAX_PLANES]; + u16 fbc; +}; + +struct g4x_sr_wm { + u16 plane; + u16 cursor; + u16 fbc; +}; + +struct vlv_wm_ddl_values { + u8 plane[I915_MAX_PLANES]; +}; + +struct vlv_wm_values { + struct g4x_pipe_wm pipe[3]; + struct g4x_sr_wm sr; + struct vlv_wm_ddl_values ddl[3]; + u8 level; + bool cxsr; +}; + +struct g4x_wm_values { + struct g4x_pipe_wm pipe[2]; + struct g4x_sr_wm sr; + struct g4x_sr_wm hpll; + bool cxsr; + bool hpll_en; + bool fbc_en; +}; + +struct skl_ddb_entry { + u16 start, end; /* in number of blocks, 'end' is exclusive */ +}; + +static inline u16 skl_ddb_entry_size(const struct skl_ddb_entry *entry) +{ + return entry->end - entry->start; +} + +static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1, + const struct skl_ddb_entry *e2) +{ + if (e1->start == e2->start && e1->end == e2->end) + return true; + + return false; +} + +#endif /* __INTEL_PM_TYPES_H__ */ -- cgit v1.2.3-59-g8ed1b From 5734c1774d8f32ea814c2904feae29b4582dd219 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Dec 2021 15:57:10 +0200 Subject: drm/i915: move enum hpd_pin to intel_display.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not the ideal location, but a better alternative than i915_drv.h. The goal is to break the intel_display_types.h to i915_drv.h dependency. Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/9f882eff78cdc6b28c18e73f5e53f57e413240dc.1638366969.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.h | 24 ++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 24 ------------------------ 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 38c15ec30ee7..8d8725b45d99 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -346,6 +346,30 @@ enum phy_fia { FIA3, }; +enum hpd_pin { + HPD_NONE = 0, + HPD_TV = HPD_NONE, /* TV is known to be unreliable */ + HPD_CRT, + HPD_SDVO_B, + HPD_SDVO_C, + HPD_PORT_A, + HPD_PORT_B, + HPD_PORT_C, + HPD_PORT_D, + HPD_PORT_E, + HPD_PORT_TC1, + HPD_PORT_TC2, + HPD_PORT_TC3, + HPD_PORT_TC4, + HPD_PORT_TC5, + HPD_PORT_TC6, + + HPD_NUM_PINS +}; + +#define for_each_hpd_pin(__pin) \ + for ((__pin) = (HPD_NONE + 1); (__pin) < HPD_NUM_PINS; (__pin)++) + #define for_each_pipe(__dev_priv, __p) \ for ((__p) = 0; (__p) < I915_MAX_PIPES; (__p)++) \ for_each_if(INTEL_INFO(__dev_priv)->pipe_mask & BIT(__p)) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d109f3051a48..b52e41ada106 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -117,30 +117,6 @@ struct drm_i915_gem_object; -enum hpd_pin { - HPD_NONE = 0, - HPD_TV = HPD_NONE, /* TV is known to be unreliable */ - HPD_CRT, - HPD_SDVO_B, - HPD_SDVO_C, - HPD_PORT_A, - HPD_PORT_B, - HPD_PORT_C, - HPD_PORT_D, - HPD_PORT_E, - HPD_PORT_TC1, - HPD_PORT_TC2, - HPD_PORT_TC3, - HPD_PORT_TC4, - HPD_PORT_TC5, - HPD_PORT_TC6, - - HPD_NUM_PINS -}; - -#define for_each_hpd_pin(__pin) \ - for ((__pin) = (HPD_NONE + 1); (__pin) < HPD_NUM_PINS; (__pin)++) - /* Threshold == 5 for long IRQs, 50 for short */ #define HPD_STORM_DEFAULT_THRESHOLD 50 -- cgit v1.2.3-59-g8ed1b From 2e6c99f88679121eacc75196bdf6da8b0e513066 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 24 Nov 2021 13:36:35 +0200 Subject: drm/i915/fbc: Nuke lots of crap from intel_fbc_state_cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no need to store all this stuff in intel_fbc_state_cache. Just check it all against the plane/crtc states and store only what we need. Probably more should get nuked still, but this is a start. So what we'll do is: - each plane will check its own state and update its local no_fbc_reason - the per-plane no_fbc_reason (if any) then gets propagated to the cache->no_fbc_reason while doing the actual update - fbc->no_fbc_reason gets updated in the end with either the value from the cache or directly from frontbuffer tracking It's still a bit messy, but should hopefuly get cleaned up more in the future. At least now we can observe each plane's reasons for rejecting FBC now more consistently, and we don't have so mcuh redundant state store all over the place. v2: store no_fbc_reason per-plane instead of per-pipe Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211124113652.22090-4-ville.syrjala@linux.intel.com Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/display/intel_display.c | 5 +- drivers/gpu/drm/i915/display/intel_display_types.h | 4 +- drivers/gpu/drm/i915/display/intel_fbc.c | 341 ++++++++++----------- drivers/gpu/drm/i915/display/intel_fbc.h | 3 +- drivers/gpu/drm/i915/i915_drv.h | 20 +- 5 files changed, 166 insertions(+), 207 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 514e7a328676..30728b7433bd 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8047,7 +8047,6 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; - intel_fbc_choose_crtc(dev_priv, state); ret = intel_compute_global_watermarks(state); if (ret) goto fail; @@ -8079,6 +8078,10 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; + ret = intel_fbc_atomic_check(state); + if (ret) + goto fail; + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (new_crtc_state->uapi.async_flip) { diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 974af6c01cca..c9c6efadf8b4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -695,6 +695,8 @@ struct intel_plane_state { /* Clear Color Value */ u64 ccval; + + const char *no_fbc_reason; }; struct intel_initial_plane_config { @@ -1125,8 +1127,6 @@ struct intel_crtc_state { bool crc_enabled; - bool enable_fbc; - bool double_wide; int pbn; diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 083c0cab4847..8bde3681b96e 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -43,6 +43,7 @@ #include "i915_drv.h" #include "i915_trace.h" #include "i915_vgpu.h" +#include "intel_cdclk.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_fbc.h" @@ -58,20 +59,6 @@ struct intel_fbc_funcs { void (*set_false_color)(struct intel_fbc *fbc, bool enable); }; -/* - * For SKL+, the plane source size used by the hardware is based on the value we - * write to the PLANE_SIZE register. For BDW-, the hardware looks at the value - * we wrote to PIPESRC. - */ -static void intel_fbc_get_plane_source_size(const struct intel_fbc_state_cache *cache, - int *width, int *height) -{ - if (width) - *width = cache->plane.src_w; - if (height) - *height = cache->plane.src_h; -} - /* plane stride in pixels */ static unsigned int intel_fbc_plane_stride(const struct intel_plane_state *plane_state) { @@ -796,9 +783,13 @@ void intel_fbc_cleanup(struct drm_i915_private *i915) mutex_unlock(&fbc->lock); } -static bool stride_is_valid(struct drm_i915_private *i915, - u64 modifier, unsigned int stride) +static bool stride_is_valid(const struct intel_plane_state *plane_state) { + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + const struct drm_framebuffer *fb = plane_state->hw.fb; + unsigned int stride = intel_fbc_plane_stride(plane_state) * + fb->format->cpp[0]; + /* This should have been caught earlier. */ if (drm_WARN_ON_ONCE(&i915->drm, (stride & (64 - 1)) != 0)) return false; @@ -815,7 +806,7 @@ static bool stride_is_valid(struct drm_i915_private *i915, /* Display WA #1105: skl,bxt,kbl,cfl,glk */ if ((DISPLAY_VER(i915) == 9 || IS_GEMINILAKE(i915)) && - modifier == DRM_FORMAT_MOD_LINEAR && stride & 511) + fb->modifier == DRM_FORMAT_MOD_LINEAR && stride & 511) return false; if (stride > 16384) @@ -824,10 +815,12 @@ static bool stride_is_valid(struct drm_i915_private *i915, return true; } -static bool pixel_format_is_valid(struct drm_i915_private *i915, - u32 pixel_format) +static bool pixel_format_is_valid(const struct intel_plane_state *plane_state) { - switch (pixel_format) { + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + const struct drm_framebuffer *fb = plane_state->hw.fb; + + switch (fb->format->format) { case DRM_FORMAT_XRGB8888: case DRM_FORMAT_XBGR8888: return true; @@ -845,10 +838,13 @@ static bool pixel_format_is_valid(struct drm_i915_private *i915, } } -static bool rotation_is_valid(struct drm_i915_private *i915, - u32 pixel_format, unsigned int rotation) +static bool rotation_is_valid(const struct intel_plane_state *plane_state) { - if (DISPLAY_VER(i915) >= 9 && pixel_format == DRM_FORMAT_RGB565 && + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + const struct drm_framebuffer *fb = plane_state->hw.fb; + unsigned int rotation = plane_state->hw.rotation; + + if (DISPLAY_VER(i915) >= 9 && fb->format->format == DRM_FORMAT_RGB565 && drm_rotation_90_or_270(rotation)) return false; else if (DISPLAY_VER(i915) <= 4 && !IS_G4X(i915) && @@ -864,10 +860,9 @@ static bool rotation_is_valid(struct drm_i915_private *i915, * the X and Y offset registers. That's why we include the src x/y offsets * instead of just looking at the plane size. */ -static bool intel_fbc_hw_tracking_covers_screen(struct intel_fbc *fbc, - struct intel_crtc *crtc) +static bool intel_fbc_hw_tracking_covers_screen(const struct intel_plane_state *plane_state) { - struct drm_i915_private *i915 = fbc->i915; + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); unsigned int effective_w, effective_h, max_w, max_h; if (DISPLAY_VER(i915) >= 10) { @@ -884,18 +879,20 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_fbc *fbc, max_h = 1536; } - intel_fbc_get_plane_source_size(&fbc->state_cache, &effective_w, - &effective_h); - effective_w += fbc->state_cache.plane.adjusted_x; - effective_h += fbc->state_cache.plane.adjusted_y; + effective_w = plane_state->view.color_plane[0].x + + (drm_rect_width(&plane_state->uapi.src) >> 16); + effective_h = plane_state->view.color_plane[0].y + + (drm_rect_height(&plane_state->uapi.src) >> 16); return effective_w <= max_w && effective_h <= max_h; } -static bool tiling_is_valid(struct drm_i915_private *i915, - u64 modifier) +static bool tiling_is_valid(const struct intel_plane_state *plane_state) { - switch (modifier) { + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + const struct drm_framebuffer *fb = plane_state->hw.fb; + + switch (fb->modifier) { case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_Y_TILED: case I915_FORMAT_MOD_Yf_TILED: @@ -916,15 +913,10 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, struct intel_fbc_state_cache *cache = &fbc->state_cache; struct drm_framebuffer *fb = plane_state->hw.fb; - cache->plane.visible = plane_state->uapi.visible; - if (!cache->plane.visible) + cache->no_fbc_reason = plane_state->no_fbc_reason; + if (cache->no_fbc_reason) return; - cache->crtc.mode_flags = crtc_state->hw.adjusted_mode.flags; - if (IS_HASWELL(i915) || IS_BROADWELL(i915)) - cache->crtc.hsw_bdw_pixel_rate = crtc_state->pixel_rate; - - cache->plane.rotation = plane_state->hw.rotation; /* * Src coordinates are already rotated by 270 degrees for * the 90/270 degree plane rotation cases (to match the @@ -932,10 +924,6 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, */ cache->plane.src_w = drm_rect_width(&plane_state->uapi.src) >> 16; cache->plane.src_h = drm_rect_height(&plane_state->uapi.src) >> 16; - cache->plane.adjusted_x = plane_state->view.color_plane[0].x; - cache->plane.adjusted_y = plane_state->view.color_plane[0].y; - - cache->plane.pixel_blend_mode = plane_state->hw.pixel_blend_mode; cache->fb.format = fb->format; cache->fb.modifier = fb->modifier; @@ -954,8 +942,6 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, cache->fence_id = plane_state->ggtt_vma->fence->id; else cache->fence_id = -1; - - cache->psr2_active = crtc_state->has_psr2; } static bool intel_fbc_cfb_size_changed(struct intel_fbc *fbc) @@ -1007,6 +993,110 @@ static bool intel_fbc_can_enable(struct intel_fbc *fbc) return true; } +static int intel_fbc_check_plane(struct intel_atomic_state *state, + struct intel_plane *plane) +{ + struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_plane_state *plane_state = + intel_atomic_get_new_plane_state(state, plane); + const struct drm_framebuffer *fb = plane_state->hw.fb; + struct intel_crtc *crtc = to_intel_crtc(plane_state->uapi.crtc); + const struct intel_crtc_state *crtc_state; + struct intel_fbc *fbc = plane->fbc; + + if (!fbc) + return 0; + + if (!plane_state->uapi.visible) { + plane_state->no_fbc_reason = "plane not visible"; + return 0; + } + + crtc_state = intel_atomic_get_new_crtc_state(state, crtc); + + if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { + plane_state->no_fbc_reason = "interlaced mode not supported"; + return 0; + } + + /* + * Display 12+ is not supporting FBC with PSR2. + * Recommendation is to keep this combination disabled + * Bspec: 50422 HSD: 14010260002 + */ + if (DISPLAY_VER(i915) >= 12 && crtc_state->has_psr2) { + plane_state->no_fbc_reason = "PSR2 enabled"; + return false; + } + + if (!pixel_format_is_valid(plane_state)) { + plane_state->no_fbc_reason = "pixel format not supported"; + return 0; + } + + if (!tiling_is_valid(plane_state)) { + plane_state->no_fbc_reason = "tiling not supported"; + return 0; + } + + if (!rotation_is_valid(plane_state)) { + plane_state->no_fbc_reason = "rotation not supported"; + return 0; + } + + if (!stride_is_valid(plane_state)) { + plane_state->no_fbc_reason = "stride not supported"; + return 0; + } + + if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && + fb->format->has_alpha) { + plane_state->no_fbc_reason = "per-pixel alpha not supported"; + return false; + } + + if (!intel_fbc_hw_tracking_covers_screen(plane_state)) { + plane_state->no_fbc_reason = "plane size too big"; + return 0; + } + + /* + * Work around a problem on GEN9+ HW, where enabling FBC on a plane + * having a Y offset that isn't divisible by 4 causes FIFO underrun + * and screen flicker. + */ + if (DISPLAY_VER(i915) >= 9 && + plane_state->view.color_plane[0].y & 3) { + plane_state->no_fbc_reason = "plane start Y offset misaligned"; + return false; + } + + /* Wa_22010751166: icl, ehl, tgl, dg1, rkl */ + if (DISPLAY_VER(i915) >= 11 && + (plane_state->view.color_plane[0].y + drm_rect_height(&plane_state->uapi.src)) & 3) { + plane_state->no_fbc_reason = "plane end Y offset misaligned"; + return false; + } + + /* WaFbcExceedCdClockThreshold:hsw,bdw */ + if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { + const struct intel_cdclk_state *cdclk_state; + + cdclk_state = intel_atomic_get_cdclk_state(state); + if (IS_ERR(cdclk_state)) + return PTR_ERR(cdclk_state); + + if (crtc_state->pixel_rate >= cdclk_state->logical.cdclk * 95 / 100) { + plane_state->no_fbc_reason = "pixel rate too high"; + return 0; + } + } + + plane_state->no_fbc_reason = NULL; + + return 0; +} + static bool intel_fbc_can_activate(struct intel_crtc *crtc) { struct drm_i915_private *i915 = to_i915(crtc->base.dev); @@ -1016,8 +1106,8 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) if (!intel_fbc_can_enable(fbc)) return false; - if (!cache->plane.visible) { - fbc->no_fbc_reason = "primary plane not visible"; + if (cache->no_fbc_reason) { + fbc->no_fbc_reason = cache->no_fbc_reason; return false; } @@ -1029,16 +1119,6 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return false; } - if (cache->crtc.mode_flags & DRM_MODE_FLAG_INTERLACE) { - fbc->no_fbc_reason = "incompatible mode"; - return false; - } - - if (!intel_fbc_hw_tracking_covers_screen(fbc, crtc)) { - fbc->no_fbc_reason = "mode too large for compression"; - return false; - } - /* The use of a CPU fence is one of two ways to detect writes by the * CPU to the scanout and trigger updates to the FBC. * @@ -1061,42 +1141,8 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return false; } - if (!pixel_format_is_valid(i915, cache->fb.format->format)) { - fbc->no_fbc_reason = "pixel format is invalid"; - return false; - } - - if (!rotation_is_valid(i915, cache->fb.format->format, - cache->plane.rotation)) { - fbc->no_fbc_reason = "rotation unsupported"; - return false; - } - - if (!tiling_is_valid(i915, cache->fb.modifier)) { - fbc->no_fbc_reason = "tiling unsupported"; - return false; - } - - if (!stride_is_valid(i915, cache->fb.modifier, - cache->fb.stride * cache->fb.format->cpp[0])) { - fbc->no_fbc_reason = "framebuffer stride not supported"; - return false; - } - - if (cache->plane.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && - cache->fb.format->has_alpha) { - fbc->no_fbc_reason = "per-pixel alpha blending is incompatible with FBC"; - return false; - } - - /* WaFbcExceedCdClockThreshold:hsw,bdw */ - if ((IS_HASWELL(i915) || IS_BROADWELL(i915)) && - cache->crtc.hsw_bdw_pixel_rate >= i915->cdclk.hw.cdclk * 95 / 100) { - fbc->no_fbc_reason = "pixel rate is too big"; - return false; - } - - /* It is possible for the required CFB size change without a + /* + * It is possible for the required CFB size change without a * crtc->disable + crtc->enable since it is possible to change the * stride without triggering a full modeset. Since we try to * over-allocate the CFB, there's a chance we may keep FBC enabled even @@ -1105,40 +1151,13 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) * for a frame, free the stolen node, then try to reenable FBC in case * we didn't get any invalidate/deactivate calls, but this would require * a lot of tracking just for a specific case. If we conclude it's an - * important case, we can implement it later. */ + * important case, we can implement it later. + */ if (intel_fbc_cfb_size_changed(fbc)) { fbc->no_fbc_reason = "CFB requirements changed"; return false; } - /* - * Work around a problem on GEN9+ HW, where enabling FBC on a plane - * having a Y offset that isn't divisible by 4 causes FIFO underrun - * and screen flicker. - */ - if (DISPLAY_VER(i915) >= 9 && - (fbc->state_cache.plane.adjusted_y & 3)) { - fbc->no_fbc_reason = "plane Y offset is misaligned"; - return false; - } - - /* Wa_22010751166: icl, ehl, tgl, dg1, rkl */ - if (DISPLAY_VER(i915) >= 11 && - (cache->plane.src_h + cache->plane.adjusted_y) % 4) { - fbc->no_fbc_reason = "plane height + offset is non-modulo of 4"; - return false; - } - - /* - * Display 12+ is not supporting FBC with PSR2. - * Recommendation is to keep this combination disabled - * Bspec: 50422 HSD: 14010260002 - */ - if (fbc->state_cache.psr2_active && DISPLAY_VER(i915) >= 12) { - fbc->no_fbc_reason = "not supported with PSR2"; - return false; - } - return true; } @@ -1157,8 +1176,6 @@ static void intel_fbc_get_reg_params(struct intel_fbc *fbc, params->fence_y_offset = cache->fence_y_offset; params->interval = cache->interval; - - params->crtc.pipe = crtc->pipe; params->crtc.i9xx_plane = to_intel_plane(crtc->base.primary)->i9xx_plane; params->fb.format = cache->fb.format; @@ -1168,8 +1185,6 @@ static void intel_fbc_get_reg_params(struct intel_fbc *fbc, params->cfb_stride = intel_fbc_cfb_stride(fbc, cache); params->cfb_size = intel_fbc_cfb_size(fbc, cache); params->override_cfb_stride = intel_fbc_override_cfb_stride(fbc, cache); - - params->plane_visible = cache->plane.visible; } static bool intel_fbc_can_flip_nuke(const struct intel_crtc_state *crtc_state) @@ -1183,9 +1198,6 @@ static bool intel_fbc_can_flip_nuke(const struct intel_crtc_state *crtc_state) if (drm_atomic_crtc_needs_modeset(&crtc_state->uapi)) return false; - if (!params->plane_visible) - return false; - if (!intel_fbc_can_activate(crtc)) return false; @@ -1381,63 +1393,21 @@ out: mutex_unlock(&fbc->lock); } -/** - * intel_fbc_choose_crtc - select a CRTC to enable FBC on - * @i915: i915 device instance - * @state: the atomic state structure - * - * This function looks at the proposed state for CRTCs and planes, then chooses - * which pipe is going to have FBC by setting intel_crtc_state->enable_fbc to - * true. - * - * Later, intel_fbc_enable is going to look for state->enable_fbc and then maybe - * enable FBC for the chosen CRTC. If it does, it will set i915->fbc.crtc. - */ -void intel_fbc_choose_crtc(struct drm_i915_private *i915, - struct intel_atomic_state *state) +int intel_fbc_atomic_check(struct intel_atomic_state *state) { - struct intel_fbc *fbc = &i915->fbc; - struct intel_plane *plane; struct intel_plane_state *plane_state; - bool crtc_chosen = false; + struct intel_plane *plane; int i; - mutex_lock(&fbc->lock); - - /* Does this atomic commit involve the CRTC currently tied to FBC? */ - if (fbc->crtc && - !intel_atomic_get_new_crtc_state(state, fbc->crtc)) - goto out; - - if (!intel_fbc_can_enable(fbc)) - goto out; - - /* Simply choose the first CRTC that is compatible and has a visible - * plane. We could go for fancier schemes such as checking the plane - * size, but this would just affect the few platforms that don't tie FBC - * to pipe or plane A. */ for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - struct intel_crtc_state *crtc_state; - struct intel_crtc *crtc = to_intel_crtc(plane_state->hw.crtc); + int ret; - if (plane->fbc != fbc) - continue; - - if (!plane_state->uapi.visible) - continue; - - crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - - crtc_state->enable_fbc = true; - crtc_chosen = true; - break; + ret = intel_fbc_check_plane(state, plane); + if (ret) + return ret; } - if (!crtc_chosen) - fbc->no_fbc_reason = "no suitable CRTC for FBC"; - -out: - mutex_unlock(&fbc->lock); + return 0; } /** @@ -1487,12 +1457,10 @@ static void intel_fbc_enable(struct intel_atomic_state *state, intel_fbc_update_state_cache(crtc, crtc_state, plane_state); - /* FIXME crtc_state->enable_fbc lies :( */ - if (!cache->plane.visible) + if (cache->no_fbc_reason) goto out; if (intel_fbc_alloc_cfb(fbc, intel_fbc_cfb_size(fbc, cache), min_limit)) { - cache->plane.visible = false; fbc->no_fbc_reason = "not enough stolen memory"; goto out; } @@ -1541,10 +1509,17 @@ void intel_fbc_disable(struct intel_crtc *crtc) void intel_fbc_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_plane *plane = to_intel_plane(crtc->base.primary); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); + const struct intel_plane_state *plane_state = + intel_atomic_get_new_plane_state(state, plane); + struct intel_fbc *fbc = plane->fbc; + + if (!fbc || !plane_state) + return; - if (crtc_state->update_pipe && !crtc_state->enable_fbc) + if (crtc_state->update_pipe && plane_state->no_fbc_reason) intel_fbc_disable(crtc); else intel_fbc_enable(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h index ce48a22c5e9e..74492e05a1c9 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.h +++ b/drivers/gpu/drm/i915/display/intel_fbc.h @@ -17,8 +17,7 @@ struct intel_crtc_state; struct intel_fbc; struct intel_plane_state; -void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, - struct intel_atomic_state *state); +int intel_fbc_atomic_check(struct intel_atomic_state *state); bool intel_fbc_is_active(struct intel_fbc *fbc); bool intel_fbc_is_compressing(struct intel_fbc *fbc); bool intel_fbc_pre_update(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b52e41ada106..c2516b8bc833 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -413,26 +413,11 @@ struct intel_fbc { * these problems. */ struct intel_fbc_state_cache { - struct { - unsigned int mode_flags; - u32 hsw_bdw_pixel_rate; - } crtc; + const char *no_fbc_reason; struct { - unsigned int rotation; int src_w; int src_h; - bool visible; - /* - * Display surface base address adjustement for - * pageflips. Note that on gen4+ this only adjusts up - * to a tile, offsets within a tile are handled in - * the hw itself (with the TILEOFF register). - */ - int adjusted_x; - int adjusted_y; - - u16 pixel_blend_mode; } plane; struct { @@ -444,7 +429,6 @@ struct intel_fbc { unsigned int fence_y_offset; u16 interval; s8 fence_id; - bool psr2_active; } state_cache; /* @@ -456,7 +440,6 @@ struct intel_fbc { */ struct intel_fbc_reg_params { struct { - enum pipe pipe; enum i9xx_plane_id i9xx_plane; } crtc; @@ -472,7 +455,6 @@ struct intel_fbc { u16 override_cfb_stride; u16 interval; s8 fence_id; - bool plane_visible; } params; const char *no_fbc_reason; -- cgit v1.2.3-59-g8ed1b From 873c995a40a5c2324a5d1e890604066b74914b3c Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 24 Nov 2021 13:36:37 +0200 Subject: drm/i915/fbc: Nuke more FBC state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There isn't a good reason why we'd have to cache all this plane state stuff in the FBC state. Instead we can just pre-calculate what FBC will really need. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211124113652.22090-6-ville.syrjala@linux.intel.com Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/display/intel_fbc.c | 132 +++++++++++++++---------------- drivers/gpu/drm/i915/i915_drv.h | 20 +---- 2 files changed, 67 insertions(+), 85 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 6368dddf977c..1e8b75cdfad8 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -73,25 +73,25 @@ static unsigned int intel_fbc_plane_stride(const struct intel_plane_state *plane } /* plane stride based cfb stride in bytes, assuming 1:1 compression limit */ -static unsigned int _intel_fbc_cfb_stride(const struct intel_fbc_state_cache *cache) +static unsigned int _intel_fbc_cfb_stride(const struct intel_plane_state *plane_state) { unsigned int cpp = 4; /* FBC always 4 bytes per pixel */ - return cache->fb.stride * cpp; + return intel_fbc_plane_stride(plane_state) * cpp; } /* minimum acceptable cfb stride in bytes, assuming 1:1 compression limit */ -static unsigned int skl_fbc_min_cfb_stride(struct intel_fbc *fbc, - const struct intel_fbc_state_cache *cache) +static unsigned int skl_fbc_min_cfb_stride(const struct intel_plane_state *plane_state) { - struct drm_i915_private *i915 = fbc->i915; + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); unsigned int limit = 4; /* 1:4 compression limit is the worst case */ unsigned int cpp = 4; /* FBC always 4 bytes per pixel */ + unsigned int width = drm_rect_width(&plane_state->uapi.src) >> 16; unsigned int height = 4; /* FBC segment is 4 lines */ unsigned int stride; /* minimum segment stride we can use */ - stride = cache->plane.src_w * cpp * height / limit; + stride = width * cpp * height / limit; /* * Wa_16011863758: icl+ @@ -111,11 +111,10 @@ static unsigned int skl_fbc_min_cfb_stride(struct intel_fbc *fbc, } /* properly aligned cfb stride in bytes, assuming 1:1 compression limit */ -static unsigned int intel_fbc_cfb_stride(struct intel_fbc *fbc, - const struct intel_fbc_state_cache *cache) +static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_state) { - struct drm_i915_private *i915 = fbc->i915; - unsigned int stride = _intel_fbc_cfb_stride(cache); + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + unsigned int stride = _intel_fbc_cfb_stride(plane_state); /* * At least some of the platforms require each 4 line segment to @@ -123,30 +122,30 @@ static unsigned int intel_fbc_cfb_stride(struct intel_fbc *fbc, * that regardless of the compression limit we choose later. */ if (DISPLAY_VER(i915) >= 9) - return max(ALIGN(stride, 512), skl_fbc_min_cfb_stride(fbc, cache)); + return max(ALIGN(stride, 512), skl_fbc_min_cfb_stride(plane_state)); else return stride; } -static unsigned int intel_fbc_cfb_size(struct intel_fbc *fbc, - const struct intel_fbc_state_cache *cache) +static unsigned int intel_fbc_cfb_size(const struct intel_plane_state *plane_state) { - struct drm_i915_private *i915 = fbc->i915; - int lines = cache->plane.src_h; + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + int lines = drm_rect_height(&plane_state->uapi.src) >> 16; if (DISPLAY_VER(i915) == 7) lines = min(lines, 2048); else if (DISPLAY_VER(i915) >= 8) lines = min(lines, 2560); - return lines * intel_fbc_cfb_stride(fbc, cache); + return lines * intel_fbc_cfb_stride(plane_state); } -static u16 intel_fbc_override_cfb_stride(struct intel_fbc *fbc, - const struct intel_fbc_state_cache *cache) +static u16 intel_fbc_override_cfb_stride(const struct intel_plane_state *plane_state) { - unsigned int stride = _intel_fbc_cfb_stride(cache); - unsigned int stride_aligned = intel_fbc_cfb_stride(fbc, cache); + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + unsigned int stride_aligned = intel_fbc_cfb_stride(plane_state); + unsigned int stride = _intel_fbc_cfb_stride(plane_state); + const struct drm_framebuffer *fb = plane_state->hw.fb; /* * Override stride in 64 byte units per 4 line segment. @@ -156,8 +155,7 @@ static u16 intel_fbc_override_cfb_stride(struct intel_fbc *fbc, * we always need to use the override there. */ if (stride != stride_aligned || - (DISPLAY_VER(fbc->i915) == 9 && - cache->fb.modifier == DRM_FORMAT_MOD_LINEAR)) + (DISPLAY_VER(i915) == 9 && fb->modifier == DRM_FORMAT_MOD_LINEAR)) return stride_aligned * 4 / 64; return 0; @@ -925,31 +923,22 @@ static bool tiling_is_valid(const struct intel_plane_state *plane_state) } } -static void intel_fbc_update_state_cache(struct intel_crtc *crtc, - const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state) +static void intel_fbc_update_state_cache(struct intel_atomic_state *state, + struct intel_crtc *crtc, + struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - struct intel_fbc *fbc = &i915->fbc; + struct drm_i915_private *i915 = to_i915(state->base.dev); + const struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + const struct intel_plane_state *plane_state = + intel_atomic_get_new_plane_state(state, plane); + struct intel_fbc *fbc = plane->fbc; struct intel_fbc_state_cache *cache = &fbc->state_cache; - struct drm_framebuffer *fb = plane_state->hw.fb; cache->no_fbc_reason = plane_state->no_fbc_reason; if (cache->no_fbc_reason) return; - /* - * Src coordinates are already rotated by 270 degrees for - * the 90/270 degree plane rotation cases (to match the - * GTT mapping), hence no need to account for rotation here. - */ - cache->plane.src_w = drm_rect_width(&plane_state->uapi.src) >> 16; - cache->plane.src_h = drm_rect_height(&plane_state->uapi.src) >> 16; - - cache->fb.format = fb->format; - cache->fb.modifier = fb->modifier; - cache->fb.stride = intel_fbc_plane_stride(plane_state); - /* FBC1 compression interval: arbitrary choice of 1 second */ cache->interval = drm_mode_vrefresh(&crtc_state->hw.adjusted_mode); @@ -963,12 +952,15 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, cache->fence_id = plane_state->ggtt_vma->fence->id; else cache->fence_id = -1; + + cache->cfb_stride = intel_fbc_cfb_stride(plane_state); + cache->cfb_size = intel_fbc_cfb_size(plane_state); + cache->override_cfb_stride = intel_fbc_override_cfb_stride(plane_state); } static bool intel_fbc_cfb_size_changed(struct intel_fbc *fbc) { - return intel_fbc_cfb_size(fbc, &fbc->state_cache) > - fbc->compressed_fb.size * fbc->limit; + return fbc->state_cache.cfb_size > fbc->compressed_fb.size * fbc->limit; } static bool intel_fbc_can_enable(struct intel_fbc *fbc) @@ -1178,45 +1170,53 @@ static void intel_fbc_get_reg_params(struct intel_fbc *fbc, params->interval = cache->interval; params->crtc.i9xx_plane = to_intel_plane(crtc->base.primary)->i9xx_plane; - params->fb.format = cache->fb.format; - params->fb.modifier = cache->fb.modifier; - params->fb.stride = cache->fb.stride; - - params->cfb_stride = intel_fbc_cfb_stride(fbc, cache); - params->cfb_size = intel_fbc_cfb_size(fbc, cache); - params->override_cfb_stride = intel_fbc_override_cfb_stride(fbc, cache); + params->cfb_stride = cache->cfb_stride; + params->cfb_size = cache->cfb_size; + params->override_cfb_stride = cache->override_cfb_stride; } -static bool intel_fbc_can_flip_nuke(const struct intel_crtc_state *crtc_state) +static bool intel_fbc_can_flip_nuke(struct intel_atomic_state *state, + struct intel_crtc *crtc, + struct intel_plane *plane) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - struct intel_fbc *fbc = &i915->fbc; + struct intel_fbc *fbc = plane->fbc; + const struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + const struct intel_plane_state *old_plane_state = + intel_atomic_get_old_plane_state(state, plane); + const struct intel_plane_state *new_plane_state = + intel_atomic_get_new_plane_state(state, plane); + const struct drm_framebuffer *old_fb = old_plane_state->hw.fb; + const struct drm_framebuffer *new_fb = new_plane_state->hw.fb; const struct intel_fbc_state_cache *cache = &fbc->state_cache; const struct intel_fbc_reg_params *params = &fbc->params; - if (drm_atomic_crtc_needs_modeset(&crtc_state->uapi)) + if (drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi)) return false; if (!intel_fbc_can_activate(crtc)) return false; - if (params->fb.format != cache->fb.format) + if (!old_fb || !new_fb) + return false; + + if (old_fb->format->format != new_fb->format->format) return false; - if (params->fb.modifier != cache->fb.modifier) + if (old_fb->modifier != new_fb->modifier) return false; - if (params->fb.stride != cache->fb.stride) + if (intel_fbc_plane_stride(old_plane_state) != + intel_fbc_plane_stride(new_plane_state)) return false; - if (params->cfb_stride != intel_fbc_cfb_stride(fbc, cache)) + if (params->cfb_stride != cache->cfb_stride) return false; - if (params->cfb_size != intel_fbc_cfb_size(fbc, cache)) + if (params->cfb_size != cache->cfb_size) return false; - if (params->override_cfb_stride != intel_fbc_override_cfb_stride(fbc, cache)) + if (params->override_cfb_stride != cache->override_cfb_stride) return false; return true; @@ -1226,8 +1226,6 @@ bool intel_fbc_pre_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_plane *plane = to_intel_plane(crtc->base.primary); - const struct intel_crtc_state *crtc_state = - intel_atomic_get_new_crtc_state(state, crtc); const struct intel_plane_state *plane_state = intel_atomic_get_new_plane_state(state, plane); struct drm_i915_private *i915 = to_i915(crtc->base.dev); @@ -1243,10 +1241,10 @@ bool intel_fbc_pre_update(struct intel_atomic_state *state, if (fbc->crtc != crtc) goto unlock; - intel_fbc_update_state_cache(crtc, crtc_state, plane_state); + intel_fbc_update_state_cache(state, crtc, plane); fbc->flip_pending = true; - if (!intel_fbc_can_flip_nuke(crtc_state)) { + if (!intel_fbc_can_flip_nuke(state, crtc, plane)) { intel_fbc_deactivate(fbc, reason); /* @@ -1425,8 +1423,6 @@ static void intel_fbc_enable(struct intel_atomic_state *state, { struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_plane *plane = to_intel_plane(crtc->base.primary); - const struct intel_crtc_state *crtc_state = - intel_atomic_get_new_crtc_state(state, crtc); const struct intel_plane_state *plane_state = intel_atomic_get_new_plane_state(state, plane); struct intel_fbc *fbc = plane->fbc; @@ -1455,12 +1451,12 @@ static void intel_fbc_enable(struct intel_atomic_state *state, drm_WARN_ON(&i915->drm, fbc->active); - intel_fbc_update_state_cache(crtc, crtc_state, plane_state); + intel_fbc_update_state_cache(state, crtc, plane); if (cache->no_fbc_reason) goto out; - if (intel_fbc_alloc_cfb(fbc, intel_fbc_cfb_size(fbc, cache), min_limit)) { + if (intel_fbc_alloc_cfb(fbc, intel_fbc_cfb_size(plane_state), min_limit)) { fbc->no_fbc_reason = "not enough stolen memory"; goto out; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c2516b8bc833..a20a90da62ba 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -415,18 +415,10 @@ struct intel_fbc { struct intel_fbc_state_cache { const char *no_fbc_reason; - struct { - int src_w; - int src_h; - } plane; - - struct { - const struct drm_format_info *format; - unsigned int stride; - u64 modifier; - } fb; - + unsigned int cfb_stride; + unsigned int cfb_size; unsigned int fence_y_offset; + u16 override_cfb_stride; u16 interval; s8 fence_id; } state_cache; @@ -443,12 +435,6 @@ struct intel_fbc { enum i9xx_plane_id i9xx_plane; } crtc; - struct { - const struct drm_format_info *format; - unsigned int stride; - u64 modifier; - } fb; - unsigned int cfb_stride; unsigned int cfb_size; unsigned int fence_y_offset; -- cgit v1.2.3-59-g8ed1b From e1521cbd27aa100a86b54094cfa4387a9bcc2f63 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 24 Nov 2021 13:36:38 +0200 Subject: drm/i915/fbc: Reuse the same struct for the cache and params MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FBC state cache and params are now nearly identical. Just use the same structure for both. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211124113652.22090-7-ville.syrjala@linux.intel.com Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/display/intel_fbc.c | 62 ++++++++++++++------------------ drivers/gpu/drm/i915/i915_drv.h | 36 +++++++------------ 2 files changed, 40 insertions(+), 58 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 1e8b75cdfad8..8625825cbee8 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -163,7 +163,7 @@ static u16 intel_fbc_override_cfb_stride(const struct intel_plane_state *plane_s static u32 i8xx_fbc_ctl(struct intel_fbc *fbc) { - const struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *params = &fbc->params; struct drm_i915_private *i915 = fbc->i915; unsigned int cfb_stride; u32 fbc_ctl; @@ -191,11 +191,11 @@ static u32 i8xx_fbc_ctl(struct intel_fbc *fbc) static u32 i965_fbc_ctl2(struct intel_fbc *fbc) { - const struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *params = &fbc->params; u32 fbc_ctl2; fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | - FBC_CTL_PLANE(params->crtc.i9xx_plane); + FBC_CTL_PLANE(params->i9xx_plane); if (params->fence_id >= 0) fbc_ctl2 |= FBC_CTL_CPU_FENCE_EN; @@ -226,7 +226,7 @@ static void i8xx_fbc_deactivate(struct intel_fbc *fbc) static void i8xx_fbc_activate(struct intel_fbc *fbc) { - const struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *params = &fbc->params; struct drm_i915_private *i915 = fbc->i915; int i; @@ -258,8 +258,8 @@ static bool i8xx_fbc_is_compressing(struct intel_fbc *fbc) static void i8xx_fbc_nuke(struct intel_fbc *fbc) { - struct intel_fbc_reg_params *params = &fbc->params; - enum i9xx_plane_id i9xx_plane = params->crtc.i9xx_plane; + struct intel_fbc_state *params = &fbc->params; + enum i9xx_plane_id i9xx_plane = params->i9xx_plane; struct drm_i915_private *dev_priv = fbc->i915; spin_lock_irq(&dev_priv->uncore.lock); @@ -294,8 +294,8 @@ static const struct intel_fbc_funcs i8xx_fbc_funcs = { static void i965_fbc_nuke(struct intel_fbc *fbc) { - struct intel_fbc_reg_params *params = &fbc->params; - enum i9xx_plane_id i9xx_plane = params->crtc.i9xx_plane; + struct intel_fbc_state *params = &fbc->params; + enum i9xx_plane_id i9xx_plane = params->i9xx_plane; struct drm_i915_private *dev_priv = fbc->i915; spin_lock_irq(&dev_priv->uncore.lock); @@ -330,12 +330,12 @@ static u32 g4x_dpfc_ctl_limit(struct intel_fbc *fbc) static u32 g4x_dpfc_ctl(struct intel_fbc *fbc) { - const struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *params = &fbc->params; struct drm_i915_private *i915 = fbc->i915; u32 dpfc_ctl; dpfc_ctl = g4x_dpfc_ctl_limit(fbc) | - DPFC_CTL_PLANE_G4X(params->crtc.i9xx_plane); + DPFC_CTL_PLANE_G4X(params->i9xx_plane); if (IS_G4X(i915)) dpfc_ctl |= DPFC_CTL_SR_EN; @@ -352,7 +352,7 @@ static u32 g4x_dpfc_ctl(struct intel_fbc *fbc) static void g4x_fbc_activate(struct intel_fbc *fbc) { - const struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *params = &fbc->params; struct drm_i915_private *i915 = fbc->i915; intel_de_write(i915, DPFC_FENCE_YOFF, @@ -403,7 +403,7 @@ static const struct intel_fbc_funcs g4x_fbc_funcs = { static void ilk_fbc_activate(struct intel_fbc *fbc) { - struct intel_fbc_reg_params *params = &fbc->params; + struct intel_fbc_state *params = &fbc->params; struct drm_i915_private *i915 = fbc->i915; intel_de_write(i915, ILK_DPFC_FENCE_YOFF, @@ -454,7 +454,7 @@ static const struct intel_fbc_funcs ilk_fbc_funcs = { static void snb_fbc_program_fence(struct intel_fbc *fbc) { - const struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *params = &fbc->params; struct drm_i915_private *i915 = fbc->i915; u32 ctl = 0; @@ -491,7 +491,7 @@ static const struct intel_fbc_funcs snb_fbc_funcs = { static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc) { - const struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *params = &fbc->params; struct drm_i915_private *i915 = fbc->i915; u32 val = 0; @@ -504,7 +504,7 @@ static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc) static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc) { - const struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *params = &fbc->params; struct drm_i915_private *i915 = fbc->i915; u32 val = 0; @@ -520,14 +520,14 @@ static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc) static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) { - const struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *params = &fbc->params; struct drm_i915_private *i915 = fbc->i915; u32 dpfc_ctl; dpfc_ctl = g4x_dpfc_ctl_limit(fbc); if (IS_IVYBRIDGE(i915)) - dpfc_ctl |= DPFC_CTL_PLANE_IVB(params->crtc.i9xx_plane); + dpfc_ctl |= DPFC_CTL_PLANE_IVB(params->i9xx_plane); if (params->fence_id >= 0) dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB; @@ -933,12 +933,14 @@ static void intel_fbc_update_state_cache(struct intel_atomic_state *state, const struct intel_plane_state *plane_state = intel_atomic_get_new_plane_state(state, plane); struct intel_fbc *fbc = plane->fbc; - struct intel_fbc_state_cache *cache = &fbc->state_cache; + struct intel_fbc_state *cache = &fbc->state_cache; cache->no_fbc_reason = plane_state->no_fbc_reason; if (cache->no_fbc_reason) return; + cache->i9xx_plane = plane->i9xx_plane; + /* FBC1 compression interval: arbitrary choice of 1 second */ cache->interval = drm_mode_vrefresh(&crtc_state->hw.adjusted_mode); @@ -1093,7 +1095,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) { struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_fbc *fbc = &i915->fbc; - struct intel_fbc_state_cache *cache = &fbc->state_cache; + struct intel_fbc_state *cache = &fbc->state_cache; if (!intel_fbc_can_enable(fbc)) return false; @@ -1156,23 +1158,13 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) static void intel_fbc_get_reg_params(struct intel_fbc *fbc, struct intel_crtc *crtc) { - const struct intel_fbc_state_cache *cache = &fbc->state_cache; - struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *cache = &fbc->state_cache; + struct intel_fbc_state *params = &fbc->params; /* Since all our fields are integer types, use memset here so the * comparison function can rely on memcmp because the padding will be * zero. */ - memset(params, 0, sizeof(*params)); - - params->fence_id = cache->fence_id; - params->fence_y_offset = cache->fence_y_offset; - - params->interval = cache->interval; - params->crtc.i9xx_plane = to_intel_plane(crtc->base.primary)->i9xx_plane; - - params->cfb_stride = cache->cfb_stride; - params->cfb_size = cache->cfb_size; - params->override_cfb_stride = cache->override_cfb_stride; + *params = *cache; } static bool intel_fbc_can_flip_nuke(struct intel_atomic_state *state, @@ -1188,8 +1180,8 @@ static bool intel_fbc_can_flip_nuke(struct intel_atomic_state *state, intel_atomic_get_new_plane_state(state, plane); const struct drm_framebuffer *old_fb = old_plane_state->hw.fb; const struct drm_framebuffer *new_fb = new_plane_state->hw.fb; - const struct intel_fbc_state_cache *cache = &fbc->state_cache; - const struct intel_fbc_reg_params *params = &fbc->params; + const struct intel_fbc_state *cache = &fbc->state_cache; + const struct intel_fbc_state *params = &fbc->params; if (drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi)) return false; @@ -1426,7 +1418,7 @@ static void intel_fbc_enable(struct intel_atomic_state *state, const struct intel_plane_state *plane_state = intel_atomic_get_new_plane_state(state, plane); struct intel_fbc *fbc = plane->fbc; - struct intel_fbc_state_cache *cache; + struct intel_fbc_state *cache; int min_limit; if (!fbc || !plane_state) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a20a90da62ba..20581312ea82 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -382,6 +382,17 @@ struct intel_fbc_funcs; #define I915_COLOR_UNEVICTABLE (-1) /* a non-vma sharing the address space */ +struct intel_fbc_state { + const char *no_fbc_reason; + enum i9xx_plane_id i9xx_plane; + unsigned int cfb_stride; + unsigned int cfb_size; + unsigned int fence_y_offset; + u16 override_cfb_stride; + u16 interval; + s8 fence_id; +}; + struct intel_fbc { struct drm_i915_private *i915; const struct intel_fbc_funcs *funcs; @@ -412,16 +423,7 @@ struct intel_fbc { * appropriate locking, so we cache information here in order to avoid * these problems. */ - struct intel_fbc_state_cache { - const char *no_fbc_reason; - - unsigned int cfb_stride; - unsigned int cfb_size; - unsigned int fence_y_offset; - u16 override_cfb_stride; - u16 interval; - s8 fence_id; - } state_cache; + struct intel_fbc_state state_cache; /* * This structure contains everything that's relevant to program the @@ -430,19 +432,7 @@ struct intel_fbc { * something different in the struct. The genx_fbc_activate functions * are supposed to read from it in order to program the registers. */ - struct intel_fbc_reg_params { - struct { - enum i9xx_plane_id i9xx_plane; - } crtc; - - unsigned int cfb_stride; - unsigned int cfb_size; - unsigned int fence_y_offset; - u16 override_cfb_stride; - u16 interval; - s8 fence_id; - } params; - + struct intel_fbc_state params; const char *no_fbc_reason; }; -- cgit v1.2.3-59-g8ed1b From 004f80f91a7831cd32970e1078bb00594d042089 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 24 Nov 2021 13:36:40 +0200 Subject: drm/i915/fbc: Track FBC usage per-plane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the future we may have multiple planes on the same pipe capable of using FBC. Prepare for that by tracking FBC usage per-plane rather than per-crtc. v2: s/intel_get_crtc_for_pipe/intel_crtc_for_pipe/ Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211124113652.22090-9-ville.syrjala@linux.intel.com Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/display/intel_fbc.c | 220 +++++++++++++++---------------- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_trace.h | 18 ++- 3 files changed, 121 insertions(+), 119 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index db390c29c665..cf7fc0de6081 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -583,7 +583,7 @@ static bool intel_fbc_hw_is_active(struct intel_fbc *fbc) static void intel_fbc_hw_activate(struct intel_fbc *fbc) { - trace_intel_fbc_activate(fbc->crtc); + trace_intel_fbc_activate(fbc->plane); fbc->active = true; fbc->activated = true; @@ -593,7 +593,7 @@ static void intel_fbc_hw_activate(struct intel_fbc *fbc) static void intel_fbc_hw_deactivate(struct intel_fbc *fbc) { - trace_intel_fbc_deactivate(fbc->crtc); + trace_intel_fbc_deactivate(fbc->plane); fbc->active = false; @@ -607,7 +607,7 @@ bool intel_fbc_is_compressing(struct intel_fbc *fbc) static void intel_fbc_nuke(struct intel_fbc *fbc) { - trace_intel_fbc_nuke(fbc->crtc); + trace_intel_fbc_nuke(fbc->plane); fbc->funcs->nuke(fbc); } @@ -1154,8 +1154,7 @@ static bool intel_fbc_can_activate(struct intel_fbc *fbc) return true; } -static void intel_fbc_get_reg_params(struct intel_fbc *fbc, - struct intel_crtc *crtc) +static void intel_fbc_get_reg_params(struct intel_fbc *fbc) { const struct intel_fbc_state *cache = &fbc->state_cache; struct intel_fbc_state *params = &fbc->params; @@ -1213,30 +1212,19 @@ static bool intel_fbc_can_flip_nuke(struct intel_atomic_state *state, return true; } -bool intel_fbc_pre_update(struct intel_atomic_state *state, - struct intel_crtc *crtc) +static bool __intel_fbc_pre_update(struct intel_atomic_state *state, + struct intel_crtc *crtc, + struct intel_plane *plane) { - struct intel_plane *plane = to_intel_plane(crtc->base.primary); - const struct intel_plane_state *plane_state = - intel_atomic_get_new_plane_state(state, plane); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_fbc *fbc = plane->fbc; - const char *reason = "update pending"; bool need_vblank_wait = false; - if (!fbc || !plane_state) - return need_vblank_wait; - - mutex_lock(&fbc->lock); - - if (fbc->crtc != crtc) - goto unlock; - intel_fbc_update_state_cache(state, crtc, plane); fbc->flip_pending = true; if (!intel_fbc_can_flip_nuke(state, crtc, plane)) { - intel_fbc_deactivate(fbc, reason); + intel_fbc_deactivate(fbc, "update pending"); /* * Display WA #1198: glk+ @@ -1256,8 +1244,31 @@ bool intel_fbc_pre_update(struct intel_atomic_state *state, need_vblank_wait = true; fbc->activated = false; } -unlock: - mutex_unlock(&fbc->lock); + + return need_vblank_wait; +} + +bool intel_fbc_pre_update(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + const struct intel_plane_state *plane_state; + bool need_vblank_wait = false; + struct intel_plane *plane; + int i; + + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { + struct intel_fbc *fbc = plane->fbc; + + if (!fbc || plane->pipe != crtc->pipe) + continue; + + mutex_lock(&fbc->lock); + + if (fbc->plane == plane) + need_vblank_wait |= __intel_fbc_pre_update(state, crtc, plane); + + mutex_unlock(&fbc->lock); + } return need_vblank_wait; } @@ -1265,18 +1276,18 @@ unlock: static void __intel_fbc_disable(struct intel_fbc *fbc) { struct drm_i915_private *i915 = fbc->i915; - struct intel_crtc *crtc = fbc->crtc; + struct intel_plane *plane = fbc->plane; drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock)); - drm_WARN_ON(&i915->drm, !fbc->crtc); + drm_WARN_ON(&i915->drm, !fbc->plane); drm_WARN_ON(&i915->drm, fbc->active); - drm_dbg_kms(&i915->drm, "Disabling FBC on pipe %c\n", - pipe_name(crtc->pipe)); + drm_dbg_kms(&i915->drm, "Disabling FBC on [PLANE:%d:%s]\n", + plane->base.base.id, plane->base.name); __intel_fbc_cleanup_cfb(fbc); - fbc->crtc = NULL; + fbc->plane = NULL; } static void __intel_fbc_post_update(struct intel_fbc *fbc) @@ -1304,27 +1315,32 @@ static void __intel_fbc_post_update(struct intel_fbc *fbc) void intel_fbc_post_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct intel_plane *plane = to_intel_plane(crtc->base.primary); - const struct intel_plane_state *plane_state = - intel_atomic_get_new_plane_state(state, plane); - struct intel_fbc *fbc = plane->fbc; + const struct intel_plane_state *plane_state; + struct intel_plane *plane; + int i; - if (!fbc || !plane_state) - return; + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { + struct intel_fbc *fbc = plane->fbc; - mutex_lock(&fbc->lock); - if (fbc->crtc == crtc) { - fbc->flip_pending = false; - intel_fbc_get_reg_params(fbc, crtc); - __intel_fbc_post_update(fbc); + if (!fbc || plane->pipe != crtc->pipe) + continue; + + mutex_lock(&fbc->lock); + + if (fbc->plane == plane) { + fbc->flip_pending = false; + intel_fbc_get_reg_params(fbc); + __intel_fbc_post_update(fbc); + } + + mutex_unlock(&fbc->lock); } - mutex_unlock(&fbc->lock); } static unsigned int intel_fbc_get_frontbuffer_bit(struct intel_fbc *fbc) { - if (fbc->crtc) - return to_intel_plane(fbc->crtc->base.primary)->frontbuffer_bit; + if (fbc->plane) + return fbc->plane->frontbuffer_bit; else return fbc->possible_framebuffer_bits; } @@ -1345,7 +1361,7 @@ void intel_fbc_invalidate(struct drm_i915_private *i915, fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits; - if (fbc->crtc && fbc->busy_bits) + if (fbc->plane && fbc->busy_bits) intel_fbc_deactivate(fbc, "frontbuffer write"); mutex_unlock(&fbc->lock); @@ -1366,7 +1382,7 @@ void intel_fbc_flush(struct drm_i915_private *i915, if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE) goto out; - if (!fbc->busy_bits && fbc->crtc && + if (!fbc->busy_bits && fbc->plane && (frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) { if (fbc->active) intel_fbc_nuke(fbc); @@ -1395,43 +1411,24 @@ int intel_fbc_atomic_check(struct intel_atomic_state *state) return 0; } -/** - * intel_fbc_enable: tries to enable FBC on the CRTC - * @crtc: the CRTC - * @state: corresponding &drm_crtc_state for @crtc - * - * This function checks if the given CRTC was chosen for FBC, then enables it if - * possible. Notice that it doesn't activate FBC. It is valid to call - * intel_fbc_enable multiple times for the same pipe without an - * intel_fbc_disable in the middle, as long as it is deactivated. - */ -static void intel_fbc_enable(struct intel_atomic_state *state, - struct intel_crtc *crtc) +static void __intel_fbc_enable(struct intel_atomic_state *state, + struct intel_crtc *crtc, + struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - struct intel_plane *plane = to_intel_plane(crtc->base.primary); + struct drm_i915_private *i915 = to_i915(state->base.dev); const struct intel_plane_state *plane_state = intel_atomic_get_new_plane_state(state, plane); struct intel_fbc *fbc = plane->fbc; - struct intel_fbc_state *cache; - int min_limit; - - if (!fbc || !plane_state) - return; - - cache = &fbc->state_cache; - - min_limit = intel_fbc_min_limit(plane_state); - - mutex_lock(&fbc->lock); + struct intel_fbc_state *cache = &fbc->state_cache; + int min_limit = intel_fbc_min_limit(plane_state); - if (fbc->crtc) { - if (fbc->crtc != crtc) - goto out; + if (fbc->plane) { + if (fbc->plane != plane) + return; if (fbc->limit >= min_limit && !intel_fbc_cfb_size_changed(fbc)) - goto out; + return; __intel_fbc_disable(fbc); } @@ -1441,22 +1438,20 @@ static void intel_fbc_enable(struct intel_atomic_state *state, intel_fbc_update_state_cache(state, crtc, plane); if (cache->no_fbc_reason) - goto out; + return; if (intel_fbc_alloc_cfb(fbc, intel_fbc_cfb_size(plane_state), min_limit)) { fbc->no_fbc_reason = "not enough stolen memory"; - goto out; + return; } - drm_dbg_kms(&i915->drm, "Enabling FBC on pipe %c\n", - pipe_name(crtc->pipe)); + drm_dbg_kms(&i915->drm, "Enabling FBC on [PLANE:%d:%s]\n", + plane->base.base.id, plane->base.name); fbc->no_fbc_reason = "FBC enabled but not active yet\n"; - fbc->crtc = crtc; + fbc->plane = plane; intel_fbc_program_cfb(fbc); -out: - mutex_unlock(&fbc->lock); } /** @@ -1467,45 +1462,48 @@ out: */ void intel_fbc_disable(struct intel_crtc *crtc) { - struct intel_plane *plane = to_intel_plane(crtc->base.primary); - struct intel_fbc *fbc = plane->fbc; + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_plane *plane; - if (!fbc) - return; + for_each_intel_plane(&i915->drm, plane) { + struct intel_fbc *fbc = plane->fbc; - mutex_lock(&fbc->lock); - if (fbc->crtc == crtc) - __intel_fbc_disable(fbc); - mutex_unlock(&fbc->lock); + if (!fbc || plane->pipe != crtc->pipe) + continue; + + mutex_lock(&fbc->lock); + if (fbc->plane == plane) + __intel_fbc_disable(fbc); + mutex_unlock(&fbc->lock); + } } -/** - * intel_fbc_update: enable/disable FBC on the CRTC - * @state: atomic state - * @crtc: the CRTC - * - * This function checks if the given CRTC was chosen for FBC, then enables it if - * possible. Notice that it doesn't activate FBC. It is valid to call - * intel_fbc_update multiple times for the same pipe without an - * intel_fbc_disable in the middle. - */ void intel_fbc_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct intel_plane *plane = to_intel_plane(crtc->base.primary); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - const struct intel_plane_state *plane_state = - intel_atomic_get_new_plane_state(state, plane); - struct intel_fbc *fbc = plane->fbc; + const struct intel_plane_state *plane_state; + struct intel_plane *plane; + int i; - if (!fbc || !plane_state) - return; + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { + struct intel_fbc *fbc = plane->fbc; - if (crtc_state->update_pipe && plane_state->no_fbc_reason) - intel_fbc_disable(crtc); - else - intel_fbc_enable(state, crtc); + if (!fbc || plane->pipe != crtc->pipe) + continue; + + mutex_lock(&fbc->lock); + + if (crtc_state->update_pipe && plane_state->no_fbc_reason) { + if (fbc->plane == plane) + __intel_fbc_disable(fbc); + } else { + __intel_fbc_enable(state, crtc, plane); + } + + mutex_unlock(&fbc->lock); + } } /** @@ -1522,10 +1520,8 @@ void intel_fbc_global_disable(struct drm_i915_private *i915) return; mutex_lock(&fbc->lock); - if (fbc->crtc) { - drm_WARN_ON(&i915->drm, fbc->crtc->active); + if (fbc->plane) __intel_fbc_disable(fbc); - } mutex_unlock(&fbc->lock); } @@ -1538,7 +1534,7 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work) mutex_lock(&fbc->lock); /* Maybe we were scheduled twice. */ - if (fbc->underrun_detected || !fbc->crtc) + if (fbc->underrun_detected || !fbc->plane) goto out; drm_dbg_kms(&i915->drm, "Disabling FBC due to FIFO underrun.\n"); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 20581312ea82..493522ce9953 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -402,7 +402,7 @@ struct intel_fbc { struct mutex lock; unsigned int possible_framebuffer_bits; unsigned int busy_bits; - struct intel_crtc *crtc; + struct intel_plane *plane; struct drm_mm_node compressed_fb; struct drm_mm_node compressed_llb; diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 26b8d75029d4..185eaa49f74e 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -372,8 +372,8 @@ TRACE_EVENT(intel_plane_disable_arm, /* fbc */ TRACE_EVENT(intel_fbc_activate, - TP_PROTO(struct intel_crtc *crtc), - TP_ARGS(crtc), + TP_PROTO(struct intel_plane *plane), + TP_ARGS(plane), TP_STRUCT__entry( __field(enum pipe, pipe) @@ -382,6 +382,8 @@ TRACE_EVENT(intel_fbc_activate, ), TP_fast_assign( + struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev), + plane->pipe); __entry->pipe = crtc->pipe; __entry->frame = intel_crtc_get_vblank_counter(crtc); __entry->scanline = intel_get_crtc_scanline(crtc); @@ -392,8 +394,8 @@ TRACE_EVENT(intel_fbc_activate, ); TRACE_EVENT(intel_fbc_deactivate, - TP_PROTO(struct intel_crtc *crtc), - TP_ARGS(crtc), + TP_PROTO(struct intel_plane *plane), + TP_ARGS(plane), TP_STRUCT__entry( __field(enum pipe, pipe) @@ -402,6 +404,8 @@ TRACE_EVENT(intel_fbc_deactivate, ), TP_fast_assign( + struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev), + plane->pipe); __entry->pipe = crtc->pipe; __entry->frame = intel_crtc_get_vblank_counter(crtc); __entry->scanline = intel_get_crtc_scanline(crtc); @@ -412,8 +416,8 @@ TRACE_EVENT(intel_fbc_deactivate, ); TRACE_EVENT(intel_fbc_nuke, - TP_PROTO(struct intel_crtc *crtc), - TP_ARGS(crtc), + TP_PROTO(struct intel_plane *plane), + TP_ARGS(plane), TP_STRUCT__entry( __field(enum pipe, pipe) @@ -422,6 +426,8 @@ TRACE_EVENT(intel_fbc_nuke, ), TP_fast_assign( + struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev), + plane->pipe); __entry->pipe = crtc->pipe; __entry->frame = intel_crtc_get_vblank_counter(crtc); __entry->scanline = intel_get_crtc_scanline(crtc); -- cgit v1.2.3-59-g8ed1b From 606754fdcb20f781774a279d62bb0852fcb2b79d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 24 Nov 2021 13:36:45 +0200 Subject: drm/i915/fbc: Allocate intel_fbc dynamically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the future we may have more than one FBC instance on some platforms. So let's just allocate it dynamically. This also lets us fully hide the implementation from prying eyes. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211124113652.22090-14-ville.syrjala@linux.intel.com Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/display/i9xx_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_fbc.c | 148 +++++++++++++++------ drivers/gpu/drm/i915/display/skl_universal_plane.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 59 +------- 4 files changed, 113 insertions(+), 98 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 84f50c90728f..85950ff67609 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -125,7 +125,7 @@ static struct intel_fbc *i9xx_plane_fbc(struct drm_i915_private *dev_priv, enum i9xx_plane_id i9xx_plane) { if (i9xx_plane_has_fbc(dev_priv, i9xx_plane)) - return &dev_priv->fbc; + return dev_priv->fbc; else return NULL; } diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 9be8e7dcaab6..1daf4f7b5d80 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -59,6 +59,63 @@ struct intel_fbc_funcs { void (*set_false_color)(struct intel_fbc *fbc, bool enable); }; +struct intel_fbc_state { + const char *no_fbc_reason; + enum i9xx_plane_id i9xx_plane; + unsigned int cfb_stride; + unsigned int cfb_size; + unsigned int fence_y_offset; + u16 override_cfb_stride; + u16 interval; + s8 fence_id; +}; + +struct intel_fbc { + struct drm_i915_private *i915; + const struct intel_fbc_funcs *funcs; + + /* + * This is always the inner lock when overlapping with + * struct_mutex and it's the outer lock when overlapping + * with stolen_lock. + */ + struct mutex lock; + unsigned int possible_framebuffer_bits; + unsigned int busy_bits; + struct intel_plane *plane; + + struct drm_mm_node compressed_fb; + struct drm_mm_node compressed_llb; + + u8 limit; + + bool false_color; + + bool active; + bool activated; + bool flip_pending; + + bool underrun_detected; + struct work_struct underrun_work; + + /* + * Due to the atomic rules we can't access some structures without the + * appropriate locking, so we cache information here in order to avoid + * these problems. + */ + struct intel_fbc_state state_cache; + + /* + * This structure contains everything that's relevant to program the + * hardware registers. When we want to figure out if we need to disable + * and re-enable FBC for a new configuration we just check if there's + * something different in the struct. The genx_fbc_activate functions + * are supposed to read from it in order to program the registers. + */ + struct intel_fbc_state params; + const char *no_fbc_reason; +}; + /* plane stride in pixels */ static unsigned int intel_fbc_plane_stride(const struct intel_plane_state *plane_state) { @@ -762,14 +819,16 @@ static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc) void intel_fbc_cleanup(struct drm_i915_private *i915) { - struct intel_fbc *fbc = &i915->fbc; + struct intel_fbc *fbc = i915->fbc; - if (!HAS_FBC(i915)) + if (!fbc) return; mutex_lock(&fbc->lock); __intel_fbc_cleanup_cfb(fbc); mutex_unlock(&fbc->lock); + + kfree(fbc); } static bool stride_is_valid(const struct intel_plane_state *plane_state) @@ -1319,9 +1378,9 @@ void intel_fbc_invalidate(struct drm_i915_private *i915, unsigned int frontbuffer_bits, enum fb_op_origin origin) { - struct intel_fbc *fbc = &i915->fbc; + struct intel_fbc *fbc = i915->fbc; - if (!HAS_FBC(i915)) + if (!fbc) return; if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE) @@ -1340,9 +1399,9 @@ void intel_fbc_invalidate(struct drm_i915_private *i915, void intel_fbc_flush(struct drm_i915_private *i915, unsigned int frontbuffer_bits, enum fb_op_origin origin) { - struct intel_fbc *fbc = &i915->fbc; + struct intel_fbc *fbc = i915->fbc; - if (!HAS_FBC(i915)) + if (!fbc) return; mutex_lock(&fbc->lock); @@ -1484,9 +1543,9 @@ void intel_fbc_update(struct intel_atomic_state *state, */ void intel_fbc_global_disable(struct drm_i915_private *i915) { - struct intel_fbc *fbc = &i915->fbc; + struct intel_fbc *fbc = i915->fbc; - if (!HAS_FBC(i915)) + if (!fbc) return; mutex_lock(&fbc->lock); @@ -1497,9 +1556,8 @@ void intel_fbc_global_disable(struct drm_i915_private *i915) static void intel_fbc_underrun_work_fn(struct work_struct *work) { - struct drm_i915_private *i915 = - container_of(work, struct drm_i915_private, fbc.underrun_work); - struct intel_fbc *fbc = &i915->fbc; + struct intel_fbc *fbc = container_of(work, typeof(*fbc), underrun_work); + struct drm_i915_private *i915 = fbc->i915; mutex_lock(&fbc->lock); @@ -1524,9 +1582,9 @@ out: */ void intel_fbc_reset_underrun(struct drm_i915_private *i915) { - struct intel_fbc *fbc = &i915->fbc; + struct intel_fbc *fbc = i915->fbc; - if (!HAS_FBC(i915)) + if (!fbc) return; cancel_work_sync(&fbc->underrun_work); @@ -1559,9 +1617,9 @@ void intel_fbc_reset_underrun(struct drm_i915_private *i915) */ void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915) { - struct intel_fbc *fbc = &i915->fbc; + struct intel_fbc *fbc = i915->fbc; - if (!HAS_FBC(i915)) + if (!fbc) return; /* There's no guarantee that underrun_detected won't be set to true @@ -1621,6 +1679,34 @@ void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane) fbc->possible_framebuffer_bits |= plane->frontbuffer_bit; } +static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915) +{ + struct intel_fbc *fbc; + + fbc = kzalloc(sizeof(*fbc), GFP_KERNEL); + if (!fbc) + return NULL; + + fbc->i915 = i915; + INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn); + mutex_init(&fbc->lock); + + if (DISPLAY_VER(i915) >= 7) + fbc->funcs = &ivb_fbc_funcs; + else if (DISPLAY_VER(i915) == 6) + fbc->funcs = &snb_fbc_funcs; + else if (DISPLAY_VER(i915) == 5) + fbc->funcs = &ilk_fbc_funcs; + else if (IS_G4X(i915)) + fbc->funcs = &g4x_fbc_funcs; + else if (DISPLAY_VER(i915) == 4) + fbc->funcs = &i965_fbc_funcs; + else + fbc->funcs = &i8xx_fbc_funcs; + + return fbc; +} + /** * intel_fbc_init - Initialize FBC * @i915: the i915 device @@ -1629,12 +1715,7 @@ void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane) */ void intel_fbc_init(struct drm_i915_private *i915) { - struct intel_fbc *fbc = &i915->fbc; - - fbc->i915 = i915; - INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn); - mutex_init(&fbc->lock); - fbc->active = false; + struct intel_fbc *fbc; if (!drm_mm_initialized(&i915->mm.stolen)) mkwrite_device_info(i915)->display.has_fbc = false; @@ -1646,29 +1727,20 @@ void intel_fbc_init(struct drm_i915_private *i915) drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n", i915->params.enable_fbc); - if (!HAS_FBC(i915)) { - fbc->no_fbc_reason = "unsupported by this chipset"; + if (!HAS_FBC(i915)) return; - } - if (DISPLAY_VER(i915) >= 7) - fbc->funcs = &ivb_fbc_funcs; - else if (DISPLAY_VER(i915) == 6) - fbc->funcs = &snb_fbc_funcs; - else if (DISPLAY_VER(i915) == 5) - fbc->funcs = &ilk_fbc_funcs; - else if (IS_G4X(i915)) - fbc->funcs = &g4x_fbc_funcs; - else if (DISPLAY_VER(i915) == 4) - fbc->funcs = &i965_fbc_funcs; - else - fbc->funcs = &i8xx_fbc_funcs; + fbc = intel_fbc_create(i915); + if (!fbc) + return; /* We still don't have any sort of hardware state readout for FBC, so * deactivate it in case the BIOS activated it to make sure software * matches the hardware state. */ if (intel_fbc_hw_is_active(fbc)) intel_fbc_hw_deactivate(fbc); + + i915->fbc = fbc; } static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) @@ -1743,8 +1815,8 @@ static void intel_fbc_debugfs_add(struct intel_fbc *fbc) void intel_fbc_debugfs_register(struct drm_i915_private *i915) { - struct intel_fbc *fbc = &i915->fbc; + struct intel_fbc *fbc = i915->fbc; - if (HAS_FBC(i915)) + if (fbc) intel_fbc_debugfs_add(fbc); } diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 253d69a08614..699672d49a32 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1833,7 +1833,7 @@ static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv, enum pipe pipe, enum plane_id plane_id) { if (skl_plane_has_fbc(dev_priv, pipe, plane_id)) - return &dev_priv->fbc; + return dev_priv->fbc; else return NULL; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 493522ce9953..820e6e920d4b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -378,64 +378,8 @@ struct drm_i915_display_funcs { void (*commit_modeset_enables)(struct intel_atomic_state *state); }; -struct intel_fbc_funcs; - #define I915_COLOR_UNEVICTABLE (-1) /* a non-vma sharing the address space */ -struct intel_fbc_state { - const char *no_fbc_reason; - enum i9xx_plane_id i9xx_plane; - unsigned int cfb_stride; - unsigned int cfb_size; - unsigned int fence_y_offset; - u16 override_cfb_stride; - u16 interval; - s8 fence_id; -}; - -struct intel_fbc { - struct drm_i915_private *i915; - const struct intel_fbc_funcs *funcs; - - /* This is always the inner lock when overlapping with struct_mutex and - * it's the outer lock when overlapping with stolen_lock. */ - struct mutex lock; - unsigned int possible_framebuffer_bits; - unsigned int busy_bits; - struct intel_plane *plane; - - struct drm_mm_node compressed_fb; - struct drm_mm_node compressed_llb; - - u8 limit; - - bool false_color; - - bool active; - bool activated; - bool flip_pending; - - bool underrun_detected; - struct work_struct underrun_work; - - /* - * Due to the atomic rules we can't access some structures without the - * appropriate locking, so we cache information here in order to avoid - * these problems. - */ - struct intel_fbc_state state_cache; - - /* - * This structure contains everything that's relevant to program the - * hardware registers. When we want to figure out if we need to disable - * and re-enable FBC for a new configuration we just check if there's - * something different in the struct. The genx_fbc_activate functions - * are supposed to read from it in order to program the registers. - */ - struct intel_fbc_state params; - const char *no_fbc_reason; -}; - /* * HIGH_RR is the highest eDP panel refresh rate read from EDID * LOW_RR is the lowest eDP panel refresh rate found from EDID @@ -472,7 +416,6 @@ struct i915_drrs { #define QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK (1<<8) struct intel_fbdev; -struct intel_fbc_work; struct intel_gmbus { struct i2c_adapter adapter; @@ -808,7 +751,7 @@ struct drm_i915_private { u32 pipestat_irq_mask[I915_MAX_PIPES]; struct i915_hotplug hotplug; - struct intel_fbc fbc; + struct intel_fbc *fbc; struct i915_drrs drrs; struct intel_opregion opregion; struct intel_vbt_data vbt; -- cgit v1.2.3-59-g8ed1b From 52407c220c44c8dcc6aa8aa35ffc8a2db3c849a9 Mon Sep 17 00:00:00 2001 From: Anusha Srivatsa Date: Thu, 2 Dec 2021 22:35:43 -0800 Subject: drm/i915/rpl-s: Add PCI IDS for Raptor Lake S MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Raptor Lake S(RPL-S) is a version 12 Display, Media and Render. For all i915 purposes it is the same as Alder Lake S (ADL-S). Introduce RPL-S as a subplatform of ADL-S. This patch adds PCI ids for RPL-S. BSpec: 53655 Cc: x86@kernel.org Cc: dri-devel@lists.freedesktop.org Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: Joonas Lahtinen Cc: Tvrtko Ursulin Cc: Matt Roper Cc: Jani Nikula Signed-off-by: Anusha Srivatsa Reviewed-by: José Roberto de Souza Acked-by: Dave Hansen # arch/x86 Acked-by: Tvrtko Ursulin Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20211203063545.2254380-2-anusha.srivatsa@intel.com --- arch/x86/kernel/early-quirks.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_pci.c | 1 + drivers/gpu/drm/i915/intel_device_info.c | 7 +++++++ drivers/gpu/drm/i915/intel_device_info.h | 3 +++ include/drm/i915_pciids.h | 9 +++++++++ 6 files changed, 23 insertions(+) (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 391a4e2b8604..fd2d3ab38ebb 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -554,6 +554,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_RKL_IDS(&gen11_early_ops), INTEL_ADLS_IDS(&gen11_early_ops), INTEL_ADLP_IDS(&gen11_early_ops), + INTEL_RPLS_IDS(&gen11_early_ops), }; struct resource intel_graphics_stolen_res __ro_after_init = DEFINE_RES_MEM(0, 0); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 820e6e920d4b..c10e2c81baea 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1281,6 +1281,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, IS_SUBPLATFORM(dev_priv, INTEL_DG2, INTEL_SUBPLATFORM_G10) #define IS_DG2_G11(dev_priv) \ IS_SUBPLATFORM(dev_priv, INTEL_DG2, INTEL_SUBPLATFORM_G11) +#define IS_ADLS_RPLS(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_ALDERLAKE_S, INTEL_SUBPLATFORM_RPL_S) #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \ (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00) #define IS_BDW_ULT(dev_priv) \ diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 729db9589482..a98941b512e5 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -1133,6 +1133,7 @@ static const struct pci_device_id pciidlist[] = { INTEL_ADLS_IDS(&adl_s_info), INTEL_ADLP_IDS(&adl_p_info), INTEL_DG1_IDS(&dg1_info), + INTEL_RPLS_IDS(&adl_s_info), {0, 0, 0} }; MODULE_DEVICE_TABLE(pci, pciidlist); diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 305facedd284..6b2d577d74ed 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -177,6 +177,10 @@ static const u16 subplatform_portf_ids[] = { INTEL_ICL_PORT_F_IDS(0), }; +static const u16 subplatform_rpls_ids[] = { + INTEL_RPLS_IDS(0), +}; + static bool find_devid(u16 id, const u16 *p, unsigned int num) { for (; num; num--, p++) { @@ -213,6 +217,9 @@ void intel_device_info_subplatform_init(struct drm_i915_private *i915) } else if (find_devid(devid, subplatform_portf_ids, ARRAY_SIZE(subplatform_portf_ids))) { mask = BIT(INTEL_SUBPLATFORM_PORTF); + } else if (find_devid(devid, subplatform_rpls_ids, + ARRAY_SIZE(subplatform_rpls_ids))) { + mask = BIT(INTEL_SUBPLATFORM_RPL_S); } if (IS_TIGERLAKE(i915)) { diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 8e6f48d1eb7b..ac427d6ae305 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -110,6 +110,9 @@ enum intel_platform { #define INTEL_SUBPLATFORM_G10 0 #define INTEL_SUBPLATFORM_G11 1 +/* ADL-S */ +#define INTEL_SUBPLATFORM_RPL_S 0 + enum intel_ppgtt_type { INTEL_PPGTT_NONE = I915_GEM_PPGTT_NONE, INTEL_PPGTT_ALIASING = I915_GEM_PPGTT_ALIASING, diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index c00ac54692d7..baf3d1d3d566 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -666,4 +666,13 @@ INTEL_VGA_DEVICE(0x46C2, info), \ INTEL_VGA_DEVICE(0x46C3, info) +/* RPL-S */ +#define INTEL_RPLS_IDS(info) \ + INTEL_VGA_DEVICE(0xA780, info), \ + INTEL_VGA_DEVICE(0xA781, info), \ + INTEL_VGA_DEVICE(0xA782, info), \ + INTEL_VGA_DEVICE(0xA783, info), \ + INTEL_VGA_DEVICE(0xA788, info), \ + INTEL_VGA_DEVICE(0xA789, info) + #endif /* _I915_PCIIDS_H */ -- cgit v1.2.3-59-g8ed1b From 67c430bbaae153433f76807d07b8298ac4714822 Mon Sep 17 00:00:00 2001 From: Siva Mullati Date: Wed, 8 Dec 2021 09:42:15 +0530 Subject: drm/i915: Skip remap_io_mapping() for non-x86 platforms Only hw that supports mappable aperture would hit this path vm_fault_gtt/vm_fault_tmm, So we never hit this function remap_io_mapping() in discrete, So skip this code for non-x86 architectures. v2: use IS_ENABLED () instead of #if defined v3: move function prototypes from i915_drv.h to i915_mm.h v4: added kernel error message in stub function v5: fixed compilation warnings v6: checkpatch style Signed-off-by: Siva Mullati Reviewed-by: Lucas De Marchi Signed-off-by: Lucas De Marchi Link: https://patchwork.freedesktop.org/patch/msgid/20211208041215.763098-1-siva.mullati@intel.com --- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 8 -------- drivers/gpu/drm/i915/i915_mm.c | 28 ++++++++++++++----------- drivers/gpu/drm/i915/i915_mm.h | 35 ++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 20 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_mm.h (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index 65fc6ff5f59d..39bb15eafc07 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -17,6 +17,7 @@ #include "i915_gem_ioctls.h" #include "i915_gem_object.h" #include "i915_gem_mman.h" +#include "i915_mm.h" #include "i915_trace.h" #include "i915_user_extensions.h" #include "i915_gem_ttm.h" diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c10e2c81baea..a087b3fd3f9c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1776,14 +1776,6 @@ mkwrite_device_info(struct drm_i915_private *dev_priv) int i915_reg_read_ioctl(struct drm_device *dev, void *data, struct drm_file *file); -/* i915_mm.c */ -int remap_io_mapping(struct vm_area_struct *vma, - unsigned long addr, unsigned long pfn, unsigned long size, - struct io_mapping *iomap); -int remap_io_sg(struct vm_area_struct *vma, - unsigned long addr, unsigned long size, - struct scatterlist *sgl, resource_size_t iobase); - static inline int intel_hws_csb_write_index(struct drm_i915_private *i915) { if (GRAPHICS_VER(i915) >= 11) diff --git a/drivers/gpu/drm/i915/i915_mm.c b/drivers/gpu/drm/i915/i915_mm.c index 666808cb3a32..7998bc74ab49 100644 --- a/drivers/gpu/drm/i915/i915_mm.c +++ b/drivers/gpu/drm/i915/i915_mm.c @@ -27,6 +27,7 @@ #include "i915_drv.h" +#include "i915_mm.h" struct remap_pfn { struct mm_struct *mm; @@ -37,17 +38,6 @@ struct remap_pfn { resource_size_t iobase; }; -static int remap_pfn(pte_t *pte, unsigned long addr, void *data) -{ - struct remap_pfn *r = data; - - /* Special PTE are not associated with any struct page */ - set_pte_at(r->mm, addr, pte, pte_mkspecial(pfn_pte(r->pfn, r->prot))); - r->pfn++; - - return 0; -} - #define use_dma(io) ((io) != -1) static inline unsigned long sgt_pfn(const struct remap_pfn *r) @@ -77,6 +67,20 @@ static int remap_sg(pte_t *pte, unsigned long addr, void *data) return 0; } +#define EXPECTED_FLAGS (VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP) + +#if IS_ENABLED(CONFIG_X86) +static int remap_pfn(pte_t *pte, unsigned long addr, void *data) +{ + struct remap_pfn *r = data; + + /* Special PTE are not associated with any struct page */ + set_pte_at(r->mm, addr, pte, pte_mkspecial(pfn_pte(r->pfn, r->prot))); + r->pfn++; + + return 0; +} + /** * remap_io_mapping - remap an IO mapping to userspace * @vma: user vma to map to @@ -94,7 +98,6 @@ int remap_io_mapping(struct vm_area_struct *vma, struct remap_pfn r; int err; -#define EXPECTED_FLAGS (VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP) GEM_BUG_ON((vma->vm_flags & EXPECTED_FLAGS) != EXPECTED_FLAGS); /* We rely on prevalidation of the io-mapping to skip track_pfn(). */ @@ -111,6 +114,7 @@ int remap_io_mapping(struct vm_area_struct *vma, return 0; } +#endif /** * remap_io_sg - remap an IO mapping to userspace diff --git a/drivers/gpu/drm/i915/i915_mm.h b/drivers/gpu/drm/i915/i915_mm.h new file mode 100644 index 000000000000..76f1d53bdf34 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_mm.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2021 Intel Corporation + */ + +#ifndef __I915_MM_H__ +#define __I915_MM_H__ + +#include + +struct vm_area_struct; +struct io_mapping; +struct scatterlist; + +#if IS_ENABLED(CONFIG_X86) +int remap_io_mapping(struct vm_area_struct *vma, + unsigned long addr, unsigned long pfn, unsigned long size, + struct io_mapping *iomap); +#else +static inline +int remap_io_mapping(struct vm_area_struct *vma, + unsigned long addr, unsigned long pfn, unsigned long size, + struct io_mapping *iomap) +{ + pr_err("Architecture has no %s() and shouldn't be calling this function\n", __func__); + WARN_ON_ONCE(1); + return 0; +} +#endif + +int remap_io_sg(struct vm_area_struct *vma, + unsigned long addr, unsigned long size, + struct scatterlist *sgl, resource_size_t iobase); + +#endif /* __I915_MM_H__ */ -- cgit v1.2.3-59-g8ed1b From cbb8a7957108e96560c43953f70c377d8d9b6643 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 3 Dec 2021 13:20:27 +0200 Subject: drm/i915: Nuke {pipe,plane}_to_crtc_mapping[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These plane/pipe->crtc mapping arrays are rather pointless. Get rid of them and just iterate the lists instead. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211203112029.1057-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_crtc.c | 44 +++++++++++++------------------ drivers/gpu/drm/i915/display/intel_crtc.h | 1 - drivers/gpu/drm/i915/display/intel_vdsc.c | 13 ++------- drivers/gpu/drm/i915/i915_drv.h | 3 --- 4 files changed, 20 insertions(+), 41 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 6930fbedc97d..8f9a9b5703b8 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -36,14 +36,6 @@ static void assert_vblank_disabled(struct drm_crtc *crtc) drm_crtc_vblank_put(crtc); } -bool intel_pipe_valid(struct drm_i915_private *i915, enum pipe pipe) -{ - return (pipe >= 0 && - pipe < ARRAY_SIZE(i915->pipe_to_crtc_mapping) && - INTEL_INFO(i915)->pipe_mask & BIT(pipe) && - i915->pipe_to_crtc_mapping[pipe]); -} - struct intel_crtc *intel_get_first_crtc(struct drm_i915_private *i915) { return to_intel_crtc(drm_crtc_from_index(&i915->drm, 0)); @@ -52,16 +44,28 @@ struct intel_crtc *intel_get_first_crtc(struct drm_i915_private *i915) struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915, enum pipe pipe) { - /* pipe_to_crtc_mapping may have hole on any of 3 display pipe system */ - drm_WARN_ON(&i915->drm, - !(INTEL_INFO(i915)->pipe_mask & BIT(pipe))); - return i915->pipe_to_crtc_mapping[pipe]; + struct intel_crtc *crtc; + + for_each_intel_crtc(&i915->drm, crtc) { + if (crtc->pipe == pipe) + return crtc; + } + + return NULL; } struct intel_crtc *intel_crtc_for_plane(struct drm_i915_private *i915, - enum i9xx_plane_id plane) + enum i9xx_plane_id i9xx_plane) { - return i915->plane_to_crtc_mapping[plane]; + struct intel_plane *plane; + + for_each_intel_plane(&i915->drm, plane) { + if (plane->id == PLANE_PRIMARY && + plane->i9xx_plane == i9xx_plane) + return intel_crtc_for_pipe(i915, plane->pipe); + } + + return NULL; } void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc) @@ -369,18 +373,6 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) if (ret) goto fail; - BUG_ON(pipe >= ARRAY_SIZE(dev_priv->pipe_to_crtc_mapping) || - dev_priv->pipe_to_crtc_mapping[pipe] != NULL); - dev_priv->pipe_to_crtc_mapping[pipe] = crtc; - - if (DISPLAY_VER(dev_priv) < 9) { - enum i9xx_plane_id i9xx_plane = primary->i9xx_plane; - - BUG_ON(i9xx_plane >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || - dev_priv->plane_to_crtc_mapping[i9xx_plane] != NULL); - dev_priv->plane_to_crtc_mapping[i9xx_plane] = crtc; - } - if (DISPLAY_VER(dev_priv) >= 11) drm_crtc_create_scaling_filter_property(&crtc->base, BIT(DRM_SCALING_FILTER_DEFAULT) | diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h index 23110e91ecd6..4654f0eb65a2 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.h +++ b/drivers/gpu/drm/i915/display/intel_crtc.h @@ -29,7 +29,6 @@ void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state); void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state); void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state); void intel_wait_for_vblank_workers(struct intel_atomic_state *state); -bool intel_pipe_valid(struct drm_i915_private *i915, enum pipe pipe); struct intel_crtc *intel_get_first_crtc(struct drm_i915_private *i915); struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915, enum pipe pipe); diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 1cc4170e6ec8..9b05f93ed8bc 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -1112,25 +1112,16 @@ static i915_reg_t dss_ctl2_reg(struct intel_crtc *crtc, enum transcoder cpu_tran ICL_PIPE_DSS_CTL2(crtc->pipe) : DSS_CTL2; } -static struct intel_crtc * -_get_crtc_for_pipe(struct drm_i915_private *i915, enum pipe pipe) -{ - if (!intel_pipe_valid(i915, pipe)) - return NULL; - - return intel_crtc_for_pipe(i915, pipe); -} - struct intel_crtc * intel_dsc_get_bigjoiner_secondary(const struct intel_crtc *primary_crtc) { - return _get_crtc_for_pipe(to_i915(primary_crtc->base.dev), primary_crtc->pipe + 1); + return intel_crtc_for_pipe(to_i915(primary_crtc->base.dev), primary_crtc->pipe + 1); } static struct intel_crtc * intel_dsc_get_bigjoiner_primary(const struct intel_crtc *secondary_crtc) { - return _get_crtc_for_pipe(to_i915(secondary_crtc->base.dev), secondary_crtc->pipe - 1); + return intel_crtc_for_pipe(to_i915(secondary_crtc->base.dev), secondary_crtc->pipe - 1); } void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a087b3fd3f9c..d8e4e1115ef8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -846,9 +846,6 @@ struct drm_i915_private { /* Kernel Modesetting */ - struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES]; - struct intel_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES]; - /** * dpll and cdclk state is protected by connection_mutex * dpll.lock serializes intel_{prepare,enable,disable}_shared_dpll. -- cgit v1.2.3-59-g8ed1b From 6678916dfa01251b888465e2193e28affb23fca9 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 10 Dec 2021 14:27:26 +0200 Subject: drm/i915: Move pipe/transcoder/abox masks under intel_device_info.display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Collect the dipslay related mask under the display sub-structure in intel_device_info. Note that there is a slight change in behaviour in that we zero out .display entirely when !HAS_DISPLAY (aka. pipe_mask==0), so now we also zero out the other masks (although cpu_transocder_mask should already be zero of pipe_mask is zero). abox_mask is only used by the display core init when HAS_DISPLAY is true, so the actual behaviour of the system shouldn't change despite the zeroing of these masks. There is a lot more display stuff directly in device info that could be moved over. Maybe someone else will be inspired to do it... Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211210122726.12577-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.h | 4 +- drivers/gpu/drm/i915/display/intel_display_power.c | 4 +- drivers/gpu/drm/i915/i915_drv.h | 6 +- drivers/gpu/drm/i915/i915_pci.c | 75 +++++++++++----------- drivers/gpu/drm/i915/intel_device_info.c | 24 +++---- drivers/gpu/drm/i915/intel_device_info.h | 9 ++- 6 files changed, 60 insertions(+), 62 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.h') diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 4b688a9727b3..43fd2f0a3e5e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -372,7 +372,7 @@ enum hpd_pin { #define for_each_pipe(__dev_priv, __p) \ for ((__p) = 0; (__p) < I915_MAX_PIPES; (__p)++) \ - for_each_if(INTEL_INFO(__dev_priv)->pipe_mask & BIT(__p)) + for_each_if(INTEL_INFO(__dev_priv)->display.pipe_mask & BIT(__p)) #define for_each_pipe_masked(__dev_priv, __p, __mask) \ for_each_pipe(__dev_priv, __p) \ @@ -380,7 +380,7 @@ enum hpd_pin { #define for_each_cpu_transcoder(__dev_priv, __t) \ for ((__t) = 0; (__t) < I915_MAX_TRANSCODERS; (__t)++) \ - for_each_if (INTEL_INFO(__dev_priv)->cpu_transcoder_mask & BIT(__t)) + for_each_if (INTEL_INFO(__dev_priv)->display.cpu_transcoder_mask & BIT(__t)) #define for_each_cpu_transcoder_masked(__dev_priv, __t, __mask) \ for_each_cpu_transcoder(__dev_priv, __t) \ diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 229b4c127c6c..05babdcf5f2e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -5370,7 +5370,7 @@ static void gen12_dbuf_slices_config(struct drm_i915_private *dev_priv) static void icl_mbus_init(struct drm_i915_private *dev_priv) { - unsigned long abox_regs = INTEL_INFO(dev_priv)->abox_mask; + unsigned long abox_regs = INTEL_INFO(dev_priv)->display.abox_mask; u32 mask, val, i; if (IS_ALDERLAKE_P(dev_priv)) @@ -5830,7 +5830,7 @@ static void tgl_bw_buddy_init(struct drm_i915_private *dev_priv) enum intel_dram_type type = dev_priv->dram_info.type; u8 num_channels = dev_priv->dram_info.num_channels; const struct buddy_page_mask *table; - unsigned long abox_mask = INTEL_INFO(dev_priv)->abox_mask; + unsigned long abox_mask = INTEL_INFO(dev_priv)->display.abox_mask; int config, i; /* BW_BUDDY registers are not used on dgpu's beyond DG1 */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d8e4e1115ef8..e99996dfd43a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1506,7 +1506,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define HAS_PSR_HW_TRACKING(dev_priv) \ (INTEL_INFO(dev_priv)->display.has_psr_hw_tracking) #define HAS_PSR2_SEL_FETCH(dev_priv) (GRAPHICS_VER(dev_priv) >= 12) -#define HAS_TRANSCODER(dev_priv, trans) ((INTEL_INFO(dev_priv)->cpu_transcoder_mask & BIT(trans)) != 0) +#define HAS_TRANSCODER(dev_priv, trans) ((INTEL_INFO(dev_priv)->display.cpu_transcoder_mask & BIT(trans)) != 0) #define HAS_RC6(dev_priv) (INTEL_INFO(dev_priv)->has_rc6) #define HAS_RC6p(dev_priv) (INTEL_INFO(dev_priv)->has_rc6p) @@ -1551,9 +1551,9 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define GT_FREQUENCY_MULTIPLIER 50 #define GEN9_FREQ_SCALER 3 -#define INTEL_NUM_PIPES(dev_priv) (hweight8(INTEL_INFO(dev_priv)->pipe_mask)) +#define INTEL_NUM_PIPES(dev_priv) (hweight8(INTEL_INFO(dev_priv)->display.pipe_mask)) -#define HAS_DISPLAY(dev_priv) (INTEL_INFO(dev_priv)->pipe_mask != 0) +#define HAS_DISPLAY(dev_priv) (INTEL_INFO(dev_priv)->display.pipe_mask != 0) #define HAS_VRR(i915) (GRAPHICS_VER(i915) >= 11) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 158d160e3996..eeee028a5ad7 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -162,8 +162,8 @@ #define I830_FEATURES \ GEN(2), \ .is_mobile = 1, \ - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \ + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \ .display.has_overlay = 1, \ .display.cursor_needs_physical = 1, \ .display.overlay_needs_physical = 1, \ @@ -183,8 +183,8 @@ #define I845_FEATURES \ GEN(2), \ - .pipe_mask = BIT(PIPE_A), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A), \ + .display.pipe_mask = BIT(PIPE_A), \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A), \ .display.has_overlay = 1, \ .display.overlay_needs_physical = 1, \ .display.has_gmch = 1, \ @@ -225,8 +225,8 @@ static const struct intel_device_info i865g_info = { #define GEN3_FEATURES \ GEN(3), \ - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \ + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \ .display.has_gmch = 1, \ .gpu_reset_clobbers_display = true, \ .platform_engine_mask = BIT(RCS0), \ @@ -315,8 +315,8 @@ static const struct intel_device_info pnv_m_info = { #define GEN4_FEATURES \ GEN(4), \ - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \ + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \ .display.has_hotplug = 1, \ .display.has_gmch = 1, \ .gpu_reset_clobbers_display = true, \ @@ -368,8 +368,8 @@ static const struct intel_device_info gm45_info = { #define GEN5_FEATURES \ GEN(5), \ - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \ + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \ .display.has_hotplug = 1, \ .platform_engine_mask = BIT(RCS0) | BIT(VCS0), \ .has_snoop = true, \ @@ -398,8 +398,8 @@ static const struct intel_device_info ilk_m_info = { #define GEN6_FEATURES \ GEN(6), \ - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \ + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \ .display.has_hotplug = 1, \ .display.has_fbc = 1, \ .platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \ @@ -449,8 +449,8 @@ static const struct intel_device_info snb_m_gt2_info = { #define GEN7_FEATURES \ GEN(7), \ - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C), \ + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C), \ .display.has_hotplug = 1, \ .display.has_fbc = 1, \ .platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \ @@ -504,8 +504,8 @@ static const struct intel_device_info ivb_q_info = { GEN7_FEATURES, PLATFORM(INTEL_IVYBRIDGE), .gt = 2, - .pipe_mask = 0, /* legal, last one wins */ - .cpu_transcoder_mask = 0, + .display.pipe_mask = 0, /* legal, last one wins */ + .display.cpu_transcoder_mask = 0, .has_l3_dpf = 1, }; @@ -513,8 +513,8 @@ static const struct intel_device_info vlv_info = { PLATFORM(INTEL_VALLEYVIEW), GEN(7), .is_lp = 1, - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), .has_runtime_pm = 1, .has_rc6 = 1, .has_reset_engine = true, @@ -538,7 +538,7 @@ static const struct intel_device_info vlv_info = { #define G75_FEATURES \ GEN7_FEATURES, \ .platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \ BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP), \ .display.has_ddi = 1, \ .display.has_fpga_dbg = 1, \ @@ -608,8 +608,8 @@ static const struct intel_device_info bdw_gt3_info = { static const struct intel_device_info chv_info = { PLATFORM(INTEL_CHERRYVIEW), GEN(8), - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C), + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C), .display.has_hotplug = 1, .is_lp = 1, .platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), @@ -686,8 +686,8 @@ static const struct intel_device_info skl_gt4_info = { .dbuf.slice_mask = BIT(DBUF_S1), \ .display.has_hotplug = 1, \ .platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \ - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \ + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \ BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \ BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C), \ .has_64bit_reloc = 1, \ @@ -795,8 +795,8 @@ static const struct intel_device_info cml_gt2_info = { #define GEN11_FEATURES \ GEN9_FEATURES, \ GEN11_DEFAULT_PAGE_SIZES, \ - .abox_mask = BIT(0), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \ + .display.abox_mask = BIT(0), \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \ BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \ BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \ .pipe_offsets = { \ @@ -847,9 +847,9 @@ static const struct intel_device_info jsl_info = { #define GEN12_FEATURES \ GEN11_FEATURES, \ GEN(12), \ - .abox_mask = GENMASK(2, 1), \ - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \ - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \ + .display.abox_mask = GENMASK(2, 1), \ + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \ + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \ BIT(TRANSCODER_C) | BIT(TRANSCODER_D) | \ BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \ .pipe_offsets = { \ @@ -884,9 +884,9 @@ static const struct intel_device_info tgl_info = { static const struct intel_device_info rkl_info = { GEN12_FEATURES, PLATFORM(INTEL_ROCKETLAKE), - .abox_mask = BIT(0), - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | + .display.abox_mask = BIT(0), + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C), .display.has_hti = 1, .display.has_psr_hw_tracking = 0, @@ -906,7 +906,7 @@ static const struct intel_device_info dg1_info = { DGFX_FEATURES, .graphics_rel = 10, PLATFORM(INTEL_DG1), - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), .require_force_probe = 1, .platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | @@ -918,7 +918,7 @@ static const struct intel_device_info dg1_info = { static const struct intel_device_info adl_s_info = { GEN12_FEATURES, PLATFORM(INTEL_ALDERLAKE_S), - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), .display.has_hti = 1, .display.has_psr_hw_tracking = 0, .platform_engine_mask = @@ -935,7 +935,7 @@ static const struct intel_device_info adl_s_info = { } #define XE_LPD_FEATURES \ - .abox_mask = GENMASK(1, 0), \ + .display.abox_mask = GENMASK(1, 0), \ .color = { .degamma_lut_size = 128, .gamma_lut_size = 1024, \ .degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING | \ DRM_COLOR_LUT_EQUAL_CHANNELS, \ @@ -955,7 +955,7 @@ static const struct intel_device_info adl_s_info = { .display.has_ipc = 1, \ .display.has_psr = 1, \ .display.ver = 13, \ - .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \ + .display.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \ .pipe_offsets = { \ [TRANSCODER_A] = PIPE_A_OFFSET, \ [TRANSCODER_B] = PIPE_B_OFFSET, \ @@ -978,7 +978,7 @@ static const struct intel_device_info adl_p_info = { GEN12_FEATURES, XE_LPD_FEATURES, PLATFORM(INTEL_ALDERLAKE_P), - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D) | BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), .display.has_cdclk_crawl = 1, @@ -1027,7 +1027,6 @@ static const struct intel_device_info xehpsdv_info = { DGFX_FEATURES, PLATFORM(INTEL_XEHPSDV), .display = { }, - .pipe_mask = 0, .platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VECS1) | BIT(VECS2) | BIT(VECS3) | @@ -1050,7 +1049,7 @@ static const struct intel_device_info dg2_info = { BIT(VECS0) | BIT(VECS1) | BIT(VCS0) | BIT(VCS2), .require_force_probe = 1, - .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | + .display.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D), }; diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 6b2d577d74ed..cbe9972478ac 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -333,33 +333,33 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { drm_info(&dev_priv->drm, "Display fused off, disabling\n"); - info->pipe_mask = 0; - info->cpu_transcoder_mask = 0; + info->display.pipe_mask = 0; + info->display.cpu_transcoder_mask = 0; } else if (fuse_strap & IVB_PIPE_C_DISABLE) { drm_info(&dev_priv->drm, "PipeC fused off\n"); - info->pipe_mask &= ~BIT(PIPE_C); - info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C); + info->display.pipe_mask &= ~BIT(PIPE_C); + info->display.cpu_transcoder_mask &= ~BIT(TRANSCODER_C); } } else if (HAS_DISPLAY(dev_priv) && DISPLAY_VER(dev_priv) >= 9) { u32 dfsm = intel_de_read(dev_priv, SKL_DFSM); if (dfsm & SKL_DFSM_PIPE_A_DISABLE) { - info->pipe_mask &= ~BIT(PIPE_A); - info->cpu_transcoder_mask &= ~BIT(TRANSCODER_A); + info->display.pipe_mask &= ~BIT(PIPE_A); + info->display.cpu_transcoder_mask &= ~BIT(TRANSCODER_A); } if (dfsm & SKL_DFSM_PIPE_B_DISABLE) { - info->pipe_mask &= ~BIT(PIPE_B); - info->cpu_transcoder_mask &= ~BIT(TRANSCODER_B); + info->display.pipe_mask &= ~BIT(PIPE_B); + info->display.cpu_transcoder_mask &= ~BIT(TRANSCODER_B); } if (dfsm & SKL_DFSM_PIPE_C_DISABLE) { - info->pipe_mask &= ~BIT(PIPE_C); - info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C); + info->display.pipe_mask &= ~BIT(PIPE_C); + info->display.cpu_transcoder_mask &= ~BIT(TRANSCODER_C); } if (DISPLAY_VER(dev_priv) >= 12 && (dfsm & TGL_DFSM_PIPE_D_DISABLE)) { - info->pipe_mask &= ~BIT(PIPE_D); - info->cpu_transcoder_mask &= ~BIT(TRANSCODER_D); + info->display.pipe_mask &= ~BIT(PIPE_D); + info->display.cpu_transcoder_mask &= ~BIT(TRANSCODER_D); } if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE) diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index ac427d6ae305..c121d7309dd2 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -192,11 +192,6 @@ struct intel_device_info { u8 gt; /* GT number, 0 if undefined */ - u8 pipe_mask; - u8 cpu_transcoder_mask; - - u8 abox_mask; - #define DEFINE_FLAG(name) u8 name:1 DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG); #undef DEFINE_FLAG @@ -204,6 +199,10 @@ struct intel_device_info { struct { u8 ver; + u8 pipe_mask; + u8 cpu_transcoder_mask; + u8 abox_mask; + #define DEFINE_FLAG(name) u8 name:1 DEV_INFO_DISPLAY_FOR_EACH_FLAG(DEFINE_FLAG); #undef DEFINE_FLAG -- cgit v1.2.3-59-g8ed1b