1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13/* SPI driver */
14
15#include <autoconf.h>
16#include <platsupport/gen_config.h>
17#include <stdio.h>
18#include <stdint.h>
19#include <platsupport/spi.h>
20#include <platsupport/plat/mux.h>
21#include "../../services.h"
22
23//#define DEBUG_SPI
24#ifdef DEBUG_SPI
25#define DSPI(args...) \
26    do { \
27        printf("SPI %s(%d):", __func__, __LINE__); \
28        printf(args); \
29        printf("\n"); \
30    } while(0)
31#else
32#define DSPI(...) do{}while(0)
33#endif
34
35/* SPI configuration */
36#define CH_CFG_HIGH_SPEED_EN       BIT(6)
37#define CH_CFG_SW_RST              BIT(5)
38#define CH_CFG_SLAVE               BIT(4)
39#define CH_CFG_CPOL                BIT(3)
40#define CH_CFG_CPHA                BIT(2)
41#define CH_CFG_RX_CH_ON            BIT(1)
42#define CH_CFG_TX_CH_ON            BIT(0)
43
44/* FIFO control */
45#define FIFO_SIZE                   64
46#define MODE_CFG_CH_WIDTH_SHF      (29)
47#define MODE_CFG_TRAILING_CNT_SHF  (19)
48#define MODE_CFG_BUS_WIDTH_SHF     (17)
49#define MODE_CFG_RX_RDY_LVL_SHF    (11)
50#define MODE_CFG_TX_RDY_LVL_SHF    (5)
51#define MODE_CFG_RX_DMA_SW         BIT(2)
52#define MODE_CFG_TX_DMA_SW         BIT(1)
53#define MODE_CFG_DMA_TYPE          BIT(0)
54
55/* Slave selection control */
56#define CS_REG_NCS_TIME_COUNT_SHF  (4)
57#define CS_REG_AUTO_N_MANUAL       BIT(1)
58#define CS_REG_NSSOUT              BIT(0)
59
60/* Interrupt enable */
61#define INT_EN_TRAILING            BIT(6)
62#define INT_EN_RX_OVERRUN          BIT(5)
63#define INT_EN_RX_UNDERRUN         BIT(4)
64#define INT_EN_TX_OVERRUN          BIT(3)
65#define INT_EN_TX_UNDERRUN         BIT(2)
66#define INT_EN_RX_FIFO_RDY         BIT(1)
67#define INT_EN_TX_FIFO_RDY         BIT(0)
68
69/* SPI status */
70#define STATUS_TX_DONE             BIT(25)
71#define STATUS_TRAILING_BYTE       BIT(24)
72#define STATUS_RX_FIFO_LVL_SHF     (15)
73#define STATUS_TX_FIFO_LVL_SHF     (6)
74#define STATUS_RX_OVERRUN          BIT(5)
75#define STATUS_RX_UNDERRUN         BIT(4)
76#define STATUS_TX_OVERRUN          BIT(3)
77#define STATUS_TX_UNDERRUN         BIT(2)
78#define STATUS_RX_FIFO_RDY         BIT(1)
79#define STATUS_TX_FIFO_RDY         BIT(0)
80
81/* Packet count */
82#define PACKET_CNT_EN              BIT(16)
83#define PACKET_CNT_VALUE_SHF       BIT(0)
84
85/* Interrupt pending clear */
86#define PENDING_CLR_TX_UNDERRUN    BIT(4)
87#define PENDING_CLR_TX_OVERRUN     BIT(3)
88#define PENDING_CLR_RX_UNDERRUN    BIT(2)
89#define PENDING_CLR_RX_OVERRUN     BIT(1)
90#define PENDING_CLR_TRAILING       BIT(0)
91
92/* Swap configuration */
93#define SWAP_CFG_RX_HWORD          BIT(7)
94#define SWAP_CFG_RX_BYTE           BIT(6)
95#define SWAP_CFG_RX_BIT            BIT(5)
96#define SWAP_CFG_RX_EN             BIT(4)
97#define SWAP_CFG_TX_HWORD          BIT(3)
98#define SWAP_CFG_TX_BYTE           BIT(2)
99#define SWAP_CFG_TX_BIT            BIT(1)
100#define SWAP_CFG_TX_EN             BIT(0)
101
102/* Feedback clock selection */
103#define FB_CLK_SEL_SHF             (0)
104
105struct spi_regs {
106    uint32_t ch_cfg;
107    uint32_t res;
108    uint32_t mode_cfg;
109    uint32_t cs_reg;
110    uint32_t int_en;
111    uint32_t status;
112    uint32_t tx_data;
113    uint32_t rx_data;
114    uint32_t packet_cnt;
115    uint32_t pending_clr;
116    uint32_t swap_cfg;
117    uint32_t fb_clk_sel;
118};
119
120enum spi_mode {
121    MASTER_MODE = 0,
122    SLAVE_MODE
123};
124
125struct spi_bus {
126    volatile struct spi_regs* regs;
127    enum mux_feature mux;
128    enum clk_id clkid;
129    int mode: 1;              //0 -- Master, 1 -- Slave
130    int high_speed: 1;        //High speed operation in slave mode.
131    int cs_auto: 1;           //Auto chip selection.
132    clk_t *clk;               //Clock for changing the bus speed.
133
134    /* Transfer management */
135    const char *txbuf;
136    char *rxbuf;
137    size_t txcnt, rxcnt;
138    size_t txsize, rxsize;
139    spi_callback_fn cb;
140    void* token;
141};
142
143static spi_bus_t _spi[NSPI] = {
144    { .regs = NULL, .mux = MUX_SPI0, .clkid = CLK_SPI0 },
145    { .regs = NULL, .mux = MUX_SPI1, .clkid = CLK_SPI1 },
146    { .regs = NULL, .mux = MUX_SPI2, .clkid = CLK_SPI2 },
147#if defined(CONFIG_PLAT_EXYNOS5)
148    { .regs = NULL, .mux = MUX_SPI0_ISP, .clkid = CLK_SPI0_ISP },
149    { .regs = NULL, .mux = MUX_SPI1_ISP, .clkid = CLK_SPI1_ISP },
150#endif /* EXYNOSX */
151};
152
153static void
154spi_reset(spi_bus_t *spi_bus)
155{
156    uint32_t v;
157
158    /* Turn off the channel */
159    v = spi_bus->regs->ch_cfg;
160    v &= ~(CH_CFG_RX_CH_ON | CH_CFG_TX_CH_ON);
161    spi_bus->regs->ch_cfg = v;
162
163    /* Write to reset bit */
164    v = spi_bus->regs->ch_cfg;
165    v |= CH_CFG_SW_RST;
166    spi_bus->regs->ch_cfg = v;
167
168    /* Clear reset bit */
169    v = spi_bus->regs->ch_cfg;
170    v &= ~CH_CFG_SW_RST;
171    spi_bus->regs->ch_cfg = v;
172
173    /* Turn on the channel */
174    v = spi_bus->regs->ch_cfg;
175    v |= (CH_CFG_RX_CH_ON | CH_CFG_TX_CH_ON);
176    spi_bus->regs->ch_cfg = v;
177}
178
179static void
180spi_config(spi_bus_t *spi_bus)
181{
182    uint32_t v;
183
184    /* Step1: SPI configuration */
185    v = 0;
186    /* Master/Slave mode */
187    if (spi_bus->mode == SLAVE_MODE) {
188        v |= CH_CFG_SLAVE;
189
190        /* High speed mode is slave mode only */
191        if (spi_bus->high_speed) {
192            v |= CH_CFG_HIGH_SPEED_EN;
193            v &= ~CH_CFG_CPHA;
194        }
195    }
196    spi_bus->regs->ch_cfg = v;
197
198    /*
199     * Step2: Feedback clock
200     * The default clock is 33MHz, so we use a 180 degree phase feedback.
201     * The feedback clock only works in the master mode.
202     */
203    if (spi_bus->mode == MASTER_MODE) {
204        v = (0x2 << FB_CLK_SEL_SHF);
205        spi_bus->regs->fb_clk_sel = v;
206    }
207
208    /*
209     * Step3: FIFO control
210     * Channel width to Byte, No DMA, only need to set trigger level.
211     */
212    v = (0x20 << MODE_CFG_RX_RDY_LVL_SHF) | (0x20 << MODE_CFG_TX_RDY_LVL_SHF);
213    spi_bus->regs->mode_cfg = v;
214
215    /* Step4: Interrupts */
216    spi_bus->regs->int_en = 0x0;
217    spi_bus->regs->pending_clr = 0xff;
218
219    /* Step5: Packet control */
220    spi_bus->regs->packet_cnt = 0;
221
222    /* Step6: Turn on the channel */
223    v = spi_bus->regs->ch_cfg;
224    v |= (CH_CFG_RX_CH_ON | CH_CFG_TX_CH_ON);
225    spi_bus->regs->ch_cfg = v;
226
227    /* Step7: Chip selection */
228    v = (0x0 << CS_REG_NCS_TIME_COUNT_SHF);
229    if (spi_bus->cs_auto) {
230        v |= CS_REG_AUTO_N_MANUAL;
231    } else {
232        v |= CS_REG_NSSOUT;
233    }
234    spi_bus->regs->cs_reg = v;
235}
236
237static void
238spi_cs(spi_bus_t* spi_bus, enum spi_cs_state state)
239{
240    if (!spi_bus->cs_auto) {
241        uint32_t v;
242        v = spi_bus->regs->cs_reg;
243        if (state == SPI_CS_ASSERT) {
244            v &= ~CS_REG_NSSOUT;
245        } else {
246            v |= CS_REG_NSSOUT;
247        }
248        spi_bus->regs->cs_reg = v;
249    }
250}
251
252static int
253spi_init_common(spi_bus_t* spi_bus, mux_sys_t* mux_sys, clock_sys_t* clock_sys)
254{
255    if (mux_sys && mux_sys_valid(mux_sys)) {
256        mux_feature_enable(mux_sys, spi_bus->mux, MUX_DIR_NOT_A_GPIO);
257    } else {
258//        LOG_INFO("SPI: Skipping MUX initialisation as no mux subsystem was provided\n");
259    }
260
261    if (clock_sys && clock_sys_valid(clock_sys)) {
262        spi_bus->clk = clk_get_clock(clock_sys, spi_bus->clkid);
263    } else {
264//        LOG_INFO("SPI: Assuming default clock frequency as no clock subsystem was provided\n");
265        spi_bus->clk = NULL;
266    }
267
268    spi_bus->mode = 0;
269    spi_bus->high_speed = 0;
270    spi_bus->cs_auto = 0;
271
272    spi_reset(spi_bus);
273    spi_config(spi_bus);
274    return 0;
275}
276
277int
278transfer_data(spi_bus_t* spi_bus)
279{
280    int rxfifo_cnt, txfifo_cnt, txfifo_space;
281    uint32_t stat;
282    stat = spi_bus->regs->status;
283    rxfifo_cnt = (stat >> STATUS_RX_FIFO_LVL_SHF) & 0x1FF;
284    txfifo_cnt = (stat >> STATUS_TX_FIFO_LVL_SHF) & 0x1FF;
285    txfifo_space = FIFO_SIZE - txfifo_cnt - 1;
286
287    /* Check for fatal events */
288    if (stat & STATUS_RX_OVERRUN) {
289        printf("SPI RX overrun\n");
290    }
291    if (stat & STATUS_RX_UNDERRUN) {
292        printf("SPI RX underrun\n");
293    }
294    if (stat & STATUS_TX_OVERRUN) {
295        printf("SPI TX overrun\n");
296    }
297    if (stat & STATUS_TX_UNDERRUN) {
298        printf("SPI TX underrun\n");
299    }
300
301    /* Drain the RX FIFO */
302    while (rxfifo_cnt--) {
303        uint32_t d;
304        d = spi_bus->regs->rx_data;
305        /* Store the data only if we are in RX phase */
306        if (spi_bus->rxcnt >= spi_bus->txsize) {
307            assert(spi_bus->rxcnt - spi_bus->txsize < spi_bus->rxsize);
308        }
309        *spi_bus->rxbuf++ = d;
310        spi_bus->rxcnt++;
311    }
312
313    /* Fill the TX FIFO */
314    if (txfifo_space > spi_bus->txsize + spi_bus->rxsize - spi_bus->rxcnt) {
315        txfifo_space = spi_bus->txsize + spi_bus->rxsize - spi_bus->txcnt;
316    }
317    while (txfifo_space--) {
318        uint32_t d;
319        if (spi_bus->txcnt < spi_bus->txsize) {
320            d = *spi_bus->txbuf++;
321        } else {
322            d = 0;
323        }
324        spi_bus->regs->tx_data = d;
325        spi_bus->txcnt++;
326    }
327
328    /* Check for completion */
329    if ((stat & STATUS_TX_DONE) && spi_bus->rxcnt == spi_bus->rxsize + spi_bus->txsize) {
330        spi_bus->regs->int_en = 0;
331        spi_cs(spi_bus, SPI_CS_RELAX);
332        if (spi_bus->cb) {
333            spi_bus->cb(spi_bus, spi_bus->txcnt, spi_bus->token);
334        }
335
336        return 0;
337    }
338
339    return 1;
340}
341
342void
343spi_handle_irq(spi_bus_t* spi_bus)
344{
345    transfer_data(spi_bus);
346}
347
348int
349spi_xfer(spi_bus_t* spi_bus, const void* txdata, size_t txcnt,
350         void* rxdata, size_t rxcnt, spi_callback_fn cb, void* token)
351{
352    spi_bus->txbuf = (const char*)txdata;
353    spi_bus->rxbuf = (char*)rxdata;
354    spi_bus->rxsize = rxcnt;
355    spi_bus->txsize = txcnt;
356    spi_bus->rxcnt = 0;
357    spi_bus->txcnt = 0;
358
359    DSPI("Starting transfer: TX: from 0x%x, %d bytes. RX to 0x%x, %d bytes\n",
360         (uint32_t)txdata, txcnt, (uint32_t)rxdata, rxcnt);
361
362    transfer_data(spi_bus);
363    spi_cs(spi_bus, SPI_CS_ASSERT);
364    if (cb == NULL) {
365        while (transfer_data(spi_bus));
366    } else {
367        uint32_t v;
368        spi_bus->cb = cb;
369        spi_bus->token = token;
370        v = INT_EN_RX_OVERRUN  | INT_EN_RX_UNDERRUN
371            | INT_EN_TX_OVERRUN  | INT_EN_TX_UNDERRUN
372            | INT_EN_RX_FIFO_RDY | INT_EN_TX_FIFO_RDY
373            | INT_EN_TRAILING;
374        spi_bus->regs->pending_clr = 0xFFFFFFFF;
375        spi_bus->regs->int_en = v;
376    }
377
378    return spi_bus->rxcnt;
379}
380
381long
382spi_set_speed(spi_bus_t* spi_bus, long bps)
383{
384    return 0;
385}
386
387void
388spi_prepare_transfer(spi_bus_t* spi_bus, const spi_slave_config_t* cfg)
389{
390    if (spi_bus->clk && clk_get_freq(spi_bus->clk) != cfg->speed_hz) {
391        clk_set_freq(spi_bus->clk, cfg->speed_hz);
392    }
393
394    /* Set feedback clock, only when SPI runs at a high frequency */
395    if (cfg->speed_hz >= 1 * MHZ) {
396        spi_bus->regs->fb_clk_sel = (cfg->fb_delay << FB_CLK_SEL_SHF);
397    }
398}
399
400int
401exynos_spi_init(enum spi_id id, void* base,
402                mux_sys_t* mux_sys, clock_sys_t* clock_sys,
403                spi_bus_t** ret_spi_bus)
404{
405    if (id >= 0 && id < NSPI) {
406        spi_bus_t* spi_bus = _spi + id;
407        *ret_spi_bus = spi_bus;
408        spi_bus->regs = base;
409        return spi_init_common(spi_bus, mux_sys, clock_sys);
410    } else {
411        return -1;
412    }
413}
414
415int
416spi_init(enum spi_id id, ps_io_ops_t* io_ops, spi_bus_t** ret_spi_bus)
417{
418    spi_bus_t* spi_bus = _spi + id;
419    *ret_spi_bus = spi_bus;
420    /* Map memory */
421    DSPI("Mapping spi %d\n", id);
422    switch (id) {
423    case SPI0:
424        MAP_IF_NULL(io_ops, EXYNOS_SPI0,      spi_bus->regs);
425        break;
426    case SPI1:
427        MAP_IF_NULL(io_ops, EXYNOS_SPI1,      spi_bus->regs);
428        break;
429    case SPI2:
430        MAP_IF_NULL(io_ops, EXYNOS_SPI2,      spi_bus->regs);
431        break;
432#ifdef CONFIG_PLAT_EXYNOS5
433    case SPI0_ISP:
434        MAP_IF_NULL(io_ops, EXYNOS_SPI0_ISP,  spi_bus->regs);
435        break;
436    case SPI1_ISP:
437        MAP_IF_NULL(io_ops, EXYNOS_SPI1_ISP,  spi_bus->regs);
438        break;
439#endif
440    default:
441        return -1;
442    }
443
444    return spi_init_common(spi_bus, &io_ops->mux_sys, &io_ops->clock_sys);
445}
446