diff mbox

[v3,00/24] i.MX Media Driver

Message ID afe51f5f-03dd-4092-9ec0-297afb1453c7@mentor.com (mailing list archive)
State New, archived
Headers show

Commit Message

Steve Longerbeam Jan. 12, 2017, 3:22 a.m. UTC
Hi Tim,


On 01/11/2017 03:14 PM, Tim Harvey wrote:
>
> <snip>
>
> Hi Steve,
>
> I took a stab at testing this today on a gw51xx which has an adv7180
> hooked up as follows:
> - i2c3@0x20
> - 8bit data bus from DAT12 to DAT19, HSYNC, VSYNC, PIXCLK on CSI0 pads
> (CSI0_IPU1)
> - PWRDWN# on MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20
> - IRQ# on MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23
> - all three analog inputs available to off-board connector
>
> My patch to the imx6qdl-gw51xx dtsi is:

As long as you used the patch to imx6qdl-sabreauto.dtsti that adds
the adv7180 support as a guide, you should be ok here.

> <snip>
>
>
>
> On an IMX6Q I'm getting the following when the adv7180 module loads:
> [   12.862477] adv7180 2-0020: chip found @ 0x20 (21a8000.i2c)
> [   12.907767] imx-media: Registered subdev adv7180 2-0020
> [   12.907793] imx-media soc:media@0: Entity type for entity adv7180
> 2-0020 was not initialized!
> [   12.907867] imx-media: imx_media_create_link: adv7180 2-0020:0 ->
> ipu1_csi0_mux:1
>
> Is the warning that adv7180 was not initialized expected and or an issue?

Yeah it's still a bug in the adv7180 driver, needs fixing.

>
> Now that your driver is hooking into the current media framework, I'm
> not at all clear on how to link and configure the media entities.

It's all documented at Documentation/media/v4l-drivers/imx.rst.
Follow the SabreAuto pipeline setup example.



> <snip>
>
>
> Additionally I've found that on an IMX6S/IMX6DL we crash while
> registering the media-ic subdev's:
> [    3.975473] imx-media: Registered subdev ipu1_csi1_mux
> [    3.980921] imx-media: Registered subdev ipu1_csi0_mux
> [    4.003205] imx-media: Registered subdev ipu1_ic_prpenc
> [    4.025373] imx-media: Registered subdev ipu1_ic_prpvf
> [    4.037944] ------------[ cut here ]------------
> [    4.042571] Kernel BUG at c06717dc [verbose debug info unavailable]
> [    4.048845] Internal error: Oops - BUG: 0 [#1] SMP ARM
> [    4.053990] Modules linked in:
> [    4.057076] CPU: 1 PID: 1 Comm: swapper/0 Not tainted
> 4.9.0-rc6-00524-g84dad6e-dirty #446
> [    4.065260] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> ...
> [    4.296250] [<c0671780>] (v4l2_subdev_init) from [<c06fb02c>]
> (imx_ic_probe+0x94/0x1ac)
> [    4.304271] [<c06faf98>] (imx_ic_probe) from [<c05173d8>]
> (platform_drv_probe+0x54/0xb8)
> [    4.312373]  r9:c0d5e858 r8:00000000 r7:fffffdfb r6:c0e5dbf8
> r5:da603810 r4:c16738d8
> [    4.320129] [<c0517384>] (platform_drv_probe) from [<c0515978>]
> (driver_probe_device+0x20c/0x2c0)
> [    4.329010]  r7:c0e5dbf8 r6:00000000 r5:da603810 r4:c16738d8
> [    4.334681] [<c051576c>] (driver_probe_device) from [<c0515af4>]
> (__driver_attach+0xc8/0xcc)
> [    4.343129]  r9:c0d5e858 r8:00000000 r7:00000000 r6:da603844
> r5:c0e5dbf8 r4:da603810
> [    4.350889] [<c0515a2c>] (__driver_attach) from [<c0513adc>]
> (bus_for_each_dev+0x74/0xa8)
> [    4.359078]  r7:00000000 r6:c0515a2c r5:c0e5dbf8 r4:00000000
> [    4.364753] [<c0513a68>] (bus_for_each_dev) from [<c05151d4>]
> (driver_attach+0x20/0x28)
>
> I assume there is an iteration that needs a test on a missing pointer
> only available on chips with both IPU's or PRP

Yep, I only have quad boards here so I haven't gotten around to
testing on S/DL.

But it looks like I forgot to clear out the csi subdev pointer array before
passing it to imx_media_of_parse(). I think that might explain the OOPS
above. Try this patch:


Steve

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Tim Harvey Jan. 12, 2017, 9:13 p.m. UTC | #1
On Wed, Jan 11, 2017 at 7:22 PM, Steve Longerbeam
<steve_longerbeam@mentor.com> wrote:
> Hi Tim,
>
>
> On 01/11/2017 03:14 PM, Tim Harvey wrote:
>>
>>
>> <snip>
>>
>> Hi Steve,
>>
>> I took a stab at testing this today on a gw51xx which has an adv7180
>> hooked up as follows:
>> - i2c3@0x20
>> - 8bit data bus from DAT12 to DAT19, HSYNC, VSYNC, PIXCLK on CSI0 pads
>> (CSI0_IPU1)
>> - PWRDWN# on MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20
>> - IRQ# on MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23
>> - all three analog inputs available to off-board connector
>>
>> My patch to the imx6qdl-gw51xx dtsi is:
>
>
> As long as you used the patch to imx6qdl-sabreauto.dtsti that adds
> the adv7180 support as a guide, you should be ok here.

yes - fairly straightforward

>
>> <snip>
>>
>>
>>
>> On an IMX6Q I'm getting the following when the adv7180 module loads:
>> [   12.862477] adv7180 2-0020: chip found @ 0x20 (21a8000.i2c)
>> [   12.907767] imx-media: Registered subdev adv7180 2-0020
>> [   12.907793] imx-media soc:media@0: Entity type for entity adv7180
>> 2-0020 was not initialized!
>> [   12.907867] imx-media: imx_media_create_link: adv7180 2-0020:0 ->
>> ipu1_csi0_mux:1
>>
>> Is the warning that adv7180 was not initialized expected and or an issue?
>
>
> Yeah it's still a bug in the adv7180 driver, needs fixing.
>

ok - ignoring

>>
>> Now that your driver is hooking into the current media framework, I'm
>> not at all clear on how to link and configure the media entities.
>
>
> It's all documented at Documentation/media/v4l-drivers/imx.rst.
> Follow the SabreAuto pipeline setup example.
>

ah yes... it helps to read your patches! You did a great job on the
documentation.

Regarding the The ipu1_csi0_mux/ipu2_csi1_mux entities which have 1
source and 2 sinks (which makes sense for a mux) how do you know which
sink pad you should use (in your adv7180 example you use the 2nd sink
pad vs the first)?

As my hardware is the same as the SabreAuto except that my adv7180 is
on i2c-2@0x20 I follow your example from
Documentation/media/v4l-drivers/imx.rst:

# Setup links
media-ctl -l '"adv7180 2-0020":0 -> "ipu1_csi0_mux":1[1]'
media-ctl -l '"ipu1_csi0_mux":2 -> "ipu1_csi0":0[1]'
media-ctl -l '"ipu1_csi0":1 -> "ipu1_smfc0":0[1]'
media-ctl -l '"ipu1_smfc0":1 -> "ipu1_ic_prpvf":0[1]'
media-ctl -l '"ipu1_ic_prpvf":1 -> "camif0":0[1]'
media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'

# Configure pads
media-ctl -V "\"adv7180 2-0020\":0 [fmt:UYVY2X8/720x480]"
media-ctl -V "\"ipu1_csi0_mux\":1 [fmt:UYVY2X8/720x480]"
media-ctl -V "\"ipu1_csi0_mux\":2 [fmt:UYVY2X8/720x480]"
media-ctl -V "\"ipu1_csi0\":0 [fmt:UYVY2X8/720x480]"
media-ctl -V "\"ipu1_csi0\":1 [fmt:UYVY2X8/720x480]"
media-ctl -V "\"ipu1_smfc0\":0 [fmt:UYVY2X8/720x480]"
media-ctl -V "\"ipu1_smfc0\":1 [fmt:UYVY2X8/720x480]"
media-ctl -V "\"ipu1_ic_prpvf\":0 [fmt:UYVY2X8/720x480]"
# pad field types for camif can be any format prpvf supports
export outputfmt="UYVY2X8/720x480"
media-ctl -V "\"ipu1_ic_prpvf\":1 [fmt:$outputfmt]"
media-ctl -V "\"camif0\":0 [fmt:$outputfmt]"
media-ctl -V "\"camif0\":1 [fmt:$outputfmt]"

# select AIN1
v4l2-ctl -d0 -i0
Video input set to 0 (ADV7180 Composite on Ain1: ok)
v4l2-ctl -d0 --set-fmt-video=width=720,height=480,pixelformat=UYVY
# capture a single raw frame
v4l2-ctl -d0 --stream-mmap --stream-to=/x.raw --stream-count=1
[ 2092.056394] camif0: pipeline_set_stream failed with -32
VIDIOC_STREAMON: failed: Broken pipe

Enabling debug in drivers/media/media-entity.c I see:
[   38.870087] imx-media soc:media@0: link validation failed for
"ipu1_smfc0":1 -> "ipu1_ic_prpvf":0, error -32

Looking at ipu1_smfc0 and ipu1_ic_prpvf with media-ctl I see:
- entity 12: ipu1_ic_prpvf (2 pads, 8 links)
             type V4L2 subdev subtype Unknown flags 0
             device node name /dev/v4l-subdev3
        pad0: Sink
                [fmt:UYVY2X8/720x480 field:alternate]
                <- "ipu1_csi0":1 []
                <- "ipu1_csi1":1 []
                <- "ipu1_smfc0":1 [ENABLED]
                <- "ipu1_smfc1":1 []
        pad1: Source
                [fmt:UYVY2X8/720x480 field:none]
                -> "camif0":0 [ENABLED]
                -> "camif1":0 []
                -> "ipu1_ic_pp0":0 []
                -> "ipu1_ic_pp1":0 []

- entity 45: ipu1_smfc0 (2 pads, 5 links)
             type V4L2 subdev subtype Unknown flags 0
             device node name /dev/v4l-subdev14
        pad0: Sink
                [fmt:UYVY2X8/720x480]
                <- "ipu1_csi0":1 [ENABLED]
        pad1: Source
                [fmt:UYVY2X8/720x480]
                -> "ipu1_ic_prpvf":0 [ENABLED]
                -> "ipu1_ic_pp0":0 []
                -> "camif0":0 []
                -> "camif1":0 []

Any ideas what is going wrong here? Seems like its perhaps a field
type mismatch. Is my outputfmt incorrect perhaps? I likely have
misunderstood the pad type comments in your documentation.

>
>
>> <snip>
>>
>>
>>
>> Additionally I've found that on an IMX6S/IMX6DL we crash while
>> registering the media-ic subdev's:
<snip>
>
> Yep, I only have quad boards here so I haven't gotten around to
> testing on S/DL.
>
> But it looks like I forgot to clear out the csi subdev pointer array before
> passing it to imx_media_of_parse(). I think that might explain the OOPS
> above. Try this patch:
>
> diff --git a/drivers/staging/media/imx/imx-media-dev.c
> b/drivers/staging/media/imx/imx-media-dev.c
> index 357654d..0cf2d61 100644
> --- a/drivers/staging/media/imx/imx-media-dev.c
> +++ b/drivers/staging/media/imx/imx-media-dev.c
> @@ -379,7 +379,7 @@ static int imx_media_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
>         struct device_node *node = dev->of_node;
> -       struct imx_media_subdev *csi[4];
> +       struct imx_media_subdev *csi[4] = {0};
>         struct imx_media_dev *imxmd;
>         int ret;
>

This does resolves the crash on S/DL.

I do notice that the ipu1_csi*_mux entities on the S/DL have 3 more
sink pads compared to the D/Q which is from the additional ports
defined in the GPR nodes you add for mipi_vc1/vc2/vc3. Are there
really 3 more MIPI virtual channels on the S/DL vs the D/Q?

I get the same results on the S/DL as I do on D/Q as long as I adjust
the links to compensate for these additional sinks:
media-ctl -l '"adv7180 2-0020":0 -> "ipu1_csi0_mux":4[1]'  # pad4
media-ctl -l '"ipu1_csi0_mux":5 -> "ipu1_csi0":0[1]' # pad5
...

This means link configuration must differ depending on S/DL vs D/Q
which is a bummer but I suppose this is the harsh reality as for
boards that use the EIM pads for IPU's they also will be using IPU2
for IMX6D/Q and IPU1 for IMX6S/DL.

Tim
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Steve Longerbeam Jan. 12, 2017, 10:32 p.m. UTC | #2
Hi Tim,


On 01/12/2017 01:13 PM, Tim Harvey wrote:
>
>>> Now that your driver is hooking into the current media framework, I'm
>>> not at all clear on how to link and configure the media entities.
>>
>> It's all documented at Documentation/media/v4l-drivers/imx.rst.
>> Follow the SabreAuto pipeline setup example.
>>
> ah yes... it helps to read your patches! You did a great job on the
> documentation.
>
> Regarding the The ipu1_csi0_mux/ipu2_csi1_mux entities which have 1
> source and 2 sinks (which makes sense for a mux) how do you know which
> sink pad you should use (in your adv7180 example you use the 2nd sink
> pad vs the first)?

The adv7180 can only go to the parallel input pad (ipu1_csi0_mux:1
on quad). The other input pads select from the mipi csi-2 receiver virtual
channels.

Have you generated a dot graph? It makes it much easier to
visualize:

# media-ctl --print-dot > graph.dot

then on your host:

% dot -Tpng graph.dot > graph.png


>
> As my hardware is the same as the SabreAuto except that my adv7180 is
> on i2c-2@0x20 I follow your example from
> Documentation/media/v4l-drivers/imx.rst:
>
> # Setup links
> media-ctl -l '"adv7180 2-0020":0 -> "ipu1_csi0_mux":1[1]'
> media-ctl -l '"ipu1_csi0_mux":2 -> "ipu1_csi0":0[1]'
> media-ctl -l '"ipu1_csi0":1 -> "ipu1_smfc0":0[1]'
> media-ctl -l '"ipu1_smfc0":1 -> "ipu1_ic_prpvf":0[1]'
> media-ctl -l '"ipu1_ic_prpvf":1 -> "camif0":0[1]'
> media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'
>
> # Configure pads
> media-ctl -V "\"adv7180 2-0020\":0 [fmt:UYVY2X8/720x480]"
> media-ctl -V "\"ipu1_csi0_mux\":1 [fmt:UYVY2X8/720x480]"
> media-ctl -V "\"ipu1_csi0_mux\":2 [fmt:UYVY2X8/720x480]"
> media-ctl -V "\"ipu1_csi0\":0 [fmt:UYVY2X8/720x480]"
> media-ctl -V "\"ipu1_csi0\":1 [fmt:UYVY2X8/720x480]"
> media-ctl -V "\"ipu1_smfc0\":0 [fmt:UYVY2X8/720x480]"
> media-ctl -V "\"ipu1_smfc0\":1 [fmt:UYVY2X8/720x480]"
> media-ctl -V "\"ipu1_ic_prpvf\":0 [fmt:UYVY2X8/720x480]"
> # pad field types for camif can be any format prpvf supports
> export outputfmt="UYVY2X8/720x480"
> media-ctl -V "\"ipu1_ic_prpvf\":1 [fmt:$outputfmt]"
> media-ctl -V "\"camif0\":0 [fmt:$outputfmt]"
> media-ctl -V "\"camif0\":1 [fmt:$outputfmt]"
>
> # select AIN1
> v4l2-ctl -d0 -i0
> Video input set to 0 (ADV7180 Composite on Ain1: ok)
> v4l2-ctl -d0 --set-fmt-video=width=720,height=480,pixelformat=UYVY
> # capture a single raw frame
> v4l2-ctl -d0 --stream-mmap --stream-to=/x.raw --stream-count=1
> [ 2092.056394] camif0: pipeline_set_stream failed with -32
> VIDIOC_STREAMON: failed: Broken pipe
>
> Enabling debug in drivers/media/media-entity.c I see:
> [   38.870087] imx-media soc:media@0: link validation failed for
> "ipu1_smfc0":1 -> "ipu1_ic_prpvf":0, error -32
>
> Looking at ipu1_smfc0 and ipu1_ic_prpvf with media-ctl I see:
> - entity 12: ipu1_ic_prpvf (2 pads, 8 links)
>               type V4L2 subdev subtype Unknown flags 0
>               device node name /dev/v4l-subdev3
>          pad0: Sink
>                  [fmt:UYVY2X8/720x480 field:alternate]
>                  <- "ipu1_csi0":1 []
>                  <- "ipu1_csi1":1 []
>                  <- "ipu1_smfc0":1 [ENABLED]
>                  <- "ipu1_smfc1":1 []
>          pad1: Source
>                  [fmt:UYVY2X8/720x480 field:none]
>                  -> "camif0":0 [ENABLED]
>                  -> "camif1":0 []
>                  -> "ipu1_ic_pp0":0 []
>                  -> "ipu1_ic_pp1":0 []
>
> - entity 45: ipu1_smfc0 (2 pads, 5 links)
>               type V4L2 subdev subtype Unknown flags 0
>               device node name /dev/v4l-subdev14
>          pad0: Sink
>                  [fmt:UYVY2X8/720x480]
>                  <- "ipu1_csi0":1 [ENABLED]
>          pad1: Source
>                  [fmt:UYVY2X8/720x480]
>                  -> "ipu1_ic_prpvf":0 [ENABLED]
>                  -> "ipu1_ic_pp0":0 []
>                  -> "camif0":0 []
>                  -> "camif1":0 []
>
> Any ideas what is going wrong here? Seems like its perhaps a field
> type mismatch.

Yes, exactly, you'll need to set the field types on every pad in your
pipeline.

>   Is my outputfmt incorrect perhaps? I likely have
> misunderstood the pad type comments in your documentation.

Attached is an update doc (from branch imx-media-staging-md-v7 on my fork).
I recently upgraded my v4l-utils package and media-ctl now supports 
specifying
the field type in the pad format strings. If you don't have the latest 
v4l-utils, it's
fairly straightforward to cross-build.

>
>>
>>> <snip>
>>>
>>>
>>>
>>> Additionally I've found that on an IMX6S/IMX6DL we crash while
>>> registering the media-ic subdev's:
> <snip>
>> Yep, I only have quad boards here so I haven't gotten around to
>> testing on S/DL.
>>
>> But it looks like I forgot to clear out the csi subdev pointer array before
>> passing it to imx_media_of_parse(). I think that might explain the OOPS
>> above. Try this patch:
>>
>> diff --git a/drivers/staging/media/imx/imx-media-dev.c
>> b/drivers/staging/media/imx/imx-media-dev.c
>> index 357654d..0cf2d61 100644
>> --- a/drivers/staging/media/imx/imx-media-dev.c
>> +++ b/drivers/staging/media/imx/imx-media-dev.c
>> @@ -379,7 +379,7 @@ static int imx_media_probe(struct platform_device *pdev)
>>   {
>>          struct device *dev = &pdev->dev;
>>          struct device_node *node = dev->of_node;
>> -       struct imx_media_subdev *csi[4];
>> +       struct imx_media_subdev *csi[4] = {0};
>>          struct imx_media_dev *imxmd;
>>          int ret;
>>
> This does resolves the crash on S/DL.

Cool thanks for verifying, I've applied this to the imx-media-staging-md-v7
branch.

>
> I do notice that the ipu1_csi*_mux entities on the S/DL have 3 more
> sink pads compared to the D/Q which is from the additional ports
> defined in the GPR nodes you add for mipi_vc1/vc2/vc3. Are there
> really 3 more MIPI virtual channels on the S/DL vs the D/Q?

Well, same number of virtual channels on quad vs S/DL. It's
just that the video mux on S/DL can select from all 4 virtual
channels, whereas quad's mux'es only select either vc0 or vc3.

>
> I get the same results on the S/DL as I do on D/Q as long as I adjust
> the links to compensate for these additional sinks:
> media-ctl -l '"adv7180 2-0020":0 -> "ipu1_csi0_mux":4[1]'  # pad4
> media-ctl -l '"ipu1_csi0_mux":5 -> "ipu1_csi0":0[1]' # pad5
> ...
>
> This means link configuration must differ depending on S/DL vs D/Q
> which is a bummer but I suppose this is the harsh reality as for
> boards that use the EIM pads for IPU's they also will be using IPU2
> for IMX6D/Q and IPU1 for IMX6S/DL.

yeah, the links necessarily must be different between quad and S/DL.

Steve
i.MX Video Capture Driver
=========================

Introduction
------------

The Freescale i.MX5/6 contains an Image Processing Unit (IPU), which
handles the flow of image frames to and from capture devices and
display devices.

For image capture, the IPU contains the following internal subunits:

- Image DMA Controller (IDMAC)
- Camera Serial Interface (CSI)
- Image Converter (IC)
- Sensor Multi-FIFO Controller (SMFC)
- Image Rotator (IRT)
- Video De-Interlace Controller (VDIC)

The IDMAC is the DMA controller for transfer of image frames to and from
memory. Various dedicated DMA channels exist for both video capture and
display paths.

The CSI is the frontend capture unit that interfaces directly with
capture sensors over Parallel, BT.656/1120, and MIPI CSI-2 busses.

The IC handles color-space conversion, resizing, and rotation
operations. There are three independent "tasks" within the IC that can
carry out conversions concurrently: pre-processing encoding,
pre-processing preview, and post-processing.

The SMFC is composed of four independent channels that each can transfer
captured frames from sensors directly to memory concurrently.

The IRT carries out 90 and 270 degree image rotation operations.

The VDIC handles the conversion of interlaced video to progressive, with
support for different motion compensation modes (low, medium, and high
motion). The deinterlaced output frames from the VDIC can be sent to the
IC pre-process preview task for further conversions.

In addition to the IPU internal subunits, there are also two units
outside the IPU that are also involved in video capture on i.MX:

- MIPI CSI-2 Receiver for camera sensors with the MIPI CSI-2 bus
  interface. This is a Synopsys DesignWare core.
- A video multiplexer for selecting among multiple sensor inputs to
  send to a CSI.

For more info, refer to the latest versions of the i.MX5/6 reference
manuals listed under References.


Features
--------

Some of the features of this driver include:

- Many different pipelines can be configured via media controller API,
  that correspond to the hardware video capture pipelines supported in
  the i.MX.

- Supports parallel, BT.565, and MIPI CSI-2 interfaces.

- Up to four concurrent sensor acquisitions, by configuring each
  sensor's pipeline using independent entities. This is currently
  demonstrated with the SabreSD and SabreLite reference boards with
  independent OV5642 and MIPI CSI-2 OV5640 sensor modules.

- Scaling, color-space conversion, and image rotation via IC task
  subdevs.

- Many pixel formats supported (RGB, packed and planar YUV, partial
  planar YUV).

- The IC pre-process preview subdev supports motion compensated
  de-interlacing using the VDIC, with three motion compensation modes:
  low, medium, and high motion. The mode is specified with a custom
  control. Pipelines are defined that allow sending frames to the
  preview subdev directly from the CSI or from the SMFC.

- Includes a Frame Interval Monitor (FIM) that can correct vertical sync
  problems with the ADV718x video decoders. See below for a description
  of the FIM.


Capture Pipelines
-----------------

The following describe the various use-cases supported by the pipelines.

The links shown do not include the frontend sensor, video mux, or mipi
csi-2 receiver links. This depends on the type of sensor interface
(parallel or mipi csi-2). So in all cases, these pipelines begin with:

sensor -> ipu_csi_mux -> ipu_csi -> ...

for parallel sensors, or:

sensor -> imx-mipi-csi2 -> (ipu_csi_mux) -> ipu_csi -> ...

for mipi csi-2 sensors. The imx-mipi-csi2 receiver may need to route
to the video mux (ipu_csi_mux) before sending to the CSI, depending
on the mipi csi-2 virtual channel, hence ipu_csi_mux is shown in
parenthesis.

Unprocessed Video Capture:
--------------------------

Send frames directly from sensor to camera interface, with no
conversions:

-> ipu_smfc -> camif

Note the ipu_smfc can do pixel reordering within the same colorspace.
For example, its sink pad can take UYVY2X8, but its source pad can
output YUYV2X8.

IC Direct Conversions:
----------------------

This pipeline uses the preprocess encode entity to route frames directly
from the CSI to the IC (bypassing the SMFC), to carry out scaling up to
1024x1024 resolution, CSC, and image rotation:

-> ipu_ic_prpenc -> camif

This can be a useful capture pipeline for heavily loaded memory bus
traffic environments, since it has minimal IDMAC channel usage.

Post-Processing Conversions:
----------------------------

This pipeline routes frames from the SMFC to the post-processing
entity. In addition to CSC and rotation, this entity supports tiling
which allows scaled output beyond the 1024x1024 limitation of the IC
(up to 4096x4096 scaling output is supported):

-> ipu_smfc -> ipu_ic_pp -> camif

Motion Compensated De-interlace:
--------------------------------

This pipeline routes frames from the SMFC to the preprocess preview
entity to support motion-compensated de-interlacing using the VDIC,
scaling up to 1024x1024, and CSC:

-> ipu_smfc -> ipu_ic_prpvf -> camif

This pipeline also carries out the same conversions as above, but routes
frames directly from the CSI to the IC preprocess preview entity for
minimal memory bandwidth usage (note: this pipeline only works in
"high motion" mode):

-> ipu_ic_prpvf -> camif

This pipeline takes the motion-compensated de-interlaced frames and
sends them to the post-processor, to support motion-compensated
de-interlacing, scaling up to 4096x4096, CSC, and rotation:

-> (ipu_smfc) -> ipu_ic_prpvf -> ipu_ic_pp -> camif


Usage Notes
-----------

Many of the subdevs require information from the active sensor in the
current pipeline when configuring pad formats. Therefore the media links
should be established before configuring the media pad formats.

Similarly, the capture v4l2 interface subdev inherits controls from the
active subdevs in the current pipeline at link-setup time. Therefore the
capture links should be the last links established in order for capture
to "see" and inherit all possible controls.

The following are usage notes for Sabre- reference platforms:


SabreLite with OV5642 and OV5640
--------------------------------

This platform requires the OmniVision OV5642 module with a parallel
camera interface, and the OV5640 module with a MIPI CSI-2
interface. Both modules are available from Boundary Devices:

https://boundarydevices.com/products/nit6x_5mp
https://boundarydevices.com/product/nit6x_5mp_mipi

Note that if only one camera module is available, the other sensor
node can be disabled in the device tree.

The OV5642 module is connected to the parallel bus input on the i.MX
internal video mux to IPU1 CSI0. It's i2c bus connects to i2c bus 2.

The MIPI CSI-2 OV5640 module is connected to the i.MX internal MIPI CSI-2
receiver, and the four virtual channel outputs from the receiver are
routed as follows: vc0 to the IPU1 CSI0 mux, vc1 directly to IPU1 CSI1,
vc2 directly to IPU2 CSI0, and vc3 to the IPU2 CSI1 mux. The OV5640 is
also connected to i2c bus 2 on the SabreLite, therefore the OV5642 and
OV5640 must not share the same i2c slave address.

The following basic example configures unprocessed video capture
pipelines for both sensors. The OV5642 is routed to camif0
(usually /dev/video0), and the OV5640 (transmitting on mipi csi-2
virtual channel 1) is routed to camif1 (usually /dev/video1). Both
sensors are configured to output 640x480, the OV5642 outputs YUYV2X8,
the OV5640 UYVY2X8:

.. code-block:: none

   # Setup links for OV5642
   media-ctl -l '"ov5642 1-0042":0 -> "ipu1_csi0_mux":1[1]'
   media-ctl -l '"ipu1_csi0_mux":2 -> "ipu1_csi0":0[1]'
   media-ctl -l '"ipu1_csi0":1 -> "ipu1_smfc0":0[1]'
   media-ctl -l '"ipu1_smfc0":1 -> "camif0":0[1]'
   media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'
   # Setup links for OV5640
   media-ctl -l '"ov5640_mipi 1-0040":0 -> "imx-mipi-csi2":0[1]'
   media-ctl -l '"imx-mipi-csi2":2 -> "ipu1_csi1":0[1]'
   media-ctl -l '"ipu1_csi1":1 -> "ipu1_smfc1":0[1]'
   media-ctl -l '"ipu1_smfc1":1 -> "camif1":0[1]'
   media-ctl -l '"camif1":1 -> "camif1 devnode":0[1]'
   # Configure pads for OV5642 pipeline
   media-ctl -V "\"ov5642 1-0042\":0 [fmt:YUYV2X8/640x480 field:none]"
   media-ctl -V "\"ipu1_csi0_mux\":1 [fmt:YUYV2X8/640x480 field:none]"
   media-ctl -V "\"ipu1_csi0_mux\":2 [fmt:YUYV2X8/640x480 field:none]"
   media-ctl -V "\"ipu1_csi0\":0 [fmt:YUYV2X8/640x480 field:none]"
   media-ctl -V "\"ipu1_csi0\":1 [fmt:YUYV2X8/640x480 field:none]"
   media-ctl -V "\"ipu1_smfc0\":0 [fmt:YUYV2X8/640x480 field:none]"
   media-ctl -V "\"ipu1_smfc0\":1 [fmt:UYVY2X8/640x480 field:none]"
   media-ctl -V "\"camif0\":0 [fmt:UYVY2X8/640x480 field:none]"
   media-ctl -V "\"camif0\":1 [fmt:UYVY2X8/640x480 field:none]"
   # Configure pads for OV5640 pipeline
   media-ctl -V "\"ov5640_mipi 1-0040\":0 [fmt:UYVY2X8/640x480 field:none]"
   media-ctl -V "\"imx-mipi-csi2\":0 [fmt:UYVY2X8/640x480 field:none]"
   media-ctl -V "\"imx-mipi-csi2\":2 [fmt:UYVY2X8/640x480 field:none]"
   media-ctl -V "\"ipu1_csi1\":0 [fmt:UYVY2X8/640x480 field:none]"
   media-ctl -V "\"ipu1_csi1\":1 [fmt:UYVY2X8/640x480 field:none]"
   media-ctl -V "\"ipu1_smfc1\":0 [fmt:UYVY2X8/640x480 field:none]"
   media-ctl -V "\"ipu1_smfc1\":1 [fmt:UYVY2X8/640x480 field:none]"
   media-ctl -V "\"camif1\":0 [fmt:UYVY2X8/640x480 field:none]"
   media-ctl -V "\"camif1\":1 [fmt:UYVY2X8/640x480 field:none]"

Streaming can then begin independently on device nodes /dev/video0
and /dev/video1.

SabreAuto with ADV7180 decoder
------------------------------

On the SabreAuto, an on-board ADV7180 SD decoder is connected to the
parallel bus input on the internal video mux to IPU1 CSI0.

The following example configures a pipeline to capture from the ADV7180
video decoder, assuming NTSC 720x480 input signals, with Motion
Compensated de-interlacing. Pad field types assume the adv7180 outputs
"alternate". $outputfmt can be any format supported by the
ipu1_ic_prpvf entity at its output pad:

.. code-block:: none

   # Setup links
   media-ctl -l '"adv7180 4-0021":0 -> "ipu1_csi0_mux":1[1]'
   media-ctl -l '"ipu1_csi0_mux":2 -> "ipu1_csi0":0[1]'
   media-ctl -l '"ipu1_csi0":1 -> "ipu1_smfc0":0[1]'
   media-ctl -l '"ipu1_smfc0":1 -> "ipu1_ic_prpvf":0[1]'
   media-ctl -l '"ipu1_ic_prpvf":1 -> "camif0":0[1]'
   media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'
   # Configure pads
   media-ctl -V "\"adv7180 4-0021\":0 [fmt:UYVY2X8/720x480]"
   media-ctl -V "\"ipu1_csi0_mux\":1 [fmt:UYVY2X8/720x480 field:alternate]"
   media-ctl -V "\"ipu1_csi0_mux\":2 [fmt:UYVY2X8/720x480 field:alternate]"
   media-ctl -V "\"ipu1_csi0\":0 [fmt:UYVY2X8/720x480 field:alternate]"
   media-ctl -V "\"ipu1_csi0\":1 [fmt:UYVY2X8/720x480 field:alternate]"
   media-ctl -V "\"ipu1_smfc0\":0 [fmt:UYVY2X8/720x480 field:alternate]"
   media-ctl -V "\"ipu1_smfc0\":1 [fmt:UYVY2X8/720x480 field:alternate]"
   media-ctl -V "\"ipu1_ic_prpvf\":0 [fmt:UYVY2X8/720x480 field:alternate]"
   media-ctl -V "\"ipu1_ic_prpvf\":1 [fmt:$outputfmt field:none]"
   media-ctl -V "\"camif0\":0 [fmt:$outputfmt field:none]"
   media-ctl -V "\"camif0\":1 [fmt:$outputfmt field:none]"

Streaming can then begin on /dev/video0.

This platform accepts Composite Video analog inputs to the ADV7180 on
Ain1 (connector J42) and Ain3 (connector J43).

To switch to Ain1:

.. code-block:: none

   # v4l2-ctl -i0

To switch to Ain3:

.. code-block:: none

   # v4l2-ctl -i1


Frame Interval Monitor
----------------------

The adv718x decoders can occasionally send corrupt fields during
NTSC/PAL signal re-sync (too little or too many video lines). When
this happens, the IPU triggers a mechanism to re-establish vertical
sync by adding 1 dummy line every frame, which causes a rolling effect
from image to image, and can last a long time before a stable image is
recovered. Or sometimes the mechanism doesn't work at all, causing a
permanent split image (one frame contains lines from two consecutive
captured images).

From experiment it was found that during image rolling, the frame
intervals (elapsed time between two EOF's) drop below the nominal
value for the current standard, by about one frame time (60 usec),
and remain at that value until rolling stops.

While the reason for this observation isn't known (the IPU dummy
line mechanism should show an increase in the intervals by 1 line
time every frame, not a fixed value), we can use it to detect the
corrupt fields using a frame interval monitor. If the FIM detects a
bad frame interval, a subdev event is sent. In response, userland can
issue a streaming restart to correct the rolling/split image.

The FIM is implemented in the imx-csi entity, and the entities that have
direct connections to the CSI call into the FIM to monitor the frame
intervals: ipu_smfc, ipu_ic_prpenc, and ipu_prpvf (when configured with
a direct link from ipu_csi). Userland can register with the FIM event
notifications on the imx-csi subdev device node
(V4L2_EVENT_IMX_FRAME_INTERVAL).

The imx-csi entity includes custom controls to tweak some dials for FIM.
If one of these controls is changed during streaming, the FIM will be
reset and will continue at the new settings.

- V4L2_CID_IMX_FIM_ENABLE

Enable/disable the FIM.

- V4L2_CID_IMX_FIM_NUM

How many frame interval errors to average before comparing against the
nominal frame interval reported by the sensor. This can reduce noise
from interrupt latency.

- V4L2_CID_IMX_FIM_TOLERANCE_MIN

If the averaged intervals fall outside nominal by this amount, in
microseconds, streaming will be restarted.

- V4L2_CID_IMX_FIM_TOLERANCE_MAX

If any interval errors are higher than this value, those error samples
are discarded and do not enter into the average. This can be used to
discard really high interval errors that might be due to very high
system load, causing excessive interrupt latencies.

- V4L2_CID_IMX_FIM_NUM_SKIP

How many frames to skip after a FIM reset or stream restart before
FIM begins to average intervals. It has been found that there can
be a few bad frame intervals after stream restart which are not
attributed to adv718x sending a corrupt field, so this is used to
skip those frames to prevent unnecessary restarts.


SabreSD with MIPI CSI-2 OV5640
------------------------------

Similarly to SabreLite, the SabreSD supports a parallel interface
OV5642 module on IPU1 CSI0, and a MIPI CSI-2 OV5640 module. The OV5642
connects to i2c bus 1 and the OV5640 to i2c bus 2.

The device tree for SabreSD includes OF graphs for both the parallel
OV5642 and the MIPI CSI-2 OV5640, but as of this writing only the MIPI
CSI-2 OV5640 has been tested, so the OV5642 node is currently disabled.
The OV5640 module connects to MIPI connector J5 (sorry I don't have the
compatible module part number or URL).

The following example configures a post-processing pipeline to capture
from the OV5640. $sensorfmt can be any format supported by the OV5640.
$outputfmt can be any format supported by the ipu1_ic_pp1 entity at its
output pad:

.. code-block:: none

   # Setup links
   media-ctl -l '"ov5640_mipi 1-003c":0 -> "imx-mipi-csi2":0[1]'
   media-ctl -l '"imx-mipi-csi2":2 -> "ipu1_csi1":0[1]'
   media-ctl -l '"ipu1_csi1":1 -> "ipu1_smfc1":0[1]'
   media-ctl -l '"ipu1_smfc1":1 -> "ipu1_ic_pp1":0[1]'
   media-ctl -l '"ipu1_ic_pp1":1 -> "camif0":0[1]'
   media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'
   # Configure pads
   media-ctl -V "\"ov5640_mipi 1-003c\":0 [fmt:$sensorfmt field:none]"
   media-ctl -V "\"imx-mipi-csi2\":0 [fmt:$sensorfmt field:none]"
   media-ctl -V "\"imx-mipi-csi2\":2 [fmt:$sensorfmt field:none]"
   media-ctl -V "\"ipu1_csi1\":0 [fmt:$sensorfmt field:none]"
   media-ctl -V "\"ipu1_csi1\":1 [fmt:$sensorfmt field:none]"
   media-ctl -V "\"ipu1_smfc1\":0 [fmt:$sensorfmt field:none]"
   media-ctl -V "\"ipu1_smfc1\":1 [fmt:$sensorfmt field:none]"
   media-ctl -V "\"ipu1_ic_pp1\":0 [fmt:$sensorfmt field:none]"
   media-ctl -V "\"ipu1_ic_pp1\":1 [fmt:$outputfmt field:none]"
   media-ctl -V "\"camif0\":0 [fmt:$outputfmt field:none]"
   media-ctl -V "\"camif0\":1 [fmt:$outputfmt field:none]"

Streaming can then begin on /dev/video0.



Known Issues
------------

1. When using 90 or 270 degree rotation control at capture resolutions
   near the IC resizer limit of 1024x1024, and combined with planar
   pixel formats (YUV420, YUV422p), frame capture will often fail with
   no end-of-frame interrupts from the IDMAC channel. To work around
   this, use lower resolution and/or packed formats (YUYV, RGB3, etc.)
   when 90 or 270 rotations are needed.


File list
---------

drivers/staging/media/imx/
include/media/imx.h
include/uapi/media/imx.h

References
----------

[1] "i.MX 6Dual/6Quad Applications Processor Reference Manual"
[2] "i.MX 6Solo/6DualLite Applications Processor Reference Manual"


Author
------
Steve Longerbeam <steve_longerbeam@mentor.com>

Copyright (C) 2012-2016 Mentor Graphics Inc.
Tim Harvey Jan. 13, 2017, 9:04 p.m. UTC | #3
On Thu, Jan 12, 2017 at 2:32 PM, Steve Longerbeam <slongerbeam@gmail.com> wrote:
> Hi Tim,
>
>
> On 01/12/2017 01:13 PM, Tim Harvey wrote:
>>
>>
>>>> Now that your driver is hooking into the current media framework, I'm
>>>> not at all clear on how to link and configure the media entities.
>>>
>>>
>>> It's all documented at Documentation/media/v4l-drivers/imx.rst.
>>> Follow the SabreAuto pipeline setup example.
>>>
>> ah yes... it helps to read your patches! You did a great job on the
>> documentation.
>>
>> Regarding the The ipu1_csi0_mux/ipu2_csi1_mux entities which have 1
>> source and 2 sinks (which makes sense for a mux) how do you know which
>> sink pad you should use (in your adv7180 example you use the 2nd sink
>> pad vs the first)?
>
>
> The adv7180 can only go to the parallel input pad (ipu1_csi0_mux:1
> on quad). The other input pads select from the mipi csi-2 receiver virtual
> channels.

right - my question was how does the user know which pad is which. I
see that the imx6q.dtsi makes it clear that port0 (sink1) is the mipi
port and port1 is the parallel port (sink2). Do you know how a user
would determine this from runtime information (maybe something via
media-ctl or /sys/class/media that I haven't yet found) or perhaps
this is to be taken care of by documentation or referring to the dts?

>
> Have you generated a dot graph? It makes it much easier to
> visualize:
>
> # media-ctl --print-dot > graph.dot
>
> then on your host:
>
> % dot -Tpng graph.dot > graph.png
>

Yes - that makes it much easier to understand the possible links.

I notice 'media-ctl --print-topology' shows link and pad type fields,
but 'media-ctl --print-dot' does not include the pad type field (maybe
newer versions do or will in the future)

Do you know how one goes about determining the possible format types
possible for each pad?

>
>
>>
>> As my hardware is the same as the SabreAuto except that my adv7180 is
>> on i2c-2@0x20 I follow your example from
>> Documentation/media/v4l-drivers/imx.rst:
>>
>> # Setup links
>> media-ctl -l '"adv7180 2-0020":0 -> "ipu1_csi0_mux":1[1]'
>> media-ctl -l '"ipu1_csi0_mux":2 -> "ipu1_csi0":0[1]'
>> media-ctl -l '"ipu1_csi0":1 -> "ipu1_smfc0":0[1]'
>> media-ctl -l '"ipu1_smfc0":1 -> "ipu1_ic_prpvf":0[1]'
>> media-ctl -l '"ipu1_ic_prpvf":1 -> "camif0":0[1]'
>> media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'
>>
>> # Configure pads
>> media-ctl -V "\"adv7180 2-0020\":0 [fmt:UYVY2X8/720x480]"
>> media-ctl -V "\"ipu1_csi0_mux\":1 [fmt:UYVY2X8/720x480]"
>> media-ctl -V "\"ipu1_csi0_mux\":2 [fmt:UYVY2X8/720x480]"
>> media-ctl -V "\"ipu1_csi0\":0 [fmt:UYVY2X8/720x480]"
>> media-ctl -V "\"ipu1_csi0\":1 [fmt:UYVY2X8/720x480]"
>> media-ctl -V "\"ipu1_smfc0\":0 [fmt:UYVY2X8/720x480]"
>> media-ctl -V "\"ipu1_smfc0\":1 [fmt:UYVY2X8/720x480]"
>> media-ctl -V "\"ipu1_ic_prpvf\":0 [fmt:UYVY2X8/720x480]"
>> # pad field types for camif can be any format prpvf supports
>> export outputfmt="UYVY2X8/720x480"
>> media-ctl -V "\"ipu1_ic_prpvf\":1 [fmt:$outputfmt]"
>> media-ctl -V "\"camif0\":0 [fmt:$outputfmt]"
>> media-ctl -V "\"camif0\":1 [fmt:$outputfmt]"
>>
>> # select AIN1
>> v4l2-ctl -d0 -i0
>> Video input set to 0 (ADV7180 Composite on Ain1: ok)
>> v4l2-ctl -d0 --set-fmt-video=width=720,height=480,pixelformat=UYVY
>> # capture a single raw frame
>> v4l2-ctl -d0 --stream-mmap --stream-to=/x.raw --stream-count=1
>> [ 2092.056394] camif0: pipeline_set_stream failed with -32
>> VIDIOC_STREAMON: failed: Broken pipe
>>
>> Enabling debug in drivers/media/media-entity.c I see:
>> [   38.870087] imx-media soc:media@0: link validation failed for
>> "ipu1_smfc0":1 -> "ipu1_ic_prpvf":0, error -32
>>
>> Looking at ipu1_smfc0 and ipu1_ic_prpvf with media-ctl I see:
>> - entity 12: ipu1_ic_prpvf (2 pads, 8 links)
>>               type V4L2 subdev subtype Unknown flags 0
>>               device node name /dev/v4l-subdev3
>>          pad0: Sink
>>                  [fmt:UYVY2X8/720x480 field:alternate]
>>                  <- "ipu1_csi0":1 []
>>                  <- "ipu1_csi1":1 []
>>                  <- "ipu1_smfc0":1 [ENABLED]
>>                  <- "ipu1_smfc1":1 []
>>          pad1: Source
>>                  [fmt:UYVY2X8/720x480 field:none]
>>                  -> "camif0":0 [ENABLED]
>>                  -> "camif1":0 []
>>                  -> "ipu1_ic_pp0":0 []
>>                  -> "ipu1_ic_pp1":0 []
>>
>> - entity 45: ipu1_smfc0 (2 pads, 5 links)
>>               type V4L2 subdev subtype Unknown flags 0
>>               device node name /dev/v4l-subdev14
>>          pad0: Sink
>>                  [fmt:UYVY2X8/720x480]
>>                  <- "ipu1_csi0":1 [ENABLED]
>>          pad1: Source
>>                  [fmt:UYVY2X8/720x480]
>>                  -> "ipu1_ic_prpvf":0 [ENABLED]
>>                  -> "ipu1_ic_pp0":0 []
>>                  -> "camif0":0 []
>>                  -> "camif1":0 []
>>
>> Any ideas what is going wrong here? Seems like its perhaps a field
>> type mismatch.
>
>
> Yes, exactly, you'll need to set the field types on every pad in your
> pipeline.
>
>>   Is my outputfmt incorrect perhaps? I likely have
>> misunderstood the pad type comments in your documentation.
>
>
> Attached is an update doc (from branch imx-media-staging-md-v7 on my fork).
> I recently upgraded my v4l-utils package and media-ctl now supports
> specifying
> the field type in the pad format strings. If you don't have the latest
> v4l-utils, it's
> fairly straightforward to cross-build.
>

Your updated imx.rst makes it very clear - I was misunderstanding the
pervious version and comments as it skipped setting the pad field
types.

The v4l-utils-1.10 from Ubuntu 16.04 allows setting field types with
the links so I didn't need to build a newer one and this did resolve
my issue.

>>
>>>
>>>> <snip>
>>>>
>>>>
>>>>
>>>> Additionally I've found that on an IMX6S/IMX6DL we crash while
>>>> registering the media-ic subdev's:
>>
>> <snip>
>>>
>>> Yep, I only have quad boards here so I haven't gotten around to
>>> testing on S/DL.
>>>
>>> But it looks like I forgot to clear out the csi subdev pointer array
>>> before
>>> passing it to imx_media_of_parse(). I think that might explain the OOPS
>>> above. Try this patch:
>>>
>>> diff --git a/drivers/staging/media/imx/imx-media-dev.c
>>> b/drivers/staging/media/imx/imx-media-dev.c
>>> index 357654d..0cf2d61 100644
>>> --- a/drivers/staging/media/imx/imx-media-dev.c
>>> +++ b/drivers/staging/media/imx/imx-media-dev.c
>>> @@ -379,7 +379,7 @@ static int imx_media_probe(struct platform_device
>>> *pdev)
>>>   {
>>>          struct device *dev = &pdev->dev;
>>>          struct device_node *node = dev->of_node;
>>> -       struct imx_media_subdev *csi[4];
>>> +       struct imx_media_subdev *csi[4] = {0};
>>>          struct imx_media_dev *imxmd;
>>>          int ret;
>>>
>> This does resolves the crash on S/DL.
>
>

I now have dts patches ready for the following which have an on-board
ADV7180 SD capture on:
arch/arm/boot/dts/imx6dl-gw52xx.dts
arch/arm/boot/dts/imx6dl-gw53xx.dts
arch/arm/boot/dts/imx6dl-gw54xx.dts
arch/arm/boot/dts/imx6q-gw52xx.dts
arch/arm/boot/dts/imx6q-gw53xx.dts
arch/arm/boot/dts/imx6q-gw54xx.dts
arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
arch/arm/boot/dts/imx6qdl-gw553x.dtsi

So for the above which I've tested with the 'sensor -> ipu_csi_mux ->
ipu_csi -> ipu_smfc -> ipu_ic_prpvf -> camif' pipeline
Tested-by: Tim Harvey <tharvey@gateworks.com>

Thanks for all your continued effort on these drivers!

Tim
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/staging/media/imx/imx-media-dev.c 
b/drivers/staging/media/imx/imx-media-dev.c
index 357654d..0cf2d61 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -379,7 +379,7 @@  static int imx_media_probe(struct platform_device *pdev)
  {
         struct device *dev = &pdev->dev;
         struct device_node *node = dev->of_node;
-       struct imx_media_subdev *csi[4];
+       struct imx_media_subdev *csi[4] = {0};
         struct imx_media_dev *imxmd;
         int ret;