mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
video: rockchip: rga3: add support guass3x3
Change-Id: I75f6d899986f9ced6beabaa9b4e67d53b5d266d6 Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com>
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user