summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPeng Fan <Peng.Fan@freescale.com>2015-03-26 11:24:45 +0800
committerMax Krummenacher <max.krummenacher@toradex.com>2016-03-09 14:42:18 +0100
commita91afa0072ee96308b1b18eacb4f616c14585039 (patch)
tree026a942ca0fe4e2c9489226b9f28ad4df6c0de81 /drivers
parentcfa08adafec791f0b0cf8cc74f5f1f2a923a6420 (diff)
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> (cherry picked from commit 9b6ac1f82b09d243dc674c780abcacf0e12262c2) Conflicts: drivers/mtd/spi/sf_internal.h drivers/mtd/spi/sf_params.c drivers/mtd/spi/sf_probe.c include/spi_flash.h Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/spi/sf_internal.h11
-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.c14
4 files changed, 98 insertions, 2 deletions
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 785f7a96fe..8987ad9ae4 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -43,8 +43,12 @@ enum {
SST_BP = 1 << 3,
SST_WP = 1 << 4,
WR_QPP = 1 << 5,
+ SECT_2K = 1 << 6,
};
+#define SPI_FLASH_PAGE_256 (1 << 0)
+#define SPI_FLASH_PAGE_264 (1 << 1)
+
#define SST_WR (SST_BP | SST_WP)
#define SPI_FLASH_3B_ADDR_LEN 3
@@ -58,6 +62,7 @@ enum {
#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
@@ -67,7 +72,11 @@ enum {
#define CMD_WRITE_STATUS 0x01
#define CMD_PAGE_PROGRAM 0x02
#define CMD_WRITE_DISABLE 0x04
-#define CMD_READ_STATUS 0x05
+#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 34bc54e73e..0e7533192b 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 c12e8c6fe7..a5cdf1172f 100644
--- a/drivers/mtd/spi/sf_params.c
+++ b/drivers/mtd/spi/sf_params.c
@@ -16,6 +16,7 @@
const struct spi_flash_params spi_flash_params_table[] = {
#ifdef CONFIG_SPI_FLASH_ATMEL /* ATMEL */
{"AT45DB011D", 0x1f2200, 0x0, 64 * 1024, 4, RD_NORM, SECT_4K},
+ {"AT45DB021E", 0x1f2300, 0x100, 32 * 1024, 8, 0, SECT_2K},
{"AT45DB021D", 0x1f2300, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K},
{"AT45DB041D", 0x1f2400, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K},
{"AT45DB081D", 0x1f2500, 0x0, 64 * 1024, 16, RD_NORM, SECT_4K},
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 689af3a71d..2ba1500d49 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -172,7 +172,10 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode,
#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) {
@@ -396,6 +399,15 @@ int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash)
if (spi_enable_wp_pin(flash))
puts("Enable WP pin failed\n");
+
+#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
+
/* Release spi bus */
spi_release_bus(spi);