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