1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 #include "spi.h"
17 #include <hi_time.h>
18 #include <hi_stdlib.h>
19 #include <hi_isr.h>
20 #include <hi_event.h>
21 #ifdef CONFIG_SPI_DMA_SUPPORT
22 #include <dma.h>
23 #endif
24
25 spi_ctrl *g_spi_ctrl[SPI_NUM] = { 0 };
26
spi_check_rx_fifo_empty(hi_u32 reg_base)27 HI_ALWAYS_STAIC_INLINE hi_bool spi_check_rx_fifo_empty(hi_u32 reg_base)
28 {
29 hi_u16 reg_val = 0;
30 hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
31 if (reg_val & MASK_SPI_SR_RNE) {
32 return HI_FALSE;
33 }
34 return HI_TRUE;
35 }
36
spi_check_busy(hi_u32 reg_base)37 HI_ALWAYS_STAIC_INLINE hi_bool spi_check_busy(hi_u32 reg_base)
38 {
39 hi_u16 reg_val = 0;
40 hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
41 if (reg_val & MASK_SPI_SR_BSY) {
42 return HI_TRUE;
43 }
44 return HI_FALSE;
45 }
46
spi_check_write_timeout(hi_u32 reg_base)47 HI_ALWAYS_STAIC_INLINE hi_u32 spi_check_write_timeout(hi_u32 reg_base)
48 {
49 hi_u16 reg_val = 0;
50 hi_u32 count = 0;
51 while (count++ < SPI_HOST_TIMEOUT_US) {
52 hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
53 if ((reg_val & MASK_SPI_SR_TFE) && (!(reg_val & MASK_SPI_SR_BSY))) {
54 break;
55 }
56 hi_udelay(1);
57 }
58 if (count >= SPI_HOST_TIMEOUT_US) {
59 spi_process_printf("%s spi transfer wait timeout!", __func__);
60 return HI_ERR_SPI_WRITE_TIMEOUT;
61 }
62 return HI_ERR_SUCCESS;
63 }
64
65 /* check tx fifo not full */
spi_check_tnf_timeout(hi_u32 reg_base,HI_CONST hi_u32 time_out_us)66 HI_ALWAYS_STAIC_INLINE hi_u32 spi_check_tnf_timeout(hi_u32 reg_base, HI_CONST hi_u32 time_out_us)
67 {
68 hi_u16 reg_val = 0;
69 hi_u32 count = 0;
70 while (count++ < time_out_us) {
71 hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
72 if ((reg_val & MASK_SPI_SR_TNF)) {
73 break;
74 }
75 hi_udelay(1);
76 }
77 if (count >= time_out_us) {
78 if (reg_val & MASK_SPI_SR_TNF) {
79 spi_process_printf("MASK_SPI_SR_TNF\n");
80 }
81 if (reg_val & MASK_SPI_SR_BSY) {
82 spi_process_printf("MASK_SPI_SR_BSY \n");
83 }
84 return HI_ERR_SPI_WRITE_TIMEOUT;
85 }
86 return HI_ERR_SUCCESS;
87 }
88 /* check rx fifo not empty */
spi_check_rne_timeout(hi_u32 reg_base,HI_CONST hi_u32 time_out_us)89 HI_ALWAYS_STAIC_INLINE hi_u32 spi_check_rne_timeout(hi_u32 reg_base, HI_CONST hi_u32 time_out_us)
90 {
91 hi_u16 reg_val = 0;
92 hi_u32 count = 0;
93 while (count++ < time_out_us) {
94 hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
95 if (((reg_val & MASK_SPI_SR_RNE))) {
96 break;
97 }
98 hi_udelay(1);
99 }
100 if (count >= time_out_us) {
101 spi_process_printf("%s timeout!\n", __func__);
102 return HI_ERR_SPI_WRITE_TIMEOUT;
103 }
104 return HI_ERR_SUCCESS;
105 }
106
107 /*
108 * spi_flush_fifo: flush spi fifo
109 */
spi_flush_fifo(hi_u32 reg_base)110 hi_void spi_flush_fifo(hi_u32 reg_base)
111 {
112 hi_u16 reg_val = 0;
113 hi_u16 fifo_len = (reg_base == HI_SSP0_REG_BASE ? SPI0_FIFO_LEN : SPI1_FIFO_LEN);
114 for (hi_u16 i = 0; i < fifo_len; i++) {
115 hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
116 if (!(reg_val & MASK_SPI_SR_RNE)) {
117 break;
118 }
119 hi_reg_read16(reg_base + REG_SPI_DR, reg_val);
120 }
121 }
122
spi_disable(spi_ctrl * ctrl)123 hi_void spi_disable(spi_ctrl *ctrl)
124 {
125 hi_u16 reg_val = 0;
126 if (ctrl == NULL) {
127 spi_process_printf("spi_disable para is null \n");
128 return;
129 }
130 if ((ctrl->spi_cfg.is_slave == 0) && spi_check_busy(ctrl->reg_base)) {
131 ctrl->disable_later = HI_TRUE;
132 return;
133 }
134 hi_reg_read16(ctrl->reg_base + REG_SPI_CR1, reg_val);
135 reg_val &= ~(1 << SPI_CR1_ST_BIT_SSE);
136 hi_reg_write16(ctrl->reg_base + REG_SPI_CR1, reg_val);
137 }
138
spi_enable(spi_ctrl * ctrl)139 static hi_void spi_enable(spi_ctrl *ctrl)
140 {
141 hi_u16 reg_val = 0;
142
143 hi_reg_read16(ctrl->reg_base + REG_SPI_CR1, reg_val);
144 reg_val |= (1 << SPI_CR1_ST_BIT_SSE);
145 hi_reg_write16(ctrl->reg_base + REG_SPI_CR1, reg_val);
146 ctrl->disable_later = HI_FALSE;
147 }
148
spi_reset(const spi_ctrl * spi_hw_ctrl)149 hi_void spi_reset(const spi_ctrl *spi_hw_ctrl)
150 {
151 hi_u8 reset_bit;
152 hi_u16 reg_val = 0;
153 hi_u32 int_value;
154 if (spi_hw_ctrl != HI_NULL &&
155 spi_hw_ctrl->reg_base == HI_SSP0_REG_BASE) {
156 reset_bit = CRG_REG_SSP_SRST_REQ_OFFSET;
157 } else {
158 reset_bit = CRG_REG_SSP2_SRST_REQ_OFFSET;
159 }
160 int_value = hi_int_lock();
161 hi_reg_read16(CLDO_CTL_SOFT_RESET_REG, reg_val);
162 reg_val &= (~((hi_u16)(1 << reset_bit)));
163 hi_reg_write16(CLDO_CTL_SOFT_RESET_REG, reg_val);
164 reg_val |= (hi_u16)(1 << reset_bit);
165 hi_reg_write16(CLDO_CTL_SOFT_RESET_REG, reg_val);
166 hi_int_restore(int_value);
167 }
168
spi_config(const spi_ctrl * spi_hw_ctrl)169 hi_u32 spi_config(const spi_ctrl *spi_hw_ctrl)
170 {
171 spi_inner_cfg inner_cfg = { 0 };
172 if (spi_hw_ctrl == HI_NULL) {
173 return HI_ERR_FAILURE;
174 }
175 if (memcpy_s(&inner_cfg, sizeof(spi_inner_cfg), &spi_hw_ctrl->spi_cfg, sizeof(spi_inner_cfg)) == EOK) {
176 hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_CR0, inner_cfg.cr0);
177 hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_CR1, inner_cfg.cr1);
178 hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_CPSR, inner_cfg.cpsdvsr);
179 } else {
180 return HI_ERR_FAILURE;
181 }
182 return HI_ERR_SUCCESS;
183 }
184
spi_set_fifo_line(const spi_ctrl * spi_hw_ctrl)185 hi_void spi_set_fifo_line(const spi_ctrl *spi_hw_ctrl)
186 {
187 hi_u16 reg_val;
188 if (spi_hw_ctrl == HI_NULL) {
189 return;
190 }
191 hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_TXFIFOCR, reg_val);
192 reg_val &= ~(hi_u16)(SPI_FIFO_LINE_MASK << SPI_FIFO_LINE_OFFSET);
193 reg_val |= (hi_u16)(spi_hw_ctrl->spi_cfg.tx_fifo_line << SPI_FIFO_LINE_OFFSET);
194 hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_TXFIFOCR, reg_val);
195 hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_RXFIFOCR, reg_val);
196 reg_val &= ~(hi_u16)(SPI_FIFO_LINE_MASK << SPI_FIFO_LINE_OFFSET);
197 reg_val |= (hi_u16)(spi_hw_ctrl->spi_cfg.rx_fifo_line << SPI_FIFO_LINE_OFFSET);
198 hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_RXFIFOCR, reg_val);
199 }
200
201 #ifdef CONFIG_SPI_DMA_SUPPORT
spi_set_dma_fifo_line(const spi_ctrl * spi_hw_ctrl)202 hi_void spi_set_dma_fifo_line(const spi_ctrl *spi_hw_ctrl)
203 {
204 hi_u16 reg_val;
205 if (spi_hw_ctrl == HI_NULL) {
206 return;
207 }
208 hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_TXFIFOCR, reg_val);
209 reg_val &= ~(hi_u16)(SPI_FIFO_LINE_MASK);
210 reg_val |= (hi_u16)(spi_hw_ctrl->spi_cfg.tx_fifo_dma_line);
211 hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_TXFIFOCR, reg_val);
212 hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_RXFIFOCR, reg_val);
213 reg_val &= ~(hi_u16)(SPI_FIFO_LINE_MASK);
214 reg_val |= (hi_u16)(spi_hw_ctrl->spi_cfg.rx_fifo_dma_line);
215 hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_RXFIFOCR, reg_val);
216 }
217
dma_write_fifo_callback(hi_u32 irq_type)218 hi_void dma_write_fifo_callback(hi_u32 irq_type)
219 {
220 spi_process_printf("This is callback,irq type is %d\r\n", irq_type);
221 if (irq_type == DMA_INT_TC) {
222 hi_event_send(g_spi_ctrl[0]->event_id, HI_EVENT_BIT_DMA_TX_DATA);
223 } else {
224 hi_event_send(g_spi_ctrl[0]->event_id, HI_EVENT_BIT_DMA_TX_ERR_DATA);
225 }
226 }
dma_read_fifo_callback(hi_u32 irq_type)227 hi_void dma_read_fifo_callback(hi_u32 irq_type)
228 {
229 spi_process_printf("This is callback,irq type is %d\r\n", irq_type);
230 if (irq_type == DMA_INT_TC) {
231 hi_event_send(g_spi_ctrl[0]->event_id, HI_EVENT_BIT_DMA_RX_DATA);
232 } else {
233 hi_event_send(g_spi_ctrl[0]->event_id, HI_EVENT_BIT_DMA_RX_ERR_DATA);
234 }
235 }
dma_write_fifo_callback_spi1(hi_u32 irq_type)236 hi_void dma_write_fifo_callback_spi1(hi_u32 irq_type)
237 {
238 spi_process_printf("This is callback,irq type is %d\r\n", irq_type);
239 if (irq_type == DMA_INT_TC) {
240 hi_event_send(g_spi_ctrl[1]->event_id, HI_EVENT_BIT_DMA_TX_DATA);
241 } else {
242 hi_event_send(g_spi_ctrl[1]->event_id, HI_EVENT_BIT_DMA_TX_ERR_DATA);
243 }
244 }
dma_read_fifo_callback_spi1(hi_u32 irq_type)245 hi_void dma_read_fifo_callback_spi1(hi_u32 irq_type)
246 {
247 spi_process_printf("This is callback,irq type is %d\r\n", irq_type);
248 if (irq_type == DMA_INT_TC) {
249 hi_event_send(g_spi_ctrl[1]->event_id, HI_EVENT_BIT_DMA_RX_DATA);
250 } else {
251 hi_event_send(g_spi_ctrl[1]->event_id, HI_EVENT_BIT_DMA_RX_ERR_DATA);
252 }
253 }
254
spi_get_rx_dma_burst_size(spi_ctrl * spi_dev_ctrl)255 HI_ALWAYS_STAIC_INLINE hi_u32 spi_get_rx_dma_burst_size(spi_ctrl *spi_dev_ctrl)
256 {
257 spi_hw_cfg *spi_cfg = &(spi_dev_ctrl->spi_cfg);
258 if (spi_dev_ctrl->reg_base == HI_SSP0_REG_BASE) {
259 return spi_cfg->rx_fifo_dma_line >=
260 SPI0_RX_FIFO_DMA_WLINE_128 ? DMA_BURST_MSIZE_128 : spi_cfg->rx_fifo_dma_line;
261 } else {
262 return spi_cfg->rx_fifo_dma_line >= SPI1_RX_FIFO_DMA_WLINE_32 ? DMA_BURST_MSIZE_32 : spi_cfg->rx_fifo_dma_line;
263 }
264 }
265
spi_get_tx_dma_burst_size(spi_ctrl * spi_dev_ctrl)266 HI_ALWAYS_STAIC_INLINE hi_u32 spi_get_tx_dma_burst_size(spi_ctrl *spi_dev_ctrl)
267 {
268 spi_hw_cfg *spi_cfg = &(spi_dev_ctrl->spi_cfg);
269 if (spi_dev_ctrl->reg_base == HI_SSP0_REG_BASE) {
270 return spi_cfg->tx_fifo_dma_line >= SPI0_TX_FIFO_DMA_WLINE_64 ? DMA_BURST_MSIZE_128 : spi_cfg->tx_fifo_dma_line;
271 } else {
272 return spi_cfg->tx_fifo_dma_line >= SPI1_TX_FIFO_DMA_WLINE_16 ? DMA_BURST_MSIZE_32 : spi_cfg->tx_fifo_dma_line;
273 }
274 }
275
spi_dma_enable(hi_u32 reg_base,hi_u16 enable_bits)276 hi_void spi_dma_enable(hi_u32 reg_base, hi_u16 enable_bits) /* 使能DMA(按bit操作) */
277 {
278 hi_u16 reg_val = 0;
279 hi_u32 int_save;
280 int_save = hi_int_lock();
281 hi_reg_read16(reg_base + REG_SPI_DMACR, reg_val);
282 reg_val |= enable_bits;
283 hi_reg_write16(reg_base + REG_SPI_DMACR, reg_val);
284 hi_int_restore(int_save);
285 spi_process_printf("dma enable 0x%x 0x%x", reg_base, reg_val);
286 }
287
spi_dma_disable(hi_u32 reg_base,hi_u16 disable_bits)288 hi_void spi_dma_disable(hi_u32 reg_base, hi_u16 disable_bits) /* 清除DMA使能位(按bit操作) */
289 {
290 hi_u16 reg_val = 0;
291 hi_u32 int_save;
292 int_save = hi_int_lock();
293 hi_reg_read16(reg_base + REG_SPI_DMACR, reg_val);
294 reg_val &= (~disable_bits);
295 hi_reg_write16(reg_base + REG_SPI_DMACR, reg_val);
296 hi_int_restore(int_save);
297 }
298
spi_dma_transer(hi_u32 tr_type,spi_ctrl * spi_dev_ctrl,uintptr_t addr,hi_u32 tran_len,hi_void (* cb)(hi_u32),hi_u32 * ch_num)299 hi_u32 spi_dma_transer(hi_u32 tr_type, spi_ctrl *spi_dev_ctrl, uintptr_t addr, hi_u32 tran_len,
300 hi_void (*cb)(hi_u32),
301 hi_u32 *ch_num)
302 {
303 hi_u32 reg_base = spi_dev_ctrl->reg_base;
304 hi_u32 data_width = WIDTH_BIT8;
305 if (hi_unlikely(spi_dev_ctrl->spi_cfg.data_width > HI_SPI_CFG_DATA_WIDTH_E_8BIT)) {
306 data_width = WIDTH_BIT16;
307 }
308 hi_u8 dma_burst_size;
309 hi_u32 dma_ts;
310 hi_dma_para dma_para;
311 dma_para.tr_type = tr_type;
312 dma_para.src_width = data_width;
313 dma_para.dst_width = data_width;
314 if (tr_type == MEM_TO_SPI) {
315 dma_para.dst_addr = reg_base + REG_SPI_DR;
316 dma_para.src_addr = addr;
317 dma_para.dst_phl = (reg_base == HI_SSP0_REG_BASE) ? SPI0_TX : SPI1_TX;
318 dma_para.src_phl = 0;
319 dma_burst_size = spi_get_tx_dma_burst_size(spi_dev_ctrl);
320 } else {
321 dma_para.dst_addr = addr;
322 dma_para.src_addr = reg_base + REG_SPI_DR;
323 dma_para.dst_phl = 0;
324 dma_para.src_phl = (reg_base == HI_SSP0_REG_BASE) ? SPI0_RX : SPI1_RX;
325 dma_burst_size = spi_get_rx_dma_burst_size(spi_dev_ctrl);
326 }
327 dma_ts = spi_get_transfer_size(dma_burst_size);
328 dma_para.dst_burst_size = (dma_ts > tran_len) ? DMA_BURST_MSIZE_1 : dma_burst_size;
329 dma_para.src_burst_size = (dma_ts > tran_len) ? DMA_BURST_MSIZE_1 : dma_burst_size;
330 dma_para.transfer_size = tran_len;
331 dma_para.cb = cb;
332 return dma_hw_request_transfer(&dma_para, ch_num);
333 }
334
335 /*
336 ・dma read fifo can used for slave device
337 */
spi_hd_dma_read_fifo(spi_ctrl * spi_dev_ctrl,hi_u32 timeout_ms)338 hi_u32 spi_hd_dma_read_fifo(spi_ctrl *spi_dev_ctrl, hi_u32 timeout_ms)
339 {
340 if (spi_dev_ctrl == HI_NULL) {
341 return HI_ERR_FAILURE;
342 }
343 hi_pvoid read_buf = spi_dev_ctrl->rx_buf.buf;
344 hi_u32 read_pos = spi_dev_ctrl->rx_buf.cur_pos;
345 hi_u32 loop = spi_dev_ctrl->trans_len - spi_dev_ctrl->rx_buf.cur_cnt;
346 hi_u32 ret;
347 hi_u32 event_bit = 0;
348 hi_u32 ch_num = 0xff; /* set invalid value 0xff */
349 if (spi_dev_ctrl->reg_base == HI_SSP0_REG_BASE) {
350 if (spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT) {
351 ret = spi_dma_transer(SPI_TO_MEM, spi_dev_ctrl, (uintptr_t)((hi_u8 *)read_buf + read_pos), loop,
352 dma_read_fifo_callback, &ch_num);
353 } else {
354 ret = spi_dma_transer(SPI_TO_MEM, spi_dev_ctrl, (uintptr_t)((hi_u16 *)read_buf + read_pos), loop,
355 dma_read_fifo_callback, &ch_num);
356 }
357 } else {
358 if (spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT) {
359 ret = spi_dma_transer(SPI_TO_MEM, spi_dev_ctrl, (uintptr_t)((hi_u8 *)read_buf + read_pos), loop,
360 dma_read_fifo_callback_spi1, &ch_num);
361 } else {
362 ret = spi_dma_transer(SPI_TO_MEM, spi_dev_ctrl, (uintptr_t)((hi_u16 *)read_buf + read_pos), loop,
363 dma_read_fifo_callback_spi1, &ch_num);
364 }
365 }
366 if (ret != HI_ERR_SUCCESS) {
367 return ret;
368 }
369 ret = hi_event_wait(spi_dev_ctrl->event_id, HI_EVENT_BIT_DMA_RX_DATA, &event_bit, timeout_ms,
370 HI_EVENT_WAITMODE_OR | HI_EVENT_WAITMODE_CLR);
371 if (event_bit & HI_EVENT_BIT_DMA_RX_ERR_DATA) {
372 spi_process_printf("DMA trans err\n");
373 return HI_ERR_FAILURE;
374 }
375 if (ret == HI_ERR_EVENT_WAIT_TIME_OUT) {
376 hi_dma_ch_close(ch_num);
377 spi_process_printf("read time out\n");
378 return HI_ERR_SPI_WRITE_TIMEOUT;
379 }
380 spi_dev_ctrl->rx_buf.cur_cnt += loop; /* update cur_cnt and read_pos/cur_pos */
381 spi_dev_ctrl->rx_buf.cur_pos += loop;
382 return ret;
383 }
spi_hd_dma_write_fifo(spi_ctrl * spi_dev_ctrl,hi_u32 timeout_ms)384 hi_u32 spi_hd_dma_write_fifo(spi_ctrl *spi_dev_ctrl, hi_u32 timeout_ms)
385 {
386 if (spi_dev_ctrl == NULL) {
387 return HI_ERR_FAILURE;
388 }
389 hi_pvoid write_buf = spi_dev_ctrl->tx_buf.buf;
390 hi_u32 write_pos = spi_dev_ctrl->tx_buf.cur_pos;
391 hi_u32 loop = spi_dev_ctrl->trans_len - spi_dev_ctrl->tx_buf.cur_cnt;
392 hi_u32 ret;
393 hi_u32 event_bit = 0;
394 hi_u32 ch_num = 0xff; /* set invalid value 0xff */
395 if (spi_dev_ctrl->reg_base == HI_SSP0_REG_BASE) {
396 if (spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT) {
397 ret = spi_dma_transer(MEM_TO_SPI, spi_dev_ctrl, (uintptr_t)((hi_u8 *)write_buf + write_pos), loop,
398 dma_write_fifo_callback, &ch_num);
399 } else {
400 ret = spi_dma_transer(MEM_TO_SPI, spi_dev_ctrl, (uintptr_t)((hi_u16 *)write_buf + write_pos), loop,
401 dma_write_fifo_callback, &ch_num);
402 }
403 } else {
404 if (spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT) {
405 ret = spi_dma_transer(MEM_TO_SPI, spi_dev_ctrl, (uintptr_t)((hi_u8 *)write_buf + write_pos), loop,
406 dma_write_fifo_callback_spi1, &ch_num);
407 } else {
408 ret = spi_dma_transer(MEM_TO_SPI, spi_dev_ctrl, (uintptr_t)((hi_u16 *)write_buf + write_pos), loop,
409 dma_write_fifo_callback_spi1, &ch_num);
410 }
411 }
412 if (ret != HI_ERR_SUCCESS) { /* dma fail */
413 return ret;
414 }
415 ret = hi_event_wait(spi_dev_ctrl->event_id, HI_EVENT_BIT_DMA_TX_DATA | HI_EVENT_BIT_DMA_TX_ERR_DATA, &event_bit,
416 timeout_ms, HI_EVENT_WAITMODE_OR | HI_EVENT_WAITMODE_CLR);
417 if (event_bit & HI_EVENT_BIT_DMA_TX_ERR_DATA) {
418 spi_process_printf("DMA trans err\n");
419 return HI_ERR_FAILURE;
420 }
421 if (ret == HI_ERR_EVENT_WAIT_TIME_OUT) {
422 hi_dma_ch_close(ch_num);
423 spi_process_printf("WRITE time out, ch_num:%d, ret:%x\n", ch_num, ret);
424 return HI_ERR_SPI_WRITE_TIMEOUT;
425 }
426 spi_dev_ctrl->tx_buf.cur_cnt += loop; /* update cur_cnt and read_pos/cur_pos */
427 spi_dev_ctrl->tx_buf.cur_pos += loop;
428 return ret;
429 }
430 #endif
431
spi_isr_enable(hi_u32 reg_base,hi_u16 enable_bits)432 hi_void spi_isr_enable(hi_u32 reg_base, hi_u16 enable_bits)
433 {
434 hi_u16 reg_val = 0;
435 hi_u32 int_save;
436 int_save = hi_int_lock();
437 hi_reg_read16(reg_base + REG_SPI_IMSC, reg_val);
438 reg_val |= enable_bits;
439 hi_reg_write16(reg_base + REG_SPI_IMSC, reg_val);
440 hi_int_restore(int_save);
441 spi_process_printf("isr enable 0x%x 0x%x", reg_base, reg_val);
442 }
443
spi_isr_disable(hi_u32 reg_base,hi_u16 disable_bits)444 hi_void spi_isr_disable(hi_u32 reg_base, hi_u16 disable_bits)
445 {
446 hi_u16 reg_val = 0;
447 hi_u32 int_save;
448 int_save = hi_int_lock();
449 hi_reg_read16(reg_base + REG_SPI_IMSC, reg_val);
450 reg_val &= (~disable_bits);
451 hi_reg_write16(reg_base + REG_SPI_IMSC, reg_val);
452 hi_int_restore(int_save);
453 }
spi_isr_clear_cr(hi_u32 reg_base,hi_u16 clear_bit)454 hi_void spi_isr_clear_cr(hi_u32 reg_base, hi_u16 clear_bit)
455 {
456 hi_u16 reg_val = 0;
457 hi_u32 int_save;
458 int_save = hi_int_lock();
459 hi_reg_read16(reg_base + REG_SPI_CR, reg_val);
460 reg_val |= clear_bit;
461 hi_reg_write16(reg_base + REG_SPI_CR, reg_val);
462 hi_int_restore(int_save);
463 }
464
spi_isr_read_16bits(spi_ctrl * spi_dev_ctrl,hi_bool fifo_irq,hi_u32 loop,hi_pvoid read_buf,hi_u16 increase_step)465 HI_ALWAYS_STAIC_INLINE hi_void spi_isr_read_16bits(spi_ctrl *spi_dev_ctrl, hi_bool fifo_irq, hi_u32 loop,
466 hi_pvoid read_buf, hi_u16 increase_step)
467 {
468 hi_u32 i;
469 hi_u32 reg_base = spi_dev_ctrl->reg_base;
470 hi_u32 read_pos = spi_dev_ctrl->rx_buf.cur_pos;
471 if (fifo_irq) {
472 for (i = 0; i < loop; i++) {
473 *((hi_u16 *)read_buf + read_pos) = (hi_u16)hi_reg_read_val16(reg_base + REG_SPI_DR);
474 read_pos += increase_step;
475 }
476 spi_dev_ctrl->rx_buf.cur_cnt += loop;
477 } else {
478 for (i = 0; i < loop; i++) {
479 if (hi_likely(!spi_check_rx_fifo_empty(reg_base))) {
480 *((hi_u16 *)read_buf + read_pos) = (hi_u16)hi_reg_read_val16(reg_base + REG_SPI_DR);
481 read_pos += increase_step;
482 spi_dev_ctrl->rx_buf.cur_cnt++;
483 } else {
484 break;
485 }
486 }
487 }
488 spi_dev_ctrl->rx_buf.cur_pos = read_pos;
489 }
490
spi_isr_read_8bits(spi_ctrl * spi_dev_ctrl,hi_bool fifo_irq,hi_u32 loop,hi_pvoid read_buf,hi_u16 increase_step)491 HI_ALWAYS_STAIC_INLINE hi_void spi_isr_read_8bits(spi_ctrl *spi_dev_ctrl, hi_bool fifo_irq, hi_u32 loop,
492 hi_pvoid read_buf, hi_u16 increase_step)
493 {
494 hi_u32 i;
495 hi_u32 reg_base = spi_dev_ctrl->reg_base;
496 hi_u32 read_pos = spi_dev_ctrl->rx_buf.cur_pos;
497 if (fifo_irq) {
498 for (i = 0; i < loop; i++) {
499 *((hi_u8 *)read_buf + read_pos) = (hi_u8)hi_reg_read_val16(reg_base + REG_SPI_DR);
500 read_pos += increase_step;
501 }
502 spi_dev_ctrl->rx_buf.cur_cnt += loop;
503 } else {
504 for (i = 0; i < loop; i++) {
505 if (hi_likely(!spi_check_rx_fifo_empty(reg_base))) {
506 *((hi_u8 *)read_buf + read_pos) = (hi_u8)hi_reg_read_val16(reg_base + REG_SPI_DR);
507 read_pos += increase_step;
508 spi_dev_ctrl->rx_buf.cur_cnt++;
509 } else {
510 break;
511 }
512 }
513 }
514 spi_dev_ctrl->rx_buf.cur_pos = read_pos;
515 }
516
spi_isr_read_fifo(spi_ctrl * spi_dev_ctrl,hi_bool fifo_irq)517 static hi_u16 spi_isr_read_fifo(spi_ctrl *spi_dev_ctrl, hi_bool fifo_irq)
518 {
519 hi_pvoid read_buf = spi_dev_ctrl->rx_buf.buf;
520 hi_u16 fix_data = SPI_UNUSE_DATA;
521 hi_u16 increase_step = 1;
522 hi_u32 loop = hi_min(spi_dev_ctrl->single_len, (spi_dev_ctrl->trans_len - spi_dev_ctrl->rx_buf.cur_cnt));
523 if (read_buf == HI_NULL) {
524 read_buf = &fix_data;
525 increase_step = 0;
526 }
527
528 if (hi_likely(spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT)) {
529 spi_isr_read_8bits(spi_dev_ctrl, fifo_irq, loop, read_buf, increase_step);
530 } else {
531 spi_isr_read_16bits(spi_dev_ctrl, fifo_irq, loop, read_buf, increase_step);
532 }
533
534 if (spi_dev_ctrl->rx_buf.cur_cnt >= spi_dev_ctrl->trans_len) {
535 return SPI_INT_BIT_RX_FIFO_WATER_LINE | SPI_INT_BIT_RX_FIFO_TIME_OUT;
536 }
537 return 0;
538 }
539
spi_isr_write_fifo(spi_ctrl * spi_dev_ctrl)540 static hi_u16 spi_isr_write_fifo(spi_ctrl *spi_dev_ctrl)
541 {
542 hi_pvoid write_buf = spi_dev_ctrl->tx_buf.buf;
543 hi_u32 i;
544 hi_u16 fix_data = SPI_UNUSE_DATA;
545 hi_u16 increase_step = 1;
546 hi_u32 reg_base = spi_dev_ctrl->reg_base;
547 hi_u32 len = spi_dev_ctrl->single_len;
548 hi_u32 write_pos = spi_dev_ctrl->tx_buf.cur_pos;
549 if (write_buf == HI_NULL) {
550 write_buf = &fix_data;
551 increase_step = 0;
552 }
553 if (hi_likely(spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT)) {
554 for (i = 0; i < len; i++) {
555 spi_process_printf("[wreg8][0x%x]", *((hi_u8 *)write_buf + write_pos));
556 hi_reg_write16(reg_base + REG_SPI_DR, *((hi_u8 *)write_buf + write_pos));
557 write_pos += increase_step;
558 }
559 spi_dev_ctrl->tx_buf.cur_cnt += len;
560 } else {
561 for (i = 0; i < len; i++) {
562 spi_process_printf("[wreg16][0x%x]", *((hi_u16 *)write_buf + write_pos));
563 hi_reg_write16(reg_base + REG_SPI_DR, *((hi_u16 *)write_buf + write_pos));
564 write_pos += increase_step;
565 }
566 spi_dev_ctrl->tx_buf.cur_cnt += len;
567 }
568 spi_dev_ctrl->tx_buf.cur_pos = write_pos;
569 if (spi_dev_ctrl->tx_buf.cur_cnt == spi_dev_ctrl->single_len) {
570 spi_dev_ctrl->tx_buf.cur_cnt = 0;
571 return SPI_INT_BIT_TX_FIFO_WATER_LINE;
572 }
573 return 0;
574 }
575
spi_isr(spi_ctrl * spi_dev_ctrl)576 hi_void spi_isr(spi_ctrl *spi_dev_ctrl)
577 {
578 if (spi_dev_ctrl == NULL) {
579 spi_process_printf("spi_isr para is null \n");
580 return;
581 }
582 hi_u32 reg_base = spi_dev_ctrl->reg_base;
583 hi_u16 int_val;
584 hi_u32 event_bits = 0;
585 hi_u16 dis_int_bis = 0;
586 hi_u16 clear_int_bits = 0;
587 hi_u32 ret;
588 hi_reg_read16(reg_base + REG_SPI_MIS, int_val);
589 if (int_val & SPI_INT_BIT_TX_FIFO_WATER_LINE) {
590 dis_int_bis |= spi_isr_write_fifo(spi_dev_ctrl);
591 event_bits |= HI_EVENT_BIT_TX_DATA;
592 }
593 if (int_val & SPI_INT_BIT_RX_FIFO_WATER_LINE) {
594 dis_int_bis |= spi_isr_read_fifo(spi_dev_ctrl, HI_TRUE);
595 event_bits |= HI_EVENT_BIT_RX_DATA;
596 }
597 if (int_val & SPI_INT_BIT_RX_FIFO_TIME_OUT) {
598 dis_int_bis |= spi_isr_read_fifo(spi_dev_ctrl, HI_FALSE);
599 event_bits |= HI_EVENT_BIT_RX_DATA;
600 clear_int_bits |= SPI_INT_BIT_RTIC;
601 }
602 if (int_val & SPI_INT_BIT_RX_FIFO_OVER_FLOW) {
603 dis_int_bis |= SPI_INT_BIT_RX_FIFO_OVER_FLOW;
604 event_bits |= HI_EVENT_BIT_RX_FIFO_OVER_FLOW;
605 clear_int_bits |= SPI_INT_BIT_RORIC;
606 }
607 spi_isr_clear_cr(reg_base, clear_int_bits);
608 spi_isr_disable(reg_base, dis_int_bis);
609 if (spi_dev_ctrl->disable_later && !spi_check_busy(reg_base)) {
610 spi_dev_ctrl->disable_later = HI_FALSE;
611 }
612 ret = hi_event_send(spi_dev_ctrl->event_id, event_bits);
613 if (ret != HI_ERR_SUCCESS) {
614 spi_process_printf("spi_isr send sig fail \n");
615 }
616 }
617
spi_trans_prepare(spi_ctrl * spi_hw_ctrl,spi_trans_attr * trans_attr)618 hi_u32 spi_trans_prepare(spi_ctrl *spi_hw_ctrl, spi_trans_attr *trans_attr)
619 {
620 hi_u32 ret = HI_ERR_SUCCESS;
621 if ((spi_hw_ctrl == NULL) || (trans_attr == NULL)) {
622 return HI_ERR_FAILURE;
623 }
624
625 if (trans_attr->trans_opt & SPI_OPT_WAIT_SIGNAL) {
626 spi_process_printf("wait_sem\n");
627 ret = hi_sem_wait(spi_hw_ctrl->sem_id, trans_attr->time_out_ms);
628 if (ret != HI_ERR_SUCCESS) {
629 return ret;
630 }
631 trans_attr->trans_opt |= SPI_OPT_TASKED_SIGNAL;
632 }
633 spi_hw_ctrl->transferring = HI_TRUE;
634 if (spi_hw_ctrl->prepare_func) {
635 spi_hw_ctrl->prepare_func();
636 }
637 if (trans_attr->trans_opt & SPI_OPT_ENABLE_SPI) {
638 spi_enable(spi_hw_ctrl);
639 }
640 return ret;
641 }
642
spi_trans_restore(spi_ctrl * spi_hw_ctrl,const spi_trans_attr * trans_attr)643 hi_void spi_trans_restore(spi_ctrl *spi_hw_ctrl, const spi_trans_attr *trans_attr)
644 {
645 if ((spi_hw_ctrl == NULL) || (trans_attr == NULL)) {
646 return;
647 }
648 if (spi_hw_ctrl->restore_func) {
649 spi_hw_ctrl->restore_func();
650 }
651
652 if ((trans_attr->trans_opt & SPI_OPT_TASKED_SIGNAL) && (trans_attr->trans_opt & SPI_OPT_FREE_SIGNAL)) {
653 spi_process_printf("free_sem\n");
654 hi_u32 ret = hi_sem_signal(spi_hw_ctrl->sem_id);
655 if (ret != HI_ERR_SUCCESS) {
656 spi_process_printf("free_sem fail\n");
657 }
658 }
659 spi_hw_ctrl->transferring = HI_FALSE;
660 }
661
spi_transfer_8bits_block(const spi_ctrl * spi_hw_ctrl,hi_u32 options)662 hi_u32 spi_transfer_8bits_block(const spi_ctrl *spi_hw_ctrl, hi_u32 options)
663 {
664 if (spi_hw_ctrl == NULL) {
665 return HI_ERR_FAILURE;
666 }
667 hi_u32 tmp_len, count;
668 hi_u16 value;
669 hi_u8 *tx = (hi_u8 *)spi_hw_ctrl->tx_buf.buf;
670 hi_u8 *rx = (hi_u8 *)spi_hw_ctrl->rx_buf.buf;
671 hi_u32 len = spi_hw_ctrl->trans_len;
672 hi_u16 fifo_len = (spi_hw_ctrl->reg_base == HI_SSP0_REG_BASE ? SPI0_FIFO_LEN : SPI1_FIFO_LEN);
673 hi_bool write_not_fix = ((options & SPI_OPT_SEND_FIX_DATA) == 0);
674 hi_bool read_not_fix = ((options & SPI_OPT_RCV_FIX_DATA) == 0);
675 hi_u32 ret;
676 while (len) {
677 if (len > fifo_len) {
678 tmp_len = fifo_len;
679 } else {
680 tmp_len = len;
681 }
682 len -= tmp_len;
683 /* wirte fifo */
684 count = tmp_len;
685 value = SPI_UNUSE_DATA;
686 while (count) {
687 if (write_not_fix && tx != HI_NULL) {
688 value = *tx++;
689 }
690 hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_DR, value);
691 count -= 1;
692 }
693 ret = spi_check_write_timeout(spi_hw_ctrl->reg_base);
694 if (ret != HI_ERR_SUCCESS) {
695 return HI_ERR_SPI_WRITE_TIMEOUT;
696 }
697 /* if host device too fast, there be delay 50-100us */
698 /* read fifo */
699 count = tmp_len;
700 while (count) {
701 hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_DR, value);
702 if (read_not_fix && rx != HI_NULL) {
703 *rx++ = (hi_u8)value;
704 }
705 count -= 1;
706 }
707 }
708 return HI_ERR_SUCCESS;
709 }
710
711 /*
712 * spi_txrx16: send and receive 16bit data
713 */
spi_transfer_16bits_block(const spi_ctrl * spi_hw_ctrl,hi_u32 options)714 hi_u32 spi_transfer_16bits_block(const spi_ctrl *spi_hw_ctrl, hi_u32 options)
715 {
716 if (spi_hw_ctrl == NULL) {
717 return HI_ERR_FAILURE;
718 }
719 hi_u32 len = spi_hw_ctrl->trans_len;
720 hi_u32 tmp_len;
721 hi_u32 count;
722 hi_u16 *tx = (hi_u16 *)spi_hw_ctrl->tx_buf.buf;
723 hi_u16 *rx = (hi_u16 *)spi_hw_ctrl->rx_buf.buf;
724 hi_u16 value;
725 hi_u16 fifo_len = (spi_hw_ctrl->reg_base == HI_SSP0_REG_BASE ? SPI0_FIFO_LEN : SPI1_FIFO_LEN);
726 hi_bool write_not_fix = ((options & SPI_OPT_SEND_FIX_DATA) == 0);
727 hi_bool read_not_fix = ((options & SPI_OPT_RCV_FIX_DATA) == 0);
728 hi_u32 ret;
729 while (len) {
730 if (len > fifo_len) {
731 tmp_len = fifo_len;
732 } else {
733 tmp_len = len;
734 }
735 len -= tmp_len;
736 /* wirte fifo */
737 count = tmp_len;
738 value = SPI_UNUSE_DATA;
739 while (count) {
740 if (write_not_fix && tx != HI_NULL) {
741 value = *tx++;
742 }
743 hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_DR, value);
744 count--;
745 }
746 ret = spi_check_write_timeout(spi_hw_ctrl->reg_base);
747 if (ret != HI_ERR_SUCCESS) {
748 return HI_ERR_SPI_WRITE_TIMEOUT;
749 }
750 /* if host device too fast, there be delay 50-100us */
751 count = tmp_len;
752 while (count) {
753 hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_DR, value);
754 if (read_not_fix && rx != HI_NULL) {
755 *rx++ = value;
756 }
757 count--;
758 }
759 }
760 return HI_ERR_SUCCESS;
761 }
762