]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ENGR00290654 IPUv3 dev:Workaround split mode downsize overflow
authorLiu Ying <Ying.Liu@freescale.com>
Wed, 4 Dec 2013 10:02:00 +0000 (18:02 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Wed, 20 Aug 2014 08:06:47 +0000 (10:06 +0200)
The downsizing ratio overflow check should cover every stripe
in the split mode. We need to do the overflow check correctly
by taking the width/height 8-pixel alignment requirement into
consideration since the alignment would be done when every
stripe is checked in it's own ipu task.

This patch takes a workaround for the issue which can be
reproduced by this unit test case:

==================================================================
mxc_v4l2_output.out -iw 1920 -ih 1080 -ow 200 -oh 200 -v 1

mxc_ipu mxc_ipu: ERR:create_split_child_task() ret:-22
mxc_ipu mxc_ipu: sp_task[0],no-0x12 fail state:-22, queue err:-22.
mxc_ipu mxc_ipu: ERR: [0xac73ea00] no-0x10,state 3: error
mxc_ipu mxc_ipu: ERR: no-0x10,ipu_queue_task err:-125
mxc_v4l2_output v4l2_out.35: display work fail ret = -125
mxc_ipu mxc_ipu: ERR:create_split_child_task() ret:-22
mxc_ipu mxc_ipu: sp_task[0],no-0x22 fail state:-22, queue err:-22.
mxc_ipu mxc_ipu: ERR: [0xac73ea00] no-0x20,state 3: error
mxc_ipu mxc_ipu: ERR: no-0x20,ipu_queue_task err:-125
mxc_v4l2_output v4l2_out.35: display work fail ret = -125
mxc_ipu mxc_ipu: ERR:create_split_child_task() ret:-22
mxc_ipu mxc_ipu: sp_task[0],no-0x32 fail state:-22, queue err:-22.
mxc_ipu mxc_ipu: ERR: [0xac63c400] no-0x30,state 3: error
mxc_ipu mxc_ipu: ERR: no-0x30,ipu_queue_task err:-125
mxc_v4l2_output v4l2_out.35: display work fail ret = -125
VIDIOC_QBUF failed -1
==================================================================

Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
drivers/mxc/ipu3/ipu_device.c

index bdd1d70618ac7f184d4485de59249246197dbc41..92f3cd8486dad3533c807e9a2e2dff40aba8738b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/ipu-v3.h>
+#include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -887,6 +888,9 @@ static int update_split_setting(struct ipu_task_entry *t, bool vdi_split)
        if (((t->set.sp_setting.ow + t->set.sp_setting.o_right_pos) > ow)
                || (t->set.sp_setting.ow > soc_max_out_width()))
                return IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER;
+       if (rounddown(t->set.sp_setting.ow, 8) * 8 <=
+           rounddown(t->set.sp_setting.iw, 8))
+               return IPU_CHECK_ERR_W_DOWNSIZE_OVER;
 
        if (t->set.split_mode & UD_SPLIT) {
                /*
@@ -933,6 +937,9 @@ static int update_split_setting(struct ipu_task_entry *t, bool vdi_split)
        if (((t->set.sp_setting.oh + t->set.sp_setting.o_bottom_pos) > oh)
                || (t->set.sp_setting.oh > soc_max_out_height()))
                return IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER;
+       if (rounddown(t->set.sp_setting.oh, 8) * 8 <=
+           rounddown(t->set.sp_setting.ih, 8))
+               return IPU_CHECK_ERR_H_DOWNSIZE_OVER;
 
        return IPU_CHECK_OK;
 }