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