Accessing FPGA registers from u-boot.
I've cobbled together a PCIe driver for u-boot that supports the Cyclone V. I started with the Series 10 FPGA driver already included and using the linux kernel module as an example hacked together a driver that configures properly for Cyclone V.
Here is an example output:
=> run loadfpga
7007204 bytes read in 346 ms (19.3 MiB/s)
=> pci long
PCI Autoconfig: pci class = 1540
PCI Autoconfig: Found P2P bridge, device 0
PCI Autoconfig: BAR 0, I/O, size=0x4, PCI: Failed autoconfig bar 10
PCI Autoconfig: pci class = 264
PCI AutoConfig: falling through to default class
PCI Autoconfig: BAR 0, Mem, size=0x4000,
Scanning PCI devices on bus 0
Found PCI device 00.00.00:
vendor ID = 0x1172
device ID = 0xe000
command register ID = 0x0006
status register = 0x0010
revision ID = 0x01
class code = 0x06 (Bridge device)
sub class code = 0x04
programming interface = 0x00
cache line = 0x08
latency time = 0x00
header type = 0x01
BIST = 0x00
base address 0 = 0xffffffff
base address 1 = 0x00000000
primary bus number = 0x00
secondary bus number = 0x01
subordinate bus number = 0x01
secondary latency timer = 0x00
IO base = 0x00
IO limit = 0x00
secondary status = 0x0000
memory base = 0xc000
memory limit = 0xc000
prefetch memory base = 0x0000
prefetch memory limit = 0x0000
prefetch memory base upper = 0x00000000
prefetch memory limit upper = 0x00000000
IO base upper 16 bits = 0x0000
IO limit upper 16 bits = 0x0000
expansion ROM base address = 0x00000000
interrupt line = 0x00
interrupt pin = 0x01
bridge control = 0x0000
=> pci header 1.0.0
vendor ID = 0x15b7
device ID = 0x5003
command register ID = 0x0006
status register = 0x0010
revision ID = 0x01
class code = 0x01 (Mass storage controller)
sub class code = 0x08
programming interface = 0x02
cache line = 0x08
latency time = 0x00
header type = 0x00
BIST = 0x00
base address 0 = 0xc0000004
base address 1 = 0x00000000
base address 2 = 0x00000000
base address 3 = 0x00000000
base address 4 = 0x00000000
base address 5 = 0x00000000
cardBus CIS pointer = 0x00000000
sub system vendor ID = 0x15b7
sub system ID = 0x5003
expansion ROM base address = 0x00000000
interrupt line = 0xff
interrupt pin = 0x01
min Grant = 0x00
max Latency = 0x00
As you can see, the Cra bus is working and both the root port and the NVMe endpoint are being detected.
The FPGA works in linux. I get about 90MB/s read and 50 MB/s write from and to the NVME device.
I use the u-boot command, "enable bridges 7" to enable all the bridges and that gets the pcie code to initialize and detect the root port and endpoint with the examples shown above.
However, when I attempt to initialize the NVMe, access to BAR0 by the pci auto config code hangs until watchdog, which implies that the Txs bus is not programmed. I have moved it around to see if there is any difference, no matter where I put the Txs (h2f or lwh2f) the hang occurs.
Here's what that looks like, with a little debug output included to see where the hang occurs.
=> nvme scan
Entering nvme_probe, name is: nvme#0
Entering INIT_LIST_HEAD
Entering readl:
trying to readl from 0xc000001c
That is a BAR0 access and for some reason it hangs.
If I simply try to md.l from 0xc0000000, I get the same reaction, a hang.
I have a feeling I'm missing something important that I don't know about. I'm currently figuring out how the WRITE ONLY 0xFF800000 register works. It seems to be set correctly. I have to figure out how the fpga2dram interface is enabled, I'm wondering if that has something to do with it. That has to be enableable somewhere.
If anyone has done this and knows what I'm missing, I'd really appreciate a pointer in the right direction.