diff --git a/drivers/video/rockchip/rga3/include/rga.h b/drivers/video/rockchip/rga3/include/rga.h index 6b19eabc895c..a87bd1dcebdb 100644 --- a/drivers/video/rockchip/rga3/include/rga.h +++ b/drivers/video/rockchip/rga3/include/rga.h @@ -221,6 +221,8 @@ struct rga_memory_parm { uint32_t width; uint32_t height; uint32_t format; + + uint32_t size; }; struct rga_external_buffer { @@ -230,7 +232,7 @@ struct rga_external_buffer { uint32_t handle; struct rga_memory_parm memory_parm; - uint8_t reserve[256]; + uint8_t reserve[252]; }; struct rga_buffer_pool { diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h index c78d26e90c42..431c4d36a483 100644 --- a/drivers/video/rockchip/rga3/include/rga_drv.h +++ b/drivers/video/rockchip/rga3/include/rga_drv.h @@ -86,7 +86,7 @@ #define DRIVER_MAJOR_VERISON 1 #define DRIVER_MINOR_VERSION 2 -#define DRIVER_REVISION_VERSION 8 +#define DRIVER_REVISION_VERSION 9 #define DRIVER_VERSION (STR(DRIVER_MAJOR_VERISON) "." STR(DRIVER_MINOR_VERSION) \ "." STR(DRIVER_REVISION_VERSION)) diff --git a/drivers/video/rockchip/rga3/rga_common.c b/drivers/video/rockchip/rga3/rga_common.c index cd378640d399..f217448ec279 100644 --- a/drivers/video/rockchip/rga3/rga_common.c +++ b/drivers/video/rockchip/rga3/rga_common.c @@ -508,6 +508,10 @@ void rga_convert_addr(struct rga_img_info_t *img, bool before_vir_get_channel) int rga_image_size_cal(int w, int h, int format, int *yrgb_size, int *uv_size, int *v_size) { + int yrgb = 0; + int uv = 0; + int v = 0; + switch (format) { case RGA_FORMAT_RGBA_8888: case RGA_FORMAT_RGBX_8888: @@ -517,11 +521,11 @@ int rga_image_size_cal(int w, int h, int format, case RGA_FORMAT_XRGB_8888: case RGA_FORMAT_ABGR_8888: case RGA_FORMAT_XBGR_8888: - *yrgb_size = w * h * 4; + yrgb = w * h * 4; break; case RGA_FORMAT_RGB_888: case RGA_FORMAT_BGR_888: - *yrgb_size = w * h * 3; + yrgb = w * h * 3; break; case RGA_FORMAT_RGB_565: case RGA_FORMAT_RGBA_5551: @@ -537,47 +541,54 @@ int rga_image_size_cal(int w, int h, int format, case RGA_FORMAT_VYUY_422: case RGA_FORMAT_YUYV_422: case RGA_FORMAT_UYVY_422: - *yrgb_size = w * h * 2; + yrgb = w * h * 2; break; case RGA_FORMAT_YVYU_420: case RGA_FORMAT_VYUY_420: case RGA_FORMAT_YUYV_420: case RGA_FORMAT_UYVY_420: - *yrgb_size = (w * h) + ((w * h) >> 1); + yrgb = (w * h) + ((w * h) >> 1); break; /* YUV FORMAT */ case RGA_FORMAT_YCbCr_422_SP: case RGA_FORMAT_YCrCb_422_SP: - *yrgb_size = w * h; - *uv_size = w * h; + yrgb = w * h; + uv = w * h; break; case RGA_FORMAT_YCbCr_422_P: case RGA_FORMAT_YCrCb_422_P: - *yrgb_size = w * h; - *uv_size = (w * h) >> 1; - *v_size = *uv_size; + yrgb = w * h; + uv = (w * h) >> 1; + v = uv; break; case RGA_FORMAT_YCbCr_420_SP: case RGA_FORMAT_YCrCb_420_SP: - *yrgb_size = w * h; - *uv_size = (w * h) >> 1; + yrgb = w * h; + uv = (w * h) >> 1; break; case RGA_FORMAT_YCbCr_420_P: case RGA_FORMAT_YCrCb_420_P: - *yrgb_size = w * h; - *uv_size = (w * h) >> 2; - *v_size = *uv_size; + yrgb = w * h; + uv = (w * h) >> 2; + v = uv; break; case RGA_FORMAT_YCbCr_400: - *yrgb_size = w * h; + yrgb = w * h; break; case RGA_FORMAT_Y4: - *yrgb_size = (w * h) >> 1; + yrgb = (w * h) >> 1; break; default: pr_err("Unsuport format [0x%x]\n", format); return -EFAULT; } - return (*yrgb_size + *uv_size + *v_size); + if (yrgb_size != NULL) + *yrgb_size = yrgb; + if (uv_size != NULL) + *uv_size = uv; + if (v_size != NULL) + *v_size = v; + + return (yrgb + uv + v); } diff --git a/drivers/video/rockchip/rga3/rga_mm.c b/drivers/video/rockchip/rga3/rga_mm.c index b7bd507cc597..10492f730d42 100644 --- a/drivers/video/rockchip/rga3/rga_mm.c +++ b/drivers/video/rockchip/rga3/rga_mm.c @@ -226,21 +226,28 @@ static int rga_alloc_virt_addr(struct rga_virt_addr **virt_addr_p, int result = 0; int order; unsigned int count; - unsigned long start_addr; + int img_size; + size_t offset; unsigned long size; - uint64_t uv_addr, v_addr; struct page **pages = NULL; struct rga_virt_addr *virt_addr = NULL; - uv_addr = viraddr + (memory_parm->width * memory_parm->height); - v_addr = uv_addr + (memory_parm->width * memory_parm->height) / - (rga_is_yuv422p_format(memory_parm->format) ? 2 : 4); + if (memory_parm->size) + img_size = memory_parm->size; + else + img_size = rga_image_size_cal(memory_parm->width, + memory_parm->height, + memory_parm->format, + NULL, NULL, NULL); - /* Calculate page size. */ - count = rga_buf_size_cal(viraddr, uv_addr, v_addr, memory_parm->format, - memory_parm->width, memory_parm->height, - &start_addr, NULL); + offset = viraddr & (~PAGE_MASK); + count = RGA_GET_PAGE_COUNT(img_size + offset); size = count * PAGE_SIZE; + if (!size) { + pr_err("failed to calculating buffer size! size = %ld, count = %d, offset = %ld\n", + size, count, (unsigned long)offset); + return -EFAULT; + } /* alloc pages and page_table */ order = get_order(count * sizeof(struct page *)); @@ -251,7 +258,7 @@ static int rga_alloc_virt_addr(struct rga_virt_addr **virt_addr_p, } /* get pages from virtual address. */ - ret = rga_get_user_pages(pages, start_addr, count, writeFlag, mm); + ret = rga_get_user_pages(pages, viraddr >> PAGE_SHIFT, count, writeFlag, mm); if (ret < 0) { pr_err("failed to get pages"); ret = -EINVAL; @@ -274,7 +281,7 @@ static int rga_alloc_virt_addr(struct rga_virt_addr **virt_addr_p, virt_addr->pages_order = order; virt_addr->page_count = count; virt_addr->size = size; - virt_addr->offset = viraddr & (~PAGE_MASK); + virt_addr->offset = offset; virt_addr->result = result; return 0;