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