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: [email protected] <[email protected]>
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.
*/