All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/6] arm/davinci: fix DDR2/mDDR memory controller initialization for Omap L138
@ 2012-06-26 10:33 Mikhail Kshevetskiy
  2012-06-26 10:33 ` [U-Boot] [PATCH 2/6] arm/davinci/da850: add uart0 pinmux Mikhail Kshevetskiy
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Mikhail Kshevetskiy @ 2012-06-26 10:33 UTC (permalink / raw)
  To: u-boot

follow section 15.2.13.1 (Initializing Following Device Power Up or Reset) of
OMAP-L138 DSP+ARM Processor Technical Reference Manual

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@gmail.com>
---
 arch/arm/cpu/arm926ejs/davinci/da850_lowlevel.c |   26 +++++++++++++++++------
 arch/arm/include/asm/arch-davinci/hardware.h    |    1 +
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/davinci/da850_lowlevel.c b/arch/arm/cpu/arm926ejs/davinci/da850_lowlevel.c
index df7d6a2..ff2e2e3 100644
--- a/arch/arm/cpu/arm926ejs/davinci/da850_lowlevel.c
+++ b/arch/arm/cpu/arm926ejs/davinci/da850_lowlevel.c
@@ -190,13 +190,21 @@ int da850_ddr_setup(void)
 
 		setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK);
 		setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN);
-
-		setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_IOPWRDWN);
 	}
-
+	setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_IOPWRDWN);
 	writel(CONFIG_SYS_DA850_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr);
-	clrbits_le32(&davinci_syscfg1_regs->ddr_slew,
-		(1 << DDR_SLEW_CMOSEN_BIT));
+
+	if (CONFIG_SYS_DA850_DDR2_SDBCR & (1 << DV_DDR_SDCR_DDR2EN_SHIFT)) {
+		/* DDR2 */
+		clrbits_le32(&davinci_syscfg1_regs->ddr_slew,
+			(1 << DDR_SLEW_DDR_PDENA_BIT) |
+			(1 << DDR_SLEW_CMOSEN_BIT));
+	} else {
+		/* MOBILE DDR */
+		setbits_le32(&davinci_syscfg1_regs->ddr_slew,
+			(1 << DDR_SLEW_DDR_PDENA_BIT) |
+			(1 << DDR_SLEW_CMOSEN_BIT));
+	}
 
 	/*
 	 * SDRAM Configuration Register (SDCR):
@@ -216,7 +224,11 @@ int da850_ddr_setup(void)
 	writel(tmp, &dv_ddr2_regs_ctrl->sdbcr);
 
 	/* write memory configuration and timing */
-	writel(CONFIG_SYS_DA850_DDR2_SDBCR2, &dv_ddr2_regs_ctrl->sdbcr2);
+	if (!(CONFIG_SYS_DA850_DDR2_SDBCR & (1 << DV_DDR_SDCR_DDR2EN_SHIFT))) {
+		/* MOBILE DDR only*/
+		writel(CONFIG_SYS_DA850_DDR2_SDBCR2,
+			&dv_ddr2_regs_ctrl->sdbcr2);
+	}
 	writel(CONFIG_SYS_DA850_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr);
 	writel(CONFIG_SYS_DA850_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2);
 
@@ -240,7 +252,7 @@ int da850_ddr_setup(void)
 
 	/* disable self refresh */
 	clrbits_le32(&dv_ddr2_regs_ctrl->sdrcr,
-		DV_DDR_SDRCR_LPMODEN | DV_DDR_SDRCR_LPMODEN);
+		DV_DDR_SDRCR_LPMODEN | DV_DDR_SDRCR_MCLKSTOPEN);
 	writel(CONFIG_SYS_DA850_DDR2_PBBPR, &dv_ddr2_regs_ctrl->pbbpr);
 
 	return 0;
diff --git a/arch/arm/include/asm/arch-davinci/hardware.h b/arch/arm/include/asm/arch-davinci/hardware.h
index b145c6e..56e5743 100644
--- a/arch/arm/include/asm/arch-davinci/hardware.h
+++ b/arch/arm/include/asm/arch-davinci/hardware.h
@@ -505,6 +505,7 @@ struct davinci_syscfg1_regs {
 	((struct davinci_syscfg1_regs *)DAVINCI_SYSCFG1_BASE)
 
 #define DDR_SLEW_CMOSEN_BIT	4
+#define DDR_SLEW_DDR_PDENA_BIT	5
 
 #define VTP_POWERDWN		(1 << 6)
 #define VTP_LOCK		(1 << 7)
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH 2/6] arm/davinci/da850: add uart0 pinmux
  2012-06-26 10:33 [U-Boot] [PATCH 1/6] arm/davinci: fix DDR2/mDDR memory controller initialization for Omap L138 Mikhail Kshevetskiy
@ 2012-06-26 10:33 ` Mikhail Kshevetskiy
  2012-06-26 10:33 ` [U-Boot] [PATCH 3/6] serial/ns16550: ns16550 has a different register layout on SOC_DA8XX Mikhail Kshevetskiy
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Mikhail Kshevetskiy @ 2012-06-26 10:33 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@gmail.com>
---
 arch/arm/cpu/arm926ejs/davinci/da850_pinmux.c   |    5 +++++
 arch/arm/include/asm/arch-davinci/hardware.h    |    1 +
 arch/arm/include/asm/arch-davinci/pinmux_defs.h |    1 +
 3 files changed, 7 insertions(+)

diff --git a/arch/arm/cpu/arm926ejs/davinci/da850_pinmux.c b/arch/arm/cpu/arm926ejs/davinci/da850_pinmux.c
index fa07fb5..dbae5fa 100644
--- a/arch/arm/cpu/arm926ejs/davinci/da850_pinmux.c
+++ b/arch/arm/cpu/arm926ejs/davinci/da850_pinmux.c
@@ -35,6 +35,11 @@ const struct pinmux_config spi1_pins_scs0[] = {
 };
 
 /* UART pin muxer settings */
+const struct pinmux_config uart0_pins_txrx[] = {
+	{ pinmux(3), 2, 4 }, /* UART0_RXD */
+	{ pinmux(3), 2, 5 }, /* UART0_TXD */
+};
+
 const struct pinmux_config uart1_pins_txrx[] = {
 	{ pinmux(4), 2, 6 }, /* UART1_RXD */
 	{ pinmux(4), 2, 7 }, /* UART1_TXD */
diff --git a/arch/arm/include/asm/arch-davinci/hardware.h b/arch/arm/include/asm/arch-davinci/hardware.h
index 56e5743..76aca24 100644
--- a/arch/arm/include/asm/arch-davinci/hardware.h
+++ b/arch/arm/include/asm/arch-davinci/hardware.h
@@ -447,6 +447,7 @@ struct davinci_pllc_regs {
 /* Clock IDs */
 enum davinci_clk_ids {
 	DAVINCI_SPI0_CLKID = 2,
+	DAVINCI_UART0_CLKID = 2,
 	DAVINCI_UART2_CLKID = 2,
 	DAVINCI_MMC_CLKID = 2,
 	DAVINCI_MDIO_CLKID = 4,
diff --git a/arch/arm/include/asm/arch-davinci/pinmux_defs.h b/arch/arm/include/asm/arch-davinci/pinmux_defs.h
index 07aceaa..eddb3f7 100644
--- a/arch/arm/include/asm/arch-davinci/pinmux_defs.h
+++ b/arch/arm/include/asm/arch-davinci/pinmux_defs.h
@@ -28,6 +28,7 @@ extern const struct pinmux_config spi1_pins_base[3];
 extern const struct pinmux_config spi1_pins_scs0[1];
 
 /* UART pin muxer settings */
+extern const struct pinmux_config uart0_pins_txrx[2];
 extern const struct pinmux_config uart1_pins_txrx[2];
 extern const struct pinmux_config uart2_pins_txrx[2];
 extern const struct pinmux_config uart2_pins_rtscts[2];
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH 3/6] serial/ns16550: ns16550 has a different register layout on SOC_DA8XX
  2012-06-26 10:33 [U-Boot] [PATCH 1/6] arm/davinci: fix DDR2/mDDR memory controller initialization for Omap L138 Mikhail Kshevetskiy
  2012-06-26 10:33 ` [U-Boot] [PATCH 2/6] arm/davinci/da850: add uart0 pinmux Mikhail Kshevetskiy
@ 2012-06-26 10:33 ` Mikhail Kshevetskiy
  2012-06-26 10:33 ` [U-Boot] [PATCH 4/6] mtd/spi/spi_flash: support CMD_READ_ID=0x90 case Mikhail Kshevetskiy
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Mikhail Kshevetskiy @ 2012-06-26 10:33 UTC (permalink / raw)
  To: u-boot

also fix NS16550_init() as we need 16x divider

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@gmail.com>
---
 drivers/serial/ns16550.c |    2 +-
 include/ns16550.h        |    9 +++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 0c23955..facadd2 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -52,7 +52,7 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
 	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
 	serial_out(UART_LCRVAL, &com_port->lcr);
 #if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \
-					defined(CONFIG_AM33XX)
+	defined(CONFIG_AM33XX) || defined(CONFIG_SOC_DA8XX)
 
 #if defined(CONFIG_APTIX)
 	/* /13 mode so Aptix 6MHz can hit 115200 */
diff --git a/include/ns16550.h b/include/ns16550.h
index e9d2eda..51cb5b4 100644
--- a/include/ns16550.h
+++ b/include/ns16550.h
@@ -46,6 +46,14 @@ struct NS16550 {
 	UART_REG(lsr);		/* 5 */
 	UART_REG(msr);		/* 6 */
 	UART_REG(spr);		/* 7 */
+#ifdef CONFIG_SOC_DA8XX
+	UART_REG(reg8);		/* 8 */
+	UART_REG(reg9);		/* 9 */
+	UART_REG(revid1);	/* A */
+	UART_REG(revid2);	/* B */
+	UART_REG(pwr_mgmt);	/* C */
+	UART_REG(mdr1);		/* D */
+#else
 	UART_REG(mdr1);		/* 8 */
 	UART_REG(reg9);		/* 9 */
 	UART_REG(regA);		/* A */
@@ -58,6 +66,7 @@ struct NS16550 {
 	UART_REG(ssr);		/* 11*/
 	UART_REG(reg12);	/* 12*/
 	UART_REG(osc_12m_sel);	/* 13*/
+#endif
 };
 
 #define thr rbr
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH 4/6] mtd/spi/spi_flash: support CMD_READ_ID=0x90 case
  2012-06-26 10:33 [U-Boot] [PATCH 1/6] arm/davinci: fix DDR2/mDDR memory controller initialization for Omap L138 Mikhail Kshevetskiy
  2012-06-26 10:33 ` [U-Boot] [PATCH 2/6] arm/davinci/da850: add uart0 pinmux Mikhail Kshevetskiy
  2012-06-26 10:33 ` [U-Boot] [PATCH 3/6] serial/ns16550: ns16550 has a different register layout on SOC_DA8XX Mikhail Kshevetskiy
@ 2012-06-26 10:33 ` Mikhail Kshevetskiy
  2012-06-26 10:33 ` [U-Boot] [PATCH 5/6] mtd/spi: add sst25l driver Mikhail Kshevetskiy
  2012-06-26 10:33 ` [U-Boot] [PATCH 6/6] MMC: u-boot-spl may be compiled without partition support Mikhail Kshevetskiy
  4 siblings, 0 replies; 7+ messages in thread
From: Mikhail Kshevetskiy @ 2012-06-26 10:33 UTC (permalink / raw)
  To: u-boot

current code does not support spi flashes that have 0x90 read_id command,
so fix this

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@gmail.com>
---
 drivers/mtd/spi/spi_flash.c          |   66 +++++++++++++++++++++++-----------
 drivers/mtd/spi/spi_flash_internal.h |    1 +
 2 files changed, 47 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index f689cc4..530b7b3 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -306,13 +306,44 @@ static const struct {
 };
 #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
 
+struct spi_flash *spi_analize_flash_probe(struct spi_slave *spi,
+		u8 *idcode, size_t idcode_len, u8 *id)
+{
+	struct spi_flash *flash = NULL;
+	int i, shift;
+	u8 *idp;
+
+#ifdef DEBUG
+	printf("SF: Got idcodes\n");
+	print_buffer(0, idcode, 1, idcode_len, 0);
+#endif
+
+	/* count the number of continuation bytes */
+	for (shift = 0, idp = idcode;
+	     shift < idcode_len && *idp == 0x7f;
+	     ++shift, ++idp)
+		continue;
+
+	*id = *idp;
+	/* 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;
+		}
+
+	return flash;
+}
+
 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;
+	u8 cmd[4], idcode[IDCODE_LEN], id;
+	int ret;
 
 	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
 	if (!spi) {
@@ -331,28 +362,23 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
 	if (ret)
 		goto err_read_id;
 
-#ifdef DEBUG
-	printf("SF: Got idcodes\n");
-	print_buffer(0, idcode, 1, sizeof(idcode), 0);
-#endif
+	flash = spi_analize_flash_probe(spi, idcode, sizeof(idcode), &id);
+	if (id == 0xff) {
+		/* try CMD_READ_ID_NEW command */
+		cmd[0] = CMD_READ_ID_NEW;
+		spi_flash_addr(0x000000, cmd);
 
-	/* count the number of continuation bytes */
-	for (shift = 0, idp = idcode;
-	     shift < IDCODE_CONT_LEN && *idp == 0x7f;
-	     ++shift, ++idp)
-		continue;
+		ret = spi_flash_cmd_read(spi, cmd, sizeof(cmd),
+					idcode, sizeof(idcode));
+		if (ret)
+			goto err_read_id;
 
-	/* 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;
-		}
+		flash = spi_analize_flash_probe(spi,
+					idcode, sizeof(idcode), &id);
+	}
 
 	if (!flash) {
-		printf("SF: Unsupported manufacturer %02x\n", *idp);
+		printf("SF: Unsupported manufacturer %02x\n", id);
 		goto err_manufacturer_probe;
 	}
 
diff --git a/drivers/mtd/spi/spi_flash_internal.h b/drivers/mtd/spi/spi_flash_internal.h
index 91e036a..b8bd5d5 100644
--- a/drivers/mtd/spi/spi_flash_internal.h
+++ b/drivers/mtd/spi/spi_flash_internal.h
@@ -14,6 +14,7 @@
 
 /* Common commands */
 #define CMD_READ_ID			0x9f
+#define CMD_READ_ID_NEW			0x90
 
 #define CMD_READ_ARRAY_SLOW		0x03
 #define CMD_READ_ARRAY_FAST		0x0b
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH 5/6] mtd/spi: add sst25l driver
  2012-06-26 10:33 [U-Boot] [PATCH 1/6] arm/davinci: fix DDR2/mDDR memory controller initialization for Omap L138 Mikhail Kshevetskiy
                   ` (2 preceding siblings ...)
  2012-06-26 10:33 ` [U-Boot] [PATCH 4/6] mtd/spi/spi_flash: support CMD_READ_ID=0x90 case Mikhail Kshevetskiy
@ 2012-06-26 10:33 ` Mikhail Kshevetskiy
  2012-06-27 17:51   ` Tom Rini
  2012-06-26 10:33 ` [U-Boot] [PATCH 6/6] MMC: u-boot-spl may be compiled without partition support Mikhail Kshevetskiy
  4 siblings, 1 reply; 7+ messages in thread
From: Mikhail Kshevetskiy @ 2012-06-26 10:33 UTC (permalink / raw)
  To: u-boot

current SST driver does not support well this types of flash, so use
linux-3.3 code as a base.

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@gmail.com>
---
 drivers/mtd/spi/Makefile             |    3 +-
 drivers/mtd/spi/spi_flash.c          |    3 +
 drivers/mtd/spi/spi_flash_internal.h |    1 +
 drivers/mtd/spi/sst25l.c             |  372 ++++++++++++++++++++++++++++++++++
 4 files changed, 378 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/spi/sst25l.c

diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index 90f8392..9285bf7 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -34,7 +34,8 @@ COBJS-$(CONFIG_SPI_FLASH_ATMEL)	+= atmel.o
 COBJS-$(CONFIG_SPI_FLASH_EON)	+= eon.o
 COBJS-$(CONFIG_SPI_FLASH_MACRONIX)	+= macronix.o
 COBJS-$(CONFIG_SPI_FLASH_SPANSION)	+= spansion.o
-COBJS-$(CONFIG_SPI_FLASH_SST)	+= sst.o
+COBJS-$(CONFIG_SPI_FLASH_SST)		+= sst.o
+COBJS-$(CONFIG_SPI_FLASH_SST25L)	+= sst25l.o
 COBJS-$(CONFIG_SPI_FLASH_STMICRO)	+= stmicro.o
 COBJS-$(CONFIG_SPI_FLASH_WINBOND)	+= winbond.o
 COBJS-$(CONFIG_SPI_FRAM_RAMTRON)	+= ramtron.o
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 530b7b3..d2da542 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -285,6 +285,9 @@ static const struct {
 #ifdef CONFIG_SPI_FLASH_SST
 	{ 0, 0xbf, spi_flash_probe_sst, },
 #endif
+#ifdef CONFIG_SPI_FLASH_SST25L
+	{ 0, 0xbf, spi_flash_probe_sst25l, },
+#endif
 #ifdef CONFIG_SPI_FLASH_STMICRO
 	{ 0, 0x20, spi_flash_probe_stmicro, },
 #endif
diff --git a/drivers/mtd/spi/spi_flash_internal.h b/drivers/mtd/spi/spi_flash_internal.h
index b8bd5d5..89d9036 100644
--- a/drivers/mtd/spi/spi_flash_internal.h
+++ b/drivers/mtd/spi/spi_flash_internal.h
@@ -98,6 +98,7 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode);
 struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode);
 struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode);
 struct spi_flash *spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode);
+struct spi_flash *spi_flash_probe_sst25l(struct spi_slave *spi, u8 *idcode);
 struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode);
 struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode);
 struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode);
diff --git a/drivers/mtd/spi/sst25l.c b/drivers/mtd/spi/sst25l.c
new file mode 100644
index 0000000..9d7be0d
--- /dev/null
+++ b/drivers/mtd/spi/sst25l.c
@@ -0,0 +1,372 @@
+/*
+ * Driver for SST25L SPI Flash chips
+ *
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ * Copyright 2008, Network Appliance Inc.
+ * Jason McMullan <mcmullan@netapp.com>
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew at freescale.com)
+ * Copyright (c) 2008-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi_flash.h>
+#include <watchdog.h>
+
+#include "spi_flash_internal.h"
+
+#define SST25L_CMD_WRSR		0x01	/* Write status register */
+#define SST25L_CMD_WRDI		0x04	/* Write disable */
+#define SST25L_CMD_RDSR		0x05	/* Read status register */
+#define SST25L_CMD_WREN		0x06	/* Write enable */
+#define SST25L_CMD_READ		0x03	/* High speed read */
+
+#define SST25L_CMD_EWSR		0x50	/* Enable write status register */
+#define SST25L_CMD_SECTOR_ERASE	0x20	/* Erase sector */
+#define SST25L_CMD_READ_ID	0x90	/* Read device ID */
+#define SST25L_CMD_AAI_PROGRAM	0xaf	/* Auto address increment */
+
+#define SST25L_STATUS_BUSY	(1 << 0)	/* Chip is busy */
+#define SST25L_STATUS_WREN	(1 << 1)	/* Write enabled */
+#define SST25L_STATUS_BP0	(1 << 2)	/* Block protection 0 */
+#define SST25L_STATUS_BP1	(1 << 3)	/* Block protection 1 */
+
+struct flash_info {
+	const char	*name;
+	u16		device_id;
+	u32		page_size;
+	u32		nr_pages;
+	u32		erase_size;
+};
+
+struct sst25l_spi_flash {
+	struct spi_flash	flash;
+	const struct flash_info	*flash_info;
+};
+
+#define to_sst25l_spi_flash(x) container_of(x, struct sst25l_spi_flash, flash)
+
+static struct flash_info sst25l_flash_info[] = {
+	{"sst25vf010a", 0xbf49, 256, 512,  4096},
+	{"sst25lf020a", 0xbf43, 256, 1024, 4096},
+	{"sst25lf040a", 0xbf44, 256, 2048, 4096},
+};
+
+static inline int spi_write_sync(struct spi_slave *spi,
+				const u8 *data, size_t len)
+{
+	return spi_xfer(spi, 8 * len, data,
+			NULL, SPI_XFER_BEGIN | SPI_XFER_END);
+}
+
+static int sst25l_status(struct spi_flash *flash, int *status)
+{
+	unsigned char	cmd_resp[2];
+	int		err;
+
+	cmd_resp[0] = SST25L_CMD_RDSR;
+	cmd_resp[1] = 0xff;
+
+	err = spi_xfer(flash->spi, 8 * sizeof(cmd_resp), cmd_resp, cmd_resp,
+			SPI_XFER_BEGIN | SPI_XFER_END);
+	if (err < 0)
+		return err;
+
+	*status = cmd_resp[1];
+	return 0;
+}
+
+static int sst25l_write_enable(struct spi_flash *flash, int enable)
+{
+	unsigned char	command[2];
+	int		status, err;
+
+	command[0] = enable ? SST25L_CMD_WREN : SST25L_CMD_WRDI;
+	err = spi_write_sync(flash->spi, command, 1);
+	if (err)
+		return err;
+
+	command[0] = SST25L_CMD_EWSR;
+	err = spi_write_sync(flash->spi, command, 1);
+	if (err)
+		return err;
+
+	command[0] = SST25L_CMD_WRSR;
+	command[1] = enable ? 0 : SST25L_STATUS_BP0 | SST25L_STATUS_BP1;
+	err = spi_write_sync(flash->spi, command, 2);
+	if (err)
+		return err;
+
+	if (enable) {
+		err = sst25l_status(flash, &status);
+		if (err)
+			return err;
+		if (!(status & SST25L_STATUS_WREN))
+			return -1;
+	}
+
+	return 0;
+}
+
+static int sst25l_wait_till_ready(struct spi_flash *flash,
+					unsigned long timeout)
+{
+	unsigned long	timebase;
+	int		status, err;
+
+	timebase = get_timer(0);
+	do {
+		WATCHDOG_RESET();
+
+		err = sst25l_status(flash, &status);
+		if (err)
+			return err;
+		if (!(status & SST25L_STATUS_BUSY))
+			return 0;
+
+	} while (get_timer(timebase) < timeout);
+
+	return -1;
+}
+
+static int sst25l_erase_sector(struct spi_flash *flash, u32 offset)
+{
+	unsigned char		command[4];
+	int			err;
+
+	err = sst25l_write_enable(flash, 1);
+	if (err)
+		return err;
+
+	command[0] = SST25L_CMD_SECTOR_ERASE;
+	command[1] = offset >> 16;
+	command[2] = offset >> 8;
+	command[3] = offset;
+	err = spi_write_sync(flash->spi, command, 4);
+	if (err)
+		return err;
+
+	err = sst25l_wait_till_ready(flash, SPI_FLASH_SECTOR_ERASE_TIMEOUT);
+	if (err)
+		return err;
+
+	return sst25l_write_enable(flash, 0);
+}
+
+static int sst25l_erase(struct spi_flash *flash, u32 offset, size_t len)
+{
+	struct sst25l_spi_flash	*sst25l = to_sst25l_spi_flash(flash);
+	const struct flash_info	*flash_info = sst25l->flash_info;
+	u32			end = offset + len;
+	int			err;
+
+	/* Sanity checks */
+	if (len % flash_info->erase_size)
+		return -1;
+
+	if (offset % flash_info->erase_size)
+		return -1;
+
+	err = sst25l_wait_till_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+	if (err)
+		return err;
+
+	while (offset < end) {
+		err = sst25l_erase_sector(flash, offset);
+		if (err)
+			return err;
+		offset += flash_info->erase_size;
+	}
+	return 0;
+}
+
+static int sst25l_read(struct spi_flash *flash,
+			u32 offset, size_t len, void *data)
+{
+	unsigned char	command[4];
+	int		ret;
+
+	command[0] = SST25L_CMD_READ;
+	command[1] = offset >> 16;
+	command[2] = offset >> 8;
+	command[3] = offset;
+
+	/* Wait for previous write/erase to complete */
+	ret = sst25l_wait_till_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+	if (ret)
+		return ret;
+
+	ret = spi_xfer(flash->spi, 8 * sizeof(command), command,
+			NULL, SPI_XFER_BEGIN);
+	if (ret)
+		return ret;
+
+	ret = spi_xfer(flash->spi, 8 * len, NULL, data, SPI_XFER_END);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int sst25l_write(struct spi_flash *flash,
+			u32 offset, size_t len, const char *buf)
+{
+	struct sst25l_spi_flash	*sst25l = to_sst25l_spi_flash(flash);
+	const struct flash_info	*flash_info = sst25l->flash_info;
+	int			i, j, ret, bytes, copied = 0;
+	unsigned char		command[5];
+
+	if (offset % flash_info->page_size)
+		return -1;
+
+	ret = sst25l_write_enable(flash, 1);
+	if (ret)
+		goto out;
+
+	for (i = 0; i < len; i += flash_info->page_size) {
+		ret = sst25l_wait_till_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+		if (ret)
+			goto out;
+
+		/* Write the first byte of the page */
+		command[0] = SST25L_CMD_AAI_PROGRAM;
+		command[1] = (offset + i) >> 16;
+		command[2] = (offset + i) >> 8;
+		command[3] = (offset + i);
+		command[4] = buf[i];
+		ret = spi_write_sync(flash->spi, command, 5);
+		if (ret < 0)
+			goto out;
+		copied++;
+
+		/*
+		 * Write the remaining bytes using auto address
+		 * increment mode
+		 */
+		bytes = min(flash_info->page_size, len - i);
+		for (j = 1; j < bytes; j++, copied++) {
+			ret = sst25l_wait_till_ready(flash,
+						SPI_FLASH_PROG_TIMEOUT);
+			if (ret)
+				goto out;
+
+			command[1] = buf[i + j];
+			ret = spi_write_sync(flash->spi, command, 2);
+			if (ret)
+				goto out;
+		}
+	}
+
+out:
+	ret = sst25l_write_enable(flash, 0);
+	if (ret)
+		return ret;
+
+	return (copied == len) ? 0 : -1;
+}
+
+static int sst25l_flash_erase(struct spi_flash *flash, u32 offset, size_t len)
+{
+	int ret;
+
+	ret = spi_claim_bus(flash->spi);
+	if (ret) {
+		debug("SF: unable to claim SPI bus\n");
+		return ret;
+	}
+
+	ret = sst25l_erase(flash, offset, len);
+	if (ret) {
+		debug("SF: unable to erase spi flash sector\n");
+		return ret;
+	}
+
+	spi_release_bus(flash->spi);
+	return ret;
+}
+
+static int sst25l_flash_read(struct spi_flash *flash,
+				u32 offset, size_t len, void *data)
+{
+	int ret;
+
+	ret = spi_claim_bus(flash->spi);
+	if (ret) {
+		debug("SF: unable to claim SPI bus\n");
+		return ret;
+	}
+
+	ret = sst25l_read(flash, offset, len, data);
+	if (ret) {
+		debug("SF: unable to read spi flash\n");
+		return ret;
+	}
+
+	spi_release_bus(flash->spi);
+	return ret;
+}
+
+static int sst25l_flash_write(struct spi_flash *flash,
+				u32 offset, size_t len, const void *buf)
+{
+	int ret;
+
+	ret = spi_claim_bus(flash->spi);
+	if (ret) {
+		debug("SF: unable to claim SPI bus\n");
+		return ret;
+	}
+
+	ret = sst25l_write(flash, offset, len, buf);
+	if (ret) {
+		debug("SF: unable to write spi flash\n");
+		return ret;
+	}
+
+	spi_release_bus(flash->spi);
+	return ret;
+}
+
+struct spi_flash *
+spi_flash_probe_sst25l(struct spi_slave *spi, u8 *idcode)
+{
+	const struct flash_info	*flash_info = NULL;
+	struct sst25l_spi_flash	*stm;
+	size_t			i;
+	u16			device_id = ((u16)idcode[0] << 8) + idcode[1];
+
+	for (i = 0; i < ARRAY_SIZE(sst25l_flash_info); ++i)
+		if (sst25l_flash_info[i].device_id == device_id) {
+			flash_info = &sst25l_flash_info[i];
+			break;
+		}
+
+	if (flash_info == NULL) {
+		debug("SF: Unsupported SST25L ID %04x\n", device_id);
+		return NULL;
+	}
+
+	stm = malloc(sizeof(*stm));
+	if (!stm) {
+		debug("SF: Failed to allocate memory\n");
+		return NULL;
+	}
+
+	stm->flash_info = flash_info;
+	stm->flash.spi  = spi;
+	stm->flash.name = flash_info->name;
+
+	stm->flash.read  = sst25l_flash_read;
+	stm->flash.write = sst25l_flash_write;
+	stm->flash.erase = sst25l_flash_erase;
+
+	stm->flash.page_size   = flash_info->page_size;
+	stm->flash.sector_size = flash_info->erase_size;
+	stm->flash.size        = flash_info->page_size * flash_info->nr_pages;
+
+	return &stm->flash;
+}
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH 6/6] MMC: u-boot-spl may be compiled without partition support
  2012-06-26 10:33 [U-Boot] [PATCH 1/6] arm/davinci: fix DDR2/mDDR memory controller initialization for Omap L138 Mikhail Kshevetskiy
                   ` (3 preceding siblings ...)
  2012-06-26 10:33 ` [U-Boot] [PATCH 5/6] mtd/spi: add sst25l driver Mikhail Kshevetskiy
@ 2012-06-26 10:33 ` Mikhail Kshevetskiy
  4 siblings, 0 replies; 7+ messages in thread
From: Mikhail Kshevetskiy @ 2012-06-26 10:33 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@gmail.com>
---
 drivers/mmc/mmc.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index aebe578..69df64a 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1253,7 +1253,9 @@ int mmc_startup(struct mmc *mmc)
 			(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
 	sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28,
 			(mmc->cid[2] >> 24) & 0xf);
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
 	init_part(&mmc->block_dev);
+#endif
 
 	return 0;
 }
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH 5/6] mtd/spi: add sst25l driver
  2012-06-26 10:33 ` [U-Boot] [PATCH 5/6] mtd/spi: add sst25l driver Mikhail Kshevetskiy
@ 2012-06-27 17:51   ` Tom Rini
  0 siblings, 0 replies; 7+ messages in thread
From: Tom Rini @ 2012-06-27 17:51 UTC (permalink / raw)
  To: u-boot

On Tue, Jun 26, 2012 at 02:33:13PM +0400, Mikhail Kshevetskiy wrote:

> current SST driver does not support well this types of flash, so use
> linux-3.3 code as a base.
> 
> Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@gmail.com>

The correct form here is to say:
Backport from Linux commit ....
If this is from the 3.3 release please say that clearly.  Thanks!

-- 
Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-06-27 17:51 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-26 10:33 [U-Boot] [PATCH 1/6] arm/davinci: fix DDR2/mDDR memory controller initialization for Omap L138 Mikhail Kshevetskiy
2012-06-26 10:33 ` [U-Boot] [PATCH 2/6] arm/davinci/da850: add uart0 pinmux Mikhail Kshevetskiy
2012-06-26 10:33 ` [U-Boot] [PATCH 3/6] serial/ns16550: ns16550 has a different register layout on SOC_DA8XX Mikhail Kshevetskiy
2012-06-26 10:33 ` [U-Boot] [PATCH 4/6] mtd/spi/spi_flash: support CMD_READ_ID=0x90 case Mikhail Kshevetskiy
2012-06-26 10:33 ` [U-Boot] [PATCH 5/6] mtd/spi: add sst25l driver Mikhail Kshevetskiy
2012-06-27 17:51   ` Tom Rini
2012-06-26 10:33 ` [U-Boot] [PATCH 6/6] MMC: u-boot-spl may be compiled without partition support Mikhail Kshevetskiy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.