diff options
Diffstat (limited to 'target/linux/brcm47xx/patches-3.9/070-bcma-add-functions-to-write-to-serial-flash.patch')
-rw-r--r-- | target/linux/brcm47xx/patches-3.9/070-bcma-add-functions-to-write-to-serial-flash.patch | 271 |
1 files changed, 0 insertions, 271 deletions
diff --git a/target/linux/brcm47xx/patches-3.9/070-bcma-add-functions-to-write-to-serial-flash.patch b/target/linux/brcm47xx/patches-3.9/070-bcma-add-functions-to-write-to-serial-flash.patch deleted file mode 100644 index 9999848..0000000 --- a/target/linux/brcm47xx/patches-3.9/070-bcma-add-functions-to-write-to-serial-flash.patch +++ /dev/null @@ -1,271 +0,0 @@ ---- a/drivers/bcma/driver_chipcommon_sflash.c -+++ b/drivers/bcma/driver_chipcommon_sflash.c -@@ -1,6 +1,9 @@ - /* - * Broadcom specific AMBA - * ChipCommon serial flash interface -+ * Copyright 2011, Jonas Gorski <jonas.gorski@gmail.com> -+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de> -+ * Copyright 2010, Broadcom Corporation - * - * Licensed under the GNU/GPL. See COPYING for details. - */ -@@ -8,7 +11,11 @@ - #include "bcma_private.h" - - #include <linux/platform_device.h> -+#include <linux/delay.h> - #include <linux/bcma/bcma.h> -+#include <linux/bcma/bcma_driver_chipcommon.h> -+ -+#define NUM_RETRIES 3 - - static struct resource bcma_sflash_resource = { - .name = "bcma_sflash", -@@ -18,7 +25,7 @@ static struct resource bcma_sflash_resou - }; - - struct platform_device bcma_sflash_dev = { -- .name = "bcma_sflash", -+ .name = "bcm47xx-sflash", - .resource = &bcma_sflash_resource, - .num_resources = 1, - }; -@@ -84,11 +91,185 @@ static void bcma_sflash_cmd(struct bcma_ - bcma_err(cc->core->bus, "SFLASH control command failed (timeout)!\n"); - } - -+static void bcma_sflash_write_u8(struct bcma_drv_cc *cc, u32 offset, u8 byte) -+{ -+ bcma_cc_write32(cc, BCMA_CC_FLASHADDR, offset); -+ bcma_cc_write32(cc, BCMA_CC_FLASHDATA, byte); -+} -+ -+/* Poll for command completion. Returns zero when complete. */ -+static int bcma_sflash_poll(struct bcm47xxsflash *dev, u32 offset) -+{ -+ struct bcma_drv_cc *cc = dev->bcc; -+ -+ if (offset >= cc->sflash.size) -+ return -22; -+ -+ switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { -+ case BCMA_CC_FLASHT_STSER: -+ /* Check for ST Write In Progress bit */ -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_RDSR); -+ return bcma_cc_read32(cc, BCMA_CC_FLASHDATA) -+ & BCMA_CC_FLASHDATA_ST_WIP; -+ case BCMA_CC_FLASHT_ATSER: -+ /* Check for Atmel Ready bit */ -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_STATUS); -+ return !(bcma_cc_read32(cc, BCMA_CC_FLASHDATA) -+ & BCMA_CC_FLASHDATA_AT_READY); -+ } -+ -+ return 0; -+} -+ -+static int sflash_st_write(struct bcm47xxsflash *dev, u32 offset, u32 len, -+ const u8 *buf) -+{ -+ int written = 1; -+ struct bcma_drv_cc *cc = dev->bcc; -+ -+ /* Enable writes */ -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_WREN); -+ bcma_sflash_write_u8(cc, offset, *buf++); -+ /* Issue a page program with CSA bit set */ -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_CSA | BCMA_CC_FLASHCTL_ST_PP); -+ offset++; -+ len--; -+ while (len > 0) { -+ if ((offset & 255) == 0) { -+ /* Page boundary, poll droping cs and return */ -+ bcma_cc_write32(cc, BCMA_CC_FLASHCTL, 0); -+ udelay(1); -+ if (!bcma_sflash_poll(dev, offset)) { -+ /* Flash rejected command */ -+ return -EAGAIN; -+ } -+ return written; -+ } else { -+ /* Write single byte */ -+ bcma_sflash_cmd(cc, -+ BCMA_CC_FLASHCTL_ST_CSA | -+ *buf++); -+ } -+ written++; -+ offset++; -+ len--; -+ } -+ /* All done, drop cs & poll */ -+ bcma_cc_write32(cc, BCMA_CC_FLASHCTL, 0); -+ udelay(1); -+ if (!bcma_sflash_poll(dev, offset)) { -+ /* Flash rejected command */ -+ return -EAGAIN; -+ } -+ return written; -+} -+ -+static int sflash_at_write(struct bcm47xxsflash *dev, u32 offset, u32 len, -+ const u8 *buf) -+{ -+ struct bcma_drv_cc *cc = dev->bcc; -+ u32 page, byte, mask; -+ int ret = 0; -+ -+ mask = dev->blocksize - 1; -+ page = (offset & ~mask) << 1; -+ byte = offset & mask; -+ /* Read main memory page into buffer 1 */ -+ if (byte || (len < dev->blocksize)) { -+ int i = 100; -+ bcma_cc_write32(cc, BCMA_CC_FLASHADDR, page); -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_BUF1_LOAD); -+ /* 250 us for AT45DB321B */ -+ while (i > 0 && bcma_sflash_poll(dev, offset)) { -+ udelay(10); -+ i--; -+ } -+ BUG_ON(!bcma_sflash_poll(dev, offset)); -+ } -+ /* Write into buffer 1 */ -+ for (ret = 0; (ret < (int)len) && (byte < dev->blocksize); ret++) { -+ bcma_sflash_write_u8(cc, byte++, *buf++); -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_BUF1_WRITE); -+ } -+ /* Write buffer 1 into main memory page */ -+ bcma_cc_write32(cc, BCMA_CC_FLASHADDR, page); -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_BUF1_PROGRAM); -+ -+ return ret; -+} -+ -+/* Write len bytes starting at offset into buf. Returns number of bytes -+ * written. Caller should poll for completion. -+ */ -+static int bcma_sflash_write(struct bcm47xxsflash *dev, u32 offset, u32 len, -+ const u8 *buf) -+{ -+ int ret = 0, tries = NUM_RETRIES; -+ struct bcma_drv_cc *cc = dev->bcc; -+ -+ if (!len) -+ return 0; -+ -+ if ((offset + len) > cc->sflash.size) -+ return -EINVAL; -+ -+ switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { -+ case BCMA_CC_FLASHT_STSER: -+ do { -+ ret = sflash_st_write(dev, offset, len, buf); -+ tries--; -+ } while (ret == -EAGAIN && tries > 0); -+ -+ if (ret == -EAGAIN && tries == 0) { -+ bcma_info(cc->core->bus, "ST Flash rejected write\n"); -+ ret = -EIO; -+ } -+ break; -+ case BCMA_CC_FLASHT_ATSER: -+ ret = sflash_at_write(dev, offset, len, buf); -+ break; -+ } -+ -+ return ret; -+} -+ -+/* Erase a region. Returns number of bytes scheduled for erasure. -+ * Caller should poll for completion. -+ */ -+static int bcma_sflash_erase(struct bcm47xxsflash *dev, u32 offset) -+{ -+ struct bcma_drv_cc *cc = dev->bcc; -+ -+ if (offset >= cc->sflash.size) -+ return -EINVAL; -+ -+ switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { -+ case BCMA_CC_FLASHT_STSER: -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_WREN); -+ bcma_cc_write32(cc, BCMA_CC_FLASHADDR, offset); -+ /* Newer flashes have "sub-sectors" which can be erased independently -+ * with a new command: ST_SSE. The ST_SE command erases 64KB just as -+ * before. -+ */ -+ if (dev->blocksize < (64 * 1024)) -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_SSE); -+ else -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_SE); -+ return dev->blocksize; -+ case BCMA_CC_FLASHT_ATSER: -+ bcma_cc_write32(cc, BCMA_CC_FLASHADDR, offset << 1); -+ bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_PAGE_ERASE); -+ return dev->blocksize; -+ } -+ -+ return 0; -+} -+ - /* Initialize serial flash access */ - int bcma_sflash_init(struct bcma_drv_cc *cc) - { - struct bcma_bus *bus = cc->core->bus; -- struct bcma_sflash *sflash = &cc->sflash; -+ struct bcm47xxsflash *sflash = &cc->sflash; - const struct bcma_sflash_tbl_e *e; - u32 id, id2; - -@@ -150,6 +331,11 @@ int bcma_sflash_init(struct bcma_drv_cc - sflash->numblocks = e->numblocks; - sflash->size = sflash->blocksize * sflash->numblocks; - sflash->present = true; -+ sflash->poll = bcma_sflash_poll; -+ sflash->write = bcma_sflash_write; -+ sflash->erase = bcma_sflash_erase; -+ sflash->type = BCM47XX_SFLASH_BCMA; -+ sflash->bcc = cc; - - bcma_info(bus, "Found %s serial flash (size: %dKiB, blocksize: 0x%X, blocks: %d)\n", - e->name, sflash->size / 1024, sflash->blocksize, ---- a/include/linux/bcma/bcma_driver_chipcommon.h -+++ b/include/linux/bcma/bcma_driver_chipcommon.h -@@ -3,6 +3,7 @@ - - #include <linux/platform_device.h> - #include <linux/gpio.h> -+#include <linux/mtd/bcm47xxsflash.h> - - /** ChipCommon core registers. **/ - #define BCMA_CC_ID 0x0000 -@@ -578,19 +579,6 @@ struct bcma_pflash { - u32 window_size; - }; - --#ifdef CONFIG_BCMA_SFLASH --struct bcma_sflash { -- bool present; -- u32 window; -- u32 blocksize; -- u16 numblocks; -- u32 size; -- -- struct mtd_info *mtd; -- void *priv; --}; --#endif -- - #ifdef CONFIG_BCMA_NFLASH - struct mtd_info; - -@@ -624,7 +612,7 @@ struct bcma_drv_cc { - #ifdef CONFIG_BCMA_DRIVER_MIPS - struct bcma_pflash pflash; - #ifdef CONFIG_BCMA_SFLASH -- struct bcma_sflash sflash; -+ struct bcm47xxsflash sflash; - #endif - #ifdef CONFIG_BCMA_NFLASH - struct bcma_nflash nflash; |