1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <errno.h>
18#include <string.h>
19
20#include <gpio.h>
21#include <spi.h>
22#include <spi_priv.h>
23#include <util.h>
24#include <atomicBitset.h>
25#include <atomic.h>
26#include <platform.h>
27
28#include <plat/cmsis.h>
29#include <plat/dma.h>
30#include <plat/gpio.h>
31#include <plat/pwr.h>
32#include <plat/exti.h>
33#include <plat/syscfg.h>
34#include <plat/spi.h>
35#include <plat/plat.h>
36
37#define SPI_CR1_CPHA                (1 << 0)
38#define SPI_CR1_CPOL                (1 << 1)
39#define SPI_CR1_MSTR                (1 << 2)
40
41#define SPI_CR1_BR(x)               ((LOG2_CEIL(x) - 1) << 3)
42#define SPI_CR1_BR_MIN              2
43#define SPI_CR1_BR_MAX              256
44#define SPI_CR1_BR_MASK             (0x7 << 3)
45
46#define SPI_CR1_SPE                 (1 << 6)
47#define SPI_CR1_LSBFIRST            (1 << 7)
48#define SPI_CR1_SSI                 (1 << 8)
49#define SPI_CR1_SSM                 (1 << 9)
50#define SPI_CR1_RXONLY              (1 << 10)
51#define SPI_CR1_DFF                 (1 << 11)
52#define SPI_CR1_BIDIOE              (1 << 14)
53#define SPI_CR1_BIDIMODE            (1 << 15)
54
55#define SPI_CR2_TXEIE               (1 << 7)
56#define SPI_CR2_RXNEIE              (1 << 6)
57#define SPI_CR2_ERRIE               (1 << 5)
58#define SPI_CR2_TXDMAEN             (1 << 1)
59#define SPI_CR2_RXDMAEN             (1 << 0)
60#define SPI_CR2_INT_MASK            (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE)
61
62#define SPI_CR2_SSOE                (1 << 2)
63
64#define SPI_SR_RXNE                 (1 << 0)
65#define SPI_SR_TXE                  (1 << 1)
66#define SPI_SR_BSY                  (1 << 7)
67
68struct StmSpi {
69    volatile uint32_t CR1;
70    volatile uint32_t CR2;
71    volatile uint32_t SR;
72    volatile uint32_t DR;
73    volatile uint32_t CRCPR;
74    volatile uint32_t RXCRCR;
75    volatile uint32_t TXCRCR;
76    volatile uint32_t I2SCFGR;
77    volatile uint32_t I2SPR;
78};
79
80struct StmSpiState {
81    uint8_t bitsPerWord;
82    uint8_t xferEnable;
83
84    uint16_t rxWord;
85    uint16_t txWord;
86
87    bool rxDone;
88    bool txDone;
89
90    struct ChainedIsr isrNss;
91
92    bool nssChange;
93};
94
95struct StmSpiCfg {
96    struct StmSpi *regs;
97
98    uint32_t clockBus;
99    uint32_t clockUnit;
100
101    IRQn_Type irq;
102
103    uint8_t dmaBus;
104};
105
106struct StmSpiDev {
107    struct SpiDevice *base;
108    const struct StmSpiCfg *cfg;
109    const struct StmSpiBoardCfg *board;
110    struct StmSpiState state;
111
112    struct Gpio *miso;
113    struct Gpio *mosi;
114    struct Gpio *sck;
115    struct Gpio *nss;
116};
117
118static inline struct Gpio *stmSpiGpioInit(uint32_t gpioNum, enum StmGpioSpeed speed, enum StmGpioAltFunc func)
119{
120    struct Gpio *gpio = gpioRequest(gpioNum);
121
122    if (gpio)
123        gpioConfigAlt(gpio, speed, GPIO_PULL_NONE, GPIO_OUT_PUSH_PULL, func);
124
125    return gpio;
126}
127
128static inline void stmSpiDataPullMode(struct StmSpiDev *pdev, enum StmGpioSpeed dataSpeed, enum GpioPullMode dataPull)
129{
130    gpioConfigAlt(pdev->miso, dataSpeed, dataPull, GPIO_OUT_PUSH_PULL, pdev->board->gpioFunc);
131    gpioConfigAlt(pdev->mosi, dataSpeed, dataPull, GPIO_OUT_PUSH_PULL, pdev->board->gpioFunc);
132}
133
134static inline void stmSpiSckPullMode(struct StmSpiDev *pdev, enum StmGpioSpeed sckSpeed, enum GpioPullMode sckPull)
135{
136    gpioConfigAlt(pdev->sck, sckSpeed, sckPull, GPIO_OUT_PUSH_PULL, pdev->board->gpioFunc);
137}
138
139static inline void stmSpiStartDma(struct StmSpiDev *pdev,
140        const struct StmSpiDmaCfg *dmaCfg, const void *buf, uint8_t bitsPerWord,
141        bool minc, size_t size, DmaCallbackF callback, bool rx)
142{
143    struct StmSpi *regs = pdev->cfg->regs;
144    struct dmaMode mode;
145
146    memset(&mode, 0, sizeof(mode));
147
148    if (bitsPerWord == 8) {
149        mode.psize = DMA_SIZE_8_BITS;
150        mode.msize = DMA_SIZE_8_BITS;
151    } else {
152        mode.psize = DMA_SIZE_16_BITS;
153        mode.msize = DMA_SIZE_16_BITS;
154    }
155    mode.priority = DMA_PRIORITY_HIGH;
156    mode.direction = rx ? DMA_DIRECTION_PERIPH_TO_MEM :
157            DMA_DIRECTION_MEM_TO_PERIPH;
158    mode.periphAddr = (uintptr_t)&regs->DR;
159    mode.minc = minc;
160    mode.channel = dmaCfg->channel;
161
162    dmaStart(pdev->cfg->dmaBus, dmaCfg->stream, buf, size, &mode, callback,
163            pdev);
164}
165
166static inline int stmSpiEnable(struct StmSpiDev *pdev,
167        const struct SpiMode *mode, bool master)
168{
169    struct StmSpi *regs = pdev->cfg->regs;
170    struct StmSpiState *state = &pdev->state;
171
172    if (mode->bitsPerWord != 8 &&
173            mode->bitsPerWord != 16)
174        return -EINVAL;
175
176    unsigned int div;
177    if (master) {
178        if (!mode->speed)
179            return -EINVAL;
180
181        uint32_t pclk = pwrGetBusSpeed(PERIPH_BUS_AHB1);
182        div = pclk / mode->speed;
183        if (div > SPI_CR1_BR_MAX)
184            return -EINVAL;
185        else if (div < SPI_CR1_BR_MIN)
186            div = SPI_CR1_BR_MIN;
187    }
188
189    atomicWriteByte(&state->xferEnable, false);
190
191    state->txWord = mode->txWord;
192    state->bitsPerWord = mode->bitsPerWord;
193
194    pwrUnitClock(pdev->cfg->clockBus, pdev->cfg->clockUnit, true);
195
196    if (master) {
197        regs->CR1 &= ~SPI_CR1_BR_MASK;
198        regs->CR1 |= SPI_CR1_BR(div);
199    }
200
201    if (mode->cpol == SPI_CPOL_IDLE_LO)
202        regs->CR1 &= ~SPI_CR1_CPOL;
203    else
204        regs->CR1 |= SPI_CR1_CPOL;
205
206    if (mode->cpha == SPI_CPHA_LEADING_EDGE)
207        regs->CR1 &= ~SPI_CR1_CPHA;
208    else
209        regs->CR1 |= SPI_CR1_CPHA;
210
211    if (mode->bitsPerWord == 8)
212        regs->CR1 &= ~SPI_CR1_DFF;
213    else
214        regs->CR1 |= SPI_CR1_DFF;
215
216    if (mode->format == SPI_FORMAT_MSB_FIRST)
217        regs->CR1 &= ~SPI_CR1_LSBFIRST;
218    else
219        regs->CR1 |= SPI_CR1_LSBFIRST;
220
221    if (master)
222        regs->CR1 |= SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_MSTR;
223    else
224        regs->CR1 &= ~(SPI_CR1_SSM | SPI_CR1_MSTR);
225
226    return 0;
227}
228
229static int stmSpiMasterStartSync(struct SpiDevice *dev, spi_cs_t cs,
230        const struct SpiMode *mode)
231{
232    struct StmSpiDev *pdev = dev->pdata;
233
234    int err = stmSpiEnable(pdev, mode, true);
235    if (err < 0)
236        return err;
237
238    stmSpiDataPullMode(pdev, pdev->board->gpioSpeed, pdev->board->gpioPull);
239    stmSpiSckPullMode(pdev, pdev->board->gpioSpeed, mode->cpol ? GPIO_PULL_UP : GPIO_PULL_DOWN);
240
241    if (!pdev->nss)
242        pdev->nss = gpioRequest(cs);
243    if (!pdev->nss)
244        return -ENODEV;
245    gpioConfigOutput(pdev->nss, pdev->board->gpioSpeed, pdev->board->gpioPull, GPIO_OUT_PUSH_PULL, 1);
246
247    return 0;
248}
249
250static int stmSpiSlaveStartSync(struct SpiDevice *dev,
251        const struct SpiMode *mode)
252{
253    struct StmSpiDev *pdev = dev->pdata;
254
255    stmSpiDataPullMode(pdev, pdev->board->gpioSpeed, GPIO_PULL_NONE);
256    stmSpiSckPullMode(pdev, pdev->board->gpioSpeed, GPIO_PULL_NONE);
257
258    if (!pdev->nss)
259        pdev->nss = stmSpiGpioInit(pdev->board->gpioNss, pdev->board->gpioSpeed, pdev->board->gpioFunc);
260    if (!pdev->nss)
261        return -ENODEV;
262
263    return stmSpiEnable(pdev, mode, false);
264}
265
266static inline bool stmSpiIsMaster(struct StmSpiDev *pdev)
267{
268    struct StmSpi *regs = pdev->cfg->regs;
269    return !!(regs->CR1 & SPI_CR1_MSTR);
270}
271
272static void stmSpiDone(struct StmSpiDev *pdev, int err)
273{
274    struct StmSpi *regs = pdev->cfg->regs;
275    struct StmSpiState *state = &pdev->state;
276
277    if (pdev->board->sleepDev >= 0)
278        platReleaseDevInSleepMode(pdev->board->sleepDev);
279
280    while (regs->SR & SPI_SR_BSY)
281        ;
282
283    if (stmSpiIsMaster(pdev)) {
284        if (state->nssChange && pdev->nss)
285            gpioSet(pdev->nss, 1);
286        spiMasterRxTxDone(pdev->base, err);
287    } else {
288        regs->CR2 = SPI_CR2_TXEIE;
289        spiSlaveRxTxDone(pdev->base, err);
290    }
291}
292
293static void stmSpiRxDone(void *cookie, uint16_t bytesLeft, int err)
294{
295    struct StmSpiDev *pdev = cookie;
296    struct StmSpi *regs = pdev->cfg->regs;
297    struct StmSpiState *state = &pdev->state;
298
299    regs->CR2 &= ~SPI_CR2_RXDMAEN;
300    state->rxDone = true;
301
302    if (state->txDone) {
303        atomicWriteByte(&state->xferEnable, false);
304        stmSpiDone(pdev, err);
305    }
306}
307
308static void stmSpiTxDone(void *cookie, uint16_t bytesLeft, int err)
309{
310    struct StmSpiDev *pdev = cookie;
311    struct StmSpi *regs = pdev->cfg->regs;
312    struct StmSpiState *state = &pdev->state;
313
314    regs->CR2 &= ~SPI_CR2_TXDMAEN;
315    state->txDone = true;
316
317    if (state->rxDone) {
318        atomicWriteByte(&state->xferEnable, false);
319        stmSpiDone(pdev, err);
320    }
321}
322
323static int stmSpiRxTx(struct SpiDevice *dev, void *rxBuf, const void *txBuf,
324        size_t size, const struct SpiMode *mode)
325{
326    struct StmSpiDev *pdev = dev->pdata;
327    struct StmSpi *regs = pdev->cfg->regs;
328    struct StmSpiState *state = &pdev->state;
329    bool rxMinc = true, txMinc = true;
330    uint32_t cr2 = SPI_CR2_TXDMAEN;
331
332    if (atomicXchgByte(&state->xferEnable, true) == true)
333        return -EBUSY;
334
335    if (stmSpiIsMaster(pdev) && pdev->nss)
336        gpioSet(pdev->nss, 0);
337
338    state->rxDone = false;
339    state->txDone = false;
340    state->nssChange = mode->nssChange;
341
342    /* In master mode, if RX is ignored at any point, then turning it on
343     * later may cause the SPI/DMA controllers to "receive" a stale byte
344     * sitting in a FIFO somewhere (even when their respective registers say
345     * their FIFOs are empty, and even if the SPI FIFO is explicitly cleared).
346     * Work around this by DMAing bytes we don't care about into a throwaway
347     * 1-word buffer.
348     *
349     * In slave mode, this specific WAR sometimes causes bigger problems
350     * (the first byte TXed is sometimes dropped or corrupted).  Slave mode
351     * has its own WARs below.
352     */
353    if (!rxBuf && stmSpiIsMaster(pdev)) {
354        rxBuf = &state->rxWord;
355        rxMinc = false;
356    }
357
358    if (rxBuf) {
359        stmSpiStartDma(pdev, &pdev->board->dmaRx, rxBuf, mode->bitsPerWord,
360                rxMinc, size, stmSpiRxDone, true);
361        cr2 |= SPI_CR2_RXDMAEN;
362    } else {
363        state->rxDone = true;
364    }
365
366    if (!txBuf) {
367        txBuf = &state->txWord;
368        txMinc = false;
369    }
370    stmSpiStartDma(pdev, &pdev->board->dmaTx, txBuf, mode->bitsPerWord, txMinc,
371            size, stmSpiTxDone, false);
372
373    /* Ensure the TXE and RXNE bits are cleared; otherwise the DMA controller
374     * may "receive" the byte sitting in the SPI controller's FIFO right now,
375     * or drop/corrupt the first TX byte.  Timing is crucial here, so do it
376     * right before enabling DMA.
377     */
378    if (!stmSpiIsMaster(pdev)) {
379        regs->CR2 &= ~SPI_CR2_TXEIE;
380        NVIC_ClearPendingIRQ(pdev->cfg->irq);
381
382        if (regs->SR & SPI_SR_RXNE)
383            (void)regs->DR;
384
385        if (regs->SR & SPI_SR_TXE)
386            regs->DR = mode->txWord;
387    }
388
389    if (pdev->board->sleepDev >= 0)
390        platRequestDevInSleepMode(pdev->board->sleepDev, 12);
391
392    regs->CR2 = cr2;
393    regs->CR1 |= SPI_CR1_SPE;
394
395
396    return 0;
397}
398
399static int stmSpiSlaveIdle(struct SpiDevice *dev, const struct SpiMode *mode)
400{
401    struct StmSpiDev *pdev = dev->pdata;
402    struct StmSpi *regs = pdev->cfg->regs;
403    struct StmSpiState *state = &pdev->state;
404
405    if (atomicXchgByte(&state->xferEnable, true) == true)
406        return -EBUSY;
407
408    regs->CR2 = SPI_CR2_TXEIE;
409    regs->CR1 |= SPI_CR1_SPE;
410
411    atomicXchgByte(&state->xferEnable, false);
412    return 0;
413}
414
415static inline void stmSpiDisable(struct SpiDevice *dev, bool master)
416{
417    struct StmSpiDev *pdev = dev->pdata;
418    struct StmSpi *regs = pdev->cfg->regs;
419
420    while (regs->SR & SPI_SR_BSY)
421        ;
422
423    if (master) {
424        stmSpiSckPullMode(pdev, pdev->board->gpioSpeed, pdev->board->gpioPull);
425    }
426
427    regs->CR2 &= ~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN | SPI_CR2_TXEIE);
428    regs->CR1 &= ~SPI_CR1_SPE;
429    pwrUnitClock(pdev->cfg->clockBus, pdev->cfg->clockUnit, false);
430}
431
432static int stmSpiMasterStopSync(struct SpiDevice *dev)
433{
434    struct StmSpiDev *pdev = dev->pdata;
435
436    if (pdev->nss) {
437        gpioSet(pdev->nss, 1);
438        gpioRelease(pdev->nss);
439    }
440
441    stmSpiDisable(dev, true);
442    pdev->nss = NULL;
443    return 0;
444}
445
446static int stmSpiSlaveStopSync(struct SpiDevice *dev)
447{
448    struct StmSpiDev *pdev = dev->pdata;
449
450    if (pdev->nss)
451        gpioRelease(pdev->nss);
452
453    stmSpiDisable(dev, false);
454    pdev->nss = NULL;
455    return 0;
456}
457
458static bool stmSpiExtiIsr(struct ChainedIsr *isr)
459{
460    struct StmSpiState *state = container_of(isr, struct StmSpiState, isrNss);
461    struct StmSpiDev *pdev = container_of(state, struct StmSpiDev, state);
462
463    if (pdev->nss && !extiIsPendingGpio(pdev->nss))
464        return false;
465
466    spiSlaveCsInactive(pdev->base);
467    if (pdev->nss)
468        extiClearPendingGpio(pdev->nss);
469    return true;
470}
471
472static void stmSpiSlaveSetCsInterrupt(struct SpiDevice *dev, bool enabled)
473{
474    struct StmSpiDev *pdev = dev->pdata;
475    struct ChainedIsr *isr = &pdev->state.isrNss;
476
477    if (enabled) {
478        isr->func = stmSpiExtiIsr;
479
480        if (pdev->nss) {
481            syscfgSetExtiPort(pdev->nss);
482            extiEnableIntGpio(pdev->nss, EXTI_TRIGGER_RISING);
483        }
484        extiChainIsr(pdev->board->irqNss, isr);
485    } else {
486        extiUnchainIsr(pdev->board->irqNss, isr);
487        if (pdev->nss)
488            extiDisableIntGpio(pdev->nss);
489    }
490}
491
492static bool stmSpiSlaveCsIsActive(struct SpiDevice *dev)
493{
494    struct StmSpiDev *pdev = dev->pdata;
495    return pdev->nss && !gpioGet(pdev->nss);
496}
497
498static inline void stmSpiTxe(struct StmSpiDev *pdev)
499{
500    struct StmSpi *regs = pdev->cfg->regs;
501
502    /**
503     * n.b.: if nothing handles the TXE interrupt in slave mode, the SPI
504     * controller will just keep reading the existing value from DR anytime it
505     * needs data
506     */
507    regs->DR = pdev->state.txWord;
508    regs->CR2 &= ~SPI_CR2_TXEIE;
509}
510
511static void stmSpiIsr(struct StmSpiDev *pdev)
512{
513    struct StmSpi *regs = pdev->cfg->regs;
514
515    if (regs->SR & SPI_SR_TXE) {
516        stmSpiTxe(pdev);
517    }
518
519    /* TODO: error conditions */
520}
521
522static int stmSpiRelease(struct SpiDevice *dev)
523{
524    struct StmSpiDev *pdev = dev->pdata;
525
526    NVIC_DisableIRQ(pdev->cfg->irq);
527
528    pdev->base = NULL;
529    return 0;
530}
531
532#define DECLARE_IRQ_HANDLER(_n)             \
533    void SPI##_n##_IRQHandler();            \
534    void SPI##_n##_IRQHandler()             \
535    {                                       \
536        stmSpiIsr(&mStmSpiDevs[_n - 1]); \
537    }
538
539const struct SpiDevice_ops mStmSpiOps = {
540    .masterStartSync = stmSpiMasterStartSync,
541    .masterRxTx = stmSpiRxTx,
542    .masterStopSync = stmSpiMasterStopSync,
543
544    .slaveStartSync = stmSpiSlaveStartSync,
545    .slaveIdle = stmSpiSlaveIdle,
546    .slaveRxTx = stmSpiRxTx,
547    .slaveStopSync = stmSpiSlaveStopSync,
548
549    .slaveSetCsInterrupt = stmSpiSlaveSetCsInterrupt,
550    .slaveCsIsActive = stmSpiSlaveCsIsActive,
551
552    .release = stmSpiRelease,
553};
554
555static const struct StmSpiCfg mStmSpiCfgs[] = {
556    [0] = {
557        .regs = (struct StmSpi *)SPI1_BASE,
558
559        .clockBus = PERIPH_BUS_APB2,
560        .clockUnit = PERIPH_APB2_SPI1,
561
562        .irq = SPI1_IRQn,
563
564        .dmaBus = SPI1_DMA_BUS,
565    },
566    [1] = {
567        .regs = (struct StmSpi *)SPI2_BASE,
568
569        .clockBus = PERIPH_BUS_APB1,
570        .clockUnit = PERIPH_APB1_SPI2,
571
572        .irq = SPI2_IRQn,
573
574        .dmaBus = SPI2_DMA_BUS,
575    },
576    [2] = {
577        .regs = (struct StmSpi *)SPI3_BASE,
578
579        .clockBus = PERIPH_BUS_APB1,
580        .clockUnit = PERIPH_APB1_SPI3,
581
582        .irq = SPI3_IRQn,
583
584        .dmaBus = SPI3_DMA_BUS,
585    },
586};
587
588static struct StmSpiDev mStmSpiDevs[ARRAY_SIZE(mStmSpiCfgs)];
589DECLARE_IRQ_HANDLER(1)
590DECLARE_IRQ_HANDLER(2)
591DECLARE_IRQ_HANDLER(3)
592
593static void stmSpiInit(struct StmSpiDev *pdev, const struct StmSpiCfg *cfg,
594        const struct StmSpiBoardCfg *board, struct SpiDevice *dev)
595{
596    pdev->miso = stmSpiGpioInit(board->gpioMiso, board->gpioSpeed, board->gpioFunc);
597    pdev->mosi = stmSpiGpioInit(board->gpioMosi, board->gpioSpeed, board->gpioFunc);
598    pdev->sck = stmSpiGpioInit(board->gpioSclk, board->gpioSpeed, board->gpioFunc);
599
600    NVIC_EnableIRQ(cfg->irq);
601
602    pdev->base = dev;
603    pdev->cfg = cfg;
604    pdev->board = board;
605}
606
607int spiRequest(struct SpiDevice *dev, uint8_t busId)
608{
609    if (busId >= ARRAY_SIZE(mStmSpiDevs))
610        return -ENODEV;
611
612    const struct StmSpiBoardCfg *board = boardStmSpiCfg(busId);
613    if (!board)
614        return -ENODEV;
615
616    struct StmSpiDev *pdev = &mStmSpiDevs[busId];
617    const struct StmSpiCfg *cfg = &mStmSpiCfgs[busId];
618    if (!pdev->base)
619        stmSpiInit(pdev, cfg, board, dev);
620
621    memset(&pdev->state, 0, sizeof(pdev->state));
622    dev->ops = &mStmSpiOps;
623    dev->pdata = pdev;
624    return 0;
625}
626
627const enum IRQn spiRxIrq(uint8_t busId)
628{
629    if (busId >= ARRAY_SIZE(mStmSpiDevs))
630        return -ENODEV;
631
632    struct StmSpiDev *pdev = &mStmSpiDevs[busId];
633
634    return dmaIrq(pdev->cfg->dmaBus, pdev->board->dmaRx.stream);
635}
636
637const enum IRQn spiTxIrq(uint8_t busId)
638{
639    if (busId >= ARRAY_SIZE(mStmSpiDevs))
640        return -ENODEV;
641
642    struct StmSpiDev *pdev = &mStmSpiDevs[busId];
643
644    return dmaIrq(pdev->cfg->dmaBus, pdev->board->dmaTx.stream);
645}
646