[U-Boot] [PATCH v5 18/32] sf: ramtron: Add support for separate flash driver

Jagannadha Sutradharudu Teki jagannadha.sutradharudu-teki at xilinx.com
Wed Oct 2 18:50:28 CEST 2013


Compared to other spi flashes, ramtron has a different
probing and implementation on flash ops, hence moved
ramtron probe code into ramtron driver.

Signed-off-by: Jagannadha Sutradharudu Teki <jaganna at xilinx.com>
---
Changes for v5:
        - none
Changes for v4:
        - none
Changes for v3:
        - none
Changes for v2:
	- none

 drivers/mtd/spi/Makefile                 |   5 +-
 drivers/mtd/spi/ramtron.c                | 123 +++++++++++++-
 drivers/mtd/spi/spi_flash_probe.c        |   4 -
 drivers/mtd/spi/spi_flash_probe_legacy.c | 276 -------------------------------
 include/configs/top9000.h                |   1 -
 5 files changed, 125 insertions(+), 284 deletions(-)
 delete mode 100644 drivers/mtd/spi/spi_flash_probe_legacy.c

diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index a10c850..2605e57 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -14,7 +14,10 @@ COBJS-$(CONFIG_SPL_SPI_LOAD)	+= spi_spl_load.o
 COBJS-$(CONFIG_SPL_SPI_BOOT)	+= fsl_espi_spl.o
 endif
 
-COBJS-$(CONFIG_SPI_FLASH) += spi_flash_probe_legacy.o spi_flash_ops.o spi_flash.o
+ifdef CONFIG_CMD_SF
+COBJS-y        += spi_flash.o
+endif
+COBJS-$(CONFIG_SPI_FLASH)	+= spi_flash_probe.o spi_flash_ops.o
 COBJS-$(CONFIG_SPI_FLASH_ATMEL)	+= atmel.o
 COBJS-$(CONFIG_SPI_FLASH_EON)	+= eon.o
 COBJS-$(CONFIG_SPI_FLASH_GIGADEVICE)	+= gigadevice.o
diff --git a/drivers/mtd/spi/ramtron.c b/drivers/mtd/spi/ramtron.c
index 38f9d69..c9701d0 100644
--- a/drivers/mtd/spi/ramtron.c
+++ b/drivers/mtd/spi/ramtron.c
@@ -214,7 +214,8 @@ static int ramtron_erase(struct spi_flash *flash, u32 offset, size_t len)
  * nore: we are called here with idcode pointing to the first non-0x7f byte
  * already!
  */
-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
+static struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi,
+		u8 *idcode)
 {
 	const struct ramtron_spi_fram_params *params;
 	struct ramtron_spi_fram *sn;
@@ -270,7 +271,7 @@ struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
 	return NULL;
 
 found:
-	sn = spi_flash_alloc(struct ramtron_spi_fram, spi, params->name);
+	sn = malloc(sizeof(*sn));
 	if (!sn) {
 		debug("SF: Failed to allocate memory\n");
 		return NULL;
@@ -285,3 +286,121 @@ found:
 
 	return &sn->flash;
 }
+
+/*
+ * The following table holds all device probe functions
+ * (All flashes are removed and implemented a common probe at
+ *  spi_flash_probe.c)
+ *
+ * shift:  number of continuation bytes before the ID
+ * idcode: the expected IDCODE or 0xff for non JEDEC devices
+ * probe:  the function to call
+ *
+ * Non JEDEC devices should be ordered in the table such that
+ * the probe functions with best detection algorithms come first.
+ *
+ * Several matching entries are permitted, they will be tried
+ * in sequence until a probe function returns non NULL.
+ *
+ * IDCODE_CONT_LEN may be redefined if a device needs to declare a
+ * larger "shift" value.  IDCODE_PART_LEN generally shouldn't be
+ * changed.  This is the max number of bytes probe functions may
+ * examine when looking up part-specific identification info.
+ *
+ * Probe functions will be given the idcode buffer starting at their
+ * manu id byte (the "idcode" in the table below).  In other words,
+ * all of the continuation bytes will be skipped (the "shift" below).
+ */
+#define IDCODE_CONT_LEN 0
+#define IDCODE_PART_LEN 5
+static const struct {
+	const u8 shift;
+	const u8 idcode;
+	struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
+} flashes[] = {
+	/* Keep it sorted by define name */
+#ifdef CONFIG_SPI_FRAM_RAMTRON
+	{ 6, 0xc2, spi_fram_probe_ramtron, },
+# undef IDCODE_CONT_LEN
+# define IDCODE_CONT_LEN 6
+#endif
+#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
+	{ 0, 0xff, spi_fram_probe_ramtron, },
+#endif
+};
+#define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
+
+struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+		unsigned int max_hz, unsigned int spi_mode)
+{
+	struct spi_slave *spi;
+	struct spi_flash *flash = NULL;
+	int ret, i, shift;
+	u8 idcode[IDCODE_LEN], *idp;
+
+	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+	if (!spi) {
+		printf("SF: Failed to set up slave\n");
+		return NULL;
+	}
+
+	ret = spi_claim_bus(spi);
+	if (ret) {
+		debug("SF: Failed to claim SPI bus: %d\n", ret);
+		goto err_claim_bus;
+	}
+
+	/* Read the ID codes */
+	ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
+	if (ret)
+		goto err_read_id;
+
+#ifdef DEBUG
+	printf("SF: Got idcodes\n");
+	print_buffer(0, idcode, 1, sizeof(idcode), 0);
+#endif
+
+	/* count the number of continuation bytes */
+	for (shift = 0, idp = idcode;
+	     shift < IDCODE_CONT_LEN && *idp == 0x7f;
+	     ++shift, ++idp)
+		continue;
+
+	/* search the table for matches in shift and id */
+	for (i = 0; i < ARRAY_SIZE(flashes); ++i)
+		if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
+			/* we have a match, call probe */
+			flash = flashes[i].probe(spi, idp);
+			if (flash)
+				break;
+		}
+
+	if (!flash) {
+		printf("SF: Unsupported manufacturer %02x\n", *idp);
+		goto err_manufacturer_probe;
+	}
+
+	printf("SF: Detected %s with page size ", flash->name);
+	print_size(flash->sector_size, ", total ");
+	print_size(flash->size, "");
+	if (flash->memory_map)
+		printf(", mapped at %p", flash->memory_map);
+	puts("\n");
+
+	spi_release_bus(spi);
+
+	return flash;
+
+err_manufacturer_probe:
+err_read_id:
+	spi_release_bus(spi);
+err_claim_bus:
+	spi_free_slave(spi);
+	return NULL;
+}
+
+void spi_flash_free(struct spi_flash *flash)
+{
+	spi_free_slave(flash->spi);
+	free(flash);
+}
diff --git a/drivers/mtd/spi/spi_flash_probe.c b/drivers/mtd/spi/spi_flash_probe.c
index cc30ad1..c432b04 100644
--- a/drivers/mtd/spi/spi_flash_probe.c
+++ b/drivers/mtd/spi/spi_flash_probe.c
@@ -144,10 +144,6 @@ static const struct spi_flash_params spi_flash_params_table[] = {
 	 * (W25Q64DW, W25Q64FV_QPI)
 	 * (W25Q128FW, W25Q128FV_QPI)
 	 */
-	/*
-	 * TODO:
-	 * RAMTRON
-	 */
 };
 
 struct spi_flash *spi_flash_validate_ids(struct spi_slave *spi, u8 *idcode)
diff --git a/drivers/mtd/spi/spi_flash_probe_legacy.c b/drivers/mtd/spi/spi_flash_probe_legacy.c
deleted file mode 100644
index 32ec578..0000000
--- a/drivers/mtd/spi/spi_flash_probe_legacy.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * SPI flash probing
- *
- * Copyright (C) 2008 Atmel Corporation
- * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
- * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <fdtdec.h>
-#include <malloc.h>
-#include <spi.h>
-#include <spi_flash.h>
-
-#include "spi_flash_internal.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#ifdef CONFIG_SPI_FLASH_BAR
-int spi_flash_bank_config(struct spi_flash *flash, u8 idcode0)
-{
-	u8 cmd;
-	u8 curr_bank = 0;
-
-	/* discover bank cmds */
-	switch (idcode0) {
-	case SPI_FLASH_SPANSION_IDCODE0:
-		flash->bank_read_cmd = CMD_BANKADDR_BRRD;
-		flash->bank_write_cmd = CMD_BANKADDR_BRWR;
-		break;
-	case SPI_FLASH_STMICRO_IDCODE0:
-	case SPI_FLASH_WINBOND_IDCODE0:
-		flash->bank_read_cmd = CMD_EXTNADDR_RDEAR;
-		flash->bank_write_cmd = CMD_EXTNADDR_WREAR;
-		break;
-	default:
-		printf("SF: Unsupported bank commands %02x\n", idcode0);
-		return -1;
-	}
-
-	/* read the bank reg - on which bank the flash is in currently */
-	cmd = flash->bank_read_cmd;
-	if (flash->size > SPI_FLASH_16MB_BOUN) {
-		if (spi_flash_read_common(flash, &cmd, 1, &curr_bank, 1)) {
-			debug("SF: fail to read bank addr register\n");
-			return -1;
-		}
-		flash->bank_curr = curr_bank;
-	} else {
-		flash->bank_curr = curr_bank;
-	}
-
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_OF_CONTROL
-int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
-{
-	fdt_addr_t addr;
-	fdt_size_t size;
-	int node;
-
-	/* If there is no node, do nothing */
-	node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
-	if (node < 0)
-		return 0;
-
-	addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
-	if (addr == FDT_ADDR_T_NONE) {
-		debug("%s: Cannot decode address\n", __func__);
-		return 0;
-	}
-
-	if (flash->size != size) {
-		debug("%s: Memory map must cover entire device\n", __func__);
-		return -1;
-	}
-	flash->memory_map = (void *)addr;
-
-	return 0;
-}
-#endif /* CONFIG_OF_CONTROL */
-
-/*
- * The following table holds all device probe functions
- *
- * shift:  number of continuation bytes before the ID
- * idcode: the expected IDCODE or 0xff for non JEDEC devices
- * probe:  the function to call
- *
- * Non JEDEC devices should be ordered in the table such that
- * the probe functions with best detection algorithms come first.
- *
- * Several matching entries are permitted, they will be tried
- * in sequence until a probe function returns non NULL.
- *
- * IDCODE_CONT_LEN may be redefined if a device needs to declare a
- * larger "shift" value.  IDCODE_PART_LEN generally shouldn't be
- * changed.  This is the max number of bytes probe functions may
- * examine when looking up part-specific identification info.
- *
- * Probe functions will be given the idcode buffer starting at their
- * manu id byte (the "idcode" in the table below).  In other words,
- * all of the continuation bytes will be skipped (the "shift" below).
- */
-#define IDCODE_CONT_LEN 0
-#define IDCODE_PART_LEN 5
-static const struct {
-	const u8 shift;
-	const u8 idcode;
-	struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
-} flashes[] = {
-	/* Keep it sorted by define name */
-#ifdef CONFIG_SPI_FLASH_ATMEL
-	{ 0, 0x1f, spi_flash_probe_atmel, },
-#endif
-#ifdef CONFIG_SPI_FLASH_EON
-	{ 0, 0x1c, spi_flash_probe_eon, },
-#endif
-#ifdef CONFIG_SPI_FLASH_GIGADEVICE
-	{ 0, 0xc8, spi_flash_probe_gigadevice, },
-#endif
-#ifdef CONFIG_SPI_FLASH_MACRONIX
-	{ 0, 0xc2, spi_flash_probe_macronix, },
-#endif
-#ifdef CONFIG_SPI_FLASH_SPANSION
-	{ 0, 0x01, spi_flash_probe_spansion, },
-#endif
-#ifdef CONFIG_SPI_FLASH_SST
-	{ 0, 0xbf, spi_flash_probe_sst, },
-#endif
-#ifdef CONFIG_SPI_FLASH_STMICRO
-	{ 0, 0x20, spi_flash_probe_stmicro, },
-#endif
-#ifdef CONFIG_SPI_FLASH_WINBOND
-	{ 0, 0xef, spi_flash_probe_winbond, },
-#endif
-#ifdef CONFIG_SPI_FRAM_RAMTRON
-	{ 6, 0xc2, spi_fram_probe_ramtron, },
-# undef IDCODE_CONT_LEN
-# define IDCODE_CONT_LEN 6
-#endif
-	/* Keep it sorted by best detection */
-#ifdef CONFIG_SPI_FLASH_STMICRO
-	{ 0, 0xff, spi_flash_probe_stmicro, },
-#endif
-#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
-	{ 0, 0xff, spi_fram_probe_ramtron, },
-#endif
-};
-#define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
-
-struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
-		unsigned int max_hz, unsigned int spi_mode)
-{
-	struct spi_slave *spi;
-	struct spi_flash *flash = NULL;
-	int ret, i, shift;
-	u8 idcode[IDCODE_LEN], *idp;
-
-	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
-	if (!spi) {
-		printf("SF: Failed to set up slave\n");
-		return NULL;
-	}
-
-	ret = spi_claim_bus(spi);
-	if (ret) {
-		debug("SF: Failed to claim SPI bus: %d\n", ret);
-		goto err_claim_bus;
-	}
-
-	/* Read the ID codes */
-	ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
-	if (ret)
-		goto err_read_id;
-
-#ifdef DEBUG
-	printf("SF: Got idcodes\n");
-	print_buffer(0, idcode, 1, sizeof(idcode), 0);
-#endif
-
-	/* count the number of continuation bytes */
-	for (shift = 0, idp = idcode;
-	     shift < IDCODE_CONT_LEN && *idp == 0x7f;
-	     ++shift, ++idp)
-		continue;
-
-	/* search the table for matches in shift and id */
-	for (i = 0; i < ARRAY_SIZE(flashes); ++i)
-		if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
-			/* we have a match, call probe */
-			flash = flashes[i].probe(spi, idp);
-			if (flash)
-				break;
-		}
-
-	if (!flash) {
-		printf("SF: Unsupported manufacturer %02x\n", *idp);
-		goto err_manufacturer_probe;
-	}
-
-#ifdef CONFIG_SPI_FLASH_BAR
-	/* Configure the BAR - disover bank cmds and read current bank  */
-	ret = spi_flash_bank_config(flash, *idp);
-	if (ret < 0)
-		goto err_manufacturer_probe;
-#endif
-
-#ifdef CONFIG_OF_CONTROL
-	if (spi_flash_decode_fdt(gd->fdt_blob, flash)) {
-		debug("SF: FDT decode error\n");
-		goto err_manufacturer_probe;
-	}
-#endif
-#ifndef CONFIG_SPL_BUILD
-	printf("SF: Detected %s with page size ", flash->name);
-	print_size(flash->sector_size, ", total ");
-	print_size(flash->size, "");
-	if (flash->memory_map)
-		printf(", mapped at %p", flash->memory_map);
-	puts("\n");
-#endif
-#ifndef CONFIG_SPI_FLASH_BAR
-	if (flash->size > SPI_FLASH_16MB_BOUN) {
-		puts("SF: Warning - Only lower 16MiB accessible,");
-		puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
-	}
-#endif
-
-	spi_release_bus(spi);
-
-	return flash;
-
-err_manufacturer_probe:
-err_read_id:
-	spi_release_bus(spi);
-err_claim_bus:
-	spi_free_slave(spi);
-	return NULL;
-}
-
-void *spi_flash_do_alloc(int offset, int size, struct spi_slave *spi,
-			 const char *name)
-{
-	struct spi_flash *flash;
-	void *ptr;
-
-	ptr = malloc(size);
-	if (!ptr) {
-		debug("SF: Failed to allocate memory\n");
-		return NULL;
-	}
-	memset(ptr, '\0', size);
-	flash = (struct spi_flash *)(ptr + offset);
-
-	/* Set up some basic fields - caller will sort out sizes */
-	flash->spi = spi;
-	flash->name = name;
-	flash->poll_cmd = CMD_READ_STATUS;
-
-	flash->read = spi_flash_cmd_read_fast;
-	flash->write = spi_flash_cmd_write_multi;
-	flash->erase = spi_flash_cmd_erase;
-
-	return flash;
-}
-
-void spi_flash_free(struct spi_flash *flash)
-{
-	spi_free_slave(flash->spi);
-	free(flash);
-}
diff --git a/include/configs/top9000.h b/include/configs/top9000.h
index 65dabde..a6d6928 100644
--- a/include/configs/top9000.h
+++ b/include/configs/top9000.h
@@ -120,7 +120,6 @@
 #define CONFIG_ATMEL_SPI0		/* SPI used for FRAM is SPI0 */
 #define FRAM_SPI_BUS		0
 #define FRAM_CS_NUM		0
-#define CONFIG_SPI_FLASH		/* RAMTRON FRAM on SPI bus */
 #define CONFIG_SPI_FRAM_RAMTRON
 #define CONFIG_SF_DEFAULT_SPEED	1000000	/* be conservative here... */
 #define CONFIG_SF_DEFAULT_MODE	SPI_MODE_0
-- 
1.8.3




More information about the U-Boot mailing list