Merge pull request #1881 from motec-research/spiflash_fixes

Spiflash fixes for issues exposed by sys_clk = 200MHz and L2 cache
This commit is contained in:
enjoy-digital 2024-02-01 08:33:36 +01:00 committed by GitHub
commit be23467cb1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 29 additions and 14 deletions

View file

@ -66,9 +66,13 @@ class OpenFPGALoader(GenericProgrammer):
# Handle kwargs for specific, less common cases. # Handle kwargs for specific, less common cases.
for key, value in kwargs.items(): for key, value in kwargs.items():
cmd.append(f"--{key}") cmd.append(f"--{key.replace('_', '-')}")
if value is not None: if value is not None:
cmd.append(str(value)) cmd.append(str(value))
# Execute Command. # Execute Command.
self.call(cmd) try:
self.call(cmd)
except OSError as e:
print(' '.join(cmd))
raise

View file

@ -1879,22 +1879,25 @@ class LiteXSoC(SoC):
self.add_constant("ETH_PHY_NO_RESET") # Disable reset from BIOS to avoid disabling Hardware Interface. self.add_constant("ETH_PHY_NO_RESET") # Disable reset from BIOS to avoid disabling Hardware Interface.
# Add SPI Flash -------------------------------------------------------------------------------- # Add SPI Flash --------------------------------------------------------------------------------
def add_spi_flash(self, name="spiflash", mode="4x", clk_freq=None, module=None, phy=None, rate="1:1", software_debug=False, **kwargs): def add_spi_flash(self, name="spiflash", mode="4x", clk_freq=20e6, module=None, phy=None, rate="1:1", software_debug=False, **kwargs):
# Imports. # Imports.
from litespi import LiteSPI from litespi import LiteSPI
from litespi.phy.generic import LiteSPIPHY from litespi.phy.generic import LiteSPIPHY
from litespi.opcodes import SpiNorFlashOpCodes from litespi.opcodes import SpiNorFlashOpCodes
import math
# Checks/Parameters. # Checks/Parameters.
assert mode in ["1x", "4x"] assert mode in ["1x", "4x"]
if clk_freq is None: clk_freq = self.sys_clk_freq # From LiteSPIClkGen: clk_freq will be ``sys_clk_freq/(2*(1+div))``.
default_divisor = math.ceil(self.sys_clk_freq/(clk_freq*2))-1
clk_freq = int(self.sys_clk_freq/(2*(1+default_divisor)))
# PHY. # PHY.
spiflash_phy = phy spiflash_phy = phy
if spiflash_phy is None: if spiflash_phy is None:
self.check_if_exists(f"{name}_phy") self.check_if_exists(f"{name}_phy")
spiflash_pads = self.platform.request(name if mode == "1x" else name + mode) 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), rate=rate) spiflash_phy = LiteSPIPHY(spiflash_pads, module, device=self.platform.device, default_divisor=default_divisor, rate=rate)
self.add_module(name=f"{name}_phy", module=spiflash_phy) self.add_module(name=f"{name}_phy", module=spiflash_phy)
# Core. # Core.
@ -1909,10 +1912,11 @@ class LiteXSoC(SoC):
self.add_constant(f"{name}_MODULE_NAME", module.name.upper()) self.add_constant(f"{name}_MODULE_NAME", module.name.upper())
self.add_constant(f"{name}_MODULE_TOTAL_SIZE", module.total_size) self.add_constant(f"{name}_MODULE_TOTAL_SIZE", module.total_size)
self.add_constant(f"{name}_MODULE_PAGE_SIZE", module.page_size) self.add_constant(f"{name}_MODULE_PAGE_SIZE", module.page_size)
if SpiNorFlashOpCodes.READ_1_1_4 in module.supported_opcodes: if mode in [ "4x" ]:
self.add_constant(f"{name}_MODULE_QUAD_CAPABLE") if SpiNorFlashOpCodes.READ_1_1_4 in module.supported_opcodes:
if SpiNorFlashOpCodes.READ_4_4_4 in module.supported_opcodes: self.add_constant(f"{name}_MODULE_QUAD_CAPABLE")
self.add_constant(f"{name}_MODULE_QPI_CAPABLE") if SpiNorFlashOpCodes.READ_4_4_4 in module.supported_opcodes:
self.add_constant(f"{name}_MODULE_QPI_CAPABLE")
if software_debug: if software_debug:
self.add_constant(f"{name}_DEBUG") self.add_constant(f"{name}_DEBUG")

View file

@ -115,6 +115,8 @@ static void crc_handler(int nb_params, char **params)
return; return;
} }
flush_cpu_dcache();
flush_l2_cache();
printf("CRC32: %08x", crc32((unsigned char *)addr, length)); printf("CRC32: %08x", crc32((unsigned char *)addr, length));
} }

View file

@ -1,6 +1,7 @@
// This file is Copyright (c) 2020 Antmicro <www.antmicro.com> // This file is Copyright (c) 2020 Antmicro <www.antmicro.com>
// License: BSD // License: BSD
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -25,6 +26,8 @@ int spiflash_freq_init(void)
unsigned int lowest_div, crc, crc_test; unsigned int lowest_div, crc, crc_test;
lowest_div = spiflash_phy_clk_divisor_read(); lowest_div = spiflash_phy_clk_divisor_read();
flush_cpu_dcache();
flush_l2_cache();
crc = crc32((unsigned char *)SPIFLASH_BASE, SPI_FLASH_BLOCK_SIZE); crc = crc32((unsigned char *)SPIFLASH_BASE, SPI_FLASH_BLOCK_SIZE);
crc_test = crc; crc_test = crc;
@ -40,19 +43,21 @@ int spiflash_freq_init(void)
while((crc == crc_test) && (lowest_div-- > 0)) { while((crc == crc_test) && (lowest_div-- > 0)) {
spiflash_phy_clk_divisor_write((uint32_t)lowest_div); spiflash_phy_clk_divisor_write((uint32_t)lowest_div);
flush_cpu_dcache();
flush_l2_cache();
crc_test = crc32((unsigned char *)SPIFLASH_BASE, SPI_FLASH_BLOCK_SIZE); crc_test = crc32((unsigned char *)SPIFLASH_BASE, SPI_FLASH_BLOCK_SIZE);
#ifdef SPIFLASH_DEBUG #ifdef SPIFLASH_DEBUG
printf("[DIV: %d] %08x\n\r", lowest_div, crc_test); printf("[DIV: %d] %08x\n\r", lowest_div, crc_test);
#endif #endif
} }
lowest_div++; lowest_div++;
printf("SPI Flash clk configured to %d MHz\n", (SPIFLASH_PHY_FREQUENCY/(2*(1 + lowest_div)))/1000000); printf("SPI Flash clk configured to %d MHz\n", CONFIG_CLOCK_FREQUENCY/(2*(1+lowest_div)*1000000));
spiflash_phy_clk_divisor_write(lowest_div); spiflash_phy_clk_divisor_write(lowest_div);
#else #else
printf("SPI Flash clk configured to %ld MHz\n", (unsigned long)(SPIFLASH_PHY_FREQUENCY/1e6)); printf("SPI Flash clk configured to %ld MHz\n", SPIFLASH_PHY_FREQUENCY/1000000);
#endif #endif
@ -63,7 +68,7 @@ void spiflash_dummy_bits_setup(unsigned int dummy_bits)
{ {
spiflash_core_mmap_dummy_bits_write((uint32_t)dummy_bits); spiflash_core_mmap_dummy_bits_write((uint32_t)dummy_bits);
#ifdef SPIFLASH_DEBUG #ifdef SPIFLASH_DEBUG
printf("Dummy bits set to: %d\n\r", spiflash_core_mmap_dummy_bits_read()); printf("Dummy bits set to: %" PRIx32 "\n\r", spiflash_core_mmap_dummy_bits_read());
#endif #endif
} }
@ -107,7 +112,7 @@ static uint32_t transfer_byte(uint8_t b)
return spiflash_core_master_rxtx_read(); return spiflash_core_master_rxtx_read();
} }
static void transfer_cmd(uint8_t *bs, uint8_t *resp, int len) static void transfer_cmd(volatile uint8_t *bs, volatile uint8_t *resp, int len)
{ {
spiflash_core_master_phyconfig_len_write(8); spiflash_core_master_phyconfig_len_write(8);
spiflash_core_master_phyconfig_width_write(1); spiflash_core_master_phyconfig_width_write(1);
@ -170,7 +175,7 @@ static void page_program(uint32_t addr, uint8_t *data, int len)
w_buf[1] = addr>>16; w_buf[1] = addr>>16;
w_buf[2] = addr>>8; w_buf[2] = addr>>8;
w_buf[3] = addr>>0; w_buf[3] = addr>>0;
memcpy(w_buf+4, data, len); memcpy((void *)w_buf+4, (void *)data, len);
transfer_cmd(w_buf, r_buf, len+4); transfer_cmd(w_buf, r_buf, len+4);
} }