kernel-fxtec-pro1x/drivers/mtd/devices/m25p80.c
David Brownell fa0a8c71f3 [MTD] m25p80 handles more chips, uses JEDEC ids and small eraseblocks
Update chip ID tables in m25p80 to handle more SPI flash chips, matching
datasheets.  All of these can use the same core operations and are newer
chips that support the JEDEC "read id" instruction:

 - Atmel AT25 and AT26 (seven chips)
 - Spansion S25SL (five chips)
 - SST 25VF (four chips)
 - ST M25, M45 (five more chips)
 - Winbond W25X series (seven chips)

That JEDEC instruction is now used, either to support a sanity check on the
platform data holding board configuration data, or to determine chip type
when it's not included in platform data.  In fact, boards that don't need a
standard partition table may not need that platform data any more.

For chips that support 4KiB erase units, use that smaller block size instead
of the larger size (usually 64KiB); it's less wasteful.  (Tested on W25X80.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
2007-06-28 22:37:36 +01:00

712 lines
18 KiB
C

/*
* MTD SPI driver for ST M25Pxx (and similar) serial flash chips
*
* Author: Mike Lavender, mike@steroidmicros.com
*
* Copyright (c) 2005, Intec Automation Inc.
*
* Some parts are based on lart.c by Abraham Van Der Merwe
*
* Cleaned up and generalized based on mtd_dataflash.c
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#define FLASH_PAGESIZE 256
/* Flash opcodes. */
#define OPCODE_WREN 0x06 /* Write enable */
#define OPCODE_RDSR 0x05 /* Read status register */
#define OPCODE_READ 0x03 /* Read data bytes (low frequency) */
#define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */
#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */
#define OPCODE_BE_4K 0x20 /* Erase 4K block */
#define OPCODE_BE_32K 0x52 /* Erase 32K block */
#define OPCODE_SE 0xd8 /* Sector erase (usually 64K) */
#define OPCODE_RDID 0x9f /* Read JEDEC ID */
/* Status Register bits. */
#define SR_WIP 1 /* Write in progress */
#define SR_WEL 2 /* Write enable latch */
/* meaning of other SR_* bits may differ between vendors */
#define SR_BP0 4 /* Block protect 0 */
#define SR_BP1 8 /* Block protect 1 */
#define SR_BP2 0x10 /* Block protect 2 */
#define SR_SRWD 0x80 /* SR write protect */
/* Define max times to check status register before we give up. */
#define MAX_READY_WAIT_COUNT 100000
#ifdef CONFIG_MTD_PARTITIONS
#define mtd_has_partitions() (1)
#else
#define mtd_has_partitions() (0)
#endif
/****************************************************************************/
struct m25p {
struct spi_device *spi;
struct mutex lock;
struct mtd_info mtd;
unsigned partitioned:1;
u8 erase_opcode;
u8 command[4];
};
static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
{
return container_of(mtd, struct m25p, mtd);
}
/****************************************************************************/
/*
* Internal helper functions
*/
/*
* Read the status register, returning its value in the location
* Return the status register value.
* Returns negative if error occurred.
*/
static int read_sr(struct m25p *flash)
{
ssize_t retval;
u8 code = OPCODE_RDSR;
u8 val;
retval = spi_write_then_read(flash->spi, &code, 1, &val, 1);
if (retval < 0) {
dev_err(&flash->spi->dev, "error %d reading SR\n",
(int) retval);
return retval;
}
return val;
}
/*
* Set write enable latch with Write Enable command.
* Returns negative if error occurred.
*/
static inline int write_enable(struct m25p *flash)
{
u8 code = OPCODE_WREN;
return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
}
/*
* Service routine to read status register until ready, or timeout occurs.
* Returns non-zero if error.
*/
static int wait_till_ready(struct m25p *flash)
{
int count;
int sr;
/* one chip guarantees max 5 msec wait here after page writes,
* but potentially three seconds (!) after page erase.
*/
for (count = 0; count < MAX_READY_WAIT_COUNT; count++) {
if ((sr = read_sr(flash)) < 0)
break;
else if (!(sr & SR_WIP))
return 0;
/* REVISIT sometimes sleeping would be best */
}
return 1;
}
/*
* Erase one sector of flash memory at offset ``offset'' which is any
* address within the sector which should be erased.
*
* Returns 0 if successful, non-zero otherwise.
*/
static int erase_sector(struct m25p *flash, u32 offset)
{
DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dK at 0x%08x\n",
flash->spi->dev.bus_id, __FUNCTION__,
flash->mtd.erasesize / 1024, offset);
/* Wait until finished previous write command. */
if (wait_till_ready(flash))
return 1;
/* Send write enable, then erase commands. */
write_enable(flash);
/* Set up command buffer. */
flash->command[0] = flash->erase_opcode;
flash->command[1] = offset >> 16;
flash->command[2] = offset >> 8;
flash->command[3] = offset;
spi_write(flash->spi, flash->command, sizeof(flash->command));
return 0;
}
/****************************************************************************/
/*
* MTD implementation
*/
/*
* Erase an address range on the flash chip. The address range may extend
* one or more erase sectors. Return an error is there is a problem erasing.
*/
static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
{
struct m25p *flash = mtd_to_m25p(mtd);
u32 addr,len;
DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
flash->spi->dev.bus_id, __FUNCTION__, "at",
(u32)instr->addr, instr->len);
/* sanity checks */
if (instr->addr + instr->len > flash->mtd.size)
return -EINVAL;
if ((instr->addr % mtd->erasesize) != 0
|| (instr->len % mtd->erasesize) != 0) {
return -EINVAL;
}
addr = instr->addr;
len = instr->len;
mutex_lock(&flash->lock);
/* REVISIT in some cases we could speed up erasing large regions
* by using OPCODE_SE instead of OPCODE_BE_4K
*/
/* now erase those sectors */
while (len) {
if (erase_sector(flash, addr)) {
instr->state = MTD_ERASE_FAILED;
mutex_unlock(&flash->lock);
return -EIO;
}
addr += mtd->erasesize;
len -= mtd->erasesize;
}
mutex_unlock(&flash->lock);
instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr);
return 0;
}
/*
* Read an address range from the flash chip. The address range
* may be any size provided it is within the physical boundaries.
*/
static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct m25p *flash = mtd_to_m25p(mtd);
struct spi_transfer t[2];
struct spi_message m;
DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
flash->spi->dev.bus_id, __FUNCTION__, "from",
(u32)from, len);
/* sanity checks */
if (!len)
return 0;
if (from + len > flash->mtd.size)
return -EINVAL;
spi_message_init(&m);
memset(t, 0, (sizeof t));
t[0].tx_buf = flash->command;
t[0].len = sizeof(flash->command);
spi_message_add_tail(&t[0], &m);
t[1].rx_buf = buf;
t[1].len = len;
spi_message_add_tail(&t[1], &m);
/* Byte count starts at zero. */
if (retlen)
*retlen = 0;
mutex_lock(&flash->lock);
/* Wait till previous write/erase is done. */
if (wait_till_ready(flash)) {
/* REVISIT status return?? */
mutex_unlock(&flash->lock);
return 1;
}
/* FIXME switch to OPCODE_FAST_READ. It's required for higher
* clocks; and at this writing, every chip this driver handles
* supports that opcode.
*/
/* Set up the write data buffer. */
flash->command[0] = OPCODE_READ;
flash->command[1] = from >> 16;
flash->command[2] = from >> 8;
flash->command[3] = from;
spi_sync(flash->spi, &m);
*retlen = m.actual_length - sizeof(flash->command);
mutex_unlock(&flash->lock);
return 0;
}
/*
* Write an address range to the flash chip. Data must be written in
* FLASH_PAGESIZE chunks. The address range may be any size provided
* it is within the physical boundaries.
*/
static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)
{
struct m25p *flash = mtd_to_m25p(mtd);
u32 page_offset, page_size;
struct spi_transfer t[2];
struct spi_message m;
DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
flash->spi->dev.bus_id, __FUNCTION__, "to",
(u32)to, len);
if (retlen)
*retlen = 0;
/* sanity checks */
if (!len)
return(0);
if (to + len > flash->mtd.size)
return -EINVAL;
spi_message_init(&m);
memset(t, 0, (sizeof t));
t[0].tx_buf = flash->command;
t[0].len = sizeof(flash->command);
spi_message_add_tail(&t[0], &m);
t[1].tx_buf = buf;
spi_message_add_tail(&t[1], &m);
mutex_lock(&flash->lock);
/* Wait until finished previous write command. */
if (wait_till_ready(flash))
return 1;
write_enable(flash);
/* Set up the opcode in the write buffer. */
flash->command[0] = OPCODE_PP;
flash->command[1] = to >> 16;
flash->command[2] = to >> 8;
flash->command[3] = to;
/* what page do we start with? */
page_offset = to % FLASH_PAGESIZE;
/* do all the bytes fit onto one page? */
if (page_offset + len <= FLASH_PAGESIZE) {
t[1].len = len;
spi_sync(flash->spi, &m);
*retlen = m.actual_length - sizeof(flash->command);
} else {
u32 i;
/* the size of data remaining on the first page */
page_size = FLASH_PAGESIZE - page_offset;
t[1].len = page_size;
spi_sync(flash->spi, &m);
*retlen = m.actual_length - sizeof(flash->command);
/* write everything in PAGESIZE chunks */
for (i = page_size; i < len; i += page_size) {
page_size = len - i;
if (page_size > FLASH_PAGESIZE)
page_size = FLASH_PAGESIZE;
/* write the next page to flash */
flash->command[1] = (to + i) >> 16;
flash->command[2] = (to + i) >> 8;
flash->command[3] = (to + i);
t[1].tx_buf = buf + i;
t[1].len = page_size;
wait_till_ready(flash);
write_enable(flash);
spi_sync(flash->spi, &m);
if (retlen)
*retlen += m.actual_length
- sizeof(flash->command);
}
}
mutex_unlock(&flash->lock);
return 0;
}
/****************************************************************************/
/*
* SPI device driver setup and teardown
*/
struct flash_info {
char *name;
/* JEDEC id zero means "no ID" (most older chips); otherwise it has
* a high byte of zero plus three data bytes: the manufacturer id,
* then a two byte device id.
*/
u32 jedec_id;
/* The size listed here is what works with OPCODE_SE, which isn't
* necessarily called a "sector" by the vendor.
*/
unsigned sector_size;
u16 n_sectors;
u16 flags;
#define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */
};
/* NOTE: double check command sets and memory organization when you add
* more flash chips. This current list focusses on newer chips, which
* have been converging on command sets which including JEDEC ID.
*/
static struct flash_info __devinitdata m25p_data [] = {
/* Atmel -- some are (confusingly) marketed as "DataFlash" */
{ "at25fs010", 0x1f6601, 32 * 1024, 4, SECT_4K, },
{ "at25fs040", 0x1f6604, 64 * 1024, 8, SECT_4K, },
{ "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, },
{ "at26f004", 0x1f0400, 64 * 1024, 8, SECT_4K, },
{ "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, },
{ "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, },
{ "at26df321", 0x1f4701, 64 * 1024, 64, SECT_4K, },
/* Spansion -- single (large) sector size only, at least
* for the chips listed here (without boot sectors).
*/
{ "s25sl004a", 0x010212, 64 * 1024, 8, },
{ "s25sl008a", 0x010213, 64 * 1024, 16, },
{ "s25sl016a", 0x010214, 64 * 1024, 32, },
{ "s25sl032a", 0x010215, 64 * 1024, 64, },
{ "s25sl064a", 0x010216, 64 * 1024, 128, },
/* SST -- large erase sizes are "overlays", "sectors" are 4K */
{ "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, },
{ "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, },
{ "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, },
{ "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, },
/* ST Microelectronics -- newer production may have feature updates */
{ "m25p05", 0x202010, 32 * 1024, 2, },
{ "m25p10", 0x202011, 32 * 1024, 4, },
{ "m25p20", 0x202012, 64 * 1024, 4, },
{ "m25p40", 0x202013, 64 * 1024, 8, },
{ "m25p80", 0, 64 * 1024, 16, },
{ "m25p16", 0x202015, 64 * 1024, 32, },
{ "m25p32", 0x202016, 64 * 1024, 64, },
{ "m25p64", 0x202017, 64 * 1024, 128, },
{ "m25p128", 0x202018, 256 * 1024, 64, },
{ "m45pe80", 0x204014, 64 * 1024, 16, },
{ "m45pe16", 0x204015, 64 * 1024, 32, },
{ "m25pe80", 0x208014, 64 * 1024, 16, },
{ "m25pe16", 0x208015, 64 * 1024, 32, SECT_4K, },
/* Winbond -- w25x "blocks" are 64K, "sectors" are 4K */
{ "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, },
{ "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, },
{ "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, },
{ "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, },
{ "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, },
{ "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, },
{ "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, },
};
static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
{
int tmp;
u8 code = OPCODE_RDID;
u8 id[3];
u32 jedec;
struct flash_info *info;
/* JEDEC also defines an optional "extended device information"
* string for after vendor-specific data, after the three bytes
* we use here. Supporting some chips might require using it.
*/
tmp = spi_write_then_read(spi, &code, 1, id, 3);
if (tmp < 0) {
DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
spi->dev.bus_id, tmp);
return NULL;
}
jedec = id[0];
jedec = jedec << 8;
jedec |= id[1];
jedec = jedec << 8;
jedec |= id[2];
for (tmp = 0, info = m25p_data;
tmp < ARRAY_SIZE(m25p_data);
tmp++, info++) {
if (info->jedec_id == jedec)
return info;
}
dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
return NULL;
}
/*
* board specific setup should have ensured the SPI clock used here
* matches what the READ command supports, at least until this driver
* understands FAST_READ (for clocks over 25 MHz).
*/
static int __devinit m25p_probe(struct spi_device *spi)
{
struct flash_platform_data *data;
struct m25p *flash;
struct flash_info *info;
unsigned i;
/* Platform data helps sort out which chip type we have, as
* well as how this board partitions it. If we don't have
* a chip ID, try the JEDEC id commands; they'll work for most
* newer chips, even if we don't recognize the particular chip.
*/
data = spi->dev.platform_data;
if (data && data->type) {
for (i = 0, info = m25p_data;
i < ARRAY_SIZE(m25p_data);
i++, info++) {
if (strcmp(data->type, info->name) == 0)
break;
}
/* unrecognized chip? */
if (i == ARRAY_SIZE(m25p_data)) {
DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n",
spi->dev.bus_id, data->type);
info = NULL;
/* recognized; is that chip really what's there? */
} else if (info->jedec_id) {
struct flash_info *chip = jedec_probe(spi);
if (!chip || chip != info) {
dev_warn(&spi->dev, "found %s, expected %s\n",
chip ? chip->name : "UNKNOWN",
info->name);
info = NULL;
}
}
} else
info = jedec_probe(spi);
if (!info)
return -ENODEV;
flash = kzalloc(sizeof *flash, GFP_KERNEL);
if (!flash)
return -ENOMEM;
flash->spi = spi;
mutex_init(&flash->lock);
dev_set_drvdata(&spi->dev, flash);
if (data && data->name)
flash->mtd.name = data->name;
else
flash->mtd.name = spi->dev.bus_id;
flash->mtd.type = MTD_NORFLASH;
flash->mtd.writesize = 1;
flash->mtd.flags = MTD_CAP_NORFLASH;
flash->mtd.size = info->sector_size * info->n_sectors;
flash->mtd.erase = m25p80_erase;
flash->mtd.read = m25p80_read;
flash->mtd.write = m25p80_write;
/* prefer "small sector" erase if possible */
if (info->flags & SECT_4K) {
flash->erase_opcode = OPCODE_BE_4K;
flash->mtd.erasesize = 4096;
} else {
flash->erase_opcode = OPCODE_SE;
flash->mtd.erasesize = info->sector_size;
}
dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name,
flash->mtd.size / 1024);
DEBUG(MTD_DEBUG_LEVEL2,
"mtd .name = %s, .size = 0x%.8x (%uM) "
".erasesize = 0x%.8x (%uK) .numeraseregions = %d\n",
flash->mtd.name,
flash->mtd.size, flash->mtd.size / (1024*1024),
flash->mtd.erasesize, flash->mtd.erasesize / 1024,
flash->mtd.numeraseregions);
if (flash->mtd.numeraseregions)
for (i = 0; i < flash->mtd.numeraseregions; i++)
DEBUG(MTD_DEBUG_LEVEL2,
"mtd.eraseregions[%d] = { .offset = 0x%.8x, "
".erasesize = 0x%.8x (%uK), "
".numblocks = %d }\n",
i, flash->mtd.eraseregions[i].offset,
flash->mtd.eraseregions[i].erasesize,
flash->mtd.eraseregions[i].erasesize / 1024,
flash->mtd.eraseregions[i].numblocks);
/* partitions should match sector boundaries; and it may be good to
* use readonly partitions for writeprotected sectors (BP2..BP0).
*/
if (mtd_has_partitions()) {
struct mtd_partition *parts = NULL;
int nr_parts = 0;
#ifdef CONFIG_MTD_CMDLINE_PARTS
static const char *part_probes[] = { "cmdlinepart", NULL, };
nr_parts = parse_mtd_partitions(&flash->mtd,
part_probes, &parts, 0);
#endif
if (nr_parts <= 0 && data && data->parts) {
parts = data->parts;
nr_parts = data->nr_parts;
}
if (nr_parts > 0) {
for (i = 0; i < nr_parts; i++) {
DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
"{.name = %s, .offset = 0x%.8x, "
".size = 0x%.8x (%uK) }\n",
i, parts[i].name,
parts[i].offset,
parts[i].size,
parts[i].size / 1024);
}
flash->partitioned = 1;
return add_mtd_partitions(&flash->mtd, parts, nr_parts);
}
} else if (data->nr_parts)
dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
data->nr_parts, data->name);
return add_mtd_device(&flash->mtd) == 1 ? -ENODEV : 0;
}
static int __devexit m25p_remove(struct spi_device *spi)
{
struct m25p *flash = dev_get_drvdata(&spi->dev);
int status;
/* Clean up MTD stuff. */
if (mtd_has_partitions() && flash->partitioned)
status = del_mtd_partitions(&flash->mtd);
else
status = del_mtd_device(&flash->mtd);
if (status == 0)
kfree(flash);
return 0;
}
static struct spi_driver m25p80_driver = {
.driver = {
.name = "m25p80",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = m25p_probe,
.remove = __devexit_p(m25p_remove),
/* REVISIT: many of these chips have deep power-down modes, which
* should clearly be entered on suspend() to minimize power use.
* And also when they're otherwise idle...
*/
};
static int m25p80_init(void)
{
return spi_register_driver(&m25p80_driver);
}
static void m25p80_exit(void)
{
spi_unregister_driver(&m25p80_driver);
}
module_init(m25p80_init);
module_exit(m25p80_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mike Lavender");
MODULE_DESCRIPTION("MTD SPI driver for ST M25Pxx flash chips");