3
0
mirror of https://github.com/Qortal/Brooklyn.git synced 2025-02-20 14:15:55 +00:00

1785 lines
47 KiB
C
Raw Normal View History

/*
* Copyright © 2014 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* DOC: Frame Buffer Compression (FBC)
*
* FBC tries to save memory bandwidth (and so power consumption) by
* compressing the amount of memory used by the display. It is total
* transparent to user space and completely handled in the kernel.
*
* The benefits of FBC are mostly visible with solid backgrounds and
* variation-less patterns. It comes from keeping the memory footprint small
* and having fewer memory pages opened and accessed for refreshing the display.
*
* i915 is responsible to reserve stolen memory for FBC and configure its
* offset on proper registers. The hardware takes care of all
* compress/decompress. However there are many known cases where we have to
* forcibly disable it to allow proper screen updates.
*/
#include <drm/drm_fourcc.h>
#include "i915_drv.h"
#include "i915_vgpu.h"
2022-04-02 17:24:34 +05:00
#include "intel_cdclk.h"
#include "intel_de.h"
2022-04-02 17:24:34 +05:00
#include "intel_display_trace.h"
#include "intel_display_types.h"
#include "intel_fbc.h"
#include "intel_frontbuffer.h"
2022-04-02 17:24:34 +05:00
struct intel_fbc_funcs {
void (*activate)(struct intel_fbc *fbc);
void (*deactivate)(struct intel_fbc *fbc);
bool (*is_active)(struct intel_fbc *fbc);
bool (*is_compressing)(struct intel_fbc *fbc);
void (*nuke)(struct intel_fbc *fbc);
void (*program_cfb)(struct intel_fbc *fbc);
void (*set_false_color)(struct intel_fbc *fbc, bool enable);
};
struct intel_fbc_state {
struct intel_plane *plane;
unsigned int cfb_stride;
unsigned int cfb_size;
unsigned int fence_y_offset;
u16 override_cfb_stride;
u16 interval;
s8 fence_id;
};
struct intel_fbc {
struct drm_i915_private *i915;
const struct intel_fbc_funcs *funcs;
/*
* This is always the inner lock when overlapping with
* struct_mutex and it's the outer lock when overlapping
* with stolen_lock.
*/
struct mutex lock;
unsigned int possible_framebuffer_bits;
unsigned int busy_bits;
struct drm_mm_node compressed_fb;
struct drm_mm_node compressed_llb;
u8 limit;
bool false_color;
bool active;
bool activated;
bool flip_pending;
bool underrun_detected;
struct work_struct underrun_work;
/*
* This structure contains everything that's relevant to program the
* hardware registers. When we want to figure out if we need to disable
* and re-enable FBC for a new configuration we just check if there's
* something different in the struct. The genx_fbc_activate functions
* are supposed to read from it in order to program the registers.
*/
struct intel_fbc_state state;
const char *no_fbc_reason;
};
/* plane stride in pixels */
static unsigned int intel_fbc_plane_stride(const struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int stride;
stride = plane_state->view.color_plane[0].mapping_stride;
if (!drm_rotation_90_or_270(plane_state->hw.rotation))
stride /= fb->format->cpp[0];
return stride;
}
/* plane stride based cfb stride in bytes, assuming 1:1 compression limit */
static unsigned int _intel_fbc_cfb_stride(const struct intel_plane_state *plane_state)
{
unsigned int cpp = 4; /* FBC always 4 bytes per pixel */
return intel_fbc_plane_stride(plane_state) * cpp;
}
/* minimum acceptable cfb stride in bytes, assuming 1:1 compression limit */
static unsigned int skl_fbc_min_cfb_stride(const struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
unsigned int limit = 4; /* 1:4 compression limit is the worst case */
unsigned int cpp = 4; /* FBC always 4 bytes per pixel */
unsigned int width = drm_rect_width(&plane_state->uapi.src) >> 16;
unsigned int height = 4; /* FBC segment is 4 lines */
unsigned int stride;
/* minimum segment stride we can use */
stride = width * cpp * height / limit;
/*
* Wa_16011863758: icl+
* Avoid some hardware segment address miscalculation.
*/
if (DISPLAY_VER(i915) >= 11)
stride += 64;
/*
* At least some of the platforms require each 4 line segment to
* be 512 byte aligned. Just do it always for simplicity.
*/
stride = ALIGN(stride, 512);
/* convert back to single line equivalent with 1:1 compression limit */
return stride * limit / height;
}
/* 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)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
unsigned int stride = _intel_fbc_cfb_stride(plane_state);
/*
* At least some of the platforms require each 4 line segment to
* be 512 byte aligned. Aligning each line to 512 bytes guarantees
* that regardless of the compression limit we choose later.
*/
if (DISPLAY_VER(i915) >= 9)
return max(ALIGN(stride, 512), skl_fbc_min_cfb_stride(plane_state));
else
return stride;
}
2022-04-02 17:24:34 +05:00
static unsigned int intel_fbc_cfb_size(const struct intel_plane_state *plane_state)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
int lines = drm_rect_height(&plane_state->uapi.src) >> 16;
2022-04-02 17:24:34 +05:00
if (DISPLAY_VER(i915) == 7)
lines = min(lines, 2048);
2022-04-02 17:24:34 +05:00
else if (DISPLAY_VER(i915) >= 8)
lines = min(lines, 2560);
2022-04-02 17:24:34 +05:00
return lines * intel_fbc_cfb_stride(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);
unsigned int stride_aligned = intel_fbc_cfb_stride(plane_state);
unsigned int stride = _intel_fbc_cfb_stride(plane_state);
const struct drm_framebuffer *fb = plane_state->hw.fb;
/*
* Override stride in 64 byte units per 4 line segment.
*
* Gen9 hw miscalculates cfb stride for linear as
* PLANE_STRIDE*512 instead of PLANE_STRIDE*64, so
* we always need to use the override there.
*/
if (stride != stride_aligned ||
(DISPLAY_VER(i915) == 9 && fb->modifier == DRM_FORMAT_MOD_LINEAR))
return stride_aligned * 4 / 64;
return 0;
}
static u32 i8xx_fbc_ctl(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915;
unsigned int cfb_stride;
u32 fbc_ctl;
cfb_stride = fbc_state->cfb_stride / fbc->limit;
/* FBC_CTL wants 32B or 64B units */
if (DISPLAY_VER(i915) == 2)
cfb_stride = (cfb_stride / 32) - 1;
else
cfb_stride = (cfb_stride / 64) - 1;
fbc_ctl = FBC_CTL_PERIODIC |
FBC_CTL_INTERVAL(fbc_state->interval) |
FBC_CTL_STRIDE(cfb_stride);
if (IS_I945GM(i915))
fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */
if (fbc_state->fence_id >= 0)
fbc_ctl |= FBC_CTL_FENCENO(fbc_state->fence_id);
return fbc_ctl;
}
static u32 i965_fbc_ctl2(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
u32 fbc_ctl2;
fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM |
FBC_CTL_PLANE(fbc_state->plane->i9xx_plane);
if (fbc_state->fence_id >= 0)
fbc_ctl2 |= FBC_CTL_CPU_FENCE_EN;
return fbc_ctl2;
}
2022-04-02 17:24:34 +05:00
static void i8xx_fbc_deactivate(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = fbc->i915;
u32 fbc_ctl;
/* Disable compression */
2022-04-02 17:24:34 +05:00
fbc_ctl = intel_de_read(i915, FBC_CONTROL);
if ((fbc_ctl & FBC_CTL_EN) == 0)
return;
fbc_ctl &= ~FBC_CTL_EN;
2022-04-02 17:24:34 +05:00
intel_de_write(i915, FBC_CONTROL, fbc_ctl);
/* Wait for compressing bit to clear */
2022-04-02 17:24:34 +05:00
if (intel_de_wait_for_clear(i915, FBC_STATUS,
FBC_STAT_COMPRESSING, 10)) {
2022-04-02 17:24:34 +05:00
drm_dbg_kms(&i915->drm, "FBC idle timed out\n");
return;
}
}
2022-04-02 17:24:34 +05:00
static void i8xx_fbc_activate(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915;
int i;
/* Clear old tags */
for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++)
2022-04-02 17:24:34 +05:00
intel_de_write(i915, FBC_TAG(i), 0);
if (DISPLAY_VER(i915) == 4) {
intel_de_write(i915, FBC_CONTROL2,
i965_fbc_ctl2(fbc));
intel_de_write(i915, FBC_FENCE_OFF,
fbc_state->fence_y_offset);
}
2022-04-02 17:24:34 +05:00
intel_de_write(i915, FBC_CONTROL,
FBC_CTL_EN | i8xx_fbc_ctl(fbc));
}
static bool i8xx_fbc_is_active(struct intel_fbc *fbc)
{
return intel_de_read(fbc->i915, FBC_CONTROL) & FBC_CTL_EN;
}
static bool i8xx_fbc_is_compressing(struct intel_fbc *fbc)
{
return intel_de_read(fbc->i915, FBC_STATUS) &
(FBC_STAT_COMPRESSING | FBC_STAT_COMPRESSED);
}
2022-04-02 17:24:34 +05:00
static void i8xx_fbc_nuke(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc_state *fbc_state = &fbc->state;
enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
struct drm_i915_private *dev_priv = fbc->i915;
spin_lock_irq(&dev_priv->uncore.lock);
intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
intel_de_read_fw(dev_priv, DSPADDR(i9xx_plane)));
spin_unlock_irq(&dev_priv->uncore.lock);
}
static void i8xx_fbc_program_cfb(struct intel_fbc *fbc)
{
struct drm_i915_private *i915 = fbc->i915;
GEM_BUG_ON(range_overflows_end_t(u64, i915->dsm.start,
fbc->compressed_fb.start, U32_MAX));
GEM_BUG_ON(range_overflows_end_t(u64, i915->dsm.start,
fbc->compressed_llb.start, U32_MAX));
intel_de_write(i915, FBC_CFB_BASE,
i915->dsm.start + fbc->compressed_fb.start);
intel_de_write(i915, FBC_LL_BASE,
i915->dsm.start + fbc->compressed_llb.start);
}
2022-04-02 17:24:34 +05:00
static const struct intel_fbc_funcs i8xx_fbc_funcs = {
.activate = i8xx_fbc_activate,
.deactivate = i8xx_fbc_deactivate,
.is_active = i8xx_fbc_is_active,
.is_compressing = i8xx_fbc_is_compressing,
.nuke = i8xx_fbc_nuke,
.program_cfb = i8xx_fbc_program_cfb,
};
static void i965_fbc_nuke(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc_state *fbc_state = &fbc->state;
enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
struct drm_i915_private *dev_priv = fbc->i915;
spin_lock_irq(&dev_priv->uncore.lock);
intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
intel_de_read_fw(dev_priv, DSPSURF(i9xx_plane)));
spin_unlock_irq(&dev_priv->uncore.lock);
}
2022-04-02 17:24:34 +05:00
static const struct intel_fbc_funcs i965_fbc_funcs = {
.activate = i8xx_fbc_activate,
.deactivate = i8xx_fbc_deactivate,
.is_active = i8xx_fbc_is_active,
.is_compressing = i8xx_fbc_is_compressing,
.nuke = i965_fbc_nuke,
.program_cfb = i8xx_fbc_program_cfb,
};
2022-04-02 17:24:34 +05:00
static u32 g4x_dpfc_ctl_limit(struct intel_fbc *fbc)
{
switch (fbc->limit) {
default:
2022-04-02 17:24:34 +05:00
MISSING_CASE(fbc->limit);
fallthrough;
case 1:
return DPFC_CTL_LIMIT_1X;
case 2:
return DPFC_CTL_LIMIT_2X;
case 4:
return DPFC_CTL_LIMIT_4X;
}
}
2022-04-02 17:24:34 +05:00
static u32 g4x_dpfc_ctl(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915;
u32 dpfc_ctl;
2022-04-02 17:24:34 +05:00
dpfc_ctl = g4x_dpfc_ctl_limit(fbc) |
DPFC_CTL_PLANE_G4X(fbc_state->plane->i9xx_plane);
2022-04-02 17:24:34 +05:00
if (IS_G4X(i915))
dpfc_ctl |= DPFC_CTL_SR_EN;
2022-04-02 17:24:34 +05:00
if (fbc_state->fence_id >= 0) {
dpfc_ctl |= DPFC_CTL_FENCE_EN_G4X;
if (DISPLAY_VER(i915) < 6)
dpfc_ctl |= DPFC_CTL_FENCENO(fbc_state->fence_id);
}
2022-04-02 17:24:34 +05:00
return dpfc_ctl;
}
static void g4x_fbc_activate(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915;
intel_de_write(i915, DPFC_FENCE_YOFF,
fbc_state->fence_y_offset);
intel_de_write(i915, DPFC_CONTROL,
DPFC_CTL_EN | g4x_dpfc_ctl(fbc));
}
2022-04-02 17:24:34 +05:00
static void g4x_fbc_deactivate(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = fbc->i915;
u32 dpfc_ctl;
/* Disable compression */
2022-04-02 17:24:34 +05:00
dpfc_ctl = intel_de_read(i915, DPFC_CONTROL);
if (dpfc_ctl & DPFC_CTL_EN) {
dpfc_ctl &= ~DPFC_CTL_EN;
2022-04-02 17:24:34 +05:00
intel_de_write(i915, DPFC_CONTROL, dpfc_ctl);
}
}
2022-04-02 17:24:34 +05:00
static bool g4x_fbc_is_active(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
return intel_de_read(fbc->i915, DPFC_CONTROL) & DPFC_CTL_EN;
}
2022-04-02 17:24:34 +05:00
static bool g4x_fbc_is_compressing(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
return intel_de_read(fbc->i915, DPFC_STATUS) & DPFC_COMP_SEG_MASK;
}
2022-04-02 17:24:34 +05:00
static void g4x_fbc_program_cfb(struct intel_fbc *fbc)
{
struct drm_i915_private *i915 = fbc->i915;
intel_de_write(i915, DPFC_CB_BASE, fbc->compressed_fb.start);
}
2022-04-02 17:24:34 +05:00
static const struct intel_fbc_funcs g4x_fbc_funcs = {
.activate = g4x_fbc_activate,
.deactivate = g4x_fbc_deactivate,
.is_active = g4x_fbc_is_active,
.is_compressing = g4x_fbc_is_compressing,
.nuke = i965_fbc_nuke,
.program_cfb = g4x_fbc_program_cfb,
};
static void ilk_fbc_activate(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915;
2022-04-02 17:24:34 +05:00
intel_de_write(i915, ILK_DPFC_FENCE_YOFF,
fbc_state->fence_y_offset);
intel_de_write(i915, ILK_DPFC_CONTROL,
DPFC_CTL_EN | g4x_dpfc_ctl(fbc));
}
2022-04-02 17:24:34 +05:00
static void ilk_fbc_deactivate(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = fbc->i915;
u32 dpfc_ctl;
2022-04-02 17:24:34 +05:00
/* Disable compression */
dpfc_ctl = intel_de_read(i915, ILK_DPFC_CONTROL);
if (dpfc_ctl & DPFC_CTL_EN) {
dpfc_ctl &= ~DPFC_CTL_EN;
intel_de_write(i915, ILK_DPFC_CONTROL, dpfc_ctl);
}
}
2022-04-02 17:24:34 +05:00
static bool ilk_fbc_is_active(struct intel_fbc *fbc)
{
return intel_de_read(fbc->i915, ILK_DPFC_CONTROL) & DPFC_CTL_EN;
}
2022-04-02 17:24:34 +05:00
static bool ilk_fbc_is_compressing(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
return intel_de_read(fbc->i915, ILK_DPFC_STATUS) & DPFC_COMP_SEG_MASK;
}
2022-04-02 17:24:34 +05:00
static void ilk_fbc_program_cfb(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = fbc->i915;
intel_de_write(i915, ILK_DPFC_CB_BASE, fbc->compressed_fb.start);
}
2022-04-02 17:24:34 +05:00
static const struct intel_fbc_funcs ilk_fbc_funcs = {
.activate = ilk_fbc_activate,
.deactivate = ilk_fbc_deactivate,
.is_active = ilk_fbc_is_active,
.is_compressing = ilk_fbc_is_compressing,
.nuke = i965_fbc_nuke,
.program_cfb = ilk_fbc_program_cfb,
};
2022-04-02 17:24:34 +05:00
static void snb_fbc_program_fence(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915;
u32 ctl = 0;
2022-04-02 17:24:34 +05:00
if (fbc_state->fence_id >= 0)
ctl = SNB_DPFC_FENCE_EN | SNB_DPFC_FENCENO(fbc_state->fence_id);
intel_de_write(i915, SNB_DPFC_CTL_SA, ctl);
intel_de_write(i915, SNB_DPFC_CPU_FENCE_OFFSET, fbc_state->fence_y_offset);
}
2022-04-02 17:24:34 +05:00
static void snb_fbc_activate(struct intel_fbc *fbc)
{
snb_fbc_program_fence(fbc);
2022-04-02 17:24:34 +05:00
ilk_fbc_activate(fbc);
}
2022-04-02 17:24:34 +05:00
static void snb_fbc_nuke(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = fbc->i915;
2022-04-02 17:24:34 +05:00
intel_de_write(i915, MSG_FBC_REND_STATE, FBC_REND_NUKE);
intel_de_posting_read(i915, MSG_FBC_REND_STATE);
}
static const struct intel_fbc_funcs snb_fbc_funcs = {
.activate = snb_fbc_activate,
.deactivate = ilk_fbc_deactivate,
.is_active = ilk_fbc_is_active,
.is_compressing = ilk_fbc_is_compressing,
.nuke = snb_fbc_nuke,
.program_cfb = ilk_fbc_program_cfb,
};
static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915;
u32 val = 0;
if (fbc_state->override_cfb_stride)
val |= FBC_STRIDE_OVERRIDE |
FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit);
intel_de_write(i915, GLK_FBC_STRIDE, val);
}
2022-04-02 17:24:34 +05:00
static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915;
u32 val = 0;
/* Display WA #0529: skl, kbl, bxt. */
if (fbc_state->override_cfb_stride)
val |= CHICKEN_FBC_STRIDE_OVERRIDE |
CHICKEN_FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit);
intel_de_rmw(i915, CHICKEN_MISC_4,
CHICKEN_FBC_STRIDE_OVERRIDE |
CHICKEN_FBC_STRIDE_MASK, val);
}
2022-04-02 17:24:34 +05:00
static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
const struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915;
u32 dpfc_ctl;
2022-04-02 17:24:34 +05:00
dpfc_ctl = g4x_dpfc_ctl_limit(fbc);
2022-04-02 17:24:34 +05:00
if (IS_IVYBRIDGE(i915))
dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane);
2022-04-02 17:24:34 +05:00
if (fbc_state->fence_id >= 0)
dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB;
2022-04-02 17:24:34 +05:00
if (fbc->false_color)
dpfc_ctl |= DPFC_CTL_FALSE_COLOR;
2022-04-02 17:24:34 +05:00
return dpfc_ctl;
}
static void ivb_fbc_activate(struct intel_fbc *fbc)
{
struct drm_i915_private *i915 = fbc->i915;
2022-04-02 17:24:34 +05:00
if (DISPLAY_VER(i915) >= 10)
glk_fbc_program_cfb_stride(fbc);
else if (DISPLAY_VER(i915) == 9)
skl_fbc_program_cfb_stride(fbc);
2022-04-02 17:24:34 +05:00
if (i915->ggtt.num_fences)
snb_fbc_program_fence(fbc);
2022-04-02 17:24:34 +05:00
intel_de_write(i915, ILK_DPFC_CONTROL,
DPFC_CTL_EN | ivb_dpfc_ctl(fbc));
}
2022-04-02 17:24:34 +05:00
static bool ivb_fbc_is_compressing(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
return intel_de_read(fbc->i915, ILK_DPFC_STATUS2) & 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,
DPFC_CTL_FALSE_COLOR, enable ? DPFC_CTL_FALSE_COLOR : 0);
}
2022-04-02 17:24:34 +05:00
static const struct intel_fbc_funcs ivb_fbc_funcs = {
.activate = ivb_fbc_activate,
.deactivate = ilk_fbc_deactivate,
.is_active = ilk_fbc_is_active,
.is_compressing = ivb_fbc_is_compressing,
.nuke = snb_fbc_nuke,
.program_cfb = ilk_fbc_program_cfb,
.set_false_color = ivb_fbc_set_false_color,
};
static bool intel_fbc_hw_is_active(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
return fbc->funcs->is_active(fbc);
}
2022-04-02 17:24:34 +05:00
static void intel_fbc_hw_activate(struct intel_fbc *fbc)
{
trace_intel_fbc_activate(fbc->state.plane);
fbc->active = true;
fbc->activated = true;
2022-04-02 17:24:34 +05:00
fbc->funcs->activate(fbc);
}
2022-04-02 17:24:34 +05:00
static void intel_fbc_hw_deactivate(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
trace_intel_fbc_deactivate(fbc->state.plane);
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
fbc->active = false;
2022-04-02 17:24:34 +05:00
fbc->funcs->deactivate(fbc);
}
2022-04-02 17:24:34 +05:00
static bool intel_fbc_is_compressing(struct intel_fbc *fbc)
{
return fbc->funcs->is_compressing(fbc);
}
static void intel_fbc_nuke(struct intel_fbc *fbc)
{
trace_intel_fbc_nuke(fbc->state.plane);
fbc->funcs->nuke(fbc);
}
static void intel_fbc_activate(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
intel_fbc_hw_activate(fbc);
intel_fbc_nuke(fbc);
fbc->no_fbc_reason = NULL;
}
2022-04-02 17:24:34 +05:00
static void intel_fbc_deactivate(struct intel_fbc *fbc, const char *reason)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = fbc->i915;
2022-04-02 17:24:34 +05:00
drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
if (fbc->active)
2022-04-02 17:24:34 +05:00
intel_fbc_hw_deactivate(fbc);
fbc->no_fbc_reason = reason;
}
static u64 intel_fbc_cfb_base_max(struct drm_i915_private *i915)
{
if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915))
return BIT_ULL(28);
else
return BIT_ULL(32);
}
2022-04-02 17:24:34 +05:00
static u64 intel_fbc_stolen_end(struct drm_i915_private *i915)
{
u64 end;
/* The FBC hardware for BDW/SKL doesn't have access to the stolen
* reserved range size, so it always assumes the maximum (8mb) is used.
* 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. */
2022-04-02 17:24:34 +05:00
if (IS_BROADWELL(i915) ||
(DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915)))
end = resource_size(&i915->dsm) - 8 * 1024 * 1024;
else
end = U64_MAX;
2022-04-02 17:24:34 +05:00
return min(end, intel_fbc_cfb_base_max(i915));
}
2022-04-02 17:24:34 +05:00
static int intel_fbc_min_limit(const struct intel_plane_state *plane_state)
{
2022-04-02 17:24:34 +05:00
return plane_state->hw.fb->format->cpp[0] == 2 ? 2 : 1;
}
2022-04-02 17:24:34 +05:00
static int intel_fbc_max_limit(struct drm_i915_private *i915)
{
/* WaFbcOnly1to1Ratio:ctg */
2022-04-02 17:24:34 +05:00
if (IS_G4X(i915))
return 1;
2022-04-02 17:24:34 +05:00
/*
* FBC2 can only do 1:1, 1:2, 1:4, we limit
* FBC1 to the same out of convenience.
*/
return 4;
}
2022-04-02 17:24:34 +05:00
static int find_compression_limit(struct intel_fbc *fbc,
unsigned int size, int min_limit)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = fbc->i915;
u64 end = intel_fbc_stolen_end(i915);
int ret, limit = min_limit;
size /= limit;
/* Try to over-allocate to reduce reallocations and fragmentation. */
2022-04-02 17:24:34 +05:00
ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
size <<= 1, 4096, 0, end);
if (ret == 0)
return limit;
2022-04-02 17:24:34 +05:00
for (; limit <= intel_fbc_max_limit(i915); limit <<= 1) {
ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
size >>= 1, 4096, 0, end);
if (ret == 0)
return limit;
}
return 0;
}
2022-04-02 17:24:34 +05:00
static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
unsigned int size, int min_limit)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = fbc->i915;
int ret;
2022-04-02 17:24:34 +05:00
drm_WARN_ON(&i915->drm,
drm_mm_node_allocated(&fbc->compressed_fb));
2022-04-02 17:24:34 +05:00
drm_WARN_ON(&i915->drm,
drm_mm_node_allocated(&fbc->compressed_llb));
2022-04-02 17:24:34 +05:00
if (DISPLAY_VER(i915) < 5 && !IS_G4X(i915)) {
ret = i915_gem_stolen_insert_node(i915, &fbc->compressed_llb,
4096, 4096);
if (ret)
goto err;
}
2022-04-02 17:24:34 +05:00
ret = find_compression_limit(fbc, size, min_limit);
if (!ret)
goto err_llb;
2022-04-02 17:24:34 +05:00
else if (ret > min_limit)
drm_info_once(&i915->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");
fbc->limit = ret;
2022-04-02 17:24:34 +05:00
drm_dbg_kms(&i915->drm,
"reserved %llu bytes of contiguous stolen space for FBC, limit: %d\n",
fbc->compressed_fb.size, fbc->limit);
return 0;
err_llb:
if (drm_mm_node_allocated(&fbc->compressed_llb))
2022-04-02 17:24:34 +05:00
i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
err:
2022-04-02 17:24:34 +05:00
if (drm_mm_initialized(&i915->mm.stolen))
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);
return -ENOSPC;
}
2022-04-02 17:24:34 +05:00
static void intel_fbc_program_cfb(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
fbc->funcs->program_cfb(fbc);
}
2022-04-02 17:24:34 +05:00
static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = fbc->i915;
2022-04-02 17:24:34 +05:00
if (WARN_ON(intel_fbc_hw_is_active(fbc)))
return;
if (drm_mm_node_allocated(&fbc->compressed_llb))
2022-04-02 17:24:34 +05:00
i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
if (drm_mm_node_allocated(&fbc->compressed_fb))
2022-04-02 17:24:34 +05:00
i915_gem_stolen_remove_node(i915, &fbc->compressed_fb);
}
2022-04-02 17:24:34 +05:00
void intel_fbc_cleanup(struct drm_i915_private *i915)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc *fbc = i915->fbc;
2022-04-02 17:24:34 +05:00
if (!fbc)
return;
mutex_lock(&fbc->lock);
2022-04-02 17:24:34 +05:00
__intel_fbc_cleanup_cfb(fbc);
mutex_unlock(&fbc->lock);
2022-04-02 17:24:34 +05:00
kfree(fbc);
}
2022-04-02 17:24:34 +05:00
static bool stride_is_valid(const struct intel_plane_state *plane_state)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int stride = intel_fbc_plane_stride(plane_state) *
fb->format->cpp[0];
/* This should have been caught earlier. */
2022-04-02 17:24:34 +05:00
if (drm_WARN_ON_ONCE(&i915->drm, (stride & (64 - 1)) != 0))
return false;
/* Below are the additional FBC restrictions. */
if (stride < 512)
return false;
2022-04-02 17:24:34 +05:00
if (DISPLAY_VER(i915) == 2 || DISPLAY_VER(i915) == 3)
return stride == 4096 || stride == 8192;
2022-04-02 17:24:34 +05:00
if (DISPLAY_VER(i915) == 4 && !IS_G4X(i915) && stride < 2048)
return false;
/* Display WA #1105: skl,bxt,kbl,cfl,glk */
2022-04-02 17:24:34 +05:00
if ((DISPLAY_VER(i915) == 9 || IS_GEMINILAKE(i915)) &&
fb->modifier == DRM_FORMAT_MOD_LINEAR && stride & 511)
return false;
if (stride > 16384)
return false;
return true;
}
2022-04-02 17:24:34 +05:00
static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
switch (fb->format->format) {
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_XBGR8888:
return true;
case DRM_FORMAT_XRGB1555:
case DRM_FORMAT_RGB565:
/* 16bpp not supported on gen2 */
2022-04-02 17:24:34 +05:00
if (DISPLAY_VER(i915) == 2)
return false;
/* WaFbcOnly1to1Ratio:ctg */
2022-04-02 17:24:34 +05:00
if (IS_G4X(i915))
return false;
return true;
default:
return false;
}
}
2022-04-02 17:24:34 +05:00
static bool rotation_is_valid(const struct intel_plane_state *plane_state)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int rotation = plane_state->hw.rotation;
if (DISPLAY_VER(i915) >= 9 && fb->format->format == DRM_FORMAT_RGB565 &&
drm_rotation_90_or_270(rotation))
return false;
2022-04-02 17:24:34 +05:00
else if (DISPLAY_VER(i915) <= 4 && !IS_G4X(i915) &&
rotation != DRM_MODE_ROTATE_0)
return false;
return true;
}
/*
* For some reason, the hardware tracking starts looking at whatever we
* programmed as the display plane base address register. It does not look at
* the X and Y offset registers. That's why we include the src x/y offsets
* instead of just looking at the plane size.
*/
2022-04-02 17:24:34 +05:00
static bool intel_fbc_hw_tracking_covers_screen(const struct intel_plane_state *plane_state)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
unsigned int effective_w, effective_h, max_w, max_h;
2022-04-02 17:24:34 +05:00
if (DISPLAY_VER(i915) >= 10) {
max_w = 5120;
max_h = 4096;
2022-04-02 17:24:34 +05:00
} else if (DISPLAY_VER(i915) >= 8 || IS_HASWELL(i915)) {
max_w = 4096;
max_h = 4096;
2022-04-02 17:24:34 +05:00
} else if (IS_G4X(i915) || DISPLAY_VER(i915) >= 5) {
max_w = 4096;
max_h = 2048;
} else {
max_w = 2048;
max_h = 1536;
}
2022-04-02 17:24:34 +05:00
effective_w = plane_state->view.color_plane[0].x +
(drm_rect_width(&plane_state->uapi.src) >> 16);
effective_h = plane_state->view.color_plane[0].y +
(drm_rect_height(&plane_state->uapi.src) >> 16);
return effective_w <= max_w && effective_h <= max_h;
}
2022-04-02 17:24:34 +05:00
static bool tiling_is_valid(const struct intel_plane_state *plane_state)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
switch (fb->modifier) {
case DRM_FORMAT_MOD_LINEAR:
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
case I915_FORMAT_MOD_Y_TILED:
2022-04-02 17:24:34 +05:00
case I915_FORMAT_MOD_Yf_TILED:
return DISPLAY_VER(i915) >= 9;
case I915_FORMAT_MOD_X_TILED:
return true;
default:
return false;
}
}
2022-04-02 17:24:34 +05:00
static void intel_fbc_update_state(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_plane *plane)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
const struct intel_plane_state *plane_state =
intel_atomic_get_new_plane_state(state, plane);
struct intel_fbc *fbc = plane->fbc;
struct intel_fbc_state *fbc_state = &fbc->state;
2022-04-02 17:24:34 +05:00
WARN_ON(plane_state->no_fbc_reason);
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
2022-04-02 17:24:34 +05:00
fbc_state->plane = plane;
/* FBC1 compression interval: arbitrary choice of 1 second */
2022-04-02 17:24:34 +05:00
fbc_state->interval = drm_mode_vrefresh(&crtc_state->hw.adjusted_mode);
2022-04-02 17:24:34 +05:00
fbc_state->fence_y_offset = intel_plane_fence_y_offset(plane_state);
2022-04-02 17:24:34 +05:00
drm_WARN_ON(&i915->drm, plane_state->flags & PLANE_HAS_FENCE &&
!plane_state->ggtt_vma->fence);
if (plane_state->flags & PLANE_HAS_FENCE &&
plane_state->ggtt_vma->fence)
2022-04-02 17:24:34 +05:00
fbc_state->fence_id = plane_state->ggtt_vma->fence->id;
else
2022-04-02 17:24:34 +05:00
fbc_state->fence_id = -1;
2022-04-02 17:24:34 +05:00
fbc_state->cfb_stride = intel_fbc_cfb_stride(plane_state);
fbc_state->cfb_size = intel_fbc_cfb_size(plane_state);
fbc_state->override_cfb_stride = intel_fbc_override_cfb_stride(plane_state);
}
2022-04-02 17:24:34 +05:00
static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
2022-04-02 17:24:34 +05:00
/* The use of a CPU fence is one of two ways to detect writes by the
* CPU to the scanout and trigger updates to the FBC.
*
* The other method is by software tracking (see
* intel_fbc_invalidate/flush()), it will manually notify FBC and nuke
* the current compressed buffer and recompress it.
*
* Note that is possible for a tiled surface to be unmappable (and
* so have no fence associated with it) due to aperture constraints
* at the time of pinning.
*
* FIXME with 90/270 degree rotation we should use the fence on
* the normal GTT view (the rotated view doesn't even have a
* fence). Would need changes to the FBC fence Y offset as well.
* For now this will effectively disable FBC with 90/270 degree
* rotation.
*/
return DISPLAY_VER(i915) >= 9 ||
(plane_state->flags & PLANE_HAS_FENCE &&
plane_state->ggtt_vma->fence);
}
2022-04-02 17:24:34 +05:00
static bool intel_fbc_is_cfb_ok(const struct intel_plane_state *plane_state)
{
2022-04-02 17:24:34 +05:00
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
struct intel_fbc *fbc = plane->fbc;
2022-04-02 17:24:34 +05:00
return intel_fbc_min_limit(plane_state) <= fbc->limit &&
intel_fbc_cfb_size(plane_state) <= fbc->compressed_fb.size * fbc->limit;
}
2022-04-02 17:24:34 +05:00
static bool intel_fbc_is_ok(const struct intel_plane_state *plane_state)
{
2022-04-02 17:24:34 +05:00
return !plane_state->no_fbc_reason &&
intel_fbc_is_fence_ok(plane_state) &&
intel_fbc_is_cfb_ok(plane_state);
}
2022-04-02 17:24:34 +05:00
static int intel_fbc_check_plane(struct intel_atomic_state *state,
struct intel_plane *plane)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_plane_state *plane_state =
intel_atomic_get_new_plane_state(state, plane);
const struct drm_framebuffer *fb = plane_state->hw.fb;
struct intel_crtc *crtc = to_intel_crtc(plane_state->uapi.crtc);
const struct intel_crtc_state *crtc_state;
struct intel_fbc *fbc = plane->fbc;
2022-04-02 17:24:34 +05:00
if (!fbc)
return 0;
2022-04-02 17:24:34 +05:00
if (intel_vgpu_active(i915)) {
plane_state->no_fbc_reason = "VGPU active";
return 0;
}
2022-04-02 17:24:34 +05:00
if (!i915->params.enable_fbc) {
plane_state->no_fbc_reason = "disabled per module param or by default";
return 0;
}
2022-04-02 17:24:34 +05:00
if (!plane_state->uapi.visible) {
plane_state->no_fbc_reason = "plane not visible";
return 0;
}
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
2022-04-02 17:24:34 +05:00
crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
2022-04-02 17:24:34 +05:00
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
plane_state->no_fbc_reason = "interlaced mode not supported";
return 0;
}
2022-04-02 17:24:34 +05:00
if (crtc_state->double_wide) {
plane_state->no_fbc_reason = "double wide pipe not supported";
return 0;
}
2022-04-02 17:24:34 +05:00
/*
* Display 12+ is not supporting FBC with PSR2.
* Recommendation is to keep this combination disabled
* Bspec: 50422 HSD: 14010260002
*/
2022-04-02 17:24:34 +05:00
if (DISPLAY_VER(i915) >= 12 && crtc_state->has_psr2) {
plane_state->no_fbc_reason = "PSR2 enabled";
return false;
}
2022-04-02 17:24:34 +05:00
if (!pixel_format_is_valid(plane_state)) {
plane_state->no_fbc_reason = "pixel format not supported";
return 0;
}
2022-04-02 17:24:34 +05:00
if (!tiling_is_valid(plane_state)) {
plane_state->no_fbc_reason = "tiling not supported";
return 0;
}
2022-04-02 17:24:34 +05:00
if (!rotation_is_valid(plane_state)) {
plane_state->no_fbc_reason = "rotation not supported";
return 0;
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
}
2022-04-02 17:24:34 +05:00
if (!stride_is_valid(plane_state)) {
plane_state->no_fbc_reason = "stride not supported";
return 0;
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
}
2022-04-02 17:24:34 +05:00
if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE &&
fb->format->has_alpha) {
plane_state->no_fbc_reason = "per-pixel alpha not supported";
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
return false;
}
2022-04-02 17:24:34 +05:00
if (!intel_fbc_hw_tracking_covers_screen(plane_state)) {
plane_state->no_fbc_reason = "plane size too big";
return 0;
}
/*
* Work around a problem on GEN9+ HW, where enabling FBC on a plane
* having a Y offset that isn't divisible by 4 causes FIFO underrun
* and screen flicker.
*/
2022-04-02 17:24:34 +05:00
if (DISPLAY_VER(i915) >= 9 &&
plane_state->view.color_plane[0].y & 3) {
plane_state->no_fbc_reason = "plane start Y offset misaligned";
return false;
}
/* Wa_22010751166: icl, ehl, tgl, dg1, rkl */
2022-04-02 17:24:34 +05:00
if (DISPLAY_VER(i915) >= 11 &&
(plane_state->view.color_plane[0].y +
(drm_rect_height(&plane_state->uapi.src) >> 16)) & 3) {
plane_state->no_fbc_reason = "plane end Y offset misaligned";
return false;
}
2022-04-02 17:24:34 +05:00
/* WaFbcExceedCdClockThreshold:hsw,bdw */
if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
const struct intel_cdclk_state *cdclk_state;
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
2022-04-02 17:24:34 +05:00
cdclk_state = intel_atomic_get_cdclk_state(state);
if (IS_ERR(cdclk_state))
return PTR_ERR(cdclk_state);
2022-04-02 17:24:34 +05:00
if (crtc_state->pixel_rate >= cdclk_state->logical.cdclk * 95 / 100) {
plane_state->no_fbc_reason = "pixel rate too high";
return 0;
}
}
2022-04-02 17:24:34 +05:00
plane_state->no_fbc_reason = NULL;
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
2022-04-02 17:24:34 +05:00
return 0;
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
}
2022-04-02 17:24:34 +05:00
static bool intel_fbc_can_flip_nuke(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_plane *plane)
{
2022-04-02 17:24:34 +05:00
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
const struct intel_plane_state *old_plane_state =
intel_atomic_get_old_plane_state(state, plane);
const struct intel_plane_state *new_plane_state =
intel_atomic_get_new_plane_state(state, plane);
const struct drm_framebuffer *old_fb = old_plane_state->hw.fb;
const struct drm_framebuffer *new_fb = new_plane_state->hw.fb;
2022-04-02 17:24:34 +05:00
if (drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi))
return false;
2022-04-02 17:24:34 +05:00
if (!intel_fbc_is_ok(old_plane_state) ||
!intel_fbc_is_ok(new_plane_state))
return false;
2022-04-02 17:24:34 +05:00
if (old_fb->format->format != new_fb->format->format)
return false;
2022-04-02 17:24:34 +05:00
if (old_fb->modifier != new_fb->modifier)
return false;
2022-04-02 17:24:34 +05:00
if (intel_fbc_plane_stride(old_plane_state) !=
intel_fbc_plane_stride(new_plane_state))
return false;
2022-04-02 17:24:34 +05:00
if (intel_fbc_cfb_stride(old_plane_state) !=
intel_fbc_cfb_stride(new_plane_state))
return false;
2022-04-02 17:24:34 +05:00
if (intel_fbc_cfb_size(old_plane_state) !=
intel_fbc_cfb_size(new_plane_state))
return false;
2022-04-02 17:24:34 +05:00
if (intel_fbc_override_cfb_stride(old_plane_state) !=
intel_fbc_override_cfb_stride(new_plane_state))
return false;
return true;
}
2022-04-02 17:24:34 +05:00
static bool __intel_fbc_pre_update(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_plane *plane)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_fbc *fbc = plane->fbc;
bool need_vblank_wait = false;
2022-04-02 17:24:34 +05:00
fbc->flip_pending = true;
2022-04-02 17:24:34 +05:00
if (intel_fbc_can_flip_nuke(state, crtc, plane))
return need_vblank_wait;
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
2022-04-02 17:24:34 +05:00
intel_fbc_deactivate(fbc, "update pending");
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
2022-04-02 17:24:34 +05:00
/*
* Display WA #1198: glk+
* Need an extra vblank wait between FBC disable and most plane
* updates. Bspec says this is only needed for plane disable, but
* that is not true. Touching most plane registers will cause the
* corruption to appear. Also SKL/derivatives do not seem to be
* affected.
*
* TODO: could optimize this a bit by sampling the frame
* counter when we disable FBC (if it was already done earlier)
* and skipping the extra vblank wait before the plane update
* if at least one frame has already passed.
*/
if (fbc->activated && DISPLAY_VER(i915) >= 10)
need_vblank_wait = true;
fbc->activated = false;
return need_vblank_wait;
}
2022-04-02 17:24:34 +05:00
bool intel_fbc_pre_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
2022-04-02 17:24:34 +05:00
const struct intel_plane_state *plane_state;
bool need_vblank_wait = false;
struct intel_plane *plane;
int i;
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
struct intel_fbc *fbc = plane->fbc;
if (!fbc || plane->pipe != crtc->pipe)
continue;
2022-04-02 17:24:34 +05:00
mutex_lock(&fbc->lock);
2022-04-02 17:24:34 +05:00
if (fbc->state.plane == plane)
need_vblank_wait |= __intel_fbc_pre_update(state, crtc, plane);
2022-04-02 17:24:34 +05:00
mutex_unlock(&fbc->lock);
}
2022-04-02 17:24:34 +05:00
return need_vblank_wait;
}
2022-04-02 17:24:34 +05:00
static void __intel_fbc_disable(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = fbc->i915;
struct intel_plane *plane = fbc->state.plane;
2022-04-02 17:24:34 +05:00
drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
drm_WARN_ON(&i915->drm, fbc->active);
2022-04-02 17:24:34 +05:00
drm_dbg_kms(&i915->drm, "Disabling FBC on [PLANE:%d:%s]\n",
plane->base.base.id, plane->base.name);
2022-04-02 17:24:34 +05:00
__intel_fbc_cleanup_cfb(fbc);
2022-04-02 17:24:34 +05:00
fbc->state.plane = NULL;
}
2022-04-02 17:24:34 +05:00
static void __intel_fbc_post_update(struct intel_fbc *fbc)
{
struct drm_i915_private *i915 = fbc->i915;
2022-04-02 17:24:34 +05:00
drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
if (!fbc->busy_bits)
2022-04-02 17:24:34 +05:00
intel_fbc_activate(fbc);
else
2022-04-02 17:24:34 +05:00
intel_fbc_deactivate(fbc, "frontbuffer write");
}
void intel_fbc_post_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
2022-04-02 17:24:34 +05:00
const struct intel_plane_state *plane_state;
struct intel_plane *plane;
int i;
2022-04-02 17:24:34 +05:00
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
struct intel_fbc *fbc = plane->fbc;
2022-04-02 17:24:34 +05:00
if (!fbc || plane->pipe != crtc->pipe)
continue;
mutex_lock(&fbc->lock);
if (fbc->state.plane == plane) {
fbc->flip_pending = false;
__intel_fbc_post_update(fbc);
}
mutex_unlock(&fbc->lock);
}
}
static unsigned int intel_fbc_get_frontbuffer_bit(struct intel_fbc *fbc)
{
2022-04-02 17:24:34 +05:00
if (fbc->state.plane)
return fbc->state.plane->frontbuffer_bit;
else
return fbc->possible_framebuffer_bits;
}
2022-04-02 17:24:34 +05:00
void intel_fbc_invalidate(struct drm_i915_private *i915,
unsigned int frontbuffer_bits,
enum fb_op_origin origin)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc *fbc = i915->fbc;
2022-04-02 17:24:34 +05:00
if (!fbc)
return;
2022-04-02 17:24:34 +05:00
if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE)
return;
mutex_lock(&fbc->lock);
fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits;
2022-04-02 17:24:34 +05:00
if (fbc->state.plane && fbc->busy_bits)
intel_fbc_deactivate(fbc, "frontbuffer write");
mutex_unlock(&fbc->lock);
}
2022-04-02 17:24:34 +05:00
void intel_fbc_flush(struct drm_i915_private *i915,
unsigned int frontbuffer_bits, enum fb_op_origin origin)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc *fbc = i915->fbc;
2022-04-02 17:24:34 +05:00
if (!fbc)
return;
mutex_lock(&fbc->lock);
fbc->busy_bits &= ~frontbuffer_bits;
2022-04-02 17:24:34 +05:00
if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE)
goto out;
2022-04-02 17:24:34 +05:00
if (!fbc->busy_bits && fbc->state.plane &&
(frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) {
if (fbc->active)
2022-04-02 17:24:34 +05:00
intel_fbc_nuke(fbc);
else if (!fbc->flip_pending)
2022-04-02 17:24:34 +05:00
__intel_fbc_post_update(fbc);
}
out:
mutex_unlock(&fbc->lock);
}
2022-04-02 17:24:34 +05:00
int intel_fbc_atomic_check(struct intel_atomic_state *state)
{
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
struct intel_plane_state *plane_state;
2022-04-02 17:24:34 +05:00
struct intel_plane *plane;
int i;
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
2022-04-02 17:24:34 +05:00
int ret;
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
2022-04-02 17:24:34 +05:00
ret = intel_fbc_check_plane(state, plane);
if (ret)
return ret;
}
2022-04-02 17:24:34 +05:00
return 0;
}
2022-04-02 17:24:34 +05:00
static void __intel_fbc_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_plane *plane)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_plane_state *plane_state =
intel_atomic_get_new_plane_state(state, plane);
2022-04-02 17:24:34 +05:00
struct intel_fbc *fbc = plane->fbc;
2022-04-02 17:24:34 +05:00
if (fbc->state.plane) {
if (fbc->state.plane != plane)
return;
2022-04-02 17:24:34 +05:00
if (intel_fbc_is_ok(plane_state)) {
intel_fbc_update_state(state, crtc, plane);
return;
}
2022-04-02 17:24:34 +05:00
__intel_fbc_disable(fbc);
}
2022-04-02 17:24:34 +05:00
drm_WARN_ON(&i915->drm, fbc->active);
2022-04-02 17:24:34 +05:00
fbc->no_fbc_reason = plane_state->no_fbc_reason;
if (fbc->no_fbc_reason)
return;
2022-04-02 17:24:34 +05:00
if (!intel_fbc_is_fence_ok(plane_state)) {
fbc->no_fbc_reason = "framebuffer not fenced";
return;
}
2022-04-02 17:24:34 +05:00
if (fbc->underrun_detected) {
fbc->no_fbc_reason = "FIFO underrun";
return;
}
2022-04-02 17:24:34 +05:00
if (intel_fbc_alloc_cfb(fbc, intel_fbc_cfb_size(plane_state),
intel_fbc_min_limit(plane_state))) {
fbc->no_fbc_reason = "not enough stolen memory";
return;
}
There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
2022-03-15 21:13:23 +05:00
2022-04-02 17:24:34 +05:00
drm_dbg_kms(&i915->drm, "Enabling FBC on [PLANE:%d:%s]\n",
plane->base.base.id, plane->base.name);
fbc->no_fbc_reason = "FBC enabled but not active yet\n";
2022-04-02 17:24:34 +05:00
intel_fbc_update_state(state, crtc, plane);
2022-04-02 17:24:34 +05:00
intel_fbc_program_cfb(fbc);
}
/**
* intel_fbc_disable - disable FBC if it's associated with crtc
* @crtc: the CRTC
*
* This function disables FBC if it's associated with the provided CRTC.
*/
void intel_fbc_disable(struct intel_crtc *crtc)
{
2022-04-02 17:24:34 +05:00
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_plane *plane;
2022-04-02 17:24:34 +05:00
for_each_intel_plane(&i915->drm, plane) {
struct intel_fbc *fbc = plane->fbc;
2022-04-02 17:24:34 +05:00
if (!fbc || plane->pipe != crtc->pipe)
continue;
mutex_lock(&fbc->lock);
if (fbc->state.plane == plane)
__intel_fbc_disable(fbc);
mutex_unlock(&fbc->lock);
}
}
void intel_fbc_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
const struct intel_plane_state *plane_state;
struct intel_plane *plane;
int i;
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
struct intel_fbc *fbc = plane->fbc;
if (!fbc || plane->pipe != crtc->pipe)
continue;
mutex_lock(&fbc->lock);
if (crtc_state->update_pipe && plane_state->no_fbc_reason) {
if (fbc->state.plane == plane)
__intel_fbc_disable(fbc);
} else {
__intel_fbc_enable(state, crtc, plane);
}
mutex_unlock(&fbc->lock);
}
}
/**
* intel_fbc_global_disable - globally disable FBC
2022-04-02 17:24:34 +05:00
* @i915: i915 device instance
*
* This function disables FBC regardless of which CRTC is associated with it.
*/
2022-04-02 17:24:34 +05:00
void intel_fbc_global_disable(struct drm_i915_private *i915)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc *fbc = i915->fbc;
2022-04-02 17:24:34 +05:00
if (!fbc)
return;
mutex_lock(&fbc->lock);
2022-04-02 17:24:34 +05:00
if (fbc->state.plane)
__intel_fbc_disable(fbc);
mutex_unlock(&fbc->lock);
}
static void intel_fbc_underrun_work_fn(struct work_struct *work)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc *fbc = container_of(work, typeof(*fbc), underrun_work);
struct drm_i915_private *i915 = fbc->i915;
mutex_lock(&fbc->lock);
/* Maybe we were scheduled twice. */
2022-04-02 17:24:34 +05:00
if (fbc->underrun_detected || !fbc->state.plane)
goto out;
2022-04-02 17:24:34 +05:00
drm_dbg_kms(&i915->drm, "Disabling FBC due to FIFO underrun.\n");
fbc->underrun_detected = true;
2022-04-02 17:24:34 +05:00
intel_fbc_deactivate(fbc, "FIFO underrun");
if (!fbc->flip_pending)
intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(i915, fbc->state.plane->pipe));
__intel_fbc_disable(fbc);
out:
mutex_unlock(&fbc->lock);
}
/*
* intel_fbc_reset_underrun - reset FBC fifo underrun status.
2022-04-02 17:24:34 +05:00
* @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.
*/
2022-04-02 17:24:34 +05:00
void intel_fbc_reset_underrun(struct drm_i915_private *i915)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc *fbc = i915->fbc;
if (!fbc)
return;
2022-04-02 17:24:34 +05:00
cancel_work_sync(&fbc->underrun_work);
2022-04-02 17:24:34 +05:00
mutex_lock(&fbc->lock);
2022-04-02 17:24:34 +05:00
if (fbc->underrun_detected) {
drm_dbg_kms(&i915->drm,
"Re-allowing FBC after fifo underrun\n");
2022-04-02 17:24:34 +05:00
fbc->no_fbc_reason = "FIFO underrun cleared";
}
2022-04-02 17:24:34 +05:00
fbc->underrun_detected = false;
mutex_unlock(&fbc->lock);
}
/**
* intel_fbc_handle_fifo_underrun_irq - disable FBC when we get a FIFO underrun
2022-04-02 17:24:34 +05:00
* @i915: i915 device
*
* 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
* become black screens or even worse, especially when paired with bad
* watermarks. So in order for us to be on the safe side, completely disable FBC
* in case we ever detect a FIFO underrun on any pipe. An underrun on any pipe
* already suggests that watermarks may be bad, so try to be as safe as
* possible.
*
* This function is called from the IRQ handler.
*/
2022-04-02 17:24:34 +05:00
void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc *fbc = i915->fbc;
2022-04-02 17:24:34 +05:00
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;
schedule_work(&fbc->underrun_work);
}
/*
* The DDX driver changes its behavior depending on the value it reads from
* i915.enable_fbc, so sanitize it by translating the default value into either
* 0 or 1 in order to allow it to know what's going on.
*
* Notice that this is done at driver initialization and we still allow user
* space to change the value during runtime without sanitizing it again. IGT
* relies on being able to change i915.enable_fbc at runtime.
*/
2022-04-02 17:24:34 +05:00
static int intel_sanitize_fbc_option(struct drm_i915_private *i915)
{
2022-04-02 17:24:34 +05:00
if (i915->params.enable_fbc >= 0)
return !!i915->params.enable_fbc;
2022-04-02 17:24:34 +05:00
if (!HAS_FBC(i915))
return 0;
2022-04-02 17:24:34 +05:00
if (IS_BROADWELL(i915) || DISPLAY_VER(i915) >= 9)
return 1;
return 0;
}
2022-04-02 17:24:34 +05:00
static bool need_fbc_vtd_wa(struct drm_i915_private *i915)
{
/* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */
2022-04-02 17:24:34 +05:00
if (intel_vtd_active(i915) &&
(IS_SKYLAKE(i915) || IS_BROXTON(i915))) {
drm_info(&i915->drm,
"Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n");
return true;
}
return false;
}
2022-04-02 17:24:34 +05:00
void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane)
{
if (!fbc)
return;
plane->fbc = fbc;
fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
}
static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915)
{
struct intel_fbc *fbc;
fbc = kzalloc(sizeof(*fbc), GFP_KERNEL);
if (!fbc)
return NULL;
fbc->i915 = i915;
INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
mutex_init(&fbc->lock);
if (DISPLAY_VER(i915) >= 7)
fbc->funcs = &ivb_fbc_funcs;
else if (DISPLAY_VER(i915) == 6)
fbc->funcs = &snb_fbc_funcs;
else if (DISPLAY_VER(i915) == 5)
fbc->funcs = &ilk_fbc_funcs;
else if (IS_G4X(i915))
fbc->funcs = &g4x_fbc_funcs;
else if (DISPLAY_VER(i915) == 4)
fbc->funcs = &i965_fbc_funcs;
else
fbc->funcs = &i8xx_fbc_funcs;
return fbc;
}
/**
* intel_fbc_init - Initialize FBC
2022-04-02 17:24:34 +05:00
* @i915: the i915 device
*
* This function might be called during PM init process.
*/
2022-04-02 17:24:34 +05:00
void intel_fbc_init(struct drm_i915_private *i915)
{
2022-04-02 17:24:34 +05:00
struct intel_fbc *fbc;
2022-04-02 17:24:34 +05:00
if (!drm_mm_initialized(&i915->mm.stolen))
mkwrite_device_info(i915)->display.has_fbc = false;
2022-04-02 17:24:34 +05:00
if (need_fbc_vtd_wa(i915))
mkwrite_device_info(i915)->display.has_fbc = false;
2022-04-02 17:24:34 +05:00
i915->params.enable_fbc = intel_sanitize_fbc_option(i915);
drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n",
i915->params.enable_fbc);
2022-04-02 17:24:34 +05:00
if (!HAS_FBC(i915))
return;
2022-04-02 17:24:34 +05:00
fbc = intel_fbc_create(i915);
if (!fbc)
return;
/* We still don't have any sort of hardware state readout for FBC, so
* deactivate it in case the BIOS activated it to make sure software
* matches the hardware state. */
2022-04-02 17:24:34 +05:00
if (intel_fbc_hw_is_active(fbc))
intel_fbc_hw_deactivate(fbc);
i915->fbc = fbc;
}
static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused)
{
struct intel_fbc *fbc = m->private;
struct drm_i915_private *i915 = fbc->i915;
struct intel_plane *plane;
intel_wakeref_t wakeref;
drm_modeset_lock_all(&i915->drm);
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
mutex_lock(&fbc->lock);
if (fbc->active) {
seq_puts(m, "FBC enabled\n");
seq_printf(m, "Compressing: %s\n",
yesno(intel_fbc_is_compressing(fbc)));
} else {
seq_printf(m, "FBC disabled: %s\n", fbc->no_fbc_reason);
}
for_each_intel_plane(&i915->drm, plane) {
const struct intel_plane_state *plane_state =
to_intel_plane_state(plane->base.state);
if (plane->fbc != fbc)
continue;
seq_printf(m, "%c [PLANE:%d:%s]: %s\n",
fbc->state.plane == plane ? '*' : ' ',
plane->base.base.id, plane->base.name,
plane_state->no_fbc_reason ?: "FBC possible");
}
mutex_unlock(&fbc->lock);
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
drm_modeset_unlock_all(&i915->drm);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(intel_fbc_debugfs_status);
static int intel_fbc_debugfs_false_color_get(void *data, u64 *val)
{
struct intel_fbc *fbc = data;
*val = fbc->false_color;
return 0;
}
static int intel_fbc_debugfs_false_color_set(void *data, u64 val)
{
struct intel_fbc *fbc = data;
mutex_lock(&fbc->lock);
fbc->false_color = val;
if (fbc->active)
fbc->funcs->set_false_color(fbc, fbc->false_color);
mutex_unlock(&fbc->lock);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(intel_fbc_debugfs_false_color_fops,
intel_fbc_debugfs_false_color_get,
intel_fbc_debugfs_false_color_set,
"%llu\n");
static void intel_fbc_debugfs_add(struct intel_fbc *fbc)
{
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);
if (fbc->funcs->set_false_color)
debugfs_create_file("i915_fbc_false_color", 0644,
minor->debugfs_root, fbc,
&intel_fbc_debugfs_false_color_fops);
}
void intel_fbc_debugfs_register(struct drm_i915_private *i915)
{
struct intel_fbc *fbc = i915->fbc;
if (fbc)
intel_fbc_debugfs_add(fbc);
}