1 /*
2 * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stdbool.h>
7 #include <assert.h>
8 #include "string.h"
9 #include "sdkconfig.h"
10 #include "esp_err.h"
11 #include "esp_log.h"
12 #include "esp32s3/rom/spi_flash.h"
13 #include "soc/efuse_reg.h"
14 #include "soc/spi_reg.h"
15 #include "soc/spi_mem_reg.h"
16 #include "soc/soc_caps.h"
17 #include "flash_qio_mode.h"
18 #include "bootloader_flash_config.h"
19 #include "bootloader_common.h"
20
21 #define FLASH_IO_MATRIX_DUMMY_40M 0
22 #define FLASH_IO_MATRIX_DUMMY_80M 0
23 #define FLASH_IO_DRIVE_GD_WITH_1V8PSRAM 3
24 #define FLASH_CS_SETUP_TIME 3
25 #define FLASH_CS_HOLD_TIME 3
26 #define FLASH_CS_HOLD_DELAY 2
27
bootloader_flash_update_id()28 void bootloader_flash_update_id()
29 {
30 esp_rom_spiflash_chip_t *chip = &rom_spiflash_legacy_data->chip;
31 chip->device_id = bootloader_read_flash_id();
32 }
33
bootloader_flash_cs_timing_config()34 void IRAM_ATTR bootloader_flash_cs_timing_config()
35 {
36 //SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for FLASH, so we only need to set SPI0 related registers here
37 #if CONFIG_ESPTOOLPY_OCT_FLASH
38 SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M);
39 SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, FLASH_CS_HOLD_TIME, SPI_MEM_CS_HOLD_TIME_S);
40 SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, FLASH_CS_SETUP_TIME, SPI_MEM_CS_SETUP_TIME_S);
41 //CS high time
42 SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_DELAY_V, FLASH_CS_HOLD_DELAY, SPI_MEM_CS_HOLD_DELAY_S);
43 #else
44 SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, 0, SPI_MEM_CS_HOLD_TIME_S);
45 SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S);
46 SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M);
47 #endif
48 }
49
bootloader_flash_clock_config(const esp_image_header_t * pfhdr)50 void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr)
51 {
52 uint32_t spi_clk_div = 0;
53 switch (pfhdr->spi_speed) {
54 case ESP_IMAGE_SPI_SPEED_80M:
55 spi_clk_div = 1;
56 break;
57 case ESP_IMAGE_SPI_SPEED_40M:
58 spi_clk_div = 2;
59 break;
60 case ESP_IMAGE_SPI_SPEED_26M:
61 spi_clk_div = 3;
62 break;
63 case ESP_IMAGE_SPI_SPEED_20M:
64 spi_clk_div = 4;
65 break;
66 default:
67 break;
68 }
69 esp_rom_spiflash_config_clk(spi_clk_div, 0);
70 esp_rom_spiflash_config_clk(spi_clk_div, 1);
71 }
72
bootloader_flash_set_dummy_out(void)73 void IRAM_ATTR bootloader_flash_set_dummy_out(void)
74 {
75 REG_SET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL);
76 REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL);
77 }
78
bootloader_flash_dummy_config(const esp_image_header_t * pfhdr)79 void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr)
80 {
81 bootloader_configure_spi_pins(1);
82 bootloader_flash_set_dummy_out();
83 }
84