summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSudhakar Rajashekhara <sudhakar.raj@ti.com>2009-02-27 03:24:43 -0500
committerJustin Waters <justin.waters@timesys.com>2009-09-09 14:03:17 -0400
commit639b8447b44c3f636ef11093899f772be0c55ea6 (patch)
treeb029316c662d0497ab1ecb101c871eaaea2d6c45
parent72d15e705bc3983884105cb7755c7ba80e74a0a5 (diff)
Primus port of u-boot.
Tested for SPI and NAND boot mode on Primus EVM. Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
-rw-r--r--Makefile6
-rw-r--r--board/da8xx/da8xx-evm/Makefile52
-rw-r--r--board/da8xx/da8xx-evm/board_init.S29
-rw-r--r--board/da8xx/da8xx-evm/config.mk30
-rw-r--r--board/da8xx/da8xx-evm/dv_board.c231
-rw-r--r--board/da8xx/da8xx-evm/u-boot.lds52
-rw-r--r--common/cmd_nvedit.c2
-rw-r--r--common/cmd_sf.c6
-rw-r--r--cpu/arm926ejs/da8xx/Makefile49
-rw-r--r--cpu/arm926ejs/da8xx/clock.c57
-rw-r--r--cpu/arm926ejs/da8xx/ether.c667
-rw-r--r--cpu/arm926ejs/da8xx/i2c.c356
-rw-r--r--cpu/arm926ejs/da8xx/lowlevel_init.S504
-rw-r--r--cpu/arm926ejs/da8xx/nand.c475
-rw-r--r--cpu/arm926ejs/da8xx/reset.S77
-rw-r--r--cpu/arm926ejs/da8xx/timer.c148
-rw-r--r--drivers/mtd/spi/Makefile1
-rw-r--r--drivers/mtd/spi/spi_flash.c7
-rw-r--r--drivers/mtd/spi/winbond.c338
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/davinci_spi.c284
-rw-r--r--drivers/spi/davinci_spi.h46
-rw-r--r--drivers/spi/spirom.c212
-rw-r--r--drivers/spi/spirom.h77
-rw-r--r--include/asm-arm/arch-da8xx/emac_defs.h331
-rw-r--r--include/asm-arm/arch-da8xx/emif_defs.h61
-rw-r--r--include/asm-arm/arch-da8xx/hardware.h199
-rw-r--r--include/asm-arm/arch-da8xx/i2c_defs.h95
-rw-r--r--include/asm-arm/arch-da8xx/nand_defs.h164
-rw-r--r--include/configs/da8xx_evm.h223
-rw-r--r--include/linux/mtd/nand.h12
-rw-r--r--lib_arm/board.c4
-rw-r--r--net/eth.c4
-rw-r--r--patches/freon_port.patch3910
-rw-r--r--patches/primus_port.patch5062
-rw-r--r--patches/series2
36 files changed, 13768 insertions, 6 deletions
diff --git a/Makefile b/Makefile
index d533564d9a..873964673c 100644
--- a/Makefile
+++ b/Makefile
@@ -151,7 +151,8 @@ ifeq ($(ARCH),ppc)
CROSS_COMPILE = ppc_8xx-
endif
ifeq ($(ARCH),arm)
-CROSS_COMPILE = arm-linux-
+#CROSS_COMPILE = arm-linux-
+CROSS_COMPILE = arm-none-linux-gnueabi-
endif
ifeq ($(ARCH),i386)
CROSS_COMPILE = i386-linux-
@@ -2715,6 +2716,9 @@ davinci_sffsdr_config : unconfig
davinci_sonata_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm926ejs sonata davinci davinci
+da8xx_evm_config : unconfig
+ @$(MKCONFIG) $(@:_config=) arm arm926ejs da8xx-evm da8xx da8xx
+
lpd7a400_config \
lpd7a404_config: unconfig
@$(MKCONFIG) $(@:_config=) arm lh7a40x lpd7a40x
diff --git a/board/da8xx/da8xx-evm/Makefile b/board/da8xx/da8xx-evm/Makefile
new file mode 100644
index 0000000000..fa0013811d
--- /dev/null
+++ b/board/da8xx/da8xx-evm/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# 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 := dv_board.o
+SOBJS := board_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 *~ .depend
+
+#########################################################################
+# This is for $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/da8xx/da8xx-evm/board_init.S b/board/da8xx/da8xx-evm/board_init.S
new file mode 100644
index 0000000000..22d8adc18c
--- /dev/null
+++ b/board/da8xx/da8xx-evm/board_init.S
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Board-specific low level initialization code. Called at the very end
+ * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no
+ * initialization required.
+ *
+ * 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>
+
+.globl dv_board_init
+dv_board_init:
+
+ mov pc, lr
diff --git a/board/da8xx/da8xx-evm/config.mk b/board/da8xx/da8xx-evm/config.mk
new file mode 100644
index 0000000000..56de37a08f
--- /dev/null
+++ b/board/da8xx/da8xx-evm/config.mk
@@ -0,0 +1,30 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+#
+# (C) Copyright 2003
+# Texas Instruments, <www.ti.com>
+# Swaminathan <swami.iyer@ti.com>
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# (C) Copyright 2008
+# Sekhar Nori, Texas Instruments, Inc. <nsekhar@ti.com>
+#
+# Texas Instruments DA8xx EVM board (ARM925EJS) cpu
+# see http://www.ti.com/ for more information on Texas Instruments
+#
+# DA8xx EVM has 1 bank of 64 MB SDRAM (2 16Meg x16 chips).
+# Physical Address:
+# C000'0000 to C400'0000
+#
+# Linux-Kernel is expected to be at C000'8000, entry C000'8000
+# (mem base + reserved)
+#
+# we load ourself to C108 '0000
+#
+#
+
+#Provide at least 16MB spacing between us and the Linux Kernel image
+TEXT_BASE = 0xC1080000
diff --git a/board/da8xx/da8xx-evm/dv_board.c b/board/da8xx/da8xx-evm/dv_board.c
new file mode 100644
index 0000000000..d6eff61242
--- /dev/null
+++ b/board/da8xx/da8xx-evm/dv_board.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc. <nsekhar@ti.com>
+ *
+ * Modified for DA8xx EVM.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts are shamelessly stolen from various TI sources, original copyright
+ * follows:
+ * -----------------------------------------------------------------
+ *
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/emac_defs.h>
+
+#define MACH_TYPE_DA8XX_EVM 1781
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern void timer_init(void);
+extern int eth_hw_init(void);
+
+/* Works on Always On power domain only (no PD argument) */
+void lpsc_on(unsigned int id)
+{
+ dv_reg_p mdstat, mdctl, ptstat, ptcmd;
+
+ if (id >= 64)
+ return;
+
+ if(id < 32) {
+ mdstat = REG_P(PSC0_MDSTAT + (id * 4));
+ mdctl = REG_P(PSC0_MDCTL + (id * 4));
+ ptstat = REG_P(PSC0_PTSTAT);
+ ptcmd = REG_P(PSC0_PTCMD);
+ } else {
+ id -= 32;
+ mdstat = REG_P(PSC1_MDSTAT + (id * 4));
+ mdctl = REG_P(PSC1_MDCTL + (id * 4));
+ ptstat = REG_P(PSC1_PTSTAT);
+ ptcmd = REG_P(PSC1_PTCMD);
+ }
+
+ while (*ptstat & 0x01) {;}
+
+ if ((*mdstat & 0x1f) == 0x03)
+ return; /* Already on and enabled */
+
+ *mdctl |= 0x03;
+
+ /* Special treatment for some modules as for sprue14 p.7.4.2 */
+ /* TBD: Confirm if such cases exist for Primus */
+ if (0)
+ *mdctl |= 0x200;
+
+ *ptcmd = 0x01;
+
+ while (*ptstat & 0x01) {;}
+ while ((*mdstat & 0x1f) != 0x03) {;} /* Probably an overkill... */
+}
+
+int board_init(void)
+{
+
+ dv_reg_p intc;
+
+ /*-------------------------------------------------------*
+ * Mask all IRQs by clearing the global enable and setting
+ * the enable clear for all the 90 interrupts. This code is
+ * also included in low level init. Including it here in case
+ * low level init is skipped. Not removing it from low level
+ * init in case some of the low level init code generates
+ * interrupts... Not expected... but you never know...
+ *-------------------------------------------------------*/
+
+#ifndef CONFIG_USE_IRQ
+ intc = REG_P(INTC_GLB_EN);
+ intc[0] = 0;
+
+ intc = REG_P(INTC_HINT_EN);
+ intc[0] = 0;
+ intc[1] = 0;
+ intc[2] = 0;
+
+ intc = REG_P(INTC_EN_CLR0);
+ intc[0] = 0xFFFFFFFF;
+ intc[1] = 0xFFFFFFFF;
+ intc[2] = 0xFFFFFFFF;
+#endif
+
+ /* arch number of the board */
+ gd->bd->bi_arch_number = MACH_TYPE_DA8XX_EVM;
+
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+ /* setup the SUSPSRC for ARM to control emulation suspend */
+ REG(SUSPSRC) &= ~( (1 << 27) /* Timer0 */
+ | (1 << 21) /* SPI0 */
+ | (1 << 20) /* UART2 */
+ | (1 << 5) /* EMAC */
+ | (1 << 16) /* I2C0 */
+ );
+
+ /* Power on required peripherals
+ * ARM does not have acess by default to PSC0 and PSC1
+ * assuming here that the DSP bootloader has set the IOPU
+ * such that PSC access is available to ARM
+ */
+ lpsc_on(DAVINCI_LPSC_AEMIF); /* NAND, NOR */
+ lpsc_on(DAVINCI_LPSC_SPI0); /* Serial Flash */
+ lpsc_on(DAVINCI_LPSC_EMAC); /* image download */
+ lpsc_on(DAVINCI_LPSC_UART2); /* console */
+ lpsc_on(DAVINCI_LPSC_GPIO);
+
+ /* Pin Muxing support */
+
+ /* write the kick registers to unlock the PINMUX registers */
+ REG(KICK0) = 0x83e70b13; /* Kick0 unlock */
+ REG(KICK1) = 0x95a4f1e0; /* Kick1 unlock */
+
+#ifdef CONFIG_SPI_FLASH
+ /* SPI0 */
+ REG(PINMUX7) &= 0x00000FFF;
+ REG(PINMUX7) |= 0x11111000;
+#endif
+
+#ifdef CONFIG_DRIVER_TI_EMAC
+ /* RMII clock is sourced externally */
+ REG(PINMUX9) &= 0xFF0FFFFF;
+ REG(PINMUX10) &= 0x0000000F;
+ REG(PINMUX10) |= 0x22222220;
+ REG(PINMUX11) &= 0xFFFFFF00;
+ REG(PINMUX11) |= 0x00000022;
+#endif
+
+ /* Async EMIF */
+#if defined(CFG_USE_NAND) || defined(CFG_USE_NOR)
+ REG(PINMUX13) &= 0x00FFFFFF;
+ REG(PINMUX13) |= 0x11000000;
+ REG(PINMUX14) = 0x11111111;
+ REG(PINMUX15) = 0x11111111;
+ REG(PINMUX16) = 0x11111111;
+ REG(PINMUX17) = 0x11111111;
+ REG(PINMUX18) = 0x11111111;
+ REG(PINMUX19) &= 0xFFFFFFF0;
+ REG(PINMUX19) |= 0x1;
+#endif
+
+ /* UART Muxing and enabling */
+ REG(PINMUX8) &= 0x0FFFFFFF;
+ REG(PINMUX8) |= 0x20000000;
+
+ REG(PINMUX9) &= 0xFFFFFFF0;
+ REG(PINMUX9) |= 0x00000002;
+
+ REG(DAVINCI_UART2_BASE + 0x30) = 0xE001;
+
+ /* I2C muxing */
+ REG(PINMUX8) &= 0xFFF00FFF;
+ REG(PINMUX8) |= 0x00022000;
+
+ /* write the kick registers to lock the PINMUX registers */
+ REG(KICK0) = 0x0; /* Kick0 lock */
+ REG(KICK1) = 0x0; /* Kick1 lock */
+
+ return(0);
+}
+
+int misc_init_r (void)
+{
+ u_int8_t tmp[20], buf[10];
+ int i;
+
+ printf ("ARM Clock : %d Hz\n", clk_get(DAVINCI_ARM_CLKID));
+
+ /* Set Ethernet MAC address from EEPROM */
+ if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0x7f00, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, buf, 6)) {
+ printf("\nEEPROM @ 0x%02x read FAILED!!!\n", CONFIG_SYS_I2C_EEPROM_ADDR);
+ } else {
+ tmp[0] = 0xff;
+ for (i = 0; i < 6; i++)
+ tmp[0] &= buf[i];
+
+ if ((tmp[0] != 0xff) && (getenv("ethaddr") == NULL)) {
+ sprintf((char *)&tmp[0], "%02x:%02x:%02x:%02x:%02x:%02x",
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+ setenv("ethaddr", (char *)&tmp[0]);
+ }
+ }
+
+ tmp[0] = 0x01;
+ tmp[1] = 0x23;
+ if(i2c_write(0x5f, 0, 0, tmp, 2)) {
+ printf("Ethernet switch start failed!\n");
+ }
+
+ if (!eth_hw_init()) {
+ printf("Error: Ethernet init failed!\n");
+ }
+
+ return(0);
+}
+
+int dram_init(void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+ return(0);
+}
diff --git a/board/da8xx/da8xx-evm/u-boot.lds b/board/da8xx/da8xx-evm/u-boot.lds
new file mode 100644
index 0000000000..a4fcd1a9bb
--- /dev/null
+++ b/board/da8xx/da8xx-evm/u-boot.lds
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm926ejs/start.o (.text)
+ *(.text)
+ }
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+ . = ALIGN(4);
+ .data : { *(.data) }
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss (NOLOAD) : { *(.bss) }
+ _end = .;
+}
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 85025daec7..cdb74bb256 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -549,6 +549,7 @@ int getenv_r (char *name, char *buf, unsigned len)
#if ((defined(CONFIG_ENV_IS_IN_NVRAM) || defined(CONFIG_ENV_IS_IN_EEPROM) \
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_FLASH)) \
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND)) \
+ || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_SF)) \
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND))) \
&& !defined(CONFIG_ENV_IS_NOWHERE))
int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
@@ -605,6 +606,7 @@ U_BOOT_CMD(
#if ((defined(CONFIG_ENV_IS_IN_NVRAM) || defined(CONFIG_ENV_IS_IN_EEPROM) \
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_FLASH)) \
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND)) \
+ || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_SF)) \
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND))) \
&& !defined(CONFIG_ENV_IS_NOWHERE))
U_BOOT_CMD(
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 8c0a7514df..5d6db2d283 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -29,6 +29,11 @@ static int do_spi_flash_probe(int argc, char *argv[])
if (argc < 2)
goto usage;
+ if(flash) {
+ printf("SPI flash already probed\n");
+ goto probe_done;
+ }
+
cs = simple_strtoul(argv[1], &endp, 0);
if (*argv[1] == 0 || (*endp != 0 && *endp != ':'))
goto usage;
@@ -63,6 +68,7 @@ static int do_spi_flash_probe(int argc, char *argv[])
spi_flash_free(flash);
flash = new;
+probe_done:
printf("%u KiB %s at %u:%u is now current device\n",
flash->size >> 10, flash->name, bus, cs);
diff --git a/cpu/arm926ejs/da8xx/Makefile b/cpu/arm926ejs/da8xx/Makefile
new file mode 100644
index 0000000000..49fa3111ef
--- /dev/null
+++ b/cpu/arm926ejs/da8xx/Makefile
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# 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 ether.o nand.o clock.o i2c.o
+SOBJS = lowlevel_init.o reset.o
+
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm926ejs/da8xx/clock.c b/cpu/arm926ejs/da8xx/clock.c
new file mode 100644
index 0000000000..7cb979bc00
--- /dev/null
+++ b/cpu/arm926ejs/da8xx/clock.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc. <nsekhar@ti.com>
+ *
+ * DA8xx clock module
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+
+dv_reg_p sysdiv[9] = {
+ PLL0_DIV1, PLL0_DIV2, PLL0_DIV3, PLL0_DIV4, PLL0_DIV5, PLL0_DIV6,
+ PLL0_DIV7, PLL0_DIV8, PLL0_DIV9 };
+
+int clk_get(unsigned int id)
+{
+ int pre_div = (REG(PLL0_PREDIV) & 0xff) + 1;
+ int pllm = REG(PLL0_PLLM) + 1;
+ int post_div = (REG(PLL0_POSTDIV) & 0xff) + 1;
+ int pll_out = CFG_OSCIN_FREQ;
+
+ if(id == DAVINCI_AUXCLK_CLKID)
+ goto out;
+
+ /* Lets keep this simple. Combining operations can result in
+ * unexpected approximations
+ */
+ pll_out /= pre_div;
+ pll_out *= pllm;
+
+ if(id == DAVINCI_PLLM_CLKID)
+ goto out;
+
+ pll_out /= post_div;
+
+ if(id == DAVINCI_PLLC_CLKID)
+ goto out;
+
+ pll_out /= (REG(sysdiv[id - 1]) & 0xff) + 1;
+
+out:
+ return pll_out;
+}
diff --git a/cpu/arm926ejs/da8xx/ether.c b/cpu/arm926ejs/da8xx/ether.c
new file mode 100644
index 0000000000..f128196bb9
--- /dev/null
+++ b/cpu/arm926ejs/da8xx/ether.c
@@ -0,0 +1,667 @@
+/*
+ * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
+ * follows:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * dm644x_emac.c
+ *
+ * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
+ *
+ * Copyright (C) 2005 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+
+ * Modifications:
+ * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
+ * ver 1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
+ *
+ */
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <miiphy.h>
+#include <asm/arch/emac_defs.h>
+
+#ifdef CONFIG_DRIVER_TI_EMAC
+
+#ifdef CONFIG_CMD_NET
+
+unsigned int emac_dbg = 0;
+#define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args)
+
+/* Internal static functions */
+static int dm644x_eth_hw_init (void);
+static int dm644x_eth_open (void);
+static int dm644x_eth_close (void);
+static int dm644x_eth_send_packet (volatile void *packet, int length);
+static int dm644x_eth_rcv_packet (void);
+static void dm644x_eth_mdio_enable(void);
+
+static int gen_init_phy(int phy_addr);
+static int gen_is_phy_connected(int phy_addr);
+static int gen_get_link_speed(int phy_addr);
+static int gen_auto_negotiate(int phy_addr);
+
+/* Wrappers exported to the U-Boot proper */
+int eth_hw_init(void)
+{
+ return(dm644x_eth_hw_init());
+}
+
+int eth_init(bd_t * bd)
+{
+ return(dm644x_eth_open());
+}
+
+void eth_halt(void)
+{
+ dm644x_eth_close();
+}
+
+int eth_send(volatile void *packet, int length)
+{
+ return(dm644x_eth_send_packet(packet, length));
+}
+
+int eth_rx(void)
+{
+ return(dm644x_eth_rcv_packet());
+}
+
+void eth_mdio_enable(void)
+{
+ dm644x_eth_mdio_enable();
+}
+/* End of wrappers */
+
+/* dm644x_eth_mac_addr[0] goes out on the wire first */
+
+static u_int8_t dm644x_eth_mac_addr[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00 };
+
+/*
+ * This function must be called before emac_open() if you want to override
+ * the default mac address.
+ */
+void dm644x_eth_set_mac_addr(const u_int8_t *addr)
+{
+ int i;
+
+ for (i = 0; i < sizeof (dm644x_eth_mac_addr); i++) {
+ dm644x_eth_mac_addr[i] = addr[i];
+ }
+}
+
+/* EMAC Addresses */
+static volatile emac_regs *adap_emac = (emac_regs *)EMAC_BASE_ADDR;
+static volatile ewrap_regs *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
+static volatile mdio_regs *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;
+
+/* EMAC descriptors */
+static volatile emac_desc *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
+static volatile emac_desc *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
+static volatile emac_desc *emac_rx_active_head = 0;
+static volatile emac_desc *emac_rx_active_tail = 0;
+static int emac_rx_queue_active = 0;
+
+/* Receive packet buffers */
+static unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
+
+/* PHY address for a discovered PHY (0xff - not found) */
+static volatile u_int8_t active_phy_addr = 0xff;
+
+static int no_phy_init (int phy_addr) { return(1); }
+static int no_phy_is_connected (int phy_addr) { return(1); }
+static int no_phy_get_link_speed (int phy_addr) { return(1); }
+static int no_phy_auto_negotiate (int phy_addr) { return(1); }
+phy_t phy = {
+ .init = no_phy_init,
+ .is_phy_connected = no_phy_is_connected,
+ .get_link_speed = no_phy_get_link_speed,
+ .auto_negotiate = no_phy_auto_negotiate
+};
+
+static void dm644x_eth_mdio_enable(void)
+{
+ u_int32_t clkdiv;
+
+ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+
+ adap_mdio->CONTROL = (clkdiv & 0xff) |
+ MDIO_CONTROL_ENABLE |
+ MDIO_CONTROL_FAULT |
+ MDIO_CONTROL_FAULT_ENABLE;
+
+ while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
+}
+
+/*
+ * Tries to find an active connected PHY. Returns 1 if address if found.
+ * If no active PHY found returns 0. If more than one active PHY (switch)
+ * returns 2
+ * Sets active_phy_addr variable when returns 1.
+ */
+static int dm644x_eth_phy_detect(void)
+{
+ u_int32_t phy_act_state;
+ int i;
+
+ active_phy_addr = 0xff;
+
+ if ((phy_act_state = adap_mdio->ALIVE) == 0)
+ return(0); /* No active PHYs */
+
+ debug_emac("dm644x_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
+
+ for (i = 0; i < 32; i++) {
+ if (phy_act_state & (1 << i)) {
+ if (phy_act_state & ~(1 << i))
+ return(2); /* More than one PHY */
+ else {
+ active_phy_addr = i;
+ return(1);
+ }
+ }
+ }
+
+ return(0); /* Just to make GCC happy */
+}
+
+
+/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
+int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
+{
+ int tmp;
+
+ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+
+ adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
+ MDIO_USERACCESS0_WRITE_READ |
+ ((reg_num & 0x1f) << 21) |
+ ((phy_addr & 0x1f) << 16);
+
+ /* Wait for command to complete */
+ while ((tmp = adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) {;}
+
+ if (tmp & MDIO_USERACCESS0_ACK) {
+ *data = tmp & 0xffff;
+ return(1);
+ }
+
+ *data = -1;
+ return(0);
+}
+
+/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
+int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
+{
+
+ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+
+ adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
+ MDIO_USERACCESS0_WRITE_WRITE |
+ ((reg_num & 0x1f) << 21) |
+ ((phy_addr & 0x1f) << 16) |
+ (data & 0xffff);
+
+ /* Wait for command to complete */
+ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+
+ return(1);
+}
+
+/* PHY functions for a generic PHY */
+static int gen_init_phy(int phy_addr)
+{
+ int ret = 1;
+
+ if (gen_get_link_speed(phy_addr)) {
+ /* Try another time */
+ ret = gen_get_link_speed(phy_addr);
+ }
+
+ return(ret);
+}
+
+static int gen_is_phy_connected(int phy_addr)
+{
+ u_int16_t dummy;
+
+ return(dm644x_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy));
+}
+
+static int gen_get_link_speed(int phy_addr)
+{
+ u_int16_t tmp;
+
+ if (dm644x_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) && (tmp & 0x04))
+ return(1);
+
+ return(0);
+}
+
+static int gen_auto_negotiate(int phy_addr)
+{
+ u_int16_t tmp;
+
+ if (!dm644x_eth_phy_read(phy_addr, PHY_BMCR, &tmp))
+ return(0);
+
+ /* Restart Auto_negotiation */
+ tmp |= PHY_BMCR_AUTON;
+ dm644x_eth_phy_write(phy_addr, PHY_BMCR, tmp);
+
+ /*check AutoNegotiate complete */
+ udelay (10000);
+ if (!dm644x_eth_phy_read(phy_addr, PHY_BMSR, &tmp))
+ return(0);
+
+ if (!(tmp & PHY_BMSR_AUTN_COMP))
+ return(0);
+
+ return(gen_get_link_speed(phy_addr));
+}
+/* End of generic PHY functions */
+
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static int dm644x_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
+{
+ return(dm644x_eth_phy_read(addr, reg, value) ? 0 : 1);
+}
+
+static int dm644x_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value)
+{
+ return(dm644x_eth_phy_write(addr, reg, value) ? 0 : 1);
+}
+
+int dm644x_eth_miiphy_initialize(bd_t *bis)
+{
+ miiphy_register(phy.name, dm644x_mii_phy_read, dm644x_mii_phy_write);
+
+ return(1);
+}
+#endif
+
+/*
+ * This function initializes the emac hardware. It does NOT initialize
+ * EMAC modules power or pin multiplexors, that is done by board_init()
+ * much earlier in bootup process. Returns 1 on success, 0 otherwise.
+ */
+static int dm644x_eth_hw_init(void)
+{
+ u_int32_t phy_id;
+ u_int16_t tmp;
+ int i, ret;
+
+ /* The RMII clock can be sources internally through the SYSCLK7
+ * or can come externally through a dedicated pin. This selection is
+ * controlled by PinMux9[21]. PinMux registers are off-limits for ARM.
+ * In short, we just assume there is a 50MHz RMII clock available.
+ */
+
+ dm644x_eth_mdio_enable();
+
+ for (i = 0; i < 256; i++) {
+ if (adap_mdio->ALIVE)
+ break;
+ udelay(1000);
+ }
+
+ if (i >= 256) {
+ printf("No ETH PHY detected!!!\n");
+ return(0);
+ }
+
+ /* Find if a PHY is connected and get it's address */
+ ret = dm644x_eth_phy_detect();
+
+ if (ret == 2) {
+ printf("More than one PHY detected.\n");
+ return(1);
+ } else if(ret == 0)
+ return(0);
+
+ /* Get PHY ID and initialize phy_ops for a detected PHY */
+ if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR1, &tmp)) {
+ active_phy_addr = 0xff;
+ return(0);
+ }
+
+ phy_id = (tmp << 16) & 0xffff0000;
+
+ if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR2, &tmp)) {
+ active_phy_addr = 0xff;
+ return(0);
+ }
+
+ phy_id |= tmp & 0x0000ffff;
+
+ switch (phy_id) {
+ default:
+ sprintf(phy.name, "GENERIC @ 0x%02x", active_phy_addr);
+ phy.init = gen_init_phy;
+ phy.is_phy_connected = gen_is_phy_connected;
+ phy.get_link_speed = gen_get_link_speed;
+ phy.auto_negotiate = gen_auto_negotiate;
+ }
+
+ return(1);
+}
+
+
+/* Eth device open */
+static int dm644x_eth_open(void)
+{
+ dv_reg_p addr;
+ u_int32_t clkdiv, cnt;
+ volatile emac_desc *rx_desc;
+ int i;
+
+ debug_emac("+ emac_open\n");
+
+ /* Reset EMAC module and disable interrupts in wrapper */
+ adap_emac->SOFTRESET = 1;
+ while (adap_emac->SOFTRESET != 0) {;}
+ adap_ewrap->SOFTRESET = 1;
+ while (adap_ewrap->SOFTRESET != 0) {;}
+
+ adap_ewrap->C0RXEN = adap_ewrap->C1RXEN = adap_ewrap->C2RXEN = 0;
+ adap_ewrap->C0TXEN = adap_ewrap->C1TXEN = adap_ewrap->C2TXEN = 0;
+ adap_ewrap->C0MISCEN = adap_ewrap->C1MISCEN = adap_ewrap->C2MISCEN = 0;
+
+ rx_desc = emac_rx_desc;
+
+ adap_emac->TXCONTROL = 0x01;
+ adap_emac->RXCONTROL = 0x01;
+
+ /* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */
+ /* Using channel 0 only - other channels are disabled */
+ for (i = 0; i < 8; i++) {
+ adap_emac->MACINDEX = i;
+ adap_emac->MACADDRHI =
+ (dm644x_eth_mac_addr[3] << 24) | /* bits 23-16 */
+ (dm644x_eth_mac_addr[2] << 16) | /* bits 31-24 */
+ (dm644x_eth_mac_addr[1] << 8) | /* bits 39-32 */
+ (dm644x_eth_mac_addr[0]); /* bits 47-40 */
+ adap_emac->MACADDRLO =
+ (dm644x_eth_mac_addr[5] << 8) | /* bits 8-0*/
+ (dm644x_eth_mac_addr[4]) | (1 << 19) | (1 << 20); /* bits 8-0 */
+ }
+
+ adap_emac->MACHASH1 = 0;
+ adap_emac->MACHASH2 = 0;
+
+ /* Set source MAC address - REQUIRED for pause frames */
+ adap_emac->MACSRCADDRHI =
+ (dm644x_eth_mac_addr[3] << 24) | /* bits 23-16 */
+ (dm644x_eth_mac_addr[2] << 16) | /* bits 31-24 */
+ (dm644x_eth_mac_addr[1] << 8) | /* bits 39-32 */
+ (dm644x_eth_mac_addr[0]); /* bits 47-40 */
+ adap_emac->MACSRCADDRLO =
+ (dm644x_eth_mac_addr[5] << 8) | /* bits 8-0 */
+ (dm644x_eth_mac_addr[4]); /* bits 15-8 */
+
+ /* Set DMA 8 TX / 8 RX Head pointers to 0 */
+ addr = &adap_emac->TX0HDP;
+ for(cnt = 0; cnt < 16; cnt++)
+ *addr++ = 0;
+
+ addr = &adap_emac->TX0CP;
+ for(cnt = 0; cnt < 16; cnt++)
+ *addr++ = 0;
+
+ /* Clear Statistics (do this before setting MacControl register) */
+ addr = &adap_emac->RXGOODFRAMES;
+ for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
+ *addr++ = 0;
+
+ /* No multicast addressing */
+ adap_emac->MACHASH1 = 0;
+ adap_emac->MACHASH2 = 0;
+
+ /* Create RX queue and set receive process in place */
+ emac_rx_active_head = emac_rx_desc;
+ for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
+ rx_desc->next = (u_int32_t)(rx_desc + 1);
+ rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
+ rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
+ rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
+ rx_desc++;
+ }
+
+ /* Set the last descriptor's "next" parameter to 0 to end the RX desc list */
+ rx_desc--;
+ rx_desc->next = 0;
+ emac_rx_active_tail = rx_desc;
+ emac_rx_queue_active = 1;
+
+ /* Enable TX/RX */
+ adap_emac->RXMAXLEN = EMAC_MAX_ETHERNET_PKT_SIZE;
+ adap_emac->RXBUFFEROFFSET = 0;
+
+ /* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */
+ adap_emac->RXMBPENABLE = EMAC_RXMBPENABLE_RXBROADEN;
+
+ /* Enable ch 0 only */
+ adap_emac->RXUNICASTSET = 0x01;
+
+ /* Enable MII interface and Full duplex mode */
+ adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE) | EMAC_MACCONTROL_RMIISPEED_100;
+
+ /* Init MDIO & get link state */
+ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+ adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
+
+ if (!phy.get_link_speed(active_phy_addr))
+ return(0);
+
+ /* Start receive process */
+ adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
+
+ debug_emac("- emac_open\n");
+
+ return(1);
+}
+
+/* EMAC Channel Teardown */
+static void dm644x_eth_ch_teardown(int ch)
+{
+ dv_reg dly = 0xff;
+ dv_reg cnt;
+
+ debug_emac("+ emac_ch_teardown\n");
+
+ if (ch == EMAC_CH_TX) {
+ /* Init TX channel teardown */
+ adap_emac->TXTEARDOWN = 1;
+ for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->TX0CP) {
+ /* Wait here for Tx teardown completion interrupt to occur
+ * Note: A task delay can be called here to pend rather than
+ * occupying CPU cycles - anyway it has been found that teardown
+ * takes very few cpu cycles and does not affect functionality */
+ dly--;
+ udelay(1);
+ if (dly == 0)
+ break;
+ }
+ adap_emac->TX0CP = cnt;
+ adap_emac->TX0HDP = 0;
+ } else {
+ /* Init RX channel teardown */
+ adap_emac->RXTEARDOWN = 1;
+ for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->RX0CP) {
+ /* Wait here for Rx teardown completion interrupt to occur
+ * Note: A task delay can be called here to pend rather than
+ * occupying CPU cycles - anyway it has been found that teardown
+ * takes very few cpu cycles and does not affect functionality */
+ dly--;
+ udelay(1);
+ if (dly == 0)
+ break;
+ }
+ adap_emac->RX0CP = cnt;
+ adap_emac->RX0HDP = 0;
+ }
+
+ debug_emac("- emac_ch_teardown\n");
+}
+
+/* Eth device close */
+static int dm644x_eth_close(void)
+{
+ debug_emac("+ emac_close\n");
+
+ dm644x_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */
+ dm644x_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */
+
+ /* Reset EMAC module and disable interrupts in wrapper */
+ adap_emac->SOFTRESET = 1;
+ adap_ewrap->SOFTRESET = 1;
+
+ adap_ewrap->C0RXEN = adap_ewrap->C1RXEN = adap_ewrap->C2RXEN = 0;
+ adap_ewrap->C0TXEN = adap_ewrap->C1TXEN = adap_ewrap->C2TXEN = 0;
+ adap_ewrap->C0MISCEN = adap_ewrap->C1MISCEN = adap_ewrap->C2MISCEN = 0;
+
+ debug_emac("- emac_close\n");
+ return(1);
+}
+
+static int tx_send_loop = 0;
+
+/*
+ * This function sends a single packet on the network and returns
+ * positive number (number of bytes transmitted) or negative for error
+ */
+static int dm644x_eth_send_packet(volatile void *packet, int length)
+{
+ int ret_status = -1;
+ tx_send_loop = 0;
+
+ /* Return error if no link */
+ if (!phy.get_link_speed(active_phy_addr))
+ {
+ printf("WARN: emac_send_packet: No link\n");
+ return (ret_status);
+ }
+
+ /* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
+ if (length < EMAC_MIN_ETHERNET_PKT_SIZE)
+ {
+ length = EMAC_MIN_ETHERNET_PKT_SIZE;
+ }
+
+ /* Populate the TX descriptor */
+ emac_tx_desc->next = 0;
+ emac_tx_desc->buffer = (u_int8_t *)packet;
+ emac_tx_desc->buff_off_len = (length & 0xffff);
+ emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
+ EMAC_CPPI_SOP_BIT |
+ EMAC_CPPI_OWNERSHIP_BIT |
+ EMAC_CPPI_EOP_BIT);
+ /* Send the packet */
+ adap_emac->TX0HDP = (unsigned int)emac_tx_desc;
+
+ /* Wait for packet to complete or link down */
+ while (1) {
+ if (!phy.get_link_speed(active_phy_addr)) {
+ dm644x_eth_ch_teardown(EMAC_CH_TX);
+ return (ret_status);
+ }
+ if (adap_emac->TXINTSTATRAW & 0x01) {
+ ret_status = length;
+ break;
+ }
+ tx_send_loop++;
+ }
+
+ return(ret_status);
+}
+
+/*
+ * This function handles receipt of a packet from the network
+ */
+static int dm644x_eth_rcv_packet(void)
+{
+ volatile emac_desc *rx_curr_desc;
+ volatile emac_desc *curr_desc;
+ volatile emac_desc *tail_desc;
+ int status, ret = -1;
+
+ rx_curr_desc = emac_rx_active_head;
+ status = rx_curr_desc->pkt_flag_len;
+ if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) {
+ if (status & EMAC_CPPI_RX_ERROR_FRAME) {
+ /* Error in packet - discard it and requeue desc */
+ printf("WARN: emac_rcv_pkt: Error in packet\n");
+ } else {
+ NetReceive(rx_curr_desc->buffer, (rx_curr_desc->buff_off_len & 0xffff));
+ ret = rx_curr_desc->buff_off_len & 0xffff;
+ }
+
+ /* Ack received packet descriptor */
+ adap_emac->RX0CP = (unsigned int)rx_curr_desc;
+ curr_desc = rx_curr_desc;
+ emac_rx_active_head = (volatile emac_desc *)rx_curr_desc->next;
+
+ if (status & EMAC_CPPI_EOQ_BIT) {
+ if (emac_rx_active_head) {
+ adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
+ } else {
+ emac_rx_queue_active = 0;
+ printf("INFO:emac_rcv_packet: RX Queue not active\n");
+ }
+ }
+
+ /* Recycle RX descriptor */
+ rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
+ rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
+ rx_curr_desc->next = 0;
+
+ if (emac_rx_active_head == 0) {
+ printf("INFO: emac_rcv_pkt: active queue head = 0\n");
+ emac_rx_active_head = curr_desc;
+ emac_rx_active_tail = curr_desc;
+ if (emac_rx_queue_active != 0) {
+ adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
+ printf("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
+ emac_rx_queue_active = 1;
+ }
+ } else {
+ tail_desc = emac_rx_active_tail;
+ emac_rx_active_tail = curr_desc;
+ tail_desc->next = (unsigned int)curr_desc;
+ status = tail_desc->pkt_flag_len;
+ if (status & EMAC_CPPI_EOQ_BIT) {
+ adap_emac->RX0HDP = (unsigned int)curr_desc;
+ status &= ~EMAC_CPPI_EOQ_BIT;
+ tail_desc->pkt_flag_len = status;
+ }
+ }
+ return(ret);
+ }
+ return(0);
+}
+
+#endif /* CONFIG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_TI_EMAC */
diff --git a/cpu/arm926ejs/da8xx/i2c.c b/cpu/arm926ejs/da8xx/i2c.c
new file mode 100644
index 0000000000..7b978a855f
--- /dev/null
+++ b/cpu/arm926ejs/da8xx/i2c.c
@@ -0,0 +1,356 @@
+/*
+ * TI DaVinci (TMS320DM644x) I2C driver.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * --------------------------------------------------------
+ *
+ * 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>
+
+#ifdef CONFIG_DRIVER_DAVINCI_I2C
+
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/i2c_defs.h>
+
+#define CHECK_NACK() \
+ do {\
+ if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
+ REG(I2C_CON) = 0;\
+ return(1);\
+ }\
+ } while (0)
+
+
+static int wait_for_bus(void)
+{
+ int stat, timeout;
+
+ REG(I2C_STAT) = 0xffff;
+
+ for (timeout = 0; timeout < 10; timeout++) {
+ if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
+ REG(I2C_STAT) = 0xffff;
+ return(0);
+ }
+
+ REG(I2C_STAT) = stat;
+ udelay(50000);
+ }
+
+ REG(I2C_STAT) = 0xffff;
+ return(1);
+}
+
+
+static int poll_i2c_irq(int mask)
+{
+ int stat, timeout;
+
+ for (timeout = 0; timeout < 10; timeout++) {
+ udelay(1000);
+ stat = REG(I2C_STAT);
+ if (stat & mask) {
+ return(stat);
+ }
+ }
+
+ REG(I2C_STAT) = 0xffff;
+ return(stat | I2C_TIMEOUT);
+}
+
+
+void flush_rx(void)
+{
+ int dummy;
+
+ while (1) {
+ if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
+ break;
+
+ dummy = REG(I2C_DRR);
+ REG(I2C_STAT) = I2C_STAT_RRDY;
+ udelay(1000);
+ }
+}
+
+
+void i2c_init(int speed, int slaveadd)
+{
+ u_int32_t div, psc;
+
+ if (REG(I2C_CON) & I2C_CON_EN) {
+ REG(I2C_CON) = 0;
+ udelay (50000);
+ }
+
+ /* Get 1MHz into I2C internal */
+ psc = CONFIG_SYS_HZ_CLOCK/1000000;
+
+ div = CONFIG_SYS_HZ_CLOCK / (psc * speed); /* SCLL + SCLH */
+
+ REG(I2C_PSC) = psc - 1; /* 27MHz / (2 + 1) = 9MHz */
+ REG(I2C_SCLL) = (div * 50) / 100; /* 50% Duty */
+ REG(I2C_SCLH) = div - REG(I2C_SCLL);
+
+ REG(I2C_OA) = slaveadd;
+ REG(I2C_CNT) = 0;
+
+ /* Interrupts must be enabled or I2C module won't work */
+ REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
+ I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
+
+ /* Now enable I2C controller (get it out of reset) */
+ REG(I2C_CON) = I2C_CON_EN;
+
+ udelay(1000);
+}
+
+
+int i2c_probe(u_int8_t chip)
+{
+ int rc = 1;
+
+ if (chip == REG(I2C_OA)) {
+ return(rc);
+ }
+
+ REG(I2C_CON) = 0;
+ if (wait_for_bus()) {return(1);}
+
+ /* try to read one byte from current (or only) address */
+ REG(I2C_CNT) = 1;
+ REG(I2C_SA) = chip;
+ REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP | I2C_CON_FREE);
+ udelay (50000);
+
+ if (!(REG(I2C_STAT) & I2C_STAT_NACK)) {
+ rc = 0;
+ flush_rx();
+ REG(I2C_STAT) = 0xffff;
+ } else {
+ REG(I2C_STAT) = 0xffff;
+ REG(I2C_CON) |= I2C_CON_STP;
+ udelay(20000);
+ if (wait_for_bus()) {return(1);}
+ }
+
+ flush_rx();
+ REG(I2C_STAT) = 0xffff;
+ REG(I2C_CNT) = 0;
+ return(rc);
+}
+
+
+int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+ u_int32_t tmp;
+ int i;
+
+ if ((alen < 0) || (alen > 2)) {
+ printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
+ return(1);
+ }
+
+ if (wait_for_bus()) {return(1);}
+
+ if (alen != 0) {
+ /* Start address phase */
+ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
+ I2C_CON_FREE;
+ REG(I2C_CNT) = alen;
+ REG(I2C_SA) = chip;
+ REG(I2C_CON) = tmp;
+
+ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+ CHECK_NACK();
+
+ switch (alen) {
+ case 2:
+ /* Send address MSByte */
+ if (tmp & I2C_STAT_XRDY) {
+ REG(I2C_DXR) = (addr >> 8) & 0xff;
+ } else {
+ REG(I2C_CON) = 0;
+ return(1);
+ }
+
+ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+ CHECK_NACK();
+ /* No break, fall through */
+ case 1:
+ /* Send address LSByte */
+ if (tmp & I2C_STAT_XRDY) {
+ REG(I2C_DXR) = addr & 0xff;
+ } else {
+ REG(I2C_CON) = 0;
+ return(1);
+ }
+
+ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY);
+
+ CHECK_NACK();
+
+ if (!(tmp & I2C_STAT_ARDY)) {
+ REG(I2C_CON) = 0;
+ return(1);
+ }
+ }
+ }
+
+ /* Address phase is over, now read 'len' bytes and stop */
+ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP | I2C_CON_FREE;
+ REG(I2C_CNT) = len & 0xffff;
+ REG(I2C_SA) = chip;
+ REG(I2C_CON) = tmp;
+
+ for (i = 0; i < len; i++) {
+ tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR);
+
+ CHECK_NACK();
+
+ if (tmp & I2C_STAT_RRDY) {
+ buf[i] = REG(I2C_DRR);
+ } else {
+ REG(I2C_CON) = 0;
+ return(1);
+ }
+ }
+
+ tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+
+ CHECK_NACK();
+
+ if (!(tmp & I2C_STAT_SCD)) {
+ REG(I2C_CON) = 0;
+ return(1);
+ }
+
+ flush_rx();
+ REG(I2C_STAT) = 0xffff;
+ REG(I2C_CNT) = 0;
+ REG(I2C_CON) = 0;
+
+ return(0);
+}
+
+
+int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+ u_int32_t tmp;
+ int i;
+
+ if ((alen < 0) || (alen > 2)) {
+ printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
+ return(1);
+ }
+ if (len < 0) {
+ printf("%s(): bogus length %x\n", __FUNCTION__, len);
+ return(1);
+ }
+
+ if (wait_for_bus()) {return(1);}
+
+ /* Start address phase */
+ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP;
+ REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
+ REG(I2C_SA) = chip;
+ REG(I2C_CON) = tmp;
+
+ switch (alen) {
+ case 2:
+ /* Send address MSByte */
+ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+ CHECK_NACK();
+
+ if (tmp & I2C_STAT_XRDY) {
+ REG(I2C_DXR) = (addr >> 8) & 0xff;
+ } else {
+ REG(I2C_CON) = 0;
+ return(1);
+ }
+ /* No break, fall through */
+ case 1:
+ /* Send address LSByte */
+ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+ CHECK_NACK();
+
+ if (tmp & I2C_STAT_XRDY) {
+ REG(I2C_DXR) = addr & 0xff;
+ } else {
+ REG(I2C_CON) = 0;
+ return(1);
+ }
+ }
+
+ for (i = 0; i < len; i++) {
+ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+ CHECK_NACK();
+
+ if (tmp & I2C_STAT_XRDY) {
+ REG(I2C_DXR) = buf[i];
+ } else {
+ return(1);
+ }
+ }
+
+ tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+
+ CHECK_NACK();
+
+ if (!(tmp & I2C_STAT_SCD)) {
+ REG(I2C_CON) = 0;
+ return(1);
+ }
+
+ flush_rx();
+ REG(I2C_STAT) = 0xffff;
+ REG(I2C_CNT) = 0;
+ REG(I2C_CON) = 0;
+
+ return(0);
+}
+
+#if 0
+u_int8_t i2c_reg_read(u_int8_t chip, u_int8_t reg)
+{
+ u_int8_t tmp;
+
+ i2c_read(chip, reg, 1, &tmp, 1);
+ return(tmp);
+}
+
+
+void i2c_reg_write(u_int8_t chip, u_int8_t reg, u_int8_t val)
+{
+ u_int8_t tmp;
+
+ i2c_write(chip, reg, 1, &tmp, 1);
+}
+#endif /* if 0 */
+
+#endif /* CONFIG_DRIVER_DAVINCI_I2C */
diff --git a/cpu/arm926ejs/da8xx/lowlevel_init.S b/cpu/arm926ejs/da8xx/lowlevel_init.S
new file mode 100644
index 0000000000..c36993e16e
--- /dev/null
+++ b/cpu/arm926ejs/da8xx/lowlevel_init.S
@@ -0,0 +1,504 @@
+/*
+ * Low-level board setup code for TI DA8xx SoC based boards.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc <www.ti.com>
+ * Sekhar Nori <nsekhar@ti.com>
+ *
+ * Based on TI DaVinci low level init code. Original copyrights follow.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Partially based on TI sources, original copyrights follow:
+ */
+
+/*
+ * Board specific setup info
+ *
+ * (C) Copyright 2003
+ * Texas Instruments, <www.ti.com>
+ * Kshitij Gupta <Kshitij@ti.com>
+ *
+ * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
+ *
+ * Modified for OMAP 5912 OSK board by Rishi Bhattacharya, Apr 2004
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Modified for DV-EVM board by Rishi Bhattacharya, Apr 2005
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Modified for DV-EVM board by Swaminathan S, Nov 2005
+ * 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>
+#include <asm/arch/hardware.h>
+
+.globl lowlevel_init
+lowlevel_init:
+
+ nop
+ nop
+ nop
+ nop
+
+ /*
+ * Call board-specific lowlevel init.
+ * That MUST be present and THAT returns
+ * back to arch calling code with "mov pc, lr."
+ */
+ b dv_board_init
+
+#ifndef CONFIG_USE_IRQ
+ /*-------------------------------------------------------*
+ * Mask all IRQs by clearing the global enable and setting
+ * the enable clear for all the 90 interrupts.
+ *-------------------------------------------------------*/
+ mov r1, $0
+ ldr r0, INTC_GLB_EN_ADDR
+ str r1, [r0]
+
+ ldr r0, INTC_HINT_EN_ADDR
+ str r1, [r0]
+ add r0, r0, $4
+ str r1, [r0]
+ add r0, r0, $4
+ str r1, [r0]
+
+ mvn r1, r1
+ ldr r0, INTC_EN_CLR0_ADDR
+ str r1, [r0]
+ add r0, r0, $4
+ str r1, [r0]
+ add r0, r0, $4
+ str r1, [r0]
+#endif
+
+ /*------------------------------------------------------*
+ * PLL0 Initialization - works only in non-secure devices
+ *------------------------------------------------------*/
+
+ /* TODO: Write the kick values and the PLL master lock bits */
+
+ /* Select OSCIN in clockmode bit in PLLCTL register. This is the only
+ * clock mode supported on DA8xx
+ */
+ ldr r6, PLL0_PLLCTL_ADDR
+ ldr r7, PLL_CLKSRC_MASK
+ ldr r8, [r6]
+ and r8, r8, r7
+ str r8, [r6]
+
+ /* Clear the PLLENSRC bit in PLLCTL */
+ ldr r7, PLL_ENSRC_MASK
+ and r8, r8, r7
+ str r8, [r6]
+
+ /* Bypass the PLL */
+ ldr r7, PLL_BYPASS_MASK
+ and r8, r8, r7
+ str r8, [r6]
+
+ /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */
+ mov r10, $0x20
+WaitPLL0Loop:
+ subs r10, r10, $1
+ bne WaitPLL0Loop
+
+ /* Reset the PLL */
+ ldr r7, PLL_RESET_MASK
+ and r8, r8, r7
+ str r8, [r6]
+
+ /* disable PLL output */
+ mov r7, $0x10
+ orr r8, r8, r7
+ str r8, [r6]
+
+ /* Power up the PLL */
+ ldr r7, PLL_PWRUP_MASK
+ and r8, r8, r7
+ str r8, [r6]
+
+ /* Enable the PLL from Disable Mode */
+ ldr r7, PLL_DISABLE_ENABLE_MASK
+ and r8, r8, r7
+ str r8, [r6]
+
+ /* Wait for the PLL stabilization time - 150us assumed */
+ mov r10, $0xE10
+PLLStableLoop:
+ subs r10, r10, $1
+ bne PLLStableLoop
+
+ /* Program the PLL Multiplier */
+ ldr r6, PLL0_PLLM_ADDR
+ mov r2, $0x18 /* 24 * 25 = 600MHz*/
+ str r2, [r6]
+
+ /* Program the POSTDIV Value */
+ ldr r6, PLL0_POSTDIV_ADDR
+ mov r3, $0x01
+ mov r3, r3, lsl $15
+ orr r3, r3, $0x01
+ str r3, [r6]
+
+ /* Program the SYSCLKx dividedrs */
+
+ /* Following defaults are good:
+ * SYSCLK1 = /1 => 300MHz GEM
+ * SYSCLK2 = /2 => 150MHz EDMA, MMC/SD, UART1/2, SPI1
+ * SYSCLK3 = /3 => 100MHz Possible EMIF2.5
+ * SYSCLK4 = /4 => 75MHz INTC, PSC, EMAC, USB 1.1, I2C1
+ * SYSCLK5 = /3 => 100MHz Possible EMIF3.0 (use DIV4p5)
+ * SYSCLK6 = /1 => 300MHz ARM
+ * SYSCLK7 = /6 => 50MHz RMII Ref Clk
+ * SYSCLK8 = /6 => 50MHz Dont use
+ * SYSCLK9 = /6 => 50MHz Dont use
+ * AUXCLK FIXED => 24Mhz Timer 0/1, 12C0, McASP AuxClk
+ */
+
+ /* Wait for PLL to Reset Properly - 128 OSCIN cycles*/
+ mov r10, $128
+ResetPPL2Loop:
+ subs r10, r10, $1
+ bne ResetPPL2Loop
+
+ /* Bring PLL out of Reset */
+ ldr r6, PLL0_PLLCTL_ADDR
+ ldr r8, [r6]
+ orr r8, r8, $0x08
+ str r8, [r6]
+
+ /* Wait for PLL to Lock */
+ ldr r10, PLL_LOCK_COUNT
+PLL0Lock:
+ subs r10, r10, $1
+ bne PLL0Lock
+
+ /* Enable the PLL */
+ ldr r6, PLL0_PLLCTL_ADDR
+ ldr r8, [r6]
+ orr r8, r8, $0x01
+ str r8, [r6]
+
+ /*------------------------------------------------------*
+ * Setup the pinmux for DDR2 *
+ *------------------------------------------------------*/
+
+ ldr r0, PINMUX1_ADDR
+ ldr r1, PINMUX1_VAL
+ str r1, [r0]
+
+ ldr r0, PINMUX2_ADDR
+ ldr r1, PINMUX2_VAL
+ str r1, [r0]
+
+ ldr r0, PINMUX5_ADDR
+ ldr r1, PINMUX5_VAL
+ str r1, [r0]
+
+ ldr r0, PINMUX6_ADDR
+ ldr r1, PINMUX6_VAL
+ str r1, [r0]
+
+ ldr r8, PINMUX7_FLAG_CLEAR
+ ldr r7, PINMUX7_VAL
+ ldr r0, PINMUX7_ADDR
+ ldr r1, [r0]
+ and r1, r1, r8
+ orr r1, r1, r7
+ str r1, [r0]
+
+
+ /*------------------------------------------------------*
+ * Get the EMIF3 out of reset *
+ *------------------------------------------------------*/
+
+ /* Shut down the DDR2 LPSC Module */
+ ldr r8, PSC_FLAG_CLEAR
+ ldr r6, MDCTL_EMIF3
+ ldr r7, [r6]
+ and r7, r7, r8
+ orr r7, r7, $0x03
+ str r7, [r6]
+
+ /* Enable the Power Domain Transition Command */
+ ldr r6, PSC1_PTCMD_ADDR
+ ldr r7, [r6]
+ orr r7, r7, $0x01
+ str r7, [r6]
+
+ /* Check for Transition Complete(PTSTAT) */
+checkStatClkStop0:
+ ldr r6, PSC1_PTSTAT_ADDR
+ ldr r7, [r6]
+ ands r7, r7, $0x01
+ bne checkStatClkStop0
+
+ /* Check for DDR2 Controller Enable Completion */
+checkDDRStatClkStop0:
+ ldr r6, MDSTAT_EMIF3
+ ldr r7, [r6]
+ and r7, r7, $0x1f
+ cmp r7, $0x03
+ bne checkDDRStatClkStop0
+
+ /*------------------------------------------------------*
+ * Put the EMIF3 in reset *
+ *------------------------------------------------------*/
+
+ /* Shut down the DDR2 LPSC Module */
+ ldr r8, PSC_FLAG_CLEAR
+ ldr r6, MDCTL_EMIF3
+ ldr r7, [r6]
+ and r7, r7, r8
+ orr r7, r7, $0x01
+ str r7, [r6]
+
+ /* Enable the Power Domain Transition Command */
+ ldr r6, PSC1_PTCMD_ADDR
+ ldr r7, [r6]
+ orr r7, r7, $0x01
+ str r7, [r6]
+
+ /* Check for Transition Complete(PTSTAT) */
+checkStatClkStop1:
+ ldr r6, PSC1_PTSTAT_ADDR
+ ldr r7, [r6]
+ ands r7, r7, $0x01
+ bne checkStatClkStop1
+
+ /* Check for DDR2 Controller Enable Completion */
+checkDDRStatClkStop1:
+ ldr r6, MDSTAT_EMIF3
+ ldr r7, [r6]
+ and r7, r7, $0x1f
+ cmp r7, $0x01
+ bne checkDDRStatClkStop1
+
+ nop
+ nop
+
+ /*------------------------------------------------------*
+ * Get the EMIF3 out of reset *
+ *------------------------------------------------------*/
+
+ /* Shut down the DDR2 LPSC Module */
+ ldr r8, PSC_FLAG_CLEAR
+ ldr r6, MDCTL_EMIF3
+ ldr r7, [r6]
+ and r7, r7, r8
+ orr r7, r7, $0x03
+ str r7, [r6]
+
+ /* Enable the Power Domain Transition Command */
+ ldr r6, PSC1_PTCMD_ADDR
+ ldr r7, [r6]
+ orr r7, r7, $0x01
+ str r7, [r6]
+
+ /* Check for Transition Complete(PTSTAT) */
+checkStatClkStop2:
+ ldr r6, PSC1_PTSTAT_ADDR
+ ldr r7, [r6]
+ ands r7, r7, $0x01
+ bne checkStatClkStop2
+
+ /* Check for DDR2 Controller Enable Completion */
+checkDDRStatClkStop2:
+ ldr r6, MDSTAT_EMIF3
+ ldr r7, [r6]
+ and r7, r7, $0x1f
+ cmp r7, $0x03
+ bne checkDDRStatClkStop2
+
+ nop
+ nop
+
+ /*-----------------------------------------------------*
+ * Wait before programing the SDRAM timimg values *
+ *-----------------------------------------------------*/
+
+ ldr r10, EMIF3_TIMING_WAIT_VAL
+emif3TimingWait:
+ sub r10, r10, $0x1
+ cmp r10, $0x0
+ bne emif3TimingWait
+
+ /*------------------------------------------------------*
+ * Program EMIF3 MMRs for 133MHz SDRAM Setting *
+ *------------------------------------------------------*/
+
+ /* Program SDRAM Bank Config Register */
+ ldr r6, SDCFG
+ ldr r7, SDCFG_VAL
+ str r7, [r6]
+
+ /* Program SDRAM TIM-0 Config Register */
+ ldr r6, SDTIM0
+ ldr r7, SDTIM0_VAL_162MHz
+ str r7, [r6]
+
+ /* Program SDRAM TIM-1 Config Register */
+ ldr r6, SDTIM1
+ ldr r7, SDTIM1_VAL_162MHz
+ str r7, [r6]
+
+ /* Program the SDRAM Bank Config Control Register */
+ ldr r10, MASK_VAL
+ ldr r8, SDCFG
+ ldr r9, SDCFG_VAL
+ and r9, r9, r10
+ str r9, [r8]
+
+ /* Program SDRAM SDREF Config Register */
+ ldr r6, SDREF
+ ldr r7, SDREF_VAL
+ str r7, [r6]
+
+ /* Issue a Dummy DDR2 read/write */
+ ldr r8, DDR2_START_ADDR
+ ldr r7, DUMMY_VAL
+ str r7, [r8]
+ ldr r7, [r8]
+
+ /* DDR Writes and Reads */
+ ldr r6, CFGTEST
+ mov r3, $0x01
+ str r3, [r6]
+
+ nop
+ nop
+ nop
+ nop
+
+ /*
+ * Call board-specific lowlevel init.
+ * That MUST be present and THAT returns
+ * back to arch calling code with "mov pc, lr."
+ */
+ b dv_board_init
+
+.ltorg
+
+PINMUX1_ADDR:
+ .word PINMUX1
+PINMUX2_ADDR:
+ .word PINMUX2
+PINMUX5_ADDR:
+ .word PINMUX5
+PINMUX6_ADDR:
+ .word PINMUX6
+PINMUX7_ADDR:
+ .word PINMUX7
+PINMUX1_VAL:
+ .word 0x11111111
+PINMUX2_VAL:
+ .word 0x01111111
+PINMUX5_VAL:
+ .word 0x11111110
+PINMUX6_VAL:
+ .word 0x11111111
+PINMUX7_FLAG_CLEAR:
+ .word 0xFFFFF000
+PINMUX7_VAL:
+ .word 0x111
+
+
+MDCTL_EMIF3:
+ .word PSC1_MDCTL + 4 * 6
+MDSTAT_EMIF3:
+ .word PSC1_MDSTAT + 4 * 6
+
+PSC1_PTCMD_ADDR:
+ .word PSC1_PTCMD
+PSC1_PTSTAT_ADDR:
+ .word PSC1_PTSTAT
+
+INTC_GLB_EN_ADDR:
+ .word INTC_GLB_EN
+INTC_EN_CLR0_ADDR:
+ .word INTC_EN_CLR0
+INTC_HINT_EN_ADDR:
+ .word INTC_HINT_EN
+
+PSC_FLAG_CLEAR:
+ .word 0xffffffe0
+PSC_GEM_FLAG_CLEAR:
+ .word 0xfffffeff
+
+/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */
+SDREF:
+ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0xc
+SDREF_VAL:
+ .word 0x000005c3
+SDCFG:
+ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0x8
+SDCFG_VAL:
+#ifdef SDRAM_4BANKS_10COLS
+ .word 0x00178622
+#elif defined SDRAM_8BANKS_10COLS
+ .word 0x00178632
+#else
+#error "Unknown SDRAM configuration!!!"
+#endif
+SDTIM0:
+ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0x10
+SDTIM0_VAL_162MHz:
+ .word 0x28923211
+SDTIM1:
+ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0x14
+SDTIM1_VAL_162MHz:
+ .word 0x0016c722
+CFGTEST:
+ .word DAVINCI_DDR_EMIF_DATA_BASE + 0x10000
+MASK_VAL:
+ .word 0x00000fff
+EMIF3_TIMING_WAIT_VAL:
+ .word 990000
+
+PLL_CLKSRC_MASK:
+ .word 0xfffffeff /* Mask the Clock Mode bit */
+PLL_ENSRC_MASK:
+ .word 0xffffffdf /* Select the PLLEN source */
+PLL_BYPASS_MASK:
+ .word 0xfffffffe /* Put the PLL in BYPASS */
+PLL_RESET_MASK:
+ .word 0xfffffff7 /* Put the PLL in Reset Mode */
+PLL_PWRUP_MASK:
+ .word 0xfffffffd /* PLL Power up Mask Bit */
+PLL_DISABLE_ENABLE_MASK:
+ .word 0xffffffef /* Enable the PLL from Disable */
+PLL_LOCK_COUNT:
+ .word 2000
+
+/* PLL0 MMRs */
+PLL0_PLLCTL_ADDR:
+ .word PLL0_PLLCTL
+PLL0_PLLM_ADDR:
+ .word PLL0_PLLM
+PLL0_POSTDIV_ADDR:
+ .word PLL0_POSTDIV
+
+DDR2_START_ADDR:
+ .word 0xc0000000
+DUMMY_VAL:
+ .word 0xa55aa55a
diff --git a/cpu/arm926ejs/da8xx/nand.c b/cpu/arm926ejs/da8xx/nand.c
new file mode 100644
index 0000000000..014e2b0c11
--- /dev/null
+++ b/cpu/arm926ejs/da8xx/nand.c
@@ -0,0 +1,475 @@
+/*
+ * NAND driver for TI DaVinci based boards.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Based on Linux DaVinci NAND driver by TI. Original copyright follows:
+ */
+
+/*
+ *
+ * linux/drivers/mtd/nand/nand_davinci.c
+ *
+ * NAND Flash Driver
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+ *
+ * Overview:
+ * This is a device driver for the NAND flash device found on the
+ * DaVinci board which utilizes the Samsung k9k2g08 part.
+ *
+ Modifications:
+ ver. 1.0: Feb 2005, Vinod/Sudhakar
+ -
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SYS_USE_NAND
+#if !defined(CONFIG_NAND_LEGACY)
+
+#include <nand.h>
+#include <asm/arch/nand_defs.h>
+#include <asm/arch/emif_defs.h>
+
+extern struct nand_chip nand_dev_desc[CONFIG_SYS_MAX_NAND_DEVICE];
+
+static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ u_int32_t IO_ADDR_W = (u_int32_t)this->IO_ADDR_W;
+
+ IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if ( ctrl & NAND_CLE )
+ IO_ADDR_W |= MASK_CLE;
+ if ( ctrl & NAND_ALE )
+ IO_ADDR_W |= MASK_ALE;
+ this->IO_ADDR_W = (void __iomem *) IO_ADDR_W;
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ writeb(cmd, this->IO_ADDR_W);
+}
+
+/* Set WP on deselect, write enable on select */
+static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
+{
+#define GPIO_SET_DATA01 0x01c67018
+#define GPIO_CLR_DATA01 0x01c6701c
+#define GPIO_NAND_WP (1 << 4)
+#ifdef SONATA_BOARD_GPIOWP
+ if (chip < 0) {
+ REG(GPIO_CLR_DATA01) |= GPIO_NAND_WP;
+ } else {
+ REG(GPIO_SET_DATA01) |= GPIO_NAND_WP;
+ }
+#endif
+}
+
+#ifdef CONFIG_SYS_NAND_HW_ECC
+#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
+/* Linux-compatible ECC uses MTD defaults. */
+/* These layouts are not compatible with Linux or RBL/UBL. */
+#ifdef CONFIG_SYS_NAND_LARGEPAGE
+static struct nand_ecclayout davinci_nand_ecclayout = {
+ .eccbytes = 12,
+ .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58},
+ .oobfree = {
+ {.offset = 2, .length = 6},
+ {.offset = 12, .length = 12},
+ {.offset = 28, .length = 12},
+ {.offset = 44, .length = 12},
+ {.offset = 60, .length = 4}
+ }
+};
+#elif defined(CONFIG_SYS_NAND_SMALLPAGE)
+static struct nand_ecclayout davinci_nand_ecclayout = {
+ .eccbytes = 3,
+ .eccpos = {0, 1, 2},
+ .oobfree = {
+ {.offset = 6, .length = 2},
+ {.offset = 8, .length = 8}
+ }
+};
+#else
+#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!"
+#endif
+#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
+
+static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ emifregs emif_addr;
+ int dummy;
+
+ emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
+
+ dummy = emif_addr->NANDF1ECC;
+ dummy = emif_addr->NANDF2ECC;
+ dummy = emif_addr->NANDF3ECC;
+ dummy = emif_addr->NANDF4ECC;
+
+ emif_addr->NANDFCR |= (1 << 8);
+}
+
+static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
+{
+ u_int32_t ecc = 0;
+ emifregs emif_base_addr;
+
+ emif_base_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
+
+ if (region == 1)
+ ecc = emif_base_addr->NANDF1ECC;
+ else if (region == 2)
+ ecc = emif_base_addr->NANDF2ECC;
+ else if (region == 3)
+ ecc = emif_base_addr->NANDF3ECC;
+ else if (region == 4)
+ ecc = emif_base_addr->NANDF4ECC;
+
+ return(ecc);
+}
+
+static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+{
+ u_int32_t tmp;
+#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
+ /*
+ * This is not how you should read ECCs on large page Davinci devices.
+ * The region parameter gets you ECCs for flash chips on different chip
+ * selects, not the 4x512 byte pages in a 2048 byte page.
+ *
+ * Preserved for backwards compatibility though.
+ */
+
+ int region, n;
+ struct nand_chip *this = mtd->priv;
+
+ n = (this->ecc.size/512);
+
+ region = 1;
+ while (n--) {
+ tmp = nand_davinci_readecc(mtd, region);
+ *ecc_code++ = tmp;
+ *ecc_code++ = tmp >> 16;
+ *ecc_code++ = ((tmp >> 8) & 0x0f) | ((tmp >> 20) & 0xf0);
+ region++;
+ }
+#else
+ const int region = 1;
+
+ tmp = nand_davinci_readecc(mtd, region);
+
+ /* Squeeze 4 bytes ECC into 3 bytes by removing RESERVED bits
+ * and shifting. RESERVED bits are 31 to 28 and 15 to 12. */
+ tmp = (tmp & 0x00000fff) | ((tmp & 0x0fff0000) >> 4);
+
+ /* Invert so that erased block ECC is correct */
+ tmp = ~tmp;
+
+ *ecc_code++ = tmp;
+ *ecc_code++ = tmp >> 8;
+ *ecc_code++ = tmp >> 16;
+#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
+ return(0);
+}
+
+#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
+static void nand_davinci_gen_true_ecc(u_int8_t *ecc_buf)
+{
+ u_int32_t tmp = ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xf0) << 20) | ((ecc_buf[2] & 0x0f) << 8);
+
+ ecc_buf[0] = ~(P64o(tmp) | P64e(tmp) | P32o(tmp) | P32e(tmp) | P16o(tmp) | P16e(tmp) | P8o(tmp) | P8e(tmp));
+ ecc_buf[1] = ~(P1024o(tmp) | P1024e(tmp) | P512o(tmp) | P512e(tmp) | P256o(tmp) | P256e(tmp) | P128o(tmp) | P128e(tmp));
+ ecc_buf[2] = ~( P4o(tmp) | P4e(tmp) | P2o(tmp) | P2e(tmp) | P1o(tmp) | P1e(tmp) | P2048o(tmp) | P2048e(tmp));
+}
+
+static int nand_davinci_compare_ecc(u_int8_t *ecc_nand, u_int8_t *ecc_calc, u_int8_t *page_data)
+{
+ u_int32_t i;
+ u_int8_t tmp0_bit[8], tmp1_bit[8], tmp2_bit[8];
+ u_int8_t comp0_bit[8], comp1_bit[8], comp2_bit[8];
+ u_int8_t ecc_bit[24];
+ u_int8_t ecc_sum = 0;
+ u_int8_t find_bit = 0;
+ u_int32_t find_byte = 0;
+ int is_ecc_ff;
+
+ is_ecc_ff = ((*ecc_nand == 0xff) && (*(ecc_nand + 1) == 0xff) && (*(ecc_nand + 2) == 0xff));
+
+ nand_davinci_gen_true_ecc(ecc_nand);
+ nand_davinci_gen_true_ecc(ecc_calc);
+
+ for (i = 0; i <= 2; i++) {
+ *(ecc_nand + i) = ~(*(ecc_nand + i));
+ *(ecc_calc + i) = ~(*(ecc_calc + i));
+ }
+
+ for (i = 0; i < 8; i++) {
+ tmp0_bit[i] = *ecc_nand % 2;
+ *ecc_nand = *ecc_nand / 2;
+ }
+
+ for (i = 0; i < 8; i++) {
+ tmp1_bit[i] = *(ecc_nand + 1) % 2;
+ *(ecc_nand + 1) = *(ecc_nand + 1) / 2;
+ }
+
+ for (i = 0; i < 8; i++) {
+ tmp2_bit[i] = *(ecc_nand + 2) % 2;
+ *(ecc_nand + 2) = *(ecc_nand + 2) / 2;
+ }
+
+ for (i = 0; i < 8; i++) {
+ comp0_bit[i] = *ecc_calc % 2;
+ *ecc_calc = *ecc_calc / 2;
+ }
+
+ for (i = 0; i < 8; i++) {
+ comp1_bit[i] = *(ecc_calc + 1) % 2;
+ *(ecc_calc + 1) = *(ecc_calc + 1) / 2;
+ }
+
+ for (i = 0; i < 8; i++) {
+ comp2_bit[i] = *(ecc_calc + 2) % 2;
+ *(ecc_calc + 2) = *(ecc_calc + 2) / 2;
+ }
+
+ for (i = 0; i< 6; i++)
+ ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2];
+
+ for (i = 0; i < 8; i++)
+ ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i];
+
+ for (i = 0; i < 8; i++)
+ ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i];
+
+ ecc_bit[22] = tmp2_bit[0] ^ comp2_bit[0];
+ ecc_bit[23] = tmp2_bit[1] ^ comp2_bit[1];
+
+ for (i = 0; i < 24; i++)
+ ecc_sum += ecc_bit[i];
+
+ switch (ecc_sum) {
+ case 0:
+ /* Not reached because this function is not called if
+ ECC values are equal */
+ return 0;
+ case 1:
+ /* Uncorrectable error */
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "ECC UNCORRECTED_ERROR 1\n");
+ return(-1);
+ case 12:
+ /* Correctable error */
+ find_byte = (ecc_bit[23] << 8) +
+ (ecc_bit[21] << 7) +
+ (ecc_bit[19] << 6) +
+ (ecc_bit[17] << 5) +
+ (ecc_bit[15] << 4) +
+ (ecc_bit[13] << 3) +
+ (ecc_bit[11] << 2) +
+ (ecc_bit[9] << 1) +
+ ecc_bit[7];
+
+ find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
+
+ MTDDEBUG (MTD_DEBUG_LEVEL0, "Correcting single bit ECC "
+ "error at offset: %d, bit: %d\n",
+ find_byte, find_bit);
+
+ page_data[find_byte] ^= (1 << find_bit);
+
+ return(0);
+ default:
+ if (is_ecc_ff) {
+ if (ecc_calc[0] == 0 && ecc_calc[1] == 0 && ecc_calc[2] == 0)
+ return(0);
+ }
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "UNCORRECTED_ERROR default\n");
+ return(-1);
+ }
+}
+#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
+
+static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
+{
+ struct nand_chip *this = mtd->priv;
+#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
+ int block_count = 0, i, rc;
+
+ block_count = (this->ecc.size/512);
+ for (i = 0; i < block_count; i++) {
+ if (memcmp(read_ecc, calc_ecc, 3) != 0) {
+ rc = nand_davinci_compare_ecc(read_ecc, calc_ecc, dat);
+ if (rc < 0) {
+ return(rc);
+ }
+ }
+ read_ecc += 3;
+ calc_ecc += 3;
+ dat += 512;
+ }
+#else
+ u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) |
+ (read_ecc[2] << 16);
+ u_int32_t ecc_calc = calc_ecc[0] | (calc_ecc[1] << 8) |
+ (calc_ecc[2] << 16);
+ u_int32_t diff = ecc_calc ^ ecc_nand;
+
+ if (diff) {
+ if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
+ /* Correctable error */
+ if ((diff >> (12 + 3)) < this->ecc.size) {
+ uint8_t find_bit = 1 << ((diff >> 12) & 7);
+ uint32_t find_byte = diff >> (12 + 3);
+
+ dat[find_byte] ^= find_bit;
+ MTDDEBUG(MTD_DEBUG_LEVEL0, "Correcting single "
+ "bit ECC error at offset: %d, bit: "
+ "%d\n", find_byte, find_bit);
+ return 1;
+ } else {
+ return -1;
+ }
+ } else if (!(diff & (diff - 1))) {
+ /* Single bit ECC error in the ECC itself,
+ nothing to fix */
+ MTDDEBUG(MTD_DEBUG_LEVEL0, "Single bit ECC error in "
+ "ECC.\n");
+ return 1;
+ } else {
+ /* Uncorrectable error */
+ MTDDEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
+ return -1;
+ }
+ }
+#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
+ return(0);
+}
+#endif /* CONFIG_SYS_NAND_HW_ECC */
+
+static int nand_davinci_dev_ready(struct mtd_info *mtd)
+{
+ emifregs emif_addr;
+
+ emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
+
+ return(emif_addr->NANDFSR & 0x1);
+}
+
+static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
+{
+ while(!nand_davinci_dev_ready(mtd)) {;}
+ *NAND_CE0CLE = NAND_STATUS;
+ return(*NAND_CE0DATA);
+}
+
+static void nand_flash_init(void)
+{
+ u_int32_t acfg1 = 0x3ffffffc;
+ u_int32_t acfg2 = 0x3ffffffc;
+ u_int32_t acfg3 = 0x3ffffffc;
+ u_int32_t acfg4 = 0x3ffffffc;
+ emifregs emif_regs;
+
+ /*------------------------------------------------------------------*
+ * NAND FLASH CHIP TIMEOUT @ 459 MHz *
+ * *
+ * AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz *
+ * AEMIF.CLK period = 1/76.5 MHz = 13.1 ns *
+ * *
+ *------------------------------------------------------------------*/
+ acfg1 = 0
+ | (0 << 31 ) /* selectStrobe */
+ | (0 << 30 ) /* extWait */
+ | (1 << 26 ) /* writeSetup 10 ns */
+ | (3 << 20 ) /* writeStrobe 40 ns */
+ | (1 << 17 ) /* writeHold 10 ns */
+ | (1 << 13 ) /* readSetup 10 ns */
+ | (5 << 7 ) /* readStrobe 60 ns */
+ | (1 << 4 ) /* readHold 10 ns */
+ | (3 << 2 ) /* turnAround ?? ns */
+ | (0 << 0 ) /* asyncSize 8-bit bus */
+ ;
+
+ emif_regs = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
+
+ emif_regs->AWCCR |= 0x10000000;
+ emif_regs->AB1CR = acfg1; /* 0x08244128 */;
+ emif_regs->AB2CR = acfg2;
+ emif_regs->AB3CR = acfg3;
+ emif_regs->AB4CR = acfg4;
+ emif_regs->NANDFCR = 0x00000101;
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+ nand->IO_ADDR_R = (void __iomem *)NAND_CE0DATA;
+ nand->IO_ADDR_W = (void __iomem *)NAND_CE0DATA;
+ nand->chip_delay = 0;
+ nand->select_chip = nand_davinci_select_chip;
+#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
+ nand->options = NAND_USE_FLASH_BBT;
+#endif
+#ifdef CONFIG_SYS_NAND_HW_ECC
+ nand->ecc.mode = NAND_ECC_HW;
+#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
+ nand->ecc.layout = &davinci_nand_ecclayout;
+#ifdef CONFIG_SYS_NAND_LARGEPAGE
+ nand->ecc.size = 2048;
+ nand->ecc.bytes = 12;
+#elif defined(CONFIG_SYS_NAND_SMALLPAGE)
+ nand->ecc.size = 512;
+ nand->ecc.bytes = 3;
+#else
+#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!"
+#endif
+#else
+ nand->ecc.size = 512;
+ nand->ecc.bytes = 3;
+#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
+ nand->ecc.calculate = nand_davinci_calculate_ecc;
+ nand->ecc.correct = nand_davinci_correct_data;
+ nand->ecc.hwctl = nand_davinci_enable_hwecc;
+#else
+ nand->ecc.mode = NAND_ECC_SOFT;
+#endif /* CONFIG_SYS_NAND_HW_ECC */
+
+ /* Set address of hardware control function */
+ nand->cmd_ctrl = nand_davinci_hwcontrol;
+
+ nand->dev_ready = nand_davinci_dev_ready;
+ nand->waitfunc = nand_davinci_waitfunc;
+
+ nand_flash_init();
+
+ return(0);
+}
+
+#else
+#error "U-Boot legacy NAND support not available for DaVinci chips"
+#endif
+#endif /* CONFIG_SYS_USE_NAND */
diff --git a/cpu/arm926ejs/da8xx/reset.S b/cpu/arm926ejs/da8xx/reset.S
new file mode 100644
index 0000000000..a687d44035
--- /dev/null
+++ b/cpu/arm926ejs/da8xx/reset.S
@@ -0,0 +1,77 @@
+/*
+ * Processor reset using WDT for TI TMS320DM644x SoC.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * -----------------------------------------------------
+ *
+ * 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
+ */
+
+.globl reset_cpu
+reset_cpu:
+ ldr r0, WDT_TGCR
+ mov r1, $0x08
+ str r1, [r0]
+ ldr r1, [r0]
+ orr r1, r1, $0x03
+ str r1, [r0]
+ mov r1, $0
+ ldr r0, WDT_TIM12
+ str r1, [r0]
+ ldr r0, WDT_TIM34
+ str r1, [r0]
+ ldr r0, WDT_PRD12
+ str r1, [r0]
+ ldr r0, WDT_PRD34
+ str r1, [r0]
+ ldr r0, WDT_TCR
+ ldr r1, [r0]
+ orr r1, r1, $0x40
+ str r1, [r0]
+ ldr r0, WDT_WDTCR
+ ldr r1, [r0]
+ orr r1, r1, $0x4000
+ str r1, [r0]
+ ldr r1, WDTCR_VAL1
+ str r1, [r0]
+ ldr r1, WDTCR_VAL2
+ str r1, [r0]
+ nop
+ nop
+ nop
+ nop
+reset_cpu_loop:
+ b reset_cpu_loop
+
+WDT_TGCR:
+ .word 0x01c21c24
+WDT_TIM12:
+ .word 0x01c21c10
+WDT_TIM34:
+ .word 0x01c21c14
+WDT_PRD12:
+ .word 0x01c21c18
+WDT_PRD34:
+ .word 0x01c21c1c
+WDT_TCR:
+ .word 0x01c21c20
+WDT_WDTCR:
+ .word 0x01c21c28
+WDTCR_VAL1:
+ .word 0xa5c64000
+WDTCR_VAL2:
+ .word 0xda7e4000
diff --git a/cpu/arm926ejs/da8xx/timer.c b/cpu/arm926ejs/da8xx/timer.c
new file mode 100644
index 0000000000..773735a1c8
--- /dev/null
+++ b/cpu/arm926ejs/da8xx/timer.c
@@ -0,0 +1,148 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * 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 <arm926ejs.h>
+
+typedef volatile struct {
+ u_int32_t pid12;
+ u_int32_t emumgt;
+ u_int32_t na1;
+ u_int32_t na2;
+ u_int32_t tim12;
+ u_int32_t tim34;
+ u_int32_t prd12;
+ u_int32_t prd34;
+ u_int32_t tcr;
+ u_int32_t tgcr;
+ u_int32_t wdtcr;
+} davinci_timer;
+
+davinci_timer *timer = (davinci_timer *)CONFIG_SYS_TIMERBASE;
+
+#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)
+#define TIM_CLK_DIV 16
+
+static ulong timestamp;
+static ulong lastinc;
+
+int timer_init(void)
+{
+ /* We are using timer34 in unchained 32-bit mode, full speed */
+ timer->tcr = 0x0;
+ timer->tgcr = 0x0;
+ timer->tgcr = 0x06 | ((TIM_CLK_DIV - 1) << 8);
+ timer->tim34 = 0x0;
+ timer->prd34 = TIMER_LOAD_VAL;
+ lastinc = 0;
+ timestamp = 0;
+ timer->tcr = 2 << 22;
+
+ return(0);
+}
+
+void reset_timer(void)
+{
+ timer->tcr = 0x0;
+ timer->tim34 = 0;
+ lastinc = 0;
+ timestamp = 0;
+ timer->tcr = 2 << 22;
+}
+
+static ulong get_timer_raw(void)
+{
+ ulong now = timer->tim34;
+
+ if (now >= lastinc) {
+ /* normal mode */
+ timestamp += now - lastinc;
+ } else {
+ /* overflow ... */
+ timestamp += now + TIMER_LOAD_VAL - lastinc;
+ }
+ lastinc = now;
+ return timestamp;
+}
+
+ulong get_timer(ulong base)
+{
+ return((get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base);
+}
+
+void set_timer(ulong t)
+{
+ timestamp = t;
+}
+
+void udelay(unsigned long usec)
+{
+ ulong tmo;
+ ulong endtime;
+ signed long diff;
+
+ tmo = CONFIG_SYS_HZ_CLOCK / 1000;
+ tmo *= usec;
+ tmo /= (1000 * TIM_CLK_DIV);
+
+ endtime = get_timer_raw() + tmo;
+
+ do {
+ ulong now = get_timer_raw();
+ diff = endtime - now;
+ } while (diff >= 0);
+}
+
+/*
+ * 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_SYS_HZ;
+}
diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index 3d4f8923cf..97d8985ce8 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -28,6 +28,7 @@ LIB := $(obj)libspi_flash.a
COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o
COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o
COBJS-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.o
+COBJS-$(CONFIG_SPI_FLASH_WINBOND) += winbond.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index d1d81af0ec..fe7d9b7d6f 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2008 Atmel Corporation
*/
-#define DEBUG
+/*#define DEBUG*/
#include <common.h>
#include <malloc.h>
#include <spi.h>
@@ -134,6 +134,11 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
flash = spi_flash_probe_atmel(spi, idcode);
break;
#endif
+#ifdef CONFIG_SPI_FLASH_WINBOND
+ case 0xef:
+ flash = spi_flash_probe_winbond(spi, idcode);
+ break;
+#endif
#ifdef CONFIG_SPI_FLASH_STMICRO
case 0x20:
flash = spi_flash_probe_stmicro(spi, idcode);
diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c
new file mode 100644
index 0000000000..1e2b36f6ae
--- /dev/null
+++ b/drivers/mtd/spi/winbond.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2008, Network Appliance Inc.
+ * Author: Jason McMullan <[EMAIL PROTECTED]>
+ *
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi_flash.h>
+
+#include "spi_flash_internal.h"
+
+/* M25Pxx-specific commands */
+#define CMD_W25_WREN 0x06 /* Write Enable */
+#define CMD_W25_WRDI 0x04 /* Write Disable */
+#define CMD_W25_RDSR 0x05 /* Read Status Register */
+#define CMD_W25_WRSR 0x01 /* Write Status Register */
+#define CMD_W25_READ 0x03 /* Read Data Bytes */
+#define CMD_W25_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */
+#define CMD_W25_PP 0x02 /* Page Program */
+#define CMD_W25_SE 0x20 /* Sector (4K) Erase */
+#define CMD_W25_BE 0xd8 /* Block (64K) Erase */
+#define CMD_W25_CE 0xc7 /* Chip Erase */
+#define CMD_W25_DP 0xb9 /* Deep Power-down */
+#define CMD_W25_RES 0xab /* Release from DP, and Read Signature */
+
+#define WINBOND_ID_W25X16 0x3015
+#define WINBOND_ID_W25X32 0x3016
+#define WINBOND_ID_W25X64 0x3017
+
+#define WINBOND_SR_WIP (1 << 0) /* Write-in-Progress */
+
+struct winbond_spi_flash_params {
+ uint16_t id;
+ /* Log2 of page size in power-of-two mode */
+ uint8_t l2_page_size;
+ uint16_t pages_per_sector;
+ uint16_t sectors_per_block;
+ uint8_t nr_blocks;
+ const char *name;
+};
+
+struct winbond_spi_flash {
+ const struct winbond_spi_flash_params *params;
+ struct spi_flash flash;
+};
+
+static inline struct winbond_spi_flash *
+to_winbond_spi_flash(struct spi_flash *flash)
+{
+ return container_of(flash, struct winbond_spi_flash, flash);
+}
+
+static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
+ {
+ .id = WINBOND_ID_W25X16,
+ .l2_page_size = 8,
+ .pages_per_sector = 16,
+ .sectors_per_block = 16,
+ .nr_blocks = 32,
+ .name = "W25X16",
+ },
+ {
+ .id = WINBOND_ID_W25X32,
+ .l2_page_size = 8,
+ .pages_per_sector = 16,
+ .sectors_per_block = 16,
+ .nr_blocks = 64,
+ .name = "W25X32",
+ },
+ {
+ .id = WINBOND_ID_W25X64,
+ .l2_page_size = 8,
+ .pages_per_sector = 16,
+ .sectors_per_block = 16,
+ .nr_blocks = 128,
+ .name = "W25X64",
+ },
+};
+
+static int wait_state;
+
+static int winbond_wait_ready(struct spi_flash *flash, unsigned long timeout)
+{
+ struct spi_slave *spi = flash->spi;
+ unsigned long timebase;
+ int ret;
+ u8 status;
+ u8 cmd[4] = { CMD_W25_RDSR, 0xff, 0xff, 0xff };
+
+ ret = spi_xfer(spi, 32, &cmd[0], NULL, SPI_XFER_BEGIN);
+ if (ret) {
+ debug("SF: Failed to send command %02x: %d\n", cmd, ret);
+ return ret;
+ }
+
+ timebase = get_timer(0);
+ do {
+ ret = spi_xfer(spi, 8, NULL, &status, 0);
+ if (ret) {
+ debug("SF: Failed to get status for cmd %02x: %d\n", cmd, ret);
+ return -1;
+ }
+
+ if ((status & WINBOND_SR_WIP) == 0)
+ break;
+ else if ((status & WINBOND_SR_WIP) == 1)
+ wait_state++;
+
+ } while (1 || (get_timer(timebase) < timeout));
+
+ spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
+
+ if ((status & WINBOND_SR_WIP) == 0)
+ return 0;
+
+ debug("SF: Timed out on command %02x: %d\n", cmd, ret);
+ /* Timed out */
+ return -1;
+}
+
+/*
+ * Assemble the address part of a command for Winbond devices in
+ * non-power-of-two page size mode.
+ */
+static void winbond_build_address(struct winbond_spi_flash *stm, u8 *cmd, u32 offset)
+{
+ unsigned long page_addr;
+ unsigned long byte_addr;
+ unsigned long page_size;
+ unsigned int page_shift;
+
+ /*
+ * The "extra" space per page is the power-of-two page size
+ * divided by 32.
+ */
+ page_shift = stm->params->l2_page_size;
+ page_size = (1 << page_shift);
+ page_addr = offset / page_size;
+ byte_addr = offset % page_size;
+
+ cmd[0] = page_addr >> (16 - page_shift);
+ cmd[1] = page_addr << (page_shift - 8) | (byte_addr >> 8);
+ cmd[2] = byte_addr;
+}
+
+static int winbond_read_fast(struct spi_flash *flash,
+ u32 offset, size_t len, void *buf)
+{
+ struct winbond_spi_flash *stm = to_winbond_spi_flash(flash);
+ u8 cmd[5];
+
+ cmd[0] = CMD_READ_ARRAY_FAST;
+ winbond_build_address(stm, cmd + 1, offset);
+ cmd[4] = 0x00;
+
+ return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len);
+}
+
+static int winbond_write(struct spi_flash *flash,
+ u32 offset, size_t len, const void *buf)
+{
+ struct winbond_spi_flash *stm = to_winbond_spi_flash(flash);
+ unsigned long page_addr;
+ unsigned long byte_addr;
+ unsigned long page_size;
+ unsigned int page_shift;
+ size_t chunk_len;
+ size_t actual;
+ int ret;
+ u8 cmd[4];
+
+ page_shift = stm->params->l2_page_size;
+ page_size = (1 << page_shift);
+ page_addr = offset / page_size;
+ byte_addr = offset % page_size;
+
+ ret = spi_claim_bus(flash->spi);
+ if (ret) {
+ debug("SF: Unable to claim SPI bus\n");
+ return ret;
+ }
+
+ for (actual = 0; actual < len; actual += chunk_len) {
+ chunk_len = min(len - actual, page_size - byte_addr);
+
+ cmd[0] = CMD_W25_PP;
+ cmd[1] = page_addr >> (16 - page_shift);
+ cmd[2] = page_addr << (page_shift - 8) | (byte_addr >> 8);
+ cmd[3] = byte_addr;
+ debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %d\n",
+ buf + actual,
+ cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+
+ ret = spi_flash_cmd(flash->spi, CMD_W25_WREN, NULL, 0);
+ if (ret < 0) {
+ debug("SF: Enabling Write failed\n");
+ goto out;
+ }
+
+ ret = spi_flash_cmd_write(flash->spi, cmd, 4,
+ buf + actual, chunk_len);
+ if (ret < 0) {
+ debug("SF: Winbond Page Program failed\n");
+ goto out;
+ }
+
+ ret = winbond_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+ if (ret < 0) {
+ debug("SF: Winbond page programming timed out\n");
+ goto out;
+ }
+
+ page_addr++;
+ byte_addr = 0;
+ }
+
+ printf("Number of times wait: %d\n", wait_state);
+ wait_state = 0;
+
+ debug("SF: Winbond: Successfully programmed %u bytes @ 0x%x\n",
+ len, offset);
+ ret = 0;
+
+out:
+ spi_release_bus(flash->spi);
+ return ret;
+}
+
+int winbond_erase(struct spi_flash *flash, u32 offset, size_t len)
+{
+ struct winbond_spi_flash *stm = to_winbond_spi_flash(flash);
+ unsigned long sector_size;
+ unsigned int page_shift;
+ size_t actual;
+ int ret;
+ u8 cmd[4];
+
+ /*
+ * This function currently uses sector erase only.
+ * probably speed things up by using bulk erase
+ * when possible.
+ */
+
+ page_shift = stm->params->l2_page_size;
+ sector_size = (1 << page_shift) * stm->params->pages_per_sector;
+
+ if (offset % sector_size || len % sector_size) {
+ debug("SF: Erase offset/length not multiple of sector size\n");
+ return -1;
+ }
+
+ len /= sector_size;
+ cmd[0] = CMD_W25_SE;
+
+ ret = spi_claim_bus(flash->spi);
+ if (ret) {
+ debug("SF: Unable to claim SPI bus\n");
+ return ret;
+ }
+
+ for (actual = 0; actual < len; actual++) {
+ winbond_build_address(stm, &cmd[1], offset + actual * sector_size);
+ printf("Erase: %02x %02x %02x %02x\n",
+ cmd[0], cmd[1], cmd[2], cmd[3]);
+
+ ret = spi_flash_cmd(flash->spi, CMD_W25_WREN, NULL, 0);
+ if (ret < 0) {
+ debug("SF: Enabling Write failed\n");
+ goto out;
+ }
+
+ ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
+ if (ret < 0) {
+ debug("SF: Winbond sector erase failed\n");
+ goto out;
+ }
+
+ ret = winbond_wait_ready(flash, 2 * CONFIG_SYS_HZ); /* Up to 2 seconds */
+ if (ret < 0) {
+ debug("SF: Winbond sector erase timed out\n");
+ goto out;
+ }
+ }
+
+ debug("SF: Winbond: Successfully erased %u bytes @ 0x%x\n",
+ len * sector_size, offset);
+ ret = 0;
+
+out:
+ spi_release_bus(flash->spi);
+ return ret;
+}
+
+struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
+{
+ const struct winbond_spi_flash_params *params;
+ unsigned long page_size;
+ struct winbond_spi_flash *stm;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) {
+ params = &winbond_spi_flash_table[i];
+ if (params->id == ((idcode[1] << 8) | idcode[2]))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(winbond_spi_flash_table)) {
+ debug("SF: Unsupported Winbond ID %02x%02x\n",
+ idcode[1], idcode[2]);
+ return NULL;
+ }
+
+ stm = malloc(sizeof(struct winbond_spi_flash));
+ if (!stm) {
+ debug("SF: Failed to allocate memory\n");
+ return NULL;
+ }
+
+ stm->params = params;
+ stm->flash.spi = spi;
+ stm->flash.name = params->name;
+
+ /* Assuming power-of-two page size initially. */
+ page_size = 1 << params->l2_page_size;
+
+ stm->flash.write = winbond_write;
+ stm->flash.erase = winbond_erase;
+ stm->flash.read = winbond_read_fast;
+ stm->flash.size = page_size * params->pages_per_sector
+ * params->sectors_per_block
+ * params->nr_blocks;
+
+ debug("SF: Detected %s with page size %u, total %u bytes\n",
+ params->name, page_size, stm->flash.size);
+
+ return &stm->flash;
+}
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 15e0f7a66d..bf6e66719a 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o
COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
+COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
new file mode 100644
index 0000000000..ed895212bd
--- /dev/null
+++ b/drivers/spi/davinci_spi.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc <www.ti.com>
+ *
+ * Driver for SPI controller on DaVinci. Based on atmel_spi.c
+ * by Atmel Corporation
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * 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 <spi.h>
+#include <malloc.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/hardware.h>
+
+#include "davinci_spi.h"
+
+static unsigned int data1_reg_val;
+
+
+void spi_init()
+{
+ /* do nothing */
+
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ struct davinci_spi_slave *ds;
+ void *regs;
+ unsigned int fmt0;
+
+ ds = malloc(sizeof(struct davinci_spi_slave));
+ if (!ds)
+ return NULL;
+
+ ds->slave.bus = bus;
+ ds->slave.cs = cs;
+ ds->regs = CFG_SPI_BASE;
+ ds->freq = max_hz;
+
+ return &ds->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+ struct davinci_spi_slave *ds = to_davinci_spi(slave);
+
+ free(ds);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+ struct davinci_spi_slave *ds = to_davinci_spi(slave);
+ unsigned int scalar;
+
+ /* Enable the SPI hardware */
+ spi_writel(ds, GCR0, 0);
+ udelay(1000);
+ spi_writel(ds, GCR0, 1);
+
+ /* Set master mode, powered up and not activated */
+ spi_writel(ds, GCR1, 0x3);
+
+ /* CS, CLK, SIMO and SOMI are functional pins */
+ spi_writel(ds, PC0, (1 << 0) | (1 << 9) | (1 << 10) | (1 << 11));
+
+ /* setup format */
+ scalar = ((CFG_SPI_CLK / ds->freq) - 1 ) & 0xFF;
+
+ spi_writel(ds, FMT0, 8 | /* character length */
+ (scalar << 8) |
+ (1 << 16) | /* clock signal delayed by half clk cycle */
+ (0 << 17) | /* clock low in idle state - Mode 0 */
+ (0 << 20)); /* MSB shifted out first */
+
+ /* hold cs active at end of transfer until explicitly de-asserted */
+ data1_reg_val = (1 << 28) | (slave->cs << 16);
+ spi_writel(ds, DAT1, data1_reg_val);
+
+ /* including a minor delay. No science here. Should be good even with
+ * no delay
+ */
+ spi_writel(ds, DELAY, (50 << 24) | (50 << 16));
+
+ /* default chip select register */
+ spi_writel(ds, DEF, 1);
+
+ /* no interrupts */
+ spi_writel(ds, INT0, 0);
+ spi_writel(ds, LVL, 0);
+
+ /* enable SPI */
+ spi_writel(ds, GCR1, spi_readl(ds, GCR1) | (1 << 24));
+
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+ struct davinci_spi_slave *ds = to_davinci_spi(slave);
+
+ /* Disable the SPI hardware */
+ spi_writel(ds, GCR0, 0);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct davinci_spi_slave *ds = to_davinci_spi(slave);
+ unsigned int len_tx;
+ unsigned int len_rx;
+ unsigned int len;
+ int ret, i;
+ u32 status;
+ const u8 *txp = dout;
+ u8 *rxp = din;
+ u8 value, dummy = 0;
+
+ ret = 0;
+
+ if (bitlen == 0)
+ /* Finish any previously submitted transfers */
+ goto out;
+
+ /*
+ * It's not clear how non-8-bit-aligned transfers are supposed to be
+ * represented as a stream of bytes...this is a limitation of
+ * the current SPI interface - here we terminate on receiving such a
+ * transfer request.
+ */
+ if (bitlen % 8) {
+ /* Errors always terminate an ongoing transfer */
+ flags |= SPI_XFER_END;
+ goto out;
+ }
+
+ len = bitlen / 8;
+
+ /* do an empty read to clear the current contents */
+ spi_readl(ds, BUF);
+
+ /* keep writing and reading 1 byte until done */
+ for (i = 0; i < len; i++) {
+
+ /* wait till TXFULL is asserted */
+ while(spi_readl(ds, BUF) & (1 << 29));
+
+ /* write the data */
+ data1_reg_val &= ~0xFFFF;
+ if(txp) {
+ data1_reg_val |= *txp & 0xFF;
+ txp++;
+ }
+
+ /* write to DAT1 is required to keep the serial transfer going */
+ /* we just terminate when we reach the end */
+ if((i == (len -1)) && (flags & SPI_XFER_END)) {
+ spi_writel(ds, DAT1, data1_reg_val & ~(1 << 28)); /* clear CS hold */
+ } else {
+ spi_writel(ds, DAT1, data1_reg_val);
+ }
+
+
+ /* read the data - wait for data availability */
+ while(spi_readl(ds, BUF) & (1 << 31));
+
+ if(rxp) {
+ *rxp = spi_readl(ds, BUF) & 0xFF;
+ rxp++;
+ } else {
+ spi_readl(ds, BUF); /* simply drop the read character */
+ }
+
+ }
+
+ return 0;
+
+out:
+ if (flags & SPI_XFER_END) {
+ spi_writel(ds, DAT1, data1_reg_val & ~(1 << 28));
+ }
+
+ return 0;
+}
+
+
+#ifdef CONFIG_CMD_EEPROM
+
+/* ------------------------------------------------------------------------ *
+ * SPI ROM Definitions *
+ * ------------------------------------------------------------------------ */
+#define SPIROM_SIZE 0x00008000
+#define SPIROM_BASE 0x00000000
+#define SPIROM_PAGESIZE 32
+#define SPIROM_PAGEMASK 0xffffffc0
+
+/* ------------------------------------------------------------------------ *
+ * SPI ROM Commands *
+ * ------------------------------------------------------------------------ */
+#define SPIROM_CMD_WRSR 0x01
+#define SPIROM_CMD_WRITE 0x02
+#define SPIROM_CMD_READ 0x03
+#define SPIROM_CMD_WRDI 0x04
+#define SPIROM_CMD_RDSR 0x05
+#define SPIROM_CMD_WREN 0x06
+
+static struct spi_slave *slave;
+
+void spi_init_f(void)
+{
+ slave = spi_setup_slave(0, 0, 1*1024*1024, 0);
+ spi_claim_bus(slave);
+}
+
+static char spirombuf[3];
+
+/* ------------------------------------------------------------------------ *
+ * spirom_status( ) *
+ * ------------------------------------------------------------------------ */
+static unsigned char spi_get_status( )
+{
+ /* Issue read status command */
+ spirombuf[0] = SPIROM_CMD_RDSR;
+ spirombuf[1] = 0;
+
+ spi_xfer(slave, (2)*8, spirombuf, spirombuf, SPI_XFER_BEGIN | SPI_XFER_END);
+
+ return spirombuf[1];
+}
+
+ssize_t spi_write(uchar *addr, int alen, uchar *buffer, int len)
+{
+
+ spirombuf[0] = SPIROM_CMD_WREN;
+ spi_xfer(slave, 1*8, spirombuf, NULL, SPI_XFER_BEGIN | SPI_XFER_END);
+
+ /* Create command block for program operation */
+ spirombuf[0] = SPIROM_CMD_WRITE;
+ spirombuf[1] = addr[0];
+ spirombuf[2] = addr[1];
+
+ spi_xfer(slave, 3 * 8, spirombuf, NULL, SPI_XFER_BEGIN);
+ spi_xfer(slave, len * 8, buffer, NULL, SPI_XFER_END);
+
+ /* Wait while busy */
+ while( (spi_get_status( ) & 0x01 ) );
+
+ return len;
+}
+
+ssize_t spi_read(uchar *addr, int alen, uchar *buffer, int len)
+{
+ spirombuf[0] = 0x3;
+ spirombuf[1] = addr[0];
+ spirombuf[2] = addr[1];
+
+ spi_xfer(slave, 3*8, spirombuf, NULL, SPI_XFER_BEGIN);
+ spi_xfer(slave, len*8, NULL, buffer, SPI_XFER_END);
+
+ return len;
+}
+
+#endif
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h
new file mode 100644
index 0000000000..0f2b0877ba
--- /dev/null
+++ b/drivers/spi/davinci_spi.h
@@ -0,0 +1,46 @@
+/*
+ * Register definitions for the DaVinci SPI Controller
+ */
+
+/* Register offsets */
+#define DAVINCI_SPI_GCR0 0x0000
+#define DAVINCI_SPI_GCR1 0x0004
+#define DAVINCI_SPI_INT0 0x0008
+#define DAVINCI_SPI_LVL 0x000c
+#define DAVINCI_SPI_FLG 0x0010
+#define DAVINCI_SPI_PC0 0x0014
+#define DAVINCI_SPI_PC1 0x0018
+#define DAVINCI_SPI_PC2 0x001c
+#define DAVINCI_SPI_PC3 0x0020
+#define DAVINCI_SPI_PC4 0x0024
+#define DAVINCI_SPI_PC5 0x0028
+#define DAVINCI_SPI_DAT0 0x0038
+#define DAVINCI_SPI_DAT1 0x003c
+#define DAVINCI_SPI_BUF 0x0040
+#define DAVINCI_SPI_EMU 0x0044
+#define DAVINCI_SPI_DELAY 0x0048
+#define DAVINCI_SPI_DEF 0x004c
+#define DAVINCI_SPI_FMT0 0x0050
+#define DAVINCI_SPI_FMT1 0x0054
+#define DAVINCI_SPI_FMT2 0x0058
+#define DAVINCI_SPI_FMT3 0x005c
+#define DAVINCI_SPI_INTVEC0 0x0060
+#define DAVINCI_SPI_INTVEC1 0x0064
+
+struct davinci_spi_slave {
+ struct spi_slave slave;
+ void *regs;
+ u32 mr;
+ unsigned int freq;
+};
+
+static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave)
+{
+ return container_of(slave, struct davinci_spi_slave, slave);
+}
+
+#define spi_readl(as, reg) \
+ readl(CFG_SPI_BASE + DAVINCI_SPI_##reg)
+#define spi_writel(as, reg, value) \
+ writel(value, CFG_SPI_BASE + DAVINCI_SPI_##reg)
+
diff --git a/drivers/spi/spirom.c b/drivers/spi/spirom.c
new file mode 100644
index 0000000000..f367335c0a
--- /dev/null
+++ b/drivers/spi/spirom.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2007 b7 Spectrum Digital Incorporated.
+ * All rights reserved. Property of Spectrum Digital Incorporated.
+ */
+
+/*
+ * SPI ROM interface
+ *
+ */
+
+#include "spirom.h"
+
+static Uint8 spirombuf[SPIROM_PAGESIZE + 5];
+static Uint8 statusbuf[8];
+static Uint32 spidat1;
+
+/* ------------------------------------------------------------------------ *
+ * *
+ * _wait( delay ) *
+ * Wait in a software loop for 'x' delay *
+ * *
+ * ------------------------------------------------------------------------ */
+void DAVINCIHD_wait( Uint32 delay )
+{
+ volatile Uint32 i;
+ for ( i = 0 ; i < delay ; i++ ){ };
+}
+
+
+/* ------------------------------------------------------------------------ *
+ * spirom_init( ) *
+ * ------------------------------------------------------------------------ */
+void spirom_init( )
+{
+ /* Reset SPI */
+ SPI_SPIGCR0 = 0;
+ _wait( 1000 );
+
+ /* Release SPI */
+ SPI_SPIGCR0 = 1;
+
+ /* SPI 4-Pin Mode setup */
+ SPI_SPIGCR1 = 0
+ | ( 0 << 24 )
+ | ( 0 << 16 )
+ | ( 1 << 1 )
+ | ( 1 << 0 );
+
+ SPI_SPIPC0 = 0
+ | ( 1 << 11 ) // DI
+ | ( 1 << 10 ) // DO
+ | ( 1 << 9 ) // CLK
+ | ( 1 << 1 ) // EN1
+ | ( 1 << 0 ); // EN0
+
+ SPI_SPIFMT0 = 0
+ | ( 0 << 20 ) // SHIFTDIR
+ | ( 0 << 17 ) // Polarity
+ | ( 1 << 16 ) // Phase
+ | ( 50 << 8 ) // Prescale
+ | ( 8 << 0 ); // Char Len
+
+ spidat1 = 0
+ | ( 1 << 28 ) // CSHOLD
+ | ( 0 << 24 ) // Format [0]
+ | ( 2 << 16 ) // CSNR [only CS0 enbled]
+ | ( 0 << 0 ); //
+
+ SPI_SPIDAT1 = spidat1;
+
+ SPI_SPIDELAY = 0
+ | ( 8 << 24 ) // C2TDELAY
+ | ( 8 << 16 ); // T2CDELAY
+
+ SPI_SPIDEF = 0
+ | ( 1 << 1 ) // EN1 inactive high
+ | ( 1 << 0 ); // EN0 inactive high
+
+ SPI_SPIINT = 0
+ | ( 0 << 16 ) //
+ | ( 0 << 8 ) //
+ | ( 0 << 6 ) //
+ | ( 1 << 4 ); //
+
+ SPI_SPILVL = 0
+ | ( 0 << 8 ) // EN0
+ | ( 0 << 6 ) // EN0
+ | ( 0 << 4 ); // EN0
+
+
+ /* Enable SPI */
+ SPI_SPIGCR1 |= ( 1 << 24 );
+}
+
+/* ------------------------------------------------------------------------ *
+ * spirom_cycle( buf, len ) *
+ * *
+ * Execute a SPI spirom data transfer cycle. Each byte in buf is shifted *
+ * out and replaced with data coming back from the spirom. *
+ * ------------------------------------------------------------------------ */
+void spirom_cycle( Uint8 *buf, Uint16 len )
+{
+ Uint16 i;
+
+ /* Clear any old data */
+ SPI_SPIBUF;
+
+ /* SPIROM access cycle */
+ for ( i = 0 ; i <= len ; i++ )
+ {
+ /* Wait for transmit ready */
+ while ( SPI_SPIBUF & 0x10000000 );
+
+ if ( i == len )
+ SPI_SPIDAT1 = ( spidat1 & 0x0ffcffff ) | buf[i];
+ else
+ SPI_SPIDAT1 = spidat1 | buf[i];
+
+ /* Wait for receive data ready */
+ while ( SPI_SPIBUF & 0x80000000 );
+
+ /* Read 1 byte */
+ buf[i] = SPI_SPIBUF;
+ }
+}
+
+/* ------------------------------------------------------------------------ *
+ * spirom_status( ) *
+ * ------------------------------------------------------------------------ */
+Uint8 spirom_status( )
+{
+ /* Issue read status command */
+ statusbuf[0] = SPIROM_CMD_RDSR;
+ statusbuf[1] = 0;
+
+ spirom_cycle( statusbuf, 2 );
+
+ return statusbuf[1];
+}
+
+/* ------------------------------------------------------------------------ *
+ * spirom_read( src, dst, length ) *
+ * ------------------------------------------------------------------------ */
+void spirom_read( Uint16 src, Uint32 dst, Uint32 length )
+{
+ Int32 i;
+ Uint8 *psrc, *pdst;
+
+ // Setup command
+ spirombuf[0] = SPIROM_CMD_READ;
+ spirombuf[1] = ( src >> 8 );
+ spirombuf[2] = ( src >> 0 );
+
+ // Execute spirom read cycle
+ spirom_cycle( spirombuf, length + 3 );
+
+ // Copy returned data
+ pdst = ( Uint8 * )dst;
+ psrc = spirombuf + 3;
+ for ( i = 0 ; i < length ; i++ )
+ *pdst++ = *psrc++;
+}
+
+/* ------------------------------------------------------------------------ *
+ * spirom_write( src, dst, length ) *
+ * ------------------------------------------------------------------------ */
+void spirom_write( Uint32 src, Uint16 dst, Uint32 length )
+{
+ Int32 i;
+ Int32 bytes_left;
+ Int32 bytes_to_program;
+ Uint8 *psrc;
+
+ /* Establish source */
+ psrc = ( Uint8 * )src;
+ bytes_left = length;
+
+ while ( bytes_left > 0 )
+ {
+ bytes_to_program = bytes_left;
+
+ /* Most to program is SPIROM_CMD_BLOCKSIZE */
+ if ( bytes_to_program > SPIROM_PAGESIZE )
+ bytes_to_program = SPIROM_PAGESIZE;
+
+ /* Make sure you don't run off the end of a block */
+ if ( ( dst & SPIROM_PAGEMASK ) != ( ( dst + bytes_to_program ) & SPIROM_PAGEMASK ) )
+ bytes_to_program -= ( dst + bytes_to_program ) - ( ( dst + bytes_to_program ) & SPIROM_PAGEMASK );
+
+ /* Issue WPEN */
+ spirombuf[0] = SPIROM_CMD_WREN;
+ spirom_cycle( spirombuf, 0 );
+
+ /* Create command block for program operation */
+ spirombuf[0] = SPIROM_CMD_WRITE;
+ spirombuf[1] = ( Uint8 )( dst >> 8 );
+ spirombuf[2] = ( Uint8 )( dst );
+
+ for ( i = 0 ; i < bytes_to_program ; i++ )
+ spirombuf[3+i] = *psrc++;
+
+ /* Execute write command */
+ spirom_cycle( spirombuf, bytes_to_program + 2 );
+
+ /* Wait while busy */
+ while( ( spirom_status( ) & 0x01 ) );
+
+ /* Get ready for next iteration */
+ bytes_left -= bytes_to_program;
+ dst += bytes_to_program;
+ }
+}
diff --git a/drivers/spi/spirom.h b/drivers/spi/spirom.h
new file mode 100644
index 0000000000..b945f59ce0
--- /dev/null
+++ b/drivers/spi/spirom.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2007 by Spectrum Digital Incorporated.
+ * All rights reserved. Property of Spectrum Digital Incorporated.
+ */
+
+/*
+ * SPI ROM header file
+ *
+ */
+
+#ifndef SPIROM_
+#define SPIROM_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "davincihd.h"
+
+/* ------------------------------------------------------------------------ *
+ * SPI ROM Definitions *
+ * ------------------------------------------------------------------------ */
+#define SPIROM_SIZE 0x00008000
+#define SPIROM_BASE 0x00000000
+#define SPIROM_PAGESIZE 32
+#define SPIROM_PAGEMASK 0xffffffc0
+
+/* ------------------------------------------------------------------------ *
+ * SPI ROM Commands *
+ * ------------------------------------------------------------------------ */
+#define SPIROM_CMD_WRSR 0x01
+#define SPIROM_CMD_WRITE 0x02
+#define SPIROM_CMD_READ 0x03
+#define SPIROM_CMD_WRDI 0x04
+#define SPIROM_CMD_RDSR 0x05
+#define SPIROM_CMD_WREN 0x06
+
+/* ------------------------------------------------------------------------ *
+ * SPI Controller *
+ * ------------------------------------------------------------------------ */
+#define SPI_BASE 0x01c66800
+#define SPI_SPIGCR0 *( volatile Uint32* )( SPI_BASE + 0x0 )
+#define SPI_SPIGCR1 *( volatile Uint32* )( SPI_BASE + 0x4 )
+#define SPI_SPIINT *( volatile Uint32* )( SPI_BASE + 0x8 )
+#define SPI_SPILVL *( volatile Uint32* )( SPI_BASE + 0xc )
+#define SPI_SPIFLG *( volatile Uint32* )( SPI_BASE + 0x10 )
+#define SPI_SPIPC0 *( volatile Uint32* )( SPI_BASE + 0x14 )
+#define SPI_SPIPC2 *( volatile Uint32* )( SPI_BASE + 0x1c )
+#define SPI_SPIDAT1_TOP *( volatile Uint16* )( SPI_BASE + 0x3c )
+#define SPI_SPIDAT1 *( volatile Uint32* )( SPI_BASE + 0x3c )
+#define SPI_SPIDAT1_PTR16 *( volatile Uint16* )( SPI_BASE + 0x3e )
+#define SPI_SPIDAT1_PTR8 *( volatile Uint8* ) ( SPI_BASE + 0x3f )
+#define SPI_SPIBUF *( volatile Uint32* )( SPI_BASE + 0x40 )
+#define SPI_SPIBUF_PTR16 *( volatile Uint16* )( SPI_BASE + 0x42 )
+#define SPI_SPIBUF_PTR8 *( volatile Uint8* ) ( SPI_BASE + 0x43 )
+#define SPI_SPIEMU *( volatile Uint32* )( SPI_BASE + 0x44 )
+#define SPI_SPIDELAY *( volatile Uint32* )( SPI_BASE + 0x48 )
+#define SPI_SPIDEF *( volatile Uint32* )( SPI_BASE + 0x4c )
+#define SPI_SPIFMT0 *( volatile Uint32* )( SPI_BASE + 0x50 )
+#define SPI_SPIFMT1 *( volatile Uint32* )( SPI_BASE + 0x54 )
+#define SPI_SPIFMT2 *( volatile Uint32* )( SPI_BASE + 0x58 )
+#define SPI_SPIFMT3 *( volatile Uint32* )( SPI_BASE + 0x5c )
+#define SPI_INTVEC0 *( volatile Uint32* )( SPI_BASE + 0x60 )
+#define SPI_INTVEC1 *( volatile Uint32* )( SPI_BASE + 0x64 )
+
+/* ------------------------------------------------------------------------ *
+ * Prototype *
+ * ------------------------------------------------------------------------ */
+void spirom_init( );
+void spirom_read( Uint16 src, Uint32 dst, Uint32 length );
+void spirom_write( Uint32 src, Uint16 dst, Uint32 length );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-da8xx/emac_defs.h b/include/asm-arm/arch-da8xx/emac_defs.h
new file mode 100644
index 0000000000..6120a595e3
--- /dev/null
+++ b/include/asm-arm/arch-da8xx/emac_defs.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Based on:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * dm644x_emac.h
+ *
+ * TI DaVinci (DM644X) EMAC peripheral driver header for DV-EVM
+ *
+ * Copyright (C) 2005 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+
+ * Modifications:
+ * ver. 1.0: Sep 2005, TI PSP Team - Created EMAC version for uBoot.
+ *
+ */
+
+#ifndef _DM644X_EMAC_H_
+#define _DM644X_EMAC_H_
+
+#include <asm/arch/hardware.h>
+
+#define EMAC_BASE_ADDR DAVINCI_EMAC_CNTRL_REGS_BASE
+#define EMAC_WRAPPER_BASE_ADDR DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE
+#define EMAC_WRAPPER_RAM_ADDR DAVINCI_EMAC_WRAPPER_RAM_BASE
+#define EMAC_MDIO_BASE_ADDR DAVINCI_MDIO_CNTRL_REGS_BASE
+
+/* MDIO module input frequency */
+#define EMAC_MDIO_BUS_FREQ clk_get(DAVINCI_MDIO_CLKID)
+
+/* MDIO clock output frequency */
+#define EMAC_MDIO_CLOCK_FREQ 2000000 /* 2.0 MHz */
+
+/* Ethernet Min/Max packet size */
+#define EMAC_MIN_ETHERNET_PKT_SIZE 60
+#define EMAC_MAX_ETHERNET_PKT_SIZE 1518
+#define EMAC_PKT_ALIGN 18 /* 1518 + 18 = 1536 (packet aligned on 32 byte boundry) */
+
+/* Number of RX packet buffers
+ * NOTE: Only 1 buffer supported as of now
+ */
+#define EMAC_MAX_RX_BUFFERS 10
+
+
+/***********************************************
+ ******** Internally used macros ***************
+ ***********************************************/
+
+#define EMAC_CH_TX 1
+#define EMAC_CH_RX 0
+
+/* Each descriptor occupies 4 words, lets start RX desc's at 0 and
+ * reserve space for 64 descriptors max
+ */
+#define EMAC_RX_DESC_BASE 0x0
+#define EMAC_TX_DESC_BASE 0x1000
+
+/* EMAC Teardown value */
+#define EMAC_TEARDOWN_VALUE 0xfffffffc
+
+/* MII Status Register */
+#define MII_STATUS_REG 1
+
+/* Number of statistics registers */
+#define EMAC_NUM_STATS 36
+
+
+/* EMAC Descriptor */
+typedef volatile struct _emac_desc
+{
+ u_int32_t next; /* Pointer to next descriptor in chain */
+ u_int8_t *buffer; /* Pointer to data buffer */
+ u_int32_t buff_off_len; /* Buffer Offset(MSW) and Length(LSW) */
+ u_int32_t pkt_flag_len; /* Packet Flags(MSW) and Length(LSW) */
+} emac_desc;
+
+/* CPPI bit positions */
+#define EMAC_CPPI_SOP_BIT (0x80000000)
+#define EMAC_CPPI_EOP_BIT (0x40000000)
+#define EMAC_CPPI_OWNERSHIP_BIT (0x20000000)
+#define EMAC_CPPI_EOQ_BIT (0x10000000)
+#define EMAC_CPPI_TEARDOWN_COMPLETE_BIT (0x08000000)
+#define EMAC_CPPI_PASS_CRC_BIT (0x04000000)
+
+#define EMAC_CPPI_RX_ERROR_FRAME (0x03fc0000)
+
+#define EMAC_MACCONTROL_RMIISPEED_100 (1 << 15)
+#define EMAC_MACCONTROL_MIIEN_ENABLE (0x20)
+#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE (0x1)
+
+#define EMAC_RXMBPENABLE_RXCAFEN_ENABLE (0x200000)
+#define EMAC_RXMBPENABLE_RXBROADEN (0x2000)
+
+
+#define MDIO_CONTROL_IDLE (0x80000000)
+#define MDIO_CONTROL_ENABLE (0x40000000)
+#define MDIO_CONTROL_FAULT_ENABLE (0x40000)
+#define MDIO_CONTROL_FAULT (0x80000)
+#define MDIO_USERACCESS0_GO (0x80000000)
+#define MDIO_USERACCESS0_WRITE_READ (0x0)
+#define MDIO_USERACCESS0_WRITE_WRITE (0x40000000)
+#define MDIO_USERACCESS0_ACK (0x20000000)
+
+/* Ethernet MAC Registers Structure */
+typedef struct {
+ dv_reg TXIDVER;
+ dv_reg TXCONTROL;
+ dv_reg TXTEARDOWN;
+ u_int8_t RSVD0[4];
+ dv_reg RXIDVER;
+ dv_reg RXCONTROL;
+ dv_reg RXTEARDOWN;
+ u_int8_t RSVD1[100];
+ dv_reg TXINTSTATRAW;
+ dv_reg TXINTSTATMASKED;
+ dv_reg TXINTMASKSET;
+ dv_reg TXINTMASKCLEAR;
+ dv_reg MACINVECTOR;
+ u_int8_t RSVD2[12];
+ dv_reg RXINTSTATRAW;
+ dv_reg RXINTSTATMASKED;
+ dv_reg RXINTMASKSET;
+ dv_reg RXINTMASKCLEAR;
+ dv_reg MACINTSTATRAW;
+ dv_reg MACINTSTATMASKED;
+ dv_reg MACINTMASKSET;
+ dv_reg MACINTMASKCLEAR;
+ u_int8_t RSVD3[64];
+ dv_reg RXMBPENABLE;
+ dv_reg RXUNICASTSET;
+ dv_reg RXUNICASTCLEAR;
+ dv_reg RXMAXLEN;
+ dv_reg RXBUFFEROFFSET;
+ dv_reg RXFILTERLOWTHRESH;
+ u_int8_t RSVD4[8];
+ dv_reg RX0FLOWTHRESH;
+ dv_reg RX1FLOWTHRESH;
+ dv_reg RX2FLOWTHRESH;
+ dv_reg RX3FLOWTHRESH;
+ dv_reg RX4FLOWTHRESH;
+ dv_reg RX5FLOWTHRESH;
+ dv_reg RX6FLOWTHRESH;
+ dv_reg RX7FLOWTHRESH;
+ dv_reg RX0FREEBUFFER;
+ dv_reg RX1FREEBUFFER;
+ dv_reg RX2FREEBUFFER;
+ dv_reg RX3FREEBUFFER;
+ dv_reg RX4FREEBUFFER;
+ dv_reg RX5FREEBUFFER;
+ dv_reg RX6FREEBUFFER;
+ dv_reg RX7FREEBUFFER;
+ dv_reg MACCONTROL;
+ dv_reg MACSTATUS;
+ dv_reg EMCONTROL;
+ dv_reg FIFOCONTROL;
+ dv_reg MACCONFIG;
+ dv_reg SOFTRESET;
+ u_int8_t RSVD5[88];
+ dv_reg MACSRCADDRLO;
+ dv_reg MACSRCADDRHI;
+ dv_reg MACHASH1;
+ dv_reg MACHASH2;
+ dv_reg BOFFTEST;
+ dv_reg TPACETEST;
+ dv_reg RXPAUSE;
+ dv_reg TXPAUSE;
+ u_int8_t RSVD6[16];
+ dv_reg RXGOODFRAMES;
+ dv_reg RXBCASTFRAMES;
+ dv_reg RXMCASTFRAMES;
+ dv_reg RXPAUSEFRAMES;
+ dv_reg RXCRCERRORS;
+ dv_reg RXALIGNCODEERRORS;
+ dv_reg RXOVERSIZED;
+ dv_reg RXJABBER;
+ dv_reg RXUNDERSIZED;
+ dv_reg RXFRAGMENTS;
+ dv_reg RXFILTERED;
+ dv_reg RXQOSFILTERED;
+ dv_reg RXOCTETS;
+ dv_reg TXGOODFRAMES;
+ dv_reg TXBCASTFRAMES;
+ dv_reg TXMCASTFRAMES;
+ dv_reg TXPAUSEFRAMES;
+ dv_reg TXDEFERRED;
+ dv_reg TXCOLLISION;
+ dv_reg TXSINGLECOLL;
+ dv_reg TXMULTICOLL;
+ dv_reg TXEXCESSIVECOLL;
+ dv_reg TXLATECOLL;
+ dv_reg TXUNDERRUN;
+ dv_reg TXCARRIERSENSE;
+ dv_reg TXOCTETS;
+ dv_reg FRAME64;
+ dv_reg FRAME65T127;
+ dv_reg FRAME128T255;
+ dv_reg FRAME256T511;
+ dv_reg FRAME512T1023;
+ dv_reg FRAME1024TUP;
+ dv_reg NETOCTETS;
+ dv_reg RXSOFOVERRUNS;
+ dv_reg RXMOFOVERRUNS;
+ dv_reg RXDMAOVERRUNS;
+ u_int8_t RSVD7[624];
+ dv_reg MACADDRLO;
+ dv_reg MACADDRHI;
+ dv_reg MACINDEX;
+ u_int8_t RSVD8[244];
+ dv_reg TX0HDP;
+ dv_reg TX1HDP;
+ dv_reg TX2HDP;
+ dv_reg TX3HDP;
+ dv_reg TX4HDP;
+ dv_reg TX5HDP;
+ dv_reg TX6HDP;
+ dv_reg TX7HDP;
+ dv_reg RX0HDP;
+ dv_reg RX1HDP;
+ dv_reg RX2HDP;
+ dv_reg RX3HDP;
+ dv_reg RX4HDP;
+ dv_reg RX5HDP;
+ dv_reg RX6HDP;
+ dv_reg RX7HDP;
+ dv_reg TX0CP;
+ dv_reg TX1CP;
+ dv_reg TX2CP;
+ dv_reg TX3CP;
+ dv_reg TX4CP;
+ dv_reg TX5CP;
+ dv_reg TX6CP;
+ dv_reg TX7CP;
+ dv_reg RX0CP;
+ dv_reg RX1CP;
+ dv_reg RX2CP;
+ dv_reg RX3CP;
+ dv_reg RX4CP;
+ dv_reg RX5CP;
+ dv_reg RX6CP;
+ dv_reg RX7CP;
+} emac_regs;
+
+/* EMAC Wrapper Registers Structure */
+typedef struct {
+ dv_reg REV;
+ dv_reg SOFTRESET;
+ dv_reg INTCONTROL;
+ dv_reg C0RXTHRESHEN;
+ dv_reg C0RXEN;
+ dv_reg C0TXEN;
+ dv_reg C0MISCEN;
+ dv_reg C1RXTHRESHEN;
+ dv_reg C1RXEN;
+ dv_reg C1TXEN;
+ dv_reg C1MISCEN;
+ dv_reg C2RXTHRESHEN;
+ dv_reg C2RXEN;
+ dv_reg C2TXEN;
+ dv_reg C2MISCEN;
+ dv_reg C0RXTHRESHSTAT;
+ dv_reg C0RXSTAT;
+ dv_reg C0TXSTAT;
+ dv_reg C0MISCSTAT;
+ dv_reg C1RXTHRESHSTAT;
+ dv_reg C1RXSTAT;
+ dv_reg C1TXSTAT;
+ dv_reg C1MISCSTAT;
+ dv_reg C2RXTHRESHSTAT;
+ dv_reg C2RXSTAT;
+ dv_reg C2TXSTAT;
+ dv_reg C2MISCSTAT;
+ dv_reg C0RXIMAX;
+ dv_reg C0TXIMAX;
+ dv_reg C1RXIMAX;
+ dv_reg C1TXIMAX;
+ dv_reg C2RXIMAX;
+ dv_reg C2TXIMAX;
+} ewrap_regs;
+
+
+/* EMAC MDIO Registers Structure */
+typedef struct {
+ dv_reg VERSION;
+ dv_reg CONTROL;
+ dv_reg ALIVE;
+ dv_reg LINK;
+ dv_reg LINKINTRAW;
+ dv_reg LINKINTMASKED;
+ u_int8_t RSVD0[8];
+ dv_reg USERINTRAW;
+ dv_reg USERINTMASKED;
+ dv_reg USERINTMASKSET;
+ dv_reg USERINTMASKCLEAR;
+ u_int8_t RSVD1[80];
+ dv_reg USERACCESS0;
+ dv_reg USERPHYSEL0;
+ dv_reg USERACCESS1;
+ dv_reg USERPHYSEL1;
+} mdio_regs;
+
+int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data);
+int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data);
+
+typedef struct
+{
+ char name[64];
+ int (*init)(int phy_addr);
+ int (*is_phy_connected)(int phy_addr);
+ int (*get_link_speed)(int phy_addr);
+ int (*auto_negotiate)(int phy_addr);
+} phy_t;
+
+#endif /* _DM644X_EMAC_H_ */
diff --git a/include/asm-arm/arch-da8xx/emif_defs.h b/include/asm-arm/arch-da8xx/emif_defs.h
new file mode 100644
index 0000000000..646fc77469
--- /dev/null
+++ b/include/asm-arm/arch-da8xx/emif_defs.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * 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 _EMIF_DEFS_H_
+#define _EMIF_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+typedef struct {
+ dv_reg ERCSR;
+ dv_reg AWCCR;
+ dv_reg SDBCR;
+ dv_reg SDRCR;
+ dv_reg AB1CR;
+ dv_reg AB2CR;
+ dv_reg AB3CR;
+ dv_reg AB4CR;
+ dv_reg SDTIMR;
+ dv_reg DDRSR;
+ dv_reg DDRPHYCR;
+ dv_reg DDRPHYSR;
+ dv_reg TOTAR;
+ dv_reg TOTACTR;
+ dv_reg DDRPHYID_REV;
+ dv_reg SDSRETR;
+ dv_reg EIRR;
+ dv_reg EIMR;
+ dv_reg EIMSR;
+ dv_reg EIMCR;
+ dv_reg IOCTRLR;
+ dv_reg IOSTATR;
+ u_int8_t RSVD0[8];
+ dv_reg NANDFCR;
+ dv_reg NANDFSR;
+ u_int8_t RSVD1[8];
+ dv_reg NANDF1ECC;
+ dv_reg NANDF2ECC;
+ dv_reg NANDF3ECC;
+ dv_reg NANDF4ECC;
+} emif_registers;
+
+typedef emif_registers *emifregs;
+#endif
diff --git a/include/asm-arm/arch-da8xx/hardware.h b/include/asm-arm/arch-da8xx/hardware.h
new file mode 100644
index 0000000000..aafbd77f2f
--- /dev/null
+++ b/include/asm-arm/arch-da8xx/hardware.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc
+ *
+ * Based on hardware.h for DaVinci. Original Copyrights follow.
+ *
+ * Sergey Kubushyn <ksi@koi8.net>
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Based on:
+ *
+ * -------------------------------------------------------------------------
+ *
+ * linux/include/asm-arm/arch-davinci/hardware.h
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <config.h>
+
+#ifndef __ASSEMBLY__
+
+#include <asm/sizes.h>
+
+#define REG(addr) (*(volatile unsigned int *)(addr))
+#define REG_P(addr) ((volatile unsigned int *)(addr))
+
+typedef volatile unsigned int dv_reg;
+typedef volatile unsigned int * dv_reg_p;
+
+#endif
+
+/*
+ * Base register addresses
+ */
+#define DAVINCI_UART0_BASE (0x01c42000)
+#define DAVINCI_UART1_BASE (0x01d0c000)
+#define DAVINCI_UART2_BASE (0x01d0d000)
+#define DAVINCI_I2C0_BASE (0x01c22000)
+#define DAVINCI_I2C1_BASE (0x01e28000)
+#define DAVINCI_TIMER0_BASE (0x01c20000)
+#define DAVINCI_TIMER1_BASE (0x01c21000)
+#define DAVINCI_WDOG_BASE (0x01c21000)
+#define DAVINCI_PLL_CNTRL0_BASE (0x01c11000)
+#define DAVINCI_PSC0_BASE (0x01c10000)
+#define DAVINCI_PSC1_BASE (0x01e27000)
+#define DAVINCI_SPI0_BASE (0x01c41000)
+#define DAVINCI_SPI1_BASE (0x01e12000)
+#define DAVINCI_GPIO_BASE (0x01e26000)
+#define DAVINCI_EMAC_CNTRL_REGS_BASE (0x01e23000)
+#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE (0x01e22000)
+#define DAVINCI_EMAC_WRAPPER_RAM_BASE (0x01e20000)
+#define DAVINCI_MDIO_CNTRL_REGS_BASE (0x01e24000)
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE (0x68000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x40000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x60000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x62000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE4_BASE (0x64000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE5_BASE (0x66000000)
+#define DAVINCI_DDR_EMIF_CTRL_BASE (0xb0000000)
+#define DAVINCI_DDR_EMIF_DATA_BASE (0xc0000000)
+#define DAVINCI_INTC_BASE (0xfffee000)
+#define DAVINCI_BOOTCFG_BASE (0x01c14000)
+
+/* Clock IDs */
+#define DAVINCI_PLLM_CLKID (0xFF + 0)
+#define DAVINCI_PLLC_CLKID (0xFF + 1)
+#define DAVINCI_AUXCLK_CLKID (0xFF + 2)
+#define DAVINCI_MDIO_CLKID 4
+#define DAVINCI_SPI0_CLKID 2
+#define DAVINCI_UART2_CLKID 2
+#define DAVINCI_ARM_CLKID 6
+
+/* Power and Sleep Controller (PSC) Domains */
+#define DAVINCI_GPSC_ARMDOMAIN 0
+#define DAVINCI_GPSC_DSPDOMAIN 1
+
+/* LPSCs in PSC0 */
+#define DAVINCI_LPSC_TPCC 0
+#define DAVINCI_LPSC_TPTC0 1
+#define DAVINCI_LPSC_TPTC1 2
+#define DAVINCI_LPSC_AEMIF 3
+#define DAVINCI_LPSC_SPI0 4
+#define DAVINCI_LPSC_MMC_SD 5
+#define DAVINCI_LPSC_AINTC 6
+#define DAVINCI_LPSC_ARM_RAM_ROM 7
+#define DAVINCI_LPSC_SECCTL_KEYMGR 8
+#define DAVINCI_LPSC_UART0 9
+#define DAVINCI_LPSC_SCR0 10
+#define DAVINCI_LPSC_SCR1 11
+#define DAVINCI_LPSC_SCR2 12
+#define DAVINCI_LPSC_DMAX 13
+#define DAVINCI_LPSC_ARM 14
+#define DAVINCI_LPSC_GEM 15
+
+/* for LPSCs in PSC1, 32 + actual id is being used for differentiation */
+#define DAVINCI_LPSC_USB11 (32 + 1)
+#define DAVINCI_LPSC_USB20 (32 + 2)
+#define DAVINCI_LPSC_GPIO (32 + 3)
+#define DAVINCI_LPSC_UHPI (32 + 4)
+#define DAVINCI_LPSC_EMAC (32 + 5)
+#define DAVINCI_LPSC_DDR_EMIF (32 + 6)
+#define DAVINCI_LPSC_McASP0 (32 + 7)
+#define DAVINCI_LPSC_McASP1 (32 + 8)
+#define DAVINCI_LPSC_McASP2 (32 + 9)
+#define DAVINCI_LPSC_SPI1 (32 + 10)
+#define DAVINCI_LPSC_I2C1 (32 + 11)
+#define DAVINCI_LPSC_UART1 (32 + 12)
+#define DAVINCI_LPSC_UART2 (32 + 13)
+#define DAVINCI_LPSC_LCDC (32 + 16)
+#define DAVINCI_LPSC_ePWM (32 + 17)
+#define DAVINCI_LPSC_eCAP (32 + 20)
+#define DAVINCI_LPSC_eQEP (32 + 21)
+#define DAVINCI_LPSC_SCR_P0 (32 + 22)
+#define DAVINCI_LPSC_SCR_P1 (32 + 23)
+#define DAVINCI_LPSC_CR_P3 (32 + 26)
+#define DAVINCI_LPSC_L3_CBA_RAM (32 + 31)
+
+/* Some PSC defines */
+
+#define PSC0_MDCTL (DAVINCI_PSC0_BASE + 0xa00)
+#define PSC0_MDSTAT (DAVINCI_PSC0_BASE + 0x800)
+#define PSC0_PTCMD (DAVINCI_PSC0_BASE + 0x120)
+#define PSC0_PTSTAT (DAVINCI_PSC0_BASE + 0x128)
+
+#define PSC1_MDCTL (DAVINCI_PSC1_BASE + 0xa00)
+#define PSC1_MDSTAT (DAVINCI_PSC1_BASE + 0x800)
+#define PSC1_PTCMD (DAVINCI_PSC1_BASE + 0x120)
+#define PSC1_PTSTAT (DAVINCI_PSC1_BASE + 0x128)
+
+/* Some PLL defines */
+#define PLL0_PLLCTL (DAVINCI_PLL_CNTRL0_BASE + 0x100)
+#define PLL0_PLLM (DAVINCI_PLL_CNTRL0_BASE + 0x110)
+#define PLL0_PREDIV (DAVINCI_PLL_CNTRL0_BASE + 0x114)
+#define PLL0_POSTDIV (DAVINCI_PLL_CNTRL0_BASE + 0x128)
+#define PLL0_DIV1 (DAVINCI_PLL_CNTRL0_BASE + 0x118)
+#define PLL0_DIV2 (DAVINCI_PLL_CNTRL0_BASE + 0x11c)
+#define PLL0_DIV3 (DAVINCI_PLL_CNTRL0_BASE + 0x120)
+#define PLL0_DIV4 (DAVINCI_PLL_CNTRL0_BASE + 0x160)
+#define PLL0_DIV5 (DAVINCI_PLL_CNTRL0_BASE + 0x164)
+#define PLL0_DIV6 (DAVINCI_PLL_CNTRL0_BASE + 0x168)
+#define PLL0_DIV7 (DAVINCI_PLL_CNTRL0_BASE + 0x16c)
+#define PLL0_DIV8 (DAVINCI_PLL_CNTRL0_BASE + 0x170)
+#define PLL0_DIV9 (DAVINCI_PLL_CNTRL0_BASE + 0x114)
+
+/* Boot config */
+#define KICK0 (DAVINCI_BOOTCFG_BASE + 0x38)
+#define KICK1 (DAVINCI_BOOTCFG_BASE + 0x3c)
+#define PINMUX0 (DAVINCI_BOOTCFG_BASE + 0x120)
+#define PINMUX1 (DAVINCI_BOOTCFG_BASE + 0x124)
+#define PINMUX2 (DAVINCI_BOOTCFG_BASE + 0x128)
+#define PINMUX3 (DAVINCI_BOOTCFG_BASE + 0x12c)
+#define PINMUX4 (DAVINCI_BOOTCFG_BASE + 0x130)
+#define PINMUX5 (DAVINCI_BOOTCFG_BASE + 0x134)
+#define PINMUX6 (DAVINCI_BOOTCFG_BASE + 0x138)
+#define PINMUX7 (DAVINCI_BOOTCFG_BASE + 0x13c)
+#define PINMUX8 (DAVINCI_BOOTCFG_BASE + 0x140)
+#define PINMUX9 (DAVINCI_BOOTCFG_BASE + 0x144)
+#define PINMUX10 (DAVINCI_BOOTCFG_BASE + 0x148)
+#define PINMUX11 (DAVINCI_BOOTCFG_BASE + 0x14c)
+#define PINMUX12 (DAVINCI_BOOTCFG_BASE + 0x150)
+#define PINMUX13 (DAVINCI_BOOTCFG_BASE + 0x154)
+#define PINMUX14 (DAVINCI_BOOTCFG_BASE + 0x158)
+#define PINMUX15 (DAVINCI_BOOTCFG_BASE + 0x15C)
+#define PINMUX16 (DAVINCI_BOOTCFG_BASE + 0x160)
+#define PINMUX17 (DAVINCI_BOOTCFG_BASE + 0x164)
+#define PINMUX18 (DAVINCI_BOOTCFG_BASE + 0x168)
+#define PINMUX19 (DAVINCI_BOOTCFG_BASE + 0x16c)
+#define SUSPSRC (DAVINCI_BOOTCFG_BASE + 0x170)
+#define CFGCHIP0 (DAVINCI_BOOTCFG_BASE + 0x17c)
+
+/* Interrupt controller */
+#define INTC_GLB_EN (DAVINCI_INTC_BASE + 0x10)
+#define INTC_HINT_EN (DAVINCI_INTC_BASE + 0x1500)
+#define INTC_EN_CLR0 (DAVINCI_INTC_BASE + 0x380)
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-da8xx/i2c_defs.h b/include/asm-arm/arch-da8xx/i2c_defs.h
new file mode 100644
index 0000000000..714211fca5
--- /dev/null
+++ b/include/asm-arm/arch-da8xx/i2c_defs.h
@@ -0,0 +1,95 @@
+/*
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ *
+ * Some changes copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * 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 _DAVINCI_I2C_H_
+#define _DAVINCI_I2C_H_
+
+#define I2C_WRITE 0
+#define I2C_READ 1
+
+#define I2C_BASE 0x01c22000
+
+#define I2C_OA (I2C_BASE + 0x00)
+#define I2C_IE (I2C_BASE + 0x04)
+#define I2C_STAT (I2C_BASE + 0x08)
+#define I2C_SCLL (I2C_BASE + 0x0c)
+#define I2C_SCLH (I2C_BASE + 0x10)
+#define I2C_CNT (I2C_BASE + 0x14)
+#define I2C_DRR (I2C_BASE + 0x18)
+#define I2C_SA (I2C_BASE + 0x1c)
+#define I2C_DXR (I2C_BASE + 0x20)
+#define I2C_CON (I2C_BASE + 0x24)
+#define I2C_IV (I2C_BASE + 0x28)
+#define I2C_PSC (I2C_BASE + 0x30)
+
+/* I2C masks */
+
+/* I2C Interrupt Enable Register (I2C_IE): */
+#define I2C_IE_SCD_IE (1 << 5) /* Stop condition detect interrupt enable */
+#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */
+#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */
+#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */
+#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */
+#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */
+
+/* I2C Status Register (I2C_STAT): */
+
+#define I2C_STAT_BB (1 << 12) /* Bus busy */
+#define I2C_STAT_ROVR (1 << 11) /* Receive overrun */
+#define I2C_STAT_XUDF (1 << 10) /* Transmit underflow */
+#define I2C_STAT_AAS (1 << 9) /* Address as slave */
+#define I2C_STAT_SCD (1 << 5) /* Stop condition detect */
+#define I2C_STAT_XRDY (1 << 4) /* Transmit data ready */
+#define I2C_STAT_RRDY (1 << 3) /* Receive data ready */
+#define I2C_STAT_ARDY (1 << 2) /* Register access ready */
+#define I2C_STAT_NACK (1 << 1) /* No acknowledgment interrupt enable */
+#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */
+
+
+/* I2C Interrupt Code Register (I2C_INTCODE): */
+
+#define I2C_INTCODE_MASK 7
+#define I2C_INTCODE_NONE 0
+#define I2C_INTCODE_AL 1 /* Arbitration lost */
+#define I2C_INTCODE_NAK 2 /* No acknowledgement/general call */
+#define I2C_INTCODE_ARDY 3 /* Register access ready */
+#define I2C_INTCODE_RRDY 4 /* Rcv data ready */
+#define I2C_INTCODE_XRDY 5 /* Xmit data ready */
+#define I2C_INTCODE_SCD 6 /* Stop condition detect */
+
+
+/* I2C Configuration Register (I2C_CON): */
+
+#define I2C_CON_EN (1 << 5) /* I2C module enable */
+#define I2C_CON_STB (1 << 4) /* Start byte mode (master mode only) */
+#define I2C_CON_MST (1 << 10) /* Master/slave mode */
+#define I2C_CON_TRX (1 << 9) /* Transmitter/receiver mode (master mode only) */
+#define I2C_CON_XA (1 << 8) /* Expand address */
+#define I2C_CON_STP (1 << 11) /* Stop condition (master mode only) */
+#define I2C_CON_STT (1 << 13) /* Start condition (master mode only) */
+#define I2C_CON_FREE (1 << 14) /* Free run on emulation */
+
+#define I2C_TIMEOUT 0xffff0000 /* Timeout mask for poll_i2c_irq() */
+
+#endif
diff --git a/include/asm-arm/arch-da8xx/nand_defs.h b/include/asm-arm/arch-da8xx/nand_defs.h
new file mode 100644
index 0000000000..450e8b986c
--- /dev/null
+++ b/include/asm-arm/arch-da8xx/nand_defs.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts shamelesly stolen from Linux Kernel source tree.
+ *
+ * ------------------------------------------------------------
+ *
+ * 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 _NAND_DEFS_H_
+#define _NAND_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+#define MASK_CLE 0x10
+//#define MASK_ALE 0x0a
+#define MASK_ALE 0x08
+
+
+#define NAND_CE0CLE ((volatile u_int8_t *)(CONFIG_SYS_NAND_BASE + 0x10))
+//#define NAND_CE0ALE ((volatile u_int8_t *)(CFG_NAND_BASE + 0x0a))
+#define NAND_CE0ALE ((volatile u_int8_t *)(CONFIG_SYS_NAND_BASE + 0x08))
+#define NAND_CE0DATA ((volatile u_int8_t *)CONFIG_SYS_NAND_BASE)
+
+typedef struct {
+ u_int32_t NRCSR;
+ u_int32_t AWCCR;
+ u_int8_t RSVD0[8];
+ u_int32_t AB1CR;
+ u_int32_t AB2CR;
+ u_int32_t AB3CR;
+ u_int32_t AB4CR;
+ u_int8_t RSVD1[32];
+ u_int32_t NIRR;
+ u_int32_t NIMR;
+ u_int32_t NIMSR;
+ u_int32_t NIMCR;
+ u_int8_t RSVD2[16];
+ u_int32_t NANDFCR;
+ u_int32_t NANDFSR;
+ u_int8_t RSVD3[8];
+ u_int32_t NANDF1ECC;
+ u_int32_t NANDF2ECC;
+ u_int32_t NANDF3ECC;
+ u_int32_t NANDF4ECC;
+ u_int8_t RSVD4[4];
+ u_int32_t IODFTECR;
+ u_int32_t IODFTGCR;
+ u_int8_t RSVD5[4];
+ u_int32_t IODFTMRLR;
+ u_int32_t IODFTMRMR;
+ u_int32_t IODFTMRMSBR;
+ u_int8_t RSVD6[20];
+ u_int32_t MODRNR;
+ u_int8_t RSVD7[76];
+ u_int32_t CE0DATA;
+ u_int32_t CE0ALE;
+ u_int32_t CE0CLE;
+ u_int8_t RSVD8[4];
+ u_int32_t CE1DATA;
+ u_int32_t CE1ALE;
+ u_int32_t CE1CLE;
+ u_int8_t RSVD9[4];
+ u_int32_t CE2DATA;
+ u_int32_t CE2ALE;
+ u_int32_t CE2CLE;
+ u_int8_t RSVD10[4];
+ u_int32_t CE3DATA;
+ u_int32_t CE3ALE;
+ u_int32_t CE3CLE;
+} nand_registers;
+
+typedef volatile nand_registers *nandregs;
+
+#define NAND_READ_START 0x00
+#define NAND_READ_END 0x30
+#define NAND_STATUS 0x70
+
+#ifdef CFG_NAND_HW_ECC
+#define NAND_Ecc_P1e (1 << 0)
+#define NAND_Ecc_P2e (1 << 1)
+#define NAND_Ecc_P4e (1 << 2)
+#define NAND_Ecc_P8e (1 << 3)
+#define NAND_Ecc_P16e (1 << 4)
+#define NAND_Ecc_P32e (1 << 5)
+#define NAND_Ecc_P64e (1 << 6)
+#define NAND_Ecc_P128e (1 << 7)
+#define NAND_Ecc_P256e (1 << 8)
+#define NAND_Ecc_P512e (1 << 9)
+#define NAND_Ecc_P1024e (1 << 10)
+#define NAND_Ecc_P2048e (1 << 11)
+
+#define NAND_Ecc_P1o (1 << 16)
+#define NAND_Ecc_P2o (1 << 17)
+#define NAND_Ecc_P4o (1 << 18)
+#define NAND_Ecc_P8o (1 << 19)
+#define NAND_Ecc_P16o (1 << 20)
+#define NAND_Ecc_P32o (1 << 21)
+#define NAND_Ecc_P64o (1 << 22)
+#define NAND_Ecc_P128o (1 << 23)
+#define NAND_Ecc_P256o (1 << 24)
+#define NAND_Ecc_P512o (1 << 25)
+#define NAND_Ecc_P1024o (1 << 26)
+#define NAND_Ecc_P2048o (1 << 27)
+
+#define TF(v) (v ? 1 : 0)
+
+#define P2048e(a) (TF(a & NAND_Ecc_P2048e) << 0)
+#define P2048o(a) (TF(a & NAND_Ecc_P2048o) << 1)
+#define P1e(a) (TF(a & NAND_Ecc_P1e) << 2)
+#define P1o(a) (TF(a & NAND_Ecc_P1o) << 3)
+#define P2e(a) (TF(a & NAND_Ecc_P2e) << 4)
+#define P2o(a) (TF(a & NAND_Ecc_P2o) << 5)
+#define P4e(a) (TF(a & NAND_Ecc_P4e) << 6)
+#define P4o(a) (TF(a & NAND_Ecc_P4o) << 7)
+
+#define P8e(a) (TF(a & NAND_Ecc_P8e) << 0)
+#define P8o(a) (TF(a & NAND_Ecc_P8o) << 1)
+#define P16e(a) (TF(a & NAND_Ecc_P16e) << 2)
+#define P16o(a) (TF(a & NAND_Ecc_P16o) << 3)
+#define P32e(a) (TF(a & NAND_Ecc_P32e) << 4)
+#define P32o(a) (TF(a & NAND_Ecc_P32o) << 5)
+#define P64e(a) (TF(a & NAND_Ecc_P64e) << 6)
+#define P64o(a) (TF(a & NAND_Ecc_P64o) << 7)
+
+#define P128e(a) (TF(a & NAND_Ecc_P128e) << 0)
+#define P128o(a) (TF(a & NAND_Ecc_P128o) << 1)
+#define P256e(a) (TF(a & NAND_Ecc_P256e) << 2)
+#define P256o(a) (TF(a & NAND_Ecc_P256o) << 3)
+#define P512e(a) (TF(a & NAND_Ecc_P512e) << 4)
+#define P512o(a) (TF(a & NAND_Ecc_P512o) << 5)
+#define P1024e(a) (TF(a & NAND_Ecc_P1024e) << 6)
+#define P1024o(a) (TF(a & NAND_Ecc_P1024o) << 7)
+
+#define P8e_s(a) (TF(a & NAND_Ecc_P8e) << 0)
+#define P8o_s(a) (TF(a & NAND_Ecc_P8o) << 1)
+#define P16e_s(a) (TF(a & NAND_Ecc_P16e) << 2)
+#define P16o_s(a) (TF(a & NAND_Ecc_P16o) << 3)
+#define P1e_s(a) (TF(a & NAND_Ecc_P1e) << 4)
+#define P1o_s(a) (TF(a & NAND_Ecc_P1o) << 5)
+#define P2e_s(a) (TF(a & NAND_Ecc_P2e) << 6)
+#define P2o_s(a) (TF(a & NAND_Ecc_P2o) << 7)
+
+#define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0)
+#define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1)
+#endif
+
+#endif
diff --git a/include/configs/da8xx_evm.h b/include/configs/da8xx_evm.h
new file mode 100644
index 0000000000..e65989326d
--- /dev/null
+++ b/include/configs/da8xx_evm.h
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2008 Texas Instruments, Inc <www.ti.com>
+ *
+ * Based on davinci_dvevm.h. Original Copyrights follow:
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * 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
+#include <asm/sizes.h>
+#include <asm/arch/hardware.h>
+
+/*=======*/
+/* Board */
+/*=======*/
+//#define CFG_USE_SPIFLASH
+#define CONFIG_SYS_USE_NAND
+
+/*===================*/
+/* SoC Configuration */
+/*===================*/
+#define CONFIG_ARM926EJS /* arm926ejs CPU core */
+#define CONFIG_DA8XX /* TI DA8xx SoC */
+#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID) /* Arm Clock */
+#define CFG_OSCIN_FREQ 24000000
+#define CONFIG_SYS_TIMERBASE DAVINCI_TIMER0_BASE /* use timer 0 */
+#define CONFIG_SYS_HZ_CLOCK clk_get(DAVINCI_AUXCLK_CLKID) /* Timer Input clock freq */
+#define CONFIG_SYS_HZ 1000
+#undef CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is _always_ loaded by a bootloader */
+#define CONFIG_SKIP_RELOCATE_UBOOT /* to a proper address, init done */
+
+/*=============*/
+/* Memory Info */
+/*=============*/
+#define CONFIG_SYS_MALLOC_LEN (0x10000 + 128*1024) /* malloc() len */
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* reserved for initial data */
+#define PHYS_SDRAM_1 DAVINCI_DDR_EMIF_DATA_BASE /* DDR Start */
+#define PHYS_SDRAM_1_SIZE 0x04000000 /* SDRAM size 64MB */
+#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM_1 /* memtest start address */
+#define CONFIG_SYS_MEMTEST_END (PHYS_SDRAM_1 + 16*1024*1024) /* 16MB RAM test */
+#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
+#define CONFIG_STACKSIZE (256*1024) /* regular stack */
+#define SDRAM_4BANKS_10COLS /* TODO: Update this! */
+
+/*====================*/
+/* Serial Driver info */
+/*====================*/
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE 4 /* NS16550 register size */
+#define CONFIG_SYS_NS16550_COM1 DAVINCI_UART2_BASE /* Base address of UART2 */
+#define CONFIG_SYS_NS16550_CLK clk_get(DAVINCI_UART2_CLKID) /* Input clock to NS16550 */
+#define CONFIG_CONS_INDEX 1 /* use UART0 for console */
+#define CONFIG_BAUDRATE 115200 /* Default baud rate */
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+/*===================*/
+/* I2C Configuration */
+/*===================*/
+#define CONFIG_HARD_I2C
+#define CONFIG_DRIVER_DAVINCI_I2C
+#define CONFIG_SYS_I2C_SPEED 25000 /* 100Kbps won't work, silicon bug */
+#define CONFIG_SYS_I2C_SLAVE 10 /* Bogus, master-only in U-Boot */
+
+/*====================================================*/
+/* I2C EEPROM definitions for catalyst 24W256 EEPROM chip */
+/*====================================================*/
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
+#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 20
+
+/*==================================*/
+/* Network & Ethernet Configuration */
+/*==================================*/
+#define CONFIG_DRIVER_TI_EMAC
+#define CONFIG_MII
+#define CONFIG_BOOTP_DEFAULT
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_NET_RETRY_COUNT 10
+
+/*=====================*/
+/* Flash & Environment */
+/*=====================*/
+#ifdef CONFIG_SYS_USE_NAND
+#undef CONFIG_ENV_IS_IN_FLASH
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_ENV_IS_IN_NAND /* U-Boot env in NAND Flash */
+#define CONFIG_ENV_SIZE SZ_128K
+#define CONFIG_NAND_1BIT_ECC
+#define CONFIG_NAND_CS 3
+#define CONFIG_SYS_NAND_BASE DAVINCI_ASYNC_EMIF_DATA_CE3_BASE
+#define CONFIG_CLE_MASK 0x10
+#define CONFIG_ALE_MASK 0x8
+#define CONFIG_NAND_HW_ECC
+#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
+#define NAND_MAX_CHIPS 1
+#define CONFIG_ENV_OFFSET 0x0 /* Block 0--not used by bootcode */
+#define DEF_BOOTM ""
+#endif
+
+#ifdef CONFIG_SYS_USE_NOR
+#define CONFIG_ENV_IS_IN_FLASH
+#undef CONFIG_SYS_NO_FLASH
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+#define CFG_MAX_FLASH_BANKS 1 /* max number of flash banks */
+#define CFG_FLASH_SECT_SZ 0x10000 /* 64KB sect size AMD Flash */
+#define CONFIG_ENV_OFFSET (CFG_FLASH_SECT_SZ*3)
+#define CFG_FLASH_BASE DAVINCI_ASYNC_EMIF_DATA_CE2_BASE
+#define PHYS_FLASH_SIZE 0x2000000 /* Flash size 32MB */
+#define CFG_MAX_FLASH_SECT (PHYS_FLASH_SIZE/CFG_FLASH_SECT_SZ)
+#define CONFIG_ENV_SECT_SIZE CFG_FLASH_SECT_SZ /* Env sector Size */
+#endif
+
+#ifdef CFG_USE_SPIFLASH
+#undef CONFIG_ENV_IS_IN_FLASH
+#undef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_SIZE SZ_16K
+#define CONFIG_ENV_OFFSET SZ_256K
+#define CONFIG_ENV_SECT_SIZE SZ_4K
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_DAVINCI_SPI
+#define CFG_SPI_BASE DAVINCI_SPI0_BASE
+#define CFG_SPI_CLK clk_get(DAVINCI_SPI0_CLKID)
+#define CONFIG_SF_DEFAULT_SPEED 50000000
+#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
+#endif
+
+
+/*==============================*/
+/* U-Boot general configuration */
+/*==============================*/
+#undef CONFIG_USE_IRQ /* No IRQ/FIQ in U-Boot */
+#define CONFIG_MISC_INIT_R
+#undef CONFIG_BOOTDELAY
+#define CONFIG_BOOTFILE "uImage" /* Boot file name */
+#define CONFIG_SYS_PROMPT "U-Boot > " /* Monitor Command Prompt */
+#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print buffer sz */
+#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
+#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_MEMTEST_START + 0x700000) /* default Linux kernel load address */
+#define CONFIG_VERSION_VARIABLE
+#define CONFIG_AUTO_COMPLETE /* Won't work with hush so far, may be later */
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_CRC32_VERIFY
+#define CONFIG_MX_CYCLIC
+
+/*===================*/
+/* Linux Information */
+/*===================*/
+#define LINUX_BOOT_PARAM_ADDR (CONFIG_SYS_MEMTEST_START + 0x100)
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTARGS "mem=32M console=ttyS2,115200n8 root=/dev/mtdblock/2 rw noinitrd ip=dhcp"
+#define CONFIG_BOOTCOMMAND ""
+#define CONFIG_BOOTDELAY 3
+
+/*=================*/
+/* U-Boot commands */
+/*=================*/
+#include <config_cmd_default.h>
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_MEMORY
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_SETGETDCR
+#define CONFIG_CMD_EEPROM
+
+#ifdef CONFIG_SYS_USE_NAND
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+#define CONFIG_CMD_NAND
+#endif
+
+#ifdef CFG_USE_SPIFLASH
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_FLASH
+#define CONFIG_CMD_SF
+#endif
+
+#if !defined(CONFIG_SYS_USE_NAND) && !defined(CONFIG_SYS_USE_NOR) && !defined(CFG_USE_SPIFLASH)
+#define CFG_ENV_IS_NOWHERE
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_ENV_SIZE SZ_16K
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_ENV
+#endif
+
+#endif /* __CONFIG_H */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 24ad2bdaa1..59e64dcb7a 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -135,6 +135,15 @@ typedef enum {
NAND_ECC_HW_SYNDROME,
} nand_ecc_modes_t;
+struct page_layout_item {
+ int length;
+ enum {
+ ITEM_TYPE_DATA,
+ ITEM_TYPE_OOB,
+ ITEM_TYPE_ECC,
+ } type;
+};
+
/*
* Constants for Hardware ECC
*/
@@ -144,6 +153,9 @@ typedef enum {
#define NAND_ECC_WRITE 1
/* Enable Hardware ECC before syndrom is read back from flash */
#define NAND_ECC_READSYN 2
+#define NAND_ECC_WRITESYN 3
+#define NAND_ECC_READOOB 4
+#define NAND_ECC_WRITEOOB 5
/* Bit mask for flags passed to do_nand_read_ecc */
#define NAND_GET_DEVICE 0x80
diff --git a/lib_arm/board.c b/lib_arm/board.c
index 2358bebdbd..0a77f7fdb2 100644
--- a/lib_arm/board.c
+++ b/lib_arm/board.c
@@ -416,9 +416,9 @@ void start_armboot (void)
/* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_TI_EMAC
-extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
+extern void dm644x_eth_set_mac_addr (const u_int8_t *addr);
if (getenv ("ethaddr")) {
- davinci_eth_set_mac_addr(gd->bd->bi_enetaddr);
+ dm644x_eth_set_mac_addr(gd->bd->bi_enetaddr);
}
#endif
diff --git a/net/eth.c b/net/eth.c
index b7ef09f447..6aba8e4a1e 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -469,7 +469,7 @@ extern int at91rm9200_miiphy_initialize(bd_t *bis);
extern int emac4xx_miiphy_initialize(bd_t *bis);
extern int mcf52x2_miiphy_initialize(bd_t *bis);
extern int ns7520_miiphy_initialize(bd_t *bis);
-extern int davinci_eth_miiphy_initialize(bd_t *bis);
+extern int dm644x_eth_miiphy_initialize(bd_t *bis);
int eth_initialize(bd_t *bis)
@@ -491,7 +491,7 @@ int eth_initialize(bd_t *bis)
ns7520_miiphy_initialize(bis);
#endif
#if defined(CONFIG_DRIVER_TI_EMAC)
- davinci_eth_miiphy_initialize(bis);
+ dm644x_eth_miiphy_initialize(bis);
#endif
return 0;
}
diff --git a/patches/freon_port.patch b/patches/freon_port.patch
new file mode 100644
index 0000000000..b70ce86498
--- /dev/null
+++ b/patches/freon_port.patch
@@ -0,0 +1,3910 @@
+Index: u-boot-2009.01-primus/include/configs/da850_evm.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/include/configs/da850_evm.h
+@@ -0,0 +1,223 @@
++/*
++ * Copyright (C) 2008 Texas Instruments, Inc <www.ti.com>
++ *
++ * Based on davinci_dvevm.h. Original Copyrights follow:
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * 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
++#include <asm/sizes.h>
++#include <asm/arch/hardware.h>
++
++/*=======*/
++/* Board */
++/*=======*/
++//#define CFG_USE_SPIFLASH
++#define CONFIG_SYS_USE_NAND
++
++/*===================*/
++/* SoC Configuration */
++/*===================*/
++#define CONFIG_ARM926EJS /* arm926ejs CPU core */
++#define CONFIG_DA850 /* TI DA850 SoC */
++#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID) /* Arm Clock */
++#define CFG_OSCIN_FREQ 24000000
++#define CONFIG_SYS_TIMERBASE DAVINCI_TIMER0_BASE /* use timer 0 */
++#define CONFIG_SYS_HZ_CLOCK clk_get(DAVINCI_AUXCLK_CLKID) /* Timer Input clock freq */
++#define CONFIG_SYS_HZ 1000
++#undef CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is _always_ loaded by a bootloader */
++#define CONFIG_SKIP_RELOCATE_UBOOT /* to a proper address, init done */
++
++/*=============*/
++/* Memory Info */
++/*=============*/
++#define CONFIG_SYS_MALLOC_LEN (0x10000 + 128*1024) /* malloc() len */
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* reserved for initial data */
++#define PHYS_SDRAM_1 DAVINCI_DDR_EMIF_DATA_BASE /* DDR Start */
++#define PHYS_SDRAM_1_SIZE 0x04000000 /* SDRAM size 64MB */
++#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM_1 /* memtest start address */
++#define CONFIG_SYS_MEMTEST_END (PHYS_SDRAM_1 + 16*1024*1024) /* 16MB RAM test */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define CONFIG_STACKSIZE (256*1024) /* regular stack */
++#define SDRAM_4BANKS_10COLS /* TODO: Update this! */
++
++/*====================*/
++/* Serial Driver info */
++/*====================*/
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4 /* NS16550 register size */
++#define CONFIG_SYS_NS16550_COM1 DAVINCI_UART0_BASE /* Base address of UART2 */
++#define CONFIG_SYS_NS16550_CLK clk_get(DAVINCI_UART0_CLKID) /* Input clock to NS16550 */
++#define CONFIG_CONS_INDEX 1 /* use UART0 for console */
++#define CONFIG_BAUDRATE 115200 /* Default baud rate */
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*===================*/
++/* I2C Configuration */
++/*===================*/
++#define CONFIG_HARD_I2C
++#define CONFIG_DRIVER_DAVINCI_I2C
++#define CONFIG_SYS_I2C_SPEED 25000 /* 100Kbps won't work, silicon bug */
++#define CONFIG_SYS_I2C_SLAVE 10 /* Bogus, master-only in U-Boot */
++
++/*====================================================*/
++/* I2C EEPROM definitions for catalyst 24W256 EEPROM chip */
++/*====================================================*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
++#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6
++#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 20
++
++/*==================================*/
++/* Network & Ethernet Configuration */
++/*==================================*/
++#define CONFIG_DRIVER_TI_EMAC
++#define CONFIG_MII
++#define CONFIG_BOOTP_DEFAULT
++#define CONFIG_BOOTP_DNS
++#define CONFIG_BOOTP_DNS2
++#define CONFIG_BOOTP_SEND_HOSTNAME
++#define CONFIG_NET_RETRY_COUNT 10
++
++/*=====================*/
++/* Flash & Environment */
++/*=====================*/
++#ifdef CONFIG_SYS_USE_NAND
++#undef CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_SYS_NO_FLASH
++#define CONFIG_ENV_IS_IN_NAND /* U-Boot env in NAND Flash */
++#define CONFIG_ENV_SIZE SZ_128K
++#define CONFIG_NAND_1BIT_ECC
++#define CONFIG_NAND_CS 3
++#define CONFIG_SYS_NAND_BASE DAVINCI_ASYNC_EMIF_DATA_CE3_BASE
++#define CONFIG_CLE_MASK 0x10
++#define CONFIG_ALE_MASK 0x8
++#define CONFIG_NAND_HW_ECC
++#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
++#define NAND_MAX_CHIPS 1
++#define CONFIG_ENV_OFFSET 0x0 /* Block 0--not used by bootcode */
++#define DEF_BOOTM ""
++#endif
++
++#ifdef CONFIG_SYS_USE_NOR
++#define CONFIG_ENV_IS_IN_FLASH
++#undef CONFIG_SYS_NO_FLASH
++#define CFG_FLASH_CFI_DRIVER
++#define CFG_FLASH_CFI
++#define CFG_MAX_FLASH_BANKS 1 /* max number of flash banks */
++#define CFG_FLASH_SECT_SZ 0x10000 /* 64KB sect size AMD Flash */
++#define CONFIG_ENV_OFFSET (CFG_FLASH_SECT_SZ*3)
++#define CFG_FLASH_BASE DAVINCI_ASYNC_EMIF_DATA_CE2_BASE
++#define PHYS_FLASH_SIZE 0x2000000 /* Flash size 32MB */
++#define CFG_MAX_FLASH_SECT (PHYS_FLASH_SIZE/CFG_FLASH_SECT_SZ)
++#define CONFIG_ENV_SECT_SIZE CFG_FLASH_SECT_SZ /* Env sector Size */
++#endif
++
++#ifdef CFG_USE_SPIFLASH
++#undef CONFIG_ENV_IS_IN_FLASH
++#undef CONFIG_ENV_IS_IN_NAND
++#define CONFIG_ENV_IS_IN_SPI_FLASH
++#define CONFIG_ENV_SIZE SZ_16K
++#define CONFIG_ENV_OFFSET SZ_256K
++#define CONFIG_ENV_SECT_SIZE SZ_4K
++#define CONFIG_SYS_NO_FLASH
++#define CONFIG_SPI
++#define CONFIG_SPI_FLASH
++#define CONFIG_SPI_FLASH_WINBOND
++#define CONFIG_DAVINCI_SPI
++#define CFG_SPI_BASE DAVINCI_SPI0_BASE
++#define CFG_SPI_CLK clk_get(DAVINCI_SPI0_CLKID)
++#define CONFIG_SF_DEFAULT_SPEED 50000000
++#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
++#endif
++
++
++/*==============================*/
++/* U-Boot general configuration */
++/*==============================*/
++#undef CONFIG_USE_IRQ /* No IRQ/FIQ in U-Boot */
++#define CONFIG_MISC_INIT_R
++#undef CONFIG_BOOTDELAY
++#define CONFIG_BOOTFILE "uImage" /* Boot file name */
++#define CONFIG_SYS_PROMPT "U-Boot > " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print buffer sz */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_MEMTEST_START + 0x700000) /* default Linux kernel load address */
++#define CONFIG_VERSION_VARIABLE
++#define CONFIG_AUTO_COMPLETE /* Won't work with hush so far, may be later */
++#define CONFIG_SYS_HUSH_PARSER
++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
++#define CONFIG_CMDLINE_EDITING
++#define CONFIG_SYS_LONGHELP
++#define CONFIG_CRC32_VERIFY
++#define CONFIG_MX_CYCLIC
++
++/*===================*/
++/* Linux Information */
++/*===================*/
++#define LINUX_BOOT_PARAM_ADDR (CONFIG_SYS_MEMTEST_START + 0x100)
++#define CONFIG_CMDLINE_TAG
++#define CONFIG_SETUP_MEMORY_TAGS
++#define CONFIG_BOOTARGS "mem=32M console=ttyS0,115200n8 root=/dev/mtdblock/2 rw noinitrd ip=dhcp"
++#define CONFIG_BOOTCOMMAND ""
++#define CONFIG_BOOTDELAY 3
++
++/*=================*/
++/* U-Boot commands */
++/*=================*/
++#include <config_cmd_default.h>
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_ASKENV
++#define CONFIG_CMD_DHCP
++#define CONFIG_CMD_DIAG
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_SAVES
++#define CONFIG_CMD_MEMORY
++#undef CONFIG_CMD_BDI
++#undef CONFIG_CMD_FPGA
++#undef CONFIG_CMD_SETGETDCR
++#define CONFIG_CMD_EEPROM
++
++#ifdef CONFIG_SYS_USE_NAND
++#undef CONFIG_CMD_FLASH
++#undef CONFIG_CMD_IMLS
++#define CONFIG_CMD_NAND
++#endif
++
++#ifdef CFG_USE_SPIFLASH
++#undef CONFIG_CMD_IMLS
++#undef CONFIG_CMD_FLASH
++#define CONFIG_CMD_SF
++#endif
++
++#if !defined(CONFIG_SYS_USE_NAND) && !defined(CONFIG_SYS_USE_NOR) && !defined(CFG_USE_SPIFLASH)
++#define CFG_ENV_IS_NOWHERE
++#define CONFIG_SYS_NO_FLASH
++#define CONFIG_ENV_SIZE SZ_16K
++#undef CONFIG_CMD_IMLS
++#undef CONFIG_CMD_FLASH
++#undef CONFIG_CMD_ENV
++#endif
++
++#endif /* __CONFIG_H */
+Index: u-boot-2009.01-primus/board/da850/da850-evm/Makefile
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/board/da850/da850-evm/Makefile
+@@ -0,0 +1,52 @@
++#
++# (C) Copyright 2000, 2001, 2002
++# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++#
++# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++#
++# 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 := dv_board.o
++SOBJS := board_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 *~ .depend
++
++#########################################################################
++# This is for $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+Index: u-boot-2009.01-primus/board/da850/da850-evm/board_init.S
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/board/da850/da850-evm/board_init.S
+@@ -0,0 +1,29 @@
++/*
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Board-specific low level initialization code. Called at the very end
++ * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no
++ * initialization required.
++ *
++ * 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>
++
++.globl dv_board_init
++dv_board_init:
++
++ mov pc, lr
+Index: u-boot-2009.01-primus/board/da850/da850-evm/config.mk
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/board/da850/da850-evm/config.mk
+@@ -0,0 +1,30 @@
++#
++# (C) Copyright 2002
++# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++#
++# (C) Copyright 2003
++# Texas Instruments, <www.ti.com>
++# Swaminathan <swami.iyer@ti.com>
++#
++# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++#
++# (C) Copyright 2008
++# Sekhar Nori, Texas Instruments, Inc. <nsekhar@ti.com>
++#
++# Texas Instruments DA8xx EVM board (ARM925EJS) cpu
++# see http://www.ti.com/ for more information on Texas Instruments
++#
++# DA8xx EVM has 1 bank of 64 MB SDRAM (2 16Meg x16 chips).
++# Physical Address:
++# C000'0000 to C400'0000
++#
++# Linux-Kernel is expected to be at C000'8000, entry C000'8000
++# (mem base + reserved)
++#
++# we load ourself to C108 '0000
++#
++#
++
++#Provide at least 16MB spacing between us and the Linux Kernel image
++TEXT_BASE = 0xC1080000
+Index: u-boot-2009.01-primus/board/da850/da850-evm/dv_board.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/board/da850/da850-evm/dv_board.c
+@@ -0,0 +1,232 @@
++/*
++ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc. <nsekhar@ti.com>
++ *
++ * Modified for DA8xx EVM.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Parts are shamelessly stolen from various TI sources, original copyright
++ * follows:
++ * -----------------------------------------------------------------
++ *
++ * Copyright (C) 2004 Texas Instruments.
++ *
++ * ----------------------------------------------------------------------------
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++ */
++
++#include <common.h>
++#include <i2c.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/emac_defs.h>
++
++#define MACH_TYPE_DA850_EVM 1781
++
++DECLARE_GLOBAL_DATA_PTR;
++
++extern void timer_init(void);
++extern int eth_hw_init(void);
++
++/* Works on Always On power domain only (no PD argument) */
++void lpsc_on(unsigned int id)
++{
++ dv_reg_p mdstat, mdctl, ptstat, ptcmd;
++
++ if (id >= 64)
++ return;
++
++ if(id < 32) {
++ mdstat = REG_P(PSC0_MDSTAT + (id * 4));
++ mdctl = REG_P(PSC0_MDCTL + (id * 4));
++ ptstat = REG_P(PSC0_PTSTAT);
++ ptcmd = REG_P(PSC0_PTCMD);
++ } else {
++ id -= 32;
++ mdstat = REG_P(PSC1_MDSTAT + (id * 4));
++ mdctl = REG_P(PSC1_MDCTL + (id * 4));
++ ptstat = REG_P(PSC1_PTSTAT);
++ ptcmd = REG_P(PSC1_PTCMD);
++ }
++
++ while (*ptstat & 0x01) {;}
++
++ if ((*mdstat & 0x1f) == 0x03)
++ return; /* Already on and enabled */
++
++ *mdctl |= 0x03;
++
++ /* Special treatment for some modules as for sprue14 p.7.4.2 */
++ /* TBD: Confirm if such cases exist for Primus */
++ if (0)
++ *mdctl |= 0x200;
++
++ *ptcmd = 0x01;
++
++ while (*ptstat & 0x01) {;}
++ while ((*mdstat & 0x1f) != 0x03) {;} /* Probably an overkill... */
++}
++
++int board_init(void)
++{
++
++ dv_reg_p intc;
++
++ /*-------------------------------------------------------*
++ * Mask all IRQs by clearing the global enable and setting
++ * the enable clear for all the 90 interrupts. This code is
++ * also included in low level init. Including it here in case
++ * low level init is skipped. Not removing it from low level
++ * init in case some of the low level init code generates
++ * interrupts... Not expected... but you never know...
++ *-------------------------------------------------------*/
++
++#ifndef CONFIG_USE_IRQ
++ intc = REG_P(INTC_GLB_EN);
++ intc[0] = 0;
++
++ intc = REG_P(INTC_HINT_EN);
++ intc[0] = 0;
++ intc[1] = 0;
++ intc[2] = 0;
++
++ intc = REG_P(INTC_EN_CLR0);
++ intc[0] = 0xFFFFFFFF;
++ intc[1] = 0xFFFFFFFF;
++ intc[2] = 0xFFFFFFFF;
++#endif
++
++ /* arch number of the board */
++ gd->bd->bi_arch_number = MACH_TYPE_DA850_EVM;
++
++ /* address of boot parameters */
++ gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
++
++ /* setup the SUSPSRC for ARM to control emulation suspend */
++ REG(SUSPSRC) &= ~( (1 << 27) /* Timer0 */
++ | (1 << 21) /* SPI0 */
++ | (1 << 18) /* UART0 */
++ | (1 << 5) /* EMAC */
++ | (1 << 16) /* I2C0 */
++ );
++
++ /* Power on required peripherals
++ * ARM does not have acess by default to PSC0 and PSC1
++ * assuming here that the DSP bootloader has set the IOPU
++ * such that PSC access is available to ARM
++ */
++ lpsc_on(DAVINCI_LPSC_AEMIF); /* NAND, NOR */
++ lpsc_on(DAVINCI_LPSC_SPI0); /* Serial Flash */
++ lpsc_on(DAVINCI_LPSC_EMAC); /* image download */
++ lpsc_on(DAVINCI_LPSC_UART0); /* console */
++ lpsc_on(DAVINCI_LPSC_GPIO);
++
++ /* Pin Muxing support */
++
++ /* write the kick registers to unlock the PINMUX registers */
++ REG(KICK0) = 0x83e70b13; /* Kick0 unlock */
++ REG(KICK1) = 0x95a4f1e0; /* Kick1 unlock */
++
++#ifdef CONFIG_SPI_FLASH
++ /* SPI0 */
++ REG(PINMUX3) &= 0xFFFF0000;
++ REG(PINMUX3) |= 0x00001111;
++ REG(PINMUX4) &= 0xFFFFFF0F;
++ REG(PINMUX4) |= 0x00000010;
++#endif
++
++#ifdef CONFIG_DRIVER_TI_EMAC
++ /* RMII clock is sourced externally */
++ REG(PINMUX15) &= 0xFFFFFFF0;
++ REG(PINMUX14) &= 0x000000FF;
++ REG(PINMUX14) |= 0x88888800;
++ REG(PINMUX15) &= 0xFFFFFF0F;
++ REG(PINMUX15) |= 0x00000080;
++ REG(PINMUX4) &= 0xFFFFFF00;
++ REG(PINMUX4) |= 0x00000088;
++#endif
++
++ /* Async EMIF */
++#if defined(CFG_USE_NAND) || defined(CFG_USE_NOR)
++ REG(PINMUX6) = 0x11111111;
++ REG(PINMUX7) = 0x11111111;
++ REG(PINMUX8) = 0x11111111;
++ REG(PINMUX9) = 0x11111111;
++ REG(PINMUX10) = 0x11111111;
++ REG(PINMUX11) = 0x11111111;
++ REG(PINMUX12) = 0x11111111;
++ REG(PINMUX5) &= 0x00FFFFFF;
++ REG(PINMUX5) |= 0x11000000;
++#endif
++
++ /* UART0 Muxing and enabling */
++ REG(PINMUX3) &= 0x0000FFFF;
++ REG(PINMUX3) |= 0x22220000;
++
++ REG(DAVINCI_UART0_BASE + 0x30) = 0xE001;
++
++ /* I2C muxing */
++ REG(PINMUX4) &= 0xFFFF00FF;
++ REG(PINMUX4) |= 0x00002200;
++
++ /* write the kick registers to lock the PINMUX registers */
++ REG(KICK0) = 0x0; /* Kick0 lock */
++ REG(KICK1) = 0x0; /* Kick1 lock */
++
++ return(0);
++}
++
++int misc_init_r (void)
++{
++ u_int8_t tmp[20], buf[10];
++ int i;
++
++ printf ("ARM Clock : %d Hz\n", clk_get(DAVINCI_ARM_CLKID));
++
++ /* Set Ethernet MAC address from EEPROM */
++ if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0x7f00, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, buf, 6)) {
++ printf("\nEEPROM @ 0x%02x read FAILED!!!\n", CONFIG_SYS_I2C_EEPROM_ADDR);
++ } else {
++ tmp[0] = 0xff;
++ for (i = 0; i < 6; i++)
++ tmp[0] &= buf[i];
++
++ if ((tmp[0] != 0xff) && (getenv("ethaddr") == NULL)) {
++ sprintf((char *)&tmp[0], "%02x:%02x:%02x:%02x:%02x:%02x",
++ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
++ setenv("ethaddr", (char *)&tmp[0]);
++ }
++ }
++
++ tmp[0] = 0x01;
++ tmp[1] = 0x23;
++ if(i2c_write(0x5f, 0, 0, tmp, 2)) {
++ printf("Ethernet switch start failed!\n");
++ }
++
++ if (!eth_hw_init()) {
++ printf("Error: Ethernet init failed!\n");
++ }
++
++ return(0);
++}
++
++int dram_init(void)
++{
++ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++
++ return(0);
++}
+Index: u-boot-2009.01-primus/board/da850/da850-evm/u-boot.lds
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/board/da850/da850-evm/u-boot.lds
+@@ -0,0 +1,52 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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
++ */
++
++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x00000000;
++ . = ALIGN(4);
++ .text :
++ {
++ cpu/arm926ejs/start.o (.text)
++ *(.text)
++ }
++ . = ALIGN(4);
++ .rodata : { *(.rodata) }
++ . = ALIGN(4);
++ .data : { *(.data) }
++ . = ALIGN(4);
++ .got : { *(.got) }
++
++ . = .;
++ __u_boot_cmd_start = .;
++ .u_boot_cmd : { *(.u_boot_cmd) }
++ __u_boot_cmd_end = .;
++
++ . = ALIGN(4);
++ __bss_start = .;
++ .bss (NOLOAD) : { *(.bss) }
++ _end = .;
++}
+Index: u-boot-2009.01-primus/cpu/arm926ejs/da850/Makefile
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/cpu/arm926ejs/da850/Makefile
+@@ -0,0 +1,49 @@
++#
++# (C) Copyright 2000-2006
++# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++#
++# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++#
++# 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 ether.o nand.o clock.o i2c.o
++SOBJS = lowlevel_init.o reset.o
++
++SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
++START := $(addprefix $(obj),$(START))
++
++all: $(obj).depend $(LIB)
++
++$(LIB): $(OBJS)
++ $(AR) $(ARFLAGS) $@ $(OBJS)
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+Index: u-boot-2009.01-primus/cpu/arm926ejs/da850/clock.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/cpu/arm926ejs/da850/clock.c
+@@ -0,0 +1,57 @@
++/*
++ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc. <nsekhar@ti.com>
++ *
++ * DA8xx clock module
++ *
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++ */
++
++#include <common.h>
++#include <asm/arch/hardware.h>
++
++dv_reg_p sysdiv[9] = {
++ PLL0_DIV1, PLL0_DIV2, PLL0_DIV3, PLL0_DIV4, PLL0_DIV5, PLL0_DIV6,
++ PLL0_DIV7, PLL0_DIV8, PLL0_DIV9 };
++
++int clk_get(unsigned int id)
++{
++ int pre_div = (REG(PLL0_PREDIV) & 0xff) + 1;
++ int pllm = REG(PLL0_PLLM) + 1;
++ int post_div = (REG(PLL0_POSTDIV) & 0xff) + 1;
++ int pll_out = CFG_OSCIN_FREQ;
++
++ if(id == DAVINCI_AUXCLK_CLKID)
++ goto out;
++
++ /* Lets keep this simple. Combining operations can result in
++ * unexpected approximations
++ */
++ pll_out /= pre_div;
++ pll_out *= pllm;
++
++ if(id == DAVINCI_PLLM_CLKID)
++ goto out;
++
++ pll_out /= post_div;
++
++ if(id == DAVINCI_PLLC_CLKID)
++ goto out;
++
++ pll_out /= (REG(sysdiv[id - 1]) & 0xff) + 1;
++
++out:
++ return pll_out;
++}
+Index: u-boot-2009.01-primus/cpu/arm926ejs/da850/ether.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/cpu/arm926ejs/da850/ether.c
+@@ -0,0 +1,667 @@
++/*
++ * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
++ * follows:
++ *
++ * ----------------------------------------------------------------------------
++ *
++ * dm644x_emac.c
++ *
++ * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
++ *
++ * Copyright (C) 2005 Texas Instruments.
++ *
++ * ----------------------------------------------------------------------------
++ *
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++
++ * Modifications:
++ * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
++ * ver 1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
++ *
++ */
++#include <common.h>
++#include <command.h>
++#include <net.h>
++#include <miiphy.h>
++#include <asm/arch/emac_defs.h>
++
++#ifdef CONFIG_DRIVER_TI_EMAC
++
++#ifdef CONFIG_CMD_NET
++
++unsigned int emac_dbg = 0;
++#define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args)
++
++/* Internal static functions */
++static int dm644x_eth_hw_init (void);
++static int dm644x_eth_open (void);
++static int dm644x_eth_close (void);
++static int dm644x_eth_send_packet (volatile void *packet, int length);
++static int dm644x_eth_rcv_packet (void);
++static void dm644x_eth_mdio_enable(void);
++
++static int gen_init_phy(int phy_addr);
++static int gen_is_phy_connected(int phy_addr);
++static int gen_get_link_speed(int phy_addr);
++static int gen_auto_negotiate(int phy_addr);
++
++/* Wrappers exported to the U-Boot proper */
++int eth_hw_init(void)
++{
++ return(dm644x_eth_hw_init());
++}
++
++int eth_init(bd_t * bd)
++{
++ return(dm644x_eth_open());
++}
++
++void eth_halt(void)
++{
++ dm644x_eth_close();
++}
++
++int eth_send(volatile void *packet, int length)
++{
++ return(dm644x_eth_send_packet(packet, length));
++}
++
++int eth_rx(void)
++{
++ return(dm644x_eth_rcv_packet());
++}
++
++void eth_mdio_enable(void)
++{
++ dm644x_eth_mdio_enable();
++}
++/* End of wrappers */
++
++/* dm644x_eth_mac_addr[0] goes out on the wire first */
++
++static u_int8_t dm644x_eth_mac_addr[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00 };
++
++/*
++ * This function must be called before emac_open() if you want to override
++ * the default mac address.
++ */
++void dm644x_eth_set_mac_addr(const u_int8_t *addr)
++{
++ int i;
++
++ for (i = 0; i < sizeof (dm644x_eth_mac_addr); i++) {
++ dm644x_eth_mac_addr[i] = addr[i];
++ }
++}
++
++/* EMAC Addresses */
++static volatile emac_regs *adap_emac = (emac_regs *)EMAC_BASE_ADDR;
++static volatile ewrap_regs *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
++static volatile mdio_regs *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;
++
++/* EMAC descriptors */
++static volatile emac_desc *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
++static volatile emac_desc *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
++static volatile emac_desc *emac_rx_active_head = 0;
++static volatile emac_desc *emac_rx_active_tail = 0;
++static int emac_rx_queue_active = 0;
++
++/* Receive packet buffers */
++static unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
++
++/* PHY address for a discovered PHY (0xff - not found) */
++static volatile u_int8_t active_phy_addr = 0xff;
++
++static int no_phy_init (int phy_addr) { return(1); }
++static int no_phy_is_connected (int phy_addr) { return(1); }
++static int no_phy_get_link_speed (int phy_addr) { return(1); }
++static int no_phy_auto_negotiate (int phy_addr) { return(1); }
++phy_t phy = {
++ .init = no_phy_init,
++ .is_phy_connected = no_phy_is_connected,
++ .get_link_speed = no_phy_get_link_speed,
++ .auto_negotiate = no_phy_auto_negotiate
++};
++
++static void dm644x_eth_mdio_enable(void)
++{
++ u_int32_t clkdiv;
++
++ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
++
++ adap_mdio->CONTROL = (clkdiv & 0xff) |
++ MDIO_CONTROL_ENABLE |
++ MDIO_CONTROL_FAULT |
++ MDIO_CONTROL_FAULT_ENABLE;
++
++ while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
++}
++
++/*
++ * Tries to find an active connected PHY. Returns 1 if address if found.
++ * If no active PHY found returns 0. If more than one active PHY (switch)
++ * returns 2
++ * Sets active_phy_addr variable when returns 1.
++ */
++static int dm644x_eth_phy_detect(void)
++{
++ u_int32_t phy_act_state;
++ int i;
++
++ active_phy_addr = 0xff;
++
++ if ((phy_act_state = adap_mdio->ALIVE) == 0)
++ return(0); /* No active PHYs */
++
++ debug_emac("dm644x_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
++
++ for (i = 0; i < 32; i++) {
++ if (phy_act_state & (1 << i)) {
++ if (phy_act_state & ~(1 << i))
++ return(2); /* More than one PHY */
++ else {
++ active_phy_addr = i;
++ return(1);
++ }
++ }
++ }
++
++ return(0); /* Just to make GCC happy */
++}
++
++
++/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
++int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
++{
++ int tmp;
++
++ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
++
++ adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
++ MDIO_USERACCESS0_WRITE_READ |
++ ((reg_num & 0x1f) << 21) |
++ ((phy_addr & 0x1f) << 16);
++
++ /* Wait for command to complete */
++ while ((tmp = adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) {;}
++
++ if (tmp & MDIO_USERACCESS0_ACK) {
++ *data = tmp & 0xffff;
++ return(1);
++ }
++
++ *data = -1;
++ return(0);
++}
++
++/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
++int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
++{
++
++ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
++
++ adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
++ MDIO_USERACCESS0_WRITE_WRITE |
++ ((reg_num & 0x1f) << 21) |
++ ((phy_addr & 0x1f) << 16) |
++ (data & 0xffff);
++
++ /* Wait for command to complete */
++ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
++
++ return(1);
++}
++
++/* PHY functions for a generic PHY */
++static int gen_init_phy(int phy_addr)
++{
++ int ret = 1;
++
++ if (gen_get_link_speed(phy_addr)) {
++ /* Try another time */
++ ret = gen_get_link_speed(phy_addr);
++ }
++
++ return(ret);
++}
++
++static int gen_is_phy_connected(int phy_addr)
++{
++ u_int16_t dummy;
++
++ return(dm644x_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy));
++}
++
++static int gen_get_link_speed(int phy_addr)
++{
++ u_int16_t tmp;
++
++ if (dm644x_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) && (tmp & 0x04))
++ return(1);
++
++ return(0);
++}
++
++static int gen_auto_negotiate(int phy_addr)
++{
++ u_int16_t tmp;
++
++ if (!dm644x_eth_phy_read(phy_addr, PHY_BMCR, &tmp))
++ return(0);
++
++ /* Restart Auto_negotiation */
++ tmp |= PHY_BMCR_AUTON;
++ dm644x_eth_phy_write(phy_addr, PHY_BMCR, tmp);
++
++ /*check AutoNegotiate complete */
++ udelay (10000);
++ if (!dm644x_eth_phy_read(phy_addr, PHY_BMSR, &tmp))
++ return(0);
++
++ if (!(tmp & PHY_BMSR_AUTN_COMP))
++ return(0);
++
++ return(gen_get_link_speed(phy_addr));
++}
++/* End of generic PHY functions */
++
++
++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
++static int dm644x_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
++{
++ return(dm644x_eth_phy_read(addr, reg, value) ? 0 : 1);
++}
++
++static int dm644x_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value)
++{
++ return(dm644x_eth_phy_write(addr, reg, value) ? 0 : 1);
++}
++
++int dm644x_eth_miiphy_initialize(bd_t *bis)
++{
++ miiphy_register(phy.name, dm644x_mii_phy_read, dm644x_mii_phy_write);
++
++ return(1);
++}
++#endif
++
++/*
++ * This function initializes the emac hardware. It does NOT initialize
++ * EMAC modules power or pin multiplexors, that is done by board_init()
++ * much earlier in bootup process. Returns 1 on success, 0 otherwise.
++ */
++static int dm644x_eth_hw_init(void)
++{
++ u_int32_t phy_id;
++ u_int16_t tmp;
++ int i, ret;
++
++ /* The RMII clock can be sources internally through the SYSCLK7
++ * or can come externally through a dedicated pin. This selection is
++ * controlled by PinMux9[21]. PinMux registers are off-limits for ARM.
++ * In short, we just assume there is a 50MHz RMII clock available.
++ */
++
++ dm644x_eth_mdio_enable();
++
++ for (i = 0; i < 256; i++) {
++ if (adap_mdio->ALIVE)
++ break;
++ udelay(1000);
++ }
++
++ if (i >= 256) {
++ printf("No ETH PHY detected!!!\n");
++ return(0);
++ }
++
++ /* Find if a PHY is connected and get it's address */
++ ret = dm644x_eth_phy_detect();
++
++ if (ret == 2) {
++ printf("More than one PHY detected.\n");
++ return(1);
++ } else if(ret == 0)
++ return(0);
++
++ /* Get PHY ID and initialize phy_ops for a detected PHY */
++ if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR1, &tmp)) {
++ active_phy_addr = 0xff;
++ return(0);
++ }
++
++ phy_id = (tmp << 16) & 0xffff0000;
++
++ if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR2, &tmp)) {
++ active_phy_addr = 0xff;
++ return(0);
++ }
++
++ phy_id |= tmp & 0x0000ffff;
++
++ switch (phy_id) {
++ default:
++ sprintf(phy.name, "GENERIC @ 0x%02x", active_phy_addr);
++ phy.init = gen_init_phy;
++ phy.is_phy_connected = gen_is_phy_connected;
++ phy.get_link_speed = gen_get_link_speed;
++ phy.auto_negotiate = gen_auto_negotiate;
++ }
++
++ return(1);
++}
++
++
++/* Eth device open */
++static int dm644x_eth_open(void)
++{
++ dv_reg_p addr;
++ u_int32_t clkdiv, cnt;
++ volatile emac_desc *rx_desc;
++ int i;
++
++ debug_emac("+ emac_open\n");
++
++ /* Reset EMAC module and disable interrupts in wrapper */
++ adap_emac->SOFTRESET = 1;
++ while (adap_emac->SOFTRESET != 0) {;}
++ adap_ewrap->SOFTRESET = 1;
++ while (adap_ewrap->SOFTRESET != 0) {;}
++
++ adap_ewrap->C0RXEN = adap_ewrap->C1RXEN = adap_ewrap->C2RXEN = 0;
++ adap_ewrap->C0TXEN = adap_ewrap->C1TXEN = adap_ewrap->C2TXEN = 0;
++ adap_ewrap->C0MISCEN = adap_ewrap->C1MISCEN = adap_ewrap->C2MISCEN = 0;
++
++ rx_desc = emac_rx_desc;
++
++ adap_emac->TXCONTROL = 0x01;
++ adap_emac->RXCONTROL = 0x01;
++
++ /* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */
++ /* Using channel 0 only - other channels are disabled */
++ for (i = 0; i < 8; i++) {
++ adap_emac->MACINDEX = i;
++ adap_emac->MACADDRHI =
++ (dm644x_eth_mac_addr[3] << 24) | /* bits 23-16 */
++ (dm644x_eth_mac_addr[2] << 16) | /* bits 31-24 */
++ (dm644x_eth_mac_addr[1] << 8) | /* bits 39-32 */
++ (dm644x_eth_mac_addr[0]); /* bits 47-40 */
++ adap_emac->MACADDRLO =
++ (dm644x_eth_mac_addr[5] << 8) | /* bits 8-0*/
++ (dm644x_eth_mac_addr[4]) | (1 << 19) | (1 << 20); /* bits 8-0 */
++ }
++
++ adap_emac->MACHASH1 = 0;
++ adap_emac->MACHASH2 = 0;
++
++ /* Set source MAC address - REQUIRED for pause frames */
++ adap_emac->MACSRCADDRHI =
++ (dm644x_eth_mac_addr[3] << 24) | /* bits 23-16 */
++ (dm644x_eth_mac_addr[2] << 16) | /* bits 31-24 */
++ (dm644x_eth_mac_addr[1] << 8) | /* bits 39-32 */
++ (dm644x_eth_mac_addr[0]); /* bits 47-40 */
++ adap_emac->MACSRCADDRLO =
++ (dm644x_eth_mac_addr[5] << 8) | /* bits 8-0 */
++ (dm644x_eth_mac_addr[4]); /* bits 15-8 */
++
++ /* Set DMA 8 TX / 8 RX Head pointers to 0 */
++ addr = &adap_emac->TX0HDP;
++ for(cnt = 0; cnt < 16; cnt++)
++ *addr++ = 0;
++
++ addr = &adap_emac->TX0CP;
++ for(cnt = 0; cnt < 16; cnt++)
++ *addr++ = 0;
++
++ /* Clear Statistics (do this before setting MacControl register) */
++ addr = &adap_emac->RXGOODFRAMES;
++ for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
++ *addr++ = 0;
++
++ /* No multicast addressing */
++ adap_emac->MACHASH1 = 0;
++ adap_emac->MACHASH2 = 0;
++
++ /* Create RX queue and set receive process in place */
++ emac_rx_active_head = emac_rx_desc;
++ for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
++ rx_desc->next = (u_int32_t)(rx_desc + 1);
++ rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
++ rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
++ rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
++ rx_desc++;
++ }
++
++ /* Set the last descriptor's "next" parameter to 0 to end the RX desc list */
++ rx_desc--;
++ rx_desc->next = 0;
++ emac_rx_active_tail = rx_desc;
++ emac_rx_queue_active = 1;
++
++ /* Enable TX/RX */
++ adap_emac->RXMAXLEN = EMAC_MAX_ETHERNET_PKT_SIZE;
++ adap_emac->RXBUFFEROFFSET = 0;
++
++ /* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */
++ adap_emac->RXMBPENABLE = EMAC_RXMBPENABLE_RXBROADEN;
++
++ /* Enable ch 0 only */
++ adap_emac->RXUNICASTSET = 0x01;
++
++ /* Enable MII interface and Full duplex mode */
++ adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE) | EMAC_MACCONTROL_RMIISPEED_100;
++
++ /* Init MDIO & get link state */
++ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
++ adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
++
++ if (!phy.get_link_speed(active_phy_addr))
++ return(0);
++
++ /* Start receive process */
++ adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
++
++ debug_emac("- emac_open\n");
++
++ return(1);
++}
++
++/* EMAC Channel Teardown */
++static void dm644x_eth_ch_teardown(int ch)
++{
++ dv_reg dly = 0xff;
++ dv_reg cnt;
++
++ debug_emac("+ emac_ch_teardown\n");
++
++ if (ch == EMAC_CH_TX) {
++ /* Init TX channel teardown */
++ adap_emac->TXTEARDOWN = 1;
++ for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->TX0CP) {
++ /* Wait here for Tx teardown completion interrupt to occur
++ * Note: A task delay can be called here to pend rather than
++ * occupying CPU cycles - anyway it has been found that teardown
++ * takes very few cpu cycles and does not affect functionality */
++ dly--;
++ udelay(1);
++ if (dly == 0)
++ break;
++ }
++ adap_emac->TX0CP = cnt;
++ adap_emac->TX0HDP = 0;
++ } else {
++ /* Init RX channel teardown */
++ adap_emac->RXTEARDOWN = 1;
++ for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->RX0CP) {
++ /* Wait here for Rx teardown completion interrupt to occur
++ * Note: A task delay can be called here to pend rather than
++ * occupying CPU cycles - anyway it has been found that teardown
++ * takes very few cpu cycles and does not affect functionality */
++ dly--;
++ udelay(1);
++ if (dly == 0)
++ break;
++ }
++ adap_emac->RX0CP = cnt;
++ adap_emac->RX0HDP = 0;
++ }
++
++ debug_emac("- emac_ch_teardown\n");
++}
++
++/* Eth device close */
++static int dm644x_eth_close(void)
++{
++ debug_emac("+ emac_close\n");
++
++ dm644x_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */
++ dm644x_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */
++
++ /* Reset EMAC module and disable interrupts in wrapper */
++ adap_emac->SOFTRESET = 1;
++ adap_ewrap->SOFTRESET = 1;
++
++ adap_ewrap->C0RXEN = adap_ewrap->C1RXEN = adap_ewrap->C2RXEN = 0;
++ adap_ewrap->C0TXEN = adap_ewrap->C1TXEN = adap_ewrap->C2TXEN = 0;
++ adap_ewrap->C0MISCEN = adap_ewrap->C1MISCEN = adap_ewrap->C2MISCEN = 0;
++
++ debug_emac("- emac_close\n");
++ return(1);
++}
++
++static int tx_send_loop = 0;
++
++/*
++ * This function sends a single packet on the network and returns
++ * positive number (number of bytes transmitted) or negative for error
++ */
++static int dm644x_eth_send_packet(volatile void *packet, int length)
++{
++ int ret_status = -1;
++ tx_send_loop = 0;
++
++ /* Return error if no link */
++ if (!phy.get_link_speed(active_phy_addr))
++ {
++ printf("WARN: emac_send_packet: No link\n");
++ return (ret_status);
++ }
++
++ /* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
++ if (length < EMAC_MIN_ETHERNET_PKT_SIZE)
++ {
++ length = EMAC_MIN_ETHERNET_PKT_SIZE;
++ }
++
++ /* Populate the TX descriptor */
++ emac_tx_desc->next = 0;
++ emac_tx_desc->buffer = (u_int8_t *)packet;
++ emac_tx_desc->buff_off_len = (length & 0xffff);
++ emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
++ EMAC_CPPI_SOP_BIT |
++ EMAC_CPPI_OWNERSHIP_BIT |
++ EMAC_CPPI_EOP_BIT);
++ /* Send the packet */
++ adap_emac->TX0HDP = (unsigned int)emac_tx_desc;
++
++ /* Wait for packet to complete or link down */
++ while (1) {
++ if (!phy.get_link_speed(active_phy_addr)) {
++ dm644x_eth_ch_teardown(EMAC_CH_TX);
++ return (ret_status);
++ }
++ if (adap_emac->TXINTSTATRAW & 0x01) {
++ ret_status = length;
++ break;
++ }
++ tx_send_loop++;
++ }
++
++ return(ret_status);
++}
++
++/*
++ * This function handles receipt of a packet from the network
++ */
++static int dm644x_eth_rcv_packet(void)
++{
++ volatile emac_desc *rx_curr_desc;
++ volatile emac_desc *curr_desc;
++ volatile emac_desc *tail_desc;
++ int status, ret = -1;
++
++ rx_curr_desc = emac_rx_active_head;
++ status = rx_curr_desc->pkt_flag_len;
++ if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) {
++ if (status & EMAC_CPPI_RX_ERROR_FRAME) {
++ /* Error in packet - discard it and requeue desc */
++ printf("WARN: emac_rcv_pkt: Error in packet\n");
++ } else {
++ NetReceive(rx_curr_desc->buffer, (rx_curr_desc->buff_off_len & 0xffff));
++ ret = rx_curr_desc->buff_off_len & 0xffff;
++ }
++
++ /* Ack received packet descriptor */
++ adap_emac->RX0CP = (unsigned int)rx_curr_desc;
++ curr_desc = rx_curr_desc;
++ emac_rx_active_head = (volatile emac_desc *)rx_curr_desc->next;
++
++ if (status & EMAC_CPPI_EOQ_BIT) {
++ if (emac_rx_active_head) {
++ adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
++ } else {
++ emac_rx_queue_active = 0;
++ printf("INFO:emac_rcv_packet: RX Queue not active\n");
++ }
++ }
++
++ /* Recycle RX descriptor */
++ rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
++ rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
++ rx_curr_desc->next = 0;
++
++ if (emac_rx_active_head == 0) {
++ printf("INFO: emac_rcv_pkt: active queue head = 0\n");
++ emac_rx_active_head = curr_desc;
++ emac_rx_active_tail = curr_desc;
++ if (emac_rx_queue_active != 0) {
++ adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
++ printf("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
++ emac_rx_queue_active = 1;
++ }
++ } else {
++ tail_desc = emac_rx_active_tail;
++ emac_rx_active_tail = curr_desc;
++ tail_desc->next = (unsigned int)curr_desc;
++ status = tail_desc->pkt_flag_len;
++ if (status & EMAC_CPPI_EOQ_BIT) {
++ adap_emac->RX0HDP = (unsigned int)curr_desc;
++ status &= ~EMAC_CPPI_EOQ_BIT;
++ tail_desc->pkt_flag_len = status;
++ }
++ }
++ return(ret);
++ }
++ return(0);
++}
++
++#endif /* CONFIG_CMD_NET */
++
++#endif /* CONFIG_DRIVER_TI_EMAC */
+Index: u-boot-2009.01-primus/cpu/arm926ejs/da850/i2c.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/cpu/arm926ejs/da850/i2c.c
+@@ -0,0 +1,356 @@
++/*
++ * TI DaVinci (TMS320DM644x) I2C driver.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * --------------------------------------------------------
++ *
++ * 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>
++
++#ifdef CONFIG_DRIVER_DAVINCI_I2C
++
++#include <i2c.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/i2c_defs.h>
++
++#define CHECK_NACK() \
++ do {\
++ if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
++ REG(I2C_CON) = 0;\
++ return(1);\
++ }\
++ } while (0)
++
++
++static int wait_for_bus(void)
++{
++ int stat, timeout;
++
++ REG(I2C_STAT) = 0xffff;
++
++ for (timeout = 0; timeout < 10; timeout++) {
++ if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
++ REG(I2C_STAT) = 0xffff;
++ return(0);
++ }
++
++ REG(I2C_STAT) = stat;
++ udelay(50000);
++ }
++
++ REG(I2C_STAT) = 0xffff;
++ return(1);
++}
++
++
++static int poll_i2c_irq(int mask)
++{
++ int stat, timeout;
++
++ for (timeout = 0; timeout < 10; timeout++) {
++ udelay(1000);
++ stat = REG(I2C_STAT);
++ if (stat & mask) {
++ return(stat);
++ }
++ }
++
++ REG(I2C_STAT) = 0xffff;
++ return(stat | I2C_TIMEOUT);
++}
++
++
++void flush_rx(void)
++{
++ int dummy;
++
++ while (1) {
++ if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
++ break;
++
++ dummy = REG(I2C_DRR);
++ REG(I2C_STAT) = I2C_STAT_RRDY;
++ udelay(1000);
++ }
++}
++
++
++void i2c_init(int speed, int slaveadd)
++{
++ u_int32_t div, psc;
++
++ if (REG(I2C_CON) & I2C_CON_EN) {
++ REG(I2C_CON) = 0;
++ udelay (50000);
++ }
++
++ /* Get 1MHz into I2C internal */
++ psc = CONFIG_SYS_HZ_CLOCK/1000000;
++
++ div = CONFIG_SYS_HZ_CLOCK / (psc * speed); /* SCLL + SCLH */
++
++ REG(I2C_PSC) = psc - 1; /* 27MHz / (2 + 1) = 9MHz */
++ REG(I2C_SCLL) = (div * 50) / 100; /* 50% Duty */
++ REG(I2C_SCLH) = div - REG(I2C_SCLL);
++
++ REG(I2C_OA) = slaveadd;
++ REG(I2C_CNT) = 0;
++
++ /* Interrupts must be enabled or I2C module won't work */
++ REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
++ I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
++
++ /* Now enable I2C controller (get it out of reset) */
++ REG(I2C_CON) = I2C_CON_EN;
++
++ udelay(1000);
++}
++
++
++int i2c_probe(u_int8_t chip)
++{
++ int rc = 1;
++
++ if (chip == REG(I2C_OA)) {
++ return(rc);
++ }
++
++ REG(I2C_CON) = 0;
++ if (wait_for_bus()) {return(1);}
++
++ /* try to read one byte from current (or only) address */
++ REG(I2C_CNT) = 1;
++ REG(I2C_SA) = chip;
++ REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP | I2C_CON_FREE);
++ udelay (50000);
++
++ if (!(REG(I2C_STAT) & I2C_STAT_NACK)) {
++ rc = 0;
++ flush_rx();
++ REG(I2C_STAT) = 0xffff;
++ } else {
++ REG(I2C_STAT) = 0xffff;
++ REG(I2C_CON) |= I2C_CON_STP;
++ udelay(20000);
++ if (wait_for_bus()) {return(1);}
++ }
++
++ flush_rx();
++ REG(I2C_STAT) = 0xffff;
++ REG(I2C_CNT) = 0;
++ return(rc);
++}
++
++
++int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
++{
++ u_int32_t tmp;
++ int i;
++
++ if ((alen < 0) || (alen > 2)) {
++ printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
++ return(1);
++ }
++
++ if (wait_for_bus()) {return(1);}
++
++ if (alen != 0) {
++ /* Start address phase */
++ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
++ I2C_CON_FREE;
++ REG(I2C_CNT) = alen;
++ REG(I2C_SA) = chip;
++ REG(I2C_CON) = tmp;
++
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ switch (alen) {
++ case 2:
++ /* Send address MSByte */
++ if (tmp & I2C_STAT_XRDY) {
++ REG(I2C_DXR) = (addr >> 8) & 0xff;
++ } else {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ CHECK_NACK();
++ /* No break, fall through */
++ case 1:
++ /* Send address LSByte */
++ if (tmp & I2C_STAT_XRDY) {
++ REG(I2C_DXR) = addr & 0xff;
++ } else {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY);
++
++ CHECK_NACK();
++
++ if (!(tmp & I2C_STAT_ARDY)) {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++ }
++ }
++
++ /* Address phase is over, now read 'len' bytes and stop */
++ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP | I2C_CON_FREE;
++ REG(I2C_CNT) = len & 0xffff;
++ REG(I2C_SA) = chip;
++ REG(I2C_CON) = tmp;
++
++ for (i = 0; i < len; i++) {
++ tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR);
++
++ CHECK_NACK();
++
++ if (tmp & I2C_STAT_RRDY) {
++ buf[i] = REG(I2C_DRR);
++ } else {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++ }
++
++ tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ if (!(tmp & I2C_STAT_SCD)) {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++
++ flush_rx();
++ REG(I2C_STAT) = 0xffff;
++ REG(I2C_CNT) = 0;
++ REG(I2C_CON) = 0;
++
++ return(0);
++}
++
++
++int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
++{
++ u_int32_t tmp;
++ int i;
++
++ if ((alen < 0) || (alen > 2)) {
++ printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
++ return(1);
++ }
++ if (len < 0) {
++ printf("%s(): bogus length %x\n", __FUNCTION__, len);
++ return(1);
++ }
++
++ if (wait_for_bus()) {return(1);}
++
++ /* Start address phase */
++ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP;
++ REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
++ REG(I2C_SA) = chip;
++ REG(I2C_CON) = tmp;
++
++ switch (alen) {
++ case 2:
++ /* Send address MSByte */
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ if (tmp & I2C_STAT_XRDY) {
++ REG(I2C_DXR) = (addr >> 8) & 0xff;
++ } else {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++ /* No break, fall through */
++ case 1:
++ /* Send address LSByte */
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ if (tmp & I2C_STAT_XRDY) {
++ REG(I2C_DXR) = addr & 0xff;
++ } else {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++ }
++
++ for (i = 0; i < len; i++) {
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ if (tmp & I2C_STAT_XRDY) {
++ REG(I2C_DXR) = buf[i];
++ } else {
++ return(1);
++ }
++ }
++
++ tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ if (!(tmp & I2C_STAT_SCD)) {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++
++ flush_rx();
++ REG(I2C_STAT) = 0xffff;
++ REG(I2C_CNT) = 0;
++ REG(I2C_CON) = 0;
++
++ return(0);
++}
++
++#if 0
++u_int8_t i2c_reg_read(u_int8_t chip, u_int8_t reg)
++{
++ u_int8_t tmp;
++
++ i2c_read(chip, reg, 1, &tmp, 1);
++ return(tmp);
++}
++
++
++void i2c_reg_write(u_int8_t chip, u_int8_t reg, u_int8_t val)
++{
++ u_int8_t tmp;
++
++ i2c_write(chip, reg, 1, &tmp, 1);
++}
++#endif /* if 0 */
++
++#endif /* CONFIG_DRIVER_DAVINCI_I2C */
+Index: u-boot-2009.01-primus/cpu/arm926ejs/da850/lowlevel_init.S
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/cpu/arm926ejs/da850/lowlevel_init.S
+@@ -0,0 +1,504 @@
++/*
++ * Low-level board setup code for TI DA8xx SoC based boards.
++ *
++ * Copyright (C) 2008 Texas Instruments, Inc <www.ti.com>
++ * Sekhar Nori <nsekhar@ti.com>
++ *
++ * Based on TI DaVinci low level init code. Original copyrights follow.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Partially based on TI sources, original copyrights follow:
++ */
++
++/*
++ * Board specific setup info
++ *
++ * (C) Copyright 2003
++ * Texas Instruments, <www.ti.com>
++ * Kshitij Gupta <Kshitij@ti.com>
++ *
++ * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
++ *
++ * Modified for OMAP 5912 OSK board by Rishi Bhattacharya, Apr 2004
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * Modified for DV-EVM board by Rishi Bhattacharya, Apr 2005
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * Modified for DV-EVM board by Swaminathan S, Nov 2005
++ * 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>
++#include <asm/arch/hardware.h>
++
++.globl lowlevel_init
++lowlevel_init:
++
++ nop
++ nop
++ nop
++ nop
++
++ /*
++ * Call board-specific lowlevel init.
++ * That MUST be present and THAT returns
++ * back to arch calling code with "mov pc, lr."
++ */
++ b dv_board_init
++
++#ifndef CONFIG_USE_IRQ
++ /*-------------------------------------------------------*
++ * Mask all IRQs by clearing the global enable and setting
++ * the enable clear for all the 90 interrupts.
++ *-------------------------------------------------------*/
++ mov r1, $0
++ ldr r0, INTC_GLB_EN_ADDR
++ str r1, [r0]
++
++ ldr r0, INTC_HINT_EN_ADDR
++ str r1, [r0]
++ add r0, r0, $4
++ str r1, [r0]
++ add r0, r0, $4
++ str r1, [r0]
++
++ mvn r1, r1
++ ldr r0, INTC_EN_CLR0_ADDR
++ str r1, [r0]
++ add r0, r0, $4
++ str r1, [r0]
++ add r0, r0, $4
++ str r1, [r0]
++#endif
++
++ /*------------------------------------------------------*
++ * PLL0 Initialization - works only in non-secure devices
++ *------------------------------------------------------*/
++
++ /* TODO: Write the kick values and the PLL master lock bits */
++
++ /* Select OSCIN in clockmode bit in PLLCTL register. This is the only
++ * clock mode supported on DA8xx
++ */
++ ldr r6, PLL0_PLLCTL_ADDR
++ ldr r7, PLL_CLKSRC_MASK
++ ldr r8, [r6]
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* Clear the PLLENSRC bit in PLLCTL */
++ ldr r7, PLL_ENSRC_MASK
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* Bypass the PLL */
++ ldr r7, PLL_BYPASS_MASK
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */
++ mov r10, $0x20
++WaitPLL0Loop:
++ subs r10, r10, $1
++ bne WaitPLL0Loop
++
++ /* Reset the PLL */
++ ldr r7, PLL_RESET_MASK
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* disable PLL output */
++ mov r7, $0x10
++ orr r8, r8, r7
++ str r8, [r6]
++
++ /* Power up the PLL */
++ ldr r7, PLL_PWRUP_MASK
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* Enable the PLL from Disable Mode */
++ ldr r7, PLL_DISABLE_ENABLE_MASK
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* Wait for the PLL stabilization time - 150us assumed */
++ mov r10, $0xE10
++PLLStableLoop:
++ subs r10, r10, $1
++ bne PLLStableLoop
++
++ /* Program the PLL Multiplier */
++ ldr r6, PLL0_PLLM_ADDR
++ mov r2, $0x18 /* 24 * 25 = 600MHz*/
++ str r2, [r6]
++
++ /* Program the POSTDIV Value */
++ ldr r6, PLL0_POSTDIV_ADDR
++ mov r3, $0x01
++ mov r3, r3, lsl $15
++ orr r3, r3, $0x01
++ str r3, [r6]
++
++ /* Program the SYSCLKx dividedrs */
++
++ /* Following defaults are good:
++ * SYSCLK1 = /1 => 300MHz GEM
++ * SYSCLK2 = /2 => 150MHz EDMA, MMC/SD, UART1/2, SPI1
++ * SYSCLK3 = /3 => 100MHz Possible EMIF2.5
++ * SYSCLK4 = /4 => 75MHz INTC, PSC, EMAC, USB 1.1, I2C1
++ * SYSCLK5 = /3 => 100MHz Possible EMIF3.0 (use DIV4p5)
++ * SYSCLK6 = /1 => 300MHz ARM
++ * SYSCLK7 = /6 => 50MHz RMII Ref Clk
++ * SYSCLK8 = /6 => 50MHz Dont use
++ * SYSCLK9 = /6 => 50MHz Dont use
++ * AUXCLK FIXED => 24Mhz Timer 0/1, 12C0, McASP AuxClk
++ */
++
++ /* Wait for PLL to Reset Properly - 128 OSCIN cycles*/
++ mov r10, $128
++ResetPPL2Loop:
++ subs r10, r10, $1
++ bne ResetPPL2Loop
++
++ /* Bring PLL out of Reset */
++ ldr r6, PLL0_PLLCTL_ADDR
++ ldr r8, [r6]
++ orr r8, r8, $0x08
++ str r8, [r6]
++
++ /* Wait for PLL to Lock */
++ ldr r10, PLL_LOCK_COUNT
++PLL0Lock:
++ subs r10, r10, $1
++ bne PLL0Lock
++
++ /* Enable the PLL */
++ ldr r6, PLL0_PLLCTL_ADDR
++ ldr r8, [r6]
++ orr r8, r8, $0x01
++ str r8, [r6]
++
++ /*------------------------------------------------------*
++ * Setup the pinmux for DDR2 *
++ *------------------------------------------------------*/
++
++ ldr r0, PINMUX1_ADDR
++ ldr r1, PINMUX1_VAL
++ str r1, [r0]
++
++ ldr r0, PINMUX2_ADDR
++ ldr r1, PINMUX2_VAL
++ str r1, [r0]
++
++ ldr r0, PINMUX5_ADDR
++ ldr r1, PINMUX5_VAL
++ str r1, [r0]
++
++ ldr r0, PINMUX6_ADDR
++ ldr r1, PINMUX6_VAL
++ str r1, [r0]
++
++ ldr r8, PINMUX7_FLAG_CLEAR
++ ldr r7, PINMUX7_VAL
++ ldr r0, PINMUX7_ADDR
++ ldr r1, [r0]
++ and r1, r1, r8
++ orr r1, r1, r7
++ str r1, [r0]
++
++
++ /*------------------------------------------------------*
++ * Get the EMIF3 out of reset *
++ *------------------------------------------------------*/
++
++ /* Shut down the DDR2 LPSC Module */
++ ldr r8, PSC_FLAG_CLEAR
++ ldr r6, MDCTL_EMIF3
++ ldr r7, [r6]
++ and r7, r7, r8
++ orr r7, r7, $0x03
++ str r7, [r6]
++
++ /* Enable the Power Domain Transition Command */
++ ldr r6, PSC1_PTCMD_ADDR
++ ldr r7, [r6]
++ orr r7, r7, $0x01
++ str r7, [r6]
++
++ /* Check for Transition Complete(PTSTAT) */
++checkStatClkStop0:
++ ldr r6, PSC1_PTSTAT_ADDR
++ ldr r7, [r6]
++ ands r7, r7, $0x01
++ bne checkStatClkStop0
++
++ /* Check for DDR2 Controller Enable Completion */
++checkDDRStatClkStop0:
++ ldr r6, MDSTAT_EMIF3
++ ldr r7, [r6]
++ and r7, r7, $0x1f
++ cmp r7, $0x03
++ bne checkDDRStatClkStop0
++
++ /*------------------------------------------------------*
++ * Put the EMIF3 in reset *
++ *------------------------------------------------------*/
++
++ /* Shut down the DDR2 LPSC Module */
++ ldr r8, PSC_FLAG_CLEAR
++ ldr r6, MDCTL_EMIF3
++ ldr r7, [r6]
++ and r7, r7, r8
++ orr r7, r7, $0x01
++ str r7, [r6]
++
++ /* Enable the Power Domain Transition Command */
++ ldr r6, PSC1_PTCMD_ADDR
++ ldr r7, [r6]
++ orr r7, r7, $0x01
++ str r7, [r6]
++
++ /* Check for Transition Complete(PTSTAT) */
++checkStatClkStop1:
++ ldr r6, PSC1_PTSTAT_ADDR
++ ldr r7, [r6]
++ ands r7, r7, $0x01
++ bne checkStatClkStop1
++
++ /* Check for DDR2 Controller Enable Completion */
++checkDDRStatClkStop1:
++ ldr r6, MDSTAT_EMIF3
++ ldr r7, [r6]
++ and r7, r7, $0x1f
++ cmp r7, $0x01
++ bne checkDDRStatClkStop1
++
++ nop
++ nop
++
++ /*------------------------------------------------------*
++ * Get the EMIF3 out of reset *
++ *------------------------------------------------------*/
++
++ /* Shut down the DDR2 LPSC Module */
++ ldr r8, PSC_FLAG_CLEAR
++ ldr r6, MDCTL_EMIF3
++ ldr r7, [r6]
++ and r7, r7, r8
++ orr r7, r7, $0x03
++ str r7, [r6]
++
++ /* Enable the Power Domain Transition Command */
++ ldr r6, PSC1_PTCMD_ADDR
++ ldr r7, [r6]
++ orr r7, r7, $0x01
++ str r7, [r6]
++
++ /* Check for Transition Complete(PTSTAT) */
++checkStatClkStop2:
++ ldr r6, PSC1_PTSTAT_ADDR
++ ldr r7, [r6]
++ ands r7, r7, $0x01
++ bne checkStatClkStop2
++
++ /* Check for DDR2 Controller Enable Completion */
++checkDDRStatClkStop2:
++ ldr r6, MDSTAT_EMIF3
++ ldr r7, [r6]
++ and r7, r7, $0x1f
++ cmp r7, $0x03
++ bne checkDDRStatClkStop2
++
++ nop
++ nop
++
++ /*-----------------------------------------------------*
++ * Wait before programing the SDRAM timimg values *
++ *-----------------------------------------------------*/
++
++ ldr r10, EMIF3_TIMING_WAIT_VAL
++emif3TimingWait:
++ sub r10, r10, $0x1
++ cmp r10, $0x0
++ bne emif3TimingWait
++
++ /*------------------------------------------------------*
++ * Program EMIF3 MMRs for 133MHz SDRAM Setting *
++ *------------------------------------------------------*/
++
++ /* Program SDRAM Bank Config Register */
++ ldr r6, SDCFG
++ ldr r7, SDCFG_VAL
++ str r7, [r6]
++
++ /* Program SDRAM TIM-0 Config Register */
++ ldr r6, SDTIM0
++ ldr r7, SDTIM0_VAL_162MHz
++ str r7, [r6]
++
++ /* Program SDRAM TIM-1 Config Register */
++ ldr r6, SDTIM1
++ ldr r7, SDTIM1_VAL_162MHz
++ str r7, [r6]
++
++ /* Program the SDRAM Bank Config Control Register */
++ ldr r10, MASK_VAL
++ ldr r8, SDCFG
++ ldr r9, SDCFG_VAL
++ and r9, r9, r10
++ str r9, [r8]
++
++ /* Program SDRAM SDREF Config Register */
++ ldr r6, SDREF
++ ldr r7, SDREF_VAL
++ str r7, [r6]
++
++ /* Issue a Dummy DDR2 read/write */
++ ldr r8, DDR2_START_ADDR
++ ldr r7, DUMMY_VAL
++ str r7, [r8]
++ ldr r7, [r8]
++
++ /* DDR Writes and Reads */
++ ldr r6, CFGTEST
++ mov r3, $0x01
++ str r3, [r6]
++
++ nop
++ nop
++ nop
++ nop
++
++ /*
++ * Call board-specific lowlevel init.
++ * That MUST be present and THAT returns
++ * back to arch calling code with "mov pc, lr."
++ */
++ b dv_board_init
++
++.ltorg
++
++PINMUX1_ADDR:
++ .word PINMUX1
++PINMUX2_ADDR:
++ .word PINMUX2
++PINMUX5_ADDR:
++ .word PINMUX5
++PINMUX6_ADDR:
++ .word PINMUX6
++PINMUX7_ADDR:
++ .word PINMUX7
++PINMUX1_VAL:
++ .word 0x11111111
++PINMUX2_VAL:
++ .word 0x01111111
++PINMUX5_VAL:
++ .word 0x11111110
++PINMUX6_VAL:
++ .word 0x11111111
++PINMUX7_FLAG_CLEAR:
++ .word 0xFFFFF000
++PINMUX7_VAL:
++ .word 0x111
++
++
++MDCTL_EMIF3:
++ .word PSC1_MDCTL + 4 * 6
++MDSTAT_EMIF3:
++ .word PSC1_MDSTAT + 4 * 6
++
++PSC1_PTCMD_ADDR:
++ .word PSC1_PTCMD
++PSC1_PTSTAT_ADDR:
++ .word PSC1_PTSTAT
++
++INTC_GLB_EN_ADDR:
++ .word INTC_GLB_EN
++INTC_EN_CLR0_ADDR:
++ .word INTC_EN_CLR0
++INTC_HINT_EN_ADDR:
++ .word INTC_HINT_EN
++
++PSC_FLAG_CLEAR:
++ .word 0xffffffe0
++PSC_GEM_FLAG_CLEAR:
++ .word 0xfffffeff
++
++/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */
++SDREF:
++ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0xc
++SDREF_VAL:
++ .word 0x000005c3
++SDCFG:
++ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0x8
++SDCFG_VAL:
++#ifdef SDRAM_4BANKS_10COLS
++ .word 0x00178622
++#elif defined SDRAM_8BANKS_10COLS
++ .word 0x00178632
++#else
++#error "Unknown SDRAM configuration!!!"
++#endif
++SDTIM0:
++ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0x10
++SDTIM0_VAL_162MHz:
++ .word 0x28923211
++SDTIM1:
++ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0x14
++SDTIM1_VAL_162MHz:
++ .word 0x0016c722
++CFGTEST:
++ .word DAVINCI_DDR_EMIF_DATA_BASE + 0x10000
++MASK_VAL:
++ .word 0x00000fff
++EMIF3_TIMING_WAIT_VAL:
++ .word 990000
++
++PLL_CLKSRC_MASK:
++ .word 0xfffffeff /* Mask the Clock Mode bit */
++PLL_ENSRC_MASK:
++ .word 0xffffffdf /* Select the PLLEN source */
++PLL_BYPASS_MASK:
++ .word 0xfffffffe /* Put the PLL in BYPASS */
++PLL_RESET_MASK:
++ .word 0xfffffff7 /* Put the PLL in Reset Mode */
++PLL_PWRUP_MASK:
++ .word 0xfffffffd /* PLL Power up Mask Bit */
++PLL_DISABLE_ENABLE_MASK:
++ .word 0xffffffef /* Enable the PLL from Disable */
++PLL_LOCK_COUNT:
++ .word 2000
++
++/* PLL0 MMRs */
++PLL0_PLLCTL_ADDR:
++ .word PLL0_PLLCTL
++PLL0_PLLM_ADDR:
++ .word PLL0_PLLM
++PLL0_POSTDIV_ADDR:
++ .word PLL0_POSTDIV
++
++DDR2_START_ADDR:
++ .word 0xc0000000
++DUMMY_VAL:
++ .word 0xa55aa55a
+Index: u-boot-2009.01-primus/cpu/arm926ejs/da850/nand.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/cpu/arm926ejs/da850/nand.c
+@@ -0,0 +1,475 @@
++/*
++ * NAND driver for TI DaVinci based boards.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Based on Linux DaVinci NAND driver by TI. Original copyright follows:
++ */
++
++/*
++ *
++ * linux/drivers/mtd/nand/nand_davinci.c
++ *
++ * NAND Flash Driver
++ *
++ * Copyright (C) 2006 Texas Instruments.
++ *
++ * ----------------------------------------------------------------------------
++ *
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++ *
++ * Overview:
++ * This is a device driver for the NAND flash device found on the
++ * DaVinci board which utilizes the Samsung k9k2g08 part.
++ *
++ Modifications:
++ ver. 1.0: Feb 2005, Vinod/Sudhakar
++ -
++ *
++ */
++
++#include <common.h>
++#include <asm/io.h>
++
++#ifdef CONFIG_SYS_USE_NAND
++#if !defined(CONFIG_NAND_LEGACY)
++
++#include <nand.h>
++#include <asm/arch/nand_defs.h>
++#include <asm/arch/emif_defs.h>
++
++extern struct nand_chip nand_dev_desc[CONFIG_SYS_MAX_NAND_DEVICE];
++
++static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
++{
++ struct nand_chip *this = mtd->priv;
++ u_int32_t IO_ADDR_W = (u_int32_t)this->IO_ADDR_W;
++
++ IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
++
++ if (ctrl & NAND_CTRL_CHANGE) {
++ if ( ctrl & NAND_CLE )
++ IO_ADDR_W |= MASK_CLE;
++ if ( ctrl & NAND_ALE )
++ IO_ADDR_W |= MASK_ALE;
++ this->IO_ADDR_W = (void __iomem *) IO_ADDR_W;
++ }
++
++ if (cmd != NAND_CMD_NONE)
++ writeb(cmd, this->IO_ADDR_W);
++}
++
++/* Set WP on deselect, write enable on select */
++static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
++{
++#define GPIO_SET_DATA01 0x01c67018
++#define GPIO_CLR_DATA01 0x01c6701c
++#define GPIO_NAND_WP (1 << 4)
++#ifdef SONATA_BOARD_GPIOWP
++ if (chip < 0) {
++ REG(GPIO_CLR_DATA01) |= GPIO_NAND_WP;
++ } else {
++ REG(GPIO_SET_DATA01) |= GPIO_NAND_WP;
++ }
++#endif
++}
++
++#ifdef CONFIG_SYS_NAND_HW_ECC
++#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
++/* Linux-compatible ECC uses MTD defaults. */
++/* These layouts are not compatible with Linux or RBL/UBL. */
++#ifdef CONFIG_SYS_NAND_LARGEPAGE
++static struct nand_ecclayout davinci_nand_ecclayout = {
++ .eccbytes = 12,
++ .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58},
++ .oobfree = {
++ {.offset = 2, .length = 6},
++ {.offset = 12, .length = 12},
++ {.offset = 28, .length = 12},
++ {.offset = 44, .length = 12},
++ {.offset = 60, .length = 4}
++ }
++};
++#elif defined(CONFIG_SYS_NAND_SMALLPAGE)
++static struct nand_ecclayout davinci_nand_ecclayout = {
++ .eccbytes = 3,
++ .eccpos = {0, 1, 2},
++ .oobfree = {
++ {.offset = 6, .length = 2},
++ {.offset = 8, .length = 8}
++ }
++};
++#else
++#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!"
++#endif
++#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
++
++static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
++{
++ emifregs emif_addr;
++ int dummy;
++
++ emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
++
++ dummy = emif_addr->NANDF1ECC;
++ dummy = emif_addr->NANDF2ECC;
++ dummy = emif_addr->NANDF3ECC;
++ dummy = emif_addr->NANDF4ECC;
++
++ emif_addr->NANDFCR |= (1 << 8);
++}
++
++static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
++{
++ u_int32_t ecc = 0;
++ emifregs emif_base_addr;
++
++ emif_base_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
++
++ if (region == 1)
++ ecc = emif_base_addr->NANDF1ECC;
++ else if (region == 2)
++ ecc = emif_base_addr->NANDF2ECC;
++ else if (region == 3)
++ ecc = emif_base_addr->NANDF3ECC;
++ else if (region == 4)
++ ecc = emif_base_addr->NANDF4ECC;
++
++ return(ecc);
++}
++
++static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
++{
++ u_int32_t tmp;
++#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
++ /*
++ * This is not how you should read ECCs on large page Davinci devices.
++ * The region parameter gets you ECCs for flash chips on different chip
++ * selects, not the 4x512 byte pages in a 2048 byte page.
++ *
++ * Preserved for backwards compatibility though.
++ */
++
++ int region, n;
++ struct nand_chip *this = mtd->priv;
++
++ n = (this->ecc.size/512);
++
++ region = 1;
++ while (n--) {
++ tmp = nand_davinci_readecc(mtd, region);
++ *ecc_code++ = tmp;
++ *ecc_code++ = tmp >> 16;
++ *ecc_code++ = ((tmp >> 8) & 0x0f) | ((tmp >> 20) & 0xf0);
++ region++;
++ }
++#else
++ const int region = 1;
++
++ tmp = nand_davinci_readecc(mtd, region);
++
++ /* Squeeze 4 bytes ECC into 3 bytes by removing RESERVED bits
++ * and shifting. RESERVED bits are 31 to 28 and 15 to 12. */
++ tmp = (tmp & 0x00000fff) | ((tmp & 0x0fff0000) >> 4);
++
++ /* Invert so that erased block ECC is correct */
++ tmp = ~tmp;
++
++ *ecc_code++ = tmp;
++ *ecc_code++ = tmp >> 8;
++ *ecc_code++ = tmp >> 16;
++#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
++ return(0);
++}
++
++#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
++static void nand_davinci_gen_true_ecc(u_int8_t *ecc_buf)
++{
++ u_int32_t tmp = ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xf0) << 20) | ((ecc_buf[2] & 0x0f) << 8);
++
++ ecc_buf[0] = ~(P64o(tmp) | P64e(tmp) | P32o(tmp) | P32e(tmp) | P16o(tmp) | P16e(tmp) | P8o(tmp) | P8e(tmp));
++ ecc_buf[1] = ~(P1024o(tmp) | P1024e(tmp) | P512o(tmp) | P512e(tmp) | P256o(tmp) | P256e(tmp) | P128o(tmp) | P128e(tmp));
++ ecc_buf[2] = ~( P4o(tmp) | P4e(tmp) | P2o(tmp) | P2e(tmp) | P1o(tmp) | P1e(tmp) | P2048o(tmp) | P2048e(tmp));
++}
++
++static int nand_davinci_compare_ecc(u_int8_t *ecc_nand, u_int8_t *ecc_calc, u_int8_t *page_data)
++{
++ u_int32_t i;
++ u_int8_t tmp0_bit[8], tmp1_bit[8], tmp2_bit[8];
++ u_int8_t comp0_bit[8], comp1_bit[8], comp2_bit[8];
++ u_int8_t ecc_bit[24];
++ u_int8_t ecc_sum = 0;
++ u_int8_t find_bit = 0;
++ u_int32_t find_byte = 0;
++ int is_ecc_ff;
++
++ is_ecc_ff = ((*ecc_nand == 0xff) && (*(ecc_nand + 1) == 0xff) && (*(ecc_nand + 2) == 0xff));
++
++ nand_davinci_gen_true_ecc(ecc_nand);
++ nand_davinci_gen_true_ecc(ecc_calc);
++
++ for (i = 0; i <= 2; i++) {
++ *(ecc_nand + i) = ~(*(ecc_nand + i));
++ *(ecc_calc + i) = ~(*(ecc_calc + i));
++ }
++
++ for (i = 0; i < 8; i++) {
++ tmp0_bit[i] = *ecc_nand % 2;
++ *ecc_nand = *ecc_nand / 2;
++ }
++
++ for (i = 0; i < 8; i++) {
++ tmp1_bit[i] = *(ecc_nand + 1) % 2;
++ *(ecc_nand + 1) = *(ecc_nand + 1) / 2;
++ }
++
++ for (i = 0; i < 8; i++) {
++ tmp2_bit[i] = *(ecc_nand + 2) % 2;
++ *(ecc_nand + 2) = *(ecc_nand + 2) / 2;
++ }
++
++ for (i = 0; i < 8; i++) {
++ comp0_bit[i] = *ecc_calc % 2;
++ *ecc_calc = *ecc_calc / 2;
++ }
++
++ for (i = 0; i < 8; i++) {
++ comp1_bit[i] = *(ecc_calc + 1) % 2;
++ *(ecc_calc + 1) = *(ecc_calc + 1) / 2;
++ }
++
++ for (i = 0; i < 8; i++) {
++ comp2_bit[i] = *(ecc_calc + 2) % 2;
++ *(ecc_calc + 2) = *(ecc_calc + 2) / 2;
++ }
++
++ for (i = 0; i< 6; i++)
++ ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2];
++
++ for (i = 0; i < 8; i++)
++ ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i];
++
++ for (i = 0; i < 8; i++)
++ ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i];
++
++ ecc_bit[22] = tmp2_bit[0] ^ comp2_bit[0];
++ ecc_bit[23] = tmp2_bit[1] ^ comp2_bit[1];
++
++ for (i = 0; i < 24; i++)
++ ecc_sum += ecc_bit[i];
++
++ switch (ecc_sum) {
++ case 0:
++ /* Not reached because this function is not called if
++ ECC values are equal */
++ return 0;
++ case 1:
++ /* Uncorrectable error */
++ MTDDEBUG (MTD_DEBUG_LEVEL0,
++ "ECC UNCORRECTED_ERROR 1\n");
++ return(-1);
++ case 12:
++ /* Correctable error */
++ find_byte = (ecc_bit[23] << 8) +
++ (ecc_bit[21] << 7) +
++ (ecc_bit[19] << 6) +
++ (ecc_bit[17] << 5) +
++ (ecc_bit[15] << 4) +
++ (ecc_bit[13] << 3) +
++ (ecc_bit[11] << 2) +
++ (ecc_bit[9] << 1) +
++ ecc_bit[7];
++
++ find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
++
++ MTDDEBUG (MTD_DEBUG_LEVEL0, "Correcting single bit ECC "
++ "error at offset: %d, bit: %d\n",
++ find_byte, find_bit);
++
++ page_data[find_byte] ^= (1 << find_bit);
++
++ return(0);
++ default:
++ if (is_ecc_ff) {
++ if (ecc_calc[0] == 0 && ecc_calc[1] == 0 && ecc_calc[2] == 0)
++ return(0);
++ }
++ MTDDEBUG (MTD_DEBUG_LEVEL0,
++ "UNCORRECTED_ERROR default\n");
++ return(-1);
++ }
++}
++#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
++
++static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
++{
++ struct nand_chip *this = mtd->priv;
++#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
++ int block_count = 0, i, rc;
++
++ block_count = (this->ecc.size/512);
++ for (i = 0; i < block_count; i++) {
++ if (memcmp(read_ecc, calc_ecc, 3) != 0) {
++ rc = nand_davinci_compare_ecc(read_ecc, calc_ecc, dat);
++ if (rc < 0) {
++ return(rc);
++ }
++ }
++ read_ecc += 3;
++ calc_ecc += 3;
++ dat += 512;
++ }
++#else
++ u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) |
++ (read_ecc[2] << 16);
++ u_int32_t ecc_calc = calc_ecc[0] | (calc_ecc[1] << 8) |
++ (calc_ecc[2] << 16);
++ u_int32_t diff = ecc_calc ^ ecc_nand;
++
++ if (diff) {
++ if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
++ /* Correctable error */
++ if ((diff >> (12 + 3)) < this->ecc.size) {
++ uint8_t find_bit = 1 << ((diff >> 12) & 7);
++ uint32_t find_byte = diff >> (12 + 3);
++
++ dat[find_byte] ^= find_bit;
++ MTDDEBUG(MTD_DEBUG_LEVEL0, "Correcting single "
++ "bit ECC error at offset: %d, bit: "
++ "%d\n", find_byte, find_bit);
++ return 1;
++ } else {
++ return -1;
++ }
++ } else if (!(diff & (diff - 1))) {
++ /* Single bit ECC error in the ECC itself,
++ nothing to fix */
++ MTDDEBUG(MTD_DEBUG_LEVEL0, "Single bit ECC error in "
++ "ECC.\n");
++ return 1;
++ } else {
++ /* Uncorrectable error */
++ MTDDEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
++ return -1;
++ }
++ }
++#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
++ return(0);
++}
++#endif /* CONFIG_SYS_NAND_HW_ECC */
++
++static int nand_davinci_dev_ready(struct mtd_info *mtd)
++{
++ emifregs emif_addr;
++
++ emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
++
++ return(emif_addr->NANDFSR & 0x1);
++}
++
++static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
++{
++ while(!nand_davinci_dev_ready(mtd)) {;}
++ *NAND_CE0CLE = NAND_STATUS;
++ return(*NAND_CE0DATA);
++}
++
++static void nand_flash_init(void)
++{
++ u_int32_t acfg1 = 0x3ffffffc;
++ u_int32_t acfg2 = 0x3ffffffc;
++ u_int32_t acfg3 = 0x3ffffffc;
++ u_int32_t acfg4 = 0x3ffffffc;
++ emifregs emif_regs;
++
++ /*------------------------------------------------------------------*
++ * NAND FLASH CHIP TIMEOUT @ 459 MHz *
++ * *
++ * AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz *
++ * AEMIF.CLK period = 1/76.5 MHz = 13.1 ns *
++ * *
++ *------------------------------------------------------------------*/
++ acfg1 = 0
++ | (0 << 31 ) /* selectStrobe */
++ | (0 << 30 ) /* extWait */
++ | (1 << 26 ) /* writeSetup 10 ns */
++ | (3 << 20 ) /* writeStrobe 40 ns */
++ | (1 << 17 ) /* writeHold 10 ns */
++ | (1 << 13 ) /* readSetup 10 ns */
++ | (5 << 7 ) /* readStrobe 60 ns */
++ | (1 << 4 ) /* readHold 10 ns */
++ | (3 << 2 ) /* turnAround ?? ns */
++ | (0 << 0 ) /* asyncSize 8-bit bus */
++ ;
++
++ emif_regs = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
++
++ emif_regs->AWCCR |= 0x10000000;
++ emif_regs->AB1CR = acfg1; /* 0x08244128 */;
++ emif_regs->AB2CR = acfg2;
++ emif_regs->AB3CR = acfg3;
++ emif_regs->AB4CR = acfg4;
++ emif_regs->NANDFCR = 0x00000101;
++}
++
++int board_nand_init(struct nand_chip *nand)
++{
++ nand->IO_ADDR_R = (void __iomem *)NAND_CE0DATA;
++ nand->IO_ADDR_W = (void __iomem *)NAND_CE0DATA;
++ nand->chip_delay = 0;
++ nand->select_chip = nand_davinci_select_chip;
++#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
++ nand->options = NAND_USE_FLASH_BBT;
++#endif
++#ifdef CONFIG_SYS_NAND_HW_ECC
++ nand->ecc.mode = NAND_ECC_HW;
++#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
++ nand->ecc.layout = &davinci_nand_ecclayout;
++#ifdef CONFIG_SYS_NAND_LARGEPAGE
++ nand->ecc.size = 2048;
++ nand->ecc.bytes = 12;
++#elif defined(CONFIG_SYS_NAND_SMALLPAGE)
++ nand->ecc.size = 512;
++ nand->ecc.bytes = 3;
++#else
++#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!"
++#endif
++#else
++ nand->ecc.size = 512;
++ nand->ecc.bytes = 3;
++#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
++ nand->ecc.calculate = nand_davinci_calculate_ecc;
++ nand->ecc.correct = nand_davinci_correct_data;
++ nand->ecc.hwctl = nand_davinci_enable_hwecc;
++#else
++ nand->ecc.mode = NAND_ECC_SOFT;
++#endif /* CONFIG_SYS_NAND_HW_ECC */
++
++ /* Set address of hardware control function */
++ nand->cmd_ctrl = nand_davinci_hwcontrol;
++
++ nand->dev_ready = nand_davinci_dev_ready;
++ nand->waitfunc = nand_davinci_waitfunc;
++
++ nand_flash_init();
++
++ return(0);
++}
++
++#else
++#error "U-Boot legacy NAND support not available for DaVinci chips"
++#endif
++#endif /* CONFIG_SYS_USE_NAND */
+Index: u-boot-2009.01-primus/cpu/arm926ejs/da850/reset.S
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/cpu/arm926ejs/da850/reset.S
+@@ -0,0 +1,77 @@
++/*
++ * Processor reset using WDT for TI TMS320DM644x SoC.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * -----------------------------------------------------
++ *
++ * 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
++ */
++
++.globl reset_cpu
++reset_cpu:
++ ldr r0, WDT_TGCR
++ mov r1, $0x08
++ str r1, [r0]
++ ldr r1, [r0]
++ orr r1, r1, $0x03
++ str r1, [r0]
++ mov r1, $0
++ ldr r0, WDT_TIM12
++ str r1, [r0]
++ ldr r0, WDT_TIM34
++ str r1, [r0]
++ ldr r0, WDT_PRD12
++ str r1, [r0]
++ ldr r0, WDT_PRD34
++ str r1, [r0]
++ ldr r0, WDT_TCR
++ ldr r1, [r0]
++ orr r1, r1, $0x40
++ str r1, [r0]
++ ldr r0, WDT_WDTCR
++ ldr r1, [r0]
++ orr r1, r1, $0x4000
++ str r1, [r0]
++ ldr r1, WDTCR_VAL1
++ str r1, [r0]
++ ldr r1, WDTCR_VAL2
++ str r1, [r0]
++ nop
++ nop
++ nop
++ nop
++reset_cpu_loop:
++ b reset_cpu_loop
++
++WDT_TGCR:
++ .word 0x01c21c24
++WDT_TIM12:
++ .word 0x01c21c10
++WDT_TIM34:
++ .word 0x01c21c14
++WDT_PRD12:
++ .word 0x01c21c18
++WDT_PRD34:
++ .word 0x01c21c1c
++WDT_TCR:
++ .word 0x01c21c20
++WDT_WDTCR:
++ .word 0x01c21c28
++WDTCR_VAL1:
++ .word 0xa5c64000
++WDTCR_VAL2:
++ .word 0xda7e4000
+Index: u-boot-2009.01-primus/cpu/arm926ejs/da850/timer.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/cpu/arm926ejs/da850/timer.c
+@@ -0,0 +1,148 @@
++/*
++ * (C) Copyright 2003
++ * Texas Instruments <www.ti.com>
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Alex Zuepke <azu@sysgo.de>
++ *
++ * (C) Copyright 2002-2004
++ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++ *
++ * (C) Copyright 2004
++ * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * 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 <arm926ejs.h>
++
++typedef volatile struct {
++ u_int32_t pid12;
++ u_int32_t emumgt;
++ u_int32_t na1;
++ u_int32_t na2;
++ u_int32_t tim12;
++ u_int32_t tim34;
++ u_int32_t prd12;
++ u_int32_t prd34;
++ u_int32_t tcr;
++ u_int32_t tgcr;
++ u_int32_t wdtcr;
++} davinci_timer;
++
++davinci_timer *timer = (davinci_timer *)CONFIG_SYS_TIMERBASE;
++
++#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)
++#define TIM_CLK_DIV 16
++
++static ulong timestamp;
++static ulong lastinc;
++
++int timer_init(void)
++{
++ /* We are using timer34 in unchained 32-bit mode, full speed */
++ timer->tcr = 0x0;
++ timer->tgcr = 0x0;
++ timer->tgcr = 0x06 | ((TIM_CLK_DIV - 1) << 8);
++ timer->tim34 = 0x0;
++ timer->prd34 = TIMER_LOAD_VAL;
++ lastinc = 0;
++ timestamp = 0;
++ timer->tcr = 2 << 22;
++
++ return(0);
++}
++
++void reset_timer(void)
++{
++ timer->tcr = 0x0;
++ timer->tim34 = 0;
++ lastinc = 0;
++ timestamp = 0;
++ timer->tcr = 2 << 22;
++}
++
++static ulong get_timer_raw(void)
++{
++ ulong now = timer->tim34;
++
++ if (now >= lastinc) {
++ /* normal mode */
++ timestamp += now - lastinc;
++ } else {
++ /* overflow ... */
++ timestamp += now + TIMER_LOAD_VAL - lastinc;
++ }
++ lastinc = now;
++ return timestamp;
++}
++
++ulong get_timer(ulong base)
++{
++ return((get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base);
++}
++
++void set_timer(ulong t)
++{
++ timestamp = t;
++}
++
++void udelay(unsigned long usec)
++{
++ ulong tmo;
++ ulong endtime;
++ signed long diff;
++
++ tmo = CONFIG_SYS_HZ_CLOCK / 1000;
++ tmo *= usec;
++ tmo /= (1000 * TIM_CLK_DIV);
++
++ endtime = get_timer_raw() + tmo;
++
++ do {
++ ulong now = get_timer_raw();
++ diff = endtime - now;
++ } while (diff >= 0);
++}
++
++/*
++ * 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_SYS_HZ;
++}
+Index: u-boot-2009.01-primus/include/asm-arm/arch-da850/emac_defs.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/include/asm-arm/arch-da850/emac_defs.h
+@@ -0,0 +1,331 @@
++/*
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Based on:
++ *
++ * ----------------------------------------------------------------------------
++ *
++ * dm644x_emac.h
++ *
++ * TI DaVinci (DM644X) EMAC peripheral driver header for DV-EVM
++ *
++ * Copyright (C) 2005 Texas Instruments.
++ *
++ * ----------------------------------------------------------------------------
++ *
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++
++ * Modifications:
++ * ver. 1.0: Sep 2005, TI PSP Team - Created EMAC version for uBoot.
++ *
++ */
++
++#ifndef _DM644X_EMAC_H_
++#define _DM644X_EMAC_H_
++
++#include <asm/arch/hardware.h>
++
++#define EMAC_BASE_ADDR DAVINCI_EMAC_CNTRL_REGS_BASE
++#define EMAC_WRAPPER_BASE_ADDR DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE
++#define EMAC_WRAPPER_RAM_ADDR DAVINCI_EMAC_WRAPPER_RAM_BASE
++#define EMAC_MDIO_BASE_ADDR DAVINCI_MDIO_CNTRL_REGS_BASE
++
++/* MDIO module input frequency */
++#define EMAC_MDIO_BUS_FREQ clk_get(DAVINCI_MDIO_CLKID)
++
++/* MDIO clock output frequency */
++#define EMAC_MDIO_CLOCK_FREQ 2000000 /* 2.0 MHz */
++
++/* Ethernet Min/Max packet size */
++#define EMAC_MIN_ETHERNET_PKT_SIZE 60
++#define EMAC_MAX_ETHERNET_PKT_SIZE 1518
++#define EMAC_PKT_ALIGN 18 /* 1518 + 18 = 1536 (packet aligned on 32 byte boundry) */
++
++/* Number of RX packet buffers
++ * NOTE: Only 1 buffer supported as of now
++ */
++#define EMAC_MAX_RX_BUFFERS 10
++
++
++/***********************************************
++ ******** Internally used macros ***************
++ ***********************************************/
++
++#define EMAC_CH_TX 1
++#define EMAC_CH_RX 0
++
++/* Each descriptor occupies 4 words, lets start RX desc's at 0 and
++ * reserve space for 64 descriptors max
++ */
++#define EMAC_RX_DESC_BASE 0x0
++#define EMAC_TX_DESC_BASE 0x1000
++
++/* EMAC Teardown value */
++#define EMAC_TEARDOWN_VALUE 0xfffffffc
++
++/* MII Status Register */
++#define MII_STATUS_REG 1
++
++/* Number of statistics registers */
++#define EMAC_NUM_STATS 36
++
++
++/* EMAC Descriptor */
++typedef volatile struct _emac_desc
++{
++ u_int32_t next; /* Pointer to next descriptor in chain */
++ u_int8_t *buffer; /* Pointer to data buffer */
++ u_int32_t buff_off_len; /* Buffer Offset(MSW) and Length(LSW) */
++ u_int32_t pkt_flag_len; /* Packet Flags(MSW) and Length(LSW) */
++} emac_desc;
++
++/* CPPI bit positions */
++#define EMAC_CPPI_SOP_BIT (0x80000000)
++#define EMAC_CPPI_EOP_BIT (0x40000000)
++#define EMAC_CPPI_OWNERSHIP_BIT (0x20000000)
++#define EMAC_CPPI_EOQ_BIT (0x10000000)
++#define EMAC_CPPI_TEARDOWN_COMPLETE_BIT (0x08000000)
++#define EMAC_CPPI_PASS_CRC_BIT (0x04000000)
++
++#define EMAC_CPPI_RX_ERROR_FRAME (0x03fc0000)
++
++#define EMAC_MACCONTROL_RMIISPEED_100 (1 << 15)
++#define EMAC_MACCONTROL_MIIEN_ENABLE (0x20)
++#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE (0x1)
++
++#define EMAC_RXMBPENABLE_RXCAFEN_ENABLE (0x200000)
++#define EMAC_RXMBPENABLE_RXBROADEN (0x2000)
++
++
++#define MDIO_CONTROL_IDLE (0x80000000)
++#define MDIO_CONTROL_ENABLE (0x40000000)
++#define MDIO_CONTROL_FAULT_ENABLE (0x40000)
++#define MDIO_CONTROL_FAULT (0x80000)
++#define MDIO_USERACCESS0_GO (0x80000000)
++#define MDIO_USERACCESS0_WRITE_READ (0x0)
++#define MDIO_USERACCESS0_WRITE_WRITE (0x40000000)
++#define MDIO_USERACCESS0_ACK (0x20000000)
++
++/* Ethernet MAC Registers Structure */
++typedef struct {
++ dv_reg TXIDVER;
++ dv_reg TXCONTROL;
++ dv_reg TXTEARDOWN;
++ u_int8_t RSVD0[4];
++ dv_reg RXIDVER;
++ dv_reg RXCONTROL;
++ dv_reg RXTEARDOWN;
++ u_int8_t RSVD1[100];
++ dv_reg TXINTSTATRAW;
++ dv_reg TXINTSTATMASKED;
++ dv_reg TXINTMASKSET;
++ dv_reg TXINTMASKCLEAR;
++ dv_reg MACINVECTOR;
++ u_int8_t RSVD2[12];
++ dv_reg RXINTSTATRAW;
++ dv_reg RXINTSTATMASKED;
++ dv_reg RXINTMASKSET;
++ dv_reg RXINTMASKCLEAR;
++ dv_reg MACINTSTATRAW;
++ dv_reg MACINTSTATMASKED;
++ dv_reg MACINTMASKSET;
++ dv_reg MACINTMASKCLEAR;
++ u_int8_t RSVD3[64];
++ dv_reg RXMBPENABLE;
++ dv_reg RXUNICASTSET;
++ dv_reg RXUNICASTCLEAR;
++ dv_reg RXMAXLEN;
++ dv_reg RXBUFFEROFFSET;
++ dv_reg RXFILTERLOWTHRESH;
++ u_int8_t RSVD4[8];
++ dv_reg RX0FLOWTHRESH;
++ dv_reg RX1FLOWTHRESH;
++ dv_reg RX2FLOWTHRESH;
++ dv_reg RX3FLOWTHRESH;
++ dv_reg RX4FLOWTHRESH;
++ dv_reg RX5FLOWTHRESH;
++ dv_reg RX6FLOWTHRESH;
++ dv_reg RX7FLOWTHRESH;
++ dv_reg RX0FREEBUFFER;
++ dv_reg RX1FREEBUFFER;
++ dv_reg RX2FREEBUFFER;
++ dv_reg RX3FREEBUFFER;
++ dv_reg RX4FREEBUFFER;
++ dv_reg RX5FREEBUFFER;
++ dv_reg RX6FREEBUFFER;
++ dv_reg RX7FREEBUFFER;
++ dv_reg MACCONTROL;
++ dv_reg MACSTATUS;
++ dv_reg EMCONTROL;
++ dv_reg FIFOCONTROL;
++ dv_reg MACCONFIG;
++ dv_reg SOFTRESET;
++ u_int8_t RSVD5[88];
++ dv_reg MACSRCADDRLO;
++ dv_reg MACSRCADDRHI;
++ dv_reg MACHASH1;
++ dv_reg MACHASH2;
++ dv_reg BOFFTEST;
++ dv_reg TPACETEST;
++ dv_reg RXPAUSE;
++ dv_reg TXPAUSE;
++ u_int8_t RSVD6[16];
++ dv_reg RXGOODFRAMES;
++ dv_reg RXBCASTFRAMES;
++ dv_reg RXMCASTFRAMES;
++ dv_reg RXPAUSEFRAMES;
++ dv_reg RXCRCERRORS;
++ dv_reg RXALIGNCODEERRORS;
++ dv_reg RXOVERSIZED;
++ dv_reg RXJABBER;
++ dv_reg RXUNDERSIZED;
++ dv_reg RXFRAGMENTS;
++ dv_reg RXFILTERED;
++ dv_reg RXQOSFILTERED;
++ dv_reg RXOCTETS;
++ dv_reg TXGOODFRAMES;
++ dv_reg TXBCASTFRAMES;
++ dv_reg TXMCASTFRAMES;
++ dv_reg TXPAUSEFRAMES;
++ dv_reg TXDEFERRED;
++ dv_reg TXCOLLISION;
++ dv_reg TXSINGLECOLL;
++ dv_reg TXMULTICOLL;
++ dv_reg TXEXCESSIVECOLL;
++ dv_reg TXLATECOLL;
++ dv_reg TXUNDERRUN;
++ dv_reg TXCARRIERSENSE;
++ dv_reg TXOCTETS;
++ dv_reg FRAME64;
++ dv_reg FRAME65T127;
++ dv_reg FRAME128T255;
++ dv_reg FRAME256T511;
++ dv_reg FRAME512T1023;
++ dv_reg FRAME1024TUP;
++ dv_reg NETOCTETS;
++ dv_reg RXSOFOVERRUNS;
++ dv_reg RXMOFOVERRUNS;
++ dv_reg RXDMAOVERRUNS;
++ u_int8_t RSVD7[624];
++ dv_reg MACADDRLO;
++ dv_reg MACADDRHI;
++ dv_reg MACINDEX;
++ u_int8_t RSVD8[244];
++ dv_reg TX0HDP;
++ dv_reg TX1HDP;
++ dv_reg TX2HDP;
++ dv_reg TX3HDP;
++ dv_reg TX4HDP;
++ dv_reg TX5HDP;
++ dv_reg TX6HDP;
++ dv_reg TX7HDP;
++ dv_reg RX0HDP;
++ dv_reg RX1HDP;
++ dv_reg RX2HDP;
++ dv_reg RX3HDP;
++ dv_reg RX4HDP;
++ dv_reg RX5HDP;
++ dv_reg RX6HDP;
++ dv_reg RX7HDP;
++ dv_reg TX0CP;
++ dv_reg TX1CP;
++ dv_reg TX2CP;
++ dv_reg TX3CP;
++ dv_reg TX4CP;
++ dv_reg TX5CP;
++ dv_reg TX6CP;
++ dv_reg TX7CP;
++ dv_reg RX0CP;
++ dv_reg RX1CP;
++ dv_reg RX2CP;
++ dv_reg RX3CP;
++ dv_reg RX4CP;
++ dv_reg RX5CP;
++ dv_reg RX6CP;
++ dv_reg RX7CP;
++} emac_regs;
++
++/* EMAC Wrapper Registers Structure */
++typedef struct {
++ dv_reg REV;
++ dv_reg SOFTRESET;
++ dv_reg INTCONTROL;
++ dv_reg C0RXTHRESHEN;
++ dv_reg C0RXEN;
++ dv_reg C0TXEN;
++ dv_reg C0MISCEN;
++ dv_reg C1RXTHRESHEN;
++ dv_reg C1RXEN;
++ dv_reg C1TXEN;
++ dv_reg C1MISCEN;
++ dv_reg C2RXTHRESHEN;
++ dv_reg C2RXEN;
++ dv_reg C2TXEN;
++ dv_reg C2MISCEN;
++ dv_reg C0RXTHRESHSTAT;
++ dv_reg C0RXSTAT;
++ dv_reg C0TXSTAT;
++ dv_reg C0MISCSTAT;
++ dv_reg C1RXTHRESHSTAT;
++ dv_reg C1RXSTAT;
++ dv_reg C1TXSTAT;
++ dv_reg C1MISCSTAT;
++ dv_reg C2RXTHRESHSTAT;
++ dv_reg C2RXSTAT;
++ dv_reg C2TXSTAT;
++ dv_reg C2MISCSTAT;
++ dv_reg C0RXIMAX;
++ dv_reg C0TXIMAX;
++ dv_reg C1RXIMAX;
++ dv_reg C1TXIMAX;
++ dv_reg C2RXIMAX;
++ dv_reg C2TXIMAX;
++} ewrap_regs;
++
++
++/* EMAC MDIO Registers Structure */
++typedef struct {
++ dv_reg VERSION;
++ dv_reg CONTROL;
++ dv_reg ALIVE;
++ dv_reg LINK;
++ dv_reg LINKINTRAW;
++ dv_reg LINKINTMASKED;
++ u_int8_t RSVD0[8];
++ dv_reg USERINTRAW;
++ dv_reg USERINTMASKED;
++ dv_reg USERINTMASKSET;
++ dv_reg USERINTMASKCLEAR;
++ u_int8_t RSVD1[80];
++ dv_reg USERACCESS0;
++ dv_reg USERPHYSEL0;
++ dv_reg USERACCESS1;
++ dv_reg USERPHYSEL1;
++} mdio_regs;
++
++int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data);
++int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data);
++
++typedef struct
++{
++ char name[64];
++ int (*init)(int phy_addr);
++ int (*is_phy_connected)(int phy_addr);
++ int (*get_link_speed)(int phy_addr);
++ int (*auto_negotiate)(int phy_addr);
++} phy_t;
++
++#endif /* _DM644X_EMAC_H_ */
+Index: u-boot-2009.01-primus/include/asm-arm/arch-da850/emif_defs.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/include/asm-arm/arch-da850/emif_defs.h
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * 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 _EMIF_DEFS_H_
++#define _EMIF_DEFS_H_
++
++#include <asm/arch/hardware.h>
++
++typedef struct {
++ dv_reg ERCSR;
++ dv_reg AWCCR;
++ dv_reg SDBCR;
++ dv_reg SDRCR;
++ dv_reg AB1CR;
++ dv_reg AB2CR;
++ dv_reg AB3CR;
++ dv_reg AB4CR;
++ dv_reg SDTIMR;
++ dv_reg DDRSR;
++ dv_reg DDRPHYCR;
++ dv_reg DDRPHYSR;
++ dv_reg TOTAR;
++ dv_reg TOTACTR;
++ dv_reg DDRPHYID_REV;
++ dv_reg SDSRETR;
++ dv_reg EIRR;
++ dv_reg EIMR;
++ dv_reg EIMSR;
++ dv_reg EIMCR;
++ dv_reg IOCTRLR;
++ dv_reg IOSTATR;
++ u_int8_t RSVD0[8];
++ dv_reg NANDFCR;
++ dv_reg NANDFSR;
++ u_int8_t RSVD1[8];
++ dv_reg NANDF1ECC;
++ dv_reg NANDF2ECC;
++ dv_reg NANDF3ECC;
++ dv_reg NANDF4ECC;
++} emif_registers;
++
++typedef emif_registers *emifregs;
++#endif
+Index: u-boot-2009.01-primus/include/asm-arm/arch-da850/hardware.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/include/asm-arm/arch-da850/hardware.h
+@@ -0,0 +1,199 @@
++/*
++ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc
++ *
++ * Based on hardware.h for DaVinci. Original Copyrights follow.
++ *
++ * Sergey Kubushyn <ksi@koi8.net>
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Based on:
++ *
++ * -------------------------------------------------------------------------
++ *
++ * linux/include/asm-arm/arch-davinci/hardware.h
++ *
++ * Copyright (C) 2006 Texas Instruments.
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++#ifndef __ASM_ARCH_HARDWARE_H
++#define __ASM_ARCH_HARDWARE_H
++
++#include <config.h>
++
++#ifndef __ASSEMBLY__
++
++#include <asm/sizes.h>
++
++#define REG(addr) (*(volatile unsigned int *)(addr))
++#define REG_P(addr) ((volatile unsigned int *)(addr))
++
++typedef volatile unsigned int dv_reg;
++typedef volatile unsigned int * dv_reg_p;
++
++#endif
++
++/*
++ * Base register addresses
++ */
++#define DAVINCI_UART0_BASE (0x01c42000)
++#define DAVINCI_UART1_BASE (0x01d0c000)
++#define DAVINCI_UART2_BASE (0x01d0d000)
++#define DAVINCI_I2C0_BASE (0x01c22000)
++#define DAVINCI_I2C1_BASE (0x01e28000)
++#define DAVINCI_TIMER0_BASE (0x01c20000)
++#define DAVINCI_TIMER1_BASE (0x01c21000)
++#define DAVINCI_WDOG_BASE (0x01c21000)
++#define DAVINCI_PLL_CNTRL0_BASE (0x01c11000)
++#define DAVINCI_PSC0_BASE (0x01c10000)
++#define DAVINCI_PSC1_BASE (0x01e27000)
++#define DAVINCI_SPI0_BASE (0x01c41000)
++#define DAVINCI_SPI1_BASE (0x01e12000)
++#define DAVINCI_GPIO_BASE (0x01e26000)
++#define DAVINCI_EMAC_CNTRL_REGS_BASE (0x01e23000)
++#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE (0x01e22000)
++#define DAVINCI_EMAC_WRAPPER_RAM_BASE (0x01e20000)
++#define DAVINCI_MDIO_CNTRL_REGS_BASE (0x01e24000)
++#define DAVINCI_ASYNC_EMIF_CNTRL_BASE (0x68000000)
++#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x40000000)
++#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x60000000)
++#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x62000000)
++#define DAVINCI_ASYNC_EMIF_DATA_CE4_BASE (0x64000000)
++#define DAVINCI_ASYNC_EMIF_DATA_CE5_BASE (0x66000000)
++#define DAVINCI_DDR_EMIF_CTRL_BASE (0xb0000000)
++#define DAVINCI_DDR_EMIF_DATA_BASE (0xc0000000)
++#define DAVINCI_INTC_BASE (0xfffee000)
++#define DAVINCI_BOOTCFG_BASE (0x01c14000)
++
++/* Clock IDs */
++#define DAVINCI_PLLM_CLKID (0xFF + 0)
++#define DAVINCI_PLLC_CLKID (0xFF + 1)
++#define DAVINCI_AUXCLK_CLKID (0xFF + 2)
++#define DAVINCI_MDIO_CLKID 4
++#define DAVINCI_SPI0_CLKID 2
++#define DAVINCI_UART0_CLKID 2
++#define DAVINCI_ARM_CLKID 6
++
++/* Power and Sleep Controller (PSC) Domains */
++#define DAVINCI_GPSC_ARMDOMAIN 0
++#define DAVINCI_GPSC_DSPDOMAIN 1
++
++/* LPSCs in PSC0 */
++#define DAVINCI_LPSC_TPCC 0
++#define DAVINCI_LPSC_TPTC0 1
++#define DAVINCI_LPSC_TPTC1 2
++#define DAVINCI_LPSC_AEMIF 3
++#define DAVINCI_LPSC_SPI0 4
++#define DAVINCI_LPSC_MMC_SD 5
++#define DAVINCI_LPSC_AINTC 6
++#define DAVINCI_LPSC_ARM_RAM_ROM 7
++#define DAVINCI_LPSC_SECCTL_KEYMGR 8
++#define DAVINCI_LPSC_UART0 9
++#define DAVINCI_LPSC_SCR0 10
++#define DAVINCI_LPSC_SCR1 11
++#define DAVINCI_LPSC_SCR2 12
++#define DAVINCI_LPSC_DMAX 13
++#define DAVINCI_LPSC_ARM 14
++#define DAVINCI_LPSC_GEM 15
++
++/* for LPSCs in PSC1, 32 + actual id is being used for differentiation */
++#define DAVINCI_LPSC_USB11 (32 + 1)
++#define DAVINCI_LPSC_USB20 (32 + 2)
++#define DAVINCI_LPSC_GPIO (32 + 3)
++#define DAVINCI_LPSC_UHPI (32 + 4)
++#define DAVINCI_LPSC_EMAC (32 + 5)
++#define DAVINCI_LPSC_DDR_EMIF (32 + 6)
++#define DAVINCI_LPSC_McASP0 (32 + 7)
++#define DAVINCI_LPSC_McASP1 (32 + 8)
++#define DAVINCI_LPSC_McASP2 (32 + 9)
++#define DAVINCI_LPSC_SPI1 (32 + 10)
++#define DAVINCI_LPSC_I2C1 (32 + 11)
++#define DAVINCI_LPSC_UART1 (32 + 12)
++#define DAVINCI_LPSC_UART2 (32 + 13)
++#define DAVINCI_LPSC_LCDC (32 + 16)
++#define DAVINCI_LPSC_ePWM (32 + 17)
++#define DAVINCI_LPSC_eCAP (32 + 20)
++#define DAVINCI_LPSC_eQEP (32 + 21)
++#define DAVINCI_LPSC_SCR_P0 (32 + 22)
++#define DAVINCI_LPSC_SCR_P1 (32 + 23)
++#define DAVINCI_LPSC_CR_P3 (32 + 26)
++#define DAVINCI_LPSC_L3_CBA_RAM (32 + 31)
++
++/* Some PSC defines */
++
++#define PSC0_MDCTL (DAVINCI_PSC0_BASE + 0xa00)
++#define PSC0_MDSTAT (DAVINCI_PSC0_BASE + 0x800)
++#define PSC0_PTCMD (DAVINCI_PSC0_BASE + 0x120)
++#define PSC0_PTSTAT (DAVINCI_PSC0_BASE + 0x128)
++
++#define PSC1_MDCTL (DAVINCI_PSC1_BASE + 0xa00)
++#define PSC1_MDSTAT (DAVINCI_PSC1_BASE + 0x800)
++#define PSC1_PTCMD (DAVINCI_PSC1_BASE + 0x120)
++#define PSC1_PTSTAT (DAVINCI_PSC1_BASE + 0x128)
++
++/* Some PLL defines */
++#define PLL0_PLLCTL (DAVINCI_PLL_CNTRL0_BASE + 0x100)
++#define PLL0_PLLM (DAVINCI_PLL_CNTRL0_BASE + 0x110)
++#define PLL0_PREDIV (DAVINCI_PLL_CNTRL0_BASE + 0x114)
++#define PLL0_POSTDIV (DAVINCI_PLL_CNTRL0_BASE + 0x128)
++#define PLL0_DIV1 (DAVINCI_PLL_CNTRL0_BASE + 0x118)
++#define PLL0_DIV2 (DAVINCI_PLL_CNTRL0_BASE + 0x11c)
++#define PLL0_DIV3 (DAVINCI_PLL_CNTRL0_BASE + 0x120)
++#define PLL0_DIV4 (DAVINCI_PLL_CNTRL0_BASE + 0x160)
++#define PLL0_DIV5 (DAVINCI_PLL_CNTRL0_BASE + 0x164)
++#define PLL0_DIV6 (DAVINCI_PLL_CNTRL0_BASE + 0x168)
++#define PLL0_DIV7 (DAVINCI_PLL_CNTRL0_BASE + 0x16c)
++#define PLL0_DIV8 (DAVINCI_PLL_CNTRL0_BASE + 0x170)
++#define PLL0_DIV9 (DAVINCI_PLL_CNTRL0_BASE + 0x114)
++
++/* Boot config */
++#define KICK0 (DAVINCI_BOOTCFG_BASE + 0x38)
++#define KICK1 (DAVINCI_BOOTCFG_BASE + 0x3c)
++#define PINMUX0 (DAVINCI_BOOTCFG_BASE + 0x120)
++#define PINMUX1 (DAVINCI_BOOTCFG_BASE + 0x124)
++#define PINMUX2 (DAVINCI_BOOTCFG_BASE + 0x128)
++#define PINMUX3 (DAVINCI_BOOTCFG_BASE + 0x12c)
++#define PINMUX4 (DAVINCI_BOOTCFG_BASE + 0x130)
++#define PINMUX5 (DAVINCI_BOOTCFG_BASE + 0x134)
++#define PINMUX6 (DAVINCI_BOOTCFG_BASE + 0x138)
++#define PINMUX7 (DAVINCI_BOOTCFG_BASE + 0x13c)
++#define PINMUX8 (DAVINCI_BOOTCFG_BASE + 0x140)
++#define PINMUX9 (DAVINCI_BOOTCFG_BASE + 0x144)
++#define PINMUX10 (DAVINCI_BOOTCFG_BASE + 0x148)
++#define PINMUX11 (DAVINCI_BOOTCFG_BASE + 0x14c)
++#define PINMUX12 (DAVINCI_BOOTCFG_BASE + 0x150)
++#define PINMUX13 (DAVINCI_BOOTCFG_BASE + 0x154)
++#define PINMUX14 (DAVINCI_BOOTCFG_BASE + 0x158)
++#define PINMUX15 (DAVINCI_BOOTCFG_BASE + 0x15C)
++#define PINMUX16 (DAVINCI_BOOTCFG_BASE + 0x160)
++#define PINMUX17 (DAVINCI_BOOTCFG_BASE + 0x164)
++#define PINMUX18 (DAVINCI_BOOTCFG_BASE + 0x168)
++#define PINMUX19 (DAVINCI_BOOTCFG_BASE + 0x16c)
++#define SUSPSRC (DAVINCI_BOOTCFG_BASE + 0x170)
++#define CFGCHIP0 (DAVINCI_BOOTCFG_BASE + 0x17c)
++
++/* Interrupt controller */
++#define INTC_GLB_EN (DAVINCI_INTC_BASE + 0x10)
++#define INTC_HINT_EN (DAVINCI_INTC_BASE + 0x1500)
++#define INTC_EN_CLR0 (DAVINCI_INTC_BASE + 0x380)
++
++#endif /* __ASM_ARCH_HARDWARE_H */
+Index: u-boot-2009.01-primus/include/asm-arm/arch-da850/i2c_defs.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/include/asm-arm/arch-da850/i2c_defs.h
+@@ -0,0 +1,95 @@
++/*
++ * (C) Copyright 2004
++ * Texas Instruments, <www.ti.com>
++ *
++ * Some changes copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * 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 _DAVINCI_I2C_H_
++#define _DAVINCI_I2C_H_
++
++#define I2C_WRITE 0
++#define I2C_READ 1
++
++#define I2C_BASE 0x01c22000
++
++#define I2C_OA (I2C_BASE + 0x00)
++#define I2C_IE (I2C_BASE + 0x04)
++#define I2C_STAT (I2C_BASE + 0x08)
++#define I2C_SCLL (I2C_BASE + 0x0c)
++#define I2C_SCLH (I2C_BASE + 0x10)
++#define I2C_CNT (I2C_BASE + 0x14)
++#define I2C_DRR (I2C_BASE + 0x18)
++#define I2C_SA (I2C_BASE + 0x1c)
++#define I2C_DXR (I2C_BASE + 0x20)
++#define I2C_CON (I2C_BASE + 0x24)
++#define I2C_IV (I2C_BASE + 0x28)
++#define I2C_PSC (I2C_BASE + 0x30)
++
++/* I2C masks */
++
++/* I2C Interrupt Enable Register (I2C_IE): */
++#define I2C_IE_SCD_IE (1 << 5) /* Stop condition detect interrupt enable */
++#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */
++#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */
++#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */
++#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */
++#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */
++
++/* I2C Status Register (I2C_STAT): */
++
++#define I2C_STAT_BB (1 << 12) /* Bus busy */
++#define I2C_STAT_ROVR (1 << 11) /* Receive overrun */
++#define I2C_STAT_XUDF (1 << 10) /* Transmit underflow */
++#define I2C_STAT_AAS (1 << 9) /* Address as slave */
++#define I2C_STAT_SCD (1 << 5) /* Stop condition detect */
++#define I2C_STAT_XRDY (1 << 4) /* Transmit data ready */
++#define I2C_STAT_RRDY (1 << 3) /* Receive data ready */
++#define I2C_STAT_ARDY (1 << 2) /* Register access ready */
++#define I2C_STAT_NACK (1 << 1) /* No acknowledgment interrupt enable */
++#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */
++
++
++/* I2C Interrupt Code Register (I2C_INTCODE): */
++
++#define I2C_INTCODE_MASK 7
++#define I2C_INTCODE_NONE 0
++#define I2C_INTCODE_AL 1 /* Arbitration lost */
++#define I2C_INTCODE_NAK 2 /* No acknowledgement/general call */
++#define I2C_INTCODE_ARDY 3 /* Register access ready */
++#define I2C_INTCODE_RRDY 4 /* Rcv data ready */
++#define I2C_INTCODE_XRDY 5 /* Xmit data ready */
++#define I2C_INTCODE_SCD 6 /* Stop condition detect */
++
++
++/* I2C Configuration Register (I2C_CON): */
++
++#define I2C_CON_EN (1 << 5) /* I2C module enable */
++#define I2C_CON_STB (1 << 4) /* Start byte mode (master mode only) */
++#define I2C_CON_MST (1 << 10) /* Master/slave mode */
++#define I2C_CON_TRX (1 << 9) /* Transmitter/receiver mode (master mode only) */
++#define I2C_CON_XA (1 << 8) /* Expand address */
++#define I2C_CON_STP (1 << 11) /* Stop condition (master mode only) */
++#define I2C_CON_STT (1 << 13) /* Start condition (master mode only) */
++#define I2C_CON_FREE (1 << 14) /* Free run on emulation */
++
++#define I2C_TIMEOUT 0xffff0000 /* Timeout mask for poll_i2c_irq() */
++
++#endif
+Index: u-boot-2009.01-primus/include/asm-arm/arch-da850/nand_defs.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01-primus/include/asm-arm/arch-da850/nand_defs.h
+@@ -0,0 +1,164 @@
++/*
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Parts shamelesly stolen from Linux Kernel source tree.
++ *
++ * ------------------------------------------------------------
++ *
++ * 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 _NAND_DEFS_H_
++#define _NAND_DEFS_H_
++
++#include <asm/arch/hardware.h>
++
++#define MASK_CLE 0x10
++//#define MASK_ALE 0x0a
++#define MASK_ALE 0x08
++
++
++#define NAND_CE0CLE ((volatile u_int8_t *)(CONFIG_SYS_NAND_BASE + 0x10))
++//#define NAND_CE0ALE ((volatile u_int8_t *)(CFG_NAND_BASE + 0x0a))
++#define NAND_CE0ALE ((volatile u_int8_t *)(CONFIG_SYS_NAND_BASE + 0x08))
++#define NAND_CE0DATA ((volatile u_int8_t *)CONFIG_SYS_NAND_BASE)
++
++typedef struct {
++ u_int32_t NRCSR;
++ u_int32_t AWCCR;
++ u_int8_t RSVD0[8];
++ u_int32_t AB1CR;
++ u_int32_t AB2CR;
++ u_int32_t AB3CR;
++ u_int32_t AB4CR;
++ u_int8_t RSVD1[32];
++ u_int32_t NIRR;
++ u_int32_t NIMR;
++ u_int32_t NIMSR;
++ u_int32_t NIMCR;
++ u_int8_t RSVD2[16];
++ u_int32_t NANDFCR;
++ u_int32_t NANDFSR;
++ u_int8_t RSVD3[8];
++ u_int32_t NANDF1ECC;
++ u_int32_t NANDF2ECC;
++ u_int32_t NANDF3ECC;
++ u_int32_t NANDF4ECC;
++ u_int8_t RSVD4[4];
++ u_int32_t IODFTECR;
++ u_int32_t IODFTGCR;
++ u_int8_t RSVD5[4];
++ u_int32_t IODFTMRLR;
++ u_int32_t IODFTMRMR;
++ u_int32_t IODFTMRMSBR;
++ u_int8_t RSVD6[20];
++ u_int32_t MODRNR;
++ u_int8_t RSVD7[76];
++ u_int32_t CE0DATA;
++ u_int32_t CE0ALE;
++ u_int32_t CE0CLE;
++ u_int8_t RSVD8[4];
++ u_int32_t CE1DATA;
++ u_int32_t CE1ALE;
++ u_int32_t CE1CLE;
++ u_int8_t RSVD9[4];
++ u_int32_t CE2DATA;
++ u_int32_t CE2ALE;
++ u_int32_t CE2CLE;
++ u_int8_t RSVD10[4];
++ u_int32_t CE3DATA;
++ u_int32_t CE3ALE;
++ u_int32_t CE3CLE;
++} nand_registers;
++
++typedef volatile nand_registers *nandregs;
++
++#define NAND_READ_START 0x00
++#define NAND_READ_END 0x30
++#define NAND_STATUS 0x70
++
++#ifdef CFG_NAND_HW_ECC
++#define NAND_Ecc_P1e (1 << 0)
++#define NAND_Ecc_P2e (1 << 1)
++#define NAND_Ecc_P4e (1 << 2)
++#define NAND_Ecc_P8e (1 << 3)
++#define NAND_Ecc_P16e (1 << 4)
++#define NAND_Ecc_P32e (1 << 5)
++#define NAND_Ecc_P64e (1 << 6)
++#define NAND_Ecc_P128e (1 << 7)
++#define NAND_Ecc_P256e (1 << 8)
++#define NAND_Ecc_P512e (1 << 9)
++#define NAND_Ecc_P1024e (1 << 10)
++#define NAND_Ecc_P2048e (1 << 11)
++
++#define NAND_Ecc_P1o (1 << 16)
++#define NAND_Ecc_P2o (1 << 17)
++#define NAND_Ecc_P4o (1 << 18)
++#define NAND_Ecc_P8o (1 << 19)
++#define NAND_Ecc_P16o (1 << 20)
++#define NAND_Ecc_P32o (1 << 21)
++#define NAND_Ecc_P64o (1 << 22)
++#define NAND_Ecc_P128o (1 << 23)
++#define NAND_Ecc_P256o (1 << 24)
++#define NAND_Ecc_P512o (1 << 25)
++#define NAND_Ecc_P1024o (1 << 26)
++#define NAND_Ecc_P2048o (1 << 27)
++
++#define TF(v) (v ? 1 : 0)
++
++#define P2048e(a) (TF(a & NAND_Ecc_P2048e) << 0)
++#define P2048o(a) (TF(a & NAND_Ecc_P2048o) << 1)
++#define P1e(a) (TF(a & NAND_Ecc_P1e) << 2)
++#define P1o(a) (TF(a & NAND_Ecc_P1o) << 3)
++#define P2e(a) (TF(a & NAND_Ecc_P2e) << 4)
++#define P2o(a) (TF(a & NAND_Ecc_P2o) << 5)
++#define P4e(a) (TF(a & NAND_Ecc_P4e) << 6)
++#define P4o(a) (TF(a & NAND_Ecc_P4o) << 7)
++
++#define P8e(a) (TF(a & NAND_Ecc_P8e) << 0)
++#define P8o(a) (TF(a & NAND_Ecc_P8o) << 1)
++#define P16e(a) (TF(a & NAND_Ecc_P16e) << 2)
++#define P16o(a) (TF(a & NAND_Ecc_P16o) << 3)
++#define P32e(a) (TF(a & NAND_Ecc_P32e) << 4)
++#define P32o(a) (TF(a & NAND_Ecc_P32o) << 5)
++#define P64e(a) (TF(a & NAND_Ecc_P64e) << 6)
++#define P64o(a) (TF(a & NAND_Ecc_P64o) << 7)
++
++#define P128e(a) (TF(a & NAND_Ecc_P128e) << 0)
++#define P128o(a) (TF(a & NAND_Ecc_P128o) << 1)
++#define P256e(a) (TF(a & NAND_Ecc_P256e) << 2)
++#define P256o(a) (TF(a & NAND_Ecc_P256o) << 3)
++#define P512e(a) (TF(a & NAND_Ecc_P512e) << 4)
++#define P512o(a) (TF(a & NAND_Ecc_P512o) << 5)
++#define P1024e(a) (TF(a & NAND_Ecc_P1024e) << 6)
++#define P1024o(a) (TF(a & NAND_Ecc_P1024o) << 7)
++
++#define P8e_s(a) (TF(a & NAND_Ecc_P8e) << 0)
++#define P8o_s(a) (TF(a & NAND_Ecc_P8o) << 1)
++#define P16e_s(a) (TF(a & NAND_Ecc_P16e) << 2)
++#define P16o_s(a) (TF(a & NAND_Ecc_P16o) << 3)
++#define P1e_s(a) (TF(a & NAND_Ecc_P1e) << 4)
++#define P1o_s(a) (TF(a & NAND_Ecc_P1o) << 5)
++#define P2e_s(a) (TF(a & NAND_Ecc_P2e) << 6)
++#define P2o_s(a) (TF(a & NAND_Ecc_P2o) << 7)
++
++#define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0)
++#define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1)
++#endif
++
++#endif
+Index: u-boot-2009.01-primus/Makefile
+===================================================================
+--- u-boot-2009.01-primus.orig/Makefile
++++ u-boot-2009.01-primus/Makefile
+@@ -2719,6 +2719,9 @@ davinci_sonata_config : unconfig
+ da8xx_evm_config : unconfig
+ @$(MKCONFIG) $(@:_config=) arm arm926ejs da8xx-evm da8xx da8xx
+
++da850_evm_config : unconfig
++ @$(MKCONFIG) $(@:_config=) arm arm926ejs da850-evm da850 da850
++
+ lpd7a400_config \
+ lpd7a404_config: unconfig
+ @$(MKCONFIG) $(@:_config=) arm lh7a40x lpd7a40x
diff --git a/patches/primus_port.patch b/patches/primus_port.patch
new file mode 100644
index 0000000000..5698e0dd7f
--- /dev/null
+++ b/patches/primus_port.patch
@@ -0,0 +1,5062 @@
+Index: u-boot-2009.01/include/configs/da8xx_evm.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/include/configs/da8xx_evm.h
+@@ -0,0 +1,223 @@
++/*
++ * Copyright (C) 2008 Texas Instruments, Inc <www.ti.com>
++ *
++ * Based on davinci_dvevm.h. Original Copyrights follow:
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * 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
++#include <asm/sizes.h>
++#include <asm/arch/hardware.h>
++
++/*=======*/
++/* Board */
++/*=======*/
++//#define CFG_USE_SPIFLASH
++#define CONFIG_SYS_USE_NAND
++
++/*===================*/
++/* SoC Configuration */
++/*===================*/
++#define CONFIG_ARM926EJS /* arm926ejs CPU core */
++#define CONFIG_DA8XX /* TI DA8xx SoC */
++#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID) /* Arm Clock */
++#define CFG_OSCIN_FREQ 24000000
++#define CONFIG_SYS_TIMERBASE DAVINCI_TIMER0_BASE /* use timer 0 */
++#define CONFIG_SYS_HZ_CLOCK clk_get(DAVINCI_AUXCLK_CLKID) /* Timer Input clock freq */
++#define CONFIG_SYS_HZ 1000
++#undef CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is _always_ loaded by a bootloader */
++#define CONFIG_SKIP_RELOCATE_UBOOT /* to a proper address, init done */
++
++/*=============*/
++/* Memory Info */
++/*=============*/
++#define CONFIG_SYS_MALLOC_LEN (0x10000 + 128*1024) /* malloc() len */
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* reserved for initial data */
++#define PHYS_SDRAM_1 DAVINCI_DDR_EMIF_DATA_BASE /* DDR Start */
++#define PHYS_SDRAM_1_SIZE 0x04000000 /* SDRAM size 64MB */
++#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM_1 /* memtest start address */
++#define CONFIG_SYS_MEMTEST_END (PHYS_SDRAM_1 + 16*1024*1024) /* 16MB RAM test */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define CONFIG_STACKSIZE (256*1024) /* regular stack */
++#define SDRAM_4BANKS_10COLS /* TODO: Update this! */
++
++/*====================*/
++/* Serial Driver info */
++/*====================*/
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4 /* NS16550 register size */
++#define CONFIG_SYS_NS16550_COM1 DAVINCI_UART2_BASE /* Base address of UART2 */
++#define CONFIG_SYS_NS16550_CLK clk_get(DAVINCI_UART2_CLKID) /* Input clock to NS16550 */
++#define CONFIG_CONS_INDEX 1 /* use UART0 for console */
++#define CONFIG_BAUDRATE 115200 /* Default baud rate */
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*===================*/
++/* I2C Configuration */
++/*===================*/
++#define CONFIG_HARD_I2C
++#define CONFIG_DRIVER_DAVINCI_I2C
++#define CONFIG_SYS_I2C_SPEED 25000 /* 100Kbps won't work, silicon bug */
++#define CONFIG_SYS_I2C_SLAVE 10 /* Bogus, master-only in U-Boot */
++
++/*====================================================*/
++/* I2C EEPROM definitions for catalyst 24W256 EEPROM chip */
++/*====================================================*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
++#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6
++#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 20
++
++/*==================================*/
++/* Network & Ethernet Configuration */
++/*==================================*/
++#define CONFIG_DRIVER_TI_EMAC
++#define CONFIG_MII
++#define CONFIG_BOOTP_DEFAULT
++#define CONFIG_BOOTP_DNS
++#define CONFIG_BOOTP_DNS2
++#define CONFIG_BOOTP_SEND_HOSTNAME
++#define CONFIG_NET_RETRY_COUNT 10
++
++/*=====================*/
++/* Flash & Environment */
++/*=====================*/
++#ifdef CONFIG_SYS_USE_NAND
++#undef CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_SYS_NO_FLASH
++#define CONFIG_ENV_IS_IN_NAND /* U-Boot env in NAND Flash */
++#define CONFIG_ENV_SIZE SZ_128K
++#define CONFIG_NAND_1BIT_ECC
++#define CONFIG_NAND_CS 3
++#define CONFIG_SYS_NAND_BASE DAVINCI_ASYNC_EMIF_DATA_CE3_BASE
++#define CONFIG_CLE_MASK 0x10
++#define CONFIG_ALE_MASK 0x8
++#define CONFIG_NAND_HW_ECC
++#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
++#define NAND_MAX_CHIPS 1
++#define CONFIG_ENV_OFFSET 0x0 /* Block 0--not used by bootcode */
++#define DEF_BOOTM ""
++#endif
++
++#ifdef CONFIG_SYS_USE_NOR
++#define CONFIG_ENV_IS_IN_FLASH
++#undef CONFIG_SYS_NO_FLASH
++#define CFG_FLASH_CFI_DRIVER
++#define CFG_FLASH_CFI
++#define CFG_MAX_FLASH_BANKS 1 /* max number of flash banks */
++#define CFG_FLASH_SECT_SZ 0x10000 /* 64KB sect size AMD Flash */
++#define CONFIG_ENV_OFFSET (CFG_FLASH_SECT_SZ*3)
++#define CFG_FLASH_BASE DAVINCI_ASYNC_EMIF_DATA_CE2_BASE
++#define PHYS_FLASH_SIZE 0x2000000 /* Flash size 32MB */
++#define CFG_MAX_FLASH_SECT (PHYS_FLASH_SIZE/CFG_FLASH_SECT_SZ)
++#define CONFIG_ENV_SECT_SIZE CFG_FLASH_SECT_SZ /* Env sector Size */
++#endif
++
++#ifdef CFG_USE_SPIFLASH
++#undef CONFIG_ENV_IS_IN_FLASH
++#undef CONFIG_ENV_IS_IN_NAND
++#define CONFIG_ENV_IS_IN_SPI_FLASH
++#define CONFIG_ENV_SIZE SZ_16K
++#define CONFIG_ENV_OFFSET SZ_256K
++#define CONFIG_ENV_SECT_SIZE SZ_4K
++#define CONFIG_SYS_NO_FLASH
++#define CONFIG_SPI
++#define CONFIG_SPI_FLASH
++#define CONFIG_SPI_FLASH_WINBOND
++#define CONFIG_DAVINCI_SPI
++#define CFG_SPI_BASE DAVINCI_SPI0_BASE
++#define CFG_SPI_CLK clk_get(DAVINCI_SPI0_CLKID)
++#define CONFIG_SF_DEFAULT_SPEED 50000000
++#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
++#endif
++
++
++/*==============================*/
++/* U-Boot general configuration */
++/*==============================*/
++#undef CONFIG_USE_IRQ /* No IRQ/FIQ in U-Boot */
++#define CONFIG_MISC_INIT_R
++#undef CONFIG_BOOTDELAY
++#define CONFIG_BOOTFILE "uImage" /* Boot file name */
++#define CONFIG_SYS_PROMPT "U-Boot > " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print buffer sz */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_MEMTEST_START + 0x700000) /* default Linux kernel load address */
++#define CONFIG_VERSION_VARIABLE
++#define CONFIG_AUTO_COMPLETE /* Won't work with hush so far, may be later */
++#define CONFIG_SYS_HUSH_PARSER
++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
++#define CONFIG_CMDLINE_EDITING
++#define CONFIG_SYS_LONGHELP
++#define CONFIG_CRC32_VERIFY
++#define CONFIG_MX_CYCLIC
++
++/*===================*/
++/* Linux Information */
++/*===================*/
++#define LINUX_BOOT_PARAM_ADDR (CONFIG_SYS_MEMTEST_START + 0x100)
++#define CONFIG_CMDLINE_TAG
++#define CONFIG_SETUP_MEMORY_TAGS
++#define CONFIG_BOOTARGS "mem=32M console=ttyS2,115200n8 root=/dev/mtdblock/2 rw noinitrd ip=dhcp"
++#define CONFIG_BOOTCOMMAND ""
++#define CONFIG_BOOTDELAY 3
++
++/*=================*/
++/* U-Boot commands */
++/*=================*/
++#include <config_cmd_default.h>
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_ASKENV
++#define CONFIG_CMD_DHCP
++#define CONFIG_CMD_DIAG
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_SAVES
++#define CONFIG_CMD_MEMORY
++#undef CONFIG_CMD_BDI
++#undef CONFIG_CMD_FPGA
++#undef CONFIG_CMD_SETGETDCR
++#define CONFIG_CMD_EEPROM
++
++#ifdef CONFIG_SYS_USE_NAND
++#undef CONFIG_CMD_FLASH
++#undef CONFIG_CMD_IMLS
++#define CONFIG_CMD_NAND
++#endif
++
++#ifdef CFG_USE_SPIFLASH
++#undef CONFIG_CMD_IMLS
++#undef CONFIG_CMD_FLASH
++#define CONFIG_CMD_SF
++#endif
++
++#if !defined(CONFIG_SYS_USE_NAND) && !defined(CONFIG_SYS_USE_NOR) && !defined(CFG_USE_SPIFLASH)
++#define CFG_ENV_IS_NOWHERE
++#define CONFIG_SYS_NO_FLASH
++#define CONFIG_ENV_SIZE SZ_16K
++#undef CONFIG_CMD_IMLS
++#undef CONFIG_CMD_FLASH
++#undef CONFIG_CMD_ENV
++#endif
++
++#endif /* __CONFIG_H */
+Index: u-boot-2009.01/board/da8xx/da8xx-evm/Makefile
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/board/da8xx/da8xx-evm/Makefile
+@@ -0,0 +1,52 @@
++#
++# (C) Copyright 2000, 2001, 2002
++# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++#
++# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++#
++# 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 := dv_board.o
++SOBJS := board_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 *~ .depend
++
++#########################################################################
++# This is for $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+Index: u-boot-2009.01/board/da8xx/da8xx-evm/board_init.S
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/board/da8xx/da8xx-evm/board_init.S
+@@ -0,0 +1,29 @@
++/*
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Board-specific low level initialization code. Called at the very end
++ * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no
++ * initialization required.
++ *
++ * 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>
++
++.globl dv_board_init
++dv_board_init:
++
++ mov pc, lr
+Index: u-boot-2009.01/board/da8xx/da8xx-evm/config.mk
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/board/da8xx/da8xx-evm/config.mk
+@@ -0,0 +1,30 @@
++#
++# (C) Copyright 2002
++# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++#
++# (C) Copyright 2003
++# Texas Instruments, <www.ti.com>
++# Swaminathan <swami.iyer@ti.com>
++#
++# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++#
++# (C) Copyright 2008
++# Sekhar Nori, Texas Instruments, Inc. <nsekhar@ti.com>
++#
++# Texas Instruments DA8xx EVM board (ARM925EJS) cpu
++# see http://www.ti.com/ for more information on Texas Instruments
++#
++# DA8xx EVM has 1 bank of 64 MB SDRAM (2 16Meg x16 chips).
++# Physical Address:
++# C000'0000 to C400'0000
++#
++# Linux-Kernel is expected to be at C000'8000, entry C000'8000
++# (mem base + reserved)
++#
++# we load ourself to C108 '0000
++#
++#
++
++#Provide at least 16MB spacing between us and the Linux Kernel image
++TEXT_BASE = 0xC1080000
+Index: u-boot-2009.01/board/da8xx/da8xx-evm/dv_board.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/board/da8xx/da8xx-evm/dv_board.c
+@@ -0,0 +1,231 @@
++/*
++ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc. <nsekhar@ti.com>
++ *
++ * Modified for DA8xx EVM.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Parts are shamelessly stolen from various TI sources, original copyright
++ * follows:
++ * -----------------------------------------------------------------
++ *
++ * Copyright (C) 2004 Texas Instruments.
++ *
++ * ----------------------------------------------------------------------------
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++ */
++
++#include <common.h>
++#include <i2c.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/emac_defs.h>
++
++#define MACH_TYPE_DA8XX_EVM 1781
++
++DECLARE_GLOBAL_DATA_PTR;
++
++extern void timer_init(void);
++extern int eth_hw_init(void);
++
++/* Works on Always On power domain only (no PD argument) */
++void lpsc_on(unsigned int id)
++{
++ dv_reg_p mdstat, mdctl, ptstat, ptcmd;
++
++ if (id >= 64)
++ return;
++
++ if(id < 32) {
++ mdstat = REG_P(PSC0_MDSTAT + (id * 4));
++ mdctl = REG_P(PSC0_MDCTL + (id * 4));
++ ptstat = REG_P(PSC0_PTSTAT);
++ ptcmd = REG_P(PSC0_PTCMD);
++ } else {
++ id -= 32;
++ mdstat = REG_P(PSC1_MDSTAT + (id * 4));
++ mdctl = REG_P(PSC1_MDCTL + (id * 4));
++ ptstat = REG_P(PSC1_PTSTAT);
++ ptcmd = REG_P(PSC1_PTCMD);
++ }
++
++ while (*ptstat & 0x01) {;}
++
++ if ((*mdstat & 0x1f) == 0x03)
++ return; /* Already on and enabled */
++
++ *mdctl |= 0x03;
++
++ /* Special treatment for some modules as for sprue14 p.7.4.2 */
++ /* TBD: Confirm if such cases exist for Primus */
++ if (0)
++ *mdctl |= 0x200;
++
++ *ptcmd = 0x01;
++
++ while (*ptstat & 0x01) {;}
++ while ((*mdstat & 0x1f) != 0x03) {;} /* Probably an overkill... */
++}
++
++int board_init(void)
++{
++
++ dv_reg_p intc;
++
++ /*-------------------------------------------------------*
++ * Mask all IRQs by clearing the global enable and setting
++ * the enable clear for all the 90 interrupts. This code is
++ * also included in low level init. Including it here in case
++ * low level init is skipped. Not removing it from low level
++ * init in case some of the low level init code generates
++ * interrupts... Not expected... but you never know...
++ *-------------------------------------------------------*/
++
++#ifndef CONFIG_USE_IRQ
++ intc = REG_P(INTC_GLB_EN);
++ intc[0] = 0;
++
++ intc = REG_P(INTC_HINT_EN);
++ intc[0] = 0;
++ intc[1] = 0;
++ intc[2] = 0;
++
++ intc = REG_P(INTC_EN_CLR0);
++ intc[0] = 0xFFFFFFFF;
++ intc[1] = 0xFFFFFFFF;
++ intc[2] = 0xFFFFFFFF;
++#endif
++
++ /* arch number of the board */
++ gd->bd->bi_arch_number = MACH_TYPE_DA8XX_EVM;
++
++ /* address of boot parameters */
++ gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
++
++ /* setup the SUSPSRC for ARM to control emulation suspend */
++ REG(SUSPSRC) &= ~( (1 << 27) /* Timer0 */
++ | (1 << 21) /* SPI0 */
++ | (1 << 20) /* UART2 */
++ | (1 << 5) /* EMAC */
++ | (1 << 16) /* I2C0 */
++ );
++
++ /* Power on required peripherals
++ * ARM does not have acess by default to PSC0 and PSC1
++ * assuming here that the DSP bootloader has set the IOPU
++ * such that PSC access is available to ARM
++ */
++ lpsc_on(DAVINCI_LPSC_AEMIF); /* NAND, NOR */
++ lpsc_on(DAVINCI_LPSC_SPI0); /* Serial Flash */
++ lpsc_on(DAVINCI_LPSC_EMAC); /* image download */
++ lpsc_on(DAVINCI_LPSC_UART2); /* console */
++ lpsc_on(DAVINCI_LPSC_GPIO);
++
++ /* Pin Muxing support */
++
++ /* write the kick registers to unlock the PINMUX registers */
++ REG(KICK0) = 0x83e70b13; /* Kick0 unlock */
++ REG(KICK1) = 0x95a4f1e0; /* Kick1 unlock */
++
++#ifdef CONFIG_SPI_FLASH
++ /* SPI0 */
++ REG(PINMUX7) &= 0x00000FFF;
++ REG(PINMUX7) |= 0x11111000;
++#endif
++
++#ifdef CONFIG_DRIVER_TI_EMAC
++ /* RMII clock is sourced externally */
++ REG(PINMUX9) &= 0xFF0FFFFF;
++ REG(PINMUX10) &= 0x0000000F;
++ REG(PINMUX10) |= 0x22222220;
++ REG(PINMUX11) &= 0xFFFFFF00;
++ REG(PINMUX11) |= 0x00000022;
++#endif
++
++ /* Async EMIF */
++#if defined(CFG_USE_NAND) || defined(CFG_USE_NOR)
++ REG(PINMUX13) &= 0x00FFFFFF;
++ REG(PINMUX13) |= 0x11000000;
++ REG(PINMUX14) = 0x11111111;
++ REG(PINMUX15) = 0x11111111;
++ REG(PINMUX16) = 0x11111111;
++ REG(PINMUX17) = 0x11111111;
++ REG(PINMUX18) = 0x11111111;
++ REG(PINMUX19) &= 0xFFFFFFF0;
++ REG(PINMUX19) |= 0x1;
++#endif
++
++ /* UART Muxing and enabling */
++ REG(PINMUX8) &= 0x0FFFFFFF;
++ REG(PINMUX8) |= 0x20000000;
++
++ REG(PINMUX9) &= 0xFFFFFFF0;
++ REG(PINMUX9) |= 0x00000002;
++
++ REG(DAVINCI_UART2_BASE + 0x30) = 0xE001;
++
++ /* I2C muxing */
++ REG(PINMUX8) &= 0xFFF00FFF;
++ REG(PINMUX8) |= 0x00022000;
++
++ /* write the kick registers to lock the PINMUX registers */
++ REG(KICK0) = 0x0; /* Kick0 lock */
++ REG(KICK1) = 0x0; /* Kick1 lock */
++
++ return(0);
++}
++
++int misc_init_r (void)
++{
++ u_int8_t tmp[20], buf[10];
++ int i;
++
++ printf ("ARM Clock : %d Hz\n", clk_get(DAVINCI_ARM_CLKID));
++
++ /* Set Ethernet MAC address from EEPROM */
++ if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0x7f00, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, buf, 6)) {
++ printf("\nEEPROM @ 0x%02x read FAILED!!!\n", CONFIG_SYS_I2C_EEPROM_ADDR);
++ } else {
++ tmp[0] = 0xff;
++ for (i = 0; i < 6; i++)
++ tmp[0] &= buf[i];
++
++ if ((tmp[0] != 0xff) && (getenv("ethaddr") == NULL)) {
++ sprintf((char *)&tmp[0], "%02x:%02x:%02x:%02x:%02x:%02x",
++ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
++ setenv("ethaddr", (char *)&tmp[0]);
++ }
++ }
++
++ tmp[0] = 0x01;
++ tmp[1] = 0x23;
++ if(i2c_write(0x5f, 0, 0, tmp, 2)) {
++ printf("Ethernet switch start failed!\n");
++ }
++
++ if (!eth_hw_init()) {
++ printf("Error: Ethernet init failed!\n");
++ }
++
++ return(0);
++}
++
++int dram_init(void)
++{
++ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++
++ return(0);
++}
+Index: u-boot-2009.01/board/da8xx/da8xx-evm/u-boot.lds
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/board/da8xx/da8xx-evm/u-boot.lds
+@@ -0,0 +1,52 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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
++ */
++
++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x00000000;
++ . = ALIGN(4);
++ .text :
++ {
++ cpu/arm926ejs/start.o (.text)
++ *(.text)
++ }
++ . = ALIGN(4);
++ .rodata : { *(.rodata) }
++ . = ALIGN(4);
++ .data : { *(.data) }
++ . = ALIGN(4);
++ .got : { *(.got) }
++
++ . = .;
++ __u_boot_cmd_start = .;
++ .u_boot_cmd : { *(.u_boot_cmd) }
++ __u_boot_cmd_end = .;
++
++ . = ALIGN(4);
++ __bss_start = .;
++ .bss (NOLOAD) : { *(.bss) }
++ _end = .;
++}
+Index: u-boot-2009.01/cpu/arm926ejs/da8xx/Makefile
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/cpu/arm926ejs/da8xx/Makefile
+@@ -0,0 +1,49 @@
++#
++# (C) Copyright 2000-2006
++# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++#
++# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++#
++# 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 ether.o nand.o clock.o i2c.o
++SOBJS = lowlevel_init.o reset.o
++
++SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
++START := $(addprefix $(obj),$(START))
++
++all: $(obj).depend $(LIB)
++
++$(LIB): $(OBJS)
++ $(AR) $(ARFLAGS) $@ $(OBJS)
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+Index: u-boot-2009.01/cpu/arm926ejs/da8xx/clock.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/cpu/arm926ejs/da8xx/clock.c
+@@ -0,0 +1,57 @@
++/*
++ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc. <nsekhar@ti.com>
++ *
++ * DA8xx clock module
++ *
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++ */
++
++#include <common.h>
++#include <asm/arch/hardware.h>
++
++dv_reg_p sysdiv[9] = {
++ PLL0_DIV1, PLL0_DIV2, PLL0_DIV3, PLL0_DIV4, PLL0_DIV5, PLL0_DIV6,
++ PLL0_DIV7, PLL0_DIV8, PLL0_DIV9 };
++
++int clk_get(unsigned int id)
++{
++ int pre_div = (REG(PLL0_PREDIV) & 0xff) + 1;
++ int pllm = REG(PLL0_PLLM) + 1;
++ int post_div = (REG(PLL0_POSTDIV) & 0xff) + 1;
++ int pll_out = CFG_OSCIN_FREQ;
++
++ if(id == DAVINCI_AUXCLK_CLKID)
++ goto out;
++
++ /* Lets keep this simple. Combining operations can result in
++ * unexpected approximations
++ */
++ pll_out /= pre_div;
++ pll_out *= pllm;
++
++ if(id == DAVINCI_PLLM_CLKID)
++ goto out;
++
++ pll_out /= post_div;
++
++ if(id == DAVINCI_PLLC_CLKID)
++ goto out;
++
++ pll_out /= (REG(sysdiv[id - 1]) & 0xff) + 1;
++
++out:
++ return pll_out;
++}
+Index: u-boot-2009.01/cpu/arm926ejs/da8xx/ether.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/cpu/arm926ejs/da8xx/ether.c
+@@ -0,0 +1,667 @@
++/*
++ * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
++ * follows:
++ *
++ * ----------------------------------------------------------------------------
++ *
++ * dm644x_emac.c
++ *
++ * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
++ *
++ * Copyright (C) 2005 Texas Instruments.
++ *
++ * ----------------------------------------------------------------------------
++ *
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++
++ * Modifications:
++ * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
++ * ver 1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
++ *
++ */
++#include <common.h>
++#include <command.h>
++#include <net.h>
++#include <miiphy.h>
++#include <asm/arch/emac_defs.h>
++
++#ifdef CONFIG_DRIVER_TI_EMAC
++
++#ifdef CONFIG_CMD_NET
++
++unsigned int emac_dbg = 0;
++#define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args)
++
++/* Internal static functions */
++static int dm644x_eth_hw_init (void);
++static int dm644x_eth_open (void);
++static int dm644x_eth_close (void);
++static int dm644x_eth_send_packet (volatile void *packet, int length);
++static int dm644x_eth_rcv_packet (void);
++static void dm644x_eth_mdio_enable(void);
++
++static int gen_init_phy(int phy_addr);
++static int gen_is_phy_connected(int phy_addr);
++static int gen_get_link_speed(int phy_addr);
++static int gen_auto_negotiate(int phy_addr);
++
++/* Wrappers exported to the U-Boot proper */
++int eth_hw_init(void)
++{
++ return(dm644x_eth_hw_init());
++}
++
++int eth_init(bd_t * bd)
++{
++ return(dm644x_eth_open());
++}
++
++void eth_halt(void)
++{
++ dm644x_eth_close();
++}
++
++int eth_send(volatile void *packet, int length)
++{
++ return(dm644x_eth_send_packet(packet, length));
++}
++
++int eth_rx(void)
++{
++ return(dm644x_eth_rcv_packet());
++}
++
++void eth_mdio_enable(void)
++{
++ dm644x_eth_mdio_enable();
++}
++/* End of wrappers */
++
++/* dm644x_eth_mac_addr[0] goes out on the wire first */
++
++static u_int8_t dm644x_eth_mac_addr[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00 };
++
++/*
++ * This function must be called before emac_open() if you want to override
++ * the default mac address.
++ */
++void dm644x_eth_set_mac_addr(const u_int8_t *addr)
++{
++ int i;
++
++ for (i = 0; i < sizeof (dm644x_eth_mac_addr); i++) {
++ dm644x_eth_mac_addr[i] = addr[i];
++ }
++}
++
++/* EMAC Addresses */
++static volatile emac_regs *adap_emac = (emac_regs *)EMAC_BASE_ADDR;
++static volatile ewrap_regs *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
++static volatile mdio_regs *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;
++
++/* EMAC descriptors */
++static volatile emac_desc *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
++static volatile emac_desc *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
++static volatile emac_desc *emac_rx_active_head = 0;
++static volatile emac_desc *emac_rx_active_tail = 0;
++static int emac_rx_queue_active = 0;
++
++/* Receive packet buffers */
++static unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
++
++/* PHY address for a discovered PHY (0xff - not found) */
++static volatile u_int8_t active_phy_addr = 0xff;
++
++static int no_phy_init (int phy_addr) { return(1); }
++static int no_phy_is_connected (int phy_addr) { return(1); }
++static int no_phy_get_link_speed (int phy_addr) { return(1); }
++static int no_phy_auto_negotiate (int phy_addr) { return(1); }
++phy_t phy = {
++ .init = no_phy_init,
++ .is_phy_connected = no_phy_is_connected,
++ .get_link_speed = no_phy_get_link_speed,
++ .auto_negotiate = no_phy_auto_negotiate
++};
++
++static void dm644x_eth_mdio_enable(void)
++{
++ u_int32_t clkdiv;
++
++ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
++
++ adap_mdio->CONTROL = (clkdiv & 0xff) |
++ MDIO_CONTROL_ENABLE |
++ MDIO_CONTROL_FAULT |
++ MDIO_CONTROL_FAULT_ENABLE;
++
++ while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
++}
++
++/*
++ * Tries to find an active connected PHY. Returns 1 if address if found.
++ * If no active PHY found returns 0. If more than one active PHY (switch)
++ * returns 2
++ * Sets active_phy_addr variable when returns 1.
++ */
++static int dm644x_eth_phy_detect(void)
++{
++ u_int32_t phy_act_state;
++ int i;
++
++ active_phy_addr = 0xff;
++
++ if ((phy_act_state = adap_mdio->ALIVE) == 0)
++ return(0); /* No active PHYs */
++
++ debug_emac("dm644x_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
++
++ for (i = 0; i < 32; i++) {
++ if (phy_act_state & (1 << i)) {
++ if (phy_act_state & ~(1 << i))
++ return(2); /* More than one PHY */
++ else {
++ active_phy_addr = i;
++ return(1);
++ }
++ }
++ }
++
++ return(0); /* Just to make GCC happy */
++}
++
++
++/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
++int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
++{
++ int tmp;
++
++ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
++
++ adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
++ MDIO_USERACCESS0_WRITE_READ |
++ ((reg_num & 0x1f) << 21) |
++ ((phy_addr & 0x1f) << 16);
++
++ /* Wait for command to complete */
++ while ((tmp = adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) {;}
++
++ if (tmp & MDIO_USERACCESS0_ACK) {
++ *data = tmp & 0xffff;
++ return(1);
++ }
++
++ *data = -1;
++ return(0);
++}
++
++/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
++int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
++{
++
++ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
++
++ adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
++ MDIO_USERACCESS0_WRITE_WRITE |
++ ((reg_num & 0x1f) << 21) |
++ ((phy_addr & 0x1f) << 16) |
++ (data & 0xffff);
++
++ /* Wait for command to complete */
++ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
++
++ return(1);
++}
++
++/* PHY functions for a generic PHY */
++static int gen_init_phy(int phy_addr)
++{
++ int ret = 1;
++
++ if (gen_get_link_speed(phy_addr)) {
++ /* Try another time */
++ ret = gen_get_link_speed(phy_addr);
++ }
++
++ return(ret);
++}
++
++static int gen_is_phy_connected(int phy_addr)
++{
++ u_int16_t dummy;
++
++ return(dm644x_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy));
++}
++
++static int gen_get_link_speed(int phy_addr)
++{
++ u_int16_t tmp;
++
++ if (dm644x_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) && (tmp & 0x04))
++ return(1);
++
++ return(0);
++}
++
++static int gen_auto_negotiate(int phy_addr)
++{
++ u_int16_t tmp;
++
++ if (!dm644x_eth_phy_read(phy_addr, PHY_BMCR, &tmp))
++ return(0);
++
++ /* Restart Auto_negotiation */
++ tmp |= PHY_BMCR_AUTON;
++ dm644x_eth_phy_write(phy_addr, PHY_BMCR, tmp);
++
++ /*check AutoNegotiate complete */
++ udelay (10000);
++ if (!dm644x_eth_phy_read(phy_addr, PHY_BMSR, &tmp))
++ return(0);
++
++ if (!(tmp & PHY_BMSR_AUTN_COMP))
++ return(0);
++
++ return(gen_get_link_speed(phy_addr));
++}
++/* End of generic PHY functions */
++
++
++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
++static int dm644x_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
++{
++ return(dm644x_eth_phy_read(addr, reg, value) ? 0 : 1);
++}
++
++static int dm644x_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value)
++{
++ return(dm644x_eth_phy_write(addr, reg, value) ? 0 : 1);
++}
++
++int dm644x_eth_miiphy_initialize(bd_t *bis)
++{
++ miiphy_register(phy.name, dm644x_mii_phy_read, dm644x_mii_phy_write);
++
++ return(1);
++}
++#endif
++
++/*
++ * This function initializes the emac hardware. It does NOT initialize
++ * EMAC modules power or pin multiplexors, that is done by board_init()
++ * much earlier in bootup process. Returns 1 on success, 0 otherwise.
++ */
++static int dm644x_eth_hw_init(void)
++{
++ u_int32_t phy_id;
++ u_int16_t tmp;
++ int i, ret;
++
++ /* The RMII clock can be sources internally through the SYSCLK7
++ * or can come externally through a dedicated pin. This selection is
++ * controlled by PinMux9[21]. PinMux registers are off-limits for ARM.
++ * In short, we just assume there is a 50MHz RMII clock available.
++ */
++
++ dm644x_eth_mdio_enable();
++
++ for (i = 0; i < 256; i++) {
++ if (adap_mdio->ALIVE)
++ break;
++ udelay(1000);
++ }
++
++ if (i >= 256) {
++ printf("No ETH PHY detected!!!\n");
++ return(0);
++ }
++
++ /* Find if a PHY is connected and get it's address */
++ ret = dm644x_eth_phy_detect();
++
++ if (ret == 2) {
++ printf("More than one PHY detected.\n");
++ return(1);
++ } else if(ret == 0)
++ return(0);
++
++ /* Get PHY ID and initialize phy_ops for a detected PHY */
++ if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR1, &tmp)) {
++ active_phy_addr = 0xff;
++ return(0);
++ }
++
++ phy_id = (tmp << 16) & 0xffff0000;
++
++ if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR2, &tmp)) {
++ active_phy_addr = 0xff;
++ return(0);
++ }
++
++ phy_id |= tmp & 0x0000ffff;
++
++ switch (phy_id) {
++ default:
++ sprintf(phy.name, "GENERIC @ 0x%02x", active_phy_addr);
++ phy.init = gen_init_phy;
++ phy.is_phy_connected = gen_is_phy_connected;
++ phy.get_link_speed = gen_get_link_speed;
++ phy.auto_negotiate = gen_auto_negotiate;
++ }
++
++ return(1);
++}
++
++
++/* Eth device open */
++static int dm644x_eth_open(void)
++{
++ dv_reg_p addr;
++ u_int32_t clkdiv, cnt;
++ volatile emac_desc *rx_desc;
++ int i;
++
++ debug_emac("+ emac_open\n");
++
++ /* Reset EMAC module and disable interrupts in wrapper */
++ adap_emac->SOFTRESET = 1;
++ while (adap_emac->SOFTRESET != 0) {;}
++ adap_ewrap->SOFTRESET = 1;
++ while (adap_ewrap->SOFTRESET != 0) {;}
++
++ adap_ewrap->C0RXEN = adap_ewrap->C1RXEN = adap_ewrap->C2RXEN = 0;
++ adap_ewrap->C0TXEN = adap_ewrap->C1TXEN = adap_ewrap->C2TXEN = 0;
++ adap_ewrap->C0MISCEN = adap_ewrap->C1MISCEN = adap_ewrap->C2MISCEN = 0;
++
++ rx_desc = emac_rx_desc;
++
++ adap_emac->TXCONTROL = 0x01;
++ adap_emac->RXCONTROL = 0x01;
++
++ /* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */
++ /* Using channel 0 only - other channels are disabled */
++ for (i = 0; i < 8; i++) {
++ adap_emac->MACINDEX = i;
++ adap_emac->MACADDRHI =
++ (dm644x_eth_mac_addr[3] << 24) | /* bits 23-16 */
++ (dm644x_eth_mac_addr[2] << 16) | /* bits 31-24 */
++ (dm644x_eth_mac_addr[1] << 8) | /* bits 39-32 */
++ (dm644x_eth_mac_addr[0]); /* bits 47-40 */
++ adap_emac->MACADDRLO =
++ (dm644x_eth_mac_addr[5] << 8) | /* bits 8-0*/
++ (dm644x_eth_mac_addr[4]) | (1 << 19) | (1 << 20); /* bits 8-0 */
++ }
++
++ adap_emac->MACHASH1 = 0;
++ adap_emac->MACHASH2 = 0;
++
++ /* Set source MAC address - REQUIRED for pause frames */
++ adap_emac->MACSRCADDRHI =
++ (dm644x_eth_mac_addr[3] << 24) | /* bits 23-16 */
++ (dm644x_eth_mac_addr[2] << 16) | /* bits 31-24 */
++ (dm644x_eth_mac_addr[1] << 8) | /* bits 39-32 */
++ (dm644x_eth_mac_addr[0]); /* bits 47-40 */
++ adap_emac->MACSRCADDRLO =
++ (dm644x_eth_mac_addr[5] << 8) | /* bits 8-0 */
++ (dm644x_eth_mac_addr[4]); /* bits 15-8 */
++
++ /* Set DMA 8 TX / 8 RX Head pointers to 0 */
++ addr = &adap_emac->TX0HDP;
++ for(cnt = 0; cnt < 16; cnt++)
++ *addr++ = 0;
++
++ addr = &adap_emac->TX0CP;
++ for(cnt = 0; cnt < 16; cnt++)
++ *addr++ = 0;
++
++ /* Clear Statistics (do this before setting MacControl register) */
++ addr = &adap_emac->RXGOODFRAMES;
++ for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
++ *addr++ = 0;
++
++ /* No multicast addressing */
++ adap_emac->MACHASH1 = 0;
++ adap_emac->MACHASH2 = 0;
++
++ /* Create RX queue and set receive process in place */
++ emac_rx_active_head = emac_rx_desc;
++ for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
++ rx_desc->next = (u_int32_t)(rx_desc + 1);
++ rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
++ rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
++ rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
++ rx_desc++;
++ }
++
++ /* Set the last descriptor's "next" parameter to 0 to end the RX desc list */
++ rx_desc--;
++ rx_desc->next = 0;
++ emac_rx_active_tail = rx_desc;
++ emac_rx_queue_active = 1;
++
++ /* Enable TX/RX */
++ adap_emac->RXMAXLEN = EMAC_MAX_ETHERNET_PKT_SIZE;
++ adap_emac->RXBUFFEROFFSET = 0;
++
++ /* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */
++ adap_emac->RXMBPENABLE = EMAC_RXMBPENABLE_RXBROADEN;
++
++ /* Enable ch 0 only */
++ adap_emac->RXUNICASTSET = 0x01;
++
++ /* Enable MII interface and Full duplex mode */
++ adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE) | EMAC_MACCONTROL_RMIISPEED_100;
++
++ /* Init MDIO & get link state */
++ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
++ adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
++
++ if (!phy.get_link_speed(active_phy_addr))
++ return(0);
++
++ /* Start receive process */
++ adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
++
++ debug_emac("- emac_open\n");
++
++ return(1);
++}
++
++/* EMAC Channel Teardown */
++static void dm644x_eth_ch_teardown(int ch)
++{
++ dv_reg dly = 0xff;
++ dv_reg cnt;
++
++ debug_emac("+ emac_ch_teardown\n");
++
++ if (ch == EMAC_CH_TX) {
++ /* Init TX channel teardown */
++ adap_emac->TXTEARDOWN = 1;
++ for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->TX0CP) {
++ /* Wait here for Tx teardown completion interrupt to occur
++ * Note: A task delay can be called here to pend rather than
++ * occupying CPU cycles - anyway it has been found that teardown
++ * takes very few cpu cycles and does not affect functionality */
++ dly--;
++ udelay(1);
++ if (dly == 0)
++ break;
++ }
++ adap_emac->TX0CP = cnt;
++ adap_emac->TX0HDP = 0;
++ } else {
++ /* Init RX channel teardown */
++ adap_emac->RXTEARDOWN = 1;
++ for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->RX0CP) {
++ /* Wait here for Rx teardown completion interrupt to occur
++ * Note: A task delay can be called here to pend rather than
++ * occupying CPU cycles - anyway it has been found that teardown
++ * takes very few cpu cycles and does not affect functionality */
++ dly--;
++ udelay(1);
++ if (dly == 0)
++ break;
++ }
++ adap_emac->RX0CP = cnt;
++ adap_emac->RX0HDP = 0;
++ }
++
++ debug_emac("- emac_ch_teardown\n");
++}
++
++/* Eth device close */
++static int dm644x_eth_close(void)
++{
++ debug_emac("+ emac_close\n");
++
++ dm644x_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */
++ dm644x_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */
++
++ /* Reset EMAC module and disable interrupts in wrapper */
++ adap_emac->SOFTRESET = 1;
++ adap_ewrap->SOFTRESET = 1;
++
++ adap_ewrap->C0RXEN = adap_ewrap->C1RXEN = adap_ewrap->C2RXEN = 0;
++ adap_ewrap->C0TXEN = adap_ewrap->C1TXEN = adap_ewrap->C2TXEN = 0;
++ adap_ewrap->C0MISCEN = adap_ewrap->C1MISCEN = adap_ewrap->C2MISCEN = 0;
++
++ debug_emac("- emac_close\n");
++ return(1);
++}
++
++static int tx_send_loop = 0;
++
++/*
++ * This function sends a single packet on the network and returns
++ * positive number (number of bytes transmitted) or negative for error
++ */
++static int dm644x_eth_send_packet(volatile void *packet, int length)
++{
++ int ret_status = -1;
++ tx_send_loop = 0;
++
++ /* Return error if no link */
++ if (!phy.get_link_speed(active_phy_addr))
++ {
++ printf("WARN: emac_send_packet: No link\n");
++ return (ret_status);
++ }
++
++ /* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
++ if (length < EMAC_MIN_ETHERNET_PKT_SIZE)
++ {
++ length = EMAC_MIN_ETHERNET_PKT_SIZE;
++ }
++
++ /* Populate the TX descriptor */
++ emac_tx_desc->next = 0;
++ emac_tx_desc->buffer = (u_int8_t *)packet;
++ emac_tx_desc->buff_off_len = (length & 0xffff);
++ emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
++ EMAC_CPPI_SOP_BIT |
++ EMAC_CPPI_OWNERSHIP_BIT |
++ EMAC_CPPI_EOP_BIT);
++ /* Send the packet */
++ adap_emac->TX0HDP = (unsigned int)emac_tx_desc;
++
++ /* Wait for packet to complete or link down */
++ while (1) {
++ if (!phy.get_link_speed(active_phy_addr)) {
++ dm644x_eth_ch_teardown(EMAC_CH_TX);
++ return (ret_status);
++ }
++ if (adap_emac->TXINTSTATRAW & 0x01) {
++ ret_status = length;
++ break;
++ }
++ tx_send_loop++;
++ }
++
++ return(ret_status);
++}
++
++/*
++ * This function handles receipt of a packet from the network
++ */
++static int dm644x_eth_rcv_packet(void)
++{
++ volatile emac_desc *rx_curr_desc;
++ volatile emac_desc *curr_desc;
++ volatile emac_desc *tail_desc;
++ int status, ret = -1;
++
++ rx_curr_desc = emac_rx_active_head;
++ status = rx_curr_desc->pkt_flag_len;
++ if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) {
++ if (status & EMAC_CPPI_RX_ERROR_FRAME) {
++ /* Error in packet - discard it and requeue desc */
++ printf("WARN: emac_rcv_pkt: Error in packet\n");
++ } else {
++ NetReceive(rx_curr_desc->buffer, (rx_curr_desc->buff_off_len & 0xffff));
++ ret = rx_curr_desc->buff_off_len & 0xffff;
++ }
++
++ /* Ack received packet descriptor */
++ adap_emac->RX0CP = (unsigned int)rx_curr_desc;
++ curr_desc = rx_curr_desc;
++ emac_rx_active_head = (volatile emac_desc *)rx_curr_desc->next;
++
++ if (status & EMAC_CPPI_EOQ_BIT) {
++ if (emac_rx_active_head) {
++ adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
++ } else {
++ emac_rx_queue_active = 0;
++ printf("INFO:emac_rcv_packet: RX Queue not active\n");
++ }
++ }
++
++ /* Recycle RX descriptor */
++ rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
++ rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
++ rx_curr_desc->next = 0;
++
++ if (emac_rx_active_head == 0) {
++ printf("INFO: emac_rcv_pkt: active queue head = 0\n");
++ emac_rx_active_head = curr_desc;
++ emac_rx_active_tail = curr_desc;
++ if (emac_rx_queue_active != 0) {
++ adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
++ printf("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
++ emac_rx_queue_active = 1;
++ }
++ } else {
++ tail_desc = emac_rx_active_tail;
++ emac_rx_active_tail = curr_desc;
++ tail_desc->next = (unsigned int)curr_desc;
++ status = tail_desc->pkt_flag_len;
++ if (status & EMAC_CPPI_EOQ_BIT) {
++ adap_emac->RX0HDP = (unsigned int)curr_desc;
++ status &= ~EMAC_CPPI_EOQ_BIT;
++ tail_desc->pkt_flag_len = status;
++ }
++ }
++ return(ret);
++ }
++ return(0);
++}
++
++#endif /* CONFIG_CMD_NET */
++
++#endif /* CONFIG_DRIVER_TI_EMAC */
+Index: u-boot-2009.01/cpu/arm926ejs/da8xx/i2c.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/cpu/arm926ejs/da8xx/i2c.c
+@@ -0,0 +1,356 @@
++/*
++ * TI DaVinci (TMS320DM644x) I2C driver.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * --------------------------------------------------------
++ *
++ * 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>
++
++#ifdef CONFIG_DRIVER_DAVINCI_I2C
++
++#include <i2c.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/i2c_defs.h>
++
++#define CHECK_NACK() \
++ do {\
++ if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
++ REG(I2C_CON) = 0;\
++ return(1);\
++ }\
++ } while (0)
++
++
++static int wait_for_bus(void)
++{
++ int stat, timeout;
++
++ REG(I2C_STAT) = 0xffff;
++
++ for (timeout = 0; timeout < 10; timeout++) {
++ if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
++ REG(I2C_STAT) = 0xffff;
++ return(0);
++ }
++
++ REG(I2C_STAT) = stat;
++ udelay(50000);
++ }
++
++ REG(I2C_STAT) = 0xffff;
++ return(1);
++}
++
++
++static int poll_i2c_irq(int mask)
++{
++ int stat, timeout;
++
++ for (timeout = 0; timeout < 10; timeout++) {
++ udelay(1000);
++ stat = REG(I2C_STAT);
++ if (stat & mask) {
++ return(stat);
++ }
++ }
++
++ REG(I2C_STAT) = 0xffff;
++ return(stat | I2C_TIMEOUT);
++}
++
++
++void flush_rx(void)
++{
++ int dummy;
++
++ while (1) {
++ if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
++ break;
++
++ dummy = REG(I2C_DRR);
++ REG(I2C_STAT) = I2C_STAT_RRDY;
++ udelay(1000);
++ }
++}
++
++
++void i2c_init(int speed, int slaveadd)
++{
++ u_int32_t div, psc;
++
++ if (REG(I2C_CON) & I2C_CON_EN) {
++ REG(I2C_CON) = 0;
++ udelay (50000);
++ }
++
++ /* Get 1MHz into I2C internal */
++ psc = CONFIG_SYS_HZ_CLOCK/1000000;
++
++ div = CONFIG_SYS_HZ_CLOCK / (psc * speed); /* SCLL + SCLH */
++
++ REG(I2C_PSC) = psc - 1; /* 27MHz / (2 + 1) = 9MHz */
++ REG(I2C_SCLL) = (div * 50) / 100; /* 50% Duty */
++ REG(I2C_SCLH) = div - REG(I2C_SCLL);
++
++ REG(I2C_OA) = slaveadd;
++ REG(I2C_CNT) = 0;
++
++ /* Interrupts must be enabled or I2C module won't work */
++ REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
++ I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
++
++ /* Now enable I2C controller (get it out of reset) */
++ REG(I2C_CON) = I2C_CON_EN;
++
++ udelay(1000);
++}
++
++
++int i2c_probe(u_int8_t chip)
++{
++ int rc = 1;
++
++ if (chip == REG(I2C_OA)) {
++ return(rc);
++ }
++
++ REG(I2C_CON) = 0;
++ if (wait_for_bus()) {return(1);}
++
++ /* try to read one byte from current (or only) address */
++ REG(I2C_CNT) = 1;
++ REG(I2C_SA) = chip;
++ REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP | I2C_CON_FREE);
++ udelay (50000);
++
++ if (!(REG(I2C_STAT) & I2C_STAT_NACK)) {
++ rc = 0;
++ flush_rx();
++ REG(I2C_STAT) = 0xffff;
++ } else {
++ REG(I2C_STAT) = 0xffff;
++ REG(I2C_CON) |= I2C_CON_STP;
++ udelay(20000);
++ if (wait_for_bus()) {return(1);}
++ }
++
++ flush_rx();
++ REG(I2C_STAT) = 0xffff;
++ REG(I2C_CNT) = 0;
++ return(rc);
++}
++
++
++int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
++{
++ u_int32_t tmp;
++ int i;
++
++ if ((alen < 0) || (alen > 2)) {
++ printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
++ return(1);
++ }
++
++ if (wait_for_bus()) {return(1);}
++
++ if (alen != 0) {
++ /* Start address phase */
++ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
++ I2C_CON_FREE;
++ REG(I2C_CNT) = alen;
++ REG(I2C_SA) = chip;
++ REG(I2C_CON) = tmp;
++
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ switch (alen) {
++ case 2:
++ /* Send address MSByte */
++ if (tmp & I2C_STAT_XRDY) {
++ REG(I2C_DXR) = (addr >> 8) & 0xff;
++ } else {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ CHECK_NACK();
++ /* No break, fall through */
++ case 1:
++ /* Send address LSByte */
++ if (tmp & I2C_STAT_XRDY) {
++ REG(I2C_DXR) = addr & 0xff;
++ } else {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY);
++
++ CHECK_NACK();
++
++ if (!(tmp & I2C_STAT_ARDY)) {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++ }
++ }
++
++ /* Address phase is over, now read 'len' bytes and stop */
++ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP | I2C_CON_FREE;
++ REG(I2C_CNT) = len & 0xffff;
++ REG(I2C_SA) = chip;
++ REG(I2C_CON) = tmp;
++
++ for (i = 0; i < len; i++) {
++ tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR);
++
++ CHECK_NACK();
++
++ if (tmp & I2C_STAT_RRDY) {
++ buf[i] = REG(I2C_DRR);
++ } else {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++ }
++
++ tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ if (!(tmp & I2C_STAT_SCD)) {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++
++ flush_rx();
++ REG(I2C_STAT) = 0xffff;
++ REG(I2C_CNT) = 0;
++ REG(I2C_CON) = 0;
++
++ return(0);
++}
++
++
++int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
++{
++ u_int32_t tmp;
++ int i;
++
++ if ((alen < 0) || (alen > 2)) {
++ printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
++ return(1);
++ }
++ if (len < 0) {
++ printf("%s(): bogus length %x\n", __FUNCTION__, len);
++ return(1);
++ }
++
++ if (wait_for_bus()) {return(1);}
++
++ /* Start address phase */
++ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP;
++ REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
++ REG(I2C_SA) = chip;
++ REG(I2C_CON) = tmp;
++
++ switch (alen) {
++ case 2:
++ /* Send address MSByte */
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ if (tmp & I2C_STAT_XRDY) {
++ REG(I2C_DXR) = (addr >> 8) & 0xff;
++ } else {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++ /* No break, fall through */
++ case 1:
++ /* Send address LSByte */
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ if (tmp & I2C_STAT_XRDY) {
++ REG(I2C_DXR) = addr & 0xff;
++ } else {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++ }
++
++ for (i = 0; i < len; i++) {
++ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ if (tmp & I2C_STAT_XRDY) {
++ REG(I2C_DXR) = buf[i];
++ } else {
++ return(1);
++ }
++ }
++
++ tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
++
++ CHECK_NACK();
++
++ if (!(tmp & I2C_STAT_SCD)) {
++ REG(I2C_CON) = 0;
++ return(1);
++ }
++
++ flush_rx();
++ REG(I2C_STAT) = 0xffff;
++ REG(I2C_CNT) = 0;
++ REG(I2C_CON) = 0;
++
++ return(0);
++}
++
++#if 0
++u_int8_t i2c_reg_read(u_int8_t chip, u_int8_t reg)
++{
++ u_int8_t tmp;
++
++ i2c_read(chip, reg, 1, &tmp, 1);
++ return(tmp);
++}
++
++
++void i2c_reg_write(u_int8_t chip, u_int8_t reg, u_int8_t val)
++{
++ u_int8_t tmp;
++
++ i2c_write(chip, reg, 1, &tmp, 1);
++}
++#endif /* if 0 */
++
++#endif /* CONFIG_DRIVER_DAVINCI_I2C */
+Index: u-boot-2009.01/cpu/arm926ejs/da8xx/lowlevel_init.S
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/cpu/arm926ejs/da8xx/lowlevel_init.S
+@@ -0,0 +1,504 @@
++/*
++ * Low-level board setup code for TI DA8xx SoC based boards.
++ *
++ * Copyright (C) 2008 Texas Instruments, Inc <www.ti.com>
++ * Sekhar Nori <nsekhar@ti.com>
++ *
++ * Based on TI DaVinci low level init code. Original copyrights follow.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Partially based on TI sources, original copyrights follow:
++ */
++
++/*
++ * Board specific setup info
++ *
++ * (C) Copyright 2003
++ * Texas Instruments, <www.ti.com>
++ * Kshitij Gupta <Kshitij@ti.com>
++ *
++ * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
++ *
++ * Modified for OMAP 5912 OSK board by Rishi Bhattacharya, Apr 2004
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * Modified for DV-EVM board by Rishi Bhattacharya, Apr 2005
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * Modified for DV-EVM board by Swaminathan S, Nov 2005
++ * 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>
++#include <asm/arch/hardware.h>
++
++.globl lowlevel_init
++lowlevel_init:
++
++ nop
++ nop
++ nop
++ nop
++
++ /*
++ * Call board-specific lowlevel init.
++ * That MUST be present and THAT returns
++ * back to arch calling code with "mov pc, lr."
++ */
++ b dv_board_init
++
++#ifndef CONFIG_USE_IRQ
++ /*-------------------------------------------------------*
++ * Mask all IRQs by clearing the global enable and setting
++ * the enable clear for all the 90 interrupts.
++ *-------------------------------------------------------*/
++ mov r1, $0
++ ldr r0, INTC_GLB_EN_ADDR
++ str r1, [r0]
++
++ ldr r0, INTC_HINT_EN_ADDR
++ str r1, [r0]
++ add r0, r0, $4
++ str r1, [r0]
++ add r0, r0, $4
++ str r1, [r0]
++
++ mvn r1, r1
++ ldr r0, INTC_EN_CLR0_ADDR
++ str r1, [r0]
++ add r0, r0, $4
++ str r1, [r0]
++ add r0, r0, $4
++ str r1, [r0]
++#endif
++
++ /*------------------------------------------------------*
++ * PLL0 Initialization - works only in non-secure devices
++ *------------------------------------------------------*/
++
++ /* TODO: Write the kick values and the PLL master lock bits */
++
++ /* Select OSCIN in clockmode bit in PLLCTL register. This is the only
++ * clock mode supported on DA8xx
++ */
++ ldr r6, PLL0_PLLCTL_ADDR
++ ldr r7, PLL_CLKSRC_MASK
++ ldr r8, [r6]
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* Clear the PLLENSRC bit in PLLCTL */
++ ldr r7, PLL_ENSRC_MASK
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* Bypass the PLL */
++ ldr r7, PLL_BYPASS_MASK
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */
++ mov r10, $0x20
++WaitPLL0Loop:
++ subs r10, r10, $1
++ bne WaitPLL0Loop
++
++ /* Reset the PLL */
++ ldr r7, PLL_RESET_MASK
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* disable PLL output */
++ mov r7, $0x10
++ orr r8, r8, r7
++ str r8, [r6]
++
++ /* Power up the PLL */
++ ldr r7, PLL_PWRUP_MASK
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* Enable the PLL from Disable Mode */
++ ldr r7, PLL_DISABLE_ENABLE_MASK
++ and r8, r8, r7
++ str r8, [r6]
++
++ /* Wait for the PLL stabilization time - 150us assumed */
++ mov r10, $0xE10
++PLLStableLoop:
++ subs r10, r10, $1
++ bne PLLStableLoop
++
++ /* Program the PLL Multiplier */
++ ldr r6, PLL0_PLLM_ADDR
++ mov r2, $0x18 /* 24 * 25 = 600MHz*/
++ str r2, [r6]
++
++ /* Program the POSTDIV Value */
++ ldr r6, PLL0_POSTDIV_ADDR
++ mov r3, $0x01
++ mov r3, r3, lsl $15
++ orr r3, r3, $0x01
++ str r3, [r6]
++
++ /* Program the SYSCLKx dividedrs */
++
++ /* Following defaults are good:
++ * SYSCLK1 = /1 => 300MHz GEM
++ * SYSCLK2 = /2 => 150MHz EDMA, MMC/SD, UART1/2, SPI1
++ * SYSCLK3 = /3 => 100MHz Possible EMIF2.5
++ * SYSCLK4 = /4 => 75MHz INTC, PSC, EMAC, USB 1.1, I2C1
++ * SYSCLK5 = /3 => 100MHz Possible EMIF3.0 (use DIV4p5)
++ * SYSCLK6 = /1 => 300MHz ARM
++ * SYSCLK7 = /6 => 50MHz RMII Ref Clk
++ * SYSCLK8 = /6 => 50MHz Dont use
++ * SYSCLK9 = /6 => 50MHz Dont use
++ * AUXCLK FIXED => 24Mhz Timer 0/1, 12C0, McASP AuxClk
++ */
++
++ /* Wait for PLL to Reset Properly - 128 OSCIN cycles*/
++ mov r10, $128
++ResetPPL2Loop:
++ subs r10, r10, $1
++ bne ResetPPL2Loop
++
++ /* Bring PLL out of Reset */
++ ldr r6, PLL0_PLLCTL_ADDR
++ ldr r8, [r6]
++ orr r8, r8, $0x08
++ str r8, [r6]
++
++ /* Wait for PLL to Lock */
++ ldr r10, PLL_LOCK_COUNT
++PLL0Lock:
++ subs r10, r10, $1
++ bne PLL0Lock
++
++ /* Enable the PLL */
++ ldr r6, PLL0_PLLCTL_ADDR
++ ldr r8, [r6]
++ orr r8, r8, $0x01
++ str r8, [r6]
++
++ /*------------------------------------------------------*
++ * Setup the pinmux for DDR2 *
++ *------------------------------------------------------*/
++
++ ldr r0, PINMUX1_ADDR
++ ldr r1, PINMUX1_VAL
++ str r1, [r0]
++
++ ldr r0, PINMUX2_ADDR
++ ldr r1, PINMUX2_VAL
++ str r1, [r0]
++
++ ldr r0, PINMUX5_ADDR
++ ldr r1, PINMUX5_VAL
++ str r1, [r0]
++
++ ldr r0, PINMUX6_ADDR
++ ldr r1, PINMUX6_VAL
++ str r1, [r0]
++
++ ldr r8, PINMUX7_FLAG_CLEAR
++ ldr r7, PINMUX7_VAL
++ ldr r0, PINMUX7_ADDR
++ ldr r1, [r0]
++ and r1, r1, r8
++ orr r1, r1, r7
++ str r1, [r0]
++
++
++ /*------------------------------------------------------*
++ * Get the EMIF3 out of reset *
++ *------------------------------------------------------*/
++
++ /* Shut down the DDR2 LPSC Module */
++ ldr r8, PSC_FLAG_CLEAR
++ ldr r6, MDCTL_EMIF3
++ ldr r7, [r6]
++ and r7, r7, r8
++ orr r7, r7, $0x03
++ str r7, [r6]
++
++ /* Enable the Power Domain Transition Command */
++ ldr r6, PSC1_PTCMD_ADDR
++ ldr r7, [r6]
++ orr r7, r7, $0x01
++ str r7, [r6]
++
++ /* Check for Transition Complete(PTSTAT) */
++checkStatClkStop0:
++ ldr r6, PSC1_PTSTAT_ADDR
++ ldr r7, [r6]
++ ands r7, r7, $0x01
++ bne checkStatClkStop0
++
++ /* Check for DDR2 Controller Enable Completion */
++checkDDRStatClkStop0:
++ ldr r6, MDSTAT_EMIF3
++ ldr r7, [r6]
++ and r7, r7, $0x1f
++ cmp r7, $0x03
++ bne checkDDRStatClkStop0
++
++ /*------------------------------------------------------*
++ * Put the EMIF3 in reset *
++ *------------------------------------------------------*/
++
++ /* Shut down the DDR2 LPSC Module */
++ ldr r8, PSC_FLAG_CLEAR
++ ldr r6, MDCTL_EMIF3
++ ldr r7, [r6]
++ and r7, r7, r8
++ orr r7, r7, $0x01
++ str r7, [r6]
++
++ /* Enable the Power Domain Transition Command */
++ ldr r6, PSC1_PTCMD_ADDR
++ ldr r7, [r6]
++ orr r7, r7, $0x01
++ str r7, [r6]
++
++ /* Check for Transition Complete(PTSTAT) */
++checkStatClkStop1:
++ ldr r6, PSC1_PTSTAT_ADDR
++ ldr r7, [r6]
++ ands r7, r7, $0x01
++ bne checkStatClkStop1
++
++ /* Check for DDR2 Controller Enable Completion */
++checkDDRStatClkStop1:
++ ldr r6, MDSTAT_EMIF3
++ ldr r7, [r6]
++ and r7, r7, $0x1f
++ cmp r7, $0x01
++ bne checkDDRStatClkStop1
++
++ nop
++ nop
++
++ /*------------------------------------------------------*
++ * Get the EMIF3 out of reset *
++ *------------------------------------------------------*/
++
++ /* Shut down the DDR2 LPSC Module */
++ ldr r8, PSC_FLAG_CLEAR
++ ldr r6, MDCTL_EMIF3
++ ldr r7, [r6]
++ and r7, r7, r8
++ orr r7, r7, $0x03
++ str r7, [r6]
++
++ /* Enable the Power Domain Transition Command */
++ ldr r6, PSC1_PTCMD_ADDR
++ ldr r7, [r6]
++ orr r7, r7, $0x01
++ str r7, [r6]
++
++ /* Check for Transition Complete(PTSTAT) */
++checkStatClkStop2:
++ ldr r6, PSC1_PTSTAT_ADDR
++ ldr r7, [r6]
++ ands r7, r7, $0x01
++ bne checkStatClkStop2
++
++ /* Check for DDR2 Controller Enable Completion */
++checkDDRStatClkStop2:
++ ldr r6, MDSTAT_EMIF3
++ ldr r7, [r6]
++ and r7, r7, $0x1f
++ cmp r7, $0x03
++ bne checkDDRStatClkStop2
++
++ nop
++ nop
++
++ /*-----------------------------------------------------*
++ * Wait before programing the SDRAM timimg values *
++ *-----------------------------------------------------*/
++
++ ldr r10, EMIF3_TIMING_WAIT_VAL
++emif3TimingWait:
++ sub r10, r10, $0x1
++ cmp r10, $0x0
++ bne emif3TimingWait
++
++ /*------------------------------------------------------*
++ * Program EMIF3 MMRs for 133MHz SDRAM Setting *
++ *------------------------------------------------------*/
++
++ /* Program SDRAM Bank Config Register */
++ ldr r6, SDCFG
++ ldr r7, SDCFG_VAL
++ str r7, [r6]
++
++ /* Program SDRAM TIM-0 Config Register */
++ ldr r6, SDTIM0
++ ldr r7, SDTIM0_VAL_162MHz
++ str r7, [r6]
++
++ /* Program SDRAM TIM-1 Config Register */
++ ldr r6, SDTIM1
++ ldr r7, SDTIM1_VAL_162MHz
++ str r7, [r6]
++
++ /* Program the SDRAM Bank Config Control Register */
++ ldr r10, MASK_VAL
++ ldr r8, SDCFG
++ ldr r9, SDCFG_VAL
++ and r9, r9, r10
++ str r9, [r8]
++
++ /* Program SDRAM SDREF Config Register */
++ ldr r6, SDREF
++ ldr r7, SDREF_VAL
++ str r7, [r6]
++
++ /* Issue a Dummy DDR2 read/write */
++ ldr r8, DDR2_START_ADDR
++ ldr r7, DUMMY_VAL
++ str r7, [r8]
++ ldr r7, [r8]
++
++ /* DDR Writes and Reads */
++ ldr r6, CFGTEST
++ mov r3, $0x01
++ str r3, [r6]
++
++ nop
++ nop
++ nop
++ nop
++
++ /*
++ * Call board-specific lowlevel init.
++ * That MUST be present and THAT returns
++ * back to arch calling code with "mov pc, lr."
++ */
++ b dv_board_init
++
++.ltorg
++
++PINMUX1_ADDR:
++ .word PINMUX1
++PINMUX2_ADDR:
++ .word PINMUX2
++PINMUX5_ADDR:
++ .word PINMUX5
++PINMUX6_ADDR:
++ .word PINMUX6
++PINMUX7_ADDR:
++ .word PINMUX7
++PINMUX1_VAL:
++ .word 0x11111111
++PINMUX2_VAL:
++ .word 0x01111111
++PINMUX5_VAL:
++ .word 0x11111110
++PINMUX6_VAL:
++ .word 0x11111111
++PINMUX7_FLAG_CLEAR:
++ .word 0xFFFFF000
++PINMUX7_VAL:
++ .word 0x111
++
++
++MDCTL_EMIF3:
++ .word PSC1_MDCTL + 4 * 6
++MDSTAT_EMIF3:
++ .word PSC1_MDSTAT + 4 * 6
++
++PSC1_PTCMD_ADDR:
++ .word PSC1_PTCMD
++PSC1_PTSTAT_ADDR:
++ .word PSC1_PTSTAT
++
++INTC_GLB_EN_ADDR:
++ .word INTC_GLB_EN
++INTC_EN_CLR0_ADDR:
++ .word INTC_EN_CLR0
++INTC_HINT_EN_ADDR:
++ .word INTC_HINT_EN
++
++PSC_FLAG_CLEAR:
++ .word 0xffffffe0
++PSC_GEM_FLAG_CLEAR:
++ .word 0xfffffeff
++
++/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */
++SDREF:
++ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0xc
++SDREF_VAL:
++ .word 0x000005c3
++SDCFG:
++ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0x8
++SDCFG_VAL:
++#ifdef SDRAM_4BANKS_10COLS
++ .word 0x00178622
++#elif defined SDRAM_8BANKS_10COLS
++ .word 0x00178632
++#else
++#error "Unknown SDRAM configuration!!!"
++#endif
++SDTIM0:
++ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0x10
++SDTIM0_VAL_162MHz:
++ .word 0x28923211
++SDTIM1:
++ .word DAVINCI_DDR_EMIF_CTRL_BASE + 0x14
++SDTIM1_VAL_162MHz:
++ .word 0x0016c722
++CFGTEST:
++ .word DAVINCI_DDR_EMIF_DATA_BASE + 0x10000
++MASK_VAL:
++ .word 0x00000fff
++EMIF3_TIMING_WAIT_VAL:
++ .word 990000
++
++PLL_CLKSRC_MASK:
++ .word 0xfffffeff /* Mask the Clock Mode bit */
++PLL_ENSRC_MASK:
++ .word 0xffffffdf /* Select the PLLEN source */
++PLL_BYPASS_MASK:
++ .word 0xfffffffe /* Put the PLL in BYPASS */
++PLL_RESET_MASK:
++ .word 0xfffffff7 /* Put the PLL in Reset Mode */
++PLL_PWRUP_MASK:
++ .word 0xfffffffd /* PLL Power up Mask Bit */
++PLL_DISABLE_ENABLE_MASK:
++ .word 0xffffffef /* Enable the PLL from Disable */
++PLL_LOCK_COUNT:
++ .word 2000
++
++/* PLL0 MMRs */
++PLL0_PLLCTL_ADDR:
++ .word PLL0_PLLCTL
++PLL0_PLLM_ADDR:
++ .word PLL0_PLLM
++PLL0_POSTDIV_ADDR:
++ .word PLL0_POSTDIV
++
++DDR2_START_ADDR:
++ .word 0xc0000000
++DUMMY_VAL:
++ .word 0xa55aa55a
+Index: u-boot-2009.01/cpu/arm926ejs/da8xx/nand.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/cpu/arm926ejs/da8xx/nand.c
+@@ -0,0 +1,475 @@
++/*
++ * NAND driver for TI DaVinci based boards.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Based on Linux DaVinci NAND driver by TI. Original copyright follows:
++ */
++
++/*
++ *
++ * linux/drivers/mtd/nand/nand_davinci.c
++ *
++ * NAND Flash Driver
++ *
++ * Copyright (C) 2006 Texas Instruments.
++ *
++ * ----------------------------------------------------------------------------
++ *
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++ *
++ * Overview:
++ * This is a device driver for the NAND flash device found on the
++ * DaVinci board which utilizes the Samsung k9k2g08 part.
++ *
++ Modifications:
++ ver. 1.0: Feb 2005, Vinod/Sudhakar
++ -
++ *
++ */
++
++#include <common.h>
++#include <asm/io.h>
++
++#ifdef CONFIG_SYS_USE_NAND
++#if !defined(CONFIG_NAND_LEGACY)
++
++#include <nand.h>
++#include <asm/arch/nand_defs.h>
++#include <asm/arch/emif_defs.h>
++
++extern struct nand_chip nand_dev_desc[CONFIG_SYS_MAX_NAND_DEVICE];
++
++static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
++{
++ struct nand_chip *this = mtd->priv;
++ u_int32_t IO_ADDR_W = (u_int32_t)this->IO_ADDR_W;
++
++ IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
++
++ if (ctrl & NAND_CTRL_CHANGE) {
++ if ( ctrl & NAND_CLE )
++ IO_ADDR_W |= MASK_CLE;
++ if ( ctrl & NAND_ALE )
++ IO_ADDR_W |= MASK_ALE;
++ this->IO_ADDR_W = (void __iomem *) IO_ADDR_W;
++ }
++
++ if (cmd != NAND_CMD_NONE)
++ writeb(cmd, this->IO_ADDR_W);
++}
++
++/* Set WP on deselect, write enable on select */
++static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
++{
++#define GPIO_SET_DATA01 0x01c67018
++#define GPIO_CLR_DATA01 0x01c6701c
++#define GPIO_NAND_WP (1 << 4)
++#ifdef SONATA_BOARD_GPIOWP
++ if (chip < 0) {
++ REG(GPIO_CLR_DATA01) |= GPIO_NAND_WP;
++ } else {
++ REG(GPIO_SET_DATA01) |= GPIO_NAND_WP;
++ }
++#endif
++}
++
++#ifdef CONFIG_SYS_NAND_HW_ECC
++#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
++/* Linux-compatible ECC uses MTD defaults. */
++/* These layouts are not compatible with Linux or RBL/UBL. */
++#ifdef CONFIG_SYS_NAND_LARGEPAGE
++static struct nand_ecclayout davinci_nand_ecclayout = {
++ .eccbytes = 12,
++ .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58},
++ .oobfree = {
++ {.offset = 2, .length = 6},
++ {.offset = 12, .length = 12},
++ {.offset = 28, .length = 12},
++ {.offset = 44, .length = 12},
++ {.offset = 60, .length = 4}
++ }
++};
++#elif defined(CONFIG_SYS_NAND_SMALLPAGE)
++static struct nand_ecclayout davinci_nand_ecclayout = {
++ .eccbytes = 3,
++ .eccpos = {0, 1, 2},
++ .oobfree = {
++ {.offset = 6, .length = 2},
++ {.offset = 8, .length = 8}
++ }
++};
++#else
++#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!"
++#endif
++#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
++
++static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
++{
++ emifregs emif_addr;
++ int dummy;
++
++ emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
++
++ dummy = emif_addr->NANDF1ECC;
++ dummy = emif_addr->NANDF2ECC;
++ dummy = emif_addr->NANDF3ECC;
++ dummy = emif_addr->NANDF4ECC;
++
++ emif_addr->NANDFCR |= (1 << 8);
++}
++
++static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
++{
++ u_int32_t ecc = 0;
++ emifregs emif_base_addr;
++
++ emif_base_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
++
++ if (region == 1)
++ ecc = emif_base_addr->NANDF1ECC;
++ else if (region == 2)
++ ecc = emif_base_addr->NANDF2ECC;
++ else if (region == 3)
++ ecc = emif_base_addr->NANDF3ECC;
++ else if (region == 4)
++ ecc = emif_base_addr->NANDF4ECC;
++
++ return(ecc);
++}
++
++static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
++{
++ u_int32_t tmp;
++#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
++ /*
++ * This is not how you should read ECCs on large page Davinci devices.
++ * The region parameter gets you ECCs for flash chips on different chip
++ * selects, not the 4x512 byte pages in a 2048 byte page.
++ *
++ * Preserved for backwards compatibility though.
++ */
++
++ int region, n;
++ struct nand_chip *this = mtd->priv;
++
++ n = (this->ecc.size/512);
++
++ region = 1;
++ while (n--) {
++ tmp = nand_davinci_readecc(mtd, region);
++ *ecc_code++ = tmp;
++ *ecc_code++ = tmp >> 16;
++ *ecc_code++ = ((tmp >> 8) & 0x0f) | ((tmp >> 20) & 0xf0);
++ region++;
++ }
++#else
++ const int region = 1;
++
++ tmp = nand_davinci_readecc(mtd, region);
++
++ /* Squeeze 4 bytes ECC into 3 bytes by removing RESERVED bits
++ * and shifting. RESERVED bits are 31 to 28 and 15 to 12. */
++ tmp = (tmp & 0x00000fff) | ((tmp & 0x0fff0000) >> 4);
++
++ /* Invert so that erased block ECC is correct */
++ tmp = ~tmp;
++
++ *ecc_code++ = tmp;
++ *ecc_code++ = tmp >> 8;
++ *ecc_code++ = tmp >> 16;
++#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
++ return(0);
++}
++
++#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
++static void nand_davinci_gen_true_ecc(u_int8_t *ecc_buf)
++{
++ u_int32_t tmp = ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xf0) << 20) | ((ecc_buf[2] & 0x0f) << 8);
++
++ ecc_buf[0] = ~(P64o(tmp) | P64e(tmp) | P32o(tmp) | P32e(tmp) | P16o(tmp) | P16e(tmp) | P8o(tmp) | P8e(tmp));
++ ecc_buf[1] = ~(P1024o(tmp) | P1024e(tmp) | P512o(tmp) | P512e(tmp) | P256o(tmp) | P256e(tmp) | P128o(tmp) | P128e(tmp));
++ ecc_buf[2] = ~( P4o(tmp) | P4e(tmp) | P2o(tmp) | P2e(tmp) | P1o(tmp) | P1e(tmp) | P2048o(tmp) | P2048e(tmp));
++}
++
++static int nand_davinci_compare_ecc(u_int8_t *ecc_nand, u_int8_t *ecc_calc, u_int8_t *page_data)
++{
++ u_int32_t i;
++ u_int8_t tmp0_bit[8], tmp1_bit[8], tmp2_bit[8];
++ u_int8_t comp0_bit[8], comp1_bit[8], comp2_bit[8];
++ u_int8_t ecc_bit[24];
++ u_int8_t ecc_sum = 0;
++ u_int8_t find_bit = 0;
++ u_int32_t find_byte = 0;
++ int is_ecc_ff;
++
++ is_ecc_ff = ((*ecc_nand == 0xff) && (*(ecc_nand + 1) == 0xff) && (*(ecc_nand + 2) == 0xff));
++
++ nand_davinci_gen_true_ecc(ecc_nand);
++ nand_davinci_gen_true_ecc(ecc_calc);
++
++ for (i = 0; i <= 2; i++) {
++ *(ecc_nand + i) = ~(*(ecc_nand + i));
++ *(ecc_calc + i) = ~(*(ecc_calc + i));
++ }
++
++ for (i = 0; i < 8; i++) {
++ tmp0_bit[i] = *ecc_nand % 2;
++ *ecc_nand = *ecc_nand / 2;
++ }
++
++ for (i = 0; i < 8; i++) {
++ tmp1_bit[i] = *(ecc_nand + 1) % 2;
++ *(ecc_nand + 1) = *(ecc_nand + 1) / 2;
++ }
++
++ for (i = 0; i < 8; i++) {
++ tmp2_bit[i] = *(ecc_nand + 2) % 2;
++ *(ecc_nand + 2) = *(ecc_nand + 2) / 2;
++ }
++
++ for (i = 0; i < 8; i++) {
++ comp0_bit[i] = *ecc_calc % 2;
++ *ecc_calc = *ecc_calc / 2;
++ }
++
++ for (i = 0; i < 8; i++) {
++ comp1_bit[i] = *(ecc_calc + 1) % 2;
++ *(ecc_calc + 1) = *(ecc_calc + 1) / 2;
++ }
++
++ for (i = 0; i < 8; i++) {
++ comp2_bit[i] = *(ecc_calc + 2) % 2;
++ *(ecc_calc + 2) = *(ecc_calc + 2) / 2;
++ }
++
++ for (i = 0; i< 6; i++)
++ ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2];
++
++ for (i = 0; i < 8; i++)
++ ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i];
++
++ for (i = 0; i < 8; i++)
++ ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i];
++
++ ecc_bit[22] = tmp2_bit[0] ^ comp2_bit[0];
++ ecc_bit[23] = tmp2_bit[1] ^ comp2_bit[1];
++
++ for (i = 0; i < 24; i++)
++ ecc_sum += ecc_bit[i];
++
++ switch (ecc_sum) {
++ case 0:
++ /* Not reached because this function is not called if
++ ECC values are equal */
++ return 0;
++ case 1:
++ /* Uncorrectable error */
++ MTDDEBUG (MTD_DEBUG_LEVEL0,
++ "ECC UNCORRECTED_ERROR 1\n");
++ return(-1);
++ case 12:
++ /* Correctable error */
++ find_byte = (ecc_bit[23] << 8) +
++ (ecc_bit[21] << 7) +
++ (ecc_bit[19] << 6) +
++ (ecc_bit[17] << 5) +
++ (ecc_bit[15] << 4) +
++ (ecc_bit[13] << 3) +
++ (ecc_bit[11] << 2) +
++ (ecc_bit[9] << 1) +
++ ecc_bit[7];
++
++ find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
++
++ MTDDEBUG (MTD_DEBUG_LEVEL0, "Correcting single bit ECC "
++ "error at offset: %d, bit: %d\n",
++ find_byte, find_bit);
++
++ page_data[find_byte] ^= (1 << find_bit);
++
++ return(0);
++ default:
++ if (is_ecc_ff) {
++ if (ecc_calc[0] == 0 && ecc_calc[1] == 0 && ecc_calc[2] == 0)
++ return(0);
++ }
++ MTDDEBUG (MTD_DEBUG_LEVEL0,
++ "UNCORRECTED_ERROR default\n");
++ return(-1);
++ }
++}
++#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
++
++static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
++{
++ struct nand_chip *this = mtd->priv;
++#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
++ int block_count = 0, i, rc;
++
++ block_count = (this->ecc.size/512);
++ for (i = 0; i < block_count; i++) {
++ if (memcmp(read_ecc, calc_ecc, 3) != 0) {
++ rc = nand_davinci_compare_ecc(read_ecc, calc_ecc, dat);
++ if (rc < 0) {
++ return(rc);
++ }
++ }
++ read_ecc += 3;
++ calc_ecc += 3;
++ dat += 512;
++ }
++#else
++ u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) |
++ (read_ecc[2] << 16);
++ u_int32_t ecc_calc = calc_ecc[0] | (calc_ecc[1] << 8) |
++ (calc_ecc[2] << 16);
++ u_int32_t diff = ecc_calc ^ ecc_nand;
++
++ if (diff) {
++ if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
++ /* Correctable error */
++ if ((diff >> (12 + 3)) < this->ecc.size) {
++ uint8_t find_bit = 1 << ((diff >> 12) & 7);
++ uint32_t find_byte = diff >> (12 + 3);
++
++ dat[find_byte] ^= find_bit;
++ MTDDEBUG(MTD_DEBUG_LEVEL0, "Correcting single "
++ "bit ECC error at offset: %d, bit: "
++ "%d\n", find_byte, find_bit);
++ return 1;
++ } else {
++ return -1;
++ }
++ } else if (!(diff & (diff - 1))) {
++ /* Single bit ECC error in the ECC itself,
++ nothing to fix */
++ MTDDEBUG(MTD_DEBUG_LEVEL0, "Single bit ECC error in "
++ "ECC.\n");
++ return 1;
++ } else {
++ /* Uncorrectable error */
++ MTDDEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
++ return -1;
++ }
++ }
++#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
++ return(0);
++}
++#endif /* CONFIG_SYS_NAND_HW_ECC */
++
++static int nand_davinci_dev_ready(struct mtd_info *mtd)
++{
++ emifregs emif_addr;
++
++ emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
++
++ return(emif_addr->NANDFSR & 0x1);
++}
++
++static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
++{
++ while(!nand_davinci_dev_ready(mtd)) {;}
++ *NAND_CE0CLE = NAND_STATUS;
++ return(*NAND_CE0DATA);
++}
++
++static void nand_flash_init(void)
++{
++ u_int32_t acfg1 = 0x3ffffffc;
++ u_int32_t acfg2 = 0x3ffffffc;
++ u_int32_t acfg3 = 0x3ffffffc;
++ u_int32_t acfg4 = 0x3ffffffc;
++ emifregs emif_regs;
++
++ /*------------------------------------------------------------------*
++ * NAND FLASH CHIP TIMEOUT @ 459 MHz *
++ * *
++ * AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz *
++ * AEMIF.CLK period = 1/76.5 MHz = 13.1 ns *
++ * *
++ *------------------------------------------------------------------*/
++ acfg1 = 0
++ | (0 << 31 ) /* selectStrobe */
++ | (0 << 30 ) /* extWait */
++ | (1 << 26 ) /* writeSetup 10 ns */
++ | (3 << 20 ) /* writeStrobe 40 ns */
++ | (1 << 17 ) /* writeHold 10 ns */
++ | (1 << 13 ) /* readSetup 10 ns */
++ | (5 << 7 ) /* readStrobe 60 ns */
++ | (1 << 4 ) /* readHold 10 ns */
++ | (3 << 2 ) /* turnAround ?? ns */
++ | (0 << 0 ) /* asyncSize 8-bit bus */
++ ;
++
++ emif_regs = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
++
++ emif_regs->AWCCR |= 0x10000000;
++ emif_regs->AB1CR = acfg1; /* 0x08244128 */;
++ emif_regs->AB2CR = acfg2;
++ emif_regs->AB3CR = acfg3;
++ emif_regs->AB4CR = acfg4;
++ emif_regs->NANDFCR = 0x00000101;
++}
++
++int board_nand_init(struct nand_chip *nand)
++{
++ nand->IO_ADDR_R = (void __iomem *)NAND_CE0DATA;
++ nand->IO_ADDR_W = (void __iomem *)NAND_CE0DATA;
++ nand->chip_delay = 0;
++ nand->select_chip = nand_davinci_select_chip;
++#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
++ nand->options = NAND_USE_FLASH_BBT;
++#endif
++#ifdef CONFIG_SYS_NAND_HW_ECC
++ nand->ecc.mode = NAND_ECC_HW;
++#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
++ nand->ecc.layout = &davinci_nand_ecclayout;
++#ifdef CONFIG_SYS_NAND_LARGEPAGE
++ nand->ecc.size = 2048;
++ nand->ecc.bytes = 12;
++#elif defined(CONFIG_SYS_NAND_SMALLPAGE)
++ nand->ecc.size = 512;
++ nand->ecc.bytes = 3;
++#else
++#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!"
++#endif
++#else
++ nand->ecc.size = 512;
++ nand->ecc.bytes = 3;
++#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
++ nand->ecc.calculate = nand_davinci_calculate_ecc;
++ nand->ecc.correct = nand_davinci_correct_data;
++ nand->ecc.hwctl = nand_davinci_enable_hwecc;
++#else
++ nand->ecc.mode = NAND_ECC_SOFT;
++#endif /* CONFIG_SYS_NAND_HW_ECC */
++
++ /* Set address of hardware control function */
++ nand->cmd_ctrl = nand_davinci_hwcontrol;
++
++ nand->dev_ready = nand_davinci_dev_ready;
++ nand->waitfunc = nand_davinci_waitfunc;
++
++ nand_flash_init();
++
++ return(0);
++}
++
++#else
++#error "U-Boot legacy NAND support not available for DaVinci chips"
++#endif
++#endif /* CONFIG_SYS_USE_NAND */
+Index: u-boot-2009.01/cpu/arm926ejs/da8xx/reset.S
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/cpu/arm926ejs/da8xx/reset.S
+@@ -0,0 +1,77 @@
++/*
++ * Processor reset using WDT for TI TMS320DM644x SoC.
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * -----------------------------------------------------
++ *
++ * 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
++ */
++
++.globl reset_cpu
++reset_cpu:
++ ldr r0, WDT_TGCR
++ mov r1, $0x08
++ str r1, [r0]
++ ldr r1, [r0]
++ orr r1, r1, $0x03
++ str r1, [r0]
++ mov r1, $0
++ ldr r0, WDT_TIM12
++ str r1, [r0]
++ ldr r0, WDT_TIM34
++ str r1, [r0]
++ ldr r0, WDT_PRD12
++ str r1, [r0]
++ ldr r0, WDT_PRD34
++ str r1, [r0]
++ ldr r0, WDT_TCR
++ ldr r1, [r0]
++ orr r1, r1, $0x40
++ str r1, [r0]
++ ldr r0, WDT_WDTCR
++ ldr r1, [r0]
++ orr r1, r1, $0x4000
++ str r1, [r0]
++ ldr r1, WDTCR_VAL1
++ str r1, [r0]
++ ldr r1, WDTCR_VAL2
++ str r1, [r0]
++ nop
++ nop
++ nop
++ nop
++reset_cpu_loop:
++ b reset_cpu_loop
++
++WDT_TGCR:
++ .word 0x01c21c24
++WDT_TIM12:
++ .word 0x01c21c10
++WDT_TIM34:
++ .word 0x01c21c14
++WDT_PRD12:
++ .word 0x01c21c18
++WDT_PRD34:
++ .word 0x01c21c1c
++WDT_TCR:
++ .word 0x01c21c20
++WDT_WDTCR:
++ .word 0x01c21c28
++WDTCR_VAL1:
++ .word 0xa5c64000
++WDTCR_VAL2:
++ .word 0xda7e4000
+Index: u-boot-2009.01/cpu/arm926ejs/da8xx/timer.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/cpu/arm926ejs/da8xx/timer.c
+@@ -0,0 +1,148 @@
++/*
++ * (C) Copyright 2003
++ * Texas Instruments <www.ti.com>
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Alex Zuepke <azu@sysgo.de>
++ *
++ * (C) Copyright 2002-2004
++ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++ *
++ * (C) Copyright 2004
++ * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
++ *
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * 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 <arm926ejs.h>
++
++typedef volatile struct {
++ u_int32_t pid12;
++ u_int32_t emumgt;
++ u_int32_t na1;
++ u_int32_t na2;
++ u_int32_t tim12;
++ u_int32_t tim34;
++ u_int32_t prd12;
++ u_int32_t prd34;
++ u_int32_t tcr;
++ u_int32_t tgcr;
++ u_int32_t wdtcr;
++} davinci_timer;
++
++davinci_timer *timer = (davinci_timer *)CONFIG_SYS_TIMERBASE;
++
++#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)
++#define TIM_CLK_DIV 16
++
++static ulong timestamp;
++static ulong lastinc;
++
++int timer_init(void)
++{
++ /* We are using timer34 in unchained 32-bit mode, full speed */
++ timer->tcr = 0x0;
++ timer->tgcr = 0x0;
++ timer->tgcr = 0x06 | ((TIM_CLK_DIV - 1) << 8);
++ timer->tim34 = 0x0;
++ timer->prd34 = TIMER_LOAD_VAL;
++ lastinc = 0;
++ timestamp = 0;
++ timer->tcr = 2 << 22;
++
++ return(0);
++}
++
++void reset_timer(void)
++{
++ timer->tcr = 0x0;
++ timer->tim34 = 0;
++ lastinc = 0;
++ timestamp = 0;
++ timer->tcr = 2 << 22;
++}
++
++static ulong get_timer_raw(void)
++{
++ ulong now = timer->tim34;
++
++ if (now >= lastinc) {
++ /* normal mode */
++ timestamp += now - lastinc;
++ } else {
++ /* overflow ... */
++ timestamp += now + TIMER_LOAD_VAL - lastinc;
++ }
++ lastinc = now;
++ return timestamp;
++}
++
++ulong get_timer(ulong base)
++{
++ return((get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base);
++}
++
++void set_timer(ulong t)
++{
++ timestamp = t;
++}
++
++void udelay(unsigned long usec)
++{
++ ulong tmo;
++ ulong endtime;
++ signed long diff;
++
++ tmo = CONFIG_SYS_HZ_CLOCK / 1000;
++ tmo *= usec;
++ tmo /= (1000 * TIM_CLK_DIV);
++
++ endtime = get_timer_raw() + tmo;
++
++ do {
++ ulong now = get_timer_raw();
++ diff = endtime - now;
++ } while (diff >= 0);
++}
++
++/*
++ * 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_SYS_HZ;
++}
+Index: u-boot-2009.01/include/asm-arm/arch-da8xx/emac_defs.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/include/asm-arm/arch-da8xx/emac_defs.h
+@@ -0,0 +1,331 @@
++/*
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Based on:
++ *
++ * ----------------------------------------------------------------------------
++ *
++ * dm644x_emac.h
++ *
++ * TI DaVinci (DM644X) EMAC peripheral driver header for DV-EVM
++ *
++ * Copyright (C) 2005 Texas Instruments.
++ *
++ * ----------------------------------------------------------------------------
++ *
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++
++ * Modifications:
++ * ver. 1.0: Sep 2005, TI PSP Team - Created EMAC version for uBoot.
++ *
++ */
++
++#ifndef _DM644X_EMAC_H_
++#define _DM644X_EMAC_H_
++
++#include <asm/arch/hardware.h>
++
++#define EMAC_BASE_ADDR DAVINCI_EMAC_CNTRL_REGS_BASE
++#define EMAC_WRAPPER_BASE_ADDR DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE
++#define EMAC_WRAPPER_RAM_ADDR DAVINCI_EMAC_WRAPPER_RAM_BASE
++#define EMAC_MDIO_BASE_ADDR DAVINCI_MDIO_CNTRL_REGS_BASE
++
++/* MDIO module input frequency */
++#define EMAC_MDIO_BUS_FREQ clk_get(DAVINCI_MDIO_CLKID)
++
++/* MDIO clock output frequency */
++#define EMAC_MDIO_CLOCK_FREQ 2000000 /* 2.0 MHz */
++
++/* Ethernet Min/Max packet size */
++#define EMAC_MIN_ETHERNET_PKT_SIZE 60
++#define EMAC_MAX_ETHERNET_PKT_SIZE 1518
++#define EMAC_PKT_ALIGN 18 /* 1518 + 18 = 1536 (packet aligned on 32 byte boundry) */
++
++/* Number of RX packet buffers
++ * NOTE: Only 1 buffer supported as of now
++ */
++#define EMAC_MAX_RX_BUFFERS 10
++
++
++/***********************************************
++ ******** Internally used macros ***************
++ ***********************************************/
++
++#define EMAC_CH_TX 1
++#define EMAC_CH_RX 0
++
++/* Each descriptor occupies 4 words, lets start RX desc's at 0 and
++ * reserve space for 64 descriptors max
++ */
++#define EMAC_RX_DESC_BASE 0x0
++#define EMAC_TX_DESC_BASE 0x1000
++
++/* EMAC Teardown value */
++#define EMAC_TEARDOWN_VALUE 0xfffffffc
++
++/* MII Status Register */
++#define MII_STATUS_REG 1
++
++/* Number of statistics registers */
++#define EMAC_NUM_STATS 36
++
++
++/* EMAC Descriptor */
++typedef volatile struct _emac_desc
++{
++ u_int32_t next; /* Pointer to next descriptor in chain */
++ u_int8_t *buffer; /* Pointer to data buffer */
++ u_int32_t buff_off_len; /* Buffer Offset(MSW) and Length(LSW) */
++ u_int32_t pkt_flag_len; /* Packet Flags(MSW) and Length(LSW) */
++} emac_desc;
++
++/* CPPI bit positions */
++#define EMAC_CPPI_SOP_BIT (0x80000000)
++#define EMAC_CPPI_EOP_BIT (0x40000000)
++#define EMAC_CPPI_OWNERSHIP_BIT (0x20000000)
++#define EMAC_CPPI_EOQ_BIT (0x10000000)
++#define EMAC_CPPI_TEARDOWN_COMPLETE_BIT (0x08000000)
++#define EMAC_CPPI_PASS_CRC_BIT (0x04000000)
++
++#define EMAC_CPPI_RX_ERROR_FRAME (0x03fc0000)
++
++#define EMAC_MACCONTROL_RMIISPEED_100 (1 << 15)
++#define EMAC_MACCONTROL_MIIEN_ENABLE (0x20)
++#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE (0x1)
++
++#define EMAC_RXMBPENABLE_RXCAFEN_ENABLE (0x200000)
++#define EMAC_RXMBPENABLE_RXBROADEN (0x2000)
++
++
++#define MDIO_CONTROL_IDLE (0x80000000)
++#define MDIO_CONTROL_ENABLE (0x40000000)
++#define MDIO_CONTROL_FAULT_ENABLE (0x40000)
++#define MDIO_CONTROL_FAULT (0x80000)
++#define MDIO_USERACCESS0_GO (0x80000000)
++#define MDIO_USERACCESS0_WRITE_READ (0x0)
++#define MDIO_USERACCESS0_WRITE_WRITE (0x40000000)
++#define MDIO_USERACCESS0_ACK (0x20000000)
++
++/* Ethernet MAC Registers Structure */
++typedef struct {
++ dv_reg TXIDVER;
++ dv_reg TXCONTROL;
++ dv_reg TXTEARDOWN;
++ u_int8_t RSVD0[4];
++ dv_reg RXIDVER;
++ dv_reg RXCONTROL;
++ dv_reg RXTEARDOWN;
++ u_int8_t RSVD1[100];
++ dv_reg TXINTSTATRAW;
++ dv_reg TXINTSTATMASKED;
++ dv_reg TXINTMASKSET;
++ dv_reg TXINTMASKCLEAR;
++ dv_reg MACINVECTOR;
++ u_int8_t RSVD2[12];
++ dv_reg RXINTSTATRAW;
++ dv_reg RXINTSTATMASKED;
++ dv_reg RXINTMASKSET;
++ dv_reg RXINTMASKCLEAR;
++ dv_reg MACINTSTATRAW;
++ dv_reg MACINTSTATMASKED;
++ dv_reg MACINTMASKSET;
++ dv_reg MACINTMASKCLEAR;
++ u_int8_t RSVD3[64];
++ dv_reg RXMBPENABLE;
++ dv_reg RXUNICASTSET;
++ dv_reg RXUNICASTCLEAR;
++ dv_reg RXMAXLEN;
++ dv_reg RXBUFFEROFFSET;
++ dv_reg RXFILTERLOWTHRESH;
++ u_int8_t RSVD4[8];
++ dv_reg RX0FLOWTHRESH;
++ dv_reg RX1FLOWTHRESH;
++ dv_reg RX2FLOWTHRESH;
++ dv_reg RX3FLOWTHRESH;
++ dv_reg RX4FLOWTHRESH;
++ dv_reg RX5FLOWTHRESH;
++ dv_reg RX6FLOWTHRESH;
++ dv_reg RX7FLOWTHRESH;
++ dv_reg RX0FREEBUFFER;
++ dv_reg RX1FREEBUFFER;
++ dv_reg RX2FREEBUFFER;
++ dv_reg RX3FREEBUFFER;
++ dv_reg RX4FREEBUFFER;
++ dv_reg RX5FREEBUFFER;
++ dv_reg RX6FREEBUFFER;
++ dv_reg RX7FREEBUFFER;
++ dv_reg MACCONTROL;
++ dv_reg MACSTATUS;
++ dv_reg EMCONTROL;
++ dv_reg FIFOCONTROL;
++ dv_reg MACCONFIG;
++ dv_reg SOFTRESET;
++ u_int8_t RSVD5[88];
++ dv_reg MACSRCADDRLO;
++ dv_reg MACSRCADDRHI;
++ dv_reg MACHASH1;
++ dv_reg MACHASH2;
++ dv_reg BOFFTEST;
++ dv_reg TPACETEST;
++ dv_reg RXPAUSE;
++ dv_reg TXPAUSE;
++ u_int8_t RSVD6[16];
++ dv_reg RXGOODFRAMES;
++ dv_reg RXBCASTFRAMES;
++ dv_reg RXMCASTFRAMES;
++ dv_reg RXPAUSEFRAMES;
++ dv_reg RXCRCERRORS;
++ dv_reg RXALIGNCODEERRORS;
++ dv_reg RXOVERSIZED;
++ dv_reg RXJABBER;
++ dv_reg RXUNDERSIZED;
++ dv_reg RXFRAGMENTS;
++ dv_reg RXFILTERED;
++ dv_reg RXQOSFILTERED;
++ dv_reg RXOCTETS;
++ dv_reg TXGOODFRAMES;
++ dv_reg TXBCASTFRAMES;
++ dv_reg TXMCASTFRAMES;
++ dv_reg TXPAUSEFRAMES;
++ dv_reg TXDEFERRED;
++ dv_reg TXCOLLISION;
++ dv_reg TXSINGLECOLL;
++ dv_reg TXMULTICOLL;
++ dv_reg TXEXCESSIVECOLL;
++ dv_reg TXLATECOLL;
++ dv_reg TXUNDERRUN;
++ dv_reg TXCARRIERSENSE;
++ dv_reg TXOCTETS;
++ dv_reg FRAME64;
++ dv_reg FRAME65T127;
++ dv_reg FRAME128T255;
++ dv_reg FRAME256T511;
++ dv_reg FRAME512T1023;
++ dv_reg FRAME1024TUP;
++ dv_reg NETOCTETS;
++ dv_reg RXSOFOVERRUNS;
++ dv_reg RXMOFOVERRUNS;
++ dv_reg RXDMAOVERRUNS;
++ u_int8_t RSVD7[624];
++ dv_reg MACADDRLO;
++ dv_reg MACADDRHI;
++ dv_reg MACINDEX;
++ u_int8_t RSVD8[244];
++ dv_reg TX0HDP;
++ dv_reg TX1HDP;
++ dv_reg TX2HDP;
++ dv_reg TX3HDP;
++ dv_reg TX4HDP;
++ dv_reg TX5HDP;
++ dv_reg TX6HDP;
++ dv_reg TX7HDP;
++ dv_reg RX0HDP;
++ dv_reg RX1HDP;
++ dv_reg RX2HDP;
++ dv_reg RX3HDP;
++ dv_reg RX4HDP;
++ dv_reg RX5HDP;
++ dv_reg RX6HDP;
++ dv_reg RX7HDP;
++ dv_reg TX0CP;
++ dv_reg TX1CP;
++ dv_reg TX2CP;
++ dv_reg TX3CP;
++ dv_reg TX4CP;
++ dv_reg TX5CP;
++ dv_reg TX6CP;
++ dv_reg TX7CP;
++ dv_reg RX0CP;
++ dv_reg RX1CP;
++ dv_reg RX2CP;
++ dv_reg RX3CP;
++ dv_reg RX4CP;
++ dv_reg RX5CP;
++ dv_reg RX6CP;
++ dv_reg RX7CP;
++} emac_regs;
++
++/* EMAC Wrapper Registers Structure */
++typedef struct {
++ dv_reg REV;
++ dv_reg SOFTRESET;
++ dv_reg INTCONTROL;
++ dv_reg C0RXTHRESHEN;
++ dv_reg C0RXEN;
++ dv_reg C0TXEN;
++ dv_reg C0MISCEN;
++ dv_reg C1RXTHRESHEN;
++ dv_reg C1RXEN;
++ dv_reg C1TXEN;
++ dv_reg C1MISCEN;
++ dv_reg C2RXTHRESHEN;
++ dv_reg C2RXEN;
++ dv_reg C2TXEN;
++ dv_reg C2MISCEN;
++ dv_reg C0RXTHRESHSTAT;
++ dv_reg C0RXSTAT;
++ dv_reg C0TXSTAT;
++ dv_reg C0MISCSTAT;
++ dv_reg C1RXTHRESHSTAT;
++ dv_reg C1RXSTAT;
++ dv_reg C1TXSTAT;
++ dv_reg C1MISCSTAT;
++ dv_reg C2RXTHRESHSTAT;
++ dv_reg C2RXSTAT;
++ dv_reg C2TXSTAT;
++ dv_reg C2MISCSTAT;
++ dv_reg C0RXIMAX;
++ dv_reg C0TXIMAX;
++ dv_reg C1RXIMAX;
++ dv_reg C1TXIMAX;
++ dv_reg C2RXIMAX;
++ dv_reg C2TXIMAX;
++} ewrap_regs;
++
++
++/* EMAC MDIO Registers Structure */
++typedef struct {
++ dv_reg VERSION;
++ dv_reg CONTROL;
++ dv_reg ALIVE;
++ dv_reg LINK;
++ dv_reg LINKINTRAW;
++ dv_reg LINKINTMASKED;
++ u_int8_t RSVD0[8];
++ dv_reg USERINTRAW;
++ dv_reg USERINTMASKED;
++ dv_reg USERINTMASKSET;
++ dv_reg USERINTMASKCLEAR;
++ u_int8_t RSVD1[80];
++ dv_reg USERACCESS0;
++ dv_reg USERPHYSEL0;
++ dv_reg USERACCESS1;
++ dv_reg USERPHYSEL1;
++} mdio_regs;
++
++int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data);
++int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data);
++
++typedef struct
++{
++ char name[64];
++ int (*init)(int phy_addr);
++ int (*is_phy_connected)(int phy_addr);
++ int (*get_link_speed)(int phy_addr);
++ int (*auto_negotiate)(int phy_addr);
++} phy_t;
++
++#endif /* _DM644X_EMAC_H_ */
+Index: u-boot-2009.01/include/asm-arm/arch-da8xx/emif_defs.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/include/asm-arm/arch-da8xx/emif_defs.h
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * 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 _EMIF_DEFS_H_
++#define _EMIF_DEFS_H_
++
++#include <asm/arch/hardware.h>
++
++typedef struct {
++ dv_reg ERCSR;
++ dv_reg AWCCR;
++ dv_reg SDBCR;
++ dv_reg SDRCR;
++ dv_reg AB1CR;
++ dv_reg AB2CR;
++ dv_reg AB3CR;
++ dv_reg AB4CR;
++ dv_reg SDTIMR;
++ dv_reg DDRSR;
++ dv_reg DDRPHYCR;
++ dv_reg DDRPHYSR;
++ dv_reg TOTAR;
++ dv_reg TOTACTR;
++ dv_reg DDRPHYID_REV;
++ dv_reg SDSRETR;
++ dv_reg EIRR;
++ dv_reg EIMR;
++ dv_reg EIMSR;
++ dv_reg EIMCR;
++ dv_reg IOCTRLR;
++ dv_reg IOSTATR;
++ u_int8_t RSVD0[8];
++ dv_reg NANDFCR;
++ dv_reg NANDFSR;
++ u_int8_t RSVD1[8];
++ dv_reg NANDF1ECC;
++ dv_reg NANDF2ECC;
++ dv_reg NANDF3ECC;
++ dv_reg NANDF4ECC;
++} emif_registers;
++
++typedef emif_registers *emifregs;
++#endif
+Index: u-boot-2009.01/include/asm-arm/arch-da8xx/hardware.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/include/asm-arm/arch-da8xx/hardware.h
+@@ -0,0 +1,199 @@
++/*
++ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc
++ *
++ * Based on hardware.h for DaVinci. Original Copyrights follow.
++ *
++ * Sergey Kubushyn <ksi@koi8.net>
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Based on:
++ *
++ * -------------------------------------------------------------------------
++ *
++ * linux/include/asm-arm/arch-davinci/hardware.h
++ *
++ * Copyright (C) 2006 Texas Instruments.
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++#ifndef __ASM_ARCH_HARDWARE_H
++#define __ASM_ARCH_HARDWARE_H
++
++#include <config.h>
++
++#ifndef __ASSEMBLY__
++
++#include <asm/sizes.h>
++
++#define REG(addr) (*(volatile unsigned int *)(addr))
++#define REG_P(addr) ((volatile unsigned int *)(addr))
++
++typedef volatile unsigned int dv_reg;
++typedef volatile unsigned int * dv_reg_p;
++
++#endif
++
++/*
++ * Base register addresses
++ */
++#define DAVINCI_UART0_BASE (0x01c42000)
++#define DAVINCI_UART1_BASE (0x01d0c000)
++#define DAVINCI_UART2_BASE (0x01d0d000)
++#define DAVINCI_I2C0_BASE (0x01c22000)
++#define DAVINCI_I2C1_BASE (0x01e28000)
++#define DAVINCI_TIMER0_BASE (0x01c20000)
++#define DAVINCI_TIMER1_BASE (0x01c21000)
++#define DAVINCI_WDOG_BASE (0x01c21000)
++#define DAVINCI_PLL_CNTRL0_BASE (0x01c11000)
++#define DAVINCI_PSC0_BASE (0x01c10000)
++#define DAVINCI_PSC1_BASE (0x01e27000)
++#define DAVINCI_SPI0_BASE (0x01c41000)
++#define DAVINCI_SPI1_BASE (0x01e12000)
++#define DAVINCI_GPIO_BASE (0x01e26000)
++#define DAVINCI_EMAC_CNTRL_REGS_BASE (0x01e23000)
++#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE (0x01e22000)
++#define DAVINCI_EMAC_WRAPPER_RAM_BASE (0x01e20000)
++#define DAVINCI_MDIO_CNTRL_REGS_BASE (0x01e24000)
++#define DAVINCI_ASYNC_EMIF_CNTRL_BASE (0x68000000)
++#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x40000000)
++#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x60000000)
++#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x62000000)
++#define DAVINCI_ASYNC_EMIF_DATA_CE4_BASE (0x64000000)
++#define DAVINCI_ASYNC_EMIF_DATA_CE5_BASE (0x66000000)
++#define DAVINCI_DDR_EMIF_CTRL_BASE (0xb0000000)
++#define DAVINCI_DDR_EMIF_DATA_BASE (0xc0000000)
++#define DAVINCI_INTC_BASE (0xfffee000)
++#define DAVINCI_BOOTCFG_BASE (0x01c14000)
++
++/* Clock IDs */
++#define DAVINCI_PLLM_CLKID (0xFF + 0)
++#define DAVINCI_PLLC_CLKID (0xFF + 1)
++#define DAVINCI_AUXCLK_CLKID (0xFF + 2)
++#define DAVINCI_MDIO_CLKID 4
++#define DAVINCI_SPI0_CLKID 2
++#define DAVINCI_UART2_CLKID 2
++#define DAVINCI_ARM_CLKID 6
++
++/* Power and Sleep Controller (PSC) Domains */
++#define DAVINCI_GPSC_ARMDOMAIN 0
++#define DAVINCI_GPSC_DSPDOMAIN 1
++
++/* LPSCs in PSC0 */
++#define DAVINCI_LPSC_TPCC 0
++#define DAVINCI_LPSC_TPTC0 1
++#define DAVINCI_LPSC_TPTC1 2
++#define DAVINCI_LPSC_AEMIF 3
++#define DAVINCI_LPSC_SPI0 4
++#define DAVINCI_LPSC_MMC_SD 5
++#define DAVINCI_LPSC_AINTC 6
++#define DAVINCI_LPSC_ARM_RAM_ROM 7
++#define DAVINCI_LPSC_SECCTL_KEYMGR 8
++#define DAVINCI_LPSC_UART0 9
++#define DAVINCI_LPSC_SCR0 10
++#define DAVINCI_LPSC_SCR1 11
++#define DAVINCI_LPSC_SCR2 12
++#define DAVINCI_LPSC_DMAX 13
++#define DAVINCI_LPSC_ARM 14
++#define DAVINCI_LPSC_GEM 15
++
++/* for LPSCs in PSC1, 32 + actual id is being used for differentiation */
++#define DAVINCI_LPSC_USB11 (32 + 1)
++#define DAVINCI_LPSC_USB20 (32 + 2)
++#define DAVINCI_LPSC_GPIO (32 + 3)
++#define DAVINCI_LPSC_UHPI (32 + 4)
++#define DAVINCI_LPSC_EMAC (32 + 5)
++#define DAVINCI_LPSC_DDR_EMIF (32 + 6)
++#define DAVINCI_LPSC_McASP0 (32 + 7)
++#define DAVINCI_LPSC_McASP1 (32 + 8)
++#define DAVINCI_LPSC_McASP2 (32 + 9)
++#define DAVINCI_LPSC_SPI1 (32 + 10)
++#define DAVINCI_LPSC_I2C1 (32 + 11)
++#define DAVINCI_LPSC_UART1 (32 + 12)
++#define DAVINCI_LPSC_UART2 (32 + 13)
++#define DAVINCI_LPSC_LCDC (32 + 16)
++#define DAVINCI_LPSC_ePWM (32 + 17)
++#define DAVINCI_LPSC_eCAP (32 + 20)
++#define DAVINCI_LPSC_eQEP (32 + 21)
++#define DAVINCI_LPSC_SCR_P0 (32 + 22)
++#define DAVINCI_LPSC_SCR_P1 (32 + 23)
++#define DAVINCI_LPSC_CR_P3 (32 + 26)
++#define DAVINCI_LPSC_L3_CBA_RAM (32 + 31)
++
++/* Some PSC defines */
++
++#define PSC0_MDCTL (DAVINCI_PSC0_BASE + 0xa00)
++#define PSC0_MDSTAT (DAVINCI_PSC0_BASE + 0x800)
++#define PSC0_PTCMD (DAVINCI_PSC0_BASE + 0x120)
++#define PSC0_PTSTAT (DAVINCI_PSC0_BASE + 0x128)
++
++#define PSC1_MDCTL (DAVINCI_PSC1_BASE + 0xa00)
++#define PSC1_MDSTAT (DAVINCI_PSC1_BASE + 0x800)
++#define PSC1_PTCMD (DAVINCI_PSC1_BASE + 0x120)
++#define PSC1_PTSTAT (DAVINCI_PSC1_BASE + 0x128)
++
++/* Some PLL defines */
++#define PLL0_PLLCTL (DAVINCI_PLL_CNTRL0_BASE + 0x100)
++#define PLL0_PLLM (DAVINCI_PLL_CNTRL0_BASE + 0x110)
++#define PLL0_PREDIV (DAVINCI_PLL_CNTRL0_BASE + 0x114)
++#define PLL0_POSTDIV (DAVINCI_PLL_CNTRL0_BASE + 0x128)
++#define PLL0_DIV1 (DAVINCI_PLL_CNTRL0_BASE + 0x118)
++#define PLL0_DIV2 (DAVINCI_PLL_CNTRL0_BASE + 0x11c)
++#define PLL0_DIV3 (DAVINCI_PLL_CNTRL0_BASE + 0x120)
++#define PLL0_DIV4 (DAVINCI_PLL_CNTRL0_BASE + 0x160)
++#define PLL0_DIV5 (DAVINCI_PLL_CNTRL0_BASE + 0x164)
++#define PLL0_DIV6 (DAVINCI_PLL_CNTRL0_BASE + 0x168)
++#define PLL0_DIV7 (DAVINCI_PLL_CNTRL0_BASE + 0x16c)
++#define PLL0_DIV8 (DAVINCI_PLL_CNTRL0_BASE + 0x170)
++#define PLL0_DIV9 (DAVINCI_PLL_CNTRL0_BASE + 0x114)
++
++/* Boot config */
++#define KICK0 (DAVINCI_BOOTCFG_BASE + 0x38)
++#define KICK1 (DAVINCI_BOOTCFG_BASE + 0x3c)
++#define PINMUX0 (DAVINCI_BOOTCFG_BASE + 0x120)
++#define PINMUX1 (DAVINCI_BOOTCFG_BASE + 0x124)
++#define PINMUX2 (DAVINCI_BOOTCFG_BASE + 0x128)
++#define PINMUX3 (DAVINCI_BOOTCFG_BASE + 0x12c)
++#define PINMUX4 (DAVINCI_BOOTCFG_BASE + 0x130)
++#define PINMUX5 (DAVINCI_BOOTCFG_BASE + 0x134)
++#define PINMUX6 (DAVINCI_BOOTCFG_BASE + 0x138)
++#define PINMUX7 (DAVINCI_BOOTCFG_BASE + 0x13c)
++#define PINMUX8 (DAVINCI_BOOTCFG_BASE + 0x140)
++#define PINMUX9 (DAVINCI_BOOTCFG_BASE + 0x144)
++#define PINMUX10 (DAVINCI_BOOTCFG_BASE + 0x148)
++#define PINMUX11 (DAVINCI_BOOTCFG_BASE + 0x14c)
++#define PINMUX12 (DAVINCI_BOOTCFG_BASE + 0x150)
++#define PINMUX13 (DAVINCI_BOOTCFG_BASE + 0x154)
++#define PINMUX14 (DAVINCI_BOOTCFG_BASE + 0x158)
++#define PINMUX15 (DAVINCI_BOOTCFG_BASE + 0x15C)
++#define PINMUX16 (DAVINCI_BOOTCFG_BASE + 0x160)
++#define PINMUX17 (DAVINCI_BOOTCFG_BASE + 0x164)
++#define PINMUX18 (DAVINCI_BOOTCFG_BASE + 0x168)
++#define PINMUX19 (DAVINCI_BOOTCFG_BASE + 0x16c)
++#define SUSPSRC (DAVINCI_BOOTCFG_BASE + 0x170)
++#define CFGCHIP0 (DAVINCI_BOOTCFG_BASE + 0x17c)
++
++/* Interrupt controller */
++#define INTC_GLB_EN (DAVINCI_INTC_BASE + 0x10)
++#define INTC_HINT_EN (DAVINCI_INTC_BASE + 0x1500)
++#define INTC_EN_CLR0 (DAVINCI_INTC_BASE + 0x380)
++
++#endif /* __ASM_ARCH_HARDWARE_H */
+Index: u-boot-2009.01/include/asm-arm/arch-da8xx/i2c_defs.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/include/asm-arm/arch-da8xx/i2c_defs.h
+@@ -0,0 +1,95 @@
++/*
++ * (C) Copyright 2004
++ * Texas Instruments, <www.ti.com>
++ *
++ * Some changes copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * 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 _DAVINCI_I2C_H_
++#define _DAVINCI_I2C_H_
++
++#define I2C_WRITE 0
++#define I2C_READ 1
++
++#define I2C_BASE 0x01c22000
++
++#define I2C_OA (I2C_BASE + 0x00)
++#define I2C_IE (I2C_BASE + 0x04)
++#define I2C_STAT (I2C_BASE + 0x08)
++#define I2C_SCLL (I2C_BASE + 0x0c)
++#define I2C_SCLH (I2C_BASE + 0x10)
++#define I2C_CNT (I2C_BASE + 0x14)
++#define I2C_DRR (I2C_BASE + 0x18)
++#define I2C_SA (I2C_BASE + 0x1c)
++#define I2C_DXR (I2C_BASE + 0x20)
++#define I2C_CON (I2C_BASE + 0x24)
++#define I2C_IV (I2C_BASE + 0x28)
++#define I2C_PSC (I2C_BASE + 0x30)
++
++/* I2C masks */
++
++/* I2C Interrupt Enable Register (I2C_IE): */
++#define I2C_IE_SCD_IE (1 << 5) /* Stop condition detect interrupt enable */
++#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */
++#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */
++#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */
++#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */
++#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */
++
++/* I2C Status Register (I2C_STAT): */
++
++#define I2C_STAT_BB (1 << 12) /* Bus busy */
++#define I2C_STAT_ROVR (1 << 11) /* Receive overrun */
++#define I2C_STAT_XUDF (1 << 10) /* Transmit underflow */
++#define I2C_STAT_AAS (1 << 9) /* Address as slave */
++#define I2C_STAT_SCD (1 << 5) /* Stop condition detect */
++#define I2C_STAT_XRDY (1 << 4) /* Transmit data ready */
++#define I2C_STAT_RRDY (1 << 3) /* Receive data ready */
++#define I2C_STAT_ARDY (1 << 2) /* Register access ready */
++#define I2C_STAT_NACK (1 << 1) /* No acknowledgment interrupt enable */
++#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */
++
++
++/* I2C Interrupt Code Register (I2C_INTCODE): */
++
++#define I2C_INTCODE_MASK 7
++#define I2C_INTCODE_NONE 0
++#define I2C_INTCODE_AL 1 /* Arbitration lost */
++#define I2C_INTCODE_NAK 2 /* No acknowledgement/general call */
++#define I2C_INTCODE_ARDY 3 /* Register access ready */
++#define I2C_INTCODE_RRDY 4 /* Rcv data ready */
++#define I2C_INTCODE_XRDY 5 /* Xmit data ready */
++#define I2C_INTCODE_SCD 6 /* Stop condition detect */
++
++
++/* I2C Configuration Register (I2C_CON): */
++
++#define I2C_CON_EN (1 << 5) /* I2C module enable */
++#define I2C_CON_STB (1 << 4) /* Start byte mode (master mode only) */
++#define I2C_CON_MST (1 << 10) /* Master/slave mode */
++#define I2C_CON_TRX (1 << 9) /* Transmitter/receiver mode (master mode only) */
++#define I2C_CON_XA (1 << 8) /* Expand address */
++#define I2C_CON_STP (1 << 11) /* Stop condition (master mode only) */
++#define I2C_CON_STT (1 << 13) /* Start condition (master mode only) */
++#define I2C_CON_FREE (1 << 14) /* Free run on emulation */
++
++#define I2C_TIMEOUT 0xffff0000 /* Timeout mask for poll_i2c_irq() */
++
++#endif
+Index: u-boot-2009.01/include/asm-arm/arch-da8xx/nand_defs.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/include/asm-arm/arch-da8xx/nand_defs.h
+@@ -0,0 +1,164 @@
++/*
++ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
++ *
++ * Parts shamelesly stolen from Linux Kernel source tree.
++ *
++ * ------------------------------------------------------------
++ *
++ * 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 _NAND_DEFS_H_
++#define _NAND_DEFS_H_
++
++#include <asm/arch/hardware.h>
++
++#define MASK_CLE 0x10
++//#define MASK_ALE 0x0a
++#define MASK_ALE 0x08
++
++
++#define NAND_CE0CLE ((volatile u_int8_t *)(CONFIG_SYS_NAND_BASE + 0x10))
++//#define NAND_CE0ALE ((volatile u_int8_t *)(CFG_NAND_BASE + 0x0a))
++#define NAND_CE0ALE ((volatile u_int8_t *)(CONFIG_SYS_NAND_BASE + 0x08))
++#define NAND_CE0DATA ((volatile u_int8_t *)CONFIG_SYS_NAND_BASE)
++
++typedef struct {
++ u_int32_t NRCSR;
++ u_int32_t AWCCR;
++ u_int8_t RSVD0[8];
++ u_int32_t AB1CR;
++ u_int32_t AB2CR;
++ u_int32_t AB3CR;
++ u_int32_t AB4CR;
++ u_int8_t RSVD1[32];
++ u_int32_t NIRR;
++ u_int32_t NIMR;
++ u_int32_t NIMSR;
++ u_int32_t NIMCR;
++ u_int8_t RSVD2[16];
++ u_int32_t NANDFCR;
++ u_int32_t NANDFSR;
++ u_int8_t RSVD3[8];
++ u_int32_t NANDF1ECC;
++ u_int32_t NANDF2ECC;
++ u_int32_t NANDF3ECC;
++ u_int32_t NANDF4ECC;
++ u_int8_t RSVD4[4];
++ u_int32_t IODFTECR;
++ u_int32_t IODFTGCR;
++ u_int8_t RSVD5[4];
++ u_int32_t IODFTMRLR;
++ u_int32_t IODFTMRMR;
++ u_int32_t IODFTMRMSBR;
++ u_int8_t RSVD6[20];
++ u_int32_t MODRNR;
++ u_int8_t RSVD7[76];
++ u_int32_t CE0DATA;
++ u_int32_t CE0ALE;
++ u_int32_t CE0CLE;
++ u_int8_t RSVD8[4];
++ u_int32_t CE1DATA;
++ u_int32_t CE1ALE;
++ u_int32_t CE1CLE;
++ u_int8_t RSVD9[4];
++ u_int32_t CE2DATA;
++ u_int32_t CE2ALE;
++ u_int32_t CE2CLE;
++ u_int8_t RSVD10[4];
++ u_int32_t CE3DATA;
++ u_int32_t CE3ALE;
++ u_int32_t CE3CLE;
++} nand_registers;
++
++typedef volatile nand_registers *nandregs;
++
++#define NAND_READ_START 0x00
++#define NAND_READ_END 0x30
++#define NAND_STATUS 0x70
++
++#ifdef CFG_NAND_HW_ECC
++#define NAND_Ecc_P1e (1 << 0)
++#define NAND_Ecc_P2e (1 << 1)
++#define NAND_Ecc_P4e (1 << 2)
++#define NAND_Ecc_P8e (1 << 3)
++#define NAND_Ecc_P16e (1 << 4)
++#define NAND_Ecc_P32e (1 << 5)
++#define NAND_Ecc_P64e (1 << 6)
++#define NAND_Ecc_P128e (1 << 7)
++#define NAND_Ecc_P256e (1 << 8)
++#define NAND_Ecc_P512e (1 << 9)
++#define NAND_Ecc_P1024e (1 << 10)
++#define NAND_Ecc_P2048e (1 << 11)
++
++#define NAND_Ecc_P1o (1 << 16)
++#define NAND_Ecc_P2o (1 << 17)
++#define NAND_Ecc_P4o (1 << 18)
++#define NAND_Ecc_P8o (1 << 19)
++#define NAND_Ecc_P16o (1 << 20)
++#define NAND_Ecc_P32o (1 << 21)
++#define NAND_Ecc_P64o (1 << 22)
++#define NAND_Ecc_P128o (1 << 23)
++#define NAND_Ecc_P256o (1 << 24)
++#define NAND_Ecc_P512o (1 << 25)
++#define NAND_Ecc_P1024o (1 << 26)
++#define NAND_Ecc_P2048o (1 << 27)
++
++#define TF(v) (v ? 1 : 0)
++
++#define P2048e(a) (TF(a & NAND_Ecc_P2048e) << 0)
++#define P2048o(a) (TF(a & NAND_Ecc_P2048o) << 1)
++#define P1e(a) (TF(a & NAND_Ecc_P1e) << 2)
++#define P1o(a) (TF(a & NAND_Ecc_P1o) << 3)
++#define P2e(a) (TF(a & NAND_Ecc_P2e) << 4)
++#define P2o(a) (TF(a & NAND_Ecc_P2o) << 5)
++#define P4e(a) (TF(a & NAND_Ecc_P4e) << 6)
++#define P4o(a) (TF(a & NAND_Ecc_P4o) << 7)
++
++#define P8e(a) (TF(a & NAND_Ecc_P8e) << 0)
++#define P8o(a) (TF(a & NAND_Ecc_P8o) << 1)
++#define P16e(a) (TF(a & NAND_Ecc_P16e) << 2)
++#define P16o(a) (TF(a & NAND_Ecc_P16o) << 3)
++#define P32e(a) (TF(a & NAND_Ecc_P32e) << 4)
++#define P32o(a) (TF(a & NAND_Ecc_P32o) << 5)
++#define P64e(a) (TF(a & NAND_Ecc_P64e) << 6)
++#define P64o(a) (TF(a & NAND_Ecc_P64o) << 7)
++
++#define P128e(a) (TF(a & NAND_Ecc_P128e) << 0)
++#define P128o(a) (TF(a & NAND_Ecc_P128o) << 1)
++#define P256e(a) (TF(a & NAND_Ecc_P256e) << 2)
++#define P256o(a) (TF(a & NAND_Ecc_P256o) << 3)
++#define P512e(a) (TF(a & NAND_Ecc_P512e) << 4)
++#define P512o(a) (TF(a & NAND_Ecc_P512o) << 5)
++#define P1024e(a) (TF(a & NAND_Ecc_P1024e) << 6)
++#define P1024o(a) (TF(a & NAND_Ecc_P1024o) << 7)
++
++#define P8e_s(a) (TF(a & NAND_Ecc_P8e) << 0)
++#define P8o_s(a) (TF(a & NAND_Ecc_P8o) << 1)
++#define P16e_s(a) (TF(a & NAND_Ecc_P16e) << 2)
++#define P16o_s(a) (TF(a & NAND_Ecc_P16o) << 3)
++#define P1e_s(a) (TF(a & NAND_Ecc_P1e) << 4)
++#define P1o_s(a) (TF(a & NAND_Ecc_P1o) << 5)
++#define P2e_s(a) (TF(a & NAND_Ecc_P2e) << 6)
++#define P2o_s(a) (TF(a & NAND_Ecc_P2o) << 7)
++
++#define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0)
++#define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1)
++#endif
++
++#endif
+Index: u-boot-2009.01/Makefile
+===================================================================
+--- u-boot-2009.01.orig/Makefile
++++ u-boot-2009.01/Makefile
+@@ -151,7 +151,8 @@ ifeq ($(ARCH),ppc)
+ CROSS_COMPILE = ppc_8xx-
+ endif
+ ifeq ($(ARCH),arm)
+-CROSS_COMPILE = arm-linux-
++#CROSS_COMPILE = arm-linux-
++CROSS_COMPILE = arm-none-linux-gnueabi-
+ endif
+ ifeq ($(ARCH),i386)
+ CROSS_COMPILE = i386-linux-
+@@ -2715,6 +2716,9 @@ davinci_sffsdr_config : unconfig
+ davinci_sonata_config : unconfig
+ @$(MKCONFIG) $(@:_config=) arm arm926ejs sonata davinci davinci
+
++da8xx_evm_config : unconfig
++ @$(MKCONFIG) $(@:_config=) arm arm926ejs da8xx-evm da8xx da8xx
++
+ lpd7a400_config \
+ lpd7a404_config: unconfig
+ @$(MKCONFIG) $(@:_config=) arm lh7a40x lpd7a40x
+Index: u-boot-2009.01/lib_arm/board.c
+===================================================================
+--- u-boot-2009.01.orig/lib_arm/board.c
++++ u-boot-2009.01/lib_arm/board.c
+@@ -416,9 +416,9 @@ void start_armboot (void)
+
+ /* Perform network card initialisation if necessary */
+ #ifdef CONFIG_DRIVER_TI_EMAC
+-extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
++extern void dm644x_eth_set_mac_addr (const u_int8_t *addr);
+ if (getenv ("ethaddr")) {
+- davinci_eth_set_mac_addr(gd->bd->bi_enetaddr);
++ dm644x_eth_set_mac_addr(gd->bd->bi_enetaddr);
+ }
+ #endif
+
+Index: u-boot-2009.01/drivers/mtd/spi/winbond.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/drivers/mtd/spi/winbond.c
+@@ -0,0 +1,338 @@
++/*
++ * Copyright 2008, Network Appliance Inc.
++ * Author: Jason McMullan <[EMAIL PROTECTED]>
++ *
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <spi_flash.h>
++
++#include "spi_flash_internal.h"
++
++/* M25Pxx-specific commands */
++#define CMD_W25_WREN 0x06 /* Write Enable */
++#define CMD_W25_WRDI 0x04 /* Write Disable */
++#define CMD_W25_RDSR 0x05 /* Read Status Register */
++#define CMD_W25_WRSR 0x01 /* Write Status Register */
++#define CMD_W25_READ 0x03 /* Read Data Bytes */
++#define CMD_W25_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */
++#define CMD_W25_PP 0x02 /* Page Program */
++#define CMD_W25_SE 0x20 /* Sector (4K) Erase */
++#define CMD_W25_BE 0xd8 /* Block (64K) Erase */
++#define CMD_W25_CE 0xc7 /* Chip Erase */
++#define CMD_W25_DP 0xb9 /* Deep Power-down */
++#define CMD_W25_RES 0xab /* Release from DP, and Read Signature */
++
++#define WINBOND_ID_W25X16 0x3015
++#define WINBOND_ID_W25X32 0x3016
++#define WINBOND_ID_W25X64 0x3017
++
++#define WINBOND_SR_WIP (1 << 0) /* Write-in-Progress */
++
++struct winbond_spi_flash_params {
++ uint16_t id;
++ /* Log2 of page size in power-of-two mode */
++ uint8_t l2_page_size;
++ uint16_t pages_per_sector;
++ uint16_t sectors_per_block;
++ uint8_t nr_blocks;
++ const char *name;
++};
++
++struct winbond_spi_flash {
++ const struct winbond_spi_flash_params *params;
++ struct spi_flash flash;
++};
++
++static inline struct winbond_spi_flash *
++to_winbond_spi_flash(struct spi_flash *flash)
++{
++ return container_of(flash, struct winbond_spi_flash, flash);
++}
++
++static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
++ {
++ .id = WINBOND_ID_W25X16,
++ .l2_page_size = 8,
++ .pages_per_sector = 16,
++ .sectors_per_block = 16,
++ .nr_blocks = 32,
++ .name = "W25X16",
++ },
++ {
++ .id = WINBOND_ID_W25X32,
++ .l2_page_size = 8,
++ .pages_per_sector = 16,
++ .sectors_per_block = 16,
++ .nr_blocks = 64,
++ .name = "W25X32",
++ },
++ {
++ .id = WINBOND_ID_W25X64,
++ .l2_page_size = 8,
++ .pages_per_sector = 16,
++ .sectors_per_block = 16,
++ .nr_blocks = 128,
++ .name = "W25X64",
++ },
++};
++
++static int wait_state;
++
++static int winbond_wait_ready(struct spi_flash *flash, unsigned long timeout)
++{
++ struct spi_slave *spi = flash->spi;
++ unsigned long timebase;
++ int ret;
++ u8 status;
++ u8 cmd[4] = { CMD_W25_RDSR, 0xff, 0xff, 0xff };
++
++ ret = spi_xfer(spi, 32, &cmd[0], NULL, SPI_XFER_BEGIN);
++ if (ret) {
++ debug("SF: Failed to send command %02x: %d\n", cmd, ret);
++ return ret;
++ }
++
++ timebase = get_timer(0);
++ do {
++ ret = spi_xfer(spi, 8, NULL, &status, 0);
++ if (ret) {
++ debug("SF: Failed to get status for cmd %02x: %d\n", cmd, ret);
++ return -1;
++ }
++
++ if ((status & WINBOND_SR_WIP) == 0)
++ break;
++ else if ((status & WINBOND_SR_WIP) == 1)
++ wait_state++;
++
++ } while (1 || (get_timer(timebase) < timeout));
++
++ spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
++
++ if ((status & WINBOND_SR_WIP) == 0)
++ return 0;
++
++ debug("SF: Timed out on command %02x: %d\n", cmd, ret);
++ /* Timed out */
++ return -1;
++}
++
++/*
++ * Assemble the address part of a command for Winbond devices in
++ * non-power-of-two page size mode.
++ */
++static void winbond_build_address(struct winbond_spi_flash *stm, u8 *cmd, u32 offset)
++{
++ unsigned long page_addr;
++ unsigned long byte_addr;
++ unsigned long page_size;
++ unsigned int page_shift;
++
++ /*
++ * The "extra" space per page is the power-of-two page size
++ * divided by 32.
++ */
++ page_shift = stm->params->l2_page_size;
++ page_size = (1 << page_shift);
++ page_addr = offset / page_size;
++ byte_addr = offset % page_size;
++
++ cmd[0] = page_addr >> (16 - page_shift);
++ cmd[1] = page_addr << (page_shift - 8) | (byte_addr >> 8);
++ cmd[2] = byte_addr;
++}
++
++static int winbond_read_fast(struct spi_flash *flash,
++ u32 offset, size_t len, void *buf)
++{
++ struct winbond_spi_flash *stm = to_winbond_spi_flash(flash);
++ u8 cmd[5];
++
++ cmd[0] = CMD_READ_ARRAY_FAST;
++ winbond_build_address(stm, cmd + 1, offset);
++ cmd[4] = 0x00;
++
++ return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len);
++}
++
++static int winbond_write(struct spi_flash *flash,
++ u32 offset, size_t len, const void *buf)
++{
++ struct winbond_spi_flash *stm = to_winbond_spi_flash(flash);
++ unsigned long page_addr;
++ unsigned long byte_addr;
++ unsigned long page_size;
++ unsigned int page_shift;
++ size_t chunk_len;
++ size_t actual;
++ int ret;
++ u8 cmd[4];
++
++ page_shift = stm->params->l2_page_size;
++ page_size = (1 << page_shift);
++ page_addr = offset / page_size;
++ byte_addr = offset % page_size;
++
++ ret = spi_claim_bus(flash->spi);
++ if (ret) {
++ debug("SF: Unable to claim SPI bus\n");
++ return ret;
++ }
++
++ for (actual = 0; actual < len; actual += chunk_len) {
++ chunk_len = min(len - actual, page_size - byte_addr);
++
++ cmd[0] = CMD_W25_PP;
++ cmd[1] = page_addr >> (16 - page_shift);
++ cmd[2] = page_addr << (page_shift - 8) | (byte_addr >> 8);
++ cmd[3] = byte_addr;
++ debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %d\n",
++ buf + actual,
++ cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
++
++ ret = spi_flash_cmd(flash->spi, CMD_W25_WREN, NULL, 0);
++ if (ret < 0) {
++ debug("SF: Enabling Write failed\n");
++ goto out;
++ }
++
++ ret = spi_flash_cmd_write(flash->spi, cmd, 4,
++ buf + actual, chunk_len);
++ if (ret < 0) {
++ debug("SF: Winbond Page Program failed\n");
++ goto out;
++ }
++
++ ret = winbond_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
++ if (ret < 0) {
++ debug("SF: Winbond page programming timed out\n");
++ goto out;
++ }
++
++ page_addr++;
++ byte_addr = 0;
++ }
++
++ printf("Number of times wait: %d\n", wait_state);
++ wait_state = 0;
++
++ debug("SF: Winbond: Successfully programmed %u bytes @ 0x%x\n",
++ len, offset);
++ ret = 0;
++
++out:
++ spi_release_bus(flash->spi);
++ return ret;
++}
++
++int winbond_erase(struct spi_flash *flash, u32 offset, size_t len)
++{
++ struct winbond_spi_flash *stm = to_winbond_spi_flash(flash);
++ unsigned long sector_size;
++ unsigned int page_shift;
++ size_t actual;
++ int ret;
++ u8 cmd[4];
++
++ /*
++ * This function currently uses sector erase only.
++ * probably speed things up by using bulk erase
++ * when possible.
++ */
++
++ page_shift = stm->params->l2_page_size;
++ sector_size = (1 << page_shift) * stm->params->pages_per_sector;
++
++ if (offset % sector_size || len % sector_size) {
++ debug("SF: Erase offset/length not multiple of sector size\n");
++ return -1;
++ }
++
++ len /= sector_size;
++ cmd[0] = CMD_W25_SE;
++
++ ret = spi_claim_bus(flash->spi);
++ if (ret) {
++ debug("SF: Unable to claim SPI bus\n");
++ return ret;
++ }
++
++ for (actual = 0; actual < len; actual++) {
++ winbond_build_address(stm, &cmd[1], offset + actual * sector_size);
++ printf("Erase: %02x %02x %02x %02x\n",
++ cmd[0], cmd[1], cmd[2], cmd[3]);
++
++ ret = spi_flash_cmd(flash->spi, CMD_W25_WREN, NULL, 0);
++ if (ret < 0) {
++ debug("SF: Enabling Write failed\n");
++ goto out;
++ }
++
++ ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
++ if (ret < 0) {
++ debug("SF: Winbond sector erase failed\n");
++ goto out;
++ }
++
++ ret = winbond_wait_ready(flash, 2 * CONFIG_SYS_HZ); /* Up to 2 seconds */
++ if (ret < 0) {
++ debug("SF: Winbond sector erase timed out\n");
++ goto out;
++ }
++ }
++
++ debug("SF: Winbond: Successfully erased %u bytes @ 0x%x\n",
++ len * sector_size, offset);
++ ret = 0;
++
++out:
++ spi_release_bus(flash->spi);
++ return ret;
++}
++
++struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
++{
++ const struct winbond_spi_flash_params *params;
++ unsigned long page_size;
++ struct winbond_spi_flash *stm;
++ unsigned int i;
++
++ for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) {
++ params = &winbond_spi_flash_table[i];
++ if (params->id == ((idcode[1] << 8) | idcode[2]))
++ break;
++ }
++
++ if (i == ARRAY_SIZE(winbond_spi_flash_table)) {
++ debug("SF: Unsupported Winbond ID %02x%02x\n",
++ idcode[1], idcode[2]);
++ return NULL;
++ }
++
++ stm = malloc(sizeof(struct winbond_spi_flash));
++ if (!stm) {
++ debug("SF: Failed to allocate memory\n");
++ return NULL;
++ }
++
++ stm->params = params;
++ stm->flash.spi = spi;
++ stm->flash.name = params->name;
++
++ /* Assuming power-of-two page size initially. */
++ page_size = 1 << params->l2_page_size;
++
++ stm->flash.write = winbond_write;
++ stm->flash.erase = winbond_erase;
++ stm->flash.read = winbond_read_fast;
++ stm->flash.size = page_size * params->pages_per_sector
++ * params->sectors_per_block
++ * params->nr_blocks;
++
++ debug("SF: Detected %s with page size %u, total %u bytes\n",
++ params->name, page_size, stm->flash.size);
++
++ return &stm->flash;
++}
+Index: u-boot-2009.01/drivers/spi/davinci_spi.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/drivers/spi/davinci_spi.c
+@@ -0,0 +1,284 @@
++/*
++ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc <www.ti.com>
++ *
++ * Driver for SPI controller on DaVinci. Based on atmel_spi.c
++ * by Atmel Corporation
++ *
++ * Copyright (C) 2007 Atmel Corporation
++ *
++ * 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 <spi.h>
++#include <malloc.h>
++
++#include <asm/io.h>
++
++#include <asm/arch/hardware.h>
++
++#include "davinci_spi.h"
++
++static unsigned int data1_reg_val;
++
++
++void spi_init()
++{
++ /* do nothing */
++
++}
++
++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
++ unsigned int max_hz, unsigned int mode)
++{
++ struct davinci_spi_slave *ds;
++ void *regs;
++ unsigned int fmt0;
++
++ ds = malloc(sizeof(struct davinci_spi_slave));
++ if (!ds)
++ return NULL;
++
++ ds->slave.bus = bus;
++ ds->slave.cs = cs;
++ ds->regs = CFG_SPI_BASE;
++ ds->freq = max_hz;
++
++ return &ds->slave;
++}
++
++void spi_free_slave(struct spi_slave *slave)
++{
++ struct davinci_spi_slave *ds = to_davinci_spi(slave);
++
++ free(ds);
++}
++
++int spi_claim_bus(struct spi_slave *slave)
++{
++ struct davinci_spi_slave *ds = to_davinci_spi(slave);
++ unsigned int scalar;
++
++ /* Enable the SPI hardware */
++ spi_writel(ds, GCR0, 0);
++ udelay(1000);
++ spi_writel(ds, GCR0, 1);
++
++ /* Set master mode, powered up and not activated */
++ spi_writel(ds, GCR1, 0x3);
++
++ /* CS, CLK, SIMO and SOMI are functional pins */
++ spi_writel(ds, PC0, (1 << 0) | (1 << 9) | (1 << 10) | (1 << 11));
++
++ /* setup format */
++ scalar = ((CFG_SPI_CLK / ds->freq) - 1 ) & 0xFF;
++
++ spi_writel(ds, FMT0, 8 | /* character length */
++ (scalar << 8) |
++ (1 << 16) | /* clock signal delayed by half clk cycle */
++ (0 << 17) | /* clock low in idle state - Mode 0 */
++ (0 << 20)); /* MSB shifted out first */
++
++ /* hold cs active at end of transfer until explicitly de-asserted */
++ data1_reg_val = (1 << 28) | (slave->cs << 16);
++ spi_writel(ds, DAT1, data1_reg_val);
++
++ /* including a minor delay. No science here. Should be good even with
++ * no delay
++ */
++ spi_writel(ds, DELAY, (50 << 24) | (50 << 16));
++
++ /* default chip select register */
++ spi_writel(ds, DEF, 1);
++
++ /* no interrupts */
++ spi_writel(ds, INT0, 0);
++ spi_writel(ds, LVL, 0);
++
++ /* enable SPI */
++ spi_writel(ds, GCR1, spi_readl(ds, GCR1) | (1 << 24));
++
++ return 0;
++}
++
++void spi_release_bus(struct spi_slave *slave)
++{
++ struct davinci_spi_slave *ds = to_davinci_spi(slave);
++
++ /* Disable the SPI hardware */
++ spi_writel(ds, GCR0, 0);
++}
++
++int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
++ const void *dout, void *din, unsigned long flags)
++{
++ struct davinci_spi_slave *ds = to_davinci_spi(slave);
++ unsigned int len_tx;
++ unsigned int len_rx;
++ unsigned int len;
++ int ret, i;
++ u32 status;
++ const u8 *txp = dout;
++ u8 *rxp = din;
++ u8 value, dummy = 0;
++
++ ret = 0;
++
++ if (bitlen == 0)
++ /* Finish any previously submitted transfers */
++ goto out;
++
++ /*
++ * It's not clear how non-8-bit-aligned transfers are supposed to be
++ * represented as a stream of bytes...this is a limitation of
++ * the current SPI interface - here we terminate on receiving such a
++ * transfer request.
++ */
++ if (bitlen % 8) {
++ /* Errors always terminate an ongoing transfer */
++ flags |= SPI_XFER_END;
++ goto out;
++ }
++
++ len = bitlen / 8;
++
++ /* do an empty read to clear the current contents */
++ spi_readl(ds, BUF);
++
++ /* keep writing and reading 1 byte until done */
++ for (i = 0; i < len; i++) {
++
++ /* wait till TXFULL is asserted */
++ while(spi_readl(ds, BUF) & (1 << 29));
++
++ /* write the data */
++ data1_reg_val &= ~0xFFFF;
++ if(txp) {
++ data1_reg_val |= *txp & 0xFF;
++ txp++;
++ }
++
++ /* write to DAT1 is required to keep the serial transfer going */
++ /* we just terminate when we reach the end */
++ if((i == (len -1)) && (flags & SPI_XFER_END)) {
++ spi_writel(ds, DAT1, data1_reg_val & ~(1 << 28)); /* clear CS hold */
++ } else {
++ spi_writel(ds, DAT1, data1_reg_val);
++ }
++
++
++ /* read the data - wait for data availability */
++ while(spi_readl(ds, BUF) & (1 << 31));
++
++ if(rxp) {
++ *rxp = spi_readl(ds, BUF) & 0xFF;
++ rxp++;
++ } else {
++ spi_readl(ds, BUF); /* simply drop the read character */
++ }
++
++ }
++
++ return 0;
++
++out:
++ if (flags & SPI_XFER_END) {
++ spi_writel(ds, DAT1, data1_reg_val & ~(1 << 28));
++ }
++
++ return 0;
++}
++
++
++#ifdef CONFIG_CMD_EEPROM
++
++/* ------------------------------------------------------------------------ *
++ * SPI ROM Definitions *
++ * ------------------------------------------------------------------------ */
++#define SPIROM_SIZE 0x00008000
++#define SPIROM_BASE 0x00000000
++#define SPIROM_PAGESIZE 32
++#define SPIROM_PAGEMASK 0xffffffc0
++
++/* ------------------------------------------------------------------------ *
++ * SPI ROM Commands *
++ * ------------------------------------------------------------------------ */
++#define SPIROM_CMD_WRSR 0x01
++#define SPIROM_CMD_WRITE 0x02
++#define SPIROM_CMD_READ 0x03
++#define SPIROM_CMD_WRDI 0x04
++#define SPIROM_CMD_RDSR 0x05
++#define SPIROM_CMD_WREN 0x06
++
++static struct spi_slave *slave;
++
++void spi_init_f(void)
++{
++ slave = spi_setup_slave(0, 0, 1*1024*1024, 0);
++ spi_claim_bus(slave);
++}
++
++static char spirombuf[3];
++
++/* ------------------------------------------------------------------------ *
++ * spirom_status( ) *
++ * ------------------------------------------------------------------------ */
++static unsigned char spi_get_status( )
++{
++ /* Issue read status command */
++ spirombuf[0] = SPIROM_CMD_RDSR;
++ spirombuf[1] = 0;
++
++ spi_xfer(slave, (2)*8, spirombuf, spirombuf, SPI_XFER_BEGIN | SPI_XFER_END);
++
++ return spirombuf[1];
++}
++
++ssize_t spi_write(uchar *addr, int alen, uchar *buffer, int len)
++{
++
++ spirombuf[0] = SPIROM_CMD_WREN;
++ spi_xfer(slave, 1*8, spirombuf, NULL, SPI_XFER_BEGIN | SPI_XFER_END);
++
++ /* Create command block for program operation */
++ spirombuf[0] = SPIROM_CMD_WRITE;
++ spirombuf[1] = addr[0];
++ spirombuf[2] = addr[1];
++
++ spi_xfer(slave, 3 * 8, spirombuf, NULL, SPI_XFER_BEGIN);
++ spi_xfer(slave, len * 8, buffer, NULL, SPI_XFER_END);
++
++ /* Wait while busy */
++ while( (spi_get_status( ) & 0x01 ) );
++
++ return len;
++}
++
++ssize_t spi_read(uchar *addr, int alen, uchar *buffer, int len)
++{
++ spirombuf[0] = 0x3;
++ spirombuf[1] = addr[0];
++ spirombuf[2] = addr[1];
++
++ spi_xfer(slave, 3*8, spirombuf, NULL, SPI_XFER_BEGIN);
++ spi_xfer(slave, len*8, NULL, buffer, SPI_XFER_END);
++
++ return len;
++}
++
++#endif
+Index: u-boot-2009.01/drivers/spi/davinci_spi.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/drivers/spi/davinci_spi.h
+@@ -0,0 +1,46 @@
++/*
++ * Register definitions for the DaVinci SPI Controller
++ */
++
++/* Register offsets */
++#define DAVINCI_SPI_GCR0 0x0000
++#define DAVINCI_SPI_GCR1 0x0004
++#define DAVINCI_SPI_INT0 0x0008
++#define DAVINCI_SPI_LVL 0x000c
++#define DAVINCI_SPI_FLG 0x0010
++#define DAVINCI_SPI_PC0 0x0014
++#define DAVINCI_SPI_PC1 0x0018
++#define DAVINCI_SPI_PC2 0x001c
++#define DAVINCI_SPI_PC3 0x0020
++#define DAVINCI_SPI_PC4 0x0024
++#define DAVINCI_SPI_PC5 0x0028
++#define DAVINCI_SPI_DAT0 0x0038
++#define DAVINCI_SPI_DAT1 0x003c
++#define DAVINCI_SPI_BUF 0x0040
++#define DAVINCI_SPI_EMU 0x0044
++#define DAVINCI_SPI_DELAY 0x0048
++#define DAVINCI_SPI_DEF 0x004c
++#define DAVINCI_SPI_FMT0 0x0050
++#define DAVINCI_SPI_FMT1 0x0054
++#define DAVINCI_SPI_FMT2 0x0058
++#define DAVINCI_SPI_FMT3 0x005c
++#define DAVINCI_SPI_INTVEC0 0x0060
++#define DAVINCI_SPI_INTVEC1 0x0064
++
++struct davinci_spi_slave {
++ struct spi_slave slave;
++ void *regs;
++ u32 mr;
++ unsigned int freq;
++};
++
++static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave)
++{
++ return container_of(slave, struct davinci_spi_slave, slave);
++}
++
++#define spi_readl(as, reg) \
++ readl(CFG_SPI_BASE + DAVINCI_SPI_##reg)
++#define spi_writel(as, reg, value) \
++ writel(value, CFG_SPI_BASE + DAVINCI_SPI_##reg)
++
+Index: u-boot-2009.01/drivers/spi/spirom.c
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/drivers/spi/spirom.c
+@@ -0,0 +1,212 @@
++/*
++ * Copyright 2007 b7 Spectrum Digital Incorporated.
++ * All rights reserved. Property of Spectrum Digital Incorporated.
++ */
++
++/*
++ * SPI ROM interface
++ *
++ */
++
++#include "spirom.h"
++
++static Uint8 spirombuf[SPIROM_PAGESIZE + 5];
++static Uint8 statusbuf[8];
++static Uint32 spidat1;
++
++/* ------------------------------------------------------------------------ *
++ * *
++ * _wait( delay ) *
++ * Wait in a software loop for 'x' delay *
++ * *
++ * ------------------------------------------------------------------------ */
++void DAVINCIHD_wait( Uint32 delay )
++{
++ volatile Uint32 i;
++ for ( i = 0 ; i < delay ; i++ ){ };
++}
++
++
++/* ------------------------------------------------------------------------ *
++ * spirom_init( ) *
++ * ------------------------------------------------------------------------ */
++void spirom_init( )
++{
++ /* Reset SPI */
++ SPI_SPIGCR0 = 0;
++ _wait( 1000 );
++
++ /* Release SPI */
++ SPI_SPIGCR0 = 1;
++
++ /* SPI 4-Pin Mode setup */
++ SPI_SPIGCR1 = 0
++ | ( 0 << 24 )
++ | ( 0 << 16 )
++ | ( 1 << 1 )
++ | ( 1 << 0 );
++
++ SPI_SPIPC0 = 0
++ | ( 1 << 11 ) // DI
++ | ( 1 << 10 ) // DO
++ | ( 1 << 9 ) // CLK
++ | ( 1 << 1 ) // EN1
++ | ( 1 << 0 ); // EN0
++
++ SPI_SPIFMT0 = 0
++ | ( 0 << 20 ) // SHIFTDIR
++ | ( 0 << 17 ) // Polarity
++ | ( 1 << 16 ) // Phase
++ | ( 50 << 8 ) // Prescale
++ | ( 8 << 0 ); // Char Len
++
++ spidat1 = 0
++ | ( 1 << 28 ) // CSHOLD
++ | ( 0 << 24 ) // Format [0]
++ | ( 2 << 16 ) // CSNR [only CS0 enbled]
++ | ( 0 << 0 ); //
++
++ SPI_SPIDAT1 = spidat1;
++
++ SPI_SPIDELAY = 0
++ | ( 8 << 24 ) // C2TDELAY
++ | ( 8 << 16 ); // T2CDELAY
++
++ SPI_SPIDEF = 0
++ | ( 1 << 1 ) // EN1 inactive high
++ | ( 1 << 0 ); // EN0 inactive high
++
++ SPI_SPIINT = 0
++ | ( 0 << 16 ) //
++ | ( 0 << 8 ) //
++ | ( 0 << 6 ) //
++ | ( 1 << 4 ); //
++
++ SPI_SPILVL = 0
++ | ( 0 << 8 ) // EN0
++ | ( 0 << 6 ) // EN0
++ | ( 0 << 4 ); // EN0
++
++
++ /* Enable SPI */
++ SPI_SPIGCR1 |= ( 1 << 24 );
++}
++
++/* ------------------------------------------------------------------------ *
++ * spirom_cycle( buf, len ) *
++ * *
++ * Execute a SPI spirom data transfer cycle. Each byte in buf is shifted *
++ * out and replaced with data coming back from the spirom. *
++ * ------------------------------------------------------------------------ */
++void spirom_cycle( Uint8 *buf, Uint16 len )
++{
++ Uint16 i;
++
++ /* Clear any old data */
++ SPI_SPIBUF;
++
++ /* SPIROM access cycle */
++ for ( i = 0 ; i <= len ; i++ )
++ {
++ /* Wait for transmit ready */
++ while ( SPI_SPIBUF & 0x10000000 );
++
++ if ( i == len )
++ SPI_SPIDAT1 = ( spidat1 & 0x0ffcffff ) | buf[i];
++ else
++ SPI_SPIDAT1 = spidat1 | buf[i];
++
++ /* Wait for receive data ready */
++ while ( SPI_SPIBUF & 0x80000000 );
++
++ /* Read 1 byte */
++ buf[i] = SPI_SPIBUF;
++ }
++}
++
++/* ------------------------------------------------------------------------ *
++ * spirom_status( ) *
++ * ------------------------------------------------------------------------ */
++Uint8 spirom_status( )
++{
++ /* Issue read status command */
++ statusbuf[0] = SPIROM_CMD_RDSR;
++ statusbuf[1] = 0;
++
++ spirom_cycle( statusbuf, 2 );
++
++ return statusbuf[1];
++}
++
++/* ------------------------------------------------------------------------ *
++ * spirom_read( src, dst, length ) *
++ * ------------------------------------------------------------------------ */
++void spirom_read( Uint16 src, Uint32 dst, Uint32 length )
++{
++ Int32 i;
++ Uint8 *psrc, *pdst;
++
++ // Setup command
++ spirombuf[0] = SPIROM_CMD_READ;
++ spirombuf[1] = ( src >> 8 );
++ spirombuf[2] = ( src >> 0 );
++
++ // Execute spirom read cycle
++ spirom_cycle( spirombuf, length + 3 );
++
++ // Copy returned data
++ pdst = ( Uint8 * )dst;
++ psrc = spirombuf + 3;
++ for ( i = 0 ; i < length ; i++ )
++ *pdst++ = *psrc++;
++}
++
++/* ------------------------------------------------------------------------ *
++ * spirom_write( src, dst, length ) *
++ * ------------------------------------------------------------------------ */
++void spirom_write( Uint32 src, Uint16 dst, Uint32 length )
++{
++ Int32 i;
++ Int32 bytes_left;
++ Int32 bytes_to_program;
++ Uint8 *psrc;
++
++ /* Establish source */
++ psrc = ( Uint8 * )src;
++ bytes_left = length;
++
++ while ( bytes_left > 0 )
++ {
++ bytes_to_program = bytes_left;
++
++ /* Most to program is SPIROM_CMD_BLOCKSIZE */
++ if ( bytes_to_program > SPIROM_PAGESIZE )
++ bytes_to_program = SPIROM_PAGESIZE;
++
++ /* Make sure you don't run off the end of a block */
++ if ( ( dst & SPIROM_PAGEMASK ) != ( ( dst + bytes_to_program ) & SPIROM_PAGEMASK ) )
++ bytes_to_program -= ( dst + bytes_to_program ) - ( ( dst + bytes_to_program ) & SPIROM_PAGEMASK );
++
++ /* Issue WPEN */
++ spirombuf[0] = SPIROM_CMD_WREN;
++ spirom_cycle( spirombuf, 0 );
++
++ /* Create command block for program operation */
++ spirombuf[0] = SPIROM_CMD_WRITE;
++ spirombuf[1] = ( Uint8 )( dst >> 8 );
++ spirombuf[2] = ( Uint8 )( dst );
++
++ for ( i = 0 ; i < bytes_to_program ; i++ )
++ spirombuf[3+i] = *psrc++;
++
++ /* Execute write command */
++ spirom_cycle( spirombuf, bytes_to_program + 2 );
++
++ /* Wait while busy */
++ while( ( spirom_status( ) & 0x01 ) );
++
++ /* Get ready for next iteration */
++ bytes_left -= bytes_to_program;
++ dst += bytes_to_program;
++ }
++}
+Index: u-boot-2009.01/drivers/spi/spirom.h
+===================================================================
+--- /dev/null
++++ u-boot-2009.01/drivers/spi/spirom.h
+@@ -0,0 +1,77 @@
++/*
++ * Copyright 2007 by Spectrum Digital Incorporated.
++ * All rights reserved. Property of Spectrum Digital Incorporated.
++ */
++
++/*
++ * SPI ROM header file
++ *
++ */
++
++#ifndef SPIROM_
++#define SPIROM_
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#include "davincihd.h"
++
++/* ------------------------------------------------------------------------ *
++ * SPI ROM Definitions *
++ * ------------------------------------------------------------------------ */
++#define SPIROM_SIZE 0x00008000
++#define SPIROM_BASE 0x00000000
++#define SPIROM_PAGESIZE 32
++#define SPIROM_PAGEMASK 0xffffffc0
++
++/* ------------------------------------------------------------------------ *
++ * SPI ROM Commands *
++ * ------------------------------------------------------------------------ */
++#define SPIROM_CMD_WRSR 0x01
++#define SPIROM_CMD_WRITE 0x02
++#define SPIROM_CMD_READ 0x03
++#define SPIROM_CMD_WRDI 0x04
++#define SPIROM_CMD_RDSR 0x05
++#define SPIROM_CMD_WREN 0x06
++
++/* ------------------------------------------------------------------------ *
++ * SPI Controller *
++ * ------------------------------------------------------------------------ */
++#define SPI_BASE 0x01c66800
++#define SPI_SPIGCR0 *( volatile Uint32* )( SPI_BASE + 0x0 )
++#define SPI_SPIGCR1 *( volatile Uint32* )( SPI_BASE + 0x4 )
++#define SPI_SPIINT *( volatile Uint32* )( SPI_BASE + 0x8 )
++#define SPI_SPILVL *( volatile Uint32* )( SPI_BASE + 0xc )
++#define SPI_SPIFLG *( volatile Uint32* )( SPI_BASE + 0x10 )
++#define SPI_SPIPC0 *( volatile Uint32* )( SPI_BASE + 0x14 )
++#define SPI_SPIPC2 *( volatile Uint32* )( SPI_BASE + 0x1c )
++#define SPI_SPIDAT1_TOP *( volatile Uint16* )( SPI_BASE + 0x3c )
++#define SPI_SPIDAT1 *( volatile Uint32* )( SPI_BASE + 0x3c )
++#define SPI_SPIDAT1_PTR16 *( volatile Uint16* )( SPI_BASE + 0x3e )
++#define SPI_SPIDAT1_PTR8 *( volatile Uint8* ) ( SPI_BASE + 0x3f )
++#define SPI_SPIBUF *( volatile Uint32* )( SPI_BASE + 0x40 )
++#define SPI_SPIBUF_PTR16 *( volatile Uint16* )( SPI_BASE + 0x42 )
++#define SPI_SPIBUF_PTR8 *( volatile Uint8* ) ( SPI_BASE + 0x43 )
++#define SPI_SPIEMU *( volatile Uint32* )( SPI_BASE + 0x44 )
++#define SPI_SPIDELAY *( volatile Uint32* )( SPI_BASE + 0x48 )
++#define SPI_SPIDEF *( volatile Uint32* )( SPI_BASE + 0x4c )
++#define SPI_SPIFMT0 *( volatile Uint32* )( SPI_BASE + 0x50 )
++#define SPI_SPIFMT1 *( volatile Uint32* )( SPI_BASE + 0x54 )
++#define SPI_SPIFMT2 *( volatile Uint32* )( SPI_BASE + 0x58 )
++#define SPI_SPIFMT3 *( volatile Uint32* )( SPI_BASE + 0x5c )
++#define SPI_INTVEC0 *( volatile Uint32* )( SPI_BASE + 0x60 )
++#define SPI_INTVEC1 *( volatile Uint32* )( SPI_BASE + 0x64 )
++
++/* ------------------------------------------------------------------------ *
++ * Prototype *
++ * ------------------------------------------------------------------------ */
++void spirom_init( );
++void spirom_read( Uint16 src, Uint32 dst, Uint32 length );
++void spirom_write( Uint32 src, Uint16 dst, Uint32 length );
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
+Index: u-boot-2009.01/net/eth.c
+===================================================================
+--- u-boot-2009.01.orig/net/eth.c
++++ u-boot-2009.01/net/eth.c
+@@ -469,7 +469,7 @@ extern int at91rm9200_miiphy_initialize(
+ extern int emac4xx_miiphy_initialize(bd_t *bis);
+ extern int mcf52x2_miiphy_initialize(bd_t *bis);
+ extern int ns7520_miiphy_initialize(bd_t *bis);
+-extern int davinci_eth_miiphy_initialize(bd_t *bis);
++extern int dm644x_eth_miiphy_initialize(bd_t *bis);
+
+
+ int eth_initialize(bd_t *bis)
+@@ -491,7 +491,7 @@ int eth_initialize(bd_t *bis)
+ ns7520_miiphy_initialize(bis);
+ #endif
+ #if defined(CONFIG_DRIVER_TI_EMAC)
+- davinci_eth_miiphy_initialize(bis);
++ dm644x_eth_miiphy_initialize(bis);
+ #endif
+ return 0;
+ }
+Index: u-boot-2009.01/drivers/mtd/spi/Makefile
+===================================================================
+--- u-boot-2009.01.orig/drivers/mtd/spi/Makefile
++++ u-boot-2009.01/drivers/mtd/spi/Makefile
+@@ -28,6 +28,7 @@ LIB := $(obj)libspi_flash.a
+ COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o
+ COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o
+ COBJS-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.o
++COBJS-$(CONFIG_SPI_FLASH_WINBOND) += winbond.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+Index: u-boot-2009.01/drivers/spi/Makefile
+===================================================================
+--- u-boot-2009.01.orig/drivers/spi/Makefile
++++ u-boot-2009.01/drivers/spi/Makefile
+@@ -29,6 +29,7 @@ COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o
+ COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
+ COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
+ COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
++COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+Index: u-boot-2009.01/drivers/mtd/spi/spi_flash.c
+===================================================================
+--- u-boot-2009.01.orig/drivers/mtd/spi/spi_flash.c
++++ u-boot-2009.01/drivers/mtd/spi/spi_flash.c
+@@ -3,7 +3,7 @@
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ */
+-#define DEBUG
++/*#define DEBUG*/
+ #include <common.h>
+ #include <malloc.h>
+ #include <spi.h>
+@@ -134,6 +134,11 @@ struct spi_flash *spi_flash_probe(unsign
+ flash = spi_flash_probe_atmel(spi, idcode);
+ break;
+ #endif
++#ifdef CONFIG_SPI_FLASH_WINBOND
++ case 0xef:
++ flash = spi_flash_probe_winbond(spi, idcode);
++ break;
++#endif
+ #ifdef CONFIG_SPI_FLASH_STMICRO
+ case 0x20:
+ flash = spi_flash_probe_stmicro(spi, idcode);
+Index: u-boot-2009.01/common/cmd_nvedit.c
+===================================================================
+--- u-boot-2009.01.orig/common/cmd_nvedit.c
++++ u-boot-2009.01/common/cmd_nvedit.c
+@@ -549,6 +549,7 @@ int getenv_r (char *name, char *buf, uns
+ #if ((defined(CONFIG_ENV_IS_IN_NVRAM) || defined(CONFIG_ENV_IS_IN_EEPROM) \
+ || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_FLASH)) \
+ || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND)) \
++ || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_SF)) \
+ || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND))) \
+ && !defined(CONFIG_ENV_IS_NOWHERE))
+ int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+@@ -605,6 +606,7 @@ U_BOOT_CMD(
+ #if ((defined(CONFIG_ENV_IS_IN_NVRAM) || defined(CONFIG_ENV_IS_IN_EEPROM) \
+ || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_FLASH)) \
+ || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND)) \
++ || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_SF)) \
+ || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND))) \
+ && !defined(CONFIG_ENV_IS_NOWHERE))
+ U_BOOT_CMD(
+Index: u-boot-2009.01/common/cmd_sf.c
+===================================================================
+--- u-boot-2009.01.orig/common/cmd_sf.c
++++ u-boot-2009.01/common/cmd_sf.c
+@@ -29,6 +29,11 @@ static int do_spi_flash_probe(int argc,
+ if (argc < 2)
+ goto usage;
+
++ if(flash) {
++ printf("SPI flash already probed\n");
++ goto probe_done;
++ }
++
+ cs = simple_strtoul(argv[1], &endp, 0);
+ if (*argv[1] == 0 || (*endp != 0 && *endp != ':'))
+ goto usage;
+@@ -63,6 +68,7 @@ static int do_spi_flash_probe(int argc,
+ spi_flash_free(flash);
+ flash = new;
+
++probe_done:
+ printf("%u KiB %s at %u:%u is now current device\n",
+ flash->size >> 10, flash->name, bus, cs);
+
+Index: u-boot-2009.01/include/linux/mtd/nand.h
+===================================================================
+--- u-boot-2009.01.orig/include/linux/mtd/nand.h
++++ u-boot-2009.01/include/linux/mtd/nand.h
+@@ -135,6 +135,15 @@ typedef enum {
+ NAND_ECC_HW_SYNDROME,
+ } nand_ecc_modes_t;
+
++struct page_layout_item {
++ int length;
++ enum {
++ ITEM_TYPE_DATA,
++ ITEM_TYPE_OOB,
++ ITEM_TYPE_ECC,
++ } type;
++};
++
+ /*
+ * Constants for Hardware ECC
+ */
+@@ -144,6 +153,9 @@ typedef enum {
+ #define NAND_ECC_WRITE 1
+ /* Enable Hardware ECC before syndrom is read back from flash */
+ #define NAND_ECC_READSYN 2
++#define NAND_ECC_WRITESYN 3
++#define NAND_ECC_READOOB 4
++#define NAND_ECC_WRITEOOB 5
+
+ /* Bit mask for flags passed to do_nand_read_ecc */
+ #define NAND_GET_DEVICE 0x80
diff --git a/patches/series b/patches/series
new file mode 100644
index 0000000000..83afb9073a
--- /dev/null
+++ b/patches/series
@@ -0,0 +1,2 @@
+primus_port.patch
+freon_port.patch