X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fmtd%2Fspi%2Fsf_dataflash.c;h=b6a2631747a9d89aea718b5f20eb2b62ec1e4e2c;hb=92430b8fc8aac3b4ab92e9ca8a09d83c4788c609;hp=7c6c8d2b027fe4e81959de20ffb5739d0cff26ee;hpb=1835302d3cb15ed67e06ee5e44fff1c611fbd467;p=oweals%2Fu-boot.git diff --git a/drivers/mtd/spi/sf_dataflash.c b/drivers/mtd/spi/sf_dataflash.c index 7c6c8d2b02..b6a2631747 100644 --- a/drivers/mtd/spi/sf_dataflash.c +++ b/drivers/mtd/spi/sf_dataflash.c @@ -1,12 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ /* - * * Atmel DataFlash probing * * Copyright (C) 2004-2009, 2015 Freescale Semiconductor, Inc. * Haikun Wang (haikun.wang@freescale.com) - * - * SPDX-License-Identifier: GPL-2.0+ -*/ + */ + #include #include #include @@ -19,6 +18,7 @@ #include "sf_internal.h" +#define CMD_READ_ID 0x9f /* reads can bypass the buffers */ #define OP_READ_CONTINUOUS 0xE8 #define OP_READ_PAGE 0xD2 @@ -67,15 +67,12 @@ #define OP_WRITE_SECURITY_REVC 0x9A #define OP_WRITE_SECURITY 0x9B /* revision D */ - struct dataflash { uint8_t command[16]; unsigned short page_offset; /* offset in flash address */ }; -/* - * Return the status of the DataFlash device. - */ +/* Return the status of the DataFlash device */ static inline int dataflash_status(struct spi_slave *spi) { int ret; @@ -114,9 +111,7 @@ static int dataflash_waitready(struct spi_slave *spi) return -ETIME; } -/* - * Erase pages of flash. - */ +/* Erase pages of flash */ static int spi_dataflash_erase(struct udevice *dev, u32 offset, size_t len) { struct dataflash *dataflash; @@ -139,15 +134,21 @@ static int spi_dataflash_erase(struct udevice *dev, u32 offset, size_t len) debug("%s: erase addr=0x%x len 0x%x\n", dev->name, offset, len); div_u64_rem(len, spi_flash->page_size, &rem); - if (rem) + if (rem) { + printf("%s: len(0x%x) isn't the multiple of page size(0x%x)\n", + dev->name, len, spi_flash->page_size); return -EINVAL; + } div_u64_rem(offset, spi_flash->page_size, &rem); - if (rem) + if (rem) { + printf("%s: offset(0x%x) isn't the multiple of page size(0x%x)\n", + dev->name, offset, spi_flash->page_size); return -EINVAL; + } status = spi_claim_bus(spi); if (status) { - debug("SPI DATAFLASH: unable to claim SPI bus\n"); + debug("dataflash: unable to claim SPI bus\n"); return status; } @@ -232,7 +233,7 @@ static int spi_dataflash_read(struct udevice *dev, u32 offset, size_t len, status = spi_claim_bus(spi); if (status) { - debug("SPI DATAFLASH: unable to claim SPI bus\n"); + debug("dataflash: unable to claim SPI bus\n"); return status; } @@ -290,7 +291,7 @@ int spi_dataflash_write(struct udevice *dev, u32 offset, size_t len, status = spi_claim_bus(spi); if (status) { - debug("SPI DATAFLASH: unable to claim SPI bus\n"); + debug("dataflash: unable to claim SPI bus\n"); return status; } @@ -387,7 +388,7 @@ int spi_dataflash_write(struct udevice *dev, u32 offset, size_t len, /* Check result of the compare operation */ if (status & (1 << 6)) { - printf("SPI DataFlash: write compare page %u, err %d\n", + printf("dataflash: write compare page %u, err %d\n", pageaddr, status); remaining = 0; status = -EIO; @@ -441,7 +442,7 @@ static int add_dataflash(struct udevice *dev, char *name, int nr_pages, return 0; } -struct flash_info { +struct data_flash_info { char *name; /* @@ -460,7 +461,7 @@ struct flash_info { #define IS_POW2PS 0x0001 /* uses 2^N byte pages */ }; -static struct flash_info dataflash_data[] = { +static struct data_flash_info dataflash_data[] = { /* * NOTE: chips with SUP_POW2PS (rev D and up) need two entries, * one with IS_POW2PS and the other without. The entry with the @@ -501,12 +502,12 @@ static struct flash_info dataflash_data[] = { { "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS}, }; -static struct flash_info *jedec_probe(struct spi_slave *spi) +static struct data_flash_info *jedec_probe(struct spi_slave *spi) { int tmp; uint8_t id[5]; uint32_t jedec; - struct flash_info *info; + struct data_flash_info *info; int status; /* @@ -539,7 +540,7 @@ static struct flash_info *jedec_probe(struct spi_slave *spi) if (info->flags & SUP_POW2PS) { status = dataflash_status(spi); if (status < 0) { - debug("SPI DataFlash: status error %d\n", + debug("dataflash: status error %d\n", status); return NULL; } @@ -561,10 +562,8 @@ static struct flash_info *jedec_probe(struct spi_slave *spi) * size (it might be binary) even when we can tell which density * class is involved (legacy chip id scheme). */ - printf("SPI DataFlash: Unsupported flash IDs: "); - printf("manuf %02x, jedec %04x, ext_jedec %04x\n", - id[0], jedec, id[3] << 8 | id[4]); - return NULL; + printf("dataflash: JEDEC id %06x not handled\n", jedec); + return ERR_PTR(-ENODEV); } /* @@ -585,16 +584,16 @@ static int spi_dataflash_probe(struct udevice *dev) { struct spi_slave *spi = dev_get_parent_priv(dev); struct spi_flash *spi_flash; - struct flash_info *info; - int ret, status = 0; + struct data_flash_info *info; + int status; spi_flash = dev_get_uclass_priv(dev); spi_flash->spi = spi; spi_flash->dev = dev; - ret = spi_claim_bus(spi); - if (ret) - return ret; + status = spi_claim_bus(spi); + if (status) + return status; /* * Try to detect dataflash by JEDEC ID. @@ -605,74 +604,68 @@ static int spi_dataflash_probe(struct udevice *dev) */ info = jedec_probe(spi); if (IS_ERR(info)) - return PTR_ERR(info); - if (info != NULL) - add_dataflash(dev, info->name, info->nr_pages, - info->pagesize, info->pageoffset, - (info->flags & SUP_POW2PS) ? 'd' : 'c'); - else { - /* - * Older chips support only legacy commands, identifing - * capacity using bits in the status byte. - */ - status = dataflash_status(spi); - if (status <= 0 || status == 0xff) { - printf("SPI DataFlash: read status error %d\n", status); - if (status == 0 || status == 0xff) - status = -ENODEV; - goto err_read_cmd; - } - /* - * if there's a device there, assume it's dataflash. - * board setup should have set spi->max_speed_max to - * match f(car) for continuous reads, mode 0 or 3. - */ - switch (status & 0x3c) { - case 0x0c: /* 0 0 1 1 x x */ - status = add_dataflash(dev, "AT45DB011B", - 512, 264, 9, 0); - break; - case 0x14: /* 0 1 0 1 x x */ - status = add_dataflash(dev, "AT45DB021B", - 1024, 264, 9, 0); - break; - case 0x1c: /* 0 1 1 1 x x */ - status = add_dataflash(dev, "AT45DB041x", - 2048, 264, 9, 0); - break; - case 0x24: /* 1 0 0 1 x x */ - status = add_dataflash(dev, "AT45DB081B", - 4096, 264, 9, 0); - break; - case 0x2c: /* 1 0 1 1 x x */ - status = add_dataflash(dev, "AT45DB161x", - 4096, 528, 10, 0); - break; - case 0x34: /* 1 1 0 1 x x */ - status = add_dataflash(dev, "AT45DB321x", - 8192, 528, 10, 0); - break; - case 0x38: /* 1 1 1 x x x */ - case 0x3c: - status = add_dataflash(dev, "AT45DB642x", - 8192, 1056, 11, 0); - break; - /* obsolete AT45DB1282 not (yet?) supported */ - default: - dev_info(&spi->dev, "unsupported device (%x)\n", - status & 0x3c); + goto err_jedec_probe; + if (info != NULL) { + status = add_dataflash(dev, info->name, info->nr_pages, + info->pagesize, info->pageoffset, + (info->flags & SUP_POW2PS) ? 'd' : 'c'); + if (status < 0) + goto err_status; + } + + /* + * Older chips support only legacy commands, identifing + * capacity using bits in the status byte. + */ + status = dataflash_status(spi); + if (status <= 0 || status == 0xff) { + printf("dataflash: read status error %d\n", status); + if (status == 0 || status == 0xff) status = -ENODEV; - goto err_read_cmd; - } + goto err_jedec_probe; } - spi_release_bus(spi); + /* + * if there's a device there, assume it's dataflash. + * board setup should have set spi->max_speed_max to + * match f(car) for continuous reads, mode 0 or 3. + */ + switch (status & 0x3c) { + case 0x0c: /* 0 0 1 1 x x */ + status = add_dataflash(dev, "AT45DB011B", 512, 264, 9, 0); + break; + case 0x14: /* 0 1 0 1 x x */ + status = add_dataflash(dev, "AT45DB021B", 1024, 264, 9, 0); + break; + case 0x1c: /* 0 1 1 1 x x */ + status = add_dataflash(dev, "AT45DB041x", 2048, 264, 9, 0); + break; + case 0x24: /* 1 0 0 1 x x */ + status = add_dataflash(dev, "AT45DB081B", 4096, 264, 9, 0); + break; + case 0x2c: /* 1 0 1 1 x x */ + status = add_dataflash(dev, "AT45DB161x", 4096, 528, 10, 0); + break; + case 0x34: /* 1 1 0 1 x x */ + status = add_dataflash(dev, "AT45DB321x", 8192, 528, 10, 0); + break; + case 0x38: /* 1 1 1 x x x */ + case 0x3c: + status = add_dataflash(dev, "AT45DB642x", 8192, 1056, 11, 0); + break; + /* obsolete AT45DB1282 not (yet?) supported */ + default: + printf("dataflash: unsupported device (%x)\n", status & 0x3c); + status = -ENODEV; + goto err_status; + } - return 0; + return status; -err_read_cmd: +err_status: + spi_free_slave(spi); +err_jedec_probe: spi_release_bus(spi); - return status; }