drm: add 10bit support for yuv format
authorMark Yao <mark.yao@rock-chips.com>
Wed, 23 Nov 2016 07:46:41 +0000 (15:46 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 24 Nov 2016 04:59:29 +0000 (12:59 +0800)
drm_format_plane_cpp use byte size, not works for 10bit
format, use drm_format_plane_bpp instead.

Change-Id: If1a6ca1c286747fdc868184cebe75eb0af0a746d
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
drivers/gpu/drm/drm_crtc.c
include/drm/drm_crtc.h
include/uapi/drm/drm_fourcc.h

index 29d13ef..b99a608 100644 (file)
@@ -3233,6 +3233,12 @@ static int format_check(const struct drm_mode_fb_cmd2 *r)
        case DRM_FORMAT_NV61:
        case DRM_FORMAT_NV24:
        case DRM_FORMAT_NV42:
+       case DRM_FORMAT_NV12_10:
+       case DRM_FORMAT_NV21_10:
+       case DRM_FORMAT_NV16_10:
+       case DRM_FORMAT_NV61_10:
+       case DRM_FORMAT_NV24_10:
+       case DRM_FORMAT_NV42_10:
        case DRM_FORMAT_YUV410:
        case DRM_FORMAT_YVU410:
        case DRM_FORMAT_YUV411:
@@ -3279,20 +3285,20 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
        for (i = 0; i < num_planes; i++) {
                unsigned int width = r->width / (i != 0 ? hsub : 1);
                unsigned int height = r->height / (i != 0 ? vsub : 1);
-               unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i);
+               unsigned int bpp = drm_format_plane_bpp(r->pixel_format, i);
 
                if (!r->handles[i]) {
                        DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
                        return -EINVAL;
                }
 
-               if ((uint64_t) width * cpp > UINT_MAX)
+               if ((uint64_t) width * bpp / 8 > UINT_MAX)
                        return -ERANGE;
 
                if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
                        return -ERANGE;
 
-               if (r->pitches[i] < width * cpp) {
+               if (r->pitches[i] < roundup(width * bpp, 8) / 8) {
                        DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
                        return -EINVAL;
                }
@@ -5716,6 +5722,12 @@ int drm_format_num_planes(uint32_t format)
        case DRM_FORMAT_NV61:
        case DRM_FORMAT_NV24:
        case DRM_FORMAT_NV42:
+       case DRM_FORMAT_NV12_10:
+       case DRM_FORMAT_NV21_10:
+       case DRM_FORMAT_NV16_10:
+       case DRM_FORMAT_NV61_10:
+       case DRM_FORMAT_NV24_10:
+       case DRM_FORMAT_NV42_10:
                return 2;
        default:
                return 1;
@@ -5724,14 +5736,14 @@ int drm_format_num_planes(uint32_t format)
 EXPORT_SYMBOL(drm_format_num_planes);
 
 /**
- * drm_format_plane_cpp - determine the bytes per pixel value
+ * drm_format_plane_bpp - get the bpp for format
  * @format: pixel format (DRM_FORMAT_*)
  * @plane: plane index
  *
  * Returns:
- * The bytes per pixel value for the specified plane.
+ * The bpp for the specified plane.
  */
-int drm_format_plane_cpp(uint32_t format, int plane)
+int drm_format_plane_bpp(uint32_t format, int plane)
 {
        unsigned int depth;
        int bpp;
@@ -5744,14 +5756,21 @@ int drm_format_plane_cpp(uint32_t format, int plane)
        case DRM_FORMAT_YVYU:
        case DRM_FORMAT_UYVY:
        case DRM_FORMAT_VYUY:
-               return 2;
+               return 16;
+       case DRM_FORMAT_NV12_10:
+       case DRM_FORMAT_NV21_10:
+       case DRM_FORMAT_NV16_10:
+       case DRM_FORMAT_NV61_10:
+       case DRM_FORMAT_NV24_10:
+       case DRM_FORMAT_NV42_10:
+               return plane ? 20 : 10;
        case DRM_FORMAT_NV12:
        case DRM_FORMAT_NV21:
        case DRM_FORMAT_NV16:
        case DRM_FORMAT_NV61:
        case DRM_FORMAT_NV24:
        case DRM_FORMAT_NV42:
-               return plane ? 2 : 1;
+               return plane ? 16 : 8;
        case DRM_FORMAT_YUV410:
        case DRM_FORMAT_YVU410:
        case DRM_FORMAT_YUV411:
@@ -5762,12 +5781,26 @@ int drm_format_plane_cpp(uint32_t format, int plane)
        case DRM_FORMAT_YVU422:
        case DRM_FORMAT_YUV444:
        case DRM_FORMAT_YVU444:
-               return 1;
+               return 8;
        default:
                drm_fb_get_bpp_depth(format, &depth, &bpp);
-               return bpp >> 3;
+               return bpp;
        }
 }
+EXPORT_SYMBOL(drm_format_plane_bpp);
+
+/**
+ * drm_format_plane_cpp - determine the bytes per pixel value
+ * @format: pixel format (DRM_FORMAT_*)
+ * @plane: plane index
+ *
+ * Returns:
+ * The bytes per pixel value for the specified plane.
+ */
+int drm_format_plane_cpp(uint32_t format, int plane)
+{
+       return drm_format_plane_bpp(format, plane) >> 3;
+}
 EXPORT_SYMBOL(drm_format_plane_cpp);
 
 /**
@@ -5794,6 +5827,10 @@ int drm_format_horz_chroma_subsampling(uint32_t format)
        case DRM_FORMAT_NV21:
        case DRM_FORMAT_NV16:
        case DRM_FORMAT_NV61:
+       case DRM_FORMAT_NV12_10:
+       case DRM_FORMAT_NV21_10:
+       case DRM_FORMAT_NV16_10:
+       case DRM_FORMAT_NV61_10:
        case DRM_FORMAT_YUV422:
        case DRM_FORMAT_YVU422:
        case DRM_FORMAT_YUV420:
@@ -5822,7 +5859,9 @@ int drm_format_vert_chroma_subsampling(uint32_t format)
        case DRM_FORMAT_YUV420:
        case DRM_FORMAT_YVU420:
        case DRM_FORMAT_NV12:
+       case DRM_FORMAT_NV12_10:
        case DRM_FORMAT_NV21:
+       case DRM_FORMAT_NV21_10:
                return 2;
        default:
                return 1;
index 0fc87d4..dd5dc4e 100644 (file)
@@ -1511,6 +1511,7 @@ extern int drm_mode_atomic_ioctl(struct drm_device *dev,
 extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
                                 int *bpp);
 extern int drm_format_num_planes(uint32_t format);
+extern int drm_format_plane_bpp(uint32_t format, int plane);
 extern int drm_format_plane_cpp(uint32_t format, int plane);
 extern int drm_format_horz_chroma_subsampling(uint32_t format);
 extern int drm_format_vert_chroma_subsampling(uint32_t format);
index 79c94b4..dc4bff5 100644 (file)
 #define DRM_FORMAT_NV24                fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
 #define DRM_FORMAT_NV42                fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
 
+#define DRM_FORMAT_NV12_10     fourcc_code('N', 'A', '1', '2') /* 2x2 subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV21_10     fourcc_code('N', 'A', '2', '1') /* 2x2 subsampled Cb:Cr plane */
+#define DRM_FORMAT_NV16_10     fourcc_code('N', 'A', '1', '6') /* 2x1 subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV61_10     fourcc_code('N', 'A', '6', '1') /* 2x1 subsampled Cb:Cr plane */
+#define DRM_FORMAT_NV24_10     fourcc_code('N', 'A', '2', '4') /* non-subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV42_10     fourcc_code('N', 'A', '4', '2') /* non-subsampled Cb:Cr plane */
+
 /*
  * 3 plane YCbCr
  * index 0: Y plane, [7:0] Y