1 /*
2 * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "sdkconfig.h"
8 #include "esp_log.h"
9 #include "esp_err.h"
10 #include "esp_rom_gpio.h"
11 #include "esp32s3/rom/gpio.h"
12 #include "esp32s3/rom/spi_flash.h"
13 #include "esp32s3/rom/opi_flash.h"
14 #include "esp_private/spi_flash_os.h"
15 #include "opi_flash_private.h"
16 #include "soc/spi_mem_reg.h"
17 #include "soc/io_mux_reg.h"
18 #include "opi_flash_cmd_format_mxic.h"
19
20 #define SPI_FLASH_SPI_CMD_WRCR2 0x72
21 #define SPI_FLASH_SPI_CMD_RDSR 0x05
22 #define SPI_FLASH_SPI_CMD_RDCR 0x15
23 #define SPI_FLASH_SPI_CMD_WRSRCR 0x01
24 #define SPI_FLASH_SPI_CMD_RDSFDP 0x5A
25
26 /**
27 * Supported Flash chip vendor id
28 */
29 #define ESP_FLASH_CHIP_MXIC_OCT 0xC2
30
31 const static char *TAG = "Octal Flash";
32 // default value is rom_default_spiflash_legacy_flash_func
33 extern const spiflash_legacy_funcs_t *rom_spiflash_legacy_funcs;
34 static uint32_t s_chip_id;
35
36
s_register_rom_function(void)37 static void s_register_rom_function(void)
38 {
39 static spiflash_legacy_funcs_t rom_func =
40 {
41 .read_sub_len = 32,
42 .write_sub_len = 32,
43 .unlock = esp_rom_opiflash_wait_idle,
44 .erase_block = esp_rom_opiflash_erase_block_64k,
45 .erase_sector = esp_rom_opiflash_erase_sector,
46 .read = esp_rom_opiflash_read,
47 .write = esp_rom_opiflash_write,
48 .wait_idle = esp_rom_opiflash_wait_idle,
49 .wren = esp_rom_opiflash_wren,
50 .erase_area = esp_rom_opiflash_erase_area,
51 };
52 rom_spiflash_legacy_funcs = &rom_func;
53 }
54
55 #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
56 /*----------------------------------------------------------------------------------------------------
57 MXIC Specific Functions
58 -----------------------------------------------------------------------------------------------------*/
s_probe_mxic_chip(uint32_t chip_id,uint8_t * out_vendor_id)59 static esp_err_t s_probe_mxic_chip(uint32_t chip_id, uint8_t *out_vendor_id)
60 {
61 if (chip_id >> 16 != ESP_FLASH_CHIP_MXIC_OCT) {
62 return ESP_ERR_NOT_FOUND;
63 }
64 if (((chip_id >> 8) & 0xf0) != 0x80) {
65 // We now suppose that middle id of opi flash is 0x8*.
66 ESP_EARLY_LOGE(TAG, "Detected MXIC Flash, but memory type is not Octal");
67 return ESP_ERR_NOT_FOUND;
68 }
69 *out_vendor_id = ESP_FLASH_CHIP_MXIC_OCT;
70
71 return ESP_OK;
72 }
73
74 #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
s_mxic_dtr_need_swap(void)75 static bool s_mxic_dtr_need_swap(void)
76 {
77 // This function is used for judging the data bytes whether need swap.
78 // For some of opi flash chips, the data bytes are ordered by D1-D0-D3-D2. This kinds of order needs swap.
79 // On the contrary, some opi flash chips order the data like D0-D1-D2-D3. This kinds of order doesn't need swap.
80 // Note: this function must be called when flash works under single line mode.
81 // 1. Send 0x5A to read SFDP regs for getting the first address of JEDEC Flash Parameter table.
82 // 2. Add offset with first address to get the order in 8D-8D-8D mode.
83 // 3. Judge whether the BIT(7) is 1, 1 stands for need swap, vice versa.
84 uint8_t JEDEC_first_address = 0;
85 uint8_t byte_order_val = 0;
86 uint8_t dummy = 8;
87 uint8_t cmd_len = 8;
88 uint8_t addr_len = 24;
89 uint8_t miso_bit_len = 8;
90 esp_rom_opiflash_exec_cmd(1, ESP_ROM_SPIFLASH_FASTRD_MODE,
91 SPI_FLASH_SPI_CMD_RDSFDP, cmd_len,
92 0x0C, addr_len,
93 dummy,
94 NULL, 0,
95 (uint8_t*)&JEDEC_first_address, miso_bit_len,
96 ESP_ROM_OPIFLASH_SEL_CS0,
97 false);
98
99 esp_rom_opiflash_exec_cmd(1, ESP_ROM_SPIFLASH_FASTRD_MODE,
100 SPI_FLASH_SPI_CMD_RDSFDP, cmd_len,
101 (JEDEC_first_address + 0x47), addr_len,
102 dummy,
103 NULL, 0,
104 (uint8_t*)&byte_order_val, miso_bit_len,
105 ESP_ROM_OPIFLASH_SEL_CS0,
106 false);
107
108 return ((byte_order_val & 0x80) == 0x80) ? true : false;
109 }
110 #endif // CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
111
112 // 0x00: SPI; 0x01: STR OPI; 0x02: DTR OPI
s_set_flash_dtr_str_opi_mode(int spi_num,uint8_t val)113 static void s_set_flash_dtr_str_opi_mode(int spi_num, uint8_t val)
114 {
115 uint8_t cmd_len = 8;
116 int addr_bit_len = 32;
117 int dummy = 0;
118 int data_bit_len = 8;
119
120 esp_rom_spiflash_write_enable(&g_rom_flashchip);
121 //SPI command, WRCR2
122 esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
123 SPI_FLASH_SPI_CMD_WRCR2, cmd_len,
124 0, addr_bit_len,
125 dummy,
126 (uint8_t *)&val, data_bit_len,
127 NULL, 0,
128 ESP_ROM_OPIFLASH_SEL_CS0,
129 false);
130 }
131
132 //To set the output driver strength
s_set_flash_ouput_driver_strength(int spi_num,uint8_t strength)133 static void s_set_flash_ouput_driver_strength(int spi_num, uint8_t strength)
134 {
135 uint16_t reg_val = 0;
136 uint8_t sr_reg_val = 0;
137 uint8_t cr_reg_val = 0;
138 uint8_t cmd_len = 8;
139 uint32_t addr = 0;
140 int addr_bit_len = 0;
141 int dummy = 0;
142 int data_bit_len = 8;
143
144 //Read
145 //SPI command, RDSR
146 esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
147 SPI_FLASH_SPI_CMD_RDSR, cmd_len,
148 addr, addr_bit_len,
149 dummy,
150 NULL, 0,
151 (uint8_t*)&sr_reg_val, data_bit_len,
152 ESP_ROM_OPIFLASH_SEL_CS0,
153 false);
154
155 //SPI command, RDCR
156 esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
157 SPI_FLASH_SPI_CMD_RDCR, cmd_len,
158 addr, addr_bit_len,
159 dummy,
160 NULL, 0,
161 (uint8_t*)&cr_reg_val, data_bit_len,
162 ESP_ROM_OPIFLASH_SEL_CS0,
163 false);
164
165 //Modify
166 reg_val = (((cr_reg_val & 0xf8) | strength) << 8) | sr_reg_val;
167
168 //Write
169 //SPI command, WRSR/WRCR
170 data_bit_len = 16;
171 esp_rom_spiflash_write_enable(&g_rom_flashchip);
172 esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
173 SPI_FLASH_SPI_CMD_WRSRCR, cmd_len,
174 addr, addr_bit_len,
175 dummy,
176 (uint8_t*)®_val, data_bit_len,
177 NULL, 0,
178 ESP_ROM_OPIFLASH_SEL_CS0,
179 false);
180 }
181
s_set_pin_drive_capability(uint8_t drv)182 static void s_set_pin_drive_capability(uint8_t drv)
183 {
184 //flash clock
185 REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_FMEM_SPICLK_FUN_DRV, 3);
186 //cs0
187 PIN_SET_DRV(IO_MUX_GPIO29_REG, 3);
188 }
189
s_flash_init_mxic(esp_rom_spiflash_read_mode_t mode)190 static void s_flash_init_mxic(esp_rom_spiflash_read_mode_t mode)
191 {
192 #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR
193 static const esp_rom_opiflash_def_t opiflash_cmd_def_mxic = OPI_CMD_FORMAT_MXIC_STR();
194 #elif CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
195 static const esp_rom_opiflash_def_t opiflash_cmd_def_mxic = OPI_CMD_FORMAT_MXIC_DTR();
196 #endif
197 esp_rom_opiflash_legacy_driver_init(&opiflash_cmd_def_mxic);
198 esp_rom_spiflash_wait_idle(&g_rom_flashchip);
199
200 // increase flash output driver strength
201 s_set_flash_ouput_driver_strength(1, 7);
202
203 // STR/DTR specific setting
204 esp_rom_spiflash_wait_idle(&g_rom_flashchip);
205 #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR
206 s_set_pin_drive_capability(3);
207 s_set_flash_dtr_str_opi_mode(1, 0x1);
208 esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd);
209 esp_rom_spi_set_dtr_swap_mode(0, false, false);
210 esp_rom_spi_set_dtr_swap_mode(1, false, false);
211 #else //CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
212 s_set_pin_drive_capability(3);
213 bool need_swap = s_mxic_dtr_need_swap();
214 s_set_flash_dtr_str_opi_mode(1, 0x2);
215 esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd);
216 esp_rom_spi_set_dtr_swap_mode(0, need_swap, need_swap);
217 esp_rom_spi_set_dtr_swap_mode(1, need_swap, need_swap);
218 #endif
219
220 esp_rom_opiflash_wait_idle();
221 }
222 #endif // #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
223
s_mxic_set_required_regs(uint32_t chip_id)224 __attribute__((unused)) static void s_mxic_set_required_regs(uint32_t chip_id)
225 {
226 bool is_swap = false;
227 #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
228 is_swap = true;
229 #else
230 //STR mode does not need to enable ddr_swap registers
231 #endif
232 esp_rom_spi_set_dtr_swap_mode(0, is_swap, is_swap);
233 esp_rom_spi_set_dtr_swap_mode(1, is_swap, is_swap);
234 }
235
236
237 /*----------------------------------------------------------------------------------------------------
238 General Functions
239 -----------------------------------------------------------------------------------------------------*/
240 typedef struct opi_flash_func_t {
241 esp_err_t (*probe)(uint32_t flash_id, uint8_t *out_vendor_id); //Function pointer for detecting Flash chip vendor
242 void (*init)(esp_rom_spiflash_read_mode_t mode); //Function pointer for initialising certain Flash chips
243 void (*regs_set)(uint32_t flash_id); //Function pointer for setting required registers, decided by certain flash chips.
244 } opi_flash_func_t;
245
246 #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
247 static const opi_flash_func_t opi_flash_func_mxic = {
248 .probe = &s_probe_mxic_chip,
249 .init = &s_flash_init_mxic,
250 .regs_set = &s_mxic_set_required_regs,
251 };
252 #endif
253
254 static const opi_flash_func_t *registered_chip_funcs[] = {
255 #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
256 &opi_flash_func_mxic,
257 #endif
258 NULL,
259 };
260
261 //To check which Flash chip is used
262 static const opi_flash_func_t **s_chip_func = NULL;
263
esp_opiflash_init(uint32_t chip_id)264 esp_err_t esp_opiflash_init(uint32_t chip_id)
265 {
266 esp_err_t ret = ESP_FAIL;
267 esp_rom_spiflash_read_mode_t mode;
268 #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR
269 mode = ESP_ROM_SPIFLASH_OPI_STR_MODE;
270 #elif CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
271 mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE;
272 #else
273 mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
274 #endif
275
276 const opi_flash_func_t **chip_func = ®istered_chip_funcs[0];
277
278 uint8_t vendor_id = 0;
279 while (*chip_func) {
280 ret = (*chip_func)->probe(chip_id, &vendor_id);
281 if (ret == ESP_OK) {
282 // Detect this is the supported chip type
283 s_chip_id = chip_id;
284 (*chip_func)->init(mode);
285 s_register_rom_function();
286 break;
287 }
288 chip_func++;
289 }
290 s_chip_func = chip_func;
291
292 if (ret != ESP_OK) {
293 ESP_EARLY_LOGE(TAG, "No detected Flash chip, please check the menuconfig to see if the chip is supported");
294 abort();
295 }
296
297 return ESP_OK;
298 }
299
300 /**
301 * Add Flash chip specifically required MSPI register settings here
302 */
esp_opiflash_set_required_regs(void)303 void esp_opiflash_set_required_regs(void)
304 {
305 (*s_chip_func)->regs_set(s_chip_id);
306 }
307