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*)&reg_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 = &registered_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