* [PATCH 3/4] drm/i915: Sprite C support for Gen4 and earlier
2013-04-17 17:11 [PATCH 1/4] drm/i915: Disable primary plane trickle feed for g4x ville.syrjala
2013-04-17 17:11 ` [PATCH 2/4] drm/i915: Clarify DSPPOS/DSPSIZE and pipe selection for planes A/B ville.syrjala
@ 2013-04-17 17:12 ` ville.syrjala
2013-04-17 17:12 ` [PATCH 4/4] drm/i915: Use ILK+ style video sprites for Gen4.5 ville.syrjala
2013-04-17 17:25 ` [PATCH 1/4] drm/i915: Disable primary plane trickle feed for g4x Chris Wilson
3 siblings, 0 replies; 7+ messages in thread
From: ville.syrjala @ 2013-04-17 17:12 UTC (permalink / raw)
To: intel-gfx
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
Gen2-4 have a non-scalable sprite C, which can be assigned to either
pipe A or pipe B dynamically. Expose sprite C as a drm_plame.
I've tested this only on 85x (8086:3582) and 946 (8086:2972).
Gen2/3 chipsets should also be able to re-assign the primary plane B
to act as a sprite on pipe A. But in order to expose that, we should
actually expose all primary planes as drm_planes. We should make
that change eventually, but currently we're not yet ready for it. So
for now only sprite C is exposed, and sprite B can't be used yet.
Based on the gen2 docs, it seems that the sprite C support is usually
present only on mobile platforms. The exception is SPG-B, which I'm
assuming means i865g for our driver.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 27 +++
drivers/gpu/drm/i915/intel_display.c | 35 +++-
drivers/gpu/drm/i915/intel_sprite.c | 339 +++++++++++++++++++++++++++++++++--
3 files changed, 381 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 31de7e4..7a0037d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3085,15 +3085,24 @@
#define DISPPLANE_SRC_KEY_DISABLE 0
#define DISPPLANE_LINE_DOUBLE (1<<20)
#define DISPPLANE_NO_LINE_DOUBLE 0
+#define DISPPLANE_PLANE_CSC_DISABLE (1<<19)
#define DISPPLANE_STEREO_POLARITY_FIRST 0
#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
+#define DISPPLANE_YUV_BYTE_ORDER_MASK (3<<16)
+#define DISPPLANE_YUV_ORDER_YUYV (0<<16)
+#define DISPPLANE_YUV_ORDER_UYVY (1<<16)
+#define DISPPLANE_YUV_ORDER_YVYU (2<<16)
+#define DISPPLANE_YUV_ORDER_VYUY (3<<16)
#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* Ironlake */
#define DISPPLANE_TILED (1<<10)
#define _DSPAADDR (dev_priv->info->display_mmio_offset + 0x70184)
#define _DSPASTRIDE (dev_priv->info->display_mmio_offset + 0x70188)
#define _DSPAPOS (dev_priv->info->display_mmio_offset + 0x7018C) /* reserved */
#define _DSPASIZE (dev_priv->info->display_mmio_offset + 0x70190)
+#define _DSPAKEYMINVAL (dev_priv->info->display_mmio_offset + 0x70194)
+#define _DSPAKEYMSK (dev_priv->info->display_mmio_offset + 0x70198)
#define _DSPASURF (dev_priv->info->display_mmio_offset + 0x7019C) /* 965+ only */
+#define _DSPAKEYMAXVAL (dev_priv->info->display_mmio_offset + 0x701A0)
#define _DSPATILEOFF (dev_priv->info->display_mmio_offset + 0x701A4) /* 965+ only */
#define _DSPAOFFSET (dev_priv->info->display_mmio_offset + 0x701A4) /* HSW */
#define _DSPASURFLIVE (dev_priv->info->display_mmio_offset + 0x701AC)
@@ -3103,7 +3112,10 @@
#define DSPSTRIDE(plane) _PIPE(plane, _DSPASTRIDE, _DSPBSTRIDE)
#define DSPPOS(plane) _PIPE(plane, _DSPAPOS, _DSPBPOS)
#define DSPSIZE(plane) _PIPE(plane, _DSPASIZE, _DSPBSIZE)
+#define DSPKEYMINVAL(plane) _PIPE(plane, _DSPAKEYMINVAL, _DSPBKEYMINVAL)
+#define DSPKEYMSK(plane) _PIPE(plane, _DSPAKEYMSK, _DSPBKEYMSK)
#define DSPSURF(plane) _PIPE(plane, _DSPASURF, _DSPBSURF)
+#define DSPKEYMAXVAL(plane) _PIPE(plane, _DSPAKEYMAXVAL, _DSPBKEYMAXVAL)
#define DSPTILEOFF(plane) _PIPE(plane, _DSPATILEOFF, _DSPBTILEOFF)
#define DSPLINOFF(plane) DSPADDR(plane)
#define DSPOFFSET(plane) _PIPE(plane, _DSPAOFFSET, _DSPBOFFSET)
@@ -3116,6 +3128,18 @@
#define I915_MODIFY_DISPBASE(reg, gfx_addr) \
(I915_WRITE((reg), (gfx_addr) | I915_LO_DISPBASE(I915_READ(reg))))
+/* plane C color correction */
+#define DCLRC0 (dev_priv->info->display_mmio_offset + 0x721d0)
+#define DCLRC1 (dev_priv->info->display_mmio_offset + 0x721d4)
+
+/* plane C pre-blend gamma */
+#define GAMC5 (dev_priv->info->display_mmio_offset + 0x721e0)
+#define GAMC4 (dev_priv->info->display_mmio_offset + 0x721e4)
+#define GAMC3 (dev_priv->info->display_mmio_offset + 0x721e8)
+#define GAMC2 (dev_priv->info->display_mmio_offset + 0x721ec)
+#define GAMC1 (dev_priv->info->display_mmio_offset + 0x721f0)
+#define GAMC0 (dev_priv->info->display_mmio_offset + 0x721f4)
+
/* VBIOS flags */
#define SWF00 (dev_priv->info->display_mmio_offset + 0x71410)
#define SWF01 (dev_priv->info->display_mmio_offset + 0x71414)
@@ -3151,9 +3175,12 @@
#define _DSPBSTRIDE (dev_priv->info->display_mmio_offset + 0x71188)
#define _DSPBPOS (dev_priv->info->display_mmio_offset + 0x7118C)
#define _DSPBSIZE (dev_priv->info->display_mmio_offset + 0x71190)
+#define _DSPBKEYMINVAL (dev_priv->info->display_mmio_offset + 0x71194)
+#define _DSPBKEYMSK (dev_priv->info->display_mmio_offset + 0x71198)
#define _DSPBSURF (dev_priv->info->display_mmio_offset + 0x7119C)
#define _DSPBTILEOFF (dev_priv->info->display_mmio_offset + 0x711A4)
#define _DSPBOFFSET (dev_priv->info->display_mmio_offset + 0x711A4)
+#define _DSPBKEYMAXVAL (dev_priv->info->display_mmio_offset + 0x711A0)
#define _DSPBSURFLIVE (dev_priv->info->display_mmio_offset + 0x711AC)
/* Sprite A control */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4f4a8d1..4f3b490 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8706,7 +8706,8 @@ int intel_framebuffer_init(struct drm_device *dev,
case DRM_FORMAT_UYVY:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_VYUY:
- if (INTEL_INFO(dev)->gen < 5) {
+ /* YUV sprite C / video sprite support? */
+ if (INTEL_INFO(dev)->num_pipes == 1) {
DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format);
return -EINVAL;
}
@@ -9054,6 +9055,10 @@ void intel_modeset_init(struct drm_device *dev)
for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) {
intel_crtc_init(dev, i);
+
+ if (INTEL_INFO(dev)->gen <= 4)
+ continue;
+
for (j = 0; j < dev_priv->num_plane; j++) {
ret = intel_plane_init(dev, i, j);
if (ret)
@@ -9062,6 +9067,34 @@ void intel_modeset_init(struct drm_device *dev)
}
}
+ /*
+ * Sprite C:
+ * the pipe we pass here doesn't matter since the
+ * sprite->pipe assignment can be changed dynamically.
+ */
+
+ /* one pipe and planes A+C */
+ if (IS_I865G(dev)) {
+ /*
+ * Sprite C:
+ * the pipe we pass here doesn't matter since the
+ * sprite->pipe assignment can be changed dynamically.
+ */
+ ret = intel_plane_init(dev, 0, PLANE_C);
+ if (ret)
+ DRM_DEBUG_KMS("plane %c init failed: %d\n",
+ plane_name(PLANE_C), ret);
+ }
+
+ /* two pipes and planes A+B+C */
+ if (INTEL_INFO(dev)->gen <= 4 &&
+ INTEL_INFO(dev)->num_pipes == 2) {
+ ret = intel_plane_init(dev, 0, PLANE_C);
+ if (ret)
+ DRM_DEBUG_KMS("plane %c init failed: %d\n",
+ plane_name(PLANE_C), ret);
+ }
+
intel_cpu_pll_init(dev);
intel_pch_pll_init(dev);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index c7d25c5..026e6b8 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -36,6 +36,239 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"
+static bool format_is_yuv(uint32_t pixel_format)
+{
+ switch (pixel_format) {
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ case DRM_FORMAT_YVYU:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void
+gen2_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb,
+ struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t x, uint32_t y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct drm_device *dev = dplane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(dplane);
+ int pipe = intel_plane->pipe;
+ int plane = intel_plane->plane;
+ u32 dspcntr;
+ unsigned long dspsurf_offset, linear_offset;
+ int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
+
+ dspcntr = I915_READ(DSPCNTR(plane));
+
+ dspcntr &= ~(DISPPLANE_GAMMA_ENABLE |
+ DISPPLANE_PIXFORMAT_MASK |
+ DISPPLANE_YUV_BYTE_ORDER_MASK |
+ DISPPLANE_PLANE_CSC_DISABLE |
+ DISPPLANE_SEL_PIPE_MASK |
+ DISPPLANE_TILED);
+
+ switch (fb->pixel_format) {
+ case DRM_FORMAT_YUYV:
+ dspcntr |= DISPPLANE_YUV422 | DISPPLANE_YUV_ORDER_YUYV;
+ break;
+ case DRM_FORMAT_YVYU:
+ dspcntr |= DISPPLANE_YUV422 | DISPPLANE_YUV_ORDER_YVYU;
+ break;
+ case DRM_FORMAT_UYVY:
+ dspcntr |= DISPPLANE_YUV422 | DISPPLANE_YUV_ORDER_UYVY;
+ break;
+ case DRM_FORMAT_VYUY:
+ dspcntr |= DISPPLANE_YUV422 | DISPPLANE_YUV_ORDER_VYUY;
+ break;
+ case DRM_FORMAT_C8:
+ dspcntr |= DISPPLANE_8BPP | DISPPLANE_GAMMA_ENABLE;
+ break;
+ case DRM_FORMAT_ARGB1555:
+ dspcntr |= IS_GEN3(dev) ? DISPPLANE_BGRA555 : DISPPLANE_BGRX555;
+ break;
+ case DRM_FORMAT_XRGB1555:
+ dspcntr |= DISPPLANE_BGRX555;
+ break;
+ case DRM_FORMAT_RGB565:
+ dspcntr |= DISPPLANE_BGRX565;
+ break;
+ case DRM_FORMAT_XRGB8888:
+ dspcntr |= DISPPLANE_BGRX888;
+ break;
+ case DRM_FORMAT_ARGB8888:
+ dspcntr |= DISPPLANE_BGRA888;
+ break;
+ case DRM_FORMAT_XBGR2101010:
+ dspcntr |= DISPPLANE_RGBX101010;
+ break;
+ case DRM_FORMAT_ABGR2101010:
+ dspcntr |= DISPPLANE_RGBA101010;
+ break;
+ case DRM_FORMAT_XBGR8888:
+ dspcntr |= DISPPLANE_RGBX888;
+ break;
+ case DRM_FORMAT_ABGR8888:
+ dspcntr |= DISPPLANE_RGBA888;
+ break;
+ default:
+ /*
+ * If we get here one of the upper layers failed to filter
+ * out the unsupported plane formats
+ */
+ BUG();
+ break;
+ }
+
+ if (pipe == PIPE_B)
+ dspcntr |= DISPPLANE_SEL_PIPE_B;
+
+ if (plane == PLANE_C && !IS_I865G(dev) &&
+ !format_is_yuv(fb->pixel_format))
+ dspcntr |= DISPPLANE_PLANE_CSC_DISABLE;
+
+ if (INTEL_INFO(dev)->gen >= 4 &&
+ obj->tiling_mode != I915_TILING_NONE)
+ dspcntr |= DISPPLANE_TILED;
+
+ dspcntr |= DISPLAY_PLANE_ENABLE;
+
+ /* Sizes are 0 based */
+ src_w--;
+ src_h--;
+ crtc_w--;
+ crtc_h--;
+
+ intel_update_sprite_watermarks(dev, plane, crtc_w, pixel_size);
+
+ /*
+ * On gen2 DCLRC1 reset value is 0. Fix it, except on
+ * i865g which supposedly doesn't support color correction.
+ */
+ if (plane == PLANE_C && IS_GEN2(dev) && !IS_I865G(dev)) {
+ /* Pass-through for color correction */
+ I915_WRITE(DCLRC0, 1 << 24);
+ I915_WRITE(DCLRC1, 1 << 8);
+ /* Plane gamma should default to linear ramp */
+ }
+
+ I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
+ I915_WRITE(DSPPOS(plane), (crtc_y << 16) | crtc_x);
+ I915_WRITE(DSPSIZE(plane), (crtc_h << 16) | crtc_w);
+ I915_WRITE(DSPCNTR(plane), dspcntr);
+
+ linear_offset = y * fb->pitches[0] + x * pixel_size;
+
+ if (INTEL_INFO(dev)->gen >= 4) {
+ dspsurf_offset = intel_gen4_compute_page_offset(&x, &y,
+ obj->tiling_mode,
+ pixel_size,
+ fb->pitches[0]);
+ linear_offset -= dspsurf_offset;
+
+ I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
+ I915_WRITE(DSPLINOFF(plane), linear_offset);
+ I915_MODIFY_DISPBASE(DSPSURF(plane), obj->gtt_offset + dspsurf_offset);
+ } else {
+ I915_WRITE(DSPADDR(plane), obj->gtt_offset + linear_offset);
+ }
+
+ intel_flush_display_plane(dev_priv, plane);
+
+}
+
+static void
+gen2_disable_plane(struct drm_plane *dplane)
+{
+ struct drm_device *dev = dplane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(dplane);
+ int plane = intel_plane->plane;
+
+ I915_WRITE(DSPCNTR(plane), I915_READ(DSPCNTR(plane)) &
+ ~DISPLAY_PLANE_ENABLE);
+ /* Activate double buffered register update */
+ intel_flush_display_plane(dev_priv, plane);
+}
+
+static int
+gen2_update_colorkey(struct drm_plane *dplane,
+ struct drm_intel_sprite_colorkey *key)
+{
+ struct drm_device *dev = dplane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(dplane);
+ int plane = intel_plane->plane;
+ u32 dspcntr;
+
+ if (key->flags & I915_SET_COLORKEY_DESTINATION)
+ return -EINVAL;
+
+ I915_WRITE(DSPKEYMINVAL(plane), key->min_value);
+ I915_WRITE(DSPKEYMAXVAL(plane), key->max_value);
+ I915_WRITE(DSPKEYMSK(plane), key->channel_mask);
+
+ dspcntr = I915_READ(DSPCNTR(plane));
+ dspcntr &= ~DISPPLANE_SRC_KEY_ENABLE;
+ if (key->flags & I915_SET_COLORKEY_SOURCE)
+ dspcntr |= DISPPLANE_SRC_KEY_ENABLE;
+ I915_WRITE(DSPCNTR(plane), dspcntr);
+
+ intel_flush_display_plane(dev_priv, plane);
+
+ return 0;
+}
+
+static void
+gen2_get_colorkey(struct drm_plane *dplane,
+ struct drm_intel_sprite_colorkey *key)
+{
+ struct drm_device *dev = dplane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(dplane);
+ int plane = intel_plane->plane;
+ u32 dspcntr;
+
+ key->min_value = I915_READ(DSPKEYMINVAL(plane));
+ key->max_value = I915_READ(DSPKEYMAXVAL(plane));
+ key->channel_mask = I915_READ(DSPKEYMSK(plane));
+
+ dspcntr = I915_READ(DSPCNTR(plane));
+ if (dspcntr & DISPPLANE_SRC_KEY_ENABLE)
+ key->flags = I915_SET_COLORKEY_SOURCE;
+ else
+ key->flags = I915_SET_COLORKEY_NONE;
+}
+
+static bool
+gen2_check_pipe_sel(struct drm_plane *dplane, int new_pipe)
+{
+ struct drm_device *dev = dplane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(dplane);
+ int plane = intel_plane->plane;
+ int old_pipe;
+ u32 dspcntr;
+
+ dspcntr = I915_READ(DSPCNTR(plane));
+
+ /* allow pipe changes only when the sprite is disabled */
+ if (!(dspcntr & DISPLAY_PLANE_ENABLE))
+ return true;
+
+ old_pipe = (dspcntr & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_B;
+
+ return !WARN(old_pipe != new_pipe,
+ "sprite %c pipe assertion failure (expected %c, current %c)",
+ plane_name(plane), pipe_name(old_pipe), pipe_name(new_pipe));
+}
+
static void
vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
@@ -596,7 +829,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct intel_plane *intel_plane = to_intel_plane(plane);
struct intel_framebuffer *intel_fb;
struct drm_i915_gem_object *obj, *old_obj;
- int pipe = intel_plane->pipe;
+ int pipe = intel_crtc->pipe; /* the new pipe */
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
pipe);
int ret = 0;
@@ -629,8 +862,13 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
return -EINVAL;
/* Don't modify another pipe's plane */
- if (intel_plane->pipe != intel_crtc->pipe)
- return -EINVAL;
+ if (INTEL_INFO(dev)->gen <= 4) {
+ if (!gen2_check_pipe_sel(plane, pipe))
+ return -EINVAL;
+ } else {
+ if (intel_plane->pipe != pipe)
+ return -EINVAL;
+ }
/* Sprite planes can be linear or x-tiled surfaces */
switch (obj->tiling_mode) {
@@ -701,6 +939,8 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
intel_plane->obj = obj;
+ intel_plane->pipe = pipe;
+
/*
* Be sure to re-enable the primary before the sprite is no longer
* covering it fully.
@@ -724,7 +964,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
*/
if (old_obj != obj) {
mutex_unlock(&dev->struct_mutex);
- intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
+ intel_wait_for_vblank(dev, pipe);
mutex_lock(&dev->struct_mutex);
}
intel_unpin_fb_obj(old_obj);
@@ -851,6 +1091,43 @@ static const struct drm_plane_funcs intel_plane_funcs = {
.destroy = intel_destroy_plane,
};
+static uint32_t i865g_plane_formats[] = {
+ DRM_FORMAT_C8,
+ DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+};
+
+static uint32_t gen2_plane_formats[] = {
+ DRM_FORMAT_C8,
+ DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_YVYU,
+ DRM_FORMAT_UYVY,
+ DRM_FORMAT_VYUY,
+};
+
+static uint32_t gen4_plane_formats[] = {
+ DRM_FORMAT_C8,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XBGR2101010,
+ DRM_FORMAT_ABGR2101010,
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_YVYU,
+ DRM_FORMAT_UYVY,
+ DRM_FORMAT_VYUY,
+};
+
static uint32_t ilk_plane_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_YUYV,
@@ -891,29 +1168,50 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
int num_plane_formats;
int ret;
- if (INTEL_INFO(dev)->gen < 5)
- return -ENODEV;
-
intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
if (!intel_plane)
return -ENOMEM;
switch (INTEL_INFO(dev)->gen) {
+ case 2:
+ case 3:
+ case 4:
case 5:
case 6:
- intel_plane->can_scale = true;
- intel_plane->max_downscale = 16;
- intel_plane->update_plane = ilk_update_plane;
- intel_plane->disable_plane = ilk_disable_plane;
- intel_plane->update_colorkey = ilk_update_colorkey;
- intel_plane->get_colorkey = ilk_get_colorkey;
+ if (INTEL_INFO(dev)->gen <= 4) {
+ intel_plane->can_scale = false;
+ intel_plane->max_downscale = 1;
- if (IS_GEN6(dev)) {
- plane_formats = snb_plane_formats;
- num_plane_formats = ARRAY_SIZE(snb_plane_formats);
+ intel_plane->update_plane = gen2_update_plane;
+ intel_plane->disable_plane = gen2_disable_plane;
+ intel_plane->update_colorkey = gen2_update_colorkey;
+ intel_plane->get_colorkey = gen2_get_colorkey;
+
+ if (IS_I865G(dev)) {
+ plane_formats = i865g_plane_formats;
+ num_plane_formats = ARRAY_SIZE(i865g_plane_formats);
+ } else if (INTEL_INFO(dev)->gen <= 3) {
+ plane_formats = gen2_plane_formats;
+ num_plane_formats = ARRAY_SIZE(gen2_plane_formats);
+ } else {
+ plane_formats = gen4_plane_formats;
+ num_plane_formats = ARRAY_SIZE(gen4_plane_formats);
+ }
} else {
- plane_formats = ilk_plane_formats;
- num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
+ intel_plane->can_scale = true;
+ intel_plane->max_downscale = 16;
+ intel_plane->update_plane = ilk_update_plane;
+ intel_plane->disable_plane = ilk_disable_plane;
+ intel_plane->update_colorkey = ilk_update_colorkey;
+ intel_plane->get_colorkey = ilk_get_colorkey;
+
+ if (IS_GEN6(dev)) {
+ plane_formats = snb_plane_formats;
+ num_plane_formats = ARRAY_SIZE(snb_plane_formats);
+ } else {
+ plane_formats = ilk_plane_formats;
+ num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
+ }
}
break;
@@ -951,7 +1249,10 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
intel_plane->pipe = pipe;
intel_plane->plane = plane;
- possible_crtcs = (1 << pipe);
+ if (INTEL_INFO(dev)->gen >= 5)
+ possible_crtcs = 1 << pipe;
+ else
+ possible_crtcs = (1 << INTEL_INFO(dev)->num_pipes) - 1;
ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
&intel_plane_funcs,
plane_formats, num_plane_formats,
--
1.8.1.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 4/4] drm/i915: Use ILK+ style video sprites for Gen4.5
2013-04-17 17:11 [PATCH 1/4] drm/i915: Disable primary plane trickle feed for g4x ville.syrjala
2013-04-17 17:11 ` [PATCH 2/4] drm/i915: Clarify DSPPOS/DSPSIZE and pipe selection for planes A/B ville.syrjala
2013-04-17 17:12 ` [PATCH 3/4] drm/i915: Sprite C support for Gen4 and earlier ville.syrjala
@ 2013-04-17 17:12 ` ville.syrjala
2013-04-17 17:25 ` [PATCH 1/4] drm/i915: Disable primary plane trickle feed for g4x Chris Wilson
3 siblings, 0 replies; 7+ messages in thread
From: ville.syrjala @ 2013-04-17 17:12 UTC (permalink / raw)
To: intel-gfx
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
According to the docs CTG and BLC have similar video sprites
as ILK/SNB.
This is what the docs say about video sprite features:
CTG and BLC have video sprites, and in addition CTG-B has YUV byte
order selection, live surface registers, and sprite scale registers.
I'm not sure how to translate that into real code. BLC I assume means
Bearlake-C, but I don't really know what it means for us. I'm thinking
that the PCI ID for BLC could be 8086:2982, aka. G35 and apparently
sometimes called Bearlake-G+. Looks like cureently we're treating it
like a 965 though, not a g4x.
Also I'm not sure where ELK fits. It's not explicitly mentioned in
most places, but when it is, it usually seems to match CTG features.
The machine I have here is 8086:2e22 which is ELK AFAICT, and my code
works on it, so apparently ELK also has video sprites, and they seem
happy to scale the content, and YUV byte order selection seems to work
as well.
There's kind of similar confusion about the frame counter registers
since the docs just say that CL uses the old style, CTG/ELK use the
new style. No mention of BW, BL or BLC here.
BLC is special in may places, in some places it matches BW/CL and
in some cases CTG.
For now I just chose to enable use the video sprite code paths when
IS_G4X() is true, and I've ignored the no-scale/no-YUV byte order
selection issues. Unfortunatly I don't have the hardware to verify
all the details.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 4 ++--
drivers/gpu/drm/i915/intel_sprite.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4f3b490..9ed2b04 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9056,7 +9056,7 @@ void intel_modeset_init(struct drm_device *dev)
for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) {
intel_crtc_init(dev, i);
- if (INTEL_INFO(dev)->gen <= 4)
+ if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev))
continue;
for (j = 0; j < dev_priv->num_plane; j++) {
@@ -9087,7 +9087,7 @@ void intel_modeset_init(struct drm_device *dev)
}
/* two pipes and planes A+B+C */
- if (INTEL_INFO(dev)->gen <= 4 &&
+ if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
INTEL_INFO(dev)->num_pipes == 2) {
ret = intel_plane_init(dev, 0, PLANE_C);
if (ret)
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 026e6b8..ae78942 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -862,7 +862,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
return -EINVAL;
/* Don't modify another pipe's plane */
- if (INTEL_INFO(dev)->gen <= 4) {
+ if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev)) {
if (!gen2_check_pipe_sel(plane, pipe))
return -EINVAL;
} else {
@@ -1178,7 +1178,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
case 4:
case 5:
case 6:
- if (INTEL_INFO(dev)->gen <= 4) {
+ if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev)) {
intel_plane->can_scale = false;
intel_plane->max_downscale = 1;
@@ -1249,7 +1249,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
intel_plane->pipe = pipe;
intel_plane->plane = plane;
- if (INTEL_INFO(dev)->gen >= 5)
+ if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
possible_crtcs = 1 << pipe;
else
possible_crtcs = (1 << INTEL_INFO(dev)->num_pipes) - 1;
--
1.8.1.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 7+ messages in thread