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 <stdlib.h>
18 #include "g2d_bld.h"
19 
20 __s32 rgb2Ycbcr_709[12] = {
21 	0x0bb, 0x0275, 0x03f, 0x4200, 0xFFFFFF99, 0xFFFFFEA6, 0x01c2, 0x20200,
22 	0x01c2, 0xFFFFFE67, 0xFFFFFFD7, 0x20200, };
23 __s32 Ycbcr2rgb_709[12] = {
24 	0x04a8, 0x0, 0x072c, 0xFFFC1F7D, 0x04a8, 0xFFFFFF26, 0xFFFFFDDD,
25 	0x133F8, 0x04a8, 0x0876, 0, 0xFFFB7AA0, };
26 __s32 rgb2Ycbcr_601[12] = {
27 	0x0107, 0x0204, 0x064, 0x4200,
28 	0xFFFFFF68, 0xFFFFFED6, 0x01c2, 0x20200,
29 	0x01c2, 0xFFFFFE87, 0xFFFFFFB7, 0x20200,};
30 __s32 Ycbcr2rgb_601[12] = {
31 	0x04a8, 0x0, 0x0662, 0xFFFC865A,
32 	0x04a8, 0xFFFFFE70, 0xFFFFFCBF, 0x21FF4,
33 	0x04a8, 0x0812, 0x0, 0xFFFBAE4A,};
34 
35 /*
36  * sel: 0-->pipe0 1-->pipe1 other:error
37  */
bld_in_set(struct blender_submodule * p_bld,__u32 sel,g2d_rect rect,int premul)38 __s32 bld_in_set(struct blender_submodule *p_bld, __u32 sel, g2d_rect rect,
39 		    int premul)
40 {
41 	__s32 ret = -1;
42 
43 	struct g2d_mixer_bld_reg *p_reg = NULL;
44 	p_reg = p_bld->get_reg(p_bld);
45 	if (!p_reg)
46 		goto OUT;
47 
48 	if (sel == 0) {
49 		p_reg->bld_en_ctrl.bits.p0_en = 1;
50 		/* we best use p0 as bottom layer */
51 		p_reg->bld_en_ctrl.bits.p0_fcen = 1;
52 		if (premul)
53 			p_reg->premulti_ctrl.bits.p0_alpha_mode = 1;
54 	} else if (sel == 1) {
55 		p_reg->bld_en_ctrl.bits.p1_en = 1;
56 		if (premul)
57 			p_reg->premulti_ctrl.bits.p1_alpha_mode = 1;
58 	} else
59 		goto OUT;
60 
61 	p_reg->mem_size[sel].bits.width = rect.w - 1;
62 	p_reg->mem_size[sel].bits.height = rect.h - 1;
63 
64 	p_reg->mem_coor[sel].bits.xcoor = rect.x <= 0 ? 0 : rect.x - 1;
65 	p_reg->mem_coor[sel].bits.ycoor = rect.y <= 0 ? 0 : rect.y - 1;
66 
67 	ret = 0;
68 
69 	p_bld->set_block_dirty(p_bld, 0, 1);
70 
71 OUT:
72 	return ret;
73 }
74 
75 /**
76  * set colorkey para.
77  */
bld_ck_para_set(struct blender_submodule * p_bld,g2d_ck * para,__u32 flag)78 __s32 bld_ck_para_set(struct blender_submodule *p_bld, g2d_ck *para, __u32 flag)
79 {
80 	__u32 tmp = 0x0;
81 	__s32 ret = -1;
82 
83 	struct g2d_mixer_bld_reg *p_reg = NULL;
84 	p_reg = p_bld->get_reg(p_bld);
85 	if (!p_reg || !para)
86 		goto OUT;
87 
88 	if (para->match_rule)
89 		tmp = 0x7;
90 
91 	p_reg->color_key_cfg.dwval = tmp;
92 	p_reg->color_key_max.dwval = para->max_color & 0x00ffffff;
93 	p_reg->color_key_min.dwval = para->min_color & 0x00ffffff;
94 
95 	if (flag & G2D_CK_SRC) {
96 		p_reg->color_key.bits.key0_en = 1;
97 		p_reg->color_key.bits.key0_match_dir = 0;
98 	} else if (flag & G2D_CK_DST) {
99 		p_reg->color_key.bits.key0_en = 1;
100 		p_reg->color_key.bits.key0_match_dir = 1;
101 	}
102 
103 	p_bld->set_block_dirty(p_bld, 0, 1);
104 OUT:
105 	return ret;
106 }
107 
108 /**
109  * background color set
110  */
bld_bk_set(struct blender_submodule * p_bld,__u32 color)111 __s32 bld_bk_set(struct blender_submodule *p_bld, __u32 color)
112 {
113 	__s32 ret = -1;
114 
115 	struct g2d_mixer_bld_reg *p_reg = NULL;
116 	p_reg = p_bld->get_reg(p_bld);
117 	if (!p_reg)
118 		goto OUT;
119 
120 	p_reg->bld_backgroud_color = color & 0xffffffff;
121 	ret = 0;
122 	p_bld->set_block_dirty(p_bld, 0, 1);
123 OUT:
124 	return ret;
125 }
126 
bld_out_setting(struct blender_submodule * p_bld,g2d_image_enh * p_image)127 __s32 bld_out_setting(struct blender_submodule *p_bld, g2d_image_enh *p_image)
128 {
129 	__s32 ret = -1;
130 
131 	struct g2d_mixer_bld_reg *p_reg = NULL;
132 	p_reg = p_bld->get_reg(p_bld);
133 	if (!p_reg)
134 		goto OUT;
135 
136 	if (p_image->bpremul)
137 		p_reg->out_color.bits.premul_en = 1;
138 	else
139 		p_reg->out_color.bits.premul_en = 0;
140 	p_reg->out_size.bits.width =
141 	    p_image->clip_rect.w == 0 ? 0 : p_image->clip_rect.w - 1;
142 	p_reg->out_size.bits.height =
143 	    p_image->clip_rect.h == 0 ? 0 : p_image->clip_rect.h - 1;
144 	p_bld->set_block_dirty(p_bld, 0, 1);
145 	ret = 0;
146 OUT:
147 	return ret;
148 }
149 
bld_set_rop_ctrl(struct blender_submodule * p_bld,__u32 value)150 __s32 bld_set_rop_ctrl(struct blender_submodule *p_bld, __u32 value)
151 {
152 	__s32 ret = -1;
153 
154 	struct g2d_mixer_bld_reg *p_reg = NULL;
155 	p_reg = p_bld->get_reg(p_bld);
156 	if (!p_reg)
157 		goto OUT;
158 
159 	p_reg->rop_ctrl.dwval = value;
160 	p_reg->ch3_index0.dwval = 0x41000;
161 	ret = 0;
162 	p_bld->set_block_dirty(p_bld, 0, 1);
163 OUT:
164 	return ret;
165 }
166 
167 /**
168  * set the bld color space based on the format
169  * if the format is UI, then set the bld in RGB color space
170  * if the format is Video, then set the bld in YUV color space
171  */
bld_cs_set(struct blender_submodule * p_bld,__u32 format)172 __s32 bld_cs_set(struct blender_submodule *p_bld, __u32 format)
173 {
174 	__s32 ret = -1;
175 
176 	struct g2d_mixer_bld_reg *p_reg = NULL;
177 	p_reg = p_bld->get_reg(p_bld);
178 	if (!p_reg)
179 		goto OUT;
180 
181 	if (format <= G2D_FORMAT_BGRA1010102) {
182 		p_reg->out_color.bits.alpha_mode = 0;
183 	} else if (format <= G2D_FORMAT_YUV411_PLANAR) {
184 		p_reg->out_color.bits.alpha_mode = 1;
185 	} else
186 		goto OUT;
187 
188 	p_bld->set_block_dirty(p_bld, 0, 1);
189 	ret = 0;
190 OUT:
191 	return ret;
192 }
193 
194 /**
195  * @csc_no: CSC ID, G2D support three CSC,
196  * -1 will return to indicate inappropriate CSC number.
197  * @csc_sel: CSC format, G2D support the ITU-R 601. ITU-R 709. standard trans-
198  *  form between RGB and YUV colorspace.
199  */
bld_csc_reg_set(struct blender_submodule * p_bld,__u32 csc_no,g2d_csc_sel csc_sel)200 __s32 bld_csc_reg_set(struct blender_submodule *p_bld, __u32 csc_no, g2d_csc_sel csc_sel)
201 {
202 	void *csc_base_addr;
203 	__s32 ret = -1;
204 
205 	struct g2d_mixer_bld_reg *p_reg = NULL;
206 	p_reg = p_bld->get_reg(p_bld);
207 	if (!p_reg)
208 		goto OUT;
209 
210 	p_reg->bld_fill_color[0] = 0x00108080;
211 	p_reg->bld_fill_color[1] = 0x00108080;
212 
213 	switch (csc_no) {
214 	case 0:
215 		csc_base_addr = &p_reg->csc0_coeff0_reg0;
216 		p_reg->cs_ctrl.bits.cs0_en = 1;
217 		break;
218 	case 1:
219 		csc_base_addr = &p_reg->csc1_coeff0_reg0;
220 		p_reg->cs_ctrl.bits.cs1_en = 1;
221 		break;
222 	case 2:
223 		csc_base_addr = &p_reg->csc2_coeff0_reg0;
224 		p_reg->cs_ctrl.bits.cs2_en = 1;
225 		break;
226 	default:
227 		goto OUT;
228 	}
229 	switch (csc_sel) {
230 	case G2D_RGB2YUV_709:
231 		memcpy(csc_base_addr, rgb2Ycbcr_709, 12 * sizeof(unsigned int));
232 		break;
233 	case G2D_YUV2RGB_709:
234 		memcpy(csc_base_addr, Ycbcr2rgb_709, 12 * sizeof(unsigned int));
235 		break;
236 	case G2D_RGB2YUV_601:
237 		memcpy(csc_base_addr, rgb2Ycbcr_601, 12 * sizeof(unsigned int));
238 		break;
239 	case G2D_YUV2RGB_601:
240 		memcpy(csc_base_addr, Ycbcr2rgb_601, 12 * sizeof(unsigned int));
241 		break;
242 	default:
243 		G2D_ERR_MSG("No implement standard:%d!\n", csc_sel);
244 		goto OUT;
245 	}
246 
247 	p_bld->set_block_dirty(p_bld, 0, 1);
248 	ret = 0;
249 OUT:
250 	return ret;
251 }
252 
bld_porter_duff(struct blender_submodule * p_bld,__u32 cmd)253 __s32 bld_porter_duff(struct blender_submodule *p_bld, __u32 cmd)
254 {
255 	struct g2d_mixer_bld_reg *p_reg = NULL;
256 	__s32 ret = -1;
257 
258 	p_reg = p_bld->get_reg(p_bld);
259 	if (!p_reg)
260 		goto OUT;
261 
262 	switch (cmd) {
263 	case G2D_BLD_CLEAR:
264 		p_reg->bld_ctrl.dwval = 0x00000000;
265 		break;
266 	case G2D_BLD_COPY:
267 		p_reg->bld_ctrl.dwval = 0x00010001;
268 		break;
269 	case G2D_BLD_DST:
270 		p_reg->bld_ctrl.dwval = 0x01000100;
271 		break;
272 	case G2D_BLD_SRCOVER:
273 		p_reg->bld_ctrl.dwval = 0x03010301;
274 		break;
275 	case G2D_BLD_DSTOVER:
276 		p_reg->bld_ctrl.dwval = 0x01030103;
277 		break;
278 	case G2D_BLD_SRCIN:
279 		p_reg->bld_ctrl.dwval = 0x00020002;
280 		break;
281 	case G2D_BLD_DSTIN:
282 		p_reg->bld_ctrl.dwval = 0x02000200;
283 		break;
284 	case G2D_BLD_SRCOUT:
285 		p_reg->bld_ctrl.dwval = 0x00030003;
286 		break;
287 	case G2D_BLD_DSTOUT:
288 		p_reg->bld_ctrl.dwval = 0x03000300;
289 		break;
290 	case G2D_BLD_SRCATOP:
291 		p_reg->bld_ctrl.dwval = 0x03020302;
292 		break;
293 	case G2D_BLD_DSTATOP:
294 		p_reg->bld_ctrl.dwval = 0x02030203;
295 		break;
296 	case G2D_BLD_XOR:
297 		p_reg->bld_ctrl.dwval = 0x03030303;
298 		break;
299 	default:
300 		p_reg->bld_ctrl.dwval = 0x03010301;
301 	}
302 	p_bld->set_block_dirty(p_bld, 0, 1);
303 	ret = 0;
304 OUT:
305 	return ret;
306 }
307 
bld_rcq_setup(struct blender_submodule * p_bld,u8 * base,struct g2d_rcq_mem_info * p_rcq_info)308 int bld_rcq_setup(struct blender_submodule *p_bld, u8 *base,
309 		  struct g2d_rcq_mem_info *p_rcq_info)
310 {
311 	u8 *reg_base = base + G2D_BLD;
312 	int ret = -1;
313 
314 	if (!p_bld) {
315 		G2D_ERR_MSG("Null pointer!\n");
316 		goto OUT;
317 	}
318 
319 	p_bld->reg_info->size = sizeof(struct g2d_mixer_bld_reg);
320 	p_bld->reg_info->vir_addr = (u8 *)g2d_top_reg_memory_alloc(
321 	    p_bld->reg_info->size, (void *)&(p_bld->reg_info->phy_addr),
322 	    p_rcq_info);
323 
324 	if (!p_bld->reg_info->vir_addr) {
325 		G2D_ERR_MSG("Malloc blender reg rcq memory fail!\n");
326 		goto OUT;
327 	}
328 
329 	p_bld->reg_blks->vir_addr = p_bld->reg_info->vir_addr;
330 	p_bld->reg_blks->phy_addr = p_bld->reg_info->phy_addr;
331 	p_bld->reg_blks->size = p_bld->reg_info->size;
332 	p_bld->reg_blks->reg_addr = reg_base;
333 	ret = 0;
334 OUT:
335 	return ret;
336 }
337 
338 /**
339  * ROP2 cmd register set
340  * Index0 is selected
341  * dst mapping ch0'
342  * src mapping ch1'
343  */
bld_rop2_set(struct blender_submodule * p_bld,__u32 rop_cmd)344 __s32 bld_rop2_set(struct blender_submodule *p_bld, __u32 rop_cmd)
345 {
346 	__s32 ret = -1;
347 	struct g2d_mixer_bld_reg *p_reg = p_bld->get_reg(p_bld);
348 
349 	p_reg = p_bld->get_reg(p_bld);
350 	if (!p_reg)
351 		goto OUT;
352 
353 	if (rop_cmd == G2D_BLT_BLACKNESS) {
354 		/* blackness */
355 		/* tmpue = 0x1<<18; */
356 		p_reg->ch3_index0.dwval = 0x40000;
357 	} else if (rop_cmd == G2D_BLT_NOTMERGEPEN) {
358 		/* ~(dst | src) */
359 		/* tmpue = (0x1<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
360 		p_reg->ch3_index0.dwval = 0x41440;
361 	} else if (rop_cmd == G2D_BLT_MASKNOTPEN) {
362 		/* ~src&dst */
363 		/* tmpue = (0x1<<4) | (0x0<<10) | (0x2<<11) | (0x1<<18); */
364 		p_reg->ch3_index0.dwval = 0x41010;
365 	} else if (rop_cmd == G2D_BLT_NOTCOPYPEN) {
366 		/* ~src */
367 		/* tmpue = (0x1<<4) | (0x2<<6) | (0x2<<11) |
368 		 * (0x1<<18) | (0x1<<17);
369 		 */
370 		p_reg->ch3_index0.dwval = 0x61090;
371 	} else if (rop_cmd == G2D_BLT_MASKPENNOT) {
372 		/* src&~dst */
373 		/* tmpue = (0x1<<3) | (0x0<<10) | (0x2<<11) | (0x1<<18); */
374 		p_reg->ch3_index0.dwval = 0x41008;
375 	} else if (rop_cmd == G2D_BLT_NOT) {
376 		/* ~dst */
377 		/* tmpue = (0x1<<3) | (0x2<<6) | (0x2<<11) |
378 		 * (0x1<<18) | (0x1<<16);
379 		 */
380 		p_reg->ch3_index0.dwval = 0x51088;
381 	} else if (rop_cmd == G2D_BLT_XORPEN) {
382 		/* src xor dst */
383 		/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18); */
384 		p_reg->ch3_index0.dwval = 0x41080;
385 	} else if (rop_cmd == G2D_BLT_NOTMASKPEN) {
386 		/* ~(src & dst) */
387 		/* tmpue = (0x0<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
388 		p_reg->ch3_index0.dwval = 0x41400;
389 	} else if (rop_cmd == G2D_BLT_MASKPEN) {
390 		/* src&dst */
391 		/* tmpue = (0x0<<6) | (0x2<<11) | (0x1<<18); */
392 		p_reg->ch3_index0.dwval = 0x41000;
393 	} else if (rop_cmd == G2D_BLT_NOTXORPEN) {
394 		/* ~(src xor dst) */
395 		/* tmpue = (0x2<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
396 		p_reg->ch3_index0.dwval = 0x41480;
397 	} else if (rop_cmd == G2D_BLT_NOP) {
398 		/* dst */
399 		/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
400 		p_reg->ch3_index0.dwval = 0x51080;
401 	} else if (rop_cmd == G2D_BLT_MERGENOTPEN) {
402 		/* ~dst or src */
403 		/* tmpue = (0x1<<3)| (0x1<<6) | (0x2<<11) | (0x1<<18) */
404 		/* write_wvalue(ROP_INDEX0, 0x40A20); */
405 		p_reg->ch3_index0.dwval = 0x41048;
406 	} else if (rop_cmd == G2D_BLT_COPYPEN) {
407 		/* src */
408 		/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<17); */
409 		p_reg->ch3_index0.dwval = 0x61080;
410 	} else if (rop_cmd == G2D_BLT_MERGEPENNOT) {
411 		/* src or ~dst */
412 		/* tmpue =  (0x1<<3)| (0x1<<6) | (0x2<<11) | (0x1<<18) */
413 		p_reg->ch3_index0.dwval = 0x41048;
414 	} else if (rop_cmd == G2D_BLT_MERGEPEN) {
415 		/* src or dst */
416 		/* tmpue = (0x1<<6) | (0x1<<18) | (0x2<<11); */
417 		p_reg->ch3_index0.dwval = 0x41040;
418 	} else if (rop_cmd == G2D_BLT_WHITENESS) {
419 		/* whiteness */
420 		/* tmpue = (0x1<<18) | (0x1<<15); */
421 		p_reg->ch3_index0.dwval = 0x48000;
422 	} else
423 		goto OUT;
424 
425 	p_reg->ch3_index0.bits.index0node0 = 2; /*TODO:different with source*/
426 	p_bld->set_block_dirty(p_bld, 0, 1);
427 
428 	ret = 0;
429 OUT:
430 	return ret;
431 }
432 
433 /**
434  * ROP3 cmd register set
435  * dst mapping ch0'
436  * src mapping ch1'
437  * ptn mapping ch2'
438  * -1 return meaning that the operate is not supported by now
439  */
bld_rop3_set(struct blender_submodule * p_bld,__u32 sel,__u32 rop3_cmd)440 __s32 bld_rop3_set(struct blender_submodule *p_bld, __u32 sel, __u32 rop3_cmd)
441 {
442 	__s32 ret = -1;
443 	union g2d_mixer_rop_ch3_index0 *p_addr = NULL;
444 	struct g2d_mixer_bld_reg *p_reg = p_bld->get_reg(p_bld);
445 
446 	p_reg = p_bld->get_reg(p_bld);
447 	if (!p_reg)
448 		goto OUT;
449 
450 	if (sel == 0)
451 		p_addr = &p_reg->ch3_index0;
452 	else if (sel == 1)
453 		p_addr = &p_reg->ch3_index1;
454 	else
455 		goto OUT;
456 
457 	if (rop3_cmd == G2D_ROP3_BLACKNESS) {
458 		/* blackness */
459 		/* 0x1<<18; */
460 		p_addr->dwval = 0x40000;
461 	} else if (rop3_cmd == G2D_ROP3_NOTSRCERASE) {
462 		/* (~src) AND (~dst) */
463 		/* (0x1<<3) | (0x1<<4) | (0x1<<18) | (0x2<<11); */
464 		p_addr->dwval = 0x41018;
465 	} else if (rop3_cmd == G2D_ROP3_NOTSRCCOPY) {
466 
467 		/* ~src */
468 		/* (0x1<<4) | (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
469 		p_addr->dwval = 0x51090;
470 	} else if (rop3_cmd == G2D_ROP3_SRCERASE) {
471 		/* src AND ~dst */
472 		/* (0x1<<3) | (0x0<<6) | (0x2<<11) | (0x1<<18); */
473 		p_addr->dwval = 0x41008;
474 	} else if (rop3_cmd == G2D_ROP3_DSTINVERT) {
475 		/* ~dst */
476 		/* (0x1<<3) | (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<17); */
477 		p_addr->dwval = 0x61088;
478 	} else if (rop3_cmd == G2D_ROP3_PATINVERT) {
479 		/* ptn XOR dst */
480 		/* (0x2<<6) | (0x2<<11) | (0x1<<17) */
481 		p_addr->dwval = 0x21080;
482 	} else if (rop3_cmd == G2D_ROP3_SRCINVERT) {
483 		/* src XOR dst */
484 		/* (0x2<<6) | (0x2<<11) | (0x1<<18); */
485 		p_addr->dwval = 0x41080;
486 	} else if (rop3_cmd == G2D_ROP3_SRCAND) {
487 		/* src AND dst */
488 		/* (0x0<<6) | (0x2<<11) | (0x1<<18); */
489 		p_addr->dwval = 0x41000;
490 	} else if (rop3_cmd == G2D_ROP3_MERGEPAINT) {
491 		/* ~src OR dst */
492 		/* (0x1<<4) | (0x1<<6) | (0x2<<11) | (0x1<<18); */
493 		p_addr->dwval = 0x41050;
494 	} else if (rop3_cmd == G2D_ROP3_MERGECOPY) {
495 		/* src AND pattern */
496 		/* (0x2<<6) | (0x1<<16) */
497 		p_addr->dwval = 0x10080;
498 	} else if (rop3_cmd == G2D_ROP3_SRCCOPY) {
499 		/* src */
500 		/* (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
501 		p_addr->dwval = 0x51080;
502 	} else if (rop3_cmd == G2D_ROP3_SRCPAINT) {
503 		/* src OR dst */
504 		/* (0x1<<6) | (0x2<<11) | (0x1<<18); */
505 		p_addr->dwval = 0x41040;
506 	} else if (rop3_cmd == G2D_ROP3_PATCOPY) {
507 		/* ptn */
508 		/* (0x1<<16) | (0x1<<17) | (0x2)<<11 */
509 		p_addr->dwval = 0x31000;
510 	} else if (rop3_cmd == G2D_ROP3_PATPAINT) {
511 		/* DPSnoo */
512 		/* (0x1<<3) | (0x1<<6) | (0x1<<11) */
513 		p_addr->dwval = 0x848;
514 	} else if (rop3_cmd == G2D_ROP3_WHITENESS) {
515 		/* whiteness */
516 		p_addr->dwval = 0x48000;
517 	} else
518 		goto OUT;
519 
520 	p_bld->set_block_dirty(p_bld, 0, 1);
521 
522 	ret = 0;
523 OUT:
524 	return ret;
525 }
526 
bld_get_reg_block_num(struct blender_submodule * p_bld)527 static __u32 bld_get_reg_block_num(struct blender_submodule *p_bld)
528 {
529 	if (p_bld)
530 		return p_bld->reg_blk_num;
531 	return 0;
532 }
533 
bld_get_reg_block(struct blender_submodule * p_bld,struct g2d_reg_block ** blks)534 static __s32 bld_get_reg_block(struct blender_submodule *p_bld,
535 			    struct g2d_reg_block **blks)
536 {
537 	__s32 i = 0, ret = -1;
538 
539 	if (p_bld) {
540 		for (i = 0; i < p_bld->reg_blk_num; ++i)
541 			blks[i] = p_bld->reg_blks + i;
542 	}
543 
544 	return ret;
545 }
546 
bld_get_reg(struct blender_submodule * p_bld)547 static struct g2d_mixer_bld_reg *bld_get_reg(struct blender_submodule *p_bld)
548 {
549 #if G2D_MIXER_RCQ_USED == 1
550 	return (struct g2d_mixer_bld_reg *)(p_bld->reg_blks
551 					    ->vir_addr);
552 #else
553 	return (struct g2d_mixer_bld_reg *)(p_bld->reg_blks
554 					    ->reg_addr);
555 #endif
556 	return NULL;
557 }
558 
bld_set_block_dirty(struct blender_submodule * p_bld,__u32 blk_id,__u32 dirty)559 static void bld_set_block_dirty(struct blender_submodule *p_bld, __u32 blk_id, __u32 dirty)
560 {
561 #if G2D_MIXER_RCQ_USED == 1
562 	if (p_bld && p_bld->reg_blks->rcq_hd)
563 		p_bld->reg_blks->rcq_hd->dirty.bits.dirty = dirty;
564 	else
565 		G2D_ERR_MSG("Null pointer!\n");
566 #else
567 
568 	if (p_bld)
569 		p_bld->reg_blks->dirty = dirty;
570 	else
571 		G2D_ERR_MSG("Null pointer!\n");
572 #endif
573 }
574 
bld_get_rcq_mem_size(struct blender_submodule * p_bld)575 static __u32 bld_get_rcq_mem_size(struct blender_submodule *p_bld)
576 {
577 	return G2D_RCQ_BYTE_ALIGN(sizeof(struct g2d_mixer_bld_reg));
578 }
579 
bld_destory(struct blender_submodule * p_bld)580 static __s32 bld_destory(struct blender_submodule *p_bld)
581 {
582 	__s32 ret = -1;
583 
584 	if (p_bld) {
585 		free(p_bld->reg_blks);
586 		p_bld->reg_blks = NULL;
587 
588 		free(p_bld->reg_info);
589 		p_bld->reg_info = NULL;
590 		free(p_bld);
591 		ret = 0;
592 	}
593 
594 	return ret;
595 }
596 
597 struct blender_submodule *
g2d_bld_submodule_setup(struct g2d_mixer_frame * p_frame)598 g2d_bld_submodule_setup(struct g2d_mixer_frame *p_frame)
599 {
600 	struct blender_submodule *p_bld = NULL;
601 
602 	p_bld = hal_malloc(sizeof(struct blender_submodule));
603 
604 	if (!p_bld) {
605 		G2D_ERR_MSG("malloc wb submodule fail!\n");
606 		return NULL;
607 	}
608 	memset(p_bld, 0, sizeof(struct blender_submodule));
609 	p_bld->rcq_setup = bld_rcq_setup;
610 	p_bld->reg_blk_num = 1;
611 	p_bld->get_reg_block_num = bld_get_reg_block_num;
612 	p_bld->get_reg_block = bld_get_reg_block;
613 	p_bld->get_reg = bld_get_reg;
614 	p_bld->set_block_dirty = bld_set_block_dirty;
615 	p_bld->get_rcq_mem_size = bld_get_rcq_mem_size;
616 	p_bld->destory = bld_destory;
617 
618 	p_bld->reg_blks =
619 	    hal_malloc(sizeof(struct g2d_reg_block) * p_bld->reg_blk_num);
620 	p_bld->reg_info =
621 	    hal_malloc(sizeof(struct g2d_reg_mem_info));
622 
623 	if (!p_bld->reg_blks || !p_bld->reg_info) {
624 		G2D_ERR_MSG("malloc wb reg info fail!\n");
625 		goto FREE_WB;
626 	}
627 	memset(p_bld->reg_blks, 0, sizeof(struct g2d_reg_block) * p_bld->reg_blk_num);
628 	memset(p_bld->reg_info, 0, sizeof(struct g2d_reg_mem_info));
629 	return p_bld;
630 FREE_WB:
631 	free(p_bld->reg_blks);
632 	free(p_bld->reg_info);
633 	free(p_bld);
634 
635 	return NULL;
636 }
637