All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support
@ 2010-04-21  7:54 Vipin KUMAR
  2010-04-21  7:54 ` [U-Boot] [PATCH 01/17] u-boot.img file not created when srctree and objtree are different Vipin KUMAR
  2010-04-21 11:54 ` [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support Peter Tyser
  0 siblings, 2 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

The following set of patches contain
1. Network driver support for designware IP
2. FSMC(Flexible static memory controller) support for ST IP.
3. I2C driver support for designware IP
4. SMI driver support for ST IP
5. spear1300 SoC and board support
6. misc changes in spear platform and board related code
7. change_bit routine defined in bitops.h(similar to setbit and clearbit)
8. Fix for u-boot.img generation

FSMC, I2C, SMI drivers earlier existed with the names spr_i2c, spr_nand etc.
These drivers have now been ported as generic IPs so that the code can be reused
by other platforms using the same peripheral

Vipin Kumar (17):
  u-boot.img file not created when srctree and objtree are different
  change_bit routine defined
  SPEAr : SMI erase and write timeouts increased
  SPEAr : Placing ethaddr write and read within CONFIG_CMD_NET
  SPEAr : Reducing the max RAM size to 128MB
  SPEAr : Basic arch related support added for SPEAr SoCs
  SPEAr : Network driver support added
  SPEAr : Network support configured for spear SoCs
  SPEAr : macb driver support added for spear310 and spear320
  SPEAr : FSMC driver support added
  SPEAr : Configuring FSMC driver for NAND interface
  SPEAr : i2c driver moved completely into drivers/i2c
  SPEAr : smi driver moved completely into drivers/mtd
  SPEAr : USBD driver support added
  SPEAr : Basic spear1300 architecture support added
  SPEAr : spear1300 SoC support added
  SPEAr : Supporting various configurations for spear3xx and spear6xx
    boards

 Makefile                                   |   24 +-
 arch/arm/cpu/arm926ejs/spear/Makefile      |    3 +-
 arch/arm/include/asm/arch-spear/hardware.h |   16 +-
 arch/arm/include/asm/arch-spear/spr_i2c.h  |  146 ----
 arch/arm/include/asm/arch-spear/spr_misc.h |    5 +
 arch/arm/include/asm/arch-spear/spr_nand.h |   57 --
 arch/arm/include/asm/arch-spear/spr_smi.h  |  115 ----
 arch/arm/include/asm/bitops.h              |   11 +-
 board/spear/common/Makefile                |   10 +-
 board/spear/common/spr_misc.c              |   23 +-
 board/spear/spear1300/Makefile             |   51 ++
 board/spear/spear1300/config.mk            |   28 +
 board/spear/spear1300/spear1300.c          |   89 +++
 board/spear/spear1300/spr_lowlevel_init.S  |   38 +
 board/spear/spear300/config.mk             |   11 -
 board/spear/spear300/spear300.c            |   11 +-
 board/spear/spear310/config.mk             |   11 -
 board/spear/spear310/spear310.c            |   18 +-
 board/spear/spear320/config.mk             |   11 -
 board/spear/spear320/spear320.c            |   15 +-
 board/spear/spear600/config.mk             |   11 -
 board/spear/spear600/spear600.c            |   11 +-
 cpu/arm926ejs/spear/cpu_info.c             |   76 ++
 cpu/arm_cortexa8/spear13xx/Makefile        |   52 ++
 cpu/arm_cortexa8/spear13xx/cache.S         |  112 +++
 cpu/arm_cortexa8/spear13xx/cpu_info.c      |  105 +++
 cpu/arm_cortexa8/spear13xx/reset.c         |   47 ++
 cpu/arm_cortexa8/spear13xx/timer.c         |  136 ++++
 drivers/i2c/Makefile                       |    2 +-
 drivers/i2c/dw_i2c.c                       |  331 +++++++++
 drivers/i2c/dw_i2c.h                       |  146 ++++
 drivers/i2c/spr_i2c.c                      |  331 ---------
 drivers/mtd/Makefile                       |    2 +-
 drivers/mtd/nand/Makefile                  |    2 +-
 drivers/mtd/nand/fsmc_nand.c               |  363 ++++++++++
 drivers/mtd/nand/fsmc_nand.h               |  104 +++
 drivers/mtd/nand/spr_nand.c                |  124 ----
 drivers/mtd/spr_smi.c                      |  523 --------------
 drivers/mtd/st_smi.c                       |  523 ++++++++++++++
 drivers/mtd/st_smi.h                       |  115 ++++
 drivers/net/Makefile                       |    1 +
 drivers/net/dw_eth.c                       |  504 ++++++++++++++
 drivers/net/dw_eth.h                       |  281 ++++++++
 drivers/serial/usbtty.h                    |    4 +-
 drivers/usb/gadget/Makefile                |    2 +-
 drivers/usb/gadget/dw_udc.c                | 1014 ++++++++++++++++++++++++++++
 drivers/usb/gadget/spr_udc.c               |  998 ---------------------------
 include/asm-arm/arch-spear/clk.h           |   27 +
 include/asm-arm/arch-spear13xx/hardware.h  |   40 ++
 include/asm-arm/arch-spear13xx/spr_gpt.h   |   85 +++
 include/asm-arm/arch-spear13xx/spr_misc.h  |  317 +++++++++
 include/asm-arm/arch-spear13xx/sys_proto.h |   32 +
 include/configs/spear-common.h             |   27 +-
 include/configs/spear13xx.h                |  199 ++++++
 include/configs/spear3xx.h                 |   30 +
 include/configs/spear6xx.h                 |   13 +
 include/netdev.h                           |    1 +
 include/usb/dw_udc.h                       |  230 +++++++
 include/usb/spr_udc.h                      |  230 -------
 59 files changed, 5237 insertions(+), 2607 deletions(-)
 delete mode 100644 arch/arm/include/asm/arch-spear/spr_i2c.h
 delete mode 100644 arch/arm/include/asm/arch-spear/spr_nand.h
 delete mode 100644 arch/arm/include/asm/arch-spear/spr_smi.h
 create mode 100644 board/spear/spear1300/Makefile
 create mode 100644 board/spear/spear1300/config.mk
 create mode 100644 board/spear/spear1300/spear1300.c
 create mode 100644 board/spear/spear1300/spr_lowlevel_init.S
 create mode 100644 cpu/arm926ejs/spear/cpu_info.c
 create mode 100644 cpu/arm_cortexa8/spear13xx/Makefile
 create mode 100644 cpu/arm_cortexa8/spear13xx/cache.S
 create mode 100644 cpu/arm_cortexa8/spear13xx/cpu_info.c
 create mode 100755 cpu/arm_cortexa8/spear13xx/reset.c
 create mode 100644 cpu/arm_cortexa8/spear13xx/timer.c
 create mode 100644 drivers/i2c/dw_i2c.c
 create mode 100644 drivers/i2c/dw_i2c.h
 delete mode 100644 drivers/i2c/spr_i2c.c
 create mode 100755 drivers/mtd/nand/fsmc_nand.c
 create mode 100644 drivers/mtd/nand/fsmc_nand.h
 delete mode 100644 drivers/mtd/nand/spr_nand.c
 delete mode 100644 drivers/mtd/spr_smi.c
 create mode 100644 drivers/mtd/st_smi.c
 create mode 100644 drivers/mtd/st_smi.h
 create mode 100755 drivers/net/dw_eth.c
 create mode 100644 drivers/net/dw_eth.h
 create mode 100644 drivers/usb/gadget/dw_udc.c
 delete mode 100644 drivers/usb/gadget/spr_udc.c
 create mode 100644 include/asm-arm/arch-spear/clk.h
 create mode 100644 include/asm-arm/arch-spear13xx/hardware.h
 create mode 100755 include/asm-arm/arch-spear13xx/spr_gpt.h
 create mode 100755 include/asm-arm/arch-spear13xx/spr_misc.h
 create mode 100644 include/asm-arm/arch-spear13xx/sys_proto.h
 create mode 100644 include/configs/spear13xx.h
 create mode 100644 include/usb/dw_udc.h
 delete mode 100644 include/usb/spr_udc.h

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

* [U-Boot] [PATCH 01/17] u-boot.img file not created when srctree and objtree are different
  2010-04-21  7:54 [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support Vipin KUMAR
@ 2010-04-21  7:54 ` Vipin KUMAR
  2010-04-21  7:54   ` [U-Boot] [PATCH 02/17] change_bit routine defined Vipin KUMAR
  2010-04-21 11:54 ` [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support Peter Tyser
  1 sibling, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

Adding ($obj) before tools/mkimage for u-boot.img file creation

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index 0381c81..1b431a5 100644
--- a/Makefile
+++ b/Makefile
@@ -317,7 +317,7 @@ $(obj)u-boot.ldr.srec:	$(obj)u-boot.ldr
 		$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary
 
 $(obj)u-boot.img:	$(obj)u-boot.bin
-		./tools/mkimage -A $(ARCH) -T firmware -C none \
+		$(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
 		-a $(TEXT_BASE) -e 0 \
 		-n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
 			sed -e 's/"[	 ]*$$/ for $(BOARD) board"/') \
-- 
1.6.0.2

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

* [U-Boot] [PATCH 02/17] change_bit routine defined
  2010-04-21  7:54 ` [U-Boot] [PATCH 01/17] u-boot.img file not created when srctree and objtree are different Vipin KUMAR
@ 2010-04-21  7:54   ` Vipin KUMAR
  2010-04-21  7:54     ` [U-Boot] [PATCH 03/17] SPEAr : SMI erase and write timeouts increased Vipin KUMAR
  0 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

change_bit routine is left implementation dependent until now.
This routine is now defined for arm platforms in asm-arm/bitops.h

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 arch/arm/include/asm/bitops.h |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index 270f163..435857b 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -29,8 +29,6 @@ extern void set_bit(int nr, volatile void * addr);
 
 extern void clear_bit(int nr, volatile void * addr);
 
-extern void change_bit(int nr, volatile void * addr);
-
 static inline void __change_bit(int nr, volatile void *addr)
 {
 	unsigned long mask = BIT_MASK(nr);
@@ -39,6 +37,15 @@ static inline void __change_bit(int nr, volatile void *addr)
 	*p ^= mask;
 }
 
+static inline void change_bit(int nr, volatile void *addr)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	__change_bit(nr, addr);
+	local_irq_restore(flags);
+}
+
 static inline int __test_and_set_bit(int nr, volatile void *addr)
 {
 	unsigned long mask = BIT_MASK(nr);
-- 
1.6.0.2

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

* [U-Boot] [PATCH 03/17] SPEAr : SMI erase and write timeouts increased
  2010-04-21  7:54   ` [U-Boot] [PATCH 02/17] change_bit routine defined Vipin KUMAR
@ 2010-04-21  7:54     ` Vipin KUMAR
  2010-04-21  7:54       ` [U-Boot] [PATCH 04/17] SPEAr : Placing ethaddr write and read within CONFIG_CMD_NET Vipin KUMAR
  0 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

SMI driver fails because of low timeout values. Increasing the erase and write
timeouts to 3 seconds

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 arch/arm/include/asm/arch-spear/spr_smi.h |    6 +++---
 drivers/mtd/spr_smi.c                     |    8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/arch-spear/spr_smi.h b/arch/arm/include/asm/arch-spear/spr_smi.h
index 06df745..e2e5e8f 100644
--- a/arch/arm/include/asm/arch-spear/spr_smi.h
+++ b/arch/arm/include/asm/arch-spear/spr_smi.h
@@ -108,8 +108,8 @@ struct flash_dev {
 	ushort sector_count;
 };
 
-#define SFLASH_PAGE_SIZE	0x100	/* flash page size */
-#define XFER_FINISH_TOUT	2	/* xfer finish timeout */
-#define WMODE_TOUT		2	/* write enable timeout */
+#define SFLASH_PAGE_SIZE	0x100		/* flash page size */
+#define XFER_FINISH_TOUT	(3 * CONFIG_SYS_HZ)
+#define WMODE_TOUT		(3 * CONFIG_SYS_HZ)
 
 #endif
diff --git a/drivers/mtd/spr_smi.c b/drivers/mtd/spr_smi.c
index 9a70a19..189ee6d 100644
--- a/drivers/mtd/spr_smi.c
+++ b/drivers/mtd/spr_smi.c
@@ -60,11 +60,11 @@ static struct flash_dev flash_ids[] = {
  */
 static void smi_wait_xfer_finish(int timeout)
 {
-	while (timeout--) {
+	do {
 		if (readl(&smicntl->smi_sr) & TFF)
 			break;
 		udelay(1000);
-	}
+	} while (timeout--);
 }
 
 /*
@@ -215,11 +215,11 @@ static int smi_write_enable(int bank)
 	/* Restore the CTRL REG1 state */
 	writel(ctrlreg1, &smicntl->smi_cr1);
 
-	while (timeout--) {
+	do {
 		if (smi_read_sr(bank) & (1 << (bank + WM_SHIFT)))
 			break;
 		udelay(1000);
-	}
+	} while (timeout--);
 
 	if (timeout)
 		return 0;
-- 
1.6.0.2

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

* [U-Boot] [PATCH 04/17] SPEAr : Placing ethaddr write and read within CONFIG_CMD_NET
  2010-04-21  7:54     ` [U-Boot] [PATCH 03/17] SPEAr : SMI erase and write timeouts increased Vipin KUMAR
@ 2010-04-21  7:54       ` Vipin KUMAR
  2010-04-21  7:54         ` [U-Boot] [PATCH 05/17] SPEAr : Reducing the max RAM size to 128MB Vipin KUMAR
  0 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

ethaddr can be optionally read from i2c memory. So, chip_config command supports
reading/writing hw mac id into i2c memory. Placing this code within
CONFIG_CMD_NET as this would only be needed when network interface is configured

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 board/spear/common/spr_misc.c |   23 ++++++++++++++++++++---
 1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/board/spear/common/spr_misc.c b/board/spear/common/spr_misc.c
index e356912..4af9436 100644
--- a/board/spear/common/spr_misc.c
+++ b/board/spear/common/spr_misc.c
@@ -38,6 +38,10 @@
 DECLARE_GLOBAL_DATA_PTR;
 static struct chip_data chip_data;
 
+#if defined(CONFIG_CMD_NET)
+static int i2c_read_mac(uchar *buffer);
+#endif
+
 int dram_init(void)
 {
 	struct xloader_table *xloader_tb =
@@ -166,6 +170,7 @@ int spear_board_init(ulong mach_type)
 	return 0;
 }
 
+#if defined(CONFIG_CMD_NET)
 static int i2c_read_mac(uchar *buffer)
 {
 	u8 buf[2];
@@ -205,15 +210,20 @@ static int write_mac(uchar *mac)
 	puts("I2C EEPROM writing failed \n");
 	return -1;
 }
+#endif
 
 int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	void (*sram_setfreq) (unsigned int, unsigned int);
 	struct chip_data *chip = &chip_data;
-	unsigned char mac[6];
-	unsigned int reg, frequency;
+	unsigned int frequency;
+
+#if defined(CONFIG_CMD_NET)
+	unsigned int reg;
 	char *s, *e;
 	char i2c_mac[20];
+	unsigned char mac[6];
+#endif
 
 	if ((argc > 3) || (argc < 2)) {
 		cmd_usage(cmdtp);
@@ -244,6 +254,8 @@ int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		}
 
 		return 0;
+
+#if defined(CONFIG_CMD_NET)
 	} else if (!strcmp(argv[1], "ethaddr")) {
 
 		s = argv[2];
@@ -255,6 +267,7 @@ int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		write_mac(mac);
 
 		return 0;
+#endif
 	} else if (!strcmp(argv[1], "print")) {
 
 		if (chip->cpufreq == -1)
@@ -274,13 +287,14 @@ int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		else
 			printf("DDR Type    = Not Known\n");
 
+#if defined(CONFIG_CMD_NET)
 		if (!i2c_read_mac(mac)) {
 			sprintf(i2c_mac, "%pM", mac);
 			printf("Ethaddr (from i2c mem) = %s\n", i2c_mac);
 		} else {
 			printf("Ethaddr (from i2c mem) = Not set\n");
 		}
-
+#endif
 		printf("Xloader Rev = %s\n", chip->version);
 
 		return 0;
@@ -293,4 +307,7 @@ int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 U_BOOT_CMD(chip_config, 3, 1, do_chip_config,
 	   "configure chip",
 	   "chip_config cpufreq/ddrfreq frequency\n"
+#if defined(CONFIG_CMD_NET)
+	   "chip_config ethaddr XX:XX:XX:XX:XX:XX\n"
+#endif
 	   "chip_config print");
-- 
1.6.0.2

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

* [U-Boot] [PATCH 05/17] SPEAr : Reducing the max RAM size to 128MB
  2010-04-21  7:54       ` [U-Boot] [PATCH 04/17] SPEAr : Placing ethaddr write and read within CONFIG_CMD_NET Vipin KUMAR
@ 2010-04-21  7:54         ` Vipin KUMAR
  2010-04-21  7:54           ` [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs Vipin KUMAR
  0 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 include/configs/spear-common.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
index cc52e39..b526558 100644
--- a/include/configs/spear-common.h
+++ b/include/configs/spear-common.h
@@ -208,6 +208,6 @@
 /* Physical Memory Map */
 #define CONFIG_NR_DRAM_BANKS			1
 #define PHYS_SDRAM_1				0x00000000
-#define PHYS_SDRAM_1_MAXSIZE			0x40000000
+#define PHYS_SDRAM_1_MAXSIZE			0x08000000
 
 #endif
-- 
1.6.0.2

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

* [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs
  2010-04-21  7:54         ` [U-Boot] [PATCH 05/17] SPEAr : Reducing the max RAM size to 128MB Vipin KUMAR
@ 2010-04-21  7:54           ` Vipin KUMAR
  2010-04-21  7:54             ` [U-Boot] [PATCH 07/17] SPEAr : Network driver support added Vipin KUMAR
  2010-04-21 11:51             ` [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs Peter Tyser
  0 siblings, 2 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

Adding CONFIG_DISPLAY_CPUINFO and CONFIG_ARCH_CPU_INIT support for SPEAr3xx and
SPEAr6xx SoCs

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 arch/arm/cpu/arm926ejs/spear/Makefile      |    3 +-
 arch/arm/include/asm/arch-spear/spr_misc.h |    5 ++
 cpu/arm926ejs/spear/cpu_info.c             |   76 ++++++++++++++++++++++++++++
 include/configs/spear-common.h             |    3 +-
 4 files changed, 85 insertions(+), 2 deletions(-)
 create mode 100644 cpu/arm926ejs/spear/cpu_info.c

diff --git a/arch/arm/cpu/arm926ejs/spear/Makefile b/arch/arm/cpu/arm926ejs/spear/Makefile
index bf8dfa8..6fe30c8 100644
--- a/arch/arm/cpu/arm926ejs/spear/Makefile
+++ b/arch/arm/cpu/arm926ejs/spear/Makefile
@@ -26,7 +26,8 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(SOC).a
 
 COBJS	:= reset.o \
-	   timer.o
+	   timer.o \
+	   cpu_info.o
 SOBJS	:=
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/arch/arm/include/asm/arch-spear/spr_misc.h b/arch/arm/include/asm/arch-spear/spr_misc.h
index 8b96d9b..045d2bb 100644
--- a/arch/arm/include/asm/arch-spear/spr_misc.h
+++ b/arch/arm/include/asm/arch-spear/spr_misc.h
@@ -126,5 +126,10 @@ struct misc_regs {
 
 /* PERIPH1_CLKEN, PERIPH1_RST value */
 #define MISC_USBDENB			0x01000000
+#define MISC_ETHENB			0x00800000
+#define MISC_SMIENB			0x00200000
+#define MISC_FSMCENB			0x00000200
+#define MISC_I2CENB			0x00000080
+#define MISC_UART0ENB			0x00000008
 
 #endif
diff --git a/cpu/arm926ejs/spear/cpu_info.c b/cpu/arm926ejs/spear/cpu_info.c
new file mode 100644
index 0000000..e935fec
--- /dev/null
+++ b/cpu/arm926ejs/spear/cpu_info.c
@@ -0,0 +1,76 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_misc.h>
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init(void)
+{
+	struct misc_regs *const misc_p =
+	    (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+	u32 periph1_clken;
+
+	periph1_clken = readl(&misc_p->periph1_clken);
+
+#if defined(CONFIG_PL011_SERIAL)
+	periph1_clken |= MISC_UART0ENB;
+#endif
+#if defined(CONFIG_DW_ETH)
+	periph1_clken |= MISC_ETHENB;
+#endif
+#if defined(CONFIG_DW_UDC)
+	periph1_clken |= MISC_USBDENB;
+#endif
+#if defined(CONFIG_DW_I2C)
+	periph1_clken |= MISC_I2CENB;
+#endif
+#if defined(CONFIG_ST_SMI)
+	periph1_clken |= MISC_SMIENB;
+#endif
+#if defined(CONFIG_NAND_FSMC)
+	periph1_clken |= MISC_FSMCENB;
+#endif
+
+	writel(periph1_clken, &misc_p->periph1_clken);
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+#ifdef CONFIG_SPEAR300
+	printf("CPU:   SPEAr300\n");
+#elif defined(CONFIG_SPEAR310)
+	printf("CPU:   SPEAr310\n");
+#elif defined(CONFIG_SPEAR320)
+	printf("CPU:   SPEAr320\n");
+#elif defined(CONFIG_SPEAR600)
+	printf("CPU:   SPEAr600\n");
+#endif
+	return 0;
+}
+#endif
diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
index b526558..68ba293 100644
--- a/include/configs/spear-common.h
+++ b/include/configs/spear-common.h
@@ -47,7 +47,6 @@
 
 /* Timer, HZ specific defines */
 #define CONFIG_SYS_HZ				(1000)
-#define CONFIG_SYS_HZ_CLOCK			(8300000)
 
 /* Flash configuration */
 #if defined(CONFIG_FLASH_PNOR)
@@ -168,6 +167,8 @@
 #define CONFIG_ENV_SIZE				0x02000
 
 /* Miscellaneous configurable options */
+#define CONFIG_ARCH_CPU_INIT			1
+#define CONFIG_DISPLAY_CPUINFO			1
 #define CONFIG_BOOT_PARAMS_ADDR			0x00000100
 #define CONFIG_CMDLINE_TAG			1
 #define CONFIG_SETUP_MEMORY_TAGS		1
-- 
1.6.0.2

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

* [U-Boot] [PATCH 07/17] SPEAr : Network driver support added
  2010-04-21  7:54           ` [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs Vipin KUMAR
@ 2010-04-21  7:54             ` Vipin KUMAR
  2010-04-21  7:54               ` [U-Boot] [PATCH 08/17] SPEAr : Network support configured for spear SoCs Vipin KUMAR
                                 ` (2 more replies)
  2010-04-21 11:51             ` [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs Peter Tyser
  1 sibling, 3 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

Designware network driver support added.
This is a Synopsys ethernet controller

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 drivers/net/Makefile |    1 +
 drivers/net/dw_eth.c |  504 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/dw_eth.h |  281 ++++++++++++++++++++++++++++
 include/netdev.h     |    1 +
 4 files changed, 787 insertions(+), 0 deletions(-)
 create mode 100755 drivers/net/dw_eth.c
 create mode 100644 drivers/net/dw_eth.h

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1ec0ba1..d03c353 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -68,6 +68,7 @@ COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o
 COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
 COBJS-$(CONFIG_SMC91111) += smc91111.o
 COBJS-$(CONFIG_SMC911X) += smc911x.o
+COBJS-$(CONFIG_DW_ETH) += dw_eth.o
 COBJS-$(CONFIG_TIGON3) += tigon3.o bcm570x_autoneg.o 5701rls.o
 COBJS-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
 COBJS-$(CONFIG_TSEC_ENET) += tsec.o
diff --git a/drivers/net/dw_eth.c b/drivers/net/dw_eth.c
new file mode 100755
index 0000000..52e7d15
--- /dev/null
+++ b/drivers/net/dw_eth.c
@@ -0,0 +1,504 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * (C) Copyright 2008
+ * Deepak Sikri, ST Micoelectronics, deepak.sikri at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Designware ethernet IP driver for u-boot
+ */
+
+#include <common.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include "dw_eth.h"
+
+static void tx_descs_init(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+	struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
+	char *txbuffs = &priv->txbuffs[0];
+	struct dmamacdescr *desc_p;
+
+	u32 idx;
+
+	for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
+
+		desc_p = &desc_table_p[idx];
+		desc_p->dmamac_addr = &txbuffs[idx * CONFIG_ETH_BUFSIZE];
+		desc_p->dmamac_next = &desc_table_p[idx + 1];
+
+#if defined(CONFIG_DW_ALTDESC)
+		desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
+				DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
+				DESC_TXSTS_TXCHECKINSCTRL | \
+				DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
+
+		desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
+		desc_p->dmamac_cntl = 0;
+		desc_p->txrx_status &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
+#else
+		desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
+		desc_p->txrx_status = 0;
+#endif
+	}
+
+	/* Correcting the last pointer of the chain */
+	desc_p->dmamac_next = &desc_table_p[0];
+
+	writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
+}
+
+static void rx_descs_init(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+	struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
+	char *rxbuffs = &priv->rxbuffs[0];
+	struct dmamacdescr *desc_p;
+
+	u32 idx;
+
+	for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
+
+		desc_p = &desc_table_p[idx];
+		desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE];
+		desc_p->dmamac_next = &desc_table_p[idx + 1];
+
+		desc_p->dmamac_cntl =
+			(MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) | \
+				      DESC_RXCTRL_RXCHAIN;
+
+		desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
+	}
+
+	/* Correcting the last pointer of the chain */
+	desc_p->dmamac_next = &desc_table_p[0];
+
+	writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
+}
+
+static void descs_init(struct eth_device *dev)
+{
+	tx_descs_init(dev);
+	rx_descs_init(dev);
+}
+
+static void mac_reset(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+
+	u32 timeout = CONFIG_MACRESET_TIMEOUT;
+
+	writel(DMAMAC_SRST, &dma_p->busmode);
+	writel(MII_PORTSELECT, &mac_p->conf);
+
+	do {
+		if (!(readl(&dma_p->busmode) & DMAMAC_SRST))
+			break;
+		udelay(1000);
+	} while (timeout--);
+}
+
+static int dw_eth_init(struct eth_device *dev, bd_t *bis)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+
+	u8 *mac_id = &dev->enetaddr[0];
+	u32 conf, macid_lo, macid_hi;
+
+	/* Reset ethernet hardware */
+	mac_reset(dev);
+
+	macid_lo = mac_id[0] + (mac_id[1] << 8) + \
+		   (mac_id[2] << 16) + (mac_id[3] << 24);
+	macid_hi = mac_id[4] + (mac_id[5] << 8);
+
+	writel(macid_hi, &mac_p->macaddr0hi);
+	writel(macid_lo, &mac_p->macaddr0lo);
+
+	writel(FIXEDBURST | PRIORXTX_41 | BURST_16,
+			&dma_p->busmode);
+
+	writel(FLUSHTXFIFO | readl(&dma_p->opmode), &dma_p->opmode);
+	writel(STOREFORWARD | TXSECONDFRAME, &dma_p->opmode);
+
+	conf = FRAMEBURSTENABLE | DISABLERXOWN;
+
+	if (priv->speed != SPEED_1000M)
+		conf |= MII_PORTSELECT;
+
+	if (priv->duplex == FULL_DUPLEX)
+		conf |= FULLDPLXMODE;
+
+	writel(conf, &mac_p->conf);
+
+	descs_init(dev);
+
+	/*
+	 * Start/Enable xfer at dma as well as mac level
+	 */
+	writel(readl(&dma_p->opmode) | RXSTART, &dma_p->opmode);
+	writel(readl(&dma_p->opmode) | TXSTART, &dma_p->opmode);
+
+	writel(readl(&mac_p->conf) | RXENABLE, &mac_p->conf);
+	writel(readl(&mac_p->conf) | TXENABLE, &mac_p->conf);
+
+	return 0;
+}
+
+static int dw_eth_send(struct eth_device *dev, volatile void *packet,
+		int length)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+	u32 desc_num = priv->tx_currdescnum;
+	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
+
+	/* Check if the descriptor is owned by CPU */
+	if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
+		printf("eth_send : CPU not owner of tx frame\n");
+		return -1;
+	}
+
+	memcpy((void *)desc_p->dmamac_addr, (void *)packet, length);
+
+#if defined(CONFIG_DW_ALTDESC)
+	desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
+	desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & \
+			       DESC_TXCTRL_SIZE1MASK;
+
+	desc_p->txrx_status &= ~(DESC_TXSTS_MSK);
+	desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
+#else
+	desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & \
+			       DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \
+			       DESC_TXCTRL_TXFIRST;
+
+	desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
+#endif
+
+	/* Test the wrap-around condition. */
+	if (++desc_num >= CONFIG_TX_DESCR_NUM)
+		desc_num = 0;
+
+	priv->tx_currdescnum = desc_num;
+
+	/* Start the transmission */
+	writel(POLL_DATA, &dma_p->txpolldemand);
+
+	return 0;
+}
+
+static int dw_eth_recv(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	u32 desc_num = priv->rx_currdescnum;
+	struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
+
+	u32 status = desc_p->txrx_status;
+	int length = 0;
+
+	/* Check  if the owner is the CPU */
+	if (!(status & DESC_RXSTS_OWNBYDMA)) {
+
+		length = (status & DESC_RXSTS_FRMLENMSK) >> \
+			 DESC_RXSTS_FRMLENSHFT;
+
+		NetReceive(desc_p->dmamac_addr, length);
+
+		/*
+		 * Make the current descriptor valid again and go to
+		 * the next one
+		 */
+		desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
+
+		/* Test the wrap-around condition. */
+		if (++desc_num >= CONFIG_RX_DESCR_NUM)
+			desc_num = 0;
+	}
+
+	priv->rx_currdescnum = desc_num;
+
+	return length;
+}
+
+static void dw_eth_halt(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+
+	mac_reset(dev);
+	priv->tx_currdescnum = priv->rx_currdescnum = 0;
+}
+
+static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	u32 miiaddr;
+	u32 timeout = CONFIG_MDIO_TIMEOUT;
+
+	miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
+		  ((reg << MIIREGSHIFT) & MII_REGMSK);
+
+	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
+
+	do {
+		if (!(readl(&mac_p->miiaddr) & MII_BUSY))
+			break;
+		udelay(1000);
+	} while (timeout--);
+
+	*val = readl(&mac_p->miidata);
+
+	return 0;
+}
+
+static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	u32 miiaddr;
+	u32 timeout = CONFIG_MDIO_TIMEOUT;
+	u16 value;
+
+	writel(val, &mac_p->miidata);
+	miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
+		  ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE;
+
+	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
+
+	do {
+		if (!(readl(&mac_p->miiaddr) & MII_BUSY))
+			break;
+		udelay(1000);
+	} while (timeout--);
+
+	/* Needed as a fix for ST-Phy */
+	eth_mdio_read(dev, addr, reg, &value);
+
+	return 0;
+}
+
+static u8 find_phy(struct eth_device *dev)
+{
+	u8 phy_addr = 0;
+	u16 ctrl, oldctrl;
+
+	do {
+		eth_mdio_read(dev, phy_addr, PHY_BMCR, &ctrl);
+		oldctrl = ctrl & PHY_BMCR_AUTON;
+
+		ctrl ^= PHY_BMCR_AUTON;
+		eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
+		eth_mdio_read(dev, phy_addr, PHY_BMCR, &ctrl);
+		ctrl &= PHY_BMCR_AUTON;
+
+		if (ctrl == oldctrl) {
+			phy_addr++;
+		} else {
+			ctrl ^= PHY_BMCR_AUTON;
+			eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
+			break;
+		}
+	} while (phy_addr < 32);
+
+	return phy_addr;
+}
+
+static void dw_reset_phy(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	u16 ctrl;
+	u32 timeout = CONFIG_PHYRESET_TIMEOUT;
+	u32 phy_addr = priv->address;
+
+	eth_mdio_write(dev, phy_addr, PHY_BMCR, PHY_BMCR_RESET);
+	do {
+		eth_mdio_read(dev, phy_addr, PHY_BMCR, &ctrl);
+		if (!(ctrl & PHY_BMCR_RESET))
+			break;
+		udelay(1000);
+	} while (timeout--);
+
+#ifdef CONFIG_PHY_RESET_DELAY
+	udelay(CONFIG_PHY_RESET_DELAY);
+#endif
+}
+
+static void configure_phy(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	u8 phy_addr;
+	u16 bmcr, ctrl;
+#if defined(CONFIG_DW_AUTONEG)
+	u16 bmsr;
+	u32 timeout;
+	u16 anlpar, btsr;
+#endif
+	priv->address = find_phy(dev);
+	phy_addr = priv->address;
+
+	dw_reset_phy(dev);
+
+#if defined(CONFIG_DW_AUTONEG)
+	bmcr = PHY_BMCR_AUTON | PHY_BMCR_RST_NEG | PHY_BMCR_100MB | \
+	       PHY_BMCR_DPLX | PHY_BMCR_1000_MBPS;
+#else
+	bmcr = PHY_BMCR_100MB | PHY_BMCR_DPLX;
+
+#if defined(CONFIG_DW_SPEED10M)
+	bmcr &= ~PHY_BMCR_100MB;
+#endif
+#if defined(CONFIG_DW_DUPLEXHALF)
+	bmcr &= ~PHY_BMCR_DPLX;
+#endif
+#endif
+	eth_mdio_write(dev, phy_addr, PHY_BMCR, bmcr);
+
+	/* Read the phy status register and populate priv structure */
+#if defined(CONFIG_DW_AUTONEG)
+	timeout = CONFIG_AUTONEG_TIMEOUT;
+	do {
+		eth_mdio_read(dev, phy_addr, PHY_BMSR, &bmsr);
+		if (bmsr & PHY_BMSR_AUTN_COMP)
+			break;
+		udelay(1000);
+	} while (timeout--);
+
+	eth_mdio_read(dev, phy_addr, PHY_ANLPAR, &anlpar);
+	eth_mdio_read(dev, phy_addr, PHY_1000BTSR, &btsr);
+
+	if (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
+		priv->speed = SPEED_1000M;
+		if (btsr & PHY_1000BTSR_1000FD)
+			priv->duplex = FULL_DUPLEX;
+		else
+			priv->duplex = HALF_DUPLEX;
+	} else {
+		if (anlpar & PHY_ANLPAR_100)
+			priv->speed = SPEED_100M;
+		else
+			priv->speed = SPEED_10M;
+
+		if (anlpar & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD))
+			priv->duplex = FULL_DUPLEX;
+		else
+			priv->duplex = HALF_DUPLEX;
+	}
+#else
+	eth_mdio_read(dev, phy_addr, PHY_BMCR, &ctrl);
+
+	if (ctrl & PHY_BMCR_DPLX)
+		priv->duplex = FULL_DUPLEX;
+	else
+		priv->duplex = HALF_DUPLEX;
+
+	if (ctrl & PHY_BMCR_1000_MBPS)
+		priv->speed = SPEED_1000M;
+	else if (ctrl & PHY_BMCR_100_MBPS)
+		priv->speed = SPEED_100M;
+	else
+		priv->speed = SPEED_10M;
+#endif
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static int dw_mii_read(char *devname, u8 addr, u8 reg, u16 *val)
+{
+	struct eth_device *netdev;
+
+	netdev = eth_get_dev_by_name(devname);
+	if (netdev)
+		eth_mdio_read(netdev, addr, reg, val);
+
+	return 0;
+}
+
+static int dw_mii_write(char *devname, u8 addr, u8 reg, u16 val)
+{
+	struct eth_device *netdev;
+
+	netdev = eth_get_dev_by_name(devname);
+	if (netdev)
+		eth_mdio_write(netdev, addr, reg, val);
+
+	return 0;
+}
+#endif
+
+int dw_mii_initialize(u32 id, ulong base_addr)
+{
+	struct eth_device *netdev;
+	struct dw_eth_dev *priv;
+
+	netdev = (struct eth_device *) malloc(sizeof(struct eth_device));
+	if (!netdev)
+		return -ENOMEM;
+
+	/*
+	 * Since the priv structure contains the descriptors which need a strict
+	 * buswidth alignment, memalign is used to allocate memory
+	 */
+	priv = (struct dw_eth_dev *) memalign(16, sizeof(struct dw_eth_dev));
+	if (!priv) {
+		free(netdev);
+		return -ENOMEM;
+	}
+
+	memset(netdev, 0, sizeof(struct eth_device));
+	memset(priv, 0, sizeof(struct dw_eth_dev));
+
+	sprintf(netdev->name, "mii%d", id);
+	netdev->iobase = (int)base_addr;
+	netdev->priv = priv;
+
+	eth_getenv_enetaddr_by_index(id, &netdev->enetaddr[0]);
+
+	priv->dev = netdev;
+	priv->mac_regs_p = (struct eth_mac_regs *)base_addr;
+	priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
+			DW_DMA_BASE_OFFSET);
+
+	mac_reset(netdev);
+	configure_phy(netdev);
+
+	netdev->init = dw_eth_init;
+	netdev->send = dw_eth_send;
+	netdev->recv = dw_eth_recv;
+	netdev->halt = dw_eth_halt;
+
+	eth_register(netdev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register(netdev->name, dw_mii_read, dw_mii_write);
+#endif
+	return 0;
+}
diff --git a/drivers/net/dw_eth.h b/drivers/net/dw_eth.h
new file mode 100644
index 0000000..068211a
--- /dev/null
+++ b/drivers/net/dw_eth.h
@@ -0,0 +1,281 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _DW_ETH_H
+#define _DW_ETH_H
+
+#define CONFIG_TX_DESCR_NUM	16
+#define CONFIG_RX_DESCR_NUM	16
+#define CONFIG_ETH_BUFSIZE	2048
+#define TX_TOTAL_BUFSIZE	(CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
+#define RX_TOTAL_BUFSIZE	(CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
+
+#define CONFIG_MACRESET_TIMEOUT	(3 * CONFIG_SYS_HZ)
+#define CONFIG_MDIO_TIMEOUT	(3 * CONFIG_SYS_HZ)
+#define CONFIG_PHYRESET_TIMEOUT	(3 * CONFIG_SYS_HZ)
+#define CONFIG_AUTONEG_TIMEOUT	(5 * CONFIG_SYS_HZ)
+
+struct eth_mac_regs {
+	u32 conf;		/* 0x00 */
+	u32 framefilt;		/* 0x04 */
+	u32 hashtablehigh;	/* 0x08 */
+	u32 hashtablelow;	/* 0x0c */
+	u32 miiaddr;		/* 0x10 */
+	u32 miidata;		/* 0x14 */
+	u32 flowcontrol;	/* 0x18 */
+	u32 vlantag;		/* 0x1c */
+	u32 version;		/* 0x20 */
+	u8 reserved_1[0x38 - 0x24];
+	u32 intreg;		/* 0x38 */
+	u32 intmask;		/* 0x3c */
+	u32 macaddr0hi;		/* 0x40 */
+	u32 macaddr0lo;		/* 0x44 */
+};
+
+/* MAC configuration register definitions */
+#define FRAMEBURSTENABLE	(1 << 21)
+#define MII_PORTSELECT		(1 << 15)
+#define FES_100			(1 << 14)
+#define DISABLERXOWN		(1 << 13)
+#define FULLDPLXMODE		(1 << 11)
+#define RXENABLE		(1 << 2)
+#define TXENABLE		(1 << 3)
+
+/* MII address register definitions */
+#define MII_BUSY		(1 << 0)
+#define MII_WRITE		(1 << 1)
+#define MII_CLKRANGE_60_100M	(0)
+#define MII_CLKRANGE_100_150M	(0x4)
+#define MII_CLKRANGE_20_35M	(0x8)
+#define MII_CLKRANGE_35_60M	(0xC)
+#define MII_CLKRANGE_150_250M	(0x10)
+#define MII_CLKRANGE_250_300M	(0x14)
+
+#define MIIADDRSHIFT		(11)
+#define MIIREGSHIFT		(6)
+#define MII_REGMSK		(0x1F << 6)
+#define MII_ADDRMSK		(0x1F << 11)
+
+
+struct eth_dma_regs {
+	u32 busmode;		/* 0x00 */
+	u32 txpolldemand;	/* 0x04 */
+	u32 rxpolldemand;	/* 0x08 */
+	u32 rxdesclistaddr;	/* 0x0c */
+	u32 txdesclistaddr;	/* 0x10 */
+	u32 status;		/* 0x14 */
+	u32 opmode;		/* 0x18 */
+	u32 intenable;		/* 0x1c */
+	u8 reserved[0x48 - 0x20];
+	u32 currhosttxdesc;	/* 0x48 */
+	u32 currhostrxdesc;	/* 0x4c */
+	u32 currhosttxbuffaddr;	/* 0x50 */
+	u32 currhostrxbuffaddr;	/* 0x54 */
+};
+
+#define DW_DMA_BASE_OFFSET	(0x1000)
+
+/* Bus mode register definitions */
+#define FIXEDBURST		(1 << 16)
+#define PRIORXTX_41		(3 << 14)
+#define PRIORXTX_31		(2 << 14)
+#define PRIORXTX_21		(1 << 14)
+#define PRIORXTX_11		(0 << 14)
+#define BURST_1			(1 << 8)
+#define BURST_2			(2 << 8)
+#define BURST_4			(4 << 8)
+#define BURST_8			(8 << 8)
+#define BURST_16		(16 << 8)
+#define BURST_32		(32 << 8)
+#define RXHIGHPRIO		(1 << 1)
+#define DMAMAC_SRST		(1 << 0)
+
+/* Poll demand definitions */
+#define POLL_DATA		(0xFFFFFFFF)
+
+/* Operation mode definitions */
+#define STOREFORWARD		(1 << 21)
+#define FLUSHTXFIFO		(1 << 20)
+#define TXSTART			(1 << 13)
+#define TXSECONDFRAME		(1 << 2)
+#define RXSTART			(1 << 1)
+
+/* Descriptior related definitions */
+#define MAC_MAX_FRAME_SZ	(2048)
+
+struct dmamacdescr {
+	u32 txrx_status;
+	u32 dmamac_cntl;
+	void *dmamac_addr;
+	struct dmamacdescr *dmamac_next;
+};
+
+/*
+ * txrx_status definitions
+ */
+
+/* tx status bits definitions */
+#if defined(CONFIG_DW_ALTDESC)
+
+#define DESC_TXSTS_OWNBYDMA		(1 << 31)
+#define DESC_TXSTS_TXINT		(1 << 30)
+#define DESC_TXSTS_TXLAST		(1 << 29)
+#define DESC_TXSTS_TXFIRST		(1 << 28)
+#define DESC_TXSTS_TXCRCDIS		(1 << 27)
+
+#define DESC_TXSTS_TXPADDIS		(1 << 26)
+#define DESC_TXSTS_TXCHECKINSCTRL	(3 << 22)
+#define DESC_TXSTS_TXRINGEND		(1 << 21)
+#define DESC_TXSTS_TXCHAIN		(1 << 20)
+#define DESC_TXSTS_MSK			(0x1FFFF << 0)
+
+#else
+
+#define DESC_TXSTS_OWNBYDMA		(1 << 31)
+#define DESC_TXSTS_MSK			(0x1FFFF << 0)
+
+#endif
+
+/* rx status bits definitions */
+#define DESC_RXSTS_OWNBYDMA		(1 << 31)
+#define DESC_RXSTS_DAFILTERFAIL		(1 << 30)
+#define DESC_RXSTS_FRMLENMSK		(0x3FFF << 16)
+#define DESC_RXSTS_FRMLENSHFT		(16)
+
+#define DESC_RXSTS_ERROR		(1 << 15)
+#define DESC_RXSTS_RXTRUNCATED		(1 << 14)
+#define DESC_RXSTS_SAFILTERFAIL		(1 << 13)
+#define DESC_RXSTS_RXIPC_GIANTFRAME	(1 << 12)
+#define DESC_RXSTS_RXDAMAGED		(1 << 11)
+#define DESC_RXSTS_RXVLANTAG		(1 << 10)
+#define DESC_RXSTS_RXFIRST		(1 << 9)
+#define DESC_RXSTS_RXLAST		(1 << 8)
+#define DESC_RXSTS_RXIPC_GIANT		(1 << 7)
+#define DESC_RXSTS_RXCOLLISION		(1 << 6)
+#define DESC_RXSTS_RXFRAMEETHER		(1 << 5)
+#define DESC_RXSTS_RXWATCHDOG		(1 << 4)
+#define DESC_RXSTS_RXMIIERROR		(1 << 3)
+#define DESC_RXSTS_RXDRIBBLING		(1 << 2)
+#define DESC_RXSTS_RXCRC		(1 << 1)
+
+/*
+ * dmamac_cntl definitions
+ */
+
+/* tx control bits definitions */
+#if defined(CONFIG_DW_ALTDESC)
+
+#define DESC_TXCTRL_SIZE1MASK		(0x1FFF << 0)
+#define DESC_TXCTRL_SIZE1SHFT		(0)
+#define DESC_TXCTRL_SIZE2MASK		(0x1FFF << 16)
+#define DESC_TXCTRL_SIZE2SHFT		(16)
+
+#else
+
+#define DESC_TXCTRL_TXINT		(1 << 31)
+#define DESC_TXCTRL_TXLAST		(1 << 30)
+#define DESC_TXCTRL_TXFIRST		(1 << 29)
+#define DESC_TXCTRL_TXCHECKINSCTRL	(3 << 27)
+#define DESC_TXCTRL_TXCRCDIS		(1 << 26)
+#define DESC_TXCTRL_TXRINGEND		(1 << 25)
+#define DESC_TXCTRL_TXCHAIN		(1 << 24)
+
+#define DESC_TXCTRL_SIZE1MASK		(0x7FF << 0)
+#define DESC_TXCTRL_SIZE1SHFT		(0)
+#define DESC_TXCTRL_SIZE2MASK		(0x7FF << 11)
+#define DESC_TXCTRL_SIZE2SHFT		(11)
+
+#endif
+
+/* rx control bits definitions */
+#if defined(CONFIG_DW_ALTDESC)
+
+#define DESC_RXCTRL_RXINTDIS		(1 << 31)
+#define DESC_RXCTRL_RXRINGEND		(1 << 15)
+#define DESC_RXCTRL_RXCHAIN		(1 << 14)
+
+#define DESC_RXCTRL_SIZE1MASK		(0x1FFF << 0)
+#define DESC_RXCTRL_SIZE1SHFT		(0)
+#define DESC_RXCTRL_SIZE2MASK		(0x1FFF << 16)
+#define DESC_RXCTRL_SIZE2SHFT		(16)
+
+#else
+
+#define DESC_RXCTRL_RXINTDIS		(1 << 31)
+#define DESC_RXCTRL_RXRINGEND		(1 << 25)
+#define DESC_RXCTRL_RXCHAIN		(1 << 24)
+
+#define DESC_RXCTRL_SIZE1MASK		(0x7FF << 0)
+#define DESC_RXCTRL_SIZE1SHFT		(0)
+#define DESC_RXCTRL_SIZE2MASK		(0x7FF << 11)
+#define DESC_RXCTRL_SIZE2SHFT		(11)
+
+#endif
+
+/*
+ * dmamac_addr definitions
+ */
+
+/* tx addr register bits definitions */
+
+/* rx addr register bits definitions */
+
+
+/*
+ * dmamac_next definitions
+ */
+
+/* tx next register bits definitions */
+
+/* rx next register bits definitions */
+
+struct dw_eth_dev {
+	u32 address;
+	u32 speed;
+	u32 duplex;
+	u32 tx_currdescnum;
+	u32 rx_currdescnum;
+	u32 padding;
+
+	struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
+	struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM];
+
+	char txbuffs[TX_TOTAL_BUFSIZE];
+	char rxbuffs[RX_TOTAL_BUFSIZE];
+
+	struct eth_mac_regs *mac_regs_p;
+	struct eth_dma_regs *dma_regs_p;
+
+	struct eth_device *dev;
+} __attribute__ ((aligned(8)));
+
+/* Speed specific definitions */
+#define SPEED_10M		1
+#define SPEED_100M		2
+#define SPEED_1000M		3
+
+/* Duplex mode specific definitions */
+#define HALF_DUPLEX		1
+#define FULL_DUPLEX		2
+
+#endif
diff --git a/include/netdev.h b/include/netdev.h
index 1dd80f0..460889c 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -79,6 +79,7 @@ int scc_initialize(bd_t *bis);
 int skge_initialize(bd_t *bis);
 int smc911x_initialize(u8 dev_num, int base_addr);
 int smc91111_initialize(u8 dev_num, int base_addr);
+int dw_mii_initialize(u32 id, ulong base_addr);
 int tsi108_eth_initialize(bd_t *bis);
 int uec_initialize(int index);
 int uec_standard_init(bd_t *bis);
-- 
1.6.0.2

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

* [U-Boot] [PATCH 08/17] SPEAr : Network support configured for spear SoCs
  2010-04-21  7:54             ` [U-Boot] [PATCH 07/17] SPEAr : Network driver support added Vipin KUMAR
@ 2010-04-21  7:54               ` Vipin KUMAR
  2010-04-21  7:54                 ` [U-Boot] [PATCH 09/17] SPEAr : macb driver support added for spear310 and spear320 Vipin KUMAR
  2010-04-21 12:00               ` [U-Boot] [PATCH 07/17] SPEAr : Network " Peter Tyser
  2010-04-21 17:48               ` Ben Warren
  2 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 arch/arm/include/asm/arch-spear/hardware.h |    1 +
 board/spear/spear300/spear300.c            |    6 ++++++
 board/spear/spear310/spear310.c            |    6 ++++++
 board/spear/spear320/spear320.c            |    6 ++++++
 board/spear/spear600/spear600.c            |    6 ++++++
 include/configs/spear-common.h             |   10 ++++++++--
 include/configs/spear3xx.h                 |    3 +++
 7 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/arch-spear/hardware.h b/arch/arm/include/asm/arch-spear/hardware.h
index 818f36c..39d64b6 100644
--- a/arch/arm/include/asm/arch-spear/hardware.h
+++ b/arch/arm/include/asm/arch-spear/hardware.h
@@ -31,6 +31,7 @@
 #define CONFIG_SPEAR_SYSCNTLBASE		(0xFCA00000)
 #define CONFIG_SPEAR_TIMERBASE			(0xFC800000)
 #define CONFIG_SPEAR_MISCBASE			(0xFCA80000)
+#define CONFIG_SPEAR_ETHBASE			(0xE0800000)
 
 #define CONFIG_SYS_NAND_CLE			(1 << 16)
 #define CONFIG_SYS_NAND_ALE			(1 << 17)
diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c
index 60ee544..e58792a 100644
--- a/board/spear/spear300/spear300.c
+++ b/board/spear/spear300/spear300.c
@@ -22,6 +22,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #include <nand.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
@@ -56,3 +57,8 @@ int board_nand_init(struct nand_chip *nand)
 
 	return -1;
 }
+
+int board_eth_init(bd_t *bis)
+{
+	return dw_mii_initialize(0, CONFIG_SPEAR_ETHBASE);
+}
diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c
index 03dfe16..e8a6552 100644
--- a/board/spear/spear310/spear310.c
+++ b/board/spear/spear310/spear310.c
@@ -23,6 +23,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #include <nand.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
@@ -57,3 +58,8 @@ int board_nand_init(struct nand_chip *nand)
 
 	return -1;
 }
+
+int board_eth_init(bd_t *bis)
+{
+	return dw_mii_initialize(0, CONFIG_SPEAR_ETHBASE);
+}
diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c
index 2ba2dbb..72bc9a5 100644
--- a/board/spear/spear320/spear320.c
+++ b/board/spear/spear320/spear320.c
@@ -23,6 +23,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #include <nand.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
@@ -57,3 +58,8 @@ int board_nand_init(struct nand_chip *nand)
 
 	return -1;
 }
+
+int board_eth_init(bd_t *bis)
+{
+	return dw_mii_initialize(0, CONFIG_SPEAR_ETHBASE);
+}
diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c
index eef9a37..b93151e 100644
--- a/board/spear/spear600/spear600.c
+++ b/board/spear/spear600/spear600.c
@@ -22,6 +22,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #include <nand.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
@@ -51,3 +52,8 @@ int board_nand_init(struct nand_chip *nand)
 
 	return -1;
 }
+
+int board_eth_init(bd_t *bis)
+{
+	return dw_mii_initialize(0, CONFIG_SPEAR_ETHBASE);
+}
diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
index 68ba293..e7905b1 100644
--- a/include/configs/spear-common.h
+++ b/include/configs/spear-common.h
@@ -27,6 +27,11 @@
  * Common configurations used for both spear3xx as well as spear6xx
  */
 
+/* Ethernet driver configuration */
+#define CONFIG_DW_ETH
+#define CONFIG_NET_MULTI
+#define CONFIG_PHY_RESET_DELAY			(10000)		/* in usec */
+
 /* USBD driver configuration */
 #define CONFIG_SPEARUDC
 #define CONFIG_USB_DEVICE
@@ -98,11 +103,12 @@
 #define CONFIG_CMD_MEMORY
 #define CONFIG_CMD_RUN
 #define CONFIG_CMD_SAVES
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
 
 /* This must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <config_cmd_default.h>
-#undef CONFIG_CMD_NET
-#undef CONFIG_CMD_NFS
 
 /*
  * Default Environment Varible definitions
diff --git a/include/configs/spear3xx.h b/include/configs/spear3xx.h
index 0248aba..f077213 100644
--- a/include/configs/spear3xx.h
+++ b/include/configs/spear3xx.h
@@ -41,6 +41,9 @@
 
 #include <configs/spear-common.h>
 
+/* Ethernet driver configuration */
+#define CONFIG_DW_ALTDESC			1
+
 /* Serial Configuration (PL011) */
 #define CONFIG_SYS_SERIAL0			0xD0000000
 
-- 
1.6.0.2

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

* [U-Boot] [PATCH 09/17] SPEAr : macb driver support added for spear310 and spear320
  2010-04-21  7:54               ` [U-Boot] [PATCH 08/17] SPEAr : Network support configured for spear SoCs Vipin KUMAR
@ 2010-04-21  7:54                 ` Vipin KUMAR
  2010-04-21  7:54                   ` [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added Vipin KUMAR
  0 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 arch/arm/include/asm/arch-spear/hardware.h |    7 +++++++
 board/spear/spear310/spear310.c            |    9 ++++++++-
 board/spear/spear320/spear320.c            |    6 +++++-
 include/asm-arm/arch-spear/clk.h           |   27 +++++++++++++++++++++++++++
 include/configs/spear3xx.h                 |   13 +++++++++++++
 5 files changed, 60 insertions(+), 2 deletions(-)
 create mode 100644 include/asm-arm/arch-spear/clk.h

diff --git a/arch/arm/include/asm/arch-spear/hardware.h b/arch/arm/include/asm/arch-spear/hardware.h
index 39d64b6..9f1e154 100644
--- a/arch/arm/include/asm/arch-spear/hardware.h
+++ b/arch/arm/include/asm/arch-spear/hardware.h
@@ -56,6 +56,11 @@
 #define CONFIG_SPEAR_EMIBASE			(0x4F000000)
 #define CONFIG_SPEAR_RASBASE			(0xB4000000)
 
+#define CONFIG_SYS_MACB0_BASE			(0xB0000000)
+#define CONFIG_SYS_MACB1_BASE			(0xB0800000)
+#define CONFIG_SYS_MACB2_BASE			(0xB1000000)
+#define CONFIG_SYS_MACB3_BASE			(0xB1800000)
+
 #elif defined(CONFIG_SPEAR320)
 #define CONFIG_SYS_I2C_BASE			(0xD0180000)
 #define CONFIG_SPEAR_FSMCBASE			(0x4C000000)
@@ -63,5 +68,7 @@
 #define CONFIG_SPEAR_EMIBASE			(0x40000000)
 #define CONFIG_SPEAR_RASBASE			(0xB3000000)
 
+#define CONFIG_SYS_MACB0_BASE			(0xAA000000)
+
 #endif
 #endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c
index e8a6552..1207709 100644
--- a/board/spear/spear310/spear310.c
+++ b/board/spear/spear310/spear310.c
@@ -61,5 +61,12 @@ int board_nand_init(struct nand_chip *nand)
 
 int board_eth_init(bd_t *bis)
 {
-	return dw_mii_initialize(0, CONFIG_SPEAR_ETHBASE);
+	dw_mii_initialize(0, CONFIG_SPEAR_ETHBASE);
+
+	macb_eth_initialize(0, (void *)CONFIG_SYS_MACB0_BASE, CONFIG_MACB0_PHY);
+	macb_eth_initialize(1, (void *)CONFIG_SYS_MACB1_BASE, CONFIG_MACB1_PHY);
+	macb_eth_initialize(2, (void *)CONFIG_SYS_MACB2_BASE, CONFIG_MACB2_PHY);
+	macb_eth_initialize(3, (void *)CONFIG_SYS_MACB3_BASE, CONFIG_MACB3_PHY);
+
+	return 0;
 }
diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c
index 72bc9a5..efc9a99 100644
--- a/board/spear/spear320/spear320.c
+++ b/board/spear/spear320/spear320.c
@@ -61,5 +61,9 @@ int board_nand_init(struct nand_chip *nand)
 
 int board_eth_init(bd_t *bis)
 {
-	return dw_mii_initialize(0, CONFIG_SPEAR_ETHBASE);
+	dw_mii_initialize(0, CONFIG_SPEAR_ETHBASE);
+
+	macb_eth_initialize(0, (void *)CONFIG_SYS_MACB0_BASE, CONFIG_MACB0_PHY);
+
+	return 0;
 }
diff --git a/include/asm-arm/arch-spear/clk.h b/include/asm-arm/arch-spear/clk.h
new file mode 100644
index 0000000..343c6ce
--- /dev/null
+++ b/include/asm-arm/arch-spear/clk.h
@@ -0,0 +1,27 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, STMicroelectronics, <vipin.kumar@st.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+static inline unsigned long get_macb_pclk_rate(unsigned int dev_id)
+{
+	return 83000000;
+}
diff --git a/include/configs/spear3xx.h b/include/configs/spear3xx.h
index f077213..c53f3cc 100644
--- a/include/configs/spear3xx.h
+++ b/include/configs/spear3xx.h
@@ -44,6 +44,19 @@
 /* Ethernet driver configuration */
 #define CONFIG_DW_ALTDESC			1
 
+#if defined(CONFIG_SPEAR310)
+#define CONFIG_MACB				1
+#define CONFIG_MACB0_PHY			0x01
+#define CONFIG_MACB1_PHY			0x03
+#define CONFIG_MACB2_PHY			0x05
+#define CONFIG_MACB3_PHY			0x07
+
+#elif defined(CONFIG_SPEAR320)
+#define CONFIG_MACB				1
+#define CONFIG_MACB0_PHY			0x01
+
+#endif
+
 /* Serial Configuration (PL011) */
 #define CONFIG_SYS_SERIAL0			0xD0000000
 
-- 
1.6.0.2

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

* [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added
  2010-04-21  7:54                 ` [U-Boot] [PATCH 09/17] SPEAr : macb driver support added for spear310 and spear320 Vipin KUMAR
@ 2010-04-21  7:54                   ` Vipin KUMAR
  2010-04-21  7:54                     ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Vipin KUMAR
  2010-04-21 17:02                     ` [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added Scott Wood
  0 siblings, 2 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

Flexible static memory controller is an IP which controls the access
to NAND chips along with many other memory device chips eg NOR, SRAM.
This is an ST peripheral. This patch adds the driver support for FSMC
controller interfacing with NAND memory.

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 drivers/mtd/nand/Makefile    |    1 +
 drivers/mtd/nand/fsmc_nand.c |  363 ++++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/nand/fsmc_nand.h |  104 ++++++++++++
 3 files changed, 468 insertions(+), 0 deletions(-)
 create mode 100755 drivers/mtd/nand/fsmc_nand.c
 create mode 100644 drivers/mtd/nand/fsmc_nand.h

diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 28f27da..4c6b54f 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -38,6 +38,7 @@ COBJS-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o
 COBJS-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
 COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
 COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
+COBJS-$(CONFIG_NAND_FSMC) += fsmc_nand.o
 COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
 COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
 COBJS-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
new file mode 100755
index 0000000..bd35c5b
--- /dev/null
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -0,0 +1,363 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <nand.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/mtd/nand_ecc.h>
+#include <asm/arch/hardware.h>
+#include "fsmc_nand.h"
+
+static u32 fsmc_version;
+static struct fsmc_regs *const fsmc_regs_p =
+    (struct fsmc_regs *)CONFIG_SYS_FSMC_BASE;
+
+#if defined(CONFIG_BOARD_NAND_LP)
+static struct nand_ecclayout fsmc_ecc13_layout = {
+	.eccbytes = 104,
+	.eccpos = {  2,   3,   4,   5,   6,   7,   8,
+		9,  10,  11,  12,  13,  14,
+		18,  19,  20,  21,  22,  23,  24,
+		25,  26,  27,  28,  29,  30,
+		34,  35,  36,  37,  38,  39,  40,
+		41,  42,  43,  44,  45,  46,
+		50,  51,  52,  53,  54,  55,  56,
+		57,  58,  59,  60,  61,  62,
+		66,  67,  68,  69,  70,  71,  72,
+		73,  74,  75,  76,  77,  78,
+		82,  83,  84,  85,  86,  87,  88,
+		89,  90,  91,  92,  93,  94,
+		98,  99, 100, 101, 102, 103, 104,
+		105, 106, 107, 108, 109, 110,
+		114, 115, 116, 117, 118, 119, 120,
+		121, 122, 123, 124, 125, 126
+	},
+	.oobfree = {
+		{.offset = 15, .length = 3},
+		{.offset = 31, .length = 3},
+		{.offset = 47, .length = 3},
+		{.offset = 63, .length = 3},
+		{.offset = 79, .length = 3},
+		{.offset = 95, .length = 3},
+		{.offset = 111, .length = 3},
+		{.offset = 127, .length = 1}
+	}
+};
+
+/*
+ * ECC placement definitions in oobfree type format
+ * There are 13 bytes of ecc for every 512 byte block and it has to be read
+ * consicutively and immidiately after the 512 byte data block for hardware to
+ * generate the error bit offsets in 512 byte data
+ * Managing the ecc bytes in the following way makes it easier for software to
+ * read ecc bytes consicutive to data bytes. This way is similar to
+ * oobfree structure maintained already in u-boot nand driver
+ */
+static struct fsmc_eccplace fsmc_eccpl = {
+	.eccplace = {
+		{.offset = 2, .length = 13},
+		{.offset = 18, .length = 13},
+		{.offset = 34, .length = 13},
+		{.offset = 50, .length = 13},
+		{.offset = 66, .length = 13},
+		{.offset = 82, .length = 13},
+		{.offset = 98, .length = 13},
+		{.offset = 114, .length = 13}
+	}
+};
+
+#elif defined(CONFIG_BOARD_NAND_SP)
+static struct nand_ecclayout fsmc_ecc13_layout = {
+	.eccbytes = 13,
+	.eccpos = { 0,  1,  2,  3,  6,  7, 8,
+		9, 10, 11, 12, 13, 14
+	},
+	.oobfree = {
+		{.offset = 15, .length = 1},
+	}
+};
+
+static struct fsmc_eccplace fsmc_eccpl = {
+	.eccplace = {
+		    {.offset = 0, .length = 4},
+		    {.offset = 6, .length = 9}
+		    }
+};
+
+#else
+#error Please define one of CONFIG_BOARD_NAND_SP or CONFIG_BOARD_NAND_LP
+#endif
+
+static struct nand_ecclayout fsmc_ecc3_layout = {
+	.eccbytes = 24,
+	.eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
+		   66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
+	.oobfree = {
+		    {.offset = 8, .length = 8},
+		    {.offset = 24, .length = 8},
+		    {.offset = 40, .length = 8},
+		    {.offset = 56, .length = 8},
+		    {.offset = 72, .length = 8},
+		    {.offset = 88, .length = 8},
+		    {.offset = 104, .length = 8},
+		    {.offset = 120, .length = 8}
+		    }
+};
+
+static void fsmc_nand_hwcontrol(struct mtd_info *mtd, int cmd, uint ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	ulong IO_ADDR_W;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		IO_ADDR_W = (ulong)this->IO_ADDR_W;
+
+		IO_ADDR_W &= ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE);
+		if (ctrl & NAND_CLE)
+			IO_ADDR_W |= CONFIG_SYS_NAND_CLE;
+		if (ctrl & NAND_ALE)
+			IO_ADDR_W |= CONFIG_SYS_NAND_ALE;
+
+		if (ctrl & NAND_NCE) {
+			writel(readl(&fsmc_regs_p->genmemctrl_pc) |
+			       FSMC_ENABLE, &fsmc_regs_p->genmemctrl_pc);
+		} else {
+			writel(readl(&fsmc_regs_p->genmemctrl_pc) &
+			       ~FSMC_ENABLE, &fsmc_regs_p->genmemctrl_pc);
+		}
+		this->IO_ADDR_W = (void *)IO_ADDR_W;
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
+}
+
+static int fsmc_correct_data(struct mtd_info *mtd, u_char *dat,
+		      u_char *read_ecc, u_char *calc_ecc)
+{
+	/* The calculated ecc is actually the correction index in data */
+	u16 err_idx[8];
+	u64 ecc_data[2];
+	u32 num_err, i = 0;
+
+	memcpy(ecc_data, calc_ecc, 13);
+	err_idx[0] = (ecc_data[0] & 0x1FFF);
+	ecc_data[0] >>= 13;
+	err_idx[1] = (ecc_data[0] & 0x1FFF);
+	ecc_data[0] >>= 13;
+	err_idx[2] = (ecc_data[0] & 0x1FFF);
+	ecc_data[0] >>= 13;
+	err_idx[3] = (ecc_data[0] & 0x1FFF);
+	ecc_data[0] >>= 13;
+	err_idx[4] = ((ecc_data[1] & 0x1) << 12) | ecc_data[0];
+	ecc_data[1] >>= 1;
+	err_idx[5] = (ecc_data[1] & 0x1FFF);
+	ecc_data[1] >>= 13;
+	err_idx[6] = (ecc_data[1] & 0x1FFF);
+	ecc_data[1] >>= 13;
+	err_idx[7] = (ecc_data[1] & 0x1FFF);
+
+	num_err = (readl(&fsmc_regs_p->genmemctrl_sts) >> 10) & 0xF;
+
+	if (num_err == 0xF)
+		return -EBADMSG;
+
+	while (num_err--) {
+		change_bit(0, &err_idx[i]);
+		change_bit(1, &err_idx[i]);
+
+		if (err_idx[i] <= 512 * 8) {
+			change_bit(err_idx[i], dat);
+			i++;
+		}
+	}
+	return i;
+}
+
+static int fsmc_read_hwecc(struct mtd_info *mtd,
+			    const u_char *data, u_char *ecc)
+{
+	u_int ecc_tmp;
+
+	switch (fsmc_version) {
+	case FSMC_VER8:
+		while (!(readl(&fsmc_regs_p->genmemctrl_sts) & FSMC_CODE_RDY))
+			;
+
+		ecc_tmp = readl(&fsmc_regs_p->genmemctrl_ecc1);
+		ecc[0] = (u_char) (ecc_tmp >> 0);
+		ecc[1] = (u_char) (ecc_tmp >> 8);
+		ecc[2] = (u_char) (ecc_tmp >> 16);
+		ecc[3] = (u_char) (ecc_tmp >> 24);
+
+		ecc_tmp = readl(&fsmc_regs_p->genmemctrl_ecc2);
+		ecc[4] = (u_char) (ecc_tmp >> 0);
+		ecc[5] = (u_char) (ecc_tmp >> 8);
+		ecc[6] = (u_char) (ecc_tmp >> 16);
+		ecc[7] = (u_char) (ecc_tmp >> 24);
+
+		ecc_tmp = readl(&fsmc_regs_p->genmemctrl_ecc3);
+		ecc[8] = (u_char) (ecc_tmp >> 0);
+		ecc[9] = (u_char) (ecc_tmp >> 8);
+		ecc[10] = (u_char) (ecc_tmp >> 16);
+		ecc[11] = (u_char) (ecc_tmp >> 24);
+
+		ecc_tmp = readl(&fsmc_regs_p->genmemctrl_sts);
+		ecc[12] = (u_char) (ecc_tmp >> 16);
+		break;
+
+	default:
+		ecc_tmp = readl(&fsmc_regs_p->genmemctrl_ecc1);
+		ecc[0] = (u_char) (ecc_tmp >> 0);
+		ecc[1] = (u_char) (ecc_tmp >> 8);
+		ecc[2] = (u_char) (ecc_tmp >> 16);
+		break;
+	}
+
+	return 0;
+}
+
+void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	writel(readl(&fsmc_regs_p->genmemctrl_pc) & ~FSMC_ECCPLEN_256,
+	       &fsmc_regs_p->genmemctrl_pc);
+	writel(readl(&fsmc_regs_p->genmemctrl_pc) & ~FSMC_ECCEN,
+	       &fsmc_regs_p->genmemctrl_pc);
+	writel(readl(&fsmc_regs_p->genmemctrl_pc) | FSMC_ECCEN,
+	       &fsmc_regs_p->genmemctrl_pc);
+}
+
+/**
+ * fsmc_read_page_hwecc
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ *
+ * This routine is needed for fsmc verison 8 as reading from NAND chip has to be
+ * performed in a strict sequence as follows:
+ * data(512 byte) -> ecc(13 byte)
+ * After this read, fsmc hardware generates and reports error data bits(upto a
+ * max of 8 bits)
+ */
+static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+				 uint8_t *buf, int page)
+{
+	int i, j, s, stat, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *p = buf;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
+	int off, len;
+	/*
+	 * ecc_oob is intentionally taken as u16. In 16bit devices, we end up
+	 * reading 14 bytes (7 words) from oob. The local array is to maintain
+	 * word alignment
+	 */
+	uint16_t ecc_oob[7];
+
+	for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
+
+		chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page);
+		chip->ecc.hwctl(mtd, NAND_ECC_READ);
+		chip->read_buf(mtd, p, eccsize);
+
+		for (j = 0; j < eccbytes;) {
+			off = fsmc_eccpl.eccplace[s].offset;
+			len = fsmc_eccpl.eccplace[s].length;
+
+			/*
+			 * length is intentionally kept a higher multiple of 2
+			 * to read@least 13 bytes even in case of 16 bit NAND
+			 * devices
+			 */
+			len = ((len + 1) >> 1) << 1;
+			chip->cmdfunc(mtd, NAND_CMD_READOOB, off, page);
+			chip->read_buf(mtd, (uint8_t *)&ecc_oob[j], len);
+			j += len;
+		}
+
+		memcpy(&ecc_code[i], ecc_oob, 13);
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+
+	return 0;
+}
+
+int fsmc_nand_init(struct nand_chip *nand)
+{
+	u32 peripid2 = readl(&fsmc_regs_p->genmemctrl_peripid2);
+
+	fsmc_version = (peripid2 >> FSMC_REVISION_SHFT) & \
+		       FSMC_REVISION_MSK;
+#if defined(CONFIG_BOARD_NAND_16BIT)
+	writel(FSMC_DEVWID_16 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON,
+	       &fsmc_regs_p->genmemctrl_pc);
+#elif defined(CONFIG_BOARD_NAND_8BIT)
+	writel(FSMC_DEVWID_8 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON,
+	       &fsmc_regs_p->genmemctrl_pc);
+#else
+#error Please define one of CONFIG_BOARD_NAND_16BIT or CONFIG_BOARD_NAND_8BIT
+#endif
+	writel(readl(&fsmc_regs_p->genmemctrl_pc) | FSMC_TCLR_1 | FSMC_TAR_1,
+	       &fsmc_regs_p->genmemctrl_pc);
+	writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
+	       &fsmc_regs_p->genmemctrl_comm);
+	writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
+	       &fsmc_regs_p->genmemctrl_attrib);
+
+	nand->options = 0;
+#if defined(CONFIG_BOARD_NAND_16BIT)
+	nand->options |= NAND_BUSWIDTH_16;
+#endif
+	nand->ecc.mode = NAND_ECC_HW;
+	nand->ecc.size = 512;
+	nand->ecc.calculate = fsmc_read_hwecc;
+	nand->ecc.hwctl = fsmc_enable_hwecc;
+	nand->cmd_ctrl = fsmc_nand_hwcontrol;
+
+	switch (fsmc_version) {
+	case FSMC_VER8:
+		nand->ecc.bytes = 13;
+		nand->ecc.layout = &fsmc_ecc13_layout;
+		nand->ecc.correct = fsmc_correct_data;
+		nand->ecc.read_page = fsmc_read_page_hwecc;
+		break;
+	default:
+		nand->ecc.bytes = 3;
+		nand->ecc.layout = &fsmc_ecc3_layout;
+		nand->ecc.correct = nand_correct_data;
+		break;
+	}
+
+	return 0;
+}
diff --git a/drivers/mtd/nand/fsmc_nand.h b/drivers/mtd/nand/fsmc_nand.h
new file mode 100644
index 0000000..ffa7718
--- /dev/null
+++ b/drivers/mtd/nand/fsmc_nand.h
@@ -0,0 +1,104 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __FSMC_NAND_H__
+#define __FSMC_NAND_H__
+
+struct fsmc_regs {
+	u8 reserved_1[0x40];
+	u32 genmemctrl_pc;		/* 0x40 */
+	u32 genmemctrl_sts;		/* 0x44 */
+	u32 genmemctrl_comm;		/* 0x48 */
+	u32 genmemctrl_attrib;		/* 0x4c */
+	u32 genmemctrl_ioata;		/* 0x50 */
+	u32 genmemctrl_ecc1;		/* 0x54 */
+	u32 genmemctrl_ecc2;		/* 0x58 */
+	u32 genmemctrl_ecc3;		/* 0x5c */
+	u8 reserved_2[0xfe0 - 0x60];
+	u32 genmemctrl_peripid0;	/* 0xfe0 */
+	u32 genmemctrl_peripid1;	/* 0xfe4 */
+	u32 genmemctrl_peripid2;	/* 0xfe8 */
+	u32 genmemctrl_peripid3;	/* 0xfec */
+	u32 genmemctrl_pcellid0;	/* 0xff0 */
+	u32 genmemctrl_pcellid1;	/* 0xff4 */
+	u32 genmemctrl_pcellid2;	/* 0xff8 */
+	u32 genmemctrl_pcellid3;	/* 0xffc */
+};
+
+/* genmemctrl_pc register definitions */
+#define FSMC_RESET		(1 << 0)
+#define FSMC_WAITON		(1 << 1)
+#define FSMC_ENABLE		(1 << 2)
+#define FSMC_DEVTYPE_NAND	(1 << 3)
+#define FSMC_DEVWID_8		(0 << 4)
+#define FSMC_DEVWID_16		(1 << 4)
+#define FSMC_ECCEN		(1 << 6)
+#define FSMC_ECCPLEN_512	(0 << 7)
+#define FSMC_ECCPLEN_256	(1 << 7)
+#define FSMC_TCLR_1		(1 << 9)
+#define FSMC_TAR_1		(1 << 13)
+
+/* genmemctrl_sts register definitions */
+#define FSMC_CODE_RDY		(1 << 15)
+
+/* genmemctrl_comm register definitions */
+#define FSMC_TSET_0		(0 << 0)
+#define FSMC_TWAIT_6		(6 << 8)
+#define FSMC_THOLD_4		(4 << 16)
+#define FSMC_THIZ_1		(1 << 24)
+
+/* genmemctrl_peripid2 register definitions */
+#define FSMC_REVISION_MSK	(0xf)
+#define FSMC_REVISION_SHFT	(0x4)
+
+enum {
+	FSMC_VER1 = 1,
+	FSMC_VER2,
+	FSMC_VER3,
+	FSMC_VER4,
+	FSMC_VER5,
+	FSMC_VER6,
+	FSMC_VER7,
+	FSMC_VER8,
+};
+
+/*
+ * There are 13 bytes of ecc for every 512 byte block and it has to be read
+ * consicutively and immidiately after the 512 byte data block for hardware to
+ * generate the error bit offsets
+ * Managing the ecc bytes in the following way is easier. This way is similar to
+ * oobfree structure maintained already in u-boot nand driver
+ */
+#define MAX_ECCPLACE_ENTRIES	32
+
+struct fsmc_nand_eccplace {
+	u32 offset;
+	u32 length;
+};
+
+struct fsmc_eccplace {
+	struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES];
+};
+
+extern int spear_nand_init(struct nand_chip *nand);
+#endif
-- 
1.6.0.2

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

* [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface
  2010-04-21  7:54                   ` [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added Vipin KUMAR
@ 2010-04-21  7:54                     ` Vipin KUMAR
  2010-04-21  7:54                       ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Vipin KUMAR
  2010-04-21 17:02                       ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Scott Wood
  2010-04-21 17:02                     ` [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added Scott Wood
  1 sibling, 2 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

Since FSMC is a standard IP and it supports different memory interfaces the FSMC
is supported independent of spear platform and spear is configured to use that
driver for interfacing with the NAND device

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 arch/arm/include/asm/arch-spear/hardware.h |    8 +-
 arch/arm/include/asm/arch-spear/spr_nand.h |   57 -------------
 board/spear/spear300/spear300.c            |    5 +-
 board/spear/spear310/spear310.c            |    5 +-
 board/spear/spear320/spear320.c            |    5 +-
 board/spear/spear600/spear600.c            |    5 +-
 drivers/mtd/nand/Makefile                  |    1 -
 drivers/mtd/nand/spr_nand.c                |  124 ----------------------------
 include/configs/spear-common.h             |    2 +-
 include/configs/spear3xx.h                 |    4 +
 include/configs/spear6xx.h                 |    3 +
 11 files changed, 24 insertions(+), 195 deletions(-)
 delete mode 100644 arch/arm/include/asm/arch-spear/spr_nand.h
 delete mode 100644 drivers/mtd/nand/spr_nand.c

diff --git a/arch/arm/include/asm/arch-spear/hardware.h b/arch/arm/include/asm/arch-spear/hardware.h
index 9f1e154..52037b6 100644
--- a/arch/arm/include/asm/arch-spear/hardware.h
+++ b/arch/arm/include/asm/arch-spear/hardware.h
@@ -38,15 +38,15 @@
 
 #if defined(CONFIG_SPEAR600)
 #define CONFIG_SYS_I2C_BASE			(0xD0200000)
-#define CONFIG_SPEAR_FSMCBASE			(0xD1800000)
+#define CONFIG_SYS_FSMC_BASE			(0xD1800000)
 
 #elif defined(CONFIG_SPEAR300)
 #define CONFIG_SYS_I2C_BASE			(0xD0180000)
-#define CONFIG_SPEAR_FSMCBASE			(0x94000000)
+#define CONFIG_SYS_FSMC_BASE			(0x94000000)
 
 #elif defined(CONFIG_SPEAR310)
 #define CONFIG_SYS_I2C_BASE			(0xD0180000)
-#define CONFIG_SPEAR_FSMCBASE			(0x44000000)
+#define CONFIG_SYS_FSMC_BASE			(0x44000000)
 
 #undef CONFIG_SYS_NAND_CLE
 #undef CONFIG_SYS_NAND_ALE
@@ -63,7 +63,7 @@
 
 #elif defined(CONFIG_SPEAR320)
 #define CONFIG_SYS_I2C_BASE			(0xD0180000)
-#define CONFIG_SPEAR_FSMCBASE			(0x4C000000)
+#define CONFIG_SYS_FSMC_BASE			(0x4C000000)
 
 #define CONFIG_SPEAR_EMIBASE			(0x40000000)
 #define CONFIG_SPEAR_RASBASE			(0xB3000000)
diff --git a/arch/arm/include/asm/arch-spear/spr_nand.h b/arch/arm/include/asm/arch-spear/spr_nand.h
deleted file mode 100644
index 2b63dc7..0000000
--- a/arch/arm/include/asm/arch-spear/spr_nand.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * (C) Copyright 2009
- * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef __SPR_NAND_H__
-#define __SPR_NAND_H__
-
-struct fsmc_regs {
-	u32 reserved_1[0x10];
-	u32 genmemctrl_pc;
-	u32 reserved_2;
-	u32 genmemctrl_comm;
-	u32 genmemctrl_attrib;
-	u32 reserved_3;
-	u32 genmemctrl_ecc;
-};
-
-/* genmemctrl_pc register definitions */
-#define FSMC_RESET		(1 << 0)
-#define FSMC_WAITON		(1 << 1)
-#define FSMC_ENABLE		(1 << 2)
-#define FSMC_DEVTYPE_NAND	(1 << 3)
-#define FSMC_DEVWID_8		(0 << 4)
-#define FSMC_DEVWID_16		(1 << 4)
-#define FSMC_ECCEN		(1 << 6)
-#define FSMC_ECCPLEN_512	(0 << 7)
-#define FSMC_ECCPLEN_256	(1 << 7)
-#define FSMC_TCLR_1		(1 << 9)
-#define FSMC_TAR_1		(1 << 13)
-
-/* genmemctrl_comm register definitions */
-#define FSMC_TSET_0		(0 << 0)
-#define FSMC_TWAIT_6		(6 << 8)
-#define FSMC_THOLD_4		(4 << 16)
-#define FSMC_THIZ_1		(1 << 24)
-
-extern int spear_nand_init(struct nand_chip *nand);
-#endif
diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c
index e58792a..33f0983 100644
--- a/board/spear/spear300/spear300.c
+++ b/board/spear/spear300/spear300.c
@@ -28,7 +28,8 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/spr_defs.h>
 #include <asm/arch/spr_misc.h>
-#include <asm/arch/spr_nand.h>
+
+int fsmc_nand_init(struct nand_chip *nand);
 
 int board_init(void)
 {
@@ -52,7 +53,7 @@ int board_nand_init(struct nand_chip *nand)
 	    ((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) ==
 	     MISC_SOCCFG31)) {
 
-		return spear_nand_init(nand);
+		return fsmc_nand_init(nand);
 	}
 
 	return -1;
diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c
index 1207709..3ac62d1 100644
--- a/board/spear/spear310/spear310.c
+++ b/board/spear/spear310/spear310.c
@@ -29,7 +29,8 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/spr_defs.h>
 #include <asm/arch/spr_misc.h>
-#include <asm/arch/spr_nand.h>
+
+int fsmc_nand_init(struct nand_chip *nand);
 
 int board_init(void)
 {
@@ -53,7 +54,7 @@ int board_nand_init(struct nand_chip *nand)
 	    ((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) ==
 	     MISC_SOCCFG31)) {
 
-		return spear_nand_init(nand);
+		return fsmc_nand_init(nand);
 	}
 
 	return -1;
diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c
index efc9a99..b94ee25 100644
--- a/board/spear/spear320/spear320.c
+++ b/board/spear/spear320/spear320.c
@@ -29,7 +29,8 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/spr_defs.h>
 #include <asm/arch/spr_misc.h>
-#include <asm/arch/spr_nand.h>
+
+int fsmc_nand_init(struct nand_chip *nand);
 
 int board_init(void)
 {
@@ -53,7 +54,7 @@ int board_nand_init(struct nand_chip *nand)
 	    ((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) ==
 	     MISC_SOCCFG31)) {
 
-		return spear_nand_init(nand);
+		return fsmc_nand_init(nand);
 	}
 
 	return -1;
diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c
index b93151e..63c2b41 100644
--- a/board/spear/spear600/spear600.c
+++ b/board/spear/spear600/spear600.c
@@ -28,7 +28,8 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/spr_defs.h>
 #include <asm/arch/spr_misc.h>
-#include <asm/arch/spr_nand.h>
+
+int fsmc_nand_init(struct nand_chip *nand);
 
 int board_init(void)
 {
@@ -48,7 +49,7 @@ int board_nand_init(struct nand_chip *nand)
 	    (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
 
 	if (!(readl(&misc_regs_p->auto_cfg_reg) & MISC_NANDDIS))
-		return spear_nand_init(nand);
+		return fsmc_nand_init(nand);
 
 	return -1;
 }
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 4c6b54f..36fc8b3 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -48,7 +48,6 @@ COBJS-$(CONFIG_NAND_NDFC) += ndfc.o
 COBJS-$(CONFIG_NAND_NOMADIK) += nomadik.o
 COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
 COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
-COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
 endif
diff --git a/drivers/mtd/nand/spr_nand.c b/drivers/mtd/nand/spr_nand.c
deleted file mode 100644
index 097d0c6..0000000
--- a/drivers/mtd/nand/spr_nand.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * (C) Copyright 2009
- * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/spr_nand.h>
-
-static struct fsmc_regs *const fsmc_regs_p =
-    (struct fsmc_regs *)CONFIG_SPEAR_FSMCBASE;
-
-static struct nand_ecclayout spear_nand_ecclayout = {
-	.eccbytes = 24,
-	.eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
-		   66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
-	.oobfree = {
-		    {.offset = 8, .length = 8},
-		    {.offset = 24, .length = 8},
-		    {.offset = 40, .length = 8},
-		    {.offset = 56, .length = 8},
-		    {.offset = 72, .length = 8},
-		    {.offset = 88, .length = 8},
-		    {.offset = 104, .length = 8},
-		    {.offset = 120, .length = 8}
-		    }
-};
-
-static void spear_nand_hwcontrol(struct mtd_info *mtd, int cmd, uint ctrl)
-{
-	struct nand_chip *this = mtd->priv;
-	ulong IO_ADDR_W;
-
-	if (ctrl & NAND_CTRL_CHANGE) {
-		IO_ADDR_W = (ulong)this->IO_ADDR_W;
-
-		IO_ADDR_W &= ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE);
-		if (ctrl & NAND_CLE)
-			IO_ADDR_W |= CONFIG_SYS_NAND_CLE;
-		if (ctrl & NAND_ALE)
-			IO_ADDR_W |= CONFIG_SYS_NAND_ALE;
-
-		if (ctrl & NAND_NCE) {
-			writel(readl(&fsmc_regs_p->genmemctrl_pc) |
-			       FSMC_ENABLE, &fsmc_regs_p->genmemctrl_pc);
-		} else {
-			writel(readl(&fsmc_regs_p->genmemctrl_pc) &
-			       ~FSMC_ENABLE, &fsmc_regs_p->genmemctrl_pc);
-		}
-		this->IO_ADDR_W = (void *)IO_ADDR_W;
-	}
-
-	if (cmd != NAND_CMD_NONE)
-		writeb(cmd, this->IO_ADDR_W);
-}
-
-static int spear_read_hwecc(struct mtd_info *mtd,
-			    const u_char *data, u_char ecc[3])
-{
-	u_int ecc_tmp;
-
-	/* read the h/w ECC */
-	ecc_tmp = readl(&fsmc_regs_p->genmemctrl_ecc);
-
-	ecc[0] = (u_char) (ecc_tmp & 0xFF);
-	ecc[1] = (u_char) ((ecc_tmp & 0xFF00) >> 8);
-	ecc[2] = (u_char) ((ecc_tmp & 0xFF0000) >> 16);
-
-	return 0;
-}
-
-void spear_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-	writel(readl(&fsmc_regs_p->genmemctrl_pc) & ~0x80,
-	       &fsmc_regs_p->genmemctrl_pc);
-	writel(readl(&fsmc_regs_p->genmemctrl_pc) & ~FSMC_ECCEN,
-	       &fsmc_regs_p->genmemctrl_pc);
-	writel(readl(&fsmc_regs_p->genmemctrl_pc) | FSMC_ECCEN,
-	       &fsmc_regs_p->genmemctrl_pc);
-}
-
-int spear_nand_init(struct nand_chip *nand)
-{
-	writel(FSMC_DEVWID_8 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON,
-	       &fsmc_regs_p->genmemctrl_pc);
-	writel(readl(&fsmc_regs_p->genmemctrl_pc) | FSMC_TCLR_1 | FSMC_TAR_1,
-	       &fsmc_regs_p->genmemctrl_pc);
-	writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
-	       &fsmc_regs_p->genmemctrl_comm);
-	writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
-	       &fsmc_regs_p->genmemctrl_attrib);
-
-	nand->options = 0;
-	nand->ecc.mode = NAND_ECC_HW;
-	nand->ecc.layout = &spear_nand_ecclayout;
-	nand->ecc.size = 512;
-	nand->ecc.bytes = 3;
-	nand->ecc.calculate = spear_read_hwecc;
-	nand->ecc.hwctl = spear_enable_hwecc;
-	nand->ecc.correct = nand_correct_data;
-	nand->cmd_ctrl = spear_nand_hwcontrol;
-	return 0;
-}
diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
index e7905b1..1e8d9d4 100644
--- a/include/configs/spear-common.h
+++ b/include/configs/spear-common.h
@@ -90,7 +90,7 @@
 #define CONFIG_SYS_LOADS_BAUD_CHANGE
 
 /* NAND FLASH Configuration */
-#define CONFIG_NAND_SPEAR			1
+#define CONFIG_NAND_FSMC			1
 #define CONFIG_SYS_MAX_NAND_DEVICE		1
 #define CONFIG_MTD_NAND_VERIFY_WRITE		1
 
diff --git a/include/configs/spear3xx.h b/include/configs/spear3xx.h
index c53f3cc..581f28d 100644
--- a/include/configs/spear3xx.h
+++ b/include/configs/spear3xx.h
@@ -133,6 +133,10 @@
 
 #endif
 
+/* NAND flash configuration */
+#define CONFIG_BOARD_NAND_SP			1
+#define CONFIG_BOARD_NAND_8BIT			1
+
 #if defined(CONFIG_SPEAR300)
 #define CONFIG_SYS_NAND_BASE			(0x80000000)
 
diff --git a/include/configs/spear6xx.h b/include/configs/spear6xx.h
index 2ad5beb..24a6948 100644
--- a/include/configs/spear6xx.h
+++ b/include/configs/spear6xx.h
@@ -38,6 +38,9 @@
 #define CONFIG_PL01x_PORTS			{ (void *)CONFIG_SYS_SERIAL0, \
 						(void *)CONFIG_SYS_SERIAL1 }
 
+/* NAND flash configuration */
+#define CONFIG_BOARD_NAND_SP			1
+#define CONFIG_BOARD_NAND_8BIT			1
 #define CONFIG_SYS_NAND_BASE			(0xD2000000)
 
 #endif  /* __CONFIG_H */
-- 
1.6.0.2

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

* [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c
  2010-04-21  7:54                     ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Vipin KUMAR
@ 2010-04-21  7:54                       ` Vipin KUMAR
  2010-04-21  7:54                         ` [U-Boot] [PATCH 13/17] SPEAr : smi driver moved completely into drivers/mtd Vipin KUMAR
  2010-04-21 12:11                         ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Peter Tyser
  2010-04-21 17:02                       ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Scott Wood
  1 sibling, 2 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

The i2c IP used by spear platform is a synopsys i2c controller
The earlier driver adds the driver of this controller as if it is specific to
spear platform.
The driver files are now moved into drivers/i2c folder for reusability by other
platforms

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 arch/arm/include/asm/arch-spear/spr_i2c.h |  146 -------------
 drivers/i2c/Makefile                      |    2 +-
 drivers/i2c/dw_i2c.c                      |  331 +++++++++++++++++++++++++++++
 drivers/i2c/dw_i2c.h                      |  146 +++++++++++++
 drivers/i2c/spr_i2c.c                     |  331 -----------------------------
 include/configs/spear-common.h            |    2 +-
 6 files changed, 479 insertions(+), 479 deletions(-)
 delete mode 100644 arch/arm/include/asm/arch-spear/spr_i2c.h
 create mode 100644 drivers/i2c/dw_i2c.c
 create mode 100644 drivers/i2c/dw_i2c.h
 delete mode 100644 drivers/i2c/spr_i2c.c

diff --git a/arch/arm/include/asm/arch-spear/spr_i2c.h b/arch/arm/include/asm/arch-spear/spr_i2c.h
deleted file mode 100644
index 7521ebc..0000000
--- a/arch/arm/include/asm/arch-spear/spr_i2c.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * (C) Copyright 2009
- * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef __SPR_I2C_H_
-#define __SPR_I2C_H_
-
-struct i2c_regs {
-	u32 ic_con;
-	u32 ic_tar;
-	u32 ic_sar;
-	u32 ic_hs_maddr;
-	u32 ic_cmd_data;
-	u32 ic_ss_scl_hcnt;
-	u32 ic_ss_scl_lcnt;
-	u32 ic_fs_scl_hcnt;
-	u32 ic_fs_scl_lcnt;
-	u32 ic_hs_scl_hcnt;
-	u32 ic_hs_scl_lcnt;
-	u32 ic_intr_stat;
-	u32 ic_intr_mask;
-	u32 ic_raw_intr_stat;
-	u32 ic_rx_tl;
-	u32 ic_tx_tl;
-	u32 ic_clr_intr;
-	u32 ic_clr_rx_under;
-	u32 ic_clr_rx_over;
-	u32 ic_clr_tx_over;
-	u32 ic_clr_rd_req;
-	u32 ic_clr_tx_abrt;
-	u32 ic_clr_rx_done;
-	u32 ic_clr_activity;
-	u32 ic_clr_stop_det;
-	u32 ic_clr_start_det;
-	u32 ic_clr_gen_call;
-	u32 ic_enable;
-	u32 ic_status;
-	u32 ic_txflr;
-	u32 ix_rxflr;
-	u32 reserved_1;
-	u32 ic_tx_abrt_source;
-};
-
-#define IC_CLK			166
-#define NANO_TO_MICRO		1000
-
-/* High and low times in different speed modes (in ns) */
-#define MIN_SS_SCL_HIGHTIME	4000
-#define MIN_SS_SCL_LOWTIME	5000
-#define MIN_FS_SCL_HIGHTIME	800
-#define MIN_FS_SCL_LOWTIME	1700
-#define MIN_HS_SCL_HIGHTIME	60
-#define MIN_HS_SCL_LOWTIME	160
-
-/* Worst case timeout for 1 byte is kept as 2ms */
-#define I2C_BYTE_TO		(CONFIG_SYS_HZ/500)
-#define I2C_STOPDET_TO		(CONFIG_SYS_HZ/500)
-#define I2C_BYTE_TO_BB		(I2C_BYTE_TO * 16)
-
-/* i2c control register definitions */
-#define IC_CON_SD		0x0040
-#define IC_CON_RE		0x0020
-#define IC_CON_10BITADDRMASTER	0x0010
-#define IC_CON_10BITADDR_SLAVE	0x0008
-#define IC_CON_SPD_MSK		0x0006
-#define IC_CON_SPD_SS		0x0002
-#define IC_CON_SPD_FS		0x0004
-#define IC_CON_SPD_HS		0x0006
-#define IC_CON_MM		0x0001
-
-/* i2c target address register definitions */
-#define TAR_ADDR		0x0050
-
-/* i2c slave address register definitions */
-#define IC_SLAVE_ADDR		0x0002
-
-/* i2c data buffer and command register definitions */
-#define IC_CMD			0x0100
-
-/* i2c interrupt status register definitions */
-#define IC_GEN_CALL		0x0800
-#define IC_START_DET		0x0400
-#define IC_STOP_DET		0x0200
-#define IC_ACTIVITY		0x0100
-#define IC_RX_DONE		0x0080
-#define IC_TX_ABRT		0x0040
-#define IC_RD_REQ		0x0020
-#define IC_TX_EMPTY		0x0010
-#define IC_TX_OVER		0x0008
-#define IC_RX_FULL		0x0004
-#define IC_RX_OVER 		0x0002
-#define IC_RX_UNDER		0x0001
-
-/* fifo threshold register definitions */
-#define IC_TL0			0x00
-#define IC_TL1			0x01
-#define IC_TL2			0x02
-#define IC_TL3			0x03
-#define IC_TL4			0x04
-#define IC_TL5			0x05
-#define IC_TL6			0x06
-#define IC_TL7			0x07
-#define IC_RX_TL		IC_TL0
-#define IC_TX_TL		IC_TL0
-
-/* i2c enable register definitions */
-#define IC_ENABLE_0B		0x0001
-
-/* i2c status register  definitions */
-#define IC_STATUS_SA		0x0040
-#define IC_STATUS_MA		0x0020
-#define IC_STATUS_RFF		0x0010
-#define IC_STATUS_RFNE		0x0008
-#define IC_STATUS_TFE		0x0004
-#define IC_STATUS_TFNF		0x0002
-#define IC_STATUS_ACT		0x0001
-
-/* Speed Selection */
-#define IC_SPEED_MODE_STANDARD	1
-#define IC_SPEED_MODE_FAST	2
-#define IC_SPEED_MODE_MAX	3
-
-#define I2C_MAX_SPEED		3400000
-#define I2C_FAST_SPEED		400000
-#define I2C_STANDARD_SPEED	100000
-
-#endif /* __SPR_I2C_H_ */
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index d2c2515..3413567 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -38,7 +38,7 @@ COBJS-$(CONFIG_PPC4XX_I2C) += ppc4xx_i2c.o
 COBJS-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o
 COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
 COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
-COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
+COBJS-$(CONFIG_DW_I2C) += dw_i2c.o
 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
 
 COBJS	:= $(COBJS-y)
diff --git a/drivers/i2c/dw_i2c.c b/drivers/i2c/dw_i2c.c
new file mode 100644
index 0000000..f36464b
--- /dev/null
+++ b/drivers/i2c/dw_i2c.c
@@ -0,0 +1,331 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include "dw_i2c.h"
+
+static struct i2c_regs *const i2c_regs_p =
+    (struct i2c_regs *)CONFIG_SYS_I2C_BASE;
+
+/*
+ * set_speed - Set the i2c speed mode (standard, high, fast)
+ * @i2c_spd:	required i2c speed mode
+ *
+ * Set the i2c speed mode (standard, high, fast)
+ */
+static void set_speed(int i2c_spd)
+{
+	unsigned int cntl;
+	unsigned int hcnt, lcnt;
+	unsigned int high, low;
+
+	cntl = (readl(&i2c_regs_p->ic_con) & (~IC_CON_SPD_MSK));
+
+	switch (i2c_spd) {
+	case IC_SPEED_MODE_MAX:
+		cntl |= IC_CON_SPD_HS;
+		high = MIN_HS_SCL_HIGHTIME;
+		low = MIN_HS_SCL_LOWTIME;
+		break;
+
+	case IC_SPEED_MODE_STANDARD:
+		cntl |= IC_CON_SPD_SS;
+		high = MIN_SS_SCL_HIGHTIME;
+		low = MIN_SS_SCL_LOWTIME;
+		break;
+
+	case IC_SPEED_MODE_FAST:
+	default:
+		cntl |= IC_CON_SPD_FS;
+		high = MIN_FS_SCL_HIGHTIME;
+		low = MIN_FS_SCL_LOWTIME;
+		break;
+	}
+
+	writel(cntl, &i2c_regs_p->ic_con);
+
+	hcnt = (IC_CLK * high) / NANO_TO_MICRO;
+	writel(hcnt, &i2c_regs_p->ic_fs_scl_hcnt);
+
+	lcnt = (IC_CLK * low) / NANO_TO_MICRO;
+	writel(lcnt, &i2c_regs_p->ic_fs_scl_lcnt);
+}
+
+/*
+ * i2c_set_bus_speed - Set the i2c speed
+ * @speed:	required i2c speed
+ *
+ * Set the i2c speed.
+ */
+void i2c_set_bus_speed(int speed)
+{
+	if (speed >= I2C_MAX_SPEED)
+		set_speed(IC_SPEED_MODE_MAX);
+	else if (speed >= I2C_FAST_SPEED)
+		set_speed(IC_SPEED_MODE_FAST);
+	else
+		set_speed(IC_SPEED_MODE_STANDARD);
+}
+
+/*
+ * i2c_get_bus_speed - Gets the i2c speed
+ *
+ * Gets the i2c speed.
+ */
+int i2c_get_bus_speed(void)
+{
+	u32 cntl;
+
+	cntl = (readl(&i2c_regs_p->ic_con) & IC_CON_SPD_MSK);
+
+	if (cntl == IC_CON_SPD_HS)
+		return I2C_MAX_SPEED;
+	else if (cntl == IC_CON_SPD_FS)
+		return I2C_FAST_SPEED;
+	else if (cntl == IC_CON_SPD_SS)
+		return I2C_STANDARD_SPEED;
+
+	return 0;
+}
+
+/*
+ * i2c_init - Init function
+ * @speed:	required i2c speed
+ * @slaveadd:	slave address for the device
+ *
+ * Initialization function.
+ */
+void i2c_init(int speed, int slaveadd)
+{
+	unsigned int enbl;
+
+	/* Disable i2c */
+	enbl = readl(&i2c_regs_p->ic_enable);
+	enbl &= ~IC_ENABLE_0B;
+	writel(enbl, &i2c_regs_p->ic_enable);
+
+	writel((IC_CON_SD | IC_CON_SPD_FS | IC_CON_MM), &i2c_regs_p->ic_con);
+	writel(IC_RX_TL, &i2c_regs_p->ic_rx_tl);
+	writel(IC_TX_TL, &i2c_regs_p->ic_tx_tl);
+	i2c_set_bus_speed(speed);
+	writel(IC_STOP_DET, &i2c_regs_p->ic_intr_mask);
+	writel(slaveadd, &i2c_regs_p->ic_sar);
+
+	/* Enable i2c */
+	enbl = readl(&i2c_regs_p->ic_enable);
+	enbl |= IC_ENABLE_0B;
+	writel(enbl, &i2c_regs_p->ic_enable);
+}
+
+/*
+ * i2c_setaddress - Sets the target slave address
+ * @i2c_addr:	target i2c address
+ *
+ * Sets the target slave address.
+ */
+static void i2c_setaddress(unsigned int i2c_addr)
+{
+	writel(i2c_addr, &i2c_regs_p->ic_tar);
+}
+
+/*
+ * i2c_flush_rxfifo - Flushes the i2c RX FIFO
+ *
+ * Flushes the i2c RX FIFO
+ */
+static void i2c_flush_rxfifo(void)
+{
+	while (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE)
+		readl(&i2c_regs_p->ic_cmd_data);
+}
+
+/*
+ * i2c_wait_for_bb - Waits for bus busy
+ *
+ * Waits for bus busy
+ */
+static int i2c_wait_for_bb(void)
+{
+	unsigned long start_time_bb = get_timer(0);
+
+	while ((readl(&i2c_regs_p->ic_status) & IC_STATUS_MA) ||
+	       !(readl(&i2c_regs_p->ic_status) & IC_STATUS_TFE)) {
+
+		/* Evaluate timeout */
+		if (get_timer(start_time_bb) > (unsigned long)(I2C_BYTE_TO_BB))
+			return 1;
+	}
+
+	return 0;
+}
+
+/* check parameters for i2c_read and i2c_write */
+static int check_params(uint addr, int alen, uchar *buffer, int len)
+{
+	if (buffer == NULL) {
+		printf("Buffer is invalid\n");
+		return 1;
+	}
+
+	if (alen > 1) {
+		printf("addr len %d not supported\n", alen);
+		return 1;
+	}
+
+	if (addr + len > 256) {
+		printf("address out of range\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+static int i2c_xfer_init(uchar chip, uint addr)
+{
+	if (i2c_wait_for_bb()) {
+		printf("Timed out waiting for bus\n");
+		return 1;
+	}
+
+	i2c_setaddress(chip);
+	writel(addr, &i2c_regs_p->ic_cmd_data);
+
+	return 0;
+}
+
+static int i2c_xfer_finish(void)
+{
+	ulong start_stop_det = get_timer(0);
+
+	while (1) {
+		if ((readl(&i2c_regs_p->ic_raw_intr_stat) & IC_STOP_DET)) {
+			readl(&i2c_regs_p->ic_clr_stop_det);
+			break;
+		} else if (get_timer(start_stop_det) > I2C_STOPDET_TO) {
+			break;
+		}
+	}
+
+	if (i2c_wait_for_bb()) {
+		printf("Timed out waiting for bus\n");
+		return 1;
+	}
+
+	i2c_flush_rxfifo();
+
+	/* Wait for read/write operation to complete on actual memory */
+	udelay(10000);
+
+	return 0;
+}
+
+/*
+ * i2c_read - Read from i2c memory
+ * @chip:	target i2c address
+ * @addr:	address to read from
+ * @alen:
+ * @buffer:	buffer for read data
+ * @len:	no of bytes to be read
+ *
+ * Read from i2c memory.
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	unsigned long start_time_rx;
+
+	if (check_params(addr, alen, buffer, len))
+		return 1;
+
+	if (i2c_xfer_init(chip, addr))
+		return 1;
+
+	start_time_rx = get_timer(0);
+	while (len) {
+		writel(IC_CMD, &i2c_regs_p->ic_cmd_data);
+
+		if (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE) {
+			*buffer++ = (uchar)readl(&i2c_regs_p->ic_cmd_data);
+			len--;
+			start_time_rx = get_timer(0);
+
+		} else if (get_timer(start_time_rx) > I2C_BYTE_TO) {
+				printf("Timed out. i2c read Failed\n");
+				return 1;
+		}
+	}
+
+	return i2c_xfer_finish();
+}
+
+/*
+ * i2c_write - Write to i2c memory
+ * @chip:	target i2c address
+ * @addr:	address to read from
+ * @alen:
+ * @buffer:	buffer for read data
+ * @len:	no of bytes to be read
+ *
+ * Write to i2c memory.
+ */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int nb = len;
+	unsigned long start_time_tx;
+
+	if (check_params(addr, alen, buffer, len))
+		return 1;
+
+	if (i2c_xfer_init(chip, addr))
+		return 1;
+
+	start_time_tx = get_timer(0);
+	while (len) {
+		if (readl(&i2c_regs_p->ic_status) & IC_STATUS_TFNF) {
+			writel(*buffer, &i2c_regs_p->ic_cmd_data);
+			buffer++;
+			len--;
+			start_time_tx = get_timer(0);
+
+		} else if (get_timer(start_time_tx) > (nb * I2C_BYTE_TO)) {
+				printf("Timed out. i2c write Failed\n");
+				return 1;
+		}
+	}
+
+	return i2c_xfer_finish();
+}
+
+/*
+ * i2c_probe - Probe the i2c chip
+ */
+int i2c_probe(uchar chip)
+{
+	u32 tmp;
+
+	/*
+	 * Try to read the first location of the chip.
+	 */
+	return i2c_read(chip, 0, 1, (uchar *)&tmp, 1);
+}
diff --git a/drivers/i2c/dw_i2c.h b/drivers/i2c/dw_i2c.h
new file mode 100644
index 0000000..03b520e
--- /dev/null
+++ b/drivers/i2c/dw_i2c.h
@@ -0,0 +1,146 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __DW_I2C_H_
+#define __DW_I2C_H_
+
+struct i2c_regs {
+	u32 ic_con;
+	u32 ic_tar;
+	u32 ic_sar;
+	u32 ic_hs_maddr;
+	u32 ic_cmd_data;
+	u32 ic_ss_scl_hcnt;
+	u32 ic_ss_scl_lcnt;
+	u32 ic_fs_scl_hcnt;
+	u32 ic_fs_scl_lcnt;
+	u32 ic_hs_scl_hcnt;
+	u32 ic_hs_scl_lcnt;
+	u32 ic_intr_stat;
+	u32 ic_intr_mask;
+	u32 ic_raw_intr_stat;
+	u32 ic_rx_tl;
+	u32 ic_tx_tl;
+	u32 ic_clr_intr;
+	u32 ic_clr_rx_under;
+	u32 ic_clr_rx_over;
+	u32 ic_clr_tx_over;
+	u32 ic_clr_rd_req;
+	u32 ic_clr_tx_abrt;
+	u32 ic_clr_rx_done;
+	u32 ic_clr_activity;
+	u32 ic_clr_stop_det;
+	u32 ic_clr_start_det;
+	u32 ic_clr_gen_call;
+	u32 ic_enable;
+	u32 ic_status;
+	u32 ic_txflr;
+	u32 ix_rxflr;
+	u32 reserved_1;
+	u32 ic_tx_abrt_source;
+};
+
+#define IC_CLK			166
+#define NANO_TO_MICRO		1000
+
+/* High and low times in different speed modes (in ns) */
+#define MIN_SS_SCL_HIGHTIME	4000
+#define MIN_SS_SCL_LOWTIME	5000
+#define MIN_FS_SCL_HIGHTIME	800
+#define MIN_FS_SCL_LOWTIME	1700
+#define MIN_HS_SCL_HIGHTIME	60
+#define MIN_HS_SCL_LOWTIME	160
+
+/* Worst case timeout for 1 byte is kept as 2ms */
+#define I2C_BYTE_TO		(CONFIG_SYS_HZ/500)
+#define I2C_STOPDET_TO		(CONFIG_SYS_HZ/500)
+#define I2C_BYTE_TO_BB		(I2C_BYTE_TO * 16)
+
+/* i2c control register definitions */
+#define IC_CON_SD		0x0040
+#define IC_CON_RE		0x0020
+#define IC_CON_10BITADDRMASTER	0x0010
+#define IC_CON_10BITADDR_SLAVE	0x0008
+#define IC_CON_SPD_MSK		0x0006
+#define IC_CON_SPD_SS		0x0002
+#define IC_CON_SPD_FS		0x0004
+#define IC_CON_SPD_HS		0x0006
+#define IC_CON_MM		0x0001
+
+/* i2c target address register definitions */
+#define TAR_ADDR		0x0050
+
+/* i2c slave address register definitions */
+#define IC_SLAVE_ADDR		0x0002
+
+/* i2c data buffer and command register definitions */
+#define IC_CMD			0x0100
+
+/* i2c interrupt status register definitions */
+#define IC_GEN_CALL		0x0800
+#define IC_START_DET		0x0400
+#define IC_STOP_DET		0x0200
+#define IC_ACTIVITY		0x0100
+#define IC_RX_DONE		0x0080
+#define IC_TX_ABRT		0x0040
+#define IC_RD_REQ		0x0020
+#define IC_TX_EMPTY		0x0010
+#define IC_TX_OVER		0x0008
+#define IC_RX_FULL		0x0004
+#define IC_RX_OVER 		0x0002
+#define IC_RX_UNDER		0x0001
+
+/* fifo threshold register definitions */
+#define IC_TL0			0x00
+#define IC_TL1			0x01
+#define IC_TL2			0x02
+#define IC_TL3			0x03
+#define IC_TL4			0x04
+#define IC_TL5			0x05
+#define IC_TL6			0x06
+#define IC_TL7			0x07
+#define IC_RX_TL		IC_TL0
+#define IC_TX_TL		IC_TL0
+
+/* i2c enable register definitions */
+#define IC_ENABLE_0B		0x0001
+
+/* i2c status register  definitions */
+#define IC_STATUS_SA		0x0040
+#define IC_STATUS_MA		0x0020
+#define IC_STATUS_RFF		0x0010
+#define IC_STATUS_RFNE		0x0008
+#define IC_STATUS_TFE		0x0004
+#define IC_STATUS_TFNF		0x0002
+#define IC_STATUS_ACT		0x0001
+
+/* Speed Selection */
+#define IC_SPEED_MODE_STANDARD	1
+#define IC_SPEED_MODE_FAST	2
+#define IC_SPEED_MODE_MAX	3
+
+#define I2C_MAX_SPEED		3400000
+#define I2C_FAST_SPEED		400000
+#define I2C_STANDARD_SPEED	100000
+
+#endif /* __DW_I2C_H_ */
diff --git a/drivers/i2c/spr_i2c.c b/drivers/i2c/spr_i2c.c
deleted file mode 100644
index eabfe84..0000000
--- a/drivers/i2c/spr_i2c.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * (C) Copyright 2009
- * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/spr_i2c.h>
-
-static struct i2c_regs *const i2c_regs_p =
-    (struct i2c_regs *)CONFIG_SYS_I2C_BASE;
-
-/*
- * set_speed - Set the i2c speed mode (standard, high, fast)
- * @i2c_spd:	required i2c speed mode
- *
- * Set the i2c speed mode (standard, high, fast)
- */
-static void set_speed(int i2c_spd)
-{
-	unsigned int cntl;
-	unsigned int hcnt, lcnt;
-	unsigned int high, low;
-
-	cntl = (readl(&i2c_regs_p->ic_con) & (~IC_CON_SPD_MSK));
-
-	switch (i2c_spd) {
-	case IC_SPEED_MODE_MAX:
-		cntl |= IC_CON_SPD_HS;
-		high = MIN_HS_SCL_HIGHTIME;
-		low = MIN_HS_SCL_LOWTIME;
-		break;
-
-	case IC_SPEED_MODE_STANDARD:
-		cntl |= IC_CON_SPD_SS;
-		high = MIN_SS_SCL_HIGHTIME;
-		low = MIN_SS_SCL_LOWTIME;
-		break;
-
-	case IC_SPEED_MODE_FAST:
-	default:
-		cntl |= IC_CON_SPD_FS;
-		high = MIN_FS_SCL_HIGHTIME;
-		low = MIN_FS_SCL_LOWTIME;
-		break;
-	}
-
-	writel(cntl, &i2c_regs_p->ic_con);
-
-	hcnt = (IC_CLK * high) / NANO_TO_MICRO;
-	writel(hcnt, &i2c_regs_p->ic_fs_scl_hcnt);
-
-	lcnt = (IC_CLK * low) / NANO_TO_MICRO;
-	writel(lcnt, &i2c_regs_p->ic_fs_scl_lcnt);
-}
-
-/*
- * i2c_set_bus_speed - Set the i2c speed
- * @speed:	required i2c speed
- *
- * Set the i2c speed.
- */
-void i2c_set_bus_speed(int speed)
-{
-	if (speed >= I2C_MAX_SPEED)
-		set_speed(IC_SPEED_MODE_MAX);
-	else if (speed >= I2C_FAST_SPEED)
-		set_speed(IC_SPEED_MODE_FAST);
-	else
-		set_speed(IC_SPEED_MODE_STANDARD);
-}
-
-/*
- * i2c_get_bus_speed - Gets the i2c speed
- *
- * Gets the i2c speed.
- */
-int i2c_get_bus_speed(void)
-{
-	u32 cntl;
-
-	cntl = (readl(&i2c_regs_p->ic_con) & IC_CON_SPD_MSK);
-
-	if (cntl == IC_CON_SPD_HS)
-		return I2C_MAX_SPEED;
-	else if (cntl == IC_CON_SPD_FS)
-		return I2C_FAST_SPEED;
-	else if (cntl == IC_CON_SPD_SS)
-		return I2C_STANDARD_SPEED;
-
-	return 0;
-}
-
-/*
- * i2c_init - Init function
- * @speed:	required i2c speed
- * @slaveadd:	slave address for the spear device
- *
- * Initialization function.
- */
-void i2c_init(int speed, int slaveadd)
-{
-	unsigned int enbl;
-
-	/* Disable i2c */
-	enbl = readl(&i2c_regs_p->ic_enable);
-	enbl &= ~IC_ENABLE_0B;
-	writel(enbl, &i2c_regs_p->ic_enable);
-
-	writel((IC_CON_SD | IC_CON_SPD_FS | IC_CON_MM), &i2c_regs_p->ic_con);
-	writel(IC_RX_TL, &i2c_regs_p->ic_rx_tl);
-	writel(IC_TX_TL, &i2c_regs_p->ic_tx_tl);
-	i2c_set_bus_speed(speed);
-	writel(IC_STOP_DET, &i2c_regs_p->ic_intr_mask);
-	writel(slaveadd, &i2c_regs_p->ic_sar);
-
-	/* Enable i2c */
-	enbl = readl(&i2c_regs_p->ic_enable);
-	enbl |= IC_ENABLE_0B;
-	writel(enbl, &i2c_regs_p->ic_enable);
-}
-
-/*
- * i2c_setaddress - Sets the target slave address
- * @i2c_addr:	target i2c address
- *
- * Sets the target slave address.
- */
-static void i2c_setaddress(unsigned int i2c_addr)
-{
-	writel(i2c_addr, &i2c_regs_p->ic_tar);
-}
-
-/*
- * i2c_flush_rxfifo - Flushes the i2c RX FIFO
- *
- * Flushes the i2c RX FIFO
- */
-static void i2c_flush_rxfifo(void)
-{
-	while (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE)
-		readl(&i2c_regs_p->ic_cmd_data);
-}
-
-/*
- * i2c_wait_for_bb - Waits for bus busy
- *
- * Waits for bus busy
- */
-static int i2c_wait_for_bb(void)
-{
-	unsigned long start_time_bb = get_timer(0);
-
-	while ((readl(&i2c_regs_p->ic_status) & IC_STATUS_MA) ||
-	       !(readl(&i2c_regs_p->ic_status) & IC_STATUS_TFE)) {
-
-		/* Evaluate timeout */
-		if (get_timer(start_time_bb) > (unsigned long)(I2C_BYTE_TO_BB))
-			return 1;
-	}
-
-	return 0;
-}
-
-/* check parameters for i2c_read and i2c_write */
-static int check_params(uint addr, int alen, uchar *buffer, int len)
-{
-	if (buffer == NULL) {
-		printf("Buffer is invalid\n");
-		return 1;
-	}
-
-	if (alen > 1) {
-		printf("addr len %d not supported\n", alen);
-		return 1;
-	}
-
-	if (addr + len > 256) {
-		printf("address out of range\n");
-		return 1;
-	}
-
-	return 0;
-}
-
-static int i2c_xfer_init(uchar chip, uint addr)
-{
-	if (i2c_wait_for_bb()) {
-		printf("Timed out waiting for bus\n");
-		return 1;
-	}
-
-	i2c_setaddress(chip);
-	writel(addr, &i2c_regs_p->ic_cmd_data);
-
-	return 0;
-}
-
-static int i2c_xfer_finish(void)
-{
-	ulong start_stop_det = get_timer(0);
-
-	while (1) {
-		if ((readl(&i2c_regs_p->ic_raw_intr_stat) & IC_STOP_DET)) {
-			readl(&i2c_regs_p->ic_clr_stop_det);
-			break;
-		} else if (get_timer(start_stop_det) > I2C_STOPDET_TO) {
-			break;
-		}
-	}
-
-	if (i2c_wait_for_bb()) {
-		printf("Timed out waiting for bus\n");
-		return 1;
-	}
-
-	i2c_flush_rxfifo();
-
-	/* Wait for read/write operation to complete on actual memory */
-	udelay(10000);
-
-	return 0;
-}
-
-/*
- * i2c_read - Read from i2c memory
- * @chip:	target i2c address
- * @addr:	address to read from
- * @alen:
- * @buffer:	buffer for read data
- * @len:	no of bytes to be read
- *
- * Read from i2c memory.
- */
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	unsigned long start_time_rx;
-
-	if (check_params(addr, alen, buffer, len))
-		return 1;
-
-	if (i2c_xfer_init(chip, addr))
-		return 1;
-
-	start_time_rx = get_timer(0);
-	while (len) {
-		writel(IC_CMD, &i2c_regs_p->ic_cmd_data);
-
-		if (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE) {
-			*buffer++ = (uchar)readl(&i2c_regs_p->ic_cmd_data);
-			len--;
-			start_time_rx = get_timer(0);
-
-		} else if (get_timer(start_time_rx) > I2C_BYTE_TO) {
-				printf("Timed out. i2c read Failed\n");
-				return 1;
-		}
-	}
-
-	return i2c_xfer_finish();
-}
-
-/*
- * i2c_write - Write to i2c memory
- * @chip:	target i2c address
- * @addr:	address to read from
- * @alen:
- * @buffer:	buffer for read data
- * @len:	no of bytes to be read
- *
- * Write to i2c memory.
- */
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	int nb = len;
-	unsigned long start_time_tx;
-
-	if (check_params(addr, alen, buffer, len))
-		return 1;
-
-	if (i2c_xfer_init(chip, addr))
-		return 1;
-
-	start_time_tx = get_timer(0);
-	while (len) {
-		if (readl(&i2c_regs_p->ic_status) & IC_STATUS_TFNF) {
-			writel(*buffer, &i2c_regs_p->ic_cmd_data);
-			buffer++;
-			len--;
-			start_time_tx = get_timer(0);
-
-		} else if (get_timer(start_time_tx) > (nb * I2C_BYTE_TO)) {
-				printf("Timed out. i2c write Failed\n");
-				return 1;
-		}
-	}
-
-	return i2c_xfer_finish();
-}
-
-/*
- * i2c_probe - Probe the i2c chip
- */
-int i2c_probe(uchar chip)
-{
-	u32 tmp;
-
-	/*
-	 * Try to read the first location of the chip.
-	 */
-	return i2c_read(chip, 0, 1, (uchar *)&tmp, 1);
-}
diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
index 1e8d9d4..41f3241 100644
--- a/include/configs/spear-common.h
+++ b/include/configs/spear-common.h
@@ -44,7 +44,7 @@
 
 /* I2C driver configuration */
 #define CONFIG_HARD_I2C
-#define CONFIG_SPEAR_I2C
+#define CONFIG_DW_I2C
 #define CONFIG_SYS_I2C_SPEED			400000
 #define CONFIG_SYS_I2C_SLAVE			0x02
 
-- 
1.6.0.2

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

* [U-Boot] [PATCH 13/17] SPEAr : smi driver moved completely into drivers/mtd
  2010-04-21  7:54                       ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Vipin KUMAR
@ 2010-04-21  7:54                         ` Vipin KUMAR
  2010-04-21  7:54                           ` [U-Boot] [PATCH 14/17] SPEAr : USBD driver support added Vipin KUMAR
  2010-04-21 12:11                         ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Peter Tyser
  1 sibling, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

The smi IP used by spear platform is a ST serial memory interface controller
The earlier driver adds the driver of this controller as if it is specific to
spear platform.
The driver files are now moved into drivers/mtd folder for reusability by other
platforms

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 arch/arm/include/asm/arch-spear/spr_smi.h |  115 -------
 drivers/mtd/Makefile                      |    2 +-
 drivers/mtd/spr_smi.c                     |  523 -----------------------------
 drivers/mtd/st_smi.c                      |  523 +++++++++++++++++++++++++++++
 drivers/mtd/st_smi.h                      |  115 +++++++
 include/configs/spear-common.h            |    6 +-
 6 files changed, 642 insertions(+), 642 deletions(-)
 delete mode 100644 arch/arm/include/asm/arch-spear/spr_smi.h
 delete mode 100644 drivers/mtd/spr_smi.c
 create mode 100644 drivers/mtd/st_smi.c
 create mode 100644 drivers/mtd/st_smi.h

diff --git a/arch/arm/include/asm/arch-spear/spr_smi.h b/arch/arm/include/asm/arch-spear/spr_smi.h
deleted file mode 100644
index e2e5e8f..0000000
--- a/arch/arm/include/asm/arch-spear/spr_smi.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * (C) Copyright 2009
- * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef SPR_SMI_H
-#define SPR_SMI_H
-
-/* 0xF800.0000 . 0xFBFF.FFFF	64MB	SMI (Serial Flash Mem) */
-/* 0xFC00.0000 . 0xFC1F.FFFF	2MB	SMI (Serial Flash Reg.) */
-
-#define FLASH_START_ADDRESS	CONFIG_SYS_FLASH_BASE
-#define FLASH_BANK_SIZE		CONFIG_SYS_FLASH_BANK_SIZE
-
-#define SMIBANK0_BASE		(FLASH_START_ADDRESS)
-#define SMIBANK1_BASE		(SMIBANK0_BASE + FLASH_BANK_SIZE)
-#define SMIBANK2_BASE		(SMIBANK1_BASE + FLASH_BANK_SIZE)
-#define SMIBANK3_BASE		(SMIBANK2_BASE + FLASH_BANK_SIZE)
-
-#define BANK0			0
-#define BANK1			1
-#define BANK2			2
-#define BANK3			3
-
-struct smi_regs {
-	u32 smi_cr1;
-	u32 smi_cr2;
-	u32 smi_sr;
-	u32 smi_tr;
-	u32 smi_rr;
-};
-
-/* CONTROL REG 1 */
-#define BANK_EN			0x0000000F	/* enables all banks */
-#define DSEL_TIME		0x00000060	/* Deselect time */
-#define PRESCAL5		0x00000500	/* AHB_CK prescaling value */
-#define PRESCALA		0x00000A00	/* AHB_CK prescaling value */
-#define PRESCAL3		0x00000300	/* AHB_CK prescaling value */
-#define PRESCAL4		0x00000400	/* AHB_CK prescaling value */
-#define SW_MODE			0x10000000	/* enables SW Mode */
-#define WB_MODE			0x20000000	/* Write Burst Mode */
-#define FAST_MODE		0x00008000	/* Fast Mode */
-#define HOLD1			0x00010000
-
-/* CONTROL REG 2 */
-#define RD_STATUS_REG		0x00000400	/* reads status reg */
-#define WE			0x00000800	/* Write Enable */
-#define BANK0_SEL		0x00000000	/* Select Banck0 */
-#define BANK1_SEL		0x00001000	/* Select Banck1 */
-#define BANK2_SEL		0x00002000	/* Select Banck2 */
-#define BANK3_SEL		0x00003000	/* Select Banck3 */
-#define BANKSEL_SHIFT		12
-#define SEND			0x00000080	/* Send data */
-#define TX_LEN_1		0x00000001	/* data length = 1 byte */
-#define TX_LEN_2		0x00000002	/* data length = 2 byte */
-#define TX_LEN_3		0x00000003	/* data length = 3 byte */
-#define TX_LEN_4		0x00000004	/* data length = 4 byte */
-#define RX_LEN_1		0x00000010	/* data length = 1 byte */
-#define RX_LEN_2		0x00000020	/* data length = 2 byte */
-#define RX_LEN_3		0x00000030	/* data length = 3 byte */
-#define RX_LEN_4		0x00000040	/* data length = 4 byte */
-#define TFIE			0x00000100	/* Tx Flag Interrupt Enable */
-#define WCIE			0x00000200	/* WCF Interrupt Enable */
-
-/* STATUS_REG */
-#define INT_WCF_CLR		0xFFFFFDFF	/* clear: WCF clear */
-#define INT_TFF_CLR		0xFFFFFEFF	/* clear: TFF clear */
-#define WIP_BIT			0x00000001	/* WIP Bit of SPI SR */
-#define WEL_BIT			0x00000002	/* WEL Bit of SPI SR */
-#define RSR			0x00000005	/* Read Status regiser */
-#define TFF			0x00000100	/* Transfer Finished FLag */
-#define WCF			0x00000200	/* Transfer Finished FLag */
-#define ERF1			0x00000400	/* Error Flag 1 */
-#define ERF2			0x00000800	/* Error Flag 2 */
-#define WM0			0x00001000	/* WM Bank 0 */
-#define WM1			0x00002000	/* WM Bank 1 */
-#define WM2			0x00004000	/* WM Bank 2 */
-#define WM3			0x00008000	/* WM Bank 3 */
-#define WM_SHIFT		12
-
-/* TR REG */
-#define READ_ID			0x0000009F	/* Read Identification */
-#define BULK_ERASE		0x000000C7	/* BULK erase */
-#define SECTOR_ERASE		0x000000D8	/* SECTOR erase */
-#define WRITE_ENABLE		0x00000006	/* Wenable command to FLASH */
-
-struct flash_dev {
-	u32 density;
-	ulong size;
-	ushort sector_count;
-};
-
-#define SFLASH_PAGE_SIZE	0x100		/* flash page size */
-#define XFER_FINISH_TOUT	(3 * CONFIG_SYS_HZ)
-#define WMODE_TOUT		(3 * CONFIG_SYS_HZ)
-
-#endif
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index cbf6f15..d868d27 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -34,7 +34,7 @@ COBJS-$(CONFIG_FLASH_CFI_MTD) += cfi_mtd.o
 COBJS-$(CONFIG_HAS_DATAFLASH) += dataflash.o
 COBJS-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o
 COBJS-$(CONFIG_MW_EEPROM) += mw_eeprom.o
-COBJS-$(CONFIG_SPEARSMI) += spr_smi.o
+COBJS-$(CONFIG_ST_SMI) += st_smi.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/mtd/spr_smi.c b/drivers/mtd/spr_smi.c
deleted file mode 100644
index 189ee6d..0000000
--- a/drivers/mtd/spr_smi.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * (C) Copyright 2009
- * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <flash.h>
-#include <linux/err.h>
-
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/spr_smi.h>
-
-#if !defined(CONFIG_SYS_NO_FLASH)
-
-static struct smi_regs *const smicntl =
-    (struct smi_regs * const)CONFIG_SYS_SMI_BASE;
-static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS] =
-    CONFIG_SYS_FLASH_ADDR_BASE;
-flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
-
-#define ST_M25Pxx_ID		0x00002020
-
-static struct flash_dev flash_ids[] = {
-	{0x10, 0x10000, 2},	/* 64K Byte */
-	{0x11, 0x20000, 4},	/* 128K Byte */
-	{0x12, 0x40000, 4},	/* 256K Byte */
-	{0x13, 0x80000, 8},	/* 512K Byte */
-	{0x14, 0x100000, 16},	/* 1M Byte */
-	{0x15, 0x200000, 32},	/* 2M Byte */
-	{0x16, 0x400000, 64},	/* 4M Byte */
-	{0x17, 0x800000, 128},	/* 8M Byte */
-	{0x18, 0x1000000, 64},	/* 16M Byte */
-	{0x00,}
-};
-
-/*
- * smi_wait_xfer_finish - Wait until TFF is set in status register
- * @timeout:	 timeout in milliseconds
- *
- * Wait until TFF is set in status register
- */
-static void smi_wait_xfer_finish(int timeout)
-{
-	do {
-		if (readl(&smicntl->smi_sr) & TFF)
-			break;
-		udelay(1000);
-	} while (timeout--);
-}
-
-/*
- * smi_read_id - Read flash id
- * @info:	 flash_info structure pointer
- * @banknum:	 bank number
- *
- * Read the flash id present at bank #banknum
- */
-static unsigned int smi_read_id(flash_info_t *info, int banknum)
-{
-	unsigned int value;
-
-	writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1);
-	writel(READ_ID, &smicntl->smi_tr);
-	writel((banknum << BANKSEL_SHIFT) | SEND | TX_LEN_1 | RX_LEN_3,
-	       &smicntl->smi_cr2);
-	smi_wait_xfer_finish(XFER_FINISH_TOUT);
-
-	value = (readl(&smicntl->smi_rr) & 0x00FFFFFF);
-
-	writel(readl(&smicntl->smi_sr) & ~TFF, &smicntl->smi_sr);
-	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
-
-	return value;
-}
-
-/*
- * flash_get_size - Detect the SMI flash by reading the ID.
- * @base:	 Base address of the flash area bank #banknum
- * @banknum:	 Bank number
- *
- * Detect the SMI flash by reading the ID. Initializes the flash_info structure
- * with size, sector count etc.
- */
-static ulong flash_get_size(ulong base, int banknum)
-{
-	flash_info_t *info = &flash_info[banknum];
-	struct flash_dev *dev;
-	unsigned int value;
-	unsigned int density;
-	int i;
-
-	value = smi_read_id(info, banknum);
-	density = (value >> 16) & 0xff;
-
-	for (i = 0, dev = &flash_ids[0]; dev->density != 0x0;
-	     i++, dev = &flash_ids[i]) {
-		if (dev->density == density) {
-			info->size = dev->size;
-			info->sector_count = dev->sector_count;
-			break;
-		}
-	}
-
-	if (dev->density == 0x0)
-		return 0;
-
-	info->flash_id = value & 0xffff;
-	info->start[0] = base;
-
-	return info->size;
-}
-
-/*
- * smi_read_sr - Read status register of SMI
- * @bank:	 bank number
- *
- * This routine will get the status register of the flash chip present at the
- * given bank
- */
-static unsigned int smi_read_sr(int bank)
-{
-	u32 ctrlreg1;
-
-	/* store the CTRL REG1 state */
-	ctrlreg1 = readl(&smicntl->smi_cr1);
-
-	/* Program SMI in HW Mode */
-	writel(readl(&smicntl->smi_cr1) & ~(SW_MODE | WB_MODE),
-	       &smicntl->smi_cr1);
-
-	/* Performing a RSR instruction in HW mode */
-	writel((bank << BANKSEL_SHIFT) | RD_STATUS_REG, &smicntl->smi_cr2);
-
-	smi_wait_xfer_finish(XFER_FINISH_TOUT);
-
-	/* Restore the CTRL REG1 state */
-	writel(ctrlreg1, &smicntl->smi_cr1);
-
-	return readl(&smicntl->smi_sr);
-}
-
-/*
- * smi_wait_till_ready - Wait till last operation is over.
- * @bank:	 bank number shifted.
- * @timeout:	 timeout in milliseconds.
- *
- * This routine checks for WIP(write in progress)bit in Status register(SMSR-b0)
- * The routine checks for #timeout loops, each at interval of 1 milli-second.
- * If successful the routine returns 0.
- */
-static int smi_wait_till_ready(int bank, int timeout)
-{
-	int count;
-	unsigned int sr;
-
-	/* One chip guarantees max 5 msec wait here after page writes,
-	   but potentially three seconds (!) after page erase. */
-	for (count = 0; count < timeout; count++) {
-
-		sr = smi_read_sr(bank);
-		if (sr < 0)
-			break;
-		else if (!(sr & WIP_BIT))
-			return 0;
-
-		/* Try again after 1m-sec */
-		udelay(1000);
-	}
-	printf("SMI controller is still in wait, timeout=%d\n", timeout);
-	return -EIO;
-}
-
-/*
- * smi_write_enable - Enable the flash to do write operation
- * @bank:	 bank number
- *
- * Set write enable latch with Write Enable command.
- * Returns negative if error occurred.
- */
-static int smi_write_enable(int bank)
-{
-	u32 ctrlreg1;
-	int timeout = WMODE_TOUT;
-
-	/* Store the CTRL REG1 state */
-	ctrlreg1 = readl(&smicntl->smi_cr1);
-
-	/* Program SMI in H/W Mode */
-	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
-
-	/* Give the Flash, Write Enable command */
-	writel((bank << BANKSEL_SHIFT) | WE, &smicntl->smi_cr2);
-
-	smi_wait_xfer_finish(XFER_FINISH_TOUT);
-
-	/* Restore the CTRL REG1 state */
-	writel(ctrlreg1, &smicntl->smi_cr1);
-
-	do {
-		if (smi_read_sr(bank) & (1 << (bank + WM_SHIFT)))
-			break;
-		udelay(1000);
-	} while (timeout--);
-
-	if (timeout)
-		return 0;
-
-	return -1;
-}
-
-/*
- * smi_init - SMI initialization routine
- *
- * SMI initialization routine. Sets SMI control register1.
- */
-static void smi_init(void)
-{
-	/* Setting the fast mode values. SMI working@166/4 = 41.5 MHz */
-	writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4,
-	       &smicntl->smi_cr1);
-}
-
-/*
- * smi_sector_erase - Erase flash sector
- * @info:	 flash_info structure pointer
- * @sector:	 sector number
- *
- * Set write enable latch with Write Enable command.
- * Returns negative if error occurred.
- */
-static int smi_sector_erase(flash_info_t *info, unsigned int sector)
-{
-	int bank;
-	unsigned int sect_add;
-	unsigned int instruction;
-
-	switch (info->start[0]) {
-	case SMIBANK0_BASE:
-		bank = BANK0;
-		break;
-	case SMIBANK1_BASE:
-		bank = BANK1;
-		break;
-	case SMIBANK2_BASE:
-		bank = BANK2;
-		break;
-	case SMIBANK3_BASE:
-		bank = BANK3;
-		break;
-	default:
-		return -1;
-	}
-
-	sect_add = sector * (info->size / info->sector_count);
-	instruction = ((sect_add >> 8) & 0x0000FF00) | SECTOR_ERASE;
-
-	writel(readl(&smicntl->smi_sr) & ~(ERF1 | ERF2), &smicntl->smi_sr);
-
-	if (info->flash_id == ST_M25Pxx_ID) {
-		/* Wait until finished previous write command. */
-		if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT))
-			return -EBUSY;
-
-		/* Send write enable, before erase commands. */
-		if (smi_write_enable(bank))
-			return -EIO;
-
-		/* Put SMI in SW mode */
-		writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1);
-
-		/* Send Sector Erase command in SW Mode */
-		writel(instruction, &smicntl->smi_tr);
-		writel((bank << BANKSEL_SHIFT) | SEND | TX_LEN_4,
-		       &smicntl->smi_cr2);
-		smi_wait_xfer_finish(XFER_FINISH_TOUT);
-
-		if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT))
-			return -EBUSY;
-
-		/* Put SMI in HW mode */
-		writel(readl(&smicntl->smi_cr1) & ~SW_MODE,
-		       &smicntl->smi_cr1);
-
-		return 0;
-	} else {
-		/* Put SMI in HW mode */
-		writel(readl(&smicntl->smi_cr1) & ~SW_MODE,
-		       &smicntl->smi_cr1);
-		return -EINVAL;
-	}
-}
-
-/*
- * smi_write - Write to SMI flash
- * @src_addr:	 source buffer
- * @dst_addr:	 destination buffer
- * @length:	 length to write in words
- * @bank:	 bank base address
- *
- * Write to SMI flash
- */
-static int smi_write(unsigned int *src_addr, unsigned int *dst_addr,
-		     unsigned int length, ulong bank_addr)
-{
-	int banknum;
-	unsigned int WM;
-
-	switch (bank_addr) {
-	case SMIBANK0_BASE:
-		banknum = BANK0;
-		WM = WM0;
-		break;
-	case SMIBANK1_BASE:
-		banknum = BANK1;
-		WM = WM1;
-		break;
-	case SMIBANK2_BASE:
-		banknum = BANK2;
-		WM = WM2;
-		break;
-	case SMIBANK3_BASE:
-		banknum = BANK3;
-		WM = WM3;
-		break;
-	default:
-		return -1;
-	}
-
-	if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT))
-		return -EBUSY;
-
-	/* Set SMI in Hardware Mode */
-	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
-
-	if (smi_write_enable(banknum))
-		return -EIO;
-
-	/* Perform the write command */
-	while (length--) {
-		if (((ulong) (dst_addr) % SFLASH_PAGE_SIZE) == 0) {
-			if (smi_wait_till_ready(banknum,
-						CONFIG_SYS_FLASH_WRITE_TOUT))
-				return -EBUSY;
-
-			if (smi_write_enable(banknum))
-				return -EIO;
-		}
-
-		*dst_addr++ = *src_addr++;
-
-		if ((readl(&smicntl->smi_sr) & (ERF1 | ERF2)))
-			return -EIO;
-	}
-
-	if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT))
-		return -EBUSY;
-
-	writel(readl(&smicntl->smi_sr) & ~(WCF), &smicntl->smi_sr);
-
-	return 0;
-}
-
-/*
- * write_buff - Write to SMI flash
- * @info:	 flash info structure
- * @src:	 source buffer
- * @dest_addr:	 destination buffer
- * @length:	 length to write in words
- *
- * Write to SMI flash
- */
-int write_buff(flash_info_t *info, uchar *src, ulong dest_addr, ulong length)
-{
-	return smi_write((unsigned int *)src, (unsigned int *)dest_addr,
-		  (length + 3) / 4, info->start[0]);
-}
-
-/*
- * flash_init - SMI flash initialization
- *
- * SMI flash initialization
- */
-unsigned long flash_init(void)
-{
-	unsigned long size = 0;
-	int i, j;
-
-	smi_init();
-
-	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
-		flash_info[i].flash_id = FLASH_UNKNOWN;
-		size += flash_info[i].size = flash_get_size(bank_base[i], i);
-	}
-
-	for (j = 0; j < CONFIG_SYS_MAX_FLASH_BANKS; j++) {
-		for (i = 1; i < flash_info[j].sector_count; i++)
-			flash_info[j].start[i] =
-			    flash_info[j].start[i - 1] +
-			    flash_info->size / flash_info->sector_count;
-
-	}
-
-	return size;
-}
-
-/*
- * flash_print_info - Print SMI flash information
- *
- * Print SMI flash information
- */
-void flash_print_info(flash_info_t *info)
-{
-	int i;
-	if (info->flash_id == FLASH_UNKNOWN) {
-		puts("missing or unknown FLASH type\n");
-		return;
-	}
-	printf("  Size: %ld MB in %d Sectors\n",
-	       info->size >> 20, info->sector_count);
-
-	puts("  Sector Start Addresses:");
-	for (i = 0; i < info->sector_count; ++i) {
-#ifdef CONFIG_SYS_FLASH_EMPTY_INFO
-		int size;
-		int erased;
-		u32 *flash;
-
-		/*
-		 * Check if whole sector is erased
-		 */
-		size = (info->size) / (info->sector_count);
-		flash = (u32 *) info->start[i];
-		size = size / sizeof(int);
-
-		while ((size--) && (*flash++ == ~0))
-			;
-
-		size++;
-		if (size)
-			erased = 0;
-		else
-			erased = 1;
-
-		if ((i % 5) == 0)
-			printf("\n");
-
-		printf(" %08lX%s%s",
-		       info->start[i],
-		       erased ? " E" : "  ", info->protect[i] ? "RO " : "   ");
-#else
-		if ((i % 5) == 0)
-			printf("\n   ");
-		printf(" %08lX%s",
-		       info->start[i], info->protect[i] ? " (RO)  " : "     ");
-#endif
-	}
-	putc('\n');
-	return;
-}
-
-/*
- * flash_erase - Erase SMI flash
- *
- * Erase SMI flash
- */
-int flash_erase(flash_info_t *info, int s_first, int s_last)
-{
-	int rcode = 0;
-	int prot = 0;
-	flash_sect_t sect;
-
-	if (info->flash_id != ST_M25Pxx_ID) {
-		puts("Can't erase unknown flash type - aborted\n");
-		return 1;
-	}
-
-	if ((s_first < 0) || (s_first > s_last)) {
-		puts("- no sectors to erase\n");
-		return 1;
-	}
-
-	for (sect = s_first; sect <= s_last; ++sect) {
-		if (info->protect[sect])
-			prot++;
-	}
-	if (prot) {
-		printf("- Warning: %d protected sectors will not be erased!\n",
-		       prot);
-	} else {
-		putc('\n');
-	}
-
-	for (sect = s_first; sect <= s_last; sect++) {
-		if (info->protect[sect] == 0) {
-			if (smi_sector_erase(info, sect))
-				rcode = 1;
-			else
-				putc('.');
-		}
-	}
-	puts(" done\n");
-	return rcode;
-}
-#endif
diff --git a/drivers/mtd/st_smi.c b/drivers/mtd/st_smi.c
new file mode 100644
index 0000000..80d9fee
--- /dev/null
+++ b/drivers/mtd/st_smi.c
@@ -0,0 +1,523 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <flash.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include "st_smi.h"
+
+#if !defined(CONFIG_SYS_NO_FLASH)
+
+static struct smi_regs *const smicntl =
+    (struct smi_regs * const)CONFIG_SYS_SMI_BASE;
+static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS] =
+    CONFIG_SYS_FLASH_ADDR_BASE;
+flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
+
+#define ST_M25Pxx_ID		0x00002020
+
+static struct flash_dev flash_ids[] = {
+	{0x10, 0x10000, 2},	/* 64K Byte */
+	{0x11, 0x20000, 4},	/* 128K Byte */
+	{0x12, 0x40000, 4},	/* 256K Byte */
+	{0x13, 0x80000, 8},	/* 512K Byte */
+	{0x14, 0x100000, 16},	/* 1M Byte */
+	{0x15, 0x200000, 32},	/* 2M Byte */
+	{0x16, 0x400000, 64},	/* 4M Byte */
+	{0x17, 0x800000, 128},	/* 8M Byte */
+	{0x18, 0x1000000, 64},	/* 16M Byte */
+	{0x00,}
+};
+
+/*
+ * smi_wait_xfer_finish - Wait until TFF is set in status register
+ * @timeout:	 timeout in milliseconds
+ *
+ * Wait until TFF is set in status register
+ */
+static void smi_wait_xfer_finish(int timeout)
+{
+	do {
+		if (readl(&smicntl->smi_sr) & TFF)
+			break;
+		udelay(1000);
+	} while (timeout--);
+}
+
+/*
+ * smi_read_id - Read flash id
+ * @info:	 flash_info structure pointer
+ * @banknum:	 bank number
+ *
+ * Read the flash id present at bank #banknum
+ */
+static unsigned int smi_read_id(flash_info_t *info, int banknum)
+{
+	unsigned int value;
+
+	writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1);
+	writel(READ_ID, &smicntl->smi_tr);
+	writel((banknum << BANKSEL_SHIFT) | SEND | TX_LEN_1 | RX_LEN_3,
+	       &smicntl->smi_cr2);
+	smi_wait_xfer_finish(XFER_FINISH_TOUT);
+
+	value = (readl(&smicntl->smi_rr) & 0x00FFFFFF);
+
+	writel(readl(&smicntl->smi_sr) & ~TFF, &smicntl->smi_sr);
+	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
+
+	return value;
+}
+
+/*
+ * flash_get_size - Detect the SMI flash by reading the ID.
+ * @base:	 Base address of the flash area bank #banknum
+ * @banknum:	 Bank number
+ *
+ * Detect the SMI flash by reading the ID. Initializes the flash_info structure
+ * with size, sector count etc.
+ */
+static ulong flash_get_size(ulong base, int banknum)
+{
+	flash_info_t *info = &flash_info[banknum];
+	struct flash_dev *dev;
+	unsigned int value;
+	unsigned int density;
+	int i;
+
+	value = smi_read_id(info, banknum);
+	density = (value >> 16) & 0xff;
+
+	for (i = 0, dev = &flash_ids[0]; dev->density != 0x0;
+	     i++, dev = &flash_ids[i]) {
+		if (dev->density == density) {
+			info->size = dev->size;
+			info->sector_count = dev->sector_count;
+			break;
+		}
+	}
+
+	if (dev->density == 0x0)
+		return 0;
+
+	info->flash_id = value & 0xffff;
+	info->start[0] = base;
+
+	return info->size;
+}
+
+/*
+ * smi_read_sr - Read status register of SMI
+ * @bank:	 bank number
+ *
+ * This routine will get the status register of the flash chip present at the
+ * given bank
+ */
+static unsigned int smi_read_sr(int bank)
+{
+	u32 ctrlreg1;
+
+	/* store the CTRL REG1 state */
+	ctrlreg1 = readl(&smicntl->smi_cr1);
+
+	/* Program SMI in HW Mode */
+	writel(readl(&smicntl->smi_cr1) & ~(SW_MODE | WB_MODE),
+	       &smicntl->smi_cr1);
+
+	/* Performing a RSR instruction in HW mode */
+	writel((bank << BANKSEL_SHIFT) | RD_STATUS_REG, &smicntl->smi_cr2);
+
+	smi_wait_xfer_finish(XFER_FINISH_TOUT);
+
+	/* Restore the CTRL REG1 state */
+	writel(ctrlreg1, &smicntl->smi_cr1);
+
+	return readl(&smicntl->smi_sr);
+}
+
+/*
+ * smi_wait_till_ready - Wait till last operation is over.
+ * @bank:	 bank number shifted.
+ * @timeout:	 timeout in milliseconds.
+ *
+ * This routine checks for WIP(write in progress)bit in Status register(SMSR-b0)
+ * The routine checks for #timeout loops, each at interval of 1 milli-second.
+ * If successful the routine returns 0.
+ */
+static int smi_wait_till_ready(int bank, int timeout)
+{
+	int count;
+	unsigned int sr;
+
+	/* One chip guarantees max 5 msec wait here after page writes,
+	   but potentially three seconds (!) after page erase. */
+	for (count = 0; count < timeout; count++) {
+
+		sr = smi_read_sr(bank);
+		if (sr < 0)
+			break;
+		else if (!(sr & WIP_BIT))
+			return 0;
+
+		/* Try again after 1m-sec */
+		udelay(1000);
+	}
+	printf("SMI controller is still in wait, timeout=%d\n", timeout);
+	return -EIO;
+}
+
+/*
+ * smi_write_enable - Enable the flash to do write operation
+ * @bank:	 bank number
+ *
+ * Set write enable latch with Write Enable command.
+ * Returns negative if error occurred.
+ */
+static int smi_write_enable(int bank)
+{
+	u32 ctrlreg1;
+	int timeout = WMODE_TOUT;
+
+	/* Store the CTRL REG1 state */
+	ctrlreg1 = readl(&smicntl->smi_cr1);
+
+	/* Program SMI in H/W Mode */
+	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
+
+	/* Give the Flash, Write Enable command */
+	writel((bank << BANKSEL_SHIFT) | WE, &smicntl->smi_cr2);
+
+	smi_wait_xfer_finish(XFER_FINISH_TOUT);
+
+	/* Restore the CTRL REG1 state */
+	writel(ctrlreg1, &smicntl->smi_cr1);
+
+	do {
+		if (smi_read_sr(bank) & (1 << (bank + WM_SHIFT)))
+			break;
+		udelay(1000);
+	} while (timeout--);
+
+	if (timeout)
+		return 0;
+
+	return -1;
+}
+
+/*
+ * smi_init - SMI initialization routine
+ *
+ * SMI initialization routine. Sets SMI control register1.
+ */
+static void smi_init(void)
+{
+	/* Setting the fast mode values. SMI working@166/4 = 41.5 MHz */
+	writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4,
+	       &smicntl->smi_cr1);
+}
+
+/*
+ * smi_sector_erase - Erase flash sector
+ * @info:	 flash_info structure pointer
+ * @sector:	 sector number
+ *
+ * Set write enable latch with Write Enable command.
+ * Returns negative if error occurred.
+ */
+static int smi_sector_erase(flash_info_t *info, unsigned int sector)
+{
+	int bank;
+	unsigned int sect_add;
+	unsigned int instruction;
+
+	switch (info->start[0]) {
+	case SMIBANK0_BASE:
+		bank = BANK0;
+		break;
+	case SMIBANK1_BASE:
+		bank = BANK1;
+		break;
+	case SMIBANK2_BASE:
+		bank = BANK2;
+		break;
+	case SMIBANK3_BASE:
+		bank = BANK3;
+		break;
+	default:
+		return -1;
+	}
+
+	sect_add = sector * (info->size / info->sector_count);
+	instruction = ((sect_add >> 8) & 0x0000FF00) | SECTOR_ERASE;
+
+	writel(readl(&smicntl->smi_sr) & ~(ERF1 | ERF2), &smicntl->smi_sr);
+
+	if (info->flash_id == ST_M25Pxx_ID) {
+		/* Wait until finished previous write command. */
+		if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT))
+			return -EBUSY;
+
+		/* Send write enable, before erase commands. */
+		if (smi_write_enable(bank))
+			return -EIO;
+
+		/* Put SMI in SW mode */
+		writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1);
+
+		/* Send Sector Erase command in SW Mode */
+		writel(instruction, &smicntl->smi_tr);
+		writel((bank << BANKSEL_SHIFT) | SEND | TX_LEN_4,
+		       &smicntl->smi_cr2);
+		smi_wait_xfer_finish(XFER_FINISH_TOUT);
+
+		if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT))
+			return -EBUSY;
+
+		/* Put SMI in HW mode */
+		writel(readl(&smicntl->smi_cr1) & ~SW_MODE,
+		       &smicntl->smi_cr1);
+
+		return 0;
+	} else {
+		/* Put SMI in HW mode */
+		writel(readl(&smicntl->smi_cr1) & ~SW_MODE,
+		       &smicntl->smi_cr1);
+		return -EINVAL;
+	}
+}
+
+/*
+ * smi_write - Write to SMI flash
+ * @src_addr:	 source buffer
+ * @dst_addr:	 destination buffer
+ * @length:	 length to write in words
+ * @bank:	 bank base address
+ *
+ * Write to SMI flash
+ */
+static int smi_write(unsigned int *src_addr, unsigned int *dst_addr,
+		     unsigned int length, ulong bank_addr)
+{
+	int banknum;
+	unsigned int WM;
+
+	switch (bank_addr) {
+	case SMIBANK0_BASE:
+		banknum = BANK0;
+		WM = WM0;
+		break;
+	case SMIBANK1_BASE:
+		banknum = BANK1;
+		WM = WM1;
+		break;
+	case SMIBANK2_BASE:
+		banknum = BANK2;
+		WM = WM2;
+		break;
+	case SMIBANK3_BASE:
+		banknum = BANK3;
+		WM = WM3;
+		break;
+	default:
+		return -1;
+	}
+
+	if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT))
+		return -EBUSY;
+
+	/* Set SMI in Hardware Mode */
+	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
+
+	if (smi_write_enable(banknum))
+		return -EIO;
+
+	/* Perform the write command */
+	while (length--) {
+		if (((ulong) (dst_addr) % SFLASH_PAGE_SIZE) == 0) {
+			if (smi_wait_till_ready(banknum,
+						CONFIG_SYS_FLASH_WRITE_TOUT))
+				return -EBUSY;
+
+			if (smi_write_enable(banknum))
+				return -EIO;
+		}
+
+		*dst_addr++ = *src_addr++;
+
+		if ((readl(&smicntl->smi_sr) & (ERF1 | ERF2)))
+			return -EIO;
+	}
+
+	if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT))
+		return -EBUSY;
+
+	writel(readl(&smicntl->smi_sr) & ~(WCF), &smicntl->smi_sr);
+
+	return 0;
+}
+
+/*
+ * write_buff - Write to SMI flash
+ * @info:	 flash info structure
+ * @src:	 source buffer
+ * @dest_addr:	 destination buffer
+ * @length:	 length to write in words
+ *
+ * Write to SMI flash
+ */
+int write_buff(flash_info_t *info, uchar *src, ulong dest_addr, ulong length)
+{
+	return smi_write((unsigned int *)src, (unsigned int *)dest_addr,
+		  (length + 3) / 4, info->start[0]);
+}
+
+/*
+ * flash_init - SMI flash initialization
+ *
+ * SMI flash initialization
+ */
+unsigned long flash_init(void)
+{
+	unsigned long size = 0;
+	int i, j;
+
+	smi_init();
+
+	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
+		flash_info[i].flash_id = FLASH_UNKNOWN;
+		size += flash_info[i].size = flash_get_size(bank_base[i], i);
+	}
+
+	for (j = 0; j < CONFIG_SYS_MAX_FLASH_BANKS; j++) {
+		for (i = 1; i < flash_info[j].sector_count; i++)
+			flash_info[j].start[i] =
+			    flash_info[j].start[i - 1] +
+			    flash_info->size / flash_info->sector_count;
+
+	}
+
+	return size;
+}
+
+/*
+ * flash_print_info - Print SMI flash information
+ *
+ * Print SMI flash information
+ */
+void flash_print_info(flash_info_t *info)
+{
+	int i;
+	if (info->flash_id == FLASH_UNKNOWN) {
+		puts("missing or unknown FLASH type\n");
+		return;
+	}
+	printf("  Size: %ld MB in %d Sectors\n",
+	       info->size >> 20, info->sector_count);
+
+	puts("  Sector Start Addresses:");
+	for (i = 0; i < info->sector_count; ++i) {
+#ifdef CONFIG_SYS_FLASH_EMPTY_INFO
+		int size;
+		int erased;
+		u32 *flash;
+
+		/*
+		 * Check if whole sector is erased
+		 */
+		size = (info->size) / (info->sector_count);
+		flash = (u32 *) info->start[i];
+		size = size / sizeof(int);
+
+		while ((size--) && (*flash++ == ~0))
+			;
+
+		size++;
+		if (size)
+			erased = 0;
+		else
+			erased = 1;
+
+		if ((i % 5) == 0)
+			printf("\n");
+
+		printf(" %08lX%s%s",
+		       info->start[i],
+		       erased ? " E" : "  ", info->protect[i] ? "RO " : "   ");
+#else
+		if ((i % 5) == 0)
+			printf("\n   ");
+		printf(" %08lX%s",
+		       info->start[i], info->protect[i] ? " (RO)  " : "     ");
+#endif
+	}
+	putc('\n');
+	return;
+}
+
+/*
+ * flash_erase - Erase SMI flash
+ *
+ * Erase SMI flash
+ */
+int flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+	int rcode = 0;
+	int prot = 0;
+	flash_sect_t sect;
+
+	if (info->flash_id != ST_M25Pxx_ID) {
+		puts("Can't erase unknown flash type - aborted\n");
+		return 1;
+	}
+
+	if ((s_first < 0) || (s_first > s_last)) {
+		puts("- no sectors to erase\n");
+		return 1;
+	}
+
+	for (sect = s_first; sect <= s_last; ++sect) {
+		if (info->protect[sect])
+			prot++;
+	}
+	if (prot) {
+		printf("- Warning: %d protected sectors will not be erased!\n",
+		       prot);
+	} else {
+		putc('\n');
+	}
+
+	for (sect = s_first; sect <= s_last; sect++) {
+		if (info->protect[sect] == 0) {
+			if (smi_sector_erase(info, sect))
+				rcode = 1;
+			else
+				putc('.');
+		}
+	}
+	puts(" done\n");
+	return rcode;
+}
+#endif
diff --git a/drivers/mtd/st_smi.h b/drivers/mtd/st_smi.h
new file mode 100644
index 0000000..37ed503
--- /dev/null
+++ b/drivers/mtd/st_smi.h
@@ -0,0 +1,115 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef ST_SMI_H
+#define ST_SMI_H
+
+/* 0xF800.0000 . 0xFBFF.FFFF	64MB	SMI (Serial Flash Mem) */
+/* 0xFC00.0000 . 0xFC1F.FFFF	2MB	SMI (Serial Flash Reg.) */
+
+#define FLASH_START_ADDRESS	CONFIG_SYS_FLASH_BASE
+#define FLASH_BANK_SIZE		CONFIG_SYS_FLASH_BANK_SIZE
+
+#define SMIBANK0_BASE		(FLASH_START_ADDRESS)
+#define SMIBANK1_BASE		(SMIBANK0_BASE + FLASH_BANK_SIZE)
+#define SMIBANK2_BASE		(SMIBANK1_BASE + FLASH_BANK_SIZE)
+#define SMIBANK3_BASE		(SMIBANK2_BASE + FLASH_BANK_SIZE)
+
+#define BANK0			0
+#define BANK1			1
+#define BANK2			2
+#define BANK3			3
+
+struct smi_regs {
+	u32 smi_cr1;
+	u32 smi_cr2;
+	u32 smi_sr;
+	u32 smi_tr;
+	u32 smi_rr;
+};
+
+/* CONTROL REG 1 */
+#define BANK_EN			0x0000000F	/* enables all banks */
+#define DSEL_TIME		0x00000060	/* Deselect time */
+#define PRESCAL5		0x00000500	/* AHB_CK prescaling value */
+#define PRESCALA		0x00000A00	/* AHB_CK prescaling value */
+#define PRESCAL3		0x00000300	/* AHB_CK prescaling value */
+#define PRESCAL4		0x00000400	/* AHB_CK prescaling value */
+#define SW_MODE			0x10000000	/* enables SW Mode */
+#define WB_MODE			0x20000000	/* Write Burst Mode */
+#define FAST_MODE		0x00008000	/* Fast Mode */
+#define HOLD1			0x00010000
+
+/* CONTROL REG 2 */
+#define RD_STATUS_REG		0x00000400	/* reads status reg */
+#define WE			0x00000800	/* Write Enable */
+#define BANK0_SEL		0x00000000	/* Select Banck0 */
+#define BANK1_SEL		0x00001000	/* Select Banck1 */
+#define BANK2_SEL		0x00002000	/* Select Banck2 */
+#define BANK3_SEL		0x00003000	/* Select Banck3 */
+#define BANKSEL_SHIFT		12
+#define SEND			0x00000080	/* Send data */
+#define TX_LEN_1		0x00000001	/* data length = 1 byte */
+#define TX_LEN_2		0x00000002	/* data length = 2 byte */
+#define TX_LEN_3		0x00000003	/* data length = 3 byte */
+#define TX_LEN_4		0x00000004	/* data length = 4 byte */
+#define RX_LEN_1		0x00000010	/* data length = 1 byte */
+#define RX_LEN_2		0x00000020	/* data length = 2 byte */
+#define RX_LEN_3		0x00000030	/* data length = 3 byte */
+#define RX_LEN_4		0x00000040	/* data length = 4 byte */
+#define TFIE			0x00000100	/* Tx Flag Interrupt Enable */
+#define WCIE			0x00000200	/* WCF Interrupt Enable */
+
+/* STATUS_REG */
+#define INT_WCF_CLR		0xFFFFFDFF	/* clear: WCF clear */
+#define INT_TFF_CLR		0xFFFFFEFF	/* clear: TFF clear */
+#define WIP_BIT			0x00000001	/* WIP Bit of SPI SR */
+#define WEL_BIT			0x00000002	/* WEL Bit of SPI SR */
+#define RSR			0x00000005	/* Read Status regiser */
+#define TFF			0x00000100	/* Transfer Finished FLag */
+#define WCF			0x00000200	/* Transfer Finished FLag */
+#define ERF1			0x00000400	/* Error Flag 1 */
+#define ERF2			0x00000800	/* Error Flag 2 */
+#define WM0			0x00001000	/* WM Bank 0 */
+#define WM1			0x00002000	/* WM Bank 1 */
+#define WM2			0x00004000	/* WM Bank 2 */
+#define WM3			0x00008000	/* WM Bank 3 */
+#define WM_SHIFT		12
+
+/* TR REG */
+#define READ_ID			0x0000009F	/* Read Identification */
+#define BULK_ERASE		0x000000C7	/* BULK erase */
+#define SECTOR_ERASE		0x000000D8	/* SECTOR erase */
+#define WRITE_ENABLE		0x00000006	/* Wenable command to FLASH */
+
+struct flash_dev {
+	u32 density;
+	ulong size;
+	ushort sector_count;
+};
+
+#define SFLASH_PAGE_SIZE	0x100		/* flash page size */
+#define XFER_FINISH_TOUT	(3 * CONFIG_SYS_HZ)
+#define WMODE_TOUT		(3 * CONFIG_SYS_HZ)
+
+#endif
diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
index 41f3241..e4090e5 100644
--- a/include/configs/spear-common.h
+++ b/include/configs/spear-common.h
@@ -57,10 +57,10 @@
 #if defined(CONFIG_FLASH_PNOR)
 #define CONFIG_SPEAR_EMI			1
 #else
-#define CONFIG_SPEARSMI				1
+#define CONFIG_ST_SMI				1
 #endif
 
-#if defined(CONFIG_SPEARSMI)
+#if defined(CONFIG_ST_SMI)
 
 #define CONFIG_SYS_MAX_FLASH_BANKS		2
 #define CONFIG_SYS_FLASH_BASE			(0xF8000000)
@@ -125,7 +125,7 @@
  * U-Boot Environment placing definitions.
  */
 #if defined(CONFIG_ENV_IS_IN_FLASH)
-#ifdef CONFIG_SPEARSMI
+#ifdef CONFIG_ST_SMI
 /*
  * Environment is in serial NOR flash
  */
-- 
1.6.0.2

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

* [U-Boot] [PATCH 14/17] SPEAr : USBD driver support added
  2010-04-21  7:54                         ` [U-Boot] [PATCH 13/17] SPEAr : smi driver moved completely into drivers/mtd Vipin KUMAR
@ 2010-04-21  7:54                           ` Vipin KUMAR
  2010-04-21  7:54                             ` [U-Boot] [PATCH 15/17] SPEAr : Basic spear1300 architecture " Vipin KUMAR
  0 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

USBD is a Synopsys IP. The earlier driver implements itself as specific to spear
SoCs. This patch implements this driver as a reusable driver for other platforms
as well.

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 drivers/serial/usbtty.h        |    4 +-
 drivers/usb/gadget/Makefile    |    2 +-
 drivers/usb/gadget/dw_udc.c    | 1014 ++++++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/spr_udc.c   |  998 ---------------------------------------
 include/configs/spear-common.h |    2 +-
 include/usb/dw_udc.h           |  230 +++++++++
 include/usb/spr_udc.h          |  230 ---------
 7 files changed, 1248 insertions(+), 1232 deletions(-)
 create mode 100644 drivers/usb/gadget/dw_udc.c
 delete mode 100644 drivers/usb/gadget/spr_udc.c
 create mode 100644 include/usb/dw_udc.h
 delete mode 100644 include/usb/spr_udc.h

diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h
index a23169a..507f60d 100644
--- a/drivers/serial/usbtty.h
+++ b/drivers/serial/usbtty.h
@@ -33,8 +33,8 @@
 #include <usb/musb_udc.h>
 #elif defined(CONFIG_PXA27X)
 #include <usb/pxa27x_udc.h>
-#elif defined(CONFIG_SPEAR3XX) || defined(CONFIG_SPEAR600)
-#include <usb/spr_udc.h>
+#elif defined(CONFIG_DW_UDC)
+#include <usb/dw_udc.h>
 #endif
 
 #include <version_autogenerated.h>
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 1d7362d..3524f36 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -32,7 +32,7 @@ COBJS-$(CONFIG_OMAP1510) += omap1510_udc.o
 COBJS-$(CONFIG_OMAP1610) += omap1510_udc.o
 COBJS-$(CONFIG_MPC885_FAMILY) += mpc8xx_udc.o
 COBJS-$(CONFIG_PXA27X) += pxa27x_udc.o
-COBJS-$(CONFIG_SPEARUDC) += spr_udc.o
+COBJS-$(CONFIG_DW_UDC) += dw_udc.o
 endif
 
 COBJS	:= $(COBJS-y)
diff --git a/drivers/usb/gadget/dw_udc.c b/drivers/usb/gadget/dw_udc.c
new file mode 100644
index 0000000..2d2f411
--- /dev/null
+++ b/drivers/usb/gadget/dw_udc.c
@@ -0,0 +1,1014 @@
+/*
+ * Based on drivers/usb/gadget/omap1510_udc.c
+ * TI OMAP1510 USB bus interface driver
+ *
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#include <usbdevice.h>
+#include "ep0.h"
+#include <usb/dw_udc.h>
+#include <asm/arch/hardware.h>
+
+#define UDC_INIT_MDELAY		80	/* Device settle delay */
+
+/* Some kind of debugging output... */
+#ifndef DEBUG_DWUSBTTY
+#define UDCDBG(str)
+#define UDCDBGA(fmt, args...)
+#else
+#define UDCDBG(str) serial_printf(str "\n")
+#define UDCDBGA(fmt, args...) serial_printf(fmt "\n", ##args)
+#endif
+
+static struct urb *ep0_urb;
+static struct usb_device_instance *udc_device;
+
+static struct plug_regs *const plug_regs_p =
+    (struct plug_regs * const)CONFIG_SYS_PLUG_BASE;
+static struct udc_regs *const udc_regs_p =
+    (struct udc_regs * const)CONFIG_SYS_USBD_BASE;
+static struct udc_endp_regs *const outep_regs_p =
+    &((struct udc_regs * const)CONFIG_SYS_USBD_BASE)->out_regs[0];
+static struct udc_endp_regs *const inep_regs_p =
+    &((struct udc_regs * const)CONFIG_SYS_USBD_BASE)->in_regs[0];
+
+/*
+ * udc_state_transition - Write the next packet to TxFIFO.
+ * @initial:	Initial state.
+ * @final:	Final state.
+ *
+ * Helper function to implement device state changes. The device states and
+ * the events that transition between them are:
+ *
+ *				STATE_ATTACHED
+ *				||	/\
+ *				\/	||
+ *	DEVICE_HUB_CONFIGURED			DEVICE_HUB_RESET
+ *				||	/\
+ *				\/	||
+ *				STATE_POWERED
+ *				||	/\
+ *				\/	||
+ *	DEVICE_RESET				DEVICE_POWER_INTERRUPTION
+ *				||	/\
+ *				\/	||
+ *				STATE_DEFAULT
+ *				||	/\
+ *				\/	||
+ *	DEVICE_ADDRESS_ASSIGNED			DEVICE_RESET
+ *				||	/\
+ *				\/	||
+ *				STATE_ADDRESSED
+ *				||	/\
+ *				\/	||
+ *	DEVICE_CONFIGURED			DEVICE_DE_CONFIGURED
+ *				||	/\
+ *				\/	||
+ *				STATE_CONFIGURED
+ *
+ * udc_state_transition transitions up (in the direction from STATE_ATTACHED
+ * to STATE_CONFIGURED) from the specified initial state to the specified final
+ * state, passing through each intermediate state on the way. If the initial
+ * state is at or above (i.e. nearer to STATE_CONFIGURED) the final state, then
+ * no state transitions will take place.
+ *
+ * udc_state_transition also transitions down (in the direction from
+ * STATE_CONFIGURED to STATE_ATTACHED) from the specified initial state to the
+ * specified final state, passing through each intermediate state on the way.
+ * If the initial state is at or below (i.e. nearer to STATE_ATTACHED) the final
+ * state, then no state transitions will take place.
+ *
+ * This function must only be called with interrupts disabled.
+ */
+static void udc_state_transition(usb_device_state_t initial,
+				 usb_device_state_t final)
+{
+	if (initial < final) {
+		switch (initial) {
+		case STATE_ATTACHED:
+			usbd_device_event_irq(udc_device,
+					      DEVICE_HUB_CONFIGURED, 0);
+			if (final == STATE_POWERED)
+				break;
+		case STATE_POWERED:
+			usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
+			if (final == STATE_DEFAULT)
+				break;
+		case STATE_DEFAULT:
+			usbd_device_event_irq(udc_device,
+					      DEVICE_ADDRESS_ASSIGNED, 0);
+			if (final == STATE_ADDRESSED)
+				break;
+		case STATE_ADDRESSED:
+			usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0);
+		case STATE_CONFIGURED:
+			break;
+		default:
+			break;
+		}
+	} else if (initial > final) {
+		switch (initial) {
+		case STATE_CONFIGURED:
+			usbd_device_event_irq(udc_device,
+					      DEVICE_DE_CONFIGURED, 0);
+			if (final == STATE_ADDRESSED)
+				break;
+		case STATE_ADDRESSED:
+			usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
+			if (final == STATE_DEFAULT)
+				break;
+		case STATE_DEFAULT:
+			usbd_device_event_irq(udc_device,
+					      DEVICE_POWER_INTERRUPTION, 0);
+			if (final == STATE_POWERED)
+				break;
+		case STATE_POWERED:
+			usbd_device_event_irq(udc_device, DEVICE_HUB_RESET, 0);
+		case STATE_ATTACHED:
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+/* Stall endpoint */
+static void udc_stall_ep(u32 ep_num)
+{
+	writel(readl(&inep_regs_p[ep_num].endp_cntl) | ENDP_CNTL_STALL,
+	       &inep_regs_p[ep_num].endp_cntl);
+
+	writel(readl(&outep_regs_p[ep_num].endp_cntl) | ENDP_CNTL_STALL,
+	       &outep_regs_p[ep_num].endp_cntl);
+}
+
+static void *get_fifo(int ep_num, int in)
+{
+	u32 *fifo_ptr = (u32 *)CONFIG_SYS_FIFO_BASE;
+
+	switch (ep_num) {
+	case UDC_EP3:
+		fifo_ptr += readl(&inep_regs_p[1].endp_bsorfn);
+		/* break intentionally left out */
+
+	case UDC_EP1:
+		fifo_ptr += readl(&inep_regs_p[0].endp_bsorfn);
+		/* break intentionally left out */
+
+	case UDC_EP0:
+	default:
+		if (in) {
+			fifo_ptr +=
+			    readl(&outep_regs_p[2].endp_maxpacksize) >> 16;
+			/* break intentionally left out */
+		} else {
+			break;
+		}
+
+	case UDC_EP2:
+		fifo_ptr += readl(&outep_regs_p[0].endp_maxpacksize) >> 16;
+		/* break intentionally left out */
+	}
+
+	return (void *)fifo_ptr;
+}
+
+static int usbgetpckfromfifo(int epNum, u8 *bufp, u32 len)
+{
+	u8 *fifo_ptr = (u8 *)get_fifo(epNum, 0);
+	u32 i, nw, nb;
+	u32 *wrdp;
+	u8 *bytp;
+
+	if (readl(&udc_regs_p->dev_stat) & DEV_STAT_RXFIFO_EMPTY)
+		return -1;
+
+	nw = len / sizeof(u32);
+	nb = len % sizeof(u32);
+
+	wrdp = (u32 *)bufp;
+	for (i = 0; i < nw; i++) {
+		writel(readl(fifo_ptr), wrdp);
+		wrdp++;
+	}
+
+	bytp = (u8 *)wrdp;
+	for (i = 0; i < nb; i++) {
+		writeb(readb(fifo_ptr), bytp);
+		fifo_ptr++;
+		bytp++;
+	}
+	readl(&outep_regs_p[epNum].write_done);
+
+	return 0;
+}
+
+static void usbputpcktofifo(int epNum, u8 *bufp, u32 len)
+{
+	u32 i, nw, nb;
+	u32 *wrdp;
+	u8 *bytp;
+	u8 *fifo_ptr = get_fifo(epNum, 1);
+
+	nw = len / sizeof(int);
+	nb = len % sizeof(int);
+	wrdp = (u32 *)bufp;
+	for (i = 0; i < nw; i++) {
+		writel(*wrdp, fifo_ptr);
+		wrdp++;
+	}
+
+	bytp = (u8 *)wrdp;
+	for (i = 0; i < nb; i++) {
+		writeb(*bytp, fifo_ptr);
+		fifo_ptr++;
+		bytp++;
+	}
+}
+
+/*
+ * dw_write_noniso_tx_fifo - Write the next packet to TxFIFO.
+ * @endpoint:		Endpoint pointer.
+ *
+ * If the endpoint has an active tx_urb, then the next packet of data from the
+ * URB is written to the tx FIFO.  The total amount of data in the urb is given
+ * by urb->actual_length.  The maximum amount of data that can be sent in any
+ * one packet is given by endpoint->tx_packetSize.  The number of data bytes
+ * from this URB that have already been transmitted is given by endpoint->sent.
+ * endpoint->last is updated by this routine with the number of data bytes
+ * transmitted in this packet.
+ *
+ */
+static void dw_write_noniso_tx_fifo(struct usb_endpoint_instance
+				       *endpoint)
+{
+	struct urb *urb = endpoint->tx_urb;
+	int align;
+
+	if (urb) {
+		u32 last;
+
+		UDCDBGA("urb->buffer %p, buffer_length %d, actual_length %d",
+			urb->buffer, urb->buffer_length, urb->actual_length);
+
+		last = MIN(urb->actual_length - endpoint->sent,
+			   endpoint->tx_packetSize);
+
+		if (last) {
+			u8 *cp = urb->buffer + endpoint->sent;
+
+			/*
+			 * This ensures that USBD packet fifo is accessed
+			 * - through word aligned pointer or
+			 * - through non word aligned pointer but only
+			 *   with a max length to make the next packet
+			 *   word aligned
+			 */
+
+			align = ((ulong)cp % sizeof(int));
+			if (align)
+				last = MIN(last, sizeof(int) - align);
+
+			UDCDBGA("endpoint->sent %d, tx_packetSize %d, last %d",
+				endpoint->sent, endpoint->tx_packetSize, last);
+
+			usbputpcktofifo(endpoint->endpoint_address &
+					USB_ENDPOINT_NUMBER_MASK, cp, last);
+		}
+		endpoint->last = last;
+	}
+}
+
+/*
+ * Handle SETUP USB interrupt.
+ * This function implements TRM Figure 14-14.
+ */
+static void dw_udc_setup(struct usb_endpoint_instance *endpoint)
+{
+	u8 *datap = (u8 *)&ep0_urb->device_request;
+	int ep_addr = endpoint->endpoint_address;
+
+	UDCDBG("-> Entering device setup");
+	usbgetpckfromfifo(ep_addr, datap, 8);
+
+	/* Try to process setup packet */
+	if (ep0_recv_setup(ep0_urb)) {
+		/* Not a setup packet, stall next EP0 transaction */
+		udc_stall_ep(0);
+		UDCDBG("can't parse setup packet, still waiting for setup");
+		return;
+	}
+
+	/* Check direction */
+	if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
+	    == USB_REQ_HOST2DEVICE) {
+		UDCDBG("control write on EP0");
+		if (le16_to_cpu(ep0_urb->device_request.wLength)) {
+			/* Stall this request */
+			UDCDBG("Stalling unsupported EP0 control write data "
+			       "stage.");
+			udc_stall_ep(0);
+		}
+	} else {
+
+		UDCDBG("control read on EP0");
+		/*
+		 * The ep0_recv_setup function has already placed our response
+		 * packet data in ep0_urb->buffer and the packet length in
+		 * ep0_urb->actual_length.
+		 */
+		endpoint->tx_urb = ep0_urb;
+		endpoint->sent = 0;
+		/*
+		 * Write packet data to the FIFO.  dw_write_noniso_tx_fifo
+		 * will update endpoint->last with the number of bytes written
+		 * to the FIFO.
+		 */
+		dw_write_noniso_tx_fifo(endpoint);
+
+		writel(0x0, &inep_regs_p[ep_addr].write_done);
+	}
+
+	udc_unset_nak(endpoint->endpoint_address);
+
+	UDCDBG("<- Leaving device setup");
+}
+
+/*
+ * Handle endpoint 0 RX interrupt
+ */
+static void dw_udc_ep0_rx(struct usb_endpoint_instance *endpoint)
+{
+	u8 dummy[64];
+
+	UDCDBG("RX on EP0");
+
+	/* Check direction */
+	if ((ep0_urb->device_request.bmRequestType
+	     & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) {
+		/*
+		 * This rx interrupt must be for a control write data
+		 * stage packet.
+		 *
+		 * We don't support control write data stages.
+		 * We should never end up here.
+		 */
+
+		UDCDBG("Stalling unexpected EP0 control write "
+		       "data stage packet");
+		udc_stall_ep(0);
+	} else {
+		/*
+		 * This rx interrupt must be for a control read status
+		 * stage packet.
+		 */
+		UDCDBG("ACK on EP0 control read status stage packet");
+		u32 len = (readl(&outep_regs_p[0].endp_status) >> 11) & 0xfff;
+		usbgetpckfromfifo(0, dummy, len);
+	}
+}
+
+/*
+ * Handle endpoint 0 TX interrupt
+ */
+static void dw_udc_ep0_tx(struct usb_endpoint_instance *endpoint)
+{
+	struct usb_device_request *request = &ep0_urb->device_request;
+	int ep_addr;
+
+	UDCDBG("TX on EP0");
+
+	/* Check direction */
+	if ((request->bmRequestType & USB_REQ_DIRECTION_MASK) ==
+	    USB_REQ_HOST2DEVICE) {
+		/*
+		 * This tx interrupt must be for a control write status
+		 * stage packet.
+		 */
+		UDCDBG("ACK on EP0 control write status stage packet");
+	} else {
+		/*
+		 * This tx interrupt must be for a control read data
+		 * stage packet.
+		 */
+		int wLength = le16_to_cpu(request->wLength);
+
+		/*
+		 * Update our count of bytes sent so far in this
+		 * transfer.
+		 */
+		endpoint->sent += endpoint->last;
+
+		/*
+		 * We are finished with this transfer if we have sent
+		 * all of the bytes in our tx urb (urb->actual_length)
+		 * unless we need a zero-length terminating packet.  We
+		 * need a zero-length terminating packet if we returned
+		 * fewer bytes than were requested (wLength) by the host,
+		 * and the number of bytes we returned is an exact
+		 * multiple of the packet size endpoint->tx_packetSize.
+		 */
+		if ((endpoint->sent == ep0_urb->actual_length) &&
+		    ((ep0_urb->actual_length == wLength) ||
+		     (endpoint->last != endpoint->tx_packetSize))) {
+			/* Done with control read data stage. */
+			UDCDBG("control read data stage complete");
+		} else {
+			/*
+			 * We still have another packet of data to send
+			 * in this control read data stage or else we
+			 * need a zero-length terminating packet.
+			 */
+			UDCDBG("ACK control read data stage packet");
+			dw_write_noniso_tx_fifo(endpoint);
+
+			ep_addr = endpoint->endpoint_address;
+			writel(0x0, &inep_regs_p[ep_addr].write_done);
+		}
+	}
+}
+
+static struct usb_endpoint_instance *dw_find_ep(int ep)
+{
+	int i;
+
+	for (i = 0; i < udc_device->bus->max_endpoints; i++) {
+		if ((udc_device->bus->endpoint_array[i].endpoint_address &
+		     USB_ENDPOINT_NUMBER_MASK) == ep)
+			return &udc_device->bus->endpoint_array[i];
+	}
+	return NULL;
+}
+
+/*
+ * Handle RX transaction on non-ISO endpoint.
+ * The ep argument is a physical endpoint number for a non-ISO IN endpoint
+ * in the range 1 to 15.
+ */
+static void dw_udc_epn_rx(int ep)
+{
+	int nbytes = 0;
+	struct urb *urb;
+	struct usb_endpoint_instance *endpoint = dw_find_ep(ep);
+
+	if (endpoint) {
+		urb = endpoint->rcv_urb;
+
+		if (urb) {
+			u8 *cp = urb->buffer + urb->actual_length;
+
+			nbytes = (readl(&outep_regs_p[ep].endp_status) >> 11) &
+			    0xfff;
+			usbgetpckfromfifo(ep, cp, nbytes);
+			usbd_rcv_complete(endpoint, nbytes, 0);
+		}
+	}
+}
+
+/*
+ * Handle TX transaction on non-ISO endpoint.
+ * The ep argument is a physical endpoint number for a non-ISO IN endpoint
+ * in the range 16 to 30.
+ */
+static void dw_udc_epn_tx(int ep)
+{
+	struct usb_endpoint_instance *endpoint = dw_find_ep(ep);
+
+	if (!endpoint)
+		return;
+
+	/*
+	 * We need to transmit a terminating zero-length packet now if
+	 * we have sent all of the data in this URB and the transfer
+	 * size was an exact multiple of the packet size.
+	 */
+	if (endpoint->tx_urb &&
+	    (endpoint->last == endpoint->tx_packetSize) &&
+	    (endpoint->tx_urb->actual_length - endpoint->sent -
+	     endpoint->last == 0)) {
+		/* handle zero length packet here */
+		writel(0x0, &inep_regs_p[ep].write_done);
+
+	}
+
+	if (endpoint->tx_urb && endpoint->tx_urb->actual_length) {
+		/* retire the data that was just sent */
+		usbd_tx_complete(endpoint);
+		/*
+		 * Check to see if we have more data ready to transmit
+		 * now.
+		 */
+		if (endpoint->tx_urb && endpoint->tx_urb->actual_length) {
+			/* write data to FIFO */
+			dw_write_noniso_tx_fifo(endpoint);
+			writel(0x0, &inep_regs_p[ep].write_done);
+
+		} else if (endpoint->tx_urb
+			   && (endpoint->tx_urb->actual_length == 0)) {
+			/* udc_set_nak(ep); */
+		}
+	}
+}
+
+/*
+ * Start of public functions.
+ */
+
+/* Called to start packet transmission. */
+int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
+{
+	udc_unset_nak(endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK);
+	return 0;
+}
+
+/* Start to initialize h/w stuff */
+int udc_init(void)
+{
+	int i;
+	u32 plug_st;
+
+	udc_device = NULL;
+
+	UDCDBG("starting");
+
+	readl(&plug_regs_p->plug_pending);
+
+	for (i = 0; i < UDC_INIT_MDELAY; i++)
+		udelay(1000);
+
+	plug_st = readl(&plug_regs_p->plug_state);
+	writel(plug_st | PLUG_STATUS_EN, &plug_regs_p->plug_state);
+
+	writel(~0x0, &udc_regs_p->endp_int);
+	writel(~0x0, &udc_regs_p->dev_int_mask);
+	writel(~0x0, &udc_regs_p->endp_int_mask);
+
+	writel(DEV_CONF_FS_SPEED | DEV_CONF_REMWAKEUP | DEV_CONF_SELFPOW |
+	       DEV_CONF_PHYINT_16, &udc_regs_p->dev_conf);
+
+	writel(DEV_CNTL_SD, &udc_regs_p->dev_cntl);
+
+	/* Clear all interrupts pending */
+	writel(DEV_INT_MSK, &udc_regs_p->dev_int);
+
+	return 0;
+}
+
+/*
+ * udc_setup_ep - setup endpoint
+ * Associate a physical endpoint with endpoint_instance
+ */
+void udc_setup_ep(struct usb_device_instance *device,
+		  u32 ep, struct usb_endpoint_instance *endpoint)
+{
+	UDCDBGA("setting up endpoint addr %x", endpoint->endpoint_address);
+	int ep_addr;
+	int ep_num, ep_type;
+	int packet_size;
+	int buffer_size;
+	int attributes;
+	char *tt;
+	u32 endp_intmask;
+
+	if ((ep != 0) && (udc_device->device_state < STATE_ADDRESSED))
+		return;
+
+	tt = getenv("usbtty");
+	if (!tt)
+		tt = "generic";
+
+	ep_addr = endpoint->endpoint_address;
+	ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+
+	if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
+		/* IN endpoint */
+		packet_size = endpoint->tx_packetSize;
+		buffer_size = packet_size * 2;
+		attributes = endpoint->tx_attributes;
+	} else {
+		/* OUT endpoint */
+		packet_size = endpoint->rcv_packetSize;
+		buffer_size = packet_size * 2;
+		attributes = endpoint->rcv_attributes;
+	}
+
+	switch (attributes & USB_ENDPOINT_XFERTYPE_MASK) {
+	case USB_ENDPOINT_XFER_CONTROL:
+		ep_type = ENDP_EPTYPE_CNTL;
+		break;
+	case USB_ENDPOINT_XFER_BULK:
+	default:
+		ep_type = ENDP_EPTYPE_BULK;
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		ep_type = ENDP_EPTYPE_INT;
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		ep_type = ENDP_EPTYPE_ISO;
+		break;
+	}
+
+	struct udc_endp_regs *out_p = &outep_regs_p[ep_num];
+	struct udc_endp_regs *in_p = &inep_regs_p[ep_num];
+
+	if (!ep_addr) {
+		/* Setup endpoint 0 */
+		buffer_size = packet_size;
+
+		writel(readl(&in_p->endp_cntl) | ENDP_CNTL_CNAK,
+		       &in_p->endp_cntl);
+
+		writel(readl(&out_p->endp_cntl) | ENDP_CNTL_CNAK,
+		       &out_p->endp_cntl);
+
+		writel(ENDP_CNTL_CONTROL | ENDP_CNTL_FLUSH, &in_p->endp_cntl);
+
+		writel(buffer_size / sizeof(int), &in_p->endp_bsorfn);
+
+		writel(packet_size, &in_p->endp_maxpacksize);
+
+		writel(ENDP_CNTL_CONTROL | ENDP_CNTL_RRDY, &out_p->endp_cntl);
+
+		writel(packet_size | ((buffer_size / sizeof(int)) << 16),
+		       &out_p->endp_maxpacksize);
+
+	} else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
+		/* Setup the IN endpoint */
+		writel(0x0, &in_p->endp_status);
+		writel((ep_type << 4) | ENDP_CNTL_RRDY, &in_p->endp_cntl);
+		writel(buffer_size / sizeof(int), &in_p->endp_bsorfn);
+		writel(packet_size, &in_p->endp_maxpacksize);
+
+		if (!strcmp(tt, "cdc_acm")) {
+			if (ep_type == ENDP_EPTYPE_INT) {
+				/* Conf no. 1 Interface no. 0 */
+				writel((packet_size << 19) |
+				       ENDP_EPDIR_IN | (1 << 7) |
+				       (0 << 11) | (ep_type << 5) | ep_num,
+				       &udc_regs_p->udc_endp_reg[ep_num]);
+			} else {
+				/* Conf no. 1 Interface no. 1 */
+				writel((packet_size << 19) |
+				       ENDP_EPDIR_IN | (1 << 7) |
+				       (1 << 11) | (ep_type << 5) | ep_num,
+				       &udc_regs_p->udc_endp_reg[ep_num]);
+			}
+		} else {
+			/* Conf no. 1 Interface no. 0 */
+			writel((packet_size << 19) |
+			       ENDP_EPDIR_IN | (1 << 7) |
+			       (0 << 11) | (ep_type << 5) | ep_num,
+			       &udc_regs_p->udc_endp_reg[ep_num]);
+		}
+
+	} else {
+		/* Setup the OUT endpoint */
+		writel(0x0, &out_p->endp_status);
+		writel((ep_type << 4) | ENDP_CNTL_RRDY, &out_p->endp_cntl);
+		writel(packet_size | ((buffer_size / sizeof(int)) << 16),
+		       &out_p->endp_maxpacksize);
+
+		if (!strcmp(tt, "cdc_acm")) {
+			writel((packet_size << 19) |
+			       ENDP_EPDIR_OUT | (1 << 7) |
+			       (1 << 11) | (ep_type << 5) | ep_num,
+			       &udc_regs_p->udc_endp_reg[ep_num]);
+		} else {
+			writel((packet_size << 19) |
+			       ENDP_EPDIR_OUT | (1 << 7) |
+			       (0 << 11) | (ep_type << 5) | ep_num,
+			       &udc_regs_p->udc_endp_reg[ep_num]);
+		}
+
+	}
+
+	endp_intmask = readl(&udc_regs_p->endp_int_mask);
+	endp_intmask &= ~((1 << ep_num) | 0x10000 << ep_num);
+	writel(endp_intmask, &udc_regs_p->endp_int_mask);
+}
+
+/* Turn on the USB connection by enabling the pullup resistor */
+void udc_connect(void)
+{
+	u32 plug_st, dev_cntl;
+
+	dev_cntl = readl(&udc_regs_p->dev_cntl);
+	dev_cntl |= DEV_CNTL_SD;
+	writel(dev_cntl, &udc_regs_p->dev_cntl);
+
+	udelay(1000);
+
+	dev_cntl = readl(&udc_regs_p->dev_cntl);
+	dev_cntl &= ~DEV_CNTL_SD;
+	writel(dev_cntl, &udc_regs_p->dev_cntl);
+
+	plug_st = readl(&plug_regs_p->plug_state);
+	plug_st &= ~(PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE);
+	writel(plug_st, &plug_regs_p->plug_state);
+}
+
+/* Turn off the USB connection by disabling the pullup resistor */
+void udc_disconnect(void)
+{
+	u32 plug_st;
+
+	writel(DEV_CNTL_SD, &udc_regs_p->dev_cntl);
+
+	plug_st = readl(&plug_regs_p->plug_state);
+	plug_st |= (PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE);
+	writel(plug_st, &plug_regs_p->plug_state);
+}
+
+/* Switch on the UDC */
+void udc_enable(struct usb_device_instance *device)
+{
+	UDCDBGA("enable device %p, status %d", device, device->status);
+
+	/* Save the device structure pointer */
+	udc_device = device;
+
+	/* Setup ep0 urb */
+	if (!ep0_urb) {
+		ep0_urb =
+		    usbd_alloc_urb(udc_device, udc_device->bus->endpoint_array);
+	} else {
+		serial_printf("udc_enable: ep0_urb already allocated %p\n",
+			      ep0_urb);
+	}
+
+	writel(DEV_INT_SOF, &udc_regs_p->dev_int_mask);
+}
+
+/**
+ * udc_startup - allow udc code to do any additional startup
+ */
+void udc_startup_events(struct usb_device_instance *device)
+{
+	/* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
+	usbd_device_event_irq(device, DEVICE_INIT, 0);
+
+	/*
+	 * The DEVICE_CREATE event puts the USB device in the state
+	 * STATE_ATTACHED.
+	 */
+	usbd_device_event_irq(device, DEVICE_CREATE, 0);
+
+	/*
+	 * Some USB controller driver implementations signal
+	 * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
+	 * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
+	 * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
+	 * The DW USB client controller has the capability to detect when the
+	 * USB cable is connected to a powered USB bus, so we will defer the
+	 * DEVICE_HUB_CONFIGURED and DEVICE_RESET events until later.
+	 */
+
+	udc_enable(device);
+}
+
+/*
+ * Plug detection interrupt handling
+ */
+void dw_udc_plug_irq(void)
+{
+	if (readl(&plug_regs_p->plug_state) & PLUG_STATUS_ATTACHED) {
+		/*
+		 * USB cable attached
+		 * Turn off PHY reset bit (PLUG detect).
+		 * Switch PHY opmode to normal operation (PLUG detect).
+		 */
+		udc_connect();
+		writel(DEV_INT_SOF, &udc_regs_p->dev_int_mask);
+
+		UDCDBG("device attached and powered");
+		udc_state_transition(udc_device->device_state, STATE_POWERED);
+	} else {
+		writel(~0x0, &udc_regs_p->dev_int_mask);
+
+		UDCDBG("device detached or unpowered");
+		udc_state_transition(udc_device->device_state, STATE_ATTACHED);
+	}
+}
+
+/*
+ * Device interrupt handling
+ */
+void dw_udc_dev_irq(void)
+{
+	if (readl(&udc_regs_p->dev_int) & DEV_INT_USBRESET) {
+		writel(~0x0, &udc_regs_p->endp_int_mask);
+
+		writel(readl(&inep_regs_p[0].endp_cntl) | ENDP_CNTL_FLUSH,
+		       &inep_regs_p[0].endp_cntl);
+
+		writel(DEV_INT_USBRESET, &udc_regs_p->dev_int);
+
+		/*
+		 * This endpoint0 specific register can be programmed only
+		 * after the phy clock is initialized
+		 */
+		writel((EP0_MAX_PACKET_SIZE << 19) | ENDP_EPTYPE_CNTL,
+				&udc_regs_p->udc_endp_reg[0]);
+
+		UDCDBG("device reset in progess");
+		udc_state_transition(udc_device->device_state, STATE_DEFAULT);
+	}
+
+	/* Device Enumeration completed */
+	if (readl(&udc_regs_p->dev_int) & DEV_INT_ENUM) {
+		writel(DEV_INT_ENUM, &udc_regs_p->dev_int);
+
+		/* Endpoint interrupt enabled for Ctrl IN & Ctrl OUT */
+		writel(readl(&udc_regs_p->endp_int_mask) & ~0x10001,
+		       &udc_regs_p->endp_int_mask);
+
+		UDCDBG("default -> addressed");
+		udc_state_transition(udc_device->device_state, STATE_ADDRESSED);
+	}
+
+	/* The USB will be in SUSPEND in 3 ms */
+	if (readl(&udc_regs_p->dev_int) & DEV_INT_INACTIVE) {
+		writel(DEV_INT_INACTIVE, &udc_regs_p->dev_int);
+
+		UDCDBG("entering inactive state");
+		/* usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0); */
+	}
+
+	/* SetConfiguration command received */
+	if (readl(&udc_regs_p->dev_int) & DEV_INT_SETCFG) {
+		writel(DEV_INT_SETCFG, &udc_regs_p->dev_int);
+
+		UDCDBG("entering configured state");
+		udc_state_transition(udc_device->device_state,
+				     STATE_CONFIGURED);
+	}
+
+	/* SetInterface command received */
+	if (readl(&udc_regs_p->dev_int) & DEV_INT_SETINTF)
+		writel(DEV_INT_SETINTF, &udc_regs_p->dev_int);
+
+	/* USB Suspend detected on cable */
+	if (readl(&udc_regs_p->dev_int) & DEV_INT_SUSPUSB) {
+		writel(DEV_INT_SUSPUSB, &udc_regs_p->dev_int);
+
+		UDCDBG("entering suspended state");
+		usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0);
+	}
+
+	/* USB Start-Of-Frame detected on cable */
+	if (readl(&udc_regs_p->dev_int) & DEV_INT_SOF)
+		writel(DEV_INT_SOF, &udc_regs_p->dev_int);
+}
+
+/*
+ * Endpoint interrupt handling
+ */
+void dw_udc_endpoint_irq(void)
+{
+	while (readl(&udc_regs_p->endp_int) & ENDP0_INT_CTRLOUT) {
+
+		writel(ENDP0_INT_CTRLOUT, &udc_regs_p->endp_int);
+
+		if ((readl(&outep_regs_p[0].endp_status) & ENDP_STATUS_OUTMSK)
+		    == ENDP_STATUS_OUT_SETUP) {
+			dw_udc_setup(udc_device->bus->endpoint_array + 0);
+			writel(ENDP_STATUS_OUT_SETUP,
+			       &outep_regs_p[0].endp_status);
+
+		} else if ((readl(&outep_regs_p[0].endp_status) &
+			    ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_DATA) {
+			dw_udc_ep0_rx(udc_device->bus->endpoint_array + 0);
+			writel(ENDP_STATUS_OUT_DATA,
+			       &outep_regs_p[0].endp_status);
+
+		} else if ((readl(&outep_regs_p[0].endp_status) &
+			    ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_NONE) {
+			/* NONE received */
+		}
+
+		writel(0x0, &outep_regs_p[0].endp_status);
+	}
+
+	if (readl(&udc_regs_p->endp_int) & ENDP0_INT_CTRLIN) {
+		dw_udc_ep0_tx(udc_device->bus->endpoint_array + 0);
+
+		writel(ENDP_STATUS_IN, &inep_regs_p[0].endp_status);
+		writel(ENDP0_INT_CTRLIN, &udc_regs_p->endp_int);
+	}
+
+	if (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOOUT_MSK) {
+		u32 epnum = 0;
+		u32 ep_int = readl(&udc_regs_p->endp_int) &
+		    ENDP_INT_NONISOOUT_MSK;
+
+		ep_int >>= 16;
+		while (0x0 == (ep_int & 0x1)) {
+			ep_int >>= 1;
+			epnum++;
+		}
+
+		writel((1 << 16) << epnum, &udc_regs_p->endp_int);
+
+		if ((readl(&outep_regs_p[epnum].endp_status) &
+		     ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_DATA) {
+
+			dw_udc_epn_rx(epnum);
+			writel(ENDP_STATUS_OUT_DATA,
+			       &outep_regs_p[epnum].endp_status);
+		} else if ((readl(&outep_regs_p[epnum].endp_status) &
+			    ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_NONE) {
+			writel(0x0, &outep_regs_p[epnum].endp_status);
+		}
+	}
+
+	if (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOIN_MSK) {
+		u32 epnum = 0;
+		u32 ep_int = readl(&udc_regs_p->endp_int) &
+		    ENDP_INT_NONISOIN_MSK;
+
+		while (0x0 == (ep_int & 0x1)) {
+			ep_int >>= 1;
+			epnum++;
+		}
+
+		if (readl(&inep_regs_p[epnum].endp_status) & ENDP_STATUS_IN) {
+			writel(ENDP_STATUS_IN,
+			       &outep_regs_p[epnum].endp_status);
+			dw_udc_epn_tx(epnum);
+
+			writel(ENDP_STATUS_IN,
+			       &outep_regs_p[epnum].endp_status);
+		}
+
+		writel((1 << epnum), &udc_regs_p->endp_int);
+	}
+}
+
+/*
+ * UDC interrupts
+ */
+void udc_irq(void)
+{
+	/*
+	 * Loop while we have interrupts.
+	 * If we don't do this, the input chain
+	 * polling delay is likely to miss
+	 * host requests.
+	 */
+	while (readl(&plug_regs_p->plug_pending))
+		dw_udc_plug_irq();
+
+	while (readl(&udc_regs_p->dev_int))
+		dw_udc_dev_irq();
+
+	if (readl(&udc_regs_p->endp_int))
+		dw_udc_endpoint_irq();
+}
+
+/* Flow control */
+void udc_set_nak(int epid)
+{
+	writel(readl(&inep_regs_p[epid].endp_cntl) | ENDP_CNTL_SNAK,
+	       &inep_regs_p[epid].endp_cntl);
+
+	writel(readl(&outep_regs_p[epid].endp_cntl) | ENDP_CNTL_SNAK,
+	       &outep_regs_p[epid].endp_cntl);
+}
+
+void udc_unset_nak(int epid)
+{
+	u32 val;
+
+	val = readl(&inep_regs_p[epid].endp_cntl);
+	val &= ~ENDP_CNTL_SNAK;
+	val |= ENDP_CNTL_CNAK;
+	writel(val, &inep_regs_p[epid].endp_cntl);
+
+	val = readl(&outep_regs_p[epid].endp_cntl);
+	val &= ~ENDP_CNTL_SNAK;
+	val |= ENDP_CNTL_CNAK;
+	writel(val, &outep_regs_p[epid].endp_cntl);
+}
diff --git a/drivers/usb/gadget/spr_udc.c b/drivers/usb/gadget/spr_udc.c
deleted file mode 100644
index f2b06d6..0000000
--- a/drivers/usb/gadget/spr_udc.c
+++ /dev/null
@@ -1,998 +0,0 @@
-/*
- * Based on drivers/usb/gadget/omap1510_udc.c
- * TI OMAP1510 USB bus interface driver
- *
- * (C) Copyright 2009
- * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <asm/io.h>
-
-#include <usbdevice.h>
-#include "ep0.h"
-#include <usb/spr_udc.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/spr_misc.h>
-
-#define UDC_INIT_MDELAY		80	/* Device settle delay */
-
-/* Some kind of debugging output... */
-#ifndef DEBUG_SPRUSBTTY
-#define UDCDBG(str)
-#define UDCDBGA(fmt, args...)
-#else
-#define UDCDBG(str) serial_printf(str "\n")
-#define UDCDBGA(fmt, args...) serial_printf(fmt "\n", ##args)
-#endif
-
-static struct urb *ep0_urb;
-static struct usb_device_instance *udc_device;
-
-static struct plug_regs *const plug_regs_p =
-    (struct plug_regs * const)CONFIG_SYS_PLUG_BASE;
-static struct udc_regs *const udc_regs_p =
-    (struct udc_regs * const)CONFIG_SYS_USBD_BASE;
-static struct udc_endp_regs *const outep_regs_p =
-    &((struct udc_regs * const)CONFIG_SYS_USBD_BASE)->out_regs[0];
-static struct udc_endp_regs *const inep_regs_p =
-    &((struct udc_regs * const)CONFIG_SYS_USBD_BASE)->in_regs[0];
-
-/*
- * udc_state_transition - Write the next packet to TxFIFO.
- * @initial:	Initial state.
- * @final:	Final state.
- *
- * Helper function to implement device state changes. The device states and
- * the events that transition between them are:
- *
- *				STATE_ATTACHED
- *				||	/\
- *				\/	||
- *	DEVICE_HUB_CONFIGURED			DEVICE_HUB_RESET
- *				||	/\
- *				\/	||
- *				STATE_POWERED
- *				||	/\
- *				\/	||
- *	DEVICE_RESET				DEVICE_POWER_INTERRUPTION
- *				||	/\
- *				\/	||
- *				STATE_DEFAULT
- *				||	/\
- *				\/	||
- *	DEVICE_ADDRESS_ASSIGNED			DEVICE_RESET
- *				||	/\
- *				\/	||
- *				STATE_ADDRESSED
- *				||	/\
- *				\/	||
- *	DEVICE_CONFIGURED			DEVICE_DE_CONFIGURED
- *				||	/\
- *				\/	||
- *				STATE_CONFIGURED
- *
- * udc_state_transition transitions up (in the direction from STATE_ATTACHED
- * to STATE_CONFIGURED) from the specified initial state to the specified final
- * state, passing through each intermediate state on the way. If the initial
- * state is at or above (i.e. nearer to STATE_CONFIGURED) the final state, then
- * no state transitions will take place.
- *
- * udc_state_transition also transitions down (in the direction from
- * STATE_CONFIGURED to STATE_ATTACHED) from the specified initial state to the
- * specified final state, passing through each intermediate state on the way.
- * If the initial state is at or below (i.e. nearer to STATE_ATTACHED) the final
- * state, then no state transitions will take place.
- *
- * This function must only be called with interrupts disabled.
- */
-static void udc_state_transition(usb_device_state_t initial,
-				 usb_device_state_t final)
-{
-	if (initial < final) {
-		switch (initial) {
-		case STATE_ATTACHED:
-			usbd_device_event_irq(udc_device,
-					      DEVICE_HUB_CONFIGURED, 0);
-			if (final == STATE_POWERED)
-				break;
-		case STATE_POWERED:
-			usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
-			if (final == STATE_DEFAULT)
-				break;
-		case STATE_DEFAULT:
-			usbd_device_event_irq(udc_device,
-					      DEVICE_ADDRESS_ASSIGNED, 0);
-			if (final == STATE_ADDRESSED)
-				break;
-		case STATE_ADDRESSED:
-			usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0);
-		case STATE_CONFIGURED:
-			break;
-		default:
-			break;
-		}
-	} else if (initial > final) {
-		switch (initial) {
-		case STATE_CONFIGURED:
-			usbd_device_event_irq(udc_device,
-					      DEVICE_DE_CONFIGURED, 0);
-			if (final == STATE_ADDRESSED)
-				break;
-		case STATE_ADDRESSED:
-			usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
-			if (final == STATE_DEFAULT)
-				break;
-		case STATE_DEFAULT:
-			usbd_device_event_irq(udc_device,
-					      DEVICE_POWER_INTERRUPTION, 0);
-			if (final == STATE_POWERED)
-				break;
-		case STATE_POWERED:
-			usbd_device_event_irq(udc_device, DEVICE_HUB_RESET, 0);
-		case STATE_ATTACHED:
-			break;
-		default:
-			break;
-		}
-	}
-}
-
-/* Stall endpoint */
-static void udc_stall_ep(u32 ep_num)
-{
-	writel(readl(&inep_regs_p[ep_num].endp_cntl) | ENDP_CNTL_STALL,
-	       &inep_regs_p[ep_num].endp_cntl);
-
-	writel(readl(&outep_regs_p[ep_num].endp_cntl) | ENDP_CNTL_STALL,
-	       &outep_regs_p[ep_num].endp_cntl);
-}
-
-static void *get_fifo(int ep_num, int in)
-{
-	u32 *fifo_ptr = (u32 *)CONFIG_SYS_FIFO_BASE;
-
-	switch (ep_num) {
-	case UDC_EP3:
-		fifo_ptr += readl(&inep_regs_p[1].endp_bsorfn);
-		/* break intentionally left out */
-
-	case UDC_EP1:
-		fifo_ptr += readl(&inep_regs_p[0].endp_bsorfn);
-		/* break intentionally left out */
-
-	case UDC_EP0:
-	default:
-		if (in) {
-			fifo_ptr +=
-			    readl(&outep_regs_p[2].endp_maxpacksize) >> 16;
-			/* break intentionally left out */
-		} else {
-			break;
-		}
-
-	case UDC_EP2:
-		fifo_ptr += readl(&outep_regs_p[0].endp_maxpacksize) >> 16;
-		/* break intentionally left out */
-	}
-
-	return (void *)fifo_ptr;
-}
-
-static int usbgetpckfromfifo(int epNum, u8 *bufp, u32 len)
-{
-	u8 *fifo_ptr = (u8 *)get_fifo(epNum, 0);
-	u32 i, nw, nb;
-	u32 *wrdp;
-	u8 *bytp;
-
-	if (readl(&udc_regs_p->dev_stat) & DEV_STAT_RXFIFO_EMPTY)
-		return -1;
-
-	nw = len / sizeof(u32);
-	nb = len % sizeof(u32);
-
-	wrdp = (u32 *)bufp;
-	for (i = 0; i < nw; i++) {
-		writel(readl(fifo_ptr), wrdp);
-		wrdp++;
-	}
-
-	bytp = (u8 *)wrdp;
-	for (i = 0; i < nb; i++) {
-		writeb(readb(fifo_ptr), bytp);
-		fifo_ptr++;
-		bytp++;
-	}
-	readl(&outep_regs_p[epNum].write_done);
-
-	return 0;
-}
-
-static void usbputpcktofifo(int epNum, u8 *bufp, u32 len)
-{
-	u32 i, nw, nb;
-	u32 *wrdp;
-	u8 *bytp;
-	u8 *fifo_ptr = get_fifo(epNum, 1);
-
-	nw = len / sizeof(int);
-	nb = len % sizeof(int);
-	wrdp = (u32 *)bufp;
-	for (i = 0; i < nw; i++) {
-		writel(*wrdp, fifo_ptr);
-		wrdp++;
-	}
-
-	bytp = (u8 *)wrdp;
-	for (i = 0; i < nb; i++) {
-		writeb(*bytp, fifo_ptr);
-		fifo_ptr++;
-		bytp++;
-	}
-}
-
-/*
- * spear_write_noniso_tx_fifo - Write the next packet to TxFIFO.
- * @endpoint:		Endpoint pointer.
- *
- * If the endpoint has an active tx_urb, then the next packet of data from the
- * URB is written to the tx FIFO.  The total amount of data in the urb is given
- * by urb->actual_length.  The maximum amount of data that can be sent in any
- * one packet is given by endpoint->tx_packetSize.  The number of data bytes
- * from this URB that have already been transmitted is given by endpoint->sent.
- * endpoint->last is updated by this routine with the number of data bytes
- * transmitted in this packet.
- *
- */
-static void spear_write_noniso_tx_fifo(struct usb_endpoint_instance
-				       *endpoint)
-{
-	struct urb *urb = endpoint->tx_urb;
-	int align;
-
-	if (urb) {
-		u32 last;
-
-		UDCDBGA("urb->buffer %p, buffer_length %d, actual_length %d",
-			urb->buffer, urb->buffer_length, urb->actual_length);
-
-		last = MIN(urb->actual_length - endpoint->sent,
-			   endpoint->tx_packetSize);
-
-		if (last) {
-			u8 *cp = urb->buffer + endpoint->sent;
-
-			/*
-			 * This ensures that USBD packet fifo is accessed
-			 * - through word aligned pointer or
-			 * - through non word aligned pointer but only
-			 *   with a max length to make the next packet
-			 *   word aligned
-			 */
-
-			align = ((ulong)cp % sizeof(int));
-			if (align)
-				last = MIN(last, sizeof(int) - align);
-
-			UDCDBGA("endpoint->sent %d, tx_packetSize %d, last %d",
-				endpoint->sent, endpoint->tx_packetSize, last);
-
-			usbputpcktofifo(endpoint->endpoint_address &
-					USB_ENDPOINT_NUMBER_MASK, cp, last);
-		}
-		endpoint->last = last;
-	}
-}
-
-/*
- * Handle SETUP USB interrupt.
- * This function implements TRM Figure 14-14.
- */
-static void spear_udc_setup(struct usb_endpoint_instance *endpoint)
-{
-	u8 *datap = (u8 *)&ep0_urb->device_request;
-	int ep_addr = endpoint->endpoint_address;
-
-	UDCDBG("-> Entering device setup");
-	usbgetpckfromfifo(ep_addr, datap, 8);
-
-	/* Try to process setup packet */
-	if (ep0_recv_setup(ep0_urb)) {
-		/* Not a setup packet, stall next EP0 transaction */
-		udc_stall_ep(0);
-		UDCDBG("can't parse setup packet, still waiting for setup");
-		return;
-	}
-
-	/* Check direction */
-	if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
-	    == USB_REQ_HOST2DEVICE) {
-		UDCDBG("control write on EP0");
-		if (le16_to_cpu(ep0_urb->device_request.wLength)) {
-			/* Stall this request */
-			UDCDBG("Stalling unsupported EP0 control write data "
-			       "stage.");
-			udc_stall_ep(0);
-		}
-	} else {
-
-		UDCDBG("control read on EP0");
-		/*
-		 * The ep0_recv_setup function has already placed our response
-		 * packet data in ep0_urb->buffer and the packet length in
-		 * ep0_urb->actual_length.
-		 */
-		endpoint->tx_urb = ep0_urb;
-		endpoint->sent = 0;
-		/*
-		 * Write packet data to the FIFO.  spear_write_noniso_tx_fifo
-		 * will update endpoint->last with the number of bytes written
-		 * to the FIFO.
-		 */
-		spear_write_noniso_tx_fifo(endpoint);
-
-		writel(0x0, &inep_regs_p[ep_addr].write_done);
-	}
-
-	udc_unset_nak(endpoint->endpoint_address);
-
-	UDCDBG("<- Leaving device setup");
-}
-
-/*
- * Handle endpoint 0 RX interrupt
- */
-static void spear_udc_ep0_rx(struct usb_endpoint_instance *endpoint)
-{
-	u8 dummy[64];
-
-	UDCDBG("RX on EP0");
-
-	/* Check direction */
-	if ((ep0_urb->device_request.bmRequestType
-	     & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) {
-		/*
-		 * This rx interrupt must be for a control write data
-		 * stage packet.
-		 *
-		 * We don't support control write data stages.
-		 * We should never end up here.
-		 */
-
-		UDCDBG("Stalling unexpected EP0 control write "
-		       "data stage packet");
-		udc_stall_ep(0);
-	} else {
-		/*
-		 * This rx interrupt must be for a control read status
-		 * stage packet.
-		 */
-		UDCDBG("ACK on EP0 control read status stage packet");
-		u32 len = (readl(&outep_regs_p[0].endp_status) >> 11) & 0xfff;
-		usbgetpckfromfifo(0, dummy, len);
-	}
-}
-
-/*
- * Handle endpoint 0 TX interrupt
- */
-static void spear_udc_ep0_tx(struct usb_endpoint_instance *endpoint)
-{
-	struct usb_device_request *request = &ep0_urb->device_request;
-	int ep_addr;
-
-	UDCDBG("TX on EP0");
-
-	/* Check direction */
-	if ((request->bmRequestType & USB_REQ_DIRECTION_MASK) ==
-	    USB_REQ_HOST2DEVICE) {
-		/*
-		 * This tx interrupt must be for a control write status
-		 * stage packet.
-		 */
-		UDCDBG("ACK on EP0 control write status stage packet");
-	} else {
-		/*
-		 * This tx interrupt must be for a control read data
-		 * stage packet.
-		 */
-		int wLength = le16_to_cpu(request->wLength);
-
-		/*
-		 * Update our count of bytes sent so far in this
-		 * transfer.
-		 */
-		endpoint->sent += endpoint->last;
-
-		/*
-		 * We are finished with this transfer if we have sent
-		 * all of the bytes in our tx urb (urb->actual_length)
-		 * unless we need a zero-length terminating packet.  We
-		 * need a zero-length terminating packet if we returned
-		 * fewer bytes than were requested (wLength) by the host,
-		 * and the number of bytes we returned is an exact
-		 * multiple of the packet size endpoint->tx_packetSize.
-		 */
-		if ((endpoint->sent == ep0_urb->actual_length) &&
-		    ((ep0_urb->actual_length == wLength) ||
-		     (endpoint->last != endpoint->tx_packetSize))) {
-			/* Done with control read data stage. */
-			UDCDBG("control read data stage complete");
-		} else {
-			/*
-			 * We still have another packet of data to send
-			 * in this control read data stage or else we
-			 * need a zero-length terminating packet.
-			 */
-			UDCDBG("ACK control read data stage packet");
-			spear_write_noniso_tx_fifo(endpoint);
-
-			ep_addr = endpoint->endpoint_address;
-			writel(0x0, &inep_regs_p[ep_addr].write_done);
-		}
-	}
-}
-
-static struct usb_endpoint_instance *spear_find_ep(int ep)
-{
-	int i;
-
-	for (i = 0; i < udc_device->bus->max_endpoints; i++) {
-		if ((udc_device->bus->endpoint_array[i].endpoint_address &
-		     USB_ENDPOINT_NUMBER_MASK) == ep)
-			return &udc_device->bus->endpoint_array[i];
-	}
-	return NULL;
-}
-
-/*
- * Handle RX transaction on non-ISO endpoint.
- * The ep argument is a physical endpoint number for a non-ISO IN endpoint
- * in the range 1 to 15.
- */
-static void spear_udc_epn_rx(int ep)
-{
-	int nbytes = 0;
-	struct urb *urb;
-	struct usb_endpoint_instance *endpoint = spear_find_ep(ep);
-
-	if (endpoint) {
-		urb = endpoint->rcv_urb;
-
-		if (urb) {
-			u8 *cp = urb->buffer + urb->actual_length;
-
-			nbytes = (readl(&outep_regs_p[ep].endp_status) >> 11) &
-			    0xfff;
-			usbgetpckfromfifo(ep, cp, nbytes);
-			usbd_rcv_complete(endpoint, nbytes, 0);
-		}
-	}
-}
-
-/*
- * Handle TX transaction on non-ISO endpoint.
- * The ep argument is a physical endpoint number for a non-ISO IN endpoint
- * in the range 16 to 30.
- */
-static void spear_udc_epn_tx(int ep)
-{
-	struct usb_endpoint_instance *endpoint = spear_find_ep(ep);
-
-	/*
-	 * We need to transmit a terminating zero-length packet now if
-	 * we have sent all of the data in this URB and the transfer
-	 * size was an exact multiple of the packet size.
-	 */
-	if (endpoint && endpoint->tx_urb && endpoint->tx_urb->actual_length) {
-		if (endpoint->last == endpoint->tx_packetSize) {
-			/* handle zero length packet here */
-			writel(0x0, &inep_regs_p[ep].write_done);
-		}
-		/* retire the data that was just sent */
-		usbd_tx_complete(endpoint);
-		/*
-		 * Check to see if we have more data ready to transmit
-		 * now.
-		 */
-		if (endpoint->tx_urb && endpoint->tx_urb->actual_length) {
-			/* write data to FIFO */
-			spear_write_noniso_tx_fifo(endpoint);
-			writel(0x0, &inep_regs_p[ep].write_done);
-
-		} else if (endpoint->tx_urb
-			   && (endpoint->tx_urb->actual_length == 0)) {
-			/* udc_set_nak(ep); */
-		}
-	}
-}
-
-/*
- * Start of public functions.
- */
-
-/* Called to start packet transmission. */
-int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
-{
-	udc_unset_nak(endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK);
-	return 0;
-}
-
-/* Start to initialize h/w stuff */
-int udc_init(void)
-{
-	int i;
-	u32 plug_st;
-
-	udc_device = NULL;
-
-	UDCDBG("starting");
-
-	readl(&plug_regs_p->plug_pending);
-
-	udc_disconnect();
-
-	for (i = 0; i < UDC_INIT_MDELAY; i++)
-		udelay(1000);
-
-	plug_st = readl(&plug_regs_p->plug_state);
-	writel(plug_st | PLUG_STATUS_EN, &plug_regs_p->plug_state);
-
-	writel(~0x0, &udc_regs_p->endp_int);
-	writel(~0x0, &udc_regs_p->dev_int_mask);
-	writel(~0x0, &udc_regs_p->endp_int_mask);
-
-	writel(DEV_CONF_FS_SPEED | DEV_CONF_REMWAKEUP | DEV_CONF_SELFPOW |
-	       /* Dev_Conf_SYNCFRAME | */
-	       DEV_CONF_PHYINT_16, &udc_regs_p->dev_conf);
-
-	writel(0x0, &udc_regs_p->dev_cntl);
-
-	/* Clear all interrupts pending */
-	writel(DEV_INT_MSK, &udc_regs_p->dev_int);
-
-	return 0;
-}
-
-/*
- * udc_setup_ep - setup endpoint
- * Associate a physical endpoint with endpoint_instance
- */
-void udc_setup_ep(struct usb_device_instance *device,
-		  u32 ep, struct usb_endpoint_instance *endpoint)
-{
-	UDCDBGA("setting up endpoint addr %x", endpoint->endpoint_address);
-	int ep_addr;
-	int ep_num, ep_type;
-	int packet_size;
-	int buffer_size;
-	int attributes;
-	char *tt;
-	u32 endp_intmask;
-
-	tt = getenv("usbtty");
-	if (!tt)
-		tt = "generic";
-
-	ep_addr = endpoint->endpoint_address;
-	ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
-
-	if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
-		/* IN endpoint */
-		packet_size = endpoint->tx_packetSize;
-		buffer_size = packet_size * 2;
-		attributes = endpoint->tx_attributes;
-	} else {
-		/* OUT endpoint */
-		packet_size = endpoint->rcv_packetSize;
-		buffer_size = packet_size * 2;
-		attributes = endpoint->rcv_attributes;
-	}
-
-	switch (attributes & USB_ENDPOINT_XFERTYPE_MASK) {
-	case USB_ENDPOINT_XFER_CONTROL:
-		ep_type = ENDP_EPTYPE_CNTL;
-		break;
-	case USB_ENDPOINT_XFER_BULK:
-	default:
-		ep_type = ENDP_EPTYPE_BULK;
-		break;
-	case USB_ENDPOINT_XFER_INT:
-		ep_type = ENDP_EPTYPE_INT;
-		break;
-	case USB_ENDPOINT_XFER_ISOC:
-		ep_type = ENDP_EPTYPE_ISO;
-		break;
-	}
-
-	struct udc_endp_regs *out_p = &outep_regs_p[ep_num];
-	struct udc_endp_regs *in_p = &inep_regs_p[ep_num];
-
-	if (!ep_addr) {
-		/* Setup endpoint 0 */
-		buffer_size = packet_size;
-
-		writel(readl(&in_p->endp_cntl) | ENDP_CNTL_CNAK,
-		       &in_p->endp_cntl);
-
-		writel(readl(&out_p->endp_cntl) | ENDP_CNTL_CNAK,
-		       &out_p->endp_cntl);
-
-		writel(ENDP_CNTL_CONTROL | ENDP_CNTL_FLUSH, &in_p->endp_cntl);
-
-		writel(buffer_size / sizeof(int), &in_p->endp_bsorfn);
-
-		writel(packet_size, &in_p->endp_maxpacksize);
-
-		writel(ENDP_CNTL_CONTROL | ENDP_CNTL_RRDY, &out_p->endp_cntl);
-
-		writel(packet_size | ((buffer_size / sizeof(int)) << 16),
-		       &out_p->endp_maxpacksize);
-
-		writel((packet_size << 19) | ENDP_EPTYPE_CNTL,
-		       &udc_regs_p->udc_endp_reg[ep_num]);
-
-	} else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
-		/* Setup the IN endpoint */
-		writel(0x0, &in_p->endp_status);
-		writel((ep_type << 4) | ENDP_CNTL_RRDY, &in_p->endp_cntl);
-		writel(buffer_size / sizeof(int), &in_p->endp_bsorfn);
-		writel(packet_size, &in_p->endp_maxpacksize);
-
-		if (!strcmp(tt, "cdc_acm")) {
-			if (ep_type == ENDP_EPTYPE_INT) {
-				/* Conf no. 1 Interface no. 0 */
-				writel((packet_size << 19) |
-				       ENDP_EPDIR_IN | (1 << 7) |
-				       (0 << 11) | (ep_type << 5) | ep_num,
-				       &udc_regs_p->udc_endp_reg[ep_num]);
-			} else {
-				/* Conf no. 1 Interface no. 1 */
-				writel((packet_size << 19) |
-				       ENDP_EPDIR_IN | (1 << 7) |
-				       (1 << 11) | (ep_type << 5) | ep_num,
-				       &udc_regs_p->udc_endp_reg[ep_num]);
-			}
-		} else {
-			/* Conf no. 1 Interface no. 0 */
-			writel((packet_size << 19) |
-			       ENDP_EPDIR_IN | (1 << 7) |
-			       (0 << 11) | (ep_type << 5) | ep_num,
-			       &udc_regs_p->udc_endp_reg[ep_num]);
-		}
-
-	} else {
-		/* Setup the OUT endpoint */
-		writel(0x0, &out_p->endp_status);
-		writel((ep_type << 4) | ENDP_CNTL_RRDY, &out_p->endp_cntl);
-		writel(packet_size | ((buffer_size / sizeof(int)) << 16),
-		       &out_p->endp_maxpacksize);
-
-		if (!strcmp(tt, "cdc_acm")) {
-			writel((packet_size << 19) |
-			       ENDP_EPDIR_OUT | (1 << 7) |
-			       (1 << 11) | (ep_type << 5) | ep_num,
-			       &udc_regs_p->udc_endp_reg[ep_num]);
-		} else {
-			writel((packet_size << 19) |
-			       ENDP_EPDIR_OUT | (1 << 7) |
-			       (0 << 11) | (ep_type << 5) | ep_num,
-			       &udc_regs_p->udc_endp_reg[ep_num]);
-		}
-
-	}
-
-	endp_intmask = readl(&udc_regs_p->endp_int_mask);
-	endp_intmask &= ~((1 << ep_num) | 0x10000 << ep_num);
-	writel(endp_intmask, &udc_regs_p->endp_int_mask);
-}
-
-/* Turn on the USB connection by enabling the pullup resistor */
-void udc_connect(void)
-{
-	u32 plug_st;
-
-	plug_st = readl(&plug_regs_p->plug_state);
-	plug_st &= ~(PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE);
-	writel(plug_st, &plug_regs_p->plug_state);
-}
-
-/* Turn off the USB connection by disabling the pullup resistor */
-void udc_disconnect(void)
-{
-	u32 plug_st;
-
-	plug_st = readl(&plug_regs_p->plug_state);
-	plug_st |= (PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE);
-	writel(plug_st, &plug_regs_p->plug_state);
-}
-
-/* Switch on the UDC */
-void udc_enable(struct usb_device_instance *device)
-{
-	UDCDBGA("enable device %p, status %d", device, device->status);
-
-	/* Save the device structure pointer */
-	udc_device = device;
-
-	/* Setup ep0 urb */
-	if (!ep0_urb) {
-		ep0_urb =
-		    usbd_alloc_urb(udc_device, udc_device->bus->endpoint_array);
-	} else {
-		serial_printf("udc_enable: ep0_urb already allocated %p\n",
-			      ep0_urb);
-	}
-
-	writel(DEV_INT_SOF, &udc_regs_p->dev_int_mask);
-}
-
-/**
- * udc_startup - allow udc code to do any additional startup
- */
-void udc_startup_events(struct usb_device_instance *device)
-{
-	/* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
-	usbd_device_event_irq(device, DEVICE_INIT, 0);
-
-	/*
-	 * The DEVICE_CREATE event puts the USB device in the state
-	 * STATE_ATTACHED.
-	 */
-	usbd_device_event_irq(device, DEVICE_CREATE, 0);
-
-	/*
-	 * Some USB controller driver implementations signal
-	 * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
-	 * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
-	 * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
-	 * The SPEAr USB client controller has the capability to detect when the
-	 * USB cable is connected to a powered USB bus, so we will defer the
-	 * DEVICE_HUB_CONFIGURED and DEVICE_RESET events until later.
-	 */
-
-	udc_enable(device);
-}
-
-/*
- * Plug detection interrupt handling
- */
-void spear_udc_plug_irq(void)
-{
-	if (readl(&plug_regs_p->plug_state) & PLUG_STATUS_ATTACHED) {
-		/*
-		 * USB cable attached
-		 * Turn off PHY reset bit (PLUG detect).
-		 * Switch PHY opmode to normal operation (PLUG detect).
-		 */
-		udc_connect();
-		writel(DEV_INT_SOF, &udc_regs_p->dev_int_mask);
-
-		UDCDBG("device attached and powered");
-		udc_state_transition(udc_device->device_state, STATE_POWERED);
-	} else {
-		/*
-		 * USB cable detached
-		 * Reset the PHY and switch the mode.
-		 */
-		udc_disconnect();
-		writel(~0x0, &udc_regs_p->dev_int_mask);
-
-		UDCDBG("device detached or unpowered");
-		udc_state_transition(udc_device->device_state, STATE_ATTACHED);
-	}
-}
-
-/*
- * Device interrupt handling
- */
-void spear_udc_dev_irq(void)
-{
-	if (readl(&udc_regs_p->dev_int) & DEV_INT_USBRESET) {
-		writel(~0x0, &udc_regs_p->endp_int_mask);
-
-		udc_connect();
-
-		writel(readl(&inep_regs_p[0].endp_cntl) | ENDP_CNTL_FLUSH,
-		       &inep_regs_p[0].endp_cntl);
-
-		writel(DEV_INT_USBRESET, &udc_regs_p->dev_int);
-
-		UDCDBG("device reset in progess");
-		udc_state_transition(udc_device->device_state, STATE_DEFAULT);
-	}
-
-	/* Device Enumeration completed */
-	if (readl(&udc_regs_p->dev_int) & DEV_INT_ENUM) {
-		writel(DEV_INT_ENUM, &udc_regs_p->dev_int);
-
-		/* Endpoint interrupt enabled for Ctrl IN & Ctrl OUT */
-		writel(readl(&udc_regs_p->endp_int_mask) & ~0x10001,
-		       &udc_regs_p->endp_int_mask);
-
-		UDCDBG("default -> addressed");
-		udc_state_transition(udc_device->device_state, STATE_ADDRESSED);
-	}
-
-	/* The USB will be in SUSPEND in 3 ms */
-	if (readl(&udc_regs_p->dev_int) & DEV_INT_INACTIVE) {
-		writel(DEV_INT_INACTIVE, &udc_regs_p->dev_int);
-
-		UDCDBG("entering inactive state");
-		/* usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0); */
-	}
-
-	/* SetConfiguration command received */
-	if (readl(&udc_regs_p->dev_int) & DEV_INT_SETCFG) {
-		writel(DEV_INT_SETCFG, &udc_regs_p->dev_int);
-
-		UDCDBG("entering configured state");
-		udc_state_transition(udc_device->device_state,
-				     STATE_CONFIGURED);
-	}
-
-	/* SetInterface command received */
-	if (readl(&udc_regs_p->dev_int) & DEV_INT_SETINTF)
-		writel(DEV_INT_SETINTF, &udc_regs_p->dev_int);
-
-	/* USB Suspend detected on cable */
-	if (readl(&udc_regs_p->dev_int) & DEV_INT_SUSPUSB) {
-		writel(DEV_INT_SUSPUSB, &udc_regs_p->dev_int);
-
-		UDCDBG("entering suspended state");
-		usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0);
-	}
-
-	/* USB Start-Of-Frame detected on cable */
-	if (readl(&udc_regs_p->dev_int) & DEV_INT_SOF)
-		writel(DEV_INT_SOF, &udc_regs_p->dev_int);
-}
-
-/*
- * Endpoint interrupt handling
- */
-void spear_udc_endpoint_irq(void)
-{
-	while (readl(&udc_regs_p->endp_int) & ENDP0_INT_CTRLOUT) {
-
-		writel(ENDP0_INT_CTRLOUT, &udc_regs_p->endp_int);
-
-		if ((readl(&outep_regs_p[0].endp_status) & ENDP_STATUS_OUTMSK)
-		    == ENDP_STATUS_OUT_SETUP) {
-			spear_udc_setup(udc_device->bus->endpoint_array + 0);
-			writel(ENDP_STATUS_OUT_SETUP,
-			       &outep_regs_p[0].endp_status);
-
-		} else if ((readl(&outep_regs_p[0].endp_status) &
-			    ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_DATA) {
-			spear_udc_ep0_rx(udc_device->bus->endpoint_array + 0);
-			writel(ENDP_STATUS_OUT_DATA,
-			       &outep_regs_p[0].endp_status);
-
-		} else if ((readl(&outep_regs_p[0].endp_status) &
-			    ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_NONE) {
-			/* NONE received */
-		}
-
-		writel(0x0, &outep_regs_p[0].endp_status);
-	}
-
-	if (readl(&udc_regs_p->endp_int) & ENDP0_INT_CTRLIN) {
-		spear_udc_ep0_tx(udc_device->bus->endpoint_array + 0);
-
-		writel(ENDP_STATUS_IN, &inep_regs_p[0].endp_status);
-		writel(ENDP0_INT_CTRLIN, &udc_regs_p->endp_int);
-	}
-
-	while (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOOUT_MSK) {
-		u32 epnum = 0;
-		u32 ep_int = readl(&udc_regs_p->endp_int) &
-		    ENDP_INT_NONISOOUT_MSK;
-
-		ep_int >>= 16;
-		while (0x0 == (ep_int & 0x1)) {
-			ep_int >>= 1;
-			epnum++;
-		}
-
-		writel((1 << 16) << epnum, &udc_regs_p->endp_int);
-
-		if ((readl(&outep_regs_p[epnum].endp_status) &
-		     ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_DATA) {
-
-			spear_udc_epn_rx(epnum);
-			writel(ENDP_STATUS_OUT_DATA,
-			       &outep_regs_p[epnum].endp_status);
-		} else if ((readl(&outep_regs_p[epnum].endp_status) &
-			    ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_NONE) {
-			writel(0x0, &outep_regs_p[epnum].endp_status);
-		}
-	}
-
-	if (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOIN_MSK) {
-		u32 epnum = 0;
-		u32 ep_int = readl(&udc_regs_p->endp_int) &
-		    ENDP_INT_NONISOIN_MSK;
-
-		while (0x0 == (ep_int & 0x1)) {
-			ep_int >>= 1;
-			epnum++;
-		}
-
-		if (readl(&inep_regs_p[epnum].endp_status) & ENDP_STATUS_IN) {
-			writel(ENDP_STATUS_IN,
-			       &outep_regs_p[epnum].endp_status);
-			spear_udc_epn_tx(epnum);
-
-			writel(ENDP_STATUS_IN,
-			       &outep_regs_p[epnum].endp_status);
-		}
-
-		writel((1 << epnum), &udc_regs_p->endp_int);
-	}
-}
-
-/*
- * UDC interrupts
- */
-void udc_irq(void)
-{
-	/*
-	 * Loop while we have interrupts.
-	 * If we don't do this, the input chain
-	 * polling delay is likely to miss
-	 * host requests.
-	 */
-	while (readl(&plug_regs_p->plug_pending))
-		spear_udc_plug_irq();
-
-	while (readl(&udc_regs_p->dev_int))
-		spear_udc_dev_irq();
-
-	if (readl(&udc_regs_p->endp_int))
-		spear_udc_endpoint_irq();
-}
-
-/* Flow control */
-void udc_set_nak(int epid)
-{
-	writel(readl(&inep_regs_p[epid].endp_cntl) | ENDP_CNTL_SNAK,
-	       &inep_regs_p[epid].endp_cntl);
-
-	writel(readl(&outep_regs_p[epid].endp_cntl) | ENDP_CNTL_SNAK,
-	       &outep_regs_p[epid].endp_cntl);
-}
-
-void udc_unset_nak(int epid)
-{
-	u32 val;
-
-	val = readl(&inep_regs_p[epid].endp_cntl);
-	val &= ~ENDP_CNTL_SNAK;
-	val |= ENDP_CNTL_CNAK;
-	writel(val, &inep_regs_p[epid].endp_cntl);
-
-	val = readl(&outep_regs_p[epid].endp_cntl);
-	val &= ~ENDP_CNTL_SNAK;
-	val |= ENDP_CNTL_CNAK;
-	writel(val, &outep_regs_p[epid].endp_cntl);
-}
diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
index e4090e5..06f77e3 100644
--- a/include/configs/spear-common.h
+++ b/include/configs/spear-common.h
@@ -33,7 +33,7 @@
 #define CONFIG_PHY_RESET_DELAY			(10000)		/* in usec */
 
 /* USBD driver configuration */
-#define CONFIG_SPEARUDC
+#define CONFIG_DW_UDC
 #define CONFIG_USB_DEVICE
 #define CONFIG_USB_TTY
 
diff --git a/include/usb/dw_udc.h b/include/usb/dw_udc.h
new file mode 100644
index 0000000..47509ba
--- /dev/null
+++ b/include/usb/dw_udc.h
@@ -0,0 +1,230 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __DW_UDC_H
+#define __DW_UDC_H
+
+/*
+ * Defines for  USBD
+ *
+ * The udc_ahb controller has three AHB slaves:
+ *
+ * 1.  THe UDC registers
+ * 2.  The plug detect
+ * 3.  The RX/TX FIFO
+ */
+
+#define MAX_ENDPOINTS		16
+
+struct udc_endp_regs {
+	u32 endp_cntl;
+	u32 endp_status;
+	u32 endp_bsorfn;
+	u32 endp_maxpacksize;
+	u32 reserved_1;
+	u32 endp_desc_point;
+	u32 reserved_2;
+	u32 write_done;
+};
+
+/* Endpoint Control Register definitions */
+
+#define  ENDP_CNTL_STALL		0x00000001
+#define  ENDP_CNTL_FLUSH		0x00000002
+#define  ENDP_CNTL_SNOOP		0x00000004
+#define  ENDP_CNTL_POLL			0x00000008
+#define  ENDP_CNTL_CONTROL		0x00000000
+#define  ENDP_CNTL_ISO			0x00000010
+#define  ENDP_CNTL_BULK			0x00000020
+#define  ENDP_CNTL_INT			0x00000030
+#define  ENDP_CNTL_NAK			0x00000040
+#define  ENDP_CNTL_SNAK			0x00000080
+#define  ENDP_CNTL_CNAK			0x00000100
+#define  ENDP_CNTL_RRDY			0x00000200
+
+/* Endpoint Satus Register definitions */
+
+#define  ENDP_STATUS_PIDMSK		0x0000000f
+#define  ENDP_STATUS_OUTMSK		0x00000030
+#define  ENDP_STATUS_OUT_NONE		0x00000000
+#define  ENDP_STATUS_OUT_DATA		0x00000010
+#define  ENDP_STATUS_OUT_SETUP		0x00000020
+#define  ENDP_STATUS_IN			0x00000040
+#define  ENDP_STATUS_BUFFNAV		0x00000080
+#define  ENDP_STATUS_FATERR		0x00000100
+#define  ENDP_STATUS_HOSTBUSERR		0x00000200
+#define  ENDP_STATUS_TDC		0x00000400
+#define  ENDP_STATUS_RXPKTMSK		0x003ff800
+
+struct udc_regs {
+	struct udc_endp_regs in_regs[MAX_ENDPOINTS];
+	struct udc_endp_regs out_regs[MAX_ENDPOINTS];
+	u32 dev_conf;
+	u32 dev_cntl;
+	u32 dev_stat;
+	u32 dev_int;
+	u32 dev_int_mask;
+	u32 endp_int;
+	u32 endp_int_mask;
+	u32 reserved_3[0x39];
+	u32 reserved_4;		/* offset 0x500 */
+	u32 udc_endp_reg[MAX_ENDPOINTS];
+};
+
+/* Device Configuration Register definitions */
+
+#define  DEV_CONF_HS_SPEED		0x00000000
+#define  DEV_CONF_LS_SPEED		0x00000002
+#define  DEV_CONF_FS_SPEED		0x00000003
+#define  DEV_CONF_REMWAKEUP		0x00000004
+#define  DEV_CONF_SELFPOW		0x00000008
+#define  DEV_CONF_SYNCFRAME		0x00000010
+#define  DEV_CONF_PHYINT_8		0x00000020
+#define  DEV_CONF_PHYINT_16		0x00000000
+#define  DEV_CONF_UTMI_BIDIR		0x00000040
+#define  DEV_CONF_STATUS_STALL		0x00000080
+
+/* Device Control Register definitions */
+
+#define  DEV_CNTL_RESUME		0x00000001
+#define  DEV_CNTL_TFFLUSH		0x00000002
+#define  DEV_CNTL_RXDMAEN		0x00000004
+#define  DEV_CNTL_TXDMAEN		0x00000008
+#define  DEV_CNTL_DESCRUPD		0x00000010
+#define  DEV_CNTL_BIGEND		0x00000020
+#define  DEV_CNTL_BUFFILL		0x00000040
+#define  DEV_CNTL_TSHLDEN		0x00000080
+#define  DEV_CNTL_BURSTEN		0x00000100
+#define  DEV_CNTL_DMAMODE		0x00000200
+#define  DEV_CNTL_SD			0x00000400
+#define  DEV_CNTL_SCALEDOWN		0x00000800
+#define  DEV_CNTL_BURSTLENU		0x00010000
+#define  DEV_CNTL_BURSTLENMSK		0x00ff0000
+#define  DEV_CNTL_TSHLDLENU		0x01000000
+#define  DEV_CNTL_TSHLDLENMSK		0xff000000
+
+/* Device Status Register definitions */
+
+#define  DEV_STAT_CFG			0x0000000f
+#define  DEV_STAT_INTF			0x000000f0
+#define  DEV_STAT_ALT			0x00000f00
+#define  DEV_STAT_SUSP			0x00001000
+#define  DEV_STAT_ENUM			0x00006000
+#define  DEV_STAT_ENUM_SPEED_HS		0x00000000
+#define  DEV_STAT_ENUM_SPEED_FS		0x00002000
+#define  DEV_STAT_ENUM_SPEED_LS		0x00004000
+#define  DEV_STAT_RXFIFO_EMPTY		0x00008000
+#define  DEV_STAT_PHY_ERR		0x00010000
+#define  DEV_STAT_TS			0xf0000000
+
+/* Device Interrupt Register definitions */
+
+#define  DEV_INT_MSK			0x0000007f
+#define  DEV_INT_SETCFG			0x00000001
+#define  DEV_INT_SETINTF		0x00000002
+#define  DEV_INT_INACTIVE		0x00000004
+#define  DEV_INT_USBRESET		0x00000008
+#define  DEV_INT_SUSPUSB		0x00000010
+#define  DEV_INT_SOF			0x00000020
+#define  DEV_INT_ENUM			0x00000040
+
+/* Endpoint Interrupt Register definitions */
+
+#define  ENDP0_INT_CTRLIN		0x00000001
+#define  ENDP1_INT_BULKIN		0x00000002
+#define  ENDP_INT_NONISOIN_MSK		0x0000AAAA
+#define  ENDP2_INT_BULKIN		0x00000004
+#define  ENDP0_INT_CTRLOUT		0x00010000
+#define  ENDP1_INT_BULKOUT		0x00020000
+#define  ENDP2_INT_BULKOUT		0x00040000
+#define  ENDP_INT_NONISOOUT_MSK		0x55540000
+
+/* Endpoint Register definitions */
+#define  ENDP_EPDIR_OUT			0x00000000
+#define  ENDP_EPDIR_IN			0x00000010
+#define  ENDP_EPTYPE_CNTL		0x0
+#define  ENDP_EPTYPE_ISO		0x1
+#define  ENDP_EPTYPE_BULK		0x2
+#define  ENDP_EPTYPE_INT		0x3
+
+/*
+ * Defines for Plug Detect
+ */
+
+struct plug_regs {
+	u32 plug_state;
+	u32 plug_pending;
+};
+
+/* Plug State Register definitions */
+#define  PLUG_STATUS_EN			0x1
+#define  PLUG_STATUS_ATTACHED		0x2
+#define  PLUG_STATUS_PHY_RESET		0x4
+#define  PLUG_STATUS_PHY_MODE		0x8
+
+/*
+ * Defines for UDC FIFO (Slave Mode)
+ */
+struct udcfifo_regs {
+	u32 *fifo_p;
+};
+
+/*
+ * USBTTY definitions
+ */
+#define  EP0_MAX_PACKET_SIZE		64
+#define  UDC_INT_ENDPOINT		1
+#define  UDC_INT_PACKET_SIZE		64
+#define  UDC_OUT_ENDPOINT		2
+#define  UDC_BULK_PACKET_SIZE		64
+#define  UDC_IN_ENDPOINT		3
+#define  UDC_OUT_PACKET_SIZE		64
+#define  UDC_IN_PACKET_SIZE		64
+
+/*
+ * UDC endpoint definitions
+ */
+#define  UDC_EP0			0
+#define  UDC_EP1			1
+#define  UDC_EP2			2
+#define  UDC_EP3			3
+
+/*
+ * Function declarations
+ */
+
+void udc_irq(void);
+
+void udc_set_nak(int epid);
+void udc_unset_nak(int epid);
+int udc_endpoint_write(struct usb_endpoint_instance *endpoint);
+int udc_init(void);
+void udc_enable(struct usb_device_instance *device);
+void udc_disable(void);
+void udc_connect(void);
+void udc_disconnect(void);
+void udc_startup_events(struct usb_device_instance *device);
+void udc_setup_ep(struct usb_device_instance *device, unsigned int ep,
+		  struct usb_endpoint_instance *endpoint);
+
+#endif /* __DW_UDC_H */
diff --git a/include/usb/spr_udc.h b/include/usb/spr_udc.h
deleted file mode 100644
index 2c332d5..0000000
--- a/include/usb/spr_udc.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * (C) Copyright 2009
- * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef __SPR_UDC_H
-#define __SPR_UDC_H
-
-/*
- * Defines for  USBD
- *
- * The udc_ahb controller has three AHB slaves:
- *
- * 1.  THe UDC registers
- * 2.  The plug detect
- * 3.  The RX/TX FIFO
- */
-
-#define MAX_ENDPOINTS		16
-
-struct udc_endp_regs {
-	u32 endp_cntl;
-	u32 endp_status;
-	u32 endp_bsorfn;
-	u32 endp_maxpacksize;
-	u32 reserved_1;
-	u32 endp_desc_point;
-	u32 reserved_2;
-	u32 write_done;
-};
-
-/* Endpoint Control Register definitions */
-
-#define  ENDP_CNTL_STALL		0x00000001
-#define  ENDP_CNTL_FLUSH		0x00000002
-#define  ENDP_CNTL_SNOOP		0x00000004
-#define  ENDP_CNTL_POLL			0x00000008
-#define  ENDP_CNTL_CONTROL		0x00000000
-#define  ENDP_CNTL_ISO			0x00000010
-#define  ENDP_CNTL_BULK			0x00000020
-#define  ENDP_CNTL_INT			0x00000030
-#define  ENDP_CNTL_NAK			0x00000040
-#define  ENDP_CNTL_SNAK			0x00000080
-#define  ENDP_CNTL_CNAK			0x00000100
-#define  ENDP_CNTL_RRDY			0x00000200
-
-/* Endpoint Satus Register definitions */
-
-#define  ENDP_STATUS_PIDMSK		0x0000000f
-#define  ENDP_STATUS_OUTMSK		0x00000030
-#define  ENDP_STATUS_OUT_NONE		0x00000000
-#define  ENDP_STATUS_OUT_DATA		0x00000010
-#define  ENDP_STATUS_OUT_SETUP		0x00000020
-#define  ENDP_STATUS_IN			0x00000040
-#define  ENDP_STATUS_BUFFNAV		0x00000080
-#define  ENDP_STATUS_FATERR		0x00000100
-#define  ENDP_STATUS_HOSTBUSERR		0x00000200
-#define  ENDP_STATUS_TDC		0x00000400
-#define  ENDP_STATUS_RXPKTMSK		0x003ff800
-
-struct udc_regs {
-	struct udc_endp_regs in_regs[MAX_ENDPOINTS];
-	struct udc_endp_regs out_regs[MAX_ENDPOINTS];
-	u32 dev_conf;
-	u32 dev_cntl;
-	u32 dev_stat;
-	u32 dev_int;
-	u32 dev_int_mask;
-	u32 endp_int;
-	u32 endp_int_mask;
-	u32 reserved_3[0x39];
-	u32 reserved_4;		/* offset 0x500 */
-	u32 udc_endp_reg[MAX_ENDPOINTS];
-};
-
-/* Device Configuration Register definitions */
-
-#define  DEV_CONF_HS_SPEED		0x00000000
-#define  DEV_CONF_LS_SPEED		0x00000002
-#define  DEV_CONF_FS_SPEED		0x00000003
-#define  DEV_CONF_REMWAKEUP		0x00000004
-#define  DEV_CONF_SELFPOW		0x00000008
-#define  DEV_CONF_SYNCFRAME		0x00000010
-#define  DEV_CONF_PHYINT_8		0x00000020
-#define  DEV_CONF_PHYINT_16		0x00000000
-#define  DEV_CONF_UTMI_BIDIR		0x00000040
-#define  DEV_CONF_STATUS_STALL		0x00000080
-
-/* Device Control Register definitions */
-
-#define  DEV_CNTL_RESUME		0x00000001
-#define  DEV_CNTL_TFFLUSH		0x00000002
-#define  DEV_CNTL_RXDMAEN		0x00000004
-#define  DEV_CNTL_TXDMAEN		0x00000008
-#define  DEV_CNTL_DESCRUPD		0x00000010
-#define  DEV_CNTL_BIGEND		0x00000020
-#define  DEV_CNTL_BUFFILL		0x00000040
-#define  DEV_CNTL_TSHLDEN		0x00000080
-#define  DEV_CNTL_BURSTEN		0x00000100
-#define  DEV_CNTL_DMAMODE		0x00000200
-#define  DEV_CNTL_SOFTDISCONNECT	0x00000400
-#define  DEV_CNTL_SCALEDOWN		0x00000800
-#define  DEV_CNTL_BURSTLENU		0x00010000
-#define  DEV_CNTL_BURSTLENMSK		0x00ff0000
-#define  DEV_CNTL_TSHLDLENU		0x01000000
-#define  DEV_CNTL_TSHLDLENMSK		0xff000000
-
-/* Device Status Register definitions */
-
-#define  DEV_STAT_CFG			0x0000000f
-#define  DEV_STAT_INTF			0x000000f0
-#define  DEV_STAT_ALT			0x00000f00
-#define  DEV_STAT_SUSP			0x00001000
-#define  DEV_STAT_ENUM			0x00006000
-#define  DEV_STAT_ENUM_SPEED_HS		0x00000000
-#define  DEV_STAT_ENUM_SPEED_FS		0x00002000
-#define  DEV_STAT_ENUM_SPEED_LS		0x00004000
-#define  DEV_STAT_RXFIFO_EMPTY		0x00008000
-#define  DEV_STAT_PHY_ERR		0x00010000
-#define  DEV_STAT_TS			0xf0000000
-
-/* Device Interrupt Register definitions */
-
-#define  DEV_INT_MSK			0x0000007f
-#define  DEV_INT_SETCFG			0x00000001
-#define  DEV_INT_SETINTF		0x00000002
-#define  DEV_INT_INACTIVE		0x00000004
-#define  DEV_INT_USBRESET		0x00000008
-#define  DEV_INT_SUSPUSB		0x00000010
-#define  DEV_INT_SOF			0x00000020
-#define  DEV_INT_ENUM			0x00000040
-
-/* Endpoint Interrupt Register definitions */
-
-#define  ENDP0_INT_CTRLIN		0x00000001
-#define  ENDP1_INT_BULKIN		0x00000002
-#define  ENDP_INT_NONISOIN_MSK		0x0000AAAA
-#define  ENDP2_INT_BULKIN		0x00000004
-#define  ENDP0_INT_CTRLOUT		0x00010000
-#define  ENDP1_INT_BULKOUT		0x00020000
-#define  ENDP2_INT_BULKOUT		0x00040000
-#define  ENDP_INT_NONISOOUT_MSK		0x55540000
-
-/* Endpoint Register definitions */
-#define  ENDP_EPDIR_OUT			0x00000000
-#define  ENDP_EPDIR_IN			0x00000010
-#define  ENDP_EPTYPE_CNTL		0x0
-#define  ENDP_EPTYPE_ISO		0x1
-#define  ENDP_EPTYPE_BULK		0x2
-#define  ENDP_EPTYPE_INT		0x3
-
-/*
- * Defines for Plug Detect
- */
-
-struct plug_regs {
-	u32 plug_state;
-	u32 plug_pending;
-};
-
-/* Plug State Register definitions */
-#define  PLUG_STATUS_EN			0x1
-#define  PLUG_STATUS_ATTACHED		0x2
-#define  PLUG_STATUS_PHY_RESET		0x4
-#define  PLUG_STATUS_PHY_MODE		0x8
-
-/*
- * Defines for UDC FIFO (Slave Mode)
- */
-struct udcfifo_regs {
-	u32 *fifo_p;
-};
-
-/*
- * USBTTY definitions
- */
-#define  EP0_MAX_PACKET_SIZE		64
-#define  UDC_INT_ENDPOINT		1
-#define  UDC_INT_PACKET_SIZE		64
-#define  UDC_OUT_ENDPOINT		2
-#define  UDC_BULK_PACKET_SIZE		64
-#define  UDC_IN_ENDPOINT		3
-#define  UDC_OUT_PACKET_SIZE		64
-#define  UDC_IN_PACKET_SIZE		64
-
-/*
- * UDC endpoint definitions
- */
-#define  UDC_EP0			0
-#define  UDC_EP1			1
-#define  UDC_EP2			2
-#define  UDC_EP3			3
-
-/*
- * Function declarations
- */
-
-void udc_irq(void);
-
-void udc_set_nak(int epid);
-void udc_unset_nak(int epid);
-int udc_endpoint_write(struct usb_endpoint_instance *endpoint);
-int udc_init(void);
-void udc_enable(struct usb_device_instance *device);
-void udc_disable(void);
-void udc_connect(void);
-void udc_disconnect(void);
-void udc_startup_events(struct usb_device_instance *device);
-void udc_setup_ep(struct usb_device_instance *device, unsigned int ep,
-		  struct usb_endpoint_instance *endpoint);
-
-#endif /* __SPR_UDC_H */
-- 
1.6.0.2

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

* [U-Boot] [PATCH 15/17] SPEAr : Basic spear1300 architecture support added
  2010-04-21  7:54                           ` [U-Boot] [PATCH 14/17] SPEAr : USBD driver support added Vipin KUMAR
@ 2010-04-21  7:54                             ` Vipin KUMAR
  2010-04-21  7:54                               ` [U-Boot] [PATCH 16/17] SPEAr : spear1300 SoC " Vipin KUMAR
  0 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 cpu/arm_cortexa8/spear13xx/Makefile        |   52 +++++
 cpu/arm_cortexa8/spear13xx/cache.S         |  112 ++++++++++
 cpu/arm_cortexa8/spear13xx/cpu_info.c      |  105 +++++++++
 cpu/arm_cortexa8/spear13xx/reset.c         |   47 ++++
 cpu/arm_cortexa8/spear13xx/timer.c         |  136 ++++++++++++
 include/asm-arm/arch-spear13xx/hardware.h  |   40 ++++
 include/asm-arm/arch-spear13xx/spr_gpt.h   |   85 ++++++++
 include/asm-arm/arch-spear13xx/spr_misc.h  |  317 ++++++++++++++++++++++++++++
 include/asm-arm/arch-spear13xx/sys_proto.h |   32 +++
 9 files changed, 926 insertions(+), 0 deletions(-)
 create mode 100644 cpu/arm_cortexa8/spear13xx/Makefile
 create mode 100644 cpu/arm_cortexa8/spear13xx/cache.S
 create mode 100644 cpu/arm_cortexa8/spear13xx/cpu_info.c
 create mode 100755 cpu/arm_cortexa8/spear13xx/reset.c
 create mode 100644 cpu/arm_cortexa8/spear13xx/timer.c
 create mode 100644 include/asm-arm/arch-spear13xx/hardware.h
 create mode 100755 include/asm-arm/arch-spear13xx/spr_gpt.h
 create mode 100755 include/asm-arm/arch-spear13xx/spr_misc.h
 create mode 100644 include/asm-arm/arch-spear13xx/sys_proto.h

diff --git a/cpu/arm_cortexa8/spear13xx/Makefile b/cpu/arm_cortexa8/spear13xx/Makefile
new file mode 100644
index 0000000..dba430a
--- /dev/null
+++ b/cpu/arm_cortexa8/spear13xx/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).a
+
+COBJS	= timer.o \
+	  reset.o \
+	  cpu_info.o
+
+SOBJS	= cache.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+
+all:	 $(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm_cortexa8/spear13xx/cache.S b/cpu/arm_cortexa8/spear13xx/cache.S
new file mode 100644
index 0000000..b3d1fb0
--- /dev/null
+++ b/cpu/arm_cortexa8/spear13xx/cache.S
@@ -0,0 +1,112 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+.global invalidate_dcache
+
+/*
+ *	invalidate_dcache()
+ *
+ *	Invalidate the whole D-cache.
+ *
+ *	Corrupted registers: r0-r5, r7, r9-r11
+ *
+ *	- mm	- mm_struct describing address space
+ */
+invalidate_dcache:
+	stmfd	r13!, {r0 - r5, r7, r9 - r12, r14}
+
+	mrc	p15, 1, r0, c0, c0, 1		@ read clidr
+	ands	r3, r0, #0x7000000		@ extract loc from clidr
+	mov	r3, r3, lsr #23			@ left align loc bit field
+	beq	finished_inval			@ if loc is 0, then no need to
+						@ clean
+	mov	r10, #0				@ start clean at cache level 0
+inval_loop1:
+	add	r2, r10, r10, lsr #1		@ work out 3x current cache
+						@ level
+	mov	r1, r0, lsr r2			@ extract cache type bits from
+						@ clidr
+	and	r1, r1, #7			@ mask of the bits for current
+						@ cache only
+	cmp	r1, #2				@ see what cache we have at
+						@ this level
+	blt	skip_inval			@ skip if no cache, or just
+						@ i-cache
+	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level
+						@ in cssr
+	mov	r2, #0				@ operand for mcr SBZ
+	mcr	p15, 0, r2, c7, c5, 4		@ flush prefetch buffer to
+						@ sych the new cssr&csidr,
+						@ with armv7 this is 'isb',
+						@ but we compile with armv5
+	mrc	p15, 1, r1, c0, c0, 0		@ read the new csidr
+	and	r2, r1, #7			@ extract the length of the
+						@ cache lines
+	add	r2, r2, #4			@ add 4 (line length offset)
+	ldr	r4, =0x3ff
+	ands	r4, r4, r1, lsr #3		@ find maximum number on the
+						@ way size
+	clz	r5, r4				@ find bit position of way
+						@ size increment
+	ldr	r7, =0x7fff
+	ands	r7, r7, r1, lsr #13		@ extract max number of the
+						@ index size
+inval_loop2:
+	mov	r9, r4				@ create working copy of max
+						@ way size
+inval_loop3:
+	orr	r11, r10, r9, lsl r5		@ factor way and cache number
+						@ into r11
+	orr	r11, r11, r7, lsl r2		@ factor index number into r11
+	mcr	p15, 0, r11, c7, c6, 2		@ invalidate by set/way
+	subs	r9, r9, #1			@ decrement the way
+	bge	inval_loop3
+	subs	r7, r7, #1			@ decrement the index
+	bge	inval_loop2
+skip_inval:
+	add	r10, r10, #2			@ increment cache number
+	cmp	r3, r10
+	bgt	inval_loop1
+finished_inval:
+	mov	r10, #0				@ swith back to cache level 0
+	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level
+						@ in cssr
+	mcr	p15, 0, r10, c7, c5, 4		@ flush prefetch buffer,
+						@ with armv7 this is 'isb',
+						@ but we compile with armv5
+
+	ldmfd	r13!, {r0 - r5, r7, r9 - r12, pc}
+
+.global l2_cache_enable
+/*
+ * l2_cache_enable
+ */
+l2_cache_enable:
+	bx	r14
+
+.global l2_cache_disable
+/*
+ * l2_cache_disable
+ */
+l2_cache_disable:
+	bx	r14
diff --git a/cpu/arm_cortexa8/spear13xx/cpu_info.c b/cpu/arm_cortexa8/spear13xx/cpu_info.c
new file mode 100644
index 0000000..e59c221
--- /dev/null
+++ b/cpu/arm_cortexa8/spear13xx/cpu_info.c
@@ -0,0 +1,105 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_misc.h>
+
+u32 get_device_type(void)
+{
+	return 0;
+}
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init(void)
+{
+	struct misc_regs *const misc_p =
+	    (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+	u32 perip1_clk_enb, perip2_clk_enb;
+#if defined(CONFIG_NAND_FSMC)
+	u32 fsmc_cfg;
+#endif
+	perip1_clk_enb = readl(&misc_p->perip1_clk_enb);
+	perip2_clk_enb = readl(&misc_p->perip2_clk_enb);
+
+	perip1_clk_enb |= GPT1_CLKEN;
+
+#if defined(CONFIG_PL011_SERIAL)
+	perip1_clk_enb |= UART_CLKEN;
+#endif
+
+#if defined(CONFIG_DW_ETH)
+	/* writel(SYNT_CLK_ENB | SYNT_FIN_FULL | SYNT_X_1 | SYNT_Y_5,
+			&misc_p->gmac_clk_synt); */
+	writel(PHY_IF_GMII | CLK_SEL_OSCI3, &misc_p->gmac_clk_cfg);
+
+	perip1_clk_enb |= GETH_CLKEN;
+#endif
+
+#if defined(CONFIG_DW_UDC)
+	perip1_clk_enb |= UDC_UPD_CLKEN;
+#endif
+
+#if defined(CONFIG_DW_I2C)
+	perip1_clk_enb |= I2C_CLKEN;
+#endif
+
+#if defined(CONFIG_ST_SMI)
+	perip1_clk_enb |= SMI_CLKEN;
+#endif
+
+#if defined(CONFIG_NAND_FSMC)
+	fsmc_cfg = readl(&misc_p->fsmc_cfg);
+	fsmc_cfg &= ~DEV_SEL_MSK;
+	fsmc_cfg |= DEV_SEL_NAND;
+#if defined(CONFIG_BOARD_NAND_16BIT)
+	fsmc_cfg |= DEV_WIDTH_16;
+#elif defined(CONFIG_BOARD_NAND_8BIT)
+	fsmc_cfg |= DEV_WIDTH_8;
+#endif
+	writel(fsmc_cfg, &misc_p->fsmc_cfg);
+
+	perip1_clk_enb |= FSMC_CLKEN;
+#endif
+
+	writel(perip1_clk_enb, &misc_p->perip1_clk_enb);
+	writel(perip2_clk_enb, &misc_p->perip2_clk_enb);
+
+#if defined(CONFIG_DW_ETH)
+	writel(readl(&misc_p->perip1_sw_rst) | GETH_CLKEN,
+			&misc_p->perip1_sw_rst);
+	writel(readl(&misc_p->perip1_sw_rst) & ~GETH_CLKEN,
+			&misc_p->perip1_sw_rst);
+#endif
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+	printf("CPU:   SPEAr1300\n");
+	return 0;
+}
+#endif
diff --git a/cpu/arm_cortexa8/spear13xx/reset.c b/cpu/arm_cortexa8/spear13xx/reset.c
new file mode 100755
index 0000000..9a43f85
--- /dev/null
+++ b/cpu/arm_cortexa8/spear13xx/reset.c
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_misc.h>
+
+void reset_cpu(ulong ignored)
+{
+	struct misc_regs *misc_regs_p =
+		(struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+
+	printf("System is going to reboot ...\n");
+
+	/*
+	 * This 1 second delay will allow the above message
+	 * to be printed before reset
+	 */
+	udelay((1000 * 1000));
+
+	writel(0x01, &misc_regs_p->sys_sw_res);
+
+	/* system will restart */
+	while (1)
+		;
+}
diff --git a/cpu/arm_cortexa8/spear13xx/timer.c b/cpu/arm_cortexa8/spear13xx/timer.c
new file mode 100644
index 0000000..d114a4a
--- /dev/null
+++ b/cpu/arm_cortexa8/spear13xx/timer.c
@@ -0,0 +1,136 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_gpt.h>
+#include <asm/arch/spr_misc.h>
+
+#define GPT_TICKS	(CONFIG_SPEAR_HZ_CLOCK / (1 << prescaler))
+#define GPT_RESOLUTION	(GPT_TICKS / CONFIG_SPEAR_HZ)
+#define READ_TIMER()	(readl(&gpt_regs_p->count) & GPT_FREE_RUNNING)
+
+static struct gpt_regs *const gpt_regs_p =
+    (struct gpt_regs *)CONFIG_SPEAR_TIMERBASE;
+
+static ulong timestamp;
+static ulong lastdec;
+static const u32 prescaler = GPT_PRESCALER_16;
+
+int timer_init(void)
+{
+	/* disable timers */
+	writel(prescaler | GPT_MODE_AUTO_RELOAD, &gpt_regs_p->control);
+
+	/* load value for free running */
+	writel(GPT_FREE_RUNNING, &gpt_regs_p->compare);
+
+	/* auto reload, start timer */
+	writel(readl(&gpt_regs_p->control) | GPT_ENABLE, &gpt_regs_p->control);
+
+	reset_timer_masked();
+
+	return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+	return (get_timer_masked() / GPT_RESOLUTION) - base;
+}
+
+void set_timer(ulong t)
+{
+	timestamp = t;
+}
+
+void __udelay(unsigned long usec)
+{
+	ulong tmo;
+	ulong start = get_timer_masked();
+	ulong tenudelcnt = GPT_TICKS / (1000 * 100);
+	ulong rndoff;
+
+	rndoff = (usec % 10) ? 1 : 0;
+
+	/* tenudelcnt timer tick gives 10 microsecconds delay */
+	tmo = ((usec / 10) + rndoff) * tenudelcnt;
+
+	while ((ulong) (get_timer_masked() - start) < tmo)
+		;
+}
+
+void reset_timer_masked(void)
+{
+	/* reset time */
+	lastdec = READ_TIMER();
+	timestamp = 0;
+}
+
+ulong get_timer_masked(void)
+{
+	ulong now = READ_TIMER();
+
+	if (now >= lastdec) {
+		/* normal mode */
+		timestamp += now - lastdec;
+	} else {
+		/* we have an overflow ... */
+		timestamp += now + GPT_FREE_RUNNING - lastdec;
+	}
+	lastdec = now;
+
+	return timestamp;
+}
+
+void udelay_masked(unsigned long usec)
+{
+	return udelay(usec);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	return CONFIG_SPEAR_HZ;
+}
diff --git a/include/asm-arm/arch-spear13xx/hardware.h b/include/asm-arm/arch-spear13xx/hardware.h
new file mode 100644
index 0000000..384260a
--- /dev/null
+++ b/include/asm-arm/arch-spear13xx/hardware.h
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, STMicroelectronics, <vipin.kumar@st.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _ASM_ARCH_HARDWARE_H
+#define _ASM_ARCH_HARDWARE_H
+
+#define CONFIG_SYS_USBD_BASE			(0xE1100000)
+#define CONFIG_SYS_PLUG_BASE			(0xE1200000)
+#define CONFIG_SYS_FIFO_BASE			(0xE1000800)
+#define CONFIG_SYS_SMI_BASE			(0xFC000000)
+#define CONFIG_SPEAR_TIMERBASE			(0xE0380000)
+#define CONFIG_SPEAR_MISCBASE			(0xE0700000)
+#define CONFIG_SYS_I2C_BASE			(0xE0280000)
+#define CONFIG_SPEAR_ETHBASE			(0xE2000000)
+#define CONFIG_SYS_FSMC_BASE			(0xB0000000)
+
+#define CONFIG_SYS_NAND_CLE			(1 << 16)
+#define CONFIG_SYS_NAND_ALE			(1 << 17)
+
+#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-spear13xx/spr_gpt.h b/include/asm-arm/arch-spear13xx/spr_gpt.h
new file mode 100755
index 0000000..ad464cb
--- /dev/null
+++ b/include/asm-arm/arch-spear13xx/spr_gpt.h
@@ -0,0 +1,85 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SPR_GPT_H
+#define _SPR_GPT_H
+
+struct gpt_regs {
+	u8 reserved[0x80];
+	u32 control;
+	u32 status;
+	u32 compare;
+	u32 count;
+	u32 capture_re;
+	u32 capture_fe;
+};
+
+/*
+ * TIMER_CONTROL register settings
+ */
+
+#define GPT_PRESCALER_MASK		0x000F
+#define GPT_PRESCALER_1			0x0000
+#define GPT_PRESCALER_2 		0x0001
+#define GPT_PRESCALER_4 		0x0002
+#define GPT_PRESCALER_8 		0x0003
+#define GPT_PRESCALER_16		0x0004
+#define GPT_PRESCALER_32		0x0005
+#define GPT_PRESCALER_64		0x0006
+#define GPT_PRESCALER_128		0x0007
+#define GPT_PRESCALER_256		0x0008
+
+#define GPT_MODE_SINGLE_SHOT		0x0010
+#define GPT_MODE_AUTO_RELOAD		0x0000
+
+#define GPT_ENABLE			0x0020
+
+#define GPT_CAPT_MODE_MASK		0x00C0
+#define GPT_CAPT_MODE_NONE		0x0000
+#define GPT_CAPT_MODE_RE		0x0040
+#define GPT_CAPT_MODE_FE		0x0080
+#define GPT_CAPT_MODE_BOTH		0x00C0
+
+#define GPT_INT_MATCH			0x0100
+#define GPT_INT_FE			0x0200
+#define GPT_INT_RE			0x0400
+
+/*
+ * TIMER_STATUS register settings
+ */
+
+#define GPT_STS_MATCH			0x0001
+#define GPT_STS_FE			0x0002
+#define GPT_STS_RE			0x0004
+
+/*
+ * TIMER_COMPARE register settings
+ */
+
+#define GPT_FREE_RUNNING		0xFFFF
+
+/* Timer, HZ specific defines */
+#define CONFIG_SPEAR_HZ			(1000)
+#define CONFIG_SPEAR_HZ_CLOCK		(24000000)
+
+#endif
diff --git a/include/asm-arm/arch-spear13xx/spr_misc.h b/include/asm-arm/arch-spear13xx/spr_misc.h
new file mode 100755
index 0000000..0b24843
--- /dev/null
+++ b/include/asm-arm/arch-spear13xx/spr_misc.h
@@ -0,0 +1,317 @@
+/*
+ * (C) Copyright 2000-2009
+ * Vipin Kumar, ST Microelectronics, vipin.kumar at st.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __SPR13XX_MISC_H
+#define __SPR13XX_MISC_H
+
+struct misc_regs {
+	u32 soc_cfg;				/* 0x000 */
+	u32 bootstrap_cfg;			/* 0x004 */
+	u8  reserved_1[0x100 - 0x8];
+	u32 pcm_cfg;				/* 0x100 */
+	u32 pcm_wkup_cfg;			/* 0x104 */
+	u32 switch_ctr;				/* 0x108 */
+	u8  reserved_2[0x200 - 0x10c];
+	u32 sys_clk_ctrl;			/* 0x200 */
+	u32 sys_sw_res;				/* 0x204 */
+	u32 sys_clk_plltimer;			/* 0x208 */
+	u32 sys_clk_oscitimer;			/* 0x20c */
+	u32 pll_cfg;				/* 0x210 */
+	u32 pll1_ctr;				/* 0x214 */
+	u32 pll1_frq;				/* 0x218 */
+	u32 pll1_mod;				/* 0x21c */
+	u32 pll2_ctr;				/* 0x220 */
+	u32 pll2_frq;				/* 0x224 */
+	u32 pll2_mod;				/* 0x228 */
+	u32 pll3_ctr;				/* 0x22c */
+	u32 pll3_frq;				/* 0x230 */
+	u32 pll3_mod;				/* 0x234 */
+	u32 pll4_ctr;				/* 0x238 */
+	u32 pll4_frq;				/* 0x23C */
+	u32 pll4_mod;				/* 0x240 */
+	u32 perip_clk_cfg;			/* 0x244 */
+	u32 gmac_clk_cfg;			/* 0x248 */
+	u32 c3_clk_synt;			/* 0x24c */
+	u32 clcd_clk_synt;			/* 0x250 */
+	u32 uart_clk_synt;			/* 0x254 */
+	u32 gmac_clk_synt;			/* 0x258 */
+	u32 mcif_sd_clk_synt;			/* 0x25c */
+	u32 mcif_cfxd_clk_synt;			/* 0x260 */
+	u32 ras_clk_synt0;			/* 0x264 */
+	u32 ras_clk_synt1;			/* 0x268 */
+	u32 ras_clk_synt2;			/* 0x26c */
+	u32 ras_clk_synt3;			/* 0x270 */
+	u32 perip1_clk_enb;			/* 0x274 */
+	u32 perip2_clk_enb;			/* 0x278 */
+	u32 perip1_sw_rst;			/* 0x27c */
+	u32 perip2_sw_rst;			/* 0x280 */
+	u32 ras_clk_enb;			/* 0x284 */
+	u32 ras_sw_rst;				/* 0x288 */
+	u32 pll1_synt;				/* 0x28c */
+	u32 i2s_clk_cfg;			/* 0x290 */
+	u8  reserved_3[0x300 - 0x294];
+	u32 dmac_hs_sel;			/* 0x300 */
+	u32 dmac_sel;				/* 0x304 */
+	u32 dmac_flow_sel;			/* 0x308 */
+	u32 dmac_dir_sel;			/* 0x30c */
+	u32 dmac_cfg;				/* 0x310 */
+	u32 usbphy_gen_cfg;			/* 0x314 */
+	u32 usbphy_p1_cfg;			/* 0x318 */
+	u32 usbphy_p2_cfg;			/* 0x31c */
+	u32 usbphy_p3_cfg;			/* 0x320 */
+	u32 pcie_cfg;				/* 0x324 */
+	u32 pcie_miphy_cfg;			/* 0x328 */
+	u32 perip_cfg;				/* 0x32c */
+	u32 fsmc_cfg;				/* 0x330 */
+	u32 mpmc_ctr_sts;			/* 0x334 */
+	u8  reserved_4[0x400 - 0x338];
+	u32 expi_clk_cfg;			/* 0x400 */
+	u32 expi_cfg;				/* 0x404 */
+	u32 expi_dmachs_flex;			/* 0x408 */
+	u8  reserved_5[0x500 - 0x40C];
+	u32 prc1_lock_ctr;			/* 0x500 */
+	u32 prc2_lock_ctr;			/* 0x504 */
+	u32 prc1_irq_ctr;			/* 0x508 */
+	u8  reserved_6[0x51c - 0x50c];
+	u32 prc2_irq_ctr;			/* 0x51c */
+	u8  reserved_7[0x600 - 0x520];
+	u32 pad_pu_cfg_1;			/* 0x600 */
+	u32 pad_pu_cfg_2;			/* 0x604 */
+	u32 pad_pu_cfg_3;			/* 0x608 */
+	u32 pad_pu_cfg_4;			/* 0x60c */
+	u32 pad_pu_cfg_5;			/* 0x610 */
+	u32 pad_pu_cfg_6;			/* 0x614 */
+	u32 pad_pu_cfg_7;			/* 0x618 */
+	u32 pad_pu_cfg_8;			/* 0x61c */
+	u32 pad_pd_cfg_1;			/* 0x620 */
+	u32 pad_pd_cfg_2;			/* 0x624 */
+	u32 pad_pd_cfg_3;			/* 0x628 */
+	u32 pad_pd_cfg_4;			/* 0x62c */
+	u32 pad_pd_cfg_5;			/* 0x630 */
+	u32 pad_pd_cfg_6;			/* 0x634 */
+	u32 pad_pd_cfg_7;			/* 0x638 */
+	u32 pad_pd_cfg_8;			/* 0x63c */
+	u32 pad_sleep_cfg;			/* 0x640 */
+	u32 pad_hyst_cfg;			/* 0x644 */
+	u32 pad_drv_cfg;			/* 0x648 */
+	u32 pad_slew_cfg;			/* 0x64c */
+	u32 pad_function_en_1;			/* 0x650 */
+	u32 pad_function_en_2;			/* 0x654 */
+	u32 pad_function_en_3;			/* 0x658 */
+	u32 ddr_pad_cfg;			/* 0x65c */
+	u8  reserved_8[0x6C4 - 0x660];
+	u32 thsens_cfg;				/* 0x6C4 */
+	u8  reserved_9[0x700 - 0x6C8];
+	u32 comp_1_cfg;				/* 0x700 */
+	u32 comp_2_cfg;				/* 0x704 */
+	u32 comp3v3_1_cfg;			/* 0x708 */
+	u32 comp3v3_2_cfg;			/* 0x70c */
+	u32 compddr_cfg;			/* 0x710 */
+	u8  reserved_10[0x800 - 0x714];
+	u32 otp_prog_ctr;			/* 0x800 */
+	u32 otp_wdata1_1;			/* 0x804 */
+	u32 otp_wdata1_2;			/* 0x808 */
+	u32 otp_wdata1_3;			/* 0x80c */
+	u32 otp_wdata1_4;			/* 0x810 */
+	u32 otp_wdata1_5;			/* 0x814 */
+	u32 otp_wdata1_6;			/* 0x818 */
+	u32 otp_wdata1_7;			/* 0x81c */
+	u32 otp_wdata1_8;			/* 0x820 */
+	u32 otp_wdata2_1;			/* 0x824 */
+	u32 otp_wdata2_2;			/* 0x828 */
+	u32 otp_wdata2_3;			/* 0x82c */
+	u32 otp_wdata2_4;			/* 0x830 */
+	u32 otp_wdata2_5;			/* 0x834 */
+	u32 otp_wdata2_6;			/* 0x838 */
+	u32 otp_wdata2_7;			/* 0x83c */
+	u32 otp_wdata2_8;			/* 0x840 */
+	u32 otp_mask_1;				/* 0x844 */
+	u32 otp_mask_2;				/* 0x848 */
+	u32 otp_mask_3;				/* 0x84c */
+	u32 otp_mask_4;				/* 0x850 */
+	u32 otp_mask_5;				/* 0x854 */
+	u32 otp_mask_6;				/* 0x858 */
+	u32 otp_mask_7;				/* 0x85c */
+	u32 otp_mask_8;				/* 0x860 */
+	u32 otp_rdata1_1;			/* 0x864 */
+	u32 otp_rdata1_2;			/* 0x868 */
+	u32 otp_rdata1_3;			/* 0x86c */
+	u32 otp_rdata1_4;			/* 0x870 */
+	u32 otp_rdata1_5;			/* 0x874 */
+	u32 otp_rdata1_6;			/* 0x878 */
+	u32 otp_rdata1_7;			/* 0x87c */
+	u32 otp_rdata1_8;			/* 0x880 */
+	u32 otp_rdata2_1;			/* 0x884 */
+	u32 otp_rdata2_2;			/* 0x888 */
+	u32 otp_rdata2_3;			/* 0x88c */
+	u32 otp_rdata2_4;			/* 0x890 */
+	u32 otp_rdata2_5;			/* 0x894 */
+	u32 otp_rdata2_6;			/* 0x898 */
+	u32 otp_rdata2_7;			/* 0x89c */
+	u32 otp_rdata2_8;			/* 0x8a0 */
+	u32 otp_rdatam_1;			/* 0x8a4 */
+	u32 otp_rdatam_2;			/* 0x8a8 */
+	u32 otp_rdatam_3;			/* 0x8ac */
+	u32 otp_rdatam_4;			/* 0x8b0 */
+	u32 otp_rdatam_5;			/* 0x8b4 */
+	u32 otp_rdatam_6;			/* 0x8b8 */
+	u32 otp_rdatam_7;			/* 0x8bc */
+	u32 otp_rdatam_8;			/* 0x8c0 */
+	u8  reserved_11[0x900 - 0x8c4];
+	u32 a9sm_clusterid;			/* 0x900 */
+	u32 a9sm_status;			/* 0x904 */
+	u32 a9sm_debug;				/* 0x908 */
+	u32 a9sm_filter;			/* 0x90c */
+	u32 a9sm_parity_cfg;			/* 0x910 */
+	u32 a9sm_parity_err;			/* 0x914 */
+	u8  reserved_12[0xa00 - 0x918];
+	u32 die_id_1;				/* 0xa00 */
+	u32 die_id_2;				/* 0xa04 */
+	u32 die_id_3;				/* 0xa08 */
+	u32 die_id_4;				/* 0xa0c */
+	u32 die_id_valid;			/* 0xa10 */
+	u8  reserved_13[0xb00 - 0xa14];
+	u32 ras1_gpp_inp;			/* 0xb00 */
+	u32 ras2_gpp_inp;			/* 0xb04 */
+	u32 ras1_gpp_out;			/* 0xb08 */
+	u32 ras2_gpp_out;			/* 0xb0c */
+	u8  reserved_14[0x1000 - 0xb10];
+	u32 miphy_test;				/* 0x1000 */
+	u32 pcie_mstr_p1;			/* 0x1004 */
+	u32 pcie_awmisc_p1;			/* 0x1008 */
+	u32 pcie_armisc_p1;			/* 0x100c */
+	u32 pcie_mstr_p2;			/* 0x1010 */
+	u32 pcie_awmisc_p2;			/* 0x1014 */
+	u32 pcie_armisc_p2;			/* 0x1018 */
+	u32 pcie_mstr_p3;			/* 0x101c */
+	u32 pcie_awmisc_p3;			/* 0x1020 */
+	u32 pcie_armisc_p3;			/* 0x1024 */
+};
+
+/* sys_clk_ctrl definitions */
+#define SYS_MODE_MASK				(7 << 0)
+#define SYS_MODE_REQ_DOZE			(1 << 0)
+#define SYS_MODE_REQ_SLOW			(2 << 0)
+#define SYS_MODE_REQ_NORMAL			(4 << 0)
+#define PLL_TIMEOUT_ENB				(1 << 3)
+#define XTAL_TIMEOUT_ENB			(1 << 4)
+#define SYS_STATE_MASK				(0xF << 16)
+#define SYS_STATE_NORMAL			(0xF << 16)
+
+/* sys_clk_*timer definitions */
+#define PLL_TIM					(0xff << 3)
+#define OSCI_TIM				(0xff << 3)
+
+/* pll_freq definitions in MHz */
+#define FREQ_1000				(0xFA000106)
+#define FREQ_996				(0x53000004)
+#define FREQ_332				(0x53000203)
+
+/* pll_ctr definitions */
+#define PLLLOCK					(1 << 0)
+#define PLLENABLE				(1 << 1)
+
+/* perip_clk_cfg definitions */
+#define MPMC_CLK_PLL4				(1 << 10)
+
+/* perip*_[clk_enb/sw_rst] definitions */
+#define BUS_CLKEN				(1 << 0)	/* perip1 */
+#define SYSROM_CLKEN				(1 << 1)
+#define AORAM_CLKEN				(1 << 2)
+#define SYSRAM_CLKEN				(1 << 3)
+#define FSMC_CLKEN				(1 << 4)
+#define SMI_CLKEN				(1 << 5)
+#define SD_CLKEN				(1 << 6)
+#define CFXD_CLKEN				(1 << 7)
+#define GETH_CLKEN				(1 << 8)
+#define UHC1_CLKEN				(1 << 9)
+#define UHC2_CLKEN				(1 << 10)
+#define UDC_UPD_CLKEN				(1 << 11)
+#define PCI1_CLKEN				(1 << 12)
+#define PCI2_CLKEN				(1 << 13)
+#define PCI3_CLKEN				(1 << 14)
+#define UART_CLKEN				(1 << 15)
+#define SSP_CLKEN				(1 << 17)
+#define I2C_CLKEN				(1 << 18)
+#define I2S_SLV_CLKEN				(1 << 19)
+#define I2S_MST_CLKEN				(1 << 20)
+#define GPT1_CLKEN				(1 << 21)
+#define GPT2_CLKEN				(1 << 22)
+#define GPIO1_CLKEN				(1 << 23)
+#define GPIO2_CLKEN				(1 << 24)
+#define DMA1_CLKEN				(1 << 25)
+#define DMA2_CLKEN				(1 << 26)
+#define CLCD_CLKEN				(1 << 27)
+#define JPEG_CLKEN				(1 << 28)
+#define C3_CLKEN				(1 << 29)
+#define ADC_CLKEN				(1 << 30)
+#define RTC_CLKEN				(1 << 31)
+
+#define DDR_CTRL_CLKEN				(1 << 0)	/* perip2 */
+#define DDR_CORE_CLKEN				(1 << 1)
+#define CPU_DBG_CLKEN				(1 << 2)
+#define KBD_CLKEN				(1 << 3)
+#define GPT3_CLKEN				(1 << 4)
+#define GPT4_CLKEN				(1 << 5)
+#define ACP_CLKEN				(1 << 6)
+#define I2S_REFOUT_CLKEN			(1 << 7)
+#define THSENS_CLKEN				(1 << 8)
+
+/* fsmc_cfg definitions */
+#define DEV_SEL_NOR				(0 << 0)
+#define DEV_SEL_NAND				(1 << 0)
+#define DEV_SEL_SRAM				(2 << 0)
+#define DEV_SEL_MSK				(3 << 0)
+#define NAND_BANK_0				(0 << 2)
+#define NAND_BANK_1				(1 << 2)
+#define NAND_BANK_2				(2 << 2)
+#define NAND_BANK_3				(3 << 2)
+#define DEV_WIDTH_8				(0 << 4)
+#define DEV_WIDTH_16				(1 << 4)
+
+/* usbphy_gen_cfg definitions */
+#define COMMON_PWDN				(1 << 0)
+#define USBPHY_POR				(1 << 12)
+#define USBPHY_RST				(1 << 13)
+#define UTMI_XFER_RST0				(1 << 14)
+#define UTMI_XFER_RST1				(1 << 15)
+#define UTMI_XFER_RST2				(1 << 16)
+#define USB_PLL_LOCK				(1 << 27)
+
+/* synth registers definitions */
+#define SYNT_CLK_ENB				(1 << 31)
+#define SYNT_FIN_FULL				(1 << 30)
+#define SYNT_X_1				(1 << 16)
+#define SYNT_Y_2				(2 << 0)
+#define SYNT_Y_5				(5 << 0)
+
+/* gmac_clk_cfg definitions */
+#define PHY_IF_GMII				(0 << 4)
+#define PHY_IF_RGMII				(1 << 4)
+#define PHY_IF_RMII				(4 << 4)
+#define GMII_SYNT_ENB				(1 << 3)
+#define CLK_SEL_PAD				(0 << 0)
+#define CLK_SEL_PLL2				(1 << 0)
+#define CLK_SEL_OSCI3				(2 << 0)
+
+#endif
diff --git a/include/asm-arm/arch-spear13xx/sys_proto.h b/include/asm-arm/arch-spear13xx/sys_proto.h
new file mode 100644
index 0000000..e6cc3a9
--- /dev/null
+++ b/include/asm-arm/arch-spear13xx/sys_proto.h
@@ -0,0 +1,32 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, STMicroelectronics, <vipin.kumar@st.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+u32 get_device_type(void);
+void invalidate_dcache(u32);
+void l2_cache_disable(void);
+void l2_cache_enable(void);
+
+#endif
-- 
1.6.0.2

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

* [U-Boot] [PATCH 16/17] SPEAr : spear1300 SoC support added
  2010-04-21  7:54                             ` [U-Boot] [PATCH 15/17] SPEAr : Basic spear1300 architecture " Vipin KUMAR
@ 2010-04-21  7:54                               ` Vipin KUMAR
  2010-04-21  7:54                                 ` [U-Boot] [PATCH 17/17] SPEAr : Supporting various configurations for spear3xx and spear6xx boards Vipin KUMAR
  0 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

SPEAr1300 SoC support contains basic spear1300 support along with the
usage of following drivers
- serial driver(UART)
- i2c driver
- smi driver
- nand driver(FSMC)
- usbd driver

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 Makefile                                  |    6 +
 board/spear/common/Makefile               |   10 +-
 board/spear/spear1300/Makefile            |   51 ++++++++
 board/spear/spear1300/config.mk           |   28 ++++
 board/spear/spear1300/spear1300.c         |   89 +++++++++++++
 board/spear/spear1300/spr_lowlevel_init.S |   38 ++++++
 include/asm-arm/arch-spear13xx/hardware.h |    8 +-
 include/configs/spear13xx.h               |  199 +++++++++++++++++++++++++++++
 8 files changed, 423 insertions(+), 6 deletions(-)
 create mode 100644 board/spear/spear1300/Makefile
 create mode 100644 board/spear/spear1300/config.mk
 create mode 100644 board/spear/spear1300/spear1300.c
 create mode 100644 board/spear/spear1300/spr_lowlevel_init.S
 create mode 100644 include/configs/spear13xx.h

diff --git a/Makefile b/Makefile
index 1b431a5..7af505e 100644
--- a/Makefile
+++ b/Makefile
@@ -3045,6 +3045,12 @@ spear320_config :	unconfig
 spear600_config :	unconfig
 	@$(MKCONFIG) -n $@ -t $(@:_config=) spear6xx arm arm926ejs $(@:_config=) spear spear
 
+spear1300_config \
+spear1300_nand_config \
+spear1300_usbtty_config \
+spear1300_usbtty_nand_config :	unconfig
+	@$(MKCONFIG) -n $@ -t $(@:_config=) spear13xx arm arm_cortexa8 spear1300 spear spear13xx
+
 suen3_config:	unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm926ejs km_arm keymile kirkwood
 
diff --git a/board/spear/common/Makefile b/board/spear/common/Makefile
index 4f8959f..1ae4fd4 100644
--- a/board/spear/common/Makefile
+++ b/board/spear/common/Makefile
@@ -29,8 +29,14 @@ endif
 
 LIB	= $(obj)lib$(VENDOR).a
 
-COBJS	:= spr_misc.o
-SOBJS	:= spr_lowlevel_init.o
+COBJS-$(CONFIG_SPEAR3XX) += spr_misc.o
+COBJS-$(CONFIG_SPEAR600) += spr_misc.o
+
+SOBJS-$(CONFIG_SPEAR3XX) += spr_lowlevel_init.o
+SOBJS-$(CONFIG_SPEAR600) += spr_lowlevel_init.o
+
+COBJS	:= $(COBJS-y)
+SOBJS	:= $(SOBJS-y)
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff --git a/board/spear/spear1300/Makefile b/board/spear/spear1300/Makefile
new file mode 100644
index 0000000..fb66895
--- /dev/null
+++ b/board/spear/spear1300/Makefile
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= spear1300.o
+SOBJS	:= spr_lowlevel_init.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/spear/spear1300/config.mk b/board/spear/spear1300/config.mk
new file mode 100644
index 0000000..0bbb40f
--- /dev/null
+++ b/board/spear/spear1300/config.mk
@@ -0,0 +1,28 @@
+#
+# (C) Copyright 2009
+# Vipin Kumar, ST Microelectronics <vipin.kumar@st.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#########################################################################
+
+TEXT_BASE = 0x00700000
+
+ALL += $(obj)u-boot.img
diff --git a/board/spear/spear1300/spear1300.c b/board/spear/spear1300/spear1300.c
new file mode 100644
index 0000000..ab8e53e
--- /dev/null
+++ b/board/spear/spear1300/spear1300.c
@@ -0,0 +1,89 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <nand.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#if defined(CONFIG_NAND_FSMC)
+int fsmc_nand_init(struct nand_chip *nand);
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	gd->bd->bi_arch_number = MACH_TYPE_SPEAR1300;
+	gd->bd->bi_boot_params = CONFIG_BOOT_PARAMS_ADDR;
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = get_ram_size(PHYS_SDRAM_1,
+					       PHYS_SDRAM_1_MAXSIZE);
+
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	setenv("verify", "n");
+
+#if defined(CONFIG_SPEAR_USBTTY)
+	setenv("stdin", "usbtty");
+	setenv("stdout", "usbtty");
+	setenv("stderr", "usbtty");
+#endif
+	return 0;
+}
+
+/*
+ * board_nand_init - Board specific NAND initialization
+ * @nand:	mtd private chip structure
+ *
+ * Called by nand_init_chip to initialize the board specific functions
+ */
+
+int board_nand_init(struct nand_chip *nand)
+{
+#if defined(CONFIG_NAND_FSMC)
+	return fsmc_nand_init(nand);
+#endif
+}
+
+#if defined(CONFIG_CMD_NET)
+int board_eth_init(bd_t *bis)
+{
+	/*
+	 * Board specific ethernet initialization comes here. eg. gmac clock
+	 * configuration etc
+	 */
+
+	return dw_mii_initialize(0, CONFIG_SPEAR_ETHBASE);
+}
+#endif
diff --git a/board/spear/spear1300/spr_lowlevel_init.S b/board/spear/spear1300/spr_lowlevel_init.S
new file mode 100644
index 0000000..ba93922
--- /dev/null
+++ b/board/spear/spear1300/spr_lowlevel_init.S
@@ -0,0 +1,38 @@
+/*
+ * (C) Copyright 2006
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+/*
+ * platform specific initializations are already done in Xloader
+ * Initializations already done include
+ * DDR, PLLs, IP's clock enable and reset release etc
+ */
+.globl lowlevel_init
+lowlevel_init:
+	/* By default, U-Boot switches CPU to low-vector */
+	/* Revert this as we work in high vector even in U-Boot */
+	mrc	p15, 0, r0, c1, c0, 0
+	orr	r0, r0, #0x00002000
+	mcr	p15, 0, r0, c1, c0, 0
+	mov	pc, lr
diff --git a/include/asm-arm/arch-spear13xx/hardware.h b/include/asm-arm/arch-spear13xx/hardware.h
index 384260a..7a1cedb 100644
--- a/include/asm-arm/arch-spear13xx/hardware.h
+++ b/include/asm-arm/arch-spear13xx/hardware.h
@@ -24,10 +24,10 @@
 #ifndef _ASM_ARCH_HARDWARE_H
 #define _ASM_ARCH_HARDWARE_H
 
-#define CONFIG_SYS_USBD_BASE			(0xE1100000)
-#define CONFIG_SYS_PLUG_BASE			(0xE1200000)
-#define CONFIG_SYS_FIFO_BASE			(0xE1000800)
-#define CONFIG_SYS_SMI_BASE			(0xFC000000)
+#define CONFIG_SYS_USBD_BASE			(0xE3800000)
+#define CONFIG_SYS_PLUG_BASE			(0xE2800000)
+#define CONFIG_SYS_FIFO_BASE			(0xE3000800)
+#define CONFIG_SYS_SMI_BASE			(0xEA000000)
 #define CONFIG_SPEAR_TIMERBASE			(0xE0380000)
 #define CONFIG_SPEAR_MISCBASE			(0xE0700000)
 #define CONFIG_SYS_I2C_BASE			(0xE0280000)
diff --git a/include/configs/spear13xx.h b/include/configs/spear13xx.h
new file mode 100644
index 0000000..bcf3381
--- /dev/null
+++ b/include/configs/spear13xx.h
@@ -0,0 +1,199 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, STMicroelectronics, <vipin.kumar@st.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#if defined(CONFIG_MK_spear1300)
+#define CONFIG_SPEAR13XX			1
+#define CONFIG_SPEAR1300			1
+#endif
+
+#if defined(CONFIG_MK_usbtty)
+#define CONFIG_SPEAR_USBTTY			1
+#endif
+
+#if defined(CONFIG_MK_nand)
+#define CONFIG_ENV_IS_IN_NAND			1
+#else
+#define CONFIG_ENV_IS_IN_FLASH			1
+#endif
+
+/* Ethernet configuration */
+#define CONFIG_MII
+#define CONFIG_DW_ETH
+#define CONFIG_NET_MULTI
+#define CONFIG_DW_ALTDESC			1
+#define CONFIG_PHY_RESET_DELAY			(10000)		/* in usec */
+
+/* USBD driver configuration */
+#define CONFIG_DW_UDC
+#define CONFIG_USB_DEVICE
+#define CONFIG_USB_TTY
+
+#define CONFIG_USBD_PRODUCT_NAME		"SPEAr SoC"
+#define CONFIG_USBD_MANUFACTURER		"ST Microelectronics"
+
+#define CONFIG_EXTRA_ENV_USBTTY			"usbtty=cdc_acm\0"
+
+/* Timer, HZ specific defines */
+#define CONFIG_SYS_HZ				(1000)
+
+/* Flash configuration */
+#define CONFIG_ST_SMI				1
+#define CONFIG_SYS_MAX_FLASH_BANKS		2
+#define CONFIG_SYS_FLASH_BASE			(0xE6000000)
+#define CONFIG_SYS_CS1_FLASH_BASE		(0xE7000000)
+#define CONFIG_SYS_FLASH_BANK_SIZE		(0x01000000)
+#define CONFIG_SYS_FLASH_ADDR_BASE		{CONFIG_SYS_FLASH_BASE, \
+						CONFIG_SYS_CS1_FLASH_BASE}
+#define CONFIG_SYS_MAX_FLASH_SECT		128
+
+#define CONFIG_SYS_FLASH_EMPTY_INFO		1
+#define CONFIG_SYS_FLASH_ERASE_TOUT		(3 * CONFIG_SYS_HZ)
+#define CONFIG_SYS_FLASH_WRITE_TOUT		(3 * CONFIG_SYS_HZ)
+
+/*
+ * Serial Configuration (PL011)
+ */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_SYS_SERIAL0			0xE0000000
+#define CONFIG_PL011_CLOCK			(48 * 1000 * 1000)
+#define CONFIG_CONS_INDEX			0
+#define CONFIG_BAUDRATE				115200
+#define CONFIG_SYS_BAUDRATE_TABLE		{ 9600, 19200, 38400, \
+						57600, 115200 }
+
+#define CONFIG_SYS_LOADS_BAUD_CHANGE
+#define CONFIG_PL01x_PORTS			{(void *)CONFIG_SYS_SERIAL0}
+
+/*
+ * NAND FLASH Configuration
+ */
+#define CONFIG_NAND_FSMC			1
+#define CONFIG_BOARD_NAND_LP			1
+#define CONFIG_BOARD_NAND_8BIT			1
+#define CONFIG_SYS_MAX_NAND_DEVICE		1
+#define CONFIG_MTD_NAND_VERIFY_WRITE		1
+#define CONFIG_SYS_NAND_BASE			(0xA0000000)
+
+/*
+ * Command support defines
+ */
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+
+/* This must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <config_cmd_default.h>
+
+/*
+ * Default Environment Varible definitions
+ */
+#if defined(CONFIG_SPEAR_USBTTY)
+#define CONFIG_BOOTDELAY			-1
+#else
+#define CONFIG_BOOTDELAY			1
+#endif
+
+/*
+ * Environment placing
+ */
+#if defined(CONFIG_ENV_IS_IN_FLASH)
+/*
+ * Environment is in serial NOR flash
+ */
+#define CONFIG_SYS_MONITOR_LEN			0x00040000
+#define CONFIG_ENV_SECT_SIZE			0x00010000
+#define CONFIG_FSMTDBLK				"/dev/mtdblock8 "
+
+#define CONFIG_BOOTCOMMAND			"bootm 0xe6050000"
+
+#define CONFIG_SYS_MONITOR_BASE			CONFIG_SYS_FLASH_BASE
+#define CONFIG_ENV_ADDR				(CONFIG_SYS_MONITOR_BASE + \
+						CONFIG_SYS_MONITOR_LEN)
+#elif defined(CONFIG_ENV_IS_IN_NAND)
+/*
+ * Environment is in NAND
+ */
+
+#define CONFIG_ENV_OFFSET			0x60000
+#define CONFIG_ENV_RANGE			0x10000
+#define CONFIG_FSMTDBLK				"/dev/mtdblock12 "
+
+#define CONFIG_BOOTCOMMAND			"nand read.jffs2 0x1600000 " \
+						"0x80000 0x4C0000; " \
+						"bootm 0x1600000"
+#endif
+
+#define CONFIG_BOOTARGS_NFS			"root=/dev/nfs ip=dhcp " \
+						"console=ttyAMA0 init=/bin/sh"
+#define CONFIG_BOOTARGS				"console=ttyAMA0 mem=128M "  \
+						"root="CONFIG_FSMTDBLK \
+						"rootfstype=jffs2"
+
+#define CONFIG_ENV_SIZE				0x02000
+
+/* Miscellaneous configurable options */
+#define CONFIG_ARCH_CPU_INIT			1
+#define CONFIG_DISPLAY_CPUINFO			1
+
+#define CONFIG_BOOT_PARAMS_ADDR			0x00000100
+#define CONFIG_CMDLINE_TAG			1
+#define CONFIG_SETUP_MEMORY_TAGS		1
+#define CONFIG_MISC_INIT_R			1
+#define CONFIG_ZERO_BOOTDELAY_CHECK		1
+#define CONFIG_AUTOBOOT_KEYED			1
+#define CONFIG_AUTOBOOT_STOP_STR		" "
+#define CONFIG_AUTOBOOT_PROMPT			\
+		"Hit SPACE in %d seconds to stop autoboot.\n", bootdelay
+
+#define CONFIG_SYS_MEMTEST_START		0x00800000
+#define CONFIG_SYS_MEMTEST_END			0x04000000
+#define CONFIG_SYS_MALLOC_LEN			(1024*1024)
+#define CONFIG_SYS_GBL_DATA_SIZE		128
+#define CONFIG_IDENT_STRING			"-SPEAr"
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT			"u-boot> "
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_CBSIZE			256
+#define CONFIG_SYS_PBSIZE			(CONFIG_SYS_CBSIZE + \
+						sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS			16
+#define CONFIG_SYS_BARGSIZE			CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_LOAD_ADDR			0x00800000
+#define CONFIG_SYS_CONSOLE_INFO_QUIET		1
+#define CONFIG_SYS_64BIT_VSPRINTF		1
+
+#define CONFIG_EXTRA_ENV_SETTINGS		CONFIG_EXTRA_ENV_USBTTY
+
+/* Physical Memory Map */
+#define CONFIG_NR_DRAM_BANKS			1
+#define PHYS_SDRAM_1				0x00000000
+#define PHYS_SDRAM_1_MAXSIZE			0x40000000
+
+#endif
-- 
1.6.0.2

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

* [U-Boot] [PATCH 17/17] SPEAr : Supporting various configurations for spear3xx and spear6xx boards
  2010-04-21  7:54                               ` [U-Boot] [PATCH 16/17] SPEAr : spear1300 SoC " Vipin KUMAR
@ 2010-04-21  7:54                                 ` Vipin KUMAR
  0 siblings, 0 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21  7:54 UTC (permalink / raw)
  To: u-boot

spear3xx and 6xx boards can be compiled in following configurations
1. Environment placed in NAND
2. console on usb device
3. console on usb device with environment placed in NAND

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 Makefile                       |   16 ++++++++++++++--
 board/spear/spear300/config.mk |   11 -----------
 board/spear/spear310/config.mk |   11 -----------
 board/spear/spear320/config.mk |   11 -----------
 board/spear/spear600/config.mk |   11 -----------
 include/configs/spear3xx.h     |   10 ++++++++++
 include/configs/spear6xx.h     |   10 ++++++++++
 7 files changed, 34 insertions(+), 46 deletions(-)

diff --git a/Makefile b/Makefile
index 7af505e..04b9cc7 100644
--- a/Makefile
+++ b/Makefile
@@ -3038,11 +3038,23 @@ smdk2410_config	:	unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0
 
 spear300_config \
+spear300_nand_config \
+spear300_usbtty_config \
+spear300_usbtty_nand_config \
 spear310_config \
-spear320_config :	unconfig
+spear310_nand_config \
+spear310_usbtty_config \
+spear310_usbtty_nand_config \
+spear320_config \
+spear320_nand_config \
+spear320_usbtty_config \
+spear320_usbtty_nand_config :	unconfig
 	@$(MKCONFIG) -n $@ -t $(@:_config=) spear3xx arm arm926ejs $(@:_config=) spear spear
 
-spear600_config :	unconfig
+spear600_config \
+spear600_nand_config \
+spear600_usbtty_config \
+spear600_usbtty_nand_config :	unconfig
 	@$(MKCONFIG) -n $@ -t $(@:_config=) spear6xx arm arm926ejs $(@:_config=) spear spear
 
 spear1300_config \
diff --git a/board/spear/spear300/config.mk b/board/spear/spear300/config.mk
index 35646f2..0bbb40f 100644
--- a/board/spear/spear300/config.mk
+++ b/board/spear/spear300/config.mk
@@ -26,14 +26,3 @@
 TEXT_BASE = 0x00700000
 
 ALL += $(obj)u-boot.img
-
-# Environment variables in NAND
-ifeq ($(ENV),NAND)
-PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_NAND
-else
-PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_FLASH
-endif
-
-ifeq ($(CONSOLE),USB)
-PLATFORM_RELFLAGS += -DCONFIG_SPEAR_USBTTY
-endif
diff --git a/board/spear/spear310/config.mk b/board/spear/spear310/config.mk
index cba8436..c8264c3 100644
--- a/board/spear/spear310/config.mk
+++ b/board/spear/spear310/config.mk
@@ -27,18 +27,7 @@ TEXT_BASE = 0x00700000
 
 ALL += $(obj)u-boot.img
 
-# Environment variables in NAND
-ifeq ($(ENV),NAND)
-PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_NAND
-else
-PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_FLASH
-endif
-
 # Support parallel flash
 ifeq ($(FLASH),PNOR)
 PLATFORM_RELFLAGS += -DCONFIG_FLASH_PNOR
 endif
-
-ifeq ($(CONSOLE),USB)
-PLATFORM_RELFLAGS += -DCONFIG_SPEAR_USBTTY
-endif
diff --git a/board/spear/spear320/config.mk b/board/spear/spear320/config.mk
index cba8436..c8264c3 100644
--- a/board/spear/spear320/config.mk
+++ b/board/spear/spear320/config.mk
@@ -27,18 +27,7 @@ TEXT_BASE = 0x00700000
 
 ALL += $(obj)u-boot.img
 
-# Environment variables in NAND
-ifeq ($(ENV),NAND)
-PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_NAND
-else
-PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_FLASH
-endif
-
 # Support parallel flash
 ifeq ($(FLASH),PNOR)
 PLATFORM_RELFLAGS += -DCONFIG_FLASH_PNOR
 endif
-
-ifeq ($(CONSOLE),USB)
-PLATFORM_RELFLAGS += -DCONFIG_SPEAR_USBTTY
-endif
diff --git a/board/spear/spear600/config.mk b/board/spear/spear600/config.mk
index 35646f2..0bbb40f 100644
--- a/board/spear/spear600/config.mk
+++ b/board/spear/spear600/config.mk
@@ -26,14 +26,3 @@
 TEXT_BASE = 0x00700000
 
 ALL += $(obj)u-boot.img
-
-# Environment variables in NAND
-ifeq ($(ENV),NAND)
-PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_NAND
-else
-PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_FLASH
-endif
-
-ifeq ($(CONSOLE),USB)
-PLATFORM_RELFLAGS += -DCONFIG_SPEAR_USBTTY
-endif
diff --git a/include/configs/spear3xx.h b/include/configs/spear3xx.h
index 581f28d..7d4d8e0 100644
--- a/include/configs/spear3xx.h
+++ b/include/configs/spear3xx.h
@@ -39,6 +39,16 @@
 #define CONFIG_SPEAR320				1
 #endif
 
+#if defined(CONFIG_MK_usbtty)
+#define CONFIG_SPEAR_USBTTY			1
+#endif
+
+#if defined(CONFIG_MK_nand)
+#define CONFIG_ENV_IS_IN_NAND			1
+#else
+#define CONFIG_ENV_IS_IN_FLASH			1
+#endif
+
 #include <configs/spear-common.h>
 
 /* Ethernet driver configuration */
diff --git a/include/configs/spear6xx.h b/include/configs/spear6xx.h
index 24a6948..1930fad 100644
--- a/include/configs/spear6xx.h
+++ b/include/configs/spear6xx.h
@@ -30,6 +30,16 @@
  */
 #define CONFIG_SPEAR600				1
 
+#if defined(CONFIG_MK_usbtty)
+#define CONFIG_SPEAR_USBTTY			1
+#endif
+
+#if defined(CONFIG_MK_nand)
+#define CONFIG_ENV_IS_IN_NAND			1
+#else
+#define CONFIG_ENV_IS_IN_FLASH			1
+#endif
+
 #include <configs/spear-common.h>
 
 /* Serial Configuration (PL011) */
-- 
1.6.0.2

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

* [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs
  2010-04-21  7:54           ` [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs Vipin KUMAR
  2010-04-21  7:54             ` [U-Boot] [PATCH 07/17] SPEAr : Network driver support added Vipin KUMAR
@ 2010-04-21 11:51             ` Peter Tyser
  2010-04-22  4:45               ` Vipin KUMAR
  1 sibling, 1 reply; 38+ messages in thread
From: Peter Tyser @ 2010-04-21 11:51 UTC (permalink / raw)
  To: u-boot

Hi Vipin,

On Wed, 2010-04-21 at 13:24 +0530, Vipin KUMAR wrote:
> Adding CONFIG_DISPLAY_CPUINFO and CONFIG_ARCH_CPU_INIT support for SPEAr3xx and
> SPEAr6xx SoCs
> 
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
> ---
>  arch/arm/cpu/arm926ejs/spear/Makefile      |    3 +-
>  arch/arm/include/asm/arch-spear/spr_misc.h |    5 ++
>  cpu/arm926ejs/spear/cpu_info.c             |   76 ++++++++++++++++++++++++++++

The cpu path above needs to be adjusted to arch/arm/cpu/...

Also, cpu_info.c doesn't seem like the best filename.  You put both
initialization code and informational code in it, so a more generic name
such as "cpu.c" would be preferred.  Or possibly cpu.c and cpu_init.c.
PowerPC boards would serve as a decent reference.

Best,
Peter

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

* [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support
  2010-04-21  7:54 [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support Vipin KUMAR
  2010-04-21  7:54 ` [U-Boot] [PATCH 01/17] u-boot.img file not created when srctree and objtree are different Vipin KUMAR
@ 2010-04-21 11:54 ` Peter Tyser
  2010-04-21 12:00   ` Vipin KUMAR
  1 sibling, 1 reply; 38+ messages in thread
From: Peter Tyser @ 2010-04-21 11:54 UTC (permalink / raw)
  To: u-boot

Hi Vipin,

>  cpu/arm926ejs/spear/cpu_info.c             |   76 ++
>  cpu/arm_cortexa8/spear13xx/Makefile        |   52 ++
>  cpu/arm_cortexa8/spear13xx/cache.S         |  112 +++
>  cpu/arm_cortexa8/spear13xx/cpu_info.c      |  105 +++
>  cpu/arm_cortexa8/spear13xx/reset.c         |   47 ++
>  cpu/arm_cortexa8/spear13xx/timer.c         |  136 ++++

It looks like the cpu/ usage needs to be reviewed across the patchset.

Best,
Peter

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

* [U-Boot] [PATCH 07/17] SPEAr : Network driver support added
  2010-04-21  7:54             ` [U-Boot] [PATCH 07/17] SPEAr : Network driver support added Vipin KUMAR
  2010-04-21  7:54               ` [U-Boot] [PATCH 08/17] SPEAr : Network support configured for spear SoCs Vipin KUMAR
@ 2010-04-21 12:00               ` Peter Tyser
  2010-04-22  4:30                 ` Vipin KUMAR
  2010-04-21 17:48               ` Ben Warren
  2 siblings, 1 reply; 38+ messages in thread
From: Peter Tyser @ 2010-04-21 12:00 UTC (permalink / raw)
  To: u-boot

Hi Vipin,

>  drivers/net/dw_eth.c |  504 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/net/dw_eth.h |  281 ++++++++++++++++++++++++++++

I'd vote to name the driver "designware.c", or something else more
descriptive than the somewhat ambiguous "dw".  The _eth portion of the
name isn't necessary either since its contained in the driver/net
directory.

Best,
Peter

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

* [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support
  2010-04-21 11:54 ` [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support Peter Tyser
@ 2010-04-21 12:00   ` Vipin KUMAR
  0 siblings, 0 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-21 12:00 UTC (permalink / raw)
  To: u-boot

On 4/21/2010 5:24 PM, Peter Tyser wrote:
> Hi Vipin,
> 
>>  cpu/arm926ejs/spear/cpu_info.c             |   76 ++
>>  cpu/arm_cortexa8/spear13xx/Makefile        |   52 ++
>>  cpu/arm_cortexa8/spear13xx/cache.S         |  112 +++
>>  cpu/arm_cortexa8/spear13xx/cpu_info.c      |  105 +++
>>  cpu/arm_cortexa8/spear13xx/reset.c         |   47 ++
>>  cpu/arm_cortexa8/spear13xx/timer.c         |  136 ++++
> 
> It looks like the cpu/ usage needs to be reviewed across the patchset.
> 

Yes, I noticed this immediately after sending the mail
I am just waiting for other comments to incorporate this as well as other 
review comments in patchset v2

> Best,
> Peter
> 
> 

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

* [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c
  2010-04-21  7:54                       ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Vipin KUMAR
  2010-04-21  7:54                         ` [U-Boot] [PATCH 13/17] SPEAr : smi driver moved completely into drivers/mtd Vipin KUMAR
@ 2010-04-21 12:11                         ` Peter Tyser
  2010-04-22  4:07                           ` Vipin KUMAR
  1 sibling, 1 reply; 38+ messages in thread
From: Peter Tyser @ 2010-04-21 12:11 UTC (permalink / raw)
  To: u-boot

Hi Vipin,

On Wed, 2010-04-21 at 13:24 +0530, Vipin KUMAR wrote:
> The i2c IP used by spear platform is a synopsys i2c controller
> The earlier driver adds the driver of this controller as if it is
> specific to
> spear platform.
> The driver files are now moved into drivers/i2c folder for reusability
> by other
> platforms
> 
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
> ---
>  arch/arm/include/asm/arch-spear/spr_i2c.h |  146 -------------
>  drivers/i2c/Makefile                      |    2 +-
>  drivers/i2c/dw_i2c.c                      |  331
> +++++++++++++++++++++++++++++

I'd similarly lean towards naming the new file designware.c, or
synopsis.c.  It looks like the rest of the i2c drivers use a _i2c
suffix, so I guess designware_i2c.c or synopsis_i2c.c would be best for
consistency's sake.  At a minimum it'd be nice to mention in the
dw_i2c.c file what silicon the driver supports as right now a user needs
to guess what "dw_i2c.c" runs on based solely on "dw".

When you create patches with git format-patch, its nice to use the -M
and -C to detect renames/copies.  It makes the patch much smaller and
much easier to review what actually changed.

Best,
Peter

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

* [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added
  2010-04-21  7:54                   ` [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added Vipin KUMAR
  2010-04-21  7:54                     ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Vipin KUMAR
@ 2010-04-21 17:02                     ` Scott Wood
  2010-04-22  4:28                       ` Vipin KUMAR
  1 sibling, 1 reply; 38+ messages in thread
From: Scott Wood @ 2010-04-21 17:02 UTC (permalink / raw)
  To: u-boot

On Wed, Apr 21, 2010 at 01:24:36PM +0530, Vipin KUMAR wrote:
> +#if defined(CONFIG_BOARD_NAND_LP)

CONFIG_SYS_FSMC_NAND_LP, CONFIG_SYS_FSMC_NAND_16BIT, etc.

> +			/*
> +			 * length is intentionally kept a higher multiple of 2
> +			 * to read at least 13 bytes even in case of 16 bit NAND
> +			 * devices
> +			 */
> +			len = ((len + 1) >> 1) << 1;

len = roundup(len, 2);

> +	fsmc_version = (peripid2 >> FSMC_REVISION_SHFT) & \
> +		       FSMC_REVISION_MSK;

Unnecessary backslash.

> +#ifndef __FSMC_NAND_H__
> +#define __FSMC_NAND_H__
> +
> +struct fsmc_regs {
> +	u8 reserved_1[0x40];
> +	u32 genmemctrl_pc;		/* 0x40 */
> +	u32 genmemctrl_sts;		/* 0x44 */
> +	u32 genmemctrl_comm;		/* 0x48 */
> +	u32 genmemctrl_attrib;		/* 0x4c */
> +	u32 genmemctrl_ioata;		/* 0x50 */
> +	u32 genmemctrl_ecc1;		/* 0x54 */
> +	u32 genmemctrl_ecc2;		/* 0x58 */
> +	u32 genmemctrl_ecc3;		/* 0x5c */
> +	u8 reserved_2[0xfe0 - 0x60];
> +	u32 genmemctrl_peripid0;	/* 0xfe0 */
> +	u32 genmemctrl_peripid1;	/* 0xfe4 */
> +	u32 genmemctrl_peripid2;	/* 0xfe8 */
> +	u32 genmemctrl_peripid3;	/* 0xfec */
> +	u32 genmemctrl_pcellid0;	/* 0xff0 */
> +	u32 genmemctrl_pcellid1;	/* 0xff4 */
> +	u32 genmemctrl_pcellid2;	/* 0xff8 */
> +	u32 genmemctrl_pcellid3;	/* 0xffc */
> +};

Is the genmemctrl_ prefix really needed?

> +extern int spear_nand_init(struct nand_chip *nand);

fsmc_nand_init?

-Scott

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

* [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface
  2010-04-21  7:54                     ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Vipin KUMAR
  2010-04-21  7:54                       ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Vipin KUMAR
@ 2010-04-21 17:02                       ` Scott Wood
  2010-04-22  4:21                         ` Vipin KUMAR
  1 sibling, 1 reply; 38+ messages in thread
From: Scott Wood @ 2010-04-21 17:02 UTC (permalink / raw)
  To: u-boot

On Wed, Apr 21, 2010 at 01:24:37PM +0530, Vipin KUMAR wrote:
> diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c
> index 1207709..3ac62d1 100644
> --- a/board/spear/spear310/spear310.c
> +++ b/board/spear/spear310/spear310.c
> @@ -29,7 +29,8 @@
>  #include <asm/arch/hardware.h>
>  #include <asm/arch/spr_defs.h>
>  #include <asm/arch/spr_misc.h>
> -#include <asm/arch/spr_nand.h>
> +
> +int fsmc_nand_init(struct nand_chip *nand);

Put it in a header file.

-Scott

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

* [U-Boot] [PATCH 07/17] SPEAr : Network driver support added
  2010-04-21  7:54             ` [U-Boot] [PATCH 07/17] SPEAr : Network driver support added Vipin KUMAR
  2010-04-21  7:54               ` [U-Boot] [PATCH 08/17] SPEAr : Network support configured for spear SoCs Vipin KUMAR
  2010-04-21 12:00               ` [U-Boot] [PATCH 07/17] SPEAr : Network " Peter Tyser
@ 2010-04-21 17:48               ` Ben Warren
  2010-04-22  4:43                 ` Vipin KUMAR
  2010-04-23 10:32                 ` Armando VISCONTI
  2 siblings, 2 replies; 38+ messages in thread
From: Ben Warren @ 2010-04-21 17:48 UTC (permalink / raw)
  To: u-boot

Hi Vipin,

On 4/21/2010 12:54 AM, Vipin KUMAR wrote:
> Designware network driver support added.
> This is a Synopsys ethernet controller
>
> Signed-off-by: Vipin Kumar<vipin.kumar@st.com>
> ---
>   drivers/net/Makefile |    1 +
>   drivers/net/dw_eth.c |  504 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   drivers/net/dw_eth.h |  281 ++++++++++++++++++++++++++++
>    
I agree with Peter that a different name would be preferable.  Something 
conveying the manufacturer or, if it's a very specific controller, the 
part number.  Give thought to whether it will potentially be expanded up 
or generic-ized in the future (I know that's hard to do!)
>   include/netdev.h     |    1 +
>   4 files changed, 787 insertions(+), 0 deletions(-)
>   create mode 100755 drivers/net/dw_eth.c
>   create mode 100644 drivers/net/dw_eth.h
>
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 1ec0ba1..d03c353 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -68,6 +68,7 @@ COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o
>   COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
>   COBJS-$(CONFIG_SMC91111) += smc91111.o
>   COBJS-$(CONFIG_SMC911X) += smc911x.o
> +COBJS-$(CONFIG_DW_ETH) += dw_eth.o
>   COBJS-$(CONFIG_TIGON3) += tigon3.o bcm570x_autoneg.o 5701rls.o
>   COBJS-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
>   COBJS-$(CONFIG_TSEC_ENET) += tsec.o
>    
Alphabetical order, please
> diff --git a/drivers/net/dw_eth.c b/drivers/net/dw_eth.c
> new file mode 100755
> index 0000000..52e7d15
> --- /dev/null
> +++ b/drivers/net/dw_eth.c
> @@ -0,0 +1,504 @@
> +/*
> + * (C) Copyright 2009
> + * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
> + *
> + * (C) Copyright 2008
> + * Deepak Sikri, ST Micoelectronics, deepak.sikri at st.com.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +/*
> + * Designware ethernet IP driver for u-boot
> + */
> +
> +#include<common.h>
> +#include<miiphy.h>
> +#include<malloc.h>
> +#include<linux/err.h>
> +#include<asm/io.h>
> +#include "dw_eth.h"
> +
> +static void tx_descs_init(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> +	struct dmamacdescr *desc_table_p =&priv->tx_mac_descrtable[0];
> +	char *txbuffs =&priv->txbuffs[0];
> +	struct dmamacdescr *desc_p;
> +
> +	u32 idx;
> +
> +	for (idx = 0; idx<  CONFIG_TX_DESCR_NUM; idx++) {
> +
> +		desc_p =&desc_table_p[idx];
> +		desc_p->dmamac_addr =&txbuffs[idx * CONFIG_ETH_BUFSIZE];
> +		desc_p->dmamac_next =&desc_table_p[idx + 1];
> +
> +#if defined(CONFIG_DW_ALTDESC)
>    
Please use a more descriptive CONFIG option. Remember these have global 
namespace
> +		desc_p->txrx_status&= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
> +				DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
> +				DESC_TXSTS_TXCHECKINSCTRL | \
> +				DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
> +
> +		desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
> +		desc_p->dmamac_cntl = 0;
> +		desc_p->txrx_status&= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
> +#else
> +		desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
> +		desc_p->txrx_status = 0;
> +#endif
> +	}
> +
> +	/* Correcting the last pointer of the chain */
> +	desc_p->dmamac_next =&desc_table_p[0];
> +
> +	writel((ulong)&desc_table_p[0],&dma_p->txdesclistaddr);
> +}
> +
> +static void rx_descs_init(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> +	struct dmamacdescr *desc_table_p =&priv->rx_mac_descrtable[0];
> +	char *rxbuffs =&priv->rxbuffs[0];
> +	struct dmamacdescr *desc_p;
> +
> +	u32 idx;
> +
> +	for (idx = 0; idx<  CONFIG_RX_DESCR_NUM; idx++) {
> +
>    
Remove unnecessary blank lines
> +		desc_p =&desc_table_p[idx];
> +		desc_p->dmamac_addr =&rxbuffs[idx * CONFIG_ETH_BUFSIZE];
> +		desc_p->dmamac_next =&desc_table_p[idx + 1];
> +
> +		desc_p->dmamac_cntl =
> +			(MAC_MAX_FRAME_SZ&  DESC_RXCTRL_SIZE1MASK) | \
> +				      DESC_RXCTRL_RXCHAIN;
> +
> +		desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
> +	}
> +
> +	/* Correcting the last pointer of the chain */
> +	desc_p->dmamac_next =&desc_table_p[0];
> +
> +	writel((ulong)&desc_table_p[0],&dma_p->rxdesclistaddr);
> +}
> +
> +static void descs_init(struct eth_device *dev)
> +{
> +	tx_descs_init(dev);
> +	rx_descs_init(dev);
> +}
> +
> +static void mac_reset(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_mac_regs *mac_p = priv->mac_regs_p;
> +	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> +
> +	u32 timeout = CONFIG_MACRESET_TIMEOUT;
> +
> +	writel(DMAMAC_SRST,&dma_p->busmode);
> +	writel(MII_PORTSELECT,&mac_p->conf);
> +
> +	do {
> +		if (!(readl(&dma_p->busmode)&  DMAMAC_SRST))
> +			break;
> +		udelay(1000);
> +	} while (timeout--);
> +}
> +
> +static int dw_eth_init(struct eth_device *dev, bd_t *bis)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_mac_regs *mac_p = priv->mac_regs_p;
> +	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> +
> +	u8 *mac_id =&dev->enetaddr[0];
> +	u32 conf, macid_lo, macid_hi;
> +
> +	/* Reset ethernet hardware */
> +	mac_reset(dev);
> +
> +	macid_lo = mac_id[0] + (mac_id[1]<<  8) + \
> +		   (mac_id[2]<<  16) + (mac_id[3]<<  24);
> +	macid_hi = mac_id[4] + (mac_id[5]<<  8);
> +
> +	writel(macid_hi,&mac_p->macaddr0hi);
> +	writel(macid_lo,&mac_p->macaddr0lo);
> +
>    
Please provide a static function with signature 'static void 
program_mac(struct eth_device *)' for programming the MAC.
> +	writel(FIXEDBURST | PRIORXTX_41 | BURST_16,
> +			&dma_p->busmode);
> +
> +	writel(FLUSHTXFIFO | readl(&dma_p->opmode),&dma_p->opmode);
> +	writel(STOREFORWARD | TXSECONDFRAME,&dma_p->opmode);
> +
> +	conf = FRAMEBURSTENABLE | DISABLERXOWN;
> +
> +	if (priv->speed != SPEED_1000M)
> +		conf |= MII_PORTSELECT;
> +
> +	if (priv->duplex == FULL_DUPLEX)
> +		conf |= FULLDPLXMODE;
> +
> +	writel(conf,&mac_p->conf);
> +
> +	descs_init(dev);
> +
> +	/*
> +	 * Start/Enable xfer at dma as well as mac level
> +	 */
> +	writel(readl(&dma_p->opmode) | RXSTART,&dma_p->opmode);
> +	writel(readl(&dma_p->opmode) | TXSTART,&dma_p->opmode);
> +
> +	writel(readl(&mac_p->conf) | RXENABLE,&mac_p->conf);
> +	writel(readl(&mac_p->conf) | TXENABLE,&mac_p->conf);
> +
> +	return 0;
> +}
> +
> +static int dw_eth_send(struct eth_device *dev, volatile void *packet,
> +		int length)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> +	u32 desc_num = priv->tx_currdescnum;
> +	struct dmamacdescr *desc_p =&priv->tx_mac_descrtable[desc_num];
> +
> +	/* Check if the descriptor is owned by CPU */
> +	if (desc_p->txrx_status&  DESC_TXSTS_OWNBYDMA) {
> +		printf("eth_send : CPU not owner of tx frame\n");
> +		return -1;
> +	}
> +
> +	memcpy((void *)desc_p->dmamac_addr, (void *)packet, length);
> +
> +#if defined(CONFIG_DW_ALTDESC)
> +	desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
> +	desc_p->dmamac_cntl |= (length<<  DESC_TXCTRL_SIZE1SHFT)&  \
> +			       DESC_TXCTRL_SIZE1MASK;
> +
> +	desc_p->txrx_status&= ~(DESC_TXSTS_MSK);
> +	desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
> +#else
> +	desc_p->dmamac_cntl |= ((length<<  DESC_TXCTRL_SIZE1SHFT)&  \
> +			       DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \
> +			       DESC_TXCTRL_TXFIRST;
> +
> +	desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
> +#endif
> +
> +	/* Test the wrap-around condition. */
> +	if (++desc_num>= CONFIG_TX_DESCR_NUM)
> +		desc_num = 0;
> +
> +	priv->tx_currdescnum = desc_num;
> +
> +	/* Start the transmission */
> +	writel(POLL_DATA,&dma_p->txpolldemand);
> +
> +	return 0;
> +}
> +
> +static int dw_eth_recv(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	u32 desc_num = priv->rx_currdescnum;
> +	struct dmamacdescr *desc_p =&priv->rx_mac_descrtable[desc_num];
> +
> +	u32 status = desc_p->txrx_status;
> +	int length = 0;
> +
> +	/* Check  if the owner is the CPU */
> +	if (!(status&  DESC_RXSTS_OWNBYDMA)) {
> +
> +		length = (status&  DESC_RXSTS_FRMLENMSK)>>  \
> +			 DESC_RXSTS_FRMLENSHFT;
> +
> +		NetReceive(desc_p->dmamac_addr, length);
> +
> +		/*
> +		 * Make the current descriptor valid again and go to
> +		 * the next one
> +		 */
> +		desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
> +
> +		/* Test the wrap-around condition. */
> +		if (++desc_num>= CONFIG_RX_DESCR_NUM)
> +			desc_num = 0;
> +	}
> +
> +	priv->rx_currdescnum = desc_num;
> +
> +	return length;
> +}
> +
> +static void dw_eth_halt(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +
> +	mac_reset(dev);
> +	priv->tx_currdescnum = priv->rx_currdescnum = 0;
> +}
> +
> +static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_mac_regs *mac_p = priv->mac_regs_p;
> +	u32 miiaddr;
> +	u32 timeout = CONFIG_MDIO_TIMEOUT;
> +
> +	miiaddr = ((addr<<  MIIADDRSHIFT)&  MII_ADDRMSK) | \
> +		  ((reg<<  MIIREGSHIFT)&  MII_REGMSK);
> +
> +	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY,&mac_p->miiaddr);
> +
> +	do {
> +		if (!(readl(&mac_p->miiaddr)&  MII_BUSY))
> +			break;
> +		udelay(1000);
> +	} while (timeout--);
> +
> +	*val = readl(&mac_p->miidata);
> +
> +	return 0;
> +}
> +
> +static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_mac_regs *mac_p = priv->mac_regs_p;
> +	u32 miiaddr;
> +	u32 timeout = CONFIG_MDIO_TIMEOUT;
> +	u16 value;
> +
> +	writel(val,&mac_p->miidata);
> +	miiaddr = ((addr<<  MIIADDRSHIFT)&  MII_ADDRMSK) | \
> +		  ((reg<<  MIIREGSHIFT)&  MII_REGMSK) | MII_WRITE;
> +
> +	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY,&mac_p->miiaddr);
> +
> +	do {
> +		if (!(readl(&mac_p->miiaddr)&  MII_BUSY))
> +			break;
> +		udelay(1000);
> +	} while (timeout--);
> +
> +	/* Needed as a fix for ST-Phy */
> +	eth_mdio_read(dev, addr, reg,&value);
> +
> +	return 0;
> +}
> +
> +static u8 find_phy(struct eth_device *dev)
> +{
> +	u8 phy_addr = 0;
> +	u16 ctrl, oldctrl;
> +
> +	do {
> +		eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
> +		oldctrl = ctrl&  PHY_BMCR_AUTON;
> +
> +		ctrl ^= PHY_BMCR_AUTON;
> +		eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
> +		eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
> +		ctrl&= PHY_BMCR_AUTON;
> +
> +		if (ctrl == oldctrl) {
> +			phy_addr++;
> +		} else {
> +			ctrl ^= PHY_BMCR_AUTON;
> +			eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
> +			break;
> +		}
> +	} while (phy_addr<  32);
> +
> +	return phy_addr;
> +}
> +
> +static void dw_reset_phy(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	u16 ctrl;
> +	u32 timeout = CONFIG_PHYRESET_TIMEOUT;
> +	u32 phy_addr = priv->address;
> +
> +	eth_mdio_write(dev, phy_addr, PHY_BMCR, PHY_BMCR_RESET);
> +	do {
> +		eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
> +		if (!(ctrl&  PHY_BMCR_RESET))
> +			break;
> +		udelay(1000);
> +	} while (timeout--);
> +
> +#ifdef CONFIG_PHY_RESET_DELAY
> +	udelay(CONFIG_PHY_RESET_DELAY);
> +#endif
> +}
> +
> +static void configure_phy(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	u8 phy_addr;
> +	u16 bmcr, ctrl;
> +#if defined(CONFIG_DW_AUTONEG)
> +	u16 bmsr;
> +	u32 timeout;
> +	u16 anlpar, btsr;
> +#endif
> +	priv->address = find_phy(dev);
> +	phy_addr = priv->address;
> +
> +	dw_reset_phy(dev);
> +
> +#if defined(CONFIG_DW_AUTONEG)
> +	bmcr = PHY_BMCR_AUTON | PHY_BMCR_RST_NEG | PHY_BMCR_100MB | \
> +	       PHY_BMCR_DPLX | PHY_BMCR_1000_MBPS;
> +#else
> +	bmcr = PHY_BMCR_100MB | PHY_BMCR_DPLX;
> +
> +#if defined(CONFIG_DW_SPEED10M)
> +	bmcr&= ~PHY_BMCR_100MB;
> +#endif
> +#if defined(CONFIG_DW_DUPLEXHALF)
> +	bmcr&= ~PHY_BMCR_DPLX;
> +#endif
> +#endif
> +	eth_mdio_write(dev, phy_addr, PHY_BMCR, bmcr);
> +
> +	/* Read the phy status register and populate priv structure */
> +#if defined(CONFIG_DW_AUTONEG)
> +	timeout = CONFIG_AUTONEG_TIMEOUT;
> +	do {
> +		eth_mdio_read(dev, phy_addr, PHY_BMSR,&bmsr);
> +		if (bmsr&  PHY_BMSR_AUTN_COMP)
> +			break;
> +		udelay(1000);
> +	} while (timeout--);
> +
> +	eth_mdio_read(dev, phy_addr, PHY_ANLPAR,&anlpar);
> +	eth_mdio_read(dev, phy_addr, PHY_1000BTSR,&btsr);
> +
> +	if (btsr&  (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
> +		priv->speed = SPEED_1000M;
> +		if (btsr&  PHY_1000BTSR_1000FD)
> +			priv->duplex = FULL_DUPLEX;
> +		else
> +			priv->duplex = HALF_DUPLEX;
> +	} else {
> +		if (anlpar&  PHY_ANLPAR_100)
> +			priv->speed = SPEED_100M;
> +		else
> +			priv->speed = SPEED_10M;
> +
> +		if (anlpar&  (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD))
> +			priv->duplex = FULL_DUPLEX;
> +		else
> +			priv->duplex = HALF_DUPLEX;
> +	}
> +#else
> +	eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
> +
> +	if (ctrl&  PHY_BMCR_DPLX)
> +		priv->duplex = FULL_DUPLEX;
> +	else
> +		priv->duplex = HALF_DUPLEX;
> +
> +	if (ctrl&  PHY_BMCR_1000_MBPS)
> +		priv->speed = SPEED_1000M;
> +	else if (ctrl&  PHY_BMCR_100_MBPS)
> +		priv->speed = SPEED_100M;
> +	else
> +		priv->speed = SPEED_10M;
> +#endif
> +}
> +
> +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
> +static int dw_mii_read(char *devname, u8 addr, u8 reg, u16 *val)
> +{
> +	struct eth_device *netdev;
> +
> +	netdev = eth_get_dev_by_name(devname);
> +	if (netdev)
> +		eth_mdio_read(netdev, addr, reg, val);
> +
> +	return 0;
> +}
> +
> +static int dw_mii_write(char *devname, u8 addr, u8 reg, u16 val)
> +{
> +	struct eth_device *netdev;
> +
> +	netdev = eth_get_dev_by_name(devname);
> +	if (netdev)
> +		eth_mdio_write(netdev, addr, reg, val);
> +
> +	return 0;
> +}
> +#endif
> +
> +int dw_mii_initialize(u32 id, ulong base_addr)
>    
Please use the same name in this function as the driver name.  We 
usually reserve 'mii' for device control plane.
> +{
> +	struct eth_device *netdev;
>    
I'd prefer if you named this variable 'dev', since 'netdev' is the name 
of a header file that's unrelated.  Apply globally.
> +	struct dw_eth_dev *priv;
> +
> +	netdev = (struct eth_device *) malloc(sizeof(struct eth_device));
> +	if (!netdev)
> +		return -ENOMEM;
> +
> +	/*
> +	 * Since the priv structure contains the descriptors which need a strict
> +	 * buswidth alignment, memalign is used to allocate memory
> +	 */
> +	priv = (struct dw_eth_dev *) memalign(16, sizeof(struct dw_eth_dev));
> +	if (!priv) {
> +		free(netdev);
> +		return -ENOMEM;
> +	}
> +
> +	memset(netdev, 0, sizeof(struct eth_device));
> +	memset(priv, 0, sizeof(struct dw_eth_dev));
> +
> +	sprintf(netdev->name, "mii%d", id);
> +	netdev->iobase = (int)base_addr;
> +	netdev->priv = priv;
>    
If you wait a couple of days until I resubmit my change to the 
'eth_device' struct, you can put in a pointer to the MAC programming 
function and not have to worry about that any more.
> +
> +	eth_getenv_enetaddr_by_index(id,&netdev->enetaddr[0]);
> +
> +	priv->dev = netdev;
> +	priv->mac_regs_p = (struct eth_mac_regs *)base_addr;
> +	priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
> +			DW_DMA_BASE_OFFSET);
> +
> +	mac_reset(netdev);
> +	configure_phy(netdev);
> +
> +	netdev->init = dw_eth_init;
> +	netdev->send = dw_eth_send;
> +	netdev->recv = dw_eth_recv;
> +	netdev->halt = dw_eth_halt;
> +
> +	eth_register(netdev);
> +
> +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
> +	miiphy_register(netdev->name, dw_mii_read, dw_mii_write);
> +#endif
> +	return 0;
>    
This should return 1 on success.
> +}
> diff --git a/drivers/net/dw_eth.h b/drivers/net/dw_eth.h
> new file mode 100644
> index 0000000..068211a
> --- /dev/null
> +++ b/drivers/net/dw_eth.h
> @@ -0,0 +1,281 @@
> +/*
> + * (C) Copyright 2009
> + * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _DW_ETH_H
> +#define _DW_ETH_H
> +
> +#define CONFIG_TX_DESCR_NUM	16
> +#define CONFIG_RX_DESCR_NUM	16
> +#define CONFIG_ETH_BUFSIZE	2048
> +#define TX_TOTAL_BUFSIZE	(CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
> +#define RX_TOTAL_BUFSIZE	(CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
> +
> +#define CONFIG_MACRESET_TIMEOUT	(3 * CONFIG_SYS_HZ)
> +#define CONFIG_MDIO_TIMEOUT	(3 * CONFIG_SYS_HZ)
> +#define CONFIG_PHYRESET_TIMEOUT	(3 * CONFIG_SYS_HZ)
> +#define CONFIG_AUTONEG_TIMEOUT	(5 * CONFIG_SYS_HZ)
> +
> +struct eth_mac_regs {
> +	u32 conf;		/* 0x00 */
> +	u32 framefilt;		/* 0x04 */
> +	u32 hashtablehigh;	/* 0x08 */
> +	u32 hashtablelow;	/* 0x0c */
> +	u32 miiaddr;		/* 0x10 */
> +	u32 miidata;		/* 0x14 */
> +	u32 flowcontrol;	/* 0x18 */
> +	u32 vlantag;		/* 0x1c */
> +	u32 version;		/* 0x20 */
> +	u8 reserved_1[0x38 - 0x24];
> +	u32 intreg;		/* 0x38 */
> +	u32 intmask;		/* 0x3c */
> +	u32 macaddr0hi;		/* 0x40 */
> +	u32 macaddr0lo;		/* 0x44 */
> +};
> +
> +/* MAC configuration register definitions */
> +#define FRAMEBURSTENABLE	(1<<  21)
> +#define MII_PORTSELECT		(1<<  15)
> +#define FES_100			(1<<  14)
> +#define DISABLERXOWN		(1<<  13)
> +#define FULLDPLXMODE		(1<<  11)
> +#define RXENABLE		(1<<  2)
> +#define TXENABLE		(1<<  3)
> +
> +/* MII address register definitions */
> +#define MII_BUSY		(1<<  0)
> +#define MII_WRITE		(1<<  1)
> +#define MII_CLKRANGE_60_100M	(0)
> +#define MII_CLKRANGE_100_150M	(0x4)
> +#define MII_CLKRANGE_20_35M	(0x8)
> +#define MII_CLKRANGE_35_60M	(0xC)
> +#define MII_CLKRANGE_150_250M	(0x10)
> +#define MII_CLKRANGE_250_300M	(0x14)
> +
> +#define MIIADDRSHIFT		(11)
> +#define MIIREGSHIFT		(6)
> +#define MII_REGMSK		(0x1F<<  6)
> +#define MII_ADDRMSK		(0x1F<<  11)
> +
> +
> +struct eth_dma_regs {
> +	u32 busmode;		/* 0x00 */
> +	u32 txpolldemand;	/* 0x04 */
> +	u32 rxpolldemand;	/* 0x08 */
> +	u32 rxdesclistaddr;	/* 0x0c */
> +	u32 txdesclistaddr;	/* 0x10 */
> +	u32 status;		/* 0x14 */
> +	u32 opmode;		/* 0x18 */
> +	u32 intenable;		/* 0x1c */
> +	u8 reserved[0x48 - 0x20];
> +	u32 currhosttxdesc;	/* 0x48 */
> +	u32 currhostrxdesc;	/* 0x4c */
> +	u32 currhosttxbuffaddr;	/* 0x50 */
> +	u32 currhostrxbuffaddr;	/* 0x54 */
> +};
> +
> +#define DW_DMA_BASE_OFFSET	(0x1000)
> +
> +/* Bus mode register definitions */
> +#define FIXEDBURST		(1<<  16)
> +#define PRIORXTX_41		(3<<  14)
> +#define PRIORXTX_31		(2<<  14)
> +#define PRIORXTX_21		(1<<  14)
> +#define PRIORXTX_11		(0<<  14)
> +#define BURST_1			(1<<  8)
> +#define BURST_2			(2<<  8)
> +#define BURST_4			(4<<  8)
> +#define BURST_8			(8<<  8)
> +#define BURST_16		(16<<  8)
> +#define BURST_32		(32<<  8)
> +#define RXHIGHPRIO		(1<<  1)
> +#define DMAMAC_SRST		(1<<  0)
> +
> +/* Poll demand definitions */
> +#define POLL_DATA		(0xFFFFFFFF)
> +
> +/* Operation mode definitions */
> +#define STOREFORWARD		(1<<  21)
> +#define FLUSHTXFIFO		(1<<  20)
> +#define TXSTART			(1<<  13)
> +#define TXSECONDFRAME		(1<<  2)
> +#define RXSTART			(1<<  1)
> +
> +/* Descriptior related definitions */
> +#define MAC_MAX_FRAME_SZ	(2048)
> +
> +struct dmamacdescr {
> +	u32 txrx_status;
> +	u32 dmamac_cntl;
> +	void *dmamac_addr;
> +	struct dmamacdescr *dmamac_next;
> +};
> +
> +/*
> + * txrx_status definitions
> + */
> +
> +/* tx status bits definitions */
> +#if defined(CONFIG_DW_ALTDESC)
> +
> +#define DESC_TXSTS_OWNBYDMA		(1<<  31)
> +#define DESC_TXSTS_TXINT		(1<<  30)
> +#define DESC_TXSTS_TXLAST		(1<<  29)
> +#define DESC_TXSTS_TXFIRST		(1<<  28)
> +#define DESC_TXSTS_TXCRCDIS		(1<<  27)
> +
> +#define DESC_TXSTS_TXPADDIS		(1<<  26)
> +#define DESC_TXSTS_TXCHECKINSCTRL	(3<<  22)
> +#define DESC_TXSTS_TXRINGEND		(1<<  21)
> +#define DESC_TXSTS_TXCHAIN		(1<<  20)
> +#define DESC_TXSTS_MSK			(0x1FFFF<<  0)
> +
> +#else
> +
> +#define DESC_TXSTS_OWNBYDMA		(1<<  31)
> +#define DESC_TXSTS_MSK			(0x1FFFF<<  0)
> +
> +#endif
> +
> +/* rx status bits definitions */
> +#define DESC_RXSTS_OWNBYDMA		(1<<  31)
> +#define DESC_RXSTS_DAFILTERFAIL		(1<<  30)
> +#define DESC_RXSTS_FRMLENMSK		(0x3FFF<<  16)
> +#define DESC_RXSTS_FRMLENSHFT		(16)
> +
> +#define DESC_RXSTS_ERROR		(1<<  15)
> +#define DESC_RXSTS_RXTRUNCATED		(1<<  14)
> +#define DESC_RXSTS_SAFILTERFAIL		(1<<  13)
> +#define DESC_RXSTS_RXIPC_GIANTFRAME	(1<<  12)
> +#define DESC_RXSTS_RXDAMAGED		(1<<  11)
> +#define DESC_RXSTS_RXVLANTAG		(1<<  10)
> +#define DESC_RXSTS_RXFIRST		(1<<  9)
> +#define DESC_RXSTS_RXLAST		(1<<  8)
> +#define DESC_RXSTS_RXIPC_GIANT		(1<<  7)
> +#define DESC_RXSTS_RXCOLLISION		(1<<  6)
> +#define DESC_RXSTS_RXFRAMEETHER		(1<<  5)
> +#define DESC_RXSTS_RXWATCHDOG		(1<<  4)
> +#define DESC_RXSTS_RXMIIERROR		(1<<  3)
> +#define DESC_RXSTS_RXDRIBBLING		(1<<  2)
> +#define DESC_RXSTS_RXCRC		(1<<  1)
> +
> +/*
> + * dmamac_cntl definitions
> + */
> +
> +/* tx control bits definitions */
> +#if defined(CONFIG_DW_ALTDESC)
> +
> +#define DESC_TXCTRL_SIZE1MASK		(0x1FFF<<  0)
> +#define DESC_TXCTRL_SIZE1SHFT		(0)
> +#define DESC_TXCTRL_SIZE2MASK		(0x1FFF<<  16)
> +#define DESC_TXCTRL_SIZE2SHFT		(16)
> +
> +#else
> +
> +#define DESC_TXCTRL_TXINT		(1<<  31)
> +#define DESC_TXCTRL_TXLAST		(1<<  30)
> +#define DESC_TXCTRL_TXFIRST		(1<<  29)
> +#define DESC_TXCTRL_TXCHECKINSCTRL	(3<<  27)
> +#define DESC_TXCTRL_TXCRCDIS		(1<<  26)
> +#define DESC_TXCTRL_TXRINGEND		(1<<  25)
> +#define DESC_TXCTRL_TXCHAIN		(1<<  24)
> +
> +#define DESC_TXCTRL_SIZE1MASK		(0x7FF<<  0)
> +#define DESC_TXCTRL_SIZE1SHFT		(0)
> +#define DESC_TXCTRL_SIZE2MASK		(0x7FF<<  11)
> +#define DESC_TXCTRL_SIZE2SHFT		(11)
> +
> +#endif
> +
> +/* rx control bits definitions */
> +#if defined(CONFIG_DW_ALTDESC)
> +
> +#define DESC_RXCTRL_RXINTDIS		(1<<  31)
> +#define DESC_RXCTRL_RXRINGEND		(1<<  15)
> +#define DESC_RXCTRL_RXCHAIN		(1<<  14)
> +
> +#define DESC_RXCTRL_SIZE1MASK		(0x1FFF<<  0)
> +#define DESC_RXCTRL_SIZE1SHFT		(0)
> +#define DESC_RXCTRL_SIZE2MASK		(0x1FFF<<  16)
> +#define DESC_RXCTRL_SIZE2SHFT		(16)
> +
> +#else
> +
> +#define DESC_RXCTRL_RXINTDIS		(1<<  31)
> +#define DESC_RXCTRL_RXRINGEND		(1<<  25)
> +#define DESC_RXCTRL_RXCHAIN		(1<<  24)
> +
> +#define DESC_RXCTRL_SIZE1MASK		(0x7FF<<  0)
> +#define DESC_RXCTRL_SIZE1SHFT		(0)
> +#define DESC_RXCTRL_SIZE2MASK		(0x7FF<<  11)
> +#define DESC_RXCTRL_SIZE2SHFT		(11)
> +
> +#endif
> +
> +/*
> + * dmamac_addr definitions
> + */
> +
> +/* tx addr register bits definitions */
> +
> +/* rx addr register bits definitions */
> +
>    
Something's missing here...
> +
> +/*
> + * dmamac_next definitions
> + */
> +
> +/* tx next register bits definitions */
> +
> +/* rx next register bits definitions */
> +
> +struct dw_eth_dev {
> +	u32 address;
> +	u32 speed;
> +	u32 duplex;
> +	u32 tx_currdescnum;
> +	u32 rx_currdescnum;
> +	u32 padding;
> +
> +	struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
> +	struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM];
> +
> +	char txbuffs[TX_TOTAL_BUFSIZE];
> +	char rxbuffs[RX_TOTAL_BUFSIZE];
> +
> +	struct eth_mac_regs *mac_regs_p;
> +	struct eth_dma_regs *dma_regs_p;
> +
> +	struct eth_device *dev;
> +} __attribute__ ((aligned(8)));
> +
> +/* Speed specific definitions */
> +#define SPEED_10M		1
> +#define SPEED_100M		2
> +#define SPEED_1000M		3
> +
> +/* Duplex mode specific definitions */
> +#define HALF_DUPLEX		1
> +#define FULL_DUPLEX		2
> +
> +#endif
> diff --git a/include/netdev.h b/include/netdev.h
> index 1dd80f0..460889c 100644
> --- a/include/netdev.h
> +++ b/include/netdev.h
> @@ -79,6 +79,7 @@ int scc_initialize(bd_t *bis);
>   int skge_initialize(bd_t *bis);
>   int smc911x_initialize(u8 dev_num, int base_addr);
>   int smc91111_initialize(u8 dev_num, int base_addr);
> +int dw_mii_initialize(u32 id, ulong base_addr);
>    
alphabetical order, please.
>   int tsi108_eth_initialize(bd_t *bis);
>   int uec_initialize(int index);
>   int uec_standard_init(bd_t *bis);
>    

Overall, a very good first pass.

thanks,
Ben

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

* [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c
  2010-04-21 12:11                         ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Peter Tyser
@ 2010-04-22  4:07                           ` Vipin KUMAR
  0 siblings, 0 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-22  4:07 UTC (permalink / raw)
  To: u-boot

On 4/21/2010 5:41 PM, Peter Tyser wrote:
> Hi Vipin,
> 
> On Wed, 2010-04-21 at 13:24 +0530, Vipin KUMAR wrote:
>> The i2c IP used by spear platform is a synopsys i2c controller
>> The earlier driver adds the driver of this controller as if it is
>> specific to
>> spear platform.
>> The driver files are now moved into drivers/i2c folder for reusability
>> by other
>> platforms
>>
>> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
>> ---
>>  arch/arm/include/asm/arch-spear/spr_i2c.h |  146 -------------
>>  drivers/i2c/Makefile                      |    2 +-
>>  drivers/i2c/dw_i2c.c                      |  331
>> +++++++++++++++++++++++++++++
> 
> I'd similarly lean towards naming the new file designware.c, or
> synopsis.c.  It looks like the rest of the i2c drivers use a _i2c
> suffix, so I guess designware_i2c.c or synopsis_i2c.c would be best for
> consistency's sake.  At a minimum it'd be nice to mention in the
> dw_i2c.c file what silicon the driver supports as right now a user needs
> to guess what "dw_i2c.c" runs on based solely on "dw".
> 

OK, that's a good suggestion. I would change the name to
designware_i2c.c and also include a little description about the 
manufacturer in the source header

> When you create patches with git format-patch, its nice to use the -M
> and -C to detect renames/copies.  It makes the patch much smaller and
> much easier to review what actually changed.
> 
OK, I would generate the patch v2 with these options enabled
Thanks for suggesting. 
Please find the changes in next version patch-set

> Best,
> Peter
> 
> 

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

* [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface
  2010-04-21 17:02                       ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Scott Wood
@ 2010-04-22  4:21                         ` Vipin KUMAR
  2010-04-22 15:39                           ` Scott Wood
  0 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-22  4:21 UTC (permalink / raw)
  To: u-boot

On 4/21/2010 10:32 PM, Scott Wood wrote:
> On Wed, Apr 21, 2010 at 01:24:37PM +0530, Vipin KUMAR wrote:
>> diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c
>> index 1207709..3ac62d1 100644
>> --- a/board/spear/spear310/spear310.c
>> +++ b/board/spear/spear310/spear310.c
>> @@ -29,7 +29,8 @@
>>  #include <asm/arch/hardware.h>
>>  #include <asm/arch/spr_defs.h>
>>  #include <asm/arch/spr_misc.h>
>> -#include <asm/arch/spr_nand.h>
>> +
>> +int fsmc_nand_init(struct nand_chip *nand);
> 
> Put it in a header file.
> 

Should I put it in a platform specific header file. That's where I was
confused

> -Scott
> 

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

* [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added
  2010-04-21 17:02                     ` [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added Scott Wood
@ 2010-04-22  4:28                       ` Vipin KUMAR
  2010-04-22 16:01                         ` Scott Wood
  0 siblings, 1 reply; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-22  4:28 UTC (permalink / raw)
  To: u-boot

On 4/21/2010 10:32 PM, Scott Wood wrote:
> On Wed, Apr 21, 2010 at 01:24:36PM +0530, Vipin KUMAR wrote:
>> +#if defined(CONFIG_BOARD_NAND_LP)
> 
> CONFIG_SYS_FSMC_NAND_LP, CONFIG_SYS_FSMC_NAND_16BIT, etc.

Incomplete comment :)
Are these deprecated

>> +			/*
>> +			 * length is intentionally kept a higher multiple of 2
>> +			 * to read at least 13 bytes even in case of 16 bit NAND
>> +			 * devices
>> +			 */
>> +			len = ((len + 1) >> 1) << 1;
> 
> len = roundup(len, 2);
> 

OK, I would change that.
Please find the changes in patch-set v2

>> +	fsmc_version = (peripid2 >> FSMC_REVISION_SHFT) & \
>> +		       FSMC_REVISION_MSK;
> 
> Unnecessary backslash.
> 
Would be removed

>> +#ifndef __FSMC_NAND_H__
>> +#define __FSMC_NAND_H__
>> +
>> +struct fsmc_regs {
>> +	u8 reserved_1[0x40];
>> +	u32 genmemctrl_pc;		/* 0x40 */
>> +	u32 genmemctrl_sts;		/* 0x44 */
>> +	u32 genmemctrl_comm;		/* 0x48 */
>> +	u32 genmemctrl_attrib;		/* 0x4c */
>> +	u32 genmemctrl_ioata;		/* 0x50 */
>> +	u32 genmemctrl_ecc1;		/* 0x54 */
>> +	u32 genmemctrl_ecc2;		/* 0x58 */
>> +	u32 genmemctrl_ecc3;		/* 0x5c */
>> +	u8 reserved_2[0xfe0 - 0x60];
>> +	u32 genmemctrl_peripid0;	/* 0xfe0 */
>> +	u32 genmemctrl_peripid1;	/* 0xfe4 */
>> +	u32 genmemctrl_peripid2;	/* 0xfe8 */
>> +	u32 genmemctrl_peripid3;	/* 0xfec */
>> +	u32 genmemctrl_pcellid0;	/* 0xff0 */
>> +	u32 genmemctrl_pcellid1;	/* 0xff4 */
>> +	u32 genmemctrl_pcellid2;	/* 0xff8 */
>> +	u32 genmemctrl_pcellid3;	/* 0xffc */
>> +};
> 
> Is the genmemctrl_ prefix really needed?
> 

The peripheral's registers are named like these so I kept it.

>> +extern int spear_nand_init(struct nand_chip *nand);
> 
> fsmc_nand_init?
> 
Yes, I would change this
Thanks

> -Scott
> 

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

* [U-Boot] [PATCH 07/17] SPEAr : Network driver support added
  2010-04-21 12:00               ` [U-Boot] [PATCH 07/17] SPEAr : Network " Peter Tyser
@ 2010-04-22  4:30                 ` Vipin KUMAR
  0 siblings, 0 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-22  4:30 UTC (permalink / raw)
  To: u-boot

On 4/21/2010 5:30 PM, Peter Tyser wrote:
> Hi Vipin,
> 
>>  drivers/net/dw_eth.c |  504 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>  drivers/net/dw_eth.h |  281 ++++++++++++++++++++++++++++
> 
> I'd vote to name the driver "designware.c", or something else more
> descriptive than the somewhat ambiguous "dw".  The _eth portion of the
> name isn't necessary either since its contained in the driver/net
> directory.
> 

OK, I would change the name to designware.c and header as designware.h
Please find the changes in patch-set v2

> Best,
> Peter
> 
> 

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

* [U-Boot] [PATCH 07/17] SPEAr : Network driver support added
  2010-04-21 17:48               ` Ben Warren
@ 2010-04-22  4:43                 ` Vipin KUMAR
  2010-04-23 10:32                 ` Armando VISCONTI
  1 sibling, 0 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-22  4:43 UTC (permalink / raw)
  To: u-boot

On 4/21/2010 11:18 PM, Ben Warren wrote:
> Hi Vipin,
> 
> On 4/21/2010 12:54 AM, Vipin KUMAR wrote:
>> Designware network driver support added.
>> This is a Synopsys ethernet controller
>>
>> Signed-off-by: Vipin Kumar<vipin.kumar@st.com>
>> ---
>>   drivers/net/Makefile |    1 +
>>   drivers/net/dw_eth.c |  504
>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>   drivers/net/dw_eth.h |  281 ++++++++++++++++++++++++++++
>>    
> I agree with Peter that a different name would be preferable.  Something
> conveying the manufacturer or, if it's a very specific controller, the
> part number.  Give thought to whether it will potentially be expanded up
> or generic-ized in the future (I know that's hard to do!)

I am planning to change the name to designware.c and designware.h

>>   include/netdev.h     |    1 +
>>   4 files changed, 787 insertions(+), 0 deletions(-)
>>   create mode 100755 drivers/net/dw_eth.c
>>   create mode 100644 drivers/net/dw_eth.h
>>
>> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
>> index 1ec0ba1..d03c353 100644
>> --- a/drivers/net/Makefile
>> +++ b/drivers/net/Makefile
>> @@ -68,6 +68,7 @@ COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o
>>   COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
>>   COBJS-$(CONFIG_SMC91111) += smc91111.o
>>   COBJS-$(CONFIG_SMC911X) += smc911x.o
>> +COBJS-$(CONFIG_DW_ETH) += dw_eth.o
>>   COBJS-$(CONFIG_TIGON3) += tigon3.o bcm570x_autoneg.o 5701rls.o
>>   COBJS-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
>>   COBJS-$(CONFIG_TSEC_ENET) += tsec.o
>>    
> Alphabetical order, please

Ah, sure

>> diff --git a/drivers/net/dw_eth.c b/drivers/net/dw_eth.c
>> new file mode 100755
>> index 0000000..52e7d15
>> --- /dev/null
>> +++ b/drivers/net/dw_eth.c
>> @@ -0,0 +1,504 @@
>> +/*
>> + * (C) Copyright 2009
>> + * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
>> + *
>> + * (C) Copyright 2008
>> + * Deepak Sikri, ST Micoelectronics, deepak.sikri at st.com.
>> + *
>> + * See file CREDITS for list of people who contributed to this
>> + * project.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>> + * MA 02111-1307 USA
>> + */
>> +
>> +/*
>> + * Designware ethernet IP driver for u-boot
>> + */
>> +
>> +#include<common.h>
>> +#include<miiphy.h>
>> +#include<malloc.h>
>> +#include<linux/err.h>
>> +#include<asm/io.h>
>> +#include "dw_eth.h"
>> +
>> +static void tx_descs_init(struct eth_device *dev)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +    struct eth_dma_regs *dma_p = priv->dma_regs_p;
>> +    struct dmamacdescr *desc_table_p =&priv->tx_mac_descrtable[0];
>> +    char *txbuffs =&priv->txbuffs[0];
>> +    struct dmamacdescr *desc_p;
>> +
>> +    u32 idx;
>> +
>> +    for (idx = 0; idx<  CONFIG_TX_DESCR_NUM; idx++) {
>> +
>> +        desc_p =&desc_table_p[idx];
>> +        desc_p->dmamac_addr =&txbuffs[idx * CONFIG_ETH_BUFSIZE];
>> +        desc_p->dmamac_next =&desc_table_p[idx + 1];
>> +
>> +#if defined(CONFIG_DW_ALTDESC)
>>    
> Please use a more descriptive CONFIG option. Remember these have global
> namespace

Hmmm, actually the peripheral supports two kinds of descriptors
Normal and Alternate/Enhanced (as they call it)
Should I put this option as CONFIG_DW_ALTDESCRIPTOR ?

>> +        desc_p->txrx_status&= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
>> +                DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
>> +                DESC_TXSTS_TXCHECKINSCTRL | \
>> +                DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
>> +
>> +        desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
>> +        desc_p->dmamac_cntl = 0;
>> +        desc_p->txrx_status&= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
>> +#else
>> +        desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
>> +        desc_p->txrx_status = 0;
>> +#endif
>> +    }
>> +
>> +    /* Correcting the last pointer of the chain */
>> +    desc_p->dmamac_next =&desc_table_p[0];
>> +
>> +    writel((ulong)&desc_table_p[0],&dma_p->txdesclistaddr);
>> +}
>> +
>> +static void rx_descs_init(struct eth_device *dev)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +    struct eth_dma_regs *dma_p = priv->dma_regs_p;
>> +    struct dmamacdescr *desc_table_p =&priv->rx_mac_descrtable[0];
>> +    char *rxbuffs =&priv->rxbuffs[0];
>> +    struct dmamacdescr *desc_p;
>> +
>> +    u32 idx;
>> +
>> +    for (idx = 0; idx<  CONFIG_RX_DESCR_NUM; idx++) {
>> +
>>    
> Remove unnecessary blank lines

OK. would be done in patch-set v2

>> +        desc_p =&desc_table_p[idx];
>> +        desc_p->dmamac_addr =&rxbuffs[idx * CONFIG_ETH_BUFSIZE];
>> +        desc_p->dmamac_next =&desc_table_p[idx + 1];
>> +
>> +        desc_p->dmamac_cntl =
>> +            (MAC_MAX_FRAME_SZ&  DESC_RXCTRL_SIZE1MASK) | \
>> +                      DESC_RXCTRL_RXCHAIN;
>> +
>> +        desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
>> +    }
>> +
>> +    /* Correcting the last pointer of the chain */
>> +    desc_p->dmamac_next =&desc_table_p[0];
>> +
>> +    writel((ulong)&desc_table_p[0],&dma_p->rxdesclistaddr);
>> +}
>> +
>> +static void descs_init(struct eth_device *dev)
>> +{
>> +    tx_descs_init(dev);
>> +    rx_descs_init(dev);
>> +}
>> +
>> +static void mac_reset(struct eth_device *dev)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +    struct eth_mac_regs *mac_p = priv->mac_regs_p;
>> +    struct eth_dma_regs *dma_p = priv->dma_regs_p;
>> +
>> +    u32 timeout = CONFIG_MACRESET_TIMEOUT;
>> +
>> +    writel(DMAMAC_SRST,&dma_p->busmode);
>> +    writel(MII_PORTSELECT,&mac_p->conf);
>> +
>> +    do {
>> +        if (!(readl(&dma_p->busmode)&  DMAMAC_SRST))
>> +            break;
>> +        udelay(1000);
>> +    } while (timeout--);
>> +}
>> +
>> +static int dw_eth_init(struct eth_device *dev, bd_t *bis)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +    struct eth_mac_regs *mac_p = priv->mac_regs_p;
>> +    struct eth_dma_regs *dma_p = priv->dma_regs_p;
>> +
>> +    u8 *mac_id =&dev->enetaddr[0];
>> +    u32 conf, macid_lo, macid_hi;
>> +
>> +    /* Reset ethernet hardware */
>> +    mac_reset(dev);
>> +
>> +    macid_lo = mac_id[0] + (mac_id[1]<<  8) + \
>> +           (mac_id[2]<<  16) + (mac_id[3]<<  24);
>> +    macid_hi = mac_id[4] + (mac_id[5]<<  8);
>> +
>> +    writel(macid_hi,&mac_p->macaddr0hi);
>> +    writel(macid_lo,&mac_p->macaddr0lo);
>> +
>>    
> Please provide a static function with signature 'static void
> program_mac(struct eth_device *)' for programming the MAC.

Sure
Would be done in v2

>> +    writel(FIXEDBURST | PRIORXTX_41 | BURST_16,
>> +            &dma_p->busmode);
>> +
>> +    writel(FLUSHTXFIFO | readl(&dma_p->opmode),&dma_p->opmode);
>> +    writel(STOREFORWARD | TXSECONDFRAME,&dma_p->opmode);
>> +
>> +    conf = FRAMEBURSTENABLE | DISABLERXOWN;
>> +
>> +    if (priv->speed != SPEED_1000M)
>> +        conf |= MII_PORTSELECT;
>> +
>> +    if (priv->duplex == FULL_DUPLEX)
>> +        conf |= FULLDPLXMODE;
>> +
>> +    writel(conf,&mac_p->conf);
>> +
>> +    descs_init(dev);
>> +
>> +    /*
>> +     * Start/Enable xfer at dma as well as mac level
>> +     */
>> +    writel(readl(&dma_p->opmode) | RXSTART,&dma_p->opmode);
>> +    writel(readl(&dma_p->opmode) | TXSTART,&dma_p->opmode);
>> +
>> +    writel(readl(&mac_p->conf) | RXENABLE,&mac_p->conf);
>> +    writel(readl(&mac_p->conf) | TXENABLE,&mac_p->conf);
>> +
>> +    return 0;
>> +}
>> +
>> +static int dw_eth_send(struct eth_device *dev, volatile void *packet,
>> +        int length)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +    struct eth_dma_regs *dma_p = priv->dma_regs_p;
>> +    u32 desc_num = priv->tx_currdescnum;
>> +    struct dmamacdescr *desc_p =&priv->tx_mac_descrtable[desc_num];
>> +
>> +    /* Check if the descriptor is owned by CPU */
>> +    if (desc_p->txrx_status&  DESC_TXSTS_OWNBYDMA) {
>> +        printf("eth_send : CPU not owner of tx frame\n");
>> +        return -1;
>> +    }
>> +
>> +    memcpy((void *)desc_p->dmamac_addr, (void *)packet, length);
>> +
>> +#if defined(CONFIG_DW_ALTDESC)
>> +    desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
>> +    desc_p->dmamac_cntl |= (length<<  DESC_TXCTRL_SIZE1SHFT)&  \
>> +                   DESC_TXCTRL_SIZE1MASK;
>> +
>> +    desc_p->txrx_status&= ~(DESC_TXSTS_MSK);
>> +    desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
>> +#else
>> +    desc_p->dmamac_cntl |= ((length<<  DESC_TXCTRL_SIZE1SHFT)&  \
>> +                   DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \
>> +                   DESC_TXCTRL_TXFIRST;
>> +
>> +    desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
>> +#endif
>> +
>> +    /* Test the wrap-around condition. */
>> +    if (++desc_num>= CONFIG_TX_DESCR_NUM)
>> +        desc_num = 0;
>> +
>> +    priv->tx_currdescnum = desc_num;
>> +
>> +    /* Start the transmission */
>> +    writel(POLL_DATA,&dma_p->txpolldemand);
>> +
>> +    return 0;
>> +}
>> +
>> +static int dw_eth_recv(struct eth_device *dev)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +    u32 desc_num = priv->rx_currdescnum;
>> +    struct dmamacdescr *desc_p =&priv->rx_mac_descrtable[desc_num];
>> +
>> +    u32 status = desc_p->txrx_status;
>> +    int length = 0;
>> +
>> +    /* Check  if the owner is the CPU */
>> +    if (!(status&  DESC_RXSTS_OWNBYDMA)) {
>> +
>> +        length = (status&  DESC_RXSTS_FRMLENMSK)>>  \
>> +             DESC_RXSTS_FRMLENSHFT;
>> +
>> +        NetReceive(desc_p->dmamac_addr, length);
>> +
>> +        /*
>> +         * Make the current descriptor valid again and go to
>> +         * the next one
>> +         */
>> +        desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
>> +
>> +        /* Test the wrap-around condition. */
>> +        if (++desc_num>= CONFIG_RX_DESCR_NUM)
>> +            desc_num = 0;
>> +    }
>> +
>> +    priv->rx_currdescnum = desc_num;
>> +
>> +    return length;
>> +}
>> +
>> +static void dw_eth_halt(struct eth_device *dev)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +
>> +    mac_reset(dev);
>> +    priv->tx_currdescnum = priv->rx_currdescnum = 0;
>> +}
>> +
>> +static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16
>> *val)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +    struct eth_mac_regs *mac_p = priv->mac_regs_p;
>> +    u32 miiaddr;
>> +    u32 timeout = CONFIG_MDIO_TIMEOUT;
>> +
>> +    miiaddr = ((addr<<  MIIADDRSHIFT)&  MII_ADDRMSK) | \
>> +          ((reg<<  MIIREGSHIFT)&  MII_REGMSK);
>> +
>> +    writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY,&mac_p->miiaddr);
>> +
>> +    do {
>> +        if (!(readl(&mac_p->miiaddr)&  MII_BUSY))
>> +            break;
>> +        udelay(1000);
>> +    } while (timeout--);
>> +
>> +    *val = readl(&mac_p->miidata);
>> +
>> +    return 0;
>> +}
>> +
>> +static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg,
>> u16 val)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +    struct eth_mac_regs *mac_p = priv->mac_regs_p;
>> +    u32 miiaddr;
>> +    u32 timeout = CONFIG_MDIO_TIMEOUT;
>> +    u16 value;
>> +
>> +    writel(val,&mac_p->miidata);
>> +    miiaddr = ((addr<<  MIIADDRSHIFT)&  MII_ADDRMSK) | \
>> +          ((reg<<  MIIREGSHIFT)&  MII_REGMSK) | MII_WRITE;
>> +
>> +    writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY,&mac_p->miiaddr);
>> +
>> +    do {
>> +        if (!(readl(&mac_p->miiaddr)&  MII_BUSY))
>> +            break;
>> +        udelay(1000);
>> +    } while (timeout--);
>> +
>> +    /* Needed as a fix for ST-Phy */
>> +    eth_mdio_read(dev, addr, reg,&value);
>> +
>> +    return 0;
>> +}
>> +
>> +static u8 find_phy(struct eth_device *dev)
>> +{
>> +    u8 phy_addr = 0;
>> +    u16 ctrl, oldctrl;
>> +
>> +    do {
>> +        eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
>> +        oldctrl = ctrl&  PHY_BMCR_AUTON;
>> +
>> +        ctrl ^= PHY_BMCR_AUTON;
>> +        eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
>> +        eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
>> +        ctrl&= PHY_BMCR_AUTON;
>> +
>> +        if (ctrl == oldctrl) {
>> +            phy_addr++;
>> +        } else {
>> +            ctrl ^= PHY_BMCR_AUTON;
>> +            eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
>> +            break;
>> +        }
>> +    } while (phy_addr<  32);
>> +
>> +    return phy_addr;
>> +}
>> +
>> +static void dw_reset_phy(struct eth_device *dev)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +    u16 ctrl;
>> +    u32 timeout = CONFIG_PHYRESET_TIMEOUT;
>> +    u32 phy_addr = priv->address;
>> +
>> +    eth_mdio_write(dev, phy_addr, PHY_BMCR, PHY_BMCR_RESET);
>> +    do {
>> +        eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
>> +        if (!(ctrl&  PHY_BMCR_RESET))
>> +            break;
>> +        udelay(1000);
>> +    } while (timeout--);
>> +
>> +#ifdef CONFIG_PHY_RESET_DELAY
>> +    udelay(CONFIG_PHY_RESET_DELAY);
>> +#endif
>> +}
>> +
>> +static void configure_phy(struct eth_device *dev)
>> +{
>> +    struct dw_eth_dev *priv = dev->priv;
>> +    u8 phy_addr;
>> +    u16 bmcr, ctrl;
>> +#if defined(CONFIG_DW_AUTONEG)
>> +    u16 bmsr;
>> +    u32 timeout;
>> +    u16 anlpar, btsr;
>> +#endif
>> +    priv->address = find_phy(dev);
>> +    phy_addr = priv->address;
>> +
>> +    dw_reset_phy(dev);
>> +
>> +#if defined(CONFIG_DW_AUTONEG)
>> +    bmcr = PHY_BMCR_AUTON | PHY_BMCR_RST_NEG | PHY_BMCR_100MB | \
>> +           PHY_BMCR_DPLX | PHY_BMCR_1000_MBPS;
>> +#else
>> +    bmcr = PHY_BMCR_100MB | PHY_BMCR_DPLX;
>> +
>> +#if defined(CONFIG_DW_SPEED10M)
>> +    bmcr&= ~PHY_BMCR_100MB;
>> +#endif
>> +#if defined(CONFIG_DW_DUPLEXHALF)
>> +    bmcr&= ~PHY_BMCR_DPLX;
>> +#endif
>> +#endif
>> +    eth_mdio_write(dev, phy_addr, PHY_BMCR, bmcr);
>> +
>> +    /* Read the phy status register and populate priv structure */
>> +#if defined(CONFIG_DW_AUTONEG)
>> +    timeout = CONFIG_AUTONEG_TIMEOUT;
>> +    do {
>> +        eth_mdio_read(dev, phy_addr, PHY_BMSR,&bmsr);
>> +        if (bmsr&  PHY_BMSR_AUTN_COMP)
>> +            break;
>> +        udelay(1000);
>> +    } while (timeout--);
>> +
>> +    eth_mdio_read(dev, phy_addr, PHY_ANLPAR,&anlpar);
>> +    eth_mdio_read(dev, phy_addr, PHY_1000BTSR,&btsr);
>> +
>> +    if (btsr&  (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
>> +        priv->speed = SPEED_1000M;
>> +        if (btsr&  PHY_1000BTSR_1000FD)
>> +            priv->duplex = FULL_DUPLEX;
>> +        else
>> +            priv->duplex = HALF_DUPLEX;
>> +    } else {
>> +        if (anlpar&  PHY_ANLPAR_100)
>> +            priv->speed = SPEED_100M;
>> +        else
>> +            priv->speed = SPEED_10M;
>> +
>> +        if (anlpar&  (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD))
>> +            priv->duplex = FULL_DUPLEX;
>> +        else
>> +            priv->duplex = HALF_DUPLEX;
>> +    }
>> +#else
>> +    eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
>> +
>> +    if (ctrl&  PHY_BMCR_DPLX)
>> +        priv->duplex = FULL_DUPLEX;
>> +    else
>> +        priv->duplex = HALF_DUPLEX;
>> +
>> +    if (ctrl&  PHY_BMCR_1000_MBPS)
>> +        priv->speed = SPEED_1000M;
>> +    else if (ctrl&  PHY_BMCR_100_MBPS)
>> +        priv->speed = SPEED_100M;
>> +    else
>> +        priv->speed = SPEED_10M;
>> +#endif
>> +}
>> +
>> +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
>> +static int dw_mii_read(char *devname, u8 addr, u8 reg, u16 *val)
>> +{
>> +    struct eth_device *netdev;
>> +
>> +    netdev = eth_get_dev_by_name(devname);
>> +    if (netdev)
>> +        eth_mdio_read(netdev, addr, reg, val);
>> +
>> +    return 0;
>> +}
>> +
>> +static int dw_mii_write(char *devname, u8 addr, u8 reg, u16 val)
>> +{
>> +    struct eth_device *netdev;
>> +
>> +    netdev = eth_get_dev_by_name(devname);
>> +    if (netdev)
>> +        eth_mdio_write(netdev, addr, reg, val);
>> +
>> +    return 0;
>> +}
>> +#endif
>> +
>> +int dw_mii_initialize(u32 id, ulong base_addr)
>>    
> Please use the same name in this function as the driver name.  We
> usually reserve 'mii' for device control plane.

OK. I would change that to dw_initialize

>> +{
>> +    struct eth_device *netdev;
>>    
> I'd prefer if you named this variable 'dev', since 'netdev' is the name
> of a header file that's unrelated.  Apply globally.

OK. I would change that to dev

>> +    struct dw_eth_dev *priv;
>> +
>> +    netdev = (struct eth_device *) malloc(sizeof(struct eth_device));
>> +    if (!netdev)
>> +        return -ENOMEM;
>> +
>> +    /*
>> +     * Since the priv structure contains the descriptors which need a
>> strict
>> +     * buswidth alignment, memalign is used to allocate memory
>> +     */
>> +    priv = (struct dw_eth_dev *) memalign(16, sizeof(struct
>> dw_eth_dev));
>> +    if (!priv) {
>> +        free(netdev);
>> +        return -ENOMEM;
>> +    }
>> +
>> +    memset(netdev, 0, sizeof(struct eth_device));
>> +    memset(priv, 0, sizeof(struct dw_eth_dev));
>> +
>> +    sprintf(netdev->name, "mii%d", id);
>> +    netdev->iobase = (int)base_addr;
>> +    netdev->priv = priv;
>>    
> If you wait a couple of days until I resubmit my change to the
> 'eth_device' struct, you can put in a pointer to the MAC programming
> function and not have to worry about that any more.

Sure, I would wait rebase over that patch and submit my patch v2

>> +
>> +    eth_getenv_enetaddr_by_index(id,&netdev->enetaddr[0]);
>> +
>> +    priv->dev = netdev;
>> +    priv->mac_regs_p = (struct eth_mac_regs *)base_addr;
>> +    priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
>> +            DW_DMA_BASE_OFFSET);
>> +
>> +    mac_reset(netdev);
>> +    configure_phy(netdev);
>> +
>> +    netdev->init = dw_eth_init;
>> +    netdev->send = dw_eth_send;
>> +    netdev->recv = dw_eth_recv;
>> +    netdev->halt = dw_eth_halt;
>> +
>> +    eth_register(netdev);
>> +
>> +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
>> +    miiphy_register(netdev->name, dw_mii_read, dw_mii_write);
>> +#endif
>> +    return 0;
>>    
> This should return 1 on success.

Ah, OK
I would change that.

>> +}
>> diff --git a/drivers/net/dw_eth.h b/drivers/net/dw_eth.h
>> new file mode 100644
>> index 0000000..068211a
>> --- /dev/null
>> +++ b/drivers/net/dw_eth.h
>> @@ -0,0 +1,281 @@
>> +/*
>> + * (C) Copyright 2009
>> + * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
>> + *
>> + * See file CREDITS for list of people who contributed to this
>> + * project.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>> + * MA 02111-1307 USA
>> + */
>> +
>> +#ifndef _DW_ETH_H
>> +#define _DW_ETH_H
>> +
>> +#define CONFIG_TX_DESCR_NUM    16
>> +#define CONFIG_RX_DESCR_NUM    16
>> +#define CONFIG_ETH_BUFSIZE    2048
>> +#define TX_TOTAL_BUFSIZE    (CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
>> +#define RX_TOTAL_BUFSIZE    (CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
>> +
>> +#define CONFIG_MACRESET_TIMEOUT    (3 * CONFIG_SYS_HZ)
>> +#define CONFIG_MDIO_TIMEOUT    (3 * CONFIG_SYS_HZ)
>> +#define CONFIG_PHYRESET_TIMEOUT    (3 * CONFIG_SYS_HZ)
>> +#define CONFIG_AUTONEG_TIMEOUT    (5 * CONFIG_SYS_HZ)
>> +
>> +struct eth_mac_regs {
>> +    u32 conf;        /* 0x00 */
>> +    u32 framefilt;        /* 0x04 */
>> +    u32 hashtablehigh;    /* 0x08 */
>> +    u32 hashtablelow;    /* 0x0c */
>> +    u32 miiaddr;        /* 0x10 */
>> +    u32 miidata;        /* 0x14 */
>> +    u32 flowcontrol;    /* 0x18 */
>> +    u32 vlantag;        /* 0x1c */
>> +    u32 version;        /* 0x20 */
>> +    u8 reserved_1[0x38 - 0x24];
>> +    u32 intreg;        /* 0x38 */
>> +    u32 intmask;        /* 0x3c */
>> +    u32 macaddr0hi;        /* 0x40 */
>> +    u32 macaddr0lo;        /* 0x44 */
>> +};
>> +
>> +/* MAC configuration register definitions */
>> +#define FRAMEBURSTENABLE    (1<<  21)
>> +#define MII_PORTSELECT        (1<<  15)
>> +#define FES_100            (1<<  14)
>> +#define DISABLERXOWN        (1<<  13)
>> +#define FULLDPLXMODE        (1<<  11)
>> +#define RXENABLE        (1<<  2)
>> +#define TXENABLE        (1<<  3)
>> +
>> +/* MII address register definitions */
>> +#define MII_BUSY        (1<<  0)
>> +#define MII_WRITE        (1<<  1)
>> +#define MII_CLKRANGE_60_100M    (0)
>> +#define MII_CLKRANGE_100_150M    (0x4)
>> +#define MII_CLKRANGE_20_35M    (0x8)
>> +#define MII_CLKRANGE_35_60M    (0xC)
>> +#define MII_CLKRANGE_150_250M    (0x10)
>> +#define MII_CLKRANGE_250_300M    (0x14)
>> +
>> +#define MIIADDRSHIFT        (11)
>> +#define MIIREGSHIFT        (6)
>> +#define MII_REGMSK        (0x1F<<  6)
>> +#define MII_ADDRMSK        (0x1F<<  11)
>> +
>> +
>> +struct eth_dma_regs {
>> +    u32 busmode;        /* 0x00 */
>> +    u32 txpolldemand;    /* 0x04 */
>> +    u32 rxpolldemand;    /* 0x08 */
>> +    u32 rxdesclistaddr;    /* 0x0c */
>> +    u32 txdesclistaddr;    /* 0x10 */
>> +    u32 status;        /* 0x14 */
>> +    u32 opmode;        /* 0x18 */
>> +    u32 intenable;        /* 0x1c */
>> +    u8 reserved[0x48 - 0x20];
>> +    u32 currhosttxdesc;    /* 0x48 */
>> +    u32 currhostrxdesc;    /* 0x4c */
>> +    u32 currhosttxbuffaddr;    /* 0x50 */
>> +    u32 currhostrxbuffaddr;    /* 0x54 */
>> +};
>> +
>> +#define DW_DMA_BASE_OFFSET    (0x1000)
>> +
>> +/* Bus mode register definitions */
>> +#define FIXEDBURST        (1<<  16)
>> +#define PRIORXTX_41        (3<<  14)
>> +#define PRIORXTX_31        (2<<  14)
>> +#define PRIORXTX_21        (1<<  14)
>> +#define PRIORXTX_11        (0<<  14)
>> +#define BURST_1            (1<<  8)
>> +#define BURST_2            (2<<  8)
>> +#define BURST_4            (4<<  8)
>> +#define BURST_8            (8<<  8)
>> +#define BURST_16        (16<<  8)
>> +#define BURST_32        (32<<  8)
>> +#define RXHIGHPRIO        (1<<  1)
>> +#define DMAMAC_SRST        (1<<  0)
>> +
>> +/* Poll demand definitions */
>> +#define POLL_DATA        (0xFFFFFFFF)
>> +
>> +/* Operation mode definitions */
>> +#define STOREFORWARD        (1<<  21)
>> +#define FLUSHTXFIFO        (1<<  20)
>> +#define TXSTART            (1<<  13)
>> +#define TXSECONDFRAME        (1<<  2)
>> +#define RXSTART            (1<<  1)
>> +
>> +/* Descriptior related definitions */
>> +#define MAC_MAX_FRAME_SZ    (2048)
>> +
>> +struct dmamacdescr {
>> +    u32 txrx_status;
>> +    u32 dmamac_cntl;
>> +    void *dmamac_addr;
>> +    struct dmamacdescr *dmamac_next;
>> +};
>> +
>> +/*
>> + * txrx_status definitions
>> + */
>> +
>> +/* tx status bits definitions */
>> +#if defined(CONFIG_DW_ALTDESC)
>> +
>> +#define DESC_TXSTS_OWNBYDMA        (1<<  31)
>> +#define DESC_TXSTS_TXINT        (1<<  30)
>> +#define DESC_TXSTS_TXLAST        (1<<  29)
>> +#define DESC_TXSTS_TXFIRST        (1<<  28)
>> +#define DESC_TXSTS_TXCRCDIS        (1<<  27)
>> +
>> +#define DESC_TXSTS_TXPADDIS        (1<<  26)
>> +#define DESC_TXSTS_TXCHECKINSCTRL    (3<<  22)
>> +#define DESC_TXSTS_TXRINGEND        (1<<  21)
>> +#define DESC_TXSTS_TXCHAIN        (1<<  20)
>> +#define DESC_TXSTS_MSK            (0x1FFFF<<  0)
>> +
>> +#else
>> +
>> +#define DESC_TXSTS_OWNBYDMA        (1<<  31)
>> +#define DESC_TXSTS_MSK            (0x1FFFF<<  0)
>> +
>> +#endif
>> +
>> +/* rx status bits definitions */
>> +#define DESC_RXSTS_OWNBYDMA        (1<<  31)
>> +#define DESC_RXSTS_DAFILTERFAIL        (1<<  30)
>> +#define DESC_RXSTS_FRMLENMSK        (0x3FFF<<  16)
>> +#define DESC_RXSTS_FRMLENSHFT        (16)
>> +
>> +#define DESC_RXSTS_ERROR        (1<<  15)
>> +#define DESC_RXSTS_RXTRUNCATED        (1<<  14)
>> +#define DESC_RXSTS_SAFILTERFAIL        (1<<  13)
>> +#define DESC_RXSTS_RXIPC_GIANTFRAME    (1<<  12)
>> +#define DESC_RXSTS_RXDAMAGED        (1<<  11)
>> +#define DESC_RXSTS_RXVLANTAG        (1<<  10)
>> +#define DESC_RXSTS_RXFIRST        (1<<  9)
>> +#define DESC_RXSTS_RXLAST        (1<<  8)
>> +#define DESC_RXSTS_RXIPC_GIANT        (1<<  7)
>> +#define DESC_RXSTS_RXCOLLISION        (1<<  6)
>> +#define DESC_RXSTS_RXFRAMEETHER        (1<<  5)
>> +#define DESC_RXSTS_RXWATCHDOG        (1<<  4)
>> +#define DESC_RXSTS_RXMIIERROR        (1<<  3)
>> +#define DESC_RXSTS_RXDRIBBLING        (1<<  2)
>> +#define DESC_RXSTS_RXCRC        (1<<  1)
>> +
>> +/*
>> + * dmamac_cntl definitions
>> + */
>> +
>> +/* tx control bits definitions */
>> +#if defined(CONFIG_DW_ALTDESC)
>> +
>> +#define DESC_TXCTRL_SIZE1MASK        (0x1FFF<<  0)
>> +#define DESC_TXCTRL_SIZE1SHFT        (0)
>> +#define DESC_TXCTRL_SIZE2MASK        (0x1FFF<<  16)
>> +#define DESC_TXCTRL_SIZE2SHFT        (16)
>> +
>> +#else
>> +
>> +#define DESC_TXCTRL_TXINT        (1<<  31)
>> +#define DESC_TXCTRL_TXLAST        (1<<  30)
>> +#define DESC_TXCTRL_TXFIRST        (1<<  29)
>> +#define DESC_TXCTRL_TXCHECKINSCTRL    (3<<  27)
>> +#define DESC_TXCTRL_TXCRCDIS        (1<<  26)
>> +#define DESC_TXCTRL_TXRINGEND        (1<<  25)
>> +#define DESC_TXCTRL_TXCHAIN        (1<<  24)
>> +
>> +#define DESC_TXCTRL_SIZE1MASK        (0x7FF<<  0)
>> +#define DESC_TXCTRL_SIZE1SHFT        (0)
>> +#define DESC_TXCTRL_SIZE2MASK        (0x7FF<<  11)
>> +#define DESC_TXCTRL_SIZE2SHFT        (11)
>> +
>> +#endif
>> +
>> +/* rx control bits definitions */
>> +#if defined(CONFIG_DW_ALTDESC)
>> +
>> +#define DESC_RXCTRL_RXINTDIS        (1<<  31)
>> +#define DESC_RXCTRL_RXRINGEND        (1<<  15)
>> +#define DESC_RXCTRL_RXCHAIN        (1<<  14)
>> +
>> +#define DESC_RXCTRL_SIZE1MASK        (0x1FFF<<  0)
>> +#define DESC_RXCTRL_SIZE1SHFT        (0)
>> +#define DESC_RXCTRL_SIZE2MASK        (0x1FFF<<  16)
>> +#define DESC_RXCTRL_SIZE2SHFT        (16)
>> +
>> +#else
>> +
>> +#define DESC_RXCTRL_RXINTDIS        (1<<  31)
>> +#define DESC_RXCTRL_RXRINGEND        (1<<  25)
>> +#define DESC_RXCTRL_RXCHAIN        (1<<  24)
>> +
>> +#define DESC_RXCTRL_SIZE1MASK        (0x7FF<<  0)
>> +#define DESC_RXCTRL_SIZE1SHFT        (0)
>> +#define DESC_RXCTRL_SIZE2MASK        (0x7FF<<  11)
>> +#define DESC_RXCTRL_SIZE2SHFT        (11)
>> +
>> +#endif
>> +
>> +/*
>> + * dmamac_addr definitions
>> + */
>> +
>> +/* tx addr register bits definitions */
>> +
>> +/* rx addr register bits definitions */
>> +
>>    
> Something's missing here...

Actually no, these are the addresses part of the descriptors so any bit
doesn't have any special meaning.
Probably I can remove it altogather in v2

>> +
>> +/*
>> + * dmamac_next definitions
>> + */
>> +
>> +/* tx next register bits definitions */
>> +
>> +/* rx next register bits definitions */
>> +
>> +struct dw_eth_dev {
>> +    u32 address;
>> +    u32 speed;
>> +    u32 duplex;
>> +    u32 tx_currdescnum;
>> +    u32 rx_currdescnum;
>> +    u32 padding;
>> +
>> +    struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
>> +    struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM];
>> +
>> +    char txbuffs[TX_TOTAL_BUFSIZE];
>> +    char rxbuffs[RX_TOTAL_BUFSIZE];
>> +
>> +    struct eth_mac_regs *mac_regs_p;
>> +    struct eth_dma_regs *dma_regs_p;
>> +
>> +    struct eth_device *dev;
>> +} __attribute__ ((aligned(8)));
>> +
>> +/* Speed specific definitions */
>> +#define SPEED_10M        1
>> +#define SPEED_100M        2
>> +#define SPEED_1000M        3
>> +
>> +/* Duplex mode specific definitions */
>> +#define HALF_DUPLEX        1
>> +#define FULL_DUPLEX        2
>> +
>> +#endif
>> diff --git a/include/netdev.h b/include/netdev.h
>> index 1dd80f0..460889c 100644
>> --- a/include/netdev.h
>> +++ b/include/netdev.h
>> @@ -79,6 +79,7 @@ int scc_initialize(bd_t *bis);
>>   int skge_initialize(bd_t *bis);
>>   int smc911x_initialize(u8 dev_num, int base_addr);
>>   int smc91111_initialize(u8 dev_num, int base_addr);
>> +int dw_mii_initialize(u32 id, ulong base_addr);
>>    
> alphabetical order, please.

Sure

>>   int tsi108_eth_initialize(bd_t *bis);
>>   int uec_initialize(int index);
>>   int uec_standard_init(bd_t *bis);
>>    
> 
> Overall, a very good first pass.
> 
Thanks. So, I am just waiting for a patch submission from you over which
I would rebase and send my patch v2 incorporating all above changes

> thanks,
> Ben
> 
Regards,
Vipin

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

* [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs
  2010-04-21 11:51             ` [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs Peter Tyser
@ 2010-04-22  4:45               ` Vipin KUMAR
  0 siblings, 0 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-22  4:45 UTC (permalink / raw)
  To: u-boot

On 4/21/2010 5:21 PM, Peter Tyser wrote:
> Hi Vipin,
> 
> On Wed, 2010-04-21 at 13:24 +0530, Vipin KUMAR wrote:
>> Adding CONFIG_DISPLAY_CPUINFO and CONFIG_ARCH_CPU_INIT support for SPEAr3xx and
>> SPEAr6xx SoCs
>>
>> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
>> ---
>>  arch/arm/cpu/arm926ejs/spear/Makefile      |    3 +-
>>  arch/arm/include/asm/arch-spear/spr_misc.h |    5 ++
>>  cpu/arm926ejs/spear/cpu_info.c             |   76 ++++++++++++++++++++++++++++
> 
> The cpu path above needs to be adjusted to arch/arm/cpu/...
> 
Yes, I would do that in patch v2

> Also, cpu_info.c doesn't seem like the best filename.  You put both
> initialization code and informational code in it, so a more generic name
> such as "cpu.c" would be preferred.  Or possibly cpu.c and cpu_init.c.
> PowerPC boards would serve as a decent reference.
> 
Yes, I just thought about it sometime back and then forgot to change the
name. I would change the name to cpu.c

> Best,
> Peter
> 
Thanks
Vipin

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

* [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface
  2010-04-22  4:21                         ` Vipin KUMAR
@ 2010-04-22 15:39                           ` Scott Wood
  0 siblings, 0 replies; 38+ messages in thread
From: Scott Wood @ 2010-04-22 15:39 UTC (permalink / raw)
  To: u-boot

Vipin KUMAR wrote:
> On 4/21/2010 10:32 PM, Scott Wood wrote:
>> On Wed, Apr 21, 2010 at 01:24:37PM +0530, Vipin KUMAR wrote:
>>> diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c
>>> index 1207709..3ac62d1 100644
>>> --- a/board/spear/spear310/spear310.c
>>> +++ b/board/spear/spear310/spear310.c
>>> @@ -29,7 +29,8 @@
>>>  #include <asm/arch/hardware.h>
>>>  #include <asm/arch/spr_defs.h>
>>>  #include <asm/arch/spr_misc.h>
>>> -#include <asm/arch/spr_nand.h>
>>> +
>>> +int fsmc_nand_init(struct nand_chip *nand);
>> Put it in a header file.
>>
> 
> Should I put it in a platform specific header file. That's where I was
> confused

Put it in fsmc_nand.h, and move that file to an include directory.

-Scott

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

* [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added
  2010-04-22  4:28                       ` Vipin KUMAR
@ 2010-04-22 16:01                         ` Scott Wood
  0 siblings, 0 replies; 38+ messages in thread
From: Scott Wood @ 2010-04-22 16:01 UTC (permalink / raw)
  To: u-boot

Vipin KUMAR wrote:
> On 4/21/2010 10:32 PM, Scott Wood wrote:
>> On Wed, Apr 21, 2010 at 01:24:36PM +0530, Vipin KUMAR wrote:
>>> +#if defined(CONFIG_BOARD_NAND_LP)
>> CONFIG_SYS_FSMC_NAND_LP, CONFIG_SYS_FSMC_NAND_16BIT, etc.
> 
> Incomplete comment :)
> Are these deprecated

CONFIG symbols that are hardware parameters rather than user-tweakable 
config go in the CONFIG_SYS namespace (see "Software Configuration" in 
README).

I think it should also be an FSMC-specific parameter, not something that 
looks universal.

>>> +#ifndef __FSMC_NAND_H__
>>> +#define __FSMC_NAND_H__
>>> +
>>> +struct fsmc_regs {
>>> +	u8 reserved_1[0x40];
>>> +	u32 genmemctrl_pc;		/* 0x40 */
>>> +	u32 genmemctrl_sts;		/* 0x44 */
>>> +	u32 genmemctrl_comm;		/* 0x48 */
>>> +	u32 genmemctrl_attrib;		/* 0x4c */
>>> +	u32 genmemctrl_ioata;		/* 0x50 */
>>> +	u32 genmemctrl_ecc1;		/* 0x54 */
>>> +	u32 genmemctrl_ecc2;		/* 0x58 */
>>> +	u32 genmemctrl_ecc3;		/* 0x5c */
>>> +	u8 reserved_2[0xfe0 - 0x60];
>>> +	u32 genmemctrl_peripid0;	/* 0xfe0 */
>>> +	u32 genmemctrl_peripid1;	/* 0xfe4 */
>>> +	u32 genmemctrl_peripid2;	/* 0xfe8 */
>>> +	u32 genmemctrl_peripid3;	/* 0xfec */
>>> +	u32 genmemctrl_pcellid0;	/* 0xff0 */
>>> +	u32 genmemctrl_pcellid1;	/* 0xff4 */
>>> +	u32 genmemctrl_pcellid2;	/* 0xff8 */
>>> +	u32 genmemctrl_pcellid3;	/* 0xffc */
>>> +};
>> Is the genmemctrl_ prefix really needed?
>>
> 
> The peripheral's registers are named like these so I kept it.

The struct name takes that role here; hardware documentation doesn't 
have the benefit of that.

-Scott

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

* [U-Boot] [PATCH 07/17] SPEAr : Network driver support added
  2010-04-21 17:48               ` Ben Warren
  2010-04-22  4:43                 ` Vipin KUMAR
@ 2010-04-23 10:32                 ` Armando VISCONTI
  2010-04-26  5:02                   ` Ben Warren
  1 sibling, 1 reply; 38+ messages in thread
From: Armando VISCONTI @ 2010-04-23 10:32 UTC (permalink / raw)
  To: u-boot

Ben,

I have a specific question on the way we handle phy address
in SPEAr.
>> +
>> +static u8 find_phy(struct eth_device *dev)
>> +{
>> +	u8 phy_addr = 0;
>> +	u16 ctrl, oldctrl;
>> +
>> +	do {
>> +		eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
>> +		oldctrl = ctrl&  PHY_BMCR_AUTON;
>> +
>> +		ctrl ^= PHY_BMCR_AUTON;
>> +		eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
>> +		eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
>> +		ctrl&= PHY_BMCR_AUTON;
>> +
>> +		if (ctrl == oldctrl) {
>> +			phy_addr++;
>> +		} else {
>> +			ctrl ^= PHY_BMCR_AUTON;
>> +			eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
>> +			break;
>> +		}
>> +	} while (phy_addr<  32);
>> +
>> +	return phy_addr;
>> +}
>> +
>>     
As you can see we use an auto-probing mechanism implemented as find_phy()
routine. This auto-probing is also used in other cases, like the
drivers/net/mcfmii.c (mii_discover_phy()).

Actually I'm not sure this auto-probing mechanism is correct, as it 
works only
in case (very used) in which the MAC-PHY are in 1:1 relationship.

Instead, the MDIO bus nature implies that there might be N MACs and M 
PHYs connected
to the bus, so the auto-probing would not work.

See here some comments on the same:
http://lists.ozlabs.org/pipermail/devicetree-discuss/2010-February/001670.html


In our PCB we have the 1:1 relationship, but since the dw_eth.c driver 
is generic, it
might be used on differently designed pcb.

What is your general opinion in that?
Should we implement it differently?

Regards,
Arm

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

* [U-Boot] [PATCH 07/17] SPEAr : Network driver support added
  2010-04-23 10:32                 ` Armando VISCONTI
@ 2010-04-26  5:02                   ` Ben Warren
  2010-04-26  8:01                     ` Armando VISCONTI
  0 siblings, 1 reply; 38+ messages in thread
From: Ben Warren @ 2010-04-26  5:02 UTC (permalink / raw)
  To: u-boot

Hi Armando,

On 4/23/2010 3:32 AM, Armando VISCONTI wrote:
> Ben,
>
> I have a specific question on the way we handle phy address
> in SPEAr.
>>> +
>>> +static u8 find_phy(struct eth_device *dev)
>>> +{
>>> +    u8 phy_addr = 0;
>>> +    u16 ctrl, oldctrl;
>>> +
>>> +    do {
>>> +        eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
>>> +        oldctrl = ctrl&  PHY_BMCR_AUTON;
>>> +
>>> +        ctrl ^= PHY_BMCR_AUTON;
>>> +        eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
>>> +        eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
>>> +        ctrl&= PHY_BMCR_AUTON;
>>> +
>>> +        if (ctrl == oldctrl) {
>>> +            phy_addr++;
>>> +        } else {
>>> +            ctrl ^= PHY_BMCR_AUTON;
>>> +            eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
>>> +            break;
>>> +        }
>>> +    } while (phy_addr<  32);
>>> +
>>> +    return phy_addr;
>>> +}
>>> +
> As you can see we use an auto-probing mechanism implemented as find_phy()
> routine. This auto-probing is also used in other cases, like the
> drivers/net/mcfmii.c (mii_discover_phy()).
>
> Actually I'm not sure this auto-probing mechanism is correct, as it 
> works only
> in case (very used) in which the MAC-PHY are in 1:1 relationship.
>
> Instead, the MDIO bus nature implies that there might be N MACs and M 
> PHYs connected
> to the bus, so the auto-probing would not work.
>
> See here some comments on the same:
> http://lists.ozlabs.org/pipermail/devicetree-discuss/2010-February/001670.html 
>
>
>
> In our PCB we have the 1:1 relationship, but since the dw_eth.c driver 
> is generic, it
> might be used on differently designed pcb.
>
> What is your general opinion in that?
> Should we implement it differently?
>
I agree that MDIO bus probing doesn't make much sense.  I don't know 
anything about your SOC, but the ones that I work with typically have 
multiple MACs (data link) but only one MDIO bus (control link).  The end 
result is multiple PHYs on a multi-drop bus, and there's no way of 
knowing which one has its data link connected to which MAC.

I'd prefer to see it hard-coded, either through a CONFIG option or an 
environment variable.
> Regards,
> Arm
regards,
Ben

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

* [U-Boot] [PATCH 07/17] SPEAr : Network driver support added
  2010-04-26  5:02                   ` Ben Warren
@ 2010-04-26  8:01                     ` Armando VISCONTI
  2010-04-26  8:34                       ` Vipin KUMAR
  0 siblings, 1 reply; 38+ messages in thread
From: Armando VISCONTI @ 2010-04-26  8:01 UTC (permalink / raw)
  To: u-boot

Hi Ben,

> I agree that MDIO bus probing doesn't make much sense.  I don't know 
> anything about your SOC, but the ones that I work with typically have 
> multiple MACs (data link) but only one MDIO bus (control link).  The 
> end result is multiple PHYs on a multi-drop bus, and there's no way of 
> knowing which one has its data link connected to which MAC.
>
> I'd prefer to see it hard-coded, either through a CONFIG option or an 
> environment variable.
In our SoC current architecture there are multiple sdio buses, basically 
one for each MAC.
Neverthelees this architecture might change in the future.

Moreover, I agree that driver should be generic, so I guess that we 
might add a phy_addr field
in the device structure and pass it thru the initialize routine, as the 
macb driver is doing.

In the meantime I saw that Vipin already provided a V2 of the driver, 
which is still in the old
way.
Vipin, can you possibly provide your comments?

Thanks,
Arm




-- 
-- "Every step appears to be the unavoidable consequence of the
-- preceding one." (A. Einstein) 
-- 
Armando Visconti                  Mobile: (+39) 346 8879146
Senior SW Engineer                Fax:    (+39) 02 93519290
CPG                               Work:   (+39) 02 93519683
Computer System Division          e-mail: armando.visconti at st.com
ST Microelectronics               TINA:   051  4683
                                    
 

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

* [U-Boot] [PATCH 07/17] SPEAr : Network driver support added
  2010-04-26  8:01                     ` Armando VISCONTI
@ 2010-04-26  8:34                       ` Vipin KUMAR
  0 siblings, 0 replies; 38+ messages in thread
From: Vipin KUMAR @ 2010-04-26  8:34 UTC (permalink / raw)
  To: u-boot

On 4/26/2010 1:31 PM, Armando VISCONTI wrote:
> Hi Ben,
> 
>> I agree that MDIO bus probing doesn't make much sense.  I don't know
>> anything about your SOC, but the ones that I work with typically have
>> multiple MACs (data link) but only one MDIO bus (control link).  The
>> end result is multiple PHYs on a multi-drop bus, and there's no way of
>> knowing which one has its data link connected to which MAC.
>>
>> I'd prefer to see it hard-coded, either through a CONFIG option or an
>> environment variable.
> In our SoC current architecture there are multiple sdio buses, basically
> one for each MAC.
> Neverthelees this architecture might change in the future.
> 
> Moreover, I agree that driver should be generic, so I guess that we
> might add a phy_addr field
> in the device structure and pass it thru the initialize routine, as the
> macb driver is doing.
> 
> In the meantime I saw that Vipin already provided a V2 of the driver,
> which is still in the old
> way.
> Vipin, can you possibly provide your comments?
> 

Actually speaking, I was waiting for a patch from Ben and this issue to
get resolved by then.
Seeing no reply from Ben, I sent a patch v2 to get the comments at least
on other subpatches. 
I think the suggested changes are fine and can be made in patch v3

> Thanks,
> Arm
> 
> 
> 
> 

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

end of thread, other threads:[~2010-04-26  8:34 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-21  7:54 [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support Vipin KUMAR
2010-04-21  7:54 ` [U-Boot] [PATCH 01/17] u-boot.img file not created when srctree and objtree are different Vipin KUMAR
2010-04-21  7:54   ` [U-Boot] [PATCH 02/17] change_bit routine defined Vipin KUMAR
2010-04-21  7:54     ` [U-Boot] [PATCH 03/17] SPEAr : SMI erase and write timeouts increased Vipin KUMAR
2010-04-21  7:54       ` [U-Boot] [PATCH 04/17] SPEAr : Placing ethaddr write and read within CONFIG_CMD_NET Vipin KUMAR
2010-04-21  7:54         ` [U-Boot] [PATCH 05/17] SPEAr : Reducing the max RAM size to 128MB Vipin KUMAR
2010-04-21  7:54           ` [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs Vipin KUMAR
2010-04-21  7:54             ` [U-Boot] [PATCH 07/17] SPEAr : Network driver support added Vipin KUMAR
2010-04-21  7:54               ` [U-Boot] [PATCH 08/17] SPEAr : Network support configured for spear SoCs Vipin KUMAR
2010-04-21  7:54                 ` [U-Boot] [PATCH 09/17] SPEAr : macb driver support added for spear310 and spear320 Vipin KUMAR
2010-04-21  7:54                   ` [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added Vipin KUMAR
2010-04-21  7:54                     ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Vipin KUMAR
2010-04-21  7:54                       ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Vipin KUMAR
2010-04-21  7:54                         ` [U-Boot] [PATCH 13/17] SPEAr : smi driver moved completely into drivers/mtd Vipin KUMAR
2010-04-21  7:54                           ` [U-Boot] [PATCH 14/17] SPEAr : USBD driver support added Vipin KUMAR
2010-04-21  7:54                             ` [U-Boot] [PATCH 15/17] SPEAr : Basic spear1300 architecture " Vipin KUMAR
2010-04-21  7:54                               ` [U-Boot] [PATCH 16/17] SPEAr : spear1300 SoC " Vipin KUMAR
2010-04-21  7:54                                 ` [U-Boot] [PATCH 17/17] SPEAr : Supporting various configurations for spear3xx and spear6xx boards Vipin KUMAR
2010-04-21 12:11                         ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Peter Tyser
2010-04-22  4:07                           ` Vipin KUMAR
2010-04-21 17:02                       ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Scott Wood
2010-04-22  4:21                         ` Vipin KUMAR
2010-04-22 15:39                           ` Scott Wood
2010-04-21 17:02                     ` [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added Scott Wood
2010-04-22  4:28                       ` Vipin KUMAR
2010-04-22 16:01                         ` Scott Wood
2010-04-21 12:00               ` [U-Boot] [PATCH 07/17] SPEAr : Network " Peter Tyser
2010-04-22  4:30                 ` Vipin KUMAR
2010-04-21 17:48               ` Ben Warren
2010-04-22  4:43                 ` Vipin KUMAR
2010-04-23 10:32                 ` Armando VISCONTI
2010-04-26  5:02                   ` Ben Warren
2010-04-26  8:01                     ` Armando VISCONTI
2010-04-26  8:34                       ` Vipin KUMAR
2010-04-21 11:51             ` [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs Peter Tyser
2010-04-22  4:45               ` Vipin KUMAR
2010-04-21 11:54 ` [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support Peter Tyser
2010-04-21 12:00   ` Vipin KUMAR

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.