Error accessing CSI/VI registers of Tegra K1

I’m getting errors such as these when writing/reading to some registers specific to VI/CSI. I am able to access many other registers, but only a few create these errors.

Host write timeout at address 54080844
Host write timeout at address 540809c8

Is there any programming sequence I have to follow to be able to access them? Any internal clocks I should enable beforehand?

Also what does offset and byte offset mean in the TRM? Registers present in a few blocks such as VI/CSI, SOR, DSI etc are given with these two values. But only the byte offset is used when I check in the kernel source code.

Each hardware controller (e.g., GPIO has 8 controllers, not sure what VI/CSI has) has a base location listed in the system address map of page 19 (TRM). Control registers are always listed in the later chapters as an offset because the “shape” of the offset pattern is the same among multiple controllers of the same type. For example, GPIO has 8 controllers for 4 “ports” each (8-bit ports so 32 bits per controller)…the offset for a given control register is the same whether looking at GPIO-1 or GPIO-4. The code used to deal with a single controller can be re-used by pointing to a different base address and re-using offsets.

In many cases the ARM CPU has registers which control/configure multiple pins. For GPIO, each controller has 32 pins which might be controlled, with options to change behavior of 8 pins at a time…so for example, one register might have bits for 8 pin enables or other option. Sometimes a register is 2 bytes in size instead of one byte, with two features controlled in a single register (perhaps combined because they are related). In the case of GPIO the first register is CNF “configuration” which is two bytes in size…low order byte decides up to 8 pins as special purpose (SFIO) or general purpose (GPIO)…alternate behaviors…while the upper order byte is a lock on that behavior (once upper byte bits are 1, SFIO or GPIO is locked and immutable). The next GPIO register (output enable) is only 1 byte in size, and controls only whether output is enabled or not…mutually incompatible with input enable register being enabled. Trying to write one byte to a two byte register could cause problems, just as writing 2 bytes to a 1 byte register is also a problem. Trying to enable both input and output of a GPIO pin at the same time is also an error.

There are also pseudo duplicate second registers in many cases, but their behavior is more selective to avoid inefficient access. Take the GPIO configuration CNF register for example. The first offset is 0x0 (no offset) to the base address at two bytes in size, while the second version is 0x80 bytes offset, and has “mask” in its name. Since one register controls 8 GPIO pins, using the non-mask pin to write to a single pin would require first reading the entire byte, altering only the bits you want to change, and then writing back…slow and inefficient. With the mask register only “1” bits are used…had the second lower order bit been 1, setting the third lower order bit to 1 and all others to 0 only changes only the third lower order bit, leaving the second lower order bit alone and remaining as 1…you can write to 1 pin without altering the other pins.

As an example, the system address map shows GPIO-6 (1-based naming) as 0x6000:d500. CNF is listed later in the GPIO chapter as 0x0 offset (page 277), while the MSK_CNF is listed as 0x80 offset. Port “U” (GPIO-6 has ports “U” through “X” under its control) CNF is thus at 0x6000:d000+0x00, two bytes wide, while the same port for mask access is at 0x6000:d500+0x80 or 0x6000:d580. The CNF without mask requires two byte access, while the mask version requires a single byte access. OE register is 0x10 bytes above base, while OE mask is 0x90 bytes above base (0x6000:d510 and 0x6000:d590).

Possibilities for register change or access failure is that the mode does not allow the operation due to read or write being contrary to what you are doing. Perhaps the mode required cannot even be changed if there is some form of security bit for locking behavior, so changing the register can’t happen without complete reset. If the register controls multiple hardware in some shared way, changing mode might be possible, but only after disabling some other part of the hardware and driving tristate logic high.

Thank you for your insight about these registers. But what you are saying is specific for GPIO registers and I am aware of the lock bits for each GPIO/SFIO. The registers you are talking about has a particular offset and for accessing each byte in the 4byte register we use byte offset. That is understood. What I dont understand is regarding csi/vi registers. Take a look at page 1806 for example (or any register in the CSI/VI block). Each and every 4 byte register is mentioned with an offset and a byte offset. What is the reason for that?

Also There are no lock bits mentioned in the TRM for this block. My suspicion is that I’m missing some particular registers which enable clocks/access to other registers in the CSI/VI block. In the programming sequence given in page 1803 of the TRM, there is no mention about which particular registers are mandatory and which order to follow when writing to these registers. Can anybody help me with that?

And I can confirm that the registers i’m trying to access have the required R/W access. And I dont have to change the modes for them.

What first comes to mind is that there is more than one CSI/VI module, that the first offset is to the start of all modules, that the second offset is to the particular controller. GPIO does this, but GPIO has different notation. So I started writing down addresses to see how they fit together.

Part of the trail of information, here are some related addresses:
System Address Map (both “CSI” and “VI”):

Start 5408:0000    End: 540b:ffff

I see CSI Pixel Stream A, in order:

Offset: 0x20e | Byte Offset: 0x838
Offset: 0x20f | Byte Offset: 0x83c
Offset: 0x210 | Byte Offset: 0x840
Offset: 0x211 | Byte Offset: 0x844
Offset: 0x212 | Byte Offset: 0x848
Offset: 0x213 | Byte Offset: 0x84c
Offset: 0x214 | Byte Offset: 0x850
Offset: 0x215 | Byte Offset: 0x854
Offset: 0x216 | Byte Offset: 0x858

NOTE: 0x54080000 + 0x216 + 0x858 = 0x54080a63

CSI Pixel Stream B, in order:

Offset: 0x21c | Byte Offset: 0x870

NOTE: 0x54080000 + 0x21c = 0x5408021c

If the first offset is one part of data access from base 0x54080000, and then the second offset is added in for a second purpose of any kind (think GPIO mask registers versus regular registers, or even a second mode), then the end of Stream A final register address would overlap the beginning of Stream B register address…this seems unlikely to be implemented.

NOTE: 0x54080000 + 0x216 = 0x54080216
NOTE: 0x54080000 + 0x858 = 0x54080858
NOTE: 0x54080000 + 0x870 = 0x54080870
…adding either first or second offset of Stream A to base remains below Stream B register start regardless of whether Stream B is base address 0x54080000 first offset or second offset.

It seems that the first memory offset and the second byte offset given are separate registers relative to the base 0x5408000. My thought is nVidia is saving document space in these tables, that there are two registers with the same exact bit patterns and purpose, with some variant on how they behave.

I have not read enough to know why nVidia docs do this, I can only speculate the two registers are linked in some way. Perhaps something for CSI uses the first offset and VI uses the second offset…both CSI and VI are listed as the same base offset 0x5408000 in the System Address Map. I just don’t know enough about CSI/VI to make more of a guess.

Well… I’m not sure about that. But thats an interesting theory. I’m gonna go with just the byte offset for now because, that’s how every register is already defined in the camera driver code.

I’m able to access those registers now. Actually those messages didn’t mean that they were inaccessible. Those where just not responding at the time I tried to write to them. Maybe the CSI/VI block was doing some operation in the background when I tried accessing them is my guess. Possibly a mistake on my part.

It would be better if there was an order given in which I should configure each block of the CSI/VI unit. ie. step by step guide on which registers to modify. I know its asking a lot but new h/w configuration is always confusing until you know how it should be done.