1 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
10 #include "spi-bcm53xx.h"
12 #define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */
14 /* The longest observed required wait was 19 ms */
15 #define BCM53XXSPI_SPE_TIMEOUT_MS 80
18 struct bcma_device
*core
;
19 struct spi_master
*master
;
24 static inline u32
bcm53xxspi_read(struct bcm53xxspi
*b53spi
, u16 offset
)
26 return bcma_read32(b53spi
->core
, offset
);
29 static inline void bcm53xxspi_write(struct bcm53xxspi
*b53spi
, u16 offset
,
32 bcma_write32(b53spi
->core
, offset
, value
);
35 static inline unsigned int bcm53xxspi_calc_timeout(size_t len
)
37 /* Do some magic calculation based on length and buad. Add 10% and 1. */
38 return (len
* 9000 / BCM53XXSPI_MAX_SPI_BAUD
* 110 / 100) + 1;
41 static int bcm53xxspi_wait(struct bcm53xxspi
*b53spi
, unsigned int timeout_ms
)
43 unsigned long deadline
;
46 /* SPE bit has to be 0 before we read MSPI STATUS */
47 deadline
= jiffies
+ msecs_to_jiffies(BCM53XXSPI_SPE_TIMEOUT_MS
);
49 tmp
= bcm53xxspi_read(b53spi
, B53SPI_MSPI_SPCR2
);
50 if (!(tmp
& B53SPI_MSPI_SPCR2_SPE
))
53 } while (!time_after_eq(jiffies
, deadline
));
55 if (tmp
& B53SPI_MSPI_SPCR2_SPE
)
59 deadline
= jiffies
+ msecs_to_jiffies(timeout_ms
);
61 tmp
= bcm53xxspi_read(b53spi
, B53SPI_MSPI_MSPI_STATUS
);
62 if (tmp
& B53SPI_MSPI_MSPI_STATUS_SPIF
) {
63 bcm53xxspi_write(b53spi
, B53SPI_MSPI_MSPI_STATUS
, 0);
69 } while (!time_after_eq(jiffies
, deadline
));
72 bcm53xxspi_write(b53spi
, B53SPI_MSPI_MSPI_STATUS
, 0);
74 pr_err("Timeout waiting for SPI to be ready!\n");
79 static void bcm53xxspi_buf_write(struct bcm53xxspi
*b53spi
, u8
*w_buf
,
80 size_t len
, bool cont
)
85 for (i
= 0; i
< len
; i
++) {
86 /* Transmit Register File MSB */
87 bcm53xxspi_write(b53spi
, B53SPI_MSPI_TXRAM
+ 4 * (i
* 2),
88 (unsigned int)w_buf
[i
]);
91 for (i
= 0; i
< len
; i
++) {
92 tmp
= B53SPI_CDRAM_CONT
| B53SPI_CDRAM_PCS_DISABLE_ALL
|
93 B53SPI_CDRAM_PCS_DSCK
;
94 if (!cont
&& i
== len
- 1)
95 tmp
&= ~B53SPI_CDRAM_CONT
;
97 /* Command Register File */
98 bcm53xxspi_write(b53spi
, B53SPI_MSPI_CDRAM
+ 4 * i
, tmp
);
101 /* Set queue pointers */
102 bcm53xxspi_write(b53spi
, B53SPI_MSPI_NEWQP
, 0);
103 bcm53xxspi_write(b53spi
, B53SPI_MSPI_ENDQP
, len
- 1);
106 bcm53xxspi_write(b53spi
, B53SPI_MSPI_WRITE_LOCK
, 1);
108 /* Start SPI transfer */
109 tmp
= bcm53xxspi_read(b53spi
, B53SPI_MSPI_SPCR2
);
110 tmp
|= B53SPI_MSPI_SPCR2_SPE
;
112 tmp
|= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD
;
113 bcm53xxspi_write(b53spi
, B53SPI_MSPI_SPCR2
, tmp
);
115 /* Wait for SPI to finish */
116 bcm53xxspi_wait(b53spi
, bcm53xxspi_calc_timeout(len
));
119 bcm53xxspi_write(b53spi
, B53SPI_MSPI_WRITE_LOCK
, 0);
121 b53spi
->read_offset
= len
;
124 static void bcm53xxspi_buf_read(struct bcm53xxspi
*b53spi
, u8
*r_buf
,
125 size_t len
, bool cont
)
130 for (i
= 0; i
< b53spi
->read_offset
+ len
; i
++) {
131 tmp
= B53SPI_CDRAM_CONT
| B53SPI_CDRAM_PCS_DISABLE_ALL
|
132 B53SPI_CDRAM_PCS_DSCK
;
133 if (!cont
&& i
== b53spi
->read_offset
+ len
- 1)
134 tmp
&= ~B53SPI_CDRAM_CONT
;
136 /* Command Register File */
137 bcm53xxspi_write(b53spi
, B53SPI_MSPI_CDRAM
+ 4 * i
, tmp
);
140 /* Set queue pointers */
141 bcm53xxspi_write(b53spi
, B53SPI_MSPI_NEWQP
, 0);
142 bcm53xxspi_write(b53spi
, B53SPI_MSPI_ENDQP
,
143 b53spi
->read_offset
+ len
- 1);
146 bcm53xxspi_write(b53spi
, B53SPI_MSPI_WRITE_LOCK
, 1);
148 /* Start SPI transfer */
149 tmp
= bcm53xxspi_read(b53spi
, B53SPI_MSPI_SPCR2
);
150 tmp
|= B53SPI_MSPI_SPCR2_SPE
;
152 tmp
|= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD
;
153 bcm53xxspi_write(b53spi
, B53SPI_MSPI_SPCR2
, tmp
);
155 /* Wait for SPI to finish */
156 bcm53xxspi_wait(b53spi
, bcm53xxspi_calc_timeout(len
));
159 bcm53xxspi_write(b53spi
, B53SPI_MSPI_WRITE_LOCK
, 0);
161 for (i
= 0; i
< len
; ++i
) {
162 int offset
= b53spi
->read_offset
+ i
;
164 /* Data stored in the transmit register file LSB */
165 r_buf
[i
] = (u8
)bcm53xxspi_read(b53spi
, B53SPI_MSPI_RXRAM
+ 4 * (1 + offset
* 2));
168 b53spi
->read_offset
= 0;
171 static int bcm53xxspi_transfer_one(struct spi_master
*master
,
172 struct spi_device
*spi
,
173 struct spi_transfer
*t
)
175 struct bcm53xxspi
*b53spi
= spi_master_get_devdata(master
);
180 buf
= (u8
*)t
->tx_buf
;
183 size_t to_write
= min_t(size_t, 16, left
);
184 bool cont
= left
- to_write
> 0;
186 bcm53xxspi_buf_write(b53spi
, buf
, to_write
, cont
);
193 buf
= (u8
*)t
->rx_buf
;
196 size_t to_read
= min_t(size_t, 16 - b53spi
->read_offset
,
198 bool cont
= left
- to_read
> 0;
200 bcm53xxspi_buf_read(b53spi
, buf
, to_read
, cont
);
209 /**************************************************
211 **************************************************/
213 static struct spi_board_info bcm53xx_info
= {
214 .modalias
= "bcm53xxspiflash",
217 static const struct bcma_device_id bcm53xxspi_bcma_tbl
[] = {
218 BCMA_CORE(BCMA_MANUF_BCM
, BCMA_CORE_NS_QSPI
, BCMA_ANY_REV
, BCMA_ANY_CLASS
),
221 MODULE_DEVICE_TABLE(bcma
, bcm53xxspi_bcma_tbl
);
223 static int bcm53xxspi_bcma_probe(struct bcma_device
*core
)
225 struct bcm53xxspi
*b53spi
;
226 struct spi_master
*master
;
229 if (core
->bus
->drv_cc
.core
->id
.rev
!= 42) {
230 pr_err("SPI on SoC with unsupported ChipCommon rev\n");
234 master
= spi_alloc_master(&core
->dev
, sizeof(*b53spi
));
238 b53spi
= spi_master_get_devdata(master
);
239 b53spi
->master
= master
;
242 master
->transfer_one
= bcm53xxspi_transfer_one
;
244 bcma_set_drvdata(core
, b53spi
);
246 err
= devm_spi_register_master(&core
->dev
, master
);
248 spi_master_put(master
);
249 bcma_set_drvdata(core
, NULL
);
253 /* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */
254 spi_new_device(master
, &bcm53xx_info
);
260 static void bcm53xxspi_bcma_remove(struct bcma_device
*core
)
262 struct bcm53xxspi
*b53spi
= bcma_get_drvdata(core
);
264 spi_unregister_master(b53spi
->master
);
267 static struct bcma_driver bcm53xxspi_bcma_driver
= {
268 .name
= KBUILD_MODNAME
,
269 .id_table
= bcm53xxspi_bcma_tbl
,
270 .probe
= bcm53xxspi_bcma_probe
,
271 .remove
= bcm53xxspi_bcma_remove
,
274 /**************************************************
276 **************************************************/
278 static int __init
bcm53xxspi_module_init(void)
282 err
= bcma_driver_register(&bcm53xxspi_bcma_driver
);
284 pr_err("Failed to register bcma driver: %d\n", err
);
289 static void __exit
bcm53xxspi_module_exit(void)
291 bcma_driver_unregister(&bcm53xxspi_bcma_driver
);
294 module_init(bcm53xxspi_module_init
);
295 module_exit(bcm53xxspi_module_exit
);
297 MODULE_DESCRIPTION("Broadcom BCM53xx SPI Controller driver");
298 MODULE_AUTHOR("Rafał Miłecki <zajec5@gmail.com>");
299 MODULE_LICENSE("GPL");