We’re trying to get two identical MIPI cameras working simultaneously. Our board is configured with two physical camera ports, providing four lanes each. One uses CSI A/B, the other CSI C/D. The Jetson documentation has an example using CSI A/B for one four-lane camera alongside another on the one-lane CSI E bus, but the driver seems to be prepared for our scenario.
Currently our driver can enable either camera, and both work well independently. However, once we enable both cameras at the same time, we get a CSI bus stall, as follows.
I’m including some snippets from our set up, in hopes that someone may notice something obvious. We’re hoping someone out there might have had a similar experience, and can provide us with some tips.
//
// This is a cleaned-up copy of what we get on the syslog. Most of this comes from our driver,
// except the last part where the syncpt timeout is reported. At this point the kernel is locked up.
//
eniac$ tail -f /var/log/syslog
Jan 29 19:48:24 eniac dbus[275]: [system] Successfully activated service 'org.freedesktop.nm_dispatcher'
Jan 29 19:52:54 eniac kernel: [ 5419.860802] ov7251_v4l2 2-0061: ov7251_power_on
Jan 29 19:52:54 eniac kernel: [ 5419.860814] ov7251_v4l2 2-0061: enabling MCLK with 24000000 Hz
Jan 29 19:52:55 eniac kernel: [ 5420.265256] tegra-i2c tegra12-i2c.2: no acknowledge from address 0x61
Jan 29 19:52:55 eniac kernel: [ 5420.268404] ov7251_v4l2 2-0061: setting I2C addr to 0x61
Jan 29 19:52:55 eniac kernel: [ 5420.274545] vi vi.0: 640x480 is supported
Jan 29 19:52:55 eniac kernel: [ 5420.274596] vi vi.0: 640x480 is supported
Jan 29 19:52:55 eniac kernel: [ 5420.275077] vi vi.0: 640x480 is supported
Jan 29 19:52:55 eniac kernel: [ 5420.275119] vi vi.0: 640x480 is supported
Jan 29 19:52:55 eniac kernel: [ 5420.286071] ov7251_v4l2 2-0061: ov7251_s_stream(enable=1)
Jan 29 19:53:17 eniac kernel: [ 5442.259624] ov7251_v4l2 2-0062: ov7251_power_on
Jan 29 19:53:17 eniac kernel: [ 5442.259632] ov7251_v4l2 2-0062: enabling MCLK with 24000000 Hz
Jan 29 19:53:17 eniac kernel: [ 5442.663825] tegra-i2c tegra12-i2c.2: no acknowledge from address 0x62
Jan 29 19:53:17 eniac kernel: [ 5442.666608] ov7251_v4l2 2-0062: setting I2C addr to 0x62
Jan 29 19:53:17 eniac kernel: [ 5442.670827] vi vi.0: 640x480 is supported
Jan 29 19:53:17 eniac kernel: [ 5442.670837] vi vi.0: 640x480 is supported
Jan 29 19:53:17 eniac kernel: [ 5442.670983] vi vi.0: 640x480 is supported
Jan 29 19:53:17 eniac kernel: [ 5442.670991] vi vi.0: 640x480 is supported
Jan 29 19:53:17 eniac kernel: [ 5442.678156] ov7251_v4l2 2-0062: ov7251_s_stream(enable=1)
Jan 29 19:53:17 eniac kernel: [ 5442.877770] vi vi.0: CSI_B/CSI_C syncpt timeout, syncpt = 498, err = -11
Jan 29 19:53:17 eniac kernel: [ 5442.886743] TEGRA_CSI_CSI_CIL_A_STATUS 0x00000000
Jan 29 19:53:17 eniac kernel: [ 5442.894701] TEGRA_CSI_CSI_CILA_STATUS 0x00000000
Jan 29 19:53:17 eniac kernel: [ 5442.902562] TEGRA_CSI_CSI_CIL_B_STATUS 0x00000000
Jan 29 19:53:17 eniac kernel: [ 5442.910861] TEGRA_CSI_CSI_CIL_C_STATUS 0x00000000
Jan 29 19:53:17 eniac kernel: [ 5442.918972] TEGRA_CSI_CSI_CIL_D_STATUS 0x00000000
Jan 29 19:53:17 eniac kernel: [ 5442.927338] TEGRA_CSI_CSI_CIL_E_STATUS 0x00000000
Jan 29 19:53:17 eniac kernel: [ 5442.935583] TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x00000000
Jan 29 19:53:17 eniac kernel: [ 5442.944190] TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x00000080
Jan 29 19:53:17 eniac kernel: [ 5442.953316] TEGRA_VI_CSI_0_ERROR_STATUS 0x00000000
Jan 29 19:53:17 eniac kernel: [ 5442.961584] TEGRA_VI_CSI_1_ERROR_STATUS 0x00000004
Jan 29 19:53:18 eniac kernel: [ 5443.169730] vi vi.0: CSI_B/CSI_C syncpt timeout, syncpt = 499, err = -11
Jan 29 19:53:18 eniac kernel: [ 5443.179176] TEGRA_CSI_CSI_CIL_A_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.187719] TEGRA_CSI_CSI_CILA_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.196022] TEGRA_CSI_CSI_CIL_B_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.203968] TEGRA_CSI_CSI_CIL_C_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.212804] TEGRA_CSI_CSI_CIL_D_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.220304] TEGRA_CSI_CSI_CIL_E_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.228621] TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.237751] TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x00000080
Jan 29 19:53:18 eniac kernel: [ 5443.246563] TEGRA_VI_CSI_0_ERROR_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.254712] TEGRA_VI_CSI_1_ERROR_STATUS 0x00000004
Jan 29 19:53:18 eniac kernel: [ 5443.463255] vi vi.0: CSI_B/CSI_C syncpt timeout, syncpt = 500, err = -11
Jan 29 19:53:18 eniac kernel: [ 5443.470379] TEGRA_CSI_CSI_CIL_A_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.478253] TEGRA_CSI_CSI_CILA_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.486846] TEGRA_CSI_CSI_CIL_B_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.495036] TEGRA_CSI_CSI_CIL_C_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.503348] TEGRA_CSI_CSI_CIL_D_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.511518] TEGRA_CSI_CSI_CIL_E_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.519587] TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.528474] TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x00000080
Jan 29 19:53:18 eniac kernel: [ 5443.537811] TEGRA_VI_CSI_0_ERROR_STATUS 0x00000000
Jan 29 19:53:18 eniac kernel: [ 5443.546449] TEGRA_VI_CSI_1_ERROR_STATUS 0x00000004
[ 5468.031278] BUG: soft lockup - CPU#0 stuck for 22s! [kworker/0:2:2186]
...
//
// This is the left-side camera. [board-ardbeg-sensors.c]
//
static struct i2c_board_info ardbeg_ov7251a_camera_i2c_device = {
I2C_BOARD_INFO("ov7251_v4l2", 0x61),
};
static struct tegra_camera_platform_data ardbeg_ov7251a_camera_platform_data = {
.port = TEGRA_CAMERA_PORT_CSI_A,
.lanes = 1,
};
static struct soc_camera_link ov7251a_iclink = {
.bus_id = 0, /* This must match the .id of tegra_vi01_device */
.board_info = &ardbeg_ov7251a_camera_i2c_device,
.module_name = "ov7251_v4l2",
.i2c_adapter_id = 2,
.priv = &ardbeg_ov7251a_camera_platform_data,
};
static struct platform_device ardbeg_ov7251a_soc_camera_device = {
.name = "soc-camera-pdrv",
.id = 0,
.dev = {
.platform_data = &ov7251a_iclink,
},
};
//
// This is the right-side camera. [board-ardbeg-sensors.c]
//
static struct i2c_board_info ardbeg_ov7251b_camera_i2c_device = {
I2C_BOARD_INFO("ov7251_v4l2", 0x62),
};
static struct tegra_camera_platform_data ardbeg_ov7251b_camera_platform_data = {
.port = TEGRA_CAMERA_PORT_CSI_B,
.lanes = 1,
};
static struct soc_camera_link ov7251b_iclink = {
.bus_id = 0, /* This must match the .id of tegra_vi01_device */
.board_info = &ardbeg_ov7251b_camera_i2c_device,
.module_name = "ov7251_v4l2",
.i2c_adapter_id = 2,
.priv = &ardbeg_ov7251b_camera_platform_data,
};
static struct platform_device ardbeg_ov7251b_soc_camera_device = {
.name = "soc-camera-pdrv",
.id = 1,
.dev = {
.platform_data = &ov7251b_iclink,
},
};
//
// These are used to exit/enter low-power mode. [ov7251_v4l2.c]
//
// The cameras also also work when CSIA is enabled for camera A,
// and CSIB is enabled for camera B, instead of two for each. I
// suspect that CSIB and DSIC are twinned somehow. Both cameras
// use only a single CSI lane.
//
static struct tegra_io_dpd csia_io[] = {
{
.name = "CSIA",
.io_dpd_reg_index = 0,
.io_dpd_bit = 0,
}, {
.name = "CSIB",
.io_dpd_reg_index = 0,
.io_dpd_bit = 1,
},
{ NULL }
};
static struct tegra_io_dpd csib_io[] = {
{
.name = "DSIC",
.io_dpd_reg_index = 1,
.io_dpd_bit = 8,
}, {
.name = "DSID",
.io_dpd_reg_index = 1,
.io_dpd_bit = 9,
},
{ NULL }
};
//
// These are selected later, depending on which camera is used.
//
static struct ov7251_platform_data *
ov7251_pdata_from_soc(struct i2c_client *client)
{
struct soc_camera_link *link = client->dev.platform_data;
struct tegra_camera_platform_data *camera = link->priv;
// ...
switch (camera->port) {
case TEGRA_CAMERA_PORT_CSI_A:
pdata->mclk_name = "vi_sensor";
pdata->pwr_en_gpio = 22*8 + 2; /* W2 */
pdata->pwdn_gpio = 27*8 + 5; /* BB5 */
pdata->csi_io = csia_io;
break;
case TEGRA_CAMERA_PORT_CSI_B:
pdata->mclk_name = "mclk2";
pdata->pwr_en_gpio = 23*8 + 6; /* X6 */
pdata->pwdn_gpio = 27*8 + 6; /* BB6 */
pdata->csi_io = csib_io;
break;
default:
dev_err(&client->dev, "unknown CSI port: %d", camera->port);
return NULL;
}
return pdata;
}