1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stddef.h>
7 #include <stdint.h>
8 #include "bootloader_flash_config.h"
9 #include "flash_qio_mode.h"
10 #include "sdkconfig.h"
11 #include "bootloader_flash_priv.h"
12 #include "esp_log.h"
13 #include "esp_err.h"
14 #include "esp_rom_efuse.h"
15 #include "flash_qio_mode.h"
16 #if CONFIG_IDF_TARGET_ESP32
17 #include "esp32/rom/spi_flash.h"
18 #elif CONFIG_IDF_TARGET_ESP32S2
19 #include "esp32s2/rom/spi_flash.h"
20 #elif CONFIG_IDF_TARGET_ESP32S3
21 #include "esp32s3/rom/spi_flash.h"
22 #elif CONFIG_IDF_TARGET_ESP32C3
23 #include "esp32c3/rom/spi_flash.h"
24 #elif CONFIG_IDF_TARGET_ESP32H2
25 #include "esp32h2/rom/spi_flash.h"
26 #endif
27 #include "soc/efuse_periph.h"
28 #include "soc/io_mux_reg.h"
29 
30 
31 static const char *TAG = "qio_mode";
32 
33 typedef unsigned (*read_status_fn_t)(void);
34 typedef void (*write_status_fn_t)(unsigned);
35 
36 typedef struct __attribute__((packed))
37 {
38     const char *manufacturer;
39     uint8_t mfg_id; /* 8-bit JEDEC manufacturer ID */
40     uint16_t flash_id; /* 16-bit JEDEC flash chip ID */
41     uint16_t id_mask; /* Bits to match on in flash chip ID */
42     read_status_fn_t read_status_fn;
43     write_status_fn_t write_status_fn;
44     uint8_t status_qio_bit;
45 } qio_info_t;
46 
47 /* Read 8 bit status using RDSR command */
48 static unsigned read_status_8b_rdsr(void);
49 /* Read 8 bit status (second byte) using RDSR2 command */
50 static unsigned read_status_8b_rdsr2(void);
51 /* read 16 bit status using RDSR & RDSR2 (low and high bytes) */
52 static unsigned read_status_16b_rdsr_rdsr2(void);
53 
54 /* Write 8 bit status using WRSR */
55 static void write_status_8b_wrsr(unsigned new_status);
56 /* Write 8 bit status (second byte) using WRSR2 */
57 static void write_status_8b_wrsr2(unsigned new_status);
58 /* Write 16 bit status using WRSR */
59 static void write_status_16b_wrsr(unsigned new_status);
60 
61 /* Read 8 bit status of XM25QU64A  */
62 static unsigned read_status_8b_xmc25qu64a(void);
63 /* Write 8 bit status of XM25QU64A */
64 static void write_status_8b_xmc25qu64a(unsigned new_status);
65 
66 /* Array of known flash chips and data to enable Quad I/O mode
67 
68    Manufacturer & flash ID can be tested by running "esptool.py
69    flash_id"
70 
71    If manufacturer ID matches, and flash ID ORed with flash ID mask
72    matches, enable_qio_mode() will execute "Read Cmd", test if bit
73    number "QIE Bit" is set, and if not set it will call "Write Cmd"
74    with this bit set.
75 
76    Searching of this table stops when the first match is found.
77  */
78 const static qio_info_t chip_data[] = {
79     /*   Manufacturer,   mfg_id, flash_id, id mask, Read Status,                Write Status,               QIE Bit */
80     { "MXIC",        0xC2,   0x2000, 0xFF00,    read_status_8b_rdsr,        write_status_8b_wrsr,       6 },
81     { "ISSI",        0x9D,   0x4000, 0xCF00,    read_status_8b_rdsr,        write_status_8b_wrsr,       6 }, /* IDs 0x40xx, 0x70xx */
82     { "WinBond",     0xEF,   0x4000, 0xFF00,    read_status_16b_rdsr_rdsr2, write_status_16b_wrsr,      9 },
83     { "GD",          0xC8,   0x6000, 0xFF00,    read_status_16b_rdsr_rdsr2, write_status_16b_wrsr,      9 },
84     { "XM25QU64A",   0x20,   0x3817, 0xFFFF,    read_status_8b_xmc25qu64a,  write_status_8b_xmc25qu64a, 6 },
85     { "TH",          0xcd,   0x6000, 0xFF00,    read_status_16b_rdsr_rdsr2, write_status_16b_wrsr,      9 },
86 
87     /* Final entry is default entry, if no other IDs have matched.
88 
89        This approach works for chips including:
90        GigaDevice (mfg ID 0xC8, flash IDs including 4016),
91        FM25Q32 (QOUT mode only, mfg ID 0xA1, flash IDs including 4016)
92        BY25Q32 (mfg ID 0x68, flash IDs including 4016)
93     */
94     { NULL,          0xFF,    0xFFFF, 0xFFFF,   read_status_8b_rdsr2,       write_status_8b_wrsr2,      1 },
95 };
96 
97 #define NUM_CHIPS (sizeof(chip_data) / sizeof(qio_info_t))
98 
99 static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
100                                  write_status_fn_t write_status_fn,
101                                  uint8_t status_qio_bit);
102 
103 /* Generic function to use the "user command" SPI controller functionality
104    to send commands to the SPI flash and read the respopnse.
105 
106    The command passed here is always the on-the-wire command given to the SPI flash unit.
107 */
108 
bootloader_enable_qio_mode(void)109 void bootloader_enable_qio_mode(void)
110 {
111     uint32_t raw_flash_id;
112     uint8_t mfg_id;
113     uint16_t flash_id;
114     size_t i;
115 
116     ESP_LOGD(TAG, "Probing for QIO mode enable...");
117     esp_rom_spiflash_wait_idle(&g_rom_flashchip);
118 
119     raw_flash_id = g_rom_flashchip.device_id;
120     ESP_LOGD(TAG, "Raw SPI flash chip id 0x%x", raw_flash_id);
121 
122     mfg_id = (raw_flash_id >> 16) & 0xFF;
123     flash_id = raw_flash_id & 0xFFFF;
124     ESP_LOGD(TAG, "Manufacturer ID 0x%02x chip ID 0x%04x", mfg_id, flash_id);
125 
126     for (i = 0; i < NUM_CHIPS - 1; i++) {
127         const qio_info_t *chip = &chip_data[i];
128         if (mfg_id == chip->mfg_id && (flash_id & chip->id_mask) == (chip->flash_id & chip->id_mask)) {
129             ESP_LOGI(TAG, "Enabling QIO for flash chip %s", chip_data[i].manufacturer);
130             break;
131         }
132     }
133 
134     if (i == NUM_CHIPS - 1) {
135         ESP_LOGI(TAG, "Enabling default flash chip QIO");
136     }
137     enable_qio_mode(chip_data[i].read_status_fn,
138                     chip_data[i].write_status_fn,
139                     chip_data[i].status_qio_bit);
140 #if SOC_CACHE_SUPPORT_WRAP
141     bootloader_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
142 #endif
143 }
144 
enable_qio_mode(read_status_fn_t read_status_fn,write_status_fn_t write_status_fn,uint8_t status_qio_bit)145 static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
146                                  write_status_fn_t write_status_fn,
147                                  uint8_t status_qio_bit)
148 {
149     uint32_t status;
150     const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
151 
152     esp_rom_spiflash_wait_idle(&g_rom_flashchip);
153 
154     status = read_status_fn();
155     ESP_LOGD(TAG, "Initial flash chip status 0x%x", status);
156 
157     if ((status & (1 << status_qio_bit)) == 0) {
158         bootloader_execute_flash_command(CMD_WREN, 0, 0, 0);
159         write_status_fn(status | (1 << status_qio_bit));
160 
161         esp_rom_spiflash_wait_idle(&g_rom_flashchip);
162 
163         status = read_status_fn();
164         ESP_LOGD(TAG, "Updated flash chip status 0x%x", status);
165         if ((status & (1 << status_qio_bit)) == 0) {
166             ESP_LOGE(TAG, "Failed to set QIE bit, not enabling QIO mode");
167             return ESP_FAIL;
168         }
169 
170     } else {
171         ESP_LOGD(TAG, "QIO mode already enabled in flash");
172     }
173 
174     ESP_LOGD(TAG, "Enabling QIO mode...");
175 
176     esp_rom_spiflash_read_mode_t mode;
177 #if CONFIG_ESPTOOLPY_FLASHMODE_QOUT
178     mode = ESP_ROM_SPIFLASH_QOUT_MODE;
179 #else
180     mode = ESP_ROM_SPIFLASH_QIO_MODE;
181 #endif
182 
183     esp_rom_spiflash_config_readmode(mode);
184 
185 #if CONFIG_IDF_TARGET_ESP32
186     int wp_pin = bootloader_flash_get_wp_pin();
187     esp_rom_spiflash_select_qio_pins(wp_pin, spiconfig);
188 #else
189     esp_rom_spiflash_select_qio_pins(esp_rom_efuse_get_flash_wp_gpio(), spiconfig);
190 #endif
191     return ESP_OK;
192 }
193 
read_status_8b_rdsr(void)194 static unsigned read_status_8b_rdsr(void)
195 {
196     return bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8);
197 }
198 
read_status_8b_rdsr2(void)199 static unsigned read_status_8b_rdsr2(void)
200 {
201     return bootloader_execute_flash_command(CMD_RDSR2, 0, 0, 8);
202 }
203 
read_status_16b_rdsr_rdsr2(void)204 static unsigned read_status_16b_rdsr_rdsr2(void)
205 {
206     return bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8) | (bootloader_execute_flash_command(CMD_RDSR2, 0, 0, 8) << 8);
207 }
208 
write_status_8b_wrsr(unsigned new_status)209 static void write_status_8b_wrsr(unsigned new_status)
210 {
211     bootloader_execute_flash_command(CMD_WRSR, new_status, 8, 0);
212 }
213 
write_status_8b_wrsr2(unsigned new_status)214 static void write_status_8b_wrsr2(unsigned new_status)
215 {
216     bootloader_execute_flash_command(CMD_WRSR2, new_status, 8, 0);
217 }
218 
write_status_16b_wrsr(unsigned new_status)219 static void write_status_16b_wrsr(unsigned new_status)
220 {
221     bootloader_execute_flash_command(CMD_WRSR, new_status, 16, 0);
222 }
223 
read_status_8b_xmc25qu64a(void)224 static unsigned read_status_8b_xmc25qu64a(void)
225 {
226     bootloader_execute_flash_command(CMD_OTPEN, 0, 0, 0);  /* Enter OTP mode */
227     esp_rom_spiflash_wait_idle(&g_rom_flashchip);
228     uint32_t read_status = bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8);
229     bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0);   /* Exit OTP mode */
230     return read_status;
231 }
232 
write_status_8b_xmc25qu64a(unsigned new_status)233 static void write_status_8b_xmc25qu64a(unsigned new_status)
234 {
235     bootloader_execute_flash_command(CMD_OTPEN, 0, 0, 0);  /* Enter OTP mode */
236     esp_rom_spiflash_wait_idle(&g_rom_flashchip);
237     bootloader_execute_flash_command(CMD_WRSR, new_status, 8, 0);
238     esp_rom_spiflash_wait_idle(&g_rom_flashchip);
239     bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0);   /* Exit OTP mode */
240 }
241