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