summaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorPeng Fan <Peng.Fan@freescale.com>2015-03-25 17:25:46 +0800
committerPeng Fan <Peng.Fan@freescale.com>2015-03-26 10:31:24 +0800
commit9b6ac1f82b09d243dc674c780abcacf0e12262c2 (patch)
treeee597ea4269535a4cb083cfee70ea9e1b34a1dcd /drivers/mtd
parent8a49e53c5b518677b46cada5df153306161f29ac (diff)
downloadu-boot-imx-9b6ac1f82b09d243dc674c780abcacf0e12262c2.zip
u-boot-imx-9b6ac1f82b09d243dc674c780abcacf0e12262c2.tar.gz
u-boot-imx-9b6ac1f82b09d243dc674c780abcacf0e12262c2.tar.bz2
MLK-10467 mtd:spi Add ATMEL AT45DB021E support
This patch is to add atmel AT45DB021E spi flash support. Since this flash is different from the spi flash that we previous use such as m25p32 and spanion spi nor flashes, pieces of code are added. 1. The default page size is 264 bytes, but the mtd/spi framework can not handle such page. So we need to configure the page size from 264 to 256 bytes. Page Size command seq “Power of 2” binary page size (256 bytes)| 3Dh 2Ah 80h A6h DataFlash page size (264 bytes) | 3Dh 2Ah 80h A7h And when probe the flash, configure the flash to 256 bytes page size, if the page size is already 256bytes, just return and do not configure it again. The page size configuration times is only about 10000, so to avoid configuring it each time. 2. Add the flash params in sf_params.c. 3. This flash support 2K block erase, add this flag. 4. The status command is 0xD7, different from others. It's polling status bit is Bit 7 -> 0 Device is busy with an internal operation. -> 1 Device is ready. This patch has been tested on mx7d 19x19 ddr3 arm2 board. And tested on mx7d 12x12 lpddr3 board. All works fine. Note: Since this flash is only 256KB, we can not test spi boot on mx7d 19x19 arm2 board. If want to test this flash, open CONFIG_SYS_USE_SPINOR. Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/spi/sf_internal.h8
-rw-r--r--drivers/mtd/spi/sf_ops.c74
-rw-r--r--drivers/mtd/spi/sf_params.c1
-rw-r--r--drivers/mtd/spi/sf_probe.c13
4 files changed, 95 insertions, 1 deletions
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 6bcd522..9fd8c73 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -10,6 +10,9 @@
#ifndef _SF_INTERNAL_H_
#define _SF_INTERNAL_H_
+#define SPI_FLASH_PAGE_256 (1 << 0)
+#define SPI_FLASH_PAGE_264 (1 << 1)
+
#define SPI_FLASH_3B_ADDR_LEN 3
#define SPI_FLASH_CMD_LEN (1 + SPI_FLASH_3B_ADDR_LEN)
#define SPI_FLASH_16MB_BOUN 0x1000000
@@ -21,6 +24,7 @@
#define SPI_FLASH_CFI_MFR_WINBOND 0xef
/* Erase commands */
+#define CMD_ERASE_2K 0x50
#define CMD_ERASE_4K 0x20
#define CMD_ERASE_32K 0x52
#define CMD_ERASE_CHIP 0xc7
@@ -30,7 +34,11 @@
#define CMD_WRITE_STATUS 0x01
#define CMD_PAGE_PROGRAM 0x02
#define CMD_WRITE_DISABLE 0x04
+#ifdef CONFIG_SPI_FLASH_ATMEL
+#define CMD_READ_STATUS 0xd7
+#else
#define CMD_READ_STATUS 0x05
+#endif
#define CMD_QUAD_PAGE_PROGRAM 0x32
#define CMD_READ_STATUS1 0x35
#define CMD_WRITE_ENABLE 0x06
diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
index ef91b92..d9dee2a 100644
--- a/drivers/mtd/spi/sf_ops.c
+++ b/drivers/mtd/spi/sf_ops.c
@@ -55,6 +55,75 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws)
return 0;
}
+#if defined(CONFIG_SPI_FLASH_ATMEL)
+/*
+ * For the AT45DB021E, there are an extra eight bytes
+ * of memory in each page for a total of an extra 8KB
+ * (64-Kbits) of user-accessible memory.
+ * In order to be compatible with spi framework, we use 256bytes.
+ */
+
+int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc)
+{
+ u8 data[3];
+ u8 cmd;
+ int ret;
+
+ ret = spi_flash_cmd_read_status(flash, &data[0]);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * PAGE SIZE Page Size, bit 0.
+ * 0 Device is configured for standard DataFlash page size (264 bytes).
+ * 1 Device is configured for “power of 2” binary page size (256 bytes).
+ */
+ if (wc == SPI_FLASH_PAGE_256) {
+ /* Already 256? */
+ if (data[0] & 1)
+ return 0;
+ } else if (wc == SPI_FLASH_PAGE_264) {
+ /* Already 264? */
+ if ((data[0] & 1) == 0)
+ return 0;
+ } else {
+ debug("Unsupport page configuration!\n");
+ return -1;
+ }
+
+ /*
+ * 3D, 2A, 80, A6 command seq will configure flash page size 256.
+ * 3D, 2A, 80, A7 command seq will configure flash page size 264.
+ */
+ cmd = 0x3D;
+ if (wc == SPI_FLASH_PAGE_256)
+ data[2] = 0xA6;
+ else if (wc == SPI_FLASH_PAGE_264)
+ data[2] = 0xA7;
+ data[1] = 0x80;
+ data[0] = 0x2A;
+ ret = spi_flash_write_common(flash, &cmd, 1, data, 3);
+ if (ret) {
+ debug("SF: fail to write config register\n");
+ return ret;
+ }
+
+ /* Check again */
+ ret = spi_flash_cmd_read_status(flash, &data[0]);
+ if (ret < 0)
+ return ret;
+
+ /* Means failed to configure page size */
+ if (((wc == SPI_FLASH_PAGE_256) && ((data[0] & 1) == 0)) ||
+ ((wc == SPI_FLASH_PAGE_264) && (data[0] & 1))) {
+ debug("Failed to configure page size!\n");
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
int spi_flash_cmd_read_config(struct spi_flash *flash, u8 *rc)
{
@@ -170,6 +239,11 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
check_status = poll_bit;
}
+#ifdef CONFIG_SPI_FLASH_ATMEL
+ poll_bit = STATUS_PEC;
+ check_status = 1 << 7;
+#endif
+
#ifdef CONFIG_SF_DUAL_FLASH
if (spi->flags & SPI_XFER_U_PAGE)
flags |= SPI_XFER_U_PAGE;
diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c
index eb372b7..8c113b4 100644
--- a/drivers/mtd/spi/sf_params.c
+++ b/drivers/mtd/spi/sf_params.c
@@ -15,6 +15,7 @@
const struct spi_flash_params spi_flash_params_table[] = {
#ifdef CONFIG_SPI_FLASH_ATMEL /* ATMEL */
{"AT45DB011D", 0x1f2200, 0x0, 64 * 1024, 4, 0, SECT_4K},
+ {"AT45DB021E", 0x1f2300, 0x100, 32 * 1024, 8, 0, SECT_2K},
{"AT45DB021D", 0x1f2300, 0x0, 64 * 1024, 8, 0, SECT_4K},
{"AT45DB041D", 0x1f2400, 0x0, 64 * 1024, 8, 0, SECT_4K},
{"AT45DB081D", 0x1f2500, 0x0, 64 * 1024, 16, 0, SECT_4K},
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 36ae5e0..3aad903 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -169,7 +169,10 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
#endif
/* Compute erase sector and command */
- if (params->flags & SECT_4K) {
+ if (params->flags & SECT_2K) {
+ flash->erase_cmd = CMD_ERASE_2K;
+ flash->erase_size = 2048 << flash->shift;
+ } else if (params->flags & SECT_4K) {
flash->erase_cmd = CMD_ERASE_4K;
flash->erase_size = 4096 << flash->shift;
} else if (params->flags & SECT_32K) {
@@ -250,6 +253,14 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
spi_flash_cmd_write_status(flash, 0);
#endif
+#if defined(CONFIG_SPI_FLASH_ATMEL)
+ /*
+ * Default configure the page size to 256bytes to
+ * be compatible with the mtd/spi framework
+ */
+ spi_flash_cmd_write_config(flash, SPI_FLASH_PAGE_256);
+#endif
+
return flash;
}