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