CSI2 debug messages don't seem to be working

I have tried enabling the debug messages with:

echo file csi2_fops.c +p > /sys/kernel/debug/dynamic_debug/control

So I can try and determine what the errors are from these messages:

[ 3344.880772] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 1
[ 3344.897398] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 2
[ 3344.914133] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 3
[ 3344.930800] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 4
[ 3344.947502] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 5
[ 3344.964192] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 6

But nothing changes in the dmesg output. I have verified by catting /sys/kernel/debug/dynamic_debug/control and see the settings have been applied. I did all this with “sudo su”

Any other ideas on why these messages aren’t printing out?

Did you run v4l2-ctl to capture?

I tried and it just would not work. So to get past it, I just hacked the files and had it print out all the time for now:

[ 1465.696580] vi 54080000.vi: TEGRA_CSI_PIXEL_PARSER_STATUS 0x00004000
[ 1465.703053] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 0
[ 1465.713327] vi 54080000.vi: TEGRA_CSI_PIXEL_PARSER_STATUS 0x00004091
[ 1465.719811] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 1
[ 1465.730024] vi 54080000.vi: TEGRA_CSI_PIXEL_PARSER_STATUS 0x00004091
[ 1465.736491] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 2
[ 1465.746625] vi 54080000.vi: TEGRA_CSI_PIXEL_PARSER_STATUS 0x00004091
[ 1465.753061] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 3
[ 1465.763526] vi 54080000.vi: TEGRA_CSI_PIXEL_PARSER_STATUS 0x00004091

So now I can at least see the problems. It’s interesting, the settings in this driver work for the raspberry pi but not for the Jetson. Not sure why.

From the REG CSI*_CSI_PIXEL_PARSER_A_STATUS_0 tell packet head have multi-bit error could be signal or sensor packet didn’t have ECC.

HPA_UNC_HDR_ERR: Uncorrectable Header Error. Set when header parser A parses a header with a
multi-bit error. This error will be detected by the headers ECC, but cannot be corrected. The packet will be discarded.

I’m thinking the problem here is the sensor is sending on 1 lane, not 2, and the CSI port defaults to 2 lanes.

I can see how to change the lanes to 1 if I have modes defined, but for this setup, I just wanted to change the num_lanes to 1 as the default.

I tried to change in the same section of the dtsi as the physical_w is defined (right before the modes) but it doesn’t seem to make a difference.

The reason I know, if I capture 720p, which requires 2 lanes, it works. If I try and capture 480p still not working. I’m thinking the CSI port is expecting data on both lanes.

I don’t see a way to change the lanes CSI is listening for programmatically. I went through the driver and don’t see how CSI receiver can be changes on the fly. (Which is what I would prefer to do)

How do you report the lanes? You should need to modify the bus-width/port-index for the CSI bus lanes configure.

So in the dtsi file, as an experiment I tried changing these:

port@0 {
reg = <0>;
tc358743_out1: endpoint {
port-index = <1>; /* CSI B /
bus-width = <2>; /
Use CSI-B only */
data-lanes = <1 2>;
clock-lanes = <0>;
clock-noncontinuous;
link-frequencies = /bits/ 64 <297000000>;
remote-endpoint = <&tc358743_csi_in0>;
};
};

to

port@0 {
reg = <0>;
tc358743_out1: endpoint {
port-index = <1>; /* CSI B /
bus-width = <1>; /
Use CSI-B only */
data-lanes = <1>;
clock-lanes = <0>;
clock-noncontinuous;
link-frequencies = /bits/ 64 <297000000>;
remote-endpoint = <&tc358743_csi_in0>;
};
};

to tell it only to use one lane. But when I connected a 720p source, and used dmesg, the tc358743 driver indicated 2 lanes were needed and 2 lanes were used. It basically just does the math at what each lane can support and tells the tc358743 how many lanes to send on.

When I switch to a 480p source, the driver indicates 1 lane is needed and 1 lane is used, but the code setting all that is just talking i2c to the source chip (tc358743). I see nothing that reconfigures the CSI port on the Jetson to use 1 lane now.

OK, you need to modify the driver to modify the bus-width at runtime. Current don’t support it.

Ahh okay, do you know of another driver that does this that I can use as a reference to modify this driver?

Check below driver.

snchen@laptop-asus:/media/snchen/project/project/32.4.3/kernel/nvidia/drivers/media/platform/tegra/camera$ grep -ir numlanes
vi/channel.c:           chan->numlanes = 2;
vi/graph.c:                     chan->numlanes = value;
vi/graph.c:                      * for numlanes greater than 4 multiple CSI bricks
vi/graph.c:                      * checks for numlanes > 4 and add a new CSI brick
csi/csi.c:      s_data->numlanes = 12;
csi/csi.c:      unsigned int port, unsigned int numlanes)
csi/csi.c:      s_data->numlanes = numlanes;
csi/csi.c:                      chan->numlanes = value;
csi/csi.c:                       * for numlanes greater than 4 multiple CSI bricks
csi/csi.c:                       * checks for numlanes > 4 and add a new CSI brick
csi/csi.c:      int numlanes = 0;
csi/csi.c:              numlanes = chan->numlanes - (i * MAX_CSI_BLOCK_LANES);
csi/csi.c:              WARN_ON(numlanes < 0);
csi/csi.c:              numlanes = numlanes > MAX_CSI_BLOCK_LANES ?
csi/csi.c:                      MAX_CSI_BLOCK_LANES : numlanes;
csi/csi.c:              chan->ports[i].lanes = numlanes;
csi/csi.c:              item->numlanes = 2;
csi/csi2_fops.c:                if (chan->numlanes <= 2) {
csi/csi2_fops.c:                if (chan->numlanes <= 2) {
camera_common.c:        s_data->numlanes = bus_width;
camera_common.c:                __func__, s_data->csi_port, s_data->numlanes);
camera_common.c:        int numports = (s_data->numlanes + 1) >> 1;
camera_common.c:        int numports = (s_data->numlanes + 1) >> 1;
1 Like

I’ve been digging into this deeper and I don’t really see how the csi port is driven to a different number of lanes.

In the driver, I grabbed the channel with:

struct tegra_csi_channel *chan = to_csi_chan(sd);

And then tried to do

chan->numlanes = 1;

But changing that value doesn’t seem to do anything.

I also notice there is a tegra_csi_port which has a “lanes” variable, but all your examples above are looking at numlanes.

Is there some sort of register I need to write into to get it to switch, or something I need to call to get this change to register?

In the tc358743 code, I am trying to set this in the set_csi command so both the chip and the Tegra are being set to the same number of lanes at the same time.

Thanks!

to_csi_chan is not going to work in this context, it is using container_of and expecting the v4l2_subdev to be a member in a tegra_csi_channel and in this driver, its in a local structure defined in the driver (tc358743_state).

So right now I am trying to figure out how to walk the information I know to get to the proper settings to change.