From: Laurent Pinchart Date: Thu, 12 Nov 2015 00:03:47 +0000 (+0200) Subject: drm: rcar-du: Add tri-planar memory formats support X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=7863ac504bc5473eb99c4356120aa372d453143e;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git drm: rcar-du: Add tri-planar memory formats support Those formats are supported on Gen3 only. Signed-off-by: Laurent Pinchart --- diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 7d65251d3df0..24725bf859b4 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -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); diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index 24acee1633e9..de7ef041182b 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -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) {