mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
video/rockchip: rga2: add YUV packet format support
Change-Id: I3b002b1bc0f06a1480936a66a90e8545402bdb84 Signed-off-by: Li Huang <putin.li@rock-chips.com>
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user