diff --git a/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/index.rst b/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/index.rst index d20a113aff1..fff945e0573 100644 --- a/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/index.rst +++ b/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/index.rst @@ -162,6 +162,38 @@ To test it, just run the ``oneshot`` example:: Waiting... Finished +psram_quad +---------- + +This config tests the PSRAM driver over SPIRAM interface in quad mode. +You can use the mm command to test the PSRAM memory:: + + nsh> mm + mallinfo: + Total space allocated from system = 8803232 + Number of non-inuse chunks = 2 + Largest non-inuse chunk = 8388592 + Total allocated space = 9672 + Total non-inuse space = 8793560 + (0)Allocating 5011 bytes + + ...... + + (31)Releasing memory at 0x3fc8c088 (size=24 bytes) + mallinfo: + Total space allocated from system = 8803232 + Number of non-inuse chunks = 2 + Largest non-inuse chunk = 8388592 + Total allocated space = 9672 + Total non-inuse space = 8793560 + TEST COMPLETE + +psram_octal +----------- + +Similar to the ```psram_quad``` configuration but using the SPIRAM +interface in octal mode. + pwm --- diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig index 243569c1734..cd2ca8a442d 100644 --- a/arch/xtensa/src/esp32s3/Kconfig +++ b/arch/xtensa/src/esp32s3/Kconfig @@ -531,6 +531,7 @@ config ESP32S3_SPIRAM_SPEED_80M config ESP32S3_SPIRAM_SPEED_120M bool "120MHz clock speed" + depends on ESP32S3_SPIRAM_MODE_QUAD endchoice # ESP32S3_SPIRAM_SPEED @@ -1017,6 +1018,9 @@ choice ESP32S3_FLASH_MODE config ESP32S3_FLASH_MODE_QOUT bool "Quad Output (QOUT)" + config ESP32S3_FLASH_MODE_OCT + bool "Octal" + endchoice # ESP32S3_FLASH_MODE choice ESP32S3_FLASH_FREQ @@ -1039,6 +1043,25 @@ choice ESP32S3_FLASH_FREQ endchoice # ESP32S3_FLASH_FREQ +config ESP32S3_FLASH_FREQ + int + default 120 if ESP32S3_FLASH_FREQ_120M + default 80 if ESP32S3_FLASH_FREQ_80M + default 40 if ESP32S3_FLASH_FREQ_40M + default 20 if ESP32S3_FLASH_FREQ_20M + +choice ESP32S3_FLASH_SAMPLE_MODE + prompt "Flash Sampling Mode" + default ESP32S3_FLASH_SAMPLE_MODE_DTR if ESP32S3_FLASH_MODE_OCT + default ESP32S3_FLASH_SAMPLE_MODE_STR if !ESP32S3_FLASH_MODE_OCT + + config ESP32S3_FLASH_SAMPLE_MODE_DTR + depends on ESP32S3_FLASH_MODE_OCT + bool "DTR Mode" + config ESP32S3_FLASH_SAMPLE_MODE_STR + bool "STR Mode" +endchoice + config ESP32S3_HAVE_OTA_PARTITION bool default n diff --git a/arch/xtensa/src/esp32s3/Make.defs b/arch/xtensa/src/esp32s3/Make.defs index d8001b8ee8b..2c2b20b5793 100644 --- a/arch/xtensa/src/esp32s3/Make.defs +++ b/arch/xtensa/src/esp32s3/Make.defs @@ -30,7 +30,7 @@ HEAD_CSRC = esp32s3_start.c CHIP_CSRCS = esp32s3_irq.c esp32s3_clockconfig.c esp32s3_region.c CHIP_CSRCS += esp32s3_systemreset.c esp32s3_user.c esp32s3_allocateheap.c CHIP_CSRCS += esp32s3_wdt.c esp32s3_gpio.c esp32s3_lowputc.c esp32s3_serial.c -CHIP_CSRCS += esp32s3_rtc_gpio.c esp32s3_libc_stubs.c +CHIP_CSRCS += esp32s3_rtc_gpio.c esp32s3_libc_stubs.c esp32s3_spi_timing.c # Configuration-dependent ESP32-S3 files @@ -118,7 +118,14 @@ endif ifeq ($(CONFIG_ESP32S3_SPIRAM),y) CHIP_CSRCS += esp32s3_spiram.c -CHIP_CSRCS += esp32s3_psram.c + +ifeq ($(CONFIG_ESP32S3_SPIRAM_MODE_QUAD),y) +CHIP_CSRCS += esp32s3_psram_quad.c +endif + +ifeq ($(CONFIG_ESP32S3_SPIRAM_MODE_OCT),y) +CHIP_CSRCS += esp32s3_psram_octal.c +endif endif ifeq ($(CONFIG_ESP32S3_TOUCH),y) diff --git a/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c b/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c index e0639a1fae5..b8d7f48846f 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c +++ b/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c @@ -38,6 +38,9 @@ #include "xtensa.h" #include "hardware/esp32s3_rom_layout.h" +#ifdef CONFIG_ESP32S3_SPIRAM +# include "esp32s3_spiram.h" +#endif /**************************************************************************** * Pre-processor Definitions @@ -154,5 +157,14 @@ void up_allocate_kheap(void **heap_start, size_t *heap_size) #if CONFIG_MM_REGIONS > 1 void xtensa_add_region(void) { +#ifdef CONFIG_ESP32S3_SPIRAM + void *start; + size_t size; + + start = (void *)esp_spiram_allocable_vaddr_start(); + size = (size_t)(esp_spiram_allocable_vaddr_end() - + esp_spiram_allocable_vaddr_start()); + umm_addregion(start, size); +#endif } #endif diff --git a/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c b/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c new file mode 100644 index 00000000000..cc9d575272f --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c @@ -0,0 +1,647 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_psram_octal.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "xtensa.h" + +#include "esp32s3_gpio.h" +#include "esp32s3_psram.h" +#include "esp32s3_spi_timing.h" + +#include "hardware/esp32s3_spi_mem_reg.h" +#include "hardware/esp32s3_iomux.h" +#include "hardware/esp32s3_gpio.h" +#include "hardware/esp32s3_gpio_sigmap.h" +#include "rom/esp32s3_spiflash.h" +#include "rom/esp32s3_opi_flash.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define OPI_PSRAM_SYNC_READ 0x0000 +#define OPI_PSRAM_SYNC_WRITE 0x8080 +#define OPI_PSRAM_REG_READ 0x4040 +#define OPI_PSRAM_REG_WRITE 0xC0C0 +#define OCT_PSRAM_RD_CMD_BITLEN 16 +#define OCT_PSRAM_WR_CMD_BITLEN 16 +#define OCT_PSRAM_ADDR_BITLEN 32 +#define OCT_PSRAM_RD_DUMMY_BITLEN (2 * (10 - 1)) +#define OCT_PSRAM_WR_DUMMY_BITLEN (2 * (5 - 1)) + +#define OCT_PSRAM_CS_SETUP_TIME 3 +#define OCT_PSRAM_CS_HOLD_TIME 3 +#define OCT_PSRAM_CS_HOLD_DELAY 2 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct opi_psram_reg +{ + union mr0_u + { + struct + { + uint8_t drive_str: 2; + uint8_t read_latency: 3; + uint8_t lt: 1; + uint8_t rsvd0_1: 2; + }; + + uint8_t val; + } + mr0; + + union mr1_u + { + struct + { + uint8_t vendor_id: 5; + uint8_t rsvd0_2: 3; + }; + + uint8_t val; + } + mr1; + + union mr2_u + { + struct + { + uint8_t density: 3; + uint8_t dev_id: 2; + uint8_t rsvd1_2: 2; + uint8_t gb: 1; + }; + + uint8_t val; + } + mr2; + + union mr3_u + { + struct + { + uint8_t rsvd3_7: 5; + uint8_t srf: 1; + uint8_t vcc: 1; + uint8_t rsvd0: 1; + }; + + uint8_t val; + } + mr3; + + union mr4_u + { + struct + { + uint8_t pasr: 3; + uint8_t rf: 1; + uint8_t rsvd3: 1; + uint8_t wr_latency: 3; + }; + + uint8_t val; + } + mr4; + + union mr8_u + { + struct + { + uint8_t bl: 2; + uint8_t bt: 1; + uint8_t rsvd0_4: 5; + }; + + uint8_t val; + } + mr8; +}; + +/**************************************************************************** + * ROM Function Prototypes + ****************************************************************************/ + +extern void cache_resume_dcache(uint32_t val); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static size_t g_psram_size; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: set_psram_reg + * + * Description: + * Set PSRAM registers' value + * + * Input Parameters: + * spi_num - SPI port + * in_reg - PSRAM registers' value + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void set_psram_reg(int spi_num, const struct opi_psram_reg *in_reg) +{ + esp_rom_spiflash_read_mode_t mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE; + int cmd_len = 16; + uint32_t addr = 0x0; + int addr_bit_len = 32; + int dummy = OCT_PSRAM_RD_DUMMY_BITLEN; + int data_bit_len = 16; + struct opi_psram_reg psram_reg = + { + 0 + }; + + esp_rom_opiflash_exec_cmd(spi_num, mode, + OPI_PSRAM_REG_READ, + cmd_len, + addr, + addr_bit_len, + dummy, + NULL, 0, + &psram_reg.mr0.val, + data_bit_len, + BIT(1), + false); + + psram_reg.mr0.lt = in_reg->mr0.lt; + psram_reg.mr0.read_latency = in_reg->mr0.read_latency; + psram_reg.mr0.drive_str = in_reg->mr0.drive_str; + + esp_rom_opiflash_exec_cmd(spi_num, mode, + OPI_PSRAM_REG_WRITE, + cmd_len, + addr, + addr_bit_len, + 0, + &psram_reg.mr0.val, + 16, + NULL, 0, + BIT(1), + false); +} + +/**************************************************************************** + * Name: get_psram_reg + * + * Description: + * Get PSRAM registers' value + * + * Input Parameters: + * spi_num - SPI port + * out_reg - PSRAM registers' value + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void get_psram_reg(int spi_num, struct opi_psram_reg *out_reg) +{ + esp_rom_spiflash_read_mode_t mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE; + int cmd_len = 16; + int addr_bit_len = 32; + int dummy = OCT_PSRAM_RD_DUMMY_BITLEN; + int data_bit_len = 16; + + /** Read MR0~1 register */ + + esp_rom_opiflash_exec_cmd(spi_num, mode, + OPI_PSRAM_REG_READ, + cmd_len, + 0x0, + addr_bit_len, + dummy, + NULL, 0, + &out_reg->mr0.val, + data_bit_len, + BIT(1), + false); + + /** Read MR2~3 register */ + + esp_rom_opiflash_exec_cmd(spi_num, mode, + OPI_PSRAM_REG_READ, + cmd_len, + 0x2, + addr_bit_len, + dummy, + NULL, 0, + &out_reg->mr2.val, + data_bit_len, + BIT(1), + false); + + /** Read MR4 register */ + + data_bit_len = 8; + esp_rom_opiflash_exec_cmd(spi_num, mode, + OPI_PSRAM_REG_READ, + cmd_len, + 0x4, + addr_bit_len, + dummy, + NULL, 0, + &out_reg->mr4.val, + data_bit_len, + BIT(1), + false); + + /** Read MR8 register */ + + esp_rom_opiflash_exec_cmd(spi_num, mode, + OPI_PSRAM_REG_READ, + cmd_len, + 0x8, + addr_bit_len, + dummy, + NULL, 0, + &out_reg->mr8.val, + data_bit_len, + BIT(1), + false); +} + +/**************************************************************************** + * Name: print_psram_reg + * + * Description: + * Print PSRAM information. + * + * Input Parameters: + * psram_reg - PSRAM registers' value + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void print_psram_reg(const struct opi_psram_reg *psram_reg) +{ + minfo("vendor id : 0x%02x (%s)\n", psram_reg->mr1.vendor_id, + psram_reg->mr1.vendor_id == 0x0d ? "AP" : "UNKNOWN"); + minfo("dev id : 0x%02x (generation %d)\n", psram_reg->mr2.dev_id, + psram_reg->mr2.dev_id + 1); + minfo("density : 0x%02x (%d Mbit)\n", psram_reg->mr2.density, + psram_reg->mr2.density == 0x1 ? 32 : + psram_reg->mr2.density == 0X3 ? 64 : + psram_reg->mr2.density == 0x5 ? 128 : + psram_reg->mr2.density == 0x7 ? 256 : 0); + minfo("good-die : 0x%02x (%s)\n", psram_reg->mr2.gb, + psram_reg->mr2.gb == 1 ? "Pass" : "Fail"); + minfo("Latency : 0x%02x (%s)\n", psram_reg->mr0.lt, + psram_reg->mr0.lt == 1 ? "Fixed" : "Variable"); + minfo("VCC : 0x%02x (%s)\n", psram_reg->mr3.vcc, + psram_reg->mr3.vcc == 1 ? "3V" : "1.8V"); + minfo("SRF : 0x%02x (%s Refresh)\n", psram_reg->mr3.srf, + psram_reg->mr3.srf == 0x1 ? "Fast" : "Slow"); + minfo("BurstType : 0x%02x (%s Wrap)\n", psram_reg->mr8.bt, + psram_reg->mr8.bt == 1 && psram_reg->mr8.bl != 3 ? "Hybrid" : ""); + minfo("BurstLen : 0x%02x (%d Byte)\n", psram_reg->mr8.bl, + psram_reg->mr8.bl == 0x00 ? 16 : + psram_reg->mr8.bl == 0x01 ? 32 : + psram_reg->mr8.bl == 0x10 ? 64 : 1024); + minfo("Readlatency : 0x%02x (%d cycles@%s)\n", + psram_reg->mr0.read_latency, + psram_reg->mr0.read_latency * 2 + 6, + psram_reg->mr0.lt == 1 ? "Fixed" : "Variable"); + minfo("DriveStrength: 0x%02x (1/%d)\n", psram_reg->mr0.drive_str, + psram_reg->mr0.drive_str == 0x00 ? 1 : + psram_reg->mr0.drive_str == 0x01 ? 2 : + psram_reg->mr0.drive_str == 0x02 ? 4 : 8); +} + +/**************************************************************************** + * Name: init_cs_timing + * + * Description: + * Initialize SPI CS timing. + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void init_cs_timing(void) +{ + /** + * SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, + * cs_hold_delay registers for PSRAM, so we only need to set SPI0 + * related registers here. + */ + + SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), + SPI_MEM_SPI_SMEM_CS_HOLD_M | + SPI_MEM_SPI_SMEM_CS_SETUP_M); + SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), + SPI_MEM_SPI_SMEM_CS_HOLD_TIME_V, + OCT_PSRAM_CS_HOLD_TIME, + SPI_MEM_SPI_SMEM_CS_HOLD_TIME_S); + SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), + SPI_MEM_SPI_SMEM_CS_SETUP_TIME_V, + OCT_PSRAM_CS_SETUP_TIME, + SPI_MEM_SPI_SMEM_CS_SETUP_TIME_S); + + /** CS1 high time */ + + SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), + SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_V, + OCT_PSRAM_CS_HOLD_DELAY, + SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_S); +} + +/**************************************************************************** + * Name: init_psram_pins + * + * Description: + * Initialize PSRAM pins. + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void init_psram_pins(void) +{ + uint32_t reg = REG_IO_MUX_BASE + + (CONFIG_ESP32S3_DEFAULT_PSRAM_CS_IO + 1) * 4; + + PIN_FUNC_SELECT(reg, FUNC_SPICS1_SPICS1); + PIN_SET_DRV(reg, 3); + REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, 3); +} + +/**************************************************************************** + * Name: config_psram_spi_phases + * + * Description: + * Configure PSRAM SPI0 phase related registers here according to + * the PSRAM chip requirement. + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void config_psram_spi_phases(void) +{ + /** Config Write CMD phase for SPI0 to access PSRAM */ + + SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), + SPI_MEM_CACHE_SRAM_USR_WCMD_M); + SET_PERI_REG_BITS(SPI_MEM_SRAM_DWR_CMD_REG(0), + SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN, + OCT_PSRAM_WR_CMD_BITLEN - 1, + SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN_S); + SET_PERI_REG_BITS(SPI_MEM_SRAM_DWR_CMD_REG(0), + SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE, + OPI_PSRAM_SYNC_WRITE, + SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE_S); + + /** Config Read CMD phase for SPI0 to access PSRAM */ + + SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), + SPI_MEM_CACHE_SRAM_USR_RCMD_M); + SET_PERI_REG_BITS(SPI_MEM_SRAM_DRD_CMD_REG(0), + SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_V, + OCT_PSRAM_RD_CMD_BITLEN - 1, + SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_S); + SET_PERI_REG_BITS(SPI_MEM_SRAM_DRD_CMD_REG(0), + SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_V, + OPI_PSRAM_SYNC_READ, + SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_S); + + /** Config ADDR phase */ + + SET_PERI_REG_BITS(SPI_MEM_CACHE_SCTRL_REG(0), + SPI_MEM_SRAM_ADDR_BITLEN_V, + OCT_PSRAM_ADDR_BITLEN - 1, + SPI_MEM_SRAM_ADDR_BITLEN_S); + SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), + SPI_MEM_CACHE_USR_SCMD_4BYTE_M); + + /** Config RD/WR Dummy phase */ + + SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), + SPI_MEM_USR_RD_SRAM_DUMMY_M | + SPI_MEM_USR_WR_SRAM_DUMMY_M); + SET_PERI_REG_BITS(SPI_MEM_CACHE_SCTRL_REG(0), + SPI_MEM_SRAM_RDUMMY_CYCLELEN_V, + OCT_PSRAM_RD_DUMMY_BITLEN - 1, + SPI_MEM_SRAM_RDUMMY_CYCLELEN_S); + SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_DDR_REG(0), + SPI_MEM_SPI_SMEM_VAR_DUMMY_M); + SET_PERI_REG_BITS(SPI_MEM_CACHE_SCTRL_REG(0), + SPI_MEM_SRAM_WDUMMY_CYCLELEN_V, + OCT_PSRAM_WR_DUMMY_BITLEN - 1, + SPI_MEM_SRAM_WDUMMY_CYCLELEN_S); + + CLEAR_PERI_REG_MASK(SPI_MEM_SPI_SMEM_DDR_REG(0), + SPI_MEM_SPI_SMEM_DDR_WDAT_SWP_M | + SPI_MEM_SPI_SMEM_DDR_RDAT_SWP_M); + SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_DDR_REG(0), + SPI_MEM_SPI_SMEM_DDR_EN_M); + + SET_PERI_REG_MASK(SPI_MEM_SRAM_CMD_REG(0), + SPI_MEM_SDUMMY_OUT_M | + SPI_MEM_SCMD_OCT_M | + SPI_MEM_SADDR_OCT_M | + SPI_MEM_SDOUT_OCT_M | + SPI_MEM_SDIN_OCT_M); + SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), + SPI_MEM_SRAM_OCT_M); + + cache_resume_dcache(0); +} + +/**************************************************************************** + * Name: spi_flash_set_rom_required_regs + * + * Description: + * Set flash ROM required register. + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void spi_flash_set_rom_required_regs(void) +{ +#ifdef CONFIG_ESP32S3_FLASH_MODE_OCT + /** + * Disable the variable dummy mode when doing timing tuning. + * + * STR /DTR mode setting is done every time when + * "esp_rom_opiflash_exec_cmd" is called. + * + * Add any registers that are not set in ROM SPI flash functions here + * in the future. + */ + + CLEAR_PERI_REG_MASK(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY); +#endif +} + +/**************************************************************************** + * Name: flash_set_vendor_required_regs + * + * Description: + * Set flash vendor required register. + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void flash_set_vendor_required_regs(void) +{ +#ifdef CONFIG_ESP32S3_FLASH_MODE_OCT + /** + * Set MSPI specifical configuration, + * "esp32s3_bsp_opiflash_set_required_regs" is board defined function. + */ + + esp32s3_bsp_opiflash_set_required_regs(); + + SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1), + SPI_MEM_CACHE_USR_CMD_4BYTE_V, + 1, + SPI_MEM_CACHE_USR_CMD_4BYTE_S); +#else + /** Restore MSPI registers after Octal PSRAM initialization. */ + + SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1), + SPI_MEM_CACHE_USR_CMD_4BYTE_V, + 0, + SPI_MEM_CACHE_USR_CMD_4BYTE_S); +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int IRAM_ATTR psram_enable(int mode, int vaddrmode) +{ + struct opi_psram_reg psram_reg = + { + 0 + }; + + init_psram_pins(); + init_cs_timing(); + + /** enter MSPI slow mode to init PSRAM device registers */ + + esp32s3_spi_timing_set_mspi_low_speed(true); + + /** set to variable dummy mode */ + + SET_PERI_REG_MASK(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY); + esp_rom_spi_set_dtr_swap_mode(1, false, false); + + /** Set PSRAM read latency and drive strength */ + + psram_reg.mr0.lt = 1; + psram_reg.mr0.read_latency = 2; + psram_reg.mr0.drive_str = 0; + set_psram_reg(1, &psram_reg); + get_psram_reg(1, &psram_reg); + print_psram_reg(&psram_reg); + + 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 : + psram_reg.mr2.density == 0x7 ? PSRAM_SIZE_32MB : 0; + + /* Back to the high speed mode. Flash/PSRAM clocks are set to the clock + * that user selected. SPI0/1 registers are all set correctly. + */ + + esp32s3_spi_timing_set_mspi_high_speed(true); + + /** + * Tuning may change SPI1 regs, whereas legacy spi_flash APIs rely on + * these regs. This function is to restore SPI1 init state. + */ + + spi_flash_set_rom_required_regs(); + + /** + * Flash chip requires MSPI specifically, call this function to set them + */ + + flash_set_vendor_required_regs(); + + config_psram_spi_phases(); + + return 0; +} + +int psram_get_physical_size(uint32_t *out_size_bytes) +{ + *out_size_bytes = g_psram_size; + return g_psram_size > 0 ? OK : -EINVAL; +} + +/* This function is to get the available physical psram size in bytes. + */ + +int psram_get_available_size(uint32_t *out_size_bytes) +{ + *out_size_bytes = g_psram_size; + return (g_psram_size ? OK : -EINVAL); +} diff --git a/arch/xtensa/src/esp32s3/esp32s3_psram.c b/arch/xtensa/src/esp32s3/esp32s3_psram_quad.c similarity index 99% rename from arch/xtensa/src/esp32s3/esp32s3_psram.c rename to arch/xtensa/src/esp32s3/esp32s3_psram_quad.c index 6a4effc162c..f45c5968b03 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_psram.c +++ b/arch/xtensa/src/esp32s3/esp32s3_psram_quad.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/xtensa/src/esp32s3/esp32s3_psram.c + * arch/xtensa/src/esp32s3/esp32s3_psram_quad.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi_timing.c b/arch/xtensa/src/esp32s3/esp32s3_spi_timing.c new file mode 100644 index 00000000000..321e4f1051a --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_spi_timing.c @@ -0,0 +1,366 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_spi_timing.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "xtensa.h" +#include "esp32s3_gpio.h" +#include "esp32s3_psram.h" +#include "esp32s3_spi_timing.h" +#include "hardware/esp32s3_spi_mem_reg.h" +#include "hardware/esp32s3_iomux.h" +#include "hardware/esp32s3_gpio.h" +#include "hardware/esp32s3_gpio_sigmap.h" +#include "rom/esp32s3_spiflash.h" +#include "rom/esp32s3_opi_flash.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CORE_CLK_REG_SEL_80M 0 +#define CORE_CLK_REG_SEL_120M 1 +#define CORE_CLK_REG_SEL_160M 2 +#define CORE_CLK_REG_SEL_240M 3 + +#if defined(CONFIG_ESP32S3_FLASH_SAMPLE_MODE_DTR) || \ + defined(CONFIG_ESP32S3_SPIRAM_MODE_OCT) +# define ESP32S3_SPI_TIMING_CORE_CLOCK_DIV 2 +#else +# define ESP32S3_SPI_TIMING_CORE_CLOCK_DIV 1 +#endif + +#if defined(CONFIG_ESP32S3_FLASH_SAMPLE_MODE_DTR) +# if defined(CONFIG_ESP32S3_FLASH_FREQ_80M) +# define ESP32S3_SPI_TIMING_FLASH_CORE_CLK 160 +# elif defined(CONFIG_ESP32S3_FLASH_FREQ_120M) +# define ESP32S3_SPI_TIMING_FLASH_CORE_CLK 240 +# endif +#elif defined(CONFIG_ESP32S3_FLASH_SAMPLE_MODE_STR) +# if defined(CONFIG_ESP32S3_FLASH_FREQ_120M) +# if ESP32S3_SPI_TIMING_CORE_CLOCK_DIV == 1 +# define ESP32S3_SPI_TIMING_FLASH_CORE_CLK 120 +# elif ESP32S3_SPI_TIMING_CORE_CLOCK_DIV == 2 +# define ESP32S3_SPI_TIMING_FLASH_CORE_CLK 240 +# endif +# endif +#endif + +#if defined(CONFIG_ESP32S3_SPIRAM_MODE_OCT) +# if defined(CONFIG_ESP32S3_SPIRAM_SPEED_80M) +# define ESP32S3_SPI_TIMING_PSRAM_CORE_CLK 160 +# endif +#elif defined(ESP32S3_SPI_TIMING_PSRAM_STR_MODE) +# if defined(CONFIG_ESP32S3_SPIRAM_SPEED_120M) +# if ESP32S3_SPI_TIMING_CORE_CLOCK_DIV == 1 +# define ESP32S3_SPI_TIMING_PSRAM_CORE_CLK 120 +# elif ESP32S3_SPI_TIMING_CORE_CLOCK_DIV == 2 +# define ESP32S3_SPI_TIMING_PSRAM_CORE_CLK 240 +# endif +# endif +#endif + +#if ESP32S3_SPI_TIMING_FLASH_TUNING +# if ESP32S3_SPI_TIMING_PSRAM_TUNING +# if ESP32S3_SPI_TIMING_FLASH_CORE_CLK != ESP32S3_SPI_TIMING_PSRAM_CORE_CLK +# error "FLASH and PSRAM Mode configuration are not supported" +# endif +# define ESP32S3_SPI_TIMING_CORE_CLK ESP32S3_SPI_TIMING_FLASH_CORE_CLK +# else +# if ESP32S3_SPI_TIMING_FLASH_CORE_CLK % ESP32S3_SPI_TIMING_PSRAM_CLOCK != 0 +# error "FLASH and PSRAM Mode configuration are not supported" +# endif +# define ESP32S3_SPI_TIMING_CORE_CLK ESP32S3_SPI_TIMING_FLASH_CORE_CLK +# endif +#else +# if ESP32S3_SPI_TIMING_PSRAM_TUNING +# if ESP32S3_SPI_TIMING_PSRAM_CORE_CLK % ESP32S3_SPI_TIMING_FLASH_CLOCK != 0 +# error "FLASH and PSRAM Mode configuration are not supported" +# endif +# define ESP32S3_SPI_TIMING_CORE_CLK ESP32S3_SPI_TIMING_PSRAM_CORE_CLK +# else +# define ESP32S3_SPI_TIMING_CORE_CLK 80 +# endif +#endif + +#define ESP32S3_CHECK_POWER_OF_2(n) ((((n) & ((~(n)) + 1))) == (n)) + +#ifdef CONFIG_ESP32S3_FLASH_SAMPLE_MODE_DTR +# if ESP32S3_CHECK_POWER_OF_2(ESP32S3_SPI_TIMING_CORE_CLK / ESP32S3_SPI_TIMING_FLASH_CLOCK) == 0 +# error "FLASH and PSRAM Mode configuration are not supported" +# endif +#endif + +#ifdef CONFIG_ESP32S3_SPIRAM_MODE_OCT +# if ESP32S3_CHECK_POWER_OF_2(ESP32S3_SPI_TIMING_CORE_CLK / ESP32S3_SPI_TIMING_PSRAM_CLOCK) == 0 +# error "FLASH and PSRAM Mode configuration are not supported" +# endif +#endif + +#if ESP32S3_SPI_TIMING_CORE_CLK == 80 +# define DEFAULT_CORE_CLOCK CORE_CLOCK_80M +# define DEFAULT_CORE_CLK_REG CORE_CLK_REG_SEL_80M +#elif ESP32S3_SPI_TIMING_CORE_CLK == 120 +# define DEFAULT_CORE_CLOCK CORE_CLOCK_120M +# define DEFAULT_CORE_CLK_REG CORE_CLK_REG_SEL_120M +#elif ESP32S3_SPI_TIMING_CORE_CLK == 160 +# define DEFAULT_CORE_CLOCK CORE_CLOCK_160M +# define DEFAULT_CORE_CLK_REG CORE_CLK_REG_SEL_160M +#elif ESP32S3_SPI_TIMING_CORE_CLK == 240 +# define DEFAULT_CORE_CLOCK CORE_CLOCK_240M +# define DEFAULT_CORE_CLK_REG CORE_CLK_REG_SEL_240M +#else +# error "SPI timing core clock is invalid" +#endif + +#if defined(CONFIG_ESP32S3_FLASH_FREQ_20M) +# define FLASH_CLOCK_DIVIDER (ESP32S3_SPI_TIMING_CORE_CLK / 20) +#elif defined(CONFIG_ESP32S3_FLASH_FREQ_40M) +# define FLASH_CLOCK_DIVIDER (ESP32S3_SPI_TIMING_CORE_CLK / 40) +#elif defined(CONFIG_ESP32S3_FLASH_FREQ_80M) +# define FLASH_CLOCK_DIVIDER (ESP32S3_SPI_TIMING_CORE_CLK / 80) +#elif defined(CONFIG_ESP32S3_FLASH_FREQ_120M) +# define FLASH_CLOCK_DIVIDER (ESP32S3_SPI_TIMING_CORE_CLK / 120) +#else +# error "SPI timing flash clock is invalid" +#endif + +#if defined(CONFIG_ESP32S3_SPIRAM_SPEED_40M) +# define PSRAM_CLOCK_DIVIDER (ESP32S3_SPI_TIMING_CORE_CLK / 40) +#elif defined(CONFIG_ESP32S3_SPIRAM_SPEED_80M) +# define PSRAM_CLOCK_DIVIDER (ESP32S3_SPI_TIMING_CORE_CLK / 80) +#elif defined(CONFIG_ESP32S3_SPIRAM_SPEED_120M) +# define PSRAM_CLOCK_DIVIDER (ESP32S3_SPI_TIMING_CORE_CLK / 120) +#else +# define PSRAM_CLOCK_DIVIDER 0 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum core_clock_e +{ + CORE_CLOCK_80M = 0, + CORE_CLOCK_120M = 1, + CORE_CLOCK_160M = 2, + CORE_CLOCK_240M = 3 +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: set_psram_clock + * + * Description: + * Set PSRAM clock. + * + * Input Parameters: + * spi_num - SPI port + * freqdiv - SPI clock divideor + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void set_psram_clock(uint8_t spi_num, uint32_t freqdiv) +{ + if (freqdiv == 1) + { + WRITE_PERI_REG(SPI_MEM_SRAM_CLK_REG(spi_num), SPI_MEM_SCLK_EQU_SYSCLK); + } + else + { + uint32_t freqbits = ((freqdiv - 1) << SPI_MEM_SCLKCNT_N_S) | + ((freqdiv / 2 - 1) << SPI_MEM_SCLKCNT_H_S) | + ((freqdiv - 1) << SPI_MEM_SCLKCNT_L_S); + + WRITE_PERI_REG(SPI_MEM_SRAM_CLK_REG(spi_num), freqbits); + } +} + +/**************************************************************************** + * Name: set_flash_clock + * + * Description: + * Set flash clock. + * + * Input Parameters: + * spi_num - SPI port + * freqdiv - SPI clock divideor + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void IRAM_ATTR set_flash_clock(uint8_t spi_num, uint32_t freqdiv) +{ + DEBUGASSERT(freqdiv > 0); + + if (freqdiv == 1) + { + WRITE_PERI_REG(SPI_MEM_CLOCK_REG(spi_num), SPI_MEM_CLK_EQU_SYSCLK); + } + else + { + uint32_t freqbits = ((freqdiv - 1) << SPI_MEM_CLKCNT_N_S) | + ((freqdiv / 2 - 1) << SPI_MEM_CLKCNT_H_S) | + ((freqdiv - 1) << SPI_MEM_CLKCNT_L_S); + + WRITE_PERI_REG(SPI_MEM_CLOCK_REG(spi_num), freqbits); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_spi_timing_set_pin_drive_strength + * + * Description: + * Make SPI all GPIO strength to be 3 under default clock. + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32s3_spi_timing_set_pin_drive_strength(void) +{ + const uint32_t regs[] = + { + IO_MUX_GPIO27_REG, + IO_MUX_GPIO28_REG, + IO_MUX_GPIO31_REG, + IO_MUX_GPIO32_REG, + IO_MUX_GPIO33_REG, + IO_MUX_GPIO34_REG, + IO_MUX_GPIO35_REG, + IO_MUX_GPIO36_REG, + IO_MUX_GPIO37_REG + }; + + /* Set default clock */ + + SET_PERI_REG_MASK(SPI_MEM_DATE_REG(0), SPI_MEM_SPICLK_PAD_DRV_CTL_EN); + REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, 3); + REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_FMEM_SPICLK_FUN_DRV, 3); + + /* Set default mspi d0 ~ d7, dqs pin drive strength */ + + for (int i = 0; i < nitems(regs); i++) + { + PIN_SET_DRV(regs[i], 3); + } +} + +/**************************************************************************** + * Name: esp32s3_spi_timing_set_mspi_high_speed + * + * Description: + * Make MSPI work under the frequency as users set, may add certain + * delays to MSPI RX direction to meet timing requirements. + * + * Input Parameters: + * spi1 - Select whether to control SPI1 + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void IRAM_ATTR esp32s3_spi_timing_set_mspi_high_speed(bool spi1) +{ + uint32_t flash_div = FLASH_CLOCK_DIVIDER; + uint32_t psram_div = PSRAM_CLOCK_DIVIDER; + + /* Set SPI0 & 1 core clock */ + + REG_SET_FIELD(SPI_MEM_CORE_CLK_SEL_REG(0), + SPI_MEM_CORE_CLK_SEL, + DEFAULT_CORE_CLK_REG); + + set_flash_clock(0, flash_div); + if (spi1) + { + set_flash_clock(1, flash_div); + } + + set_psram_clock(0, psram_div); +} + +/**************************************************************************** + * Name: esp32s3_spi_timing_set_mspi_low_speed + * + * Description: + * Make MSPI work under 20MHz and remove the timing tuning required delays. + * + * Input Parameters: + * spi1 - Select whether to control SPI1 + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void IRAM_ATTR esp32s3_spi_timing_set_mspi_low_speed(bool spi1) +{ + /** + * Here we are going to set the SPI1 frequency to be 20MHz, + * so we need to set SPI1 din_num and din_mode regs. + * + * Because SPI0 and SPI1 share the din_num and din_mode regs, + * but if we clear SPI1 din_num and din_mode to 0 and SPI0 flash + * module clock is still in high freq, it may not work correctly. + * + * Therefore, we need to set both the SPI0 and SPI1 and related + * timing tuning regs to be 20MHz. + */ + + /* Set SPIMEM core clock as 80MHz, and set SPI1 and SPI0 clock + * to be 20MHz by setting clock division as 4 + */ + + REG_SET_FIELD(SPI_MEM_CORE_CLK_SEL_REG(0), + SPI_MEM_CORE_CLK_SEL, + CORE_CLK_REG_SEL_80M); + + set_flash_clock(0, 4); + if (spi1) + { + /* After tuning, won't touch SPI1 again */ + + set_flash_clock(1, 4); + } +} diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi_timing.h b/arch/xtensa/src/esp32s3/esp32s3_spi_timing.h new file mode 100644 index 00000000000..1e5f67e1187 --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_spi_timing.h @@ -0,0 +1,170 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_spi_timing.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_SPI_TIMING_H +#define __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_SPI_TIMING_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_ESP32S3_FLASH_FREQ_20M) +# define ESP32S3_SPI_TIMING_FLASH_CLOCK 20 +#elif defined(CONFIG_ESP32S3_FLASH_FREQ_40M) +# define ESP32S3_SPI_TIMING_FLASH_CLOCK 40 +#elif defined(CONFIG_ESP32S3_FLASH_FREQ_80M) +# define ESP32S3_SPI_TIMING_FLASH_CLOCK 80 +#elif defined(CONFIG_ESP32S3_FLASH_FREQ_120M) +# define ESP32S3_SPI_TIMING_FLASH_CLOCK 120 +#endif + +#if defined(CONFIG_ESP32S3_FLASH_SAMPLE_MODE_DTR) +# if ESP32S3_SPI_TIMING_FLASH_CLOCK > 40 +# define ESP32S3_SPI_TIMING_FLASH_TUNING 1 +# else +# define ESP32S3_SPI_TIMING_FLASH_TUNING 0 +# endif +#elif defined(CONFIG_ESP32S3_FLASH_SAMPLE_MODE_STR) +# if ESP32S3_SPI_TIMING_FLASH_CLOCK > 80 +# define ESP32S3_SPI_TIMING_FLASH_TUNING 1 +# else +# define ESP32S3_SPI_TIMING_FLASH_TUNING 0 +# endif +#else +# define ESP32S3_SPI_TIMING_FLASH_TUNING 0 +#endif + +#if ESP32S3_SPI_TIMING_FLASH_TUNING +# error "SPI flash tuning is not supported" +#endif + +#if defined(CONFIG_ESP32S3_SPIRAM) +# if defined(CONFIG_ESP32S3_SPIRAM_SPEED_40M) +# define ESP32S3_SPI_TIMING_PSRAM_CLOCK 40 +# elif defined(CONFIG_ESP32S3_SPIRAM_SPEED_80M) +# define ESP32S3_SPI_TIMING_PSRAM_CLOCK 80 +# elif defined(CONFIG_ESP32S3_SPIRAM_SPEED_120M) +# define ESP32S3_SPI_TIMING_PSRAM_CLOCK 120 +# endif +#else +# define ESP32S3_SPI_TIMING_PSRAM_CLOCK 10 +#endif + +#if defined(CONFIG_ESP32S3_SPIRAM_MODE_OCT) +# if ESP32S3_SPI_TIMING_PSRAM_CLOCK > 40 +# define ESP32S3_SPI_TIMING_PSRAM_TUNING 1 +# else +# define ESP32S3_SPI_TIMING_PSRAM_TUNING 0 +# endif +#elif defined(CONFIG_ESP32S3_SPIRAM_MODE_QUAD) +# if ESP32S3_SPI_TIMING_PSRAM_CLOCK > 80 +# define ESP32S3_SPI_TIMING_PSRAM_TUNING 1 +# else +# define ESP32S3_SPI_TIMING_PSRAM_TUNING 0 +# endif +#else +# define ESP32S3_SPI_TIMING_PSRAM_TUNING 0 +#endif + +#if ESP32S3_SPI_TIMING_PSRAM_TUNING +# error "SPI PSRAM tuning is not supported" +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_spi_timing_set_mspi_low_speed + * + * Description: + * Make MSPI work under 20MHz and remove the timing tuning required delays. + * + * Input Parameters: + * spi1 - Select whether to control SPI1 + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32s3_spi_timing_set_mspi_low_speed(bool control_spi1); + +/**************************************************************************** + * Name: esp32s3_spi_timing_set_mspi_high_speed + * + * Description: + * Make MSPI work under the frequency as users set, may add certain + * delays to MSPI RX direction to meet timing requirements. + * + * Input Parameters: + * spi1 - Select whether to control SPI1 + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32s3_spi_timing_set_mspi_high_speed(bool control_spi1); + +/**************************************************************************** + * Name: esp32s3_spi_timing_set_pin_drive_strength + * + * Description: + * Make SPI all GPIO strength to be 3 under default clock. + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32s3_spi_timing_set_pin_drive_strength(void); + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_SPI_H */ diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiram.c b/arch/xtensa/src/esp32s3/esp32s3_spiram.c index a3d2d416b32..27b0f629c81 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_spiram.c +++ b/arch/xtensa/src/esp32s3/esp32s3_spiram.c @@ -186,7 +186,7 @@ bool esp_spiram_test(void) if (errct < 4) { - merr("SPI SRAM error@%08x:%08x/%08x \n", &spiram[p], spiram[p], + merr("SPI SRAM error@%p:%08x/%08x \n", &spiram[p], spiram[p], p ^ 0xaaaaaaaa); } } @@ -380,4 +380,26 @@ uint8_t esp_spiram_get_cs_io(void) return psram_get_cs_io(); } +/** + * @brief Get allocable virtual start address + * + * @return Allocable virtual start address + */ + +uint32_t esp_spiram_allocable_vaddr_start(void) +{ + return g_allocable_vaddr_start; +} + +/** + * @brief Get allocable virtual end address + * + * @return Allocable virtual end address + */ + +uint32_t esp_spiram_allocable_vaddr_end(void) +{ + return g_allocable_vaddr_end; +} + #endif diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiram.h b/arch/xtensa/src/esp32s3/esp32s3_spiram.h index 2c441926480..5af08a0abbd 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_spiram.h +++ b/arch/xtensa/src/esp32s3/esp32s3_spiram.h @@ -199,6 +199,22 @@ int rodata_flash2spiram_offset(void); #endif +/** + * @brief Get allocable virtual start address + * + * @return Allocable virtual start address + */ + +uint32_t esp_spiram_allocable_vaddr_start(void); + +/** + * @brief Get allocable virtual end address + * + * @return Allocable virtual end address + */ + +uint32_t esp_spiram_allocable_vaddr_end(void); + #ifdef __cplusplus } #endif diff --git a/arch/xtensa/src/esp32s3/esp32s3_start.c b/arch/xtensa/src/esp32s3/esp32s3_start.c index 49cac473d51..7a377e599c5 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_start.c +++ b/arch/xtensa/src/esp32s3/esp32s3_start.c @@ -42,10 +42,13 @@ #ifdef CONFIG_BUILD_PROTECTED # include "esp32s3_userspace.h" #endif +#include "esp32s3_spi_timing.h" #include "hardware/esp32s3_cache_memory.h" #include "hardware/esp32s3_system.h" #include "hardware/esp32s3_extmem.h" #include "rom/esp32s3_libc_stubs.h" +#include "rom/esp32s3_spiflash.h" +#include "rom/esp32s3_opi_flash.h" /**************************************************************************** * Pre-processor Definitions @@ -336,6 +339,12 @@ void noreturn_function IRAM_ATTR __esp32s3_start(void) showprogress('A'); +#if defined(CONFIG_ESP32S3_FLASH_MODE_OCT) || \ + defined(CONFIG_ESP32S3_SPIRAM_MODE_OCT) + esp_rom_opiflash_pin_config(); + esp32s3_spi_timing_set_pin_drive_strength(); +#endif + #if defined(CONFIG_ESP32S3_SPIRAM_BOOT_INIT) if (esp_spiram_init() != OK) { diff --git a/arch/xtensa/src/esp32s3/hardware/esp32s3_spi_mem_reg.h b/arch/xtensa/src/esp32s3/hardware/esp32s3_spi_mem_reg.h index d80a847c2a0..bb80bde4370 100644 --- a/arch/xtensa/src/esp32s3/hardware/esp32s3_spi_mem_reg.h +++ b/arch/xtensa/src/esp32s3/hardware/esp32s3_spi_mem_reg.h @@ -416,8 +416,10 @@ extern "C" /* Description: Set this bit to enable 8-bit-mode(8-bm) in ADDR phase. */ -#define SPI_MEM_FADDR_OCT (BIT(6)) #define SPI_MEM_FADDR_OCT_M (BIT(6)) -#define SPI_MEM_FADDR_OCT_V 0x1 #define SPI_MEM_FADDR_OCT_S 6 +#define SPI_MEM_FADDR_OCT (BIT(6)) +#define SPI_MEM_FADDR_OCT_M (BIT(6)) +#define SPI_MEM_FADDR_OCT_V 0x1 +#define SPI_MEM_FADDR_OCT_S 6 /* SPI_MEM_FDIN_OCT : R/W ;bitpos:[5] ;default: 1'b0 ; */ diff --git a/arch/xtensa/src/esp32s3/rom/esp32s3_opi_flash.h b/arch/xtensa/src/esp32s3/rom/esp32s3_opi_flash.h index e8e2919b0f4..e36b1a191d9 100644 --- a/arch/xtensa/src/esp32s3/rom/esp32s3_opi_flash.h +++ b/arch/xtensa/src/esp32s3/rom/esp32s3_opi_flash.h @@ -96,7 +96,6 @@ typedef struct #define ESP_ROM_SPIFLASH_BP0 BIT2 #define ESP_ROM_SPIFLASH_BP1 BIT3 #define ESP_ROM_SPIFLASH_BP2 BIT4 -#define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0 | ESP_ROM_SPIFLASH_BP1 | ESP_ROM_SPIFLASH_BP2) #define ESP_ROM_SPIFLASH_QE BIT9 #define FLASH_OP_MODE_RDCMD_DOUT 0x3B diff --git a/arch/xtensa/src/esp32s3/rom/esp32s3_spiflash.h b/arch/xtensa/src/esp32s3/rom/esp32s3_spiflash.h index 77ddde1f4e2..1ebfcb5c7d1 100644 --- a/arch/xtensa/src/esp32s3/rom/esp32s3_spiflash.h +++ b/arch/xtensa/src/esp32s3/rom/esp32s3_spiflash.h @@ -55,19 +55,11 @@ extern "C" #define PERIPHS_SPI_FLASH_C7 SPI_W7_REG(1) #define PERIPHS_SPI_FLASH_TX_CRC SPI_TX_CRC_REG(1) -#define SPI0_R_QIO_DUMMY_CYCLELEN 3 -#define SPI0_R_QIO_ADDR_BITSLEN 31 -#define SPI0_R_FAST_DUMMY_CYCLELEN 7 -#define SPI0_R_DIO_DUMMY_CYCLELEN 1 -#define SPI0_R_DIO_ADDR_BITSLEN 27 -#define SPI0_R_FAST_ADDR_BITSLEN 23 -#define SPI0_R_SIO_ADDR_BITSLEN 23 - -#define SPI1_R_QIO_DUMMY_CYCLELEN 3 -#define SPI1_R_QIO_ADDR_BITSLEN 31 +#define SPI1_R_QIO_DUMMY_CYCLELEN 5 +#define SPI1_R_QIO_ADDR_BITSLEN 23 #define SPI1_R_FAST_DUMMY_CYCLELEN 7 #define SPI1_R_DIO_DUMMY_CYCLELEN 3 -#define SPI1_R_DIO_ADDR_BITSLEN 31 +#define SPI1_R_DIO_ADDR_BITSLEN 23 #define SPI1_R_FAST_ADDR_BITSLEN 23 #define SPI1_R_SIO_ADDR_BITSLEN 23 @@ -89,8 +81,8 @@ extern "C" #define ESP_ROM_SPIFLASH_BP0 BIT2 #define ESP_ROM_SPIFLASH_BP1 BIT3 #define ESP_ROM_SPIFLASH_BP2 BIT4 -#define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|\ - ESP_ROM_SPIFLASH_BP1|\ +#define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0 | \ + ESP_ROM_SPIFLASH_BP1 | \ ESP_ROM_SPIFLASH_BP2) #define ESP_ROM_SPIFLASH_QE BIT9 @@ -113,7 +105,12 @@ typedef enum ESP_ROM_SPIFLASH_DIO_MODE, ESP_ROM_SPIFLASH_DOUT_MODE, ESP_ROM_SPIFLASH_FASTRD_MODE, - ESP_ROM_SPIFLASH_SLOWRD_MODE + ESP_ROM_SPIFLASH_SLOWRD_MODE, + ESP_ROM_SPIFLASH_OPI_STR_MODE, + ESP_ROM_SPIFLASH_OPI_DTR_MODE, + ESP_ROM_SPIFLASH_OOUT_MODE, + ESP_ROM_SPIFLASH_OIO_STR_MODE, + ESP_ROM_SPIFLASH_OIO_DTR_MODE, } esp_rom_spiflash_read_mode_t; typedef enum diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/psram_octal/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/psram_octal/defconfig new file mode 100644 index 00000000000..df13f3d5708 --- /dev/null +++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/psram_octal/defconfig @@ -0,0 +1,50 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32s3-devkit" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32S3_DEVKIT=y +CONFIG_ARCH_CHIP="esp32s3" +CONFIG_ARCH_CHIP_ESP32S3=y +CONFIG_ARCH_CHIP_ESP32S3WROOM1=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_ESP32S3_FLASH_FREQ_80M=y +CONFIG_ESP32S3_SPIRAM=y +CONFIG_ESP32S3_SPIRAM_MODE_OCT=y +CONFIG_ESP32S3_UART0=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_MM_REGIONS=2 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_MM=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/psram_quad/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/psram_quad/defconfig new file mode 100644 index 00000000000..9b2e380e108 --- /dev/null +++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/psram_quad/defconfig @@ -0,0 +1,49 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32s3-devkit" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32S3_DEVKIT=y +CONFIG_ARCH_CHIP="esp32s3" +CONFIG_ARCH_CHIP_ESP32S3=y +CONFIG_ARCH_CHIP_ESP32S3WROOM1=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_ESP32S3_FLASH_FREQ_80M=y +CONFIG_ESP32S3_SPIRAM=y +CONFIG_ESP32S3_UART0=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_MM_REGIONS=2 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_MM=y +CONFIG_UART0_SERIAL_CONSOLE=y