video: rockchip: rga3: add support guass3x3

Change-Id: I75f6d899986f9ced6beabaa9b4e67d53b5d266d6
Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com>
This commit is contained in:
Yu Qiaowei
2024-01-05 10:34:37 +08:00
committed by Tao Huang
parent 7bcacad517
commit 0d6962db93
3 changed files with 81 additions and 3 deletions

View File

@@ -421,6 +421,11 @@ struct rga_mosaic_info {
uint8_t mode;
};
struct rga_gauss_config {
uint32_t size;
uint64_t coe_ptr;
};
/* MAX(min, (max - channel_value)) */
struct rga_osd_invert_factor {
uint8_t alpha_max;
@@ -745,7 +750,9 @@ struct rga_req {
struct rga_rgba5551_alpha rgba5551_alpha;
uint8_t reservr[39];
struct rga_gauss_config gauss_config;
uint8_t reservr[27];
};
struct rga_alpha_config {
@@ -878,6 +885,8 @@ struct rga2_req {
struct rga_iommu_prefetch iommu_prefetch;
struct rga_rgba5551_alpha rgba5551_alpha;
struct rga_gauss_config gauss_config;
};
struct rga3_req {

View File

@@ -61,6 +61,7 @@
#define RGA2_OSD_CTRL1_OFFSET 0x024 // repeat
#define RGA2_SRC_BG_COLOR_OFFSET 0x028
#define RGA2_OSD_COLOR0_OFFSET 0x028 // repeat
#define RGA2_GAUSS_COE_OFFSET 0x028 // repeat
#define RGA2_SRC_FG_COLOR_OFFSET 0x02c
#define RGA2_OSD_COLOR1_OFFSET 0x02c // repeat
#define RGA2_SRC_TR_COLOR0_OFFSET 0x030
@@ -209,6 +210,7 @@
#define m_RGA2_MODE_CTRL_SW_TILE4x4_IN_EN (0x1 << 12)
#define m_RGA2_MODE_CTRL_SW_TILE4x4_OUT_EN (0x1 << 13)
#define m_RGA2_MODE_CTRL_SW_FBC_IN_EN (0x1 << 16)
#define m_RGA2_MODE_CTRL_SW_SRC_GAUSS_EN (0x1 << 17)
#define m_RGA2_MODE_CTRL_SW_FBC_BSP_DIS (0x1 << 18)
#define m_RGA2_MODE_CTRL_SW_TABLE_PRE_FETCH_DIS (0x1 << 19)
#define m_RGA2_MODE_CTRL_SW_AXI_WR128_DIS (0x1 << 20)
@@ -226,6 +228,7 @@
#define s_RGA2_MODE_CTRL_SW_TILE4x4_IN_EN(x) ((x & 0x1) << 12)
#define s_RGA2_MODE_CTRL_SW_TILE4x4_OUT_EN(x) ((x & 0x1) << 13)
#define s_RGA2_MODE_CTRL_SW_FBC_IN_EN(x) ((x & 0x1) << 16)
#define s_RGA2_MODE_CTRL_SW_SRC_GAUSS_EN(x) ((x & 0x1) << 17)
#define s_RGA2_MODE_CTRL_SW_FBC_BSP_DIS(x) ((x & 0x1) << 18)
#define s_RGA2_MODE_CTRL_SW_TABLE_PRE_FETCH_DIS(x) ((x & 0x1) << 19)
#define s_RGA2_MODE_CTRL_SW_AXI_WR128_DIS(x) ((x & 0x1) << 20)
@@ -312,6 +315,15 @@
#define s_RGA2_OSD_CTRL0_SW_OSD_FIX_WIDTH(x) ((x & 0x3ff) << 20)
#define s_RGA2_OSD_CTRL0_SW_OSD_2BPP_MODE(x) ((x & 0x1) << 30)
/* RGA2_GAUSS_COE */
#define m_RGA2_GAUSS_COE_SW_COE0 (0x3f << 0)
#define m_RGA2_GAUSS_COE_SW_COE1 (0x3f << 8)
#define m_RGA2_GAUSS_COE_SW_COE2 (0xff << 16)
#define s_RGA2_GAUSS_COE_SW_COE0(x) ((x & 0x3f) << 0)
#define s_RGA2_GAUSS_COE_SW_COE1(x) ((x & 0x3f) << 8)
#define s_RGA2_GAUSS_COE_SW_COE2(x) ((x & 0xff) << 16)
/* RGA2_OSD_CTRL1 */
#define m_RGA2_OSD_CTRL1_SW_OSD_COLOR_SEL (0x1 << 0)
#define m_RGA2_OSD_CTRL1_SW_OSD_FLAG_SEL (0x1 << 1)

View File

@@ -225,6 +225,10 @@ static void RGA2_set_mode_ctrl(u8 *base, struct rga2_req *msg)
reg = ((reg & (~m_RGA2_MODE_CTRL_SW_OSD_E)) |
(s_RGA2_MODE_CTRL_SW_OSD_E(msg->osd_info.enable)));
if (msg->gauss_config.size > 0)
reg = ((reg & (~m_RGA2_MODE_CTRL_SW_SRC_GAUSS_EN)) |
(s_RGA2_MODE_CTRL_SW_SRC_GAUSS_EN(1)));
*bRGA_MODE_CTL = reg;
}
@@ -1905,6 +1909,50 @@ static void RGA_set_reg_mosaic(u8 *base, struct rga2_req *msg)
*bRGA_MOSAIC_MODE = (u32)(msg->mosaic_info.mode & 0x7);
}
static int RGA_set_reg_gauss(u8 *base, struct rga2_req *msg)
{
uint32_t *bRGA_GAUSS_COE;
uint32_t reg = 0;
uint32_t *coe;
bRGA_GAUSS_COE = (u32 *)(base + RGA2_GAUSS_COE_OFFSET);
if (msg->gauss_config.size != 3) {
pr_err("Gaussian blur only support 3x3\n");
return -EINVAL;
}
coe = kmalloc(sizeof(uint32_t) * msg->gauss_config.size, GFP_KERNEL);
if (coe == NULL) {
pr_err("Gaussian blur alloc coe buffer error!\n");
return -ENOMEM;
}
if (unlikely(copy_from_user(coe,
u64_to_user_ptr(msg->gauss_config.coe_ptr),
sizeof(uint32_t) * msg->gauss_config.size))) {
pr_err("Gaussian blur coe copy_from_user failed\n");
kfree(coe);
return -EFAULT;
}
reg = ((reg & (~m_RGA2_GAUSS_COE_SW_COE0)) |
(s_RGA2_GAUSS_COE_SW_COE0(coe[0])));
reg = ((reg & (~m_RGA2_GAUSS_COE_SW_COE1)) |
(s_RGA2_GAUSS_COE_SW_COE1(coe[1])));
reg = ((reg & (~m_RGA2_GAUSS_COE_SW_COE2)) |
(s_RGA2_GAUSS_COE_SW_COE2(coe[2])));
*bRGA_GAUSS_COE = reg;
kfree(coe);
return 0;
}
static void RGA2_set_reg_osd(u8 *base, struct rga2_req *msg)
{
u32 *bRGA_OSD_CTRL0;
@@ -2213,6 +2261,7 @@ static void RGA2_set_mmu_reg_info(struct rga_scheduler_t *scheduler, u8 *base, s
static int rga2_gen_reg_info(struct rga_scheduler_t *scheduler, u8 *base, struct rga2_req *msg)
{
int ret;
u8 dst_nn_quantize_en = 0;
RGA2_set_mode_ctrl(base, msg);
@@ -2236,6 +2285,11 @@ static int rga2_gen_reg_info(struct rga_scheduler_t *scheduler, u8 *base, struct
RGA_set_reg_mosaic(base, msg);
if (msg->osd_info.enable)
RGA2_set_reg_osd(base, msg);
if (msg->gauss_config.size > 0) {
ret = RGA_set_reg_gauss(base, msg);
if (ret < 0)
return ret;
}
break;
case COLOR_FILL_MODE:
@@ -2266,7 +2320,7 @@ static int rga2_gen_reg_info(struct rga_scheduler_t *scheduler, u8 *base, struct
break;
default:
pr_err("ERROR msg render mode %d\n", msg->render_mode);
break;
return -EINVAL;
}
RGA2_set_mmu_reg_info(scheduler, base, msg);
@@ -2428,6 +2482,8 @@ static void rga_cmd_to_rga2_cmd(struct rga_scheduler_t *scheduler,
/* RGA2 1106 add */
memcpy(&req->mosaic_info, &req_rga->mosaic_info, sizeof(req_rga->mosaic_info));
memcpy(&req->gauss_config, &req_rga->gauss_config, sizeof(req_rga->gauss_config));
if ((scheduler->data->feature & RGA_YIN_YOUT) &&
rga_is_only_y_format(req->src.format) &&
rga_is_only_y_format(req->dst.format))
@@ -2767,7 +2823,8 @@ static int rga2_init_reg(struct rga_job *job)
if (scheduler->data->mmu == RGA_IOMMU)
req.CMD_fin_int_enable = 1;
if (rga2_gen_reg_info(scheduler, (uint8_t *)job->cmd_buf->vaddr, &req) == -1) {
ret = rga2_gen_reg_info(scheduler, (uint8_t *)job->cmd_buf->vaddr, &req);
if (ret < 0) {
pr_err("gen reg info error\n");
return -EINVAL;
}