10
10
#include "spi-bcm53xx.h"
11
11
12
12
#define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */
13
+ #define BCM53XXSPI_FLASH_WINDOW SZ_32M
13
14
14
15
/* The longest observed required wait was 19 ms */
15
16
#define BCM53XXSPI_SPE_TIMEOUT_MS 80
16
17
17
18
struct bcm53xxspi {
18
19
struct bcma_device * core ;
19
20
struct spi_master * master ;
21
+ void __iomem * mmio_base ;
20
22
21
23
size_t read_offset ;
24
+ bool bspi ; /* Boot SPI mode with memory mapping */
22
25
};
23
26
24
27
static inline u32 bcm53xxspi_read (struct bcm53xxspi * b53spi , u16 offset )
@@ -32,6 +35,50 @@ static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset,
32
35
bcma_write32 (b53spi -> core , offset , value );
33
36
}
34
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
+
35
82
static inline unsigned int bcm53xxspi_calc_timeout (size_t len )
36
83
{
37
84
/* Do some magic calculation based on length and buad. Add 10% and 1. */
@@ -176,6 +223,8 @@ static int bcm53xxspi_transfer_one(struct spi_master *master,
176
223
u8 * buf ;
177
224
size_t left ;
178
225
226
+ bcm53xxspi_disable_bspi (b53spi );
227
+
179
228
if (t -> tx_buf ) {
180
229
buf = (u8 * )t -> tx_buf ;
181
230
left = t -> len ;
@@ -206,6 +255,22 @@ static int bcm53xxspi_transfer_one(struct spi_master *master,
206
255
return 0 ;
207
256
}
208
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
+
209
274
/**************************************************
210
275
* BCMA
211
276
**************************************************/
@@ -222,6 +287,7 @@ MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl);
222
287
223
288
static int bcm53xxspi_bcma_probe (struct bcma_device * core )
224
289
{
290
+ struct device * dev = & core -> dev ;
225
291
struct bcm53xxspi * b53spi ;
226
292
struct spi_master * master ;
227
293
int err ;
@@ -231,19 +297,27 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core)
231
297
return - ENOTSUPP ;
232
298
}
233
299
234
- master = spi_alloc_master (& core -> dev , sizeof (* b53spi ));
300
+ master = spi_alloc_master (dev , sizeof (* b53spi ));
235
301
if (!master )
236
302
return - ENOMEM ;
237
303
238
304
b53spi = spi_master_get_devdata (master );
239
305
b53spi -> master = master ;
240
306
b53spi -> core = core ;
241
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
+
242
314
master -> transfer_one = bcm53xxspi_transfer_one ;
315
+ if (b53spi -> mmio_base )
316
+ master -> spi_flash_read = bcm53xxspi_flash_read ;
243
317
244
318
bcma_set_drvdata (core , b53spi );
245
319
246
- err = devm_spi_register_master (& core -> dev , master );
320
+ err = devm_spi_register_master (dev , master );
247
321
if (err ) {
248
322
spi_master_put (master );
249
323
bcma_set_drvdata (core , NULL );
0 commit comments