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