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.
This commit is contained in:
Florent Kermarrec 2021-09-07 13:45:43 +02:00
parent aff2aefa72
commit 575af6fc60
3 changed files with 47 additions and 60 deletions

View File

@ -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:

View File

@ -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);

View File

@ -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"])