x86/smpboot: Init apic mapping before usage
[cascardo/linux.git] / drivers / spi / spi-bcm53xx.c
1 #define pr_fmt(fmt)             KBUILD_MODNAME ": " fmt
2
3 #include <linux/kernel.h>
4 #include <linux/module.h>
5 #include <linux/slab.h>
6 #include <linux/delay.h>
7 #include <linux/bcma/bcma.h>
8 #include <linux/spi/spi.h>
9
10 #include "spi-bcm53xx.h"
11
12 #define BCM53XXSPI_MAX_SPI_BAUD 13500000        /* 216 MHz? */
13 #define BCM53XXSPI_FLASH_WINDOW SZ_32M
14
15 /* The longest observed required wait was 19 ms */
16 #define BCM53XXSPI_SPE_TIMEOUT_MS       80
17
18 struct bcm53xxspi {
19         struct bcma_device *core;
20         struct spi_master *master;
21         void __iomem *mmio_base;
22
23         size_t read_offset;
24         bool bspi;                              /* Boot SPI mode with memory mapping */
25 };
26
27 static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset)
28 {
29         return bcma_read32(b53spi->core, offset);
30 }
31
32 static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset,
33                                     u32 value)
34 {
35         bcma_write32(b53spi->core, offset, value);
36 }
37
38 static void bcm53xxspi_disable_bspi(struct bcm53xxspi *b53spi)
39 {
40         struct device *dev = &b53spi->core->dev;
41         unsigned long deadline;
42         u32 tmp;
43
44         if (!b53spi->bspi)
45                 return;
46
47         tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL);
48         if (tmp & 0x1)
49                 return;
50
51         deadline = jiffies + usecs_to_jiffies(200);
52         do {
53                 tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_BUSY_STATUS);
54                 if (!(tmp & 0x1)) {
55                         bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL,
56                                          0x1);
57                         ndelay(200);
58                         b53spi->bspi = false;
59                         return;
60                 }
61                 udelay(1);
62         } while (!time_after_eq(jiffies, deadline));
63
64         dev_warn(dev, "Timeout disabling BSPI\n");
65 }
66
67 static void bcm53xxspi_enable_bspi(struct bcm53xxspi *b53spi)
68 {
69         u32 tmp;
70
71         if (b53spi->bspi)
72                 return;
73
74         tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL);
75         if (!(tmp & 0x1))
76                 return;
77
78         bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, 0x0);
79         b53spi->bspi = true;
80 }
81
82 static inline unsigned int bcm53xxspi_calc_timeout(size_t len)
83 {
84         /* Do some magic calculation based on length and buad. Add 10% and 1. */
85         return (len * 9000 / BCM53XXSPI_MAX_SPI_BAUD * 110 / 100) + 1;
86 }
87
88 static int bcm53xxspi_wait(struct bcm53xxspi *b53spi, unsigned int timeout_ms)
89 {
90         unsigned long deadline;
91         u32 tmp;
92
93         /* SPE bit has to be 0 before we read MSPI STATUS */
94         deadline = jiffies + msecs_to_jiffies(BCM53XXSPI_SPE_TIMEOUT_MS);
95         do {
96                 tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2);
97                 if (!(tmp & B53SPI_MSPI_SPCR2_SPE))
98                         break;
99                 udelay(5);
100         } while (!time_after_eq(jiffies, deadline));
101
102         if (tmp & B53SPI_MSPI_SPCR2_SPE)
103                 goto spi_timeout;
104
105         /* Check status */
106         deadline = jiffies + msecs_to_jiffies(timeout_ms);
107         do {
108                 tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_MSPI_STATUS);
109                 if (tmp & B53SPI_MSPI_MSPI_STATUS_SPIF) {
110                         bcm53xxspi_write(b53spi, B53SPI_MSPI_MSPI_STATUS, 0);
111                         return 0;
112                 }
113
114                 cpu_relax();
115                 udelay(100);
116         } while (!time_after_eq(jiffies, deadline));
117
118 spi_timeout:
119         bcm53xxspi_write(b53spi, B53SPI_MSPI_MSPI_STATUS, 0);
120
121         pr_err("Timeout waiting for SPI to be ready!\n");
122
123         return -EBUSY;
124 }
125
126 static void bcm53xxspi_buf_write(struct bcm53xxspi *b53spi, u8 *w_buf,
127                                  size_t len, bool cont)
128 {
129         u32 tmp;
130         int i;
131
132         for (i = 0; i < len; i++) {
133                 /* Transmit Register File MSB */
134                 bcm53xxspi_write(b53spi, B53SPI_MSPI_TXRAM + 4 * (i * 2),
135                                  (unsigned int)w_buf[i]);
136         }
137
138         for (i = 0; i < len; i++) {
139                 tmp = B53SPI_CDRAM_CONT | B53SPI_CDRAM_PCS_DISABLE_ALL |
140                       B53SPI_CDRAM_PCS_DSCK;
141                 if (!cont && i == len - 1)
142                         tmp &= ~B53SPI_CDRAM_CONT;
143                 tmp &= ~0x1;
144                 /* Command Register File */
145                 bcm53xxspi_write(b53spi, B53SPI_MSPI_CDRAM + 4 * i, tmp);
146         }
147
148         /* Set queue pointers */
149         bcm53xxspi_write(b53spi, B53SPI_MSPI_NEWQP, 0);
150         bcm53xxspi_write(b53spi, B53SPI_MSPI_ENDQP, len - 1);
151
152         if (cont)
153                 bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 1);
154
155         /* Start SPI transfer */
156         tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2);
157         tmp |= B53SPI_MSPI_SPCR2_SPE;
158         if (cont)
159                 tmp |= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD;
160         bcm53xxspi_write(b53spi, B53SPI_MSPI_SPCR2, tmp);
161
162         /* Wait for SPI to finish */
163         bcm53xxspi_wait(b53spi, bcm53xxspi_calc_timeout(len));
164
165         if (!cont)
166                 bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 0);
167
168         b53spi->read_offset = len;
169 }
170
171 static void bcm53xxspi_buf_read(struct bcm53xxspi *b53spi, u8 *r_buf,
172                                 size_t len, bool cont)
173 {
174         u32 tmp;
175         int i;
176
177         for (i = 0; i < b53spi->read_offset + len; i++) {
178                 tmp = B53SPI_CDRAM_CONT | B53SPI_CDRAM_PCS_DISABLE_ALL |
179                       B53SPI_CDRAM_PCS_DSCK;
180                 if (!cont && i == b53spi->read_offset + len - 1)
181                         tmp &= ~B53SPI_CDRAM_CONT;
182                 tmp &= ~0x1;
183                 /* Command Register File */
184                 bcm53xxspi_write(b53spi, B53SPI_MSPI_CDRAM + 4 * i, tmp);
185         }
186
187         /* Set queue pointers */
188         bcm53xxspi_write(b53spi, B53SPI_MSPI_NEWQP, 0);
189         bcm53xxspi_write(b53spi, B53SPI_MSPI_ENDQP,
190                          b53spi->read_offset + len - 1);
191
192         if (cont)
193                 bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 1);
194
195         /* Start SPI transfer */
196         tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2);
197         tmp |= B53SPI_MSPI_SPCR2_SPE;
198         if (cont)
199                 tmp |= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD;
200         bcm53xxspi_write(b53spi, B53SPI_MSPI_SPCR2, tmp);
201
202         /* Wait for SPI to finish */
203         bcm53xxspi_wait(b53spi, bcm53xxspi_calc_timeout(len));
204
205         if (!cont)
206                 bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 0);
207
208         for (i = 0; i < len; ++i) {
209                 int offset = b53spi->read_offset + i;
210
211                 /* Data stored in the transmit register file LSB */
212                 r_buf[i] = (u8)bcm53xxspi_read(b53spi, B53SPI_MSPI_RXRAM + 4 * (1 + offset * 2));
213         }
214
215         b53spi->read_offset = 0;
216 }
217
218 static int bcm53xxspi_transfer_one(struct spi_master *master,
219                                    struct spi_device *spi,
220                                    struct spi_transfer *t)
221 {
222         struct bcm53xxspi *b53spi = spi_master_get_devdata(master);
223         u8 *buf;
224         size_t left;
225
226         bcm53xxspi_disable_bspi(b53spi);
227
228         if (t->tx_buf) {
229                 buf = (u8 *)t->tx_buf;
230                 left = t->len;
231                 while (left) {
232                         size_t to_write = min_t(size_t, 16, left);
233                         bool cont = left - to_write > 0;
234
235                         bcm53xxspi_buf_write(b53spi, buf, to_write, cont);
236                         left -= to_write;
237                         buf += to_write;
238                 }
239         }
240
241         if (t->rx_buf) {
242                 buf = (u8 *)t->rx_buf;
243                 left = t->len;
244                 while (left) {
245                         size_t to_read = min_t(size_t, 16 - b53spi->read_offset,
246                                                left);
247                         bool cont = left - to_read > 0;
248
249                         bcm53xxspi_buf_read(b53spi, buf, to_read, cont);
250                         left -= to_read;
251                         buf += to_read;
252                 }
253         }
254
255         return 0;
256 }
257
258 static int bcm53xxspi_flash_read(struct spi_device *spi,
259                                  struct spi_flash_read_message *msg)
260 {
261         struct bcm53xxspi *b53spi = spi_master_get_devdata(spi->master);
262         int ret = 0;
263
264         if (msg->from + msg->len > BCM53XXSPI_FLASH_WINDOW)
265                 return -EINVAL;
266
267         bcm53xxspi_enable_bspi(b53spi);
268         memcpy_fromio(msg->buf, b53spi->mmio_base + msg->from, msg->len);
269         msg->retlen = msg->len;
270
271         return ret;
272 }
273
274 /**************************************************
275  * BCMA
276  **************************************************/
277
278 static struct spi_board_info bcm53xx_info = {
279         .modalias       = "bcm53xxspiflash",
280 };
281
282 static const struct bcma_device_id bcm53xxspi_bcma_tbl[] = {
283         BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_QSPI, BCMA_ANY_REV, BCMA_ANY_CLASS),
284         {},
285 };
286 MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl);
287
288 static int bcm53xxspi_bcma_probe(struct bcma_device *core)
289 {
290         struct device *dev = &core->dev;
291         struct bcm53xxspi *b53spi;
292         struct spi_master *master;
293         int err;
294
295         if (core->bus->drv_cc.core->id.rev != 42) {
296                 pr_err("SPI on SoC with unsupported ChipCommon rev\n");
297                 return -ENOTSUPP;
298         }
299
300         master = spi_alloc_master(dev, sizeof(*b53spi));
301         if (!master)
302                 return -ENOMEM;
303
304         b53spi = spi_master_get_devdata(master);
305         b53spi->master = master;
306         b53spi->core = core;
307
308         if (core->addr_s[0])
309                 b53spi->mmio_base = devm_ioremap(dev, core->addr_s[0],
310                                                  BCM53XXSPI_FLASH_WINDOW);
311         b53spi->bspi = true;
312         bcm53xxspi_disable_bspi(b53spi);
313
314         master->transfer_one = bcm53xxspi_transfer_one;
315         if (b53spi->mmio_base)
316                 master->spi_flash_read = bcm53xxspi_flash_read;
317
318         bcma_set_drvdata(core, b53spi);
319
320         err = devm_spi_register_master(dev, master);
321         if (err) {
322                 spi_master_put(master);
323                 bcma_set_drvdata(core, NULL);
324                 return err;
325         }
326
327         /* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */
328         spi_new_device(master, &bcm53xx_info);
329
330         return 0;
331 }
332
333 static struct bcma_driver bcm53xxspi_bcma_driver = {
334         .name           = KBUILD_MODNAME,
335         .id_table       = bcm53xxspi_bcma_tbl,
336         .probe          = bcm53xxspi_bcma_probe,
337 };
338
339 /**************************************************
340  * Init & exit
341  **************************************************/
342
343 static int __init bcm53xxspi_module_init(void)
344 {
345         int err = 0;
346
347         err = bcma_driver_register(&bcm53xxspi_bcma_driver);
348         if (err)
349                 pr_err("Failed to register bcma driver: %d\n", err);
350
351         return err;
352 }
353
354 static void __exit bcm53xxspi_module_exit(void)
355 {
356         bcma_driver_unregister(&bcm53xxspi_bcma_driver);
357 }
358
359 module_init(bcm53xxspi_module_init);
360 module_exit(bcm53xxspi_module_exit);
361
362 MODULE_DESCRIPTION("Broadcom BCM53xx SPI Controller driver");
363 MODULE_AUTHOR("Rafał Miłecki <zajec5@gmail.com>");
364 MODULE_LICENSE("GPL");