2 * Copyright (C) 2014-2016 Rafał Miłecki <rafal@milecki.pl>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/delay.h>
15 #include <linux/bcma/bcma.h>
16 #include <linux/spi/spi.h>
18 #include "spi-bcm53xx.h"
20 #define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */
21 #define BCM53XXSPI_FLASH_WINDOW SZ_32M
23 /* The longest observed required wait was 19 ms */
24 #define BCM53XXSPI_SPE_TIMEOUT_MS 80
27 struct bcma_device
*core
;
28 struct spi_master
*master
;
29 void __iomem
*mmio_base
;
32 bool bspi
; /* Boot SPI mode with memory mapping */
35 static inline u32
bcm53xxspi_read(struct bcm53xxspi
*b53spi
, u16 offset
)
37 return bcma_read32(b53spi
->core
, offset
);
40 static inline void bcm53xxspi_write(struct bcm53xxspi
*b53spi
, u16 offset
,
43 bcma_write32(b53spi
->core
, offset
, value
);
46 static void bcm53xxspi_disable_bspi(struct bcm53xxspi
*b53spi
)
48 struct device
*dev
= &b53spi
->core
->dev
;
49 unsigned long deadline
;
55 tmp
= bcm53xxspi_read(b53spi
, B53SPI_BSPI_MAST_N_BOOT_CTRL
);
59 deadline
= jiffies
+ usecs_to_jiffies(200);
61 tmp
= bcm53xxspi_read(b53spi
, B53SPI_BSPI_BUSY_STATUS
);
63 bcm53xxspi_write(b53spi
, B53SPI_BSPI_MAST_N_BOOT_CTRL
,
70 } while (!time_after_eq(jiffies
, deadline
));
72 dev_warn(dev
, "Timeout disabling BSPI\n");
75 static void bcm53xxspi_enable_bspi(struct bcm53xxspi
*b53spi
)
82 tmp
= bcm53xxspi_read(b53spi
, B53SPI_BSPI_MAST_N_BOOT_CTRL
);
86 bcm53xxspi_write(b53spi
, B53SPI_BSPI_MAST_N_BOOT_CTRL
, 0x0);
90 static inline unsigned int bcm53xxspi_calc_timeout(size_t len
)
92 /* Do some magic calculation based on length and buad. Add 10% and 1. */
93 return (len
* 9000 / BCM53XXSPI_MAX_SPI_BAUD
* 110 / 100) + 1;
96 static int bcm53xxspi_wait(struct bcm53xxspi
*b53spi
, unsigned int timeout_ms
)
98 unsigned long deadline
;
101 /* SPE bit has to be 0 before we read MSPI STATUS */
102 deadline
= jiffies
+ msecs_to_jiffies(BCM53XXSPI_SPE_TIMEOUT_MS
);
104 tmp
= bcm53xxspi_read(b53spi
, B53SPI_MSPI_SPCR2
);
105 if (!(tmp
& B53SPI_MSPI_SPCR2_SPE
))
108 } while (!time_after_eq(jiffies
, deadline
));
110 if (tmp
& B53SPI_MSPI_SPCR2_SPE
)
114 deadline
= jiffies
+ msecs_to_jiffies(timeout_ms
);
116 tmp
= bcm53xxspi_read(b53spi
, B53SPI_MSPI_MSPI_STATUS
);
117 if (tmp
& B53SPI_MSPI_MSPI_STATUS_SPIF
) {
118 bcm53xxspi_write(b53spi
, B53SPI_MSPI_MSPI_STATUS
, 0);
124 } while (!time_after_eq(jiffies
, deadline
));
127 bcm53xxspi_write(b53spi
, B53SPI_MSPI_MSPI_STATUS
, 0);
129 pr_err("Timeout waiting for SPI to be ready!\n");
134 static void bcm53xxspi_buf_write(struct bcm53xxspi
*b53spi
, u8
*w_buf
,
135 size_t len
, bool cont
)
140 for (i
= 0; i
< len
; i
++) {
141 /* Transmit Register File MSB */
142 bcm53xxspi_write(b53spi
, B53SPI_MSPI_TXRAM
+ 4 * (i
* 2),
143 (unsigned int)w_buf
[i
]);
146 for (i
= 0; i
< len
; i
++) {
147 tmp
= B53SPI_CDRAM_CONT
| B53SPI_CDRAM_PCS_DISABLE_ALL
|
148 B53SPI_CDRAM_PCS_DSCK
;
149 if (!cont
&& i
== len
- 1)
150 tmp
&= ~B53SPI_CDRAM_CONT
;
152 /* Command Register File */
153 bcm53xxspi_write(b53spi
, B53SPI_MSPI_CDRAM
+ 4 * i
, tmp
);
156 /* Set queue pointers */
157 bcm53xxspi_write(b53spi
, B53SPI_MSPI_NEWQP
, 0);
158 bcm53xxspi_write(b53spi
, B53SPI_MSPI_ENDQP
, len
- 1);
161 bcm53xxspi_write(b53spi
, B53SPI_MSPI_WRITE_LOCK
, 1);
163 /* Start SPI transfer */
164 tmp
= bcm53xxspi_read(b53spi
, B53SPI_MSPI_SPCR2
);
165 tmp
|= B53SPI_MSPI_SPCR2_SPE
;
167 tmp
|= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD
;
168 bcm53xxspi_write(b53spi
, B53SPI_MSPI_SPCR2
, tmp
);
170 /* Wait for SPI to finish */
171 bcm53xxspi_wait(b53spi
, bcm53xxspi_calc_timeout(len
));
174 bcm53xxspi_write(b53spi
, B53SPI_MSPI_WRITE_LOCK
, 0);
176 b53spi
->read_offset
= len
;
179 static void bcm53xxspi_buf_read(struct bcm53xxspi
*b53spi
, u8
*r_buf
,
180 size_t len
, bool cont
)
185 for (i
= 0; i
< b53spi
->read_offset
+ len
; i
++) {
186 tmp
= B53SPI_CDRAM_CONT
| B53SPI_CDRAM_PCS_DISABLE_ALL
|
187 B53SPI_CDRAM_PCS_DSCK
;
188 if (!cont
&& i
== b53spi
->read_offset
+ len
- 1)
189 tmp
&= ~B53SPI_CDRAM_CONT
;
191 /* Command Register File */
192 bcm53xxspi_write(b53spi
, B53SPI_MSPI_CDRAM
+ 4 * i
, tmp
);
195 /* Set queue pointers */
196 bcm53xxspi_write(b53spi
, B53SPI_MSPI_NEWQP
, 0);
197 bcm53xxspi_write(b53spi
, B53SPI_MSPI_ENDQP
,
198 b53spi
->read_offset
+ len
- 1);
201 bcm53xxspi_write(b53spi
, B53SPI_MSPI_WRITE_LOCK
, 1);
203 /* Start SPI transfer */
204 tmp
= bcm53xxspi_read(b53spi
, B53SPI_MSPI_SPCR2
);
205 tmp
|= B53SPI_MSPI_SPCR2_SPE
;
207 tmp
|= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD
;
208 bcm53xxspi_write(b53spi
, B53SPI_MSPI_SPCR2
, tmp
);
210 /* Wait for SPI to finish */
211 bcm53xxspi_wait(b53spi
, bcm53xxspi_calc_timeout(len
));
214 bcm53xxspi_write(b53spi
, B53SPI_MSPI_WRITE_LOCK
, 0);
216 for (i
= 0; i
< len
; ++i
) {
217 int offset
= b53spi
->read_offset
+ i
;
219 /* Data stored in the transmit register file LSB */
220 r_buf
[i
] = (u8
)bcm53xxspi_read(b53spi
, B53SPI_MSPI_RXRAM
+ 4 * (1 + offset
* 2));
223 b53spi
->read_offset
= 0;
226 static int bcm53xxspi_transfer_one(struct spi_master
*master
,
227 struct spi_device
*spi
,
228 struct spi_transfer
*t
)
230 struct bcm53xxspi
*b53spi
= spi_master_get_devdata(master
);
234 bcm53xxspi_disable_bspi(b53spi
);
237 buf
= (u8
*)t
->tx_buf
;
240 size_t to_write
= min_t(size_t, 16, left
);
241 bool cont
= left
- to_write
> 0;
243 bcm53xxspi_buf_write(b53spi
, buf
, to_write
, cont
);
250 buf
= (u8
*)t
->rx_buf
;
253 size_t to_read
= min_t(size_t, 16 - b53spi
->read_offset
,
255 bool cont
= left
- to_read
> 0;
257 bcm53xxspi_buf_read(b53spi
, buf
, to_read
, cont
);
266 static int bcm53xxspi_flash_read(struct spi_device
*spi
,
267 struct spi_flash_read_message
*msg
)
269 struct bcm53xxspi
*b53spi
= spi_master_get_devdata(spi
->master
);
272 if (msg
->from
+ msg
->len
> BCM53XXSPI_FLASH_WINDOW
)
275 bcm53xxspi_enable_bspi(b53spi
);
276 memcpy_fromio(msg
->buf
, b53spi
->mmio_base
+ msg
->from
, msg
->len
);
277 msg
->retlen
= msg
->len
;
282 /**************************************************
284 **************************************************/
286 static const struct bcma_device_id bcm53xxspi_bcma_tbl
[] = {
287 BCMA_CORE(BCMA_MANUF_BCM
, BCMA_CORE_NS_QSPI
, BCMA_ANY_REV
, BCMA_ANY_CLASS
),
290 MODULE_DEVICE_TABLE(bcma
, bcm53xxspi_bcma_tbl
);
292 static int bcm53xxspi_bcma_probe(struct bcma_device
*core
)
294 struct device
*dev
= &core
->dev
;
295 struct bcm53xxspi
*b53spi
;
296 struct spi_master
*master
;
299 if (core
->bus
->drv_cc
.core
->id
.rev
!= 42) {
300 pr_err("SPI on SoC with unsupported ChipCommon rev\n");
304 master
= spi_alloc_master(dev
, sizeof(*b53spi
));
308 b53spi
= spi_master_get_devdata(master
);
309 b53spi
->master
= master
;
313 b53spi
->mmio_base
= devm_ioremap(dev
, core
->addr_s
[0],
314 BCM53XXSPI_FLASH_WINDOW
);
316 bcm53xxspi_disable_bspi(b53spi
);
318 master
->dev
.of_node
= dev
->of_node
;
319 master
->transfer_one
= bcm53xxspi_transfer_one
;
320 if (b53spi
->mmio_base
)
321 master
->spi_flash_read
= bcm53xxspi_flash_read
;
323 bcma_set_drvdata(core
, b53spi
);
325 err
= devm_spi_register_master(dev
, master
);
327 spi_master_put(master
);
328 bcma_set_drvdata(core
, NULL
);
335 static struct bcma_driver bcm53xxspi_bcma_driver
= {
336 .name
= KBUILD_MODNAME
,
337 .id_table
= bcm53xxspi_bcma_tbl
,
338 .probe
= bcm53xxspi_bcma_probe
,
341 /**************************************************
343 **************************************************/
345 static int __init
bcm53xxspi_module_init(void)
349 err
= bcma_driver_register(&bcm53xxspi_bcma_driver
);
351 pr_err("Failed to register bcma driver: %d\n", err
);
356 static void __exit
bcm53xxspi_module_exit(void)
358 bcma_driver_unregister(&bcm53xxspi_bcma_driver
);
361 module_init(bcm53xxspi_module_init
);
362 module_exit(bcm53xxspi_module_exit
);
364 MODULE_DESCRIPTION("Broadcom BCM53xx SPI Controller driver");
365 MODULE_AUTHOR("Rafał Miłecki <zajec5@gmail.com>");
366 MODULE_LICENSE("GPL v2");