1
0
mirror of synced 2026-01-20 09:35:04 +00:00

access the SDRAM using a custom DMA; unreliable yet

This commit is contained in:
Romain Dolbeau 2021-07-17 11:03:44 -04:00
parent 4303270b53
commit cd9fa81a82
7 changed files with 1006 additions and 56 deletions

View File

@ -110,6 +110,12 @@ sbusfpga_sdram_match(device_t parent, cfdata_t cf, void *aux)
int
sdram_init(struct sbusfpga_sdram_softc *sc);
int
dma_init(struct sbusfpga_sdram_softc *sc);
int
dma_memtest(struct sbusfpga_sdram_softc *sc);
/*
* Attach all the sub-devices we can find
*/
@ -123,11 +129,12 @@ sbusfpga_sdram_attach(device_t parent, device_t self, void *aux)
int sbusburst;
sc->sc_bustag = sa->sa_bustag;
sc->sc_dmatag = sa->sa_dmatag;
sc->sc_dev = self;
aprint_normal("\n");
if (sa->sa_nreg < 2) {
if (sa->sa_nreg < 3) {
aprint_error(": Not enough registers spaces\n");
return;
}
@ -142,7 +149,7 @@ sbusfpga_sdram_attach(device_t parent, device_t self, void *aux)
aprint_error(": cannot map DDR PHY registers\n");
return;
} else {
aprint_normal_dev(self, ": DDR PHY registers @ %p\n", (void*)sc->sc_bhregs_ddrphy);
aprint_normal_dev(self, "DDR PHY registers @ %p\n", (void*)sc->sc_bhregs_ddrphy);
}
/* map SDRAM DFII */
if (sbus_bus_map(sc->sc_bustag,
@ -154,11 +161,42 @@ sbusfpga_sdram_attach(device_t parent, device_t self, void *aux)
aprint_error(": cannot map SDRAM DFII registers\n");
return;
} else {
aprint_normal_dev(self, ": SDRAM DFII registers @ %p\n", (void*)sc->sc_bhregs_sdram);
aprint_normal_dev(self, "SDRAM DFII registers @ %p\n", (void*)sc->sc_bhregs_sdram);
}
/* custom DMA */
if (sbus_bus_map(sc->sc_bustag,
sa->sa_reg[2].oa_space /* sa_slot */,
sa->sa_reg[2].oa_base /* sa_offset */,
sa->sa_reg[2].oa_size /* sa_size */,
BUS_SPACE_MAP_LINEAR,
&sc->sc_bhregs_exchange_with_mem) != 0) {
aprint_error(": cannot map DMA registers\n");
return;
} else {
aprint_normal_dev(self, "DMA registers @ %p\n", (void*)sc->sc_bhregs_exchange_with_mem);
}
if (sa->sa_nreg >= 4) {
/* if we map some of the memory itself */
/* normally disabled, it's a debug feature */
if (sbus_bus_map(sc->sc_bustag,
sa->sa_reg[3].oa_space /* sa_slot */,
sa->sa_reg[3].oa_base /* sa_offset */,
sa->sa_reg[3].oa_size /* sa_size */,
BUS_SPACE_MAP_LINEAR,
&sc->sc_bhregs_mmap) != 0) {
aprint_error(": cannot map MMAP\n");
return;
} else {
aprint_normal_dev(self, "MMAP @ %p\n", (void*)sc->sc_bhregs_mmap);
}
sc->sc_bufsiz_mmap = sa->sa_reg[3].oa_size;
} else {
sc->sc_bufsiz_mmap = 0;
}
sc->sc_bufsiz_ddrphy = sa->sa_reg[0].oa_size;
sc->sc_bufsiz_sdram = sa->sa_reg[1].oa_size;
sc->sc_bufsiz_exchange_with_mem = sa->sa_reg[2].oa_size;
node = sc->sc_node = sa->sa_node;
@ -183,14 +221,279 @@ sbusfpga_sdram_attach(device_t parent, device_t self, void *aux)
sc->sc_burst,
sbsc->sc_burst);
sdram_init(sc);
if (!sdram_init(sc)) {
aprint_error_dev(self, "couldn't initialize SDRAM\n");
return;
}
if (!dma_init(sc)) {
aprint_error_dev(self, "couldn't initialize DMA for SDRAM\n");
return;
}
if (!dma_memtest(sc)) {
aprint_error_dev(self, "DMA-MEMTEST failed for SDRAM\n");
return;
}
}
#define CONFIG_CSR_DATA_WIDTH 32
// define CSR_LEDS_BASE to avoid defining the CSRs
// define CSR_LEDS_BASE & others to avoid defining the CSRs of HW we don't handle
#define CSR_LEDS_BASE
#define CSR_SDBLOCK2MEM_BASE
#define CSR_SDCORE_BASE
#define CSR_SDIRQ_BASE
#define CSR_SDMEM2BLOCK_BASE
#define CSR_SDPHY_BASE
#include "dev/sbus/litex_csr.h"
#undef CSR_LEDS_BASE
#undef CSR_SDBLOCK2MEM_BASE
#undef CSR_SDCORE_BASE
#undef CSR_SDIRQ_BASE
#undef CSR_SDMEM2BLOCK_BASE
#undef CSR_SDPHY_BASE
int
dma_init(struct sbusfpga_sdram_softc *sc) {
sc->dma_blk_size = exchange_with_mem_blk_size_read(sc);
sc->dma_blk_base = exchange_with_mem_blk_base_read(sc);
aprint_normal_dev(sc->sc_dev, "DMA: HW -> block size is %d, base address is 0x%08x\n", sc->dma_blk_size, sc->dma_blk_base * sc->dma_blk_size);
/* Allocate a dmamap */
if (bus_dmamap_create(sc->sc_dmatag, SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ, 1, SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_dmamap) != 0) {
aprint_error_dev(sc->sc_dev, "DMA map create failed\n");
return 0;
} else {
aprint_normal_dev(sc->sc_dev, "dmamap: %lu %lu %d (%p)\n", sc->sc_dmamap->dm_maxsegsz, sc->sc_dmamap->dm_mapsize, sc->sc_dmamap->dm_nsegs, sc->sc_dmatag->_dmamap_load);
}
if (bus_dmamem_alloc(sc->sc_dmatag, SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ, 64, 64, &sc->sc_segs, 1, &sc->sc_rsegs, BUS_DMA_NOWAIT | BUS_DMA_STREAMING)) {
aprint_error_dev(sc->sc_dev, "cannot allocate DVMA memory");
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_dmamap);
return 0;
}
if (bus_dmamem_map(sc->sc_dmatag, &sc->sc_segs, 1, SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ, &sc->sc_dma_kva, BUS_DMA_NOWAIT)) {
aprint_error_dev(sc->sc_dev, "cannot allocate DVMA address");
bus_dmamem_free(sc->sc_dmatag, &sc->sc_segs, 1);
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_dmamap);
return 0;
}
if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, sc->sc_dma_kva, SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ, /* kernel space */ NULL,
BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_WRITE)) {
aprint_error_dev(sc->sc_dev, "cannot load dma map");
bus_dmamem_unmap(sc->sc_dmatag, &sc->sc_dma_kva, SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ);
bus_dmamem_free(sc->sc_dmatag, &sc->sc_segs, 1);
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_dmamap);
return 0;
}
aprint_normal_dev(sc->sc_dev, "DMA: SW -> kernal address is %p, dvma address is 0x%08llx\n", sc->sc_dma_kva, sc->sc_dmamap->dm_segs[0].ds_addr);
return 1;
}
static inline unsigned long
lfsr (unsigned long bits, unsigned long prev);
int
dma_memtest(struct sbusfpga_sdram_softc *sc) {
unsigned long *kva_ulong = (unsigned long*)sc->sc_dma_kva;
unsigned long val;
unsigned int blkn = 0; // 113;
unsigned int testdatasize = 4096;
unsigned int blkcnt ;
int count;
aprint_normal_dev(sc->sc_dev, "Initializing DMA buffer.\n");
val = 0xDEADBEEF;
for (int i = 0 ; i < testdatasize/sizeof(unsigned long) ; i++) {
val = lfsr(32, val);
kva_ulong[i] = val;
}
aprint_normal_dev(sc->sc_dev, "First value: 0x%08lx\n", kva_ulong[0]);
if (sc->sc_bufsiz_mmap > 0) {
int idx = blkn * sc->dma_blk_size / sizeof(unsigned long), x;
int bound = sc->sc_bufsiz_mmap / sizeof(unsigned long);
if (bound > idx) {
if ((bound - idx) > 10)
bound = idx + 10;
count = 0;
for (x = idx ; x < bound; x++) {
unsigned long data = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_mmap, x*sizeof(unsigned long));
aprint_normal_dev(sc->sc_dev, "Prior to write [mmap] at %d: 0x%08lx\n", x, data);
}
}
}
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, 4096, BUS_DMASYNC_PREREAD);
aprint_normal_dev(sc->sc_dev, "Starting DMA Write-to-Sdram.\n");
exchange_with_mem_blk_addr_write(sc, blkn + sc->dma_blk_base);
exchange_with_mem_dma_addr_write(sc, sc->sc_dmamap->dm_segs[0].ds_addr);
exchange_with_mem_blk_cnt_write(sc, 0x80000000 | (testdatasize / sc->dma_blk_size));
aprint_normal_dev(sc->sc_dev, "DMA Write-to-Sdram started, polling\n");
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, 4096, BUS_DMASYNC_POSTREAD);
delay(500);
count = 0;
while (((blkcnt = exchange_with_mem_blk_cnt_read(sc)) != 0) && (count < 10)) {
aprint_normal_dev(sc->sc_dev, "DMA Write-to-Sdram ongoing (%u, status 0x%08x, lastblk req 0x%08x, last phys addr written 0x%08x)\n",
blkcnt & 0x0000FFFF,
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_blk_read(sc),
exchange_with_mem_wr_tosdram_read(sc));
count ++;
delay(500);
}
if (blkcnt) {
aprint_error_dev(sc->sc_dev, "DMA Write-to-Sdram didn't finish ? (%u, status 0x%08x, 0x%08x, 0x%08x, lastblk req 0x%08x, last phys addr written 0x%08x)\n",
blkcnt & 0x0000FFFF,
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_dma_read(sc),
exchange_with_mem_blk_rem_read(sc),
exchange_with_mem_last_blk_read(sc),
exchange_with_mem_wr_tosdram_read(sc));
return 0;
} else {
aprint_normal_dev(sc->sc_dev, "DMA Write-to-Sdram done (status 0x%08x, 0x%08x, 0x%08x, 0x%08x, last phys addr written 0x%08x)\n",
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_blk_read(sc),
exchange_with_mem_last_dma_read(sc),
exchange_with_mem_blk_rem_read(sc),
exchange_with_mem_wr_tosdram_read(sc));
}
count = 0;
while ((((blkcnt = exchange_with_mem_dma_status_read(sc)) & 0x3) != 0) && (count < 10)) {
aprint_normal_dev(sc->sc_dev, "DMA Write-to-Sdram hasn't reached SDRAM yet (status 0x%08x)\n", blkcnt);
count ++;
delay(500);
}
if (blkcnt & 0x3) {
aprint_error_dev(sc->sc_dev, "DMA Write-to-Sdram can't reach SDRAM ? (%u, status 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", blkcnt & 0x0000FFFF,
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_blk_read(sc),
exchange_with_mem_last_dma_read(sc),
exchange_with_mem_blk_rem_read(sc));
return 0;
} else {
aprint_normal_dev(sc->sc_dev, "DMA Write-to-Sdram has reached SDRAM (status 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_blk_read(sc),
exchange_with_mem_last_dma_read(sc),
exchange_with_mem_blk_rem_read(sc));
}
if (sc->sc_bufsiz_mmap > 0) {
int idx = blkn * sc->dma_blk_size / sizeof(unsigned long), x;
int bound = sc->sc_bufsiz_mmap / sizeof(unsigned long);
if (bound > idx) {
count = 0;
val = 0xDEADBEEF;
if ((bound - idx) > (testdatasize / sizeof(unsigned long)))
bound = idx + (testdatasize / sizeof(unsigned long));
for (x = idx ; x < bound && count < 10; x++) {
unsigned long data = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_mmap, x*sizeof(unsigned long));
val = lfsr(32, val);
if (val != data) {
aprint_error_dev(sc->sc_dev, "Read-after-write [mmap] error at %d: 0x%08lx vs. 0x%08lx (0x%08lx)\n", x, data, val, val ^ data);
count ++;
}
}
}
}
for (int i = 0 ; i < testdatasize/sizeof(unsigned long) ; i++) {
kva_ulong[i] = 0x0c0ffee0;
}
aprint_normal_dev(sc->sc_dev, "First value: 0x%08lx\n", kva_ulong[0]);
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, 4096, BUS_DMASYNC_PREWRITE);
aprint_normal_dev(sc->sc_dev, "Starting DMA Read-from-Sdram.\n");
exchange_with_mem_blk_addr_write(sc, blkn + sc->dma_blk_base);
exchange_with_mem_dma_addr_write(sc, sc->sc_dmamap->dm_segs[0].ds_addr);
exchange_with_mem_blk_cnt_write(sc, 0x00000000 | (testdatasize / sc->dma_blk_size));
aprint_normal_dev(sc->sc_dev, "DMA Read-from-Sdram started, polling\n");
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, 4096, BUS_DMASYNC_POSTWRITE);
delay(500);
count = 0;
while (((blkcnt = exchange_with_mem_blk_cnt_read(sc)) != 0) && (count < 10)) {
aprint_normal_dev(sc->sc_dev, "DMA Read-from-Sdram ongoing (%u, status 0x%08x)\n", blkcnt & 0x0000FFFF, exchange_with_mem_dma_status_read(sc));
count ++;
delay(500);
}
if (blkcnt) {
aprint_error_dev(sc->sc_dev, "DMA Read-from-Sdram didn't finish ? (%u, status 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
blkcnt & 0x0000FFFF,
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_blk_read(sc),
exchange_with_mem_last_dma_read(sc),
exchange_with_mem_blk_rem_read(sc));
return 0;
} else {
aprint_normal_dev(sc->sc_dev, "DMA Read-from-Sdram done (status 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_blk_read(sc),
exchange_with_mem_last_dma_read(sc),
exchange_with_mem_blk_rem_read(sc));
}
count = 0;
while ((((blkcnt = exchange_with_mem_dma_status_read(sc)) & 0x3) != 0) && (count < 10)) {
aprint_normal_dev(sc->sc_dev, "DMA Read-from-Sdram hasn't reached memory yet (status 0x%08x)\n", blkcnt);
count ++;
delay(500);
}
aprint_normal_dev(sc->sc_dev, "First value: 0x%08lx\n", kva_ulong[0]);
if (blkcnt & 0x3) {
aprint_error_dev(sc->sc_dev, "DMA Read-from-Sdram can't reach memory ? (%u, status 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", blkcnt & 0x0000FFFF,
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_blk_read(sc),
exchange_with_mem_last_dma_read(sc),
exchange_with_mem_blk_rem_read(sc));
return 0;
} else {
aprint_normal_dev(sc->sc_dev, "DMA Read-from-Sdram has reached memory (status 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_blk_read(sc),
exchange_with_mem_last_dma_read(sc),
exchange_with_mem_blk_rem_read(sc));
}
count = 0;
val = 0xDEADBEEF;
for (int i = 0 ; i < testdatasize/sizeof(unsigned long) && count < 10; i++) {
val = lfsr(32, val);
if (kva_ulong[i] != val) {
aprint_error_dev(sc->sc_dev, "Read-after-write error at %d: 0x%08lx vs. 0x%08lx (0x%08lx)\n", i, kva_ulong[i], val, val ^ kva_ulong[i]);
count ++;
}
}
if (count)
return 0;
return 1;
}
/* auto-generated sdram_phy.h + sc */
#define DFII_CONTROL_SEL 0x01
@ -732,7 +1035,7 @@ sdram_software_control_on(struct sbusfpga_sdram_softc *sc)
previous = sdram_dfii_control_read(sc);
if (previous != (0x02 | 0x04 | 0x08)) {
sdram_dfii_control_write(sc, (0x02 | 0x04 | 0x08));
aprint_normal ("Switching SDRAM to software control.\n");
aprint_normal_dev(sc->sc_dev, "Switching SDRAM to software control.\n");
}
}
static void
@ -742,7 +1045,7 @@ sdram_software_control_off(struct sbusfpga_sdram_softc *sc)
previous = sdram_dfii_control_read(sc);
if (previous != (0x01)) {
sdram_dfii_control_write(sc, (0x01));
aprint_normal ("Switching SDRAM to hardware control.\n");
aprint_normal_dev(sc->sc_dev, "Switching SDRAM to hardware control.\n");
}
}
__attribute__((unused)) static void
@ -785,7 +1088,7 @@ popcount (unsigned int x)
static void
print_scan_errors (unsigned int errors)
{
aprint_normal ("%d", errors == 0);
aprint_normal("%d", errors == 0);
}
static unsigned int
sdram_write_read_check_test_pattern (struct sbusfpga_sdram_softc *sc, int module, unsigned int seed)
@ -837,7 +1140,7 @@ sdram_leveling_center_module (struct sbusfpga_sdram_softc *sc, int module, int s
int delay, delay_mid, delay_range;
int delay_min = -1, delay_max = -1;
if (show_long)
aprint_normal ("m%d: |", module);
aprint_normal_dev(sc->sc_dev, "m%d: |", module);
delay = 0;
rst_delay(sc, module);
while (1) {
@ -846,7 +1149,7 @@ sdram_leveling_center_module (struct sbusfpga_sdram_softc *sc, int module, int s
working = errors == 0;
show = show_long;
if (show)
print_scan_errors (errors);
print_scan_errors(errors);
if (working && delay_min < 0) {
delay_min = delay;
break;
@ -864,7 +1167,7 @@ sdram_leveling_center_module (struct sbusfpga_sdram_softc *sc, int module, int s
working = errors == 0;
show = show_long;
if (show)
print_scan_errors (errors);
print_scan_errors(errors);
if (!working && delay_max < 0) {
delay_max = delay;
}
@ -877,17 +1180,17 @@ sdram_leveling_center_module (struct sbusfpga_sdram_softc *sc, int module, int s
delay_max = delay;
}
if (show_long)
aprint_normal ("| ");
aprint_normal_dev(sc->sc_dev, "| ");
delay_mid = (delay_min + delay_max) / 2 % 32;
delay_range = (delay_max - delay_min) / 2;
if (show_short) {
if (delay_min < 0)
aprint_normal ("delays: -");
aprint_normal("delays: -");
else
aprint_normal ("delays: %02d+-%02d", delay_mid, delay_range);
aprint_normal("delays: %02d+-%02d", delay_mid, delay_range);
}
if (show_long)
aprint_normal ("\n");
aprint_normal("\n");
rst_delay(sc, module);
cdelay (100);
for (i = 0; i < delay_mid; i++) {
@ -934,7 +1237,7 @@ sdram_read_leveling_scan_module (struct sbusfpga_sdram_softc *sc, int module, in
unsigned int errors;
score = 0;
if (show)
aprint_normal (" m%d, b%02d: |", module, bitslip);
aprint_normal_dev(sc->sc_dev, " m%d, b%02d: |", module, bitslip);
sdram_read_leveling_rst_delay(sc, module);
for (i = 0; i < 32; i++) {
int working;
@ -944,12 +1247,12 @@ sdram_read_leveling_scan_module (struct sbusfpga_sdram_softc *sc, int module, in
working = errors == 0;
score += (working * max_errors * 32) + (max_errors - errors);
if (_show) {
print_scan_errors (errors);
print_scan_errors(errors);
}
sdram_read_leveling_inc_delay(sc, module);
}
if (show)
aprint_normal ("| ");
aprint_normal("| ");
return score;
}
static void
@ -969,7 +1272,7 @@ sdram_read_leveling(struct sbusfpga_sdram_softc *sc)
sdram_leveling_center_module(sc, module, 1, 0,
sdram_read_leveling_rst_delay,
sdram_read_leveling_inc_delay);
aprint_normal ("\n");
aprint_normal("\n");
if (score > best_score) {
best_bitslip = bitslip;
best_score = score;
@ -978,14 +1281,14 @@ sdram_read_leveling(struct sbusfpga_sdram_softc *sc)
break;
sdram_read_leveling_inc_bitslip(sc, module);
}
aprint_normal (" best: m%d, b%02d ", module, best_bitslip);
aprint_normal_dev(sc->sc_dev, " best: m%d, b%02d ", module, best_bitslip);
sdram_read_leveling_rst_bitslip(sc, module);
for (bitslip = 0; bitslip < best_bitslip; bitslip++)
sdram_read_leveling_inc_bitslip(sc, module);
sdram_leveling_center_module(sc, module, 1, 0,
sdram_read_leveling_rst_delay,
sdram_read_leveling_inc_delay);
aprint_normal ("\n");
aprint_normal("\n");
}
}
static void
@ -1026,9 +1329,9 @@ sdram_write_latency_calibration(struct sbusfpga_sdram_softc *sc)
else
bitslip = _sdram_write_leveling_bitslips[module];
if (bitslip == -1)
aprint_normal ("m%d:- ", module);
aprint_normal_dev(sc->sc_dev, "m%d:- ", module);
else
aprint_normal ("m%d:%d ", module, bitslip);
aprint_normal_dev(sc->sc_dev, "m%d:%d ", module, bitslip);
ddrphy_dly_sel_write(sc, 1 << module);
ddrphy_wdly_dq_bitslip_rst_write(sc, 1);
for (i = 0; i < bitslip; i++) {
@ -1036,7 +1339,7 @@ sdram_write_latency_calibration(struct sbusfpga_sdram_softc *sc)
}
ddrphy_dly_sel_write(sc, 0);
}
aprint_normal ("\n");
aprint_normal("\n");
}
static int
sdram_leveling(struct sbusfpga_sdram_softc *sc)
@ -1047,9 +1350,9 @@ sdram_leveling(struct sbusfpga_sdram_softc *sc)
sdram_read_leveling_rst_delay(sc, module);
sdram_read_leveling_rst_bitslip(sc, module);
}
aprint_normal ("Write latency calibration:\n");
aprint_normal_dev(sc->sc_dev, "Write latency calibration:\n");
sdram_write_latency_calibration(sc);
aprint_normal ("Read leveling:\n");
aprint_normal_dev(sc->sc_dev, "Read leveling:\n");
sdram_read_leveling(sc);
sdram_software_control_off(sc);
return 1;
@ -1059,7 +1362,7 @@ sdram_init(struct sbusfpga_sdram_softc *sc)
{
ddrphy_rdphase_write(sc, 2);
ddrphy_wrphase_write(sc, 3);
aprint_normal ("Initializing SDRAM @0x%08lx...\n", 0x80000000L);
aprint_normal_dev(sc->sc_dev, "Initializing SDRAM @0x%08lx...\n", 0x80000000L);
sdram_software_control_on(sc);
ddrphy_rst_write(sc, 1);
cdelay (1000);

View File

@ -37,8 +37,23 @@ struct sbusfpga_sdram_softc {
bus_space_tag_t sc_bustag; /* bus tag */
bus_space_handle_t sc_bhregs_ddrphy; /* bus handle */
bus_space_handle_t sc_bhregs_sdram; /* bus handle */
bus_space_handle_t sc_bhregs_exchange_with_mem; /* bus handle */
bus_space_handle_t sc_bhregs_mmap; /* bus handle */
int sc_bufsiz_ddrphy; /* Size of buffer */
int sc_bufsiz_sdram; /* Size of buffer */
int sc_bufsiz_exchange_with_mem; /* bus handle */
int sc_bufsiz_mmap; /* bus handle */
/* specific of the DMA engine */
u_int dma_blk_size;
u_int dma_blk_base;
/* DMA kernel structures */
bus_dma_tag_t sc_dmatag;
bus_dmamap_t sc_dmamap;
bus_dma_segment_t sc_segs;
int sc_rsegs;
void * sc_dma_kva;
};
#define SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ (4*1024)
#endif /* _SBUSFPGA_SDRAM_H_ */

View File

@ -0,0 +1,465 @@
//--------------------------------------------------------------------------------
// Auto-generated by Migen (3ffd64c) & LiteX (8a644c90) on 2021-07-17 11:01:08
//--------------------------------------------------------------------------------
#ifndef __GENERATED_CSR_H
#define __GENERATED_CSR_H
#ifndef CSR_BASE
#define CSR_BASE 0x40000L
#endif
/* leds */
#ifndef CSR_LEDS_BASE
#define CSR_LEDS_BASE (CSR_BASE + 0x0L)
#define CSR_LEDS_OUT_ADDR (CSR_LEDS_BASE + 0x0L)
#define CSR_LEDS_OUT_SIZE 1
static inline uint32_t leds_out_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_leds, 0x0L);
}
static inline void leds_out_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_leds, 0x0L, v);
}
#endif // CSR_LEDS_BASE
/* ddrphy */
#ifndef CSR_DDRPHY_BASE
#define CSR_DDRPHY_BASE (CSR_BASE + 0x1000L)
#define CSR_DDRPHY_RST_ADDR (CSR_DDRPHY_BASE + 0x0L)
#define CSR_DDRPHY_RST_SIZE 1
static inline uint32_t ddrphy_rst_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x0L);
}
static inline void ddrphy_rst_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x0L, v);
}
#define CSR_DDRPHY_HALF_SYS8X_TAPS_ADDR (CSR_DDRPHY_BASE + 0x4L)
#define CSR_DDRPHY_HALF_SYS8X_TAPS_SIZE 1
static inline uint32_t ddrphy_half_sys8x_taps_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x4L);
}
static inline void ddrphy_half_sys8x_taps_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x4L, v);
}
#define CSR_DDRPHY_WLEVEL_EN_ADDR (CSR_DDRPHY_BASE + 0x8L)
#define CSR_DDRPHY_WLEVEL_EN_SIZE 1
static inline uint32_t ddrphy_wlevel_en_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x8L);
}
static inline void ddrphy_wlevel_en_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x8L, v);
}
#define CSR_DDRPHY_WLEVEL_STROBE_ADDR (CSR_DDRPHY_BASE + 0xcL)
#define CSR_DDRPHY_WLEVEL_STROBE_SIZE 1
static inline uint32_t ddrphy_wlevel_strobe_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0xcL);
}
static inline void ddrphy_wlevel_strobe_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0xcL, v);
}
#define CSR_DDRPHY_DLY_SEL_ADDR (CSR_DDRPHY_BASE + 0x10L)
#define CSR_DDRPHY_DLY_SEL_SIZE 1
static inline uint32_t ddrphy_dly_sel_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x10L);
}
static inline void ddrphy_dly_sel_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x10L, v);
}
#define CSR_DDRPHY_RDLY_DQ_RST_ADDR (CSR_DDRPHY_BASE + 0x14L)
#define CSR_DDRPHY_RDLY_DQ_RST_SIZE 1
static inline uint32_t ddrphy_rdly_dq_rst_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x14L);
}
static inline void ddrphy_rdly_dq_rst_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x14L, v);
}
#define CSR_DDRPHY_RDLY_DQ_INC_ADDR (CSR_DDRPHY_BASE + 0x18L)
#define CSR_DDRPHY_RDLY_DQ_INC_SIZE 1
static inline uint32_t ddrphy_rdly_dq_inc_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x18L);
}
static inline void ddrphy_rdly_dq_inc_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x18L, v);
}
#define CSR_DDRPHY_RDLY_DQ_BITSLIP_RST_ADDR (CSR_DDRPHY_BASE + 0x1cL)
#define CSR_DDRPHY_RDLY_DQ_BITSLIP_RST_SIZE 1
static inline uint32_t ddrphy_rdly_dq_bitslip_rst_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x1cL);
}
static inline void ddrphy_rdly_dq_bitslip_rst_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x1cL, v);
}
#define CSR_DDRPHY_RDLY_DQ_BITSLIP_ADDR (CSR_DDRPHY_BASE + 0x20L)
#define CSR_DDRPHY_RDLY_DQ_BITSLIP_SIZE 1
static inline uint32_t ddrphy_rdly_dq_bitslip_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x20L);
}
static inline void ddrphy_rdly_dq_bitslip_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x20L, v);
}
#define CSR_DDRPHY_WDLY_DQ_BITSLIP_RST_ADDR (CSR_DDRPHY_BASE + 0x24L)
#define CSR_DDRPHY_WDLY_DQ_BITSLIP_RST_SIZE 1
static inline uint32_t ddrphy_wdly_dq_bitslip_rst_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x24L);
}
static inline void ddrphy_wdly_dq_bitslip_rst_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x24L, v);
}
#define CSR_DDRPHY_WDLY_DQ_BITSLIP_ADDR (CSR_DDRPHY_BASE + 0x28L)
#define CSR_DDRPHY_WDLY_DQ_BITSLIP_SIZE 1
static inline uint32_t ddrphy_wdly_dq_bitslip_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x28L);
}
static inline void ddrphy_wdly_dq_bitslip_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x28L, v);
}
#define CSR_DDRPHY_RDPHASE_ADDR (CSR_DDRPHY_BASE + 0x2cL)
#define CSR_DDRPHY_RDPHASE_SIZE 1
static inline uint32_t ddrphy_rdphase_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x2cL);
}
static inline void ddrphy_rdphase_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x2cL, v);
}
#define CSR_DDRPHY_WRPHASE_ADDR (CSR_DDRPHY_BASE + 0x30L)
#define CSR_DDRPHY_WRPHASE_SIZE 1
static inline uint32_t ddrphy_wrphase_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x30L);
}
static inline void ddrphy_wrphase_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_ddrphy, 0x30L, v);
}
#endif // CSR_DDRPHY_BASE
/* exchange_with_mem */
#ifndef CSR_EXCHANGE_WITH_MEM_BASE
#define CSR_EXCHANGE_WITH_MEM_BASE (CSR_BASE + 0x2000L)
#define CSR_EXCHANGE_WITH_MEM_BLK_SIZE_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x0L)
#define CSR_EXCHANGE_WITH_MEM_BLK_SIZE_SIZE 1
static inline uint32_t exchange_with_mem_blk_size_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x0L);
}
#define CSR_EXCHANGE_WITH_MEM_BLK_BASE_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x4L)
#define CSR_EXCHANGE_WITH_MEM_BLK_BASE_SIZE 1
static inline uint32_t exchange_with_mem_blk_base_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x4L);
}
#define CSR_EXCHANGE_WITH_MEM_BLK_ADDR_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x8L)
#define CSR_EXCHANGE_WITH_MEM_BLK_ADDR_SIZE 1
static inline uint32_t exchange_with_mem_blk_addr_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x8L);
}
static inline void exchange_with_mem_blk_addr_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x8L, v);
}
#define CSR_EXCHANGE_WITH_MEM_DMA_ADDR_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0xcL)
#define CSR_EXCHANGE_WITH_MEM_DMA_ADDR_SIZE 1
static inline uint32_t exchange_with_mem_dma_addr_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0xcL);
}
static inline void exchange_with_mem_dma_addr_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0xcL, v);
}
#define CSR_EXCHANGE_WITH_MEM_BLK_CNT_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x10L)
#define CSR_EXCHANGE_WITH_MEM_BLK_CNT_SIZE 1
static inline uint32_t exchange_with_mem_blk_cnt_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x10L);
}
static inline void exchange_with_mem_blk_cnt_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x10L, v);
}
#define CSR_EXCHANGE_WITH_MEM_LAST_BLK_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x14L)
#define CSR_EXCHANGE_WITH_MEM_LAST_BLK_SIZE 1
static inline uint32_t exchange_with_mem_last_blk_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x14L);
}
#define CSR_EXCHANGE_WITH_MEM_LAST_DMA_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x18L)
#define CSR_EXCHANGE_WITH_MEM_LAST_DMA_SIZE 1
static inline uint32_t exchange_with_mem_last_dma_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x18L);
}
#define CSR_EXCHANGE_WITH_MEM_BLK_REM_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x1cL)
#define CSR_EXCHANGE_WITH_MEM_BLK_REM_SIZE 1
static inline uint32_t exchange_with_mem_blk_rem_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x1cL);
}
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x20L)
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_SIZE 1
static inline uint32_t exchange_with_mem_dma_status_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x20L);
}
#define CSR_EXCHANGE_WITH_MEM_WR_TOSDRAM_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x24L)
#define CSR_EXCHANGE_WITH_MEM_WR_TOSDRAM_SIZE 1
static inline uint32_t exchange_with_mem_wr_tosdram_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x24L);
}
#endif // CSR_EXCHANGE_WITH_MEM_BASE
/* sdram */
#ifndef CSR_SDRAM_BASE
#define CSR_SDRAM_BASE (CSR_BASE + 0x3000L)
#define CSR_SDRAM_DFII_CONTROL_ADDR (CSR_SDRAM_BASE + 0x0L)
#define CSR_SDRAM_DFII_CONTROL_SIZE 1
static inline uint32_t sdram_dfii_control_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x0L);
}
static inline void sdram_dfii_control_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x0L, v);
}
#define CSR_SDRAM_DFII_CONTROL_SEL_OFFSET 0
#define CSR_SDRAM_DFII_CONTROL_SEL_SIZE 1
static inline uint32_t sdram_dfii_control_sel_extract(struct sbusfpga_sdram_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t sdram_dfii_control_sel_read(struct sbusfpga_sdram_softc *sc) {
uint32_t word = sdram_dfii_control_read(sc);
return sdram_dfii_control_sel_extract(sc, word);
}
static inline uint32_t sdram_dfii_control_sel_replace(struct sbusfpga_sdram_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void sdram_dfii_control_sel_write(struct sbusfpga_sdram_softc *sc, uint32_t plain_value) {
uint32_t oldword = sdram_dfii_control_read(sc);
uint32_t newword = sdram_dfii_control_sel_replace(sc, oldword, plain_value);
sdram_dfii_control_write(sc, newword);
}
#define CSR_SDRAM_DFII_CONTROL_CKE_OFFSET 1
#define CSR_SDRAM_DFII_CONTROL_CKE_SIZE 1
static inline uint32_t sdram_dfii_control_cke_extract(struct sbusfpga_sdram_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t sdram_dfii_control_cke_read(struct sbusfpga_sdram_softc *sc) {
uint32_t word = sdram_dfii_control_read(sc);
return sdram_dfii_control_cke_extract(sc, word);
}
static inline uint32_t sdram_dfii_control_cke_replace(struct sbusfpga_sdram_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 1))) | (mask & plain_value)<< 1 ;
}
static inline void sdram_dfii_control_cke_write(struct sbusfpga_sdram_softc *sc, uint32_t plain_value) {
uint32_t oldword = sdram_dfii_control_read(sc);
uint32_t newword = sdram_dfii_control_cke_replace(sc, oldword, plain_value);
sdram_dfii_control_write(sc, newword);
}
#define CSR_SDRAM_DFII_CONTROL_ODT_OFFSET 2
#define CSR_SDRAM_DFII_CONTROL_ODT_SIZE 1
static inline uint32_t sdram_dfii_control_odt_extract(struct sbusfpga_sdram_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 2) & mask );
}
static inline uint32_t sdram_dfii_control_odt_read(struct sbusfpga_sdram_softc *sc) {
uint32_t word = sdram_dfii_control_read(sc);
return sdram_dfii_control_odt_extract(sc, word);
}
static inline uint32_t sdram_dfii_control_odt_replace(struct sbusfpga_sdram_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 2))) | (mask & plain_value)<< 2 ;
}
static inline void sdram_dfii_control_odt_write(struct sbusfpga_sdram_softc *sc, uint32_t plain_value) {
uint32_t oldword = sdram_dfii_control_read(sc);
uint32_t newword = sdram_dfii_control_odt_replace(sc, oldword, plain_value);
sdram_dfii_control_write(sc, newword);
}
#define CSR_SDRAM_DFII_CONTROL_RESET_N_OFFSET 3
#define CSR_SDRAM_DFII_CONTROL_RESET_N_SIZE 1
static inline uint32_t sdram_dfii_control_reset_n_extract(struct sbusfpga_sdram_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 3) & mask );
}
static inline uint32_t sdram_dfii_control_reset_n_read(struct sbusfpga_sdram_softc *sc) {
uint32_t word = sdram_dfii_control_read(sc);
return sdram_dfii_control_reset_n_extract(sc, word);
}
static inline uint32_t sdram_dfii_control_reset_n_replace(struct sbusfpga_sdram_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 3))) | (mask & plain_value)<< 3 ;
}
static inline void sdram_dfii_control_reset_n_write(struct sbusfpga_sdram_softc *sc, uint32_t plain_value) {
uint32_t oldword = sdram_dfii_control_read(sc);
uint32_t newword = sdram_dfii_control_reset_n_replace(sc, oldword, plain_value);
sdram_dfii_control_write(sc, newword);
}
#define CSR_SDRAM_DFII_PI0_COMMAND_ADDR (CSR_SDRAM_BASE + 0x4L)
#define CSR_SDRAM_DFII_PI0_COMMAND_SIZE 1
static inline uint32_t sdram_dfii_pi0_command_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x4L);
}
static inline void sdram_dfii_pi0_command_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x4L, v);
}
#define CSR_SDRAM_DFII_PI0_COMMAND_ISSUE_ADDR (CSR_SDRAM_BASE + 0x8L)
#define CSR_SDRAM_DFII_PI0_COMMAND_ISSUE_SIZE 1
static inline uint32_t sdram_dfii_pi0_command_issue_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x8L);
}
static inline void sdram_dfii_pi0_command_issue_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x8L, v);
}
#define CSR_SDRAM_DFII_PI0_ADDRESS_ADDR (CSR_SDRAM_BASE + 0xcL)
#define CSR_SDRAM_DFII_PI0_ADDRESS_SIZE 1
static inline uint32_t sdram_dfii_pi0_address_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0xcL);
}
static inline void sdram_dfii_pi0_address_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0xcL, v);
}
#define CSR_SDRAM_DFII_PI0_BADDRESS_ADDR (CSR_SDRAM_BASE + 0x10L)
#define CSR_SDRAM_DFII_PI0_BADDRESS_SIZE 1
static inline uint32_t sdram_dfii_pi0_baddress_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x10L);
}
static inline void sdram_dfii_pi0_baddress_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x10L, v);
}
#define CSR_SDRAM_DFII_PI0_WRDATA_ADDR (CSR_SDRAM_BASE + 0x14L)
#define CSR_SDRAM_DFII_PI0_WRDATA_SIZE 1
static inline uint32_t sdram_dfii_pi0_wrdata_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x14L);
}
static inline void sdram_dfii_pi0_wrdata_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x14L, v);
}
#define CSR_SDRAM_DFII_PI0_RDDATA_ADDR (CSR_SDRAM_BASE + 0x18L)
#define CSR_SDRAM_DFII_PI0_RDDATA_SIZE 1
static inline uint32_t sdram_dfii_pi0_rddata_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x18L);
}
#define CSR_SDRAM_DFII_PI1_COMMAND_ADDR (CSR_SDRAM_BASE + 0x1cL)
#define CSR_SDRAM_DFII_PI1_COMMAND_SIZE 1
static inline uint32_t sdram_dfii_pi1_command_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x1cL);
}
static inline void sdram_dfii_pi1_command_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x1cL, v);
}
#define CSR_SDRAM_DFII_PI1_COMMAND_ISSUE_ADDR (CSR_SDRAM_BASE + 0x20L)
#define CSR_SDRAM_DFII_PI1_COMMAND_ISSUE_SIZE 1
static inline uint32_t sdram_dfii_pi1_command_issue_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x20L);
}
static inline void sdram_dfii_pi1_command_issue_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x20L, v);
}
#define CSR_SDRAM_DFII_PI1_ADDRESS_ADDR (CSR_SDRAM_BASE + 0x24L)
#define CSR_SDRAM_DFII_PI1_ADDRESS_SIZE 1
static inline uint32_t sdram_dfii_pi1_address_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x24L);
}
static inline void sdram_dfii_pi1_address_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x24L, v);
}
#define CSR_SDRAM_DFII_PI1_BADDRESS_ADDR (CSR_SDRAM_BASE + 0x28L)
#define CSR_SDRAM_DFII_PI1_BADDRESS_SIZE 1
static inline uint32_t sdram_dfii_pi1_baddress_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x28L);
}
static inline void sdram_dfii_pi1_baddress_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x28L, v);
}
#define CSR_SDRAM_DFII_PI1_WRDATA_ADDR (CSR_SDRAM_BASE + 0x2cL)
#define CSR_SDRAM_DFII_PI1_WRDATA_SIZE 1
static inline uint32_t sdram_dfii_pi1_wrdata_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x2cL);
}
static inline void sdram_dfii_pi1_wrdata_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x2cL, v);
}
#define CSR_SDRAM_DFII_PI1_RDDATA_ADDR (CSR_SDRAM_BASE + 0x30L)
#define CSR_SDRAM_DFII_PI1_RDDATA_SIZE 1
static inline uint32_t sdram_dfii_pi1_rddata_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x30L);
}
#define CSR_SDRAM_DFII_PI2_COMMAND_ADDR (CSR_SDRAM_BASE + 0x34L)
#define CSR_SDRAM_DFII_PI2_COMMAND_SIZE 1
static inline uint32_t sdram_dfii_pi2_command_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x34L);
}
static inline void sdram_dfii_pi2_command_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x34L, v);
}
#define CSR_SDRAM_DFII_PI2_COMMAND_ISSUE_ADDR (CSR_SDRAM_BASE + 0x38L)
#define CSR_SDRAM_DFII_PI2_COMMAND_ISSUE_SIZE 1
static inline uint32_t sdram_dfii_pi2_command_issue_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x38L);
}
static inline void sdram_dfii_pi2_command_issue_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x38L, v);
}
#define CSR_SDRAM_DFII_PI2_ADDRESS_ADDR (CSR_SDRAM_BASE + 0x3cL)
#define CSR_SDRAM_DFII_PI2_ADDRESS_SIZE 1
static inline uint32_t sdram_dfii_pi2_address_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x3cL);
}
static inline void sdram_dfii_pi2_address_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x3cL, v);
}
#define CSR_SDRAM_DFII_PI2_BADDRESS_ADDR (CSR_SDRAM_BASE + 0x40L)
#define CSR_SDRAM_DFII_PI2_BADDRESS_SIZE 1
static inline uint32_t sdram_dfii_pi2_baddress_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x40L);
}
static inline void sdram_dfii_pi2_baddress_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x40L, v);
}
#define CSR_SDRAM_DFII_PI2_WRDATA_ADDR (CSR_SDRAM_BASE + 0x44L)
#define CSR_SDRAM_DFII_PI2_WRDATA_SIZE 1
static inline uint32_t sdram_dfii_pi2_wrdata_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x44L);
}
static inline void sdram_dfii_pi2_wrdata_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x44L, v);
}
#define CSR_SDRAM_DFII_PI2_RDDATA_ADDR (CSR_SDRAM_BASE + 0x48L)
#define CSR_SDRAM_DFII_PI2_RDDATA_SIZE 1
static inline uint32_t sdram_dfii_pi2_rddata_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x48L);
}
#define CSR_SDRAM_DFII_PI3_COMMAND_ADDR (CSR_SDRAM_BASE + 0x4cL)
#define CSR_SDRAM_DFII_PI3_COMMAND_SIZE 1
static inline uint32_t sdram_dfii_pi3_command_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x4cL);
}
static inline void sdram_dfii_pi3_command_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x4cL, v);
}
#define CSR_SDRAM_DFII_PI3_COMMAND_ISSUE_ADDR (CSR_SDRAM_BASE + 0x50L)
#define CSR_SDRAM_DFII_PI3_COMMAND_ISSUE_SIZE 1
static inline uint32_t sdram_dfii_pi3_command_issue_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x50L);
}
static inline void sdram_dfii_pi3_command_issue_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x50L, v);
}
#define CSR_SDRAM_DFII_PI3_ADDRESS_ADDR (CSR_SDRAM_BASE + 0x54L)
#define CSR_SDRAM_DFII_PI3_ADDRESS_SIZE 1
static inline uint32_t sdram_dfii_pi3_address_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x54L);
}
static inline void sdram_dfii_pi3_address_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x54L, v);
}
#define CSR_SDRAM_DFII_PI3_BADDRESS_ADDR (CSR_SDRAM_BASE + 0x58L)
#define CSR_SDRAM_DFII_PI3_BADDRESS_SIZE 1
static inline uint32_t sdram_dfii_pi3_baddress_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x58L);
}
static inline void sdram_dfii_pi3_baddress_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x58L, v);
}
#define CSR_SDRAM_DFII_PI3_WRDATA_ADDR (CSR_SDRAM_BASE + 0x5cL)
#define CSR_SDRAM_DFII_PI3_WRDATA_SIZE 1
static inline uint32_t sdram_dfii_pi3_wrdata_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x5cL);
}
static inline void sdram_dfii_pi3_wrdata_write(struct sbusfpga_sdram_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x5cL, v);
}
#define CSR_SDRAM_DFII_PI3_RDDATA_ADDR (CSR_SDRAM_BASE + 0x60L)
#define CSR_SDRAM_DFII_PI3_RDDATA_SIZE 1
static inline uint32_t sdram_dfii_pi3_rddata_read(struct sbusfpga_sdram_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_sdram, 0x60L);
}
#endif // CSR_SDRAM_BASE
#endif

View File

@ -1,12 +1,8 @@
\ auto-generated base regions for CSRs in the PROM
h# 40000 constant sbusfpga_csraddr_leds
h# 41000 constant sbusfpga_csraddr_ddrphy
h# 42000 constant sbusfpga_csraddr_sdblock2mem
h# 43000 constant sbusfpga_csraddr_sdcore
h# 44000 constant sbusfpga_csraddr_sdirq
h# 45000 constant sbusfpga_csraddr_sdmem2block
h# 46000 constant sbusfpga_csraddr_sdphy
h# 47000 constant sbusfpga_csraddr_sdram
h# 42000 constant sbusfpga_csraddr_exchange_with_mem
h# 43000 constant sbusfpga_csraddr_sdram
h# 80000 constant sbusfpga_regionaddr_usb_host_ctrl
h# 0 constant sbusfpga_regionaddr_prom
h# fc000000 constant sbusfpga_regionaddr_usb_fake_dma

View File

@ -43,6 +43,7 @@ new-device
\ Absolute minimal stuff; name & registers def.
" generic-ohci" device-name
\ USB registers are in the device space, not the CSR space
my-address sbusfpga_regionaddr_usb_host_ctrl + my-space h# 1000 reg
\ we don't support ET or anything non-32bits
h# 7c xdrint " slave-burst-sizes" attribute
@ -89,11 +90,15 @@ new-device
\ Absolute minimal stuff; name & registers def.
" RDOL,sdram" device-name
\ two pages of registers:
\ three pages of registers:
my-address sbusfpga_csraddr_ddrphy + my-space xdrphys \ Offset#1
h# 1000 xdrint xdr+ \ Merge size#1
my-address sbusfpga_csraddr_sdram + my-space xdrphys xdr+ \ Merge offset#2
h# 1000 xdrint xdr+ \ Merge size#2
my-address sbusfpga_csraddr_exchange_with_mem + my-space xdrphys xdr+ \ Merge offset#3
h# 1000 xdrint xdr+ \ Merge size#3
\ my-address sbusfpga_regionaddr_main_ram + my-space xdrphys xdr+ \ Merge offset#4
\ h# 10000 xdrint xdr+ \ Merge size#4
" reg" attribute
\ we don't support ET or anything non-32bits
@ -102,7 +107,8 @@ h# 7c xdrint " burst-sizes" attribute
headers
-1 instance value mregs-ddrphy-virt
-1 instance value mregs-sdramdfii-virt
-1 instance value mregs-sdram-virt
-1 instance value mregs-exchange_with_mem-virt
my-address constant my-sbus-address
my-space constant my-sbus-space
: map-in ( adr space size -- virt ) " map-in" $call-parent ;
@ -110,11 +116,13 @@ my-space constant my-sbus-space
: map-in-mregs ( -- )
my-sbus-address sbusfpga_csraddr_ddrphy + my-sbus-space h# 1000 map-in is mregs-ddrphy-virt
my-sbus-address sbusfpga_csraddr_sdram + my-sbus-space h# 1000 map-in is mregs-sdramdfii-virt
my-sbus-address sbusfpga_csraddr_sdram + my-sbus-space h# 1000 map-in is mregs-sdram-virt
my-sbus-address sbusfpga_csraddr_exchange_with_mem + my-sbus-space h# 1000 map-in is mregs-exchange_with_mem-virt
;
: map-out-mregs ( -- )
mregs-ddrphy-virt h# 1000 map-out
mregs-sdramdfii-virt h# 1000 map-out
mregs-sdram-virt h# 1000 map-out
mregs-exchange_with_mem-virt h# 1000 map-out
;
\ fload sdram_init.fth

View File

@ -29,6 +29,7 @@ ROM_ADDR_PFX = Signal(12, reset = 0)
WISHBONE_CSR_ADDR_PFX = Signal(12, reset = 4)
USBOHCI_ADDR_PFX = Signal(12, reset = 8)
SRAM_ADDR_PFX = Signal(12, reset = 9)
SDRAM_ADDR_PFX = Signal(12, reset = 2048)
wishbone_default_timeout = 120 ## must be > sbus_default_timeout
sbus_default_timeout = 100 ## must be below 127 as we can wait twice on it inside the 255 cycles
@ -171,12 +172,23 @@ LED_M_READ = 0x20
LED_M_CACHE = 0x40
class SBusFPGABus(Module):
def __init__(self, platform, hold_reset, wishbone_slave, wishbone_master):
def __init__(self, platform, hold_reset, wishbone_slave, wishbone_master, tosbus_fifo, fromsbus_fifo, fromsbus_req_fifo, burst_size = 8):
self.platform = platform
self.hold_reset = hold_reset
self.wishbone_slave = wishbone_slave
self.wishbone_master = wishbone_master
self.tosbus_fifo = tosbus_fifo
self.fromsbus_fifo = fromsbus_fifo
self.fromsbus_req_fifo = fromsbus_req_fifo
data_width = burst_size * 4
data_width_bits = burst_size * 32
blk_addr_width = 32 - log2_int(data_width) # 27 for burst_size == 8
fifo_blk_addr = Signal(blk_addr_width)
fifo_buffer = Signal(data_width_bits)
pad_SBUS_DATA_OE_LED = platform.request("SBUS_DATA_OE_LED")
SBUS_DATA_OE_LED_o = Signal()
@ -266,6 +278,8 @@ class SBusFPGABus(Module):
data_read_enable = Signal() # start enqueuing req. to read from WB
master_data = Signal(32) # could be merged with p_data
master_data_src_tosbus_fifo = Signal()
master_data_src_fromsbus_fifo = Signal()
master_addr = Signal(30) # could be meged with data_read_addr
master_size = Signal(4)
master_idx = Signal(2)
@ -278,7 +292,7 @@ class SBusFPGABus(Module):
wishbone_slave_timeout = Signal(6)
sbus_slave_timeout = Signal(6)
sbus_master_throttle = Signal(4)
sbus_master_throttle = Signal(2)
#self.submodules.led_display = LedDisplay(platform.request_all("user_led"))
@ -340,6 +354,9 @@ class SBusFPGABus(Module):
self.submodules.slave_fsm = slave_fsm = FSM(reset_state="Reset")
self.sync += platform.request("user_led", 5).eq(~slave_fsm.ongoing("Idle"))
self.sync += platform.request("user_led", 6).eq(master_data_src_tosbus_fifo)
self.sync += platform.request("user_led", 7).eq(master_data_src_fromsbus_fifo)
slave_fsm.act("Reset",
#NextValue(self.led_display.value, 0x0000000000),
@ -387,7 +404,8 @@ class SBusFPGABus(Module):
).Elif(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ROM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == WISHBONE_CSR_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == USBOHCI_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
NextValue(SBUS_3V3_ACKs_o, ACK_IDLE), # need to wait for data, don't ACK yet
NextValue(SBUS_3V3_ERRs_o, 1),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
@ -419,7 +437,8 @@ class SBusFPGABus(Module):
NextValue(sbus_oe_master_in, 1),
NextValue(sbus_last_pa, SBUS_3V3_PA_i),
If(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ROM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)|
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
NextValue(SBUS_3V3_ACKs_o, ACK_IDLE), # need to wait for data, don't ACK yet
NextValue(SBUS_3V3_ERRs_o, 1),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
@ -456,7 +475,8 @@ class SBusFPGABus(Module):
#NextValue(led0123, led0123 | LED_PARITY),
NextState("Slave_Error")
).Elif(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ROM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)|
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
NextValue(SBUS_3V3_ACKs_o, ACK_IDLE), # need to wait for data, don't ACK yet
NextValue(SBUS_3V3_ERRs_o, 1),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
@ -502,7 +522,8 @@ class SBusFPGABus(Module):
NextState("Slave_Error")
).Elif(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == WISHBONE_CSR_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == USBOHCI_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
If(~self.wishbone_master.cyc,
NextValue(SBUS_3V3_ACKs_o, ACK_WORD),
@ -528,7 +549,8 @@ class SBusFPGABus(Module):
(SBUS_3V3_PPRD_i == 0)),
NextValue(sbus_oe_master_in, 1),
NextValue(sbus_last_pa, SBUS_3V3_PA_i),
If((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX),
If(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
If(~self.wishbone_master.cyc,
NextValue(SBUS_3V3_ACKs_o, ACK_BYTE),
@ -559,7 +581,8 @@ class SBusFPGABus(Module):
NextValue(SBUS_3V3_ERRs_o, 1),
#NextValue(led0123, led0123 | LED_PARITY),
NextState("Slave_Error")
).Elif((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX),
).Elif(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
If(~self.wishbone_master.cyc,
NextValue(SBUS_3V3_ACKs_o, ACK_HWORD),
@ -689,6 +712,70 @@ class SBusFPGABus(Module):
#NextValue(self.led_display.value, 0x0000000000 | Cat(Signal(8, reset = 0x00), self.wishbone_slave.adr)),
#NextValue(self.led_display.value, Cat(Signal(8, reset = LED_M_READ), Signal(2, reset = 0), self.master_read_buffer_addr)),
NextState("Master_Translation")
).Elif(SBUS_3V3_BGs_i &
self.tosbus_fifo.readable &
(sbus_master_throttle == 0),
NextValue(SBUS_3V3_BRs_o, 0)
).Elif(~SBUS_3V3_BGs_i &
self.tosbus_fifo.readable,
NextValue(sbus_wishbone_le, 0), # checkme
NextValue(SBUS_3V3_BRs_o, 1), # relinquish the request
NextValue(sbus_oe_data, 1), ## output data (at least for @ during translation)
NextValue(sbus_oe_slave_in, 1), ## PPRD, SIZ becomes output
NextValue(sbus_oe_master_in, 0), ## ERRs, ACKs are input
NextValue(burst_counter, 0),
NextValue(burst_limit_m1, burst_size - 1),
NextValue(SBUS_3V3_D_o, self.tosbus_fifo.dout[0:32]),
NextValue(master_addr, self.tosbus_fifo.dout[2:32]),
NextValue(master_data, self.tosbus_fifo.dout[32:64]),
NextValue(fifo_buffer, self.tosbus_fifo.dout[32:]),
NextValue(master_data_src_tosbus_fifo, 1),
self.tosbus_fifo.re.eq(1),
Case(burst_size, {
2 : [NextValue(SBUS_3V3_SIZ_o, SIZ_BURST2),
NextValue(master_size, SIZ_BURST2)],
4 : [NextValue(SBUS_3V3_SIZ_o, SIZ_BURST4),
NextValue(master_size, SIZ_BURST4)],
8 : [NextValue(SBUS_3V3_SIZ_o, SIZ_BURST8),
NextValue(master_size, SIZ_BURST8)],
16 : [NextValue(SBUS_3V3_SIZ_o, SIZ_BURST16),
NextValue(master_size, SIZ_BURST16)],
}),
NextValue(SBUS_3V3_PPRD_o, 0),
NextValue(master_we, 1),
NextState("Master_Translation")
).Elif(SBUS_3V3_BGs_i &
self.fromsbus_req_fifo.readable &
self.fromsbus_fifo.writable &
(sbus_master_throttle == 0),
NextValue(SBUS_3V3_BRs_o, 0)
).Elif(~SBUS_3V3_BGs_i &
self.fromsbus_req_fifo.readable &
self.fromsbus_fifo.writable,
NextValue(sbus_wishbone_le, 0), # checkme
NextValue(SBUS_3V3_BRs_o, 1), # relinquish the request
NextValue(sbus_oe_data, 1), ## output data (at least for @ during translation)
NextValue(sbus_oe_slave_in, 1), ## PPRD, SIZ becomes output
NextValue(sbus_oe_master_in, 0), ## ERRs, ACKs are input
NextValue(burst_counter, 0),
NextValue(burst_limit_m1, burst_size - 1),
NextValue(SBUS_3V3_D_o, self.fromsbus_req_fifo.dout[blk_addr_width:blk_addr_width+32]),
NextValue(fifo_blk_addr, self.fromsbus_req_fifo.dout[0:blk_addr_width]),
NextValue(master_data_src_fromsbus_fifo, 1),
self.fromsbus_req_fifo.re.eq(1),
Case(burst_size, {
2 : [NextValue(SBUS_3V3_SIZ_o, SIZ_BURST2),
NextValue(master_size, SIZ_BURST2)],
4 : [NextValue(SBUS_3V3_SIZ_o, SIZ_BURST4),
NextValue(master_size, SIZ_BURST4)],
8 : [NextValue(SBUS_3V3_SIZ_o, SIZ_BURST8),
NextValue(master_size, SIZ_BURST8)],
16 : [NextValue(SBUS_3V3_SIZ_o, SIZ_BURST16),
NextValue(master_size, SIZ_BURST16)],
}),
NextValue(SBUS_3V3_PPRD_o, 1),
NextValue(master_we, 0),
NextState("Master_Translation")
).Elif(((SBUS_3V3_SELs_i == 0) &
(SBUS_3V3_ASs_i == 0)),
NextValue(sbus_oe_master_in, 1),
@ -1050,6 +1137,10 @@ class SBusFPGABus(Module):
If(master_we,
NextValue(sbus_oe_data, 1),
Case(master_size, {
SIZ_BURST2: NextValue(SBUS_3V3_D_o, master_data),
SIZ_BURST4: NextValue(SBUS_3V3_D_o, master_data),
SIZ_BURST8: NextValue(SBUS_3V3_D_o, master_data),
SIZ_BURST16: NextValue(SBUS_3V3_D_o, master_data),
SIZ_WORD: NextValue(SBUS_3V3_D_o, master_data),
SIZ_BYTE: Case(master_idx, {
0: NextValue(SBUS_3V3_D_o, Cat(master_data[ 0: 8],
@ -1075,7 +1166,10 @@ class SBusFPGABus(Module):
2: NextValue(SBUS_3V3_D_o, Cat(master_data[16:32],
master_data[16:32],)),
})
})
}),
If(master_data_src_tosbus_fifo,
NextValue(master_data, fifo_buffer[32:64]), # 0:32 is on the bus already
),
).Else(
NextValue(sbus_oe_data, 0)
),
@ -1096,9 +1190,10 @@ class SBusFPGABus(Module):
NextState("Idle")],
ACK_IDLE:
[If(master_we,
NextState("Master_Write")
NextState("Master_Write"),
## FIXME: in burst mode, should update master_data with the next value
## FIXME: we don't do burst mode yet
## FIXME: actually now from FIFO is handled above
).Else(
NextState("Master_Read")
)],
@ -1140,8 +1235,29 @@ class SBusFPGABus(Module):
)
slave_fsm.act("Master_Read_Ack",
#NextValue(self.led_display.value, Cat(Signal(8, reset = 0x0b), self.led_display.value[8:40])),
NextValue(self.master_read_buffer_data[burst_counter[0:2]], SBUS_3V3_D_i),
NextValue(self.master_read_buffer_done[burst_counter[0:2]], 1),
If(master_data_src_fromsbus_fifo,
Case(burst_counter, {
0: NextValue(fifo_buffer[0:32], SBUS_3V3_D_i),
1: NextValue(fifo_buffer[32:64], SBUS_3V3_D_i),
2: NextValue(fifo_buffer[64:96], SBUS_3V3_D_i),
3: NextValue(fifo_buffer[96:128], SBUS_3V3_D_i),
4: NextValue(fifo_buffer[128:160], SBUS_3V3_D_i),
5: NextValue(fifo_buffer[160:192], SBUS_3V3_D_i),
6: NextValue(fifo_buffer[192:224], SBUS_3V3_D_i),
7: NextValue(fifo_buffer[224:256], SBUS_3V3_D_i),
# 8: NextValue(fifo_buffer[256:288], SBUS_3V3_D_i),
# 9: NextValue(fifo_buffer[288:320], SBUS_3V3_D_i),
# 10: NextValue(fifo_buffer[320:352], SBUS_3V3_D_i),
# 11: NextValue(fifo_buffer[352:384], SBUS_3V3_D_i),
# 12: NextValue(fifo_buffer[384:416], SBUS_3V3_D_i),
# 13: NextValue(fifo_buffer[416:448], SBUS_3V3_D_i),
# 14: NextValue(fifo_buffer[448:480], SBUS_3V3_D_i),
# 15: NextValue(fifo_buffer[480:512], SBUS_3V3_D_i),
}),
).Else(
NextValue(self.master_read_buffer_data[burst_counter[0:2]], SBUS_3V3_D_i),
NextValue(self.master_read_buffer_done[burst_counter[0:2]], 1),
),
NextValue(burst_counter, burst_counter + 1),
If(burst_counter == burst_limit_m1,
NextValue(self.master_read_buffer_start, 0),
@ -1167,6 +1283,11 @@ class SBusFPGABus(Module):
)
slave_fsm.act("Master_Read_Finish", ## missing the handling of late error
#NextValue(self.led_display.value, Cat(Signal(8, reset = 0x0c), self.led_display.value[8:40])),
If(master_data_src_fromsbus_fifo,
fromsbus_fifo.we.eq(1),
fromsbus_fifo.din.eq(Cat(fifo_blk_addr, fifo_buffer)),
NextValue(master_data_src_fromsbus_fifo, 0),
),
NextValue(sbus_oe_data, 0),
NextValue(sbus_oe_slave_in, 0),
NextValue(sbus_oe_master_in, 0),
@ -1178,9 +1299,33 @@ class SBusFPGABus(Module):
ACK_WORD: # FIXME: check againt master_size ?
[If(burst_counter == burst_limit_m1,
NextState("Master_Write_Final"),
If(master_data_src_tosbus_fifo,
NextValue(master_data_src_tosbus_fifo, 0),
)
).Else(
NextValue(SBUS_3V3_D_o, master_data), ## FIXME: we're not updating master_data for burst mode yet
NextValue(SBUS_3V3_D_o, master_data),
NextValue(burst_counter, burst_counter + 1),
If(master_data_src_tosbus_fifo,
Case(burst_counter, { #0:32 just ack'd, 32:64 is on the bus now, burst_counter will only increment for the next cycle, so we're two steps ahead
0: NextValue(master_data, fifo_buffer[64:96]),
1: NextValue(master_data, fifo_buffer[96:128]),
2: NextValue(master_data, fifo_buffer[128:160]),
3: NextValue(master_data, fifo_buffer[160:192]),
4: NextValue(master_data, fifo_buffer[192:224]),
5: NextValue(master_data, fifo_buffer[224:256]),
# 6: NextValue(master_data, fifo_buffer[256:288]),
# 7: NextValue(master_data, fifo_buffer[288:320]),
# 8: NextValue(master_data, fifo_buffer[320:352]),
# 9: NextValue(master_data, fifo_buffer[352:384]),
# 10: NextValue(master_data, fifo_buffer[384:416]),
# 11: NextValue(master_data, fifo_buffer[416:448]),
# 12: NextValue(master_data, fifo_buffer[448:480]),
# 13: NextValue(master_data, fifo_buffer[480:512]),
#14: NextValue(master_data, fifo_buffer[512:544]),
#15: NextValue(master_data, fifo_buffer[544:576]),
"default": NextValue(master_data, 0),
})
),
)],
ACK_BYTE: # FIXME: check againt master_size ?
[NextState("Master_Write_Final"),
@ -1210,7 +1355,7 @@ class SBusFPGABus(Module):
NextValue(sbus_oe_data, 0),
NextValue(sbus_oe_slave_in, 0),
NextValue(sbus_oe_master_in, 0),
NextValue(sbus_master_throttle, 7),
NextValue(sbus_master_throttle, 3),
NextState("Idle")
)
# ##### FINISHED #####

View File

@ -17,6 +17,7 @@ from litedram.modules import MT41J128M16
from litedram.phy import s7ddrphy
from sbus_to_fpga_fsm import *;
from sbus_to_fpga_blk_dma import *;
import sbus_to_fpga_export;
@ -107,7 +108,7 @@ class SBusFPGA(SoCCore):
# Anything at 0x10000000 is therefore unreachable directly
# The position of the 'usb_fake_dma' is so it overlaps
# the virtual address space used by NetBSD DMA allocators
wb_mem_map = {
self.wb_mem_map = wb_mem_map = {
"prom": 0x00000000,
"csr" : 0x00040000,
"usb_host": 0x00080000,
@ -171,16 +172,33 @@ class SBusFPGA(SoCCore):
wishbone_master_sys = wishbone.Interface(data_width=self.bus.data_width)
self.submodules.wishbone_master_sbus = wishbone.WishboneDomainCrossingMaster(platform=self.platform, slave=wishbone_master_sys, cd_master="sbus", cd_slave="sys")
self.submodules.wishbone_slave_sys = wishbone.WishboneDomainCrossingMaster(platform=self.platform, slave=wishbone_slave_sbus, cd_master="sys", cd_slave="sbus")
burst_size=8
self.submodules.tosbus_fifo = ClockDomainsRenamer({"read": "sbus", "write": "sys"})(AsyncFIFOBuffered(width=(32+burst_size*32), depth=4))
self.submodules.fromsbus_fifo = ClockDomainsRenamer({"write": "sbus", "read": "sys"})(AsyncFIFOBuffered(width=((30-log2_int(burst_size))+burst_size*32), depth=4))
self.submodules.fromsbus_req_fifo = ClockDomainsRenamer({"read": "sbus", "write": "sys"})(AsyncFIFOBuffered(width=((30-log2_int(burst_size))+32), depth=16))
self.submodules.exchange_with_mem = ExchangeWithMem(soc=self,
tosbus_fifo=self.tosbus_fifo,
fromsbus_fifo=self.fromsbus_fifo,
fromsbus_req_fifo=self.fromsbus_req_fifo,
burst_size=burst_size)
_sbus_bus = SBusFPGABus(platform=self.platform,
hold_reset=hold_reset,
wishbone_slave=wishbone_slave_sbus,
wishbone_master=self.wishbone_master_sbus)
wishbone_master=self.wishbone_master_sbus,
tosbus_fifo=self.tosbus_fifo,
fromsbus_fifo=self.fromsbus_fifo,
fromsbus_req_fifo=self.fromsbus_req_fifo,
burst_size=burst_size)
#self.submodules.sbus_bus = _sbus_bus
self.submodules.sbus_bus = ClockDomainsRenamer("sbus")(_sbus_bus)
self.bus.add_master(name="SBusBridgeToWishbone", master=wishbone_master_sys)
self.bus.add_slave(name="usb_fake_dma", slave=self.wishbone_slave_sys, region=SoCRegion(origin=self.mem_map.get("usb_fake_dma", None), size=0x03ffffff, cached=False))
self.bus.add_master(name="mem_read_master", master=self.exchange_with_mem.wishbone_r_master)
self.bus.add_master(name="mem_write_master", master=self.exchange_with_mem.wishbone_w_master)
self.submodules.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
memtype = "DDR3",
@ -189,10 +207,10 @@ class SBusFPGA(SoCCore):
self.add_sdram("sdram",
phy = self.ddrphy,
module = MT41J128M16(sys_clk_freq, "1:4"),
l2_cache_size = 0
l2_cache_size = 0,
)
self.add_sdcard()
#self.add_sdcard()
def main():
parser = argparse.ArgumentParser(description="SbusFPGA")