• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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