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