• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Allwinner SoCs g2d driver.
3  *
4  * Copyright (C) 2016 Allwinner.
5  *
6  * This file is licensed under the terms of the GNU General Public
7  * License version 2.  This program is licensed "as is" without any
8  * warranty of any kind, whether express or implied.
9  */
10 #include "g2d_bsp.h"
11 #include "g2d_regs_v2.h"
12 #include <linux/types.h>
13 #include <linux/stddef.h>
14 
15 static unsigned long base_addr;
16 /* byte input */
17 #define read_bvalue(offset)		get_bvalue(base_addr + offset)
18 /* byte output */
19 #define write_bvalue(offset, value)	put_bvalue(base_addr + offset, value)
20 /* half word input */
21 #define read_hvalue(offset)		get_hvalue(base_addr + offset)
22 /* half word output */
23 #define write_hvalue(offset, value)	put_hvalue(base_addr + offset, value)
24 /* word input */
25 #define read_wvalue(offset)		get_wvalue(base_addr + offset)
26 /* word output */
27 #define write_wvalue(offset, value)	put_wvalue(base_addr + offset, value)
28 
29 __s32 g2d_fc_set(__u32 sel, __u32 color_value);
30 __s32 g2d_format_trans(__s32 data_fmt, __s32 pixel_seq);
31 __s32 rgb2Ycbcr_709[12] = {
32 	0x0bb, 0x0275, 0x03f, 0x4200, 0xFFFFFF99, 0xFFFFFEA6, 0x01c2, 0x20200,
33 	0x01c2, 0xFFFFFE67, 0xFFFFFFD7, 0x20200, };
34 __s32 Ycbcr2rgb_709[12] = {
35 	0x04a8, 0x0, 0x072c, 0xFFFC1F7D, 0x04a8, 0xFFFFFF26, 0xFFFFFDDD,
36 	0x133F8, 0x04a8, 0x0876, 0, 0xFFFB7AA0, };
37 
38 __s32 rgb2Ycbcr_601[12] = {
39 	0x0107, 0x0204, 0x064, 0x4200,
40 	0xFFFFFF68, 0xFFFFFED6, 0x01c2, 0x20200,
41 	0x01c2, 0xFFFFFE87, 0xFFFFFFB7, 0x20200,};
42 __s32 Ycbcr2rgb_601[12] = {
43 	0x04a8, 0x0, 0x0662, 0xFFFC865A,
44 	0x04a8, 0xFFFFFE70, 0xFFFFFCBF, 0x21FF4,
45 	0x04a8, 0x0812, 0x0, 0xFFFBAE4A,};
46 
47 __s32 lan2coefftab32_full[512] = {
48 	0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, 0x00063efc, 0xff083dfc,
49 	0x000a3bfb, 0xff0d39fb, 0xff0f37fb, 0xff1136fa, 0xfe1433fb,
50 	0xfe1631fb, 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc,
51 	0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd, 0xfb2f19fd,
52 	0xfb3116fe, 0xfb3314fe, 0xfa3611ff, 0xfb370fff, 0xfb390dff,
53 	0xfb3b0a00, 0xfc3d08ff, 0xfc3e0600, 0xfd3f0400, 0xfe3f0300,
54 	0xff400100,
55 	/* counter = 1 */
56 	0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, 0x00063efc,
57 	0xff083dfc, 0x000a3bfb, 0xff0d39fb, 0xff0f37fb, 0xff1136fa,
58 	0xfe1433fb, 0xfe1631fb, 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb,
59 	0xfc2127fc, 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd,
60 	0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff, 0xfb370fff,
61 	0xfb390dff, 0xfb3b0a00, 0xfc3d08ff, 0xfc3e0600, 0xfd3f0400,
62 	0xfe3f0300, 0xff400100,
63 	/* counter = 2 */
64 	0xff053804, 0xff063803, 0xff083801, 0xff093701, 0xff0a3700,
65 	0xff0c3500, 0xff0e34ff, 0xff1033fe, 0xff1232fd, 0xfe1431fd,
66 	0xfe162ffd, 0xfe182dfd, 0xfd1b2cfc, 0xfd1d2afc, 0xfd1f28fc,
67 	0xfd2126fc, 0xfd2323fd, 0xfc2621fd, 0xfc281ffd, 0xfc2a1dfd,
68 	0xfc2c1bfd, 0xfd2d18fe, 0xfd2f16fe, 0xfd3114fe, 0xfd3212ff,
69 	0xfe3310ff, 0xff340eff, 0x00350cff, 0x00360a00, 0x01360900,
70 	0x02370700, 0x03370600,
71 	/* counter = 3 */
72 	0xff083207, 0xff093206, 0xff0a3205, 0xff0c3203, 0xff0d3103,
73 	0xff0e3102, 0xfe113001, 0xfe132f00, 0xfe142e00, 0xfe162dff,
74 	0xfe182bff, 0xfe192aff, 0xfe1b29fe, 0xfe1d27fe, 0xfe1f25fe,
75 	0xfd2124fe, 0xfe2222fe, 0xfe2421fd, 0xfe251ffe, 0xfe271dfe,
76 	0xfe291bfe, 0xff2a19fe, 0xff2b18fe, 0xff2d16fe, 0x002e14fe,
77 	0x002f12ff, 0x013010ff, 0x02300fff, 0x03310dff, 0x04310cff,
78 	0x05310a00, 0x06310900,
79 	/* counter = 4 */
80 	0xff0a2e09, 0xff0b2e08, 0xff0c2e07, 0xff0e2d06, 0xff0f2d05,
81 	0xff102d04, 0xff122c03, 0xfe142c02, 0xfe152b02, 0xfe172a01,
82 	0xfe182901, 0xfe1a2800, 0xfe1b2700, 0xfe1d2500, 0xff1e24ff,
83 	0xfe2023ff, 0xff2121ff, 0xff2320fe, 0xff241eff, 0x00251dfe,
84 	0x00261bff, 0x00281afe, 0x012818ff, 0x012a16ff, 0x022a15ff,
85 	0x032b13ff, 0x032c12ff, 0x052c10ff, 0x052d0fff, 0x062d0d00,
86 	0x072d0c00, 0x082d0b00,
87 	/* counter = 5 */
88 	0xff0c2a0b, 0xff0d2a0a, 0xff0e2a09, 0xff0f2a08, 0xff102a07,
89 	0xff112a06, 0xff132905, 0xff142904, 0xff162803, 0xff172703,
90 	0xff182702, 0xff1a2601, 0xff1b2501, 0xff1c2401, 0xff1e2300,
91 	0xff1f2200, 0x00202000, 0x00211f00, 0x01221d00, 0x01231c00,
92 	0x01251bff, 0x02251aff, 0x032618ff, 0x032717ff, 0x042815ff,
93 	0x052814ff, 0x052913ff, 0x06291100, 0x072a10ff, 0x082a0e00,
94 	0x092a0d00, 0x0a2a0c00,
95 	/* counter = 6 */
96 	0xff0d280c, 0xff0e280b, 0xff0f280a, 0xff102809, 0xff112808,
97 	0xff122708, 0xff142706, 0xff152705, 0xff162605, 0xff172604,
98 	0xff192503, 0xff1a2403, 0x001b2302, 0x001c2202, 0x001d2201,
99 	0x001e2101, 0x011f1f01, 0x01211e00, 0x01221d00, 0x02221c00,
100 	0x02231b00, 0x03241900, 0x04241800, 0x04251700, 0x052616ff,
101 	0x06261400, 0x072713ff, 0x08271100, 0x08271100, 0x09271000,
102 	0x0a280e00, 0x0b280d00,
103 	/* counter = 7 */
104 	0xff0e260d, 0xff0f260c, 0xff10260b, 0xff11260a, 0xff122609,
105 	0xff132608, 0xff142508, 0xff152507, 0x00152506, 0x00172405,
106 	0x00182305, 0x00192304, 0x001b2203, 0x001c2103, 0x011d2002,
107 	0x011d2002, 0x011f1f01, 0x021f1e01, 0x02201d01, 0x03211c00,
108 	0x03221b00, 0x04221a00, 0x04231801, 0x05241700, 0x06241600,
109 	0x07241500, 0x08251300, 0x09251200, 0x09261100, 0x0a261000,
110 	0x0b260f00, 0x0c260e00,
111 	/* counter = 8 */
112 	0xff0e250e, 0xff0f250d, 0xff10250c, 0xff11250b, 0x0011250a,
113 	0x00132409, 0x00142408, 0x00152407, 0x00162307, 0x00172306,
114 	0x00182206, 0x00192205, 0x011a2104, 0x011b2004, 0x011c2003,
115 	0x021c1f03, 0x021e1e02, 0x031e1d02, 0x03201c01, 0x04201b01,
116 	0x04211a01, 0x05221900, 0x05221801, 0x06231700, 0x07231600,
117 	0x07241500, 0x08241400, 0x09241300, 0x0a241200, 0x0b241100,
118 	0x0c241000, 0x0d240f00,
119 	/* counter = 9 */
120 	0x000e240e, 0x000f240d, 0x0010240c, 0x0011240b, 0x0013230a,
121 	0x0013230a, 0x00142309, 0x00152308, 0x00162208, 0x00172207,
122 	0x01182106, 0x01192105, 0x011a2005, 0x021b1f04, 0x021b1f04,
123 	0x021d1e03, 0x031d1d03, 0x031e1d02, 0x041e1c02, 0x041f1b02,
124 	0x05201a01, 0x05211901, 0x06211801, 0x07221700, 0x07221601,
125 	0x08231500, 0x09231400, 0x0a231300, 0x0a231300, 0x0b231200,
126 	0x0c231100, 0x0d231000,
127 	/* counter = 10 */
128 	0x000f220f, 0x0010220e, 0x0011220d, 0x0012220c, 0x0013220b,
129 	0x0013220b, 0x0015210a, 0x0015210a, 0x01162108, 0x01172008,
130 	0x01182007, 0x02191f06, 0x02191f06, 0x021a1e06, 0x031a1e05,
131 	0x031c1d04, 0x041c1c04, 0x041d1c03, 0x051d1b03, 0x051e1a03,
132 	0x061f1902, 0x061f1902, 0x07201801, 0x08201701, 0x08211601,
133 	0x09211501, 0x0a211500, 0x0b211400, 0x0b221300, 0x0c221200,
134 	0x0d221100, 0x0e221000,
135 	/* counter = 11 */
136 	0x0010210f, 0x0011210e, 0x0011210e, 0x0012210d, 0x0013210c,
137 	0x0014200c, 0x0114200b, 0x0115200a, 0x01161f0a, 0x01171f09,
138 	0x02171f08, 0x02181e08, 0x03181e07, 0x031a1d06, 0x031a1d06,
139 	0x041b1c05, 0x041c1c04, 0x051c1b04, 0x051d1a04, 0x061d1a03,
140 	0x071d1903, 0x071e1803, 0x081e1802, 0x081f1702, 0x091f1602,
141 	0x0a201501, 0x0b1f1501, 0x0b201401, 0x0c211300, 0x0d211200,
142 	0x0e201200, 0x0e211100,
143 	/* counter = 12 */
144 	0x00102010, 0x0011200f, 0x0012200e, 0x0013200d, 0x0013200d,
145 	0x01141f0c, 0x01151f0b, 0x01151f0b, 0x01161f0a, 0x02171e09,
146 	0x02171e09, 0x03181d08, 0x03191d07, 0x03191d07, 0x041a1c06,
147 	0x041b1c05, 0x051b1b05, 0x051c1b04, 0x061c1a04, 0x071d1903,
148 	0x071d1903, 0x081d1803, 0x081e1703, 0x091e1702, 0x0a1f1601,
149 	0x0a1f1502, 0x0b1f1501, 0x0c1f1401, 0x0d201300, 0x0d201300,
150 	0x0e201200, 0x0f201100,
151 	/* counter = 13 */
152 	0x00102010, 0x0011200f, 0x00121f0f, 0x00131f0e, 0x00141f0d,
153 	0x01141f0c, 0x01141f0c, 0x01151e0c, 0x02161e0a, 0x02171e09,
154 	0x03171d09, 0x03181d08, 0x03181d08, 0x04191c07, 0x041a1c06,
155 	0x051a1b06, 0x051b1b05, 0x061b1a05, 0x061c1a04, 0x071c1904,
156 	0x081c1903, 0x081d1803, 0x091d1703, 0x091e1702, 0x0a1e1602,
157 	0x0b1e1502, 0x0c1e1501, 0x0c1f1401, 0x0d1f1400, 0x0e1f1300,
158 	0x0e1f1201, 0x0f1f1200,
159 	/* counter = 14 */
160 	0x00111e11, 0x00121e10, 0x00131e0f, 0x00131e0f, 0x01131e0e,
161 	0x01141d0e, 0x02151d0c, 0x02151d0c, 0x02161d0b, 0x03161c0b,
162 	0x03171c0a, 0x04171c09, 0x04181b09, 0x05181b08, 0x05191b07,
163 	0x06191a07, 0x061a1a06, 0x071a1906, 0x071b1905, 0x081b1805,
164 	0x091b1804, 0x091c1704, 0x0a1c1703, 0x0a1c1604, 0x0b1d1602,
165 	0x0c1d1502, 0x0c1d1502, 0x0d1d1402, 0x0e1d1401, 0x0e1e1301,
166 	0x0f1e1300, 0x101e1200,
167 	/* counter = 15 */
168 	0x00111e11, 0x00121e10, 0x00131d10, 0x01131d0f, 0x01141d0e,
169 	0x01141d0e, 0x02151c0d, 0x02151c0d, 0x03161c0b, 0x03161c0b,
170 	0x04171b0a, 0x04171b0a, 0x05171b09, 0x05181a09, 0x06181a08,
171 	0x06191a07, 0x07191907, 0x071a1906, 0x081a1806, 0x081a1806,
172 	0x091a1805, 0x0a1b1704, 0x0a1b1704, 0x0b1c1603, 0x0b1c1603,
173 	0x0c1c1503, 0x0d1c1502, 0x0d1d1402, 0x0e1d1401, 0x0f1d1301,
174 	0x0f1d1301, 0x101e1200,
175 	/* counter = 16 */
176 };
177 
178 __s32 linearcoefftab32[32] = {
179 	0x00004000, 0x00023e00, 0x00043c00, 0x00063a00, 0x00083800,
180 	0x000a3600, 0x000c3400, 0x000e3200, 0x00103000, 0x00122e00,
181 	0x00142c00, 0x00162a00, 0x00182800, 0x001a2600, 0x001c2400,
182 	0x001e2200, 0x00202000, 0x00221e00, 0x00241c00, 0x00261a00,
183 	0x00281800, 0x002a1600, 0x002c1400, 0x002e1200, 0x00301000,
184 	0x00320e00, 0x00340c00, 0x00360a00, 0x00380800, 0x003a0600,
185 	0x003c0400, 0x003e0200, };
g2d_bsp_open(void)186 __s32 g2d_bsp_open(void)
187 {
188 	write_wvalue(G2D_SCLK_GATE, 0x3);
189 	write_wvalue(G2D_HCLK_GATE, 0x3);
190 	write_wvalue(G2D_AHB_RESET, 0x3);
191 	return 0;
192 }
193 
g2d_bsp_close(void)194 __s32 g2d_bsp_close(void)
195 {
196 	write_wvalue(G2D_AHB_RESET, 0x0);
197 	write_wvalue(G2D_HCLK_GATE, 0x0);
198 	write_wvalue(G2D_SCLK_GATE, 0x0);
199 	return 0;
200 }
201 
g2d_bsp_reset(void)202 __s32 g2d_bsp_reset(void)
203 {
204 	write_wvalue(G2D_AHB_RESET, 0x0);
205 	write_wvalue(G2D_AHB_RESET, 0x3);
206 	return 0;
207 }
208 
g2d_mixer_reset(void)209 __s32 g2d_mixer_reset(void)
210 {
211 	__u32 reg_val;
212 
213 	reg_val = read_wvalue(G2D_AHB_RESET);
214 	write_wvalue(G2D_AHB_RESET, reg_val & 0xfffffffe);
215 	write_wvalue(G2D_AHB_RESET, reg_val & 0xffffffff);
216 	return 0;
217 }
218 
g2d_rot_reset(void)219 __s32 g2d_rot_reset(void)
220 {
221 	__u32 reg_val;
222 
223 	reg_val = read_wvalue(G2D_AHB_RESET);
224 	write_wvalue(G2D_AHB_RESET, reg_val & 0xfffffffd);
225 	write_wvalue(G2D_AHB_RESET, reg_val & 0xffffffff);
226 	return 0;
227 }
228 
g2d_scan_order_fun(__u32 scan_order)229 __s32 g2d_scan_order_fun(__u32 scan_order)
230 {
231 	__u32 tmp;
232 
233 	tmp = read_wvalue(G2D_MIXER_CTL);
234 	tmp |= ((scan_order >> 24) & 0xf0);
235 	write_wvalue(G2D_MIXER_CTL, tmp);
236 	return 0;
237 }
238 
239 
240 /**
241  * G2D IRQ query funct
242  * if the mission finish IRQ flag was set to 1, then clear the flag
243  * and return 1
244  * if the IRQ was set to 0, then return 0
245  */
mixer_irq_query(void)246 __s32 mixer_irq_query(void)
247 {
248 	__u32 tmp;
249 
250 	tmp = read_wvalue(G2D_MIXER_INT);
251 	if (tmp & 0x1) {
252 		write_wvalue(G2D_MIXER_INT, tmp);
253 		return 0;
254 	}
255 	return -1;
256 }
257 
258 
259 /**
260  * G2D IRQ query funct
261  * if the mission finish IRQ flag was set to 1, then clear the flag
262  * and return 1
263  * if the IRQ was set to 0, then return 0
264  */
rot_irq_query(void)265 __s32 rot_irq_query(void)
266 {
267 	__u32 tmp;
268 
269 	tmp = read_wvalue(ROT_INT);
270 	if (tmp & 0x1) {
271 		write_wvalue(ROT_INT, tmp);
272 		return 0;
273 	}
274 	return -1;
275 }
276 
mixer_irq_enable(void)277 __s32 mixer_irq_enable(void)
278 {
279 	write_wvalue(G2D_MIXER_INT, 0x10);
280 	return 0;
281 }
282 
rot_irq_enable(void)283 __s32 rot_irq_enable(void)
284 {
285 	write_wvalue(ROT_INT, 0x10000);
286 	return 0;
287 }
288 
g2d_irq_disable(void)289 __s32 g2d_irq_disable(void)
290 {
291 	write_wvalue(G2D_MIXER_INT, 0x0);
292 	return 0;
293 }
294 
rot_irq_disable(void)295 __s32 rot_irq_disable(void)
296 {
297 	write_wvalue(ROT_INT, 0x0);
298 	return 0;
299 }
300 
g2d_sclk_div(__u32 div)301 __s32 g2d_sclk_div(__u32 div)
302 {
303 	__u32 reg_val;
304 
305 	reg_val = read_wvalue(G2D_SCLK_DIV);
306 	reg_val &= 0xfffffff0;
307 	reg_val |= (div & 0xf);
308 	write_wvalue(G2D_SCLK_DIV, reg_val);
309 	return 0;
310 }
311 
rot_sclk_div(__u32 div)312 __s32 rot_sclk_div(__u32 div)
313 {
314 	__u32 reg_val;
315 
316 	reg_val = read_wvalue(G2D_SCLK_DIV);
317 	reg_val &= 0xffffff0f;
318 	reg_val |= (div & 0xf) << 4;
319 	write_wvalue(G2D_SCLK_DIV, reg_val);
320 	return 0;
321 }
322 
porter_duff(__u32 cmd)323 __s32 porter_duff(__u32 cmd)
324 {
325 	switch (cmd) {
326 	case G2D_BLD_CLEAR:
327 		write_wvalue(BLD_CTL, 0x00000000);
328 		break;
329 	case G2D_BLD_COPY:
330 		write_wvalue(BLD_CTL, 0x00010001);
331 		break;
332 	case G2D_BLD_DST:
333 		write_wvalue(BLD_CTL, 0x01000100);
334 		break;
335 	case G2D_BLD_SRCOVER:
336 		write_wvalue(BLD_CTL, 0x03010301);
337 		break;
338 	case G2D_BLD_DSTOVER:
339 		write_wvalue(BLD_CTL, 0x01030103);
340 		break;
341 	case G2D_BLD_SRCIN:
342 		write_wvalue(BLD_CTL, 0x00020002);
343 		break;
344 	case G2D_BLD_DSTIN:
345 		write_wvalue(BLD_CTL, 0x02000200);
346 		break;
347 	case G2D_BLD_SRCOUT:
348 		write_wvalue(BLD_CTL, 0x00030003);
349 		break;
350 	case G2D_BLD_DSTOUT:
351 		write_wvalue(BLD_CTL, 0x03000300);
352 		break;
353 	case G2D_BLD_SRCATOP:
354 		write_wvalue(BLD_CTL, 0x03020302);
355 		break;
356 	case G2D_BLD_DSTATOP:
357 		write_wvalue(BLD_CTL, 0x02030203);
358 		break;
359 	case G2D_BLD_XOR:
360 		write_wvalue(BLD_CTL, 0x03030303);
361 		break;
362 	default:
363 		write_wvalue(BLD_CTL, 0x03010301);
364 		}
365 	return 0;
366 }
367 
368 
369 /**
370  * @csc_no: CSC ID, G2D support three CSC,
371  * -1 will return to indicate inappropriate CSC number.
372  * @csc_sel: CSC format, G2D support the ITU-R 601. ITU-R 709. standard trans-
373  *  form between RGB and YUV colorspace.
374  */
g2d_csc_reg_set(__u32 csc_no,g2d_csc_sel csc_sel)375 __s32 g2d_csc_reg_set(__u32 csc_no, g2d_csc_sel csc_sel)
376 {
377 	__u32 i;
378 	__u32 csc_base_addr;
379 	__u32 tmp;
380 
381 	switch (csc_no) {
382 	case 0:
383 		csc_base_addr = G2D_BLD + 0x110;
384 		tmp = read_wvalue(BLD_CSC_CTL);
385 		tmp |= 0x1;
386 		write_wvalue(BLD_CSC_CTL, tmp);
387 		break;
388 	case 1:
389 		csc_base_addr = G2D_BLD + 0x140;
390 		tmp = read_wvalue(BLD_CSC_CTL);
391 		tmp |= 0x1 << 1;
392 		write_wvalue(BLD_CSC_CTL, tmp);
393 		break;
394 	case 2:
395 		csc_base_addr = G2D_BLD + 0x170;
396 		tmp = read_wvalue(BLD_CSC_CTL);
397 		tmp |= 0x1 << 2;
398 		write_wvalue(BLD_CSC_CTL, tmp);
399 		break;
400 	default:
401 
402 /* __wrn("sel wrong csc no.\n"); */
403 		    return -1;
404 	}
405 	switch (csc_sel) {
406 	case G2D_RGB2YUV_709:
407 		for (i = 0; i < 12; i++)
408 			write_wvalue(csc_base_addr + (i << 2),
409 				      rgb2Ycbcr_709[i]);
410 		break;
411 	case G2D_YUV2RGB_709:
412 		for (i = 0; i < 12; i++)
413 			write_wvalue(csc_base_addr + (i << 2),
414 				      Ycbcr2rgb_709[i]);
415 		break;
416 	case G2D_RGB2YUV_601:
417 		for (i = 0; i < 12; i++)
418 			write_wvalue(csc_base_addr + (i << 2),
419 				      rgb2Ycbcr_601[i]);
420 
421 /* write_wvalue(csc_base_addr + (i<<2), */
422 /* rgb2Ycbcr_601[i]); */
423 		    break;
424 	case G2D_YUV2RGB_601:
425 		for (i = 0; i < 12; i++)
426 			write_wvalue(csc_base_addr + (i << 2),
427 				      Ycbcr2rgb_601[i]);
428 
429 /* write_wvalue(csc_base_addr + (i<<2), */
430 /* Ycbcr2rgb_601[i]); */
431 		    break;
432 	default:
433 
434 /* __wrn("wrong csc standard\n"); */
435 		    return -2;
436 	}
437 	return 0;
438 }
439 
440 
441 /**
442  * set colorkey para.
443  */
ck_para_set(g2d_ck * para)444 __s32 ck_para_set(g2d_ck *para)
445 {
446 	__u32 tmp = 0x0;
447 
448 	if (para->match_rule)
449 		tmp = 0x7;
450 	write_wvalue(BLD_KEY_CON, tmp);
451 	write_wvalue(BLD_KEY_MAX, para->max_color & 0x00ffffff);
452 	write_wvalue(BLD_KEY_MIN, para->min_color & 0x00ffffff);
453 	return 0;
454 }
455 
456 
457 /**
458  */
g2d_byte_cal(__u32 format,__u32 * ycnt,__u32 * ucnt,__u32 * vcnt)459 __s32 g2d_byte_cal(__u32 format, __u32 *ycnt, __u32 *ucnt, __u32 *vcnt)
460 {
461 	*ycnt = 0;
462 	*ucnt = 0;
463 	*vcnt = 0;
464 	if (format <= G2D_FORMAT_BGRX8888)
465 		*ycnt = 4;
466 
467 	else if (format <= G2D_FORMAT_BGR888)
468 		*ycnt = 3;
469 
470 	else if (format <= G2D_FORMAT_BGRA5551)
471 		*ycnt = 2;
472 
473 	else if (format <= G2D_FORMAT_BGRA1010102)
474 		*ycnt = 4;
475 
476 	else if (format <= 0x23) {
477 		*ycnt = 2;
478 	}
479 
480 	else if (format <= 0x25) {
481 		*ycnt = 1;
482 		*ucnt = 2;
483 	}
484 
485 	else if (format == 0x26) {
486 		*ycnt = 1;
487 		*ucnt = 1;
488 		*vcnt = 1;
489 	}
490 
491 	else if (format <= 0x29) {
492 		*ycnt = 1;
493 		*ucnt = 2;
494 	}
495 
496 	else if (format == 0x2a) {
497 		*ycnt = 1;
498 		*ucnt = 1;
499 		*vcnt = 1;
500 	}
501 
502 	else if (format <= 0x2d) {
503 		*ycnt = 1;
504 		*ucnt = 2;
505 	}
506 
507 	else if (format == 0x2e) {
508 		*ycnt = 1;
509 		*ucnt = 1;
510 		*vcnt = 1;
511 	}
512 
513 	else if (format == 0x30)
514 		*ycnt = 1;
515 
516 	else if (format <= 0x36) {
517 		*ycnt = 2;
518 		*ucnt = 4;
519 	}
520 
521 	else if (format <= 0x39)
522 		*ycnt = 6;
523 	return 0;
524 }
525 
526 
527 /**
528  */
cal_align(__u32 width,__u32 align)529 __u32 cal_align(__u32 width, __u32 align)
530 {
531 	switch (align) {
532 	case 0:
533 		return width;
534 	case 4:
535 		return (width + 3) >> 1 << 1;
536 	case 8:
537 		return (width + 7) >> 3 << 3;
538 	case 16:
539 		return (width + 15) >> 4 << 4;
540 	case 32:
541 		return (width + 31) >> 5 << 5;
542 	case 64:
543 		return (width + 63) >> 6 << 6;
544 	case 128:
545 		return (width + 127) >> 7 << 7;
546 	default:
547 		return (width + 31) >> 5 << 5;
548 	}
549 }
550 
551 
552 /**
553  * @sel:layer no.
554  */
g2d_vlayer_set(__u32 sel,g2d_image_enh * image)555 __s32 g2d_vlayer_set(__u32 sel, g2d_image_enh *image)
556 {
557 	unsigned long long addr0, addr1, addr2;
558 	__u32 tmp;
559 	__u32 ycnt, ucnt, vcnt;
560 	__u32 pitch0, pitch1, pitch2;
561 	__u32 ch, cw, cy, cx;
562 
563 	switch (sel) {
564 	case 0:
565 
566 		    /* base_addr = G2D_V0; */
567 		    break;
568 	default:
569 		return -1;
570 	}
571 	tmp = ((image->alpha & 0xff) << 24);
572 	if (image->bpremul)
573 		tmp |= (0x1 << 17);
574 	tmp |= (image->format << 8);
575 	tmp |= (image->mode << 1);
576 	tmp |= 1;
577 	write_wvalue(V0_ATTCTL, tmp);
578 	tmp =
579 	    (((image->clip_rect.h ==
580 	       0 ? 0 : image->clip_rect.h -
581 	       1) & 0x1fff) << 16) | ((image->clip_rect.w ==
582 					0 ? 0 : image->clip_rect.w -
583 					1) & 0x1fff);
584 	write_wvalue(V0_MBSIZE, tmp);
585 
586 	    /* offset is set to 0, ovl size is set to layer size */
587 	    write_wvalue(V0_SIZE, tmp);
588 	write_wvalue(V0_COOR, 0);
589 	if ((image->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0)
590 	      && (image->format <= G2D_FORMAT_YUV422_PLANAR)) {
591 		cw = image->width >> 1;
592 		ch = image->height;
593 		cx = image->clip_rect.x >> 1;
594 		cy = image->clip_rect.y;
595 	}
596 
597 	else if ((image->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0)
598 		 && (image->format <= G2D_FORMAT_YUV420_PLANAR)) {
599 		cw = image->width >> 1;
600 		ch = image->height >> 1;
601 		cx = image->clip_rect.x >> 1;
602 		cy = image->clip_rect.y >> 1;
603 	}
604 
605 	else if ((image->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0)
606 		 && (image->format <= G2D_FORMAT_YUV411_PLANAR)) {
607 		cw = image->width >> 2;
608 		ch = image->height;
609 		cx = image->clip_rect.x >> 2;
610 		cy = image->clip_rect.y;
611 	}
612 
613 	else {
614 		cw = 0;
615 		ch = 0;
616 		cx = 0;
617 		cy = 0;
618 	}
619 	g2d_byte_cal(image->format, &ycnt, &ucnt, &vcnt);
620 	pitch0 = cal_align(ycnt * image->width, image->align[0]);
621 	write_wvalue(V0_PITCH0, pitch0);
622 	pitch1 = cal_align(ucnt * cw, image->align[1]);
623 	write_wvalue(V0_PITCH1, pitch1);
624 	pitch2 = cal_align(vcnt * cw, image->align[2]);
625 	write_wvalue(V0_PITCH2, pitch2);
626 	G2D_INFO_MSG("VInPITCH: %d, %d, %d\n",
627 				pitch0, pitch1, pitch2);
628 	G2D_INFO_MSG("VInAddrB: 0x%x, 0x%x, 0x%x\n",
629 			image->laddr[0], image->laddr[1], image->laddr[2]);
630 	addr0 =
631 	    image->laddr[0] + ((__u64) image->haddr[0] << 32) +
632 	    pitch0 * image->clip_rect.y + ycnt * image->clip_rect.x;
633 	write_wvalue(V0_LADD0, addr0 & 0xffffffff);
634 	addr1 =
635 	    image->laddr[1] + ((__u64) image->haddr[1] << 32) + pitch1 * cy +
636 	    ucnt * cx;
637 	write_wvalue(V0_LADD1, addr1 & 0xffffffff);
638 	addr2 =
639 	    image->laddr[2] + ((__u64) image->haddr[2] << 32) + pitch2 * cy +
640 	    vcnt * cx;
641 	write_wvalue(V0_LADD2, addr2 & 0xffffffff);
642 	tmp = ((addr0 >> 32) & 0xff) | ((addr1 >> 32) & 0xff) << 8 |
643 	    ((addr2 >> 32) & 0xff) << 16;
644 	write_wvalue(V0_HADD, tmp);
645 	G2D_INFO_MSG("VInAddrA: 0x%llx, 0x%llx, 0x%llx\n",
646 							addr0, addr1, addr2);
647 	if (image->bbuff == 0)
648 		g2d_fc_set((sel + VI_LAYER_NUMBER), image->color);
649 	return 0;
650 }
651 
g2d_uilayer_set(__u32 sel,g2d_image_enh * img)652 __s32 g2d_uilayer_set(__u32 sel, g2d_image_enh *img)
653 {
654 	__u64 addr0;
655 	__u32 base_addr_u, tmp;
656 	__u32 ycnt, ucnt, vcnt;
657 	__u32 pitch0;
658 
659 	switch (sel) {
660 	case 0:
661 		base_addr_u = G2D_UI0;
662 		break;
663 	case 1:
664 		base_addr_u = G2D_UI1;
665 		break;
666 	case 2:
667 		base_addr_u = G2D_UI2;
668 		break;
669 	default:
670 		return -1;
671 	}
672 	tmp = (img->alpha & 0xff) << 24;
673 	if (img->bpremul)
674 		tmp |= 0x1 << 17;
675 	tmp |= img->format << 8;
676 	tmp |= img->mode << 1;
677 	tmp |= 1;
678 	write_wvalue(base_addr_u, tmp);
679 	tmp =
680 	    (((img->clip_rect.h ==
681 	       0 ? 0 : img->clip_rect.h -
682 	       1) & 0x1fff) << 16) | ((img->clip_rect.w ==
683 					0 ? 0 : img->clip_rect.w - 1) & 0x1fff);
684 	write_wvalue(base_addr_u + 0x4, tmp);
685 	write_wvalue(base_addr_u + 0x1C, tmp);
686 	write_wvalue(base_addr_u + 0x8, 0);
687 	g2d_byte_cal(img->format, &ycnt, &ucnt, &vcnt);
688 	pitch0 = cal_align(ycnt * img->width, img->align[0]);
689 	write_wvalue(base_addr_u + 0xC, pitch0);
690 	addr0 =
691 	    img->laddr[0] + ((__u64) img->haddr[0] << 32) +
692 	    pitch0 * img->clip_rect.y + ycnt * img->clip_rect.x;
693 	write_wvalue(base_addr_u + 0x10, addr0 & 0xffffffff);
694 	write_wvalue(base_addr_u + 0x18, (addr0 >> 32) & 0xff);
695 	if (img->bbuff == 0)
696 		g2d_fc_set((sel + VI_LAYER_NUMBER), img->color);
697 	return 0;
698 }
699 
g2d_wb_set(g2d_image_enh * image)700 __s32 g2d_wb_set(g2d_image_enh *image)
701 {
702 	__u64 addr0, addr1, addr2;
703 	__u32 tmp;
704 	__u32 ycnt, ucnt, vcnt;
705 	__u32 pitch0, pitch1, pitch2;
706 	__u32 ch, cw, cy, cx;
707 
708 	write_wvalue(WB_ATT, image->format);
709 	tmp =
710 	    (((image->clip_rect.h ==
711 	       0 ? 0 : image->clip_rect.h -
712 	       1) & 0x1fff) << 16) | ((image->clip_rect.w ==
713 					0 ? 0 : image->clip_rect.w -
714 					1) & 0x1fff);
715 	write_wvalue(WB_SIZE, tmp);
716 	/*write to the bld out reg */
717 	G2D_INFO_MSG("BLD_CH_OSIZE W:  0x%x\n", image->clip_rect.w);
718 	G2D_INFO_MSG("BLD_CH_OSIZE H:  0x%x\n", image->clip_rect.h);
719 	write_wvalue(BLD_SIZE, tmp);
720 	/* set outdata premul */
721 	tmp = read_wvalue(BLD_OUT_COLOR);
722 
723 	if (image->bpremul)
724 		write_wvalue(BLD_OUT_COLOR, tmp | 0x1);
725 
726 	else
727 		write_wvalue(BLD_OUT_COLOR, tmp & 0x2);
728 	if ((image->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0)
729 	      && (image->format <= G2D_FORMAT_YUV422_PLANAR)) {
730 		cw = image->width >> 1;
731 		ch = image->height;
732 		cx = image->clip_rect.x >> 1;
733 		cy = image->clip_rect.y;
734 	}
735 
736 	else if ((image->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0)
737 		 && (image->format <= G2D_FORMAT_YUV420_PLANAR)) {
738 		cw = image->width >> 1;
739 		ch = image->height >> 1;
740 		cx = image->clip_rect.x >> 1;
741 		cy = image->clip_rect.y >> 1;
742 	}
743 
744 	else if ((image->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0)
745 		 && (image->format <= G2D_FORMAT_YUV411_PLANAR)) {
746 		cw = image->width >> 2;
747 		ch = image->height;
748 		cx = image->clip_rect.x >> 2;
749 		cy = image->clip_rect.y;
750 	}
751 
752 	else {
753 		cw = 0;
754 		ch = 0;
755 		cx = 0;
756 		cy = 0;
757 	}
758 	g2d_byte_cal(image->format, &ycnt, &ucnt, &vcnt);
759 	pitch0 = cal_align(ycnt * image->width, image->align[0]);
760 	write_wvalue(WB_PITCH0, pitch0);
761 	pitch1 = cal_align(ucnt * cw, image->align[1]);
762 	write_wvalue(WB_PITCH1, pitch1);
763 	pitch2 = cal_align(vcnt * cw, image->align[2]);
764 	write_wvalue(WB_PITCH2, pitch2);
765 	G2D_INFO_MSG("OutputPitch: %d, %d, %d\n", pitch0, pitch1, pitch2);
766 
767 	addr0 =
768 	    image->laddr[0] + ((__u64) image->haddr[0] << 32) +
769 	    pitch0 * image->clip_rect.y + ycnt * image->clip_rect.x;
770 	write_wvalue(WB_LADD0, addr0 & 0xffffffff);
771 	write_wvalue(WB_HADD0, (addr0 >> 32) & 0xff);
772 	addr1 =
773 	    image->laddr[1] + ((__u64) image->haddr[1] << 32) + pitch1 * cy +
774 	    ucnt * cx;
775 	write_wvalue(WB_LADD1, addr1 & 0xffffffff);
776 	write_wvalue(WB_HADD1, (addr1 >> 32) & 0xff);
777 	addr2 =
778 	    image->laddr[2] + ((__u64) image->haddr[2] << 32) + pitch2 * cy +
779 	    vcnt * cx;
780 	write_wvalue(WB_LADD2, addr2 & 0xffffffff);
781 	write_wvalue(WB_HADD2, (addr2 >> 32) & 0xff);
782 	G2D_INFO_MSG("WbAddr: 0x%llx, 0x%llx, 0x%llx\n", addr0, addr1, addr2);
783 	return 0;
784 }
785 
786 
787 /**
788  * fillcolor set
789  * @sel:layer_no, 0--Layer Video,1--Layer UI0,2--Layer UI1,3--Layer UI2
790  * @color_value:fill color value
791  */
g2d_fc_set(__u32 sel,__u32 color_value)792 __s32 g2d_fc_set(__u32 sel, __u32 color_value)
793 {
794 	__u32 tmp;
795 
796 	G2D_INFO_MSG("FILLCOLOR: sel: %d, color: 0x%x\n", sel, color_value);
797 
798 	if (sel == 0) {
799 		/* Layer Video */
800 		tmp = read_wvalue(V0_ATTCTL);
801 		tmp |= (0x1 << 4);
802 		write_wvalue(V0_ATTCTL, tmp);
803 		write_wvalue(V0_FILLC, color_value);
804 	}
805 	if (sel == 1) {
806 		/* Layer UI0 */
807 		tmp = read_wvalue(UI0_ATTR);
808 		tmp |= (0x1 << 4);
809 		write_wvalue(UI0_ATTR, tmp);
810 		write_wvalue(UI0_FILLC, color_value);
811 	}
812 	if (sel == 2) {
813 		/* Layer UI1 */
814 		tmp = read_wvalue(UI1_ATTR);
815 		tmp |= (0x1 << 4);
816 		write_wvalue(UI1_ATTR, tmp);
817 		write_wvalue(UI1_FILLC, color_value);
818 	}
819 	if (sel == 3) {
820 		/* Layer UI2 */
821 		tmp = read_wvalue(UI2_ATTR);
822 		tmp |= (0x1 << 4);
823 		write_wvalue(UI2_ATTR, tmp);
824 		write_wvalue(UI2_FILLC, color_value);
825 	}
826 	return 0;
827 }
828 
829 
830 /**
831  * ROP2 cmd register set
832  * Index0 is selected
833  * dst mapping ch0'
834  * src mapping ch1'
835  */
g2d_rop2_set(__u32 rop_cmd)836 __s32 g2d_rop2_set(__u32 rop_cmd)
837 {
838 	if (rop_cmd == G2D_BLT_BLACKNESS) {
839 		/* blackness */
840 		/* tmpue = 0x1<<18; */
841 		write_wvalue(ROP_INDEX0, 0x40000);
842 	} else if (rop_cmd == G2D_BLT_NOTMERGEPEN) {
843 		/* ~(dst | src) */
844 		/* tmpue = (0x1<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
845 		write_wvalue(ROP_INDEX0, 0x41440);
846 	} else if (rop_cmd == G2D_BLT_MASKNOTPEN) {
847 		/* ~src&dst */
848 		/* tmpue = (0x1<<4) | (0x0<<10) | (0x2<<11) | (0x1<<18); */
849 		write_wvalue(ROP_INDEX0, 0x41010);
850 	} else if (rop_cmd == G2D_BLT_NOTCOPYPEN) {
851 		/* ~src */
852 		/* tmpue = (0x1<<4) | (0x2<<6) | (0x2<<11) |
853 		 * (0x1<<18) | (0x1<<17);
854 		 */
855 		write_wvalue(ROP_INDEX0, 0x61090);
856 	} else if (rop_cmd == G2D_BLT_MASKPENNOT) {
857 		/* src&~dst */
858 		/* tmpue = (0x1<<3) | (0x0<<10) | (0x2<<11) | (0x1<<18); */
859 		write_wvalue(ROP_INDEX0, 0x41008);
860 	} else if (rop_cmd == G2D_BLT_NOT) {
861 		/* ~dst */
862 		/* tmpue = (0x1<<3) | (0x2<<6) | (0x2<<11) |
863 		 * (0x1<<18) | (0x1<<16);
864 		 */
865 		write_wvalue(ROP_INDEX0, 0x51088);
866 	} else if (rop_cmd == G2D_BLT_XORPEN) {
867 		/* src xor dst */
868 		/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18); */
869 		write_wvalue(ROP_INDEX0, 0x41080);
870 	} else if (rop_cmd == G2D_BLT_NOTMASKPEN) {
871 		/* ~(src & dst) */
872 		/* tmpue = (0x0<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
873 		write_wvalue(ROP_INDEX0, 0x41400);
874 	} else if (rop_cmd == G2D_BLT_MASKPEN) {
875 		/* src&dst */
876 		/* tmpue = (0x0<<6) | (0x2<<11) | (0x1<<18); */
877 		write_wvalue(ROP_INDEX0, 0x41000);
878 	} else if (rop_cmd == G2D_BLT_NOTXORPEN) {
879 		/* ~(src xor dst) */
880 		/* tmpue = (0x2<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
881 		write_wvalue(ROP_INDEX0, 0x41480);
882 	} else if (rop_cmd == G2D_BLT_NOP) {
883 		/* dst */
884 		/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
885 		write_wvalue(ROP_INDEX0, 0x51080);
886 	} else if (rop_cmd == G2D_BLT_MERGENOTPEN) {
887 		/* ~dst or src */
888 		/* tmpue = (0x1<<3)| (0x1<<6) | (0x2<<11) | (0x1<<18) */
889 		/* write_wvalue(ROP_INDEX0, 0x40A20); */
890 		write_wvalue(ROP_INDEX0, 0x41048);
891 	} else if (rop_cmd == G2D_BLT_COPYPEN) {
892 		/* src */
893 		/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<17); */
894 		write_wvalue(ROP_INDEX0, 0x61080);
895 	} else if (rop_cmd == G2D_BLT_MERGEPENNOT) {
896 		/* src or ~dst */
897 		/* tmpue =  (0x1<<3)| (0x1<<6) | (0x2<<11) | (0x1<<18) */
898 		write_wvalue(ROP_INDEX0, 0x41048);
899 	} else if (rop_cmd == G2D_BLT_MERGEPEN) {
900 		/* src or dst */
901 		/* tmpue = (0x1<<6) | (0x1<<18) | (0x2<<11); */
902 		write_wvalue(ROP_INDEX0, 0x41040);
903 	} else if (rop_cmd == G2D_BLT_WHITENESS) {
904 		/* whiteness */
905 		/* tmpue = (0x1<<18) | (0x1<<15); */
906 		write_wvalue(ROP_INDEX0, 0x48000);
907 	} else
908 		return -1;
909 	return 0;
910 }
911 
912 
913 /**
914  * ROP3 cmd register set
915  * dst mapping ch0'
916  * src mapping ch1'
917  * ptn mapping ch2'
918  * -1 return meaning that the operate is not supported by now
919  */
g2d_rop3_set(__u32 sel,__u32 rop3_cmd)920 __s32 g2d_rop3_set(__u32 sel, __u32 rop3_cmd)
921 {
922 	__u32 addr;
923 
924 	if (sel == 0)
925 		addr = ROP_INDEX0;
926 	else if (sel == 1)
927 		addr = ROP_INDEX1;
928 
929 	else
930 		return -1;
931 	if (rop3_cmd == G2D_ROP3_BLACKNESS) {
932 		/* blackness */
933 		/* 0x1<<18; */
934 		write_wvalue(addr, 0x40000);
935 	} else if (rop3_cmd == G2D_ROP3_NOTSRCERASE) {
936 		/* (~src) AND (~dst) */
937 		/* (0x1<<3) | (0x1<<4) | (0x1<<18) | (0x2<<11); */
938 		write_wvalue(addr, 0x41018);
939 	} else if (rop3_cmd == G2D_ROP3_NOTSRCCOPY) {
940 
941 		/* ~src */
942 		/* (0x1<<4) | (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
943 		write_wvalue(addr, 0x51090);
944 	} else if (rop3_cmd == G2D_ROP3_SRCERASE) {
945 		/* src AND ~dst */
946 		/* (0x1<<3) | (0x0<<6) | (0x2<<11) | (0x1<<18); */
947 		write_wvalue(addr, 0x41008);
948 	} else if (rop3_cmd == G2D_ROP3_DSTINVERT) {
949 		/* ~dst */
950 		/* (0x1<<3) | (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<17); */
951 		write_wvalue(addr, 0x61088);
952 	} else if (rop3_cmd == G2D_ROP3_PATINVERT) {
953 		/* ptn XOR dst */
954 		/* (0x2<<6) | (0x2<<11) | (0x1<<17) */
955 		write_wvalue(addr, 0x21080);
956 	} else if (rop3_cmd == G2D_ROP3_SRCINVERT) {
957 		/* src XOR dst */
958 		/* (0x2<<6) | (0x2<<11) | (0x1<<18); */
959 		write_wvalue(addr, 0x41080);
960 	} else if (rop3_cmd == G2D_ROP3_SRCAND) {
961 		/* src AND dst */
962 		/* (0x0<<6) | (0x2<<11) | (0x1<<18); */
963 		write_wvalue(addr, 0x41000);
964 	} else if (rop3_cmd == G2D_ROP3_MERGEPAINT) {
965 		/* ~src OR dst */
966 		/* (0x1<<4) | (0x1<<6) | (0x2<<11) | (0x1<<18); */
967 		write_wvalue(addr, 0x41050);
968 	} else if (rop3_cmd == G2D_ROP3_MERGECOPY) {
969 		/* src AND pattern */
970 		/* (0x2<<6) | (0x1<<16) */
971 		write_wvalue(addr, 0x10080);
972 	} else if (rop3_cmd == G2D_ROP3_SRCCOPY) {
973 		/* src */
974 		/* (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
975 		write_wvalue(addr, 0x51080);
976 	} else if (rop3_cmd == G2D_ROP3_SRCPAINT) {
977 		/* src OR dst */
978 		/* (0x1<<6) | (0x2<<11) | (0x1<<18); */
979 		write_wvalue(addr, 0x41040);
980 	} else if (rop3_cmd == G2D_ROP3_PATCOPY) {
981 		/* ptn */
982 		/* (0x1<<16) | (0x1<<17) | (0x2)<<11 */
983 		write_wvalue(addr, 0x31000);
984 	} else if (rop3_cmd == G2D_ROP3_PATPAINT) {
985 		/* DPSnoo */
986 		/* (0x1<<3) | (0x1<<6) | (0x1<<11) */
987 		write_wvalue(addr, 0x848);
988 	} else if (rop3_cmd == G2D_ROP3_WHITENESS) {
989 		/* whiteness */
990 		write_wvalue(addr, 0x48000);
991 	} else
992 		return -1;
993 	return 0;
994 }
995 
996 /**
997  * background color set
998  */
g2d_bk_set(__u32 color)999 __s32 g2d_bk_set(__u32 color)
1000 {
1001 	write_wvalue(BLD_BK_COLOR, color & 0xffffffff);
1002 	return 0;
1003 }
1004 
1005 /**
1006  * function       : g2d_vsu_calc_fir_coef(unsigned int step)
1007  * description    : set fir coefficients
1008  * parameters     :
1009  *                  step		<horizontal scale ratio of vsu>
1010  * return         :
1011  *                  offset (in word) of coefficient table
1012  */
g2d_vsu_calc_fir_coef(__u32 step)1013 static __u32 g2d_vsu_calc_fir_coef(__u32 step)
1014 {
1015 	__u32 pt_coef;
1016 	__u32 scale_ratio, int_part, float_part, fir_coef_ofst;
1017 
1018 	scale_ratio = step >> (VSU_PHASE_FRAC_BITWIDTH - 3);
1019 	int_part = scale_ratio >> 3;
1020 	float_part = scale_ratio & 0x7;
1021 	fir_coef_ofst = (int_part == 0) ? VSU_ZOOM0_SIZE :
1022 	    (int_part == 1) ? VSU_ZOOM0_SIZE + float_part :
1023 	    (int_part ==
1024 	     2) ? VSU_ZOOM0_SIZE + VSU_ZOOM1_SIZE +
1025 	    (float_part >> 1) : (int_part ==
1026 				  3) ? VSU_ZOOM0_SIZE + VSU_ZOOM1_SIZE +
1027 	    VSU_ZOOM2_SIZE : (int_part ==
1028 			       4) ? VSU_ZOOM0_SIZE + VSU_ZOOM1_SIZE +
1029 	    VSU_ZOOM2_SIZE + VSU_ZOOM3_SIZE : VSU_ZOOM0_SIZE +
1030 	    VSU_ZOOM1_SIZE + VSU_ZOOM2_SIZE + VSU_ZOOM3_SIZE + VSU_ZOOM4_SIZE;
1031 	pt_coef = fir_coef_ofst * VSU_PHASE_NUM;
1032 	return pt_coef;
1033 }
1034 
g2d_rop_by_pass(__u32 sel)1035 __s32 g2d_rop_by_pass(__u32 sel)
1036 {
1037 	if (sel == 0)
1038 		write_wvalue(ROP_CTL, 0xF0);
1039 
1040 	else if (sel == 1)
1041 		write_wvalue(ROP_CTL, 0x55F0);
1042 
1043 	else if (sel == 2)
1044 		write_wvalue(ROP_CTL, 0xAAF0);
1045 
1046 	else
1047 		return -1;
1048 	return 0;
1049 }
1050 
g2d_vsu_para_set(__u32 fmt,__u32 in_w,__u32 in_h,__u32 out_w,__u32 out_h,__u8 alpha)1051 __s32 g2d_vsu_para_set(__u32 fmt, __u32 in_w, __u32 in_h, __u32 out_w,
1052 			   __u32 out_h, __u8 alpha)
1053 {
1054 	__u32 i;
1055 	__u64 tmp, temp;
1056 	__u32 yhstep, yvstep;
1057 	__u32 incw, inch;
1058 	__u32 yhcoef_offset, yvcoef_offset, chcoef_offset;
1059 	__u32 format;
1060 
1061 	if (fmt > G2D_FORMAT_IYUV422_Y1U0Y0V0)
1062 		write_wvalue(VS_CTRL, 0x10101);
1063 
1064 	else
1065 		write_wvalue(VS_CTRL, 0x00000101);
1066 	tmp = ((out_h - 1) << 16) | (out_w - 1);
1067 	write_wvalue(VS_OUT_SIZE, tmp);
1068 	write_wvalue(VS_GLB_ALPHA, alpha & 0xff);
1069 	write_wvalue(VS_Y_SIZE, ((in_h - 1) << 16) | (in_w - 1));
1070 	temp = in_w << VSU_PHASE_FRAC_BITWIDTH;
1071 	if (out_w)
1072 		do_div(temp, out_w);
1073 
1074 	    /* temp = temp/out_w; */
1075 	else
1076 		temp = 0;
1077 	yhstep = temp;
1078 	write_wvalue(VS_Y_HSTEP, yhstep << 1);
1079 	temp = in_h << VSU_PHASE_FRAC_BITWIDTH;
1080 	if (out_h)
1081 		do_div(temp, out_h);
1082 	else
1083 		temp = 0;
1084 	yvstep = temp;
1085 	write_wvalue(VS_Y_VSTEP, yvstep << 1);
1086 	yhcoef_offset = g2d_vsu_calc_fir_coef(yhstep);
1087 	for (i = 0; i < VSU_PHASE_NUM; i++) {
1088 		write_wvalue(VS_Y_HCOEF0 + (i << 2),
1089 			      lan2coefftab32_full[yhcoef_offset + i]);
1090 	}
1091 	yvcoef_offset = g2d_vsu_calc_fir_coef(yvstep);
1092 	switch (fmt) {
1093 	case G2D_FORMAT_IYUV422_V0Y1U0Y0:
1094 	case G2D_FORMAT_IYUV422_Y1V0Y0U0:
1095 	case G2D_FORMAT_IYUV422_U0Y1V0Y0:
1096 	case G2D_FORMAT_IYUV422_Y1U0Y0V0:{
1097 			incw = (in_w + 1) >> 1;
1098 			inch = in_h;
1099 			format = VSU_FORMAT_YUV422;
1100 			write_wvalue(VS_C_SIZE,
1101 				      ((inch - 1) << 16) | (incw - 1));
1102 
1103 			    /* chstep = yhstep>>1 cvstep = yvstep */
1104 			    write_wvalue(VS_C_HSTEP, yhstep);
1105 			write_wvalue(VS_C_VSTEP, yvstep << 1);
1106 			chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 1);
1107 			for (i = 0; i < VSU_PHASE_NUM; i++)
1108 				write_wvalue(VS_C_HCOEF0 + (i << 2),
1109 					      lan2coefftab32_full[chcoef_offset
1110 								  + i]);
1111 			for (i = 0; i < VSU_PHASE_NUM; i++)
1112 				write_wvalue(VS_Y_VCOEF0 + (i << 2),
1113 					      linearcoefftab32[i]);
1114 			break;
1115 		}
1116 	case G2D_FORMAT_YUV422UVC_V1U1V0U0:
1117 	case G2D_FORMAT_YUV422UVC_U1V1U0V0:
1118 	case G2D_FORMAT_YUV422_PLANAR:{
1119 			incw = (in_w + 1) >> 1;
1120 			inch = in_h;
1121 			format = VSU_FORMAT_YUV422;
1122 			write_wvalue(VS_C_SIZE,
1123 				      ((inch - 1) << 16) | (incw - 1));
1124 
1125 			    /* chstep = yhstep>>1 cvstep = yvstep>>1 */
1126 			    write_wvalue(VS_C_HSTEP, yhstep);
1127 			write_wvalue(VS_C_VSTEP, yvstep << 1);
1128 			chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 1);
1129 			for (i = 0; i < VSU_PHASE_NUM; i++)
1130 				write_wvalue(VS_C_HCOEF0 + (i << 2),
1131 					      lan2coefftab32_full[chcoef_offset
1132 								  + i]);
1133 			for (i = 0; i < VSU_PHASE_NUM; i++)
1134 				write_wvalue(VS_Y_VCOEF0 + (i << 2),
1135 					      lan2coefftab32_full[yvcoef_offset
1136 								  + i]);
1137 			break;
1138 		}
1139 	case G2D_FORMAT_YUV420_PLANAR:
1140 	case G2D_FORMAT_YUV420UVC_V1U1V0U0:
1141 	case G2D_FORMAT_YUV420UVC_U1V1U0V0:{
1142 			incw = (in_w + 1) >> 1;
1143 			inch = (in_h + 1) >> 1;
1144 			format = VSU_FORMAT_YUV420;
1145 			write_wvalue(VS_C_SIZE,
1146 				      ((inch - 1) << 16) | (incw - 1));
1147 			write_wvalue(VS_C_HSTEP, yhstep);
1148 			write_wvalue(VS_C_VSTEP, yvstep);
1149 			chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 1);
1150 			for (i = 0; i < VSU_PHASE_NUM; i++)
1151 				write_wvalue(VS_C_HCOEF0 + (i << 2),
1152 					      lan2coefftab32_full[chcoef_offset
1153 								  + i]);
1154 			for (i = 0; i < VSU_PHASE_NUM; i++)
1155 				write_wvalue(VS_Y_VCOEF0 + (i << 2),
1156 					      lan2coefftab32_full[yvcoef_offset
1157 								  + i]);
1158 			break;
1159 		}
1160 	case G2D_FORMAT_YUV411_PLANAR:
1161 	case G2D_FORMAT_YUV411UVC_V1U1V0U0:
1162 	case G2D_FORMAT_YUV411UVC_U1V1U0V0:{
1163 			incw = (in_w + 3) >> 2;
1164 			inch = in_h;
1165 			format = VSU_FORMAT_YUV411;
1166 			write_wvalue(VS_C_SIZE,
1167 				      ((inch - 1) << 16) | (incw - 1));
1168 
1169 			    /* chstep = yhstep>>2 cvstep = yvstep */
1170 			    write_wvalue(VS_C_HSTEP, yhstep >> 1);
1171 			write_wvalue(VS_C_VSTEP, yvstep << 1);
1172 			chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 2);
1173 			for (i = 0; i < VSU_PHASE_NUM; i++)
1174 				write_wvalue(VS_C_HCOEF0 + (i << 2),
1175 					      lan2coefftab32_full[chcoef_offset
1176 								  + i]);
1177 			for (i = 0; i < VSU_PHASE_NUM; i++)
1178 				write_wvalue(VS_Y_VCOEF0 + (i << 2),
1179 					      lan2coefftab32_full[yvcoef_offset
1180 								  + i]);
1181 			break;
1182 		}
1183 	default:
1184 		format = VSU_FORMAT_RGB;
1185 		incw = in_w;
1186 		inch = in_h;
1187 		write_wvalue(VS_C_SIZE, ((inch - 1) << 16) | (incw - 1));
1188 
1189 		    /* chstep = yhstep cvstep = yvstep */
1190 		    write_wvalue(VS_C_HSTEP, yhstep << 1);
1191 		write_wvalue(VS_C_VSTEP, yvstep << 1);
1192 		chcoef_offset = g2d_vsu_calc_fir_coef(yhstep);
1193 		for (i = 0; i < VSU_PHASE_NUM; i++)
1194 			write_wvalue(VS_C_HCOEF0 + (i << 2),
1195 				      lan2coefftab32_full[chcoef_offset + i]);
1196 		for (i = 0; i < VSU_PHASE_NUM; i++)
1197 			write_wvalue(VS_Y_VCOEF0 + (i << 2),
1198 				      linearcoefftab32[i]);
1199 		break;
1200 	}
1201 	if (format == VSU_FORMAT_YUV420) {
1202 
1203 		/**
1204 		 * yhphase = 0;
1205 		 * yvphase = 0;
1206 		 * chphase = 0xFFFE0000;
1207 		 * cvphase = 0xFFFE0000;
1208 		 */
1209 		write_wvalue(VS_Y_HPHASE, 0);
1210 		write_wvalue(VS_Y_VPHASE0, 0);
1211 		write_wvalue(VS_C_HPHASE, 0xFFFc0000);
1212 		write_wvalue(VS_C_VPHASE0, 0xFFFc0000);
1213 	}
1214 
1215 	else {
1216 		write_wvalue(VS_Y_HPHASE, 0);
1217 		write_wvalue(VS_Y_VPHASE0, 0);
1218 		write_wvalue(VS_C_HPHASE, 0);
1219 		write_wvalue(VS_C_VPHASE0, 0);
1220 	}
1221 	if (fmt >= G2D_FORMAT_IYUV422_Y1U0Y0V0)
1222 		write_wvalue(VS_CTRL, 0x10001);
1223 
1224 	else
1225 		write_wvalue(VS_CTRL, 0x00001);
1226 	return 0;
1227 }
1228 
1229 
g2d_calc_coarse(__u32 format,__u32 inw,__u32 inh,__u32 outw,__u32 outh,__u32 * midw,__u32 * midh)1230 __s32 g2d_calc_coarse(__u32 format, __u32 inw, __u32 inh, __u32 outw,
1231 			  __u32 outh, __u32 *midw, __u32 *midh)
1232 {
1233 	__u32 tmp;
1234 
1235 	switch (format) {
1236 	case G2D_FORMAT_IYUV422_V0Y1U0Y0:
1237 	case G2D_FORMAT_IYUV422_Y1V0Y0U0:
1238 	case G2D_FORMAT_IYUV422_U0Y1V0Y0:
1239 	case G2D_FORMAT_IYUV422_Y1U0Y0V0:{
1240 		/* interleaved YUV422 format */
1241 		*midw = inw;
1242 		*midh = inh;
1243 		break;
1244 	}
1245 	case G2D_FORMAT_YUV422UVC_V1U1V0U0:
1246 	case G2D_FORMAT_YUV422UVC_U1V1U0V0:
1247 	case G2D_FORMAT_YUV422_PLANAR:{
1248 		if (inw >= (outw << 3)) {
1249 			*midw = outw << 3;
1250 			tmp = (*midw << 16) | inw;
1251 			write_wvalue(V0_HDS_CTL0, tmp);
1252 			tmp = (*midw << 15) | ((inw + 1) >> 1);
1253 			write_wvalue(V0_HDS_CTL1, tmp);
1254 		} else
1255 			*midw = inw;
1256 		if (inh >= (outh << 2)) {
1257 			*midh = (outh << 2);
1258 			tmp = (*midh << 16) | inh;
1259 			write_wvalue(V0_VDS_CTL0, tmp);
1260 			write_wvalue(V0_VDS_CTL1, tmp);
1261 		} else
1262 			*midh = inh;
1263 		break;
1264 	}
1265 	case G2D_FORMAT_YUV420_PLANAR:
1266 	case G2D_FORMAT_YUV420UVC_V1U1V0U0:
1267 	case G2D_FORMAT_YUV420UVC_U1V1U0V0:{
1268 		if (inw >= (outw << 3)) {
1269 			*midw = outw << 3;
1270 			tmp = (*midw << 16) | inw;
1271 			write_wvalue(V0_HDS_CTL0, tmp);
1272 			tmp = (*midw << 15) | ((inw + 1) >> 1);
1273 			write_wvalue(V0_HDS_CTL0, tmp);
1274 		} else
1275 			*midw = inw;
1276 		if (inh >= (outh << 2)) {
1277 			*midh = (outh << 2);
1278 			tmp = (*midh << 16) | inh;
1279 			write_wvalue(V0_VDS_CTL0, tmp);
1280 			tmp = (*midh << 15) | ((inh + 1) >> 1);
1281 			write_wvalue(V0_VDS_CTL1, tmp);
1282 		} else
1283 			*midh = inh;
1284 		break;
1285 	}
1286 	case G2D_FORMAT_YUV411_PLANAR:
1287 	case G2D_FORMAT_YUV411UVC_V1U1V0U0:
1288 	case G2D_FORMAT_YUV411UVC_U1V1U0V0:{
1289 		if (inw >= (outw << 3)) {
1290 			*midw = outw << 3;
1291 			tmp = ((*midw) << 16) | inw;
1292 			write_wvalue(V0_HDS_CTL0, tmp);
1293 			tmp = ((*midw) << 14) | ((inw + 3) >> 2);
1294 			write_wvalue(V0_HDS_CTL1, tmp);
1295 		} else
1296 			*midw = inw;
1297 		if (inh >= (outh << 2)) {
1298 			*midh = (outh << 2);
1299 			tmp = ((*midh) << 16) | inh;
1300 			write_wvalue(V0_VDS_CTL0, tmp);
1301 			write_wvalue(V0_VDS_CTL1, tmp);
1302 		} else
1303 			*midh = inh;
1304 		break;
1305 	}
1306 	default:
1307 		if (inw >= (outw << 3)) {
1308 			*midw = outw << 3;
1309 			tmp = ((*midw) << 16) | inw;
1310 			write_wvalue(V0_HDS_CTL0, tmp);
1311 			write_wvalue(V0_HDS_CTL1, tmp);
1312 		} else
1313 			*midw = inw;
1314 		if (inh >= (outh << 2)) {
1315 			*midh = (outh << 2);
1316 			tmp = ((*midh) << 16) | inh;
1317 			write_wvalue(V0_VDS_CTL0, tmp);
1318 			write_wvalue(V0_VDS_CTL1, tmp);
1319 		} else
1320 			*midh = inh;
1321 		break;
1322 	}
1323 	return 0;
1324 }
1325 
1326 
1327 /*
1328  * sel: 0-->pipe0 1-->pipe1 other:error
1329  */
g2d_bldin_set(__u32 sel,g2d_rect rect,int premul)1330 __s32 g2d_bldin_set(__u32 sel, g2d_rect rect, int premul)
1331 {
1332 	__u32 tmp;
1333 	__u32 offset;
1334 
1335 	if (sel == 0) {
1336 		offset = 0;
1337 		tmp = read_wvalue(BLD_EN_CTL);
1338 		tmp |= 0x1 << 8;
1339 		write_wvalue(BLD_EN_CTL, tmp);
1340 		if (premul) {
1341 			tmp = read_wvalue(BLD_PREMUL_CTL);
1342 			tmp |= 0x1;
1343 			write_wvalue(BLD_PREMUL_CTL, tmp);
1344 		}
1345 	} else if (sel == 1) {
1346 		offset = 0x4;
1347 		tmp = read_wvalue(BLD_EN_CTL);
1348 		tmp |= 0x1 << 9;
1349 		write_wvalue(BLD_EN_CTL, tmp);
1350 		if (premul) {
1351 			tmp = read_wvalue(BLD_PREMUL_CTL);
1352 			tmp |= 0x1 << 1;
1353 			write_wvalue(BLD_PREMUL_CTL, tmp);
1354 		}
1355 	} else
1356 		return -1;
1357 	tmp = ((rect.h - 1) << 16) | (rect.w - 1);
1358 
1359 	G2D_INFO_MSG("BLD_CH_ISIZE W:  0x%x\n", rect.w);
1360 	G2D_INFO_MSG("BLD_CH_ISIZE H:  0x%x\n", rect.h);
1361 
1362 	write_wvalue(BLD_CH_ISIZE0 + offset, tmp);
1363 	tmp =
1364 	    ((rect.y <= 0 ? 0 : rect.y - 1) << 16) | (rect.x <=
1365 						      0 ? 0 : rect.x - 1);
1366 
1367 	G2D_INFO_MSG("BLD_CH_ISIZE X:  0x%x\n", rect.x);
1368 	G2D_INFO_MSG("BLD_CH_ISIZE Y:  0x%x\n", rect.y);
1369 
1370 	write_wvalue(BLD_CH_OFFSET0 + offset, tmp);
1371 	return 0;
1372 }
1373 
1374 /**
1375  * set the bld color space based on the format
1376  * if the format is UI, then set the bld in RGB color space
1377  * if the format is Video, then set the bld in YUV color space
1378  */
g2d_bld_cs_set(__u32 format)1379 __s32 g2d_bld_cs_set(__u32 format)
1380 {
1381 	__u32 tmp;
1382 
1383 	if (format <= G2D_FORMAT_BGRA1010102) {
1384 		tmp = read_wvalue(BLD_OUT_COLOR);
1385 		tmp &= 0xFFFFFFFD;
1386 		write_wvalue(BLD_OUT_COLOR, tmp);
1387 	} else if (format <= G2D_FORMAT_YUV411_PLANAR) {
1388 		tmp = read_wvalue(BLD_OUT_COLOR);
1389 		tmp |= 0x1 << 1;
1390 		write_wvalue(BLD_OUT_COLOR, tmp);
1391 	} else
1392 		return -1;
1393 	return 0;
1394 }
1395 
mixer_fillrectangle(g2d_fillrect * para)1396 __s32 mixer_fillrectangle(g2d_fillrect *para)
1397 {
1398 	g2d_image_enh src_tmp, dst_tmp;
1399 	g2d_image_enh *src = &src_tmp;
1400 	g2d_image_enh *dst = &dst_tmp;
1401 	__s32 result;
1402 
1403 	g2d_mixer_reset();
1404 	if (para->flag == G2D_FIL_NONE) {
1405 		pr_info("fc only!\n");
1406 		dst->bbuff = 1;
1407 		dst->color = para->color;
1408 		dst->format =
1409 			g2d_format_trans(para->dst_image.format,
1410 					para->dst_image.pixel_seq);
1411 		dst->laddr[0] = para->dst_image.addr[0];
1412 		dst->laddr[1] = para->dst_image.addr[1];
1413 		dst->laddr[2] = para->dst_image.addr[2];
1414 		dst->width = para->dst_image.w;
1415 		dst->height = para->dst_image.h;
1416 		dst->clip_rect.x = para->dst_rect.x;
1417 		dst->clip_rect.y = para->dst_rect.y;
1418 		dst->clip_rect.w = para->dst_rect.w;
1419 		dst->clip_rect.h = para->dst_rect.h;
1420 		dst->gamut = G2D_BT709;
1421 		dst->alpha = para->alpha;
1422 		dst->mode = 0;
1423 		result = g2d_fillrectangle(dst, dst->color);
1424 		return result;
1425 	}
1426 	dst->bbuff = 1;
1427 	dst->color = para->color;
1428 	dst->format =
1429 		g2d_format_trans(para->dst_image.format,
1430 				para->dst_image.pixel_seq);
1431 	dst->laddr[0] = para->dst_image.addr[0];
1432 	dst->laddr[1] = para->dst_image.addr[1];
1433 	dst->laddr[2] = para->dst_image.addr[2];
1434 	dst->width = para->dst_image.w;
1435 	dst->height = para->dst_image.h;
1436 	dst->clip_rect.x = para->dst_rect.x;
1437 	dst->clip_rect.y = para->dst_rect.y;
1438 	dst->clip_rect.w = para->dst_rect.w;
1439 	dst->clip_rect.h = para->dst_rect.h;
1440 	dst->gamut = G2D_BT709;
1441 	dst->alpha = para->alpha;
1442 	if (para->flag & G2D_FIL_PIXEL_ALPHA)
1443 		dst->mode = G2D_PIXEL_ALPHA;
1444 	if (para->flag & G2D_FIL_PLANE_ALPHA)
1445 		dst->mode = G2D_GLOBAL_ALPHA;
1446 	if (para->flag & G2D_FIL_MULTI_ALPHA)
1447 		dst->mode = G2D_MIXER_ALPHA;
1448 	src->bbuff = 0;
1449 	src->color = para->color;
1450 	src->format = dst->format;
1451 	src->gamut = G2D_BT709;
1452 	src->format = 0;
1453 	dst->laddr[0] = para->dst_image.addr[0];
1454 	src->width = para->dst_image.w;
1455 	src->height = para->dst_image.h;
1456 	src->clip_rect.x = para->dst_rect.x;
1457 	src->clip_rect.y = para->dst_rect.y;
1458 	src->clip_rect.w = para->dst_rect.w;
1459 	src->clip_rect.h = para->dst_rect.h;
1460 	result = g2d_bsp_bld(src, dst, G2D_BLD_DSTOVER, NULL);
1461 	return result;
1462 }
1463 
g2d_fillrectangle(g2d_image_enh * dst,__u32 color_value)1464 __s32 g2d_fillrectangle(g2d_image_enh *dst, __u32 color_value)
1465 {
1466 	g2d_rect rect0;
1467 	__u32 tmp;
1468 	__s32 result;
1469 
1470 	g2d_bsp_reset();
1471 	/* set the input layer */
1472 	g2d_vlayer_set(0, dst);
1473 	/* set the fill color value */
1474 	g2d_fc_set(0, color_value);
1475 	if (dst->format >= G2D_FORMAT_IYUV422_V0Y1U0Y0) {
1476 		g2d_vsu_para_set(dst->format, dst->clip_rect.w,
1477 				  dst->clip_rect.h, dst->clip_rect.w,
1478 				  dst->clip_rect.h, 0xff);
1479 		g2d_csc_reg_set(1, G2D_RGB2YUV_709);
1480 	}
1481 
1482 	/* for interleaved test */
1483 	if ((dst->format >= G2D_FORMAT_IYUV422_V0Y1U0Y0)
1484 			&& (dst->format <= G2D_FORMAT_IYUV422_Y1U0Y0V0)) {
1485 		g2d_csc_reg_set(0, G2D_RGB2YUV_709);
1486 		g2d_csc_reg_set(2, G2D_RGB2YUV_709);
1487 		write_wvalue(BLD_CSC_CTL, 0x2);
1488 		g2d_bk_set(0xff123456);
1489 		porter_duff(G2D_BLD_SRCOVER);
1490 		write_wvalue(BLD_FILLC0, 0x00108080);
1491 		write_wvalue(BLD_FILLC1, 0x00108080);
1492 		write_wvalue(UI0_FILLC, 0xffffffff);
1493 		write_wvalue(UI1_FILLC, 0xffffffff);
1494 	}
1495 	rect0.x = 0;
1496 	rect0.y = 0;
1497 	rect0.w = dst->clip_rect.w;
1498 	rect0.h = dst->clip_rect.h;
1499 	g2d_bldin_set(0, rect0, dst->bpremul);
1500 	g2d_bld_cs_set(dst->format);
1501 
1502 	/* ROP sel ch0 pass */
1503 	write_wvalue(ROP_CTL, 0xf0);
1504 	g2d_wb_set(dst);
1505 
1506 	/* start the module */
1507 	mixer_irq_enable();
1508 	tmp = read_wvalue(G2D_MIXER_CTL);
1509 	tmp |= 0x80000000;
1510 	G2D_INFO_MSG("INIT_MODULE: 0x%x\n", tmp);
1511 	write_wvalue(G2D_MIXER_CTL, tmp);
1512 
1513 	result = g2d_wait_cmd_finish();
1514 	return result;
1515 }
1516 
1517 
1518 /**
1519  * src:source
1520  * ptn:pattern
1521  * dst:destination
1522  * mask:mask
1523  * if mask is set to NULL, do ROP3 among src, ptn, and dst using the
1524  * fore_flag
1525  */
g2d_bsp_maskblt(g2d_image_enh * src,g2d_image_enh * ptn,g2d_image_enh * mask,g2d_image_enh * dst,__u32 back_flag,__u32 fore_flag)1526 __s32 g2d_bsp_maskblt(g2d_image_enh *src, g2d_image_enh *ptn,
1527 			  g2d_image_enh *mask, g2d_image_enh *dst,
1528 			  __u32 back_flag, __u32 fore_flag)
1529 {
1530 	__u32 tmp;
1531 	g2d_rect rect0;
1532 	bool b_pre;
1533 	__s32 result;
1534 
1535 	/* int b_pre; */
1536 	g2d_bsp_reset();
1537 	if (dst == NULL)
1538 		return -1;
1539 	if (dst->format > G2D_FORMAT_BGRA1010102)
1540 		return -2;
1541 	g2d_vlayer_set(0, dst);
1542 	if (src != NULL) {
1543 		src->clip_rect.w = dst->clip_rect.w;
1544 		src->clip_rect.h = dst->clip_rect.h;
1545 		g2d_uilayer_set(0, src);
1546 	}
1547 	if (ptn != NULL) {
1548 		ptn->clip_rect.w = dst->clip_rect.w;
1549 		ptn->clip_rect.h = dst->clip_rect.h;
1550 		g2d_uilayer_set(1, ptn);
1551 	}
1552 	if (mask != NULL) {
1553 		mask->clip_rect.w = dst->clip_rect.w;
1554 		mask->clip_rect.h = dst->clip_rect.h;
1555 		g2d_uilayer_set(2, mask);
1556 
1557 		/* set the ROP4 */
1558 		write_wvalue(ROP_CTL, 0x1);
1559 		g2d_rop3_set(0, back_flag & 0xff);
1560 		g2d_rop3_set(1, fore_flag & 0xff);
1561 	} else {
1562 		write_wvalue(ROP_CTL, 0x0);
1563 		g2d_rop3_set(0, back_flag);
1564 	}
1565 	b_pre = dst->bpremul;
1566 	if (src)
1567 		b_pre |= src->bpremul;
1568 	if (ptn)
1569 		b_pre |= ptn->bpremul;
1570 	if (b_pre) {
1571 		/* some layer is not premul */
1572 		if (!src->bpremul) {
1573 			tmp = read_wvalue(UI0_ATTR);
1574 			tmp |= 0x1 << 16;
1575 			write_wvalue(UI0_ATTR, tmp);
1576 		}
1577 		if (!dst->bpremul) {
1578 			tmp = read_wvalue(V0_ATTCTL);
1579 			tmp |= 0x1 << 16;
1580 			write_wvalue(V0_ATTCTL, tmp);
1581 		}
1582 		if (!ptn->bpremul) {
1583 			tmp = read_wvalue(UI1_ATTR);
1584 			tmp |= 0x1 << 16;
1585 			write_wvalue(UI1_ATTR, tmp);
1586 		}
1587 
1588 		    /* set bld in premul data */
1589 		    write_wvalue(BLD_PREMUL_CTL, 0x1);
1590 	}
1591 
1592 	/*set bld para */
1593 	rect0.x = 0;
1594 	rect0.y = 0;
1595 	rect0.w = dst->clip_rect.w;
1596 	rect0.h = dst->clip_rect.h;
1597 	g2d_bldin_set(0, rect0, dst->bpremul);
1598 	g2d_wb_set(dst);
1599 
1600 	/* start the module */
1601 	mixer_irq_enable();
1602 	tmp = read_wvalue(G2D_MIXER_CTL);
1603 	tmp |= 0x80000000;
1604 	G2D_INFO_MSG("INIT_MODULE: 0x%x\n", tmp);
1605 	write_wvalue(G2D_MIXER_CTL, tmp);
1606 
1607 	result = g2d_wait_cmd_finish();
1608 	return result;
1609 }
1610 
g2d_format_trans(__s32 data_fmt,__s32 pixel_seq)1611 __s32 g2d_format_trans(__s32 data_fmt, __s32 pixel_seq)
1612 {
1613 	/* transform the g2d format 2 enhance format */
1614 	switch (data_fmt) {
1615 	case G2D_FMT_ARGB_AYUV8888:
1616 		return G2D_FORMAT_ARGB8888;
1617 	case G2D_FMT_BGRA_VUYA8888:
1618 		return G2D_FORMAT_BGRA8888;
1619 	case G2D_FMT_ABGR_AVUY8888:
1620 		return G2D_FORMAT_ABGR8888;
1621 	case G2D_FMT_RGBA_YUVA8888:
1622 		return G2D_FORMAT_RGBA8888;
1623 	case G2D_FMT_XRGB8888:
1624 		return G2D_FORMAT_XRGB8888;
1625 	case G2D_FMT_BGRX8888:
1626 		return G2D_FORMAT_BGRX8888;
1627 	case G2D_FMT_XBGR8888:
1628 		return G2D_FORMAT_XBGR8888;
1629 	case G2D_FMT_RGBX8888:
1630 		return G2D_FORMAT_RGBX8888;
1631 	case G2D_FMT_ARGB4444:
1632 		return G2D_FORMAT_ARGB4444;
1633 	case G2D_FMT_ABGR4444:
1634 		return G2D_FORMAT_ABGR4444;
1635 	case G2D_FMT_RGBA4444:
1636 		return G2D_FORMAT_RGBA4444;
1637 	case G2D_FMT_BGRA4444:
1638 		return G2D_FORMAT_BGRA4444;
1639 	case G2D_FMT_ARGB1555:
1640 		return G2D_FORMAT_ARGB1555;
1641 	case G2D_FMT_ABGR1555:
1642 		return G2D_FORMAT_ABGR1555;
1643 	case G2D_FMT_RGBA5551:
1644 		return G2D_FORMAT_RGBA5551;
1645 	case G2D_FMT_BGRA5551:
1646 		return G2D_FORMAT_BGRA5551;
1647 	case G2D_FMT_RGB565:
1648 		return G2D_FORMAT_RGB565;
1649 	case G2D_FMT_BGR565:
1650 		return G2D_FORMAT_BGR565;
1651 	case G2D_FMT_IYUV422:
1652 		if (pixel_seq == G2D_SEQ_VYUY)
1653 			return G2D_FORMAT_IYUV422_V0Y1U0Y0;
1654 		if (pixel_seq == G2D_SEQ_YVYU)
1655 			return G2D_FORMAT_IYUV422_Y1V0Y0U0;
1656 		return -1;
1657 	case G2D_FMT_PYUV422UVC:
1658 		if (pixel_seq == G2D_SEQ_VUVU)
1659 			return G2D_FORMAT_YUV422UVC_V1U1V0U0;
1660 		return G2D_FORMAT_YUV422UVC_U1V1U0V0;
1661 	case G2D_FMT_PYUV420UVC:
1662 		if (pixel_seq == G2D_SEQ_VUVU)
1663 			return G2D_FORMAT_YUV420UVC_V1U1V0U0;
1664 		return G2D_FORMAT_YUV420UVC_U1V1U0V0;
1665 	case G2D_FMT_PYUV411UVC:
1666 		if (pixel_seq == G2D_SEQ_VUVU)
1667 			return G2D_FORMAT_YUV411UVC_V1U1V0U0;
1668 		return G2D_FORMAT_YUV411UVC_U1V1U0V0;
1669 	case G2D_FMT_PYUV422:
1670 		return G2D_FORMAT_YUV422_PLANAR;
1671 	case G2D_FMT_PYUV420:
1672 		return G2D_FORMAT_YUV420_PLANAR;
1673 	case G2D_FMT_PYUV411:
1674 		return G2D_FORMAT_YUV411_PLANAR;
1675 	default:
1676 		return -1;
1677 	}
1678 }
1679 
mixer_stretchblt(g2d_stretchblt * para,enum g2d_scan_order scan_order)1680 __s32 mixer_stretchblt(g2d_stretchblt *para,
1681 			   enum g2d_scan_order scan_order)
1682 {
1683 	g2d_image_enh src_tmp, dst_tmp;
1684 	g2d_image_enh *src = &src_tmp, *dst = &dst_tmp;
1685 	g2d_ck ck_para_tmp;
1686 	g2d_ck *ck_para = &ck_para_tmp;
1687 	__s32 result;
1688 
1689 	memset(src, 0, sizeof(g2d_image_enh));
1690 	memset(dst, 0, sizeof(g2d_image_enh));
1691 	memset(ck_para, 0, sizeof(g2d_ck));
1692 
1693 	src->bbuff = 1;
1694 	src->color = para->color;
1695 	src->format =
1696 		g2d_format_trans(para->src_image.format,
1697 				para->src_image.pixel_seq);
1698 	src->laddr[0] = para->src_image.addr[0];
1699 	src->laddr[1] = para->src_image.addr[1];
1700 	src->laddr[2] = para->src_image.addr[2];
1701 	src->width = para->src_image.w;
1702 	src->height = para->src_image.h;
1703 	src->clip_rect.x = para->src_rect.x;
1704 	src->clip_rect.y = para->src_rect.y;
1705 	src->clip_rect.w = para->src_rect.w;
1706 	src->clip_rect.h = para->src_rect.h;
1707 	src->gamut = G2D_BT709;
1708 	src->alpha = para->alpha;
1709 	dst->bbuff = 1;
1710 	dst->color = para->color;
1711 	dst->format =
1712 		g2d_format_trans(para->dst_image.format,
1713 				para->dst_image.pixel_seq);
1714 	dst->laddr[0] = para->dst_image.addr[0];
1715 	dst->laddr[1] = para->dst_image.addr[1];
1716 	dst->laddr[2] = para->dst_image.addr[2];
1717 	dst->width = para->dst_image.w;
1718 	dst->height = para->dst_image.h;
1719 	dst->clip_rect.x = para->dst_rect.x;
1720 	dst->clip_rect.y = para->dst_rect.y;
1721 	dst->clip_rect.w = para->dst_rect.w;
1722 	dst->clip_rect.h = para->dst_rect.h;
1723 	dst->gamut = G2D_BT709;
1724 	dst->alpha = para->alpha;
1725 
1726 	if ((para->flag == G2D_BLT_NONE) ||
1727 	      (para->flag == G2D_BLT_FLIP_HORIZONTAL) ||
1728 	      (para->flag == G2D_BLT_FLIP_VERTICAL) ||
1729 	      (para->flag == G2D_BLT_ROTATE90) ||
1730 	      (para->flag == G2D_BLT_ROTATE180) ||
1731 	      (para->flag == G2D_BLT_ROTATE270) ||
1732 	      (para->flag == G2D_BLT_MIRROR45) ||
1733 	      (para->flag == G2D_BLT_MIRROR135)) {
1734 		/* ROT or scal case */
1735 		switch (para->flag) {
1736 		case G2D_BLT_NONE:
1737 			if ((dst->width == src->width) &&
1738 					(dst->height == src->height)) {
1739 				result = g2d_bsp_bitblt(src, dst, G2D_ROT_0);
1740 				return result;
1741 			}
1742 			if (scan_order == G2D_SM_DTLR)
1743 				result = g2d_bsp_bitblt(src, dst,
1744 						G2D_BLT_NONE | G2D_SM_DTLR_1);
1745 			else
1746 				result = g2d_bsp_bitblt(src, dst, G2D_BLT_NONE);
1747 			return result;
1748 		case G2D_BLT_FLIP_HORIZONTAL:
1749 			result = g2d_bsp_bitblt(src, dst, G2D_ROT_H);
1750 			return result;
1751 		case G2D_BLT_FLIP_VERTICAL:
1752 			result = g2d_bsp_bitblt(src, dst, G2D_ROT_V);
1753 			return result;
1754 		case G2D_BLT_ROTATE90:
1755 			result = g2d_bsp_bitblt(src, dst, G2D_ROT_90);
1756 			return result;
1757 		case G2D_BLT_ROTATE180:
1758 			result = g2d_bsp_bitblt(src, dst, G2D_ROT_180);
1759 			return result;
1760 		case G2D_BLT_ROTATE270:
1761 			result = g2d_bsp_bitblt(src, dst, G2D_ROT_270);
1762 			return result;
1763 		case G2D_BLT_MIRROR45:
1764 			result = g2d_bsp_bitblt(src, dst,
1765 						G2D_ROT_90 | G2D_ROT_H);
1766 			return result;
1767 		case G2D_BLT_MIRROR135:
1768 			result = g2d_bsp_bitblt(src, dst,
1769 						G2D_ROT_90 | G2D_ROT_V);
1770 			return result;
1771 		default:
1772 			return -1;
1773 		}
1774 	} else {
1775 		if (para->flag & 0xfe0) {
1776 			pr_err("Wrong! mixer and rot cant use at same time!\n");
1777 			return -1;
1778 		}
1779 		if (para->flag & G2D_BLT_SRC_PREMULTIPLY)
1780 			src->bpremul = 1;
1781 		if (para->flag & G2D_BLT_DST_PREMULTIPLY)
1782 			dst->bpremul = 1;
1783 		if (para->flag & G2D_BLT_PIXEL_ALPHA) {
1784 			src->mode = G2D_PIXEL_ALPHA;
1785 			dst->mode = G2D_PIXEL_ALPHA;
1786 		}
1787 		if (para->flag & G2D_BLT_PLANE_ALPHA) {
1788 			src->mode = G2D_GLOBAL_ALPHA;
1789 			dst->mode = G2D_GLOBAL_ALPHA;
1790 		}
1791 		if (para->flag & G2D_BLT_MULTI_ALPHA) {
1792 			src->mode = G2D_MIXER_ALPHA;
1793 			dst->mode = G2D_MIXER_ALPHA;
1794 		}
1795 		ck_para->match_rule = 0;
1796 		ck_para->max_color = para->color;
1797 		ck_para->min_color = para->color;
1798 
1799 		result = g2d_bsp_bitblt(src, dst, G2D_BLT_NONE);
1800 
1801 		return result;
1802 	}
1803 }
1804 
mixer_blt(g2d_blt * para,enum g2d_scan_order scan_order)1805 __s32 mixer_blt(g2d_blt *para, enum g2d_scan_order scan_order)
1806 {
1807 	g2d_image_enh src_tmp, dst_tmp;
1808 	g2d_image_enh *src = &src_tmp;
1809 	g2d_image_enh *dst = &dst_tmp;
1810 	g2d_ck ck_para_tmp;
1811 	g2d_ck *ck_para = &ck_para_tmp;
1812 	__s32 result;
1813 
1814 	memset(src, 0, sizeof(g2d_image_enh));
1815 	memset(dst, 0, sizeof(g2d_image_enh));
1816 	memset(ck_para, 0, sizeof(g2d_ck));
1817 
1818 	G2D_INFO_MSG("Input_G2D_Format:  0x%x\n", para->src_image.format);
1819 	G2D_INFO_MSG("BITBLT_flag:  0x%x\n", para->flag);
1820 	G2D_INFO_MSG("inPICWidth:  %d\n", para->src_image.w);
1821 	G2D_INFO_MSG("inPICHeight: %d\n", para->src_image.h);
1822 	G2D_INFO_MSG("inRectX:  %d\n", para->src_rect.x);
1823 	G2D_INFO_MSG("inRectY: %d\n", para->src_rect.y);
1824 	G2D_INFO_MSG("inRectW:  %d\n", para->src_rect.w);
1825 	G2D_INFO_MSG("inRectH: %d\n", para->src_rect.h);
1826 	G2D_INFO_MSG("Output_G2D_Format:  0x%x\n", para->dst_image.format);
1827 	G2D_INFO_MSG("outPICWidth:  %d\n", para->dst_image.w);
1828 	G2D_INFO_MSG("outPICHeight: %d\n", para->dst_image.h);
1829 	G2D_INFO_MSG("outRectX:  %d\n", para->dst_x);
1830 	G2D_INFO_MSG("outRectY: %d\n", para->dst_y);
1831 	src->bbuff = 1;
1832 	src->color = para->color;
1833 	src->format =
1834 			g2d_format_trans(para->src_image.format,
1835 					para->src_image.pixel_seq);
1836 	src->laddr[0] = para->src_image.addr[0];
1837 	src->laddr[1] = para->src_image.addr[1];
1838 	src->laddr[2] = para->src_image.addr[2];
1839 	src->width = para->src_image.w;
1840 	src->height = para->src_image.h;
1841 	src->clip_rect.x = para->src_rect.x;
1842 	src->clip_rect.y = para->src_rect.y;
1843 	src->clip_rect.w = para->src_rect.w;
1844 	src->clip_rect.h = para->src_rect.h;
1845 	src->gamut = G2D_BT709;
1846 	src->alpha = para->alpha;
1847 	dst->bbuff = 1;
1848 	dst->format =
1849 		g2d_format_trans(para->dst_image.format,
1850 						para->dst_image.pixel_seq);
1851 	dst->laddr[0] = para->dst_image.addr[0];
1852 	dst->laddr[1] = para->dst_image.addr[1];
1853 	dst->laddr[2] = para->dst_image.addr[2];
1854 	dst->width = para->dst_image.w;
1855 	dst->height = para->dst_image.h;
1856 	dst->clip_rect.x = para->dst_x;
1857 	dst->clip_rect.y = para->dst_y;
1858 	dst->clip_rect.w = src->clip_rect.w;
1859 	dst->clip_rect.h = src->clip_rect.h;
1860 	dst->gamut = G2D_BT709;
1861 	dst->alpha = para->alpha;
1862 
1863 	G2D_INFO_MSG("inPICaddr0: 0x%x\n", src->laddr[0]);
1864 	G2D_INFO_MSG("inPICaddr1: 0x%x\n", src->laddr[1]);
1865 	G2D_INFO_MSG("inPICaddr2: 0x%x\n", src->laddr[2]);
1866 	G2D_INFO_MSG("outPICaddr0: 0x%x\n", dst->laddr[0]);
1867 	G2D_INFO_MSG("outPICaddr1: 0x%x\n", dst->laddr[1]);
1868 	G2D_INFO_MSG("outPICaddr2: 0x%x\n", dst->laddr[2]);
1869 
1870 	if ((para->flag == G2D_BLT_NONE) ||
1871 	      (para->flag == G2D_BLT_FLIP_HORIZONTAL) ||
1872 	      (para->flag == G2D_BLT_FLIP_VERTICAL) ||
1873 	      (para->flag == G2D_BLT_ROTATE90) ||
1874 	      (para->flag == G2D_BLT_ROTATE180) ||
1875 	      (para->flag == G2D_BLT_ROTATE270) ||
1876 	      (para->flag == G2D_BLT_MIRROR45) ||
1877 	      (para->flag == G2D_BLT_MIRROR135)) {
1878 		/* ROT case */
1879 		switch (para->flag) {
1880 		case G2D_BLT_NONE:
1881 			if ((dst->width == src->width) &&
1882 					(dst->height == src->height)) {
1883 				result = g2d_bsp_bitblt(src, dst, G2D_ROT_0);
1884 				return result;
1885 			}
1886 			if (scan_order == G2D_SM_DTLR)
1887 				result = g2d_bsp_bitblt(src, dst,
1888 						G2D_BLT_NONE | G2D_SM_DTLR_1);
1889 			else
1890 				result = g2d_bsp_bitblt(src, dst, G2D_BLT_NONE);
1891 			return result;
1892 		case G2D_BLT_FLIP_HORIZONTAL:
1893 			result = g2d_bsp_bitblt(src, dst, G2D_ROT_H);
1894 			return result;
1895 		case G2D_BLT_FLIP_VERTICAL:
1896 			result = g2d_bsp_bitblt(src, dst, G2D_ROT_V);
1897 			return result;
1898 		case G2D_BLT_ROTATE90:
1899 			result = g2d_bsp_bitblt(src, dst, G2D_ROT_90);
1900 			return result;
1901 		case G2D_BLT_ROTATE180:
1902 			result = g2d_bsp_bitblt(src, dst, G2D_ROT_180);
1903 			return result;
1904 		case G2D_BLT_ROTATE270:
1905 			result = g2d_bsp_bitblt(src, dst, G2D_ROT_270);
1906 			return result;
1907 		case G2D_BLT_MIRROR45:
1908 			result = g2d_bsp_bitblt(src, dst,
1909 						G2D_ROT_90 | G2D_ROT_H);
1910 			return result;
1911 		case G2D_BLT_MIRROR135:
1912 			result = g2d_bsp_bitblt(src, dst,
1913 						G2D_ROT_90 | G2D_ROT_V);
1914 			return result;
1915 		default:
1916 			return -1;
1917 		}
1918 	} else {
1919 		if (para->flag & 0xfe0) {
1920 			pr_err("Wrong! mixer and rot cant use at same time!\n");
1921 			return -1;
1922 		}
1923 		if (para->flag & G2D_BLT_SRC_PREMULTIPLY)
1924 			src->bpremul = 1;
1925 		if (para->flag & G2D_BLT_DST_PREMULTIPLY)
1926 			dst->bpremul = 1;
1927 		if (para->flag & G2D_BLT_PIXEL_ALPHA) {
1928 			src->mode = G2D_PIXEL_ALPHA;
1929 			dst->mode = G2D_PIXEL_ALPHA;
1930 		}
1931 		if (para->flag & G2D_BLT_PLANE_ALPHA) {
1932 			src->mode = G2D_GLOBAL_ALPHA;
1933 			dst->mode = G2D_GLOBAL_ALPHA;
1934 		}
1935 		if (para->flag & G2D_BLT_MULTI_ALPHA) {
1936 			src->mode = G2D_MIXER_ALPHA;
1937 			dst->mode = G2D_MIXER_ALPHA;
1938 		}
1939 		ck_para->match_rule = 0;
1940 		ck_para->max_color = para->color;
1941 		ck_para->min_color = para->color;
1942 
1943 		result = g2d_bsp_bld(src, dst, G2D_BLD_DSTOVER, NULL);
1944 
1945 		return result;
1946 	}
1947 }
1948 
g2d_bsp_bitblt(g2d_image_enh * src,g2d_image_enh * dst,__u32 flag)1949 __s32 g2d_bsp_bitblt(g2d_image_enh *src, g2d_image_enh *dst, __u32 flag)
1950 {
1951 	g2d_rect rect0, rect1;
1952 	bool bpre;
1953 	__u32 ycnt, ucnt, vcnt;
1954 	__u32 pitch0, pitch1, pitch2;
1955 	__u64 addr0, addr1, addr2;
1956 	__u32 midw, midh;
1957 	__u32 tmp;
1958 	__u32 ch, cw, cy, cx;
1959 	__s32 result;
1960 
1961 	g2d_bsp_reset();
1962 	if (dst == NULL) {
1963 		pr_err("[G2D]dst image is NULL!\n");
1964 		return -1;
1965 	}
1966 	if (src == NULL) {
1967 		pr_err("[G2D]src image is NULL!\n");
1968 		return -2;
1969 	}
1970 	G2D_INFO_MSG("BITBLT_flag:  0x%x\n", flag);
1971 	if (G2D_BLT_NONE == (flag & 0x0fffffff)) {
1972 		G2D_INFO_MSG("Input info:---------------------------------\n");
1973 		G2D_INFO_MSG("Src_fd:  %d\n", src->fd);
1974 		G2D_INFO_MSG("Format:  0x%x\n", src->format);
1975 		G2D_INFO_MSG("BITBLT_alpha_mode:  0x%x\n", src->mode);
1976 		G2D_INFO_MSG("BITBLT_alpha_val:  0x%x\n", src->alpha);
1977 		G2D_INFO_MSG("inClipRectX:  %d\n", src->clip_rect.x);
1978 		G2D_INFO_MSG("inClipRectY: %d\n", src->clip_rect.y);
1979 		G2D_INFO_MSG("inClipRectW:  %d\n", src->clip_rect.w);
1980 		G2D_INFO_MSG("inClipRectH: %d\n", src->clip_rect.h);
1981 
1982 		G2D_INFO_MSG("Output info:--------------------------------\n");
1983 		G2D_INFO_MSG("Dst_fd:  %d\n", dst->fd);
1984 		G2D_INFO_MSG("Format:  0x%x\n", dst->format);
1985 		G2D_INFO_MSG("outClipRectX:  %d\n", dst->clip_rect.x);
1986 		G2D_INFO_MSG("outClipRectY: %d\n", dst->clip_rect.y);
1987 		G2D_INFO_MSG("outClipRectW:  %d\n", dst->clip_rect.w);
1988 		G2D_INFO_MSG("outClipRectH: %d\n", dst->clip_rect.h);
1989 		/*single src opt */
1990 		g2d_vlayer_set(0, src);
1991 		if (src->mode) {
1992 			/* need abp process */
1993 			g2d_uilayer_set(2, dst);
1994 		}
1995 		if ((src->format >= G2D_FORMAT_IYUV422_V0Y1U0Y0) ||
1996 				(src->clip_rect.w != dst->clip_rect.w) ||
1997 				(src->clip_rect.h != dst->clip_rect.h)) {
1998 			g2d_calc_coarse(src->format, src->clip_rect.w,
1999 					src->clip_rect.h, dst->clip_rect.w,
2000 					dst->clip_rect.h, &midw, &midh);
2001 			g2d_vsu_para_set(src->format, midw, midh,
2002 					dst->clip_rect.w, dst->clip_rect.h,
2003 					0xff);
2004 		}
2005 		write_wvalue(ROP_CTL, 0xf0);
2006 		/*set bld para */
2007 		rect0.x = 0;
2008 		rect0.y = 0;
2009 		rect0.w = dst->clip_rect.w;
2010 		rect0.h = dst->clip_rect.h;
2011 		g2d_bldin_set(0, rect0, dst->bpremul);
2012 		g2d_bld_cs_set(src->format);
2013 		if (src->mode) {
2014 			/* need abp process */
2015 			rect1.x = 0;
2016 			rect1.y = 0;
2017 			rect1.w = dst->clip_rect.w;
2018 			rect1.h = dst->clip_rect.h;
2019 			g2d_bldin_set(1, rect1, dst->bpremul);
2020 		}
2021 		if ((src->format <= G2D_FORMAT_BGRA1010102) &&
2022 		      (dst->format > G2D_FORMAT_BGRA1010102)) {
2023 			if (dst->clip_rect.w <= 1280 && dst->clip_rect.h <= 720)
2024 				g2d_csc_reg_set(2, G2D_RGB2YUV_601);
2025 			else
2026 				g2d_csc_reg_set(2, G2D_RGB2YUV_709);
2027 		}
2028 		if ((src->format > G2D_FORMAT_BGRA1010102) &&
2029 		      (dst->format <= G2D_FORMAT_BGRA1010102)) {
2030 			if (dst->clip_rect.w <= 1280 && dst->clip_rect.h <= 720)
2031 				g2d_csc_reg_set(2, G2D_YUV2RGB_601);
2032 			else
2033 				g2d_csc_reg_set(2, G2D_YUV2RGB_709);
2034 		}
2035 		g2d_wb_set(dst);
2036 	}
2037 
2038 	else if (flag & 0xff) {
2039 		/* ROP2 operate */
2040 		if ((src->format > G2D_FORMAT_BGRA1010102) | (dst->format >
2041 					G2D_FORMAT_BGRA1010102))
2042 			return -3;
2043 		g2d_uilayer_set(0, dst);
2044 		g2d_vlayer_set(0, src);
2045 
2046 		/* bpre = 0; */
2047 		bpre = false;
2048 		if (src->bpremul || dst->bpremul) {
2049 			bpre = true;
2050 			/* bpre = 1; */
2051 			/* some layer is premul */
2052 			if (!src->bpremul) {
2053 				tmp = read_wvalue(V0_ATTCTL);
2054 				tmp |= 0x1 << 16;
2055 				write_wvalue(V0_ATTCTL, tmp);
2056 			}
2057 			if (!dst->bpremul) {
2058 				tmp = read_wvalue(UI0_ATTR);
2059 				tmp |= 0x1 << 16;
2060 				write_wvalue(UI0_ATTR, tmp);
2061 			}
2062 		}
2063 		if ((src->clip_rect.w != dst->clip_rect.w)
2064 		      || (src->clip_rect.h != dst->clip_rect.h)) {
2065 			g2d_calc_coarse(src->format, src->clip_rect.w,
2066 					 src->clip_rect.h, dst->clip_rect.w,
2067 					 dst->clip_rect.h, &midw, &midh);
2068 			g2d_vsu_para_set(src->format, midw, midh,
2069 					   dst->clip_rect.w, dst->clip_rect.h,
2070 					   0xff);
2071 		}
2072 		write_wvalue(ROP_CTL, 0x0);
2073 		g2d_rop2_set(flag & 0xff);
2074 		tmp = read_wvalue(ROP_INDEX0);
2075 		tmp |= 0x2;
2076 		write_wvalue(ROP_INDEX0, tmp);
2077 
2078 		/*set bld para */
2079 		rect0.x = 0;
2080 		rect0.y = 0;
2081 		rect0.w = dst->clip_rect.w;
2082 		rect0.h = dst->clip_rect.h;
2083 		g2d_bldin_set(0, rect0, bpre);
2084 		g2d_wb_set(dst);
2085 	}
2086 
2087 	else if (flag & 0xff00) {
2088 		/* ROT operate */
2089 		tmp = 1;
2090 		if (flag & G2D_ROT_H)
2091 			tmp |= 0x1 << 7;
2092 		if (flag & G2D_ROT_V)
2093 			tmp |= 0x1 << 6;
2094 		if ((flag & 0xf00) == G2D_ROT_90)
2095 			tmp |= 0x1 << 4;
2096 		if ((flag & 0xf00) == G2D_ROT_180)
2097 			tmp |= 0x2 << 4;
2098 		if ((flag & 0xf00) == G2D_ROT_270)
2099 			tmp |= 0x3 << 4;
2100 		if ((flag & 0xf00) == G2D_ROT_0)
2101 			tmp |= 0x0 << 4;
2102 
2103 		G2D_INFO_MSG("ROT input info: ----------------------------\n");
2104 		G2D_INFO_MSG("Src_fd:  %d\n", src->fd);
2105 		G2D_INFO_MSG("Format:  0x%x\n", src->format);
2106 		G2D_INFO_MSG("Flag:  0x%x\n", flag);
2107 		G2D_INFO_MSG("inClipRectX:  %d\n", src->clip_rect.x);
2108 		G2D_INFO_MSG("inClipRectY: %d\n", src->clip_rect.y);
2109 		G2D_INFO_MSG("inClipRectW:  %d\n", src->clip_rect.w);
2110 		G2D_INFO_MSG("inClipRectH: %d\n", src->clip_rect.h);
2111 
2112 		write_wvalue(ROT_CTL, tmp);
2113 		write_wvalue(ROT_IFMT, src->format & 0x3F);
2114 		write_wvalue(ROT_ISIZE,
2115 			      ((((src->clip_rect.h -
2116 				  1) & 0x1fff) << 16)) | ((src->clip_rect.w -
2117 							    1) & 0x1fff));
2118 
2119 		G2D_INFO_MSG("ROT_IFMT: 0x%x\n", read_wvalue(ROT_IFMT));
2120 		G2D_INFO_MSG("ROT_ISIZE: 0x%x\n", read_wvalue(ROT_ISIZE));
2121 		G2D_INFO_MSG("SRC_align: %d, %d, %d\n",
2122 				src->align[0], src->align[1], src->align[2]);
2123 		G2D_INFO_MSG("DST_align: %d, %d, %d\n",
2124 				dst->align[0], dst->align[1], dst->align[2]);
2125 
2126 		if ((src->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0)
2127 			&& (src->format <= G2D_FORMAT_YUV422_PLANAR)) {
2128 			cw = src->width >> 1;
2129 			ch = src->height;
2130 			cx = src->clip_rect.x >> 1;
2131 			cy = src->clip_rect.y;
2132 		}
2133 
2134 		else if ((src->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0)
2135 			&& (src->format <= G2D_FORMAT_YUV420_PLANAR)) {
2136 			cw = src->width >> 1;
2137 			ch = src->height >> 1;
2138 			cx = src->clip_rect.x >> 1;
2139 			cy = src->clip_rect.y >> 1;
2140 		}
2141 
2142 		else if ((src->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0)
2143 			&& (src->format <= G2D_FORMAT_YUV411_PLANAR)) {
2144 			cw = src->width >> 2;
2145 			ch = src->height;
2146 			cx = src->clip_rect.x >> 2;
2147 			cy = src->clip_rect.y;
2148 		}
2149 
2150 		else {
2151 			cw = 0;
2152 			ch = 0;
2153 			cx = 0;
2154 			cy = 0;
2155 		}
2156 
2157 		g2d_byte_cal(src->format, &ycnt, &ucnt, &vcnt);
2158 		pitch0 = cal_align(ycnt * src->width, src->align[0]);
2159 		write_wvalue(ROT_IPITCH0, pitch0);
2160 		pitch1 = cal_align(ucnt * cw, src->align[1]);
2161 		write_wvalue(ROT_IPITCH1, pitch1);
2162 		pitch2 = cal_align(vcnt * cw, src->align[2]);
2163 		write_wvalue(ROT_IPITCH2, pitch2);
2164 
2165 		G2D_INFO_MSG("ROT_InPITCH: %d, %d, %d\n",
2166 				pitch0, pitch1, pitch2);
2167 		G2D_INFO_MSG("SRC_ADDR0: 0x%x\n", src->laddr[0]);
2168 		G2D_INFO_MSG("SRC_ADDR1: 0x%x\n", src->laddr[1]);
2169 		G2D_INFO_MSG("SRC_ADDR2: 0x%x\n", src->laddr[2]);
2170 
2171 		addr0 =
2172 		    src->laddr[0] + ((__u64) src->haddr[0] << 32) +
2173 		    pitch0 * src->clip_rect.y + ycnt * src->clip_rect.x;
2174 		write_wvalue(ROT_ILADD0, addr0 & 0xffffffff);
2175 		write_wvalue(ROT_IHADD0, (addr0 >> 32) & 0xff);
2176 		addr1 =
2177 		    src->laddr[1] + ((__u64) src->haddr[1] << 32) +
2178 		    pitch1 * cy + ucnt * cx;
2179 		write_wvalue(ROT_ILADD1, addr1 & 0xffffffff);
2180 		write_wvalue(ROT_IHADD1, (addr1 >> 32) & 0xff);
2181 		addr2 =
2182 		    src->laddr[2] + ((__u64) src->haddr[2] << 32) +
2183 		    pitch2 * cy + vcnt * cx;
2184 		write_wvalue(ROT_ILADD2, addr2 & 0xffffffff);
2185 		write_wvalue(ROT_IHADD2, (addr2 >> 32) & 0xff);
2186 
2187 		if (((flag & 0xf00) == G2D_ROT_90) | ((flag & 0xf00) ==
2188 							G2D_ROT_270)) {
2189 			dst->clip_rect.w = src->clip_rect.h;
2190 			dst->clip_rect.h = src->clip_rect.w;
2191 		}
2192 
2193 		else {
2194 			dst->clip_rect.w = src->clip_rect.w;
2195 			dst->clip_rect.h = src->clip_rect.h;
2196 		}
2197 		write_wvalue(ROT_OSIZE,
2198 			       ((((dst->clip_rect.h -
2199 				   1) & 0x1fff) << 16)) | ((dst->clip_rect.w -
2200 							     1) & 0x1fff));
2201 		/* YUV output fmt only support 420 */
2202 		if (src->format == G2D_FORMAT_YUV422UVC_V1U1V0U0)
2203 			dst->format = G2D_FORMAT_YUV420UVC_V1U1V0U0;
2204 		else if (src->format == G2D_FORMAT_YUV422UVC_U1V1U0V0)
2205 			dst->format = G2D_FORMAT_YUV420UVC_U1V1U0V0;
2206 		else if (src->format == G2D_FORMAT_YUV422_PLANAR)
2207 			dst->format = G2D_FORMAT_YUV420_PLANAR;
2208 		else
2209 			dst->format = src->format;
2210 
2211 		if ((dst->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0)
2212 			&& (dst->format <= G2D_FORMAT_YUV422_PLANAR)) {
2213 			cw = dst->width >> 1;
2214 			ch = dst->height;
2215 			cx = dst->clip_rect.x >> 1;
2216 			cy = dst->clip_rect.y;
2217 		}
2218 
2219 		else if ((dst->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0)
2220 			&& (dst->format <= G2D_FORMAT_YUV420_PLANAR)) {
2221 			cw = dst->width >> 1;
2222 			ch = dst->height >> 1;
2223 			cx = dst->clip_rect.x >> 1;
2224 			cy = dst->clip_rect.y >> 1;
2225 		}
2226 
2227 		else if ((dst->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0)
2228 			&& (dst->format <= G2D_FORMAT_YUV411_PLANAR)) {
2229 			cw = dst->width >> 2;
2230 			ch = dst->height;
2231 			cx = dst->clip_rect.x >> 2;
2232 			cy = dst->clip_rect.y;
2233 		}
2234 
2235 		else {
2236 			cw = 0;
2237 			ch = 0;
2238 			cx = 0;
2239 			cy = 0;
2240 		}
2241 
2242 		g2d_byte_cal(dst->format, &ycnt, &ucnt, &vcnt);
2243 		G2D_INFO_MSG("ROT output info: ----------------------------\n");
2244 		G2D_INFO_MSG("Dst_fd:  %d\n", dst->fd);
2245 		G2D_INFO_MSG("Format:  0x%x\n", dst->format);
2246 
2247 		pitch0 = cal_align(ycnt * dst->width, dst->align[0]);
2248 		write_wvalue(ROT_OPITCH0, pitch0);
2249 		pitch1 = cal_align(ucnt * cw, dst->align[1]);
2250 		write_wvalue(ROT_OPITCH1, pitch1);
2251 		pitch2 = cal_align(vcnt * cw, dst->align[2]);
2252 		write_wvalue(ROT_OPITCH2, pitch2);
2253 
2254 		G2D_INFO_MSG("ROT_OutPITCH: %d, %d, %d\n",
2255 				pitch0, pitch1, pitch2);
2256 		G2D_INFO_MSG("outClipRectX:  %d\n", dst->clip_rect.x);
2257 		G2D_INFO_MSG("outClipRectY: %d\n", dst->clip_rect.y);
2258 		G2D_INFO_MSG("outClipRectW:  %d\n", dst->clip_rect.w);
2259 		G2D_INFO_MSG("outClipRectH: %d\n", dst->clip_rect.h);
2260 		addr0 =
2261 		    dst->laddr[0] + ((__u64) dst->haddr[0] << 32) +
2262 		    pitch0 * dst->clip_rect.y + ycnt * dst->clip_rect.x;
2263 		write_wvalue(ROT_OLADD0, addr0 & 0xffffffff);
2264 		write_wvalue(ROT_OHADD0, (addr0 >> 32) & 0xff);
2265 		addr1 =
2266 		    dst->laddr[1] + ((__u64) dst->haddr[1] << 32) +
2267 		    pitch1 * cy + ucnt * cx;
2268 		write_wvalue(ROT_OLADD1, addr1 & 0xffffffff);
2269 		write_wvalue(ROT_OHADD1, (addr1 >> 32) & 0xff);
2270 		addr2 =
2271 		    dst->laddr[2] + ((__u64) dst->haddr[2] << 32) +
2272 		    pitch2 * cy + vcnt * cx;
2273 		write_wvalue(ROT_OLADD2, addr2 & 0xffffffff);
2274 		write_wvalue(ROT_OHADD2, (addr2 >> 32) & 0xff);
2275 
2276 		G2D_INFO_MSG("DST_ADDR0: 0x%x\n", dst->laddr[0]);
2277 		G2D_INFO_MSG("DST_ADDR1: 0x%x\n", dst->laddr[1]);
2278 		G2D_INFO_MSG("DST_ADDR2: 0x%x\n", dst->laddr[2]);
2279 
2280 		/* start the module */
2281 		rot_irq_enable();
2282 		tmp = read_wvalue(ROT_CTL);
2283 		tmp |= (0x1 << 31);
2284 		G2D_INFO_MSG("init_module: 0x%x\n", tmp);
2285 		write_wvalue(ROT_CTL, tmp);
2286 
2287 		result = g2d_wait_cmd_finish();
2288 
2289 		return result;
2290 	}
2291 	g2d_scan_order_fun(flag & 0xf0000000);
2292 
2293 	/* start the module */
2294 	mixer_irq_enable();
2295 	tmp = read_wvalue(G2D_MIXER_CTL);
2296 	tmp |= 0x80000000;
2297 	G2D_INFO_MSG("INIT_MODULE: 0x%x\n", tmp);
2298 	write_wvalue(G2D_MIXER_CTL, tmp);
2299 
2300 	result = g2d_wait_cmd_finish();
2301 	return result;
2302 }
2303 
g2d_bsp_bld(g2d_image_enh * src,g2d_image_enh * dst,__u32 flag,g2d_ck * ck_para)2304 __s32 g2d_bsp_bld(g2d_image_enh *src, g2d_image_enh *dst, __u32 flag,
2305 		    g2d_ck *ck_para)
2306 {
2307 	g2d_rect rect0, rect1;
2308 	__u32 tmp;
2309 	__s32 result;
2310 
2311 	if (dst == NULL)
2312 		return -1;
2313 	g2d_mixer_reset();
2314 	g2d_vlayer_set(0, dst);
2315 	g2d_uilayer_set(2, src);
2316 	if ((dst->format > G2D_FORMAT_BGRA1010102) &&
2317 			(src->format <= G2D_FORMAT_BGRA1010102))
2318 		g2d_csc_reg_set(1, G2D_RGB2YUV_709);
2319 	write_wvalue(ROP_CTL, 0xF0);
2320 
2321 	rect0.x = 0;
2322 	rect0.y = 0;
2323 	rect0.w = dst->clip_rect.w;
2324 	rect0.h = dst->clip_rect.h;
2325 
2326 	rect1.x = 0;
2327 	rect1.y = 0;
2328 	rect1.w = src->clip_rect.w;
2329 	rect1.h = src->clip_rect.h;
2330 	g2d_bldin_set(0, rect0, dst->bpremul);
2331 	g2d_bldin_set(1, rect1, src->bpremul);
2332 
2333 	G2D_INFO_MSG("BLD_FLAG:  0x%x\n", flag);
2334 
2335 	porter_duff(flag & 0xFFF);
2336 	if (flag & G2D_CK_SRC)
2337 		write_wvalue(BLD_KEY_CTL, 0x3);
2338 
2339 	else if (flag & G2D_CK_DST)
2340 		write_wvalue(BLD_KEY_CTL, 0x1);
2341 	if (ck_para != NULL)
2342 		ck_para_set(ck_para);
2343 	g2d_wb_set(dst);
2344 	g2d_bld_cs_set(dst->format);
2345 
2346 	/* start the modult */
2347 	mixer_irq_enable();
2348 	tmp = read_wvalue(G2D_MIXER_CTL);
2349 	tmp |= 0x80000000;
2350 	G2D_INFO_MSG("INIT_MODULE: 0x%x\n", tmp);
2351 	write_wvalue(G2D_MIXER_CTL, tmp);
2352 
2353 	result = g2d_wait_cmd_finish();
2354 	return result;
2355 }
2356 
g2d_get_clk_cnt(__u32 * clk)2357 __s32 g2d_get_clk_cnt(__u32 *clk)
2358 {
2359 	__s32 ret;
2360 
2361 	ret = read_wvalue(G2D_MIXER_CLK);
2362 	if (ret != 0)
2363 		return -1;
2364 
2365 	    /* clear clk cnt */
2366 	    write_wvalue(G2D_MIXER_CLK, 0);
2367 	return 0;
2368 }
2369 
mixer_set_reg_base(unsigned long addr)2370 __u32 mixer_set_reg_base(unsigned long addr)
2371 {
2372 	base_addr = addr;
2373 	return 0;
2374 }
2375 
2376