mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
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:
commit
be23467cb1
4 changed files with 29 additions and 14 deletions
|
@ -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.
|
||||
try:
|
||||
self.call(cmd)
|
||||
except OSError as e:
|
||||
print(' '.join(cmd))
|
||||
raise
|
||||
|
|
|
@ -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,6 +1912,7 @@ 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 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:
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue