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 
25 /**
26  * Supported Flash chip vendor id
27  */
28 #define ESP_FLASH_CHIP_MXIC_OCT     0xC2
29 
30 const static char *TAG = "Octal Flash";
31 // default value is rom_default_spiflash_legacy_flash_func
32 extern const spiflash_legacy_funcs_t *rom_spiflash_legacy_funcs;
33 extern int SPI_write_enable(void *spi);
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) & 0xff) != 0x80) {
65         ESP_EARLY_LOGE(TAG, "Detected MXIC Flash, but memory type is not Octal");
66         return ESP_ERR_NOT_FOUND;
67     }
68     *out_vendor_id = ESP_FLASH_CHIP_MXIC_OCT;
69 
70     return ESP_OK;
71 }
72 
73 // 0x00: SPI; 0x01: STR OPI;  0x02: DTR OPI
s_set_flash_dtr_str_opi_mode(int spi_num,uint8_t val)74 static void s_set_flash_dtr_str_opi_mode(int spi_num, uint8_t val)
75 {
76     uint8_t cmd_len = 8;
77     int addr_bit_len = 32;
78     int dummy = 0;
79     int data_bit_len = 8;
80 
81     SPI_write_enable(&g_rom_flashchip);
82     //SPI command, WRCR2
83     esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
84                               SPI_FLASH_SPI_CMD_WRCR2, cmd_len,
85                               0, addr_bit_len,
86                               dummy,
87                               (uint8_t *)&val, data_bit_len,
88                               NULL, 0,
89                               ESP_ROM_OPIFLASH_SEL_CS0,
90                               false);
91 }
92 
93 //To set the output driver strength
s_set_flash_ouput_driver_strength(int spi_num,uint8_t strength)94 static void s_set_flash_ouput_driver_strength(int spi_num, uint8_t strength)
95 {
96     uint16_t reg_val = 0;
97     uint8_t sr_reg_val = 0;
98     uint8_t cr_reg_val = 0;
99     uint8_t cmd_len = 8;
100     uint32_t addr = 0;
101     int addr_bit_len = 0;
102     int dummy = 0;
103     int data_bit_len = 8;
104 
105     //Read
106     //SPI command, RDSR
107     esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
108                               SPI_FLASH_SPI_CMD_RDSR, cmd_len,
109                               addr, addr_bit_len,
110                               dummy,
111                               NULL, 0,
112                               (uint8_t*)&sr_reg_val, data_bit_len,
113                               ESP_ROM_OPIFLASH_SEL_CS0,
114                               false);
115 
116     //SPI command, RDCR
117     esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
118                               SPI_FLASH_SPI_CMD_RDCR, cmd_len,
119                               addr, addr_bit_len,
120                               dummy,
121                               NULL, 0,
122                               (uint8_t*)&cr_reg_val, data_bit_len,
123                               ESP_ROM_OPIFLASH_SEL_CS0,
124                               false);
125 
126     //Modify
127     reg_val = (((cr_reg_val & 0xf8) | strength) << 8) | sr_reg_val;
128 
129     //Write
130     //SPI command, WRSR/WRCR
131     data_bit_len = 16;
132     SPI_write_enable(&g_rom_flashchip);
133     esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
134                               SPI_FLASH_SPI_CMD_WRSRCR, cmd_len,
135                               addr, addr_bit_len,
136                               dummy,
137                               (uint8_t*)&reg_val, data_bit_len,
138                               NULL, 0,
139                               ESP_ROM_OPIFLASH_SEL_CS0,
140                               false);
141 }
142 
s_set_pin_drive_capability(uint8_t drv)143 static void s_set_pin_drive_capability(uint8_t drv)
144 {
145     //flash clock
146     REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_FMEM_SPICLK_FUN_DRV, 3);
147     //cs0
148     PIN_SET_DRV(IO_MUX_GPIO29_REG, 3);
149 }
150 
s_flash_init_mxic(esp_rom_spiflash_read_mode_t mode)151 static void s_flash_init_mxic(esp_rom_spiflash_read_mode_t mode)
152 {
153     static const esp_rom_opiflash_def_t opiflash_cmd_def_mxic = OPI_CMD_FORMAT_MXIC();
154     esp_rom_opiflash_legacy_driver_init(&opiflash_cmd_def_mxic);
155     esp_rom_spiflash_wait_idle(&g_rom_flashchip);
156 
157     // increase flash output driver strength
158     s_set_flash_ouput_driver_strength(1, 7);
159 
160     // STR/DTR specific setting
161     esp_rom_spiflash_wait_idle(&g_rom_flashchip);
162 #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR
163     s_set_pin_drive_capability(3);
164     s_set_flash_dtr_str_opi_mode(1, 0x1);
165     esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd);
166     esp_rom_spi_set_dtr_swap_mode(0, false, false);
167     esp_rom_spi_set_dtr_swap_mode(1, false, false);
168 #else //CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
169     s_set_pin_drive_capability(3);
170     s_set_flash_dtr_str_opi_mode(1, 0x2);
171     esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd);
172     esp_rom_spi_set_dtr_swap_mode(0, true, true);
173     esp_rom_spi_set_dtr_swap_mode(1, true, true);
174 #endif
175 
176     esp_rom_opiflash_wait_idle();
177 }
178 #endif   // #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
179 
s_mxic_set_required_regs(uint32_t chip_id)180 static void s_mxic_set_required_regs(uint32_t chip_id)
181 {
182     bool is_swap = false;
183 #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
184     is_swap = true;
185 #else
186     //STR mode does not need to enable ddr_swap registers
187 #endif
188     esp_rom_spi_set_dtr_swap_mode(0, is_swap, is_swap);
189     esp_rom_spi_set_dtr_swap_mode(1, is_swap, is_swap);
190 }
191 
192 
193 /*----------------------------------------------------------------------------------------------------
194                                 General Functions
195 -----------------------------------------------------------------------------------------------------*/
196 typedef struct opi_flash_func_t {
197     esp_err_t (*probe)(uint32_t flash_id, uint8_t *out_vendor_id);      //Function pointer for detecting Flash chip vendor
198     void (*init)(esp_rom_spiflash_read_mode_t mode);                    //Function pointer for initialising certain Flash chips
199     void (*regs_set)(uint32_t flash_id);                                //Function pointer for setting required registers, decided by certain flash chips.
200 } opi_flash_func_t;
201 
202 #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
203 static const opi_flash_func_t opi_flash_func_mxic = {
204     .probe = &s_probe_mxic_chip,
205     .init = &s_flash_init_mxic,
206     .regs_set = &s_mxic_set_required_regs,
207 };
208 #endif
209 
210 static const opi_flash_func_t *registered_chip_funcs[] = {
211 #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
212     &opi_flash_func_mxic,
213 #endif
214     NULL,
215 };
216 
217 //To check which Flash chip is used
218 static const opi_flash_func_t **s_chip_func = NULL;
219 
esp_opiflash_init(uint32_t chip_id)220 esp_err_t esp_opiflash_init(uint32_t chip_id)
221 {
222     esp_err_t ret = ESP_FAIL;
223     esp_rom_spiflash_read_mode_t mode;
224 #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR
225     mode = ESP_ROM_SPIFLASH_OPI_STR_MODE;
226 #elif CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
227     mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE;
228 #else
229     mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
230 #endif
231 
232     const opi_flash_func_t **chip_func = &registered_chip_funcs[0];
233 
234     uint8_t vendor_id = 0;
235     while (*chip_func) {
236         ret = (*chip_func)->probe(chip_id, &vendor_id);
237         if (ret == ESP_OK) {
238             // Detect this is the supported chip type
239             s_chip_id = chip_id;
240             (*chip_func)->init(mode);
241             s_register_rom_function();
242             break;
243         }
244         chip_func++;
245     }
246     s_chip_func = chip_func;
247 
248     if (ret != ESP_OK) {
249         ESP_EARLY_LOGE(TAG, "No detected Flash chip, please check the menuconfig to see if the chip is supported");
250         abort();
251     }
252 
253     return ESP_OK;
254 }
255 
256 /**
257  * Add Flash chip specifically required MSPI register settings here
258  */
esp_opiflash_set_required_regs(void)259 void esp_opiflash_set_required_regs(void)
260 {
261     (*s_chip_func)->regs_set(s_chip_id);
262 }
263