Add ability to deassert CS after a configured idle interval

Do not attempt merged Flashed read/writes during 32-bit CPU accesses in non-merged mode
Split Kestrel SPI defines into dedicated header
parent 3c5f77ce
......@@ -16,6 +16,7 @@
#include <generated/mem.h>
#include "fsi.h"
#include "tercel_spi.h"
#define DEBUG_HOST_SPI_FLASH_READ 1
......@@ -120,31 +121,6 @@ static void memcpy32(uint32_t *destination, uint32_t *source, int words) {
}
}
#define TERCEL_SPI_ENABLE_USER_MODE_MASK 0x1
#define TERCEL_SPI_ENABLE_USER_MODE_SHIFT 0x0
#define TERCEL_SPI_PHY_DUMMY_CYCLES_MASK 0xff
#define TERCEL_SPI_PHY_DUMMY_CYCLES_SHIFT 8
#define TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK 0xff
#define TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT 0
#define TERCEL_SPI_PHY_IO_TYPE_MASK 0x3
#define TERCEL_SPI_PHY_IO_TYPE_SHIFT 16
#define TERCEL_SPI_PHY_4BA_ENABLE_MASK 0x1
#define TERCEL_SPI_PHY_4BA_ENABLE_SHIFT 18
#define TERCEL_SPI_PHY_FAST_READ_ENABLE_MASK 0x1
#define TERCEL_SPI_PHY_FAST_READ_ENABLE_SHIFT 19
#define TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_MASK 0xff
#define TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_SHIFT 24
#define TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_MASK 0x1
#define TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_SHIFT 1
#define TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK 0x1
#define TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT 0
#define TERCEL_SPI_PHY_IO_TYPE_SINGLE 0x0
#define TERCEL_SPI_PHY_IO_TYPE_QUAD 0x2
#define TERCEL_SPI_PHY_3BA_MODE 0x0
#define TERCEL_SPI_PHY_4BA_MODE 0x1
static uint32_t read_host_spi_flash_id(void) {
uint32_t flash_id = 0;
......@@ -178,13 +154,18 @@ static int host_spi_flash_init(void) {
// Set SPI core to automatic mode
hostspiflash_core_ctl1_write(hostspiflash_core_ctl1_read() & ~(TERCEL_SPI_ENABLE_USER_MODE_MASK << TERCEL_SPI_ENABLE_USER_MODE_SHIFT));
#if 1
// Set extra CS delay cycle count to 0
dword = hostspiflash_phy_cfg1_read();
dword &= ~(TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_MASK << TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_SHIFT);
dword |= ((0 & TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_MASK) << TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_SHIFT);
hostspiflash_phy_cfg1_write(dword);
// Set maximum CS assert cycle count to 10000
dword = hostspiflash_flash_cfg4_read();
dword &= ~(TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_MASK << TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_SHIFT);
dword |= ((10000 & TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_MASK) << TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_SHIFT);
hostspiflash_flash_cfg4_write(dword);
// Set SPI fast read dummy cycles to 10
dword = hostspiflash_phy_cfg1_read();
dword &= ~(TERCEL_SPI_PHY_DUMMY_CYCLES_MASK << TERCEL_SPI_PHY_DUMMY_CYCLES_SHIFT);
......@@ -214,7 +195,6 @@ static int host_spi_flash_init(void) {
dword &= ~(TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK << TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT);
dword |= ((4 & TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK) << TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT);
hostspiflash_phy_cfg1_write(dword);
#endif
// Calculate and dump configured SPI clock speed
uint8_t spi_divisor = (hostspiflash_phy_cfg1_read() >> TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT) & TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK;
......@@ -222,13 +202,11 @@ static int host_spi_flash_init(void) {
uint8_t spi_dummy_cycles = (hostspiflash_phy_cfg1_read() >> TERCEL_SPI_PHY_DUMMY_CYCLES_SHIFT) & TERCEL_SPI_PHY_DUMMY_CYCLES_MASK;
printf("Flash controller frequency configured to %d MHz (bus frequency %d MHz, dummy cycles %d)\n", (hostspiflash_sys_clk_freq_read() / spi_divisor) / 1000000, hostspiflash_sys_clk_freq_read() / 1000000, spi_dummy_cycles);
#if 1
// Enable read merging
hostspiflash_flash_cfg4_write(hostspiflash_flash_cfg4_read() | (TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK << TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT));
hostspiflash_flash_cfg5_write(hostspiflash_flash_cfg5_read() | (TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK << TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT));
// Enable write merging
hostspiflash_flash_cfg4_write(hostspiflash_flash_cfg4_read() | (TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_MASK << TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_SHIFT));
#endif
hostspiflash_flash_cfg5_write(hostspiflash_flash_cfg5_read() | (TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_MASK << TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_SHIFT));
return 0;
}
......@@ -255,12 +233,11 @@ int main(void)
printf("\r[%d/64]", chunk + 1);
// Reset ongoing multibyte access due to die switch requirements on the N25Q Flash devices
hostspiflash_flash_cfg4_write(hostspiflash_flash_cfg4_read() & ~(TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK << TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT));
hostspiflash_flash_cfg4_write(hostspiflash_flash_cfg4_read() | (TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK << TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT));
hostspiflash_flash_cfg5_write(hostspiflash_flash_cfg5_read() & ~(TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK << TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT));
hostspiflash_flash_cfg5_write(hostspiflash_flash_cfg5_read() | (TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK << TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT));
}
printf("\r%dMB copied\n", chunk);
#ifdef DEBUG_HOST_SPI_FLASH_READ
printf("host_flash_buffer: %p First 1KB:\n", host_flash_buffer);
int byte = 0;
......
// © 2020 Raptor Engineering, LLC
//
// Released under the terms of the AGPL v3
// See the LICENSE file for full details
#define TERCEL_SPI_ENABLE_USER_MODE_MASK 0x1
#define TERCEL_SPI_ENABLE_USER_MODE_SHIFT 0x0
#define TERCEL_SPI_PHY_DUMMY_CYCLES_MASK 0xff
#define TERCEL_SPI_PHY_DUMMY_CYCLES_SHIFT 8
#define TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK 0xff
#define TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT 0
#define TERCEL_SPI_PHY_IO_TYPE_MASK 0x3
#define TERCEL_SPI_PHY_IO_TYPE_SHIFT 16
#define TERCEL_SPI_PHY_4BA_ENABLE_MASK 0x1
#define TERCEL_SPI_PHY_4BA_ENABLE_SHIFT 18
#define TERCEL_SPI_PHY_FAST_READ_ENABLE_MASK 0x1
#define TERCEL_SPI_PHY_FAST_READ_ENABLE_SHIFT 19
#define TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_MASK 0xff
#define TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_SHIFT 24
#define TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_MASK 0x1
#define TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_SHIFT 1
#define TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK 0x1
#define TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT 0
#define TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_MASK 0xffffffff
#define TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_SHIFT 0
#define TERCEL_SPI_PHY_IO_TYPE_SINGLE 0x0
#define TERCEL_SPI_PHY_IO_TYPE_QUAD 0x2
#define TERCEL_SPI_PHY_3BA_MODE 0x0
#define TERCEL_SPI_PHY_4BA_MODE 0x1
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment