From ba3908894a13688973b13ef06e499e6bb72807b6 Mon Sep 17 00:00:00 2001 From: zsq Date: Tue, 20 Jan 2015 17:05:53 +0800 Subject: [PATCH] add rga2 drivers for 64bit platform --- arch/arm64/configs/rockchip_defconfig | 2 + drivers/video/rockchip/rga/RGA_API.c | 72 +- drivers/video/rockchip/rga/rga.h | 15 +- drivers/video/rockchip/rga/rga_drv.c | 1286 ++++++++++--------- drivers/video/rockchip/rga/rga_mmu_info.c | 304 +---- drivers/video/rockchip/rga2/rga2.h | 31 +- drivers/video/rockchip/rga2/rga2_drv.c | 307 ++--- drivers/video/rockchip/rga2/rga2_mmu_info.c | 229 +--- drivers/video/rockchip/rga2/rga2_reg_info.c | 3 +- 9 files changed, 973 insertions(+), 1276 deletions(-) diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig index fece209c092f..44f5f8b506e8 100644 --- a/arch/arm64/configs/rockchip_defconfig +++ b/arch/arm64/configs/rockchip_defconfig @@ -385,6 +385,8 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_PWM=y CONFIG_FB_ROCKCHIP=y CONFIG_LCDC_RK3368=y +CONFIG_ROCKCHIP_RGA=y +CONFIG_ROCKCHIP_RGA2=y CONFIG_RK_TRSM=y CONFIG_RK31XX_LVDS=y CONFIG_DP_ANX6345=y diff --git a/drivers/video/rockchip/rga/RGA_API.c b/drivers/video/rockchip/rga/RGA_API.c index 0b48f95c8e5a..7055d858d8a4 100755 --- a/drivers/video/rockchip/rga/RGA_API.c +++ b/drivers/video/rockchip/rga/RGA_API.c @@ -6,18 +6,18 @@ #define IS_YUV_420(format) \ ((format == RK_FORMAT_YCbCr_420_P) | (format == RK_FORMAT_YCbCr_420_SP) | \ - (format == RK_FORMAT_YCrCb_420_P) | (format == RK_FORMAT_YCrCb_420_SP)) + (format == RK_FORMAT_YCrCb_420_P) | (format == RK_FORMAT_YCrCb_420_SP)) #define IS_YUV_422(format) \ ((format == RK_FORMAT_YCbCr_422_P) | (format == RK_FORMAT_YCbCr_422_SP) | \ - (format == RK_FORMAT_YCrCb_422_P) | (format == RK_FORMAT_YCrCb_422_SP)) + (format == RK_FORMAT_YCrCb_422_P) | (format == RK_FORMAT_YCrCb_422_SP)) #define IS_YUV(format) \ ((format == RK_FORMAT_YCbCr_420_P) | (format == RK_FORMAT_YCbCr_420_SP) | \ (format == RK_FORMAT_YCrCb_420_P) | (format == RK_FORMAT_YCrCb_420_SP) | \ (format == RK_FORMAT_YCbCr_422_P) | (format == RK_FORMAT_YCbCr_422_SP) | \ (format == RK_FORMAT_YCrCb_422_P) | (format == RK_FORMAT_YCrCb_422_SP)) - + extern rga_service_info rga_service; @@ -42,7 +42,7 @@ matrix_cal(const struct rga_req *msg, TILE_INFO *tile) x_time = ((s_act_w - 1)<<16) / (d_act_w - 1); y_time = ((s_act_h - 1)<<16) / (d_act_h - 1); - + sina = msg->sina; cosa = msg->cosa; @@ -51,36 +51,36 @@ matrix_cal(const struct rga_req *msg, TILE_INFO *tile) /* 16.16 x 16.16 */ /* matrix[] is 64 bit wide */ case 1 : - tile->matrix[0] = cosa*x_time; - tile->matrix[1] = -sina*y_time; - tile->matrix[2] = sina*x_time; + tile->matrix[0] = cosa*x_time; + tile->matrix[1] = -sina*y_time; + tile->matrix[2] = sina*x_time; tile->matrix[3] = cosa*y_time; break; case 2 : - tile->matrix[0] = -(x_time<<16); - tile->matrix[1] = 0; - tile->matrix[2] = 0; + tile->matrix[0] = -(x_time<<16); + tile->matrix[1] = 0; + tile->matrix[2] = 0; tile->matrix[3] = (y_time<<16); break; case 3 : - tile->matrix[0] = (x_time<<16); - tile->matrix[1] = 0; - tile->matrix[2] = 0; + tile->matrix[0] = (x_time<<16); + tile->matrix[1] = 0; + tile->matrix[2] = 0; tile->matrix[3] = -(y_time<<16); break; default : - tile->matrix[0] = (uint64_t)1<<32; - tile->matrix[1] = 0; - tile->matrix[2] = 0; + tile->matrix[0] = (uint64_t)1<<32; + tile->matrix[1] = 0; + tile->matrix[2] = 0; tile->matrix[3] = (uint64_t)1<<32; - break; - } + break; + } } int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1) { - + struct rga_req *mp; uint32_t w_ratio, h_ratio; uint32_t stride; @@ -89,10 +89,10 @@ int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1) uint32_t pl; daw = dah = 0; - + mp = msg1; - if(msg->dst.act_w == 0) + if(msg->dst.act_w == 0) { printk("%s, [%d] rga dst act_w is zero\n", __FUNCTION__, __LINE__); return -EINVAL; @@ -105,57 +105,57 @@ int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1) } w_ratio = (msg->src.act_w << 16) / msg->dst.act_w; h_ratio = (msg->src.act_h << 16) / msg->dst.act_h; - + memcpy(msg1, msg, sizeof(struct rga_req)); msg->dst.format = msg->src.format; /*pre_scale_w cal*/ - if ((w_ratio >= (2<<16)) && (w_ratio < (4<<16))) { + if ((w_ratio >= (2<<16)) && (w_ratio < (4<<16))) { daw = (msg->src.act_w + 1) >> 1; if((IS_YUV_420(msg->dst.format)) && (daw & 1)) { daw -= 1; msg->src.act_w = daw << 1; - } + } } else if ((w_ratio >= (4<<16)) && (w_ratio < (8<<16))) { - daw = (msg->src.act_w + 3) >> 2; + daw = (msg->src.act_w + 3) >> 2; if((IS_YUV_420(msg->dst.format)) && (daw & 1)) { daw -= 1; - msg->src.act_w = daw << 2; + msg->src.act_w = daw << 2; } } else if ((w_ratio >= (8<<16)) && (w_ratio < (16<<16))) { daw = (msg->src.act_w + 7) >> 3; if((IS_YUV_420(msg->dst.format)) && (daw & 1)) { daw -= 1; - msg->src.act_w = daw << 3; + msg->src.act_w = daw << 3; } } else { daw = msg->src.act_w; } - + pl = (RGA_pixel_width_init(msg->src.format)); stride = (pl * daw + 3) & (~3); msg->dst.act_w = daw; msg->dst.vir_w = stride / pl; - /*pre_scale_h cal*/ - if ((h_ratio >= (2<<16)) && (h_ratio < (4<<16))) { + /*pre_scale_h cal*/ + if ((h_ratio >= (2<<16)) && (h_ratio < (4<<16))) { dah = (msg->src.act_h + 1) >> 1; if((IS_YUV(msg->dst.format)) && (dah & 1)) { dah -= 1; msg->src.act_h = dah << 1; - } + } } else if ((h_ratio >= (4<<16)) && (h_ratio < (8<<16))) { dah = (msg->src.act_h + 3) >> 2; if((IS_YUV(msg->dst.format)) && (dah & 1)) { dah -= 1; msg->src.act_h = dah << 2; - + } } else if ((h_ratio >= (8<<16)) && (h_ratio < (16<<16))) { @@ -169,14 +169,14 @@ int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1) { dah = msg->src.act_h; } - + msg->dst.act_h = dah; msg->dst.vir_h = dah; msg->dst.x_offset = 0; msg->dst.y_offset = 0; - - msg->dst.yrgb_addr = (u32)rga_service.pre_scale_buf; + + msg->dst.yrgb_addr = (unsigned long)rga_service.pre_scale_buf; msg->dst.uv_addr = msg->dst.yrgb_addr + stride * dah; msg->dst.v_addr = msg->dst.uv_addr + ((stride * dah) >> 1); @@ -193,7 +193,7 @@ int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1) msg1->src.x_offset = 0; msg1->src.y_offset = 0; - + return 0; } diff --git a/drivers/video/rockchip/rga/rga.h b/drivers/video/rockchip/rga/rga.h index 833837fe7a45..31ab69401b4a 100755 --- a/drivers/video/rockchip/rga/rga.h +++ b/drivers/video/rockchip/rga/rga.h @@ -117,10 +117,10 @@ enum typedef struct rga_img_info_t { - unsigned int yrgb_addr; /* yrgb mem addr */ - unsigned int uv_addr; /* cb/cr mem addr */ - unsigned int v_addr; /* cr mem addr */ - unsigned int format; //definition by RK_FORMAT + unsigned long yrgb_addr; /* yrgb mem addr */ + unsigned long uv_addr; /* cb/cr mem addr */ + unsigned long v_addr; /* cr mem addr */ + unsigned long format; //definition by RK_FORMAT unsigned short act_w; unsigned short act_h; @@ -181,7 +181,7 @@ typedef struct RGB typedef struct MMU { unsigned char mmu_en; - uint32_t base_addr; + unsigned long base_addr; uint32_t mmu_flag; /* [0] mmu enable [1] src_flush [2] dst_flush [3] CMD_flush [4~5] page size*/ } MMU; @@ -232,8 +232,8 @@ struct rga_req { rga_img_info_t dst; /* dst image info */ rga_img_info_t pat; /* patten image info */ - uint32_t rop_mask_addr; /* rop4 mask addr */ - uint32_t LUT_addr; /* LUT addr */ + unsigned long rop_mask_addr; /* rop4 mask addr */ + unsigned long LUT_addr; /* LUT addr */ RECT clip; /* dst clip window default value is dst_vir */ /* value from [0, w-1] / [0, h-1]*/ @@ -392,6 +392,7 @@ typedef struct rga_service_info { uint32_t cmd_buff[28*8];/* cmd_buff for rga */ uint32_t *pre_scale_buf; + unsigned long *pre_scale_buf_virtual; atomic_t int_disable; /* 0 int enable 1 int disable */ atomic_t cmd_num; atomic_t rga_working; diff --git a/drivers/video/rockchip/rga/rga_drv.c b/drivers/video/rockchip/rga/rga_drv.c index cba97beea1aa..d5857c9dac53 100755 --- a/drivers/video/rockchip/rga/rga_drv.c +++ b/drivers/video/rockchip/rga/rga_drv.c @@ -1,322 +1,323 @@ -/* - * Copyright (C) 2012 ROCKCHIP, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#define pr_fmt(fmt) "rga: " fmt -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_ION_ROCKCHIP) -#include -#endif - - -#include "rga.h" -#include "rga_reg_info.h" -#include "rga_mmu_info.h" -#include "RGA_API.h" - -#define RGA_TEST_CASE 0 - -#define RGA_TEST 0 -#define RGA_TEST_TIME 0 -#define RGA_TEST_FLUSH_TIME 0 -#define RGA_INFO_BUS_ERROR 1 - -#define PRE_SCALE_BUF_SIZE 2048*1024*4 - -#define RGA_POWER_OFF_DELAY 4*HZ /* 4s */ -#define RGA_TIMEOUT_DELAY 2*HZ /* 2s */ - -#define RGA_MAJOR 255 - -#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) -#define RK30_RGA_PHYS RK2928_RGA_PHYS -#define RK30_RGA_SIZE RK2928_RGA_SIZE -#endif -#define RGA_RESET_TIMEOUT 1000 - -/* Driver information */ -#define DRIVER_DESC "RGA Device Driver" -#define DRIVER_NAME "rga" - -#define RGA_VERSION "1.003" - -ktime_t rga_start; -ktime_t rga_end; - -rga_session rga_session_global; - -long (*rga_ioctl_kernel_p)(struct rga_req *); - - -struct rga_drvdata { - struct miscdevice miscdev; - struct device dev; - void *rga_base; - int irq; - - struct delayed_work power_off_work; - void (*rga_irq_callback)(int rga_retval); //callback function used by aync call - struct wake_lock wake_lock; - - struct clk *pd_rga; - struct clk *aclk_rga; - struct clk *hclk_rga; - - //#if defined(CONFIG_ION_ROCKCHIP) - struct ion_client * ion_client; - //#endif -}; - -static struct rga_drvdata *drvdata; -rga_service_info rga_service; -struct rga_mmu_buf_t rga_mmu_buf; - - -#if defined(CONFIG_ION_ROCKCHIP) -extern struct ion_client *rockchip_ion_client_create(const char * name); -#endif - -static int rga_blit_async(rga_session *session, struct rga_req *req); -static void rga_del_running_list(void); -static void rga_del_running_list_timeout(void); -static void rga_try_set_reg(void); - - -/* Logging */ -#define RGA_DEBUG 1 -#if RGA_DEBUG -#define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) -#define ERR(format, args...) printk(KERN_ERR "%s: " format, DRIVER_NAME, ## args) -#define WARNING(format, args...) printk(KERN_WARN "%s: " format, DRIVER_NAME, ## args) -#define INFO(format, args...) printk(KERN_INFO "%s: " format, DRIVER_NAME, ## args) -#else -#define DBG(format, args...) -#define ERR(format, args...) -#define WARNING(format, args...) -#define INFO(format, args...) -#endif - -#if RGA_TEST -static void print_info(struct rga_req *req) -{ - printk("src : yrgb_addr = %.8x, src.uv_addr = %.8x, src.v_addr = %.8x, format = %d\n", - req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, req->src.format); - printk("src : act_w = %d, act_h = %d, vir_w = %d, vir_h = %d\n", - req->src.act_w, req->src.act_h, req->src.vir_w, req->src.vir_h); - printk("src : x_off = %.8x y_off = %.8x\n", req->src.x_offset, req->src.y_offset); - - printk("dst : yrgb_addr = %.8x, dst.uv_addr = %.8x, dst.v_addr = %.8x, format = %d\n", - req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, req->dst.format); - printk("dst : x_off = %.8x y_off = %.8x\n", req->dst.x_offset, req->dst.y_offset); - printk("dst : act_w = %d, act_h = %d, vir_w = %d, vir_h = %d\n", - req->dst.act_w, req->dst.act_h, req->dst.vir_w, req->dst.vir_h); - - printk("clip.xmin = %d, clip.xmax = %d. clip.ymin = %d, clip.ymax = %d\n", - req->clip.xmin, req->clip.xmax, req->clip.ymin, req->clip.ymax); - - printk("mmu_flag = %.8x\n", req->mmu_info.mmu_flag); - - //printk("alpha_rop_flag = %.8x\n", req->alpha_rop_flag); - //printk("alpha_rop_mode = %.8x\n", req->alpha_rop_mode); - //printk("PD_mode = %.8x\n", req->PD_mode); -} -#endif - - -static inline void rga_write(u32 b, u32 r) -{ - __raw_writel(b, drvdata->rga_base + r); -} - -static inline u32 rga_read(u32 r) -{ - return __raw_readl(drvdata->rga_base + r); -} - -static void rga_soft_reset(void) -{ - u32 i; - u32 reg; - - rga_write(1, RGA_SYS_CTRL); //RGA_SYS_CTRL - - for(i = 0; i < RGA_RESET_TIMEOUT; i++) - { - reg = rga_read(RGA_SYS_CTRL) & 1; //RGA_SYS_CTRL - - if(reg == 0) - break; - - udelay(1); - } - - if(i == RGA_RESET_TIMEOUT) - ERR("soft reset timeout.\n"); -} - -static void rga_dump(void) -{ - int running; - struct rga_reg *reg, *reg_tmp; - rga_session *session, *session_tmp; - - running = atomic_read(&rga_service.total_running); - printk("rga total_running %d\n", running); - - #if 0 - - /* Dump waiting list info */ - if (!list_empty(&rga_service.waiting)) - { - list_head *next; +/* + * Copyright (C) 2012 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#define pr_fmt(fmt) "rga: " fmt +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_ION_ROCKCHIP) +#include +#endif + + +#include "rga.h" +#include "rga_reg_info.h" +#include "rga_mmu_info.h" +#include "RGA_API.h" + +#define RGA_TEST_CASE 0 + +#define RGA_TEST 0 +#define RGA_TEST_TIME 0 +#define RGA_TEST_FLUSH_TIME 0 +#define RGA_INFO_BUS_ERROR 1 + +#define PRE_SCALE_BUF_SIZE 2048*1024*4 + +#define RGA_POWER_OFF_DELAY 4*HZ /* 4s */ +#define RGA_TIMEOUT_DELAY 2*HZ /* 2s */ + +#define RGA_MAJOR 255 + +#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) +#define RK30_RGA_PHYS RK2928_RGA_PHYS +#define RK30_RGA_SIZE RK2928_RGA_SIZE +#endif +#define RGA_RESET_TIMEOUT 1000 + +/* Driver information */ +#define DRIVER_DESC "RGA Device Driver" +#define DRIVER_NAME "rga" + +#define RGA_VERSION "1.003" + +ktime_t rga_start; +ktime_t rga_end; + +rga_session rga_session_global; + +long (*rga_ioctl_kernel_p)(struct rga_req *); + + +struct rga_drvdata { + struct miscdevice miscdev; + struct device dev; + void *rga_base; + int irq; + + struct delayed_work power_off_work; + void (*rga_irq_callback)(int rga_retval); //callback function used by aync call + struct wake_lock wake_lock; + + struct clk *pd_rga; + struct clk *aclk_rga; + struct clk *hclk_rga; + + //#if defined(CONFIG_ION_ROCKCHIP) + struct ion_client * ion_client; + //#endif +}; + +static struct rga_drvdata *drvdata; +rga_service_info rga_service; +struct rga_mmu_buf_t rga_mmu_buf; + + +#if defined(CONFIG_ION_ROCKCHIP) +extern struct ion_client *rockchip_ion_client_create(const char * name); +#endif + +static int rga_blit_async(rga_session *session, struct rga_req *req); +static void rga_del_running_list(void); +static void rga_del_running_list_timeout(void); +static void rga_try_set_reg(void); + + +/* Logging */ +#define RGA_DEBUG 1 +#if RGA_DEBUG +#define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) +#define ERR(format, args...) printk(KERN_ERR "%s: " format, DRIVER_NAME, ## args) +#define WARNING(format, args...) printk(KERN_WARN "%s: " format, DRIVER_NAME, ## args) +#define INFO(format, args...) printk(KERN_INFO "%s: " format, DRIVER_NAME, ## args) +#else +#define DBG(format, args...) +#define ERR(format, args...) +#define WARNING(format, args...) +#define INFO(format, args...) +#endif + +#if RGA_TEST +static void print_info(struct rga_req *req) +{ + printk("src : yrgb_addr = %.8x, src.uv_addr = %.8x, src.v_addr = %.8x, format = %d\n", + req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, req->src.format); + printk("src : act_w = %d, act_h = %d, vir_w = %d, vir_h = %d\n", + req->src.act_w, req->src.act_h, req->src.vir_w, req->src.vir_h); + printk("src : x_off = %.8x y_off = %.8x\n", req->src.x_offset, req->src.y_offset); + + printk("dst : yrgb_addr = %.8x, dst.uv_addr = %.8x, dst.v_addr = %.8x, format = %d\n", + req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, req->dst.format); + printk("dst : x_off = %.8x y_off = %.8x\n", req->dst.x_offset, req->dst.y_offset); + printk("dst : act_w = %d, act_h = %d, vir_w = %d, vir_h = %d\n", + req->dst.act_w, req->dst.act_h, req->dst.vir_w, req->dst.vir_h); + + printk("clip.xmin = %d, clip.xmax = %d. clip.ymin = %d, clip.ymax = %d\n", + req->clip.xmin, req->clip.xmax, req->clip.ymin, req->clip.ymax); + + printk("mmu_flag = %.8x\n", req->mmu_info.mmu_flag); + + //printk("alpha_rop_flag = %.8x\n", req->alpha_rop_flag); + //printk("alpha_rop_mode = %.8x\n", req->alpha_rop_mode); + //printk("PD_mode = %.8x\n", req->PD_mode); +} +#endif + + +static inline void rga_write(u32 b, u32 r) +{ + __raw_writel(b, drvdata->rga_base + r); +} + +static inline u32 rga_read(u32 r) +{ + return __raw_readl(drvdata->rga_base + r); +} + +static void rga_soft_reset(void) +{ + u32 i; + u32 reg; + + rga_write(1, RGA_SYS_CTRL); //RGA_SYS_CTRL + + for(i = 0; i < RGA_RESET_TIMEOUT; i++) + { + reg = rga_read(RGA_SYS_CTRL) & 1; //RGA_SYS_CTRL + + if(reg == 0) + break; + + udelay(1); + } + + if(i == RGA_RESET_TIMEOUT) + ERR("soft reset timeout.\n"); +} + +static void rga_dump(void) +{ + int running; + struct rga_reg *reg, *reg_tmp; + rga_session *session, *session_tmp; + + running = atomic_read(&rga_service.total_running); + printk("rga total_running %d\n", running); + + #if 0 + + /* Dump waiting list info */ + if (!list_empty(&rga_service.waiting)) + { + list_head *next; + + next = &rga_service.waiting; + + printk("rga_service dump waiting list\n"); + + do + { + reg = list_entry(next->next, struct rga_reg, status_link); + running = atomic_read(®->session->task_running); + num_done = atomic_read(®->session->num_done); + printk("rga session pid %d, done %d, running %d\n", reg->session->pid, num_done, running); + next = next->next; + } + while(!list_empty(next)); + } + + /* Dump running list info */ + if (!list_empty(&rga_service.running)) + { + printk("rga_service dump running list\n"); + + list_head *next; + + next = &rga_service.running; + do + { + reg = list_entry(next->next, struct rga_reg, status_link); + running = atomic_read(®->session->task_running); + num_done = atomic_read(®->session->num_done); + printk("rga session pid %d, done %d, running %d:\n", reg->session->pid, num_done, running); + next = next->next; + } + while(!list_empty(next)); + } + #endif + + list_for_each_entry_safe(session, session_tmp, &rga_service.session, list_session) + { + printk("session pid %d:\n", session->pid); + running = atomic_read(&session->task_running); + printk("task_running %d\n", running); + list_for_each_entry_safe(reg, reg_tmp, &session->waiting, session_link) + { + printk("waiting register set 0x%.lu\n", (unsigned long)reg); + } + list_for_each_entry_safe(reg, reg_tmp, &session->running, session_link) + { + printk("running register set 0x%.lu\n", (unsigned long)reg); + } + } +} + +static inline void rga_queue_power_off_work(void) +{ + queue_delayed_work(system_nrt_wq, &drvdata->power_off_work, RGA_POWER_OFF_DELAY); +} + +/* Caller must hold rga_service.lock */ +static void rga_power_on(void) +{ + static ktime_t last; + ktime_t now = ktime_get(); + + if (ktime_to_ns(ktime_sub(now, last)) > NSEC_PER_SEC) { + cancel_delayed_work_sync(&drvdata->power_off_work); + rga_queue_power_off_work(); + last = now; + } + if (rga_service.enable) + return; + + clk_prepare_enable(drvdata->aclk_rga); + clk_prepare_enable(drvdata->hclk_rga); + //clk_prepare_enable(drvdata->pd_rga); + wake_lock(&drvdata->wake_lock); + rga_service.enable = true; +} + +/* Caller must hold rga_service.lock */ +static void rga_power_off(void) +{ + int total_running; + + if (!rga_service.enable) { + return; + } + + total_running = atomic_read(&rga_service.total_running); + if (total_running) { + pr_err("power off when %d task running!!\n", total_running); + mdelay(50); + pr_err("delay 50 ms for running task\n"); + rga_dump(); + } + + //clk_disable_unprepare(drvdata->pd_rga); + clk_disable_unprepare(drvdata->aclk_rga); + clk_disable_unprepare(drvdata->hclk_rga); + wake_unlock(&drvdata->wake_lock); + rga_service.enable = false; +} + +static void rga_power_off_work(struct work_struct *work) +{ + if (mutex_trylock(&rga_service.lock)) { + rga_power_off(); + mutex_unlock(&rga_service.lock); + } else { + /* Come back later if the device is busy... */ - next = &rga_service.waiting; - - printk("rga_service dump waiting list\n"); - - do - { - reg = list_entry(next->next, struct rga_reg, status_link); - running = atomic_read(®->session->task_running); - num_done = atomic_read(®->session->num_done); - printk("rga session pid %d, done %d, running %d\n", reg->session->pid, num_done, running); - next = next->next; - } - while(!list_empty(next)); - } - - /* Dump running list info */ - if (!list_empty(&rga_service.running)) - { - printk("rga_service dump running list\n"); - - list_head *next; - - next = &rga_service.running; - do - { - reg = list_entry(next->next, struct rga_reg, status_link); - running = atomic_read(®->session->task_running); - num_done = atomic_read(®->session->num_done); - printk("rga session pid %d, done %d, running %d:\n", reg->session->pid, num_done, running); - next = next->next; - } - while(!list_empty(next)); - } - #endif - - list_for_each_entry_safe(session, session_tmp, &rga_service.session, list_session) - { - printk("session pid %d:\n", session->pid); - running = atomic_read(&session->task_running); - printk("task_running %d\n", running); - list_for_each_entry_safe(reg, reg_tmp, &session->waiting, session_link) - { - printk("waiting register set 0x%.8x\n", (unsigned int)reg); - } - list_for_each_entry_safe(reg, reg_tmp, &session->running, session_link) - { - printk("running register set 0x%.8x\n", (unsigned int)reg); - } - } -} - -static inline void rga_queue_power_off_work(void) -{ - queue_delayed_work(system_nrt_wq, &drvdata->power_off_work, RGA_POWER_OFF_DELAY); -} - -/* Caller must hold rga_service.lock */ -static void rga_power_on(void) -{ - static ktime_t last; - ktime_t now = ktime_get(); - - if (ktime_to_ns(ktime_sub(now, last)) > NSEC_PER_SEC) { - cancel_delayed_work_sync(&drvdata->power_off_work); - rga_queue_power_off_work(); - last = now; - } - if (rga_service.enable) - return; - - clk_prepare_enable(drvdata->aclk_rga); - clk_prepare_enable(drvdata->hclk_rga); - //clk_prepare_enable(drvdata->pd_rga); - wake_lock(&drvdata->wake_lock); - rga_service.enable = true; -} - -/* Caller must hold rga_service.lock */ -static void rga_power_off(void) -{ - int total_running; - - if (!rga_service.enable) { - return; - } - - total_running = atomic_read(&rga_service.total_running); - if (total_running) { - pr_err("power off when %d task running!!\n", total_running); - mdelay(50); - pr_err("delay 50 ms for running task\n"); - rga_dump(); - } - - //clk_disable_unprepare(drvdata->pd_rga); - clk_disable_unprepare(drvdata->aclk_rga); - clk_disable_unprepare(drvdata->hclk_rga); - wake_unlock(&drvdata->wake_lock); - rga_service.enable = false; -} - -static void rga_power_off_work(struct work_struct *work) -{ - if (mutex_trylock(&rga_service.lock)) { - rga_power_off(); - mutex_unlock(&rga_service.lock); - } else { - /* Come back later if the device is busy... */ rga_queue_power_off_work(); } } @@ -449,12 +450,9 @@ static void rga_copy_reg(struct rga_reg *reg, uint32_t offset) cmd_buf = (uint32_t *)rga_service.cmd_buff + offset*32; reg_p = (uint32_t *)reg->cmd_reg; - for(i=0; i<32; i++) - { + for(i=0; i<32; i++) cmd_buf[i] = reg_p[i]; - } - - dsb(); + } @@ -635,9 +633,13 @@ static void rga_try_set_reg(void) rga_copy_reg(reg, 0); rga_reg_from_wait_to_run(reg); - + + #ifdef CONFIG_ARM dmac_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[28]); - outer_flush_range(virt_to_phys(&rga_service.cmd_buff[0]),virt_to_phys(&rga_service.cmd_buff[28])); + outer_flush_range(virt_to_phys(&rga_service.cmd_buff[0]),virt_to_phys(&rga_service.cmd_buff[28])); + #elif defined(CONFIG_ARM64) + __dma_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[28]); + #endif #if defined(CONFIG_ARCH_RK30) rga_soft_reset(); @@ -816,7 +818,7 @@ static int rga_convert_dma_buf(struct rga_req *req) req->sg_src = NULL; req->sg_dst = NULL; - + src_offset = req->line_draw_info.flag; dst_offset = req->line_draw_info.line_width; @@ -1282,317 +1284,321 @@ static int rga_drv_probe(struct platform_device *pdev) } else { dev_info(&pdev->dev, "rga ion client create success!\n"); } - #endif - - ret = misc_register(&rga_dev); - if(ret) - { - ERR("cannot register miscdev (%d)\n", ret); - goto err_misc_register; - } - - pr_info("Driver loaded succesfully\n"); - - return 0; - -err_misc_register: - free_irq(data->irq, pdev); -err_irq: - iounmap(data->rga_base); -err_ioremap: - wake_lock_destroy(&data->wake_lock); - //kfree(data); - - return ret; -} - -static int rga_drv_remove(struct platform_device *pdev) -{ - struct rga_drvdata *data = platform_get_drvdata(pdev); - DBG("%s [%d]\n",__FUNCTION__,__LINE__); - - wake_lock_destroy(&data->wake_lock); - misc_deregister(&(data->miscdev)); - free_irq(data->irq, &data->miscdev); - iounmap((void __iomem *)(data->rga_base)); - - //clk_put(data->pd_rga); - devm_clk_put(&pdev->dev, data->aclk_rga); - devm_clk_put(&pdev->dev, data->hclk_rga); - - //kfree(data); - return 0; -} - -static struct platform_driver rga_driver = { - .probe = rga_drv_probe, - .remove = rga_drv_remove, - .driver = { - .owner = THIS_MODULE, - .name = "rga", - .of_match_table = of_match_ptr(rockchip_rga_dt_ids), - }, -}; - - -void rga_test_0(void); -void rga_test_1(void); - - -static int __init rga_init(void) -{ - int ret; - uint32_t *mmu_buf; - uint32_t i; - uint32_t *buf_p; - - /* malloc pre scale mid buf mmu table */ - mmu_buf = kzalloc(1024*8, GFP_KERNEL); - if(mmu_buf == NULL) { - printk(KERN_ERR "RGA get Pre Scale buff failed. \n"); - return -1; - } - - /* malloc 4 M buf */ - for(i=0; i<1024; i++) { - buf_p = (uint32_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO); - if(buf_p == NULL) { - printk(KERN_ERR "RGA init pre scale buf falied\n"); - return -ENOMEM; - } - mmu_buf[i] = virt_to_phys((void *)((uint32_t)buf_p)); - } - - rga_service.pre_scale_buf = (uint32_t *)mmu_buf; - - buf_p = kmalloc(1024*256, GFP_KERNEL); - rga_mmu_buf.buf_virtual = buf_p; - rga_mmu_buf.buf = (uint32_t *)virt_to_phys((void *)((uint32_t)buf_p)); - rga_mmu_buf.front = 0; - rga_mmu_buf.back = 64*1024; - rga_mmu_buf.size = 64*1024; - - rga_mmu_buf.pages = kmalloc((32768)* sizeof(struct page *), GFP_KERNEL); - - if ((ret = platform_driver_register(&rga_driver)) != 0) - { - printk(KERN_ERR "Platform device register failed (%d).\n", ret); - return ret; - } - - { - rga_session_global.pid = 0x0000ffff; - INIT_LIST_HEAD(&rga_session_global.waiting); - INIT_LIST_HEAD(&rga_session_global.running); - INIT_LIST_HEAD(&rga_session_global.list_session); - - INIT_LIST_HEAD(&rga_service.waiting); - INIT_LIST_HEAD(&rga_service.running); - INIT_LIST_HEAD(&rga_service.done); - INIT_LIST_HEAD(&rga_service.session); - - init_waitqueue_head(&rga_session_global.wait); - //mutex_lock(&rga_service.lock); - list_add_tail(&rga_session_global.list_session, &rga_service.session); - //mutex_unlock(&rga_service.lock); - atomic_set(&rga_session_global.task_running, 0); - atomic_set(&rga_session_global.num_done, 0); - } - - - - #if RGA_TEST_CASE - rga_test_0(); - #endif - - INFO("Module initialized.\n"); - - return 0; -} - -static void __exit rga_exit(void) -{ - uint32_t i; - - rga_power_off(); - - for(i=0; i<1024; i++) - { - if((uint32_t *)rga_service.pre_scale_buf[i] != NULL) - { - __free_page((void *)rga_service.pre_scale_buf[i]); - } - } - - if(rga_service.pre_scale_buf != NULL) { - kfree((uint8_t *)rga_service.pre_scale_buf); - } - - if (rga_mmu_buf.buf_virtual) - kfree(rga_mmu_buf.buf_virtual); - - if (rga_mmu_buf.pages) - kfree(rga_mmu_buf.pages); - - platform_driver_unregister(&rga_driver); -} - - -#if RGA_TEST_CASE - -extern struct fb_info * rk_get_fb(int fb_id); -EXPORT_SYMBOL(rk_get_fb); - -extern void rk_direct_fb_show(struct fb_info * fbi); -EXPORT_SYMBOL(rk_direct_fb_show); - -unsigned int src_buf[1920*1080]; -unsigned int dst_buf[1920*1080]; -//unsigned int tmp_buf[1920*1080 * 2]; - -void rga_test_0(void) -{ - struct rga_req req; - rga_session session; - unsigned int *src, *dst; - uint32_t i, j; - uint8_t *p; - uint8_t t; - uint32_t *dst0, *dst1, *dst2; - - struct fb_info *fb; - - session.pid = current->pid; - INIT_LIST_HEAD(&session.waiting); - INIT_LIST_HEAD(&session.running); - INIT_LIST_HEAD(&session.list_session); - init_waitqueue_head(&session.wait); - /* no need to protect */ - list_add_tail(&session.list_session, &rga_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 rga_req)); - src = src_buf; - dst = dst_buf; - - memset(src_buf, 0x80, 1024*600*4); - - dmac_flush_range(&src_buf[0], &src_buf[1024*600]); - outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[1024*600])); - - - #if 0 - memset(src_buf, 0x80, 800*480*4); - memset(dst_buf, 0xcc, 800*480*4); - - 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])); - #endif - - dst0 = &dst_buf[0]; - //dst1 = &dst_buf[1280*800*4]; - //dst2 = &dst_buf[1280*800*4*2]; - - i = j = 0; - - printk("\n********************************\n"); - printk("************ RGA_TEST ************\n"); - printk("********************************\n\n"); - - req.src.act_w = 1024; - req.src.act_h = 600; - - req.src.vir_w = 1024; - req.src.vir_h = 600; - req.src.yrgb_addr = (uint32_t)virt_to_phys(src); - req.src.uv_addr = (uint32_t)(req.src.yrgb_addr + 1080*1920); - req.src.v_addr = (uint32_t)virt_to_phys(src); - req.src.format = RK_FORMAT_RGBA_8888; - - req.dst.act_w = 600; - req.dst.act_h = 352; - - req.dst.vir_w = 1280; - req.dst.vir_h = 800; - req.dst.x_offset = 600; - req.dst.y_offset = 0; - - dst = dst0; - - req.dst.yrgb_addr = ((uint32_t)virt_to_phys(dst)); - - //req.dst.format = RK_FORMAT_RGB_565; - - req.clip.xmin = 0; - req.clip.xmax = 1279; - req.clip.ymin = 0; - req.clip.ymax = 799; - - //req.render_mode = color_fill_mode; - //req.fg_color = 0x80ffffff; - - req.rotate_mode = 1; - //req.scale_mode = 2; - - //req.alpha_rop_flag = 0; - //req.alpha_rop_mode = 0x19; - //req.PD_mode = 3; - - req.sina = 65536; - req.cosa = 0; - - //req.mmu_info.mmu_flag = 0x21; - //req.mmu_info.mmu_en = 1; - - //printk("src = %.8x\n", req.src.yrgb_addr); - //printk("src = %.8x\n", req.src.uv_addr); - //printk("dst = %.8x\n", req.dst.yrgb_addr); - - - rga_blit_sync(&session, &req); - - #if 1 - fb->var.bits_per_pixel = 32; - - fb->var.xres = 1280; - fb->var.yres = 800; - - fb->var.red.length = 8; - fb->var.red.offset = 0; - fb->var.red.msb_right = 0; - - fb->var.green.length = 8; - fb->var.green.offset = 8; - fb->var.green.msb_right = 0; - - fb->var.blue.length = 8; - - fb->var.blue.offset = 16; - fb->var.blue.msb_right = 0; - - fb->var.transp.length = 8; - fb->var.transp.offset = 24; - fb->var.transp.msb_right = 0; - - fb->var.nonstd &= (~0xff); - fb->var.nonstd |= 1; - - fb->fix.smem_start = virt_to_phys(dst); - - rk_direct_fb_show(fb); - #endif - -} - -#endif -module_init(rga_init); -module_exit(rga_exit); - -/* Module information */ -MODULE_AUTHOR("zsq@rock-chips.com"); -MODULE_DESCRIPTION("Driver for rga device"); -MODULE_LICENSE("GPL"); + #endif + + ret = misc_register(&rga_dev); + if(ret) + { + ERR("cannot register miscdev (%d)\n", ret); + goto err_misc_register; + } + + pr_info("Driver loaded succesfully\n"); + + return 0; + +err_misc_register: + free_irq(data->irq, pdev); +err_irq: + iounmap(data->rga_base); +err_ioremap: + wake_lock_destroy(&data->wake_lock); + //kfree(data); + + return ret; +} + +static int rga_drv_remove(struct platform_device *pdev) +{ + struct rga_drvdata *data = platform_get_drvdata(pdev); + DBG("%s [%d]\n",__FUNCTION__,__LINE__); + + wake_lock_destroy(&data->wake_lock); + misc_deregister(&(data->miscdev)); + free_irq(data->irq, &data->miscdev); + iounmap((void __iomem *)(data->rga_base)); + + //clk_put(data->pd_rga); + devm_clk_put(&pdev->dev, data->aclk_rga); + devm_clk_put(&pdev->dev, data->hclk_rga); + + //kfree(data); + return 0; +} + +static struct platform_driver rga_driver = { + .probe = rga_drv_probe, + .remove = rga_drv_remove, + .driver = { + .owner = THIS_MODULE, + .name = "rga", + .of_match_table = of_match_ptr(rockchip_rga_dt_ids), + }, +}; + + +void rga_test_0(void); +void rga_test_1(void); + + +static int __init rga_init(void) +{ + int ret; + uint32_t *mmu_buf; + unsigned long *mmu_buf_virtual; + uint32_t i; + uint32_t *buf_p; + + /* malloc pre scale mid buf mmu table */ + mmu_buf = kzalloc(1024*8, GFP_KERNEL); + mmu_buf_virtual = kzalloc(1024*2*sizeof(unsigned long), GFP_KERNEL); + if(mmu_buf == NULL) { + printk(KERN_ERR "RGA get Pre Scale buff failed. \n"); + return -1; + } + + /* malloc 4 M buf */ + for(i=0; i<1024; i++) { + buf_p = (uint32_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO); + if(buf_p == NULL) { + printk(KERN_ERR "RGA init pre scale buf falied\n"); + return -ENOMEM; + } + mmu_buf[i] = virt_to_phys((void *)((unsigned long)buf_p)); + mmu_buf_virtual[i] = (unsigned long)buf_p; + } + + rga_service.pre_scale_buf = (uint32_t *)mmu_buf; + rga_service.pre_scale_buf_virtual = (unsigned long *)mmu_buf_virtual; + + buf_p = kmalloc(1024*256, GFP_KERNEL); + rga_mmu_buf.buf_virtual = buf_p; + rga_mmu_buf.buf = (uint32_t *)virt_to_phys((void *)((unsigned long)buf_p)); + rga_mmu_buf.front = 0; + rga_mmu_buf.back = 64*1024; + rga_mmu_buf.size = 64*1024; + + rga_mmu_buf.pages = kmalloc((32768)* sizeof(struct page *), GFP_KERNEL); + + if ((ret = platform_driver_register(&rga_driver)) != 0) + { + printk(KERN_ERR "Platform device register failed (%d).\n", ret); + return ret; + } + + { + rga_session_global.pid = 0x0000ffff; + INIT_LIST_HEAD(&rga_session_global.waiting); + INIT_LIST_HEAD(&rga_session_global.running); + INIT_LIST_HEAD(&rga_session_global.list_session); + + INIT_LIST_HEAD(&rga_service.waiting); + INIT_LIST_HEAD(&rga_service.running); + INIT_LIST_HEAD(&rga_service.done); + INIT_LIST_HEAD(&rga_service.session); + + init_waitqueue_head(&rga_session_global.wait); + //mutex_lock(&rga_service.lock); + list_add_tail(&rga_session_global.list_session, &rga_service.session); + //mutex_unlock(&rga_service.lock); + atomic_set(&rga_session_global.task_running, 0); + atomic_set(&rga_session_global.num_done, 0); + } + + + + #if RGA_TEST_CASE + rga_test_0(); + #endif + + INFO("Module initialized.\n"); + + return 0; +} + +static void __exit rga_exit(void) +{ + uint32_t i; + + rga_power_off(); + + for(i=0; i<1024; i++) + { + if((unsigned long)rga_service.pre_scale_buf_virtual[i]) + { + __free_page((void *)rga_service.pre_scale_buf_virtual[i]); + } + } + + if(rga_service.pre_scale_buf != NULL) { + kfree((uint8_t *)rga_service.pre_scale_buf); + } + + if (rga_mmu_buf.buf_virtual) + kfree(rga_mmu_buf.buf_virtual); + + if (rga_mmu_buf.pages) + kfree(rga_mmu_buf.pages); + + platform_driver_unregister(&rga_driver); +} + + +#if RGA_TEST_CASE + +extern struct fb_info * rk_get_fb(int fb_id); +EXPORT_SYMBOL(rk_get_fb); + +extern void rk_direct_fb_show(struct fb_info * fbi); +EXPORT_SYMBOL(rk_direct_fb_show); + +unsigned int src_buf[1920*1080]; +unsigned int dst_buf[1920*1080]; +//unsigned int tmp_buf[1920*1080 * 2]; + +void rga_test_0(void) +{ + struct rga_req req; + rga_session session; + unsigned int *src, *dst; + uint32_t i, j; + uint8_t *p; + uint8_t t; + uint32_t *dst0, *dst1, *dst2; + + struct fb_info *fb; + + session.pid = current->pid; + INIT_LIST_HEAD(&session.waiting); + INIT_LIST_HEAD(&session.running); + INIT_LIST_HEAD(&session.list_session); + init_waitqueue_head(&session.wait); + /* no need to protect */ + list_add_tail(&session.list_session, &rga_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 rga_req)); + src = src_buf; + dst = dst_buf; + + memset(src_buf, 0x80, 1024*600*4); + + dmac_flush_range(&src_buf[0], &src_buf[1024*600]); + outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[1024*600])); + + + #if 0 + memset(src_buf, 0x80, 800*480*4); + memset(dst_buf, 0xcc, 800*480*4); + + 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])); + #endif + + dst0 = &dst_buf[0]; + //dst1 = &dst_buf[1280*800*4]; + //dst2 = &dst_buf[1280*800*4*2]; + + i = j = 0; + + printk("\n********************************\n"); + printk("************ RGA_TEST ************\n"); + printk("********************************\n\n"); + + req.src.act_w = 1024; + req.src.act_h = 600; + + req.src.vir_w = 1024; + req.src.vir_h = 600; + req.src.yrgb_addr = (uint32_t)virt_to_phys(src); + req.src.uv_addr = (uint32_t)(req.src.yrgb_addr + 1080*1920); + req.src.v_addr = (uint32_t)virt_to_phys(src); + req.src.format = RK_FORMAT_RGBA_8888; + + req.dst.act_w = 600; + req.dst.act_h = 352; + + req.dst.vir_w = 1280; + req.dst.vir_h = 800; + req.dst.x_offset = 600; + req.dst.y_offset = 0; + + dst = dst0; + + req.dst.yrgb_addr = ((uint32_t)virt_to_phys(dst)); + + //req.dst.format = RK_FORMAT_RGB_565; + + req.clip.xmin = 0; + req.clip.xmax = 1279; + req.clip.ymin = 0; + req.clip.ymax = 799; + + //req.render_mode = color_fill_mode; + //req.fg_color = 0x80ffffff; + + req.rotate_mode = 1; + //req.scale_mode = 2; + + //req.alpha_rop_flag = 0; + //req.alpha_rop_mode = 0x19; + //req.PD_mode = 3; + + req.sina = 65536; + req.cosa = 0; + + //req.mmu_info.mmu_flag = 0x21; + //req.mmu_info.mmu_en = 1; + + //printk("src = %.8x\n", req.src.yrgb_addr); + //printk("src = %.8x\n", req.src.uv_addr); + //printk("dst = %.8x\n", req.dst.yrgb_addr); + + + rga_blit_sync(&session, &req); + + #if 1 + fb->var.bits_per_pixel = 32; + + fb->var.xres = 1280; + fb->var.yres = 800; + + fb->var.red.length = 8; + fb->var.red.offset = 0; + fb->var.red.msb_right = 0; + + fb->var.green.length = 8; + fb->var.green.offset = 8; + fb->var.green.msb_right = 0; + + fb->var.blue.length = 8; + + fb->var.blue.offset = 16; + fb->var.blue.msb_right = 0; + + fb->var.transp.length = 8; + fb->var.transp.offset = 24; + fb->var.transp.msb_right = 0; + + fb->var.nonstd &= (~0xff); + fb->var.nonstd |= 1; + + fb->fix.smem_start = virt_to_phys(dst); + + rk_direct_fb_show(fb); + #endif + +} + +#endif +module_init(rga_init); +module_exit(rga_exit); + +/* Module information */ +MODULE_AUTHOR("zsq@rock-chips.com"); +MODULE_DESCRIPTION("Driver for rga device"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/rockchip/rga/rga_mmu_info.c b/drivers/video/rockchip/rga/rga_mmu_info.c index 56f2110bed2c..c0b999dd6bf6 100755 --- a/drivers/video/rockchip/rga/rga_mmu_info.c +++ b/drivers/video/rockchip/rga/rga_mmu_info.c @@ -57,9 +57,9 @@ static int rga_mmu_buf_get_try(struct rga_mmu_buf_t *t, uint32_t size) return 0; } -static int rga_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr) +static int rga_mem_size_cal(unsigned long Mem, uint32_t MemSize, unsigned long *StartAddr) { - uint32_t start, end; + unsigned long start, end; uint32_t pageCount; end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT; @@ -69,14 +69,14 @@ static int rga_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr) return pageCount; } -static int rga_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_addr, - int format, uint32_t w, uint32_t h, uint32_t *StartAddr ) +static int rga_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, unsigned long v_addr, + int format, uint32_t w, uint32_t h, unsigned long *StartAddr ) { uint32_t size_yrgb = 0; uint32_t size_uv = 0; uint32_t size_v = 0; uint32_t stride = 0; - uint32_t start, end; + unsigned long start, end; uint32_t pageCount; switch(format) @@ -239,20 +239,18 @@ static int rga_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_add static int rga_MapUserMemory(struct page **pages, uint32_t *pageTable, - uint32_t Memory, + unsigned long Memory, uint32_t pageCount) { int32_t result; uint32_t i; uint32_t status; - uint32_t Address; - //uint32_t temp; + unsigned long Address; status = 0; Address = 0; - do - { + do { down_read(¤t->mm->mmap_sem); result = get_user_pages(current, current->mm, @@ -387,7 +385,7 @@ static int rga_MapION(struct sg_table *sg, { uint32_t i; uint32_t status; - uint32_t Address; + unsigned long Address; uint32_t mapped_size = 0; uint32_t len = 0; struct scatterlist *sgl = sg->sgl; @@ -463,7 +461,7 @@ static int rga_MapION(struct sg_table *sg, static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) { int SrcMemSize, DstMemSize; - uint32_t SrcStart, DstStart; + unsigned long SrcStart, DstStart; uint32_t i; uint32_t AllSize; uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; @@ -529,7 +527,7 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) else { MMU_p = MMU_Base; - if(req->src.yrgb_addr == (uint32_t)rga_service.pre_scale_buf) { + if(req->src.yrgb_addr == (unsigned long)rga_service.pre_scale_buf) { for(i=0; immu_info.base_addr = (uint32_t)MMU_Base_phys >> 2; + req->mmu_info.base_addr = (unsigned long)MMU_Base_phys >> 2; uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; @@ -579,8 +577,12 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); outer_flush_range(virt_to_phys(MMU_Base), virt_to_phys(MMU_Base + AllSize + 1)); + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); + #endif rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); reg->MMU_len = AllSize + 16; @@ -597,7 +599,7 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *req) { int SrcMemSize, DstMemSize, CMDMemSize; - uint32_t SrcStart, DstStart, CMDStart; + unsigned long SrcStart, DstStart, CMDStart; struct page **pages = NULL; uint32_t i; uint32_t AllSize; @@ -627,7 +629,7 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req * return -EINVAL; } - CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); if(CMDMemSize == 0) { return -EINVAL; } @@ -653,7 +655,7 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req * /* map CMD addr */ for(i=0; iMMU_base = MMU_Base; /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); + #endif rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); reg->MMU_len = AllSize + 16; @@ -719,7 +725,7 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req * static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req) { int DstMemSize; - uint32_t DstStart; + unsigned long DstStart; struct page **pages = NULL; uint32_t i; uint32_t AllSize; @@ -729,8 +735,7 @@ static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req MMU_Base = NULL; - do - { + do { DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, req->dst.format, req->dst.vir_w, req->dst.vir_h, &DstStart); @@ -778,15 +783,19 @@ static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req * change the buf address in req struct */ - req->mmu_info.base_addr = ((uint32_t)(MMU_Base_phys)>>2); + req->mmu_info.base_addr = ((unsigned long)(MMU_Base_phys)>>2); req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)); /*record the malloc buf for the cmd end to release*/ reg->MMU_base = MMU_Base; /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); + #endif rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); reg->MMU_len = AllSize + 16; @@ -801,229 +810,12 @@ static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req) { - int DstMemSize; - uint32_t DstStart; - struct page **pages = NULL; - uint32_t i; - uint32_t AllSize; - uint32_t *MMU_Base, *MMU_p; - int ret, status; - - MMU_Base = NULL; - - do - { - /* cal dst buf mmu info */ - DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, - req->dst.format, req->dst.vir_w, req->dst.vir_h, - &DstStart); - if(DstMemSize == 0) { - return -EINVAL; - } - - AllSize = DstMemSize; - - pages = kzalloc((AllSize + 1) * sizeof(struct page *), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc pages mem failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc MMU_Base point failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - if (req->dst.yrgb_addr < KERNEL_SPACE_VALID) - { - ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize); - if (ret < 0) { - pr_err("rga map dst memory failed\n"); - status = ret; - break; - } - } - else - { - MMU_p = MMU_Base; - - for(i=0; immu_info.base_addr = (virt_to_phys(MMU_Base) >> 2); - req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)); - - - /*record the malloc buf for the cmd end to release*/ - reg->MMU_base = MMU_Base; - - /* flush data to DDR */ - dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); - - /* Free the page table */ - if (pages != NULL) { - kfree(pages); - } - - return 0; - - } - while(0); - - if (pages != NULL) - kfree(pages); - - if (MMU_Base != NULL) - kfree(MMU_Base); - - return status; + return 0; } static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req) { - int SrcMemSize, DstMemSize; - uint32_t SrcStart, DstStart; - struct page **pages = NULL; - uint32_t i; - uint32_t AllSize; - uint32_t *MMU_Base, *MMU_p; - int ret, status; - uint32_t uv_size, v_size; - - MMU_Base = NULL; - - do - { - /* cal src buf mmu info */ - SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, - req->src.format, req->src.vir_w, req->src.vir_h, - &SrcStart); - if(SrcMemSize == 0) { - return -EINVAL; - } - - /* cal dst buf mmu info */ - DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, - req->dst.format, req->dst.vir_w, req->dst.vir_h, - &DstStart); - if(DstMemSize == 0) { - return -EINVAL; - } - - AllSize = SrcMemSize + DstMemSize; - - pages = kzalloc((AllSize + 1) * sizeof(struct page *), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc pages mem failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc MMU_Base point failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - if (req->src.yrgb_addr < KERNEL_SPACE_VALID) - { - ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize); - if (ret < 0) - { - pr_err("rga map src memory failed\n"); - status = ret; - break; - } - } - else - { - MMU_p = MMU_Base; - - for(i=0; idst.yrgb_addr < KERNEL_SPACE_VALID) - { - ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize); - if (ret < 0) - { - pr_err("rga map dst memory failed\n"); - status = ret; - break; - } - } - else - { - MMU_p = MMU_Base + SrcMemSize; - - for(i=0; immu_info.base_addr = (virt_to_phys(MMU_Base) >> 2); - - uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; - v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; - - req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); - req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT); - req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT); - - uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; - v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; - - req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT); - req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); - req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT); - - - /*record the malloc buf for the cmd end to release*/ - reg->MMU_base = MMU_Base; - - /* flush data to DDR */ - dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); - - /* Free the page table */ - if (pages != NULL) { - kfree(pages); - } - - return 0; - } - while(0); - - if (pages != NULL) - kfree(pages); - - if (MMU_Base != NULL) - kfree(MMU_Base); - - return status; + return 0; } @@ -1031,7 +823,7 @@ static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_r static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) { int SrcMemSize, DstMemSize; - uint32_t SrcStart, DstStart; + unsigned long SrcStart, DstStart; struct page **pages = NULL; uint32_t i; uint32_t AllSize; @@ -1116,7 +908,7 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) /* kernel space */ MMU_p = MMU_Base + SrcMemSize; - if(req->dst.yrgb_addr == (uint32_t)rga_service.pre_scale_buf) { + if(req->dst.yrgb_addr == (unsigned long)rga_service.pre_scale_buf) { for(i=0; immu_info.base_addr = ((uint32_t)(MMU_Base_phys)>>2); + req->mmu_info.base_addr = ((unsigned long)(MMU_Base_phys)>>2); uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; @@ -1153,8 +945,12 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) reg->MMU_base = MMU_Base; /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); + #endif rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); reg->MMU_len = AllSize + 16; @@ -1170,7 +966,7 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req) { int SrcMemSize, CMDMemSize; - uint32_t SrcStart, CMDStart; + unsigned long SrcStart, CMDStart; struct page **pages = NULL; uint32_t i; uint32_t AllSize; @@ -1179,8 +975,7 @@ static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rg MMU_Base = NULL; - do - { + do { /* cal src buf mmu info */ SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart); if(SrcMemSize == 0) { @@ -1188,7 +983,7 @@ static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rg } /* cal cmd buf mmu info */ - CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); if(CMDMemSize == 0) { return -EINVAL; } @@ -1210,7 +1005,7 @@ static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rg } for(i=0; isrc.yrgb_addr < KERNEL_SPACE_VALID) @@ -1243,8 +1038,13 @@ static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rg reg->MMU_base = MMU_Base; /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize)); + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize)); + #endif + if (pages != NULL) { /* Free the page table */ @@ -1267,7 +1067,7 @@ static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rg static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req) { int SrcMemSize, CMDMemSize; - uint32_t SrcStart, CMDStart; + unsigned long SrcStart, CMDStart; struct page **pages = NULL; uint32_t i; uint32_t AllSize; @@ -1286,7 +1086,7 @@ static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_ } /* cal cmd buf mmu info */ - CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); if(CMDMemSize == 0) { return -EINVAL; } @@ -1342,8 +1142,12 @@ static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_ reg->MMU_base = MMU_Base; /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize)); + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize)); + #endif if (pages != NULL) { /* Free the page table */ diff --git a/drivers/video/rockchip/rga2/rga2.h b/drivers/video/rockchip/rga2/rga2.h index ba2c1ddfa225..545454e187f6 100644 --- a/drivers/video/rockchip/rga2/rga2.h +++ b/drivers/video/rockchip/rga2/rga2.h @@ -131,10 +131,10 @@ mdp_img_vir; typedef struct MMU_INFO { - u32 src0_base_addr; - u32 src1_base_addr; - u32 dst_base_addr; - u32 els_base_addr; + uint64_t src0_base_addr; + uint64_t src1_base_addr; + uint64_t dst_base_addr; + uint64_t els_base_addr; u8 src0_mmu_flag; /* [0] src0 mmu enable [1] src0_flush [2] src0_prefetch_en [3] src0_prefetch dir */ u8 src1_mmu_flag; /* [0] src1 mmu enable [1] src1_flush [2] src1_prefetch_en [3] src1_prefetch dir */ @@ -219,7 +219,7 @@ FADING; typedef struct MMU { unsigned char mmu_en; - uint32_t base_addr; + uint64_t base_addr; uint32_t mmu_flag; /* [0] mmu enable [1] src_flush [2] dst_flush [3] CMD_flush [4~5] page size*/ } MMU; @@ -251,9 +251,9 @@ line_draw_t; typedef struct rga_img_info_t { - unsigned int yrgb_addr; /* yrgb mem addr */ - unsigned int uv_addr; /* cb/cr mem addr */ - unsigned int v_addr; /* cr mem addr */ + uint64_t yrgb_addr; /* yrgb mem addr */ + uint64_t uv_addr; /* cb/cr mem addr */ + uint64_t v_addr; /* cr mem addr */ unsigned int format; //definition by RK_FORMAT unsigned short act_w; @@ -266,9 +266,6 @@ typedef struct rga_img_info_t unsigned short endian_mode; //for BPP unsigned short alpha_swap; - - //unsigned short uv_x_off; - //unsigned short uv_y_off; } rga_img_info_t; @@ -279,8 +276,8 @@ struct rga_req { rga_img_info_t dst; /* dst image info */ rga_img_info_t pat; /* patten image info */ - uint32_t rop_mask_addr; /* rop4 mask addr */ - uint32_t LUT_addr; /* LUT addr */ + uint64_t rop_mask_addr; /* rop4 mask addr */ + uint64_t LUT_addr; /* LUT addr */ RECT clip; /* dst clip window default value is dst_vir */ /* value from [0, w-1] / [0, h-1]*/ @@ -356,8 +353,8 @@ struct rga2_req rga_img_info_t dst; // dst active window rga_img_info_t pat; // patten active window - u32 rop_mask_addr; // rop4 mask addr - u32 LUT_addr; // LUT addr + uint64_t rop_mask_addr; // rop4 mask addr + uint64_t LUT_addr; // LUT addr u32 rop_mask_stride; @@ -462,9 +459,9 @@ struct rga2_mmu_buf_t { int32_t curr; unsigned int *buf; unsigned int *buf_virtual; -}; -//add for FPGA test ,by hxx & luj + struct page **pages; +}; enum { diff --git a/drivers/video/rockchip/rga2/rga2_drv.c b/drivers/video/rockchip/rga2/rga2_drv.c index ce517f1ff40a..3852d4460872 100755 --- a/drivers/video/rockchip/rga2/rga2_drv.c +++ b/drivers/video/rockchip/rga2/rga2_drv.c @@ -56,8 +56,6 @@ #define CONFIG_RGA_IOMMU #endif - - #define RGA2_TEST_FLUSH_TIME 0 #define RGA2_INFO_BUS_ERROR 1 @@ -137,11 +135,11 @@ static void print_info(struct rga2_req *req) { printk("render_mode=%d bitblt_mode=%d rotate_mode=%.8x\n", req->render_mode, req->bitblt_mode, req->rotate_mode); - printk("src : y=%.8x uv=%.8x v=%.8x format=%d aw=%d ah=%d vw=%d vh=%d xoff=%d yoff=%d \n", + printk("src : y=%.llx uv=%.llx v=%.llx format=%d aw=%d ah=%d vw=%d vh=%d xoff=%d yoff=%d \n", req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, req->src.format, req->src.act_w, req->src.act_h, req->src.vir_w, req->src.vir_h, req->src.x_offset, req->src.y_offset); - printk("dst : y=%.8x uv=%.8x v=%.8x format=%d aw=%d ah=%d vw=%d vh=%d xoff=%d yoff=%d \n", + printk("dst : y=%llx uv=%llx v=%llx format=%d aw=%d ah=%d vw=%d vh=%d xoff=%d yoff=%d \n", req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, req->dst.format, req->dst.act_w, req->dst.act_h, req->dst.vir_w, req->dst.vir_h, req->dst.x_offset, req->dst.y_offset); @@ -156,12 +154,16 @@ static void print_info(struct rga2_req *req) static inline void rga2_write(u32 b, u32 r) { - __raw_writel(b, rga2_drvdata->rga_base + r); + //__raw_writel(b, rga2_drvdata->rga_base + r); + + *((volatile unsigned int *)(rga2_drvdata->rga_base + r)) = b; } static inline u32 rga2_read(u32 r) { - return __raw_readl(rga2_drvdata->rga_base + r); + //return __raw_readl(rga2_drvdata->rga_base + r); + + return *((volatile unsigned int *)(rga2_drvdata->rga_base + r)); } static void rga2_soft_reset(void) @@ -169,7 +171,7 @@ static void rga2_soft_reset(void) u32 i; u32 reg; - rga2_write(1, RGA2_SYS_CTRL); //RGA_SYS_CTRL + rga2_write((1 << 3) | (1 << 4), RGA2_SYS_CTRL); //RGA_SYS_CTRL for(i = 0; i < RGA2_RESET_TIMEOUT; i++) { @@ -194,48 +196,6 @@ static void rga2_dump(void) running = atomic_read(&rga2_service.total_running); printk("rga total_running %d\n", running); - #if 0 - - /* Dump waiting list info */ - if (!list_empty(&rga_service.waiting)) - { - list_head *next; - - next = &rga_service.waiting; - - printk("rga_service dump waiting list\n"); - - do - { - reg = list_entry(next->next, struct rga_reg, status_link); - running = atomic_read(®->session->task_running); - num_done = atomic_read(®->session->num_done); - printk("rga session pid %d, done %d, running %d\n", reg->session->pid, num_done, running); - next = next->next; - } - while(!list_empty(next)); - } - - /* Dump running list info */ - if (!list_empty(&rga_service.running)) - { - printk("rga_service dump running list\n"); - - list_head *next; - - next = &rga_service.running; - do - { - reg = list_entry(next->next, struct rga_reg, status_link); - running = atomic_read(®->session->task_running); - num_done = atomic_read(®->session->num_done); - printk("rga session pid %d, done %d, running %d:\n", reg->session->pid, num_done, running); - next = next->next; - } - while(!list_empty(next)); - } - #endif - list_for_each_entry_safe(session, session_tmp, &rga2_service.session, list_session) { printk("session pid %d:\n", session->pid); @@ -243,11 +203,11 @@ static void rga2_dump(void) printk("task_running %d\n", running); list_for_each_entry_safe(reg, reg_tmp, &session->waiting, session_link) { - printk("waiting register set 0x%.8x\n", (unsigned int)reg); + printk("waiting register set 0x%.lu\n", (unsigned long)reg); } list_for_each_entry_safe(reg, reg_tmp, &session->running, session_link) { - printk("running register set 0x%.8x\n", (unsigned int)reg); + printk("running register set 0x%.lu\n", (unsigned long)reg); } } } @@ -272,7 +232,6 @@ static void rga2_power_on(void) return; clk_prepare_enable(rga2_drvdata->rga2); - clk_prepare_enable(rga2_drvdata->pd_rga2); clk_prepare_enable(rga2_drvdata->aclk_rga2); clk_prepare_enable(rga2_drvdata->hclk_rga2); //clk_enable(rga2_drvdata->pd_rga2); @@ -299,7 +258,7 @@ static void rga2_power_off(void) //clk_disable(rga2_drvdata->pd_rga2); clk_disable_unprepare(rga2_drvdata->rga2); - clk_disable_unprepare(rga2_drvdata->pd_rga2); + //clk_disable_unprepare(rga2_drvdata->pd_rga2); clk_disable_unprepare(rga2_drvdata->aclk_rga2); clk_disable_unprepare(rga2_drvdata->hclk_rga2); wake_unlock(&rga2_drvdata->wake_lock); @@ -435,9 +394,7 @@ static void rga2_copy_reg(struct rga2_reg *reg, uint32_t offset) uint32_t *reg_p; if(atomic_read(®->session->task_running) != 0) - { printk(KERN_ERR "task_running is no zero\n"); - } atomic_add(1, &rga2_service.cmd_num); atomic_add(1, ®->session->task_running); @@ -446,11 +403,7 @@ static void rga2_copy_reg(struct rga2_reg *reg, uint32_t offset) reg_p = (uint32_t *)reg->cmd_reg; for(i=0; i<32; i++) - { cmd_buf[i] = reg_p[i]; - } - - dsb(); } @@ -551,23 +504,22 @@ static void rga2_try_set_reg(void) rga2_copy_reg(reg, 0); rga2_reg_from_wait_to_run(reg); + #ifdef CONFIG_ARM dmac_flush_range(&rga2_service.cmd_buff[0], &rga2_service.cmd_buff[32]); outer_flush_range(virt_to_phys(&rga2_service.cmd_buff[0]),virt_to_phys(&rga2_service.cmd_buff[32])); + #elif defined(CONFIG_ARM64) + __dma_flush_range(&rga2_service.cmd_buff[0], &rga2_service.cmd_buff[32]); + #endif - #if defined(CONFIG_ARCH_RK30) rga2_soft_reset(); - #endif rga2_write(0x0, RGA2_SYS_CTRL); - //rga2_write(0, RGA_MMU_CTRL); /* CMD buff */ rga2_write(virt_to_phys(rga2_service.cmd_buff), RGA2_CMD_BASE); #if RGA2_TEST - if(rga2_flag) - { - //printk(KERN_DEBUG "cmd_addr = %.8x\n", rga_read(RGA_CMD_ADDR)); + if(rga2_flag) { uint32_t i, *p; p = rga2_service.cmd_buff; printk("CMD_REG\n"); @@ -583,7 +535,7 @@ static void rga2_try_set_reg(void) rga2_write(rga2_read(RGA2_INT)|(0x1<<10)|(0x1<<8), RGA2_INT); #if RGA2_TEST_TIME - rga_start = ktime_get(); + rga2_start = ktime_get(); #endif /* Start proc */ @@ -652,26 +604,8 @@ static void rga2_del_running_list_timeout(void) atomic_sub(1, ®->session->task_running); atomic_sub(1, &rga2_service.total_running); - //printk("RGA soft reset for timeout process\n"); rga2_soft_reset(); - - #if 0 - printk("RGA_INT is %.8x\n", rga_read(RGA_INT)); - printk("reg->session->task_running = %d\n", atomic_read(®->session->task_running)); - printk("rga_service.total_running = %d\n", atomic_read(&rga_service.total_running)); - - print_info(®->req); - - { - uint32_t *p, i; - p = reg->cmd_reg; - for (i=0; i<7; i++) - printk("%.8x %.8x %.8x %.8x\n", p[0 + i*4], p[1+i*4], p[2 + i*4], p[3 + i*4]); - - } - #endif - if(list_empty(®->session->waiting)) { atomic_set(®->session->done, 1); @@ -855,9 +789,7 @@ static int rga2_blit_sync(rga2_session *session, struct rga2_req *req) ret = rga2_blit(session, req); if(ret < 0) - { return ret; - } ret_timeout = wait_event_timeout(session->wait, atomic_read(&session->done), RGA2_TIMEOUT_DELAY); @@ -993,6 +925,114 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg) return ret; } +static long compat_rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg) +{ + struct rga2_req req; + struct rga_req req_rga; + int ret = 0; + rga2_session *session; + + memset(&req, 0x0, sizeof(req)); + + mutex_lock(&rga2_service.mutex); + + session = (rga2_session *)file->private_data; + + #if RGA2_TEST_MSG + printk("use compat_rga_ioctl\n"); + #endif + + if (NULL == session) { + printk("%s [%d] rga thread session is null\n",__FUNCTION__,__LINE__); + mutex_unlock(&rga2_service.mutex); + return -EINVAL; + } + + memset(&req, 0x0, sizeof(req)); + + switch (cmd) { + case RGA_BLIT_SYNC: + if (unlikely(copy_from_user(&req_rga, compat_ptr((compat_uptr_t)arg), sizeof(struct rga_req)))) + { + ERR("copy_from_user failed\n"); + ret = -EFAULT; + break; + } + + RGA_MSG_2_RGA2_MSG(&req_rga, &req); + + ret = rga2_blit_sync(session, &req); + break; + case RGA_BLIT_ASYNC: + if (unlikely(copy_from_user(&req_rga, compat_ptr((compat_uptr_t)arg), sizeof(struct rga_req)))) + { + ERR("copy_from_user failed\n"); + ret = -EFAULT; + break; + } + + RGA_MSG_2_RGA2_MSG(&req_rga, &req); + + if((atomic_read(&rga2_service.total_running) > 8)) + { + ret = rga2_blit_sync(session, &req); + } + else + { + ret = rga2_blit_async(session, &req); + } + break; + case RGA2_BLIT_SYNC: + if (unlikely(copy_from_user(&req, compat_ptr((compat_uptr_t)arg), sizeof(struct rga2_req)))) + { + ERR("copy_from_user failed\n"); + ret = -EFAULT; + break; + } + ret = rga2_blit_sync(session, &req); + break; + case RGA2_BLIT_ASYNC: + if (unlikely(copy_from_user(&req, compat_ptr((compat_uptr_t)arg), sizeof(struct rga2_req)))) + { + ERR("copy_from_user failed\n"); + ret = -EFAULT; + break; + } + + if((atomic_read(&rga2_service.total_running) > 16)) + { + ret = rga2_blit_sync(session, &req); + } + else + { + ret = rga2_blit_async(session, &req); + } + break; + case RGA_FLUSH: + case RGA2_FLUSH: + ret = rga2_flush(session, arg); + break; + case RGA_GET_RESULT: + case RGA2_GET_RESULT: + ret = rga2_get_result(session, arg); + break; + case RGA_GET_VERSION: + case RGA2_GET_VERSION: + ret = copy_to_user((void *)arg, RGA2_VERSION, sizeof(RGA2_VERSION)); + //ret = 0; + break; + default: + ERR("unknown ioctl cmd!\n"); + ret = -EINVAL; + break; + } + + mutex_unlock(&rga2_service.mutex); + + return ret; +} + + long rga2_ioctl_kernel(struct rga_req *req_rga) { @@ -1102,6 +1142,7 @@ struct file_operations rga2_fops = { .open = rga2_open, .release = rga2_release, .unlocked_ioctl = rga_ioctl, + .compat_ioctl = compat_rga_ioctl, }; static struct miscdevice rga2_dev ={ @@ -1111,7 +1152,7 @@ static struct miscdevice rga2_dev ={ }; static const struct of_device_id rockchip_rga_dt_ids[] = { - { .compatible = "rockchip,rk3288-rga2", }, + { .compatible = "rockchip,rk3368-rga2", }, {}, }; @@ -1246,11 +1287,13 @@ static int __init rga2_init(void) /* malloc pre scale mid buf mmu table */ buf_p = kmalloc(1024*256, GFP_KERNEL); rga2_mmu_buf.buf_virtual = buf_p; - rga2_mmu_buf.buf = (uint32_t *)virt_to_phys((void *)((uint32_t)buf_p)); + rga2_mmu_buf.buf = (uint32_t *)virt_to_phys((void *)((unsigned long)buf_p)); rga2_mmu_buf.front = 0; rga2_mmu_buf.back = 64*1024; rga2_mmu_buf.size = 64*1024; + rga2_mmu_buf.pages = kmalloc(32768 * sizeof(struct page *), GFP_KERNEL); + if ((ret = platform_driver_register(&rga2_driver)) != 0) { printk(KERN_ERR "Platform device register failed (%d).\n", ret); @@ -1297,16 +1340,6 @@ static void __exit rga2_exit(void) #if RGA2_TEST_CASE -extern struct fb_info * rk_get_fb(int fb_id); -EXPORT_SYMBOL(rk_get_fb); - -extern void rk_direct_fb_show(struct fb_info * fbi); -EXPORT_SYMBOL(rk_direct_fb_show); - -//unsigned int src_buf[4096*2304*3/2]; -//unsigned int dst_buf[3840*2304*3/2]; -//unsigned int tmp_buf[1920*1080 * 2]; - void rga2_test_0(void) { struct rga2_req req; @@ -1333,10 +1366,15 @@ void rga2_test_0(void) //fb = rk_get_fb(0); memset(&req, 0, sizeof(struct rga2_req)); - src = kmalloc(4096*2304*3/2, GFP_KERNEL); - dst = kmalloc(3840*2160*3/2, GFP_KERNEL); + src = kmalloc(800*480*4, GFP_KERNEL); + dst = kmalloc(800*480*4, GFP_KERNEL); - //memset(src, 0x80, 4096*2304*4); + printk("\n********************************\n"); + 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])); @@ -1354,39 +1392,39 @@ void rga2_test_0(void) i = j = 0; - printk("\n********************************\n"); - printk("************ RGA2_TEST ************\n"); - printk("********************************\n\n"); + + #if 0 req.pat.act_w = 16; req.pat.act_h = 16; req.pat.vir_w = 16; req.pat.vir_h = 16; req.pat.yrgb_addr = virt_to_phys(src); - req.render_mode = update_palette_table_mode; + req.render_mode = 0; rga2_blit_sync(&session, &req); + #endif - req.src.act_w = 4096; - req.src.act_h = 2304; + req.src.act_w = 320; + req.src.act_h = 240; - req.src.vir_w = 4096; - req.src.vir_h = 2304; - req.src.yrgb_addr = (uint32_t)0;//virt_to_phys(src); - req.src.uv_addr = (uint32_t)virt_to_phys(src); + 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_YCbCr_420_SP; + req.src.format = RGA2_FORMAT_RGBA_8888; - req.dst.act_w = 3840; - req.dst.act_h = 2160; + req.dst.act_w = 320; + req.dst.act_h = 240; req.dst.x_offset = 0; req.dst.y_offset = 0; - req.dst.vir_w = 3840; - req.dst.vir_h = 2160; + req.dst.vir_w = 320; + req.dst.vir_h = 240; req.dst.yrgb_addr = 0;//((uint32_t)virt_to_phys(dst)); - req.dst.uv_addr = ((uint32_t)virt_to_phys(dst)); - req.dst.format = RGA2_FORMAT_YCbCr_420_SP; + req.dst.uv_addr = (unsigned long)virt_to_phys(dst); + req.dst.format = RGA2_FORMAT_RGBA_8888; //dst = dst0; @@ -1409,36 +1447,9 @@ void rga2_test_0(void) rga2_blit_sync(&session, &req); - #if 0 - fb->var.bits_per_pixel = 32; - - fb->var.xres = 1280; - fb->var.yres = 800; - - fb->var.red.length = 8; - fb->var.red.offset = 0; - fb->var.red.msb_right = 0; - - fb->var.green.length = 8; - fb->var.green.offset = 8; - fb->var.green.msb_right = 0; - - fb->var.blue.length = 8; - - fb->var.blue.offset = 16; - fb->var.blue.msb_right = 0; - - fb->var.transp.length = 8; - fb->var.transp.offset = 24; - fb->var.transp.msb_right = 0; - - fb->var.nonstd &= (~0xff); - fb->var.nonstd |= 1; - - fb->fix.smem_start = virt_to_phys(dst); - - rk_direct_fb_show(fb); - #endif + for(j=0; j<100; j++) { + printk("%.8x\n", dst[j]); + } if(src) kfree(src); diff --git a/drivers/video/rockchip/rga2/rga2_mmu_info.c b/drivers/video/rockchip/rga2/rga2_mmu_info.c index b5c6af78cc68..ca05a79d08c1 100644 --- a/drivers/video/rockchip/rga2/rga2_mmu_info.c +++ b/drivers/video/rockchip/rga2/rga2_mmu_info.c @@ -86,23 +86,9 @@ static int rga2_mmu_buf_get_try(struct rga2_mmu_buf_t *t, uint32_t size) return 0; } -#if 0 -static int rga2_mmu_buf_cal(struct rga2_mmu_buf_t *t, uint32_t size) -{ - if((t->front + size) > t->back) { - return -1; - } - else { - return 0; - } -} -#endif - - - -static int rga2_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr) +static int rga2_mem_size_cal(unsigned long Mem, uint32_t MemSize, unsigned long *StartAddr) { - uint32_t start, end; + unsigned long start, end; uint32_t pageCount; end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT; @@ -112,14 +98,14 @@ static int rga2_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr return pageCount; } -static int rga2_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_addr, - int format, uint32_t w, uint32_t h, uint32_t *StartAddr ) +static int rga2_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, unsigned long v_addr, + int format, uint32_t w, uint32_t h, unsigned long *StartAddr ) { uint32_t size_yrgb = 0; uint32_t size_uv = 0; uint32_t size_v = 0; uint32_t stride = 0; - uint32_t start, end; + unsigned long start, end; uint32_t pageCount; switch(format) @@ -243,14 +229,13 @@ static int rga2_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_ad static int rga2_MapUserMemory(struct page **pages, uint32_t *pageTable, - uint32_t Memory, + unsigned long Memory, uint32_t pageCount) { int32_t result; uint32_t i; uint32_t status; - uint32_t Address; - //uint32_t temp; + unsigned long Address; status = 0; Address = 0; @@ -269,27 +254,6 @@ static int rga2_MapUserMemory(struct page **pages, ); up_read(¤t->mm->mmap_sem); - #if 0 - if(result <= 0 || result < pageCount) - { - status = 0; - - for(i=0; ivm_flags & VM_PFNMAP) ) { - #if 1 do { pte_t * pte; @@ -353,29 +316,7 @@ static int rga2_MapUserMemory(struct page **pages, } while (0); - #else - do - { - pte_t * pte; - spinlock_t * ptl; - unsigned long pfn; - pgd_t * pgd; - pud_t * pud; - pmd_t * pmd; - - pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT); - pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT); - pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT); - pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl); - - pfn = pte_pfn(*pte); - Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK)); - pte_unmap_unlock(pte, ptl); - } - while (0); - #endif - - pageTable[i] = Address; + pageTable[i] = (uint32_t)Address; } else { @@ -386,7 +327,6 @@ static int rga2_MapUserMemory(struct page **pages, return status; } - #endif /* Fill the page table. */ for(i=0; isgl; @@ -426,7 +366,7 @@ static int rga2_MapION(struct sg_table *sg, Address = sg_phys(sgl); for(i=0; immu_info.src0_mmu_flag & 1) { Src0MemSize = rga2_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, @@ -504,12 +443,7 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req) break; } - pages = kzalloc((AllSize)* sizeof(struct page *), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc pages mem failed\n"); - status = RGA2_MALLOC_ERROR; - break; - } + pages = rga2_mmu_buf.pages; mutex_lock(&rga2_service.lock); MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1)); @@ -525,14 +459,12 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req) if (ret < 0) { pr_err("rga2 map src0 memory failed\n"); - pr_err("RGA2 : yrgb = %.8x, uv = %.8x format = %d\n", req->src.yrgb_addr, req->src.uv_addr, req->src.format); - pr_err("RGA2 : vir_w = %d, vir_h = %d\n", req->src.vir_w, req->src.vir_h); status = ret; break; } /* change the buf address in req struct */ - req->mmu_info.src0_base_addr = (((uint32_t)MMU_Base_phys)); + req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys)); uv_size = (req->src.uv_addr - (Src0Start << PAGE_SHIFT)) >> PAGE_SHIFT; v_size = (req->src.v_addr - (Src0Start << PAGE_SHIFT)) >> PAGE_SHIFT; @@ -551,14 +483,12 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req) if (ret < 0) { pr_err("rga2 map src1 memory failed\n"); - pr_err("RGA2 : yrgb = %.8x, format = %d\n", req->src1.yrgb_addr, req->src1.format); - pr_err("RGA2 : vir_w = %d, vir_h = %d\n", req->src1.vir_w, req->src1.vir_h); status = ret; break; } /* change the buf address in req struct */ - req->mmu_info.src1_base_addr = ((uint32_t)(MMU_Base_phys + Src0MemSize)); + req->mmu_info.src1_base_addr = ((unsigned long)(MMU_Base_phys + Src0MemSize)); req->src1.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); } @@ -571,14 +501,12 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req) } if (ret < 0) { pr_err("rga2 map dst memory failed\n"); - pr_err("RGA2 : yrgb = %.8x, uv = %.8x\n, format = %d\n", req->dst.yrgb_addr, req->dst.uv_addr, req->dst.format); - pr_err("RGA2 : vir_w = %d, vir_h = %d\n", req->dst.vir_w, req->dst.vir_h); status = ret; break; } /* change the buf address in req struct */ - req->mmu_info.dst_base_addr = ((uint32_t)(MMU_Base_phys + Src0MemSize + Src1MemSize)); + req->mmu_info.dst_base_addr = ((unsigned long)(MMU_Base_phys + Src0MemSize + Src1MemSize)); req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)); uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; @@ -587,36 +515,29 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req) } /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize)); + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize)); + #endif rga2_mmu_buf_get(&rga2_mmu_buf, AllSize); reg->MMU_len = AllSize; status = 0; - /* Free the page table */ - if (pages != NULL) { - kfree(pages); - } - return status; } while(0); - - /* Free the page table */ - if (pages != NULL) { - kfree(pages); - } - return status; } static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_req *req) { int SrcMemSize, DstMemSize; - uint32_t SrcStart, DstStart; + unsigned long SrcStart, DstStart; struct page **pages = NULL; uint32_t AllSize; uint32_t *MMU_Base = NULL, *MMU_Base_phys; @@ -634,8 +555,7 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re SrcMemSize = 0; DstMemSize = 0; - do - { + do { if (req->mmu_info.src0_mmu_flag) { SrcMemSize = rga2_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart); if(SrcMemSize == 0) { @@ -663,7 +583,7 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re break; } - pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + pages = rga2_mmu_buf.pages; if(pages == NULL) { pr_err("RGA MMU malloc pages mem failed\n"); return -EINVAL; @@ -683,7 +603,7 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re } /* change the buf address in req struct */ - req->mmu_info.src0_base_addr = (((uint32_t)MMU_Base_phys)); + req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys)); req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); } @@ -696,40 +616,32 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re } /* change the buf address in req struct */ - req->mmu_info.dst_base_addr = ((uint32_t)(MMU_Base_phys + SrcMemSize)); + req->mmu_info.dst_base_addr = ((unsigned long)(MMU_Base_phys + SrcMemSize)); req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)); } /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize)); + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize)); + #endif rga2_mmu_buf_get(&rga2_mmu_buf, AllSize); reg->MMU_len = AllSize; - status = 0; - - /* Free the page table */ - if (pages != NULL) { - kfree(pages); - } - - return status; + return 0; } while(0); - /* Free the page table */ - if (pages != NULL) { - kfree(pages); - } - return 0; } static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req *req) { int DstMemSize; - uint32_t DstStart; + unsigned long DstStart; struct page **pages = NULL; uint32_t AllSize; uint32_t *MMU_Base, *MMU_Base_phys; @@ -738,8 +650,7 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req * MMU_Base = NULL; - do - { + do { if(req->mmu_info.dst_mmu_flag & 1) { DstMemSize = rga2_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, req->dst.format, req->dst.vir_w, req->dst.vir_h, @@ -751,12 +662,7 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req * AllSize = (DstMemSize + 15) & (~15); - pages = kzalloc((AllSize)* sizeof(struct page *), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA2 MMU malloc pages mem failed\n"); - status = RGA2_MALLOC_ERROR; - break; - } + pages = rga2_mmu_buf.pages; if(rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) { pr_err("RGA2 Get MMU mem failed\n"); @@ -783,27 +689,24 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req * } /* change the buf address in req struct */ - req->mmu_info.dst_base_addr = ((uint32_t)MMU_Base_phys); + req->mmu_info.dst_base_addr = ((unsigned long)MMU_Base_phys); req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)); } /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); + #endif rga2_mmu_buf_get(&rga2_mmu_buf, AllSize); - /* Free the page table */ - if (pages != NULL) - kfree(pages); - return 0; } while(0); - if (pages != NULL) - kfree(pages); - return status; } @@ -811,7 +714,7 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req * static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct rga2_req *req) { int SrcMemSize; - uint32_t SrcStart; + unsigned long SrcStart; struct page **pages = NULL; uint32_t AllSize; uint32_t *MMU_Base, *MMU_Base_phys; @@ -819,8 +722,7 @@ static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct MMU_Base = NULL; - do - { + do { /* cal src buf mmu info */ SrcMemSize = rga2_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h, &SrcStart); if(SrcMemSize == 0) { @@ -842,11 +744,6 @@ static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct mutex_unlock(&rga2_service.lock); pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc pages mem failed\n"); - status = RGA2_MALLOC_ERROR; - break; - } if(SrcMemSize) { ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize); @@ -857,36 +754,32 @@ static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct } /* change the buf address in req struct */ - req->mmu_info.src0_base_addr = (((uint32_t)MMU_Base_phys)); + req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys)); req->pat.yrgb_addr = (req->pat.yrgb_addr & (~PAGE_MASK)); } /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); outer_flush_range(virt_to_phys(MMU_Base), virt_to_phys(MMU_Base + AllSize)); + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize)); + #endif rga2_mmu_buf_get(&rga2_mmu_buf, AllSize); reg->MMU_len = AllSize; - if (pages != NULL) { - /* Free the page table */ - kfree(pages); - } - return 0; } while(0); - if (pages != NULL) - kfree(pages); - return status; } static int rga2_mmu_info_update_patten_buff_mode(struct rga2_reg *reg, struct rga2_req *req) { int SrcMemSize, CMDMemSize; - uint32_t SrcStart, CMDStart; + unsigned long SrcStart, CMDStart; struct page **pages = NULL; uint32_t i; uint32_t AllSize; @@ -895,9 +788,7 @@ static int rga2_mmu_info_update_patten_buff_mode(struct rga2_reg *reg, struct rg MMU_Base = MMU_p = 0; - do - { - + do { /* cal src buf mmu info */ SrcMemSize = rga2_mem_size_cal(req->pat.yrgb_addr, req->pat.act_w * req->pat.act_h * 4, &SrcStart); if(SrcMemSize == 0) { @@ -905,26 +796,16 @@ static int rga2_mmu_info_update_patten_buff_mode(struct rga2_reg *reg, struct rg } /* cal cmd buf mmu info */ - CMDMemSize = rga2_mem_size_cal((uint32_t)rga2_service.cmd_buff, RGA2_CMD_BUF_SIZE, &CMDStart); + CMDMemSize = rga2_mem_size_cal((unsigned long)rga2_service.cmd_buff, RGA2_CMD_BUF_SIZE, &CMDStart); if(CMDMemSize == 0) { return -EINVAL; } AllSize = SrcMemSize + CMDMemSize; - pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc pages mem failed\n"); - status = RGA2_MALLOC_ERROR; - break; - } + pages = rga2_mmu_buf.pages; MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc MMU_Base point failed\n"); - status = RGA2_MALLOC_ERROR; - break; - } for(i=0; iMMU_base = MMU_Base; /* flush data to DDR */ + #ifdef CONFIG_ARM dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize)); - - if (pages != NULL) { - /* Free the page table */ - kfree(pages); - } + #elif defined(CONFIG_ARM64) + __dma_flush_range(MMU_Base, (MMU_Base + AllSize)); + #endif return 0; } while(0); - if (pages != NULL) - kfree(pages); - return status; } diff --git a/drivers/video/rockchip/rga2/rga2_reg_info.c b/drivers/video/rockchip/rga2/rga2_reg_info.c index 01bdfcc1c0de..e131181c25ff 100644 --- a/drivers/video/rockchip/rga2/rga2_reg_info.c +++ b/drivers/video/rockchip/rga2/rga2_reg_info.c @@ -695,7 +695,7 @@ RGA2_set_reg_color_palette(RK_U8 *base, struct rga2_req *msg) p = p + (x_off>>shift) + y_off*src_stride; - *bRGA_SRC_BASE0 = (RK_U32)p; + *bRGA_SRC_BASE0 = (unsigned long)p; reg = ((reg & (~m_RGA2_SRC_INFO_SW_SRC_FMT)) | (s_RGA2_SRC_INFO_SW_SRC_FMT((msg->palette_mode | 0xc)))); reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_CP_ENDAIN)) | (s_RGA2_SRC_INFO_SW_SW_CP_ENDAIN(msg->endian_mode & 1))); @@ -767,7 +767,6 @@ RGA2_set_reg_update_palette_table(RK_U8 *base, struct rga2_req *msg) bRGA_FADING_CTRL = (RK_U32 *)(base + RGA2_FADING_CTRL_OFFSET); *bRGA_FADING_CTRL = msg->fading_g_value << 8; - // *bRGA_MASK_BASE = (RK_U32)msg->LUT_addr; *bRGA_MASK_BASE = (RK_U32)msg->pat.yrgb_addr; } -- 2.34.1