• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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