1 /*
2 * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT espressif_esp32_flash_controller
8 #define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash)
9
10 #define FLASH_WRITE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, write_block_size)
11 #define FLASH_ERASE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, erase_block_size)
12
13 /*
14 * HAL includes go first to
15 * avoid BIT macro redefinition
16 */
17 #include <esp_spi_flash.h>
18 #include <hal/spi_ll.h>
19 #include <hal/spi_flash_ll.h>
20 #include <hal/spi_flash_hal.h>
21 #include <soc/spi_struct.h>
22 #include <spi_flash_defs.h>
23 #include <esp_flash_encrypt.h>
24
25 #include <zephyr/kernel.h>
26 #include <zephyr/device.h>
27 #include <stddef.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <zephyr/drivers/flash.h>
31 #include <soc.h>
32
33 #if defined(CONFIG_SOC_SERIES_ESP32)
34 #include "soc/dport_reg.h"
35 #include "esp32/rom/cache.h"
36 #include "esp32/rom/spi_flash.h"
37 #include "esp32/spiram.h"
38 #elif defined(CONFIG_SOC_SERIES_ESP32S2)
39 #include "soc/spi_mem_reg.h"
40 #include "esp32s2/rom/cache.h"
41 #include "esp32s2/rom/spi_flash.h"
42 #elif defined(CONFIG_SOC_SERIES_ESP32S3)
43 #include "soc/spi_mem_reg.h"
44 #include "esp32s3/rom/cache.h"
45 #include "esp32s3/rom/spi_flash.h"
46 #elif defined(CONFIG_SOC_SERIES_ESP32C3)
47 #include "soc/spi_periph.h"
48 #include "soc/spi_mem_reg.h"
49 #include "soc/dport_access.h"
50 #include "esp32c3/dport_access.h"
51 #include "esp32c3/rom/cache.h"
52 #include "esp32c3/rom/spi_flash.h"
53 #endif
54
55 #include "soc/mmu.h"
56
57 #include <zephyr/logging/log.h>
58 LOG_MODULE_REGISTER(flash_esp32, CONFIG_FLASH_LOG_LEVEL);
59
60 #define FLASH_SEM_TIMEOUT (k_is_in_isr() ? K_NO_WAIT : K_FOREVER)
61
62 struct flash_esp32_dev_config {
63 spi_dev_t *controller;
64 };
65
66 struct flash_esp32_dev_data {
67 #ifdef CONFIG_MULTITHREADING
68 struct k_sem sem;
69 #endif
70 };
71
72 static const struct flash_parameters flash_esp32_parameters = {
73 .write_block_size = FLASH_WRITE_BLK_SZ,
74 .erase_value = 0xff,
75 };
76
77 #ifdef CONFIG_MULTITHREADING
flash_esp32_sem_take(const struct device * dev)78 static inline void flash_esp32_sem_take(const struct device *dev)
79 {
80 struct flash_esp32_dev_data *data = dev->data;
81
82 k_sem_take(&data->sem, FLASH_SEM_TIMEOUT);
83 }
84
flash_esp32_sem_give(const struct device * dev)85 static inline void flash_esp32_sem_give(const struct device *dev)
86 {
87 struct flash_esp32_dev_data *data = dev->data;
88
89 k_sem_give(&data->sem);
90 }
91 #else
92
93 #define flash_esp32_sem_take(dev) do {} while (0)
94 #define flash_esp32_sem_give(dev) do {} while (0)
95
96 #endif /* CONFIG_MULTITHREADING */
97
flash_esp32_read(const struct device * dev,off_t address,void * buffer,size_t length)98 static int flash_esp32_read(const struct device *dev, off_t address, void *buffer, size_t length)
99 {
100 int ret = 0;
101
102 flash_esp32_sem_take(dev);
103 if (!esp_flash_encryption_enabled()) {
104 ret = spi_flash_read(address, buffer, length);
105 } else {
106 ret = spi_flash_read_encrypted(address, buffer, length);
107 }
108 flash_esp32_sem_give(dev);
109 return ret;
110 }
111
flash_esp32_write(const struct device * dev,off_t address,const void * buffer,size_t length)112 static int flash_esp32_write(const struct device *dev,
113 off_t address,
114 const void *buffer,
115 size_t length)
116 {
117 int ret = 0;
118
119 flash_esp32_sem_take(dev);
120 if (!esp_flash_encryption_enabled()) {
121 ret = spi_flash_write(address, buffer, length);
122 } else {
123 ret = spi_flash_write_encrypted(address, buffer, length);
124 }
125 flash_esp32_sem_give(dev);
126 return ret;
127 }
128
flash_esp32_erase(const struct device * dev,off_t start,size_t len)129 static int flash_esp32_erase(const struct device *dev, off_t start, size_t len)
130 {
131 flash_esp32_sem_take(dev);
132 int ret = spi_flash_erase_range(start, len);
133 flash_esp32_sem_give(dev);
134 return ret;
135 }
136
137 #if CONFIG_FLASH_PAGE_LAYOUT
138 static const struct flash_pages_layout flash_esp32_pages_layout = {
139 .pages_count = DT_REG_SIZE(SOC_NV_FLASH_NODE) / FLASH_ERASE_BLK_SZ,
140 .pages_size = DT_PROP(SOC_NV_FLASH_NODE, erase_block_size),
141 };
142
flash_esp32_page_layout(const struct device * dev,const struct flash_pages_layout ** layout,size_t * layout_size)143 void flash_esp32_page_layout(const struct device *dev,
144 const struct flash_pages_layout **layout,
145 size_t *layout_size)
146 {
147 *layout = &flash_esp32_pages_layout;
148 *layout_size = 1;
149 }
150 #endif /* CONFIG_FLASH_PAGE_LAYOUT */
151
152 static const struct flash_parameters *
flash_esp32_get_parameters(const struct device * dev)153 flash_esp32_get_parameters(const struct device *dev)
154 {
155 ARG_UNUSED(dev);
156
157 return &flash_esp32_parameters;
158 }
159
flash_esp32_init(const struct device * dev)160 static int flash_esp32_init(const struct device *dev)
161 {
162 struct flash_esp32_dev_data *const dev_data = dev->data;
163
164 #ifdef CONFIG_MULTITHREADING
165 k_sem_init(&dev_data->sem, 1, 1);
166 #endif /* CONFIG_MULTITHREADING */
167
168 return 0;
169 }
170
171 static const struct flash_driver_api flash_esp32_driver_api = {
172 .read = flash_esp32_read,
173 .write = flash_esp32_write,
174 .erase = flash_esp32_erase,
175 .get_parameters = flash_esp32_get_parameters,
176 #ifdef CONFIG_FLASH_PAGE_LAYOUT
177 .page_layout = flash_esp32_page_layout,
178 #endif
179 };
180
181 static struct flash_esp32_dev_data flash_esp32_data;
182
183 static const struct flash_esp32_dev_config flash_esp32_config = {
184 .controller = (spi_dev_t *) DT_INST_REG_ADDR(0),
185 };
186
187 DEVICE_DT_INST_DEFINE(0, flash_esp32_init,
188 NULL,
189 &flash_esp32_data, &flash_esp32_config,
190 POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY,
191 &flash_esp32_driver_api);
192