1 /* g2d_bsp.c
2 *
3 * Copyright (c) 2011 Allwinnertech Co., Ltd.
4 * 2011 Yupu Tang
5 *
6 * G2D driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
16 * GNU General Public License for more details.
17 */
18
19 #include "g2d_regs.h"
20 #include "g2d_bsp.h"
21
22 static unsigned long base_addr;
23
24 /* byte input */
25 #define read_bvalue(offset) get_bvalue(base_addr + offset)
26 /* byte output */
27 #define write_bvalue(offset, value) put_bvalue(base_addr + offset, value)
28 /* half word input */
29 #define read_hvalue(offset) get_hvalue(base_addr + offset)
30 /* half word output */
31 #define write_hvalue(offset, value) put_hvalue(base_addr + offset, value)
32 /* word input */
33 #define read_wvalue(offset) get_wvalue(base_addr + offset)
34 /* word output */
35 #define write_wvalue(offset, value) put_wvalue(base_addr + offset, value)
36
37 __s32 csc0coeff[12] = {
38
39 0x4a7, 0x1e6f, 0x1cbf, 0x877,
40 0x4a7, 0x00, 0x662, 0x3211,
41 0x4a7, 0x812, 0x00, 0x2eb1
42 };
43 __s32 csc1coeff[12] = {
44
45 0x4a7, 0x1e6f, 0x1cbf, 0x877,
46 0x4a7, 0x00, 0x662, 0x3211,
47 0x4a7, 0x812, 0x00, 0x2eb1
48 };
49
50 __s32 csc2coeff[12] = {
51
52 0x204, 0x107, 0x64, 0x100, /* YG,YR,YB,YC */
53 0x1ED6, 0x1F69, 0x1C1, 0x800, /* UG,UR,UB,UC */
54 0x1E87, 0x1C1, 0x1FB8, 0x800, /* VG,VR,VB,VC */
55 };
56
57 __s32 csc2coeff_VUVU[12] = {
58
59 0x204, 0x107, 0x64, 0x100, /* YG,YR,YB,YC */
60 0x1E87, 0x1C1, 0x1FB8, 0x800, /* VG,VR,VB,VC */
61 0x1ED6, 0x1F69, 0x1C1, 0x800, /* UG,UR,UB,UC */
62 };
63
64 __s32 scalercoeff[64] = {
65
66 /* Horizontal Filtering Coefficient(0x200-0x27c) */
67 0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, 0x00063efc,
68 0xff083dfc, 0x000a3bfb, 0xff0d39fb, 0xff0f37fb, 0xff1136fa,
69 0xfe1433fb, 0xfe1631fb, 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb,
70 0xfc2127fc, 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd,
71 0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff, 0xfb370fff,
72 0xfb390dff, 0xfb3b0a00, 0xfc3d08ff, 0xfc3e0600, 0xfd3f0400,
73 0xfe3f0300, 0xff400100,
74
75 /* Vertical Filtering Coefficient(0x280-0x2fc) */
76 0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, 0x00063efc,
77 0xff083dfc, 0x000a3bfb, 0xff0d39fb, 0xff0f37fb, 0xff1136fa,
78 0xfe1433fb, 0xfe1631fb, 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb,
79 0xfc2127fc, 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd,
80 0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff, 0xfb370fff,
81 0xfb390dff, 0xfb3b0a00, 0xfc3d08ff, 0xfc3e0600, 0xfd3f0400,
82 0xfe3f0300, 0xff400100,
83 };
84
85 /* Set the Color Space Converter Coefficient Parameter */
csc_coeff_set(void)86 void csc_coeff_set(void)
87 {
88 __u32 i, j;
89
90 /* 0x180-0x1ac */
91 for (i = 0, j = 0; i < 12; i++, j += 4)
92 write_wvalue(G2D_CSC01_ADDR_REG + j,
93 (((csc1coeff[i] & 0xFFFF) << 16) |
94 (csc0coeff[i] & 0xFFFF)));
95
96 /* 0x1c0-0x1ec */
97 for (i = 0, j = 0; i < 12; i++, j += 4)
98 write_wvalue(G2D_CSC2_ADDR_REG + j, csc2coeff[i]&0xFFFF);
99
100 }
101
102 /* Set the Scaling Horizontal/Vertical Filtering Coefficient Parameter */
scaler_coeff_set(void)103 void scaler_coeff_set(void)
104 {
105 __u32 i, j;
106
107 /* 0x200-0x2fc */
108 for (i = 0, j = 0; i < 64; i++, j += 4)
109 write_wvalue(G2D_SCALER_HFILTER_REG + j, scalercoeff[i]);
110
111 }
112
mixer_set_reg_base(unsigned long addr)113 __u32 mixer_set_reg_base(unsigned long addr)
114 {
115 base_addr = addr;
116 return 0;
117 }
118
119 /* clear most of the registers value to default */
mixer_reg_init(void)120 __u32 mixer_reg_init(void)
121 {
122 __u32 i;
123
124 for (i = 0; i <= 0x148; i += 4)
125 write_wvalue(i, 0);
126 write_wvalue(G2D_SCAN_ORDER_REG, 0x15FF0000);
127
128 /* initial the color space converter parameter */
129 csc_coeff_set();
130
131 /* initial the scaler coefficient parameter */
132 scaler_coeff_set();
133
134 return 0;
135 }
136
mixer_set_fillcolor(__u32 color,__u32 sel)137 __u32 mixer_set_fillcolor(__u32 color, __u32 sel)
138 {
139 __u32 value;
140
141 if (sel == 1) {
142 value = read_wvalue(G2D_DMA1_CONTROL_REG) | G2D_FILL_ENABLE;
143 write_wvalue(G2D_DMA1_CONTROL_REG, value);
144 write_wvalue(G2D_DMA1_FILLCOLOR_REG, color);
145 } else if (sel == 2) {
146 value = read_wvalue(G2D_DMA2_CONTROL_REG) | G2D_FILL_ENABLE;
147 write_wvalue(G2D_DMA2_CONTROL_REG, value);
148 write_wvalue(G2D_DMA2_FILLCOLOR_REG, color);
149 } else if (sel == 3) {
150 value = read_wvalue(G2D_DMA3_CONTROL_REG) | G2D_FILL_ENABLE;
151 write_wvalue(G2D_DMA3_CONTROL_REG, value);
152 write_wvalue(G2D_DMA3_FILLCOLOR_REG, color);
153 } else {
154 value = read_wvalue(G2D_DMA0_CONTROL_REG) | G2D_FILL_ENABLE;
155 write_wvalue(G2D_DMA0_CONTROL_REG, value);
156 write_wvalue(G2D_DMA0_FILLCOLOR_REG, color);
157 }
158
159 return 0;
160 }
161
mixer_bpp_count(__u32 format)162 __u32 mixer_bpp_count(__u32 format)
163 {
164 __u32 bpp = 32;
165
166 switch (format) {
167 case G2D_FMT_1BPP_MONO:
168 case G2D_FMT_1BPP_PALETTE:
169 bpp = 1;
170 break;
171
172 case G2D_FMT_2BPP_MONO:
173 case G2D_FMT_2BPP_PALETTE:
174 bpp = 2;
175 break;
176
177 case G2D_FMT_4BPP_MONO:
178 case G2D_FMT_4BPP_PALETTE:
179 bpp = 4;
180 break;
181
182 case G2D_FMT_8BPP_MONO:
183 case G2D_FMT_8BPP_PALETTE:
184 case G2D_FMT_PYUV422UVC:
185 case G2D_FMT_PYUV420UVC:
186 case G2D_FMT_PYUV411UVC:
187 case G2D_FMT_PYUV422:
188 case G2D_FMT_PYUV420:
189 case G2D_FMT_PYUV411:
190 case G2D_FMT_PYUV422UVC_MB16:
191 case G2D_FMT_PYUV420UVC_MB16:
192 case G2D_FMT_PYUV411UVC_MB16:
193 case G2D_FMT_PYUV422UVC_MB32:
194 case G2D_FMT_PYUV420UVC_MB32:
195 case G2D_FMT_PYUV411UVC_MB32:
196 case G2D_FMT_PYUV422UVC_MB64:
197 case G2D_FMT_PYUV420UVC_MB64:
198 case G2D_FMT_PYUV411UVC_MB64:
199 case G2D_FMT_PYUV422UVC_MB128:
200 case G2D_FMT_PYUV420UVC_MB128:
201 case G2D_FMT_PYUV411UVC_MB128:
202 bpp = 8;
203 break;
204
205 case G2D_FMT_IYUV422:
206 case G2D_FMT_RGB565:
207 case G2D_FMT_BGR565:
208 case G2D_FMT_ARGB1555:
209 case G2D_FMT_ABGR1555:
210 case G2D_FMT_RGBA5551:
211 case G2D_FMT_BGRA5551:
212 case G2D_FMT_ARGB4444:
213 case G2D_FMT_ABGR4444:
214 case G2D_FMT_RGBA4444:
215 case G2D_FMT_BGRA4444:
216 bpp = 16;
217 break;
218
219 case G2D_FMT_ARGB_AYUV8888:
220 case G2D_FMT_BGRA_VUYA8888:
221 case G2D_FMT_ABGR_AVUY8888:
222 case G2D_FMT_RGBA_YUVA8888:
223 case G2D_FMT_XRGB8888:
224 case G2D_FMT_BGRX8888:
225 case G2D_FMT_XBGR8888:
226 case G2D_FMT_RGBX8888:
227 bpp = 32;
228 break;
229
230 default:
231 bpp = 32;
232 break;
233 }
234 return bpp;
235
236 }
237
mixer_in_fmtseq_set(__u32 format,__u32 pixel_seq)238 __u32 mixer_in_fmtseq_set(__u32 format, __u32 pixel_seq)
239 {
240 __u32 val = 32;
241
242 switch (format) {
243 case G2D_FMT_1BPP_MONO:
244 case G2D_FMT_1BPP_PALETTE:
245 if (pixel_seq == G2D_SEQ_1BPP_LITTER_LITTER)
246 val = 0x3A;
247 else if (pixel_seq == G2D_SEQ_1BPP_BIG_LITTER)
248 val = 0x1A;
249 else if (pixel_seq == G2D_SEQ_1BPP_LITTER_BIG)
250 val = 0x2A;
251 else
252 val = 0xA;
253 break;
254
255 case G2D_FMT_2BPP_MONO:
256 case G2D_FMT_2BPP_PALETTE:
257 if (pixel_seq == G2D_SEQ_2BPP_LITTER_LITTER)
258 val = 0x39;
259 else if (pixel_seq == G2D_SEQ_2BPP_BIG_LITTER)
260 val = 0x19;
261 else if (pixel_seq == G2D_SEQ_2BPP_LITTER_BIG)
262 val = 0x29;
263 else
264 val = 0x9;
265 break;
266
267 case G2D_FMT_4BPP_MONO:
268 case G2D_FMT_4BPP_PALETTE:
269 if (pixel_seq == G2D_SEQ_P01234567)
270 val = 0x38;
271 else if (pixel_seq == G2D_SEQ_P67452301)
272 val = 0x18;
273 else if (pixel_seq == G2D_SEQ_P10325476)
274 val = 0x28;
275 else
276 val = 0x8;
277 break;
278
279 case G2D_FMT_8BPP_MONO:
280 case G2D_FMT_8BPP_PALETTE:
281 if (pixel_seq == G2D_SEQ_P0123)
282 val = 0x17;
283 else
284 val = 0x7;
285 break;
286
287 case G2D_FMT_PYUV422UVC:
288 case G2D_FMT_PYUV420UVC:
289 case G2D_FMT_PYUV411UVC:
290 case G2D_FMT_PYUV422UVC_MB16:
291 case G2D_FMT_PYUV420UVC_MB16:
292 case G2D_FMT_PYUV411UVC_MB16:
293 case G2D_FMT_PYUV422UVC_MB32:
294 case G2D_FMT_PYUV420UVC_MB32:
295 case G2D_FMT_PYUV411UVC_MB32:
296 case G2D_FMT_PYUV422UVC_MB64:
297 case G2D_FMT_PYUV420UVC_MB64:
298 case G2D_FMT_PYUV411UVC_MB64:
299 case G2D_FMT_PYUV422UVC_MB128:
300 case G2D_FMT_PYUV420UVC_MB128:
301 case G2D_FMT_PYUV411UVC_MB128:
302 val = 0x6;
303 break;
304
305 case G2D_FMT_IYUV422:
306 if (pixel_seq == G2D_SEQ_YVYU)
307 val = 0x14;
308 else
309 val = 0x4;
310 break;
311 case G2D_FMT_RGB565:
312 if (pixel_seq == G2D_SEQ_P01)
313 val = 0x13;
314 else
315 val = 0x3;
316 break;
317 case G2D_FMT_BGR565:
318 if (pixel_seq == G2D_SEQ_P01)
319 val = 0x93;
320 else
321 val = 0x83;
322 break;
323 case G2D_FMT_ARGB1555:
324 if (pixel_seq == G2D_SEQ_P01)
325 val = 0x12;
326 else
327 val = 0x2;
328 break;
329 case G2D_FMT_ABGR1555:
330 if (pixel_seq == G2D_SEQ_P01)
331 val = 0x92;
332 else
333 val = 0x82;
334 break;
335 case G2D_FMT_RGBA5551:
336 if (pixel_seq == G2D_SEQ_P01)
337 val = 0xb2;
338 else
339 val = 0xa2;
340 break;
341 case G2D_FMT_BGRA5551:
342 if (pixel_seq == G2D_SEQ_P01)
343 val = 0x32;
344 else
345 val = 0x22;
346 break;
347 case G2D_FMT_ARGB4444:
348 if (pixel_seq == G2D_SEQ_P01)
349 val = 0x11;
350 else
351 val = 0x01;
352 break;
353 case G2D_FMT_ABGR4444:
354 if (pixel_seq == G2D_SEQ_P01)
355 val = 0x91;
356 else
357 val = 0x81;
358 break;
359 case G2D_FMT_RGBA4444:
360 if (pixel_seq == G2D_SEQ_P01)
361 val = 0xb1;
362 else
363 val = 0xa1;
364 break;
365 case G2D_FMT_BGRA4444:
366 if (pixel_seq == G2D_SEQ_P01)
367 val = 0x31;
368 else
369 val = 0x21;
370 break;
371 case G2D_FMT_ARGB_AYUV8888:
372 case G2D_FMT_XRGB8888:
373 val = 0x0;
374 break;
375 case G2D_FMT_BGRA_VUYA8888:
376 case G2D_FMT_BGRX8888:
377 val = 0x20;
378 break;
379 case G2D_FMT_ABGR_AVUY8888:
380 case G2D_FMT_XBGR8888:
381 val = 0x80;
382 break;
383 case G2D_FMT_RGBA_YUVA8888:
384 case G2D_FMT_RGBX8888:
385 val = 0xa0;
386 break;
387
388 default:
389 val = 0;
390 break;
391 }
392 return val << 8;
393
394 }
395
mixer_in_csc_set(__u32 format)396 __u32 mixer_in_csc_set(__u32 format)
397 {
398 __u32 val = 0;
399
400 switch (format) {
401 case G2D_FMT_IYUV422:
402 val = 0x11;
403 break;
404 case G2D_FMT_PYUV422UVC:
405 case G2D_FMT_PYUV422UVC_MB16:
406 case G2D_FMT_PYUV422UVC_MB32:
407 case G2D_FMT_PYUV422UVC_MB64:
408 case G2D_FMT_PYUV422UVC_MB128:
409 val = 0x21;
410 break;
411 case G2D_FMT_PYUV420UVC:
412 case G2D_FMT_PYUV420UVC_MB16:
413 case G2D_FMT_PYUV420UVC_MB32:
414 case G2D_FMT_PYUV420UVC_MB64:
415 case G2D_FMT_PYUV420UVC_MB128:
416 val = 0x31;
417 break;
418 case G2D_FMT_PYUV411UVC:
419 case G2D_FMT_PYUV411UVC_MB16:
420 case G2D_FMT_PYUV411UVC_MB32:
421 case G2D_FMT_PYUV411UVC_MB64:
422 case G2D_FMT_PYUV411UVC_MB128:
423 val = 0x41;
424 break;
425
426 default:
427 val = 0;
428 break;
429 }
430
431 return val;
432 }
433
mixer_out_fmtseq_set(__u32 format,__u32 pixel_seq)434 __u32 mixer_out_fmtseq_set(__u32 format, __u32 pixel_seq)
435 {
436 __u32 val = 0;
437
438 switch (format) {
439 case G2D_FMT_1BPP_MONO:
440 if (pixel_seq == G2D_SEQ_1BPP_LITTER_LITTER)
441 val = 0x38A;
442 else if (pixel_seq == G2D_SEQ_1BPP_BIG_LITTER)
443 val = 0x18A;
444 else if (pixel_seq == G2D_SEQ_1BPP_LITTER_BIG)
445 val = 0x28A;
446 else
447 val = 0x8A;
448 break;
449
450 case G2D_FMT_2BPP_MONO:
451 if (pixel_seq == G2D_SEQ_2BPP_LITTER_LITTER)
452 val = 0x389;
453 else if (pixel_seq == G2D_SEQ_2BPP_BIG_LITTER)
454 val = 0x189;
455 else if (pixel_seq == G2D_SEQ_2BPP_LITTER_BIG)
456 val = 0x289;
457 else
458 val = 0x89;
459 break;
460
461 case G2D_FMT_4BPP_MONO:
462 if (pixel_seq == G2D_SEQ_P01234567)
463 val = 0x388;
464 else if (pixel_seq == G2D_SEQ_P67452301)
465 val = 0x188;
466 else if (pixel_seq == G2D_SEQ_P10325476)
467 val = 0x288;
468 else
469 val = 0x88;
470 break;
471
472 case G2D_FMT_8BPP_MONO:
473 if (pixel_seq == G2D_SEQ_P0123)
474 val = 0x187;
475 else
476 val = 0x87;
477 break;
478 case G2D_FMT_PYUV422:
479 val = 0x86;
480 break;
481 case G2D_FMT_PYUV422UVC:
482 val = 0x85;
483 break;
484 case G2D_FMT_PYUV420UVC:
485 val = 0x8b;
486 break;
487 case G2D_FMT_PYUV420:
488 val = 0x8c;
489 break;
490 case G2D_FMT_PYUV411UVC:
491 val = 0x8d;
492 break;
493 case G2D_FMT_PYUV411:
494 val = 0x8e;
495 break;
496 case G2D_FMT_IYUV422:
497 if (pixel_seq == G2D_SEQ_YVYU)
498 val = 0x184;
499 else
500 val = 0x84;
501 break;
502 case G2D_FMT_RGB565:
503 if (pixel_seq == G2D_SEQ_P01)
504 val = 0x183;
505 else
506 val = 0x3;
507 break;
508 case G2D_FMT_BGR565:
509 if (pixel_seq == G2D_SEQ_P01)
510 val = 0x983;
511 else
512 val = 0x883;
513 break;
514 case G2D_FMT_ARGB1555:
515 if (pixel_seq == G2D_SEQ_P01)
516 val = 0x182;
517 else
518 val = 0x82;
519 break;
520 case G2D_FMT_ABGR1555:
521 if (pixel_seq == G2D_SEQ_P01)
522 val = 0x982;
523 else
524 val = 0x882;
525 break;
526 case G2D_FMT_RGBA5551:
527 if (pixel_seq == G2D_SEQ_P01)
528 val = 0xb82;
529 else
530 val = 0xa82;
531 break;
532 case G2D_FMT_BGRA5551:
533 if (pixel_seq == G2D_SEQ_P01)
534 val = 0x382;
535 else
536 val = 0x282;
537 break;
538 case G2D_FMT_ARGB4444:
539 if (pixel_seq == G2D_SEQ_P01)
540 val = 0x181;
541 else
542 val = 0x81;
543 break;
544 case G2D_FMT_ABGR4444:
545 if (pixel_seq == G2D_SEQ_P01)
546 val = 0x981;
547 else
548 val = 0x881;
549 break;
550 case G2D_FMT_RGBA4444:
551 if (pixel_seq == G2D_SEQ_P01)
552 val = 0xb81;
553 else
554 val = 0xa81;
555 break;
556 case G2D_FMT_BGRA4444:
557 if (pixel_seq == G2D_SEQ_P01)
558 val = 0x381;
559 else
560 val = 0x281;
561 break;
562 case G2D_FMT_ARGB_AYUV8888:
563 case G2D_FMT_XRGB8888:
564 val = 0x80;
565 break;
566 case G2D_FMT_BGRA_VUYA8888:
567 case G2D_FMT_BGRX8888:
568 val = 0x280;
569 break;
570 case G2D_FMT_ABGR_AVUY8888:
571 case G2D_FMT_XBGR8888:
572 val = 0x880;
573 break;
574 case G2D_FMT_RGBA_YUVA8888:
575 case G2D_FMT_RGBX8888:
576 val = 0xa80;
577 break;
578
579 default:
580 val = 80;
581 break;
582 }
583 return val;
584
585 }
586
mixer_get_addr(__u32 buffer_addr,__u32 format,__u32 stride,__u32 x,__u32 y)587 __u64 mixer_get_addr(__u32 buffer_addr, __u32 format, __u32 stride,
588 __u32 x, __u32 y)
589 {
590 __u32 bpp = 0;
591 __u64 addr = 0;
592
593 bpp = mixer_bpp_count(format);
594 addr = (__u64) (buffer_addr) * 8 +
595 (__u64) ((stride * y + x) * bpp); /* bits */
596
597 return addr;
598 }
599
mixer_get_irq(void)600 __u32 mixer_get_irq(void)
601 {
602 __u32 reg_val = 0;
603
604 reg_val = read_wvalue(G2D_STATUS_REG);
605
606 return reg_val;
607 }
608
mixer_get_irq0(void)609 __u32 mixer_get_irq0(void)
610 {
611 __u32 reg_val = 0;
612
613 reg_val = read_wvalue(G2D_CMDQ_STS_REG);
614
615 return reg_val;
616 }
617
mixer_clear_init(void)618 __u32 mixer_clear_init(void)
619 {
620
621 write_wvalue(G2D_STATUS_REG, 0x300);
622 write_wvalue(G2D_CONTROL_REG, 0x0);
623
624 return 0;
625 }
626
mixer_clear_init0(void)627 __u32 mixer_clear_init0(void)
628 {
629
630 write_wvalue(G2D_CMDQ_STS_REG, 0x100);
631 write_wvalue(G2D_CMDQ_CTL_REG, 0x0);
632
633 return 0;
634 }
635
mixer_set_rotate_reg(__u32 flag)636 __u32 mixer_set_rotate_reg(__u32 flag)
637 {
638 __u32 rot = 0;
639
640 if (flag & G2D_BLT_FLIP_HORIZONTAL)
641 rot = 0x10;
642 else if (flag & G2D_BLT_FLIP_VERTICAL)
643 rot = 0x20;
644 else if (flag & G2D_BLT_ROTATE90)
645 rot = 0x50;
646 else if (flag & G2D_BLT_ROTATE180)
647 rot = 0x30;
648 else if (flag & G2D_BLT_ROTATE270)
649 rot = 0x60;
650 else if (flag & G2D_BLT_MIRROR45)
651 rot = 0x70;
652 else if (flag & G2D_BLT_MIRROR135)
653 rot = 0x40;
654 else
655 rot = 0;
656
657 return rot;
658 }
659
mixer_fillrectangle(g2d_fillrect * para)660 __s32 mixer_fillrectangle(g2d_fillrect *para)
661 {
662 __u32 reg_val = 0;
663 __u64 addr_val;
664 __s32 result = 0;
665
666 mixer_reg_init();/* initial mixer register */
667
668 /* channel0 is the fill surface */
669 write_wvalue(G2D_DMA0_SIZE_REG,
670 (para->dst_rect.w - 1) | ((para->dst_rect.h - 1) << 16));
671
672 /* globe alpha mode */
673 if (para->flag & G2D_FIL_PLANE_ALPHA)
674 reg_val |= (para->alpha << 24) | 0x4;
675 else if (para->flag & G2D_FIL_MULTI_ALPHA)
676 reg_val |= (para->alpha << 24) | 0x8;
677 reg_val |= 0x1;
678 write_wvalue(G2D_DMA0_CONTROL_REG, reg_val);
679 mixer_set_fillcolor(para->color, 0);
680 if ((para->flag & G2D_FIL_PLANE_ALPHA)
681 || (para->flag & G2D_FIL_PIXEL_ALPHA)
682 || (para->flag & G2D_FIL_MULTI_ALPHA)) {
683 /* channel3 is the dst surface */
684 addr_val =
685 mixer_get_addr(para->dst_image.addr[0],
686 para->dst_image.format, para->dst_image.w,
687 para->dst_rect.x, para->dst_rect.y);
688 reg_val = (addr_val >> 32) & 0xF; /* high addr in bits */
689 write_wvalue(G2D_DMA_HADDR_REG, reg_val << 24);
690 reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
691 write_wvalue(G2D_DMA3_LADDR_REG, reg_val);
692 write_wvalue(G2D_DMA3_STRIDE_REG,
693 para->dst_image.w *
694 mixer_bpp_count(para->dst_image.format));
695 write_wvalue(G2D_DMA3_SIZE_REG,
696 (para->dst_rect.w -
697 1) | ((para->dst_rect.h - 1) << 16));
698 reg_val = read_wvalue(G2D_DMA3_CONTROL_REG);
699
700 /* palette format */
701 if (para->dst_image.format > 0x19)
702 reg_val |= 0x2;
703 reg_val |=
704 G2D_IDMA_ENABLE | mixer_in_fmtseq_set(para->dst_image.
705 format,
706 para->dst_image.
707 pixel_seq);
708 write_wvalue(G2D_DMA3_CONTROL_REG, reg_val);
709 write_wvalue(G2D_CK_CONTROL_REG, 0x1);
710 }
711 write_wvalue(G2D_ROP_INDEX0_REG, 0x840);
712
713 /* output surface is the dst surface */
714 write_wvalue(G2D_OUTPUT_SIZE_REG,
715 (para->dst_rect.w - 1) | ((para->dst_rect.h - 1) << 16));
716
717 addr_val =
718 mixer_get_addr(para->dst_image.addr[0], para->dst_image.format,
719 para->dst_image.w, para->dst_rect.x,
720 para->dst_rect.y);
721 reg_val = (addr_val >> 32) & 0xF; /* high addr in bits */
722 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
723 reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
724 write_wvalue(G2D_OUTPUT0_LADDR_REG, reg_val);
725
726 write_wvalue(G2D_OUTPUT0_STRIDE_REG,
727 para->dst_image.w *
728 mixer_bpp_count(para->dst_image.format));
729 write_wvalue(G2D_OUTPUT_CONTROL_REG,
730 mixer_out_fmtseq_set(para->dst_image.format,
731 para->dst_image.pixel_seq));
732
733 /* start */
734 write_wvalue(G2D_CONTROL_REG, 0);
735 write_wvalue(G2D_CONTROL_REG, 0x303);
736 result = g2d_wait_cmd_finish();
737
738 return result;
739 }
740
mixer_blt(g2d_blt * para,enum g2d_scan_order scan_order)741 __s32 mixer_blt(g2d_blt *para, enum g2d_scan_order scan_order)
742 {
743 __u32 bppnum = 0;
744 __u32 reg_val = 0;
745 __u64 addr_val;
746 __s32 result = 0;
747 __u32 i, j;
748
749 mixer_reg_init(); /* initial mixer register */
750 if ((para->dst_image.format > 0x16) && (para->dst_image.format < 0x1A)
751 && (para->dst_image.pixel_seq == G2D_SEQ_VUVU)) {
752 for (i = 0, j = 0; i < 12; i++, j += 4)
753 write_wvalue(G2D_CSC2_ADDR_REG + j,
754 csc2coeff_VUVU[i] & 0xFFFF);
755 /* 0x1c0-0x1ec */
756 }
757
758 /* src surface */
759 addr_val =
760 mixer_get_addr(para->src_image.addr[0], para->src_image.format,
761 para->src_image.w, para->src_rect.x,
762 para->src_rect.y);
763 reg_val = (addr_val >> 32) & 0xF; /* high addr in bits */
764 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
765 reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
766 write_wvalue(G2D_DMA0_LADDR_REG, reg_val);
767 write_wvalue(G2D_DMA0_STRIDE_REG,
768 para->src_image.w *
769 mixer_bpp_count(para->src_image.format));
770 write_wvalue(G2D_DMA0_SIZE_REG,
771 (para->src_rect.w - 1) | ((para->src_rect.h - 1) << 16));
772 reg_val = read_wvalue(G2D_DMA0_CONTROL_REG);
773 reg_val |=
774 mixer_in_fmtseq_set(para->src_image.format,
775 para->src_image.pixel_seq) | G2D_IDMA_ENABLE;
776
777 /* rgbx/bgrx/xrgb/xbgr format */
778 if ((para->src_image.format > 0x03) && (para->src_image.format < 0x08))
779 reg_val |= (0xFF << 24) | 0x4;
780
781 /* palette format */
782 if ((para->src_image.format > 0x1C) && (para->src_image.format < 0x21))
783 reg_val |= 0x2;
784
785 /* globe alpha mode */
786 if (para->flag & G2D_BLT_PLANE_ALPHA)
787 reg_val |= (para->alpha << 24) | 0x4;
788 else if (para->flag & G2D_BLT_MULTI_ALPHA)
789 reg_val |= (para->alpha << 24) | 0x8;
790
791 /* rotate/mirror */
792 reg_val |= mixer_set_rotate_reg(para->flag);
793 write_wvalue(G2D_DMA0_CONTROL_REG, reg_val);
794 reg_val = mixer_in_csc_set(para->src_image.format);
795 write_wvalue(G2D_CSC0_CONTROL_REG, reg_val);
796 reg_val = mixer_in_csc_set(para->dst_image.format);
797 write_wvalue(G2D_CSC1_CONTROL_REG, reg_val);
798
799 /* pyuv422/420/411uvc */
800 if ((para->src_image.format > 0x16) &&
801 (para->src_image.format < 0x1A)) {
802 if (para->src_image.format == G2D_FMT_PYUV411UVC)
803 bppnum = 4;
804 else
805 bppnum = 8;
806 if (para->src_image.format == G2D_FMT_PYUV420UVC)
807 addr_val =
808 (__u64) para->src_image.addr[1] * 8 +
809 (__u64) ((para->src_image.w *
810 (para->src_rect.y / 2) +
811 para->src_rect.x) * bppnum);
812 else
813 addr_val =
814 (__u64) para->src_image.addr[1] * 8 +
815 (__u64) ((para->src_image.w * para->src_rect.y +
816 para->src_rect.x) * bppnum);
817 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
818 reg_val |= ((addr_val >> 32) & 0xF) << 8;/* high addr in bits */
819 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
820 reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
821 write_wvalue(G2D_DMA1_LADDR_REG, reg_val);
822 write_wvalue(G2D_DMA1_STRIDE_REG, para->src_image.w * bppnum);
823 write_wvalue(G2D_DMA1_SIZE_REG,
824 (para->src_rect.w -
825 1) | ((para->src_rect.h - 1) << 16));
826 reg_val = read_wvalue(G2D_DMA1_CONTROL_REG);
827 reg_val |= (5 << 8) | G2D_IDMA_ENABLE;
828
829 /* rotate/mirror */
830 reg_val |= mixer_set_rotate_reg(para->flag);
831 write_wvalue(G2D_DMA1_CONTROL_REG, reg_val);
832 }
833 mixer_micro_block_set(para);
834 write_wvalue(G2D_DMA1_FILLCOLOR_REG, 0xFFFFFFFF);
835 write_wvalue(G2D_DMA2_FILLCOLOR_REG, 0xFFFFFFFF);
836
837 if ((para->flag & G2D_BLT_PIXEL_ALPHA)
838 || (para->flag & G2D_BLT_PLANE_ALPHA)
839 || (para->flag & G2D_BLT_MULTI_ALPHA)
840 || (para->flag & G2D_BLT_SRC_COLORKEY)
841 || (para->flag & G2D_BLT_DST_COLORKEY)) {
842 /* pyuv422/420/411uvc */
843 if ((para->dst_image.format > 0x16)
844 && (para->dst_image.format < 0x1A)) {
845 if (para->dst_image.format == G2D_FMT_PYUV411UVC)
846 bppnum = 4;
847 else
848 bppnum = 8;
849 if (para->dst_image.format == G2D_FMT_PYUV420UVC)
850 addr_val =
851 (__u64) para->dst_image.addr[1] * 8 +
852 (__u64) ((para->dst_image.w *
853 (para->dst_y / 2) +
854 para->dst_x) * bppnum);
855 else
856 addr_val =
857 (__u64) para->dst_image.addr[1] * 8 +
858 (__u64) ((para->dst_image.w * para->dst_y +
859 para->dst_x) * bppnum);
860 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
861 /* high addr in bits */
862 reg_val |= ((addr_val >> 32) & 0xF) << 16;
863 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
864 /* low addr in bits */
865 reg_val = addr_val & 0xFFFFFFFF;
866 write_wvalue(G2D_DMA2_LADDR_REG, reg_val);
867 write_wvalue(G2D_DMA2_STRIDE_REG,
868 para->dst_image.w * bppnum);
869 write_wvalue(G2D_DMA2_SIZE_REG,
870 (para->src_rect.w -
871 1) | ((para->src_rect.h - 1) << 16));
872 reg_val = read_wvalue(G2D_DMA2_CONTROL_REG);
873 reg_val |= (5 << 8) | G2D_IDMA_ENABLE;
874 write_wvalue(G2D_DMA2_CONTROL_REG, reg_val);
875 }
876
877 /* channel3 is dst surface */
878 addr_val =
879 mixer_get_addr(para->dst_image.addr[0],
880 para->dst_image.format, para->dst_image.w,
881 para->dst_x, para->dst_y);
882 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
883 reg_val |= ((addr_val >> 32) & 0xF) << 24;/*high addr in bits*/
884 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
885 reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
886 write_wvalue(G2D_DMA3_LADDR_REG, reg_val);
887 write_wvalue(G2D_DMA3_STRIDE_REG,
888 para->dst_image.w *
889 mixer_bpp_count(para->dst_image.format));
890 if ((para->flag & G2D_BLT_ROTATE90)
891 || (para->flag & G2D_BLT_ROTATE270))
892 write_wvalue(G2D_DMA3_SIZE_REG,
893 (para->src_rect.h -
894 1) | ((para->src_rect.w - 1) << 16));
895 else
896 write_wvalue(G2D_DMA3_SIZE_REG,
897 (para->src_rect.w -
898 1) | ((para->src_rect.h - 1) << 16));
899 reg_val = read_wvalue(G2D_DMA3_CONTROL_REG);
900 reg_val |=
901 mixer_in_fmtseq_set(para->dst_image.format,
902 para->dst_image.
903 pixel_seq) | G2D_IDMA_ENABLE;
904
905 /* rgbx/bgrx/xrgb/xbgr format */
906 if ((para->dst_image.format > 0x03)
907 && (para->dst_image.format < 0x08)) {
908 reg_val |= (0xFF << 24) | 0x4;
909 }
910 write_wvalue(G2D_DMA3_CONTROL_REG, reg_val);
911 }
912
913 /* colorkey */
914 if (para->flag & G2D_BLT_SRC_COLORKEY) {
915 reg_val = 0x3;
916 } else if (para->flag & G2D_BLT_DST_COLORKEY) {
917 reg_val = 0x5;
918 } else if ((para->flag & G2D_BLT_PIXEL_ALPHA)
919 || (para->flag & G2D_BLT_PLANE_ALPHA)
920 || (para->flag & G2D_BLT_MULTI_ALPHA)) {
921 reg_val = 0x1;
922 } else {
923 reg_val = 0x0;
924 }
925 write_wvalue(G2D_CK_CONTROL_REG, reg_val);
926 write_wvalue(G2D_CK_MINCOLOR_REG, para->color);
927 write_wvalue(G2D_CK_MAXCOLOR_REG, para->color);
928
929 /* output surface is the dst surface */
930 if ((para->flag & G2D_BLT_ROTATE90) ||
931 (para->flag & G2D_BLT_ROTATE270)) {
932 write_wvalue(G2D_OUTPUT_SIZE_REG,
933 (para->src_rect.h -
934 1) | ((para->src_rect.w - 1) << 16));
935 } else {
936 write_wvalue(G2D_OUTPUT_SIZE_REG,
937 (para->src_rect.w -
938 1) | ((para->src_rect.h - 1) << 16));
939 }
940 addr_val =
941 mixer_get_addr(para->dst_image.addr[0], para->dst_image.format,
942 para->dst_image.w, para->dst_x, para->dst_y);
943 reg_val = (addr_val >> 32) & 0xF; /* high addr in bits */
944 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
945 reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
946 write_wvalue(G2D_OUTPUT0_LADDR_REG, reg_val);
947 write_wvalue(G2D_OUTPUT0_STRIDE_REG,
948 para->dst_image.w *
949 mixer_bpp_count(para->dst_image.format));
950 reg_val =
951 mixer_out_fmtseq_set(para->dst_image.format,
952 para->dst_image.pixel_seq);
953 write_wvalue(G2D_OUTPUT_CONTROL_REG, reg_val);
954
955 if ((para->dst_image.format > 0x16) &&
956 (para->dst_image.format < 0x1D)) {
957 if ((para->dst_image.format == G2D_FMT_PYUV411UVC)
958 || (para->dst_image.format == G2D_FMT_PYUV422)
959 || (para->dst_image.format == G2D_FMT_PYUV420))
960 bppnum = 4;
961 else if (para->dst_image.format == G2D_FMT_PYUV411)
962 bppnum = 2;
963 else
964 bppnum = 8;
965 if ((para->dst_image.format == G2D_FMT_PYUV420UVC)
966 || (para->dst_image.format == G2D_FMT_PYUV420))
967 addr_val =
968 (__u64) para->dst_image.addr[1] * 8 +
969 (__u64) ((para->dst_image.w * (para->dst_y / 2) +
970 para->dst_x) * bppnum);
971 else
972 addr_val =
973 (__u64) para->dst_image.addr[1] * 8 +
974 (__u64) ((para->dst_image.w * para->dst_y +
975 para->dst_x) * bppnum);
976 reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
977 reg_val |= ((addr_val >> 32) & 0xF) << 8;/* high addr in bits */
978 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
979 reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
980 write_wvalue(G2D_OUTPUT1_LADDR_REG, reg_val);
981 write_wvalue(G2D_OUTPUT1_STRIDE_REG,
982 para->dst_image.w * bppnum);
983 if (para->dst_image.format == G2D_FMT_PYUV420)
984 addr_val =
985 (__u64) para->dst_image.addr[2] * 8 +
986 (__u64) ((para->dst_image.w * (para->dst_y / 2) +
987 para->dst_x) * bppnum);
988 else if ((para->dst_image.format == G2D_FMT_PYUV422)
989 || (para->dst_image.format == G2D_FMT_PYUV411))
990 addr_val =
991 (__u64) para->dst_image.addr[2] * 8 +
992 (__u64) ((para->dst_image.w * para->dst_y +
993 para->dst_x) * bppnum);
994 else
995 addr_val = 0;
996 reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
997 reg_val |= ((addr_val >> 32) & 0xF) << 16;/*high addr in bits*/
998 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
999 reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
1000 write_wvalue(G2D_OUTPUT2_LADDR_REG, reg_val);
1001 write_wvalue(G2D_OUTPUT2_STRIDE_REG,
1002 para->dst_image.w * bppnum);
1003 write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
1004 }
1005 if ((para->dst_image.format > 0x11) && (para->dst_image.format < 0x1D))
1006 write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
1007 if ((para->flag & G2D_BLT_PIXEL_ALPHA) | (para->
1008 flag & G2D_BLT_PLANE_ALPHA) |
1009 (para->flag & G2D_BLT_MULTI_ALPHA) | (para->
1010 flag & G2D_BLT_SRC_COLORKEY) |
1011 (para->flag & G2D_BLT_DST_COLORKEY))
1012 write_wvalue(G2D_OALPHA_CONTROL_REG, 0x80);
1013 /* 0x40: A2 area keep the dst alpha,0x80: A2 area keep the
1014 * src+dst(1-src) alpha value
1015 */
1016 mixer_premultiply_set(para->flag);
1017 /*scan order */
1018 write_wvalue(G2D_SCAN_ORDER_REG, (scan_order & 0x3) << 8);
1019
1020 /* start */
1021 write_wvalue(G2D_CONTROL_REG, 0x0);
1022 write_wvalue(G2D_CONTROL_REG, 0x303);
1023 result = g2d_wait_cmd_finish();
1024
1025 return result;
1026 }
1027
mixer_stretchblt(g2d_stretchblt * para,enum g2d_scan_order scan_order)1028 __s32 mixer_stretchblt(g2d_stretchblt *para, enum g2d_scan_order scan_order)
1029 {
1030 __u32 bppnum = 0;
1031 __u32 reg_val = 0;
1032 __u32 reg_tmp = 0;
1033 __u64 addr_val;
1034 __u32 cnt, sinw, soutw, scaler_inx, scaler_iny, scaler_outx;
1035 __u32 scaler_outy, i;
1036 __s32 result = 0;
1037
1038 mixer_reg_init();/* initial mixer register */
1039
1040 /* src surface */
1041 write_wvalue(G2D_DMA0_STRIDE_REG,
1042 para->src_image.w *
1043 mixer_bpp_count(para->src_image.format));
1044 reg_val = read_wvalue(G2D_DMA0_CONTROL_REG);
1045 reg_val |=
1046 mixer_in_fmtseq_set(para->src_image.format,
1047 para->src_image.pixel_seq) | G2D_IDMA_ENABLE;
1048
1049 /* rgbx/bgrx/xrgb/xbgr format */
1050 if ((para->src_image.format > 0x03) &&
1051 (para->src_image.format < 0x08)) {
1052 reg_val |= (0xFF<<24)|0x4;
1053 }
1054
1055 /* palette format */
1056 if (para->src_image.format > 0x1C)
1057 reg_val |= 0x2;
1058 /* globe alpha mode */
1059 if (para->flag & G2D_BLT_PLANE_ALPHA)
1060 reg_val |= (para->alpha<<24)|0x4;
1061 else if (para->flag & G2D_BLT_MULTI_ALPHA)
1062 reg_val |= (para->alpha<<24)|0x8;
1063
1064 /* rotate/mirror */
1065 reg_val |= mixer_set_rotate_reg(para->flag);
1066 write_wvalue(G2D_DMA0_CONTROL_REG, reg_val);
1067 reg_val = mixer_in_csc_set(para->src_image.format);
1068 write_wvalue(G2D_CSC0_CONTROL_REG, reg_val);
1069 reg_val = mixer_in_csc_set(para->dst_image.format);
1070 write_wvalue(G2D_CSC1_CONTROL_REG, reg_val);
1071
1072 /* sacler setting */
1073 write_wvalue(G2D_SCALER_CONTROL_REG,
1074 G2D_SCALER_4TAP4 | G2D_SCALER_ENABLE);
1075 write_wvalue(G2D_SCALER_HPHASE_REG, 0);
1076 write_wvalue(G2D_SCALER_VPHASE_REG, 0);
1077 write_wvalue(G2D_ROP_INDEX0_REG, 0x840);
1078
1079 /* channel3 is dst surface */
1080 write_wvalue(G2D_DMA3_STRIDE_REG,
1081 para->dst_image.w *
1082 mixer_bpp_count(para->dst_image.format));
1083 reg_val = read_wvalue(G2D_DMA3_CONTROL_REG);
1084 reg_val |=
1085 mixer_in_fmtseq_set(para->dst_image.format,
1086 para->dst_image.pixel_seq);
1087 if ((para->flag & G2D_BLT_PIXEL_ALPHA)
1088 || (para->flag & G2D_BLT_PLANE_ALPHA)
1089 || (para->flag & G2D_BLT_MULTI_ALPHA)
1090 || (para->flag & G2D_BLT_SRC_COLORKEY)
1091 || (para->flag & G2D_BLT_DST_COLORKEY))
1092 reg_val |= G2D_IDMA_ENABLE;
1093
1094 /* rgbx/bgrx/xrgb/xbgr format */
1095 if ((para->src_image.format > 0x03) && (para->src_image.format < 0x08))
1096 reg_val |= (0xFF<<24)|0x4;
1097 write_wvalue(G2D_DMA3_CONTROL_REG, reg_val);
1098
1099 /* colorkey */
1100 if (para->flag & G2D_BLT_SRC_COLORKEY)
1101
1102 reg_val = 0x3;
1103 else if (para->flag & G2D_BLT_DST_COLORKEY)
1104
1105 reg_val = 0x5;
1106 else if ((para->flag & G2D_BLT_PIXEL_ALPHA)
1107 || (para->flag & G2D_BLT_PLANE_ALPHA)
1108 || (para->flag & G2D_BLT_MULTI_ALPHA))
1109 reg_val = 1;
1110 else
1111 reg_val = 0x0;
1112 write_wvalue(G2D_CK_CONTROL_REG, reg_val);
1113 write_wvalue(G2D_CK_MINCOLOR_REG, para->color);
1114 write_wvalue(G2D_CK_MAXCOLOR_REG, para->color);
1115
1116 write_wvalue(G2D_OUTPUT0_STRIDE_REG,
1117 para->dst_image.w *
1118 mixer_bpp_count(para->dst_image.format));
1119 reg_val =
1120 mixer_out_fmtseq_set(para->dst_image.format,
1121 para->dst_image.pixel_seq);
1122 write_wvalue(G2D_OUTPUT_CONTROL_REG, reg_val);
1123 if ((para->flag & G2D_BLT_PIXEL_ALPHA) | (para->
1124 flag & G2D_BLT_PLANE_ALPHA) |
1125 (para->flag & G2D_BLT_MULTI_ALPHA) | (para->
1126 flag & G2D_BLT_SRC_COLORKEY) |
1127 (para->flag & G2D_BLT_DST_COLORKEY))
1128 write_wvalue(G2D_OALPHA_CONTROL_REG, 0x80);
1129 /* 0x40: A2 area keep the dst alpha,0x80: A2 area keep the
1130 * src+dst(1-src) alpha value
1131 */
1132 mixer_premultiply_set(para->flag);
1133
1134 /* output width lager than 1024 pixel width */
1135 if (para->dst_rect.w > 0x400) {
1136 /* scaler up divide the output into 1024 pixel width part */
1137 cnt = para->dst_rect.w / 1024;
1138 cnt = (para->dst_rect.w % 1024) ? cnt : cnt - 1;
1139 sinw = (para->src_rect.w / para->dst_rect.w) << 10;
1140 sinw |=
1141 ((para->src_rect.w % para->dst_rect.w) << 10) /
1142 para->dst_rect.w;
1143 if ((para->flag & G2D_BLT_ROTATE90)
1144 || (para->flag & G2D_BLT_ROTATE270)) {
1145 sinw = (para->src_rect.h / para->dst_rect.w) << 10;
1146 sinw |=
1147 ((para->src_rect.h % para->dst_rect.w) << 10) /
1148 para->dst_rect.w;
1149 }
1150 scaler_inx = para->src_rect.x;
1151 scaler_iny = para->src_rect.y;
1152 scaler_outx = para->dst_rect.x;
1153 scaler_outy = para->dst_rect.y;
1154 for (i = 0; i < cnt; i++) {
1155 /* DMA0 */
1156 addr_val =
1157 mixer_get_addr(para->src_image.addr[0],
1158 para->src_image.format,
1159 para->src_image.w, scaler_inx,
1160 para->src_rect.y);
1161 reg_val = (addr_val >> 32) & 0xF;/* high addr in bits */
1162 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1163 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1164 write_wvalue(G2D_DMA0_LADDR_REG, reg_val);
1165 if (sinw < 1)
1166 sinw = 1;
1167 write_wvalue(G2D_DMA0_SIZE_REG, (sinw - 1) |
1168 ((para->src_rect.h - 1)<<16));
1169 if ((para->flag & G2D_BLT_ROTATE90) ||
1170 (para->flag & G2D_BLT_ROTATE270))
1171 write_wvalue(G2D_DMA0_SIZE_REG,
1172 (para->src_rect.w - 1) |
1173 ((sinw - 1)<<16));
1174
1175 /* DMA1 pyuv422/420/411uvc */
1176 if ((para->src_image.format > 0x16) &&
1177 (para->src_image.format < 0x1A)) {
1178 if (para->src_image.format ==
1179 G2D_FMT_PYUV411UVC)
1180 bppnum = 4;
1181 else
1182 bppnum = 8;
1183 if (para->src_image.format ==
1184 G2D_FMT_PYUV420UVC)
1185 addr_val = (__u64)para->src_image.addr[1] * 8 +
1186 (__u64)((para->src_image.w *
1187 (para->src_rect.y/2) +
1188 scaler_inx) * bppnum);
1189 else
1190 addr_val = (__u64)para->src_image.addr[1] * 8 +
1191 (__u64)((para->src_image.w *
1192 para->src_rect.y +
1193 scaler_inx) * bppnum);
1194 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
1195 /* high addr in bits */
1196 reg_val |= ((addr_val>>32)&0xF)<<8;
1197 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1198 /* low addr in bits */
1199 reg_val = addr_val&0xFFFFFFFF;
1200 write_wvalue(G2D_DMA1_LADDR_REG, reg_val);
1201 write_wvalue(G2D_DMA1_STRIDE_REG,
1202 para->src_image.w * bppnum);
1203 if (sinw < 1)
1204 sinw = 1;
1205 write_wvalue(G2D_DMA1_SIZE_REG, (sinw - 1) |
1206 ((para->src_rect.h - 1)<<16));
1207 reg_val = read_wvalue(G2D_DMA1_CONTROL_REG);
1208 reg_val |= (5 << 8) | G2D_IDMA_ENABLE;
1209
1210 /* rotate/mirror */
1211 reg_val |= mixer_set_rotate_reg(para->flag);
1212 write_wvalue(G2D_DMA1_CONTROL_REG, reg_val);
1213 }
1214
1215 /* scaler setting */
1216 if ((para->flag & G2D_BLT_ROTATE90) ||
1217 (para->flag & G2D_BLT_ROTATE270)) {
1218 write_wvalue(G2D_SCALER_SIZE_REG,
1219 (para->dst_rect.h - 1) | ((0x400 - 1)<<16));
1220 reg_val = (para->src_rect.w/para->dst_rect.h)<<16;
1221 reg_tmp = (para->src_rect.w%para->dst_rect.h);
1222 reg_val |= (reg_tmp<<16)/para->dst_rect.h;
1223 write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
1224 reg_val = (sinw/0x400)<<16;
1225 reg_tmp = (sinw%0x400);
1226 reg_val |= (reg_tmp<<16)/0x400;
1227 write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
1228 } else {
1229 write_wvalue(G2D_SCALER_SIZE_REG,
1230 (0x400 - 1) | ((para->dst_rect.h - 1)<<16));
1231 reg_val = (sinw/0x400)<<16;
1232 reg_tmp = (sinw%0x400);
1233 reg_val |= (reg_tmp<<16)/0x400;
1234 write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
1235
1236 reg_val = (para->src_rect.h/para->dst_rect.h)<<16;
1237 reg_tmp = (para->src_rect.h%para->dst_rect.h);
1238 reg_val |= (reg_tmp<<16)/para->dst_rect.h;
1239 write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
1240 }
1241 if ((para->flag & G2D_BLT_PIXEL_ALPHA) ||
1242 (para->flag & G2D_BLT_PLANE_ALPHA) ||
1243 (para->flag & G2D_BLT_MULTI_ALPHA) ||
1244 (para->flag & G2D_BLT_SRC_COLORKEY) ||
1245 (para->flag & G2D_BLT_DST_COLORKEY)) {
1246 /* DMA2 pyuv422/420/411uvc */
1247 if ((para->dst_image.format > 0x16) &&
1248 (para->dst_image.format < 0x1A)) {
1249 if (para->dst_image.format ==
1250 G2D_FMT_PYUV411UVC)
1251 bppnum = 4;
1252 else
1253 bppnum = 8;
1254 if (para->dst_image.format ==
1255 G2D_FMT_PYUV420UVC)
1256 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1257 (__u64)((para->dst_image.w *
1258 (para->dst_rect.y / 2) +
1259 scaler_outx) * bppnum);
1260 else
1261 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1262 (__u64)((para->dst_image.w *
1263 para->dst_rect.y +
1264 scaler_outx) * bppnum);
1265 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
1266 /* high addr in bits */
1267 reg_val |= ((addr_val>>32)&0xF)<<16;
1268 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1269 /* low addr in bits */
1270 reg_val = addr_val&0xFFFFFFFF;
1271 write_wvalue(G2D_DMA2_LADDR_REG, reg_val);
1272 write_wvalue(G2D_DMA2_STRIDE_REG,
1273 para->dst_image.w*bppnum);
1274 write_wvalue(G2D_DMA2_SIZE_REG, (0x400 - 1) |
1275 ((para->dst_rect.h - 1)<<16));
1276 reg_val = read_wvalue(G2D_DMA2_CONTROL_REG);
1277 reg_val |= (5<<8) | G2D_IDMA_ENABLE;
1278 write_wvalue(G2D_DMA2_CONTROL_REG, reg_val);
1279 }
1280
1281 /* DMA3 */
1282 addr_val = mixer_get_addr(para->dst_image.addr[0],
1283 para->dst_image.format,
1284 para->dst_image.w, scaler_outx,
1285 para->dst_rect.y);
1286 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
1287 reg_val = reg_val & 0xF0FFFFFF;
1288 /* high addr in bits */
1289 reg_val |= ((addr_val>>32)&0xF)<<24;
1290 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1291 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1292 write_wvalue(G2D_DMA3_LADDR_REG, reg_val);
1293 write_wvalue(G2D_DMA3_SIZE_REG, (0x400 - 1) |
1294 ((para->dst_rect.h - 1)<<16));
1295 }
1296 /* OUT */
1297 write_wvalue(G2D_OUTPUT_SIZE_REG, (0x400 - 1) |
1298 ((para->dst_rect.h - 1)<<16));
1299 if ((para->flag & G2D_BLT_ROTATE180))
1300 scaler_outx = para->dst_rect.w - 0x400;
1301 addr_val = mixer_get_addr(para->dst_image.addr[0],
1302 para->dst_image.format,
1303 para->dst_image.w, scaler_outx,
1304 scaler_outy);
1305 if ((para->flag & G2D_BLT_ROTATE270))
1306 addr_val = mixer_get_addr(para->dst_image.addr[0],
1307 para->dst_image.format,
1308 para->dst_image.w,
1309 scaler_outx-0x400,
1310 scaler_outy);
1311 reg_val = (addr_val>>32)&0xF;/* high addr in bits */
1312 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
1313 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1314 write_wvalue(G2D_OUTPUT0_LADDR_REG, reg_val);
1315
1316 /* OUT1 */
1317 if ((para->dst_image.format > 0x16) &&
1318 (para->dst_image.format < 0x1A)) {
1319 if (para->dst_image.format ==
1320 G2D_FMT_PYUV411UVC)
1321 bppnum = 4;
1322 else
1323 bppnum = 8;
1324 if (para->dst_image.format ==
1325 G2D_FMT_PYUV420UVC)
1326 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1327 (__u64)((para->dst_image.w *
1328 (scaler_outy/2) +
1329 scaler_outx) * bppnum);
1330 else
1331 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1332 (__u64)((para->dst_image.w *
1333 scaler_outy +
1334 scaler_outx) * bppnum);
1335 reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
1336 /* high addr in bits */
1337 reg_val |= ((addr_val>>32)&0xF)<<8;
1338 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
1339 /* low addr in bits */
1340 reg_val = addr_val&0xFFFFFFFF;
1341 write_wvalue(G2D_OUTPUT1_LADDR_REG, reg_val);
1342 write_wvalue(G2D_OUTPUT1_STRIDE_REG,
1343 para->dst_image.w*bppnum);
1344 write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
1345 }
1346 if ((para->dst_image.format > 0x11) &&
1347 (para->dst_image.format < 0x1D))
1348 write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
1349
1350 scaler_inx += sinw;
1351 if ((para->flag & G2D_BLT_ROTATE90)) {
1352 scaler_outx += 0x400;
1353 scaler_iny += sinw;
1354 scaler_inx = para->src_rect.x;
1355 } else if ((para->flag & G2D_BLT_ROTATE270)) {
1356 scaler_outx = para->dst_rect.x;
1357 scaler_iny += sinw;
1358 scaler_inx = para->src_rect.x;
1359 } else if ((para->flag & G2D_BLT_ROTATE180)) {
1360 scaler_outy = para->dst_rect.y;
1361 scaler_outx = para->dst_rect.x -
1362 para->dst_image.w;
1363 } else {
1364 scaler_outy = para->dst_rect.y;
1365 scaler_outx += 0x400;
1366 }
1367
1368 /* start */
1369 write_wvalue(G2D_CONTROL_REG, 0x0);
1370 write_wvalue(G2D_CONTROL_REG, 0x303);
1371 result |= g2d_wait_cmd_finish();
1372 if (result != 0)
1373 return result;
1374 }
1375
1376 /* last block */
1377 soutw = para->dst_rect.w - 0x400*cnt;
1378 if ((para->flag & G2D_BLT_ROTATE90) ||
1379 (para->flag & G2D_BLT_ROTATE270))
1380 sinw = para->src_rect.h - sinw*cnt;
1381 else
1382 sinw = para->src_rect.w - sinw*cnt;
1383
1384 /* DMA0 */
1385 addr_val = mixer_get_addr(para->src_image.addr[0],
1386 para->src_image.format, para->src_image.w,
1387 scaler_inx, para->src_rect.y);
1388 if ((para->flag & G2D_BLT_ROTATE90) ||
1389 (para->flag & G2D_BLT_ROTATE270))
1390 addr_val = mixer_get_addr(para->src_image.addr[0],
1391 para->src_image.format,
1392 para->src_image.w,
1393 scaler_inx, scaler_iny);
1394 reg_val = (addr_val>>32)&0xF;/* high addr in bits */
1395 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1396 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1397 write_wvalue(G2D_DMA0_LADDR_REG, reg_val);
1398 write_wvalue(G2D_DMA0_SIZE_REG,
1399 (sinw - 1) | ((para->src_rect.h - 1)<<16));
1400 if ((para->flag & G2D_BLT_ROTATE90) ||
1401 (para->flag & G2D_BLT_ROTATE270))
1402 write_wvalue(G2D_DMA0_SIZE_REG,
1403 (para->src_rect.w - 1) | ((sinw - 1)<<16));
1404
1405 /* DMA1 pyuv422/420/411uvc */
1406 if ((para->src_image.format > 0x16) &&
1407 (para->src_image.format < 0x1A)) {
1408 if (para->src_image.format ==
1409 G2D_FMT_PYUV411UVC)
1410 bppnum = 4;
1411 else
1412 bppnum = 8;
1413 if (para->src_image.format == G2D_FMT_PYUV420UVC)
1414 addr_val = (__u64)para->src_image.addr[1] * 8 +
1415 (__u64)((para->src_image.w *
1416 (para->src_rect.y/2) +
1417 scaler_inx) * bppnum);
1418 else
1419 addr_val = (__u64)para->src_image.addr[1] * 8 +
1420 (__u64)((para->src_image.w *
1421 para->src_rect.y +
1422 scaler_inx) * bppnum);
1423 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
1424 reg_val |= ((addr_val>>32)&0xF)<<8;/*high addr in bits*/
1425 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1426 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1427 write_wvalue(G2D_DMA1_LADDR_REG, reg_val);
1428 write_wvalue(G2D_DMA1_STRIDE_REG,
1429 para->src_image.w * bppnum);
1430 if (sinw < 1)
1431 sinw = 1;
1432 write_wvalue(G2D_DMA1_SIZE_REG,
1433 (sinw - 1) | ((para->src_rect.h - 1)<<16));
1434 reg_val = read_wvalue(G2D_DMA1_CONTROL_REG);
1435 reg_val |= (5<<8) | G2D_IDMA_ENABLE;
1436
1437 /* rotate/mirror */
1438 reg_val |= mixer_set_rotate_reg(para->flag);
1439 write_wvalue(G2D_DMA1_CONTROL_REG, reg_val);
1440 }
1441
1442 /* scaler setting */
1443 if (soutw < 1)
1444 soutw = 1;
1445 if ((para->flag & G2D_BLT_ROTATE90) ||
1446 (para->flag & G2D_BLT_ROTATE270)) {
1447 write_wvalue(G2D_SCALER_SIZE_REG,
1448 (para->dst_rect.h - 1) | ((soutw - 1)<<16));
1449 reg_val = (para->src_rect.w/para->dst_rect.h)<<16;
1450 reg_tmp = (para->src_rect.w%para->dst_rect.h);
1451 reg_val |= (reg_tmp<<16)/para->dst_rect.h;
1452 write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
1453 reg_val = (sinw/soutw)<<16;
1454 reg_tmp = (sinw%soutw);
1455 reg_val |= (reg_tmp<<16)/soutw;
1456 write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
1457 } else {
1458 write_wvalue(G2D_SCALER_SIZE_REG,
1459 (soutw - 1) | ((para->dst_rect.h - 1)<<16));
1460 reg_val = (sinw/soutw)<<16;
1461 reg_tmp = (sinw%soutw);
1462 reg_val |= (reg_tmp<<16)/soutw;
1463 write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
1464
1465 reg_val = (para->src_rect.h/para->dst_rect.h)<<16;
1466 reg_tmp = (para->src_rect.h%para->dst_rect.h);
1467 reg_val |= (reg_tmp<<16)/para->dst_rect.h;
1468 write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
1469 }
1470 if ((para->flag & G2D_BLT_PIXEL_ALPHA) ||
1471 (para->flag & G2D_BLT_PLANE_ALPHA) ||
1472 (para->flag & G2D_BLT_MULTI_ALPHA) ||
1473 (para->flag & G2D_BLT_SRC_COLORKEY) ||
1474 (para->flag & G2D_BLT_DST_COLORKEY)) {
1475 /* DMA2 pyuv422/420/411uvc */
1476 if ((para->dst_image.format > 0x16) &&
1477 (para->dst_image.format < 0x1A)) {
1478 if (para->dst_image.format == G2D_FMT_PYUV411UVC)
1479 bppnum = 4;
1480 else
1481 bppnum = 8;
1482 if (para->dst_image.format == G2D_FMT_PYUV420UVC)
1483 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1484 (__u64)((para->dst_image.w *
1485 (para->dst_rect.y/2) +
1486 scaler_outx) * bppnum);
1487 else
1488 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1489 (__u64)((para->dst_image.w *
1490 para->dst_rect.y +
1491 scaler_outx)*bppnum);
1492 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
1493 /*high addr in bits*/
1494 reg_val |= ((addr_val>>32)&0xF)<<16;
1495 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1496 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1497 write_wvalue(G2D_DMA2_LADDR_REG, reg_val);
1498 write_wvalue(G2D_DMA2_STRIDE_REG,
1499 para->dst_image.w*bppnum);
1500 if (soutw < 1)
1501 soutw = 1;
1502 write_wvalue(G2D_DMA2_SIZE_REG,
1503 (soutw - 1) | ((para->dst_rect.h - 1)<<16));
1504 reg_val = read_wvalue(G2D_DMA2_CONTROL_REG);
1505 reg_val |= (5<<8) | G2D_IDMA_ENABLE;
1506 write_wvalue(G2D_DMA2_CONTROL_REG, reg_val);
1507 }
1508
1509 /* DMA3 */
1510 addr_val = mixer_get_addr(para->dst_image.addr[0],
1511 para->dst_image.format, para->dst_image.w,
1512 scaler_outx, para->dst_rect.y);
1513 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
1514 reg_val = reg_val&0xF0FFFFFF;
1515 reg_val |= ((addr_val>>32)&0xF)<<24;/* high addr in bits */
1516 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1517 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1518 write_wvalue(G2D_DMA3_LADDR_REG, reg_val);
1519 write_wvalue(G2D_DMA3_SIZE_REG,
1520 (soutw - 1) | ((para->dst_rect.h - 1)<<16));
1521 }
1522 /* OUT */
1523 write_wvalue(G2D_OUTPUT_SIZE_REG,
1524 (soutw - 1) | ((para->dst_rect.h - 1)<<16));
1525 if ((para->flag & G2D_BLT_ROTATE90) ||
1526 (para->flag & G2D_BLT_ROTATE270))
1527 addr_val = mixer_get_addr(para->dst_image.addr[0],
1528 para->dst_image.format,
1529 para->dst_image.w,
1530 scaler_outx, scaler_outy);
1531 else
1532 addr_val = mixer_get_addr(para->dst_image.addr[0],
1533 para->dst_image.format, para->dst_image.w,
1534 scaler_outx, para->dst_rect.y);
1535 reg_val = (addr_val>>32)&0xF;/* high addr in bits */
1536 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
1537 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1538 write_wvalue(G2D_OUTPUT0_LADDR_REG, reg_val);
1539
1540 /* OUT1 */
1541 if ((para->dst_image.format > 0x16) &&
1542 (para->dst_image.format < 0x1A)) {
1543 if (para->dst_image.format == G2D_FMT_PYUV411UVC)
1544 bppnum = 4;
1545 else
1546 bppnum = 8;
1547 if (para->dst_image.format == G2D_FMT_PYUV420UVC)
1548 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1549 (__u64)((para->dst_image.w *
1550 (para->dst_rect.y/2) +
1551 scaler_outx)*bppnum);
1552 else
1553 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1554 (__u64)((para->dst_image.w *
1555 para->dst_rect.y +
1556 scaler_outx) * bppnum);
1557 reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
1558 /* high addr in bits */
1559 reg_val |= ((addr_val>>32)&0xF)<<8;
1560 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
1561 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1562 write_wvalue(G2D_OUTPUT1_LADDR_REG, reg_val);
1563 write_wvalue(G2D_OUTPUT1_STRIDE_REG,
1564 para->dst_image.w*bppnum);
1565 write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
1566 }
1567 if ((para->dst_image.format > 0x11) &&
1568 (para->dst_image.format < 0x1D))
1569 write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
1570
1571 /*scan order*/
1572 write_wvalue(G2D_SCAN_ORDER_REG, (scan_order & 0x3) << 8);
1573 /* start */
1574 write_wvalue(G2D_CONTROL_REG, 0x0);
1575 write_wvalue(G2D_CONTROL_REG, 0x303);
1576 result |= g2d_wait_cmd_finish();
1577 }
1578
1579 /* output width smaller than 1024 pixel width */
1580 else {
1581 addr_val = mixer_get_addr(para->src_image.addr[0],
1582 para->src_image.format, para->src_image.w,
1583 para->src_rect.x, para->src_rect.y);
1584 reg_val = (addr_val>>32)&0xF;/* high addr in bits */
1585 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1586 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1587 write_wvalue(G2D_DMA0_LADDR_REG, reg_val);
1588 write_wvalue(G2D_DMA0_SIZE_REG,
1589 (para->src_rect.w - 1) | ((para->src_rect.h - 1)<<16));
1590
1591 if ((para->flag & G2D_BLT_ROTATE90) ||
1592 (para->flag & G2D_BLT_ROTATE270)) {
1593 write_wvalue(G2D_SCALER_SIZE_REG,
1594 (para->dst_rect.h - 1) |
1595 ((para->dst_rect.w - 1)<<16));
1596 reg_val = (para->src_rect.w/para->dst_rect.h)<<16;
1597 reg_tmp = (para->src_rect.w%para->dst_rect.h);
1598 reg_val |= (reg_tmp<<16)/para->dst_rect.h;
1599 write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
1600 reg_val = (para->src_rect.h/para->dst_rect.w)<<16;
1601 reg_tmp = (para->src_rect.h%para->dst_rect.w);
1602 reg_val |= (reg_tmp<<16)/para->dst_rect.w;
1603 write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
1604 } else {
1605 write_wvalue(G2D_SCALER_SIZE_REG,
1606 (para->dst_rect.w - 1) |
1607 ((para->dst_rect.h - 1)<<16));
1608 reg_val = (para->src_rect.w/para->dst_rect.w)<<16;
1609 reg_tmp = (para->src_rect.w%para->dst_rect.w);
1610 reg_val |= (reg_tmp<<16)/para->dst_rect.w;
1611 write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
1612 reg_val = (para->src_rect.h/para->dst_rect.h)<<16;
1613 reg_tmp = (para->src_rect.h%para->dst_rect.h);
1614 reg_val |= (reg_tmp<<16)/para->dst_rect.h;
1615 write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
1616 }
1617 /* pyuv422/420/411uvc */
1618 if ((para->src_image.format > 0x16) &&
1619 (para->src_image.format < 0x1A)) {
1620 if (para->src_image.format == G2D_FMT_PYUV411UVC)
1621 bppnum = 4;
1622 else
1623 bppnum = 8;
1624 if (para->src_image.format == G2D_FMT_PYUV420UVC)
1625 addr_val = (__u64)para->src_image.addr[1] * 8 +
1626 (__u64)((para->src_image.w *
1627 (para->src_rect.y/2) +
1628 para->src_rect.x) * bppnum);
1629 else
1630 addr_val = (__u64)para->src_image.addr[1] * 8 +
1631 (__u64)((para->src_image.w *
1632 para->src_rect.y +
1633 para->src_rect.x) * bppnum);
1634 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
1635 /* high addr in bits */
1636 reg_val |= ((addr_val>>32)&0xF)<<8;
1637 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1638 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1639 write_wvalue(G2D_DMA1_LADDR_REG, reg_val);
1640 write_wvalue(G2D_DMA1_STRIDE_REG,
1641 para->src_image.w*bppnum);
1642 write_wvalue(G2D_DMA1_SIZE_REG,
1643 (para->src_rect.w - 1) |
1644 ((para->src_rect.h - 1)<<16));
1645 reg_val = read_wvalue(G2D_DMA1_CONTROL_REG);
1646 reg_val |= (5<<8) | G2D_IDMA_ENABLE;
1647 reg_val |= mixer_set_rotate_reg(para->flag);
1648 write_wvalue(G2D_DMA1_CONTROL_REG, reg_val);
1649 }
1650 if ((para->flag & G2D_BLT_PIXEL_ALPHA) ||
1651 (para->flag & G2D_BLT_PLANE_ALPHA) ||
1652 (para->flag & G2D_BLT_MULTI_ALPHA) ||
1653 (para->flag & G2D_BLT_SRC_COLORKEY) ||
1654 (para->flag & G2D_BLT_DST_COLORKEY)) {
1655 /* pyuv422/420/411uvc */
1656 if ((para->dst_image.format > 0x16) &&
1657 (para->dst_image.format < 0x1A)) {
1658 if (para->dst_image.format == G2D_FMT_PYUV411UVC)
1659 bppnum = 4;
1660 else
1661 bppnum = 8;
1662 if (para->dst_image.format == G2D_FMT_PYUV420UVC)
1663 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1664 (__u64)((para->dst_image.w *
1665 (para->dst_rect.y/2) +
1666 para->dst_rect.x) * bppnum);
1667 else
1668 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1669 (__u64)((para->dst_image.w *
1670 para->dst_rect.y +
1671 para->dst_rect.x) * bppnum);
1672 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
1673 /* high addr in bits */
1674 reg_val |= ((addr_val>>32)&0xF)<<16;
1675 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1676 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1677 write_wvalue(G2D_DMA2_LADDR_REG, reg_val);
1678 write_wvalue(G2D_DMA2_STRIDE_REG,
1679 para->dst_image.w * bppnum);
1680 write_wvalue(G2D_DMA2_SIZE_REG,
1681 (para->dst_rect.w - 1) |
1682 ((para->dst_rect.h - 1)<<16));
1683 reg_val = read_wvalue(G2D_DMA2_CONTROL_REG);
1684 reg_val |= (5<<8) | G2D_IDMA_ENABLE;
1685 write_wvalue(G2D_DMA2_CONTROL_REG, reg_val);
1686 }
1687
1688 addr_val = mixer_get_addr(para->dst_image.addr[0],
1689 para->dst_image.format, para->dst_image.w,
1690 para->dst_rect.x, para->dst_rect.y);
1691 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
1692 reg_val |= ((addr_val>>32)&0xF)<<24;/* high addr in bits */
1693 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1694 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1695 write_wvalue(G2D_DMA3_LADDR_REG, reg_val);
1696 write_wvalue(G2D_DMA3_SIZE_REG,
1697 (para->dst_rect.w - 1) |
1698 ((para->dst_rect.h - 1)<<16));
1699 }
1700 /* output surface is the dst surface */
1701 write_wvalue(G2D_OUTPUT_SIZE_REG,
1702 (para->dst_rect.w - 1) |
1703 ((para->dst_rect.h - 1)<<16));
1704 addr_val = mixer_get_addr(para->dst_image.addr[0],
1705 para->dst_image.format, para->dst_image.w,
1706 para->dst_rect.x, para->dst_rect.y);
1707 reg_val = (addr_val>>32)&0xF;/* high addr in bits */
1708 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
1709 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1710 write_wvalue(G2D_OUTPUT0_LADDR_REG, reg_val);
1711
1712 if ((para->dst_image.format > 0x16) &&
1713 (para->dst_image.format < 0x1D)) {
1714 if ((para->dst_image.format == G2D_FMT_PYUV411UVC) ||
1715 (para->dst_image.format == G2D_FMT_PYUV422) ||
1716 (para->dst_image.format == G2D_FMT_PYUV420))
1717 bppnum = 4;
1718 else if (para->dst_image.format == G2D_FMT_PYUV411)
1719 bppnum = 2;
1720 else
1721 bppnum = 8;
1722 if ((para->dst_image.format == G2D_FMT_PYUV420UVC) ||
1723 (para->dst_image.format == G2D_FMT_PYUV420))
1724 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1725 (__u64)((para->dst_image.w *
1726 (para->dst_rect.y/2) +
1727 para->dst_rect.x) * bppnum);
1728 else
1729 addr_val = (__u64)para->dst_image.addr[1] * 8 +
1730 (__u64)((para->dst_image.w *
1731 para->dst_rect.y +
1732 para->dst_rect.x) * bppnum);
1733 reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
1734 /* high addr in bits */
1735 reg_val |= ((addr_val>>32)&0xF)<<8;
1736 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
1737 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1738 write_wvalue(G2D_OUTPUT1_LADDR_REG, reg_val);
1739 write_wvalue(G2D_OUTPUT1_STRIDE_REG,
1740 para->dst_image.w * bppnum);
1741 if (para->dst_image.format == G2D_FMT_PYUV420)
1742 addr_val = (__u64)para->dst_image.addr[2] * 8 +
1743 (__u64)((para->dst_image.w *
1744 (para->dst_rect.y/2) +
1745 para->dst_rect.x) * bppnum);
1746 else if ((para->dst_image.format == G2D_FMT_PYUV422) ||
1747 (para->dst_image.format == G2D_FMT_PYUV411))
1748 addr_val = (__u64)para->dst_image.addr[2] * 8 +
1749 (__u64)((para->dst_image.w *
1750 para->dst_rect.y +
1751 para->dst_rect.x) * bppnum);
1752 else
1753 addr_val = 0;
1754 reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
1755 /* high addr in bits */
1756 reg_val |= ((addr_val>>32)&0xF)<<16;
1757 write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
1758 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1759 write_wvalue(G2D_OUTPUT2_LADDR_REG, reg_val);
1760 write_wvalue(G2D_OUTPUT2_STRIDE_REG,
1761 para->dst_image.w * bppnum);
1762 write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
1763 }
1764 if ((para->dst_image.format > 0x11) &&
1765 (para->dst_image.format < 0x1D))
1766 write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
1767
1768 /*scan order*/
1769 write_wvalue(G2D_SCAN_ORDER_REG, (scan_order & 0x3) << 8);
1770
1771 /* start */
1772 write_wvalue(G2D_CONTROL_REG, 0x0);
1773 write_wvalue(G2D_CONTROL_REG, 0x303);
1774 result = g2d_wait_cmd_finish();
1775 }
1776
1777 return result;
1778 }
1779
mixer_set_palette(g2d_palette * para)1780 __u32 mixer_set_palette(g2d_palette *para)
1781 {
1782 __u32 *pdest_end;
1783 __u32 *psrc_cur;
1784 __u32 *pdest_cur;
1785
1786 if (para->size > 0x400)
1787 para->size = 0x400;
1788 psrc_cur = para->pbuffer;
1789 pdest_cur = (__u32 *)(base_addr+G2D_PALETTE_TAB_REG);
1790 pdest_end = pdest_cur + (para->size>>2);
1791
1792 while (pdest_cur < pdest_end)
1793 *(volatile __u32 *)pdest_cur++ = *psrc_cur++;
1794
1795 return 0;
1796 }
1797
mixer_cmdq(__u32 addr)1798 __s32 mixer_cmdq(__u32 addr)
1799 {
1800 __s32 result = 0;
1801
1802 write_wvalue(G2D_CONTROL_REG, 0x0);
1803 write_wvalue(G2D_CMDQ_ADDR_REG, addr);
1804
1805 /* start */
1806 write_wvalue(G2D_CMDQ_STS_REG, 0x100);
1807 write_wvalue(G2D_CMDQ_CTL_REG, 0x0);
1808 write_wvalue(G2D_CMDQ_CTL_REG, 0x103);
1809 result = g2d_wait_cmd_finish();
1810
1811 return result;
1812 }
1813
mixer_premultiply_set(__u32 flag)1814 __u32 mixer_premultiply_set(__u32 flag)
1815 {
1816 __u32 reg_val;
1817
1818 reg_val = read_wvalue(G2D_CK_CONTROL_REG);
1819
1820 /* src premultiply, dst non-premultiply,
1821 * dst_c = src_c + dst_c*(1-src_a)/A;A = src_a + dst_a*(1-src_a)
1822 */
1823 if (flag&G2D_BLT_SRC_PREMULTIPLY) {
1824 reg_val |= (0x3<<6);
1825 write_wvalue(G2D_CK_CONTROL_REG, reg_val);
1826 }
1827
1828 /* src non-premultiply, dst(out) premultiply,
1829 * dst_c = src_c*src_a + dst_c*dst_a(1-src_a);
1830 * A = src_a + dst_a*(1-src_a)
1831 */
1832 else if (flag&G2D_BLT_DST_PREMULTIPLY) {
1833 reg_val |= (0x7<<5);
1834 write_wvalue(G2D_CK_CONTROL_REG, reg_val);
1835 write_wvalue(G2D_OALPHA_CONTROL_REG, 0xAA);
1836 }
1837
1838 return 0;
1839 }
1840
mixer_micro_block_set(g2d_blt * para)1841 __u32 mixer_micro_block_set(g2d_blt *para)
1842 {
1843 __u32 reg_val, bppnum;
1844 __u64 addr_val;
1845
1846 if (para->src_image.format > 0x20) {
1847 if ((para->src_image.format == G2D_FMT_PYUV411UVC_MB16) ||
1848 (para->src_image.format == G2D_FMT_PYUV411UVC_MB32) ||
1849 (para->src_image.format == G2D_FMT_PYUV411UVC_MB64) ||
1850 (para->src_image.format == G2D_FMT_PYUV411UVC_MB128))
1851 bppnum = 4;
1852 else
1853 bppnum = 8;
1854 if ((para->src_image.format == G2D_FMT_PYUV420UVC_MB16) ||
1855 (para->src_image.format == G2D_FMT_PYUV420UVC_MB32) ||
1856 (para->src_image.format == G2D_FMT_PYUV420UVC_MB64) ||
1857 (para->src_image.format == G2D_FMT_PYUV420UVC_MB128))
1858 addr_val = (__u64)para->src_image.addr[1] * 8 +
1859 (__u64)((para->src_image.w *
1860 (para->src_rect.y/2) +
1861 para->src_rect.x) * bppnum);
1862 else
1863 addr_val = (__u64)para->src_image.addr[1] * 8 +
1864 (__u64)((para->src_image.w *
1865 para->src_rect.y +
1866 para->src_rect.x) * bppnum);
1867 reg_val = read_wvalue(G2D_DMA_HADDR_REG);
1868 reg_val |= ((addr_val>>32)&0xF)<<8;/* high addr in bits */
1869 write_wvalue(G2D_DMA_HADDR_REG, reg_val);
1870 reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
1871 write_wvalue(G2D_DMA1_LADDR_REG, reg_val);
1872
1873 write_wvalue(G2D_DMA1_STRIDE_REG, para->src_image.w*bppnum);
1874 write_wvalue(G2D_DMA1_SIZE_REG,
1875 (para->src_rect.w - 1) | ((para->src_rect.h - 1)<<16));
1876 reg_val = read_wvalue(G2D_DMA1_CONTROL_REG);
1877 reg_val |= (5<<8) | G2D_IDMA_ENABLE;
1878
1879 /* rotate/mirror */
1880 reg_val |= mixer_set_rotate_reg(para->flag);
1881 write_wvalue(G2D_DMA1_CONTROL_REG, reg_val);
1882 if (para->src_image.format > 0x23 &&
1883 para->src_image.format < 0x27)
1884 reg_val = 0x29<<17;
1885 else if (para->src_image.format > 0x26 &&
1886 para->src_image.format < 0x2A)
1887 reg_val = 0x32<<17;
1888 else if (para->src_image.format > 0x29 &&
1889 para->src_image.format < 0x2D)
1890 reg_val = 0x3b<<17;
1891 else
1892 reg_val = 0x20<<17;
1893 write_wvalue(G2D_DMA0_CONTROL_REG, (reg_val |
1894 (read_wvalue(G2D_DMA0_CONTROL_REG)&0xff81ffff)));
1895 write_wvalue(G2D_DMA1_CONTROL_REG, (reg_val |
1896 (read_wvalue(G2D_DMA1_CONTROL_REG)&0xff81ffff)));
1897 write_wvalue(G2D_DMA0_MBCTL_REG,
1898 (para->src_rect.y&0xFFFF)<<16|
1899 (para->src_rect.x&0xFFFF));
1900 write_wvalue(G2D_DMA1_MBCTL_REG,
1901 (para->src_rect.y&0xFFFF)<<16|
1902 (para->src_rect.x&0xFFFF));
1903
1904 }
1905
1906 return 0;
1907 }
1908