* [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.