From: Ville Syrjälä <ville.syrj...@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.syrj...@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

Reply via email to