From 9370bb92b2d16684ee45cf24e879c93c509162da Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 19 Dec 2024 01:47:39 +0000
Subject: [PATCH] add wifi6 8852be driver

---
 kernel/drivers/video/rockchip/rga3/rga2_reg_info.c |  759 ++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 494 insertions(+), 265 deletions(-)

diff --git a/kernel/drivers/video/rockchip/rga3/rga2_reg_info.c b/kernel/drivers/video/rockchip/rga3/rga2_reg_info.c
index 923c1f3..8792e8d 100644
--- a/kernel/drivers/video/rockchip/rga3/rga2_reg_info.c
+++ b/kernel/drivers/video/rockchip/rga3/rga2_reg_info.c
@@ -7,7 +7,6 @@
 
 #define pr_fmt(fmt) "rga2_reg: " fmt
 
-#include "rga_job.h"
 #include "rga2_reg_info.h"
 #include "rga_dma_buf.h"
 #include "rga_iommu.h"
@@ -165,12 +164,8 @@
 
 	bRGA_MODE_CTL = (u32 *) (base + RGA2_MODE_CTRL_OFFSET);
 
-	if (msg->render_mode == 4)
-		render_mode = 3;
-
-	/* In slave mode, the current frame completion interrupt must be enabled. */
-	if (!RGA2_USE_MASTER_MODE)
-		msg->CMD_fin_int_enable = 1;
+	if (msg->render_mode == UPDATE_PALETTE_TABLE_MODE)
+		render_mode = 0x3;
 
 	reg =
 		((reg & (~m_RGA2_MODE_CTRL_SW_RENDER_MODE)) |
@@ -231,6 +226,7 @@
 	u32 sw, sh;
 	u32 dw, dh;
 	u8 rotate_mode;
+	u8 vsp_scale_mode = 0;
 	u8 scale_w_flag, scale_h_flag;
 
 	bRGA_SRC_INFO = (u32 *) (base + RGA2_SRC_INFO_OFFSET);
@@ -292,6 +288,18 @@
 		/* uvvds need to force tile mode. */
 		if (msg->uvvds_mode && scale_w_flag == 0)
 			scale_w_flag = 3;
+	}
+
+	/* VSP scale mode select, HSD > VSD > VSP > HSP */
+	if (scale_h_flag == 0x2) {
+		/* After HSD, VSP needs to check dst_width */
+		if ((scale_w_flag == 0x1) && (dw < RGA2_VSP_BICUBIC_LIMIT))
+			vsp_scale_mode = 0x0;
+		else if (sw < RGA2_VSP_BICUBIC_LIMIT)
+			vsp_scale_mode = 0x0;
+		else
+			/* default select bilinear */
+			vsp_scale_mode = 0x1;
 	}
 
 	switch (msg->src.format) {
@@ -564,8 +572,7 @@
 		 ((msg->alpha_rop_flag >> 4) & 0x1)));
 	reg =
 		((reg & (~m_RGA2_SRC_INFO_SW_SW_VSP_MODE_SEL)) |
-		 (s_RGA2_SRC_INFO_SW_SW_VSP_MODE_SEL((
-			 msg->scale_bicu_mode >> 4))));
+		 (s_RGA2_SRC_INFO_SW_SW_VSP_MODE_SEL((vsp_scale_mode))));
 	reg =
 		((reg & (~m_RGA2_SRC_INFO_SW_SW_YUV10_E)) |
 		 (s_RGA2_SRC_INFO_SW_SW_YUV10_E((yuv10))));
@@ -1270,104 +1277,253 @@
 	u32 *bRGA_ALPHA_CTRL0;
 	u32 *bRGA_ALPHA_CTRL1;
 	u32 *bRGA_FADING_CTRL;
-	u32 reg0 = 0;
-	u32 reg1 = 0;
+	u32 reg = 0;
+	union rga2_color_ctrl color_ctrl;
+	union rga2_alpha_ctrl alpha_ctrl;
+	struct rga_alpha_config *config;
 
 	bRGA_ALPHA_CTRL0 = (u32 *) (base + RGA2_ALPHA_CTRL0_OFFSET);
 	bRGA_ALPHA_CTRL1 = (u32 *) (base + RGA2_ALPHA_CTRL1_OFFSET);
 	bRGA_FADING_CTRL = (u32 *) (base + RGA2_FADING_CTRL_OFFSET);
 
-	reg0 =
-		((reg0 & (~m_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_0)) |
+	color_ctrl.value = 0;
+	alpha_ctrl.value = 0;
+	config = &msg->alpha_config;
+
+	color_ctrl.bits.src_color_mode =
+		config->fg_pre_multiplied ? RGA_ALPHA_PRE_MULTIPLIED : RGA_ALPHA_NO_PRE_MULTIPLIED;
+	color_ctrl.bits.dst_color_mode =
+		config->bg_pre_multiplied ? RGA_ALPHA_PRE_MULTIPLIED : RGA_ALPHA_NO_PRE_MULTIPLIED;
+
+	if (config->fg_pixel_alpha_en)
+		color_ctrl.bits.src_blend_mode =
+			config->fg_global_alpha_en ? RGA_ALPHA_PER_PIXEL_GLOBAL :
+			RGA_ALPHA_PER_PIXEL;
+	else
+		color_ctrl.bits.src_blend_mode = RGA_ALPHA_GLOBAL;
+
+	if (config->bg_pixel_alpha_en)
+		color_ctrl.bits.dst_blend_mode =
+			config->bg_global_alpha_en ? RGA_ALPHA_PER_PIXEL_GLOBAL :
+			RGA_ALPHA_PER_PIXEL;
+	else
+		color_ctrl.bits.dst_blend_mode = RGA_ALPHA_GLOBAL;
+
+	/*
+	 * Since the hardware uses 256 as 1, the original alpha value needs to
+	 * be + (alpha >> 7).
+	 */
+	color_ctrl.bits.src_alpha_cal_mode = RGA_ALPHA_SATURATION;
+	color_ctrl.bits.dst_alpha_cal_mode = RGA_ALPHA_SATURATION;
+
+	/* porter duff alpha enable */
+	switch (config->mode) {
+	case RGA_ALPHA_BLEND_SRC:
+		/*
+		 * SRC mode:
+		 *	Sf = 1, Df = 0;
+		 *	[Rc,Ra] = [Sc,Sa];
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_ONE;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_ZERO;
+
+		break;
+
+	case RGA_ALPHA_BLEND_DST:
+		/*
+		 * SRC mode:
+		 *	Sf = 0, Df = 1;
+		 *	[Rc,Ra] = [Dc,Da];
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_ZERO;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_ONE;
+
+		break;
+
+	case RGA_ALPHA_BLEND_SRC_OVER:
+		/*
+		 * SRC-OVER mode:
+		 *	Sf = 1, Df = (1 - Sa)
+		 *	[Rc,Ra] = [ Sc + (1 - Sa) * Dc, Sa + (1 - Sa) * Da ]
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_ONE;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
+
+		break;
+
+	case RGA_ALPHA_BLEND_DST_OVER:
+		/*
+		 * DST-OVER mode:
+		 *	Sf = (1 - Da) , Df = 1
+		 *	[Rc,Ra] = [ Sc * (1 - Da) + Dc, Sa * (1 - Da) + Da ]
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_ONE;
+
+		break;
+
+	case RGA_ALPHA_BLEND_SRC_IN:
+		/*
+		 * SRC-IN mode:
+		 *	Sf = Da , Df = 0
+		 *	[Rc,Ra] = [ Sc * Da, Sa * Da ]
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_OPPOSITE;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_ZERO;
+
+		break;
+
+	case RGA_ALPHA_BLEND_DST_IN:
+		/*
+		 * DST-IN mode:
+		 *	Sf = 0 , Df = Sa
+		 *	[Rc,Ra] = [ Dc * Sa, Da * Sa ]
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_ZERO;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_OPPOSITE;
+
+		break;
+
+	case RGA_ALPHA_BLEND_SRC_OUT:
+		/*
+		 * SRC-OUT mode:
+		 *	Sf = (1 - Da) , Df = 0
+		 *	[Rc,Ra] = [ Sc * (1 - Da), Sa * (1 - Da) ]
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_ZERO;
+
+		break;
+
+	case RGA_ALPHA_BLEND_DST_OUT:
+		/*
+		 * DST-OUT mode:
+		 *	Sf = 0 , Df = (1 - Sa)
+		 *	[Rc,Ra] = [ Dc * (1 - Sa), Da * (1 - Sa) ]
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_ZERO;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
+
+		break;
+
+	case RGA_ALPHA_BLEND_SRC_ATOP:
+		/*
+		 * SRC-ATOP mode:
+		 *	Sf = Da , Df = (1 - Sa)
+		 *	[Rc,Ra] = [ Sc * Da + Dc * (1 - Sa), Sa * Da + Da * (1 - Sa) ]
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_OPPOSITE;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
+
+		break;
+
+	case RGA_ALPHA_BLEND_DST_ATOP:
+		/*
+		 * DST-ATOP mode:
+		 *	Sf = (1 - Da) , Df = Sa
+		 *	[Rc,Ra] = [ Sc * (1 - Da) + Dc * Sa, Sa * (1 - Da) + Da * Sa ]
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_OPPOSITE;
+
+		break;
+
+	case RGA_ALPHA_BLEND_XOR:
+		/*
+		 * DST-XOR mode:
+		 *	Sf = (1 - Da) , Df = (1 - Sa)
+		 *	[Rc,Ra] = [ Sc * (1 - Da) + Dc * (1 - Sa), Sa * (1 - Da) + Da * (1 - Sa) ]
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
+
+		break;
+
+	case RGA_ALPHA_BLEND_CLEAR:
+		/*
+		 * DST-CLEAR mode:
+		 *	Sf = 0 , Df = 0
+		 *	[Rc,Ra] = [ 0, 0 ]
+		 */
+		color_ctrl.bits.src_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.src_factor_mode = RGA_ALPHA_ZERO;
+
+		color_ctrl.bits.dst_alpha_mode = RGA_ALPHA_STRAIGHT;
+		color_ctrl.bits.dst_factor_mode = RGA_ALPHA_ZERO;
+
+		break;
+
+	default:
+		break;
+	}
+
+	alpha_ctrl.bits.src_blend_mode = color_ctrl.bits.src_blend_mode;
+	alpha_ctrl.bits.dst_blend_mode = color_ctrl.bits.dst_blend_mode;
+
+	alpha_ctrl.bits.src_alpha_cal_mode = color_ctrl.bits.src_alpha_cal_mode;
+	alpha_ctrl.bits.dst_alpha_cal_mode = color_ctrl.bits.dst_alpha_cal_mode;
+
+	alpha_ctrl.bits.src_alpha_mode = color_ctrl.bits.src_alpha_mode;
+	alpha_ctrl.bits.src_factor_mode = color_ctrl.bits.src_factor_mode;
+
+	alpha_ctrl.bits.dst_alpha_mode = color_ctrl.bits.dst_alpha_mode;
+	alpha_ctrl.bits.dst_factor_mode = color_ctrl.bits.dst_factor_mode;
+
+	reg =
+		((reg & (~m_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_0)) |
 		 (s_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_0(msg->alpha_rop_flag)));
-	reg0 =
-		((reg0 & (~m_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_SEL)) |
+	reg =
+		((reg & (~m_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_SEL)) |
 		 (s_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_SEL
 		 (msg->alpha_rop_flag >> 1)));
-	reg0 =
-		((reg0 & (~m_RGA2_ALPHA_CTRL0_SW_ROP_MODE)) |
+	reg =
+		((reg & (~m_RGA2_ALPHA_CTRL0_SW_ROP_MODE)) |
 		 (s_RGA2_ALPHA_CTRL0_SW_ROP_MODE(msg->rop_mode)));
-	reg0 =
-		((reg0 & (~m_RGA2_ALPHA_CTRL0_SW_SRC_GLOBAL_ALPHA)) |
+	reg =
+		((reg & (~m_RGA2_ALPHA_CTRL0_SW_SRC_GLOBAL_ALPHA)) |
 		 (s_RGA2_ALPHA_CTRL0_SW_SRC_GLOBAL_ALPHA
-		 (msg->src_a_global_val)));
-	reg0 =
-		((reg0 & (~m_RGA2_ALPHA_CTRL0_SW_DST_GLOBAL_ALPHA)) |
+		 ((uint8_t)config->fg_global_alpha_value)));
+	reg =
+		((reg & (~m_RGA2_ALPHA_CTRL0_SW_DST_GLOBAL_ALPHA)) |
 		 (s_RGA2_ALPHA_CTRL0_SW_DST_GLOBAL_ALPHA
-		 (msg->dst_a_global_val)));
+		 ((uint8_t)config->bg_global_alpha_value)));
 
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_DST_COLOR_M0)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_DST_COLOR_M0
-		 (msg->alpha_mode_0 >> 15)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_SRC_COLOR_M0)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_SRC_COLOR_M0
-		 (msg->alpha_mode_0 >> 7)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_DST_FACTOR_M0)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_DST_FACTOR_M0
-		 (msg->alpha_mode_0 >> 12)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_SRC_FACTOR_M0)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_SRC_FACTOR_M0
-		 (msg->alpha_mode_0 >> 4)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_CAL_M0)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_CAL_M0
-		 (msg->alpha_mode_0 >> 11)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_CAL_M0)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_CAL_M0
-		 (msg->alpha_mode_0 >> 3)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_DST_BLEND_M0)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_DST_BLEND_M0
-		 (msg->alpha_mode_0 >> 9)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_SRC_BLEND_M0)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_SRC_BLEND_M0
-		 (msg->alpha_mode_0 >> 1)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_M0)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_M0
-		 (msg->alpha_mode_0 >> 8)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_M0)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_M0
-		 (msg->alpha_mode_0 >> 0)));
+	*bRGA_ALPHA_CTRL0 = reg;
+	*bRGA_ALPHA_CTRL1 = color_ctrl.value | (alpha_ctrl.value << 16);
 
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_DST_FACTOR_M1)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_DST_FACTOR_M1
-		 (msg->alpha_mode_1 >> 12)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_SRC_FACTOR_M1)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_SRC_FACTOR_M1
-		 (msg->alpha_mode_1 >> 4)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_CAL_M1)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_CAL_M1
-		 (msg->alpha_mode_1 >> 11)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_CAL_M1)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_CAL_M1
-		 (msg->alpha_mode_1 >> 3)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_DST_BLEND_M1)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_DST_BLEND_M1(msg->alpha_mode_1 >> 9)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_SRC_BLEND_M1)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_SRC_BLEND_M1(msg->alpha_mode_1 >> 1)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_M1)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_M1(msg->alpha_mode_1 >> 8)));
-	reg1 =
-		((reg1 & (~m_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_M1)) |
-		 (s_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_M1(msg->alpha_mode_1 >> 0)));
-
-	*bRGA_ALPHA_CTRL0 = reg0;
-	*bRGA_ALPHA_CTRL1 = reg1;
 
 	if ((msg->alpha_rop_flag >> 2) & 1) {
 		*bRGA_FADING_CTRL = (1 << 24) | (msg->fading_b_value << 16) |
@@ -1715,7 +1871,7 @@
 	*bRGA_MMU_ELS_BASE = (u32) (msg->mmu_info.els_base_addr) >> 4;
 }
 
-int rga2_gen_reg_info(u8 *base, struct rga2_req *msg)
+static int rga2_gen_reg_info(u8 *base, struct rga2_req *msg)
 {
 	u8 dst_nn_quantize_en = 0;
 
@@ -1769,8 +1925,6 @@
 static void rga_cmd_to_rga2_cmd(struct rga_scheduler_t *scheduler,
 				struct rga_req *req_rga, struct rga2_req *req)
 {
-	u16 alpha_mode_0, alpha_mode_1;
-
 	if (req_rga->render_mode == 6)
 		req->render_mode = UPDATE_PALETTE_TABLE_MODE;
 	else if (req_rga->render_mode == 7)
@@ -1848,9 +2002,6 @@
 		break;
 	}
 
-	if ((req->dst.act_w > 2048) && (req->src.act_h < req->dst.act_h))
-		req->scale_bicu_mode |= (1 << 4);
-
 	req->LUT_addr = req_rga->LUT_addr;
 	req->rop_mask_addr = req_rga->rop_mask_addr;
 
@@ -1873,6 +2024,8 @@
 
 	req->palette_mode = req_rga->palette_mode;
 	req->yuv2rgb_mode = req_rga->yuv2rgb_mode;
+	if (req_rga->full_csc.flag & 0x1)
+		req->full_csc_en = 1;
 	req->endian_mode = req_rga->endian_mode;
 	req->rgb2yuv_mode = 0;
 
@@ -1914,110 +2067,52 @@
 
 	if (((req_rga->alpha_rop_flag) & 1)) {
 		if ((req_rga->alpha_rop_flag >> 3) & 1) {
-			/* porter duff alpha enable */
-			switch (req_rga->PD_mode) {
-			/* dst = 0 */
-			case 0:
-				break;
-			/* dst = src */
-			case 1:
-				req->alpha_mode_0 = 0x0212;
-				req->alpha_mode_1 = 0x0212;
-				break;
-			/* dst = dst */
-			case 2:
-				req->alpha_mode_0 = 0x1202;
-				req->alpha_mode_1 = 0x1202;
-				break;
-			/* dst = (256*sc + (256 - sa)*dc) >> 8 */
-			case 3:
-				if ((req_rga->alpha_rop_mode & 3) == 0) {
-					/* both use globalAlpha. */
-					alpha_mode_0 = 0x3010;
-					alpha_mode_1 = 0x3010;
-				} else if ((req_rga->alpha_rop_mode & 3) == 1) {
-					/* Do not use globalAlpha. */
-					alpha_mode_0 = 0x3212;
-					alpha_mode_1 = 0x3212;
-				} else if ((req_rga->alpha_rop_mode & 3) == 2) {
-					/*
-					 * dst use globalAlpha,
-					 * and dst has pixelAlpha.
-					 */
-					alpha_mode_0 = 0x3014;
-					alpha_mode_1 = 0x3014;
-				} else {
-					/*
-					 * dst use globalAlpha, and
-					 * dst does not have pixelAlpha.
-					 */
-					alpha_mode_0 = 0x3012;
-					alpha_mode_1 = 0x3012;
-				}
-				req->alpha_mode_0 = alpha_mode_0;
-				req->alpha_mode_1 = alpha_mode_1;
-				break;
-			/* dst = (sc*(256-da) + 256*dc) >> 8 */
-			case 4:
-				/* Do not use globalAlpha. */
-				req->alpha_mode_0 = 0x1232;
-				req->alpha_mode_1 = 0x1232;
-				break;
-			/* dst = (da*sc) >> 8 */
-			case 5:
-				break;
-			/* dst = (sa*dc) >> 8 */
-			case 6:
-				break;
-			/* dst = ((256-da)*sc) >> 8 */
-			case 7:
-				break;
-			/* dst = ((256-sa)*dc) >> 8 */
-			case 8:
-				break;
-			/* dst = (da*sc + (256-sa)*dc) >> 8 */
-			case 9:
-				req->alpha_mode_0 = 0x3040;
-				req->alpha_mode_1 = 0x3040;
-				break;
-			/* dst = ((256-da)*sc + (sa*dc)) >> 8 */
-			case 10:
-				break;
-			/* dst = ((256-da)*sc + (256-sa)*dc) >> 8 */
-			case 11:
-				break;
-			case 12:
-				req->alpha_mode_0 = 0x0010;
-				req->alpha_mode_1 = 0x0820;
-				break;
-			default:
-				break;
-			}
+			req->alpha_config.enable = true;
 
-			if (req->osd_info.enable) {
-				/* set dst(osd_block) real color mode */
-				if (req->alpha_mode_0 & (0x01 << 9))
-					req->alpha_mode_0 |= (1 << 15);
-			}
-
-			/* Real color mode */
 			if ((req_rga->alpha_rop_flag >> 9) & 1) {
-				if (req->alpha_mode_0 & (0x01 << 1))
-					req->alpha_mode_0 |= (1 << 7);
-				if (req->alpha_mode_0 & (0x01 << 9))
-					req->alpha_mode_0 |= (1 << 15);
+				req->alpha_config.fg_pre_multiplied = false;
+				req->alpha_config.bg_pre_multiplied = false;
+			} else if (req->osd_info.enable) {
+				req->alpha_config.fg_pre_multiplied = true;
+				/* set dst(osd_block) real color mode */
+				req->alpha_config.bg_pre_multiplied = false;
+			} else {
+				req->alpha_config.fg_pre_multiplied = true;
+				req->alpha_config.bg_pre_multiplied = true;
 			}
-		} else {
-			if ((req_rga->alpha_rop_mode & 3) == 0) {
-				req->alpha_mode_0 = 0x3040;
-				req->alpha_mode_1 = 0x3040;
-			} else if ((req_rga->alpha_rop_mode & 3) == 1) {
-				req->alpha_mode_0 = 0x3042;
-				req->alpha_mode_1 = 0x3242;
-			} else if ((req_rga->alpha_rop_mode & 3) == 2) {
-				req->alpha_mode_0 = 0x3044;
-				req->alpha_mode_1 = 0x3044;
+
+			req->alpha_config.fg_pixel_alpha_en = rga_is_alpha_format(req->src.format);
+			if (req->bitblt_mode)
+				req->alpha_config.bg_pixel_alpha_en =
+					rga_is_alpha_format(req->src1.format);
+			else
+				req->alpha_config.bg_pixel_alpha_en =
+					rga_is_alpha_format(req->dst.format);
+
+			if (req_rga->feature.global_alpha_en) {
+				if (req_rga->fg_global_alpha < 0xff) {
+					req->alpha_config.fg_global_alpha_en = true;
+					req->alpha_config.fg_global_alpha_value =
+						req_rga->fg_global_alpha;
+				} else if (!req->alpha_config.fg_pixel_alpha_en) {
+					req->alpha_config.fg_global_alpha_en = true;
+					req->alpha_config.fg_global_alpha_value = 0xff;
+				}
+
+				if (req_rga->bg_global_alpha < 0xff) {
+					req->alpha_config.bg_global_alpha_en = true;
+					req->alpha_config.bg_global_alpha_value =
+						req_rga->bg_global_alpha;
+				} else if (!req->alpha_config.bg_pixel_alpha_en) {
+					req->alpha_config.bg_global_alpha_en = true;
+					req->alpha_config.bg_global_alpha_value = 0xff;
+				}
+			} else {
+				req->alpha_config.bg_global_alpha_value = 0xff;
+				req->alpha_config.bg_global_alpha_value = 0xff;
 			}
+
+			req->alpha_config.mode = req_rga->PD_mode;
 		}
 	}
 
@@ -2060,16 +2155,18 @@
 	}
 }
 
-void rga2_soft_reset(struct rga_scheduler_t *scheduler)
+static void rga2_soft_reset(struct rga_scheduler_t *scheduler)
 {
 	u32 i;
 	u32 reg;
-	u32 iommu_dte_addr;
+	u32 iommu_dte_addr = 0;
 
 	if (scheduler->data->mmu == RGA_IOMMU)
-		iommu_dte_addr = rga_read(0xf00, scheduler);
+		iommu_dte_addr = rga_read(RGA_IOMMU_DTE_ADDR, scheduler);
 
-	rga_write((1 << 3) | (1 << 4) | (1 << 6), RGA2_SYS_CTRL, scheduler);
+	rga_write(m_RGA2_SYS_CTRL_ACLK_SRESET_P | m_RGA2_SYS_CTRL_CCLK_SRESET_P |
+		  m_RGA2_SYS_CTRL_RST_PROTECT_P,
+		  RGA2_SYS_CTRL, scheduler);
 
 	for (i = 0; i < RGA_RESET_TIMEOUT; i++) {
 		/* RGA_SYS_CTRL */
@@ -2082,13 +2179,16 @@
 	}
 
 	if (scheduler->data->mmu == RGA_IOMMU) {
-		rga_write(iommu_dte_addr, 0xf00, scheduler);
+		rga_write(iommu_dte_addr, RGA_IOMMU_DTE_ADDR, scheduler);
 		/* enable iommu */
-		rga_write(0, 0xf08, scheduler);
+		rga_write(RGA_IOMMU_CMD_ENABLE_PAGING, RGA_IOMMU_COMMAND, scheduler);
 	}
 
 	if (i == RGA_RESET_TIMEOUT)
-		pr_err("soft reset timeout.\n");
+		pr_err("RAG2 core[%d] soft reset timeout.\n", scheduler->core);
+	else
+		pr_info("RGA2 core[%d] soft reset complete.\n", scheduler->core);
+
 }
 
 static int rga2_check_param(const struct rga_hw_data *data, const struct rga2_req *req)
@@ -2207,19 +2307,23 @@
 	pr_info("mmu: src=%.2x src1=%.2x dst=%.2x els=%.2x\n",
 		req->mmu_info.src0_mmu_flag, req->mmu_info.src1_mmu_flag,
 		req->mmu_info.dst_mmu_flag, req->mmu_info.els_mmu_flag);
-	pr_info("alpha: flag %x mode0=%x mode1=%x\n", req->alpha_rop_flag,
-		req->alpha_mode_0, req->alpha_mode_1);
-	pr_info("blend mode is %s\n",
-		rga_get_blend_mode_str(req->alpha_rop_flag, req->alpha_mode_0,
-					req->alpha_mode_1));
+	pr_info("alpha: flag %x mode=%s\n",
+		req->alpha_rop_flag, rga_get_blend_mode_str(req->alpha_config.mode));
+	pr_info("alpha: pre_multi=[%d,%d] pixl=[%d,%d] glb=[%d,%d]\n",
+		req->alpha_config.fg_pre_multiplied, req->alpha_config.bg_pre_multiplied,
+		req->alpha_config.fg_pixel_alpha_en, req->alpha_config.bg_pixel_alpha_en,
+		req->alpha_config.fg_global_alpha_en, req->alpha_config.bg_global_alpha_en);
+	pr_info("alpha: fg_global_alpha=%x bg_global_alpha=%x\n",
+		req->alpha_config.fg_global_alpha_value, req->alpha_config.bg_global_alpha_value);
 	pr_info("yuv2rgb mode is %x\n", req->yuv2rgb_mode);
 }
 
-int rga2_init_reg(struct rga_job *job)
+static int rga2_init_reg(struct rga_job *job)
 {
 	struct rga2_req req;
 	int ret = 0;
 	struct rga_scheduler_t *scheduler = NULL;
+	ktime_t timestamp = ktime_get();
 
 	scheduler = job->scheduler;
 	if (unlikely(scheduler == NULL)) {
@@ -2230,7 +2334,24 @@
 	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));
+	if (req.full_csc_en) {
+		memcpy(&job->full_csc, &job->rga_command_base.full_csc, sizeof(job->full_csc));
+		if (job->rga_command_base.feature.full_csc_clip_en) {
+			memcpy(&job->full_csc_clip, &job->rga_command_base.full_csc_clip,
+			       sizeof(job->full_csc_clip));
+		} else {
+			job->full_csc_clip.y.max = 0xff;
+			job->full_csc_clip.y.min = 0x0;
+			job->full_csc_clip.uv.max = 0xff;
+			job->full_csc_clip.uv.min = 0x0;
+		}
+
+	} else {
+		job->full_csc_clip.y.max = 0xff;
+		job->full_csc_clip.y.min = 0x0;
+		job->full_csc_clip.uv.max = 0xff;
+		job->full_csc_clip.uv.min = 0x0;
+	}
 	memcpy(&job->pre_intr_info, &job->rga_command_base.pre_intr_info,
 	       sizeof(job->pre_intr_info));
 
@@ -2267,10 +2388,18 @@
 		}
 	}
 
+	/* In slave mode, the current frame completion interrupt must be enabled. */
+	if (scheduler->data->mmu == RGA_IOMMU)
+		req.CMD_fin_int_enable = 1;
+
 	if (rga2_gen_reg_info((uint8_t *)job->cmd_reg, &req) == -1) {
 		pr_err("gen reg info error\n");
 		return -EINVAL;
 	}
+
+	if (DEBUGGER_EN(TIME))
+		pr_info("request[%d], generate register cost time %lld us\n",
+			job->request_id, ktime_us_delta(ktime_get(), timestamp));
 
 	return ret;
 }
@@ -2338,7 +2467,7 @@
 			cmd_reg[2 + i * 4], cmd_reg[3 + i * 4]);
 }
 
-void rga2_dump_read_back_reg(struct rga_scheduler_t *scheduler)
+static void rga2_dump_read_back_reg(struct rga_scheduler_t *scheduler)
 {
 	rga2_dump_read_back_sys_reg(scheduler);
 	rga2_dump_read_back_csc_reg(scheduler);
@@ -2351,66 +2480,71 @@
 
 	if (job->pre_intr_info.read_intr_en) {
 		reg = s_RGA2_READ_LINE_SW_INTR_LINE_RD_TH(job->pre_intr_info.read_threshold);
-		rga_write(reg, RGA2_READ_LINE_CNT_OFFSET, scheduler);
+		rga_write(reg, RGA2_READ_LINE_CNT, scheduler);
 	}
 
 	if (job->pre_intr_info.write_intr_en) {
 		reg = s_RGA2_WRITE_LINE_SW_INTR_LINE_WR_START(job->pre_intr_info.write_start);
 		reg = ((reg & (~m_RGA2_WRITE_LINE_SW_INTR_LINE_WR_STEP)) |
 		       (s_RGA2_WRITE_LINE_SW_INTR_LINE_WR_STEP(job->pre_intr_info.write_step)));
-		rga_write(reg, RGA2_WRITE_LINE_CNT_OFFSET, scheduler);
+		rga_write(reg, RGA2_WRITE_LINE_CNT, scheduler);
 	}
 
-	reg = rga_read(RGA2_SYS_CTRL_OFFSET, scheduler);
-	reg = ((reg & (~m_RGA2_SYS_HOLD_MODE_EN)) |
-	       (s_RGA2_SYS_HOLD_MODE_EN(job->pre_intr_info.read_hold_en)));
-	rga_write(reg, RGA2_SYS_CTRL_OFFSET, scheduler);
+	reg = rga_read(RGA2_SYS_CTRL, scheduler);
+	reg = ((reg & (~m_RGA2_SYS_CTRL_HOLD_MODE_EN)) |
+	       (s_RGA2_SYS_CTRL_HOLD_MODE_EN(job->pre_intr_info.read_hold_en)));
+	rga_write(reg, RGA2_SYS_CTRL, scheduler);
 
-	reg = rga_read(RGA2_INT_OFFSET, scheduler);
+	reg = rga_read(RGA2_INT, scheduler);
 	reg = (reg | s_RGA2_INT_LINE_RD_CLEAR(0x1) | s_RGA2_INT_LINE_WR_CLEAR(0x1));
 	reg = ((reg & (~m_RGA2_INT_LINE_RD_EN)) |
 	       (s_RGA2_INT_LINE_RD_EN(job->pre_intr_info.read_intr_en)));
 	reg = ((reg & (~m_RGA2_INT_LINE_WR_EN)) |
 	       (s_RGA2_INT_LINE_WR_EN(job->pre_intr_info.write_intr_en)));
-	rga_write(reg, RGA2_INT_OFFSET, scheduler);
+	rga_write(reg, RGA2_INT, 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);
+	rga_write(job->full_csc.coe_y.r_v |
+		  (job->full_csc_clip.y.max << 16) | (job->full_csc_clip.y.min << 24),
+		  RGA2_DST_CSC_00, scheduler);
+	rga_write(job->full_csc.coe_y.g_y |
+		  (job->full_csc_clip.uv.max << 16) | (job->full_csc_clip.uv.min << 24),
+		  RGA2_DST_CSC_01, scheduler);
+	rga_write(job->full_csc.coe_y.b_u, RGA2_DST_CSC_02, scheduler);
+	rga_write(job->full_csc.coe_y.off, RGA2_DST_CSC_OFF0, 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);
+	rga_write(job->full_csc.coe_u.r_v, RGA2_DST_CSC_10, scheduler);
+	rga_write(job->full_csc.coe_u.g_y, RGA2_DST_CSC_11, scheduler);
+	rga_write(job->full_csc.coe_u.b_u, RGA2_DST_CSC_12, scheduler);
+	rga_write(job->full_csc.coe_u.off, RGA2_DST_CSC_OFF1, 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);
+	rga_write(job->full_csc.coe_v.r_v, RGA2_DST_CSC_20, scheduler);
+	rga_write(job->full_csc.coe_v.g_y, RGA2_DST_CSC_21, scheduler);
+	rga_write(job->full_csc.coe_v.b_u, RGA2_DST_CSC_22, scheduler);
+	rga_write(job->full_csc.coe_v.off, RGA2_DST_CSC_OFF2, scheduler);
 }
 
-int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
+static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
 {
-	ktime_t now = ktime_get();
 	int i;
+	bool master_mode_en;
+	uint32_t sys_ctrl;
+	ktime_t now = ktime_get();
+
+	/*
+	 * Currently there is no iova allocated for storing cmd for the IOMMU device,
+	 * so the iommu device needs to use the slave mode.
+	 */
+	if (scheduler->data->mmu != RGA_IOMMU)
+		master_mode_en = true;
+	else
+		master_mode_en = false;
 
 	if (job->pre_intr_info.enable)
 		rga2_set_pre_intr_reg(job, scheduler);
@@ -2419,7 +2553,7 @@
 		rga2_set_reg_full_csc(job, scheduler);
 
 	if (DEBUGGER_EN(REG)) {
-		int32_t *p;
+		uint32_t *p;
 
 		rga2_dump_read_back_sys_reg(scheduler);
 		rga2_dump_read_back_csc_reg(scheduler);
@@ -2434,42 +2568,44 @@
 
 	/* All CMD finish int */
 	rga_write(rga_read(RGA2_INT, scheduler) |
-		  (0x1 << 10) | (0x1 << 9) | (0x1 << 8), RGA2_INT, scheduler);
+		  m_RGA2_INT_ERROR_ENABLE_MASK | m_RGA2_INT_ALL_CMD_DONE_INT_EN,
+		  RGA2_INT, scheduler);
 
 	/* sys_reg init */
-	rga_write((0x1 << 2) | (0x1 << 5) | (0x1 << 6) | (0x1 << 11) | (0x1 << 12),
-		  RGA2_SYS_CTRL, scheduler);
+	sys_ctrl = m_RGA2_SYS_CTRL_AUTO_CKG | m_RGA2_SYS_CTRL_AUTO_RST |
+		   m_RGA2_SYS_CTRL_RST_PROTECT_P | m_RGA2_SYS_CTRL_DST_WR_OPT_DIS |
+		   m_RGA2_SYS_CTRL_SRC0YUV420SP_RD_OPT_DIS;
 
-	if (RGA2_USE_MASTER_MODE) {
+	if (master_mode_en) {
 		/* master mode */
-		rga_write(rga_read(RGA2_SYS_CTRL, scheduler) | (0x1 << 1),
-			  RGA2_SYS_CTRL, scheduler);
+		sys_ctrl |= s_RGA2_SYS_CTRL_CMD_MODE(1);
 
 		/* cmd buffer flush cache to ddr */
 		rga_dma_sync_flush_range(&job->cmd_reg[0], &job->cmd_reg[32], scheduler);
 
 		/* set cmd_addr */
 		rga_write(virt_to_phys(job->cmd_reg), RGA2_CMD_BASE, scheduler);
-
-		rga_write(1, RGA2_CMD_CTRL, scheduler);
+		rga_write(sys_ctrl, RGA2_SYS_CTRL, scheduler);
+		rga_write(m_RGA2_CMD_CTRL_CMD_LINE_ST_P, RGA2_CMD_CTRL, scheduler);
 	} else {
 		/* slave mode */
-		rga_write(rga_read(RGA2_SYS_CTRL, scheduler) | (0x0 << 1),
-			  RGA2_SYS_CTRL, scheduler);
+		sys_ctrl |= s_RGA2_SYS_CTRL_CMD_MODE(0) | m_RGA2_SYS_CTRL_CMD_OP_ST_P;
 
 		/* set cmd_reg */
 		for (i = 0; i <= 32; i++)
 			rga_write(job->cmd_reg[i], 0x100 + i * 4, scheduler);
 
-		rga_write(rga_read(RGA2_SYS_CTRL, scheduler) | 0x1, RGA2_SYS_CTRL, scheduler);
+		rga_write(sys_ctrl, RGA2_SYS_CTRL, scheduler);
 	}
 
-	if (DEBUGGER_EN(TIME)) {
-		pr_info("sys_ctrl = %x, int = %x, set cmd use time = %lld\n",
+	if (DEBUGGER_EN(REG))
+		pr_info("sys_ctrl = %x, int = %x\n",
 			rga_read(RGA2_SYS_CTRL, scheduler),
-			rga_read(RGA2_INT, scheduler),
-			ktime_us_delta(now, job->timestamp));
-	}
+			rga_read(RGA2_INT, scheduler));
+
+	if (DEBUGGER_EN(TIME))
+		pr_info("request[%d], set register cost time %lld us\n",
+			job->request_id, ktime_us_delta(now, job->timestamp));
 
 	job->hw_running_time = now;
 	job->hw_recoder_time = now;
@@ -2480,7 +2616,7 @@
 	return 0;
 }
 
-int rga2_get_version(struct rga_scheduler_t *scheduler)
+static int rga2_get_version(struct rga_scheduler_t *scheduler)
 {
 	u32 major_version, minor_version, svn_version;
 	u32 reg_version;
@@ -2511,3 +2647,96 @@
 
 	return 0;
 }
+
+static int rga2_read_back_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
+{
+	if (job->rga_command_base.osd_info.enable) {
+		job->rga_command_base.osd_info.cur_flags0 = rga_read(RGA2_OSD_CUR_FLAGS0,
+								     scheduler);
+		job->rga_command_base.osd_info.cur_flags1 = rga_read(RGA2_OSD_CUR_FLAGS1,
+								     scheduler);
+	}
+
+	return 0;
+}
+
+static int rga2_irq(struct rga_scheduler_t *scheduler)
+{
+	struct rga_job *job = scheduler->running_job;
+
+	/* The hardware interrupt top-half don't need to lock the scheduler. */
+	if (job == NULL)
+		return IRQ_HANDLED;
+
+	if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state))
+		return IRQ_WAKE_THREAD;
+
+	job->intr_status = rga_read(RGA2_INT, scheduler);
+	job->hw_status = rga_read(RGA2_STATUS2, scheduler);
+	job->cmd_status = rga_read(RGA2_STATUS1, scheduler);
+
+	if (DEBUGGER_EN(INT_FLAG))
+		pr_info("irq handler, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n",
+			job->intr_status, job->hw_status, job->cmd_status);
+
+	if (job->intr_status &
+	    (m_RGA2_INT_CUR_CMD_DONE_INT_FLAG | m_RGA2_INT_ALL_CMD_DONE_INT_FLAG)) {
+		set_bit(RGA_JOB_STATE_FINISH, &job->state);
+	} else if (job->intr_status & m_RGA2_INT_ERROR_FLAG_MASK) {
+		set_bit(RGA_JOB_STATE_INTR_ERR, &job->state);
+
+		pr_err("irq handler err! INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n",
+		       job->intr_status, job->hw_status, job->cmd_status);
+		scheduler->ops->soft_reset(scheduler);
+	}
+
+	/*clear INTR */
+	rga_write(rga_read(RGA2_INT, scheduler) |
+		  (m_RGA2_INT_ERROR_CLEAR_MASK |
+		   m_RGA2_INT_ALL_CMD_DONE_INT_CLEAR | m_RGA2_INT_NOW_CMD_DONE_INT_CLEAR |
+		   m_RGA2_INT_LINE_RD_CLEAR | m_RGA2_INT_LINE_WR_CLEAR),
+		  RGA2_INT, scheduler);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static int rga2_isr_thread(struct rga_job *job, struct rga_scheduler_t *scheduler)
+{
+	if (DEBUGGER_EN(INT_FLAG))
+		pr_info("isr thread, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n",
+			rga_read(RGA2_INT, scheduler),
+			rga_read(RGA2_STATUS2, scheduler),
+			rga_read(RGA2_STATUS1, scheduler));
+
+	if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) {
+		if (job->hw_status & m_RGA2_STATUS2_RPP_ERROR)
+			pr_err("RGA current status: rpp error!\n");
+		if (job->hw_status & m_RGA2_STATUS2_BUS_ERROR)
+			pr_err("RGA current status: bus error!\n");
+
+		if (job->intr_status & m_RGA2_INT_ERROR_INT_FLAG) {
+			pr_err("RGA bus error intr, please check your configuration and buffer.\n");
+			job->ret = -EFAULT;
+		} else if (job->intr_status & m_RGA2_INT_MMU_INT_FLAG) {
+			pr_err("mmu failed, please check size of the buffer or whether the buffer has been freed.\n");
+			job->ret = -EACCES;
+		}
+
+		if (job->ret == 0) {
+			pr_err("rga intr error[0x%x]!\n", job->intr_status);
+			job->ret = -EFAULT;
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+const struct rga_backend_ops rga2_ops = {
+	.get_version = rga2_get_version,
+	.set_reg = rga2_set_reg,
+	.init_reg = rga2_init_reg,
+	.soft_reset = rga2_soft_reset,
+	.read_back_reg = rga2_read_back_reg,
+	.irq = rga2_irq,
+	.isr_thread = rga2_isr_thread,
+};

--
Gitblit v1.6.2