This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push: new 54b71de23a xtensa/esp32s3: Fix some ESP32S3 module reboot and QVL issues 54b71de23a is described below commit 54b71de23a9a8f572ff4f783d008ec1d38127ed1 Author: chen...@espressif.com <chen...@espressif.com> AuthorDate: Tue Oct 24 10:31:30 2023 +0800 xtensa/esp32s3: Fix some ESP32S3 module reboot and QVL issues 1. Increase the data length in timing tuning. 2. Add MSPI Error-Correcting Code function when accessing SPIRAM. 3. Add delay before timing tuning. --- arch/xtensa/src/esp32s3/Kconfig | 8 ++ arch/xtensa/src/esp32s3/esp32s3_psram_octal.c | 113 +++++++++++++++++++++++++- arch/xtensa/src/esp32s3/esp32s3_spi_timing.c | 4 +- arch/xtensa/src/esp32s3/esp32s3_spiram.h | 2 +- 4 files changed, 123 insertions(+), 4 deletions(-) diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig index f4d8faff62..e51a49fb23 100644 --- a/arch/xtensa/src/esp32s3/Kconfig +++ b/arch/xtensa/src/esp32s3/Kconfig @@ -861,6 +861,14 @@ config ESP32S3_SPIRAM_SPEED default 80 if ESP32S3_SPIRAM_SPEED_80M default 40 if ESP32S3_SPIRAM_SPEED_40M +config ESP32S3_SPIRAM_ECC_ENABLE + bool "Enable SPI RAM ECC" + default n + depends on ESP32S3_SPIRAM_MODE_OCT + ---help--- + Enable MSPI Error-Correcting Code function when accessing SPIRAM. + If enabled, 1/16 of the SPI RAM total size will be reserved for error-correcting code. + config ESP32S3_SPIRAM_BOOT_INIT bool "Initialize SPI RAM during startup" depends on ESP32S3_SPIRAM diff --git a/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c b/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c index 652847fbe8..675fa14e44 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c +++ b/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c @@ -37,6 +37,7 @@ #include "hardware/esp32s3_iomux.h" #include "hardware/esp32s3_gpio.h" #include "hardware/esp32s3_gpio_sigmap.h" +#include "hardware/esp32s3_syscon.h" #include "rom/esp32s3_spiflash.h" #include "rom/esp32s3_opi_flash.h" @@ -56,8 +57,12 @@ #define OCT_PSRAM_CS_SETUP_TIME 3 #define OCT_PSRAM_CS_HOLD_TIME 3 +#define OCT_PSRAM_CS_ECC_HOLD_TIME 3 #define OCT_PSRAM_CS_HOLD_DELAY 2 +#define OCT_PSRAM_PAGE_SIZE 2 +#define OCT_PSRAM_ECC_ENABLE_MASK BIT(8) + /**************************************************************************** * Private Types ****************************************************************************/ @@ -151,6 +156,7 @@ struct opi_psram_reg ****************************************************************************/ extern void cache_resume_dcache(uint32_t val); +extern void ets_delay_us(uint32_t us); /**************************************************************************** * Private Data @@ -218,6 +224,37 @@ static void IRAM_ATTR set_psram_reg(int spi_num, NULL, 0, BIT(1), false); + +#if CONFIG_ESP32S3_SPIRAM_ECC_ENABLE + addr = 0x8; + data_bit_len = 8; + esp_rom_opiflash_exec_cmd(spi_num, mode, + OPI_PSRAM_REG_READ, + cmd_len, + addr, + addr_bit_len, + dummy, + NULL, 0, + &psram_reg.mr8.val, + data_bit_len, + BIT(1), + false); + + psram_reg.mr8.bt = in_reg->mr8.bt; + psram_reg.mr8.bl = in_reg->mr8.bl; + + esp_rom_opiflash_exec_cmd(spi_num, mode, + OPI_PSRAM_REG_WRITE, + cmd_len, + addr, + addr_bit_len, + 0, + &psram_reg.mr8.val, + 16, + NULL, 0, + BIT(1), + false); +#endif } /**************************************************************************** @@ -302,6 +339,47 @@ static void IRAM_ATTR get_psram_reg(int spi_num, false); } +/**************************************************************************** + * Name: configure_psram_ecc + * + * Description: + * Enable error correcting code feature, Can add an input parameter for + * selecting ECC mode if needed. + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void IRAM_ATTR configure_psram_ecc(void) +{ +#if CONFIG_ESP32S3_SPIRAM_ECC_ENABLE + /* Clear this bit to use ECC 16to17 mode */ + + CLEAR_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), + SPI_MEM_SPI_SMEM_ECC_16TO18_BYTE_EN_M); + SET_PERI_REG_BITS(SYSCON_SPI_MEM_ECC_CTRL_REG, + SYSCON_SRAM_PAGE_SIZE_V, + OCT_PSRAM_PAGE_SIZE, + SYSCON_SRAM_PAGE_SIZE_S); + SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), + SPI_MEM_SPI_SMEM_ECC_SKIP_PAGE_CORNER_M); + + /* Enable ECC region 0 (ACE0) + * Default: ACE0 range: 0 ~ 256MB + * Current Octal PSRAM is 8MB, ACE0 is enough + */ + + SET_PERI_REG_MASK(SYSCON_SRAM_ACE0_ATTR_REG, OCT_PSRAM_ECC_ENABLE_MASK); + minfo("PSRAM ECC is enabled\n"); +#else + CLEAR_PERI_REG_MASK(SYSCON_SRAM_ACE0_ATTR_REG, OCT_PSRAM_ECC_ENABLE_MASK); +#endif +} + /**************************************************************************** * Name: print_psram_reg * @@ -383,6 +461,12 @@ static void IRAM_ATTR init_cs_timing(void) SPI_MEM_SPI_SMEM_CS_SETUP_TIME_V, OCT_PSRAM_CS_SETUP_TIME, SPI_MEM_SPI_SMEM_CS_SETUP_TIME_S); +#if CONFIG_ESP32S3_SPIRAM_ECC_ENABLE + SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), + SPI_MEM_SPI_SMEM_ECC_CS_HOLD_TIME_V, + OCT_PSRAM_CS_ECC_HOLD_TIME, + SPI_MEM_SPI_SMEM_ECC_CS_HOLD_TIME_S); +#endif /* CS1 high time */ @@ -598,8 +682,10 @@ int IRAM_ATTR psram_enable(int mode, int vaddrmode) psram_reg.mr0.drive_str = 0; set_psram_reg(1, &psram_reg); get_psram_reg(1, &psram_reg); - print_psram_reg(&psram_reg); + /* workaround: some chips are unstable without delay */ + + ets_delay_us(50000); g_psram_size = psram_reg.mr2.density == 0x1 ? PSRAM_SIZE_4MB : psram_reg.mr2.density == 0X3 ? PSRAM_SIZE_8MB : psram_reg.mr2.density == 0x5 ? PSRAM_SIZE_16MB : @@ -611,6 +697,17 @@ int IRAM_ATTR psram_enable(int mode, int vaddrmode) esp32s3_spi_timing_set_mspi_psram_tuning(); + esp32s3_spi_timing_set_mspi_low_speed(true); + + /* Enable ecc after timing tuning */ + + configure_psram_ecc(); + psram_reg.mr8.bl = 3; + psram_reg.mr8.bt = 0; + set_psram_reg(1, &psram_reg); + get_psram_reg(1, &psram_reg); + print_psram_reg(&psram_reg); + /* Back to the high speed mode. Flash/PSRAM clocks are set to the clock * that user selected. SPI0/1 registers are all set correctly. */ @@ -634,6 +731,11 @@ int IRAM_ATTR psram_enable(int mode, int vaddrmode) int psram_get_physical_size(uint32_t *out_size_bytes) { + if (!out_size_bytes) + { + return -EINVAL; + } + *out_size_bytes = g_psram_size; return g_psram_size > 0 ? OK : -EINVAL; } @@ -642,6 +744,15 @@ int psram_get_physical_size(uint32_t *out_size_bytes) int psram_get_available_size(uint32_t *out_size_bytes) { + if (!out_size_bytes) + { + return -EINVAL; + } + +#if CONFIG_ESP32S3_SPIRAM_ECC_ENABLE + *out_size_bytes = g_psram_size * 15 / 16; +#else *out_size_bytes = g_psram_size; +#endif return (g_psram_size ? OK : -EINVAL); } diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi_timing.c b/arch/xtensa/src/esp32s3/esp32s3_spi_timing.c index 47a897b20d..5bcc8aebad 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_spi_timing.c +++ b/arch/xtensa/src/esp32s3/esp32s3_spi_timing.c @@ -171,7 +171,7 @@ #define MSPI_TIMING_FLASH_DTR_MODE CONFIG_ESP32S3_FLASH_SAMPLE_MODE_DTR #define MSPI_TIMING_FLASH_STR_MODE CONFIG_ESP32S3_FLASH_SAMPLE_MODE_STR -#define MSPI_TIMING_TEST_DATA_LEN 64 +#define MSPI_TIMING_TEST_DATA_LEN 1024 #define MSPI_TIMING_PSRAM_TEST_DATA_ADDR 0 #define MSPI_TIMING_FLASH_TEST_DATA_ADDR 0 @@ -1356,7 +1356,7 @@ static void do_tuning(const uint8_t *reference_data, * ****************************************************************************/ -void esp32s3_spi_timing_set_pin_drive_strength(void) +void IRAM_ATTR esp32s3_spi_timing_set_pin_drive_strength(void) { const uint32_t regs[] = { diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiram.h b/arch/xtensa/src/esp32s3/esp32s3_spiram.h index 5af08a0abb..940a339da4 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_spiram.h +++ b/arch/xtensa/src/esp32s3/esp32s3_spiram.h @@ -76,7 +76,7 @@ int esp_spiram_add_to_heapalloc(void); * @brief Get the available physical size of the attached SPI RAM chip * * @note If ECC is enabled, the available physical size would be smaller - * than the physical size. See `CONFIG_SPIRAM_ECC_ENABLE` + * than the physical size. See `CONFIG_ESP32S3_SPIRAM_ECC_ENABLE` * * @return Size in bytes, or 0 if no external RAM chip support compiled in. */