1 /*
2 * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
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
16 /**
17 * @file wm_hspi.c
18 *
19 * @brief High speed spi slave Module
20 *
21 * @author dave
22 *
23 * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
24 */
25
26 #include "wm_regs.h"
27 #include "wm_config.h"
28 #include "wm_mem.h"
29 #include "wm_osal.h"
30 #include "wm_irq.h"
31 #include "wm_io.h"
32 #include "wm_hspi.h"
33
34 #if TLS_CONFIG_HS_SPI
35
36 struct tls_slave_hspi g_slave_hspi;
37 #define SET_BIT(x) (1UL << (x))
38 void hspi_free_rxdesc(struct tls_hspi_rx_desc *rx_desc);
39
hspi_rx_init(struct tls_slave_hspi * hspi)40 void hspi_rx_init(struct tls_slave_hspi *hspi)
41 {
42 struct tls_hspi_rx_desc *hspi_rx_desc;
43 int i;
44
45 /* set current availble rx desc pointer */
46 hspi_rx_desc = (struct tls_hspi_rx_desc *) HSPI_RX_DESC_BASE_ADDR;
47 hspi->curr_rx_desc = hspi_rx_desc;
48
49 /* initialize rx descriptor content */
50 for (i = 0; i < HSPI_RX_DESC_NUM; i++) {
51 /* initialize tx descriptors */
52 if (i < HSPI_RXBUF_NUM) {
53 hspi_rx_desc->valid_ctrl = SET_BIT(31);
54 hspi_rx_desc->buf_addr = HSPI_RXBUF_BASE_ADDR + i * HSPI_RXBUF_SIZE;
55 } else {
56 /* indicate this descriptor is can't use by hspi */
57 hspi_rx_desc->valid_ctrl = 0;
58 /* point to null */
59 hspi_rx_desc->buf_addr = 0x0;
60 }
61
62 if (i == (HSPI_RX_DESC_NUM - 1)) {
63 hspi_rx_desc->next_desc_addr = (u32) HSPI_RX_DESC_BASE_ADDR;
64 } else {
65 hspi_rx_desc->next_desc_addr = (u32) (hspi_rx_desc + 1);
66 }
67 hspi_rx_desc++;
68 }
69 }
70
hspi_tx_init(struct tls_slave_hspi * hspi)71 void hspi_tx_init(struct tls_slave_hspi *hspi)
72 {
73 struct tls_hspi_tx_desc *hspi_tx_desc;
74 int i;
75
76 hspi_tx_desc = (struct tls_hspi_tx_desc *) HSPI_TX_DESC_BASE_ADDR;
77
78 hspi->curr_tx_desc = hspi_tx_desc;
79
80 for (i = 0; i < HSPI_TX_DESC_NUM; i++) {
81 hspi_tx_desc->valid_ctrl = 0;
82 hspi_tx_desc->buf_info = 0;
83 #if HSPI_TX_MEM_MALLOC
84 hspi_tx_desc->txbuf_addr = NULL;
85 hspi_tx_desc->buf_addr[0] = 0;
86 #else
87 hspi_tx_desc->buf_addr[0] = HSPI_TXBUF_BASE_ADDR + i * HSPI_TXBUF_SIZE;
88 #endif
89 hspi_tx_desc->buf_addr[1] = 0;
90 hspi_tx_desc->buf_addr[2] = 0;
91 if (i == (HSPI_TX_DESC_NUM - 1)) {
92 hspi_tx_desc->next_desc_addr = (u32) HSPI_TX_DESC_BASE_ADDR;
93 } else {
94 hspi_tx_desc->next_desc_addr = (u32) (hspi_tx_desc + 1);
95 }
96 hspi_tx_desc++;
97 }
98 }
99
slave_spi_rx_data(struct tls_slave_hspi * hspi)100 static int slave_spi_rx_data(struct tls_slave_hspi *hspi)
101 {
102 struct tls_hspi_rx_desc *rx_desc;
103
104 /* get rx descriptor */
105 rx_desc = hspi->curr_rx_desc;
106
107 while (!(rx_desc->valid_ctrl & SET_BIT(31))) {
108 if (hspi->rx_data_callback)
109 hspi->rx_data_callback((char *) rx_desc->buf_addr);
110 hspi_free_rxdesc(rx_desc);
111
112 rx_desc = (struct tls_hspi_rx_desc *) rx_desc->next_desc_addr;
113 hspi->curr_rx_desc = rx_desc;
114 }
115
116 return 0;
117 }
118
SDIO_RX_IRQHandler(void)119 void SDIO_RX_IRQHandler(void)
120 {
121 struct tls_slave_hspi *hspi = (struct tls_slave_hspi *) &g_slave_hspi;
122
123 #if HSPI_TX_MEM_MALLOC
124 hspi->txdoneflag = 1;
125 #endif
126 if (hspi->tx_data_callback)
127 hspi->tx_data_callback((char *) hspi->curr_tx_desc->buf_addr);
128 /* clear interrupt */
129 tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_DATA_UP);
130 }
131
SDIO_TX_IRQHandler(void)132 void SDIO_TX_IRQHandler(void)
133 {
134 struct tls_slave_hspi *hspi = (struct tls_slave_hspi *) &g_slave_hspi;
135
136 // �û�ģʽ�£�ֱ�Ӹ������ݣ������IJ���������ţ��������������������
137 if (hspi->ifusermode) {
138 slave_spi_rx_data(hspi);
139 } else {
140 if (hspi->rx_data_callback)
141 hspi->rx_data_callback((char *) hspi->curr_rx_desc->buf_addr);
142 }
143
144 /* clear interrupt */
145 tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_DATA_DOWN);
146 }
147
SDIO_RX_CMD_IRQHandler(void)148 void SDIO_RX_CMD_IRQHandler(void)
149 {
150 struct tls_slave_hspi *hspi = (struct tls_slave_hspi *) &g_slave_hspi;
151
152 if (hspi->rx_cmd_callback)
153 hspi->rx_cmd_callback((char *) SDIO_CMD_RXBUF_ADDR);
154
155 if (hspi->ifusermode) { // �û�ģʽ�£����ݸ���ȥ֮�Ĵ����������Լ�����
156 tls_reg_write32(HR_SDIO_DOWNCMDVALID, 0x1);
157 }
158
159 /* clear interrupt */
160 tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_CMD_DOWN);
161 }
162
HSPI_IRQHandler(void)163 ATTRIBUTE_ISR void HSPI_IRQHandler(void)
164 {
165 printf("spi HS irqhandle\n");
166 }
167
SDIOA_IRQHandler(void)168 ATTRIBUTE_ISR void SDIOA_IRQHandler(void)
169 {
170 u32 int_src = tls_reg_read32(HR_SDIO_INT_SRC);
171 csi_kernel_intrpt_enter();
172 if (int_src & SDIO_WP_INT_SRC_CMD_DOWN) {
173 SDIO_RX_CMD_IRQHandler();
174 } else if (int_src & SDIO_WP_INT_SRC_DATA_UP) {
175 SDIO_RX_IRQHandler();
176 } else if (int_src & SDIO_WP_INT_SRC_DATA_DOWN) {
177 SDIO_TX_IRQHandler();
178 } else if (int_src & SDIO_WP_INT_SRC_CMD_UP) {
179 tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_CMD_UP);
180 }
181 csi_kernel_intrpt_exit();
182 }
183
hspi_free_rxdesc(struct tls_hspi_rx_desc * rx_desc)184 void hspi_free_rxdesc(struct tls_hspi_rx_desc *rx_desc)
185 {
186 rx_desc->valid_ctrl = SET_BIT(31);
187 /* ����hspi/sdio tx enable�Ĵ�������sdioӲ��֪���п��õ�tx descriptor */
188 tls_reg_write32(HR_SDIO_TXEN, SET_BIT(0));
189 }
190
hspi_regs_cfg(void)191 void hspi_regs_cfg(void)
192 {
193 tls_reg_write32(HR_HSPI_CLEAR_FIFO, 0x1); /* Clear data up&down interrput
194 */
195 tls_reg_write32(HR_HSPI_SPI_CFG, 0); /* CPOL=0, CPHA=0, Small-Endian */
196 tls_reg_write32(HR_HSPI_MODE_CFG, 0x0);
197 tls_reg_write32(HR_HSPI_INT_MASK, 0x03);
198 tls_reg_write32(HR_HSPI_INT_STTS, 0x03);
199 }
200
sdio_init_cis(void)201 void sdio_init_cis(void)
202 {
203 tls_reg_write32(FN0_TPL_FUNCID, 0x000C0221);
204 tls_reg_write32(FN0_TPL_FUNCE, 0x00000422);
205 tls_reg_write32(FN0_TPL_FUNCE_MAXBLK, 0x04203208);
206 tls_reg_write32(FN0_TPL_MANFID_MID, 0x53470296);
207 tls_reg_write32(FN0_TPL_END, 0x000000ff);
208
209 tls_reg_write32(FN1_TPL_FUNCID, 0x000C0221);
210 tls_reg_write32(FN1_TPL_FUNCE, 0x01012a22);
211 tls_reg_write32(FN1_TPL_FUNCE_VER, 0x00000011);
212 tls_reg_write32(FN1_TPL_FUNCE_NSN, 0x02000000);
213 tls_reg_write32(FN1_TPL_FUNCE_CSASIZE, 0x08000300);
214 tls_reg_write32(FN1_TPL_FUNCE_OCR, 0x00FF8000);
215 tls_reg_write32(FN1_TPL_FUNCE_MINPWR, 0x010f0a08);
216 tls_reg_write32(FN1_TPL_FUNCE_STANDBY, 0x00000101);
217 tls_reg_write32(FN1_TPL_FUNCE_OPTBW, 0x00000000);
218 tls_reg_write32(FN1_TPL_FUNCE_NTIMEOUT, 0x00000000);
219 tls_reg_write32(FN1_TPL_FUNCE_AVGPWR, 0x00000000);
220 tls_reg_write32(FN1_TPL_FUNCE_AVGPWR + 4, 0x00000000);
221 tls_reg_write32(FN1_TPL_END, 0x000000ff);
222 }
223
hsdio_regs_cfg(void)224 void hsdio_regs_cfg(void)
225 {
226 u32 v;
227
228 sdio_init_cis();
229 tls_reg_write32(HR_SDIO_CIS0, SDIO_CIS0_ADDR - 0x1000);
230 tls_reg_write32(HR_SDIO_CIS1, SDIO_CIS1_ADDR - 0x2000);
231
232 v = tls_reg_read32(HR_SDIO_CIA);
233 tls_reg_write32(HR_SDIO_CIA, (v & 0xFFFFF000) | 0x232);
234
235 /* set sdio ready */
236 tls_reg_write32(HR_SDIO_PROG, 0x02FD);
237 }
238
239 /**
240 * @brief This function is used to initial HSPI register.
241 *
242 * @param[in] None
243 *
244 * @retval 0 success
245 * @retval other failed
246 *
247 * @note When the system is initialized, the function has been called, so users can not call the function.
248 */
tls_slave_spi_init(void)249 int tls_slave_spi_init(void)
250 {
251 struct tls_slave_hspi *hspi;
252
253 hspi = &g_slave_hspi;
254 memset_s(hspi, sizeof(hspi), 0, sizeof(struct tls_slave_hspi));
255
256 hspi_rx_init(hspi);
257 hspi_tx_init(hspi);
258 /* regiseter hspi tx rx cmd interrupt handler */
259
260 /* setting hw interrupt module isr enable regiset */
261 tls_irq_enable(SDIO_IRQn);
262 tls_irq_enable(SPI_HS_IRQn);
263
264 /********************************************
265 * setting hspi wrapper registers
266 *********************************************/
267 /* hspi data down(rx) */
268 tls_reg_write32(HR_SDIO_TXBD_ADDR, HSPI_RX_DESC_BASE_ADDR);
269 tls_reg_write32(HR_SDIO_TXBD_LINKEN, 1);
270 tls_reg_write32(HR_SDIO_TXEN, 1);
271 /* hspi data up (tx) */
272 tls_reg_write32(HR_SDIO_RXBD_ADDR, HSPI_TX_DESC_BASE_ADDR);
273 tls_reg_write32(HR_SDIO_RXBD_LINKEN, 1);
274
275 /* hspi cmd down */
276 tls_reg_write32(HR_SDIO_CMD_ADDR, SDIO_CMD_RXBUF_ADDR);
277 tls_reg_write32(HR_SDIO_CMD_SIZE, SDIO_CMD_RXBUF_SIZE);
278 tls_reg_write32(HR_SDIO_DOWNCMDVALID, 0x1);
279
280 /* enable sdio module register */
281 tls_reg_write32(HR_SDIO_INT_MASK, 0x00);
282
283 return 0;
284 }
285
286 /**
287 * @brief This function is used to set high speed interface type.
288 *
289 * @param[in] type is the interface type. HSPI_INTERFACE_SPI or HSPI_INTERFACE_SDIO
290 *
291 * @return None
292 *
293 * @note None
294 */
tls_set_high_speed_interface_type(int type)295 void tls_set_high_speed_interface_type(int type)
296 {
297 if (HSPI_INTERFACE_SPI == type) {
298 hspi_regs_cfg();
299 } else if (HSPI_INTERFACE_SDIO == type) {
300 hsdio_regs_cfg();
301 }
302 }
303
304 /**
305 * @brief This function is used to enable or disable user mode.
306 *
307 * @param[in] ifenable TRUE or FALSE
308 *
309 * @return None
310 *
311 * @note If the user enables the user mode, RICM instruction in the system will not be used by SPI.
312 * If the user wants to use the SPI interface as other use, need to enable the user mode.
313 * This function must be called before the register function.
314 */
tls_set_hspi_user_mode(u8 ifenable)315 void tls_set_hspi_user_mode(u8 ifenable)
316 {
317 struct tls_slave_hspi *hspi = &g_slave_hspi;
318
319 hspi->ifusermode = ifenable;
320
321 if (ifenable) {
322 hspi->rx_cmd_callback = NULL;
323 hspi->rx_data_callback = NULL;
324 hspi->tx_data_callback = NULL;
325 }
326 }
327
328 /**
329 * @brief This function is used to register hspi rx command interrupt.
330 *
331 * @param[in] rx_cmd_callback is the hspi rx interrupt call back function.
332 *
333 * @return None
334 *
335 * @note None
336 */
tls_hspi_rx_cmd_callback_register(s16 (* rx_cmd_callback)(char * buf))337 void tls_hspi_rx_cmd_callback_register(s16(*rx_cmd_callback) (char *buf))
338 {
339 g_slave_hspi.rx_cmd_callback = rx_cmd_callback;
340 }
341
342 /**
343 * @brief This function is used to register hspi rx data interrupt.
344 *
345 * @param[in] rx_data_callback is the hspi rx interrupt call back function.
346 *
347 * @return None
348 *
349 * @note None
350 */
tls_hspi_rx_data_callback_register(s16 (* rx_data_callback)(char * buf))351 void tls_hspi_rx_data_callback_register(s16(*rx_data_callback) (char *buf))
352 {
353 g_slave_hspi.rx_data_callback = rx_data_callback;
354 }
355
356 /**
357 * @brief This function is used to register hspi tx data interrupt.
358 *
359 * @param[in] tx_data_callback is the hspi tx interrupt call back function.
360 *
361 * @return None
362 *
363 * @note None
364 */
tls_hspi_tx_data_callback_register(s16 (* tx_data_callback)(char * buf))365 void tls_hspi_tx_data_callback_register(s16(*tx_data_callback) (char *buf))
366 {
367 g_slave_hspi.tx_data_callback = tx_data_callback;
368 }
369
370 /**
371 * @brief This function is used to transfer data.
372 *
373 * @param[in] txbuf is a buf for saving user data.
374 * @param[in] len is the data length.
375 *
376 * @retval transfer data len success
377 * @retval 0 failed
378 *
379 * @note None
380 */
tls_hspi_tx_data(char * txbuf,int len)381 int tls_hspi_tx_data(char *txbuf, int len)
382 {
383 struct tls_hspi_tx_desc *tx_desc;
384 int totallen = len;
385
386 if (txbuf || len <= 0 || len > (HSPI_TXBUF_SIZE * HSPI_TX_DESC_NUM) == NULL) {
387 printf("\nhspi tx param error\n");
388 return 0;
389 }
390 tx_desc = g_slave_hspi.curr_tx_desc;
391 while (1) {
392 if ((tx_desc->valid_ctrl & SET_BIT(31)) == 0)
393 break;
394 tls_os_time_delay(1);
395 }
396 while (!(tx_desc->valid_ctrl & SET_BIT(31))) {
397 int txlen = (totallen > HSPI_TXBUF_SIZE) ? HSPI_TXBUF_SIZE : totallen;
398 #if HSPI_TX_MEM_MALLOC
399 if (tx_desc->txbuf_addr != NULL) {
400 printf("\nhspi txbuf not null,error %x\n", tx_desc->txbuf_addr);
401 if (tx_desc->txbuf_addr == tx_desc->buf_addr[0]) {
402 mem_free((void *) tx_desc->txbuf_addr);
403 tx_desc->txbuf_addr = NULL;
404 } else { // ��Ӧ�ó���
405 printf("\nhspi tx mem error\n");
406 break;
407 }
408 }
409
410 tx_desc->txbuf_addr = (u32) mem_malloc(txlen + 1);
411 if (tx_desc->txbuf_addr == NULL) {
412 printf("\nhspi tx data malloc error\n");
413 break;
414 }
415 tx_desc->buf_addr[0] = tx_desc->txbuf_addr;
416 #endif
417 MEMCPY((char *) tx_desc->buf_addr[0], txbuf, txlen);
418 tx_desc->buf_info = txlen << 12;
419 tx_desc->valid_ctrl = SET_BIT(31);
420 tls_reg_write32(HR_SDIO_RXEN, 0x01);
421 tx_desc = (struct tls_hspi_tx_desc *) tx_desc->next_desc_addr;
422 g_slave_hspi.curr_tx_desc = tx_desc;
423 totallen -= txlen;
424 if (totallen <= 0)
425 break;
426 }
427 return (len - totallen);
428 }
429
430 #endif
431
432