57d41b778b258d431656bc4a682fabc0418828f5
[oweals/u-boot.git] / drivers / spi / uniphier_spi.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * uniphier_spi.c - Socionext UniPhier SPI driver
4  * Copyright 2019 Socionext, Inc.
5  */
6
7 #include <clk.h>
8 #include <common.h>
9 #include <dm.h>
10 #include <log.h>
11 #include <time.h>
12 #include <dm/device_compat.h>
13 #include <linux/bitfield.h>
14 #include <linux/io.h>
15 #include <spi.h>
16 #include <wait_bit.h>
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 #define SSI_CTL                 0x00
21 #define   SSI_CTL_EN            BIT(0)
22
23 #define SSI_CKS                 0x04
24 #define   SSI_CKS_CKRAT_MASK    GENMASK(7, 0)
25 #define   SSI_CKS_CKPHS         BIT(14)
26 #define   SSI_CKS_CKINIT        BIT(13)
27 #define   SSI_CKS_CKDLY         BIT(12)
28
29 #define SSI_TXWDS               0x08
30 #define   SSI_TXWDS_WDLEN_MASK  GENMASK(13, 8)
31 #define   SSI_TXWDS_TDTF_MASK   GENMASK(7, 6)
32 #define   SSI_TXWDS_DTLEN_MASK  GENMASK(5, 0)
33
34 #define SSI_RXWDS               0x0c
35 #define   SSI_RXWDS_RDTF_MASK   GENMASK(7, 6)
36 #define   SSI_RXWDS_DTLEN_MASK  GENMASK(5, 0)
37
38 #define SSI_FPS                 0x10
39 #define   SSI_FPS_FSPOL         BIT(15)
40 #define   SSI_FPS_FSTRT         BIT(14)
41
42 #define SSI_SR                  0x14
43 #define   SSI_SR_BUSY           BIT(7)
44 #define   SSI_SR_TNF            BIT(5)
45 #define   SSI_SR_RNE            BIT(0)
46
47 #define SSI_IE                  0x18
48
49 #define SSI_IC                  0x1c
50 #define   SSI_IC_TCIC           BIT(4)
51 #define   SSI_IC_RCIC           BIT(3)
52 #define   SSI_IC_RORIC          BIT(0)
53
54 #define SSI_FC                  0x20
55 #define   SSI_FC_TXFFL          BIT(12)
56 #define   SSI_FC_TXFTH_MASK     GENMASK(11, 8)
57 #define   SSI_FC_RXFFL          BIT(4)
58 #define   SSI_FC_RXFTH_MASK     GENMASK(3, 0)
59
60 #define SSI_XDR                 0x24    /* TXDR for write, RXDR for read */
61
62 #define SSI_FIFO_DEPTH          8U
63
64 #define SSI_REG_TIMEOUT         (CONFIG_SYS_HZ / 100)   /* 10 ms */
65 #define SSI_XFER_TIMEOUT        (CONFIG_SYS_HZ)         /* 1 sec */
66
67 #define SSI_CLK                 50000000        /* internal I/O clock: 50MHz */
68
69 struct uniphier_spi_platdata {
70         void __iomem *base;
71         u32 frequency;                  /* input frequency */
72         u32 speed_hz;
73         uint deactivate_delay_us;       /* Delay to wait after deactivate */
74         uint activate_delay_us;         /* Delay to wait after activate */
75 };
76
77 struct uniphier_spi_priv {
78         void __iomem *base;
79         u8 mode;
80         u8 fifo_depth;
81         u8 bits_per_word;
82         ulong last_transaction_us;      /* Time of last transaction end */
83 };
84
85 static void uniphier_spi_enable(struct uniphier_spi_priv *priv, int enable)
86 {
87         u32 val;
88
89         val = readl(priv->base + SSI_CTL);
90         if (enable)
91                 val |= SSI_CTL_EN;
92         else
93                 val &= ~SSI_CTL_EN;
94         writel(val, priv->base + SSI_CTL);
95 }
96
97 static void uniphier_spi_regdump(struct uniphier_spi_priv *priv)
98 {
99         pr_debug("CTL   %08x\n", readl(priv->base + SSI_CTL));
100         pr_debug("CKS   %08x\n", readl(priv->base + SSI_CKS));
101         pr_debug("TXWDS %08x\n", readl(priv->base + SSI_TXWDS));
102         pr_debug("RXWDS %08x\n", readl(priv->base + SSI_RXWDS));
103         pr_debug("FPS   %08x\n", readl(priv->base + SSI_FPS));
104         pr_debug("SR    %08x\n", readl(priv->base + SSI_SR));
105         pr_debug("IE    %08x\n", readl(priv->base + SSI_IE));
106         pr_debug("IC    %08x\n", readl(priv->base + SSI_IC));
107         pr_debug("FC    %08x\n", readl(priv->base + SSI_FC));
108         pr_debug("XDR   %08x\n", readl(priv->base + SSI_XDR));
109 }
110
111 static void spi_cs_activate(struct udevice *dev)
112 {
113         struct udevice *bus = dev->parent;
114         struct uniphier_spi_platdata *plat = bus->platdata;
115         struct uniphier_spi_priv *priv = dev_get_priv(bus);
116         ulong delay_us;         /* The delay completed so far */
117         u32 val;
118
119         /* If it's too soon to do another transaction, wait */
120         if (plat->deactivate_delay_us && priv->last_transaction_us) {
121                 delay_us = timer_get_us() - priv->last_transaction_us;
122                 if (delay_us < plat->deactivate_delay_us)
123                         udelay(plat->deactivate_delay_us - delay_us);
124         }
125
126         val = readl(priv->base + SSI_FPS);
127         if (priv->mode & SPI_CS_HIGH)
128                 val |= SSI_FPS_FSPOL;
129         else
130                 val &= ~SSI_FPS_FSPOL;
131         writel(val, priv->base + SSI_FPS);
132
133         if (plat->activate_delay_us)
134                 udelay(plat->activate_delay_us);
135 }
136
137 static void spi_cs_deactivate(struct udevice *dev)
138 {
139         struct udevice *bus = dev->parent;
140         struct uniphier_spi_platdata *plat = bus->platdata;
141         struct uniphier_spi_priv *priv = dev_get_priv(bus);
142         u32 val;
143
144         val = readl(priv->base + SSI_FPS);
145         if (priv->mode & SPI_CS_HIGH)
146                 val &= ~SSI_FPS_FSPOL;
147         else
148                 val |= SSI_FPS_FSPOL;
149         writel(val, priv->base + SSI_FPS);
150
151         /* Remember time of this transaction so we can honour the bus delay */
152         if (plat->deactivate_delay_us)
153                 priv->last_transaction_us = timer_get_us();
154 }
155
156 static int uniphier_spi_claim_bus(struct udevice *dev)
157 {
158         struct udevice *bus = dev->parent;
159         struct uniphier_spi_priv *priv = dev_get_priv(bus);
160         u32 val, size;
161
162         uniphier_spi_enable(priv, false);
163
164         /* disable interrupts */
165         writel(0, priv->base + SSI_IE);
166
167         /* bits_per_word */
168         size = priv->bits_per_word;
169         val = readl(priv->base + SSI_TXWDS);
170         val &= ~(SSI_TXWDS_WDLEN_MASK | SSI_TXWDS_DTLEN_MASK);
171         val |= FIELD_PREP(SSI_TXWDS_WDLEN_MASK, size);
172         val |= FIELD_PREP(SSI_TXWDS_DTLEN_MASK, size);
173         writel(val, priv->base + SSI_TXWDS);
174
175         val = readl(priv->base + SSI_RXWDS);
176         val &= ~SSI_RXWDS_DTLEN_MASK;
177         val |= FIELD_PREP(SSI_RXWDS_DTLEN_MASK, size);
178         writel(val, priv->base + SSI_RXWDS);
179
180         /* reset FIFOs */
181         val = SSI_FC_TXFFL | SSI_FC_RXFFL;
182         writel(val, priv->base + SSI_FC);
183
184         /* FIFO threthold */
185         val = readl(priv->base + SSI_FC);
186         val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK);
187         val |= FIELD_PREP(SSI_FC_TXFTH_MASK, priv->fifo_depth);
188         val |= FIELD_PREP(SSI_FC_RXFTH_MASK, priv->fifo_depth);
189         writel(val, priv->base + SSI_FC);
190
191         /* clear interrupts */
192         writel(SSI_IC_TCIC | SSI_IC_RCIC | SSI_IC_RORIC,
193                priv->base + SSI_IC);
194
195         uniphier_spi_enable(priv, true);
196
197         return 0;
198 }
199
200 static int uniphier_spi_release_bus(struct udevice *dev)
201 {
202         struct udevice *bus = dev->parent;
203         struct uniphier_spi_priv *priv = dev_get_priv(bus);
204
205         uniphier_spi_enable(priv, false);
206
207         return 0;
208 }
209
210 static int uniphier_spi_xfer(struct udevice *dev, unsigned int bitlen,
211                              const void *dout, void *din, unsigned long flags)
212 {
213         struct udevice *bus = dev->parent;
214         struct uniphier_spi_priv *priv = dev_get_priv(bus);
215         const u8 *tx_buf = dout;
216         u8 *rx_buf = din, buf;
217         u32 len = bitlen / 8;
218         u32 tx_len, rx_len;
219         u32 ts, status;
220         int ret = 0;
221
222         if (bitlen % 8) {
223                 dev_err(dev, "Non byte aligned SPI transfer\n");
224                 return -EINVAL;
225         }
226
227         if (flags & SPI_XFER_BEGIN)
228                 spi_cs_activate(dev);
229
230         uniphier_spi_enable(priv, true);
231
232         ts = get_timer(0);
233         tx_len = len;
234         rx_len = len;
235
236         uniphier_spi_regdump(priv);
237
238         while (tx_len || rx_len) {
239                 ret = wait_for_bit_le32(priv->base + SSI_SR, SSI_SR_BUSY, false,
240                                         SSI_REG_TIMEOUT * 1000, false);
241                 if (ret) {
242                         if (ret == -ETIMEDOUT)
243                                 dev_err(dev, "access timeout\n");
244                         break;
245                 }
246
247                 status = readl(priv->base + SSI_SR);
248                 /* write the data into TX */
249                 if (tx_len && (status & SSI_SR_TNF)) {
250                         buf = tx_buf ? *tx_buf++ : 0;
251                         writel(buf, priv->base + SSI_XDR);
252                         tx_len--;
253                 }
254
255                 /* read the data from RX */
256                 if (rx_len && (status & SSI_SR_RNE)) {
257                         buf = readl(priv->base + SSI_XDR);
258                         if (rx_buf)
259                                 *rx_buf++ = buf;
260                         rx_len--;
261                 }
262
263                 if (get_timer(ts) >= SSI_XFER_TIMEOUT) {
264                         dev_err(dev, "transfer timeout\n");
265                         ret = -ETIMEDOUT;
266                         break;
267                 }
268         }
269
270         if (flags & SPI_XFER_END)
271                 spi_cs_deactivate(dev);
272
273         uniphier_spi_enable(priv, false);
274
275         return ret;
276 }
277
278 static int uniphier_spi_set_speed(struct udevice *bus, uint speed)
279 {
280         struct uniphier_spi_platdata *plat = bus->platdata;
281         struct uniphier_spi_priv *priv = dev_get_priv(bus);
282         u32 val, ckdiv;
283
284         if (speed > plat->frequency)
285                 speed = plat->frequency;
286
287         /* baudrate */
288         ckdiv = DIV_ROUND_UP(SSI_CLK, speed);
289         ckdiv = round_up(ckdiv, 2);
290
291         val = readl(priv->base + SSI_CKS);
292         val &= ~SSI_CKS_CKRAT_MASK;
293         val |= ckdiv & SSI_CKS_CKRAT_MASK;
294         writel(val, priv->base + SSI_CKS);
295
296         return 0;
297 }
298
299 static int uniphier_spi_set_mode(struct udevice *bus, uint mode)
300 {
301         struct uniphier_spi_priv *priv = dev_get_priv(bus);
302         u32 val1, val2;
303
304         /*
305          * clock setting
306          * CKPHS    capture timing. 0:rising edge, 1:falling edge
307          * CKINIT   clock initial level. 0:low, 1:high
308          * CKDLY    clock delay. 0:no delay, 1:delay depending on FSTRT
309          *          (FSTRT=0: 1 clock, FSTRT=1: 0.5 clock)
310          *
311          * frame setting
312          * FSPOL    frame signal porarity. 0: low, 1: high
313          * FSTRT    start frame timing
314          *          0: rising edge of clock, 1: falling edge of clock
315          */
316         val1 = readl(priv->base + SSI_CKS);
317         val2 = readl(priv->base + SSI_FPS);
318
319         switch (mode & (SPI_CPOL | SPI_CPHA)) {
320         case SPI_MODE_0:
321                 /* CKPHS=1, CKINIT=0, CKDLY=1, FSTRT=0 */
322                 val1 |= SSI_CKS_CKPHS | SSI_CKS_CKDLY;
323                 val1 &= ~SSI_CKS_CKINIT;
324                 val2 &= ~SSI_FPS_FSTRT;
325                 break;
326         case SPI_MODE_1:
327                 /* CKPHS=0, CKINIT=0, CKDLY=0, FSTRT=1 */
328                 val1 &= ~(SSI_CKS_CKPHS | SSI_CKS_CKINIT | SSI_CKS_CKDLY);
329                 val2 |= SSI_FPS_FSTRT;
330                 break;
331         case SPI_MODE_2:
332                 /* CKPHS=0, CKINIT=1, CKDLY=1, FSTRT=1 */
333                 val1 |= SSI_CKS_CKINIT | SSI_CKS_CKDLY;
334                 val1 &= ~SSI_CKS_CKPHS;
335                 val2 |= SSI_FPS_FSTRT;
336                 break;
337         case SPI_MODE_3:
338                 /* CKPHS=1, CKINIT=1, CKDLY=0, FSTRT=0 */
339                 val1 |= SSI_CKS_CKPHS | SSI_CKS_CKINIT;
340                 val1 &= ~SSI_CKS_CKDLY;
341                 val2 &= ~SSI_FPS_FSTRT;
342                 break;
343         }
344
345         writel(val1, priv->base + SSI_CKS);
346         writel(val2, priv->base + SSI_FPS);
347
348         /* format */
349         val1 = readl(priv->base + SSI_TXWDS);
350         val2 = readl(priv->base + SSI_RXWDS);
351         if (mode & SPI_LSB_FIRST) {
352                 val1 |= FIELD_PREP(SSI_TXWDS_TDTF_MASK, 1);
353                 val2 |= FIELD_PREP(SSI_RXWDS_RDTF_MASK, 1);
354         }
355         writel(val1, priv->base + SSI_TXWDS);
356         writel(val2, priv->base + SSI_RXWDS);
357
358         priv->mode = mode;
359
360         return 0;
361 }
362
363 static int uniphier_spi_ofdata_to_platdata(struct udevice *bus)
364 {
365         struct uniphier_spi_platdata *plat = bus->platdata;
366         const void *blob = gd->fdt_blob;
367         int node = dev_of_offset(bus);
368
369         plat->base = devfdt_get_addr_ptr(bus);
370
371         plat->frequency =
372                 fdtdec_get_int(blob, node, "spi-max-frequency", 12500000);
373         plat->deactivate_delay_us =
374                 fdtdec_get_int(blob, node, "spi-deactivate-delay", 0);
375         plat->activate_delay_us =
376                 fdtdec_get_int(blob, node, "spi-activate-delay", 0);
377         plat->speed_hz = plat->frequency / 2;
378
379         return 0;
380 }
381
382 static int uniphier_spi_probe(struct udevice *bus)
383 {
384         struct uniphier_spi_platdata *plat = dev_get_platdata(bus);
385         struct uniphier_spi_priv *priv = dev_get_priv(bus);
386
387         priv->base = plat->base;
388         priv->fifo_depth = SSI_FIFO_DEPTH;
389         priv->bits_per_word = 8;
390
391         return 0;
392 }
393
394 static const struct dm_spi_ops uniphier_spi_ops = {
395         .claim_bus      = uniphier_spi_claim_bus,
396         .release_bus    = uniphier_spi_release_bus,
397         .xfer           = uniphier_spi_xfer,
398         .set_speed      = uniphier_spi_set_speed,
399         .set_mode       = uniphier_spi_set_mode,
400 };
401
402 static const struct udevice_id uniphier_spi_ids[] = {
403         { .compatible = "socionext,uniphier-scssi" },
404         { /* Sentinel */ }
405 };
406
407 U_BOOT_DRIVER(uniphier_spi) = {
408         .name   = "uniphier_spi",
409         .id     = UCLASS_SPI,
410         .of_match = uniphier_spi_ids,
411         .ops    = &uniphier_spi_ops,
412         .ofdata_to_platdata = uniphier_spi_ofdata_to_platdata,
413         .platdata_auto_alloc_size = sizeof(struct uniphier_spi_platdata),
414         .priv_auto_alloc_size = sizeof(struct uniphier_spi_priv),
415         .probe  = uniphier_spi_probe,
416 };