• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 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_hi35xx.h"
17 #include "device_resource_if.h"
18 #include "dmac_core.h"
19 #include "hdf_base.h"
20 #include "hdf_log.h"
21 #include "los_vm_phys.h"
22 #include "osal_io.h"
23 #include "osal_irq.h"
24 #include "osal_mem.h"
25 #include "osal_sem.h"
26 #include "osal_time.h"
27 #include "spi_core.h"
28 #include "spi_dev.h"
29 
30 #define HDF_LOG_TAG spi_hi35xx
31 
32 struct Pl022 {
33     struct SpiCntlr *cntlr;
34     struct DListHead deviceList;
35     struct OsalSem sem;
36     volatile unsigned char *phyBase;
37     volatile unsigned char *regBase;
38     uint32_t irqNum;
39     uint32_t busNum;
40     uint32_t numCs;
41     uint32_t curCs;
42     uint32_t speed;
43     uint32_t fifoSize;
44     uint32_t clkRate;
45     uint32_t maxSpeedHz;
46     uint32_t minSpeedHz;
47     uint32_t regCrg;
48     uint32_t clkEnBit;
49     uint32_t clkRstBit;
50     uint32_t regMiscCtrl;
51     uint32_t miscCtrlCsShift;
52     uint32_t miscCtrlCs;
53     uint16_t mode;
54     uint8_t bitsPerWord;
55     uint8_t transferMode;
56 };
57 
SpiCfgCs(struct Pl022 * pl022,uint32_t cs)58 static int32_t SpiCfgCs(struct Pl022 *pl022, uint32_t cs)
59 {
60     uint32_t value;
61 
62     if ((cs + 1) > pl022->numCs) {
63         HDF_LOGE("%s: cs %d is big than pl022 csNum %d", __func__, cs, pl022->numCs);
64         return HDF_FAILURE;
65     }
66     if (pl022->numCs == 1) {
67         return HDF_SUCCESS;
68     }
69     value = OSAL_READL(pl022->regMiscCtrl);
70     value &= ~pl022->miscCtrlCs;
71     value |= (cs << pl022->miscCtrlCsShift);
72     OSAL_WRITEL(value, pl022->regMiscCtrl);
73     return 0;
74 }
75 
SpiHwInitCfg(struct Pl022 * pl022)76 static int32_t SpiHwInitCfg(struct Pl022 *pl022)
77 {
78     uint32_t value;
79 
80     value = OSAL_READL(pl022->regCrg);
81     value &= ~pl022->clkRstBit;
82     value |= pl022->clkEnBit;
83     OSAL_WRITEL(value, pl022->regCrg); /* open spi clk */
84     return 0;
85 }
86 
SpiHwExitCfg(struct Pl022 * pl022)87 static int32_t SpiHwExitCfg(struct Pl022 *pl022)
88 {
89     uint32_t value;
90 
91     value = OSAL_READL(pl022->regCrg);
92     value |= pl022->clkRstBit;
93     value &= ~pl022->clkEnBit;
94     OSAL_WRITEL(value, pl022->regCrg); /* close spi clk */
95     return 0;
96 }
97 
Pl022Enable(const struct Pl022 * pl022)98 static void Pl022Enable(const struct Pl022 *pl022)
99 {
100     uint32_t value;
101 
102     value = OSAL_READL((uintptr_t)(pl022->regBase) + REG_SPI_CR1);
103     value |= SPI_CR1_SSE;
104     OSAL_WRITEL(value, (uintptr_t)(pl022->regBase) + REG_SPI_CR1);
105 }
106 
Pl022Disable(const struct Pl022 * pl022)107 static void Pl022Disable(const struct Pl022 *pl022)
108 {
109     uint32_t value;
110 
111     value = OSAL_READL((uintptr_t)(pl022->regBase) + REG_SPI_CR1);
112     value &= ~SPI_CR1_SSE;
113     OSAL_WRITEL(value, (uintptr_t)(pl022->regBase) + REG_SPI_CR1);
114 }
115 
Pl022ConfigCPSR(const struct Pl022 * pl022,uint32_t cpsdvsr)116 static void Pl022ConfigCPSR(const struct Pl022 *pl022, uint32_t cpsdvsr)
117 {
118     uint32_t value;
119 
120     value = OSAL_READL((uintptr_t)(pl022->regBase) + REG_SPI_CPSR);
121     value &= ~SPI_CPSR_CPSDVSR;
122     value |= cpsdvsr << SPI_CPSR_CPSDVSR_SHIFT;
123     OSAL_WRITEL(value, (uintptr_t)(pl022->regBase) + REG_SPI_CPSR);
124 }
125 
Pl022ConfigCR0(const struct Pl022 * pl022,uint32_t scr)126 static void Pl022ConfigCR0(const struct Pl022 *pl022, uint32_t scr)
127 {
128     uint32_t tmp;
129     uint32_t value;
130 
131     value = OSAL_READL((uintptr_t)(pl022->regBase) + REG_SPI_CR0);
132     value &= ~SPI_CR0_DSS;
133     value |= (pl022->bitsPerWord - 1) << SPI_CR0_DSS_SHIFT;
134     value &= ~SPI_CR0_FRF;
135     value &= ~SPI_CR0_SPO;
136     tmp = (!!(pl022->mode & SPI_CLK_POLARITY)) ? (1 << SPI_CR0_SPO_SHIFT) : 0;
137     value |= tmp;
138     value &= ~SPI_CR0_SPH;
139     tmp = (!!(pl022->mode & SPI_CLK_PHASE)) ? (1 << SPI_CR0_SPH_SHIFT) : 0;
140     value |= tmp;
141     value &= ~SPI_CR0_SCR;
142     value |= (scr << SPI_CR0_SCR_SHIFT);
143     OSAL_WRITEL(value, (uintptr_t)(pl022->regBase) + REG_SPI_CR0);
144 }
145 
Pl022ConfigCR1(const struct Pl022 * pl022)146 static void Pl022ConfigCR1(const struct Pl022 *pl022)
147 {
148     uint32_t tmp;
149     uint32_t value;
150 
151     value = OSAL_READL((uintptr_t)(pl022->regBase) + REG_SPI_CR1);
152     value &= ~SPI_CR1_LBN;
153     tmp = (!!(pl022->mode & SPI_MODE_LOOP)) ? (1 << SPI_CR1_LBN_SHIFT) : 0;
154     value |= tmp;
155     value &= ~SPI_CR1_MS;
156     value &= ~SPI_CR1_BIG_END;
157     tmp = (!!(pl022->mode & SPI_MODE_LSBFE)) ? (1 << SPI_CR1_BIG_END_SHIFT) : 0;
158     value |= tmp;
159     value &= ~SPI_CR1_ALT;
160     value |= 0x1 << SPI_CR1_ALT_SHIFT;
161     OSAL_WRITEL(value, (uintptr_t)(pl022->regBase) + REG_SPI_CR1);
162 }
163 
Pl022ConfigDma(struct Pl022 * pl022)164 static void Pl022ConfigDma(struct Pl022 *pl022)
165 {
166     uint32_t value;
167     if (pl022->transferMode == SPI_DMA_TRANSFER) {
168         OSAL_WRITEL((0x1 << TX_DMA_EN_SHIFT) | (0x1 << RX_DMA_EN_SHIFT),
169             (uintptr_t)(pl022->regBase) + SPI_DMA_CR);
170 
171         value = OSAL_READL((uintptr_t)(pl022->regBase) + SPI_TX_FIFO_CR);
172         value &= ~(TX_DMA_BR_SIZE_MASK << TX_DMA_BR_SIZE_SHIFT);
173         OSAL_WRITEL(value, (uintptr_t)(pl022->regBase) + SPI_TX_FIFO_CR);
174 
175         value = OSAL_READL((uintptr_t)(pl022->regBase) + SPI_RX_FIFO_CR);
176         value &= ~(RX_DMA_BR_SIZE_MASK << RX_DMA_BR_SIZE_SHIFT);
177         OSAL_WRITEL(value, (uintptr_t)(pl022->regBase) + SPI_RX_FIFO_CR);
178     } else {
179         OSAL_WRITEL(0, (uintptr_t)(pl022->regBase) + SPI_DMA_CR);
180     }
181 }
182 
183 #define RX_INT_SIZE_VALUE      0x6
184 #define RX_INT_FIFO_LEVEL      (256 - 128)
185 #define RX_INT_WAIT_TIMEOUT    1000 // ms
186 
Pl022ConfigIrq(struct Pl022 * pl022)187 static void Pl022ConfigIrq(struct Pl022 *pl022)
188 {
189     unsigned long value;
190 
191     if (pl022->transferMode == SPI_INTERRUPT_TRANSFER) {
192         value = OSAL_READL((uintptr_t)(pl022->regBase) + SPI_RX_FIFO_CR);
193         value &= ~(RX_INT_SIZE_MASK << RX_INT_SIZE_SHIFT);
194         value |= ((RX_INT_SIZE_VALUE & RX_INT_SIZE_MASK) << RX_INT_SIZE_SHIFT);
195         OSAL_WRITEL(value, (uintptr_t)(pl022->regBase) + SPI_RX_FIFO_CR);
196     }
197 
198     OSAL_WRITEL(SPI_ALL_IRQ_DISABLE, (uintptr_t)(pl022->regBase) + REG_SPI_IMSC);
199     OSAL_WRITEL(SPI_ALL_IRQ_CLEAR, (uintptr_t)(pl022->regBase) + REG_SPI_ICR);
200 }
201 
Pl022Config(struct Pl022 * pl022)202 static int32_t Pl022Config(struct Pl022 *pl022)
203 {
204     uint32_t tmp;
205     uint32_t scr;
206     uint32_t cpsdvsr;
207 
208     Pl022Disable(pl022);
209     /* Check if we can provide the requested rate */
210     if (pl022->speed > pl022->maxSpeedHz) {
211         HDF_LOGW("%s: invalid speed:%d, use max:%d instead", __func__, pl022->speed, pl022->maxSpeedHz);
212         pl022->speed = pl022->maxSpeedHz;
213     }
214     /* Min possible */
215     if (pl022->speed == 0 || pl022->speed < pl022->minSpeedHz) {
216         HDF_LOGW("%s: invalid speed:%d, use min:%d instead", __func__, pl022->speed, pl022->minSpeedHz);
217         pl022->speed = pl022->minSpeedHz;
218     }
219     /* Check if we can provide the requested bits_per_word */
220     if ((pl022->bitsPerWord < BITS_PER_WORD_MIN) || (pl022->bitsPerWord > BITS_PER_WORD_MAX)) {
221         HDF_LOGE("%s: pl022->bitsPerWord is %d not support", __func__, pl022->bitsPerWord);
222         return HDF_FAILURE;
223     }
224     /* compute spi speed, speed=clk/(cpsdvsr*(scr+1)) */
225     tmp = (pl022->clkRate) / (pl022->speed);
226     cpsdvsr = (tmp < CPSDVSR_MIN) ? CPSDVSR_MIN : (tmp <= CPSDVSR_MAX) ? (tmp & (~0x1)) : CPSDVSR_MAX;
227     scr = (tmp < CPSDVSR_MIN) ? 0 : (tmp <= CPSDVSR_MAX);
228 
229     /* config SPICPSR register */
230     Pl022ConfigCPSR(pl022, cpsdvsr);
231     /* config SPICR0 register */
232     Pl022ConfigCR0(pl022, scr);
233     /* config SPICR1 register */
234     Pl022ConfigCR1(pl022);
235     /* config irq */
236     Pl022ConfigIrq(pl022);
237     /* config dma */
238     Pl022ConfigDma(pl022);
239     return 0;
240 }
241 
Pl022CheckTimeout(const struct Pl022 * pl022)242 static int32_t Pl022CheckTimeout(const struct Pl022 *pl022)
243 {
244     uint32_t tmp = 0;
245     unsigned long value;
246 
247     while (1) {
248         value = OSAL_READL((uintptr_t)(pl022->regBase) + REG_SPI_SR);
249         if ((value & SPI_SR_TFE) && (!(value & SPI_SR_BSY))) {
250             break;
251         }
252         if (tmp++ > MAX_WAIT) {
253             HDF_LOGE("%s: spi transfer wait timeout", __func__);
254             return HDF_ERR_TIMEOUT;
255         }
256         OsalUDelay(1);
257     }
258     return HDF_SUCCESS;
259 }
260 
Pl022FlushFifo(const struct Pl022 * pl022)261 static int32_t Pl022FlushFifo(const struct Pl022 *pl022)
262 {
263     uint32_t value;
264     uint32_t tmp;
265 
266     tmp = Pl022CheckTimeout(pl022);
267     if (tmp) {
268         return tmp;
269     }
270     while (1) {
271         value = OSAL_READL((uintptr_t)(pl022->regBase) + REG_SPI_SR);
272         if (!(value & SPI_SR_RNE)) {
273             break;
274         }
275         if (tmp++ > pl022->fifoSize) {
276             HDF_LOGE("%s: spi transfer check rx fifo wait timeout", __func__);
277             return HDF_ERR_TIMEOUT;
278         }
279         OSAL_READL((uintptr_t)(pl022->regBase) + REG_SPI_DR);
280     }
281     return 0;
282 }
283 
284 #define PL022_ONE_BYTE 1
285 #define PL022_TWO_BYTE 2
286 
Pl022ToByteWidth(uint8_t bitsPerWord)287 static inline uint8_t Pl022ToByteWidth(uint8_t bitsPerWord)
288 {
289     if (bitsPerWord <= BITS_PER_WORD_EIGHT) {
290         return PL022_ONE_BYTE;
291     } else {
292         return PL022_TWO_BYTE;
293     }
294 }
295 
Pl022WriteFifo(const struct Pl022 * pl022,const uint8_t * tx,uint32_t count)296 static void Pl022WriteFifo(const struct Pl022 *pl022, const uint8_t *tx, uint32_t count)
297 {
298     unsigned long value;
299     uint8_t bytes = Pl022ToByteWidth(pl022->bitsPerWord);
300 
301     for (value = 0; count >= bytes; count -= bytes) {
302         if (tx != NULL) {
303             value = (bytes == 1) ? *tx : *((uint16_t *)tx);
304             tx += bytes;
305         }
306         OSAL_WRITEL(value, (uintptr_t)(pl022->regBase) + REG_SPI_DR);
307     }
308 }
309 
Pl022ReadFifo(const struct Pl022 * pl022,uint8_t * rx,uint32_t count)310 static void Pl022ReadFifo(const struct Pl022 *pl022, uint8_t *rx, uint32_t count)
311 {
312     unsigned long value;
313     uint8_t bytes = Pl022ToByteWidth(pl022->bitsPerWord);
314 
315     for (value = 0; count >= bytes; count -= bytes) {
316         value = OSAL_READL((uintptr_t)(pl022->regBase) + REG_SPI_DR);
317         if (rx == NULL) {
318             continue;
319         }
320         if (bytes == 1) {
321             *rx = (uint8_t)value;
322         } else {
323             *((uint16_t *)rx) = (uint16_t)value;
324         }
325         rx += bytes;
326     }
327 }
328 
Pl022TxRx(const struct Pl022 * pl022,const struct SpiMsg * msg)329 static int32_t Pl022TxRx(const struct Pl022 *pl022, const struct SpiMsg *msg)
330 {
331     int32_t ret;
332     uint32_t tmpLen;
333     uint32_t len = msg->len;
334     const uint8_t *tx = msg->wbuf;
335     uint8_t *rx = msg->rbuf;
336     uint8_t bytes = Pl022ToByteWidth(pl022->bitsPerWord);
337     uint32_t burstSize = pl022->fifoSize * bytes;
338 
339     if (tx == NULL && rx == NULL) {
340         return HDF_ERR_INVALID_PARAM;
341     }
342 
343     if (pl022->transferMode == SPI_INTERRUPT_TRANSFER && RX_INT_FIFO_LEVEL < pl022->fifoSize) {
344         burstSize = RX_INT_FIFO_LEVEL * bytes;
345     }
346 
347     for (tmpLen = 0, len = msg->len; len > 0; len -= tmpLen) {
348         tmpLen = (len > burstSize) ? burstSize : len;
349         if (pl022->transferMode == SPI_INTERRUPT_TRANSFER && tmpLen == burstSize) {
350             OSAL_WRITEL(SPI_ALL_IRQ_ENABLE, (uintptr_t)(pl022->regBase) + REG_SPI_IMSC);
351         }
352         Pl022WriteFifo(pl022, tx, tmpLen);
353         tx = (tx == NULL) ? NULL : tx + tmpLen;
354         if (pl022->transferMode == SPI_INTERRUPT_TRANSFER && tmpLen == burstSize) {
355             ret = OsalSemWait((struct OsalSem *)(&pl022->sem), RX_INT_WAIT_TIMEOUT);
356         } else {
357             ret = Pl022CheckTimeout(pl022);
358         }
359 
360         if (ret != HDF_SUCCESS) {
361             HDF_LOGE("%s: %s timeout", __func__, (pl022->transferMode == SPI_INTERRUPT_TRANSFER) ?
362                 "wait rx fifo int" : "wait tx fifo idle");
363             return ret;
364         }
365 
366         Pl022ReadFifo(pl022, rx, tmpLen);
367         rx = (rx == NULL) ? NULL : (rx + tmpLen);
368     }
369     return 0;
370 }
371 
Pl022SetCs(struct Pl022 * pl022,uint32_t cs,uint32_t flag)372 static int32_t Pl022SetCs(struct Pl022 *pl022, uint32_t cs, uint32_t flag)
373 {
374     if (SpiCfgCs(pl022, cs)) {
375         return HDF_FAILURE;
376     }
377     if (flag == SPI_CS_ACTIVE) {
378         Pl022Enable(pl022);
379     } else {
380         Pl022Disable(pl022);
381     }
382     return 0;
383 }
384 
Pl022FindDeviceByCsNum(const struct Pl022 * pl022,uint32_t cs)385 static struct SpiDev *Pl022FindDeviceByCsNum(const struct Pl022 *pl022, uint32_t cs)
386 {
387     struct SpiDev *dev = NULL;
388     struct SpiDev *tmpDev = NULL;
389 
390     if (pl022 == NULL || pl022->numCs <= cs) {
391         return NULL;
392     }
393     DLIST_FOR_EACH_ENTRY_SAFE(dev, tmpDev, &(pl022->deviceList), struct SpiDev, list) {
394         if (dev->csNum  == cs) {
395             break;
396         }
397     }
398     return dev;
399 }
400 
Pl022SetCfg(struct SpiCntlr * cntlr,struct SpiCfg * cfg)401 static int32_t Pl022SetCfg(struct SpiCntlr *cntlr, struct SpiCfg *cfg)
402 {
403     struct Pl022 *pl022 = NULL;
404     struct SpiDev *dev = NULL;
405 
406     if (cntlr == NULL || cntlr->priv == NULL || cfg == NULL) {
407         HDF_LOGE("%s: cntlr priv or cfg is NULL", __func__);
408         return HDF_ERR_INVALID_PARAM;
409     }
410     pl022 = (struct Pl022 *)cntlr->priv;
411     dev = Pl022FindDeviceByCsNum(pl022, cntlr->curCs);
412     if (dev == NULL) {
413         return HDF_FAILURE;
414     }
415     dev->cfg.mode = cfg->mode;
416     dev->cfg.transferMode = cfg->transferMode;
417     if (cfg->bitsPerWord < BITS_PER_WORD_MIN || cfg->bitsPerWord > BITS_PER_WORD_MAX) {
418         HDF_LOGE("%s: bitsPerWord %d not support, use defaule bitsPerWord %d",
419             __func__, cfg->bitsPerWord, BITS_PER_WORD_EIGHT);
420         dev->cfg.bitsPerWord = BITS_PER_WORD_EIGHT;
421     } else {
422         dev->cfg.bitsPerWord = cfg->bitsPerWord;
423     }
424     if (cfg->maxSpeedHz != 0) {
425         dev->cfg.maxSpeedHz = cfg->maxSpeedHz;
426     }
427     return 0;
428 }
429 
Pl022GetCfg(struct SpiCntlr * cntlr,struct SpiCfg * cfg)430 static int32_t Pl022GetCfg(struct SpiCntlr *cntlr, struct SpiCfg *cfg)
431 {
432     struct Pl022 *pl022 = NULL;
433     struct SpiDev *dev = NULL;
434 
435     if (cntlr == NULL || cntlr->priv == NULL || cfg == NULL) {
436         HDF_LOGE("%s: cntlr priv or cfg is NULL", __func__);
437         return HDF_ERR_INVALID_PARAM;
438     }
439     pl022 = (struct Pl022 *)cntlr->priv;
440     dev = Pl022FindDeviceByCsNum(pl022, cntlr->curCs);
441     if (dev == NULL) {
442         return HDF_FAILURE;
443     }
444     *cfg = dev->cfg;
445     return HDF_SUCCESS;
446 }
447 
448 struct SpiDmaEvent {
449     const struct SpiMsg *spiMsg;
450     struct DmacMsg *dmaMsg;
451     struct OsalSem sem;
452     int32_t retValue;
453 };
454 
Pl022DmaCallBack(void * data,int status)455 static void Pl022DmaCallBack(void *data, int status)
456 {
457     struct SpiDmaEvent *xEvent = (struct SpiDmaEvent *)data;
458 
459     if (xEvent != NULL) {
460 #ifdef SPI_HI35XX_DEBUG
461         HDF_LOGD("%s: dmamsg transfer %s!", __func__, status == DMAC_CHN_SUCCESS ? "Success!" : "Error!");
462 #endif
463         if (status != DMAC_CHN_SUCCESS) {
464             xEvent->retValue = HDF_FAILURE;
465             HDF_LOGE("%s: dma msg transfer failed, status = %d", __func__, status);
466         }
467         (void)OsalSemPost(&xEvent->sem);
468     }
469 }
470 
GetDmaCntlr(void)471 static struct DmaCntlr *GetDmaCntlr(void)
472 {
473     static struct DmaCntlr *cntlr = NULL;
474 
475     if (cntlr == NULL) {
476         cntlr = (struct DmaCntlr *)DevSvcManagerClntGetService("HDF_PLATFORM_DMAC0");
477         if (cntlr != NULL) {
478             HDF_LOGE("%s: get dmac0 success!", __func__);
479         } else {
480             HDF_LOGE("%s: get dmac0 fail!", __func__);
481         }
482     }
483     return cntlr;
484 }
485 
Pl022AllocBufPhy(size_t len)486 static inline uintptr_t Pl022AllocBufPhy(size_t len)
487 {
488     void *tmpBuf = OsalMemCalloc(len);
489     return tmpBuf == NULL ? 0 : (uintptr_t)LOS_PaddrQuery(tmpBuf);
490 }
491 
Pl022RleaseBufPhy(uintptr_t buf)492 static inline void Pl022RleaseBufPhy(uintptr_t buf)
493 {
494     void *tmpBuf = NULL;
495 
496     if (buf != 0) {
497         tmpBuf = LOS_PaddrToKVaddr((paddr_t)buf);
498         OsalMemFree(tmpBuf);
499     }
500 }
501 
Pl022TxRxDma(const struct Pl022 * pl022,const struct SpiMsg * msg)502 static int32_t Pl022TxRxDma(const struct Pl022 *pl022, const struct SpiMsg *msg)
503 {
504     int32_t ret;
505     struct SpiDmaEvent rxEvent;
506     struct DmacMsg dmaMsgRx;
507     struct DmacMsg dmaMsgTx;
508     uintptr_t tmpBuf = 0;
509 
510     rxEvent.dmaMsg = &dmaMsgRx;
511     rxEvent.spiMsg = msg;
512     rxEvent.retValue = HDF_SUCCESS;
513 
514     (void)OsalSemInit(&rxEvent.sem, 0);
515 
516     if (msg->rbuf == NULL || msg->wbuf == NULL) {
517         if ((tmpBuf = Pl022AllocBufPhy(msg->len)) == 0) {
518             return HDF_ERR_MALLOC_FAIL;
519         }
520     }
521 
522     dmaMsgRx.srcAddr = (uintptr_t)(pl022->phyBase + REG_SPI_DR);
523     dmaMsgRx.destAddr = (msg->rbuf == NULL) ? tmpBuf : (uintptr_t)(LOS_PaddrQuery(msg->rbuf));
524     dmaMsgRx.transLen = msg->len;
525     dmaMsgRx.transType = TRASFER_TYPE_P2M;
526     dmaMsgRx.cb = Pl022DmaCallBack;
527     dmaMsgRx.para = &rxEvent;
528     dmaMsgRx.srcWidth = dmaMsgRx.destWidth = Pl022ToByteWidth(pl022->bitsPerWord);
529 
530     dmaMsgTx.srcAddr = (msg->wbuf == NULL) ? tmpBuf : (uintptr_t)(LOS_PaddrQuery(msg->wbuf));
531     dmaMsgTx.destAddr = (uintptr_t)(pl022->phyBase + REG_SPI_DR);
532     dmaMsgTx.transLen = msg->len;
533     dmaMsgTx.transType = TRASFER_TYPE_M2P;
534     dmaMsgTx.cb = NULL;
535     dmaMsgTx.para = NULL;
536     dmaMsgTx.srcWidth = dmaMsgTx.destWidth = dmaMsgRx.srcWidth;
537 
538     if ((ret = DmaCntlrTransfer(GetDmaCntlr(), &dmaMsgRx)) != HDF_SUCCESS) {
539         HDF_LOGE("%s: rx dma trans fail : %d", __func__, ret);
540         goto __OUT;
541     }
542     if ((ret = DmaCntlrTransfer(GetDmaCntlr(), &dmaMsgTx)) != HDF_SUCCESS) {
543         HDF_LOGE("%s: tx dma trans fail : %d", __func__, ret);
544         goto __OUT;
545     }
546 
547 #ifdef SPI_HI35XX_DEBUG
548     HDF_LOGD("%s: trying to wait dma callback...", __func__);
549 #endif
550     (void)OsalSemWait(&rxEvent.sem, HDF_WAIT_FOREVER);
551     ret = (rxEvent.retValue != HDF_SUCCESS) ? rxEvent.retValue : ret;
552 
553 __OUT:
554     (void)OsalSemDestroy(&rxEvent.sem);
555     Pl022RleaseBufPhy(tmpBuf);
556     return ret;
557 }
558 
Pl022TransferOneMessage(struct Pl022 * pl022,struct SpiMsg * msg)559 static int32_t Pl022TransferOneMessage(struct Pl022 *pl022, struct SpiMsg *msg)
560 {
561     int32_t ret;
562 
563     pl022->speed = (msg->speed) == 0 ? DEFAULT_SPEED : msg->speed;
564 
565     ret = Pl022Config(pl022);
566     if (ret != 0) {
567         return ret;
568     }
569     ret = Pl022SetCs(pl022, pl022->curCs, SPI_CS_ACTIVE);
570     if (ret != 0) {
571         return ret;
572     }
573     ret = Pl022FlushFifo(pl022);
574     if (ret != 0) {
575         return ret;
576     }
577     if (pl022->transferMode == SPI_DMA_TRANSFER) {
578         ret = Pl022TxRxDma(pl022, msg);
579     } else {
580         ret = Pl022TxRx(pl022, msg);
581     }
582     if (ret || msg->csChange) {
583         Pl022SetCs(pl022, pl022->curCs, SPI_CS_INACTIVE);
584     }
585     return ret;
586 }
587 
Pl022Transfer(struct SpiCntlr * cntlr,struct SpiMsg * msg,uint32_t count)588 static int32_t Pl022Transfer(struct SpiCntlr *cntlr, struct SpiMsg *msg, uint32_t count)
589 {
590     int32_t ret = HDF_FAILURE;
591     uint32_t i;
592     struct Pl022 *pl022 = NULL;
593     struct SpiDev *dev = NULL;
594 
595     if (cntlr == NULL || cntlr->priv == NULL) {
596         HDF_LOGE("%s: invalid controller", __func__);
597         return HDF_ERR_INVALID_OBJECT;
598     }
599     if (msg == NULL || (msg->rbuf == NULL && msg->wbuf == NULL) || count == 0) {
600         HDF_LOGE("%s: invalid parameter", __func__);
601         return HDF_ERR_INVALID_PARAM;
602     }
603 
604     pl022 = (struct Pl022 *)cntlr->priv;
605     dev = Pl022FindDeviceByCsNum(pl022, cntlr->curCs);
606     if (dev == NULL) {
607         goto __ERR;
608     }
609     pl022->mode = dev->cfg.mode;
610     pl022->transferMode = dev->cfg.transferMode;
611     pl022->bitsPerWord = dev->cfg.bitsPerWord;
612     pl022->maxSpeedHz = dev->cfg.maxSpeedHz;
613     pl022->curCs = dev->csNum;
614     for (i = 0; i < count; i++) {
615         ret = Pl022TransferOneMessage(pl022, &(msg[i]));
616         if (ret != 0) {
617             HDF_LOGE("%s: transfer error", __func__);
618             goto __ERR;
619         }
620     }
621 __ERR:
622     return ret;
623 }
624 
Pl022Open(struct SpiCntlr * cntlr)625 int32_t Pl022Open(struct SpiCntlr *cntlr)
626 {
627     (void)cntlr;
628     return HDF_SUCCESS;
629 }
630 
Pl022Close(struct SpiCntlr * cntlr)631 int32_t Pl022Close(struct SpiCntlr *cntlr)
632 {
633     (void)cntlr;
634     return HDF_SUCCESS;
635 }
636 
Pl022Probe(struct Pl022 * pl022)637 static int32_t Pl022Probe(struct Pl022 *pl022)
638 {
639     int32_t ret;
640 
641     ret = SpiHwInitCfg(pl022);
642     if (ret != 0) {
643         HDF_LOGE("%s: SpiHwInitCfg error", __func__);
644         return HDF_FAILURE;
645     }
646     ret = Pl022Config(pl022);
647     if (ret != 0) {
648         HDF_LOGE("%s: Pl022Config error", __func__);
649     }
650     return ret;
651 }
652 
653 struct SpiCntlrMethod g_method = {
654     .Transfer = Pl022Transfer,
655     .SetCfg = Pl022SetCfg,
656     .GetCfg = Pl022GetCfg,
657     .Open = Pl022Open,
658     .Close = Pl022Close,
659 };
660 
Pl022CreatAndInitDevice(struct Pl022 * pl022)661 static int32_t Pl022CreatAndInitDevice(struct Pl022 *pl022)
662 {
663     uint32_t i;
664     struct SpiDev *device = NULL;
665 
666     for (i = 0; i < pl022->numCs; i++) {
667         device = (struct SpiDev *)OsalMemCalloc(sizeof(*device));
668         if (device == NULL) {
669             HDF_LOGE("%s: OsalMemCalloc error", __func__);
670             return HDF_FAILURE;
671         }
672         device->cntlr = pl022->cntlr;
673         device->csNum = i;
674         device->cfg.bitsPerWord = pl022->bitsPerWord;
675         device->cfg.transferMode = pl022->transferMode;
676         device->cfg.maxSpeedHz = pl022->maxSpeedHz;
677         device->cfg.mode = pl022->mode;
678         DListHeadInit(&device->list);
679         DListInsertTail(&device->list, &pl022->deviceList);
680         SpiAddDev(device);
681     }
682     return 0;
683 }
684 
Pl022Release(struct Pl022 * pl022)685 static void Pl022Release(struct Pl022 *pl022)
686 {
687     struct SpiDev *dev = NULL;
688     struct SpiDev *tmpDev = NULL;
689 
690     DLIST_FOR_EACH_ENTRY_SAFE(dev, tmpDev, &(pl022->deviceList), struct SpiDev, list) {
691         SpiRemoveDev(dev);
692         DListRemove(&(dev->list));
693         OsalMemFree(dev);
694     }
695     if (pl022->irqNum != 0) {
696         (void)OsalUnregisterIrq(pl022->irqNum, pl022);
697     }
698     OsalMemFree(pl022);
699 }
700 
SpiGetBaseCfgFromHcs(struct Pl022 * pl022,const struct DeviceResourceNode * node)701 static int32_t SpiGetBaseCfgFromHcs(struct Pl022 *pl022, const struct DeviceResourceNode *node)
702 {
703     struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
704 
705     if (iface == NULL || iface->GetUint8 == NULL || iface->GetUint16 == NULL || iface->GetUint32 == NULL) {
706         HDF_LOGE("%s: face is invalid", __func__);
707         return HDF_FAILURE;
708     }
709     if (iface->GetUint32(node, "busNum", &pl022->busNum, 0) != HDF_SUCCESS) {
710         HDF_LOGE("%s: read busNum fail", __func__);
711         return HDF_FAILURE;
712     }
713     if (iface->GetUint32(node, "numCs", &pl022->numCs, 0) != HDF_SUCCESS) {
714         HDF_LOGE("%s: read numCs fail", __func__);
715         return HDF_FAILURE;
716     }
717     if (iface->GetUint32(node, "speed", &pl022->speed, 0) != HDF_SUCCESS) {
718         HDF_LOGE("%s: read speed fail", __func__);
719         return HDF_FAILURE;
720     }
721     if (iface->GetUint32(node, "fifoSize", &pl022->fifoSize, 0) != HDF_SUCCESS) {
722         HDF_LOGE("%s: read fifoSize fail", __func__);
723         return HDF_FAILURE;
724     }
725     if (iface->GetUint32(node, "clkRate", &pl022->clkRate, 0) != HDF_SUCCESS) {
726         HDF_LOGE("%s: read clkRate fail", __func__);
727         return HDF_FAILURE;
728     }
729     if (iface->GetUint16(node, "mode", &pl022->mode, 0) != HDF_SUCCESS) {
730         HDF_LOGE("%s: read mode fail", __func__);
731         return HDF_FAILURE;
732     }
733     if (iface->GetUint8(node, "bitsPerWord", &pl022->bitsPerWord, 0) != HDF_SUCCESS) {
734         HDF_LOGE("%s: read bitsPerWord fail", __func__);
735         return HDF_FAILURE;
736     }
737     if (iface->GetUint8(node, "transferMode", &pl022->transferMode, 0) != HDF_SUCCESS) {
738         HDF_LOGE("%s: read comMode fail", __func__);
739         return HDF_FAILURE;
740     }
741     return 0;
742 }
743 
SpiGetRegCfgFromHcs(struct Pl022 * pl022,const struct DeviceResourceNode * node)744 static int32_t SpiGetRegCfgFromHcs(struct Pl022 *pl022, const struct DeviceResourceNode *node)
745 {
746     uint32_t tmp;
747     struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
748 
749     if (iface == NULL || iface->GetUint32 == NULL) {
750         HDF_LOGE("%s: face is invalid", __func__);
751         return HDF_FAILURE;
752     }
753     if (iface->GetUint32(node, "regBase", &tmp, 0) != HDF_SUCCESS) {
754         HDF_LOGE("%s: read regBase fail", __func__);
755         return HDF_FAILURE;
756     }
757     pl022->phyBase = (void *)(uintptr_t)(tmp);
758     pl022->regBase = HDF_IO_DEVICE_ADDR(pl022->phyBase);
759 
760     if (iface->GetUint32(node, "irqNum", &pl022->irqNum, 0) != HDF_SUCCESS) {
761         HDF_LOGE("%s: read irqNum fail", __func__);
762         return HDF_FAILURE;
763     }
764     if (iface->GetUint32(node, "REG_CRG_SPI", &pl022->regCrg, 0) != HDF_SUCCESS) {
765         HDF_LOGE("%s: read regCrg fail", __func__);
766         return HDF_FAILURE;
767     }
768     pl022->regCrg = HDF_IO_DEVICE_ADDR(pl022->regCrg);
769     if (iface->GetUint32(node, "CRG_SPI_CKEN", &pl022->clkEnBit, 0) != HDF_SUCCESS) {
770         HDF_LOGE("%s: read clkEnBit fail", __func__);
771         return HDF_FAILURE;
772     }
773     if (iface->GetUint32(node, "CRG_SPI_RST", &pl022->clkRstBit, 0) != HDF_SUCCESS) {
774         HDF_LOGE("%s: read clkRstBit fail", __func__);
775         return HDF_FAILURE;
776     }
777     if (iface->GetUint32(node, "REG_MISC_CTRL_SPI", &pl022->regMiscCtrl, 0) != HDF_SUCCESS) {
778         HDF_LOGE("%s: read regMiscCtrl fail", __func__);
779         return HDF_FAILURE;
780     }
781     pl022->regMiscCtrl = HDF_IO_DEVICE_ADDR(pl022->regMiscCtrl);
782     if (iface->GetUint32(node, "MISC_CTRL_SPI_CS", &pl022->miscCtrlCs, 0) != HDF_SUCCESS) {
783         HDF_LOGE("%s: read miscCtrlCs fail", __func__);
784         return HDF_FAILURE;
785     }
786     if (iface->GetUint32(node, "MISC_CTRL_SPI_CS_SHIFT", &pl022->miscCtrlCsShift, 0) != HDF_SUCCESS) {
787         HDF_LOGE("%s: read miscCtrlCsShift fail", __func__);
788         return HDF_FAILURE;
789     }
790     return 0;
791 }
792 
Pl022IrqHandleNoShare(uint32_t irq,void * data)793 static uint32_t Pl022IrqHandleNoShare(uint32_t irq, void *data)
794 {
795     unsigned long value;
796     struct Pl022 *pl022 = (struct Pl022 *)data;
797 
798     (void)irq;
799     if (pl022 == NULL) {
800         HDF_LOGE("%s: data is NULL!", __func__);
801         return HDF_ERR_INVALID_PARAM;
802     }
803     // check SPI_RX_INTR
804     value = OSAL_READL((uintptr_t)(pl022->regBase) + REG_SPI_MIS);
805     if ((value & SPI_RX_INTR_MASK) != 0) {
806         OSAL_WRITEL(SPI_ALL_IRQ_DISABLE, (uintptr_t)(pl022->regBase) + REG_SPI_IMSC);
807         OSAL_WRITEL(SPI_ALL_IRQ_CLEAR, (uintptr_t)(pl022->regBase) + REG_SPI_ICR);
808         (void)OsalSemPost(&pl022->sem);
809     }
810 
811     return HDF_SUCCESS;
812 }
813 
Pl022Init(struct SpiCntlr * cntlr,const struct HdfDeviceObject * device)814 static int32_t Pl022Init(struct SpiCntlr *cntlr, const struct HdfDeviceObject *device)
815 {
816     int32_t ret;
817     struct Pl022 *pl022 = NULL;
818 
819     if (device->property == NULL) {
820         HDF_LOGE("%s: property is NULL", __func__);
821         return HDF_ERR_INVALID_PARAM;
822     }
823 
824     pl022 = (struct Pl022 *)OsalMemCalloc(sizeof(*pl022));
825     if (pl022 == NULL) {
826         HDF_LOGE("%s: OsalMemCalloc error", __func__);
827         return HDF_FAILURE;
828     }
829     ret = SpiGetBaseCfgFromHcs(pl022, device->property);
830     if (ret != HDF_SUCCESS) {
831         HDF_LOGE("%s: SpiGetBaseCfgFromHcs error", __func__);
832         OsalMemFree(pl022);
833         return HDF_FAILURE;
834     }
835     ret = SpiGetRegCfgFromHcs(pl022, device->property);
836     if (ret != HDF_SUCCESS) {
837         HDF_LOGE("%s: SpiGetRegCfgFromHcs error", __func__);
838         OsalMemFree(pl022);
839         return HDF_FAILURE;
840     }
841     pl022->maxSpeedHz = (pl022->clkRate) / ((SCR_MIN + 1) * CPSDVSR_MIN);
842     pl022->minSpeedHz = (pl022->clkRate) / ((SCR_MAX + 1) * CPSDVSR_MAX);
843     DListHeadInit(&pl022->deviceList);
844     pl022->cntlr = cntlr;
845     cntlr->priv = pl022;
846     cntlr->busNum = pl022->busNum;
847     cntlr->method = &g_method;
848     ret = OsalSemInit(&pl022->sem, 0);
849     if (ret != HDF_SUCCESS) {
850         OsalMemFree(pl022);
851         return ret;
852     }
853 
854     if (pl022->irqNum != 0) {
855         OSAL_WRITEL(SPI_ALL_IRQ_DISABLE, (uintptr_t)(pl022->regBase) + REG_SPI_IMSC);
856         ret = OsalRegisterIrq(pl022->irqNum, 0, Pl022IrqHandleNoShare, "SPI_HI35XX", pl022);
857         if (ret != HDF_SUCCESS) {
858             OsalMemFree(pl022);
859             (void)OsalSemDestroy(&pl022->sem);
860             return ret;
861         }
862     }
863 
864     ret = Pl022CreatAndInitDevice(pl022);
865     if (ret != 0) {
866         Pl022Release(pl022);
867         return ret;
868     }
869     return 0;
870 }
871 
Pl022Remove(struct Pl022 * pl022)872 static void Pl022Remove(struct Pl022 *pl022)
873 {
874     if (SpiHwExitCfg(pl022) != 0) {
875         HDF_LOGE("%s: SpiHwExitCfg error", __func__);
876     }
877     Pl022Release(pl022);
878 }
879 
HdfSpiDeviceBind(struct HdfDeviceObject * device)880 static int32_t HdfSpiDeviceBind(struct HdfDeviceObject *device)
881 {
882     HDF_LOGI("%s: entry", __func__);
883     if (device == NULL) {
884         return HDF_ERR_INVALID_OBJECT;
885     }
886     return (SpiCntlrCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS;
887 }
888 
HdfSpiDeviceInit(struct HdfDeviceObject * device)889 static int32_t HdfSpiDeviceInit(struct HdfDeviceObject *device)
890 {
891     int32_t ret;
892     struct SpiCntlr *cntlr = NULL;
893 
894     HDF_LOGI("%s: entry", __func__);
895     if (device == NULL) {
896         HDF_LOGE("%s: ptr is null", __func__);
897         return HDF_ERR_INVALID_OBJECT;
898     }
899     cntlr = SpiCntlrFromDevice(device);
900     if (cntlr == NULL) {
901         HDF_LOGE("%s: cntlr is null", __func__);
902         return HDF_FAILURE;
903     }
904 
905     ret = Pl022Init(cntlr, device);
906     if (ret != 0) {
907         HDF_LOGE("%s: error init", __func__);
908         return HDF_FAILURE;
909     }
910     ret = Pl022Probe(cntlr->priv);
911     if (ret != 0) {
912         HDF_LOGE("%s: error probe", __func__);
913     }
914     return ret;
915 }
916 
HdfSpiDeviceRelease(struct HdfDeviceObject * device)917 static void HdfSpiDeviceRelease(struct HdfDeviceObject *device)
918 {
919     struct SpiCntlr *cntlr = NULL;
920 
921     HDF_LOGI("%s: entry", __func__);
922     if (device == NULL) {
923         HDF_LOGE("%s: device is null", __func__);
924         return;
925     }
926     cntlr = SpiCntlrFromDevice(device);
927     if (cntlr == NULL) {
928         HDF_LOGE("%s: cntlr is null", __func__);
929         return;
930     }
931     if (cntlr->priv != NULL) {
932         Pl022Remove((struct Pl022 *)cntlr->priv);
933     }
934     SpiCntlrDestroy(cntlr);
935 }
936 
937 struct HdfDriverEntry g_hdfSpiDevice = {
938     .moduleVersion = 1,
939     .moduleName = "HDF_PLATFORM_SPI",
940     .Bind = HdfSpiDeviceBind,
941     .Init = HdfSpiDeviceInit,
942     .Release = HdfSpiDeviceRelease,
943 };
944 
945 HDF_INIT(g_hdfSpiDevice);
946