0001
0002 #include <linux/kernel.h>
0003 #include <linux/module.h>
0004 #include <linux/slab.h>
0005 #include <linux/delay.h>
0006 #include <linux/ioport.h>
0007 #include <linux/mtd/mtd.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/bcma/bcma.h>
0010
0011 #include "bcm47xxsflash.h"
0012
0013 MODULE_LICENSE("GPL");
0014 MODULE_DESCRIPTION("Serial flash driver for BCMA bus");
0015
0016 static const char * const probes[] = { "bcm47xxpart", NULL };
0017
0018
0019
0020
0021
0022 static void bcm47xxsflash_cmd(struct bcm47xxsflash *b47s, u32 opcode)
0023 {
0024 int i;
0025
0026 b47s->cc_write(b47s, BCMA_CC_FLASHCTL, BCMA_CC_FLASHCTL_START | opcode);
0027 for (i = 0; i < 1000; i++) {
0028 if (!(b47s->cc_read(b47s, BCMA_CC_FLASHCTL) &
0029 BCMA_CC_FLASHCTL_BUSY))
0030 return;
0031 cpu_relax();
0032 }
0033 pr_err("Control command failed (timeout)!\n");
0034 }
0035
0036 static int bcm47xxsflash_poll(struct bcm47xxsflash *b47s, int timeout)
0037 {
0038 unsigned long deadline = jiffies + timeout;
0039
0040 do {
0041 switch (b47s->type) {
0042 case BCM47XXSFLASH_TYPE_ST:
0043 bcm47xxsflash_cmd(b47s, OPCODE_ST_RDSR);
0044 if (!(b47s->cc_read(b47s, BCMA_CC_FLASHDATA) &
0045 SR_ST_WIP))
0046 return 0;
0047 break;
0048 case BCM47XXSFLASH_TYPE_ATMEL:
0049 bcm47xxsflash_cmd(b47s, OPCODE_AT_STATUS);
0050 if (b47s->cc_read(b47s, BCMA_CC_FLASHDATA) &
0051 SR_AT_READY)
0052 return 0;
0053 break;
0054 }
0055
0056 cpu_relax();
0057 udelay(1);
0058 } while (!time_after_eq(jiffies, deadline));
0059
0060 pr_err("Timeout waiting for flash to be ready!\n");
0061
0062 return -EBUSY;
0063 }
0064
0065
0066
0067
0068
0069 static int bcm47xxsflash_erase(struct mtd_info *mtd, struct erase_info *erase)
0070 {
0071 struct bcm47xxsflash *b47s = mtd->priv;
0072
0073 switch (b47s->type) {
0074 case BCM47XXSFLASH_TYPE_ST:
0075 bcm47xxsflash_cmd(b47s, OPCODE_ST_WREN);
0076 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, erase->addr);
0077
0078
0079
0080
0081 if (b47s->blocksize < (64 * 1024))
0082 bcm47xxsflash_cmd(b47s, OPCODE_ST_SSE);
0083 else
0084 bcm47xxsflash_cmd(b47s, OPCODE_ST_SE);
0085 break;
0086 case BCM47XXSFLASH_TYPE_ATMEL:
0087 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, erase->addr << 1);
0088 bcm47xxsflash_cmd(b47s, OPCODE_AT_PAGE_ERASE);
0089 break;
0090 }
0091
0092 return bcm47xxsflash_poll(b47s, HZ);
0093 }
0094
0095 static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
0096 size_t *retlen, u_char *buf)
0097 {
0098 struct bcm47xxsflash *b47s = mtd->priv;
0099 size_t orig_len = len;
0100
0101
0102 if ((from + len) > mtd->size)
0103 return -EINVAL;
0104
0105
0106 if (from < BCM47XXSFLASH_WINDOW_SZ) {
0107 size_t memcpy_len;
0108
0109 memcpy_len = min(len, (size_t)(BCM47XXSFLASH_WINDOW_SZ - from));
0110 memcpy_fromio(buf, b47s->window + from, memcpy_len);
0111 from += memcpy_len;
0112 len -= memcpy_len;
0113 buf += memcpy_len;
0114 }
0115
0116
0117 for (; len; len--) {
0118 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, from++);
0119 bcm47xxsflash_cmd(b47s, OPCODE_ST_READ4B);
0120 *buf++ = b47s->cc_read(b47s, BCMA_CC_FLASHDATA);
0121 }
0122
0123 *retlen = orig_len;
0124
0125 return orig_len;
0126 }
0127
0128 static int bcm47xxsflash_write_st(struct mtd_info *mtd, u32 offset, size_t len,
0129 const u_char *buf)
0130 {
0131 struct bcm47xxsflash *b47s = mtd->priv;
0132 int written = 0;
0133
0134
0135 bcm47xxsflash_cmd(b47s, OPCODE_ST_WREN);
0136
0137
0138 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, offset);
0139 b47s->cc_write(b47s, BCMA_CC_FLASHDATA, *buf++);
0140
0141
0142 if (b47s->bcma_cc->core->id.rev < 20) {
0143 bcm47xxsflash_cmd(b47s, OPCODE_ST_PP);
0144 return 1;
0145 }
0146
0147
0148 bcm47xxsflash_cmd(b47s, OPCODE_ST_CSA | OPCODE_ST_PP);
0149 offset++;
0150 len--;
0151 written++;
0152
0153 while (len > 0) {
0154
0155 if ((offset & 0xFF) == 0)
0156 break;
0157
0158 bcm47xxsflash_cmd(b47s, OPCODE_ST_CSA | *buf++);
0159 offset++;
0160 len--;
0161 written++;
0162 }
0163
0164
0165 b47s->cc_write(b47s, BCMA_CC_FLASHCTL, 0);
0166 udelay(1);
0167 if (bcm47xxsflash_poll(b47s, HZ / 10))
0168 pr_err("Flash rejected dropping CSA\n");
0169
0170 return written;
0171 }
0172
0173 static int bcm47xxsflash_write_at(struct mtd_info *mtd, u32 offset, size_t len,
0174 const u_char *buf)
0175 {
0176 struct bcm47xxsflash *b47s = mtd->priv;
0177 u32 mask = b47s->blocksize - 1;
0178 u32 page = (offset & ~mask) << 1;
0179 u32 byte = offset & mask;
0180 int written = 0;
0181
0182
0183 if (byte || (len < b47s->blocksize)) {
0184 int err;
0185
0186 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, page);
0187 bcm47xxsflash_cmd(b47s, OPCODE_AT_BUF1_LOAD);
0188
0189 err = bcm47xxsflash_poll(b47s, HZ / 1000);
0190 if (err) {
0191 pr_err("Timeout reading page 0x%X info buffer\n", page);
0192 return err;
0193 }
0194 }
0195
0196
0197 while (len > 0) {
0198
0199 if (byte == b47s->blocksize)
0200 break;
0201
0202 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, byte++);
0203 b47s->cc_write(b47s, BCMA_CC_FLASHDATA, *buf++);
0204 bcm47xxsflash_cmd(b47s, OPCODE_AT_BUF1_WRITE);
0205 len--;
0206 written++;
0207 }
0208
0209
0210 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, page);
0211 bcm47xxsflash_cmd(b47s, OPCODE_AT_BUF1_PROGRAM);
0212
0213 return written;
0214 }
0215
0216 static int bcm47xxsflash_write(struct mtd_info *mtd, loff_t to, size_t len,
0217 size_t *retlen, const u_char *buf)
0218 {
0219 struct bcm47xxsflash *b47s = mtd->priv;
0220 int written;
0221
0222
0223
0224
0225 while (len > 0) {
0226 switch (b47s->type) {
0227 case BCM47XXSFLASH_TYPE_ST:
0228 written = bcm47xxsflash_write_st(mtd, to, len, buf);
0229 break;
0230 case BCM47XXSFLASH_TYPE_ATMEL:
0231 written = bcm47xxsflash_write_at(mtd, to, len, buf);
0232 break;
0233 default:
0234 BUG_ON(1);
0235 }
0236 if (written < 0) {
0237 pr_err("Error writing at offset 0x%llX\n", to);
0238 return written;
0239 }
0240 to += (loff_t)written;
0241 len -= written;
0242 *retlen += written;
0243 buf += written;
0244 }
0245
0246 return 0;
0247 }
0248
0249 static void bcm47xxsflash_fill_mtd(struct bcm47xxsflash *b47s,
0250 struct device *dev)
0251 {
0252 struct mtd_info *mtd = &b47s->mtd;
0253
0254 mtd->priv = b47s;
0255 mtd->dev.parent = dev;
0256 mtd->name = "bcm47xxsflash";
0257
0258 mtd->type = MTD_NORFLASH;
0259 mtd->flags = MTD_CAP_NORFLASH;
0260 mtd->size = b47s->size;
0261 mtd->erasesize = b47s->blocksize;
0262 mtd->writesize = 1;
0263 mtd->writebufsize = 1;
0264
0265 mtd->_erase = bcm47xxsflash_erase;
0266 mtd->_read = bcm47xxsflash_read;
0267 mtd->_write = bcm47xxsflash_write;
0268 }
0269
0270
0271
0272
0273
0274 static int bcm47xxsflash_bcma_cc_read(struct bcm47xxsflash *b47s, u16 offset)
0275 {
0276 return bcma_cc_read32(b47s->bcma_cc, offset);
0277 }
0278
0279 static void bcm47xxsflash_bcma_cc_write(struct bcm47xxsflash *b47s, u16 offset,
0280 u32 value)
0281 {
0282 bcma_cc_write32(b47s->bcma_cc, offset, value);
0283 }
0284
0285 static int bcm47xxsflash_bcma_probe(struct platform_device *pdev)
0286 {
0287 struct device *dev = &pdev->dev;
0288 struct bcma_sflash *sflash = dev_get_platdata(dev);
0289 struct bcm47xxsflash *b47s;
0290 struct resource *res;
0291 int err;
0292
0293 b47s = devm_kzalloc(dev, sizeof(*b47s), GFP_KERNEL);
0294 if (!b47s)
0295 return -ENOMEM;
0296
0297 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0298 if (!res) {
0299 dev_err(dev, "invalid resource\n");
0300 return -EINVAL;
0301 }
0302 if (!devm_request_mem_region(dev, res->start, resource_size(res),
0303 res->name)) {
0304 dev_err(dev, "can't request region for resource %pR\n", res);
0305 return -EBUSY;
0306 }
0307
0308 b47s->bcma_cc = container_of(sflash, struct bcma_drv_cc, sflash);
0309 b47s->cc_read = bcm47xxsflash_bcma_cc_read;
0310 b47s->cc_write = bcm47xxsflash_bcma_cc_write;
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 if (b47s->bcma_cc->core->id.rev == 54)
0323 b47s->window = ioremap(res->start, resource_size(res));
0324 else
0325 b47s->window = ioremap_cache(res->start, resource_size(res));
0326 if (!b47s->window) {
0327 dev_err(dev, "ioremap failed for resource %pR\n", res);
0328 return -ENOMEM;
0329 }
0330
0331 switch (b47s->bcma_cc->capabilities & BCMA_CC_CAP_FLASHT) {
0332 case BCMA_CC_FLASHT_STSER:
0333 b47s->type = BCM47XXSFLASH_TYPE_ST;
0334 break;
0335 case BCMA_CC_FLASHT_ATSER:
0336 b47s->type = BCM47XXSFLASH_TYPE_ATMEL;
0337 break;
0338 }
0339
0340 b47s->blocksize = sflash->blocksize;
0341 b47s->numblocks = sflash->numblocks;
0342 b47s->size = sflash->size;
0343 bcm47xxsflash_fill_mtd(b47s, &pdev->dev);
0344
0345 platform_set_drvdata(pdev, b47s);
0346
0347 err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0);
0348 if (err) {
0349 pr_err("Failed to register MTD device: %d\n", err);
0350 iounmap(b47s->window);
0351 return err;
0352 }
0353
0354 if (bcm47xxsflash_poll(b47s, HZ / 10))
0355 pr_warn("Serial flash busy\n");
0356
0357 return 0;
0358 }
0359
0360 static int bcm47xxsflash_bcma_remove(struct platform_device *pdev)
0361 {
0362 struct bcm47xxsflash *b47s = platform_get_drvdata(pdev);
0363
0364 mtd_device_unregister(&b47s->mtd);
0365 iounmap(b47s->window);
0366
0367 return 0;
0368 }
0369
0370 static struct platform_driver bcma_sflash_driver = {
0371 .probe = bcm47xxsflash_bcma_probe,
0372 .remove = bcm47xxsflash_bcma_remove,
0373 .driver = {
0374 .name = "bcma_sflash",
0375 },
0376 };
0377
0378
0379
0380
0381
0382 module_platform_driver(bcma_sflash_driver);