1 --- a/drivers/ssb/Kconfig
2 +++ b/drivers/ssb/Kconfig
3 @@ -139,7 +139,7 @@ config SSB_DRIVER_MIPS
6 bool "SSB serial flash support"
7 - depends on SSB_DRIVER_MIPS && BROKEN
8 + depends on SSB_DRIVER_MIPS
11 # Assumption: We are on embedded, if we compile the MIPS core.
12 --- a/drivers/ssb/driver_chipcommon_sflash.c
13 +++ b/drivers/ssb/driver_chipcommon_sflash.c
16 * Sonics Silicon Backplane
17 * ChipCommon serial flash interface
18 + * Copyright 2011, Jonas Gorski <jonas.gorski@gmail.com>
19 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
20 + * Copyright 2010, Broadcom Corporation
22 * Licensed under the GNU/GPL. See COPYING for details.
25 +#include <linux/platform_device.h>
26 +#include <linux/delay.h>
27 #include <linux/ssb/ssb.h>
28 +#include <linux/ssb/ssb_driver_chipcommon.h>
30 #include "ssb_private.h"
32 -/* Initialize serial flash access */
33 -int ssb_sflash_init(struct ssb_chipcommon *cc)
34 +#define NUM_RETRIES 3
36 +static struct resource ssb_sflash_resource = {
37 + .name = "ssb_sflash",
38 + .start = SSB_FLASH2,
40 + .flags = IORESOURCE_MEM | IORESOURCE_READONLY,
43 +struct platform_device ssb_sflash_dev = {
44 + .name = "bcm47xx-sflash",
45 + .resource = &ssb_sflash_resource,
49 +struct ssb_sflash_tbl_e {
56 +static const struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = {
57 + { "M25P20", 0x11, 0x10000, 4, },
58 + { "M25P40", 0x12, 0x10000, 8, },
60 + { "M25P16", 0x14, 0x10000, 32, },
61 + { "M25P32", 0x14, 0x10000, 64, },
62 + { "M25P64", 0x16, 0x10000, 128, },
63 + { "M25FL128", 0x17, 0x10000, 256, },
67 +static const struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = {
68 + { "SST25WF512", 1, 0x1000, 16, },
69 + { "SST25VF512", 0x48, 0x1000, 16, },
70 + { "SST25WF010", 2, 0x1000, 32, },
71 + { "SST25VF010", 0x49, 0x1000, 32, },
72 + { "SST25WF020", 3, 0x1000, 64, },
73 + { "SST25VF020", 0x43, 0x1000, 64, },
74 + { "SST25WF040", 4, 0x1000, 128, },
75 + { "SST25VF040", 0x44, 0x1000, 128, },
76 + { "SST25VF040B", 0x8d, 0x1000, 128, },
77 + { "SST25WF080", 5, 0x1000, 256, },
78 + { "SST25VF080B", 0x8e, 0x1000, 256, },
79 + { "SST25VF016", 0x41, 0x1000, 512, },
80 + { "SST25VF032", 0x4a, 0x1000, 1024, },
81 + { "SST25VF064", 0x4b, 0x1000, 2048, },
85 +static const struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = {
86 + { "AT45DB011", 0xc, 256, 512, },
87 + { "AT45DB021", 0x14, 256, 1024, },
88 + { "AT45DB041", 0x1c, 256, 2048, },
89 + { "AT45DB081", 0x24, 256, 4096, },
90 + { "AT45DB161", 0x2c, 512, 4096, },
91 + { "AT45DB321", 0x34, 512, 8192, },
92 + { "AT45DB642", 0x3c, 1024, 8192, },
96 +static void ssb_sflash_cmd(struct ssb_chipcommon *chipco, u32 opcode)
99 + chipco_write32(chipco, SSB_CHIPCO_FLASHCTL,
100 + SSB_CHIPCO_FLASHCTL_START | opcode);
101 + for (i = 0; i < 1000; i++) {
102 + if (!(chipco_read32(chipco, SSB_CHIPCO_FLASHCTL) &
103 + SSB_CHIPCO_FLASHCTL_BUSY))
107 + pr_err("SFLASH control command failed (timeout)!\n");
110 +static void ssb_sflash_write_u8(struct ssb_chipcommon *chipco, u32 offset, u8 byte)
112 + chipco_write32(chipco, SSB_CHIPCO_FLASHADDR, offset);
113 + chipco_write32(chipco, SSB_CHIPCO_FLASHDATA, byte);
116 +/* Read len bytes starting at offset into buf. Returns number of bytes read. */
117 +static int ssb_sflash_read(struct bcm47xx_sflash *dev, u32 offset, u32 len, u8 *buf)
121 + struct ssb_chipcommon *chipco = dev->scc;
126 + if ((offset + len) > chipco->sflash.size)
129 + if ((len >= 4) && (offset & 3))
130 + cnt = 4 - (offset & 3);
131 + else if ((len >= 4) && ((u32)buf & 3))
132 + cnt = 4 - ((u32)buf & 3);
136 + from = (u8 *)KSEG0ADDR(SSB_FLASH2 + offset);
141 + for (i = 0; i < cnt; i++) {
150 + *(u32 *)to = readl(from);
159 +/* Poll for command completion. Returns zero when complete. */
160 +static int ssb_sflash_poll(struct bcm47xx_sflash *dev, u32 offset)
162 - pr_err("Serial flash support is not implemented yet!\n");
163 + struct ssb_chipcommon *chipco = dev->scc;
165 + if (offset >= chipco->sflash.size)
168 + switch (chipco->capabilities & SSB_CHIPCO_CAP_FLASHT) {
169 + case SSB_CHIPCO_FLASHT_STSER:
170 + /* Check for ST Write In Progress bit */
171 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_ST_RDSR);
172 + return chipco_read32(chipco, SSB_CHIPCO_FLASHDATA)
173 + & SSB_CHIPCO_FLASHDATA_ST_WIP;
174 + case SSB_CHIPCO_FLASHT_ATSER:
175 + /* Check for Atmel Ready bit */
176 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_AT_STATUS);
177 + return !(chipco_read32(chipco, SSB_CHIPCO_FLASHDATA)
178 + & SSB_CHIPCO_FLASHDATA_AT_READY);
185 +static int sflash_st_write(struct bcm47xx_sflash *dev, u32 offset, u32 len,
189 + struct ssb_chipcommon *chipco = dev->scc;
191 + /* Enable writes */
192 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_ST_WREN);
193 + ssb_sflash_write_u8(chipco, offset, *buf++);
194 + /* Issue a page program with CSA bit set */
195 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_ST_CSA | SSB_CHIPCO_FLASHCTL_ST_PP);
199 + if ((offset & 255) == 0) {
200 + /* Page boundary, poll droping cs and return */
201 + chipco_write32(chipco, SSB_CHIPCO_FLASHCTL, 0);
203 + if (!ssb_sflash_poll(dev, offset)) {
204 + /* Flash rejected command */
209 + /* Write single byte */
210 + ssb_sflash_cmd(chipco,
211 + SSB_CHIPCO_FLASHCTL_ST_CSA |
218 + /* All done, drop cs & poll */
219 + chipco_write32(chipco, SSB_CHIPCO_FLASHCTL, 0);
221 + if (!ssb_sflash_poll(dev, offset)) {
222 + /* Flash rejected command */
228 +static int sflash_at_write(struct bcm47xx_sflash *dev, u32 offset, u32 len,
231 + struct ssb_chipcommon *chipco = dev->scc;
232 + u32 page, byte, mask;
235 + mask = dev->blocksize - 1;
236 + page = (offset & ~mask) << 1;
237 + byte = offset & mask;
238 + /* Read main memory page into buffer 1 */
239 + if (byte || (len < dev->blocksize)) {
241 + chipco_write32(chipco, SSB_CHIPCO_FLASHADDR, page);
242 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_AT_BUF1_LOAD);
243 + /* 250 us for AT45DB321B */
244 + while (i > 0 && ssb_sflash_poll(dev, offset)) {
248 + BUG_ON(!ssb_sflash_poll(dev, offset));
250 + /* Write into buffer 1 */
251 + for (ret = 0; (ret < (int)len) && (byte < dev->blocksize); ret++) {
252 + ssb_sflash_write_u8(chipco, byte++, *buf++);
253 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_AT_BUF1_WRITE);
255 + /* Write buffer 1 into main memory page */
256 + chipco_write32(chipco, SSB_CHIPCO_FLASHADDR, page);
257 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_AT_BUF1_PROGRAM);
262 +/* Write len bytes starting at offset into buf. Returns number of bytes
263 + * written. Caller should poll for completion.
265 +static int ssb_sflash_write(struct bcm47xx_sflash *dev, u32 offset, u32 len,
268 + int ret = 0, tries = NUM_RETRIES;
269 + struct ssb_chipcommon *chipco = dev->scc;
274 + if ((offset + len) > chipco->sflash.size)
277 + switch (chipco->capabilities & SSB_CHIPCO_CAP_FLASHT) {
278 + case SSB_CHIPCO_FLASHT_STSER:
280 + ret = sflash_st_write(dev, offset, len, buf);
282 + } while (ret == -EAGAIN && tries > 0);
284 + if (ret == -EAGAIN && tries == 0) {
285 + pr_info("ST Flash rejected write\n");
289 + case SSB_CHIPCO_FLASHT_ATSER:
290 + ret = sflash_at_write(dev, offset, len, buf);
297 +/* Erase a region. Returns number of bytes scheduled for erasure.
298 + * Caller should poll for completion.
300 +static int ssb_sflash_erase(struct bcm47xx_sflash *dev, u32 offset)
302 + struct ssb_chipcommon *chipco = dev->scc;
304 + if (offset >= chipco->sflash.size)
307 + switch (chipco->capabilities & SSB_CHIPCO_CAP_FLASHT) {
308 + case SSB_CHIPCO_FLASHT_STSER:
309 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_ST_WREN);
310 + chipco_write32(chipco, SSB_CHIPCO_FLASHADDR, offset);
311 + /* Newer flashes have "sub-sectors" which can be erased independently
312 + * with a new command: ST_SSE. The ST_SE command erases 64KB just as
315 + if (dev->blocksize < (64 * 1024))
316 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_ST_SSE);
318 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_ST_SE);
319 + return dev->blocksize;
320 + case SSB_CHIPCO_FLASHT_ATSER:
321 + chipco_write32(chipco, SSB_CHIPCO_FLASHADDR, offset << 1);
322 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_AT_PAGE_ERASE);
323 + return dev->blocksize;
329 +/* Initialize serial flash achipcoess */
330 +int ssb_sflash_init(struct ssb_chipcommon *chipco)
332 + struct bcm47xx_sflash *sflash = &chipco->sflash;
333 + const struct ssb_sflash_tbl_e *e;
336 + switch (chipco->capabilities & SSB_CHIPCO_CAP_FLASHT) {
337 + case SSB_CHIPCO_FLASHT_STSER:
338 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_ST_DP);
340 + chipco_write32(chipco, SSB_CHIPCO_FLASHADDR, 0);
341 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_ST_RES);
342 + id = chipco_read32(chipco, SSB_CHIPCO_FLASHDATA);
344 + chipco_write32(chipco, SSB_CHIPCO_FLASHADDR, 1);
345 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_ST_RES);
346 + id2 = chipco_read32(chipco, SSB_CHIPCO_FLASHDATA);
350 + for (e = ssb_sflash_sst_tbl; e->name; e++) {
358 + for (e = ssb_sflash_st_tbl; e->name; e++) {
365 + pr_err("Unsupported ST serial flash (id: 0x%X, id2: 0x%X)\n", id, id2);
370 + case SSB_CHIPCO_FLASHT_ATSER:
371 + ssb_sflash_cmd(chipco, SSB_CHIPCO_FLASHCTL_AT_STATUS);
372 + id = chipco_read32(chipco, SSB_CHIPCO_FLASHDATA) & 0x3c;
374 + for (e = ssb_sflash_at_tbl; e->name; e++) {
379 + pr_err("Unsupported Atmel serial flash (id: 0x%X)\n", id);
385 + pr_err("Unsupported flash type\n");
389 + sflash->window = SSB_FLASH2;
390 + sflash->blocksize = e->blocksize;
391 + sflash->numblocks = e->numblocks;
392 + sflash->size = sflash->blocksize * sflash->numblocks;
393 + sflash->present = true;
394 + sflash->read = ssb_sflash_read;
395 + sflash->poll = ssb_sflash_poll;
396 + sflash->write = ssb_sflash_write;
397 + sflash->erase = ssb_sflash_erase;
398 + sflash->type = BCM47XX_SFLASH_SSB;
399 + sflash->scc = chipco;
401 + pr_info("Found %s serial flash (size: %dKiB, blocksize: 0x%X, blocks: %d)\n",
402 + e->name, sflash->size / 1024, sflash->blocksize,
403 + sflash->numblocks);
405 + /* Prepare platform device, but don't register it yet. It's too early,
406 + * malloc (required by device_private_init) is not available yet. */
407 + ssb_sflash_dev.resource[0].end = ssb_sflash_dev.resource[0].start +
409 + ssb_sflash_dev.dev.platform_data = sflash;
414 --- a/drivers/ssb/main.c
415 +++ b/drivers/ssb/main.c
417 #include <linux/ssb/ssb_driver_gige.h>
418 #include <linux/dma-mapping.h>
419 #include <linux/pci.h>
420 +#include <linux/platform_device.h>
421 #include <linux/mmc/sdio_func.h>
422 #include <linux/slab.h>
424 @@ -540,6 +541,15 @@ static int ssb_devices_register(struct s
428 +#ifdef CONFIG_SSB_SFLASH
429 + if (bus->chipco.sflash.present) {
430 + err = platform_device_register(&ssb_sflash_dev);
432 + ssb_printk(KERN_ERR PFX
433 + "Error registering serial flash\n");
439 /* Unwind the already registered devices. */
440 --- a/drivers/ssb/ssb_private.h
441 +++ b/drivers/ssb/ssb_private.h
442 @@ -220,6 +220,7 @@ extern u32 ssb_chipco_watchdog_timer_set
443 /* driver_chipcommon_sflash.c */
444 #ifdef CONFIG_SSB_SFLASH
445 int ssb_sflash_init(struct ssb_chipcommon *cc);
446 +extern struct platform_device ssb_sflash_dev;
448 static inline int ssb_sflash_init(struct ssb_chipcommon *cc)
450 --- a/include/linux/ssb/ssb_driver_chipcommon.h
451 +++ b/include/linux/ssb/ssb_driver_chipcommon.h
453 * Licensed under the GPL version 2. See COPYING for details.
456 +#include <linux/mtd/bcm47xx_sflash.h>
458 /** ChipCommon core registers. **/
460 #define SSB_CHIPCO_CHIPID 0x0000
462 #define SSB_CHIPCO_FLASHCTL_BUSY SSB_CHIPCO_FLASHCTL_START
463 #define SSB_CHIPCO_FLASHADDR 0x0044
464 #define SSB_CHIPCO_FLASHDATA 0x0048
465 +/* Status register bits for ST flashes */
466 +#define SSB_CHIPCO_FLASHDATA_ST_WIP 0x01 /* Write In Progress */
467 +#define SSB_CHIPCO_FLASHDATA_ST_WEL 0x02 /* Write Enable Latch */
468 +#define SSB_CHIPCO_FLASHDATA_ST_BP_MASK 0x1c /* Block Protect */
469 +#define SSB_CHIPCO_FLASHDATA_ST_BP_SHIFT 2
470 +#define SSB_CHIPCO_FLASHDATA_ST_SRWD 0x80 /* Status Register Write Disable */
471 +/* Status register bits for Atmel flashes */
472 +#define SSB_CHIPCO_FLASHDATA_AT_READY 0x80
473 +#define SSB_CHIPCO_FLASHDATA_AT_MISMATCH 0x40
474 +#define SSB_CHIPCO_FLASHDATA_AT_ID_MASK 0x38
475 +#define SSB_CHIPCO_FLASHDATA_AT_ID_SHIFT 3
476 #define SSB_CHIPCO_BCAST_ADDR 0x0050
477 #define SSB_CHIPCO_BCAST_DATA 0x0054
478 #define SSB_CHIPCO_GPIOPULLUP 0x0058 /* Rev >= 20 only */
480 #define SSB_CHIPCO_FLASHCTL_ST_PP 0x0302 /* Page Program */
481 #define SSB_CHIPCO_FLASHCTL_ST_SE 0x02D8 /* Sector Erase */
482 #define SSB_CHIPCO_FLASHCTL_ST_BE 0x00C7 /* Bulk Erase */
483 -#define SSB_CHIPCO_FLASHCTL_ST_DP 0x00B9 /* Deep Power-down */
484 +#define SSB_CHIPCO_FLASHCTL_ST_DP 0x00D9 /* Deep Power-down */
485 #define SSB_CHIPCO_FLASHCTL_ST_RES 0x03AB /* Read Electronic Signature */
486 #define SSB_CHIPCO_FLASHCTL_ST_CSA 0x1000 /* Keep chip select asserted */
487 #define SSB_CHIPCO_FLASHCTL_ST_SSE 0x0220 /* Sub-sector Erase */
488 @@ -594,6 +607,9 @@ struct ssb_chipcommon {
489 struct ssb_chipcommon_pmu pmu;
492 +#ifdef CONFIG_SSB_SFLASH
493 + struct bcm47xx_sflash sflash;
497 static inline bool ssb_chipco_available(struct ssb_chipcommon *cc)