mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
video: rockchip: rga3: Fix 1106 RGA2 CSC output exception
Default configuration Y_clip[0,255] UV_clip[0,255]. Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com> Change-Id: I2134fa5fc179a6e86d73b11a632236b6859cc056
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user