Camera outputs to 1 buffer only

Could you modify the csi2_fop.c current it hard code as oxA, search the “TEGRA_CSI_CIL_PHY_CONTROL” to find it. The range is 1 - 15

void csi2_start_streaming(struct tegra_csi_device *csi,
                          enum tegra_csi_port_num port_num)
{
        struct tegra_csi_port *port = &csi->ports[port_num];

        csi2_write(csi, TEGRA_CSI_CLKEN_OVERRIDE, 0, port_num >> 1);

        /* Clean up status */
        csi2_pp_write(port, TEGRA_CSI_PIXEL_PARSER_STATUS, 0xFFFFFFFF);
        csi2_cil_write(port, TEGRA_CSI_CIL_STATUS, 0xFFFFFFFF);
        csi2_cil_write(port, TEGRA_CSI_CILX_STATUS, 0xFFFFFFFF);

        csi2_cil_write(port, TEGRA_CSI_CIL_INTERRUPT_MASK, 0x0);

        /* CIL PHY registers setup */
        csi2_cil_write(port, TEGRA_CSI_CIL_PAD_CONFIG0, 0x0);
        csi2_cil_write(port, TEGRA_CSI_CIL_PHY_CONTROL,
                       BYPASS_LP_SEQ | 0xA);

Hi Shane,

I’m not sure what you want me to change.

I found csi2_fops.c file but the function that you identified has a different structure as what you have here. Should I copy the entire code you sent here or do you need me to change a specific setting only (change 0xA to what?)?

If I change specific lines, there might be conflicting variable names as well (*csi argument is named as *chan in the current file).

For reference, here is the current version for csi2_start_streaming function:

int csi2_start_streaming(struct tegra_csi_channel *chan,
				enum tegra_csi_port_num port_num)
{
	struct tegra_csi_port *port = &chan->ports[port_num];
	struct tegra_csi_device *csi = chan->csi;
	struct camera_common_data *s_data = chan->s_data;
	const struct sensor_mode_properties *mode = NULL;
	int csi_port, csi_lanes;
	/* Clocks for the CSI interface */
	const unsigned int cil_clk_mhz = TEGRA_CSICIL_CLK_MHZ;
	const unsigned int csi_clk_mhz = csi->clk_freq / 1000000;
	/* Calculated clock settling times for cil and csi clocks */
	unsigned int cil_settletime = 0;
	unsigned int csi_settletime;

	csi_port = chan->ports[port_num].num;
	csi_lanes = chan->ports[port_num].lanes;

	/* Attempt to find the cil_settingtime from the device tree */
	if (s_data) {
		int idx = s_data->mode_prop_idx;

		dev_dbg(csi->dev, "cil_settingtime is pulled from device");
		if (idx < s_data->sensor_props.num_modes &&
				s_data->sensor_props.sensor_modes != NULL) {
			mode = &s_data->sensor_props.sensor_modes[idx];
			cil_settletime = mode->signal_properties.cil_settletime;
		} else {
			dev_dbg(csi->dev, "mode not listed in DT, use default");
			cil_settletime = 0;
		}
	} else if (chan->of_node) {
		int err = 0;
		const char *str;

		dev_dbg(csi->dev,
			"cil_settletime is pulled from device of_node");
		err = of_property_read_string(chan->of_node, "cil_settletime",
			&str);
		if (!err) {
			err = kstrtou32(str, 10, &cil_settletime);
			if (err)
				dev_dbg(csi->dev,
					"no cil_settletime in of_node");
				cil_settletime = 0;
		}
	}

	/* calculate MIPI settling time if no settletime is set*/
	if (!cil_settletime) {
		dev_dbg(csi->dev, "cil_settingtime was autocalculated");
		cil_settletime = tegra_csi_ths_settling_time(csi,
						cil_clk_mhz,
						csi_clk_mhz);
	}
	csi_settletime = tegra_csi_clk_settling_time(csi,
			cil_clk_mhz);

	dev_dbg(csi->dev, "csi clock settle time: %u, cil settle time: %u",
			csi_settletime, cil_settletime);

	csi_write(chan, TEGRA_CSI_CLKEN_OVERRIDE, 0, csi_port >> 1);

	/* Clean up status */
	pp_write(port, TEGRA_CSI_PIXEL_PARSER_STATUS, 0xFFFFFFFF);
	cil_write(port, TEGRA_CSI_CIL_STATUS, 0xFFFFFFFF);
	cil_write(port, TEGRA_CSI_CILX_STATUS, 0xFFFFFFFF);

	cil_write(port, TEGRA_CSI_CIL_INTERRUPT_MASK, 0x0);

	/* CIL PHY registers setup */
	cil_write(port, TEGRA_CSI_CIL_PAD_CONFIG0, 0x0);
	cil_write(port, TEGRA_CSI_CIL_PHY_CONTROL,
			csi_settletime << CLK_SETTLE_SHIFT |
			BYPASS_LP_SEQ |
			cil_settletime << THS_SETTLE_SHIFT);

For 28.1 it’s hard code as 0xA, I would like you try this REG setting from 1 - 0xf.

Ok, I thought you were referring to the R28.2 file.

I’ll try flashing again using R28.1 and change that REG setting.

Hi Shane,

I’ve already tried all settings of TEGRA_CSI_CIL_PHY_CONTROL from 0x1 to 0xF but it still did not work.

Do you have any other suggestions to try?

Thanks.

Try the BYPASS_LP_SEQ = 0 like below.

#define BYPASS_LP_SEQ (0x0 << 6)

Hi Shane,

Do I need to try that together with different settings of TEGRA_CSI_CIL_PHY_CONTROL from 0x1 to 0xF?

For the values that I’ve tried so far, it still doesn’t work.

You can just need try 3,5,7,9,11,13

Ok, I’ll test it out.

Another info about the issue, when I run v4l2-compliance test, I get a failing test for VIDIOC_G/S_PARM:

v4l2-compliance SHA   : not available

Driver Info:
	Driver name   : tegra-video
	Card type     : vi-output, ar0237 30-0010
	Bus info      : platform:54080000.vi:0
	Driver version: 4.4.38
	Capabilities  : 0x84200001
		Video Capture
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps   : 0x04200001
		Video Capture
		Streaming
		Extended Pix Format

Compliance test for device /dev/video0 (not using libv4l2):

Required ioctls:
	test VIDIOC_QUERYCAP: OK

Allow for multiple opens:
	test second video open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 1 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Test input 0:

	Control ioctls:
		test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
		test VIDIOC_QUERYCTRL: OK
		test VIDIOC_G/S_CTRL: OK
		test VIDIOC_G/S/TRY_EXT_CTRLS: OK
		test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
		test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
		Standard Controls: 1 Private Controls: 16

	Format ioctls:
		test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
		fail: v4l2-test-formats.cpp(1162): ret && node->has_frmintervals
		test VIDIOC_G/S_PARM: FAIL
		test VIDIOC_G_FBUF: OK (Not Supported)
		test VIDIOC_G_FMT: OK
		test VIDIOC_TRY_FMT: OK
		test VIDIOC_S_FMT: OK
		test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
		test Cropping: OK (Not Supported)
		test Composing: OK (Not Supported)
		test Scaling: OK (Not Supported)

	Codec ioctls:
		test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
		test VIDIOC_G_ENC_INDEX: OK (Not Supported)
		test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

	Buffer ioctls:
		test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
		test VIDIOC_EXPBUF: OK

Test input 0:


Total: 43, Succeeded: 42, Failed: 1, Warnings: 0

Maybe this is relevant to the cause of the issue.

Hi Shane,

I’ve already the new settings and it still did not work. I’m still only getting 1 working out of N available v4l2 buffers.

Hi,

Can anyone suggest any other things that we can check?

Try to dump the reg like tegra_csi_status() function after capture failed.

Hi Shane,

I’m confused with what you want me to do.

Do you want to dump the reg data output of the sensor or the reg csi_status from that function?

Where is the tegra_csi_status being dumped?

I’m still new in using Ubuntu and TX1 so it would help a lot if you can specify it more.

Thanks.

OK, just enable the dev_dbg() for the csi2_fops.c and vi2_fops.c

Hi Shane,

I enabled the dev_dbg() for both files. Here is the kernel log write after the capture sequence I did using v4l2:

May 11 06:59:42 tegra-ubuntu kernel: [   93.115666] ar0237 30-0010: ar0237_power_on: power on
May 11 06:59:42 tegra-ubuntu kernel: [   93.176658] vi 54080000.vi: Calibrate csi port 0
May 11 06:59:42 tegra-ubuntu kernel: [   93.181681] ar0237 30-0010: ar0237_s_stream++
May 11 06:59:42 tegra-ubuntu kernel: [   93.186599] ar0237 30-0010: ar0237_s_stream mode[3]
May 11 06:59:42 tegra-ubuntu kernel: [   93.194905] ar0237 30-0010: post ar0237_s_stream mode[3]
May 11 06:59:42 tegra-ubuntu kernel: [   93.200274] ar0237 30-0010: ar0237_s_stream mode[0]
May 11 06:59:42 tegra-ubuntu kernel: [   93.264222] ar0237 30-0010: post ar0237_s_stream mode[0]
May 11 06:59:44 tegra-ubuntu kernel: [   95.391391] ar0237 30-0010: ar0237_s_stream++
May 11 06:59:44 tegra-ubuntu kernel: [   95.396086] ar0237 30-0010: ar0237_s_stream mode[3]
May 11 06:59:44 tegra-ubuntu kernel: [   95.404674] ar0237 30-0010: post ar0237_s_stream mode[3]
May 11 06:59:45 tegra-ubuntu kernel: [   95.422652] ar0237 30-0010: ar0237_power_off: power off

Only

vi 54080000.vi: Calibrate csi port 0

is the new log.

That’s stranger,
Should have “MW_ACK_DONE syncpoint” and then print the CSI reg if capture failed.

Does this mean that there seems to be no error on the csi/vi data input streaming?

Is there a log that we can also enable to check issues on the v4l2 buffer handling?

If without any error that means CSI/VI capture finish normally.
Also check the dev_dbg() can print message.

If I understand it correctly, the issue should now just be coming from V4L2 buffer handling.

This is also more apparent because the blank frames correspond to the number of buffers used (N-1). And it is affecting the dequeue process because some frames are dequeued with both new and old lines in the same frame.

Am I correct? How can we proceed to fixing this issue?