2 * Copyright (C) 2013 ROCKCHIP, Inc.
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.
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.
15 #include <linux/delay.h>
16 #include <linux/slab.h>
17 #include "hw_iep_reg.h"
19 #include "hw_iep_config_addr.h"
21 extern iep_service_info iep_service;
22 static void iep_config_src_size(struct IEP_MSG *iep_msg)
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);
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);
35 static void iep_config_dst_size(struct IEP_MSG *iep_msg)
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);
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);
48 static void iep_config_dst_width_tile(struct IEP_MSG *iep_msg)
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();*/
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");
62 static void iep_config_dst_fmt(struct IEP_MSG *iep_msg)
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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 ;"
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",
169 IEP_DBG("sw_dst_fmt = %d;//0:argb; 1:rgb565; 2:yuv422;"
170 " 3:yuv420;\n\n", dst_fmt);
174 static void iep_config_src_fmt(struct IEP_MSG *iep_msg)
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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",
274 IEP_DBG("sw_src_fmt = %d;//0:argb; 1:rgb565;"
275 " 2:yuv422; 3:yuv420;\n\n", src_fmt);
279 static void iep_config_scl(struct IEP_MSG *iep_msg)
286 unsigned int src_height, src_width, dst_height, dst_width;
288 int div_height_dst_src;
289 int div_width_dst_src;
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;
296 if ((iep_msg->src.act_w == iep_msg->dst.act_w) &&
297 (iep_msg->src.act_h == iep_msg->dst.act_h))
302 if ((iep_msg->src.act_w >= iep_msg->dst.act_w) &&
303 (iep_msg->src.act_h >= iep_msg->dst.act_h))
305 else if ((iep_msg->src.act_w >= iep_msg->dst.act_w) &&
306 (iep_msg->src.act_h <= iep_msg->dst.act_h))
308 else if ((iep_msg->src.act_w <= iep_msg->dst.act_w) &&
309 (iep_msg->src.act_h >= iep_msg->dst.act_h))
315 if ((scl_sel == 1) || (scl_sel == 3)) {
316 div_height_dst_src = src_height * 65536 / dst_height;
318 div_height_dst_src = (dst_height + 1) * 65536 /
320 if ((div_height_dst_src * (src_height + 1)) <
321 ((dst_height + 1) * 65536))
322 div_height_dst_src = div_height_dst_src + 1;
325 if (div_height_dst_src == 65536)
326 div_height_dst_src = 0;
329 if ((scl_sel == 2) || (scl_sel == 3)) {
330 div_width_dst_src = src_width * 65536 / dst_width;
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;
338 if (div_width_dst_src == 65536)
339 div_width_dst_src = 0;
342 IEP_REGB_SCL_EN(iep_msg->base, scl_en);
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);
350 #ifdef IEP_PRINT_INFO
351 IEP_DBG(" //==scaling config============================//\n\n");
352 IEP_DBG("sw_scl_en = %d;//0:disable; 1:enable;\n",
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);
370 static void iep_config_cg_order(struct IEP_MSG *iep_msg)
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);
383 static void iep_config_cg(struct IEP_MSG *iep_msg)
386 unsigned int cg_conf_addr;
388 IEP_REGB_RGB_CON_GAM_EN(iep_msg->base, iep_msg->rgb_cg_en);
390 if (iep_msg->rgb_cg_en) {
391 cg_conf_addr = rIEP_CG_TAB_ADDR;
393 for (i = 0; i < 192; i++) {
394 WriteReg32(iep_msg->base, cg_conf_addr,
396 cg_conf_addr += 0x04;
400 #ifdef IEP_PRINT_INFO
401 IEP_DBG("sw_rgb_con_gam_en = 0;//0:contrast"
402 " & gamma disable; 1:enable;\n",
407 static void iep_config_dde(struct IEP_MSG *iep_msg)
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);
421 static void iep_config_color_enh(struct IEP_MSG *iep_msg)
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;"
428 iep_msg->rgb_color_enhance_en);
432 static void iep_config_yuv_dns(struct IEP_MSG *iep_msg)
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);
447 static void iep_config_dil(struct IEP_MSG *iep_msg)
450 switch (iep_msg->dein_mode) {
451 case IEP_DEINTERLACE_MODE_DISABLE:
452 dein_mode = dein_mode_bypass_dis;
454 case IEP_DEINTERLACE_MODE_I2O1:
455 dein_mode = iep_msg->field_order == FIELD_ORDER_TOP_FIRST ? dein_mode_I2O1T : dein_mode_I2O1B;
457 case IEP_DEINTERLACE_MODE_I4O1:
459 dein_mode = iep_msg->field_order == FIELD_ORDER_TOP_FIRST ? dein_mode_I4O1B : dein_mode_I4O1T;
461 dein_mode = iep_msg->field_order == FIELD_ORDER_TOP_FIRST ? dein_mode_I4O1T : dein_mode_I4O1B;
464 case IEP_DEINTERLACE_MODE_I4O2:
465 dein_mode = dein_mode_I4O2;
467 case IEP_DEINTERLACE_MODE_BYPASS:
468 dein_mode = dein_mode_bypass;
471 IEP_ERR("unknown deinterlace mode, set deinterlace mode (bypass)\n");
472 dein_mode = dein_mode_bypass;
475 IEP_REGB_DIL_MODE(iep_msg->base, dein_mode);
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);
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);
494 static void iep_config_yuv_enh(struct IEP_MSG *iep_msg)
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);
519 static void iep_config_rgb2yuv(struct IEP_MSG *iep_msg)
521 unsigned char cond1, cond2;
522 unsigned int rgb2yuv_en = 0;
525 cond1 = ((iep_msg->src.format <= 5) && (iep_msg->dst.format > 5)) ?
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;
535 if ((cond1 == 1) || (cond2 == 1)) {
536 IEP_REGB_RGB_TO_YUV_EN(iep_msg->base, 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);
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);
552 static void iep_config_yuv2rgb(struct IEP_MSG *iep_msg)
554 unsigned char cond1, cond2;
555 unsigned int yuv2rgb_en = 0;
558 cond1 = ((iep_msg->src.format > 5) &&
559 (iep_msg->dst.format <= 5)) ? 1 : 0;
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;
567 if ((cond1 == 1) || (cond2 == 1)) {
568 IEP_REGB_YUV_TO_RGB_EN(iep_msg->base, 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);
575 IEP_REGB_YUV_TO_RGB_EN(iep_msg->base, 0);
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);
584 static void iep_config_dither_up(struct IEP_MSG *iep_msg)
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;
592 IEP_REGB_DITHER_UP_EN(iep_msg->base, 0);
594 #ifdef IEP_PRINT_INFO
595 IEP_DBG("//==dither config=============================//\n\n");
596 IEP_DBG("sw_dither_up_en = %d;\n", dither_up);
600 static void iep_config_dither_down(struct IEP_MSG *iep_msg)
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);
608 IEP_REGB_DITHER_DOWN_EN(iep_msg->base, 0);
610 #ifdef IEP_PRINT_INFO
611 IEP_DBG("sw_dither_down_en = %d;\n\n", dither_down);
615 static void iep_config_glb_alpha(struct IEP_MSG *iep_msg)
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);
625 static void iep_config_vir_line(struct IEP_MSG *iep_msg)
627 unsigned int src_vir_w;
628 unsigned int dst_vir_w;
630 switch (iep_msg->src.format) {
631 case IEP_FORMAT_ARGB_8888 :
632 src_vir_w = iep_msg->src.vir_w;
634 case IEP_FORMAT_ABGR_8888 :
635 src_vir_w = iep_msg->src.vir_w;
637 case IEP_FORMAT_RGBA_8888 :
638 src_vir_w = iep_msg->src.vir_w;
640 case IEP_FORMAT_BGRA_8888 :
641 src_vir_w = iep_msg->src.vir_w;
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;
647 src_vir_w = iep_msg->src.vir_w / 2;
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;
653 src_vir_w = iep_msg->src.vir_w / 2;
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;
659 src_vir_w = iep_msg->src.vir_w / 4;
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;
665 src_vir_w = iep_msg->src.vir_w / 4;
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;
671 src_vir_w = iep_msg->src.vir_w / 4;
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;
677 src_vir_w = iep_msg->src.vir_w / 4;
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;
683 src_vir_w = iep_msg->src.vir_w / 4;
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;
689 src_vir_w = iep_msg->src.vir_w / 4;
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;
695 src_vir_w = iep_msg->src.vir_w / 4;
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;
701 src_vir_w = iep_msg->src.vir_w / 4;
704 IEP_ERR("Unkown format,"
705 "set the source image virtual width 0\n");
710 switch (iep_msg->dst.format) {
711 case IEP_FORMAT_ARGB_8888 :
712 dst_vir_w = iep_msg->dst.vir_w;
714 case IEP_FORMAT_ABGR_8888 :
715 dst_vir_w = iep_msg->dst.vir_w;
717 case IEP_FORMAT_RGBA_8888 :
718 dst_vir_w = iep_msg->dst.vir_w;
720 case IEP_FORMAT_BGRA_8888 :
721 dst_vir_w = iep_msg->dst.vir_w;
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;
727 dst_vir_w = iep_msg->dst.vir_w / 2;
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;
733 dst_vir_w = iep_msg->dst.vir_w / 2;
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;
739 dst_vir_w = iep_msg->dst.vir_w / 4;
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;
745 dst_vir_w = iep_msg->dst.vir_w / 4;
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;
751 dst_vir_w = iep_msg->dst.vir_w / 4;
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;
757 dst_vir_w = iep_msg->dst.vir_w / 4;
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;
763 dst_vir_w = iep_msg->dst.vir_w / 4;
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;
769 dst_vir_w = iep_msg->dst.vir_w / 4;
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;
775 dst_vir_w = iep_msg->dst.vir_w / 4;
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;
781 dst_vir_w = iep_msg->dst.vir_w / 4;
784 IEP_ERR("Unkown format, set the destination"
785 " image virtual width 0\n");
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);
793 static void iep_config_src_addr(struct IEP_MSG *iep_msg)
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;
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;
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;
835 offset_addr_y = iep_msg->src.y_off *
836 iep_msg->src.vir_w + iep_msg->src.x_off;
839 //**********************************************//
840 //***********uv addr offset*********************//
841 //**********************************************//
842 // note: image size align to even when image format is yuv
844 //----------offset_w--------//
845 if (iep_msg->src.x_off % 2 == 1)
846 offset_x_equ_uv = iep_msg->src.x_off + 1;
848 offset_x_equ_uv = iep_msg->src.x_off;
850 offset_x_u_byte = offset_x_equ_uv / 2;
851 offset_x_v_byte = offset_x_equ_uv / 2;
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;
859 offset_addr_uv_w = offset_x_u_byte;
860 offset_addr_v_w = offset_x_v_byte;
863 //----------offset_h--------//
864 if (iep_msg->src.vir_w % 2 == 1)
865 vir_w_euq_uv = iep_msg->src.vir_w + 1;
867 vir_w_euq_uv = iep_msg->src.vir_w;
869 line_u_byte = vir_w_euq_uv / 2;
870 line_v_byte = vir_w_euq_uv / 2;
872 if (iep_msg->src.y_off % 2 == 1)
873 offset_y_equ_420_uv = iep_msg->src.y_off + 1;
875 offset_y_equ_420_uv = iep_msg->src.y_off;
877 switch (iep_msg->src.format) {
878 case IEP_FORMAT_YCbCr_422_SP :
879 offset_addr_uv_h = (line_u_byte + line_v_byte) *
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;
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;
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;
894 case IEP_FORMAT_YCrCb_422_SP :
895 offset_addr_uv_h = (line_u_byte + line_v_byte) *
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;
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;
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;
913 //----------offset u/v addr--------//
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;
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;
929 src_addr_y_itemp = ((u32)iep_msg->src_itemp.mem_addr) +
931 src_addr_cbcr_itemp = ((u32)iep_msg->src_itemp.uv_addr) +
933 src_addr_cr_itemp = ((u32)iep_msg->src_itemp.v_addr) +
936 src_addr_y_ftemp = ((u32)iep_msg->src_ftemp.mem_addr) +
938 src_addr_cbcr_ftemp = ((u32)iep_msg->src_ftemp.uv_addr) +
940 src_addr_cr_ftemp = ((u32)iep_msg->src_ftemp.v_addr) +
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);
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);
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);
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);
966 if ((iep_msg->dein_mode == IEP_DEINTERLACE_MODE_I4O1 ||
967 iep_msg->dein_mode == IEP_DEINTERLACE_MODE_I4O2) &&
969 iep_msg->field_order == FIELD_ORDER_BOTTOM_FIRST
971 iep_msg->field_order == FIELD_ORDER_TOP_FIRST
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);
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);
989 if (iep_msg->yuv_3D_denoise_en) {
990 IEP_REGB_SRC_ADDR_Y_ITEMP(iep_msg->base,
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,
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,
1004 IEP_REGB_SRC_ADDR_CR_FTEMP(iep_msg->base,
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);
1025 static void iep_config_dst_addr(struct IEP_MSG *iep_msg)
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;
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;
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;
1067 offset_addr_y = iep_msg->dst.y_off *
1068 iep_msg->dst.vir_w + iep_msg->dst.x_off;
1071 //**********************************************//
1072 //***********uv addr offset*********************//
1073 //**********************************************//
1074 // note: image size align to even when image format is yuv
1076 //----------offset_w--------//
1077 if (iep_msg->dst.x_off % 2 == 1)
1078 offset_x_equ_uv = iep_msg->dst.x_off + 1;
1080 offset_x_equ_uv = iep_msg->dst.x_off;
1082 offset_x_u_byte = offset_x_equ_uv / 2;
1083 offset_x_v_byte = offset_x_equ_uv / 2;
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;
1091 offset_addr_uv_w = offset_x_u_byte;
1092 offset_addr_v_w = offset_x_v_byte;
1095 //----------offset_h--------//
1096 if (iep_msg->dst.vir_w % 2 == 1)
1097 vir_w_euq_uv = iep_msg->dst.vir_w + 1;
1099 vir_w_euq_uv = iep_msg->dst.vir_w;
1101 line_u_byte = vir_w_euq_uv / 2;
1102 line_v_byte = vir_w_euq_uv / 2;
1104 if (iep_msg->dst.y_off % 2 == 1)
1105 offset_y_equ_420_uv = iep_msg->dst.y_off + 1;
1107 offset_y_equ_420_uv = iep_msg->dst.y_off;
1109 switch (iep_msg->dst.format) {
1110 case IEP_FORMAT_YCbCr_422_SP :
1111 offset_addr_uv_h = (line_u_byte + line_v_byte) *
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;
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;
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;
1126 case IEP_FORMAT_YCrCb_422_SP :
1127 offset_addr_uv_h = (line_u_byte + line_v_byte) *
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;
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;
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;
1145 //----------offset u/v addr--------//
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 //**********************************************//
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;
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;
1163 dst_addr_y_itemp = ((u32)iep_msg->dst_itemp.mem_addr) +
1165 dst_addr_cbcr_itemp = ((u32)iep_msg->dst_itemp.uv_addr) +
1167 dst_addr_cr_itemp = ((u32)iep_msg->dst_itemp.v_addr) +
1170 dst_addr_y_ftemp = ((u32)iep_msg->dst_ftemp.mem_addr) +
1172 dst_addr_cbcr_ftemp = ((u32)iep_msg->dst_ftemp.uv_addr) +
1174 dst_addr_cr_ftemp = ((u32)iep_msg->dst_ftemp.v_addr) +
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);
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);
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);
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);
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);
1208 if (iep_msg->yuv_3D_denoise_en) {
1209 IEP_REGB_DST_ADDR_Y_ITEMP(iep_msg->base,
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,
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,
1223 IEP_REGB_DST_ADDR_CR_FTEMP(iep_msg->base,
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);
1256 void iep_config_lcdc_path(struct IEP_MSG *iep_msg)
1258 IEP_REGB_LCDC_PATH_EN(iep_msg->base, iep_msg->lcdc_path_en);
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);
1267 int iep_probe_int(void *base)
1269 return ReadReg32(base, rIEP_INT) & 1;
1272 void iep_config_frame_end_int_clr(void *base)
1274 IEP_REGB_FRAME_END_INT_CLR(base, 1);
1277 void iep_config_frame_end_int_en(void *base)
1279 IEP_REGB_FRAME_END_INT_CLR(base, 1);
1280 IEP_REGB_FRAME_END_INT_EN(base, 1);
1283 #if defined(CONFIG_IEP_MMU)
1284 struct iep_mmu_int_status iep_probe_mmu_int_status(void *base)
1286 uint32_t mmu_int_sts = IEP_REGB_MMU_INT_STATUS(base);
1287 struct iep_mmu_int_status sts;
1289 memcpy(&sts, &mmu_int_sts, 4);
1294 void iep_config_mmu_page_fault_int_en(void *base, bool en)
1296 IEP_REGB_MMU_INT_MASK_PAGE_FAULT_INT_EN(base, en);
1299 void iep_config_mmu_page_fault_int_clr(void *base)
1301 IEP_REGB_MMU_INT_CLEAR_PAGE_FAULT_CLEAR(base, 1);
1304 void iep_config_mmu_read_bus_error_int_clr(void *base)
1306 IEP_REGB_MMU_INT_CLEAR_READ_BUS_ERROR_CLEAR(base, 1);
1309 uint32_t iep_probe_mmu_page_fault_addr(void *base)
1311 return IEP_REGB_MMU_PAGE_FAULT_ADDR(base);
1314 void iep_config_mmu_cmd(void *base, enum iep_mmu_cmd cmd)
1316 IEP_REGB_MMU_CMD(base, cmd);
1319 void iep_config_mmu_dte_addr(void *base, uint32_t addr)
1321 IEP_REGB_MMU_DTE_ADDR(base, addr);
1325 void iep_config_misc(struct IEP_MSG *iep_msg)
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");
1336 #define IEP_RESET_TIMEOUT 1000
1337 void iep_soft_rst(void *base)
1339 unsigned int rst_state = 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) {
1351 WriteReg32(base, IEP_SOFT_RST, 2);
1353 if (i == IEP_RESET_TIMEOUT)
1354 IEP_DBG("soft reset timeout.\n");
1357 void iep_config_done(void *base)
1359 WriteReg32(base, rIEP_CONF_DONE, 1);
1362 void iep_config_frm_start(void *base)
1364 IEP_REGB_FRM_START(base, 1);
1367 struct iep_status iep_get_status(void *base)
1369 uint32_t sts_int = IEP_REGB_STATUS(base);
1370 struct iep_status sts;
1372 memcpy(&sts, &sts_int, 4);
1377 int iep_get_deinterlace_mode(void *base)
1379 int cfg = ReadReg32(base, IEP_CONFIG0);
1380 return (cfg >> 8) & 0x7;
1383 void iep_set_deinterlace_mode(int mode, void *base)
1387 if (mode > dein_mode_bypass) {
1388 IEP_ERR("invalid deinterlace mode\n");
1392 cfg = ReadReg32(base, RAW_IEP_CONFIG0);
1393 cfg = (cfg & (~(7 << 8))) | (mode << 8);
1394 WriteReg32(base, IEP_CONFIG0, cfg);
1396 //IEP_REGB_DIL_MODE(base, mode);
1399 void iep_switch_input_address(void *base)
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);
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);
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);
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)
1425 if (tbl == NULL || size <= 0) {
1426 dev_err(pservice->iommu_dev, "input arguments invalidate\n");
1430 for (i = 0; i < size; i++) {
1431 usr_fd = reg->reg[tbl[i]] & 0x3FF;
1432 offset = reg->reg[tbl[i]] >> 10;
1434 struct ion_handle *hdl;
1436 struct iep_mem_region *mem_region;
1438 hdl = ion_import_dma_buf(pservice->ion_client, usr_fd);
1440 dev_err(pservice->iommu_dev,
1441 "import dma-buf from fd %d"
1442 " failed, reg[%d]\n",
1444 return PTR_ERR(hdl);
1447 mem_region = kzalloc(sizeof(struct iep_mem_region),
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);
1458 mem_region->hdl = hdl;
1460 ret = ion_map_iommu(pservice->iommu_dev,
1461 pservice->ion_client, mem_region->hdl,
1462 &mem_region->iova, &mem_region->len);
1464 dev_err(pservice->iommu_dev,
1465 "ion map iommu failed\n");
1467 ion_free(pservice->ion_client, hdl);
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 ®->mem_region_list);
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
1485 static int iep_reg_address_translate(iep_service_info *pservice, struct iep_reg *reg)
1487 return iep_bufid_to_iova(pservice, addr_tbl_iep, sizeof(addr_tbl_iep), reg);
1492 * generating a series of registers copy from iep message
1494 void iep_config(iep_session *session, struct IEP_MSG *iep_msg)
1496 struct iep_reg *reg = kzalloc(sizeof(struct iep_reg), GFP_KERNEL);
1500 reg->session = session;
1501 iep_msg->base = reg->reg;
1502 atomic_set(®->session->done, 0);
1504 INIT_LIST_HEAD(®->session_link);
1505 INIT_LIST_HEAD(®->status_link);
1507 #if defined(CONFIG_IEP_IOMMU)
1508 INIT_LIST_HEAD(®->mem_region_list);
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);
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
1537 if (iep_msg->lcdc_path_en) {
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;
1548 reg->dpi_en = false;
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);
1556 iep_config_mmu_cmd(iep_msg->base, MMU_DISABLE_PAGING);
1557 iep_config_mmu_page_fault_int_en(iep_msg->base, 0);
1559 iep_config_mmu_dte_addr(iep_msg->base,
1560 (uint32_t)virt_to_phys((uint32_t *)session->dte_table));
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");
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;
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;
1583 mutex_lock(&iep_service.lock);
1585 list_add_tail(®->status_link, &iep_service.waiting);
1586 list_add_tail(®->session_link, &session->waiting);
1587 mutex_unlock(&iep_service.lock);