From: Alpha Lin Date: Fri, 10 Apr 2015 05:53:02 +0000 (+0800) Subject: IEP: Support processing part of input image X-Git-Tag: firefly_0821_release~4158^2~220 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=f161a8f22b63a2ea6e22de96d0ce79f343c897ba;p=firefly-linux-kernel-4.4.55.git IEP: Support processing part of input image Enable virtual size and actual size and start offset, to support processing part of input image. Signed-off-by: Alpha Lin --- diff --git a/drivers/video/rockchip/iep/hw_iep_reg.c b/drivers/video/rockchip/iep/hw_iep_reg.c index 0f8062546391..9df61660b9e0 100644 --- a/drivers/video/rockchip/iep/hw_iep_reg.c +++ b/drivers/video/rockchip/iep/hw_iep_reg.c @@ -18,6 +18,7 @@ #include "iep.h" #include "hw_iep_config_addr.h" +extern iep_service_info iep_service; static void iep_config_src_size(struct IEP_MSG *iep_msg) { IEP_REGB_SRC_IMG_WIDTH(iep_msg->base, iep_msg->src.act_w - 1); @@ -916,35 +917,58 @@ static void iep_config_src_addr(struct IEP_MSG *iep_msg) //**********************************************// //***********yuv address *********************// //**********************************************// - src_addr_yrgb = ((u32)iep_msg->src.mem_addr) + offset_addr_y; - src_addr_cbcr = ((u32)iep_msg->src.uv_addr) + offset_addr_uv; - src_addr_cr = ((u32)iep_msg->src.v_addr) + offset_addr_v; - - // former frame when processing deinterlace - src_addr_y1 = ((u32)iep_msg->src1.mem_addr) + offset_addr_y; - src_addr_cbcr1 = ((u32)iep_msg->src1.uv_addr) + offset_addr_uv; - src_addr_cr1 = ((u32)iep_msg->src1.v_addr) + offset_addr_v; - - src_addr_y_itemp = ((u32)iep_msg->src_itemp.mem_addr) + - offset_addr_y; - src_addr_cbcr_itemp = ((u32)iep_msg->src_itemp.uv_addr) + - offset_addr_uv; - src_addr_cr_itemp = ((u32)iep_msg->src_itemp.v_addr) + - offset_addr_v; - - src_addr_y_ftemp = ((u32)iep_msg->src_ftemp.mem_addr) + - offset_addr_y; - src_addr_cbcr_ftemp = ((u32)iep_msg->src_ftemp.uv_addr) + - offset_addr_uv; - src_addr_cr_ftemp = ((u32)iep_msg->src_ftemp.v_addr) + - offset_addr_v; + if (iep_service.iommu_dev == NULL) { + src_addr_yrgb = ((u32)iep_msg->src.mem_addr) + offset_addr_y; + src_addr_cbcr = ((u32)iep_msg->src.uv_addr) + offset_addr_uv; + src_addr_cr = ((u32)iep_msg->src.v_addr) + offset_addr_v; + + src_addr_y1 = ((u32)iep_msg->src1.mem_addr) + offset_addr_y; + src_addr_cbcr1 = ((u32)iep_msg->src1.uv_addr) + offset_addr_uv; + src_addr_cr1 = ((u32)iep_msg->src1.v_addr) + offset_addr_v; + + src_addr_y_itemp = ((u32)iep_msg->src_itemp.mem_addr) + + offset_addr_y; + src_addr_cbcr_itemp = ((u32)iep_msg->src_itemp.uv_addr) + + offset_addr_uv; + src_addr_cr_itemp = ((u32)iep_msg->src_itemp.v_addr) + + offset_addr_v; + + src_addr_y_ftemp = ((u32)iep_msg->src_ftemp.mem_addr) + + offset_addr_y; + src_addr_cbcr_ftemp = ((u32)iep_msg->src_ftemp.uv_addr) + + offset_addr_uv; + src_addr_cr_ftemp = ((u32)iep_msg->src_ftemp.v_addr) + + offset_addr_v; + } else { + src_addr_yrgb = ((u32)iep_msg->src.mem_addr) + (offset_addr_y << 10); + src_addr_cbcr = ((u32)iep_msg->src.uv_addr) + (offset_addr_uv << 10); + src_addr_cr = ((u32)iep_msg->src.v_addr) + (offset_addr_v << 10); + + src_addr_y1 = ((u32)iep_msg->src1.mem_addr) + (offset_addr_y << 10); + src_addr_cbcr1 = ((u32)iep_msg->src1.uv_addr) + (offset_addr_uv << 10); + src_addr_cr1 = ((u32)iep_msg->src1.v_addr) + (offset_addr_v << 10); + + src_addr_y_itemp = ((u32)iep_msg->src_itemp.mem_addr) + + (offset_addr_y << 10); + src_addr_cbcr_itemp = ((u32)iep_msg->src_itemp.uv_addr) + + (offset_addr_uv << 10); + src_addr_cr_itemp = ((u32)iep_msg->src_itemp.v_addr) + + (offset_addr_v << 10); + + src_addr_y_ftemp = ((u32)iep_msg->src_ftemp.mem_addr) + + (offset_addr_y << 10); + src_addr_cbcr_ftemp = ((u32)iep_msg->src_ftemp.uv_addr) + + (offset_addr_uv << 10); + src_addr_cr_ftemp = ((u32)iep_msg->src_ftemp.v_addr) + + (offset_addr_v << 10); + } if ((iep_msg->dein_mode == IEP_DEINTERLACE_MODE_I4O1 || iep_msg->dein_mode == IEP_DEINTERLACE_MODE_I4O2) && #if 1 iep_msg->field_order == FIELD_ORDER_BOTTOM_FIRST #else - iep_msg->field_order == FIELD_ORDER_TOP_FIRST + iep_msg->field_order == FIELD_ORDER_TOP_FIRST #endif ) { IEP_REGB_SRC_ADDR_YRGB(iep_msg->base, src_addr_y1); @@ -1000,30 +1024,204 @@ static void iep_config_src_addr(struct IEP_MSG *iep_msg) static void iep_config_dst_addr(struct IEP_MSG *iep_msg) { - IEP_REGB_DST_ADDR_YRGB(iep_msg->base, (u32)iep_msg->dst.mem_addr); - IEP_REGB_DST_ADDR_CBCR(iep_msg->base, (u32)iep_msg->dst.uv_addr); - IEP_REGB_DST_ADDR_Y1(iep_msg->base, (u32)iep_msg->dst1.mem_addr); - IEP_REGB_DST_ADDR_CBCR1(iep_msg->base, (u32)iep_msg->dst1.uv_addr); - IEP_REGB_DST_ADDR_CR(iep_msg->base, (u32)iep_msg->dst.v_addr); - IEP_REGB_DST_ADDR_CR1(iep_msg->base, (u32)iep_msg->dst1.v_addr); + u32 dst_addr_yrgb; + u32 dst_addr_cbcr; + u32 dst_addr_cr; + u32 dst_addr_y1; + u32 dst_addr_cbcr1; + u32 dst_addr_cr1; + u32 dst_addr_y_itemp; + u32 dst_addr_cbcr_itemp; + u32 dst_addr_cr_itemp; + u32 dst_addr_y_ftemp; + u32 dst_addr_cbcr_ftemp; + u32 dst_addr_cr_ftemp; + unsigned int offset_addr_y = 0; + unsigned int offset_addr_uv = 0; + unsigned int offset_addr_v = 0; + //unsigned int offset_addr_y_w = 0; + unsigned int offset_addr_uv_w = 0; + unsigned int offset_addr_v_w = 0; + //unsigned int offset_addr_y_h = 0; + unsigned int offset_addr_uv_h = 0; + unsigned int offset_addr_v_h = 0; + + unsigned int offset_x_equ_uv; + unsigned int offset_x_u_byte; + unsigned int offset_x_v_byte; + unsigned int vir_w_euq_uv; + unsigned int line_u_byte; + unsigned int line_v_byte; + unsigned int offset_y_equ_420_uv = 0; + + //**********************************************// + //***********y addr offset**********************// + //**********************************************// + if (iep_msg->dst.format <= 3) { + offset_addr_y = iep_msg->dst.y_off * 4 * + iep_msg->dst.vir_w + iep_msg->dst.x_off * 4; + } else if (iep_msg->dst.format <= 5) { + offset_addr_y = iep_msg->dst.y_off * 2 * + iep_msg->dst.vir_w + iep_msg->dst.x_off * 2; + } else { + offset_addr_y = iep_msg->dst.y_off * + iep_msg->dst.vir_w + iep_msg->dst.x_off; + } + + //**********************************************// + //***********uv addr offset*********************// + //**********************************************// + // note: image size align to even when image format is yuv + + //----------offset_w--------// + if (iep_msg->dst.x_off % 2 == 1) + offset_x_equ_uv = iep_msg->dst.x_off + 1; + else + offset_x_equ_uv = iep_msg->dst.x_off; + + offset_x_u_byte = offset_x_equ_uv / 2; + offset_x_v_byte = offset_x_equ_uv / 2; + + if ((iep_msg->dst.format == IEP_FORMAT_YCbCr_422_SP) || + (iep_msg->dst.format == IEP_FORMAT_YCbCr_420_SP) + || (iep_msg->dst.format == IEP_FORMAT_YCrCb_422_SP) || + (iep_msg->dst.format == IEP_FORMAT_YCrCb_420_SP)) + offset_addr_uv_w = offset_x_u_byte + offset_x_v_byte; + else { + offset_addr_uv_w = offset_x_u_byte; + offset_addr_v_w = offset_x_v_byte; + } + + //----------offset_h--------// + if (iep_msg->dst.vir_w % 2 == 1) + vir_w_euq_uv = iep_msg->dst.vir_w + 1; + else + vir_w_euq_uv = iep_msg->dst.vir_w; + + line_u_byte = vir_w_euq_uv / 2; + line_v_byte = vir_w_euq_uv / 2; + + if (iep_msg->dst.y_off % 2 == 1) + offset_y_equ_420_uv = iep_msg->dst.y_off + 1; + else + offset_y_equ_420_uv = iep_msg->dst.y_off; + + switch (iep_msg->dst.format) { + case IEP_FORMAT_YCbCr_422_SP : + offset_addr_uv_h = (line_u_byte + line_v_byte) * + iep_msg->dst.y_off; + break; + case IEP_FORMAT_YCbCr_422_P : + offset_addr_uv_h = line_u_byte * iep_msg->dst.y_off; + offset_addr_v_h = line_v_byte * iep_msg->dst.y_off; + break; + case IEP_FORMAT_YCbCr_420_SP : + offset_addr_uv_h = (line_u_byte + line_v_byte) * + offset_y_equ_420_uv / 2; + break; + case IEP_FORMAT_YCbCr_420_P : + offset_addr_uv_h = line_u_byte * offset_y_equ_420_uv / 2; + offset_addr_v_h = line_v_byte * offset_y_equ_420_uv / 2; + break; + case IEP_FORMAT_YCrCb_422_SP : + offset_addr_uv_h = (line_u_byte + line_v_byte) * + iep_msg->dst.y_off; + break; + case IEP_FORMAT_YCrCb_422_P : + offset_addr_uv_h = line_u_byte * iep_msg->dst.y_off; + offset_addr_v_h = line_v_byte * iep_msg->dst.y_off; + break; + case IEP_FORMAT_YCrCb_420_SP : + offset_addr_uv_h = (line_u_byte + line_v_byte) * + offset_y_equ_420_uv / 2; + break; + case IEP_FORMAT_YCrCb_420_P : + offset_addr_uv_h = line_u_byte * offset_y_equ_420_uv / 2; + offset_addr_v_h = line_v_byte * offset_y_equ_420_uv / 2; + break; + default: + break; + } + //----------offset u/v addr--------// + + offset_addr_uv = offset_addr_uv_w + offset_addr_uv_h; + offset_addr_v = offset_addr_v_w + offset_addr_v_h; + //**********************************************// + //***********yuv address *********************// + //**********************************************// + + if (iep_service.iommu_dev == NULL) { + dst_addr_yrgb = ((u32)iep_msg->dst.mem_addr) + offset_addr_y; + dst_addr_cbcr = ((u32)iep_msg->dst.uv_addr) + offset_addr_uv; + dst_addr_cr = ((u32)iep_msg->dst.v_addr) + offset_addr_v; + + // former frame when processing deinterlace + dst_addr_y1 = ((u32)iep_msg->dst1.mem_addr) + offset_addr_y; + dst_addr_cbcr1 = ((u32)iep_msg->dst1.uv_addr) + offset_addr_uv; + dst_addr_cr1 = ((u32)iep_msg->dst1.v_addr) + offset_addr_v; + + dst_addr_y_itemp = ((u32)iep_msg->dst_itemp.mem_addr) + + offset_addr_y; + dst_addr_cbcr_itemp = ((u32)iep_msg->dst_itemp.uv_addr) + + offset_addr_uv; + dst_addr_cr_itemp = ((u32)iep_msg->dst_itemp.v_addr) + + offset_addr_v; + + dst_addr_y_ftemp = ((u32)iep_msg->dst_ftemp.mem_addr) + + offset_addr_y; + dst_addr_cbcr_ftemp = ((u32)iep_msg->dst_ftemp.uv_addr) + + offset_addr_uv; + dst_addr_cr_ftemp = ((u32)iep_msg->dst_ftemp.v_addr) + + offset_addr_v; + } else { + dst_addr_yrgb = ((u32)iep_msg->dst.mem_addr) + (offset_addr_y << 10); + dst_addr_cbcr = ((u32)iep_msg->dst.uv_addr) + (offset_addr_uv << 10); + dst_addr_cr = ((u32)iep_msg->dst.v_addr) + (offset_addr_v << 10); + + // former frame when processing deinterlace + dst_addr_y1 = ((u32)iep_msg->dst1.mem_addr) + (offset_addr_y << 10); + dst_addr_cbcr1 = ((u32)iep_msg->dst1.uv_addr) + (offset_addr_uv << 10); + dst_addr_cr1 = ((u32)iep_msg->dst1.v_addr) + (offset_addr_v << 10); + + dst_addr_y_itemp = ((u32)iep_msg->dst_itemp.mem_addr) + + (offset_addr_y << 10); + dst_addr_cbcr_itemp = ((u32)iep_msg->dst_itemp.uv_addr) + + (offset_addr_uv << 10); + dst_addr_cr_itemp = ((u32)iep_msg->dst_itemp.v_addr) + + (offset_addr_v << 10); + + dst_addr_y_ftemp = ((u32)iep_msg->dst_ftemp.mem_addr) + + (offset_addr_y << 10); + dst_addr_cbcr_ftemp = ((u32)iep_msg->dst_ftemp.uv_addr) + + (offset_addr_uv << 10); + dst_addr_cr_ftemp = ((u32)iep_msg->dst_ftemp.v_addr) + + (offset_addr_v << 10); + } + + IEP_REGB_DST_ADDR_YRGB(iep_msg->base, dst_addr_yrgb); + IEP_REGB_DST_ADDR_CBCR(iep_msg->base, dst_addr_cbcr); + IEP_REGB_DST_ADDR_Y1(iep_msg->base, dst_addr_y1); + IEP_REGB_DST_ADDR_CBCR1(iep_msg->base, dst_addr_cbcr1); + IEP_REGB_DST_ADDR_CR(iep_msg->base, dst_addr_cr); + IEP_REGB_DST_ADDR_CR1(iep_msg->base, dst_addr_cr1); if (iep_msg->yuv_3D_denoise_en) { IEP_REGB_DST_ADDR_Y_ITEMP(iep_msg->base, - (u32)iep_msg->dst_itemp.mem_addr); + dst_addr_y_itemp); IEP_REGB_DST_ADDR_CBCR_ITEMP(iep_msg->base, - (u32)iep_msg->dst_itemp.uv_addr); + dst_addr_cbcr_itemp); IEP_REGB_DST_ADDR_Y_FTEMP(iep_msg->base, - (u32)iep_msg->dst_ftemp.mem_addr); + dst_addr_y_ftemp); IEP_REGB_DST_ADDR_CBCR_FTEMP(iep_msg->base, - (u32)iep_msg->dst_ftemp.uv_addr); + dst_addr_cbcr_ftemp); if ((iep_msg->dst.format == IEP_FORMAT_YCbCr_422_P) || (iep_msg->dst.format == IEP_FORMAT_YCbCr_420_P) || (iep_msg->dst.format == IEP_FORMAT_YCrCb_422_P) || (iep_msg->dst.format == IEP_FORMAT_YCrCb_420_P)) { IEP_REGB_DST_ADDR_CR_ITEMP(iep_msg->base, - (u32)iep_msg->dst_itemp.v_addr); + dst_addr_cr_itemp); IEP_REGB_DST_ADDR_CR_FTEMP(iep_msg->base, - (u32)iep_msg->dst_ftemp.v_addr); + dst_addr_cr_ftemp); } } #ifdef IEP_PRINT_INFO @@ -1293,7 +1491,6 @@ static int iep_reg_address_translate(iep_service_info *pservice, struct iep_reg /** * generating a series of registers copy from iep message */ -extern iep_service_info iep_service; void iep_config(iep_session *session, struct IEP_MSG *iep_msg) { struct iep_reg *reg = kzalloc(sizeof(struct iep_reg), GFP_KERNEL); diff --git a/drivers/video/rockchip/iep/iep.h b/drivers/video/rockchip/iep/iep.h index 8f5554fb5ce1..63ad697dfc6e 100644 --- a/drivers/video/rockchip/iep/iep.h +++ b/drivers/video/rockchip/iep/iep.h @@ -12,6 +12,7 @@ #define IEP_GET_RESULT_ASYNC _IOW(IEP_IOC_MAGIC, 7, unsigned long) #define IEP_SET_PARAMETER _IOW(IEP_IOC_MAGIC, 8, unsigned long) #define IEP_RELEASE_CURRENT_TASK _IOW(IEP_IOC_MAGIC, 9, unsigned long) +#define IEP_GET_IOMMU_STATE _IOR(IEP_IOC_MAGIC,10, unsigned long) #ifdef CONFIG_COMPAT #define COMPAT_IEP_SET_PARAMETER_REQ _IOW(IEP_IOC_MAGIC, 1, u32) @@ -23,6 +24,7 @@ #define COMPAT_IEP_GET_RESULT_ASYNC _IOW(IEP_IOC_MAGIC, 7, u32) #define COMPAT_IEP_SET_PARAMETER _IOW(IEP_IOC_MAGIC, 8, u32) #define COMPAT_IEP_RELEASE_CURRENT_TASK _IOW(IEP_IOC_MAGIC, 9, u32) +#define COMPAT_IEP_GET_IOMMU_STATE _IOR(IEP_IOC_MAGIC,10, u32) #endif /* Driver information */ diff --git a/drivers/video/rockchip/iep/iep_drv.c b/drivers/video/rockchip/iep/iep_drv.c index 2e93cf2a67ac..5ac19f8c9e93 100644 --- a/drivers/video/rockchip/iep/iep_drv.c +++ b/drivers/video/rockchip/iep/iep_drv.c @@ -786,6 +786,20 @@ static long iep_ioctl(struct file *filp, uint32_t cmd, unsigned long arg) iep_try_set_reg(); iep_try_start_frm(); break; + case IEP_GET_IOMMU_STATE: + { + int iommu_enable = 0; + +#if defined(CONFIG_IEP_IOMMU) + iommu_enable = iep_service.iommu_dev ? 1 : 0; +#endif + if (copy_to_user((void __user *)arg, &iommu_enable, + sizeof(int))) { + IEP_ERR("error: copy_to_user failed\n"); + return -EFAULT; + } + } + break; default: IEP_ERR("unknown ioctl cmd!\n"); ret = -EINVAL; @@ -858,6 +872,20 @@ static long compat_iep_ioctl(struct file *filp, uint32_t cmd, iep_try_set_reg(); iep_try_start_frm(); break; + case COMPAT_IEP_GET_IOMMU_STATE: + { + int iommu_enable = 0; + +#if defined(CONFIG_IEP_IOMMU) + iommu_enable = iep_service.iommu_dev ? 1 : 0; +#endif + if (copy_to_user((void __user *)arg, &iommu_enable, + sizeof(int))) { + IEP_ERR("error: copy_to_user failed\n"); + return -EFAULT; + } + } + break; default: IEP_ERR("unknown ioctl cmd!\n"); ret = -EINVAL;