From: Ville Syrj?l? <ville.syrj...@linux.intel.com>

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 at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      |   17 ++++--
 drivers/gpu/drm/i915/intel_display.c |   94 ++++++++++++++++++++++------------
 2 files changed, 74 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a4162dd..c2e82cc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2998,12 +2998,19 @@
 #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
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 461a637..2dd19f3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1969,24 +1969,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;
@@ -2053,27 +2067,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;
        }

@@ -7707,24 +7725,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;
        }

-- 
1.7.8.6

Reply via email to