summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/i9xx_plane.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/i9xx_plane.c')
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_plane.c373
1 files changed, 221 insertions, 152 deletions
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 17a1e3801a85..013295f66d56 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -8,6 +8,7 @@
#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
+#include "i915_drv.h"
#include "i915_reg.h"
#include "i9xx_plane.h"
#include "i9xx_plane_regs.h"
@@ -108,42 +109,42 @@ static bool i965_plane_format_mod_supported(struct drm_plane *_plane,
}
}
-static bool i9xx_plane_has_fbc(struct drm_i915_private *dev_priv,
+static bool i9xx_plane_has_fbc(struct intel_display *display,
enum i9xx_plane_id i9xx_plane)
{
- if (!HAS_FBC(dev_priv))
+ if (!HAS_FBC(display))
return false;
- if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
+ if (display->platform.broadwell || display->platform.haswell)
return i9xx_plane == PLANE_A; /* tied to pipe A */
- else if (IS_IVYBRIDGE(dev_priv))
+ else if (display->platform.ivybridge)
return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B ||
i9xx_plane == PLANE_C;
- else if (DISPLAY_VER(dev_priv) >= 4)
+ else if (DISPLAY_VER(display) >= 4)
return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B;
else
return i9xx_plane == PLANE_A;
}
-static struct intel_fbc *i9xx_plane_fbc(struct drm_i915_private *dev_priv,
+static struct intel_fbc *i9xx_plane_fbc(struct intel_display *display,
enum i9xx_plane_id i9xx_plane)
{
- if (i9xx_plane_has_fbc(dev_priv, i9xx_plane))
- return dev_priv->display.fbc[INTEL_FBC_A];
+ if (i9xx_plane_has_fbc(display, i9xx_plane))
+ return display->fbc[INTEL_FBC_A];
else
return NULL;
}
static bool i9xx_plane_has_windowing(struct intel_plane *plane)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane);
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
- if (IS_CHERRYVIEW(dev_priv))
+ if (display->platform.cherryview)
return i9xx_plane == PLANE_B;
- else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
+ else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
return false;
- else if (DISPLAY_VER(dev_priv) == 4)
+ else if (DISPLAY_VER(display) == 4)
return i9xx_plane == PLANE_C;
else
return i9xx_plane == PLANE_B ||
@@ -153,16 +154,15 @@ static bool i9xx_plane_has_windowing(struct intel_plane *plane)
static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
- struct drm_i915_private *dev_priv =
- to_i915(plane_state->uapi.plane->dev);
+ struct intel_display *display = to_intel_display(plane_state);
const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int rotation = plane_state->hw.rotation;
u32 dspcntr;
dspcntr = DISP_ENABLE;
- if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) ||
- IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv))
+ if (display->platform.g4x || display->platform.ironlake ||
+ display->platform.sandybridge || display->platform.ivybridge)
dspcntr |= DISP_TRICKLE_FEED_DISABLE;
switch (fb->format->format) {
@@ -210,7 +210,7 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
return 0;
}
- if (DISPLAY_VER(dev_priv) >= 4 &&
+ if (DISPLAY_VER(display) >= 4 &&
fb->modifier == I915_FORMAT_MOD_X_TILED)
dspcntr |= DISP_TILED;
@@ -225,8 +225,8 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
{
+ struct intel_display *display = to_intel_display(plane_state);
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
int src_x, src_y, src_w;
u32 offset;
@@ -244,12 +244,16 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
src_y = plane_state->uapi.src.y1 >> 16;
/* Undocumented hardware limit on i965/g4x/vlv/chv */
- if (HAS_GMCH(dev_priv) && fb->format->cpp[0] == 8 && src_w > 2048)
+ if (HAS_GMCH(display) && fb->format->cpp[0] == 8 && src_w > 2048) {
+ drm_dbg_kms(display->drm,
+ "[PLANE:%d:%s] plane too wide (%d) for 64bpp\n",
+ plane->base.base.id, plane->base.name, src_w);
return -EINVAL;
+ }
intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
- if (DISPLAY_VER(dev_priv) >= 4)
+ if (DISPLAY_VER(display) >= 4)
offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
plane_state, 0);
else
@@ -266,14 +270,15 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
* Linear surfaces seem to work just fine, even on hsw/bdw
* despite them not using the linear offset anymore.
*/
- if (DISPLAY_VER(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
+ if (DISPLAY_VER(display) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
unsigned int alignment = plane->min_alignment(plane, fb, 0);
int cpp = fb->format->cpp[0];
while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].mapping_stride) {
if (offset == 0) {
- drm_dbg_kms(&dev_priv->drm,
- "Unable to find suitable display surface offset due to X-tiling\n");
+ drm_dbg_kms(display->drm,
+ "[PLANE:%d:%s] unable to find suitable display surface offset due to X-tiling\n",
+ plane->base.base.id, plane->base.name);
return -EINVAL;
}
@@ -290,7 +295,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
src_x << 16, src_y << 16);
/* HSW/BDW do this automagically in hardware */
- if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) {
+ if (!display->platform.haswell && !display->platform.broadwell) {
unsigned int rotation = plane_state->hw.rotation;
int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
@@ -303,11 +308,11 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
}
}
- if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
- drm_WARN_ON(&dev_priv->drm, src_x > 8191 || src_y > 4095);
- } else if (DISPLAY_VER(dev_priv) >= 4 &&
+ if (display->platform.haswell || display->platform.broadwell) {
+ drm_WARN_ON(display->drm, src_x > 8191 || src_y > 4095);
+ } else if (DISPLAY_VER(display) >= 4 &&
fb->modifier == I915_FORMAT_MOD_X_TILED) {
- drm_WARN_ON(&dev_priv->drm, src_x > 4095 || src_y > 4095);
+ drm_WARN_ON(display->drm, src_x > 4095 || src_y > 4095);
}
plane_state->view.color_plane[0].offset = offset;
@@ -353,8 +358,8 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state,
static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
{
+ struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dspcntr = 0;
if (crtc_state->gamma_enable)
@@ -363,7 +368,7 @@ static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
if (crtc_state->csc_enable)
dspcntr |= DISP_PIPE_CSC_ENABLE;
- if (DISPLAY_VER(dev_priv) < 5)
+ if (DISPLAY_VER(display) < 5)
dspcntr |= DISP_PIPE_SEL(crtc->pipe);
return dspcntr;
@@ -421,13 +426,13 @@ static void i9xx_plane_update_noarm(struct intel_dsb *dsb,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane);
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
- intel_de_write_fw(dev_priv, DSPSTRIDE(dev_priv, i9xx_plane),
+ intel_de_write_fw(display, DSPSTRIDE(display, i9xx_plane),
plane_state->view.color_plane[0].mapping_stride);
- if (DISPLAY_VER(dev_priv) < 4) {
+ if (DISPLAY_VER(display) < 4) {
int crtc_x = plane_state->uapi.dst.x1;
int crtc_y = plane_state->uapi.dst.y1;
int crtc_w = drm_rect_width(&plane_state->uapi.dst);
@@ -438,9 +443,9 @@ static void i9xx_plane_update_noarm(struct intel_dsb *dsb,
* generator but let's assume we still need to
* program whatever is there.
*/
- intel_de_write_fw(dev_priv, DSPPOS(dev_priv, i9xx_plane),
+ intel_de_write_fw(display, DSPPOS(display, i9xx_plane),
DISP_POS_Y(crtc_y) | DISP_POS_X(crtc_x));
- intel_de_write_fw(dev_priv, DSPSIZE(dev_priv, i9xx_plane),
+ intel_de_write_fw(display, DSPSIZE(display, i9xx_plane),
DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1));
}
}
@@ -450,7 +455,7 @@ static void i9xx_plane_update_arm(struct intel_dsb *dsb,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane);
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
int x = plane_state->view.color_plane[0].x;
int y = plane_state->view.color_plane[0].y;
@@ -465,32 +470,32 @@ static void i9xx_plane_update_arm(struct intel_dsb *dsb,
linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
- if (DISPLAY_VER(dev_priv) >= 4)
+ if (DISPLAY_VER(display) >= 4)
dspaddr_offset = plane_state->view.color_plane[0].offset;
else
dspaddr_offset = linear_offset;
- if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
+ if (display->platform.cherryview && i9xx_plane == PLANE_B) {
int crtc_x = plane_state->uapi.dst.x1;
int crtc_y = plane_state->uapi.dst.y1;
int crtc_w = drm_rect_width(&plane_state->uapi.dst);
int crtc_h = drm_rect_height(&plane_state->uapi.dst);
- intel_de_write_fw(dev_priv, PRIMPOS(dev_priv, i9xx_plane),
+ intel_de_write_fw(display, PRIMPOS(display, i9xx_plane),
PRIM_POS_Y(crtc_y) | PRIM_POS_X(crtc_x));
- intel_de_write_fw(dev_priv, PRIMSIZE(dev_priv, i9xx_plane),
+ intel_de_write_fw(display, PRIMSIZE(display, i9xx_plane),
PRIM_HEIGHT(crtc_h - 1) | PRIM_WIDTH(crtc_w - 1));
- intel_de_write_fw(dev_priv,
- PRIMCNSTALPHA(dev_priv, i9xx_plane), 0);
+ intel_de_write_fw(display,
+ PRIMCNSTALPHA(display, i9xx_plane), 0);
}
- if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
- intel_de_write_fw(dev_priv, DSPOFFSET(dev_priv, i9xx_plane),
+ if (display->platform.haswell || display->platform.broadwell) {
+ intel_de_write_fw(display, DSPOFFSET(display, i9xx_plane),
DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
- } else if (DISPLAY_VER(dev_priv) >= 4) {
- intel_de_write_fw(dev_priv, DSPLINOFF(dev_priv, i9xx_plane),
+ } else if (DISPLAY_VER(display) >= 4) {
+ intel_de_write_fw(display, DSPLINOFF(display, i9xx_plane),
linear_offset);
- intel_de_write_fw(dev_priv, DSPTILEOFF(dev_priv, i9xx_plane),
+ intel_de_write_fw(display, DSPTILEOFF(display, i9xx_plane),
DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
}
@@ -499,13 +504,13 @@ static void i9xx_plane_update_arm(struct intel_dsb *dsb,
* disabled. Try to make the plane enable atomic by writing
* the control register just before the surface register.
*/
- intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
+ intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
- if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
+ if (DISPLAY_VER(display) >= 4)
+ intel_de_write_fw(display, DSPSURF(display, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
else
- intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane),
+ intel_de_write_fw(display, DSPADDR(display, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
}
@@ -528,7 +533,7 @@ static void i9xx_plane_disable_arm(struct intel_dsb *dsb,
struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane);
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
u32 dspcntr;
@@ -544,12 +549,46 @@ static void i9xx_plane_disable_arm(struct intel_dsb *dsb,
*/
dspcntr = i9xx_plane_ctl_crtc(crtc_state);
- intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
+ intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
- if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), 0);
+ if (DISPLAY_VER(display) >= 4)
+ intel_de_write_fw(display, DSPSURF(display, i9xx_plane), 0);
else
- intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane), 0);
+ intel_de_write_fw(display, DSPADDR(display, i9xx_plane), 0);
+}
+
+static void g4x_primary_capture_error(struct intel_crtc *crtc,
+ struct intel_plane *plane,
+ struct intel_plane_error *error)
+{
+ struct intel_display *display = to_intel_display(plane);
+ enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
+
+ error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
+ error->surf = intel_de_read(display, DSPSURF(display, i9xx_plane));
+ error->surflive = intel_de_read(display, DSPSURFLIVE(display, i9xx_plane));
+}
+
+static void i965_plane_capture_error(struct intel_crtc *crtc,
+ struct intel_plane *plane,
+ struct intel_plane_error *error)
+{
+ struct intel_display *display = to_intel_display(plane);
+ enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
+
+ error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
+ error->surf = intel_de_read(display, DSPSURF(display, i9xx_plane));
+}
+
+static void i8xx_plane_capture_error(struct intel_crtc *crtc,
+ struct intel_plane *plane,
+ struct intel_plane_error *error)
+{
+ struct intel_display *display = to_intel_display(plane);
+ enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
+
+ error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
+ error->surf = intel_de_read(display, DSPADDR(display, i9xx_plane));
}
static void
@@ -559,7 +598,7 @@ g4x_primary_async_flip(struct intel_dsb *dsb,
const struct intel_plane_state *plane_state,
bool async_flip)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane);
u32 dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
@@ -567,9 +606,9 @@ g4x_primary_async_flip(struct intel_dsb *dsb,
if (async_flip)
dspcntr |= DISP_ASYNC_FLIP;
- intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
+ intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
- intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
+ intel_de_write_fw(display, DSPSURF(display, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
}
@@ -580,11 +619,11 @@ vlv_primary_async_flip(struct intel_dsb *dsb,
const struct intel_plane_state *plane_state,
bool async_flip)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane);
u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
- intel_de_write_fw(dev_priv, DSPADDR_VLV(dev_priv, i9xx_plane),
+ intel_de_write_fw(display, DSPADDR_VLV(display, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
}
@@ -672,10 +711,15 @@ vlv_primary_disable_flip_done(struct intel_plane *plane)
spin_unlock_irq(&i915->irq_lock);
}
+static bool i9xx_plane_can_async_flip(u64 modifier)
+{
+ return modifier == I915_FORMAT_MOD_X_TILED;
+}
+
static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
enum pipe *pipe)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane);
enum intel_display_power_domain power_domain;
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
intel_wakeref_t wakeref;
@@ -688,20 +732,20 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
* display power wells.
*/
power_domain = POWER_DOMAIN_PIPE(plane->pipe);
- wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
+ wakeref = intel_display_power_get_if_enabled(display, power_domain);
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
+ val = intel_de_read(display, DSPCNTR(display, i9xx_plane));
ret = val & DISP_ENABLE;
- if (DISPLAY_VER(dev_priv) >= 5)
+ if (DISPLAY_VER(display) >= 5)
*pipe = plane->pipe;
else
*pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val);
- intel_display_power_put(dev_priv, power_domain, wakeref);
+ intel_display_power_put(display, power_domain, wakeref);
return ret;
}
@@ -770,16 +814,21 @@ i8xx_plane_max_stride(struct intel_plane *plane,
return 8 * 1024;
}
-static unsigned int vlv_primary_min_alignment(struct intel_plane *plane,
- const struct drm_framebuffer *fb,
- int color_plane)
+unsigned int vlv_plane_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane);
+
+ if (intel_plane_can_async_flip(plane, fb->modifier))
+ return 256 * 1024;
+
+ /* FIXME undocumented so not sure what's actually needed */
+ if (intel_scanout_needs_vtd_wa(display))
+ return 256 * 1024;
switch (fb->modifier) {
case I915_FORMAT_MOD_X_TILED:
- if (HAS_ASYNC_FLIPS(i915))
- return 256 * 1024;
return 4 * 1024;
case DRM_FORMAT_MOD_LINEAR:
return 128 * 1024;
@@ -793,13 +842,16 @@ static unsigned int g4x_primary_min_alignment(struct intel_plane *plane,
const struct drm_framebuffer *fb,
int color_plane)
{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane);
+
+ if (intel_plane_can_async_flip(plane, fb->modifier))
+ return 256 * 1024;
+
+ if (intel_scanout_needs_vtd_wa(display))
+ return 256 * 1024;
switch (fb->modifier) {
case I915_FORMAT_MOD_X_TILED:
- if (HAS_ASYNC_FLIPS(i915))
- return 256 * 1024;
- return 4 * 1024;
case DRM_FORMAT_MOD_LINEAR:
return 4 * 1024;
default:
@@ -849,7 +901,7 @@ static const struct drm_plane_funcs i8xx_plane_funcs = {
};
struct intel_plane *
-intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
+intel_primary_plane_create(struct intel_display *display, enum pipe pipe)
{
struct intel_plane *plane;
const struct drm_plane_funcs *plane_funcs;
@@ -868,20 +920,20 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
* On gen2/3 only plane A can do FBC, but the panel fitter and LVDS
* port is hooked to pipe B. Hence we want plane A feeding pipe B.
*/
- if (HAS_FBC(dev_priv) && DISPLAY_VER(dev_priv) < 4 &&
- INTEL_NUM_PIPES(dev_priv) == 2)
+ if (HAS_FBC(display) && DISPLAY_VER(display) < 4 &&
+ INTEL_NUM_PIPES(display) == 2)
plane->i9xx_plane = (enum i9xx_plane_id) !pipe;
else
plane->i9xx_plane = (enum i9xx_plane_id) pipe;
plane->id = PLANE_PRIMARY;
plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
- intel_fbc_add_plane(i9xx_plane_fbc(dev_priv, plane->i9xx_plane), plane);
+ intel_fbc_add_plane(i9xx_plane_fbc(display, plane->i9xx_plane), plane);
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+ if (display->platform.valleyview || display->platform.cherryview) {
formats = vlv_primary_formats;
num_formats = ARRAY_SIZE(vlv_primary_formats);
- } else if (DISPLAY_VER(dev_priv) >= 4) {
+ } else if (DISPLAY_VER(display) >= 4) {
/*
* WaFP16GammaEnabling:ivb
* "Workaround : When using the 64-bit format, the plane
@@ -895,7 +947,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
* planes, so we choose not to expose fp16 on IVB primary
* planes. HSW primary planes no longer have this problem.
*/
- if (IS_IVYBRIDGE(dev_priv)) {
+ if (display->platform.ivybridge) {
formats = ivb_primary_formats;
num_formats = ARRAY_SIZE(ivb_primary_formats);
} else {
@@ -907,44 +959,48 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
num_formats = ARRAY_SIZE(i8xx_primary_formats);
}
- if (DISPLAY_VER(dev_priv) >= 4)
+ if (DISPLAY_VER(display) >= 4)
plane_funcs = &i965_plane_funcs;
else
plane_funcs = &i8xx_plane_funcs;
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+ if (display->platform.valleyview || display->platform.cherryview)
plane->min_cdclk = vlv_plane_min_cdclk;
- else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
+ else if (display->platform.broadwell || display->platform.haswell)
plane->min_cdclk = hsw_plane_min_cdclk;
- else if (IS_IVYBRIDGE(dev_priv))
+ else if (display->platform.ivybridge)
plane->min_cdclk = ivb_plane_min_cdclk;
else
plane->min_cdclk = i9xx_plane_min_cdclk;
- if (HAS_GMCH(dev_priv)) {
- if (DISPLAY_VER(dev_priv) >= 4)
+ if (HAS_GMCH(display)) {
+ if (DISPLAY_VER(display) >= 4)
plane->max_stride = i965_plane_max_stride;
- else if (DISPLAY_VER(dev_priv) == 3)
+ else if (DISPLAY_VER(display) == 3)
plane->max_stride = i915_plane_max_stride;
else
plane->max_stride = i8xx_plane_max_stride;
} else {
- if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
+ if (display->platform.broadwell || display->platform.haswell)
plane->max_stride = hsw_primary_max_stride;
else
plane->max_stride = ilk_primary_max_stride;
}
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
- plane->min_alignment = vlv_primary_min_alignment;
- else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
+ if (display->platform.valleyview || display->platform.cherryview)
+ plane->min_alignment = vlv_plane_min_alignment;
+ else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
plane->min_alignment = g4x_primary_min_alignment;
- else if (DISPLAY_VER(dev_priv) == 4)
+ else if (DISPLAY_VER(display) == 4)
plane->min_alignment = i965_plane_min_alignment;
else
plane->min_alignment = i9xx_plane_min_alignment;
- if (IS_I830(dev_priv) || IS_I845G(dev_priv)) {
+ /* FIXME undocumented for VLV/CHV so not sure what's actually needed */
+ if (intel_scanout_needs_vtd_wa(display))
+ plane->vtd_guard = 128;
+
+ if (display->platform.i830 || display->platform.i845g) {
plane->update_arm = i830_plane_update_arm;
} else {
plane->update_noarm = i9xx_plane_update_noarm;
@@ -954,36 +1010,49 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
plane->get_hw_state = i9xx_plane_get_hw_state;
plane->check_plane = i9xx_plane_check;
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- plane->async_flip = vlv_primary_async_flip;
- plane->enable_flip_done = vlv_primary_enable_flip_done;
- plane->disable_flip_done = vlv_primary_disable_flip_done;
- } else if (IS_BROADWELL(dev_priv)) {
- plane->need_async_flip_toggle_wa = true;
- plane->async_flip = g4x_primary_async_flip;
- plane->enable_flip_done = bdw_primary_enable_flip_done;
- plane->disable_flip_done = bdw_primary_disable_flip_done;
- } else if (DISPLAY_VER(dev_priv) >= 7) {
- plane->async_flip = g4x_primary_async_flip;
- plane->enable_flip_done = ivb_primary_enable_flip_done;
- plane->disable_flip_done = ivb_primary_disable_flip_done;
- } else if (DISPLAY_VER(dev_priv) >= 5) {
- plane->async_flip = g4x_primary_async_flip;
- plane->enable_flip_done = ilk_primary_enable_flip_done;
- plane->disable_flip_done = ilk_primary_disable_flip_done;
+ if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
+ plane->capture_error = g4x_primary_capture_error;
+ else if (DISPLAY_VER(display) >= 4)
+ plane->capture_error = i965_plane_capture_error;
+ else
+ plane->capture_error = i8xx_plane_capture_error;
+
+ if (HAS_ASYNC_FLIPS(display)) {
+ if (display->platform.valleyview || display->platform.cherryview) {
+ plane->async_flip = vlv_primary_async_flip;
+ plane->enable_flip_done = vlv_primary_enable_flip_done;
+ plane->disable_flip_done = vlv_primary_disable_flip_done;
+ plane->can_async_flip = i9xx_plane_can_async_flip;
+ } else if (display->platform.broadwell) {
+ plane->need_async_flip_toggle_wa = true;
+ plane->async_flip = g4x_primary_async_flip;
+ plane->enable_flip_done = bdw_primary_enable_flip_done;
+ plane->disable_flip_done = bdw_primary_disable_flip_done;
+ plane->can_async_flip = i9xx_plane_can_async_flip;
+ } else if (DISPLAY_VER(display) >= 7) {
+ plane->async_flip = g4x_primary_async_flip;
+ plane->enable_flip_done = ivb_primary_enable_flip_done;
+ plane->disable_flip_done = ivb_primary_disable_flip_done;
+ plane->can_async_flip = i9xx_plane_can_async_flip;
+ } else if (DISPLAY_VER(display) >= 5) {
+ plane->async_flip = g4x_primary_async_flip;
+ plane->enable_flip_done = ilk_primary_enable_flip_done;
+ plane->disable_flip_done = ilk_primary_disable_flip_done;
+ plane->can_async_flip = i9xx_plane_can_async_flip;
+ }
}
- modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X);
+ modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X);
- if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
- ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
+ if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
+ ret = drm_universal_plane_init(display->drm, &plane->base,
0, plane_funcs,
formats, num_formats,
modifiers,
DRM_PLANE_TYPE_PRIMARY,
"primary %c", pipe_name(pipe));
else
- ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
+ ret = drm_universal_plane_init(display->drm, &plane->base,
0, plane_funcs,
formats, num_formats,
modifiers,
@@ -996,18 +1065,18 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
if (ret)
goto fail;
- if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
+ if (display->platform.cherryview && pipe == PIPE_B) {
supported_rotations =
DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
DRM_MODE_REFLECT_X;
- } else if (DISPLAY_VER(dev_priv) >= 4) {
+ } else if (DISPLAY_VER(display) >= 4) {
supported_rotations =
DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
} else {
supported_rotations = DRM_MODE_ROTATE_0;
}
- if (DISPLAY_VER(dev_priv) >= 4)
+ if (DISPLAY_VER(display) >= 4)
drm_plane_create_rotation_property(&plane->base,
DRM_MODE_ROTATE_0,
supported_rotations);
@@ -1062,8 +1131,7 @@ void
i9xx_get_initial_plane_config(struct intel_crtc *crtc,
struct intel_initial_plane_config *plane_config)
{
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
+ struct intel_display *display = to_intel_display(crtc);
struct intel_plane *plane = to_intel_plane(crtc->base.primary);
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
enum pipe pipe;
@@ -1076,21 +1144,21 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
if (!plane->get_hw_state(plane, &pipe))
return;
- drm_WARN_ON(dev, pipe != crtc->pipe);
+ drm_WARN_ON(display->drm, pipe != crtc->pipe);
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
if (!intel_fb) {
- drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n");
+ drm_dbg_kms(display->drm, "failed to alloc fb\n");
return;
}
fb = &intel_fb->base;
- fb->dev = dev;
+ fb->dev = display->drm;
- val = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
+ val = intel_de_read(display, DSPCNTR(display, i9xx_plane));
- if (DISPLAY_VER(dev_priv) >= 4) {
+ if (DISPLAY_VER(display) >= 4) {
if (val & DISP_TILED) {
plane_config->tiling = I915_TILING_X;
fb->modifier = I915_FORMAT_MOD_X_TILED;
@@ -1100,50 +1168,51 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->rotation = DRM_MODE_ROTATE_180;
}
- if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B &&
- val & DISP_MIRROR)
+ if (display->platform.cherryview &&
+ pipe == PIPE_B && val & DISP_MIRROR)
plane_config->rotation |= DRM_MODE_REFLECT_X;
pixel_format = val & DISP_FORMAT_MASK;
fourcc = i9xx_format_to_fourcc(pixel_format);
fb->format = drm_format_info(fourcc);
- if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
- offset = intel_de_read(dev_priv,
- DSPOFFSET(dev_priv, i9xx_plane));
- base = intel_de_read(dev_priv, DSPSURF(dev_priv, i9xx_plane)) & DISP_ADDR_MASK;
- } else if (DISPLAY_VER(dev_priv) >= 4) {
+ if (display->platform.haswell || display->platform.broadwell) {
+ offset = intel_de_read(display,
+ DSPOFFSET(display, i9xx_plane));
+ base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
+ } else if (DISPLAY_VER(display) >= 4) {
if (plane_config->tiling)
- offset = intel_de_read(dev_priv,
- DSPTILEOFF(dev_priv, i9xx_plane));
+ offset = intel_de_read(display,
+ DSPTILEOFF(display, i9xx_plane));
else
- offset = intel_de_read(dev_priv,
- DSPLINOFF(dev_priv, i9xx_plane));
- base = intel_de_read(dev_priv, DSPSURF(dev_priv, i9xx_plane)) & DISP_ADDR_MASK;
+ offset = intel_de_read(display,
+ DSPLINOFF(display, i9xx_plane));
+ base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
} else {
offset = 0;
- base = intel_de_read(dev_priv, DSPADDR(dev_priv, i9xx_plane));
+ base = intel_de_read(display, DSPADDR(display, i9xx_plane));
}
plane_config->base = base;
- drm_WARN_ON(&dev_priv->drm, offset != 0);
+ drm_WARN_ON(display->drm, offset != 0);
- val = intel_de_read(dev_priv, PIPESRC(dev_priv, pipe));
+ val = intel_de_read(display, PIPESRC(display, pipe));
fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1;
fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1;
- val = intel_de_read(dev_priv, DSPSTRIDE(dev_priv, i9xx_plane));
+ val = intel_de_read(display, DSPSTRIDE(display, i9xx_plane));
fb->pitches[0] = val & 0xffffffc0;
aligned_height = intel_fb_align_height(fb, 0, fb->height);
plane_config->size = fb->pitches[0] * aligned_height;
- drm_dbg_kms(&dev_priv->drm,
- "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
- crtc->base.name, plane->base.name, fb->width, fb->height,
- fb->format->cpp[0] * 8, base, fb->pitches[0],
- plane_config->size);
+ drm_dbg_kms(display->drm,
+ "[CRTC:%d:%s][PLANE:%d:%s] with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
+ crtc->base.base.id, crtc->base.name,
+ plane->base.base.id, plane->base.name,
+ fb->width, fb->height, fb->format->cpp[0] * 8,
+ base, fb->pitches[0], plane_config->size);
plane_config->fb = intel_fb;
}
@@ -1151,7 +1220,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
const struct intel_initial_plane_config *plane_config)
{
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(crtc);
struct intel_plane *plane = to_intel_plane(crtc->base.primary);
const struct intel_plane_state *plane_state =
to_intel_plane_state(plane->base.state);
@@ -1170,10 +1239,10 @@ bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
if (plane_config->base == base)
return false;
- if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write(dev_priv, DSPSURF(dev_priv, i9xx_plane), base);
+ if (DISPLAY_VER(display) >= 4)
+ intel_de_write(display, DSPSURF(display, i9xx_plane), base);
else
- intel_de_write(dev_priv, DSPADDR(dev_priv, i9xx_plane), base);
+ intel_de_write(display, DSPADDR(display, i9xx_plane), base);
return true;
}