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