From cd9fa81a828569b51ab3855a959aa3e3d38c0c05 Mon Sep 17 00:00:00 2001 From: Romain Dolbeau Date: Sat, 17 Jul 2021 11:03:44 -0400 Subject: [PATCH] access the SDRAM using a custom DMA; unreliable yet --- .../9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.c | 359 ++++++++++++-- .../9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.h | 15 + sbus-to-ztex-gateware-migen/netbsd_csr.h | 465 ++++++++++++++++++ sbus-to-ztex-gateware-migen/prom_csr.fth | 8 +- sbus-to-ztex-gateware-migen/prom_migen.fth | 16 +- .../sbus_to_fpga_fsm.py | 173 ++++++- .../sbus_to_fpga_soc.py | 26 +- 7 files changed, 1006 insertions(+), 56 deletions(-) create mode 100644 sbus-to-ztex-gateware-migen/netbsd_csr.h diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.c b/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.c index f273c8b..035e98b 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.c +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.c @@ -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); diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.h b/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.h index 2fa554a..3c24afe 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.h +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.h @@ -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_ */ diff --git a/sbus-to-ztex-gateware-migen/netbsd_csr.h b/sbus-to-ztex-gateware-migen/netbsd_csr.h new file mode 100644 index 0000000..f7a1606 --- /dev/null +++ b/sbus-to-ztex-gateware-migen/netbsd_csr.h @@ -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 diff --git a/sbus-to-ztex-gateware-migen/prom_csr.fth b/sbus-to-ztex-gateware-migen/prom_csr.fth index 5c43479..d9d0973 100644 --- a/sbus-to-ztex-gateware-migen/prom_csr.fth +++ b/sbus-to-ztex-gateware-migen/prom_csr.fth @@ -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 diff --git a/sbus-to-ztex-gateware-migen/prom_migen.fth b/sbus-to-ztex-gateware-migen/prom_migen.fth index 6b9388a..6b0821d 100644 --- a/sbus-to-ztex-gateware-migen/prom_migen.fth +++ b/sbus-to-ztex-gateware-migen/prom_migen.fth @@ -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 diff --git a/sbus-to-ztex-gateware-migen/sbus_to_fpga_fsm.py b/sbus-to-ztex-gateware-migen/sbus_to_fpga_fsm.py index 8155104..280685c 100644 --- a/sbus-to-ztex-gateware-migen/sbus_to_fpga_fsm.py +++ b/sbus-to-ztex-gateware-migen/sbus_to_fpga_fsm.py @@ -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 ##### diff --git a/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py b/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py index 2a259f7..f795598 100644 --- a/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py +++ b/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py @@ -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")