mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
video/rockchip: rga2: Add support for full csc (RGB2YUV/YUV2YUV).
Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com> Change-Id: I72fcbc85a5bc24357d64579dd56b8a20715e59bc
This commit is contained in:
@@ -284,6 +284,21 @@ typedef struct line_draw_t
|
||||
}
|
||||
line_draw_t;
|
||||
|
||||
/* color space convert coefficient. */
|
||||
typedef struct csc_coe_t {
|
||||
int16_t r_v;
|
||||
int16_t g_y;
|
||||
int16_t b_u;
|
||||
int32_t off;
|
||||
} csc_coe_t;
|
||||
|
||||
typedef struct full_csc_t {
|
||||
unsigned char flag;
|
||||
csc_coe_t coe_y;
|
||||
csc_coe_t coe_u;
|
||||
csc_coe_t coe_v;
|
||||
} full_csc_t;
|
||||
|
||||
typedef struct rga_img_info_t
|
||||
{
|
||||
unsigned long yrgb_addr; /* yrgb mem addr */
|
||||
@@ -394,6 +409,8 @@ struct rga_req {
|
||||
uint8_t src_trans_mode;
|
||||
|
||||
uint8_t dither_mode;
|
||||
|
||||
full_csc_t full_csc; /* full color space convert */
|
||||
};
|
||||
struct rga_req_32
|
||||
{
|
||||
@@ -446,6 +463,8 @@ struct rga_req_32
|
||||
uint8_t src_trans_mode;
|
||||
|
||||
uint8_t dither_mode;
|
||||
|
||||
full_csc_t full_csc; /* full color space convert */
|
||||
};
|
||||
|
||||
|
||||
@@ -530,13 +549,18 @@ struct rga2_req
|
||||
u8 src_a_global_val; /* src global alpha value */
|
||||
u8 dst_a_global_val; /* dst global alpha value */
|
||||
|
||||
|
||||
u8 rop_mode; /* rop mode select 0 : rop2 1 : rop3 2 : rop4 */
|
||||
u16 rop_code; /* rop2/3/4 code */
|
||||
|
||||
u8 palette_mode; /* (enum) color palatte 0/1bpp, 1/2bpp 2/4bpp 3/8bpp*/
|
||||
|
||||
u8 yuv2rgb_mode; /* (enum) BT.601 MPEG / BT.601 JPEG / BT.709 */
|
||||
/* [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_csc_t full_csc; /* full color space convert */
|
||||
|
||||
u8 endian_mode; /* 0/little endian 1/big endian */
|
||||
|
||||
@@ -688,6 +712,7 @@ struct rga2_reg {
|
||||
struct list_head session_link;
|
||||
struct list_head status_link;
|
||||
uint32_t sys_reg[8];
|
||||
uint32_t csc_reg[12];
|
||||
uint32_t cmd_reg[32];
|
||||
|
||||
uint32_t *MMU_src0_base;
|
||||
@@ -749,6 +774,9 @@ struct rga2_service_info {
|
||||
#define RGA2_MMU_CTRL0 0x018
|
||||
#define RGA2_MMU_CMD_BASE 0x01c
|
||||
|
||||
//Full Csc Coefficient
|
||||
#define RGA2_CSC_COE_BASE 0x60
|
||||
|
||||
//Command code start
|
||||
#define RGA2_MODE_CTRL 0x100
|
||||
#define RGA_BLIT_COMPLETE_EVENT 1
|
||||
|
||||
@@ -871,7 +871,7 @@ static struct rga2_reg * rga2_reg_init(rga2_session *session, struct rga2_req *r
|
||||
}
|
||||
}
|
||||
|
||||
if(RGA2_gen_reg_info((uint8_t *)reg->cmd_reg, req) == -1) {
|
||||
if (RGA2_gen_reg_info((uint8_t *)reg->cmd_reg, (uint8_t *)reg->csc_reg, req) == -1) {
|
||||
printk("gen reg info error\n");
|
||||
free_page((unsigned long)reg);
|
||||
|
||||
@@ -934,6 +934,7 @@ static void rga2_service_session_clear(rga2_session *session)
|
||||
/* Caller must hold rga_service.lock */
|
||||
static void rga2_try_set_reg(void)
|
||||
{
|
||||
int i;
|
||||
struct rga2_reg *reg ;
|
||||
|
||||
if (list_empty(&rga2_service.running))
|
||||
@@ -958,16 +959,29 @@ static void rga2_try_set_reg(void)
|
||||
/* CMD buff */
|
||||
rga2_write(virt_to_phys(reg->cmd_reg), RGA2_CMD_BASE);
|
||||
|
||||
/* full csc reg */
|
||||
for (i = 0; i < 12; i++) {
|
||||
rga2_write(reg->csc_reg[i], RGA2_CSC_COE_BASE + i * 4);
|
||||
}
|
||||
|
||||
#if RGA2_DEBUGFS
|
||||
if (RGA2_TEST_REG) {
|
||||
if (rga2_flag) {
|
||||
int32_t i, *p;
|
||||
int32_t *p;
|
||||
|
||||
p = rga2_service.cmd_buff;
|
||||
INFO("CMD_REG\n");
|
||||
for (i=0; i<8; i++)
|
||||
INFO("%.8x %.8x %.8x %.8x\n",
|
||||
p[0 + i * 4], p[1 + i * 4],
|
||||
p[2 + i * 4], p[3 + i * 4]);
|
||||
|
||||
p = reg->csc_reg;
|
||||
INFO("CSC_REG\n");
|
||||
for (i = 0; i < 3; i++)
|
||||
INFO("%.8x %.8x %.8x %.8x\n",
|
||||
p[0 + i * 4], p[1 + i * 4],
|
||||
p[2 + i * 4], p[3 + i * 4]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -989,7 +1003,6 @@ static void rga2_try_set_reg(void)
|
||||
#if RGA2_DEBUGFS
|
||||
if (RGA2_TEST_REG) {
|
||||
if (rga2_flag) {
|
||||
uint32_t i;
|
||||
INFO("CMD_READ_BACK_REG\n");
|
||||
for (i=0; i<8; i++)
|
||||
INFO("%.8x %.8x %.8x %.8x\n",
|
||||
@@ -997,6 +1010,14 @@ static void rga2_try_set_reg(void)
|
||||
rga2_read(0x100 + i * 16 + 4),
|
||||
rga2_read(0x100 + i * 16 + 8),
|
||||
rga2_read(0x100 + i * 16 + 12));
|
||||
|
||||
INFO("CSC_READ_BACK_REG\n");
|
||||
for (i = 0; i < 3; i++)
|
||||
INFO("%.8x %.8x %.8x %.8x\n",
|
||||
rga2_read(RGA2_CSC_COE_BASE + i * 16 + 0),
|
||||
rga2_read(RGA2_CSC_COE_BASE + i * 16 + 4),
|
||||
rga2_read(RGA2_CSC_COE_BASE + i * 16 + 8),
|
||||
rga2_read(RGA2_CSC_COE_BASE + i * 16 + 12));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -476,6 +476,8 @@ static void RGA2_set_reg_dst_info(u8 *base, struct rga2_req *msg)
|
||||
reg = ((reg & (~m_RGA2_DST_INFO_SW_DITHER_MODE)) | (s_RGA2_DST_INFO_SW_DITHER_MODE(msg->dither_mode)));
|
||||
reg = ((reg & (~m_RGA2_DST_INFO_SW_DST_CSC_MODE)) | (s_RGA2_DST_INFO_SW_DST_CSC_MODE(msg->yuv2rgb_mode >> 2)));
|
||||
reg = ((reg & (~m_RGA2_DST_INFO_SW_CSC_CLIP_MODE)) | (s_RGA2_DST_INFO_SW_CSC_CLIP_MODE(msg->yuv2rgb_mode >> 4)));
|
||||
/* 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)));
|
||||
/* Some older chips do not support src1 csc mode, they do not have these two registers. */
|
||||
reg = ((reg & (~m_RGA2_DST_INFO_SW_SRC1_CSC_MODE)) | (s_RGA2_DST_INFO_SW_SRC1_CSC_MODE(msg->yuv2rgb_mode >> 5)));
|
||||
reg = ((reg & (~m_RGA2_DST_INFO_SW_SRC1_CSC_CLIP_MODE)) | (s_RGA2_DST_INFO_SW_SRC1_CSC_CLIP_MODE(msg->yuv2rgb_mode >> 7)));
|
||||
@@ -790,6 +792,56 @@ static void RGA2_set_reg_rop_info(u8 *base, struct rga2_req *msg)
|
||||
|
||||
}
|
||||
|
||||
static void RGA2_set_reg_full_csc(u8 *base, struct rga2_req *msg)
|
||||
{
|
||||
RK_U32 *bRGA2_DST_CSC_00;
|
||||
RK_U32 *bRGA2_DST_CSC_01;
|
||||
RK_U32 *bRGA2_DST_CSC_02;
|
||||
RK_U32 *bRGA2_DST_CSC_OFF0;
|
||||
|
||||
RK_U32 *bRGA2_DST_CSC_10;
|
||||
RK_U32 *bRGA2_DST_CSC_11;
|
||||
RK_U32 *bRGA2_DST_CSC_12;
|
||||
RK_U32 *bRGA2_DST_CSC_OFF1;
|
||||
|
||||
RK_U32 *bRGA2_DST_CSC_20;
|
||||
RK_U32 *bRGA2_DST_CSC_21;
|
||||
RK_U32 *bRGA2_DST_CSC_22;
|
||||
RK_U32 *bRGA2_DST_CSC_OFF2;
|
||||
|
||||
bRGA2_DST_CSC_00 = (RK_U32 *)(base + RGA2_DST_CSC_00_OFFSET);
|
||||
bRGA2_DST_CSC_01 = (RK_U32 *)(base + RGA2_DST_CSC_01_OFFSET);
|
||||
bRGA2_DST_CSC_02 = (RK_U32 *)(base + RGA2_DST_CSC_02_OFFSET);
|
||||
bRGA2_DST_CSC_OFF0 = (RK_U32 *)(base + RGA2_DST_CSC_OFF0_OFFSET);
|
||||
|
||||
bRGA2_DST_CSC_10 = (RK_U32 *)(base + RGA2_DST_CSC_10_OFFSET);
|
||||
bRGA2_DST_CSC_11 = (RK_U32 *)(base + RGA2_DST_CSC_11_OFFSET);
|
||||
bRGA2_DST_CSC_12 = (RK_U32 *)(base + RGA2_DST_CSC_12_OFFSET);
|
||||
bRGA2_DST_CSC_OFF1 = (RK_U32 *)(base + RGA2_DST_CSC_OFF1_OFFSET);
|
||||
|
||||
bRGA2_DST_CSC_20 = (RK_U32 *)(base + RGA2_DST_CSC_20_OFFSET);
|
||||
bRGA2_DST_CSC_21 = (RK_U32 *)(base + RGA2_DST_CSC_21_OFFSET);
|
||||
bRGA2_DST_CSC_22 = (RK_U32 *)(base + RGA2_DST_CSC_22_OFFSET);
|
||||
bRGA2_DST_CSC_OFF2 = (RK_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(RK_U8 *base, struct rga2_req *msg)
|
||||
{
|
||||
RK_U32 *bRGA_SRC_BASE0, *bRGA_SRC_INFO, *bRGA_SRC_VIR_INFO, *bRGA_SRC_ACT_INFO, *bRGA_SRC_FG_COLOR, *bRGA_SRC_BG_COLOR;
|
||||
@@ -989,9 +1041,8 @@ static void RGA2_set_mmu_info(RK_U8 *base, struct rga2_req *msg)
|
||||
*bRGA_MMU_ELS_BASE = (RK_U32)(msg->mmu_info.els_base_addr) >> 4;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
RGA2_gen_reg_info(RK_U8 *base , struct rga2_req *msg)
|
||||
RGA2_gen_reg_info(RK_U8 *base, RK_U8 *csc_base, struct rga2_req *msg)
|
||||
{
|
||||
RK_U8 dst_nn_quantize_en = 0;
|
||||
|
||||
@@ -1011,6 +1062,10 @@ RGA2_gen_reg_info(RK_U8 *base , struct rga2_req *msg)
|
||||
RGA2_set_reg_rop_info(base, msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (msg->full_csc.flag) {
|
||||
RGA2_set_reg_full_csc(csc_base, msg);
|
||||
}
|
||||
break;
|
||||
case color_fill_mode :
|
||||
RGA2_set_reg_color_fill(base, msg);
|
||||
@@ -1195,6 +1250,7 @@ void RGA_MSG_2_RGA2_MSG(struct rga_req *req_rga, struct rga2_req *req)
|
||||
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;
|
||||
@@ -1455,6 +1511,8 @@ void RGA_MSG_2_RGA2_MSG_32(struct rga_req_32 *req_rga, struct rga2_req *req)
|
||||
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;
|
||||
req->endian_mode = req_rga->endian_mode;
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
#define m_RGA2_DST_INFO_SW_DITHER_MODE ( 0x3<<14)
|
||||
#define m_RGA2_DST_INFO_SW_DST_CSC_MODE ( 0x3<<16) //add
|
||||
#define m_RGA2_DST_INFO_SW_CSC_CLIP_MODE ( 0x1<<18)
|
||||
#define m_RGA2_DST_INFO_SW_DST_CSC_MODE_2 ( 0x1<<19) //add
|
||||
#define m_RGA2_DST_INFO_SW_DST_FMT_YUV400_EN ( 0x1<<24)
|
||||
#define m_RGA2_DST_INFO_SW_DST_FMT_Y4_EN ( 0x1<<25)
|
||||
#define m_RGA2_DST_INFO_SW_DST_NN_QUANTIZE_EN ( 0x1<<26)
|
||||
@@ -160,6 +161,7 @@
|
||||
#define s_RGA2_DST_INFO_SW_DITHER_MODE(x) ( (x&0x3)<<14)
|
||||
#define s_RGA2_DST_INFO_SW_DST_CSC_MODE(x) ( (x&0x3)<<16) //add
|
||||
#define s_RGA2_DST_INFO_SW_CSC_CLIP_MODE(x) ( (x&0x1)<<18)
|
||||
#define s_RGA2_DST_INFO_SW_DST_CSC_MODE_2(x) ( (x&0x1)<<19) //add
|
||||
#define s_RGA2_DST_INFO_SW_DST_FMT_YUV400_EN(x) ( (x&0x1)<<24)
|
||||
#define s_RGA2_DST_INFO_SW_DST_FMT_Y4_EN(x) ( (x&0x1)<<25)
|
||||
#define s_RGA2_DST_INFO_SW_DST_NN_QUANTIZE_EN(x) ( (x&0x1)<<26)
|
||||
@@ -264,6 +266,19 @@
|
||||
#define RGA2_INT_OFFSET 0x10
|
||||
#define RGA2_MMU_CTRL0_OFFSET 0x14
|
||||
#define RGA2_MMU_CMD_BASE_OFFSET 0x18
|
||||
/* 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
|
||||
|
||||
#define RGA2_MODE_CTRL_OFFSET 0x00
|
||||
#define RGA2_SRC_INFO_OFFSET 0x04
|
||||
@@ -306,7 +321,7 @@
|
||||
#define RGA2_MMU_DST_BASE_OFFSET 0x78
|
||||
#define RGA2_MMU_ELS_BASE_OFFSET 0x7c
|
||||
|
||||
int RGA2_gen_reg_info(unsigned char *base, struct rga2_req *msg);
|
||||
int RGA2_gen_reg_info(unsigned char *base, unsigned char *csc_base, struct rga2_req *msg);
|
||||
void RGA_MSG_2_RGA2_MSG(struct rga_req *req_rga, struct rga2_req *req);
|
||||
void RGA_MSG_2_RGA2_MSG_32(struct rga_req_32 *req_rga, struct rga2_req *req);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user