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.
for key, value in kwargs.items():
cmd.append(f"--{key}")
cmd.append(f"--{key.replace('_', '-')}")
if value is not None:
cmd.append(str(value))
# 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.
# 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.
from litespi import LiteSPI
from litespi.phy.generic import LiteSPIPHY
from litespi.opcodes import SpiNorFlashOpCodes
import math
# Checks/Parameters.
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.
spiflash_phy = phy
if spiflash_phy is None:
self.check_if_exists(f"{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), 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)
# Core.
@ -1909,10 +1912,11 @@ class LiteXSoC(SoC):
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_PAGE_SIZE", module.page_size)
if SpiNorFlashOpCodes.READ_1_1_4 in module.supported_opcodes:
self.add_constant(f"{name}_MODULE_QUAD_CAPABLE")
if SpiNorFlashOpCodes.READ_4_4_4 in module.supported_opcodes:
self.add_constant(f"{name}_MODULE_QPI_CAPABLE")
if mode in [ "4x" ]:
if SpiNorFlashOpCodes.READ_1_1_4 in module.supported_opcodes:
self.add_constant(f"{name}_MODULE_QUAD_CAPABLE")
if SpiNorFlashOpCodes.READ_4_4_4 in module.supported_opcodes:
self.add_constant(f"{name}_MODULE_QPI_CAPABLE")
if software_debug:
self.add_constant(f"{name}_DEBUG")

View file

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

View file

@ -1,6 +1,7 @@
// This file is Copyright (c) 2020 Antmicro <www.antmicro.com>
// License: BSD
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -25,6 +26,8 @@ int spiflash_freq_init(void)
unsigned int lowest_div, crc, crc_test;
lowest_div = spiflash_phy_clk_divisor_read();
flush_cpu_dcache();
flush_l2_cache();
crc = crc32((unsigned char *)SPIFLASH_BASE, SPI_FLASH_BLOCK_SIZE);
crc_test = crc;
@ -40,19 +43,21 @@ int spiflash_freq_init(void)
while((crc == crc_test) && (lowest_div-- > 0)) {
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);
#ifdef 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);
printf("SPI Flash clk configured to %d MHz\n", CONFIG_CLOCK_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));
printf("SPI Flash clk configured to %ld MHz\n", SPIFLASH_PHY_FREQUENCY/1000000);
#endif
@ -63,7 +68,7 @@ void spiflash_dummy_bits_setup(unsigned int dummy_bits)
{
spiflash_core_mmap_dummy_bits_write((uint32_t)dummy_bits);
#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
}
@ -107,7 +112,7 @@ static uint32_t transfer_byte(uint8_t b)
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_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[2] = addr>>8;
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);
}