From 575af6fc603a404b572118504f45622ec5df70db Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 7 Sep 2021 13:45:43 +0200 Subject: [PATCH] litespi/integration: Review/Cleanup #1024. Integration from #1024 was working on some boards (ex Arty) but breaking others (ex iCEBreaker); simplify things for now: - Avoid duplication in spiflash_freq_init. - Avoid passing useless SPIFLASH_LEGACY flag to software (software can detect it from csr.h). - Only keep integration support for "legacy" PHY, others are not generic enough and can be passed with phy parameter. --- litex/soc/integration/soc.py | 32 ++++++------ litex/soc/software/liblitespi/spiflash.c | 62 ++++++++++-------------- litex/tools/litex_sim.py | 13 +++-- 3 files changed, 47 insertions(+), 60 deletions(-) diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index 82626f7d7..148fb113e 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -1491,7 +1491,7 @@ class LiteXSoC(SoC): self.platform.add_false_path_constraints(self.crg.cd_sys.clk, eth_rx_clk, eth_tx_clk) # Add SPI Flash -------------------------------------------------------------------------------- - def add_spi_flash(self, name="spiflash", mode="4x", dummy_cycles=None, clk_freq=None, module=None, init=None, clock_domain="sys", **kwargs): + def add_spi_flash(self, name="spiflash", mode="4x", dummy_cycles=None, clk_freq=None, module=None, phy=None, **kwargs): if module is None: # Use previous LiteX SPI Flash core with compat, will be deprecated at some point. from litex.compat.soc_add_spi_flash import add_spi_flash @@ -1500,37 +1500,33 @@ class LiteXSoC(SoC): else: # Imports. from litespi import LiteSPI + from litespi.phy.generic import LiteSPIPHY from litespi.opcodes import SpiNorFlashOpCodes # Checks/Parameters. assert mode in ["1x", "4x"] if clk_freq is None: clk_freq = self.sys_clk_freq + # PHY. + spiflash_phy = phy + if spiflash_phy is None: + self.check_if_exists(name + "_phy") + spiflash_pads = self.platform.request(name if mode == "1x" else name + mode) + spiflash_phy = LiteSPIPHY(spiflash_pads, module, device=self.platform.device, default_divisor=int(self.sys_clk_freq/clk_freq)) + setattr(self.submodules, name + "_phy", spiflash_phy) + # Core. - self.check_if_exists(name + "_phy") self.check_if_exists(name + "_mmap") - spiflash_pads = self.platform.request(name if mode == "1x" else name + mode) - if init is None: - from litespi.phy.generic import LiteSPIPHY - 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) - spiflash_core = LiteSPI(spiflash_phy, clock_domain=clock_domain, mmap_endianness=self.cpu.endianness, **kwargs) - setattr(self.submodules, name + "_phy", spiflash_phy) + spiflash_core = LiteSPI(spiflash_phy, mmap_endianness=self.cpu.endianness, **kwargs) setattr(self.submodules, name + "_core", spiflash_core) spiflash_region = SoCRegion(origin=self.mem_map.get(name, None), size=module.total_size) self.bus.add_slave(name=name, slave=spiflash_core.bus, region=spiflash_region) # Constants. - self.add_constant("SPIFLASH_FREQUENCY", clk_freq) - self.add_constant("SPIFLASH_MODULE_NAME", module.name.upper()) + self.add_constant("SPIFLASH_PHY_FREQUENCY", clk_freq) + self.add_constant("SPIFLASH_MODULE_NAME", module.name.upper()) self.add_constant("SPIFLASH_MODULE_TOTAL_SIZE", module.total_size) - self.add_constant("SPIFLASH_MODULE_PAGE_SIZE", module.page_size) + self.add_constant("SPIFLASH_MODULE_PAGE_SIZE", module.page_size) if SpiNorFlashOpCodes.READ_1_1_4 in module.supported_opcodes: self.add_constant("SPIFLASH_MODULE_QUAD_CAPABLE") if SpiNorFlashOpCodes.READ_4_4_4 in module.supported_opcodes: diff --git a/litex/soc/software/liblitespi/spiflash.c b/litex/soc/software/liblitespi/spiflash.c index e19179cf1..6f8c47a63 100644 --- a/litex/soc/software/liblitespi/spiflash.c +++ b/litex/soc/software/liblitespi/spiflash.c @@ -13,47 +13,20 @@ #include "spiflash.h" +//#define SPIFLASH_DEBUG + #if defined(CSR_SPIFLASH_CORE_BASE) -#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 +#ifdef CSR_SPIFLASH_PHY_CLK_DIVISOR_ADDR - /* 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; - } + unsigned int lowest_div, crc, crc_test; - 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) -{ - unsigned int crc = crc32((unsigned char *)SPIFLASH_BASE, SPI_FLASH_BLOCK_SIZE); - unsigned int crc_test = crc; + lowest_div = spiflash_phy_clk_divisor_read(); + crc = crc32((unsigned char *)SPIFLASH_BASE, SPI_FLASH_BLOCK_SIZE); + crc_test = crc; #if SPIFLASH_DEBUG printf("Testing against CRC32: %08x\n\r", crc); @@ -65,12 +38,27 @@ int spiflash_freq_init(void) return -1; } - printf("SPI Flash clk configured to %ld MHz\n", (unsigned long)(spiflash_frequency_read()/1e6)); + 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_PHY_FREQUENCY/(2*(1 + lowest_div)))/1000000); + + spiflash_phy_clk_divisor_write(lowest_div); + +#else + + printf("SPI Flash clk configured to %ld MHz\n", (unsigned long)(SPIFLASH_PHY_FREQUENCY/1e6)); + +#endif + return 0; } -#endif // SPIFLASH_LEGACY - void spiflash_dummy_bits_setup(unsigned int dummy_bits) { spiflash_core_mmap_dummy_bits_write((uint32_t)dummy_bits); diff --git a/litex/tools/litex_sim.py b/litex/tools/litex_sim.py index 6a6815433..961c3635e 100755 --- a/litex/tools/litex_sim.py +++ b/litex/tools/litex_sim.py @@ -116,7 +116,7 @@ class SimSoC(SoCCore): with_i2c = False, with_sdcard = False, with_spi_flash = False, - flash_init = [], + spi_flash_init = [], sim_debug = False, trace_reset_on = False, **kwargs): @@ -252,12 +252,15 @@ class SimSoC(SoCCore): # SPI Flash -------------------------------------------------------------------------------- if with_spi_flash: + from litespi.phy.model import LiteSPIPHYModel from litespi.modules import S25FL128L from litespi.opcodes import SpiNorFlashOpCodes as Codes - if flash_init is None: + spiflash_module = S25FL128L(Codes.READ_1_1_4) + if spi_flash_init is None: platform.add_sources(os.path.abspath(os.path.dirname(__file__)), "../build/sim/verilog/iddr_verilog.v") platform.add_sources(os.path.abspath(os.path.dirname(__file__)), "../build/sim/verilog/oddr_verilog.v") - self.add_spi_flash(mode="4x", module=S25FL128L(Codes.READ_1_1_4), with_master=True, init=flash_init) + self.submodules.spiflash_phy = LiteSPIPHYModel(spiflash_module, init=spi_flash_init) + self.add_spi_flash(phy=self.spiflash_phy, mode="4x", module=spiflash_module, with_master=True) # Simulation debugging ---------------------------------------------------------------------- if sim_debug: @@ -323,7 +326,7 @@ def sim_args(parser): parser.add_argument("--with-i2c", action="store_true", help="Enable I2C support") parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support") parser.add_argument("--with-spi-flash", action="store_true", help="Enable SPI Flash (MMAPed)") - parser.add_argument("--flash-init", default=None, help="Flash init file") + parser.add_argument("--spi_flash-init", default=None, help="SPI Flash init file") parser.add_argument("--trace", action="store_true", help="Enable Tracing") parser.add_argument("--trace-fst", action="store_true", help="Enable FST tracing (default=VCD)") parser.add_argument("--trace-start", default="0", help="Time to start tracing (ps)") @@ -394,7 +397,7 @@ def main(): sim_debug = args.sim_debug, trace_reset_on = trace_start > 0 or trace_end > 0, sdram_init = [] if args.sdram_init is None else get_mem_data(args.sdram_init, cpu.endianness), - flash_init = None if args.flash_init is None else get_mem_data(args.flash_init, "big"), + spi_flash_init = None if args.spi_flash_init is None else get_mem_data(args.spi_flash_init, "big"), **soc_kwargs) if args.ram_init is not None or args.sdram_init is not None: soc.add_constant("ROM_BOOT_ADDRESS", soc.mem_map["main_ram"])