xref: /OK3568_Linux_fs/kernel/drivers/video/rockchip/rga3/rga3_reg_info.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) Rockchip Electronics Co., Ltd.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Author: Huang Lee <Putin.li@rock-chips.com>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #define pr_fmt(fmt) "rga3_reg: " fmt
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include "rga3_reg_info.h"
11*4882a593Smuzhiyun #include "rga_dma_buf.h"
12*4882a593Smuzhiyun #include "rga_iommu.h"
13*4882a593Smuzhiyun #include "rga_common.h"
14*4882a593Smuzhiyun #include "rga_debugger.h"
15*4882a593Smuzhiyun #include "rga_hw_config.h"
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define FACTOR_MAX ((int)(2 << 15))
18*4882a593Smuzhiyun 
RGA3_set_reg_win0_info(u8 * base,struct rga3_req * msg)19*4882a593Smuzhiyun static void RGA3_set_reg_win0_info(u8 *base, struct rga3_req *msg)
20*4882a593Smuzhiyun {
21*4882a593Smuzhiyun 	u32 *bRGA3_WIN0_RD_CTRL;
22*4882a593Smuzhiyun 	u32 *bRGA3_WIN0_Y_BASE, *bRGA3_WIN0_U_BASE, *bRGA3_WIN0_V_BASE;
23*4882a593Smuzhiyun 	u32 *bRGA3_WIN0_VIR_STRIDE;
24*4882a593Smuzhiyun 	u32 *bRGA3_WIN0_UV_VIR_STRIDE;
25*4882a593Smuzhiyun 	u32 *bRGA3_WIN0_SRC_SIZE;
26*4882a593Smuzhiyun 	u32 *bRGA3_WIN0_ACT_OFF;
27*4882a593Smuzhiyun 	u32 *bRGA3_WIN0_ACT_SIZE;
28*4882a593Smuzhiyun 	u32 *bRGA3_WIN0_DST_SIZE;
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 	u32 *bRGA3_WIN0_SCL_FAC;
31*4882a593Smuzhiyun 	/* Not used yet. */
32*4882a593Smuzhiyun 	// u32 *bRGA3_WIN0_FBC_OFF;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	u32 sw = 0, sh = 0;
35*4882a593Smuzhiyun 	u32 dw = 0, dh = 0;
36*4882a593Smuzhiyun 	u32 param_x = 0, param_y = 0;
37*4882a593Smuzhiyun 	u8 x_up = 0, y_up = 0, x_by = 0, y_by = 0;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 	u32 reg = 0;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	u8 win_format = 0;
42*4882a593Smuzhiyun 	u8 win_yc_swp = 0;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	/* rb swap on RGB, uv swap on YUV */
45*4882a593Smuzhiyun 	u8 win_pix_swp = 0;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	/*
48*4882a593Smuzhiyun 	 * 1: Semi planar, for yuv 4:2:x
49*4882a593Smuzhiyun 	 * 2: Interleaved (yuyv), for yuv422 8bit only ,RGB
50*4882a593Smuzhiyun 	 */
51*4882a593Smuzhiyun 	u8 win_interleaved = 1;
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	/* enable r2y or y2r */
54*4882a593Smuzhiyun 	u8 win_r2y = 0;
55*4882a593Smuzhiyun 	u8 win_y2r = 0;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	u8 rotate_mode = 0;
58*4882a593Smuzhiyun 	u8 xmirror = 0;
59*4882a593Smuzhiyun 	u8 ymirror = 0;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	u8 pixel_width = 1;
62*4882a593Smuzhiyun 	u8 yuv10 = 0;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	u32 stride = 0;
65*4882a593Smuzhiyun 	u32 uv_stride = 0;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	bRGA3_WIN0_RD_CTRL = (u32 *) (base + RGA3_WIN0_RD_CTRL_OFFSET);
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	bRGA3_WIN0_Y_BASE = (u32 *) (base + RGA3_WIN0_Y_BASE_OFFSET);
70*4882a593Smuzhiyun 	bRGA3_WIN0_U_BASE = (u32 *) (base + RGA3_WIN0_U_BASE_OFFSET);
71*4882a593Smuzhiyun 	bRGA3_WIN0_V_BASE = (u32 *) (base + RGA3_WIN0_V_BASE_OFFSET);
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	bRGA3_WIN0_VIR_STRIDE = (u32 *) (base + RGA3_WIN0_VIR_STRIDE_OFFSET);
74*4882a593Smuzhiyun 	bRGA3_WIN0_UV_VIR_STRIDE =
75*4882a593Smuzhiyun 		(u32 *) (base + RGA3_WIN0_UV_VIR_STRIDE_OFFSET);
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	/* Not used yet. */
78*4882a593Smuzhiyun 	// bRGA3_WIN0_FBC_OFF = (u32 *) (base + RGA3_WIN0_FBC_OFF_OFFSET);
79*4882a593Smuzhiyun 	bRGA3_WIN0_ACT_OFF = (u32 *) (base + RGA3_WIN0_ACT_OFF_OFFSET);
80*4882a593Smuzhiyun 	bRGA3_WIN0_SRC_SIZE = (u32 *) (base + RGA3_WIN0_SRC_SIZE_OFFSET);
81*4882a593Smuzhiyun 	bRGA3_WIN0_ACT_SIZE = (u32 *) (base + RGA3_WIN0_ACT_SIZE_OFFSET);
82*4882a593Smuzhiyun 	bRGA3_WIN0_DST_SIZE = (u32 *) (base + RGA3_WIN0_DST_SIZE_OFFSET);
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	bRGA3_WIN0_SCL_FAC = (u32 *) (base + RGA3_WIN0_SCL_FAC_OFFSET);
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	if (msg->win0.rotate_mode != 0) {
87*4882a593Smuzhiyun 		rotate_mode = msg->rotate_mode & RGA3_ROT_BIT_ROT_90 ? 1 : 0;
88*4882a593Smuzhiyun 		xmirror = msg->rotate_mode & RGA3_ROT_BIT_X_MIRROR ? 1 : 0;
89*4882a593Smuzhiyun 		ymirror = msg->rotate_mode & RGA3_ROT_BIT_Y_MIRROR ? 1 : 0;
90*4882a593Smuzhiyun 	}
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	/* scale */
93*4882a593Smuzhiyun 	dw = msg->win0.dst_act_w;
94*4882a593Smuzhiyun 	dh = msg->win0.dst_act_h;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	if (rotate_mode) {
97*4882a593Smuzhiyun 		sh = msg->win0.src_act_w;
98*4882a593Smuzhiyun 		sw = msg->win0.src_act_h;
99*4882a593Smuzhiyun 	} else {
100*4882a593Smuzhiyun 		sw = msg->win0.src_act_w;
101*4882a593Smuzhiyun 		sh = msg->win0.src_act_h;
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	if (sw > dw) {
105*4882a593Smuzhiyun 		x_up = 0;
106*4882a593Smuzhiyun 		x_by = 0;
107*4882a593Smuzhiyun 	} else if (sw < dw) {
108*4882a593Smuzhiyun 		x_up = 1;
109*4882a593Smuzhiyun 		x_by = 0;
110*4882a593Smuzhiyun 	} else {
111*4882a593Smuzhiyun 		x_up = 0;
112*4882a593Smuzhiyun 		x_by = 1;
113*4882a593Smuzhiyun 	}
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	if (sh > dh) {
116*4882a593Smuzhiyun 		y_up = 0;
117*4882a593Smuzhiyun 		y_by = 0;
118*4882a593Smuzhiyun 	} else if (sh < dh) {
119*4882a593Smuzhiyun 		y_up = 1;
120*4882a593Smuzhiyun 		y_by = 0;
121*4882a593Smuzhiyun 	} else {
122*4882a593Smuzhiyun 		y_up = 0;
123*4882a593Smuzhiyun 		y_by = 1;
124*4882a593Smuzhiyun 	}
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	if (x_by == 1 && x_up == 0)
127*4882a593Smuzhiyun 		param_x = 0;
128*4882a593Smuzhiyun 	else if (x_up == 1 && x_by == 0) {
129*4882a593Smuzhiyun 		param_x = FACTOR_MAX * (sw - 1) / (dw - 1);
130*4882a593Smuzhiyun 		/* even multiples of 128 require a scaling factor -1 */
131*4882a593Smuzhiyun 		if ((FACTOR_MAX * (sw - 1)) % (dw - 1) == 0)
132*4882a593Smuzhiyun 			param_x = param_x - 1;
133*4882a593Smuzhiyun 	} else
134*4882a593Smuzhiyun 		param_x = FACTOR_MAX * (dw - 1) / (sw - 1) + 1;
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	if (y_by == 1 && y_up == 0)
137*4882a593Smuzhiyun 		param_y = 0;
138*4882a593Smuzhiyun 	else if (y_up == 1 && y_by == 0) {
139*4882a593Smuzhiyun 		param_y = FACTOR_MAX * (sh - 1) / (dh - 1);
140*4882a593Smuzhiyun 		/* even multiples of 128 require a scaling factor -1 */
141*4882a593Smuzhiyun 		if ((FACTOR_MAX * (sh - 1)) % (dh - 1) == 0)
142*4882a593Smuzhiyun 			param_y = param_y - 1;
143*4882a593Smuzhiyun 	} else
144*4882a593Smuzhiyun 		param_y = FACTOR_MAX * (dh - 1) / (sh - 1) + 1;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	switch (msg->win0.format) {
147*4882a593Smuzhiyun 	case RGA_FORMAT_RGBA_8888:
148*4882a593Smuzhiyun 		win_format = 0x8;
149*4882a593Smuzhiyun 		pixel_width = 4;
150*4882a593Smuzhiyun 		win_interleaved = 2;
151*4882a593Smuzhiyun 		break;
152*4882a593Smuzhiyun 	case RGA_FORMAT_BGRA_8888:
153*4882a593Smuzhiyun 		win_format = 0x6;
154*4882a593Smuzhiyun 		pixel_width = 4;
155*4882a593Smuzhiyun 		win_interleaved = 2;
156*4882a593Smuzhiyun 		break;
157*4882a593Smuzhiyun 	case RGA_FORMAT_ARGB_8888:
158*4882a593Smuzhiyun 		win_format = 0x9;
159*4882a593Smuzhiyun 		pixel_width = 4;
160*4882a593Smuzhiyun 		win_interleaved = 2;
161*4882a593Smuzhiyun 		break;
162*4882a593Smuzhiyun 	case RGA_FORMAT_ABGR_8888:
163*4882a593Smuzhiyun 		win_format = 0x7;
164*4882a593Smuzhiyun 		pixel_width = 4;
165*4882a593Smuzhiyun 		win_interleaved = 2;
166*4882a593Smuzhiyun 		break;
167*4882a593Smuzhiyun 	case RGA_FORMAT_RGB_888:
168*4882a593Smuzhiyun 		win_format = 0x5;
169*4882a593Smuzhiyun 		pixel_width = 3;
170*4882a593Smuzhiyun 		win_interleaved = 2;
171*4882a593Smuzhiyun 		win_pix_swp = 1;
172*4882a593Smuzhiyun 		break;
173*4882a593Smuzhiyun 	case RGA_FORMAT_BGR_888:
174*4882a593Smuzhiyun 		win_format = 0x5;
175*4882a593Smuzhiyun 		pixel_width = 3;
176*4882a593Smuzhiyun 		win_interleaved = 2;
177*4882a593Smuzhiyun 		break;
178*4882a593Smuzhiyun 	case RGA_FORMAT_RGB_565:
179*4882a593Smuzhiyun 		win_format = 0x4;
180*4882a593Smuzhiyun 		pixel_width = 2;
181*4882a593Smuzhiyun 		win_interleaved = 2;
182*4882a593Smuzhiyun 		win_pix_swp = 1;
183*4882a593Smuzhiyun 		break;
184*4882a593Smuzhiyun 	case RGA_FORMAT_BGR_565:
185*4882a593Smuzhiyun 		win_format = 0x4;
186*4882a593Smuzhiyun 		pixel_width = 2;
187*4882a593Smuzhiyun 		win_interleaved = 2;
188*4882a593Smuzhiyun 		break;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	case RGA_FORMAT_YVYU_422:
191*4882a593Smuzhiyun 		win_format = 0x1;
192*4882a593Smuzhiyun 		pixel_width = 2;
193*4882a593Smuzhiyun 		win_pix_swp = 1;
194*4882a593Smuzhiyun 		win_yc_swp = 1;
195*4882a593Smuzhiyun 		win_interleaved = 2;
196*4882a593Smuzhiyun 		break;
197*4882a593Smuzhiyun 	case RGA_FORMAT_VYUY_422:
198*4882a593Smuzhiyun 		win_format = 0x1;
199*4882a593Smuzhiyun 		pixel_width = 2;
200*4882a593Smuzhiyun 		win_pix_swp = 1;
201*4882a593Smuzhiyun 		win_yc_swp = 0;
202*4882a593Smuzhiyun 		win_interleaved = 2;
203*4882a593Smuzhiyun 		break;
204*4882a593Smuzhiyun 	case RGA_FORMAT_YUYV_422:
205*4882a593Smuzhiyun 		win_format = 0x1;
206*4882a593Smuzhiyun 		pixel_width = 2;
207*4882a593Smuzhiyun 		win_pix_swp = 0;
208*4882a593Smuzhiyun 		win_yc_swp = 1;
209*4882a593Smuzhiyun 		win_interleaved = 2;
210*4882a593Smuzhiyun 		break;
211*4882a593Smuzhiyun 	case RGA_FORMAT_UYVY_422:
212*4882a593Smuzhiyun 		win_format = 0x1;
213*4882a593Smuzhiyun 		pixel_width = 2;
214*4882a593Smuzhiyun 		win_pix_swp = 0;
215*4882a593Smuzhiyun 		win_yc_swp = 0;
216*4882a593Smuzhiyun 		win_interleaved = 2;
217*4882a593Smuzhiyun 		break;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_422_SP:
220*4882a593Smuzhiyun 		win_format = 0x1;
221*4882a593Smuzhiyun 		break;
222*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_420_SP:
223*4882a593Smuzhiyun 		win_format = 0x0;
224*4882a593Smuzhiyun 		break;
225*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_422_SP:
226*4882a593Smuzhiyun 		win_format = 0x1;
227*4882a593Smuzhiyun 		win_pix_swp = 1;
228*4882a593Smuzhiyun 		break;
229*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_420_SP:
230*4882a593Smuzhiyun 		win_format = 0x0;
231*4882a593Smuzhiyun 		win_pix_swp = 1;
232*4882a593Smuzhiyun 		break;
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_420_SP_10B:
235*4882a593Smuzhiyun 		win_format = 0x2;
236*4882a593Smuzhiyun 		yuv10 = 1;
237*4882a593Smuzhiyun 		break;
238*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_420_SP_10B:
239*4882a593Smuzhiyun 		win_format = 0x2;
240*4882a593Smuzhiyun 		yuv10 = 1;
241*4882a593Smuzhiyun 		win_pix_swp = 1;
242*4882a593Smuzhiyun 		break;
243*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_422_SP_10B:
244*4882a593Smuzhiyun 		win_format = 0x3;
245*4882a593Smuzhiyun 		yuv10 = 1;
246*4882a593Smuzhiyun 		break;
247*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_422_SP_10B:
248*4882a593Smuzhiyun 		win_format = 0x3;
249*4882a593Smuzhiyun 		yuv10 = 1;
250*4882a593Smuzhiyun 		win_pix_swp = 1;
251*4882a593Smuzhiyun 		break;
252*4882a593Smuzhiyun 	};
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	if (rga_is_rgb_format(msg->win0.format) &&
255*4882a593Smuzhiyun 	    rga_is_yuv_format(msg->wr.format))
256*4882a593Smuzhiyun 		win_r2y = 1;
257*4882a593Smuzhiyun 	if (rga_is_yuv_format(msg->win0.format) &&
258*4882a593Smuzhiyun 	    rga_is_rgb_format(msg->wr.format))
259*4882a593Smuzhiyun 		win_y2r = 1;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	reg =
262*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_R2Y_EN)) |
263*4882a593Smuzhiyun 		 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_R2Y_EN(win_r2y)));
264*4882a593Smuzhiyun 	reg =
265*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_Y2R_EN)) |
266*4882a593Smuzhiyun 		 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_Y2R_EN(win_y2r)));
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	reg =
269*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_PIC_FORMAT)) |
270*4882a593Smuzhiyun 		 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_PIC_FORMAT(win_format)));
271*4882a593Smuzhiyun 	reg =
272*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_PIX_SWAP)) |
273*4882a593Smuzhiyun 		 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_PIX_SWAP(win_pix_swp)));
274*4882a593Smuzhiyun 	reg =
275*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_YC_SWAP)) |
276*4882a593Smuzhiyun 		 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_YC_SWAP(win_yc_swp)));
277*4882a593Smuzhiyun 	reg =
278*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_RD_FORMAT)) |
279*4882a593Smuzhiyun 		 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_RD_FORMAT(win_interleaved)));
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	if (win_r2y == 1) {
282*4882a593Smuzhiyun 		reg =
283*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_CSC_MODE)) |
284*4882a593Smuzhiyun 			(s_RGA3_WIN0_RD_CTRL_SW_WIN0_CSC_MODE(msg->win0.r2y_mode)));
285*4882a593Smuzhiyun 	} else if (win_y2r == 1) {
286*4882a593Smuzhiyun 		reg =
287*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_CSC_MODE)) |
288*4882a593Smuzhiyun 			(s_RGA3_WIN0_RD_CTRL_SW_WIN0_CSC_MODE(msg->win0.y2r_mode)));
289*4882a593Smuzhiyun 	}
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	/* rotate & mirror */
292*4882a593Smuzhiyun 	if (msg->win0.rotate_mode == 1) {
293*4882a593Smuzhiyun 		reg =
294*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_ROT)) |
295*4882a593Smuzhiyun 			 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_ROT(rotate_mode)));
296*4882a593Smuzhiyun 		reg =
297*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_XMIRROR)) |
298*4882a593Smuzhiyun 			 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_XMIRROR(xmirror)));
299*4882a593Smuzhiyun 		reg =
300*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_YMIRROR)) |
301*4882a593Smuzhiyun 			 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_YMIRROR(ymirror)));
302*4882a593Smuzhiyun 	}
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	/* scale */
305*4882a593Smuzhiyun 	*bRGA3_WIN0_SCL_FAC = param_x | param_y << 16;
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	reg =
308*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_HOR_BY)) |
309*4882a593Smuzhiyun 			(s_RGA3_WIN0_RD_CTRL_SW_WIN0_HOR_BY(x_by)));
310*4882a593Smuzhiyun 	reg =
311*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_HOR_UP)) |
312*4882a593Smuzhiyun 			(s_RGA3_WIN0_RD_CTRL_SW_WIN0_HOR_UP(x_up)));
313*4882a593Smuzhiyun 	reg =
314*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_VER_BY)) |
315*4882a593Smuzhiyun 			(s_RGA3_WIN0_RD_CTRL_SW_WIN0_VER_BY(y_by)));
316*4882a593Smuzhiyun 	reg =
317*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_VER_UP)) |
318*4882a593Smuzhiyun 			(s_RGA3_WIN0_RD_CTRL_SW_WIN0_VER_UP(y_up)));
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	/* rd_mode */
321*4882a593Smuzhiyun 	reg =
322*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_RD_MODE)) |
323*4882a593Smuzhiyun 		 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_RD_MODE(msg->win0.rd_mode)));
324*4882a593Smuzhiyun 	/* win0 enable */
325*4882a593Smuzhiyun 	reg =
326*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_ENABLE)) |
327*4882a593Smuzhiyun 		 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_ENABLE(msg->win0.enable)));
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	reg =
330*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_YUV10B_COMPACT)) |
331*4882a593Smuzhiyun 		 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_YUV10B_COMPACT(1)));
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	/* Only on raster mode, yuv 10bit can change to compact or set endian */
334*4882a593Smuzhiyun 	if (msg->win0.rd_mode == RGA_RASTER_MODE && yuv10 == 1) {
335*4882a593Smuzhiyun 		reg =
336*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_YUV10B_COMPACT)) |
337*4882a593Smuzhiyun 			 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_YUV10B_COMPACT
338*4882a593Smuzhiyun 			 (msg->win0.is_10b_compact)));
339*4882a593Smuzhiyun 		reg =
340*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_ENDIAN_MODE)) |
341*4882a593Smuzhiyun 			 (s_RGA3_WIN0_RD_CTRL_SW_WIN0_ENDIAN_MODE
342*4882a593Smuzhiyun 			 (msg->win0.is_10b_endian)));
343*4882a593Smuzhiyun 	}
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	*bRGA3_WIN0_RD_CTRL = reg;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	switch (msg->win0.rd_mode) {
348*4882a593Smuzhiyun 	case 0: /* raster */
349*4882a593Smuzhiyun 		stride = (((msg->win0.vir_w * pixel_width) + 15) & ~15) >> 2;
350*4882a593Smuzhiyun 		if (rga_is_yuv420_semi_planar_format(msg->win0.format))
351*4882a593Smuzhiyun 			uv_stride = ((msg->win0.vir_w + 15) & ~15) >> 2;
352*4882a593Smuzhiyun 		else
353*4882a593Smuzhiyun 			uv_stride = stride;
354*4882a593Smuzhiyun 		break;
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	case 1: /* fbc */
357*4882a593Smuzhiyun 		stride = ((msg->win0.vir_w + 15) & ~15) >> 2;
358*4882a593Smuzhiyun 		if (rga_is_yuv420_semi_planar_format(msg->win0.format))
359*4882a593Smuzhiyun 			uv_stride = ((msg->win0.vir_w + 15) & ~15) >> 2;
360*4882a593Smuzhiyun 		else
361*4882a593Smuzhiyun 			uv_stride = stride;
362*4882a593Smuzhiyun 		break;
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	case 2: /* tile 8*8 */
365*4882a593Smuzhiyun 		/*
366*4882a593Smuzhiyun 		 * tile 8*8 mode 8 lines of data are read/written at one time,
367*4882a593Smuzhiyun 		 * so stride needs * 8. YUV420 only has 4 lines of UV data, so
368*4882a593Smuzhiyun 		 * it needs to >>1.
369*4882a593Smuzhiyun 		 */
370*4882a593Smuzhiyun 		stride = (((msg->win0.vir_w * pixel_width * 8) + 15) & ~15) >> 2;
371*4882a593Smuzhiyun 		if (rga_is_yuv420_semi_planar_format(msg->win0.format))
372*4882a593Smuzhiyun 			uv_stride = ((((msg->win0.vir_w * 8) + 15) & ~15) >> 1) >> 2;
373*4882a593Smuzhiyun 		else
374*4882a593Smuzhiyun 			uv_stride = stride;
375*4882a593Smuzhiyun 		break;
376*4882a593Smuzhiyun 	}
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	*bRGA3_WIN0_Y_BASE = (u32) msg->win0.yrgb_addr;
379*4882a593Smuzhiyun 	*bRGA3_WIN0_U_BASE = (u32) msg->win0.uv_addr;
380*4882a593Smuzhiyun 	*bRGA3_WIN0_V_BASE = (u32) msg->win0.v_addr;
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	*bRGA3_WIN0_VIR_STRIDE = stride;
383*4882a593Smuzhiyun 	*bRGA3_WIN0_UV_VIR_STRIDE = uv_stride;
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	*bRGA3_WIN0_ACT_OFF = msg->win0.x_offset | (msg->win0.y_offset << 16);
386*4882a593Smuzhiyun 	/* fbcd offset */
387*4882a593Smuzhiyun 	/*
388*4882a593Smuzhiyun 	 *	*bRGA3_WIN0_FBC_OFF = msg->win0.fbc_x_offset |
389*4882a593Smuzhiyun 	 *		 (msg->win0.fbc_y_offset << 16);
390*4882a593Smuzhiyun 	 */
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 	/* do not use win0 src size except fbcd */
393*4882a593Smuzhiyun 	/* in FBCD, src_width needs to be aligned at 16 */
394*4882a593Smuzhiyun 	*bRGA3_WIN0_SRC_SIZE = ALIGN(msg->win0.src_act_w + msg->win0.x_offset, 16) |
395*4882a593Smuzhiyun 			       (ALIGN(msg->win0.y_offset + msg->win0.src_act_h, 16) << 16);
396*4882a593Smuzhiyun 	*bRGA3_WIN0_ACT_SIZE =
397*4882a593Smuzhiyun 		msg->win0.src_act_w | (msg->win0.src_act_h << 16);
398*4882a593Smuzhiyun 	*bRGA3_WIN0_DST_SIZE =
399*4882a593Smuzhiyun 		msg->win0.dst_act_w | (msg->win0.dst_act_h << 16);
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun 
RGA3_set_reg_win1_info(u8 * base,struct rga3_req * msg)402*4882a593Smuzhiyun static void RGA3_set_reg_win1_info(u8 *base, struct rga3_req *msg)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun 	u32 *bRGA3_WIN1_RD_CTRL;
405*4882a593Smuzhiyun 	u32 *bRGA3_WIN1_Y_BASE, *bRGA3_WIN1_U_BASE, *bRGA3_WIN1_V_BASE;
406*4882a593Smuzhiyun 	u32 *bRGA3_WIN1_VIR_STRIDE;
407*4882a593Smuzhiyun 	u32 *bRGA3_WIN1_UV_VIR_STRIDE;
408*4882a593Smuzhiyun 	u32 *bRGA3_WIN1_SRC_SIZE;
409*4882a593Smuzhiyun 	u32 *bRGA3_WIN1_ACT_OFF;
410*4882a593Smuzhiyun 	u32 *bRGA3_WIN1_ACT_SIZE;
411*4882a593Smuzhiyun 	u32 *bRGA3_WIN1_DST_SIZE;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	u32 *bRGA3_WIN1_SCL_FAC;
414*4882a593Smuzhiyun 	/* Not used yet. */
415*4882a593Smuzhiyun 	// u32 *bRGA3_WIN1_FBC_OFF;
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	u32 sw = 0, sh = 0;
418*4882a593Smuzhiyun 	u32 dw = 0, dh = 0;
419*4882a593Smuzhiyun 	u32 param_x = 0, param_y = 0;
420*4882a593Smuzhiyun 	u8 x_up = 0, y_up = 0, x_by = 0, y_by = 0;
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	u32 reg = 0;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	u8 win_format = 0;
425*4882a593Smuzhiyun 	u8 win_yc_swp = 0;
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	/* rb swap on RGB, uv swap on YUV */
428*4882a593Smuzhiyun 	u8 win_pix_swp = 0;
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	/*
431*4882a593Smuzhiyun 	 * 1: Semi planar, for yuv 4:2:x
432*4882a593Smuzhiyun 	 * 2: Interleaved (yuyv), for yuv422 8bit only ,RGB
433*4882a593Smuzhiyun 	 */
434*4882a593Smuzhiyun 	u8 win_interleaved = 1;
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	u8 pixel_width = 1;
437*4882a593Smuzhiyun 	u8 yuv10 = 0;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	/* enable r2y or y2r */
440*4882a593Smuzhiyun 	u8 win_r2y = 0;
441*4882a593Smuzhiyun 	u8 win_y2r = 0;
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	u8 rotate_mode = 0;
444*4882a593Smuzhiyun 	u8 xmirror = 0;
445*4882a593Smuzhiyun 	u8 ymirror = 0;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	u32 stride = 0;
448*4882a593Smuzhiyun 	u32 uv_stride = 0;
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	bRGA3_WIN1_RD_CTRL = (u32 *) (base + RGA3_WIN1_RD_CTRL_OFFSET);
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 	bRGA3_WIN1_Y_BASE = (u32 *) (base + RGA3_WIN1_Y_BASE_OFFSET);
453*4882a593Smuzhiyun 	bRGA3_WIN1_U_BASE = (u32 *) (base + RGA3_WIN1_U_BASE_OFFSET);
454*4882a593Smuzhiyun 	bRGA3_WIN1_V_BASE = (u32 *) (base + RGA3_WIN1_V_BASE_OFFSET);
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	bRGA3_WIN1_VIR_STRIDE = (u32 *) (base + RGA3_WIN1_VIR_STRIDE_OFFSET);
457*4882a593Smuzhiyun 	bRGA3_WIN1_UV_VIR_STRIDE =
458*4882a593Smuzhiyun 		(u32 *) (base + RGA3_WIN1_UV_VIR_STRIDE_OFFSET);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	/* Not used yet. */
461*4882a593Smuzhiyun 	// bRGA3_WIN1_FBC_OFF = (u32 *) (base + RGA3_WIN1_FBC_OFF_OFFSET);
462*4882a593Smuzhiyun 	bRGA3_WIN1_ACT_OFF = (u32 *) (base + RGA3_WIN1_ACT_OFF_OFFSET);
463*4882a593Smuzhiyun 	bRGA3_WIN1_SRC_SIZE = (u32 *) (base + RGA3_WIN1_SRC_SIZE_OFFSET);
464*4882a593Smuzhiyun 	bRGA3_WIN1_ACT_SIZE = (u32 *) (base + RGA3_WIN1_ACT_SIZE_OFFSET);
465*4882a593Smuzhiyun 	bRGA3_WIN1_DST_SIZE = (u32 *) (base + RGA3_WIN1_DST_SIZE_OFFSET);
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	bRGA3_WIN1_SCL_FAC = (u32 *) (base + RGA3_WIN1_SCL_FAC_OFFSET);
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	if (msg->win1.rotate_mode != 0) {
470*4882a593Smuzhiyun 		rotate_mode = msg->rotate_mode & RGA3_ROT_BIT_ROT_90 ? 1 : 0;
471*4882a593Smuzhiyun 		xmirror = msg->rotate_mode & RGA3_ROT_BIT_X_MIRROR ? 1 : 0;
472*4882a593Smuzhiyun 		ymirror = msg->rotate_mode & RGA3_ROT_BIT_Y_MIRROR ? 1 : 0;
473*4882a593Smuzhiyun 	}
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	/* scale */
476*4882a593Smuzhiyun 	dw = msg->win1.dst_act_w;
477*4882a593Smuzhiyun 	dh = msg->win1.dst_act_h;
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 	if (rotate_mode) {
480*4882a593Smuzhiyun 		sh = msg->win1.src_act_w;
481*4882a593Smuzhiyun 		sw = msg->win1.src_act_h;
482*4882a593Smuzhiyun 	} else {
483*4882a593Smuzhiyun 		sw = msg->win1.src_act_w;
484*4882a593Smuzhiyun 		sh = msg->win1.src_act_h;
485*4882a593Smuzhiyun 	}
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	if (sw > dw) {
488*4882a593Smuzhiyun 		x_up = 0;
489*4882a593Smuzhiyun 		x_by = 0;
490*4882a593Smuzhiyun 	} else if (sw < dw) {
491*4882a593Smuzhiyun 		x_up = 1;
492*4882a593Smuzhiyun 		x_by = 0;
493*4882a593Smuzhiyun 	} else {
494*4882a593Smuzhiyun 		x_up = 0;
495*4882a593Smuzhiyun 		x_by = 1;
496*4882a593Smuzhiyun 	}
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 	if (sh > dh) {
499*4882a593Smuzhiyun 		y_up = 0;
500*4882a593Smuzhiyun 		y_by = 0;
501*4882a593Smuzhiyun 	} else if (sh < dh) {
502*4882a593Smuzhiyun 		y_up = 1;
503*4882a593Smuzhiyun 		y_by = 0;
504*4882a593Smuzhiyun 	} else {
505*4882a593Smuzhiyun 		y_up = 0;
506*4882a593Smuzhiyun 		y_by = 1;
507*4882a593Smuzhiyun 	}
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	if (x_by == 1)
510*4882a593Smuzhiyun 		param_x = 0;
511*4882a593Smuzhiyun 	else if (x_up == 1) {
512*4882a593Smuzhiyun 		param_x = (FACTOR_MAX * (sw - 1)) / (dw - 1);
513*4882a593Smuzhiyun 		/* even multiples of 128 require a scaling factor -1 */
514*4882a593Smuzhiyun 		if ((FACTOR_MAX * (sw - 1)) % (dw - 1) == 0)
515*4882a593Smuzhiyun 			param_x = param_x - 1;
516*4882a593Smuzhiyun 	} else
517*4882a593Smuzhiyun 		param_x = (FACTOR_MAX * (dw - 1)) / (sw - 1) + 1;
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 	if (y_by == 1)
520*4882a593Smuzhiyun 		param_y = 0;
521*4882a593Smuzhiyun 	else if (y_up == 1) {
522*4882a593Smuzhiyun 		param_y = (FACTOR_MAX * (sh - 1)) / (dh - 1);
523*4882a593Smuzhiyun 		/* even multiples of 128 require a scaling factor -1 */
524*4882a593Smuzhiyun 		if ((FACTOR_MAX * (sh - 1)) % (dh - 1) == 0)
525*4882a593Smuzhiyun 			param_y = param_y - 1;
526*4882a593Smuzhiyun 	} else
527*4882a593Smuzhiyun 		param_y = (FACTOR_MAX * (dh - 1)) / (sh - 1) + 1;
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	switch (msg->win1.format) {
530*4882a593Smuzhiyun 	case RGA_FORMAT_RGBA_8888:
531*4882a593Smuzhiyun 		win_format = 0x8;
532*4882a593Smuzhiyun 		pixel_width = 4;
533*4882a593Smuzhiyun 		win_interleaved = 2;
534*4882a593Smuzhiyun 		break;
535*4882a593Smuzhiyun 	case RGA_FORMAT_BGRA_8888:
536*4882a593Smuzhiyun 		win_format = 0x6;
537*4882a593Smuzhiyun 		pixel_width = 4;
538*4882a593Smuzhiyun 		win_interleaved = 2;
539*4882a593Smuzhiyun 		break;
540*4882a593Smuzhiyun 	case RGA_FORMAT_ARGB_8888:
541*4882a593Smuzhiyun 		win_format = 0x9;
542*4882a593Smuzhiyun 		pixel_width = 4;
543*4882a593Smuzhiyun 		win_interleaved = 2;
544*4882a593Smuzhiyun 		break;
545*4882a593Smuzhiyun 	case RGA_FORMAT_ABGR_8888:
546*4882a593Smuzhiyun 		win_format = 0x7;
547*4882a593Smuzhiyun 		pixel_width = 4;
548*4882a593Smuzhiyun 		win_interleaved = 2;
549*4882a593Smuzhiyun 		break;
550*4882a593Smuzhiyun 	case RGA_FORMAT_RGB_888:
551*4882a593Smuzhiyun 		win_format = 0x5;
552*4882a593Smuzhiyun 		pixel_width = 3;
553*4882a593Smuzhiyun 		win_interleaved = 2;
554*4882a593Smuzhiyun 		win_pix_swp = 1;
555*4882a593Smuzhiyun 		break;
556*4882a593Smuzhiyun 	case RGA_FORMAT_BGR_888:
557*4882a593Smuzhiyun 		win_format = 0x5;
558*4882a593Smuzhiyun 		pixel_width = 3;
559*4882a593Smuzhiyun 		win_interleaved = 2;
560*4882a593Smuzhiyun 		break;
561*4882a593Smuzhiyun 	case RGA_FORMAT_RGB_565:
562*4882a593Smuzhiyun 		win_format = 0x4;
563*4882a593Smuzhiyun 		pixel_width = 2;
564*4882a593Smuzhiyun 		win_interleaved = 2;
565*4882a593Smuzhiyun 		win_pix_swp = 1;
566*4882a593Smuzhiyun 		break;
567*4882a593Smuzhiyun 	case RGA_FORMAT_BGR_565:
568*4882a593Smuzhiyun 		win_format = 0x4;
569*4882a593Smuzhiyun 		pixel_width = 2;
570*4882a593Smuzhiyun 		win_interleaved = 2;
571*4882a593Smuzhiyun 		break;
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	case RGA_FORMAT_YVYU_422:
574*4882a593Smuzhiyun 		win_format = 0x1;
575*4882a593Smuzhiyun 		pixel_width = 2;
576*4882a593Smuzhiyun 		win_pix_swp = 1;
577*4882a593Smuzhiyun 		win_yc_swp = 1;
578*4882a593Smuzhiyun 		win_interleaved = 2;
579*4882a593Smuzhiyun 		break;
580*4882a593Smuzhiyun 	case RGA_FORMAT_VYUY_422:
581*4882a593Smuzhiyun 		win_format = 0x1;
582*4882a593Smuzhiyun 		pixel_width = 2;
583*4882a593Smuzhiyun 		win_pix_swp = 1;
584*4882a593Smuzhiyun 		win_yc_swp = 0;
585*4882a593Smuzhiyun 		win_interleaved = 2;
586*4882a593Smuzhiyun 		break;
587*4882a593Smuzhiyun 	case RGA_FORMAT_YUYV_422:
588*4882a593Smuzhiyun 		win_format = 0x1;
589*4882a593Smuzhiyun 		pixel_width = 2;
590*4882a593Smuzhiyun 		win_pix_swp = 0;
591*4882a593Smuzhiyun 		win_yc_swp = 1;
592*4882a593Smuzhiyun 		win_interleaved = 2;
593*4882a593Smuzhiyun 		break;
594*4882a593Smuzhiyun 	case RGA_FORMAT_UYVY_422:
595*4882a593Smuzhiyun 		win_format = 0x1;
596*4882a593Smuzhiyun 		pixel_width = 2;
597*4882a593Smuzhiyun 		win_pix_swp = 0;
598*4882a593Smuzhiyun 		win_yc_swp = 0;
599*4882a593Smuzhiyun 		win_interleaved = 2;
600*4882a593Smuzhiyun 		break;
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_422_SP:
603*4882a593Smuzhiyun 		win_format = 0x1;
604*4882a593Smuzhiyun 		break;
605*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_420_SP:
606*4882a593Smuzhiyun 		win_format = 0x0;
607*4882a593Smuzhiyun 		break;
608*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_422_SP:
609*4882a593Smuzhiyun 		win_format = 0x1;
610*4882a593Smuzhiyun 		win_pix_swp = 1;
611*4882a593Smuzhiyun 		break;
612*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_420_SP:
613*4882a593Smuzhiyun 		win_format = 0x0;
614*4882a593Smuzhiyun 		win_pix_swp = 1;
615*4882a593Smuzhiyun 		break;
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_420_SP_10B:
618*4882a593Smuzhiyun 		win_format = 0x2;
619*4882a593Smuzhiyun 		yuv10 = 1;
620*4882a593Smuzhiyun 		break;
621*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_420_SP_10B:
622*4882a593Smuzhiyun 		win_format = 0x2;
623*4882a593Smuzhiyun 		win_pix_swp = 1;
624*4882a593Smuzhiyun 		yuv10 = 1;
625*4882a593Smuzhiyun 		break;
626*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_422_SP_10B:
627*4882a593Smuzhiyun 		win_format = 0x3;
628*4882a593Smuzhiyun 		yuv10 = 1;
629*4882a593Smuzhiyun 		break;
630*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_422_SP_10B:
631*4882a593Smuzhiyun 		win_format = 0x3;
632*4882a593Smuzhiyun 		win_pix_swp = 1;
633*4882a593Smuzhiyun 		yuv10 = 1;
634*4882a593Smuzhiyun 		break;
635*4882a593Smuzhiyun 	};
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 	if (rga_is_rgb_format(msg->win1.format) &&
638*4882a593Smuzhiyun 	    rga_is_yuv_format(msg->wr.format))
639*4882a593Smuzhiyun 		win_r2y = 1;
640*4882a593Smuzhiyun 	if (rga_is_yuv_format(msg->win1.format) &&
641*4882a593Smuzhiyun 	    rga_is_rgb_format(msg->wr.format))
642*4882a593Smuzhiyun 		win_y2r = 1;
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	reg =
645*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_R2Y_EN)) |
646*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_R2Y_EN(win_r2y)));
647*4882a593Smuzhiyun 	reg =
648*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_Y2R_EN)) |
649*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_Y2R_EN(win_y2r)));
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	reg =
652*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_PIC_FORMAT)) |
653*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_PIC_FORMAT(win_format)));
654*4882a593Smuzhiyun 	reg =
655*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_PIX_SWAP)) |
656*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_PIX_SWAP(win_pix_swp)));
657*4882a593Smuzhiyun 	reg =
658*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_YC_SWAP)) |
659*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_YC_SWAP(win_yc_swp)));
660*4882a593Smuzhiyun 	reg =
661*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_RD_FORMAT)) |
662*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_RD_FORMAT(win_interleaved)));
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun 	if (win_r2y == 1) {
665*4882a593Smuzhiyun 		reg =
666*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_CSC_MODE)) |
667*4882a593Smuzhiyun 			(s_RGA3_WIN0_RD_CTRL_SW_WIN0_CSC_MODE(msg->win1.r2y_mode)));
668*4882a593Smuzhiyun 	} else if (win_y2r == 1) {
669*4882a593Smuzhiyun 		reg =
670*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN0_RD_CTRL_SW_WIN0_CSC_MODE)) |
671*4882a593Smuzhiyun 			(s_RGA3_WIN0_RD_CTRL_SW_WIN0_CSC_MODE(msg->win1.y2r_mode)));
672*4882a593Smuzhiyun 	}
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun 	/* rotate & mirror */
675*4882a593Smuzhiyun 	reg =
676*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_ROT)) |
677*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_ROT(rotate_mode)));
678*4882a593Smuzhiyun 	reg =
679*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_XMIRROR)) |
680*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_XMIRROR(xmirror)));
681*4882a593Smuzhiyun 	reg =
682*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_YMIRROR)) |
683*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_YMIRROR(ymirror)));
684*4882a593Smuzhiyun 	//warning: TRM not complete
685*4882a593Smuzhiyun 	/* scale */
686*4882a593Smuzhiyun 	*bRGA3_WIN1_SCL_FAC = param_x | param_y << 16;
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	reg =
689*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_HOR_BY)) |
690*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_HOR_BY(x_by)));
691*4882a593Smuzhiyun 	reg =
692*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_HOR_UP)) |
693*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_HOR_UP(x_up)));
694*4882a593Smuzhiyun 	reg =
695*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_VER_BY)) |
696*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_VER_BY(y_by)));
697*4882a593Smuzhiyun 	reg =
698*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_VER_UP)) |
699*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_VER_UP(y_up)));
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	reg =
702*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_YUV10B_COMPACT)) |
703*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_YUV10B_COMPACT(1)));
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	/* Only on roster mode, yuv 10bit can change to compact or set endian */
706*4882a593Smuzhiyun 	if (msg->win1.rd_mode == RGA_RASTER_MODE && yuv10 == 1) {
707*4882a593Smuzhiyun 		reg =
708*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_YUV10B_COMPACT)) |
709*4882a593Smuzhiyun 			 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_YUV10B_COMPACT
710*4882a593Smuzhiyun 			 (msg->win1.is_10b_compact)));
711*4882a593Smuzhiyun 		reg =
712*4882a593Smuzhiyun 			((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_ENDIAN_MODE)) |
713*4882a593Smuzhiyun 			 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_ENDIAN_MODE
714*4882a593Smuzhiyun 			 (msg->win1.is_10b_endian)));
715*4882a593Smuzhiyun 	}
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	/* rd_mode */
718*4882a593Smuzhiyun 	reg =
719*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_RD_MODE)) |
720*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_RD_MODE(msg->win1.rd_mode)));
721*4882a593Smuzhiyun 	/* win1 enable */
722*4882a593Smuzhiyun 	reg =
723*4882a593Smuzhiyun 		((reg & (~m_RGA3_WIN1_RD_CTRL_SW_WIN1_ENABLE)) |
724*4882a593Smuzhiyun 		 (s_RGA3_WIN1_RD_CTRL_SW_WIN1_ENABLE(msg->win1.enable)));
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun 	*bRGA3_WIN1_RD_CTRL = reg;
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	switch (msg->win1.rd_mode) {
729*4882a593Smuzhiyun 	case 0: /* raster */
730*4882a593Smuzhiyun 		stride = (((msg->win1.vir_w * pixel_width) + 15) & ~15) >> 2;
731*4882a593Smuzhiyun 		if (rga_is_yuv420_semi_planar_format(msg->win1.format))
732*4882a593Smuzhiyun 			uv_stride = ((msg->win1.vir_w + 15) & ~15) >> 2;
733*4882a593Smuzhiyun 		else
734*4882a593Smuzhiyun 			uv_stride = stride;
735*4882a593Smuzhiyun 		break;
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun 	case 1: /* fbc */
738*4882a593Smuzhiyun 		stride = ((msg->win1.vir_w + 15) & ~15) >> 2;
739*4882a593Smuzhiyun 		if (rga_is_yuv420_semi_planar_format(msg->win1.format))
740*4882a593Smuzhiyun 			uv_stride = ((msg->win1.vir_w + 15) & ~15) >> 2;
741*4882a593Smuzhiyun 		else
742*4882a593Smuzhiyun 			uv_stride = stride;
743*4882a593Smuzhiyun 		break;
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	case 2: /* tile 8*8 */
746*4882a593Smuzhiyun 		stride = (((msg->win1.vir_w * pixel_width * 8) + 15) & ~15) >> 2;
747*4882a593Smuzhiyun 		if (rga_is_yuv420_semi_planar_format(msg->win1.format))
748*4882a593Smuzhiyun 			uv_stride = ((((msg->win1.vir_w * 8) + 15) & ~15) >> 1) >> 2;
749*4882a593Smuzhiyun 		else
750*4882a593Smuzhiyun 			uv_stride = stride;
751*4882a593Smuzhiyun 		break;
752*4882a593Smuzhiyun 	}
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 	*bRGA3_WIN1_Y_BASE = (u32) msg->win1.yrgb_addr;
755*4882a593Smuzhiyun 	*bRGA3_WIN1_U_BASE = (u32) msg->win1.uv_addr;
756*4882a593Smuzhiyun 	*bRGA3_WIN1_V_BASE = (u32) msg->win1.v_addr;
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun 	*bRGA3_WIN1_VIR_STRIDE = stride;
759*4882a593Smuzhiyun 	*bRGA3_WIN1_UV_VIR_STRIDE = uv_stride;
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun 	*bRGA3_WIN1_ACT_OFF = msg->win1.x_offset | (msg->win1.y_offset << 16);
762*4882a593Smuzhiyun 	/* fbcd offset */
763*4882a593Smuzhiyun 	/*
764*4882a593Smuzhiyun 	 *		 *bRGA3_WIN1_FBC_OFF = msg->win1.fbc_x_offset |
765*4882a593Smuzhiyun 	 *			(msg->win1.fbc_y_offset << 16);
766*4882a593Smuzhiyun 	 */
767*4882a593Smuzhiyun 
768*4882a593Smuzhiyun 	/* do not use win1 src size except fbcd */
769*4882a593Smuzhiyun 	*bRGA3_WIN1_SRC_SIZE = (msg->win1.src_act_w +
770*4882a593Smuzhiyun 		msg->win1.x_offset) | ((msg->win1.src_act_h +
771*4882a593Smuzhiyun 		msg->win1.y_offset) << 16);
772*4882a593Smuzhiyun 	*bRGA3_WIN1_ACT_SIZE =
773*4882a593Smuzhiyun 		msg->win1.src_act_w | (msg->win1.src_act_h << 16);
774*4882a593Smuzhiyun 	*bRGA3_WIN1_DST_SIZE =
775*4882a593Smuzhiyun 		msg->win1.dst_act_w | (msg->win1.dst_act_h << 16);
776*4882a593Smuzhiyun }
777*4882a593Smuzhiyun 
RGA3_set_reg_wr_info(u8 * base,struct rga3_req * msg)778*4882a593Smuzhiyun static void RGA3_set_reg_wr_info(u8 *base, struct rga3_req *msg)
779*4882a593Smuzhiyun {
780*4882a593Smuzhiyun 	u32 *bRGA3_WR_RD_CTRL;
781*4882a593Smuzhiyun 	u32 *bRGA3_WR_Y_BASE, *bRGA3_WR_U_BASE, *bRGA3_WR_V_BASE;
782*4882a593Smuzhiyun 	u32 *bRGA3_WR_VIR_STRIDE;
783*4882a593Smuzhiyun 	u32 *bRGA3_WR_PL_VIR_STRIDE;
784*4882a593Smuzhiyun 	u32 *bRGA3_WR_FBCD_CTRL;
785*4882a593Smuzhiyun 
786*4882a593Smuzhiyun 	u32 reg = 0;
787*4882a593Smuzhiyun 	u32 fbcd_reg = 0;
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	u8 wr_format = 0;
790*4882a593Smuzhiyun 	u8 wr_yc_swp = 0;
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 	/* rb swap on RGB, uv swap on YUV */
793*4882a593Smuzhiyun 	u8 wr_pix_swp = 0;
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun 	u8 pixel_width = 1;
796*4882a593Smuzhiyun 	u8 yuv10 = 0;
797*4882a593Smuzhiyun 
798*4882a593Smuzhiyun 	/*
799*4882a593Smuzhiyun 	 * 1: Semi planar, for yuv 4:2:x
800*4882a593Smuzhiyun 	 * 2: Interleaved (yuyv), for yuv422 8bit only ,RGB
801*4882a593Smuzhiyun 	 */
802*4882a593Smuzhiyun 	u8 wr_interleaved = 1;
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun 	u32 stride = 0;
805*4882a593Smuzhiyun 	u32 uv_stride = 0;
806*4882a593Smuzhiyun 
807*4882a593Smuzhiyun 	u32 vir_h = 0;
808*4882a593Smuzhiyun 
809*4882a593Smuzhiyun 	bRGA3_WR_RD_CTRL = (u32 *) (base + RGA3_WR_CTRL_OFFSET);
810*4882a593Smuzhiyun 	bRGA3_WR_FBCD_CTRL = (u32 *) (base + RGA3_WR_FBCE_CTRL_OFFSET);
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 	bRGA3_WR_Y_BASE = (u32 *) (base + RGA3_WR_Y_BASE_OFFSET);
813*4882a593Smuzhiyun 	bRGA3_WR_U_BASE = (u32 *) (base + RGA3_WR_U_BASE_OFFSET);
814*4882a593Smuzhiyun 	bRGA3_WR_V_BASE = (u32 *) (base + RGA3_WR_V_BASE_OFFSET);
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun 	bRGA3_WR_VIR_STRIDE = (u32 *) (base + RGA3_WR_VIR_STRIDE_OFFSET);
817*4882a593Smuzhiyun 	bRGA3_WR_PL_VIR_STRIDE =
818*4882a593Smuzhiyun 		(u32 *) (base + RGA3_WR_PL_VIR_STRIDE_OFFSET);
819*4882a593Smuzhiyun 
820*4882a593Smuzhiyun 	switch (msg->wr.format) {
821*4882a593Smuzhiyun 	case RGA_FORMAT_RGBA_8888:
822*4882a593Smuzhiyun 		wr_format = 0x6;
823*4882a593Smuzhiyun 		pixel_width = 4;
824*4882a593Smuzhiyun 		wr_interleaved = 2;
825*4882a593Smuzhiyun 		wr_pix_swp = 1;
826*4882a593Smuzhiyun 		break;
827*4882a593Smuzhiyun 	case RGA_FORMAT_BGRA_8888:
828*4882a593Smuzhiyun 		wr_format = 0x6;
829*4882a593Smuzhiyun 		pixel_width = 4;
830*4882a593Smuzhiyun 		wr_interleaved = 2;
831*4882a593Smuzhiyun 		break;
832*4882a593Smuzhiyun 	case RGA_FORMAT_RGB_888:
833*4882a593Smuzhiyun 		wr_format = 0x5;
834*4882a593Smuzhiyun 		pixel_width = 3;
835*4882a593Smuzhiyun 		wr_interleaved = 2;
836*4882a593Smuzhiyun 		wr_pix_swp = 1;
837*4882a593Smuzhiyun 		break;
838*4882a593Smuzhiyun 	case RGA_FORMAT_BGR_888:
839*4882a593Smuzhiyun 		wr_format = 0x5;
840*4882a593Smuzhiyun 		pixel_width = 3;
841*4882a593Smuzhiyun 		wr_interleaved = 2;
842*4882a593Smuzhiyun 		break;
843*4882a593Smuzhiyun 	case RGA_FORMAT_RGB_565:
844*4882a593Smuzhiyun 		wr_format = 0x4;
845*4882a593Smuzhiyun 		pixel_width = 2;
846*4882a593Smuzhiyun 		wr_interleaved = 2;
847*4882a593Smuzhiyun 		wr_pix_swp = 1;
848*4882a593Smuzhiyun 		break;
849*4882a593Smuzhiyun 	case RGA_FORMAT_BGR_565:
850*4882a593Smuzhiyun 		wr_format = 0x4;
851*4882a593Smuzhiyun 		pixel_width = 2;
852*4882a593Smuzhiyun 		wr_interleaved = 2;
853*4882a593Smuzhiyun 		break;
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun 	case RGA_FORMAT_YVYU_422:
856*4882a593Smuzhiyun 		wr_format = 0x1;
857*4882a593Smuzhiyun 		pixel_width = 2;
858*4882a593Smuzhiyun 		wr_pix_swp = 1;
859*4882a593Smuzhiyun 		wr_yc_swp = 1;
860*4882a593Smuzhiyun 		wr_interleaved = 2;
861*4882a593Smuzhiyun 		break;
862*4882a593Smuzhiyun 	case RGA_FORMAT_VYUY_422:
863*4882a593Smuzhiyun 		wr_format = 0x1;
864*4882a593Smuzhiyun 		pixel_width = 2;
865*4882a593Smuzhiyun 		wr_pix_swp = 1;
866*4882a593Smuzhiyun 		wr_yc_swp = 0;
867*4882a593Smuzhiyun 		wr_interleaved = 2;
868*4882a593Smuzhiyun 		break;
869*4882a593Smuzhiyun 	case RGA_FORMAT_YUYV_422:
870*4882a593Smuzhiyun 		wr_format = 0x1;
871*4882a593Smuzhiyun 		pixel_width = 2;
872*4882a593Smuzhiyun 		wr_pix_swp = 0;
873*4882a593Smuzhiyun 		wr_yc_swp = 1;
874*4882a593Smuzhiyun 		wr_interleaved = 2;
875*4882a593Smuzhiyun 		break;
876*4882a593Smuzhiyun 	case RGA_FORMAT_UYVY_422:
877*4882a593Smuzhiyun 		wr_format = 0x1;
878*4882a593Smuzhiyun 		pixel_width = 2;
879*4882a593Smuzhiyun 		wr_pix_swp = 0;
880*4882a593Smuzhiyun 		wr_yc_swp = 0;
881*4882a593Smuzhiyun 		wr_interleaved = 2;
882*4882a593Smuzhiyun 		break;
883*4882a593Smuzhiyun 
884*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_422_SP:
885*4882a593Smuzhiyun 		wr_format = 0x1;
886*4882a593Smuzhiyun 		break;
887*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_420_SP:
888*4882a593Smuzhiyun 		wr_format = 0x0;
889*4882a593Smuzhiyun 		break;
890*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_422_SP:
891*4882a593Smuzhiyun 		wr_format = 0x1;
892*4882a593Smuzhiyun 		wr_pix_swp = 1;
893*4882a593Smuzhiyun 		break;
894*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_420_SP:
895*4882a593Smuzhiyun 		wr_format = 0x0;
896*4882a593Smuzhiyun 		wr_pix_swp = 1;
897*4882a593Smuzhiyun 		break;
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_420_SP_10B:
900*4882a593Smuzhiyun 		wr_format = 0x2;
901*4882a593Smuzhiyun 		yuv10 = 1;
902*4882a593Smuzhiyun 		break;
903*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_420_SP_10B:
904*4882a593Smuzhiyun 		wr_format = 0x2;
905*4882a593Smuzhiyun 		wr_pix_swp = 1;
906*4882a593Smuzhiyun 		yuv10 = 1;
907*4882a593Smuzhiyun 		break;
908*4882a593Smuzhiyun 	case RGA_FORMAT_YCbCr_422_SP_10B:
909*4882a593Smuzhiyun 		wr_format = 0x3;
910*4882a593Smuzhiyun 		yuv10 = 1;
911*4882a593Smuzhiyun 		break;
912*4882a593Smuzhiyun 	case RGA_FORMAT_YCrCb_422_SP_10B:
913*4882a593Smuzhiyun 		wr_format = 0x3;
914*4882a593Smuzhiyun 		wr_pix_swp = 1;
915*4882a593Smuzhiyun 		yuv10 = 1;
916*4882a593Smuzhiyun 		break;
917*4882a593Smuzhiyun 	};
918*4882a593Smuzhiyun 
919*4882a593Smuzhiyun 	reg =
920*4882a593Smuzhiyun 		((reg & (~m_RGA3_WR_CTRL_SW_WR_PIC_FORMAT)) |
921*4882a593Smuzhiyun 		 (s_RGA3_WR_CTRL_SW_WR_PIC_FORMAT(wr_format)));
922*4882a593Smuzhiyun 	reg =
923*4882a593Smuzhiyun 		((reg & (~m_RGA3_WR_CTRL_SW_WR_PIX_SWAP)) |
924*4882a593Smuzhiyun 		 (s_RGA3_WR_CTRL_SW_WR_PIX_SWAP(wr_pix_swp)));
925*4882a593Smuzhiyun 	reg =
926*4882a593Smuzhiyun 		((reg & (~m_RGA3_WR_CTRL_SW_WR_YC_SWAP)) |
927*4882a593Smuzhiyun 		 (s_RGA3_WR_CTRL_SW_WR_YC_SWAP(wr_yc_swp)));
928*4882a593Smuzhiyun 	reg =
929*4882a593Smuzhiyun 		((reg & (~m_RGA3_WR_CTRL_SW_WR_FORMAT)) |
930*4882a593Smuzhiyun 		 (s_RGA3_WR_CTRL_SW_WR_FORMAT(wr_interleaved)));
931*4882a593Smuzhiyun 	reg =
932*4882a593Smuzhiyun 		((reg & (~m_RGA3_WR_CTRL_SW_WR_FBCE_SPARSE_EN)) |
933*4882a593Smuzhiyun 		 (s_RGA3_WR_CTRL_SW_WR_FBCE_SPARSE_EN(1)));
934*4882a593Smuzhiyun 
935*4882a593Smuzhiyun 	reg =
936*4882a593Smuzhiyun 		((reg & (~m_RGA3_WR_CTRL_SW_OUTSTANDING_MAX)) |
937*4882a593Smuzhiyun 		 (s_RGA3_WR_CTRL_SW_OUTSTANDING_MAX(0xf)));
938*4882a593Smuzhiyun 
939*4882a593Smuzhiyun 	reg =
940*4882a593Smuzhiyun 		((reg & (~m_RGA3_WR_CTRL_SW_WR_YUV10B_COMPACT)) |
941*4882a593Smuzhiyun 		 (s_RGA3_WR_CTRL_SW_WR_YUV10B_COMPACT(1)));
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun 	/* Only on roster mode, yuv 10bit can change to compact or set endian */
944*4882a593Smuzhiyun 	if (msg->wr.rd_mode == 0 && yuv10 == 1) {
945*4882a593Smuzhiyun 		reg =
946*4882a593Smuzhiyun 			((reg & (~m_RGA3_WR_CTRL_SW_WR_YUV10B_COMPACT)) |
947*4882a593Smuzhiyun 			 (s_RGA3_WR_CTRL_SW_WR_YUV10B_COMPACT
948*4882a593Smuzhiyun 			 (msg->wr.is_10b_compact)));
949*4882a593Smuzhiyun 		reg =
950*4882a593Smuzhiyun 			((reg & (~m_RGA3_WR_CTRL_SW_WR_ENDIAN_MODE)) |
951*4882a593Smuzhiyun 			 (s_RGA3_WR_CTRL_SW_WR_ENDIAN_MODE
952*4882a593Smuzhiyun 			 (msg->wr.is_10b_endian)));
953*4882a593Smuzhiyun 	}
954*4882a593Smuzhiyun 
955*4882a593Smuzhiyun 	/* rd_mode */
956*4882a593Smuzhiyun 	reg =
957*4882a593Smuzhiyun 		((reg & (~m_RGA3_WR_CTRL_SW_WR_MODE)) |
958*4882a593Smuzhiyun 		 (s_RGA3_WR_CTRL_SW_WR_MODE(msg->wr.rd_mode)));
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	fbcd_reg = ((fbcd_reg & (~m_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_HOFF_DISS)) |
961*4882a593Smuzhiyun 		 (s_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_HOFF_DISS(0)));
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun 	*bRGA3_WR_RD_CTRL = reg;
964*4882a593Smuzhiyun 	*bRGA3_WR_FBCD_CTRL = fbcd_reg;
965*4882a593Smuzhiyun 
966*4882a593Smuzhiyun 	switch (msg->wr.rd_mode) {
967*4882a593Smuzhiyun 	case 0: /* raster */
968*4882a593Smuzhiyun 		stride = (((msg->wr.vir_w * pixel_width) + 15) & ~15) >> 2;
969*4882a593Smuzhiyun 		uv_stride = ((msg->wr.vir_w + 15) & ~15) >> 2;
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun 		*bRGA3_WR_U_BASE = (u32) msg->wr.uv_addr;
972*4882a593Smuzhiyun 
973*4882a593Smuzhiyun 		break;
974*4882a593Smuzhiyun 
975*4882a593Smuzhiyun 	case 1: /* fbc */
976*4882a593Smuzhiyun 		stride = ((msg->wr.vir_w + 15) & ~15) >> 2;
977*4882a593Smuzhiyun 		/* need to calculate fbcd header size */
978*4882a593Smuzhiyun 		vir_h = ((msg->wr.vir_h + 15) & ~15);
979*4882a593Smuzhiyun 
980*4882a593Smuzhiyun 		/* RGBA8888 */
981*4882a593Smuzhiyun 		if (wr_format == 0x6)
982*4882a593Smuzhiyun 			uv_stride = ((msg->wr.vir_w + 15) & ~15);
983*4882a593Smuzhiyun 		/* RGB888 */
984*4882a593Smuzhiyun 		else if (wr_format == 0x5)
985*4882a593Smuzhiyun 			uv_stride = (((msg->wr.vir_w + 15) & ~15) >> 2) * 3;
986*4882a593Smuzhiyun 		/* RGB565, yuv422 8bit, yuv420 10bit */
987*4882a593Smuzhiyun 		else if (wr_format == 0x4 || wr_format == 0x1 || wr_format == 0x2)
988*4882a593Smuzhiyun 			uv_stride = ((msg->wr.vir_w + 15) & ~15) >> 1;
989*4882a593Smuzhiyun 		/* yuv420 8bit */
990*4882a593Smuzhiyun 		else if (wr_format == 0x0)
991*4882a593Smuzhiyun 			uv_stride = (((msg->wr.vir_w + 15) & ~15) >> 3) * 3;
992*4882a593Smuzhiyun 		/* yuv422 10bit */
993*4882a593Smuzhiyun 		else if (wr_format == 0x3)
994*4882a593Smuzhiyun 			uv_stride = (((msg->wr.vir_w + 15) & ~15) >> 3) * 5;
995*4882a593Smuzhiyun 
996*4882a593Smuzhiyun 		*bRGA3_WR_U_BASE = (u32) (msg->wr.uv_addr + ((stride * vir_h)>>2));
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun 		break;
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun 	case 2: /* tile 8*8 */
1001*4882a593Smuzhiyun 		stride = (((msg->wr.vir_w * pixel_width * 8) + 15) & ~15) >> 2;
1002*4882a593Smuzhiyun 		if (rga_is_yuv420_semi_planar_format(msg->win0.format))
1003*4882a593Smuzhiyun 			uv_stride = ((((msg->wr.vir_w * 8) + 15) & ~15) >> 1) >> 2;
1004*4882a593Smuzhiyun 		else
1005*4882a593Smuzhiyun 			uv_stride = stride;
1006*4882a593Smuzhiyun 
1007*4882a593Smuzhiyun 		*bRGA3_WR_U_BASE = (u32) msg->wr.uv_addr;
1008*4882a593Smuzhiyun 		break;
1009*4882a593Smuzhiyun 	}
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun 	*bRGA3_WR_Y_BASE = (u32) msg->wr.yrgb_addr;
1012*4882a593Smuzhiyun 	*bRGA3_WR_V_BASE = (u32) msg->wr.v_addr;
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 	*bRGA3_WR_VIR_STRIDE = stride;
1015*4882a593Smuzhiyun 	*bRGA3_WR_PL_VIR_STRIDE = uv_stride;
1016*4882a593Smuzhiyun }
1017*4882a593Smuzhiyun 
RGA3_set_reg_overlap_info(u8 * base,struct rga3_req * msg)1018*4882a593Smuzhiyun static void RGA3_set_reg_overlap_info(u8 *base, struct rga3_req *msg)
1019*4882a593Smuzhiyun {
1020*4882a593Smuzhiyun 	u32 *bRGA_OVERLAP_TOP_CTRL;
1021*4882a593Smuzhiyun 	u32 *bRGA_OVERLAP_BOT_CTRL;
1022*4882a593Smuzhiyun 	u32 *bRGA_OVERLAP_TOP_ALPHA;
1023*4882a593Smuzhiyun 	u32 *bRGA_OVERLAP_BOT_ALPHA;
1024*4882a593Smuzhiyun 	u32 *bRGA_OVERLAP_TOP_KEY_MIN;
1025*4882a593Smuzhiyun 	u32 *bRGA_OVERLAP_TOP_KEY_MAX;
1026*4882a593Smuzhiyun 
1027*4882a593Smuzhiyun 	u32 *bRGA_OVERLAP_CTRL;
1028*4882a593Smuzhiyun 	u32 *bRGA3_OVLP_OFF;
1029*4882a593Smuzhiyun 
1030*4882a593Smuzhiyun 	u32 reg;
1031*4882a593Smuzhiyun 	union rga3_color_ctrl top_color_ctrl, bottom_color_ctrl;
1032*4882a593Smuzhiyun 	union rga3_alpha_ctrl top_alpha_ctrl, bottom_alpha_ctrl;
1033*4882a593Smuzhiyun 	struct rga_alpha_config *config;
1034*4882a593Smuzhiyun 
1035*4882a593Smuzhiyun 	bRGA_OVERLAP_TOP_CTRL = (u32 *) (base + RGA3_OVLP_TOP_CTRL_OFFSET);
1036*4882a593Smuzhiyun 	bRGA_OVERLAP_BOT_CTRL = (u32 *) (base + RGA3_OVLP_BOT_CTRL_OFFSET);
1037*4882a593Smuzhiyun 	bRGA_OVERLAP_TOP_ALPHA = (u32 *) (base + RGA3_OVLP_TOP_ALPHA_OFFSET);
1038*4882a593Smuzhiyun 	bRGA_OVERLAP_BOT_ALPHA = (u32 *) (base + RGA3_OVLP_BOT_ALPHA_OFFSET);
1039*4882a593Smuzhiyun 
1040*4882a593Smuzhiyun 	bRGA_OVERLAP_CTRL = (u32 *) (base + RGA3_OVLP_CTRL_OFFSET);
1041*4882a593Smuzhiyun 	bRGA3_OVLP_OFF = (u32 *) (base + RGA3_OVLP_OFF_OFFSET);
1042*4882a593Smuzhiyun 
1043*4882a593Smuzhiyun 	/* Alpha blend */
1044*4882a593Smuzhiyun 	/*bot -> win0(dst), top -> win1(src). */
1045*4882a593Smuzhiyun 	top_color_ctrl.value = 0;
1046*4882a593Smuzhiyun 	bottom_color_ctrl.value = 0;
1047*4882a593Smuzhiyun 	top_alpha_ctrl.value = 0;
1048*4882a593Smuzhiyun 	bottom_alpha_ctrl.value = 0;
1049*4882a593Smuzhiyun 	config = &msg->alpha_config;
1050*4882a593Smuzhiyun 
1051*4882a593Smuzhiyun 	if (config->fg_pixel_alpha_en)
1052*4882a593Smuzhiyun 		top_color_ctrl.bits.blend_mode =
1053*4882a593Smuzhiyun 			config->fg_global_alpha_en ? RGA_ALPHA_PER_PIXEL_GLOBAL :
1054*4882a593Smuzhiyun 			RGA_ALPHA_PER_PIXEL;
1055*4882a593Smuzhiyun 	else
1056*4882a593Smuzhiyun 		top_color_ctrl.bits.blend_mode = RGA_ALPHA_GLOBAL;
1057*4882a593Smuzhiyun 
1058*4882a593Smuzhiyun 	if (config->bg_pixel_alpha_en)
1059*4882a593Smuzhiyun 		bottom_color_ctrl.bits.blend_mode =
1060*4882a593Smuzhiyun 			config->bg_global_alpha_en ? RGA_ALPHA_PER_PIXEL_GLOBAL :
1061*4882a593Smuzhiyun 			RGA_ALPHA_PER_PIXEL;
1062*4882a593Smuzhiyun 	else
1063*4882a593Smuzhiyun 		bottom_color_ctrl.bits.blend_mode = RGA_ALPHA_GLOBAL;
1064*4882a593Smuzhiyun 
1065*4882a593Smuzhiyun 	/*
1066*4882a593Smuzhiyun 	 * Since the hardware uses 256 as 1, the original alpha value needs to
1067*4882a593Smuzhiyun 	 * be + (alpha >> 7).
1068*4882a593Smuzhiyun 	 */
1069*4882a593Smuzhiyun 	top_color_ctrl.bits.alpha_cal_mode = RGA_ALPHA_SATURATION;
1070*4882a593Smuzhiyun 	bottom_color_ctrl.bits.alpha_cal_mode = RGA_ALPHA_SATURATION;
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	top_color_ctrl.bits.global_alpha = config->fg_global_alpha_value;
1073*4882a593Smuzhiyun 	bottom_color_ctrl.bits.global_alpha = config->fg_global_alpha_value;
1074*4882a593Smuzhiyun 
1075*4882a593Smuzhiyun 	/* porter duff alpha enable */
1076*4882a593Smuzhiyun 	switch (config->mode) {
1077*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_SRC:
1078*4882a593Smuzhiyun 		/*
1079*4882a593Smuzhiyun 		 * SRC mode:
1080*4882a593Smuzhiyun 		 *	Sf = 1, Df = 0;
1081*4882a593Smuzhiyun 		 *	[Rc,Ra] = [Sc,Sa];
1082*4882a593Smuzhiyun 		 */
1083*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1084*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_ONE;
1085*4882a593Smuzhiyun 
1086*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1087*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_ZERO;
1088*4882a593Smuzhiyun 
1089*4882a593Smuzhiyun 		break;
1090*4882a593Smuzhiyun 
1091*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_DST:
1092*4882a593Smuzhiyun 		/*
1093*4882a593Smuzhiyun 		 * SRC mode:
1094*4882a593Smuzhiyun 		 *	Sf = 0, Df = 1;
1095*4882a593Smuzhiyun 		 *	[Rc,Ra] = [Dc,Da];
1096*4882a593Smuzhiyun 		 */
1097*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1098*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_ZERO;
1099*4882a593Smuzhiyun 
1100*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1101*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_ONE;
1102*4882a593Smuzhiyun 
1103*4882a593Smuzhiyun 		break;
1104*4882a593Smuzhiyun 
1105*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_SRC_OVER:
1106*4882a593Smuzhiyun 		/*
1107*4882a593Smuzhiyun 		 * SRC-OVER mode:
1108*4882a593Smuzhiyun 		 *	Sf = 1, Df = (1 - Sa)
1109*4882a593Smuzhiyun 		 *	[Rc,Ra] = [ Sc + (1 - Sa) * Dc, Sa + (1 - Sa) * Da ]
1110*4882a593Smuzhiyun 		 */
1111*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1112*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_ONE;
1113*4882a593Smuzhiyun 
1114*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1115*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
1116*4882a593Smuzhiyun 
1117*4882a593Smuzhiyun 		break;
1118*4882a593Smuzhiyun 
1119*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_DST_OVER:
1120*4882a593Smuzhiyun 		/*
1121*4882a593Smuzhiyun 		 * DST-OVER mode:
1122*4882a593Smuzhiyun 		 *	Sf = (1 - Da) , Df = 1
1123*4882a593Smuzhiyun 		 *	[Rc,Ra] = [ Sc * (1 - Da) + Dc, Sa * (1 - Da) + Da ]
1124*4882a593Smuzhiyun 		 */
1125*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1126*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1129*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_ONE;
1130*4882a593Smuzhiyun 
1131*4882a593Smuzhiyun 		break;
1132*4882a593Smuzhiyun 
1133*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_SRC_IN:
1134*4882a593Smuzhiyun 		/*
1135*4882a593Smuzhiyun 		 * SRC-IN mode:
1136*4882a593Smuzhiyun 		 *	Sf = Da , Df = 0
1137*4882a593Smuzhiyun 		 *	[Rc,Ra] = [ Sc * Da, Sa * Da ]
1138*4882a593Smuzhiyun 		 */
1139*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1140*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE;
1141*4882a593Smuzhiyun 
1142*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1143*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_ZERO;
1144*4882a593Smuzhiyun 
1145*4882a593Smuzhiyun 		break;
1146*4882a593Smuzhiyun 
1147*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_DST_IN:
1148*4882a593Smuzhiyun 		/*
1149*4882a593Smuzhiyun 		 * DST-IN mode:
1150*4882a593Smuzhiyun 		 *	Sf = 0 , Df = Sa
1151*4882a593Smuzhiyun 		 *	[Rc,Ra] = [ Dc * Sa, Da * Sa ]
1152*4882a593Smuzhiyun 		 */
1153*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1154*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_ZERO;
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1157*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE;
1158*4882a593Smuzhiyun 
1159*4882a593Smuzhiyun 		break;
1160*4882a593Smuzhiyun 
1161*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_SRC_OUT:
1162*4882a593Smuzhiyun 		/*
1163*4882a593Smuzhiyun 		 * SRC-OUT mode:
1164*4882a593Smuzhiyun 		 *	Sf = (1 - Da) , Df = 0
1165*4882a593Smuzhiyun 		 *	[Rc,Ra] = [ Sc * (1 - Da), Sa * (1 - Da) ]
1166*4882a593Smuzhiyun 		 */
1167*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1168*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
1169*4882a593Smuzhiyun 
1170*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1171*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_ZERO;
1172*4882a593Smuzhiyun 
1173*4882a593Smuzhiyun 		break;
1174*4882a593Smuzhiyun 
1175*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_DST_OUT:
1176*4882a593Smuzhiyun 		/*
1177*4882a593Smuzhiyun 		 * DST-OUT mode:
1178*4882a593Smuzhiyun 		 *	Sf = 0 , Df = (1 - Sa)
1179*4882a593Smuzhiyun 		 *	[Rc,Ra] = [ Dc * (1 - Sa), Da * (1 - Sa) ]
1180*4882a593Smuzhiyun 		 */
1181*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1182*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_ZERO;
1183*4882a593Smuzhiyun 
1184*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1185*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
1186*4882a593Smuzhiyun 
1187*4882a593Smuzhiyun 		break;
1188*4882a593Smuzhiyun 
1189*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_SRC_ATOP:
1190*4882a593Smuzhiyun 		/*
1191*4882a593Smuzhiyun 		 * SRC-ATOP mode:
1192*4882a593Smuzhiyun 		 *	Sf = Da , Df = (1 - Sa)
1193*4882a593Smuzhiyun 		 *	[Rc,Ra] = [ Sc * Da + Dc * (1 - Sa), Sa * Da + Da * (1 - Sa) ]
1194*4882a593Smuzhiyun 		 */
1195*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1196*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE;
1197*4882a593Smuzhiyun 
1198*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1199*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
1200*4882a593Smuzhiyun 
1201*4882a593Smuzhiyun 		break;
1202*4882a593Smuzhiyun 
1203*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_DST_ATOP:
1204*4882a593Smuzhiyun 		/*
1205*4882a593Smuzhiyun 		 * DST-ATOP mode:
1206*4882a593Smuzhiyun 		 *	Sf = (1 - Da) , Df = Sa
1207*4882a593Smuzhiyun 		 *	[Rc,Ra] = [ Sc * (1 - Da) + Dc * Sa, Sa * (1 - Da) + Da * Sa ]
1208*4882a593Smuzhiyun 		 */
1209*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1210*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1213*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE;
1214*4882a593Smuzhiyun 
1215*4882a593Smuzhiyun 		break;
1216*4882a593Smuzhiyun 
1217*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_XOR:
1218*4882a593Smuzhiyun 		/*
1219*4882a593Smuzhiyun 		 * DST-XOR mode:
1220*4882a593Smuzhiyun 		 *	Sf = (1 - Da) , Df = (1 - Sa)
1221*4882a593Smuzhiyun 		 *	[Rc,Ra] = [ Sc * (1 - Da) + Dc * (1 - Sa), Sa * (1 - Da) + Da * (1 - Sa) ]
1222*4882a593Smuzhiyun 		 */
1223*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1224*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
1225*4882a593Smuzhiyun 
1226*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1227*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_OPPOSITE_INVERSE;
1228*4882a593Smuzhiyun 
1229*4882a593Smuzhiyun 		break;
1230*4882a593Smuzhiyun 
1231*4882a593Smuzhiyun 	case RGA_ALPHA_BLEND_CLEAR:
1232*4882a593Smuzhiyun 		/*
1233*4882a593Smuzhiyun 		 * DST-CLEAR mode:
1234*4882a593Smuzhiyun 		 *	Sf = 0 , Df = 0
1235*4882a593Smuzhiyun 		 *	[Rc,Ra] = [ 0, 0 ]
1236*4882a593Smuzhiyun 		 */
1237*4882a593Smuzhiyun 		top_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1238*4882a593Smuzhiyun 		top_color_ctrl.bits.factor_mode = RGA_ALPHA_ZERO;
1239*4882a593Smuzhiyun 
1240*4882a593Smuzhiyun 		bottom_color_ctrl.bits.alpha_mode = RGA_ALPHA_STRAIGHT;
1241*4882a593Smuzhiyun 		bottom_color_ctrl.bits.factor_mode = RGA_ALPHA_ZERO;
1242*4882a593Smuzhiyun 
1243*4882a593Smuzhiyun 		break;
1244*4882a593Smuzhiyun 
1245*4882a593Smuzhiyun 	default:
1246*4882a593Smuzhiyun 		break;
1247*4882a593Smuzhiyun 	}
1248*4882a593Smuzhiyun 
1249*4882a593Smuzhiyun 	if (!config->enable && msg->abb_alpha_pass) {
1250*4882a593Smuzhiyun 		/*
1251*4882a593Smuzhiyun 		 * enabled by default bot_blend_m1 && bot_alpha_cal_m1 for src channel(win0)
1252*4882a593Smuzhiyun 		 * In ABB mode, the number will be fetched according to 16*16, so it needs to
1253*4882a593Smuzhiyun 		 * be enabled top_blend_m1 && top_alpha_cal_m1 for dst channel(wr).
1254*4882a593Smuzhiyun 		 */
1255*4882a593Smuzhiyun 		top_color_ctrl.bits.color_mode = RGA_ALPHA_PRE_MULTIPLIED;
1256*4882a593Smuzhiyun 
1257*4882a593Smuzhiyun 		top_alpha_ctrl.bits.blend_mode = RGA_ALPHA_PER_PIXEL;
1258*4882a593Smuzhiyun 		top_alpha_ctrl.bits.alpha_cal_mode = RGA_ALPHA_NO_SATURATION;
1259*4882a593Smuzhiyun 
1260*4882a593Smuzhiyun 		bottom_color_ctrl.bits.color_mode = RGA_ALPHA_PRE_MULTIPLIED;
1261*4882a593Smuzhiyun 
1262*4882a593Smuzhiyun 		bottom_alpha_ctrl.bits.blend_mode = RGA_ALPHA_PER_PIXEL;
1263*4882a593Smuzhiyun 		bottom_alpha_ctrl.bits.alpha_cal_mode = RGA_ALPHA_NO_SATURATION;
1264*4882a593Smuzhiyun 	} else {
1265*4882a593Smuzhiyun 		top_color_ctrl.bits.color_mode =
1266*4882a593Smuzhiyun 			config->fg_pre_multiplied ?
1267*4882a593Smuzhiyun 				RGA_ALPHA_PRE_MULTIPLIED : RGA_ALPHA_NO_PRE_MULTIPLIED;
1268*4882a593Smuzhiyun 
1269*4882a593Smuzhiyun 		top_alpha_ctrl.bits.blend_mode = top_color_ctrl.bits.blend_mode;
1270*4882a593Smuzhiyun 		top_alpha_ctrl.bits.alpha_cal_mode = top_color_ctrl.bits.alpha_cal_mode;
1271*4882a593Smuzhiyun 		top_alpha_ctrl.bits.alpha_mode = top_color_ctrl.bits.alpha_mode;
1272*4882a593Smuzhiyun 		top_alpha_ctrl.bits.factor_mode = top_color_ctrl.bits.factor_mode;
1273*4882a593Smuzhiyun 
1274*4882a593Smuzhiyun 		bottom_color_ctrl.bits.color_mode =
1275*4882a593Smuzhiyun 			config->bg_pre_multiplied ?
1276*4882a593Smuzhiyun 				RGA_ALPHA_PRE_MULTIPLIED : RGA_ALPHA_NO_PRE_MULTIPLIED;
1277*4882a593Smuzhiyun 
1278*4882a593Smuzhiyun 		bottom_alpha_ctrl.bits.blend_mode = bottom_color_ctrl.bits.blend_mode;
1279*4882a593Smuzhiyun 		bottom_alpha_ctrl.bits.alpha_cal_mode = bottom_color_ctrl.bits.alpha_cal_mode;
1280*4882a593Smuzhiyun 		bottom_alpha_ctrl.bits.alpha_mode = bottom_color_ctrl.bits.alpha_mode;
1281*4882a593Smuzhiyun 		bottom_alpha_ctrl.bits.factor_mode = bottom_color_ctrl.bits.factor_mode;
1282*4882a593Smuzhiyun 	}
1283*4882a593Smuzhiyun 
1284*4882a593Smuzhiyun 	*bRGA_OVERLAP_TOP_CTRL = top_color_ctrl.value;
1285*4882a593Smuzhiyun 	*bRGA_OVERLAP_BOT_CTRL = bottom_color_ctrl.value;
1286*4882a593Smuzhiyun 	*bRGA_OVERLAP_TOP_ALPHA = top_alpha_ctrl.value;
1287*4882a593Smuzhiyun 	*bRGA_OVERLAP_BOT_ALPHA = bottom_alpha_ctrl.value;
1288*4882a593Smuzhiyun 
1289*4882a593Smuzhiyun 	/* set RGA_OVERLAP_CTRL */
1290*4882a593Smuzhiyun 	reg = 0;
1291*4882a593Smuzhiyun 	/* color key */
1292*4882a593Smuzhiyun 	bRGA_OVERLAP_TOP_KEY_MIN =
1293*4882a593Smuzhiyun 		(u32 *) (base + RGA3_OVLP_TOP_KEY_MIN_OFFSET);
1294*4882a593Smuzhiyun 	bRGA_OVERLAP_TOP_KEY_MAX =
1295*4882a593Smuzhiyun 		(u32 *) (base + RGA3_OVLP_TOP_KEY_MAX_OFFSET);
1296*4882a593Smuzhiyun 
1297*4882a593Smuzhiyun 	/*
1298*4882a593Smuzhiyun 	 * YG : value		 (0:9)
1299*4882a593Smuzhiyun 	 * UB : value >> 10	 (10:19)
1300*4882a593Smuzhiyun 	 * VG : value >> 20	 (20:29)
1301*4882a593Smuzhiyun 	 */
1302*4882a593Smuzhiyun 	if (msg->color_key_min > 0 || msg->color_key_max > 0) {
1303*4882a593Smuzhiyun 		*bRGA_OVERLAP_TOP_KEY_MIN = msg->color_key_min;
1304*4882a593Smuzhiyun 		*bRGA_OVERLAP_TOP_KEY_MAX = msg->color_key_max;
1305*4882a593Smuzhiyun 		reg = ((reg & (~m_RGA3_OVLP_CTRL_SW_TOP_KEY_EN)) |
1306*4882a593Smuzhiyun 			 (s_RGA3_OVLP_CTRL_SW_TOP_KEY_EN(1)));
1307*4882a593Smuzhiyun 	}
1308*4882a593Smuzhiyun 
1309*4882a593Smuzhiyun 	/* 1: ABB mode, 0: ABC mode, ABB cannot support fbc in&out */
1310*4882a593Smuzhiyun 	if (msg->win0.yrgb_addr == msg->wr.yrgb_addr)
1311*4882a593Smuzhiyun 		reg = ((reg & (~m_RGA3_OVLP_CTRL_SW_OVLP_MODE)) |
1312*4882a593Smuzhiyun 			(s_RGA3_OVLP_CTRL_SW_OVLP_MODE(1)));
1313*4882a593Smuzhiyun 
1314*4882a593Smuzhiyun 	/* 1: yuv field, 0: rgb field */
1315*4882a593Smuzhiyun 	if (rga_is_yuv_format(msg->wr.format))
1316*4882a593Smuzhiyun 		reg = ((reg & (~m_RGA3_OVLP_CTRL_SW_OVLP_FIELD)) |
1317*4882a593Smuzhiyun 			 (s_RGA3_OVLP_CTRL_SW_OVLP_FIELD(1)));
1318*4882a593Smuzhiyun 
1319*4882a593Smuzhiyun 	/*
1320*4882a593Smuzhiyun 	 * warning: if m1 & m0 need config split,need to redesign
1321*4882a593Smuzhiyun 	 * this judge, which consider RGBA8888 format
1322*4882a593Smuzhiyun 	 */
1323*4882a593Smuzhiyun 	reg = ((reg & (~m_RGA3_OVLP_CTRL_SW_TOP_ALPHA_EN)) |
1324*4882a593Smuzhiyun 	       (s_RGA3_OVLP_CTRL_SW_TOP_ALPHA_EN(config->enable)));
1325*4882a593Smuzhiyun 
1326*4882a593Smuzhiyun 	*bRGA_OVERLAP_CTRL = reg;
1327*4882a593Smuzhiyun 
1328*4882a593Smuzhiyun 	*bRGA3_OVLP_OFF = msg->wr.x_offset | (msg->wr.y_offset << 16);
1329*4882a593Smuzhiyun }
1330*4882a593Smuzhiyun 
rga3_gen_reg_info(u8 * base,struct rga3_req * msg)1331*4882a593Smuzhiyun static int rga3_gen_reg_info(u8 *base, struct rga3_req *msg)
1332*4882a593Smuzhiyun {
1333*4882a593Smuzhiyun 	switch (msg->render_mode) {
1334*4882a593Smuzhiyun 	case BITBLT_MODE:
1335*4882a593Smuzhiyun 		RGA3_set_reg_win0_info(base, msg);
1336*4882a593Smuzhiyun 		RGA3_set_reg_win1_info(base, msg);
1337*4882a593Smuzhiyun 		RGA3_set_reg_overlap_info(base, msg);
1338*4882a593Smuzhiyun 		RGA3_set_reg_wr_info(base, msg);
1339*4882a593Smuzhiyun 		break;
1340*4882a593Smuzhiyun 	default:
1341*4882a593Smuzhiyun 		pr_err("error msg render mode %d\n", msg->render_mode);
1342*4882a593Smuzhiyun 		break;
1343*4882a593Smuzhiyun 	}
1344*4882a593Smuzhiyun 
1345*4882a593Smuzhiyun 	return 0;
1346*4882a593Smuzhiyun }
1347*4882a593Smuzhiyun 
addr_copy(struct rga_win_info_t * win,struct rga_img_info_t * img)1348*4882a593Smuzhiyun static void addr_copy(struct rga_win_info_t *win, struct rga_img_info_t *img)
1349*4882a593Smuzhiyun {
1350*4882a593Smuzhiyun 	win->yrgb_addr = img->yrgb_addr;
1351*4882a593Smuzhiyun 	win->uv_addr = img->uv_addr;
1352*4882a593Smuzhiyun 	win->v_addr = img->v_addr;
1353*4882a593Smuzhiyun 	win->enable = 1;
1354*4882a593Smuzhiyun }
1355*4882a593Smuzhiyun 
set_win_info(struct rga_win_info_t * win,struct rga_img_info_t * img)1356*4882a593Smuzhiyun static void set_win_info(struct rga_win_info_t *win, struct rga_img_info_t *img)
1357*4882a593Smuzhiyun {
1358*4882a593Smuzhiyun 	win->x_offset = img->x_offset;
1359*4882a593Smuzhiyun 	win->y_offset = img->y_offset;
1360*4882a593Smuzhiyun 	win->src_act_w = img->act_w;
1361*4882a593Smuzhiyun 	win->src_act_h = img->act_h;
1362*4882a593Smuzhiyun 	win->vir_w = img->vir_w;
1363*4882a593Smuzhiyun 	win->vir_h = img->vir_h;
1364*4882a593Smuzhiyun 	if (img->rd_mode == RGA_RASTER_MODE)
1365*4882a593Smuzhiyun 		win->rd_mode = 0;
1366*4882a593Smuzhiyun 	else if (img->rd_mode == RGA_FBC_MODE)
1367*4882a593Smuzhiyun 		win->rd_mode = 1;
1368*4882a593Smuzhiyun 	else if (img->rd_mode == RGA_TILE_MODE)
1369*4882a593Smuzhiyun 		win->rd_mode = 2;
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun 	switch (img->compact_mode) {
1372*4882a593Smuzhiyun 	case RGA_10BIT_INCOMPACT:
1373*4882a593Smuzhiyun 		win->is_10b_compact = 0;
1374*4882a593Smuzhiyun 		break;
1375*4882a593Smuzhiyun 	case RGA_10BIT_COMPACT:
1376*4882a593Smuzhiyun 	default:
1377*4882a593Smuzhiyun 		win->is_10b_compact = 1;
1378*4882a593Smuzhiyun 		break;
1379*4882a593Smuzhiyun 	}
1380*4882a593Smuzhiyun 
1381*4882a593Smuzhiyun 	win->is_10b_endian = img->is_10b_endian;
1382*4882a593Smuzhiyun }
1383*4882a593Smuzhiyun 
set_wr_info(struct rga_req * req_rga,struct rga3_req * req)1384*4882a593Smuzhiyun static void set_wr_info(struct rga_req *req_rga, struct rga3_req *req)
1385*4882a593Smuzhiyun {
1386*4882a593Smuzhiyun 	/* The output w/h are bound to the dst_act_w/h of win0. */
1387*4882a593Smuzhiyun 	req->wr.dst_act_w = req->win0.dst_act_w;
1388*4882a593Smuzhiyun 	req->wr.dst_act_h = req->win0.dst_act_h;
1389*4882a593Smuzhiyun 
1390*4882a593Smuzhiyun 	/* Some configurations need to be all equal to the output w/h. */
1391*4882a593Smuzhiyun 	req->wr.vir_w = req_rga->dst.vir_w;
1392*4882a593Smuzhiyun 	req->wr.vir_h = req_rga->dst.vir_h;
1393*4882a593Smuzhiyun 
1394*4882a593Smuzhiyun 	if (req_rga->dst.rd_mode == RGA_RASTER_MODE)
1395*4882a593Smuzhiyun 		req->wr.rd_mode = 0;
1396*4882a593Smuzhiyun 	else if (req_rga->dst.rd_mode == RGA_FBC_MODE)
1397*4882a593Smuzhiyun 		req->wr.rd_mode = 1;
1398*4882a593Smuzhiyun 	else if (req_rga->dst.rd_mode == RGA_TILE_MODE)
1399*4882a593Smuzhiyun 		req->wr.rd_mode = 2;
1400*4882a593Smuzhiyun 
1401*4882a593Smuzhiyun 	switch (req_rga->dst.compact_mode) {
1402*4882a593Smuzhiyun 	case RGA_10BIT_INCOMPACT:
1403*4882a593Smuzhiyun 		req->wr.is_10b_compact = 0;
1404*4882a593Smuzhiyun 		break;
1405*4882a593Smuzhiyun 	case RGA_10BIT_COMPACT:
1406*4882a593Smuzhiyun 	default:
1407*4882a593Smuzhiyun 		req->wr.is_10b_compact = 1;
1408*4882a593Smuzhiyun 		break;
1409*4882a593Smuzhiyun 	}
1410*4882a593Smuzhiyun 
1411*4882a593Smuzhiyun 	req->wr.is_10b_endian = req_rga->dst.is_10b_endian;
1412*4882a593Smuzhiyun }
1413*4882a593Smuzhiyun 
1414*4882a593Smuzhiyun /* TODO: common part */
rga_cmd_to_rga3_cmd(struct rga_req * req_rga,struct rga3_req * req)1415*4882a593Smuzhiyun static void rga_cmd_to_rga3_cmd(struct rga_req *req_rga, struct rga3_req *req)
1416*4882a593Smuzhiyun {
1417*4882a593Smuzhiyun 	struct rga_img_info_t tmp;
1418*4882a593Smuzhiyun 
1419*4882a593Smuzhiyun 	req->render_mode = BITBLT_MODE;
1420*4882a593Smuzhiyun 
1421*4882a593Smuzhiyun 	/* rotate & mirror */
1422*4882a593Smuzhiyun 	switch (req_rga->rotate_mode & 0x0f) {
1423*4882a593Smuzhiyun 	case 0x1:
1424*4882a593Smuzhiyun 		if (req_rga->sina == 65536 && req_rga->cosa == 0) {
1425*4882a593Smuzhiyun 			/* rot-90 */
1426*4882a593Smuzhiyun 			req->rotate_mode = RGA3_ROT_BIT_ROT_90;
1427*4882a593Smuzhiyun 		} else if (req_rga->sina == 0 && req_rga->cosa == -65536) {
1428*4882a593Smuzhiyun 			/* rot-180 = X-mirror + Y-mirror */
1429*4882a593Smuzhiyun 			req->rotate_mode = RGA3_ROT_BIT_X_MIRROR | RGA3_ROT_BIT_Y_MIRROR;
1430*4882a593Smuzhiyun 		} else if (req_rga->sina == -65536 && req_rga->cosa == 0) {
1431*4882a593Smuzhiyun 			/* rot-270 or -90 = rot-90 + X-mirror + Y-mirror */
1432*4882a593Smuzhiyun 			req->rotate_mode = RGA3_ROT_BIT_X_MIRROR | RGA3_ROT_BIT_Y_MIRROR |
1433*4882a593Smuzhiyun 					   RGA3_ROT_BIT_ROT_90;
1434*4882a593Smuzhiyun 		} else if (req_rga->sina == 0 && req_rga->cosa == 65536) {
1435*4882a593Smuzhiyun 			/* bypass */
1436*4882a593Smuzhiyun 			req->rotate_mode = 0;
1437*4882a593Smuzhiyun 		}
1438*4882a593Smuzhiyun 		break;
1439*4882a593Smuzhiyun 	case 0x2:
1440*4882a593Smuzhiyun 		/* X-mirror */
1441*4882a593Smuzhiyun 		req->rotate_mode = RGA3_ROT_BIT_X_MIRROR;
1442*4882a593Smuzhiyun 		break;
1443*4882a593Smuzhiyun 	case 0x3:
1444*4882a593Smuzhiyun 		/* Y-mirror */
1445*4882a593Smuzhiyun 		req->rotate_mode = RGA3_ROT_BIT_Y_MIRROR;
1446*4882a593Smuzhiyun 		break;
1447*4882a593Smuzhiyun 	case 0x4:
1448*4882a593Smuzhiyun 		/* X-mirror + Y-mirror */
1449*4882a593Smuzhiyun 		req->rotate_mode = RGA3_ROT_BIT_X_MIRROR | RGA3_ROT_BIT_Y_MIRROR;
1450*4882a593Smuzhiyun 		break;
1451*4882a593Smuzhiyun 	default:
1452*4882a593Smuzhiyun 		req->rotate_mode = 0;
1453*4882a593Smuzhiyun 		break;
1454*4882a593Smuzhiyun 	}
1455*4882a593Smuzhiyun 
1456*4882a593Smuzhiyun 	/* The upper four bits are only allowed to configure the mirror. */
1457*4882a593Smuzhiyun 	switch ((req_rga->rotate_mode & 0xf0) >> 4) {
1458*4882a593Smuzhiyun 	case 2:
1459*4882a593Smuzhiyun 		/* X-mirror */
1460*4882a593Smuzhiyun 		req->rotate_mode ^= RGA3_ROT_BIT_X_MIRROR;
1461*4882a593Smuzhiyun 		break;
1462*4882a593Smuzhiyun 	case 3:
1463*4882a593Smuzhiyun 		/* Y-mirror */
1464*4882a593Smuzhiyun 		req->rotate_mode ^= RGA3_ROT_BIT_Y_MIRROR;
1465*4882a593Smuzhiyun 		break;
1466*4882a593Smuzhiyun 	case 0x4:
1467*4882a593Smuzhiyun 		/* X-mirror + Y-mirror */
1468*4882a593Smuzhiyun 		req->rotate_mode ^= RGA3_ROT_BIT_X_MIRROR | RGA3_ROT_BIT_Y_MIRROR;
1469*4882a593Smuzhiyun 		break;
1470*4882a593Smuzhiyun 	}
1471*4882a593Smuzhiyun 
1472*4882a593Smuzhiyun 	req->win0_a_global_val = req_rga->alpha_global_value;
1473*4882a593Smuzhiyun 	req->win1_a_global_val = req_rga->alpha_global_value;
1474*4882a593Smuzhiyun 
1475*4882a593Smuzhiyun 	/* fixup yuv/rgb convert to rgba missing alpha channel */
1476*4882a593Smuzhiyun 	if (!(req_rga->alpha_rop_flag & 1)) {
1477*4882a593Smuzhiyun 		if (!rga_is_alpha_format(req_rga->src.format) &&
1478*4882a593Smuzhiyun 		    rga_is_alpha_format(req_rga->dst.format)) {
1479*4882a593Smuzhiyun 			req->alpha_config.fg_global_alpha_value = 0xff;
1480*4882a593Smuzhiyun 			req->alpha_config.bg_global_alpha_value = 0xff;
1481*4882a593Smuzhiyun 		}
1482*4882a593Smuzhiyun 	}
1483*4882a593Smuzhiyun 
1484*4882a593Smuzhiyun 	/* simple win can not support dst offset */
1485*4882a593Smuzhiyun 	if ((!((req_rga->alpha_rop_flag) & 1)) &&
1486*4882a593Smuzhiyun 	    (req_rga->dst.x_offset == 0 && req_rga->dst.y_offset == 0) &&
1487*4882a593Smuzhiyun 	    (req_rga->src.yrgb_addr != req_rga->dst.yrgb_addr)) {
1488*4882a593Smuzhiyun 		/*
1489*4882a593Smuzhiyun 		 * ABB mode Layer binding:
1490*4882a593Smuzhiyun 		 *     src => win0
1491*4882a593Smuzhiyun 		 *     dst => wr
1492*4882a593Smuzhiyun 		 */
1493*4882a593Smuzhiyun 
1494*4882a593Smuzhiyun 		/*
1495*4882a593Smuzhiyun 		 * enabled by default bot_blend_m1 && bot_alpha_cal_m1 for src channel(win0)
1496*4882a593Smuzhiyun 		 * In ABB mode, the number will be fetched according to 16*16, so it needs to
1497*4882a593Smuzhiyun 		 * be enabled top_blend_m1 && top_alpha_cal_m1 for dst channel(wr).
1498*4882a593Smuzhiyun 		 */
1499*4882a593Smuzhiyun 		if (rga_is_alpha_format(req_rga->src.format))
1500*4882a593Smuzhiyun 			req->abb_alpha_pass = true;
1501*4882a593Smuzhiyun 
1502*4882a593Smuzhiyun 		set_win_info(&req->win0, &req_rga->src);
1503*4882a593Smuzhiyun 
1504*4882a593Smuzhiyun 		/* enable win0 rotate */
1505*4882a593Smuzhiyun 		req->win0.rotate_mode = 1;
1506*4882a593Smuzhiyun 
1507*4882a593Smuzhiyun 		/* set win dst size */
1508*4882a593Smuzhiyun 		req->win0.dst_act_w = req_rga->dst.act_w;
1509*4882a593Smuzhiyun 		req->win0.dst_act_h = req_rga->dst.act_h;
1510*4882a593Smuzhiyun 
1511*4882a593Smuzhiyun 		addr_copy(&req->win0, &req_rga->src);
1512*4882a593Smuzhiyun 		addr_copy(&req->wr, &req_rga->dst);
1513*4882a593Smuzhiyun 
1514*4882a593Smuzhiyun 		req->win0.format = req_rga->src.format;
1515*4882a593Smuzhiyun 		req->wr.format = req_rga->dst.format;
1516*4882a593Smuzhiyun 	} else {
1517*4882a593Smuzhiyun 		/*
1518*4882a593Smuzhiyun 		 * ABC mode Layer binding:
1519*4882a593Smuzhiyun 		 *     src => win1
1520*4882a593Smuzhiyun 		 *     src1/dst => win0
1521*4882a593Smuzhiyun 		 *     dst => wr
1522*4882a593Smuzhiyun 		 */
1523*4882a593Smuzhiyun 
1524*4882a593Smuzhiyun 		/*
1525*4882a593Smuzhiyun 		 * enabled by default top_blend_m1 && top_alpha_cal_m1 for src channel(win1)
1526*4882a593Smuzhiyun 		 * In ABB mode, the number will be fetched according to 16*16, so it needs to
1527*4882a593Smuzhiyun 		 * be enabled bot_blend_m1 && bot_alpha_cal_m1 for src1/dst channel(win0).
1528*4882a593Smuzhiyun 		 */
1529*4882a593Smuzhiyun 		if (rga_is_alpha_format(req_rga->src.format))
1530*4882a593Smuzhiyun 			req->abb_alpha_pass = true;
1531*4882a593Smuzhiyun 
1532*4882a593Smuzhiyun 		if (req_rga->pat.yrgb_addr != 0) {
1533*4882a593Smuzhiyun 			if (req_rga->src.yrgb_addr == req_rga->dst.yrgb_addr) {
1534*4882a593Smuzhiyun 				/* Convert ABC mode to ABB mode. */
1535*4882a593Smuzhiyun 				memcpy(&req_rga->src, &req_rga->pat, sizeof(req_rga->src));
1536*4882a593Smuzhiyun 				memset(&req_rga->pat, 0x0, sizeof(req_rga->pat));
1537*4882a593Smuzhiyun 				req_rga->bsfilter_flag = 0;
1538*4882a593Smuzhiyun 
1539*4882a593Smuzhiyun 				rga_swap_pd_mode(req_rga);
1540*4882a593Smuzhiyun 			} else if ((req_rga->dst.x_offset + req_rga->src.act_w >
1541*4882a593Smuzhiyun 				    req_rga->pat.act_w) ||
1542*4882a593Smuzhiyun 				   (req_rga->dst.y_offset + req_rga->src.act_h >
1543*4882a593Smuzhiyun 				    req_rga->pat.act_h)) {
1544*4882a593Smuzhiyun 				/* wr_offset + win1.act_size need > win0.act_size */
1545*4882a593Smuzhiyun 				memcpy(&tmp, &req_rga->src, sizeof(tmp));
1546*4882a593Smuzhiyun 				memcpy(&req_rga->src, &req_rga->pat, sizeof(req_rga->src));
1547*4882a593Smuzhiyun 				memcpy(&req_rga->pat, &tmp, sizeof(req_rga->pat));
1548*4882a593Smuzhiyun 
1549*4882a593Smuzhiyun 				rga_swap_pd_mode(req_rga);
1550*4882a593Smuzhiyun 			}
1551*4882a593Smuzhiyun 		}
1552*4882a593Smuzhiyun 
1553*4882a593Smuzhiyun 		set_win_info(&req->win1, &req_rga->src);
1554*4882a593Smuzhiyun 
1555*4882a593Smuzhiyun 		/* enable win1 rotate */
1556*4882a593Smuzhiyun 		req->win1.rotate_mode = 1;
1557*4882a593Smuzhiyun 
1558*4882a593Smuzhiyun 		addr_copy(&req->win1, &req_rga->src);
1559*4882a593Smuzhiyun 		addr_copy(&req->wr, &req_rga->dst);
1560*4882a593Smuzhiyun 
1561*4882a593Smuzhiyun 		req->win1.format = req_rga->src.format;
1562*4882a593Smuzhiyun 		req->wr.format = req_rga->dst.format;
1563*4882a593Smuzhiyun 
1564*4882a593Smuzhiyun 		if (req_rga->pat.yrgb_addr != 0) {
1565*4882a593Smuzhiyun 			/* A+B->C mode */
1566*4882a593Smuzhiyun 			set_win_info(&req->win0, &req_rga->pat);
1567*4882a593Smuzhiyun 			addr_copy(&req->win0, &req_rga->pat);
1568*4882a593Smuzhiyun 			req->win0.format = req_rga->pat.format;
1569*4882a593Smuzhiyun 
1570*4882a593Smuzhiyun 			/* set win0 dst size */
1571*4882a593Smuzhiyun 			if (req->win0.x_offset || req->win0.y_offset) {
1572*4882a593Smuzhiyun 				req->win0.src_act_w = req->win0.src_act_w + req->win0.x_offset;
1573*4882a593Smuzhiyun 				req->win0.src_act_h = req->win0.src_act_h + req->win0.y_offset;
1574*4882a593Smuzhiyun 				req->win0.dst_act_w = req_rga->dst.act_w + req->win0.x_offset;
1575*4882a593Smuzhiyun 				req->win0.dst_act_h = req_rga->dst.act_h + req->win0.y_offset;
1576*4882a593Smuzhiyun 
1577*4882a593Smuzhiyun 				req->win0.x_offset = 0;
1578*4882a593Smuzhiyun 				req->win0.y_offset = 0;
1579*4882a593Smuzhiyun 			} else {
1580*4882a593Smuzhiyun 				req->win0.dst_act_w = req_rga->dst.act_w;
1581*4882a593Smuzhiyun 				req->win0.dst_act_h = req_rga->dst.act_h;
1582*4882a593Smuzhiyun 			}
1583*4882a593Smuzhiyun 			/* set win1 dst size */
1584*4882a593Smuzhiyun 			req->win1.dst_act_w = req_rga->dst.act_w;
1585*4882a593Smuzhiyun 			req->win1.dst_act_h = req_rga->dst.act_h;
1586*4882a593Smuzhiyun 		} else {
1587*4882a593Smuzhiyun 			/* A+B->B mode */
1588*4882a593Smuzhiyun 			set_win_info(&req->win0, &req_rga->dst);
1589*4882a593Smuzhiyun 			addr_copy(&req->win0, &req_rga->dst);
1590*4882a593Smuzhiyun 			req->win0.format = req_rga->dst.format;
1591*4882a593Smuzhiyun 
1592*4882a593Smuzhiyun 			/* only win1 && wr support fbcd, win0 default raster */
1593*4882a593Smuzhiyun 			req->win0.rd_mode = 0;
1594*4882a593Smuzhiyun 
1595*4882a593Smuzhiyun 			/* set win0 dst size */
1596*4882a593Smuzhiyun 			req->win0.dst_act_w = req_rga->dst.act_w;
1597*4882a593Smuzhiyun 			req->win0.dst_act_h = req_rga->dst.act_h;
1598*4882a593Smuzhiyun 			/* set win1 dst size */
1599*4882a593Smuzhiyun 			req->win1.dst_act_w = req_rga->dst.act_w;
1600*4882a593Smuzhiyun 			req->win1.dst_act_h = req_rga->dst.act_h;
1601*4882a593Smuzhiyun 		}
1602*4882a593Smuzhiyun 
1603*4882a593Smuzhiyun 		/* dst offset need to config overlap offset */
1604*4882a593Smuzhiyun 		req->wr.x_offset = req_rga->dst.x_offset;
1605*4882a593Smuzhiyun 		req->wr.y_offset = req_rga->dst.y_offset;
1606*4882a593Smuzhiyun 	}
1607*4882a593Smuzhiyun 	set_wr_info(req_rga, req);
1608*4882a593Smuzhiyun 
1609*4882a593Smuzhiyun 	if (req->rotate_mode & RGA3_ROT_BIT_ROT_90) {
1610*4882a593Smuzhiyun 		if (req->win1.yrgb_addr != 0) {
1611*4882a593Smuzhiyun 			/* ABB */
1612*4882a593Smuzhiyun 			if (req->win0.yrgb_addr == req->wr.yrgb_addr) {
1613*4882a593Smuzhiyun 				req->win1.dst_act_w = req_rga->dst.act_h;
1614*4882a593Smuzhiyun 				req->win1.dst_act_h = req_rga->dst.act_w;
1615*4882a593Smuzhiyun 
1616*4882a593Smuzhiyun 				/* win0 do not need rotate, but net equal to wr */
1617*4882a593Smuzhiyun 				req->win0.dst_act_w = req_rga->dst.act_h;
1618*4882a593Smuzhiyun 				req->win0.dst_act_h = req_rga->dst.act_w;
1619*4882a593Smuzhiyun 				req->win0.src_act_w = req_rga->dst.act_h;
1620*4882a593Smuzhiyun 				req->win0.src_act_h = req_rga->dst.act_w;
1621*4882a593Smuzhiyun 			}
1622*4882a593Smuzhiyun 		} else {
1623*4882a593Smuzhiyun 			req->win0.rotate_mode = 1;
1624*4882a593Smuzhiyun 			req->win0.dst_act_w = req_rga->dst.act_h;
1625*4882a593Smuzhiyun 			req->win0.dst_act_h = req_rga->dst.act_w;
1626*4882a593Smuzhiyun 		}
1627*4882a593Smuzhiyun 	}
1628*4882a593Smuzhiyun 
1629*4882a593Smuzhiyun 	/* overlap */
1630*4882a593Smuzhiyun 	/* Alpha blend mode */
1631*4882a593Smuzhiyun 	if (((req_rga->alpha_rop_flag) & 1)) {
1632*4882a593Smuzhiyun 		if ((req_rga->alpha_rop_flag >> 3) & 1) {
1633*4882a593Smuzhiyun 			req->alpha_config.enable = true;
1634*4882a593Smuzhiyun 
1635*4882a593Smuzhiyun 			if ((req_rga->alpha_rop_flag >> 9) & 1) {
1636*4882a593Smuzhiyun 				req->alpha_config.fg_pre_multiplied = false;
1637*4882a593Smuzhiyun 				req->alpha_config.bg_pre_multiplied = false;
1638*4882a593Smuzhiyun 			} else {
1639*4882a593Smuzhiyun 				req->alpha_config.fg_pre_multiplied = true;
1640*4882a593Smuzhiyun 				req->alpha_config.bg_pre_multiplied = true;
1641*4882a593Smuzhiyun 			}
1642*4882a593Smuzhiyun 
1643*4882a593Smuzhiyun 			req->alpha_config.fg_pixel_alpha_en = rga_is_alpha_format(req->win1.format);
1644*4882a593Smuzhiyun 			req->alpha_config.bg_pixel_alpha_en = rga_is_alpha_format(req->win0.format);
1645*4882a593Smuzhiyun 
1646*4882a593Smuzhiyun 			req->alpha_config.fg_global_alpha_en = false;
1647*4882a593Smuzhiyun 			req->alpha_config.bg_global_alpha_en = false;
1648*4882a593Smuzhiyun 
1649*4882a593Smuzhiyun 			req->alpha_config.fg_global_alpha_value = req_rga->alpha_global_value;
1650*4882a593Smuzhiyun 			req->alpha_config.bg_global_alpha_value = req_rga->alpha_global_value;
1651*4882a593Smuzhiyun 
1652*4882a593Smuzhiyun 			/* porter duff alpha enable */
1653*4882a593Smuzhiyun 			switch (req_rga->PD_mode) {
1654*4882a593Smuzhiyun 			/* dst = 0 */
1655*4882a593Smuzhiyun 			case 0:
1656*4882a593Smuzhiyun 				break;
1657*4882a593Smuzhiyun 			case 1:
1658*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_SRC;
1659*4882a593Smuzhiyun 				break;
1660*4882a593Smuzhiyun 			case 2:
1661*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_DST;
1662*4882a593Smuzhiyun 				break;
1663*4882a593Smuzhiyun 			case 3:
1664*4882a593Smuzhiyun 				if ((req_rga->alpha_rop_mode & 3) == 0) {
1665*4882a593Smuzhiyun 					/* both use globalAlpha. */
1666*4882a593Smuzhiyun 					req->alpha_config.fg_global_alpha_en = true;
1667*4882a593Smuzhiyun 					req->alpha_config.bg_global_alpha_en = true;
1668*4882a593Smuzhiyun 				} else if ((req_rga->alpha_rop_mode & 3) == 1) {
1669*4882a593Smuzhiyun 					/* Do not use globalAlpha. */
1670*4882a593Smuzhiyun 					req->alpha_config.fg_global_alpha_en = false;
1671*4882a593Smuzhiyun 					req->alpha_config.bg_global_alpha_en = false;
1672*4882a593Smuzhiyun 				} else {
1673*4882a593Smuzhiyun 					/* dst use globalAlpha */
1674*4882a593Smuzhiyun 					req->alpha_config.fg_global_alpha_en = false;
1675*4882a593Smuzhiyun 					req->alpha_config.bg_global_alpha_en = true;
1676*4882a593Smuzhiyun 				}
1677*4882a593Smuzhiyun 
1678*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_SRC_OVER;
1679*4882a593Smuzhiyun 				break;
1680*4882a593Smuzhiyun 			case 4:
1681*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_DST_OVER;
1682*4882a593Smuzhiyun 				break;
1683*4882a593Smuzhiyun 			case 5:
1684*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_SRC_IN;
1685*4882a593Smuzhiyun 				break;
1686*4882a593Smuzhiyun 			case 6:
1687*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_DST_IN;
1688*4882a593Smuzhiyun 				break;
1689*4882a593Smuzhiyun 			case 7:
1690*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_SRC_OUT;
1691*4882a593Smuzhiyun 				break;
1692*4882a593Smuzhiyun 			case 8:
1693*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_DST_OUT;
1694*4882a593Smuzhiyun 				break;
1695*4882a593Smuzhiyun 			case 9:
1696*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_SRC_ATOP;
1697*4882a593Smuzhiyun 				break;
1698*4882a593Smuzhiyun 			case 10:
1699*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_DST_ATOP;
1700*4882a593Smuzhiyun 				break;
1701*4882a593Smuzhiyun 			case 11:
1702*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_XOR;
1703*4882a593Smuzhiyun 				break;
1704*4882a593Smuzhiyun 			case 12:
1705*4882a593Smuzhiyun 				req->alpha_config.mode = RGA_ALPHA_BLEND_CLEAR;
1706*4882a593Smuzhiyun 				break;
1707*4882a593Smuzhiyun 			default:
1708*4882a593Smuzhiyun 				break;
1709*4882a593Smuzhiyun 			}
1710*4882a593Smuzhiyun 		}
1711*4882a593Smuzhiyun 	}
1712*4882a593Smuzhiyun 
1713*4882a593Smuzhiyun 	/* yuv to rgb */
1714*4882a593Smuzhiyun 	/* 601 limit */
1715*4882a593Smuzhiyun 	if (req_rga->yuv2rgb_mode == 1) {
1716*4882a593Smuzhiyun 		req->win0.y2r_mode = 0;
1717*4882a593Smuzhiyun 		req->win1.y2r_mode = 0;
1718*4882a593Smuzhiyun 	/* 601 full */
1719*4882a593Smuzhiyun 	} else if (req_rga->yuv2rgb_mode == 2) {
1720*4882a593Smuzhiyun 		req->win0.y2r_mode = 2;
1721*4882a593Smuzhiyun 		req->win1.y2r_mode = 2;
1722*4882a593Smuzhiyun 	/* 709 limit */
1723*4882a593Smuzhiyun 	} else if (req_rga->yuv2rgb_mode == 3) {
1724*4882a593Smuzhiyun 		req->win0.y2r_mode = 1;
1725*4882a593Smuzhiyun 		req->win1.y2r_mode = 1;
1726*4882a593Smuzhiyun 	}
1727*4882a593Smuzhiyun 
1728*4882a593Smuzhiyun 	/* rgb to yuv */
1729*4882a593Smuzhiyun 	/* 601 limit */
1730*4882a593Smuzhiyun 	if ((req_rga->yuv2rgb_mode >> 2) == 2) {
1731*4882a593Smuzhiyun 		req->win0.r2y_mode = 0;
1732*4882a593Smuzhiyun 		req->win1.r2y_mode = 0;
1733*4882a593Smuzhiyun 	/* 601 full */
1734*4882a593Smuzhiyun 	} else if ((req_rga->yuv2rgb_mode >> 2) == 1) {
1735*4882a593Smuzhiyun 		req->win0.r2y_mode = 2;
1736*4882a593Smuzhiyun 		req->win1.r2y_mode = 2;
1737*4882a593Smuzhiyun 	/* 709 limit */
1738*4882a593Smuzhiyun 	} else if ((req_rga->yuv2rgb_mode >> 2) == 3) {
1739*4882a593Smuzhiyun 		req->win0.r2y_mode = 1;
1740*4882a593Smuzhiyun 		req->win1.r2y_mode = 1;
1741*4882a593Smuzhiyun 	}
1742*4882a593Smuzhiyun 
1743*4882a593Smuzhiyun 	/* color key: 8bit->10bit */
1744*4882a593Smuzhiyun 	req->color_key_min = (req_rga->color_key_min & 0xff) << 22 |
1745*4882a593Smuzhiyun 			     ((req_rga->color_key_min >> 8) & 0xff) << 2 |
1746*4882a593Smuzhiyun 			     ((req_rga->color_key_min >> 16) & 0xff) << 12;
1747*4882a593Smuzhiyun 	req->color_key_max = (req_rga->color_key_max & 0xff) << 22 |
1748*4882a593Smuzhiyun 			     ((req_rga->color_key_max >> 8) & 0xff) << 2 |
1749*4882a593Smuzhiyun 			     ((req_rga->color_key_max >> 16) & 0xff) << 12;
1750*4882a593Smuzhiyun 
1751*4882a593Smuzhiyun 	if (req_rga->mmu_info.mmu_en && (req_rga->mmu_info.mmu_flag & 1) == 1) {
1752*4882a593Smuzhiyun 		req->mmu_info.src0_mmu_flag = 1;
1753*4882a593Smuzhiyun 		req->mmu_info.src1_mmu_flag = 1;
1754*4882a593Smuzhiyun 		req->mmu_info.dst_mmu_flag = 1;
1755*4882a593Smuzhiyun 	}
1756*4882a593Smuzhiyun }
1757*4882a593Smuzhiyun 
rga3_soft_reset(struct rga_scheduler_t * scheduler)1758*4882a593Smuzhiyun static void rga3_soft_reset(struct rga_scheduler_t *scheduler)
1759*4882a593Smuzhiyun {
1760*4882a593Smuzhiyun 	u32 i;
1761*4882a593Smuzhiyun 	u32 iommu_dte_addr = 0;
1762*4882a593Smuzhiyun 
1763*4882a593Smuzhiyun 	if (scheduler->data->mmu == RGA_IOMMU)
1764*4882a593Smuzhiyun 		iommu_dte_addr = rga_read(RGA_IOMMU_DTE_ADDR, scheduler);
1765*4882a593Smuzhiyun 
1766*4882a593Smuzhiyun 	rga_write(s_RGA3_SYS_CTRL_CCLK_SRESET(1) | s_RGA3_SYS_CTRL_ACLK_SRESET(1),
1767*4882a593Smuzhiyun 		  RGA3_SYS_CTRL, scheduler);
1768*4882a593Smuzhiyun 
1769*4882a593Smuzhiyun 	for (i = 0; i < RGA_RESET_TIMEOUT; i++) {
1770*4882a593Smuzhiyun 		if (rga_read(RGA3_RO_SRST, scheduler) & m_RGA3_RO_SRST_RO_RST_DONE)
1771*4882a593Smuzhiyun 			break;
1772*4882a593Smuzhiyun 
1773*4882a593Smuzhiyun 		udelay(1);
1774*4882a593Smuzhiyun 	}
1775*4882a593Smuzhiyun 
1776*4882a593Smuzhiyun 	rga_write(s_RGA3_SYS_CTRL_CCLK_SRESET(0) | s_RGA3_SYS_CTRL_ACLK_SRESET(0),
1777*4882a593Smuzhiyun 		  RGA3_SYS_CTRL, scheduler);
1778*4882a593Smuzhiyun 
1779*4882a593Smuzhiyun 	if (scheduler->data->mmu == RGA_IOMMU) {
1780*4882a593Smuzhiyun 		rga_write(iommu_dte_addr, RGA_IOMMU_DTE_ADDR, scheduler);
1781*4882a593Smuzhiyun 		/* enable iommu */
1782*4882a593Smuzhiyun 		rga_write(RGA_IOMMU_CMD_ENABLE_PAGING, RGA_IOMMU_COMMAND, scheduler);
1783*4882a593Smuzhiyun 	}
1784*4882a593Smuzhiyun 
1785*4882a593Smuzhiyun 	if (i == RGA_RESET_TIMEOUT)
1786*4882a593Smuzhiyun 		pr_err("RGA3 core[%d] soft reset timeout. SYS_CTRL[0x%x], RO_SRST[0x%x]\n",
1787*4882a593Smuzhiyun 		       scheduler->core, rga_read(RGA3_SYS_CTRL, scheduler),
1788*4882a593Smuzhiyun 		       rga_read(RGA3_RO_SRST, scheduler));
1789*4882a593Smuzhiyun 	else
1790*4882a593Smuzhiyun 		pr_info("RGA3 core[%d] soft reset complete.\n", scheduler->core);
1791*4882a593Smuzhiyun }
1792*4882a593Smuzhiyun 
rga3_scale_check(const struct rga3_req * req)1793*4882a593Smuzhiyun static int rga3_scale_check(const struct rga3_req *req)
1794*4882a593Smuzhiyun {
1795*4882a593Smuzhiyun 	u32 win0_saw, win0_sah, win0_daw, win0_dah;
1796*4882a593Smuzhiyun 	u32 win1_saw, win1_sah, win1_daw, win1_dah;
1797*4882a593Smuzhiyun 
1798*4882a593Smuzhiyun 	win0_saw = req->win0.src_act_w;
1799*4882a593Smuzhiyun 	win0_sah = req->win0.src_act_h;
1800*4882a593Smuzhiyun 	win0_daw = req->win0.dst_act_w;
1801*4882a593Smuzhiyun 	win0_dah = req->win0.dst_act_h;
1802*4882a593Smuzhiyun 
1803*4882a593Smuzhiyun 	if (((win0_saw >> 3) > win0_daw) || ((win0_sah >> 3) > win0_dah)) {
1804*4882a593Smuzhiyun 		pr_info("win0 unsupported to scaling less than 1/8 times.\n");
1805*4882a593Smuzhiyun 		return -EINVAL;
1806*4882a593Smuzhiyun 	}
1807*4882a593Smuzhiyun 	if (((win0_daw >> 3) > win0_saw) || ((win0_dah >> 3) > win0_sah)) {
1808*4882a593Smuzhiyun 		pr_info("win0 unsupported to scaling more than 8 times.\n");
1809*4882a593Smuzhiyun 		return -EINVAL;
1810*4882a593Smuzhiyun 	}
1811*4882a593Smuzhiyun 
1812*4882a593Smuzhiyun 	if (req->win1.yrgb_addr != 0) {
1813*4882a593Smuzhiyun 		win1_saw = req->win1.src_act_w;
1814*4882a593Smuzhiyun 		win1_sah = req->win1.src_act_h;
1815*4882a593Smuzhiyun 		win1_daw = req->win1.dst_act_w;
1816*4882a593Smuzhiyun 		win1_dah = req->win1.dst_act_h;
1817*4882a593Smuzhiyun 
1818*4882a593Smuzhiyun 		if (((win1_saw >> 3) > win1_daw) || ((win1_sah >> 3) > win1_dah)) {
1819*4882a593Smuzhiyun 			pr_info("win1 unsupported to scaling less than 1/8 times.\n");
1820*4882a593Smuzhiyun 			return -EINVAL;
1821*4882a593Smuzhiyun 		}
1822*4882a593Smuzhiyun 		if (((win1_daw >> 3) > win1_saw) || ((win1_dah >> 3) > win1_sah)) {
1823*4882a593Smuzhiyun 			pr_info("win1 unsupported to scaling more than 8 times.\n");
1824*4882a593Smuzhiyun 			return -EINVAL;
1825*4882a593Smuzhiyun 		}
1826*4882a593Smuzhiyun 	}
1827*4882a593Smuzhiyun 
1828*4882a593Smuzhiyun 	return 0;
1829*4882a593Smuzhiyun }
1830*4882a593Smuzhiyun 
rga3_check_param(const struct rga_hw_data * data,const struct rga3_req * req)1831*4882a593Smuzhiyun static int rga3_check_param(const struct rga_hw_data *data, const struct rga3_req *req)
1832*4882a593Smuzhiyun {
1833*4882a593Smuzhiyun 	if (unlikely(rga_hw_out_of_range(&(data->input_range),
1834*4882a593Smuzhiyun 					 req->win0.src_act_w, req->win0.src_act_h) ||
1835*4882a593Smuzhiyun 		     rga_hw_out_of_range(&(data->input_range),
1836*4882a593Smuzhiyun 					 req->win0.dst_act_w, req->win0.dst_act_h) ||
1837*4882a593Smuzhiyun 		     rga_hw_out_of_range(&(data->input_range),
1838*4882a593Smuzhiyun 					 req->win0.src_act_w + req->win0.x_offset,
1839*4882a593Smuzhiyun 					 req->win0.src_act_h + req->win0.y_offset))) {
1840*4882a593Smuzhiyun 		pr_err("invalid win0, src[w,h] = [%d, %d], dst[w,h] = [%d, %d], off[x,y] = [%d,%d]\n",
1841*4882a593Smuzhiyun 		       req->win0.src_act_w, req->win0.src_act_h,
1842*4882a593Smuzhiyun 		       req->win0.dst_act_w, req->win0.dst_act_h,
1843*4882a593Smuzhiyun 		       req->win0.x_offset, req->win0.y_offset);
1844*4882a593Smuzhiyun 		return -EINVAL;
1845*4882a593Smuzhiyun 	}
1846*4882a593Smuzhiyun 
1847*4882a593Smuzhiyun 	if (unlikely(req->win0.vir_w * rga_get_pixel_stride_from_format(req->win0.format) >
1848*4882a593Smuzhiyun 		     data->max_byte_stride * 8)) {
1849*4882a593Smuzhiyun 		pr_err("invalid win0 stride, stride = %d, pixel_stride = %d, max_byte_stride = %d\n",
1850*4882a593Smuzhiyun 		       req->win0.vir_w, rga_get_pixel_stride_from_format(req->win0.format),
1851*4882a593Smuzhiyun 		       data->max_byte_stride);
1852*4882a593Smuzhiyun 		return -EINVAL;
1853*4882a593Smuzhiyun 	}
1854*4882a593Smuzhiyun 
1855*4882a593Smuzhiyun 	if (unlikely(rga_hw_out_of_range(&(data->output_range),
1856*4882a593Smuzhiyun 					 req->wr.dst_act_w, req->wr.dst_act_h))) {
1857*4882a593Smuzhiyun 		pr_err("invalid wr, [w,h] = [%d, %d]\n", req->wr.dst_act_w, req->wr.dst_act_h);
1858*4882a593Smuzhiyun 		return -EINVAL;
1859*4882a593Smuzhiyun 	}
1860*4882a593Smuzhiyun 
1861*4882a593Smuzhiyun 	if (unlikely(req->wr.vir_w * rga_get_pixel_stride_from_format(req->wr.format) >
1862*4882a593Smuzhiyun 		     data->max_byte_stride * 8)) {
1863*4882a593Smuzhiyun 		pr_err("invalid wr stride, stride = %d, pixel_stride = %d, max_byte_stride = %d\n",
1864*4882a593Smuzhiyun 		       req->wr.vir_w, rga_get_pixel_stride_from_format(req->wr.format),
1865*4882a593Smuzhiyun 		       data->max_byte_stride);
1866*4882a593Smuzhiyun 		return -EINVAL;
1867*4882a593Smuzhiyun 	}
1868*4882a593Smuzhiyun 
1869*4882a593Smuzhiyun 	if (req->win1.yrgb_addr != 0) {
1870*4882a593Smuzhiyun 		if (unlikely(rga_hw_out_of_range(&(data->input_range),
1871*4882a593Smuzhiyun 						 req->win1.src_act_w, req->win1.src_act_h) ||
1872*4882a593Smuzhiyun 			     rga_hw_out_of_range(&(data->input_range),
1873*4882a593Smuzhiyun 						 req->win1.dst_act_w, req->win1.dst_act_h) ||
1874*4882a593Smuzhiyun 			     rga_hw_out_of_range(&(data->input_range),
1875*4882a593Smuzhiyun 						 req->win1.src_act_w + req->win1.x_offset,
1876*4882a593Smuzhiyun 						 req->win1.src_act_h + req->win1.y_offset))) {
1877*4882a593Smuzhiyun 			pr_err("invalid win1, src[w,h] = [%d, %d], dst[w,h] = [%d, %d], off[x,y] = [%d,%d]\n",
1878*4882a593Smuzhiyun 			       req->win1.src_act_w, req->win1.src_act_h,
1879*4882a593Smuzhiyun 			       req->win1.dst_act_w, req->win1.dst_act_h,
1880*4882a593Smuzhiyun 			       req->win1.x_offset, req->win1.y_offset);
1881*4882a593Smuzhiyun 			return -EINVAL;
1882*4882a593Smuzhiyun 		}
1883*4882a593Smuzhiyun 
1884*4882a593Smuzhiyun 		if (unlikely(req->win1.vir_w * rga_get_pixel_stride_from_format(req->win1.format) >
1885*4882a593Smuzhiyun 			     data->max_byte_stride * 8)) {
1886*4882a593Smuzhiyun 			pr_err("invalid win1 stride, stride = %d, pixel_stride = %d, max_byte_stride = %d\n",
1887*4882a593Smuzhiyun 			       req->win1.vir_w, rga_get_pixel_stride_from_format(req->win1.format),
1888*4882a593Smuzhiyun 			       data->max_byte_stride);
1889*4882a593Smuzhiyun 			return -EINVAL;
1890*4882a593Smuzhiyun 		}
1891*4882a593Smuzhiyun 
1892*4882a593Smuzhiyun 		/* warning: rotate mode skip this judge */
1893*4882a593Smuzhiyun 		if (req->rotate_mode == 0) {
1894*4882a593Smuzhiyun 			/* check win0 dst size > win1 dst size */
1895*4882a593Smuzhiyun 			if (unlikely((req->win1.dst_act_w > req->win0.dst_act_w) ||
1896*4882a593Smuzhiyun 				     (req->win1.dst_act_h > req->win0.dst_act_h))) {
1897*4882a593Smuzhiyun 				pr_err("invalid output param win0[w,h] = [%d, %d], win1[w,h] = [%d, %d]\n",
1898*4882a593Smuzhiyun 				       req->win0.dst_act_w, req->win0.dst_act_h,
1899*4882a593Smuzhiyun 				       req->win1.dst_act_w, req->win1.dst_act_h);
1900*4882a593Smuzhiyun 				return -EINVAL;
1901*4882a593Smuzhiyun 			}
1902*4882a593Smuzhiyun 		}
1903*4882a593Smuzhiyun 	}
1904*4882a593Smuzhiyun 
1905*4882a593Smuzhiyun 	if (rga3_scale_check(req) < 0)
1906*4882a593Smuzhiyun 		return -EINVAL;
1907*4882a593Smuzhiyun 
1908*4882a593Smuzhiyun 	return 0;
1909*4882a593Smuzhiyun }
1910*4882a593Smuzhiyun 
print_debug_info(struct rga3_req * req)1911*4882a593Smuzhiyun static void print_debug_info(struct rga3_req *req)
1912*4882a593Smuzhiyun {
1913*4882a593Smuzhiyun 	pr_info("render_mode:%s, bitblit_mode=%d, rotate_mode:%x\n",
1914*4882a593Smuzhiyun 		rga_get_render_mode_str(req->render_mode), req->bitblt_mode,
1915*4882a593Smuzhiyun 		req->rotate_mode);
1916*4882a593Smuzhiyun 	pr_info("win0: y = %lx uv = %lx v = %lx src_w = %d src_h = %d\n",
1917*4882a593Smuzhiyun 		 req->win0.yrgb_addr, req->win0.uv_addr, req->win0.v_addr,
1918*4882a593Smuzhiyun 		 req->win0.src_act_w, req->win0.src_act_h);
1919*4882a593Smuzhiyun 	pr_info("win0: vw = %d vh = %d xoff = %d yoff = %d format = %s\n",
1920*4882a593Smuzhiyun 		 req->win0.vir_w, req->win0.vir_h,
1921*4882a593Smuzhiyun 		 req->win0.x_offset, req->win0.y_offset,
1922*4882a593Smuzhiyun 		 rga_get_format_name(req->win0.format));
1923*4882a593Smuzhiyun 	pr_info("win0: dst_w = %d, dst_h = %d, rd_mode = %d\n",
1924*4882a593Smuzhiyun 		 req->win0.dst_act_w, req->win0.dst_act_h, req->win0.rd_mode);
1925*4882a593Smuzhiyun 	pr_info("win0: rot_mode = %d, en = %d, compact = %d, endian = %d\n",
1926*4882a593Smuzhiyun 		 req->win0.rotate_mode, req->win0.enable,
1927*4882a593Smuzhiyun 		 req->win0.is_10b_compact, req->win0.is_10b_endian);
1928*4882a593Smuzhiyun 
1929*4882a593Smuzhiyun 	if (req->win1.yrgb_addr != 0 || req->win1.uv_addr != 0
1930*4882a593Smuzhiyun 		|| req->win1.v_addr != 0) {
1931*4882a593Smuzhiyun 		pr_info("win1: y = %lx uv = %lx v = %lx src_w = %d src_h = %d\n",
1932*4882a593Smuzhiyun 			 req->win1.yrgb_addr, req->win1.uv_addr,
1933*4882a593Smuzhiyun 			 req->win1.v_addr, req->win1.src_act_w,
1934*4882a593Smuzhiyun 			 req->win1.src_act_h);
1935*4882a593Smuzhiyun 		pr_info("win1: vw = %d vh = %d xoff = %d yoff = %d format = %s\n",
1936*4882a593Smuzhiyun 			 req->win1.vir_w, req->win1.vir_h,
1937*4882a593Smuzhiyun 			 req->win1.x_offset, req->win1.y_offset,
1938*4882a593Smuzhiyun 			 rga_get_format_name(req->win1.format));
1939*4882a593Smuzhiyun 		pr_info("win1: dst_w = %d, dst_h = %d, rd_mode = %d\n",
1940*4882a593Smuzhiyun 			 req->win1.dst_act_w, req->win1.dst_act_h,
1941*4882a593Smuzhiyun 			 req->win1.rd_mode);
1942*4882a593Smuzhiyun 		pr_info("win1: rot_mode = %d, en = %d, compact = %d, endian = %d\n",
1943*4882a593Smuzhiyun 			 req->win1.rotate_mode, req->win1.enable,
1944*4882a593Smuzhiyun 			 req->win1.is_10b_compact, req->win1.is_10b_endian);
1945*4882a593Smuzhiyun 	}
1946*4882a593Smuzhiyun 
1947*4882a593Smuzhiyun 	pr_info("wr: y = %lx uv = %lx v = %lx vw = %d vh = %d\n",
1948*4882a593Smuzhiyun 		 req->wr.yrgb_addr, req->wr.uv_addr, req->wr.v_addr,
1949*4882a593Smuzhiyun 		 req->wr.vir_w, req->wr.vir_h);
1950*4882a593Smuzhiyun 	pr_info("wr: ovlp_xoff = %d ovlp_yoff = %d format = %s rdmode = %d\n",
1951*4882a593Smuzhiyun 		 req->wr.x_offset, req->wr.y_offset,
1952*4882a593Smuzhiyun 		 rga_get_format_name(req->wr.format), req->wr.rd_mode);
1953*4882a593Smuzhiyun 
1954*4882a593Smuzhiyun 	pr_info("mmu: win0 = %.2x win1 = %.2x wr = %.2x\n",
1955*4882a593Smuzhiyun 		req->mmu_info.src0_mmu_flag, req->mmu_info.src1_mmu_flag,
1956*4882a593Smuzhiyun 		req->mmu_info.dst_mmu_flag);
1957*4882a593Smuzhiyun 	pr_info("alpha: flag %x mode=%s\n",
1958*4882a593Smuzhiyun 		req->alpha_rop_flag, rga_get_blend_mode_str(req->alpha_config.mode));
1959*4882a593Smuzhiyun 	pr_info("alpha: pre_multi=[%d,%d] pixl=[%d,%d] glb=[%d,%d]\n",
1960*4882a593Smuzhiyun 		req->alpha_config.fg_pre_multiplied, req->alpha_config.bg_pre_multiplied,
1961*4882a593Smuzhiyun 		req->alpha_config.fg_pixel_alpha_en, req->alpha_config.bg_pixel_alpha_en,
1962*4882a593Smuzhiyun 		req->alpha_config.fg_global_alpha_en, req->alpha_config.bg_global_alpha_en);
1963*4882a593Smuzhiyun 	pr_info("alpha: fg_global_alpha=%x bg_global_alpha=%x\n",
1964*4882a593Smuzhiyun 		req->alpha_config.fg_global_alpha_value, req->alpha_config.bg_global_alpha_value);
1965*4882a593Smuzhiyun 	pr_info("yuv2rgb mode is %x\n", req->yuv2rgb_mode);
1966*4882a593Smuzhiyun }
1967*4882a593Smuzhiyun 
rga3_align_check(struct rga3_req * req)1968*4882a593Smuzhiyun static int rga3_align_check(struct rga3_req *req)
1969*4882a593Smuzhiyun {
1970*4882a593Smuzhiyun 	if (rga_is_yuv10bit_format(req->win0.format))
1971*4882a593Smuzhiyun 		if ((req->win0.vir_w % 64) || (req->win0.x_offset % 4) ||
1972*4882a593Smuzhiyun 			(req->win0.src_act_w % 4) || (req->win0.y_offset % 4) ||
1973*4882a593Smuzhiyun 			(req->win0.src_act_h % 4) || (req->win0.vir_h % 2))
1974*4882a593Smuzhiyun 			pr_info("yuv10bit err win0 wstride is not align\n");
1975*4882a593Smuzhiyun 	if (rga_is_yuv10bit_format(req->win1.format))
1976*4882a593Smuzhiyun 		if ((req->win1.vir_w % 64) || (req->win1.x_offset % 4) ||
1977*4882a593Smuzhiyun 			(req->win1.src_act_w % 4) || (req->win1.y_offset % 4) ||
1978*4882a593Smuzhiyun 			(req->win1.src_act_h % 4) || (req->win1.vir_h % 2))
1979*4882a593Smuzhiyun 			pr_info("yuv10bit err win1 wstride is not align\n");
1980*4882a593Smuzhiyun 	if (rga_is_yuv8bit_format(req->win0.format))
1981*4882a593Smuzhiyun 		if ((req->win0.vir_w % 16) || (req->win0.x_offset % 2) ||
1982*4882a593Smuzhiyun 			(req->win0.src_act_w % 2) || (req->win0.y_offset % 2) ||
1983*4882a593Smuzhiyun 			(req->win0.src_act_h % 2) || (req->win0.vir_h % 2))
1984*4882a593Smuzhiyun 			pr_info("yuv8bit err win0 wstride is not align\n");
1985*4882a593Smuzhiyun 	if (rga_is_yuv8bit_format(req->win1.format))
1986*4882a593Smuzhiyun 		if ((req->win1.vir_w % 16) || (req->win1.x_offset % 2) ||
1987*4882a593Smuzhiyun 			(req->win1.src_act_w % 2) || (req->win1.y_offset % 2) ||
1988*4882a593Smuzhiyun 			(req->win1.src_act_h % 2) || (req->win1.vir_h % 2))
1989*4882a593Smuzhiyun 			pr_info("yuv8bit err win1 wstride is not align\n");
1990*4882a593Smuzhiyun 	return 0;
1991*4882a593Smuzhiyun }
1992*4882a593Smuzhiyun 
rga3_init_reg(struct rga_job * job)1993*4882a593Smuzhiyun static int rga3_init_reg(struct rga_job *job)
1994*4882a593Smuzhiyun {
1995*4882a593Smuzhiyun 	struct rga3_req req;
1996*4882a593Smuzhiyun 	int ret = 0;
1997*4882a593Smuzhiyun 	struct rga_scheduler_t *scheduler = NULL;
1998*4882a593Smuzhiyun 
1999*4882a593Smuzhiyun 	scheduler = job->scheduler;
2000*4882a593Smuzhiyun 	if (unlikely(scheduler == NULL)) {
2001*4882a593Smuzhiyun 		pr_err("failed to get scheduler, %s(%d)\n", __func__, __LINE__);
2002*4882a593Smuzhiyun 		return -EINVAL;
2003*4882a593Smuzhiyun 	}
2004*4882a593Smuzhiyun 
2005*4882a593Smuzhiyun 	memset(&req, 0x0, sizeof(req));
2006*4882a593Smuzhiyun 
2007*4882a593Smuzhiyun 	rga_cmd_to_rga3_cmd(&job->rga_command_base, &req);
2008*4882a593Smuzhiyun 
2009*4882a593Smuzhiyun 	/* check value if legal */
2010*4882a593Smuzhiyun 	ret = rga3_check_param(scheduler->data, &req);
2011*4882a593Smuzhiyun 	if (ret == -EINVAL) {
2012*4882a593Smuzhiyun 		pr_err("req argument is inval\n");
2013*4882a593Smuzhiyun 		return ret;
2014*4882a593Smuzhiyun 	}
2015*4882a593Smuzhiyun 
2016*4882a593Smuzhiyun 	rga3_align_check(&req);
2017*4882a593Smuzhiyun 
2018*4882a593Smuzhiyun 	/* for debug */
2019*4882a593Smuzhiyun 	if (DEBUGGER_EN(MSG))
2020*4882a593Smuzhiyun 		print_debug_info(&req);
2021*4882a593Smuzhiyun 
2022*4882a593Smuzhiyun 	if (rga3_gen_reg_info((uint8_t *) job->cmd_reg, &req) == -1) {
2023*4882a593Smuzhiyun 		pr_err("RKA: gen reg info error\n");
2024*4882a593Smuzhiyun 		return -EINVAL;
2025*4882a593Smuzhiyun 	}
2026*4882a593Smuzhiyun 
2027*4882a593Smuzhiyun 	return ret;
2028*4882a593Smuzhiyun }
2029*4882a593Smuzhiyun 
rga3_dump_read_back_reg(struct rga_scheduler_t * scheduler)2030*4882a593Smuzhiyun static void rga3_dump_read_back_reg(struct rga_scheduler_t *scheduler)
2031*4882a593Smuzhiyun {
2032*4882a593Smuzhiyun 	int i;
2033*4882a593Smuzhiyun 	unsigned long flags;
2034*4882a593Smuzhiyun 	uint32_t cmd_reg[48] = {0};
2035*4882a593Smuzhiyun 
2036*4882a593Smuzhiyun 	spin_lock_irqsave(&scheduler->irq_lock, flags);
2037*4882a593Smuzhiyun 
2038*4882a593Smuzhiyun 	for (i = 0; i < 48; i++)
2039*4882a593Smuzhiyun 		cmd_reg[i] = rga_read(0x100 + i * 4, scheduler);
2040*4882a593Smuzhiyun 
2041*4882a593Smuzhiyun 	spin_unlock_irqrestore(&scheduler->irq_lock, flags);
2042*4882a593Smuzhiyun 
2043*4882a593Smuzhiyun 	pr_info("CMD_READ_BACK_REG\n");
2044*4882a593Smuzhiyun 	for (i = 0; i < 12; i++)
2045*4882a593Smuzhiyun 		pr_info("i = %x : %.8x %.8x %.8x %.8x\n", i,
2046*4882a593Smuzhiyun 			cmd_reg[0 + i * 4], cmd_reg[1 + i * 4],
2047*4882a593Smuzhiyun 			cmd_reg[2 + i * 4], cmd_reg[3 + i * 4]);
2048*4882a593Smuzhiyun }
2049*4882a593Smuzhiyun 
rga3_set_reg(struct rga_job * job,struct rga_scheduler_t * scheduler)2050*4882a593Smuzhiyun static int rga3_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
2051*4882a593Smuzhiyun {
2052*4882a593Smuzhiyun 	int i;
2053*4882a593Smuzhiyun 	bool master_mode_en;
2054*4882a593Smuzhiyun 	uint32_t sys_ctrl;
2055*4882a593Smuzhiyun 	ktime_t now = ktime_get();
2056*4882a593Smuzhiyun 
2057*4882a593Smuzhiyun 	/*
2058*4882a593Smuzhiyun 	 * Currently there is no iova allocated for storing cmd for the IOMMU device,
2059*4882a593Smuzhiyun 	 * so the iommu device needs to use the slave mode.
2060*4882a593Smuzhiyun 	 */
2061*4882a593Smuzhiyun 	if (scheduler->data->mmu != RGA_IOMMU)
2062*4882a593Smuzhiyun 		master_mode_en = true;
2063*4882a593Smuzhiyun 	else
2064*4882a593Smuzhiyun 		master_mode_en = false;
2065*4882a593Smuzhiyun 
2066*4882a593Smuzhiyun 	if (DEBUGGER_EN(REG)) {
2067*4882a593Smuzhiyun 		uint32_t *p;
2068*4882a593Smuzhiyun 
2069*4882a593Smuzhiyun 		p = job->cmd_reg;
2070*4882a593Smuzhiyun 		pr_info("CMD_REG\n");
2071*4882a593Smuzhiyun 		for (i = 0; i < 12; i++)
2072*4882a593Smuzhiyun 			pr_info("i = %x : %.8x %.8x %.8x %.8x\n", i,
2073*4882a593Smuzhiyun 				p[0 + i * 4], p[1 + i * 4],
2074*4882a593Smuzhiyun 				p[2 + i * 4], p[3 + i * 4]);
2075*4882a593Smuzhiyun 	}
2076*4882a593Smuzhiyun 
2077*4882a593Smuzhiyun 	/* All CMD finish int */
2078*4882a593Smuzhiyun 	rga_write(m_RGA3_INT_FRM_DONE | m_RGA3_INT_CMD_LINE_FINISH | m_RGA3_INT_ERROR_MASK,
2079*4882a593Smuzhiyun 		  RGA3_INT_EN, scheduler);
2080*4882a593Smuzhiyun 
2081*4882a593Smuzhiyun 	if (master_mode_en) {
2082*4882a593Smuzhiyun 		/* master mode */
2083*4882a593Smuzhiyun 		sys_ctrl = s_RGA3_SYS_CTRL_CMD_MODE(1);
2084*4882a593Smuzhiyun 
2085*4882a593Smuzhiyun 		/* cmd buffer flush cache to ddr */
2086*4882a593Smuzhiyun 		rga_dma_sync_flush_range(&job->cmd_reg[0], &job->cmd_reg[50], scheduler);
2087*4882a593Smuzhiyun 
2088*4882a593Smuzhiyun 		rga_write(virt_to_phys(job->cmd_reg), RGA3_CMD_ADDR, scheduler);
2089*4882a593Smuzhiyun 		rga_write(sys_ctrl, RGA3_SYS_CTRL, scheduler);
2090*4882a593Smuzhiyun 		rga_write(m_RGA3_CMD_CTRL_CMD_LINE_ST_P, RGA3_CMD_CTRL, scheduler);
2091*4882a593Smuzhiyun 	} else {
2092*4882a593Smuzhiyun 		/* slave mode */
2093*4882a593Smuzhiyun 		sys_ctrl = s_RGA3_SYS_CTRL_CMD_MODE(0) | m_RGA3_SYS_CTRL_RGA_SART;
2094*4882a593Smuzhiyun 
2095*4882a593Smuzhiyun 		for (i = 0; i <= 50; i++)
2096*4882a593Smuzhiyun 			rga_write(job->cmd_reg[i], 0x100 + i * 4, scheduler);
2097*4882a593Smuzhiyun 
2098*4882a593Smuzhiyun 		rga_write(sys_ctrl, RGA3_SYS_CTRL, scheduler);
2099*4882a593Smuzhiyun 	}
2100*4882a593Smuzhiyun 
2101*4882a593Smuzhiyun 	if (DEBUGGER_EN(REG)) {
2102*4882a593Smuzhiyun 		pr_info("sys_ctrl = 0x%x, int_en = 0x%x, int_raw = 0x%x\n",
2103*4882a593Smuzhiyun 			rga_read(RGA3_SYS_CTRL, scheduler),
2104*4882a593Smuzhiyun 			rga_read(RGA3_INT_EN, scheduler),
2105*4882a593Smuzhiyun 			rga_read(RGA3_INT_RAW, scheduler));
2106*4882a593Smuzhiyun 
2107*4882a593Smuzhiyun 		pr_info("hw_status = 0x%x, cmd_status = 0x%x\n",
2108*4882a593Smuzhiyun 			rga_read(RGA3_STATUS0, scheduler),
2109*4882a593Smuzhiyun 			rga_read(RGA3_CMD_STATE, scheduler));
2110*4882a593Smuzhiyun 	}
2111*4882a593Smuzhiyun 
2112*4882a593Smuzhiyun 	if (DEBUGGER_EN(TIME))
2113*4882a593Smuzhiyun 		pr_info("set cmd use time = %lld\n", ktime_us_delta(now, job->timestamp));
2114*4882a593Smuzhiyun 
2115*4882a593Smuzhiyun 	job->hw_running_time = now;
2116*4882a593Smuzhiyun 	job->hw_recoder_time = now;
2117*4882a593Smuzhiyun 
2118*4882a593Smuzhiyun 	if (DEBUGGER_EN(REG))
2119*4882a593Smuzhiyun 		rga3_dump_read_back_reg(scheduler);
2120*4882a593Smuzhiyun 
2121*4882a593Smuzhiyun 	return 0;
2122*4882a593Smuzhiyun }
2123*4882a593Smuzhiyun 
rga3_get_version(struct rga_scheduler_t * scheduler)2124*4882a593Smuzhiyun static int rga3_get_version(struct rga_scheduler_t *scheduler)
2125*4882a593Smuzhiyun {
2126*4882a593Smuzhiyun 	u32 major_version, minor_version, svn_version;
2127*4882a593Smuzhiyun 	u32 reg_version;
2128*4882a593Smuzhiyun 
2129*4882a593Smuzhiyun 	if (!scheduler) {
2130*4882a593Smuzhiyun 		pr_err("scheduler is null\n");
2131*4882a593Smuzhiyun 		return -EINVAL;
2132*4882a593Smuzhiyun 	}
2133*4882a593Smuzhiyun 
2134*4882a593Smuzhiyun 	reg_version = rga_read(RGA3_VERSION_NUM, scheduler);
2135*4882a593Smuzhiyun 
2136*4882a593Smuzhiyun 	major_version = (reg_version & RGA3_MAJOR_VERSION_MASK) >> 28;
2137*4882a593Smuzhiyun 	minor_version = (reg_version & RGA3_MINOR_VERSION_MASK) >> 20;
2138*4882a593Smuzhiyun 	svn_version = (reg_version & RGA3_SVN_VERSION_MASK);
2139*4882a593Smuzhiyun 
2140*4882a593Smuzhiyun 	snprintf(scheduler->version.str, 10, "%x.%01x.%05x", major_version,
2141*4882a593Smuzhiyun 		 minor_version, svn_version);
2142*4882a593Smuzhiyun 
2143*4882a593Smuzhiyun 	scheduler->version.major = major_version;
2144*4882a593Smuzhiyun 	scheduler->version.minor = minor_version;
2145*4882a593Smuzhiyun 	scheduler->version.revision = svn_version;
2146*4882a593Smuzhiyun 
2147*4882a593Smuzhiyun 	return 0;
2148*4882a593Smuzhiyun }
2149*4882a593Smuzhiyun 
rga3_irq(struct rga_scheduler_t * scheduler)2150*4882a593Smuzhiyun static int rga3_irq(struct rga_scheduler_t *scheduler)
2151*4882a593Smuzhiyun {
2152*4882a593Smuzhiyun 	struct rga_job *job = scheduler->running_job;
2153*4882a593Smuzhiyun 
2154*4882a593Smuzhiyun 	if (job == NULL)
2155*4882a593Smuzhiyun 		return IRQ_HANDLED;
2156*4882a593Smuzhiyun 
2157*4882a593Smuzhiyun 	if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state))
2158*4882a593Smuzhiyun 		return IRQ_WAKE_THREAD;
2159*4882a593Smuzhiyun 
2160*4882a593Smuzhiyun 	job->intr_status = rga_read(RGA3_INT_RAW, scheduler);
2161*4882a593Smuzhiyun 	job->hw_status = rga_read(RGA3_STATUS0, scheduler);
2162*4882a593Smuzhiyun 	job->cmd_status = rga_read(RGA3_CMD_STATE, scheduler);
2163*4882a593Smuzhiyun 
2164*4882a593Smuzhiyun 	if (DEBUGGER_EN(INT_FLAG))
2165*4882a593Smuzhiyun 		pr_info("irq handler, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n",
2166*4882a593Smuzhiyun 			job->intr_status, job->hw_status, job->cmd_status);
2167*4882a593Smuzhiyun 
2168*4882a593Smuzhiyun 	if (job->intr_status & (m_RGA3_INT_FRM_DONE | m_RGA3_INT_CMD_LINE_FINISH)) {
2169*4882a593Smuzhiyun 		set_bit(RGA_JOB_STATE_FINISH, &job->state);
2170*4882a593Smuzhiyun 	} else if (job->intr_status & m_RGA3_INT_ERROR_MASK) {
2171*4882a593Smuzhiyun 		set_bit(RGA_JOB_STATE_INTR_ERR, &job->state);
2172*4882a593Smuzhiyun 
2173*4882a593Smuzhiyun 		pr_err("irq handler err! INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n",
2174*4882a593Smuzhiyun 		       job->intr_status, job->hw_status, job->cmd_status);
2175*4882a593Smuzhiyun 		scheduler->ops->soft_reset(scheduler);
2176*4882a593Smuzhiyun 	}
2177*4882a593Smuzhiyun 
2178*4882a593Smuzhiyun 	/*clear INTR */
2179*4882a593Smuzhiyun 	rga_write(m_RGA3_INT_FRM_DONE | m_RGA3_INT_CMD_LINE_FINISH | m_RGA3_INT_ERROR_MASK,
2180*4882a593Smuzhiyun 		  RGA3_INT_CLR, scheduler);
2181*4882a593Smuzhiyun 
2182*4882a593Smuzhiyun 	return IRQ_WAKE_THREAD;
2183*4882a593Smuzhiyun }
2184*4882a593Smuzhiyun 
rga3_isr_thread(struct rga_job * job,struct rga_scheduler_t * scheduler)2185*4882a593Smuzhiyun static int rga3_isr_thread(struct rga_job *job, struct rga_scheduler_t *scheduler)
2186*4882a593Smuzhiyun {
2187*4882a593Smuzhiyun 	if (DEBUGGER_EN(INT_FLAG))
2188*4882a593Smuzhiyun 		pr_info("isr thread, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n",
2189*4882a593Smuzhiyun 			rga_read(RGA3_INT_RAW, scheduler),
2190*4882a593Smuzhiyun 			rga_read(RGA3_STATUS0, scheduler),
2191*4882a593Smuzhiyun 			rga_read(RGA3_CMD_STATE, scheduler));
2192*4882a593Smuzhiyun 
2193*4882a593Smuzhiyun 	if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) {
2194*4882a593Smuzhiyun 		if (job->intr_status & m_RGA3_INT_RAG_MI_RD_BUS_ERR) {
2195*4882a593Smuzhiyun 			pr_err("DMA read bus error, please check size of the input_buffer or whether the buffer has been freed.\n");
2196*4882a593Smuzhiyun 			job->ret = -EFAULT;
2197*4882a593Smuzhiyun 		} else if (job->intr_status & m_RGA3_INT_WIN0_FBCD_DEC_ERR) {
2198*4882a593Smuzhiyun 			pr_err("win0 FBC decoder error, please check the fbc image of the source.\n");
2199*4882a593Smuzhiyun 			job->ret = -EFAULT;
2200*4882a593Smuzhiyun 		} else if (job->intr_status & m_RGA3_INT_WIN1_FBCD_DEC_ERR) {
2201*4882a593Smuzhiyun 			pr_err("win1 FBC decoder error, please check the fbc image of the source.\n");
2202*4882a593Smuzhiyun 			job->ret = -EFAULT;
2203*4882a593Smuzhiyun 		} else if (job->intr_status & m_RGA3_INT_RGA_MI_WR_BUS_ERR) {
2204*4882a593Smuzhiyun 			pr_err("wr buss error, please check size of the output_buffer or whether the buffer has been freed.\n");
2205*4882a593Smuzhiyun 			job->ret = -EFAULT;
2206*4882a593Smuzhiyun 		}
2207*4882a593Smuzhiyun 
2208*4882a593Smuzhiyun 		if (job->ret == 0) {
2209*4882a593Smuzhiyun 			pr_err("rga intr error[0x%x]!\n", job->intr_status);
2210*4882a593Smuzhiyun 			job->ret = -EFAULT;
2211*4882a593Smuzhiyun 		}
2212*4882a593Smuzhiyun 	}
2213*4882a593Smuzhiyun 
2214*4882a593Smuzhiyun 	return IRQ_HANDLED;
2215*4882a593Smuzhiyun }
2216*4882a593Smuzhiyun 
2217*4882a593Smuzhiyun const struct rga_backend_ops rga3_ops = {
2218*4882a593Smuzhiyun 	.get_version = rga3_get_version,
2219*4882a593Smuzhiyun 	.set_reg = rga3_set_reg,
2220*4882a593Smuzhiyun 	.init_reg = rga3_init_reg,
2221*4882a593Smuzhiyun 	.soft_reset = rga3_soft_reset,
2222*4882a593Smuzhiyun 	.read_back_reg = NULL,
2223*4882a593Smuzhiyun 	.irq = rga3_irq,
2224*4882a593Smuzhiyun 	.isr_thread = rga3_isr_thread,
2225*4882a593Smuzhiyun };
2226