• 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/dma.h>
16 #include <driver/gpio.h>
17 #include <driver/int.h>
18 #include <driver/spi.h>
19 #include "clock_driver.h"
20 #include "dma_hal.h"
21 #include "gpio_driver.h"
22 #include "icu_driver.h"
23 #include <common/bk_include.h>
24 #include <os/mem.h>
25 #include "power_driver.h"
26 #include <os/os.h>
27 #include "spi_driver.h"
28 #include "spi_hal.h"
29 #include "spi_statis.h"
30 #include "spi_config.h"
31 #include "sys_driver.h"
32 
33 typedef struct {
34 	spi_hal_t hal;
35 	uint8_t id_init_bits;
36 	uint8_t * tx_buf;
37 	uint32_t tx_size;
38 	uint8_t * rx_buf;
39 	uint32_t rx_size;
40 	volatile uint32_t rx_offset;
41 	bool is_tx_blocked;
42 	bool is_sw_tx_finished;
43 	bool is_rx_blocked;
44 	beken_semaphore_t tx_sema;
45 	beken_semaphore_t rx_sema;
46 	dma_id_t spi_tx_dma_chan;
47 	dma_id_t spi_rx_dma_chan;
48 } spi_driver_t;
49 
50 typedef struct {
51 	spi_isr_t callback;
52 	void *param;
53 } spi_callback_t;
54 
55 #define SPI_RETURN_ON_NOT_INIT() do {\
56 	if (!s_spi_driver_is_init) {\
57 		SPI_LOGE("SPI driver not init\r\n");\
58 		return BK_ERR_SPI_NOT_INIT;\
59 	}\
60 } while(0)
61 
62 #define SPI_RETURN_ON_ID_NOT_INIT(id) do {\
63 	if (!s_spi[id].id_init_bits) {\
64 		SPI_LOGE("SPI(%d) not init\r\n", id);\
65 		return BK_ERR_SPI_ID_NOT_INIT;\
66 	}\
67 } while(0)
68 
69 #define SPI_RETURN_ON_INVALID_ID(id) do {\
70 	if ((id) >= SOC_SPI_UNIT_NUM) {\
71 		SPI_LOGE("SPI id number(%d) is invalid\r\n", (id));\
72 		return BK_ERR_SPI_INVALID_ID;\
73 	}\
74 } while(0)
75 
76 #define SPI_SET_PIN(id) do {\
77 	gpio_dev_unmap(SPI##id##_LL_CSN_PIN);\
78 	gpio_dev_unmap(SPI##id##_LL_SCK_PIN);\
79 	gpio_dev_unmap(SPI##id##_LL_MOSI_PIN);\
80 	gpio_dev_unmap(SPI##id##_LL_MISO_PIN);\
81 	gpio_dev_map(SPI##id##_LL_CSN_PIN, GPIO_DEV_SPI##id##_CSN);\
82 	gpio_dev_map(SPI##id##_LL_SCK_PIN, GPIO_DEV_SPI##id##_SCK);\
83 	gpio_dev_map(SPI##id##_LL_MOSI_PIN, GPIO_DEV_SPI##id##_MOSI);\
84 	gpio_dev_map(SPI##id##_LL_MISO_PIN, GPIO_DEV_SPI##id##_MISO);\
85 	bk_gpio_pull_up(SPI##id##_LL_CSN_PIN);\
86 	bk_gpio_pull_up(SPI##id##_LL_SCK_PIN);\
87 } while(0)
88 
89 static spi_driver_t s_spi[SOC_SPI_UNIT_NUM] = {0};
90 static bool s_spi_driver_is_init = false;
91 static volatile spi_id_t s_current_spi_dma_wr_id;
92 static volatile spi_id_t s_current_spi_dma_rd_id;
93 static spi_callback_t s_spi_rx_isr[SOC_SPI_UNIT_NUM] = {NULL};
94 static spi_callback_t s_spi_tx_finish_isr[SOC_SPI_UNIT_NUM] = {NULL};
95 static spi_callback_t s_spi_rx_finish_isr[SOC_SPI_UNIT_NUM] = {NULL};
96 
97 static void spi_isr(void);
98 #if (SOC_SPI_UNIT_NUM > 1)
99 static void spi2_isr(void);
100 #endif
101 #if (SOC_SPI_UNIT_NUM > 2)
102 static void spi3_isr(void);
103 #endif
104 
spi_init_gpio(spi_id_t id)105 static void spi_init_gpio(spi_id_t id)
106 {
107 	switch (id) {
108 	case SPI_ID_0:
109 		SPI_SET_PIN(0);
110 		break;
111 #if (SOC_SPI_UNIT_NUM > 1)
112 	case SPI_ID_1:
113 		SPI_SET_PIN(1);
114 		break;
115 #endif
116 #if (SOC_SPI_UNIT_NUM > 2)
117 	case SPI_ID_2:
118 		SPI_SET_PIN(2);
119 		break;
120 #endif
121 	default:
122 		break;
123 	}
124 #if (!CONFIG_SYSTEM_CTRL)
125 	gpio_spi_sel(GPIO_SPI_MAP_MODE1);
126 #endif
127 }
128 
129 #if (CONFIG_SYSTEM_CTRL)
spi_clock_enable(spi_id_t id)130 static void spi_clock_enable(spi_id_t id)
131 {
132 	switch(id)
133 	{
134 		case SPI_ID_0:
135 			sys_drv_dev_clk_pwr_up(CLK_PWR_ID_SPI_1, CLK_PWR_CTRL_PWR_UP);
136 			break;
137 #if (SOC_SPI_UNIT_NUM > 1)
138 		case SPI_ID_1:
139 			sys_drv_dev_clk_pwr_up(CLK_PWR_ID_SPI_2, CLK_PWR_CTRL_PWR_UP);
140 			break;
141 #endif
142 		default:
143 			break;
144 	}
145 }
146 
spi_clock_disable(spi_id_t id)147 static void spi_clock_disable(spi_id_t id)
148 {
149 	switch(id)
150 	{
151 		case SPI_ID_0:
152 			sys_drv_dev_clk_pwr_up(CLK_PWR_ID_SPI_1, CLK_PWR_CTRL_PWR_DOWN);
153 			break;
154 #if (SOC_SPI_UNIT_NUM > 1)
155 		case SPI_ID_1:
156 			sys_drv_dev_clk_pwr_up(CLK_PWR_ID_SPI_2, CLK_PWR_CTRL_PWR_DOWN);
157 			break;
158 #endif
159 		default:
160 			break;
161 	}
162 }
163 
spi_interrupt_enable(spi_id_t id)164 static void spi_interrupt_enable(spi_id_t id)
165 {
166 	switch(id)
167 	{
168 		case SPI_ID_0:
169 			sys_drv_int_enable(SPI_INTERRUPT_CTRL_BIT);
170 			break;
171 #if (SOC_SPI_UNIT_NUM > 1)
172 		case SPI_ID_1:
173 			sys_drv_int_enable(SPI1_INTERRUPT_CTRL_BIT);
174 			break;
175 #endif
176 		default:
177 			break;
178 	}
179 }
180 
spi_interrupt_disable(spi_id_t id)181 static void spi_interrupt_disable(spi_id_t id)
182 {
183 	switch(id)
184 	{
185 		case SPI_ID_0:
186 			sys_drv_int_disable(SPI_INTERRUPT_CTRL_BIT);
187 			break;
188 #if (SOC_SPI_UNIT_NUM > 1)
189 		case SPI_ID_1:
190 			sys_drv_int_disable(SPI1_INTERRUPT_CTRL_BIT);
191 			break;
192 #endif
193 		default:
194 			break;
195 	}
196 }
197 #endif
198 
199 /* 1. power up spi
200  * 2. set clk
201  * 3. set gpio as spi
202  * 4. icu enable interrupt
203  */
spi_id_init_common(spi_id_t id)204 static bk_err_t spi_id_init_common(spi_id_t id)
205 {
206 	int ret = 0;
207 
208 #if (CONFIG_SYSTEM_CTRL)
209 	spi_clock_enable(id);
210 	spi_interrupt_enable(id);
211 #else
212 	power_up_spi(id);
213 	clk_set_spi_clk_26m(id);
214 	icu_enable_spi_interrupt(id);
215 #endif
216 	spi_init_gpio(id);
217 
218 	if (s_spi[id].tx_sema == NULL) {
219 		ret = rtos_init_semaphore(&(s_spi[id].tx_sema), 1);
220 		BK_ASSERT(kNoErr == ret);
221 	}
222 	if (s_spi[id].rx_sema == NULL) {
223 		ret = rtos_init_semaphore(&(s_spi[id].rx_sema), 1);
224 		BK_ASSERT(kNoErr == ret);
225 	}
226 	s_spi[id].is_tx_blocked = false;
227 	s_spi[id].is_sw_tx_finished = true;
228 	s_spi[id].is_rx_blocked = false;
229 	s_spi[id].id_init_bits |= BIT(id);
230 
231 	return ret;
232 }
233 
spi_id_deinit_common(spi_id_t id)234 static void spi_id_deinit_common(spi_id_t id)
235 {
236 	spi_hal_stop_common(&s_spi[id].hal);
237 
238 #if (CONFIG_SYSTEM_CTRL)
239 	spi_clock_disable(id);
240 	spi_interrupt_disable(id);
241 #else
242 	icu_disable_spi_interrupt(id);
243 	power_down_spi(id);
244 #endif
245 	rtos_deinit_semaphore(&(s_spi[id].tx_sema));
246 	rtos_deinit_semaphore(&(s_spi[id].rx_sema));
247 	s_spi[id].id_init_bits &= ~BIT(id);
248 }
249 
spi_id_write_bytes_common(spi_id_t id)250 static void spi_id_write_bytes_common(spi_id_t id)
251 {
252 	for (int i = 0; i < s_spi[id].tx_size; i++) {
253 		BK_WHILE (!spi_hal_is_tx_fifo_wr_ready(&s_spi[id].hal));
254 		spi_hal_write_byte(&s_spi[id].hal, s_spi[id].tx_buf[i]);
255 	}
256 }
257 
spi_id_read_bytes_common(spi_id_t id)258 static uint32_t spi_id_read_bytes_common(spi_id_t id)
259 {
260 	uint8_t data = 0;
261 	uint32_t offset = s_spi[id].rx_offset;
262 
263 	while (spi_hal_read_byte(&s_spi[id].hal, &data) == BK_OK) {
264 		if ((s_spi[id].rx_buf) && (offset < s_spi[id].rx_size)) {
265 			s_spi[id].rx_buf[offset++] = data;
266 		}
267 	}
268 	s_spi[id].rx_offset = offset;
269 	SPI_LOGD("spi offset:%d\r\n", s_spi[id].rx_offset);
270 	return offset;
271 }
272 
273 #if CONFIG_SPI_DMA
274 
spi_dma_tx_finish_handler(dma_id_t id)275 static void spi_dma_tx_finish_handler(dma_id_t id)
276 {
277 	SPI_LOGI("[%s] spi_id:%d\r\n", __func__, s_current_spi_dma_wr_id);
278 }
279 
spi_dma_rx_finish_handler(dma_id_t id)280 static void spi_dma_rx_finish_handler(dma_id_t id)
281 {
282 	SPI_LOGI("[%s] spi_id:%d\r\n", __func__, s_current_spi_dma_rd_id);
283 	if (s_spi_rx_finish_isr[s_current_spi_dma_rd_id].callback){
284 		s_spi_rx_finish_isr[s_current_spi_dma_rd_id].callback(s_current_spi_dma_rd_id,s_spi_rx_finish_isr[s_current_spi_dma_rd_id].param);
285 	}
286 	if (s_spi[s_current_spi_dma_rd_id].is_rx_blocked) {
287 		rtos_set_semaphore(&s_spi[s_current_spi_dma_rd_id].rx_sema);
288 		s_spi[s_current_spi_dma_rd_id].is_rx_blocked = false;
289 	}
290 }
291 
spi_dma_tx_init(spi_id_t id,dma_id_t spi_tx_dma_chan)292 static void spi_dma_tx_init(spi_id_t id, dma_id_t spi_tx_dma_chan)
293 {
294 	dma_config_t dma_config = {0};
295 	spi_int_config_t int_cfg_table[] = SPI_INT_CONFIG_TABLE;
296 
297 	s_spi[id].spi_tx_dma_chan = spi_tx_dma_chan;
298 
299 	dma_config.mode = DMA_WORK_MODE_SINGLE;
300 	dma_config.chan_prio = 0;
301 	dma_config.src.dev = DMA_DEV_DTCM;
302 	dma_config.src.width = DMA_DATA_WIDTH_32BITS;
303 	dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE;
304 	dma_config.src.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
305 	dma_config.dst.width = DMA_DATA_WIDTH_8BITS;
306 	dma_config.dst.start_addr = SPI_R_DATA(id);
307 	dma_config.dst.dev = int_cfg_table[id].dma_dev;
308 
309 	BK_LOG_ON_ERR(bk_dma_init(spi_tx_dma_chan, &dma_config));
310 	BK_LOG_ON_ERR(bk_dma_register_isr(spi_tx_dma_chan, NULL, spi_dma_tx_finish_handler));
311 	BK_LOG_ON_ERR(bk_dma_enable_finish_interrupt(spi_tx_dma_chan));
312 }
313 
spi_dma_rx_init(spi_id_t id,dma_id_t spi_rx_dma_chan)314 static void spi_dma_rx_init(spi_id_t id, dma_id_t spi_rx_dma_chan)
315 {
316 	dma_config_t dma_config = {0};
317 	spi_int_config_t int_cfg_table[] = SPI_INT_CONFIG_TABLE;
318 
319 	s_spi[id].spi_rx_dma_chan = spi_rx_dma_chan;
320 
321 	dma_config.mode = DMA_WORK_MODE_SINGLE;
322 	dma_config.chan_prio = 0;
323 	dma_config.src.dev = int_cfg_table[id].dma_dev;
324 	dma_config.src.width = DMA_DATA_WIDTH_8BITS;
325 	dma_config.src.start_addr = SPI_R_DATA(id);
326 	dma_config.dst.dev = DMA_DEV_DTCM;
327 	dma_config.dst.width = DMA_DATA_WIDTH_32BITS;
328 	dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE;
329 	dma_config.dst.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
330 
331 	BK_LOG_ON_ERR(bk_dma_init(spi_rx_dma_chan, &dma_config));
332 	BK_LOG_ON_ERR(bk_dma_register_isr(spi_rx_dma_chan, NULL, spi_dma_rx_finish_handler));
333 	BK_LOG_ON_ERR(bk_dma_enable_finish_interrupt(spi_rx_dma_chan));
334 }
335 
336 #endif /* CONFIG_SPI_DMA */
337 
bk_spi_driver_init(void)338 bk_err_t bk_spi_driver_init(void)
339 {
340 	if (s_spi_driver_is_init) {
341 		return BK_OK;
342 	}
343 
344 	spi_int_config_t int_config_table[] = SPI_INT_CONFIG_TABLE;
345 
346 	os_memset(&s_spi, 0, sizeof(s_spi));
347 	os_memset(&s_spi_rx_isr, 0, sizeof(s_spi_rx_isr));
348 	os_memset(&s_spi_tx_finish_isr, 0, sizeof(s_spi_tx_finish_isr));
349 
350 	for (int id = SPI_ID_0; id < SPI_ID_MAX; id++) {
351 		spi_int_config_t *cur_int_cfg = &int_config_table[id];
352 		bk_int_isr_register(cur_int_cfg->int_src, cur_int_cfg->isr, NULL);
353 		s_spi[id].hal.id = id;
354 		spi_hal_init(&s_spi[id].hal);
355 	}
356 	spi_statis_init();
357 	s_spi_driver_is_init = true;
358 
359 	return BK_OK;
360 }
361 
bk_spi_driver_deinit(void)362 bk_err_t bk_spi_driver_deinit(void)
363 {
364 	if (!s_spi_driver_is_init) {
365 		return BK_OK;
366 	}
367 	spi_int_config_t int_cfg_table[] = SPI_INT_CONFIG_TABLE;
368 	for (int id = SPI_ID_0; id < SPI_ID_MAX; id++) {
369 		spi_id_deinit_common(id);
370 		bk_int_isr_unregister(int_cfg_table[id].int_src);
371 	}
372 	s_spi_driver_is_init = false;
373 
374 	return BK_OK;
375 }
376 
bk_spi_init(spi_id_t id,const spi_config_t * config)377 bk_err_t bk_spi_init(spi_id_t id, const spi_config_t *config)
378 {
379 	BK_RETURN_ON_NULL(config);
380 	SPI_RETURN_ON_NOT_INIT();
381 	SPI_RETURN_ON_INVALID_ID(id);
382 
383 	spi_id_init_common(id);
384 	spi_hal_configure(&s_spi[id].hal, config);
385 	spi_hal_start_common(&s_spi[id].hal);
386 #if (CONFIG_SPI_DMA)
387 	if (config->dma_mode) {
388 #if (!CONFIG_SYSTEM_CTRL)
389 		gpio_spi_sel(GPIO_SPI_MAP_MODE0);
390 #endif
391 		spi_dma_tx_init(id, config->spi_tx_dma_chan);
392 		spi_dma_rx_init(id, config->spi_rx_dma_chan);
393 	}
394 #endif
395 
396 	return BK_OK;
397 }
398 
399 
bk_spi_deinit(spi_id_t id)400 bk_err_t bk_spi_deinit(spi_id_t id)
401 {
402 	SPI_RETURN_ON_NOT_INIT();
403 	SPI_RETURN_ON_INVALID_ID(id);
404 	spi_id_deinit_common(id);
405 	return BK_OK;
406 }
407 
bk_spi_set_mode(spi_id_t id,spi_mode_t mode)408 bk_err_t bk_spi_set_mode(spi_id_t id, spi_mode_t mode)
409 {
410 	SPI_RETURN_ON_NOT_INIT();
411 	SPI_RETURN_ON_INVALID_ID(id);
412 
413 	spi_hal_t *hal = &s_spi[id].hal;
414 	switch (mode) {
415 	case SPI_POL_MODE_0:
416 		spi_hal_set_cpol(hal, SPI_POLARITY_LOW);
417 		spi_hal_set_cpha(hal, SPI_PHASE_1ST_EDGE);
418 		break;
419 	case SPI_POL_MODE_1:
420 		spi_hal_set_cpol(hal, SPI_POLARITY_LOW);
421 		spi_hal_set_cpha(hal, SPI_PHASE_2ND_EDGE);
422 		break;
423 	case SPI_POL_MODE_2:
424 		spi_hal_set_cpol(hal, SPI_POLARITY_HIGH);
425 		spi_hal_set_cpha(hal, SPI_PHASE_1ST_EDGE);
426 		break;
427 	case SPI_POL_MODE_3:
428 	default:
429 		spi_hal_set_cpol(hal, SPI_POLARITY_HIGH);
430 		spi_hal_set_cpha(hal, SPI_PHASE_2ND_EDGE);
431 		break;
432 	}
433 	return BK_OK;
434 }
435 
bk_spi_set_bit_width(spi_id_t id,spi_bit_width_t bit_width)436 bk_err_t bk_spi_set_bit_width(spi_id_t id, spi_bit_width_t bit_width)
437 {
438 	SPI_RETURN_ON_NOT_INIT();
439 	SPI_RETURN_ON_INVALID_ID(id);
440 	spi_hal_set_bit_width(&s_spi[id].hal, bit_width);
441 	return BK_OK;
442 }
443 
bk_spi_set_wire_mode(spi_id_t id,spi_wire_mode_t wire_mode)444 bk_err_t bk_spi_set_wire_mode(spi_id_t id, spi_wire_mode_t wire_mode)
445 {
446 	SPI_RETURN_ON_NOT_INIT();
447 	SPI_RETURN_ON_INVALID_ID(id);
448 	spi_hal_set_wire_mode(&s_spi[id].hal, wire_mode);
449 	return BK_OK;
450 }
451 
bk_spi_set_baud_rate(spi_id_t id,uint32_t baud_rate)452 bk_err_t bk_spi_set_baud_rate(spi_id_t id, uint32_t baud_rate)
453 {
454 	SPI_RETURN_ON_NOT_INIT();
455 	SPI_RETURN_ON_INVALID_ID(id);
456 	spi_hal_set_baud_rate(&s_spi[id].hal, baud_rate);
457 	return BK_OK;
458 }
459 
bk_spi_set_bit_order(spi_id_t id,spi_bit_order_t bit_order)460 bk_err_t bk_spi_set_bit_order(spi_id_t id, spi_bit_order_t bit_order)
461 {
462 	SPI_RETURN_ON_NOT_INIT();
463 	SPI_RETURN_ON_INVALID_ID(id);
464 	spi_hal_set_first_bit(&s_spi[id].hal, bit_order);
465 	return BK_OK;
466 }
467 
bk_spi_register_rx_isr(spi_id_t id,spi_isr_t isr,void * param)468 bk_err_t bk_spi_register_rx_isr(spi_id_t id, spi_isr_t isr, void *param)
469 {
470 	SPI_RETURN_ON_INVALID_ID(id);
471 	uint32_t int_level = rtos_disable_int();
472 	s_spi_rx_isr[id].callback = isr;
473 	s_spi_rx_isr[id].param = param;
474 	rtos_enable_int(int_level);
475 	return BK_OK;
476 }
477 
bk_spi_register_rx_finish_isr(spi_id_t id,spi_isr_t isr,void * param)478 bk_err_t bk_spi_register_rx_finish_isr(spi_id_t id, spi_isr_t isr, void *param)
479 {
480 	SPI_RETURN_ON_INVALID_ID(id);
481 	uint32_t int_level = rtos_disable_int();
482 	s_spi_rx_finish_isr[id].callback = isr;
483 	s_spi_rx_finish_isr[id].param = param;
484 	rtos_enable_int(int_level);
485 	return BK_OK;
486 }
487 
488 
bk_spi_register_tx_finish_isr(spi_id_t id,spi_isr_t isr,void * param)489 bk_err_t bk_spi_register_tx_finish_isr(spi_id_t id, spi_isr_t isr, void *param)
490 {
491 	SPI_RETURN_ON_INVALID_ID(id);
492 	uint32_t int_level = rtos_disable_int();
493 	s_spi_tx_finish_isr[id].callback = isr;
494 	s_spi_tx_finish_isr[id].param = param;
495 	rtos_enable_int(int_level);
496 	return BK_OK;
497 }
498 
bk_spi_unregister_rx_isr(spi_id_t id)499 bk_err_t bk_spi_unregister_rx_isr(spi_id_t id)
500 {
501 	SPI_RETURN_ON_INVALID_ID(id);
502 	uint32_t int_level = rtos_disable_int();
503 	s_spi_rx_isr[id].callback = NULL;
504 	s_spi_rx_isr[id].param = NULL;
505 	rtos_enable_int(int_level);
506 	return BK_OK;
507 }
508 
bk_spi_unregister_rx_finish_isr(spi_id_t id)509 bk_err_t bk_spi_unregister_rx_finish_isr(spi_id_t id)
510 {
511 	SPI_RETURN_ON_INVALID_ID(id);
512 	uint32_t int_level = rtos_disable_int();
513 	s_spi_rx_finish_isr[id].callback = NULL;
514 	s_spi_rx_finish_isr[id].param = NULL;
515 	rtos_enable_int(int_level);
516 	return BK_OK;
517 }
518 
519 
bk_spi_unregister_tx_finish_isr(spi_id_t id)520 bk_err_t bk_spi_unregister_tx_finish_isr(spi_id_t id)
521 {
522 	SPI_RETURN_ON_INVALID_ID(id);
523 	uint32_t int_level = rtos_disable_int();
524 	s_spi_tx_finish_isr[id].callback = NULL;
525 	s_spi_tx_finish_isr[id].param = NULL;
526 	rtos_enable_int(int_level);
527 	return BK_OK;
528 }
529 
530 
bk_spi_write_bytes(spi_id_t id,const void * data,uint32_t size)531 bk_err_t bk_spi_write_bytes(spi_id_t id, const void *data, uint32_t size)
532 {
533 	SPI_RETURN_ON_NOT_INIT();
534 	SPI_RETURN_ON_INVALID_ID(id);
535 	SPI_RETURN_ON_ID_NOT_INIT(id);
536 	BK_RETURN_ON_NULL(data);
537 
538 	uint32_t int_level = rtos_disable_int();
539 	s_spi[id].tx_buf = (uint8_t *)data;
540 	s_spi[id].tx_size = size;
541 	s_spi[id].is_sw_tx_finished = false;
542 	s_spi[id].is_tx_blocked = true;
543 	s_spi[id].rx_size = size;
544 	s_spi[id].rx_offset = 0;
545 	spi_hal_clear_tx_fifo(&s_spi[id].hal);
546 	spi_hal_set_tx_trans_len(&s_spi[id].hal, size);
547 #if CONFIG_SPI_SUPPORT_TX_FIFO_WR_READY
548 	spi_hal_disable_tx_fifo_int(&s_spi[id].hal);
549 #else
550 	spi_hal_enable_tx_fifo_int(&s_spi[id].hal);
551 #endif
552 	spi_hal_enable_tx(&s_spi[id].hal);
553 	rtos_enable_int(int_level);
554 
555 #if CONFIG_SPI_SUPPORT_TX_FIFO_WR_READY
556 	s_spi[id].is_sw_tx_finished = true;
557 	spi_id_write_bytes_common(id); /* to solve slave write */
558 #endif
559 
560 	rtos_get_semaphore(&s_spi[id].tx_sema, BEKEN_NEVER_TIMEOUT);
561 
562 	int_level = rtos_disable_int();
563 	spi_hal_disable_tx_fifo_int(&s_spi[id].hal);
564 	spi_hal_disable_tx(&s_spi[id].hal);
565 	rtos_enable_int(int_level);
566 
567 	return BK_OK;
568 }
569 
bk_spi_read_bytes(spi_id_t id,void * data,uint32_t size)570 bk_err_t bk_spi_read_bytes(spi_id_t id, void *data, uint32_t size)
571 {
572 	SPI_RETURN_ON_NOT_INIT();
573 	SPI_RETURN_ON_INVALID_ID(id);
574 	SPI_RETURN_ON_ID_NOT_INIT(id);
575 	BK_RETURN_ON_NULL(data);
576 
577 	uint32_t int_level = rtos_disable_int();
578 	s_spi[id].rx_size = size;
579 	s_spi[id].rx_buf = (uint8_t *)data;
580 	s_spi[id].rx_offset = 0;
581 	s_spi[id].is_rx_blocked = true;
582 	spi_hal_set_rx_trans_len(&s_spi[id].hal, size);
583 	spi_hal_clear_rx_fifo(&s_spi[id].hal);
584 	spi_hal_enable_rx_fifo_int(&s_spi[id].hal);
585 	spi_hal_enable_rx_finish_int(&s_spi[id].hal);
586 	spi_hal_enable_rx(&s_spi[id].hal);
587 #if !CONFIG_SPI_SUPPORT_TX_FIFO_WR_READY
588 	/* special for bk7251, bk7251 need enable tx fifo int, otherwize spi_isr will not triggered */
589 	spi_hal_enable_tx_fifo_int(&s_spi[id].hal);
590 #endif
591 	rtos_enable_int(int_level);
592 
593 	rtos_get_semaphore(&(s_spi[id].rx_sema), BEKEN_NEVER_TIMEOUT);
594 
595 	int_level = rtos_disable_int();
596 	spi_hal_disable_rx(&s_spi[id].hal);
597 	spi_hal_disable_tx_fifo_int(&s_spi[id].hal);
598 	spi_hal_disable_rx_fifo_int(&s_spi[id].hal);
599 	s_spi[id].rx_size = 0;
600 	s_spi[id].rx_offset = 0;
601 	s_spi[id].rx_buf = NULL;
602 	rtos_enable_int(int_level);
603 
604 	return BK_OK;
605 }
606 
bk_spi_transmit(spi_id_t id,const void * tx_data,uint32_t tx_size,void * rx_data,uint32_t rx_size)607 bk_err_t bk_spi_transmit(spi_id_t id, const void *tx_data, uint32_t tx_size, void *rx_data, uint32_t rx_size)
608 {
609 	SPI_RETURN_ON_INVALID_ID(id);
610 	SPI_RETURN_ON_ID_NOT_INIT(id);
611 
612 	if (tx_size && tx_data) {
613 		BK_LOG_ON_ERR(bk_spi_write_bytes(id, tx_data, tx_size));
614 	}
615 
616 	if (rx_size && rx_data) {
617 		BK_LOG_ON_ERR(bk_spi_read_bytes(id, rx_data, rx_size));
618 	}
619 
620 	return BK_OK;
621 }
622 
623 
bk_spi_clr_tx(spi_id_t id)624 bk_err_t bk_spi_clr_tx(spi_id_t id)
625 {
626     spi_hal_disable_tx_fifo_int(&s_spi[id].hal);
627     spi_hal_disable_tx(&s_spi[id].hal);
628     return BK_OK;
629 }
630 
bk_spi_clr_rx(spi_id_t id)631 bk_err_t bk_spi_clr_rx(spi_id_t id)
632 {
633     spi_hal_disable_rx(&s_spi[id].hal);
634     spi_hal_disable_tx_fifo_int(&s_spi[id].hal);
635     spi_hal_disable_rx_fifo_int(&s_spi[id].hal);
636     s_spi[id].rx_size = 0;
637     s_spi[id].rx_offset = 0;
638     s_spi[id].rx_buf = NULL;
639     return BK_OK;
640 }
641 
642 
bk_spi_write_bytes_async(spi_id_t id,const void * data,uint32_t size)643 bk_err_t bk_spi_write_bytes_async(spi_id_t id, const void *data, uint32_t size)
644 {
645 	SPI_RETURN_ON_NOT_INIT();
646 	SPI_RETURN_ON_INVALID_ID(id);
647 	SPI_RETURN_ON_ID_NOT_INIT(id);
648 	BK_RETURN_ON_NULL(data);
649 
650 	uint32_t int_level = rtos_disable_int();
651 	s_spi[id].tx_buf = (uint8_t *)data;
652 	s_spi[id].tx_size = size;
653 	s_spi[id].is_sw_tx_finished = false;
654 	s_spi[id].is_tx_blocked = false;
655 	s_spi[id].rx_size = size;
656 	s_spi[id].rx_offset = 0;
657 	spi_hal_clear_tx_fifo(&s_spi[id].hal);
658 	spi_hal_set_tx_trans_len(&s_spi[id].hal, size);
659 #if CONFIG_SPI_SUPPORT_TX_FIFO_WR_READY
660 	spi_hal_disable_tx_fifo_int(&s_spi[id].hal);
661 #else
662 	spi_hal_enable_tx_fifo_int(&s_spi[id].hal);
663 #endif
664 	spi_hal_enable_tx(&s_spi[id].hal);
665 	rtos_enable_int(int_level);
666 
667 #if CONFIG_SPI_SUPPORT_TX_FIFO_WR_READY
668 	s_spi[id].is_sw_tx_finished = true;
669 	spi_id_write_bytes_common(id); /* to solve slave write */
670 #endif
671 
672 	return BK_OK;
673 }
674 
bk_spi_read_bytes_async(spi_id_t id,void * data,uint32_t size)675 bk_err_t bk_spi_read_bytes_async(spi_id_t id, void *data, uint32_t size)
676 {
677 	SPI_RETURN_ON_NOT_INIT();
678 	SPI_RETURN_ON_INVALID_ID(id);
679 	SPI_RETURN_ON_ID_NOT_INIT(id);
680 	BK_RETURN_ON_NULL(data);
681 
682 	uint32_t int_level = rtos_disable_int();
683 	s_spi[id].rx_size = size;
684 	s_spi[id].rx_buf = (uint8_t *)data;
685 	s_spi[id].rx_offset = 0;
686 	s_spi[id].is_rx_blocked = false;
687 	spi_hal_set_rx_trans_len(&s_spi[id].hal, size);
688 	spi_hal_clear_rx_fifo(&s_spi[id].hal);
689 	spi_hal_enable_rx_fifo_int(&s_spi[id].hal);
690 	spi_hal_enable_rx_finish_int(&s_spi[id].hal);
691 	spi_hal_enable_rx(&s_spi[id].hal);
692 #if !CONFIG_SPI_SUPPORT_TX_FIFO_WR_READY
693 	/* special for bk7251, bk7251 need enable tx fifo int, otherwize spi_isr will not triggered */
694 	spi_hal_enable_tx_fifo_int(&s_spi[id].hal);
695 #endif
696 	rtos_enable_int(int_level);
697 
698 	return BK_OK;
699 }
700 
701 
702 #if CONFIG_SPI_DMA
703 
bk_spi_dma_write_bytes(spi_id_t id,const void * data,uint32_t size)704 bk_err_t bk_spi_dma_write_bytes(spi_id_t id, const void *data, uint32_t size)
705 {
706 	BK_RETURN_ON_NULL(data);
707 	SPI_RETURN_ON_INVALID_ID(id);
708 	SPI_RETURN_ON_ID_NOT_INIT(id);
709 
710 	uint32_t int_level = rtos_disable_int();
711 	s_spi[id].is_tx_blocked = true;
712 	s_current_spi_dma_wr_id = id;
713 	spi_hal_set_tx_trans_len(&s_spi[id].hal, size);
714 	spi_hal_enable_tx(&s_spi[id].hal);
715 	rtos_enable_int(int_level);
716 	bk_dma_write(s_spi[id].spi_tx_dma_chan, (uint8_t *)data, size);
717 
718 	rtos_get_semaphore(&s_spi[id].tx_sema, BEKEN_NEVER_TIMEOUT);
719 
720 	int_level = rtos_disable_int();
721 	spi_hal_disable_tx(&s_spi[id].hal);
722 	bk_dma_stop(s_spi[id].spi_tx_dma_chan);
723 	rtos_enable_int(int_level);
724 	return BK_OK;
725 }
726 
bk_spi_dma_read_bytes(spi_id_t id,void * data,uint32_t size)727 bk_err_t bk_spi_dma_read_bytes(spi_id_t id, void *data, uint32_t size)
728 {
729 	SPI_RETURN_ON_INVALID_ID(id);
730 	SPI_RETURN_ON_ID_NOT_INIT(id);
731 	BK_RETURN_ON_NULL(data);
732 
733 	uint32_t int_level = rtos_disable_int();
734 	s_current_spi_dma_rd_id = id;
735 	s_spi[id].is_rx_blocked = true;
736 	spi_hal_set_rx_trans_len(&s_spi[id].hal, size);
737 	spi_hal_clear_rx_fifo(&s_spi[id].hal);
738 	spi_hal_disable_rx_fifo_int(&s_spi[id].hal);
739 	spi_hal_enable_rx(&s_spi[id].hal);
740 	rtos_enable_int(int_level);
741 	bk_dma_read(s_spi[id].spi_rx_dma_chan, (uint8_t *)data, size);
742 
743 	rtos_get_semaphore(&s_spi[id].rx_sema, BEKEN_NEVER_TIMEOUT);
744 
745 	int_level = rtos_disable_int();
746 	spi_hal_disable_rx(&s_spi[id].hal);
747 	bk_dma_stop(s_spi[id].spi_rx_dma_chan);
748 	rtos_enable_int(int_level);
749 	return BK_OK;
750 }
751 
bk_spi_dma_transmit(spi_id_t id,const void * tx_data,uint32_t tx_size,void * rx_data,uint32_t rx_size)752 bk_err_t bk_spi_dma_transmit(spi_id_t id, const void *tx_data, uint32_t tx_size, void *rx_data, uint32_t rx_size)
753 {
754 	SPI_RETURN_ON_INVALID_ID(id);
755 	SPI_RETURN_ON_ID_NOT_INIT(id);
756 
757 	if (tx_size && tx_data) {
758 		BK_LOG_ON_ERR(bk_spi_dma_write_bytes(id, tx_data, tx_size));
759 	}
760 
761 	if (rx_size && rx_data) {
762 		BK_LOG_ON_ERR(bk_spi_dma_read_bytes(id, rx_data, rx_size));
763 	}
764 
765 	return BK_OK;
766 }
767 
768 #endif
769 
spi_isr_common(spi_id_t id)770 static void spi_isr_common(spi_id_t id)
771 {
772 	spi_hal_t *hal = &s_spi[id].hal;
773 	uint8_t rd_data = 0;
774 	uint32_t int_status = 0;
775 	uint32_t rd_offset = s_spi[id].rx_offset;
776 	SPI_STATIS_DEC();
777 	SPI_STATIS_GET(spi_statis, id);
778 
779 	int_status = spi_hal_get_interrupt_status(hal);
780 	spi_hal_clear_interrupt_status(hal, int_status);
781 
782 	SPI_LOGD("int_status:%x\r\n", int_status);
783 
784 	if (spi_hal_is_rx_fifo_int_triggered_with_status(hal, int_status)) {
785 		SPI_STATIS_INC(spi_statis->rx_fifo_isr_cnt);
786 		SPI_LOGD("rx fifo int triggered\r\n");
787 		spi_id_read_bytes_common(id);
788 		if (s_spi_rx_isr[id].callback) {
789 			s_spi_rx_isr[id].callback(id, s_spi_rx_isr[id].param);
790 		}
791 	}
792 
793 	if (spi_hal_is_rx_finish_int_triggered(hal, int_status)) {
794 		SPI_STATIS_INC(spi_statis->rx_finish_isr_cnt);
795 		SPI_LOGD("rx fifo finish int triggered\r\n");
796 		if (s_spi[id].rx_size && s_spi[id].rx_buf) {
797 			while (spi_hal_read_byte(hal, &rd_data) == BK_OK) {
798 				if (rd_offset < s_spi[id].rx_size) {
799 					s_spi[id].rx_buf[rd_offset++] = rd_data;
800 				}
801 			}
802 			s_spi[id].rx_offset = rd_offset;
803 		}
804 		bk_spi_clr_rx(id);
805 		if (s_spi_rx_finish_isr[id].callback){
806 			s_spi_rx_finish_isr[id].callback(s_current_spi_dma_rd_id,s_spi_rx_finish_isr[id].param);
807 		}
808 		if (s_spi[id].is_rx_blocked) {
809 			rtos_set_semaphore(&s_spi[id].rx_sema);
810 			s_spi[id].is_rx_blocked = false;
811 		}
812 	}
813 
814 	if (spi_hal_is_rx_overflow_int_triggered(hal, int_status)) {
815 		SPI_STATIS_INC(spi_statis->rx_overflow_isr_cnt);
816 		SPI_LOGW("rx overflow int triggered\r\n");
817 	}
818 
819 	if (spi_hal_is_tx_fifo_int_triggered_with_status(hal, int_status)) {
820 		SPI_STATIS_INC(spi_statis->tx_fifo_isr_cnt);
821 		SPI_LOGD("tx fifo int triggered\r\n");
822 #if !CONFIG_SPI_SUPPORT_TX_FIFO_WR_READY
823 		if ((!s_spi[id].is_sw_tx_finished) &&
824 			s_spi[id].tx_size &&
825 			s_spi[id].tx_buf) {
826 			spi_id_write_bytes_common(id);
827 			s_spi[id].is_sw_tx_finished = true;
828 		}
829 		for (int i = 0; (i < s_spi[id].rx_size) && s_spi[id].rx_buf; i++) {
830 			/* bk7251 need spi_hal_write_byte when read byte,
831 			 * bk7251 master read data will not work without this operation */
832 			if (spi_hal_is_master(hal)) {
833 				spi_hal_write_byte(hal, 0xff);
834 			}
835 			if (spi_hal_read_byte(hal, &rd_data) == BK_OK) {
836 				SPI_LOGD("tx fifo int read byte\r\n");
837 				if (rd_offset < s_spi[id].rx_size) {
838 					s_spi[id].rx_buf[rd_offset++] = rd_data;
839 				}
840 			} else {
841 				break;
842 			}
843 		}
844 		s_spi[id].rx_offset = rd_offset;
845 		if (s_spi[id].is_sw_tx_finished) {
846 			spi_hal_disable_tx_fifo_int(hal);
847 		}
848 #endif
849 	}
850 
851 	if (spi_hal_is_tx_finish_int_triggered(hal, int_status) &&
852 		s_spi[id].is_sw_tx_finished) {
853 		SPI_STATIS_INC(spi_statis->tx_finish_isr_cnt);
854 		SPI_LOGD("tx finish int triggered\r\n");
855 		if (spi_hal_is_master(hal)) {
856 			if (s_spi[id].is_tx_blocked) {
857 				rtos_set_semaphore(&s_spi[id].tx_sema);
858 				s_spi[id].is_tx_blocked = false;
859 			}
860 			if (s_spi_tx_finish_isr[id].callback) {
861 				s_spi_tx_finish_isr[id].callback(id, s_spi_tx_finish_isr[id].param);
862 			}
863 			bk_spi_clr_tx(id);
864 		} else {
865 			SPI_LOGW("tx finish int triggered, but current mode is spi_slave\r\n");
866 		}
867 	}
868 
869 	if (spi_hal_is_tx_underflow_int_triggered(hal, int_status)) {
870 		SPI_STATIS_INC(spi_statis->tx_underflow_isr_cnt);
871 		SPI_LOGW("tx underflow int triggered\r\n");
872 	}
873 
874 	if (spi_hal_is_slave_release_int_triggered(hal, int_status)) {
875 		SPI_STATIS_INC(spi_statis->slave_release_isr_cnt);
876 		SPI_LOGD("slave cs up int triggered\r\n");
877 		if (spi_hal_is_slave(hal)) {
878 			if (s_spi[id].is_tx_blocked) {
879 				rtos_set_semaphore(&s_spi[id].tx_sema);
880 				s_spi[id].is_tx_blocked = false;
881 			}
882 			if (s_spi_tx_finish_isr[id].callback) {
883 				s_spi_tx_finish_isr[id].callback(id, s_spi_tx_finish_isr[id].param);
884 			}
885 		}
886 		if (s_spi[id].is_rx_blocked) {
887 			rtos_set_semaphore(&s_spi[id].rx_sema);
888 			s_spi[id].is_rx_blocked = false;
889 		}
890 	}
891 }
892 
spi_isr(void)893 static void spi_isr(void)
894 {
895 	SPI_STATIS_DEC();
896 	SPI_STATIS_GET(spi_statis, SPI_ID_0);
897 	SPI_STATIS_INC(spi_statis->spi_isr_cnt);
898 	spi_isr_common(SPI_ID_0);
899 }
900 
901 #if (SOC_SPI_UNIT_NUM > 1)
902 
spi2_isr(void)903 static void spi2_isr(void)
904 {
905 	SPI_STATIS_DEC();
906 	SPI_STATIS_GET(spi_statis, SPI_ID_1);
907 	SPI_STATIS_INC(spi_statis->spi_isr_cnt);
908 	spi_isr_common(SPI_ID_1);
909 }
910 
911 #endif
912 
913 #if (SOC_SPI_UNIT_NUM > 2)
914 
spi3_isr(void)915 static void spi3_isr(void)
916 {
917 	SPI_STATIS_DEC();
918 	SPI_STATIS_GET(spi_statis, SPI_ID_2);
919 	SPI_STATIS_INC(spi_statis->spi_isr_cnt);
920 	spi_isr_common(SPI_ID_2);
921 }
922 
923 #endif
924 
925