rk3368 lcdc: overlay mode depend on screen color mode
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / iep / hw_iep_reg.c
1 /* 
2  * Copyright (C) 2013 ROCKCHIP, Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  * 
13  */
14
15 #include <linux/delay.h>
16 #include <linux/slab.h>
17 #include "hw_iep_reg.h"
18 #include "iep.h"
19 #include "hw_iep_config_addr.h"
20
21 static void iep_config_src_size(struct IEP_MSG *iep_msg)
22 {
23         IEP_REGB_SRC_IMG_WIDTH(iep_msg->base, iep_msg->src.act_w - 1);
24         IEP_REGB_SRC_IMG_HEIGHT(iep_msg->base, iep_msg->src.act_h - 1);
25 #ifdef IEP_PRINT_INFO
26         IEP_DBG(" //==source image size config===================//\n\n");
27         IEP_DBG("sw_src_img_height          = %d;//source image height \n",
28                 iep_msg->src.act_h - 1);
29         IEP_DBG("sw_src_img_width           = %d;//source image width \n\n",
30                 iep_msg->src.act_w - 1);
31 #endif
32 }
33
34 static void iep_config_dst_size(struct IEP_MSG *iep_msg)
35 {
36         IEP_REGB_DST_IMG_WIDTH(iep_msg->base, iep_msg->dst.act_w - 1);
37         IEP_REGB_DST_IMG_HEIGHT(iep_msg->base, iep_msg->dst.act_h - 1);
38 #ifdef IEP_PRINT_INFO
39         IEP_DBG(" //==destination image size config===================//\n\n");
40         IEP_DBG("sw_dst_img_height          = %d;//source image height \n",
41                 iep_msg->dst.act_h - 1);
42         IEP_DBG("sw_dst_img_width           = %d;//source image width \n",
43                 iep_msg->dst.act_w - 1);
44 #endif
45 }
46
47 static void iep_config_dst_width_tile(struct IEP_MSG *iep_msg)
48 {
49         /*IEP_REGB_DST_IMG_WIDTH_TILE0();
50         IEP_REGB_DST_IMG_WIDTH_TILE1();
51         IEP_REGB_DST_IMG_WIDTH_TILE2();
52         IEP_REGB_DST_IMG_WIDTH_TILE3();*/
53 #ifdef IEP_PRINT_INFO
54         IEP_DBG("sw_dst_width_tile0         = 0;\n");
55         IEP_DBG("sw_dst_width_tile1         = 0;\n");
56         IEP_DBG("sw_dst_width_tile2         = 0;\n");
57         IEP_DBG("sw_dst_width_tile3         = 0;\n\n");
58 #endif
59 }
60
61 static void iep_config_dst_fmt(struct IEP_MSG *iep_msg)
62 {
63         unsigned int dst_fmt = 0;
64         unsigned int dst_rgb_swap = 0;
65         unsigned int dst_yuv_swap = 0;
66         switch (iep_msg->dst.format) {
67         case IEP_FORMAT_ARGB_8888 :
68                 IEP_REGB_DST_FMT(iep_msg->base, 0);
69                 IEP_REGB_DST_RGB_SWAP(iep_msg->base, 0);
70                 dst_fmt = 0;
71                 dst_rgb_swap = 0;
72                 dst_yuv_swap = 0;
73                 break;
74         case IEP_FORMAT_ABGR_8888 :
75                 IEP_REGB_DST_FMT(iep_msg->base, 0);
76                 IEP_REGB_DST_RGB_SWAP(iep_msg->base, 1);
77                 dst_fmt = 0;
78                 dst_rgb_swap = 1;
79                 dst_yuv_swap = 0;
80                 break;
81         case IEP_FORMAT_RGBA_8888 :
82                 IEP_REGB_DST_FMT(iep_msg->base, 0);
83                 IEP_REGB_DST_RGB_SWAP(iep_msg->base, 2);
84                 dst_fmt = 0;
85                 dst_rgb_swap = 2;
86                 dst_yuv_swap = 0;
87                 break;
88         case IEP_FORMAT_BGRA_8888 :
89                 IEP_REGB_DST_FMT(iep_msg->base, 0);
90                 IEP_REGB_DST_RGB_SWAP(iep_msg->base, 3);
91                 dst_fmt = 0;
92                 dst_rgb_swap = 3;
93                 dst_yuv_swap = 0;
94                 break;
95         case IEP_FORMAT_RGB_565 :
96                 IEP_REGB_DST_FMT(iep_msg->base, 1);
97                 IEP_REGB_DST_RGB_SWAP(iep_msg->base, 0);
98                 dst_fmt = 1;
99                 dst_rgb_swap = 0;
100                 dst_yuv_swap = 0;
101                 break;
102         case IEP_FORMAT_BGR_565 :
103                 IEP_REGB_DST_FMT(iep_msg->base, 1);
104                 IEP_REGB_DST_RGB_SWAP(iep_msg->base, 1);
105                 dst_fmt = 1;
106                 dst_rgb_swap = 1;
107                 dst_yuv_swap = 0;
108                 break;
109         case IEP_FORMAT_YCbCr_422_SP :
110                 IEP_REGB_DST_FMT(iep_msg->base, 2);
111                 IEP_REGB_DST_YUV_SWAP(iep_msg->base, 0);
112                 dst_fmt = 2;
113                 dst_yuv_swap = 0;
114                 break;
115         case IEP_FORMAT_YCbCr_422_P :
116                 IEP_REGB_DST_FMT(iep_msg->base, 2);
117                 IEP_REGB_DST_YUV_SWAP(iep_msg->base, 2);
118                 dst_fmt = 2;
119                 dst_yuv_swap = 2;
120                 break;
121         case IEP_FORMAT_YCbCr_420_SP :
122                 IEP_REGB_DST_FMT(iep_msg->base, 3);
123                 IEP_REGB_DST_YUV_SWAP(iep_msg->base, 0);
124                 dst_fmt = 3;
125                 dst_yuv_swap = 0;
126                 break;
127         case IEP_FORMAT_YCbCr_420_P :
128                 IEP_REGB_DST_FMT(iep_msg->base, 3);
129                 IEP_REGB_DST_YUV_SWAP(iep_msg->base, 2);
130                 dst_fmt = 3;
131                 dst_yuv_swap = 2;
132                 break;
133         case IEP_FORMAT_YCrCb_422_SP :
134                 IEP_REGB_DST_FMT(iep_msg->base, 2);
135                 IEP_REGB_DST_YUV_SWAP(iep_msg->base, 1);
136                 dst_fmt = 2;
137                 dst_yuv_swap = 1;
138                 break;
139         case IEP_FORMAT_YCrCb_422_P :
140                 IEP_REGB_DST_FMT(iep_msg->base, 2);
141                 IEP_REGB_DST_YUV_SWAP(iep_msg->base, 2);
142                 dst_fmt = 2;
143                 dst_yuv_swap = 2;
144                 break;
145         case IEP_FORMAT_YCrCb_420_SP :
146                 IEP_REGB_DST_FMT(iep_msg->base, 3);
147                 IEP_REGB_DST_YUV_SWAP(iep_msg->base, 1);
148                 dst_fmt = 3;
149                 dst_yuv_swap = 1;
150                 break;
151         case IEP_FORMAT_YCrCb_420_P :
152                 IEP_REGB_DST_FMT(iep_msg->base, 3);
153                 IEP_REGB_DST_YUV_SWAP(iep_msg->base, 2);
154                 dst_fmt = 3;
155                 dst_yuv_swap = 2;
156                 break;
157         default:
158                 break;
159         }
160 #ifdef IEP_PRINT_INFO
161         IEP_DBG(" //==destination data format config============//\n\n");
162         IEP_DBG("sw_dst_yuv_swap            = %d;//0:sp uv; 1:sp vu; 2:p ;"
163                 " 3:p;\n",
164                 dst_yuv_swap);
165         IEP_DBG("sw_dst_rgb_swap            = %d;//if ARGB 0:argb; "
166                 "1,abgr; 2:rgba; 3:bgra; if rgb565: 0,2:rgb; 1,3:bgr;\n",
167                 dst_rgb_swap);
168         IEP_DBG("sw_dst_fmt                 = %d;//0:argb; 1:rgb565; 2:yuv422;"
169                 " 3:yuv420;\n\n", dst_fmt);
170 #endif
171 }
172
173 static void iep_config_src_fmt(struct IEP_MSG *iep_msg)
174 {
175         unsigned int src_fmt = 0;
176         unsigned int src_rgb_swap = 0;
177         unsigned int src_yuv_swap = 0;
178         switch (iep_msg->src.format) {
179         case IEP_FORMAT_ARGB_8888 :
180                 IEP_REGB_SRC_FMT(iep_msg->base, 0);
181                 IEP_REGB_SRC_RGB_SWAP(iep_msg->base, 0);
182                 src_fmt = 0;
183                 src_rgb_swap = 0;
184                 break;
185         case IEP_FORMAT_ABGR_8888 :
186                 IEP_REGB_SRC_FMT(iep_msg->base, 0);
187                 IEP_REGB_SRC_RGB_SWAP(iep_msg->base, 1);
188                 src_fmt = 0;
189                 src_rgb_swap = 1;
190                 break;
191         case IEP_FORMAT_RGBA_8888 :
192                 IEP_REGB_SRC_FMT(iep_msg->base, 0);
193                 IEP_REGB_SRC_RGB_SWAP(iep_msg->base, 2);
194                 src_fmt = 0;
195                 src_rgb_swap = 2;
196                 break;
197         case IEP_FORMAT_BGRA_8888 :
198                 IEP_REGB_SRC_FMT(iep_msg->base, 0);
199                 IEP_REGB_SRC_RGB_SWAP(iep_msg->base, 3);
200                 src_fmt = 0;
201                 src_rgb_swap = 3;
202                 break;
203         case IEP_FORMAT_RGB_565 :
204                 IEP_REGB_SRC_FMT(iep_msg->base, 1);
205                 IEP_REGB_SRC_RGB_SWAP(iep_msg->base, 0);
206                 src_fmt = 1;
207                 src_rgb_swap = 0;
208                 break;
209         case IEP_FORMAT_BGR_565 :
210                 IEP_REGB_SRC_FMT(iep_msg->base, 1);
211                 IEP_REGB_SRC_RGB_SWAP(iep_msg->base, 1);
212                 src_fmt = 1;
213                 src_rgb_swap = 1;
214                 break;
215         case IEP_FORMAT_YCbCr_422_SP :
216                 IEP_REGB_SRC_FMT(iep_msg->base, 2);
217                 IEP_REGB_SRC_YUV_SWAP(iep_msg->base, 0);
218                 src_fmt = 2;
219                 src_yuv_swap = 0;
220                 break;
221         case IEP_FORMAT_YCbCr_422_P :
222                 IEP_REGB_SRC_FMT(iep_msg->base, 2);
223                 IEP_REGB_SRC_YUV_SWAP(iep_msg->base, 2);
224                 src_fmt = 2;
225                 src_yuv_swap = 2;
226                 break;
227         case IEP_FORMAT_YCbCr_420_SP :
228                 IEP_REGB_SRC_FMT(iep_msg->base, 3);
229                 IEP_REGB_SRC_YUV_SWAP(iep_msg->base, 0);
230                 src_fmt = 3;
231                 src_yuv_swap = 0;
232                 break;
233         case IEP_FORMAT_YCbCr_420_P :
234                 IEP_REGB_SRC_FMT(iep_msg->base, 3);
235                 IEP_REGB_SRC_YUV_SWAP(iep_msg->base, 2);
236                 src_fmt = 3;
237                 src_yuv_swap = 2;
238                 break;
239         case IEP_FORMAT_YCrCb_422_SP :
240                 IEP_REGB_SRC_FMT(iep_msg->base, 2);
241                 IEP_REGB_SRC_YUV_SWAP(iep_msg->base, 1);
242                 src_fmt = 2;
243                 src_yuv_swap = 1;
244                 break;
245         case IEP_FORMAT_YCrCb_422_P :
246                 IEP_REGB_SRC_FMT(iep_msg->base, 2);
247                 IEP_REGB_SRC_YUV_SWAP(iep_msg->base, 2);
248                 src_fmt = 2;
249                 src_yuv_swap = 2;
250                 break;
251         case IEP_FORMAT_YCrCb_420_SP :
252                 IEP_REGB_SRC_FMT(iep_msg->base, 3);
253                 IEP_REGB_SRC_YUV_SWAP(iep_msg->base, 1);
254                 src_fmt = 3;
255                 src_yuv_swap = 1;
256                 break;
257         case IEP_FORMAT_YCrCb_420_P :
258                 IEP_REGB_SRC_FMT(iep_msg->base, 3);
259                 IEP_REGB_SRC_YUV_SWAP(iep_msg->base, 2);
260                 src_fmt = 3;
261                 src_yuv_swap = 2;
262                 break;
263         default:
264                 break;
265         }
266 #ifdef IEP_PRINT_INFO
267         IEP_DBG(" //==source data format config=================//\n\n");
268         IEP_DBG("sw_src_yuv_swap            = %d;//0:sp uv; 1:sp vu;"
269                 " 2:p ; 3:p;\n", src_yuv_swap);
270         IEP_DBG("sw_src_rgb_swap            = %d;//if ARGB 0:argb; 1,abgr;"
271                 " 2:rgba; 3:bgra; if rgb565: 0,2:rgb; 1,3:bgr;\n",
272                 src_rgb_swap);
273         IEP_DBG("sw_src_fmt                 = %d;//0:argb; 1:rgb565;"
274                 " 2:yuv422; 3:yuv420;\n\n", src_fmt);
275 #endif
276 }
277
278 static void iep_config_scl(struct IEP_MSG *iep_msg)
279 {
280         int scl_en;
281         int scl_sel;
282         //int vrt_fct;
283         //int hrz_fct;
284
285         unsigned int src_height, src_width, dst_height, dst_width;
286
287         int div_height_dst_src;
288         int div_width_dst_src;
289
290         src_height = iep_msg->src.act_h - 1;
291         src_width = iep_msg->src.act_w - 1;
292         dst_height = iep_msg->dst.act_h - 1;
293         dst_width = iep_msg->dst.act_w - 1;
294
295         if ((iep_msg->src.act_w == iep_msg->dst.act_w) &&
296             (iep_msg->src.act_h == iep_msg->dst.act_h))
297                 scl_en = 0;
298         else
299                 scl_en = 1;
300
301         if ((iep_msg->src.act_w >= iep_msg->dst.act_w) &&
302             (iep_msg->src.act_h >= iep_msg->dst.act_h))
303                 scl_sel = 0;
304         else if ((iep_msg->src.act_w >= iep_msg->dst.act_w) &&
305                  (iep_msg->src.act_h <= iep_msg->dst.act_h))
306                 scl_sel = 1;
307         else if ((iep_msg->src.act_w <= iep_msg->dst.act_w) &&
308                  (iep_msg->src.act_h >= iep_msg->dst.act_h))
309                 scl_sel = 2;
310         else
311                 scl_sel = 3;
312
313         //for vrt_fct
314         if ((scl_sel == 1) || (scl_sel == 3)) {
315                 div_height_dst_src = src_height * 65536 / dst_height;
316         } else {
317                 div_height_dst_src = (dst_height + 1) * 65536 /
318                         (src_height + 1);
319                 if ((div_height_dst_src * (src_height + 1)) <
320                     ((dst_height + 1) * 65536))
321                         div_height_dst_src = div_height_dst_src + 1;
322         }
323
324         if (div_height_dst_src == 65536)
325                 div_height_dst_src = 0;
326
327         //for hrz_fct
328         if ((scl_sel == 2) || (scl_sel == 3)) {
329                 div_width_dst_src = src_width * 65536 / dst_width;
330         } else {
331                 div_width_dst_src = (dst_width + 1) * 65536 / (src_width + 1);
332                 if ((div_width_dst_src * (src_width + 1)) <
333                     ((dst_width + 1) * 65536))
334                         div_width_dst_src = div_width_dst_src + 1;
335         }
336
337         if (div_width_dst_src == 65536)
338                 div_width_dst_src = 0;
339
340
341         IEP_REGB_SCL_EN(iep_msg->base, scl_en);
342
343         if (scl_en == 1) {
344                 IEP_REGB_SCL_SEL(iep_msg->base, scl_sel);
345                 IEP_REGB_SCL_UP_COE_SEL(iep_msg->base, iep_msg->scale_up_mode);
346                 IEP_REGB_SCL_VRT_FCT(iep_msg->base, div_height_dst_src);
347                 IEP_REGB_SCL_HRZ_FCT(iep_msg->base, div_width_dst_src);
348         }
349 #ifdef IEP_PRINT_INFO
350         IEP_DBG(" //==scaling config============================//\n\n");
351         IEP_DBG("sw_scl_en                  = %d;//0:disable; 1:enable;\n",
352                 scl_en);
353         IEP_DBG("sw_scl_sel                 = %d;//0:hrz down & vrt down;"
354                 "  1:hrz down & vrt up; 2:hrz up & vrt down;  3:hrz up &"
355                 " vrt up;\n", scl_sel);
356         IEP_DBG("sw_scl_up_coe_sel          = %d;//select four groups of"
357                 " up scaling coefficient\n", iep_msg->scale_up_mode);
358         IEP_DBG("sw_scl_vrt_fct             = %d;//if up-scaling,equal"
359                 " to floor(src_img_height/dst_image_height)*2^16;"
360                 " if down-scaling,equal to ceiling(dst_image_height/"
361                 "src_image_height)*2^16;\n", div_height_dst_src);
362         IEP_DBG("sw_scl_hrz_fct             = %d;//if up-scaling,equal"
363                 " to floor(src_img_widht/dst_image_width)*2^16;   if"
364                 " down-scaling,equal to ceiling(dst_image_width/"
365                 "src_image_width)*2^16  ; \n\n", div_width_dst_src);
366 #endif
367 }
368
369 static void iep_config_cg_order(struct IEP_MSG *iep_msg)
370 {
371         IEP_REGB_CON_GAM_ORDER(iep_msg->base,
372                 iep_msg->rgb_contrast_enhance_mode);
373 #ifdef IEP_PRINT_INFO
374         IEP_DBG(" //==rgb enhancement & denoise config==========//\n\n");
375         IEP_DBG("sw_con_gam_order           = %d;//0:CG(contrast/gamma"
376                 " operation)prior to DDE(de-noise/detail/edge enhance);"
377                 "  1:DDE prior to CG;\n",
378                 iep_msg->rgb_contrast_enhance_mode);
379 #endif
380 }
381
382 static void iep_config_cg(struct IEP_MSG *iep_msg)
383 {
384         unsigned i;
385         unsigned int cg_conf_addr;
386
387         IEP_REGB_RGB_CON_GAM_EN(iep_msg->base, iep_msg->rgb_cg_en);
388
389         if (iep_msg->rgb_cg_en) {
390                 cg_conf_addr = rIEP_CG_TAB_ADDR;
391
392                 for (i = 0; i < 192; i++) {
393                         WriteReg32(iep_msg->base, cg_conf_addr,
394                                 iep_msg->cg_tab[i]);
395                         cg_conf_addr += 0x04;
396                 }
397         }
398
399 #ifdef IEP_PRINT_INFO
400         IEP_DBG("sw_rgb_con_gam_en = 0;//0:contrast"
401                 " & gamma disable; 1:enable;\n",
402                 iep_msg->rgb_cg_en);
403 #endif
404 }
405
406 static void iep_config_dde(struct IEP_MSG *iep_msg)
407 {
408         IEP_REGB_RGB_ENH_SEL(iep_msg->base, iep_msg->rgb_enhance_mode);
409         IEP_REGB_ENH_THRESHOLD(iep_msg->base, iep_msg->enh_threshold);
410         IEP_REGB_ENH_ALPHA(iep_msg->base, iep_msg->enh_alpha);
411         IEP_REGB_ENH_RADIUS(iep_msg->base, iep_msg->enh_radius);
412 #ifdef IEP_PRINT_INFO
413         IEP_DBG("sw_rgb_enh_sel = %d;//0:no operation;"
414                 " 1:de-noise; 2:detail enhance; 3:edge enhance;\n",
415                 iep_msg->rgb_enhance_mode);
416 #endif
417
418 }
419
420 static void iep_config_color_enh(struct IEP_MSG *iep_msg)
421 {
422         IEP_REGB_RGB_COLOR_ENH_EN(iep_msg->base, iep_msg->rgb_color_enhance_en);
423         IEP_REGB_ENH_C_COE(iep_msg->base, iep_msg->rgb_enh_coe);
424 #ifdef IEP_PRINT_INFO
425         IEP_DBG("sw_rgb_color_enh_en = %d;//0:color enhance disable;"
426                 " 1:enable;\n\n",
427                 iep_msg->rgb_color_enhance_en);
428 #endif
429 }
430
431 static void iep_config_yuv_dns(struct IEP_MSG *iep_msg)
432 {
433         IEP_REGB_YUV_DNS_EN(iep_msg->base, iep_msg->yuv_3D_denoise_en);
434         IEP_REGB_YUV_DNS_LUMA_SPAT_SEL(iep_msg->base, 0);
435         IEP_REGB_YUV_DNS_LUMA_TEMP_SEL(iep_msg->base, 1);
436         IEP_REGB_YUV_DNS_CHROMA_SPAT_SEL(iep_msg->base, 2);
437         IEP_REGB_YUV_DNS_CHROMA_TEMP_SEL(iep_msg->base, 3);
438 #ifdef IEP_PRINT_INFO
439         IEP_DBG("//==yuv denoise config========================// \n\n");
440         IEP_DBG("sw_yuv_dns_en              = %d;//0:yuv 3d denoise disable;"
441                 " 1:enable\n\n", iep_msg->yuv_3D_denoise_en);
442 #endif
443 }
444
445
446 static void iep_config_dil(struct IEP_MSG *iep_msg)
447 {
448     int dein_mode;
449     switch (iep_msg->dein_mode) {
450     case IEP_DEINTERLACE_MODE_DISABLE:
451         dein_mode = dein_mode_bypass_dis;
452         break;
453     case IEP_DEINTERLACE_MODE_I2O1:
454         dein_mode = iep_msg->field_order == FIELD_ORDER_TOP_FIRST ? dein_mode_I2O1T : dein_mode_I2O1B;
455         break;
456     case IEP_DEINTERLACE_MODE_I4O1:
457 #if 1
458         dein_mode = iep_msg->field_order == FIELD_ORDER_TOP_FIRST ? dein_mode_I4O1B : dein_mode_I4O1T;
459 #else
460         dein_mode = iep_msg->field_order == FIELD_ORDER_TOP_FIRST ? dein_mode_I4O1T : dein_mode_I4O1B;
461 #endif
462         break;
463     case IEP_DEINTERLACE_MODE_I4O2:
464         dein_mode = dein_mode_I4O2;
465         break;
466     case IEP_DEINTERLACE_MODE_BYPASS:
467         dein_mode = dein_mode_bypass;
468         break;
469     default:
470         IEP_ERR("unknown deinterlace mode, set deinterlace mode (bypass)\n");
471         dein_mode = dein_mode_bypass;
472     }
473
474     IEP_REGB_DIL_MODE(iep_msg->base, dein_mode);
475     //hf
476     IEP_REGB_DIL_HF_EN(iep_msg->base, iep_msg->dein_high_fre_en);
477     if (iep_msg->dein_high_fre_en == 1) IEP_REGB_DIL_HF_FCT(iep_msg->base, iep_msg->dein_high_fre_fct);
478     //ei
479     IEP_REGB_DIL_EI_MODE(iep_msg->base, iep_msg->dein_ei_mode);
480     IEP_REGB_DIL_EI_SMOOTH(iep_msg->base, iep_msg->dein_ei_smooth);
481     IEP_REGB_DIL_EI_SEL(iep_msg->base, iep_msg->dein_ei_sel);
482     if (iep_msg->dein_ei_sel == 0) IEP_REGB_DIL_EI_RADIUS(iep_msg->base, iep_msg->dein_ei_radius);
483         IEP_REGB_DIL_MTN_TAB0(iep_msg->base, 0x40404040);
484         IEP_REGB_DIL_MTN_TAB1(iep_msg->base, 0x3c3e3f3f);
485         IEP_REGB_DIL_MTN_TAB2(iep_msg->base, 0x3336393b);
486         IEP_REGB_DIL_MTN_TAB3(iep_msg->base, 0x272a2d31);
487         IEP_REGB_DIL_MTN_TAB4(iep_msg->base, 0x181c2023);
488         IEP_REGB_DIL_MTN_TAB5(iep_msg->base, 0x0c0e1215);
489         IEP_REGB_DIL_MTN_TAB6(iep_msg->base, 0x03040609);
490         IEP_REGB_DIL_MTN_TAB7(iep_msg->base, 0x00000001);
491 }
492
493 static void iep_config_yuv_enh(struct IEP_MSG *iep_msg)
494 {
495         IEP_REGB_YUV_ENH_EN(iep_msg->base, iep_msg->yuv_enhance_en);
496         if (iep_msg->yuv_enhance_en == 1) {
497                 IEP_REGB_VIDEO_MODE(iep_msg->base, iep_msg->video_mode);
498                 if (iep_msg->video_mode == normal_mode) {
499                         IEP_REGB_SAT_CON(iep_msg->base, iep_msg->sat_con_int);
500                         IEP_REGB_CONTRAST(iep_msg->base,
501                                 iep_msg->contrast_int);
502                         IEP_REGB_BRIGHTNESS(iep_msg->base,
503                                 iep_msg->yuv_enh_brightness);
504                         IEP_REGB_COS_HUE(iep_msg->base, iep_msg->cos_hue_int);
505                         IEP_REGB_SIN_HUE(iep_msg->base, iep_msg->sin_hue_int);
506                 } else if (iep_msg->video_mode == color_bar) { //color bar
507                         IEP_REGB_COLOR_BAR_Y(iep_msg->base,
508                                 iep_msg->color_bar_y);
509                         IEP_REGB_COLOR_BAR_U(iep_msg->base,
510                                 iep_msg->color_bar_u);
511                         IEP_REGB_COLOR_BAR_V(iep_msg->base,
512                                 iep_msg->color_bar_v);
513                 }
514
515         }
516 }
517
518 static void iep_config_rgb2yuv(struct IEP_MSG *iep_msg)
519 {
520         unsigned char cond1, cond2;
521         unsigned int rgb2yuv_en = 0;
522
523         //rgb in,yuv out
524         cond1 = ((iep_msg->src.format <= 5) && (iep_msg->dst.format > 5)) ?
525                 1 : 0;
526
527         //rgb process,yuv out
528         cond2 = (((iep_msg->rgb_color_enhance_en == 1) ||
529                   (iep_msg->rgb_cg_en == 1) ||
530                   (iep_msg->rgb_enhance_mode != rgb_enhance_bypass)) &&
531                  (iep_msg->dst.format > 5)) ? 1 : 0;
532
533
534         if ((cond1 == 1) || (cond2 == 1)) {
535                 IEP_REGB_RGB_TO_YUV_EN(iep_msg->base, 1);
536                 rgb2yuv_en = 1;
537                 IEP_REGB_RGB2YUV_COE_SEL(iep_msg->base, iep_msg->rgb2yuv_mode);
538                 IEP_REGB_RGB2YUV_INPUT_CLIP(iep_msg->base,
539                         iep_msg->rgb2yuv_clip_en);
540         } else
541                 IEP_REGB_RGB_TO_YUV_EN(iep_msg->base, 0);
542 #ifdef IEP_PRINT_INFO
543         IEP_DBG("//==color space conversion config============//\n\n");
544         IEP_DBG("sw_rgb_to_yuv_en = %d;\n", rgb2yuv_en);
545         IEP_DBG("sw_rgb2yuv_coe_sel = %d;\n", iep_msg->rgb2yuv_mode);
546         IEP_DBG("sw_rgb2yuv_input_clip = %d;\n\n", iep_msg->rgb2yuv_clip_en);
547 #endif
548
549 }
550
551 static void iep_config_yuv2rgb(struct IEP_MSG *iep_msg)
552 {
553         unsigned char cond1, cond2;
554         unsigned int yuv2rgb_en = 0;
555
556         //yuv in,rgb out
557         cond1 = ((iep_msg->src.format > 5) &&
558                  (iep_msg->dst.format <= 5)) ? 1 : 0;
559
560         //yuv in,rgb process
561         cond2 = (((iep_msg->rgb_color_enhance_en == 1) ||
562                   (iep_msg->rgb_cg_en == 1) ||
563                   (iep_msg->rgb_enhance_mode != rgb_enhance_bypass)) &&
564                  (iep_msg->src.format > 5)) ? 1 : 0;
565
566         if ((cond1 == 1) || (cond2 == 1)) {
567                 IEP_REGB_YUV_TO_RGB_EN(iep_msg->base, 1);
568                 yuv2rgb_en = 1;
569                 IEP_REGB_YUV2RGB_COE_SEL(iep_msg->base,
570                         iep_msg->yuv2rgb_mode);
571                 IEP_REGB_YUV2RGB_INPUT_CLIP(iep_msg->base,
572                         iep_msg->yuv2rgb_clip_en);
573         } else {
574                 IEP_REGB_YUV_TO_RGB_EN(iep_msg->base, 0);
575         }
576 #ifdef IEP_PRINT_INFO
577         IEP_DBG("sw_yuv_to_rgb_en           = %d;\n", yuv2rgb_en);
578         IEP_DBG("sw_yuv2rgb_coe_sel         = %d;\n", iep_msg->yuv2rgb_mode);
579         IEP_DBG("sw_yuv2rgb_input_clip = %d;\n\n", iep_msg->yuv2rgb_clip_en);
580 #endif
581 }
582
583 static void iep_config_dither_up(struct IEP_MSG *iep_msg)
584 {
585         unsigned int dither_up = 0;
586         if ((iep_msg->src.format == IEP_FORMAT_RGB_565) ||
587             (iep_msg->src.format == IEP_FORMAT_BGR_565)) {
588                 IEP_REGB_DITHER_UP_EN(iep_msg->base, iep_msg->dither_up_en);
589                 dither_up = iep_msg->dither_up_en;
590         } else {
591                 IEP_REGB_DITHER_UP_EN(iep_msg->base, 0);
592         }
593 #ifdef IEP_PRINT_INFO
594         IEP_DBG("//==dither config=============================//\n\n");
595         IEP_DBG("sw_dither_up_en            = %d;\n", dither_up);
596 #endif
597 }
598
599 static void iep_config_dither_down(struct IEP_MSG *iep_msg)
600 {
601         unsigned int dither_down = 0;
602         if ((iep_msg->dst.format == IEP_FORMAT_RGB_565) ||
603             (iep_msg->dst.format == IEP_FORMAT_BGR_565)) {
604                 IEP_REGB_DITHER_DOWN_EN(iep_msg->base, 1);
605                 dither_down = 1;
606         } else {
607                 IEP_REGB_DITHER_DOWN_EN(iep_msg->base, 0);
608         }
609 #ifdef IEP_PRINT_INFO
610         IEP_DBG("sw_dither_down_en = %d;\n\n", dither_down);
611 #endif
612 }
613
614 static void iep_config_glb_alpha(struct IEP_MSG *iep_msg)
615 {
616         IEP_REGB_GLB_ALPHA(iep_msg->base, iep_msg->global_alpha_value);
617 #ifdef IEP_PRINT_INFO
618         IEP_DBG("//==global alpha for ARGB config=============//\n\n");
619         IEP_DBG("sw_glb_alpha = %d;//global alpha value for output ARGB\n\n",
620                 iep_msg->global_alpha_value);
621 #endif
622 }
623
624 static void iep_config_vir_line(struct IEP_MSG *iep_msg)
625 {
626         unsigned int src_vir_w;
627         unsigned int dst_vir_w;
628
629         switch (iep_msg->src.format) {
630         case IEP_FORMAT_ARGB_8888 :
631                 src_vir_w = iep_msg->src.vir_w;
632                 break;
633         case IEP_FORMAT_ABGR_8888 :
634                 src_vir_w = iep_msg->src.vir_w;
635                 break;
636         case IEP_FORMAT_RGBA_8888 :
637                 src_vir_w = iep_msg->src.vir_w;
638                 break;
639         case IEP_FORMAT_BGRA_8888 :
640                 src_vir_w = iep_msg->src.vir_w;
641                 break;
642         case IEP_FORMAT_RGB_565 :
643                 if (iep_msg->src.vir_w % 2 == 1)
644                         src_vir_w = (iep_msg->src.vir_w + 1) / 2;
645                 else
646                         src_vir_w = iep_msg->src.vir_w / 2;
647                 break;
648         case IEP_FORMAT_BGR_565 :
649                 if (iep_msg->src.vir_w % 2 == 1)
650                         src_vir_w = iep_msg->src.vir_w / 2 + 1;
651                 else
652                         src_vir_w = iep_msg->src.vir_w / 2;
653                 break;
654         case IEP_FORMAT_YCbCr_422_SP :
655                 if (iep_msg->src.vir_w % 4 != 0)
656                         src_vir_w = iep_msg->src.vir_w / 4 + 1;
657                 else
658                         src_vir_w = iep_msg->src.vir_w / 4;
659                 break;
660         case IEP_FORMAT_YCbCr_422_P :
661                 if (iep_msg->src.vir_w % 4 != 0)
662                         src_vir_w = iep_msg->src.vir_w / 4 + 1;
663                 else
664                         src_vir_w = iep_msg->src.vir_w / 4;
665                 break;
666         case IEP_FORMAT_YCbCr_420_SP :
667                 if (iep_msg->src.vir_w % 4 != 0)
668                         src_vir_w = iep_msg->src.vir_w / 4 + 1;
669                 else
670                         src_vir_w = iep_msg->src.vir_w / 4;
671                 break;
672         case IEP_FORMAT_YCbCr_420_P :
673                 if (iep_msg->src.vir_w % 4 != 0)
674                         src_vir_w = iep_msg->src.vir_w / 4 + 1;
675                 else
676                         src_vir_w = iep_msg->src.vir_w / 4;
677                 break;
678         case IEP_FORMAT_YCrCb_422_SP :
679                 if (iep_msg->src.vir_w % 4 != 0)
680                         src_vir_w = iep_msg->src.vir_w / 4 + 1;
681                 else
682                         src_vir_w = iep_msg->src.vir_w / 4;
683                 break;
684         case IEP_FORMAT_YCrCb_422_P :
685                 if (iep_msg->src.vir_w % 4 != 0)
686                         src_vir_w = iep_msg->src.vir_w / 4 + 1;
687                 else
688                         src_vir_w = iep_msg->src.vir_w / 4;
689                 break;
690         case IEP_FORMAT_YCrCb_420_SP :
691                 if (iep_msg->src.vir_w % 4 != 0)
692                         src_vir_w = iep_msg->src.vir_w / 4 + 1;
693                 else
694                         src_vir_w = iep_msg->src.vir_w / 4;
695                 break;
696         case IEP_FORMAT_YCrCb_420_P :
697                 if (iep_msg->src.vir_w % 4 != 0)
698                         src_vir_w = iep_msg->src.vir_w / 4 + 1;
699                 else
700                         src_vir_w = iep_msg->src.vir_w / 4;
701                 break;
702         default:
703                 IEP_ERR("Unkown format,"
704                         "set the source image virtual width 0\n");
705                 src_vir_w = 0;
706                 break;
707         }
708
709         switch (iep_msg->dst.format) {
710         case IEP_FORMAT_ARGB_8888 :
711                 dst_vir_w = iep_msg->dst.vir_w;
712                 break;
713         case IEP_FORMAT_ABGR_8888 :
714                 dst_vir_w = iep_msg->dst.vir_w;
715                 break;
716         case IEP_FORMAT_RGBA_8888 :
717                 dst_vir_w = iep_msg->dst.vir_w;
718                 break;
719         case IEP_FORMAT_BGRA_8888 :
720                 dst_vir_w = iep_msg->dst.vir_w;
721                 break;
722         case IEP_FORMAT_RGB_565 :
723                 if (iep_msg->dst.vir_w % 2 == 1)
724                         dst_vir_w = (iep_msg->dst.vir_w + 1) / 2;
725                 else
726                         dst_vir_w = iep_msg->dst.vir_w / 2;
727                 break;
728         case IEP_FORMAT_BGR_565 :
729                 if (iep_msg->dst.vir_w % 2 == 1)
730                         dst_vir_w = iep_msg->dst.vir_w / 2 + 1;
731                 else
732                         dst_vir_w = iep_msg->dst.vir_w / 2;
733                 break;
734         case IEP_FORMAT_YCbCr_422_SP :
735                 if (iep_msg->dst.vir_w % 4 != 0)
736                         dst_vir_w = iep_msg->dst.vir_w / 4 + 1;
737                 else
738                         dst_vir_w = iep_msg->dst.vir_w / 4;
739                 break;
740         case IEP_FORMAT_YCbCr_422_P :
741                 if (iep_msg->dst.vir_w % 4 != 0)
742                         dst_vir_w = iep_msg->dst.vir_w / 4 + 1;
743                 else
744                         dst_vir_w = iep_msg->dst.vir_w / 4;
745                 break;
746         case IEP_FORMAT_YCbCr_420_SP :
747                 if (iep_msg->dst.vir_w % 4 != 0)
748                         dst_vir_w = iep_msg->dst.vir_w / 4 + 1;
749                 else
750                         dst_vir_w = iep_msg->dst.vir_w / 4;
751                 break;
752         case IEP_FORMAT_YCbCr_420_P :
753                 if (iep_msg->dst.vir_w % 4 != 0)
754                         dst_vir_w = iep_msg->dst.vir_w / 4 + 1;
755                 else
756                         dst_vir_w = iep_msg->dst.vir_w / 4;
757                 break;
758         case IEP_FORMAT_YCrCb_422_SP :
759                 if (iep_msg->dst.vir_w % 4 != 0)
760                         dst_vir_w = iep_msg->dst.vir_w / 4 + 1;
761                 else
762                         dst_vir_w = iep_msg->dst.vir_w / 4;
763                 break;
764         case IEP_FORMAT_YCrCb_422_P :
765                 if (iep_msg->dst.vir_w % 4 != 0)
766                         dst_vir_w = iep_msg->dst.vir_w / 4 + 1;
767                 else
768                         dst_vir_w = iep_msg->dst.vir_w / 4;
769                 break;
770         case IEP_FORMAT_YCrCb_420_SP :
771                 if (iep_msg->dst.vir_w % 4 != 0)
772                         dst_vir_w = iep_msg->dst.vir_w / 4 + 1;
773                 else
774                         dst_vir_w = iep_msg->dst.vir_w / 4;
775                 break;
776         case IEP_FORMAT_YCrCb_420_P :
777                 if (iep_msg->dst.vir_w % 4 != 0)
778                         dst_vir_w = iep_msg->dst.vir_w / 4 + 1;
779                 else
780                         dst_vir_w = iep_msg->dst.vir_w / 4;
781                 break;
782         default:
783                 IEP_ERR("Unkown format, set the destination"
784                         " image virtual width 0\n");
785                 dst_vir_w = 0;
786                 break;
787         }
788         IEP_REGB_DST_VIR_LINE_WIDTH(iep_msg->base, dst_vir_w);
789         IEP_REGB_SRC_VIR_LINE_WIDTH(iep_msg->base, src_vir_w);
790 }
791
792 static void iep_config_src_addr(struct IEP_MSG *iep_msg)
793 {
794         u32 src_addr_yrgb;
795         u32 src_addr_cbcr;
796         u32 src_addr_cr;
797         u32 src_addr_y1;
798         u32 src_addr_cbcr1;
799         u32 src_addr_cr1;
800         u32 src_addr_y_itemp;
801         u32 src_addr_cbcr_itemp;
802         u32 src_addr_cr_itemp;
803         u32 src_addr_y_ftemp;
804         u32 src_addr_cbcr_ftemp;
805         u32 src_addr_cr_ftemp;
806         unsigned int offset_addr_y = 0;
807         unsigned int offset_addr_uv = 0;
808         unsigned int offset_addr_v = 0;
809         //unsigned int offset_addr_y_w = 0;
810         unsigned int offset_addr_uv_w = 0;
811         unsigned int offset_addr_v_w = 0;
812         //unsigned int offset_addr_y_h = 0;
813         unsigned int offset_addr_uv_h = 0;
814         unsigned int offset_addr_v_h = 0;
815
816         unsigned int offset_x_equ_uv;
817         unsigned int offset_x_u_byte;
818         unsigned int offset_x_v_byte;
819         unsigned int vir_w_euq_uv;
820         unsigned int line_u_byte;
821         unsigned int line_v_byte;
822         unsigned int offset_y_equ_420_uv = 0;
823
824         //**********************************************//
825         //***********y addr offset**********************//
826         //**********************************************//
827         if (iep_msg->src.format <= 3) {
828                 offset_addr_y = iep_msg->src.y_off * 4 *
829                         iep_msg->src.vir_w + iep_msg->src.x_off * 4;
830         } else if (iep_msg->src.format <= 5) {
831                 offset_addr_y = iep_msg->src.y_off * 2 *
832                         iep_msg->src.vir_w + iep_msg->src.x_off * 2;
833         } else {
834                 offset_addr_y = iep_msg->src.y_off *
835                         iep_msg->src.vir_w + iep_msg->src.x_off;
836         }
837
838         //**********************************************//
839         //***********uv addr offset*********************//
840         //**********************************************//
841         // note: image size align to even when image format is yuv
842
843         //----------offset_w--------//
844         if (iep_msg->src.x_off % 2 == 1)
845                 offset_x_equ_uv = iep_msg->src.x_off + 1;
846         else
847                 offset_x_equ_uv = iep_msg->src.x_off;
848
849         offset_x_u_byte = offset_x_equ_uv / 2;
850         offset_x_v_byte = offset_x_equ_uv / 2;
851
852         if ((iep_msg->src.format == IEP_FORMAT_YCbCr_422_SP) ||
853             (iep_msg->src.format == IEP_FORMAT_YCbCr_420_SP)
854                 || (iep_msg->src.format == IEP_FORMAT_YCrCb_422_SP) ||
855             (iep_msg->src.format == IEP_FORMAT_YCrCb_420_SP))
856                 offset_addr_uv_w = offset_x_u_byte + offset_x_v_byte;
857         else {
858                 offset_addr_uv_w = offset_x_u_byte;
859                 offset_addr_v_w = offset_x_v_byte;
860         }
861
862         //----------offset_h--------//
863         if (iep_msg->src.vir_w % 2 == 1)
864                 vir_w_euq_uv = iep_msg->src.vir_w + 1;
865         else
866                 vir_w_euq_uv = iep_msg->src.vir_w;
867
868         line_u_byte = vir_w_euq_uv / 2;
869         line_v_byte = vir_w_euq_uv / 2;
870
871         if (iep_msg->src.y_off % 2 == 1)
872                 offset_y_equ_420_uv = iep_msg->src.y_off + 1;
873         else
874                 offset_y_equ_420_uv = iep_msg->src.y_off;
875
876         switch (iep_msg->src.format) {
877         case IEP_FORMAT_YCbCr_422_SP :
878                 offset_addr_uv_h = (line_u_byte + line_v_byte) *
879                         iep_msg->src.y_off;
880                 break;
881         case IEP_FORMAT_YCbCr_422_P :
882                 offset_addr_uv_h = line_u_byte * iep_msg->src.y_off;
883                 offset_addr_v_h = line_v_byte * iep_msg->src.y_off;
884                 break;
885         case IEP_FORMAT_YCbCr_420_SP :
886                 offset_addr_uv_h = (line_u_byte + line_v_byte) *
887                         offset_y_equ_420_uv / 2;
888                 break;
889         case IEP_FORMAT_YCbCr_420_P :
890                 offset_addr_uv_h = line_u_byte * offset_y_equ_420_uv / 2;
891                 offset_addr_v_h = line_v_byte * offset_y_equ_420_uv / 2;
892                 break;
893         case IEP_FORMAT_YCrCb_422_SP :
894                 offset_addr_uv_h = (line_u_byte + line_v_byte) *
895                         iep_msg->src.y_off;
896                 break;
897         case IEP_FORMAT_YCrCb_422_P :
898                 offset_addr_uv_h = line_u_byte * iep_msg->src.y_off;
899                 offset_addr_v_h = line_v_byte * iep_msg->src.y_off;
900                 break;
901         case IEP_FORMAT_YCrCb_420_SP :
902                 offset_addr_uv_h = (line_u_byte + line_v_byte) *
903                         offset_y_equ_420_uv / 2;
904                 break;
905         case IEP_FORMAT_YCrCb_420_P :
906                 offset_addr_uv_h = line_u_byte * offset_y_equ_420_uv / 2;
907                 offset_addr_v_h = line_v_byte * offset_y_equ_420_uv / 2;
908                 break;
909         default:
910                 break;
911         }
912         //----------offset u/v addr--------//
913
914         offset_addr_uv = offset_addr_uv_w + offset_addr_uv_h;
915         offset_addr_v  = offset_addr_v_w + offset_addr_v_h;
916         //**********************************************//
917         //***********yuv address   *********************//
918         //**********************************************//
919         src_addr_yrgb = ((u32)iep_msg->src.mem_addr) + offset_addr_y;
920         src_addr_cbcr = ((u32)iep_msg->src.uv_addr) + offset_addr_uv;
921         src_addr_cr = ((u32)iep_msg->src.v_addr) + offset_addr_v;
922
923         // former frame when processing deinterlace
924         src_addr_y1 = ((u32)iep_msg->src1.mem_addr) + offset_addr_y;
925         src_addr_cbcr1 = ((u32)iep_msg->src1.uv_addr) + offset_addr_uv;
926         src_addr_cr1 = ((u32)iep_msg->src1.v_addr) + offset_addr_v;
927
928         src_addr_y_itemp = ((u32)iep_msg->src_itemp.mem_addr) +
929                 offset_addr_y;
930         src_addr_cbcr_itemp = ((u32)iep_msg->src_itemp.uv_addr) +
931                 offset_addr_uv;
932         src_addr_cr_itemp = ((u32)iep_msg->src_itemp.v_addr) +
933                 offset_addr_v;
934
935         src_addr_y_ftemp = ((u32)iep_msg->src_ftemp.mem_addr) +
936                 offset_addr_y;
937         src_addr_cbcr_ftemp = ((u32)iep_msg->src_ftemp.uv_addr) +
938                 offset_addr_uv;
939         src_addr_cr_ftemp = ((u32)iep_msg->src_ftemp.v_addr) +
940                 offset_addr_v;
941
942         if ((iep_msg->dein_mode == IEP_DEINTERLACE_MODE_I4O1 ||
943              iep_msg->dein_mode == IEP_DEINTERLACE_MODE_I4O2) &&
944 #if 1
945                 iep_msg->field_order == FIELD_ORDER_BOTTOM_FIRST
946 #else
947             iep_msg->field_order == FIELD_ORDER_TOP_FIRST
948 #endif
949                 ) {
950                 IEP_REGB_SRC_ADDR_YRGB(iep_msg->base, src_addr_y1);
951                 IEP_REGB_SRC_ADDR_CBCR(iep_msg->base, src_addr_cbcr1);
952                 IEP_REGB_SRC_ADDR_CR(iep_msg->base, src_addr_cr1);
953                 IEP_REGB_SRC_ADDR_Y1(iep_msg->base, src_addr_yrgb);
954                 IEP_REGB_SRC_ADDR_CBCR1(iep_msg->base, src_addr_cbcr);
955                 IEP_REGB_SRC_ADDR_CR1(iep_msg->base, src_addr_cr);
956         } else {
957                 IEP_REGB_SRC_ADDR_YRGB(iep_msg->base, src_addr_yrgb);
958                 IEP_REGB_SRC_ADDR_CBCR(iep_msg->base, src_addr_cbcr);
959                 IEP_REGB_SRC_ADDR_CR(iep_msg->base, src_addr_cr);
960                 IEP_REGB_SRC_ADDR_Y1(iep_msg->base, src_addr_y1);
961                 IEP_REGB_SRC_ADDR_CBCR1(iep_msg->base, src_addr_cbcr1);
962                 IEP_REGB_SRC_ADDR_CR1(iep_msg->base, src_addr_cr1);
963         }
964
965         if (iep_msg->yuv_3D_denoise_en) {
966                 IEP_REGB_SRC_ADDR_Y_ITEMP(iep_msg->base,
967                         src_addr_y_itemp);
968                 IEP_REGB_SRC_ADDR_CBCR_ITEMP(iep_msg->base,
969                         src_addr_cbcr_itemp);
970                 IEP_REGB_SRC_ADDR_Y_FTEMP(iep_msg->base,
971                         src_addr_y_ftemp);
972                 IEP_REGB_SRC_ADDR_CBCR_FTEMP(iep_msg->base,
973                         src_addr_cbcr_ftemp);
974                 if ((iep_msg->src.format == IEP_FORMAT_YCbCr_422_P) ||
975                     (iep_msg->src.format == IEP_FORMAT_YCbCr_420_P)
976                         || (iep_msg->src.format == IEP_FORMAT_YCrCb_422_P) ||
977                     (iep_msg->src.format == IEP_FORMAT_YCrCb_420_P)) {
978                         IEP_REGB_SRC_ADDR_CR_ITEMP(iep_msg->base,
979                                 src_addr_cr_itemp);
980                         IEP_REGB_SRC_ADDR_CR_FTEMP(iep_msg->base,
981                                 src_addr_cr_ftemp);
982                 }
983         }
984 #ifdef IEP_PRINT_INFO
985         IEP_DBG("//-------source address for image-------// \n\n");
986         IEP_DBG("sw_src_addr_yrgb           = 32'h%x;\n", src_addr_yrgb);
987         IEP_DBG("sw_src_addr_cbcr           = 32'h%x;\n", src_addr_cbcr);
988         IEP_DBG("sw_src_addr_cr             = 32'h%x;\n", src_addr_cr);
989         IEP_DBG("sw_src_addr_y1             = 32'h%x;\n", src_addr_y1);
990         IEP_DBG("sw_src_addr_cbcr0          = 32'h%x;\n", src_addr_cbcr1);
991         IEP_DBG("sw_src_addr_cr0            = 32'h%x;\n", src_addr_cr1);
992         IEP_DBG("sw_src_addr_y_itemp        = 32'h%x;\n", src_addr_y_itemp);
993         IEP_DBG("sw_src_addr_cbcr_itemp     = 32'h%x;\n", src_addr_cbcr_itemp);
994         IEP_DBG("sw_src_addr_cr_itemp       = 32'h%x;\n", src_addr_cr_itemp);
995         IEP_DBG("sw_src_addr_y_ftemp        = 32'h%x;\n", src_addr_y_ftemp);
996         IEP_DBG("sw_src_addr_cbcr_ftemp     = 32'h%x;\n", src_addr_cbcr_ftemp);
997         IEP_DBG("sw_src_addr_cr_ftemp       = 32'h%x;\n\n", src_addr_cr_ftemp);
998 #endif
999 }
1000
1001 static void iep_config_dst_addr(struct IEP_MSG *iep_msg)
1002 {
1003         IEP_REGB_DST_ADDR_YRGB(iep_msg->base, (u32)iep_msg->dst.mem_addr);
1004         IEP_REGB_DST_ADDR_CBCR(iep_msg->base, (u32)iep_msg->dst.uv_addr);
1005         IEP_REGB_DST_ADDR_Y1(iep_msg->base, (u32)iep_msg->dst1.mem_addr);
1006         IEP_REGB_DST_ADDR_CBCR1(iep_msg->base, (u32)iep_msg->dst1.uv_addr);
1007         IEP_REGB_DST_ADDR_CR(iep_msg->base, (u32)iep_msg->dst.v_addr);
1008         IEP_REGB_DST_ADDR_CR1(iep_msg->base, (u32)iep_msg->dst1.v_addr);
1009
1010         if (iep_msg->yuv_3D_denoise_en) {
1011                 IEP_REGB_DST_ADDR_Y_ITEMP(iep_msg->base,
1012                         (u32)iep_msg->dst_itemp.mem_addr);
1013                 IEP_REGB_DST_ADDR_CBCR_ITEMP(iep_msg->base,
1014                         (u32)iep_msg->dst_itemp.uv_addr);
1015                 IEP_REGB_DST_ADDR_Y_FTEMP(iep_msg->base,
1016                         (u32)iep_msg->dst_ftemp.mem_addr);
1017                 IEP_REGB_DST_ADDR_CBCR_FTEMP(iep_msg->base,
1018                         (u32)iep_msg->dst_ftemp.uv_addr);
1019                 if ((iep_msg->dst.format == IEP_FORMAT_YCbCr_422_P) ||
1020                     (iep_msg->dst.format == IEP_FORMAT_YCbCr_420_P) ||
1021                     (iep_msg->dst.format == IEP_FORMAT_YCrCb_422_P) ||
1022                     (iep_msg->dst.format == IEP_FORMAT_YCrCb_420_P)) {
1023                         IEP_REGB_DST_ADDR_CR_ITEMP(iep_msg->base,
1024                                 (u32)iep_msg->dst_itemp.v_addr);
1025                         IEP_REGB_DST_ADDR_CR_FTEMP(iep_msg->base,
1026                                 (u32)iep_msg->dst_ftemp.v_addr);
1027                 }
1028         }
1029 #ifdef IEP_PRINT_INFO
1030         IEP_DBG("//-------destination address for image-------// \n\n");
1031         IEP_DBG("sw_dst_addr_yrgb           = 32'h%x;\n",
1032                 (u32)iep_msg->dst.mem_addr);
1033         IEP_DBG("sw_dst_addr_cbcr           = 32'h%x;\n",
1034                 (u32)iep_msg->dst.uv_addr);
1035         IEP_DBG("sw_dst_addr_cr             = 32'h%x;\n",
1036                 (u32)iep_msg->dst.v_addr);
1037         IEP_DBG("sw_dst_addr_y1             = 32'h%x;\n",
1038                 (u32)iep_msg->dst1.mem_addr);
1039         IEP_DBG("sw_dst_addr_cbcr0          = 32'h%x;\n",
1040                 (u32)iep_msg->dst1.uv_addr);
1041         IEP_DBG("sw_dst_addr_cr0            = 32'h%x;\n",
1042                 (u32)iep_msg->dst1.v_addr);
1043         IEP_DBG("sw_dst_addr_y_itemp        = 32'h%x;\n",
1044                 (u32)iep_msg->dst_itemp.mem_addr);
1045         IEP_DBG("sw_dst_addr_cbcr_itemp     = 32'h%x;\n",
1046                 (u32)iep_msg->dst_itemp.uv_addr);
1047         IEP_DBG("sw_dst_addr_cr_itemp       = 32'h%x;\n",
1048                 (u32)iep_msg->dst_itemp.v_addr);
1049         IEP_DBG("sw_dst_addr_y_ftemp        = 32'h%x;\n",
1050                 (u32)iep_msg->dst_ftemp.mem_addr);
1051         IEP_DBG("sw_dst_addr_cbcr_ftemp     = 32'h%x;\n",
1052                 (u32)iep_msg->dst_ftemp.uv_addr);
1053         IEP_DBG("sw_dst_addr_cr_ftemp       = 32'h%x;\n\n",
1054                 (u32)iep_msg->dst_ftemp.v_addr);
1055 #endif
1056 }
1057
1058 void iep_config_lcdc_path(struct IEP_MSG *iep_msg)
1059 {
1060         IEP_REGB_LCDC_PATH_EN(iep_msg->base, iep_msg->lcdc_path_en);
1061
1062 #ifdef IEP_PRINT_INFO
1063         IEP_DBG("//==write back or lcdc direct path config=====// \n\n");
1064         IEP_DBG("sw_lcdc_path_en = %d;//lcdc direct path enable,c"
1065                 " model don't care this value\n\n", iep_msg->lcdc_path_en);
1066 #endif
1067 }
1068
1069 int iep_probe_int(void *base)
1070 {
1071         return ReadReg32(base, rIEP_INT) & 1;
1072 }
1073
1074 void iep_config_frame_end_int_clr(void *base)
1075 {
1076         IEP_REGB_FRAME_END_INT_CLR(base, 1);
1077 }
1078
1079 void iep_config_frame_end_int_en(void *base)
1080 {
1081         IEP_REGB_FRAME_END_INT_CLR(base, 1);
1082         IEP_REGB_FRAME_END_INT_EN(base, 1);
1083 }
1084
1085 #if defined(CONFIG_IEP_MMU)
1086 struct iep_mmu_int_status iep_probe_mmu_int_status(void *base)
1087 {
1088         uint32_t mmu_int_sts = IEP_REGB_MMU_INT_STATUS(base);
1089         struct iep_mmu_int_status sts;
1090
1091         memcpy(&sts, &mmu_int_sts, 4);
1092
1093         return sts;
1094 }
1095
1096 void iep_config_mmu_page_fault_int_en(void *base, bool en)
1097 {
1098         IEP_REGB_MMU_INT_MASK_PAGE_FAULT_INT_EN(base, en);
1099 }
1100
1101 void iep_config_mmu_page_fault_int_clr(void *base)
1102 {
1103         IEP_REGB_MMU_INT_CLEAR_PAGE_FAULT_CLEAR(base, 1);
1104 }
1105
1106 void iep_config_mmu_read_bus_error_int_clr(void *base)
1107 {
1108         IEP_REGB_MMU_INT_CLEAR_READ_BUS_ERROR_CLEAR(base, 1);
1109 }
1110
1111 uint32_t iep_probe_mmu_page_fault_addr(void *base)
1112 {
1113         return IEP_REGB_MMU_PAGE_FAULT_ADDR(base);
1114 }
1115
1116 void iep_config_mmu_cmd(void *base, enum iep_mmu_cmd cmd)
1117 {
1118         IEP_REGB_MMU_CMD(base, cmd);
1119 }
1120
1121 void iep_config_mmu_dte_addr(void *base, uint32_t addr)
1122 {
1123         IEP_REGB_MMU_DTE_ADDR(base, addr);
1124 }
1125 #endif
1126
1127 void iep_config_misc(struct IEP_MSG *iep_msg)
1128 {
1129 //      IEP_REGB_V_REVERSE_DISP();
1130 //      IEP_REGB_H_REVERSE_DISP();
1131 #ifdef IEP_PRINT_INFO
1132         IEP_DBG("//==misc config==========================//\n\n");
1133         IEP_DBG("sw_v_reverse_disp          = 0;\n");
1134         IEP_DBG("sw_u_reverse_disp          = 0;\n\n");
1135 #endif
1136 }
1137
1138 #define IEP_RESET_TIMEOUT   1000
1139 void iep_soft_rst(void *base)
1140 {
1141         unsigned int rst_state = 0;
1142         int i = 0;
1143         WriteReg32(base, rIEP_SOFT_RST, 2);
1144         WriteReg32(base, rIEP_SOFT_RST, 1);
1145         while (i++ < IEP_RESET_TIMEOUT) {
1146                 rst_state = ReadReg32(base, IEP_STATUS);
1147                 if ((rst_state & 0x200) == 0x200) {
1148                         break;
1149                 }
1150
1151                 udelay(1);
1152         }
1153         WriteReg32(base, IEP_SOFT_RST, 2);
1154
1155         if (i == IEP_RESET_TIMEOUT)
1156                 IEP_DBG("soft reset timeout.\n");
1157 }
1158
1159 void iep_config_done(void *base)
1160 {
1161         WriteReg32(base, rIEP_CONF_DONE, 1);
1162 }
1163
1164 void iep_config_frm_start(void *base)
1165 {
1166         IEP_REGB_FRM_START(base, 1);
1167 }
1168
1169 struct iep_status iep_get_status(void *base)
1170 {
1171         uint32_t sts_int = IEP_REGB_STATUS(base);
1172         struct iep_status sts;
1173
1174         memcpy(&sts, &sts_int, 4);
1175
1176         return sts;
1177 }
1178
1179 int iep_get_deinterlace_mode(void *base)
1180 {
1181         int cfg = ReadReg32(base, IEP_CONFIG0);
1182         return (cfg >> 8) & 0x7;
1183 }
1184
1185 void iep_set_deinterlace_mode(int mode, void *base)
1186 {
1187         int cfg;
1188
1189         if (mode > dein_mode_bypass) {
1190                 IEP_ERR("invalid deinterlace mode\n");
1191                 return;
1192         }
1193
1194         cfg = ReadReg32(base, RAW_IEP_CONFIG0);
1195         cfg = (cfg & (~(7 << 8))) | (mode << 8);
1196         WriteReg32(base, IEP_CONFIG0, cfg);
1197
1198         //IEP_REGB_DIL_MODE(base, mode);
1199 }
1200
1201 void iep_switch_input_address(void *base)
1202 {
1203         u32 src_addr_yrgb  = ReadReg32(base, IEP_SRC_ADDR_YRGB);
1204         u32 src_addr_cbcr  = ReadReg32(base, IEP_SRC_ADDR_CBCR);
1205         u32 src_addr_cr    = ReadReg32(base, IEP_SRC_ADDR_CR);
1206
1207         u32 src_addr_y1    = ReadReg32(base, IEP_SRC_ADDR_Y1);
1208         u32 src_addr_cbcr1 = ReadReg32(base, IEP_SRC_ADDR_CBCR1);
1209         u32 src_addr_cr1   = ReadReg32(base, IEP_SRC_ADDR_CR1);
1210
1211         IEP_REGB_SRC_ADDR_YRGB(base, src_addr_y1);
1212         IEP_REGB_SRC_ADDR_CBCR(base, src_addr_cbcr1);
1213         IEP_REGB_SRC_ADDR_CR(base, src_addr_cr1);
1214         IEP_REGB_SRC_ADDR_Y1(base, src_addr_yrgb);
1215         IEP_REGB_SRC_ADDR_CBCR1(base, src_addr_cbcr);
1216         IEP_REGB_SRC_ADDR_CR1(base, src_addr_cr);
1217 }
1218
1219 #if defined(CONFIG_IEP_IOMMU)
1220 static int iep_bufid_to_iova(iep_service_info *pservice, u8 *tbl,
1221         int size, struct iep_reg *reg)
1222 {
1223         int i;
1224         int usr_fd = 0;
1225         int offset = 0;
1226
1227         if (tbl == NULL || size <= 0) {
1228                 dev_err(pservice->iommu_dev, "input arguments invalidate\n");
1229                 return -1;
1230         }
1231
1232         for (i = 0; i < size; i++) {
1233                 usr_fd = reg->reg[tbl[i]] & 0x3FF;
1234                 offset = reg->reg[tbl[i]] >> 10;
1235                 if (usr_fd != 0) {
1236                         struct ion_handle *hdl;
1237                         int ret;
1238                         struct iep_mem_region *mem_region;
1239
1240                         hdl = ion_import_dma_buf(pservice->ion_client, usr_fd);
1241                         if (IS_ERR(hdl)) {
1242                                 dev_err(pservice->iommu_dev,
1243                                         "import dma-buf from fd %d"
1244                                         " failed, reg[%d]\n",
1245                                         usr_fd, tbl[i]);
1246                                 return PTR_ERR(hdl);
1247                         }
1248
1249                         mem_region = kzalloc(sizeof(struct iep_mem_region),
1250                                 GFP_KERNEL);
1251
1252                         if (mem_region == NULL) {
1253                                 dev_err(pservice->iommu_dev,
1254                                         "allocate memory for"
1255                                         " iommu memory region failed\n");
1256                                 ion_free(pservice->ion_client, hdl);
1257                                 return -1;
1258                         }
1259
1260                         mem_region->hdl = hdl;
1261
1262                         ret = ion_map_iommu(pservice->iommu_dev,
1263                                 pservice->ion_client, mem_region->hdl,
1264                                 &mem_region->iova, &mem_region->len);
1265                         if (ret < 0) {
1266                                 dev_err(pservice->iommu_dev,
1267                                         "ion map iommu failed\n");
1268                                 kfree(mem_region);
1269                                 ion_free(pservice->ion_client, hdl);
1270                                 return ret;
1271                         }
1272
1273                         reg->reg[tbl[i]] = mem_region->iova + offset;
1274                         INIT_LIST_HEAD(&mem_region->reg_lnk);
1275                         list_add_tail(&mem_region->reg_lnk,
1276                                 &reg->mem_region_list);
1277                 }
1278         }
1279
1280         return 0;
1281 }
1282
1283 static u8 addr_tbl_iep[] = {
1284         32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55
1285 };
1286
1287 static int iep_reg_address_translate(iep_service_info *pservice, struct iep_reg *reg)
1288 {
1289         return iep_bufid_to_iova(pservice, addr_tbl_iep, sizeof(addr_tbl_iep), reg);
1290 }
1291 #endif
1292
1293 /**
1294  * generating a series of registers copy from iep message
1295  */
1296 extern iep_service_info iep_service;
1297 void iep_config(iep_session *session, struct IEP_MSG *iep_msg)
1298 {
1299         struct iep_reg *reg = kzalloc(sizeof(struct iep_reg), GFP_KERNEL);
1300
1301         reg->session = session;
1302         iep_msg->base = reg->reg;
1303         atomic_set(&reg->session->done, 0);
1304
1305         INIT_LIST_HEAD(&reg->session_link);
1306         INIT_LIST_HEAD(&reg->status_link);
1307
1308 #if defined(CONFIG_IEP_IOMMU)
1309         INIT_LIST_HEAD(&reg->mem_region_list);
1310 #endif
1311
1312         //write config
1313         iep_config_src_size(iep_msg);
1314         iep_config_dst_size(iep_msg);
1315         iep_config_dst_width_tile(iep_msg); //not implement
1316         iep_config_dst_fmt(iep_msg);
1317         iep_config_src_fmt(iep_msg);
1318         iep_config_scl(iep_msg);
1319         iep_config_cg_order(iep_msg);
1320
1321         iep_config_cg(iep_msg);
1322         iep_config_dde(iep_msg);            //not implement
1323         iep_config_color_enh(iep_msg);      //not implement
1324         iep_config_yuv_dns(iep_msg);
1325         iep_config_dil(iep_msg);
1326         iep_config_yuv_enh(iep_msg);
1327         iep_config_rgb2yuv(iep_msg);
1328         iep_config_yuv2rgb(iep_msg);
1329         iep_config_dither_up(iep_msg);
1330         iep_config_dither_down(iep_msg);
1331         iep_config_glb_alpha(iep_msg);
1332         iep_config_vir_line(iep_msg);
1333         iep_config_src_addr(iep_msg);
1334         iep_config_dst_addr(iep_msg);
1335         iep_config_lcdc_path(iep_msg);
1336         iep_config_misc(iep_msg);           //not implement
1337
1338         if (iep_msg->lcdc_path_en) {
1339                 reg->dpi_en     = true;
1340                 reg->act_width  = iep_msg->dst.act_w;
1341                 reg->act_height = iep_msg->dst.act_h;
1342                 reg->off_x      = iep_msg->off_x;
1343                 reg->off_y      = iep_msg->off_y;
1344                 reg->vir_width  = iep_msg->width;
1345                 reg->vir_height = iep_msg->height;
1346                 reg->layer      = iep_msg->layer;
1347                 reg->format     = iep_msg->dst.format;
1348         } else {
1349                 reg->dpi_en     = false;
1350         }
1351
1352 #if defined(CONFIG_IEP_MMU)
1353         if (iep_msg->vir_addr_enable) {
1354                 iep_config_mmu_cmd(iep_msg->base, MMU_ENABLE_PAGING);
1355                 iep_config_mmu_page_fault_int_en(iep_msg->base, 1);
1356         } else {
1357                 iep_config_mmu_cmd(iep_msg->base, MMU_DISABLE_PAGING);
1358                 iep_config_mmu_page_fault_int_en(iep_msg->base, 0);
1359         }
1360         iep_config_mmu_dte_addr(iep_msg->base,
1361                 (uint32_t)virt_to_phys((uint32_t *)session->dte_table));
1362 #endif
1363
1364 #if defined(CONFIG_IEP_IOMMU)
1365         if (iep_service.iommu_dev) {
1366                 if (0 > iep_reg_address_translate(&iep_service, reg)) {
1367                         IEP_ERR("error: translate reg address failed\n");
1368                         kfree(reg);
1369                         return;
1370                 }
1371         }
1372 #endif
1373
1374         mutex_lock(&iep_service.lock);
1375
1376         list_add_tail(&reg->status_link, &iep_service.waiting);
1377         list_add_tail(&reg->session_link, &session->waiting);
1378         mutex_unlock(&iep_service.lock);
1379 }
1380