Commit fd5a9b95 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915/fbc: Convert to intel_display, mostly

Switch the FBC code over to intel_display from i915, as
much as possible. This is the future direction so that
the display code can be shared between i915 and xe more
cleanly.

Some of the platform checks and the stolen mem facing stiff
still need i915 around though.

v2: Drop some redundant to_i915() casts
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240705145254.3355-3-ville.syrjala@linux.intel.comReviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent bc34d310
...@@ -1008,7 +1008,7 @@ i915_fifo_underrun_reset_write(struct file *filp, ...@@ -1008,7 +1008,7 @@ i915_fifo_underrun_reset_write(struct file *filp,
return ret; return ret;
} }
intel_fbc_reset_underrun(dev_priv); intel_fbc_reset_underrun(&dev_priv->display);
return cnt; return cnt;
} }
...@@ -1063,7 +1063,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915) ...@@ -1063,7 +1063,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915)
intel_bios_debugfs_register(i915); intel_bios_debugfs_register(i915);
intel_cdclk_debugfs_register(i915); intel_cdclk_debugfs_register(i915);
intel_dmc_debugfs_register(i915); intel_dmc_debugfs_register(i915);
intel_fbc_debugfs_register(i915); intel_fbc_debugfs_register(&i915->display);
intel_hpd_debugfs_register(i915); intel_hpd_debugfs_register(i915);
intel_opregion_debugfs_register(i915); intel_opregion_debugfs_register(i915);
intel_psr_debugfs_register(i915); intel_psr_debugfs_register(i915);
......
...@@ -265,7 +265,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915) ...@@ -265,7 +265,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
intel_init_quirks(display); intel_init_quirks(display);
intel_fbc_init(i915); intel_fbc_init(display);
return 0; return 0;
...@@ -607,7 +607,7 @@ void intel_display_driver_remove_noirq(struct drm_i915_private *i915) ...@@ -607,7 +607,7 @@ void intel_display_driver_remove_noirq(struct drm_i915_private *i915)
destroy_workqueue(i915->display.wq.flip); destroy_workqueue(i915->display.wq.flip);
destroy_workqueue(i915->display.wq.modeset); destroy_workqueue(i915->display.wq.modeset);
intel_fbc_cleanup(i915); intel_fbc_cleanup(&i915->display);
} }
/* part #3: call after gem init */ /* part #3: call after gem init */
......
...@@ -60,13 +60,13 @@ ...@@ -60,13 +60,13 @@
#include "intel_fbc_regs.h" #include "intel_fbc_regs.h"
#include "intel_frontbuffer.h" #include "intel_frontbuffer.h"
#define for_each_fbc_id(__dev_priv, __fbc_id) \ #define for_each_fbc_id(__display, __fbc_id) \
for ((__fbc_id) = INTEL_FBC_A; (__fbc_id) < I915_MAX_FBCS; (__fbc_id)++) \ for ((__fbc_id) = INTEL_FBC_A; (__fbc_id) < I915_MAX_FBCS; (__fbc_id)++) \
for_each_if(DISPLAY_RUNTIME_INFO(__dev_priv)->fbc_mask & BIT(__fbc_id)) for_each_if(DISPLAY_RUNTIME_INFO(__display)->fbc_mask & BIT(__fbc_id))
#define for_each_intel_fbc(__dev_priv, __fbc, __fbc_id) \ #define for_each_intel_fbc(__display, __fbc, __fbc_id) \
for_each_fbc_id((__dev_priv), (__fbc_id)) \ for_each_fbc_id((__display), (__fbc_id)) \
for_each_if((__fbc) = (__dev_priv)->display.fbc[(__fbc_id)]) for_each_if((__fbc) = (__display)->fbc[(__fbc_id)])
struct intel_fbc_funcs { struct intel_fbc_funcs {
void (*activate)(struct intel_fbc *fbc); void (*activate)(struct intel_fbc *fbc);
...@@ -89,7 +89,7 @@ struct intel_fbc_state { ...@@ -89,7 +89,7 @@ struct intel_fbc_state {
}; };
struct intel_fbc { struct intel_fbc {
struct drm_i915_private *i915; struct intel_display *display;
const struct intel_fbc_funcs *funcs; const struct intel_fbc_funcs *funcs;
/* /*
...@@ -150,7 +150,7 @@ static unsigned int _intel_fbc_cfb_stride(const struct intel_plane_state *plane_ ...@@ -150,7 +150,7 @@ static unsigned int _intel_fbc_cfb_stride(const struct intel_plane_state *plane_
/* minimum acceptable cfb stride in bytes, assuming 1:1 compression limit */ /* minimum acceptable cfb stride in bytes, assuming 1:1 compression limit */
static unsigned int skl_fbc_min_cfb_stride(const struct intel_plane_state *plane_state) static unsigned int skl_fbc_min_cfb_stride(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
unsigned int limit = 4; /* 1:4 compression limit is the worst case */ unsigned int limit = 4; /* 1:4 compression limit is the worst case */
unsigned int cpp = 4; /* FBC always 4 bytes per pixel */ unsigned int cpp = 4; /* FBC always 4 bytes per pixel */
unsigned int width = drm_rect_width(&plane_state->uapi.src) >> 16; unsigned int width = drm_rect_width(&plane_state->uapi.src) >> 16;
...@@ -164,7 +164,7 @@ static unsigned int skl_fbc_min_cfb_stride(const struct intel_plane_state *plane ...@@ -164,7 +164,7 @@ static unsigned int skl_fbc_min_cfb_stride(const struct intel_plane_state *plane
* Wa_16011863758: icl+ * Wa_16011863758: icl+
* Avoid some hardware segment address miscalculation. * Avoid some hardware segment address miscalculation.
*/ */
if (DISPLAY_VER(i915) >= 11) if (DISPLAY_VER(display) >= 11)
stride += 64; stride += 64;
/* /*
...@@ -180,7 +180,7 @@ static unsigned int skl_fbc_min_cfb_stride(const struct intel_plane_state *plane ...@@ -180,7 +180,7 @@ static unsigned int skl_fbc_min_cfb_stride(const struct intel_plane_state *plane
/* properly aligned cfb stride in bytes, assuming 1:1 compression limit */ /* properly aligned cfb stride in bytes, assuming 1:1 compression limit */
static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_state) static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
unsigned int stride = _intel_fbc_cfb_stride(plane_state); unsigned int stride = _intel_fbc_cfb_stride(plane_state);
/* /*
...@@ -188,7 +188,7 @@ static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_s ...@@ -188,7 +188,7 @@ static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_s
* be 512 byte aligned. Aligning each line to 512 bytes guarantees * be 512 byte aligned. Aligning each line to 512 bytes guarantees
* that regardless of the compression limit we choose later. * that regardless of the compression limit we choose later.
*/ */
if (DISPLAY_VER(i915) >= 9) if (DISPLAY_VER(display) >= 9)
return max(ALIGN(stride, 512), skl_fbc_min_cfb_stride(plane_state)); return max(ALIGN(stride, 512), skl_fbc_min_cfb_stride(plane_state));
else else
return stride; return stride;
...@@ -196,12 +196,12 @@ static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_s ...@@ -196,12 +196,12 @@ static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_s
static unsigned int intel_fbc_cfb_size(const struct intel_plane_state *plane_state) static unsigned int intel_fbc_cfb_size(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
int lines = drm_rect_height(&plane_state->uapi.src) >> 16; int lines = drm_rect_height(&plane_state->uapi.src) >> 16;
if (DISPLAY_VER(i915) == 7) if (DISPLAY_VER(display) == 7)
lines = min(lines, 2048); lines = min(lines, 2048);
else if (DISPLAY_VER(i915) >= 8) else if (DISPLAY_VER(display) >= 8)
lines = min(lines, 2560); lines = min(lines, 2560);
return lines * intel_fbc_cfb_stride(plane_state); return lines * intel_fbc_cfb_stride(plane_state);
...@@ -209,7 +209,7 @@ static unsigned int intel_fbc_cfb_size(const struct intel_plane_state *plane_sta ...@@ -209,7 +209,7 @@ static unsigned int intel_fbc_cfb_size(const struct intel_plane_state *plane_sta
static u16 intel_fbc_override_cfb_stride(const struct intel_plane_state *plane_state) static u16 intel_fbc_override_cfb_stride(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
unsigned int stride_aligned = intel_fbc_cfb_stride(plane_state); unsigned int stride_aligned = intel_fbc_cfb_stride(plane_state);
unsigned int stride = _intel_fbc_cfb_stride(plane_state); unsigned int stride = _intel_fbc_cfb_stride(plane_state);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
...@@ -222,28 +222,31 @@ static u16 intel_fbc_override_cfb_stride(const struct intel_plane_state *plane_s ...@@ -222,28 +222,31 @@ static u16 intel_fbc_override_cfb_stride(const struct intel_plane_state *plane_s
* we always need to use the override there. * we always need to use the override there.
*/ */
if (stride != stride_aligned || if (stride != stride_aligned ||
(DISPLAY_VER(i915) == 9 && fb->modifier == DRM_FORMAT_MOD_LINEAR)) (DISPLAY_VER(display) == 9 && fb->modifier == DRM_FORMAT_MOD_LINEAR))
return stride_aligned * 4 / 64; return stride_aligned * 4 / 64;
return 0; return 0;
} }
static bool intel_fbc_has_fences(struct drm_i915_private *i915) static bool intel_fbc_has_fences(struct intel_display *display)
{ {
struct drm_i915_private __maybe_unused *i915 = to_i915(display->drm);
return intel_gt_support_legacy_fencing(to_gt(i915)); return intel_gt_support_legacy_fencing(to_gt(i915));
} }
static u32 i8xx_fbc_ctl(struct intel_fbc *fbc) static u32 i8xx_fbc_ctl(struct intel_fbc *fbc)
{ {
const struct intel_fbc_state *fbc_state = &fbc->state; const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
unsigned int cfb_stride; unsigned int cfb_stride;
u32 fbc_ctl; u32 fbc_ctl;
cfb_stride = fbc_state->cfb_stride / fbc->limit; cfb_stride = fbc_state->cfb_stride / fbc->limit;
/* FBC_CTL wants 32B or 64B units */ /* FBC_CTL wants 32B or 64B units */
if (DISPLAY_VER(i915) == 2) if (DISPLAY_VER(display) == 2)
cfb_stride = (cfb_stride / 32) - 1; cfb_stride = (cfb_stride / 32) - 1;
else else
cfb_stride = (cfb_stride / 64) - 1; cfb_stride = (cfb_stride / 64) - 1;
...@@ -277,21 +280,21 @@ static u32 i965_fbc_ctl2(struct intel_fbc *fbc) ...@@ -277,21 +280,21 @@ static u32 i965_fbc_ctl2(struct intel_fbc *fbc)
static void i8xx_fbc_deactivate(struct intel_fbc *fbc) static void i8xx_fbc_deactivate(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
u32 fbc_ctl; u32 fbc_ctl;
/* Disable compression */ /* Disable compression */
fbc_ctl = intel_de_read(i915, FBC_CONTROL); fbc_ctl = intel_de_read(display, FBC_CONTROL);
if ((fbc_ctl & FBC_CTL_EN) == 0) if ((fbc_ctl & FBC_CTL_EN) == 0)
return; return;
fbc_ctl &= ~FBC_CTL_EN; fbc_ctl &= ~FBC_CTL_EN;
intel_de_write(i915, FBC_CONTROL, fbc_ctl); intel_de_write(display, FBC_CONTROL, fbc_ctl);
/* Wait for compressing bit to clear */ /* Wait for compressing bit to clear */
if (intel_de_wait_for_clear(i915, FBC_STATUS, if (intel_de_wait_for_clear(display, FBC_STATUS,
FBC_STAT_COMPRESSING, 10)) { FBC_STAT_COMPRESSING, 10)) {
drm_dbg_kms(&i915->drm, "FBC idle timed out\n"); drm_dbg_kms(display->drm, "FBC idle timed out\n");
return; return;
} }
} }
...@@ -299,32 +302,32 @@ static void i8xx_fbc_deactivate(struct intel_fbc *fbc) ...@@ -299,32 +302,32 @@ static void i8xx_fbc_deactivate(struct intel_fbc *fbc)
static void i8xx_fbc_activate(struct intel_fbc *fbc) static void i8xx_fbc_activate(struct intel_fbc *fbc)
{ {
const struct intel_fbc_state *fbc_state = &fbc->state; const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
int i; int i;
/* Clear old tags */ /* Clear old tags */
for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++)
intel_de_write(i915, FBC_TAG(i), 0); intel_de_write(display, FBC_TAG(i), 0);
if (DISPLAY_VER(i915) == 4) { if (DISPLAY_VER(display) == 4) {
intel_de_write(i915, FBC_CONTROL2, intel_de_write(display, FBC_CONTROL2,
i965_fbc_ctl2(fbc)); i965_fbc_ctl2(fbc));
intel_de_write(i915, FBC_FENCE_OFF, intel_de_write(display, FBC_FENCE_OFF,
fbc_state->fence_y_offset); fbc_state->fence_y_offset);
} }
intel_de_write(i915, FBC_CONTROL, intel_de_write(display, FBC_CONTROL,
FBC_CTL_EN | i8xx_fbc_ctl(fbc)); FBC_CTL_EN | i8xx_fbc_ctl(fbc));
} }
static bool i8xx_fbc_is_active(struct intel_fbc *fbc) static bool i8xx_fbc_is_active(struct intel_fbc *fbc)
{ {
return intel_de_read(fbc->i915, FBC_CONTROL) & FBC_CTL_EN; return intel_de_read(fbc->display, FBC_CONTROL) & FBC_CTL_EN;
} }
static bool i8xx_fbc_is_compressing(struct intel_fbc *fbc) static bool i8xx_fbc_is_compressing(struct intel_fbc *fbc)
{ {
return intel_de_read(fbc->i915, FBC_STATUS) & return intel_de_read(fbc->display, FBC_STATUS) &
(FBC_STAT_COMPRESSING | FBC_STAT_COMPRESSED); (FBC_STAT_COMPRESSING | FBC_STAT_COMPRESSED);
} }
...@@ -332,7 +335,7 @@ static void i8xx_fbc_nuke(struct intel_fbc *fbc) ...@@ -332,7 +335,7 @@ static void i8xx_fbc_nuke(struct intel_fbc *fbc)
{ {
struct intel_fbc_state *fbc_state = &fbc->state; struct intel_fbc_state *fbc_state = &fbc->state;
enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane; enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
struct drm_i915_private *dev_priv = fbc->i915; struct drm_i915_private *dev_priv = to_i915(fbc->display->drm);
intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane), intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane),
intel_de_read_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane))); intel_de_read_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane)));
...@@ -340,13 +343,14 @@ static void i8xx_fbc_nuke(struct intel_fbc *fbc) ...@@ -340,13 +343,14 @@ static void i8xx_fbc_nuke(struct intel_fbc *fbc)
static void i8xx_fbc_program_cfb(struct intel_fbc *fbc) static void i8xx_fbc_program_cfb(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
drm_WARN_ON(&i915->drm, drm_WARN_ON(display->drm,
range_overflows_end_t(u64, i915_gem_stolen_area_address(i915), range_overflows_end_t(u64, i915_gem_stolen_area_address(i915),
i915_gem_stolen_node_offset(&fbc->compressed_fb), i915_gem_stolen_node_offset(&fbc->compressed_fb),
U32_MAX)); U32_MAX));
drm_WARN_ON(&i915->drm, drm_WARN_ON(display->drm,
range_overflows_end_t(u64, i915_gem_stolen_area_address(i915), range_overflows_end_t(u64, i915_gem_stolen_area_address(i915),
i915_gem_stolen_node_offset(&fbc->compressed_llb), i915_gem_stolen_node_offset(&fbc->compressed_llb),
U32_MAX)); U32_MAX));
...@@ -369,7 +373,7 @@ static void i965_fbc_nuke(struct intel_fbc *fbc) ...@@ -369,7 +373,7 @@ static void i965_fbc_nuke(struct intel_fbc *fbc)
{ {
struct intel_fbc_state *fbc_state = &fbc->state; struct intel_fbc_state *fbc_state = &fbc->state;
enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane; enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
struct drm_i915_private *dev_priv = fbc->i915; struct drm_i915_private *dev_priv = to_i915(fbc->display->drm);
intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
intel_de_read_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane))); intel_de_read_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane)));
...@@ -402,7 +406,8 @@ static u32 g4x_dpfc_ctl_limit(struct intel_fbc *fbc) ...@@ -402,7 +406,8 @@ static u32 g4x_dpfc_ctl_limit(struct intel_fbc *fbc)
static u32 g4x_dpfc_ctl(struct intel_fbc *fbc) static u32 g4x_dpfc_ctl(struct intel_fbc *fbc)
{ {
const struct intel_fbc_state *fbc_state = &fbc->state; const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
u32 dpfc_ctl; u32 dpfc_ctl;
dpfc_ctl = g4x_dpfc_ctl_limit(fbc) | dpfc_ctl = g4x_dpfc_ctl_limit(fbc) |
...@@ -414,7 +419,7 @@ static u32 g4x_dpfc_ctl(struct intel_fbc *fbc) ...@@ -414,7 +419,7 @@ static u32 g4x_dpfc_ctl(struct intel_fbc *fbc)
if (fbc_state->fence_id >= 0) { if (fbc_state->fence_id >= 0) {
dpfc_ctl |= DPFC_CTL_FENCE_EN_G4X; dpfc_ctl |= DPFC_CTL_FENCE_EN_G4X;
if (DISPLAY_VER(i915) < 6) if (DISPLAY_VER(display) < 6)
dpfc_ctl |= DPFC_CTL_FENCENO(fbc_state->fence_id); dpfc_ctl |= DPFC_CTL_FENCENO(fbc_state->fence_id);
} }
...@@ -424,43 +429,43 @@ static u32 g4x_dpfc_ctl(struct intel_fbc *fbc) ...@@ -424,43 +429,43 @@ static u32 g4x_dpfc_ctl(struct intel_fbc *fbc)
static void g4x_fbc_activate(struct intel_fbc *fbc) static void g4x_fbc_activate(struct intel_fbc *fbc)
{ {
const struct intel_fbc_state *fbc_state = &fbc->state; const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
intel_de_write(i915, DPFC_FENCE_YOFF, intel_de_write(display, DPFC_FENCE_YOFF,
fbc_state->fence_y_offset); fbc_state->fence_y_offset);
intel_de_write(i915, DPFC_CONTROL, intel_de_write(display, DPFC_CONTROL,
DPFC_CTL_EN | g4x_dpfc_ctl(fbc)); DPFC_CTL_EN | g4x_dpfc_ctl(fbc));
} }
static void g4x_fbc_deactivate(struct intel_fbc *fbc) static void g4x_fbc_deactivate(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
u32 dpfc_ctl; u32 dpfc_ctl;
/* Disable compression */ /* Disable compression */
dpfc_ctl = intel_de_read(i915, DPFC_CONTROL); dpfc_ctl = intel_de_read(display, DPFC_CONTROL);
if (dpfc_ctl & DPFC_CTL_EN) { if (dpfc_ctl & DPFC_CTL_EN) {
dpfc_ctl &= ~DPFC_CTL_EN; dpfc_ctl &= ~DPFC_CTL_EN;
intel_de_write(i915, DPFC_CONTROL, dpfc_ctl); intel_de_write(display, DPFC_CONTROL, dpfc_ctl);
} }
} }
static bool g4x_fbc_is_active(struct intel_fbc *fbc) static bool g4x_fbc_is_active(struct intel_fbc *fbc)
{ {
return intel_de_read(fbc->i915, DPFC_CONTROL) & DPFC_CTL_EN; return intel_de_read(fbc->display, DPFC_CONTROL) & DPFC_CTL_EN;
} }
static bool g4x_fbc_is_compressing(struct intel_fbc *fbc) static bool g4x_fbc_is_compressing(struct intel_fbc *fbc)
{ {
return intel_de_read(fbc->i915, DPFC_STATUS) & DPFC_COMP_SEG_MASK; return intel_de_read(fbc->display, DPFC_STATUS) & DPFC_COMP_SEG_MASK;
} }
static void g4x_fbc_program_cfb(struct intel_fbc *fbc) static void g4x_fbc_program_cfb(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
intel_de_write(i915, DPFC_CB_BASE, intel_de_write(display, DPFC_CB_BASE,
i915_gem_stolen_node_offset(&fbc->compressed_fb)); i915_gem_stolen_node_offset(&fbc->compressed_fb));
} }
...@@ -476,43 +481,43 @@ static const struct intel_fbc_funcs g4x_fbc_funcs = { ...@@ -476,43 +481,43 @@ static const struct intel_fbc_funcs g4x_fbc_funcs = {
static void ilk_fbc_activate(struct intel_fbc *fbc) static void ilk_fbc_activate(struct intel_fbc *fbc)
{ {
struct intel_fbc_state *fbc_state = &fbc->state; struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
intel_de_write(i915, ILK_DPFC_FENCE_YOFF(fbc->id), intel_de_write(display, ILK_DPFC_FENCE_YOFF(fbc->id),
fbc_state->fence_y_offset); fbc_state->fence_y_offset);
intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), intel_de_write(display, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_EN | g4x_dpfc_ctl(fbc)); DPFC_CTL_EN | g4x_dpfc_ctl(fbc));
} }
static void ilk_fbc_deactivate(struct intel_fbc *fbc) static void ilk_fbc_deactivate(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
u32 dpfc_ctl; u32 dpfc_ctl;
/* Disable compression */ /* Disable compression */
dpfc_ctl = intel_de_read(i915, ILK_DPFC_CONTROL(fbc->id)); dpfc_ctl = intel_de_read(display, ILK_DPFC_CONTROL(fbc->id));
if (dpfc_ctl & DPFC_CTL_EN) { if (dpfc_ctl & DPFC_CTL_EN) {
dpfc_ctl &= ~DPFC_CTL_EN; dpfc_ctl &= ~DPFC_CTL_EN;
intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl); intel_de_write(display, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl);
} }
} }
static bool ilk_fbc_is_active(struct intel_fbc *fbc) static bool ilk_fbc_is_active(struct intel_fbc *fbc)
{ {
return intel_de_read(fbc->i915, ILK_DPFC_CONTROL(fbc->id)) & DPFC_CTL_EN; return intel_de_read(fbc->display, ILK_DPFC_CONTROL(fbc->id)) & DPFC_CTL_EN;
} }
static bool ilk_fbc_is_compressing(struct intel_fbc *fbc) static bool ilk_fbc_is_compressing(struct intel_fbc *fbc)
{ {
return intel_de_read(fbc->i915, ILK_DPFC_STATUS(fbc->id)) & DPFC_COMP_SEG_MASK; return intel_de_read(fbc->display, ILK_DPFC_STATUS(fbc->id)) & DPFC_COMP_SEG_MASK;
} }
static void ilk_fbc_program_cfb(struct intel_fbc *fbc) static void ilk_fbc_program_cfb(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
intel_de_write(i915, ILK_DPFC_CB_BASE(fbc->id), intel_de_write(display, ILK_DPFC_CB_BASE(fbc->id),
i915_gem_stolen_node_offset(&fbc->compressed_fb)); i915_gem_stolen_node_offset(&fbc->compressed_fb));
} }
...@@ -528,14 +533,14 @@ static const struct intel_fbc_funcs ilk_fbc_funcs = { ...@@ -528,14 +533,14 @@ static const struct intel_fbc_funcs ilk_fbc_funcs = {
static void snb_fbc_program_fence(struct intel_fbc *fbc) static void snb_fbc_program_fence(struct intel_fbc *fbc)
{ {
const struct intel_fbc_state *fbc_state = &fbc->state; const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
u32 ctl = 0; u32 ctl = 0;
if (fbc_state->fence_id >= 0) if (fbc_state->fence_id >= 0)
ctl = SNB_DPFC_FENCE_EN | SNB_DPFC_FENCENO(fbc_state->fence_id); ctl = SNB_DPFC_FENCE_EN | SNB_DPFC_FENCENO(fbc_state->fence_id);
intel_de_write(i915, SNB_DPFC_CTL_SA, ctl); intel_de_write(display, SNB_DPFC_CTL_SA, ctl);
intel_de_write(i915, SNB_DPFC_CPU_FENCE_OFFSET, fbc_state->fence_y_offset); intel_de_write(display, SNB_DPFC_CPU_FENCE_OFFSET, fbc_state->fence_y_offset);
} }
static void snb_fbc_activate(struct intel_fbc *fbc) static void snb_fbc_activate(struct intel_fbc *fbc)
...@@ -547,10 +552,10 @@ static void snb_fbc_activate(struct intel_fbc *fbc) ...@@ -547,10 +552,10 @@ static void snb_fbc_activate(struct intel_fbc *fbc)
static void snb_fbc_nuke(struct intel_fbc *fbc) static void snb_fbc_nuke(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
intel_de_write(i915, MSG_FBC_REND_STATE(fbc->id), FBC_REND_NUKE); intel_de_write(display, MSG_FBC_REND_STATE(fbc->id), FBC_REND_NUKE);
intel_de_posting_read(i915, MSG_FBC_REND_STATE(fbc->id)); intel_de_posting_read(display, MSG_FBC_REND_STATE(fbc->id));
} }
static const struct intel_fbc_funcs snb_fbc_funcs = { static const struct intel_fbc_funcs snb_fbc_funcs = {
...@@ -565,20 +570,20 @@ static const struct intel_fbc_funcs snb_fbc_funcs = { ...@@ -565,20 +570,20 @@ static const struct intel_fbc_funcs snb_fbc_funcs = {
static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc) static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc)
{ {
const struct intel_fbc_state *fbc_state = &fbc->state; const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
u32 val = 0; u32 val = 0;
if (fbc_state->override_cfb_stride) if (fbc_state->override_cfb_stride)
val |= FBC_STRIDE_OVERRIDE | val |= FBC_STRIDE_OVERRIDE |
FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit); FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit);
intel_de_write(i915, GLK_FBC_STRIDE(fbc->id), val); intel_de_write(display, GLK_FBC_STRIDE(fbc->id), val);
} }
static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc) static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc)
{ {
const struct intel_fbc_state *fbc_state = &fbc->state; const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
u32 val = 0; u32 val = 0;
/* Display WA #0529: skl, kbl, bxt. */ /* Display WA #0529: skl, kbl, bxt. */
...@@ -586,7 +591,7 @@ static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc) ...@@ -586,7 +591,7 @@ static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc)
val |= CHICKEN_FBC_STRIDE_OVERRIDE | val |= CHICKEN_FBC_STRIDE_OVERRIDE |
CHICKEN_FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit); CHICKEN_FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit);
intel_de_rmw(i915, CHICKEN_MISC_4, intel_de_rmw(display, CHICKEN_MISC_4,
CHICKEN_FBC_STRIDE_OVERRIDE | CHICKEN_FBC_STRIDE_OVERRIDE |
CHICKEN_FBC_STRIDE_MASK, val); CHICKEN_FBC_STRIDE_MASK, val);
} }
...@@ -594,7 +599,8 @@ static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc) ...@@ -594,7 +599,8 @@ static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc)
static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)
{ {
const struct intel_fbc_state *fbc_state = &fbc->state; const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
u32 dpfc_ctl; u32 dpfc_ctl;
dpfc_ctl = g4x_dpfc_ctl_limit(fbc); dpfc_ctl = g4x_dpfc_ctl_limit(fbc);
...@@ -602,7 +608,7 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) ...@@ -602,7 +608,7 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)
if (IS_IVYBRIDGE(i915)) if (IS_IVYBRIDGE(i915))
dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane); dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane);
if (DISPLAY_VER(i915) >= 20) if (DISPLAY_VER(display) >= 20)
dpfc_ctl |= DPFC_CTL_PLANE_BINDING(fbc_state->plane->id); dpfc_ctl |= DPFC_CTL_PLANE_BINDING(fbc_state->plane->id);
if (fbc_state->fence_id >= 0) if (fbc_state->fence_id >= 0)
...@@ -616,35 +622,35 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) ...@@ -616,35 +622,35 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)
static void ivb_fbc_activate(struct intel_fbc *fbc) static void ivb_fbc_activate(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
u32 dpfc_ctl; u32 dpfc_ctl;
if (DISPLAY_VER(i915) >= 10) if (DISPLAY_VER(display) >= 10)
glk_fbc_program_cfb_stride(fbc); glk_fbc_program_cfb_stride(fbc);
else if (DISPLAY_VER(i915) == 9) else if (DISPLAY_VER(display) == 9)
skl_fbc_program_cfb_stride(fbc); skl_fbc_program_cfb_stride(fbc);
if (intel_fbc_has_fences(i915)) if (intel_fbc_has_fences(display))
snb_fbc_program_fence(fbc); snb_fbc_program_fence(fbc);
/* wa_14019417088 Alternative WA*/ /* wa_14019417088 Alternative WA*/
dpfc_ctl = ivb_dpfc_ctl(fbc); dpfc_ctl = ivb_dpfc_ctl(fbc);
if (DISPLAY_VER(i915) >= 20) if (DISPLAY_VER(display) >= 20)
intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl); intel_de_write(display, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl);
intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), intel_de_write(display, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_EN | dpfc_ctl); DPFC_CTL_EN | dpfc_ctl);
} }
static bool ivb_fbc_is_compressing(struct intel_fbc *fbc) static bool ivb_fbc_is_compressing(struct intel_fbc *fbc)
{ {
return intel_de_read(fbc->i915, ILK_DPFC_STATUS2(fbc->id)) & DPFC_COMP_SEG_MASK_IVB; return intel_de_read(fbc->display, ILK_DPFC_STATUS2(fbc->id)) & DPFC_COMP_SEG_MASK_IVB;
} }
static void ivb_fbc_set_false_color(struct intel_fbc *fbc, static void ivb_fbc_set_false_color(struct intel_fbc *fbc,
bool enable) bool enable)
{ {
intel_de_rmw(fbc->i915, ILK_DPFC_CONTROL(fbc->id), intel_de_rmw(fbc->display, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_FALSE_COLOR, enable ? DPFC_CTL_FALSE_COLOR : 0); DPFC_CTL_FALSE_COLOR, enable ? DPFC_CTL_FALSE_COLOR : 0);
} }
...@@ -689,10 +695,10 @@ static bool intel_fbc_is_compressing(struct intel_fbc *fbc) ...@@ -689,10 +695,10 @@ static bool intel_fbc_is_compressing(struct intel_fbc *fbc)
static void intel_fbc_nuke(struct intel_fbc *fbc) static void intel_fbc_nuke(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
lockdep_assert_held(&fbc->lock); lockdep_assert_held(&fbc->lock);
drm_WARN_ON(&i915->drm, fbc->flip_pending); drm_WARN_ON(display->drm, fbc->flip_pending);
trace_intel_fbc_nuke(fbc->state.plane); trace_intel_fbc_nuke(fbc->state.plane);
...@@ -719,16 +725,19 @@ static void intel_fbc_deactivate(struct intel_fbc *fbc, const char *reason) ...@@ -719,16 +725,19 @@ static void intel_fbc_deactivate(struct intel_fbc *fbc, const char *reason)
fbc->no_fbc_reason = reason; fbc->no_fbc_reason = reason;
} }
static u64 intel_fbc_cfb_base_max(struct drm_i915_private *i915) static u64 intel_fbc_cfb_base_max(struct intel_display *display)
{ {
if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915)) struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(display) >= 5 || IS_G4X(i915))
return BIT_ULL(28); return BIT_ULL(28);
else else
return BIT_ULL(32); return BIT_ULL(32);
} }
static u64 intel_fbc_stolen_end(struct drm_i915_private *i915) static u64 intel_fbc_stolen_end(struct intel_display *display)
{ {
struct drm_i915_private __maybe_unused *i915 = to_i915(display->drm);
u64 end; u64 end;
/* The FBC hardware for BDW/SKL doesn't have access to the stolen /* The FBC hardware for BDW/SKL doesn't have access to the stolen
...@@ -736,12 +745,12 @@ static u64 intel_fbc_stolen_end(struct drm_i915_private *i915) ...@@ -736,12 +745,12 @@ static u64 intel_fbc_stolen_end(struct drm_i915_private *i915)
* If we enable FBC using a CFB on that memory range we'll get FIFO * If we enable FBC using a CFB on that memory range we'll get FIFO
* underruns, even if that range is not reserved by the BIOS. */ * underruns, even if that range is not reserved by the BIOS. */
if (IS_BROADWELL(i915) || if (IS_BROADWELL(i915) ||
(DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915))) (DISPLAY_VER(display) == 9 && !IS_BROXTON(i915)))
end = i915_gem_stolen_area_size(i915) - 8 * 1024 * 1024; end = i915_gem_stolen_area_size(i915) - 8 * 1024 * 1024;
else else
end = U64_MAX; end = U64_MAX;
return min(end, intel_fbc_cfb_base_max(i915)); return min(end, intel_fbc_cfb_base_max(display));
} }
static int intel_fbc_min_limit(const struct intel_plane_state *plane_state) static int intel_fbc_min_limit(const struct intel_plane_state *plane_state)
...@@ -749,8 +758,10 @@ static int intel_fbc_min_limit(const struct intel_plane_state *plane_state) ...@@ -749,8 +758,10 @@ static int intel_fbc_min_limit(const struct intel_plane_state *plane_state)
return plane_state->hw.fb->format->cpp[0] == 2 ? 2 : 1; return plane_state->hw.fb->format->cpp[0] == 2 ? 2 : 1;
} }
static int intel_fbc_max_limit(struct drm_i915_private *i915) static int intel_fbc_max_limit(struct intel_display *display)
{ {
struct drm_i915_private *i915 = to_i915(display->drm);
/* WaFbcOnly1to1Ratio:ctg */ /* WaFbcOnly1to1Ratio:ctg */
if (IS_G4X(i915)) if (IS_G4X(i915))
return 1; return 1;
...@@ -765,8 +776,9 @@ static int intel_fbc_max_limit(struct drm_i915_private *i915) ...@@ -765,8 +776,9 @@ static int intel_fbc_max_limit(struct drm_i915_private *i915)
static int find_compression_limit(struct intel_fbc *fbc, static int find_compression_limit(struct intel_fbc *fbc,
unsigned int size, int min_limit) unsigned int size, int min_limit)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
u64 end = intel_fbc_stolen_end(i915); struct drm_i915_private *i915 = to_i915(display->drm);
u64 end = intel_fbc_stolen_end(display);
int ret, limit = min_limit; int ret, limit = min_limit;
size /= limit; size /= limit;
...@@ -777,7 +789,7 @@ static int find_compression_limit(struct intel_fbc *fbc, ...@@ -777,7 +789,7 @@ static int find_compression_limit(struct intel_fbc *fbc,
if (ret == 0) if (ret == 0)
return limit; return limit;
for (; limit <= intel_fbc_max_limit(i915); limit <<= 1) { for (; limit <= intel_fbc_max_limit(display); limit <<= 1) {
ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb, ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
size >>= 1, 4096, 0, end); size >>= 1, 4096, 0, end);
if (ret == 0) if (ret == 0)
...@@ -790,15 +802,16 @@ static int find_compression_limit(struct intel_fbc *fbc, ...@@ -790,15 +802,16 @@ static int find_compression_limit(struct intel_fbc *fbc,
static int intel_fbc_alloc_cfb(struct intel_fbc *fbc, static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
unsigned int size, int min_limit) unsigned int size, int min_limit)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
int ret; int ret;
drm_WARN_ON(&i915->drm, drm_WARN_ON(display->drm,
i915_gem_stolen_node_allocated(&fbc->compressed_fb)); i915_gem_stolen_node_allocated(&fbc->compressed_fb));
drm_WARN_ON(&i915->drm, drm_WARN_ON(display->drm,
i915_gem_stolen_node_allocated(&fbc->compressed_llb)); i915_gem_stolen_node_allocated(&fbc->compressed_llb));
if (DISPLAY_VER(i915) < 5 && !IS_G4X(i915)) { if (DISPLAY_VER(display) < 5 && !IS_G4X(i915)) {
ret = i915_gem_stolen_insert_node(i915, &fbc->compressed_llb, ret = i915_gem_stolen_insert_node(i915, &fbc->compressed_llb,
4096, 4096); 4096, 4096);
if (ret) if (ret)
...@@ -809,12 +822,12 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc, ...@@ -809,12 +822,12 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
if (!ret) if (!ret)
goto err_llb; goto err_llb;
else if (ret > min_limit) else if (ret > min_limit)
drm_info_once(&i915->drm, drm_info_once(display->drm,
"Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n"); "Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n");
fbc->limit = ret; fbc->limit = ret;
drm_dbg_kms(&i915->drm, drm_dbg_kms(display->drm,
"reserved %llu bytes of contiguous stolen space for FBC, limit: %d\n", "reserved %llu bytes of contiguous stolen space for FBC, limit: %d\n",
i915_gem_stolen_node_size(&fbc->compressed_fb), fbc->limit); i915_gem_stolen_node_size(&fbc->compressed_fb), fbc->limit);
return 0; return 0;
...@@ -824,7 +837,8 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc, ...@@ -824,7 +837,8 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
i915_gem_stolen_remove_node(i915, &fbc->compressed_llb); i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
err: err:
if (i915_gem_stolen_initialized(i915)) if (i915_gem_stolen_initialized(i915))
drm_info_once(&i915->drm, "not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size); drm_info_once(display->drm,
"not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
return -ENOSPC; return -ENOSPC;
} }
...@@ -835,14 +849,15 @@ static void intel_fbc_program_cfb(struct intel_fbc *fbc) ...@@ -835,14 +849,15 @@ static void intel_fbc_program_cfb(struct intel_fbc *fbc)
static void intel_fbc_program_workarounds(struct intel_fbc *fbc) static void intel_fbc_program_workarounds(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
if (IS_SKYLAKE(i915) || IS_BROXTON(i915)) { if (IS_SKYLAKE(i915) || IS_BROXTON(i915)) {
/* /*
* WaFbcHighMemBwCorruptionAvoidance:skl,bxt * WaFbcHighMemBwCorruptionAvoidance:skl,bxt
* Display WA #0883: skl,bxt * Display WA #0883: skl,bxt
*/ */
intel_de_rmw(i915, ILK_DPFC_CHICKEN(fbc->id), intel_de_rmw(display, ILK_DPFC_CHICKEN(fbc->id),
0, DPFC_DISABLE_DUMMY0); 0, DPFC_DISABLE_DUMMY0);
} }
...@@ -852,24 +867,25 @@ static void intel_fbc_program_workarounds(struct intel_fbc *fbc) ...@@ -852,24 +867,25 @@ static void intel_fbc_program_workarounds(struct intel_fbc *fbc)
* WaFbcNukeOnHostModify:skl,kbl,cfl * WaFbcNukeOnHostModify:skl,kbl,cfl
* Display WA #0873: skl,kbl,cfl * Display WA #0873: skl,kbl,cfl
*/ */
intel_de_rmw(i915, ILK_DPFC_CHICKEN(fbc->id), intel_de_rmw(display, ILK_DPFC_CHICKEN(fbc->id),
0, DPFC_NUKE_ON_ANY_MODIFICATION); 0, DPFC_NUKE_ON_ANY_MODIFICATION);
} }
/* Wa_1409120013:icl,jsl,tgl,dg1 */ /* Wa_1409120013:icl,jsl,tgl,dg1 */
if (IS_DISPLAY_VER(i915, 11, 12)) if (IS_DISPLAY_VER(display, 11, 12))
intel_de_rmw(i915, ILK_DPFC_CHICKEN(fbc->id), intel_de_rmw(display, ILK_DPFC_CHICKEN(fbc->id),
0, DPFC_CHICKEN_COMP_DUMMY_PIXEL); 0, DPFC_CHICKEN_COMP_DUMMY_PIXEL);
/* Wa_22014263786:icl,jsl,tgl,dg1,rkl,adls,adlp,mtl */ /* Wa_22014263786:icl,jsl,tgl,dg1,rkl,adls,adlp,mtl */
if (DISPLAY_VER(i915) >= 11 && !IS_DG2(i915)) if (DISPLAY_VER(display) >= 11 && !IS_DG2(i915))
intel_de_rmw(i915, ILK_DPFC_CHICKEN(fbc->id), intel_de_rmw(display, ILK_DPFC_CHICKEN(fbc->id),
0, DPFC_CHICKEN_FORCE_SLB_INVALIDATION); 0, DPFC_CHICKEN_FORCE_SLB_INVALIDATION);
} }
static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc) static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
if (WARN_ON(intel_fbc_hw_is_active(fbc))) if (WARN_ON(intel_fbc_hw_is_active(fbc)))
return; return;
...@@ -880,12 +896,12 @@ static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc) ...@@ -880,12 +896,12 @@ static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
i915_gem_stolen_remove_node(i915, &fbc->compressed_fb); i915_gem_stolen_remove_node(i915, &fbc->compressed_fb);
} }
void intel_fbc_cleanup(struct drm_i915_private *i915) void intel_fbc_cleanup(struct intel_display *display)
{ {
struct intel_fbc *fbc; struct intel_fbc *fbc;
enum intel_fbc_id fbc_id; enum intel_fbc_id fbc_id;
for_each_intel_fbc(i915, fbc, fbc_id) { for_each_intel_fbc(display, fbc, fbc_id) {
mutex_lock(&fbc->lock); mutex_lock(&fbc->lock);
__intel_fbc_cleanup_cfb(fbc); __intel_fbc_cleanup_cfb(fbc);
mutex_unlock(&fbc->lock); mutex_unlock(&fbc->lock);
...@@ -937,15 +953,16 @@ static bool icl_fbc_stride_is_valid(const struct intel_plane_state *plane_state) ...@@ -937,15 +953,16 @@ static bool icl_fbc_stride_is_valid(const struct intel_plane_state *plane_state)
static bool stride_is_valid(const struct intel_plane_state *plane_state) static bool stride_is_valid(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(i915) >= 11) if (DISPLAY_VER(display) >= 11)
return icl_fbc_stride_is_valid(plane_state); return icl_fbc_stride_is_valid(plane_state);
else if (DISPLAY_VER(i915) >= 9) else if (DISPLAY_VER(display) >= 9)
return skl_fbc_stride_is_valid(plane_state); return skl_fbc_stride_is_valid(plane_state);
else if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915)) else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915))
return g4x_fbc_stride_is_valid(plane_state); return g4x_fbc_stride_is_valid(plane_state);
else if (DISPLAY_VER(i915) == 4) else if (DISPLAY_VER(display) == 4)
return i965_fbc_stride_is_valid(plane_state); return i965_fbc_stride_is_valid(plane_state);
else else
return i8xx_fbc_stride_is_valid(plane_state); return i8xx_fbc_stride_is_valid(plane_state);
...@@ -953,7 +970,7 @@ static bool stride_is_valid(const struct intel_plane_state *plane_state) ...@@ -953,7 +970,7 @@ static bool stride_is_valid(const struct intel_plane_state *plane_state)
static bool i8xx_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state) static bool i8xx_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
switch (fb->format->format) { switch (fb->format->format) {
...@@ -963,7 +980,7 @@ static bool i8xx_fbc_pixel_format_is_valid(const struct intel_plane_state *plane ...@@ -963,7 +980,7 @@ static bool i8xx_fbc_pixel_format_is_valid(const struct intel_plane_state *plane
case DRM_FORMAT_XRGB1555: case DRM_FORMAT_XRGB1555:
case DRM_FORMAT_RGB565: case DRM_FORMAT_RGB565:
/* 16bpp not supported on gen2 */ /* 16bpp not supported on gen2 */
if (DISPLAY_VER(i915) == 2) if (DISPLAY_VER(display) == 2)
return false; return false;
return true; return true;
default: default:
...@@ -973,7 +990,8 @@ static bool i8xx_fbc_pixel_format_is_valid(const struct intel_plane_state *plane ...@@ -973,7 +990,8 @@ static bool i8xx_fbc_pixel_format_is_valid(const struct intel_plane_state *plane
static bool g4x_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state) static bool g4x_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
switch (fb->format->format) { switch (fb->format->format) {
...@@ -1008,11 +1026,12 @@ static bool lnl_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_ ...@@ -1008,11 +1026,12 @@ static bool lnl_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_
static bool pixel_format_is_valid(const struct intel_plane_state *plane_state) static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(i915) >= 20) if (DISPLAY_VER(display) >= 20)
return lnl_fbc_pixel_format_is_valid(plane_state); return lnl_fbc_pixel_format_is_valid(plane_state);
else if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915)) else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915))
return g4x_fbc_pixel_format_is_valid(plane_state); return g4x_fbc_pixel_format_is_valid(plane_state);
else else
return i8xx_fbc_pixel_format_is_valid(plane_state); return i8xx_fbc_pixel_format_is_valid(plane_state);
...@@ -1042,11 +1061,12 @@ static bool skl_fbc_rotation_is_valid(const struct intel_plane_state *plane_stat ...@@ -1042,11 +1061,12 @@ static bool skl_fbc_rotation_is_valid(const struct intel_plane_state *plane_stat
static bool rotation_is_valid(const struct intel_plane_state *plane_state) static bool rotation_is_valid(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(i915) >= 9) if (DISPLAY_VER(display) >= 9)
return skl_fbc_rotation_is_valid(plane_state); return skl_fbc_rotation_is_valid(plane_state);
else if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915)) else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915))
return g4x_fbc_rotation_is_valid(plane_state); return g4x_fbc_rotation_is_valid(plane_state);
else else
return i8xx_fbc_rotation_is_valid(plane_state); return i8xx_fbc_rotation_is_valid(plane_state);
...@@ -1060,19 +1080,20 @@ static bool rotation_is_valid(const struct intel_plane_state *plane_state) ...@@ -1060,19 +1080,20 @@ static bool rotation_is_valid(const struct intel_plane_state *plane_state)
*/ */
static bool intel_fbc_hw_tracking_covers_screen(const struct intel_plane_state *plane_state) static bool intel_fbc_hw_tracking_covers_screen(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
unsigned int effective_w, effective_h, max_w, max_h; unsigned int effective_w, effective_h, max_w, max_h;
if (DISPLAY_VER(i915) >= 11) { if (DISPLAY_VER(display) >= 11) {
max_w = 8192; max_w = 8192;
max_h = 4096; max_h = 4096;
} else if (DISPLAY_VER(i915) >= 10) { } else if (DISPLAY_VER(display) >= 10) {
max_w = 5120; max_w = 5120;
max_h = 4096; max_h = 4096;
} else if (DISPLAY_VER(i915) >= 7) { } else if (DISPLAY_VER(display) >= 7) {
max_w = 4096; max_w = 4096;
max_h = 4096; max_h = 4096;
} else if (IS_G4X(i915) || DISPLAY_VER(i915) >= 5) { } else if (IS_G4X(i915) || DISPLAY_VER(display) >= 5) {
max_w = 4096; max_w = 4096;
max_h = 2048; max_h = 2048;
} else { } else {
...@@ -1090,16 +1111,17 @@ static bool intel_fbc_hw_tracking_covers_screen(const struct intel_plane_state * ...@@ -1090,16 +1111,17 @@ static bool intel_fbc_hw_tracking_covers_screen(const struct intel_plane_state *
static bool intel_fbc_plane_size_valid(const struct intel_plane_state *plane_state) static bool intel_fbc_plane_size_valid(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
unsigned int w, h, max_w, max_h; unsigned int w, h, max_w, max_h;
if (DISPLAY_VER(i915) >= 10) { if (DISPLAY_VER(display) >= 10) {
max_w = 5120; max_w = 5120;
max_h = 4096; max_h = 4096;
} else if (DISPLAY_VER(i915) >= 8 || IS_HASWELL(i915)) { } else if (DISPLAY_VER(display) >= 8 || IS_HASWELL(i915)) {
max_w = 4096; max_w = 4096;
max_h = 4096; max_h = 4096;
} else if (IS_G4X(i915) || DISPLAY_VER(i915) >= 5) { } else if (IS_G4X(i915) || DISPLAY_VER(display) >= 5) {
max_w = 4096; max_w = 4096;
max_h = 2048; max_h = 2048;
} else { } else {
...@@ -1127,9 +1149,9 @@ static bool skl_fbc_tiling_valid(const struct intel_plane_state *plane_state) ...@@ -1127,9 +1149,9 @@ static bool skl_fbc_tiling_valid(const struct intel_plane_state *plane_state)
static bool tiling_is_valid(const struct intel_plane_state *plane_state) static bool tiling_is_valid(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
if (DISPLAY_VER(i915) >= 9) if (DISPLAY_VER(display) >= 9)
return skl_fbc_tiling_valid(plane_state); return skl_fbc_tiling_valid(plane_state);
else else
return i8xx_fbc_tiling_valid(plane_state); return i8xx_fbc_tiling_valid(plane_state);
...@@ -1139,7 +1161,7 @@ static void intel_fbc_update_state(struct intel_atomic_state *state, ...@@ -1139,7 +1161,7 @@ static void intel_fbc_update_state(struct intel_atomic_state *state,
struct intel_crtc *crtc, struct intel_crtc *crtc,
struct intel_plane *plane) struct intel_plane *plane)
{ {
struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_display *display = to_intel_display(state->base.dev);
const struct intel_crtc_state *crtc_state = const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc); intel_atomic_get_new_crtc_state(state, crtc);
const struct intel_plane_state *plane_state = const struct intel_plane_state *plane_state =
...@@ -1157,8 +1179,8 @@ static void intel_fbc_update_state(struct intel_atomic_state *state, ...@@ -1157,8 +1179,8 @@ static void intel_fbc_update_state(struct intel_atomic_state *state,
fbc_state->fence_y_offset = intel_plane_fence_y_offset(plane_state); fbc_state->fence_y_offset = intel_plane_fence_y_offset(plane_state);
drm_WARN_ON(&i915->drm, plane_state->flags & PLANE_HAS_FENCE && drm_WARN_ON(display->drm, plane_state->flags & PLANE_HAS_FENCE &&
!intel_fbc_has_fences(i915)); !intel_fbc_has_fences(display));
if (plane_state->flags & PLANE_HAS_FENCE) if (plane_state->flags & PLANE_HAS_FENCE)
fbc_state->fence_id = i915_vma_fence_id(plane_state->ggtt_vma); fbc_state->fence_id = i915_vma_fence_id(plane_state->ggtt_vma);
...@@ -1172,7 +1194,7 @@ static void intel_fbc_update_state(struct intel_atomic_state *state, ...@@ -1172,7 +1194,7 @@ static void intel_fbc_update_state(struct intel_atomic_state *state,
static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state) static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
/* /*
* The use of a CPU fence is one of two ways to detect writes by the * The use of a CPU fence is one of two ways to detect writes by the
...@@ -1186,7 +1208,7 @@ static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state) ...@@ -1186,7 +1208,7 @@ static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state)
* so have no fence associated with it) due to aperture constraints * so have no fence associated with it) due to aperture constraints
* at the time of pinning. * at the time of pinning.
*/ */
return DISPLAY_VER(i915) >= 9 || return DISPLAY_VER(display) >= 9 ||
(plane_state->flags & PLANE_HAS_FENCE && (plane_state->flags & PLANE_HAS_FENCE &&
i915_vma_fence_id(plane_state->ggtt_vma) != -1); i915_vma_fence_id(plane_state->ggtt_vma) != -1);
} }
...@@ -1211,7 +1233,8 @@ static bool intel_fbc_is_ok(const struct intel_plane_state *plane_state) ...@@ -1211,7 +1233,8 @@ static bool intel_fbc_is_ok(const struct intel_plane_state *plane_state)
static int intel_fbc_check_plane(struct intel_atomic_state *state, static int intel_fbc_check_plane(struct intel_atomic_state *state,
struct intel_plane *plane) struct intel_plane *plane)
{ {
struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_display *display = to_intel_display(state->base.dev);
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_plane_state *plane_state = struct intel_plane_state *plane_state =
intel_atomic_get_new_plane_state(state, plane); intel_atomic_get_new_plane_state(state, plane);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
...@@ -1232,7 +1255,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, ...@@ -1232,7 +1255,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
return 0; return 0;
} }
if (!i915->display.params.enable_fbc) { if (!display->params.enable_fbc) {
plane_state->no_fbc_reason = "disabled per module param or by default"; plane_state->no_fbc_reason = "disabled per module param or by default";
return 0; return 0;
} }
...@@ -1265,14 +1288,14 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, ...@@ -1265,14 +1288,14 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
* Recommendation is to keep this combination disabled * Recommendation is to keep this combination disabled
* Bspec: 50422 HSD: 14010260002 * Bspec: 50422 HSD: 14010260002
*/ */
if (IS_DISPLAY_VER(i915, 12, 14) && crtc_state->has_sel_update && if (IS_DISPLAY_VER(display, 12, 14) && crtc_state->has_sel_update &&
!crtc_state->has_panel_replay) { !crtc_state->has_panel_replay) {
plane_state->no_fbc_reason = "PSR2 enabled"; plane_state->no_fbc_reason = "PSR2 enabled";
return 0; return 0;
} }
/* Wa_14016291713 */ /* Wa_14016291713 */
if ((IS_DISPLAY_VER(i915, 12, 13) || if ((IS_DISPLAY_VER(display, 12, 13) ||
IS_DISPLAY_IP_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_C0)) && IS_DISPLAY_IP_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_C0)) &&
crtc_state->has_psr && !crtc_state->has_panel_replay) { crtc_state->has_psr && !crtc_state->has_panel_replay) {
plane_state->no_fbc_reason = "PSR1 enabled (Wa_14016291713)"; plane_state->no_fbc_reason = "PSR1 enabled (Wa_14016291713)";
...@@ -1299,7 +1322,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, ...@@ -1299,7 +1322,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
return 0; return 0;
} }
if (DISPLAY_VER(i915) < 20 && if (DISPLAY_VER(display) < 20 &&
plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE &&
fb->format->has_alpha) { fb->format->has_alpha) {
plane_state->no_fbc_reason = "per-pixel alpha not supported"; plane_state->no_fbc_reason = "per-pixel alpha not supported";
...@@ -1321,14 +1344,14 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, ...@@ -1321,14 +1344,14 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
* having a Y offset that isn't divisible by 4 causes FIFO underrun * having a Y offset that isn't divisible by 4 causes FIFO underrun
* and screen flicker. * and screen flicker.
*/ */
if (DISPLAY_VER(i915) >= 9 && if (DISPLAY_VER(display) >= 9 &&
plane_state->view.color_plane[0].y & 3) { plane_state->view.color_plane[0].y & 3) {
plane_state->no_fbc_reason = "plane start Y offset misaligned"; plane_state->no_fbc_reason = "plane start Y offset misaligned";
return 0; return 0;
} }
/* Wa_22010751166: icl, ehl, tgl, dg1, rkl */ /* Wa_22010751166: icl, ehl, tgl, dg1, rkl */
if (DISPLAY_VER(i915) >= 11 && if (DISPLAY_VER(display) >= 11 &&
(plane_state->view.color_plane[0].y + (plane_state->view.color_plane[0].y +
(drm_rect_height(&plane_state->uapi.src) >> 16)) & 3) { (drm_rect_height(&plane_state->uapi.src) >> 16)) & 3) {
plane_state->no_fbc_reason = "plane end Y offset misaligned"; plane_state->no_fbc_reason = "plane end Y offset misaligned";
...@@ -1404,7 +1427,7 @@ static bool __intel_fbc_pre_update(struct intel_atomic_state *state, ...@@ -1404,7 +1427,7 @@ static bool __intel_fbc_pre_update(struct intel_atomic_state *state,
struct intel_crtc *crtc, struct intel_crtc *crtc,
struct intel_plane *plane) struct intel_plane *plane)
{ {
struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_display *display = to_intel_display(state->base.dev);
struct intel_fbc *fbc = plane->fbc; struct intel_fbc *fbc = plane->fbc;
bool need_vblank_wait = false; bool need_vblank_wait = false;
...@@ -1430,7 +1453,7 @@ static bool __intel_fbc_pre_update(struct intel_atomic_state *state, ...@@ -1430,7 +1453,7 @@ static bool __intel_fbc_pre_update(struct intel_atomic_state *state,
* and skipping the extra vblank wait before the plane update * and skipping the extra vblank wait before the plane update
* if at least one frame has already passed. * if at least one frame has already passed.
*/ */
if (fbc->activated && DISPLAY_VER(i915) >= 10) if (fbc->activated && DISPLAY_VER(display) >= 10)
need_vblank_wait = true; need_vblank_wait = true;
fbc->activated = false; fbc->activated = false;
...@@ -1464,13 +1487,13 @@ bool intel_fbc_pre_update(struct intel_atomic_state *state, ...@@ -1464,13 +1487,13 @@ bool intel_fbc_pre_update(struct intel_atomic_state *state,
static void __intel_fbc_disable(struct intel_fbc *fbc) static void __intel_fbc_disable(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
struct intel_plane *plane = fbc->state.plane; struct intel_plane *plane = fbc->state.plane;
lockdep_assert_held(&fbc->lock); lockdep_assert_held(&fbc->lock);
drm_WARN_ON(&i915->drm, fbc->active); drm_WARN_ON(display->drm, fbc->active);
drm_dbg_kms(&i915->drm, "Disabling FBC on [PLANE:%d:%s]\n", drm_dbg_kms(display->drm, "Disabling FBC on [PLANE:%d:%s]\n",
plane->base.base.id, plane->base.name); plane->base.base.id, plane->base.name);
__intel_fbc_cleanup_cfb(fbc); __intel_fbc_cleanup_cfb(fbc);
...@@ -1547,7 +1570,7 @@ void intel_fbc_invalidate(struct drm_i915_private *i915, ...@@ -1547,7 +1570,7 @@ void intel_fbc_invalidate(struct drm_i915_private *i915,
struct intel_fbc *fbc; struct intel_fbc *fbc;
enum intel_fbc_id fbc_id; enum intel_fbc_id fbc_id;
for_each_intel_fbc(i915, fbc, fbc_id) for_each_intel_fbc(&i915->display, fbc, fbc_id)
__intel_fbc_invalidate(fbc, frontbuffer_bits, origin); __intel_fbc_invalidate(fbc, frontbuffer_bits, origin);
} }
...@@ -1586,7 +1609,7 @@ void intel_fbc_flush(struct drm_i915_private *i915, ...@@ -1586,7 +1609,7 @@ void intel_fbc_flush(struct drm_i915_private *i915,
struct intel_fbc *fbc; struct intel_fbc *fbc;
enum intel_fbc_id fbc_id; enum intel_fbc_id fbc_id;
for_each_intel_fbc(i915, fbc, fbc_id) for_each_intel_fbc(&i915->display, fbc, fbc_id)
__intel_fbc_flush(fbc, frontbuffer_bits, origin); __intel_fbc_flush(fbc, frontbuffer_bits, origin);
} }
...@@ -1611,7 +1634,7 @@ static void __intel_fbc_enable(struct intel_atomic_state *state, ...@@ -1611,7 +1634,7 @@ static void __intel_fbc_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc, struct intel_crtc *crtc,
struct intel_plane *plane) struct intel_plane *plane)
{ {
struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_display *display = to_intel_display(state->base.dev);
const struct intel_plane_state *plane_state = const struct intel_plane_state *plane_state =
intel_atomic_get_new_plane_state(state, plane); intel_atomic_get_new_plane_state(state, plane);
struct intel_fbc *fbc = plane->fbc; struct intel_fbc *fbc = plane->fbc;
...@@ -1630,7 +1653,7 @@ static void __intel_fbc_enable(struct intel_atomic_state *state, ...@@ -1630,7 +1653,7 @@ static void __intel_fbc_enable(struct intel_atomic_state *state,
__intel_fbc_disable(fbc); __intel_fbc_disable(fbc);
} }
drm_WARN_ON(&i915->drm, fbc->active); drm_WARN_ON(display->drm, fbc->active);
fbc->no_fbc_reason = plane_state->no_fbc_reason; fbc->no_fbc_reason = plane_state->no_fbc_reason;
if (fbc->no_fbc_reason) if (fbc->no_fbc_reason)
...@@ -1652,7 +1675,7 @@ static void __intel_fbc_enable(struct intel_atomic_state *state, ...@@ -1652,7 +1675,7 @@ static void __intel_fbc_enable(struct intel_atomic_state *state,
return; return;
} }
drm_dbg_kms(&i915->drm, "Enabling FBC on [PLANE:%d:%s]\n", drm_dbg_kms(display->drm, "Enabling FBC on [PLANE:%d:%s]\n",
plane->base.base.id, plane->base.name); plane->base.base.id, plane->base.name);
fbc->no_fbc_reason = "FBC enabled but not active yet\n"; fbc->no_fbc_reason = "FBC enabled but not active yet\n";
...@@ -1670,10 +1693,10 @@ static void __intel_fbc_enable(struct intel_atomic_state *state, ...@@ -1670,10 +1693,10 @@ static void __intel_fbc_enable(struct intel_atomic_state *state,
*/ */
void intel_fbc_disable(struct intel_crtc *crtc) void intel_fbc_disable(struct intel_crtc *crtc)
{ {
struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_display *display = to_intel_display(crtc->base.dev);
struct intel_plane *plane; struct intel_plane *plane;
for_each_intel_plane(&i915->drm, plane) { for_each_intel_plane(display->drm, plane) {
struct intel_fbc *fbc = plane->fbc; struct intel_fbc *fbc = plane->fbc;
if (!fbc || plane->pipe != crtc->pipe) if (!fbc || plane->pipe != crtc->pipe)
...@@ -1718,7 +1741,8 @@ void intel_fbc_update(struct intel_atomic_state *state, ...@@ -1718,7 +1741,8 @@ void intel_fbc_update(struct intel_atomic_state *state,
static void intel_fbc_underrun_work_fn(struct work_struct *work) static void intel_fbc_underrun_work_fn(struct work_struct *work)
{ {
struct intel_fbc *fbc = container_of(work, typeof(*fbc), underrun_work); struct intel_fbc *fbc = container_of(work, typeof(*fbc), underrun_work);
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
mutex_lock(&fbc->lock); mutex_lock(&fbc->lock);
...@@ -1726,7 +1750,7 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work) ...@@ -1726,7 +1750,7 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work)
if (fbc->underrun_detected || !fbc->state.plane) if (fbc->underrun_detected || !fbc->state.plane)
goto out; goto out;
drm_dbg_kms(&i915->drm, "Disabling FBC due to FIFO underrun.\n"); drm_dbg_kms(display->drm, "Disabling FBC due to FIFO underrun.\n");
fbc->underrun_detected = true; fbc->underrun_detected = true;
intel_fbc_deactivate(fbc, "FIFO underrun"); intel_fbc_deactivate(fbc, "FIFO underrun");
...@@ -1739,14 +1763,14 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work) ...@@ -1739,14 +1763,14 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work)
static void __intel_fbc_reset_underrun(struct intel_fbc *fbc) static void __intel_fbc_reset_underrun(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
cancel_work_sync(&fbc->underrun_work); cancel_work_sync(&fbc->underrun_work);
mutex_lock(&fbc->lock); mutex_lock(&fbc->lock);
if (fbc->underrun_detected) { if (fbc->underrun_detected) {
drm_dbg_kms(&i915->drm, drm_dbg_kms(display->drm,
"Re-allowing FBC after fifo underrun\n"); "Re-allowing FBC after fifo underrun\n");
fbc->no_fbc_reason = "FIFO underrun cleared"; fbc->no_fbc_reason = "FIFO underrun cleared";
} }
...@@ -1757,22 +1781,24 @@ static void __intel_fbc_reset_underrun(struct intel_fbc *fbc) ...@@ -1757,22 +1781,24 @@ static void __intel_fbc_reset_underrun(struct intel_fbc *fbc)
/* /*
* intel_fbc_reset_underrun - reset FBC fifo underrun status. * intel_fbc_reset_underrun - reset FBC fifo underrun status.
* @i915: the i915 device * @display: display
* *
* See intel_fbc_handle_fifo_underrun_irq(). For automated testing we * See intel_fbc_handle_fifo_underrun_irq(). For automated testing we
* want to re-enable FBC after an underrun to increase test coverage. * want to re-enable FBC after an underrun to increase test coverage.
*/ */
void intel_fbc_reset_underrun(struct drm_i915_private *i915) void intel_fbc_reset_underrun(struct intel_display *display)
{ {
struct intel_fbc *fbc; struct intel_fbc *fbc;
enum intel_fbc_id fbc_id; enum intel_fbc_id fbc_id;
for_each_intel_fbc(i915, fbc, fbc_id) for_each_intel_fbc(display, fbc, fbc_id)
__intel_fbc_reset_underrun(fbc); __intel_fbc_reset_underrun(fbc);
} }
static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc) static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = to_i915(fbc->display->drm);
/* /*
* There's no guarantee that underrun_detected won't be set to true * 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 * right after this check and before the work is scheduled, but that's
...@@ -1784,12 +1810,12 @@ static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc) ...@@ -1784,12 +1810,12 @@ static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc)
if (READ_ONCE(fbc->underrun_detected)) if (READ_ONCE(fbc->underrun_detected))
return; return;
queue_work(fbc->i915->unordered_wq, &fbc->underrun_work); queue_work(i915->unordered_wq, &fbc->underrun_work);
} }
/** /**
* intel_fbc_handle_fifo_underrun_irq - disable FBC when we get a FIFO underrun * intel_fbc_handle_fifo_underrun_irq - disable FBC when we get a FIFO underrun
* @i915: i915 device * @display: display
* *
* Without FBC, most underruns are harmless and don't really cause too many * Without FBC, most underruns are harmless and don't really cause too many
* problems, except for an annoying message on dmesg. With FBC, underruns can * problems, except for an annoying message on dmesg. With FBC, underruns can
...@@ -1801,12 +1827,12 @@ static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc) ...@@ -1801,12 +1827,12 @@ static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc)
* *
* This function is called from the IRQ handler. * This function is called from the IRQ handler.
*/ */
void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915) void intel_fbc_handle_fifo_underrun_irq(struct intel_display *display)
{ {
struct intel_fbc *fbc; struct intel_fbc *fbc;
enum intel_fbc_id fbc_id; enum intel_fbc_id fbc_id;
for_each_intel_fbc(i915, fbc, fbc_id) for_each_intel_fbc(display, fbc, fbc_id)
__intel_fbc_handle_fifo_underrun_irq(fbc); __intel_fbc_handle_fifo_underrun_irq(fbc);
} }
...@@ -1819,15 +1845,17 @@ void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915) ...@@ -1819,15 +1845,17 @@ void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915)
* space to change the value during runtime without sanitizing it again. IGT * space to change the value during runtime without sanitizing it again. IGT
* relies on being able to change i915.enable_fbc at runtime. * relies on being able to change i915.enable_fbc at runtime.
*/ */
static int intel_sanitize_fbc_option(struct drm_i915_private *i915) static int intel_sanitize_fbc_option(struct intel_display *display)
{ {
if (i915->display.params.enable_fbc >= 0) struct drm_i915_private *i915 = to_i915(display->drm);
return !!i915->display.params.enable_fbc;
if (display->params.enable_fbc >= 0)
return !!display->params.enable_fbc;
if (!HAS_FBC(i915)) if (!HAS_FBC(display))
return 0; return 0;
if (IS_BROADWELL(i915) || DISPLAY_VER(i915) >= 9) if (IS_BROADWELL(i915) || DISPLAY_VER(display) >= 9)
return 1; return 1;
return 0; return 0;
...@@ -1838,9 +1866,10 @@ void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane) ...@@ -1838,9 +1866,10 @@ void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane)
plane->fbc = fbc; plane->fbc = fbc;
} }
static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915, static struct intel_fbc *intel_fbc_create(struct intel_display *display,
enum intel_fbc_id fbc_id) enum intel_fbc_id fbc_id)
{ {
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_fbc *fbc; struct intel_fbc *fbc;
fbc = kzalloc(sizeof(*fbc), GFP_KERNEL); fbc = kzalloc(sizeof(*fbc), GFP_KERNEL);
...@@ -1848,19 +1877,19 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915, ...@@ -1848,19 +1877,19 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915,
return NULL; return NULL;
fbc->id = fbc_id; fbc->id = fbc_id;
fbc->i915 = i915; fbc->display = display;
INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn); INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
mutex_init(&fbc->lock); mutex_init(&fbc->lock);
if (DISPLAY_VER(i915) >= 7) if (DISPLAY_VER(display) >= 7)
fbc->funcs = &ivb_fbc_funcs; fbc->funcs = &ivb_fbc_funcs;
else if (DISPLAY_VER(i915) == 6) else if (DISPLAY_VER(display) == 6)
fbc->funcs = &snb_fbc_funcs; fbc->funcs = &snb_fbc_funcs;
else if (DISPLAY_VER(i915) == 5) else if (DISPLAY_VER(display) == 5)
fbc->funcs = &ilk_fbc_funcs; fbc->funcs = &ilk_fbc_funcs;
else if (IS_G4X(i915)) else if (IS_G4X(i915))
fbc->funcs = &g4x_fbc_funcs; fbc->funcs = &g4x_fbc_funcs;
else if (DISPLAY_VER(i915) == 4) else if (DISPLAY_VER(display) == 4)
fbc->funcs = &i965_fbc_funcs; fbc->funcs = &i965_fbc_funcs;
else else
fbc->funcs = &i8xx_fbc_funcs; fbc->funcs = &i8xx_fbc_funcs;
...@@ -1870,36 +1899,36 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915, ...@@ -1870,36 +1899,36 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915,
/** /**
* intel_fbc_init - Initialize FBC * intel_fbc_init - Initialize FBC
* @i915: the i915 device * @display: display
* *
* This function might be called during PM init process. * This function might be called during PM init process.
*/ */
void intel_fbc_init(struct drm_i915_private *i915) void intel_fbc_init(struct intel_display *display)
{ {
enum intel_fbc_id fbc_id; enum intel_fbc_id fbc_id;
i915->display.params.enable_fbc = intel_sanitize_fbc_option(i915); display->params.enable_fbc = intel_sanitize_fbc_option(display);
drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n", drm_dbg_kms(display->drm, "Sanitized enable_fbc value: %d\n",
i915->display.params.enable_fbc); display->params.enable_fbc);
for_each_fbc_id(i915, fbc_id) for_each_fbc_id(display, fbc_id)
i915->display.fbc[fbc_id] = intel_fbc_create(i915, fbc_id); display->fbc[fbc_id] = intel_fbc_create(display, fbc_id);
} }
/** /**
* intel_fbc_sanitize - Sanitize FBC * intel_fbc_sanitize - Sanitize FBC
* @i915: the i915 device * @display: display
* *
* Make sure FBC is initially disabled since we have no * Make sure FBC is initially disabled since we have no
* idea eg. into which parts of stolen it might be scribbling * idea eg. into which parts of stolen it might be scribbling
* into. * into.
*/ */
void intel_fbc_sanitize(struct drm_i915_private *i915) void intel_fbc_sanitize(struct intel_display *display)
{ {
struct intel_fbc *fbc; struct intel_fbc *fbc;
enum intel_fbc_id fbc_id; enum intel_fbc_id fbc_id;
for_each_intel_fbc(i915, fbc, fbc_id) { for_each_intel_fbc(display, fbc, fbc_id) {
if (intel_fbc_hw_is_active(fbc)) if (intel_fbc_hw_is_active(fbc))
intel_fbc_hw_deactivate(fbc); intel_fbc_hw_deactivate(fbc);
} }
...@@ -1908,11 +1937,12 @@ void intel_fbc_sanitize(struct drm_i915_private *i915) ...@@ -1908,11 +1937,12 @@ void intel_fbc_sanitize(struct drm_i915_private *i915)
static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused)
{ {
struct intel_fbc *fbc = m->private; struct intel_fbc *fbc = m->private;
struct drm_i915_private *i915 = fbc->i915; struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_plane *plane; struct intel_plane *plane;
intel_wakeref_t wakeref; intel_wakeref_t wakeref;
drm_modeset_lock_all(&i915->drm); drm_modeset_lock_all(display->drm);
wakeref = intel_runtime_pm_get(&i915->runtime_pm); wakeref = intel_runtime_pm_get(&i915->runtime_pm);
mutex_lock(&fbc->lock); mutex_lock(&fbc->lock);
...@@ -1925,7 +1955,7 @@ static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) ...@@ -1925,7 +1955,7 @@ static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused)
seq_printf(m, "FBC disabled: %s\n", fbc->no_fbc_reason); seq_printf(m, "FBC disabled: %s\n", fbc->no_fbc_reason);
} }
for_each_intel_plane(&i915->drm, plane) { for_each_intel_plane(display->drm, plane) {
const struct intel_plane_state *plane_state = const struct intel_plane_state *plane_state =
to_intel_plane_state(plane->base.state); to_intel_plane_state(plane->base.state);
...@@ -1941,7 +1971,7 @@ static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) ...@@ -1941,7 +1971,7 @@ static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused)
mutex_unlock(&fbc->lock); mutex_unlock(&fbc->lock);
intel_runtime_pm_put(&i915->runtime_pm, wakeref); intel_runtime_pm_put(&i915->runtime_pm, wakeref);
drm_modeset_unlock_all(&i915->drm); drm_modeset_unlock_all(display->drm);
return 0; return 0;
} }
...@@ -1998,12 +2028,12 @@ void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc) ...@@ -1998,12 +2028,12 @@ void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc)
} }
/* FIXME: remove this once igt is on board with per-crtc stuff */ /* FIXME: remove this once igt is on board with per-crtc stuff */
void intel_fbc_debugfs_register(struct drm_i915_private *i915) void intel_fbc_debugfs_register(struct intel_display *display)
{ {
struct drm_minor *minor = i915->drm.primary; struct drm_minor *minor = display->drm->primary;
struct intel_fbc *fbc; struct intel_fbc *fbc;
fbc = i915->display.fbc[INTEL_FBC_A]; fbc = display->fbc[INTEL_FBC_A];
if (fbc) if (fbc)
intel_fbc_debugfs_add(fbc, minor->debugfs_root); intel_fbc_debugfs_add(fbc, minor->debugfs_root);
} }
...@@ -13,6 +13,7 @@ struct drm_i915_private; ...@@ -13,6 +13,7 @@ struct drm_i915_private;
struct intel_atomic_state; struct intel_atomic_state;
struct intel_crtc; struct intel_crtc;
struct intel_crtc_state; struct intel_crtc_state;
struct intel_display;
struct intel_fbc; struct intel_fbc;
struct intel_plane; struct intel_plane;
struct intel_plane_state; struct intel_plane_state;
...@@ -31,9 +32,9 @@ bool intel_fbc_pre_update(struct intel_atomic_state *state, ...@@ -31,9 +32,9 @@ bool intel_fbc_pre_update(struct intel_atomic_state *state,
struct intel_crtc *crtc); struct intel_crtc *crtc);
void intel_fbc_post_update(struct intel_atomic_state *state, void intel_fbc_post_update(struct intel_atomic_state *state,
struct intel_crtc *crtc); struct intel_crtc *crtc);
void intel_fbc_init(struct drm_i915_private *dev_priv); void intel_fbc_init(struct intel_display *display);
void intel_fbc_cleanup(struct drm_i915_private *dev_priv); void intel_fbc_cleanup(struct intel_display *display);
void intel_fbc_sanitize(struct drm_i915_private *dev_priv); void intel_fbc_sanitize(struct intel_display *display);
void intel_fbc_update(struct intel_atomic_state *state, void intel_fbc_update(struct intel_atomic_state *state,
struct intel_crtc *crtc); struct intel_crtc *crtc);
void intel_fbc_disable(struct intel_crtc *crtc); void intel_fbc_disable(struct intel_crtc *crtc);
...@@ -43,9 +44,9 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, ...@@ -43,9 +44,9 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
void intel_fbc_flush(struct drm_i915_private *dev_priv, void intel_fbc_flush(struct drm_i915_private *dev_priv,
unsigned int frontbuffer_bits, enum fb_op_origin origin); unsigned int frontbuffer_bits, enum fb_op_origin origin);
void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane); 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_handle_fifo_underrun_irq(struct intel_display *display);
void intel_fbc_reset_underrun(struct drm_i915_private *i915); void intel_fbc_reset_underrun(struct intel_display *display);
void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc); void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc);
void intel_fbc_debugfs_register(struct drm_i915_private *i915); void intel_fbc_debugfs_register(struct intel_display *display);
#endif /* __INTEL_FBC_H__ */ #endif /* __INTEL_FBC_H__ */
...@@ -440,7 +440,7 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, ...@@ -440,7 +440,7 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe)); drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
} }
intel_fbc_handle_fifo_underrun_irq(dev_priv); intel_fbc_handle_fifo_underrun_irq(&dev_priv->display);
} }
/** /**
......
...@@ -966,7 +966,7 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, ...@@ -966,7 +966,7 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915,
} }
} }
intel_fbc_sanitize(i915); intel_fbc_sanitize(&i915->display);
intel_sanitize_plane_mapping(i915); intel_sanitize_plane_mapping(i915);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment