2020-06-07 20:27:37

by Jonas Karlman

[permalink] [raw]
Subject: [PATCH 0/2] drm: rockchip: add NV15 and NV20 support

Hi,

This series adds support for displaying 10-bit 4:2:0 and 4:2:2 formats produced
by the Rockchip Video Decoder on RK322X, RK3288, RK3328, RK3368 and RK3399.

First patch adds a new fourcc 10-bit YUV format with 4:2:2 sub-sampling.
Second patch adds support for using the the two new fourcc formats.
Both depend on "drm: drm_fourcc: add NV15, Q410, Q401 YUV formats" at [1].

This series can also be found at [2], and can be tested on RK3399 using an
upcoming rkvdec series at [3] together with ffmpeg at [4] and kodi-gbm or mpv.

[1] https://patchwork.freedesktop.org/series/76326/
[2] https://github.com/Kwiboo/linux-rockchip/commits/next-20200605-fmt_10
[3] https://github.com/Kwiboo/linux-rockchip/commits/next-20200605-rkvdec
[4] https://github.com/Kwiboo/FFmpeg/commits/v4l2-request-hwaccel-4.2.2-rkvdec

Regards,
Jonas

Jonas Karlman (2):
drm: drm_fourcc: add NV20 YUV format
drm: rockchip: add NV15 and NV20 support

drivers/gpu/drm/drm_fourcc.c | 4 +++
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 27 ++++++++++++++++--
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 31 +++++++++++++++++----
include/uapi/drm/drm_fourcc.h | 1 +
5 files changed, 56 insertions(+), 8 deletions(-)

--
2.17.1


2020-06-07 20:28:15

by Jonas Karlman

[permalink] [raw]
Subject: [PATCH 1/2] drm: drm_fourcc: add NV20 YUV format

DRM_FORMAT_NV20 is a 2 plane format suitable for linear memory layout.
The format is similar to P210 with 4:2:2 sub-sampling but has no padding
between components. Instead, luminance and chrominance samples are grouped
into 4s so that each group is packed into an integer number of bytes:

YYYY = UVUV = 4 * 10 bits = 40 bits = 5 bytes

The '20' suffix refers to the optimum effective bits per pixel which is
achieved when the total number of luminance samples is a multiple of 4.

Signed-off-by: Jonas Karlman <[email protected]>
---
drivers/gpu/drm/drm_fourcc.c | 4 ++++
include/uapi/drm/drm_fourcc.h | 1 +
2 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 722c7ebe4e88..2a9c8ae719ed 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -278,6 +278,10 @@ const struct drm_format_info *__drm_format_info(u32 format)
.num_planes = 2, .char_per_block = { 5, 5, 0 },
.block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
.vsub = 2, .is_yuv = true },
+ { .format = DRM_FORMAT_NV20, .depth = 0,
+ .num_planes = 2, .char_per_block = { 5, 5, 0 },
+ .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
+ .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_Q410, .depth = 0,
.num_planes = 3, .char_per_block = { 2, 2, 2 },
.block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index b5bf1c0e630e..244d32433a67 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -242,6 +242,7 @@ extern "C" {
* index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
*/
#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */

/*
* 2 plane YCbCr MSB aligned
--
2.17.1

2020-06-07 20:30:00

by Jonas Karlman

[permalink] [raw]
Subject: [PATCH 2/2] drm: rockchip: add NV15 and NV20 support

Add support for displaying 10-bit 4:2:0 and 4:2:2 formats produced by the
Rockchip Video Decoder on RK322X, RK3288, RK3328, RK3368 and RK3399.

Signed-off-by: Jonas Karlman <[email protected]>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 27 ++++++++++++++++--
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 31 +++++++++++++++++----
3 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 33463b79a37b..13a0682d438b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -261,6 +261,17 @@ static bool has_rb_swapped(uint32_t format)
}
}

+static bool is_fmt_10(uint32_t format)
+{
+ switch (format) {
+ case DRM_FORMAT_NV15:
+ case DRM_FORMAT_NV20:
+ return true;
+ default:
+ return false;
+ }
+}
+
static enum vop_data_format vop_convert_format(uint32_t format)
{
switch (format) {
@@ -276,8 +287,10 @@ static enum vop_data_format vop_convert_format(uint32_t format)
case DRM_FORMAT_BGR565:
return VOP_FMT_RGB565;
case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV15:
return VOP_FMT_YUV420SP;
case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV20:
return VOP_FMT_YUV422SP;
case DRM_FORMAT_NV24:
return VOP_FMT_YUV444SP;
@@ -922,7 +935,12 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);

- offset = (src->x1 >> 16) * fb->format->cpp[0];
+ if (fb->format->block_w[0])
+ offset = (src->x1 >> 16) * fb->format->char_per_block[0] /
+ fb->format->block_w[0];
+ else
+ offset = (src->x1 >> 16) * fb->format->cpp[0];
+
offset += (src->y1 >> 16) * fb->pitches[0];
dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];

@@ -948,6 +966,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
}

VOP_WIN_SET(vop, win, format, format);
+ VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format));
VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
@@ -964,7 +983,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
uv_obj = fb->obj[1];
rk_uv_obj = to_rockchip_obj(uv_obj);

- offset = (src->x1 >> 16) * bpp / hsub;
+ if (fb->format->block_w[1])
+ offset = (src->x1 >> 16) * bpp /
+ fb->format->block_w[1] / hsub;
+ else
+ offset = (src->x1 >> 16) * bpp / hsub;
offset += (src->y1 >> 16) * fb->pitches[1] / vsub;

dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index d03bdb531ef2..db1138da2bd4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -154,6 +154,7 @@ struct vop_win_phy {
struct vop_reg enable;
struct vop_reg gate;
struct vop_reg format;
+ struct vop_reg fmt_10;
struct vop_reg rb_swap;
struct vop_reg act_info;
struct vop_reg dsp_info;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 2413deded22c..503736c8b6c4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -50,6 +50,22 @@ static const uint32_t formats_win_full[] = {
DRM_FORMAT_NV24,
};

+static const uint32_t formats_win_full_10[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_BGR888,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_BGR565,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV15,
+ DRM_FORMAT_NV20,
+};
+
static const uint64_t format_modifiers_win_full[] = {
DRM_FORMAT_MOD_LINEAR,
DRM_FORMAT_MOD_INVALID,
@@ -570,11 +586,12 @@ static const struct vop_scl_regs rk3288_win_full_scl = {

static const struct vop_win_phy rk3288_win01_data = {
.scl = &rk3288_win_full_scl,
- .data_formats = formats_win_full,
- .nformats = ARRAY_SIZE(formats_win_full),
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
.format_modifiers = format_modifiers_win_full,
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
@@ -704,11 +721,12 @@ static const struct vop_intr rk3368_vop_intr = {

static const struct vop_win_phy rk3368_win01_data = {
.scl = &rk3288_win_full_scl,
- .data_formats = formats_win_full,
- .nformats = ARRAY_SIZE(formats_win_full),
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
.format_modifiers = format_modifiers_win_full,
.enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
.x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
.y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
@@ -853,11 +871,12 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {

static const struct vop_win_phy rk3399_win01_data = {
.scl = &rk3288_win_full_scl,
- .data_formats = formats_win_full,
- .nformats = ARRAY_SIZE(formats_win_full),
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
.format_modifiers = format_modifiers_win_full_afbc,
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
--
2.17.1

2020-06-08 09:16:56

by Brian Starkey

[permalink] [raw]
Subject: Re: [PATCH 1/2] drm: drm_fourcc: add NV20 YUV format

Hi Jonas,

On Sun, Jun 07, 2020 at 08:25:25PM +0000, Jonas Karlman wrote:
> DRM_FORMAT_NV20 is a 2 plane format suitable for linear memory layout.
> The format is similar to P210 with 4:2:2 sub-sampling but has no padding
> between components. Instead, luminance and chrominance samples are grouped
> into 4s so that each group is packed into an integer number of bytes:
>
> YYYY = UVUV = 4 * 10 bits = 40 bits = 5 bytes
>
> The '20' suffix refers to the optimum effective bits per pixel which is
> achieved when the total number of luminance samples is a multiple of 4.
>
> Signed-off-by: Jonas Karlman <[email protected]>
> ---
> drivers/gpu/drm/drm_fourcc.c | 4 ++++
> include/uapi/drm/drm_fourcc.h | 1 +
> 2 files changed, 5 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index 722c7ebe4e88..2a9c8ae719ed 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -278,6 +278,10 @@ const struct drm_format_info *__drm_format_info(u32 format)
> .num_planes = 2, .char_per_block = { 5, 5, 0 },
> .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
> .vsub = 2, .is_yuv = true },
> + { .format = DRM_FORMAT_NV20, .depth = 0,
> + .num_planes = 2, .char_per_block = { 5, 5, 0 },
> + .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
> + .vsub = 1, .is_yuv = true },

That looks how I would expect, so:

Reviewed-by: Brian Starkey <[email protected]>

Cheers,
-Brian

> { .format = DRM_FORMAT_Q410, .depth = 0,
> .num_planes = 3, .char_per_block = { 2, 2, 2 },
> .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> index b5bf1c0e630e..244d32433a67 100644
> --- a/include/uapi/drm/drm_fourcc.h
> +++ b/include/uapi/drm/drm_fourcc.h
> @@ -242,6 +242,7 @@ extern "C" {
> * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
> */
> #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */
> +#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */
>
> /*
> * 2 plane YCbCr MSB aligned
> --
> 2.17.1
>

2020-06-17 09:32:29

by Heiko Stuebner

[permalink] [raw]
Subject: Re: [PATCH 2/2] drm: rockchip: add NV15 and NV20 support

Am Sonntag, 7. Juni 2020, 22:25:26 CEST schrieb Jonas Karlman:
> Add support for displaying 10-bit 4:2:0 and 4:2:2 formats produced by the
> Rockchip Video Decoder on RK322X, RK3288, RK3328, RK3368 and RK3399.
>
> Signed-off-by: Jonas Karlman <[email protected]>

Reviewed-by: Heiko Stuebner <[email protected]>

> ---
> drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 27 ++++++++++++++++--
> drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
> drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 31 +++++++++++++++++----
> 3 files changed, 51 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 33463b79a37b..13a0682d438b 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -261,6 +261,17 @@ static bool has_rb_swapped(uint32_t format)
> }
> }
>
> +static bool is_fmt_10(uint32_t format)
> +{
> + switch (format) {
> + case DRM_FORMAT_NV15:
> + case DRM_FORMAT_NV20:
> + return true;
> + default:
> + return false;
> + }
> +}
> +
> static enum vop_data_format vop_convert_format(uint32_t format)
> {
> switch (format) {
> @@ -276,8 +287,10 @@ static enum vop_data_format vop_convert_format(uint32_t format)
> case DRM_FORMAT_BGR565:
> return VOP_FMT_RGB565;
> case DRM_FORMAT_NV12:
> + case DRM_FORMAT_NV15:
> return VOP_FMT_YUV420SP;
> case DRM_FORMAT_NV16:
> + case DRM_FORMAT_NV20:
> return VOP_FMT_YUV422SP;
> case DRM_FORMAT_NV24:
> return VOP_FMT_YUV444SP;
> @@ -922,7 +935,12 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
> dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
> dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
>
> - offset = (src->x1 >> 16) * fb->format->cpp[0];
> + if (fb->format->block_w[0])
> + offset = (src->x1 >> 16) * fb->format->char_per_block[0] /
> + fb->format->block_w[0];
> + else
> + offset = (src->x1 >> 16) * fb->format->cpp[0];
> +
> offset += (src->y1 >> 16) * fb->pitches[0];
> dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];
>
> @@ -948,6 +966,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
> }
>
> VOP_WIN_SET(vop, win, format, format);
> + VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format));
> VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
> VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
> VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
> @@ -964,7 +983,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
> uv_obj = fb->obj[1];
> rk_uv_obj = to_rockchip_obj(uv_obj);
>
> - offset = (src->x1 >> 16) * bpp / hsub;
> + if (fb->format->block_w[1])
> + offset = (src->x1 >> 16) * bpp /
> + fb->format->block_w[1] / hsub;
> + else
> + offset = (src->x1 >> 16) * bpp / hsub;
> offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
>
> dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
> index d03bdb531ef2..db1138da2bd4 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
> @@ -154,6 +154,7 @@ struct vop_win_phy {
> struct vop_reg enable;
> struct vop_reg gate;
> struct vop_reg format;
> + struct vop_reg fmt_10;
> struct vop_reg rb_swap;
> struct vop_reg act_info;
> struct vop_reg dsp_info;
> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> index 2413deded22c..503736c8b6c4 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> @@ -50,6 +50,22 @@ static const uint32_t formats_win_full[] = {
> DRM_FORMAT_NV24,
> };
>
> +static const uint32_t formats_win_full_10[] = {
> + DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_ARGB8888,
> + DRM_FORMAT_XBGR8888,
> + DRM_FORMAT_ABGR8888,
> + DRM_FORMAT_RGB888,
> + DRM_FORMAT_BGR888,
> + DRM_FORMAT_RGB565,
> + DRM_FORMAT_BGR565,
> + DRM_FORMAT_NV12,
> + DRM_FORMAT_NV16,
> + DRM_FORMAT_NV24,
> + DRM_FORMAT_NV15,
> + DRM_FORMAT_NV20,
> +};
> +
> static const uint64_t format_modifiers_win_full[] = {
> DRM_FORMAT_MOD_LINEAR,
> DRM_FORMAT_MOD_INVALID,
> @@ -570,11 +586,12 @@ static const struct vop_scl_regs rk3288_win_full_scl = {
>
> static const struct vop_win_phy rk3288_win01_data = {
> .scl = &rk3288_win_full_scl,
> - .data_formats = formats_win_full,
> - .nformats = ARRAY_SIZE(formats_win_full),
> + .data_formats = formats_win_full_10,
> + .nformats = ARRAY_SIZE(formats_win_full_10),
> .format_modifiers = format_modifiers_win_full,
> .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
> .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
> + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
> .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
> .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
> .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
> @@ -704,11 +721,12 @@ static const struct vop_intr rk3368_vop_intr = {
>
> static const struct vop_win_phy rk3368_win01_data = {
> .scl = &rk3288_win_full_scl,
> - .data_formats = formats_win_full,
> - .nformats = ARRAY_SIZE(formats_win_full),
> + .data_formats = formats_win_full_10,
> + .nformats = ARRAY_SIZE(formats_win_full_10),
> .format_modifiers = format_modifiers_win_full,
> .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
> .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
> + .fmt_10 = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 4),
> .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
> .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
> .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
> @@ -853,11 +871,12 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
>
> static const struct vop_win_phy rk3399_win01_data = {
> .scl = &rk3288_win_full_scl,
> - .data_formats = formats_win_full,
> - .nformats = ARRAY_SIZE(formats_win_full),
> + .data_formats = formats_win_full_10,
> + .nformats = ARRAY_SIZE(formats_win_full_10),
> .format_modifiers = format_modifiers_win_full_afbc,
> .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
> .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
> + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
> .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
> .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
> .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
>




2020-06-17 12:18:12

by Sandy Huang

[permalink] [raw]
Subject: Re: [PATCH 1/2] drm: drm_fourcc: add NV20 YUV format【请注意,邮件由linux-rockchip-bo [email protected] 代发】

Hi Jonas Karlman,

    Is there an another yuv 10bit format with 4:4:4 sub-simpling but
has no padding?

 Maybe we can call it DRM_FORMAT_NV30:

{ .format = DRM_FORMAT_NV30, .depth = 0,
.num_planes = 2, .char_per_block = { 5, 5, 0 },
.block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1,
.vsub = 1, .is_yuv = true },

this format can supported by rockchip rk3288/rk3399... platform, can you
add this format at this series patches?

在 2020/6/8 4:25, Jonas Karlman 写道:
> DRM_FORMAT_NV20 is a 2 plane format suitable for linear memory layout.
> The format is similar to P210 with 4:2:2 sub-sampling but has no padding
> between components. Instead, luminance and chrominance samples are grouped
> into 4s so that each group is packed into an integer number of bytes:
>
> YYYY = UVUV = 4 * 10 bits = 40 bits = 5 bytes
>
> The '20' suffix refers to the optimum effective bits per pixel which is
> achieved when the total number of luminance samples is a multiple of 4.
>
> Signed-off-by: Jonas Karlman <[email protected]>
> ---
> drivers/gpu/drm/drm_fourcc.c | 4 ++++
> include/uapi/drm/drm_fourcc.h | 1 +
> 2 files changed, 5 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index 722c7ebe4e88..2a9c8ae719ed 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -278,6 +278,10 @@ const struct drm_format_info *__drm_format_info(u32 format)
> .num_planes = 2, .char_per_block = { 5, 5, 0 },
> .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
> .vsub = 2, .is_yuv = true },
> + { .format = DRM_FORMAT_NV20, .depth = 0,
> + .num_planes = 2, .char_per_block = { 5, 5, 0 },
> + .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
> + .vsub = 1, .is_yuv = true },
> { .format = DRM_FORMAT_Q410, .depth = 0,
> .num_planes = 3, .char_per_block = { 2, 2, 2 },
> .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> index b5bf1c0e630e..244d32433a67 100644
> --- a/include/uapi/drm/drm_fourcc.h
> +++ b/include/uapi/drm/drm_fourcc.h
> @@ -242,6 +242,7 @@ extern "C" {
> * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
> */
> #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */
> +#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */
>
> /*
> * 2 plane YCbCr MSB aligned

--
Best Regard

黄家钗
Sandy Huang
Addr: 福州市鼓楼区铜盘路软件大道89号福州软件园A区21号楼(350003)
No. 21 Building, A District, No.89,software Boulevard Fuzhou,Fujian,PRC
Tel:+86 0591-87884919 8690
E-mail:[email protected]



2020-06-26 14:22:03

by Jonas Karlman

[permalink] [raw]
Subject: Re: [PATCH 1/2] drm: drm_fourcc: add NV20 YUV format【请注意,邮件由linux-rockchip-bounces+sa [email protected] d.org代发】

On 2020-06-17 14:07, Huang Jiachai wrote:
> Hi Jonas Karlman,
>
>     Is there an another yuv 10bit format with 4:4:4 sub-simpling but
> has no padding?
>
>  Maybe we can call it DRM_FORMAT_NV30:
>
> { .format = DRM_FORMAT_NV30, .depth = 0,
> .num_planes = 2, .char_per_block = { 5, 5, 0 },
> .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1,
> .vsub = 1, .is_yuv = true },
>
> this format can supported by rockchip rk3288/rk3399... platform, can you
> add this format at this series patches?

I will send a v2 including this 4:4:4 format later this weekend.

Is there any hw block on rk3288/rk3399 that can produce a buffer in such format?
If I am not mistaken rkvdec only support 10-bit h264 in 4:2:0/4:2:2 and
hevc 4:2:0 10-bit, those are the formats I have been able to test so far.

Regards,
Jonas

>
> 在 2020/6/8 4:25, Jonas Karlman 写道:
>> DRM_FORMAT_NV20 is a 2 plane format suitable for linear memory layout.
>> The format is similar to P210 with 4:2:2 sub-sampling but has no padding
>> between components. Instead, luminance and chrominance samples are grouped
>> into 4s so that each group is packed into an integer number of bytes:
>>
>> YYYY = UVUV = 4 * 10 bits = 40 bits = 5 bytes
>>
>> The '20' suffix refers to the optimum effective bits per pixel which is
>> achieved when the total number of luminance samples is a multiple of 4.
>>
>> Signed-off-by: Jonas Karlman <[email protected]>
>> ---
>> drivers/gpu/drm/drm_fourcc.c | 4 ++++
>> include/uapi/drm/drm_fourcc.h | 1 +
>> 2 files changed, 5 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
>> index 722c7ebe4e88..2a9c8ae719ed 100644
>> --- a/drivers/gpu/drm/drm_fourcc.c
>> +++ b/drivers/gpu/drm/drm_fourcc.c
>> @@ -278,6 +278,10 @@ const struct drm_format_info *__drm_format_info(u32 format)
>> .num_planes = 2, .char_per_block = { 5, 5, 0 },
>> .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
>> .vsub = 2, .is_yuv = true },
>> + { .format = DRM_FORMAT_NV20, .depth = 0,
>> + .num_planes = 2, .char_per_block = { 5, 5, 0 },
>> + .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
>> + .vsub = 1, .is_yuv = true },
>> { .format = DRM_FORMAT_Q410, .depth = 0,
>> .num_planes = 3, .char_per_block = { 2, 2, 2 },
>> .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
>> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
>> index b5bf1c0e630e..244d32433a67 100644
>> --- a/include/uapi/drm/drm_fourcc.h
>> +++ b/include/uapi/drm/drm_fourcc.h
>> @@ -242,6 +242,7 @@ extern "C" {
>> * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
>> */
>> #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */
>> +#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */
>>
>> /*
>> * 2 plane YCbCr MSB aligned
>

2020-06-28 01:54:28

by Sandy Huang

[permalink] [raw]
Subject: Re: [PATCH 1/2] drm: drm_fourcc: add NV20 YUV format【请注意,邮件由linux-rockchip-bo [email protected] 代发】

Hi Jonas Karlman,

在 2020/6/26 22:19, Jonas Karlman 写道:
> On 2020-06-17 14:07, Huang Jiachai wrote:
>> Hi Jonas Karlman,
>>
>>     Is there an another yuv 10bit format with 4:4:4 sub-simpling but
>> has no padding?
>>
>>  Maybe we can call it DRM_FORMAT_NV30:
>>
>> { .format = DRM_FORMAT_NV30, .depth = 0,
>> .num_planes = 2, .char_per_block = { 5, 5, 0 },
>> .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1,
>> .vsub = 1, .is_yuv = true },
>>
>> this format can supported by rockchip rk3288/rk3399... platform, can you
>> add this format at this series patches?
> I will send a v2 including this 4:4:4 format later this weekend.
>
> Is there any hw block on rk3288/rk3399 that can produce a buffer in such format?
> If I am not mistaken rkvdec only support 10-bit h264 in 4:2:0/4:2:2 and
> hevc 4:2:0 10-bit, those are the formats I have been able to test so far.
>
> Regards,
> Jonas

yes,rockchip platform hw video decoder 10-bit yuv format only can
support 4:2:0/4:2:2 so far, but the software decoder path maybe output
4:4:4-10 format to VOP.

>
>> 在 2020/6/8 4:25, Jonas Karlman 写道:
>>> DRM_FORMAT_NV20 is a 2 plane format suitable for linear memory layout.
>>> The format is similar to P210 with 4:2:2 sub-sampling but has no padding
>>> between components. Instead, luminance and chrominance samples are grouped
>>> into 4s so that each group is packed into an integer number of bytes:
>>>
>>> YYYY = UVUV = 4 * 10 bits = 40 bits = 5 bytes
>>>
>>> The '20' suffix refers to the optimum effective bits per pixel which is
>>> achieved when the total number of luminance samples is a multiple of 4.
>>>
>>> Signed-off-by: Jonas Karlman <[email protected]>
>>> ---
>>> drivers/gpu/drm/drm_fourcc.c | 4 ++++
>>> include/uapi/drm/drm_fourcc.h | 1 +
>>> 2 files changed, 5 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
>>> index 722c7ebe4e88..2a9c8ae719ed 100644
>>> --- a/drivers/gpu/drm/drm_fourcc.c
>>> +++ b/drivers/gpu/drm/drm_fourcc.c
>>> @@ -278,6 +278,10 @@ const struct drm_format_info *__drm_format_info(u32 format)
>>> .num_planes = 2, .char_per_block = { 5, 5, 0 },
>>> .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
>>> .vsub = 2, .is_yuv = true },
>>> + { .format = DRM_FORMAT_NV20, .depth = 0,
>>> + .num_planes = 2, .char_per_block = { 5, 5, 0 },
>>> + .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
>>> + .vsub = 1, .is_yuv = true },
>>> { .format = DRM_FORMAT_Q410, .depth = 0,
>>> .num_planes = 3, .char_per_block = { 2, 2, 2 },
>>> .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
>>> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
>>> index b5bf1c0e630e..244d32433a67 100644
>>> --- a/include/uapi/drm/drm_fourcc.h
>>> +++ b/include/uapi/drm/drm_fourcc.h
>>> @@ -242,6 +242,7 @@ extern "C" {
>>> * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
>>> */
>>> #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */
>>> +#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */
>>>
>>> /*
>>> * 2 plane YCbCr MSB aligned
> _______________________________________________
> Linux-rockchip mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-rockchip

--
Best Regard

黄家钗
Sandy Huang
Addr: 福州市鼓楼区铜盘路软件大道89号福州软件园A区21号楼(350003)
No. 21 Building, A District, No.89,software Boulevard
Fuzhou,Fujian,PRC
Tel:+86 0591-87884919 8690
E-mail:[email protected]



2020-07-06 22:31:22

by Jonas Karlman

[permalink] [raw]
Subject: [PATCH v2 0/2] drm: rockchip: add NV15, NV20 and NV30 support

Hi,

This series adds support for displaying 10-bit 4:2:0 and 4:2:2 formats produced
by the Rockchip Video Decoder on RK322X, RK3288, RK3328, RK3368 and RK3399.
Also include 10-bit 4:4:4 support since VOP can support that also.

First patch adds new fourcc 10-bit YUV formats with 4:2:2/4:4:4 sub-sampling.
Second patch adds support for displaying the the new fourcc formats.

Changes in v2:
- Add NV30 format
- R-B tags was not collected due to NV30 changes

This series has been tested on RK3399 using a Rockchip Video Decoder series
at [1] together with ffmpeg at [2] and kodi-gbm or mpv. [3] contains all
patches needed on top of linux-media master for easy testing.

[1] https://patchwork.linuxtv.org/project/linux-media/list/?series=2859
[2] https://github.com/Kwiboo/FFmpeg/commits/v4l2-request-hwaccel-4.3-rkvdec-high-10
[3] https://github.com/Kwiboo/linux-rockchip/commits/linuxtv-rkvdec-high-10-v2

Regards,
Jonas

Jonas Karlman (2):
drm: drm_fourcc: add NV20 and NV30 YUV formats
drm: rockchip: add NV15, NV20 and NV30 support

drivers/gpu/drm/drm_fourcc.c | 8 ++++++
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +++++++++++++++++--
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 32 +++++++++++++++++----
include/uapi/drm/drm_fourcc.h | 2 ++
5 files changed, 64 insertions(+), 8 deletions(-)

--
2.17.1

2020-07-06 22:31:27

by Jonas Karlman

[permalink] [raw]
Subject: [PATCH v2 2/2] drm: rockchip: add NV15, NV20 and NV30 support

Add support for displaying 10-bit 4:2:0 and 4:2:2 formats produced by the
Rockchip Video Decoder on RK322X, RK3288, RK3328, RK3368 and RK3399.
Also add support for 10-bit 4:4:4 format while at it.

V2: Added NV30 support

Signed-off-by: Jonas Karlman <[email protected]>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +++++++++++++++++--
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 32 +++++++++++++++++----
3 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index c80f7d9fd13f..eb663e25ad9e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -261,6 +261,18 @@ static bool has_rb_swapped(uint32_t format)
}
}

+static bool is_fmt_10(uint32_t format)
+{
+ switch (format) {
+ case DRM_FORMAT_NV15:
+ case DRM_FORMAT_NV20:
+ case DRM_FORMAT_NV30:
+ return true;
+ default:
+ return false;
+ }
+}
+
static enum vop_data_format vop_convert_format(uint32_t format)
{
switch (format) {
@@ -276,10 +288,13 @@ static enum vop_data_format vop_convert_format(uint32_t format)
case DRM_FORMAT_BGR565:
return VOP_FMT_RGB565;
case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV15:
return VOP_FMT_YUV420SP;
case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV20:
return VOP_FMT_YUV422SP;
case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV30:
return VOP_FMT_YUV444SP;
default:
DRM_ERROR("unsupported format[%08x]\n", format);
@@ -922,7 +937,12 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);

- offset = (src->x1 >> 16) * fb->format->cpp[0];
+ if (fb->format->block_w[0])
+ offset = (src->x1 >> 16) * fb->format->char_per_block[0] /
+ fb->format->block_w[0];
+ else
+ offset = (src->x1 >> 16) * fb->format->cpp[0];
+
offset += (src->y1 >> 16) * fb->pitches[0];
dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];

@@ -948,6 +968,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
}

VOP_WIN_SET(vop, win, format, format);
+ VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format));
VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
@@ -964,7 +985,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
uv_obj = fb->obj[1];
rk_uv_obj = to_rockchip_obj(uv_obj);

- offset = (src->x1 >> 16) * bpp / hsub;
+ if (fb->format->block_w[1])
+ offset = (src->x1 >> 16) * bpp /
+ fb->format->block_w[1] / hsub;
+ else
+ offset = (src->x1 >> 16) * bpp / hsub;
offset += (src->y1 >> 16) * fb->pitches[1] / vsub;

dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 4a2099cb582e..eab055d9b56d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -154,6 +154,7 @@ struct vop_win_phy {
struct vop_reg enable;
struct vop_reg gate;
struct vop_reg format;
+ struct vop_reg fmt_10;
struct vop_reg rb_swap;
struct vop_reg act_info;
struct vop_reg dsp_info;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 80053d91a301..2c55e1852c3d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -50,6 +50,23 @@ static const uint32_t formats_win_full[] = {
DRM_FORMAT_NV24,
};

+static const uint32_t formats_win_full_10[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_BGR888,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_BGR565,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV15,
+ DRM_FORMAT_NV20,
+ DRM_FORMAT_NV30,
+};
+
static const uint64_t format_modifiers_win_full[] = {
DRM_FORMAT_MOD_LINEAR,
DRM_FORMAT_MOD_INVALID,
@@ -579,11 +596,12 @@ static const struct vop_scl_regs rk3288_win_full_scl = {

static const struct vop_win_phy rk3288_win01_data = {
.scl = &rk3288_win_full_scl,
- .data_formats = formats_win_full,
- .nformats = ARRAY_SIZE(formats_win_full),
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
.format_modifiers = format_modifiers_win_full,
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
@@ -713,11 +731,12 @@ static const struct vop_intr rk3368_vop_intr = {

static const struct vop_win_phy rk3368_win01_data = {
.scl = &rk3288_win_full_scl,
- .data_formats = formats_win_full,
- .nformats = ARRAY_SIZE(formats_win_full),
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
.format_modifiers = format_modifiers_win_full,
.enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
.x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
.y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
@@ -862,11 +881,12 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {

static const struct vop_win_phy rk3399_win01_data = {
.scl = &rk3288_win_full_scl,
- .data_formats = formats_win_full,
- .nformats = ARRAY_SIZE(formats_win_full),
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
.format_modifiers = format_modifiers_win_full_afbc,
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
--
2.17.1

2020-07-07 11:47:46

by Sandy Huang

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] drm: rockchip: add NV15, N V20 and NV30 support【请注意,邮件由linu [email protected] radead.org代发】


?? 2020/7/7 6:30, Jonas Karlman д??:
> Add support for displaying 10-bit 4:2:0 and 4:2:2 formats produced by the
> Rockchip Video Decoder on RK322X, RK3288, RK3328, RK3368 and RK3399.
> Also add support for 10-bit 4:4:4 format while at it.
>
> V2: Added NV30 support
>
> Signed-off-by: Jonas Karlman <[email protected]>
> ---
> drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +++++++++++++++++--
> drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
> drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 32 +++++++++++++++++----
> 3 files changed, 54 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index c80f7d9fd13f..eb663e25ad9e 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -261,6 +261,18 @@ static bool has_rb_swapped(uint32_t format)
> }
> }
>
> +static bool is_fmt_10(uint32_t format)
> +{
> + switch (format) {
> + case DRM_FORMAT_NV15:
> + case DRM_FORMAT_NV20:
> + case DRM_FORMAT_NV30:
> + return true;
> + default:
> + return false;
> + }
> +}
> +
> static enum vop_data_format vop_convert_format(uint32_t format)
> {
> switch (format) {
> @@ -276,10 +288,13 @@ static enum vop_data_format vop_convert_format(uint32_t format)
> case DRM_FORMAT_BGR565:
> return VOP_FMT_RGB565;
> case DRM_FORMAT_NV12:
> + case DRM_FORMAT_NV15:
> return VOP_FMT_YUV420SP;
> case DRM_FORMAT_NV16:
> + case DRM_FORMAT_NV20:
> return VOP_FMT_YUV422SP;
> case DRM_FORMAT_NV24:
> + case DRM_FORMAT_NV30:
> return VOP_FMT_YUV444SP;
> default:
> DRM_ERROR("unsupported format[%08x]\n", format);
> @@ -922,7 +937,12 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
> dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
> dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
>
> - offset = (src->x1 >> 16) * fb->format->cpp[0];
> + if (fb->format->block_w[0])
> + offset = (src->x1 >> 16) * fb->format->char_per_block[0] /
> + fb->format->block_w[0];
> + else
> + offset = (src->x1 >> 16) * fb->format->cpp[0];
> +
> offset += (src->y1 >> 16) * fb->pitches[0];
> dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];
>
> @@ -948,6 +968,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
> }
>
> VOP_WIN_SET(vop, win, format, format);
> + VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format));
> VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
> VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
> VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
> @@ -964,7 +985,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
> uv_obj = fb->obj[1];
> rk_uv_obj = to_rockchip_obj(uv_obj);
>
> - offset = (src->x1 >> 16) * bpp / hsub;
> + if (fb->format->block_w[1])
> + offset = (src->x1 >> 16) * bpp /
> + fb->format->block_w[1] / hsub;
> + else
> + offset = (src->x1 >> 16) * bpp / hsub;
> offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
>
> dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
> index 4a2099cb582e..eab055d9b56d 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
> @@ -154,6 +154,7 @@ struct vop_win_phy {
> struct vop_reg enable;
> struct vop_reg gate;
> struct vop_reg format;
> + struct vop_reg fmt_10;
> struct vop_reg rb_swap;
> struct vop_reg act_info;
> struct vop_reg dsp_info;
> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> index 80053d91a301..2c55e1852c3d 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> @@ -50,6 +50,23 @@ static const uint32_t formats_win_full[] = {
> DRM_FORMAT_NV24,
> };
>
> +static const uint32_t formats_win_full_10[] = {
> + DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_ARGB8888,
> + DRM_FORMAT_XBGR8888,
> + DRM_FORMAT_ABGR8888,
> + DRM_FORMAT_RGB888,
> + DRM_FORMAT_BGR888,
> + DRM_FORMAT_RGB565,
> + DRM_FORMAT_BGR565,
> + DRM_FORMAT_NV12,
> + DRM_FORMAT_NV16,
> + DRM_FORMAT_NV24,
> + DRM_FORMAT_NV15,
> + DRM_FORMAT_NV20,
> + DRM_FORMAT_NV30,
> +};
> +
> static const uint64_t format_modifiers_win_full[] = {
> DRM_FORMAT_MOD_LINEAR,
> DRM_FORMAT_MOD_INVALID,
> @@ -579,11 +596,12 @@ static const struct vop_scl_regs rk3288_win_full_scl = {
>
> static const struct vop_win_phy rk3288_win01_data = {
> .scl = &rk3288_win_full_scl,
> - .data_formats = formats_win_full,
> - .nformats = ARRAY_SIZE(formats_win_full),
> + .data_formats = formats_win_full_10,
> + .nformats = ARRAY_SIZE(formats_win_full_10),
> .format_modifiers = format_modifiers_win_full,
> .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
> .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
> + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
> .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
> .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
> .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
> @@ -713,11 +731,12 @@ static const struct vop_intr rk3368_vop_intr = {
>
> static const struct vop_win_phy rk3368_win01_data = {
> .scl = &rk3288_win_full_scl,
> - .data_formats = formats_win_full,
> - .nformats = ARRAY_SIZE(formats_win_full),
> + .data_formats = formats_win_full_10,
> + .nformats = ARRAY_SIZE(formats_win_full_10),
> .format_modifiers = format_modifiers_win_full,
> .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
> .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
> + .fmt_10 = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 4),
> .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
> .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
> .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
> @@ -862,11 +881,12 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
>
> static const struct vop_win_phy rk3399_win01_data = {
> .scl = &rk3288_win_full_scl,
> - .data_formats = formats_win_full,
> - .nformats = ARRAY_SIZE(formats_win_full),
> + .data_formats = formats_win_full_10,
> + .nformats = ARRAY_SIZE(formats_win_full_10),
> .format_modifiers = format_modifiers_win_full_afbc,
> .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
> .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
> + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
> .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
> .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
> .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),

Reviewed-by: Sandy Huang <[email protected]>

--
Best Regard

?Ƽ???
Sandy Huang
Addr: ?????й?¥??ͭ??·????????89?Ÿ???????԰A??21??¥(350003)
No. 21 Building, A District, No.89,software Boulevard Fuzhou,Fujian,PRC
Tel??+86 0591-87884919 8690
[email protected]



2020-07-14 07:37:26

by Alex Bee

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] drm: rockchip: add NV15, NV20 and NV30 support

Hi Jonas,

Am 07.07.20 um 00:30 schrieb Jonas Karlman:
> Add support for displaying 10-bit 4:2:0 and 4:2:2 formats produced by the
> Rockchip Video Decoder on RK322X, RK3288, RK3328, RK3368 and RK3399.
> Also add support for 10-bit 4:4:4 format while at it.
>
> V2: Added NV30 support
>
> Signed-off-by: Jonas Karlman <[email protected]>
> Reviewed-by: Sandy Huang <[email protected]>
> ---
> drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +++++++++++++++++--
> drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
> drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 32 +++++++++++++++++----
> 3 files changed, 54 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index c80f7d9fd13f..eb663e25ad9e 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -261,6 +261,18 @@ static bool has_rb_swapped(uint32_t format)
> }
> }
>
> +static bool is_fmt_10(uint32_t format)
> +{
> + switch (format) {
> + case DRM_FORMAT_NV15:
> + case DRM_FORMAT_NV20:
> + case DRM_FORMAT_NV30:
> + return true;
> + default:
> + return false;
> + }
> +}
> +
> static enum vop_data_format vop_convert_format(uint32_t format)
> {
> switch (format) {
> @@ -276,10 +288,13 @@ static enum vop_data_format vop_convert_format(uint32_t format)
> case DRM_FORMAT_BGR565:
> return VOP_FMT_RGB565;
> case DRM_FORMAT_NV12:
> + case DRM_FORMAT_NV15:
> return VOP_FMT_YUV420SP;
> case DRM_FORMAT_NV16:
> + case DRM_FORMAT_NV20:
> return VOP_FMT_YUV422SP;
> case DRM_FORMAT_NV24:
> + case DRM_FORMAT_NV30:
> return VOP_FMT_YUV444SP;
> default:
> DRM_ERROR("unsupported format[%08x]\n", format);
> @@ -922,7 +937,12 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
> dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
> dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
>
> - offset = (src->x1 >> 16) * fb->format->cpp[0];
> + if (fb->format->block_w[0])
> + offset = (src->x1 >> 16) * fb->format->char_per_block[0] /
> + fb->format->block_w[0];
> + else
> + offset = (src->x1 >> 16) * fb->format->cpp[0];
> +
> offset += (src->y1 >> 16) * fb->pitches[0];
> dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];
>
> @@ -948,6 +968,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
> }
>
> VOP_WIN_SET(vop, win, format, format);
> + VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format));
> VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
> VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
> VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
> @@ -964,7 +985,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
> uv_obj = fb->obj[1];
> rk_uv_obj = to_rockchip_obj(uv_obj);
>
> - offset = (src->x1 >> 16) * bpp / hsub;
> + if (fb->format->block_w[1])
> + offset = (src->x1 >> 16) * bpp /
> + fb->format->block_w[1] / hsub;
> + else
> + offset = (src->x1 >> 16) * bpp / hsub;
> offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
>
> dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
> index 4a2099cb582e..eab055d9b56d 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
> @@ -154,6 +154,7 @@ struct vop_win_phy {
> struct vop_reg enable;
> struct vop_reg gate;
> struct vop_reg format;
> + struct vop_reg fmt_10;
> struct vop_reg rb_swap;
> struct vop_reg act_info;
> struct vop_reg dsp_info;
> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> index 80053d91a301..2c55e1852c3d 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> @@ -50,6 +50,23 @@ static const uint32_t formats_win_full[] = {
> DRM_FORMAT_NV24,
> };
>
> +static const uint32_t formats_win_full_10[] = {
> + DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_ARGB8888,
> + DRM_FORMAT_XBGR8888,
> + DRM_FORMAT_ABGR8888,
> + DRM_FORMAT_RGB888,
> + DRM_FORMAT_BGR888,
> + DRM_FORMAT_RGB565,
> + DRM_FORMAT_BGR565,
> + DRM_FORMAT_NV12,
> + DRM_FORMAT_NV16,
> + DRM_FORMAT_NV24,
> + DRM_FORMAT_NV15,
> + DRM_FORMAT_NV20,
> + DRM_FORMAT_NV30,
> +};
> +
> static const uint64_t format_modifiers_win_full[] = {
> DRM_FORMAT_MOD_LINEAR,
> DRM_FORMAT_MOD_INVALID,
> @@ -579,11 +596,12 @@ static const struct vop_scl_regs rk3288_win_full_scl = {
>
> static const struct vop_win_phy rk3288_win01_data = {
> .scl = &rk3288_win_full_scl,
> - .data_formats = formats_win_full,
> - .nformats = ARRAY_SIZE(formats_win_full),
> + .data_formats = formats_win_full_10,
> + .nformats = ARRAY_SIZE(formats_win_full_10),
> .format_modifiers = format_modifiers_win_full,
> .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
> .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
> + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
> .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
> .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
> .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
> @@ -713,11 +731,12 @@ static const struct vop_intr rk3368_vop_intr = {
>
> static const struct vop_win_phy rk3368_win01_data = {
> .scl = &rk3288_win_full_scl,
> - .data_formats = formats_win_full,
> - .nformats = ARRAY_SIZE(formats_win_full),
> + .data_formats = formats_win_full_10,
> + .nformats = ARRAY_SIZE(formats_win_full_10),
> .format_modifiers = format_modifiers_win_full,
> .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
> .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
> + .fmt_10 = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 4),
> .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
> .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
> .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),

As per TRM/datasheet RK3368's VOP does not support 10-bit color formats.

Therefore data_formats should be kept at formats_win_full here.

> @@ -862,11 +881,12 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
>
> static const struct vop_win_phy rk3399_win01_data = {
> .scl = &rk3288_win_full_scl,
> - .data_formats = formats_win_full,
> - .nformats = ARRAY_SIZE(formats_win_full),
> + .data_formats = formats_win_full_10,
> + .nformats = ARRAY_SIZE(formats_win_full_10),
> .format_modifiers = format_modifiers_win_full_afbc,
> .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
> .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
> + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
> .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
> .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
> .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),

Regards,

Alex