From cce936f4fff736927ffd53a61d7b2c6a1064e0c5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 13 Dec 2021 13:41:05 +0200 Subject: drm/i915/cdclk: turn around i915_drv.h and intel_cdclk.h dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_cdclk.h only needs i915_drv.h for struct intel_cdclk_config. Move the definition to intel_cdclk.h and turn the includes around to avoid including i915_drv.h from other headers. The intel cdclk state macros in intel_cdclk.h still reference struct drm_i915_private, but as macros they don't strictly require the definition until they are used. v2: Expand on the commit message wrt cdclk state macros Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20211213114106.296017-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_atomic.c | 1 + drivers/gpu/drm/i915/display/intel_cdclk.h | 6 +++++- drivers/gpu/drm/i915/i915_drv.h | 6 +----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index a62550711e98..1080741d1561 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -34,6 +34,7 @@ #include #include +#include "i915_drv.h" #include "intel_atomic.h" #include "intel_cdclk.h" #include "intel_display_types.h" diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index fc638522e445..71dd84740ae3 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -8,7 +8,6 @@ #include -#include "i915_drv.h" #include "intel_display.h" #include "intel_global_state.h" @@ -16,6 +15,11 @@ struct drm_i915_private; struct intel_atomic_state; struct intel_crtc_state; +struct intel_cdclk_config { + unsigned int cdclk, vco, ref, bypass; + u8 voltage_level; +}; + struct intel_cdclk_state { struct intel_global_state base; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e99996dfd43a..433c1387a137 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -65,6 +65,7 @@ #include "i915_utils.h" #include "display/intel_bios.h" +#include "display/intel_cdclk.h" #include "display/intel_display.h" #include "display/intel_display_power.h" #include "display/intel_dmc.h" @@ -627,11 +628,6 @@ struct i915_virtual_gpu { u32 caps; }; -struct intel_cdclk_config { - unsigned int cdclk, vco, ref, bypass; - u8 voltage_level; -}; - struct i915_selftest_stash { atomic_t counter; struct ida mock_region_instances; -- cgit v1.2.3 From a908db6d98782e8d9a8d545dcc74937db5bfac04 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 13 Dec 2021 13:41:06 +0200 Subject: drm/i915/cdclk: move struct intel_cdclk_funcs to intel_cdclk.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The funcs struct can be opaque, make it internal to intel_cdclk.c. Suggested-by: Ville Syrjälä Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211213114106.296017-2-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 11 +++++++++++ drivers/gpu/drm/i915/i915_drv.h | 12 +----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index c30cf8d2b835..249f81a80eb7 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -63,6 +63,17 @@ * dividers can be programmed correctly. */ +struct intel_cdclk_funcs { + void (*get_cdclk)(struct drm_i915_private *i915, + struct intel_cdclk_config *cdclk_config); + void (*set_cdclk)(struct drm_i915_private *i915, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe); + int (*bw_calc_min_cdclk)(struct intel_atomic_state *state); + int (*modeset_calc_cdclk)(struct intel_cdclk_state *state); + u8 (*calc_voltage_level)(int cdclk); +}; + void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv, struct intel_cdclk_config *cdclk_config) { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 433c1387a137..9a4070988749 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -293,6 +293,7 @@ struct intel_connector; struct intel_encoder; struct intel_atomic_state; struct intel_cdclk_config; +struct intel_cdclk_funcs; struct intel_cdclk_state; struct intel_cdclk_vals; struct intel_initial_plane_config; @@ -341,17 +342,6 @@ struct intel_color_funcs { void (*read_luts)(struct intel_crtc_state *crtc_state); }; -struct intel_cdclk_funcs { - void (*get_cdclk)(struct drm_i915_private *dev_priv, - struct intel_cdclk_config *cdclk_config); - void (*set_cdclk)(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe); - int (*bw_calc_min_cdclk)(struct intel_atomic_state *state); - int (*modeset_calc_cdclk)(struct intel_cdclk_state *state); - u8 (*calc_voltage_level)(int cdclk); -}; - struct intel_hotplug_funcs { void (*hpd_irq_setup)(struct drm_i915_private *dev_priv); }; -- cgit v1.2.3 From ae361eb07e9b498bc224db81113118fd28e35f6e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Dec 2021 20:46:16 +0200 Subject: drm/i915/fbc: Parametrize FBC register offsets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parametrize ilk+ FBC register offsets based on the FBC instance. v2: More intel_ namespace (Jani) v3: Don't break gvt (Jani) Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211214184616.1410-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 34 ++++++++++++++++++-------------- drivers/gpu/drm/i915/display/intel_fbc.h | 6 ++++++ drivers/gpu/drm/i915/gvt/handlers.c | 13 ++++++------ drivers/gpu/drm/i915/i915_reg.h | 34 ++++++++++++++++---------------- drivers/gpu/drm/i915/intel_pm.c | 31 +++++++++++++++++------------ 5 files changed, 67 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index b33941c9e089..0ee71ca35286 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -85,6 +85,8 @@ struct intel_fbc { struct drm_mm_node compressed_fb; struct drm_mm_node compressed_llb; + enum intel_fbc_id id; + u8 limit; bool false_color; @@ -454,10 +456,10 @@ static void ilk_fbc_activate(struct intel_fbc *fbc) struct intel_fbc_state *fbc_state = &fbc->state; struct drm_i915_private *i915 = fbc->i915; - intel_de_write(i915, ILK_DPFC_FENCE_YOFF, + intel_de_write(i915, ILK_DPFC_FENCE_YOFF(fbc->id), fbc_state->fence_y_offset); - intel_de_write(i915, ILK_DPFC_CONTROL, + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), DPFC_CTL_EN | g4x_dpfc_ctl(fbc)); } @@ -467,28 +469,28 @@ static void ilk_fbc_deactivate(struct intel_fbc *fbc) u32 dpfc_ctl; /* Disable compression */ - dpfc_ctl = intel_de_read(i915, ILK_DPFC_CONTROL); + dpfc_ctl = intel_de_read(i915, ILK_DPFC_CONTROL(fbc->id)); if (dpfc_ctl & DPFC_CTL_EN) { dpfc_ctl &= ~DPFC_CTL_EN; - intel_de_write(i915, ILK_DPFC_CONTROL, dpfc_ctl); + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl); } } static bool ilk_fbc_is_active(struct intel_fbc *fbc) { - return intel_de_read(fbc->i915, ILK_DPFC_CONTROL) & DPFC_CTL_EN; + return intel_de_read(fbc->i915, ILK_DPFC_CONTROL(fbc->id)) & DPFC_CTL_EN; } static bool ilk_fbc_is_compressing(struct intel_fbc *fbc) { - return intel_de_read(fbc->i915, ILK_DPFC_STATUS) & DPFC_COMP_SEG_MASK; + return intel_de_read(fbc->i915, ILK_DPFC_STATUS(fbc->id)) & DPFC_COMP_SEG_MASK; } static void ilk_fbc_program_cfb(struct intel_fbc *fbc) { struct drm_i915_private *i915 = fbc->i915; - intel_de_write(i915, ILK_DPFC_CB_BASE, fbc->compressed_fb.start); + intel_de_write(i915, ILK_DPFC_CB_BASE(fbc->id), fbc->compressed_fb.start); } static const struct intel_fbc_funcs ilk_fbc_funcs = { @@ -524,8 +526,8 @@ static void snb_fbc_nuke(struct intel_fbc *fbc) { struct drm_i915_private *i915 = fbc->i915; - intel_de_write(i915, MSG_FBC_REND_STATE, FBC_REND_NUKE); - intel_de_posting_read(i915, MSG_FBC_REND_STATE); + intel_de_write(i915, MSG_FBC_REND_STATE(fbc->id), FBC_REND_NUKE); + intel_de_posting_read(i915, MSG_FBC_REND_STATE(fbc->id)); } static const struct intel_fbc_funcs snb_fbc_funcs = { @@ -547,7 +549,7 @@ static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc) val |= FBC_STRIDE_OVERRIDE | FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit); - intel_de_write(i915, GLK_FBC_STRIDE, val); + intel_de_write(i915, GLK_FBC_STRIDE(fbc->id), val); } static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc) @@ -598,19 +600,19 @@ static void ivb_fbc_activate(struct intel_fbc *fbc) if (i915->ggtt.num_fences) snb_fbc_program_fence(fbc); - intel_de_write(i915, ILK_DPFC_CONTROL, + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), DPFC_CTL_EN | ivb_dpfc_ctl(fbc)); } static bool ivb_fbc_is_compressing(struct intel_fbc *fbc) { - return intel_de_read(fbc->i915, ILK_DPFC_STATUS2) & DPFC_COMP_SEG_MASK_IVB; + return intel_de_read(fbc->i915, ILK_DPFC_STATUS2(fbc->id)) & DPFC_COMP_SEG_MASK_IVB; } static void ivb_fbc_set_false_color(struct intel_fbc *fbc, bool enable) { - intel_de_rmw(fbc->i915, ILK_DPFC_CONTROL, + intel_de_rmw(fbc->i915, ILK_DPFC_CONTROL(fbc->id), DPFC_CTL_FALSE_COLOR, enable ? DPFC_CTL_FALSE_COLOR : 0); } @@ -1620,7 +1622,8 @@ 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) +static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915, + enum intel_fbc_id fbc_id) { struct intel_fbc *fbc; @@ -1628,6 +1631,7 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915) if (!fbc) return NULL; + fbc->id = fbc_id; fbc->i915 = i915; INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn); mutex_init(&fbc->lock); @@ -1671,7 +1675,7 @@ void intel_fbc_init(struct drm_i915_private *i915) if (!HAS_FBC(i915)) return; - fbc = intel_fbc_create(i915); + fbc = intel_fbc_create(i915, INTEL_FBC_A); if (!fbc) return; diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h index 07ad0411fcc3..7b7631aec527 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.h +++ b/drivers/gpu/drm/i915/display/intel_fbc.h @@ -17,6 +17,12 @@ struct intel_fbc; struct intel_plane; struct intel_plane_state; +enum intel_fbc_id { + INTEL_FBC_A, + + I915_MAX_FBCS, +}; + int intel_fbc_atomic_check(struct intel_atomic_state *state); bool intel_fbc_pre_update(struct intel_atomic_state *state, struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index cde0a477fb49..3938df0db188 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -40,6 +40,7 @@ #include "gvt.h" #include "i915_pvinfo.h" #include "display/intel_display_types.h" +#include "display/intel_fbc.h" /* XXX FIXME i915 has changed PP_XXX definition */ #define PCH_PP_STATUS _MMIO(0xc7200) @@ -2647,12 +2648,12 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_D(_MMIO(_TRANSA_CHICKEN2), D_ALL); MMIO_D(_MMIO(_TRANSB_CHICKEN2), D_ALL); - MMIO_D(ILK_DPFC_CB_BASE, D_ALL); - MMIO_D(ILK_DPFC_CONTROL, D_ALL); - MMIO_D(ILK_DPFC_RECOMP_CTL, D_ALL); - MMIO_D(ILK_DPFC_STATUS, D_ALL); - MMIO_D(ILK_DPFC_FENCE_YOFF, D_ALL); - MMIO_D(ILK_DPFC_CHICKEN, D_ALL); + MMIO_D(ILK_DPFC_CB_BASE(INTEL_FBC_A), D_ALL); + MMIO_D(ILK_DPFC_CONTROL(INTEL_FBC_A), D_ALL); + MMIO_D(ILK_DPFC_RECOMP_CTL(INTEL_FBC_A), D_ALL); + MMIO_D(ILK_DPFC_STATUS(INTEL_FBC_A), D_ALL); + MMIO_D(ILK_DPFC_FENCE_YOFF(INTEL_FBC_A), D_ALL); + MMIO_D(ILK_DPFC_CHICKEN(INTEL_FBC_A), D_ALL); MMIO_D(ILK_FBC_RT_BASE, D_ALL); MMIO_D(IPS_CTL, D_ALL); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9e5ccf86088c..8528db258827 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3353,10 +3353,10 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define FBC_LL_SIZE (1536) /* Framebuffer compression for GM45+ */ -#define DPFC_CB_BASE _MMIO(0x3200) -#define ILK_DPFC_CB_BASE _MMIO(0x43200) -#define DPFC_CONTROL _MMIO(0x3208) -#define ILK_DPFC_CONTROL _MMIO(0x43208) +#define DPFC_CB_BASE _MMIO(0x3200) +#define ILK_DPFC_CB_BASE(fbc_id) _MMIO_PIPE((fbc_id), 0x43200, 0x43240) +#define DPFC_CONTROL _MMIO(0x3208) +#define ILK_DPFC_CONTROL(fbc_id) _MMIO_PIPE((fbc_id), 0x43208, 0x43248) #define DPFC_CTL_EN REG_BIT(31) #define DPFC_CTL_PLANE_MASK_G4X REG_BIT(30) /* g4x-snb */ #define DPFC_CTL_PLANE_G4X(i9xx_plane) REG_FIELD_PREP(DPFC_CTL_PLANE_MASK_G4X, (i9xx_plane)) @@ -3374,28 +3374,28 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define DPFC_CTL_LIMIT_4X REG_FIELD_PREP(DPFC_CTL_LIMIT_MASK, 2) #define DPFC_CTL_FENCENO_MASK REG_GENMASK(3, 0) #define DPFC_CTL_FENCENO(fence) REG_FIELD_PREP(DPFC_CTL_FENCENO_MASK, (fence)) -#define DPFC_RECOMP_CTL _MMIO(0x320c) -#define ILK_DPFC_RECOMP_CTL _MMIO(0x4320c) +#define DPFC_RECOMP_CTL _MMIO(0x320c) +#define ILK_DPFC_RECOMP_CTL(fbc_id) _MMIO_PIPE((fbc_id), 0x4320c, 0x4324c) #define DPFC_RECOMP_STALL_EN REG_BIT(27) #define DPFC_RECOMP_STALL_WM_MASK REG_GENMASK(26, 16) #define DPFC_RECOMP_TIMER_COUNT_MASK REG_GENMASK(5, 0) -#define DPFC_STATUS _MMIO(0x3210) -#define ILK_DPFC_STATUS _MMIO(0x43210) +#define DPFC_STATUS _MMIO(0x3210) +#define ILK_DPFC_STATUS(fbc_id) _MMIO_PIPE((fbc_id), 0x43210, 0x43250) #define DPFC_INVAL_SEG_MASK REG_GENMASK(26, 16) #define DPFC_COMP_SEG_MASK REG_GENMASK(10, 0) -#define DPFC_STATUS2 _MMIO(0x3214) -#define ILK_DPFC_STATUS2 _MMIO(0x43214) +#define DPFC_STATUS2 _MMIO(0x3214) +#define ILK_DPFC_STATUS2(fbc_id) _MMIO_PIPE((fbc_id), 0x43214, 0x43254) #define DPFC_COMP_SEG_MASK_IVB REG_GENMASK(11, 0) -#define DPFC_FENCE_YOFF _MMIO(0x3218) -#define ILK_DPFC_FENCE_YOFF _MMIO(0x43218) -#define DPFC_CHICKEN _MMIO(0x3224) -#define ILK_DPFC_CHICKEN _MMIO(0x43224) +#define DPFC_FENCE_YOFF _MMIO(0x3218) +#define ILK_DPFC_FENCE_YOFF(fbc_id) _MMIO_PIPE((fbc_id), 0x43218, 0x43258) +#define DPFC_CHICKEN _MMIO(0x3224) +#define ILK_DPFC_CHICKEN(fbc_id) _MMIO_PIPE((fbc_id), 0x43224, 0x43264) #define DPFC_HT_MODIFY REG_BIT(31) /* pre-ivb */ #define DPFC_NUKE_ON_ANY_MODIFICATION REG_BIT(23) /* bdw+ */ #define DPFC_CHICKEN_COMP_DUMMY_PIXEL REG_BIT(14) /* glk+ */ #define DPFC_DISABLE_DUMMY0 REG_BIT(8) /* ivb+ */ -#define GLK_FBC_STRIDE _MMIO(0x43228) +#define GLK_FBC_STRIDE(fbc_id) _MMIO_PIPE((fbc_id), 0x43228, 0x43268) #define FBC_STRIDE_OVERRIDE REG_BIT(15) #define FBC_STRIDE_MASK REG_GENMASK(14, 0) #define FBC_STRIDE(x) REG_FIELD_PREP(FBC_STRIDE_MASK, (x)) @@ -3438,9 +3438,9 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define IPS_CTL _MMIO(0x43408) #define IPS_ENABLE (1 << 31) -#define MSG_FBC_REND_STATE _MMIO(0x50380) +#define MSG_FBC_REND_STATE(fbc_id) _MMIO_PIPE((fbc_id), 0x50380, 0x50384) #define FBC_REND_NUKE REG_BIT(2) -#define FBC_REND_CACHE_CLEAN REG_BIT(1) +#define FBC_REND_CACHE_CLEAN REG_BIT(1) /* * GPIO regs diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index fe1a83c02852..3714f96f17b3 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -160,8 +160,9 @@ static void bxt_init_clock_gating(struct drm_i915_private *dev_priv) * WaFbcHighMemBwCorruptionAvoidance:bxt * Display WA #0883: bxt */ - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN) | - DPFC_DISABLE_DUMMY0); + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A)) | + DPFC_DISABLE_DUMMY0); } static void glk_init_clock_gating(struct drm_i915_private *dev_priv) @@ -7451,8 +7452,8 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, static void icl_init_clock_gating(struct drm_i915_private *dev_priv) { /* Wa_1409120013:icl,ehl */ - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, - DPFC_CHICKEN_COMP_DUMMY_PIXEL); + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + DPFC_CHICKEN_COMP_DUMMY_PIXEL); /*Wa_14010594013:icl, ehl */ intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, @@ -7464,7 +7465,7 @@ static void gen12lp_init_clock_gating(struct drm_i915_private *dev_priv) /* Wa_1409120013:tgl,rkl,adl-s,dg1,dg2 */ if (IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv) || IS_ALDERLAKE_S(dev_priv) || IS_DG1(dev_priv) || IS_DG2(dev_priv)) - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), DPFC_CHICKEN_COMP_DUMMY_PIXEL); /* Wa_1409825376:tgl (pre-prod)*/ @@ -7526,8 +7527,9 @@ static void cfl_init_clock_gating(struct drm_i915_private *dev_priv) * WaFbcNukeOnHostModify:cfl * Display WA #0873: cfl */ - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN) | - DPFC_NUKE_ON_ANY_MODIFICATION); + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A)) | + DPFC_NUKE_ON_ANY_MODIFICATION); } static void kbl_init_clock_gating(struct drm_i915_private *dev_priv) @@ -7559,8 +7561,9 @@ static void kbl_init_clock_gating(struct drm_i915_private *dev_priv) * WaFbcNukeOnHostModify:kbl * Display WA #0873: kbl */ - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN) | - DPFC_NUKE_ON_ANY_MODIFICATION); + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A)) | + DPFC_NUKE_ON_ANY_MODIFICATION); } static void skl_init_clock_gating(struct drm_i915_private *dev_priv) @@ -7586,15 +7589,17 @@ static void skl_init_clock_gating(struct drm_i915_private *dev_priv) * WaFbcNukeOnHostModify:skl * Display WA #0873: skl */ - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN) | - DPFC_NUKE_ON_ANY_MODIFICATION); + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A)) | + DPFC_NUKE_ON_ANY_MODIFICATION); /* * WaFbcHighMemBwCorruptionAvoidance:skl * Display WA #0883: skl */ - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN) | - DPFC_DISABLE_DUMMY0); + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A)) | + DPFC_DISABLE_DUMMY0); } static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) -- cgit v1.2.3 From c2a9682d2214e834b493c454e38809e571bb3045 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Dec 2021 15:44:48 +0200 Subject: drm/i915/fbc: Loop through FBC instances in various places MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert i915->fbc into an array in preparation for multiple FBC instances, and loop through all instances in all places where the caller does not know which instance(s) (if any) are relevant. This is the case for eg. frontbuffer tracking and FIFO underrun hadling. v2: More intel_ namespace (Jani) Leave out debugfs for later Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211213134450.3082-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/i9xx_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_fbc.c | 147 +++++++++++++-------- drivers/gpu/drm/i915/display/skl_universal_plane.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 3 +- 4 files changed, 94 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 85950ff67609..fc6f05146a9f 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[INTEL_FBC_A]; else return NULL; } diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 0ee71ca35286..a73256f22a1e 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -49,6 +49,13 @@ #include "intel_fbc.h" #include "intel_frontbuffer.h" +#define for_each_fbc_id(__fbc_id) \ + for ((__fbc_id) = INTEL_FBC_A; (__fbc_id) < I915_MAX_FBCS; (__fbc_id)++) + +#define for_each_intel_fbc(__dev_priv, __fbc, __fbc_id) \ + for_each_fbc_id(__fbc_id) \ + for_each_if((__fbc) = (__dev_priv)->fbc[(__fbc_id)]) + struct intel_fbc_funcs { void (*activate)(struct intel_fbc *fbc); void (*deactivate)(struct intel_fbc *fbc); @@ -812,16 +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; - - if (!fbc) - return; + struct intel_fbc *fbc; + enum intel_fbc_id fbc_id; - mutex_lock(&fbc->lock); - __intel_fbc_cleanup_cfb(fbc); - mutex_unlock(&fbc->lock); + for_each_intel_fbc(i915, fbc, fbc_id) { + mutex_lock(&fbc->lock); + __intel_fbc_cleanup_cfb(fbc); + mutex_unlock(&fbc->lock); - kfree(fbc); + kfree(fbc); + } } static bool stride_is_valid(const struct intel_plane_state *plane_state) @@ -1307,15 +1314,10 @@ static unsigned int intel_fbc_get_frontbuffer_bit(struct intel_fbc *fbc) return fbc->possible_framebuffer_bits; } -void intel_fbc_invalidate(struct drm_i915_private *i915, - unsigned int frontbuffer_bits, - enum fb_op_origin origin) +static void __intel_fbc_invalidate(struct intel_fbc *fbc, + unsigned int frontbuffer_bits, + enum fb_op_origin origin) { - struct intel_fbc *fbc = i915->fbc; - - if (!fbc) - return; - if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE) return; @@ -1329,14 +1331,22 @@ void intel_fbc_invalidate(struct drm_i915_private *i915, mutex_unlock(&fbc->lock); } -void intel_fbc_flush(struct drm_i915_private *i915, - unsigned int frontbuffer_bits, enum fb_op_origin origin) +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; + enum intel_fbc_id fbc_id; - if (!fbc) - return; + for_each_intel_fbc(i915, fbc, fbc_id) + __intel_fbc_invalidate(fbc, frontbuffer_bits, origin); + +} +static void __intel_fbc_flush(struct intel_fbc *fbc, + unsigned int frontbuffer_bits, + enum fb_op_origin origin) +{ mutex_lock(&fbc->lock); fbc->busy_bits &= ~frontbuffer_bits; @@ -1356,6 +1366,17 @@ out: mutex_unlock(&fbc->lock); } +void intel_fbc_flush(struct drm_i915_private *i915, + unsigned int frontbuffer_bits, + enum fb_op_origin origin) +{ + struct intel_fbc *fbc; + enum intel_fbc_id fbc_id; + + for_each_intel_fbc(i915, fbc, fbc_id) + __intel_fbc_flush(fbc, frontbuffer_bits, origin); +} + int intel_fbc_atomic_check(struct intel_atomic_state *state) { struct intel_plane_state *plane_state; @@ -1483,15 +1504,15 @@ 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; - - if (!fbc) - return; + struct intel_fbc *fbc; + enum intel_fbc_id fbc_id; - mutex_lock(&fbc->lock); - if (fbc->state.plane) - __intel_fbc_disable(fbc); - mutex_unlock(&fbc->lock); + for_each_intel_fbc(i915, fbc, fbc_id) { + mutex_lock(&fbc->lock); + if (fbc->state.plane) + __intel_fbc_disable(fbc); + mutex_unlock(&fbc->lock); + } } static void intel_fbc_underrun_work_fn(struct work_struct *work) @@ -1516,19 +1537,9 @@ out: mutex_unlock(&fbc->lock); } -/* - * intel_fbc_reset_underrun - reset FBC fifo underrun status. - * @i915: the i915 device - * - * See intel_fbc_handle_fifo_underrun_irq(). For automated testing we - * want to re-enable FBC after an underrun to increase test coverage. - */ -void intel_fbc_reset_underrun(struct drm_i915_private *i915) +static void __intel_fbc_reset_underrun(struct intel_fbc *fbc) { - struct intel_fbc *fbc = i915->fbc; - - if (!fbc) - return; + struct drm_i915_private *i915 = fbc->i915; cancel_work_sync(&fbc->underrun_work); @@ -1544,6 +1555,38 @@ void intel_fbc_reset_underrun(struct drm_i915_private *i915) mutex_unlock(&fbc->lock); } +/* + * intel_fbc_reset_underrun - reset FBC fifo underrun status. + * @i915: the i915 device + * + * See intel_fbc_handle_fifo_underrun_irq(). For automated testing we + * want to re-enable FBC after an underrun to increase test coverage. + */ +void intel_fbc_reset_underrun(struct drm_i915_private *i915) +{ + struct intel_fbc *fbc; + enum intel_fbc_id fbc_id; + + for_each_intel_fbc(i915, fbc, fbc_id) + __intel_fbc_reset_underrun(fbc); +} + +static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc) +{ + /* + * There's no guarantee that underrun_detected won't be set to true + * right after this check and before the work is scheduled, but that's + * not a problem since we'll check it again under the work function + * while FBC is locked. This check here is just to prevent us from + * unnecessarily scheduling the work, and it relies on the fact that we + * never switch underrun_detect back to false after it's true. + */ + if (READ_ONCE(fbc->underrun_detected)) + return; + + schedule_work(&fbc->underrun_work); +} + /** * intel_fbc_handle_fifo_underrun_irq - disable FBC when we get a FIFO underrun * @i915: i915 device @@ -1560,21 +1603,11 @@ 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; - - if (!fbc) - return; - - /* There's no guarantee that underrun_detected won't be set to true - * right after this check and before the work is scheduled, but that's - * not a problem since we'll check it again under the work function - * while FBC is locked. This check here is just to prevent us from - * unnecessarily scheduling the work, and it relies on the fact that we - * never switch underrun_detect back to false after it's true. */ - if (READ_ONCE(fbc->underrun_detected)) - return; + struct intel_fbc *fbc; + enum intel_fbc_id fbc_id; - schedule_work(&fbc->underrun_work); + for_each_intel_fbc(i915, fbc, fbc_id) + __intel_fbc_handle_fifo_underrun_irq(fbc); } /* @@ -1685,7 +1718,7 @@ void intel_fbc_init(struct drm_i915_private *i915) if (intel_fbc_hw_is_active(fbc)) intel_fbc_hw_deactivate(fbc); - i915->fbc = fbc; + i915->fbc[fbc->id] = fbc; } static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) @@ -1778,7 +1811,7 @@ 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[INTEL_FBC_A]; 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 d5359cf3d270..3db57cd7474b 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1829,7 +1829,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[INTEL_FBC_A]; else return NULL; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9a4070988749..5eaa6ac3eeeb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -71,6 +71,7 @@ #include "display/intel_dmc.h" #include "display/intel_dpll_mgr.h" #include "display/intel_dsb.h" +#include "display/intel_fbc.h" #include "display/intel_frontbuffer.h" #include "display/intel_global_state.h" #include "display/intel_gmbus.h" @@ -737,7 +738,7 @@ struct drm_i915_private { u32 pipestat_irq_mask[I915_MAX_PIPES]; struct i915_hotplug hotplug; - struct intel_fbc *fbc; + struct intel_fbc *fbc[I915_MAX_FBCS]; struct i915_drrs drrs; struct intel_opregion opregion; struct intel_vbt_data vbt; -- cgit v1.2.3 From b8ca477e51318d28f7514abfb5a369e11848a8cf Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Dec 2021 15:44:49 +0200 Subject: drm/i915/fbc: Introduce device info fbc_mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare which FBC instances are present via a fbc_mask in device info. For the moment there is just the one. TODO: Need to figure out how to expose multiple FBC instances in debugs. Just different file names, or move the files under some subdirectory (per-crtc maybe), or something else? This will need igt changes as well. v2: Put the mask into device_info.display (Jani) Put the magic pipe->fbc thing into skl_fbc_id_for_pipe() (Jani) Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211213134450.3082-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 38 ++++++++++++---------- drivers/gpu/drm/i915/display/skl_universal_plane.c | 17 +++++++--- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_pci.c | 22 ++++++------- drivers/gpu/drm/i915/intel_device_info.c | 4 ++- drivers/gpu/drm/i915/intel_device_info.h | 2 +- 6 files changed, 49 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index a73256f22a1e..796453e1c101 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -49,11 +49,12 @@ #include "intel_fbc.h" #include "intel_frontbuffer.h" -#define for_each_fbc_id(__fbc_id) \ - for ((__fbc_id) = INTEL_FBC_A; (__fbc_id) < I915_MAX_FBCS; (__fbc_id)++) +#define for_each_fbc_id(__dev_priv, __fbc_id) \ + for ((__fbc_id) = INTEL_FBC_A; (__fbc_id) < I915_MAX_FBCS; (__fbc_id)++) \ + for_each_if(INTEL_INFO(__dev_priv)->display.fbc_mask & BIT(__fbc_id)) #define for_each_intel_fbc(__dev_priv, __fbc, __fbc_id) \ - for_each_fbc_id(__fbc_id) \ + for_each_fbc_id((__dev_priv), (__fbc_id)) \ for_each_if((__fbc) = (__dev_priv)->fbc[(__fbc_id)]) struct intel_fbc_funcs { @@ -1693,32 +1694,35 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915, */ void intel_fbc_init(struct drm_i915_private *i915) { - struct intel_fbc *fbc; + enum intel_fbc_id fbc_id; if (!drm_mm_initialized(&i915->mm.stolen)) - mkwrite_device_info(i915)->display.has_fbc = false; + mkwrite_device_info(i915)->display.fbc_mask = 0; if (need_fbc_vtd_wa(i915)) - mkwrite_device_info(i915)->display.has_fbc = false; + mkwrite_device_info(i915)->display.fbc_mask = 0; i915->params.enable_fbc = intel_sanitize_fbc_option(i915); drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n", i915->params.enable_fbc); - if (!HAS_FBC(i915)) - return; + for_each_fbc_id(i915, fbc_id) { + struct intel_fbc *fbc; - fbc = intel_fbc_create(i915, INTEL_FBC_A); - if (!fbc) - return; + fbc = intel_fbc_create(i915, fbc_id); + if (!fbc) + continue; - /* 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); + /* + * 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->id] = fbc; + i915->fbc[fbc->id] = fbc; + } } static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 3db57cd7474b..158d89b8d490 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1816,20 +1816,27 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state, return 0; } +static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe) +{ + return pipe - PIPE_A + INTEL_FBC_A; +} + static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, - enum pipe pipe, enum plane_id plane_id) + enum intel_fbc_id fbc_id, enum plane_id plane_id) { - if (!HAS_FBC(dev_priv)) + if ((INTEL_INFO(dev_priv)->display.fbc_mask & BIT(fbc_id)) == 0) return false; - return pipe == PIPE_A && plane_id == PLANE_PRIMARY; + return plane_id == PLANE_PRIMARY; } 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[INTEL_FBC_A]; + enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(pipe); + + if (skl_plane_has_fbc(dev_priv, fbc_id, plane_id)) + return dev_priv->fbc[fbc_id]; else return NULL; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5eaa6ac3eeeb..23e2a1bcc257 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1478,7 +1478,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define I915_HAS_HOTPLUG(dev_priv) (INTEL_INFO(dev_priv)->display.has_hotplug) #define HAS_FW_BLC(dev_priv) (GRAPHICS_VER(dev_priv) > 2) -#define HAS_FBC(dev_priv) (INTEL_INFO(dev_priv)->display.has_fbc) +#define HAS_FBC(dev_priv) (INTEL_INFO(dev_priv)->display.fbc_mask != 0) #define HAS_CUR_FBC(dev_priv) (!HAS_GMCH(dev_priv) && GRAPHICS_VER(dev_priv) >= 7) #define HAS_IPS(dev_priv) (IS_HSW_ULT(dev_priv) || IS_BROADWELL(dev_priv)) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index eeee028a5ad7..12e331f5fa57 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -214,13 +214,13 @@ static const struct intel_device_info i845g_info = { static const struct intel_device_info i85x_info = { I830_FEATURES, PLATFORM(INTEL_I85X), - .display.has_fbc = 1, + .display.fbc_mask = BIT(INTEL_FBC_A), }; static const struct intel_device_info i865g_info = { I845_FEATURES, PLATFORM(INTEL_I865G), - .display.has_fbc = 1, + .display.fbc_mask = BIT(INTEL_FBC_A), }; #define GEN3_FEATURES \ @@ -258,7 +258,7 @@ static const struct intel_device_info i915gm_info = { .display.has_overlay = 1, .display.overlay_needs_physical = 1, .display.supports_tv = 1, - .display.has_fbc = 1, + .display.fbc_mask = BIT(INTEL_FBC_A), .hws_needs_physical = 1, .unfenced_needs_alignment = 1, }; @@ -283,7 +283,7 @@ static const struct intel_device_info i945gm_info = { .display.has_overlay = 1, .display.overlay_needs_physical = 1, .display.supports_tv = 1, - .display.has_fbc = 1, + .display.fbc_mask = BIT(INTEL_FBC_A), .hws_needs_physical = 1, .unfenced_needs_alignment = 1, }; @@ -342,7 +342,7 @@ static const struct intel_device_info i965gm_info = { GEN4_FEATURES, PLATFORM(INTEL_I965GM), .is_mobile = 1, - .display.has_fbc = 1, + .display.fbc_mask = BIT(INTEL_FBC_A), .display.has_overlay = 1, .display.supports_tv = 1, .hws_needs_physical = 1, @@ -360,7 +360,7 @@ static const struct intel_device_info gm45_info = { GEN4_FEATURES, PLATFORM(INTEL_GM45), .is_mobile = 1, - .display.has_fbc = 1, + .display.fbc_mask = BIT(INTEL_FBC_A), .display.supports_tv = 1, .platform_engine_mask = BIT(RCS0) | BIT(VCS0), .gpu_reset_clobbers_display = false, @@ -393,7 +393,7 @@ static const struct intel_device_info ilk_m_info = { PLATFORM(INTEL_IRONLAKE), .is_mobile = 1, .has_rps = true, - .display.has_fbc = 1, + .display.fbc_mask = BIT(INTEL_FBC_A), }; #define GEN6_FEATURES \ @@ -401,7 +401,7 @@ static const struct intel_device_info ilk_m_info = { .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, \ + .display.fbc_mask = BIT(INTEL_FBC_A), \ .platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \ .has_coherent_ggtt = true, \ .has_llc = 1, \ @@ -452,7 +452,7 @@ static const struct intel_device_info snb_m_gt2_info = { .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, \ + .display.fbc_mask = BIT(INTEL_FBC_A), \ .platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \ .has_coherent_ggtt = true, \ .has_llc = 1, \ @@ -693,7 +693,7 @@ static const struct intel_device_info skl_gt4_info = { .has_64bit_reloc = 1, \ .display.has_ddi = 1, \ .display.has_fpga_dbg = 1, \ - .display.has_fbc = 1, \ + .display.fbc_mask = BIT(INTEL_FBC_A), \ .display.has_hdcp = 1, \ .display.has_psr = 1, \ .display.has_psr_hw_tracking = 1, \ @@ -948,7 +948,7 @@ static const struct intel_device_info adl_s_info = { .display.has_dp_mst = 1, \ .display.has_dsb = 1, \ .display.has_dsc = 1, \ - .display.has_fbc = 1, \ + .display.fbc_mask = BIT(INTEL_FBC_A), \ .display.has_fpga_dbg = 1, \ .display.has_hdcp = 1, \ .display.has_hotplug = 1, \ diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index cbe9972478ac..bb7d37b70626 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -335,6 +335,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) "Display fused off, disabling\n"); info->display.pipe_mask = 0; info->display.cpu_transcoder_mask = 0; + info->display.fbc_mask = 0; } else if (fuse_strap & IVB_PIPE_C_DISABLE) { drm_info(&dev_priv->drm, "PipeC fused off\n"); info->display.pipe_mask &= ~BIT(PIPE_C); @@ -346,6 +347,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) if (dfsm & SKL_DFSM_PIPE_A_DISABLE) { info->display.pipe_mask &= ~BIT(PIPE_A); info->display.cpu_transcoder_mask &= ~BIT(TRANSCODER_A); + info->display.fbc_mask &= ~BIT(INTEL_FBC_A); } if (dfsm & SKL_DFSM_PIPE_B_DISABLE) { info->display.pipe_mask &= ~BIT(PIPE_B); @@ -366,7 +368,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) info->display.has_hdcp = 0; if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE) - info->display.has_fbc = 0; + info->display.fbc_mask = 0; if (DISPLAY_VER(dev_priv) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE)) info->display.has_dmc = 0; diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index c121d7309dd2..7cef02f5ce65 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -155,7 +155,6 @@ enum intel_ppgtt_type { func(has_dp_mst); \ func(has_dsb); \ func(has_dsc); \ - func(has_fbc); \ func(has_fpga_dbg); \ func(has_gmch); \ func(has_hdcp); \ @@ -201,6 +200,7 @@ struct intel_device_info { u8 pipe_mask; u8 cpu_transcoder_mask; + u8 fbc_mask; u8 abox_mask; #define DEFINE_FLAG(name) u8 name:1 -- cgit v1.2.3 From e74c6aa955caedd06b5ade58e31e33338e4efde6 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Dec 2021 17:14:35 +0200 Subject: drm/i915/fbc: Register per-crtc debugfs files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose FBC debugfs files for each crtc. These may or may not point to the same FBC instance depending on the platform. We leave the old global debugfs files in place until igt catches up to the new per-crtc approach. v2: Take a trip via intel_crtc_debugfs_add() (Jani) Cc: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211213151435.9700-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_debugfs.c | 7 +++-- drivers/gpu/drm/i915/display/intel_fbc.c | 31 +++++++++++++--------- drivers/gpu/drm/i915/display/intel_fbc.h | 1 + 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 572445299b04..f4de004d470f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -2402,6 +2402,9 @@ void intel_connector_debugfs_add(struct intel_connector *intel_connector) */ void intel_crtc_debugfs_add(struct drm_crtc *crtc) { - if (crtc->debugfs_entry) - crtc_updates_add(crtc); + if (!crtc->debugfs_entry) + return; + + crtc_updates_add(crtc); + intel_fbc_crtc_debugfs_add(to_intel_crtc(crtc)); } diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 796453e1c101..8b9acedcdfc1 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1798,25 +1798,32 @@ DEFINE_SIMPLE_ATTRIBUTE(intel_fbc_debugfs_false_color_fops, intel_fbc_debugfs_false_color_set, "%llu\n"); -static void intel_fbc_debugfs_add(struct intel_fbc *fbc) +static void intel_fbc_debugfs_add(struct intel_fbc *fbc, + struct dentry *parent) { - struct drm_i915_private *i915 = fbc->i915; - struct drm_minor *minor = i915->drm.primary; - - debugfs_create_file("i915_fbc_status", 0444, - minor->debugfs_root, fbc, - &intel_fbc_debugfs_status_fops); + debugfs_create_file("i915_fbc_status", 0444, parent, + fbc, &intel_fbc_debugfs_status_fops); if (fbc->funcs->set_false_color) - debugfs_create_file("i915_fbc_false_color", 0644, - minor->debugfs_root, fbc, - &intel_fbc_debugfs_false_color_fops); + debugfs_create_file("i915_fbc_false_color", 0644, parent, + fbc, &intel_fbc_debugfs_false_color_fops); } +void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc) +{ + struct intel_plane *plane = to_intel_plane(crtc->base.primary); + + if (plane->fbc) + intel_fbc_debugfs_add(plane->fbc, crtc->base.debugfs_entry); +} + +/* FIXME: remove this once igt is on board with per-crtc stuff */ void intel_fbc_debugfs_register(struct drm_i915_private *i915) { - struct intel_fbc *fbc = i915->fbc[INTEL_FBC_A]; + struct drm_minor *minor = i915->drm.primary; + struct intel_fbc *fbc; + fbc = i915->fbc[INTEL_FBC_A]; if (fbc) - intel_fbc_debugfs_add(fbc); + intel_fbc_debugfs_add(fbc, minor->debugfs_root); } diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h index 7b7631aec527..8c5a7339a27f 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.h +++ b/drivers/gpu/drm/i915/display/intel_fbc.h @@ -42,6 +42,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane); void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915); void intel_fbc_reset_underrun(struct drm_i915_private *i915); +void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc); void intel_fbc_debugfs_register(struct drm_i915_private *i915); #endif /* __INTEL_FBC_H__ */ -- cgit v1.2.3 From 637088a21e204b129a03dbd59bc0cd80d0292651 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 21 Nov 2021 12:00:32 +0100 Subject: drm/i915/backlight: Make ext_pwm_disable_backlight() call intel_backlight_set_pwm_level() At least the Bay Trail LPSS PWM controller used with DSI panels on many Bay Trail tablets seems to leave the PWM pin in whatever state it was (high or low) ATM that the PWM gets disabled. Combined with some panels not having a separate backlight-enable pin this leads to the backlight sometimes staying on while it should not (when the pin was high during PWM-disabling). First calling intel_backlight_set_pwm_level() will ensure that the pin is always low (or high for inverted brightness panels) since the passed in duty-cycle is 0% (or 100%) when the PWM gets disabled fixing the backlight sometimes staying on. With the exception of ext_pwm_disable_backlight() all other foo_disable_backlight() functions call intel_backlight_set_pwm_level() already before disabling the backlight, so this change also aligns ext_pwm_disable_backlight() with all the other disable() functions. Signed-off-by: Hans de Goede Acked-by: Jani Nikula Reviewed-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20211121110032.4720-2-hdegoede@redhat.com --- drivers/gpu/drm/i915/display/intel_backlight.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 9523411cddd8..2db3b792aca6 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -433,6 +433,8 @@ static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct intel_panel *panel = &connector->panel; + intel_backlight_set_pwm_level(old_conn_state, level); + panel->backlight.pwm_state.enabled = false; pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); } -- cgit v1.2.3 From d0c0cf22d7071e9ba8d30be91723e1d997a07970 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 21 Nov 2021 20:10:01 +0100 Subject: drm/i915: Remove unused intel_gmbus_set_speed() function The intel_gmbus_set_speed() function is not used anywhere, remove it. Note drivers/gpu/drm/gma500 has its own copy called gma_intel_gmbus_set_speed() which is used, the intel_gmbus_set_speed() version in the i915 code is not used at all Signed-off-by: Hans de Goede Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20211121191001.252076-1-hdegoede@redhat.com --- drivers/gpu/drm/i915/display/intel_gmbus.c | 7 ------- drivers/gpu/drm/i915/display/intel_gmbus.h | 1 - 2 files changed, 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c index 3b8b84177085..6ce8c10fe975 100644 --- a/drivers/gpu/drm/i915/display/intel_gmbus.c +++ b/drivers/gpu/drm/i915/display/intel_gmbus.c @@ -931,13 +931,6 @@ struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, return &dev_priv->gmbus[pin].adapter; } -void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed) -{ - struct intel_gmbus *bus = to_intel_gmbus(adapter); - - bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | speed; -} - void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit) { struct intel_gmbus *bus = to_intel_gmbus(adapter); diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.h b/drivers/gpu/drm/i915/display/intel_gmbus.h index b96212b85425..8edc2e99cf53 100644 --- a/drivers/gpu/drm/i915/display/intel_gmbus.h +++ b/drivers/gpu/drm/i915/display/intel_gmbus.h @@ -41,7 +41,6 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter); struct i2c_adapter * intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, unsigned int pin); -void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed); void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit); bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter); void intel_gmbus_reset(struct drm_i915_private *dev_priv); -- cgit v1.2.3 From a36e7dc0af1cc7e5eaa89136c35a5305fd693731 Mon Sep 17 00:00:00 2001 From: Clint Taylor Date: Wed, 15 Dec 2021 22:26:45 -0800 Subject: drm/i915/dg1: Read OPROM via SPI controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Read OPROM SPI through MMIO and find VBT entry since we can't use OpRegion and PCI mapping may not work on some systems due to most BIOSes not leaving the Option ROM mapped. v2: Remove message with allocation failure Cc: Ville Syrjälä Cc: Tomas Winkler Signed-off-by: Clint Taylor Signed-off-by: Lucas De Marchi Signed-off-by: Jani Nikula Acked-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20211216062645.3477854-1-lucas.demarchi@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 77 ++++++++++++++++++++++++++++--- drivers/gpu/drm/i915/i915_reg.h | 8 ++++ 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 9d989c9f5da4..76a8f001f4c4 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -2335,6 +2335,63 @@ bool intel_bios_is_valid_vbt(const void *buf, size_t size) return vbt; } +static struct vbt_header *spi_oprom_get_vbt(struct drm_i915_private *i915) +{ + u32 count, data, found, store = 0; + u32 static_region, oprom_offset; + u32 oprom_size = 0x200000; + u16 vbt_size; + u32 *vbt; + + static_region = intel_uncore_read(&i915->uncore, SPI_STATIC_REGIONS); + static_region &= OPTIONROM_SPI_REGIONID_MASK; + intel_uncore_write(&i915->uncore, PRIMARY_SPI_REGIONID, static_region); + + oprom_offset = intel_uncore_read(&i915->uncore, OROM_OFFSET); + oprom_offset &= OROM_OFFSET_MASK; + + for (count = 0; count < oprom_size; count += 4) { + intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, oprom_offset + count); + data = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER); + + if (data == *((const u32 *)"$VBT")) { + found = oprom_offset + count; + break; + } + } + + if (count >= oprom_size) + goto err_not_found; + + /* Get VBT size and allocate space for the VBT */ + intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, found + + offsetof(struct vbt_header, vbt_size)); + vbt_size = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER); + vbt_size &= 0xffff; + + vbt = kzalloc(vbt_size, GFP_KERNEL); + if (!vbt) + goto err_not_found; + + for (count = 0; count < vbt_size; count += 4) { + intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, found + count); + data = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER); + *(vbt + store++) = data; + } + + if (!intel_bios_is_valid_vbt(vbt, vbt_size)) + goto err_free_vbt; + + drm_dbg_kms(&i915->drm, "Found valid VBT in SPI flash\n"); + + return (struct vbt_header *)vbt; + +err_free_vbt: + kfree(vbt); +err_not_found: + return NULL; +} + static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915) { struct pci_dev *pdev = to_pci_dev(i915->drm.dev); @@ -2384,6 +2441,8 @@ static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915) pci_unmap_rom(pdev, oprom); + drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n"); + return vbt; err_free_vbt: @@ -2418,17 +2477,23 @@ void intel_bios_init(struct drm_i915_private *i915) init_vbt_defaults(i915); - /* If the OpRegion does not have VBT, look in PCI ROM. */ + /* + * If the OpRegion does not have VBT, look in SPI flash through MMIO or + * PCI mapping + */ + if (!vbt && IS_DGFX(i915)) { + oprom_vbt = spi_oprom_get_vbt(i915); + vbt = oprom_vbt; + } + if (!vbt) { oprom_vbt = oprom_get_vbt(i915); - if (!oprom_vbt) - goto out; - vbt = oprom_vbt; - - drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n"); } + if (!vbt) + goto out; + bdb = get_bdb_header(vbt); i915->vbt.version = bdb->version; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8528db258827..5b502c8f0cfb 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -12853,6 +12853,14 @@ enum skl_power_gate { #define TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT REG_BIT(1) #define TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT REG_BIT(0) +#define PRIMARY_SPI_TRIGGER _MMIO(0x102040) +#define PRIMARY_SPI_ADDRESS _MMIO(0x102080) +#define PRIMARY_SPI_REGIONID _MMIO(0x102084) +#define SPI_STATIC_REGIONS _MMIO(0x102090) +#define OPTIONROM_SPI_REGIONID_MASK REG_GENMASK(7, 0) +#define OROM_OFFSET _MMIO(0x1020c0) +#define OROM_OFFSET_MASK REG_GENMASK(20, 16) + /* This register controls the Display State Buffer (DSB) engines. */ #define _DSBSL_INSTANCE_BASE 0x70B00 #define DSBSL_INSTANCE(pipe, id) (_DSBSL_INSTANCE_BASE + \ -- cgit v1.2.3 From 7e28d0b26759846485978ada860ef4a427e06c8f Mon Sep 17 00:00:00 2001 From: Tejas Upadhyay Date: Fri, 10 Dec 2021 10:48:02 +0530 Subject: drm/i915/adl-n: Enable ADL-N platform Adding PCI device ids and enabling ADL-N platform. ADL-N from i915 point of view is subplatform of ADL-P. BSpec: 68397 Changes since V2: - Added version log history Changes since V1: - replace IS_ALDERLAKE_N with IS_ADLP_N - Jani Nikula Signed-off-by: Tejas Upadhyay Reviewed-by: Anusha Srivatsa Acked-by: Thomas Gleixner Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20211210051802.4063958-1-tejaskumarx.surendrakumar.upadhyay@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 | 6 ++++++ 6 files changed, 20 insertions(+) diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index fd2d3ab38ebb..1ca3a56fdc2d 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_ADLN_IDS(&gen11_early_ops), INTEL_RPLS_IDS(&gen11_early_ops), }; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 23e2a1bcc257..b7d6402ef6d6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1267,6 +1267,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, 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_ADLP_N(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_N) #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 12e331f5fa57..960c358990bc 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -1129,6 +1129,7 @@ static const struct pci_device_id pciidlist[] = { INTEL_RKL_IDS(&rkl_info), INTEL_ADLS_IDS(&adl_s_info), INTEL_ADLP_IDS(&adl_p_info), + INTEL_ADLN_IDS(&adl_p_info), INTEL_DG1_IDS(&dg1_info), INTEL_RPLS_IDS(&adl_s_info), {0, 0, 0} diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index bb7d37b70626..24e05f1ef486 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_n_ids[] = { + INTEL_ADLN_IDS(0), +}; + static const u16 subplatform_rpls_ids[] = { INTEL_RPLS_IDS(0), }; @@ -217,6 +221,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_n_ids, + ARRAY_SIZE(subplatform_n_ids))) { + mask = BIT(INTEL_SUBPLATFORM_N); } else if (find_devid(devid, subplatform_rpls_ids, ARRAY_SIZE(subplatform_rpls_ids))) { mask = BIT(INTEL_SUBPLATFORM_RPL_S); diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 7cef02f5ce65..2a4e32b4ebfd 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -113,6 +113,9 @@ enum intel_platform { /* ADL-S */ #define INTEL_SUBPLATFORM_RPL_S 0 +/* ADL-P */ +#define INTEL_SUBPLATFORM_N 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 baf3d1d3d566..533890dc9da1 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -666,6 +666,12 @@ INTEL_VGA_DEVICE(0x46C2, info), \ INTEL_VGA_DEVICE(0x46C3, info) +/* ADL-N */ +#define INTEL_ADLN_IDS(info) \ + INTEL_VGA_DEVICE(0x46D0, info), \ + INTEL_VGA_DEVICE(0x46D1, info), \ + INTEL_VGA_DEVICE(0x46D2, info) + /* RPL-S */ #define INTEL_RPLS_IDS(info) \ INTEL_VGA_DEVICE(0xA780, info), \ -- cgit v1.2.3 From 825ca9ed1c9f5516b30292bb1c7ab648c2a01b92 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 21 Dec 2021 21:37:53 +0200 Subject: drm: Always include the debugfs dentry in drm_crtc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the counterproductive CONFIG_DEBUG_FS ifdef and just include the debugfs dentry in drm_crtc always. This way we don't need annoying ifdefs in the actual code with DEBUGFS=n. Also we don't have these ifdefs around any of the other debugfs dentries either so can't see why drm_crtc should be special. This fixes the i915 DEBUGFS=n build because I assumed the dentry would always be there. Cc: Jani Nikula Reported-by: Nathan Chancellor Tested-by: Nathan Chancellor Fixes: e74c6aa955ca ("drm/i915/fbc: Register per-crtc debugfs files") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211221193754.12287-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula Acked-by: Daniel Vetter --- include/drm/drm_crtc.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 13eeba2a750a..4d01b4d89775 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1135,14 +1135,12 @@ struct drm_crtc { */ spinlock_t commit_lock; -#ifdef CONFIG_DEBUG_FS /** * @debugfs_entry: * * Debugfs directory for this CRTC. */ struct dentry *debugfs_entry; -#endif /** * @crc: -- cgit v1.2.3 From 980f42e7d57464af190d05b9cc0bc21846734f48 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 22 Dec 2021 10:16:54 +0200 Subject: drm/i915/bios: fix slab-out-of-bounds access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If VBT size is not a multiple of 4, the last 4-byte store will be out of bounds of the allocated buffer. Spotted with KASAN. Round up the allocation size. v2: Use round_up() intead of roundup() as it's a power of 2 (Thomas) Reported-by: Thomas Hellström Fixes: a36e7dc0af1c ("drm/i915/dg1: Read OPROM via SPI controller") Cc: Clint Taylor Cc: Lucas De Marchi Reviewed-by: Thomas Hellström Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20211222081654.1843211-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 76a8f001f4c4..c7a8d517ce81 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -2369,7 +2369,7 @@ static struct vbt_header *spi_oprom_get_vbt(struct drm_i915_private *i915) vbt_size = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER); vbt_size &= 0xffff; - vbt = kzalloc(vbt_size, GFP_KERNEL); + vbt = kzalloc(round_up(vbt_size, 4), GFP_KERNEL); if (!vbt) goto err_not_found; -- cgit v1.2.3 From 798c5daf3cddff3f39c5542a50a2dbd83879b05d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 16 Dec 2021 13:08:22 +0200 Subject: drm/i915/fbc: Remember to update FBC state even when not reallocating CFB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We mustn't forget to update our FBC state even if we don't have to reallocate the CFB. Otherwise we won't refresh our notion of what eg. the new fence or the new override CFB stride should be. Using the wrong CFB stride in particular can cause underruns and could even corrupt other stuff in stolen. Fixes: f4cfdbb02ca8 ("drm/i915/fbc: Nuke state_cache") Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/4774 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211216110822.8461-1-ville.syrjala@linux.intel.com Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/display/intel_fbc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 8b9acedcdfc1..7fd11d735ca4 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1408,8 +1408,10 @@ static void __intel_fbc_enable(struct intel_atomic_state *state, if (fbc->state.plane != plane) return; - if (intel_fbc_is_ok(plane_state)) + if (intel_fbc_is_ok(plane_state)) { + intel_fbc_update_state(state, crtc, plane); return; + } __intel_fbc_disable(fbc); } -- cgit v1.2.3 From f7747be1410321de8a92e340c5ca6c18a59770e9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 22 Dec 2021 17:40:33 +0200 Subject: drm/i915/dsi: Drop double check ACPI companion device for NULL acpi_dev_get_resources() does perform the NULL pointer check against ACPI companion device which is given as function parameter. Thus, there is no need to duplicate this check in the caller. Signed-off-by: Andy Shevchenko Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20211222154033.6770-1-andriy.shevchenko@linux.intel.com --- drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c index 0da91849efde..da0bd056f3d3 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c @@ -426,24 +426,16 @@ static void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi, const u16 slave_addr) { struct drm_device *drm_dev = intel_dsi->base.base.dev; - struct device *dev = drm_dev->dev; - struct acpi_device *acpi_dev; - struct list_head resource_list; - struct i2c_adapter_lookup lookup; - - acpi_dev = ACPI_COMPANION(dev); - if (acpi_dev) { - memset(&lookup, 0, sizeof(lookup)); - lookup.slave_addr = slave_addr; - lookup.intel_dsi = intel_dsi; - lookup.dev_handle = acpi_device_handle(acpi_dev); - - INIT_LIST_HEAD(&resource_list); - acpi_dev_get_resources(acpi_dev, &resource_list, - i2c_adapter_lookup, - &lookup); - acpi_dev_free_resource_list(&resource_list); - } + struct acpi_device *adev = ACPI_COMPANION(drm_dev->dev); + struct i2c_adapter_lookup lookup = { + .slave_addr = slave_addr, + .intel_dsi = intel_dsi, + .dev_handle = acpi_device_handle(adev), + }; + LIST_HEAD(resource_list); + + acpi_dev_get_resources(adev, &resource_list, i2c_adapter_lookup, &lookup); + acpi_dev_free_resource_list(&resource_list); } #else static inline void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi, -- cgit v1.2.3 From e35d8762b04f89f9f5a188d0c440d3a2c1d010ed Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Wed, 29 Dec 2021 23:21:59 +0100 Subject: drm/i915/opregion: add support for mailbox #5 EDID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ACPI OpRegion Mailbox #5 ASLE extension may contain an EDID to be used for the embedded display. Add support for using it via by adding the EDID to the list of available modes on the connector, and use it for eDP when available. If a panel's EDID is broken, there may be an override EDID set in the ACPI OpRegion mailbox #5. Use it if available. Fixes the GPD Win Max display. Based on original patch series by: Jani Nikula https://patchwork.kernel.org/project/intel-gfx/patch/20200828061941.17051-1-jani.nikula@intel.com/ Changes: - EDID is copied and validated with drm_edid_is_valid - EDID is now only used as a fallback. - squashed the two patches Cc: Jani Nikula Cc: Uma Shankar Cc: Ville Syrjälä Co-developed-by: Jani Nikula Signed-off-by: Jani Nikula Signed-off-by: Anisse Astier Link: https://patchwork.freedesktop.org/patch/msgid/20211229222200.53128-2-anisse@astier.eu --- drivers/gpu/drm/i915/display/intel_dp.c | 8 ++++ drivers/gpu/drm/i915/display/intel_opregion.c | 55 ++++++++++++++++++++++++++- drivers/gpu/drm/i915/display/intel_opregion.h | 10 +++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index b5e2508db1cf..d6d8c9922feb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4974,6 +4974,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, mutex_lock(&dev->mode_config.mutex); edid = drm_get_edid(connector, &intel_dp->aux.ddc); + if (!edid) { + /* Fallback to EDID from ACPI OpRegion, if any */ + edid = intel_opregion_get_edid(intel_connector); + if (edid) + drm_dbg_kms(&dev_priv->drm, + "[CONNECTOR:%d:%s] Using OpRegion EDID\n", + connector->base.id, connector->name); + } if (edid) { if (drm_add_edid_modes(connector, edid)) { drm_connector_update_edid_property(connector, edid); diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index 0065111593a6..985790a66a4d 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -195,6 +195,8 @@ struct opregion_asle_ext { #define ASLE_IUER_WINDOWS_BTN (1 << 1) #define ASLE_IUER_POWER_BTN (1 << 0) +#define ASLE_PHED_EDID_VALID_MASK 0x3 + /* Software System Control Interrupt (SWSCI) */ #define SWSCI_SCIC_INDICATOR (1 << 0) #define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1 @@ -908,8 +910,10 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv) opregion->asle->ardy = ASLE_ARDY_NOT_READY; } - if (mboxes & MBOX_ASLE_EXT) + if (mboxes & MBOX_ASLE_EXT) { drm_dbg(&dev_priv->drm, "ASLE extension supported\n"); + opregion->asle_ext = base + OPREGION_ASLE_EXT_OFFSET; + } if (intel_load_vbt_firmware(dev_priv) == 0) goto out; @@ -1036,6 +1040,54 @@ intel_opregion_get_panel_type(struct drm_i915_private *dev_priv) return ret - 1; } +/** + * intel_opregion_get_edid - Fetch EDID from ACPI OpRegion mailbox #5 + * @intel_connector: eDP connector + * + * This reads the ACPI Opregion mailbox #5 to extract the EDID that is passed + * to it. + * + * Returns: + * The EDID in the OpRegion, or NULL if there is none or it's invalid. + * + */ +struct edid *intel_opregion_get_edid(struct intel_connector *intel_connector) +{ + struct drm_connector *connector = &intel_connector->base; + struct drm_i915_private *i915 = to_i915(connector->dev); + struct intel_opregion *opregion = &i915->opregion; + const void *in_edid; + const struct edid *edid; + struct edid *new_edid; + int len; + + if (!opregion->asle_ext) + return NULL; + + in_edid = opregion->asle_ext->bddc; + + /* Validity corresponds to number of 128-byte blocks */ + len = (opregion->asle_ext->phed & ASLE_PHED_EDID_VALID_MASK) * 128; + if (!len || !memchr_inv(in_edid, 0, len)) + return NULL; + + edid = in_edid; + + if (len < EDID_LENGTH * (1 + edid->extensions)) { + drm_dbg_kms(&i915->drm, "Invalid EDID in ACPI OpRegion (Mailbox #5): too short\n"); + return NULL; + } + new_edid = drm_edid_duplicate(edid); + if (!new_edid) + return NULL; + if (!drm_edid_is_valid(new_edid)) { + kfree(new_edid); + drm_dbg_kms(&i915->drm, "Invalid EDID in ACPI OpRegion (Mailbox #5)\n"); + return NULL; + } + return new_edid; +} + void intel_opregion_register(struct drm_i915_private *i915) { struct intel_opregion *opregion = &i915->opregion; @@ -1129,6 +1181,7 @@ void intel_opregion_unregister(struct drm_i915_private *i915) opregion->acpi = NULL; opregion->swsci = NULL; opregion->asle = NULL; + opregion->asle_ext = NULL; opregion->vbt = NULL; opregion->lid_state = NULL; } diff --git a/drivers/gpu/drm/i915/display/intel_opregion.h b/drivers/gpu/drm/i915/display/intel_opregion.h index 4aa68ffbd30e..82cc0ba34af7 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.h +++ b/drivers/gpu/drm/i915/display/intel_opregion.h @@ -29,12 +29,14 @@ #include struct drm_i915_private; +struct intel_connector; struct intel_encoder; struct opregion_header; struct opregion_acpi; struct opregion_swsci; struct opregion_asle; +struct opregion_asle_ext; struct intel_opregion { struct opregion_header *header; @@ -43,6 +45,7 @@ struct intel_opregion { u32 swsci_gbda_sub_functions; u32 swsci_sbcb_sub_functions; struct opregion_asle *asle; + struct opregion_asle_ext *asle_ext; void *rvda; void *vbt_firmware; const void *vbt; @@ -71,6 +74,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, int intel_opregion_notify_adapter(struct drm_i915_private *dev_priv, pci_power_t state); int intel_opregion_get_panel_type(struct drm_i915_private *dev_priv); +struct edid *intel_opregion_get_edid(struct intel_connector *connector); #else /* CONFIG_ACPI*/ @@ -117,6 +121,12 @@ static inline int intel_opregion_get_panel_type(struct drm_i915_private *dev) return -ENODEV; } +static inline struct edid * +intel_opregion_get_edid(struct intel_connector *connector) +{ + return NULL; +} + #endif /* CONFIG_ACPI */ #endif -- cgit v1.2.3 From 0b464ca3e0dd3cec65f28bc6d396d82f19080f69 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Wed, 29 Dec 2021 23:22:00 +0100 Subject: drm: Add orientation quirk for GPD Win Max Panel is 800x1280, but mounted on a laptop form factor, sideways. Signed-off-by: Anisse Astier Reviewed-by: Hans de Goede Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20211229222200.53128-3-anisse@astier.eu --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 042bb80383c9..3dc383b1e2ba 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -174,6 +174,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MicroPC"), }, .driver_data = (void *)&lcd720x1280_rightside_up, + }, { /* GPD Win Max */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1619-01"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* * GPD Pocket, note that the the DMI data is less generic then * it seems, devices with a board-vendor of "AMI Corporation" -- cgit v1.2.3 From 80dfdeb75028084f42a81a4151a986c56aeec1c1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 5 Jan 2022 12:21:31 +0200 Subject: drm/i915: stop including i915_irq.h from i915_drv.h Only include i915_irq.h where actually needed. Signed-off-by: Jani Nikula Acked-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20220105102131.988791-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_crtc.c | 1 + drivers/gpu/drm/i915/display/intel_display_trace.h | 1 + drivers/gpu/drm/i915/gt/intel_rps.c | 1 + drivers/gpu/drm/i915/gt/uc/intel_guc.c | 1 + drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 1 - 6 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 16c3ca66d9f0..08ee3e17ee5c 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -12,6 +12,7 @@ #include #include +#include "i915_irq.h" #include "i915_vgpu.h" #include "i9xx_plane.h" #include "icl_dsi.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h index 4043e1276383..f05f0f9b5103 100644 --- a/drivers/gpu/drm/i915/display/intel_display_trace.h +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -13,6 +13,7 @@ #include #include "i915_drv.h" +#include "i915_irq.h" #include "intel_crtc.h" #include "intel_display_types.h" diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index 5e275f8dda8c..8f5bce298574 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.c +++ b/drivers/gpu/drm/i915/gt/intel_rps.c @@ -6,6 +6,7 @@ #include #include "i915_drv.h" +#include "i915_irq.h" #include "intel_breadcrumbs.h" #include "intel_gt.h" #include "intel_gt_clock_utils.h" diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c index 6e228343e8cb..0c52d1652e8b 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c @@ -12,6 +12,7 @@ #include "intel_guc_ads.h" #include "intel_guc_submission.h" #include "i915_drv.h" +#include "i915_irq.h" /** * DOC: GuC diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c index ac0931f0374b..7b0b43e87244 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c @@ -7,6 +7,7 @@ #include "gt/intel_gt.h" #include "i915_drv.h" +#include "i915_irq.h" #include "i915_memcpy.h" #include "intel_guc_log.h" diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b7d6402ef6d6..c7ce23da6ffa 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -106,7 +106,6 @@ #include "i915_scheduler.h" #include "gt/intel_timeline.h" #include "i915_vma.h" -#include "i915_irq.h" /* General customization: -- cgit v1.2.3