From ad0fcc22e602891ec5eeae67ecc94a8fc170fa2c Mon Sep 17 00:00:00 2001 From: Pawel Sagan Date: Thu, 2 Sep 2021 17:38:17 +0200 Subject: [PATCH] litex: adding legacy mode for litespi Inside the litex add_spi_flash function we are detecting the devices that can't be used with more efficient DDR version of litespi phy core and we are choosing whether to instantiate the legacy or DDR core --- litex/soc/integration/soc.py | 6 +++- litex/soc/software/liblitespi/spiflash.c | 39 ++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index a73e21be1..82626f7d7 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -1512,7 +1512,11 @@ class LiteXSoC(SoC): spiflash_pads = self.platform.request(name if mode == "1x" else name + mode) if init is None: from litespi.phy.generic import LiteSPIPHY - spiflash_phy = LiteSPIPHY(spiflash_pads, module, clock_domain=clock_domain, device=self.platform.device,) + if not hasattr(spiflash_pads, "clk") or self.platform.device.startswith("LFE5U") or self.platform.device.startswith("LAE5U"): + spiflash_phy = LiteSPIPHY(spiflash_pads, module, clock_domain=clock_domain, device=self.platform.device, default_divisor=int(self.sys_clk_freq/clk_freq), legacy=True) + self.add_constant("SPIFLASH_LEGACY") + else: + spiflash_phy = LiteSPIPHY(spiflash_pads, module, clock_domain=clock_domain, device=self.platform.device, legacy=False) else: from litespi.phy.model import LiteSPIPHYModel spiflash_phy = LiteSPIPHYModel(module, init=init, clock_domain=clock_domain) diff --git a/litex/soc/software/liblitespi/spiflash.c b/litex/soc/software/liblitespi/spiflash.c index 80ea8f752..e19179cf1 100644 --- a/litex/soc/software/liblitespi/spiflash.c +++ b/litex/soc/software/liblitespi/spiflash.c @@ -15,8 +15,40 @@ #if defined(CSR_SPIFLASH_CORE_BASE) -//#define SPIFLASH_DEBUG -//#define SPIFLASH_MODULE_DUMMY_BITS 8 +#if defined(SPIFLASH_LEGACY) + +int spiflash_freq_init(void) +{ + unsigned int lowest_div = spiflash_phy_clk_divisor_read(); + unsigned int crc = crc32((unsigned char *)SPIFLASH_BASE, SPI_FLASH_BLOCK_SIZE); + unsigned int crc_test = crc; + +#if SPIFLASH_DEBUG + printf("Testing against CRC32: %08x\n\r", crc); +#endif + + /* Check if block is erased (filled with 0xFF) */ + if(crc == CRC32_ERASED_FLASH) { + printf("Block of size %d, started on address 0x%lx is erased. Cannot proceed with SPI Flash frequency test.\n\r", SPI_FLASH_BLOCK_SIZE, SPIFLASH_BASE); + return -1; + } + + while((crc == crc_test) && (lowest_div-- > 0)) { + spiflash_phy_clk_divisor_write((uint32_t)lowest_div); + crc_test = crc32((unsigned char *)SPIFLASH_BASE, SPI_FLASH_BLOCK_SIZE); +#if SPIFLASH_DEBUG + printf("[DIV: %d] %08x\n\r", lowest_div, crc_test); +#endif + } + lowest_div++; + printf("SPI Flash clk configured to %d MHz\n", (spiflash_frequency_read()/(2*(1 + lowest_div)))/1000000); + + spiflash_phy_clk_divisor_write(lowest_div); + + return 0; +} + +#else int spiflash_freq_init(void) { @@ -36,6 +68,9 @@ int spiflash_freq_init(void) printf("SPI Flash clk configured to %ld MHz\n", (unsigned long)(spiflash_frequency_read()/1e6)); return 0; } + +#endif // SPIFLASH_LEGACY + void spiflash_dummy_bits_setup(unsigned int dummy_bits) { spiflash_core_mmap_dummy_bits_write((uint32_t)dummy_bits);