rockchip/rga: add rga support yuv 10 bit

Change-Id: Id7bd3ea75831b671f9739337c457f59c38fde4c3
Signed-off-by: Zhiqin Wei <wzq@rock-chips.com>
This commit is contained in:
Zhiqin Wei
2016-06-12 18:17:47 +08:00
committed by Gerrit Code Review
parent d0caa4e9aa
commit 51e65247a4
6 changed files with 167 additions and 73 deletions

View File

@@ -112,6 +112,8 @@ enum
RK_FORMAT_BPP2 = 0x11,
RK_FORMAT_BPP4 = 0x12,
RK_FORMAT_BPP8 = 0x13,
RK_FORMAT_YCbCr_420_SP_10B = 0x20,
RK_FORMAT_YCrCb_420_SP_10B = 0x21,
};

View File

@@ -95,6 +95,10 @@ enum
RGA2_FORMAT_YCrCb_422_P = 0x15,
RGA2_FORMAT_YCrCb_420_SP = 0x16,
RGA2_FORMAT_YCrCb_420_P = 0x17,
RGA2_FORMAT_YCbCr_420_SP_10B = 0x20,
RGA2_FORMAT_YCrCb_420_SP_10B = 0x21,
RGA2_FORMAT_YCbCr_422_SP_10B = 0x22,
RGA2_FORMAT_YCrCb_422_SP_10B = 0x23,
};
typedef struct mdp_img

View File

@@ -602,91 +602,116 @@ static int rga2_convert_dma_buf(struct rga2_req *req)
ion_phys_addr_t phy_addr;
size_t len;
int ret;
uint32_t src_vir_w, dst_vir_w;
src_vir_w = req->src.vir_w;
dst_vir_w = req->dst.vir_w;
req->sg_src0 = NULL;
req->sg_src1 = NULL;
req->sg_dst = NULL;
req->sg_els = NULL;
if((int)req->src.yrgb_addr > 0) {
hdl = ion_import_dma_buf(rga2_drvdata->ion_client, req->src.yrgb_addr);
if ((int)req->src.yrgb_addr > 0) {
hdl = ion_import_dma_buf(rga2_drvdata->ion_client,
req->src.yrgb_addr);
if (IS_ERR(hdl)) {
ret = PTR_ERR(hdl);
printk("RGA2 SRC ERROR ion buf handle\n");
return ret;
}
if (req->mmu_info.src0_mmu_flag) {
req->sg_src0 = ion_sg_table(rga2_drvdata->ion_client, hdl);
req->sg_src0 = ion_sg_table(rga2_drvdata->ion_client,
hdl);
req->src.yrgb_addr = req->src.uv_addr;
req->src.uv_addr = req->src.yrgb_addr + (req->src.vir_w * req->src.vir_h);
req->src.v_addr = req->src.uv_addr + (req->src.vir_w * req->src.vir_h)/4;
}
else {
ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr, &len);
req->src.uv_addr = req->src.yrgb_addr
+ (src_vir_w * req->src.vir_h);
req->src.v_addr = req->src.uv_addr
+ (src_vir_w * req->src.vir_h) / 4;
} else {
ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr,
&len);
req->src.yrgb_addr = phy_addr;
req->src.uv_addr = req->src.yrgb_addr + (req->src.vir_w * req->src.vir_h);
req->src.v_addr = req->src.uv_addr + (req->src.vir_w * req->src.vir_h)/4;
req->src.uv_addr = req->src.yrgb_addr
+ (src_vir_w * req->src.vir_h);
req->src.v_addr = req->src.uv_addr
+ (src_vir_w * req->src.vir_h) / 4;
}
ion_free(rga2_drvdata->ion_client, hdl);
}
else {
} else {
req->src.yrgb_addr = req->src.uv_addr;
req->src.uv_addr = req->src.yrgb_addr + (req->src.vir_w * req->src.vir_h);
req->src.v_addr = req->src.uv_addr + (req->src.vir_w * req->src.vir_h)/4;
req->src.uv_addr = req->src.yrgb_addr
+ (src_vir_w * req->src.vir_h);
req->src.v_addr = req->src.uv_addr
+ (src_vir_w * req->src.vir_h) / 4;
}
if((int)req->dst.yrgb_addr > 0) {
hdl = ion_import_dma_buf(rga2_drvdata->ion_client, req->dst.yrgb_addr);
if ((int)req->dst.yrgb_addr > 0) {
hdl = ion_import_dma_buf(rga2_drvdata->ion_client,
req->dst.yrgb_addr);
if (IS_ERR(hdl)) {
ret = PTR_ERR(hdl);
printk("RGA2 DST ERROR ion buf handle\n");
return ret;
}
if (req->mmu_info.dst_mmu_flag) {
req->sg_dst = ion_sg_table(rga2_drvdata->ion_client, hdl);
req->sg_dst = ion_sg_table(rga2_drvdata->ion_client,
hdl);
req->dst.yrgb_addr = req->dst.uv_addr;
req->dst.uv_addr = req->dst.yrgb_addr + (req->dst.vir_w * req->dst.vir_h);
req->dst.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h)/4;
}
else {
ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr, &len);
req->dst.uv_addr = req->dst.yrgb_addr
+ (dst_vir_w * req->dst.vir_h);
req->dst.v_addr = req->dst.uv_addr
+ (dst_vir_w * req->dst.vir_h) / 4;
} else {
ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr,
&len);
req->dst.yrgb_addr = phy_addr;
req->dst.uv_addr = req->dst.yrgb_addr + (req->dst.vir_w * req->dst.vir_h);
req->dst.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h)/4;
req->dst.uv_addr = req->dst.yrgb_addr
+ (dst_vir_w * req->dst.vir_h);
req->dst.v_addr = req->dst.uv_addr
+ (dst_vir_w * req->dst.vir_h) / 4;
}
ion_free(rga2_drvdata->ion_client, hdl);
}
else {
} else {
req->dst.yrgb_addr = req->dst.uv_addr;
req->dst.uv_addr = req->dst.yrgb_addr + (req->dst.vir_w * req->dst.vir_h);
req->dst.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h)/4;
req->dst.uv_addr = req->dst.yrgb_addr
+ (dst_vir_w * req->dst.vir_h);
req->dst.v_addr = req->dst.uv_addr
+ (dst_vir_w * req->dst.vir_h) / 4;
}
if((int)req->src1.yrgb_addr > 0) {
hdl = ion_import_dma_buf(rga2_drvdata->ion_client, req->src1.yrgb_addr);
if ((int)req->src1.yrgb_addr > 0) {
hdl = ion_import_dma_buf(rga2_drvdata->ion_client,
req->src1.yrgb_addr);
if (IS_ERR(hdl)) {
ret = PTR_ERR(hdl);
printk("RGA2 ERROR ion buf handle\n");
return ret;
}
if (req->mmu_info.dst_mmu_flag) {
req->sg_src1 = ion_sg_table(rga2_drvdata->ion_client, hdl);
req->src1.yrgb_addr = 0;
req->src1.uv_addr = req->dst.yrgb_addr + (req->dst.vir_w * req->dst.vir_h);
req->src1.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h)/4;
}
else {
ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr, &len);
req->sg_src1 = ion_sg_table(rga2_drvdata->ion_client,
hdl);
req->src1.yrgb_addr = req->src1.uv_addr;
req->src1.uv_addr = req->src1.yrgb_addr
+ (req->src1.vir_w * req->src1.vir_h);
req->src1.v_addr = req->src1.uv_addr
+ (req->src1.vir_w * req->src1.vir_h) / 4;
} else {
ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr,
&len);
req->src1.yrgb_addr = phy_addr;
req->src1.uv_addr = req->dst.yrgb_addr + (req->dst.vir_w * req->dst.vir_h);
req->src1.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h)/4;
req->src1.uv_addr = req->src1.yrgb_addr
+ (req->src1.vir_w * req->src1.vir_h);
req->src1.v_addr = req->src1.uv_addr
+ (req->src1.vir_w * req->src1.vir_h) / 4;
}
ion_free(rga2_drvdata->ion_client, hdl);
}
else {
req->src1.yrgb_addr = req->dst.uv_addr;
req->src1.uv_addr = req->dst.yrgb_addr + (req->dst.vir_w * req->dst.vir_h);
req->src1.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h)/4;
} else {
req->src1.yrgb_addr = req->src1.uv_addr;
req->src1.uv_addr = req->src1.yrgb_addr
+ (req->src1.vir_w * req->src1.vir_h);
req->src1.v_addr = req->src1.uv_addr
+ (req->src1.vir_w * req->src1.vir_h) / 4;
}
return 0;
@@ -1320,8 +1345,8 @@ static int __init rga2_init(void)
rga2_mmu_buf.pages = kmalloc(32768 * sizeof(struct page *), GFP_KERNEL);
if ((ret = platform_driver_register(&rga2_driver)) != 0)
{
ret = platform_driver_register(&rga2_driver);
if (ret != 0) {
printk(KERN_ERR "Platform device register failed (%d).\n", ret);
return ret;
}
@@ -1369,8 +1394,6 @@ void rga2_test_0(void)
struct rga2_req req;
rga2_session session;
unsigned int *src, *dst;
uint32_t i, j;
uint32_t *dst0;
session.pid = current->pid;
INIT_LIST_HEAD(&session.waiting);
@@ -1381,9 +1404,6 @@ void rga2_test_0(void)
list_add_tail(&session.list_session, &rga2_service.session);
atomic_set(&session.task_running, 0);
atomic_set(&session.num_done, 0);
//file->private_data = (void *)session;
//fb = rk_get_fb(0);
memset(&req, 0, sizeof(struct rga2_req));
src = kmalloc(800*480*4, GFP_KERNEL);
@@ -1393,22 +1413,18 @@ void rga2_test_0(void)
printk("************ RGA2_TEST ************\n");
printk("********************************\n\n");
memset(src, 0x80, 800*480*4);
memset(dst, 0x0, 800*480*4);
//dmac_flush_range(&src, &src[800*480*4]);
//outer_flush_range(virt_to_phys(&src),virt_to_phys(&src[800*480*4]));
#if 1
memset(src, 0x80, 800 * 480 * 4);
memset(dst, 0xcc, 800 * 480 * 4);
#endif
#if 0
memset(src_buf, 0x80, 800*480*4);
memset(dst_buf, 0xcc, 800*480*4);
dmac_flush_range(src, &src[800 * 480]);
outer_flush_range(virt_to_phys(src), virt_to_phys(&src[800 * 480]));
dmac_flush_range(&dst_buf[0], &dst_buf[800*480]);
outer_flush_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[800*480]));
dmac_flush_range(dst, &dst[800 * 480]);
outer_flush_range(virt_to_phys(dst), virt_to_phys(&dst[800 * 480]));
#endif
dst0 = (uint32_t *)&dst;
i = j = 0;
#if 0
req.pat.act_w = 16;
req.pat.act_h = 16;
@@ -1418,16 +1434,39 @@ void rga2_test_0(void)
req.render_mode = 0;
rga2_blit_sync(&session, &req);
#endif
{
uint32_t i, j;
uint8_t *sp;
req.src.act_w = 320;
sp = (uint8_t *)src;
for (j = 0; j < 240; j++) {
sp = (uint8_t *)src + j * 320 * 10 / 8;
for (i = 0; i < 320; i++) {
if ((i & 3) == 0) {
sp[i * 5 / 4] = 0;
sp[i * 5 / 4+1] = 0x1;
} else if ((i & 3) == 1) {
sp[i * 5 / 4+1] = 0x4;
} else if ((i & 3) == 2) {
sp[i * 5 / 4+1] = 0x10;
} else if ((i & 3) == 3) {
sp[i * 5 / 4+1] = 0x40;
}
}
}
sp = (uint8_t *)src;
for (j = 0; j < 100; j++)
printk("src %.2x\n", sp[j]);
}
req.src.act_w = 320;
req.src.act_h = 240;
req.src.vir_w = 320;
req.src.vir_w = 320;
req.src.vir_h = 240;
req.src.yrgb_addr = 0;//(uint32_t)virt_to_phys(src);
req.src.uv_addr = (unsigned long)virt_to_phys(src);
req.src.v_addr = 0;
req.src.format = RGA2_FORMAT_RGBA_8888;
req.src.format = RGA2_FORMAT_YCbCr_420_SP_10B;
req.dst.act_w = 320;
req.dst.act_h = 240;
@@ -1439,7 +1478,7 @@ void rga2_test_0(void)
req.dst.yrgb_addr = 0;//((uint32_t)virt_to_phys(dst));
req.dst.uv_addr = (unsigned long)virt_to_phys(dst);
req.dst.format = RGA2_FORMAT_RGBA_8888;
req.dst.format = RGA2_FORMAT_YCbCr_420_SP;
//dst = dst0;
@@ -1449,6 +1488,7 @@ void rga2_test_0(void)
req.rotate_mode = 0;
req.scale_bicu_mode = 2;
#if 0
//req.alpha_rop_flag = 0;
//req.alpha_rop_mode = 0x19;
//req.PD_mode = 3;
@@ -1459,12 +1499,28 @@ void rga2_test_0(void)
//printk("src = %.8x\n", req.src.yrgb_addr);
//printk("src = %.8x\n", req.src.uv_addr);
//printk("dst = %.8x\n", req.dst.yrgb_addr);
#endif
rga2_blit_sync(&session, &req);
for(j=0; j<100; j++) {
printk("%.8x\n", dst[j]);
#if 0
uint32_t j;
for (j = 0; j < 320 * 240 * 10 / 8; j++) {
if (src[j] != dst[j])
printk("error value dst not equal src j %d, s %.2x d %.2x\n",
j, src[j], dst[j]);
}
#endif
#if 1
{
uint32_t j;
uint8_t *dp = (uint8_t *)dst;
for (j = 0; j < 100; j++)
printk("%d %.2x\n", j, dp[j]);
}
#endif
if(src)
kfree(src);

View File

@@ -222,6 +222,18 @@ static int rga2_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, uns
case RK_FORMAT_BPP8 :
break;
#endif
case RGA2_FORMAT_YCbCr_420_SP_10B:
case RGA2_FORMAT_YCrCb_420_SP_10B:
stride = (w + 3) & (~3);
stride = stride;
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;
default :
pageCount = 0;
start = 0;

View File

@@ -171,6 +171,7 @@ RGA2_set_reg_src_info(RK_U8 *base, struct rga2_req *msg)
RK_U32 uv_stride = 0;
RK_U32 mask_stride = 0;
RK_U32 ydiv = 1, xdiv = 2;
RK_U8 yuv10 = 0;
RK_U32 sw, sh;
RK_U32 dw, dh;
@@ -191,6 +192,14 @@ RGA2_set_reg_src_info(RK_U8 *base, struct rga2_req *msg)
bRGA_SRC_TR_COLOR0 = (RK_U32 *)(base + RGA2_SRC_TR_COLOR0_OFFSET);
bRGA_SRC_TR_COLOR1 = (RK_U32 *)(base + RGA2_SRC_TR_COLOR1_OFFSET);
if (msg->src.format == RGA2_FORMAT_YCbCr_420_SP_10B ||
msg->src.format == RGA2_FORMAT_YCrCb_420_SP_10B) {
if ((msg->src.act_w == msg->dst.act_w) &&
(msg->src.act_h == msg->dst.act_h) &&
(msg->rotate_mode == 0))
msg->rotate_mode = 1 << 6;
}
{
rotate_mode = msg->rotate_mode & 0x3;
@@ -252,6 +261,8 @@ RGA2_set_reg_src_info(RK_U8 *base, struct rga2_req *msg)
case RGA2_FORMAT_YCrCb_422_P : src0_format = 0x9; xdiv = 2; ydiv = 1; src0_cbcr_swp = 1; break;
case RGA2_FORMAT_YCrCb_420_SP : src0_format = 0xa; xdiv = 1; ydiv = 2; src0_cbcr_swp = 1; break;
case RGA2_FORMAT_YCrCb_420_P : src0_format = 0xb; xdiv = 2; ydiv = 2; src0_cbcr_swp = 1; break;
case RGA2_FORMAT_YCbCr_420_SP_10B : src0_format = 0xa; xdiv = 1; ydiv = 2; yuv10 = 1; break;
case RGA2_FORMAT_YCrCb_420_SP_10B : src0_format = 0xa; xdiv = 1; ydiv = 2; src0_cbcr_swp = 1; yuv10 = 1; break;
};
reg = ((reg & (~m_RGA2_SRC_INFO_SW_SRC_FMT)) | (s_RGA2_SRC_INFO_SW_SRC_FMT(src0_format)));
@@ -275,10 +286,11 @@ RGA2_set_reg_src_info(RK_U8 *base, struct rga2_req *msg)
reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_TRANS_E)) | (s_RGA2_SRC_INFO_SW_SW_SRC_TRANS_E(msg->src_trans_mode >> 1)));
reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_DITHER_UP_E)) | (s_RGA2_SRC_INFO_SW_SW_SRC_DITHER_UP_E((msg->alpha_rop_flag >> 4) & 0x1)));
reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_VSP_MODE_SEL)) | (s_RGA2_SRC_INFO_SW_SW_VSP_MODE_SEL((msg->scale_bicu_mode>>4))));
reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_YUV10_E)) | (s_RGA2_SRC_INFO_SW_SW_YUV10_E((yuv10))));
reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_YUV10_ROUND_E)) | (s_RGA2_SRC_INFO_SW_SW_YUV10_ROUND_E((yuv10))));
RGA2_reg_get_param(base, msg);
stride = (((msg->src.vir_w * pixel_width) + 3) & ~3) >> 2;
uv_stride = ((msg->src.vir_w / xdiv + 3) & ~3);
*bRGA_SRC_BASE0 = (RK_U32)(msg->src.yrgb_addr + msg->src.y_offset * (stride<<2) + msg->src.x_offset * pixel_width);
@@ -961,6 +973,9 @@ 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 0x20:*df = RGA2_FORMAT_YCbCr_420_SP_10B; break;
case 0x21:*df = RGA2_FORMAT_YCrCb_420_SP_10B; break;
}
}
@@ -1014,12 +1029,12 @@ void RGA_MSG_2_RGA2_MSG(struct rga_req *req_rga, struct rga2_req *req)
else if (req_rga->rotate_mode == 2)
{
//x_mirror
req->rotate_mode = (1 << 4);
req->rotate_mode |= (1 << 4);
}
else if (req_rga->rotate_mode == 3)
{
//y_mirror
req->rotate_mode = (2 << 4);
req->rotate_mode |= (2 << 4);
}
else {
req->rotate_mode = 0;

View File

@@ -86,6 +86,10 @@
#define m_RGA2_SRC_INFO_SW_SW_SRC_DITHER_UP_E ( 0x1<<23 )
#define m_RGA2_SRC_INFO_SW_SW_SRC_SCL_FILTER ( 0x3<<24 )
#define m_RGA2_SRC_INFO_SW_SW_VSP_MODE_SEL ( 0x1<<26 )
#define m_RGA2_SRC_INFO_SW_SW_YUV10_E ( 0x1<<27 )
#define m_RGA2_SRC_INFO_SW_SW_YUV10_ROUND_E ( 0x1<<28 )
@@ -105,7 +109,8 @@
#define s_RGA2_SRC_INFO_SW_SW_SRC_DITHER_UP_E(x) ( (x&0x1)<<23 )
#define s_RGA2_SRC_INFO_SW_SW_SRC_SCL_FILTER(x) ( (x&0x3)<<24 )
#define s_RGA2_SRC_INFO_SW_SW_VSP_MODE_SEL(x) ( (x&0x1)<<26 )
#define s_RGA2_SRC_INFO_SW_SW_YUV10_E(x) ( (x&0x1)<<27 )
#define s_RGA2_SRC_INFO_SW_SW_YUV10_ROUND_E(x) ( (x&0x1)<<28 )
/* RGA_SRC_VIR_INFO */
#define m_RGA2_SRC_VIR_INFO_SW_SRC_VIR_STRIDE ( 0x7fff<<0 ) //modify