All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Yao <mark.yao@rock-chips.com>
To: dri-devel@lists.freedesktop.org
Cc: David Airlie <airlied@linux.ie>, Heiko Stuebner <heiko@sntech.de>,
	Daniel Kurtz <djkurtz@chromium.org>,
	Mark Yao <mark.yao@rock-chips.com>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	Daniel Vetter <daniel@ffwll.ch>, Rob Clark <robdclark@gmail.com>,
	tfiga@chromium.org, linux-arm-kernel@lists.infradead.org,
	linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org,
	sandy.huang@rock-chips.com, dkm@rock-chips.com,
	zwl@rock-chips.com
Subject: [PATCH v4 3/6] drm/rockchip: vop: Add yuv plane support
Date: Mon, 27 Jul 2015 10:05:59 +0800	[thread overview]
Message-ID: <1437962762-19157-4-git-send-email-mark.yao@rock-chips.com> (raw)
In-Reply-To: <1437962762-19157-1-git-send-email-mark.yao@rock-chips.com>

vop support yuv with NV12, NV16 and NV24, only 2 plane yuv.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v4: rebase to drm-next, fix conflict

Changes in v3:
Adviced by Tomasz Figa
- separate dest calculate to another patch
- fix src x1,x2 when do align, and remove unnecessary src.y1 align.

Changes in v2:
- Uv buffer not support odd offset, align it.
- Fix error display when move yuv image.  

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   56 ++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index da72de9..c1264d5 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -393,6 +393,18 @@ static enum vop_data_format vop_convert_format(uint32_t format)
 	}
 }
 
+static bool is_yuv_support(uint32_t format)
+{
+	switch (format) {
+	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_NV16:
+	case DRM_FORMAT_NV24:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static bool is_alpha_support(uint32_t format)
 {
 	switch (format) {
@@ -598,17 +610,22 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	struct vop *vop = to_vop(crtc);
 	struct drm_gem_object *obj;
 	struct rockchip_gem_object *rk_obj;
+	struct drm_gem_object *uv_obj;
+	struct rockchip_gem_object *rk_uv_obj;
 	unsigned long offset;
 	unsigned int actual_w;
 	unsigned int actual_h;
 	unsigned int dsp_stx;
 	unsigned int dsp_sty;
 	unsigned int y_vir_stride;
+	unsigned int uv_vir_stride = 0;
 	dma_addr_t yrgb_mst;
+	dma_addr_t uv_mst = 0;
 	enum vop_data_format format;
 	uint32_t val;
 	bool is_alpha;
 	bool rb_swap;
+	bool is_yuv;
 	bool visible;
 	int ret;
 	struct drm_rect dest = {
@@ -643,6 +660,8 @@ static int vop_update_plane_event(struct drm_plane *plane,
 
 	is_alpha = is_alpha_support(fb->pixel_format);
 	rb_swap = has_rb_swapped(fb->pixel_format);
+	is_yuv = is_yuv_support(fb->pixel_format);
+
 	format = vop_convert_format(fb->pixel_format);
 	if (format < 0)
 		return format;
@@ -655,18 +674,47 @@ static int vop_update_plane_event(struct drm_plane *plane,
 
 	rk_obj = to_rockchip_obj(obj);
 
+	if (is_yuv) {
+		/*
+		 * Src.x1 can be odd when do clip, but yuv plane start point
+		 * need align with 2 pixel.
+		 */
+		val = (src.x1 >> 16) % 2;
+		src.x1 += val << 16;
+		src.x2 += val << 16;
+	}
+
 	actual_w = (src.x2 - src.x1) >> 16;
 	actual_h = (src.y2 - src.y1) >> 16;
 
 	dsp_stx = dest.x1 + crtc->mode.htotal - crtc->mode.hsync_start;
 	dsp_sty = dest.y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
 
-	offset = (src.x1 >> 16) * (fb->bits_per_pixel >> 3);
+	offset = (src.x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
 	offset += (src.y1 >> 16) * fb->pitches[0];
-	yrgb_mst = rk_obj->dma_addr + offset;
 
+	yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
 	y_vir_stride = fb->pitches[0] >> 2;
 
+	if (is_yuv) {
+		int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
+		int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
+		int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
+
+		uv_obj = rockchip_fb_get_gem_obj(fb, 1);
+		if (!uv_obj) {
+			DRM_ERROR("fail to get uv object from framebuffer\n");
+			return -EINVAL;
+		}
+		rk_uv_obj = to_rockchip_obj(uv_obj);
+		uv_vir_stride = fb->pitches[1] >> 2;
+
+		offset = (src.x1 >> 16) * bpp / hsub;
+		offset += (src.y1 >> 16) * fb->pitches[1] / vsub;
+
+		uv_mst = rk_uv_obj->dma_addr + offset + fb->offsets[1];
+	}
+
 	/*
 	 * If this plane update changes the plane's framebuffer, (or more
 	 * precisely, if this update has a different framebuffer than the last
@@ -702,6 +750,10 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	VOP_WIN_SET(vop, win, format, format);
 	VOP_WIN_SET(vop, win, yrgb_vir, y_vir_stride);
 	VOP_WIN_SET(vop, win, yrgb_mst, yrgb_mst);
+	if (is_yuv) {
+		VOP_WIN_SET(vop, win, uv_vir, uv_vir_stride);
+		VOP_WIN_SET(vop, win, uv_mst, uv_mst);
+	}
 	val = (actual_h - 1) << 16;
 	val |= (actual_w - 1) & 0xffff;
 	VOP_WIN_SET(vop, win, act_info, val);
-- 
1.7.9.5



WARNING: multiple messages have this Message-ID (diff)
From: Mark Yao <mark.yao@rock-chips.com>
To: dri-devel@lists.freedesktop.org
Cc: zwl@rock-chips.com, linux-kernel@vger.kernel.org,
	tfiga@chromium.org, linux-rockchip@lists.infradead.org,
	dkm@rock-chips.com, sandy.huang@rock-chips.com,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 3/6] drm/rockchip: vop: Add yuv plane support
Date: Mon, 27 Jul 2015 10:05:59 +0800	[thread overview]
Message-ID: <1437962762-19157-4-git-send-email-mark.yao@rock-chips.com> (raw)
In-Reply-To: <1437962762-19157-1-git-send-email-mark.yao@rock-chips.com>

vop support yuv with NV12, NV16 and NV24, only 2 plane yuv.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v4: rebase to drm-next, fix conflict

Changes in v3:
Adviced by Tomasz Figa
- separate dest calculate to another patch
- fix src x1,x2 when do align, and remove unnecessary src.y1 align.

Changes in v2:
- Uv buffer not support odd offset, align it.
- Fix error display when move yuv image.  

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   56 ++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index da72de9..c1264d5 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -393,6 +393,18 @@ static enum vop_data_format vop_convert_format(uint32_t format)
 	}
 }
 
+static bool is_yuv_support(uint32_t format)
+{
+	switch (format) {
+	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_NV16:
+	case DRM_FORMAT_NV24:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static bool is_alpha_support(uint32_t format)
 {
 	switch (format) {
@@ -598,17 +610,22 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	struct vop *vop = to_vop(crtc);
 	struct drm_gem_object *obj;
 	struct rockchip_gem_object *rk_obj;
+	struct drm_gem_object *uv_obj;
+	struct rockchip_gem_object *rk_uv_obj;
 	unsigned long offset;
 	unsigned int actual_w;
 	unsigned int actual_h;
 	unsigned int dsp_stx;
 	unsigned int dsp_sty;
 	unsigned int y_vir_stride;
+	unsigned int uv_vir_stride = 0;
 	dma_addr_t yrgb_mst;
+	dma_addr_t uv_mst = 0;
 	enum vop_data_format format;
 	uint32_t val;
 	bool is_alpha;
 	bool rb_swap;
+	bool is_yuv;
 	bool visible;
 	int ret;
 	struct drm_rect dest = {
@@ -643,6 +660,8 @@ static int vop_update_plane_event(struct drm_plane *plane,
 
 	is_alpha = is_alpha_support(fb->pixel_format);
 	rb_swap = has_rb_swapped(fb->pixel_format);
+	is_yuv = is_yuv_support(fb->pixel_format);
+
 	format = vop_convert_format(fb->pixel_format);
 	if (format < 0)
 		return format;
@@ -655,18 +674,47 @@ static int vop_update_plane_event(struct drm_plane *plane,
 
 	rk_obj = to_rockchip_obj(obj);
 
+	if (is_yuv) {
+		/*
+		 * Src.x1 can be odd when do clip, but yuv plane start point
+		 * need align with 2 pixel.
+		 */
+		val = (src.x1 >> 16) % 2;
+		src.x1 += val << 16;
+		src.x2 += val << 16;
+	}
+
 	actual_w = (src.x2 - src.x1) >> 16;
 	actual_h = (src.y2 - src.y1) >> 16;
 
 	dsp_stx = dest.x1 + crtc->mode.htotal - crtc->mode.hsync_start;
 	dsp_sty = dest.y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
 
-	offset = (src.x1 >> 16) * (fb->bits_per_pixel >> 3);
+	offset = (src.x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
 	offset += (src.y1 >> 16) * fb->pitches[0];
-	yrgb_mst = rk_obj->dma_addr + offset;
 
+	yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
 	y_vir_stride = fb->pitches[0] >> 2;
 
+	if (is_yuv) {
+		int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
+		int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
+		int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
+
+		uv_obj = rockchip_fb_get_gem_obj(fb, 1);
+		if (!uv_obj) {
+			DRM_ERROR("fail to get uv object from framebuffer\n");
+			return -EINVAL;
+		}
+		rk_uv_obj = to_rockchip_obj(uv_obj);
+		uv_vir_stride = fb->pitches[1] >> 2;
+
+		offset = (src.x1 >> 16) * bpp / hsub;
+		offset += (src.y1 >> 16) * fb->pitches[1] / vsub;
+
+		uv_mst = rk_uv_obj->dma_addr + offset + fb->offsets[1];
+	}
+
 	/*
 	 * If this plane update changes the plane's framebuffer, (or more
 	 * precisely, if this update has a different framebuffer than the last
@@ -702,6 +750,10 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	VOP_WIN_SET(vop, win, format, format);
 	VOP_WIN_SET(vop, win, yrgb_vir, y_vir_stride);
 	VOP_WIN_SET(vop, win, yrgb_mst, yrgb_mst);
+	if (is_yuv) {
+		VOP_WIN_SET(vop, win, uv_vir, uv_vir_stride);
+		VOP_WIN_SET(vop, win, uv_mst, uv_mst);
+	}
 	val = (actual_h - 1) << 16;
 	val |= (actual_w - 1) & 0xffff;
 	VOP_WIN_SET(vop, win, act_info, val);
-- 
1.7.9.5


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: mark.yao@rock-chips.com (Mark Yao)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 3/6] drm/rockchip: vop: Add yuv plane support
Date: Mon, 27 Jul 2015 10:05:59 +0800	[thread overview]
Message-ID: <1437962762-19157-4-git-send-email-mark.yao@rock-chips.com> (raw)
In-Reply-To: <1437962762-19157-1-git-send-email-mark.yao@rock-chips.com>

vop support yuv with NV12, NV16 and NV24, only 2 plane yuv.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v4: rebase to drm-next, fix conflict

Changes in v3:
Adviced by Tomasz Figa
- separate dest calculate to another patch
- fix src x1,x2 when do align, and remove unnecessary src.y1 align.

Changes in v2:
- Uv buffer not support odd offset, align it.
- Fix error display when move yuv image.  

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   56 ++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index da72de9..c1264d5 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -393,6 +393,18 @@ static enum vop_data_format vop_convert_format(uint32_t format)
 	}
 }
 
+static bool is_yuv_support(uint32_t format)
+{
+	switch (format) {
+	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_NV16:
+	case DRM_FORMAT_NV24:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static bool is_alpha_support(uint32_t format)
 {
 	switch (format) {
@@ -598,17 +610,22 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	struct vop *vop = to_vop(crtc);
 	struct drm_gem_object *obj;
 	struct rockchip_gem_object *rk_obj;
+	struct drm_gem_object *uv_obj;
+	struct rockchip_gem_object *rk_uv_obj;
 	unsigned long offset;
 	unsigned int actual_w;
 	unsigned int actual_h;
 	unsigned int dsp_stx;
 	unsigned int dsp_sty;
 	unsigned int y_vir_stride;
+	unsigned int uv_vir_stride = 0;
 	dma_addr_t yrgb_mst;
+	dma_addr_t uv_mst = 0;
 	enum vop_data_format format;
 	uint32_t val;
 	bool is_alpha;
 	bool rb_swap;
+	bool is_yuv;
 	bool visible;
 	int ret;
 	struct drm_rect dest = {
@@ -643,6 +660,8 @@ static int vop_update_plane_event(struct drm_plane *plane,
 
 	is_alpha = is_alpha_support(fb->pixel_format);
 	rb_swap = has_rb_swapped(fb->pixel_format);
+	is_yuv = is_yuv_support(fb->pixel_format);
+
 	format = vop_convert_format(fb->pixel_format);
 	if (format < 0)
 		return format;
@@ -655,18 +674,47 @@ static int vop_update_plane_event(struct drm_plane *plane,
 
 	rk_obj = to_rockchip_obj(obj);
 
+	if (is_yuv) {
+		/*
+		 * Src.x1 can be odd when do clip, but yuv plane start point
+		 * need align with 2 pixel.
+		 */
+		val = (src.x1 >> 16) % 2;
+		src.x1 += val << 16;
+		src.x2 += val << 16;
+	}
+
 	actual_w = (src.x2 - src.x1) >> 16;
 	actual_h = (src.y2 - src.y1) >> 16;
 
 	dsp_stx = dest.x1 + crtc->mode.htotal - crtc->mode.hsync_start;
 	dsp_sty = dest.y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
 
-	offset = (src.x1 >> 16) * (fb->bits_per_pixel >> 3);
+	offset = (src.x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
 	offset += (src.y1 >> 16) * fb->pitches[0];
-	yrgb_mst = rk_obj->dma_addr + offset;
 
+	yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
 	y_vir_stride = fb->pitches[0] >> 2;
 
+	if (is_yuv) {
+		int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
+		int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
+		int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
+
+		uv_obj = rockchip_fb_get_gem_obj(fb, 1);
+		if (!uv_obj) {
+			DRM_ERROR("fail to get uv object from framebuffer\n");
+			return -EINVAL;
+		}
+		rk_uv_obj = to_rockchip_obj(uv_obj);
+		uv_vir_stride = fb->pitches[1] >> 2;
+
+		offset = (src.x1 >> 16) * bpp / hsub;
+		offset += (src.y1 >> 16) * fb->pitches[1] / vsub;
+
+		uv_mst = rk_uv_obj->dma_addr + offset + fb->offsets[1];
+	}
+
 	/*
 	 * If this plane update changes the plane's framebuffer, (or more
 	 * precisely, if this update has a different framebuffer than the last
@@ -702,6 +750,10 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	VOP_WIN_SET(vop, win, format, format);
 	VOP_WIN_SET(vop, win, yrgb_vir, y_vir_stride);
 	VOP_WIN_SET(vop, win, yrgb_mst, yrgb_mst);
+	if (is_yuv) {
+		VOP_WIN_SET(vop, win, uv_vir, uv_vir_stride);
+		VOP_WIN_SET(vop, win, uv_mst, uv_mst);
+	}
 	val = (actual_h - 1) << 16;
 	val |= (actual_w - 1) & 0xffff;
 	VOP_WIN_SET(vop, win, act_info, val);
-- 
1.7.9.5

  parent reply	other threads:[~2015-07-27  2:07 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-27  2:05 [PATCH v4 0/6] drm/rockchip: fixes and new features Mark Yao
2015-07-27  2:05 ` Mark Yao
2015-07-27  2:05 ` [PATCH v4 1/6] drm/rockchip: vop: Fix virtual stride calculation Mark Yao
2015-07-27  2:05   ` Mark Yao
2015-07-27  2:05 ` [PATCH v4 2/6] drm/rockchip: vop: Fix window dest start point Mark Yao
2015-07-27  2:05   ` Mark Yao
2015-07-27  2:05 ` Mark Yao [this message]
2015-07-27  2:05   ` [PATCH v4 3/6] drm/rockchip: vop: Add yuv plane support Mark Yao
2015-07-27  2:05   ` Mark Yao
2015-07-27  2:06 ` [PATCH v4 4/6] drm/rockchip: vop: Default enable win2/3 area0 bit Mark Yao
2015-07-27  2:06   ` Mark Yao
2015-07-27  2:06   ` Mark Yao
2015-07-27  2:08 ` [PATCH v4 5/6] drm/rockchip: vop: restore vop registers when resume Mark Yao
2015-07-27  2:08   ` Mark Yao
2015-07-27  2:08   ` Mark Yao
2015-07-27  2:09 ` [PATCH v4 6/6] drm/rockchip: vop: support plane scale Mark Yao
2015-07-27  2:09   ` Mark Yao
2015-07-27  2:09   ` Mark Yao
2015-08-26  6:34 ` [GIT PULL] drm/rockchip: fixes and new features Mark yao
2015-08-26  6:34   ` Mark yao
2015-08-26  6:34   ` Mark yao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1437962762-19157-4-git-send-email-mark.yao@rock-chips.com \
    --to=mark.yao@rock-chips.com \
    --cc=airlied@linux.ie \
    --cc=daniel@ffwll.ch \
    --cc=djkurtz@chromium.org \
    --cc=dkm@rock-chips.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=heiko@sntech.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=p.zabel@pengutronix.de \
    --cc=robdclark@gmail.com \
    --cc=sandy.huang@rock-chips.com \
    --cc=tfiga@chromium.org \
    --cc=zwl@rock-chips.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.