• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * g2d_bld/g2d_bld.c
3  *
4  * Copyright (c) 2007-2019 Allwinnertech Co., Ltd.
5  * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 #include "g2d_bld.h"
18 
19 __s32 rgb2Ycbcr_601[48] = {
20 	/* full to limit */
21 	/* (0.2568, 0.5041, 0.0979, 16) * 1024
22 	 * (-0.1482, -0.291, 0.4392, 128) * 1024
23 	 * (0.4392, -0.3678, -0.0714, 128) * 1024
24 	 * */
25 	0x107, 0x204, 0x064, 0x4000, 0xFFFFFF68, 0xFFFFFED6, 0x01c2, 0x20000,
26 	0x01c2, 0xFFFFFE87, 0xFFFFFFB7, 0x20000,
27 	/* limit to limit */
28 	0x132, 0x259, 0x075, 0x0, 0xFFFFFF4F, 0xFFFFFEA5, 0x020c, 0x20000,
29 	0x020c, 0xFFFFFE49, 0xFFFFFFAB, 0x20000,
30 	/* full to full */
31 	0x132, 0x0259, 0x075, 0x0, 0xFFFFFF53, 0xFFFFFEAD, 0x0200, 0x20000,
32 	0x0200, 0xFFFFFE53, 0xFFFFFFAD, 0x20000,
33 	/* limit to full */
34 	0x0165, 0x02BC, 0x088, 0xFFFFF570, 0xFFFFFF37, 0xFFFFFE75, 0x0254, 0x20000,
35 	0x0254, 0xFFFFFE0D, 0xFFFFFF9F, 0x20000,
36 };
37 __s32 Ycbcr2rgb_601[48] = {
38 	/* full to limit */
39 	0x04a8, 0x0, 0x0662, 0xFFFC8480, 0x04a8, 0xFFFFFE6F, 0xFFFFFCC0,
40 	0x21E00, 0x04a8, 0x0812, 0x0, 0xFFFBAC80,
41 	/* limit to limit */
42 	0x0400, 0x0, 0x057c, 0xFFFD0200, 0x0400, 0xFFFFFEA7, 0xFFFFFD35, 0x1D200,
43 	0x0400, 0x06EE, 0x0, 0xFFFC4900,
44 	/* full to full */
45 	0x0400, 0x0, 0x059c, 0xFFFCF200, 0x0400, 0xFFFFFEA0, 0xFFFFFD25, 0x1DD80,
46 	0x0400, 0x0717, 0x0, 0xFFFC3480,
47 	/* limit to full */
48 	0x036F, 0x0, 0x04D1, 0xFFFDA090, 0x36F, 0xFFFFFED1, 0xFFFFFD8C, 0x1DA90,
49 	0x036F, 0x0616, 0x0, 0xFFFCFE10,
50 };
51 __s32 rgb2Ycbcr_709[48] = {
52 	/* full to limit */
53 	0x0bb, 0x0275, 0x03f, 0x4000, 0xFFFFFF99, 0xFFFFFEA5, 0x01c2, 0x20000,
54 	0x01c2, 0xFFFFFE67, 0xFFFFFFD7, 0x20000,
55 	/* limit to limit */
56 	0x0DA, 0x02DC, 0x04A, 0x0, 0xFFFFFF88, 0xFFFFFE6C, 0x020c, 0x20000,
57 	0x020c, 0xFFFFFE24, 0xFFFFFFD0, 0x20000,
58 	/* full to full */
59 	0x0DA, 0x02DC, 0x04a, 0x0, 0xFFFFFF8B, 0xFFFFFE75, 0x0200, 0x20000,
60 	0x0200, 0xFFFFFE2F, 0xFFFFFFD1, 0x20000,
61 	/* limit to full */
62 	0x0FD, 0x0355, 0x056, 0xFFFFF580, 0xFFFFFF77, 0xFFFFFE34, 0x0254, 0x20010,
63 	0x0254, 0xFFFFFDE3, 0xFFFFFFC9, 0x20000,
64 };
65 
66 __s32 Ycbcr2rgb_709[48] = {
67 	/* full to limit */
68 	0x04a8, 0x0, 0x072c, 0xFFFC1F80, 0x04a8, 0xFFFFFF26, 0xFFFFFDDE,
69 	0x13380, 0x04a8, 0x0873, 0, 0xFFFB7C00,
70 	/* limit to limit */
71 	0x0400, 0x0, 0x0629, 0xFFFCAB80, 0x0400, 0xFFFFFF44, 0xFFFFE2B, 0x10880,
72 	0x0400, 0x0742, 0x0, 0xFFFC1F00,
73 	/* full to full */
74 	0x0400, 0x0, 0x64D, 0xFFFC9980, 0x0400, 0xFFFFFF40, 0xFFFFFE21, 0x10F80,
75 	0x0400, 0x076C, 0x0, 0xFFFC0A00,
76 	/* limit to full */
77 	0x36f, 0x0, 0x0569, 0xFFFD5490, 0x36f, 0xFFFFFF5B, 0xFFFFFE64, 0x12990,
78 	0x36f, 0x0660, 0x0, 0xFFFCD910,
79 };
80 
81 /*
82  * sel: 0-->pipe0 1-->pipe1 other:error
83  */
bld_in_set(struct blender_submodule * p_bld,__u32 sel,g2d_rect rect,int premul)84 __s32 bld_in_set(struct blender_submodule *p_bld, __u32 sel, g2d_rect rect,
85 		    int premul)
86 {
87 	__s32 ret = -1;
88 
89 	struct g2d_mixer_bld_reg *p_reg = NULL;
90 	p_reg = p_bld->get_reg(p_bld);
91 	if (!p_reg)
92 		goto OUT;
93 
94 	if (sel == 0) {
95 		p_reg->bld_en_ctrl.bits.p0_en = 1;
96 		/* we best use p0 as bottom layer */
97 		p_reg->bld_en_ctrl.bits.p0_fcen = 1;
98 		if (premul)
99 			p_reg->premulti_ctrl.bits.p0_alpha_mode = 1;
100 	} else if (sel == 1) {
101 		p_reg->bld_en_ctrl.bits.p1_en = 1;
102 		if (premul)
103 			p_reg->premulti_ctrl.bits.p1_alpha_mode = 1;
104 	} else
105 		goto OUT;
106 
107 	p_reg->mem_size[sel].bits.width = rect.w - 1;
108 	p_reg->mem_size[sel].bits.height = rect.h - 1;
109 
110 	p_reg->mem_coor[sel].bits.xcoor = rect.x <= 0 ? 0 : rect.x - 1;
111 	p_reg->mem_coor[sel].bits.ycoor = rect.y <= 0 ? 0 : rect.y - 1;
112 
113 	ret = 0;
114 
115 	p_bld->set_block_dirty(p_bld, 0, 1);
116 
117 OUT:
118 	return ret;
119 }
120 
121 /**
122  * set colorkey para.
123  */
bld_ck_para_set(struct blender_submodule * p_bld,g2d_ck * para,__u32 flag)124 __s32 bld_ck_para_set(struct blender_submodule *p_bld, g2d_ck *para, __u32 flag)
125 {
126 	__u32 tmp = 0x0;
127 	__s32 ret = -1;
128 
129 	struct g2d_mixer_bld_reg *p_reg = NULL;
130 	p_reg = p_bld->get_reg(p_bld);
131 	if (!p_reg || !para)
132 		goto OUT;
133 
134 	if (para->match_rule)
135 		tmp = 0x7;
136 
137 	p_reg->color_key_cfg.dwval = tmp;
138 	p_reg->color_key_max.dwval = para->max_color & 0x00ffffff;
139 	p_reg->color_key_min.dwval = para->min_color & 0x00ffffff;
140 
141 	if (flag & G2D_CK_SRC) {
142 		p_reg->color_key.bits.key0_en = 1;
143 		p_reg->color_key.bits.key0_match_dir = 0;
144 	} else if (flag & G2D_CK_DST) {
145 		p_reg->color_key.bits.key0_en = 1;
146 		p_reg->color_key.bits.key0_match_dir = 1;
147 	}
148 
149 	p_bld->set_block_dirty(p_bld, 0, 1);
150 OUT:
151 	return ret;
152 }
153 
154 /**
155  * background color set
156  */
bld_bk_set(struct blender_submodule * p_bld,__u32 color)157 __s32 bld_bk_set(struct blender_submodule *p_bld, __u32 color)
158 {
159 	__s32 ret = -1;
160 
161 	struct g2d_mixer_bld_reg *p_reg = NULL;
162 	p_reg = p_bld->get_reg(p_bld);
163 	if (!p_reg)
164 		goto OUT;
165 
166 	p_reg->bld_backgroud_color = color & 0xffffffff;
167 	ret = 0;
168 	p_bld->set_block_dirty(p_bld, 0, 1);
169 OUT:
170 	return ret;
171 }
172 
bld_out_setting(struct blender_submodule * p_bld,g2d_image_enh * p_image)173 __s32 bld_out_setting(struct blender_submodule *p_bld, g2d_image_enh *p_image)
174 {
175 	__s32 ret = -1;
176 
177 	struct g2d_mixer_bld_reg *p_reg = NULL;
178 	p_reg = p_bld->get_reg(p_bld);
179 	if (!p_reg)
180 		goto OUT;
181 
182 	if (p_image->bpremul)
183 		p_reg->out_color.bits.premul_en = 1;
184 	else
185 		p_reg->out_color.bits.premul_en = 0;
186 	p_reg->out_size.bits.width =
187 	    p_image->clip_rect.w == 0 ? 0 : p_image->clip_rect.w - 1;
188 	p_reg->out_size.bits.height =
189 	    p_image->clip_rect.h == 0 ? 0 : p_image->clip_rect.h - 1;
190 	p_bld->set_block_dirty(p_bld, 0, 1);
191 	ret = 0;
192 OUT:
193 	return ret;
194 }
195 
bld_set_rop_ctrl(struct blender_submodule * p_bld,__u32 value)196 __s32 bld_set_rop_ctrl(struct blender_submodule *p_bld, __u32 value)
197 {
198 	__s32 ret = -1;
199 
200 	struct g2d_mixer_bld_reg *p_reg = NULL;
201 	p_reg = p_bld->get_reg(p_bld);
202 	if (!p_reg)
203 		goto OUT;
204 
205 	p_reg->rop_ctrl.dwval = value;
206 	p_reg->ch3_index0.dwval = 0x41000;
207 	ret = 0;
208 	p_bld->set_block_dirty(p_bld, 0, 1);
209 OUT:
210 	return ret;
211 }
212 
213 /**
214  * set the bld color space based on the format
215  * if the format is UI, then set the bld in RGB color space
216  * if the format is Video, then set the bld in YUV color space
217  */
bld_cs_set(struct blender_submodule * p_bld,__u32 format)218 __s32 bld_cs_set(struct blender_submodule *p_bld, __u32 format)
219 {
220 	__s32 ret = -1;
221 
222 	struct g2d_mixer_bld_reg *p_reg = NULL;
223 	p_reg = p_bld->get_reg(p_bld);
224 	if (!p_reg)
225 		goto OUT;
226 
227 	if (format <= G2D_FORMAT_BGRA1010102) {
228 		p_reg->out_color.bits.alpha_mode = 0;
229 	} else if (format <= G2D_FORMAT_YUV411_PLANAR) {
230 		p_reg->out_color.bits.alpha_mode = 1;
231 	} else
232 		goto OUT;
233 
234 	p_bld->set_block_dirty(p_bld, 0, 1);
235 	ret = 0;
236 OUT:
237 	return ret;
238 }
239 
240 /**
241  * @csc_no: CSC ID, G2D support three CSC,
242  * -1 will return to indicate inappropriate CSC number.
243  * @csc_sel: CSC format, G2D support the ITU-R 601. ITU-R 709. standard trans-
244  *  form between RGB and YUV colorspace.
245  */
bld_csc_reg_set(struct blender_submodule * p_bld,__u32 csc_no,g2d_csc_sel csc_sel,enum color_range src_cr,enum color_range dst_cr)246 __s32 bld_csc_reg_set(struct blender_submodule *p_bld, __u32 csc_no,
247 		g2d_csc_sel csc_sel, enum color_range src_cr, enum color_range dst_cr)
248 {
249 	void *csc_base_addr;
250 	__s32 ret = -1;
251 
252 	struct g2d_mixer_bld_reg *p_reg = NULL;
253 	p_reg = p_bld->get_reg(p_bld);
254 	if (!p_reg)
255 		goto OUT;
256 
257 	p_reg->bld_fill_color[0] = 0x00108080;
258 	p_reg->bld_fill_color[1] = 0x00108080;
259 
260 	switch (csc_no) {
261 	case 0:
262 		csc_base_addr = &p_reg->csc0_coeff0_reg0;
263 		p_reg->cs_ctrl.bits.cs0_en = 1;
264 		break;
265 	case 1:
266 		csc_base_addr = &p_reg->csc1_coeff0_reg0;
267 		p_reg->cs_ctrl.bits.cs1_en = 1;
268 		break;
269 	case 2:
270 		csc_base_addr = &p_reg->csc2_coeff0_reg0;
271 		p_reg->cs_ctrl.bits.cs2_en = 1;
272 		break;
273 	default:
274 		goto OUT;
275 	}
276 	switch (csc_sel) {
277 	case G2D_RGB2YUV_709:
278 		if (src_cr == COLOR_RANGE_0_255) {
279 			if (dst_cr == COLOR_RANGE_0_255)
280 				/* full to full */
281 				memcpy(csc_base_addr, (rgb2Ycbcr_709 + 0x18), 12 * sizeof(unsigned int));
282 			else
283 				/* full to limit */
284 				memcpy(csc_base_addr, rgb2Ycbcr_709, 12 * sizeof(unsigned int));
285 		} else {
286 			if (dst_cr == COLOR_RANGE_0_255)
287 				/* limit to full */
288 				memcpy(csc_base_addr, (rgb2Ycbcr_709 + 0x24), 12 * sizeof(unsigned int));
289 			else
290 				/* limit to limit */
291 				memcpy(csc_base_addr, (rgb2Ycbcr_709 + 0xc), 12 * sizeof(unsigned int));
292 		}
293 		break;
294 	case G2D_YUV2RGB_709:
295 		if (src_cr == COLOR_RANGE_0_255) {
296 			if (dst_cr == COLOR_RANGE_0_255)
297 				/* full to full */
298 				memcpy(csc_base_addr, (Ycbcr2rgb_709 + 0x18), 12 * sizeof(unsigned int));
299 			else
300 				/* full to limit */
301 				memcpy(csc_base_addr, Ycbcr2rgb_709, 12 * sizeof(unsigned int));
302 		} else {
303 			if (dst_cr == COLOR_RANGE_0_255)
304 				/* limit to full */
305 				memcpy(csc_base_addr, (Ycbcr2rgb_709 + 0x24), 12 * sizeof(unsigned int));
306 			else
307 				/* limit to limit */
308 				memcpy(csc_base_addr, (Ycbcr2rgb_709 + 0xc), 12 * sizeof(unsigned int));
309 		}
310 		break;
311 	case G2D_RGB2YUV_601:
312 		if (src_cr == COLOR_RANGE_0_255) {
313 			if (dst_cr == COLOR_RANGE_0_255)
314 				/* full to full */
315 				memcpy(csc_base_addr, (rgb2Ycbcr_601 + 0x18), 12 * sizeof(unsigned int));
316 			else
317 				/* full to limit */
318 				memcpy(csc_base_addr, rgb2Ycbcr_601, 12 * sizeof(unsigned int));
319 		} else {
320 			if (dst_cr == COLOR_RANGE_0_255)
321 				/* limit to full */
322 				memcpy(csc_base_addr, (rgb2Ycbcr_601 + 0x24), 12 * sizeof(unsigned int));
323 			else
324 				/* limit to limit */
325 				memcpy(csc_base_addr, (rgb2Ycbcr_601 + 0xc), 12 * sizeof(unsigned int));
326 		}
327 		break;
328 	case G2D_YUV2RGB_601:
329 		if (src_cr == COLOR_RANGE_0_255) {
330 			if (dst_cr == COLOR_RANGE_0_255)
331 				/* full to full */
332 				memcpy(csc_base_addr, (Ycbcr2rgb_601 + 0x18), 12 * sizeof(unsigned int));
333 			else
334 				/* full to limit */
335 				memcpy(csc_base_addr, Ycbcr2rgb_601, 12 * sizeof(unsigned int));
336 		} else {
337 			if (dst_cr == COLOR_RANGE_0_255)
338 				/* limit to full */
339 				memcpy(csc_base_addr, (Ycbcr2rgb_601 + 0x24), 12 * sizeof(unsigned int));
340 			else
341 				/* limit to limit */
342 				memcpy(csc_base_addr, (Ycbcr2rgb_601 + 0xc), 12 * sizeof(unsigned int));
343 		}
344 		break;
345 	default:
346 		G2D_ERR_MSG("No implement standard:%d!\n", csc_sel);
347 		goto OUT;
348 	}
349 
350 	p_bld->set_block_dirty(p_bld, 0, 1);
351 	ret = 0;
352 OUT:
353 	return ret;
354 }
355 
bld_porter_duff(struct blender_submodule * p_bld,__u32 cmd)356 __s32 bld_porter_duff(struct blender_submodule *p_bld, __u32 cmd)
357 {
358 	struct g2d_mixer_bld_reg *p_reg = NULL;
359 	__s32 ret = -1;
360 
361 	p_reg = p_bld->get_reg(p_bld);
362 	if (!p_reg)
363 		goto OUT;
364 
365 	switch (cmd) {
366 	case G2D_BLD_CLEAR:
367 		p_reg->bld_ctrl.dwval = 0x00000000;
368 		break;
369 	case G2D_BLD_COPY:
370 		p_reg->bld_ctrl.dwval = 0x00010001;
371 		break;
372 	case G2D_BLD_DST:
373 		p_reg->bld_ctrl.dwval = 0x01000100;
374 		break;
375 	case G2D_BLD_SRCOVER:
376 		p_reg->bld_ctrl.dwval = 0x03010301;
377 		break;
378 	case G2D_BLD_DSTOVER:
379 		p_reg->bld_ctrl.dwval = 0x01030103;
380 		break;
381 	case G2D_BLD_SRCIN:
382 		p_reg->bld_ctrl.dwval = 0x00020002;
383 		break;
384 	case G2D_BLD_DSTIN:
385 		p_reg->bld_ctrl.dwval = 0x02000200;
386 		break;
387 	case G2D_BLD_SRCOUT:
388 		p_reg->bld_ctrl.dwval = 0x00030003;
389 		break;
390 	case G2D_BLD_DSTOUT:
391 		p_reg->bld_ctrl.dwval = 0x03000300;
392 		break;
393 	case G2D_BLD_SRCATOP:
394 		p_reg->bld_ctrl.dwval = 0x03020302;
395 		break;
396 	case G2D_BLD_DSTATOP:
397 		p_reg->bld_ctrl.dwval = 0x02030203;
398 		break;
399 	case G2D_BLD_XOR:
400 		p_reg->bld_ctrl.dwval = 0x03030303;
401 		break;
402 	default:
403 		p_reg->bld_ctrl.dwval = 0x03010301;
404 	}
405 	p_bld->set_block_dirty(p_bld, 0, 1);
406 	ret = 0;
407 OUT:
408 	return ret;
409 }
410 
bld_rcq_setup(struct blender_submodule * p_bld,u8 __iomem * base,struct g2d_rcq_mem_info * p_rcq_info)411 int bld_rcq_setup(struct blender_submodule *p_bld, u8 __iomem *base,
412 		  struct g2d_rcq_mem_info *p_rcq_info)
413 {
414 	u8 __iomem *reg_base = base + G2D_BLD;
415 	int ret = -1;
416 
417 	if (!p_bld) {
418 		G2D_ERR_MSG("Null pointer!\n");
419 		goto OUT;
420 	}
421 
422 	p_bld->reg_info->size = sizeof(struct g2d_mixer_bld_reg);
423 	p_bld->reg_info->vir_addr = (u8 *)g2d_top_reg_memory_alloc(
424 	    p_bld->reg_info->size, (void *)&(p_bld->reg_info->phy_addr),
425 	    p_rcq_info);
426 
427 	if (!p_bld->reg_info->vir_addr) {
428 		G2D_ERR_MSG("Malloc blender reg rcq memory fail!\n");
429 		goto OUT;
430 	}
431 
432 	p_bld->reg_blks->vir_addr = p_bld->reg_info->vir_addr;
433 	p_bld->reg_blks->phy_addr = p_bld->reg_info->phy_addr;
434 	p_bld->reg_blks->size = p_bld->reg_info->size;
435 	p_bld->reg_blks->reg_addr = reg_base;
436 	ret = 0;
437 OUT:
438 	return ret;
439 }
440 
441 /**
442  * ROP2 cmd register set
443  * Index0 is selected
444  * dst mapping ch0'
445  * src mapping ch1'
446  */
bld_rop2_set(struct blender_submodule * p_bld,__u32 rop_cmd)447 __s32 bld_rop2_set(struct blender_submodule *p_bld, __u32 rop_cmd)
448 {
449 	__s32 ret = -1;
450 	struct g2d_mixer_bld_reg *p_reg = p_bld->get_reg(p_bld);
451 
452 	p_reg = p_bld->get_reg(p_bld);
453 	if (!p_reg)
454 		goto OUT;
455 
456 	if (rop_cmd == G2D_BLT_BLACKNESS) {
457 		/* blackness */
458 		/* tmpue = 0x1<<18; */
459 		p_reg->ch3_index0.dwval = 0x40000;
460 	} else if (rop_cmd == G2D_BLT_NOTMERGEPEN) {
461 		/* ~(dst | src) */
462 		/* tmpue = (0x1<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
463 		p_reg->ch3_index0.dwval = 0x41440;
464 	} else if (rop_cmd == G2D_BLT_MASKNOTPEN) {
465 		/* ~src&dst */
466 		/* tmpue = (0x1<<4) | (0x0<<10) | (0x2<<11) | (0x1<<18); */
467 		p_reg->ch3_index0.dwval = 0x41010;
468 	} else if (rop_cmd == G2D_BLT_NOTCOPYPEN) {
469 		/* ~src */
470 		/* tmpue = (0x1<<4) | (0x2<<6) | (0x2<<11) |
471 		 * (0x1<<18) | (0x1<<17);
472 		 */
473 		p_reg->ch3_index0.dwval = 0x61090;
474 	} else if (rop_cmd == G2D_BLT_MASKPENNOT) {
475 		/* src&~dst */
476 		/* tmpue = (0x1<<3) | (0x0<<10) | (0x2<<11) | (0x1<<18); */
477 		p_reg->ch3_index0.dwval = 0x41008;
478 	} else if (rop_cmd == G2D_BLT_NOT) {
479 		/* ~dst */
480 		/* tmpue = (0x1<<3) | (0x2<<6) | (0x2<<11) |
481 		 * (0x1<<18) | (0x1<<16);
482 		 */
483 		p_reg->ch3_index0.dwval = 0x51088;
484 	} else if (rop_cmd == G2D_BLT_XORPEN) {
485 		/* src xor dst */
486 		/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18); */
487 		p_reg->ch3_index0.dwval = 0x41080;
488 	} else if (rop_cmd == G2D_BLT_NOTMASKPEN) {
489 		/* ~(src & dst) */
490 		/* tmpue = (0x0<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
491 		p_reg->ch3_index0.dwval = 0x41400;
492 	} else if (rop_cmd == G2D_BLT_MASKPEN) {
493 		/* src&dst */
494 		/* tmpue = (0x0<<6) | (0x2<<11) | (0x1<<18); */
495 		p_reg->ch3_index0.dwval = 0x41000;
496 	} else if (rop_cmd == G2D_BLT_NOTXORPEN) {
497 		/* ~(src xor dst) */
498 		/* tmpue = (0x2<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
499 		p_reg->ch3_index0.dwval = 0x41480;
500 	} else if (rop_cmd == G2D_BLT_NOP) {
501 		/* dst */
502 		/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
503 		p_reg->ch3_index0.dwval = 0x51080;
504 	} else if (rop_cmd == G2D_BLT_MERGENOTPEN) {
505 		/* ~dst or src */
506 		/* tmpue = (0x1<<3)| (0x1<<6) | (0x2<<11) | (0x1<<18) */
507 		/* write_wvalue(ROP_INDEX0, 0x40A20); */
508 		p_reg->ch3_index0.dwval = 0x41048;
509 	} else if (rop_cmd == G2D_BLT_COPYPEN) {
510 		/* src */
511 		/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<17); */
512 		p_reg->ch3_index0.dwval = 0x61080;
513 	} else if (rop_cmd == G2D_BLT_MERGEPENNOT) {
514 		/* src or ~dst */
515 		/* tmpue =  (0x1<<3)| (0x1<<6) | (0x2<<11) | (0x1<<18) */
516 		p_reg->ch3_index0.dwval = 0x41048;
517 	} else if (rop_cmd == G2D_BLT_MERGEPEN) {
518 		/* src or dst */
519 		/* tmpue = (0x1<<6) | (0x1<<18) | (0x2<<11); */
520 		p_reg->ch3_index0.dwval = 0x41040;
521 	} else if (rop_cmd == G2D_BLT_WHITENESS) {
522 		/* whiteness */
523 		/* tmpue = (0x1<<18) | (0x1<<15); */
524 		p_reg->ch3_index0.dwval = 0x48000;
525 	} else
526 		goto OUT;
527 
528 	p_reg->ch3_index0.bits.index0node0 = 2; /*TODO:different with source*/
529 	p_bld->set_block_dirty(p_bld, 0, 1);
530 
531 	ret = 0;
532 OUT:
533 	return ret;
534 }
535 
536 /**
537  * ROP3 cmd register set
538  * dst mapping ch0'
539  * src mapping ch1'
540  * ptn mapping ch2'
541  * -1 return meaning that the operate is not supported by now
542  */
bld_rop3_set(struct blender_submodule * p_bld,__u32 sel,__u32 rop3_cmd)543 __s32 bld_rop3_set(struct blender_submodule *p_bld, __u32 sel, __u32 rop3_cmd)
544 {
545 	__s32 ret = -1;
546 	union g2d_mixer_rop_ch3_index0 *p_addr = NULL;
547 	struct g2d_mixer_bld_reg *p_reg = p_bld->get_reg(p_bld);
548 
549 	p_reg = p_bld->get_reg(p_bld);
550 	if (!p_reg)
551 		goto OUT;
552 
553 	if (sel == 0)
554 		p_addr = &p_reg->ch3_index0;
555 	else if (sel == 1)
556 		p_addr = &p_reg->ch3_index1;
557 	else
558 		goto OUT;
559 
560 	if (rop3_cmd == G2D_ROP3_BLACKNESS) {
561 		/* blackness */
562 		/* 0x1<<18; */
563 		p_addr->dwval = 0x40000;
564 	} else if (rop3_cmd == G2D_ROP3_NOTSRCERASE) {
565 		/* (~src) AND (~dst) */
566 		/* (0x1<<3) | (0x1<<4) | (0x1<<18) | (0x2<<11); */
567 		p_addr->dwval = 0x41018;
568 	} else if (rop3_cmd == G2D_ROP3_NOTSRCCOPY) {
569 
570 		/* ~src */
571 		/* (0x1<<4) | (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
572 		p_addr->dwval = 0x51090;
573 	} else if (rop3_cmd == G2D_ROP3_SRCERASE) {
574 		/* src AND ~dst */
575 		/* (0x1<<3) | (0x0<<6) | (0x2<<11) | (0x1<<18); */
576 		p_addr->dwval = 0x41008;
577 	} else if (rop3_cmd == G2D_ROP3_DSTINVERT) {
578 		/* ~dst */
579 		/* (0x1<<3) | (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<17); */
580 		p_addr->dwval = 0x61088;
581 	} else if (rop3_cmd == G2D_ROP3_PATINVERT) {
582 		/* ptn XOR dst */
583 		/* (0x2<<6) | (0x2<<11) | (0x1<<17) */
584 		p_addr->dwval = 0x21080;
585 	} else if (rop3_cmd == G2D_ROP3_SRCINVERT) {
586 		/* src XOR dst */
587 		/* (0x2<<6) | (0x2<<11) | (0x1<<18); */
588 		p_addr->dwval = 0x41080;
589 	} else if (rop3_cmd == G2D_ROP3_SRCAND) {
590 		/* src AND dst */
591 		/* (0x0<<6) | (0x2<<11) | (0x1<<18); */
592 		p_addr->dwval = 0x41000;
593 	} else if (rop3_cmd == G2D_ROP3_MERGEPAINT) {
594 		/* ~src OR dst */
595 		/* (0x1<<4) | (0x1<<6) | (0x2<<11) | (0x1<<18); */
596 		p_addr->dwval = 0x41050;
597 	} else if (rop3_cmd == G2D_ROP3_MERGECOPY) {
598 		/* src AND pattern */
599 		/* (0x2<<6) | (0x1<<16) */
600 		p_addr->dwval = 0x10080;
601 	} else if (rop3_cmd == G2D_ROP3_SRCCOPY) {
602 		/* src */
603 		/* (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
604 		p_addr->dwval = 0x51080;
605 	} else if (rop3_cmd == G2D_ROP3_SRCPAINT) {
606 		/* src OR dst */
607 		/* (0x1<<6) | (0x2<<11) | (0x1<<18); */
608 		p_addr->dwval = 0x41040;
609 	} else if (rop3_cmd == G2D_ROP3_PATCOPY) {
610 		/* ptn */
611 		/* (0x1<<16) | (0x1<<17) | (0x2)<<11 */
612 		p_addr->dwval = 0x31000;
613 	} else if (rop3_cmd == G2D_ROP3_PATPAINT) {
614 		/* DPSnoo */
615 		/* (0x1<<3) | (0x1<<6) | (0x1<<11) */
616 		p_addr->dwval = 0x848;
617 	} else if (rop3_cmd == G2D_ROP3_WHITENESS) {
618 		/* whiteness */
619 		p_addr->dwval = 0x48000;
620 	} else
621 		goto OUT;
622 
623 	p_bld->set_block_dirty(p_bld, 0, 1);
624 
625 	ret = 0;
626 OUT:
627 	return ret;
628 }
629 
bld_get_reg_block_num(struct blender_submodule * p_bld)630 static __u32 bld_get_reg_block_num(struct blender_submodule *p_bld)
631 {
632 	if (p_bld)
633 		return p_bld->reg_blk_num;
634 	return 0;
635 }
636 
bld_get_reg_block(struct blender_submodule * p_bld,struct g2d_reg_block ** blks)637 static __s32 bld_get_reg_block(struct blender_submodule *p_bld,
638 			    struct g2d_reg_block **blks)
639 {
640 	__s32 i = 0, ret = -1;
641 
642 	if (p_bld) {
643 		for (i = 0; i < p_bld->reg_blk_num; ++i)
644 			blks[i] = p_bld->reg_blks + i;
645 	}
646 
647 	return ret;
648 }
649 
bld_get_reg(struct blender_submodule * p_bld)650 static struct g2d_mixer_bld_reg *bld_get_reg(struct blender_submodule *p_bld)
651 {
652 #if G2D_MIXER_RCQ_USED == 1
653 	return (struct g2d_mixer_bld_reg *)(p_bld->reg_blks
654 					    ->vir_addr);
655 #else
656 	return (struct g2d_mixer_bld_reg *)(p_bld->reg_blks
657 					    ->reg_addr);
658 #endif
659 	return NULL;
660 }
661 
bld_set_block_dirty(struct blender_submodule * p_bld,__u32 blk_id,__u32 dirty)662 static void bld_set_block_dirty(struct blender_submodule *p_bld, __u32 blk_id, __u32 dirty)
663 {
664 #if G2D_MIXER_RCQ_USED == 1
665 	if (p_bld && p_bld->reg_blks->rcq_hd)
666 		p_bld->reg_blks->rcq_hd->dirty.bits.dirty = dirty;
667 	else
668 		G2D_ERR_MSG("Null pointer!\n");
669 #else
670 
671 	if (p_bld)
672 		p_bld->reg_blks->dirty = dirty;
673 	else
674 		G2D_ERR_MSG("Null pointer!\n");
675 #endif
676 }
677 
bld_get_rcq_mem_size(struct blender_submodule * p_bld)678 static __u32 bld_get_rcq_mem_size(struct blender_submodule *p_bld)
679 {
680 	return G2D_RCQ_BYTE_ALIGN(sizeof(struct g2d_mixer_bld_reg));
681 }
682 
bld_destory(struct blender_submodule * p_bld)683 static __s32 bld_destory(struct blender_submodule *p_bld)
684 {
685 	__s32 ret = -1;
686 
687 	if (p_bld) {
688 		kfree(p_bld->reg_blks);
689 		p_bld->reg_blks = NULL;
690 
691 		kfree(p_bld->reg_info);
692 		p_bld->reg_info = NULL;
693 		kfree(p_bld);
694 		ret = 0;
695 	}
696 
697 	return ret;
698 }
699 
700 struct blender_submodule *
g2d_bld_submodule_setup(struct g2d_mixer_frame * p_frame)701 g2d_bld_submodule_setup(struct g2d_mixer_frame *p_frame)
702 {
703 	struct blender_submodule *p_bld = NULL;
704 
705 	p_bld = kmalloc(sizeof(struct blender_submodule), GFP_KERNEL | __GFP_ZERO);
706 
707 	if (!p_bld) {
708 		G2D_ERR_MSG("Kmalloc wb submodule fail!\n");
709 		return NULL;
710 	}
711 
712 	p_bld->rcq_setup = bld_rcq_setup;
713 	p_bld->reg_blk_num = 1;
714 	p_bld->get_reg_block_num = bld_get_reg_block_num;
715 	p_bld->get_reg_block = bld_get_reg_block;
716 	p_bld->get_reg = bld_get_reg;
717 	p_bld->set_block_dirty = bld_set_block_dirty;
718 	p_bld->get_rcq_mem_size = bld_get_rcq_mem_size;
719 	p_bld->destory = bld_destory;
720 
721 	p_bld->reg_blks =
722 	    kmalloc(sizeof(struct g2d_reg_block) * p_bld->reg_blk_num,
723 		    GFP_KERNEL | __GFP_ZERO);
724 	p_bld->reg_info =
725 	    kmalloc(sizeof(struct g2d_reg_mem_info), GFP_KERNEL | __GFP_ZERO);
726 
727 	if (!p_bld->reg_blks || !p_bld->reg_info) {
728 		G2D_ERR_MSG("Kmalloc wb reg info fail!\n");
729 		goto FREE_WB;
730 	}
731 
732 
733 	return p_bld;
734 FREE_WB:
735 	kfree(p_bld->reg_blks);
736 	kfree(p_bld->reg_info);
737 	kfree(p_bld);
738 
739 	return NULL;
740 }
741