OSDN Git Service

drm: rcar-du: Add tri-planar memory formats support
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Thu, 12 Nov 2015 00:03:47 +0000 (02:03 +0200)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tue, 23 Feb 2016 07:34:33 +0000 (09:34 +0200)
Those formats are supported on Gen3 only.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
drivers/gpu/drm/rcar-du/rcar_du_kms.c
drivers/gpu/drm/rcar-du/rcar_du_vsp.c

index 7d65251..24725bf 100644 (file)
@@ -90,13 +90,44 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
                .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
                .edf = PnDDCR4_EDF_NONE,
        }, {
-               /* In YUV 4:2:2, only NV16 is supported (NV61 isn't) */
                .fourcc = DRM_FORMAT_NV16,
                .bpp = 16,
                .planes = 2,
                .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
                .edf = PnDDCR4_EDF_NONE,
        },
+       /* The following formats are not supported on Gen2 and thus have no
+        * associated .pnmr or .edf settings.
+        */
+       {
+               .fourcc = DRM_FORMAT_NV61,
+               .bpp = 16,
+               .planes = 2,
+       }, {
+               .fourcc = DRM_FORMAT_YUV420,
+               .bpp = 12,
+               .planes = 3,
+       }, {
+               .fourcc = DRM_FORMAT_YVU420,
+               .bpp = 12,
+               .planes = 3,
+       }, {
+               .fourcc = DRM_FORMAT_YUV422,
+               .bpp = 16,
+               .planes = 3,
+       }, {
+               .fourcc = DRM_FORMAT_YVU422,
+               .bpp = 16,
+               .planes = 3,
+       }, {
+               .fourcc = DRM_FORMAT_YUV444,
+               .bpp = 24,
+               .planes = 3,
+       }, {
+               .fourcc = DRM_FORMAT_YVU444,
+               .bpp = 24,
+               .planes = 3,
+       },
 };
 
 const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc)
@@ -144,6 +175,7 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
        unsigned int max_pitch;
        unsigned int align;
        unsigned int bpp;
+       unsigned int i;
 
        format = rcar_du_format_info(mode_cmd->pixel_format);
        if (format == NULL) {
@@ -156,7 +188,7 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
         * The pitch and alignment constraints are expressed in pixels on the
         * hardware side and in bytes in the DRM API.
         */
-       bpp = format->planes == 2 ? 1 : format->bpp / 8;
+       bpp = format->planes == 1 ? format->bpp / 8 : 1;
        max_pitch =  4096 * bpp;
 
        if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
@@ -171,8 +203,8 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
                return ERR_PTR(-EINVAL);
        }
 
-       if (format->planes == 2) {
-               if (mode_cmd->pitches[1] != mode_cmd->pitches[0]) {
+       for (i = 1; i < format->planes; ++i) {
+               if (mode_cmd->pitches[i] != mode_cmd->pitches[0]) {
                        dev_dbg(dev->dev,
                                "luma and chroma pitches do not match\n");
                        return ERR_PTR(-EINVAL);
index 24acee1..de7ef04 100644 (file)
@@ -106,6 +106,12 @@ static const u32 formats_kms[] = {
        DRM_FORMAT_NV21,
        DRM_FORMAT_NV16,
        DRM_FORMAT_NV61,
+       DRM_FORMAT_YUV420,
+       DRM_FORMAT_YVU420,
+       DRM_FORMAT_YUV422,
+       DRM_FORMAT_YVU422,
+       DRM_FORMAT_YUV444,
+       DRM_FORMAT_YVU444,
 };
 
 static const u32 formats_v4l2[] = {
@@ -129,6 +135,12 @@ static const u32 formats_v4l2[] = {
        V4L2_PIX_FMT_NV21M,
        V4L2_PIX_FMT_NV16M,
        V4L2_PIX_FMT_NV61M,
+       V4L2_PIX_FMT_YUV420M,
+       V4L2_PIX_FMT_YVU420M,
+       V4L2_PIX_FMT_YUV422M,
+       V4L2_PIX_FMT_YVU422M,
+       V4L2_PIX_FMT_YUV444M,
+       V4L2_PIX_FMT_YVU444M,
 };
 
 static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
@@ -136,7 +148,6 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
        struct rcar_du_vsp_plane_state *state =
                to_rcar_vsp_plane_state(plane->plane.state);
        struct drm_framebuffer *fb = plane->plane.state->fb;
-       struct drm_gem_cma_object *gem;
        struct v4l2_rect src;
        struct v4l2_rect dst;
        dma_addr_t paddr[2] = { 0, };
@@ -153,12 +164,11 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
        dst.width = state->state.crtc_w;
        dst.height = state->state.crtc_h;
 
-       gem = drm_fb_cma_get_gem_obj(fb, 0);
-       paddr[0] = gem->paddr + fb->offsets[0];
+       for (i = 0; i < state->format->planes; ++i) {
+               struct drm_gem_cma_object *gem;
 
-       if (state->format->planes == 2) {
-               gem = drm_fb_cma_get_gem_obj(fb, 1);
-               paddr[1] = gem->paddr + fb->offsets[1];
+               gem = drm_fb_cma_get_gem_obj(fb, i);
+               paddr[i] = gem->paddr + fb->offsets[i];
        }
 
        for (i = 0; i < ARRAY_SIZE(formats_kms); ++i) {