From 3ef13fd27a027c98bbe2a0b5b252c175fc0262c6 Mon Sep 17 00:00:00 2001 From: Gabriel Somlo Date: Sun, 17 Nov 2019 10:08:50 -0500 Subject: [PATCH] soc_sdram, bios/sdram: support sdram init for csr_data_width <= 32 Enable SDRAM to be initialized when csr_data_width > 8 bits. Currently, csr_data_width up to 32 bits is supported. Read leveling tested with csr_data_width [8, 16, 32] on the ecp5-versa5g and trellisboard (using yosys/trellis/nextpnr), and on the nexys4ddr (using Vivado). Signed-off-by: Gabriel Somlo --- litex/soc/integration/soc_sdram.py | 4 +- litex/soc/software/bios/sdram.c | 162 +++++++++++++++++++---------- 2 files changed, 109 insertions(+), 57 deletions(-) diff --git a/litex/soc/integration/soc_sdram.py b/litex/soc/integration/soc_sdram.py index c5db62b5b..9786e7792 100644 --- a/litex/soc/integration/soc_sdram.py +++ b/litex/soc/integration/soc_sdram.py @@ -29,8 +29,8 @@ class SoCSDRAM(SoCCore): def __init__(self, platform, clk_freq, l2_size=8192, **kwargs): SoCCore.__init__(self, platform, clk_freq, **kwargs) if not self.integrated_main_ram_size: - if self.cpu_type is not None and self.csr_data_width != 8: - raise NotImplementedError("BIOS supports SDRAM initialization only for csr_data_width=8") + if self.cpu_type is not None and self.csr_data_width > 32: + raise NotImplementedError("BIOS supports SDRAM initialization only for csr_data_width<=32") self.l2_size = l2_size self._sdram_phy = [] diff --git a/litex/soc/software/bios/sdram.c b/litex/soc/software/bios/sdram.c index f0c12edfe..652d9098f 100644 --- a/litex/soc/software/bios/sdram.c +++ b/litex/soc/software/bios/sdram.c @@ -20,6 +20,8 @@ #include #include +#include // for hton/ntoh (byteswap) functions + #include "sdram.h" // FIXME(hack): If we don't have main ram, just target the sram instead. @@ -55,6 +57,26 @@ __attribute__((unused)) static void cdelay(int i) #define DFII_ADDR_SHIFT CONFIG_CSR_ALIGNMENT/8 +#define CSR_DATA_BYTES CONFIG_CSR_DATA_WIDTH/8 + +#define DFII_PIX_DATA_BYTES DFII_PIX_DATA_SIZE*CSR_DATA_BYTES + +#if CSR_DATA_BYTES == 1 + typedef uint8_t csr_dw_t; + #define csr_dw_hton(x) (x) + #define csr_dw_ntoh(x) (x) +#elif CSR_DATA_BYTES == 2 + typedef uint16_t csr_dw_t; + #define csr_dw_hton(x) htons(x) + #define csr_dw_ntoh(x) ntohs(x) +#elif CSR_DATA_BYTES == 4 + typedef uint32_t csr_dw_t; + #define csr_dw_hton(x) htonl(x) + #define csr_dw_ntoh(x) ntohl(x) +#else +#error Unsupported CSR data width +#endif + void sdrsw(void) { sdram_dfii_control_write(DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N); @@ -96,18 +118,23 @@ void sdrrdbuf(int dq) { int i, p; int first_byte, step; + csr_dw_t buf[DFII_PIX_DATA_SIZE]; + unsigned char *buf_bytes = (unsigned char *)&(buf[0]); if(dq < 0) { first_byte = 0; step = 1; } else { - first_byte = DFII_PIX_DATA_SIZE/2 - 1 - dq; - step = DFII_PIX_DATA_SIZE/2; + first_byte = DFII_PIX_DATA_BYTES/2 - 1 - dq; + step = DFII_PIX_DATA_BYTES/2; } - for(p=0;p\n"); @@ -162,8 +190,9 @@ void sdrrderr(char *count) return; } - for(i=0;i\n"); + printf("sdrwr
\n"); return; } addr = strtoul(startaddr, &c, 0); @@ -213,9 +242,12 @@ void sdrwr(char *startaddr) return; } - for(p=0;p