mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
video/rockchip: rga2: Optimize the process of mapping dma.
Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com> Change-Id: Ie8d140d8fc102c9a3677b266ac7848c4c3ade78e
This commit is contained in:
@@ -337,6 +337,18 @@ typedef struct rga_img_info_32_t
|
||||
}
|
||||
rga_img_info_32_t;
|
||||
|
||||
struct rga_dma_buffer_t {
|
||||
/* DMABUF information */
|
||||
struct dma_buf *dma_buf;
|
||||
struct dma_buf_attachment *attach;
|
||||
struct sg_table *sgt;
|
||||
|
||||
dma_addr_t iova;
|
||||
unsigned long size;
|
||||
void *vaddr;
|
||||
enum dma_data_direction dir;
|
||||
};
|
||||
|
||||
struct rga_req {
|
||||
uint8_t render_mode; /* (enum) process mode sel */
|
||||
|
||||
@@ -578,14 +590,6 @@ struct rga2_req
|
||||
u8 rgb2yuv_mode;
|
||||
|
||||
u8 buf_type;
|
||||
struct sg_table *sg_src0;
|
||||
struct sg_table *sg_src1;
|
||||
struct sg_table *sg_dst;
|
||||
struct sg_table *sg_els;
|
||||
struct dma_buf_attachment *attach_src0;
|
||||
struct dma_buf_attachment *attach_src1;
|
||||
struct dma_buf_attachment *attach_dst;
|
||||
struct dma_buf_attachment *attach_els;
|
||||
};
|
||||
|
||||
struct rga2_mmu_buf_t {
|
||||
@@ -726,15 +730,10 @@ struct rga2_reg {
|
||||
uint32_t MMU_len;
|
||||
bool MMU_map;
|
||||
|
||||
struct sg_table *sg_src0;
|
||||
struct sg_table *sg_src1;
|
||||
struct sg_table *sg_dst;
|
||||
struct sg_table *sg_els;
|
||||
|
||||
struct dma_buf_attachment *attach_src0;
|
||||
struct dma_buf_attachment *attach_src1;
|
||||
struct dma_buf_attachment *attach_dst;
|
||||
struct dma_buf_attachment *attach_els;
|
||||
struct rga_dma_buffer_t dma_buffer_src0;
|
||||
struct rga_dma_buffer_t dma_buffer_src1;
|
||||
struct rga_dma_buffer_t dma_buffer_dst;
|
||||
struct rga_dma_buffer_t dma_buffer_els;
|
||||
};
|
||||
|
||||
struct rga2_service_info {
|
||||
|
||||
@@ -367,71 +367,6 @@ static int rga2_align_check(struct rga2_req *req)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga2_memory_check(void *vaddr, u32 w, u32 h, u32 format, int fd)
|
||||
{
|
||||
int bits = 32;
|
||||
int temp_data = 0;
|
||||
void *one_line = kzalloc(w * 4, GFP_KERNEL);
|
||||
|
||||
if (!one_line) {
|
||||
ERR("kzalloc fail %s[%d]\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
switch (format) {
|
||||
case RGA2_FORMAT_RGBA_8888:
|
||||
case RGA2_FORMAT_RGBX_8888:
|
||||
case RGA2_FORMAT_BGRA_8888:
|
||||
case RGA2_FORMAT_BGRX_8888:
|
||||
bits = 32;
|
||||
break;
|
||||
case RGA2_FORMAT_RGB_888:
|
||||
case RGA2_FORMAT_BGR_888:
|
||||
bits = 24;
|
||||
break;
|
||||
case RGA2_FORMAT_RGB_565:
|
||||
case RGA2_FORMAT_RGBA_5551:
|
||||
case RGA2_FORMAT_RGBA_4444:
|
||||
case RGA2_FORMAT_BGR_565:
|
||||
case RGA2_FORMAT_YCbCr_422_SP:
|
||||
case RGA2_FORMAT_YCbCr_422_P:
|
||||
case RGA2_FORMAT_YCrCb_422_SP:
|
||||
case RGA2_FORMAT_YCrCb_422_P:
|
||||
case RGA2_FORMAT_BGRA_5551:
|
||||
case RGA2_FORMAT_BGRA_4444:
|
||||
bits = 16;
|
||||
break;
|
||||
case RGA2_FORMAT_YCbCr_420_SP:
|
||||
case RGA2_FORMAT_YCbCr_420_P:
|
||||
case RGA2_FORMAT_YCrCb_420_SP:
|
||||
case RGA2_FORMAT_YCrCb_420_P:
|
||||
bits = 12;
|
||||
break;
|
||||
case RGA2_FORMAT_YCbCr_420_SP_10B:
|
||||
case RGA2_FORMAT_YCrCb_420_SP_10B:
|
||||
case RGA2_FORMAT_YCbCr_422_SP_10B:
|
||||
case RGA2_FORMAT_YCrCb_422_SP_10B:
|
||||
bits = 15;
|
||||
break;
|
||||
default:
|
||||
INFO("un know format\n");
|
||||
kfree(one_line);
|
||||
return -1;
|
||||
}
|
||||
temp_data = w * (h - 1) * bits >> 3;
|
||||
if (fd > 0) {
|
||||
INFO("vaddr is%p, bits is %d, fd check\n", vaddr, bits);
|
||||
memcpy(one_line, (char *)vaddr + temp_data, w * bits >> 3);
|
||||
INFO("fd check ok\n");
|
||||
} else {
|
||||
INFO("vir addr memory check.\n");
|
||||
memcpy((void *)((char *)vaddr + temp_data), one_line,
|
||||
w * bits >> 3);
|
||||
INFO("vir addr check ok.\n");
|
||||
}
|
||||
kfree(one_line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rga2_scale_check(struct rga2_req *req)
|
||||
{
|
||||
u32 saw, sah, daw, dah;
|
||||
@@ -486,19 +421,6 @@ static void rga2_printf_cmd_buf(u32 *cmd_buf)
|
||||
dst_aw, dst_ah, dst_stride, dst_format);
|
||||
}
|
||||
|
||||
static bool is_yuv422p_format(u32 format)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
switch (format) {
|
||||
case RGA2_FORMAT_YCbCr_422_P:
|
||||
case RGA2_FORMAT_YCrCb_422_P:
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void rga2_write(u32 b, u32 r)
|
||||
{
|
||||
*((volatile unsigned int *)(rga2_drvdata->rga_base + r)) = b;
|
||||
@@ -843,6 +765,14 @@ static struct rga2_reg * rga2_reg_init(rga2_session *session, struct rga2_req *r
|
||||
INIT_LIST_HEAD(®->session_link);
|
||||
INIT_LIST_HEAD(®->status_link);
|
||||
|
||||
ret = rga2_get_dma_info(reg, req);
|
||||
if (ret < 0) {
|
||||
pr_err("fail to get dma buffer info!\n");
|
||||
free_page((unsigned long)reg);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((req->mmu_info.src0_mmu_flag & 1) || (req->mmu_info.src1_mmu_flag & 1)
|
||||
|| (req->mmu_info.dst_mmu_flag & 1) || (req->mmu_info.els_mmu_flag & 1))
|
||||
{
|
||||
@@ -861,16 +791,6 @@ static struct rga2_reg * rga2_reg_init(rga2_session *session, struct rga2_req *r
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
reg->sg_src0 = req->sg_src0;
|
||||
reg->sg_dst = req->sg_dst;
|
||||
reg->sg_src1 = req->sg_src1;
|
||||
reg->sg_els = req->sg_els;
|
||||
reg->attach_src0 = req->attach_src0;
|
||||
reg->attach_dst = req->attach_dst;
|
||||
reg->attach_src1 = req->attach_src1;
|
||||
reg->attach_els = req->attach_els;
|
||||
#endif
|
||||
|
||||
mutex_lock(&rga2_service.lock);
|
||||
list_add_tail(®->status_link, &rga2_service.waiting);
|
||||
@@ -1009,59 +929,6 @@ static void rga2_try_set_reg(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
static int rga2_put_dma_buf(struct rga2_req *req, struct rga2_reg *reg)
|
||||
{
|
||||
struct dma_buf_attachment *attach = NULL;
|
||||
struct sg_table *sgt = NULL;
|
||||
struct dma_buf *dma_buf = NULL;
|
||||
|
||||
if (!req && !reg)
|
||||
return -EINVAL;
|
||||
|
||||
attach = reg ? reg->attach_src0 : req->attach_src0;
|
||||
sgt = reg ? reg->sg_src0 : req->sg_src0;
|
||||
if (attach && sgt)
|
||||
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
|
||||
if (attach) {
|
||||
dma_buf = attach->dmabuf;
|
||||
dma_buf_detach(dma_buf, attach);
|
||||
dma_buf_put(dma_buf);
|
||||
}
|
||||
|
||||
attach = reg ? reg->attach_dst : req->attach_dst;
|
||||
sgt = reg ? reg->sg_dst : req->sg_dst;
|
||||
if (attach && sgt)
|
||||
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
|
||||
if (attach) {
|
||||
dma_buf = attach->dmabuf;
|
||||
dma_buf_detach(dma_buf, attach);
|
||||
dma_buf_put(dma_buf);
|
||||
}
|
||||
|
||||
attach = reg ? reg->attach_src1 : req->attach_src1;
|
||||
sgt = reg ? reg->sg_src1 : req->sg_src1;
|
||||
if (attach && sgt)
|
||||
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
|
||||
if (attach) {
|
||||
dma_buf = attach->dmabuf;
|
||||
dma_buf_detach(dma_buf, attach);
|
||||
dma_buf_put(dma_buf);
|
||||
}
|
||||
|
||||
attach = reg ? reg->attach_els : req->attach_els;
|
||||
sgt = reg ? reg->sg_els : req->sg_els;
|
||||
if (attach && sgt)
|
||||
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
|
||||
if (attach) {
|
||||
dma_buf = attach->dmabuf;
|
||||
dma_buf_detach(dma_buf, attach);
|
||||
dma_buf_put(dma_buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void rga2_del_running_list(void)
|
||||
{
|
||||
@@ -1077,9 +944,7 @@ static void rga2_del_running_list(void)
|
||||
else
|
||||
tbuf->back += reg->MMU_len;
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
rga2_put_dma_buf(NULL, reg);
|
||||
#endif
|
||||
rga2_put_dma_info(reg);
|
||||
atomic_sub(1, ®->session->task_running);
|
||||
atomic_sub(1, &rga2_service.total_running);
|
||||
|
||||
@@ -1110,9 +975,7 @@ static void rga2_del_running_list_timeout(void)
|
||||
else
|
||||
tbuf->back += reg->MMU_len;
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
rga2_put_dma_buf(NULL, reg);
|
||||
#endif
|
||||
rga2_put_dma_info(reg);
|
||||
atomic_sub(1, ®->session->task_running);
|
||||
atomic_sub(1, &rga2_service.total_running);
|
||||
rga2_soft_reset();
|
||||
@@ -1124,315 +987,6 @@ static void rga2_del_running_list_timeout(void)
|
||||
}
|
||||
return;
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
static int rga2_get_img_info(rga_img_info_t *img,
|
||||
u8 mmu_flag,
|
||||
struct sg_table **psgt,
|
||||
struct dma_buf_attachment **pattach)
|
||||
{
|
||||
struct dma_buf_attachment *attach = NULL;
|
||||
struct device *rga_dev = NULL;
|
||||
struct sg_table *sgt = NULL;
|
||||
struct dma_buf *dma_buf = NULL;
|
||||
u32 vir_w, vir_h;
|
||||
int yrgb_addr = -1;
|
||||
int ret = 0;
|
||||
|
||||
rga_dev = rga2_drvdata->dev;
|
||||
yrgb_addr = (int)img->yrgb_addr;
|
||||
vir_w = img->vir_w;
|
||||
vir_h = img->vir_h;
|
||||
|
||||
if (yrgb_addr > 0) {
|
||||
dma_buf = dma_buf_get(img->yrgb_addr);
|
||||
if (IS_ERR(dma_buf)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("dma_buf_get fail fd[%d]\n", yrgb_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
attach = dma_buf_attach(dma_buf, rga_dev);
|
||||
if (IS_ERR(attach)) {
|
||||
dma_buf_put(dma_buf);
|
||||
ret = -EINVAL;
|
||||
pr_err("Failed to attach dma_buf\n");
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER
|
||||
if (RGA2_CHECK_MODE) {
|
||||
void *vaddr = dma_buf_vmap(dma_buf);
|
||||
if (vaddr)
|
||||
rga2_memory_check(vaddr, img->vir_w, img->vir_h,
|
||||
img->format, img->yrgb_addr);
|
||||
dma_buf_vunmap(dma_buf, vaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
*pattach = attach;
|
||||
sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
|
||||
if (IS_ERR(sgt)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("Failed to map src attachment\n");
|
||||
goto err_get_sg;
|
||||
}
|
||||
if (!mmu_flag) {
|
||||
ret = -EINVAL;
|
||||
pr_err("Fix it please enable iommu flag\n");
|
||||
goto err_get_sg;
|
||||
}
|
||||
|
||||
if (mmu_flag) {
|
||||
*psgt = sgt;
|
||||
img->yrgb_addr = img->uv_addr;
|
||||
img->uv_addr = img->yrgb_addr + (vir_w * vir_h);
|
||||
if (is_yuv422p_format(img->format))
|
||||
img->v_addr = img->uv_addr + (vir_w * vir_h) / 2;
|
||||
else
|
||||
img->v_addr = img->uv_addr + (vir_w * vir_h) / 4;
|
||||
}
|
||||
} else {
|
||||
img->yrgb_addr = img->uv_addr;
|
||||
img->uv_addr = img->yrgb_addr + (vir_w * vir_h);
|
||||
if (is_yuv422p_format(img->format))
|
||||
img->v_addr = img->uv_addr + (vir_w * vir_h) / 2;
|
||||
else
|
||||
img->v_addr = img->uv_addr + (vir_w * vir_h) / 4;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err_get_sg:
|
||||
if (!IS_ERR(sgt) && sgt)
|
||||
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
|
||||
if (!IS_ERR(attach) && attach) {
|
||||
dma_buf = attach->dmabuf;
|
||||
dma_buf_detach(dma_buf, attach);
|
||||
*pattach = NULL;
|
||||
dma_buf_put(dma_buf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rga2_get_dma_buf(struct rga2_req *req)
|
||||
{
|
||||
struct dma_buf *dma_buf = NULL;
|
||||
u8 mmu_flag = 0;
|
||||
int ret = 0;
|
||||
|
||||
req->sg_src0 = NULL;
|
||||
req->sg_src1 = NULL;
|
||||
req->sg_dst = NULL;
|
||||
req->sg_els = NULL;
|
||||
req->attach_src0 = NULL;
|
||||
req->attach_dst = NULL;
|
||||
req->attach_src1 = NULL;
|
||||
req->attach_els = NULL;
|
||||
mmu_flag = req->mmu_info.src0_mmu_flag;
|
||||
ret = rga2_get_img_info(&req->src, mmu_flag, &req->sg_src0,
|
||||
&req->attach_src0);
|
||||
if (ret) {
|
||||
pr_err("src:rga2_get_img_info fail\n");
|
||||
goto err_src;
|
||||
}
|
||||
|
||||
mmu_flag = req->mmu_info.dst_mmu_flag;
|
||||
ret = rga2_get_img_info(&req->dst, mmu_flag, &req->sg_dst,
|
||||
&req->attach_dst);
|
||||
if (ret) {
|
||||
pr_err("dst:rga2_get_img_info fail\n");
|
||||
goto err_dst;
|
||||
}
|
||||
|
||||
mmu_flag = req->mmu_info.src1_mmu_flag;
|
||||
ret = rga2_get_img_info(&req->src1, mmu_flag, &req->sg_src1,
|
||||
&req->attach_src1);
|
||||
if (ret) {
|
||||
pr_err("src1:rga2_get_img_info fail\n");
|
||||
goto err_src1;
|
||||
}
|
||||
|
||||
mmu_flag = req->mmu_info.els_mmu_flag;
|
||||
ret = rga2_get_img_info(&req->pat, mmu_flag, &req->sg_els,
|
||||
&req->attach_els);
|
||||
if (ret) {
|
||||
pr_err("els:rga2_get_img_info fail\n");
|
||||
goto err_els;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err_els:
|
||||
if (req->sg_src1 && req->attach_src1) {
|
||||
dma_buf_unmap_attachment(req->attach_src1,
|
||||
req->sg_src1, DMA_BIDIRECTIONAL);
|
||||
dma_buf = req->attach_src1->dmabuf;
|
||||
dma_buf_detach(dma_buf, req->attach_src1);
|
||||
dma_buf_put(dma_buf);
|
||||
}
|
||||
err_src1:
|
||||
if (req->sg_dst && req->attach_dst) {
|
||||
dma_buf_unmap_attachment(req->attach_dst,
|
||||
req->sg_dst, DMA_BIDIRECTIONAL);
|
||||
dma_buf = req->attach_dst->dmabuf;
|
||||
dma_buf_detach(dma_buf, req->attach_dst);
|
||||
dma_buf_put(dma_buf);
|
||||
}
|
||||
err_dst:
|
||||
if (req->sg_src0 && req->attach_src0) {
|
||||
dma_buf_unmap_attachment(req->attach_src0,
|
||||
req->sg_src0, DMA_BIDIRECTIONAL);
|
||||
dma_buf = req->attach_src0->dmabuf;
|
||||
dma_buf_detach(dma_buf, req->attach_src0);
|
||||
dma_buf_put(dma_buf);
|
||||
}
|
||||
err_src:
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static int rga2_convert_dma_buf(struct rga2_req *req)
|
||||
{
|
||||
struct ion_handle *hdl;
|
||||
ion_phys_addr_t phy_addr;
|
||||
size_t len;
|
||||
int ret;
|
||||
u32 src_vir_w, dst_vir_w;
|
||||
void *vaddr = NULL;
|
||||
|
||||
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 (IS_ERR(hdl)) {
|
||||
ret = PTR_ERR(hdl);
|
||||
pr_err("RGA2 SRC ERROR ion buf handle\n");
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER
|
||||
if (RGA2_CHECK_MODE) {
|
||||
vaddr = ion_map_kernel(rga2_drvdata->ion_client, hdl);
|
||||
if (vaddr)
|
||||
rga2_memory_check(vaddr, req->src.vir_w, req->src.vir_h,
|
||||
req->src.format, req->src.yrgb_addr);
|
||||
ion_unmap_kernel(rga2_drvdata->ion_client, hdl);
|
||||
}
|
||||
#endif
|
||||
if (req->mmu_info.src0_mmu_flag) {
|
||||
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 + (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 + (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 {
|
||||
req->src.yrgb_addr = req->src.uv_addr;
|
||||
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 (IS_ERR(hdl)) {
|
||||
ret = PTR_ERR(hdl);
|
||||
pr_err("RGA2 DST ERROR ion buf handle\n");
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER
|
||||
if (RGA2_CHECK_MODE) {
|
||||
vaddr = ion_map_kernel(rga2_drvdata->ion_client, hdl);
|
||||
if (vaddr)
|
||||
rga2_memory_check(vaddr, req->dst.vir_w, req->dst.vir_h,
|
||||
req->dst.format, req->dst.yrgb_addr);
|
||||
ion_unmap_kernel(rga2_drvdata->ion_client, hdl);
|
||||
}
|
||||
#endif
|
||||
if (req->mmu_info.dst_mmu_flag) {
|
||||
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 + (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 + (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 {
|
||||
req->dst.yrgb_addr = req->dst.uv_addr;
|
||||
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 (IS_ERR(hdl)) {
|
||||
ret = PTR_ERR(hdl);
|
||||
pr_err("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 = 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->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->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;
|
||||
}
|
||||
if (is_yuv422p_format(req->src.format))
|
||||
req->src.v_addr = req->src.uv_addr + (req->src.vir_w * req->src.vir_h) / 2;
|
||||
if (is_yuv422p_format(req->dst.format))
|
||||
req->dst.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h) / 2;
|
||||
if (is_yuv422p_format(req->src1.format))
|
||||
req->src1.v_addr = req->src1.uv_addr + (req->src1.vir_w * req->dst.vir_h) / 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rga2_blit_flush_cache(rga2_session *session, struct rga2_req *req)
|
||||
{
|
||||
@@ -1446,19 +1000,13 @@ static int rga2_blit_flush_cache(rga2_session *session, struct rga2_req *req)
|
||||
ret = -ENOMEM;
|
||||
goto err_free_reg;
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
if (rga2_get_dma_buf(req)) {
|
||||
pr_err("RGA2 : DMA buf copy error\n");
|
||||
ret = -EFAULT;
|
||||
|
||||
ret = rga2_get_dma_info(reg, req);
|
||||
if (ret < 0) {
|
||||
pr_err("fail to get dma buffer info!\n");
|
||||
goto err_free_reg;
|
||||
}
|
||||
#else
|
||||
if (rga2_convert_dma_buf(req)) {
|
||||
pr_err("RGA2 : DMA buf copy error\n");
|
||||
ret = -EFAULT;
|
||||
goto err_free_reg;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((req->mmu_info.src0_mmu_flag & 1) || (req->mmu_info.src1_mmu_flag & 1) ||
|
||||
(req->mmu_info.dst_mmu_flag & 1) || (req->mmu_info.els_mmu_flag & 1)) {
|
||||
reg->MMU_map = true;
|
||||
@@ -1487,54 +1035,26 @@ static int rga2_blit(rga2_session *session, struct rga2_req *req)
|
||||
int num = 0;
|
||||
struct rga2_reg *reg;
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
if (rga2_get_dma_buf(req)) {
|
||||
pr_err("RGA2 : DMA buf copy error\n");
|
||||
/* check value if legal */
|
||||
ret = rga2_check_param(req);
|
||||
if (ret == -EINVAL) {
|
||||
pr_err("req argument is inval\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
reg = rga2_reg_init(session, req);
|
||||
if (reg == NULL) {
|
||||
pr_err("init reg fail\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
#else
|
||||
if (rga2_convert_dma_buf(req)) {
|
||||
pr_err("RGA2 : DMA buf copy error\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
/* check value if legal */
|
||||
ret = rga2_check_param(req);
|
||||
if(ret == -EINVAL) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
pr_err("req argument is inval\n");
|
||||
goto err_put_dma_buf;
|
||||
#else
|
||||
pr_err("req argument is inval\n");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
reg = rga2_reg_init(session, req);
|
||||
if(reg == NULL) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
pr_err("init reg fail\n");
|
||||
goto err_put_dma_buf;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
num = 1;
|
||||
mutex_lock(&rga2_service.lock);
|
||||
atomic_add(num, &rga2_service.total_running);
|
||||
rga2_try_set_reg();
|
||||
mutex_unlock(&rga2_service.lock);
|
||||
|
||||
num = 1;
|
||||
mutex_lock(&rga2_service.lock);
|
||||
atomic_add(num, &rga2_service.total_running);
|
||||
rga2_try_set_reg();
|
||||
mutex_unlock(&rga2_service.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
while(0);
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
err_put_dma_buf:
|
||||
rga2_put_dma_buf(req, NULL);
|
||||
#endif
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga2_blit_async(rga2_session *session, struct rga2_req *req)
|
||||
|
||||
@@ -19,11 +19,15 @@
|
||||
#include <asm/memory.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))
|
||||
#include <linux/rockchip_ion.h>
|
||||
#endif
|
||||
#include "rga2_mmu_info.h"
|
||||
#include "rga2_debugger.h"
|
||||
|
||||
extern struct rga2_service_info rga2_service;
|
||||
extern struct rga2_mmu_buf_t rga2_mmu_buf;
|
||||
extern struct rga2_drvdata_t *rga2_drvdata;
|
||||
|
||||
//extern int mmu_buff_temp[1024];
|
||||
|
||||
@@ -118,6 +122,431 @@ static unsigned int armv7_va_to_pa(unsigned int v_addr)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool rga2_is_yuv422p_format(u32 format)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
switch (format) {
|
||||
case RGA2_FORMAT_YCbCr_422_P:
|
||||
case RGA2_FORMAT_YCrCb_422_P:
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER
|
||||
static int rga2_memory_check(void *vaddr, u32 w, u32 h, u32 format, int fd)
|
||||
{
|
||||
int bits = 32;
|
||||
int temp_data = 0;
|
||||
void *one_line = kzalloc(w * 4, GFP_KERNEL);
|
||||
|
||||
if (!one_line) {
|
||||
ERR("kzalloc fail %s[%d]\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
switch (format) {
|
||||
case RGA2_FORMAT_RGBA_8888:
|
||||
case RGA2_FORMAT_RGBX_8888:
|
||||
case RGA2_FORMAT_BGRA_8888:
|
||||
case RGA2_FORMAT_BGRX_8888:
|
||||
bits = 32;
|
||||
break;
|
||||
case RGA2_FORMAT_RGB_888:
|
||||
case RGA2_FORMAT_BGR_888:
|
||||
bits = 24;
|
||||
break;
|
||||
case RGA2_FORMAT_RGB_565:
|
||||
case RGA2_FORMAT_RGBA_5551:
|
||||
case RGA2_FORMAT_RGBA_4444:
|
||||
case RGA2_FORMAT_BGR_565:
|
||||
case RGA2_FORMAT_YCbCr_422_SP:
|
||||
case RGA2_FORMAT_YCbCr_422_P:
|
||||
case RGA2_FORMAT_YCrCb_422_SP:
|
||||
case RGA2_FORMAT_YCrCb_422_P:
|
||||
case RGA2_FORMAT_BGRA_5551:
|
||||
case RGA2_FORMAT_BGRA_4444:
|
||||
bits = 16;
|
||||
break;
|
||||
case RGA2_FORMAT_YCbCr_420_SP:
|
||||
case RGA2_FORMAT_YCbCr_420_P:
|
||||
case RGA2_FORMAT_YCrCb_420_SP:
|
||||
case RGA2_FORMAT_YCrCb_420_P:
|
||||
bits = 12;
|
||||
break;
|
||||
case RGA2_FORMAT_YCbCr_420_SP_10B:
|
||||
case RGA2_FORMAT_YCrCb_420_SP_10B:
|
||||
case RGA2_FORMAT_YCbCr_422_SP_10B:
|
||||
case RGA2_FORMAT_YCrCb_422_SP_10B:
|
||||
bits = 15;
|
||||
break;
|
||||
default:
|
||||
INFO("un know format\n");
|
||||
kfree(one_line);
|
||||
return -1;
|
||||
}
|
||||
temp_data = w * (h - 1) * bits >> 3;
|
||||
if (fd > 0) {
|
||||
INFO("vaddr is%p, bits is %d, fd check\n", vaddr, bits);
|
||||
memcpy(one_line, (char *)vaddr + temp_data, w * bits >> 3);
|
||||
INFO("fd check ok\n");
|
||||
} else {
|
||||
INFO("vir addr memory check.\n");
|
||||
memcpy((void *)((char *)vaddr + temp_data), one_line,
|
||||
w * bits >> 3);
|
||||
INFO("vir addr check ok.\n");
|
||||
}
|
||||
kfree(one_line);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
static int rga2_map_dma_buffer(struct rga_img_info_t *img,
|
||||
struct rga_dma_buffer_t *rga_dma_buffer,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
struct device *rga_dev = NULL;
|
||||
struct dma_buf *dma_buf = NULL;
|
||||
struct dma_buf_attachment *attach = NULL;
|
||||
struct sg_table *sgt = NULL;
|
||||
u32 vir_w, vir_h;
|
||||
int fd = -1;
|
||||
int ret = 0;
|
||||
|
||||
rga_dev = rga2_drvdata->dev;
|
||||
fd = (int)img->yrgb_addr;
|
||||
vir_w = img->vir_w;
|
||||
vir_h = img->vir_h;
|
||||
|
||||
dma_buf = dma_buf_get(fd);
|
||||
if (IS_ERR(dma_buf)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("dma_buf_get fail fd[%d]\n", fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
attach = dma_buf_attach(dma_buf, rga_dev);
|
||||
if (IS_ERR(attach)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("Failed to attach dma_buf\n");
|
||||
goto err_get_attach;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER
|
||||
if (RGA2_CHECK_MODE) {
|
||||
void *vaddr = dma_buf_vmap(dma_buf);
|
||||
|
||||
if (vaddr)
|
||||
rga2_memory_check(vaddr, img->vir_w, img->vir_h,
|
||||
img->format, img->yrgb_addr);
|
||||
dma_buf_vunmap(dma_buf, vaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
sgt = dma_buf_map_attachment(attach, dir);
|
||||
if (IS_ERR(sgt)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("Failed to map src attachment\n");
|
||||
goto err_get_sgt;
|
||||
}
|
||||
|
||||
rga_dma_buffer->dma_buf = dma_buf;
|
||||
rga_dma_buffer->attach = attach;
|
||||
rga_dma_buffer->sgt = sgt;
|
||||
rga_dma_buffer->size = sg_dma_len(sgt->sgl);
|
||||
rga_dma_buffer->dir = dir;
|
||||
|
||||
return ret;
|
||||
|
||||
err_get_sgt:
|
||||
if (attach)
|
||||
dma_buf_detach(dma_buf, attach);
|
||||
err_get_attach:
|
||||
if (dma_buf)
|
||||
dma_buf_put(dma_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rga2_unmap_dma_buffer(struct rga_dma_buffer_t *rga_dma_buffer)
|
||||
{
|
||||
if (rga_dma_buffer->attach && rga_dma_buffer->sgt)
|
||||
dma_buf_unmap_attachment(rga_dma_buffer->attach,
|
||||
rga_dma_buffer->sgt,
|
||||
rga_dma_buffer->dir);
|
||||
if (rga_dma_buffer->attach) {
|
||||
dma_buf_detach(rga_dma_buffer->dma_buf, rga_dma_buffer->attach);
|
||||
dma_buf_put(rga_dma_buffer->dma_buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void rga2_convert_addr(struct rga_img_info_t *img)
|
||||
{
|
||||
/*
|
||||
* If it is not using dma fd, the virtual/phyical address is assigned
|
||||
* to the address of the corresponding channel.
|
||||
*/
|
||||
img->yrgb_addr = img->uv_addr;
|
||||
img->uv_addr = img->yrgb_addr + (img->vir_w * img->vir_h);
|
||||
if (rga2_is_yuv422p_format(img->format))
|
||||
img->v_addr = img->uv_addr + (img->vir_w * img->vir_h) / 2;
|
||||
else
|
||||
img->v_addr = img->uv_addr + (img->vir_w * img->vir_h) / 4;
|
||||
}
|
||||
|
||||
int rga2_get_dma_info(struct rga2_reg *reg, struct rga2_req *req)
|
||||
{
|
||||
uint32_t mmu_flag;
|
||||
int ret;
|
||||
|
||||
struct rga_dma_buffer_t *buffer_src0, *buffer_src1, *buffer_dst, *buffer_els;
|
||||
struct rga_img_info_t *src0, *src1, *dst, *els;
|
||||
|
||||
/*
|
||||
* Since the life cycle of rga2_req cannot satisfy the release of
|
||||
* dmabuffer after the task is over, the mapped dmabuffer is saved
|
||||
* in rga2_reg.
|
||||
*/
|
||||
buffer_src0 = ®->dma_buffer_src0;
|
||||
buffer_src1 = ®->dma_buffer_src1;
|
||||
buffer_dst = ®->dma_buffer_dst;
|
||||
buffer_els = ®->dma_buffer_els;
|
||||
|
||||
src0 = &req->src;
|
||||
src1 = &req->src1;
|
||||
dst = &req->dst;
|
||||
els = &req->pat;
|
||||
|
||||
/* src0 chanel */
|
||||
mmu_flag = req->mmu_info.src0_mmu_flag;
|
||||
if (unlikely(!mmu_flag && src0->yrgb_addr)) {
|
||||
pr_err("Fix it please enable src0 mmu\n");
|
||||
return -EINVAL;
|
||||
} else if (mmu_flag && src0->yrgb_addr) {
|
||||
ret = rga2_map_dma_buffer(src0, buffer_src0, DMA_BIDIRECTIONAL);
|
||||
if (ret < 0) {
|
||||
pr_err("src0: can't map dma-buf\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
rga2_convert_addr(src0);
|
||||
|
||||
/* src1 chanel */
|
||||
mmu_flag = req->mmu_info.src1_mmu_flag;
|
||||
if (unlikely(!mmu_flag && src1->yrgb_addr)) {
|
||||
pr_err("Fix it please enable src1 mmu\n");
|
||||
ret = -EINVAL;
|
||||
goto err_src1_channel;
|
||||
} else if (mmu_flag && src1->yrgb_addr) {
|
||||
ret = rga2_map_dma_buffer(src1, buffer_src1, DMA_BIDIRECTIONAL);
|
||||
if (ret < 0) {
|
||||
pr_err("src1: can't map dma-buf\n");
|
||||
goto err_src1_channel;
|
||||
}
|
||||
}
|
||||
rga2_convert_addr(src1);
|
||||
|
||||
/* dst chanel */
|
||||
mmu_flag = req->mmu_info.dst_mmu_flag;
|
||||
if (unlikely(!mmu_flag && dst->yrgb_addr)) {
|
||||
pr_err("Fix it please enable dst mmu\n");
|
||||
ret = -EINVAL;
|
||||
goto err_dst_channel;
|
||||
} else if (mmu_flag && dst->yrgb_addr) {
|
||||
ret = rga2_map_dma_buffer(dst, buffer_dst, DMA_BIDIRECTIONAL);
|
||||
if (ret < 0) {
|
||||
pr_err("dst: can't map dma-buf\n");
|
||||
goto err_dst_channel;
|
||||
}
|
||||
}
|
||||
rga2_convert_addr(dst);
|
||||
|
||||
/* els chanel */
|
||||
mmu_flag = req->mmu_info.els_mmu_flag;
|
||||
if (unlikely(!mmu_flag && els->yrgb_addr)) {
|
||||
pr_err("Fix it please enable els mmu\n");
|
||||
ret = -EINVAL;
|
||||
goto err_els_channel;
|
||||
} else if (mmu_flag && els->yrgb_addr) {
|
||||
ret = rga2_map_dma_buffer(els, buffer_els, DMA_BIDIRECTIONAL);
|
||||
if (ret < 0) {
|
||||
pr_err("els: can't map dma-buf\n");
|
||||
goto err_els_channel;
|
||||
}
|
||||
}
|
||||
rga2_convert_addr(els);
|
||||
|
||||
return 0;
|
||||
|
||||
err_els_channel:
|
||||
rga2_unmap_dma_buffer(buffer_dst);
|
||||
err_dst_channel:
|
||||
rga2_unmap_dma_buffer(buffer_src1);
|
||||
err_src1_channel:
|
||||
rga2_unmap_dma_buffer(buffer_src0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rga2_put_dma_info(struct rga2_reg *reg)
|
||||
{
|
||||
rga2_unmap_dma_buffer(®->dma_buffer_src0);
|
||||
rga2_unmap_dma_buffer(®->dma_buffer_src1);
|
||||
rga2_unmap_dma_buffer(®->dma_buffer_dst);
|
||||
rga2_unmap_dma_buffer(®->dma_buffer_els);
|
||||
}
|
||||
|
||||
#else
|
||||
static int rga2_get_dma_info(struct rga2_reg *reg, struct rga2_req *req)
|
||||
{
|
||||
struct ion_handle *hdl;
|
||||
ion_phys_addr_t phy_addr;
|
||||
size_t len;
|
||||
int ret;
|
||||
u32 src_vir_w, dst_vir_w;
|
||||
void *vaddr = NULL;
|
||||
struct rga_dma_buffer_t *buffer_src0, *buffer_src1, *buffer_dst, *buffer_els;
|
||||
|
||||
src_vir_w = req->src.vir_w;
|
||||
dst_vir_w = req->dst.vir_w;
|
||||
|
||||
buffer_src0 = ®->dma_buffer_src0;
|
||||
buffer_src1 = ®->dma_buffer_src1;
|
||||
buffer_dst = ®->dma_buffer_dst;
|
||||
buffer_els = ®->dma_buffer_els;
|
||||
|
||||
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);
|
||||
pr_err("RGA2 SRC ERROR ion buf handle\n");
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER
|
||||
if (RGA2_CHECK_MODE) {
|
||||
vaddr = ion_map_kernel(rga2_drvdata->ion_client, hdl);
|
||||
if (vaddr)
|
||||
rga2_memory_check(vaddr, req->src.vir_w, req->src.vir_h,
|
||||
req->src.format, req->src.yrgb_addr);
|
||||
ion_unmap_kernel(rga2_drvdata->ion_client, hdl);
|
||||
}
|
||||
#endif
|
||||
if (req->mmu_info.src0_mmu_flag) {
|
||||
buffer_src0.sgt =
|
||||
ion_sg_table(rga2_drvdata->ion_client, hdl);
|
||||
req->src.yrgb_addr = req->src.uv_addr;
|
||||
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 + (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 {
|
||||
req->src.yrgb_addr = req->src.uv_addr;
|
||||
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 (IS_ERR(hdl)) {
|
||||
ret = PTR_ERR(hdl);
|
||||
pr_err("RGA2 DST ERROR ion buf handle\n");
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER
|
||||
if (RGA2_CHECK_MODE) {
|
||||
vaddr = ion_map_kernel(rga2_drvdata->ion_client, hdl);
|
||||
if (vaddr)
|
||||
rga2_memory_check(vaddr, req->dst.vir_w, req->dst.vir_h,
|
||||
req->dst.format, req->dst.yrgb_addr);
|
||||
ion_unmap_kernel(rga2_drvdata->ion_client, hdl);
|
||||
}
|
||||
#endif
|
||||
if (req->mmu_info.dst_mmu_flag) {
|
||||
buffer_dst.sgt =
|
||||
ion_sg_table(rga2_drvdata->ion_client, hdl);
|
||||
req->dst.yrgb_addr = req->dst.uv_addr;
|
||||
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 + (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 {
|
||||
req->dst.yrgb_addr = req->dst.uv_addr;
|
||||
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 (IS_ERR(hdl)) {
|
||||
ret = PTR_ERR(hdl);
|
||||
pr_err("RGA2 ERROR ion buf handle\n");
|
||||
return ret;
|
||||
}
|
||||
if (req->mmu_info.dst_mmu_flag) {
|
||||
buffer_src1.sgt =
|
||||
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->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->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;
|
||||
}
|
||||
if (rga2_is_yuv422p_format(req->src.format))
|
||||
req->src.v_addr = req->src.uv_addr + (req->src.vir_w * req->src.vir_h) / 2;
|
||||
if (rga2_is_yuv422p_format(req->dst.format))
|
||||
req->dst.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h) / 2;
|
||||
if (rga2_is_yuv422p_format(req->src1.format))
|
||||
req->src1.v_addr = req->src1.uv_addr + (req->src1.vir_w * req->dst.vir_h) / 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* When the kernel version is lower than 4.4, no put buffer operation is required. */
|
||||
void rga2_put_dma_info(struct rga2_reg *reg) {}
|
||||
#endif
|
||||
|
||||
static int rga2_mmu_buf_get(struct rga2_mmu_buf_t *t, uint32_t size)
|
||||
{
|
||||
mutex_lock(&rga2_service.lock);
|
||||
@@ -597,6 +1026,7 @@ static int rga2_mmu_flush_cache(struct rga2_reg *reg, struct rga2_req *req)
|
||||
int ret;
|
||||
int status;
|
||||
struct page **pages = NULL;
|
||||
struct rga_dma_buffer_t *dma_buffer = NULL;
|
||||
|
||||
MMU_Base = NULL;
|
||||
DstMemSize = 0;
|
||||
@@ -637,7 +1067,8 @@ static int rga2_mmu_flush_cache(struct rga2_reg *reg, struct rga2_req *req)
|
||||
|
||||
mutex_unlock(&rga2_service.lock);
|
||||
if (DstMemSize) {
|
||||
if (req->sg_dst) {
|
||||
dma_buffer = ®->dma_buffer_dst;
|
||||
if (dma_buffer->sgt) {
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
} else {
|
||||
@@ -678,6 +1109,8 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)
|
||||
int status;
|
||||
uint32_t uv_size, v_size;
|
||||
struct page **pages = NULL;
|
||||
struct rga_dma_buffer_t *dma_buffer = NULL;
|
||||
|
||||
MMU_Base = NULL;
|
||||
Src0MemSize = 0;
|
||||
Src1MemSize = 0;
|
||||
@@ -749,8 +1182,10 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)
|
||||
mutex_unlock(&rga2_service.lock);
|
||||
|
||||
if (Src0MemSize) {
|
||||
if (req->sg_src0) {
|
||||
ret = rga2_MapION(req->sg_src0,
|
||||
dma_buffer = ®->dma_buffer_src0;
|
||||
|
||||
if (dma_buffer->sgt) {
|
||||
ret = rga2_MapION(dma_buffer->sgt,
|
||||
&MMU_Base[0], Src0MemSize);
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0],
|
||||
@@ -788,9 +1223,12 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)
|
||||
req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) |
|
||||
(v_size << PAGE_SHIFT);
|
||||
}
|
||||
|
||||
if (Src1MemSize) {
|
||||
if (req->sg_src1) {
|
||||
ret = rga2_MapION(req->sg_src1,
|
||||
dma_buffer = ®->dma_buffer_src1;
|
||||
|
||||
if (dma_buffer->sgt) {
|
||||
ret = rga2_MapION(dma_buffer->sgt,
|
||||
MMU_Base + Src0MemSize, Src1MemSize);
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0],
|
||||
@@ -813,8 +1251,10 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)
|
||||
req->src1.yrgb_addr = (req->src1.yrgb_addr & (~PAGE_MASK));
|
||||
}
|
||||
if (DstMemSize) {
|
||||
if (req->sg_dst) {
|
||||
ret = rga2_MapION(req->sg_dst, MMU_Base + Src0MemSize
|
||||
dma_buffer = ®->dma_buffer_dst;
|
||||
|
||||
if (dma_buffer->sgt) {
|
||||
ret = rga2_MapION(dma_buffer->sgt, MMU_Base + Src0MemSize
|
||||
+ Src1MemSize, DstMemSize);
|
||||
} else if (req->alpha_mode_0 != 0 && req->bitblt_mode == 0) {
|
||||
/* The blend mode of src + dst => dst requires clean and invalidate */
|
||||
@@ -900,6 +1340,7 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re
|
||||
|
||||
uint8_t shift;
|
||||
uint32_t sw, byte_num;
|
||||
struct rga_dma_buffer_t *dma_buffer = NULL;
|
||||
|
||||
shift = 3 - (req->palette_mode & 3);
|
||||
sw = req->src.vir_w*req->src.vir_h;
|
||||
@@ -961,8 +1402,10 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re
|
||||
mutex_unlock(&rga2_service.lock);
|
||||
|
||||
if(SrcMemSize) {
|
||||
if (req->sg_src0) {
|
||||
ret = rga2_MapION(req->sg_src0,
|
||||
dma_buffer = ®->dma_buffer_src0;
|
||||
|
||||
if (dma_buffer->sgt) {
|
||||
ret = rga2_MapION(dma_buffer->sgt,
|
||||
&MMU_Base[0], SrcMemSize);
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0],
|
||||
@@ -990,8 +1433,10 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re
|
||||
}
|
||||
|
||||
if(DstMemSize) {
|
||||
if (req->sg_dst) {
|
||||
ret = rga2_MapION(req->sg_dst,
|
||||
dma_buffer = ®->dma_buffer_dst;
|
||||
|
||||
if (dma_buffer->sgt) {
|
||||
ret = rga2_MapION(dma_buffer->sgt,
|
||||
MMU_Base + SrcMemSize, DstMemSize);
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0], MMU_Base + SrcMemSize,
|
||||
@@ -1045,6 +1490,7 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req *
|
||||
uint32_t *MMU_Base, *MMU_Base_phys;
|
||||
int ret;
|
||||
int status;
|
||||
struct rga_dma_buffer_t *dma_buffer = NULL;
|
||||
|
||||
DstMemSize = 0;
|
||||
DstPageCount = 0;
|
||||
@@ -1082,8 +1528,10 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req *
|
||||
mutex_unlock(&rga2_service.lock);
|
||||
|
||||
if (DstMemSize) {
|
||||
if (req->sg_dst) {
|
||||
ret = rga2_MapION(req->sg_dst, &MMU_Base[0], DstMemSize);
|
||||
dma_buffer = ®->dma_buffer_dst;
|
||||
|
||||
if (dma_buffer->sgt) {
|
||||
ret = rga2_MapION(dma_buffer->sgt, &MMU_Base[0], DstMemSize);
|
||||
}
|
||||
else {
|
||||
ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0],
|
||||
@@ -1133,6 +1581,7 @@ static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct
|
||||
uint32_t AllSize;
|
||||
uint32_t *MMU_Base, *MMU_Base_phys;
|
||||
int ret, status;
|
||||
struct rga_dma_buffer_t *dma_buffer = NULL;
|
||||
|
||||
MMU_Base = NULL;
|
||||
LutPageCount = 0;
|
||||
@@ -1175,8 +1624,10 @@ static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct
|
||||
mutex_unlock(&rga2_service.lock);
|
||||
|
||||
if (LutMemSize) {
|
||||
if (req->sg_els) {
|
||||
ret = rga2_MapION(req->sg_els,
|
||||
dma_buffer = ®->dma_buffer_els;
|
||||
|
||||
if (dma_buffer->sgt) {
|
||||
ret = rga2_MapION(dma_buffer->sgt,
|
||||
&MMU_Base[0], LutMemSize);
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0],
|
||||
|
||||
@@ -28,5 +28,8 @@ int rga2_set_mmu_info(struct rga2_reg *reg, struct rga2_req *req);
|
||||
void rga2_dma_flush_range(void *pstart, void *pend);
|
||||
dma_addr_t rga2_dma_flush_page(struct page *page, int map);
|
||||
|
||||
int rga2_get_dma_info(struct rga2_reg *reg, struct rga2_req *req);
|
||||
void rga2_put_dma_info(struct rga2_reg *reg);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user