drm/i915: Fix display pixel format handling
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 31 Oct 2012 15:50:14 +0000 (17:50 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Sun, 11 Nov 2012 22:51:12 +0000 (23:51 +0100)
Fix support for all RGB/BGR pixel formats (except the 16:16:16:16 float
format).

Fix intel_init_framebuffer() to match hardware and driver limitations:
* RGB332 is not supported at all
* CI8 is supported
* XRGB1555 & co. are supported on Gen3 and earlier
* XRGB210101010 & co. are supported from Gen4 onwards
* BGR formats are supported from Gen4 onwards
* YUV formats are supported from Gen5 onwards (driver limitation)

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c

index 0514823e561bf63faac552e9161cebe533ca6073..d4520d5817c56f7a42634f9c28111aee488ba6f9 100644 (file)
 #define   DISPPLANE_GAMMA_ENABLE               (1<<30)
 #define   DISPPLANE_GAMMA_DISABLE              0
 #define   DISPPLANE_PIXFORMAT_MASK             (0xf<<26)
+#define   DISPPLANE_YUV422                     (0x0<<26)
 #define   DISPPLANE_8BPP                       (0x2<<26)
-#define   DISPPLANE_15_16BPP                   (0x4<<26)
-#define   DISPPLANE_16BPP                      (0x5<<26)
-#define   DISPPLANE_32BPP_NO_ALPHA             (0x6<<26)
-#define   DISPPLANE_32BPP                      (0x7<<26)
-#define   DISPPLANE_32BPP_30BIT_NO_ALPHA       (0xa<<26)
+#define   DISPPLANE_BGRA555                    (0x3<<26)
+#define   DISPPLANE_BGRX555                    (0x4<<26)
+#define   DISPPLANE_BGRX565                    (0x5<<26)
+#define   DISPPLANE_BGRX888                    (0x6<<26)
+#define   DISPPLANE_BGRA888                    (0x7<<26)
+#define   DISPPLANE_RGBX101010                 (0x8<<26)
+#define   DISPPLANE_RGBA101010                 (0x9<<26)
+#define   DISPPLANE_BGRX101010                 (0xa<<26)
+#define   DISPPLANE_RGBX161616                 (0xc<<26)
+#define   DISPPLANE_RGBX888                    (0xe<<26)
+#define   DISPPLANE_RGBA888                    (0xf<<26)
 #define   DISPPLANE_STEREO_ENABLE              (1<<25)
 #define   DISPPLANE_STEREO_DISABLE             0
 #define   DISPPLANE_SEL_PIPE_SHIFT             24
index fe2bb77c221d33acae63d69707ad74b7796cc4b6..14fc2641a10c0d07a885114a0ebc044a588b07d0 100644 (file)
@@ -2000,24 +2000,38 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
        dspcntr = I915_READ(reg);
        /* Mask out pixel format bits in case we change it */
        dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-       switch (fb->bits_per_pixel) {
-       case 8:
+       switch (fb->pixel_format) {
+       case DRM_FORMAT_C8:
                dspcntr |= DISPPLANE_8BPP;
                break;
-       case 16:
-               if (fb->depth == 15)
-                       dspcntr |= DISPPLANE_15_16BPP;
-               else
-                       dspcntr |= DISPPLANE_16BPP;
+       case DRM_FORMAT_XRGB1555:
+       case DRM_FORMAT_ARGB1555:
+               dspcntr |= DISPPLANE_BGRX555;
                break;
-       case 24:
-       case 32:
-               dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+       case DRM_FORMAT_RGB565:
+               dspcntr |= DISPPLANE_BGRX565;
+               break;
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_ARGB8888:
+               dspcntr |= DISPPLANE_BGRX888;
+               break;
+       case DRM_FORMAT_XBGR8888:
+       case DRM_FORMAT_ABGR8888:
+               dspcntr |= DISPPLANE_RGBX888;
+               break;
+       case DRM_FORMAT_XRGB2101010:
+       case DRM_FORMAT_ARGB2101010:
+               dspcntr |= DISPPLANE_BGRX101010;
+               break;
+       case DRM_FORMAT_XBGR2101010:
+       case DRM_FORMAT_ABGR2101010:
+               dspcntr |= DISPPLANE_RGBX101010;
                break;
        default:
-               DRM_ERROR("Unknown color depth %d\n", fb->bits_per_pixel);
+               DRM_ERROR("Unknown pixel format 0x%08x\n", fb->pixel_format);
                return -EINVAL;
        }
+
        if (INTEL_INFO(dev)->gen >= 4) {
                if (obj->tiling_mode != I915_TILING_NONE)
                        dspcntr |= DISPPLANE_TILED;
@@ -2084,27 +2098,31 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
        dspcntr = I915_READ(reg);
        /* Mask out pixel format bits in case we change it */
        dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-       switch (fb->bits_per_pixel) {
-       case 8:
+       switch (fb->pixel_format) {
+       case DRM_FORMAT_C8:
                dspcntr |= DISPPLANE_8BPP;
                break;
-       case 16:
-               if (fb->depth != 16)
-                       return -EINVAL;
-
-               dspcntr |= DISPPLANE_16BPP;
+       case DRM_FORMAT_RGB565:
+               dspcntr |= DISPPLANE_BGRX565;
                break;
-       case 24:
-       case 32:
-               if (fb->depth == 24)
-                       dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-               else if (fb->depth == 30)
-                       dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA;
-               else
-                       return -EINVAL;
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_ARGB8888:
+               dspcntr |= DISPPLANE_BGRX888;
+               break;
+       case DRM_FORMAT_XBGR8888:
+       case DRM_FORMAT_ABGR8888:
+               dspcntr |= DISPPLANE_RGBX888;
+               break;
+       case DRM_FORMAT_XRGB2101010:
+       case DRM_FORMAT_ARGB2101010:
+               dspcntr |= DISPPLANE_BGRX101010;
+               break;
+       case DRM_FORMAT_XBGR2101010:
+       case DRM_FORMAT_ABGR2101010:
+               dspcntr |= DISPPLANE_RGBX101010;
                break;
        default:
-               DRM_ERROR("Unknown color depth %d\n", fb->bits_per_pixel);
+               DRM_ERROR("Unknown pixel format 0x%08x\n", fb->pixel_format);
                return -EINVAL;
        }
 
@@ -8334,24 +8352,36 @@ int intel_framebuffer_init(struct drm_device *dev,
        if (mode_cmd->pitches[0] & 63)
                return -EINVAL;
 
+       /* Reject formats not supported by any plane early. */
        switch (mode_cmd->pixel_format) {
-       case DRM_FORMAT_RGB332:
+       case DRM_FORMAT_C8:
        case DRM_FORMAT_RGB565:
        case DRM_FORMAT_XRGB8888:
-       case DRM_FORMAT_XBGR8888:
        case DRM_FORMAT_ARGB8888:
+               break;
+       case DRM_FORMAT_XRGB1555:
+       case DRM_FORMAT_ARGB1555:
+               if (INTEL_INFO(dev)->gen > 3)
+                       return -EINVAL;
+               break;
+       case DRM_FORMAT_XBGR8888:
+       case DRM_FORMAT_ABGR8888:
        case DRM_FORMAT_XRGB2101010:
        case DRM_FORMAT_ARGB2101010:
-               /* RGB formats are common across chipsets */
+       case DRM_FORMAT_XBGR2101010:
+       case DRM_FORMAT_ABGR2101010:
+               if (INTEL_INFO(dev)->gen < 4)
+                       return -EINVAL;
                break;
        case DRM_FORMAT_YUYV:
        case DRM_FORMAT_UYVY:
        case DRM_FORMAT_YVYU:
        case DRM_FORMAT_VYUY:
+               if (INTEL_INFO(dev)->gen < 6)
+                       return -EINVAL;
                break;
        default:
-               DRM_DEBUG_KMS("unsupported pixel format %u\n",
-                               mode_cmd->pixel_format);
+               DRM_DEBUG_KMS("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format);
                return -EINVAL;
        }