]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00161526 mxc v4l2 output: 720p ic bypass output may failed in block
authorJason Chen <b02280@freescale.com>
Mon, 7 Nov 2011 08:46:36 +0000 (16:46 +0800)
committerOliver Wendt <ow@karo-electronics.de>
Mon, 30 Sep 2013 12:09:58 +0000 (14:09 +0200)
Repeat play with below cmdline:
/unit_tests/mxc_v4l2_output.out -iw 1280 -ih 720 -ow 1280 -oh
720 -fr 10 -l 1 /unit_tests/720p.yuv

Found the ipu update offset function cause this issue, it can be
work-around by setting it only when value changed.

Signed-off-by: Jason Chen <b02280@freescale.com>
drivers/media/video/mxc/output/mxc_vout.c
drivers/mxc/ipu3/ipu_param_mem.h
drivers/video/mxc/mxc_ipuv3_fb.c

index ccce9a43ee47cfa922fbce80c087b6c169137be1..8596b42d6ca5285bf78e28fb74ac0db25c5cbc8e 100644 (file)
@@ -1217,8 +1217,11 @@ static void release_disp_output(struct mxc_vout_output *vout)
        console_unlock();
 
        /* fix if ic bypass crack smem_start */
-       if (is_pp_bypass(vout))
+       if (is_pp_bypass(vout)) {
+               console_lock();
                fbi->fix.smem_start = vout->disp_bufs[0];
+               console_unlock();
+       }
 
        if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
                console_lock();
index 7fbd4e12d0fd65221dca725bacba53a2e8430ce8..223a1cdf5fa4852b5c044baffe60d02fc6534e40 100644 (file)
@@ -653,6 +653,7 @@ static inline void _ipu_ch_offset_update(struct ipu_soc *ipu,
 {
        uint32_t u_offset = 0;
        uint32_t v_offset = 0;
+       uint32_t old_offset = 0;
        uint32_t u_fix = 0;
        uint32_t v_fix = 0;
        int32_t sub_ch = 0;
@@ -788,14 +789,22 @@ static inline void _ipu_ch_offset_update(struct ipu_soc *ipu,
                dev_warn(ipu->dev,
                        "IDMAC%d's V offset is not 8-byte aligned\n", ch);
 
-       ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22, u_offset / 8);
-       ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22, v_offset / 8);
+       old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22);
+       if (old_offset != u_offset / 8)
+               ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22, u_offset / 8);
+       old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22);
+       if (old_offset != v_offset / 8)
+               ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22, v_offset / 8);
 
        sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
        if (sub_ch <= 0)
                return;
-       ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22, u_offset / 8);
-       ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22, v_offset / 8);
+       old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22);
+       if (old_offset != u_offset / 8)
+               ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22, u_offset / 8);
+       old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22);
+       if (old_offset != v_offset / 8)
+               ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22, v_offset / 8);
 };
 
 static inline void _ipu_ch_params_set_alpha_width(struct ipu_soc *ipu, uint32_t ch, int alpha_width)
index 11e67449fea972bb5e5469b0e182c1171410181f..74e4077600b7b03ade0173b0ed987b32dc56aa21 100644 (file)
@@ -1234,15 +1234,16 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
                }
 
                /* update u/v offset */
-               ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
-                               IPU_INPUT_BUFFER,
-                               bpp_to_pixfmt(info),
-                               info->var.xres_virtual,
-                               info->var.yres_virtual,
-                               info->var.xres_virtual,
-                               0, 0,
-                               var->yoffset,
-                               var->xoffset);
+               if (info->var.xres_virtual > info->var.xres)
+                       ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+                                       IPU_INPUT_BUFFER,
+                                       bpp_to_pixfmt(info),
+                                       info->var.xres_virtual,
+                                       info->var.yres_virtual,
+                                       info->var.xres_virtual,
+                                       0, 0,
+                                       var->yoffset,
+                                       var->xoffset);
 
                ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
                                  mxc_fbi->cur_ipu_buf);