1 /*
2 * Allwinner SoCs display 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
11 /******************************************************************************
12 *All Winner Tech, All Right Reserved. 2014-2015 Copyright (c)
13 *
14 *File name :de_ccsc.c
15 *
16 *Description :display engine 2.0 channel csc basic function definition
17 *
18 *History :2014/05/16 vito cheng v0.1 Initial version
19 ******************************************************************************/
20
21 #include "de_rtmx.h"
22 #include "de_csc_type.h"
23 #include "de_vep_table.h"
24 #include "de_csc.h"
25 #include "de_enhance.h"
26
27 #define CCSC00_OFST 0xAA050
28 /* device0 channel0 (or device1 channel0 support vep) */
29 #define CCSC01_OFST 0xFA000 /* non-ncat 0xFA050 */
30 /* device0 channel1 (or device1 channel1 support vep) */
31 #define CCSC10_OFST 0xA0000
32 /* device1 channel0 not support vep */
33 #define CCSC11_OFST 0xF0000
34 /* device1 channel1 not support vep */
35 #define ICSC0_OFST 0xA0040
36 #define ICSC1_OFST 0xF0040
37
38 static volatile struct __csc_reg_t *ccsc_dev[DE_NUM][CHN_NUM];
39 static volatile struct __icsc_reg_t *icsc_dev[DE_NUM][CHN_NUM];
40 static struct de_reg_blocks csc_block[DE_NUM][CHN_NUM];
41 static struct de_reg_blocks icsc_block[DE_NUM][CHN_NUM];
42
43 static unsigned int vi_num[DE_NUM];
44 static unsigned int vep_support[DE_NUM][CHN_NUM];
45
de_ccsc_set_reg_base(unsigned int sel,unsigned int chno,void * base)46 static int de_ccsc_set_reg_base(unsigned int sel, unsigned int chno, void *base)
47 {
48 DE_INF("sel=%d, chno=%d, base=0x%p\n", sel, chno, base);
49 ccsc_dev[sel][chno] = (struct __csc_reg_t *) base;
50
51 return 0;
52 }
53
de_icsc_set_reg_base(unsigned int sel,unsigned int chno,void * base)54 static int de_icsc_set_reg_base(unsigned int sel, unsigned int chno, void *base)
55 {
56 DE_INF("sel=%d, chno=%d, base=0x%p\n", sel, chno, base);
57 icsc_dev[sel][chno] = (struct __icsc_reg_t *) base;
58
59 return 0;
60 }
61
de_ccsc_apply(unsigned int sel,unsigned int ch_id,struct disp_csc_config * config)62 int de_ccsc_apply(unsigned int sel, unsigned int ch_id,
63 struct disp_csc_config *config)
64 {
65 int csc_coeff[12];
66 unsigned int in_fmt, in_mode, out_fmt, out_mode;
67
68 /* enable FCE CSC when UI(RGB format) input */
69 if (vep_support[sel][ch_id]) {
70 if (config->in_fmt == DE_RGB && config->out_fmt == DE_RGB) {
71 icsc_dev[sel][ch_id]->bypass.bits.enable = 1;
72 icsc_block[sel][ch_id].dirty = 1;
73
74 in_fmt = DE_YUV;
75 in_mode = DE_ENHANCE;
76 out_fmt = DE_RGB;
77 out_mode = DE_BT601;
78 } else {
79 icsc_dev[sel][ch_id]->bypass.bits.enable = 0;
80 icsc_block[sel][ch_id].dirty = 1;
81
82 in_fmt = config->in_fmt;
83 in_mode = config->in_mode;
84 out_fmt = config->out_fmt;
85 out_mode = config->out_mode;
86 }
87
88 } else {
89 in_fmt = config->in_fmt;
90 in_mode = config->in_mode;
91 out_fmt = config->out_fmt;
92 out_mode = config->out_mode;
93 }
94
95 de_csc_coeff_calc(in_fmt, in_mode, out_fmt, out_mode,
96 config->brightness, config->contrast,
97 config->saturation, config->hue,
98 config->out_color_range, csc_coeff);
99
100 ccsc_dev[sel][ch_id]->c00.dwval = *(csc_coeff);
101 ccsc_dev[sel][ch_id]->c01.dwval = *(csc_coeff + 1);
102 ccsc_dev[sel][ch_id]->c02.dwval = *(csc_coeff + 2);
103 ccsc_dev[sel][ch_id]->c03.dwval = *(csc_coeff + 3) + 0x200;
104 ccsc_dev[sel][ch_id]->c10.dwval = *(csc_coeff + 4);
105 ccsc_dev[sel][ch_id]->c11.dwval = *(csc_coeff + 5);
106 ccsc_dev[sel][ch_id]->c12.dwval = *(csc_coeff + 6);
107 ccsc_dev[sel][ch_id]->c13.dwval = *(csc_coeff + 7) + 0x200;
108 ccsc_dev[sel][ch_id]->c20.dwval = *(csc_coeff + 8);
109 ccsc_dev[sel][ch_id]->c21.dwval = *(csc_coeff + 9);
110 ccsc_dev[sel][ch_id]->c22.dwval = *(csc_coeff + 10);
111 ccsc_dev[sel][ch_id]->c23.dwval = *(csc_coeff + 11) + 0x200;
112
113 ccsc_dev[sel][ch_id]->bypass.bits.enable = 1;
114 /* always enable csc */
115 csc_block[sel][ch_id].dirty = 1;
116
117 return 0;
118 }
119
de_ccsc_update_regs(unsigned int sel)120 int de_ccsc_update_regs(unsigned int sel)
121 {
122 int ch_id;
123
124 for (ch_id = 0; ch_id < vi_num[sel]; ch_id++) {
125 if (csc_block[sel][ch_id].dirty == 0x1) {
126 regwrite((void *)csc_block[sel][ch_id].off,
127 csc_block[sel][ch_id].val,
128 csc_block[sel][ch_id].size);
129 csc_block[sel][ch_id].dirty = 0x0;
130 }
131 if (vep_support[sel][ch_id]) {
132 if (icsc_block[sel][ch_id].dirty == 0x1) {
133 regwrite((void *)icsc_block[sel][ch_id].off,
134 icsc_block[sel][ch_id].val,
135 icsc_block[sel][ch_id].size);
136 icsc_block[sel][ch_id].dirty = 0x0;
137 }
138 }
139 }
140 return 0;
141 }
142
de_ccsc_init(struct disp_bsp_init_para * para)143 int de_ccsc_init(struct disp_bsp_init_para *para)
144 {
145 uintptr_t base, base_ofst;
146 void *memory;
147 int screen_id, ch_id, device_num;
148
149 device_num = de_feat_get_num_screens();
150
151 for (screen_id = 0; screen_id < device_num; screen_id++)
152 vi_num[screen_id] = de_feat_get_num_vi_chns(screen_id);
153
154 for (screen_id = 0; screen_id < device_num; screen_id++)
155 for (ch_id = 0; ch_id < vi_num[screen_id]; ch_id++) {
156 vep_support[screen_id][ch_id] =
157 de_feat_is_support_vep_by_chn(screen_id, ch_id);
158
159 if (screen_id == 0) {
160 base_ofst =
161 (ch_id == 0) ? CCSC00_OFST : CCSC01_OFST;
162 } else {
163 if (vep_support[screen_id][ch_id]) {
164 base_ofst = (ch_id == 0) ?
165 CCSC00_OFST : CCSC01_OFST;
166 } else {
167 base_ofst = (ch_id == 0) ?
168 CCSC10_OFST : CCSC11_OFST;
169 }
170 }
171
172 #if defined(CONFIG_ARCH_SUN50IW10)
173 base = para->reg_base[DISP_MOD_DE + screen_id] + (screen_id + 1)
174 * 0x00100000 + base_ofst;
175 if (screen_id)
176 base = base - 0x00100000;
177 #else
178 base = para->reg_base[DISP_MOD_DE] + (screen_id + 1)
179 * 0x00100000 + base_ofst;
180 #endif
181 memory =
182 disp_sys_malloc(sizeof(struct __csc_reg_t));
183 if (memory == NULL) {
184 DE_WRN("alloc Ccsc[%d][%d] mm fail!size=0x%x\n",
185 screen_id, ch_id,
186 (unsigned int)sizeof(struct __csc_reg_t));
187 return -1;
188 }
189
190 csc_block[screen_id][ch_id].off = base;
191 csc_block[screen_id][ch_id].val = memory;
192 csc_block[screen_id][ch_id].size = 0x40;
193 csc_block[screen_id][ch_id].dirty = 0;
194
195 de_ccsc_set_reg_base(screen_id, ch_id, memory);
196
197 /* input csc */
198 if (vep_support[screen_id][ch_id]) {
199 base_ofst = (ch_id == 0) ?
200 ICSC0_OFST : ICSC1_OFST;
201 #if defined(CONFIG_ARCH_SUN50IW10)
202 base = para->reg_base[DISP_MOD_DE + screen_id] +
203 (screen_id + 1) * 0x00100000
204 + FCE_OFST + 0x40;
205 if (screen_id)
206 base = base - 0x00100000;
207 #else
208 base = para->reg_base[DISP_MOD_DE] +
209 (screen_id + 1) * 0x00100000
210 + FCE_OFST + 0x40;
211 #endif
212 DE_INF("sel%d, Icsc_base[%d]=0x%p\n", screen_id,
213 ch_id, (void *)base);
214
215 memory =
216 disp_sys_malloc(sizeof(struct __icsc_reg_t));
217
218 icsc_block[screen_id][ch_id].off = base;
219 icsc_block[screen_id][ch_id].val = memory;
220 icsc_block[screen_id][ch_id].size = 0x04;
221 icsc_block[screen_id][ch_id].dirty = 0;
222
223 de_icsc_set_reg_base(screen_id, ch_id, memory);
224 }
225
226 }
227
228 return 0;
229 }
230
de_ccsc_exit(void)231 int de_ccsc_exit(void)
232 {
233 int screen_id, ch_id, device_num;
234
235 device_num = de_feat_get_num_screens();
236
237 for (screen_id = 0; screen_id < device_num; screen_id++)
238 vi_num[screen_id] = de_feat_get_num_vi_chns(screen_id);
239
240 for (screen_id = 0; screen_id < device_num; screen_id++) {
241 for (ch_id = 0; ch_id < vi_num[screen_id]; ch_id++) {
242 vep_support[screen_id][ch_id] =
243 de_feat_is_support_vep_by_chn(screen_id, ch_id);
244 disp_sys_free(csc_block[screen_id][ch_id].val);
245
246 /* input csc */
247 if (vep_support[screen_id][ch_id])
248 disp_sys_free(icsc_block[screen_id][ch_id].val);
249
250 }
251 }
252
253 return 0;
254 }
255
256 struct __scal_matrix4x4 {
257 __s64 x00;
258 __s64 x01;
259 __s64 x02;
260 __s64 x03;
261 __s64 x10;
262 __s64 x11;
263 __s64 x12;
264 __s64 x13;
265 __s64 x20;
266 __s64 x21;
267 __s64 x22;
268 __s64 x23;
269 __s64 x30;
270 __s64 x31;
271 __s64 x32;
272 __s64 x33;
273 };
274
in_tright_shift(int datain,unsigned int shiftbit)275 inline int in_tright_shift(int datain, unsigned int shiftbit)
276 {
277 int dataout;
278 int tmp;
279
280 tmp = (shiftbit >= 1) ? (1 << (shiftbit - 1)) : 0;
281 if (datain >= 0)
282 dataout = (datain + tmp) >> shiftbit;
283 else
284 dataout = -((-datain + tmp) >> shiftbit);
285
286 return dataout;
287 }
288
IntRightShift64(__s64 datain,unsigned int shiftbit)289 __s64 IntRightShift64(__s64 datain, unsigned int shiftbit)
290 {
291 __s64 dataout;
292 __s64 tmp;
293
294 tmp = (shiftbit >= 1) ? (1 << (shiftbit - 1)) : 0;
295 if (datain >= 0)
296 dataout = (datain + tmp) >> shiftbit;
297 else
298 dataout = -((-datain + tmp) >> shiftbit);
299
300 return dataout;
301 }
302
IDE_SCAL_MATRIC_MUL(struct __scal_matrix4x4 * in1,struct __scal_matrix4x4 * in2,struct __scal_matrix4x4 * result)303 static s32 IDE_SCAL_MATRIC_MUL(struct __scal_matrix4x4 *in1,
304 struct __scal_matrix4x4 *in2, struct __scal_matrix4x4 *result)
305 {
306
307 result->x00 =
308 IntRightShift64(in1->x00 * in2->x00 + in1->x01 * in2->x10 +
309 in1->x02 * in2->x20 + in1->x03 * in2->x30, 10);
310 result->x01 =
311 IntRightShift64(in1->x00 * in2->x01 + in1->x01 * in2->x11 +
312 in1->x02 * in2->x21 + in1->x03 * in2->x31, 10);
313 result->x02 =
314 IntRightShift64(in1->x00 * in2->x02 + in1->x01 * in2->x12 +
315 in1->x02 * in2->x22 + in1->x03 * in2->x32, 10);
316 result->x03 =
317 IntRightShift64(in1->x00 * in2->x03 + in1->x01 * in2->x13 +
318 in1->x02 * in2->x23 + in1->x03 * in2->x33, 10);
319 result->x10 =
320 IntRightShift64(in1->x10 * in2->x00 + in1->x11 * in2->x10 +
321 in1->x12 * in2->x20 + in1->x13 * in2->x30, 10);
322 result->x11 =
323 IntRightShift64(in1->x10 * in2->x01 + in1->x11 * in2->x11 +
324 in1->x12 * in2->x21 + in1->x13 * in2->x31, 10);
325 result->x12 =
326 IntRightShift64(in1->x10 * in2->x02 + in1->x11 * in2->x12 +
327 in1->x12 * in2->x22 + in1->x13 * in2->x32, 10);
328 result->x13 =
329 IntRightShift64(in1->x10 * in2->x03 + in1->x11 * in2->x13 +
330 in1->x12 * in2->x23 + in1->x13 * in2->x33, 10);
331 result->x20 =
332 IntRightShift64(in1->x20 * in2->x00 + in1->x21 * in2->x10 +
333 in1->x22 * in2->x20 + in1->x23 * in2->x30, 10);
334 result->x21 =
335 IntRightShift64(in1->x20 * in2->x01 + in1->x21 * in2->x11 +
336 in1->x22 * in2->x21 + in1->x23 * in2->x31, 10);
337 result->x22 =
338 IntRightShift64(in1->x20 * in2->x02 + in1->x21 * in2->x12 +
339 in1->x22 * in2->x22 + in1->x23 * in2->x32, 10);
340 result->x23 =
341 IntRightShift64(in1->x20 * in2->x03 + in1->x21 * in2->x13 +
342 in1->x22 * in2->x23 + in1->x23 * in2->x33, 10);
343 result->x30 =
344 IntRightShift64(in1->x30 * in2->x00 + in1->x31 * in2->x10 +
345 in1->x32 * in2->x20 + in1->x33 * in2->x30, 10);
346 result->x31 =
347 IntRightShift64(in1->x30 * in2->x01 + in1->x31 * in2->x11 +
348 in1->x32 * in2->x21 + in1->x33 * in2->x31, 10);
349 result->x32 =
350 IntRightShift64(in1->x30 * in2->x02 + in1->x31 * in2->x12 +
351 in1->x32 * in2->x22 + in1->x33 * in2->x32, 10);
352 result->x33 =
353 IntRightShift64(in1->x30 * in2->x03 + in1->x31 * in2->x13 +
354 in1->x32 * in2->x23 + in1->x33 * in2->x33, 10);
355
356 return 0;
357 }
358
359 /* normal case:
360 *display a SD video:
361 *infmt = DE_YUV, incscmod = BT_601, outfmt = DE_RGB
362 *outcscmod = BT_601, out_color_range = DISP_COLOR_RANGE_0_255
363 *display a HD video:
364 *infmt = DE_YUV, incscmod = BT_709, outfmt = DE_RGB
365 *outcscmod = BT_601, out_color_range = DISP_COLOR_RANGE_0_255
366 *display a JPEG picture:
367 *infmt = DE_YUV, incscmod = BT_YCC, outfmt = DE_RGB
368 *outcscmod = BT_601, out_color_range = DISP_COLOR_RANGE_0_255
369 *display a UI (RGB format) with ENHANCE enable
370 *infmt = DE_YUV, incscmod = BT_ENHANCE, outfmt = DE_RGB
371 *outcscmod = BT_601, out_color_range = DISP_COLOR_RANGE_0_255
372 *output to TV with HDMI in RGB mode:
373 *infmt = DE_RGB, incscmod = BT_601, outfmt = DE_RGB
374 *outcscmod = BT_601, out_color_range = DISP_COLOR_RANGE_16_235
375 *output to PC with HDMI in RGB mode:
376 *infmt = DE_RGB, incscmod = BT_601, outfmt = DE_RGB
377 *outcscmod = BT_601, out_color_range = DISP_COLOR_RANGE_0_255
378 *output to TV with HDMI in YCbCr mode, 480i/576i/480p/576p:
379 *infmt = DE_RGB, incscmod = BT_601, outfmt = DE_YUV, outcscmod = BT_601
380 *out_color_range = DISP_COLOR_RANGE_0_255
381 *output to TV with HDMI in YCbCr mode, 720p/1080p/2160p:
382 *infmt = DE_RGB, incscmod = BT_601, outfmt = DE_YUV
383 *outcscmod = BT_709, out_color_range = DISP_COLOR_RANGE_0_255
384 *output to TV with CVBS:
385 *infmt = DE_RGB, incscmod = BT_601, outfmt = DE_YUV
386 *outcscmod = BT_601, out_color_range = DISP_COLOR_RANGE_0_255
387 *bypass:
388 *outfmt = infmt, outcscmod = incscmod
389 *out_color_range = DISP_COLOR_RANGE_0_255
390 *brightness=contrast=saturation=hue=50
391 */
de_csc_coeff_calc(unsigned int infmt,unsigned int incscmod,unsigned int outfmt,unsigned int outcscmod,unsigned int brightness,unsigned int contrast,unsigned int saturation,unsigned int hue,unsigned int out_color_range,int * csc_coeff)392 int de_csc_coeff_calc(unsigned int infmt, unsigned int incscmod,
393 unsigned int outfmt, unsigned int outcscmod,
394 unsigned int brightness, unsigned int contrast,
395 unsigned int saturation, unsigned int hue,
396 unsigned int out_color_range, int *csc_coeff)
397 {
398 struct __scal_matrix4x4 *enhancecoeff, *tmpcoeff;
399 struct __scal_matrix4x4 *coeff[5], *in0coeff, *in1coeff;
400 int oper, i;
401 int i_bright, i_contrast, i_saturation, i_hue, sinv, cosv;
402
403 oper = 0;
404
405 enhancecoeff = disp_sys_malloc(sizeof(struct __scal_matrix4x4));
406 tmpcoeff = disp_sys_malloc(sizeof(struct __scal_matrix4x4));
407 in0coeff = disp_sys_malloc(sizeof(struct __scal_matrix4x4));
408
409 if (!enhancecoeff || !tmpcoeff || !in0coeff) {
410 DE_WRN("kmalloc fail!\n");
411 goto err;
412 }
413 /* BYPASS */
414 if (infmt == outfmt && incscmod == outcscmod
415 && out_color_range == DISP_COLOR_RANGE_0_255 && brightness == 50
416 && contrast == 50 && saturation == 50 && hue == 50) {
417 memcpy(csc_coeff, bypass_csc, 48);
418 goto err;
419 }
420 /* NON-BYPASS */
421 if (infmt == DE_RGB) {
422 /* convert to YCbCr */
423 if (outfmt == DE_RGB) {
424 coeff[oper] = (struct __scal_matrix4x4 *) (r2y + 0x20);
425 oper++;
426 } else {
427 if (outcscmod == DE_BT601) {
428 coeff[oper] = (struct __scal_matrix4x4 *) (r2y);
429 oper++;
430 } else if (outcscmod == DE_BT709) {
431 coeff[oper] = (struct __scal_matrix4x4 *)
432 (r2y + 0x20);
433 oper++;
434 }
435 }
436 } else {
437 if (incscmod != outcscmod && outfmt == DE_YUV) {
438 if (incscmod == DE_BT601 && outcscmod == DE_BT709) {
439 coeff[oper] = (struct __scal_matrix4x4 *) (y2y);
440 oper++;
441 } else if (incscmod == DE_BT709
442 && outcscmod == DE_BT601) {
443 coeff[oper] = (struct __scal_matrix4x4 *)
444 (y2y + 0x20);
445 oper++;
446 }
447 }
448 }
449
450 if (brightness != 50 || contrast != 50
451 || saturation != 50 || hue != 50) {
452 brightness = brightness > 100 ? 100 : brightness;
453 contrast = contrast > 100 ? 100 : contrast;
454 saturation = saturation > 100 ? 100 : saturation;
455 hue = hue > 100 ? 100 : hue;
456
457 i_bright = (int)(brightness * 64 / 100);
458 i_saturation = (int)(saturation * 64 / 100);
459 i_contrast = (int)(contrast * 64 / 100);
460 i_hue = (int)(hue * 64 / 100);
461
462 sinv = sin_cos[i_hue & 0x3f];
463 cosv = sin_cos[64 + (i_hue & 0x3f)];
464
465 /* calculate enhance matrix */
466 enhancecoeff->x00 = i_contrast << 7;
467 enhancecoeff->x01 = 0;
468 enhancecoeff->x02 = 0;
469 enhancecoeff->x03 =
470 (((i_bright - 32) + 16) << 12) - (i_contrast << 11);
471 enhancecoeff->x10 = 0;
472 enhancecoeff->x11 = (i_contrast * i_saturation * cosv) >> 5;
473 enhancecoeff->x12 = (i_contrast * i_saturation * sinv) >> 5;
474 enhancecoeff->x13 =
475 (1 << 19) - ((enhancecoeff->x11 + enhancecoeff->x12) << 7);
476 enhancecoeff->x20 = 0;
477 enhancecoeff->x21 = (-i_contrast * i_saturation * sinv) >> 5;
478 enhancecoeff->x22 = (i_contrast * i_saturation * cosv) >> 5;
479 enhancecoeff->x23 =
480 (1 << 19) - ((enhancecoeff->x22 + enhancecoeff->x21) << 7);
481 enhancecoeff->x30 = 0;
482 enhancecoeff->x31 = 0;
483 enhancecoeff->x32 = 0;
484 enhancecoeff->x33 = 4096;
485
486 coeff[oper] = enhancecoeff;
487 oper++;
488
489 }
490
491 if (outfmt == DE_RGB) {
492 if (infmt == DE_RGB) {
493 coeff[oper] = (struct __scal_matrix4x4 *) (y2r + 0x20);
494 oper++;
495
496 if (out_color_range == DISP_COLOR_RANGE_16_235) {
497 coeff[oper] = (struct __scal_matrix4x4 *) (r2r);
498 oper++;
499 }
500 } else {
501 if (out_color_range == DISP_COLOR_RANGE_16_235) {
502 if (incscmod == DE_BT601) {
503 coeff[oper] =
504 (struct __scal_matrix4x4 *)
505 (y2r + 0x80);
506 oper++;
507 } else if (incscmod == DE_BT709) {
508 coeff[oper] =
509 (struct __scal_matrix4x4 *)
510 (y2r + 0xa0);
511 oper++;
512 }
513 } else {
514 if (incscmod == DE_BT601) {
515 coeff[oper] =
516 (struct __scal_matrix4x4 *) (y2r);
517 oper++;
518 } else if (incscmod == DE_BT709) {
519 coeff[oper] =
520 (struct __scal_matrix4x4 *)
521 (y2r + 0x20);
522 oper++;
523 } else if (incscmod == DE_YCC) {
524 coeff[oper] =
525 (struct __scal_matrix4x4 *)
526 (y2r + 0x40);
527 oper++;
528 } else if (incscmod == DE_ENHANCE) {
529 coeff[oper] =
530 (struct __scal_matrix4x4 *)
531 (y2r + 0x60);
532 oper++;
533 }
534 }
535 }
536 }
537 /* matrix multiply */
538 if (oper == 0) {
539 csc_coeff = bypass_csc;
540 } else if (oper == 1) {
541 for (i = 0; i < 12; i++)
542 *(csc_coeff + i) =
543 IntRightShift64((int)(*((__s64 *) coeff[0] + i)),
544 oper << 1);
545 } else {
546 memcpy((void *)in0coeff, (void *)coeff[0],
547 sizeof(struct __scal_matrix4x4));
548 for (i = 1; i < oper; i++) {
549 in1coeff = coeff[i];
550 IDE_SCAL_MATRIC_MUL(in1coeff, in0coeff, tmpcoeff);
551 memcpy((void *)in0coeff, (void *)tmpcoeff,
552 sizeof(struct __scal_matrix4x4));
553 }
554
555 for (i = 0; i < 12; i++)
556 *(csc_coeff + i) =
557 IntRightShift64((int)(*((__s64 *) tmpcoeff + i)),
558 oper << 1);
559 }
560
561 err:
562 disp_sys_free(in0coeff);
563 disp_sys_free(tmpcoeff);
564 disp_sys_free(enhancecoeff);
565
566 return 0;
567
568 }
569