From c7123b711276fef1b5a98f41da5ee3558c3dcba8 Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Fri, 4 Mar 2022 18:26:57 +0800 Subject: [PATCH] video: rockchip: rga3: Fix 1106 RGA2 CSC output exception Default configuration Y_clip[0,255] UV_clip[0,255]. Signed-off-by: Yu Qiaowei Change-Id: I2134fa5fc179a6e86d73b11a632236b6859cc056 --- drivers/video/rockchip/rga3/include/rga.h | 20 +-- .../rockchip/rga3/include/rga2_reg_info.h | 36 +++-- drivers/video/rockchip/rga3/include/rga_drv.h | 2 +- drivers/video/rockchip/rga3/rga2_reg_info.c | 128 ++++++------------ 4 files changed, 68 insertions(+), 118 deletions(-) diff --git a/drivers/video/rockchip/rga3/include/rga.h b/drivers/video/rockchip/rga3/include/rga.h index ca027d14aaea..fefab4e7cb9e 100644 --- a/drivers/video/rockchip/rga3/include/rga.h +++ b/drivers/video/rockchip/rga3/include/rga.h @@ -294,18 +294,18 @@ struct rga_line_draw_t { }; /* color space convert coefficient. */ -struct rga_csc_coe_t { +struct rga_csc_coe { int16_t r_v; int16_t g_y; int16_t b_u; int32_t off; }; -struct rga_full_csc_t { +struct rga_full_csc { uint8_t flag; - struct rga_csc_coe_t coe_y; - struct rga_csc_coe_t coe_u; - struct rga_csc_coe_t coe_v; + struct rga_csc_coe coe_y; + struct rga_csc_coe coe_u; + struct rga_csc_coe coe_v; }; struct rga_mosaic_info { @@ -583,7 +583,7 @@ struct rga_req { uint8_t dither_mode; /* full color space convert */ - struct rga_full_csc_t full_csc; + struct rga_full_csc full_csc; int32_t in_fence_fd; uint8_t core; @@ -710,13 +710,7 @@ struct rga2_req { /* (enum) BT.601 MPEG / BT.601 JPEG / BT.709 */ u8 yuv2rgb_mode; - /* [1:0] src0 csc mode */ - /* [3:2] dst csc mode */ - /* [4] dst csc clip enable */ - /* [6:5] src1 csc mdoe */ - /* [7] src1 csc clip enable */ - /* full color space convert */ - struct rga_full_csc_t full_csc; + u8 full_csc_en; /* 0/little endian 1/big endian */ u8 endian_mode; diff --git a/drivers/video/rockchip/rga3/include/rga2_reg_info.h b/drivers/video/rockchip/rga3/include/rga2_reg_info.h index aa6aa640da5f..55618faeeb0d 100644 --- a/drivers/video/rockchip/rga3/include/rga2_reg_info.h +++ b/drivers/video/rockchip/rga3/include/rga2_reg_info.h @@ -14,9 +14,6 @@ #define RGA2_MMU_CMD_BASE 0x01c #define RGA2_VERSION_NUM 0x028 -/* Full Csc Coefficient */ -#define RGA2_CSC_COE_BASE 0x60 - #define rRGA_SYS_CTRL (*(volatile u32 *)(RGA2_BASE + RGA2_SYS_CTRL_OFFSET)) #define rRGA_CMD_CTRL (*(volatile u32 *)(RGA2_BASE + RGA2_CMD_CTRL_OFFSET)) #define rRGA_CMD_BASE (*(volatile u32 *)(RGA2_BASE + RGA2_CMD_BASE_OFFSET)) @@ -338,23 +335,21 @@ #define RGA2_WRITE_LINE_CNT_OFFSET 0x34 #define RGA2_LINE_CNT_OFFSET 0x38 #define RGA2_PERF_CTRL0_OFFSET 0x40 +#define RGA2_DST_CSC_00_OFFSET 0x60 +#define RGA2_DST_CSC_01_OFFSET 0x64 +#define RGA2_DST_CSC_02_OFFSET 0x68 +#define RGA2_DST_CSC_OFF0_OFFSET 0x6c +#define RGA2_DST_CSC_10_OFFSET 0x70 +#define RGA2_DST_CSC_11_OFFSET 0x74 +#define RGA2_DST_CSC_12_OFFSET 0x78 +#define RGA2_DST_CSC_OFF1_OFFSET 0x7c +#define RGA2_DST_CSC_20_OFFSET 0x80 +#define RGA2_DST_CSC_21_OFFSET 0x84 +#define RGA2_DST_CSC_22_OFFSET 0x88 +#define RGA2_DST_CSC_OFF2_OFFSET 0x8c #define RGA2_OSD_CUR_FLAGS0_OFFSET 0x90 #define RGA2_OSD_CUR_FLAGS1_OFFSET 0x9c -/* dst full csc */ -#define RGA2_DST_CSC_00_OFFSET 0x0 -#define RGA2_DST_CSC_01_OFFSET 0x4 -#define RGA2_DST_CSC_02_OFFSET 0x8 -#define RGA2_DST_CSC_OFF0_OFFSET 0xc -#define RGA2_DST_CSC_10_OFFSET 0x10 -#define RGA2_DST_CSC_11_OFFSET 0x14 -#define RGA2_DST_CSC_12_OFFSET 0x18 -#define RGA2_DST_CSC_OFF1_OFFSET 0x1c -#define RGA2_DST_CSC_20_OFFSET 0x20 -#define RGA2_DST_CSC_21_OFFSET 0x24 -#define RGA2_DST_CSC_22_OFFSET 0x28 -#define RGA2_DST_CSC_OFF2_OFFSET 0x2c - /* mode ctrl */ #define RGA2_MODE_CTRL_OFFSET 0x00 #define RGA2_SRC_INFO_OFFSET 0x04 @@ -406,8 +401,11 @@ #define RGA2_MMU_DST_BASE_OFFSET 0x78 #define RGA2_MMU_ELS_BASE_OFFSET 0x7c -int rga2_gen_reg_info(unsigned char *base, - unsigned char *csc_base, struct rga2_req *msg); +#define RGA2_SYS_REG_BASE 0x0 +#define RGA2_CSC_REG_BASE 0x60 +#define RGA2_CMD_REG_BASE 0x100 + +int rga2_gen_reg_info(unsigned char *base, struct rga2_req *msg); void rga2_soft_reset(struct rga_scheduler_t *scheduler); int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler); diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h index b78c76e97a04..5f95d05628eb 100644 --- a/drivers/video/rockchip/rga3/include/rga_drv.h +++ b/drivers/video/rockchip/rga3/include/rga_drv.h @@ -256,7 +256,7 @@ struct rga_job { struct list_head head; struct rga_req rga_command_base; uint32_t cmd_reg[32 * 8]; - uint32_t csc_reg[12]; + struct rga_full_csc full_csc; struct rga_pre_intr_info pre_intr_info; struct rga_dma_buffer_t *rga_dma_buffer_src0; diff --git a/drivers/video/rockchip/rga3/rga2_reg_info.c b/drivers/video/rockchip/rga3/rga2_reg_info.c index b07d27d64a2f..d1c95d714377 100644 --- a/drivers/video/rockchip/rga3/rga2_reg_info.c +++ b/drivers/video/rockchip/rga3/rga2_reg_info.c @@ -1047,7 +1047,7 @@ static void RGA2_set_reg_dst_info(u8 *base, struct rga2_req *msg) /* full csc enable */ reg = ((reg & (~m_RGA2_DST_INFO_SW_DST_CSC_MODE_2)) | - (s_RGA2_DST_INFO_SW_DST_CSC_MODE_2(msg->full_csc.flag))); + (s_RGA2_DST_INFO_SW_DST_CSC_MODE_2(msg->full_csc_en))); /* * Some older chips do not support src1 csc mode, * they do not have these two registers. @@ -1509,56 +1509,6 @@ static void RGA2_set_reg_osd(u8 *base, struct rga2_req *msg) } } -static void RGA2_set_reg_full_csc(u8 *base, struct rga2_req *msg) -{ - u32 *bRGA2_DST_CSC_00; - u32 *bRGA2_DST_CSC_01; - u32 *bRGA2_DST_CSC_02; - u32 *bRGA2_DST_CSC_OFF0; - - u32 *bRGA2_DST_CSC_10; - u32 *bRGA2_DST_CSC_11; - u32 *bRGA2_DST_CSC_12; - u32 *bRGA2_DST_CSC_OFF1; - - u32 *bRGA2_DST_CSC_20; - u32 *bRGA2_DST_CSC_21; - u32 *bRGA2_DST_CSC_22; - u32 *bRGA2_DST_CSC_OFF2; - - bRGA2_DST_CSC_00 = (u32 *) (base + RGA2_DST_CSC_00_OFFSET); - bRGA2_DST_CSC_01 = (u32 *) (base + RGA2_DST_CSC_01_OFFSET); - bRGA2_DST_CSC_02 = (u32 *) (base + RGA2_DST_CSC_02_OFFSET); - bRGA2_DST_CSC_OFF0 = (u32 *) (base + RGA2_DST_CSC_OFF0_OFFSET); - - bRGA2_DST_CSC_10 = (u32 *) (base + RGA2_DST_CSC_10_OFFSET); - bRGA2_DST_CSC_11 = (u32 *) (base + RGA2_DST_CSC_11_OFFSET); - bRGA2_DST_CSC_12 = (u32 *) (base + RGA2_DST_CSC_12_OFFSET); - bRGA2_DST_CSC_OFF1 = (u32 *) (base + RGA2_DST_CSC_OFF1_OFFSET); - - bRGA2_DST_CSC_20 = (u32 *) (base + RGA2_DST_CSC_20_OFFSET); - bRGA2_DST_CSC_21 = (u32 *) (base + RGA2_DST_CSC_21_OFFSET); - bRGA2_DST_CSC_22 = (u32 *) (base + RGA2_DST_CSC_22_OFFSET); - bRGA2_DST_CSC_OFF2 = (u32 *) (base + RGA2_DST_CSC_OFF2_OFFSET); - - /* full csc coefficient */ - /* Y coefficient */ - *bRGA2_DST_CSC_00 = msg->full_csc.coe_y.r_v; - *bRGA2_DST_CSC_01 = msg->full_csc.coe_y.g_y; - *bRGA2_DST_CSC_02 = msg->full_csc.coe_y.b_u; - *bRGA2_DST_CSC_OFF0 = msg->full_csc.coe_y.off; - /* U coefficient */ - *bRGA2_DST_CSC_10 = msg->full_csc.coe_u.r_v; - *bRGA2_DST_CSC_11 = msg->full_csc.coe_u.g_y; - *bRGA2_DST_CSC_12 = msg->full_csc.coe_u.b_u; - *bRGA2_DST_CSC_OFF1 = msg->full_csc.coe_u.off; - /* V coefficient */ - *bRGA2_DST_CSC_20 = msg->full_csc.coe_v.r_v; - *bRGA2_DST_CSC_21 = msg->full_csc.coe_v.g_y; - *bRGA2_DST_CSC_22 = msg->full_csc.coe_v.b_u; - *bRGA2_DST_CSC_OFF2 = msg->full_csc.coe_v.off; -} - static void RGA2_set_reg_color_palette(u8 *base, struct rga2_req *msg) { u32 *bRGA_SRC_BASE0, *bRGA_SRC_INFO, *bRGA_SRC_VIR_INFO, @@ -1758,7 +1708,7 @@ static void RGA2_set_mmu_reg_info(u8 *base, struct rga2_req *msg) *bRGA_MMU_ELS_BASE = (u32) (msg->mmu_info.els_base_addr) >> 4; } -int rga2_gen_reg_info(u8 *base, u8 *csc_base, struct rga2_req *msg) +int rga2_gen_reg_info(u8 *base, struct rga2_req *msg) { u8 dst_nn_quantize_en = 0; @@ -1777,9 +1727,6 @@ int rga2_gen_reg_info(u8 *base, u8 *csc_base, struct rga2_req *msg) RGA2_set_reg_alpha_info(base, msg); RGA2_set_reg_rop_info(base, msg); } - - if (msg->full_csc.flag) - RGA2_set_reg_full_csc(csc_base, msg); } if (msg->mosaic_info.enable) RGA_set_reg_mosaic(base, msg); @@ -1916,7 +1863,6 @@ static void rga_cmd_to_rga2_cmd(struct rga_scheduler_t *scheduler, req->fg_color = req_rga->fg_color; req->bg_color = req_rga->bg_color; memcpy(&req->gr_color, &req_rga->gr_color, sizeof(req_rga->gr_color)); - memcpy(&req->full_csc, &req_rga->full_csc, sizeof(req_rga->full_csc)); req->palette_mode = req_rga->palette_mode; req->yuv2rgb_mode = req_rga->yuv2rgb_mode; @@ -2271,6 +2217,7 @@ int rga2_init_reg(struct rga_job *job) memset(&req, 0x0, sizeof(req)); rga_cmd_to_rga2_cmd(scheduler, &job->rga_command_base, &req); + memcpy(&job->full_csc, &job->rga_command_base.full_csc, sizeof(job->full_csc)); memcpy(&job->pre_intr_info, &job->rga_command_base.pre_intr_info, sizeof(job->pre_intr_info)); @@ -2310,8 +2257,7 @@ int rga2_init_reg(struct rga_job *job) mutex_unlock(&rga_drvdata->lock); - if (rga2_gen_reg_info((uint8_t *)job->cmd_reg, - (uint8_t *)job->csc_reg, &req) == -1) { + if (rga2_gen_reg_info((uint8_t *)job->cmd_reg, &req) == -1) { pr_err("gen reg info error\n"); return -EINVAL; } @@ -2331,29 +2277,20 @@ static void rga2_dump_read_back_reg(struct rga_scheduler_t *scheduler) int i; unsigned long flags; uint32_t cmd_reg[32] = {0}; - uint32_t csc_reg[12] = {0}; spin_lock_irqsave(&scheduler->irq_lock, flags); for (i = 0; i < 32; i++) - cmd_reg[i] = rga_read(0x100 + i * 4, scheduler); - - for (i = 0; i < 12; i++) - csc_reg[i] = rga_read(RGA2_CSC_COE_BASE + i * 4, scheduler); + cmd_reg[i] = rga_read(RGA2_CMD_REG_BASE + i * 4, scheduler); spin_unlock_irqrestore(&scheduler->irq_lock, flags); pr_info("CMD_READ_BACK_REG\n"); for (i = 0; i < 8; i++) - pr_info("i = %x : %.8x %.8x %.8x %.8x\n", i, + pr_info("0x%04x : %.8x %.8x %.8x %.8x\n", + RGA2_CMD_REG_BASE + i * 0x10, cmd_reg[0 + i * 4], cmd_reg[1 + i * 4], cmd_reg[2 + i * 4], cmd_reg[3 + i * 4]); - - pr_info("CSC_READ_BACK_REG\n"); - for (i = 0; i < 3; i++) - pr_info("%.8x %.8x %.8x %.8x\n", - csc_reg[0 + i * 4], csc_reg[1 + i * 4], - csc_reg[2 + i * 4], csc_reg[3 + i * 4]); } static void rga2_set_pre_intr_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) @@ -2386,6 +2323,38 @@ static void rga2_set_pre_intr_reg(struct rga_job *job, struct rga_scheduler_t *s rga_write(reg, RGA2_INT_OFFSET, scheduler); } +static void rga2_set_reg_full_csc(struct rga_job *job, struct rga_scheduler_t *scheduler) +{ + uint8_t clip_y_max, clip_y_min; + uint8_t clip_uv_max, clip_uv_min; + + clip_y_max = 0xff; + clip_y_min = 0x0; + clip_uv_max = 0xff; + clip_uv_min = 0; + + /* full csc coefficient */ + /* Y coefficient */ + rga_write(job->full_csc.coe_y.r_v | (clip_y_max << 16) | (clip_y_min << 24), + RGA2_DST_CSC_00_OFFSET, scheduler); + rga_write(job->full_csc.coe_y.g_y | (clip_uv_max << 16) | (clip_uv_min << 24), + RGA2_DST_CSC_01_OFFSET, scheduler); + rga_write(job->full_csc.coe_y.b_u, RGA2_DST_CSC_02_OFFSET, scheduler); + rga_write(job->full_csc.coe_y.off, RGA2_DST_CSC_OFF0_OFFSET, scheduler); + + /* U coefficient */ + rga_write(job->full_csc.coe_u.r_v, RGA2_DST_CSC_10_OFFSET, scheduler); + rga_write(job->full_csc.coe_u.g_y, RGA2_DST_CSC_11_OFFSET, scheduler); + rga_write(job->full_csc.coe_u.b_u, RGA2_DST_CSC_12_OFFSET, scheduler); + rga_write(job->full_csc.coe_u.off, RGA2_DST_CSC_OFF1_OFFSET, scheduler); + + /* V coefficient */ + rga_write(job->full_csc.coe_v.r_v, RGA2_DST_CSC_20_OFFSET, scheduler); + rga_write(job->full_csc.coe_v.g_y, RGA2_DST_CSC_21_OFFSET, scheduler); + rga_write(job->full_csc.coe_v.b_u, RGA2_DST_CSC_22_OFFSET, scheduler); + rga_write(job->full_csc.coe_v.off, RGA2_DST_CSC_OFF2_OFFSET, scheduler); +} + int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) { ktime_t now = ktime_get(); @@ -2412,15 +2381,11 @@ int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) #endif - /* full csc reg */ - for (i = 0; i < 12; i++) { - rga_write(job->csc_reg[i], RGA2_CSC_COE_BASE + i * 4, - scheduler); - } - - if (job->pre_intr_info.enable) { + if (job->pre_intr_info.enable) rga2_set_pre_intr_reg(job, scheduler); - } + + if (job->full_csc.flag) + rga2_set_reg_full_csc(job, scheduler); if (DEBUGGER_EN(REG)) { int32_t *p; @@ -2431,13 +2396,6 @@ int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) pr_info("i = %x : %.8x %.8x %.8x %.8x\n", i, p[0 + i * 4], p[1 + i * 4], p[2 + i * 4], p[3 + i * 4]); - - p = job->csc_reg; - pr_info("CSC_REG\n"); - for (i = 0; i < 3; i++) - pr_info("%.8x %.8x %.8x %.8x\n", - p[0 + i * 4], p[1 + i * 4], - p[2 + i * 4], p[3 + i * 4]); } #ifndef CONFIG_ROCKCHIP_FPGA