From: 黄涛 Date: Thu, 23 Feb 2012 08:04:40 +0000 (+0800) Subject: rk30: add RGA driver X-Git-Tag: firefly_0821_release~9595^2~125 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=919de0db884beb129cb4ad756887d303d8124ee9;p=firefly-linux-kernel-4.4.55.git rk30: add RGA driver --- diff --git a/arch/arm/mach-rk30/devices.c b/arch/arm/mach-rk30/devices.c index 460463fcf694..0e40bf740398 100755 --- a/arch/arm/mach-rk30/devices.c +++ b/arch/arm/mach-rk30/devices.c @@ -723,6 +723,28 @@ static struct platform_device device_lcdc = { }; #endif +#ifdef CONFIG_RGA_RK30 +static struct resource resource_rga[] = { + [0] = { + .start = RK30_RGA_PHYS, + .end = RK30_RGA_PHYS + RK30_RGA_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_RGA, + .end = IRQ_RGA, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device device_rga = { + .name = "rga", + .id = -1, + .num_resources = ARRAY_SIZE(resource_rga), + .resource = resource_rga, +}; +#endif + #ifdef CONFIG_KEYS_RK29 extern struct rk29_keys_platform_data rk29_keys_pdata; static struct platform_device device_keys = { @@ -746,6 +768,9 @@ static int __init rk30_init_devices(void) #ifdef CONFIG_KEYS_RK29 platform_device_register(&device_keys); #endif +#ifdef CONFIG_RGA_RK30 + platform_device_register(&device_rga); +#endif #ifdef CONFIG_LCDC_RK30 platform_device_register(&device_lcdc); #endif diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 016839ca0b38..3c49a34c7cb6 100755 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -126,7 +126,7 @@ obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o obj-$(CONFIG_FB_PS3) += ps3fb.o obj-$(CONFIG_FB_RK29) += rk29_fb.o -obj-$(CONFIG_FB_ROCKCHIP) += rockchip/ +obj-y += rockchip/ obj-$(CONFIG_FB_SM501) += sm501fb.o obj-$(CONFIG_FB_UDL) += udlfb.o obj-$(CONFIG_FB_XILINX) += xilinxfb.o diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig index 9198783073db..87deb99d3a66 100644 --- a/drivers/video/rockchip/Kconfig +++ b/drivers/video/rockchip/Kconfig @@ -5,9 +5,12 @@ config FB_ROCKCHIP select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT ---help--- - Framebuffer driver for rochip based Platform + Framebuffer driver for rockchip based platform + config LCDC_RK30 tristate "Frame buffer driver support for rk30 lcdc " depends on FB_ROCKCHIP help Frame buffer driver for rk30 lcdc based boards. + +source "drivers/video/rockchip/rga/Kconfig" diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile index 184952bc7ab1..efd39468e08d 100644 --- a/drivers/video/rockchip/Makefile +++ b/drivers/video/rockchip/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_FB_ROCKCHIP) += rk_fb.o obj-$(CONFIG_LCDC_RK30) += chips/rk30_lcdc.o +obj-$(CONFIG_RGA_RK30) += rga/ diff --git a/drivers/video/rockchip/rga/Kconfig b/drivers/video/rockchip/rga/Kconfig new file mode 100644 index 000000000000..4653cd8a1c70 --- /dev/null +++ b/drivers/video/rockchip/rga/Kconfig @@ -0,0 +1,9 @@ +menu "RGA" + depends on ARCH_RK30 + +config RGA_RK30 + tristate "ROCKCHIP RK30 RGA" + help + rk30 rga module. + +endmenu diff --git a/drivers/video/rockchip/rga/Makefile b/drivers/video/rockchip/rga/Makefile new file mode 100644 index 000000000000..228838c635b2 --- /dev/null +++ b/drivers/video/rockchip/rga/Makefile @@ -0,0 +1,3 @@ +rga-y := rga_drv.o rga_mmu_info.o rga_reg_info.o RGA_API.o + +obj-$(CONFIG_RGA_RK30) += rga.o diff --git a/drivers/video/rockchip/rga/RGA_API.c b/drivers/video/rockchip/rga/RGA_API.c new file mode 100644 index 000000000000..f7e7d0b0dd6e --- /dev/null +++ b/drivers/video/rockchip/rga/RGA_API.c @@ -0,0 +1,330 @@ + +#include +#include "RGA_API.h" +#include "rga.h" +//#include "rga_angle.h" + +#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)) + +#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)) + +#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; + + +void +matrix_cal(const struct rga_req *msg, TILE_INFO *tile) +{ + uint32_t x_time, y_time; + uint64_t sina, cosa; + + int s_act_w, s_act_h, d_act_w, d_act_h; + + s_act_w = msg->src.act_w; + s_act_h = msg->src.act_h; + d_act_w = msg->dst.act_w; + d_act_h = msg->dst.act_h; + + if (s_act_w == 1) s_act_w += 1; + if (s_act_h == 1) s_act_h += 1; + if (d_act_h == 1) d_act_h += 1; + if (d_act_w == 1) d_act_w += 1; + + 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; + + switch(msg->rotate_mode) + { + /* 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[3] = cosa*y_time; + break; + case 2 : + 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[3] = -(y_time<<16); + break; + default : + tile->matrix[0] = (uint64_t)1<<32; + tile->matrix[1] = 0; + tile->matrix[2] = 0; + tile->matrix[3] = (uint64_t)1<<32; + break; + } +} + + + + +u32 +RGA_dst_act_addr_temp(const struct rga_req *msg) +{ + u32 pw; + u32 x_off, y_off; + u32 stride; + u32 p; + + pw = RGA_pixel_width_init(msg->dst.format); + stride = (msg->dst.vir_w * pw + 3) & (~3); + + x_off = msg->dst.x_offset; + y_off = msg->dst.y_offset; + + p = (u32)((stride * y_off) + (x_off * pw)); + + return p; +} + +void +RGA_set_cmd_info(u8 cmd_mode, u32 cmd_addr) +{ + u32 reg = 0; + + //reg = rRGA_SYS_CTRL; + reg |= ((cmd_mode & 1) << 1); + rRGA_SYS_CTRL = reg; + rRGA_CMD_ADDR = cmd_addr; +} + +void +RGA_start(void) +{ + u32 reg = 0; + u8 cmd_mode; + + reg = rRGA_SYS_CTRL; + cmd_mode = (reg >> 2) & 1; + + if (cmd_mode == 0) + { + /* passive */ + reg |= (1<<1); + rRGA_SYS_CTRL = reg; + } + else + { + /* master */ + reg = rRGA_CMD_CTRL; + reg |= 1; + rRGA_CMD_CTRL = reg; + } +} + + +void +RGA_soft_reset(void) +{ + u32 reg = 0; + + reg = rRGA_SYS_CTRL; + reg |= 1; + rRGA_SYS_CTRL = reg; +} + + +#if 0 +/*****************************************/ +//hxx add,2011.6.24 +void rga_one_op_st_master(RGA_INFO *p_rga_info) +{ + rRGA_SYS_CTRL = 0x4; + + rRGA_INT = s_RGA_INT_ALL_CMD_DONE_INT_EN(p_rga_info->int_info.all_cmd_done_int_en)| + s_RGA_INT_MMU_INT_EN(p_rga_info->int_info.mmu_int_en)| + s_RGA_INT_ERROR_INT_EN(p_rga_info->int_info.error_int_en); + + rRGA_CMD_ADDR = (u32) p_rga_info->sys_info.p_cmd_mst; + + rRGA_CMD_CTRL = 0x3; +} + + +void rga_set_int_info(MSG *p_msg,RGA_INFO *p_rga_info) +{ + p_msg->CMD_fin_int_enable = p_rga_info->int_info.cur_cmd_done_int_en; +} + + +void rga_check_int_all_cmd_finish(RGA_INFO *p_rga_info) +{ + u8 int_flag; + + int_flag = 0; + while(!int_flag) + { + int_flag = rRGA_INT & m_RGA_INT_ALL_CMD_DONE_INT_FLAG; + } + rRGA_INT = rRGA_INT | s_RGA_INT_ALL_CMD_DONE_INT_CLEAR(0x1); + + //if(p_rga_info->sys_info.p_cmd_mst != NULL) + // free(p_rga_info->sys_info.p_cmd_mst); +} +#endif + +void rga_start_cmd_AXI(u8 *base, u32 num) +{ + rRGA_SYS_CTRL = 0x4; + rRGA_INT = s_RGA_INT_ALL_CMD_DONE_INT_EN(ENABLE)| s_RGA_INT_MMU_INT_EN(ENABLE)| s_RGA_INT_ERROR_INT_EN(ENABLE); + rRGA_CMD_ADDR = (u32)base; + rRGA_CMD_CTRL |= (num<<3); + rRGA_CMD_CTRL |= 0x3; +} + +void rga_check_cmd_finish(void) +{ + u8 int_flag; + u8 error_flag; + + int_flag = 0; + error_flag = 0; + + while(!int_flag) + { + int_flag = rRGA_INT & m_RGA_INT_ALL_CMD_DONE_INT_FLAG; + error_flag = rRGA_INT & (m_RGA_INT_ERROR_INT_FLAG); + + if(error_flag) + { + printk("~~~~~ ERROR INTTUR OCCUR ~~~~~\n"); + } + error_flag = rRGA_INT & m_RGA_INT_MMU_INT_FLAG; + if(error_flag) + { + printk("~~~~~ MMU ERROR INTTUR OCCUR ~~~~~\n"); + } + } + rRGA_INT = rRGA_INT | s_RGA_INT_ALL_CMD_DONE_INT_CLEAR(0x1); +} + + + +void rga_start_cmd_AHB(u8 *base) +{ + u32 *base_p32; + + base_p32 = (u32 *)base; + *base_p32 = (*base_p32 | (1<<29)); + + memcpy((u8 *)(RGA_BASE + 0x100), base, 28*4); + + rRGA_SYS_CTRL = 0x2; +} + + +void rga_check_cmd_AHB_finish(void) +{ + u8 int_flag; + + int_flag = 0; + while(!int_flag) + { + int_flag = rRGA_INT & m_RGA_INT_NOW_CMD_DONE_INT_FLAG; + } + rRGA_INT = rRGA_INT | s_RGA_INT_NOW_CMD_DONE_INT_CLEAR(0x1); +} + + + +uint32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1) +{ + + struct rga_req *mp; + u32 w_ratio, h_ratio; + u32 stride; + + u32 daw, dah; + u32 pl; + + daw = dah = 0; + + mp = msg1; + w_ratio = (msg->src.act_w << 16) / msg->dst.act_w; + h_ratio = (msg->src.act_h << 16) / msg->dst.act_h; + + memcpy(&mp->src, &msg->src, sizeof(rga_img_info_t)); + + mp->dst.format = msg->src.format; + + /*pre_scale_w cal*/ + if ((w_ratio >= (2<<16)) && (w_ratio < (4<<16))) { + daw = (msg->src.act_w + 1) >> 1; + if((IS_YUV_420(mp->dst.format)) && (daw & 1)) { + mp->src.act_w = (daw - 1) << 1; + } + } + else if ((w_ratio >= (4<<16)) && (w_ratio < (8<<16))) { + daw = (msg->src.act_w + 3) >> 2; + if((IS_YUV_420(mp->dst.format)) && (daw & 1)) { + mp->src.act_w = (daw - 1) << 2; + } + } + else if ((w_ratio >= (8<<16)) && (w_ratio < (16<<16))) { + daw = (msg->src.act_w + 7) >> 3; + if((IS_YUV_420(mp->dst.format)) && (daw & 1)) { + mp->src.act_w = (daw - 1) << 3; + } + } + + pl = (RGA_pixel_width_init(msg->src.format)); + stride = (pl * daw + 3) & (~3); + mp->dst.act_w = daw; + mp->dst.vir_w = stride / pl; + + /*pre_scale_h cal*/ + if ((h_ratio >= (2<<16)) && (h_ratio < (4<<16))) { + dah = (msg->src.act_h + 1) >> 1; + if((IS_YUV(mp->dst.format)) && (dah & 1)) { + mp->src.act_h = (dah - 1) << 1; + } + } + else if ((h_ratio >= (4<<16)) && (h_ratio < (8<<16))) { + dah = (msg->src.act_h + 3) >> 2; + if((IS_YUV(mp->dst.format)) && (dah & 1)) { + mp->src.act_h = (dah - 1) << 2; + } + } + else if ((h_ratio >= (8<<16)) && (h_ratio < (16<<16))) { + dah = (msg->src.act_h + 7) >> 3; + if((IS_YUV(mp->dst.format)) && (dah & 1)) { + mp->src.act_h = (dah - 1) << 3; + } + } + mp->dst.act_h = dah; + mp->dst.vir_h = dah; + + mp->dst.yrgb_addr = (u32)rga_service.pre_scale_buf; + mp->dst.uv_addr = mp->dst.yrgb_addr + stride * dah; + mp->dst.v_addr = mp->dst.uv_addr + ((stride * dah) >> 1); + + mp->render_mode = pre_scaling_mode; + + memcpy(&msg->src, &mp->dst, sizeof(rga_img_info_t)); + + return 0; +} + + diff --git a/drivers/video/rockchip/rga/RGA_API.h b/drivers/video/rockchip/rga/RGA_API.h new file mode 100644 index 000000000000..59879e25ae9d --- /dev/null +++ b/drivers/video/rockchip/rga/RGA_API.h @@ -0,0 +1,227 @@ +#ifndef __RGA_API_H__ +#define __RGA_API_H__ + +#include "rga_reg_info.h" +#include "rga.h" + +#define ENABLE 1 +#define DISABLE 0 + +#if 0 +int +RGA_set_src_act_info( + msg_t *msg, + unsigned int width, /* act width */ + unsigned int height, /* act height */ + unsigned int x_off, /* x_off */ + unsigned int y_off /* y_off */ + ); + +int +RGA_set_src_vir_info( + msg_t *msg, + unsigned int yrgb_addr, /* yrgb_addr */ + unsigned int uv_addr, /* uv_addr */ + unsigned int v_addr, /* v_addr */ + unsigned int vir_w, /* vir width */ + unsigned int vir_h, /* vir height */ + unsigned char format, /* format */ + unsigned char a_swap_en + ); + +int +RGA_set_dst_act_info( + msg_t *msg, + unsigned int width, /* act width */ + unsigned int height, /* act height */ + unsigned int x_off, /* x_off */ + unsigned int y_off /* y_off */ + ); + +int +RGA_set_dst_vir_info( + msg_t *msg, + unsigned int yrgb_addr, /* yrgb_addr */ + unsigned int uv_addr, /* uv_addr */ + unsigned int v_addr, /* v_addr */ + unsigned int vir_w, /* vir width */ + unsigned int vir_h, /* vir height */ + RECT clip, /* clip window*/ + unsigned char format, /* format */ + unsigned char a_swap_en ); + + + +int +RGA_set_rop_mask_info( + msg_t *msg, + u32 rop_mask_addr, + u32 rop_mask_endian_mode); + +int +RGA_set_pat_info( + msg_t *msg, + u32 width, + u32 height, + u32 x_off, + u32 y_off, + u32 pat_format); + +int +RGA_set_alpha_en_info( + msg_t *msg, + unsigned int alpha_cal_mode, + unsigned int alpha_mode, + unsigned int global_a_value, + unsigned int PD_en, + unsigned int PD_mode + ); + +int +RGA_set_rop_en_info( + msg_t *msg, + unsigned int ROP_mode, + unsigned int ROP_code, + unsigned int color_mode, + unsigned int solid_color); + +/* +int +RGA_set_MMU_info( + MSG *msg, + unsigned int base_addr, + unsigned int src_flush, + unsigned int dst_flush, + unsigned int cmd_flush, + unsigned int page_size + ); +*/ + +int +RGA_set_MMU_info( + msg_t *msg, + u8 mmu_en, + u8 src_flush, + u8 dst_flush, + u8 cmd_flush, + u32 base_addr, + u8 page_size); + + +int +RGA_set_bitblt_mode( + msg_t *msg, + unsigned char scale_mode, // 0/near 1/bilnear 2/bicubic + unsigned char rotate_mode, // 0/copy 1/rotate_scale 2/x_mirror 3/y_mirror + unsigned int angle, // rotate angle (0~359) + unsigned int dither_en, // dither en flag + unsigned int AA_en, // AA flag + unsigned int yuv2rgb_mode + ); + + +int +RGA_set_color_palette_mode( + msg_t *msg, + u8 palette_mode, /* 1bpp/2bpp/4bpp/8bpp */ + u8 endian_mode, /* src endian mode sel */ + u32 bpp1_0_color, /* BPP1 = 0 */ + u32 bpp1_1_color /* BPP1 = 1 */ + ); + + + +int +RGA_set_color_fill_mode( + msg_t *msg, + CF_GR_COLOR gr_color, /* gradient color part*/ + u8 gr_satur_mode, /* saturation mode */ + u8 cf_mode, /* patten fill or solid fill */ + u32 color, /* solid color */ + u16 pat_width, /* pat_width */ + u16 pat_height, /* pat_height */ + u8 pat_x_off, /* patten x offset */ + u8 pat_y_off, /* patten y offset */ + u8 aa_en /* alpha en */ + ); + + +int +RGA_set_line_point_drawing_mode( + msg_t *msg, + POINT sp, /* start point */ + POINT ep, /* end point */ + unsigned int color, /* line point drawing color */ + unsigned int line_width, /* line width */ + unsigned char AA_en, /* AA en */ + unsigned char last_point_en /* last point en */ + ); + + + +int +RGA_set_blur_sharp_filter_mode( + msg_t *msg, + unsigned char filter_mode, /* blur/sharpness */ + unsigned char filter_type, /* filter intensity */ + unsigned char dither_en /* dither_en flag */ + ); + +int +RGA_set_pre_scaling_mode( + msg_t *msg, + unsigned char dither_en + ); + + +int +RGA_update_palette_table_mode( + msg_t *msg, + unsigned int LUT_addr, /* LUT table addr */ + unsigned int palette_mode /* 1bpp/2bpp/4bpp/8bpp */ + ); + + +int +RGA_set_update_patten_buff_mode( + msg_t *msg, + unsigned int pat_addr, /* patten addr */ + unsigned int w, /* patten width */ + unsigned int h, /* patten height */ + unsigned int format /* patten format */ + ); +/* +int +RGA_set_MMU_info( + MSG *msg, + unsigned int base_addr, + unsigned int src_flush, + unsigned int dst_flush, + unsigned int cmd_flush, + unsigned int page_size + ); +*/ + +int +RGA_set_mmu_info( + msg_t *msg, + u8 mmu_en, + u8 src_flush, + u8 dst_flush, + u8 cmd_flush, + u32 base_addr, + u8 page_size); + +msg_t * RGA_init_msg(void); +int RGA_free_msg(msg_t *msg); +void matrix_cal(msg_t *msg, TILE_INFO *tile); +unsigned char * RGA_set_reg_info(msg_t *msg, u8 *base); +void RGA_set_cmd_info(u8 cmd_mode, u32 cmd_addr); +void RGA_start(void); +void RGA_soft_reset(void); +#endif + +uint32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1); + + +#endif diff --git a/drivers/video/rockchip/rga/rga.h b/drivers/video/rockchip/rga/rga.h new file mode 100644 index 000000000000..68b7fdb36c96 --- /dev/null +++ b/drivers/video/rockchip/rga/rga.h @@ -0,0 +1,483 @@ +#ifndef _RGA_DRIVER_H_ +#define _RGA_DRIVER_H_ + +#include "rga_type.h" +#include +#include +#include + + +#define RGA_BLIT_SYNC 0x5017 +#define RGA_BLIT_ASYNC 0x5018 +#define RGA_FLUSH 0x5019 + + +#define RGA_REG_CTRL_LEN 0x8 /* 8 */ +#define RGA_REG_CMD_LEN 0x1c /* 28 */ +#define RGA_CMD_BUF_SIZE 0x700 /* 16*28*4 */ + + +/* RGA process mode enum */ +enum +{ + bitblt_mode = 0x0, + color_palette_mode = 0x1, + color_fill_mode = 0x2, + line_point_drawing_mode = 0x3, + blur_sharp_filter_mode = 0x4, + pre_scaling_mode = 0x5, + update_palette_table_mode = 0x6, + update_patten_buff_mode = 0x7, +}; + + +enum +{ + rop_enable_mask = 0x2, + dither_enable_mask = 0x8, + fading_enable_mask = 0x10, + PD_enbale_mask = 0x20, +}; + +enum +{ + yuv2rgb_mode0 = 0x0, /* BT.601 MPEG */ + yuv2rgb_mode1 = 0x1, /* BT.601 JPEG */ + yuv2rgb_mode2 = 0x2, /* BT.709 */ +}; + + +/* RGA rotate mode */ +enum +{ + rotate_mode0 = 0x0, /* no rotate */ + rotate_mode1 = 0x1, /* rotate */ + rotate_mode2 = 0x2, /* x_mirror */ + rotate_mode3 = 0x3, /* y_mirror */ +}; + +enum +{ + color_palette_mode0 = 0x0, /* 1K */ + color_palette_mode1 = 0x1, /* 2K */ + color_palette_mode2 = 0x2, /* 4K */ + color_palette_mode3 = 0x3, /* 8K */ +}; + + + +/* +// Alpha Red Green Blue +{ 4, 32, {{32,24, 8, 0, 16, 8, 24,16 }}, GGL_RGBA }, // RK_FORMAT_RGBA_8888 +{ 4, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // RK_FORMAT_RGBX_8888 +{ 3, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // RK_FORMAT_RGB_888 +{ 4, 32, {{32,24, 24,16, 16, 8, 8, 0 }}, GGL_BGRA }, // RK_FORMAT_BGRA_8888 +{ 2, 16, {{ 0, 0, 16,11, 11, 5, 5, 0 }}, GGL_RGB }, // RK_FORMAT_RGB_565 +{ 2, 16, {{ 1, 0, 16,11, 11, 6, 6, 1 }}, GGL_RGBA }, // RK_FORMAT_RGBA_5551 +{ 2, 16, {{ 4, 0, 16,12, 12, 8, 8, 4 }}, GGL_RGBA }, // RK_FORMAT_RGBA_4444 +{ 3, 24, {{ 0, 0, 24,16, 16, 8, 8, 0 }}, GGL_BGR }, // RK_FORMAT_BGB_888 + +*/ +enum +{ + RK_FORMAT_RGBA_8888 = 0x0, + RK_FORMAT_RGBX_8888 = 0x1, + RK_FORMAT_RGB_888 = 0x2, + RK_FORMAT_BGRA_8888 = 0x3, + RK_FORMAT_RGB_565 = 0x4, + RK_FORMAT_RGBA_5551 = 0x5, + RK_FORMAT_RGBA_4444 = 0x6, + RK_FORMAT_BGR_888 = 0x7, + + RK_FORMAT_YCbCr_422_SP = 0x8, + RK_FORMAT_YCbCr_422_P = 0x9, + RK_FORMAT_YCbCr_420_SP = 0xa, + RK_FORMAT_YCbCr_420_P = 0xb, + + RK_FORMAT_YCrCb_422_SP = 0xc, + RK_FORMAT_YCrCb_422_P = 0xd, + RK_FORMAT_YCrCb_420_SP = 0xe, + RK_FORMAT_YCrCb_420_P = 0xf, + + RK_FORMAT_BPP1 = 0x10, + RK_FORMAT_BPP2 = 0x11, + RK_FORMAT_BPP4 = 0x12, + RK_FORMAT_BPP8 = 0x13, +}; + + +typedef struct rga_img_info_t +{ + uint32 yrgb_addr; /* yrgb mem addr */ + uint32 uv_addr; /* cb/cr mem addr */ + uint32 v_addr; /* cr mem addr */ + uint32 format; //definition by RK_FORMAT + + UWORD16 act_w; + UWORD16 act_h; + UWORD16 x_offset; + UWORD16 y_offset; + + UWORD16 vir_w; + UWORD16 vir_h; + + UWORD16 endian_mode; //for BPP + UWORD16 alpha_swap; +} +rga_img_info_t; + + +typedef struct mdp_img_act +{ + UWORD16 w; // width + UWORD16 h; // height + WORD16 x_off; // x offset for the vir + WORD16 y_off; // y offset for the vir +} +mdp_img_act; + + + +typedef struct RANGE +{ + UWORD16 min; + UWORD16 max; +} +RANGE; + +typedef struct POINT +{ + UWORD16 x; + UWORD16 y; +} +POINT; + +typedef struct RECT +{ + WORD16 xmin; + WORD16 xmax; // width - 1 + WORD16 ymin; + WORD16 ymax; // height - 1 +} RECT; + +typedef struct RGB +{ + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char res; +}RGB; + + +typedef struct MMU +{ + unsigned char mmu_en; + uint32 base_addr; + uint32 mmu_flag; /* [0] mmu enable [1] src_flush [2] dst_flush [3] CMD_flush [4~5] page size*/ +} MMU; + + + + +typedef struct COLOR_FILL +{ + short gr_x_a; + short gr_y_a; + short gr_x_b; + short gr_y_b; + short gr_x_g; + short gr_y_g; + short gr_x_r; + short gr_y_r; + + //u8 cp_gr_saturation; +} +COLOR_FILL; + +typedef struct FADING +{ + UBYTE b; + UBYTE g; + UBYTE r; + UBYTE res; +} +FADING; + + +typedef struct line_draw_t +{ + POINT start_point; /* LineDraw_start_point */ + POINT end_point; /* LineDraw_end_point */ + uint32 color; /* LineDraw_color */ + uint32 flag; /* (enum) LineDrawing mode sel */ + uint32 line_width; /* range 1~16 */ +} +line_draw_t; + + + +struct rga_req { + UBYTE render_mode; /* (enum) process mode sel */ + + rga_img_info_t src; /* src image info */ + rga_img_info_t dst; /* dst image info */ + rga_img_info_t pat; /* patten image info */ + + uint32 rop_mask_addr; /* rop4 mask addr */ + uint32 LUT_addr; /* LUT addr */ + + RECT clip; /* dst clip window default value is dst_vir */ + /* value from [0, w-1] / [0, h-1]*/ + + int32_t sina; /* dst angle default value 0 16.16 scan from table */ + int32_t cosa; /* dst angle default value 0 16.16 scan from table */ + + uint16_t alpha_rop_flag; /* alpha rop process flag */ + /* ([0] = 1 alpha_rop_enable) */ + /* ([1] = 1 rop enable) */ + /* ([2] = 1 fading_enable) */ + /* ([3] = 1 PD_enable) */ + /* ([4] = 1 alpha cal_mode_sel) */ + /* ([5] = 1 dither_enable) */ + /* ([6] = 1 gradient fill mode sel) */ + /* ([7] = 1 AA_enable) */ + + uint8_t scale_mode; /* 0 nearst / 1 bilnear / 2 bicubic */ + + uint32 color_key_max; /* color key max */ + uint32 color_key_min; /* color key min */ + + uint32 fg_color; /* foreground color */ + uint32 bg_color; /* background color */ + + COLOR_FILL gr_color; /* color fill use gradient */ + + line_draw_t line_draw_info; + + FADING fading; + + uint8_t PD_mode; /* porter duff alpha mode sel */ + + uint8_t alpha_global_value; /* global alpha value */ + + uint16_t rop_code; /* rop2/3/4 code scan from rop code table*/ + + uint8_t bsfilter_flag; /* [2] 0 blur 1 sharp / [1:0] filter_type*/ + + uint8_t palette_mode; /* (enum) color palatte 0/1bpp, 1/2bpp 2/4bpp 3/8bpp*/ + + uint8_t yuv2rgb_mode; /* (enum) BT.601 MPEG / BT.601 JPEG / BT.709 */ + + uint8_t endian_mode; /* 0/big endian 1/little endian*/ + + uint8_t rotate_mode; /* (enum) rotate mode */ + /* 0x0, no rotate */ + /* 0x1, rotate */ + /* 0x2, x_mirror */ + /* 0x3, y_mirror */ + + uint8_t color_fill_mode; /* 0 solid color / 1 patten color */ + + MMU mmu_info; /* mmu information */ + + uint8_t alpha_rop_mode; /* ([0~1] alpha mode) */ + /* ([2~3] rop mode) */ + /* ([4] zero mode en) */ + /* ([5] dst alpha mode) */ + + uint8_t src_trans_mode; + + uint8_t CMD_fin_int_enable; + + /* completion is reported through a callback */ + void (*complete)(int retval); +}; + + +typedef struct TILE_INFO +{ + int64_t matrix[4]; + + uint16_t tile_x_num; /* x axis tile num / tile size is 8x8 pixel */ + uint16_t tile_y_num; /* y axis tile num */ + + int16_t dst_x_tmp; /* dst pos x = (xstart - xoff) default value 0 */ + int16_t dst_y_tmp; /* dst pos y = (ystart - yoff) default value 0 */ + + uint16_t tile_w; + uint16_t tile_h; + int16_t tile_start_x_coor; + int16_t tile_start_y_coor; + int32_t tile_xoff; + int32_t tile_yoff; + + int32_t tile_temp_xstart; + int32_t tile_temp_ystart; + + /* src tile incr */ + int32_t x_dx; + int32_t x_dy; + int32_t y_dx; + int32_t y_dy; + + mdp_img_act dst_ctrl; + +} +TILE_INFO; + + +/** + * struct for process session which connect to rga + * + * @author ZhangShengqin (2012-2-15) + */ +typedef struct rga_session { + /* a linked list of data so we can access them for debugging */ + struct list_head list_session; + /* a linked list of register data waiting for process */ + struct list_head waiting; + /* a linked list of register data in processing */ + struct list_head running; + /* all coommand this thread done */ + uint32_t done; + wait_queue_head_t wait; + pid_t pid; + atomic_t task_running; +} rga_session; + +struct rga_reg { + rga_session *session; + struct list_head session_link; /* link to rga service session */ + struct list_head status_link; /* link to register set list */ + uint32_t sys_reg[RGA_REG_CTRL_LEN]; + uint32_t cmd_reg[RGA_REG_CMD_LEN]; + uint32_t *MMU_base; + atomic_t int_enable; +}; + + + +typedef struct rga_service_info { + spinlock_t lock; + struct timer_list timer; /* timer for power off */ + struct list_head waiting; /* link to link_reg in struct vpu_reg */ + struct list_head running; /* link to link_reg in struct vpu_reg */ + struct list_head done; /* link to link_reg in struct vpu_reg */ + struct list_head session; /* link to list_session in struct vpu_session */ + atomic_t total_running; + bool enabled; + struct rga_reg *reg; + uint32_t cmd_buff[28*16];/* cmd_buff for rga */ + uint32_t *pre_scale_buf; + atomic_t int_disable; /* 0 int enable 1 int disable */ +} rga_service_info; + + + + +struct rga_drvdata { + struct miscdevice miscdev; + struct device dev; + void *rga_base; + int irq0; + + struct clk *pd_display; + struct clk *aclk_lcdc; + struct clk *hclk_lcdc; + struct clk *aclk_ddr_lcdc; + struct clk *hclk_cpu_display; + struct clk *aclk_disp_matrix; + struct clk *hclk_disp_matrix; + struct clk *axi_clk; + struct clk *ahb_clk; + + struct mutex mutex; // mutex + + struct delayed_work power_off_work; + bool enable; //clk enable or disable + void (*rga_irq_callback)(int rga_retval); //callback function used by aync call +}; + + + + + +#define RGA_BASE 0x10114000 + +//General Registers +#define RGA_SYS_CTRL 0x000 +#define RGA_CMD_CTRL 0x004 +#define RGA_CMD_ADDR 0x008 +#define RGA_STATUS 0x00c +#define RGA_INT 0x010 +#define RGA_AXI_ID 0x014 +#define RGA_MMU_STA_CTRL 0x018 +#define RGA_MMU_STA 0x01c + +//Command code start +#define RGA_MODE_CTRL 0x100 + +//Source Image Registers +#define RGA_SRC_Y_MST 0x104 +#define RGA_SRC_CB_MST 0x108 +#define RGA_MASK_READ_MST 0x108 //repeat +#define RGA_SRC_CR_MST 0x10c +#define RGA_SRC_VIR_INFO 0x110 +#define RGA_SRC_ACT_INFO 0x114 +#define RGA_SRC_X_PARA 0x118 +#define RGA_SRC_Y_PARA 0x11c +#define RGA_SRC_TILE_XINFO 0x120 +#define RGA_SRC_TILE_YINFO 0x124 +#define RGA_SRC_TILE_H_INCR 0x128 +#define RGA_SRC_TILE_V_INCR 0x12c +#define RGA_SRC_TILE_OFFSETX 0x130 +#define RGA_SRC_TILE_OFFSETY 0x134 +#define RGA_SRC_BG_COLOR 0x138 +#define RGA_SRC_FG_COLOR 0x13c +#define RGA_LINE_DRAWING_COLOR 0x13c //repeat +#define RGA_SRC_TR_COLOR0 0x140 +#define RGA_CP_GR_A 0x140 //repeat +#define RGA_SRC_TR_COLOR1 0x144 +#define RGA_CP_GR_B 0x144 //repeat + +#define RGA_LINE_DRAW 0x148 +#define RGA_PAT_START_POINT 0x148 //repeat + +//Destination Image Registers +#define RGA_DST_MST 0x14c +#define RGA_LUT_MST 0x14c //repeat +#define RGA_PAT_MST 0x14c //repeat +#define RGA_LINE_DRAWING_MST 0x14c //repeat + +#define RGA_DST_VIR_INFO 0x150 + +#define RGA_DST_CTR_INFO 0x154 +#define RGA_LINE_DRAW_XY_INFO 0x154 //repeat + +//Alpha/ROP Registers +#define RGA_ALPHA_CON 0x158 + +#define RGA_PAT_CON 0x15c +#define RGA_DST_VIR_WIDTH_PIX 0x15c //repeat + +#define RGA_ROP_CON0 0x160 +#define RGA_CP_GR_G 0x160 //repeat +#define RGA_PRESCL_CB_MST 0x160 //repeat + +#define RGA_ROP_CON1 0x164 +#define RGA_CP_GR_R 0x164 //repeat +#define RGA_PRESCL_CR_MST 0x164 //repeat + +//MMU Register +#define RGA_FADING_CON 0x168 +#define RGA_MMU_CTRL 0x168 //repeat + +#define RGA_MMU_TBL 0x16c //repeat + + +#define RGA_BLIT_COMPLETE_EVENT 1 + + + + +#endif /*_RK29_IPP_DRIVER_H_*/ diff --git a/drivers/video/rockchip/rga/rga_drv.c b/drivers/video/rockchip/rga/rga_drv.c new file mode 100644 index 000000000000..1bc9c0e64c9a --- /dev/null +++ b/drivers/video/rockchip/rga/rga_drv.c @@ -0,0 +1,989 @@ +/* + * 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. + * + */ + +#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 + + +#include "rga.h" +#include "rga_reg_info.h" +#include "rga_mmu_info.h" +#include "RGA_API.h" + + +#define PRE_SCALE_BUF_SIZE 2048*1024*4 + +#define RGA_POWER_OFF_DELAY 4*HZ /* 4s */ +#define RGA_TIMEOUT_DELAY 2*HZ /* 2s */ + + + + +static struct rga_drvdata *drvdata = NULL; +rga_service_info rga_service; + + +static int rga_blit_async(rga_session *session, struct rga_req *req); + + +#define RGA_MAJOR 232 + +#define RK30_RGA_PHYS 0x10114000 +#define RK30_RGA_SIZE SZ_8K +#define RGA_RESET_TIMEOUT 1000 + +/* Driver information */ +#define DRIVER_DESC "RGA Device Driver" +#define DRIVER_NAME "rga" + + +/* Logging */ +#define RGA_DEBUG 0 +#if RGA_DEBUG +#define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) +#define ERR(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) +#define WARNING(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) +#define INFO(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) +#else +#define DBG(format, args...) +#define ERR(format, args...) +#define WARNING(format, args...) +#define INFO(format, args...) +#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("total_running %d\n", running); + + 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 void rga_power_on(void) +{ + //printk("rga_power_on\n"); + cancel_delayed_work_sync(&drvdata->power_off_work); + if (drvdata->enable) + return; + + clk_enable(drvdata->pd_display); + clk_enable(drvdata->aclk_lcdc); + clk_enable(drvdata->hclk_lcdc); + clk_enable(drvdata->aclk_ddr_lcdc); + clk_enable(drvdata->hclk_cpu_display); + clk_enable(drvdata->aclk_disp_matrix); + clk_enable(drvdata->hclk_disp_matrix); + clk_enable(drvdata->axi_clk); + clk_enable(drvdata->ahb_clk); + + drvdata->enable = true; +} + + +static void rga_power_off(struct work_struct *work) +{ + int total_running; + + //printk("rga_power_off\n"); + if(!drvdata->enable) + return; + + total_running = atomic_read(&rga_service.total_running); + if (total_running) { + pr_alert("power off when %d task running!!\n", total_running); + mdelay(50); + pr_alert("delay 50 ms for running task\n"); + rga_dump(); + } + + clk_disable(drvdata->pd_display); + clk_disable(drvdata->aclk_lcdc); + clk_disable(drvdata->hclk_lcdc); + clk_disable(drvdata->aclk_ddr_lcdc); + clk_disable(drvdata->hclk_cpu_display); + clk_disable(drvdata->aclk_disp_matrix); + clk_disable(drvdata->hclk_disp_matrix); + clk_disable(drvdata->axi_clk); + clk_disable(drvdata->ahb_clk); + + drvdata->enable = false; +} + + +static int rga_flush(rga_session *session, unsigned long arg) +{ + //printk("rga_get_result %d\n",drvdata->rga_result); + + int ret; + + ret = wait_event_interruptible_timeout(session->wait, session->done, RGA_TIMEOUT_DELAY); + + if (unlikely(ret < 0)) { + pr_err("pid %d wait task ret %d\n", session->pid, ret); + } else if (0 == ret) { + pr_err("pid %d wait %d task done timeout\n", session->pid, atomic_read(&session->task_running)); + ret = -ETIMEDOUT; + } + + return ret; +} + + +static int rga_check_param(const struct rga_req *req) +{ + #if 1 + /*RGA can support up to 8192*8192 resolution in RGB format,but we limit the image size to 8191*8191 here*/ + //check src width and height + if (unlikely((req->src.act_w < 0) || (req->src.act_w > 8191) || (req->src.act_h < 0) || (req->src.act_h > 8191))) { + ERR("invalid source resolution\n"); + return -EINVAL; + } + + //check dst width and height + if (unlikely((req->dst.act_w < 0) || (req->dst.act_w > 2048) || (req->dst.act_h < 16) || (req->dst.act_h > 2048))) { + ERR("invalid destination resolution\n"); + return -EINVAL; + } + + //check src_vir_w + if(unlikely(req->src.vir_w < req->src.act_w)){ + ERR("invalid src_vir_w\n"); + return -EINVAL; + } + + //check dst_vir_w + if(unlikely(req->dst.vir_w < req->dst.act_w)){ + ERR("invalid dst_vir_w\n"); + return -EINVAL; + } + + //check src address + if (unlikely(req->src.yrgb_addr == 0)) + { + ERR("could not retrieve src image from memory\n"); + return -EINVAL; + } + + //check src address + if (unlikely(req->dst.yrgb_addr == 0)) + { + ERR("could not retrieve dst image from memory\n"); + return -EINVAL; + } + #endif + + + return 0; +} + +static void rga_copy_reg(struct rga_reg *reg, uint32_t offset) +{ + uint32_t i; + uint32_t *cmd_buf; + uint32_t *reg_p; + + atomic_add(1, &rga_service.total_running); + atomic_add(1, ®->session->task_running); + + cmd_buf = (uint32_t *)rga_service.cmd_buff + offset*28; + reg_p = (uint32_t *)reg->cmd_reg; + + for(i=0; i<28; i++) + { + cmd_buf[i] = reg_p[i]; + } +} + + +static struct rga_reg * rga_reg_init(rga_session *session, struct rga_req *req) +{ + unsigned long flag; + struct rga_reg *reg = kmalloc(sizeof(struct rga_reg), GFP_KERNEL); + if (NULL == reg) { + pr_err("kmalloc fail in rga_reg_init\n"); + return NULL; + } + + reg->session = session; + INIT_LIST_HEAD(®->session_link); + INIT_LIST_HEAD(®->status_link); + + rga_set_mmu_info(reg, req); + RGA_gen_reg_info(req, (uint8_t *)reg->cmd_reg); + + spin_lock_irqsave(&rga_service.lock, flag); + list_add_tail(®->status_link, &rga_service.waiting); + list_add_tail(®->session_link, &session->waiting); + spin_unlock_irqrestore(&rga_service.lock, flag); + + return reg; +} + +static void rga_reg_deinit(struct rga_reg *reg) +{ + list_del_init(®->session_link); + list_del_init(®->status_link); + kfree(reg); +} + +static void rga_reg_from_wait_to_run(struct rga_reg *reg) +{ + list_del_init(®->status_link); + list_add_tail(®->status_link, &rga_service.running); + + list_del_init(®->session_link); + list_add_tail(®->session_link, ®->session->running); +} + +#if 0 +static void rga_reg_from_run_to_done(struct rga_reg *reg) +{ + spin_lock(&rga_service.lock); + list_del_init(®->status_link); + list_add_tail(®->status_link, &rga_service.done); + + list_del_init(®->session_link); + list_add_tail(®->session_link, ®->session->done); + + atomic_sub(1, ®->session->task_running); + atomic_sub(1, &rga_service.total_running); + wake_up_interruptible_sync(®->session->wait); + spin_unlock(&rga_service.lock); +} +#endif + + +static void rga_service_session_clear(rga_session *session) +{ + struct rga_reg *reg, *n; + + list_for_each_entry_safe(reg, n, &session->waiting, session_link) + { + rga_reg_deinit(reg); + } + + list_for_each_entry_safe(reg, n, &session->running, session_link) + { + rga_reg_deinit(reg); + } +} + + +static void rga_try_set_reg(void) +{ + unsigned long flag; + + // first get reg from reg list + spin_lock_irqsave(&rga_service.lock, flag); + if (!list_empty(&rga_service.waiting)) + { + struct rga_reg *reg = list_entry(rga_service.waiting.next, struct rga_reg, status_link); + + if(!(rga_read(RGA_STATUS) & 0x1)) + { + /* RGA is busy */ + if((atomic_read(&rga_service.total_running) <= 0xf) && (atomic_read(&rga_service.int_disable) == 0)) + { + rga_copy_reg(reg, atomic_read(&rga_service.total_running)); + rga_reg_from_wait_to_run(reg); + rga_write(RGA_INT, 0x1<<10); + reg->session->done = 0; + rga_write(RGA_CMD_CTRL, (0x1<<3)|(0x1<<1)); + if(atomic_read(®->int_enable)) + atomic_set(&rga_service.int_disable, 1); + } + } + else + { + /* RGA is idle */ + rga_copy_reg(reg, 0); + rga_reg_from_wait_to_run(reg); + + /* MMU */ + rga_write(RGA_CMD_ADDR, 0); + + /* All CMD finish int */ + rga_write(RGA_INT, 0x1<<10); + + /* Start proc */ + reg->session->done = 0; + rga_write(RGA_CMD_CTRL, (0x1<<3)|0x1); + } + } + spin_unlock_irqrestore(&rga_service.lock, flag); +} + + + +static int rga_blit_async(rga_session *session, struct rga_req *req) +{ + int ret = -1; + struct rga_reg *reg0, *reg1; + struct rga_req *req2; + + uint32_t saw, sah, daw, dah; + + saw = req->src.act_w; + sah = req->src.act_h; + daw = req->dst.act_w; + dah = req->dst.act_h; + + if((req->render_mode == bitblt_mode) && (((saw>>1) >= daw) || ((sah>>1) >= dah))) + { + /* generate 2 cmd for pre scale */ + + req2 = kmalloc(sizeof(struct rga_req), GFP_KERNEL); + if(NULL == req2) { + return -EINVAL; + } + + RGA_gen_two_pro(req, req2); + + reg0 = rga_reg_init(session, req2); + if(reg0 == NULL) { + return -EFAULT; + } + + reg1 = rga_reg_init(session, req); + if(reg1 == NULL) { + return -EFAULT; + } + + rga_try_set_reg(); + rga_try_set_reg(); + + if(req2 != NULL) + { + kfree(req2); + } + + } + else { + /* check value if legal */ + ret = rga_check_param(req); + if(ret == -EINVAL) { + return -EINVAL; + } + + reg0 = rga_reg_init(session, req); + if(reg0 == NULL) { + return -EFAULT; + } + + rga_try_set_reg(); + } + + //printk("rga_blit_async done******************\n"); + +#if 0 +error_status: +error_scale: + ret = -EINVAL; + rga_soft_reset(); + rga_power_off(); +#endif + return ret; + +} + +static int rga_blit_sync(rga_session *session, struct rga_req *req) +{ + int ret = 0; + struct rga_reg *reg0, *reg1; + struct rga_req *req2; + + uint32_t saw, sah, daw, dah; + + saw = req->src.act_w; + sah = req->src.act_h; + daw = req->dst.act_w; + dah = req->dst.act_h; + + if((req->render_mode == bitblt_mode) && (((saw>>1) >= daw) || ((sah>>1) >= dah))) + { + /* generate 2 cmd for pre scale */ + + req2 = kmalloc(sizeof(struct rga_req), GFP_KERNEL); + if(NULL == req2) { + return -EINVAL; + } + + RGA_gen_two_pro(req, req2); + + reg0 = rga_reg_init(session, req2); + if(reg0 == NULL) { + return -EFAULT; + } + + reg1 = rga_reg_init(session, req); + if(reg1 == NULL) { + return -EFAULT; + } + atomic_set(®1->int_enable, 1); + + rga_try_set_reg(); + rga_try_set_reg(); + + } + else { + /* check value if legal */ + ret = rga_check_param(req); + if(ret == -EINVAL) { + return -EFAULT; + } + + reg0 = rga_reg_init(session, req); + if(reg0 == NULL) { + return -EFAULT; + } + atomic_set(®0->int_enable, 1); + + rga_try_set_reg(); + } + + ret = wait_event_interruptible_timeout(session->wait, session->done, RGA_TIMEOUT_DELAY); + + if (unlikely(ret < 0)) + { + pr_err("pid %d wait task ret %d\n", session->pid, ret); + } + else if (0 == ret) + { + pr_err("pid %d wait %d task done timeout\n", session->pid, atomic_read(&session->task_running)); + ret = -ETIMEDOUT; + } + + return ret; + + //printk("rga_blit_sync done******************\n"); +} + +static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg) +{ + struct rga_req *req; + int ret = 0; + rga_session *session = (rga_session *)file->private_data; + if (NULL == session) + { + printk("%s [%d] rga thread session is null\n",__FUNCTION__,__LINE__); + return -EINVAL; + } + + req = (struct rga_req *)kmalloc(sizeof(struct rga_req), GFP_KERNEL); + if(req == NULL) + { + printk("%s [%d] get rga_req mem failed\n",__FUNCTION__,__LINE__); + ret = -EINVAL; + } + + if (unlikely(copy_from_user(&req, (struct rga_req*)arg, sizeof(struct rga_req)))) + { + ERR("copy_from_user failed\n"); + ret = -EFAULT; + } + + switch (cmd) + { + case RGA_BLIT_SYNC: + ret = rga_blit_sync(session, req); + break; + case RGA_BLIT_ASYNC: + ret = rga_blit_async(session, req); + break; + case RGA_FLUSH: + ret = rga_flush(session, arg); + break; + default: + ERR("unknown ioctl cmd!\n"); + ret = -EINVAL; + break; + } + + if(req != NULL) + { + kfree(req); + } + + return ret; +} + +static int rga_open(struct inode *inode, struct file *file) +{ + rga_session *session = (rga_session *)kmalloc(sizeof(rga_session), GFP_KERNEL); + if (NULL == session) { + pr_err("unable to allocate memory for rga_session."); + return -ENOMEM; + } + + 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); + file->private_data = (void *)session; + + DBG("*** rga dev opened *** \n"); + return nonseekable_open(inode, file); + +} + +static int rga_release(struct inode *inode, struct file *file) +{ + int task_running; + unsigned long flag; + rga_session *session = (rga_session *)file->private_data; + if (NULL == session) + return -EINVAL; + + task_running = atomic_read(&session->task_running); + if (task_running) { + pr_err("rga_service session %d still has %d task running when closing\n", session->pid, task_running); + msleep(50); + } + wake_up_interruptible_sync(&session->wait); + spin_lock_irqsave(&rga_service.lock, flag); + list_del(&session->list_session); + rga_service_session_clear(session); + kfree(session); + spin_unlock_irqrestore(&rga_service.lock, flag); + + pr_debug("dev closed\n"); + return 0; +} + +static irqreturn_t rga_irq(int irq, void *dev_id) +{ + struct rga_reg *reg; + + DBG("rga_irq %d \n", irq); + + /*clear INT */ + rga_write(rga_read(RGA_INT) | (0x1<<6), RGA_INT); + if(((rga_read(RGA_STATUS) & 0x1) != 0))// idle + { + printk("RGA is not idle!\n"); + rga_soft_reset(); + } + + spin_lock(&rga_service.lock); + do + { + reg = list_entry(rga_service.running.next, struct rga_reg, status_link); + if(reg->MMU_base != NULL) + { + kfree(reg->MMU_base); + } + + atomic_sub(1, ®->session->task_running); + atomic_sub(1, &rga_service.total_running); + + if(list_empty(®->session->waiting)) + { + reg->session->done = 1; + wake_up_interruptible_sync(®->session->wait); + } + rga_reg_deinit(reg); + + } + while(!list_empty(&rga_service.running)); + + + /* add cmd to cmd buf */ + while(((!list_empty(&rga_service.waiting)) && (atomic_read(&rga_service.int_disable) == 0))) + { + rga_try_set_reg(); + } + + spin_lock(&rga_service.lock); + + return IRQ_HANDLED; +} + +static int rga_suspend(struct platform_device *pdev, pm_message_t state) +{ + uint32_t enable; + + enable = drvdata->enable; + rga_power_off(NULL); + drvdata->enable = enable; + + return 0; +} + +static int rga_resume(struct platform_device *pdev) +{ + rga_power_on(); + return 0; +} + +static void rga_shutdown(struct platform_device *pdev) +{ + pr_cont("shutdown..."); + rga_power_off(NULL); + pr_cont("done\n"); +} + + + +struct file_operations rga_fops = { + .owner = THIS_MODULE, + .open = rga_open, + .release = rga_release, + .unlocked_ioctl = rga_ioctl, +}; + +static struct miscdevice rga_dev ={ + .minor = RGA_MAJOR, + .name = "rga", + .fops = &rga_fops, +}; + +static int __devinit rga_drv_probe(struct platform_device *pdev) +{ + struct rga_drvdata *data; + int ret = 0; + + data = kmalloc(sizeof(struct rga_drvdata), GFP_KERNEL); + + INIT_LIST_HEAD(&rga_service.waiting); + INIT_LIST_HEAD(&rga_service.running); + INIT_LIST_HEAD(&rga_service.done); + INIT_LIST_HEAD(&rga_service.session); + spin_lock_init(&rga_service.lock); + atomic_set(&rga_service.total_running, 0); + rga_service.enabled = false; + + if(NULL == data) + { + ERR("failed to allocate driver data.\n"); + return -ENOMEM; + } + + /* get the clock */ + data->pd_display = clk_get(&pdev->dev, "pd_display"); + if (IS_ERR(data->pd_display)) + { + ERR("failed to find rga pd_display source\n"); + ret = -ENOENT; + goto err_clock; + } + + data->aclk_lcdc = clk_get(&pdev->dev, "aclk_lcdc"); + if (IS_ERR(data->aclk_lcdc)) + { + ERR("failed to find rga aclk_lcdc source\n"); + ret = -ENOENT; + goto err_clock; + } + + data->hclk_lcdc = clk_get(&pdev->dev, "hclk_lcdc"); + if (IS_ERR(data->hclk_lcdc)) + { + ERR("failed to find rga hclk_lcdc source\n"); + ret = -ENOENT; + goto err_clock; + } + + data->aclk_ddr_lcdc = clk_get(&pdev->dev, "aclk_ddr_lcdc"); + if (IS_ERR(data->aclk_ddr_lcdc)) + { + ERR("failed to find rga aclk_ddr_lcdc source\n"); + ret = -ENOENT; + goto err_clock; + } + + data->hclk_cpu_display = clk_get(&pdev->dev, "hclk_cpu_display"); + if (IS_ERR(data->hclk_cpu_display)) + { + ERR("failed to find rga hclk_cpu_display source\n"); + ret = -ENOENT; + goto err_clock; + } + + data->aclk_disp_matrix = clk_get(&pdev->dev, "aclk_disp_matrix"); + if (IS_ERR(data->aclk_disp_matrix)) + { + ERR("failed to find rga aclk_disp_matrix source\n"); + ret = -ENOENT; + goto err_clock; + } + + data->hclk_disp_matrix = clk_get(&pdev->dev, "hclk_disp_matrix"); + if (IS_ERR(data->hclk_disp_matrix)) + { + ERR("failed to find rga hclk_disp_matrix source\n"); + ret = -ENOENT; + goto err_clock; + } + + data->axi_clk = clk_get(&pdev->dev, "aclk_rga"); + if (IS_ERR(data->axi_clk)) + { + ERR("failed to find rga axi clock source\n"); + ret = -ENOENT; + goto err_clock; + } + + data->ahb_clk = clk_get(&pdev->dev, "hclk_rga"); + if (IS_ERR(data->ahb_clk)) + { + ERR("failed to find rga ahb clock source\n"); + ret = -ENOENT; + goto err_clock; + } + + /* map the memory */ + if (!request_mem_region(RK30_RGA_PHYS, RK30_RGA_SIZE, "rga_io")) + { + pr_info("failed to reserve rga HW regs\n"); + return -EBUSY; + } + data->rga_base = (void*)ioremap_nocache(RK30_RGA_PHYS, RK30_RGA_SIZE); + if (data->rga_base == NULL) + { + ERR("rga ioremap failed\n"); + ret = -ENOENT; + goto err_ioremap; + } + + /* get the IRQ */ + data->irq0 = pdev->resource[1].start; + printk("rga irq %d\n", data->irq0); + if (data->irq0 <= 0) + { + ERR("failed to get rga irq resource (%d).\n", data->irq0); + ret = data->irq0; + goto err_irq; + } + + /* request the IRQ */ + ret = request_irq(data->irq0, rga_irq, 0/*IRQF_DISABLED*/, "rga", pdev); + if (ret) + { + ERR("rga request_irq failed (%d).\n", ret); + goto err_irq; + } + + mutex_init(&data->mutex); + data->enable = false; + INIT_DELAYED_WORK(&data->power_off_work, rga_power_off); + data->rga_irq_callback = NULL; + + platform_set_drvdata(pdev, data); + drvdata = data; + + ret = misc_register(&rga_dev); + if(ret) + { + ERR("cannot register miscdev (%d)\n", ret); + goto err_misc_register; + } + DBG("RGA Driver loaded succesfully\n"); + + return 0; + +err_misc_register: + free_irq(data->irq0, pdev); +err_irq: + iounmap(data->rga_base); +err_ioremap: +err_clock: + 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__); + + misc_deregister(&(data->miscdev)); + free_irq(data->irq0, &data->miscdev); + iounmap((void __iomem *)(data->rga_base)); + + if(data->axi_clk) { + clk_put(data->axi_clk); + } + + if(data->ahb_clk) { + clk_put(data->ahb_clk); + } + if(data->aclk_disp_matrix) { + clk_put(data->aclk_disp_matrix); + } + + if(data->hclk_disp_matrix) { + clk_put(data->hclk_disp_matrix); + } + + if(data->aclk_ddr_lcdc) { + clk_put(data->aclk_ddr_lcdc); + } + + if(data->hclk_lcdc) { + clk_put(data->hclk_lcdc); + } + + if(data->aclk_lcdc) { + clk_put(data->aclk_lcdc); + } + + if(data->hclk_cpu_display) { + clk_put(data->hclk_cpu_display); + } + + if(data->pd_display){ + clk_put(data->pd_display); + } + + kfree(data); + return 0; +} + +static struct platform_driver rga_driver = { + .probe = rga_drv_probe, + .remove = __devexit_p(rga_drv_remove), + .suspend = rga_suspend, + .resume = rga_resume, + .shutdown = rga_shutdown, + .driver = { + .owner = THIS_MODULE, + .name = "rga", + }, +}; + +static int __init rga_init(void) +{ + int ret; + uint8_t *buf; + + /* malloc pre scale mid buf */ + buf = kmalloc(PRE_SCALE_BUF_SIZE, GFP_KERNEL); + if(buf == NULL) { + ERR("RGA get Pre Scale buff failed. \n"); + return -1; + } + rga_service.pre_scale_buf = (uint32_t *)buf; + + if ((ret = platform_driver_register(&rga_driver)) != 0) + { + ERR("Platform device register failed (%d).\n", ret); + return ret; + } + + INFO("Module initialized.\n"); + + return 0; +} + +static void __exit rga_exit(void) +{ + if(rga_service.pre_scale_buf != NULL) { + kfree((uint8_t *)rga_service.pre_scale_buf); + } + platform_driver_unregister(&rga_driver); +} + + + +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 new file mode 100644 index 000000000000..4fca3633d818 --- /dev/null +++ b/drivers/video/rockchip/rga/rga_mmu_info.c @@ -0,0 +1,950 @@ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "rga_mmu_info.h" + + +extern rga_service_info rga_service; + +#define KERNEL_SPACE_VALID 0xc0000000 + +static int rga_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr) +{ + uint32_t start, end; + uint32_t pageCount; + + end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT; + start = Mem >> PAGE_SHIFT; + pageCount = end - start; + *StartAddr = start; + 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 ) +{ + uint32_t size_yrgb = 0; + uint32_t size_uv = 0; + uint32_t size_v = 0; + uint32_t stride = 0; + uint32_t start, end; + uint32_t pageCount; + + switch(format) + { + case RK_FORMAT_RGBA_8888 : + stride = (w * 4 + 3) & (~3); + size_yrgb = stride*h; + end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_RGBX_8888 : + stride = (w * 4 + 3) & (~3); + size_yrgb = stride*h; + end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_RGB_888 : + stride = (w * 3 + 3) & (~3); + size_yrgb = stride*h; + end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_BGRA_8888 : + size_yrgb = w*h*4; + end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = end - start; + *StartAddr = start; + break; + case RK_FORMAT_RGB_565 : + stride = (w*2 + 3) & (~3); + size_yrgb = stride * h; + end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_RGBA_5551 : + stride = (w*2 + 3) & (~3); + size_yrgb = stride * h; + end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_RGBA_4444 : + stride = (w*2 + 3) & (~3); + size_yrgb = stride * h; + end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_BGR_888 : + stride = (w*3 + 3) & (~3); + size_yrgb = stride * h; + end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = end - start; + break; + + /* YUV FORMAT */ + case RK_FORMAT_YCbCr_422_SP : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = stride * h; + start = MIN(yrgb_addr, uv_addr); + start >>= PAGE_SHIFT; + end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_YCbCr_422_P : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = ((stride >> 1) * h); + size_v = ((stride >> 1) * h); + start = MIN(MIN(yrgb_addr, uv_addr), v_addr); + start = start >> PAGE_SHIFT; + end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_YCbCr_420_SP : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = (stride * (h >> 1)); + start = MIN(yrgb_addr, uv_addr); + start >>= PAGE_SHIFT; + end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_YCbCr_420_P : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = ((stride >> 1) * (h >> 1)); + size_v = ((stride >> 1) * (h >> 1)); + start = MIN(MIN(yrgb_addr, uv_addr), v_addr); + start >>= PAGE_SHIFT; + end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + + case RK_FORMAT_YCrCb_422_SP : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = stride * h; + start = MIN(yrgb_addr, uv_addr); + start >>= PAGE_SHIFT; + end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_YCrCb_422_P : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = ((stride >> 1) * h); + size_v = ((stride >> 1) * h); + start = MIN(MIN(yrgb_addr, uv_addr), v_addr); + start >>= PAGE_SHIFT; + end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + + case RK_FORMAT_YCrCb_420_SP : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = (stride * (h >> 1)); + start = MIN(yrgb_addr, uv_addr); + start >>= PAGE_SHIFT; + end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_YCrCb_420_P : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = ((stride >> 1) * (h >> 1)); + size_v = ((stride >> 1) * (h >> 1)); + start = MIN(MIN(yrgb_addr, uv_addr), v_addr); + start >>= PAGE_SHIFT; + end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + #if 0 + case RK_FORMAT_BPP1 : + break; + case RK_FORMAT_BPP2 : + break; + case RK_FORMAT_BPP4 : + break; + case RK_FORMAT_BPP8 : + break; + #endif + default : + pageCount = 0; + start = 0; + break; + } + + *StartAddr = start; + return pageCount; +} + +static int rga_MapUserMemory(struct page **pages, + uint32_t *pageTable, + uint32_t Memory, + uint32_t pageCount) +{ + int32_t result; + uint32_t i; + + down_read(¤t->mm->mmap_sem); + result = get_user_pages(current, + current->mm, + Memory << PAGE_SHIFT, + pageCount, + 1, + 0, + pages, + NULL + ); + up_read(¤t->mm->mmap_sem); + + if(result <= 0 || result < pageCount) + { + return -EINVAL; + } + + for (i = 0; i < pageCount; i++) + { + /* Flush the data cache. */ +#ifdef ANDROID + dma_sync_single_for_device( + gcvNULL, + page_to_phys(pages[i]), + PAGE_SIZE, + DMA_TO_DEVICE); +#else + flush_dcache_page(pages[i]); +#endif + } + + /* Fill the page table. */ + for(i=0; isrc.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; + } + + /* cal cmd buf mmu info */ + CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + AllSize = SrcMemSize + DstMemSize + CMDMemSize; + + pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc pages mem failed"); + return -EINVAL; + } + + MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc MMU_Base point failed"); + return -EINVAL; + } + + for(i=0; isrc.yrgb_addr < KERNEL_SPACE_VALID) + { + ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); + if (ret < 0) { + pr_err("rga map src memory failed"); + return -EINVAL; + } + } + else + { + MMU_p = MMU_Base + CMDMemSize; + + for(i=0; idst.yrgb_addr < KERNEL_SPACE_VALID) + { + ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize); + if (ret < 0) { + pr_err("rga map dst memory failed"); + return -EINVAL; + } + } + else + { + MMU_p = MMU_Base + CMDMemSize + SrcMemSize; + + for(i=0; immu_info.base_addr = virt_to_phys(MMU_Base); + + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + + req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT); + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + if (pages != NULL) { + /* Free the page table */ + kfree(pages); + } + + return 0; +} + +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; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base; + int ret; + uint32_t stride; + + uint8_t shift; + uint16_t sw, byte_num; + + shift = 3 - (req->palette_mode & 3); + sw = req->src.vir_w; + byte_num = sw >> shift; + stride = (byte_num + 3) & (~3); + + SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart); + if(SrcMemSize == 0) { + return -EINVAL; + } + + 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; + } + + CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + AllSize = SrcMemSize + DstMemSize + CMDMemSize; + + pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc pages mem failed"); + return -EINVAL; + } + + MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc MMU_Base point failed"); + return -EINVAL; + } + + for(i=0; immu_info.base_addr = virt_to_phys(MMU_Base); + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT); + + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + if (pages != NULL) { + /* Free the page table */ + kfree(pages); + } + + return 0; +} + +static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req) +{ + int DstMemSize, CMDMemSize; + uint32_t DstStart, CMDStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base; + int ret; + + 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; + } + + CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + AllSize = DstMemSize + CMDMemSize; + + pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc pages mem failed"); + return -EINVAL; + } + + MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc MMU_Base point failed"); + return -EINVAL; + } + + for(i=0; immu_info.base_addr = virt_to_phys(MMU_Base); + req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize) << PAGE_SHIFT); + + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + if (pages != NULL) { + /* Free the page table */ + kfree(pages); + } + + return 0; +} + + +static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req) +{ + int DstMemSize, CMDMemSize; + uint32_t DstStart, CMDStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base; + int ret; + + /* 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; + } + + CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + AllSize = DstMemSize + CMDMemSize; + + pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc pages mem failed"); + return -EINVAL; + } + + MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc MMU_Base point failed"); + return -EINVAL; + } + + for(i=0; immu_info.base_addr = virt_to_phys(MMU_Base); + req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize) << PAGE_SHIFT); + + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + if (pages != NULL) { + /* Free the page table */ + kfree(pages); + } + + return 0; +} + +static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req) +{ + int SrcMemSize, DstMemSize, CMDMemSize; + uint32_t SrcStart, DstStart, CMDStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base; + int ret; + + /* 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; + } + + /* cal cmd buf mmu info */ + CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + AllSize = SrcMemSize + DstMemSize + CMDMemSize; + + pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc pages mem failed"); + return -EINVAL; + } + + MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc MMU_Base point failed"); + return -EINVAL; + } + + for(i=0; immu_info.base_addr = virt_to_phys(MMU_Base); + + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + + req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT); + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + if (pages != NULL) { + /* Free the page table */ + kfree(pages); + } + + return 0; +} + + + +static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) +{ + int SrcMemSize, DstMemSize, CMDMemSize; + uint32_t SrcStart, DstStart, CMDStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base, *MMU_p; + int ret; + + /* 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; + } + + /* cal cmd buf mmu info */ + CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + AllSize = SrcMemSize + DstMemSize + CMDMemSize; + + pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc pages mem failed"); + return -EINVAL; + } + + /* + * Allocate MMU Index mem + * This mem release in run_to_done fun + */ + MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc MMU_Base point failed"); + return -EINVAL; + } + + for(i=0; idst.yrgb_addr >= 0xc0000000) + { + /* kernel space */ + MMU_p = MMU_Base + CMDMemSize + SrcMemSize; + for(i=0; immu_info.base_addr = virt_to_phys(MMU_Base); + + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + + req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT); + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + if (pages != NULL) { + /* Free the page table */ + kfree(pages); + } + + return 0; +} + + +static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req) +{ + int SrcMemSize, DstMemSize, CMDMemSize; + uint32_t SrcStart, CMDStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base; + int ret; + + /* 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) { + return -EINVAL; + } + + /* cal cmd buf mmu info */ + CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + AllSize = SrcMemSize + DstMemSize + CMDMemSize; + + pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc pages mem failed"); + return -EINVAL; + } + + MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc MMU_Base point failed"); + return -EINVAL; + } + + for(i=0; immu_info.base_addr = virt_to_phys(MMU_Base); + + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + if (pages != NULL) { + /* Free the page table */ + kfree(pages); + } + + return 0; +} + +static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req) +{ + int SrcMemSize, DstMemSize, CMDMemSize; + uint32_t SrcStart, CMDStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base; + int ret; + + /* cal src buf mmu info */ + SrcMemSize = rga_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h * 4, &SrcStart); + if(SrcMemSize == 0) { + return -EINVAL; + } + + /* cal cmd buf mmu info */ + CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + AllSize = SrcMemSize + DstMemSize + CMDMemSize; + + pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc pages mem failed"); + return -EINVAL; + } + + MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc MMU_Base point failed"); + return -EINVAL; + } + + for(i=0; immu_info.base_addr = virt_to_phys(MMU_Base); + + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + if (pages != NULL) { + /* Free the page table */ + kfree(pages); + } + + return 0; +} + +int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req) +{ + int ret; + + switch (req->render_mode) { + case bitblt_mode : + ret = rga_mmu_info_BitBlt_mode(reg, req); + break; + case color_palette_mode : + ret = rga_mmu_info_color_palette_mode(reg, req); + break; + case color_fill_mode : + ret = rga_mmu_info_color_fill_mode(reg, req); + break; + case line_point_drawing_mode : + ret = rga_mmu_info_line_point_drawing_mode(reg, req); + break; + case blur_sharp_filter_mode : + ret = rga_mmu_info_blur_sharp_filter_mode(reg, req); + break; + case pre_scaling_mode : + ret = rga_mmu_info_pre_scale_mode(reg, req); + break; + case update_palette_table_mode : + ret = rga_mmu_info_update_palette_table_mode(reg, req); + break; + case update_patten_buff_mode : + ret = rga_mmu_info_update_patten_buff_mode(reg, req); + break; + default : + ret = -1; + break; + } + + return ret; +} + diff --git a/drivers/video/rockchip/rga/rga_mmu_info.h b/drivers/video/rockchip/rga/rga_mmu_info.h new file mode 100644 index 000000000000..d8e18e2fb15e --- /dev/null +++ b/drivers/video/rockchip/rga/rga_mmu_info.h @@ -0,0 +1,20 @@ +#ifndef __RGA_MMU_INFO_H__ +#define __RGA_MMU_INFO_H__ + +#include "rga.h" + +#ifndef MIN +#define MIN(X, Y) ((X)<(Y)?(X):(Y)) +#endif + +#ifndef MAX +#define MAX(X, Y) ((X)>(Y)?(X):(Y)) +#endif + + +int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req); + + +#endif + + diff --git a/drivers/video/rockchip/rga/rga_reg_info.c b/drivers/video/rockchip/rga/rga_reg_info.c new file mode 100644 index 000000000000..fe6e35531d1d --- /dev/null +++ b/drivers/video/rockchip/rga/rga_reg_info.c @@ -0,0 +1,1503 @@ + +//#include +#include +#include "rga_reg_info.h" +#include "rga_rop.h" +#include "rga.h" + + +/************************************************************* +Func: + RGA_pixel_width_init +Description: + select pixel_width form data format +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ +unsigned char +RGA_pixel_width_init(unsigned int format) +{ + unsigned char pixel_width; + + pixel_width = 0; + + switch(format) + { + /* RGB FORMAT */ + case RK_FORMAT_RGBA_8888 : pixel_width = 4; break; + case RK_FORMAT_RGBX_8888 : pixel_width = 4; break; + case RK_FORMAT_RGB_888 : pixel_width = 3; break; + case RK_FORMAT_BGRA_8888 : pixel_width = 4; break; + case RK_FORMAT_RGB_565 : pixel_width = 2; break; + case RK_FORMAT_RGBA_5551 : pixel_width = 2; break; + case RK_FORMAT_RGBA_4444 : pixel_width = 2; break; + case RK_FORMAT_BGR_888 : pixel_width = 3; break; + + /* YUV FORMAT */ + case RK_FORMAT_YCbCr_422_SP : pixel_width = 1; break; + case RK_FORMAT_YCbCr_422_P : pixel_width = 1; break; + case RK_FORMAT_YCbCr_420_SP : pixel_width = 1; break; + case RK_FORMAT_YCbCr_420_P : pixel_width = 1; break; + case RK_FORMAT_YCrCb_422_SP : pixel_width = 1; break; + case RK_FORMAT_YCrCb_422_P : pixel_width = 1; break; + case RK_FORMAT_YCrCb_420_SP : pixel_width = 1; break; + case RK_FORMAT_YCrCb_420_P : pixel_width = 1; break; + //case default : pixel_width = 0; break; + } + + return pixel_width; +} + +/************************************************************* +Func: + dst_ctrl_cal +Description: + calculate dst act window position / width / height + and set the tile struct +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ +void +dst_ctrl_cal(const struct rga_req *msg, TILE_INFO *tile) +{ + u32 width = msg->dst.act_w; + u32 height = msg->dst.act_h; + s32 xoff = msg->dst.x_offset; + s32 yoff = msg->dst.y_offset; + + s32 x0, y0, x1, y1, x2, y2; + s32 x00,y00,x10,y10,x20,y20; + s32 xx, xy, yx, yy; + s32 pos[8]; + + s32 xmax, xmin, ymax, ymin; + + s32 sina = msg->sina; /* 16.16 */ + s32 cosa = msg->cosa; /* 16.16 */ + + xmax = xmin = ymax = ymin = 0; + + if((msg->rotate_mode == 0)||(msg->rotate_mode == 2)||(msg->rotate_mode == 3)) + { + pos[0] = xoff; + pos[1] = yoff; + + pos[2] = xoff; + pos[3] = yoff + height - 1; + + pos[4] = xoff + width - 1; + pos[5] = yoff + height - 1; + + pos[6] = xoff + width - 1; + pos[7] = yoff; + + xmax = MIN(MAX(MAX(MAX(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmax); + xmin = MAX(MIN(MIN(MIN(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmin); + + ymax = MIN(MAX(MAX(MAX(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymax); + ymin = MAX(MIN(MIN(MIN(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymin); + } + else if(msg->rotate_mode == 1) + { + if((sina == 0) || (cosa == 0)) + { + if((sina == 0) && (cosa == -65536)) + { + /* 180 */ + pos[0] = xoff - width + 1; + pos[1] = yoff - height + 1; + + pos[2] = xoff - width + 1; + pos[3] = yoff; + + pos[4] = xoff; + pos[5] = yoff; + + pos[6] = xoff; + pos[7] = yoff - height + 1; + } + else if((cosa == 0)&&(sina == 65536)) + { + /* 90 */ + pos[0] = xoff - height + 1; + pos[1] = yoff; + + pos[2] = xoff - height + 1; + pos[3] = yoff + width - 1; + + pos[4] = xoff; + pos[5] = yoff + width - 1; + + pos[6] = xoff; + pos[7] = yoff; + } + else if((cosa == 0)&&(sina == -65536)) + { + /* 270 */ + pos[0] = xoff; + pos[1] = yoff - width + 1; + + pos[2] = xoff; + pos[3] = yoff; + + pos[4] = xoff + height - 1; + pos[5] = yoff; + + pos[6] = xoff + height - 1; + pos[7] = yoff - width + 1; + } + else + { + /* 0 */ + pos[0] = xoff; + pos[1] = yoff; + + pos[2] = xoff; + pos[3] = yoff + height - 1; + + pos[4] = xoff + width - 1; + pos[5] = yoff + height - 1; + + pos[6] = xoff + width - 1; + pos[7] = yoff; + } + + xmax = MIN(MAX(MAX(MAX(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmax); + xmin = MAX(MIN(MIN(MIN(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmin); + + ymax = MIN(MAX(MAX(MAX(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymax); + ymin = MAX(MIN(MIN(MIN(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymin); + } + else + { + xx = msg->cosa; + xy = msg->sina; + yx = xy; + yy = xx; + + x0 = width + xoff; + y0 = yoff; + + x1 = xoff; + y1 = height + yoff; + + x2 = width + xoff; + y2 = height + yoff; + + pos[0] = xoff; + pos[1] = yoff; + + pos[2] = x00 = (((x0 - xoff)*xx - (y0 - yoff)*xy)>>16) + xoff; + pos[3] = y00 = (((x0 - xoff)*yx + (y0 - yoff)*yy)>>16) + yoff; + + pos[4] = x10 = (((x1 - xoff)*xx - (y1 - yoff)*xy)>>16) + xoff; + pos[5] = y10 = (((x1 - xoff)*yx + (y1 - yoff)*yy)>>16) + yoff; + + pos[6] = x20 = (((x2 - xoff)*xx - (y2 - yoff)*xy)>>16) + xoff; + pos[7] = y20 = (((x2 - xoff)*yx + (y2 - yoff)*yy)>>16) + yoff; + + xmax = MAX(MAX(MAX(x00, xoff), x10), x20) + 2; + xmin = MIN(MIN(MIN(x00, xoff), x10), x20) - 1; + + ymax = MAX(MAX(MAX(y00, yoff), y10), y20) + 2; + ymin = MIN(MIN(MIN(y00, yoff), y10), y20) - 1; + + xmax = MIN(xmax, msg->clip.xmax); + xmin = MAX(xmin, msg->clip.xmin); + + ymax = MIN(ymax, msg->clip.ymax); + ymin = MAX(ymin, msg->clip.ymin); + } + } + + if ((xmax < xmin) || (ymax < ymin)) { + xmin = xmax; + ymin = ymax; + } + + if ((xmin >= msg->dst.vir_w)||(xmax < 0)||(ymin >= msg->dst.vir_h)||(ymax < 0)) { + xmin = xmax = ymin = ymax = 0; + } + + tile->dst_ctrl.w = (xmax - xmin); + tile->dst_ctrl.h = (ymax - ymin); + tile->dst_ctrl.x_off = xmin; + tile->dst_ctrl.y_off = ymin; + + tile->tile_x_num = (xmax - xmin + 1 + 7)>>3; + tile->tile_y_num = (ymax - ymin + 1 + 7)>>3; + + tile->dst_x_tmp = xmin - msg->dst.x_offset; + tile->dst_y_tmp = ymin - msg->dst.y_offset; +} + +/************************************************************* +Func: + src_tile_info_cal +Description: + calculate src remap window position / width / height + and set the tile struct +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +void +src_tile_info_cal(const struct rga_req *msg, TILE_INFO *tile) +{ + s32 x0, x1, x2, x3, y0, y1, y2, y3; + + int64_t xx, xy, yx, yy; + + int64_t pos[8]; + int64_t epos[8]; + + int64_t x_dx, x_dy, y_dx, y_dy; + int64_t x_temp_start, y_temp_start; + int64_t xmax, xmin, ymax, ymin; + + int64_t t_xoff, t_yoff; + + xx = tile->matrix[0]; /* 32.32 */ + xy = tile->matrix[1]; /* 32.32 */ + yx = tile->matrix[2]; /* 32.32 */ + yy = tile->matrix[3]; /* 32.32 */ + + if(msg->rotate_mode == 1) + { + x0 = tile->dst_x_tmp; + y0 = tile->dst_y_tmp; + + x1 = x0; + y1 = y0 + 8; + + x2 = x0 + 8; + y2 = y0 + 8; + + x3 = x0 + 8; + y3 = y0; + + pos[0] = (x0*xx + y0*yx); + pos[1] = (x0*xy + y0*yy); + + pos[2] = (x1*xx + y1*yx); + pos[3] = (x1*xy + y1*yy); + + pos[4] = (x2*xx + y2*yx); + pos[5] = (x2*xy + y2*yy); + + pos[6] = (x3*xx + y3*yx); + pos[7] = (x3*xy + y3*yy); + + y1 = y0 + 7; + x2 = x0 + 7; + y2 = y0 + 7; + x3 = x0 + 7; + + epos[0] = pos[0]; + epos[1] = pos[1]; + + epos[2] = (x1*xx + y1*yx); + epos[3] = (x1*xy + y1*yy); + + epos[4] = (x2*xx + y2*yx); + epos[5] = (x2*xy + y2*yy); + + epos[6] = (x3*xx + y3*yx); + epos[7] = (x3*xy + y3*yy); + + x_dx = pos[6] - pos[0]; + x_dy = pos[7] - pos[1]; + + y_dx = pos[2] - pos[0]; + y_dy = pos[3] - pos[1]; + + tile->x_dx = (s32)(x_dx >> 22 ); + tile->x_dy = (s32)(x_dy >> 22 ); + tile->y_dx = (s32)(y_dx >> 22 ); + tile->y_dy = (s32)(y_dy >> 22 ); + + x_temp_start = x0*xx + y0*yx; + y_temp_start = x0*xy + y0*yy; + + xmax = (MAX(MAX(MAX(epos[0], epos[2]), epos[4]), epos[6])); + xmin = (MIN(MIN(MIN(epos[0], epos[2]), epos[4]), epos[6])); + + ymax = (MAX(MAX(MAX(epos[1], epos[3]), epos[5]), epos[7])); + ymin = (MIN(MIN(MIN(epos[1], epos[3]), epos[5]), epos[7])); + + t_xoff = (x_temp_start - xmin)>>18; + t_yoff = (y_temp_start - ymin)>>18; + + tile->tile_xoff = (s32)t_xoff; + tile->tile_yoff = (s32)t_yoff; + + tile->tile_w = (u16)((xmax - xmin)>>21); //.11 + tile->tile_h = (u16)((ymax - ymin)>>21); //.11 + + tile->tile_start_x_coor = (s16)(xmin>>29); //.3 + tile->tile_start_y_coor = (s16)(ymin>>29); //.3 + } + else if (msg->rotate_mode == 2) + { + tile->x_dx = (s32)((8*xx)>>22); + tile->x_dy = 0; + tile->y_dx = 0; + tile->y_dy = (s32)((8*yy)>>22); + + tile->tile_w = ABS((s32)((7*xx)>>21)); + tile->tile_h = ABS((s32)((7*yy)>>21)); + + tile->tile_xoff = ABS((s32)((7*xx)>>18)); + tile->tile_yoff = 0; + + tile->tile_start_x_coor = (((msg->src.act_w - 1)<<11) - (tile->tile_w))>>8; + tile->tile_start_y_coor = 0; + } + else if (msg->rotate_mode == 3) + { + tile->x_dx = (s32)((8*xx)>>22); + tile->x_dy = 0; + tile->y_dx = 0; + tile->y_dy = (s32)((8*yy)>>22); + + tile->tile_w = ABS((s32)((7*xx)>>21)); + tile->tile_h = ABS((s32)((7*yy)>>21)); + + tile->tile_xoff = 0; + tile->tile_yoff = ABS((s32)((7*yy)>>18)); + + tile->tile_start_x_coor = 0; + tile->tile_start_y_coor = (((msg->src.act_h - 1)<<11) - (tile->tile_h))>>8; + } + + if ((msg->scale_mode == 2)||(msg->alpha_rop_flag >> 7)) + { + tile->tile_start_x_coor -= (1<<3); + tile->tile_start_y_coor -= (1<<3); + tile->tile_w += (2 << 11); + tile->tile_h += (2 << 11); + tile->tile_xoff += (1<<14); + tile->tile_yoff += (1<<14); + } +} + + +/************************************************************* +Func: + RGA_set_mode_ctrl +Description: + fill mode ctrl reg info +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +void +RGA_set_mode_ctrl(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_MODE_CTL; + u32 reg = 0; + + u8 src_rgb_pack = 0; + u8 src_format = 0; + u8 src_rb_swp = 0; + u8 src_a_swp = 0; + u8 src_cbcr_swp = 0; + + u8 dst_rgb_pack = 0; + u8 dst_format = 0; + u8 dst_rb_swp = 0; + u8 dst_a_swp = 0; + + bRGA_MODE_CTL = (u32 *)(base + RGA_MODE_CTRL_OFFSET); + + reg = ((reg & (~m_RGA_MODE_CTRL_2D_RENDER_MODE)) | (s_RGA_MODE_CTRL_2D_RENDER_MODE(msg->render_mode))); + + /* src info set */ + + if (msg->render_mode == color_palette_mode || msg->render_mode == update_palette_table_mode) + { + src_format = 0x10 | (msg->palette_mode & 3); + } + else + { + switch (msg->src.format) + { + case RK_FORMAT_RGBA_8888 : src_format = 0x0; break; + case RK_FORMAT_RGBA_4444 : src_format = 0x3; break; + case RK_FORMAT_RGBA_5551 : src_format = 0x2; break; + case RK_FORMAT_BGRA_8888 : src_format = 0x0; src_rb_swp = 0x1; break; + case RK_FORMAT_RGBX_8888 : src_format = 0x0; break; + case RK_FORMAT_RGB_565 : src_format = 0x1; break; + case RK_FORMAT_RGB_888 : src_format = 0x0; src_rgb_pack = 1; break; + case RK_FORMAT_BGR_888 : src_format = 0x0; src_rgb_pack = 1; src_rb_swp = 1; break; + + case RK_FORMAT_YCbCr_422_SP : src_format = 0x4; break; + case RK_FORMAT_YCbCr_422_P : src_format = 0x5; break; + case RK_FORMAT_YCbCr_420_SP : src_format = 0x6; break; + case RK_FORMAT_YCbCr_420_P : src_format = 0x7; break; + + case RK_FORMAT_YCrCb_422_SP : src_format = 0x4; src_cbcr_swp = 1; break; + case RK_FORMAT_YCrCb_422_P : src_format = 0x5; src_cbcr_swp = 1; break; + case RK_FORMAT_YCrCb_420_SP : src_format = 0x6; src_cbcr_swp = 1; break; + case RK_FORMAT_YCrCb_420_P : src_format = 0x7; src_cbcr_swp = 1; break; + } + } + + src_a_swp = msg->src.alpha_swap & 1; + + reg = ((reg & (~m_RGA_MODE_CTRL_SRC_RGB_PACK)) | (s_RGA_MODE_CTRL_SRC_RGB_PACK(src_rgb_pack))); + reg = ((reg & (~m_RGA_MODE_CTRL_SRC_FORMAT)) | (s_RGA_MODE_CTRL_SRC_FORMAT(src_format))); + reg = ((reg & (~m_RGA_MODE_CTRL_SRC_RB_SWAP)) | (s_RGA_MODE_CTRL_SRC_RB_SWAP(src_rb_swp))); + reg = ((reg & (~m_RGA_MODE_CTRL_SRC_ALPHA_SWAP)) | (s_RGA_MODE_CTRL_SRC_ALPHA_SWAP(src_a_swp))); + reg = ((reg & (~m_RGA_MODE_CTRL_SRC_UV_SWAP_MODE )) | (s_RGA_MODE_CTRL_SRC_UV_SWAP_MODE (src_cbcr_swp))); + + + /* YUV2RGB MODE */ + reg = ((reg & (~m_RGA_MODE_CTRL_YUV2RGB_CON_MODE)) | (s_RGA_MODE_CTRL_YUV2RGB_CON_MODE(msg->yuv2rgb_mode))); + + /* ROTATE MODE */ + reg = ((reg & (~m_RGA_MODE_CTRL_ROTATE_MODE)) | (s_RGA_MODE_CTRL_ROTATE_MODE(msg->rotate_mode))); + + /* SCALE MODE */ + reg = ((reg & (~m_RGA_MODE_CTRL_SCALE_MODE)) | (s_RGA_MODE_CTRL_SCALE_MODE(msg->scale_mode))); + + /* COLOR FILL MODE */ + reg = ((reg & (~m_RGA_MODE_CTRL_PAT_SEL)) | (s_RGA_MODE_CTRL_PAT_SEL(msg->color_fill_mode))); + + + if ((msg->render_mode == update_palette_table_mode)||(msg->render_mode == update_patten_buff_mode)) + { + dst_format = msg->pat.format; + } + else + { + dst_format = (u8)msg->dst.format; + } + + /* dst info set */ + switch (dst_format) + { + case RK_FORMAT_BGRA_8888 : dst_format = 0x0; dst_rb_swp = 0x1; break; + case RK_FORMAT_RGBA_4444 : dst_format = 0x3; break; + case RK_FORMAT_RGBA_5551 : dst_format = 0x2; break; + case RK_FORMAT_RGBA_8888 : dst_format = 0x0; break; + case RK_FORMAT_RGB_565 : dst_format = 0x1; break; + case RK_FORMAT_RGB_888 : dst_format = 0x0; dst_rgb_pack = 0x1; break; + case RK_FORMAT_BGR_888 : dst_format = 0x0; dst_rgb_pack = 0x1; dst_rb_swp = 1; break; + case RK_FORMAT_RGBX_8888 : dst_format = 0x0; break; + } + + dst_a_swp = msg->dst.alpha_swap & 1; + + reg = ((reg & (~m_RGA_MODE_CTRL_DST_FORMAT)) | (s_RGA_MODE_CTRL_DST_FORMAT(dst_format))); + reg = ((reg & (~m_RGA_MODE_CTRL_DST_RGB_PACK)) | (s_RGA_MODE_CTRL_DST_RGB_PACK(dst_rgb_pack))); + reg = ((reg & (~m_RGA_MODE_CTRL_DST_RB_SWAP)) | (s_RGA_MODE_CTRL_DST_RB_SWAP(dst_rb_swp))); + reg = ((reg & (~m_RGA_MODE_CTRL_DST_ALPHA_SWAP)) | (s_RGA_MODE_CTRL_DST_ALPHA_SWAP(dst_a_swp))); + reg = ((reg & (~m_RGA_MODE_CTRL_LUT_ENDIAN_MODE)) | (s_RGA_MODE_CTRL_LUT_ENDIAN_MODE(msg->endian_mode & 1))); + reg = ((reg & (~m_RGA_MODE_CTRL_CMD_INT_ENABLE)) | (s_RGA_MODE_CTRL_CMD_INT_ENABLE(msg->CMD_fin_int_enable))); + reg = ((reg & (~m_RGA_MODE_CTRL_SRC_TRANS_MODE)) | (s_RGA_MODE_CTRL_SRC_TRANS_MODE(msg->src_trans_mode))); + reg = ((reg & (~m_RGA_MODE_CTRL_ZERO_MODE_ENABLE)) | (s_RGA_MODE_CTRL_ZERO_MODE_ENABLE(msg->alpha_rop_mode >> 4))); + reg = ((reg & (~m_RGA_MODE_CTRL_DST_ALPHA_ENABLE)) | (s_RGA_MODE_CTRL_DST_ALPHA_ENABLE(msg->alpha_rop_mode >> 5))); + + *bRGA_MODE_CTL = reg; + +} + + + +/************************************************************* +Func: + RGA_set_src +Description: + fill src relate reg info +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +void +RGA_set_src(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_SRC_VIR_INFO; + u32 *bRGA_SRC_ACT_INFO; + u32 *bRGA_SRC_Y_MST; + u32 *bRGA_SRC_CB_MST; + u32 *bRGA_SRC_CR_MST; + + s16 x_off, y_off, stride; + s16 uv_x_off, uv_y_off, uv_stride; + u32 pixel_width; + + uv_x_off = uv_y_off = uv_stride = 0; + + bRGA_SRC_Y_MST = (u32 *)(base + RGA_SRC_Y_MST_OFFSET); + bRGA_SRC_CB_MST = (u32 *)(base + RGA_SRC_CB_MST_OFFSET); + bRGA_SRC_CR_MST = (u32 *)(base + RGA_SRC_CR_MST_OFFSET); + bRGA_SRC_VIR_INFO = (u32 *)(base + RGA_SRC_VIR_INFO_OFFSET); + bRGA_SRC_ACT_INFO = (u32 *)(base + RGA_SRC_ACT_INFO_OFFSET); + + x_off = msg->src.x_offset; + y_off = msg->src.y_offset; + + pixel_width = RGA_pixel_width_init(msg->src.format); + + stride = ((msg->src.vir_w * pixel_width) + 3) & (~3); + + switch(msg->src.format) + { + case RK_FORMAT_YCbCr_422_SP : + uv_stride = stride; + uv_x_off = x_off; + uv_y_off = y_off; + break; + case RK_FORMAT_YCbCr_422_P : + uv_stride = stride >> 1; + uv_x_off = x_off >> 1; + uv_y_off = y_off; + break; + case RK_FORMAT_YCbCr_420_SP : + uv_stride = stride; + uv_x_off = x_off; + uv_y_off = y_off >> 1; + break; + case RK_FORMAT_YCbCr_420_P : + uv_stride = stride >> 1; + uv_x_off = x_off >> 1; + uv_y_off = y_off >> 1; + break; + case RK_FORMAT_YCrCb_422_SP : + uv_stride = stride; + uv_x_off = x_off; + uv_y_off = y_off; + break; + case RK_FORMAT_YCrCb_422_P : + uv_stride = stride >> 1; + uv_x_off = x_off >> 1; + uv_y_off = y_off; + break; + case RK_FORMAT_YCrCb_420_SP : + uv_stride = stride; + uv_x_off = x_off; + uv_y_off = y_off >> 1; + break; + case RK_FORMAT_YCrCb_420_P : + uv_stride = stride >> 1; + uv_x_off = x_off >> 1; + uv_y_off = y_off >> 1; + break; + } + + + /* src addr set */ + *bRGA_SRC_Y_MST = msg->src.yrgb_addr + (y_off * stride) + (x_off * pixel_width); + *bRGA_SRC_CB_MST = msg->src.uv_addr + uv_y_off * uv_stride + uv_x_off; + *bRGA_SRC_CR_MST = msg->src.v_addr + uv_y_off * uv_stride + uv_x_off; + + if((msg->alpha_rop_flag >> 1) & 1) + *bRGA_SRC_CB_MST = (u32)msg->rop_mask_addr; + + if (msg->render_mode == color_palette_mode) + { + u8 shift; + u16 sw, byte_num; + shift = 3 - (msg->palette_mode & 3); + sw = msg->src.vir_w; + + byte_num = sw >> shift; + stride = (byte_num + 3) & (~3); + } + + /* src act window / vir window set */ + *bRGA_SRC_VIR_INFO = ((stride >> 2) | (msg->src.vir_h)<<16); + *bRGA_SRC_ACT_INFO = ((msg->src.act_w-1) | (msg->src.act_h-1)<<16); +} + + +/************************************************************* +Func: + RGA_set_dst +Description: + fill dst relate reg info +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +s32 RGA_set_dst(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_DST_MST; + u32 *bRGA_DST_VIR_INFO; + u32 *bRGA_DST_CTR_INFO; + u32 *bRGA_PRESCL_CB_MST; + u32 *bRGA_PRESCL_CR_MST; + u32 reg = 0; + + u8 pw; + s16 x_off = msg->dst.x_offset; + s16 y_off = msg->dst.y_offset; + u16 stride, rop_mask_stride; + + bRGA_DST_MST = (u32 *)(base + RGA_DST_MST_OFFSET); + bRGA_DST_VIR_INFO = (u32 *)(base + RGA_DST_VIR_INFO_OFFSET); + bRGA_DST_CTR_INFO = (u32 *)(base + RGA_DST_CTR_INFO_OFFSET); + bRGA_PRESCL_CB_MST = (u32 *)(base + RGA_PRESCL_CB_MST_OFFSET); + bRGA_PRESCL_CR_MST = (u32 *)(base + RGA_PRESCL_CR_MST_OFFSET); + + pw = RGA_pixel_width_init(msg->dst.format); + + stride = (msg->dst.vir_w * pw + 3) & (~3); + + *bRGA_DST_MST = (u32)msg->dst.yrgb_addr + (y_off * stride) + (x_off * pw); + + if (msg->render_mode == pre_scaling_mode) + { + switch(msg->dst.format) + { + case RK_FORMAT_YCbCr_422_SP : + *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off) * pw); + break; + case RK_FORMAT_YCbCr_422_P : + *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off>>1) * pw); + *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off) * stride) + ((x_off>>1) * pw); + break; + case RK_FORMAT_YCbCr_420_SP : + *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off) * pw); + break; + case RK_FORMAT_YCbCr_420_P : + *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); + *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); + break; + case RK_FORMAT_YCrCb_422_SP : + *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off) * pw); + break; + case RK_FORMAT_YCrCb_422_P : + *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off>>1) * pw); + *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off) * stride) + ((x_off>>1) * pw); + break; + case RK_FORMAT_YCrCb_420_SP : + *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off) * pw); + break; + case RK_FORMAT_YCrCb_420_P : + *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); + *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); + break; + } + } + + rop_mask_stride = (((msg->src.vir_w + 7)>>3) + 3) & (~3);//not dst_vir.w,hxx,2011.7.21 + + reg = (stride >> 2) & 0xffff; + reg = reg | ((rop_mask_stride>>2) << 16); + + if (msg->render_mode == line_point_drawing_mode) + { + reg &= 0xffff; + reg = reg | (msg->dst.vir_h << 16); + } + + *bRGA_DST_VIR_INFO = reg; + *bRGA_DST_CTR_INFO = (msg->dst.act_w - 1) | ((msg->dst.act_h - 1) << 16); + + return 0; +} + + +/************************************************************* +Func: + RGA_set_alpha_rop +Description: + fill alpha rop some relate reg bit +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ +void +RGA_set_alpha_rop(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_ALPHA_CON; + u32 *bRGA_ROP_CON0; + u32 *bRGA_ROP_CON1; + u32 reg = 0; + u32 rop_con0, rop_con1; + + u8 rop_mode = (msg->alpha_rop_mode) & 3; + u8 alpha_mode = msg->alpha_rop_mode & 3; + + rop_con0 = rop_con1 = 0; + + bRGA_ALPHA_CON = (u32 *)(base + RGA_ALPHA_CON_OFFSET); + + reg = ((reg & (~m_RGA_ALPHA_CON_ENABLE) )| (s_RGA_ALPHA_CON_ENABLE(msg->alpha_rop_flag & 1))); + reg = ((reg & (~m_RGA_ALPHA_CON_A_OR_R_SEL)) | (s_RGA_ALPHA_CON_A_OR_R_SEL((msg->alpha_rop_flag >> 1) & 1))); + reg = ((reg & (~m_RGA_ALPHA_CON_ALPHA_MODE)) | (s_RGA_ALPHA_CON_ALPHA_MODE(alpha_mode))); + reg = ((reg & (~m_RGA_ALPHA_CON_PD_MODE)) | (s_RGA_ALPHA_CON_PD_MODE(msg->PD_mode))); + reg = ((reg & (~m_RGA_ALPHA_CON_SET_CONSTANT_VALUE)) | (s_RGA_ALPHA_CON_SET_CONSTANT_VALUE(msg->alpha_global_value))); + reg = ((reg & (~m_RGA_ALPHA_CON_PD_M_SEL)) | (s_RGA_ALPHA_CON_PD_M_SEL(msg->alpha_rop_flag >> 3))); + reg = ((reg & (~m_RGA_ALPHA_CON_FADING_ENABLE)) | (s_RGA_ALPHA_CON_FADING_ENABLE(msg->alpha_rop_flag >> 2))); + reg = ((reg & (~m_RGA_ALPHA_CON_ROP_MODE_SEL)) | (s_RGA_ALPHA_CON_ROP_MODE_SEL(rop_mode))); + reg = ((reg & (~m_RGA_ALPHA_CON_CAL_MODE_SEL)) | (s_RGA_ALPHA_CON_CAL_MODE_SEL(msg->alpha_rop_flag >> 4))); + reg = ((reg & (~m_RGA_ALPHA_CON_DITHER_ENABLE)) | (s_RGA_ALPHA_CON_DITHER_ENABLE(msg->alpha_rop_flag >> 5))); + reg = ((reg & (~m_RGA_ALPHA_CON_GRADIENT_CAL_MODE)) | (s_RGA_ALPHA_CON_GRADIENT_CAL_MODE(msg->alpha_rop_flag >> 6))); + reg = ((reg & (~m_RGA_ALPHA_CON_AA_SEL)) | (s_RGA_ALPHA_CON_AA_SEL(msg->alpha_rop_flag >> 7))); + + *bRGA_ALPHA_CON = reg; + + if(rop_mode == 0) { + rop_con0 = ROP3_code[(msg->rop_code & 0xff)]; + } + else if(rop_mode == 1) { + rop_con0 = ROP3_code[(msg->rop_code & 0xff)]; + } + else if(rop_mode == 2) { + rop_con0 = ROP3_code[(msg->rop_code & 0xff)]; + rop_con1 = ROP3_code[(msg->rop_code & 0xff00)>>8]; + } + + bRGA_ROP_CON0 = (u32 *)(base + RGA_ROP_CON0_OFFSET); + bRGA_ROP_CON1 = (u32 *)(base + RGA_ROP_CON1_OFFSET); + + *bRGA_ROP_CON0 = (u32)rop_con0; + *bRGA_ROP_CON1 = (u32)rop_con1; +} + + +/************************************************************* +Func: + RGA_set_color +Description: + fill color some relate reg bit + bg_color/fg_color +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +void +RGA_set_color(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_SRC_TR_COLOR0; + u32 *bRGA_SRC_TR_COLOR1; + u32 *bRGA_SRC_BG_COLOR; + u32 *bRGA_SRC_FG_COLOR; + + + bRGA_SRC_BG_COLOR = (u32 *)(base + RGA_SRC_BG_COLOR_OFFSET); + bRGA_SRC_FG_COLOR = (u32 *)(base + RGA_SRC_FG_COLOR_OFFSET); + + *bRGA_SRC_BG_COLOR = msg->bg_color; /* 1bpp 0 */ + *bRGA_SRC_FG_COLOR = msg->fg_color; /* 1bpp 1 */ + + bRGA_SRC_TR_COLOR0 = (u32 *)(base + RGA_SRC_TR_COLOR0_OFFSET); + bRGA_SRC_TR_COLOR1 = (u32 *)(base + RGA_SRC_TR_COLOR1_OFFSET); + + *bRGA_SRC_TR_COLOR0 = msg->color_key_min; + *bRGA_SRC_TR_COLOR1 = msg->color_key_max; +} + + +/************************************************************* +Func: + RGA_set_fading +Description: + fill fading some relate reg bit +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +s32 +RGA_set_fading(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_FADING_CON; + u8 r, g, b; + u32 reg = 0; + + bRGA_FADING_CON = (u32 *)(base + RGA_FADING_CON_OFFSET); + + b = msg->fading.b; + g = msg->fading.g; + r = msg->fading.r; + + reg = (r<<8) | (g<<16) | (b<<24) | reg; + + *bRGA_FADING_CON = reg; + + return 0; +} + + +/************************************************************* +Func: + RGA_set_pat +Description: + fill patten some relate reg bit +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +s32 +RGA_set_pat(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_PAT_CON; + u32 *bRGA_PAT_START_POINT; + u32 reg = 0; + + bRGA_PAT_START_POINT = (u32 *)(base + RGA_PAT_START_POINT_OFFSET); + + bRGA_PAT_CON = (u32 *)(base + RGA_PAT_CON_OFFSET); + + *bRGA_PAT_START_POINT = (msg->pat.act_w * msg->pat.y_offset) + msg->pat.x_offset; + + reg = (msg->pat.act_w - 1) | ((msg->pat.act_h - 1) << 8) | (msg->pat.x_offset << 16) | (msg->pat.y_offset << 24); + *bRGA_PAT_CON = reg; + + return 0; +} + + + + +/************************************************************* +Func: + RGA_set_bitblt_reg_info +Description: + fill bitblt mode relate ren info +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +void +RGA_set_bitblt_reg_info(u8 *base, const struct rga_req * msg, TILE_INFO *tile) +{ + u32 *bRGA_SRC_Y_MST; + u32 *bRGA_SRC_CB_MST; + u32 *bRGA_SRC_CR_MST; + u32 *bRGA_SRC_X_PARA; + u32 *bRGA_SRC_Y_PARA; + u32 *bRGA_SRC_TILE_XINFO; + u32 *bRGA_SRC_TILE_YINFO; + u32 *bRGA_SRC_TILE_H_INCR; + u32 *bRGA_SRC_TILE_V_INCR; + u32 *bRGA_SRC_TILE_OFFSETX; + u32 *bRGA_SRC_TILE_OFFSETY; + + u32 *bRGA_DST_MST; + u32 *bRGA_DST_CTR_INFO; + + s32 m0, m1, m2, m3; + s32 pos[8]; + //s32 x_dx, x_dy, y_dx, y_dy; + s32 xmin, xmax, ymin, ymax; + s32 xp, yp; + u32 y_addr, u_addr, v_addr; + u32 pixel_width, stride; + + u_addr = v_addr = 0; + + /* src info */ + + bRGA_SRC_Y_MST = (u32 *)(base + RGA_SRC_Y_MST_OFFSET); + bRGA_SRC_CB_MST = (u32 *)(base + RGA_SRC_CB_MST_OFFSET); + bRGA_SRC_CR_MST = (u32 *)(base + RGA_SRC_CR_MST_OFFSET); + + bRGA_SRC_X_PARA = (u32 *)(base + RGA_SRC_X_PARA_OFFSET); + bRGA_SRC_Y_PARA = (u32 *)(base + RGA_SRC_Y_PARA_OFFSET); + + bRGA_SRC_TILE_XINFO = (u32 *)(base + RGA_SRC_TILE_XINFO_OFFSET); + bRGA_SRC_TILE_YINFO = (u32 *)(base + RGA_SRC_TILE_YINFO_OFFSET); + bRGA_SRC_TILE_H_INCR = (u32 *)(base + RGA_SRC_TILE_H_INCR_OFFSET); + bRGA_SRC_TILE_V_INCR = (u32 *)(base + RGA_SRC_TILE_V_INCR_OFFSET); + bRGA_SRC_TILE_OFFSETX = (u32 *)(base + RGA_SRC_TILE_OFFSETX_OFFSET); + bRGA_SRC_TILE_OFFSETY = (u32 *)(base + RGA_SRC_TILE_OFFSETY_OFFSET); + + bRGA_DST_MST = (u32 *)(base + RGA_DST_MST_OFFSET); + bRGA_DST_CTR_INFO = (u32 *)(base + RGA_DST_CTR_INFO_OFFSET); + + /* Matrix reg fill */ + m0 = (s32)(tile->matrix[0]*(1<<14)); + m1 = (s32)(tile->matrix[1]*(1<<14)); + m2 = (s32)(tile->matrix[2]*(1<<14)); + m3 = (s32)(tile->matrix[3]*(1<<14)); + + *bRGA_SRC_X_PARA = (m0 & 0xffff) | (m2 << 16); + *bRGA_SRC_Y_PARA = (m1 & 0xffff) | (m3 << 16); + + /* src tile information setting */ + if(msg->rotate_mode != 0)//add by hxx,2011.7.12,for rtl0707,when line scanning ,do not calc src tile info + { + *bRGA_SRC_TILE_XINFO = (tile->tile_start_x_coor & 0xffff) | (tile->tile_w << 16); + *bRGA_SRC_TILE_YINFO = (tile->tile_start_y_coor & 0xffff) | (tile->tile_h << 16); + + *bRGA_SRC_TILE_H_INCR = ((tile->x_dx) & 0xffff) | ((tile->x_dy) << 16); + *bRGA_SRC_TILE_V_INCR = ((tile->y_dx) & 0xffff) | ((tile->y_dy) << 16); + + *bRGA_SRC_TILE_OFFSETX = tile->tile_xoff; + *bRGA_SRC_TILE_OFFSETY = tile->tile_yoff; + } + + pixel_width = RGA_pixel_width_init(msg->src.format); + + stride = ((msg->src.vir_w * pixel_width) + 3) & (~3); + + if ((msg->rotate_mode == 1)||(msg->rotate_mode == 2)||(msg->rotate_mode == 3)) + { + pos[0] = tile->tile_start_x_coor<<8; + pos[1] = tile->tile_start_y_coor<<8; + + pos[2] = pos[0]; + pos[3] = pos[1] + tile->tile_h; + + pos[4] = pos[0] + tile->tile_w; + pos[5] = pos[1] + tile->tile_h; + + pos[6] = pos[0] + tile->tile_w; + pos[7] = pos[1]; + + pos[0] >>= 11; + pos[1] >>= 11; + + pos[2] >>= 11; + pos[3] >>= 11; + + pos[4] >>= 11; + pos[5] >>= 11; + + pos[6] >>= 11; + pos[7] >>= 11; + + xmax = (MAX(MAX(MAX(pos[0], pos[2]), pos[4]), pos[6]) + 1); + xmin = (MIN(MIN(MIN(pos[0], pos[2]), pos[4]), pos[6])); + + ymax = (MAX(MAX(MAX(pos[1], pos[3]), pos[5]), pos[7]) + 1); + ymin = (MIN(MIN(MIN(pos[1], pos[3]), pos[5]), pos[7])); + + xp = xmin + msg->src.x_offset; + yp = ymin + msg->src.y_offset; + + if (!((xmax < 0)||(xmin > msg->src.act_w - 1)||(ymax < 0)||(ymin > msg->src.act_h - 1))) + { + xp = CLIP(xp, 0, msg->src.vir_w - 1); + yp = CLIP(yp, 0, msg->src.vir_h - 1); + } + + switch(msg->src.format) + { + case RK_FORMAT_YCbCr_420_P : + y_addr = msg->src.yrgb_addr + yp*stride + xp; + u_addr = msg->src.uv_addr + (yp>>1)*(stride>>1) + (xp>>1); + v_addr = msg->src.v_addr + (yp>>1)*(stride>>1) + (xp>>1); + break; + case RK_FORMAT_YCbCr_420_SP : + y_addr = msg->src.yrgb_addr + yp*stride + xp; + u_addr = msg->src.uv_addr + (yp>>1)*stride + ((xp>>1)<<1); + break; + case RK_FORMAT_YCbCr_422_P : + y_addr = msg->src.yrgb_addr + yp*stride + xp; + u_addr = msg->src.uv_addr + (yp)*(stride>>1) + (xp>>1); + v_addr = msg->src.v_addr + (yp)*(stride>>1) + (xp>>1); + break; + case RK_FORMAT_YCbCr_422_SP: + y_addr = msg->src.yrgb_addr + yp*stride + xp; + u_addr = msg->src.uv_addr + yp*stride + ((xp>>1)<<1); + break; + case RK_FORMAT_YCrCb_420_P : + y_addr = msg->src.yrgb_addr + yp*stride + xp; + u_addr = msg->src.uv_addr + (yp>>1)*(stride>>1) + (xp>>1); + v_addr = msg->src.v_addr + (yp>>1)*(stride>>1) + (xp>>1); + break; + case RK_FORMAT_YCrCb_420_SP : + y_addr = msg->src.yrgb_addr + yp*stride + xp; + u_addr = msg->src.uv_addr + (yp>>1)*stride + ((xp>>1)<<1); + break; + case RK_FORMAT_YCrCb_422_P : + y_addr = msg->src.yrgb_addr + yp*stride + xp; + u_addr = msg->src.uv_addr + (yp)*(stride>>1) + (xp>>1); + v_addr = msg->src.v_addr + (yp)*(stride>>1) + (xp>>1); + break; + case RK_FORMAT_YCrCb_422_SP: + y_addr = msg->src.yrgb_addr + yp*stride + xp; + u_addr = msg->src.uv_addr + yp*stride + ((xp>>1)<<1); + break; + default : + y_addr = msg->src.yrgb_addr + yp*stride + xp*pixel_width; + break; + } + + *bRGA_SRC_Y_MST = y_addr; + *bRGA_SRC_CB_MST = u_addr; + *bRGA_SRC_CR_MST = v_addr; + } + + /*dst info*/ + pixel_width = RGA_pixel_width_init(msg->dst.format); + stride = (msg->dst.vir_w * pixel_width + 3) & (~3); + *bRGA_DST_MST = (u32)msg->dst.yrgb_addr + (tile->dst_ctrl.y_off * stride) + (tile->dst_ctrl.x_off * pixel_width); + *bRGA_DST_CTR_INFO = (tile->dst_ctrl.w) | ((tile->dst_ctrl.h) << 16); +} + + + + +/************************************************************* +Func: + RGA_set_color_palette_reg_info +Description: + fill color palette process some relate reg bit +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +void +RGA_set_color_palette_reg_info(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_SRC_Y_MST; + u32 p; + s16 x_off, y_off; + u16 src_stride; + u8 shift; + u16 sw, byte_num; + + x_off = msg->src.x_offset; + y_off = msg->src.y_offset; + + sw = msg->src.vir_w; + shift = 3 - (msg->palette_mode & 3); + byte_num = sw >> shift; + src_stride = (byte_num + 3) & (~3); + + p = msg->src.yrgb_addr; + p = p + (x_off>>shift) + y_off*src_stride; + + bRGA_SRC_Y_MST = (u32 *)(base + RGA_SRC_Y_MST_OFFSET); + *bRGA_SRC_Y_MST = (u32)p; +} + + +/************************************************************* +Func: + RGA_set_color_fill_reg_info +Description: + fill color fill process some relate reg bit +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ +void +RGA_set_color_fill_reg_info(u8 *base, const struct rga_req *msg) +{ + + u32 *bRGA_CP_GR_A; + u32 *bRGA_CP_GR_B; + u32 *bRGA_CP_GR_G; + u32 *bRGA_CP_GR_R; + + u32 *bRGA_PAT_CON; + + bRGA_CP_GR_A = (u32 *)(base + RGA_CP_GR_A_OFFSET); + bRGA_CP_GR_B = (u32 *)(base + RGA_CP_GR_B_OFFSET); + bRGA_CP_GR_G = (u32 *)(base + RGA_CP_GR_G_OFFSET); + bRGA_CP_GR_R = (u32 *)(base + RGA_CP_GR_R_OFFSET); + + bRGA_PAT_CON = (u32 *)(base + RGA_PAT_CON_OFFSET); + + *bRGA_CP_GR_A = (msg->gr_color.gr_x_a & 0xffff) | (msg->gr_color.gr_y_a << 16); + *bRGA_CP_GR_B = (msg->gr_color.gr_x_b & 0xffff) | (msg->gr_color.gr_y_b << 16); + *bRGA_CP_GR_G = (msg->gr_color.gr_x_g & 0xffff) | (msg->gr_color.gr_y_g << 16); + *bRGA_CP_GR_R = (msg->gr_color.gr_x_r & 0xffff) | (msg->gr_color.gr_y_r << 16); + + *bRGA_PAT_CON = (msg->pat.vir_w-1) | ((msg->pat.vir_h-1) << 8) | (msg->pat.x_offset << 16) | (msg->pat.y_offset << 24); + +} + + +/************************************************************* +Func: + RGA_set_line_drawing_reg_info +Description: + fill line drawing process some relate reg bit +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +s32 RGA_set_line_drawing_reg_info(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_LINE_DRAW; + u32 *bRGA_DST_VIR_INFO; + u32 *bRGA_LINE_DRAW_XY_INFO; + u32 *bRGA_LINE_DRAW_WIDTH; + u32 *bRGA_LINE_DRAWING_COLOR; + u32 *bRGA_LINE_DRAWING_MST; + + u32 reg = 0; + + s16 x_width, y_width; + u16 abs_x, abs_y, delta; + u16 stride; + u8 pw; + u32 start_addr; + u8 line_dir, dir_major, dir_semi_major; + u16 major_width; + + bRGA_LINE_DRAW = (u32 *)(base + RGA_LINE_DRAW_OFFSET); + bRGA_DST_VIR_INFO = (u32 *)(base + RGA_DST_VIR_INFO_OFFSET); + bRGA_LINE_DRAW_XY_INFO = (u32 *)(base + RGA_LINE_DRAW_XY_INFO_OFFSET); + bRGA_LINE_DRAW_WIDTH = (u32 *)(base + RGA_LINE_DRAWING_WIDTH_OFFSET); + bRGA_LINE_DRAWING_COLOR = (u32 *)(base + RGA_LINE_DRAWING_COLOR_OFFSET); + bRGA_LINE_DRAWING_MST = (u32 *)(base + RGA_LINE_DRAWING_MST_OFFSET); + + pw = RGA_pixel_width_init(msg->dst.format); + + stride = (msg->dst.vir_w * pw + 3) & (~3); + + start_addr = msg->dst.yrgb_addr + + (msg->line_draw_info.start_point.y * stride) + + (msg->line_draw_info.start_point.x * pw); + + x_width = msg->line_draw_info.start_point.x - msg->line_draw_info.end_point.x; + y_width = msg->line_draw_info.start_point.y - msg->line_draw_info.end_point.y; + + abs_x = abs(x_width); + abs_y = abs(y_width); + + if (abs_x >= abs_y) + { + if (y_width > 0) + dir_semi_major = 1; + else + dir_semi_major = 0; + + if (x_width > 0) + dir_major = 1; + else + dir_major = 0; + + if((abs_x == 0)||(abs_y == 0)) + delta = 0; + else + delta = (abs_y<<12)/abs_x; + + if (delta >> 12) + delta -= 1; + + major_width = abs_x; + line_dir = 0; + } + else + { + if (x_width > 0) + dir_semi_major = 1; + else + dir_semi_major = 0; + + if (y_width > 0) + dir_major = 1; + else + dir_major = 0; + + delta = (abs_x<<12)/abs_y; + major_width = abs_y; + line_dir = 1; + } + + reg = (reg & (~m_RGA_LINE_DRAW_MAJOR_WIDTH)) | (s_RGA_LINE_DRAW_MAJOR_WIDTH(major_width)); + reg = (reg & (~m_RGA_LINE_DRAW_LINE_DIRECTION)) | (s_RGA_LINE_DRAW_LINE_DIRECTION(line_dir)); + reg = (reg & (~m_RGA_LINE_DRAW_LINE_WIDTH)) | (s_RGA_LINE_DRAW_LINE_WIDTH(msg->line_draw_info.line_width - 1)); + reg = (reg & (~m_RGA_LINE_DRAW_INCR_VALUE)) | (s_RGA_LINE_DRAW_INCR_VALUE(delta)); + reg = (reg & (~m_RGA_LINE_DRAW_DIR_SEMI_MAJOR)) | (s_RGA_LINE_DRAW_DIR_SEMI_MAJOR(dir_semi_major)); + reg = (reg & (~m_RGA_LINE_DRAW_DIR_MAJOR)) | (s_RGA_LINE_DRAW_DIR_MAJOR(dir_major)); + reg = (reg & (~m_RGA_LINE_DRAW_LAST_POINT)) | (s_RGA_LINE_DRAW_LAST_POINT(msg->line_draw_info.flag >> 1)); + reg = (reg & (~m_RGA_LINE_DRAW_ANTI_ALISING)) | (s_RGA_LINE_DRAW_ANTI_ALISING(msg->line_draw_info.flag)); + + *bRGA_LINE_DRAW = reg; + + reg = (msg->line_draw_info.start_point.x & 0xfff) | ((msg->line_draw_info.start_point.y & 0xfff) << 16); + *bRGA_LINE_DRAW_XY_INFO = reg; + + *bRGA_LINE_DRAW_WIDTH = msg->dst.vir_w; + + *bRGA_LINE_DRAWING_COLOR = msg->line_draw_info.color; + + *bRGA_LINE_DRAWING_MST = (u32)start_addr; + + return 0; +} + + +/*full*/ +s32 +RGA_set_filter_reg_info(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_BLUR_SHARP_INFO; + u32 reg = 0; + + bRGA_BLUR_SHARP_INFO = (u32 *)(base + RGA_ALPHA_CON_OFFSET); + + reg = *bRGA_BLUR_SHARP_INFO; + + reg = ((reg & (~m_RGA_BLUR_SHARP_FILTER_TYPE)) | (s_RGA_BLUR_SHARP_FILTER_TYPE(msg->bsfilter_flag & 3))); + reg = ((reg & (~m_RGA_BLUR_SHARP_FILTER_MODE)) | (s_RGA_BLUR_SHARP_FILTER_MODE(msg->bsfilter_flag >>2))); + + *bRGA_BLUR_SHARP_INFO = reg; + + return 0; +} + + +/*full*/ +s32 +RGA_set_pre_scale_reg_info(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_PRE_SCALE_INFO; + u32 reg = 0; + u32 h_ratio = 0; + u32 v_ratio = 0; + u32 ps_yuv_flag = 0; + u32 src_width, src_height; + u32 dst_width, dst_height; + + src_width = msg->src.act_w; + src_height = msg->src.act_h; + + dst_width = msg->dst.act_w; + dst_height = msg->dst.act_h; + + h_ratio = (src_width )<<16 / dst_width; + v_ratio = (src_height)<<16 / dst_height; + + if (h_ratio <= (1<<16)) + h_ratio = 0; + else if (h_ratio <= (2<<16)) + h_ratio = 1; + else if (h_ratio <= (4<<16)) + h_ratio = 2; + else if (h_ratio <= (8<<16)) + h_ratio = 3; + + if (v_ratio <= (1<<16)) + v_ratio = 0; + else if (v_ratio <= (2<<16)) + v_ratio = 1; + else if (v_ratio <= (4<<16)) + v_ratio = 2; + else if (v_ratio <= (8<<16)) + v_ratio = 3; + + if(msg->src.format == msg->dst.format) + ps_yuv_flag = 0; + else + ps_yuv_flag = 1; + + bRGA_PRE_SCALE_INFO = (u32 *)(base + RGA_ALPHA_CON_OFFSET); + + reg = *bRGA_PRE_SCALE_INFO; + reg = ((reg & (~m_RGA_PRE_SCALE_HOR_RATIO)) | (s_RGA_PRE_SCALE_HOR_RATIO((u8)h_ratio))); + reg = ((reg & (~m_RGA_PRE_SCALE_VER_RATIO)) | (s_RGA_PRE_SCALE_VER_RATIO((u8)v_ratio))); + reg = ((reg & (~m_RGA_PRE_SCALE_OUTPUT_FORMAT)) | (s_RGA_PRE_SCALE_OUTPUT_FORMAT(ps_yuv_flag))); + + *bRGA_PRE_SCALE_INFO = reg; + + return 0; +} + + + +/*full*/ +int +RGA_set_update_palette_table_reg_info(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_LUT_MST; + + if (!msg->LUT_addr) { + return -1; + } + + bRGA_LUT_MST = (u32 *)(base + RGA_LUT_MST_OFFSET); + + *bRGA_LUT_MST = (u32)msg->LUT_addr; + + return 0; +} + + + +/*full*/ +int +RGA_set_update_patten_buff_reg_info(u8 *base, const struct rga_req *msg) +{ + u32 *bRGA_PAT_MST; + u32 *bRGA_PAT_CON; + u32 *bRGA_PAT_START_POINT; + u32 reg = 0; + rga_img_info_t *pat; + + pat = (rga_img_info_t *)&msg->pat; + + bRGA_PAT_START_POINT = (u32 *)(base + RGA_PAT_START_POINT_OFFSET); + bRGA_PAT_MST = (u32 *)(base + RGA_PAT_MST_OFFSET); + bRGA_PAT_CON = (u32 *)(base + RGA_PAT_CON_OFFSET); + + if ( !pat->yrgb_addr ) { + return -1; + } + *bRGA_PAT_MST = (u32)pat->yrgb_addr; + + if ((pat->vir_w > 256)||(pat->x_offset > 256)||(pat->y_offset > 256)) { + return -1; + } + *bRGA_PAT_START_POINT = (pat->vir_w * pat->y_offset) + pat->x_offset; + + reg = (pat->vir_w-1) | ((pat->vir_h-1) << 8) | (pat->x_offset << 16) | (pat->y_offset << 24); + *bRGA_PAT_CON = reg; + + return 0; +} + + +/************************************************************* +Func: + RGA_set_mmu_ctrl_reg_info +Description: + fill mmu relate some reg info +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ + +s32 +RGA_set_mmu_ctrl_reg_info(u8 *base, const struct rga_req *msg) +{ + u32 *RGA_MMU_TLB, *RGA_MMU_CTRL_ADDR; + u32 mmu_addr; + u8 TLB_size, mmu_enable, src_flag, dst_flag, CMD_flag; + u32 reg = 0; + + mmu_addr = (u32)msg->mmu_info.base_addr; + TLB_size = (msg->mmu_info.mmu_flag >> 4) & 0x3; + mmu_enable = msg->mmu_info.mmu_flag & 0x1; + + src_flag = (msg->mmu_info.mmu_flag >> 1) & 0x1; + dst_flag = (msg->mmu_info.mmu_flag >> 2) & 0x1; + CMD_flag = (msg->mmu_info.mmu_flag >> 3) & 0x1; + + RGA_MMU_TLB = (u32 *)(base + RGA_MMU_TLB_OFFSET); + RGA_MMU_CTRL_ADDR = (u32 *)(base + RGA_FADING_CON_OFFSET); + + reg = ((reg & (~m_RGA_MMU_CTRL_TLB_ADDR)) | s_RGA_MMU_CTRL_TLB_ADDR(mmu_addr)); + *RGA_MMU_TLB = reg; + + reg = *RGA_MMU_CTRL_ADDR; + reg = ((reg & (~m_RGA_MMU_CTRL_PAGE_TABLE_SIZE)) | s_RGA_MMU_CTRL_PAGE_TABLE_SIZE(TLB_size)); + reg = ((reg & (~m_RGA_MMU_CTRL_MMU_ENABLE)) | s_RGA_MMU_CTRL_MMU_ENABLE(mmu_enable)); + reg = ((reg & (~m_RGA_MMU_CTRL_SRC_FLUSH)) | s_RGA_MMU_CTRL_SRC_FLUSH(src_flag)); + reg = ((reg & (~m_RGA_MMU_CTRL_DST_FLUSH)) | s_RGA_MMU_CTRL_DST_FLUSH(dst_flag)); + reg = ((reg & (~m_RGA_MMU_CTRL_CMD_CHAN_FLUSH)) | s_RGA_MMU_CTRL_CMD_CHAN_FLUSH(CMD_flag)); + *RGA_MMU_CTRL_ADDR = reg; + + return 0; +} + + + +/************************************************************* +Func: + RGA_gen_reg_info +Description: + Generate RGA command reg list from rga_req struct. +Author: + ZhangShengqin +Date: + 20012-2-2 10:59:25 +**************************************************************/ +unsigned int +RGA_gen_reg_info(const struct rga_req *msg, unsigned char *base) +{ + TILE_INFO tile; + + memset(base, 0x0, 28*4); + RGA_set_mode_ctrl(base, msg); + + switch(msg->render_mode) + { + case bitblt_mode : + RGA_set_alpha_rop(base, msg); + RGA_set_src(base, msg); + RGA_set_dst(base, msg); + RGA_set_color(base, msg); + RGA_set_fading(base, msg); + RGA_set_pat(base, msg); + matrix_cal(msg, &tile); + dst_ctrl_cal(msg, &tile); + src_tile_info_cal(msg, &tile); + RGA_set_bitblt_reg_info(base, msg, &tile); + break; + case color_palette_mode : + RGA_set_src(base, msg); + RGA_set_dst(base, msg); + RGA_set_color(base, msg); + RGA_set_color_palette_reg_info(base, msg); + break; + case color_fill_mode : + RGA_set_dst(base, msg); + RGA_set_color(base, msg); + RGA_set_pat(base, msg); + RGA_set_color_fill_reg_info(base, msg); + break; + case line_point_drawing_mode : + RGA_set_alpha_rop(base, msg); + RGA_set_dst(base, msg); + RGA_set_color(base, msg); + RGA_set_line_drawing_reg_info(base, msg); + break; + case blur_sharp_filter_mode : + RGA_set_src(base, msg); + RGA_set_dst(base, msg); + RGA_set_filter_reg_info(base, msg); + break; + case pre_scaling_mode : + RGA_set_src(base, msg); + RGA_set_dst(base, msg); + RGA_set_pre_scale_reg_info(base, msg); + break; + case update_palette_table_mode : + if (RGA_set_update_palette_table_reg_info(base, msg)) { + return -1; + } + break; + case update_patten_buff_mode: + if (RGA_set_update_patten_buff_reg_info(base, msg)){ + return -1; + } + + break; + } + + RGA_set_mmu_ctrl_reg_info(base, msg); + + return 0; +} + + + diff --git a/drivers/video/rockchip/rga/rga_reg_info.h b/drivers/video/rockchip/rga/rga_reg_info.h new file mode 100644 index 000000000000..b869f926b230 --- /dev/null +++ b/drivers/video/rockchip/rga/rga_reg_info.h @@ -0,0 +1,485 @@ +#ifndef __REG_INFO_H__ +#define __REG_INFO_H__ + + +//#include "chip_register.h" + +//#include "rga_struct.h" +#include "rga.h" + +#ifndef MIN +#define MIN(X, Y) ((X)<(Y)?(X):(Y)) +#endif + +#ifndef MAX +#define MAX(X, Y) ((X)>(Y)?(X):(Y)) +#endif + +#ifndef ABS +#define ABS(X) (((X) < 0) ? (-(X)) : (X)) +#endif + +#ifndef CLIP +#define CLIP(x, a, b) ((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x)) +#endif + +//RGA register map + +//General Registers +#define rRGA_SYS_CTRL (*(volatile uint32 *)(RGA_BASE + RGA_SYS_CTRL)) +#define rRGA_CMD_CTRL (*(volatile uint32 *)(RGA_BASE + RGA_CMD_CTRL)) +#define rRGA_CMD_ADDR (*(volatile uint32 *)(RGA_BASE + RGA_CMD_ADDR)) +#define rRGA_STATUS (*(volatile uint32 *)(RGA_BASE + RGA_STATUS)) +#define rRGA_INT (*(volatile uint32 *)(RGA_BASE + RGA_INT)) +#define rRGA_AXI_ID (*(volatile uint32 *)(RGA_BASE + RGA_AXI_ID)) +#define rRGA_MMU_STA_CTRL (*(volatile uint32 *)(RGA_BASE + RGA_MMU_STA_CTRL)) +#define rRGA_MMU_STA (*(volatile uint32 *)(RGA_BASE + RGA_MMU_STA)) + +//Command code start +#define rRGA_MODE_CTRL (*(volatile uint32 *)(RGA_BASE + RGA_MODE_CTRL)) + +//Source Image Registers +#define rRGA_SRC_Y_MST (*(volatile uint32 *)(RGA_BASE + RGA_SRC_Y_MST)) +#define rRGA_SRC_CB_MST (*(volatile uint32 *)(RGA_BASE + RGA_SRC_CB_MST)) +#define rRGA_MASK_READ_MST (*(volatile uint32 *)(RGA_BASE + RGA_MASK_READ_MST)) //repeat +#define rRGA_SRC_CR_MST (*(volatile uint32 *)(RGA_BASE + RGA_SRC_CR_MST)) +#define rRGA_SRC_VIR_INFO (*(volatile uint32 *)(RGA_BASE + RGA_SRC_VIR_INFO)) +#define rRGA_SRC_ACT_INFO (*(volatile uint32 *)(RGA_BASE + RGA_SRC_ACT_INFO)) +#define rRGA_SRC_X_PARA (*(volatile uint32 *)(RGA_BASE + RGA_SRC_X_PARA)) +#define rRGA_SRC_Y_PARA (*(volatile uint32 *)(RGA_BASE + RGA_SRC_Y_PARA)) +#define rRGA_SRC_TILE_XINFO (*(volatile uint32 *)(RGA_BASE + RGA_SRC_TILE_XINFO)) +#define rRGA_SRC_TILE_YINFO (*(volatile uint32 *)(RGA_BASE + RGA_SRC_TILE_YINFO)) +#define rRGA_SRC_TILE_H_INCR (*(volatile uint32 *)(RGA_BASE + RGA_SRC_TILE_H_INCR)) +#define rRGA_SRC_TILE_V_INCR (*(volatile uint32 *)(RGA_BASE + RGA_SRC_TILE_V_INCR)) +#define rRGA_SRC_TILE_OFFSETX (*(volatile uint32 *)(RGA_BASE + RGA_SRC_TILE_OFFSETX)) +#define rRGA_SRC_TILE_OFFSETY (*(volatile uint32 *)(RGA_BASE + RGA_SRC_TILE_OFFSETY)) +#define rRGA_SRC_BG_COLOR (*(volatile uint32 *)(RGA_BASE + RGA_SRC_BG_COLOR)) +#define rRGA_SRC_FG_COLOR (*(volatile uint32 *)(RGA_BASE + RGA_SRC_FG_COLOR)) +#define rRGA_LINE_DRAWING_COLOR (*(volatile uint32 *)(RGA_BASE + RGA_LINE_DRAWING_COLOR)) //repeat +#define rRGA_SRC_TR_COLOR0 (*(volatile uint32 *)(RGA_BASE + RGA_SRC_TR_COLOR0)) +#define rRGA_CP_GR_A (*(volatile uint32 *)(RGA_BASE + RGA_CP_GR_A)) //repeat +#define rRGA_SRC_TR_COLOR1 (*(volatile uint32 *)(RGA_BASE + RGA_SRC_TR_COLOR1)) +#define rRGA_CP_GR_B (*(volatile uint32 *)(RGA_BASE + RGA_CP_GR_B)) //repeat + +#define rRGA_LINE_DRAW (*(volatile uint32 *)(RGA_BASE + RGA_LINE_DRAW)) +#define rRGA_PAT_START_POINT (*(volatile uint32 *)(RGA_BASE + RGA_PAT_START_POINT)) //repeat + +//Destination Image Registers +#define rRGA_DST_MST (*(volatile uint32 *)(RGA_BASE + RGA_DST_MST)) +#define rRGA_LUT_MST (*(volatile uint32 *)(RGA_BASE + RGA_LUT_MST)) //repeat +#define rRGA_PAT_MST (*(volatile uint32 *)(RGA_BASE + RGA_PAT_MST)) //repeat +#define rRGA_LINE_DRAWING_MST (*(volatile uint32 *)(RGA_BASE + RGA_LINE_DRAWING_MST)) //repeat + +#define rRGA_DST_VIR_INFO (*(volatile uint32 *)(RGA_BASE + RGA_DST_VIR_INFO)) + +#define rRGA_DST_CTR_INFO (*(volatile uint32 *)(RGA_BASE + RGA_DST_CTR_INFO)) +#define rRGA_LINE_DRAW_XY_INFO (*(volatile uint32 *)(RGA_BASE + RGA_LINE_DRAW_XY_INFO)) //repeat + +//Alpha/ROP Registers +#define rRGA_ALPHA_CON (*(volatile uint32 *)(RGA_BASE + RGA_ALPHA_CON)) +#define rRGA_FADING_CON (*(volatile uint32 *)(RGA_BASE + RGA_FADING_CON)) + +#define rRGA_PAT_CON (*(volatile uint32 *)(RGA_BASE + RGA_PAT_CON)) +#define rRGA_DST_VIR_WIDTH_PIX (*(volatile uint32 *)(RGA_BASE + RGA_DST_VIR_WIDTH_PIX)) //repeat + +#define rRGA_ROP_CON0 (*(volatile uint32 *)(RGA_BASE + RGA_ROP_CON0)) +#define rRGA_CP_GR_G (*(volatile uint32 *)(RGA_BASE + RGA_CP_GR_G)) //repeat +#define rRGA_PRESCL_CB_MST (*(volatile uint32 *)(RGA_BASE + RGA_PRESCL_CB_MST)) //repeat + +#define rRGA_ROP_CON1 (*(volatile uint32 *)(RGA_BASE + RGA_ROP_CON1)) +#define rRGA_CP_GR_R (*(volatile uint32 *)(RGA_BASE + RGA_CP_GR_R)) //repeat +#define rRGA_PRESCL_CR_MST (*(volatile uint32 *)(RGA_BASE + RGA_PRESCL_CR_MST)) //repeat + +//MMU Register +#define rRGA_MMU_CTRL (*(volatile uint32 *)(RGA_BASE + RGA_MMU_CTRL)) + + + + +//----------------------------------------------------------------- +//reg detail definition +//----------------------------------------------------------------- +/*RGA_SYS_CTRL*/ +#define m_RGA_SYS_CTRL_CMD_MODE ( 1<<2 ) +#define m_RGA_SYS_CTRL_OP_ST_SLV ( 1<<1 ) +#define m_RGA_sys_CTRL_SOFT_RESET ( 1<<0 ) + +#define s_RGA_SYS_CTRL_CMD_MODE(x) ( (x&0x1)<<2 ) +#define s_RGA_SYS_CTRL_OP_ST_SLV(x) ( (x&0x1)<<1 ) +#define s_RGA_sys_CTRL_SOFT_RESET(x) ( (x&0x1)<<0 ) + + +/*RGA_CMD_CTRL*/ +#define m_RGA_CMD_CTRL_CMD_INCR_NUM ( 0x3ff<<3 ) +#define m_RGA_CMD_CTRL_CMD_STOP_MODE ( 1<<2 ) +#define m_RGA_CMD_CTRL_CMD_INCR_VALID ( 1<<1 ) +#define m_RGA_CMD_CTRL_CMD_LINE_FET_ST ( 1<<0 ) + +#define s_RGA_CMD_CTRL_CMD_INCR_NUM(x) ( (x&0x3ff)<<3 ) +#define s_RGA_CMD_CTRL_CMD_STOP_MODE(x) ( (x&0x1)<<2 ) +#define s_RGA_CMD_CTRL_CMD_INCR_VALID(x) ( (x&0x1)<<1 ) +#define s_RGA_CMD_CTRL_CMD_LINE_FET_ST(x) ( (x*0x1)<<0 ) + + +/*RGA_STATUS*/ +#define m_RGA_CMD_STATUS_CMD_TOTAL_NUM ( 0xfff<<20 ) +#define m_RGA_CMD_STATUS_NOW_CMD_NUM ( 0xfff<<8 ) +#define m_RGA_CMD_STATUS_ENGINE_STATUS ( 1<<0 ) + + +/*RGA_INT*/ +#define m_RGA_INT_ALL_CMD_DONE_INT_EN ( 1<<10 ) +#define m_RGA_INT_MMU_INT_EN ( 1<<9 ) +#define m_RGA_INT_ERROR_INT_EN ( 1<<8 ) +#define m_RGA_INT_NOW_CMD_DONE_INT_CLEAR ( 1<<7 ) +#define m_RGA_INT_ALL_CMD_DONE_INT_CLEAR ( 1<<6 ) +#define m_RGA_INT_MMU_INT_CLEAR ( 1<<5 ) +#define m_RGA_INT_ERROR_INT_CLEAR ( 1<<4 ) +#define m_RGA_INT_NOW_CMD_DONE_INT_FLAG ( 1<<3 ) +#define m_RGA_INT_ALL_CMD_DONE_INT_FLAG ( 1<<2 ) +#define m_RGA_INT_MMU_INT_FLAG ( 1<<1 ) +#define m_RGA_INT_ERROR_INT_FLAG ( 1<<0 ) + +#define s_RGA_INT_ALL_CMD_DONE_INT_EN(x) ( (x&0x1)<<10 ) +#define s_RGA_INT_MMU_INT_EN(x) ( (x&0x1)<<9 ) +#define s_RGA_INT_ERROR_INT_EN(x) ( (x&0x1)<<8 ) +#define s_RGA_INT_NOW_CMD_DONE_INT_CLEAR(x) ( (x&0x1)<<7 ) +#define s_RGA_INT_ALL_CMD_DONE_INT_CLEAR(x) ( (x&0x1)<<6 ) +#define s_RGA_INT_MMU_INT_CLEAR(x) ( (x&0x1)<<5 ) +#define s_RGA_INT_ERROR_INT_CLEAR(x) ( (x&0x1)<<4 ) + + +/*RGA_AXI_ID*/ +#define m_RGA_AXI_ID_MMU_READ ( 3<<30 ) +#define m_RGA_AXI_ID_MMU_WRITE ( 3<<28 ) +#define m_RGA_AXI_ID_MASK_READ ( 0xf<<24 ) +#define m_RGA_AXI_ID_CMD_FET ( 0xf<<20 ) +#define m_RGA_AXI_ID_DST_WRITE ( 0xf<<16 ) +#define m_RGA_AXI_ID_DST_READ ( 0xf<<12 ) +#define m_RGA_AXI_ID_SRC_CR_READ ( 0xf<<8 ) +#define m_RGA_AXI_ID_SRC_CB_READ ( 0xf<<4 ) +#define m_RGA_AXI_ID_SRC_Y_READ ( 0xf<<0 ) + +#define s_RGA_AXI_ID_MMU_READ(x) ( (x&0x3)<<30 ) +#define s_RGA_AXI_ID_MMU_WRITE(x) ( (x&0x3)<<28 ) +#define s_RGA_AXI_ID_MASK_READ(x) ( (x&0xf)<<24 ) +#define s_RGA_AXI_ID_CMD_FET(x) ( (x&0xf)<<20 ) +#define s_RGA_AXI_ID_DST_WRITE(x) ( (x&0xf)<<16 ) +#define s_RGA_AXI_ID_DST_READ(x) ( (x&0xf)<<12 ) +#define s_RGA_AXI_ID_SRC_CR_READ(x) ( (x&0xf)<<8 ) +#define s_RGA_AXI_ID_SRC_CB_READ(x) ( (x&0xf)<<4 ) +#define s_RGA_AXI_ID_SRC_Y_READ(x) ( (x&0xf)<<0 ) + + +/*RGA_MMU_STA_CTRL*/ +#define m_RGA_MMU_STA_CTRL_TLB_STA_CLEAR ( 1<<3 ) +#define m_RGA_MMU_STA_CTRL_TLB_STA_RESUME ( 1<<2 ) +#define m_RGA_MMU_STA_CTRL_TLB_STA_PAUSE ( 1<<1 ) +#define m_RGA_MMU_STA_CTRL_TLB_STA_EN ( 1<<0 ) + +#define s_RGA_MMU_STA_CTRL_TLB_STA_CLEAR(x) ( (x&0x1)<<3 ) +#define s_RGA_MMU_STA_CTRL_TLB_STA_RESUME(x) ( (x&0x1)<<2 ) +#define s_RGA_MMU_STA_CTRL_TLB_STA_PAUSE(x) ( (x&0x1)<<1 ) +#define s_RGA_MMU_STA_CTRL_TLB_STA_EN(x) ( (x&0x1)<<0 ) + + + +/* RGA_MODE_CTRL */ +#define m_RGA_MODE_CTRL_2D_RENDER_MODE ( 7<<0 ) +#define m_RGA_MODE_CTRL_SRC_RGB_PACK ( 1<<3 ) +#define m_RGA_MODE_CTRL_SRC_FORMAT ( 15<<4 ) +#define m_RGA_MODE_CTRL_SRC_RB_SWAP ( 1<<8 ) +#define m_RGA_MODE_CTRL_SRC_ALPHA_SWAP ( 1<<9 ) +#define m_RGA_MODE_CTRL_SRC_UV_SWAP_MODE ( 1<<10 ) +#define m_RGA_MODE_CTRL_YUV2RGB_CON_MODE ( 3<<11 ) +#define m_RGA_MODE_CTRL_SRC_TRANS_MODE (0x1f<<13 ) +#define m_RGA_MODE_CTRL_SRC_TR_MODE ( 1<<13 ) +#define m_RGA_MODE_CTRL_SRC_TR_R_EN ( 1<<14 ) +#define m_RGA_MODE_CTRL_SRC_TR_G_EN ( 1<<15 ) +#define m_RGA_MODE_CTRL_SRC_TR_B_EN ( 1<<16 ) +#define m_RGA_MODE_CTRL_SRC_TR_A_EN ( 1<<17 ) +#define m_RGA_MODE_CTRL_ROTATE_MODE ( 3<<18 ) +#define m_RGA_MODE_CTRL_SCALE_MODE ( 3<<20 ) +#define m_RGA_MODE_CTRL_PAT_SEL ( 1<<22 ) +#define m_RGA_MODE_CTRL_DST_FORMAT ( 3<<23 ) +#define m_RGA_MODE_CTRL_DST_RGB_PACK ( 1<<25 ) +#define m_RGA_MODE_CTRL_DST_RB_SWAP ( 1<<26 ) +#define m_RGA_MODE_CTRL_DST_ALPHA_SWAP ( 1<<27 ) +#define m_RGA_MODE_CTRL_LUT_ENDIAN_MODE ( 1<<28 ) +#define m_RGA_MODE_CTRL_CMD_INT_ENABLE ( 1<<29 ) +#define m_RGA_MODE_CTRL_ZERO_MODE_ENABLE ( 1<<30 ) +#define m_RGA_MODE_CTRL_DST_ALPHA_ENABLE ( 1<<30 ) + + + +#define s_RGA_MODE_CTRL_2D_RENDER_MODE(x) ( (x&0x7)<<0 ) +#define s_RGA_MODE_CTRL_SRC_RGB_PACK(x) ( (x&0x1)<<3 ) +#define s_RGA_MODE_CTRL_SRC_FORMAT(x) ( (x&0xf)<<4 ) +#define s_RGA_MODE_CTRL_SRC_RB_SWAP(x) ( (x&0x1)<<8 ) +#define s_RGA_MODE_CTRL_SRC_ALPHA_SWAP(x) ( (x&0x1)<<9 ) +#define s_RGA_MODE_CTRL_SRC_UV_SWAP_MODE(x) ( (x&0x1)<<10 ) +#define s_RGA_MODE_CTRL_YUV2RGB_CON_MODE(x) ( (x&0x3)<<11 ) +#define s_RGA_MODE_CTRL_SRC_TRANS_MODE(x) ( (x&0x1f)<<13 ) +#define s_RGA_MODE_CTRL_SRC_TR_MODE(x) ( (x&0x1)<<13 ) +#define s_RGA_MODE_CTRL_SRC_TR_R_EN(x) ( (x&0x1)<<14 ) +#define s_RGA_MODE_CTRL_SRC_TR_G_EN(x) ( (x&0x1)<<15 ) +#define s_RGA_MODE_CTRL_SRC_TR_B_EN(x) ( (x&0x1)<<16 ) +#define s_RGA_MODE_CTRL_SRC_TR_A_EN(x) ( (x&0x1)<<17 ) +#define s_RGA_MODE_CTRL_ROTATE_MODE(x) ( (x&0x3)<<18 ) +#define s_RGA_MODE_CTRL_SCALE_MODE(x) ( (x&0x3)<<20 ) +#define s_RGA_MODE_CTRL_PAT_SEL(x) ( (x&0x1)<<22 ) +#define s_RGA_MODE_CTRL_DST_FORMAT(x) ( (x&0x3)<<23 ) +#define s_RGA_MODE_CTRL_DST_RGB_PACK(x) ( (x&0x1)<<25 ) +#define s_RGA_MODE_CTRL_DST_RB_SWAP(x) ( (x&0x1)<<26 ) +#define s_RGA_MODE_CTRL_DST_ALPHA_SWAP(x) ( (x&0x1)<<27 ) +#define s_RGA_MODE_CTRL_LUT_ENDIAN_MODE(x) ( (x&0x1)<<28 ) +#define s_RGA_MODE_CTRL_CMD_INT_ENABLE(x) ( (x&0x1)<<29 ) +#define s_RGA_MODE_CTRL_ZERO_MODE_ENABLE(x) ( (x&0x1)<<30 ) +#define s_RGA_MODE_CTRL_DST_ALPHA_ENABLE(x) ( (x&0x1)<<31 ) + + + +/* RGA_LINE_DRAW */ +#define m_RGA_LINE_DRAW_MAJOR_WIDTH ( 0x7ff<<0 ) +#define m_RGA_LINE_DRAW_LINE_DIRECTION ( 0x1<<11) +#define m_RGA_LINE_DRAW_LINE_WIDTH ( 0xf<<12) +#define m_RGA_LINE_DRAW_INCR_VALUE ( 0xfff<<16) +#define m_RGA_LINE_DRAW_DIR_MAJOR ( 0x1<<28) +#define m_RGA_LINE_DRAW_DIR_SEMI_MAJOR ( 0x1<<29) +#define m_RGA_LINE_DRAW_LAST_POINT ( 0x1<<30) +#define m_RGA_LINE_DRAW_ANTI_ALISING ( 0x1<<31) + +#define s_RGA_LINE_DRAW_MAJOR_WIDTH(x) (((x)&0x7ff)<<0 ) +#define s_RGA_LINE_DRAW_LINE_DIRECTION(x) ( ((x)&0x1)<<11) +#define s_RGA_LINE_DRAW_LINE_WIDTH(x) ( ((x)&0xf)<<12) +#define s_RGA_LINE_DRAW_INCR_VALUE(x) (((x)&0xfff)<<16) +#define s_RGA_LINE_DRAW_DIR_MAJOR(x) ( ((x)&0x1)<<28) +#define s_RGA_LINE_DRAW_DIR_SEMI_MAJOR(x) ( ((x)&0x1)<<29) +#define s_RGA_LINE_DRAW_LAST_POINT(x) ( ((x)&0x1)<<30) +#define s_RGA_LINE_DRAW_ANTI_ALISING(x) ( ((x)&0x1)<<31) + + +/* RGA_ALPHA_CON */ +#define m_RGA_ALPHA_CON_ENABLE ( 0x1<<0 ) +#define m_RGA_ALPHA_CON_A_OR_R_SEL ( 0x1<<1 ) +#define m_RGA_ALPHA_CON_ALPHA_MODE ( 0x3<<2 ) +#define m_RGA_ALPHA_CON_PD_MODE ( 0xf<<4 ) +#define m_RGA_ALPHA_CON_SET_CONSTANT_VALUE (0xff<<8 ) +#define m_RGA_ALPHA_CON_PD_M_SEL ( 0x1<<16) +#define m_RGA_ALPHA_CON_FADING_ENABLE ( 0x1<<17) +#define m_RGA_ALPHA_CON_ROP_MODE_SEL ( 0x3<<18) +#define m_RGA_ALPHA_CON_CAL_MODE_SEL ( 0x1<<28) +#define m_RGA_ALPHA_CON_DITHER_ENABLE ( 0x1<<29) +#define m_RGA_ALPHA_CON_GRADIENT_CAL_MODE ( 0x1<<30) +#define m_RGA_ALPHA_CON_AA_SEL ( 0x1<<31) + +#define s_RGA_ALPHA_CON_ENABLE(x) ( (x&0x1)<<0 ) +#define s_RGA_ALPHA_CON_A_OR_R_SEL(x) ( (x&0x1)<<1 ) +#define s_RGA_ALPHA_CON_ALPHA_MODE(x) ( (x&0x3)<<2 ) +#define s_RGA_ALPHA_CON_PD_MODE(x) ( (x&0xf)<<4 ) +#define s_RGA_ALPHA_CON_SET_CONSTANT_VALUE(x) ((x&0xff)<<8 ) +#define s_RGA_ALPHA_CON_PD_M_SEL(x) ( (x&0x1)<<16) +#define s_RGA_ALPHA_CON_FADING_ENABLE(x) ( (x&0x1)<<17) +#define s_RGA_ALPHA_CON_ROP_MODE_SEL(x) ( (x&0x3)<<18) +#define s_RGA_ALPHA_CON_CAL_MODE_SEL(x) ( (x&0x1)<<28) +#define s_RGA_ALPHA_CON_DITHER_ENABLE(x) ( (x&0x1)<<29) +#define s_RGA_ALPHA_CON_GRADIENT_CAL_MODE(x) ( (x&0x1)<<30) +#define s_RGA_ALPHA_CON_AA_SEL(x) ( (x&0x1)<<31) + + +/* blur sharp mode */ +#define m_RGA_BLUR_SHARP_FILTER_MODE ( 0x1<<25 ) +#define m_RGA_BLUR_SHARP_FILTER_TYPE ( 0x3<<26 ) + +#define s_RGA_BLUR_SHARP_FILTER_MODE(x) ( (x&0x1)<<25 ) +#define s_RGA_BLUR_SHARP_FILTER_TYPE(x) ( (x&0x3)<<26 ) + + +/* pre scale mode */ +#define m_RGA_PRE_SCALE_HOR_RATIO ( 0x3 <<20 ) +#define m_RGA_PRE_SCALE_VER_RATIO ( 0x3 <<22 ) +#define m_RGA_PRE_SCALE_OUTPUT_FORMAT ( 0x1 <<24 ) + +#define s_RGA_PRE_SCALE_HOR_RATIO(x) ( (x&0x3) <<20 ) +#define s_RGA_PRE_SCALE_VER_RATIO(x) ( (x&0x3) <<22 ) +#define s_RGA_PRE_SCALE_OUTPUT_FORMAT(x) ( (x&0x1) <<24 ) + + + +/* RGA_MMU_CTRL*/ +#define m_RGA_MMU_CTRL_TLB_ADDR ( 0xffffffff<<0) +#define m_RGA_MMU_CTRL_PAGE_TABLE_SIZE ( 0x3<<4 ) +#define m_RGA_MMU_CTRL_MMU_ENABLE ( 0x1<<0 ) +#define m_RGA_MMU_CTRL_SRC_FLUSH ( 0x1<<1 ) +#define m_RGA_MMU_CTRL_DST_FLUSH ( 0x1<<2 ) +#define m_RGA_MMU_CTRL_CMD_CHAN_FLUSH ( 0x1<<3 ) + +#define s_RGA_MMU_CTRL_TLB_ADDR(x) ((x&0xffffffff)) +#define s_RGA_MMU_CTRL_PAGE_TABLE_SIZE(x) ((x&0x3)<<4) +#define s_RGA_MMU_CTRL_MMU_ENABLE(x) ((x&0x1)<<0) +#define s_RGA_MMU_CTRL_SRC_FLUSH(x) ((x&0x1)<<1) +#define s_RGA_MMU_CTRL_DST_FLUSH(x) ((x&0x1)<<2) +#define s_RGA_MMU_CTRL_CMD_CHAN_FLUSH(x) ((x&0x1)<<3) + +#endif + +/* +#define RGA_MODE_CTRL_OFFSET 0x0 +#define RGA_SRC_Y_MST_OFFSET 0x4 +#define RGA_SRC_CB_MST_OFFSET 0x8 +#define RGA_SRC_CR_MST_OFFSET 0xc +#define RGA_SRC_VIR_INFO_OFFSET 0x10 +#define RGA_SRC_ACT_INFO_OFFSET 0x14 +#define RGA_SRC_X_PARA_OFFSET 0x18 +#define RGA_SRC_Y_PARA_OFFSET 0x1c +#define RGA_SRC_TILE_XINFO_OFFSET 0x20 +#define RGA_SRC_TILE_YINFO_OFFSET 0x24 +#define RGA_SRC_TILE_H_INCR_OFFSET 0x28 +#define RGA_SRC_TILE_V_INCR_OFFSET 0x2c +#define RGA_SRC_TILE_OFFSETX_OFFSET 0x30 +#define RGA_SRC_TILE_OFFSETY_OFFSET 0x34 +#define RGA_SRC_BG_COLOR_OFFSET 0x38 + +#define RGA_SRC_FG_COLOR_OFFSET 0x3c +#define RGA_LINE_DRAWING_COLOR_OFFSET 0x3c + +#define RGA_SRC_TR_COLOR0_OFFSET 0x40 +#define RGA_CP_GR_A_OFFSET 0x40 //repeat + +#define RGA_SRC_TR_COLOR1_OFFSET 0x44 +#define RGA_CP_GR_B_OFFSET 0x44 //repeat + +#define RGA_LINE_DRAW_OFFSET 0x48 +#define RGA_PAT_START_POINT_OFFSET 0x48 //repeat + +#define RGA_DST_MST_OFFSET 0x4c +#define RGA_LUT_MST_OFFSET 0x4c //repeat +#define RGA_PAT_MST_OFFSET 0x4c //repeat +#define RGA_LINE_DRAWING_MST_OFFSET 0x4c //repeat + +#define RGA_DST_VIR_INFO_OFFSET 0x50 + +#define RGA_DST_CTR_INFO_OFFSET 0x54 +#define RGA_LINE_DRAW_XY_INFO_OFFSET 0x54 //repeat + +#define RGA_ALPHA_CON_OFFSET 0x58 +#define RGA_FADING_CON_OFFSET 0x5c + +#define RGA_PAT_CON_OFFSET 0x60 +#define RGA_LINE_DRAWING_WIDTH_OFFSET 0x60 //repeat + +#define RGA_ROP_CON0_OFFSET 0x64 +#define RGA_CP_GR_G_OFFSET 0x64 //repeat +#define RGA_PRESCL_CB_MST_OFFSET 0x64 //repeat + +#define RGA_ROP_CON1_OFFSET 0x68 +#define RGA_CP_GR_R_OFFSET 0x68 //repeat +#define RGA_PRESCL_CR_MST_OFFSET 0x68 //repeat + +#define RGA_MMU_CTRL_OFFSET 0x6c + + +#define RGA_SYS_CTRL_OFFSET 0x000 +#define RGA_CMD_CTRL_OFFSET 0x004 +#define RGA_CMD_ADDR_OFFSET 0x008 +#define RGA_STATUS_OFFSET 0x00c +#define RGA_INT_OFFSET 0x010 +#define RGA_AXI_ID_OFFSET 0x014 +#define RGA_MMU_STA_CTRL_OFFSET 0x018 +#define RGA_MMU_STA_OFFSET 0x01c +*/ +//hxx + +#define RGA_SYS_CTRL_OFFSET (RGA_SYS_CTRL-0x100) +#define RGA_CMD_CTRL_OFFSET (RGA_CMD_CTRL-0x100) +#define RGA_CMD_ADDR_OFFSET (RGA_CMD_ADDR-0x100) +#define RGA_STATUS_OFFSET (RGA_STATUS-0x100) +#define RGA_INT_OFFSET (RGA_INT-0x100) +#define RGA_AXI_ID_OFFSET (RGA_AXI_ID-0x100) +#define RGA_MMU_STA_CTRL_OFFSET (RGA_MMU_STA_CTRL-0x100) +#define RGA_MMU_STA_OFFSET (RGA_MMU_STA-0x100) + +#define RGA_MODE_CTRL_OFFSET (RGA_MODE_CTRL-0x100) +#define RGA_SRC_Y_MST_OFFSET (RGA_SRC_Y_MST-0x100) +#define RGA_SRC_CB_MST_OFFSET (RGA_SRC_CB_MST-0x100) +#define RGA_SRC_CR_MST_OFFSET (RGA_SRC_CR_MST-0x100) +#define RGA_SRC_VIR_INFO_OFFSET (RGA_SRC_VIR_INFO-0x100) +#define RGA_SRC_ACT_INFO_OFFSET (RGA_SRC_ACT_INFO-0x100) +#define RGA_SRC_X_PARA_OFFSET (RGA_SRC_X_PARA-0x100) +#define RGA_SRC_Y_PARA_OFFSET (RGA_SRC_Y_PARA-0x100) +#define RGA_SRC_TILE_XINFO_OFFSET (RGA_SRC_TILE_XINFO-0x100) +#define RGA_SRC_TILE_YINFO_OFFSET (RGA_SRC_TILE_YINFO-0x100) +#define RGA_SRC_TILE_H_INCR_OFFSET (RGA_SRC_TILE_H_INCR-0x100) +#define RGA_SRC_TILE_V_INCR_OFFSET (RGA_SRC_TILE_V_INCR-0x100) +#define RGA_SRC_TILE_OFFSETX_OFFSET (RGA_SRC_TILE_OFFSETX-0x100) +#define RGA_SRC_TILE_OFFSETY_OFFSET (RGA_SRC_TILE_OFFSETY-0x100) +#define RGA_SRC_BG_COLOR_OFFSET (RGA_SRC_BG_COLOR-0x100) + +#define RGA_SRC_FG_COLOR_OFFSET (RGA_SRC_FG_COLOR-0x100) +#define RGA_LINE_DRAWING_COLOR_OFFSET (RGA_LINE_DRAWING_COLOR-0x100) + +#define RGA_SRC_TR_COLOR0_OFFSET (RGA_SRC_TR_COLOR0-0x100) +#define RGA_CP_GR_A_OFFSET (RGA_CP_GR_A-0x100) //repeat + +#define RGA_SRC_TR_COLOR1_OFFSET (RGA_SRC_TR_COLOR1-0x100) +#define RGA_CP_GR_B_OFFSET (RGA_CP_GR_B-0x100) //repeat + +#define RGA_LINE_DRAW_OFFSET (RGA_LINE_DRAW-0x100) +#define RGA_PAT_START_POINT_OFFSET (RGA_PAT_START_POINT-0x100) //repeat + +#define RGA_DST_MST_OFFSET (RGA_DST_MST-0x100) +#define RGA_LUT_MST_OFFSET (RGA_LUT_MST-0x100) //repeat +#define RGA_PAT_MST_OFFSET (RGA_PAT_MST-0x100) //repeat +#define RGA_LINE_DRAWING_MST_OFFSET (RGA_LINE_DRAWING_MST-0x100) //repeat + +#define RGA_DST_VIR_INFO_OFFSET (RGA_DST_VIR_INFO-0x100) + +#define RGA_DST_CTR_INFO_OFFSET (RGA_DST_CTR_INFO-0x100) +#define RGA_LINE_DRAW_XY_INFO_OFFSET (RGA_LINE_DRAW_XY_INFO-0x100) //repeat + +#define RGA_ALPHA_CON_OFFSET (RGA_ALPHA_CON-0x100) + +#define RGA_PAT_CON_OFFSET (RGA_PAT_CON-0x100) +#define RGA_LINE_DRAWING_WIDTH_OFFSET (RGA_DST_VIR_WIDTH_PIX-0x100) //repeat + +#define RGA_ROP_CON0_OFFSET (RGA_ROP_CON0-0x100) +#define RGA_CP_GR_G_OFFSET (RGA_CP_GR_G-0x100) //repeat +#define RGA_PRESCL_CB_MST_OFFSET (RGA_PRESCL_CB_MST-0x100) //repeat + +#define RGA_ROP_CON1_OFFSET (RGA_ROP_CON1-0x100) +#define RGA_CP_GR_R_OFFSET (RGA_CP_GR_R-0x100) //repeat +#define RGA_PRESCL_CR_MST_OFFSET (RGA_PRESCL_CR_MST-0x100) //repeat + +#define RGA_FADING_CON_OFFSET (RGA_FADING_CON-0x100) +#define RGA_MMU_TLB_OFFSET (RGA_MMU_CTRL-0x100) + + +void matrix_cal(const struct rga_req *msg, TILE_INFO *tile); + + +unsigned int RGA_gen_reg_info(const struct rga_req *msg, unsigned char *base); +uint8_t RGA_pixel_width_init(uint32_t format); + + + +/* +u8 RGA_pixel_width_init(u32 format); +void dst_ctrl_cal(msg_t *msg, TILE_INFO *tile); +void src_tile_info_cal(msg_t *msg, TILE_INFO *tile); +void RGA_set_mode_ctrl(u8 *base, msg_t *msg); +void RGA_set_src(u8 *base, msg_t *msg, TILE_INFO *tile); +s32 RGA_set_dst(u8 *base, msg_t *msg); +void RGA_set_alpha_rop(u8 *base, msg_t *msg); +void RGA_set_color(u8 *base, msg_t *msg); +s32 RGA_set_fading(u8 *base, msg_t *msg); +s32 RGA_set_pat(u8 *base, msg_t *msg); +void RGA_set_bitblt_reg_info(u8 *base, msg_t * msg, TILE_INFO *tile); +void RGA_set_color_palette_reg_info(u8 *base, msg_t *msg); +void RGA_set_color_fill_reg_info(u8 *base, msg_t *msg); +s32 RGA_set_line_drawing_reg_info(u8 *base, msg_t *msg); +s32 RGA_set_filter_reg_info(u8 *base, msg_t *msg); +s32 RGA_set_pre_scale_reg_info(u8 *base, msg_t *msg); +s32 RGA_set_update_palette_table_reg_info(u8 *base, msg_t *msg); +s32 RGA_set_update_patten_buff_reg_info(u8 *base, msg_t *msg); +s32 RGA_set_mmu_ctrl_reg_info(u8 *base, msg_t *msg); +*/ diff --git a/drivers/video/rockchip/rga/rga_rop.h b/drivers/video/rockchip/rga/rga_rop.h new file mode 100644 index 000000000000..c4be6352cc0f --- /dev/null +++ b/drivers/video/rockchip/rga/rga_rop.h @@ -0,0 +1,57 @@ +#ifndef __RGA_ROP_H__ +#define __RGA_ROP_H__ + +#include "rga_type.h" + +UWORD32 ROP3_code[256] = +{ + 0x00000007, 0x00000451, 0x00006051, 0x00800051, 0x00007041, 0x00800041, 0x00804830, 0x000004f0,//0 + 0x00800765, 0x000004b0, 0x00000065, 0x000004f4, 0x00000075, 0x000004e6, 0x00804850, 0x00800005, + + 0x00006850, 0x00800050, 0x00805028, 0x00000568, 0x00804031, 0x00000471, 0x002b6071, 0x018037aa,//1 + 0x008007aa, 0x00036071, 0x00002c6a, 0x00803631, 0x00002d68, 0x00802721, 0x008002d0, 0x000006d0, + + 0x0080066e, 0x00000528, 0x00000066, 0x0000056c, 0x018007aa, 0x0002e06a, 0x00003471, 0x00834031,//2 + 0x00800631, 0x0002b471, 0x00006071, 0x008037aa, 0x000036d0, 0x008002d4, 0x00002d28, 0x000006d4, + + 0x0000006e, 0x00000565, 0x00003451, 0x00800006, 0x000034f0, 0x00834830, 0x00800348, 0x00000748,//3 + 0x00002f48, 0x0080034c, 0x000034b0, 0x0000074c, 0x00000031, 0x00834850, 0x000034e6, 0x00800071, + + 0x008006f4, 0x00000431, 0x018007a1, 0x00b6e870, 0x00000074, 0x0000046e, 0x00002561, 0x00802f28,//4 + 0x00800728, 0x0002a561, 0x000026c2, 0x008002c6, 0x00007068, 0x018035aa, 0x00002c2a, 0x000006c6, + + 0x0000006c, 0x00000475, 0x000024e2, 0x008036b0, 0x00804051, 0x00800004, 0x00800251, 0x00000651, + 0x00002e4a, 0x0080024e, 0x00000028, 0x00824842, 0x000024a2, 0x0000064e, 0x000024f4, 0x00800068,//5 + + 0x008006b0, 0x000234f0, 0x00002741, 0x00800345, 0x00003651, 0x00800255, 0x00000030, 0x00834051, + 0x00a34842, 0x000002b0, 0x00800271, 0x0002b651, 0x00800368, 0x0002a741, 0x0000364e, 0x00806830,//6 + + 0x00006870, 0x008037a2, 0x00003431, 0x00000745, 0x00002521, 0x00000655, 0x0000346e, 0x00800062, + 0x008002f0, 0x000236d0, 0x000026d4, 0x00807028, 0x000036c6, 0x00806031, 0x008005aa, 0x00000671,//7 + + 0x00800671, 0x000005aa, 0x00006031, 0x008036c6, 0x00007028, 0x00802e55, 0x008236d0, 0x000002f0, + 0x00000070, 0x0080346e, 0x00800655, 0x00802521, 0x00800745, 0x00803431, 0x000037a2, 0x00806870,//8 + + 0x00006830, 0x0080364e, 0x00822f48, 0x00000361, 0x0082b651, 0x00000271, 0x00800231, 0x002b4051, + 0x00034051, 0x00800030, 0x0080026e, 0x00803651, 0x0080036c, 0x00802741, 0x008234f0, 0x000006b0,//9 + + 0x00000068, 0x00802c75, 0x0080064e, 0x008024a2, 0x0002c04a, 0x00800021, 0x00800275, 0x00802e51, + 0x00800651, 0x00000251, 0x00800000, 0x00004051, 0x000036b0, 0x008024e2, 0x00800475, 0x00000045,//a + + 0x008006c6, 0x00802c2a, 0x000035aa, 0x00807068, 0x008002f4, 0x008026c2, 0x00822d68, 0x00000728, + 0x00002f28, 0x00802561, 0x0080046e, 0x00000046, 0x00836870, 0x000007a2, 0x00800431, 0x00004071,//b + + 0x00000071, 0x008034e6, 0x00034850, 0x00800031, 0x0080074c, 0x008034b0, 0x00800365, 0x00802f48, + 0x00800748, 0x00000341, 0x000026a2, 0x008034f0, 0x00800002, 0x00005048, 0x00800565, 0x00000055,//c + + 0x008006d4, 0x00802d28, 0x008002e6, 0x008036d0, 0x000037aa, 0x00806071, 0x0082b471, 0x00000631, + 0x00002e2a, 0x00803471, 0x00826862, 0x010007aa, 0x0080056c, 0x00000054, 0x00800528, 0x00005068,//d + + 0x008006d0, 0x000002d0, 0x00002721, 0x00802d68, 0x00003631, 0x00802c6a, 0x00836071, 0x000007aa, + 0x010037aa, 0x00a36870, 0x00800471, 0x00004031, 0x00800568, 0x00005028, 0x00000050, 0x00800545,//e + + 0x00800001, 0x00004850, 0x008004e6, 0x0000004e, 0x008004f4, 0x0000004c, 0x008004b0, 0x00004870, + 0x008004f0, 0x00004830, 0x00000048, 0x0080044e, 0x00000051, 0x008004d4, 0x00800451, 0x00800007,//f +}; + +#endif diff --git a/drivers/video/rockchip/rga/rga_type.h b/drivers/video/rockchip/rga/rga_type.h new file mode 100644 index 000000000000..38a872034da1 --- /dev/null +++ b/drivers/video/rockchip/rga/rga_type.h @@ -0,0 +1,48 @@ +#ifndef __RGA_TYPE_H__ +#define __RGA_TYPE_H__ + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +typedef unsigned int UWORD32; +typedef unsigned int uint32; +typedef unsigned int RK_U32; + +typedef unsigned short UWORD16; +typedef unsigned short RK_U16; + +typedef unsigned char UBYTE; +typedef unsigned char RK_U8; + +typedef int WORD32; +typedef int RK_S32; + +typedef short WORD16; +typedef short RK_S16; + +typedef char BYTE; +typedef char RK_S8; + + +#ifndef NULL +#define NULL 0L +#endif + +#ifndef TRUE +#define TRUE 1L +#endif + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + + +#endif /* __RGA_TYPR_H__ */ +