1 // Copyright (C) 2022 Beken Corporation
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
15 #include <driver/int.h>
16 #include <os/mem.h>
17 #include <driver/qspi.h>
18 #include "bk_drv_model.h"
19 #include "bk_sys_ctrl.h"
20 #include "clock_driver.h"
21 #include "gpio_driver.h"
22 #include "power_driver.h"
23 #include "qspi_driver.h"
24 #include "qspi_hal.h"
25 #include "qspi_statis.h"
26 #include "sys_driver.h"
27 #include <driver/gpio.h>
28 #include <driver/trng.h>
29
30 typedef struct {
31 qspi_hal_t hal;
32 uint8_t id_init_bits;
33 } qspi_driver_t;
34
35 typedef struct {
36 qspi_isr_t callback;
37 void *param;
38 } qspi_callback_t;
39
40 #define QSPI_RETURN_ON_NOT_INIT() do {\
41 if (!s_qspi_driver_is_init) {\
42 QSPI_LOGE("QSPI driver not init\r\n");\
43 return BK_ERR_QSPI_NOT_INIT;\
44 }\
45 } while(0)
46
47 #define QSPI_RETURN_ON_ID_NOT_INIT() do {\
48 if (!s_qspi.id_init_bits) {\
49 QSPI_LOGE("QSPI not init\r\n");\
50 return BK_ERR_QSPI_ID_NOT_INIT;\
51 }\
52 } while(0)
53
54 static qspi_driver_t s_qspi = {0};
55 static bool s_qspi_driver_is_init = false;
56 static qspi_callback_t s_qspi_tx_isr = {NULL};
57 static qspi_callback_t s_qspi_rx_isr = {NULL};
58
qspi_init_gpio(void)59 static void qspi_init_gpio(void)
60 {
61 #if (CONFIG_SYSTEM_CTRL)
62 gpio_dev_map(QSPI_LL_CLK_PIN, GPIO_DEV_QSPI_CLK);
63 gpio_dev_map(QSPI_LL_CSN_PIN, GPIO_DEV_QSPI_CSN);
64 bk_gpio_set_capacity(QSPI_LL_CLK_PIN, 3);
65 bk_gpio_set_capacity(QSPI_LL_CSN_PIN, 3);
66 #else
67 gpio_dev_map(QSPI_LL_RAM_CSN_PIN, GPIO_DEV_QSPI_RAM_CSN);
68 gpio_dev_map(QSPI_LL_RAM_CLK_PIN, GPIO_DEV_QSPI_RAM_CLK);
69 #endif
70 gpio_dev_map(QSPI_LL_IO0_PIN, GPIO_DEV_QSPI_IO0);
71 gpio_dev_map(QSPI_LL_IO1_PIN, GPIO_DEV_QSPI_IO1);
72 gpio_dev_map(QSPI_LL_IO2_PIN, GPIO_DEV_QSPI_IO2);
73 gpio_dev_map(QSPI_LL_IO3_PIN, GPIO_DEV_QSPI_IO3);
74 }
75
76
77 /* 1. power up qspi
78 * 2. set clock
79 * 3. set gpio as qspi
80 * 4. icu enable psram interrupt(fiq_int_enable)
81 * 5. sys_ctrl set psram voltage
82 * 6. sys_ctrl block_en
83 */
qspi_id_init_common(void)84 static void qspi_id_init_common(void)
85 {
86 #if (CONFIG_SYSTEM_CTRL)
87 sys_drv_dev_clk_pwr_up(CLK_PWR_ID_QSPI_1, CLK_PWR_CTRL_PWR_UP);
88 sys_drv_int_enable(QSPI_INTERRUPT_CTRL_BIT);
89 #else
90 power_qspi_pwr_up();
91 clk_set_qspi_clk_26m();
92 icu_enable_qspi_interrupt();
93 #endif
94 qspi_init_gpio();
95 qspi_hal_init_common(&s_qspi.hal);
96 }
97
qspi_id_deinit_common(void)98 static void qspi_id_deinit_common(void)
99 {
100 #if (CONFIG_SYSTEM_CTRL)
101 sys_drv_dev_clk_pwr_up(CLK_PWR_ID_QSPI_1, CLK_PWR_CTRL_PWR_DOWN);
102 sys_drv_int_disable(QSPI_INTERRUPT_CTRL_BIT);
103 #else
104 icu_disable_qspi_interrupt();
105 power_qspi_pwr_down();
106 #endif
107 qspi_hal_deinit_common(&s_qspi.hal);
108 }
109
110 #if (!CONFIG_SYSTEM_CTRL)
111 static void qspi_isr(void);
112 #endif
113
bk_qspi_driver_init(void)114 bk_err_t bk_qspi_driver_init(void)
115 {
116 if (s_qspi_driver_is_init) {
117 return BK_OK;
118 }
119
120 os_memset(&s_qspi, 0, sizeof(s_qspi));
121 #if (!CONFIG_SYSTEM_CTRL)
122 bk_int_isr_register(INT_SRC_PSRAM, qspi_isr, NULL);
123 #endif
124 qspi_hal_init(&s_qspi.hal);
125 qspi_statis_init();
126 s_qspi_driver_is_init = true;
127
128 return BK_OK;
129 }
130
bk_qspi_driver_deinit(void)131 bk_err_t bk_qspi_driver_deinit(void)
132 {
133 if (!s_qspi_driver_is_init) {
134 return BK_OK;
135 }
136 qspi_id_deinit_common();
137 #if (!CONFIG_SYSTEM_CTRL)
138 bk_int_isr_unregister(INT_SRC_PSRAM);
139 #endif
140 s_qspi_driver_is_init = false;
141
142 return BK_OK;
143 }
144
bk_qspi_init(const qspi_config_t * config)145 bk_err_t bk_qspi_init(const qspi_config_t *config)
146 {
147 BK_RETURN_ON_NULL(config);
148 QSPI_RETURN_ON_NOT_INIT();
149
150 qspi_id_init_common();
151 #if (!CONFIG_SYSTEM_CTRL)
152 switch (config->src_clk) {
153 case QSPI_SCLK_DCO:
154 clk_set_qspi_clk_dco();
155 break;
156 case QSPI_SCLK_80M:
157 clk_set_qspi_clk_80m();
158 break;
159 case QSPI_SCLK_120M:
160 clk_set_qspi_clk_120m();
161 break;
162 case QSPI_SCLK_XTAL_26M:
163 default:
164 clk_set_qspi_clk_26m();
165 break;
166 }
167 #else
168 switch (config->src_clk) {
169 case QSPI_SCLK_320M:
170 sys_drv_qspi_clk_sel(QSPI_CLK_320M);
171 break;
172 case QSPI_SCLK_480M:
173 sys_drv_qspi_clk_sel(QSPI_CLK_480M);
174 break;
175 default:
176 sys_drv_qspi_clk_sel(QSPI_CLK_480M);
177 break;
178 }
179 sys_drv_qspi_set_src_clk_div(config->src_clk_div);
180 #endif
181 qspi_hal_set_clk_div(&s_qspi.hal, config->clk_div);
182
183 s_qspi.id_init_bits |= BIT(0);
184 return BK_OK;
185 }
186
bk_qspi_deinit(void)187 bk_err_t bk_qspi_deinit(void)
188 {
189 qspi_id_deinit_common();
190 s_qspi.id_init_bits &= ~BIT(0);
191 return BK_OK;
192 }
193
bk_qspi_command(const qspi_cmd_t * cmd)194 bk_err_t bk_qspi_command(const qspi_cmd_t *cmd)
195 {
196 BK_RETURN_ON_NULL(cmd);
197 QSPI_RETURN_ON_ID_NOT_INIT();
198 qspi_hal_command(&s_qspi.hal, cmd);
199 return BK_OK;
200 }
201
bk_qspi_write(const void * data,uint32_t size)202 bk_err_t bk_qspi_write(const void *data, uint32_t size)
203 {
204 BK_RETURN_ON_NULL(data);
205
206 qspi_hal_io_write(&s_qspi.hal, data, size);
207
208 return BK_OK;
209 }
210
bk_qspi_read(void * data,uint32_t size)211 bk_err_t bk_qspi_read(void *data, uint32_t size)
212 {
213 BK_RETURN_ON_NULL(data);
214
215 qspi_hal_io_read(&s_qspi.hal, data, size);
216
217 return BK_OK;
218 }
219
bk_qspi_register_tx_isr(qspi_isr_t isr,void * param)220 bk_err_t bk_qspi_register_tx_isr(qspi_isr_t isr, void *param)
221 {
222 uint32_t int_level = rtos_disable_int();
223 s_qspi_tx_isr.callback = isr;
224 s_qspi_tx_isr.param = param;
225 rtos_enable_int(int_level);
226 return BK_OK;
227 }
228
bk_qspi_register_rx_isr(qspi_isr_t isr,void * param)229 bk_err_t bk_qspi_register_rx_isr(qspi_isr_t isr, void *param)
230 {
231 uint32_t int_level = rtos_disable_int();
232 s_qspi_rx_isr.callback = isr;
233 s_qspi_rx_isr.param = param;
234 rtos_enable_int(int_level);
235 return BK_OK;
236 }
237
238 #if (!CONFIG_SYSTEM_CTRL)
qspi_isr(void)239 static void qspi_isr(void)
240 {
241 qspi_hal_t *hal = &s_qspi.hal;
242 uint32_t int_status = 0;
243 QSPI_STATIS_DEC();
244 QSPI_STATIS_GET(qspi_statis);
245 QSPI_STATIS_INC(qspi_statis->qspi_int_cnt);
246
247 int_status = qspi_hal_get_interrupt_status_before_mask(hal);
248 QSPI_LOGD("int_status before mask:%x\r\n", int_status);
249
250 int_status = qspi_hal_get_interrupt_status_after_mask(hal);
251 QSPI_LOGD("int_status after mask:%x\r\n", int_status);
252 qspi_hal_clear_interrupt_status(hal, int_status);
253
254 if (qspi_hal_is_sw_op_int_triggered(hal, int_status)) {
255 QSPI_STATIS_INC(qspi_statis->sw_op_int_cnt);
256 QSPI_LOGD("sw op int triggered\r\n");
257 qspi_hal_clear_sw_op_int(hal);
258 qspi_hal_stop_sw_op(hal);
259 if (qspi_hal_is_cur_sw_op_write_data()) {
260 qspi_hal_disable_ge0_tx(hal);
261 if (s_qspi_tx_isr.callback) {
262 s_qspi_tx_isr.callback(0, s_qspi_tx_isr.param);
263 }
264 }
265
266 if (qspi_hal_is_cur_sw_op_read_data()) {
267 qspi_hal_disable_ge1_rx(hal);
268 if (s_qspi_rx_isr.callback) {
269 s_qspi_rx_isr.callback(0, s_qspi_rx_isr.param);
270 }
271 }
272 }
273 }
274 #endif
275