AnsweredAssumed Answered

i.MX6 doesn't recognize MIPI clock from ISL79987

Question asked by Puckett on Nov 3, 2017

I'm attempting to interface an Intersil video decoder eval board with a i.MX6Q sabreauto board using the MIPI CSI2 interface.  The i.MX6's MIPI controller always reports that it is unable to detect a DDR clock coming from the decoder in the MIPI_CSI_PHY_STATE register.

 

Sabreauto board info:

MCIMX6xAICPU2

SCH-27925 REV F3

700-27925 REV B.

 

Intersil board info:

ISL79985.87 EVB

It is dated SEP/19/2016 and labelled rev 1.1

 

The ISL79987 decoder supports up to four simultaneous composite video feeds sent to an external processor using a one or two lane MIPI bus.  We only plan on using two of the video inputs but the decoder driver currently configures the decoder to be in four channel mode.

 

We made an interface board to connect the two boards using a flex cable (schematic attached).

 

I'm building our kernel using the FSL community BSP but am using an external kernel source tree since we anticipate some prolonged kernel development.

The kernel version is 4.1.43 and was retrieved from git://github.com/Freescale/linux-fslc.

 

I got the ISL79987 driver and associated kernel changes from this post:

https://community.nxp.com/docs/DOC-158531

I used the patches in the L4.1.15_ISL7998x_Surroundview_Patch_20161122.zip file attached in that post.

Our kernel source differed from the one used to create the patches so I migrated the code changes manually.

The code builds, boots and correctly discovers the decoder over the I2C bus.

 

I added a number of test prints to mxc_mipi_csi2.c in the kernel (including a MIPI register dump) so at bootup I see this:

 

...

udevd[195]: starting eudev-3.2

Galcore version 5.0.11.41671

mipi_csi2_enable() - ret1 = 0, ret2 = 0

isl7998x_hardware_init() - after mipi_csi2_enable()

MIPI_CSI_VERSION = 0x3130302a.

MIPI_CSI_N_LANES = 0x3.

MIPI_CSI_PHY_SHUTDOWNZ = 0x0.

MIPI_CSI_DPHY_RSTZ = 0x0.

MIPI_CSI_CSI2_RESETN = 0x0.

MIPI_CSI_PHY_STATE = 0x200.

MIPI_CSI_DATA_IDS_1 = 0x0.

MIPI_CSI_DATA_IDS_2 = 0x0.

MIPI_CSI_ERR1 = 0x0.

MIPI_CSI_ERR2 = 0x0.

MIPI_CSI_MASK1 = 0x0.

MIPI_CSI_MASK2 = 0x0.

MIPI_CSI_PHY_TST_CTRL0 = 0x0.

MIPI_CSI_PHY_TST_CTRL1 = 0xc00.

mxc_mipi_csi2 21dc000.mipi_csi: mipi_csi2_reset: mipi_lane_bps = 432 Mbps

mxc_mipi_csi2 21dc000.mipi_csi: mipi_csi2_reset: value = 0xc.

isl7998x_hardware_init() - after reg write

MIPI_CSI_VERSION = 0x3130302a.

MIPI_CSI_N_LANES = 0x1.

MIPI_CSI_PHY_SHUTDOWNZ = 0x1.

MIPI_CSI_DPHY_RSTZ = 0x1.

MIPI_CSI_CSI2_RESETN = 0x1.

MIPI_CSI_PHY_STATE = 0x0.

MIPI_CSI_DATA_IDS_1 = 0x0.

MIPI_CSI_DATA_IDS_2 = 0x0.

MIPI_CSI_ERR1 = 0x0.

MIPI_CSI_ERR2 = 0x0.

MIPI_CSI_MASK1 = 0x0.

MIPI_CSI_MASK2 = 0x0.

MIPI_CSI_PHY_TST_CTRL0 = 0x0.

MIPI_CSI_PHY_TST_CTRL1 = 0xc0c.

isl7998x_hardware_init() - after wait for sensor ready

MIPI_CSI_VERSION = 0x3130302a.

MIPI_CSI_N_LANES = 0x1.

MIPI_CSI_PHY_SHUTDOWNZ = 0x1.

MIPI_CSI_DPHY_RSTZ = 0x1.

MIPI_CSI_CSI2_RESETN = 0x1.

MIPI_CSI_PHY_STATE = 0x0.

MIPI_CSI_DATA_IDS_1 = 0x0.

MIPI_CSI_DATA_IDS_2 = 0x0.

MIPI_CSI_ERR1 = 0x0.

MIPI_CSI_ERR2 = 0x0.

MIPI_CSI_MASK1 = 0x0.

MIPI_CSI_MASK2 = 0x0.

MIPI_CSI_PHY_TST_CTRL0 = 0x0.

MIPI_CSI_PHY_TST_CTRL1 = 0xc0c.

mipi csi2 can not receive sensor clk! MIPI_CSI_PHY_STATE = 0x0.

...

 

The value of the MIPI_CSI_PHY_STATE register has varied throughout this process and these are the values I have observed:

0x0

0x200

0x630

 

All of these values indicate that the MIPI controller is not detecting the clock from the decoder.

 

 

The ISL79987 manual has a table defining the clock speed for various video channel/lane configurations:

1 channel, 1 lane = 108MHz

2 channels, 1 lane = 216MHz

2 channels, 2 lanes = 108MHz

4 channels, 1 lane = 432MHz

4 channels, 2 lanes = 216MHz

 

I have confirmed with a scope that clocks with these rates are appearing on the clock lane and have traced them to the connector on our interface board that plugs into the MIPI connector (J7) on the sabreauto board.

 

 

The mipi_csi2_reset() function in mxc_mipi_csi2.c was modified to vary the D-PHY clock value written based on a passed in bps value.  (See attached)

 

The isl7998x_hardware_init() function passes this value like this:

 

/* Only reset MIPI CSI2 HW at sensor initialize */

/* 13.5MHz pixel clock (720*480@30fps) * 16 bits per pixel (YUV422) = 216Mbps mipi data rate for each camera */

mipi_csi2_reset(mipi_csi2_info, (216 * SENSOR_NUM) / (lanes + 1));

 

SENSOR_NUM is defined as 4 and lanes can be 0 or 1.

The result of this calculation is double the expected MIPI clock from the table in the ISL79987 manual.

 

 

The IOMUXC_GPR1 register is configured to correctly select the MIPI interface on the CSI lines using this code in mach-imx6q.c:

 

gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");

if (!IS_ERR(gpr)) {

if (of_machine_is_compatible("fsl,imx6q-sabresd") ||

of_machine_is_compatible("fsl,imx6q-sabreauto"))

regmap_update_bits(gpr, IOMUXC_GPR1, 3 << 19, 0 << 19);

else if (of_machine_is_compatible("fsl,imx6dl-sabresd") ||

 of_machine_is_compatible("fsl,imx6dl-sabreauto"))

regmap_update_bits(gpr, IOMUXC_GPR13, 0x3F, 0x1C);

} else {

pr_err("%s(): failed to find fsl,imx6q-iomux-gpr regmap\n",

       __func__);

}

 

I have attached the modified kernel code I'm currently using and associated schematics,

Unfortunately I am unable to attach any of the ISL79987 documentation at this time.

Outcomes