From e1f6f92d1cf6694a114cb9a66bcacc89a445c06a Mon Sep 17 00:00:00 2001 From: Li Huang Date: Fri, 25 Oct 2019 14:34:34 +0800 Subject: [PATCH] video/rockchip: rga2: add YUV packet format support Change-Id: I3b002b1bc0f06a1480936a66a90e8545402bdb84 Signed-off-by: Li Huang --- drivers/video/rockchip/rga2/rga2.h | 10 +++ drivers/video/rockchip/rga2/rga2_drv.c | 17 +++++ drivers/video/rockchip/rga2/rga2_mmu_info.c | 26 +++++++ drivers/video/rockchip/rga2/rga2_reg_info.c | 81 +++++++++++++++++---- 4 files changed, 119 insertions(+), 15 deletions(-) diff --git a/drivers/video/rockchip/rga2/rga2.h b/drivers/video/rockchip/rga2/rga2.h index 6a3bdf7a7e4a..dfd5d76023e5 100644 --- a/drivers/video/rockchip/rga2/rga2.h +++ b/drivers/video/rockchip/rga2/rga2.h @@ -102,6 +102,16 @@ enum RGA2_FORMAT_YCrCb_422_P = 0x15, RGA2_FORMAT_YCrCb_420_SP = 0x16, RGA2_FORMAT_YCrCb_420_P = 0x17, + + RGA2_FORMAT_YVYU_422 = 0x18, + RGA2_FORMAT_YVYU_420 = 0x19, + RGA2_FORMAT_VYUY_422 = 0x1a, + RGA2_FORMAT_VYUY_420 = 0x1b, + RGA2_FORMAT_YUYV_422 = 0x1c, + RGA2_FORMAT_YUYV_420 = 0x1d, + RGA2_FORMAT_UYVY_422 = 0x1e, + RGA2_FORMAT_UYVY_420 = 0x1f, + RGA2_FORMAT_YCbCr_420_SP_10B = 0x20, RGA2_FORMAT_YCrCb_420_SP_10B = 0x21, RGA2_FORMAT_YCbCr_422_SP_10B = 0x22, diff --git a/drivers/video/rockchip/rga2/rga2_drv.c b/drivers/video/rockchip/rga2/rga2_drv.c index 2dbe9ea87fde..b01ff1b6a3f6 100644 --- a/drivers/video/rockchip/rga2/rga2_drv.c +++ b/drivers/video/rockchip/rga2/rga2_drv.c @@ -289,6 +289,23 @@ static const char *rga2_get_format_name(uint32_t format) case RGA2_FORMAT_YCrCb_420_P: return "YCrCb420P"; + case RGA2_FORMAT_YVYU_422: + return "YVYU422"; + case RGA2_FORMAT_YVYU_420: + return "YVYU420"; + case RGA2_FORMAT_VYUY_422: + return "VYUY422"; + case RGA2_FORMAT_VYUY_420: + return "VYUY420"; + case RGA2_FORMAT_YUYV_422: + return "YUYV422"; + case RGA2_FORMAT_YUYV_420: + return "YUYV420"; + case RGA2_FORMAT_UYVY_422: + return "UYVY422"; + case RGA2_FORMAT_UYVY_420: + return "UYVY420"; + case RGA2_FORMAT_YCbCr_420_SP_10B: return "YCrCb420SP10B"; case RGA2_FORMAT_YCrCb_420_SP_10B: diff --git a/drivers/video/rockchip/rga2/rga2_mmu_info.c b/drivers/video/rockchip/rga2/rga2_mmu_info.c index f5d842684e0b..cfc4940ee681 100644 --- a/drivers/video/rockchip/rga2/rga2_mmu_info.c +++ b/drivers/video/rockchip/rga2/rga2_mmu_info.c @@ -268,6 +268,32 @@ static int rga2_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, uns end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; pageCount = end - start; break; + case RGA2_FORMAT_YVYU_422: + case RGA2_FORMAT_VYUY_422: + case RGA2_FORMAT_YUYV_422: + case RGA2_FORMAT_UYVY_422: + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = stride * h; + start = MIN(yrgb_addr, uv_addr); + start >>= PAGE_SHIFT; + end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RGA2_FORMAT_YVYU_420: + case RGA2_FORMAT_VYUY_420: + case RGA2_FORMAT_YUYV_420: + case RGA2_FORMAT_UYVY_420: + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = (stride * (h >> 1)); + start = MIN(yrgb_addr, uv_addr); + start >>= PAGE_SHIFT; + end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; #if 0 case RK_FORMAT_BPP1 : break; diff --git a/drivers/video/rockchip/rga2/rga2_reg_info.c b/drivers/video/rockchip/rga2/rga2_reg_info.c index 848b7c2ac963..992ae45fae23 100644 --- a/drivers/video/rockchip/rga2/rga2_reg_info.c +++ b/drivers/video/rockchip/rga2/rga2_reg_info.c @@ -393,6 +393,15 @@ static void RGA2_set_reg_dst_info(u8 *base, struct rga2_req *msg) case RGA2_FORMAT_YCrCb_422_P : dst_format = 0x9; dst_cbcr_swp = 1; x_div = 2; y_div = 1; break; case RGA2_FORMAT_YCrCb_420_SP : dst_format = 0xa; dst_cbcr_swp = 1; x_div = 1; y_div = 2; break; case RGA2_FORMAT_YCrCb_420_P : dst_format = 0xb; dst_cbcr_swp = 1; x_div = 2; y_div = 2; break; + + case RGA2_FORMAT_YUYV_422 : dst_format = 0xc; dpw = 2; break; + case RGA2_FORMAT_YVYU_422 : dst_format = 0xc; dpw = 2; dst_cbcr_swp = 1; break; + case RGA2_FORMAT_YUYV_420 : dst_format = 0xd; dpw = 2; break; + case RGA2_FORMAT_YVYU_420 : dst_format = 0xd; dpw = 2; dst_cbcr_swp = 1; break; + case RGA2_FORMAT_UYVY_422 : dst_format = 0xe; dpw = 2; break; + case RGA2_FORMAT_VYUY_422 : dst_format = 0xe; dpw = 2; dst_cbcr_swp = 1; break; + case RGA2_FORMAT_UYVY_420 : dst_format = 0xf; dpw = 2; break; + case RGA2_FORMAT_VYUY_420 : dst_format = 0xf; dpw = 2; dst_cbcr_swp = 1; break; }; reg = ((reg & (~m_RGA2_DST_INFO_SW_DST_FMT)) | (s_RGA2_DST_INFO_SW_DST_FMT(dst_format))); @@ -447,19 +456,48 @@ static void RGA2_set_reg_dst_info(u8 *base, struct rga2_req *msg) y_lt_addr = yrgb_addr; u_lt_addr = u_addr; v_lt_addr = v_addr; - - y_ld_addr = yrgb_addr + (msg->dst.act_h - 1) * (d_stride); - u_ld_addr = u_addr + ((msg->dst.act_h / y_div) - 1) * (d_uv_stride); - v_ld_addr = v_addr + ((msg->dst.act_h / y_div) - 1) * (d_uv_stride); - - y_rt_addr = yrgb_addr + (msg->dst.act_w - 1) * dpw; - u_rt_addr = u_addr + (msg->dst.act_w / x_div) - 1; - v_rt_addr = v_addr + (msg->dst.act_w / x_div) - 1; - - y_rd_addr = y_ld_addr + (msg->dst.act_w - 1) * dpw; - u_rd_addr = u_ld_addr + (msg->dst.act_w / x_div) - 1; - v_rd_addr = v_ld_addr + (msg->dst.act_w / x_div) - 1; - + + if (msg->dst.format < 0x18) { + /* 270 degree & Mirror V*/ + y_ld_addr = yrgb_addr + (msg->dst.act_h - 1) * (d_stride); + u_ld_addr = u_addr + ((msg->dst.act_h / y_div) - 1) * (d_uv_stride); + v_ld_addr = v_addr + ((msg->dst.act_h / y_div) - 1) * (d_uv_stride); + /* 90 degree & Mirror H */ + y_rt_addr = yrgb_addr + (msg->dst.act_w - 1) * dpw; + u_rt_addr = u_addr + (msg->dst.act_w / x_div) - 1; + v_rt_addr = v_addr + (msg->dst.act_w / x_div) - 1; + /* 180 degree */ + y_rd_addr = y_ld_addr + (msg->dst.act_w - 1) * dpw; + u_rd_addr = u_ld_addr + (msg->dst.act_w / x_div) - 1; + v_rd_addr = v_ld_addr + (msg->dst.act_w / x_div) - 1; + } else { + if (msg->dst.format == RGA2_FORMAT_YUYV_422 || + msg->dst.format == RGA2_FORMAT_YVYU_422 || + msg->dst.format == RGA2_FORMAT_UYVY_422 || + msg->dst.format == RGA2_FORMAT_VYUY_422) { + y_ld_addr = yrgb_addr + (msg->dst.act_h - 1) * (d_stride); + y_rt_addr = yrgb_addr + (msg->dst.act_w * 2 - 1); + y_rd_addr = y_ld_addr + (msg->dst.act_w * 2 - 1); + u_ld_addr = 0; + u_rt_addr = 0; + u_rd_addr = 0; + v_ld_addr = 0; + v_rt_addr = 0; + v_rd_addr = 0; + } else { + y_ld_addr = (RK_U32)msg->dst.yrgb_addr + + ((msg->dst.y_offset + (msg->dst.act_h -1)) * d_stride) + + msg->dst.x_offset; + y_rt_addr = yrgb_addr + (msg->dst.act_w * 2 - 1); + y_rd_addr = y_ld_addr + (msg->dst.act_w - 1); + u_ld_addr = 0; + u_rt_addr = 0; + u_rd_addr = 0; + v_ld_addr = 0; + v_rt_addr = 0; + v_rd_addr = 0; + } + } if(rot_90_flag == 0) { if(y_mirr == 1) @@ -560,7 +598,10 @@ static void RGA2_set_reg_dst_info(u8 *base, struct rga2_req *msg) *bRGA_DST_BASE1 = (RK_U32)u_addr; *bRGA_DST_BASE2 = (RK_U32)v_addr; } - + + if (msg->dst.format >= 0x18) { + *bRGA_DST_BASE1 = msg->dst.x_offset; + } *bRGA_SRC_BASE3 = (RK_U32)s_y_lt_addr; } @@ -955,9 +996,19 @@ static void format_name_convert(uint32_t *df, uint32_t sf) case 0xd: *df = RGA2_FORMAT_YCrCb_422_P; break; case 0xe: *df = RGA2_FORMAT_YCrCb_420_SP; break; case 0xf: *df = RGA2_FORMAT_YCrCb_420_P; break; - + + case 0x18: *df = RGA2_FORMAT_YVYU_422; break; + case 0x19: *df = RGA2_FORMAT_YVYU_420; break; + case 0x1a: *df = RGA2_FORMAT_VYUY_422; break; + case 0x1b: *df = RGA2_FORMAT_VYUY_420; break; + case 0x1c: *df = RGA2_FORMAT_YUYV_422; break; + case 0x1d: *df = RGA2_FORMAT_YUYV_420; break; + case 0x1e: *df = RGA2_FORMAT_UYVY_422; break; + case 0x1f: *df = RGA2_FORMAT_UYVY_420; break; + case 0x20:*df = RGA2_FORMAT_YCbCr_420_SP_10B; break; case 0x21:*df = RGA2_FORMAT_YCrCb_420_SP_10B; break; + } }