Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: bcm47xxsflash: support reading flash out of mapping window

For reading flash content we use MMIO but it's possible to read only
first 16 MiB this way. It's simply an arch design/limitation.
To support flash sizes bigger than 16 MiB implement indirect access
using ChipCommon registers.
This has been tested using MX25L25635F.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Acked-by: Marek Vasut <marek.vasut@gmail.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>

authored by

Rafał Miłecki and committed by
Brian Norris
ccc38234 9c8d7ff3

+24 -3
+21 -3
drivers/mtd/devices/bcm47xxsflash.c
··· 105 105 size_t *retlen, u_char *buf) 106 106 { 107 107 struct bcm47xxsflash *b47s = mtd->priv; 108 + size_t orig_len = len; 108 109 109 110 /* Check address range */ 110 111 if ((from + len) > mtd->size) 111 112 return -EINVAL; 112 113 113 - memcpy_fromio(buf, b47s->window + from, len); 114 - *retlen = len; 114 + /* Read as much as possible using fast MMIO window */ 115 + if (from < BCM47XXSFLASH_WINDOW_SZ) { 116 + size_t memcpy_len; 115 117 116 - return len; 118 + memcpy_len = min(len, (size_t)(BCM47XXSFLASH_WINDOW_SZ - from)); 119 + memcpy_fromio(buf, b47s->window + from, memcpy_len); 120 + from += memcpy_len; 121 + len -= memcpy_len; 122 + buf += memcpy_len; 123 + } 124 + 125 + /* Use indirect access for content out of the window */ 126 + for (; len; len--) { 127 + b47s->cc_write(b47s, BCMA_CC_FLASHADDR, from++); 128 + bcm47xxsflash_cmd(b47s, OPCODE_ST_READ4B); 129 + *buf++ = b47s->cc_read(b47s, BCMA_CC_FLASHDATA); 130 + } 131 + 132 + *retlen = orig_len; 133 + 134 + return orig_len; 117 135 } 118 136 119 137 static int bcm47xxsflash_write_st(struct mtd_info *mtd, u32 offset, size_t len,
+3
drivers/mtd/devices/bcm47xxsflash.h
··· 3 3 4 4 #include <linux/mtd/mtd.h> 5 5 6 + #define BCM47XXSFLASH_WINDOW_SZ SZ_16M 7 + 6 8 /* Used for ST flashes only. */ 7 9 #define OPCODE_ST_WREN 0x0006 /* Write Enable */ 8 10 #define OPCODE_ST_WRDIS 0x0004 /* Write Disable */ ··· 18 16 #define OPCODE_ST_RES 0x03ab /* Read Electronic Signature */ 19 17 #define OPCODE_ST_CSA 0x1000 /* Keep chip select asserted */ 20 18 #define OPCODE_ST_SSE 0x0220 /* Sub-sector Erase */ 19 + #define OPCODE_ST_READ4B 0x6313 /* Read Data Bytes in 4Byte addressing mode */ 21 20 22 21 /* Used for Atmel flashes only. */ 23 22 #define OPCODE_AT_READ 0x07e8