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