Open lachlansmith opened 2 years ago
FYI - @mateusz-holenko
@michalsieron will take a look at that
Hi @michalsieron thanks for looking at this. Hope you're not delving too deep cause I'd like to actually implement this and learn from it. I've more or less just hit a road block with the theory of calculating csr size and determining the gpio indexes.
Sorry for late answer, but here is what I was able to find
SPI driver in Zephyr for LiteX is slightly outdated and has incorrect offset for loopback register.
If you open SPIMaster
implementation in LiteX you can see that previous register - chip select - has two flags on offsets 0 and 16. This means, that with 8-bit CSRs, it will take 3 subregisters - 17 bits require 3 bytes, so 3 subregisters with 8-bit CSRs.
With 32-bit CSRs, this shouldn't matter, because 3 bytes fit in one 4-byte subregister anyway, so offsets are correct.
But this makes me wonder, whether there are other things to fix in this driver.
We will take a look at that.
I believe, that at the time drivers were being written, those sizes were just sum of bytes taken in address space by CSRs assigned to given node. So for example uart0
would have rxtx
, txfull
, rxempty
, ev_status
, ev_pending
, ev_enable
, txempty
and rxfull
registers. Each of them fits inside one byte, so together they would take 8 subregisters and because each subregister is aligned to 4 bytes we get 8 * 4 = 32 = 0x20
. I would imagine it goes the same for other handlers as well.
With changes I made in https://github.com/zephyrproject-rtos/zephyr/pull/45198 and https://github.com/enjoy-digital/litex/pull/1287, you can easily see what is going on.
&uart0 {
reg = <0xf0001800 0x4
0xf0001804 0x4
0xf0001808 0x4
0xf000180c 0x4
0xf0001810 0x4
0xf0001814 0x4
0xf0001818 0x4
0xf000181c 0x4>;
reg-names = "rxtx",
"txfull",
"rxempty",
"ev_status",
"ev_pending",
"ev_enable",
"txempty",
"rxfull";
interrupts = <0x2 0>;
};
You can see that even though some of those registers are just 1 bit flags, their sizes are 4 bytes anyway. That is because the script generates overlay from csr.json file, where size is provided in number of subregisters. As number of subregisters is useless for driver when using LiteX HAL from https://github.com/zephyrproject-rtos/zephyr/pull/45196/, I normalized sizes to bytes.
You may have also noticed, there is no handler for spi
, only for spiflash
. It means, that even if you were to add SPIMaster
to your SoC, the script wouldn't generate overlay for it (unless you name the SPI submodule spiflash
or change the name in handler).
There are also no handles for gpio
nodes.
If you wrote those overlays yourself, do remember that number of gpios is configured with ngpios
parameter (link to docs). Right now, there is no information on number of gpio pins in csr.json file, so the script cannot generate an overlay for it.
@mateusz-holenko - Please review this.
Added my comments to #1287
Hi @michalsieron, thanks for the breakdown and going over spi in more detail. I am mostly interested in spi. With one of my peripherals requiring it and litex,uart0 not supporting interrupts, I'll also need it to get BT HCI working.
So using the csr.json I attached prior with spi0. The registers with sizes are spi_control:2
, spi_status:1
, spi_mosi:1
, spi_miso:1
, spi_cs:3
and spi_loopback:1
. Since csr.json provides these register sizes in number of subregisters the total size of spi0 is 9 * 4 = 36 = 0x24
?
This makes sense however still doesn't sit well with me. From zephyr > dts > riscv > riscv32-litex-vexriscv.dtsi spi0 is originally defined with a register size of 0x34, which is not a multiple of 4. This node also references interrupts at position 5, however, the spi_litespi.c
driver doesn't use any interrupts. So I'm unsure how this node was written and if it is since outdated it very much distracted me from reaching the above conclusion.
spi0: spi@e0002000 {
compatible = "litex,spi";
interrupt-parent = <&intc0>;
interrupts = <5 0>;
reg = <0xe0002000 0x34>;
reg-names = "control";
label = "spi0";
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
I wrote the spi and gpio_out overlay handles because I assume the intended workflow for developing with Zephyr & LiteX is to do so. Otherwise, eth and i2c are really the only two supported transports at the moment.
Thanks for flagging up ngpios. With gpio thats okay if a script can't generate it, however, can a pins index still be determined somehow? Is it simply the order the pins are passed into GPIOOut?
Hi @michalsieron could help me understand why SPIMaster is generating spi_cs
with size 3.
"spi_cs": {
"addr": 4026540052,
"size": 3,
"type": "rw"
}
The Zephyr driver spi_litespi.h
expects this register to have size 1, 0x18 - 0x14 = 0x04 = 1 subregister
. Is it cause the register is rw
?
#define SPI_BASE_ADDR DT_INST_REG_ADDR(0)
#define SPI_CONTROL_REG SPI_BASE_ADDR
#define SPI_STATUS_REG (SPI_BASE_ADDR + 0x08)
#define SPI_MOSI_DATA_REG (SPI_BASE_ADDR + 0x0c)
#define SPI_MISO_DATA_REG (SPI_BASE_ADDR + 0x10)
#define SPI_CS_REG (SPI_BASE_ADDR + 0x14)
#define SPI_LOOPBACK_REG (SPI_BASE_ADDR + 0x18)
Is this what you meant by your comment on incorrect loopback support, given that spi_cs is no longer size 1, and offsetting the loopback register.
Nevermind, re-read the above, been awhile since I've looked back into this
I'm attempting to use HCI SPI with a Particle Argon and an Arty to implement a full-fledged Bluetooth stack, however, I need to confirm the spi & gpio_out nodes are correct before I debug the connection with a logic analyser. I have two main questions:
I'm also curious why litex,spi has interrupts when SPIMaster doesn't generate any in the interrupt map.
I'm wondering how sizes are calculated because this statement in the Wiki still leaves me questioning, _"The size of the CSR segment, and also the number of bits dedicated to accessing LiteX CSRs is dictated by csr_addresswidth" (csr_address_width = 14). I understand these size values are coming from the overlay handlers in
litex/tools/litex_json2dts_zephyr.py
. Yet I can't see how the sizes in csr.json with csr-address-width evaluate to the hardcoded values in the handlers.Built with
csr.json.zip