How to reset IPU when DMA does not terminate?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to reset IPU when DMA does not terminate?

1,216 Views
adriancox
Contributor III

I'm using the IPU on the IMX.6Q (silicon rev 1.2) to place an overlay on to video before encoding in the VPU. I have a number of other IPU tasks handling deinterlace, colour space conversion, and display.

After a period running, having submitted this IPU task successfully thousands of times, the application crashes. In this state, all other applications (including the IPU examples) fail with a timeout when they submit an IPU task. The problem is only cured by a reboot.

I think I now need advice on how to modify the IPU driver so that I can reset the relevant parts of the IPU when I detect this condition, ideally without disrupting the display. I'm not sure whether this is a kernel bug or silicon problem.

By inserting debug into the driver, I can tell the following about the state. This is my IPU task:

imx-ipuv3 imx-ipuv3.0: [0xbafbf000]input:
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     format = 0x32315559
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     width = 720
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     height = 576
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.w = 720
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.h = 576
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.pos.x = 0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.pos.y = 0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]input buffer:
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     paddr = 0x18000000
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     i_off = 0x0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     i_uoff = 0x65400
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     i_voff = 0x7e900
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     istride = 720
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]output:
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     format = 0x33424752
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     width = 720
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     height = 576
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.w = 720
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.h = 576
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.pos.x = 0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.pos.y = 0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     rotate = 0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]output buffer:
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     paddr = 0x18a00000
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     o_off = 0x0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     o_uoff = 0x0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     o_voff = 0x0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     ostride = 2160
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]overlay:
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     format = 0x41524742
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     width = 720
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     height = 576
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.w = 720
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.h = 576
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.pos.x = 0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     crop.pos.y = 0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]overlay buffer:
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     paddr = 0x18e00000
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     ov_off = 0x0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     ov_uoff = 0x0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     ov_voff = 0x0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     ovstride = 2880
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]local alpha enabled with:
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     paddr = 0x0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     ov_alpha_off = 0x0
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     ov_alpha_stride = 720
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]want task_id = 1
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]want task mode is 0x1
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     IC_MODE = 0x1
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     ROT_MODE = 0x2
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     VDI_MODE = 0x4
imx-ipuv3 imx-ipuv3.0: [0xbafbf000]     Task_no = 0x740


These are the channel parameters:


imx-ipuv3 imx-ipuv3.0: ch 14 word 0 - 10000000 00003000 00000000 E0000000 0008FC59

imx-ipuv3 imx-ipuv3.0: ch 14 word 1 - 031C0000 00000000 20E3C000 FFF2CFC0 00006208

imx-ipuv3 imx-ipuv3.0: PFS 0x7,      

imx-ipuv3 imx-ipuv3.0: BPP 0x0,      

imx-ipuv3 imx-ipuv3.0: NPB 0xf      

imx-ipuv3 imx-ipuv3.0: FW 719,     

imx-ipuv3 imx-ipuv3.0: FH 575,       

imx-ipuv3 imx-ipuv3.0: EBA0 0x18e00000   

imx-ipuv3 imx-ipuv3.0: EBA1 0x0

imx-ipuv3 imx-ipuv3.0: Stride 2879   

imx-ipuv3 imx-ipuv3.0: scan_order 0

imx-ipuv3 imx-ipuv3.0: uv_stride 8712

imx-ipuv3 imx-ipuv3.0: u_offset 0x0

imx-ipuv3 imx-ipuv3.0: v_offset 0x0

imx-ipuv3 imx-ipuv3.0: Width0 7+1,

imx-ipuv3 imx-ipuv3.0: Width1 7+1,

imx-ipuv3 imx-ipuv3.0: Width2 7+1,

imx-ipuv3 imx-ipuv3.0: Width3 7+1,

imx-ipuv3 imx-ipuv3.0: Offset0 8,

imx-ipuv3 imx-ipuv3.0: Offset1 16,

imx-ipuv3 imx-ipuv3.0: Offset2 24,

imx-ipuv3 imx-ipuv3.0: Offset3 0

These are the IPU registers:

imx-ipuv3 imx-ipuv3.0: IPU_CONF =       0x00000004  

imx-ipuv3 imx-ipuv3.0: IDMAC_CONF =     0x0000002F

imx-ipuv3 imx-ipuv3.0: IDMAC_CHA_EN1 =  0x00205000

imx-ipuv3 imx-ipuv3.0: IDMAC_CHA_EN2 =  0x00000000

imx-ipuv3 imx-ipuv3.0: IDMAC_CHA_PRI1 =         0x18800001

imx-ipuv3 imx-ipuv3.0: IDMAC_CHA_PRI2 =         0x00000000

imx-ipuv3 imx-ipuv3.0: IDMAC_BAND_EN1 =         0x00000000

imx-ipuv3 imx-ipuv3.0: IDMAC_BAND_EN2 =         0x00000000

imx-ipuv3 imx-ipuv3.0: IPU_CHA_DB_MODE_SEL0 =   0x00000000

imx-ipuv3 imx-ipuv3.0: IPU_CHA_DB_MODE_SEL1 =   0x00000000

imx-ipuv3 imx-ipuv3.0: IPU_CHA_TRB_MODE_SEL0 =  0x00000000

imx-ipuv3 imx-ipuv3.0: IPU_CHA_TRB_MODE_SEL1 =  0x00000000

imx-ipuv3 imx-ipuv3.0: DMFC_WR_CHAN =   0x00000090

imx-ipuv3 imx-ipuv3.0: DMFC_WR_CHAN_DEF =       0x202020F6

imx-ipuv3 imx-ipuv3.0: DMFC_DP_CHAN =   0x00009694

imx-ipuv3 imx-ipuv3.0: DMFC_DP_CHAN_DEF =       0x2020F6F6

imx-ipuv3 imx-ipuv3.0: DMFC_IC_CTRL =   0x00000002

imx-ipuv3 imx-ipuv3.0: IPU_FS_PROC_FLOW1 =      0x80000000

imx-ipuv3 imx-ipuv3.0: IPU_FS_PROC_FLOW2 =      0x00000000

imx-ipuv3 imx-ipuv3.0: IPU_FS_PROC_FLOW3 =      0x00000000

imx-ipuv3 imx-ipuv3.0: IPU_FS_DISP_FLOW1 =      0x00000000

imx-ipuv3 imx-ipuv3.0: IPU_VDIC_VDI_FSIZE =     0x00000000

imx-ipuv3 imx-ipuv3.0: IPU_VDIC_VDI_C =         0x00000000

imx-ipuv3 imx-ipuv3.0: IPU_IC_CONF =    0x40000B00


Labels (4)
Tags (2)
0 Kudos
1 Reply

478 Views
adriancox
Contributor III

I have a workaround that greatly reduces the frequency of the lockup. This patch prevents the IPU driver executing two overlay operations at once - even though the operations should be independent, and I can find no suggestion in the datasheet that they might clash.

--- a/drivers/mxc/ipu3/ipu_device.c

+++ b/drivers/mxc/ipu3/ipu_device.c

@@ -327,6 +327,7 @@ struct ipu_channel_tabel {

  struct mutex lock;

  u8 used[MXC_IPU_MAX_NUM][MAX_PP_CH];

  u8 vdoa_used;

+ u8 overlay_used;

};

struct ipu_thread_data {

@@ -1171,6 +1172,10 @@ static int _get_vdoa_ipu_res(struct ipu_task_entry *t)

  goto out;

  }

  }

+

+ // Don't run two overlays at once. Don't know why

+ if (t->overlay_en && tbl->overlay_used)

+ goto out;

  for (i = 0; i < max_ipu_no; i++) {

  ipu = ipu_get_soc(i);

@@ -1229,6 +1234,8 @@ next:

  t->ipu = ipu;

  t->ipu_id = i;

  t->dev = ipu->dev;

+ if (t->overlay_en)

+ tbl->overlay_used = 1;

  if (atomic_inc_return(&t->res_get) == 2)

  dev_err(t->dev,

  "ERR no:0x%x,found_vdoa:%d,get ipu twice\n",

@@ -1269,6 +1276,8 @@ static void put_vdoa_ipu_res(struct ipu_task_entry *tsk, int vdoa_only)

  goto out;

  }

  }

+ if (tsk->overlay_en)

+ tbl->overlay_used = 0;

  tbl->used[tsk->ipu_id][tsk->task_id - 1] = 0;

  rel_ipu = 1;

--

0 Kudos