summaryrefslogtreecommitdiffstats
path: root/patches/u-boot-2011.09/0000-v2011.09-arago-beaglebone.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/u-boot-2011.09/0000-v2011.09-arago-beaglebone.patch')
-rw-r--r--patches/u-boot-2011.09/0000-v2011.09-arago-beaglebone.patch16912
1 files changed, 16912 insertions, 0 deletions
diff --git a/patches/u-boot-2011.09/0000-v2011.09-arago-beaglebone.patch b/patches/u-boot-2011.09/0000-v2011.09-arago-beaglebone.patch
new file mode 100644
index 0000000..8b66149
--- /dev/null
+++ b/patches/u-boot-2011.09/0000-v2011.09-arago-beaglebone.patch
@@ -0,0 +1,16912 @@
+diff --git a/Makefile b/Makefile
+index 77140eb..99b9278 100644
+--- a/Makefile
++++ b/Makefile
+@@ -279,6 +279,9 @@ LIBS += lib/libfdt/libfdt.o
+ LIBS += api/libapi.o
+ LIBS += post/libpost.o
+
++ifeq ($(SOC),ti81xx)
++LIBS += $(CPUDIR)/omap-common/libomap-common.o
++endif
+ ifeq ($(SOC),omap3)
+ LIBS += $(CPUDIR)/omap-common/libomap-common.o
+ endif
+@@ -868,6 +871,45 @@ tx25_config : unconfig
+ @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
+ @$(MKCONFIG) $@ arm arm926ejs tx25 karo mx25
+
++ti8168_evm_config \
++ti8168_evm_config_nand \
++ti8168_evm_config_nor \
++ti8168_evm_config_spi \
++ti8168_evm_min_ocmc \
++ti8168_evm_min_sd: unconfig
++ @mkdir -p $(obj)include
++ @echo "#define CONFIG_TI81XX" >>$(obj)include/config.h
++ @echo "#define CONFIG_TI816X" >>$(obj)include/config.h
++ @if [ "$(findstring _nand,$@)" ] ; then \
++ echo "#define CONFIG_SYS_NO_FLASH" >>$(obj)include/config.h ; \
++ echo "#define CONFIG_NAND_ENV" >>$(obj)include/config.h ; \
++ echo "Setting up TI8168 NAND build with ENV in NAND..." ; \
++ elif [ "$(findstring _nor,$@)" ] ; then \
++ echo "#define CONFIG_NOR" >>$(obj)include/config.h ; \
++ echo "#define CONFIG_NOR_BOOT" >>$(obj)include/config.h ; \
++ echo "Setting up TI8168 NOR build with ENV in NOR..." ; \
++ elif [ "$(findstring _spi,$@)" ] ; then \
++ echo "#define CONFIG_SYS_NO_FLASH" >>$(obj)include/config.h ; \
++ echo "#define CONFIG_SPI_ENV" >>$(obj)include/config.h ; \
++ echo "#define CONFIG_TI81XX_SPI_BOOT" >>$(obj)include/config.h ; \
++ echo "Setting up TI8168 SPI build with ENV in SPI..." ; \
++ elif [ "$(findstring _sd,$@)" ] ; then \
++ echo "#define CONFIG_SYS_NO_FLASH" >>$(obj)include/config.h ; \
++ echo "#define CONFIG_SD_BOOT" >>$(obj)include/config.h ; \
++ echo "TI_IMAGE = u-boot.min.sd" >>$(obj)board/ti/ti8168/config.tmp; \
++ echo "Setting up TI8168 SD boot minimal build..." ; \
++ elif [ "$(findstring _ocmc,$@)" ] ; then \
++ echo "#define CONFIG_SYS_NO_FLASH" >>$(obj)include/config.h ; \
++ echo "#define CONFIG_MINIMAL" >>$(obj)include/config.h ; \
++ echo "CONFIG_SYS_TEXT_BASE = 0x40410000" >>$(obj)board/ti/ti8168/config.tmp; \
++ echo "Setting up TI8168 minimal build..." ; \
++ else \
++ echo "#define CONFIG_SYS_NO_FLASH" >>$(obj)include/config.h ; \
++ echo "#define CONFIG_NAND_ENV" >>$(obj)include/config.h ; \
++ echo "Setting up TI8168 default build with NAND..." ; \
++ fi;
++ @$(MKCONFIG) -a ti8168_evm arm armv7 ti8168 ti ti81xx
++
+ #########################################################################
+ ## XScale Systems
+ #########################################################################
+diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile
+index ea9f8ec..0865cd8 100644
+--- a/arch/arm/cpu/armv7/omap-common/Makefile
++++ b/arch/arm/cpu/armv7/omap-common/Makefile
+@@ -29,10 +29,21 @@ SOBJS := reset.o
+
+ COBJS := timer.o
+ COBJS += utils.o
++ifdef CONFIG_OMAP
+ COBJS += gpio.o
++endif
+
+ ifdef CONFIG_SPL_BUILD
+ COBJS += spl.o
++ifdef CONFIG_SPL_NAND_SUPPORT
++COBJS += spl_nand.o
++endif
++ifdef CONFIG_SPL_MMC_SUPPORT
++COBJS += spl_mmc.o
++endif
++ifdef CONFIG_SPL_YMODEM_SUPPORT
++COBJS += spl_ymodem.o
++endif
+ endif
+
+ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c
+index d177652..abe8c56 100644
+--- a/arch/arm/cpu/armv7/omap-common/spl.c
++++ b/arch/arm/cpu/armv7/omap-common/spl.c
+@@ -26,6 +26,7 @@
+ #include <asm/u-boot.h>
+ #include <asm/utils.h>
+ #include <asm/arch/sys_proto.h>
++#include <nand.h>
+ #include <mmc.h>
+ #include <fat.h>
+ #include <timestamp_autogenerated.h>
+@@ -37,14 +38,11 @@
+
+ DECLARE_GLOBAL_DATA_PTR;
+
++struct spl_image_info spl_image;
++
+ /* Define global data structure pointer to it*/
+ static gd_t gdata __attribute__ ((section(".data")));
+ static bd_t bdata __attribute__ ((section(".data")));
+-static const char *image_name;
+-static u8 image_os;
+-static u32 image_load_addr;
+-static u32 image_entry_point;
+-static u32 image_size;
+
+ inline void hang(void)
+ {
+@@ -65,154 +63,40 @@ void board_init_f(ulong dummy)
+ relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE);
+ }
+
+-#ifdef CONFIG_GENERIC_MMC
+-int board_mmc_init(bd_t *bis)
+-{
+- switch (omap_boot_device()) {
+- case BOOT_DEVICE_MMC1:
+- omap_mmc_init(0);
+- break;
+- case BOOT_DEVICE_MMC2:
+- omap_mmc_init(1);
+- break;
+- }
+- return 0;
+-}
+-#endif
+-
+-static void parse_image_header(const struct image_header *header)
++void spl_parse_image_header(const struct image_header *header)
+ {
+ u32 header_size = sizeof(struct image_header);
+
+ if (__be32_to_cpu(header->ih_magic) == IH_MAGIC) {
+- image_size = __be32_to_cpu(header->ih_size) + header_size;
+- image_entry_point = __be32_to_cpu(header->ih_load);
++ spl_image.size = __be32_to_cpu(header->ih_size) + header_size;
++ spl_image.entry_point = __be32_to_cpu(header->ih_load);
+ /* Load including the header */
+- image_load_addr = image_entry_point - header_size;
+- image_os = header->ih_os;
+- image_name = (const char *)&header->ih_name;
++ spl_image.load_addr = spl_image.entry_point - header_size;
++ spl_image.os = header->ih_os;
++ spl_image.name = (const char *)&header->ih_name;
+ debug("spl: payload image: %s load addr: 0x%x size: %d\n",
+- image_name, image_load_addr, image_size);
++ spl_image.name, spl_image.load_addr, spl_image.size);
+ } else {
+ /* Signature not found - assume u-boot.bin */
+ printf("mkimage signature not found - ih_magic = %x\n",
+ header->ih_magic);
+ puts("Assuming u-boot.bin ..\n");
+ /* Let's assume U-Boot will not be more than 200 KB */
+- image_size = 200 * 1024;
+- image_entry_point = CONFIG_SYS_TEXT_BASE;
+- image_load_addr = CONFIG_SYS_TEXT_BASE;
+- image_os = IH_OS_U_BOOT;
+- image_name = "U-Boot";
+- }
+-}
+-
+-static void mmc_load_image_raw(struct mmc *mmc)
+-{
+- u32 image_size_sectors, err;
+- const struct image_header *header;
+-
+- header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
+- sizeof(struct image_header));
+-
+- /* read image header to find the image size & load address */
+- err = mmc->block_dev.block_read(0,
+- CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1,
+- (void *)header);
+-
+- if (err <= 0)
+- goto end;
+-
+- parse_image_header(header);
+-
+- /* convert size to sectors - round up */
+- image_size_sectors = (image_size + MMCSD_SECTOR_SIZE - 1) /
+- MMCSD_SECTOR_SIZE;
+-
+- /* Read the header too to avoid extra memcpy */
+- err = mmc->block_dev.block_read(0,
+- CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
+- image_size_sectors, (void *)image_load_addr);
+-
+-end:
+- if (err <= 0) {
+- printf("spl: mmc blk read err - %d\n", err);
+- hang();
++ spl_image.size = 200 * 1024;
++ spl_image.entry_point = CONFIG_SYS_TEXT_BASE;
++ spl_image.load_addr = CONFIG_SYS_TEXT_BASE;
++ spl_image.os = IH_OS_U_BOOT;
++ spl_image.name = "U-Boot";
+ }
+ }
+
+-static void mmc_load_image_fat(struct mmc *mmc)
+-{
+- s32 err;
+- struct image_header *header;
+-
+- header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
+- sizeof(struct image_header));
+-
+- err = fat_register_device(&mmc->block_dev,
+- CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION);
+- if (err) {
+- printf("spl: fat register err - %d\n", err);
+- hang();
+- }
+-
+- err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
+- (u8 *)header, sizeof(struct image_header));
+- if (err <= 0)
+- goto end;
+-
+- parse_image_header(header);
+-
+- err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
+- (u8 *)image_load_addr, 0);
+-
+-end:
+- if (err <= 0) {
+- printf("spl: error reading image %s, err - %d\n",
+- CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err);
+- hang();
+- }
+-}
+-
+-static void mmc_load_image(void)
+-{
+- struct mmc *mmc;
+- int err;
+- u32 boot_mode;
+-
+- mmc_initialize(gd->bd);
+- /* We register only one device. So, the dev id is always 0 */
+- mmc = find_mmc_device(0);
+- if (!mmc) {
+- puts("spl: mmc device not found!!\n");
+- hang();
+- }
+-
+- err = mmc_init(mmc);
+- if (err) {
+- printf("spl: mmc init failed: err - %d\n", err);
+- hang();
+- }
+-
+- boot_mode = omap_boot_mode();
+- if (boot_mode == MMCSD_MODE_RAW) {
+- debug("boot mode - RAW\n");
+- mmc_load_image_raw(mmc);
+- } else if (boot_mode == MMCSD_MODE_FAT) {
+- debug("boot mode - FAT\n");
+- mmc_load_image_fat(mmc);
+- } else {
+- puts("spl: wrong MMC boot mode\n");
+- hang();
+- }
+-}
+-
+-void jump_to_image_no_args(void)
++static void jump_to_image_no_args(void)
+ {
+ typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn));
+ image_entry_noargs_t image_entry =
+- (image_entry_noargs_t) image_entry_point;
++ (image_entry_noargs_t) spl_image.entry_point;
+
++ debug("image entry point: 0x%X\n", spl_image.entry_point);
+ image_entry();
+ }
+
+@@ -225,20 +109,36 @@ void board_init_r(gd_t *id, ulong dummy)
+ timer_init();
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
++#ifdef CONFIG_SPL_BOARD_INIT
++ spl_board_init();
++#endif
++
+ boot_device = omap_boot_device();
+ debug("boot device - %d\n", boot_device);
+ switch (boot_device) {
++#ifdef CONFIG_SPL_MMC_SUPPORT
+ case BOOT_DEVICE_MMC1:
+ case BOOT_DEVICE_MMC2:
+- mmc_load_image();
++ spl_mmc_load_image();
++ break;
++#endif
++#ifdef CONFIG_SPL_NAND_SUPPORT
++ case BOOT_DEVICE_NAND:
++ spl_nand_load_image();
+ break;
++#endif
++#ifdef CONFIG_SPL_YMODEM_SUPPORT
++ case BOOT_DEVICE_UART:
++ spl_ymodem_load_image();
++ break;
++#endif
+ default:
+ printf("SPL: Un-supported Boot Device - %d!!!\n", boot_device);
+ hang();
+ break;
+ }
+
+- switch (image_os) {
++ switch (spl_image.os) {
+ case IH_OS_U_BOOT:
+ debug("Jumping to U-Boot\n");
+ jump_to_image_no_args();
+@@ -249,6 +149,7 @@ void board_init_r(gd_t *id, ulong dummy)
+ }
+ }
+
++/* This requires UART clocks to be enabled */
+ void preloader_console_init(void)
+ {
+ const char *u_boot_rev = U_BOOT_VERSION;
+@@ -259,7 +160,6 @@ void preloader_console_init(void)
+ gd->flags |= GD_FLG_RELOC;
+ gd->baudrate = CONFIG_BAUDRATE;
+
+- setup_clocks_for_console();
+ serial_init(); /* serial communications setup */
+
+ /* Avoid a second "U-Boot" coming from this string */
+@@ -270,3 +170,11 @@ void preloader_console_init(void)
+ omap_rev_string(rev_string_buffer);
+ printf("Texas Instruments %s\n", rev_string_buffer);
+ }
++
++void __omap_rev_string(char *str)
++{
++ sprintf(str, "Revision detection unimplemented");
++}
++
++void omap_rev_string(char *str)
++ __attribute__((weak, alias("__omap_rev_string")));
+diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c
+new file mode 100644
+index 0000000..1d1e50c
+--- /dev/null
++++ b/arch/arm/cpu/armv7/omap-common/spl_mmc.c
+@@ -0,0 +1,150 @@
++/*
++ * (C) Copyright 2010
++ * Texas Instruments, <www.ti.com>
++ *
++ * Aneesh V <aneesh@ti.com>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#include <common.h>
++#include <asm/u-boot.h>
++#include <asm/utils.h>
++#include <asm/arch/sys_proto.h>
++#include <mmc.h>
++#include <fat.h>
++#include <timestamp_autogenerated.h>
++#include <version_autogenerated.h>
++#include <asm/omap_common.h>
++#include <asm/arch/mmc_host_def.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#ifdef CONFIG_GENERIC_MMC
++int board_mmc_init(bd_t *bis)
++{
++ switch (omap_boot_device()) {
++ case BOOT_DEVICE_MMC1:
++ omap_mmc_init(0);
++ break;
++ case BOOT_DEVICE_MMC2:
++ omap_mmc_init(1);
++ break;
++ }
++ return 0;
++}
++#endif
++
++static void mmc_load_image_raw(struct mmc *mmc)
++{
++ u32 image_size_sectors, err;
++ const struct image_header *header;
++
++ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
++ sizeof(struct image_header));
++
++ /* read image header to find the image size & load address */
++ err = mmc->block_dev.block_read(0,
++ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1,
++ (void *)header);
++
++ if (err <= 0)
++ goto end;
++
++ spl_parse_image_header(header);
++
++ /* convert size to sectors - round up */
++ image_size_sectors = (spl_image.size + MMCSD_SECTOR_SIZE - 1) /
++ MMCSD_SECTOR_SIZE;
++
++ /* Read the header too to avoid extra memcpy */
++ err = mmc->block_dev.block_read(0,
++ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
++ image_size_sectors, (void *)spl_image.load_addr);
++
++end:
++ if (err <= 0) {
++ printf("spl: mmc blk read err - %d\n", err);
++ hang();
++ }
++}
++
++static void mmc_load_image_fat(struct mmc *mmc)
++{
++ s32 err;
++ struct image_header *header;
++
++ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
++ sizeof(struct image_header));
++
++ err = fat_register_device(&mmc->block_dev,
++ CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION);
++ if (err) {
++ printf("spl: fat register err - %d\n", err);
++ hang();
++ }
++
++ err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
++ (u8 *)header, sizeof(struct image_header));
++ if (err <= 0)
++ goto end;
++
++ spl_parse_image_header(header);
++
++ err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
++ (u8 *)spl_image.load_addr, 0);
++
++end:
++ if (err <= 0) {
++ printf("spl: error reading image %s, err - %d\n",
++ CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err);
++ hang();
++ }
++}
++
++void spl_mmc_load_image(void)
++{
++ struct mmc *mmc;
++ int err;
++ u32 boot_mode;
++
++ mmc_initialize(gd->bd);
++ /* We register only one device. So, the dev id is always 0 */
++ mmc = find_mmc_device(0);
++ if (!mmc) {
++ puts("spl: mmc device not found!!\n");
++ hang();
++ }
++
++ err = mmc_init(mmc);
++ if (err) {
++ printf("spl: mmc init failed: err - %d\n", err);
++ hang();
++ }
++ boot_mode = omap_boot_mode();
++ if (boot_mode == MMCSD_MODE_RAW) {
++ debug("boot mode - RAW\n");
++ mmc_load_image_raw(mmc);
++ } else if (boot_mode == MMCSD_MODE_FAT) {
++ debug("boot mode - FAT\n");
++ mmc_load_image_fat(mmc);
++ } else {
++ puts("spl: wrong MMC boot mode\n");
++ hang();
++ }
++}
+diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c
+new file mode 100644
+index 0000000..af02a59
+--- /dev/null
++++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c
+@@ -0,0 +1,71 @@
++/*
++ * Copyright (C) 2011
++ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#include <common.h>
++#include <asm/u-boot.h>
++#include <asm/utils.h>
++#include <asm/arch/sys_proto.h>
++#include <nand.h>
++#include <timestamp_autogenerated.h>
++#include <version_autogenerated.h>
++#include <asm/omap_common.h>
++
++
++void spl_nand_load_image(void)
++{
++ struct image_header *header;
++ switch (omap_boot_mode()) {
++ case NAND_MODE_HW_ECC:
++ debug("spl: nand - using hw ecc\n");
++ gpmc_init();
++ nand_init();
++ break;
++ default:
++ puts("spl: ERROR: This bootmode is not implemented - hanging");
++ hang();
++ }
++
++ /*use CONFIG_SYS_TEXT_BASE as temporary storage area */
++ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
++
++#ifdef CONFIG_NAND_ENV_DST
++ nand_spl_load_image(CONFIG_ENV_OFFSET,
++ CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
++ spl_parse_image_header(header);
++ nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
++ (void *)image_load_addr);
++#ifdef CONFIG_ENV_OFFSET_REDUND
++ nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
++ CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
++ spl_parse_image_header(header);
++ nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
++ (void *)image_load_addr);
++#endif
++#endif
++ /* Load u-boot */
++ nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
++ CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
++ spl_parse_image_header(header);
++ nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
++ spl_image.size, (void *)spl_image.load_addr);
++ nand_deselect();
++}
+diff --git a/arch/arm/cpu/armv7/omap-common/spl_ymodem.c b/arch/arm/cpu/armv7/omap-common/spl_ymodem.c
+new file mode 100644
+index 0000000..0bc5306
+--- /dev/null
++++ b/arch/arm/cpu/armv7/omap-common/spl_ymodem.c
+@@ -0,0 +1,78 @@
++/*
++ * (C) Copyright 2000-2004
++ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++ *
++ * (C) Copyright 2011
++ * Texas Instruments, <www.ti.com>
++ *
++ * Matt Porter <mporter@ti.com>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#include <common.h>
++#include <xyzModem.h>
++#include <asm/u-boot.h>
++#include <asm/utils.h>
++#include <asm/arch/sys_proto.h>
++#include <timestamp_autogenerated.h>
++#include <version_autogenerated.h>
++#include <asm/omap_common.h>
++
++#define BUF_SIZE 1024
++
++static int getcymodem(void) {
++ if (tstc())
++ return (getc());
++ return -1;
++}
++
++void spl_ymodem_load_image(void)
++{
++ int size = 0;
++ int err;
++ int res;
++ int ret;
++ connection_info_t info;
++ char buf[BUF_SIZE];
++ ulong store_addr = ~0;
++ ulong addr = 0;
++
++ info.mode = xyzModem_ymodem;
++ ret = xyzModem_stream_open(&info, &err);
++
++ if (!ret) {
++ while ((res =
++ xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) {
++ if (addr == 0)
++ spl_parse_image_header((struct image_header *)buf);
++ store_addr = addr + spl_image.load_addr;
++ size += res;
++ addr += res;
++ memcpy((char *)(store_addr), buf, res);
++ }
++ } else {
++ printf("spl: ymodem err - %s\n", xyzModem_error(err));
++ hang();
++ }
++
++ xyzModem_stream_close(&err);
++ xyzModem_stream_terminate(false, &getcymodem);
++
++ printf("Loaded %d bytes\n", size);
++}
+diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
+index 0448bc9..3d74634 100644
+--- a/arch/arm/cpu/armv7/omap3/board.c
++++ b/arch/arm/cpu/armv7/omap3/board.c
+@@ -39,6 +39,8 @@
+ #include <asm/cache.h>
+ #include <asm/armv7.h>
+ #include <asm/arch/gpio.h>
++#include <asm/omap_common.h>
++#include <linux/mtd/nand.h>
+
+ /* Declarations */
+ extern omap3_sysinfo sysinfo;
+@@ -56,6 +58,41 @@ static const struct gpio_bank gpio_bank_34xx[6] = {
+
+ const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx;
+
++#ifdef CONFIG_SPL_BUILD
++/*
++* We use static variables because global data is not ready yet.
++* Initialized data is available in SPL right from the beginning.
++* We would not typically need to save these parameters in regular
++* U-Boot. This is needed only in SPL at the moment.
++*/
++u32 omap3_boot_device = BOOT_DEVICE_NAND;
++
++/* auto boot mode detection is not possible for OMAP3 - hard code */
++u32 omap_boot_mode(void)
++{
++ switch (omap_boot_device()) {
++ case BOOT_DEVICE_MMC2:
++ return MMCSD_MODE_RAW;
++ case BOOT_DEVICE_MMC1:
++ return MMCSD_MODE_FAT;
++ break;
++ case BOOT_DEVICE_NAND:
++ return NAND_MODE_HW_ECC;
++ break;
++ default:
++ puts("spl: ERROR: unknown device - can't select boot mode\n");
++ hang();
++ }
++}
++
++u32 omap_boot_device(void)
++{
++ return omap3_boot_device;
++}
++
++#endif /* CONFIG_SPL_BUILD */
++
++
+ /******************************************************************************
+ * Routine: delay
+ * Description: spinning delay to use before udelay works
+@@ -197,6 +234,10 @@ void s_init(void)
+
+ per_clocks_enable();
+
++#ifdef CONFIG_SPL_BUILD
++ preloader_console_init();
++#endif
++
+ if (!in_sdram)
+ mem_init();
+ }
+@@ -245,18 +286,26 @@ void abort(void)
+ {
+ }
+
+-#ifdef CONFIG_NAND_OMAP_GPMC
++#if defined(CONFIG_NAND_OMAP_GPMC) & !defined(CONFIG_SPL_BUILD)
+ /******************************************************************************
+ * OMAP3 specific command to switch between NAND HW and SW ecc
+ *****************************************************************************/
+ static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+ {
+- if (argc != 2)
++ if (argc < 2)
+ goto usage;
+- if (strncmp(argv[1], "hw", 2) == 0)
+- omap_nand_switch_ecc(1);
++ if (strncmp(argv[1], "hw", 2) == 0) {
++ int type = 1;
++ if (argc == 3)
++ type = simple_strtoul(argv[2], NULL, 10);
++ omap_nand_switch_ecc(NAND_ECC_HW, type);
++ }
+ else if (strncmp(argv[1], "sw", 2) == 0)
+- omap_nand_switch_ecc(0);
++ omap_nand_switch_ecc(NAND_ECC_SOFT, 0);
++ else if (strncmp(argv[1], "bch4_sw", 7) == 0)
++ omap_nand_switch_ecc(NAND_ECC_4BIT_SOFT, 0);
++ else if (strncmp(argv[1], "bch8_sw", 7) == 0)
++ omap_nand_switch_ecc(NAND_ECC_8BIT_SOFT, 0);
+ else
+ goto usage;
+
+@@ -268,12 +317,15 @@ usage:
+ }
+
+ U_BOOT_CMD(
+- nandecc, 2, 1, do_switch_ecc,
++ nandecc, 3, 1, do_switch_ecc,
+ "switch OMAP3 NAND ECC calculation algorithm",
+- "[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc algorithm"
++ "[hw 1/hw 2/sw/bch4_sw/bch8_sw] - Switch between NAND hardware for \
++kernel/FS layout (hw 1), hardware for xloader/uboot layout (hw 2), \
++1-bit software (sw), 4-bit software (bch4_sw), or 8-bit software \
++(bch8_sw) ecc algorithm"
+ );
+
+-#endif /* CONFIG_NAND_OMAP_GPMC */
++#endif /* CONFIG_NAND_OMAP_GPMC & !CONFIG_SPL_BUILD */
+
+ #ifdef CONFIG_DISPLAY_BOARDINFO
+ /**
+diff --git a/arch/arm/cpu/armv7/omap3/config.mk b/arch/arm/cpu/armv7/omap3/config.mk
+new file mode 100644
+index 0000000..b34fa64
+--- /dev/null
++++ b/arch/arm/cpu/armv7/omap3/config.mk
+@@ -0,0 +1,30 @@
++#
++# Copyright 2011 Linaro Limited
++# See file CREDITS for list of people who contributed to this
++# project.
++#
++# (C) Copyright 2010
++# Texas Instruments, <www.ti.com>
++#
++# Aneesh V <aneesh@ti.com>
++#
++# 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
++#
++ifdef CONFIG_SPL_BUILD
++ALL-y += $(OBJTREE)/MLO
++else
++ALL-y += $(obj)u-boot.img
++endif
+diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
+index 67e8ceb..a308ebd 100644
+--- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S
++++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
+@@ -35,6 +35,16 @@
+ _TEXT_BASE:
+ .word CONFIG_SYS_TEXT_BASE /* sdram load addr from config.mk */
+
++.global save_boot_params
++save_boot_params:
++#ifdef CONFIG_SPL_BUILD
++ ldr r4, =omap3_boot_device
++ ldr r5, [r0, #0x4]
++ and r5, r5, #0xff
++ str r5, [r4]
++#endif
++ bx lr
++
+ .global omap3_gp_romcode_call
+ omap3_gp_romcode_call:
+ PUSH {r4-r12, lr} @ Save all registers from ROM code!
+diff --git a/arch/arm/cpu/armv7/omap3/mem.c b/arch/arm/cpu/armv7/omap3/mem.c
+index a01c303..77b5b77 100644
+--- a/arch/arm/cpu/armv7/omap3/mem.c
++++ b/arch/arm/cpu/armv7/omap3/mem.c
+@@ -51,6 +51,18 @@ static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
+
+ #endif
+
++#if defined (CONFIG_CMD_FLASH)
++static const u32 gpmc_nor[GPMC_MAX_REG] = {
++ STNOR_GPMC_CONFIG1,
++ STNOR_GPMC_CONFIG2,
++ STNOR_GPMC_CONFIG3,
++ STNOR_GPMC_CONFIG4,
++ STNOR_GPMC_CONFIG5,
++ STNOR_GPMC_CONFIG6, 0
++};
++#endif
++
++
+ #if defined(CONFIG_CMD_ONENAND)
+ static const u32 gpmc_onenand[GPMC_MAX_REG] = {
+ ONENAND_GPMC_CONFIG1,
+@@ -126,6 +138,18 @@ void gpmc_init(void)
+ u32 size = 0;
+ #endif
+ u32 config = 0;
++ u32 order, mem_type;
++
++ /*
++ * Detect the boot device
++ *
++ * 0x0D => NOR Flash boot
++ * 0x0C => NAND Flash boot
++ * 0x2D => MMC/SD boot
++ */
++ mem_type = get_boot_type();
++ order = mem_type & (1<<5);
++ mem_type &= ~(1<<5);
+
+ /* global settings */
+ writel(0, &gpmc_cfg->irqenable); /* isr's sources masked */
+@@ -139,7 +163,9 @@ void gpmc_init(void)
+ * Disable the GPMC0 config set by ROM code
+ * It conflicts with our MPDB (both at 0x08000000)
+ */
+- writel(0, &gpmc_cfg->cs[0].config7);
++ if (order || (get_boot_type() != 0xD))
++ writel(0, &gpmc_cfg->cs[0].config7);
++
+ sdelay(1000);
+
+ #if defined(CONFIG_CMD_NAND) /* CS 0 */
+@@ -147,13 +173,29 @@ void gpmc_init(void)
+
+ base = PISMO1_NAND_BASE;
+ size = PISMO1_NAND_SIZE;
+- enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
++ if (order || (get_boot_type() != 0xD))
++ enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
++ else
++ enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[2], base, size);
++
+ #endif
+
+ #if defined(CONFIG_CMD_ONENAND)
+ gpmc_config = gpmc_onenand;
+ base = PISMO1_ONEN_BASE;
+ size = PISMO1_ONEN_SIZE;
+- enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
++ if (order || (get_boot_type() != 0xD))
++ enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
++ else
++ enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[2], base, size);
++
++#endif
++
++#if defined (CONFIG_CMD_FLASH) && defined (CONFIG_OMAP3_AM3517EVM)
++ /* NOR - CS2 */
++ if (order || (get_boot_type() != 0xD))
++ enable_gpmc_cs_config(gpmc_nor,
++ (struct gpmc_cs *)GPMC_CONFIG_CS2_BASE,
++ DEBUG_BASE, GPMC_SIZE_64M);
+ #endif
+ }
+diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c
+index 2a7970b..0dd1955 100644
+--- a/arch/arm/cpu/armv7/omap3/sdrc.c
++++ b/arch/arm/cpu/armv7/omap3/sdrc.c
+@@ -8,6 +8,9 @@
+ * Copyright (C) 2004-2010
+ * Texas Instruments Incorporated - http://www.ti.com/
+ *
++ * Copyright (C) 2011
++ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
++ *
+ * Author :
+ * Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+@@ -133,13 +136,40 @@ void do_sdrc_init(u32 cs, u32 early)
+ sdelay(0x20000);
+ }
+
++/* As long as V_MCFG and V_RFR_CTRL is not defined for all OMAP3 boards we need
++ * to prevent this to be build in non-SPL build */
++#ifdef CONFIG_SPL_BUILD
++ /* If we use a SPL there is no x-loader nor config header so we have
++ * to do the job ourselfs
++ */
++ if (cs == CS0) {
++ sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE;
++
++ /* General SDRC config */
++ writel(V_MCFG, &sdrc_base->cs[cs].mcfg);
++ writel(V_RFR_CTRL, &sdrc_base->cs[cs].rfr_ctrl);
++
++ /* AC timings */
++ writel(V_ACTIMA_165, &sdrc_actim_base0->ctrla);
++ writel(V_ACTIMB_165, &sdrc_actim_base0->ctrlb);
++
++ /* Initialize */
++ writel(CMD_NOP, &sdrc_base->cs[cs].manual);
++ writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual);
++ writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
++ writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
++
++ writel(V_MR, &sdrc_base->cs[cs].mr);
++ }
++#endif
++
+ /*
+ * SDRC timings are set up by x-load or config header
+ * We don't need to redo them here.
+ * Older x-loads configure only CS0
+ * configure CS1 to handle this ommission
+ */
+- if (cs) {
++ if (cs == CS1) {
+ sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE;
+ sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE;
+ writel(readl(&sdrc_base->cs[CS0].mcfg),
+diff --git a/arch/arm/cpu/armv7/omap4/board.c b/arch/arm/cpu/armv7/omap4/board.c
+index 309b244..8584fdd 100644
+--- a/arch/arm/cpu/armv7/omap4/board.c
++++ b/arch/arm/cpu/armv7/omap4/board.c
+@@ -257,6 +257,7 @@ void s_init(void)
+ watchdog_init();
+ set_mux_conf_regs();
+ #ifdef CONFIG_SPL_BUILD
++ setup_clocks_for_console();
+ preloader_console_init();
+ do_io_settings();
+ #endif
+diff --git a/arch/arm/cpu/armv7/ti81xx/Makefile b/arch/arm/cpu/armv7/ti81xx/Makefile
+new file mode 100644
+index 0000000..a3a9c50
+--- /dev/null
++++ b/arch/arm/cpu/armv7/ti81xx/Makefile
+@@ -0,0 +1,50 @@
++#
++# Copyright (C) 2009, Texas Instruments, Incorporated
++#
++# 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 version 2.
++#
++# This program is distributed "as is" WITHOUT ANY WARRANTY of any
++# kind, whether express or implied; without even the implied warranty
++# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(SOC).o
++
++SOBJS := lowlevel_init.o
++SOBJS += cache.o
++
++COBJS += mem.o
++COBJS += sys_info.o
++COBJS += board.o
++
++COBJS-$(CONFIG_NAND_TI81XX) += elm.o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++clean:
++ rm -f $(SOBJS) $(OBJS)
++
++distclean: clean
++ rm -f $(LIB) core *.bak .depend
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
++
+diff --git a/arch/arm/cpu/armv7/ti81xx/board.c b/arch/arm/cpu/armv7/ti81xx/board.c
+new file mode 100644
+index 0000000..446470d
+--- /dev/null
++++ b/arch/arm/cpu/armv7/ti81xx/board.c
+@@ -0,0 +1,66 @@
++/*
++ *
++ * Common board functions for AM33XX based boards.
++ *
++ * (C) Copyright 2011
++ * Texas Instruments, <www.ti.com>
++ *
++ * Derived from arch/arm/cpu/armv7/omap3/board.c by
++ * Sunil Kumar <sunilsaini05@gmail.com>
++ * Shashi Ranjan <shashiranjanmca05@gmail.com>
++ *
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#include <common.h>
++#include <asm/arch/sys_proto.h>
++#include <asm/omap_common.h>
++
++#ifdef CONFIG_SPL_BUILD
++/*
++* We use static variables because global data is not ready yet.
++* Initialized data is available in SPL right from the beginning.
++* We would not typically need to save these parameters in regular
++* U-Boot. This is needed only in SPL at the moment.
++*/
++u32 ti81xx_boot_device = BOOT_DEVICE_NAND;
++
++/* auto boot mode detection is not possible for AM335X - hard code */
++u32 omap_boot_mode(void)
++{
++ switch (omap_boot_device()) {
++ case BOOT_DEVICE_MMC2:
++ return MMCSD_MODE_RAW;
++ case BOOT_DEVICE_MMC1:
++ return MMCSD_MODE_FAT;
++ break;
++ case BOOT_DEVICE_NAND:
++ return NAND_MODE_HW_ECC;
++ break;
++ default:
++ puts("spl: ERROR: unknown device - can't select boot mode\n");
++ hang();
++ }
++}
++
++u32 omap_boot_device(void)
++{
++ return ti81xx_boot_device;
++}
++#endif /* CONFIG_SPL_BUILD */
+diff --git a/arch/arm/cpu/armv7/ti81xx/cache.S b/arch/arm/cpu/armv7/ti81xx/cache.S
+new file mode 100644
+index 0000000..45e61a5
+--- /dev/null
++++ b/arch/arm/cpu/armv7/ti81xx/cache.S
+@@ -0,0 +1,113 @@
++/*
++ * lowlevel_init.S
++ *
++ * TI81XX low level initialization.
++ *
++ * Copyright (C) 2010, Texas Instruments, Incorporated
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++.global invalidate_dcache
++.global l2_cache_enable
++.global l2_cache_disable
++
++/*
++ * invalidate_dcache()
++ *
++ * Invalidate the whole D-cache.
++ *
++ * Corrupted registers: r0-r5, r7, r9-r11
++ *
++ * - mm - mm_struct describing address space
++ */
++invalidate_dcache:
++ stmfd r13!, {r0 - r5, r7, r9 - r12, r14}
++
++ mrc p15, 1, r0, c0, c0, 1 @ read clidr
++ ands r3, r0, #0x7000000 @ extract loc from clidr
++ mov r3, r3, lsr #23 @ left align loc bit field
++ beq finished_inval @ if loc is 0, then no need to
++ @ clean
++ mov r10, #0 @ start clean at cache level 0
++inval_loop1:
++ add r2, r10, r10, lsr #1 @ work out 3x current cache
++ @ level
++ mov r1, r0, lsr r2 @ extract cache type bits from
++ @ clidr
++ and r1, r1, #7 @ mask of the bits for current
++ @ cache only
++ cmp r1, #2 @ see what cache we have at
++ @ this level
++ blt skip_inval @ skip if no cache, or just
++ @ i-cache
++ mcr p15, 2, r10, c0, c0, 0 @ select current cache level
++ @ in cssr
++ mov r2, #0 @ operand for mcr SBZ
++ mcr p15, 0, r2, c7, c5, 4 @ flush prefetch buffer to
++ @ sych the new cssr&csidr,
++ @ with armv7 this is 'isb',
++ @ but we compile with armv5
++ mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
++ and r2, r1, #7 @ extract the length of the
++ @ cache lines
++ add r2, r2, #4 @ add 4 (line length offset)
++ ldr r4, =0x3ff
++ ands r4, r4, r1, lsr #3 @ find maximum number on the
++ @ way size
++ clz r5, r4 @ find bit position of way
++ @ size increment
++ ldr r7, =0x7fff
++ ands r7, r7, r1, lsr #13 @ extract max number of the
++ @ index size
++inval_loop2:
++ mov r9, r4 @ create working copy of max
++ @ way size
++inval_loop3:
++ orr r11, r10, r9, lsl r5 @ factor way and cache number
++ @ into r11
++ orr r11, r11, r7, lsl r2 @ factor index number into r11
++ mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
++ subs r9, r9, #1 @ decrement the way
++ bge inval_loop3
++ subs r7, r7, #1 @ decrement the index
++ bge inval_loop2
++skip_inval:
++ add r10, r10, #2 @ increment cache number
++ cmp r3, r10
++ bgt inval_loop1
++finished_inval:
++ mov r10, #0 @ swith back to cache level 0
++ mcr p15, 2, r10, c0, c0, 0 @ select current cache level
++ @ in cssr
++ mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer,
++ @ with armv7 this is 'isb',
++ @ but we compile with armv5
++ ldmfd r13!, {r0 - r5, r7, r9 - r12, pc}
++
++
++l2_cache_enable:
++ push {r0, r1, r2, lr}
++ mrc 15, 0, r3, cr1, cr0, 1
++ orr r3, r3, #2
++ mcr 15, 0, r3, cr1, cr0, 1
++ pop {r1, r2, r3, pc}
++
++
++l2_cache_disable:
++ push {r0, r1, r2, lr}
++ mrc 15, 0, r3, cr1, cr0, 1
++ bic r3, r3, #2
++ mcr 15, 0, r3, cr1, cr0, 1
++ pop {r1, r2, r3, pc}
++
+diff --git a/arch/arm/cpu/armv7/ti81xx/config.mk b/arch/arm/cpu/armv7/ti81xx/config.mk
+new file mode 100644
+index 0000000..4cd7e82
+--- /dev/null
++++ b/arch/arm/cpu/armv7/ti81xx/config.mk
+@@ -0,0 +1,28 @@
++#
++# Copyright 2011 Linaro Limited
++# See file CREDITS for list of people who contributed to this
++# project.
++#
++# (C) Copyright 2010
++# Texas Instruments, <www.ti.com>
++#
++# 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
++#
++ifdef CONFIG_SPL_BUILD
++ALL-y += $(OBJTREE)/MLO
++else
++ALL-y += $(obj)u-boot.img
++endif
+diff --git a/arch/arm/cpu/armv7/ti81xx/elm.c b/arch/arm/cpu/armv7/ti81xx/elm.c
+new file mode 100644
+index 0000000..fbf3348
+--- /dev/null
++++ b/arch/arm/cpu/armv7/ti81xx/elm.c
+@@ -0,0 +1,238 @@
++/*
++ * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
++ * Mansoor Ahamed <mansoor.ahamed@ti.com>
++ *
++ * BCH Error Location Module (ELM) support.
++ *
++ * NOTE:
++ * 1. Supports only continuous mode. Dont see need for page mode in uboot
++ * 2. Supports only syndrome polynomial 0. i.e. poly local variable is
++ * always set to ELM_DEFAULT_POLY. Dont see need for other polynomial
++ * sets in uboot
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <asm/io.h>
++#include <asm/errno.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/nand.h>
++
++#define ELM_DEFAULT_POLY (0)
++
++struct elm *elm_cfg;
++
++/**
++ * elm_load_syndromes - Load BCH syndromes based on nibble selection
++ * @syndrome: BCH syndrome
++ * @nibbles:
++ * @poly: Syndrome Polynomial set to use
++ *
++ * Load BCH syndromes based on nibble selection
++ */
++static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
++{
++ u32 *ptr;
++ u32 val;
++
++ /* reg 0 */
++ ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[0];
++ val = syndrome[0] | (syndrome[1] << 8) | (syndrome[2] << 16) |
++ (syndrome[3] << 24);
++ writel(val, ptr);
++ /* reg 1 */
++ ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[1];
++ val = syndrome[4] | (syndrome[5] << 8) | (syndrome[6] << 16) |
++ (syndrome[7] << 24);
++ writel(val, ptr);
++
++ /* BCH 8-bit with 26 nibbles (4*8=32) */
++ if (nibbles > 13) {
++ /* reg 2 */
++ ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2];
++ val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) |
++ (syndrome[11] << 24);
++ writel(val, ptr);
++ /* reg 3 */
++ ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[3];
++ val = syndrome[12] | (syndrome[13] << 8) | (syndrome[14] << 16) |
++ (syndrome[15] << 24);
++ writel(val, ptr);
++ }
++
++ /* BCH 16-bit with 52 nibbles (7*8=56) */
++ if (nibbles > 26) {
++ /* reg 4 */
++ ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4];
++ val = syndrome[16] | (syndrome[17] << 8) | (syndrome[18] << 16) |
++ (syndrome[19] << 24);
++ writel(val, ptr);
++
++ /* reg 5 */
++ ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[5];
++ val = syndrome[20] | (syndrome[21] << 8) | (syndrome[22] << 16) |
++ (syndrome[23] << 24);
++ writel(val, ptr);
++
++ /* reg 6 */
++ ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6];
++ val = syndrome[24] | (syndrome[25] << 8) | (syndrome[26] << 16) |
++ (syndrome[27] << 24);
++ writel(val, ptr);
++ }
++
++#ifndef CONFIG_TI816X
++ /* BCH 4-bit with 13 nibbles (2*8 = 16) */
++ writel(syndrome[0],
++ &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[0]);
++ writel(syndrome[1],
++ &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[1]);
++
++ /* BCH 8-bit with 26 nibbles (4*8=32) */
++ if (nibbles > 13) {
++ writel(syndrome[2],
++ &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2]);
++ writel(syndrome[3],
++ &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[3]);
++ }
++
++ /* BCH 16-bit with 52 nibbles (7*8=56) */
++ if (nibbles > 26) {
++ /* do not start processing here */
++ syndrome[6] &= 0x0000FFFF;
++
++ writel(syndrome[4],
++ &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4]);
++ writel(syndrome[5],
++ &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[5]);
++ writel(syndrome[6],
++ &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]);
++
++ }
++#endif
++}
++
++/**
++ * elm_check_errors - Check for BCH errors and return error locations
++ * @syndrome: BCH syndrome
++ * @nibbles:
++ * @error_count: Returns number of errrors in the syndrome
++ * @error_locations: Returns error locations (in decimal) in this array
++ *
++ * Check the provided syndrome for BCH errors and return error count
++ * and locations in the array passed. Returns -1 if error is not correctable,
++ * else returns 0
++ */
++int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
++ u32 *error_locations)
++{
++ u8 poly = ELM_DEFAULT_POLY;
++ s8 i;
++ u32 location_status;
++
++ elm_load_syndromes(syndrome, nibbles, poly);
++
++ /* start processing */
++ writel((readl(&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6])
++ | ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID),
++ &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]);
++
++ /* wait for processing to complete */
++ while((readl(&elm_cfg->irqstatus) & (0x1 << poly)) != 0x1);
++ /* clear status */
++ writel((readl(&elm_cfg->irqstatus) | (0x1 << poly)), &elm_cfg->irqstatus);
++
++ /* check if correctable */
++ location_status = readl(&elm_cfg->error_location[poly].location_status);
++ if (!(location_status & ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK))
++ return -1;
++
++ /* get error count */
++ *error_count = readl(&elm_cfg->error_location[poly].location_status) &
++ ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK;
++
++ for (i = 0; i < *error_count; i++)
++ error_locations[i] =
++ readl(&elm_cfg->error_location[poly].error_location_x[i]);
++
++ return 0;
++}
++
++
++/**
++ * elm_config - Configure ELM module
++ * @level: 4 / 8 / 16 bit BCH
++ * @buffer_size: Buffer size in bytes
++ *
++ * Configure ELM module based on BCH level and buffer size passed.
++ * Set mode as continuous mode.
++ * Currently we are using only syndrome 0 and syndromes 1 to 6 are not used.
++ * Also, the mode is set only for syndrome 0
++ */
++/* int elm_config(enum bch_level level, u32 buffer_size) */
++int elm_config(enum bch_level level)
++{
++ u32 val;
++ u8 poly = ELM_DEFAULT_POLY;
++ u32 buffer_size= 0x7FF;
++
++ /* config size and level */
++ val = (u32)(level) & ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK;
++ val |= ((buffer_size << ELM_LOCATION_CONFIG_ECC_SIZE_POS) &
++ ELM_LOCATION_CONFIG_ECC_SIZE_MASK);
++ writel(val, &elm_cfg->location_config);
++
++ /* config continous mode */
++ /* enable interrupt generation for syndrome polynomial set */
++ writel((readl(&elm_cfg->irqenable) | (0x1 << poly)), &elm_cfg->irqenable);
++ /* set continuous mode for the syndrome polynomial set */
++ writel((readl(&elm_cfg->page_ctrl) & ~(0x1 << poly)), &elm_cfg->page_ctrl);
++
++ return 0;
++}
++
++/**
++ * elm_reset - Do a soft reset of ELM
++ *
++ * Perform a soft reset of ELM and return after reset is done.
++ */
++void elm_reset(void)
++{
++ /* initiate reset */
++ writel((readl(&elm_cfg->sysconfig) | ELM_SYSCONFIG_SOFTRESET),
++ &elm_cfg->sysconfig);
++
++ /* wait for reset complete and normal operation */
++ while((readl(&elm_cfg->sysstatus) & ELM_SYSSTATUS_RESETDONE) !=
++ ELM_SYSSTATUS_RESETDONE);
++}
++
++/**
++ * elm_init - Initialize ELM module
++ *
++ * Initialize ELM support. Currently it does only base address init
++ * and ELM reset.
++ */
++void elm_init( void )
++{
++ elm_cfg = (struct elm *)ELM_BASE;
++ elm_reset();
++}
++
+diff --git a/arch/arm/cpu/armv7/ti81xx/lowlevel_init.S b/arch/arm/cpu/armv7/ti81xx/lowlevel_init.S
+new file mode 100644
+index 0000000..359cd64
+--- /dev/null
++++ b/arch/arm/cpu/armv7/ti81xx/lowlevel_init.S
+@@ -0,0 +1,464 @@
++/*
++ * lowlevel_init.S
++ *
++ * TI81XX low level initialization.
++ *
++ * Copyright (C) 2010, Texas Instruments, Incorporated
++ *
++ * Initial Code by:
++ * Mansoor Ahamed <mansoor.ahamed@ti.com>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <config.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/clocks_ti816x.h>
++
++_TEXT_BASE:
++ .word CONFIG_SYS_TEXT_BASE /* Load address (RAM) */
++
++.global save_boot_params
++save_boot_params:
++#ifdef CONFIG_SPL_BUILD
++ ldr r4, =ti81xx_boot_device
++ ldr r5, [r0, #BOOT_DEVICE_OFFSET]
++ and r5, r5, #BOOT_DEVICE_MASK
++ str r5, [r4]
++#endif
++ bx lr
++
++#ifdef CONFIG_NOR_BOOT
++/* GPMC CFG values for Spansion S29GL512P11TFI010 & S29GL512N11TFI010
++ * This should work for most NOR, else we might have to move
++ * these defines to evm.h
++ * Values used here are for nominal speed, tweak it to improve performance
++ */
++#define SPNOR_GPMC_CONFIG1 0x00001010
++#define SPNOR_GPMC_CONFIG2 0x00101080
++#define SPNOR_GPMC_CONFIG3 0x00020201
++#define SPNOR_GPMC_CONFIG4 0x0f031003
++#define SPNOR_GPMC_CONFIG5 0x000f1111
++#define SPNOR_GPMC_CONFIG6 0x0f030080
++#ifndef CONFIG_AM335X
++#define SPNOR_GPMC_CONFIG7 0x00000C08
++#else
++#define SPNOR_GPMC_CONFIG7 0x00000F08
++#endif
++/* default gpmc pad config valaue */
++#define GPMC_PAD_DEF_VAL (0x00000001)
++
++/* GPIO clk control */
++#define GPIO0_CFG_VAL 0xFFEFFFFF
++#define GPIO0_CLKCTRL_VAL 0x102
++
++#define SRAM1_START (0x40400000)
++#define RAM_ADDR_MASK (0xC0000000)
++
++/**************************************************************************
++ * cpy_nor_gpmc_code: relocates nor gpmc init code into ocmc0 where its
++ * safer to execute
++ * R2 is loaded wtih size of data to be copied, this should be calculated
++ * if we are modifying nor_gpmc_init()
++ *************************************************************************/
++.global cpy_nor_gpmc_code
++cpy_nor_gpmc_code:
++ stmfd sp!, {r0 - r10}
++ /* Copy NOR GPMC init code into SRAM */
++ adr r0, nor_gpmc_init /* get addr of nor gpmc init code */
++ mov r2, #640 /* r2 <- copy size(% by 32 bytes:r3-r10 (8) regs used) */
++ ldr r1, sram_pc_start /* r1 <- dest address (passed in) */
++ add r2, r2, r0 /* r2 <- source end address */
++next2:
++ ldmia r0!, {r3 - r10} /* copy from source address [r0] */
++ stmia r1!, {r3 - r10} /* copy to target address [r1] */
++ cmp r0, r2 /* until source end address [r2] */
++ bne next2
++ ldmfd sp!, {r0 - r10}
++ mov pc, lr /* back to caller */
++
++/*****************************************************************************
++ * nor_gpmc_init: - Init GPMC for NOR on CS0, executed from SRAM.
++ *
++ * R0 - used for saving SP, hence do not use it anywhere
++ ****************************************************************************/
++.global nor_gpmc_init
++nor_gpmc_init:
++ mov r0, sp
++ ldr sp, SRAM_STACK_GPMC
++ stmfd sp!, {r0 - r5}
++ stmfd sp!, {ip}
++
++ /****** GPMC out of reset ******/
++ ldr r5, cm_alwon_gpmc_clkctrl_addr
++ mov r2, #0x2
++ str r2, [r5]
++ /* wait for gpmc enable to settle */
++gpmc_next_wait0:
++ ldr r2, [r5]
++ ands r2, r2, #0x00030000
++ cmp r2, #0
++ bne gpmc_next_wait0
++#ifndef CONFIG_AM335X
++ /****** GPIO out of reset *******/
++ ldr r5, cm_alwon_gpio_clkctrl_addr
++ ldr r2, cm_alwon_gpio_clkctrl_val
++ str r2, [r5]
++ /* wait for gpio enable to settle */
++gpio_next_wait0:
++ ldr r2, [r5]
++ ands r2, r2, #0x3
++ cmp r2, #0x2
++ bne gpio_next_wait0
++
++ /****** Set GPIO-20 to low */
++ ldr r5, gpio_data_addr
++ mov r2, #0x0
++ str r2, [r5]
++ ldr r5, gpio_cfg_addr
++ ldr r2, gpio_cfg_val
++ str r2, [r5]
++#endif
++ /***** GPMC CS0 init ******/
++ /* disable CS0 */
++ ldr r5, gpmc_cfg7_addr
++ mov r2, #0
++ str r2, [r5]
++ /* wait for disable to settle */
++ mov r3, #0x900
++gpmc_next_wait1:
++ sub r3, r3, #1
++ cmp r3, #1
++ bne gpmc_next_wait1
++
++ /* set gpmc config registers */
++ ldr r5, gpmc_cfg1_addr
++ ldr r2, gpmc_cfg1_val
++ str r2, [r5]
++ ldr r5, gpmc_cfg2_addr
++ ldr r2, gpmc_cfg2_val
++ str r2, [r5]
++ ldr r5, gpmc_cfg3_addr
++ ldr r2, gpmc_cfg3_val
++ str r2, [r5]
++ ldr r5, gpmc_cfg4_addr
++ ldr r2, gpmc_cfg4_val
++ str r2, [r5]
++ ldr r5, gpmc_cfg5_addr
++ ldr r2, gpmc_cfg5_val
++ str r2, [r5]
++ ldr r5, gpmc_cfg6_addr
++ ldr r2, gpmc_cfg6_val
++ str r2, [r5]
++ ldr r5, gpmc_cfg7_addr
++ ldr r2, gpmc_cfg7_val
++ str r2, [r5]
++#ifndef CONFIG_AM335X
++ /* do pin muxing */
++ mov r2, #0x1
++ ldr r5, gpmc_a12_addr
++ str r2, [r5]
++ ldr r5, gpmc_a13_addr
++ str r2, [r5]
++ ldr r5, gpmc_a14_addr
++ str r2, [r5]
++ ldr r5, gpmc_a15_addr
++ str r2, [r5]
++ ldr r5, sc1_rst_addr /* gpmc_a15 used in two pins */
++ str r2, [r5]
++ ldr r5, gpmc_a16_addr
++ str r2, [r5]
++ ldr r5, gpmc_a17_addr
++ str r2, [r5]
++ ldr r5, gpmc_a18_addr
++ str r2, [r5]
++ ldr r5, gpmc_a19_addr
++ str r2, [r5]
++ ldr r5, gpmc_a20_addr
++ str r2, [r5]
++ ldr r5, gpmc_a21_addr
++ str r2, [r5]
++ ldr r5, gpmc_a22_addr
++ str r2, [r5]
++ ldr r5, gpmc_a23_addr
++ mov r2, #0x2
++ str r2, [r5]
++ mov r2, #0x1
++ ldr r5, gpmc_a24_addr
++ str r2, [r5]
++ ldr r5, gpmc_a25_addr
++ str r2, [r5]
++ ldr r5, gpmc_a27_addr
++ str r2, [r5]
++#else
++ mov r2, #0x9 /* MODE 1, PULLUP/DOWN Disabled */
++ ldr r5, gpmc_a12_addr
++ str r2, [r5]
++ ldr r5, gpmc_a13_addr
++ str r2, [r5]
++ ldr r5, gpmc_a14_addr
++ str r2, [r5]
++ ldr r5, gpmc_a15_addr
++ str r2, [r5]
++ ldr r5, gpmc_a16_addr
++ str r2, [r5]
++ ldr r5, gpmc_a17_addr
++ str r2, [r5]
++ ldr r5, gpmc_a18_addr
++ str r2, [r5]
++ ldr r5, gpmc_a19_addr
++ str r2, [r5]
++ mov r2, #0x4 /* MODE 4, */
++ ldr r5, gpmc_a20_addr
++ str r2, [r5]
++ ldr r5, gpmc_a21_addr
++ str r2, [r5]
++ ldr r5, gpmc_a22_addr
++ str r2, [r5]
++#endif
++ /* enable CS0 */
++ ldr r5, gpmc_cfg7_addr
++ ldr r2, gpmc_cfg7_val
++ orr r2, r2, #0x40
++ str r2, [r5]
++ /* wait for enable to settle */
++ mov r3, #0x900
++gpmc_next_wait2:
++ sub r3, r3, #1
++ cmp r3, #1
++ bne gpmc_next_wait2
++
++ ldmfd sp!, {ip}
++ ldmfd sp!, {r0 - r5}
++ mov sp, r0
++ mov pc, lr /* back to caller*/
++
++/* these constants need to be close for PIC code */
++/* The Nor has to be in the Flash Base CS0 for this condition to happen */
++cm_alwon_gpmc_clkctrl_addr:
++ .word CM_ALWON_GPMC_CLKCTRL
++cm_alwon_gpio_clkctrl_addr:
++ .word CM_ALWON_GPIO_0_CLKCTRL
++cm_alwon_gpio_clkctrl_val:
++ .word GPIO0_CLKCTRL_VAL
++gpio_cfg_addr:
++ .word (GPIO0_BASE + 0x134)
++gpio_data_addr:
++ .word (GPIO0_BASE + 0x13C)
++gpio_cfg_val:
++ .word GPIO0_CFG_VAL
++sram_pc_start:
++ .word (SRAM0_START + 0x10000)
++SRAM_STACK_GPMC:
++ .word (SRAM0_START + 0x1000)
++gpmc_cfg1_addr:
++ .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG1)
++gpmc_cfg2_addr:
++ .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG2)
++gpmc_cfg3_addr:
++ .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG3)
++gpmc_cfg4_addr:
++ .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG4)
++gpmc_cfg5_addr:
++ .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG5)
++gpmc_cfg6_addr:
++ .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG6)
++gpmc_cfg7_addr:
++ .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG7)
++
++gpmc_cfg1_val:
++ .word SPNOR_GPMC_CONFIG1
++gpmc_cfg2_val:
++ .word SPNOR_GPMC_CONFIG2
++gpmc_cfg3_val:
++ .word SPNOR_GPMC_CONFIG3
++gpmc_cfg4_val:
++ .word SPNOR_GPMC_CONFIG4
++gpmc_cfg5_val:
++ .word SPNOR_GPMC_CONFIG5
++gpmc_cfg6_val:
++ .word SPNOR_GPMC_CONFIG6
++gpmc_cfg7_val:
++ .word SPNOR_GPMC_CONFIG7
++
++/* pad config reg addresses and values */
++gpmc_a12_addr:
++ .word GPMC_A12
++gpmc_a13_addr:
++ .word GPMC_A13
++gpmc_a14_addr:
++ .word GPMC_A14
++gpmc_a15_addr:
++ .word GPMC_A15
++gpmc_a16_addr:
++ .word GPMC_A16
++gpmc_a17_addr:
++ .word GPMC_A17
++gpmc_a18_addr:
++ .word GPMC_A18
++gpmc_a19_addr:
++ .word GPMC_A19
++gpmc_a20_addr:
++ .word GPMC_A20
++gpmc_a21_addr:
++ .word GPMC_A21
++gpmc_a22_addr:
++ .word GPMC_A22
++#ifndef CONFIG_AM335X
++gpmc_a23_addr:
++ .word GPMC_A23
++gpmc_a24_addr:
++ .word GPMC_A24
++gpmc_a25_addr:
++ .word GPMC_A25
++gpmc_a27_addr:
++ .word GPMC_A27
++sc1_rst_addr:
++ .word SC1_RST
++#endif
++ram_addr_mask:
++ .word RAM_ADDR_MASK
++#endif
++
++/*****************************************************************************
++ * lowlevel_init: - Platform low level init.
++ * Corrupted Register : r0, r1, r2, r3, r4, r5, r6
++ ****************************************************************************/
++.globl lowlevel_init
++lowlevel_init:
++
++ /* The link register is saved in ip by start.S */
++ mov r6, ip
++ /* check if we are already running from RAM */
++ ldr r2, _lowlevel_init
++ ldr r3, _TEXT_BASE
++ sub r4, r2, r3
++ sub r0, pc, r4
++ /* require dummy instr or subtract pc by 4 instead i'm doing stack init */
++ ldr sp, SRAM_STACK
++mark1:
++ ldr r5, _mark1
++ sub r5, r5, r2 /* bytes between mark1 and lowlevel_init */
++ sub r0, r0, r5 /* r0 <- _start w.r.t current place of execution */
++ mov r10, #0x0 /* r10 has in_ddr used by s_init() */
++
++#ifdef CONFIG_NOR_BOOT
++ cmp r0, #0x08000000 /* check for running from NOR */
++ beq ocmc_init_start /* if == then running from NOR */
++ ands r0, r0, #0xC0000000 /* MSB 2 bits <> 0 then we are in ocmc or DDR */
++ cmp r0, #0x40000000 /* if running from ocmc */
++ beq nor_init_start /* if == skip ocmc init and jump to nor init */
++ mov r10, #0x01 /* if <> we are running from DDR hence skip ddr init */
++ /* by setting in_ddr to 1 */
++ b s_init_start /* and jump to s_init */
++#else
++ ands r0, r0, #0xC0000000 /* MSB 2 bits <> 0 then we are in ocmc or DDR */
++ cmp r0, #0x80000000
++ bne s_init_start
++ mov r10, #0x01
++ b s_init_start
++#endif
++
++#ifdef CONFIG_NOR_BOOT
++ocmc_init_start:
++ /**** enable ocmc 0 ****/
++ /* CLKSTCTRL */
++ ldr r5, cm_alwon_ocmc_0_clkstctrl_addr
++ mov r2, #0x2
++ str r2, [r5]
++ /* wait for gpmc enable to settle */
++ocmc0_wait0:
++ ldr r2, [r5]
++#ifdef CONFIG_AM335X
++ ands r2, r2, #0x00000100
++ cmp r2, #0x00000100
++#else
++ ands r2, r2, #0x00000010
++ cmp r2, #0x00000010
++#endif
++ bne ocmc0_wait0
++ /* CLKCTRL */
++ ldr r5, cm_alwon_ocmc_0_clkctrl_addr
++ mov r2, #0x2
++ str r2, [r5]
++ /* wait for gpmc enable to settle */
++ocmc0_wait1:
++ ldr r2, [r5]
++ ands r2, r2, #0x00030000
++ cmp r2, #0
++ bne ocmc0_wait1
++
++#ifndef CONFIG_AM335X
++ /**** enable ocmc 1 ****/
++ /* CLKSTCTRL */
++ ldr r5, cm_alwon_ocmc_1_clkstctrl_addr
++ mov r2, #0x2
++ str r2, [r5]
++ /* wait for gpmc enable to settle */
++ocmc1_wait0:
++ ldr r2, [r5]
++ ands r2, r2, #0x00000100
++ cmp r2, #0x00000100
++ bne ocmc1_wait0
++ /* CLKCTRL */
++ ldr r5, cm_alwon_ocmc_1_clkctrl_addr
++ mov r2, #0x2
++ str r2, [r5]
++ /* wait for gpmc enable to settle */
++ocmc1_wait1:
++ ldr r2, [r5]
++ ands r2, r2, #0x00030000
++ cmp r2, #0
++ bne ocmc1_wait1
++#endif
++nor_init_start:
++ /* gpmc init */
++ bl cpy_nor_gpmc_code /* copy nor gpmc init code to sram */
++ mov r0, pc
++ add r0, r0, #12 /* 12 is for next three instructions */
++ mov lr, r0 /* gpmc init code in sram should return to s_init_start */
++ ldr r0, sram_pc_start
++ mov pc, r0 /* transfer ctrl to nor_gpmc_init() in sram */
++#endif
++
++s_init_start:
++ mov r0, r10 /* passing in_ddr in r0 */
++ bl s_init
++ /* back to arch calling code */
++ mov pc, r6
++ /* the literal pools origin */
++ .ltorg
++
++#ifdef CONFIG_NOR_BOOT
++cm_alwon_ocmc_0_clkstctrl_addr:
++ .word CM_ALWON_OCMC_0_CLKSTCTRL
++cm_alwon_ocmc_0_clkctrl_addr:
++ .word CM_ALWON_OCMC_0_CLKCTRL
++#ifndef CONFIG_AM335X
++cm_alwon_ocmc_1_clkstctrl_addr:
++ .word CM_ALWON_OCMC_1_CLKSTCTRL
++cm_alwon_ocmc_1_clkctrl_addr:
++ .word CM_ALWON_OCMC_1_CLKCTRL
++#endif
++#endif
++SRAM_STACK:
++ .word LOW_LEVEL_SRAM_STACK
++
++_mark1:
++ .word mark1
++_lowlevel_init:
++ .word lowlevel_init
++_s_init_start:
++ .word s_init_start
++
+diff --git a/arch/arm/cpu/armv7/ti81xx/mem.c b/arch/arm/cpu/armv7/ti81xx/mem.c
+new file mode 100644
+index 0000000..e7f1cf7
+--- /dev/null
++++ b/arch/arm/cpu/armv7/ti81xx/mem.c
+@@ -0,0 +1,104 @@
++/*
++ * (C) Copyright 2010
++ * Texas Instruments, <www.ti.com>
++ *
++ * Author :
++ * Mansoor Ahamed <mansoor.ahamed@ti.com>
++ *
++ * Initial Code from:
++ * Manikandan Pillai <mani.pillai@ti.com>
++ * Richard Woodruff <r-woodruff2@ti.com>
++ * Syed Mohammed Khasim <khasim@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <asm/io.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/mem.h>
++#include <asm/arch/sys_proto.h>
++#include <command.h>
++
++struct gpmc *gpmc_cfg;
++
++#if defined(CONFIG_CMD_NAND)
++static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
++ M_NAND_GPMC_CONFIG1,
++ M_NAND_GPMC_CONFIG2,
++ M_NAND_GPMC_CONFIG3,
++ M_NAND_GPMC_CONFIG4,
++ M_NAND_GPMC_CONFIG5,
++ M_NAND_GPMC_CONFIG6, 0
++};
++
++#define GPMC_CS 0
++
++#endif
++
++
++void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
++ u32 size)
++{
++ writel(0, &cs->config7);
++ sdelay(1000);
++ /* Delay for settling */
++ writel(gpmc_config[0], &cs->config1);
++ writel(gpmc_config[1], &cs->config2);
++ writel(gpmc_config[2], &cs->config3);
++ writel(gpmc_config[3], &cs->config4);
++ writel(gpmc_config[4], &cs->config5);
++ writel(gpmc_config[5], &cs->config6);
++ /* Enable the config */
++ writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) |
++ (1 << 6)), &cs->config7);
++ sdelay(2000);
++}
++
++/*****************************************************
++ * gpmc_init(): init gpmc bus
++ * Init GPMC for x16, MuxMode (SDRAM in x32).
++ * This code can only be executed from SRAM or SDRAM.
++ *****************************************************/
++void gpmc_init(void)
++{
++ /* putting a blanket check on GPMC based on ZeBu for now */
++ gpmc_cfg = (struct gpmc *)GPMC_BASE;
++
++#if defined(CONFIG_CMD_NAND) || defined(CONFIG_CMD_ONENAND)
++ const u32 *gpmc_config = NULL;
++ u32 base = 0;
++ u32 size = 0;
++#endif
++ /* global settings */
++ writel(0x00000008, &gpmc_cfg->sysconfig);
++ writel(0x00000100, &gpmc_cfg->irqstatus);
++ writel(0x00000200, &gpmc_cfg->irqenable);
++ writel(0x00000012, &gpmc_cfg->config);
++ /*
++ * Disable the GPMC0 config set by ROM code
++ */
++ writel(0, &gpmc_cfg->cs[0].config7);
++ sdelay(1000);
++
++#if defined(CONFIG_CMD_NAND) /* CS 0 */
++ gpmc_config = gpmc_m_nand;
++
++ base = PISMO1_NAND_BASE;
++ size = PISMO1_NAND_SIZE;
++ enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
++#endif
++}
+diff --git a/arch/arm/cpu/armv7/ti81xx/sys_info.c b/arch/arm/cpu/armv7/ti81xx/sys_info.c
+new file mode 100644
+index 0000000..c32dfad
+--- /dev/null
++++ b/arch/arm/cpu/armv7/ti81xx/sys_info.c
+@@ -0,0 +1,161 @@
++/*
++ * (C) Copyright 2009
++ * Texas Instruments, <www.ti.com>
++ *
++ * Author :
++ * Manikandan Pillai <mani.pillai@ti.com>
++ *
++ * Derived from Beagle Board and 3430 SDP code by
++ * Richard Woodruff <r-woodruff2@ti.com>
++ * Syed Mohammed Khasim <khasim@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <asm/io.h>
++#include <asm/arch/sys_proto.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/clock.h>
++
++extern omap3_sysinfo sysinfo;
++
++/******************************************
++ * get_cpu_rev(void) - extract rev info
++ ******************************************/
++u32 get_cpu_rev(void)
++{
++ u32 id;
++ u32 rev;
++
++ id = readl(DEVICE_ID);
++ rev = (id >> 28) & 0xff;
++ return rev;
++}
++
++/******************************************
++ * get_cpu_type(void) - extract cpu info
++ ******************************************/
++u32 get_cpu_type(void)
++{
++ u32 id = 0;
++ u32 partnum;
++
++ id = readl(DEVICE_ID);
++ partnum = (id >> 12) & 0xffff;
++
++ return partnum;
++}
++
++/*************************************************************************
++ * get_board_rev() - setup to pass kernel board revision information
++ * returns:(bit[0-3] sub version, higher bit[7-4] is higher version)
++ *************************************************************************/
++u32 get_board_rev(void)
++{
++ return 0x0;
++}
++
++/*************************************************************
++ * get_device_type(): tell if GP/HS/EMU/TST
++ *************************************************************/
++u32 get_device_type(void)
++{
++ int mode;
++ mode = __raw_readl(CONTROL_STATUS) & (DEVICE_MASK);
++ return(mode >>= 8);
++}
++
++/************************************************
++ * get_sysboot_value(void) - return SYS_BOOT[4:0]
++ ************************************************/
++u32 get_sysboot_value(void)
++{
++ int mode;
++ mode = __raw_readl(CONTROL_STATUS) & (SYSBOOT_MASK);
++ return mode;
++}
++
++#ifdef CONFIG_DISPLAY_CPUINFO
++/**
++ * Print CPU information
++ */
++int print_cpuinfo (void)
++{
++ char *cpu_s, *sec_s;
++ int arm_freq, ddr_freq;
++
++ switch (get_cpu_type()) {
++ case TI8168:
++ cpu_s = "8168";
++ break;
++ default:
++ cpu_s = "Unknown cpu type";
++ break;
++ }
++
++ switch (get_device_type()) {
++ case TST_DEVICE:
++ sec_s = "TST";
++ break;
++ case EMU_DEVICE:
++ sec_s = "EMU";
++ break;
++ case HS_DEVICE:
++ sec_s = "HS";
++ break;
++ case GP_DEVICE:
++ sec_s = "GP";
++ break;
++ default:
++ sec_s = "?";
++ }
++
++ printf("TI%s-%s rev 1.%d\n",
++ cpu_s, sec_s, get_cpu_rev());
++ printf("\n");
++
++ /* ARM and DDR frequencies */
++
++#ifdef CONFIG_TI816X
++ /* f0 = ((N * K) / (FREQ * P * M)) * fr */
++
++ arm_freq = (((MAIN_N * FAPLL_K * OSC_FREQ)/
++ ( MAIN_P * MAIN_MDIV2 )))/SYSCLK_2_DIV;
++
++ /*
++ * If the fractional part (MAIN_FRACFREQ2i) in non zero then the formula
++ * is : fo = ((N * K) / ( (INTFREQ + FRACFREQ) * p * M)) * fr
++ *
++ * For 13.824, INTFREQ = 0xD and FRACFREQ = 0xD2F1A9
++ * We are supposed to divide FRACFREQ by 0x1000000
++ *
++ * Due to overflow of values on multiplying by 0x1000000
++ * we discard the least 8 bits
++ */
++ arm_freq = (arm_freq * (0x1000000 >> 8));
++ arm_freq=arm_freq/((MAIN_INTFREQ2 * 0x1000000 + MAIN_FRACFREQ2)>>8);
++
++ ddr_freq = ((DDR_N * OSC_FREQ)/DDR_MDIV1);
++
++ printf("ARM clk: %dMHz\n", arm_freq);
++ printf("DDR clk: %dMHz\n", ddr_freq);
++ printf("\n");
++#endif
++
++ return 0;
++}
++#endif /* CONFIG_DISPLAY_CPUINFO */
+diff --git a/arch/arm/cpu/armv7/u-boot.lds b/arch/arm/cpu/armv7/u-boot.lds
+index 40ecf78..c132e33 100644
+--- a/arch/arm/cpu/armv7/u-boot.lds
++++ b/arch/arm/cpu/armv7/u-boot.lds
+@@ -57,11 +57,12 @@ SECTIONS
+
+ __image_copy_end = .;
+
++ . = ALIGN(4);
++ __rel_dyn_start = .;
+ .rel.dyn : {
+- __rel_dyn_start = .;
+ *(.rel*)
+- __rel_dyn_end = .;
+ }
++ __rel_dyn_end = .;
+
+ .dynsym : {
+ __dynsym_start = .;
+@@ -70,7 +71,7 @@ SECTIONS
+
+ _end = .;
+
+- .bss __rel_dyn_start (OVERLAY) : {
++ .bss : {
+ __bss_start = .;
+ *(.bss)
+ . = ALIGN(4);
+diff --git a/arch/arm/include/asm/arch-davinci/emac_defs.h b/arch/arm/include/asm/arch-davinci/emac_defs.h
+index 4a4ee04..3bc9362 100644
+--- a/arch/arm/include/asm/arch-davinci/emac_defs.h
++++ b/arch/arm/include/asm/arch-davinci/emac_defs.h
+@@ -30,11 +30,13 @@
+
+ * Modifications:
+ * ver. 1.0: Sep 2005, TI PSP Team - Created EMAC version for uBoot.
++ * ver. 2.0: May 2010, TI PSP Team - Cleanup, move platform independent
++ * portion to driver header file.
+ *
+ */
+
+-#ifndef _DM644X_EMAC_H_
+-#define _DM644X_EMAC_H_
++#ifndef _EMAC_DEFS_H_
++#define _EMAC_DEFS_H_
+
+ #include <asm/arch/hardware.h>
+
+diff --git a/arch/arm/include/asm/arch-omap3/cpu.h b/arch/arm/include/asm/arch-omap3/cpu.h
+index 08a725d..ec05891 100644
+--- a/arch/arm/include/asm/arch-omap3/cpu.h
++++ b/arch/arm/include/asm/arch-omap3/cpu.h
+@@ -78,7 +78,7 @@ struct ctrl_id {
+
+ /* device type */
+ #define DEVICE_MASK (0x7 << 8)
+-#define SYSBOOT_MASK 0x1F
++#define SYSBOOT_MASK 0x3F
+ #define TST_DEVICE 0x0
+ #define EMU_DEVICE 0x1
+ #define HS_DEVICE 0x2
+@@ -92,6 +92,8 @@ struct ctrl_id {
+ #define GPMC_BASE (OMAP34XX_GPMC_BASE)
+ #define GPMC_CONFIG_CS0 0x60
+ #define GPMC_CONFIG_CS0_BASE (GPMC_BASE + GPMC_CONFIG_CS0)
++#define GPMC_CONFIG_CS1_BASE (GPMC_BASE + GPMC_CONFIG_CS0 + (0x30 * 1))
++#define GPMC_CONFIG_CS2_BASE (GPMC_BASE + GPMC_CONFIG_CS0 + (0x30 * 2))
+
+ #ifndef __KERNEL_STRICT_NAMES
+ #ifndef __ASSEMBLY__
+diff --git a/arch/arm/include/asm/arch-omap3/emac_defs.h b/arch/arm/include/asm/arch-omap3/emac_defs.h
+new file mode 100644
+index 0000000..7f9b194
+--- /dev/null
++++ b/arch/arm/include/asm/arch-omap3/emac_defs.h
+@@ -0,0 +1,59 @@
++/*
++ * 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 _AM3517_EMAC_H_
++#define _AM3517_EMAC_H_
++
++#define EMAC_BASE_ADDR 0x5C010000
++#define EMAC_WRAPPER_BASE_ADDR 0x5C000000
++#define EMAC_WRAPPER_RAM_ADDR 0x5C020000
++#define EMAC_MDIO_BASE_ADDR 0x5C030000
++#define EMAC_HW_RAM_ADDR 0x01E20000
++
++#define EMAC_MDIO_BUS_FREQ 166000000 /* 166 MHZ check */
++#define EMAC_MDIO_CLOCK_FREQ 1000000 /* 2.0 MHz */
++
++/* PHY mask - set only those phy number bits where phy is/can be connected */
++#define EMAC_MDIO_PHY_NUM 0
++#define EMAC_MDIO_PHY_MASK (1 << EMAC_MDIO_PHY_NUM)
++
++
++#define DAVINCI_EMAC_VERSION2
++
++/* SOFTRESET macro definition interferes with emac_regs structure definition */
++#undef SOFTRESET
++
++#endif /* _AM3517_EMAC_H_ */
++
+diff --git a/arch/arm/include/asm/arch-omap3/i2c.h b/arch/arm/include/asm/arch-omap3/i2c.h
+index d2e7488..c7f2b5d 100644
+--- a/arch/arm/include/asm/arch-omap3/i2c.h
++++ b/arch/arm/include/asm/arch-omap3/i2c.h
+@@ -26,39 +26,162 @@
+ #define I2C_BUS_MAX 3
+ #define I2C_DEFAULT_BASE I2C_BASE1
+
+-struct i2c {
+- unsigned short rev; /* 0x00 */
+- unsigned short res1;
+- unsigned short ie; /* 0x04 */
+- unsigned short res2;
+- unsigned short stat; /* 0x08 */
+- unsigned short res3;
+- unsigned short iv; /* 0x0C */
+- unsigned short res4;
+- unsigned short syss; /* 0x10 */
+- unsigned short res4a;
+- unsigned short buf; /* 0x14 */
+- unsigned short res5;
+- unsigned short cnt; /* 0x18 */
+- unsigned short res6;
+- unsigned short data; /* 0x1C */
+- unsigned short res7;
+- unsigned short sysc; /* 0x20 */
+- unsigned short res8;
+- unsigned short con; /* 0x24 */
+- unsigned short res9;
+- unsigned short oa; /* 0x28 */
+- unsigned short res10;
+- unsigned short sa; /* 0x2C */
+- unsigned short res11;
+- unsigned short psc; /* 0x30 */
+- unsigned short res12;
+- unsigned short scll; /* 0x34 */
+- unsigned short res13;
+- unsigned short sclh; /* 0x38 */
+- unsigned short res14;
+- unsigned short systest; /* 0x3c */
+- unsigned short res15;
+-};
+-
+-#endif /* _OMAP3_I2C_H_ */
++#define I2C_BUS_MAX 3
++
++#define I2C_REV (I2C_DEFAULT_BASE + 0x00)
++#define I2C_IE (I2C_DEFAULT_BASE + 0x04)
++#define I2C_STAT (I2C_DEFAULT_BASE + 0x08)
++#define I2C_IV (I2C_DEFAULT_BASE + 0x0c)
++#define I2C_BUF (I2C_DEFAULT_BASE + 0x14)
++#define I2C_CNT (I2C_DEFAULT_BASE + 0x18)
++#define I2C_DATA (I2C_DEFAULT_BASE + 0x1c)
++#define I2C_SYSC (I2C_DEFAULT_BASE + 0x20)
++#define I2C_CON (I2C_DEFAULT_BASE + 0x24)
++#define I2C_OA (I2C_DEFAULT_BASE + 0x28)
++#define I2C_SA (I2C_DEFAULT_BASE + 0x2c)
++#define I2C_PSC (I2C_DEFAULT_BASE + 0x30)
++#define I2C_SCLL (I2C_DEFAULT_BASE + 0x34)
++#define I2C_SCLH (I2C_DEFAULT_BASE + 0x38)
++#define I2C_SYSTEST (I2C_DEFAULT_BASE + 0x3c)
++
++/* I2C masks */
++
++/* I2C Interrupt Enable Register (I2C_IE): */
++#define I2C_IE_GC_IE (1 << 5)
++#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_SBD (1 << 15) /* Single byte data */
++#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_GC (1 << 5)
++#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 */
++
++/* I2C Buffer Configuration Register (I2C_BUF): */
++
++#define I2C_BUF_RDMA_EN (1 << 15) /* Receive DMA channel enable */
++#define I2C_BUF_XDMA_EN (1 << 7) /* Transmit DMA channel enable */
++
++/* I2C Configuration Register (I2C_CON): */
++
++#define I2C_CON_EN (1 << 15) /* I2C module enable */
++#define I2C_CON_BE (1 << 14) /* Big endian mode */
++#define I2C_CON_STB (1 << 11) /* 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 << 1) /* Stop condition (master mode only) */
++#define I2C_CON_STT (1 << 0) /* Start condition (master mode only) */
++
++/* I2C System Test Register (I2C_SYSTEST): */
++
++#define I2C_SYSTEST_ST_EN (1 << 15) /* System test enable */
++#define I2C_SYSTEST_FREE (1 << 14) /* Free running mode, on brkpoint) */
++#define I2C_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select */
++#define I2C_SYSTEST_TMODE_SHIFT (12) /* Test mode select */
++#define I2C_SYSTEST_SCL_I (1 << 3) /* SCL line sense input value */
++#define I2C_SYSTEST_SCL_O (1 << 2) /* SCL line drive output value */
++#define I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense input value */
++#define I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive output value */
++
++#define I2C_SCLL_SCLL 0
++#define I2C_SCLL_SCLL_M 0xFF
++#define I2C_SCLL_HSSCLL 8
++#define I2C_SCLH_HSSCLL_M 0xFF
++#define I2C_SCLH_SCLH 0
++#define I2C_SCLH_SCLH_M 0xFF
++#define I2C_SCLH_HSSCLH 8
++#define I2C_SCLH_HSSCLH_M 0xFF
++
++#define OMAP_I2C_STANDARD 100000
++#define OMAP_I2C_FAST_MODE 400000
++#define OMAP_I2C_HIGH_SPEED 3400000
++
++#define SYSTEM_CLOCK_12 12000000
++#define SYSTEM_CLOCK_13 13000000
++#define SYSTEM_CLOCK_192 19200000
++#define SYSTEM_CLOCK_96 96000000
++
++/* Use the reference value of 96MHz if not explicitly set by the board */
++#ifndef I2C_IP_CLK
++#define I2C_IP_CLK SYSTEM_CLOCK_96
++#endif
++
++/*
++ * The reference minimum clock for high speed is 19.2MHz.
++ * The linux 2.6.30 kernel uses this value.
++ * The reference minimum clock for fast mode is 9.6MHz
++ * The reference minimum clock for standard mode is 4MHz
++ * In TRM, the value of 12MHz is used.
++ */
++#ifndef I2C_INTERNAL_SAMPLING_CLK
++#define I2C_INTERNAL_SAMPLING_CLK 19200000
++#endif
++
++/*
++ * The equation for the low and high time is
++ * tlow = scll + scll_trim = (sampling clock * tlow_duty) / speed
++ * thigh = sclh + sclh_trim = (sampling clock * (1 - tlow_duty)) / speed
++ *
++ * If the duty cycle is 50%
++ *
++ * tlow = scll + scll_trim = sampling clock / (2 * speed)
++ * thigh = sclh + sclh_trim = sampling clock / (2 * speed)
++ *
++ * In TRM
++ * scll_trim = 7
++ * sclh_trim = 5
++ *
++ * The linux 2.6.30 kernel uses
++ * scll_trim = 6
++ * sclh_trim = 6
++ *
++ * These are the trim values for standard and fast speed
++ */
++#ifndef I2C_FASTSPEED_SCLL_TRIM
++#define I2C_FASTSPEED_SCLL_TRIM 6
++#endif
++#ifndef I2C_FASTSPEED_SCLH_TRIM
++#define I2C_FASTSPEED_SCLH_TRIM 6
++#endif
++
++/* These are the trim values for high speed */
++#ifndef I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM
++#define I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM I2C_FASTSPEED_SCLL_TRIM
++#endif
++#ifndef I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM
++#define I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM I2C_FASTSPEED_SCLH_TRIM
++#endif
++#ifndef I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM
++#define I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM I2C_FASTSPEED_SCLL_TRIM
++#endif
++#ifndef I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM
++#define I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM I2C_FASTSPEED_SCLH_TRIM
++#endif
++
++#define I2C_PSC_MAX 0x0f
++#define I2C_PSC_MIN 0x00
++
++#endif /* _I2C_H_ */
+diff --git a/arch/arm/include/asm/arch-omap3/mem.h b/arch/arm/include/asm/arch-omap3/mem.h
+index f165949..81eb660 100644
+--- a/arch/arm/include/asm/arch-omap3/mem.h
++++ b/arch/arm/include/asm/arch-omap3/mem.h
+@@ -128,6 +128,33 @@ enum {
+ (MICRON_XSR_165 << 0) | (MICRON_TXP_165 << 8) | \
+ (MICRON_TWTR_165 << 16))
+
++#define MICRON_RAMTYPE 0x1
++#define MICRON_DDRTYPE 0x0
++#define MICRON_DEEPPD 0x1
++#define MICRON_B32NOT16 0x1
++#define MICRON_BANKALLOCATION 0x2
++#define MICRON_RAMSIZE ((PHYS_SDRAM_1_SIZE/(1024*1024))/2)
++#define MICRON_ADDRMUXLEGACY 0x1
++#define MICRON_CASWIDTH 0x5
++#define MICRON_RASWIDTH 0x2
++#define MICRON_LOCKSTATUS 0x0
++#define MICRON_V_MCFG ((MICRON_LOCKSTATUS << 30) | (MICRON_RASWIDTH << 24) | \
++ (MICRON_CASWIDTH << 20) | (MICRON_ADDRMUXLEGACY << 19) | \
++ (MICRON_RAMSIZE << 8) | (MICRON_BANKALLOCATION << 6) | \
++ (MICRON_B32NOT16 << 4) | (MICRON_DEEPPD << 3) | \
++ (MICRON_DDRTYPE << 2) | (MICRON_RAMTYPE))
++
++#define MICRON_ARCV 2030
++#define MICRON_ARE 0x1
++#define MICRON_V_RFR_CTRL ((MICRON_ARCV << 8) | (MICRON_ARE))
++
++#define MICRON_BL 0x2
++#define MICRON_SIL 0x0
++#define MICRON_CASL 0x3
++#define MICRON_WBST 0x0
++#define MICRON_V_MR ((MICRON_WBST << 9) | (MICRON_CASL << 4) | \
++ (MICRON_SIL << 3) | (MICRON_BL))
++
+ /*
+ * NUMONYX part of IGEP v2 (165MHz optimized) 6.06ns
+ * ACTIMA
+@@ -171,10 +198,15 @@ enum {
+ #define V_ACTIMA_165 INFINEON_V_ACTIMA_165
+ #define V_ACTIMB_165 INFINEON_V_ACTIMB_165
+ #endif
++
+ #ifdef CONFIG_OMAP3_MICRON_DDR
+ #define V_ACTIMA_165 MICRON_V_ACTIMA_165
+ #define V_ACTIMB_165 MICRON_V_ACTIMB_165
++#define V_MCFG MICRON_V_MCFG
++#define V_RFR_CTRL MICRON_V_RFR_CTRL
++#define V_MR MICRON_V_MR
+ #endif
++
+ #ifdef CONFIG_OMAP3_NUMONYX_DDR
+ #define V_ACTIMA_165 NUMONYX_V_ACTIMA_165
+ #define V_ACTIMB_165 NUMONYX_V_ACTIMB_165
+@@ -184,6 +216,10 @@ enum {
+ #error "Please choose the right DDR type in config header"
+ #endif
+
++#if defined(CONFIG_SPL_BUILD) && (!defined(V_MCFG) || !defined(V_RFR_CTRL))
++#error "Please choose the right DDR type in config header"
++#endif
++
+ /*
+ * GPMC settings -
+ * Definitions is as per the following format
+@@ -242,12 +278,15 @@ enum {
+ #define M_NAND_GPMC_CONFIG6 0x1f0f0A80
+ #define M_NAND_GPMC_CONFIG7 0x00000C44
+
+-#define STNOR_GPMC_CONFIG1 0x3
+-#define STNOR_GPMC_CONFIG2 0x00151501
+-#define STNOR_GPMC_CONFIG3 0x00060602
+-#define STNOR_GPMC_CONFIG4 0x11091109
+-#define STNOR_GPMC_CONFIG5 0x01141F1F
+-#define STNOR_GPMC_CONFIG6 0x000004c4
++/*
++ * Configuration required for AM3517EVM PC28F640P30B85 Flash
++ */
++#define STNOR_GPMC_CONFIG1 0x00001210
++#define STNOR_GPMC_CONFIG2 0x00101001
++#define STNOR_GPMC_CONFIG3 0x00020201
++#define STNOR_GPMC_CONFIG4 0x0f031003
++#define STNOR_GPMC_CONFIG5 0x000f1111
++#define STNOR_GPMC_CONFIG6 0x0f030080
+
+ #define SIBNOR_GPMC_CONFIG1 0x1200
+ #define SIBNOR_GPMC_CONFIG2 0x001f1f00
+diff --git a/arch/arm/include/asm/arch-omap3/omap_bch_soft.h b/arch/arm/include/asm/arch-omap3/omap_bch_soft.h
+new file mode 100644
+index 0000000..7fd8197
+--- /dev/null
++++ b/arch/arm/include/asm/arch-omap3/omap_bch_soft.h
+@@ -0,0 +1,36 @@
++/*
++ * omap_bch_soft.h
++ *
++ * Header for support modules for BCH 4-bit/8-bit error correction.
++ *
++ * Copyright (C) {2011} Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#ifndef __ASM_ARCH_OMAP_BCH_SOFT_H
++#define __ASM_ARCH_OMAP_BCH_SOFT_H
++
++#include <linux/mtd/nand.h>
++
++struct nand_ecclayout *omap_get_ecc_layout_bch(int bus_width,
++ int correct_bits);
++void omap_hwecc_init_bch(struct nand_chip *chip);
++int omap_correct_data_bch4(struct mtd_info *mtd, uint8_t *dat,
++ uint8_t *read_ecc, uint8_t *calc_ecc);
++int omap_correct_data_bch8(struct mtd_info *mtd, uint8_t *dat,
++ uint8_t *read_ecc, uint8_t *calc_ecc);
++int omap_calculate_ecc_bch4(struct mtd_info *mtd, const uint8_t *dat,
++ uint8_t *ecc_code);
++int omap_calculate_ecc_bch8(struct mtd_info *mtd, const uint8_t *dat,
++ uint8_t *ecc_code);
++void omap_enable_hwecc_bch4(struct mtd_info *mtd, int32_t mode);
++void omap_enable_hwecc_bch8(struct mtd_info *mtd, int32_t mode);
++
++#endif
+diff --git a/arch/arm/include/asm/arch-omap3/omap_gpmc.h b/arch/arm/include/asm/arch-omap3/omap_gpmc.h
+index bd22bce..68bc70e 100644
+--- a/arch/arm/include/asm/arch-omap3/omap_gpmc.h
++++ b/arch/arm/include/asm/arch-omap3/omap_gpmc.h
+@@ -56,6 +56,16 @@
+ {.offset = 14,\
+ .length = 50 } } \
+ }
++/* NAND device layout in synch with the kernel */
++#define GPMC_NAND_HW_ECC_LAYOUT_KERNEL {\
++ .eccbytes = 12,\
++ .eccpos = {\
++ 40, 41, 42, 43, 44, 45, 46, 47,\
++ 48, 49, 50, 51},\
++ .oobfree = {\
++ {.offset = 2,\
++ .length = 38} } \
++}
+ #endif
+
+ /* Small Page x8 NAND device Layout */
+diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h
+index 995e7cb..52f0f49 100644
+--- a/arch/arm/include/asm/arch-omap3/sys_proto.h
++++ b/arch/arm/include/asm/arch-omap3/sys_proto.h
+@@ -66,7 +66,7 @@ void sr32(void *, u32, u32, u32);
+ u32 wait_on_value(u32, u32, void *, u32);
+ void sdelay(unsigned long);
+ void make_cs1_contiguous(void);
+-void omap_nand_switch_ecc(int);
++void omap_nand_switch_ecc(int, int);
+ void power_init_r(void);
+ void dieid_num_r(void);
+ void do_omap3_emu_romcode_call(u32 service_id, u32 parameters);
+diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h
+index a81f8e5..1aacbb1 100644
+--- a/arch/arm/include/asm/arch-omap4/sys_proto.h
++++ b/arch/arm/include/asm/arch-omap4/sys_proto.h
+@@ -43,7 +43,6 @@ void sr32(void *, u32, u32, u32);
+ u32 wait_on_value(u32, u32, void *, u32);
+ void sdelay(unsigned long);
+ void set_pl310_ctrl_reg(u32 val);
+-void omap_rev_string(char *omap4_rev_string);
+ void setup_clocks_for_console(void);
+ void prcm_init(void);
+ void bypass_dpll(u32 *const base);
+diff --git a/arch/arm/include/asm/arch-ti81xx/clock.h b/arch/arm/include/asm/arch-ti81xx/clock.h
+new file mode 100644
+index 0000000..2b69795
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/clock.h
+@@ -0,0 +1,36 @@
++/*
++ * (C) Copyright 2006-2008
++ * Texas Instruments, <www.ti.com>
++ * Richard Woodruff <r-woodruff2@ti.com>
++ *
++ * 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 _CLOCKS_H_
++#define _CLOCKS_H_
++
++#ifdef CONFIG_TI816X
++#include <asm/arch/clocks_ti816x.h>
++#endif
++
++#ifdef CONFIG_TI814X
++#include <asm/arch/clocks_ti814x.h>
++#endif
++
++#ifdef CONFIG_AM335X
++#include <asm/arch/clocks_am335x.h>
++#endif
++#endif
++
+diff --git a/arch/arm/include/asm/arch-ti81xx/clocks_am335x.h b/arch/arm/include/asm/arch-ti81xx/clocks_am335x.h
+new file mode 100644
+index 0000000..b5fbc29
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/clocks_am335x.h
+@@ -0,0 +1,65 @@
++/*
++ * clocks_am335x.h
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * 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 _CLOCKS_AM335X_H_
++#define _CLOCKS_AM335X_H_
++
++/* Put the pll config values over here */
++
++#define OSC 24
++
++/* MAIN PLL Fdll = 1 GHZ, */
++#define MPUPLL_M_500 500 /* 125 * n */
++#define MPUPLL_M_550 550 /* 125 * n */
++#define MPUPLL_M_600 600 /* 125 * n */
++#define MPUPLL_M_720 720 /* 125 * n */
++
++#define MPUPLL_N 23 /* (n -1 ) */
++#define MPUPLL_M2 1
++
++/* Core PLL Fdll = 1 GHZ, */
++#define COREPLL_M 1000 /* 125 * n */
++#define COREPLL_N 23 /* (n -1 ) */
++
++#define COREPLL_M4 10 /* CORE_CLKOUTM4 = 200 MHZ */
++#define COREPLL_M5 8 /* CORE_CLKOUTM5 = 250 MHZ */
++#define COREPLL_M6 4 /* CORE_CLKOUTM6 = 500 MHZ */
++
++/*
++ * USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll
++ * frequency needs to be set to 960 MHZ. Hence,
++ * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
++ */
++#define PERPLL_M 960
++#define PERPLL_N 23
++#define PERPLL_M2 5
++
++/* DDR Freq is 166 MHZ for now*/
++/* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
++#if (CONFIG_AM335X_EVM_IS_13x13 == 1)
++#define DDRPLL_M 166 /* M/N + 1 = 25/3 */
++#else
++#define DDRPLL_M 266
++#endif
++
++#define DDRPLL_N 23
++#define DDRPLL_M2 1
++
++#endif /* endif _CLOCKS_AM335X_H_ */
+diff --git a/arch/arm/include/asm/arch-ti81xx/clocks_ti814x.h b/arch/arm/include/asm/arch-ti81xx/clocks_ti814x.h
+new file mode 100644
+index 0000000..1b41c6f
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/clocks_ti814x.h
+@@ -0,0 +1,72 @@
++/*
++ * (C) Copyright 2006-2008
++ * Texas Instruments, <www.ti.com>
++ * Richard Woodruff <r-woodruff2@ti.com>
++ *
++ * 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 _CLOCKS_TI814X_H_
++#define _CLOCKS_TI814X_H_
++
++/* CLK_SRC */
++#define OSC_SRC0 0
++#define OSC_SRC1 1
++
++#define L3_OSC_SRC OSC_SRC0
++#define AUDIO_OSC_SRC OSC_SRC0
++
++/* Put the pll config values over here */
++#define AUDIO_N 19
++#define AUDIO_M 500
++#define AUDIO_M2 2
++#define AUDIO_CLKCTRL 0x801
++
++#define MODENA_N 0x10001
++#define MODENA_M 0x3C
++#define MODENA_M2 1
++#define MODENA_CLKCTRL 0x1
++
++#define L3_N 19
++#define L3_M 880
++#define L3_M2 4
++#define L3_CLKCTRL 0x801
++
++#define DDR_N 19
++#define DDR_M 666
++#define DDR_M2 2
++#define DDR_CLKCTRL 0x801
++
++#define DSP_N 19
++#define DSP_M 500
++#define DSP_M2 1
++#define DSP_CLKCTRL 0x801
++
++#define IVA_N 19
++#define IVA_M 640
++#define IVA_M2 2
++#define IVA_CLKCTRL 0x801
++
++#define ISS_N 19
++#define ISS_M 800
++#define ISS_M2 2
++#define ISS_CLKCTRL 0x801
++
++#define USB_N 19
++#define USB_M 960
++#define USB_M2 1
++#define USB_CLKCTRL 0x200a0801
++#endif /* endif _CLOCKS_TI814X_H_ */
++
+diff --git a/arch/arm/include/asm/arch-ti81xx/clocks_ti816x.h b/arch/arm/include/asm/arch-ti81xx/clocks_ti816x.h
+new file mode 100644
+index 0000000..8590c2f
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/clocks_ti816x.h
+@@ -0,0 +1,162 @@
++/*
++ * (C) Copyright 2006-2008
++ * Texas Instruments, <www.ti.com>
++ * Richard Woodruff <r-woodruff2@ti.com>
++ *
++ * 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 _CLOCKS_TI816X_H_
++#define _CLOCKS_TI816X_H_
++
++/*
++ * In TI816x the 27MHz crystal generates various root clks (main pll, audio pll, video pll and ddr pll)
++ * From these root clks the SYSCLKs are generated by making use of dividers and multipliers
++ */
++
++#define FAPLL_K 8
++#define SYSCLK_2_DIV 1
++#define OSC_FREQ 27
++#define DDR_PLL_400 /* Values supported 400,531,675,796 */
++
++/* Main PLL */
++#define MAIN_N 64
++#define MAIN_P 0x1
++#define MAIN_INTFREQ1 0x8
++#define MAIN_FRACFREQ1 0x800000
++#define MAIN_MDIV1 0x2
++#define MAIN_INTFREQ2 0xE
++#define MAIN_FRACFREQ2 0x0
++#define MAIN_MDIV2 0x1
++#define MAIN_INTFREQ3 0x8
++#define MAIN_FRACFREQ3 0xAAAAB0
++#define MAIN_MDIV3 0x3
++#define MAIN_INTFREQ4 0x9
++#define MAIN_FRACFREQ4 0x55554F
++#define MAIN_MDIV4 0x3
++#define MAIN_INTFREQ5 0x9
++#define MAIN_FRACFREQ5 0x374BC6
++#define MAIN_MDIV5 0xC
++#define MAIN_MDIV6 0x48
++#define MAIN_MDIV7 0x4
++
++/* DDR PLL */
++/* For 400 MHz */
++#if defined(DDR_PLL_400)
++#define DDR_N 59
++#define DDR_P 0x1
++#define DDR_MDIV1 0x4
++#define DDR_INTFREQ2 0x8
++#define DDR_FRACFREQ2 0xD99999
++#define DDR_MDIV2 0x1E
++#define DDR_INTFREQ3 0x8
++#define DDR_FRACFREQ3 0x0
++#define DDR_MDIV3 0x4
++#define DDR_INTFREQ4 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ4 0x0
++#define DDR_MDIV4 0x4
++#define DDR_INTFREQ5 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ5 0x0
++#define DDR_MDIV5 0x4
++#endif
++
++/* For 531 MHz */
++#if defined(DDR_PLL_531)
++#define DDR_N 59
++#define DDR_P 0x1
++#define DDR_MDIV1 0x3
++#define DDR_INTFREQ2 0x8
++#define DDR_FRACFREQ2 0xD99999
++#define DDR_MDIV2 0x1E
++#define DDR_INTFREQ3 0x8
++#define DDR_FRACFREQ3 0x0
++#define DDR_MDIV3 0x4
++#define DDR_INTFREQ4 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ4 0x0
++#define DDR_MDIV4 0x4
++#define DDR_INTFREQ5 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ5 0x0
++#define DDR_MDIV5 0x4
++#endif
++
++/* For 675 MHz */
++#if defined(DDR_PLL_675)
++#define DDR_N 50
++#define DDR_P 0x1
++#define DDR_MDIV1 0x2
++#define DDR_INTFREQ2 0x9
++#define DDR_FRACFREQ2 0x0
++#define DDR_MDIV2 0x19
++#define DDR_INTFREQ3 0x13
++#define DDR_FRACFREQ3 0x800000
++#define DDR_MDIV3 0x2
++#define DDR_INTFREQ4 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ4 0x0
++#define DDR_MDIV4 0x4
++#define DDR_INTFREQ5 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ5 0x0
++#define DDR_MDIV5 0x4
++#endif
++
++/* For 796 MHz */
++#if defined(DDR_PLL_796)
++#define DDR_N 59
++#define DDR_P 0x1
++#define DDR_MDIV1 0x2
++#define DDR_INTFREQ2 0x8
++#define DDR_FRACFREQ2 0xD99999
++#define DDR_MDIV2 0x1E
++#define DDR_INTFREQ3 0x8
++#define DDR_FRACFREQ3 0x0
++#define DDR_MDIV3 0x4
++#define DDR_INTFREQ4 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ4 0x0
++#define DDR_MDIV4 0x4
++#define DDR_INTFREQ5 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ5 0x0
++#define DDR_MDIV5 0x4
++#endif
++
++/* Video PLL */
++#define VIDEO_N 110
++#define VIDEO_P 0x2
++#define VIDEO_INTFREQ1 0xB
++#define VIDEO_FRACFREQ1 0x0
++#define VIDEO_MDIV1 0x5
++#define VIDEO_INTFREQ2 0xA
++#define VIDEO_FRACFREQ2 0x0
++#define VIDEO_MDIV2 0x2
++#define VIDEO_INTFREQ3 0xA
++#define VIDEO_FRACFREQ3 0x0
++#define VIDEO_MDIV3 0x2
++
++/* Audio PLL */
++#define AUDIO_N 64
++#define AUDIO_P 0x19
++#define AUDIO_INTFREQ2 0xE
++#define AUDIO_FRACFREQ2 0x0
++#define AUDIO_MDIV2 0x4
++#define AUDIO_INTFREQ3 0x9
++#define AUDIO_FRACFREQ3 0x0
++#define AUDIO_MDIV3 0x5
++#define AUDIO_INTFREQ4 0x9
++#define AUDIO_FRACFREQ4 0xCBC148
++#define AUDIO_MDIV4 0x14
++#define AUDIO_INTFREQ5 0xD
++#define AUDIO_FRACFREQ5 0x800000
++#define AUDIO_MDIV5 0x14
++
++#endif /* endif _CLOCKS_TI816X_H_ */
++
+diff --git a/arch/arm/include/asm/arch-ti81xx/cpu.h b/arch/arm/include/asm/arch-ti81xx/cpu.h
+new file mode 100644
+index 0000000..8cbc289
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/cpu.h
+@@ -0,0 +1,726 @@
++/*
++ * (C) Copyright 2006
++ * Texas Instruments, <www.ti.com>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ *
++ */
++
++#ifndef _TI81XX_CPU_H
++#define _TI81XX_CPU_H
++
++#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
++#include <asm/types.h>
++#endif /* !(__KERNEL_STRICT_NAMES || __ASSEMBLY__) */
++
++#include <asm/arch/hardware.h>
++
++#define BIT(x) (1 << x)
++#define CL_BIT(x) (0 << x)
++
++/* Timer registers */
++#define TIMER_TCLR 0x38 /* Timer control register */
++#define TIMER_TCRR 0x3C /* Timer counter register */
++#define TIMER_TLDR 0x40 /* Timer load value register*/
++
++/* Timer 32 bit registers */
++#ifndef __KERNEL_STRICT_NAMES
++#ifndef __ASSEMBLY__
++struct gptimer {
++ u32 tidr; /* 0x00 r */
++ u8 res1[0xc];
++ u32 tiocp_cfg; /* 0x10 rw */
++ u8 res2[0xc];
++ u32 tier; /* 0x20 rw */
++ u32 tistatr;/* 0x24 r */
++ u32 tistat; /* 0x28 r */
++ u32 tisr; /* 0x2c rw */
++ u32 tcicr; /* 0x30 rw */
++ u32 twer; /* 0x34 rw */
++ u32 tclr; /* 0x38 rw - control reg */
++ u32 tcrr; /* 0x3c rw - counter reg */
++ u32 tldr; /* 0x40 rw - load reg */
++ u32 ttgr; /* 0x44 rw */
++ u32 twpc; /* 0x48 r*/
++ u32 tmar; /* 0x4c rw*/
++ u32 tcar1; /* 0x50 r */
++ u32 tscir; /* 0x54 r */
++ u32 tcar2; /* 0x58 r */
++};
++#endif /* __ASSEMBLY__ */
++#endif /* __KERNEL_STRICT_NAMES */
++
++/* Timer register bits */
++#define TCLR_ST BIT(0) /* Start=1 Stop=0 */
++#define TCLR_AR BIT(1) /* Auto reload */
++#define TCLR_PRE BIT(5) /* Pre-scaler enable */
++#define TCLR_PTV_SHIFT (2) /* Pre-scaler shift value */
++#define TCLR_PRE_DISABLE CL_BIT(5) /* Pre-scalar disable */
++
++/* Control */
++#define CONTROL_STATUS (CTRL_BASE + 0x40)
++
++/* device type */
++#define DEVICE_MASK (BIT(8) | BIT(9) | BIT(10))
++#define TST_DEVICE 0x0
++#define EMU_DEVICE 0x1
++#define HS_DEVICE 0x2
++#define GP_DEVICE 0x3
++
++/* rom boot device/mode id */
++#define BOOT_DEVICE_OFFSET 8
++#define BOOT_DEVICE_MASK 0xff
++
++/* cpu-id for TI81XX family */
++#define TI8168 0xb81e
++#define AM335X 0xB944
++
++#define DEVICE_ID (CTRL_BASE + 0x0600)
++/* This gives the status of the boot mode pins on the evm */
++#define SYSBOOT_MASK (BIT(0) | BIT(1) | BIT(2) |BIT(3) |BIT(4))
++
++/* Reset control */
++#ifdef CONFIG_AM335X
++#define PRM_RSTCTRL (PRCM_BASE + 0x0F00)
++#else
++#define PRM_RSTCTRL (PRCM_BASE + 0x00A0)
++#endif
++#define PRM_RSTCTRL_RESET 0x01
++
++/* TI816X specific bits for PRM_DEVICE module */
++#define GLOBAL_RST_COLD BIT(1)
++
++/* PLL related registers */
++#ifdef CONFIG_TI816X
++#define MAINPLL_CTRL (CTRL_BASE + 0x0400)
++#define MAINPLL_PWD (CTRL_BASE + 0x0404)
++#define MAINPLL_FREQ1 (CTRL_BASE + 0x0408)
++#define MAINPLL_DIV1 (CTRL_BASE + 0x040C)
++#define MAINPLL_FREQ2 (CTRL_BASE + 0x0410)
++#define MAINPLL_DIV2 (CTRL_BASE + 0x0414)
++#define MAINPLL_FREQ3 (CTRL_BASE + 0x0418)
++#define MAINPLL_DIV3 (CTRL_BASE + 0x041C)
++#define MAINPLL_FREQ4 (CTRL_BASE + 0x0420)
++#define MAINPLL_DIV4 (CTRL_BASE + 0x0424)
++#define MAINPLL_FREQ5 (CTRL_BASE + 0x0428)
++#define MAINPLL_DIV5 (CTRL_BASE + 0x042C)
++#define MAINPLL_DIV6 (CTRL_BASE + 0x0434)
++#define MAINPLL_DIV7 (CTRL_BASE + 0x043C)
++
++#define DDRPLL_CTRL (CTRL_BASE + 0x0440)
++#define DDRPLL_PWD (CTRL_BASE + 0x0444)
++#define DDRPLL_DIV1 (CTRL_BASE + 0x044C)
++#define DDRPLL_FREQ2 (CTRL_BASE + 0x0450)
++#define DDRPLL_DIV2 (CTRL_BASE + 0x0454)
++#define DDRPLL_FREQ3 (CTRL_BASE + 0x0458)
++#define DDRPLL_DIV3 (CTRL_BASE + 0x045C)
++#define DDRPLL_FREQ4 (CTRL_BASE + 0x0460)
++#define DDRPLL_DIV4 (CTRL_BASE + 0x0464)
++#define DDRPLL_FREQ5 (CTRL_BASE + 0x0468)
++#define DDRPLL_DIV5 (CTRL_BASE + 0x046C)
++
++#define DDR_RCD (CTRL_BASE + 0x070C)
++
++#define VIDEOPLL_CTRL (CTRL_BASE + 0x0470)
++#define VIDEOPLL_PWD (CTRL_BASE + 0x0474)
++#define VIDEOPLL_FREQ1 (CTRL_BASE + 0x0478)
++#define VIDEOPLL_DIV1 (CTRL_BASE + 0x047C)
++#define VIDEOPLL_FREQ2 (CTRL_BASE + 0x0480)
++#define VIDEOPLL_DIV2 (CTRL_BASE + 0x0484)
++#define VIDEOPLL_FREQ3 (CTRL_BASE + 0x0488)
++#define VIDEOPLL_DIV3 (CTRL_BASE + 0x048C)
++
++#define AUDIOPLL_CTRL (CTRL_BASE + 0x04A0)
++#define AUDIOPLL_PWD (CTRL_BASE + 0x04A4)
++#define AUDIOPLL_FREQ2 (CTRL_BASE + 0x04B0)
++#define AUDIOPLL_DIV2 (CTRL_BASE + 0x04B4)
++#define AUDIOPLL_FREQ3 (CTRL_BASE + 0x04B8)
++#define AUDIOPLL_DIV3 (CTRL_BASE + 0x04BC)
++#define AUDIOPLL_FREQ4 (CTRL_BASE + 0x04C0)
++#define AUDIOPLL_DIV4 (CTRL_BASE + 0x04C4)
++#define AUDIOPLL_FREQ5 (CTRL_BASE + 0x04C8)
++#define AUDIOPLL_DIV5 (CTRL_BASE + 0x04CC)
++
++#endif
++
++#ifdef CONFIG_TI814X
++
++#define GMII_SEL (CTRL_BASE + 0x650)
++
++#define PCIE_PLLCFG0 (CTRL_BASE + 0x6D8)
++#define PCIE_PLLCFG1 (CTRL_BASE + 0x6DC)
++#define PCIE_PLLCFG2 (CTRL_BASE + 0x6E0)
++#define PCIE_PLLCFG3 (CTRL_BASE + 0x6E4)
++#define PCIE_PLLCFG4 (CTRL_BASE + 0x6E8)
++#define PCIE_PLLSTATUS (CTRL_BASE + 0x6EC)
++#define PCIE_RXSTATUS (CTRL_BASE + 0x6F0)
++#define PCIE_TXSTATUS (CTRL_BASE + 0x6F4)
++#define SERDES_REFCLK_CTRL (CTRL_BASE + 0xE24)
++
++#define SATA_PLLCFG0 (CTRL_BASE + 0x720)
++#define SATA_PLLCFG1 (CTRL_BASE + 0x724)
++#define SATA_PLLCFG2 (CTRL_BASE + 0x728)
++#define SATA_PLLCFG3 (CTRL_BASE + 0x72C)
++#define SATA_PLLCFG4 (CTRL_BASE + 0x730)
++#define SATA_PLLSTATUS (CTRL_BASE + 0x734)
++#define SATA_RXSTATUS (CTRL_BASE + 0x738)
++#define SATA_TXSTATUS (CTRL_BASE + 0x73C)
++
++/* pin muxing registers */
++#define PIN_CTRL_BASE (CTRL_BASE + 0x800)
++#define N_PINS (271) /* PIN1=800, PIN 271=800+270*4=C38) */
++
++/* Clocks are derived from ADPLLJ */
++#define ADPLLJ_CLKCTRL 0x4
++#define ADPLLJ_TENABLE 0x8
++#define ADPLLJ_TENABLEDIV 0xC
++#define ADPLLJ_M2NDIV 0x10
++#define ADPLLJ_MN2DIV 0x14
++#define ADPLLJ_STATUS 0x24
++
++/* ADPLLJ register values */
++#define ADPLLJ_CLKCTRL_HS2 0x00000801 /* HS2 mode, TINT2 = 1 */
++#define ADPLLJ_CLKCTRL_HS1 0x00001001 /* HS1 mode, TINT2 = 1 */
++#define ADPLLJ_CLKCTRL_CLKDCO 0x200A0000 /* Enable CLKDCOEN, CLKLDOEN, CLKDCOPWDNZ */
++
++#define MODENA_PLL_BASE (PLL_SUBSYS_BASE + 0x048)
++#define DSP_PLL_BASE (PLL_SUBSYS_BASE + 0x080)
++#define SGX_PLL_BASE (PLL_SUBSYS_BASE + 0x0B0)
++#define IVA_PLL_BASE (PLL_SUBSYS_BASE + 0x0E0)
++#define L3_PLL_BASE (PLL_SUBSYS_BASE + 0x110)
++#define ISS_PLL_BASE (PLL_SUBSYS_BASE + 0x140)
++#define DSS_PLL_BASE (PLL_SUBSYS_BASE + 0x170)
++#define VIDEO0_PLL_BASE (PLL_SUBSYS_BASE + 0x1A0)
++#define VIDEO1_PLL_BASE (PLL_SUBSYS_BASE + 0x1D0)
++#define HDMI_PLL_BASE (PLL_SUBSYS_BASE + 0x200)
++#define AUDIO_PLL_BASE (PLL_SUBSYS_BASE + 0x230)
++#define USB_PLL_BASE (PLL_SUBSYS_BASE + 0x260)
++#define DDR_PLL_BASE (PLL_SUBSYS_BASE + 0x290)
++
++#define OSC_SRC_CTRL (PLL_SUBSYS_BASE + 0x2C0)
++#define ARM_CLKSRC (PLL_SUBSYS_BASE + 0x2C4)
++#define VIDEO_PLL_CLKSRC (PLL_SUBSYS_BASE + 0x2C8)
++#define MLB_ATL_CLKSRC (PLL_SUBSYS_BASE + 0x2CC)
++#define McASP235_AUX_CLKSRC (PLL_SUBSYS_BASE + 0x2D0)
++#define McASP_AHCLK_CLKSRC (PLL_SUBSYS_BASE + 0x2D4)
++#define McBSP_UART_CLKSRC (PLL_SUBSYS_BASE + 0x2D8)
++#define HDMI_I2S_CLKSRC (PLL_SUBSYS_BASE + 0x2DC)
++#define DMTIMER_CLKSRC (PLL_SUBSYS_BASE + 0x2E0)
++#define CLKOUT_MUX (PLL_SUBSYS_BASE + 0x2E4)
++#define RMII_REFCLK_SRC (PLL_SUBSYS_BASE + 0x2E8)
++#define SECSS_CLKSRC (PLL_SUBSYS_BASE + 0x2EC)
++#define SYSCLK18_SRC (PLL_SUBSYS_BASE + 0x2F0)
++#define WDT0_CLKSRC (PLL_SUBSYS_BASE + 0x2F4)
++
++#endif
++
++#ifdef CONFIG_AM335X
++/* Module Offsets */
++#define CM_PER (PRCM_BASE + 0x0)
++#define CM_WKUP (PRCM_BASE + 0x400)
++#define CM_DPLL (PRCM_BASE + 0x500)
++#define CM_DEVICE (PRCM_BASE + 0x0700)
++#define CM_CEFUSE (PRCM_BASE + 0x0A00)
++#define PRM_DEVICE (PRCM_BASE + 0x0F00)
++
++/* Register Offsets */
++/* Core PLL ADPLLS */
++#define CM_CLKSEL_DPLL_CORE (CM_WKUP + 0x68)
++#define CM_CLKMODE_DPLL_CORE (CM_WKUP + 0x90)
++
++/* Core HSDIV */
++#define CM_DIV_M4_DPLL_CORE (CM_WKUP + 0x80)
++#define CM_DIV_M5_DPLL_CORE (CM_WKUP + 0x84)
++#define CM_DIV_M6_DPLL_CORE (CM_WKUP + 0xD8)
++#define CM_IDLEST_DPLL_CORE (CM_WKUP + 0x5c)
++
++/* Peripheral PLL */
++#define CM_CLKSEL_DPLL_PER (CM_WKUP + 0x9c)
++#define CM_CLKMODE_DPLL_PER (CM_WKUP + 0x8c)
++#define CM_DIV_M2_DPLL_PER (CM_WKUP + 0xAC)
++#define CM_IDLEST_DPLL_PER (CM_WKUP + 0x70)
++
++/* Display PLL */
++#define CM_CLKSEL_DPLL_DISP (CM_WKUP + 0x54)
++#define CM_CLKMODE_DPLL_DISP (CM_WKUP + 0x98)
++#define CM_DIV_M2_DPLL_DISP (CM_WKUP + 0xA4)
++
++/* DDR PLL */
++#define CM_CLKSEL_DPLL_DDR (CM_WKUP + 0x40)
++#define CM_CLKMODE_DPLL_DDR (CM_WKUP + 0x94)
++#define CM_DIV_M2_DPLL_DDR (CM_WKUP + 0xA0)
++#define CM_IDLEST_DPLL_DDR (CM_WKUP + 0x34)
++
++/* MPU PLL */
++#define CM_CLKSEL_DPLL_MPU (CM_WKUP + 0x2c)
++#define CM_CLKMODE_DPLL_MPU (CM_WKUP + 0x88)
++#define CM_DIV_M2_DPLL_MPU (CM_WKUP + 0xA8)
++#define CM_IDLEST_DPLL_MPU (CM_WKUP + 0x20)
++
++/* TIMER Clock Source Select */
++#define CLKSEL_TIMER2_CLK (CM_DPLL + 0x8)
++
++/* Interconnect clocks */
++#define CM_PER_L4LS_CLKCTRL (CM_PER + 0x60) /* EMIF */
++#define CM_PER_L4FW_CLKCTRL (CM_PER + 0x64) /* EMIF FW */
++#define CM_PER_L3_CLKCTRL (CM_PER + 0xE0) /* OCMC RAM */
++#define CM_PER_L3_INSTR_CLKCTRL (CM_PER + 0xDC)
++#define CM_PER_L4HS_CLKCTRL (CM_PER + 0x120)
++#define CM_WKUP_L4WKUP_CLKCTRL (CM_WKUP + 0x0c)/* UART0 */
++
++/* Domain Wake UP */
++#define CM_WKUP_CLKSTCTRL (CM_WKUP + 0) /* UART0 */
++#define CM_PER_L4LS_CLKSTCTRL (CM_PER + 0x0) /* TIMER2 */
++#define CM_PER_L3_CLKSTCTRL (CM_PER + 0x0c) /* EMIF */
++#define CM_PER_L4FW_CLKSTCTRL (CM_PER + 0x08) /* EMIF FW */
++#define CM_PER_L3S_CLKSTCTRL (CM_PER + 0x4)
++#define CM_PER_L4HS_CLKSTCTRL (CM_PER + 0x011c)
++#define CM_CEFUSE_CLKSTCTRL (CM_CEFUSE + 0x0)
++
++/* Module Enable Registers */
++#define CM_PER_TIMER2_CLKCTRL (CM_PER + 0x80) /* Timer2 */
++#define CM_WKUP_UART0_CLKCTRL (CM_WKUP + 0xB4)/* UART0 */
++#define CM_WKUP_CONTROL_CLKCTRL (CM_WKUP + 0x4) /* Control Module */
++#define CM_PER_EMIF_CLKCTRL (CM_PER + 0x28) /* EMIF */
++#define CM_PER_EMIF_FW_CLKCTRL (CM_PER + 0xD0) /* EMIF FW */
++#define CM_PER_GPMC_CLKCTRL (CM_PER + 0x30) /* GPMC */
++#define CM_PER_ELM_CLKCTRL (CM_PER + 0x40) /* ELM */
++#define CM_PER_SPI0_CLKCTRL (CM_PER + 0x4c) /* SPI0 */
++#define CM_PER_SPI1_CLKCTRL (CM_PER + 0x50) /* SPI1 */
++#define CM_WKUP_I2C0_CLKCTRL (CM_WKUP + 0xB8) /* I2C0 */
++#define CM_PER_CPGMAC0_CLKCTRL (CM_PER + 0x14) /* Ethernet */
++#define CM_PER_CPSW_CLKSTCTRL (CM_PER + 0x144)/* Ethernet */
++#define CM_PER_OCMCRAM_CLKCTRL (CM_PER + 0x2C) /* OCMC RAM */
++#define CM_PER_GPIO2_CLKCTRL (CM_PER + 0xB0) /* GPIO2 */
++#define CM_PER_UART3_CLKCTRL (CM_PER + 0x74) /* UART3 */
++#define CM_PER_I2C1_CLKCTRL (CM_PER + 0x48) /* I2C1 */
++#define CM_PER_I2C2_CLKCTRL (CM_PER + 0x44) /* I2C2 */
++#define CM_WKUP_GPIO0_CLKCTRL (CM_WKUP + 0x8) /* GPIO0 */
++
++#define CM_PER_MMC0_CLKCTRL (CM_PER + 0x3C)
++#define CM_PER_MMC1_CLKCTRL (CM_PER + 0xF4)
++#define CM_PER_MMC2_CLKCTRL (CM_PER + 0xF8)
++
++#endif /* CONFIG_AM335X */
++
++/* PRCM */
++#define CM_DPLL_OFFSET (PRCM_BASE + 0x0300)
++
++#ifdef CONFIG_TI816X
++#define CM_TIMER1_CLKSEL (CM_DPLL_OFFSET + 0x90)
++
++/* Timers */
++#define CM_ALWON_TIMER_0_CLKCTRL (PRCM_BASE + 0x156C)
++#define CM_ALWON_TIMER_1_CLKCTRL (PRCM_BASE + 0x1570)
++#define CM_ALWON_TIMER_2_CLKCTRL (PRCM_BASE + 0x1574)
++#define CM_ALWON_TIMER_3_CLKCTRL (PRCM_BASE + 0x1578)
++#define CM_ALWON_TIMER_4_CLKCTRL (PRCM_BASE + 0x157C)
++#define CM_ALWON_TIMER_5_CLKCTRL (PRCM_BASE + 0x1580)
++#define CM_ALWON_TIMER_6_CLKCTRL (PRCM_BASE + 0x1584)
++#define CM_ALWON_TIMER_7_CLKCTRL (PRCM_BASE + 0x1588)
++#endif
++
++#define CM_ALWON_WDTIMER_CLKCTRL (PRCM_BASE + 0x158C)
++#define CM_ALWON_SPI_CLKCTRL (PRCM_BASE + 0x1590)
++#define CM_ALWON_CONTROL_CLKCTRL (PRCM_BASE + 0x15C4)
++
++#define CM_ALWON_L3_SLOW_CLKSTCTRL (PRCM_BASE + 0x1400)
++
++#ifdef CONFIG_TI816X
++#define CM_ALWON_CUST_EFUSE_CLKCTRL (PRCM_BASE + 0x1628)
++#endif
++
++#define CM_ALWON_GPIO_0_CLKCTRL (PRCM_BASE + 0x155c)
++#define CM_ALWON_GPIO_0_OPTFCLKEN_DBCLK (PRCM_BASE + 0x155c)
++
++/* Ethernet */
++#define CM_ETHERNET_CLKSTCTRL (PRCM_BASE + 0x1404)
++#define CM_ALWON_ETHERNET_0_CLKCTRL (PRCM_BASE + 0x15D4)
++#define CM_ALWON_ETHERNET_1_CLKCTRL (PRCM_BASE + 0x15D8)
++
++/* UARTs */
++#define CM_ALWON_UART_0_CLKCTRL (PRCM_BASE + 0x1550)
++#define CM_ALWON_UART_1_CLKCTRL (PRCM_BASE + 0x1554)
++#define CM_ALWON_UART_2_CLKCTRL (PRCM_BASE + 0x1558)
++
++/* I2C */
++/* Note: In ti814x I2C0 and I2C2 have common clk control */
++#define CM_ALWON_I2C_0_CLKCTRL (PRCM_BASE + 0x1564)
++
++/* HSMMC */
++#ifdef CONFIG_TI816X
++#define CM_ALWON_HSMMC_CLKCTRL (PRCM_BASE + 0x15B0)
++#endif
++
++#ifdef CONFIG_TI814X
++#define CM_ALWON_HSMMC_CLKCTRL (PRCM_BASE + 0x1620)
++#endif
++
++/* UART2 registers */
++#ifdef CONFIG_TI816X
++#define DEFAULT_UART_BASE UART2_BASE
++#endif
++
++#ifdef CONFIG_TI814X
++#define DEFAULT_UART_BASE UART0_BASE
++#endif
++
++#ifdef CONFIG_AM335X
++#define DEFAULT_UART_BASE UART0_BASE
++#endif
++/* UART registers */
++/*TODO:Move to a new file */
++#define UART_SYSCFG (DEFAULT_UART_BASE + 0x54)
++#define UART_SYSSTS (DEFAULT_UART_BASE + 0x58)
++#define UART_LCR (DEFAULT_UART_BASE + 0x0C)
++#define UART_EFR (DEFAULT_UART_BASE + 0x08)
++#define UART_MCR (DEFAULT_UART_BASE + 0x10)
++#define UART_SCR (DEFAULT_UART_BASE + 0x40)
++#define UART_TCR (DEFAULT_UART_BASE + 0x18)
++#define UART_FCR (DEFAULT_UART_BASE + 0x08)
++#define UART_DLL (DEFAULT_UART_BASE + 0x00)
++#define UART_DLH (DEFAULT_UART_BASE + 0x04)
++#define UART_MDR (DEFAULT_UART_BASE + 0x20)
++
++/*DMM & EMIF4 MMR Declaration*/
++/*TODO: Move to a new file */
++#define DMM_LISA_MAP__0 (DMM_BASE + 0x40)
++#define DMM_LISA_MAP__1 (DMM_BASE + 0x44)
++#define DMM_LISA_MAP__2 (DMM_BASE + 0x48)
++#define DMM_LISA_MAP__3 (DMM_BASE + 0x4C)
++#define DMM_PAT_BASE_ADDR (DMM_BASE + 0x460)
++
++#ifdef CONFIG_AM335X
++#define EMIF_MOD_ID_REV (EMIF4_0_CFG_BASE + 0x0)
++#define EMIF4_0_SDRAM_STATUS (EMIF4_0_CFG_BASE + 0x04)
++#define EMIF4_0_SDRAM_CONFIG (EMIF4_0_CFG_BASE + 0x08)
++#define EMIF4_0_SDRAM_CONFIG2 (EMIF4_0_CFG_BASE + 0x0C)
++#define EMIF4_0_SDRAM_REF_CTRL (EMIF4_0_CFG_BASE + 0x10)
++#define EMIF4_0_SDRAM_REF_CTRL_SHADOW (EMIF4_0_CFG_BASE + 0x14)
++#define EMIF4_0_SDRAM_TIM_1 (EMIF4_0_CFG_BASE + 0x18)
++#define EMIF4_0_SDRAM_TIM_1_SHADOW (EMIF4_0_CFG_BASE + 0x1C)
++#define EMIF4_0_SDRAM_TIM_2 (EMIF4_0_CFG_BASE + 0x20)
++#define EMIF4_0_SDRAM_TIM_2_SHADOW (EMIF4_0_CFG_BASE + 0x24)
++#define EMIF4_0_SDRAM_TIM_3 (EMIF4_0_CFG_BASE + 0x28)
++#define EMIF4_0_SDRAM_TIM_3_SHADOW (EMIF4_0_CFG_BASE + 0x2C)
++#define EMIF0_0_SDRAM_MGMT_CTRL (EMIF4_0_CFG_BASE + 0x38)
++#define EMIF0_0_SDRAM_MGMT_CTRL_SHD (EMIF4_0_CFG_BASE + 0x3C)
++#define EMIF4_0_DDR_PHY_CTRL_1 (EMIF4_0_CFG_BASE + 0xE4)
++#define EMIF4_0_DDR_PHY_CTRL_1_SHADOW (EMIF4_0_CFG_BASE + 0xE8)
++#define EMIF4_0_DDR_PHY_CTRL_2 (EMIF4_0_CFG_BASE + 0xEC)
++#define EMIF4_0_IODFT_TLGC (EMIF4_0_CFG_BASE + 0x60)
++#else
++#define EMIF4_0_SDRAM_CONFIG (EMIF4_0_CFG_BASE + 0x08)
++#define EMIF4_0_SDRAM_CONFIG2 (EMIF4_0_CFG_BASE + 0x0C)
++#define EMIF4_0_SDRAM_REF_CTRL (EMIF4_0_CFG_BASE + 0x10)
++#define EMIF4_0_SDRAM_REF_CTRL_SHADOW (EMIF4_0_CFG_BASE + 0x14)
++#define EMIF4_0_SDRAM_TIM_1 (EMIF4_0_CFG_BASE + 0x18)
++#define EMIF4_0_SDRAM_TIM_1_SHADOW (EMIF4_0_CFG_BASE + 0x1C)
++#define EMIF4_0_SDRAM_TIM_2 (EMIF4_0_CFG_BASE + 0x20)
++#define EMIF4_0_SDRAM_TIM_2_SHADOW (EMIF4_0_CFG_BASE + 0x24)
++#define EMIF4_0_SDRAM_TIM_3 (EMIF4_0_CFG_BASE + 0x28)
++#define EMIF4_0_SDRAM_TIM_3_SHADOW (EMIF4_0_CFG_BASE + 0x2C)
++#define EMIF4_0_DDR_PHY_CTRL_1 (EMIF4_0_CFG_BASE + 0xE4)
++#define EMIF4_0_DDR_PHY_CTRL_1_SHADOW (EMIF4_0_CFG_BASE + 0xE8)
++#define EMIF4_0_IODFT_TLGC (EMIF4_0_CFG_BASE + 0x60)
++#endif
++
++#define EMIF4_1_SDRAM_CONFIG (EMIF4_1_CFG_BASE + 0x08)
++#define EMIF4_1_SDRAM_CONFIG2 (EMIF4_1_CFG_BASE + 0x0C)
++#define EMIF4_1_SDRAM_REF_CTRL (EMIF4_1_CFG_BASE + 0x10)
++#define EMIF4_1_SDRAM_REF_CTRL_SHADOW (EMIF4_1_CFG_BASE + 0x14)
++#define EMIF4_1_SDRAM_TIM_1 (EMIF4_1_CFG_BASE + 0x18)
++#define EMIF4_1_SDRAM_TIM_1_SHADOW (EMIF4_1_CFG_BASE + 0x1C)
++#define EMIF4_1_SDRAM_TIM_2 (EMIF4_1_CFG_BASE + 0x20)
++#define EMIF4_1_SDRAM_TIM_2_SHADOW (EMIF4_1_CFG_BASE + 0x24)
++#define EMIF4_1_SDRAM_TIM_3 (EMIF4_1_CFG_BASE + 0x28)
++#define EMIF4_1_SDRAM_TIM_3_SHADOW (EMIF4_1_CFG_BASE + 0x2C)
++#define EMIF4_1_DDR_PHY_CTRL_1 (EMIF4_1_CFG_BASE + 0xE4)
++#define EMIF4_1_DDR_PHY_CTRL_1_SHADOW (EMIF4_1_CFG_BASE + 0xE8)
++#define EMIF4_1_IODFT_TLGC (EMIF4_1_CFG_BASE + 0x60)
++
++#ifdef CONFIG_AM335X
++#define VTP0_CTRL_REG 0x44E10E0C
++#else
++#define VTP0_CTRL_REG 0x48140E0C
++#endif
++#define VTP1_CTRL_REG 0x48140E10
++
++/*EMIF4 PRCM Defintion*/
++#define CM_DEFAULT_L3_FAST_CLKSTCTRL (PRCM_BASE + 0x0508)
++#define CM_DEFAULT_EMIF_0_CLKCTRL (PRCM_BASE + 0x0520)
++#define CM_DEFAULT_EMIF_1_CLKCTRL (PRCM_BASE + 0x0524)
++#define CM_DEFAULT_DMM_CLKCTRL (PRCM_BASE + 0x0528)
++#define CM_DEFAULT_FW_CLKCTRL (PRCM_BASE + 0x052C)
++
++/* Smartreflex Registers */
++#define TI816X_SMRT_SCALE_ADDR (CTRL_BASE + 0x06A0)
++#define TI816X_SMRT_OPP_SVT_ADDR (CTRL_BASE + 0x06A8)
++#define TI816X_SMRT_OPP_HVT_ADDR (CTRL_BASE + 0x06AC)
++
++
++/* ALWON PRCM */
++#ifdef CONFIG_AM335X
++#define CM_ALWON_OCMC_0_CLKSTCTRL CM_PER_L3_CLKSTCTRL
++#define CM_ALWON_OCMC_0_CLKCTRL CM_PER_OCMCRAM_CLKCTRL
++#else
++#define CM_ALWON_OCMC_0_CLKSTCTRL (PRCM_BASE + 0x1414)
++#define CM_ALWON_OCMC_0_CLKCTRL (PRCM_BASE + 0x15B4)
++#endif
++
++#ifdef CONFIG_TI816X
++#define CM_ALWON_OCMC_1_CLKSTCTRL (PRCM_BASE + 0x1418)
++#define CM_ALWON_OCMC_1_CLKCTRL (PRCM_BASE + 0x15B8)
++#endif
++
++#ifdef CONFIG_AM335X
++#define CM_ALWON_GPMC_CLKCTRL CM_PER_GPMC_CLKCTRL
++#else
++#define CM_ALWON_GPMC_CLKCTRL (PRCM_BASE + 0x15D0)
++#endif
++
++/* OCMC */
++#ifdef CONFIG_TI816X
++#define SRAM0_SIZE (0x40000)
++#define SRAM_GPMC_STACK_SIZE (0x40)
++#endif
++
++#if defined(CONFIG_AM335X) || defined(CONFIG_TI814X)
++#define SRAM0_SIZE (0x1B400) /* 109 KB */
++#define SRAM_GPMC_STACK_SIZE (0x40)
++#endif
++
++#define LOW_LEVEL_SRAM_STACK (SRAM0_START + SRAM0_SIZE - 4)
++
++/* GPMC related */
++#define GPMC_CONFIG_CS0 (0x60)
++#define GPMC_CONFIG_CS0_BASE (GPMC_BASE + GPMC_CONFIG_CS0)
++#define GPMC_CONFIG1 (0x00)
++#define GPMC_CONFIG2 (0x04)
++#define GPMC_CONFIG3 (0x08)
++#define GPMC_CONFIG4 (0x0C)
++#define GPMC_CONFIG5 (0x10)
++#define GPMC_CONFIG6 (0x14)
++#define GPMC_CONFIG7 (0x18)
++
++/* PAD configuration register offsets and values for gpmc address
++ * lines a12 - a26
++ */
++#ifdef CONFIG_TI816X
++
++#define TIM7_OUT (CTRL_BASE + 0xb34) /* a12 */
++#define UART1_CTSN (CTRL_BASE + 0xadc) /* a13 */
++#define UART1_RTSN (CTRL_BASE + 0xad8) /* a14 */
++#define UART2_RTSN (CTRL_BASE + 0xae8) /* a15 */
++#define SC1_RST (CTRL_BASE + 0xb10) /* a15 */
++#define UART2_CTSN (CTRL_BASE + 0xaec) /* a16 */
++#define UART0_RIN (CTRL_BASE + 0xacc) /* a17 */
++#define UART0_DCDN (CTRL_BASE + 0xac8) /* a18 */
++#define UART0_DSRN (CTRL_BASE + 0xac4) /* a19 */
++#define UART0_DTRN (CTRL_BASE + 0xac0) /* a20 */
++#define SPI_SCS3 (CTRL_BASE + 0xaa4) /* a21 */
++#define SPI_SC2 (CTRL_BASE + 0xaa0) /* a22 */
++#define GPO_IO6 (CTRL_BASE + 0xca0) /* a23 */
++#define TIM6_OUT (CTRL_BASE + 0xb30) /* a24 */
++#define SC0_DATA (CTRL_BASE + 0xafc) /* a25 */
++#define GPMC_A27 (CTRL_BASE + 0xba0) /* a27 */
++
++/* MMC Pad register offsets */
++#define MMC_POW (CTRL_BASE + 0xa70)
++#define MMC_CLK (CTRL_BASE + 0xa74)
++#define MMC_CMD (CTRL_BASE + 0xa78)
++#define MMC_DAT0 (CTRL_BASE + 0xa7c)
++#define MMC_DAT1_SDIRQ (CTRL_BASE + 0xa80)
++#define MMC_DAT2_SDRW (CTRL_BASE + 0xa84)
++#define MMC_DAT3 (CTRL_BASE + 0xa88)
++
++#define GPMC_A12 TIM7_OUT
++#define GPMC_A13 UART1_CTSN
++#define GPMC_A14 UART1_RTSN
++#define GPMC_A15 UART2_RTSN
++#define GPMC_A16 UART2_CTSN
++#define GPMC_A17 UART0_RIN
++#define GPMC_A18 UART0_DCDN
++#define GPMC_A19 UART0_DSRN
++#define GPMC_A20 UART0_DTRN
++#define GPMC_A21 SPI_SCS3
++#define GPMC_A22 SPI_SC2
++#define GPMC_A23 GPO_IO6
++#define GPMC_A24 TIM6_OUT
++#define GPMC_A25 SC0_DATA
++#endif
++
++#ifdef CONFIG_AM335X
++#define GPMC_A12 (CTRL_BASE + 0x8c0) /* LCD_DATA8 */
++#define GPMC_A13 (CTRL_BASE + 0x8c4) /* LCD_DATA9 */
++#define GPMC_A14 (CTRL_BASE + 0x8c8) /* LCD_DATA10 */
++#define GPMC_A15 (CTRL_BASE + 0x8cc) /* LCD_DATA11 */
++#define GPMC_A16 (CTRL_BASE + 0x8d0) /* LCD_DATA12 */
++#define GPMC_A17 (CTRL_BASE + 0x8d4) /* LCD_DATA13 */
++#define GPMC_A18 (CTRL_BASE + 0x8d8) /* LCD_DATA14 */
++#define GPMC_A19 (CTRL_BASE + 0x8dc) /* LCD_DATA15 */
++#define GPMC_A20 (CTRL_BASE + 0x850) /* GPMC_A4 */
++#define GPMC_A21 (CTRL_BASE + 0x854) /* GPMC_A5 */
++#define GPMC_A22 (CTRL_BASE + 0x858) /* GPMC_A6 */
++
++/* DDR offsets */
++#define DDR_PHY_BASE_ADDR 0x44E12000
++#define DDR_IO_CTRL 0x44E10E04
++#define DDR_CKE_CTRL 0x44E1131C
++#define CONTROL_BASE_ADDR 0x44E10000
++
++#define DDR_CMD0_IOCTRL (CONTROL_BASE_ADDR + 0x1404)
++#define DDR_CMD1_IOCTRL (CONTROL_BASE_ADDR + 0x1408)
++#define DDR_CMD2_IOCTRL (CONTROL_BASE_ADDR + 0x140C)
++#define DDR_DATA0_IOCTRL (CONTROL_BASE_ADDR + 0x1440)
++#define DDR_DATA1_IOCTRL (CONTROL_BASE_ADDR + 0x1444)
++
++#define CMD0_CTRL_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x01C)
++#define CMD0_CTRL_SLAVE_FORCE_0 (DDR_PHY_BASE_ADDR + 0x020)
++#define CMD0_CTRL_SLAVE_DELAY_0 (DDR_PHY_BASE_ADDR + 0x024)
++#define CMD0_DLL_LOCK_DIFF_0 (DDR_PHY_BASE_ADDR + 0x028)
++#define CMD0_INVERT_CLKOUT_0 (DDR_PHY_BASE_ADDR + 0x02C)
++
++#define CMD1_CTRL_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x050)
++#define CMD1_CTRL_SLAVE_FORCE_0 (DDR_PHY_BASE_ADDR + 0x054)
++#define CMD1_CTRL_SLAVE_DELAY_0 (DDR_PHY_BASE_ADDR + 0x058)
++#define CMD1_DLL_LOCK_DIFF_0 (DDR_PHY_BASE_ADDR + 0x05C)
++#define CMD1_INVERT_CLKOUT_0 (DDR_PHY_BASE_ADDR + 0x060)
++
++#define CMD2_CTRL_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x084)
++#define CMD2_CTRL_SLAVE_FORCE_0 (DDR_PHY_BASE_ADDR + 0x088)
++#define CMD2_CTRL_SLAVE_DELAY_0 (DDR_PHY_BASE_ADDR + 0x08C)
++#define CMD2_DLL_LOCK_DIFF_0 (DDR_PHY_BASE_ADDR + 0x090)
++#define CMD2_INVERT_CLKOUT_0 (DDR_PHY_BASE_ADDR + 0x094)
++
++#define DATA0_RD_DQS_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x0C8)
++#define DATA0_RD_DQS_SLAVE_RATIO_1 (DDR_PHY_BASE_ADDR + 0x0CC)
++#define DATA0_WR_DQS_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x0DC)
++
++#define DATA0_WR_DQS_SLAVE_RATIO_1 (DDR_PHY_BASE_ADDR + 0x0E0)
++#define DATA0_WRLVL_INIT_RATIO_0 (DDR_PHY_BASE_ADDR + 0x0F0)
++
++#define DATA0_WRLVL_INIT_RATIO_1 (DDR_PHY_BASE_ADDR + 0x0F4)
++#define DATA0_GATELVL_INIT_RATIO_0 (DDR_PHY_BASE_ADDR + 0x0FC)
++
++#define DATA0_GATELVL_INIT_RATIO_1 (DDR_PHY_BASE_ADDR + 0x100)
++#define DATA0_FIFO_WE_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x108)
++
++#define DATA0_FIFO_WE_SLAVE_RATIO_1 (DDR_PHY_BASE_ADDR + 0x10C)
++#define DATA0_WR_DATA_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x120)
++
++#define DATA0_WR_DATA_SLAVE_RATIO_1 (DDR_PHY_BASE_ADDR + 0x124)
++#define DATA0_DLL_LOCK_DIFF_0 (DDR_PHY_BASE_ADDR + 0x138)
++
++#define DATA0_RANK0_DELAYS_0 (DDR_PHY_BASE_ADDR + 0x134)
++#define DATA1_RANK0_DELAYS_0 (DDR_PHY_BASE_ADDR + 0x1D8)
++
++#endif
++
++#ifndef __KERNEL_STRICT_NAMES
++#ifndef __ASSEMBLY__
++struct gpmc_cs {
++ u32 config1; /* 0x00 */
++ u32 config2; /* 0x04 */
++ u32 config3; /* 0x08 */
++ u32 config4; /* 0x0C */
++ u32 config5; /* 0x10 */
++ u32 config6; /* 0x14 */
++ u32 config7; /* 0x18 */
++ u32 nand_cmd; /* 0x1C */
++ u32 nand_adr; /* 0x20 */
++ u32 nand_dat; /* 0x24 */
++ u8 res[8]; /* blow up to 0x30 byte */
++};
++
++struct bch_res_0_3 {
++ u32 bch_result_x[4];
++};
++
++
++
++struct gpmc {
++ u8 res1[0x10];
++ u32 sysconfig; /* 0x10 */
++ u8 res2[0x4];
++ u32 irqstatus; /* 0x18 */
++ u32 irqenable; /* 0x1C */
++ u8 res3[0x20];
++ u32 timeout_control; /* 0x40 */
++ u8 res4[0xC];
++ u32 config; /* 0x50 */
++ u32 status; /* 0x54 */
++ u8 res5[0x8]; /* 0x58 */
++ struct gpmc_cs cs[8]; /* 0x60, 0x90, .. */
++ u8 res6[0x14]; /* 0x1E0 */
++ u32 ecc_config; /* 0x1F4 */
++ u32 ecc_control; /* 0x1F8 */
++ u32 ecc_size_config; /* 0x1FC */
++ u32 ecc1_result; /* 0x200 */
++ u32 ecc2_result; /* 0x204 */
++ u32 ecc3_result; /* 0x208 */
++ u32 ecc4_result; /* 0x20C */
++ u32 ecc5_result; /* 0x210 */
++ u32 ecc6_result; /* 0x214 */
++ u32 ecc7_result; /* 0x218 */
++ u32 ecc8_result; /* 0x21C */
++ u32 ecc9_result; /* 0x220 */
++ u8 res7[12]; /* 0x224 */
++ u32 testmomde_ctrl; /* 0x230 */
++ u8 res8[12]; /* 0x234 */
++ struct bch_res_0_3 bch_result_0_3[2]; /* 0x240 */
++};
++
++/* Used for board specific gpmc initialization */
++extern struct gpmc *gpmc_cfg;
++
++#endif /* __ASSEMBLY__ */
++#endif /* __KERNEL_STRICT_NAMES */
++
++/* Ethernet MAC ID from EFuse */
++#define MAC_ID0_LO (CTRL_BASE + 0x630)
++#define MAC_ID0_HI (CTRL_BASE + 0x634)
++#define MAC_ID1_LO (CTRL_BASE + 0x638)
++#define MAC_ID1_HI (CTRL_BASE + 0x63c)
++#define MAC_MII_SEL (CTRL_BASE + 0x650)
++
++/* WDT related */
++/* TODO: Move to a new file */
++#define WDT_WDSC (WDT_BASE + 0x010)
++#define WDT_WDST (WDT_BASE + 0x014)
++#define WDT_WISR (WDT_BASE + 0x018)
++#define WDT_WIER (WDT_BASE + 0x01C)
++#define WDT_WWER (WDT_BASE + 0x020)
++#define WDT_WCLR (WDT_BASE + 0x024)
++#define WDT_WCRR (WDT_BASE + 0x028)
++#define WDT_WLDR (WDT_BASE + 0x02C)
++#define WDT_WTGR (WDT_BASE + 0x030)
++#define WDT_WWPS (WDT_BASE + 0x034)
++#define WDT_WDLY (WDT_BASE + 0x044)
++#define WDT_WSPR (WDT_BASE + 0x048)
++#define WDT_WIRQEOI (WDT_BASE + 0x050)
++#define WDT_WIRQSTATRAW (WDT_BASE + 0x054)
++#define WDT_WIRQSTAT (WDT_BASE + 0x058)
++#define WDT_WIRQENSET (WDT_BASE + 0x05C)
++#define WDT_WIRQENCLR (WDT_BASE + 0x060)
++
++#define WDT_UNFREEZE (CTRL_BASE + 0x100)
++
++#endif /* _TI816X_CPU_H */
++
+diff --git a/arch/arm/include/asm/arch-ti81xx/ddr_defs.h b/arch/arm/include/asm/arch-ti81xx/ddr_defs.h
+new file mode 100644
+index 0000000..6c4b422
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/ddr_defs.h
+@@ -0,0 +1,362 @@
++/*
++ * Copyright (C) 2010 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.
++ * ----------------------------------------------------------------------------
++ *
++ */
++
++#ifndef _DDR_DEFS_H
++#define _DDR_DEFS_H
++
++#include <asm/arch/hardware.h>
++
++#ifdef CONFIG_TI816X_EVM_DDR3
++
++#define CONFIG_TI816X_DDR3_400 /* Values supported 400,531,675,796 */
++#define CONFIG_TI816X_DDR3_SW_LEVELING /* Enable software leveling as part of DDR3 init*/
++
++
++/*
++ * DDR3 force values. These are board dependent
++ */
++
++/* EVM 400 MHz clock Settings
++ * EVM has only a single RANK (chip select) */
++#define N_RANK 1
++
++/*
++ * Invert clock adds an additional half cycle delay on the command
++ * interface. The additional half cycle, is usually meant to enable
++ * leveling in the situation that DQS is later than CK on the board. It
++ * also helps provide some additional margin for leveling.
++ *
++ * For the EVM this is helping us with additional room for the write
++ * leveling. Since the dqs delays are very small.
++ */
++#define INVERT_CLOCK 1
++
++/*
++ * CMD_SLAVE_RATIO determines where is the command placed with respect
++ * to the clock edge. This is a ratio, implying 0x100 is one cycle.
++ * Ideally the command is centered so - this should be half cycle
++ * delay (0x80). But if invert clock is in use, an additional half
++ * cycle must be added
++ */
++#define CMD_SLAVE_FROM_INV_CLOCK(i) (((i)==0) ? 0x80 : 0x100)
++#define CMD_SLAVE_RATIO CMD_SLAVE_FROM_INV_CLOCK(INVERT_CLOCK)
++
++#ifdef TI816X_DDR3_PG_1_0
++/*
++ * EMIF PHY allows for controlling write DQS delay w.r.t. clock. The
++ * value may be forced or use values determined from the leveling
++ * process. Since we are doing the leveling - these are actually
++ * don't care and are not used. The force is in delay units
++ */
++#define WR_DQS_FORCE_3 0x00000010
++#define WR_DQS_FORCE_2 0x00000010
++#define WR_DQS_FORCE_1 0x00000010
++#define WR_DQS_FORCE_0 0x00000010
++
++/*
++ * EMIF PHY allows for controlling how much the read DQS must be
++ * delayed to sample the data correctly. Ideally this is about half a
++ * cycle. The force here is delay units. The value here is in use -
++ * as the current leveling process may not obtain this reliably. The
++ * value has been determined via various tests on the EVM and changing
++ * this setting is no recomended.
++ */
++#define RD_DQS_FORCE_0 0x00000028
++#define RD_DQS_FORCE_1 0x00000028
++#define RD_DQS_FORCE_2 0x00000028
++#define RD_DQS_FORCE_3 0x00000028
++
++/*
++ * read gate represents the round trip delay from command to read data
++ * on the board + some package delay. This is the period for which
++ * the bust may be tristated between a write and a read command and
++ * hence must not be sampled (gated off). This is actually determined
++ * via the read leveling process and hence this value is a don't care
++ * for the EVM
++ */
++#define RD_GATE_FORCE_3 0x44
++#define RD_GATE_FORCE_2 0x44
++#define RD_GATE_FORCE_1 0x44
++#define RD_GATE_FORCE_0 0x44
++
++#endif
++
++/*
++ * This represents the initial value for the leveling process. The
++ * value is a ratio - so 0x100 represents one cycle. The real delay
++ * is determined through the leveling process.
++ *
++ * During the leveling process, 0x20 is subtracted from the value, so
++ * we have added that to the value we want to set. We also set the
++ * values such that byte3 completes leveling after byte2 and byte1
++ * after byte0.
++ */
++#define WR_DQS_RATIO_0 0x20
++#define WR_DQS_RATIO_1 0x20
++#define WR_DQS_RATIO_2 0x20
++#define WR_DQS_RATIO_3 0x20
++
++#ifdef TI816X_DDR3_PG_1_0
++/*
++ * read dqs ratio is only used in DDR2
++ */
++#define RD_DQS_RATIO_0 0x40
++#define RD_DQS_RATIO_1 0x40
++#define RD_DQS_RATIO_2 0x40
++#define RD_DQS_RATIO_3 0x40
++#endif
++
++/*
++ * This represents the initial value for the leveling process. The
++ * value is a ratio - so 0x100 represents one cycle. The real delay
++ * is determined through the leveling process.
++ *
++ * During the leveling process, 0x20 is subtracted from the value, so
++ * we have added that to the value we want to set. We also set the
++ * values such that byte3 completes leveling after byte2 and byte1
++ * after byte0.
++ */
++#define RD_GATE_RATIO_0 0x20
++#define RD_GATE_RATIO_1 0x20
++#define RD_GATE_RATIO_2 0x20
++#define RD_GATE_RATIO_3 0x20
++
++#ifdef TI816X_DDR3_PG_1_0
++/*
++ * currently there is an issue with the automatic training process for
++ * DDR3 by setting the initial leveling ratios appropriately we are
++ * able to work arround write leveling and read gate leveling. How
++ * ever the automatic process may not work well for the read eye
++ * training (determining rd dqs delay). To work arround this - we
++ * leverage the pre-knowledge of a working RD DQS delay and make the
++ * leveling process complete by forcing good and bad values
++ * This is enabled via HACK_EYE_TRAINING
++ */
++#define HACK_EYE_TRAINING 0
++
++/*
++ * only the rd dqs delay needs to be forced. Others are determined via the leveling process
++ */
++#define USE_WR_DQS_FORCE 0
++#define USE_RD_DQS_FORCE HACK_EYE_TRAINING
++#define USE_RD_GATE_FORCE 0
++
++#endif
++/*
++ * data rate in MHz. The DDR clock will be 1/2 of this value
++ */
++#define DDR_DATA_RATE 800
++
++#define USE_EMIF0 1
++#define USE_EMIF1 1
++
++/*
++ * EMIF Paramters. Refer the EMIF register documentation and the
++ * memory datasheet for details
++ */
++/* For 400 MHz */
++#if defined(CONFIG_TI816X_DDR3_400)
++#define EMIF_TIM1 0x0CCCE524
++#define EMIF_TIM2 0x30308023
++#define EMIF_TIM3 0x009F82CF
++#define EMIF_SDREF 0x10000C30
++#define EMIF_SDCFG 0x62A41032
++#define EMIF_PHYCFG 0x0000010B
++
++#if defined(CONFIG_TI816X_DDR3_SW_LEVELING)
++/* These values are obtained from the CCS app */
++#define RD_DQS_GATE 0x12A
++#define RD_DQS 0x3B
++#define WR_DQS 0xA6
++#endif
++
++#endif /* CONFIG_TI816X_DDR3_400 */
++
++/* For 531 MHz */
++#if defined(CONFIG_TI816X_DDR3_531)
++#define EMIF_TIM1 0x0EF136AC
++#define EMIF_TIM2 0x30408063
++#define EMIF_TIM3 0x009F83AF
++#define EMIF_SDREF 0x1000102E
++#define EMIF_SDCFG 0x62A51832
++#define EMIF_PHYCFG 0x0000010C
++
++#if defined(CONFIG_TI816X_DDR3_SW_LEVELING)
++/* These values are obtained from the CCS app */
++#define RD_DQS_GATE 0x13D
++#define RD_DQS 0x39
++#define WR_DQS 0xB4
++#endif
++
++#endif /* CONFIG_TI816X_DDR_531 */
++
++/* For 675 MHz */
++#if defined(CONFIG_TI816X_DDR3_675)
++#define EMIF_TIM1 0x13358875
++#define EMIF_TIM2 0x5051806C
++#define EMIF_TIM3 0x009F84AF
++#define EMIF_SDREF 0x10001491
++#define EMIF_SDCFG 0x62A63032
++#define EMIF_PHYCFG 0x0000010F
++
++#if defined(CONFIG_TI816X_DDR3_SW_LEVELING)
++/* These values are obtained from the CCS app */
++#define RD_DQS_GATE 0x196
++#define RD_DQS 0x39
++#define WR_DQS 0x91
++
++#endif
++
++#endif /* CONFIG_TI816X_DDR3_675 */
++
++/* For 796 MHz */
++#if defined(CONFIG_TI816X_DDR3_796)
++#define EMIF_TIM1 0x1779C9FE
++#define EMIF_TIM2 0x50608074
++#define EMIF_TIM3 0x009F857F
++#define EMIF_SDREF 0x10001841
++#define EMIF_SDCFG 0x62A73832
++#define EMIF_PHYCFG 0x00000110
++
++#if defined(CONFIG_TI816X_DDR3_SW_LEVELING)
++/* These values are obtained from the CCS app */
++#define RD_DQS_GATE 0x1B3
++#define RD_DQS 0x35
++#define WR_DQS 0x93
++
++#endif
++
++#endif /* CONFIG_TI816X_DDR_796 */
++
++
++#if defined(CONFIG_TI816X_DDR3_SW_LEVELING)
++#define WR_DQS_RATIO_BYTE_LANE3 ((WR_DQS << 10) | WR_DQS)
++#define WR_DQS_RATIO_BYTE_LANE2 ((WR_DQS << 10) | WR_DQS)
++#define WR_DQS_RATIO_BYTE_LANE1 ((WR_DQS << 10) | WR_DQS)
++#define WR_DQS_RATIO_BYTE_LANE0 ((WR_DQS << 10) | WR_DQS)
++
++#define WR_DATA_RATIO_BYTE_LANE3 (((WR_DQS + 0x40) << 10) | (WR_DQS + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE2 (((WR_DQS + 0x40) << 10) | (WR_DQS + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE1 (((WR_DQS + 0x40) << 10) | (WR_DQS + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE0 (((WR_DQS + 0x40) << 10) | (WR_DQS + 0x40))
++
++#define RD_DQS_RATIO ((RD_DQS << 10) | RD_DQS)
++
++#define DQS_GATE_BYTE_LANE0 ((RD_DQS_GATE << 10) | RD_DQS_GATE)
++#define DQS_GATE_BYTE_LANE1 ((RD_DQS_GATE << 10) | RD_DQS_GATE)
++#define DQS_GATE_BYTE_LANE2 ((RD_DQS_GATE << 10) | RD_DQS_GATE)
++#define DQS_GATE_BYTE_LANE3 ((RD_DQS_GATE << 10) | RD_DQS_GATE)
++
++#endif /* CONFIG_TI816X_DDR3_SW_LEVELING */
++
++#endif /* CONFIG_TI816X_EVM_DDR3 */
++
++#ifdef CONFIG_TI816X_EVM_DDR2
++
++#define INVERT_CLK_OUT 0x0
++#define CMD_SLAVE_RATIO 0x80
++/*
++ * DDR2 ratio values. These are board dependent
++ * obtained from sweep experiments
++ */
++
++/* EVM 400 MHz clock Settings */
++
++#define WR_DQS_RATIO_BYTE_LANE3 ((0x4a << 10) | 0x4a)
++#define WR_DQS_RATIO_BYTE_LANE2 ((0x4a << 10) | 0x4a)
++#define WR_DQS_RATIO_BYTE_LANE1 ((0x4a << 10) | 0x4a)
++#define WR_DQS_RATIO_BYTE_LANE0 ((0x4a << 10) | 0x4a)
++
++#define WR_DATA_RATIO_BYTE_LANE3 (((0x4a + 0x40) << 10) | (0x4a + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE2 (((0x4a + 0x40) << 10) | (0x4a + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE1 (((0x4a + 0x40) << 10) | (0x4a + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE0 (((0x4a + 0x40) << 10) | (0x4a + 0x40))
++
++#define RD_DQS_RATIO ((0x40 << 10) | 0x40)
++
++#define DQS_GATE_BYTE_LANE0 ((0x13a << 10) | 0x13a)
++#define DQS_GATE_BYTE_LANE1 ((0x13a << 10) | 0x13a)
++#define DQS_GATE_BYTE_LANE2 ((0x13a << 10) | 0x13a)
++#define DQS_GATE_BYTE_LANE3 ((0x13a << 10) | 0x13a)
++
++/*
++ * EMIF Paramters
++ */
++#define EMIF_TIM1 0xAAB15E2
++#define EMIF_TIM2 0x423631D2
++#define EMIF_TIM3 0x80032F
++#define EMIF_SDREF 0x10000C30
++#define EMIF_SDCFG 0x43801A3A /* 32 bit ddr2, CL=6, CWL=5, 13 rows, 8 banks, 10 bit column, 2 CS */
++#define EMIF_PHYCFG 0x0000010B /* local odt = 1, read latency = 11 (max = 12, min=6) */
++
++#endif /* CONFIG_TI816X_EVM_DDR2 */
++
++#ifdef CONFIG_TI814X_EVM_DDR2
++/* ti814x specific settings to be added */
++#endif
++
++/* AM335X EMIF Register values */
++#ifdef CONFIG_AM335X
++#define EMIF_SDMGT 0x80000000
++#define EMIF_SDRAM 0x00004650
++#define EMIF_PHYCFG 0x2
++#define DDR_PHY_RESET (0x1 << 10)
++#define DDR_FUNCTIONAL_MODE_EN 0x1
++#define DDR_PHY_READY (0x1 << 2)
++#define VTP_CTRL_READY (0x1 << 5)
++#define VTP_CTRL_ENABLE (0x1 << 6)
++#define VTP_CTRL_LOCK_EN (0x1 << 4)
++#define VTP_CTRL_START_EN (0x1)
++#define DDR2_RATIO 0x80 /* for mDDR */
++#define CMD_FORCE 0x00 /* common #def */
++#define CMD_DELAY 0x00
++#if (CONFIG_AM335X_EVM_IS_13x13 == 1)
++#define EMIF_READ_LATENCY 0x05
++#define EMIF_TIM1 0x04446249
++#define EMIF_TIM2 0x101731C0
++#define EMIF_TIM3 0x137
++#define EMIF_SDCFG 0x20004EA3
++#define EMIF_SDREF 0x57c
++#define DDR2_DLL_LOCK_DIFF 0x4
++#define DDR2_RD_DQS 0x40
++#define DDR2_PHY_FIFO_WE 0x56
++#else
++#define EMIF_READ_LATENCY 0x04
++#define EMIF_TIM1 0x0666B3D6
++#define EMIF_TIM2 0x143731DA
++#define EMIF_TIM3 0x00000347
++#define EMIF_SDCFG 0x43805332
++#define EMIF_SDREF 0x0000081a
++#define DDR2_DLL_LOCK_DIFF 0x0
++#define DDR2_RD_DQS 0x12
++#define DDR2_PHY_FIFO_WE 0x80
++#endif
++#define DDR2_INVERT_CLKOUT 0x00
++#define DDR2_WR_DQS 0x00
++#define DDR2_PHY_WRLVL 0x00
++#define DDR2_PHY_GATELVL 0x00
++#define DDR2_PHY_WR_DATA 0x40
++#define PHY_RANK0_DELAY 0x01
++#define PHY_DLL_LOCK_DIFF 0x0
++#define DDR_IOCTRL_VALUE 0x18B
++#endif
++
++#endif /* _DDR_DEFS_H */
++
+diff --git a/arch/arm/include/asm/arch-ti81xx/emac_defs.h b/arch/arm/include/asm/arch-ti81xx/emac_defs.h
+new file mode 100644
+index 0000000..1cd571c
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/emac_defs.h
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (C) 2010 Texas Instruments
++ *
++ * 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.
++ * ver. 2.0: May 2010, TI PSP Team - Cleanup, move platform independent
++ * portion to driver header file.
++ *
++ */
++
++#ifndef _EMAC_DEFS_H_
++#define _EMAC_DEFS_H_
++
++#include <asm/arch/hardware.h>
++
++#ifdef CONFIG_TI81XX
++#define EMAC_BASE_ADDR (0x4A100000)
++#define EMAC_WRAPPER_BASE_ADDR (0x4A100900)
++#define EMAC_WRAPPER_RAM_ADDR (0x4A102000)
++#define EMAC_MDIO_BASE_ADDR (0x4A100800)
++#define DAVINCI_EMAC_VERSION2
++#define DAVINCI_EMAC_GIG_ENABLE
++
++#define EMAC_MDIO_BUS_FREQ (250000000UL)
++#define EMAC_MDIO_CLOCK_FREQ (2000000UL)
++
++/*TODO: verify Phy address */
++#define EMAC_MDIO_PHY_NUM (1)
++#define EMAC_MDIO_PHY_MASK (1 << EMAC_MDIO_PHY_NUM)
++#endif
++
++#endif /* _DM644X_EMAC_H_ */
++
+diff --git a/arch/arm/include/asm/arch-ti81xx/hardware.h b/arch/arm/include/asm/arch-ti81xx/hardware.h
+new file mode 100644
+index 0000000..ee4256a
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/hardware.h
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (C) 2009, Texas Instruments, Incorporated
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __TI81XX_HARDWARE_H
++#define __TI81XX_HARDWARE_H
++
++/* The objective is to keep only the overall memory map here
++ * The break-up of the memory map for individual modules registers should
++ * be in a different file like cpu.h so that this is the only place
++ * where change is needed for new SoCs when the IP is otherwise the same
++ */
++#ifdef CONFIG_AM335X
++#define SRAM0_START 0x402F0400
++#else
++#define SRAM0_START 0x40300000
++#endif
++#ifdef CONFIG_AM335X
++#define UART0_BASE 0x44E09000
++#else
++#define UART0_BASE 0x48020000
++#endif
++#define UART1_BASE 0x48022000
++#define UART2_BASE 0x48024000
++#define UART3_BASE 0x481A6000
++
++/* DM Timer base addresses */
++#define DM_TIMER0_BASE 0x4802C000
++#define DM_TIMER1_BASE 0x4802E000
++#define DM_TIMER2_BASE 0x48040000
++#define DM_TIMER3_BASE 0x48042000
++#define DM_TIMER4_BASE 0x48044000
++#define DM_TIMER5_BASE 0x48046000
++#define DM_TIMER6_BASE 0x48048000
++#define DM_TIMER7_BASE 0x4804A000
++
++/* GPIO Base address */
++#define GPIO0_BASE 0x48032000
++#define GPIO1_BASE 0x4804C000
++#ifdef CONFIG_AM335X
++#define GPIO2_BASE 0x481AC000
++#endif
++/* BCH Error Location Module */
++#define ELM_BASE 0x48080000
++
++/* Watchdog Timer */
++#ifdef CONFIG_AM335X
++#define WDT_BASE 0x44E35000
++#else
++#define WDT_BASE 0x480C2000
++#endif
++
++/* Control Module Base Address */
++#ifdef CONFIG_AM335X
++#define CTRL_BASE 0x44E10000
++#else
++#define CTRL_BASE 0x48140000
++#endif
++
++/* PRCM Base Address */
++#ifdef CONFIG_AM335X
++#define PRCM_BASE 0x44E00000
++#else
++#define PRCM_BASE 0x48180000
++#endif
++
++/* PLL Subsystem Base Address */
++#ifdef CONFIG_TI814X
++#define PLL_SUBSYS_BASE 0x481C5000
++#endif
++
++/* EMIF Base address */
++#define EMIF4_0_CFG_BASE 0x4C000000
++#define EMIF4_1_CFG_BASE 0x4D000000
++#define DMM_BASE 0x4E000000
++
++#ifdef CONFIG_TI816X
++#define DDRPHY_0_CONFIG_BASE 0x48198000
++#define DDRPHY_1_CONFIG_BASE 0x4819a000
++#define DDRPHY_CONFIG_BASE ((emif == 0) ? DDRPHY_0_CONFIG_BASE:DDRPHY_1_CONFIG_BASE)
++#endif
++
++#ifdef CONFIG_TI814X
++#define DDRPHY_0_CONFIG_BASE (CTRL_BASE + 0x1400)
++#define DDRPHY_1_CONFIG_BASE (CTRL_BASE + 0x1500)
++#define DDRPHY_CONFIG_BASE ((emif == 0) ? DDRPHY_0_CONFIG_BASE:DDRPHY_1_CONFIG_BASE)
++#endif
++
++#ifdef CONFIG_AM335X
++#define DDRPHY_0_CONFIG_BASE (CTRL_BASE + 0x1400)
++#define DDRPHY_CONFIG_BASE DDRPHY_0_CONFIG_BASE
++#endif
++
++/* GPMC Base address */
++#define GPMC_BASE 0x50000000
++
++/* CPSW Config space */
++#define TI814X_CPSW_BASE 0x4A100000
++#define TI814X_CPSW_MDIO_BASE 0x4A100800
++
++#define AM335X_CPSW_BASE 0x4A100000
++#define AM335X_CPSW_MDIO_BASE 0x4A101000
++
++#endif /* __TI81XX_HARDWARE_H */
++
+diff --git a/arch/arm/include/asm/arch-ti81xx/i2c.h b/arch/arm/include/asm/arch-ti81xx/i2c.h
+new file mode 100644
+index 0000000..31a5581
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/i2c.h
+@@ -0,0 +1,212 @@
++/*
++ * (C) Copyright 2004-2008
++ * Texas Instruments, <www.ti.com>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#ifndef _I2C_H_
++#define _I2C_H_
++
++#ifdef CONFIG_AM335X
++#define I2C_BASE1 0x44E0B000
++#define I2C_BASE2 0x4802A000
++#define I2C_BASE3 0x4819C000
++#define I2C_BUS_MAX 3
++#else
++#define I2C_BASE1 0x48028000
++#define I2C_BASE2 0x4802A000
++#define I2C_BUS_MAX 2
++#endif
++
++#define I2C_DEFAULT_BASE I2C_BASE1
++#define I2C_IP_CLK 48000000
++#define I2C_INTERNAL_SAMPLING_CLK 12000000
++
++#define I2C_REV (I2C_DEFAULT_BASE + 0x00)
++#define I2C_IE (I2C_DEFAULT_BASE + 0x2C)
++#define I2C_STAT (I2C_DEFAULT_BASE + 0x28)
++#define I2C_BUF (I2C_DEFAULT_BASE + 0x94)
++#define I2C_CNT (I2C_DEFAULT_BASE + 0x98)
++#define I2C_DATA (I2C_DEFAULT_BASE + 0x9c)
++#define I2C_CON (I2C_DEFAULT_BASE + 0xA4)
++#define I2C_OA (I2C_DEFAULT_BASE + 0xA8)
++#define I2C_SA (I2C_DEFAULT_BASE + 0xAC)
++#define I2C_PSC (I2C_DEFAULT_BASE + 0xB0)
++#define I2C_SCLL (I2C_DEFAULT_BASE + 0xB4)
++#define I2C_SCLH (I2C_DEFAULT_BASE + 0xB8)
++#define I2C_SYSTEST (I2C_DEFAULT_BASE + 0xBc)
++
++/* I2C masks */
++
++/* I2C Interrupt Enable Register (I2C_IE): */
++#define I2C_IE_GC_IE (1 << 5)
++#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_SBD (1 << 15) /* Single byte data */
++#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_GC (1 << 5)
++#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 */
++
++/* I2C Buffer Configuration Register (I2C_BUF): */
++
++#define I2C_BUF_RDMA_EN (1 << 15) /* Receive DMA channel enable */
++#define I2C_BUF_XDMA_EN (1 << 7) /* Transmit DMA channel enable */
++#define I2C_TXFIFO_CLEAR (1 << 6) /* TX FIFO clear */
++#define I2C_RXFIFO_CLEAR (1 << 14) /* RX FIFO Clear */
++
++/* I2C Configuration Register (I2C_CON): */
++
++#define I2C_CON_EN (1 << 15) /* I2C module enable */
++#define I2C_CON_BE (1 << 14) /* Big endian mode */
++#define I2C_CON_STB (1 << 11) /* 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 << 1) /* Stop condition (master mode only) */
++#define I2C_CON_STT (1 << 0) /* Start condition (master mode only) */
++
++/* I2C System Test Register (I2C_SYSTEST): */
++
++#define I2C_SYSTEST_ST_EN (1 << 15) /* System test enable */
++#define I2C_SYSTEST_FREE (1 << 14) /* Free running mode, on brkpoint) */
++#define I2C_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select */
++#define I2C_SYSTEST_TMODE_SHIFT (12) /* Test mode select */
++#define I2C_SYSTEST_SCL_I (1 << 3) /* SCL line sense input value */
++#define I2C_SYSTEST_SCL_O (1 << 2) /* SCL line drive output value */
++#define I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense input value */
++#define I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive output value */
++
++#define I2C_SCLL_SCLL 0
++#define I2C_SCLL_SCLL_M 0xFF
++#define I2C_SCLL_HSSCLL 8
++#define I2C_SCLH_HSSCLL_M 0xFF
++#define I2C_SCLH_SCLH 0
++#define I2C_SCLH_SCLH_M 0xFF
++#define I2C_SCLH_HSSCLH 8
++#define I2C_SCLH_HSSCLH_M 0xFF
++
++#define OMAP_I2C_STANDARD 100000
++#define OMAP_I2C_FAST_MODE 400000
++#define OMAP_I2C_HIGH_SPEED 3400000
++
++#define SYSTEM_CLOCK_12 12000000
++#define SYSTEM_CLOCK_13 13000000
++#define SYSTEM_CLOCK_192 19200000
++#define SYSTEM_CLOCK_96 96000000
++
++/* Use the reference value of 96MHz if not explicitly set by the board */
++#ifndef I2C_IP_CLK
++#define I2C_IP_CLK SYSTEM_CLOCK_96
++#endif
++
++/*
++ * The reference minimum clock for high speed is 19.2MHz.
++ * The linux 2.6.30 kernel uses this value.
++ * The reference minimum clock for fast mode is 9.6MHz
++ * The reference minimum clock for standard mode is 4MHz
++ * In TRM, the value of 12MHz is used.
++ */
++#ifndef I2C_INTERNAL_SAMPLING_CLK
++#define I2C_INTERNAL_SAMPLING_CLK 19200000
++#endif
++
++/*
++ * The equation for the low and high time is
++ * tlow = scll + scll_trim = (sampling clock * tlow_duty) / speed
++ * thigh = sclh + sclh_trim = (sampling clock * (1 - tlow_duty)) / speed
++ *
++ * If the duty cycle is 50%
++ *
++ * tlow = scll + scll_trim = sampling clock / (2 * speed)
++ * thigh = sclh + sclh_trim = sampling clock / (2 * speed)
++ *
++ * In TRM
++ * scll_trim = 7
++ * sclh_trim = 5
++ *
++ * The linux 2.6.30 kernel uses
++ * scll_trim = 6
++ * sclh_trim = 6
++ *
++ * These are the trim values for standard and fast speed
++ */
++#ifndef I2C_FASTSPEED_SCLL_TRIM
++#define I2C_FASTSPEED_SCLL_TRIM 6
++#endif
++#ifndef I2C_FASTSPEED_SCLH_TRIM
++#define I2C_FASTSPEED_SCLH_TRIM 6
++#endif
++
++/* These are the trim values for high speed */
++#ifndef I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM
++#define I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM I2C_FASTSPEED_SCLL_TRIM
++#endif
++#ifndef I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM
++#define I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM I2C_FASTSPEED_SCLH_TRIM
++#endif
++#ifndef I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM
++#define I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM I2C_FASTSPEED_SCLL_TRIM
++#endif
++#ifndef I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM
++#define I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM I2C_FASTSPEED_SCLH_TRIM
++#endif
++
++/*
++#define OMAP_I2C_STANDARD 100
++#define OMAP_I2C_FAST_MODE 400
++#define OMAP_I2C_HIGH_SPEED 3400
++
++#define SYSTEM_CLOCK_12 12000
++#define SYSTEM_CLOCK_13 13000
++#define SYSTEM_CLOCK_192 19200
++#define SYSTEM_CLOCK_96 96000
++
++#define I2C_IP_CLK SYSTEM_CLOCK_12
++
++*/
++
++
++#define I2C_PSC_MAX 0x0f
++#define I2C_PSC_MIN 0x00
++
++#endif /* _I2C_H_ */
+diff --git a/arch/arm/include/asm/arch-ti81xx/mem.h b/arch/arm/include/asm/arch-ti81xx/mem.h
+new file mode 100644
+index 0000000..0ceb073
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/mem.h
+@@ -0,0 +1,181 @@
++/*
++ * (C) Copyright 2006-2008
++ * Texas Instruments, <www.ti.com>
++ *
++ * Author
++ * Mansoor Ahamed <mansoor.ahamed@ti.com>
++ *
++ * Initial Code from:
++ * Richard Woodruff <r-woodruff2@ti.com>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef _MEM_H_
++#define _MEM_H_
++
++#define CS0 0x0
++#define CS1 0x1 /* mirror CS1 regs appear offset 0x30 from CS0 */
++
++#ifndef __ASSEMBLY__
++enum {
++ STACKED = 0,
++ IP_DDR = 1,
++ COMBO_DDR = 2,
++ IP_SDR = 3,
++};
++#endif /* __ASSEMBLY__ */
++
++#define EARLY_INIT 1
++
++/*
++ * GPMC settings -
++ * Definitions is as per the following format
++ * #define <PART>_GPMC_CONFIG<x> <value>
++ * Where:
++ * PART is the part name e.g. STNOR - Intel Strata Flash
++ * x is GPMC config registers from 1 to 6 (there will be 6 macros)
++ * Value is corresponding value
++ *
++ * For every valid PRCM configuration there should be only one definition of
++ * the same. if values are independent of the board, this definition will be
++ * present in this file if values are dependent on the board, then this should
++ * go into corresponding mem-boardName.h file
++ *
++ * Currently valid part Names are (PART):
++ * STNOR - Intel Strata Flash
++ * SMNAND - Samsung NAND
++ * MPDB - H4 MPDB board
++ * SBNOR - Sibley NOR
++ * MNAND - Micron Large page x16 NAND
++ * ONNAND - Samsung One NAND
++ *
++ * include/configs/file.h contains the defn - for all CS we are interested
++ * #define OMAP34XX_GPMC_CSx PART
++ * #define OMAP34XX_GPMC_CSx_SIZE Size
++ * #define OMAP34XX_GPMC_CSx_MAP Map
++ * Where:
++ * x - CS number
++ * PART - Part Name as defined above
++ * SIZE - how big is the mapping to be
++ * GPMC_SIZE_128M - 0x8
++ * GPMC_SIZE_64M - 0xC
++ * GPMC_SIZE_32M - 0xE
++ * GPMC_SIZE_16M - 0xF
++ * MAP - Map this CS to which address(GPMC address space)- Absolute address
++ * >>24 before being used.
++ */
++#define GPMC_SIZE_256M 0x0
++#define GPMC_SIZE_128M 0x8
++#define GPMC_SIZE_64M 0xC
++#define GPMC_SIZE_32M 0xE
++#define GPMC_SIZE_16M 0xF
++
++#define SMNAND_GPMC_CONFIG1 0x00000800
++#define SMNAND_GPMC_CONFIG2 0x00141400
++#define SMNAND_GPMC_CONFIG3 0x00141400
++#define SMNAND_GPMC_CONFIG4 0x0F010F01
++#define SMNAND_GPMC_CONFIG5 0x010C1414
++#define SMNAND_GPMC_CONFIG6 0x1F0F0A80
++#define SMNAND_GPMC_CONFIG7 0x00000C44
++
++
++#ifdef CONFIG_AM335X /* SA 8-Bit Nand */
++#define M_NAND_GPMC_CONFIG1 0x00000800
++#else
++#define M_NAND_GPMC_CONFIG1 0x00001810
++#endif
++#define M_NAND_GPMC_CONFIG2 0x001e1e00
++#define M_NAND_GPMC_CONFIG3 0x001e1e00
++#define M_NAND_GPMC_CONFIG4 0x16051807
++#define M_NAND_GPMC_CONFIG5 0x00151e1e
++#define M_NAND_GPMC_CONFIG6 0x16000f80
++#define M_NAND_GPMC_CONFIG7 0x00000008
++
++#define STNOR_GPMC_CONFIG1 0x3
++#define STNOR_GPMC_CONFIG2 0x00151501
++#define STNOR_GPMC_CONFIG3 0x00060602
++#define STNOR_GPMC_CONFIG4 0x11091109
++#define STNOR_GPMC_CONFIG5 0x01141F1F
++#define STNOR_GPMC_CONFIG6 0x000004c4
++
++#define SIBNOR_GPMC_CONFIG1 0x1200
++#define SIBNOR_GPMC_CONFIG2 0x001f1f00
++#define SIBNOR_GPMC_CONFIG3 0x00080802
++#define SIBNOR_GPMC_CONFIG4 0x1C091C09
++#define SIBNOR_GPMC_CONFIG5 0x01131F1F
++#define SIBNOR_GPMC_CONFIG6 0x1F0F03C2
++
++#define SDPV2_MPDB_GPMC_CONFIG1 0x00611200
++#define SDPV2_MPDB_GPMC_CONFIG2 0x001F1F01
++#define SDPV2_MPDB_GPMC_CONFIG3 0x00080803
++#define SDPV2_MPDB_GPMC_CONFIG4 0x1D091D09
++#define SDPV2_MPDB_GPMC_CONFIG5 0x041D1F1F
++#define SDPV2_MPDB_GPMC_CONFIG6 0x1D0904C4
++
++#define MPDB_GPMC_CONFIG1 0x00011000
++#define MPDB_GPMC_CONFIG2 0x001f1f01
++#define MPDB_GPMC_CONFIG3 0x00080803
++#define MPDB_GPMC_CONFIG4 0x1c0b1c0a
++#define MPDB_GPMC_CONFIG5 0x041f1F1F
++#define MPDB_GPMC_CONFIG6 0x1F0F04C4
++
++#define P2_GPMC_CONFIG1 0x0
++#define P2_GPMC_CONFIG2 0x0
++#define P2_GPMC_CONFIG3 0x0
++#define P2_GPMC_CONFIG4 0x0
++#define P2_GPMC_CONFIG5 0x0
++#define P2_GPMC_CONFIG6 0x0
++
++#define ONENAND_GPMC_CONFIG1 0x00001200
++#define ONENAND_GPMC_CONFIG2 0x000F0F01
++#define ONENAND_GPMC_CONFIG3 0x00030301
++#define ONENAND_GPMC_CONFIG4 0x0F040F04
++#define ONENAND_GPMC_CONFIG5 0x010F1010
++#define ONENAND_GPMC_CONFIG6 0x1F060000
++
++#define NET_GPMC_CONFIG1 0x00001000
++#define NET_GPMC_CONFIG2 0x001e1e01
++#define NET_GPMC_CONFIG3 0x00080300
++#define NET_GPMC_CONFIG4 0x1c091c09
++#define NET_GPMC_CONFIG5 0x04181f1f
++#define NET_GPMC_CONFIG6 0x00000FCF
++#define NET_GPMC_CONFIG7 0x00000f6c
++
++/* max number of GPMC Chip Selects */
++#define GPMC_MAX_CS 8
++/* max number of GPMC regs */
++#define GPMC_MAX_REG 7
++
++#define PISMO1_NOR 1
++#define PISMO1_NAND 2
++#define PISMO2_CS0 3
++#define PISMO2_CS1 4
++#define PISMO1_ONENAND 5
++#define DBG_MPDB 6
++#define PISMO2_NAND_CS0 7
++#define PISMO2_NAND_CS1 8
++
++/* make it readable for the gpmc_init */
++#define PISMO1_NOR_BASE FLASH_BASE
++#define PISMO1_NAND_BASE NAND_BASE
++#define PISMO1_NAND_SIZE GPMC_SIZE_256M
++
++#endif /* endif _MEM_H_ */
++
+diff --git a/arch/arm/include/asm/arch-ti81xx/mmc.h b/arch/arm/include/asm/arch-ti81xx/mmc.h
+new file mode 100644
+index 0000000..196ffdc
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/mmc.h
+@@ -0,0 +1,242 @@
++/*
++ * (C) Copyright 2008
++ * Texas Instruments, <www.ti.com>
++ * Syed Mohammed Khasim <khasim@ti.com>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation's version 2 of
++ * the License.
++ *
++ * 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 MMC_H
++#define MMC_H
++
++#include "mmc_host_def.h"
++
++/* Responses */
++#define RSP_TYPE_NONE (RSP_TYPE_NORSP | CCCE_NOCHECK | CICE_NOCHECK)
++#define RSP_TYPE_R1 (RSP_TYPE_LGHT48 | CCCE_CHECK | CICE_CHECK)
++#define RSP_TYPE_R1B (RSP_TYPE_LGHT48B | CCCE_CHECK | CICE_CHECK)
++#define RSP_TYPE_R2 (RSP_TYPE_LGHT136 | CCCE_CHECK | CICE_NOCHECK)
++#define RSP_TYPE_R3 (RSP_TYPE_LGHT48 | CCCE_NOCHECK | CICE_NOCHECK)
++#define RSP_TYPE_R4 (RSP_TYPE_LGHT48 | CCCE_NOCHECK | CICE_NOCHECK)
++#define RSP_TYPE_R5 (RSP_TYPE_LGHT48 | CCCE_CHECK | CICE_CHECK)
++#define RSP_TYPE_R6 (RSP_TYPE_LGHT48 | CCCE_CHECK | CICE_CHECK)
++#define RSP_TYPE_R7 (RSP_TYPE_LGHT48 | CCCE_CHECK | CICE_CHECK)
++
++/* All supported commands */
++#define MMC_CMD0 (INDEX(0) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD1 (INDEX(1) | RSP_TYPE_R3 | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD2 (INDEX(2) | RSP_TYPE_R2 | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD3 (INDEX(3) | RSP_TYPE_R1 | DP_NO_DATA | DDIR_WRITE)
++#define MMC_SDCMD3 (INDEX(3) | RSP_TYPE_R6 | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD4 (INDEX(4) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD6 (INDEX(6) | RSP_TYPE_R1B | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD7_SELECT (INDEX(7) | RSP_TYPE_R1B | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD7_DESELECT (INDEX(7)| RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD8 (INDEX(8) | RSP_TYPE_R1 | DP_DATA | DDIR_READ)
++#define MMC_SDCMD8 (INDEX(8) | RSP_TYPE_R7 | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD9 (INDEX(9) | RSP_TYPE_R2 | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD12 (INDEX(12) | RSP_TYPE_R1B | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD13 (INDEX(13) | RSP_TYPE_R1 | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD15 (INDEX(15) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD16 (INDEX(16) | RSP_TYPE_R1 | DP_NO_DATA | DDIR_WRITE)
++#define MMC_CMD17 (INDEX(17) | RSP_TYPE_R1 | DP_DATA | DDIR_READ)
++#define MMC_CMD24 (INDEX(24) | RSP_TYPE_R1 | DP_DATA | DDIR_WRITE)
++#define MMC_ACMD6 (INDEX(6) | RSP_TYPE_R1 | DP_NO_DATA | DDIR_WRITE)
++#define MMC_ACMD41 (INDEX(41) | RSP_TYPE_R3 | DP_NO_DATA | DDIR_WRITE)
++#define MMC_ACMD51 (INDEX(51) | RSP_TYPE_R1 | DP_DATA | DDIR_READ)
++#define MMC_CMD55 (INDEX(55) | RSP_TYPE_R1 | DP_NO_DATA | DDIR_WRITE)
++
++#define MMC_AC_CMD_RCA_MASK (unsigned int)(0xFFFF << 16)
++#define MMC_BC_CMD_DSR_MASK (unsigned int)(0xFFFF << 16)
++#define MMC_DSR_DEFAULT 0x0404
++#define SD_CMD8_CHECK_PATTERN 0xAA
++#define SD_CMD8_2_7_3_6_V_RANGE (0x01 << 8)
++
++/* Clock Configurations and Macros */
++
++#define MMC_CLOCK_REFERENCE 96
++#define MMC_RELATIVE_CARD_ADDRESS 0x1234
++#define MMC_INIT_SEQ_CLK (MMC_CLOCK_REFERENCE * 1000 / 80)
++#define MMC_400kHz_CLK (MMC_CLOCK_REFERENCE * 1000 / 400)
++#define CLKDR(r, f, u) ((((r)*100) / ((f)*(u))) + 1)
++#define CLKD(f, u) (CLKDR(MMC_CLOCK_REFERENCE, f, u))
++
++#define MMC_OCR_REG_ACCESS_MODE_MASK (0x3 << 29)
++#define MMC_OCR_REG_ACCESS_MODE_BYTE (0x0 << 29)
++#define MMC_OCR_REG_ACCESS_MODE_SECTOR (0x2 << 29)
++
++#define MMC_OCR_REG_HOST_CAPACITY_SUPPORT_MASK (0x1 << 30)
++#define MMC_OCR_REG_HOST_CAPACITY_SUPPORT_BYTE (0x0 << 30)
++#define MMC_OCR_REG_HOST_CAPACITY_SUPPORT_SECTOR (0x1 << 30)
++
++#define MMC_SD2_CSD_C_SIZE_LSB_MASK 0xFFFF
++#define MMC_SD2_CSD_C_SIZE_MSB_MASK 0x003F
++#define MMC_SD2_CSD_C_SIZE_MSB_OFFSET 16
++#define MMC_CSD_C_SIZE_LSB_MASK 0x0003
++#define MMC_CSD_C_SIZE_MSB_MASK 0x03FF
++#define MMC_CSD_C_SIZE_MSB_OFFSET 2
++
++#define MMC_CSD_TRAN_SPEED_UNIT_MASK (0x07 << 0)
++#define MMC_CSD_TRAN_SPEED_FACTOR_MASK (0x0F << 3)
++#define MMC_CSD_TRAN_SPEED_UNIT_100MHZ (0x3 << 0)
++#define MMC_CSD_TRAN_SPEED_FACTOR_1_0 (0x01 << 3)
++#define MMC_CSD_TRAN_SPEED_FACTOR_8_0 (0x0F << 3)
++
++typedef struct {
++ unsigned not_used:1;
++ unsigned crc:7;
++ unsigned ecc:2;
++ unsigned file_format:2;
++ unsigned tmp_write_protect:1;
++ unsigned perm_write_protect:1;
++ unsigned copy:1;
++ unsigned file_format_grp:1;
++ unsigned content_prot_app:1;
++ unsigned reserved_1:4;
++ unsigned write_bl_partial:1;
++ unsigned write_bl_len:4;
++ unsigned r2w_factor:3;
++ unsigned default_ecc:2;
++ unsigned wp_grp_enable:1;
++ unsigned wp_grp_size:5;
++ unsigned erase_grp_mult:5;
++ unsigned erase_grp_size:5;
++ unsigned c_size_mult:3;
++ unsigned vdd_w_curr_max:3;
++ unsigned vdd_w_curr_min:3;
++ unsigned vdd_r_curr_max:3;
++ unsigned vdd_r_curr_min:3;
++ unsigned c_size_lsb:2;
++ unsigned c_size_msb:10;
++ unsigned reserved_2:2;
++ unsigned dsr_imp:1;
++ unsigned read_blk_misalign:1;
++ unsigned write_blk_misalign:1;
++ unsigned read_bl_partial:1;
++ unsigned read_bl_len:4;
++ unsigned ccc:12;
++ unsigned tran_speed:8;
++ unsigned nsac:8;
++ unsigned taac:8;
++ unsigned reserved_3:2;
++ unsigned spec_vers:4;
++ unsigned csd_structure:2;
++} mmc_csd_reg_t;
++
++/* csd for sd2.0 */
++typedef struct {
++ unsigned not_used:1;
++ unsigned crc:7;
++ unsigned reserved_1:2;
++ unsigned file_format:2;
++ unsigned tmp_write_protect:1;
++ unsigned perm_write_protect:1;
++ unsigned copy:1;
++ unsigned file_format_grp:1;
++ unsigned reserved_2:5;
++ unsigned write_bl_partial:1;
++ unsigned write_bl_len:4;
++ unsigned r2w_factor:3;
++ unsigned reserved_3:2;
++ unsigned wp_grp_enable:1;
++ unsigned wp_grp_size:7;
++ unsigned sector_size:7;
++ unsigned erase_blk_len:1;
++ unsigned reserved_4:1;
++ unsigned c_size_lsb:16;
++ unsigned c_size_msb:6;
++ unsigned reserved_5:6;
++ unsigned dsr_imp:1;
++ unsigned read_blk_misalign:1;
++ unsigned write_blk_misalign:1;
++ unsigned read_bl_partial:1;
++ unsigned read_bl_len:4;
++ unsigned ccc:12;
++ unsigned tran_speed:8;
++ unsigned nsac:8;
++ unsigned taac:8;
++ unsigned reserved_6:6;
++ unsigned csd_structure:2;
++} mmc_sd2_csd_reg_t;
++
++/* extended csd - 512 bytes long */
++typedef struct {
++ unsigned char reserved_1[181];
++ unsigned char erasedmemorycontent;
++ unsigned char reserved_2;
++ unsigned char buswidthmode;
++ unsigned char reserved_3;
++ unsigned char highspeedinterfacetiming;
++ unsigned char reserved_4;
++ unsigned char powerclass;
++ unsigned char reserved_5;
++ unsigned char commandsetrevision;
++ unsigned char reserved_6;
++ unsigned char commandset;
++ unsigned char extendedcsdrevision;
++ unsigned char reserved_7;
++ unsigned char csdstructureversion;
++ unsigned char reserved_8;
++ unsigned char cardtype;
++ unsigned char reserved_9[3];
++ unsigned char powerclass_52mhz_1_95v;
++ unsigned char powerclass_26mhz_1_95v;
++ unsigned char powerclass_52mhz_3_6v;
++ unsigned char powerclass_26mhz_3_6v;
++ unsigned char reserved_10;
++ unsigned char minreadperf_4b_26mhz;
++ unsigned char minwriteperf_4b_26mhz;
++ unsigned char minreadperf_8b_26mhz_4b_52mhz;
++ unsigned char minwriteperf_8b_26mhz_4b_52mhz;
++ unsigned char minreadperf_8b_52mhz;
++ unsigned char minwriteperf_8b_52mhz;
++ unsigned char reserved_11;
++ unsigned int sectorcount;
++ unsigned char reserved_12[288];
++ unsigned char supportedcommandsets;
++ unsigned char reserved_13[7];
++} mmc_extended_csd_reg_t;
++
++/* mmc sd responce */
++typedef struct {
++ unsigned int ocr;
++} mmc_resp_r3;
++
++typedef struct {
++ unsigned short cardstatus;
++ unsigned short newpublishedrca;
++} mmc_resp_r6;
++
++typedef union {
++ unsigned int resp[4];
++ mmc_resp_r3 r3;
++ mmc_resp_r6 r6;
++ mmc_csd_reg_t Card_CSD;
++} mmc_resp_t;
++
++extern mmc_card_data mmc_dev;
++
++unsigned char mmc_lowlevel_init(void);
++unsigned char mmc_send_command(unsigned int cmd, unsigned int arg,
++ unsigned int *response);
++unsigned char mmc_setup_clock(unsigned int iclk, unsigned short clkd);
++unsigned char mmc_set_opendrain(unsigned char state);
++unsigned char mmc_read_data(unsigned int *output_buf);
++
++#endif /* MMC_H */
+diff --git a/arch/arm/include/asm/arch-ti81xx/mmc_host_def.h b/arch/arm/include/asm/arch-ti81xx/mmc_host_def.h
+new file mode 100644
+index 0000000..55012c6
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/mmc_host_def.h
+@@ -0,0 +1,185 @@
++/*
++ * (C) Copyright 2008
++ * Texas Instruments, <www.ti.com>
++ * Syed Mohammed Khasim <khasim@ti.com>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation's version 2 of
++ * the License.
++ *
++ * 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 MMC_HOST_DEF_H
++#define MMC_HOST_DEF_H
++
++/*
++ * OMAP HSMMC register definitions
++ */
++#if defined(CONFIG_TI816X)
++# define OMAP_HSMMC1_BASE 0x48060100
++#elif defined(CONFIG_TI814X)
++# define OMAP_HSMMC1_BASE 0x481D8100
++#elif defined(CONFIG_AM335X)
++# define OMAP_HSMMC1_BASE CONFIG_AM335X_HSMMC_BASE
++#endif
++
++typedef struct hsmmc {
++ unsigned char res1[0x10];
++ unsigned int sysconfig; /* 0x10 */
++ unsigned int sysstatus; /* 0x14 */
++ unsigned char res2[0x14];
++ unsigned int con; /* 0x2C */
++ unsigned char res3[0xD4];
++ unsigned int blk; /* 0x104 */
++ unsigned int arg; /* 0x108 */
++ unsigned int cmd; /* 0x10C */
++ unsigned int rsp10; /* 0x110 */
++ unsigned int rsp32; /* 0x114 */
++ unsigned int rsp54; /* 0x118 */
++ unsigned int rsp76; /* 0x11C */
++ unsigned int data; /* 0x120 */
++ unsigned int pstate; /* 0x124 */
++ unsigned int hctl; /* 0x128 */
++ unsigned int sysctl; /* 0x12C */
++ unsigned int stat; /* 0x130 */
++ unsigned int ie; /* 0x134 */
++ unsigned char res4[0x8];
++ unsigned int capa; /* 0x140 */
++} hsmmc_t;
++
++/*
++ * OMAP HS MMC Bit definitions
++ */
++#define MMC_SOFTRESET (0x1 << 1)
++#define RESETDONE (0x1 << 0)
++#define NOOPENDRAIN (0x0 << 0)
++#define OPENDRAIN (0x1 << 0)
++#define OD (0x1 << 0)
++#define INIT_NOINIT (0x0 << 1)
++#define INIT_INITSTREAM (0x1 << 1)
++#define HR_NOHOSTRESP (0x0 << 2)
++#define STR_BLOCK (0x0 << 3)
++#define MODE_FUNC (0x0 << 4)
++#define DW8_1_4BITMODE (0x0 << 5)
++#define MIT_CTO (0x0 << 6)
++#define CDP_ACTIVEHIGH (0x0 << 7)
++#define WPP_ACTIVEHIGH (0x0 << 8)
++#define RESERVED_MASK (0x3 << 9)
++#define CTPL_MMC_SD (0x0 << 11)
++#define BLEN_512BYTESLEN (0x200 << 0)
++#define NBLK_STPCNT (0x0 << 16)
++#define DE_DISABLE (0x0 << 0)
++#define BCE_DISABLE (0x0 << 1)
++#define BCE_ENABLE (0x1 << 1)
++#define ACEN_DISABLE (0x0 << 2)
++#define DDIR_OFFSET (4)
++#define DDIR_MASK (0x1 << 4)
++#define DDIR_WRITE (0x0 << 4)
++#define DDIR_READ (0x1 << 4)
++#define MSBS_SGLEBLK (0x0 << 5)
++#define MSBS_MULTIBLK (0x1 << 5)
++#define RSP_TYPE_OFFSET (16)
++#define RSP_TYPE_MASK (0x3 << 16)
++#define RSP_TYPE_NORSP (0x0 << 16)
++#define RSP_TYPE_LGHT136 (0x1 << 16)
++#define RSP_TYPE_LGHT48 (0x2 << 16)
++#define RSP_TYPE_LGHT48B (0x3 << 16)
++#define CCCE_NOCHECK (0x0 << 19)
++#define CCCE_CHECK (0x1 << 19)
++#define CICE_NOCHECK (0x0 << 20)
++#define CICE_CHECK (0x1 << 20)
++#define DP_OFFSET (21)
++#define DP_MASK (0x1 << 21)
++#define DP_NO_DATA (0x0 << 21)
++#define DP_DATA (0x1 << 21)
++#define CMD_TYPE_NORMAL (0x0 << 22)
++#define INDEX_OFFSET (24)
++#define INDEX_MASK (0x3f << 24)
++#define INDEX(i) (i << 24)
++#define DATI_MASK (0x1 << 1)
++#define DATI_CMDDIS (0x1 << 1)
++#define DTW_1_BITMODE (0x0 << 1)
++#define DTW_4_BITMODE (0x1 << 1)
++#define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/
++#define SDBP_PWROFF (0x0 << 8)
++#define SDBP_PWRON (0x1 << 8)
++#define SDVS_1V8 (0x5 << 9)
++#define SDVS_3V0 (0x6 << 9)
++#define ICE_MASK (0x1 << 0)
++#define ICE_STOP (0x0 << 0)
++#define ICS_MASK (0x1 << 1)
++#define ICS_NOTREADY (0x0 << 1)
++#define ICE_OSCILLATE (0x1 << 0)
++#define CEN_MASK (0x1 << 2)
++#define CEN_DISABLE (0x0 << 2)
++#define CEN_ENABLE (0x1 << 2)
++#define CLKD_OFFSET (6)
++#define CLKD_MASK (0x3FF << 6)
++#define DTO_MASK (0xF << 16)
++#define DTO_15THDTO (0xE << 16)
++#define SOFTRESETALL (0x1 << 24)
++#define CC_MASK (0x1 << 0)
++#define TC_MASK (0x1 << 1)
++#define BWR_MASK (0x1 << 4)
++#define BRR_MASK (0x1 << 5)
++#define ERRI_MASK (0x1 << 15)
++#define IE_CC (0x01 << 0)
++#define IE_TC (0x01 << 1)
++#define IE_BWR (0x01 << 4)
++#define IE_BRR (0x01 << 5)
++#define IE_CTO (0x01 << 16)
++#define IE_CCRC (0x01 << 17)
++#define IE_CEB (0x01 << 18)
++#define IE_CIE (0x01 << 19)
++#define IE_DTO (0x01 << 20)
++#define IE_DCRC (0x01 << 21)
++#define IE_DEB (0x01 << 22)
++#define IE_CERR (0x01 << 28)
++#define IE_BADA (0x01 << 29)
++
++#define VS30_3V0SUP (1 << 25)
++#define VS18_1V8SUP (1 << 26)
++
++/* Driver definitions */
++#define MMCSD_SECTOR_SIZE 512
++#define MMC_CARD 0
++#define SD_CARD 1
++#define BYTE_MODE 0
++#define SECTOR_MODE 1
++#define CLK_INITSEQ 0
++#define CLK_400KHZ 1
++#define CLK_MISC 2
++
++typedef struct {
++ unsigned int card_type;
++ unsigned int version;
++ unsigned int mode;
++ unsigned int size;
++ unsigned int RCA;
++} mmc_card_data;
++
++#define RSP_TYPE_NONE (RSP_TYPE_NORSP | CCCE_NOCHECK | CICE_NOCHECK)
++#define MMC_CMD0 (INDEX(0) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE)
++
++/* Clock Configurations and Macros */
++#define MMC_CLOCK_REFERENCE 96 /* MHz */
++
++#define mmc_reg_out(addr, mask, val)\
++ writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))
++
++int omap_mmc_init(int dev_index);
++
++#endif /* MMC_HOST_DEF_H */
+diff --git a/arch/arm/include/asm/arch-ti81xx/nand.h b/arch/arm/include/asm/arch-ti81xx/nand.h
+new file mode 100644
+index 0000000..e22a60e
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/nand.h
+@@ -0,0 +1,207 @@
++/*
++ * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
++ * Mansoor Ahamed <mansoor.ahamed@ti.com>
++ *
++ * Derived from work done by Rohit Choraria <rohitkc@ti.com> for omap3
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#ifndef __ASM_ARCH_OMAP_GPMC_H
++#define __ASM_ARCH_OMAP_GPMC_H
++
++#define GPMC_BUF_EMPTY 0
++#define GPMC_BUF_FULL 1
++
++#define ECCCLEAR (0x1 << 8)
++#define ECCRESULTREG1 (0x1 << 0)
++#define ECCSIZE512BYTE 0xFF
++#define ECCSIZE1 (ECCSIZE512BYTE << 22)
++#define ECCSIZE0 (ECCSIZE512BYTE << 12)
++#define ECCSIZE0SEL (0x000 << 0)
++
++/* Generic ECC Layouts */
++/* Large Page x8 NAND device Layout */
++#ifdef GPMC_NAND_ECC_LP_x8_LAYOUT
++#define GPMC_NAND_HW_ECC_LAYOUT {\
++ .eccbytes = 12,\
++ .eccpos = {1, 2, 3, 4, 5, 6, 7, 8,\
++ 9, 10, 11, 12},\
++ .oobfree = {\
++ {.offset = 13,\
++ .length = 51 } } \
++}
++#endif
++
++/* Large Page x16 NAND device Layout */
++#ifdef GPMC_NAND_ECC_LP_x16_LAYOUT
++#define GPMC_NAND_HW_ECC_LAYOUT {\
++ .eccbytes = 12,\
++ .eccpos = {2, 3, 4, 5, 6, 7, 8, 9,\
++ 10, 11, 12, 13},\
++ .oobfree = {\
++ {.offset = 14,\
++ .length = 50 } } \
++}
++#endif
++
++/* NAND device layout in synch with the kernel */
++#ifdef GPMC_NAND_ECC_LP_x16_LAYOUT
++#define GPMC_NAND_HW_ECC_LAYOUT_KERNEL {\
++ .eccbytes = 12,\
++ .eccpos = {\
++ 40, 41, 42, 43, 44, 45, 46, 47,\
++ 48, 49, 50, 51},\
++ .oobfree = {\
++ {.offset = 2,\
++ .length = 38} } \
++}
++#endif
++
++/* Small Page x8 NAND device Layout */
++#ifdef GPMC_NAND_ECC_SP_x8_LAYOUT
++#define GPMC_NAND_HW_ECC_LAYOUT {\
++ .eccbytes = 3,\
++ .eccpos = {1, 2, 3},\
++ .oobfree = {\
++ {.offset = 4,\
++ .length = 12 } } \
++}
++#endif
++
++/* Small Page x16 NAND device Layout */
++#ifdef GPMC_NAND_ECC_SP_x16_LAYOUT
++#define GPMC_NAND_HW_ECC_LAYOUT {\
++ .eccbytes = 3,\
++ .eccpos = {2, 3, 4},\
++ .oobfree = {\
++ {.offset = 58,\
++ .length = 6 } } \
++}
++#endif
++
++#define GPMC_NAND_HW_BCH4_ECC_LAYOUT {\
++ .eccbytes = 32,\
++ .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
++ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
++ 28, 29, 30, 31, 32, 33},\
++ .oobfree = {\
++ {.offset = 34,\
++ .length = 30 } } \
++}
++
++#define GPMC_NAND_HW_BCH8_ECC_LAYOUT {\
++ .eccbytes = 56,\
++ .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
++ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
++ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
++ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
++ 52, 53, 54, 55, 56, 57},\
++ .oobfree = {\
++ {.offset = 58,\
++ .length = 6 } } \
++}
++
++#define GPMC_NAND_HW_BCH16_ECC_LAYOUT {\
++ .eccbytes = 104,\
++ .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
++ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
++ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
++ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
++ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\
++ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,\
++ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,\
++ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\
++ 100, 101, 102, 103, 104, 105},\
++ .oobfree = {\
++ {.offset = 106,\
++ .length = 8 } } \
++}
++
++/*
++ * ELM Module Registers
++ */
++
++/* ELM registers bit fields */
++#define ELM_SYSCONFIG_SOFTRESET_MASK (0x2)
++#define ELM_SYSCONFIG_SOFTRESET (0x2)
++#define ELM_SYSSTATUS_RESETDONE_MASK (0x1)
++#define ELM_SYSSTATUS_RESETDONE (0x1)
++#define ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK (0x3)
++#define ELM_LOCATION_CONFIG_ECC_SIZE_MASK (0x7FF0000)
++#define ELM_LOCATION_CONFIG_ECC_SIZE_POS (16)
++#define ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID (0x00010000)
++#define ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK (0x100)
++#define ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK (0x1F)
++
++#ifndef __KERNEL_STRICT_NAMES
++#ifndef __ASSEMBLY__
++
++enum bch_level {
++ BCH_4_BIT = 0,
++ BCH_8_BIT,
++ BCH_16_BIT
++};
++
++
++/* BCH syndrome registers */
++struct syndrome {
++ u32 syndrome_fragment_x[7]; /* 0x400, 0x404.... 0x418 */
++ u8 res1[36]; /* 0x41c */
++};
++
++/* BCH error status & location register */
++struct location {
++ u32 location_status; /* 0x800 */
++ u8 res1[124]; /* 0x804 */
++ u32 error_location_x[16]; /* 0x880.... */
++ u8 res2[64]; /* 0x8c0 */
++};
++
++/* BCH ELM register map - do not try to allocate memmory for this structure.
++ * We have used plenty of reserved variables to fill the slots in the ELM
++ * register memory map.
++ * Directly initialize the struct pointer to ELM base address.
++ */
++struct elm {
++ u32 rev; /* 0x000 */
++ u8 res1[12]; /* 0x004 */
++ u32 sysconfig; /* 0x010 */
++ u32 sysstatus; /* 0x014 */
++ u32 irqstatus; /* 0x018 */
++ u32 irqenable; /* 0x01c */
++ u32 location_config; /* 0x020 */
++ u8 res2[92]; /* 0x024 */
++ u32 page_ctrl; /* 0x080 */
++ u8 res3[892]; /* 0x084 */
++ struct syndrome syndrome_fragments[8]; /* 0x400 */
++ u8 res4[512]; /* 0x600 */
++ struct location error_location[8]; /* 0x800 */
++};
++
++int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
++ u32 *error_locations);
++int elm_config(enum bch_level level);
++void elm_reset(void);
++void elm_init(void);
++#endif /* __ASSEMBLY__ */
++#endif /* __KERNEL_STRICT_NAMES */
++
++
++#endif /* __ASM_ARCH_OMAP_GPMC_H */
++
+diff --git a/arch/arm/include/asm/arch-ti81xx/sys_proto.h b/arch/arm/include/asm/arch-ti81xx/sys_proto.h
+new file mode 100644
+index 0000000..a5dc6b2
+--- /dev/null
++++ b/arch/arm/include/asm/arch-ti81xx/sys_proto.h
+@@ -0,0 +1,64 @@
++/*
++ * (C) Copyright 2004-2008
++ * Texas Instruments, <www.ti.com>
++ * Richard Woodruff <r-woodruff2@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#ifndef _SYS_PROTO_H_
++#define _SYS_PROTO_H_
++
++typedef struct {
++ u32 board_type_v1;
++ u32 board_type_v2;
++ u32 mtype;
++ char *board_string;
++ char *nand_string;
++} omap3_sysinfo;
++
++/* CPU Revision for TI814X PG2.1 is 0x3 and PG1.0 is0 */
++enum cpu_rev {
++ PG1_0 = 0,
++ PG2_1,
++ PG_END
++};
++
++void prcm_init(void);
++void per_clocks_enable(void);
++void gpmc_init(void);
++void watchdog_init(void);
++void set_muxconf_regs(void);
++u32 get_cpu_rev(void);
++u32 get_mem_type(void);
++u32 get_sysboot_value(void);
++int print_cpuinfo (void);
++u32 is_gpmc_muxed(void);
++u32 get_gpmc0_type(void);
++u32 get_gpmc0_width(void);
++u32 get_board_type(void);
++void display_board_info(u32);
++u32 get_sdr_cs_size(u32);
++u32 get_sdr_cs_offset(u32);
++u32 get_device_type(void);
++u32 get_boot_type(void);
++void sr32(void*, u32 , u32 , u32);
++u32 wait_on_value(u32, u32, void*, u32);
++void sdelay(unsigned long);
++void omap_nand_switch_ecc(int);
++void power_init_r(void);
++void invalidate_dcache(u32);
++#endif
++
+diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h
+index a1fd03a..c6ea523 100644
+--- a/arch/arm/include/asm/mach-types.h
++++ b/arch/arm/include/asm/mach-types.h
+@@ -3312,6 +3312,8 @@ extern unsigned int __machine_arch_type;
+ #define MACH_TYPE_T5388P 3336
+ #define MACH_TYPE_DINGO 3337
+ #define MACH_TYPE_GOFLEXHOME 3338
++#define MACH_TYPE_TIAM335EVM 3589
++#define MACH_TYPE_TIAM335IAEVM 3684
+
+ #ifdef CONFIG_ARCH_EBSA110
+ # ifdef machine_arch_type
+@@ -42913,6 +42915,18 @@ extern unsigned int __machine_arch_type;
+ # define machine_is_goflexhome() (0)
+ #endif
+
++#ifdef CONFIG_MACH_TIAM335EVM
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_TIAM335EVM
++# endif
++# define machine_is_tiam335evm() (machine_arch_type == MACH_TYPE_TIAM335EVM)
++#else
++# define machine_is_tiam335evm() (0)
++#endif
++
+ /*
+ * These have not yet been registered
+ */
+diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
+index d3cb857..d257d5b 100644
+--- a/arch/arm/include/asm/omap_common.h
++++ b/arch/arm/include/asm/omap_common.h
+@@ -37,6 +37,7 @@
+ void preloader_console_init(void);
+
+ /* Boot device */
++#ifdef CONFIG_OMAP44XX /* OMAP4 */
+ #define BOOT_DEVICE_NONE 0
+ #define BOOT_DEVICE_XIP 1
+ #define BOOT_DEVICE_XIPWAIT 2
+@@ -44,13 +45,54 @@ void preloader_console_init(void);
+ #define BOOT_DEVICE_ONE_NAND 4
+ #define BOOT_DEVICE_MMC1 5
+ #define BOOT_DEVICE_MMC2 6
++#elif defined(CONFIG_OMAP34XX) /* OMAP3 */
++#define BOOT_DEVICE_NONE 0
++#define BOOT_DEVICE_XIP 1
++#define BOOT_DEVICE_NAND 2
++#define BOOT_DEVICE_ONE_NAND 3
++#define BOOT_DEVICE_MMC2 5 /*emmc*/
++#define BOOT_DEVICE_MMC1 6
++#define BOOT_DEVICE_XIPWAIT 7
++#elif defined(CONFIG_TI81XX) /* AM33XX */
++#define BOOT_DEVICE_NONE 0
++#define BOOT_DEVICE_NAND 5
++#define BOOT_DEVICE_MMC1 8
++#define BOOT_DEVICE_MMC2 0 /* eMMC, TODO */
++#define BOOT_DEVICE_UART 65
++#endif
+
+ /* Boot type */
+ #define MMCSD_MODE_UNDEFINED 0
+ #define MMCSD_MODE_RAW 1
+ #define MMCSD_MODE_FAT 2
++#define NAND_MODE_HW_ECC 3
++
++struct spl_image_info {
++ const char *name;
++ u8 os;
++ u32 load_addr;
++ u32 entry_point;
++ u32 size;
++};
++
++extern struct spl_image_info spl_image;
+
+ u32 omap_boot_device(void);
+ u32 omap_boot_mode(void);
+
++
++/* SPL common function s*/
++void spl_board_init(void);
++void spl_parse_image_header(const struct image_header *header);
++void omap_rev_string(char *omap_rev_string);
++
++/* NAND SPL functions */
++void spl_nand_load_image(void);
++
++/* MMC SPL functions */
++void spl_mmc_load_image(void);
++
++/* YMODEM SPL functions */
++void spl_ymodem_load_image(void);
++
+ #endif /* _OMAP_COMMON_H_ */
+diff --git a/board/logicpd/am3517evm/am3517evm.c b/board/logicpd/am3517evm/am3517evm.c
+index c0a006a..89339b5 100644
+--- a/board/logicpd/am3517evm/am3517evm.c
++++ b/board/logicpd/am3517evm/am3517evm.c
+@@ -27,13 +27,22 @@
+ #include <asm/io.h>
+ #include <asm/arch/mem.h>
+ #include <asm/arch/mux.h>
++#include <asm/arch/gpio.h>
+ #include <asm/arch/sys_proto.h>
+ #include <asm/arch/mmc_host_def.h>
++#include <asm/arch/emac_defs.h>
+ #include <asm/mach-types.h>
+ #include <i2c.h>
++#include <netdev.h>
+ #include "am3517evm.h"
+
+-DECLARE_GLOBAL_DATA_PTR;
++
++#define AM3517_IP_SW_RESET 0x48002598
++#define CPGMACSS_SW_RST (1 << 1)
++
++
++
++
+
+ /*
+ * Routine: board_init
+@@ -41,6 +50,8 @@ DECLARE_GLOBAL_DATA_PTR;
+ */
+ int board_init(void)
+ {
++ DECLARE_GLOBAL_DATA_PTR;
++
+ gpmc_init(); /* in SRAM or SDRAM, finish GPMC */
+ /* board id for Linux */
+ gd->bd->bi_arch_number = MACH_TYPE_OMAP3517EVM;
+@@ -56,15 +67,64 @@ int board_init(void)
+ */
+ int misc_init_r(void)
+ {
++ volatile unsigned int ctr;
++ u32 reset;
++
++
+ #ifdef CONFIG_DRIVER_OMAP34XX_I2C
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ #endif
+
+ dieid_num_r();
+
++
++#if defined(CONFIG_DRIVER_TI_EMAC)
++
++ omap_request_gpio(30);
++ omap_set_gpio_direction(30,0);
++ omap_set_gpio_dataout(30,0);
++ ctr = 0;
++ do{
++ udelay(1000);
++ ctr++;
++ }while (ctr <300);
++ omap_set_gpio_dataout(30,1);
++ ctr =0;
++ /* allow the PHY to stabilize and settle down */
++ do{
++ udelay(1000);
++ ctr++;
++ }while (ctr <300);
++
++ /*ensure that the module is out of reset*/
++ reset = readl(AM3517_IP_SW_RESET);
++ reset &= (~CPGMACSS_SW_RST);
++ writel(reset,AM3517_IP_SW_RESET);
++
++#endif
++
++
++
+ return 0;
+ }
+
++
++/*
++ * Initializes on-chip ethernet controllers.
++ * to override, implement board_eth_init()
++ */
++int cpu_eth_init(bd_t *bis)
++{
++#if defined(CONFIG_DRIVER_TI_EMAC)
++ printf("davinci_emac_initialize\n");
++ davinci_emac_initialize();
++#endif
++ return 0;
++ }
++
++
++
++
+ /*
+ * Routine: set_muxconf_regs
+ * Description: Setting up the configuration Mux registers specific to the
+diff --git a/board/logicpd/am3517evm/am3517evm.h b/board/logicpd/am3517evm/am3517evm.h
+index 3d74ef1..69f54dc 100644
+--- a/board/logicpd/am3517evm/am3517evm.h
++++ b/board/logicpd/am3517evm/am3517evm.h
+@@ -367,7 +367,7 @@ const omap3_sysinfo sysinfo = {
+ MUX_VAL(CP(SYS_CLKREQ), (IEN | PTD | DIS | M0)) \
+ MUX_VAL(CP(SYS_NIRQ), (IEN | PTU | EN | M0)) \
+ /*SYS_nRESWARM */\
+- MUX_VAL(CP(SYS_NRESWARM), (IDIS | PTU | DIS | M4)) \
++ MUX_VAL(CP(SYS_NRESWARM), (IDIS | PTU | EN | M4)) \
+ /* - GPIO30 */\
+ MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /*GPIO_2*/\
+ /* - PEN_IRQ */\
+diff --git a/board/ti/am335x/Makefile b/board/ti/am335x/Makefile
+new file mode 100644
+index 0000000..214a289
+--- /dev/null
++++ b/board/ti/am335x/Makefile
+@@ -0,0 +1,41 @@
++#
++# Makefile
++#
++# Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++#
++# 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 version 2.
++#
++# This program is distributed "as is" WITHOUT ANY WARRANTY of any
++# kind, whether express or implied; without even the implied warranty
++# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS := evm.o pll.o mux.o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++
++$(LIB): $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++clean:
++ rm -f $(OBJS)
++
++distclean: clean
++ rm -f $(LIB) core *.bak $(obj).depend
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+diff --git a/board/ti/am335x/common_def.h b/board/ti/am335x/common_def.h
+new file mode 100644
+index 0000000..21a50dd
+--- /dev/null
++++ b/board/ti/am335x/common_def.h
+@@ -0,0 +1,48 @@
++/*
++ * common_def.h
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#ifndef __COMMON_DEF_H__
++#define __COMMON_DEF_H__
++
++/* AM335X type */
++#define BONE_BOARD 0
++#define GP_BOARD 1
++#define IA_BOARD 2
++#define IPP_BOARD 3
++#define BASE_BOARD 4
++
++/* Profiles */
++#define PROFILE_NONE 0x0
++#define PROFILE_0 (1 << 0)
++#define PROFILE_1 (1 << 1)
++#define PROFILE_2 (1 << 2)
++#define PROFILE_3 (1 << 3)
++#define PROFILE_4 (1 << 4)
++#define PROFILE_5 (1 << 5)
++#define PROFILE_6 (1 << 6)
++#define PROFILE_7 (1 << 7)
++#define PROFILE_ALL 0xFF
++
++extern void pll_init(void);
++extern void mpu_pll_config(int mpupll_M);
++extern void enable_ddr_clocks(void);
++
++extern void enable_i2c0_pin_mux(void);
++extern void enable_uart0_pin_mux(void);
++extern void configure_evm_pin_mux(unsigned char daughter_board_id,
++ char daughter_board_version[],
++ unsigned short daughter_board_profile,
++ unsigned int daughter_board_flag);
++
++#endif/*__COMMON_DEF_H__ */
+diff --git a/board/ti/am335x/evm.c b/board/ti/am335x/evm.c
+new file mode 100644
+index 0000000..e95a088
+--- /dev/null
++++ b/board/ti/am335x/evm.c
+@@ -0,0 +1,1042 @@
++/*
++ * evm.c
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <common.h>
++#include <asm/cache.h>
++#include <asm/omap_common.h>
++#include <asm/io.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/ddr_defs.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/mmc_host_def.h>
++#include <asm/arch/sys_proto.h>
++#include <asm/arch/mem.h>
++#include <asm/arch/nand.h>
++#include <asm/arch/clock.h>
++#include <linux/mtd/nand.h>
++#include <nand.h>
++#include <net.h>
++#include <miiphy.h>
++#include <netdev.h>
++#include <spi_flash.h>
++#include "common_def.h"
++#include "pmic.h"
++#include "tps65217.h"
++#include <i2c.h>
++#include <serial.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/* UART Defines */
++#define UART_SYSCFG_OFFSET (0x54)
++#define UART_SYSSTS_OFFSET (0x58)
++
++#define UART_RESET (0x1 << 1)
++#define UART_CLK_RUNNING_MASK 0x1
++#define UART_SMART_IDLE_EN (0x1 << 0x3)
++
++/* Timer Defines */
++#define TSICR_REG 0x54
++#define TIOCP_CFG_REG 0x10
++#define TCLR_REG 0x38
++
++/* CPLD registers */
++#define CFG_REG 0x10
++
++/*
++ * I2C Address of various board
++ */
++#define I2C_BASE_BOARD_ADDR 0x50
++#define I2C_DAUGHTER_BOARD_ADDR 0x51
++#define I2C_LCD_BOARD_ADDR 0x52
++
++#define I2C_CPLD_ADDR 0x35
++
++/* RGMII mode define */
++#define RGMII_MODE_ENABLE 0xA
++#define RMII_MODE_ENABLE 0x5
++#define MII_MODE_ENABLE 0x0
++
++/* TLK110 PHY registers */
++#define TLK110_COARSEGAIN_REG 0x00A3
++#define TLK110_LPFHPF_REG 0x00AC
++#define TLK110_SPAREANALOG_REG 0x00B9
++#define TLK110_VRCR_REG 0x00D0
++#define TLK110_SETFFE_REG 0x0107
++#define TLK110_FTSP_REG 0x0154
++#define TLK110_ALFATPIDL_REG 0x002A
++#define TLK110_PSCOEF21_REG 0x0096
++#define TLK110_PSCOEF3_REG 0x0097
++#define TLK110_ALFAFACTOR1_REG 0x002C
++#define TLK110_ALFAFACTOR2_REG 0x0023
++#define TLK110_CFGPS_REG 0x0095
++#define TLK110_FTSPTXGAIN_REG 0x0150
++#define TLK110_SWSCR3_REG 0x000B
++#define TLK110_SCFALLBACK_REG 0x0040
++#define TLK110_PHYRCR_REG 0x001F
++
++/* TLK110 register writes values */
++#define TLK110_COARSEGAIN_VAL 0x0000
++#define TLK110_LPFHPF_VAL 0x8000
++#define TLK110_SPAREANALOG_VAL 0x0000
++#define TLK110_VRCR_VAL 0x0008
++#define TLK110_SETFFE_VAL 0x0605
++#define TLK110_FTSP_VAL 0x0255
++#define TLK110_ALFATPIDL_VAL 0x7998
++#define TLK110_PSCOEF21_VAL 0x3A20
++#define TLK110_PSCOEF3_VAL 0x003F
++#define TLK110_ALFAFACTOR1_VAL 0xFF80
++#define TLK110_ALFAFACTOR2_VAL 0x021C
++#define TLK110_CFGPS_VAL 0x0000
++#define TLK110_FTSPTXGAIN_VAL 0x6A88
++#define TLK110_SWSCR3_VAL 0x0000
++#define TLK110_SCFALLBACK_VAL 0xC11D
++#define TLK110_PHYRCR_VAL 0x4000
++#define TLK110_PHYIDR1 0x2000
++#define TLK110_PHYIDR2 0xA201
++
++#define NO_OF_MAC_ADDR 3
++#define ETH_ALEN 6
++
++struct am335x_baseboard_id {
++ unsigned int magic;
++ char name[8];
++ char version[4];
++ char serial[12];
++ char config[32];
++ char mac_addr[NO_OF_MAC_ADDR][ETH_ALEN];
++};
++
++static struct am335x_baseboard_id header;
++extern void cpsw_eth_set_mac_addr(const u_int8_t *addr);
++static unsigned char daughter_board_connected;
++static volatile int board_id = BASE_BOARD;
++
++/*
++ * dram_init:
++ * At this point we have initialized the i2c bus and can read the
++ * EEPROM which will tell us what board and revision we are on.
++ */
++int dram_init(void)
++{
++ gd->ram_size = PHYS_DRAM_1_SIZE;
++
++ return 0;
++}
++
++void dram_init_banksize (void)
++{
++ /* Fill up board info */
++ gd->bd->bi_dram[0].start = PHYS_DRAM_1;
++ gd->bd->bi_dram[0].size = PHYS_DRAM_1_SIZE;
++}
++
++#ifdef CONFIG_SPL_BUILD
++static void Data_Macro_Config(int dataMacroNum)
++{
++ u32 BaseAddrOffset = 0x00;;
++
++ if (dataMacroNum == 1)
++ BaseAddrOffset = 0xA4;
++
++ __raw_writel(((DDR2_RD_DQS<<30)|(DDR2_RD_DQS<<20)
++ |(DDR2_RD_DQS<<10)|(DDR2_RD_DQS<<0)),
++ (DATA0_RD_DQS_SLAVE_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_RD_DQS>>2,
++ (DATA0_RD_DQS_SLAVE_RATIO_1 + BaseAddrOffset));
++ __raw_writel(((DDR2_WR_DQS<<30)|(DDR2_WR_DQS<<20)
++ |(DDR2_WR_DQS<<10)|(DDR2_WR_DQS<<0)),
++ (DATA0_WR_DQS_SLAVE_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_WR_DQS>>2,
++ (DATA0_WR_DQS_SLAVE_RATIO_1 + BaseAddrOffset));
++ __raw_writel(((DDR2_PHY_WRLVL<<30)|(DDR2_PHY_WRLVL<<20)
++ |(DDR2_PHY_WRLVL<<10)|(DDR2_PHY_WRLVL<<0)),
++ (DATA0_WRLVL_INIT_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_PHY_WRLVL>>2,
++ (DATA0_WRLVL_INIT_RATIO_1 + BaseAddrOffset));
++ __raw_writel(((DDR2_PHY_GATELVL<<30)|(DDR2_PHY_GATELVL<<20)
++ |(DDR2_PHY_GATELVL<<10)|(DDR2_PHY_GATELVL<<0)),
++ (DATA0_GATELVL_INIT_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_PHY_GATELVL>>2,
++ (DATA0_GATELVL_INIT_RATIO_1 + BaseAddrOffset));
++ __raw_writel(((DDR2_PHY_FIFO_WE<<30)|(DDR2_PHY_FIFO_WE<<20)
++ |(DDR2_PHY_FIFO_WE<<10)|(DDR2_PHY_FIFO_WE<<0)),
++ (DATA0_FIFO_WE_SLAVE_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_PHY_FIFO_WE>>2,
++ (DATA0_FIFO_WE_SLAVE_RATIO_1 + BaseAddrOffset));
++ __raw_writel(((DDR2_PHY_WR_DATA<<30)|(DDR2_PHY_WR_DATA<<20)
++ |(DDR2_PHY_WR_DATA<<10)|(DDR2_PHY_WR_DATA<<0)),
++ (DATA0_WR_DATA_SLAVE_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_PHY_WR_DATA>>2,
++ (DATA0_WR_DATA_SLAVE_RATIO_1 + BaseAddrOffset));
++ __raw_writel(PHY_DLL_LOCK_DIFF,
++ (DATA0_DLL_LOCK_DIFF_0 + BaseAddrOffset));
++}
++
++static void Cmd_Macro_Config(void)
++{
++ __raw_writel(DDR2_RATIO, CMD0_CTRL_SLAVE_RATIO_0);
++ __raw_writel(CMD_FORCE, CMD0_CTRL_SLAVE_FORCE_0);
++ __raw_writel(CMD_DELAY, CMD0_CTRL_SLAVE_DELAY_0);
++ __raw_writel(DDR2_DLL_LOCK_DIFF, CMD0_DLL_LOCK_DIFF_0);
++ __raw_writel(DDR2_INVERT_CLKOUT, CMD0_INVERT_CLKOUT_0);
++
++ __raw_writel(DDR2_RATIO, CMD1_CTRL_SLAVE_RATIO_0);
++ __raw_writel(CMD_FORCE, CMD1_CTRL_SLAVE_FORCE_0);
++ __raw_writel(CMD_DELAY, CMD1_CTRL_SLAVE_DELAY_0);
++ __raw_writel(DDR2_DLL_LOCK_DIFF, CMD1_DLL_LOCK_DIFF_0);
++ __raw_writel(DDR2_INVERT_CLKOUT, CMD1_INVERT_CLKOUT_0);
++
++ __raw_writel(DDR2_RATIO, CMD2_CTRL_SLAVE_RATIO_0);
++ __raw_writel(CMD_FORCE, CMD2_CTRL_SLAVE_FORCE_0);
++ __raw_writel(CMD_DELAY, CMD2_CTRL_SLAVE_DELAY_0);
++ __raw_writel(DDR2_DLL_LOCK_DIFF, CMD2_DLL_LOCK_DIFF_0);
++ __raw_writel(DDR2_INVERT_CLKOUT, CMD2_INVERT_CLKOUT_0);
++}
++
++static void config_vtp(void)
++{
++ __raw_writel(__raw_readl(VTP0_CTRL_REG) | VTP_CTRL_ENABLE,
++ VTP0_CTRL_REG);
++ __raw_writel(__raw_readl(VTP0_CTRL_REG) & (~VTP_CTRL_START_EN),
++ VTP0_CTRL_REG);
++ __raw_writel(__raw_readl(VTP0_CTRL_REG) | VTP_CTRL_START_EN,
++ VTP0_CTRL_REG);
++
++ /* Poll for READY */
++ while ((__raw_readl(VTP0_CTRL_REG) & VTP_CTRL_READY) != VTP_CTRL_READY);
++}
++
++static void config_emif_ddr2(void)
++{
++ u32 i;
++
++ /*Program EMIF0 CFG Registers*/
++ __raw_writel(EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1);
++ __raw_writel(EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
++ __raw_writel(EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_2);
++ __raw_writel(EMIF_TIM1, EMIF4_0_SDRAM_TIM_1);
++ __raw_writel(EMIF_TIM1, EMIF4_0_SDRAM_TIM_1_SHADOW);
++ __raw_writel(EMIF_TIM2, EMIF4_0_SDRAM_TIM_2);
++ __raw_writel(EMIF_TIM2, EMIF4_0_SDRAM_TIM_2_SHADOW);
++ __raw_writel(EMIF_TIM3, EMIF4_0_SDRAM_TIM_3);
++ __raw_writel(EMIF_TIM3, EMIF4_0_SDRAM_TIM_3_SHADOW);
++
++ __raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG);
++ __raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG2);
++
++ /* __raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL);
++ __raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL_SHD); */
++ __raw_writel(0x00004650, EMIF4_0_SDRAM_REF_CTRL);
++ __raw_writel(0x00004650, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
++
++ for (i = 0; i < 5000; i++) {
++
++ }
++
++ /* __raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL);
++ __raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL_SHD); */
++ __raw_writel(EMIF_SDREF, EMIF4_0_SDRAM_REF_CTRL);
++ __raw_writel(EMIF_SDREF, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
++
++ __raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG);
++ __raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG2);
++}
++
++/* void DDR2_EMIF_Config(void); */
++static void config_am335x_ddr(void)
++{
++ int data_macro_0 = 0;
++ int data_macro_1 = 1;
++
++ enable_ddr_clocks();
++
++ config_vtp();
++
++ Cmd_Macro_Config();
++
++ Data_Macro_Config(data_macro_0);
++ Data_Macro_Config(data_macro_1);
++
++ __raw_writel(PHY_RANK0_DELAY, DATA0_RANK0_DELAYS_0);
++ __raw_writel(PHY_RANK0_DELAY, DATA1_RANK0_DELAYS_0);
++
++ __raw_writel(DDR_IOCTRL_VALUE, DDR_CMD0_IOCTRL);
++ __raw_writel(DDR_IOCTRL_VALUE, DDR_CMD1_IOCTRL);
++ __raw_writel(DDR_IOCTRL_VALUE, DDR_CMD2_IOCTRL);
++ __raw_writel(DDR_IOCTRL_VALUE, DDR_DATA0_IOCTRL);
++ __raw_writel(DDR_IOCTRL_VALUE, DDR_DATA1_IOCTRL);
++
++ __raw_writel(__raw_readl(DDR_IO_CTRL) & 0xefffffff, DDR_IO_CTRL);
++ __raw_writel(__raw_readl(DDR_CKE_CTRL) | 0x00000001, DDR_CKE_CTRL);
++
++ config_emif_ddr2();
++}
++
++static void init_timer(void)
++{
++ /* Reset the Timer */
++ __raw_writel(0x2, (DM_TIMER2_BASE + TSICR_REG));
++
++ /* Wait until the reset is done */
++ while (__raw_readl(DM_TIMER2_BASE + TIOCP_CFG_REG) & 1);
++
++ /* Start the Timer */
++ __raw_writel(0x1, (DM_TIMER2_BASE + TCLR_REG));
++}
++#endif
++
++/*
++ * Read header information from EEPROM into global structure.
++ */
++int read_eeprom(void)
++{
++ /* Check if baseboard eeprom is available */
++ if (i2c_probe(I2C_BASE_BOARD_ADDR)) {
++ printf("Could not probe the EEPROM; something fundamentally "
++ "wrong on the I2C bus.\n");
++ return 1;
++ }
++
++ /* read the eeprom using i2c */
++ if (i2c_read(I2C_BASE_BOARD_ADDR, 0, 2, (uchar *)&header,
++ sizeof(header))) {
++ printf("Could not read the EEPROM; something fundamentally"
++ " wrong on the I2C bus.\n");
++ return 1;
++ }
++
++ if (header.magic != 0xEE3355AA) {
++ /* read the eeprom using i2c again, but use only a 1 byte address */
++ if (i2c_read(I2C_BASE_BOARD_ADDR, 0, 1, (uchar *)&header,
++ sizeof(header))) {
++ printf("Could not read the EEPROM; something fundamentally"
++ " wrong on the I2C bus.\n");
++ return 1;
++ }
++
++ if (header.magic != 0xEE3355AA) {
++ printf("Incorrect magic number in EEPROM\n");
++ return 1;
++ }
++ }
++ return 0;
++}
++
++#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_BOARD_INIT)
++
++/**
++ * tps65217_reg_read() - Generic function that can read a TPS65217 register
++ * @src_reg: Source register address
++ * @src_val: Address of destination variable
++ */
++
++unsigned char tps65217_reg_read(uchar src_reg, uchar *src_val)
++{
++ if (i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1))
++ return 1;
++ return 0;
++}
++
++/**
++ * tps65217_reg_write() - Generic function that can write a TPS65217 PMIC
++ * register or bit field regardless of protection
++ * level.
++ *
++ * @prot_level: Register password protection.
++ * use PROT_LEVEL_NONE, PROT_LEVEL_1, or PROT_LEVEL_2
++ * @dest_reg: Register address to write.
++ * @dest_val: Value to write.
++ * @mask: Bit mask (8 bits) to be applied. Function will only
++ * change bits that are set in the bit mask.
++ *
++ * @return: 0 for success, 1 for failure.
++ */
++int tps65217_reg_write(uchar prot_level, uchar dest_reg,
++ uchar dest_val, uchar mask)
++{
++ uchar read_val;
++ uchar xor_reg;
++
++ /* if we are affecting only a bit field, read dest_reg and apply the mask */
++ if (mask != MASK_ALL_BITS) {
++ if (i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1))
++ return 1;
++ read_val &= (~mask);
++ read_val |= (dest_val & mask);
++ dest_val = read_val;
++ }
++
++ if (prot_level > 0) {
++ xor_reg = dest_reg ^ PASSWORD_UNLOCK;
++ if (i2c_write(TPS65217_CHIP_PM, PASSWORD, 1, &xor_reg, 1))
++ return 1;
++ }
++
++ if (i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1))
++ return 1;
++
++ if (prot_level == PROT_LEVEL_2) {
++ if (i2c_write(TPS65217_CHIP_PM, PASSWORD, 1, &xor_reg, 1))
++ return 1;
++
++ if (i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1))
++ return 1;
++ }
++
++ return 0;
++}
++
++/**
++ * tps65217_voltage_update() - Controls output voltage setting for the DCDC1,
++ * DCDC2, or DCDC3 control registers in the PMIC.
++ *
++ * @dc_cntrl_reg: DCDC Control Register address.
++ * Must be DEFDCDC1, DEFDCDC2, or DEFDCDC3.
++ * @volt_sel: Register value to set. See PMIC TRM for value set.
++ *
++ * @return: 0 for success, 1 for failure.
++ */
++int tps65217_voltage_update(unsigned char dc_cntrl_reg, unsigned char volt_sel)
++{
++ if ((dc_cntrl_reg != DEFDCDC1) && (dc_cntrl_reg != DEFDCDC2)
++ && (dc_cntrl_reg != DEFDCDC3))
++ return 1;
++
++ /* set voltage level */
++ if (tps65217_reg_write(PROT_LEVEL_2, dc_cntrl_reg, volt_sel, MASK_ALL_BITS))
++ return 1;
++
++ /* set GO bit to initiate voltage transition */
++ if (tps65217_reg_write(PROT_LEVEL_2, DEFSLEW, DCDC_GO, DCDC_GO))
++ return 1;
++
++ return 0;
++}
++
++/*
++ * MPU voltage switching for MPU frequency switching.
++ */
++int mpu_voltage_update(unsigned char vdd1_op_vol_sel)
++{
++ uchar buf[4];
++
++ /* Select VDD1 OP */
++ if (i2c_read(PMIC_SR_I2C_ADDR, PMIC_VDD1_OP_REG, 1, buf, 1))
++ return 1;
++
++ buf[0] &= ~PMIC_OP_REG_CMD_MASK;
++
++ if (i2c_write(PMIC_SR_I2C_ADDR, PMIC_VDD1_OP_REG, 1, buf, 1))
++ return 1;
++
++ /* Configure VDD1 OP Voltage */
++ if (i2c_read(PMIC_SR_I2C_ADDR, PMIC_VDD1_OP_REG, 1, buf, 1))
++ return 1;
++
++ buf[0] &= ~PMIC_OP_REG_SEL_MASK;
++ buf[0] |= vdd1_op_vol_sel;
++
++ if (i2c_write(PMIC_SR_I2C_ADDR, PMIC_VDD1_OP_REG, 1, buf, 1))
++ return 1;
++
++ if (i2c_read(PMIC_SR_I2C_ADDR, PMIC_VDD1_OP_REG, 1, buf, 1))
++ return 1;
++
++ if ((buf[0] & PMIC_OP_REG_SEL_MASK ) != vdd1_op_vol_sel)
++ return 1;
++
++ return 0;
++}
++
++void spl_board_init(void)
++{
++ uchar pmic_status_reg;
++
++ /* Configure the i2c0 pin mux */
++ enable_i2c0_pin_mux();
++
++ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
++
++ if (read_eeprom()) {
++ printf("read_eeprom() failure\n");
++ return;
++ }
++
++ if (!strncmp("A335BONE", header.name, 8)) {
++ /* BeagleBone PMIC Code */
++ if (i2c_probe(TPS65217_CHIP_PM))
++ return;
++
++ if (tps65217_reg_read(STATUS, &pmic_status_reg))
++ return;
++
++ /* Only perform PMIC configurations if board rev > A1 */
++ if (!strncmp(header.version, "00A1", 4))
++ return;
++
++ if (!(pmic_status_reg & PWR_SRC_AC_BITMASK)) {
++ printf("No AC power, disabling frequency switch\n");
++ return;
++ }
++
++ /* Set LDO3, LDO4 output voltage to 3.3V */
++ if (tps65217_reg_write(PROT_LEVEL_2, DEFLS1,
++ LDO_VOLTAGE_OUT_3_3, LDO_MASK))
++ printf("tps65217_reg_write failure\n");
++
++ if (tps65217_reg_write(PROT_LEVEL_2, DEFLS2,
++ LDO_VOLTAGE_OUT_3_3, LDO_MASK))
++ printf("tps65217_reg_write failure\n");
++
++ /* Increase USB current limit to 1300mA */
++ if (tps65217_reg_write(PROT_LEVEL_NONE, POWER_PATH,
++ USB_INPUT_CUR_LIMIT_1300MA,
++ USB_INPUT_CUR_LIMIT_MASK))
++ printf("tps65217_reg_write failure\n");
++
++ /* Set DCDC2 (MPU) voltage to 1.275V */
++ if (!tps65217_voltage_update(DEFDCDC2,
++ DCDC_VOLT_SEL_1275MV)) {
++ /* Set MPU Frequency to 720MHz */
++ mpu_pll_config(MPUPLL_M_720);
++ } else {
++ printf("tps65217_voltage_update failure\n");
++ }
++ } else {
++ /*
++ * EVM PMIC code. PMIC voltage is configuring for frequency
++ * scaling.
++ */
++ if (!i2c_probe(PMIC_SR_I2C_ADDR)) {
++ if (!mpu_voltage_update(PMIC_OP_REG_SEL_1_2_6)) {
++ /* Frequency switching for OPP 120 */
++ mpu_pll_config(MPUPLL_M_720);
++ }
++ }
++ }
++}
++#endif
++
++/*
++ * early system init of muxing and clocks.
++ */
++void s_init(void)
++{
++ /* Can be removed as A8 comes up with L2 enabled */
++ l2_cache_enable();
++
++ /* WDT1 is already running when the bootloader gets control
++ * Disable it to avoid "random" resets
++ */
++ __raw_writel(0xAAAA, WDT_WSPR);
++ while(__raw_readl(WDT_WWPS) != 0x0);
++ __raw_writel(0x5555, WDT_WSPR);
++ while(__raw_readl(WDT_WWPS) != 0x0);
++
++#ifdef CONFIG_SPL_BUILD
++ /* Setup the PLLs and the clocks for the peripherals */
++ pll_init();
++
++ /* UART softreset */
++ u32 regVal;
++ u32 uart_base = DEFAULT_UART_BASE;
++
++ enable_uart0_pin_mux();
++ /* IA Motor Control Board has default console on UART3*/
++ /* XXX: This is before we've probed / set board_id */
++ if (board_id == IA_BOARD) {
++ uart_base = UART3_BASE;
++ }
++
++ regVal = __raw_readl(uart_base + UART_SYSCFG_OFFSET);
++ regVal |= UART_RESET;
++ __raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET) );
++ while ((__raw_readl(uart_base + UART_SYSSTS_OFFSET) &
++ UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK);
++
++ /* Disable smart idle */
++ regVal = __raw_readl((uart_base + UART_SYSCFG_OFFSET));
++ regVal |= UART_SMART_IDLE_EN;
++ __raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET));
++
++ /* Initialize the Timer */
++ init_timer();
++
++ preloader_console_init();
++
++ config_am335x_ddr();
++#endif
++}
++
++static void detect_daughter_board(void)
++{
++ /* Check if daughter board is conneted */
++ if (i2c_probe(I2C_DAUGHTER_BOARD_ADDR)) {
++ printf("No daughter card present\n");
++ return;
++ } else {
++ printf("Found a daughter card connected\n");
++ daughter_board_connected = 1;
++ }
++}
++
++static unsigned char profile = PROFILE_0;
++static void detect_daughter_board_profile(void)
++{
++ unsigned short val;
++
++ if (i2c_probe(I2C_CPLD_ADDR))
++ return;
++
++ if (i2c_read(I2C_CPLD_ADDR, CFG_REG, 1, (unsigned char *)(&val), 2))
++ return;
++
++ profile = 1 << (val & 0x7);
++}
++
++/*
++ * Basic board specific setup
++ */
++#ifndef CONFIG_SPL_BUILD
++int board_evm_init(void)
++{
++ /* mach type passed to kernel */
++ if (board_id == IA_BOARD)
++ gd->bd->bi_arch_number = MACH_TYPE_TIAM335IAEVM;
++ else
++ gd->bd->bi_arch_number = MACH_TYPE_TIAM335EVM;
++
++ /* address of boot parameters */
++ gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
++
++ return 0;
++}
++#endif
++
++#if 0
++struct serial_device *default_serial_console(void)
++{
++
++ if (board_id != IA_BOARD) {
++ return &eserial1_device; /* UART0 */
++ } else {
++ return &eserial4_device; /* UART3 */
++ }
++}
++#endif
++
++int board_init(void)
++{
++ /* Configure the i2c0 pin mux */
++ enable_i2c0_pin_mux();
++
++ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
++
++ if (read_eeprom())
++ goto err_out;
++
++ detect_daughter_board();
++
++ if (!strncmp("SKU#01", header.config, 6)) {
++ board_id = GP_BOARD;
++ detect_daughter_board_profile();
++ } else if (!strncmp("SKU#02", header.config, 6)) {
++ board_id = IA_BOARD;
++ detect_daughter_board_profile();
++ } else if (!strncmp("SKU#03", header.config, 6)) {
++ board_id = IPP_BOARD;
++ } else if (!strncmp("A335BONE", header.name, 8)) {
++ board_id = BONE_BOARD;
++ profile = 1; /* profile 0 is internally considered as 1 */
++ daughter_board_connected = 0;
++ } else {
++ printf("Did not find a recognized configuration, "
++ "assuming General purpose EVM in Profile 0 with "
++ "Daughter board\n");
++ board_id = GP_BOARD;
++ profile = 1; /* profile 0 is internally considered as 1 */
++ daughter_board_connected = 1;
++ }
++
++ configure_evm_pin_mux(board_id, header.version, profile, daughter_board_connected);
++
++#ifndef CONFIG_SPL_BUILD
++ board_evm_init();
++#endif
++
++ gpmc_init();
++
++ return 0;
++
++err_out:
++ /*
++ * When we cannot use the EEPROM to determine what board we
++ * are we assume BeagleBone currently as we have not yet
++ * programmed the EEPROMs.
++ */
++ board_id = BONE_BOARD;
++ profile = 1; /* profile 0 is internally considered as 1 */
++ daughter_board_connected = 1;
++ configure_evm_pin_mux(board_id, header.version, profile, daughter_board_connected);
++
++#ifndef CONFIG_SPL_BUILD
++ board_evm_init();
++#endif
++
++ gpmc_init();
++
++ return 0;
++}
++
++int misc_init_r(void)
++{
++#ifdef DEBUG
++ unsigned int cntr;
++ unsigned char *valPtr;
++
++ debug("EVM Configuration - ");
++ debug("\tBoard id %x, profile %x, db %d\n", board_id, profile,
++ daughter_board_connected);
++ debug("Base Board EEPROM Data\n");
++ valPtr = (unsigned char *)&header;
++ for(cntr = 0; cntr < sizeof(header); cntr++) {
++ if(cntr % 16 == 0)
++ debug("\n0x%02x :", cntr);
++ debug(" 0x%02x", (unsigned int)valPtr[cntr]);
++ }
++ debug("\n\n");
++
++ debug("Board identification from EEPROM contents:\n");
++ debug("\tBoard name : %.8s\n", header.name);
++ debug("\tBoard version: %.4s\n", header.version);
++ debug("\tBoard serial : %.12s\n", header.serial);
++ debug("\tBoard config : %.6s\n\n", header.config);
++#endif
++ return 0;
++}
++
++#ifdef BOARD_LATE_INIT
++int board_late_init(void)
++{
++ if (board_id == IA_BOARD) {
++ /*
++ * SPI bus number is switched to in case Industrial Automation
++ * motor control EVM.
++ */
++ setenv("spi_bus_no", "1");
++ /* Change console to tty03 for IA Motor Control EVM */
++ setenv("console", "ttyO3,115200n8");
++ }
++
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_DRIVER_TI_CPSW
++/* TODO : Check for the board specific PHY */
++static void evm_phy_init(char *name, int addr)
++{
++ unsigned short val;
++ unsigned int cntr = 0;
++ unsigned short phyid1, phyid2;
++ int bone_pre_a3 = 0;
++
++ if (board_id == BONE_BOARD && (!strncmp(header.version, "00A1", 4) ||
++ !strncmp(header.version, "00A2", 4)))
++ bone_pre_a3 = 1;
++
++ /*
++ * This is done as a workaround to support TLK110 rev1.0 PHYs.
++ * We can only perform these reads on these PHYs (currently
++ * only found on the IA EVM).
++ */
++ if ((miiphy_read(name, addr, MII_PHYSID1, &phyid1) != 0) ||
++ (miiphy_read(name, addr, MII_PHYSID2, &phyid2) != 0))
++ return;
++
++ if ((phyid1 == TLK110_PHYIDR1) && (phyid2 == TLK110_PHYIDR2)) {
++ miiphy_read(name, addr, TLK110_COARSEGAIN_REG, &val);
++ val |= TLK110_COARSEGAIN_VAL;
++ miiphy_write(name, addr, TLK110_COARSEGAIN_REG, val);
++
++ miiphy_read(name, addr, TLK110_LPFHPF_REG, &val);
++ val |= TLK110_LPFHPF_VAL;
++ miiphy_write(name, addr, TLK110_LPFHPF_REG, val);
++
++ miiphy_read(name, addr, TLK110_SPAREANALOG_REG, &val);
++ val |= TLK110_SPAREANALOG_VAL;
++ miiphy_write(name, addr, TLK110_SPAREANALOG_REG, val);
++
++ miiphy_read(name, addr, TLK110_VRCR_REG, &val);
++ val |= TLK110_VRCR_VAL;
++ miiphy_write(name, addr, TLK110_VRCR_REG, val);
++
++ miiphy_read(name, addr, TLK110_SETFFE_REG, &val);
++ val |= TLK110_SETFFE_VAL;
++ miiphy_write(name, addr, TLK110_SETFFE_REG, val);
++
++ miiphy_read(name, addr, TLK110_FTSP_REG, &val);
++ val |= TLK110_FTSP_VAL;
++ miiphy_write(name, addr, TLK110_FTSP_REG, val);
++
++ miiphy_read(name, addr, TLK110_ALFATPIDL_REG, &val);
++ val |= TLK110_ALFATPIDL_VAL;
++ miiphy_write(name, addr, TLK110_ALFATPIDL_REG, val);
++
++ miiphy_read(name, addr, TLK110_PSCOEF21_REG, &val);
++ val |= TLK110_PSCOEF21_VAL;
++ miiphy_write(name, addr, TLK110_PSCOEF21_REG, val);
++
++ miiphy_read(name, addr, TLK110_PSCOEF3_REG, &val);
++ val |= TLK110_PSCOEF3_VAL;
++ miiphy_write(name, addr, TLK110_PSCOEF3_REG, val);
++
++ miiphy_read(name, addr, TLK110_ALFAFACTOR1_REG, &val);
++ val |= TLK110_ALFAFACTOR1_VAL;
++ miiphy_write(name, addr, TLK110_ALFAFACTOR1_REG, val);
++
++ miiphy_read(name, addr, TLK110_ALFAFACTOR2_REG, &val);
++ val |= TLK110_ALFAFACTOR2_VAL;
++ miiphy_write(name, addr, TLK110_ALFAFACTOR2_REG, val);
++
++ miiphy_read(name, addr, TLK110_CFGPS_REG, &val);
++ val |= TLK110_CFGPS_VAL;
++ miiphy_write(name, addr, TLK110_CFGPS_REG, val);
++
++ miiphy_read(name, addr, TLK110_FTSPTXGAIN_REG, &val);
++ val |= TLK110_FTSPTXGAIN_VAL;
++ miiphy_write(name, addr, TLK110_FTSPTXGAIN_REG, val);
++
++ miiphy_read(name, addr, TLK110_SWSCR3_REG, &val);
++ val |= TLK110_SWSCR3_VAL;
++ miiphy_write(name, addr, TLK110_SWSCR3_REG, val);
++
++ miiphy_read(name, addr, TLK110_SCFALLBACK_REG, &val);
++ val |= TLK110_SCFALLBACK_VAL;
++ miiphy_write(name, addr, TLK110_SCFALLBACK_REG, val);
++
++ miiphy_read(name, addr, TLK110_PHYRCR_REG, &val);
++ val |= TLK110_PHYRCR_VAL;
++ miiphy_write(name, addr, TLK110_PHYRCR_REG, val);
++ }
++
++ /* Enable Autonegotiation */
++ if (miiphy_read(name, addr, MII_BMCR, &val) != 0) {
++ printf("failed to read bmcr\n");
++ return;
++ }
++
++ if (bone_pre_a3) {
++ val &= ~(BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_SPEED100);
++ val |= BMCR_FULLDPLX;
++ } else
++ val |= BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_SPEED100;
++
++ if (miiphy_write(name, addr, MII_BMCR, val) != 0) {
++ printf("failed to write bmcr\n");
++ return;
++ }
++ miiphy_read(name, addr, MII_BMCR, &val);
++
++ /* TODO: Disable GIG advertisement for the time being */
++ if (board_id != IA_BOARD && board_id != BONE_BOARD) {
++ miiphy_read(name, addr, MII_CTRL1000, &val);
++ val &= ~PHY_1000BTCR_1000FD;
++ val &= ~PHY_1000BTCR_1000HD;
++ miiphy_write(name, addr, MII_CTRL1000, val);
++ miiphy_read(name, addr, MII_CTRL1000, &val);
++ }
++
++ /* Setup general advertisement */
++ if (miiphy_read(name, addr, MII_ADVERTISE, &val) != 0) {
++ printf("failed to read anar\n");
++ return;
++ }
++
++ if (bone_pre_a3)
++ val |= (LPA_10HALF | LPA_10FULL);
++ else
++ val |= (LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL);
++
++ if (miiphy_write(name, addr, MII_ADVERTISE, val) != 0) {
++ printf("failed to write anar\n");
++ return;
++ }
++ miiphy_read(name, addr, MII_ADVERTISE, &val);
++
++ /* Restart auto negotiation*/
++ miiphy_read(name, addr, MII_BMCR, &val);
++ val |= BMCR_ANRESTART;
++ miiphy_write(name, addr, MII_BMCR, val);
++
++ /*check AutoNegotiate complete - it can take upto 3 secs*/
++ do {
++ udelay(40000);
++ cntr++;
++ if (!miiphy_read(name, addr, MII_BMSR, &val)) {
++ if (val & BMSR_ANEGCOMPLETE)
++ break;
++ }
++ } while (cntr < 250);
++
++ if (cntr >= 250)
++ printf("Auto negotitation failed\n");
++
++ return;
++}
++
++static void cpsw_control(int enabled)
++{
++ /* nothing for now */
++ /* TODO : VTP was here before */
++ return;
++}
++
++static struct cpsw_slave_data cpsw_slaves[] = {
++ {
++ .slave_reg_ofs = 0x208,
++ .sliver_reg_ofs = 0xd80,
++ .phy_id = 0,
++ },
++ {
++ .slave_reg_ofs = 0x308,
++ .sliver_reg_ofs = 0xdc0,
++ .phy_id = 1,
++ },
++};
++
++static struct cpsw_platform_data cpsw_data = {
++ .mdio_base = AM335X_CPSW_MDIO_BASE,
++ .cpsw_base = AM335X_CPSW_BASE,
++ .mdio_div = 0xff,
++ .channels = 8,
++ .cpdma_reg_ofs = 0x800,
++ .slaves = 2,
++ .slave_data = cpsw_slaves,
++ .ale_reg_ofs = 0xd00,
++ .ale_entries = 1024,
++ .host_port_reg_ofs = 0x108,
++ .hw_stats_reg_ofs = 0x900,
++ .mac_control = (1 << 5) /* MIIEN */,
++ .control = cpsw_control,
++ .phy_init = evm_phy_init,
++ .host_port_num = 0,
++ .version = CPSW_CTRL_VERSION_2,
++};
++
++int board_eth_init(bd_t *bis)
++{
++ uint8_t mac_addr[6];
++ uint32_t mac_hi, mac_lo;
++ u_int32_t i;
++
++ if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
++ debug("<ethaddr> not set. Reading from E-fuse\n");
++ /* try reading mac address from efuse */
++ mac_lo = __raw_readl(MAC_ID0_LO);
++ mac_hi = __raw_readl(MAC_ID0_HI);
++ mac_addr[0] = mac_hi & 0xFF;
++ mac_addr[1] = (mac_hi & 0xFF00) >> 8;
++ mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
++ mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
++ mac_addr[4] = mac_lo & 0xFF;
++ mac_addr[5] = (mac_lo & 0xFF00) >> 8;
++
++ if (!is_valid_ether_addr(mac_addr)) {
++ debug("Did not find a valid mac address in e-fuse. "
++ "Trying the one present in EEPROM\n");
++
++ for (i = 0; i < ETH_ALEN; i++)
++ mac_addr[i] = header.mac_addr[0][i];
++ }
++
++ if (is_valid_ether_addr(mac_addr))
++ eth_setenv_enetaddr("ethaddr", mac_addr);
++ else {
++ printf("Caution: Using hardcoded mac address. "
++ "Set <ethaddr> variable to overcome this.\n");
++ }
++ }
++
++ if (board_id == BONE_BOARD) {
++ /* For beaglebone > Rev A2 , enable MII mode, for others enable RMII */
++ if (!strncmp(header.version, "00A1", 4) ||
++ !strncmp(header.version, "00A2", 4))
++ __raw_writel(RMII_MODE_ENABLE, MAC_MII_SEL);
++ else
++ __raw_writel(MII_MODE_ENABLE, MAC_MII_SEL);
++ } else if (board_id == IA_BOARD) {
++ cpsw_slaves[0].phy_id = 30;
++ cpsw_slaves[1].phy_id = 0;
++ } else {
++ /* set mii mode to rgmii in in device configure register */
++ __raw_writel(RGMII_MODE_ENABLE, MAC_MII_SEL);
++ }
++
++ return cpsw_register(&cpsw_data);
++}
++#endif
++
++#ifndef CONFIG_SPL_BUILD
++#ifdef CONFIG_GENERIC_MMC
++int board_mmc_init(bd_t *bis)
++{
++ omap_mmc_init(0);
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_NAND_TI81XX
++/******************************************************************************
++ * Command to switch between NAND HW and SW ecc
++ *****************************************************************************/
++extern void ti81xx_nand_switch_ecc(nand_ecc_modes_t hardware, int32_t mode);
++static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
++{
++ int type = 0;
++ if (argc < 2)
++ goto usage;
++
++ if (strncmp(argv[1], "hw", 2) == 0) {
++ if (argc == 3)
++ type = simple_strtoul(argv[2], NULL, 10);
++ ti81xx_nand_switch_ecc(NAND_ECC_HW, type);
++ }
++ else if (strncmp(argv[1], "sw", 2) == 0)
++ ti81xx_nand_switch_ecc(NAND_ECC_SOFT, 0);
++ else
++ goto usage;
++
++ return 0;
++
++usage:
++ printf("Usage: nandecc %s\n", cmdtp->usage);
++ return 1;
++}
++
++U_BOOT_CMD(
++ nandecc, 3, 1, do_switch_ecc,
++ "Switch NAND ECC calculation algorithm b/w hardware and software",
++ "[sw|hw <hw_type>] \n"
++ " [sw|hw]- Switch b/w hardware(hw) & software(sw) ecc algorithm\n"
++ " hw_type- 0 for Hamming code\n"
++ " 1 for bch4\n"
++ " 2 for bch8\n"
++ " 3 for bch16\n"
++);
++
++#endif /* CONFIG_NAND_TI81XX */
++#endif /* CONFIG_SPL_BUILD */
+diff --git a/board/ti/am335x/mux.c b/board/ti/am335x/mux.c
+new file mode 100644
+index 0000000..d9956f3
+--- /dev/null
++++ b/board/ti/am335x/mux.c
+@@ -0,0 +1,688 @@
++/*
++ * mux.c
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#include <common.h>
++#include <config.h>
++#include <asm/io.h>
++#include "common_def.h"
++#include <asm/arch/hardware.h>
++
++#define MUX_CFG(value, offset) \
++ __raw_writel(value, (CTRL_BASE + offset));
++
++/* PAD Control Fields */
++#define SLEWCTRL (0x1 << 6)
++#define RXACTIVE (0x1 << 5)
++#define PULLUP_EN (0x1 << 4) /* Pull UP Selection */
++#define PULLUDEN (0x0 << 3) /* Pull up enabled */
++#define PULLUDDIS (0x1 << 3) /* Pull up disabled */
++#define MODE(val) val
++
++/*
++ * PAD CONTROL OFFSETS
++ * Field names corresponds to the pad signal name
++ */
++struct pad_signals {
++ int gpmc_ad0;
++ int gpmc_ad1;
++ int gpmc_ad2;
++ int gpmc_ad3;
++ int gpmc_ad4;
++ int gpmc_ad5;
++ int gpmc_ad6;
++ int gpmc_ad7;
++ int gpmc_ad8;
++ int gpmc_ad9;
++ int gpmc_ad10;
++ int gpmc_ad11;
++ int gpmc_ad12;
++ int gpmc_ad13;
++ int gpmc_ad14;
++ int gpmc_ad15;
++ int gpmc_a0;
++ int gpmc_a1;
++ int gpmc_a2;
++ int gpmc_a3;
++ int gpmc_a4;
++ int gpmc_a5;
++ int gpmc_a6;
++ int gpmc_a7;
++ int gpmc_a8;
++ int gpmc_a9;
++ int gpmc_a10;
++ int gpmc_a11;
++ int gpmc_wait0;
++ int gpmc_wpn;
++ int gpmc_be1n;
++ int gpmc_csn0;
++ int gpmc_csn1;
++ int gpmc_csn2;
++ int gpmc_csn3;
++ int gpmc_clk;
++ int gpmc_advn_ale;
++ int gpmc_oen_ren;
++ int gpmc_wen;
++ int gpmc_be0n_cle;
++ int lcd_data0;
++ int lcd_data1;
++ int lcd_data2;
++ int lcd_data3;
++ int lcd_data4;
++ int lcd_data5;
++ int lcd_data6;
++ int lcd_data7;
++ int lcd_data8;
++ int lcd_data9;
++ int lcd_data10;
++ int lcd_data11;
++ int lcd_data12;
++ int lcd_data13;
++ int lcd_data14;
++ int lcd_data15;
++ int lcd_vsync;
++ int lcd_hsync;
++ int lcd_pclk;
++ int lcd_ac_bias_en;
++ int mmc0_dat3;
++ int mmc0_dat2;
++ int mmc0_dat1;
++ int mmc0_dat0;
++ int mmc0_clk;
++ int mmc0_cmd;
++ int mii1_col;
++ int mii1_crs;
++ int mii1_rxerr;
++ int mii1_txen;
++ int mii1_rxdv;
++ int mii1_txd3;
++ int mii1_txd2;
++ int mii1_txd1;
++ int mii1_txd0;
++ int mii1_txclk;
++ int mii1_rxclk;
++ int mii1_rxd3;
++ int mii1_rxd2;
++ int mii1_rxd1;
++ int mii1_rxd0;
++ int rmii1_refclk;
++ int mdio_data;
++ int mdio_clk;
++ int spi0_sclk;
++ int spi0_d0;
++ int spi0_d1;
++ int spi0_cs0;
++ int spi0_cs1;
++ int ecap0_in_pwm0_out;
++ int uart0_ctsn;
++ int uart0_rtsn;
++ int uart0_rxd;
++ int uart0_txd;
++ int uart1_ctsn;
++ int uart1_rtsn;
++ int uart1_rxd;
++ int uart1_txd;
++ int i2c0_sda;
++ int i2c0_scl;
++ int mcasp0_aclkx;
++ int mcasp0_fsx;
++ int mcasp0_axr0;
++ int mcasp0_ahclkr;
++ int mcasp0_aclkr;
++ int mcasp0_fsr;
++ int mcasp0_axr1;
++ int mcasp0_ahclkx;
++ int xdma_event_intr0;
++ int xdma_event_intr1;
++ int nresetin_out;
++ int porz;
++ int nnmi;
++ int osc0_in;
++ int osc0_out;
++ int rsvd1;
++ int tms;
++ int tdi;
++ int tdo;
++ int tck;
++ int ntrst;
++ int emu0;
++ int emu1;
++ int osc1_in;
++ int osc1_out;
++ int pmic_power_en;
++ int rtc_porz;
++ int rsvd2;
++ int ext_wakeup;
++ int enz_kaldo_1p8v;
++ int usb0_dm;
++ int usb0_dp;
++ int usb0_ce;
++ int usb0_id;
++ int usb0_vbus;
++ int usb0_drvvbus;
++ int usb1_dm;
++ int usb1_dp;
++ int usb1_ce;
++ int usb1_id;
++ int usb1_vbus;
++ int usb1_drvvbus;
++ int ddr_resetn;
++ int ddr_csn0;
++ int ddr_cke;
++ int ddr_ck;
++ int ddr_nck;
++ int ddr_casn;
++ int ddr_rasn;
++ int ddr_wen;
++ int ddr_ba0;
++ int ddr_ba1;
++ int ddr_ba2;
++ int ddr_a0;
++ int ddr_a1;
++ int ddr_a2;
++ int ddr_a3;
++ int ddr_a4;
++ int ddr_a5;
++ int ddr_a6;
++ int ddr_a7;
++ int ddr_a8;
++ int ddr_a9;
++ int ddr_a10;
++ int ddr_a11;
++ int ddr_a12;
++ int ddr_a13;
++ int ddr_a14;
++ int ddr_a15;
++ int ddr_odt;
++ int ddr_d0;
++ int ddr_d1;
++ int ddr_d2;
++ int ddr_d3;
++ int ddr_d4;
++ int ddr_d5;
++ int ddr_d6;
++ int ddr_d7;
++ int ddr_d8;
++ int ddr_d9;
++ int ddr_d10;
++ int ddr_d11;
++ int ddr_d12;
++ int ddr_d13;
++ int ddr_d14;
++ int ddr_d15;
++ int ddr_dqm0;
++ int ddr_dqm1;
++ int ddr_dqs0;
++ int ddr_dqsn0;
++ int ddr_dqs1;
++ int ddr_dqsn1;
++ int ddr_vref;
++ int ddr_vtp;
++ int ddr_strben0;
++ int ddr_strben1;
++ int ain7;
++ int ain6;
++ int ain5;
++ int ain4;
++ int ain3;
++ int ain2;
++ int ain1;
++ int ain0;
++ int vrefp;
++ int vrefn;
++};
++
++struct module_pin_mux {
++ short reg_offset;
++ unsigned char val;
++};
++
++struct evm_pin_mux {
++ struct module_pin_mux *mod_pin_mux;
++ unsigned short profile;
++/*
++* If the device is required on both baseboard & daughter board (ex i2c),
++* specify DEV_ON_BASEBOARD
++*/
++#define DEV_ON_BASEBOARD 0
++#define DEV_ON_DGHTR_BRD 1
++ unsigned short device_on;
++};
++
++#define PAD_CTRL_BASE 0x800
++#define OFFSET(x) (unsigned int) (&((struct pad_signals *) \
++ (PAD_CTRL_BASE))->x)
++
++static struct module_pin_mux uart0_pin_mux[] = {
++ {OFFSET(uart0_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* UART0_RXD */
++ {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)}, /* UART0_TXD */
++ {-1},
++};
++
++static struct module_pin_mux uart3_pin_mux[] = {
++ {OFFSET(spi0_cs1), (MODE(1) | PULLUDEN | RXACTIVE)}, /* UART3_RXD */
++ {OFFSET(ecap0_in_pwm0_out), (MODE(1) | PULLUDEN)}, /* UART3_TXD */
++ {-1},
++};
++
++
++#ifdef CONFIG_NAND
++static struct module_pin_mux nand_pin_mux[] = {
++ {OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD0 */
++ {OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD1 */
++ {OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD2 */
++ {OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD3 */
++ {OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD4 */
++ {OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD5 */
++ {OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD6 */
++ {OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD7 */
++ {OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */
++ {OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)}, /* NAND_WPN */
++ {OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)}, /* NAND_CS0 */
++ {OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */
++ {OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)}, /* NAND_OE */
++ {OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)}, /* NAND_WEN */
++ {OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)}, /* NAND_BE_CLE */
++ {-1},
++};
++#endif
++
++static struct module_pin_mux i2c0_pin_mux[] = {
++ {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
++ {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
++ {-1},
++};
++
++static struct module_pin_mux i2c1_pin_mux[] = {
++ {OFFSET(spi0_d1), (MODE(2) | RXACTIVE | PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
++ {OFFSET(spi0_cs0), (MODE(2) | RXACTIVE | PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
++ {-1},
++};
++
++#ifndef CONFIG_NO_ETH
++static struct module_pin_mux rgmii1_pin_mux[] = {
++ {OFFSET(mii1_txen), MODE(2)}, /* RGMII1_TCTL */
++ {OFFSET(mii1_rxdv), MODE(2) | RXACTIVE}, /* RGMII1_RCTL */
++ {OFFSET(mii1_txd3), MODE(2)}, /* RGMII1_TD3 */
++ {OFFSET(mii1_txd2), MODE(2)}, /* RGMII1_TD2 */
++ {OFFSET(mii1_txd1), MODE(2)}, /* RGMII1_TD1 */
++ {OFFSET(mii1_txd0), MODE(2)}, /* RGMII1_TD0 */
++ {OFFSET(mii1_txclk), MODE(2)}, /* RGMII1_TCLK */
++ {OFFSET(mii1_rxclk), MODE(2) | RXACTIVE}, /* RGMII1_RCLK */
++ {OFFSET(mii1_rxd3), MODE(2) | RXACTIVE}, /* RGMII1_RD3 */
++ {OFFSET(mii1_rxd2), MODE(2) | RXACTIVE}, /* RGMII1_RD2 */
++ {OFFSET(mii1_rxd1), MODE(2) | RXACTIVE}, /* RGMII1_RD1 */
++ {OFFSET(mii1_rxd0), MODE(2) | RXACTIVE}, /* RGMII1_RD0 */
++ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
++ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
++ {-1},
++};
++
++static struct module_pin_mux rgmii2_pin_mux[] = {
++ {OFFSET(gpmc_a0), MODE(2)}, /* RGMII2_TCTL */
++ {OFFSET(gpmc_a1), MODE(2) | RXACTIVE}, /* RGMII2_RCTL */
++ {OFFSET(gpmc_a2), MODE(2)}, /* RGMII2_TD3 */
++ {OFFSET(gpmc_a3), MODE(2)}, /* RGMII2_TD2 */
++ {OFFSET(gpmc_a4), MODE(2)}, /* RGMII2_TD1 */
++ {OFFSET(gpmc_a5), MODE(2)}, /* RGMII2_TD0 */
++ {OFFSET(gpmc_a6), MODE(2)}, /* RGMII2_TCLK */
++ {OFFSET(gpmc_a7), MODE(2) | RXACTIVE}, /* RGMII2_RCLK */
++ {OFFSET(gpmc_a8), MODE(2) | RXACTIVE}, /* RGMII2_RD3 */
++ {OFFSET(gpmc_a9), MODE(2) | RXACTIVE}, /* RGMII2_RD2 */
++ {OFFSET(gpmc_a10), MODE(2) | RXACTIVE}, /* RGMII2_RD1 */
++ {OFFSET(gpmc_a11), MODE(2) | RXACTIVE}, /* RGMII2_RD0 */
++ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
++ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
++ {-1},
++};
++
++static struct module_pin_mux mii1_pin_mux[] = {
++ {OFFSET(mii1_rxerr), MODE(0) | RXACTIVE}, /* MII1_RXERR */
++ {OFFSET(mii1_txen), MODE(0)}, /* MII1_TXEN */
++ {OFFSET(mii1_rxdv), MODE(0) | RXACTIVE}, /* MII1_RXDV */
++ {OFFSET(mii1_txd3), MODE(0)}, /* MII1_TXD3 */
++ {OFFSET(mii1_txd2), MODE(0)}, /* MII1_TXD2 */
++ {OFFSET(mii1_txd1), MODE(0)}, /* MII1_TXD1 */
++ {OFFSET(mii1_txd0), MODE(0)}, /* MII1_TXD0 */
++ {OFFSET(mii1_txclk), MODE(0) | RXACTIVE}, /* MII1_TXCLK */
++ {OFFSET(mii1_rxclk), MODE(0) | RXACTIVE}, /* MII1_RXCLK */
++ {OFFSET(mii1_rxd3), MODE(0) | RXACTIVE}, /* MII1_RXD3 */
++ {OFFSET(mii1_rxd2), MODE(0) | RXACTIVE}, /* MII1_RXD2 */
++ {OFFSET(mii1_rxd1), MODE(0) | RXACTIVE}, /* MII1_RXD1 */
++ {OFFSET(mii1_rxd0), MODE(0) | RXACTIVE}, /* MII1_RXD0 */
++ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
++ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
++ {-1},
++};
++
++static struct module_pin_mux rmii1_pin_mux[] = {
++ {OFFSET(mii1_crs), MODE(1) | RXACTIVE}, /* RMII1_CRS */
++ {OFFSET(mii1_rxerr), MODE(1) | RXACTIVE}, /* RMII1_RXERR */
++ {OFFSET(mii1_txen), MODE(1)}, /* RMII1_TXEN */
++ {OFFSET(mii1_txd1), MODE(1)}, /* RMII1_TXD1 */
++ {OFFSET(mii1_txd0), MODE(1)}, /* RMII1_TXD0 */
++ {OFFSET(mii1_rxd1), MODE(1) | RXACTIVE}, /* RMII1_RXD1 */
++ {OFFSET(mii1_rxd0), MODE(1) | RXACTIVE}, /* RMII1_RXD0 */
++ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
++ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
++ {OFFSET(rmii1_refclk), MODE(0) | RXACTIVE}, /* RMII1_REFCLK */
++ {-1},
++};
++#endif
++
++#ifdef CONFIG_NOR
++static struct module_pin_mux nor_pin_mux[] = {
++ {OFFSET(lcd_data0), MODE(1) | PULLUDEN}, /* NOR_A0 */
++ {OFFSET(lcd_data1), MODE(1) | PULLUDEN}, /* NOR_A1 */
++ {OFFSET(lcd_data2), MODE(1) | PULLUDEN}, /* NOR_A2 */
++ {OFFSET(lcd_data3), MODE(1) | PULLUDEN}, /* NOR_A3 */
++ {OFFSET(lcd_data4), MODE(1) | PULLUDEN}, /* NOR_A4 */
++ {OFFSET(lcd_data5), MODE(1) | PULLUDEN}, /* NOR_A5 */
++ {OFFSET(lcd_data6), MODE(1) | PULLUDEN}, /* NOR_A6 */
++ {OFFSET(lcd_data7), MODE(1) | PULLUDEN}, /* NOR_A7 */
++ {OFFSET(gpmc_a8), MODE(0)}, /* NOR_A8 */
++ {OFFSET(gpmc_a9), MODE(0)}, /* NOR_A9 */
++ {OFFSET(gpmc_a10), MODE(0)}, /* NOR_A10 */
++ {OFFSET(gpmc_a11), MODE(0)}, /* NOR_A11 */
++ {OFFSET(lcd_data8), MODE(1) | PULLUDEN}, /* NOR_A12 */
++ {OFFSET(lcd_data9), MODE(1) | PULLUDEN}, /* NOR_A13 */
++ {OFFSET(lcd_data10), MODE(1) | PULLUDEN}, /* NOR_A14 */
++ {OFFSET(lcd_data11), MODE(1) | PULLUDEN}, /* NOR_A15 */
++ {OFFSET(lcd_data12), MODE(1) | PULLUDEN}, /* NOR_A16 */
++ {OFFSET(lcd_data13), MODE(1) | PULLUDEN}, /* NOR_A17 */
++ {OFFSET(lcd_data14), MODE(1) | PULLUDEN}, /* NOR_A18 */
++ {OFFSET(lcd_data15), MODE(1) | PULLUDEN}, /* NOR_A19 */
++ {OFFSET(gpmc_a4), MODE(4)}, /* NOR_A20 */
++ {OFFSET(gpmc_a5), MODE(4)}, /* NOR_A21 */
++ {OFFSET(gpmc_a6), MODE(4)}, /* NOR_A22 */
++ {OFFSET(gpmc_ad0), MODE(0) | RXACTIVE}, /* NOR_AD0 */
++ {OFFSET(gpmc_ad1), MODE(0) | RXACTIVE}, /* NOR_AD1 */
++ {OFFSET(gpmc_ad2), MODE(0) | RXACTIVE}, /* NOR_AD2 */
++ {OFFSET(gpmc_ad3), MODE(0) | RXACTIVE}, /* NOR_AD3 */
++ {OFFSET(gpmc_ad4), MODE(0) | RXACTIVE}, /* NOR_AD4 */
++ {OFFSET(gpmc_ad5), MODE(0) | RXACTIVE}, /* NOR_AD5 */
++ {OFFSET(gpmc_ad6), MODE(0) | RXACTIVE}, /* NOR_AD6 */
++ {OFFSET(gpmc_ad7), MODE(0) | RXACTIVE}, /* NOR_AD7 */
++ {OFFSET(gpmc_ad8), MODE(0) | RXACTIVE}, /* NOR_AD8 */
++ {OFFSET(gpmc_ad9), MODE(0) | RXACTIVE}, /* NOR_AD9 */
++ {OFFSET(gpmc_ad10), MODE(0) | RXACTIVE}, /* NOR_AD10 */
++ {OFFSET(gpmc_ad11), MODE(0) | RXACTIVE}, /* NOR_AD11 */
++ {OFFSET(gpmc_ad12), MODE(0) | RXACTIVE}, /* NOR_AD12 */
++ {OFFSET(gpmc_ad13), MODE(0) | RXACTIVE}, /* NOR_AD13 */
++ {OFFSET(gpmc_ad14), MODE(0) | RXACTIVE}, /* NOR_AD14 */
++ {OFFSET(gpmc_ad15), MODE(0) | RXACTIVE}, /* NOR_AD15 */
++ {OFFSET(gpmc_csn0), (MODE(0) | PULLUP_EN)}, /* NOR_CE */
++ {OFFSET(gpmc_oen_ren), (MODE(0) | PULLUP_EN)}, /* NOR_OE */
++ {OFFSET(gpmc_wen), (MODE(0) | PULLUP_EN)}, /* NOR_WEN */
++ {OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NOR WAIT */
++ {OFFSET(lcd_ac_bias_en), MODE(7) | RXACTIVE | PULLUDEN}, /* NOR RESET */
++ {-1},
++};
++#endif
++
++#ifdef CONFIG_MMC
++static struct module_pin_mux mmc0_pin_mux[] = {
++ {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT3 */
++ {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT2 */
++ {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT1 */
++ {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT0 */
++ {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CLK */
++ {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CMD */
++ {OFFSET(mcasp0_aclkr), (MODE(4) | RXACTIVE)}, /* MMC0_WP */
++ {OFFSET(spi0_cs1), (MODE(5) | RXACTIVE | PULLUP_EN)}, /* MMC0_CD */
++ {-1},
++};
++
++static struct module_pin_mux mmc1_pin_mux[] = {
++ {OFFSET(gpmc_ad3), (MODE(1) | RXACTIVE)}, /* MMC1_DAT3 */
++ {OFFSET(gpmc_ad2), (MODE(1) | RXACTIVE)}, /* MMC1_DAT2 */
++ {OFFSET(gpmc_ad1), (MODE(1) | RXACTIVE)}, /* MMC1_DAT1 */
++ {OFFSET(gpmc_ad0), (MODE(1) | RXACTIVE)}, /* MMC1_DAT0 */
++ {OFFSET(gpmc_csn1), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* MMC1_CLK */
++ {OFFSET(gpmc_csn2), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* MMC1_CMD */
++ {OFFSET(uart1_rxd), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_WP */
++ {OFFSET(mcasp0_fsx), (MODE(4) | RXACTIVE)}, /* MMC1_CD */
++ {-1},
++};
++#endif
++
++#ifdef CONFIG_SPI
++static struct module_pin_mux spi0_pin_mux[] = {
++ {OFFSET(spi0_sclk), MODE(0) | PULLUDEN | RXACTIVE}, /*SPI0_SCLK */
++ {OFFSET(spi0_d0), MODE(0) | PULLUDEN | PULLUP_EN |
++ RXACTIVE}, /*SPI0_D0 */
++ {OFFSET(spi0_d1), MODE(0) | PULLUDEN |
++ RXACTIVE}, /*SPI0_D1 */
++ {OFFSET(spi0_cs0), MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE}, /*SPI0_CS0 */
++ {-1},
++};
++
++static struct module_pin_mux spi1_pin_mux[] = {
++ {OFFSET(mcasp0_aclkx), MODE(3) | PULLUDEN | RXACTIVE}, /*SPI0_SCLK */
++ {OFFSET(mcasp0_fsx), MODE(3) | PULLUDEN | PULLUP_EN |
++ RXACTIVE}, /*SPI0_D0 */
++ {OFFSET(mcasp0_axr0), MODE(3) | PULLUDEN | RXACTIVE}, /*SPI0_D1 */
++ {OFFSET(mcasp0_ahclkr), MODE(3) | PULLUDEN | PULLUP_EN |
++ RXACTIVE}, /*SPI0_CS0 */
++ {-1},
++};
++#endif
++
++/*
++ * Update the structure with the modules present in the general purpose
++ * board and the profiles in which the modules are present.
++ * If the module is physically present but if it is not available
++ * in any of the profile, then do not update it.
++ * For eg, nand is avialable only in the profiles 0 and 1, whereas
++ * UART0 is available in all the profiles.
++ */
++static struct evm_pin_mux general_purpose_evm_pin_mux[] = {
++ {uart0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {i2c1_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_4, DEV_ON_BASEBOARD},
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_3, DEV_ON_DGHTR_BRD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {rgmii1_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {rgmii2_pin_mux, PROFILE_1 | PROFILE_2 | PROFILE_4 | PROFILE_6,
++ DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_NOR
++ {nor_pin_mux, PROFILE_3, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {mmc1_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_SPI
++ {spi0_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++ {0},
++};
++
++/*
++ * Update the structure with the modules present in the ia daughter board and
++ * the profiles in which the modules are present. If the module is physically
++ * present but if it is not available in any of the profile, then do not update
++ */
++static struct evm_pin_mux ia_motor_control_evm_pin_mux[] = {
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_ALL, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++#endif
++#ifdef CONFIG_SPI
++ {spi1_pin_mux, PROFILE_ALL, DEV_ON_DGHTR_BRD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {mii1_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++#endif
++ {uart3_pin_mux, PROFILE_ALL, DEV_ON_DGHTR_BRD},
++ {0},
++};
++
++/* IP Phone EVM has single profile */
++static struct evm_pin_mux ip_phone_evm_pin_mux[] = {
++ {uart0_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++ {i2c1_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_0, DEV_ON_BASEBOARD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {rgmii1_pin_mux, PROFILE_0, DEV_ON_BASEBOARD},
++ {rgmii2_pin_mux, PROFILE_0, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_0, DEV_ON_BASEBOARD},
++#endif
++ {0},
++};
++
++/* Base board has single profile */
++static struct evm_pin_mux low_cost_evm_pin_mux[] = {
++ {uart0_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++ {i2c1_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {rgmii1_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++#endif
++ {0},
++};
++
++static struct evm_pin_mux beaglebone_pin_mux[] = {
++ {uart0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {i2c1_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_4, DEV_ON_BASEBOARD},
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_3, DEV_ON_DGHTR_BRD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {mii1_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {mmc1_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_SPI
++ {spi0_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++ {0},
++};
++
++static struct evm_pin_mux beaglebone_old_pin_mux[] = {
++ {uart0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {i2c1_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_4, DEV_ON_BASEBOARD},
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_3, DEV_ON_DGHTR_BRD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {rmii1_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {mmc1_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_SPI
++ {spi0_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++ {0},
++};
++
++static struct evm_pin_mux *am335x_evm_pin_mux[] = {
++ beaglebone_pin_mux,
++ general_purpose_evm_pin_mux,
++ ia_motor_control_evm_pin_mux,
++ ip_phone_evm_pin_mux,
++ low_cost_evm_pin_mux,
++};
++
++/*
++ * Configure the pin mux for the module
++ */
++static void configure_module_pin_mux(struct module_pin_mux *mod_pin_mux)
++{
++ int i;
++
++ if (!mod_pin_mux)
++ return;
++
++ for (i = 0; mod_pin_mux[i].reg_offset != -1; i++)
++ MUX_CFG(mod_pin_mux[i].val, mod_pin_mux[i].reg_offset);
++}
++
++/*
++ * Check each module in the daughter board(first argument) whether it is
++ * available in the selected profile(second argument). If the module is not
++ * available in the selected profile, skip the corresponding configuration.
++ */
++static void set_evm_pin_mux(struct evm_pin_mux *pin_mux,
++ int prof, unsigned int dghtr_brd_flg)
++{
++ int i;
++
++ if (!pin_mux)
++ return;
++
++ /*
++ * Only General Purpose & Industrial Auto Motro Control
++ * EVM has profiles. So check if this evm has profile.
++ * If not, ignore the profile comparison
++ */
++
++ /*
++ * If the device is on baseboard, directly configure it. Else (device on
++ * Daughter board), check if the daughter card is detected.
++ */
++
++ for (i = 0; pin_mux[i].mod_pin_mux != 0; i++) {
++ if ((pin_mux[i].profile & prof) ||
++ (prof == PROFILE_NONE)) {
++ if (pin_mux->device_on == DEV_ON_BASEBOARD)
++ configure_module_pin_mux(pin_mux[i].
++ mod_pin_mux);
++ else if (dghtr_brd_flg)
++ configure_module_pin_mux(pin_mux[i].
++ mod_pin_mux);
++ }
++ }
++}
++
++void configure_evm_pin_mux(unsigned char dghtr_brd_id, char version[4], unsigned short
++ profile, unsigned int daughter_board_flag)
++{
++ if (dghtr_brd_id > BASE_BOARD)
++ return;
++
++ /* Setup correct evm pinmux for older bone boards (Rev < A2) */
++ if (dghtr_brd_id == BONE_BOARD &&
++ (!strncmp(version, "00A2", 4) || !strncmp(version, "00A1", 4)))
++ am335x_evm_pin_mux[dghtr_brd_id] = beaglebone_old_pin_mux;
++
++ set_evm_pin_mux(am335x_evm_pin_mux[dghtr_brd_id], profile,
++ daughter_board_flag);
++}
++
++void enable_i2c0_pin_mux(void)
++{
++ configure_module_pin_mux(i2c0_pin_mux);
++}
++
++void enable_uart0_pin_mux(void)
++{
++ configure_module_pin_mux(uart0_pin_mux);
++}
+diff --git a/board/ti/am335x/pll.c b/board/ti/am335x/pll.c
+new file mode 100644
+index 0000000..5391ee4
+--- /dev/null
++++ b/board/ti/am335x/pll.c
+@@ -0,0 +1,292 @@
++/*
++ * pll.c
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#include <common.h>
++#include <asm/io.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/clock.h>
++#include <asm/arch/hardware.h>
++#include "common_def.h"
++
++#define PRCM_MOD_EN 0x2
++#define PRCM_FORCE_WAKEUP 0x2
++
++#define PRCM_EMIF_CLK_ACTIVITY (0x1 << 2)
++#define PRCM_L3_GCLK_ACTIVITY (0x1 << 4)
++
++#define PLL_BYPASS_MODE 0x4
++#define PLL_LOCK_MODE 0x7
++#define PLL_MULTIPLIER_SHIFT 8
++
++static void interface_clocks_enable(void)
++{
++ /* Enable all the Interconnect Modules */
++ __raw_writel(PRCM_MOD_EN, CM_PER_L3_CLKCTRL);
++ while (__raw_readl(CM_PER_L3_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_L4LS_CLKCTRL);
++ while (__raw_readl(CM_PER_L4LS_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_L4FW_CLKCTRL);
++ while (__raw_readl(CM_PER_L4FW_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_WKUP_L4WKUP_CLKCTRL);
++ while (__raw_readl(CM_WKUP_L4WKUP_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_L3_INSTR_CLKCTRL);
++ while (__raw_readl(CM_PER_L3_INSTR_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_L4HS_CLKCTRL);
++ while (__raw_readl(CM_PER_L4HS_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_SPI1_CLKCTRL);
++ while (__raw_readl(CM_PER_SPI1_CLKCTRL) != PRCM_MOD_EN);
++
++ /* GPIO0 */
++ __raw_writel(PRCM_MOD_EN, CM_WKUP_GPIO0_CLKCTRL);
++ while (__raw_readl(CM_WKUP_GPIO0_CLKCTRL) != PRCM_MOD_EN);
++}
++
++static void power_domain_transition_enable(void)
++{
++ /*
++ * Force power domain wake up transition
++ * Ensure that the corresponding interface clock is active before
++ * using the peripheral
++ */
++ __raw_writel(PRCM_FORCE_WAKEUP, CM_PER_L3_CLKSTCTRL);
++
++ __raw_writel(PRCM_FORCE_WAKEUP, CM_PER_L4LS_CLKSTCTRL);
++
++ __raw_writel(PRCM_FORCE_WAKEUP, CM_WKUP_CLKSTCTRL);
++
++ __raw_writel(PRCM_FORCE_WAKEUP, CM_PER_L4FW_CLKSTCTRL);
++
++ __raw_writel(PRCM_FORCE_WAKEUP, CM_PER_L3S_CLKSTCTRL);
++}
++
++/*
++ * Enable the module clock and the power domain for required peripherals
++ */
++static void per_clocks_enable(void)
++{
++ /* Enable the module clock */
++ __raw_writel(PRCM_MOD_EN, CM_PER_TIMER2_CLKCTRL);
++ while (__raw_readl(CM_PER_TIMER2_CLKCTRL) != PRCM_MOD_EN);
++
++ /* Select the Master osc 24 MHZ as Timer2 clock source */
++ __raw_writel(0x1, CLKSEL_TIMER2_CLK);
++
++ /* UART0 */
++ __raw_writel(PRCM_MOD_EN, CM_WKUP_UART0_CLKCTRL);
++ while (__raw_readl(CM_WKUP_UART0_CLKCTRL) != PRCM_MOD_EN);
++
++ /* UART3 */
++ __raw_writel(PRCM_MOD_EN, CM_PER_UART3_CLKCTRL);
++ while (__raw_readl(CM_PER_UART3_CLKCTRL) != PRCM_MOD_EN);
++
++ /* GPMC */
++ __raw_writel(PRCM_MOD_EN, CM_PER_GPMC_CLKCTRL);
++ while (__raw_readl(CM_PER_GPMC_CLKCTRL) != PRCM_MOD_EN);
++
++ /* ELM */
++ __raw_writel(PRCM_MOD_EN, CM_PER_ELM_CLKCTRL);
++ while (__raw_readl(CM_PER_ELM_CLKCTRL) != PRCM_MOD_EN);
++
++ /* i2c0 */
++ __raw_writel(PRCM_MOD_EN, CM_WKUP_I2C0_CLKCTRL);
++ while (__raw_readl(CM_WKUP_I2C0_CLKCTRL) != PRCM_MOD_EN);
++
++ /* i2c1 */
++ __raw_writel(PRCM_MOD_EN, CM_PER_I2C1_CLKCTRL);
++ while (__raw_readl(CM_PER_I2C1_CLKCTRL) != PRCM_MOD_EN);
++
++ /* i2c2 */
++ __raw_writel(PRCM_MOD_EN, CM_PER_I2C2_CLKCTRL);
++ while (__raw_readl(CM_PER_I2C2_CLKCTRL) != PRCM_MOD_EN);
++
++ /* Ethernet */
++ __raw_writel(PRCM_MOD_EN, CM_PER_CPGMAC0_CLKCTRL);
++ __raw_writel(PRCM_MOD_EN, CM_PER_CPSW_CLKSTCTRL);
++ while ((__raw_readl(CM_PER_CPGMAC0_CLKCTRL) & 0x30000) != 0x0);
++
++ /* MMC 0 & 1 */
++ __raw_writel(PRCM_MOD_EN, CM_PER_MMC0_CLKCTRL);
++ while (__raw_readl(CM_PER_MMC0_CLKCTRL) != PRCM_MOD_EN);
++ __raw_writel(PRCM_MOD_EN, CM_PER_MMC1_CLKCTRL);
++ while (__raw_readl(CM_PER_MMC1_CLKCTRL) != PRCM_MOD_EN);
++
++ /* Enable the control module though RBL would have done it*/
++ __raw_writel(PRCM_MOD_EN, CM_WKUP_CONTROL_CLKCTRL);
++ while (__raw_readl(CM_WKUP_CONTROL_CLKCTRL) != PRCM_MOD_EN);
++
++ /* SPI 0 & 1 */
++ __raw_writel(PRCM_MOD_EN, CM_PER_SPI0_CLKCTRL);
++ while (__raw_readl(CM_PER_SPI0_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_SPI1_CLKCTRL);
++ while (__raw_readl(CM_PER_SPI1_CLKCTRL) != PRCM_MOD_EN);
++}
++
++void mpu_pll_config(int mpupll_M)
++{
++ u32 clkmode, clksel, div_m2;
++
++ clkmode = __raw_readl(CM_CLKMODE_DPLL_MPU);
++ clksel = __raw_readl(CM_CLKSEL_DPLL_MPU);
++ div_m2 = __raw_readl(CM_DIV_M2_DPLL_MPU);
++
++ /* Set the PLL to bypass Mode */
++ __raw_writel(PLL_BYPASS_MODE, CM_CLKMODE_DPLL_MPU);
++
++ while(__raw_readl(CM_IDLEST_DPLL_MPU) != 0x00000100);
++
++ clksel = clksel & (~0x7ffff);
++ clksel = clksel | ((mpupll_M << 0x8) | MPUPLL_N);
++ __raw_writel(clksel, CM_CLKSEL_DPLL_MPU);
++
++ div_m2 = div_m2 & ~0x1f;
++ div_m2 = div_m2 | MPUPLL_M2;
++ __raw_writel(div_m2, CM_DIV_M2_DPLL_MPU);
++
++ clkmode = clkmode | 0x7;
++ __raw_writel(clkmode, CM_CLKMODE_DPLL_MPU);
++
++ while(__raw_readl(CM_IDLEST_DPLL_MPU) != 0x1);
++}
++
++static void core_pll_config(void)
++{
++ u32 clkmode, clksel, div_m4, div_m5, div_m6;
++
++ clkmode = __raw_readl(CM_CLKMODE_DPLL_CORE);
++ clksel = __raw_readl(CM_CLKSEL_DPLL_CORE);
++ div_m4 = __raw_readl(CM_DIV_M4_DPLL_CORE);
++ div_m5 = __raw_readl(CM_DIV_M5_DPLL_CORE);
++ div_m6 = __raw_readl(CM_DIV_M6_DPLL_CORE);
++
++ /* Set the PLL to bypass Mode */
++ __raw_writel(PLL_BYPASS_MODE, CM_CLKMODE_DPLL_CORE);
++
++ while(__raw_readl(CM_IDLEST_DPLL_CORE) != 0x00000100);
++
++ clksel = clksel & (~0x7ffff);
++ clksel = clksel | ((COREPLL_M << 0x8) | COREPLL_N);
++ __raw_writel(clksel, CM_CLKSEL_DPLL_CORE);
++
++ div_m4 = div_m4 & ~0x1f;
++ div_m4 = div_m4 | COREPLL_M4;
++ __raw_writel(div_m4, CM_DIV_M4_DPLL_CORE);
++
++ div_m5 = div_m5 & ~0x1f;
++ div_m5 = div_m5 | COREPLL_M5;
++ __raw_writel(div_m5, CM_DIV_M5_DPLL_CORE);
++
++ div_m6 = div_m6 & ~0x1f;
++ div_m6 = div_m6 | COREPLL_M6;
++ __raw_writel(div_m6, CM_DIV_M6_DPLL_CORE);
++
++
++ clkmode = clkmode | 0x7;
++ __raw_writel(clkmode, CM_CLKMODE_DPLL_CORE);
++
++ while(__raw_readl(CM_IDLEST_DPLL_CORE) != 0x1);
++}
++
++static void per_pll_config(void)
++{
++ u32 clkmode, clksel, div_m2;
++
++ clkmode = __raw_readl(CM_CLKMODE_DPLL_PER);
++ clksel = __raw_readl(CM_CLKSEL_DPLL_PER);
++ div_m2 = __raw_readl(CM_DIV_M2_DPLL_PER);
++
++ /* Set the PLL to bypass Mode */
++ __raw_writel(PLL_BYPASS_MODE, CM_CLKMODE_DPLL_PER);
++
++ while(__raw_readl(CM_IDLEST_DPLL_PER) != 0x00000100);
++
++ clksel = clksel & (~0x7ffff);
++ clksel = clksel | ((PERPLL_M << 0x8) | PERPLL_N);
++ __raw_writel(clksel, CM_CLKSEL_DPLL_PER);
++
++ div_m2 = div_m2 & ~0x7f;
++ div_m2 = div_m2 | PERPLL_M2;
++ __raw_writel(div_m2, CM_DIV_M2_DPLL_PER);
++
++ clkmode = clkmode | 0x7;
++ __raw_writel(clkmode, CM_CLKMODE_DPLL_PER);
++
++ while(__raw_readl(CM_IDLEST_DPLL_PER) != 0x1);
++}
++
++static void ddr_pll_config(void)
++{
++ u32 clkmode, clksel, div_m2;
++
++ clkmode = __raw_readl(CM_CLKMODE_DPLL_DDR);
++ clksel = __raw_readl(CM_CLKSEL_DPLL_DDR);
++ div_m2 = __raw_readl(CM_DIV_M2_DPLL_DDR);
++
++ /* Set the PLL to bypass Mode */
++ clkmode = (clkmode & 0xfffffff8) | 0x00000004;
++ __raw_writel(clkmode, CM_CLKMODE_DPLL_DDR);
++
++ while ((__raw_readl(CM_IDLEST_DPLL_DDR) & 0x00000100) != 0x00000100);
++
++ clksel = clksel & (~0x7ffff);
++ clksel = clksel | ((DDRPLL_M << 0x8) | DDRPLL_N);
++ __raw_writel(clksel, CM_CLKSEL_DPLL_DDR);
++
++ div_m2 = div_m2 & 0xFFFFFFE0;
++ div_m2 = div_m2 | DDRPLL_M2;
++ __raw_writel(div_m2, CM_DIV_M2_DPLL_DDR);
++
++ clkmode = (clkmode & 0xfffffff8) | 0x7;
++ __raw_writel(clkmode, CM_CLKMODE_DPLL_DDR);
++
++ while ((__raw_readl(CM_IDLEST_DPLL_DDR) & 0x00000001) != 0x1);
++}
++
++void enable_ddr_clocks(void)
++{
++ /* Enable the EMIF_FW Functional clock */
++ __raw_writel(PRCM_MOD_EN, CM_PER_EMIF_FW_CLKCTRL);
++ /* Enable EMIF0 Clock */
++ __raw_writel(PRCM_MOD_EN, CM_PER_EMIF_CLKCTRL);
++ /* Poll for emif_gclk & L3_G clock are active */
++ while ((__raw_readl(CM_PER_L3_CLKSTCTRL) & (PRCM_EMIF_CLK_ACTIVITY |
++ PRCM_L3_GCLK_ACTIVITY)) != (PRCM_EMIF_CLK_ACTIVITY |
++ PRCM_L3_GCLK_ACTIVITY));
++ /* Poll if module is functional */
++ while ((__raw_readl(CM_PER_EMIF_CLKCTRL)) != PRCM_MOD_EN);
++
++}
++
++/*
++ * Configure the PLL/PRCM for necessary peripherals
++ */
++void pll_init()
++{
++ mpu_pll_config(MPUPLL_M_500);
++ core_pll_config();
++ per_pll_config();
++ ddr_pll_config();
++ /* Enable the required interconnect clocks */
++ interface_clocks_enable();
++ /* Enable power domain transition */
++ power_domain_transition_enable();
++ /* Enable the required peripherals */
++ per_clocks_enable();
++}
+diff --git a/board/ti/am335x/pmic.h b/board/ti/am335x/pmic.h
+new file mode 100644
+index 0000000..39246c6
+--- /dev/null
++++ b/board/ti/am335x/pmic.h
+@@ -0,0 +1,71 @@
++/*
++ * pmic.h
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#ifndef PMIC_h
++#define PMIC_H
++
++#define PMIC_SR_I2C_ADDR 0x12
++/* PMIC Register offsets */
++#define PMIC_VDD1_REG 0x21
++#define PMIC_VDD1_OP_REG 0x22
++#define PMIC_VDD2_REG 0x24
++#define PMIC_VDD2_OP_REG 0x25
++#define PMIC_DEVCTRL_REG 0x3f
++
++/* VDD2 & VDD1 control register (VDD2_REG & VDD1_REG) */
++#define PMIC_VGAIN_SEL_MASK (0x3 << 6)
++#define PMIC_ILMAX_MASK (0x1 << 5)
++#define PMIC_TSTEP_MASK (0x7 << 2)
++#define PMIC_ST_MASK (0x3 << 0)
++
++#define PMIC_REG_VGAIN_SEL_X1 (0x0 << 6)
++#define PMIC_REG_VGAIN_SEL_X1_0 (0x1 << 6)
++#define PMIC_REG_VGAIN_SEL_X3 (0x2 << 6)
++#define PMIC_REG_VGAIN_SEL_X4 (0x3 << 6)
++
++#define PMIC_REG_ILMAX_1_0_A (0x0 << 5)
++#define PMIC_REG_ILMAX_1_5_A (0x1 << 5)
++
++#define PMIC_REG_TSTEP_ (0x0 << 2)
++#define PMIC_REG_TSTEP_12_5 (0x1 << 2)
++#define PMIC_REG_TSTEP_9_4 (0x2 << 2)
++#define PMIC_REG_TSTEP_7_5 (0x3 << 2)
++#define PMIC_REG_TSTEP_6_25 (0x4 << 2)
++#define PMIC_REG_TSTEP_4_7 (0x5 << 2)
++#define PMIC_REG_TSTEP_3_12 (0x6 << 2)
++#define PMIC_REG_TSTEP_2_5 (0x7 << 2)
++
++#define PMIC_REG_ST_OFF (0x0 << 0)
++#define PMIC_REG_ST_ON_HI_POW (0x1 << 0)
++#define PMIC_REG_ST_OFF_1 (0x2 << 0)
++#define PMIC_REG_ST_ON_LOW_POW (0x3 << 0)
++
++
++/* VDD2 & VDD1 voltage selection register. (VDD2_OP_REG & VDD1_OP_REG) */
++#define PMIC_OP_REG_SEL (0x7F << 0)
++
++#define PMIC_OP_REG_CMD_MASK (0x1 << 7)
++#define PMIC_OP_REG_CMD_OP (0x0 << 7)
++#define PMIC_OP_REG_CMD_SR (0x1 << 7)
++
++#define PMIC_OP_REG_SEL_MASK (0x7F << 0)
++#define PMIC_OP_REG_SEL_1_2 (0x33 << 0)
++#define PMIC_OP_REG_SEL_1_2_6 (0x38 << 0) /* 1.2625 V */
++
++/* Device control register . (DEVCTRL_REG) */
++#define PMIC_DEVCTRL_REG_SR_CTL_I2C_MASK (0x1 << 4)
++#define PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_SR_I2C (0x0 << 4)
++#define PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C (0x1 << 4)
++
++#endif
+diff --git a/board/ti/am335x/tps65217.h b/board/ti/am335x/tps65217.h
+new file mode 100644
+index 0000000..ab3ab80
+--- /dev/null
++++ b/board/ti/am335x/tps65217.h
+@@ -0,0 +1,89 @@
++/*
++ * (C) Copyright 2011
++ * Texas Instruments, <www.ti.com>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __TPS65217_H__
++#define __TPS65217_H__
++
++#include <common.h>
++#include <i2c.h>
++
++/* I2C chip address */
++#define TPS65217_CHIP_PM 0x24
++
++/* Registers */
++#define CHIPID 0x00
++#define POWER_PATH 0x01
++#define INTERRUPT 0x02
++#define CHGCONFIG0 0x03
++#define CHGCONFIG1 0x04
++#define CHGCONFIG2 0x05
++#define CHGCONFIG3 0x06
++#define WLEDCTRL1 0x07
++#define WLEDCTRL2 0x08
++#define MUXCTRL 0x09
++#define STATUS 0x0A
++#define PASSWORD 0x0B
++#define PGOOD 0x0C
++#define DEFPG 0x0D
++#define DEFDCDC1 0x0E
++#define DEFDCDC2 0x0F
++#define DEFDCDC3 0x10
++#define DEFSLEW 0x11
++#define DEFLDO1 0x12
++#define DEFLDO2 0x13
++#define DEFLS1 0x14
++#define DEFLS2 0x15
++#define ENABLE 0x16
++#define DEFUVLO 0x18
++#define SEQ1 0x19
++#define SEQ2 0x1A
++#define SEQ3 0x1B
++#define SEQ4 0x1C
++#define SEQ5 0x1D
++#define SEQ6 0x1E
++
++#define PROT_LEVEL_NONE 0x00
++#define PROT_LEVEL_1 0x01
++#define PROT_LEVEL_2 0x02
++
++#define PASSWORD_LOCK_FOR_WRITE 0x00
++#define PASSWORD_UNLOCK 0x7D
++
++#define DCDC_GO 0x80
++
++#define MASK_ALL_BITS 0xFF
++
++#define USB_INPUT_CUR_LIMIT_MASK 0x03
++#define USB_INPUT_CUR_LIMIT_100MA 0x00
++#define USB_INPUT_CUR_LIMIT_500MA 0x01
++#define USB_INPUT_CUR_LIMIT_1300MA 0x02
++#define USB_INPUT_CUR_LIMIT_1800MA 0x03
++
++#define DCDC_VOLT_SEL_1275MV 0x0F
++
++#define LDO_MASK 0x1F
++#define LDO_VOLTAGE_OUT_3_3 0x1F
++
++#define PWR_SRC_USB_BITMASK 0x4
++#define PWR_SRC_AC_BITMASK 0x8
++#endif
+diff --git a/board/ti/ti8148/Makefile b/board/ti/ti8148/Makefile
+new file mode 100644
+index 0000000..187adc5
+--- /dev/null
++++ b/board/ti/ti8148/Makefile
+@@ -0,0 +1,43 @@
++#
++# Copyright (C) 2009, Texas Instruments, Incorporated
++#
++# 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 version 2.
++#
++# This program is distributed "as is" WITHOUT ANY WARRANTY of any
++# kind, whether express or implied; without even the implied warranty
++# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS := evm.o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++clean:
++ rm -f $(OBJS)
++
++distclean: clean
++ rm -f $(LIB) core *.bak $(obj).depend
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
++
+diff --git a/board/ti/ti8148/evm.c b/board/ti/ti8148/evm.c
+new file mode 100644
+index 0000000..981d01c
+--- /dev/null
++++ b/board/ti/ti8148/evm.c
+@@ -0,0 +1,954 @@
++/*
++ * Copyright (C) 2009, Texas Instruments, Incorporated
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <common.h>
++#include <asm/cache.h>
++#include <asm/arch/clock.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/ddr_defs.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/sys_proto.h>
++#include <asm/arch/mem.h>
++#include <asm/arch/nand.h>
++#include <linux/mtd/nand.h>
++#include <nand.h>
++#include <net.h>
++#include <miiphy.h>
++#include <netdev.h>
++#include "mux.h"
++
++#define __raw_readl(a) (*(volatile unsigned int *)(a))
++#define __raw_writel(v, a) (*(volatile unsigned int *)(a) = (v))
++#define __raw_readw(a) (*(volatile unsigned short *)(a))
++#define __raw_writew(v, a) (*(volatile unsigned short *)(a) = (v))
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#ifdef CONFIG_SPL_BUILD
++static void pll_config(u32, u32, u32, u32, u32);
++#if 0
++static void pcie_pll_config(void);
++#endif
++static void audio_pll_config(void);
++static void sata_pll_config(void);
++static void modena_pll_config(void);
++static void l3_pll_config(void);
++static void ddr_pll_config(void);
++static void dsp_pll_config(void);
++static void iss_pll_config(void);
++static void iva_pll_config(void);
++static void usb_pll_config(void);
++#endif
++
++int dram_init(void)
++{
++ gd->ram_size = PHYS_DRAM_1_SIZE + PHYS_DRAM_2_SIZE;
++
++ return 0;
++}
++
++void dram_init_banksize (void)
++{
++ /* Fill up board info */
++ gd->bd->bi_dram[0].start = PHYS_DRAM_1;
++ gd->bd->bi_dram[0].size = PHYS_DRAM_1_SIZE;
++
++ gd->bd->bi_dram[1].start = PHYS_DRAM_2;
++ gd->bd->bi_dram[1].size = PHYS_DRAM_2_SIZE;
++}
++
++/*
++ * spinning delay to use before udelay works
++ */
++static inline void delay(unsigned long loops)
++{
++ __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
++ "bne 1b" : "=r" (loops) : "0"(loops));
++}
++
++/*
++ * Basic board specific setup
++ */
++int board_init(void)
++{
++#ifdef CONFIG_DRIVER_TI_CPSW
++ if (PG2_1 == get_cpu_rev()) {
++ /* setup RMII_REFCLK to be sourced from audio_pll */
++ __raw_writel(0x4,RMII_REFCLK_SRC);
++ /*program GMII_SEL register for RGMII mode */
++ __raw_writel(0x30a,GMII_SEL);
++ }
++#endif
++
++ /* mach type passed to kernel */
++ gd->bd->bi_arch_number = MACH_TYPE_TI8148EVM;
++
++ /* address of boot parameters */
++ gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
++ gpmc_init();
++ return 0;
++}
++
++#ifdef CONFIG_SPL_BUILD
++static void config_ti814x_ddr(void)
++{
++ __raw_writel(0x2, CM_DEFAULT_FW_CLKCTRL); /*Enable the Power Domain Transition of L3 Fast Domain Peripheral*/
++ __raw_writel(0x2, CM_DEFAULT_L3_FAST_CLKSTCTRL); /*Enable the Power Domain Transition of L3 Fast Domain Peripheral*/
++ __raw_writel(0x2, CM_DEFAULT_EMIF_0_CLKCTRL); /*Enable EMIF0 Clock*/
++ __raw_writel(0x2, CM_DEFAULT_EMIF_1_CLKCTRL); /*Enable EMIF1 Clock*/
++ __raw_writel(0x2, CM_DEFAULT_DMM_CLKCTRL);
++
++ while((__raw_readl(CM_DEFAULT_L3_FAST_CLKSTCTRL) & 0x300) != 0x300); /*Poll for L3_FAST_GCLK & DDR_GCLK are active*/
++ while((__raw_readl(CM_DEFAULT_EMIF_0_CLKCTRL)) != 0x2); /*Poll for Module is functional*/
++ while((__raw_readl(CM_DEFAULT_EMIF_1_CLKCTRL)) != 0x2); /*Poll for Module is functional*/
++ while((__raw_readl(CM_DEFAULT_DMM_CLKCTRL)) != 0x2); /*Poll for Module is functional*/
++
++ __raw_writel(__raw_readl(VTP0_CTRL_REG) | 0x00000040 , VTP0_CTRL_REG);
++ __raw_writel(__raw_readl(VTP1_CTRL_REG) | 0x00000040 , VTP1_CTRL_REG);
++
++ // Write 0 to CLRZ bit
++ __raw_writel(__raw_readl(VTP0_CTRL_REG) & 0xfffffffe , VTP0_CTRL_REG);
++ __raw_writel(__raw_readl(VTP1_CTRL_REG) & 0xfffffffe , VTP1_CTRL_REG);
++
++ // Write 1 to CLRZ bit
++ __raw_writel(__raw_readl(VTP0_CTRL_REG) | 0x00000001 , VTP0_CTRL_REG);
++ __raw_writel(__raw_readl(VTP1_CTRL_REG) | 0x00000001 , VTP1_CTRL_REG);
++
++ // Read VTP control registers & check READY bits
++ while( (__raw_readl(VTP0_CTRL_REG) & 0x00000020) != 0x20);
++ while( (__raw_readl(VTP1_CTRL_REG) & 0x00000020) != 0x20);
++
++ /*Program the DMM to Access EMIF0 and EMIF1*/
++ __raw_writel(0x80440300, DMM_LISA_MAP__0);
++ __raw_writel(0x90440300, DMM_LISA_MAP__1);
++ __raw_writel(0xa0440308, DMM_LISA_MAP__2);
++ __raw_writel(0xb0440308, DMM_LISA_MAP__3);
++
++ while(__raw_readl(DMM_LISA_MAP__0)!=0x80440300);
++ while(__raw_readl(DMM_LISA_MAP__1)!=0x90440300);
++ while(__raw_readl(DMM_LISA_MAP__2)!=0xa0440308);
++ while(__raw_readl(DMM_LISA_MAP__3)!=0xb0440308);
++
++ __raw_writel(0x80000000, DMM_PAT_BASE_ADDR);
++
++ /*Program EMIF0 CFG Registers*/
++ __raw_writel(0x7, EMIF4_0_DDR_PHY_CTRL_1);//RL =5
++ __raw_writel(0x7, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);//RL =5
++ __raw_writel(0x0AAAF552, EMIF4_0_SDRAM_TIM_1);
++ __raw_writel(0x0AAAF552, EMIF4_0_SDRAM_TIM_1_SHADOW);
++ __raw_writel(0x043631D2, EMIF4_0_SDRAM_TIM_2);
++ __raw_writel(0x043631D2, EMIF4_0_SDRAM_TIM_2_SHADOW);
++ __raw_writel(0x00000327, EMIF4_0_SDRAM_TIM_3);
++ __raw_writel(0x00000327, EMIF4_0_SDRAM_TIM_3_SHADOW);
++ __raw_writel(0x10000C30, EMIF4_0_SDRAM_REF_CTRL);
++ __raw_writel(0x10000C30, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
++ __raw_writel(0x40801AB2, EMIF4_0_SDRAM_CONFIG);// CL = 6
++
++ /*Program EMIF1 CFG Registers*/
++ __raw_writel(0x7, EMIF4_1_DDR_PHY_CTRL_1);
++ __raw_writel(0x7, EMIF4_1_DDR_PHY_CTRL_1_SHADOW);
++ __raw_writel(0x0AAAF552, EMIF4_1_SDRAM_TIM_1);
++ __raw_writel(0x0AAAF552, EMIF4_1_SDRAM_TIM_1_SHADOW);
++ __raw_writel(0x043631D2, EMIF4_1_SDRAM_TIM_2);
++ __raw_writel(0x043631D2, EMIF4_1_SDRAM_TIM_2_SHADOW);
++ __raw_writel(0x00000327, EMIF4_1_SDRAM_TIM_3);
++ __raw_writel(0x00000327, EMIF4_1_SDRAM_TIM_3_SHADOW);
++ __raw_writel(0x10000C30, EMIF4_1_SDRAM_REF_CTRL);
++ __raw_writel(0x10000C30, EMIF4_1_SDRAM_REF_CTRL_SHADOW);
++ __raw_writel(0x40801AB2, EMIF4_1_SDRAM_CONFIG);// CL = 6
++
++
++}
++
++static void audio_pll_config()
++{
++ u32 audio_osc_src, rd_osc_src = 0;
++
++ audio_osc_src = AUDIO_OSC_SRC;
++ rd_osc_src = __raw_readl(OSC_SRC_CTRL);
++
++ if(OSC_SRC0 == audio_osc_src)
++ __raw_writel((rd_osc_src & 0xfeffffff)|0x0, OSC_SRC_CTRL);
++ else
++ __raw_writel((rd_osc_src & 0xfeffffff)|0x01000000, OSC_SRC_CTRL);
++
++ pll_config(AUDIO_PLL_BASE,
++ AUDIO_N, AUDIO_M,
++ AUDIO_M2, AUDIO_CLKCTRL);
++}
++
++#if 0
++static void pcie_pll_config()
++{
++ /* Powerdown both reclkp/n single ended receiver */
++ __raw_writel(0x00000002, SERDES_REFCLK_CTRL);
++
++ __raw_writel(0x00000000, PCIE_PLLCFG0);
++
++ /* PCIe(2.5GHz) mode, 100MHz refclk, MDIVINT = 25, disable (50,100,125M) clks */
++ __raw_writel(0x00640000, PCIE_PLLCFG1);
++
++ /* SSC Mantissa and exponent = 0 */
++ __raw_writel(0x00000000, PCIE_PLLCFG2);
++
++ /* TBD */
++ __raw_writel(0x004008E0, PCIE_PLLCFG3);
++
++ /* TBD */
++ __raw_writel(0x0000609C, PCIE_PLLCFG4);
++
++ /* pcie_serdes_cfg_misc */
++ /* TODO: verify the address over here (CTRL_BASE + 0x6FC = 0x481406FC ???)*/
++ //__raw_writel(0x00000E7B, 0x48141318);
++ delay(3);
++
++ /* Enable PLL LDO */
++ __raw_writel(0x00000004, PCIE_PLLCFG0);
++ delay(3);
++
++ /* Enable DIG LDO, PLL LD0 */
++ __raw_writel(0x00000014, PCIE_PLLCFG0);
++ delay(3);
++
++ /* Enable DIG LDO, ENBGSC_REF, PLL LDO */
++ __raw_writel(0x00000016, PCIE_PLLCFG0);
++ delay(3);
++ __raw_writel(0x30000016, PCIE_PLLCFG0);
++ delay(3);
++ __raw_writel(0x70000016, PCIE_PLLCFG0);
++ delay(3);
++
++ /* Enable DIG LDO, SELSC, ENBGSC_REF, PLL LDO */
++ __raw_writel(0x70000017, PCIE_PLLCFG0);
++ delay(3);
++
++ /* wait for ADPLL lock */
++ while(__raw_readl(PCIE_PLLSTATUS) != 0x1);
++
++}
++#endif
++
++static void sata_pll_config()
++{
++ __raw_writel(0xC12C003C, SATA_PLLCFG1);
++ __raw_writel(0x004008E0, SATA_PLLCFG3);
++ delay(0xFFFF);
++
++ __raw_writel(0x80000004, SATA_PLLCFG0);
++ delay(0xFFFF);
++
++ /* Enable PLL LDO */
++ __raw_writel(0x80000014, SATA_PLLCFG0);
++ delay(0xFFFF);
++
++ /* Enable DIG LDO, ENBGSC_REF, PLL LDO */
++ __raw_writel(0x80000016, SATA_PLLCFG0);
++ delay(0xFFFF);
++
++ __raw_writel(0xC0000017, SATA_PLLCFG0);
++ delay(0xFFFF);
++
++ /* wait for ADPLL lock */
++ while(((__raw_readl(SATA_PLLSTATUS) & 0x01) == 0x0));
++
++}
++
++static void usb_pll_config()
++{
++ pll_config(USB_PLL_BASE,
++ USB_N, USB_M,
++ USB_M2, USB_CLKCTRL);
++}
++
++static void modena_pll_config()
++{
++ pll_config(MODENA_PLL_BASE,
++ MODENA_N, MODENA_M,
++ MODENA_M2, MODENA_CLKCTRL);
++}
++
++static void l3_pll_config()
++{
++ u32 l3_osc_src, rd_osc_src = 0;
++
++ l3_osc_src = L3_OSC_SRC;
++ rd_osc_src = __raw_readl(OSC_SRC_CTRL);
++
++ if(OSC_SRC0 == l3_osc_src)
++ __raw_writel((rd_osc_src & 0xfffffffe)|0x0, OSC_SRC_CTRL);
++ else
++ __raw_writel((rd_osc_src & 0xfffffffe)|0x1, OSC_SRC_CTRL);
++
++ pll_config(L3_PLL_BASE,
++ L3_N, L3_M,
++ L3_M2, L3_CLKCTRL);
++}
++
++static void ddr_pll_config()
++{
++ pll_config(DDR_PLL_BASE,
++ DDR_N, DDR_M,
++ DDR_M2, DDR_CLKCTRL);
++}
++
++static void dsp_pll_config()
++{
++ pll_config(DSP_PLL_BASE,
++ DSP_N, DSP_M,
++ DSP_M2, DSP_CLKCTRL);
++}
++
++static void iss_pll_config()
++{
++ pll_config(ISS_PLL_BASE,
++ ISS_N, ISS_M,
++ ISS_M2, ISS_CLKCTRL);
++}
++
++static void iva_pll_config()
++{
++ pll_config(IVA_PLL_BASE,
++ IVA_N, IVA_M,
++ IVA_M2, IVA_CLKCTRL);
++}
++
++/*
++ * configure individual ADPLLJ
++ */
++static void pll_config(u32 base, u32 n, u32 m, u32 m2, u32 clkctrl_val)
++{
++ u32 m2nval, mn2val, read_clkctrl = 0;
++
++ m2nval = (m2 << 16) | n;
++ mn2val = m;
++
++ /*
++ * ref_clk = 20/(n + 1);
++ * clkout_dco = ref_clk * m;
++ * clk_out = clkout_dco/m2;
++ */
++
++ __raw_writel(m2nval, (base + ADPLLJ_M2NDIV));
++ __raw_writel(mn2val, (base + ADPLLJ_MN2DIV));
++
++ /* Load M2, N2 dividers of ADPLL */
++ __raw_writel(0x1, (base + ADPLLJ_TENABLEDIV));
++ __raw_writel(0x0, (base + ADPLLJ_TENABLEDIV));
++
++ /* Loda M, N dividers of ADPLL */
++ __raw_writel(0x1, (base + ADPLLJ_TENABLE));
++ __raw_writel(0x0, (base + ADPLLJ_TENABLE));
++
++ read_clkctrl = __raw_readl(base + ADPLLJ_CLKCTRL);
++
++ if (MODENA_PLL_BASE == base)
++ __raw_writel((read_clkctrl & 0xff7fffff) | clkctrl_val,
++ base + ADPLLJ_CLKCTRL);
++ else
++ __raw_writel((read_clkctrl & 0xff7fe3ff) | clkctrl_val,
++ base + ADPLLJ_CLKCTRL);
++
++
++ /* Wait for phase and freq lock */
++ while((__raw_readl(base + ADPLLJ_STATUS) & 0x00000600) != 0x00000600);
++
++}
++#endif
++
++/*
++ * Enable the clks & power for perifs (TIMER1, UART0,...)
++ */
++void per_clocks_enable(void)
++{
++ u32 temp;
++
++ __raw_writel(0x2, CM_ALWON_L3_SLOW_CLKSTCTRL);
++
++ /* TODO: No module level enable as in ti8148 ??? */
++#if 0
++ /* TIMER 1 */
++ __raw_writel(0x2, CM_ALWON_TIMER_1_CLKCTRL);
++#endif
++ /* Selects OSC0 (20MHz) for DMTIMER1 */
++ temp = __raw_readl(DMTIMER_CLKSRC);
++ temp &= ~(0x7 << 3);
++ temp |= (0x4 << 3);
++ __raw_writel(temp, DMTIMER_CLKSRC);
++
++#if 0
++ while(((__raw_readl(CM_ALWON_L3_SLOW_CLKSTCTRL) & (0x80000<<1)) >> (19+1)) != 1);
++ while(((__raw_readl(CM_ALWON_TIMER_1_CLKCTRL) & 0x30000)>>16) !=0);
++#endif
++ __raw_writel(0x2,(DM_TIMER1_BASE + 0x54));
++ while(__raw_readl(DM_TIMER1_BASE + 0x10) & 1);
++
++ __raw_writel(0x1,(DM_TIMER1_BASE + 0x38));
++
++ /* UARTs */
++ __raw_writel(0x2, CM_ALWON_UART_0_CLKCTRL);
++ while(__raw_readl(CM_ALWON_UART_0_CLKCTRL) != 0x2);
++
++ __raw_writel(0x2, CM_ALWON_UART_1_CLKCTRL);
++ while(__raw_readl(CM_ALWON_UART_1_CLKCTRL) != 0x2);
++
++ __raw_writel(0x2, CM_ALWON_UART_2_CLKCTRL);
++ while(__raw_readl(CM_ALWON_UART_2_CLKCTRL) != 0x2);
++
++ while((__raw_readl(CM_ALWON_L3_SLOW_CLKSTCTRL) & 0x2100) != 0x2100);
++
++ /* SPI */
++ __raw_writel(0x2, CM_ALWON_SPI_CLKCTRL);
++ while(__raw_readl(CM_ALWON_SPI_CLKCTRL) != 0x2);
++
++ /* I2C0 and I2C2 */
++ __raw_writel(0x2, CM_ALWON_I2C_0_CLKCTRL);
++ while(__raw_readl(CM_ALWON_I2C_0_CLKCTRL) != 0x2);
++
++ /* Ethernet */
++ __raw_writel(0x2, CM_ETHERNET_CLKSTCTRL);
++ __raw_writel(0x2, CM_ALWON_ETHERNET_0_CLKCTRL);
++ while((__raw_readl(CM_ALWON_ETHERNET_0_CLKCTRL) & 0x30000) != 0);
++ __raw_writel(0x2, CM_ALWON_ETHERNET_1_CLKCTRL);
++ /* HSMMC */
++ __raw_writel(0x2, CM_ALWON_HSMMC_CLKCTRL);
++ while(__raw_readl(CM_ALWON_HSMMC_CLKCTRL) != 0x2);
++
++
++}
++
++/*
++ * inits clocks for PRCM as defined in clocks.h
++ */
++void prcm_init(void)
++{
++ /* Enable the control module */
++ __raw_writel(0x2, CM_ALWON_CONTROL_CLKCTRL);
++
++#ifdef CONFIG_SPL_BUILD
++ /* Setup the various plls */
++ audio_pll_config();
++ sata_pll_config();
++// pcie_pll_config();
++ modena_pll_config();
++ l3_pll_config();
++ ddr_pll_config();
++ dsp_pll_config();
++ iva_pll_config();
++ iss_pll_config();
++
++ usb_pll_config();
++
++ /* With clk freqs setup to desired values, enable the required peripherals */
++ per_clocks_enable();
++#endif
++}
++
++#define PADCTRL_BASE 0x48140000
++
++#define PAD204_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B2c))
++#define PAD205_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B30))
++#define PAD206_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B34))
++#define PAD207_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B38))
++#define PAD208_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B3c))
++#define PAD209_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B40))
++#define PAD210_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B44))
++#define PAD211_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B48))
++#define PAD212_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B4c))
++#define PAD213_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B50))
++#define PAD214_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B54))
++#define PAD215_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B58))
++#define PAD216_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B5c))
++#define PAD217_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B60))
++#define PAD218_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B64))
++#define PAD219_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B68))
++#define PAD220_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B6c))
++#define PAD221_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B70))
++#define PAD222_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B74))
++#define PAD223_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B78))
++#define PAD224_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B7c))
++#define PAD225_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B80))
++#define PAD226_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B84))
++#define PAD227_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B88))
++
++#define PAD232_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B9C))
++#define PAD233_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BA0))
++#define PAD234_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BA4))
++#define PAD235_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BA8))
++#define PAD236_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BAC))
++#define PAD237_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BB0))
++#define PAD238_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BB4))
++#define PAD239_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BB8))
++#define PAD240_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BBC))
++#define PAD241_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BC0))
++#define PAD242_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BC4))
++#define PAD243_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BC8))
++#define PAD244_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BCC))
++#define PAD245_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BD0))
++#define PAD246_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BD4))
++#define PAD247_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BD8))
++#define PAD248_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BDC))
++#define PAD249_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BE0))
++#define PAD250_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BE4))
++#define PAD251_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BE8))
++#define PAD252_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BEC))
++#define PAD253_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BF0))
++#define PAD254_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BF4))
++#define PAD255_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BF8))
++#define PAD256_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BFC))
++#define PAD257_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0C00))
++#define PAD258_CNTRL (*(volatile unsigned int *)(PADCTRL_BASE + 0x0C04))
++
++#ifdef CONFIG_DRIVER_TI_CPSW
++static void cpsw_pad_config(void)
++{
++ volatile u32 val = 0;
++
++ /*configure pin mux for rmii_refclk,mdio_clk,mdio_d */
++ val = PAD232_CNTRL;
++ PAD232_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD233_CNTRL;
++ PAD233_CNTRL = (volatile unsigned int) (BIT(19) | BIT(17) | BIT(0));
++ val = PAD234_CNTRL;
++ PAD234_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(17) |
++ BIT(0));
++
++ /*For PG1.0 we only support GMII Mode, setup gmii0/gmii1 pins here*/
++ if (PG1_0 == get_cpu_rev()) {
++ /* setup gmii0 pins, pins235-258 in function mode 1 */
++ val = PAD235_CNTRL;
++ PAD235_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(0));
++ val = PAD236_CNTRL;
++ PAD236_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(0));
++ val = PAD237_CNTRL;
++ PAD237_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(0));
++ val = PAD238_CNTRL;
++ PAD238_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(0));
++ val = PAD239_CNTRL;
++ PAD239_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(0));
++ val = PAD240_CNTRL;
++ PAD240_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD241_CNTRL;
++ PAD241_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD242_CNTRL;
++ PAD242_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD243_CNTRL;
++ PAD243_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD244_CNTRL;
++ PAD244_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD245_CNTRL;
++ PAD245_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD246_CNTRL;
++ PAD246_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD247_CNTRL;
++ PAD247_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD248_CNTRL;
++ PAD248_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD249_CNTRL;
++ PAD249_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD250_CNTRL;
++ PAD250_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD251_CNTRL;
++ PAD251_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD252_CNTRL;
++ PAD252_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD253_CNTRL;
++ PAD253_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD254_CNTRL;
++ PAD254_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD255_CNTRL;
++ PAD255_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD256_CNTRL;
++ PAD256_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD257_CNTRL;
++ PAD257_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD258_CNTRL;
++ PAD258_CNTRL = (volatile unsigned int) (BIT(0));
++
++ /* setup gmii1 pins, pins204-227 in function mode 2 */
++ val = PAD204_CNTRL;
++ PAD204_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(1));
++ val = PAD205_CNTRL;
++ PAD205_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(1));
++ val = PAD206_CNTRL;
++ PAD206_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(1));
++ val = PAD207_CNTRL;
++ PAD207_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(1));
++ val = PAD208_CNTRL;
++ PAD208_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(1));
++ val = PAD209_CNTRL;
++ PAD209_CNTRL = (volatile unsigned int) (BIT(18) | BIT(1));
++ val = PAD210_CNTRL;
++ PAD210_CNTRL = (volatile unsigned int) (BIT(18) | BIT(1));
++ val = PAD211_CNTRL;
++ PAD211_CNTRL = (volatile unsigned int) (BIT(18) | BIT(1));
++ val = PAD212_CNTRL;
++ PAD212_CNTRL = (volatile unsigned int) (BIT(18) | BIT(1));
++ val = PAD213_CNTRL;
++ PAD213_CNTRL = (volatile unsigned int) (BIT(18) | BIT(1));
++ val = PAD214_CNTRL;
++ PAD214_CNTRL = (volatile unsigned int) (BIT(18) | BIT(1));
++ val = PAD215_CNTRL;
++ PAD215_CNTRL = (volatile unsigned int) (BIT(18) | BIT(1));
++ val = PAD216_CNTRL;
++ PAD216_CNTRL = (volatile unsigned int) (BIT(18) | BIT(1));
++ val = PAD217_CNTRL;
++ PAD217_CNTRL = (volatile unsigned int) (BIT(18) | BIT(1));
++ val = PAD218_CNTRL;
++ PAD218_CNTRL = (volatile unsigned int) (BIT(1));
++ val = PAD219_CNTRL;
++ PAD219_CNTRL = (volatile unsigned int) (BIT(1));
++ val = PAD220_CNTRL;
++ PAD220_CNTRL = (volatile unsigned int) (BIT(1));
++ val = PAD221_CNTRL;
++ PAD221_CNTRL = (volatile unsigned int) (BIT(1));
++ val = PAD222_CNTRL;
++ PAD222_CNTRL = (volatile unsigned int) (BIT(1));
++ val = PAD223_CNTRL;
++ PAD223_CNTRL = (volatile unsigned int) (BIT(1));
++ val = PAD224_CNTRL;
++ PAD224_CNTRL = (volatile unsigned int) (BIT(1));
++ val = PAD225_CNTRL;
++ PAD225_CNTRL = (volatile unsigned int) (BIT(1));
++ val = PAD226_CNTRL;
++ PAD226_CNTRL = (volatile unsigned int) (BIT(1));
++ val = PAD227_CNTRL;
++ PAD227_CNTRL = (volatile unsigned int) (BIT(1));
++
++ } else {/*setup rgmii0/rgmii1 pins here*/
++ /* In this case we enable rgmii_en bit in GMII_SEL register and
++ * still program the pins in gmii mode: gmii0 pins in mode 1*/
++ val = PAD235_CNTRL; /*rgmii0_rxc*/
++ PAD235_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD236_CNTRL; /*rgmii0_rxctl*/
++ PAD236_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD237_CNTRL; /*rgmii0_rxd[2]*/
++ PAD237_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD238_CNTRL; /*rgmii0_txctl*/
++ PAD238_CNTRL = (volatile unsigned int) BIT(0);
++ val = PAD239_CNTRL; /*rgmii0_txc*/
++ PAD239_CNTRL = (volatile unsigned int) BIT(0);
++ val = PAD240_CNTRL; /*rgmii0_txd[0]*/
++ PAD240_CNTRL = (volatile unsigned int) BIT(0);
++ val = PAD241_CNTRL; /*rgmii0_rxd[0]*/
++ PAD241_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD242_CNTRL; /*rgmii0_rxd[1]*/
++ PAD242_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD243_CNTRL; /*rgmii1_rxctl*/
++ PAD243_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD244_CNTRL; /*rgmii0_rxd[3]*/
++ PAD244_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD245_CNTRL; /*rgmii0_txd[3]*/
++ PAD245_CNTRL = (volatile unsigned int) BIT(0);
++ val = PAD246_CNTRL; /*rgmii0_txd[2]*/
++ PAD246_CNTRL = (volatile unsigned int) BIT(0);
++ val = PAD247_CNTRL; /*rgmii0_txd[1]*/
++ PAD247_CNTRL = (volatile unsigned int) BIT(0);
++ val = PAD248_CNTRL; /*rgmii1_rxd[1]*/
++ PAD248_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD249_CNTRL; /*rgmii1_rxc*/
++ PAD249_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD250_CNTRL; /*rgmii1_rxd[3]*/
++ PAD250_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD251_CNTRL; /*rgmii1_txd[1]*/
++ PAD251_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD252_CNTRL; /*rgmii1_txctl*/
++ PAD252_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD253_CNTRL; /*rgmii1_txd[0]*/
++ PAD253_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD254_CNTRL; /*rgmii1_txd[2]*/
++ PAD254_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD255_CNTRL; /*rgmii1_txc*/
++ PAD255_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD256_CNTRL; /*rgmii1_rxd[0]*/
++ PAD256_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ val = PAD257_CNTRL; /*rgmii1_txd[3]*/
++ PAD257_CNTRL = (volatile unsigned int) (BIT(0));
++ val = PAD258_CNTRL; /*rgmii1_rxd[2]*/
++ PAD258_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
++ }
++}
++#endif
++
++/*
++ * baord specific muxing of pins
++ */
++void set_muxconf_regs(void)
++{
++ u32 i, add, val;
++
++ for (i = 0; i<N_PINS; i++)
++ {
++ add = PIN_CTRL_BASE + (i*4);
++ val = __raw_readl(add);
++ val |= pad_conf[i];
++ __raw_writel(val, add);
++ }
++ /* MMC/SD pull-down enable */
++ __raw_writel(0x000C0040, 0x48140928);
++}
++
++static void unlock_pll_control_mmr(void)
++{
++ /* ??? */
++ __raw_writel(0x1EDA4C3D, 0x481C5040);
++ __raw_writel(0x2FF1AC2B, 0x48140060);
++ __raw_writel(0xF757FDC0, 0x48140064);
++ __raw_writel(0xE2BC3A6D, 0x48140068);
++ __raw_writel(0x1EBF131D, 0x4814006c);
++ __raw_writel(0x6F361E05, 0x48140070);
++
++}
++
++/*
++ * early system init of muxing and clocks.
++ */
++void s_init(u32 in_ddr)
++{
++ /* TODO: Revisit enabling of I/D-cache in 1st stage */
++#if 0
++ icache_enable();
++ dcache_enable();
++#endif
++ l2_cache_enable(); /* Can be removed as A8 comes up with L2 enabled */
++ unlock_pll_control_mmr();
++ prcm_init(); /* Setup the PLLs and the clocks for the peripherals */
++
++#ifdef CONFIG_SPL_BUILD
++ /* Do the required pin-muxing before modules are setup */
++ set_muxconf_regs();
++
++ /* UART softreset */
++ {
++ u32 regVal;
++
++ regVal = __raw_readl(UART_SYSCFG);
++ regVal |= 0x2;
++ __raw_writel(regVal, UART_SYSCFG);
++ while( (__raw_readl(UART_SYSSTS) & 0x1) != 0x1);
++
++ /* Disable UART smart idle */
++ regVal = __raw_readl(UART_SYSCFG);
++ regVal |= (1<<3);
++ __raw_writel(regVal, UART_SYSCFG);
++ }
++
++ preloader_console_init();
++
++ config_ti814x_ddr(); /* Do DDR settings */
++
++ board_init();
++#endif /* CONFIG_SPL_BUILD */
++}
++
++#ifdef CONFIG_DRIVER_TI_CPSW
++
++#define PHY_CONF_REG 22
++#define PHY_CONF_TXCLKEN (1 << 5)
++
++/* TODO : Check for the board specific PHY */
++static void evm_phy_init(char *name, int addr)
++{
++ unsigned short val;
++ unsigned int cntr = 0;
++
++ miiphy_reset(name, addr);
++
++ udelay(100000);
++
++ /* Enable PHY to clock out TX_CLK */
++ miiphy_read(name, addr, PHY_CONF_REG, &val);
++ val |= PHY_CONF_TXCLKEN;
++ miiphy_write(name, addr, PHY_CONF_REG, val);
++ miiphy_read(name, addr, PHY_CONF_REG, &val);
++
++ /* Enable Autonegotiation */
++ if (miiphy_read(name, addr, MII_BMCR, &val) != 0) {
++ printf("failed to read bmcr\n");
++ return;
++ }
++ val |= BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_SPEED100;
++ if (miiphy_write(name, addr, MII_BMCR, val) != 0) {
++ printf("failed to write bmcr\n");
++ return;
++ }
++ miiphy_read(name, addr, MII_BMCR, &val);
++
++ /* Setup GIG advertisement */
++ miiphy_read(name, addr, MII_CTRL1000, &val);
++ val |= PHY_1000BTCR_1000FD;
++ val &= ~PHY_1000BTCR_1000HD;
++ miiphy_write(name, addr, MII_CTRL1000, val);
++ miiphy_read(name, addr, MII_CTRL1000, &val);
++
++ /* Setup general advertisement */
++ if (miiphy_read(name, addr, MII_ADVERTISE, &val) != 0) {
++ printf("failed to read anar\n");
++ return;
++ }
++ val |= (LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL);
++ if (miiphy_write(name, addr, MII_ADVERTISE, val) != 0) {
++ printf("failed to write anar\n");
++ return;
++ }
++ miiphy_read(name, addr, MII_ADVERTISE, &val);
++
++ /* Restart auto negotiation*/
++ miiphy_read(name, addr, MII_BMCR, &val);
++ val |= BMCR_ANRESTART;
++ miiphy_write(name, addr, MII_BMCR, val);
++
++ /*check AutoNegotiate complete - it can take upto 3 secs*/
++ do{
++ udelay(40000);
++ cntr++;
++
++ if (!miiphy_read(name, addr, MII_BMSR, &val)){
++ if(val & BMSR_ANEGCOMPLETE)
++ break;
++ }
++
++ }while(cntr < 250);
++
++ if (!miiphy_read(name, addr, MII_BMSR, &val)) {
++ if (!(val & BMSR_ANEGCOMPLETE))
++ printf("Auto negotitation failed\n");
++ }
++
++ return;
++}
++
++static void cpsw_control(int enabled)
++{
++ /* nothing for now */
++ /* TODO : VTP was here before */
++ return;
++}
++
++static struct cpsw_slave_data cpsw_slaves[] = {
++ {
++ .slave_reg_ofs = 0x50,
++ .sliver_reg_ofs = 0x700,
++ .phy_id = 1,
++ },
++ {
++ .slave_reg_ofs = 0x90,
++ .sliver_reg_ofs = 0x740,
++ .phy_id = 0,
++ },
++};
++
++static struct cpsw_platform_data cpsw_data = {
++ .mdio_base = TI814X_CPSW_MDIO_BASE,
++ .cpsw_base = TI814X_CPSW_BASE,
++ .mdio_div = 0xff,
++ .channels = 8,
++ .cpdma_reg_ofs = 0x100,
++ .slaves = 1,
++ .slave_data = cpsw_slaves,
++ .ale_reg_ofs = 0x600,
++ .ale_entries = 1024,
++ .host_port_reg_ofs = 0x28,
++ .hw_stats_reg_ofs = 0x400,
++ .mac_control = (1 << 5) /* MIIEN */,
++ .control = cpsw_control,
++ .phy_init = evm_phy_init,
++ .host_port_num = 0,
++};
++
++int board_eth_init(bd_t *bis)
++{
++ u_int8_t mac_addr[6];
++ u_int32_t mac_hi,mac_lo;
++
++ cpsw_pad_config();
++
++ if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
++ printf("<ethaddr> not set. Reading from E-fuse\n");
++ /* try reading mac address from efuse */
++ mac_lo = __raw_readl(MAC_ID0_LO);
++ mac_hi = __raw_readl(MAC_ID0_HI);
++ mac_addr[0] = mac_hi & 0xFF;
++ mac_addr[1] = (mac_hi & 0xFF00) >> 8;
++ mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
++ mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
++ mac_addr[4] = mac_lo & 0xFF;
++ mac_addr[5] = (mac_lo & 0xFF00) >> 8;
++ }
++
++ if (is_valid_ether_addr(mac_addr))
++ eth_setenv_enetaddr("ethaddr", mac_addr);
++ else
++ printf("Caution:using static MACID!! Set <ethaddr> variable\n");
++
++ if (PG1_0 != get_cpu_rev()) {
++ cpsw_slaves[0].phy_id = 0;
++ cpsw_slaves[1].phy_id = 1;
++ }
++
++ return cpsw_register(&cpsw_data);
++}
++#endif
++
++#ifndef CONFIG_SPL_BUILD
++#ifdef CONFIG_GENERIC_MMC
++int board_mmc_init(bd_t *bis)
++{
++ omap_mmc_init(0);
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_NAND_TI81XX
++/******************************************************************************
++ * Command to switch between NAND HW and SW ecc
++ *****************************************************************************/
++extern void ti81xx_nand_switch_ecc(nand_ecc_modes_t hardware, int32_t mode);
++static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
++{
++ int type = 0;
++ if (argc < 2)
++ goto usage;
++
++ if (strncmp(argv[1], "hw", 2) == 0) {
++ if (argc == 3)
++ type = simple_strtoul(argv[2], NULL, 10);
++ ti81xx_nand_switch_ecc(NAND_ECC_HW, type);
++ }
++ else if (strncmp(argv[1], "sw", 2) == 0)
++ ti81xx_nand_switch_ecc(NAND_ECC_SOFT, 0);
++ else
++ goto usage;
++
++ return 0;
++
++usage:
++ printf ("Usage: nandecc %s\n", cmdtp->usage);
++ return 1;
++}
++
++U_BOOT_CMD(
++ nandecc, 3, 1, do_switch_ecc,
++ "Switch NAND ECC calculation algorithm b/w hardware and software",
++ "[sw|hw <hw_type>] \n"
++ " [sw|hw]- Switch b/w hardware(hw) & software(sw) ecc algorithm\n"
++ " hw_type- 0 for Hamming code\n"
++ " 1 for bch4\n"
++ " 2 for bch8\n"
++ " 3 for bch16\n"
++);
++
++#endif /* CONFIG_NAND_TI81XX */
++#endif /* CONFIG_SPL_BUILD */
+diff --git a/board/ti/ti8148/mux.h b/board/ti/ti8148/mux.h
+new file mode 100644
+index 0000000..541b113
+--- /dev/null
++++ b/board/ti/ti8148/mux.h
+@@ -0,0 +1,87 @@
++/*
++ * Copyright (C) 2009, Texas Instruments, Incorporated
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++static u32 pad_conf[] = {
++/* 1-4 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -8 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -12 */ BIT(0), BIT(0), BIT(0), BIT(0),
++ /* 14 usb1_drvvbus, fn8, pulldn enable */
++/* -16 */ BIT(0), BIT(7), BIT(0), BIT(0),
++/* -20 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -24 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -28 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -32 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -36 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -40 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -44 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -48 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -52 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -56 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -60 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -64 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -68 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -72 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -76 */ BIT(0), BIT(6), BIT(6), BIT(0), /* 74 - mmc1_pow, 75 - mmc1_sdwp */
++/* -80 */ BIT(0), BIT(0), BIT(0), BIT(1), /* 80 - mmc1_sdcd */
++/* -84 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -88 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -92 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -96 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -100 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -104 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -108 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -112 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -116 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -120 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -124 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -128 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -132 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -136 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -140 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -144 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -148 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -152 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -156 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -160 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -164 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -168 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -172 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -176 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -180 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -184 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -188 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -192 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -196 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -200 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -204 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -208 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -212 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -216 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -220 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -224 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -228 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -232 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -236 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -240 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -244 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -248 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -252 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -256 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -260 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -264 */ BIT(0), BIT(0), BIT(0), BIT(0),
++/* -268 */ BIT(0), BIT(0), BIT(0), BIT(0),
++ /* 270 usb0_drvvbus, fn1, pulldn enable */
++/* -271 */ BIT(0), BIT(0), BIT(0),
++};
+diff --git a/board/ti/ti8168/Makefile b/board/ti/ti8168/Makefile
+new file mode 100644
+index 0000000..187adc5
+--- /dev/null
++++ b/board/ti/ti8168/Makefile
+@@ -0,0 +1,43 @@
++#
++# Copyright (C) 2009, Texas Instruments, Incorporated
++#
++# 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 version 2.
++#
++# This program is distributed "as is" WITHOUT ANY WARRANTY of any
++# kind, whether express or implied; without even the implied warranty
++# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS := evm.o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++clean:
++ rm -f $(OBJS)
++
++distclean: clean
++ rm -f $(LIB) core *.bak $(obj).depend
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
++
+diff --git a/board/ti/ti8168/config.mk b/board/ti/ti8168/config.mk
+new file mode 100644
+index 0000000..cb1b120
+--- /dev/null
++++ b/board/ti/ti8168/config.mk
+@@ -0,0 +1,26 @@
++#
++# Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
++#
++# See file CREDITS for list of people who contributed to this
++# project.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of the GNU General Public License as
++# published by the Free Software Foundation version 2.
++#
++# This program is distributed "as is" WITHOUT ANY WARRANTY of any
++# kind, whether express or implied; without even the implied warranty
++# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++
++# Output image name. Used only in case of non-xip. For NOR boot u-boot.bin
++# could be used.
++TI_IMAGE = u-boot.noxip.bin
++# This will be used by mkimage extension to select header for image
++TI_DEVICE = ti81xx
++# ROM code will load u-boot to this address
++TI_LOAD_ADDR = 0x40400000
++CONFIG_SYS_TEXT_BASE = 0x80700000
++# Over-ride the macros if supplied from the Makefile
++sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
+diff --git a/board/ti/ti8168/evm.c b/board/ti/ti8168/evm.c
+new file mode 100644
+index 0000000..f8ba79a
+--- /dev/null
++++ b/board/ti/ti8168/evm.c
+@@ -0,0 +1,1202 @@
++/*
++ * Copyright (C) 2009, Texas Instruments, Incorporated
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <common.h>
++#include <asm/cache.h>
++#include <asm/arch/clock.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/ddr_defs.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/sys_proto.h>
++#include <asm/arch/mem.h>
++#include <asm/arch/nand.h>
++#include <linux/mtd/nand.h>
++#include <nand.h>
++#include <net.h>
++#include <netdev.h>
++
++#define __raw_readl(a) (*(volatile unsigned int *)(a))
++#define __raw_writel(v, a) (*(volatile unsigned int *)(a) = (v))
++#define __raw_readw(a) (*(volatile unsigned short *)(a))
++#define __raw_writew(v, a) (*(volatile unsigned short *)(a) = (v))
++#define __raw_readc(a) (*(volatile char *)(a))
++#define __raw_writec(v, a) (*(volatile char *)(a) = (v))
++
++#define WR_MEM_32(a, d) (*(volatile int*)(a) = (d))
++#define RD_MEM_32(a) (*(volatile int*)(a))
++#define WR_MEM_8(a, d) (*(volatile char*)(a) = (d))
++#define RD_MEM_8(a) (*(volatile char*)(a))
++/*
++ * IEN - Input Enable
++ * IDIS - Input Disable
++ * PTD - Pull type Down
++ * PTU - Pull type Up
++ * DIS - Pull type selection is inactive
++ * EN - Pull type selection is active
++ * M0 - Mode 0
++ */
++#define IEN (1 << 8)
++
++#define IDIS (0 << 8)
++#define PTU (1 << 4)
++#define PTD (0 << 4)
++#define EN (1 << 3)
++#define DIS (0 << 3)
++
++#define M0 0
++#define M1 1
++#define M2 2
++#define M3 3
++#define M4 4
++#define M5 5
++#define M6 6
++#define M7 7
++
++DECLARE_GLOBAL_DATA_PTR;
++
++void walking_one_test(unsigned long start_addr, unsigned long end_addr);
++void data_walking_test(unsigned long addr, unsigned long mask);
++void address_walking_test(unsigned long addr, unsigned long mask);
++#ifdef CONFIG_TI816X_DDR3_SW_LEVELING
++static void ddr3_sw_levelling(int emif);
++#endif
++
++#ifdef CONFIG_TI816X_VOLT_SCALE
++#define NUM_VOLT_DATA 4
++
++struct voltage_scale_data {
++ u32 efuse_data;
++ u8 gpio_val;
++};
++
++/*
++ * TODO: Populate this table based on silicon characterization data
++ */
++static struct voltage_scale_data ti816x_volt_scale_data[NUM_VOLT_DATA] = {
++ {0, 0},
++ {0, 0},
++ {0, 0},
++ {0, 0},
++};
++
++static u8 voltage_scale_lookup(u32 efuse_data)
++{
++ int i;
++ u8 gpio_val = 0;
++
++ for (i=0; i < NUM_VOLT_DATA; i++) {
++ if (ti816x_volt_scale_data[i].efuse_data == efuse_data) {
++ gpio_val = ti816x_volt_scale_data[i].gpio_val;
++ break;
++ }
++ }
++ return gpio_val;
++}
++
++/*
++ * The routine reads the efuse register and programs the GPIO
++ * to adjust the TPS40041 core voltage.
++ * Assumptions:
++ * 1. The efuse data is programmed into TI816X_SMRT_SCALE_ADDR
++ * 2. The efuse and gpio clocks are already enabled
++ */
++static void voltage_scale_init(void)
++{
++ u32 sr_efuse_data;
++ u8 gpio_val;
++ u32 gpio_reg_val;
++
++ sr_efuse_data = __raw_readl(TI816X_SMRT_SCALE_ADDR);
++
++ gpio_val = voltage_scale_lookup(sr_efuse_data);
++ if (gpio_val != 0) {
++ gpio_val &= 0xF;
++
++ /* Enable Output on GPIO0[0:3] */
++ gpio_reg_val = __raw_readl(TI816X_GPIO0_BASE + 0x134);
++ gpio_reg_val &= 0xF;
++ __raw_writel(gpio_reg_val, TI816X_GPIO0_BASE + 0x134);
++
++ /* Clear any existing output data */
++ gpio_reg_val = __raw_readl(TI816X_GPIO0_BASE + 0x190);
++ gpio_reg_val &= 0xF;
++ __raw_writel(gpio_reg_val, TI816X_GPIO0_BASE + 0x190);
++
++ /* Program the GPIO to change the TPS40041 Voltage */
++ gpio_reg_val = __raw_readl(TI816X_GPIO0_BASE + 0x194);
++ gpio_reg_val &= gpio_val;
++ __raw_writel(gpio_reg_val, TI816X_GPIO0_BASE + 0x194);
++ }
++}
++#endif
++
++/*******************************************************
++ * Routine: delay
++ * Description: spinning delay to use before udelay works
++ ******************************************************/
++static inline void delay(unsigned long loops)
++{
++ __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
++ "bne 1b" : "=r" (loops) : "0"(loops));
++}
++
++/*
++ * Basic board specific setup
++ */
++int board_init(void)
++{
++ u32 regVal;
++
++ /* Get Timer and UART out of reset */
++
++ /* UART softreset */
++ regVal = __raw_readl(UART_SYSCFG);
++ regVal |= 0x2;
++ __raw_writel(regVal, UART_SYSCFG);
++ while( (__raw_readl(UART_SYSSTS) & 0x1) != 0x1);
++
++ /* Disable smart idle */
++ regVal = __raw_readl(UART_SYSCFG);
++ regVal |= (1<<3);
++ __raw_writel(regVal, UART_SYSCFG);
++
++ gd->bd->bi_arch_number = MACH_TYPE_TI8168EVM;
++
++ /* address of boot parameters */
++ gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
++
++ gpmc_init();
++
++ return 0;
++}
++
++#ifdef CONFIG_DRIVER_TI_EMAC
++extern void davinci_eth_set_mac_addr(const u_int8_t *addr);
++
++int board_eth_init(bd_t *bis)
++{
++ /* TODO : read MAC address from EFUSE */
++ u_int8_t mac_addr[6];
++ u_int32_t mac_hi,mac_lo;
++
++ if(!eth_getenv_enetaddr("ethaddr", mac_addr)) {
++ printf("<ethaddr> not set. Reading from E-fuse\n");
++ /* try reading mac address from efuse */
++ mac_lo = __raw_readl(MAC_ID0_LO);
++ mac_hi = __raw_readl(MAC_ID0_HI);
++ mac_addr[0] = mac_hi & 0xFF;
++ mac_addr[1] = (mac_hi & 0xFF00) >> 8;
++ mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
++ mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
++ mac_addr[4] = mac_lo & 0xFF;
++ mac_addr[5] = (mac_lo & 0xFF00) >> 8;
++ /* set the ethaddr variable with MACID detected */
++ eth_setenv_enetaddr("ethaddr", mac_addr);
++ }
++
++ if(is_valid_ether_addr(mac_addr)) {
++ printf("Detected MACID:%x:%x:%x:%x:%x:%x\n",mac_addr[0],
++ mac_addr[1], mac_addr[2], mac_addr[3],
++ mac_addr[4], mac_addr[5]);
++ davinci_eth_set_mac_addr(mac_addr);
++ } else {
++ printf("Caution:using static MACID!! Set <ethaddr> variable\n");
++ }
++
++ davinci_emac_initialize();
++ return 0;
++}
++#endif
++
++/*
++ * Configure DRAM banks
++ *
++ * Description: sets uboots idea of sdram size
++ */
++int dram_init(void)
++{
++ /* Fill up board info */
++ gd->bd->bi_dram[0].start = PHYS_DRAM_1;
++ gd->bd->bi_dram[0].size = PHYS_DRAM_1_SIZE;
++
++ gd->bd->bi_dram[1].start = PHYS_DRAM_2;
++ gd->bd->bi_dram[1].size = PHYS_DRAM_2_SIZE;
++
++ return 0;
++}
++
++/* assume delay is aprox at least 1us */
++void ddr_delay(int d)
++{ /*
++ * in interactive mode use a user response
++ * printf("Pause... Press enter to continue\n");
++ * getchar();
++ */
++ int i;
++
++ /*
++ * read a control module register.
++ * this is a bit more delay and cannot be optimized by the compiler
++ * assuming one read takes 200 cycles and A8 is runing 1 GHz
++ * somewhat conservative setting
++ */
++ for(i=0; i<50*d; i++)
++ __raw_readl(CONTROL_STATUS);
++}
++
++#ifdef CONFIG_TI816X_EVM_DDR3
++/*********************************************************************
++ * Init DDR3 on TI816X EVM
++ *********************************************************************/
++static void ddr_init_settings(int emif)
++{
++ /*
++ * DLL Lockdiff DLL_Lockdiff determines effectively is the
++ * threshold internal to the DLL to indicate that the DLL has
++ * lost lock. When this happens the PHY currently issues an
++ * internal reset. The reset value for this is 0x4, which is
++ * insufficient. Set this to 15 (maximum possible - to
++ * prevent this reset. If the reset happens it would cause
++ * the data to be corrupted.
++ */
++ if(0 == get_cpu_rev())
++ {
++ __raw_writel(0xF, DDRPHY_CONFIG_BASE + 0x028);
++ __raw_writel(0xF, DDRPHY_CONFIG_BASE + 0x05C);
++ __raw_writel(0xF, DDRPHY_CONFIG_BASE + 0x090);
++ __raw_writel(0xF, DDRPHY_CONFIG_BASE + 0x138);
++ __raw_writel(0xF, DDRPHY_CONFIG_BASE + 0x1DC);
++ __raw_writel(0xF, DDRPHY_CONFIG_BASE + 0x280);
++ __raw_writel(0xF, DDRPHY_CONFIG_BASE + 0x324);
++ }
++
++ /*
++ * setup use_rank_delays to 1. This is only necessary when
++ * multiple ranks are in use. Though the EVM does not have
++ * multiple ranks, this is a good value to set.
++ */
++ __raw_writel(1, DDRPHY_CONFIG_BASE + 0x134);
++ __raw_writel(1, DDRPHY_CONFIG_BASE + 0x1d8);
++ __raw_writel(1, DDRPHY_CONFIG_BASE + 0x27c);
++ __raw_writel(1, DDRPHY_CONFIG_BASE + 0x320);
++
++ /* see ddr_defs.h for invert clock setting and details */
++ __raw_writel(INVERT_CLOCK, DDRPHY_CONFIG_BASE + 0x02C); /* invert_clk_out cmd0 */
++ __raw_writel(INVERT_CLOCK, DDRPHY_CONFIG_BASE + 0x060); /* invert_clk_out cmd0 */
++ __raw_writel(INVERT_CLOCK, DDRPHY_CONFIG_BASE + 0x094); /* invert_clk_out cmd0 */
++
++ /* with inv clkout: 0x100. no inv clkout: 0x80. See ddr_defs.h */
++ __raw_writel(CMD_SLAVE_RATIO, DDRPHY_CONFIG_BASE + 0x01C); /* cmd0 slave ratio */
++ __raw_writel(CMD_SLAVE_RATIO, DDRPHY_CONFIG_BASE + 0x050); /* cmd1 slave ratio */
++ __raw_writel(CMD_SLAVE_RATIO, DDRPHY_CONFIG_BASE + 0x084); /* cmd2 slave ratio */
++
++ /* for ddr3 this needs to be set to 1 */
++ __raw_writel(0x1, DDRPHY_CONFIG_BASE + 0x0F8); /* init mode */
++ __raw_writel(0x1, DDRPHY_CONFIG_BASE + 0x104);
++ __raw_writel(0x1, DDRPHY_CONFIG_BASE + 0x19C);
++ __raw_writel(0x1, DDRPHY_CONFIG_BASE + 0x1A8);
++ __raw_writel(0x1, DDRPHY_CONFIG_BASE + 0x240);
++ __raw_writel(0x1, DDRPHY_CONFIG_BASE + 0x24C);
++ __raw_writel(0x1, DDRPHY_CONFIG_BASE + 0x2E4);
++ __raw_writel(0x1, DDRPHY_CONFIG_BASE + 0x2F0);
++
++ /**** setup the initial levelinihg ratios ****/
++ /* these are derived from board delays and may be different for different boards
++ * see ddr_defs.h
++ * we are setting the values here for both the ranks, though only one is in use
++ */
++ __raw_writel((WR_DQS_RATIO_3 << 10) | WR_DQS_RATIO_3, DDRPHY_CONFIG_BASE + 0x0F0); /* data0 writelvl init ratio */
++ __raw_writel(0x00000, DDRPHY_CONFIG_BASE + 0x0F4); /* */
++ __raw_writel((WR_DQS_RATIO_2 << 10) | WR_DQS_RATIO_2, DDRPHY_CONFIG_BASE + 0x194); /* data1 writelvl init ratio */
++ __raw_writel(0x00000, DDRPHY_CONFIG_BASE + 0x198); /* */
++ __raw_writel((WR_DQS_RATIO_1 << 10) | WR_DQS_RATIO_1, DDRPHY_CONFIG_BASE + 0x238); /* data2 writelvl init ratio */
++ __raw_writel(0x00000, DDRPHY_CONFIG_BASE + 0x23c); /* */
++ __raw_writel((WR_DQS_RATIO_0 << 10) | WR_DQS_RATIO_0, DDRPHY_CONFIG_BASE + 0x2dc); /* data3 writelvl init ratio */
++ __raw_writel(0x00000, DDRPHY_CONFIG_BASE + 0x2e0); /* */
++
++
++ __raw_writel((RD_GATE_RATIO_3 << 10) | RD_GATE_RATIO_3, DDRPHY_CONFIG_BASE + 0x0FC); /* data0 gatelvl init ratio */
++ __raw_writel(0x0, DDRPHY_CONFIG_BASE + 0x100);
++ __raw_writel((RD_GATE_RATIO_2 << 10) | RD_GATE_RATIO_2, DDRPHY_CONFIG_BASE + 0x1A0); /* data1 gatelvl init ratio */
++ __raw_writel(0x0, DDRPHY_CONFIG_BASE + 0x1A4);
++ __raw_writel((RD_GATE_RATIO_1 << 10) | RD_GATE_RATIO_1, DDRPHY_CONFIG_BASE + 0x244); /* data2 gatelvl init ratio */
++ __raw_writel(0x0, DDRPHY_CONFIG_BASE + 0x248);
++ __raw_writel((RD_GATE_RATIO_0 << 10) | RD_GATE_RATIO_0, DDRPHY_CONFIG_BASE + 0x2E8); /* data3 gatelvl init ratio */
++ __raw_writel(0x0, DDRPHY_CONFIG_BASE + 0x2EC);
++
++#ifdef CONFIG_TI816X_DDR3_PG_1_0
++ if(HACK_EYE_TRAINING){
++ __raw_writel((RD_DQS_FORCE_3 << 9) | RD_DQS_FORCE_3, DDRPHY_CONFIG_BASE + 0x0D4);
++ __raw_writel(0x00000001, DDRPHY_CONFIG_BASE + 0x0D0);
++
++ __raw_writel((RD_DQS_FORCE_2 << 9) | RD_DQS_FORCE_2, DDRPHY_CONFIG_BASE + 0x178);
++ __raw_writel(0x00000001, DDRPHY_CONFIG_BASE + 0x174);
++
++ __raw_writel((RD_DQS_FORCE_1 << 9) | RD_DQS_FORCE_1, DDRPHY_CONFIG_BASE + 0x21C);
++ __raw_writel(0x00000001, DDRPHY_CONFIG_BASE + 0x218);
++
++ /* rd dqs - lane 0 */
++ __raw_writel((RD_DQS_FORCE_0 << 9) | RD_DQS_FORCE_0, DDRPHY_CONFIG_BASE + 0x2C0);
++ __raw_writel(0x00000001, DDRPHY_CONFIG_BASE + 0x2BC);
++ }
++ /* DDR3 */
++#endif
++
++ __raw_writel(0x5, DDRPHY_CONFIG_BASE + 0x00C); /* cmd0 io config - output impedance of pad */
++ __raw_writel(0x5, DDRPHY_CONFIG_BASE + 0x010); /* cmd0 io clk config - output impedance of pad */
++ __raw_writel(0x5, DDRPHY_CONFIG_BASE + 0x040); /* cmd1 io config - output impedance of pad */
++ __raw_writel(0x5, DDRPHY_CONFIG_BASE + 0x044); /* cmd1 io clk config - output impedance of pad */
++ __raw_writel(0x5, DDRPHY_CONFIG_BASE + 0x074); /* cmd2 io config - output impedance of pad */
++ __raw_writel(0x5, DDRPHY_CONFIG_BASE + 0x078); /* cmd2 io clk config - output impedance of pad */
++ __raw_writel(0x4, DDRPHY_CONFIG_BASE + 0x0A8); /* data0 io config - output impedance of pad */
++ __raw_writel(0x4, DDRPHY_CONFIG_BASE + 0x0AC); /* data0 io clk config - output impedance of pad */
++ __raw_writel(0x4, DDRPHY_CONFIG_BASE + 0x14C); /* data1 io config - output impedance of pa */
++ __raw_writel(0x4, DDRPHY_CONFIG_BASE + 0x150); /* data1 io clk config - output impedance of pad */
++ __raw_writel(0x4, DDRPHY_CONFIG_BASE + 0x1F0); /* data2 io config - output impedance of pa */
++ __raw_writel(0x4, DDRPHY_CONFIG_BASE + 0x1F4); /* data2 io clk config - output impedance of pad */
++ __raw_writel(0x4, DDRPHY_CONFIG_BASE + 0x294); /* data3 io config - output impedance of pa */
++ __raw_writel(0x4, DDRPHY_CONFIG_BASE + 0x298); /* data3 io clk config - output impedance of pad */
++
++ if(0 == get_cpu_rev())
++ {
++ __raw_writel(0x5, DDRPHY_CONFIG_BASE + 0x338); /* fifo_we_out0 - output impedance of pad */
++ __raw_writel(0x5, DDRPHY_CONFIG_BASE + 0x340); /* fifo_we_out1 - output impedance of pad */
++ __raw_writel(0x5, DDRPHY_CONFIG_BASE + 0x348); /* fifo_we_in2 - output impedance of pad */
++ __raw_writel(0x5, DDRPHY_CONFIG_BASE + 0x350); /* fifo_we_in3 - output impedance of pad */
++ }
++}
++
++static void emif4p_init(u32 TIM1, u32 TIM2, u32 TIM3, u32 SDREF, u32 SDCFG, u32 RL)
++{
++ if(USE_EMIF0){
++ /*Program EMIF0 CFG Registers*/
++ __raw_writel(TIM1, EMIF4_0_SDRAM_TIM_1);
++ __raw_writel(TIM1, EMIF4_0_SDRAM_TIM_1_SHADOW);
++ __raw_writel(TIM2, EMIF4_0_SDRAM_TIM_2);
++ __raw_writel(TIM2, EMIF4_0_SDRAM_TIM_2_SHADOW);
++ __raw_writel(TIM3, EMIF4_0_SDRAM_TIM_3);
++ __raw_writel(TIM3, EMIF4_0_SDRAM_TIM_3_SHADOW);
++ __raw_writel(SDCFG, EMIF4_0_SDRAM_CONFIG);
++ __raw_writel(RL, EMIF4_0_DDR_PHY_CTRL_1);
++ __raw_writel(RL, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
++ __raw_writel(0x0000613B, EMIF4_0_SDRAM_REF_CTRL); /* initially a large refresh period */
++ __raw_writel(0x1000613B, EMIF4_0_SDRAM_REF_CTRL); /* trigger initialization */
++ __raw_writel((0x10000000|EMIF_SDREF), EMIF4_0_SDRAM_REF_CTRL);
++ }
++
++ if(USE_EMIF1){
++ /*Program EMIF1 CFG Registers*/
++ __raw_writel(TIM1, EMIF4_1_SDRAM_TIM_1);
++ __raw_writel(TIM1, EMIF4_1_SDRAM_TIM_1_SHADOW);
++ __raw_writel(TIM2, EMIF4_1_SDRAM_TIM_2);
++ __raw_writel(TIM2, EMIF4_1_SDRAM_TIM_2_SHADOW);
++ __raw_writel(TIM3, EMIF4_1_SDRAM_TIM_3);
++ __raw_writel(TIM3, EMIF4_1_SDRAM_TIM_3_SHADOW);
++ __raw_writel(SDCFG, EMIF4_1_SDRAM_CONFIG);
++ __raw_writel(RL, EMIF4_1_DDR_PHY_CTRL_1);
++ __raw_writel(RL, EMIF4_1_DDR_PHY_CTRL_1_SHADOW);
++ __raw_writel(0x0000613B, EMIF4_1_SDRAM_REF_CTRL); /* initially a large refresh period */
++ __raw_writel(0x1000613B, EMIF4_1_SDRAM_REF_CTRL); /* trigger initialization */
++ __raw_writel((0x10000000|EMIF_SDREF), EMIF4_1_SDRAM_REF_CTRL);
++ }
++
++ delay(1000);
++#ifdef CONFIG_TI816X_DDR3_SW_LEVELING
++ ddr3_sw_levelling(0);
++ ddr3_sw_levelling(1);
++#endif
++}
++
++static void config_ti816x_sdram_ddr(void)
++{
++ __raw_writel(0x2, CM_DEFAULT_FW_CLKCTRL); /*Enable the EMIF Firewall clocks */
++ __raw_writel(0x2, CM_DEFAULT_L3_FAST_CLKSTCTRL); /*Enable the Power Domain Transition of L3 Fast Domain Peripheral*/
++ __raw_writel(0x2, CM_DEFAULT_EMIF_0_CLKCTRL); /*Enable EMIF0 Clock*/
++ __raw_writel(0x2, CM_DEFAULT_EMIF_1_CLKCTRL); /*Enable EMIF1 Clock*/
++ while((__raw_readl(CM_DEFAULT_L3_FAST_CLKSTCTRL) & 0x300) != 0x300); /*Poll for L3_FAST_GCLK & DDR_GCLK are active*/
++ while((__raw_readl(CM_DEFAULT_EMIF_0_CLKCTRL)) != 0x2); /*Poll for Module is functional*/
++ while((__raw_readl(CM_DEFAULT_EMIF_1_CLKCTRL)) != 0x2); /*Poll for Module is functional*/
++
++ if (USE_EMIF0) {
++ ddr_init_settings(0);
++ }
++
++ if (USE_EMIF1) {
++ ddr_init_settings(1);
++ }
++
++ __raw_writel(0x2, CM_DEFAULT_DMM_CLKCTRL); /*Enable EMIF1 Clock*/
++ while((__raw_readl(CM_DEFAULT_DMM_CLKCTRL)) != 0x2); /*Poll for Module is functional*/
++
++#ifdef CONFIG_MINIMAL
++ /* Program the DMM to for non-interleaved configuration */
++ __raw_writel(0x0, DMM_LISA_MAP__0);
++ __raw_writel(0x0, DMM_LISA_MAP__1);
++ __raw_writel(0x80500100, DMM_LISA_MAP__2);
++ __raw_writel(0xA0500200, DMM_LISA_MAP__3);
++#else
++ /* Program the DMM to for interleaved configuration */
++ __raw_writel(0x80640300, DMM_LISA_MAP__0);
++ __raw_writel(0xC0640320, DMM_LISA_MAP__1);
++ __raw_writel(0x80640300, DMM_LISA_MAP__2);
++ __raw_writel(0xC0640320, DMM_LISA_MAP__3);
++#endif
++
++ /*Enable Tiled Access*/
++ __raw_writel(0x80000000, DMM_PAT_BASE_ADDR);
++
++ emif4p_init(EMIF_TIM1, EMIF_TIM2, EMIF_TIM3, EMIF_SDREF & 0xFFFFFFF, EMIF_SDCFG, EMIF_PHYCFG);
++
++#ifdef CONFIG_TI816X_DDR3_PG_1_0
++ if(HACK_EYE_TRAINING) {
++ ddr_delay(10000);
++
++ if(USE_EMIF0){
++ __raw_writel(((RD_DQS_FORCE_2 + 50) << 9) | (RD_DQS_FORCE_2 + 50), DDRPHY_0_CONFIG_BASE + 0x178);
++ __raw_writel(((RD_DQS_FORCE_0 + 50) << 9) | (RD_DQS_FORCE_0 + 50), DDRPHY_0_CONFIG_BASE + 0x21C);
++ }
++
++ if(USE_EMIF1){
++ __raw_writel(((RD_DQS_FORCE_2 + 50) << 9) | (RD_DQS_FORCE_2 + 50), DDRPHY_1_CONFIG_BASE + 0x178);
++ __raw_writel(((RD_DQS_FORCE_0 + 50) << 9) | (RD_DQS_FORCE_0 + 50), DDRPHY_1_CONFIG_BASE + 0x21C);
++ }
++
++ ddr_delay(1000); /* wait for 1 ms */
++
++ if(USE_EMIF0) {
++ __raw_writel(((RD_DQS_FORCE_3 + 50) << 9) | (RD_DQS_FORCE_3 + 50), DDRPHY_0_CONFIG_BASE + 0x0D4);
++ __raw_writel(((RD_DQS_FORCE_1 + 50) << 9) | (RD_DQS_FORCE_1 + 50), DDRPHY_0_CONFIG_BASE + 0x2C0);
++ }
++
++ if(USE_EMIF1){
++ __raw_writel(((RD_DQS_FORCE_3 + 50) << 9) | (RD_DQS_FORCE_3 + 50), DDRPHY_1_CONFIG_BASE + 0x0D4);
++ __raw_writel(((RD_DQS_FORCE_1 + 50) << 9) | (RD_DQS_FORCE_1 + 50), DDRPHY_1_CONFIG_BASE + 0x2C0);
++ }
++
++ ddr_delay(1000); /* wait for 1 ms */
++
++ if(USE_EMIF0) {
++ __raw_writel(((RD_DQS_FORCE_3 << 9) | RD_DQS_FORCE_3),DDRPHY_0_CONFIG_BASE + 0x0D4);
++ __raw_writel(((RD_DQS_FORCE_0 << 9) | RD_DQS_FORCE_0),DDRPHY_0_CONFIG_BASE + 0x2C0);
++ __raw_writel(((RD_DQS_FORCE_2 << 9) | RD_DQS_FORCE_2),DDRPHY_0_CONFIG_BASE + 0x178);
++ __raw_writel(((RD_DQS_FORCE_1 << 9) | RD_DQS_FORCE_1),DDRPHY_0_CONFIG_BASE + 0x21C);
++ }
++
++ if(USE_EMIF1) {
++ __raw_writel(((RD_DQS_FORCE_3 << 9) | RD_DQS_FORCE_3),DDRPHY_1_CONFIG_BASE + 0x0D4);
++ __raw_writel(((RD_DQS_FORCE_0 << 9) | RD_DQS_FORCE_0),DDRPHY_1_CONFIG_BASE + 0x2C0);
++ __raw_writel(((RD_DQS_FORCE_2 << 9) | RD_DQS_FORCE_2),DDRPHY_1_CONFIG_BASE + 0x178);
++ __raw_writel(((RD_DQS_FORCE_1 << 9) | RD_DQS_FORCE_1),DDRPHY_1_CONFIG_BASE + 0x21C);
++ }
++
++ } /* hack eye training */
++
++ ddr_delay(1000); /* wait for 1 ms */
++ /* finish off */
++
++ if(USE_EMIF0){
++ __raw_writel(0x10000C30, EMIF4_0_SDRAM_REF_CTRL);
++ __raw_readl(EMIF4_0_SDRAM_REF_CTRL);
++ }
++
++ if(USE_EMIF1){
++ __raw_writel(0x10000C30, EMIF4_1_SDRAM_REF_CTRL);
++ __raw_readl(EMIF4_1_SDRAM_REF_CTRL);
++ }
++
++ walking_one_test(0x80000000, 0x9fffffff);
++#endif
++}
++
++#ifdef CONFIG_TI816X_DDR3_SW_LEVELING
++static void ddr3_sw_levelling(int emif)
++{
++ __raw_writel(0x6, (DDRPHY_CONFIG_BASE + 0x358));
++
++ __raw_writel(DQS_GATE_BYTE_LANE0, (DDRPHY_CONFIG_BASE + 0x108));
++ __raw_writel(0x00000000, (DDRPHY_CONFIG_BASE + 0x10C));
++ __raw_writel(DQS_GATE_BYTE_LANE1, (DDRPHY_CONFIG_BASE + 0x1AC));
++ __raw_writel(0x00000000, (DDRPHY_CONFIG_BASE + 0x1B0));
++ __raw_writel(DQS_GATE_BYTE_LANE2, (DDRPHY_CONFIG_BASE + 0x250));
++ __raw_writel(0x00000000, (DDRPHY_CONFIG_BASE + 0x254));
++ __raw_writel(DQS_GATE_BYTE_LANE3, (DDRPHY_CONFIG_BASE + 0x2F4));
++ __raw_writel(0x00000000, (DDRPHY_CONFIG_BASE + 0x2F8));
++
++ __raw_writel(WR_DQS_RATIO_BYTE_LANE0, (DDRPHY_CONFIG_BASE + 0x0DC));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x0E0));
++ __raw_writel(WR_DQS_RATIO_BYTE_LANE1, (DDRPHY_CONFIG_BASE + 0x180));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x184));
++ __raw_writel(WR_DQS_RATIO_BYTE_LANE2, (DDRPHY_CONFIG_BASE + 0x224));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x228));
++ __raw_writel(WR_DQS_RATIO_BYTE_LANE3, (DDRPHY_CONFIG_BASE + 0x2C8));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x2CC));
++
++ __raw_writel(WR_DATA_RATIO_BYTE_LANE0, (DDRPHY_CONFIG_BASE + 0x120));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x124));
++ __raw_writel(WR_DATA_RATIO_BYTE_LANE1, (DDRPHY_CONFIG_BASE + 0x1C4));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x1C8));
++ __raw_writel(WR_DATA_RATIO_BYTE_LANE2, (DDRPHY_CONFIG_BASE + 0x268));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x26C));
++ __raw_writel(WR_DATA_RATIO_BYTE_LANE3, (DDRPHY_CONFIG_BASE + 0x30C));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x310));
++
++ __raw_writel(RD_DQS_RATIO, (DDRPHY_CONFIG_BASE + 0x0C8));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x0CC));
++ __raw_writel(RD_DQS_RATIO, (DDRPHY_CONFIG_BASE + 0x16C));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x170));
++ __raw_writel(RD_DQS_RATIO, (DDRPHY_CONFIG_BASE + 0x210));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x214));
++ __raw_writel(RD_DQS_RATIO, (DDRPHY_CONFIG_BASE + 0x2B4));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x2B8));
++
++
++}
++#endif /* CONFIG_TI816X_DDR3_SW_LEVELING */
++
++#endif /* CONFIG_TI816X_EVM_DDR3 */
++
++#ifdef CONFIG_TI816X_EVM_DDR2
++static void ddr_init_settings(int emif)
++{
++ /* DLL Lockdiff */
++ if(0 == get_cpu_rev())
++ {
++ __raw_writel(0xF, (DDRPHY_CONFIG_BASE + 0x028));
++ __raw_writel(0xF, (DDRPHY_CONFIG_BASE + 0x05C));
++ __raw_writel(0xF, (DDRPHY_CONFIG_BASE + 0x090));
++ __raw_writel(0xF, (DDRPHY_CONFIG_BASE + 0x138));
++ __raw_writel(0xF, (DDRPHY_CONFIG_BASE + 0x1DC));
++ __raw_writel(0xF, (DDRPHY_CONFIG_BASE + 0x280));
++ __raw_writel(0xF, (DDRPHY_CONFIG_BASE + 0x324));
++ }
++
++ if(1 == get_cpu_rev())
++ {
++ __raw_writel(0x6, (DDRPHY_CONFIG_BASE + 0x358));
++ }
++
++ /* setup rank delays */
++ __raw_writel(0x1, (DDRPHY_CONFIG_BASE + 0x134));
++ __raw_writel(0x1, (DDRPHY_CONFIG_BASE + 0x1D8));
++ __raw_writel(0x1, (DDRPHY_CONFIG_BASE + 0x27C));
++ __raw_writel(0x1, (DDRPHY_CONFIG_BASE + 0x320));
++
++
++ __raw_writel(INVERT_CLK_OUT, (DDRPHY_CONFIG_BASE + 0x02C)); /* invert_clk_out cmd0 */
++ __raw_writel(INVERT_CLK_OUT, (DDRPHY_CONFIG_BASE + 0x060)); /* invert_clk_out cmd0 */
++ __raw_writel(INVERT_CLK_OUT, (DDRPHY_CONFIG_BASE + 0x094)); /* invert_clk_out cmd0 */
++
++
++ __raw_writel(CMD_SLAVE_RATIO, (DDRPHY_CONFIG_BASE + 0x01C)); /* cmd0 slave ratio */
++ __raw_writel(CMD_SLAVE_RATIO, (DDRPHY_CONFIG_BASE + 0x050)); /* cmd0 slave ratio */
++ __raw_writel(CMD_SLAVE_RATIO, (DDRPHY_CONFIG_BASE + 0x084)); /* cmd0 slave ratio */
++
++ __raw_writel(DQS_GATE_BYTE_LANE0, (DDRPHY_CONFIG_BASE + 0x108));
++ __raw_writel(0x00000000, (DDRPHY_CONFIG_BASE + 0x10C));
++ __raw_writel(DQS_GATE_BYTE_LANE1, (DDRPHY_CONFIG_BASE + 0x1AC));
++ __raw_writel(0x00000000, (DDRPHY_CONFIG_BASE + 0x1B0));
++ __raw_writel(DQS_GATE_BYTE_LANE2, (DDRPHY_CONFIG_BASE + 0x250));
++ __raw_writel(0x00000000, (DDRPHY_CONFIG_BASE + 0x254));
++ __raw_writel(DQS_GATE_BYTE_LANE3, (DDRPHY_CONFIG_BASE + 0x2F4));
++ __raw_writel(0x00000000, (DDRPHY_CONFIG_BASE + 0x2F8));
++
++ __raw_writel(WR_DQS_RATIO_BYTE_LANE0, (DDRPHY_CONFIG_BASE + 0x0DC));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x0E0));
++ __raw_writel(WR_DQS_RATIO_BYTE_LANE1, (DDRPHY_CONFIG_BASE + 0x180));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x184));
++ __raw_writel(WR_DQS_RATIO_BYTE_LANE2, (DDRPHY_CONFIG_BASE + 0x224));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x228));
++ __raw_writel(WR_DQS_RATIO_BYTE_LANE3, (DDRPHY_CONFIG_BASE + 0x2C8));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x2CC));
++
++ __raw_writel(WR_DATA_RATIO_BYTE_LANE0, (DDRPHY_CONFIG_BASE + 0x120));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x124));
++ __raw_writel(WR_DATA_RATIO_BYTE_LANE1, (DDRPHY_CONFIG_BASE + 0x1C4));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x1C8));
++ __raw_writel(WR_DATA_RATIO_BYTE_LANE2, (DDRPHY_CONFIG_BASE + 0x268));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x26C));
++ __raw_writel(WR_DATA_RATIO_BYTE_LANE3, (DDRPHY_CONFIG_BASE + 0x30C));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x310));
++
++ __raw_writel(RD_DQS_RATIO, (DDRPHY_CONFIG_BASE + 0x0C8));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x0CC));
++ __raw_writel(RD_DQS_RATIO, (DDRPHY_CONFIG_BASE + 0x16C));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x170));
++ __raw_writel(RD_DQS_RATIO, (DDRPHY_CONFIG_BASE + 0x210));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x214));
++ __raw_writel(RD_DQS_RATIO, (DDRPHY_CONFIG_BASE + 0x2B4));
++ __raw_writel(0x0, (DDRPHY_CONFIG_BASE + 0x2B8));
++
++ __raw_writel(0x5, (DDRPHY_CONFIG_BASE + 0x00C));
++ __raw_writel(0x5, (DDRPHY_CONFIG_BASE + 0x010));
++ __raw_writel(0x5, (DDRPHY_CONFIG_BASE + 0x040));
++ __raw_writel(0x5, (DDRPHY_CONFIG_BASE + 0x044));
++ __raw_writel(0x5, (DDRPHY_CONFIG_BASE + 0x074));
++ __raw_writel(0x5, (DDRPHY_CONFIG_BASE + 0x078));
++
++ __raw_writel(0x4, (DDRPHY_CONFIG_BASE + 0x0A8));
++ __raw_writel(0x4, (DDRPHY_CONFIG_BASE + 0x0AC));
++ __raw_writel(0x4, (DDRPHY_CONFIG_BASE + 0x14C));
++ __raw_writel(0x4, (DDRPHY_CONFIG_BASE + 0x150));
++ __raw_writel(0x4, (DDRPHY_CONFIG_BASE + 0x1F0));
++ __raw_writel(0x4, (DDRPHY_CONFIG_BASE + 0x1F4));
++ __raw_writel(0x4, (DDRPHY_CONFIG_BASE + 0x294));
++ __raw_writel(0x4, (DDRPHY_CONFIG_BASE + 0x298));
++
++ if(0 == get_cpu_rev())
++ {
++ __raw_writel(0x5, (DDRPHY_CONFIG_BASE + 0x338));
++ __raw_writel(0x5, (DDRPHY_CONFIG_BASE + 0x340));
++ __raw_writel(0x5, (DDRPHY_CONFIG_BASE + 0x348));
++ __raw_writel(0x5, (DDRPHY_CONFIG_BASE + 0x350));
++ }
++
++}
++
++static void emif4p_init(u32 TIM1, u32 TIM2, u32 TIM3, u32 SDREF, u32 SDCFG, u32 RL)
++{
++ /*Program EMIF0 CFG Registers*/
++ __raw_writel(TIM1, EMIF4_0_SDRAM_TIM_1);
++ __raw_writel(TIM1, EMIF4_0_SDRAM_TIM_1_SHADOW);
++ __raw_writel(TIM2, EMIF4_0_SDRAM_TIM_2);
++ __raw_writel(TIM2, EMIF4_0_SDRAM_TIM_2_SHADOW);
++ __raw_writel(TIM3, EMIF4_0_SDRAM_TIM_3);
++ __raw_writel(TIM3, EMIF4_0_SDRAM_TIM_3_SHADOW);
++ __raw_writel(SDCFG, EMIF4_0_SDRAM_CONFIG);
++ __raw_writel(RL, EMIF4_0_DDR_PHY_CTRL_1);
++ __raw_writel(RL, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
++
++ if (CONFIG_TI816X_TWO_EMIF){
++ __raw_writel(TIM1, EMIF4_1_SDRAM_TIM_1);
++ __raw_writel(TIM1, EMIF4_1_SDRAM_TIM_1_SHADOW);
++ __raw_writel(TIM2, EMIF4_1_SDRAM_TIM_2);
++ __raw_writel(TIM2, EMIF4_1_SDRAM_TIM_2_SHADOW);
++ __raw_writel(TIM3, EMIF4_1_SDRAM_TIM_3);
++ __raw_writel(TIM3, EMIF4_1_SDRAM_TIM_3_SHADOW);
++ __raw_writel(SDCFG, EMIF4_1_SDRAM_CONFIG);
++ __raw_writel(RL, EMIF4_1_DDR_PHY_CTRL_1);
++ __raw_writel(RL, EMIF4_1_DDR_PHY_CTRL_1_SHADOW);
++ }
++
++ /* setup a small control period */
++ __raw_writel(0x0000613B, EMIF4_0_SDRAM_REF_CTRL);
++ __raw_writel(0x1000613B, EMIF4_0_SDRAM_REF_CTRL);
++ __raw_writel((0x10000000|SDREF), EMIF4_0_SDRAM_REF_CTRL);
++
++ if (CONFIG_TI816X_TWO_EMIF){
++ /* setup a small control period */
++ __raw_writel(0x0000613B, EMIF4_1_SDRAM_REF_CTRL);
++ __raw_writel(0x1000613B, EMIF4_1_SDRAM_REF_CTRL);
++ __raw_writel((0x10000000|SDREF), EMIF4_1_SDRAM_REF_CTRL);
++
++ }
++
++
++}
++
++static void config_ti816x_sdram_ddr(void)
++{
++ __raw_writel(0x2, CM_DEFAULT_L3_FAST_CLKSTCTRL); /*Enable the Power Domain Transition of L3 Fast Domain Peripheral*/
++ __raw_writel(0x2, CM_DEFAULT_EMIF_0_CLKCTRL); /*Enable EMIF0 Clock*/
++ __raw_writel(0x2, CM_DEFAULT_EMIF_1_CLKCTRL); /*Enable EMIF1 Clock*/
++ while((__raw_readl(CM_DEFAULT_L3_FAST_CLKSTCTRL) & 0x300) != 0x300); /*Poll for L3_FAST_GCLK & DDR_GCLK are active*/
++ while((__raw_readl(CM_DEFAULT_EMIF_0_CLKCTRL)) != 0x2); /*Poll for Module is functional*/
++ while((__raw_readl(CM_DEFAULT_EMIF_1_CLKCTRL)) != 0x2); /*Poll for Module is functional*/
++
++ ddr_init_settings(0);
++
++ if (CONFIG_TI816X_TWO_EMIF){
++ ddr_init_settings(1);
++ }
++
++ __raw_writel(0x2, CM_DEFAULT_DMM_CLKCTRL); /*Enable EMIF1 Clock*/
++ while((__raw_readl(CM_DEFAULT_DMM_CLKCTRL)) != 0x2); /*Poll for Module is functional*/
++
++#ifdef CONFIG_MINIMAL
++ /* Program the DMM for non-interleave setting */
++ __raw_writel(0x0, DMM_LISA_MAP__0);
++ __raw_writel(0x0, DMM_LISA_MAP__1);
++ __raw_writel(0x80500100, DMM_LISA_MAP__2);
++ __raw_writel(0xA0500200, DMM_LISA_MAP__3);
++#else
++ /*Program the DMM for interleave setting */
++ __raw_writel(0x80640300, DMM_LISA_MAP__0);
++ __raw_writel(0xC0640320, DMM_LISA_MAP__1);
++ __raw_writel(0x80640300, DMM_LISA_MAP__2);
++ __raw_writel(0xC0640320, DMM_LISA_MAP__3);
++#endif
++
++ /*Enable Tiled Access*/
++ __raw_writel(0x80000000, DMM_PAT_BASE_ADDR);
++
++ emif4p_init(EMIF_TIM1, EMIF_TIM2, EMIF_TIM3, EMIF_SDREF & 0xFFFFFFF, EMIF_SDCFG, EMIF_PHYCFG);
++}
++#endif
++
++/*
++ * TI816X specific functions
++ */
++static void main_pll_init_ti816x(u32 sil_index, u32 clk_index)
++{
++ u32 main_pll_ctrl=0;
++
++ /* Sequence to be followed:
++ * 1. Put the PLL in bypass mode by setting BIT2 in its ctrl reg
++ * 2. Write the values of N,P in the CTRL reg
++ * 3. Program the freq values, divider values for the required output in the Control module reg
++ * 4. Note: Loading the freq value requires a particular bit to be set in the freq reg.
++ * 4. Program the CM divider value in the CM module reg
++ * 5. Enable the PLL by setting the appropriate bit in the CTRL reg of the PLL
++ */
++
++ /* If the registers have been set by the ROM code dont do anything
++ */
++
++ main_pll_ctrl = __raw_readl(MAINPLL_CTRL);
++ main_pll_ctrl &= 0xFFFFFFFB;
++ main_pll_ctrl |= 4;
++ __raw_writel(main_pll_ctrl, MAINPLL_CTRL);
++
++ main_pll_ctrl = __raw_readl(MAINPLL_CTRL);
++ main_pll_ctrl &= 0xFFFFFFF7;
++ main_pll_ctrl |= 8;
++ __raw_writel(main_pll_ctrl, MAINPLL_CTRL);
++
++ main_pll_ctrl = __raw_readl(MAINPLL_CTRL);
++ main_pll_ctrl &= 0xFF;
++ main_pll_ctrl |= (MAIN_N<<16 | MAIN_P<<8);
++ __raw_writel(main_pll_ctrl, MAINPLL_CTRL);
++
++ __raw_writel(0x0, MAINPLL_PWD);
++
++ __raw_writel((1<<31 | 1<<28 | (MAIN_INTFREQ1<<24) | MAIN_FRACFREQ1), MAINPLL_FREQ1);
++ __raw_writel(((1<<8) | MAIN_MDIV1), MAINPLL_DIV1);
++
++ __raw_writel((1<<31 | 1<<28 | (MAIN_INTFREQ2<<24) | MAIN_FRACFREQ2), MAINPLL_FREQ2);
++ __raw_writel(((1<<8) | MAIN_MDIV2), MAINPLL_DIV2);
++
++ __raw_writel((1<<31 | 1<<28 | (MAIN_INTFREQ3<<24) | MAIN_FRACFREQ3), MAINPLL_FREQ3);
++ __raw_writel(((1<<8) | MAIN_MDIV3), MAINPLL_DIV3);
++
++ __raw_writel((1<<31 | 1<<28 | (MAIN_INTFREQ4<<24) | MAIN_FRACFREQ4), MAINPLL_FREQ4);
++ __raw_writel(((1<<8) | MAIN_MDIV4), MAINPLL_DIV4);
++
++ __raw_writel((1<<31 | 1<<28 | (MAIN_INTFREQ5<<24) | MAIN_FRACFREQ5), MAINPLL_FREQ5);
++ __raw_writel(((1<<8) | MAIN_MDIV5), MAINPLL_DIV5);
++
++ __raw_writel((1<<8 | MAIN_MDIV6), MAINPLL_DIV6);
++
++ __raw_writel((1<<8 | MAIN_MDIV7), MAINPLL_DIV7);
++
++ while((__raw_readl(MAINPLL_CTRL) & 0x80) != 0x80);
++
++ main_pll_ctrl = __raw_readl(MAINPLL_CTRL);
++ main_pll_ctrl &= 0xFFFFFFFB;
++
++ __raw_writel(main_pll_ctrl, MAINPLL_CTRL);
++
++}
++
++static void ddr_pll_init_ti816x(u32 sil_index, u32 clk_index)
++{
++ u32 ddr_pll_ctrl=0;
++
++ /* Sequence to be followed:
++ * 1. Put the PLL in bypass mode by setting BIT2 in its ctrl reg
++ * 2. Write the values of N,P in the CTRL reg
++ * 3. Program the freq values, divider values for the required output in the Control module reg
++ * 4. Note: Loading the freq value requires a particular bit to be set in the freq reg.
++ * 4. Program the CM divider value in the CM module reg
++ * 5. Enable the PLL by setting the appropriate bit in the CTRL reg of the PLL
++ */
++
++ /* If the registers have been set by the ROM code dont do anything
++ */
++
++ ddr_pll_ctrl = __raw_readl(DDRPLL_CTRL);
++ ddr_pll_ctrl &= 0xFFFFFFFB;
++ __raw_writel(ddr_pll_ctrl, DDRPLL_CTRL);
++
++ ddr_pll_ctrl = __raw_readl(DDRPLL_CTRL);
++ ddr_pll_ctrl &= 0xFFFFFFF7;
++ ddr_pll_ctrl |= 8;
++ __raw_writel(ddr_pll_ctrl, DDRPLL_CTRL);
++
++ ddr_pll_ctrl = __raw_readl(DDRPLL_CTRL);
++ ddr_pll_ctrl &= 0xFF;
++ ddr_pll_ctrl |= (DDR_N<<16 | DDR_P<<8);
++ __raw_writel(ddr_pll_ctrl, DDRPLL_CTRL);
++
++ /* 10usec delay */
++ ddr_delay(10);
++
++ __raw_writel(0x0,DDRPLL_PWD);
++
++ __raw_writel(((0<<8) | DDR_MDIV1), DDRPLL_DIV1);
++ ddr_delay(1);
++ __raw_writel(((1<<8) | DDR_MDIV1), DDRPLL_DIV1);
++
++ __raw_writel((1<<31 | 1<<28 | (DDR_INTFREQ2<<24) | DDR_FRACFREQ2), DDRPLL_FREQ2);
++ __raw_writel(((1<<8) | DDR_MDIV2), DDRPLL_DIV2);
++
++ __raw_writel(((0<<8) | DDR_MDIV3), DDRPLL_DIV3);
++ ddr_delay(1);
++ __raw_writel(((1<<8) | DDR_MDIV3), DDRPLL_DIV3);
++ ddr_delay(1);
++ __raw_writel((0<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3), DDRPLL_FREQ3);
++ ddr_delay(1);
++ __raw_writel((1<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3), DDRPLL_FREQ3);
++
++ ddr_delay(5);
++
++ /* Wait for PLL to lock */
++ while((__raw_readl(DDRPLL_CTRL) & 0x80) != 0x80);
++
++ ddr_pll_ctrl = __raw_readl(DDRPLL_CTRL);
++ ddr_pll_ctrl &= 0xFFFFFFFB;
++ ddr_pll_ctrl |= 4;
++ __raw_writel(ddr_pll_ctrl, DDRPLL_CTRL);
++
++ __raw_writel(0x1, DDR_RCD);
++
++}
++
++/*******************************************************
++ * Routine: misc_init_r
++ ********************************************************/
++int misc_init_r (void)
++{
++ #ifdef CONFIG_TI816X_ASCIIART
++ int i = 0, j = 0;
++ char ti816x[23][79] = {
++":,;;:;:;;;;;;;;r;;:,;;:;:;;;;;;;;:,;;:;:;;;;;;;;:,;;:;:;;;;;;;;:;;;;;;;;:,;;:;:",
++";,;:::;;;;r;;;rssiSiS552X5252525259GX2X9hX9X9XX2325S55252i5:,;;:;:;;;;;;;;:,;;:",
++";:;;;;;;;rrssSsS52S22h52299GGAAMHMM#BBH#B#HMM#HMBA&&XX2255S2S5Si:,;;:;:;;;;;;;;",
++";:;;r;;rsrrriiXS5S329&A&MH#BMB#A&9XXA252GXiSXX39AAMMMBB&G22S5i2SSiiiisi:,;;:;:;",
++";;;;;r;rr2iisiih393HB#B#AA99i22irrrX3X52AGsisss2Xii2299HBMA&X2S5S5iSiisSsi:,;;:",
++"r:r;rrsrsihXSi2&##MHB&Ahh3AGHGA9G9h&#H##@@@##MAMMXXX9SSS29&&HGGX2i5iisiiisisi:,",
++";;rrrrsSiiiA&ABH&A9GAGhAhBAMHA9HM@@@@@@@@@@@@@@@@@@@HHhAh2S2SX9&Gh22SSiisiiisii",
++"r:rrssisiS2XM##&h3AGAX&3GG3Ssr5H@M#HM2; ;2X&&&MHMB###GBB#B&XXSSs529XX55iSsisisi",
++"r;rsrisSi2XHAhX99A3XXG&&XS;:,rH#HGhAS @@@@3rs2XBM@@A552&&AHA2XiisSS252SSsisSs",
++"r;issi5S22&&3iSSX292&hXsr;;:;h@&G339&S9@@@@2@MA&9&HB##Xris29ABMAAX2ir;rsSi5iss5",
++"rrsSi2XhG&9GXh399&X99i;;;;;;r#H&293H9X#@@@@@@@B&9GhAH@XrrsrsiXABHB&HG2rr;rrSiSi",
++";:rsisS599&AA9XG&3A35r;:::;,;BMh&&2iX5A@@@@@@@&392X5GB2;;;r;iSX393A##A&Xi:::rsi",
++";:rss552222X553&XHMhir;;::,:,h#HhGSXhG3#@@@@#AXXS2XAHA;::;;;;ss55XShBA3239r:,;;",
++"r;ii2S5SSi2i53hirsh2srr::,,,,;MMXX359&Ah3h&Si59SX99A#i:,::::;;sri2,.2r;:SGAr;,:",
++";:;rrrrssiriXGSi::shs;;;,,,:,,rBBA9h5s5h5iS5isi2SAHB5:,,,:::;rrs5&SrisSX5Srrr:,",
++";,r;;;;rsriSSrrrr;;5Xrr;;,:,,.,;9AA2SsisS5323XXXG9&i:.,,::;;r;;;srrrrrr;;:;::::",
++":,;r;r;rrissrrr;:;::;s;;;;,:,,..,r293h222hXXAAGGGX;:,,,:,:,::;:;::,:,,,,...,,,,",
++";,;;;;rrrrrrrrirr;,.,,:::::::,,,,.,;SX&ABAB2hhXir:,,.,,.,,:,,,,..,,,..,..,,,..:",
++":.:;:;;;:;;;;r;rrs;:.. ,,:::::,:,:,,.::rrsrr;;,,.......,..,....,,,,,,,...,.,,:,",
++":.:::,::::::;;r;rrr;:.......,.,.,,:::,,...............,,::.,,,,:,::,,:,:,,,:,;:",
++",.::,:,,,,,;;;;;;;;r;;::,..............................;;;:;::::,:::::::,:,:,,,",
++": ,,:,,,,,,,,,,,,,:;rrr;;:;,,,,,,,::,.,.:.,.,;s,:;;;;:;:;;;;;::::,:::,:::,:,:,:",
++",.,,,,,,,...,,.,,....................................:,............:,,,:,:,,,,,"};
++
++ for (i = 0; i<23; i++)
++ {
++ for(j = 0; j<79; j++)
++ printf("%c",ti816x[i][j]);
++ printf("\n");
++ }
++ printf("\n");
++ #endif
++ return 0;
++}
++
++#ifdef CONFIG_TI816X_DDR3_PG_1_0
++void walking_one_test(unsigned long start_addr, unsigned long end_addr)
++{
++ data_walking_test(start_addr, 0xffffffff);
++ address_walking_test(start_addr, (end_addr - start_addr));
++}
++
++void data_walking_test(unsigned long addr, unsigned long mask)
++{
++ unsigned bit = 1;
++ int i;
++
++ for(i=0; i<32; i++){
++ if(mask & bit){
++ __raw_writel(bit, addr);
++ if(__raw_readl(addr) != bit){
++ /* If this happens DDR3 init has failed */
++ while (1);
++ }
++ }
++
++ bit = bit << 1;
++ }
++}
++
++void address_walking_test(unsigned long addr, unsigned long mask)
++{
++ unsigned bit = 1;
++ int i;
++ unsigned char write_value = 1;
++
++ /* perform the writes */
++ for(i=0; i<32; i++){
++ if(mask & bit){
++ __raw_writec(write_value, addr + bit);
++ }
++
++ bit = bit << 1;
++ write_value++;
++ }
++
++ /* check that it was all good */
++ write_value = 1;
++
++ for(i=0; i<32; i++){
++ if(mask & bit){
++ if(__raw_readc(addr + bit) != write_value){
++ /* If this happens DDR3 init has failed */
++ while (1);
++ }
++ }
++
++ bit = bit << 1;
++ write_value++;
++ }
++}
++#endif
++
++/*****************************************************************
++ * Routine: peripheral_enable
++ * Description: Enable the clks & power for perifs (TIMER1, UART0,...)
++ *
++ ******************************************************************/
++static void peripheral_enable(void)
++{
++ /* DMTimers */
++ __raw_writel(0x2, CM_ALWON_L3_SLOW_CLKSTCTRL);
++
++ /* Note on Timers:
++ * There are 8 timers(0-7) out of which timer 0 is a secure timer.
++ * Timer 0 mux should not be changed
++ * For other timers, there are 3 inputs TCLKIN, 32KHz (external clk or SYSCLK18?) and CLKIN(27MHz)
++ * We select CLKIN and use that
++ */
++
++ /* First we need to enable the modules and setup the clk path
++ * Then the timers need to be configured by writing to their registers
++ * To access the timer registers we need the module to be
++ * enabled which is what we do in the first step
++ */
++
++ /* TIMER 1 */
++ __raw_writel(0x2, CM_ALWON_TIMER_1_CLKCTRL);
++
++ /* Selects CLKIN (27MHz) */
++ __raw_writel(0x2, CM_TIMER1_CLKSEL);
++
++ while(((__raw_readl(CM_ALWON_L3_SLOW_CLKSTCTRL) & (0x80000<<1)) >> (19+1)) != 1);
++
++ while(((__raw_readl(CM_ALWON_TIMER_1_CLKCTRL) & 0x30000)>>16) !=0);
++
++
++ __raw_writel(0x2,(DM_TIMER1_BASE + 0x54));
++ while(__raw_readl(DM_TIMER1_BASE + 0x10) & 1);
++
++ __raw_writel(0x1,(DM_TIMER1_BASE + 0x38));
++
++ /* UARTs */
++ /* Note: The clock has been set to correct rate before this step */
++ __raw_writel(0x2, CM_ALWON_UART_0_CLKCTRL);
++ while(__raw_readl(CM_ALWON_UART_0_CLKCTRL) != 0x2);
++
++ __raw_writel(0x2, CM_ALWON_UART_1_CLKCTRL);
++ while(__raw_readl(CM_ALWON_UART_1_CLKCTRL) != 0x2);
++
++ __raw_writel(0x2, CM_ALWON_UART_2_CLKCTRL);
++ while(__raw_readl(CM_ALWON_UART_2_CLKCTRL) != 0x2);
++
++ while((__raw_readl(CM_ALWON_L3_SLOW_CLKSTCTRL) & 0x2100) != 0x2100);
++
++ /* eFuse */
++ __raw_writel(0x2, CM_ALWON_CUST_EFUSE_CLKCTRL);
++ while(__raw_readl(CM_ALWON_CUST_EFUSE_CLKCTRL) != 0x2);
++
++ /* GPIO0 */
++ __raw_writel(0x2, CM_ALWON_GPIO_0_CLKCTRL);
++ while(__raw_readl(CM_ALWON_GPIO_0_CLKCTRL) != 0x2);
++
++ __raw_writel((BIT(8)), CM_ALWON_GPIO_0_OPTFCLKEN_DBCLK);
++
++ /* SPI */
++ __raw_writel(0x2, CM_ALWON_SPI_CLKCTRL);
++ while(__raw_readl(CM_ALWON_SPI_CLKCTRL) != 0x2);
++
++ /* I2C0 */
++ __raw_writel(0x2, CM_ALWON_I2C_0_CLKCTRL);
++ while(__raw_readl(CM_ALWON_I2C_0_CLKCTRL) != 0x2);
++
++ /* Ethernet */
++ __raw_writel(0x2, CM_ETHERNET_CLKSTCTRL);
++ __raw_writel(0x2, CM_ALWON_ETHERNET_0_CLKCTRL);
++ __raw_writel(0x2, CM_ALWON_ETHERNET_1_CLKCTRL);
++
++ /* HSMMC */
++ __raw_writel(0x2, CM_ALWON_HSMMC_CLKCTRL);
++ while(__raw_readl(CM_ALWON_HSMMC_CLKCTRL) != 0x2);
++
++ /* WDT */
++ /* For WDT to be functional, it needs to be first stopped by writing
++ * the pattern 0xAAAA followed by 0x5555 in the WDT start/stop register.
++ * After that a write-once register in Control module needs to be configured
++ * to unfreeze the timer.
++ * Note: It is important to stop the watchdog before unfreezing it
++ */
++ __raw_writel(0xAAAA, WDT_WSPR);
++ while(__raw_readl(WDT_WWPS) != 0x0);
++ __raw_writel(0x5555, WDT_WSPR);
++ while(__raw_readl(WDT_WWPS) != 0x0);
++
++ /* Unfreeze WDT */
++ __raw_writel(0x2, WDT_UNFREEZE);
++}
++
++/******************************************************************************
++ * prcm_init() - inits clocks for PRCM as defined in clocks.h
++ *****************************************************************************/
++void prcm_init(u32 in_ddr)
++{
++ /* For future */
++ u32 clk_index = 0, sil_index = 0;
++
++ __raw_writel(0x2, 0x48200010);
++ /* Enable the control module */
++ __raw_writel(0x2, CM_ALWON_CONTROL_CLKCTRL);
++
++ /* Fix ROM code bug */
++ __raw_writel(0x0, 0x48180324);
++
++ //if (is_cpu_family() == CPU_TI816X) {
++ main_pll_init_ti816x(clk_index, sil_index);
++ if (!in_ddr)
++ ddr_pll_init_ti816x(clk_index, sil_index);
++ //}
++
++ /* With clk freqs setup to desired values, enable the required peripherals */
++ peripheral_enable();
++}
++
++/******************************************************************************
++ * set_muxconf_regs(void) - Setting up the configuration Mux registers
++ *****************************************************************************/
++void set_muxconf_regs(void)
++{
++ /* HSMMC Padconfig */
++ __raw_writew((PTD | EN | M0), MMC_POW);
++ __raw_writew((PTD | DIS | M0), MMC_CLK);
++ __raw_writew((PTU | EN | M0), MMC_CMD);
++ __raw_writew((PTU | EN | M0), MMC_DAT0);
++ __raw_writew((PTU | EN | M0), MMC_DAT1_SDIRQ);
++ __raw_writew((PTU | EN | M0), MMC_DAT2_SDRW);
++ __raw_writew((PTU | EN | M0), MMC_DAT3);
++}
++
++#ifdef CONFIG_GENERIC_MMC
++int board_mmc_init(bd_t *bis)
++{
++ omap_mmc_init(0);
++ return 0;
++}
++#endif
++
++/**********************************************************
++ * Routine: s_init
++ * Description: Does early system init of muxing and clocks.
++ * - Called at time when only stack is available.
++ **********************************************************/
++void s_init(u32 in_ddr)
++{
++ l2_cache_enable(); /* Can be removed as A8 comes up with L2 enabled */
++#ifdef CONFIG_SETUP_1V
++ __raw_writel(0x102, 0x4818155c);
++ while((__raw_readl(0x4818155c) & 0x3) != 0x2);
++
++ __raw_writel(0x102, 0x48181560);
++ while((__raw_readl(0x48181560) & 0x3) != 0x2);
++
++ __raw_writel(0x00000001, 0x4803213c);
++ __raw_writel(0xfffffff0, 0x48032134);
++#endif
++
++ prcm_init(in_ddr); /* Setup the PLLs and the clocks for the peripherals */
++ set_muxconf_regs();
++ if (!in_ddr)
++ config_ti816x_sdram_ddr(); /* Do DDR settings */
++#ifdef CONFIG_TI816X_VOLT_SCALE
++ voltage_scale_init();
++#endif
++}
++
++/* optionally do something like blinking LED */
++void board_hang (void)
++{ while (0) {};}
++
++/* Reset the board */
++void reset_cpu (ulong addr)
++{
++ addr = __raw_readl(PRM_DEVICE_RSTCTRL);
++ addr &= ~BIT(1);
++ addr |= BIT(1);
++ __raw_writel(addr, PRM_DEVICE_RSTCTRL);
++}
++
++#ifdef CONFIG_NAND_TI81XX
++/******************************************************************************
++ * Command to switch between NAND HW and SW ecc
++ *****************************************************************************/
++extern void ti81xx_nand_switch_ecc(nand_ecc_modes_t hardware, int32_t mode);
++static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
++{
++ int type = 0;
++ if (argc < 2)
++ goto usage;
++
++ if (strncmp(argv[1], "hw", 2) == 0) {
++ if (argc == 3)
++ type = simple_strtoul(argv[2], NULL, 10);
++ ti81xx_nand_switch_ecc(NAND_ECC_HW, type);
++ }
++ else if (strncmp(argv[1], "sw", 2) == 0)
++ ti81xx_nand_switch_ecc(NAND_ECC_SOFT, 0);
++ else
++ goto usage;
++
++ return 0;
++
++usage:
++ printf ("Usage: nandecc %s\n", cmdtp->usage);
++ return 1;
++}
++
++U_BOOT_CMD(
++ nandecc, 3, 1, do_switch_ecc,
++ "Switch NAND ECC calculation algorithm b/w hardware and software",
++ "[sw|hw <hw_type>] \n"
++ " [sw|hw]- Switch b/w hardware(hw) & software(sw) ecc algorithm\n"
++ " hw_type- 0 for Hamming code\n"
++ " 1 for bch4\n"
++ " 2 for bch8\n"
++ " 3 for bch16\n"
++);
++
++#endif /* CONFIG_NAND_TI81XX */
++
+diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c
+index 533af5a..f50d113 100644
+--- a/board/timll/devkit8000/devkit8000.c
++++ b/board/timll/devkit8000/devkit8000.c
+@@ -128,7 +128,7 @@ int board_mmc_init(bd_t *bis)
+ }
+ #endif
+
+-#ifdef CONFIG_DRIVER_DM9000
++#if defined(CONFIG_DRIVER_DM9000) & !defined(CONFIG_SPL_BUILD)
+ /*
+ * Routine: board_eth_init
+ * Description: Setting up the Ethernet hardware.
+diff --git a/boards.cfg b/boards.cfg
+index d32ff7e..75dbc53 100644
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -167,6 +167,7 @@ omap3_overo arm armv7 overo -
+ omap3_pandora arm armv7 pandora - omap3
+ igep0020 arm armv7 igep0020 isee omap3
+ igep0030 arm armv7 igep0030 isee omap3
++am335x_evm arm armv7 am335x ti ti81xx
+ am3517_crane arm armv7 am3517crane ti omap3
+ am3517_evm arm armv7 am3517evm logicpd omap3
+ dig297 arm armv7 dig297 comelit omap3
+@@ -178,6 +179,7 @@ omap3_sdp3430 arm armv7 sdp3430 ti
+ devkit8000 arm armv7 devkit8000 timll omap3
+ omap4_panda arm armv7 panda ti omap4
+ omap4_sdp4430 arm armv7 sdp4430 ti omap4
++ti8148_evm arm armv7 ti8148 ti ti81xx
+ s5p_goni arm armv7 goni samsung s5pc1xx
+ smdkc100 arm armv7 smdkc100 samsung s5pc1xx
+ origen arm armv7 origen samsung s5pc2xx
+diff --git a/common/Makefile b/common/Makefile
+index 2edbd71..54dc558 100644
+--- a/common/Makefile
++++ b/common/Makefile
+@@ -175,6 +175,9 @@ COBJS-$(CONFIG_UPDATE_TFTP) += update.o
+ COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
+ endif
+
++ifdef CONFIG_SPL_BUILD
++COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
++endif
+ COBJS-y += console.o
+ COBJS-y += memsize.o
+ COBJS-y += stdio.o
+diff --git a/common/env_nand.c b/common/env_nand.c
+index 14446a6..0db7230 100644
+--- a/common/env_nand.c
++++ b/common/env_nand.c
+@@ -161,6 +161,10 @@ int writeenv(size_t offset, u_char *buf)
+
+ u_char *char_ptr;
+
++ /* fail if no nand detected */
++ if (nand_info[0].type == 0)
++ return 1;
++
+ blocksize = nand_info[0].erasesize;
+ len = min(blocksize, CONFIG_ENV_SIZE);
+
+diff --git a/common/miiphyutil.c b/common/miiphyutil.c
+index 35ad357..22db4d7 100644
+--- a/common/miiphyutil.c
++++ b/common/miiphyutil.c
+@@ -558,7 +558,9 @@ int miiphy_is_1000base_x(const char *devname, unsigned char addr)
+ "1000BASE-X\n");
+ return 0;
+ }
+- return 0 != (exsr & (ESTATUS_1000XF | ESTATUS_1000XH));
++ /*temporary hack*/
++ return 0;
++ /*return 0 != (exsr & (ESTATUS_1000XF | ESTATUS_1000XH)); */
+ #else
+ return 0;
+ #endif
+diff --git a/doc/README.SPL b/doc/README.SPL
+index 30624a5..d53ef9c 100644
+--- a/doc/README.SPL
++++ b/doc/README.SPL
+@@ -60,3 +60,5 @@ CONFIG_SPL_SPI_FLASH_SUPPORT (drivers/mtd/spi/libspi_flash.o)
+ CONFIG_SPL_SPI_SUPPORT (drivers/spi/libspi.o)
+ CONFIG_SPL_FAT_SUPPORT (fs/fat/libfat.o)
+ CONFIG_SPL_LIBGENERIC_SUPPORT (lib/libgeneric.o)
++CONFIG_SPL_POWER_SUPPORT (drivers/power/libpower.o)
++CONFIG_SPL_NAND_SUPPORT (drivers/mtd/nand/libnand.o)
+diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
+index a48047a..8e8a412 100644
+--- a/drivers/i2c/Makefile
++++ b/drivers/i2c/Makefile
+@@ -34,6 +34,7 @@ COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
+ COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
+ COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
+ COBJS-$(CONFIG_DRIVER_OMAP34XX_I2C) += omap24xx_i2c.o
++COBJS-$(CONFIG_DRIVER_TI81XX_I2C) += omap24xx_i2c.o
+ COBJS-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o
+ COBJS-$(CONFIG_PPC4XX_I2C) += ppc4xx_i2c.o
+ COBJS-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o
+diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
+index 4ae237a..bc7b89f 100644
+--- a/drivers/i2c/omap24xx_i2c.c
++++ b/drivers/i2c/omap24xx_i2c.c
+@@ -25,17 +25,29 @@
+ #include <asm/arch/i2c.h>
+ #include <asm/io.h>
+
+-#include "omap24xx_i2c.h"
+-
+ DECLARE_GLOBAL_DATA_PTR;
+
+-#define I2C_TIMEOUT 1000
+-
+-static void wait_for_bb(void);
+-static u16 wait_for_pin(void);
++#define I2C_REV_OFS (0x00)
++#define I2C_SYSC_OFS (0x10)
++#define I2C_IE_OFS (0x2C)
++#define I2C_STAT_OFS (0x28)
++#define I2C_SYSS_OFS (0x90)
++#define I2C_BUF_OFS (0x94)
++#define I2C_CNT_OFS (0x98)
++#define I2C_DATA_OFS (0x9c)
++#define I2C_CON_OFS (0xA4)
++#define I2C_OA_OFS (0xA8)
++#define I2C_SA_OFS (0xAC)
++#define I2C_PSC_OFS (0xB0)
++#define I2C_SCLL_OFS (0xB4)
++#define I2C_SCLH_OFS (0xB8)
++#define I2C_SYSTEST_OFS (0xBc)
++
++#define I2C_TIMEOUT ( 1 << 31)
++static u32 wait_for_bb (void);
++static u32 wait_for_status_mask(u16 mask);
+ static void flush_fifo(void);
+-
+-static struct i2c *i2c_base = (struct i2c *)I2C_DEFAULT_BASE;
++static u32 i2c_base = (u32)I2C_DEFAULT_BASE;
+
+ static unsigned int bus_initialized[I2C_BUS_MAX];
+ static unsigned int current_bus;
+@@ -45,20 +57,17 @@ void i2c_init(int speed, int slaveadd)
+ int psc, fsscll, fssclh;
+ int hsscll = 0, hssclh = 0;
+ u32 scll, sclh;
+- int timeout = I2C_TIMEOUT;
+
+ /* Only handle standard, fast and high speeds */
+ if ((speed != OMAP_I2C_STANDARD) &&
+ (speed != OMAP_I2C_FAST_MODE) &&
+ (speed != OMAP_I2C_HIGH_SPEED)) {
+- printf("Error : I2C unsupported speed %d\n", speed);
+ return;
+ }
+
+ psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK;
+ psc -= 1;
+ if (psc < I2C_PSC_MIN) {
+- printf("Error : I2C unsupported prescalar %d\n", psc);
+ return;
+ }
+
+@@ -73,7 +82,6 @@ void i2c_init(int speed, int slaveadd)
+ fssclh -= I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM;
+ if (((fsscll < 0) || (fssclh < 0)) ||
+ ((fsscll > 255) || (fssclh > 255))) {
+- printf("Error : I2C initializing first phase clock\n");
+ return;
+ }
+
+@@ -84,7 +92,6 @@ void i2c_init(int speed, int slaveadd)
+ hssclh -= I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM;
+ if (((fsscll < 0) || (fssclh < 0)) ||
+ ((fsscll > 255) || (fssclh > 255))) {
+- printf("Error : I2C initializing second phase clock\n");
+ return;
+ }
+
+@@ -99,7 +106,6 @@ void i2c_init(int speed, int slaveadd)
+ fssclh -= I2C_FASTSPEED_SCLH_TRIM;
+ if (((fsscll < 0) || (fssclh < 0)) ||
+ ((fsscll > 255) || (fssclh > 255))) {
+- printf("Error : I2C initializing clock\n");
+ return;
+ }
+
+@@ -107,114 +113,29 @@ void i2c_init(int speed, int slaveadd)
+ sclh = (unsigned int)fssclh;
+ }
+
+- if (readw(&i2c_base->con) & I2C_CON_EN) {
+- writew(0, &i2c_base->con);
+- udelay(50000);
+- }
+-
+- writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */
+- udelay(1000);
++ if (gd->flags & GD_FLG_RELOC)
++ bus_initialized[current_bus] = 1;
+
+- writew(I2C_CON_EN, &i2c_base->con);
+- while (!(readw(&i2c_base->syss) & I2C_SYSS_RDONE) && timeout--) {
+- if (timeout <= 0) {
+- printf("ERROR: Timeout in soft-reset\n");
+- return;
+- }
+- udelay(1000);
++ if (readw ((i2c_base + I2C_CON_OFS)) & I2C_CON_EN) {
++ writew (0, (i2c_base + I2C_CON_OFS));
++ udelay (50000);
+ }
+
+- writew(0, &i2c_base->con);
+- writew(psc, &i2c_base->psc);
+- writew(scll, &i2c_base->scll);
+- writew(sclh, &i2c_base->sclh);
++ writew(psc, (i2c_base + I2C_PSC_OFS));
++ writew(scll, (i2c_base + I2C_SCLL_OFS));
++ writew(sclh, (i2c_base + I2C_SCLH_OFS));
+
+ /* own address */
+- writew(slaveadd, &i2c_base->oa);
+- writew(I2C_CON_EN, &i2c_base->con);
++ writew (slaveadd, (i2c_base + I2C_OA_OFS));
++ writew (I2C_CON_EN, (i2c_base + I2C_CON_OFS));
+
+ /* have to enable intrrupts or OMAP i2c module doesn't work */
+- writew(I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
+- I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie);
+- udelay(1000);
++ writew (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
++ I2C_IE_NACK_IE | I2C_IE_AL_IE, (i2c_base + I2C_IE_OFS));
++ udelay (1000);
+ flush_fifo();
+- writew(0xFFFF, &i2c_base->stat);
+- writew(0, &i2c_base->cnt);
+-
+- if (gd->flags & GD_FLG_RELOC)
+- bus_initialized[current_bus] = 1;
+-}
+-
+-static int i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value)
+-{
+- int i2c_error = 0;
+- u16 status;
+-
+- /* wait until bus not busy */
+- wait_for_bb();
+-
+- /* one byte only */
+- writew(1, &i2c_base->cnt);
+- /* set slave address */
+- writew(devaddr, &i2c_base->sa);
+- /* no stop bit needed here */
+- writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+- I2C_CON_TRX, &i2c_base->con);
+-
+- /* send register offset */
+- while (1) {
+- status = wait_for_pin();
+- if (status == 0 || status & I2C_STAT_NACK) {
+- i2c_error = 1;
+- goto read_exit;
+- }
+- if (status & I2C_STAT_XRDY) {
+- /* Important: have to use byte access */
+- writeb(regoffset, &i2c_base->data);
+- writew(I2C_STAT_XRDY, &i2c_base->stat);
+- }
+- if (status & I2C_STAT_ARDY) {
+- writew(I2C_STAT_ARDY, &i2c_base->stat);
+- break;
+- }
+- }
+-
+- /* set slave address */
+- writew(devaddr, &i2c_base->sa);
+- /* read one byte from slave */
+- writew(1, &i2c_base->cnt);
+- /* need stop bit here */
+- writew(I2C_CON_EN | I2C_CON_MST |
+- I2C_CON_STT | I2C_CON_STP,
+- &i2c_base->con);
+-
+- /* receive data */
+- while (1) {
+- status = wait_for_pin();
+- if (status == 0 || status & I2C_STAT_NACK) {
+- i2c_error = 1;
+- goto read_exit;
+- }
+- if (status & I2C_STAT_RRDY) {
+-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
+- defined(CONFIG_OMAP44XX)
+- *value = readb(&i2c_base->data);
+-#else
+- *value = readw(&i2c_base->data);
+-#endif
+- writew(I2C_STAT_RRDY, &i2c_base->stat);
+- }
+- if (status & I2C_STAT_ARDY) {
+- writew(I2C_STAT_ARDY, &i2c_base->stat);
+- break;
+- }
+- }
+-
+-read_exit:
+- flush_fifo();
+- writew(0xFFFF, &i2c_base->stat);
+- writew(0, &i2c_base->cnt);
+- return i2c_error;
++ writew (0xFFFF, (i2c_base + I2C_STAT_OFS));
++ writew (0, (i2c_base + I2C_CNT_OFS));
+ }
+
+ static void flush_fifo(void)
+@@ -223,16 +144,15 @@ static void flush_fifo(void)
+ /* note: if you try and read data when its not there or ready
+ * you get a bus error
+ */
+- while (1) {
+- stat = readw(&i2c_base->stat);
+- if (stat == I2C_STAT_RRDY) {
+-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
+- defined(CONFIG_OMAP44XX)
+- readb(&i2c_base->data);
++ while(1){
++ stat = readw((i2c_base + I2C_STAT_OFS));
++ if(stat == I2C_STAT_RRDY){
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || defined(CONFIG_TI81XX)
++ readb((i2c_base + I2C_DATA_OFS));
+ #else
+- readw(&i2c_base->data);
++ readw((i2c_base + I2C_DATA_OFS));
+ #endif
+- writew(I2C_STAT_RRDY, &i2c_base->stat);
++ writew(I2C_STAT_RRDY,(i2c_base + I2C_STAT_OFS));
+ udelay(1000);
+ } else
+ break;
+@@ -241,197 +161,427 @@ static void flush_fifo(void)
+
+ int i2c_probe(uchar chip)
+ {
+- u16 status;
+ int res = 1; /* default = fail */
++ u32 status;
+
+- if (chip == readw(&i2c_base->oa))
++ if (chip == readw ((i2c_base + I2C_OA_OFS)))
+ return res;
+
+ /* wait until bus not busy */
+- wait_for_bb();
++ status = wait_for_bb();
++
++ /* exiting on BUS busy */
++ if (status & I2C_TIMEOUT)
++ return res;
+
+- /* try to write one byte */
+- writew(1, &i2c_base->cnt);
++ /* try to read one byte */
++ writew (1, (i2c_base + I2C_CNT_OFS));
+ /* set slave address */
+- writew(chip, &i2c_base->sa);
++ writew (chip, (i2c_base + I2C_SA_OFS));
+ /* stop bit needed here */
+- writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
+- I2C_CON_STP, &i2c_base->con);
+-
+- status = wait_for_pin();
+-
+- /* check for ACK (!NAK) */
+- if (!(status & I2C_STAT_NACK))
+- res = 0;
+-
+- /* abort transfer (force idle state) */
+- writew(0, &i2c_base->con);
+-
++ writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, (i2c_base + I2C_CON_OFS));
++ /* enough delay for the NACK bit set */
++ udelay (50000);
++
++ if (!(readw ((i2c_base + I2C_STAT_OFS)) & I2C_STAT_NACK)) {
++ res = 0; /* success case */
++ flush_fifo();
++ writew(0xFFFF, (i2c_base + I2C_STAT_OFS));
++ } else {
++ writew(0xFFFF, (i2c_base + I2C_STAT_OFS)); /* failue, clear sources*/
++ /* finish up xfer */
++ writew(readw((i2c_base + I2C_CON_OFS)) | I2C_CON_STP, (i2c_base + I2C_CON_OFS));
++ udelay(20000);
++ wait_for_bb();
++ status = wait_for_bb();
++
++ /* exiting on BUS busy */
++ if (status & I2C_TIMEOUT)
++ return res;
++ }
+ flush_fifo();
+- /* don't allow any more data in... we don't want it. */
+- writew(0, &i2c_base->cnt);
+- writew(0xFFFF, &i2c_base->stat);
++ /* don't allow any more data in...we don't want it.*/
++ writew(0, (i2c_base + I2C_CNT_OFS));
++ writew(0xFFFF, (i2c_base + I2C_STAT_OFS));
+ return res;
+ }
+
+ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+ {
+- int i;
++ int i2c_error = 0, i;
++ u32 status;
+
+- if (alen > 1) {
+- printf("I2C read: addr len %d not supported\n", alen);
++ if ((alen > 2) || (alen < 0)) {
+ return 1;
+ }
+
+- if (addr + len > 256) {
+- printf("I2C read: address out of range\n");
++ if (addr + len > 0xFFFF) {
+ return 1;
+ }
+
+- for (i = 0; i < len; i++) {
+- if (i2c_read_byte(chip, addr + i, &buffer[i])) {
+- printf("I2C read: I/O error\n");
+- i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+- return 1;
++ /* wait until bus not busy */
++ status = wait_for_bb();
++
++ /* exiting on BUS busy */
++ if (status & I2C_TIMEOUT)
++ return 1;
++
++ /* one byte only */
++ writew((alen & 0xFF), (i2c_base + I2C_CNT_OFS));
++ /* set slave address */
++ writew(chip, (i2c_base + I2C_SA_OFS));
++ /* Clear the Tx & Rx FIFOs */
++ writew((readw((i2c_base + I2C_BUF_OFS)) | I2C_RXFIFO_CLEAR | I2C_TXFIFO_CLEAR), (i2c_base + I2C_BUF_OFS));
++ /* no stop bit needed here */
++ writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_TRX | I2C_CON_STT, (i2c_base + I2C_CON_OFS));
++
++ /* waiting for Transmit ready condition */
++ status = wait_for_status_mask(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ if (status & (I2C_STAT_NACK | I2C_TIMEOUT))
++ i2c_error = 1;
++
++ if (!i2c_error) {
++ if (status & I2C_STAT_XRDY) {
++ switch (alen) {
++ case 2:
++ /* Send address MSByte */
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)\
++ || defined(CONFIG_TI81XX)
++ writew(((addr >> 8) & 0xFF), (i2c_base + I2C_DATA_OFS));
++
++ /* Clearing XRDY event */
++ writew((status & I2C_STAT_XRDY), (i2c_base + I2C_STAT_OFS));
++ /*waiting for Transmit ready * condition */
++ status = wait_for_status_mask(I2C_STAT_XRDY |
++ I2C_STAT_NACK);
++
++ if (status & (I2C_STAT_NACK |
++ I2C_TIMEOUT)) {
++ i2c_error = 1;
++ break;
++ }
++#else
++#endif
++ case 1:
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)\
++ || defined(CONFIG_TI81XX)
++ /* Send address LSByte */
++ writew((addr & 0xFF), (i2c_base + I2C_DATA_OFS));
++#else
++ /* Send address Short word */
++ writew((addr & 0xFFFF), (i2c_base + I2C_DATA_OFS));
++#endif
++ /* Clearing XRDY event */
++ writew((status & I2C_STAT_XRDY), (i2c_base + I2C_STAT_OFS));
++ /*waiting for Transmit ready * condition */
++ status = wait_for_status_mask(I2C_STAT_ARDY |
++ I2C_STAT_NACK);
++
++ if (status & (I2C_STAT_NACK |
++ I2C_TIMEOUT)) {
++ i2c_error = 1;
++ break;
++ }
++ }
++ } else
++ i2c_error = 1;
++ }
++
++ /* Waiting for ARDY to set */
++ status = wait_for_status_mask(I2C_STAT_ARDY | I2C_STAT_NACK
++ | I2C_STAT_AL);
++
++ if (!i2c_error) {
++ /* set slave address */
++ writew(chip, (i2c_base + I2C_SA_OFS));
++ /* read one byte from slave */
++ writew((len & 0xFF), (i2c_base + I2C_CNT_OFS));
++ /* Clear the Tx & Rx FIFOs */
++ writew((readw((i2c_base + I2C_BUF_OFS)) | I2C_RXFIFO_CLEAR |
++ I2C_TXFIFO_CLEAR), (i2c_base + I2C_BUF_OFS));
++ /* need stop bit here */
++ writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
++ (i2c_base + I2C_CON_OFS));
++
++ for (i = 0; i < len; i++) {
++ /* waiting for Receive condition */
++ status = wait_for_status_mask(I2C_STAT_RRDY |
++ I2C_STAT_NACK);
++
++ if (status & (I2C_STAT_NACK | I2C_TIMEOUT)) {
++ i2c_error = 1;
++ break;
++ }
++
++ if (status & I2C_STAT_RRDY) {
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) \
++ || defined(CONFIG_TI81XX)
++ buffer[i] = readb((i2c_base + I2C_DATA_OFS));
++#else
++ *((u16 *)&buffer[i]) = readw((i2c_base + I2C_DATA_OFS)) & 0xFFFF;
++ i++;
++#endif
++ writew((status & I2C_STAT_RRDY), (i2c_base + I2C_STAT_OFS));
++ udelay(1000);
++ } else {
++ i2c_error = 1;
++ }
+ }
+ }
+
++ /* Waiting for ARDY to set */
++ status = wait_for_status_mask(I2C_STAT_ARDY | I2C_STAT_NACK
++ | I2C_STAT_AL);
++
++ if (i2c_error) {
++ writew(0, (i2c_base + I2C_CON_OFS));
++ return 1;
++ }
++
++ if (!i2c_error) {
++ writew(I2C_CON_EN, (i2c_base + I2C_CON_OFS));
++
++ while (readw((i2c_base + I2C_STAT_OFS))
++ || (readw((i2c_base + I2C_CON_OFS)) & I2C_CON_MST)) {
++ udelay(10000);
++ writew(0xFFFF, (i2c_base + I2C_STAT_OFS));
++ }
++ }
++
++ writew(I2C_CON_EN, (i2c_base + I2C_CON_OFS));
++ flush_fifo();
++ writew(0xFFFF, (i2c_base + I2C_STAT_OFS));
++ writew(0, (i2c_base + I2C_CNT_OFS));
++
+ return 0;
+ }
+
+-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
++int i2c_write(uchar chip, uint addr, int alen,
++ uchar *buffer, int len)
+ {
+- int i;
+- u16 status;
+- int i2c_error = 0;
++ int i, i2c_error = 0;
++ u16 writelen;
++ u32 status;
+
+- if (alen > 1) {
+- printf("I2C write: addr len %d not supported\n", alen);
++ if (alen > 2) {
+ return 1;
+ }
+
+- if (addr + len > 256) {
+- printf("I2C write: address 0x%x + 0x%x out of range\n",
+- addr, len);
++ if (addr + len > 0xFFFF) {
+ return 1;
+ }
+
+ /* wait until bus not busy */
+- wait_for_bb();
++ status = wait_for_bb();
+
+- /* start address phase - will write regoffset + len bytes data */
+- /* TODO consider case when !CONFIG_OMAP243X/34XX/44XX */
+- writew(alen + len, &i2c_base->cnt);
++ /* exiting on BUS busy */
++ if (status & I2C_TIMEOUT)
++ return 1;
++
++ writelen = (len & 0xFFFF) + alen;
++
++ /* two bytes */
++ writew((writelen & 0xFFFF), (i2c_base + I2C_CNT_OFS));
++ /* Clear the Tx & Rx FIFOs */
++ writew((readw((i2c_base + I2C_BUF_OFS)) | I2C_RXFIFO_CLEAR | I2C_TXFIFO_CLEAR), (i2c_base + I2C_BUF_OFS));
+ /* set slave address */
+- writew(chip, &i2c_base->sa);
++ writew(chip, (i2c_base + I2C_SA_OFS));
+ /* stop bit needed here */
+ writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
+- I2C_CON_STP, &i2c_base->con);
++ I2C_CON_STP, (i2c_base + I2C_CON_OFS));
+
+- /* Send address byte */
+- status = wait_for_pin();
++ /* waiting for Transmit ready condition */
++ status = wait_for_status_mask(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+- if (status == 0 || status & I2C_STAT_NACK) {
++ if (status & (I2C_STAT_NACK | I2C_TIMEOUT))
+ i2c_error = 1;
+- printf("error waiting for i2c address ACK (status=0x%x)\n",
+- status);
+- goto write_exit;
++
++ if (!i2c_error) {
++ if (status & I2C_STAT_XRDY) {
++ switch (alen) {
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)\
++ || defined(CONFIG_TI81XX)
++ case 2:
++ /* send out MSB byte */
++ writeb(((addr >> 8) & 0xFF), (i2c_base + I2C_DATA_OFS));
++#else
++ writeb((addr & 0xFFFF), (i2c_base + I2C_DATA_OFS));
++ break;
++#endif
++ /* Clearing XRDY event */
++ writew((status & I2C_STAT_XRDY), (i2c_base + I2C_STAT_OFS));
++ /*waiting for Transmit ready * condition */
++ status = wait_for_status_mask(I2C_STAT_XRDY |
++ I2C_STAT_NACK);
++
++ if (status & (I2C_STAT_NACK | I2C_TIMEOUT)) {
++ i2c_error = 1;
++ break;
++ }
++ case 1:
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)\
++ || defined(CONFIG_TI81XX)
++ /* send out MSB byte */
++ writeb((addr & 0xFF), (i2c_base + I2C_DATA_OFS));
++#else
++ writew(((bufer[0] << 8) | (addr & 0xFF)),
++ (i2c_base + I2C_DATA_OFS));
++#endif
++ }
++
++ /* Clearing XRDY event */
++ writew((status & I2C_STAT_XRDY), (i2c_base + I2C_STAT_OFS));
++ }
++
++ /* waiting for Transmit ready condition */
++ status = wait_for_status_mask(I2C_STAT_XRDY | I2C_STAT_NACK);
++
++ if (status & (I2C_STAT_NACK | I2C_TIMEOUT))
++ i2c_error = 1;
++
++ if (!i2c_error) {
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) \
++ || defined(CONFIG_TI81XX)
++ for (i = 0; i < len; i++) {
++#else
++ for (i = ((alen > 1) ? 0 : 1); i < len; i++) {
++#endif
++ if (status & I2C_STAT_XRDY) {
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) \
++ || defined(CONFIG_TI81XX)
++ writeb((buffer[i] & 0xFF), (i2c_base + I2C_DATA_OFS));
++#else
++ writew((((bufer[i] << 8) | buffer[i + 1]) &
++ 0xFFFF) ,
++ (i2c_base + I2C_DATA_OFS));
++ i++;
++#endif
++ } else
++ i2c_error = 1;
++
++ /* Clearing XRDY event */
++ writew((status & I2C_STAT_XRDY),
++ (i2c_base + I2C_STAT_OFS));
++ /* waiting for XRDY condition */
++ status = wait_for_status_mask(
++ I2C_STAT_XRDY |
++ I2C_STAT_ARDY |
++ I2C_STAT_NACK);
++
++ if (status & (I2C_STAT_NACK | I2C_TIMEOUT)) {
++ i2c_error = 1;
++ break;
++ }
++
++ if (status & I2C_STAT_ARDY)
++ break;
++ }
++ }
++
+ }
+
+- if (status & I2C_STAT_XRDY) {
+- writeb(addr & 0xFF, &i2c_base->data);
+- writew(I2C_STAT_XRDY, &i2c_base->stat);
+- } else {
++ status = wait_for_status_mask(I2C_STAT_ARDY | I2C_STAT_NACK |
++ I2C_STAT_AL);
++
++ if (status & (I2C_STAT_NACK | I2C_TIMEOUT))
+ i2c_error = 1;
+- printf("i2c bus not ready for transmit (status=0x%x)\n",
+- status);
+- goto write_exit;
++
++ if (i2c_error) {
++ writew(0, (i2c_base + I2C_CON_OFS));
++ return 1;
+ }
+
+- /* address phase is over, now write data */
+- for (i = 0; i < len; i++) {
+- status = wait_for_pin();
++ if (!i2c_error) {
++ int eout = 200;
+
+- if (status == 0 || status & I2C_STAT_NACK) {
+- i2c_error = 1;
+- printf("i2c error waiting for data ACK (status=0x%x)\n",
+- status);
+- goto write_exit;
+- }
++ writew(I2C_CON_EN, (i2c_base + I2C_CON_OFS));
++ while ((status = readw((i2c_base + I2C_STAT_OFS))) ||
++ (readw((i2c_base + I2C_CON_OFS)) & I2C_CON_MST)) {
++ udelay(1000);
++ /* have to read to clear intrrupt */
++ writew(0xFFFF, (i2c_base + I2C_STAT_OFS));
+
+- if (status & I2C_STAT_XRDY) {
+- writeb(buffer[i], &i2c_base->data);
+- writew(I2C_STAT_XRDY, &i2c_base->stat);
+- } else {
+- i2c_error = 1;
+- printf("i2c bus not ready for Tx (i=%d)\n", i);
+- goto write_exit;
++ if (--eout == 0)
++ /* better leave with error than hang */
++ break;
+ }
+ }
+
+-write_exit:
+ flush_fifo();
+- writew(0xFFFF, &i2c_base->stat);
+- return i2c_error;
++ writew(0xFFFF, (i2c_base + I2C_STAT_OFS));
++ writew(0, (i2c_base + I2C_CNT_OFS));
++ return 0;
+ }
+
+-static void wait_for_bb(void)
++static u32 wait_for_bb (void)
+ {
+- int timeout = I2C_TIMEOUT;
+- u16 stat;
++ int timeout = 10;
++ u32 stat;
+
+- writew(0xFFFF, &i2c_base->stat); /* clear current interrupts...*/
+- while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
+- writew(stat, &i2c_base->stat);
+- udelay(1000);
++ writew(0xFFFF, (i2c_base + I2C_STAT_OFS)); /* clear current interruts...*/
++ while ((stat = readw ((i2c_base + I2C_STAT_OFS)) & I2C_STAT_BB) && timeout--) {
++ writew (stat, (i2c_base + I2C_STAT_OFS));
++ udelay (50000);
+ }
+
+ if (timeout <= 0) {
+- printf("timed out in wait_for_bb: I2C_STAT=%x\n",
+- readw(&i2c_base->stat));
++ stat |= I2C_TIMEOUT;
+ }
+- writew(0xFFFF, &i2c_base->stat); /* clear delayed stuff*/
++ writew(0xFFFF, (i2c_base + I2C_STAT_OFS)); /* clear delayed stuff*/
++ return stat;
+ }
+
+-static u16 wait_for_pin(void)
++static u32 wait_for_status_mask(u16 mask)
+ {
+- u16 status;
+- int timeout = I2C_TIMEOUT;
++ u32 status;
++ int timeout = 10;
+
+ do {
+ udelay(1000);
+- status = readw(&i2c_base->stat);
+- } while (!(status &
+- (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
+- I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
+- I2C_STAT_AL)) && timeout--);
++ status = readw((i2c_base + I2C_STAT_OFS));
++ } while (!(status & mask) && timeout--);
+
+ if (timeout <= 0) {
+- printf("timed out in wait_for_pin: I2C_STAT=%x\n",
+- readw(&i2c_base->stat));
+- writew(0xFFFF, &i2c_base->stat);
+- status = 0;
++ writew(0xFFFF, (i2c_base + I2C_STAT_OFS));
++ status |= I2C_TIMEOUT;
+ }
+-
+ return status;
+ }
+
++#if defined(CONFIG_I2C_MULTI_BUS)
++/*
++* Functions for multiple I2C bus handling
++*/
++
++/**
++* i2c_get_bus_num - returns index of active I2C bus
++*/
++unsigned int i2c_get_bus_num(void)
++{
++ return current_bus;
++}
++
++/**
++* i2c_set_bus_num - change active I2C bus
++* @bus: bus index, zero based
++* @returns: 0 on success, non-0 on failure
++*/
+ int i2c_set_bus_num(unsigned int bus)
+ {
+ if ((bus < 0) || (bus >= I2C_BUS_MAX)) {
+- printf("Bad bus: %d\n", bus);
+ return -1;
+ }
+
+ #if I2C_BUS_MAX == 3
+ if (bus == 2)
+- i2c_base = (struct i2c *)I2C_BASE3;
++ i2c_base = (u32)I2C_BASE3;
+ else
+ #endif
+ if (bus == 1)
+- i2c_base = (struct i2c *)I2C_BASE2;
++ i2c_base = (u32)I2C_BASE2;
+ else
+- i2c_base = (struct i2c *)I2C_BASE1;
++ i2c_base = (u32)I2C_BASE1;
+
+ current_bus = bus;
+
+@@ -440,8 +590,4 @@ int i2c_set_bus_num(unsigned int bus)
+
+ return 0;
+ }
+-
+-int i2c_get_bus_num(void)
+-{
+- return (int) current_bus;
+-}
++#endif
+diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
+index ef12ecd..06b39c4 100644
+--- a/drivers/mmc/omap_hsmmc.c
++++ b/drivers/mmc/omap_hsmmc.c
+@@ -450,12 +450,16 @@ int omap_mmc_init(int dev_index)
+ case 0:
+ mmc->priv = (hsmmc_t *)OMAP_HSMMC1_BASE;
+ break;
++#ifdef OMAP_HSMMC2_BASE
+ case 1:
+ mmc->priv = (hsmmc_t *)OMAP_HSMMC2_BASE;
+ break;
++#endif
++#ifdef OMAP_HSMMC3_BASE
+ case 2:
+ mmc->priv = (hsmmc_t *)OMAP_HSMMC3_BASE;
+ break;
++#endif
+ default:
+ mmc->priv = (hsmmc_t *)OMAP_HSMMC1_BASE;
+ return 1;
+diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
+index 8b598f6..b324acf 100644
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -26,12 +26,18 @@ include $(TOPDIR)/config.mk
+ LIB := $(obj)libnand.o
+
+ ifdef CONFIG_CMD_NAND
++ifdef CONFIG_SPL_BUILD
++ifdef CONFIG_SPL_NAND_SIMPLE
++COBJS-y += nand_spl_simple.o
++endif
++else
+ COBJS-y += nand.o
+-COBJS-y += nand_base.o
+ COBJS-y += nand_bbt.o
+-COBJS-y += nand_ecc.o
+ COBJS-y += nand_ids.o
+ COBJS-y += nand_util.o
++endif
++COBJS-y += nand_ecc.o
++COBJS-y += nand_base.o
+
+ COBJS-$(CONFIG_NAND_ATMEL) += atmel_nand.o
+ COBJS-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o
+@@ -48,8 +54,9 @@ COBJS-$(CONFIG_NAND_NOMADIK) += nomadik.o
+ COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
+ COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
+ COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
+-COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
++COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_bch_decoder.o omap_gpmc.o omap_bch_soft.o
+ COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
++COBJS-$(CONFIG_NAND_TI81XX) += ti81xx_nand.o
+ endif
+
+ COBJS := $(COBJS-y)
+diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
+index 1a95a91..75a7ca2 100644
+--- a/drivers/mtd/nand/nand_base.c
++++ b/drivers/mtd/nand/nand_base.c
+@@ -44,6 +44,10 @@
+ #include <linux/mtd/nand.h>
+ #include <linux/mtd/nand_ecc.h>
+
++#if !defined(CONFIG_TI81XX)
++#include <asm/arch/omap_bch_soft.h>
++#endif
++
+ #ifdef CONFIG_MTD_PARTITIONS
+ #include <linux/mtd/partitions.h>
+ #endif
+@@ -213,7 +217,7 @@ static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+ *
+ * Default read function for 8bit buswith
+ */
+-static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
++void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+ {
+ int i;
+ struct nand_chip *chip = mtd->priv;
+@@ -269,7 +273,7 @@ static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
+ *
+ * Default read function for 16bit buswith
+ */
+-static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
++void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
+ {
+ int i;
+ struct nand_chip *chip = mtd->priv;
+@@ -2749,6 +2753,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
+ */
+ int nand_scan_tail(struct mtd_info *mtd)
+ {
++ uint32_t dev_width;
+ int i;
+ struct nand_chip *chip = mtd->priv;
+
+@@ -2760,6 +2765,8 @@ int nand_scan_tail(struct mtd_info *mtd)
+ /* Set the internal oob buffer location, just after the page data */
+ chip->oob_poi = chip->buffers->databuf + mtd->writesize;
+
++ dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
++
+ /*
+ * If no default placement scheme is given, select an appropriate one
+ */
+@@ -2864,6 +2871,47 @@ int nand_scan_tail(struct mtd_info *mtd)
+ chip->ecc.bytes = 3;
+ break;
+
++#if !defined(CONFIG_TI81XX)
++ case NAND_ECC_4BIT_SOFT:
++ /* Use standard hwecc read page function */
++ if (!chip->ecc.read_page)
++ chip->ecc.read_page = nand_read_page_hwecc;
++ if (!chip->ecc.write_page)
++ chip->ecc.write_page = nand_write_page_hwecc;
++ if (!chip->ecc.read_oob)
++ chip->ecc.read_oob = nand_read_oob_std;
++ if (!chip->ecc.write_oob)
++ chip->ecc.write_oob = nand_write_oob_std;
++ chip->ecc.size = 2048;
++ chip->ecc.bytes = 28;
++ chip->ecc.hwctl = omap_enable_hwecc_bch4;
++ chip->ecc.calculate = omap_calculate_ecc_bch4;
++ chip->ecc.correct = omap_correct_data_bch4;
++ chip->ecc.layout = omap_get_ecc_layout_bch(dev_width, 4);
++ omap_hwecc_init_bch(chip);
++ break;
++
++ case NAND_ECC_8BIT_SOFT:
++ /* Use standard hwecc read page function */
++ if (!chip->ecc.read_page)
++ chip->ecc.read_page = nand_read_page_hwecc;
++ if (!chip->ecc.write_page)
++ chip->ecc.write_page = nand_write_page_hwecc;
++ if (!chip->ecc.read_oob)
++ chip->ecc.read_oob = nand_read_oob_std;
++ if (!chip->ecc.write_oob)
++ chip->ecc.write_oob = nand_write_oob_std;
++ chip->ecc.size = 2048;
++ chip->ecc.bytes = 52;
++ chip->ecc.hwctl = omap_enable_hwecc_bch8;
++ chip->ecc.calculate = omap_calculate_ecc_bch8;
++ chip->ecc.correct = omap_correct_data_bch8;
++ chip->ecc.layout = omap_get_ecc_layout_bch(dev_width, 8);
++ omap_hwecc_init_bch(chip);
++
++ break;
++#endif
++
+ case NAND_ECC_NONE:
+ printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "
+ "This is not recommended !!\n");
+diff --git a/drivers/mtd/nand/nand_spl_simple.c b/drivers/mtd/nand/nand_spl_simple.c
+new file mode 100644
+index 0000000..71491d4
+--- /dev/null
++++ b/drivers/mtd/nand/nand_spl_simple.c
+@@ -0,0 +1,245 @@
++/*
++ * (C) Copyright 2006-2008
++ * Stefan Roese, DENX Software Engineering, sr@denx.de.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <nand.h>
++#include <asm/io.h>
++
++static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
++static nand_info_t mtd;
++static struct nand_chip nand_chip;
++
++#if (CONFIG_SYS_NAND_PAGE_SIZE <= 512)
++/*
++ * NAND command for small page NAND devices (512)
++ */
++static int nand_command(int block, int page, uint32_t offs,
++ u8 cmd)
++{
++ struct nand_chip *this = mtd.priv;
++ int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
++
++ while (!this->dev_ready(&mtd))
++ ;
++
++ /* Begin command latch cycle */
++ this->cmd_ctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
++ /* Set ALE and clear CLE to start address cycle */
++ /* Column address */
++ this->cmd_ctrl(&mtd, offs, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
++ this->cmd_ctrl(&mtd, page_addr & 0xff, NAND_CTRL_ALE); /* A[16:9] */
++ this->cmd_ctrl(&mtd, (page_addr >> 8) & 0xff,
++ NAND_CTRL_ALE); /* A[24:17] */
++#ifdef CONFIG_SYS_NAND_4_ADDR_CYCLE
++ /* One more address cycle for devices > 32MiB */
++ this->cmd_ctrl(&mtd, (page_addr >> 16) & 0x0f,
++ NAND_CTRL_ALE); /* A[28:25] */
++#endif
++ /* Latch in address */
++ this->cmd_ctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
++
++ /*
++ * Wait a while for the data to be ready
++ */
++ while (!this->dev_ready(&mtd))
++ ;
++
++ return 0;
++}
++#else
++/*
++ * NAND command for large page NAND devices (2k)
++ */
++static int nand_command(int block, int page, uint32_t offs,
++ u8 cmd)
++{
++ struct nand_chip *this = mtd.priv;
++ int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
++ void (*hwctrl)(struct mtd_info *mtd, int cmd,
++ unsigned int ctrl) = this->cmd_ctrl;
++
++ while (!this->dev_ready(&mtd))
++ ;
++
++ /* Emulate NAND_CMD_READOOB */
++ if (cmd == NAND_CMD_READOOB) {
++ offs += CONFIG_SYS_NAND_PAGE_SIZE;
++ cmd = NAND_CMD_READ0;
++ }
++
++ /* Shift the offset from byte addressing to word addressing. */
++ if (this->options & NAND_BUSWIDTH_16)
++ offs >>= 1;
++
++ /* Begin command latch cycle */
++ hwctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
++ /* Set ALE and clear CLE to start address cycle */
++ /* Column address */
++ hwctrl(&mtd, offs & 0xff,
++ NAND_CTRL_ALE | NAND_CTRL_CHANGE); /* A[7:0] */
++ hwctrl(&mtd, (offs >> 8) & 0xff, NAND_CTRL_ALE); /* A[11:9] */
++ /* Row address */
++ hwctrl(&mtd, (page_addr & 0xff), NAND_CTRL_ALE); /* A[19:12] */
++ hwctrl(&mtd, ((page_addr >> 8) & 0xff),
++ NAND_CTRL_ALE); /* A[27:20] */
++#ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE
++ /* One more address cycle for devices > 128MiB */
++ hwctrl(&mtd, (page_addr >> 16) & 0x0f,
++ NAND_CTRL_ALE); /* A[31:28] */
++#endif
++ /* Latch in address */
++ hwctrl(&mtd, NAND_CMD_READSTART,
++ NAND_CTRL_CLE | NAND_CTRL_CHANGE);
++ hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
++
++ /*
++ * Wait a while for the data to be ready
++ */
++ while (!this->dev_ready(&mtd))
++ ;
++
++ return 0;
++}
++#endif
++
++static int nand_is_bad_block(int block)
++{
++ struct nand_chip *this = mtd.priv;
++
++ nand_command(block, 0, CONFIG_SYS_NAND_BAD_BLOCK_POS,
++ NAND_CMD_READOOB);
++
++ /*
++ * Read one byte (or two if it's a 16 bit chip).
++ */
++ if (this->options & NAND_BUSWIDTH_16) {
++ if (readw(this->IO_ADDR_R) != 0xffff)
++ return 1;
++ } else {
++ if (readb(this->IO_ADDR_R) != 0xff)
++ return 1;
++ }
++
++ return 0;
++}
++
++static int nand_read_page(int block, int page, void *dst)
++{
++ struct nand_chip *this = mtd.priv;
++ u_char *ecc_calc;
++ u_char *ecc_code;
++ u_char *oob_data;
++ int i;
++ int eccsize = CONFIG_SYS_NAND_ECCSIZE;
++ int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
++ int eccsteps = CONFIG_SYS_NAND_ECCSTEPS;
++ uint8_t *p = dst;
++ int stat;
++
++ nand_command(block, page, 0, NAND_CMD_READ0);
++
++ /* No malloc available for now, just use some temporary locations
++ * in SDRAM
++ */
++ ecc_calc = (u_char *)(CONFIG_SYS_SDRAM_BASE + 0x10000);
++ ecc_code = ecc_calc + 0x100;
++ oob_data = ecc_calc + 0x200;
++
++ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
++ this->ecc.hwctl(&mtd, NAND_ECC_READ);
++ this->read_buf(&mtd, p, eccsize);
++ this->ecc.calculate(&mtd, p, &ecc_calc[i]);
++ }
++ this->read_buf(&mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE);
++
++ /* Pick the ECC bytes out of the oob data */
++ for (i = 0; i < CONFIG_SYS_NAND_ECCTOTAL; i++)
++ ecc_code[i] = oob_data[nand_ecc_pos[i]];
++
++ eccsteps = CONFIG_SYS_NAND_ECCSTEPS;
++ p = dst;
++
++ for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
++ /* No chance to do something with the possible error message
++ * from correct_data(). We just hope that all possible errors
++ * are corrected by this routine.
++ */
++ stat = this->ecc.correct(&mtd, p, &ecc_code[i], &ecc_calc[i]);
++ }
++
++ return 0;
++}
++
++int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
++{
++ unsigned int block, lastblock;
++ unsigned int page;
++
++ /*
++ * offs has to be aligned to a page address!
++ */
++ block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
++ lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
++ page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
++
++ while (block <= lastblock) {
++ if (!nand_is_bad_block(block)) {
++ /*
++ * Skip bad blocks
++ */
++ while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
++ nand_read_page(block, page, dst);
++ dst += CONFIG_SYS_NAND_PAGE_SIZE;
++ page++;
++ }
++
++ page = 0;
++ } else {
++ lastblock++;
++ }
++
++ block++;
++ }
++
++ return 0;
++}
++
++/* nand_init() - initialize data to make nand usable by SPL */
++void nand_init(void)
++{
++ /*
++ * Init board specific nand support
++ */
++ mtd.priv = &nand_chip;
++ nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W =
++ (void __iomem *)CONFIG_SYS_NAND_BASE;
++ nand_chip.options = 0;
++ board_nand_init(&nand_chip);
++
++ if (nand_chip.select_chip)
++ nand_chip.select_chip(&mtd, 0);
++}
++
++/* Unselect after operation */
++void nand_deselect(void)
++{
++ if (nand_chip.select_chip)
++ nand_chip.select_chip(&mtd, -1);
++}
+diff --git a/drivers/mtd/nand/omap_bch_decoder.c b/drivers/mtd/nand/omap_bch_decoder.c
+new file mode 100644
+index 0000000..fdfefd2
+--- /dev/null
++++ b/drivers/mtd/nand/omap_bch_decoder.c
+@@ -0,0 +1,398 @@
++/*
++ * lib/omap_bch_decoder.c
++ *
++ * Whole BCH ECC Decoder (Post hardware generated syndrome decoding)
++ *
++ * Copyright (c) 2007 Texas Instruments
++ *
++ * Author: Sukumar Ghorai <s-ghorai@ti.com
++ * Michael Fillinger <m-fillinger@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#define printk //printf
++
++#define mm 13
++#define kk_shorten 4096
++#define nn 8191 /* Length of codeword, n = 2**mm - 1 */
++
++#define PPP 0x201B /* Primary Polynomial : x^13 + x^4 + x^3 + x + 1 */
++#define P 0x001B /* With omitted x^13 */
++#define POLY 12 /* degree of the primary Polynomial less one */
++
++/**
++ * mpy_mod_gf - GALOIS field multiplier
++ * Input : A(x), B(x)
++ * Output : A(x)*B(x) mod P(x)
++ */
++static unsigned int mpy_mod_gf(unsigned int a, unsigned int b)
++{
++ unsigned int R = 0;
++ unsigned int R1 = 0;
++ unsigned int k = 0;
++
++ for (k = 0; k < mm; k++) {
++
++ R = (R << 1) & 0x1FFE;
++ if (R1 == 1)
++ R ^= P;
++
++ if (((a >> (POLY - k)) & 1) == 1)
++ R ^= b;
++
++ if (k < POLY)
++ R1 = (R >> POLY) & 1;
++ }
++ return R;
++}
++
++/**
++ * chien - CHIEN search
++ *
++ * @location - Error location vector pointer
++ *
++ * Inputs : ELP(z)
++ * No. of found errors
++ * Size of input codeword
++ * Outputs : Up to 8 locations
++ * No. of errors
++ */
++static int chien(unsigned int select_4_8, int err_nums,
++ unsigned int err[], unsigned int *location)
++{
++ int i, count; /* Number of dectected errors */
++ /* Contains accumulation of evaluation at x^i (i:1->8) */
++ unsigned int gammas[8] = {0};
++ unsigned int alpha;
++ unsigned int bit, ecc_bits;
++ unsigned int elp_sum;
++
++ ecc_bits = (select_4_8 == 0) ? 52 : 104;
++
++ /* Start evaluation at Alpha**8192 and decreasing */
++ for (i = 0; i < 8; i++)
++ gammas[i] = err[i];
++
++ count = 0;
++ for (i = 1; (i <= nn) && (count < err_nums); i++) {
++
++ /* Result of evaluation at root */
++ elp_sum = 1 ^ gammas[0] ^ gammas[1] ^
++ gammas[2] ^ gammas[3] ^
++ gammas[4] ^ gammas[5] ^
++ gammas[6] ^ gammas[7];
++
++ alpha = PPP >> 1;
++ gammas[0] = mpy_mod_gf(gammas[0], alpha);
++ alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-2 */
++ gammas[1] = mpy_mod_gf(gammas[1], alpha);
++ alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-2 */
++ gammas[2] = mpy_mod_gf(gammas[2], alpha);
++ alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-3 */
++ gammas[3] = mpy_mod_gf(gammas[3], alpha);
++ alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-4 */
++ gammas[4] = mpy_mod_gf(gammas[4], alpha);
++ alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-5 */
++ gammas[5] = mpy_mod_gf(gammas[5], alpha);
++ alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-6 */
++ gammas[6] = mpy_mod_gf(gammas[6], alpha);
++ alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-7 */
++ gammas[7] = mpy_mod_gf(gammas[7], alpha);
++
++ if (elp_sum == 0) {
++ /* calculate location */
++ bit = ((i-1) & ~7)|(7-((i-1) & 7));
++ if ((select_4_8 == 0) && (i >= 2 * ecc_bits)) {
++ location[count++] = kk_shorten - (bit - 2 * ecc_bits) - 1;
++ } else if ((select_4_8 == 1) && (i >= 2 * ecc_bits)) {
++ location[count++] = kk_shorten - (bit - 2 * ecc_bits) - 1;
++ }
++ }
++ }
++
++ /* Failure: No. of detected errors != No. or corrected errors */
++ if (count != err_nums) {
++ count = -1;
++ /* printk(KERN_INFO "BCH decoding failed\n");*/
++ }
++ /*
++ for (i = 0; i < count; i++)
++ printk(KERN_INFO "%d ", location[i]);
++ */
++ return count;
++}
++
++/* synd : 16 Syndromes
++ * return: gamaas - Coefficients to the error polynomial
++ * return: : Number of detected errors
++*/
++static unsigned int berlekamp(unsigned int select_4_8,
++ unsigned int synd[], unsigned int err[])
++{
++ int loop, iteration;
++ unsigned int LL = 0; /* Detected errors */
++ unsigned int d = 0; /* Distance between Syndromes and ELP[n](z) */
++ unsigned int invd = 0; /* Inverse of d */
++ /* Intermediate ELP[n](z).
++ * Final ELP[n](z) is Error Location Polynomial
++ */
++ unsigned int gammas[16] = {0};
++ /* Intermediate normalized ELP[n](z) : D[n](z) */
++ unsigned int D[16] = {0};
++ /* Temporary value that holds an ELP[n](z) coefficient */
++ unsigned int next_gamma = 0;
++
++ int e = 0;
++ unsigned int sign = 0;
++ unsigned int u = 0;
++ unsigned int v = 0;
++ unsigned int C1 = 0, C2 = 0;
++ unsigned int ss = 0;
++ unsigned int tmp_v = 0, tmp_s = 0;
++ unsigned int tmp_poly;
++
++ /*-------------- Step 0 ------------------*/
++ for (loop = 0; loop < 16; loop++)
++ gammas[loop] = 0;
++ gammas[0] = 1;
++ D[1] = 1;
++
++ iteration = 0;
++ LL = 0;
++ while ((iteration < ((select_4_8+1)*2*4)) &&
++ (LL <= ((select_4_8+1)*4))) {
++
++ /*printk(KERN_INFO "\nIteration.............%d\n", iteration);*/
++ d = 0;
++ /* Step: 0 */
++ for (loop = 0; loop <= LL; loop++) {
++ tmp_poly = mpy_mod_gf(
++ gammas[loop], synd[iteration - loop]);
++ d ^= tmp_poly;
++ /*printk(KERN_INFO "%02d. s=0 LL=%x poly %x\n",
++ loop, LL, tmp_poly);*/
++ }
++
++ /* Step 1: 1 cycle only to perform inversion */
++ v = d << 1;
++ e = -1;
++ sign = 1;
++ ss = 0x2000;
++ invd = 0;
++ u = PPP;
++ for (loop = 0; (d != 0) && (loop <= (2 * POLY)); loop++) {
++ /*printk(KERN_INFO "%02d. s=1 LL=%x poly NULL\n",
++ loop, LL);*/
++ C1 = (v >> 13) & 1;
++ C2 = C1 & sign;
++
++ sign ^= C2 ^ (e == 0);
++
++ tmp_v = v;
++ tmp_s = ss;
++
++ if (C1 == 1) {
++ v ^= u;
++ ss ^= invd;
++ }
++ v = (v << 1) & 0x3FFF;
++ if (C2 == 1) {
++ u = tmp_v;
++ invd = tmp_s;
++ e = -e;
++ }
++ invd >>= 1;
++ e--;
++ }
++
++ for (loop = 0; (d != 0) && (loop <= (iteration + 1)); loop++) {
++ /* Step 2
++ * Interleaved with Step 3, if L<(n-k)
++ * invd: Update of ELP[n](z) = ELP[n-1](z) - d.D[n-1](z)
++ */
++
++ /* Holds value of ELP coefficient until precedent
++ * value does not have to be used anymore
++ */
++ tmp_poly = mpy_mod_gf(d, D[loop]);
++ /*printk(KERN_INFO "%02d. s=2 LL=%x poly %x\n",
++ loop, LL, tmp_poly);*/
++
++ next_gamma = gammas[loop] ^ tmp_poly;
++ if ((2 * LL) < (iteration + 1)) {
++ /* Interleaving with Step 3
++ * for parallelized update of ELP(z) and D(z)
++ */
++ } else {
++ /* Update of ELP(z) only -> stay in Step 2 */
++ gammas[loop] = next_gamma;
++ if (loop == (iteration + 1)) {
++ /* to step 4 */
++ break;
++ }
++ }
++
++ /* Step 3
++ * Always interleaved with Step 2 (case when L<(n-k))
++ * Update of D[n-1](z) = ELP[n-1](z)/d
++ */
++ D[loop] = mpy_mod_gf(gammas[loop], invd);
++ /*printk(KERN_INFO "%02d. s=3 LL=%x poly %x\n",
++ loop, LL, D[loop]);*/
++
++ /* Can safely update ELP[n](z) */
++ gammas[loop] = next_gamma;
++
++ if (loop == (iteration + 1)) {
++ /* If update finished */
++ LL = iteration - LL + 1;
++ /* to step 4 */
++ break;
++ }
++ /* Else, interleaving to step 2*/
++ }
++
++ /* Step 4: Update D(z): i:0->L */
++ /* Final update of D[n](z) = D[n](z).z*/
++ for (loop = 0; loop < 15; loop++) /* Left Shift */
++ D[15 - loop] = D[14 - loop];
++
++ D[0] = 0;
++
++ iteration++;
++ } /* while */
++
++ /* Processing finished, copy ELP to final registers : 0->2t-1*/
++ for (loop = 0; loop < 8; loop++)
++ err[loop] = gammas[loop+1];
++
++ /*printk(KERN_INFO "\n Err poly:");
++ for (loop = 0; loop < 8; loop++)
++ printk(KERN_INFO "0x%x ", err[loop]);
++ */
++ return LL;
++}
++
++/*
++ * syndrome - Generate syndrome components from hw generate syndrome
++ * r(x) = c(x) + e(x)
++ * s(x) = c(x) mod g(x) + e(x) mod g(x) = e(x) mod g(x)
++ * so receiver checks if the syndrome s(x) = r(x) mod g(x) is equal to zero.
++ * unsigned int s[16]; - Syndromes
++ */
++static void syndrome(unsigned int select_4_8,
++ unsigned char *ecc, unsigned int syn[])
++{
++ unsigned int k, l, t;
++ unsigned int alpha_bit, R_bit;
++ int ecc_pos, ecc_min;
++
++ /* 2t-1 = 15 (for t=8) minimal polynomials of the first 15 powers of a
++ * primitive elemmants of GF(m); Even powers minimal polynomials are
++ * duplicate of odd powers' minimal polynomials.
++ * Odd powers of alpha (1 to 15)
++ */
++ unsigned int pow_alpha[8] = {0x0002, 0x0008, 0x0020, 0x0080,
++ 0x0200, 0x0800, 0x001B, 0x006C};
++
++ /*printk(KERN_INFO "\n ECC[0..n]: ");
++ for (k = 0; k < 13; k++)
++ printk(KERN_INFO "0x%x ", ecc[k]);
++ */
++
++ if (select_4_8 == 0) {
++ t = 4;
++ ecc_pos = 55; /* bits(52-bits): 55->4 */
++ ecc_min = 4;
++ } else {
++ t = 8;
++ ecc_pos = 103; /* bits: 103->0 */
++ ecc_min = 0;
++ }
++
++ /* total numbber of syndrom to be used is 2t */
++ /* Step1: calculate the odd syndrome(s) */
++ R_bit = ((ecc[ecc_pos/8] >> (7 - ecc_pos%8)) & 1);
++ ecc_pos--;
++ for (k = 0; k < t; k++)
++ syn[2 * k] = R_bit;
++
++ while (ecc_pos >= ecc_min) {
++ R_bit = ((ecc[ecc_pos/8] >> (7 - ecc_pos%8)) & 1);
++ ecc_pos--;
++
++ for (k = 0; k < t; k++) {
++ /* Accumulate value of x^i at alpha^(2k+1) */
++ if (R_bit == 1)
++ syn[2*k] ^= pow_alpha[k];
++
++ /* Compute a**(2k+1), using LSFR */
++ for (l = 0; l < (2 * k + 1); l++) {
++ alpha_bit = (pow_alpha[k] >> POLY) & 1;
++ pow_alpha[k] = (pow_alpha[k] << 1) & 0x1FFF;
++ if (alpha_bit == 1)
++ pow_alpha[k] ^= P;
++ }
++ }
++ }
++
++ /* Step2: calculate the even syndrome(s)
++ * Compute S(a), where a is an even power of alpha
++ * Evenry even power of primitive element has the same minimal
++ * polynomial as some odd power of elemets.
++ * And based on S(a^2) = S^2(a)
++ */
++ for (k = 0; k < t; k++)
++ syn[2*k+1] = mpy_mod_gf(syn[k], syn[k]);
++
++ /*printk(KERN_INFO "\n Syndromes: ");
++ for (k = 0; k < 16; k++)
++ printk(KERN_INFO "0x%x ", syn[k]);*/
++}
++
++/**
++ * decode_bch - BCH decoder for 4- and 8-bit error correction
++ *
++ * @ecc - ECC syndrome generated by hw BCH engine
++ * @err_loc - pointer to error location array
++ *
++ * This function does post sydrome generation (hw generated) decoding
++ * for:-
++ * Dimension of Galoise Field: m = 13
++ * Length of codeword: n = 2**m - 1
++ * Number of errors that can be corrected: 4- or 8-bits
++ * Length of information bit: kk = nn - rr
++ */
++int decode_bch(int select_4_8, unsigned char *ecc, unsigned int *err_loc)
++{
++ int no_of_err;
++ unsigned int syn[16] = {0,}; /* 16 Syndromes */
++ unsigned int err_poly[8] = {0,};
++ /* Coefficients to the error polynomial
++ * ELP(x) = 1 + err0.x + err1.x^2 + ... + err7.x^8
++ */
++
++ /* Decoting involes three steps
++ * 1. Compute the syndrom from teh received codeword,
++ * 2. Find the error location polynomial from a set of equations
++ * derived from the syndrome,
++ * 3. Use the error location polynomial to identify errants bits,
++ *
++ * And correcttion done by bit flips using error locaiton and expected
++ * to be outseide of this implementation.
++ */
++ syndrome(select_4_8, ecc, syn);
++ no_of_err = berlekamp(select_4_8, syn, err_poly);
++ if (no_of_err <= (4 << select_4_8))
++ no_of_err = chien(select_4_8, no_of_err, err_poly, err_loc);
++
++ return no_of_err;
++}
+diff --git a/drivers/mtd/nand/omap_bch_soft.c b/drivers/mtd/nand/omap_bch_soft.c
+new file mode 100644
+index 0000000..ac4848a
+--- /dev/null
++++ b/drivers/mtd/nand/omap_bch_soft.c
+@@ -0,0 +1,326 @@
++/*
++ * omap_bch_soft.c
++ *
++ * Support modules for BCH 4-bit/8-bit error correction.
++ *
++ * Copyright (C) {2011} Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <common.h>
++#include <asm/arch/omap_bch_soft.h>
++#include <asm/io.h>
++#include <asm/errno.h>
++#include <asm/arch/mem.h>
++#include <asm/arch/omap_gpmc.h>
++#include <linux/mtd/nand_ecc.h>
++
++#define GPMC_ECC_BCH_RESULT_0 0x240
++extern uint8_t cs;
++
++int decode_bch(int select_4_8, unsigned char *ecc, unsigned int *err_loc);
++
++/* bus_width : 0 for x8, 1 for x16 */
++static struct nand_ecclayout nand_bch_oob;
++struct nand_ecclayout *omap_get_ecc_layout_bch(int bus_width, int correct_bits)
++{
++ int offset, ecc_romcode = 0;
++ int i;
++
++ offset = (bus_width == 0) ? 1 : 2;
++
++ switch(correct_bits)
++ {
++ case 1: nand_bch_oob.eccbytes = 12; break;
++ case 4: nand_bch_oob.eccbytes = 28; break;
++ case 8: nand_bch_oob.eccbytes = 52; break;
++ default: return 0;
++ }
++
++ if (!ecc_romcode)
++ offset = (64 - nand_bch_oob.eccbytes);
++ else
++ offset = (bus_width == 0) ? 1 : 2;
++
++ for (i = 0; i < nand_bch_oob.eccbytes; i++)
++ nand_bch_oob.eccpos[i] = i + offset;
++
++ offset = (bus_width == 0) ? 1 : 2;
++ nand_bch_oob.oobfree->offset =
++ (ecc_romcode ? (nand_bch_oob.eccbytes + offset) : offset);
++ nand_bch_oob.oobfree->length = 64 - (nand_bch_oob.eccbytes + offset);
++
++ return &nand_bch_oob;
++};
++
++/*
++ * omap_hwecc_init - Initialize the Hardware ECC for NAND flash in
++ * GPMC controller
++ * @mtd: MTD device structure
++ *
++ */
++void omap_hwecc_init_bch(struct nand_chip *chip)
++{
++ /*
++ * Init ECC Control Register
++ * Clear all ECC | Enable Reg1
++ */
++ writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
++}
++
++/* Implementation for 4b/8b BCH correction. Pass either 4 or 8 into the
++ correct_bits parameter. */
++static int omap_correct_data_bch(int correct_bits, struct mtd_info *mtd,
++ uint8_t *dat, uint8_t *read_ecc,
++ uint8_t *calc_ecc)
++{
++ int i=0, blockCnt=4, j, eccflag, count, corrected=0;
++ int eccsize = (correct_bits == 8) ? 13 : 7;
++ int mode = (correct_bits == 8) ? 1 : 0;
++ unsigned int err_loc[8];
++
++ if (correct_bits == 4)
++ omap_calculate_ecc_bch4(mtd, dat, calc_ecc);
++ else if (correct_bits == 8)
++ omap_calculate_ecc_bch8(mtd, dat, calc_ecc);
++ else
++ return -1; /* unsupported number of correction bits */
++
++ for (i = 0; i < blockCnt; i++) {
++ /* check if any ecc error */
++ eccflag = 0;
++ for (j = 0; (j < eccsize) && (eccflag == 0); j++)
++ if (calc_ecc[j] != 0)
++ eccflag = 1;
++
++ if (eccflag == 1) {
++ eccflag = 0;
++ for (j = 0; (j < eccsize) && (eccflag == 0); j++)
++ if (read_ecc[j] != 0xFF)
++ eccflag = 1;
++ }
++
++ if (eccflag == 1) {
++ /*printk(KERN_INFO "...bch correct(%d 512 byte)\n", i+1);*/
++ count = decode_bch(mode, calc_ecc, err_loc);
++
++ corrected += count;
++
++ for (j = 0; j < count; j++) {
++ /*printk(KERN_INFO "err_loc=%d\n", err_loc[j]);*/
++ printf("err_loc=%d\n", err_loc[j]);
++ if (err_loc[j] < 4096)
++ dat[err_loc[j] >> 3] ^= 1 << (err_loc[j] & 7);
++ /* else, not interested to correct ecc */
++ }
++
++ }
++
++ calc_ecc = calc_ecc + eccsize;
++ read_ecc = read_ecc + eccsize;
++ dat += 512;
++ }
++
++ return corrected;
++}
++
++/* Wrapper function for 4 bit BCH correction */
++int omap_correct_data_bch4(struct mtd_info *mtd, uint8_t *dat,
++ uint8_t *read_ecc, uint8_t *calc_ecc)
++{
++ return omap_correct_data_bch(4, mtd, dat, read_ecc, calc_ecc);
++}
++
++/* Wrapper function for 8 bit BCH correction */
++int omap_correct_data_bch8(struct mtd_info *mtd, uint8_t *dat,
++ uint8_t *read_ecc, uint8_t *calc_ecc)
++{
++ return omap_correct_data_bch(8, mtd, dat, read_ecc, calc_ecc);
++}
++
++/*
++ * omap_calculate_ecc_bch8 - Version for 8BIT BCH correction.
++ *
++ * @mtd: MTD structure
++ * @dat: unused
++ * @ecc_code: ecc_code buffer
++ */
++int omap_calculate_ecc_bch8(struct mtd_info *mtd, const uint8_t *dat,
++ uint8_t *ecc_code)
++{
++ struct nand_chip *nand = mtd->priv;
++ unsigned long reg, val1 = 0x0, val2 = 0x0;
++ unsigned long val3 = 0x0, val4 = 0x0;
++ int i;
++
++ for (i = 0; i < nand->ecc.size/512; i++) {
++ /* Reading HW ECC_BCH_Results
++ * 0x240-0x24C, 0x250-0x25C, 0x260-0x26C, 0x270-0x27C
++ */
++ reg = (unsigned long)(GPMC_BASE +
++ GPMC_ECC_BCH_RESULT_0 + (0x10 * i));
++ val1 = __raw_readl(reg);
++ val2 = __raw_readl(reg + 4);
++ val3 = __raw_readl(reg + 8);
++ val4 = __raw_readl(reg + 12);
++
++ *ecc_code++ = (val4 & 0xFF);
++ *ecc_code++ = ((val3 >> 24) & 0xFF);
++ *ecc_code++ = ((val3 >> 16) & 0xFF);
++ *ecc_code++ = ((val3 >> 8) & 0xFF);
++ *ecc_code++ = (val3 & 0xFF);
++ *ecc_code++ = ((val2 >> 24) & 0xFF);
++
++ *ecc_code++ = ((val2 >> 16) & 0xFF);
++ *ecc_code++ = ((val2 >> 8) & 0xFF);
++ *ecc_code++ = (val2 & 0xFF);
++ *ecc_code++ = ((val1 >> 24) & 0xFF);
++ *ecc_code++ = ((val1 >> 16) & 0xFF);
++ *ecc_code++ = ((val1 >> 8) & 0xFF);
++ *ecc_code++ = (val1 & 0xFF);
++ }
++ return 0;
++}
++
++/*
++ * omap_calculate_ecc_bch4 - Version for 4BIT BCH correction.
++ *
++ * @mtd: MTD structure
++ * @dat: unused
++ * @ecc_code: ecc_code buffer
++ */
++int omap_calculate_ecc_bch4(struct mtd_info *mtd, const uint8_t *dat,
++ uint8_t *ecc_code)
++{
++ struct nand_chip *nand = mtd->priv;
++ unsigned long reg, val1 = 0x0, val2 = 0x0;
++ int i;
++
++ for (i = 0; i < nand->ecc.size/512; i++) {
++ /* Reading HW ECC_BCH_Results
++ * 0x240-0x24C, 0x250-0x25C, 0x260-0x26C, 0x270-0x27C
++ */
++ reg = (unsigned long)(GPMC_BASE +
++ GPMC_ECC_BCH_RESULT_0 + (0x10 * i));
++ val1 = __raw_readl(reg);
++ val2 = __raw_readl(reg + 4);
++
++ *ecc_code++ = ((val2 >> 16) & 0xFF);
++ *ecc_code++ = ((val2 >> 8) & 0xFF);
++ *ecc_code++ = (val2 & 0xFF);
++ *ecc_code++ = ((val1 >> 24) & 0xFF);
++ *ecc_code++ = ((val1 >> 16) & 0xFF);
++ *ecc_code++ = ((val1 >> 8) & 0xFF);
++ *ecc_code++ = (val1 & 0xFF);
++ }
++ return 0;
++}
++
++/*
++ * omap_enable_ecc - This function enables the hardware ecc functionality
++ * @mtd: MTD device structure
++ * @mode: Read/Write mode
++ */
++void omap_enable_hwecc_bch4(struct mtd_info *mtd, int32_t mode)
++{
++ struct nand_chip *chip = mtd->priv;
++ uint32_t bch_mod=0;
++ uint32_t dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
++ unsigned int eccsize1, eccsize0;
++ unsigned int ecc_conf_val = 0, ecc_size_conf_val = 0;
++
++ switch (mode) {
++ case NAND_ECC_READ :
++ eccsize1 = 0xD; eccsize0 = 0x48;
++ /* ECCSIZE1=26 | ECCSIZE0=12 */
++ ecc_size_conf_val = (eccsize1 << 22) | (eccsize0 << 12);
++
++ /* ECCALGORITHM | ECCBCHT8 | ECCWRAPMODE | ECC16B |
++ * ECCTOPSECTOR | ECCCS | ECC Enable
++ */
++ ecc_conf_val = ((0x01 << 16) | (bch_mod << 12) | (0x09 << 8) |
++ (dev_width << 7) | (0x03 << 4) |
++ (cs << 1) | (0x1));
++ break;
++ case NAND_ECC_WRITE :
++ eccsize1 = 0x20; eccsize0 = 0x00;
++
++ /* ECCSIZE1=32 | ECCSIZE0=00 */
++ ecc_size_conf_val = (eccsize1 << 22) | (eccsize0 << 12);
++
++ /* ECCALGORITHM | ECCBCHT8 | ECCWRAPMODE | ECC16B |
++ * ECCTOPSECTOR | ECCCS | ECC Enable
++ */
++ ecc_conf_val = ((0x01 << 16) | (bch_mod << 12) | (0x06 << 8) |
++ (dev_width << 7) | (0x03 << 4) |
++ (cs << 1) | (0x1));
++ break;
++ default:
++ printf("Error: Unrecognized Mode[%d]!\n", mode);
++ break;
++ }
++
++ writel(0x1, &gpmc_cfg->ecc_control);
++ writel(ecc_size_conf_val, &gpmc_cfg->ecc_size_config);
++ writel(ecc_conf_val, &gpmc_cfg->ecc_config);
++ writel(0x101, &gpmc_cfg->ecc_control);
++}
++
++/*
++ * omap_enable_ecc - This function enables the hardware ecc functionality
++ * @mtd: MTD device structure
++ * @mode: Read/Write mode
++ */
++void omap_enable_hwecc_bch8(struct mtd_info *mtd, int32_t mode)
++{
++ struct nand_chip *chip = mtd->priv;
++ uint32_t bch_mod=1;
++ uint32_t dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
++ unsigned int eccsize1, eccsize0;
++ unsigned int ecc_conf_val = 0, ecc_size_conf_val = 0;
++
++ switch (mode) {
++ case NAND_ECC_READ :
++ eccsize1 = 0x1A; eccsize0 = 0x18;
++ /* ECCSIZE1=26 | ECCSIZE0=12 */
++ ecc_size_conf_val = (eccsize1 << 22) | (eccsize0 << 12);
++
++ /* ECCALGORITHM | ECCBCHT8 | ECCWRAPMODE | ECC16B |
++ * ECCTOPSECTOR | ECCCS | ECC Enable
++ */
++ ecc_conf_val = ((0x01 << 16) | (bch_mod << 12) | (0x04 << 8) |
++ (dev_width << 7) | (0x03 << 4) |
++ (cs << 1) | (0x1));
++ break;
++ case NAND_ECC_WRITE :
++ eccsize1 = 0x20; eccsize0 = 0x00;
++
++ /* ECCSIZE1=32 | ECCSIZE0=00 */
++ ecc_size_conf_val = (eccsize1 << 22) | (eccsize0 << 12);
++
++ /* ECCALGORITHM | ECCBCHT8 | ECCWRAPMODE | ECC16B |
++ * ECCTOPSECTOR | ECCCS | ECC Enable
++ */
++ ecc_conf_val = ((0x01 << 16) | (bch_mod << 12) | (0x06 << 8) |
++ (dev_width << 7) | (0x03 << 4) |
++ (cs << 1) | (0x1));
++ break;
++ default:
++ printf("Error: Unrecognized Mode[%d]!\n", mode);
++ break;
++ }
++
++ writel(0x1, &gpmc_cfg->ecc_control);
++ writel(ecc_size_conf_val, &gpmc_cfg->ecc_size_config);
++ writel(ecc_conf_val, &gpmc_cfg->ecc_config);
++ writel(0x101, &gpmc_cfg->ecc_control);
++}
++
+diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
+index 99b9cef..d381554 100644
+--- a/drivers/mtd/nand/omap_gpmc.c
++++ b/drivers/mtd/nand/omap_gpmc.c
+@@ -26,11 +26,15 @@
+ #include <asm/errno.h>
+ #include <asm/arch/mem.h>
+ #include <asm/arch/omap_gpmc.h>
++#include <asm/arch/omap_bch_soft.h>
+ #include <linux/mtd/nand_ecc.h>
+ #include <nand.h>
+
+-static uint8_t cs;
++uint8_t cs;
+ static struct nand_ecclayout hw_nand_oob = GPMC_NAND_HW_ECC_LAYOUT;
++#if defined(GPMC_NAND_ECC_LP_x16_LAYOUT) && !defined(CONFIG_SPL_BUILD)
++static struct nand_ecclayout hw_nand_oob_kernel = GPMC_NAND_HW_ECC_LAYOUT_KERNEL;
++#endif
+
+ /*
+ * omap_nand_hwcontrol - Set the address pointers corretly for the
+@@ -61,6 +65,14 @@ static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
+ writeb(cmd, this->IO_ADDR_W);
+ }
+
++#ifdef CONFIG_SPL_BUILD
++/* Check wait pin as dev ready indicator */
++int omap_spl_dev_ready(struct mtd_info *mtd)
++{
++ return gpmc_cfg->status & (1 << 8);
++}
++#endif
++
+ /*
+ * omap_hwecc_init - Initialize the Hardware ECC for NAND flash in
+ * GPMC controller
+@@ -224,23 +236,25 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
+ }
+ }
+
++#ifndef CONFIG_SPL_BUILD
+ /*
+ * omap_nand_switch_ecc - switch the ECC operation b/w h/w ecc and s/w ecc.
+ * The default is to come up on s/w ecc
+ *
+- * @hardware - 1 -switch to h/w ecc, 0 - s/w ecc
+- *
++ * @hardware - 1 -switch to 1-bit h/w ecc (kernel/FS layout),
++ * 2 -switch to 1-bit h/w ecc (xloader/uboot layout)
++ * (0 -default value)
+ */
+-void omap_nand_switch_ecc(int32_t hardware)
++void omap_nand_switch_ecc(nand_ecc_modes_t mode, int32_t hardware)
+ {
+ struct nand_chip *nand;
+ struct mtd_info *mtd;
++ uint32_t dev_width;
+
+ if (nand_curr_device < 0 ||
+- nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
+- !nand_info[nand_curr_device].name) {
+- printf("Error: Can't switch ecc, no devices available\n");
+- return;
++ nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE) {
++ printf("Error: Can't switch ecc, no devices available\n");
++ return;
+ }
+
+ mtd = &nand_info[nand_curr_device];
+@@ -257,29 +271,68 @@ void omap_nand_switch_ecc(int32_t hardware)
+ nand->ecc.correct = NULL;
+ nand->ecc.calculate = NULL;
+
+- /* Setup the ecc configurations again */
+- if (hardware) {
++ dev_width = (nand->options & NAND_BUSWIDTH_16) >> 1;
++
++ switch(mode)
++ {
++ case NAND_ECC_HW:
+ nand->ecc.mode = NAND_ECC_HW;
++#ifdef GPMC_NAND_ECC_LP_x16_LAYOUT
++ nand->ecc.layout = (hardware == 1) ? &hw_nand_oob_kernel : &hw_nand_oob;
++#else
+ nand->ecc.layout = &hw_nand_oob;
++#endif
++ nand->ecc.hwctl = omap_enable_hwecc;
+ nand->ecc.size = 512;
+ nand->ecc.bytes = 3;
+- nand->ecc.hwctl = omap_enable_hwecc;
+ nand->ecc.correct = omap_correct_data;
+ nand->ecc.calculate = omap_calculate_ecc;
+ omap_hwecc_init(nand);
++#ifdef GPMC_NAND_ECC_LP_x16_LAYOUT
++ printf("HW ECC [%s layout] selected\n",(hardware == 1) ? "Kernel/FS" : "X-loader/U-boot");
++#else
+ printf("HW ECC selected\n");
+- } else {
++#endif
++ break;
++ case NAND_ECC_SOFT:
+ nand->ecc.mode = NAND_ECC_SOFT;
+ /* Use mtd default settings */
+ nand->ecc.layout = NULL;
+ printf("SW ECC selected\n");
+- }
++ break;
++ case NAND_ECC_4BIT_SOFT:
++ nand->ecc.mode = mode;
++ nand->ecc.layout = omap_get_ecc_layout_bch(dev_width, 4);
++ nand->ecc.hwctl = omap_enable_hwecc_bch4;
++ nand->ecc.size = 2048;
++ nand->ecc.bytes = 28;
++ nand->ecc.calculate = omap_calculate_ecc_bch4;
++ nand->ecc.correct = omap_correct_data_bch4;
++ omap_hwecc_init_bch(nand);
++ printf("4 BIT SW ECC selected\n");
++ break;
++ case NAND_ECC_8BIT_SOFT:
++ nand->ecc.mode = mode;
++ nand->ecc.layout = omap_get_ecc_layout_bch(dev_width, 8);
++ nand->ecc.hwctl = omap_enable_hwecc_bch8;
++ nand->ecc.size = 2048;
++ nand->ecc.bytes = 52;
++ nand->ecc.calculate = omap_calculate_ecc_bch8;
++ nand->ecc.correct = omap_correct_data_bch8;
++ omap_hwecc_init_bch(nand);
++ printf("8 BIT SW ECC selected\n");
++ break;
++ default:
++ printf("Error: Unsupported ECC switch\n");
++ return;
++ }
+
+ /* Update NAND handling after ECC mode switch */
+ nand_scan_tail(mtd);
+
+ nand->options &= ~NAND_OWN_BUFFERS;
+ }
++#endif /* CONFIG_SPL_BUILD */
+
+ /*
+ * Board-specific NAND initialization. The following members of the
+@@ -309,17 +362,17 @@ int board_nand_init(struct nand_chip *nand)
+ * devices.
+ */
+ while (cs < GPMC_MAX_CS) {
+- /* Check if NAND type is set */
+- if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
+- /* Found it!! */
+- break;
+- }
+- cs++;
++ /* Check if NAND type is set */
++ if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
++ /* Found it!! */
++ break;
++ }
++ cs++;
+ }
+ if (cs >= GPMC_MAX_CS) {
+- printf("NAND: Unable to find NAND settings in "
+- "GPMC Configuration - quitting\n");
+- return -ENODEV;
++ printf("NAND: Unable to find NAND settings in "
++ "GPMC Configuration - quitting\n");
++ return -ENODEV;
+ }
+
+ gpmc_config = readl(&gpmc_cfg->config);
+@@ -334,11 +387,35 @@ int board_nand_init(struct nand_chip *nand)
+ nand->options = NAND_NO_PADDING | NAND_CACHEPRG | NAND_NO_AUTOINCR;
+ /* If we are 16 bit dev, our gpmc config tells us that */
+ if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000)
+- nand->options |= NAND_BUSWIDTH_16;
++ nand->options |= NAND_BUSWIDTH_16;
+
++ /* fallback ecc info, this will be overridden by
++ * ti81xx_nand_switch_ecc() below to 1-bit h/w ecc
++ */
+ nand->chip_delay = 100;
+ /* Default ECC mode */
+- nand->ecc.mode = NAND_ECC_SOFT;
++#ifndef CONFIG_SPL_BUILD
++ nand->ecc.mode = NAND_ECC_4BIT_SOFT;
++
++ /* Making 1-bit hw ecc (kernel/FS layout) as default ecc scheme */
++ nand_curr_device = 0;
++ omap_nand_switch_ecc(NAND_ECC_HW, 1);
++#else
++ nand->ecc.mode = NAND_ECC_HW;
++ nand->ecc.layout = &hw_nand_oob;
++ nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
++ nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
++ nand->ecc.hwctl = omap_enable_hwecc;
++ nand->ecc.correct = omap_correct_data;
++ nand->ecc.calculate = omap_calculate_ecc;
++ omap_hwecc_init(nand);
++
++ if (nand->options & NAND_BUSWIDTH_16)
++ nand->read_buf = nand_read_buf16;
++ else
++ nand->read_buf = nand_read_buf;
++ nand->dev_ready = omap_spl_dev_ready;
++#endif
+
+ return 0;
+ }
+diff --git a/drivers/mtd/nand/ti81xx_nand.c b/drivers/mtd/nand/ti81xx_nand.c
+new file mode 100644
+index 0000000..f941b72
+--- /dev/null
++++ b/drivers/mtd/nand/ti81xx_nand.c
+@@ -0,0 +1,931 @@
++/*
++ * (C) Copyright 2004-2008 Texas Instruments, <www.ti.com>
++ * Mansoor Ahamed <mansoor.ahamed@ti.com>
++ *
++ * Derived from work done by Rohit Choraria <rohitkc@ti.com> for omap
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <asm/io.h>
++#include <asm/errno.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/mem.h>
++#include <asm/arch/nand.h>
++#include <linux/mtd/nand_ecc.h>
++#include <nand.h>
++
++struct nand_bch_priv {
++ uint8_t mode;
++ uint8_t type;
++ uint8_t nibbles;
++};
++
++/* bch types */
++#define ECC_BCH4 0
++#define ECC_BCH8 1
++#define ECC_BCH16 2
++
++/* BCH nibbles for diff bch levels */
++#define NAND_ECC_HW_BCH ((uint8_t)(NAND_ECC_HW_OOB_FIRST) + 1)
++#define ECC_BCH4_NIBBLES 13
++#define ECC_BCH8_NIBBLES 26
++#define ECC_BCH16_NIBBLES 52
++
++static uint8_t cs;
++#ifndef CONFIG_SPL_BUILD
++static struct nand_ecclayout hw_nand_oob = GPMC_NAND_HW_ECC_LAYOUT_KERNEL;
++static struct nand_ecclayout hw_bch4_nand_oob = GPMC_NAND_HW_BCH4_ECC_LAYOUT;
++static struct nand_ecclayout hw_bch16_nand_oob = GPMC_NAND_HW_BCH16_ECC_LAYOUT;
++#endif
++static struct nand_ecclayout hw_bch8_nand_oob = GPMC_NAND_HW_BCH8_ECC_LAYOUT;
++
++
++static struct nand_bch_priv bch_priv = {
++ .mode = NAND_ECC_HW_BCH,
++ .type = ECC_BCH8,
++ .nibbles = ECC_BCH8_NIBBLES
++};
++
++/*
++ * ti81xx_read_bch8_result - Read BCH result for BCH8 level
++ *
++ * @mtd: MTD device structure
++ * @big_endian: When set read register 3 first
++ * @ecc_code: Read syndrome from BCH result registers
++ */
++static void ti81xx_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian,
++ uint8_t *ecc_code)
++{
++ uint32_t *ptr;
++ int8_t i = 0, j;
++
++ if (big_endian) {
++ ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
++ ecc_code[i++] = readl(ptr) & 0xFF;
++ ptr--;
++ for (j = 0; j < 3; j++) {
++ ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
++ ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
++ ecc_code[i++] = (readl(ptr) >> 8) & 0xFF;
++ ecc_code[i++] = readl(ptr) & 0xFF;
++ ptr--;
++ }
++ }
++ else {
++ ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[0];
++ for (j = 0; j < 3; j++) {
++ ecc_code[i++] = readl(ptr) & 0xFF;
++ ecc_code[i++] = (readl(ptr) >> 8) & 0xFF;
++ ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
++ ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
++ ptr++;
++ }
++ ecc_code[i++] = readl(ptr) & 0xFF;
++ }
++}
++
++/*
++ * ti81xx_ecc_disable - Disable H/W ECC calculation
++ *
++ * @mtd: MTD device structure
++ *
++ */
++static void ti81xx_ecc_disable(struct mtd_info *mtd) {
++
++ writel((readl(&gpmc_cfg->ecc_config) & ~0x1),
++ &gpmc_cfg->ecc_config);
++}
++
++#if 0
++/*
++ * ti81xx_ecc_enable_bch - Enable BCH H/W ECC calculation
++ *
++ * @mtd: MTD device structure
++ *
++ */
++static void ti81xx_ecc_enable_bch(struct mtd_info *mtd) {
++ uint32_t val;
++
++ val = readl(&gpmc_cfg->ecc_control);
++ val |= 0x00000100u;
++ writel(val, &gpmc_cfg->ecc_control); /* clear ECC outputs */
++
++ val = readl(&gpmc_cfg->ecc_control);
++ val &= ~0xF;
++ val |= 0x1;
++ writel(val, &gpmc_cfg->ecc_control); /* reset ecc pointer to result 1 */
++
++ val = readl(&gpmc_cfg->ecc_config);
++ val |= 0x1;
++ writel(val, &gpmc_cfg->ecc_config); /* enable ecc */
++}
++#endif
++
++/*
++ * ti81xx_nand_hwcontrol - Set the address pointers correctly for the
++ * following address/data/command operation
++ */
++static void ti81xx_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
++ uint32_t ctrl)
++{
++ register struct nand_chip *this = mtd->priv;
++
++ /*
++ * Point the IO_ADDR to DATA and ADDRESS registers instead
++ * of chip address
++ */
++ switch (ctrl) {
++ case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
++ this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
++ break;
++ case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
++ this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_adr;
++ break;
++ case NAND_CTRL_CHANGE | NAND_NCE:
++ this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
++ break;
++ }
++
++ if (cmd != NAND_CMD_NONE)
++ writeb(cmd, this->IO_ADDR_W);
++}
++
++/*
++ * ti81xx_hwecc_init_bch - Initialize the BCH Hardware ECC for NAND flash in
++ * GPMC controller
++ * @mtd: MTD device structure
++ * @mode: Read/Write mode
++ */
++static void ti81xx_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
++{
++ uint32_t val, dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
++ uint32_t unused_length = 0;
++ struct nand_bch_priv *bch = chip->priv;
++
++ switch(bch->nibbles) {
++ case ECC_BCH4_NIBBLES:
++ unused_length = 3;
++ break;
++ case ECC_BCH8_NIBBLES:
++ unused_length = 2;
++ break;
++ case ECC_BCH16_NIBBLES:
++ unused_length = 0;
++ break;
++ }
++
++ /* Clear the ecc result registers, select ecc reg as 1 */
++ writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
++
++ switch (mode) {
++ case NAND_ECC_WRITE:
++ /* eccsize1 config */
++ val = ((unused_length + bch->nibbles) << 22);
++ break;
++
++ case NAND_ECC_READ:
++ default:
++ /* by default eccsize0 selected for ecc1resultsize */
++ /* eccsize0 config */
++ val = (bch->nibbles << 12);
++ /* eccsize1 config */
++ val |= (unused_length << 22);
++ break;
++ }
++ /* ecc size configuration */
++ writel(val, &gpmc_cfg->ecc_size_config);
++ /* by default 512bytes sector page is selected */
++ /* set bch mode */
++ val = (1 << 16);
++ /* bch4 / bch8 / bch16 */
++ val |= (bch->type << 12);
++ /* set wrap mode to 1 */
++ val |= (1 << 8);
++ val |= (dev_width << 7);
++ val |= (cs << 1);
++ /* enable ecc */
++ /* val |= (1); */ /* should not enable ECC just init i.e. config */
++ writel(val, &gpmc_cfg->ecc_config);
++}
++
++
++#ifndef CONFIG_SPL_BUILD
++/*
++ * ti81xx_hwecc_init - Initialize the Hardware ECC for NAND flash in
++ * GPMC controller
++ * @mtd: MTD device structure
++ *
++ */
++static void ti81xx_hwecc_init(struct nand_chip *chip)
++{
++ /*
++ * Init ECC Control Register
++ * Clear all ECC | Enable Reg1
++ */
++ writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
++ writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL, &gpmc_cfg->ecc_size_config);
++}
++
++/*
++ * gen_true_ecc - This function will generate true ECC value, which
++ * can be used when correcting data read from NAND flash memory core
++ *
++ * @ecc_buf: buffer to store ecc code
++ *
++ * @return: re-formatted ECC value
++ */
++static uint32_t gen_true_ecc(uint8_t *ecc_buf)
++{
++ return ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xF0) << 20) |
++ ((ecc_buf[2] & 0x0F) << 8);
++}
++#endif
++
++/*
++ * ti81xx_rotate_ecc_bch - Rotate the syndrome bytes
++ *
++ * @mtd: MTD device structure
++ * @calc_ecc: ECC read from ECC registers
++ * @syndrome: Rotated syndrome will be retuned in this array
++ *
++ */
++static void ti81xx_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc,
++ uint8_t *syndrome)
++{
++ struct nand_chip *chip = mtd->priv;
++ struct nand_bch_priv *bch = chip->priv;
++ uint8_t n_bytes = 0;
++ int8_t i,j;
++
++ switch(bch->type) {
++ case ECC_BCH4:
++ n_bytes = 8;
++ break;
++
++ case ECC_BCH16:
++ n_bytes = 28;
++ break;
++
++ case ECC_BCH8:
++ default:
++ n_bytes = 13;
++ break;
++ }
++
++ for (i = 0, j = (n_bytes-1); i < n_bytes; i++, j--)
++ syndrome[i] = calc_ecc[j];
++}
++
++
++/*
++ * ti81xx_fix_errors_bch - Correct bch error in the data
++ *
++ * @mtd: MTD device structure
++ * @data: Data read from flash
++ * @error_count:Number of errors in data
++ * @error_loc: Locations of errors in the data
++ *
++ */
++static void ti81xx_fix_errors_bch(struct mtd_info *mtd, uint8_t *data,
++ uint32_t error_count, uint32_t *error_loc)
++{
++ struct nand_chip *chip = mtd->priv;
++ struct nand_bch_priv *bch = chip->priv;
++ uint8_t count = 0;
++ uint32_t error_byte_pos;
++ uint32_t error_bit_mask;
++ uint32_t last_bit = (bch->nibbles * 4) - 1;
++
++ /* Flip all bits as specified by the error location array. */
++ /* FOR( each found error location flip the bit ) */
++ for (count = 0; count < error_count; count++) {
++ if (error_loc[count] > last_bit) {
++ /* Remove the ECC spare bits from correction. */
++ error_loc[count] -= (last_bit + 1);
++ /* Offset bit in data region */
++ error_byte_pos = (512 * 8) - (error_loc[count] / 8) - 1;
++ /* Error Bit mask */
++ error_bit_mask = 0x1 << (error_loc[count] % 8);
++ /* Toggle the error bit to make the correction. */
++ data[error_byte_pos] ^= error_bit_mask;
++ }
++ }
++}
++
++/*
++ * ti81xx_correct_data_bch - Compares the ecc read from nand spare area
++ * with ECC registers values and corrects one bit error if it has occured
++ *
++ * @mtd: MTD device structure
++ * @dat: page data
++ * @read_ecc: ecc read from nand flash (ignored)
++ * @calc_ecc: ecc read from ECC registers
++ *
++ * @return 0 if data is OK or corrected, else returns -1
++ */
++static int ti81xx_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
++ uint8_t *read_ecc, uint8_t *calc_ecc)
++{
++ struct nand_chip *chip = mtd->priv;
++ struct nand_bch_priv *bch = chip->priv;
++ uint8_t syndrome[28];
++ uint32_t error_count = 0;
++ uint32_t error_loc[8];
++
++ elm_reset();
++ elm_config((enum bch_level)(bch->type));
++
++ /* while reading ECC result we read it in big endian.
++ * Hence while loading to ELM we have rotate to get the right endian.
++ */
++ ti81xx_rotate_ecc_bch(mtd, calc_ecc, syndrome);
++
++#ifdef NAND_DEBUG
++ {
++ uint8_t i = 0;
++ printf("----\necc\n---\n");
++ for (i = 0; i < 13; i++)
++ printf(" 0x%2x", syndrome[i]);
++ printf("\n");
++ }
++#endif
++
++
++ /* use elm module to check for errors */
++ if (elm_check_error(syndrome, bch->nibbles, &error_count, error_loc) != 0) {
++#ifndef CONFIG_SPL_BUILD
++ /* This currently sees all pages as being completely full of
++ * uncorrectable errors. The suspicion is that this is due
++ * to limitations in the elm support we have in U-Boot today
++ */
++ printf("ECC: uncorrectable.\n");
++#endif
++ return -1;
++ }
++
++ /* correct bch error */
++ if (error_count > 0) {
++ ti81xx_fix_errors_bch(mtd, dat, error_count, error_loc);
++ }
++
++ return 0;
++}
++
++#ifndef CONFIG_SPL_BUILD
++/*
++ * ti81xx_correct_data - Compares the ecc read from nand spare area with ECC
++ * registers values and corrects one bit error if it has occured
++ * Further details can be had from TI81xx TRM and the following selected links:
++ * http://en.wikipedia.org/wiki/Hamming_code
++ * http://www.cs.utexas.edu/users/plaxton/c/337/05f/slides/ErrorCorrection-4.pdf
++ *
++ * @mtd: MTD device structure
++ * @dat: page data
++ * @read_ecc: ecc read from nand flash
++ * @calc_ecc: ecc read from ECC registers
++ *
++ * @return 0 if data is OK or corrected, else returns -1
++ */
++static int ti81xx_correct_data(struct mtd_info *mtd, uint8_t *dat,
++ uint8_t *read_ecc, uint8_t *calc_ecc)
++{
++ uint32_t orig_ecc, new_ecc, res, hm;
++ uint16_t parity_bits, byte;
++ uint8_t bit;
++
++ /* Regenerate the orginal ECC */
++ orig_ecc = gen_true_ecc(read_ecc);
++ new_ecc = gen_true_ecc(calc_ecc);
++ /* Get the XOR of real ecc */
++ res = orig_ecc ^ new_ecc;
++ if (res) {
++ /* Get the hamming width */
++ hm = hweight32(res);
++ /* Single bit errors can be corrected! */
++ if (hm == 12) {
++ /* Correctable data! */
++ parity_bits = res >> 16;
++ bit = (parity_bits & 0x7);
++ byte = (parity_bits >> 3) & 0x1FF;
++ /* Flip the bit to correct */
++ dat[byte] ^= (0x1 << bit);
++ } else if (hm == 1) {
++ printf("Error: Ecc is wrong\n");
++ /* ECC itself is corrupted */
++ return 2;
++ } else {
++ /*
++ * hm distance != parity pairs OR one, could mean 2 bit
++ * error OR potentially be on a blank page..
++ * orig_ecc: contains spare area data from nand flash.
++ * new_ecc: generated ecc while reading data area.
++ * Note: if the ecc = 0, all data bits from which it was
++ * generated are 0xFF.
++ * The 3 byte(24 bits) ecc is generated per 512byte
++ * chunk of a page. If orig_ecc(from spare area)
++ * is 0xFF && new_ecc(computed now from data area)=0x0,
++ * this means that data area is 0xFF and spare area is
++ * 0xFF. A sure sign of a erased page!
++ */
++ if ((orig_ecc == 0x0FFF0FFF) && (new_ecc == 0x00000000))
++ return 0;
++ printf("Error: Bad compare! failed\n");
++ /* detected 2 bit error */
++ return -1;
++ }
++ }
++ return 0;
++}
++#endif
++
++/*
++ * ti81xx_calculate_ecc_bch - Read BCH ECC result
++ *
++ * @mtd: MTD structure
++ * @dat: unused
++ * @ecc_code: ecc_code buffer
++ */
++static int ti81xx_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
++ uint8_t *ecc_code)
++{
++ struct nand_chip *chip = mtd->priv;
++ struct nand_bch_priv *bch = chip->priv;
++ uint8_t big_endian = 1;
++ int8_t ret = 0;
++
++ if (bch->type == ECC_BCH8)
++ ti81xx_read_bch8_result(mtd, big_endian, ecc_code);
++ else /* BCH4 and BCH16 currently not supported */
++ ret = -1;
++
++#ifdef NAND_DEBUG
++ {
++ int8_t i = 0;
++ printf("----\nECC\n---\n");
++ for (i = 0; i < 13; i++)
++ printf(" 0x%2x", ecc_code[i]);
++ printf("\n");
++ }
++#endif
++
++ /*
++ * Stop reading anymore ECC vals and clear old results
++ * enable will be called if more reads are required
++ */
++ ti81xx_ecc_disable(mtd);
++
++ return ret;
++}
++
++#ifndef CONFIG_SPL_BUILD
++/*
++ * ti81xx_calculate_ecc - Generate non-inverted ECC bytes.
++ *
++ * Using noninverted ECC can be considered ugly since writing a blank
++ * page ie. padding will clear the ECC bytes. This is no problem as
++ * long nobody is trying to write data on the seemingly unused page.
++ * Reading an erased page will produce an ECC mismatch between
++ * generated and read ECC bytes that has to be dealt with separately.
++ * E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
++ * is used, the result of read will be 0x0 while the ECC offsets of the
++ * spare area will be 0xFF which will result in an ECC mismatch.
++ * @mtd: MTD structure
++ * @dat: unused
++ * @ecc_code: ecc_code buffer
++ */
++static int ti81xx_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
++ uint8_t *ecc_code)
++{
++ u_int32_t val;
++
++ /* Start Reading from HW ECC1_Result = 0x200 */
++ val = readl(&gpmc_cfg->ecc1_result);
++
++ ecc_code[0] = val & 0xFF;
++ ecc_code[1] = (val >> 16) & 0xFF;
++ ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
++
++ /*
++ * Stop reading anymore ECC vals and clear old results
++ * enable will be called if more reads are required
++ */
++ writel(0x000, &gpmc_cfg->ecc_config);
++
++ return 0;
++}
++
++/**
++ * ti81xx_write_page_bch - [REPLACABLE] hardware ecc based page write function
++ * @mtd: mtd info structure
++ * @chip: nand chip info structure
++ * @buf: data buffer
++ */
++static void ti81xx_write_page_bch(struct mtd_info *mtd,
++ struct nand_chip *chip, const uint8_t *buf)
++{
++ int i, eccsize = chip->ecc.size;
++ int eccbytes = chip->ecc.bytes;
++ int eccsteps = chip->ecc.steps;
++ uint8_t *ecc_calc = chip->buffers->ecccalc;
++ const uint8_t *p = buf;
++ uint32_t *eccpos = chip->ecc.layout->eccpos;
++
++ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
++ chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
++ chip->write_buf(mtd, p, eccsize);
++ chip->ecc.calculate(mtd, p, &ecc_calc[i]);
++ }
++
++ for (i = 0; i < chip->ecc.total; i++)
++ chip->oob_poi[eccpos[i]] = ecc_calc[i];
++
++ chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
++}
++
++
++/**
++ * ti81xx_read_page_bch - hardware ecc based page read function
++ * @mtd: mtd info structure
++ * @chip: nand chip info structure
++ * @buf: buffer to store read data
++ * @page: page number to read
++ *
++ */
++static int ti81xx_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
++ uint8_t *buf, int page)
++{
++ int i, eccsize = chip->ecc.size;
++ int eccbytes = chip->ecc.bytes;
++ int eccsteps = chip->ecc.steps;
++ uint8_t *p = buf;
++ uint8_t *ecc_calc = chip->buffers->ecccalc;
++ uint8_t *ecc_code = chip->buffers->ecccode;
++ uint32_t *eccpos = chip->ecc.layout->eccpos;
++ uint8_t *oob = chip->oob_poi;
++ uint32_t data_pos;
++ uint32_t oob_pos;
++
++ data_pos = 0;
++ /* oob area start */
++ oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
++ //oob_pos = (eccsize * eccsteps) + 2;
++
++ chip->ecc.hwctl(mtd, NAND_ECC_READ);
++ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
++ oob += eccbytes) {
++ /* read data */
++ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, page);
++ chip->read_buf(mtd, p, eccsize);
++#ifdef NAND_DEBUG
++ {
++ uint32_t j;
++ printf("----\nDATA\n---\n");
++ for (j = 0; j < 13; j++)
++ printf(" 0x%2x", p[j]);
++ printf("\n");
++ }
++#endif
++
++ /* read respective ecc from oob area */
++ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, page);
++ chip->read_buf(mtd, oob, eccbytes);
++#ifdef NAND_DEBUG
++ {
++ uint32_t j;
++ printf("----\nOOB\n---\n");
++ for (j = 0; j < 13; j++)
++ printf(" 0x%2x", oob[j]);
++ printf("\n");
++ }
++#endif
++ /* read syndrome */
++ chip->ecc.calculate(mtd, p, &ecc_calc[i]);
++
++ data_pos += eccsize;
++ oob_pos += eccbytes;
++ }
++
++ for (i = 0; i < chip->ecc.total; i++)
++ ecc_code[i] = chip->oob_poi[eccpos[i]];
++
++ eccsteps = chip->ecc.steps;
++ p = buf;
++
++ for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
++ int stat;
++
++ stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
++ if (stat < 0)
++ mtd->ecc_stats.failed++;
++ else
++ mtd->ecc_stats.corrected += stat;
++ }
++ return 0;
++}
++#endif
++
++/*
++ * ti81xx_enable_ecc_bch- This function enables the bch h/w ecc functionality
++ * @mtd: MTD device structure
++ * @mode: Read/Write mode
++ *
++ */
++static void ti81xx_enable_ecc_bch(struct mtd_info *mtd, int32_t mode)
++{
++ struct nand_chip *chip = mtd->priv;
++
++ ti81xx_hwecc_init_bch(chip, mode);
++ /* enable ecc */
++ writel((readl(&gpmc_cfg->ecc_config) | 0x1), &gpmc_cfg->ecc_config);
++}
++
++#ifndef CONFIG_SPL_BUILD
++/*
++ * ti81xx_enable_ecc - This function enables the hardware ecc functionality
++ * @mtd: MTD device structure
++ * @mode: Read/Write mode
++ */
++static void ti81xx_enable_ecc(struct mtd_info *mtd, int32_t mode)
++{
++ struct nand_chip *chip = mtd->priv;
++ uint32_t val, dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
++
++ switch (mode) {
++ case NAND_ECC_READ:
++ case NAND_ECC_WRITE:
++ /* Clear the ecc result registers, select ecc reg as 1 */
++ writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
++
++ /*
++ * Size 0 = 0xFF, Size1 is 0xFF - both are 512 bytes
++ * tell all regs to generate size0 sized regs
++ * we just have a single ECC engine for all CS
++ */
++ writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL,
++ &gpmc_cfg->ecc_size_config);
++ val = (dev_width << 7) | (cs << 1) | (0x1);
++ writel(val, &gpmc_cfg->ecc_config);
++ break;
++ default:
++ printf("Error: Unrecognized Mode[%d]!\n", mode);
++ break;
++ }
++}
++
++/*
++ * __ti81xx_nand_switch_ecc - switch the ECC operation ib/w h/w ecc
++ * (i.e. hamming / bch) and s/w ecc.
++ * The default is to come up on s/w ecc
++ *
++ * @nand: NAND chip datastructure
++ * @hardware: NAND_ECC_HW -switch to h/w ecc
++ * NAND_ECC_SOFT -switch to s/w ecc
++ *
++ * @mode: 0 - hamming code
++ * 1 - bch4
++ * 2 - bch8
++ * 3 - bch16
++ *
++ *
++ */
++void __ti81xx_nand_switch_ecc(struct nand_chip *nand,
++ nand_ecc_modes_t hardware, int32_t mode)
++{
++ struct nand_bch_priv *bch;
++
++ bch = nand->priv;
++ nand->options |= NAND_OWN_BUFFERS;
++
++ /* Reset ecc interface */
++ nand->ecc.read_page = NULL;
++ nand->ecc.write_page = NULL;
++ nand->ecc.read_oob = NULL;
++ nand->ecc.write_oob = NULL;
++ nand->ecc.hwctl = NULL;
++ nand->ecc.correct = NULL;
++ nand->ecc.calculate = NULL;
++
++ nand->ecc.write_page = NULL;
++ nand->ecc.read_page = NULL;
++ nand->ecc.mode = hardware;
++ /* Setup the ecc configurations again */
++ if (hardware == NAND_ECC_HW) {
++ if (mode) {
++ bch->mode = NAND_ECC_HW_BCH;
++ /* -1 for converting mode to bch type */
++ bch->type = mode - 1;
++ printf("HW ECC BCH");
++ switch (bch->type) {
++ case ECC_BCH4:
++ nand->ecc.layout = &hw_bch4_nand_oob;
++ bch->nibbles = ECC_BCH4_NIBBLES;
++ nand->ecc.bytes = 8;
++ printf("4 not supported\n");
++ goto no_support;
++ break;
++ case ECC_BCH16:
++ nand->ecc.bytes = 26;
++ nand->ecc.layout = &hw_bch16_nand_oob;
++ bch->nibbles = ECC_BCH16_NIBBLES;
++ printf("16 not supported\n");
++ goto no_support;
++ break;
++ case ECC_BCH8:
++ default:
++ nand->ecc.bytes = 14;
++ nand->ecc.layout = &hw_bch8_nand_oob;
++ bch->nibbles = ECC_BCH8_NIBBLES;
++ printf("8 Selected\n");
++ break;
++ }
++ bch->mode = NAND_ECC_HW;
++ nand->ecc.mode = NAND_ECC_HW_SYNDROME;
++ nand->ecc.steps = 4;
++ nand->ecc.size = 512;
++ nand->ecc.total = (nand->ecc.steps * nand->ecc.bytes);
++ nand->ecc.write_page = ti81xx_write_page_bch;
++ nand->ecc.read_page = ti81xx_read_page_bch;
++ nand->ecc.hwctl = ti81xx_enable_ecc_bch;
++ nand->ecc.correct = ti81xx_correct_data_bch;
++ nand->ecc.calculate = ti81xx_calculate_ecc_bch;
++ ti81xx_hwecc_init_bch(nand, NAND_ECC_READ);
++ } else {
++ bch->mode = NAND_ECC_HW;
++ nand->ecc.layout = &hw_nand_oob;
++ nand->ecc.size = 512;
++ nand->ecc.bytes = 3;
++ nand->ecc.hwctl = ti81xx_enable_ecc;
++ nand->ecc.correct = ti81xx_correct_data;
++ nand->ecc.calculate = ti81xx_calculate_ecc;
++ ti81xx_hwecc_init(nand);
++ printf("HW ECC Hamming Code selected\n");
++ }
++ } else if(hardware == NAND_ECC_SOFT) {
++ /* Use mtd default settings */
++ nand->ecc.layout = NULL;
++ printf("SW ECC selected\n");
++ } else {
++ printf("ECC Disabled\n");
++ }
++
++no_support:
++ return;
++}
++
++/*
++ * ti81xx_nand_switch_ecc - switch the ECC operation ib/w h/w ecc
++ * (i.e. hamming / bch) and s/w ecc.
++ * The default is to come up on s/w ecc
++ *
++ * @hardware - NAND_ECC_HW -switch to h/w ecc
++ * NAND_ECC_SOFT -switch to s/w ecc
++ *
++ * @mode - 0 - hamming code
++ * 1 - bch4
++ * 2 - bch8
++ * 3 - bch16
++ *
++ *
++ */
++void ti81xx_nand_switch_ecc(nand_ecc_modes_t hardware, int32_t mode)
++{
++ struct nand_chip *nand;
++ struct mtd_info *mtd;
++
++ if (nand_curr_device < 0 ||
++ nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE) {
++ printf("Error: Can't switch ecc, no devices available\n");
++ return;
++ }
++
++ mtd = &nand_info[nand_curr_device];
++ nand = mtd->priv;
++
++ __ti81xx_nand_switch_ecc(nand, hardware, mode);
++
++ /* Update NAND handling after ECC mode switch */
++ nand_scan_tail(mtd);
++
++ nand->options &= ~NAND_OWN_BUFFERS;
++ return;
++}
++#endif
++
++#ifdef CONFIG_SPL_BUILD
++/* Check wait pin as dev ready indicator */
++static int ti81xx_spl_dev_ready(struct mtd_info *mtd)
++{
++ return gpmc_cfg->status & (1 << 8);
++}
++#endif
++
++/*
++ * Board-specific NAND initialization. The following members of the
++ * argument are board-specific:
++ * - IO_ADDR_R: address to read the 8 I/O lines of the flash device
++ * - IO_ADDR_W: address to write the 8 I/O lines of the flash device
++ * - cmd_ctrl: hardwarespecific function for accesing control-lines
++ * - waitfunc: hardwarespecific function for accesing device ready/busy line
++ * - ecc.hwctl: function to enable (reset) hardware ecc generator
++ * - ecc.mode: mode of ecc, see defines
++ * - chip_delay: chip dependent delay for transfering data from array to
++ * read regs (tR)
++ * - options: various chip options. They can partly be set to inform
++ * nand_scan about special functionality. See the defines for further
++ * explanation
++ */
++int board_nand_init(struct nand_chip *nand)
++{
++ /* int32_t gpmc_config = 0; */
++ cs = 0;
++
++ /*
++ * xloader/Uboot's gpmc configuration would have configured GPMC for
++ * nand type of memory. The following logic scans and latches on to the
++ * first CS with NAND type memory.
++ * TBD: need to make this logic generic to handle multiple CS NAND
++ * devices.
++ */
++ while (cs < GPMC_MAX_CS) {
++ /* Check if NAND type is set */
++ if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
++ /* Found it!! */
++#ifdef NAND_DEBUG
++ printf("Searching for NAND device @ GPMC CS:%1d\n", cs);
++#endif
++ break;
++ }
++ cs++;
++ }
++ if (cs >= GPMC_MAX_CS) {
++ printf("NAND: Unable to find NAND settings in "
++ "GPMC Configuration - quitting\n");
++ return -ENODEV;
++ }
++
++ nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
++ nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
++
++ nand->cmd_ctrl = ti81xx_nand_hwcontrol;
++ nand->options = NAND_NO_PADDING | NAND_CACHEPRG | NAND_NO_AUTOINCR;
++ /* If we are 16 bit dev, our gpmc config tells us that */
++ if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000) {
++ nand->options |= NAND_BUSWIDTH_16;
++ }
++
++ nand->chip_delay = 100;
++
++ /* required in case of BCH */
++ elm_init();
++
++ /* BCH info that will be correct for SPL or overridden otherwise. */
++ nand->priv = &bch_priv;
++
++#ifndef CONFIG_SPL_BUILD
++ /* For undocumented reasons we need to currently keep our environment
++ * in 1-bit ECC so we configure ourself thusly. */
++ nand_curr_device = 0;
++ ti81xx_nand_switch_ecc(NAND_ECC_HW, 0);
++#else
++ /* The NAND chip present requires that we have written data in with
++ * at least 4-bit ECC so we configure outself for that in SPL.
++ */
++ nand->ecc.mode = NAND_ECC_HW_SYNDROME;
++ nand->ecc.layout = &hw_bch8_nand_oob;
++ nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
++ nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
++ nand->ecc.steps = CONFIG_SYS_NAND_ECCSTEPS;
++ nand->ecc.total = CONFIG_SYS_NAND_ECCTOTAL;
++ nand->ecc.hwctl = ti81xx_enable_ecc_bch;
++ nand->ecc.correct = ti81xx_correct_data_bch;
++ nand->ecc.calculate = ti81xx_calculate_ecc_bch;
++
++ if (nand->options & NAND_BUSWIDTH_16)
++ nand->read_buf = nand_read_buf16;
++ else
++ nand->read_buf = nand_read_buf;
++ nand->dev_ready = ti81xx_spl_dev_ready;
++
++ ti81xx_hwecc_init_bch(nand, NAND_ECC_READ);
++#endif
++
++ return 0;
++}
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+index 819b197..becd1ce 100644
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -79,6 +79,7 @@ COBJS-$(CONFIG_TIGON3) += tigon3.o
+ COBJS-$(CONFIG_TIGON3) += bcm570x_autoneg.o
+ COBJS-$(CONFIG_TIGON3) += 5701rls.o
+ COBJS-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
++COBJS-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o
+ COBJS-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o
+ COBJS-$(CONFIG_TSI108_ETH) += tsi108_eth.o
+ COBJS-$(CONFIG_ULI526X) += uli526x.o
+diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
+new file mode 100644
+index 0000000..90b8fd4
+--- /dev/null
++++ b/drivers/net/cpsw.c
+@@ -0,0 +1,913 @@
++/*
++ * CPSW Ethernet Switch Driver
++ *
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <common.h>
++#include <command.h>
++#include <net.h>
++#include <miiphy.h>
++#include <malloc.h>
++#include <net.h>
++#include <netdev.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++
++#define BITMASK(bits) ((1 << (bits)) - 1)
++#define PHY_REG_MASK 0x1f
++#define PHY_ID_MASK 0x1f
++#define NUM_DESCS (PKTBUFSRX * 2)
++#define PKT_MIN 60
++#define PKT_MAX (1500 + 14 + 4 + 4)
++
++/* DMA Registers */
++#define CPDMA_TXCONTROL 0x004
++#define CPDMA_RXCONTROL 0x014
++#define CPDMA_SOFTRESET 0x01c
++#define CPDMA_RXFREE 0x0e0
++#define CPDMA_TXHDP_VER1 0x100
++#define CPDMA_TXHDP_VER2 0x200
++#define CPDMA_RXHDP_VER1 0x120
++#define CPDMA_RXHDP_VER2 0x220
++#define CPDMA_TXCP_VER1 0x140
++#define CPDMA_TXCP_VER2 0x240
++#define CPDMA_RXCP_VER1 0x160
++#define CPDMA_RXCP_VER2 0x260
++
++/* Descriptor mode bits */
++#define CPDMA_DESC_SOP BIT(31)
++#define CPDMA_DESC_EOP BIT(30)
++#define CPDMA_DESC_OWNER BIT(29)
++#define CPDMA_DESC_EOQ BIT(28)
++
++struct cpsw_mdio_regs {
++ u32 version;
++ u32 control;
++#define CONTROL_IDLE (1 << 31)
++#define CONTROL_ENABLE (1 << 30)
++
++ u32 alive;
++ u32 link;
++ u32 linkintraw;
++ u32 linkintmasked;
++ u32 __reserved_0[2];
++ u32 userintraw;
++ u32 userintmasked;
++ u32 userintmaskset;
++ u32 userintmaskclr;
++ u32 __reserved_1[20];
++
++ struct {
++ u32 access;
++ u32 physel;
++#define USERACCESS_GO (1 << 31)
++#define USERACCESS_WRITE (1 << 30)
++#define USERACCESS_ACK (1 << 29)
++#define USERACCESS_READ (0)
++#define USERACCESS_DATA (0xffff)
++ } user[0];
++};
++
++struct cpsw_regs {
++ u32 id_ver;
++ u32 control;
++ u32 soft_reset;
++ u32 stat_port_en;
++ u32 ptype;
++};
++
++struct cpsw_slave_regs {
++ u32 max_blks;
++ u32 blk_cnt;
++ u32 flow_thresh;
++ u32 port_vlan;
++ u32 tx_pri_map;
++#ifdef CONFIG_TI814X
++ u32 ts_ctl;
++ u32 ts_seq_ltype;
++ u32 ts_vlan;
++#endif
++ u32 sa_lo;
++ u32 sa_hi;
++};
++
++struct cpsw_host_regs {
++ u32 max_blks;
++ u32 blk_cnt;
++ u32 flow_thresh;
++ u32 port_vlan;
++ u32 tx_pri_map;
++ u32 cpdma_tx_pri_map;
++ u32 cpdma_rx_chan_map;
++};
++
++struct cpsw_sliver_regs {
++ u32 id_ver;
++ u32 mac_control;
++ u32 mac_status;
++ u32 soft_reset;
++ u32 rx_maxlen;
++ u32 __reserved_0;
++ u32 rx_pause;
++ u32 tx_pause;
++ u32 __reserved_1;
++ u32 rx_pri_map;
++};
++
++#define ALE_ENTRY_BITS 68
++#define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32)
++
++/* ALE Registers */
++#define ALE_CONTROL 0x08
++#define ALE_UNKNOWNVLAN 0x18
++#define ALE_TABLE_CONTROL 0x20
++#define ALE_TABLE 0x34
++#define ALE_PORTCTL 0x40
++
++#define ALE_TABLE_WRITE BIT(31)
++
++#define ALE_TYPE_FREE 0
++#define ALE_TYPE_ADDR 1
++#define ALE_TYPE_VLAN 2
++#define ALE_TYPE_VLAN_ADDR 3
++
++#define ALE_UCAST_PERSISTANT 0
++#define ALE_UCAST_UNTOUCHED 1
++#define ALE_UCAST_OUI 2
++#define ALE_UCAST_TOUCHED 3
++
++#define ALE_MCAST_FWD 0
++#define ALE_MCAST_BLOCK_LEARN_FWD 1
++#define ALE_MCAST_FWD_LEARN 2
++#define ALE_MCAST_FWD_2 3
++
++enum cpsw_ale_port_state {
++ ALE_PORT_STATE_DISABLE = 0x00,
++ ALE_PORT_STATE_BLOCK = 0x01,
++ ALE_PORT_STATE_LEARN = 0x02,
++ ALE_PORT_STATE_FORWARD = 0x03,
++};
++
++/* ALE unicast entry flags - passed into cpsw_ale_add_ucast() */
++#define ALE_SECURE 1
++#define ALE_BLOCKED 2
++
++struct cpsw_slave {
++ struct cpsw_slave_regs *regs;
++ struct cpsw_sliver_regs *sliver;
++ int slave_num;
++ u32 mac_control;
++ struct cpsw_slave_data *data;
++};
++
++struct cpdma_desc {
++ /* hardware fields */
++ u32 hw_next;
++ u32 hw_buffer;
++ u32 hw_len;
++ u32 hw_mode;
++ /* software fields */
++ u32 sw_buffer;
++ u32 sw_len;
++};
++
++struct cpdma_chan {
++ struct cpdma_desc *head, *tail;
++ void *hdp, *cp, *rxfree;
++};
++
++#define desc_write(desc, fld, val) __raw_writel((u32)(val), &(desc)->fld)
++#define desc_read(desc, fld) __raw_readl(&(desc)->fld)
++#define desc_read_ptr(desc, fld) ((void *)__raw_readl(&(desc)->fld))
++
++#define chan_write(chan, fld, val) __raw_writel((u32)(val), (chan)->fld)
++#define chan_read(chan, fld) __raw_readl((chan)->fld)
++#define chan_read_ptr(chan, fld) ((void *)__raw_readl((chan)->fld))
++
++struct cpsw_priv {
++ struct eth_device *dev;
++ struct cpsw_platform_data data;
++ int host_port;
++
++ struct cpsw_regs *regs;
++ void *dma_regs;
++ struct cpsw_host_regs *host_port_regs;
++ void *ale_regs;
++
++ struct cpdma_desc descs[NUM_DESCS];
++ struct cpdma_desc *desc_free;
++ struct cpdma_chan rx_chan, tx_chan;
++
++ struct cpsw_slave *slaves;
++#define for_each_slave(priv, func, arg...) \
++ do { \
++ int idx; \
++ for (idx = 0; idx < (priv)->data.slaves; idx++) \
++ (func)((priv)->slaves + idx, ##arg); \
++ } while (0)
++};
++
++static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
++{
++ int idx;
++
++ idx = start / 32;
++ start -= idx * 32;
++ idx = 2 - idx; /* flip */
++ return (ale_entry[idx] >> start) & BITMASK(bits);
++}
++
++static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
++ u32 value)
++{
++ int idx;
++
++ value &= BITMASK(bits);
++ idx = start / 32;
++ start -= idx * 32;
++ idx = 2 - idx; /* flip */
++ ale_entry[idx] &= ~(BITMASK(bits) << start);
++ ale_entry[idx] |= (value << start);
++}
++
++#define DEFINE_ALE_FIELD(name, start, bits) \
++static inline int cpsw_ale_get_##name(u32 *ale_entry) \
++{ \
++ return cpsw_ale_get_field(ale_entry, start, bits); \
++} \
++static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \
++{ \
++ cpsw_ale_set_field(ale_entry, start, bits, value); \
++}
++
++DEFINE_ALE_FIELD(entry_type, 60, 2)
++DEFINE_ALE_FIELD(mcast_state, 62, 2)
++DEFINE_ALE_FIELD(port_mask, 66, 3)
++DEFINE_ALE_FIELD(ucast_type, 62, 2)
++DEFINE_ALE_FIELD(port_num, 66, 2)
++DEFINE_ALE_FIELD(blocked, 65, 1)
++DEFINE_ALE_FIELD(secure, 64, 1)
++DEFINE_ALE_FIELD(mcast, 40, 1)
++
++/* The MAC address field in the ALE entry cannot be macroized as above */
++static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
++{
++ int i;
++
++ for (i = 0; i < 6; i++)
++ addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8);
++}
++
++static inline void cpsw_ale_set_addr(u32 *ale_entry, u8 *addr)
++{
++ int i;
++
++ for (i = 0; i < 6; i++)
++ cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]);
++}
++
++static int cpsw_ale_read(struct cpsw_priv *priv, int idx, u32 *ale_entry)
++{
++ int i;
++
++ __raw_writel(idx, priv->ale_regs + ALE_TABLE_CONTROL);
++
++ for (i = 0; i < ALE_ENTRY_WORDS; i++)
++ ale_entry[i] = __raw_readl(priv->ale_regs + ALE_TABLE + 4 * i);
++
++ return idx;
++}
++
++static int cpsw_ale_write(struct cpsw_priv *priv, int idx, u32 *ale_entry)
++{
++ int i;
++
++ for (i = 0; i < ALE_ENTRY_WORDS; i++)
++ __raw_writel(ale_entry[i], priv->ale_regs + ALE_TABLE + 4 * i);
++
++ __raw_writel(idx | ALE_TABLE_WRITE, priv->ale_regs + ALE_TABLE_CONTROL);
++
++ return idx;
++}
++
++static int cpsw_ale_match_addr(struct cpsw_priv *priv, u8* addr)
++{
++ u32 ale_entry[ALE_ENTRY_WORDS];
++ int type, idx;
++
++ for (idx = 0; idx < priv->data.ale_entries; idx++) {
++ u8 entry_addr[6];
++
++ cpsw_ale_read(priv, idx, ale_entry);
++ type = cpsw_ale_get_entry_type(ale_entry);
++ if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
++ continue;
++ cpsw_ale_get_addr(ale_entry, entry_addr);
++ if (memcmp(entry_addr, addr, 6) == 0)
++ return idx;
++ }
++ return -ENOENT;
++}
++
++static int cpsw_ale_match_free(struct cpsw_priv *priv)
++{
++ u32 ale_entry[ALE_ENTRY_WORDS];
++ int type, idx;
++
++ for (idx = 0; idx < priv->data.ale_entries; idx++) {
++ cpsw_ale_read(priv, idx, ale_entry);
++ type = cpsw_ale_get_entry_type(ale_entry);
++ if (type == ALE_TYPE_FREE)
++ return idx;
++ }
++ return -ENOENT;
++}
++
++static int cpsw_ale_find_ageable(struct cpsw_priv *priv)
++{
++ u32 ale_entry[ALE_ENTRY_WORDS];
++ int type, idx;
++
++ for (idx = 0; idx < priv->data.ale_entries; idx++) {
++ cpsw_ale_read(priv, idx, ale_entry);
++ type = cpsw_ale_get_entry_type(ale_entry);
++ if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
++ continue;
++ if (cpsw_ale_get_mcast(ale_entry))
++ continue;
++ type = cpsw_ale_get_ucast_type(ale_entry);
++ if (type != ALE_UCAST_PERSISTANT &&
++ type != ALE_UCAST_OUI)
++ return idx;
++ }
++ return -ENOENT;
++}
++
++static int cpsw_ale_add_ucast(struct cpsw_priv *priv, u8 *addr,
++ int port, int flags)
++{
++ u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
++ int idx;
++
++ cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
++ cpsw_ale_set_addr(ale_entry, addr);
++ cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT);
++ cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0);
++ cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
++ cpsw_ale_set_port_num(ale_entry, port);
++
++ idx = cpsw_ale_match_addr(priv, addr);
++ if (idx < 0)
++ idx = cpsw_ale_match_free(priv);
++ if (idx < 0)
++ idx = cpsw_ale_find_ageable(priv);
++ if (idx < 0)
++ return -ENOMEM;
++
++ cpsw_ale_write(priv, idx, ale_entry);
++ return 0;
++}
++
++static int cpsw_ale_add_mcast(struct cpsw_priv *priv, u8 *addr, int port_mask)
++{
++ u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
++ int idx, mask;
++
++ idx = cpsw_ale_match_addr(priv, addr);
++ if (idx >= 0)
++ cpsw_ale_read(priv, idx, ale_entry);
++
++ cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
++ cpsw_ale_set_addr(ale_entry, addr);
++ cpsw_ale_set_mcast_state(ale_entry, ALE_MCAST_FWD_2);
++
++ mask = cpsw_ale_get_port_mask(ale_entry);
++ port_mask |= mask;
++ cpsw_ale_set_port_mask(ale_entry, port_mask);
++
++ if (idx < 0)
++ idx = cpsw_ale_match_free(priv);
++ if (idx < 0)
++ idx = cpsw_ale_find_ageable(priv);
++ if (idx < 0)
++ return -ENOMEM;
++
++ cpsw_ale_write(priv, idx, ale_entry);
++ return 0;
++}
++
++static inline void cpsw_ale_control(struct cpsw_priv *priv, int bit, int val)
++{
++ u32 tmp, mask = BIT(bit);
++
++ tmp = __raw_readl(priv->ale_regs + ALE_CONTROL);
++ tmp &= ~mask;
++ tmp |= val ? mask : 0;
++ __raw_writel(tmp, priv->ale_regs + ALE_CONTROL);
++}
++
++#define cpsw_ale_enable(priv, val) cpsw_ale_control(priv, 31, val)
++#define cpsw_ale_clear(priv, val) cpsw_ale_control(priv, 30, val)
++#define cpsw_ale_vlan_aware(priv, val) cpsw_ale_control(priv, 2, val)
++
++static inline void cpsw_ale_port_state(struct cpsw_priv *priv, int port,
++ int val)
++{
++ int offset = ALE_PORTCTL + 4 * port;
++ u32 tmp, mask = 0x3;
++
++ tmp = __raw_readl(priv->ale_regs + offset);
++ tmp &= ~mask;
++ tmp |= val & 0x3;
++ __raw_writel(tmp, priv->ale_regs + offset);
++}
++
++static struct cpsw_mdio_regs *mdio_regs;
++
++/* wait until hardware is ready for another user access */
++static inline u32 wait_for_user_access(void)
++{
++ u32 reg;
++
++ while ((reg = __raw_readl(&mdio_regs->user[0].access)) & USERACCESS_GO)
++ ;
++
++ return reg;
++}
++
++/* wait until hardware state machine is idle */
++static inline void wait_for_idle(void)
++{
++ while ((__raw_readl(&mdio_regs->control) & CONTROL_IDLE) == 0)
++ ;
++}
++
++static int cpsw_mdio_read(const char *devname, unsigned char phy_id,
++ unsigned char phy_reg, unsigned short *data)
++{
++ u32 reg;
++
++ if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
++ return -EINVAL;
++
++ wait_for_user_access();
++ reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
++ (phy_id << 16));
++ __raw_writel(reg, &mdio_regs->user[0].access);
++ reg = wait_for_user_access();
++
++ *data = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -1;
++ return (reg & USERACCESS_ACK) ? 0 : -EIO;
++}
++
++static int cpsw_mdio_write(const char *devname, unsigned char phy_id,
++ unsigned char phy_reg, unsigned short data)
++{
++ u32 reg;
++
++ if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
++ return -EINVAL;
++
++ wait_for_user_access();
++ reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
++ (phy_id << 16) | (data & USERACCESS_DATA));
++ __raw_writel(reg, &mdio_regs->user[0].access);
++ wait_for_user_access();
++
++ return 0;
++}
++
++static void cpsw_mdio_init(char *name, u32 mdio_base, u32 div)
++{
++ mdio_regs = (struct cpsw_mdio_regs *)mdio_base;
++
++ /* set enable and clock divider */
++ __raw_writel(div | CONTROL_ENABLE, &mdio_regs->control);
++
++ /*
++ * wait for scan logic to settle:
++ * the scan time consists of (a) a large fixed component, and (b) a
++ * small component that varies with the mii bus frequency. These
++ * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
++ * silicon. Since the effect of (b) was found to be largely
++ * negligible, we keep things simple here.
++ */
++ udelay(1000);
++
++ miiphy_register(name, cpsw_mdio_read, cpsw_mdio_write);
++}
++
++static inline void soft_reset(void *reg)
++{
++ __raw_writel(1, reg);
++ while (__raw_readl(reg) & 1)
++ ;
++}
++
++#define mac_hi(mac) (((mac)[0] << 0) | ((mac)[1] << 8) | \
++ ((mac)[2] << 16) | ((mac)[3] << 24))
++#define mac_lo(mac) (((mac)[4] << 0) | ((mac)[5] << 8))
++
++static void cpsw_set_slave_mac(struct cpsw_slave *slave,
++ struct cpsw_priv *priv)
++{
++ __raw_writel(mac_hi(priv->dev->enetaddr), &slave->regs->sa_hi);
++ __raw_writel(mac_lo(priv->dev->enetaddr), &slave->regs->sa_lo);
++}
++
++static void cpsw_slave_update_link(struct cpsw_slave *slave,
++ struct cpsw_priv *priv, int *link)
++{
++ char *name = priv->dev->name;
++ int phy_id = slave->data->phy_id;
++ int speed, duplex;
++ unsigned short reg;
++ u32 mac_control = 0;
++
++ if (miiphy_read(name, phy_id, MII_BMSR, &reg))
++ return; /* could not read, assume no link */
++
++ if (reg & BMSR_LSTATUS) { /* link up */
++ speed = miiphy_speed(name, phy_id);
++ duplex = miiphy_duplex(name, phy_id);
++
++ *link = 1;
++ mac_control = priv->data.mac_control;
++ if (speed == 10)
++ mac_control |= BIT(18); /* In Band mode */
++ else if (speed == 100)
++ mac_control |= BIT(15);
++ else if (speed == 1000)
++ mac_control &= ~BIT(7); /* TODO: Do not enable
++ * gig support now */
++ if (duplex == FULL)
++ mac_control |= BIT(0); /* FULLDUPLEXEN */
++ }
++
++ if (mac_control == slave->mac_control)
++ return;
++
++ if (mac_control) {
++ printf("link up on port %d, speed %d, %s duplex\n",
++ slave->slave_num, speed,
++ (duplex == FULL) ? "full" : "half");
++ } else {
++ printf("link down on port %d\n", slave->slave_num);
++ }
++
++ __raw_writel(mac_control, &slave->sliver->mac_control);
++ slave->mac_control = mac_control;
++}
++
++static int cpsw_update_link(struct cpsw_priv *priv)
++{
++ int link = 0;
++ for_each_slave(priv, cpsw_slave_update_link, priv, &link);
++ return link;
++}
++
++static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
++{
++ if (priv->host_port == 0)
++ return slave_num + 1;
++ else
++ return slave_num;
++}
++
++static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
++{
++ u32 slave_port;
++ soft_reset(&slave->sliver->soft_reset);
++
++ /* setup priority mapping */
++ __raw_writel(0x76543210, &slave->sliver->rx_pri_map);
++ __raw_writel(0x33221100, &slave->regs->tx_pri_map);
++
++ /* setup max packet size, and mac address */
++ __raw_writel(PKT_MAX, &slave->sliver->rx_maxlen);
++ cpsw_set_slave_mac(slave, priv);
++
++ slave->mac_control = 0; /* no link yet */
++
++ /* enable forwarding */
++ slave_port = cpsw_get_slave_port(priv, slave->slave_num);
++ cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD);
++
++ cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave_port);
++
++ priv->data.phy_init(priv->dev->name, slave->data->phy_id);
++}
++
++static struct cpdma_desc *cpdma_desc_alloc(struct cpsw_priv *priv)
++{
++ struct cpdma_desc *desc = priv->desc_free;
++
++ if (desc)
++ priv->desc_free = desc_read_ptr(desc, hw_next);
++ return desc;
++}
++
++static void cpdma_desc_free(struct cpsw_priv *priv, struct cpdma_desc *desc)
++{
++ if (desc) {
++ desc_write(desc, hw_next, priv->desc_free);
++ priv->desc_free = desc;
++ }
++}
++
++static int cpdma_submit(struct cpsw_priv *priv, struct cpdma_chan *chan,
++ volatile void *buffer, int len)
++{
++ struct cpdma_desc *desc, *prev;
++ u32 mode;
++
++ desc = cpdma_desc_alloc(priv);
++ if (!desc)
++ return -ENOMEM;
++
++ if (len < PKT_MIN)
++ len = PKT_MIN;
++
++ mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP;
++
++ desc_write(desc, hw_next, 0);
++ desc_write(desc, hw_buffer, buffer);
++ desc_write(desc, hw_len, len);
++ desc_write(desc, hw_mode, mode | len);
++ desc_write(desc, sw_buffer, buffer);
++ desc_write(desc, sw_len, len);
++
++ if (!chan->head) {
++ /* simple case - first packet enqueued */
++ chan->head = desc;
++ chan->tail = desc;
++ chan_write(chan, hdp, desc);
++ goto done;
++ }
++
++ /* not the first packet - enqueue at the tail */
++ prev = chan->tail;
++ desc_write(prev, hw_next, desc);
++ chan->tail = desc;
++
++ /* next check if EOQ has been triggered already */
++ if (desc_read(prev, hw_mode) & CPDMA_DESC_EOQ)
++ chan_write(chan, hdp, desc);
++
++done:
++ if (chan->rxfree)
++ chan_write(chan, rxfree, 1);
++ return 0;
++}
++
++static int cpdma_process(struct cpsw_priv *priv, struct cpdma_chan *chan,
++ void **buffer, int *len)
++{
++ struct cpdma_desc *desc = chan->head;
++ u32 status;
++
++ if (!desc)
++ return -ENOENT;
++
++ status = desc_read(desc, hw_mode);
++
++ if (len)
++ *len = status & 0x7ff;
++
++ if (buffer)
++ *buffer = desc_read_ptr(desc, sw_buffer);
++
++ if (status & CPDMA_DESC_OWNER)
++ return -EBUSY;
++
++ chan->head = desc_read_ptr(desc, hw_next);
++ chan_write(chan, cp, desc);
++
++ cpdma_desc_free(priv, desc);
++ return 0;
++}
++
++static int cpsw_init(struct eth_device *dev, bd_t *bis)
++{
++ struct cpsw_priv *priv = dev->priv;
++ int i, ret;
++
++ priv->data.control(1);
++
++ /* soft reset the controller and initialize priv */
++ soft_reset(&priv->regs->soft_reset);
++
++ /* initialize and reset the address lookup engine */
++ cpsw_ale_enable(priv, 1);
++ cpsw_ale_clear(priv, 1);
++ cpsw_ale_vlan_aware(priv, 0); /* vlan unaware mode */
++
++ /* setup host port priority mapping */
++ __raw_writel(0x76543210, &priv->host_port_regs->cpdma_tx_pri_map);
++ __raw_writel(0, &priv->host_port_regs->cpdma_rx_chan_map);
++
++ /* disable priority elevation and enable statistics on all ports */
++ __raw_writel(0, &priv->regs->ptype);
++
++ /* enable statistics collection only on the host port */
++ __raw_writel(BIT(priv->host_port), &priv->regs->stat_port_en);
++
++ cpsw_ale_port_state(priv, priv->host_port, ALE_PORT_STATE_FORWARD);
++
++ cpsw_ale_add_ucast(priv, priv->dev->enetaddr, priv->host_port,
++ ALE_SECURE);
++ cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << priv->host_port);
++
++ for_each_slave(priv, cpsw_slave_init, priv);
++
++ cpsw_update_link(priv);
++
++ /* init descriptor pool */
++ for (i = 0; i < NUM_DESCS; i++) {
++ desc_write(&priv->descs[i], hw_next,
++ (i == (NUM_DESCS - 1)) ? 0 : &priv->descs[i+1]);
++ }
++ priv->desc_free = &priv->descs[0];
++
++ /* initialize channels */
++ if (priv->data.version == CPSW_CTRL_VERSION_2) {
++ memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
++ priv->rx_chan.hdp = priv->dma_regs + CPDMA_RXHDP_VER2;
++ priv->rx_chan.cp = priv->dma_regs + CPDMA_RXCP_VER2;
++ priv->rx_chan.rxfree = priv->dma_regs + CPDMA_RXFREE;
++
++ memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
++ priv->tx_chan.hdp = priv->dma_regs + CPDMA_TXHDP_VER2;
++ priv->tx_chan.cp = priv->dma_regs + CPDMA_TXCP_VER2;
++ } else {
++ memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
++ priv->rx_chan.hdp = priv->dma_regs + CPDMA_RXHDP_VER1;
++ priv->rx_chan.cp = priv->dma_regs + CPDMA_RXCP_VER1;
++ priv->rx_chan.rxfree = priv->dma_regs + CPDMA_RXFREE;
++
++ memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
++ priv->tx_chan.hdp = priv->dma_regs + CPDMA_TXHDP_VER1;
++ priv->tx_chan.cp = priv->dma_regs + CPDMA_TXCP_VER1;
++ }
++
++ /* clear dma state */
++ soft_reset(priv->dma_regs + CPDMA_SOFTRESET);
++
++ if (priv->data.version == CPSW_CTRL_VERSION_2) {
++ for (i = 0; i < priv->data.channels; i++) {
++ __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER2 + 4
++ * i);
++ __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
++ * i);
++ __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER2 + 4
++ * i);
++ __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER2 + 4
++ * i);
++ __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER2 + 4
++ * i);
++ }
++ } else {
++ for (i = 0; i < priv->data.channels; i++) {
++ __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER1 + 4
++ * i);
++ __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
++ * i);
++ __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER1 + 4
++ * i);
++ __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER1 + 4
++ * i);
++ __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER1 + 4
++ * i);
++
++ }
++ }
++ __raw_writel(1, priv->dma_regs + CPDMA_TXCONTROL);
++ __raw_writel(1, priv->dma_regs + CPDMA_RXCONTROL);
++
++ /* submit rx descs */
++ for (i = 0; i < PKTBUFSRX; i++) {
++ ret = cpdma_submit(priv, &priv->rx_chan, NetRxPackets[i],
++ PKTSIZE);
++ if (ret < 0) {
++ printf("error %d submitting rx desc\n", ret);
++ break;
++ }
++ }
++
++ return 0;
++}
++
++static void cpsw_halt(struct eth_device *dev)
++{
++ struct cpsw_priv *priv = dev->priv;
++ priv->data.control(0);
++}
++
++static int cpsw_send(struct eth_device *dev, volatile void *packet, int length)
++{
++ struct cpsw_priv *priv = dev->priv;
++ void *buffer;
++ int len;
++
++ if (!cpsw_update_link(priv))
++ return -EIO;
++
++ /* first reap completed packets */
++ while (cpdma_process(priv, &priv->tx_chan, &buffer, &len) >= 0)
++ ;
++
++ return cpdma_submit(priv, &priv->tx_chan, packet, length);
++}
++
++static int cpsw_recv(struct eth_device *dev)
++{
++ struct cpsw_priv *priv = dev->priv;
++ void *buffer;
++ int len;
++
++ while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) {
++ NetReceive(buffer, len);
++ cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE);
++ }
++
++ return 0;
++}
++
++static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
++ struct cpsw_priv *priv)
++{
++ void *regs = priv->regs;
++ struct cpsw_slave_data *data = priv->data.slave_data + slave_num;
++
++ slave->slave_num = slave_num;
++ slave->data = data;
++ slave->regs = regs + data->slave_reg_ofs;
++ slave->sliver = regs + data->sliver_reg_ofs;
++}
++
++int cpsw_register(struct cpsw_platform_data *data)
++{
++ struct cpsw_priv *priv;
++ void *regs = (void *)data->cpsw_base;
++ struct eth_device *dev;
++
++ dev = malloc(sizeof(*dev));
++ if (!dev)
++ return -ENOMEM;
++ memset(dev, 0, sizeof(*dev));
++
++ priv = malloc(sizeof(*priv));
++ if (!priv) {
++ free(dev);
++ return -ENOMEM;
++ }
++ memset(priv, 0, sizeof(*priv));
++
++ priv->data = *data;
++ priv->dev = dev;
++
++ priv->slaves = malloc(sizeof(struct cpsw_slave) * data->slaves);
++ if (!priv->slaves) {
++ free(dev);
++ free(priv);
++ return -ENOMEM;
++ }
++
++ priv->host_port = data->host_port_num;
++ priv->regs = regs;
++ priv->host_port_regs = regs + data->host_port_reg_ofs;
++ priv->dma_regs = regs + data->cpdma_reg_ofs;
++ priv->ale_regs = regs + data->ale_reg_ofs;
++
++ for_each_slave(priv, cpsw_slave_setup, idx, priv);
++
++ strcpy(dev->name, "cpsw");
++ dev->iobase = 0;
++ dev->init = cpsw_init;
++ dev->halt = cpsw_halt;
++ dev->send = cpsw_send;
++ dev->recv = cpsw_recv;
++ dev->priv = priv;
++
++ eth_register(dev);
++
++ cpsw_mdio_init(dev->name, data->mdio_base, data->mdio_div);
++
++ return 1;
++}
+diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
+index c0b8929..6565133 100644
+--- a/drivers/net/davinci_emac.c
++++ b/drivers/net/davinci_emac.c
+@@ -42,11 +42,23 @@
+ #include <miiphy.h>
+ #include <malloc.h>
+ #include <asm/arch/emac_defs.h>
++#include "davinci_emac.h"
+ #include <asm/io.h>
+
+ unsigned int emac_dbg = 0;
+ #define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args)
+
++#ifdef EMAC_HW_RAM_ADDR
++#warning "Use different address for BD"
++#define BD_TO_HW(x) \
++ ( ( (x) == 0) ? 0 : ( (x) - EMAC_WRAPPER_RAM_ADDR + EMAC_HW_RAM_ADDR ))
++#define HW_TO_BD(x) \
++ ( ( (x) == 0) ? 0 : ( (x) - EMAC_HW_RAM_ADDR + EMAC_WRAPPER_RAM_ADDR ))
++#else
++#define BD_TO_HW(x) (x)
++#define HW_TO_BD(x) (x)
++#endif
++
+ #ifdef DAVINCI_EMAC_GIG_ENABLE
+ #define emac_gigabit_enable() davinci_eth_gigabit_enable()
+ #else
+@@ -279,10 +291,33 @@ static int gen_get_link_speed(int phy_addr)
+ static int gen_auto_negotiate(int phy_addr)
+ {
+ u_int16_t tmp;
++ u_int16_t val;
++ unsigned int cntr = 0;
++
+
+ if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
+ return(0);
+
++ val = tmp | PHY_BMCR_DPLX | PHY_BMCR_AUTON | PHY_BMCR_100_MBPS;
++ davinci_eth_phy_write(phy_addr, PHY_BMCR, val);
++ davinci_eth_phy_read(phy_addr, PHY_BMCR, &val);
++
++#ifdef DAVINCI_EMAC_GIG_ENABLE
++ davinci_eth_phy_read(phy_addr,PHY_1000BTCR, &val);
++ val |= PHY_1000BTCR_1000FD;
++ val &= ~PHY_1000BTCR_1000HD;
++ davinci_eth_phy_write(phy_addr,PHY_1000BTCR, val);
++ davinci_eth_phy_read(phy_addr,PHY_1000BTCR, &val);
++#endif
++ /* advertise 100 Full Duplex */
++ davinci_eth_phy_read(phy_addr,PHY_ANAR, &val);
++ val |= (PHY_ANLPAR_10 | PHY_ANLPAR_10FD | PHY_ANLPAR_TX
++ | PHY_ANLPAR_TXFD);
++ davinci_eth_phy_write(phy_addr,PHY_ANAR, val);
++ davinci_eth_phy_read(phy_addr,PHY_ANAR, &val);
++
++ davinci_eth_phy_read(phy_addr, PHY_BMCR, &tmp);
++
+ /* Restart Auto_negotiation */
+ tmp |= BMCR_ANENABLE;
+ davinci_eth_phy_write(phy_addr, MII_BMCR, tmp);
+@@ -336,6 +371,10 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
+ dv_reg_p addr;
+ u_int32_t clkdiv, cnt;
+ volatile emac_desc *rx_desc;
++ uint16_t lpa_val;
++ unsigned long mac_hi;
++ unsigned long mac_lo;
++ u_int32_t mac_control = 0;
+
+ debug_emac("+ emac_open\n");
+
+@@ -388,7 +427,7 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
+ /* 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->next = BD_TO_HW((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;
+@@ -414,18 +453,6 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
+ /* Enable ch 0 only */
+ writel(1, &adap_emac->RXUNICASTSET);
+
+- /* Enable MII interface and Full duplex mode */
+-#ifdef CONFIG_SOC_DA8XX
+- writel((EMAC_MACCONTROL_MIIEN_ENABLE |
+- EMAC_MACCONTROL_FULLDUPLEX_ENABLE |
+- EMAC_MACCONTROL_RMIISPEED_100),
+- &adap_emac->MACCONTROL);
+-#else
+- writel((EMAC_MACCONTROL_MIIEN_ENABLE |
+- EMAC_MACCONTROL_FULLDUPLEX_ENABLE),
+- &adap_emac->MACCONTROL);
+-#endif
+-
+ /* Init MDIO & get link state */
+ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+ writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT,
+@@ -434,13 +461,30 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
+ /* We need to wait for MDIO to start */
+ udelay(1000);
+
+- if (!phy.get_link_speed(active_phy_addr))
++ if (!phy.auto_negotiate(active_phy_addr))
+ return(0);
+-
+- emac_gigabit_enable();
++ mac_control |= EMAC_MACCONTROL_MIIEN_ENABLE;
++#ifdef DAVINCI_EMAC_GIG_ENABLE
++ davinci_eth_phy_read(active_phy_addr,PHY_1000BTSR,&lpa_val);
++ if (lpa_val & PHY_1000BTSR_1000FD) {
++ debug_emac("eth_open : gigabit negotiated\n");
++ mac_control |= EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
++ mac_control |= EMAC_MACCONTROL_GIGABIT_ENABLE;
++ }
++#endif
++ davinci_eth_phy_read(active_phy_addr,PHY_ANLPAR,&lpa_val);
++ if (lpa_val & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD) ) {
++ /* set EMAC for Full Duplex */
++ mac_control |= EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
++ }
++
++#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
++ mac_control |= EMAC_MACCONTROL_RMIISPEED_100;
++#endif
++ writel(mac_control, &adap_emac->MACCONTROL);
+
+ /* Start receive process */
+- writel((u_int32_t)emac_rx_desc, &adap_emac->RX0HDP);
++ writel((BD_TO_HW((u_int32_t)emac_rx_desc)), &adap_emac->RX0HDP);
+
+ debug_emac("- emac_open\n");
+
+@@ -542,8 +586,6 @@ static int davinci_eth_send_packet (struct eth_device *dev,
+ return (ret_status);
+ }
+
+- emac_gigabit_enable();
+-
+ /* 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;
+@@ -558,7 +600,7 @@ static int davinci_eth_send_packet (struct eth_device *dev,
+ EMAC_CPPI_OWNERSHIP_BIT |
+ EMAC_CPPI_EOP_BIT);
+ /* Send the packet */
+- writel((unsigned long)emac_tx_desc, &adap_emac->TX0HDP);
++ writel((BD_TO_HW((unsigned int) emac_tx_desc)), &adap_emac->TX0HDP);
+
+ /* Wait for packet to complete or link down */
+ while (1) {
+@@ -567,8 +609,6 @@ static int davinci_eth_send_packet (struct eth_device *dev,
+ return (ret_status);
+ }
+
+- emac_gigabit_enable();
+-
+ if (readl(&adap_emac->TXINTSTATRAW) & 0x01) {
+ ret_status = length;
+ break;
+@@ -602,14 +642,14 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
+ }
+
+ /* Ack received packet descriptor */
+- writel((unsigned long)rx_curr_desc, &adap_emac->RX0CP);
++ writel((BD_TO_HW((unsigned int) rx_curr_desc)), &adap_emac->RX0CP);
+ curr_desc = rx_curr_desc;
+- emac_rx_active_head =
+- (volatile emac_desc *) rx_curr_desc->next;
++ emac_rx_active_head = (volatile emac_desc *)
++ (HW_TO_BD(rx_curr_desc->next));
+
+ if (status & EMAC_CPPI_EOQ_BIT) {
+ if (emac_rx_active_head) {
+- writel((unsigned long)emac_rx_active_head,
++ writel((BD_TO_HW((unsigned int) emac_rx_active_head)),
+ &adap_emac->RX0HDP);
+ } else {
+ emac_rx_queue_active = 0;
+@@ -627,7 +667,7 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
+ emac_rx_active_head = curr_desc;
+ emac_rx_active_tail = curr_desc;
+ if (emac_rx_queue_active != 0) {
+- writel((unsigned long)emac_rx_active_head,
++ writel((BD_TO_HW((unsigned int) emac_rx_active_head)),
+ &adap_emac->RX0HDP);
+ printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
+ emac_rx_queue_active = 1;
+@@ -635,10 +675,10 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
+ } else {
+ tail_desc = emac_rx_active_tail;
+ emac_rx_active_tail = curr_desc;
+- tail_desc->next = (unsigned int) curr_desc;
++ tail_desc->next = BD_TO_HW((unsigned int) curr_desc);
+ status = tail_desc->pkt_flag_len;
+ if (status & EMAC_CPPI_EOQ_BIT) {
+- writel((unsigned long)curr_desc,
++ writel((BD_TO_HW((unsigned int) curr_desc)),
+ &adap_emac->RX0HDP);
+ status &= ~EMAC_CPPI_EOQ_BIT;
+ tail_desc->pkt_flag_len = status;
+@@ -711,6 +751,7 @@ int davinci_emac_initialize(void)
+ phy_id |= tmp & 0x0000ffff;
+
+ switch (phy_id) {
++ #if defined(PHY_LXT972)
+ case PHY_LXT972:
+ sprintf(phy.name, "LXT972 @ 0x%02x", active_phy_addr);
+ phy.init = lxt972_init_phy;
+@@ -718,6 +759,8 @@ int davinci_emac_initialize(void)
+ phy.get_link_speed = lxt972_get_link_speed;
+ phy.auto_negotiate = lxt972_auto_negotiate;
+ break;
++ #endif
++ #if defined(PHY_DP83848)
+ case PHY_DP83848:
+ sprintf(phy.name, "DP83848 @ 0x%02x", active_phy_addr);
+ phy.init = dp83848_init_phy;
+@@ -725,6 +768,8 @@ int davinci_emac_initialize(void)
+ phy.get_link_speed = dp83848_get_link_speed;
+ phy.auto_negotiate = dp83848_auto_negotiate;
+ break;
++ #endif
++ #if defined(PHY_ET1011C)
+ case PHY_ET1011C:
+ sprintf(phy.name, "ET1011C @ 0x%02x", active_phy_addr);
+ phy.init = gen_init_phy;
+@@ -732,6 +777,7 @@ int davinci_emac_initialize(void)
+ phy.get_link_speed = et1011c_get_link_speed;
+ phy.auto_negotiate = gen_auto_negotiate;
+ break;
++ #endif
+ default:
+ sprintf(phy.name, "GENERIC @ 0x%02x", active_phy_addr);
+ phy.init = gen_init_phy;
+@@ -743,5 +789,12 @@ int davinci_emac_initialize(void)
+ printf("Ethernet PHY: %s\n", phy.name);
+
+ miiphy_register(phy.name, davinci_mii_phy_read, davinci_mii_phy_write);
++#ifdef DAVINCI_EMAC_GIG_ENABLE
++ /* Enable PHY to clock out TX_CLK */
++ davinci_eth_phy_read(active_phy_addr, PHY_CONF_REG, &tmp);
++ tmp |= PHY_CONF_TXCLKEN;
++ davinci_eth_phy_write(active_phy_addr, PHY_CONF_REG, tmp);
++ davinci_eth_phy_read(active_phy_addr, PHY_CONF_REG, &tmp);
++#endif
+ return(1);
+ }
+diff --git a/drivers/net/davinci_emac.h b/drivers/net/davinci_emac.h
+new file mode 100644
+index 0000000..3c8e0e1
+--- /dev/null
++++ b/drivers/net/davinci_emac.h
+@@ -0,0 +1,340 @@
++/*
++ * Copyright (C) 2010 Texas Instruments
++ *
++ * 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.
++ * ver, 1.1: May 2010, Cleanup - moved platform independent definitions to
++ * separate driver header file(this file).
++ *
++ */
++
++#ifndef _DAVINCI_EMAC_H_
++#define _DAVINCI_EMAC_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;
++
++/* 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
++/* PHY Configuration register */
++#define PHY_CONF_REG 22
++#define PHY_CONF_TXCLKEN (1 << 5)
++
++/* 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_MIIEN_ENABLE (0x20)
++#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE (0x1)
++#define EMAC_MACCONTROL_GIGABIT_ENABLE (1 << 7)
++#define EMAC_MACCONTROL_GIGFORCE (1 << 17)
++#define EMAC_MACCONTROL_RMIISPEED_100 (1 << 15)
++
++#define EMAC_MAC_ADDR_MATCH (1 << 19)
++#define EMAC_MAC_ADDR_IS_VALID (1 << 20)
++
++#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 {
++#ifdef DAVINCI_EMAC_VERSION2
++ dv_reg idver;
++ dv_reg softrst;
++ dv_reg emctrl;
++ 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;
++#else
++ u_int8_t RSVD0[4100];
++ dv_reg EWCTL;
++ dv_reg EWINTTCNT;
++#endif
++} 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 davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data);
++int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data);
++void davinci_eth_set_mac_addr(const u_int8_t *addr);
++
++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 /* _DAVINCI_EMAC_H_ */
+diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
+index 8eeb48f..1a1b96c 100644
+--- a/drivers/serial/ns16550.c
++++ b/drivers/serial/ns16550.c
+@@ -31,7 +31,7 @@
+ void NS16550_init (NS16550_t com_port, int baud_divisor)
+ {
+ serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
+-#if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)
++#if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || defined(CONFIG_TI81XX)
+ serial_out(0x7, &com_port->mdr1); /* mode select reset TL16C750*/
+ #endif
+ serial_out(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr);
+@@ -44,7 +44,7 @@ void NS16550_init (NS16550_t com_port, int baud_divisor)
+ serial_out(baud_divisor & 0xff, &com_port->dll);
+ serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
+ serial_out(UART_LCRVAL, &com_port->lcr);
+-#if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)
++#if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || defined(CONFIG_TI81XX)
+ #if defined(CONFIG_APTIX)
+ serial_out(3, &com_port->mdr1); /* /13 mode so Aptix 6MHz can hit 115200 */
+ #else
+diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
+index af12c0e..7446ff7 100644
+--- a/drivers/spi/omap3_spi.c
++++ b/drivers/spi/omap3_spi.c
+@@ -86,6 +86,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ case 0:
+ ds->regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
+ break;
++#if !defined CONFIG_TI81XX || defined CONFIG_AM335X
+ case 1:
+ ds->regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
+ break;
+@@ -95,6 +96,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ case 3:
+ ds->regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
+ break;
++#endif
+ default:
+ printf("SPI error: unsupported bus %i. \
+ Supported busses 0 - 3\n", bus);
+@@ -102,10 +104,21 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ }
+ ds->slave.bus = bus;
+
++ ds->data_lines_reversed = 0;
++#ifdef CONFIG_TI81XX
++#ifndef CONFIG_AM335X
++ if ((bus == 0) && (cs > 3)) {
++ ds->data_lines_reversed = 1;
++#else
++ if (((bus == 0) && (cs > 1))
++ || ((bus == 1) && (cs > 1))) {
++#endif
++#else
+ if (((bus == 0) && (cs > 3)) ||
+ ((bus == 1) && (cs > 1)) ||
+ ((bus == 2) && (cs > 1)) ||
+ ((bus == 3) && (cs > 0))) {
++#endif
+ printf("SPI error: unsupported chip select %i \
+ on bus %i\n", cs, bus);
+ return NULL;
+@@ -114,7 +127,8 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+
+ if (max_hz > OMAP3_MCSPI_MAX_FREQ) {
+ printf("SPI error: unsupported frequency %i Hz. \
+- Max frequency is 48 Mhz\n", max_hz);
++ Max frequency is %d Mhz\n", max_hz,
++ (OMAP3_MCSPI_MAX_FREQ/1000/1000));
+ return NULL;
+ }
+ ds->freq = max_hz;
+@@ -164,11 +178,20 @@ int spi_claim_bus(struct spi_slave *slave)
+
+ conf = readl(&ds->regs->channel[ds->slave.cs].chconf);
+
+- /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS
++ /* channel defaults - 1.5 clock TCS and FIFO mode for TX/RX */
++ conf |= OMAP3_MCSPI_CHCONF_TCS | OMAP3_MCSPI_CHCONF_FFEW |
++ OMAP3_MCSPI_CHCONF_FFER;
++
++ /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS
+ * REVISIT: this controller could support SPI_3WIRE mode.
+ */
+- conf &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
+- conf |= OMAP3_MCSPI_CHCONF_DPE0;
++ if (!ds->data_lines_reversed) {
++ conf &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
++ conf |= OMAP3_MCSPI_CHCONF_DPE0;
++ } else {
++ conf &= ~OMAP3_MCSPI_CHCONF_DPE0;
++ conf |= (OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
++ }
+
+ /* wordlength */
+ conf &= ~OMAP3_MCSPI_CHCONF_WL_MASK;
+diff --git a/drivers/spi/omap3_spi.h b/drivers/spi/omap3_spi.h
+index b8e3a4c..77cd3fe 100644
+--- a/drivers/spi/omap3_spi.h
++++ b/drivers/spi/omap3_spi.h
+@@ -30,12 +30,28 @@
+ #ifndef _OMAP3_SPI_H_
+ #define _OMAP3_SPI_H_
+
++#if defined(CONFIG_TI816X)
++#define OMAP3_MCSPI1_BASE 0x48030100
++#define OMAP3_MCSPI_MAX_FREQ 125000000
++#elif defined(CONFIG_TI814X)
++#define OMAP3_MCSPI1_BASE 0x48030100
++#define OMAP3_MCSPI2_BASE 0x481A0000
++#define OMAP3_MCSPI3_BASE 0x481A2000
++#define OMAP3_MCSPI4_BASE 0x481A4000
++#define OMAP3_MCSPI_MAX_FREQ 125000000
++#elif defined(CONFIG_AM335X)
++#define OMAP3_MCSPI1_BASE 0x48030100
++#define OMAP3_MCSPI2_BASE 0x481A0100
++#define OMAP3_MCSPI3_BASE 0x480B8000
++#define OMAP3_MCSPI4_BASE 0x480BA000
++#define OMAP3_MCSPI_MAX_FREQ 80000000
++#else
+ #define OMAP3_MCSPI1_BASE 0x48098000
++#define OMAP3_MCSPI_MAX_FREQ 48000000
+ #define OMAP3_MCSPI2_BASE 0x4809A000
+ #define OMAP3_MCSPI3_BASE 0x480B8000
+ #define OMAP3_MCSPI4_BASE 0x480BA000
+-
+-#define OMAP3_MCSPI_MAX_FREQ 48000000
++#endif
+
+ /* OMAP3 McSPI registers */
+ struct mcspi_channel {
+@@ -88,6 +104,10 @@ struct mcspi {
+ #define OMAP3_MCSPI_CHCONF_IS (1 << 18)
+ #define OMAP3_MCSPI_CHCONF_TURBO (1 << 19)
+ #define OMAP3_MCSPI_CHCONF_FORCE (1 << 20)
++#define OMAP3_MCSPI_CHCONF_TCS (1 << 25)
++#define OMAP3_MCSPI_CHCONF_FFEW (1 << 27)
++#define OMAP3_MCSPI_CHCONF_FFER (1 << 28)
++
+
+ #define OMAP3_MCSPI_CHSTAT_RXS (1 << 0)
+ #define OMAP3_MCSPI_CHSTAT_TXS (1 << 1)
+@@ -102,6 +122,7 @@ struct omap3_spi_slave {
+ struct mcspi *regs;
+ unsigned int freq;
+ unsigned int mode;
++ unsigned char data_lines_reversed;
+ };
+
+ static inline struct omap3_spi_slave *to_omap3_spi(struct spi_slave *slave)
+diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
+new file mode 100755
+index 0000000..41a3316
+--- /dev/null
++++ b/include/configs/am335x_evm.h
+@@ -0,0 +1,410 @@
++/*
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#ifndef __CONFIG_AM335X_EVM_H
++#define __CONFIG_AM335X_EVM_H
++
++#define CONFIG_AM335X
++#define CONFIG_TI81XX
++#define CONFIG_SYS_NO_FLASH
++#define CONFIG_NAND_ENV
++
++#include <asm/arch/cpu.h> /* get chip and board defs */
++#include <asm/arch/hardware.h>
++
++#define CONFIG_AM335X_HSMMC_INSTANCE 0 /* 0 - MMC0, 1 - MMC1 */
++
++#include <config_cmd_default.h>
++
++#define CONFIG_ENV_SIZE 0x2000
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (32 * 1024))
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_SYS_LONGHELP
++#define CONFIG_SYS_PROMPT "U-Boot# "
++/* Use HUSH parser to allow command parsing */
++#define CONFIG_SYS_HUSH_PARSER
++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
++#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS
++#define CONFIG_INITRD_TAG /* Required for ramdisk support */
++
++/* set to negative value for no autoboot */
++#define CONFIG_BOOTDELAY 3
++
++#define CONFIG_MMC
++#define CONFIG_NAND
++#define CONFIG_SPI
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ "bootfile=uImage\0" \
++ "loadaddr=0x82000000\0" \
++ "script_addr=0x81900000\0" \
++ "console=ttyO0,115200n8\0" \
++ "mmc_dev=0\0" \
++ "mmc_root=/dev/mmcblk0p2 rw\0" \
++ "nand_root=/dev/mtdblock7 rw\0" \
++ "spi_root=/dev/mtdblock4 rw\0" \
++ "nor_root=/dev/mtdblock3 rw\0" \
++ "mmc_root_fs_type=ext3 rootwait\0" \
++ "nand_root_fs_type=jffs2\0" \
++ "spi_root_fs_type=jffs2\0" \
++ "nor_root_fs_type=jffs2\0" \
++ "nand_src_addr=0x280000\0" \
++ "spi_src_addr=0x62000\0" \
++ "nor_src_addr=0x08080000\0" \
++ "nand_img_siz=0x500000\0" \
++ "spi_img_siz=0x280000\0" \
++ "nor_img_siz=0x280000\0" \
++ "spi_bus_no=0\0" \
++ "rootpath=/export/rootfs\0" \
++ "nfsopts=nolock\0" \
++ "static_ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}" \
++ "::off\0" \
++ "ip_method=dhcp\0" \
++ "bootenv=uEnv.txt\0" \
++ "loadbootenv=fatload mmc ${mmc_dev} ${loadaddr} ${bootenv}\0" \
++ "importbootenv=echo Importing environment from mmc ...; " \
++ "env import -t $loadaddr $filesize\0" \
++ "mmc_load_uimage=fatload mmc ${mmc_dev} ${loadaddr} ${bootfile}\0" \
++ "optargs=\0" \
++ "bootargs_defaults=setenv bootargs " \
++ "console=${console} " \
++ "${optargs}\0" \
++ "mmc_args=run bootargs_defaults;" \
++ "setenv bootargs ${bootargs} " \
++ "root=${mmc_root} " \
++ "rootfstype=${mmc_root_fs_type} ip=${ip_method}\0" \
++ "nand_args=run bootargs_defaults;" \
++ "setenv bootargs ${bootargs} " \
++ "root=${nand_root} noinitrd " \
++ "rootfstype=${nand_root_fs_type} ip=${ip_method}\0" \
++ "spi_args=run bootargs_defaults;" \
++ "setenv bootargs ${bootargs} " \
++ "root=${spi_root} " \
++ "rootfstype=${spi_root_fs_type} ip=${ip_method}\0" \
++ "nor_args=run bootargs_defaults;" \
++ "setenv bootargs ${bootargs} " \
++ "root={nor_root} " \
++ "rootfstype=${nor_root_fs_type} ip=${ip_method}\0" \
++ "net_args=run bootargs_defaults;" \
++ "setenv bootargs ${bootargs} " \
++ "root=/dev/nfs " \
++ "nfsroot=${serverip}:${rootpath},${nfsopts} rw " \
++ "ip=${ip_method}\0" \
++ "mmc_boot=run mmc_args; " \
++ "run mmc_load_uimage; " \
++ "bootm ${loadaddr}\0" \
++ "nand_boot=echo Booting from nand ...; " \
++ "run nand_args; " \
++ "nand read.i ${loadaddr} ${nand_src_addr} ${nand_img_siz}; " \
++ "bootm ${loadaddr}\0" \
++ "spi_boot=echo Booting from spi ...; " \
++ "run spi_args; " \
++ "sf probe ${spi_bus_no}:0; " \
++ "sf read ${loadaddr} ${spi_src_addr} ${spi_img_siz}; " \
++ "bootm ${loadaddr}\0" \
++ "nor_boot=echo Booting from NOR ...; " \
++ "run nor_args; " \
++ "cp.b ${0x08080000} ${loadaddr} ${nor_img_siz}; " \
++ "bootm ${loadaddr}\0" \
++ "net_boot=echo Booting from network ...; " \
++ "setenv autoload no; " \
++ "dhcp; " \
++ "tftp ${loadaddr} ${bootfile}; " \
++ "run net_args; " \
++ "bootm ${loadaddr}\0" \
++
++#define CONFIG_BOOTCOMMAND \
++ "if mmc rescan; then " \
++ "echo SD/MMC found on device ${mmc_dev};" \
++ "if run loadbootenv; then " \
++ "echo Loaded environment from ${bootenv};" \
++ "run importbootenv;" \
++ "fi;" \
++ "if test -n $uenvcmd; then " \
++ "echo Running uenvcmd ...;" \
++ "run uenvcmd;" \
++ "fi;" \
++ "if run mmc_load_uimage; then " \
++ "run mmc_args;" \
++ "bootm ${loadaddr};" \
++ "fi;" \
++ "fi;" \
++ "run nand_boot;" \
++
++#define CONFIG_MISC_INIT_R
++#define CONFIG_SYS_AUTOLOAD "yes"
++#define CONFIG_CMD_CACHE
++#define CONFIG_CMD_ECHO
++
++/* max number of command args */
++#define CONFIG_SYS_MAXARGS 32
++/* Console I/O Buffer Size */
++#define CONFIG_SYS_CBSIZE 512
++/* Print Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \
++ + sizeof(CONFIG_SYS_PROMPT) + 16)
++/* Boot Argument Buffer Size */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
++/*
++ * memtest works on 8 MB in DRAM after skipping 32MB from
++ * start addr of ram disk
++ */
++#define CONFIG_SYS_MEMTEST_START (PHYS_DRAM_1 + (64 * 1024 * 1024))
++#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START \
++ + (8 * 1024 * 1024))
++
++#define CONFIG_SYS_LOAD_ADDR 0x81000000 /* Default load address */
++
++ /* Physical Memory Map */
++#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
++#define PHYS_DRAM_1 0x80000000 /* DRAM Bank #1 */
++#define PHYS_DRAM_1_SIZE 0x10000000 /* 256 MiB */
++
++#define CONFIG_SYS_SDRAM_BASE PHYS_DRAM_1
++#define CONFIG_SYS_INIT_RAM_ADDR SRAM0_START
++#define CONFIG_SYS_INIT_RAM_SIZE SRAM0_SIZE
++#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
++ CONFIG_SYS_INIT_RAM_SIZE - \
++ GENERATED_GBL_DATA_SIZE)
++
++/* Defines for SPL */
++#define CONFIG_SPL
++#define CONFIG_SPL_BOARD_INIT
++#define CONFIG_SPL_TEXT_BASE 0x402F0400
++#define CONFIG_SPL_MAX_SIZE (46 * 1024)
++#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
++
++#define CONFIG_SPL_BSS_START_ADDR 0x80000000
++#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 /* 512 KB */
++
++#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 /* address 0x60000 */
++#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x200 /* 256 KB */
++#define CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION 1
++#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME "u-boot.img"
++#define CONFIG_SPL_MMC_SUPPORT
++#define CONFIG_SPL_FAT_SUPPORT
++
++#define CONFIG_SPL_LIBCOMMON_SUPPORT
++#define CONFIG_SPL_LIBDISK_SUPPORT
++#define CONFIG_SPL_I2C_SUPPORT
++#define CONFIG_SPL_LIBGENERIC_SUPPORT
++#define CONFIG_SPL_SERIAL_SUPPORT
++#define CONFIG_SPL_YMODEM_SUPPORT
++#define CONFIG_SPL_POWER_SUPPORT
++#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/omap-common/u-boot-spl.lds"
++
++/* NAND boot config */
++#define CONFIG_SPL_NAND_SIMPLE
++#define CONFIG_SPL_NAND_SUPPORT
++#define CONFIG_SYS_NAND_5_ADDR_CYCLE
++#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \
++ CONFIG_SYS_NAND_PAGE_SIZE)
++#define CONFIG_SYS_NAND_PAGE_SIZE 2048
++#define CONFIG_SYS_NAND_OOBSIZE 64
++#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)
++#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS
++#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \
++ 10, 11, 12, 13, 14, 15, 16, 17, \
++ 18, 19, 20, 21, 22, 23, 24, 25, \
++ 26, 27, 28, 29, 30, 31, 32, 33, \
++ 34, 35, 36, 37, 38, 39, 40, 41, \
++ 42, 43, 44, 45, 46, 47, 48, 49, \
++ 50, 51, 52, 53, 54, 55, 56, 57, }
++
++#define CONFIG_SYS_NAND_ECCSIZE 512
++#define CONFIG_SYS_NAND_ECCBYTES 14
++
++#define CONFIG_SYS_NAND_ECCSTEPS 4
++#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
++ CONFIG_SYS_NAND_ECCSTEPS)
++
++#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
++
++#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
++
++/*
++ * 8MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM.
++ * 64 bytes before this address should be set aside for u-boot.img's
++ * header. That is 0x807FFFC0--0x80800000 should not be used for any
++ * other needs.
++ */
++#define CONFIG_SYS_TEXT_BASE 0x80800000
++
++/* Since SPL did all of this for us, we don't need to do it twice. */
++#ifndef CONFIG_SPL_BUILD
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#endif
++
++/**
++ * Clock related defines
++ */
++#define V_OSCK 24000000 /* Clock output from T2 */
++#define V_SCLK (V_OSCK)
++#define CONFIG_SYS_TIMERBASE 0x48040000 /* Use Timer2 */
++#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */
++#define CONFIG_SYS_HZ 1000
++
++/* NS16550 Configuration */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE (-4)
++#define CONFIG_SYS_NS16550_CLK (48000000)
++#define CONFIG_SYS_NS16550_COM1 0x44e09000 /* Base EVM has UART0 */
++#define CONFIG_SYS_NS16550_COM4 0x481A6000 /* UART3 on IA BOard */
++
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 110, 300, 600, 1200, 2400, \
++4800, 9600, 14400, 19200, 28800, 38400, 56000, 57600, 115200 }
++
++/*
++ * select serial console configuration
++ */
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 1
++#define CONFIG_SYS_CONSOLE_INFO_QUIET
++
++#if defined(CONFIG_NO_ETH)
++# undef CONFIG_CMD_NET
++#else
++# define CONFIG_CMD_DHCP
++# define CONFIG_CMD_PING
++#endif
++
++#if defined(CONFIG_CMD_NET)
++# define CONFIG_DRIVER_TI_CPSW
++# define CONFIG_MII
++# define CONFIG_BOOTP_DEFAULT
++# define CONFIG_BOOTP_DNS
++# define CONFIG_BOOTP_DNS2
++# define CONFIG_BOOTP_SEND_HOSTNAME
++# define CONFIG_BOOTP_GATEWAY
++# define CONFIG_BOOTP_SUBNETMASK
++# define CONFIG_NET_RETRY_COUNT 10
++# define CONFIG_NET_MULTI
++# define CONFIG_PHY_GIGE
++#endif
++
++#if defined(CONFIG_SYS_NO_FLASH)
++# define CONFIG_ENV_IS_NOWHERE
++#endif
++
++/* NAND support */
++#ifdef CONFIG_NAND
++#define CONFIG_CMD_NAND
++#define CONFIG_NAND_TI81XX
++#define GPMC_NAND_ECC_LP_x16_LAYOUT 1
++#define NAND_BASE (0x08000000)
++#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */
++ /* to access nand */
++#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */
++ /* to access nand at */
++ /* CS0 */
++#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */
++#endif /* devices */
++
++/* ENV in NAND */
++#if defined(CONFIG_NAND_ENV)
++#undef CONFIG_ENV_IS_NOWHERE
++#define CONFIG_ENV_IS_IN_NAND
++#define CONFIG_SYS_MAX_FLASH_SECT 520 /* max no of sectors in a chip */
++#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max no of flash banks */
++#define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */
++#define CONFIG_SYS_FLASH_BASE PISMO1_NAND_BASE
++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
++#define MNAND_ENV_OFFSET 0x260000 /* environment starts here */
++#define CONFIG_SYS_ENV_SECT_SIZE (128 << 10) /* 128 KiB */
++#define CONFIG_ENV_OFFSET MNAND_ENV_OFFSET
++#define CONFIG_ENV_ADDR MNAND_ENV_OFFSET
++#endif /* NAND support */
++
++/*
++ * NOR Size = 16 MB
++ * No.Of Sectors/Blocks = 128
++ * Sector Size = 128 KB
++ * Word lenght = 16 bits
++ */
++#if defined(CONFIG_NOR)
++# undef CONFIG_ENV_IS_NOWHERE
++# undef CONFIG_SYS_MALLOC_LEN
++# define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1
++# define CONFIG_SYS_MALLOC_LEN (0x100000)
++# define CONFIG_SYS_FLASH_CFI
++# define CONFIG_FLASH_CFI_DRIVER
++# define CONFIG_FLASH_CFI_MTD
++# define CONFIG_SYS_MAX_FLASH_SECT 128
++# define CONFIG_SYS_MAX_FLASH_BANKS 1
++# define CONFIG_SYS_FLASH_BASE (0x08000000)
++# define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
++# define CONFIG_ENV_IS_IN_FLASH 1
++# define NOR_SECT_SIZE (128 * 1024)
++# define CONFIG_SYS_ENV_SECT_SIZE (NOR_SECT_SIZE)
++# define CONFIG_ENV_SECT_SIZE (NOR_SECT_SIZE)
++# define CONFIG_ENV_OFFSET (8 * NOR_SECT_SIZE) /* After 1 MB */
++# define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + \
++ CONFIG_ENV_OFFSET)
++# define CONFIG_MTD_DEVICE
++#endif /* NOR support */
++
++/* SPI support */
++#ifdef CONFIG_SPI
++#define BOARD_LATE_INIT
++#define CONFIG_OMAP3_SPI
++#define CONFIG_MTD_DEVICE
++#define CONFIG_SPI_FLASH
++#define CONFIG_SPI_FLASH_WINBOND
++#define CONFIG_CMD_SF
++#define CONFIG_SF_DEFAULT_SPEED (75000000)
++#endif
++
++/* ENV in SPI */
++#if defined(CONFIG_SPI_ENV)
++# undef CONFIG_ENV_IS_NOWHERE
++# define CONFIG_ENV_IS_IN_SPI_FLASH
++# define CONFIG_SYS_FLASH_BASE (0)
++# define SPI_FLASH_ERASE_SIZE (4 * 1024) /* sector size */
++# define CONFIG_SYS_ENV_SECT_SIZE (2 * SPI_FLASH_ERASE_SIZE)
++# define CONFIG_ENV_SECT_SIZE (CONFIG_SYS_ENV_SECT_SIZE)
++# define CONFIG_ENV_OFFSET (96 * SPI_FLASH_ERASE_SIZE)
++# define CONFIG_ENV_ADDR (CONFIG_ENV_OFFSET)
++# define CONFIG_SYS_MAX_FLASH_SECT (1024) /* # of sectors in SPI flash */
++# define CONFIG_SYS_MAX_FLASH_BANKS (1)
++#endif /* SPI support */
++
++/* I2C */
++#define CONFIG_I2C
++#define CONFIG_CMD_I2C
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_I2C_MULTI_BUS
++#define CONFIG_DRIVER_TI81XX_I2C
++
++/* HSMMC support */
++#ifdef CONFIG_MMC
++#if (CONFIG_AM335X_HSMMC_INSTANCE == 0)
++#define CONFIG_AM335X_HSMMC_BASE 0x48060100
++#else
++#define CONFIG_AM335X_HSMMC_BASE 0x481D8100
++#endif
++#define CONFIG_GENERIC_MMC
++#define CONFIG_OMAP_HSMMC
++#define CONFIG_CMD_MMC
++#define CONFIG_DOS_PARTITION
++#define CONFIG_CMD_FAT
++#define CONFIG_CMD_EXT2
++#endif
++
++/* Unsupported features */
++#undef CONFIG_USE_IRQ
++
++#endif /* ! __CONFIG_AM335X_EVM_H */
+diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h
+index 72dd6f0..c98f2e4 100644
+--- a/include/configs/am3517_evm.h
++++ b/include/configs/am3517_evm.h
+@@ -148,12 +148,13 @@
+ #define CONFIG_CMD_DHCP
+ #define CONFIG_CMD_PING
+
+-#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */
++#undef CONFIG_CMD_FLASH
++#define CONFIG_SYS_NO_FLASH
++
+ #undef CONFIG_CMD_FPGA /* FPGA configuration Support */
+ #undef CONFIG_CMD_IMI /* iminfo */
+ #undef CONFIG_CMD_IMLS /* List all found images */
+
+-#define CONFIG_SYS_NO_FLASH
+ #define CONFIG_HARD_I2C 1
+ #define CONFIG_SYS_I2C_SPEED 100000
+ #define CONFIG_SYS_I2C_SLAVE 1
+@@ -161,8 +162,7 @@
+ #define CONFIG_SYS_I2C_BUS_SELECT 1
+ #define CONFIG_DRIVER_OMAP34XX_I2C 1
+
+-#undef CONFIG_CMD_NET
+-#undef CONFIG_CMD_NFS
++#define CONFIG_CMD_NET
+ /*
+ * Board NAND Info.
+ */
+@@ -289,18 +289,8 @@
+ #define PISMO1_NAND_SIZE GPMC_SIZE_128M
+ #define PISMO1_ONEN_SIZE GPMC_SIZE_128M
+
+-#define CONFIG_SYS_MAX_FLASH_SECT 520 /* max number of sectors */
+- /* on one chip */
+-#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max number of flash banks */
+ #define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */
+
+-#if defined(CONFIG_CMD_NAND)
+-#define CONFIG_SYS_FLASH_BASE PISMO1_NAND_BASE
+-#endif
+-
+-/* Monitor at start of flash */
+-#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
+-
+ #define CONFIG_NAND_OMAP_GPMC
+ #define GPMC_NAND_ECC_LP_x16_LAYOUT 1
+ #define CONFIG_ENV_IS_IN_NAND 1
+@@ -313,6 +303,30 @@
+ /*-----------------------------------------------------------------------
+ * CFI FLASH driver setup
+ */
++#if defined (CONFIG_CMD_FLASH)
++#define CONFIG_SYS_FLASH_BASE DEBUG_BASE
++#define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */
++#define CONFIG_SYS_FLASH_CFI 1 /* use CFI geometry data */
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1 /* ~10x faster writes */
++#define CONFIG_SYS_FLASH_PROTECTION 1 /* hardware sector protection */
++#define CONFIG_SYS_FLASH_EMPTY_INFO 1 /* flinfo 'E' for empty */
++#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE}
++#define CONFIG_SYS_FLASH_CFI_WIDTH 2
++#define PHYS_FLASH_SIZE (8 << 20)
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of flash banks */
++
++#else /* CONFIG_CMD_FLASH */
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max number of flash banks */
++#define CONFIG_SYS_FLASH_BASE boot_flash_base
++
++#endif /* CONFIG_CMD_FLASH */
++
++#define CONFIG_SYS_MAX_FLASH_SECT 512 /* max sectors on one chip */
++/* Monitor at start of flash */
++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
++
+ /* timeout values are in ticks */
+ #define CONFIG_SYS_FLASH_ERASE_TOUT (100 * CONFIG_SYS_HZ)
+ #define CONFIG_SYS_FLASH_WRITE_TOUT (100 * CONFIG_SYS_HZ)
+@@ -325,10 +339,27 @@
+ #define CONFIG_SYS_JFFS2_FIRST_BANK CONFIG_SYS_MAX_FLASH_BANKS
+ #define CONFIG_SYS_JFFS2_NUM_BANKS 1
+
++/*-----------------------------------------------------
++ * ethernet support for AM3517 EVM
++ *------------------------------------------------
++ */
++#if defined(CONFIG_CMD_NET)
++#define CONFIG_DRIVER_TI_EMAC
++#define CONFIG_DRIVER_TI_EMAC_USE_RMII
++#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
++#define CONFIG_NET_MULTI
++#endif
++
+ #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+ #define CONFIG_SYS_INIT_RAM_ADDR 0x4020f800
+ #define CONFIG_SYS_INIT_RAM_SIZE 0x800
+ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
+ CONFIG_SYS_INIT_RAM_SIZE - \
+ GENERATED_GBL_DATA_SIZE)
++
+ #endif /* __CONFIG_H */
+diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h
+index 710092d..1d49b86 100644
+--- a/include/configs/devkit8000.h
++++ b/include/configs/devkit8000.h
+@@ -308,4 +308,50 @@
+ CONFIG_SYS_INIT_RAM_SIZE - \
+ GENERATED_GBL_DATA_SIZE)
+
++/* SRAM config */
++#define CONFIG_SYS_SRAM_START 0x40200000
++#define CONFIG_SYS_SRAM_SIZE 0x10000
++
++/* Defines for SPL */
++#define CONFIG_SPL
++#define CONFIG_SPL_NAND_SIMPLE
++
++#define CONFIG_SPL_LIBCOMMON_SUPPORT
++#define CONFIG_SPL_LIBDISK_SUPPORT
++#define CONFIG_SPL_I2C_SUPPORT
++#define CONFIG_SPL_LIBGENERIC_SUPPORT
++#define CONFIG_SPL_SERIAL_SUPPORT
++#define CONFIG_SPL_POWER_SUPPORT
++#define CONFIG_SPL_NAND_SUPPORT
++#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/omap-common/u-boot-spl.lds"
++
++#define CONFIG_SPL_TEXT_BASE 0x40200000 /*CONFIG_SYS_SRAM_START*/
++#define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */
++#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
++
++#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/
++#define CONFIG_SPL_BSS_MAX_SIZE 0x80000
++
++/* NAND boot config */
++#define CONFIG_SYS_NAND_PAGE_COUNT 64
++#define CONFIG_SYS_NAND_PAGE_SIZE 2048
++#define CONFIG_SYS_NAND_OOBSIZE 64
++#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)
++#define CONFIG_SYS_NAND_BAD_BLOCK_POS 0
++#define CONFIG_SYS_NAND_ECCPOS {2, 3, 4, 5, 6, 7, 8, 9,\
++ 10, 11, 12, 13}
++
++#define CONFIG_SYS_NAND_ECCSIZE 512
++#define CONFIG_SYS_NAND_ECCBYTES 3
++
++#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
++ CONFIG_SYS_NAND_ECCSIZE)
++#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
++ CONFIG_SYS_NAND_ECCSTEPS)
++
++#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
++
++#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
++#define CONFIG_SYS_NAND_U_BOOT_SIZE 0x200000
++
+ #endif /* __CONFIG_H */
+diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
+index 1369c89..97daa04 100644
+--- a/include/configs/omap3_beagle.h
++++ b/include/configs/omap3_beagle.h
+@@ -120,26 +120,46 @@
+ /* Probe all devices */
+ #define CONFIG_SYS_I2C_NOPROBES {{0x0, 0x0}}
+
+-/* USB */
+-#define CONFIG_MUSB_UDC 1
+-#define CONFIG_USB_OMAP3 1
+-#define CONFIG_TWL4030_USB 1
++/* USB
++ * Enable CONFIG_MUSB_HCD for Host functionalities MSC, keyboard
++ * Enable CONFIG_MUSB_UDC for Device functionalities. Enable CONFIG_USB_EHCI
++ * to use the EHCI driver for Host functionalities.
++ */
++#define CONFIG_USB_OMAP3
++#define CONFIG_MUSB_HCD
++/* #define CONFIG_MUSB_UDC */
++/* #define CONFIG_USB_EHCI */
++/* #define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 */
++#define CONFIG_TWL4030_USB
+
+-/* USB device configuration */
+-#define CONFIG_USB_DEVICE 1
+-#define CONFIG_USB_TTY 1
+-#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1
++#ifdef CONFIG_USB_OMAP3
+
+-/* USB EHCI */
++#ifdef CONFIG_MUSB_HCD
+ #define CONFIG_CMD_USB
+-#define CONFIG_USB_EHCI
+-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
+ #define CONFIG_USB_HOST_ETHER
+ #define CONFIG_USB_ETHER_SMSC95XX
+ #define CONFIG_USB_ETHER_ASIX
+
+ #define CONFIG_NET_MULTI
+
++#define CONFIG_USB_STORAGE
++#define CONGIG_CMD_STORAGE
++#define CONFIG_CMD_FAT
++
++#ifdef CONFIG_USB_KEYBOARD
++#define CONFIG_SYS_USB_EVENT_POLL
++#define CONFIG_PREBOOT "usb start"
++#endif /* CONFIG_USB_KEYBOARD */
++
++#endif /* CONFIG_MUSB_HCD */
++
++#ifdef CONFIG_MUSB_UDC
++/* USB device configuration */
++#define CONFIG_USB_DEVICE
++#define CONFIG_USB_TTY
++#define CONFIG_SYS_CONSOLE_IS_IN_ENV
++#endif /* CONFIG_MUSB_UDC */
++#endif /* CONFIG_USB_OMAP3 */
+ /* commands to include */
+ #include <config_cmd_default.h>
+
+@@ -216,7 +236,7 @@
+ "rdaddr=0x81000000\0" \
+ "usbtty=cdc_acm\0" \
+ "bootfile=uImage.beagle\0" \
+- "console=ttyS2,115200n8\0" \
++ "console=ttyO2,115200n8\0" \
+ "mpurate=auto\0" \
+ "buddy=none "\
+ "optargs=\0" \
+diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h
+index fdc861d..d1fefdc 100644
+--- a/include/configs/omap3_evm.h
++++ b/include/configs/omap3_evm.h
+@@ -200,7 +200,7 @@
+ "loadaddr=0x82000000\0" \
+ "usbtty=cdc_acm\0" \
+ "mmcdev=0\0" \
+- "console=ttyS2,115200n8\0" \
++ "console=ttyO0,115200n8\0" \
+ "mmcargs=setenv bootargs console=${console} " \
+ "root=/dev/mmcblk0p2 rw " \
+ "rootfstype=ext3 rootwait\0" \
+@@ -243,7 +243,7 @@
+ /* Print Buffer Size */
+ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+-#define CONFIG_SYS_MAXARGS 16 /* max number of command */
++#define CONFIG_SYS_MAXARGS 32 /* max number of command */
+ /* args */
+ /* Boot Argument Buffer Size */
+ #define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE)
+diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h
+index 3f37263..2d15017 100644
+--- a/include/configs/omap3_overo.h
++++ b/include/configs/omap3_overo.h
+@@ -215,7 +215,7 @@
+ /* Print Buffer Size */
+ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+-#define CONFIG_SYS_MAXARGS 16 /* max number of command */
++#define CONFIG_SYS_MAXARGS 32 /* max number of command */
+ /* args */
+ /* Boot Argument Buffer Size */
+ #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+diff --git a/include/configs/omap3_pandora.h b/include/configs/omap3_pandora.h
+index 3c2793e..8e6eb1d 100644
+--- a/include/configs/omap3_pandora.h
++++ b/include/configs/omap3_pandora.h
+@@ -201,7 +201,7 @@
+ /* Print Buffer Size */
+ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+-#define CONFIG_SYS_MAXARGS 16 /* max number of command */
++#define CONFIG_SYS_MAXARGS 32 /* max number of command */
+ /* args */
+ /* Boot Argument Buffer Size */
+ #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+diff --git a/include/configs/omap3_sdp3430.h b/include/configs/omap3_sdp3430.h
+index 6a826ba..210b7d1 100644
+--- a/include/configs/omap3_sdp3430.h
++++ b/include/configs/omap3_sdp3430.h
+@@ -274,7 +274,7 @@
+ /* Print Buffer Size */
+ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+-#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_MAXARGS 32 /* max number of command args */
+ /* Boot Argument Buffer Size */
+ #define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE)
+
+diff --git a/include/configs/omap3_zoom1.h b/include/configs/omap3_zoom1.h
+index fbac222..b721e78 100644
+--- a/include/configs/omap3_zoom1.h
++++ b/include/configs/omap3_zoom1.h
+@@ -226,7 +226,7 @@
+ /* Print Buffer Size */
+ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+-#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_MAXARGS 32 /* max number of command args */
+ /* Boot Argument Buffer Size */
+ #define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE)
+
+diff --git a/include/configs/omap3_zoom2.h b/include/configs/omap3_zoom2.h
+index 8de3d31..2aed05f 100644
+--- a/include/configs/omap3_zoom2.h
++++ b/include/configs/omap3_zoom2.h
+@@ -204,7 +204,7 @@
+ #define CONFIG_SYS_CBSIZE 512
+ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+-#define CONFIG_SYS_MAXARGS 16
++#define CONFIG_SYS_MAXARGS 32
+ #define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE)
+ /* Memtest from start of memory to 31MB */
+ #define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0)
+diff --git a/include/configs/ti8148_evm.h b/include/configs/ti8148_evm.h
+new file mode 100644
+index 0000000..7842463
+--- /dev/null
++++ b/include/configs/ti8148_evm.h
+@@ -0,0 +1,348 @@
++/*
++ * Copyright (C) 2009, Texas Instruments, Incorporated
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __CONFIG_TI8148_EVM_H
++#define __CONFIG_TI8148_EVM_H
++
++#define CONFIG_TI81XX
++#define CONFIG_TI814X
++#define CONFIG_SYS_NO_FLASH
++#define CONFIG_NAND_ENV
++
++#include <asm/arch/cpu.h> /* get chip and board defs */
++#include <asm/arch/hardware.h>
++
++
++# if defined(CONFIG_SPI_BOOT) /* Autoload the 2nd stage from SPI */
++# define CONFIG_SPI 1
++# define CONFIG_EXTRA_ENV_SETTINGS \
++ "verify=yes\0" \
++ "bootcmd=sf probe 0; sf read 0x81000000 0x20000 0x40000; go 0x81000000\0" \
++
++# elif defined(CONFIG_NAND_BOOT) /* Autoload the 2nd stage from NAND */
++# define CONFIG_NAND 1
++# define CONFIG_EXTRA_ENV_SETTINGS \
++ "verify=yes\0" \
++ "bootcmd=nand read 0x81000000 0x20000 0x40000; go 0x81000000\0" \
++
++# elif defined(CONFIG_SD_BOOT) /* Autoload the 2nd stage from SD */
++# define CONFIG_MMC 1
++# define CONFIG_EXTRA_ENV_SETTINGS \
++ "verify=yes\0" \
++ "bootcmd=mmc rescan; fatload mmc 0:1 0x80800000 u-boot.img; go 0x80800000\0" \
++
++# endif
++
++# include <config_cmd_default.h>
++
++/* Clock Defines */
++#define V_OSCK 24000000 /* Clock output from T2 */
++#define V_SCLK (V_OSCK >> 1)
++
++# define CONFIG_ENV_SIZE 0x2000
++# define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (32 * 1024))
++# define CONFIG_ENV_OVERWRITE
++# define CONFIG_SYS_LONGHELP
++# define CONFIG_SYS_PROMPT "TI8148_EVM# "
++# define CONFIG_SYS_HUSH_PARSER /* Use HUSH parser to allow command parsing */
++# define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
++# define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++# define CONFIG_SETUP_MEMORY_TAGS 1
++# define CONFIG_INITRD_TAG 1 /* Required for ramdisk support */
++# define CONFIG_BOOTDELAY 3 /* set to negative value for no autoboot */
++/* By default, 2nd stage will have MMC, NAND, SPI and I2C support */
++# define CONFIG_MMC 1
++# define CONFIG_NAND 1
++# define CONFIG_SPI 1
++# define CONFIG_I2C 1
++# define CONFIG_EXTRA_ENV_SETTINGS \
++ "verify=yes\0" \
++ "bootfile=uImage\0" \
++ "ramdisk_file=ramdisk.gz\0" \
++ "loadaddr=0x81000000\0" \
++ "script_addr=0x80900000\0" \
++ "loadbootscript=fatload mmc 0:1 ${script_addr} boot.scr\0" \
++ "bootscript= echo Running bootscript from MMC/SD to set the ENV...; " \
++ "source ${script_addr}\0" \
++
++#define CONFIG_SYS_AUTOLOAD "yes"
++#define CONFIG_CMD_CACHE
++#define CONFIG_CMD_ECHO
++
++/*
++ * Miscellaneous configurable options
++ */
++
++/* max number of command args */
++#define CONFIG_SYS_MAXARGS 32
++/* Console I/O Buffer Size */
++#define CONFIG_SYS_CBSIZE 512
++/* Print Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \
++ + sizeof(CONFIG_SYS_PROMPT) + 16)
++/* Boot Argument Buffer Size */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
++/* memtest works on 8 MB in DRAM after skipping 32MB from start addr of ram disk*/
++#define CONFIG_SYS_MEMTEST_START (PHYS_DRAM_1 + (64 *1024 *1024))
++#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START \
++ + (8 * 1024 * 1024))
++
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#define CONFIG_SYS_LOAD_ADDR 0x81000000 /* Default load address */
++
++/**
++ * Physical Memory Map
++ */
++#define CONFIG_NR_DRAM_BANKS 2 /* we have 2 banks of DRAM */
++#define PHYS_DRAM_1 0x80000000 /* DRAM Bank #1 */
++#define PHYS_DRAM_1_SIZE 0x20000000 /* 512MB */
++#define PHYS_DRAM_2 0xA0000000 /* DRAM Bank #2 */
++#define PHYS_DRAM_2_SIZE 0x20000000 /* 512MB */
++
++#define CONFIG_SYS_SDRAM_BASE PHYS_DRAM_1
++#define CONFIG_SYS_INIT_RAM_ADDR SRAM0_START
++#define CONFIG_SYS_INIT_RAM_SIZE SRAM0_SIZE
++#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
++ CONFIG_SYS_INIT_RAM_SIZE - \
++ GENERATED_GBL_DATA_SIZE)
++/* Defines for SPL */
++#define CONFIG_SPL
++#define CONFIG_SPL_TEXT_BASE 0x40300000
++#define CONFIG_SPL_MAX_SIZE ((128 - 18 - 1) * 1024)
++#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
++
++#define CONFIG_SPL_BSS_START_ADDR 0x80000000
++#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 /* 512 KB */
++
++#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 /* address 0x60000 */
++#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x200 /* 256 KB */
++#define CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION 1
++#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME "u-boot.img"
++#define CONFIG_SPL_MMC_SUPPORT
++#define CONFIG_SPL_FAT_SUPPORT
++
++#define CONFIG_SPL_LIBCOMMON_SUPPORT
++#define CONFIG_SPL_LIBDISK_SUPPORT
++#define CONFIG_SPL_I2C_SUPPORT
++#define CONFIG_SPL_LIBGENERIC_SUPPORT
++#define CONFIG_SPL_SERIAL_SUPPORT
++#define CONFIG_SPL_YMODEM_SUPPORT
++#define CONFIG_SPL_POWER_SUPPORT
++#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/omap-common/u-boot-spl.lds"
++
++/* NAND boot config */
++#define CONFIG_SPL_NAND_SIMPLE
++#define CONFIG_SPL_NAND_SUPPORT
++#define CONFIG_SYS_NAND_5_ADDR_CYCLE
++#define CONFIG_SYS_NAND_PAGE_COUNT 64
++#define CONFIG_SYS_NAND_PAGE_SIZE 2048
++#define CONFIG_SYS_NAND_OOBSIZE 64
++#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)
++#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS
++#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \
++ 10, 11, 12, 13, 14, 15, 16, 17, \
++ 18, 19, 20, 21, 22, 23, 24, 25, \
++ 26, 27, 28, 29, 30, 31, 32, 33, \
++ 34, 35, 36, 37, 38, 39, 40, 41, \
++ 42, 43, 44, 45, 46, 47, 48, 49, \
++ 50, 51, 52, 53, 54, 55, 56, 57, }
++
++#define CONFIG_SYS_NAND_ECCSIZE 512
++#define CONFIG_SYS_NAND_ECCBYTES 14
++
++#define CONFIG_SYS_NAND_ECCSTEPS 4
++#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
++ CONFIG_SYS_NAND_ECCSTEPS)
++
++#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
++
++#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
++
++/*
++ * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
++ * 64 bytes before this address should be set aside for u-boot.img's
++ * header. That is 0x800FFFC0--0x80800000 should not be used for any
++ * other needs.
++ */
++#define CONFIG_SYS_TEXT_BASE 0x80800000
++
++/**
++ * Platform/Board specific defs
++ */
++#define CONFIG_SYS_CLK_FREQ 27000000
++#define CONFIG_SYS_TIMERBASE 0x4802E000
++#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */
++#define CONFIG_SYS_HZ 1000
++
++/*
++ * NS16550 Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE (-4)
++#define CONFIG_SYS_NS16550_CLK (48000000)
++#define CONFIG_SYS_NS16550_COM1 0x48020000 /* Base EVM has UART0 */
++
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 110, 300, 600, 1200, 2400, \
++4800, 9600, 14400, 19200, 28800, 38400, 56000, 57600, 115200 }
++
++/*
++ * select serial console configuration
++ */
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 1
++#define CONFIG_SYS_CONSOLE_INFO_QUIET
++
++#if defined(CONFIG_NO_ETH)
++# undef CONFIG_CMD_NET
++# undef CONFIG_CMD_NFS
++#else
++# define CONFIG_CMD_DHCP
++# define CONFIG_CMD_PING
++# define CONFIG_DRIVER_TI_CPSW
++# define CONFIG_MII
++# define CONFIG_BOOTP_DEFAULT
++# define CONFIG_BOOTP_DNS
++# define CONFIG_BOOTP_DNS2
++# define CONFIG_BOOTP_SEND_HOSTNAME
++# define CONFIG_BOOTP_GATEWAY
++# define CONFIG_BOOTP_SUBNETMASK
++# define CONFIG_NET_RETRY_COUNT 10
++# define CONFIG_NET_MULTI
++# define CONFIG_PHY_GIGE
++#endif
++
++#if defined(CONFIG_SYS_NO_FLASH)
++# define CONFIG_ENV_IS_NOWHERE
++#endif
++
++/* NAND support */
++#ifdef CONFIG_NAND
++#define CONFIG_CMD_NAND
++#define CONFIG_NAND_TI81XX
++#define GPMC_NAND_ECC_LP_x16_LAYOUT 1
++#define NAND_BASE (0x08000000)
++#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */
++ /* to access nand */
++#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */
++ /* to access nand at */
++ /* CS0 */
++#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */
++#endif /* devices */
++
++/* ENV in NAND */
++#if defined(CONFIG_NAND_ENV)
++# undef CONFIG_ENV_IS_NOWHERE
++# define CONFIG_ENV_IS_IN_NAND 1
++# ifdef CONFIG_ENV_IS_IN_NAND
++# define CONFIG_SYS_MAX_FLASH_SECT 520 /* max number of sectors in a chip */
++# define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max number of flash banks */
++# define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */
++# define CONFIG_SYS_FLASH_BASE PISMO1_NAND_BASE
++# define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
++# define MNAND_ENV_OFFSET 0x260000 /* environment starts here */
++# define CONFIG_SYS_ENV_SECT_SIZE (128 << 10) /* 128 KiB */
++# define CONFIG_ENV_OFFSET MNAND_ENV_OFFSET
++# define CONFIG_ENV_ADDR MNAND_ENV_OFFSET
++# endif
++#endif /* NAND support */
++
++/* SPI support */
++#ifdef CONFIG_SPI
++#define CONFIG_OMAP3_SPI
++#define CONFIG_MTD_DEVICE
++#define CONFIG_SPI_FLASH
++#define CONFIG_SPI_FLASH_WINBOND
++#define CONFIG_CMD_SF
++#define CONFIG_SF_DEFAULT_SPEED (75000000)
++#endif
++
++/* ENV in SPI */
++#if defined(CONFIG_SPI_ENV)
++# undef CONFIG_ENV_IS_NOWHERE
++# define CONFIG_ENV_IS_IN_SPI_FLASH 1
++# ifdef CONFIG_ENV_IS_IN_SPI_FLASH
++# define CONFIG_SYS_FLASH_BASE (0)
++# define SPI_FLASH_ERASE_SIZE (4 * 1024) /* sector size of SPI flash */
++# define CONFIG_SYS_ENV_SECT_SIZE (2 * SPI_FLASH_ERASE_SIZE) /* env size */
++# define CONFIG_ENV_SECT_SIZE (CONFIG_SYS_ENV_SECT_SIZE)
++# define CONFIG_ENV_OFFSET (96 * SPI_FLASH_ERASE_SIZE)
++# define CONFIG_ENV_ADDR (CONFIG_ENV_OFFSET)
++# define CONFIG_SYS_MAX_FLASH_SECT (1024) /* no of sectors in SPI flash */
++# define CONFIG_SYS_MAX_FLASH_BANKS (1)
++# endif
++#endif /* SPI support */
++
++/* NOR support */
++#if defined(CONFIG_NOR_BOOT)
++# undef CONFIG_CMD_NAND /* Remove NAND support */
++# undef CONFIG_NAND_TI81XX
++# undef CONFIG_ENV_IS_NOWHERE
++# ifdef CONFIG_SYS_MALLOC_LEN
++# undef CONFIG_SYS_MALLOC_LEN
++# endif
++# define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1
++# define CONFIG_SYS_MALLOC_LEN (0x100000)
++# define CONFIG_SYS_FLASH_CFI
++# define CONFIG_FLASH_CFI_DRIVER
++# define CONFIG_FLASH_CFI_MTD
++# define CONFIG_SYS_MAX_FLASH_SECT 512
++# define CONFIG_SYS_MAX_FLASH_BANKS 1
++# define CONFIG_SYS_FLASH_BASE (0x08000000)
++# define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
++# define CONFIG_ENV_IS_IN_FLASH 1
++# define NOR_SECT_SIZE (128 * 1024)
++# define CONFIG_SYS_ENV_SECT_SIZE (NOR_SECT_SIZE)
++# define CONFIG_ENV_SECT_SIZE (NOR_SECT_SIZE)
++# define CONFIG_ENV_OFFSET (2 * NOR_SECT_SIZE)
++# define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
++# define CONFIG_MTD_DEVICE
++#endif /* NOR support */
++
++
++/* No I2C support in 1st stage */
++#ifdef CONFIG_I2C
++
++# define CONFIG_CMD_I2C
++# define CONFIG_HARD_I2C 1
++# define CONFIG_SYS_I2C_SPEED 100000
++# define CONFIG_SYS_I2C_SLAVE 1
++# define CONFIG_SYS_I2C_BUS 0
++# define CONFIG_SYS_I2C_BUS_SELECT 1
++# define CONFIG_DRIVER_TI81XX_I2C 1
++
++/* EEPROM definitions */
++# define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 3
++# define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
++# define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6
++# define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 20
++
++#endif
++
++/* HSMMC support */
++#ifdef CONFIG_MMC
++# define CONFIG_GENERIC_MMC
++# define CONFIG_OMAP_HSMMC
++# define CONFIG_CMD_MMC
++# define CONFIG_DOS_PARTITION
++# define CONFIG_CMD_FAT
++#endif
++
++/* Unsupported features */
++#undef CONFIG_USE_IRQ
++
++#endif /* ! __CONFIG_TI8148_EVM_H */
+diff --git a/include/configs/ti8168_evm.h b/include/configs/ti8168_evm.h
+new file mode 100644
+index 0000000..76e90dd
+--- /dev/null
++++ b/include/configs/ti8168_evm.h
+@@ -0,0 +1,332 @@
++/*
++ * Copyright (C) 2009, Texas Instruments, Incorporated
++ *
++ * 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 version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __CONFIG_TI816X_EVM_H
++#define __CONFIG_TI816X_EVM_H
++
++#define CONFIG_ARMV7
++
++#include <asm/arch/cpu.h> /* get chip and board defs */
++#include <asm/arch/hardware.h>
++
++/* U-Boot default commands */
++#include <config_cmd_default.h>
++
++/* Display CPU info */
++#define CONFIG_DISPLAY_CPUINFO 1
++
++//#define CONFIG_SETUP_1V
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_ENV_SIZE 0x2000
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (32 * 1024))
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for
++ initial data */
++
++/* Only one the following two options (DDR3/DDR2) should be enabled */
++#define CONFIG_TI816X_EVM_DDR3 /* Configure DDR3 in U-Boot */
++//#define CONFIG_TI816X_EVM_DDR2 /* Configure DDR2 in U-Boot */
++#define CONFIG_TI816X_TWO_EMIF 1
++#define CONFIG_MISC_INIT_R 1
++#define CONFIG_TI816X_ASCIIART 1 /* The eye */
++
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1 /* Required for ramdisk support */
++
++#define CONFIG_CMD_ASKENV
++#define CONFIG_VERSION_VARIABLE
++#define CONFIG_CMD_ECHO
++
++/* By default, any image built will have MMC, NAND, SPI and I2C support */
++#define CONFIG_MMC 1
++#define CONFIG_NAND 1
++#define CONFIG_SPI 1
++#define CONFIG_I2C 1
++
++/* Minimal image which runs out of internal memory */
++#ifdef CONFIG_MINIMAL
++# undef CONFIG_MMC
++# undef CONFIG_NAND
++# undef CONFIG_SPI
++# undef CONFIG_I2C
++# define CONFIG_NO_ETH
++#endif
++
++
++
++/* Due to size restrictions in RBL while in SD Boot mode, NAND/NOR support
++ * cannot co-exist in the same u-boot image that is loaded by the RBL from
++ * MMC/SD card.
++ */
++#ifdef CONFIG_SD_BOOT
++# undef CONFIG_TI816X_ASCIIART
++# undef CONFIG_DISPLAY_CPUINFO
++# undef CONFIG_NAND
++# undef CONFIG_SPI
++# undef CONFIG_I2C
++# undef CONFIG_SYS_HUSH_PARSER
++# define CONFIG_NO_ETH
++# define CONFIG_BOOTDELAY 0
++# define CONFIG_SYS_AUTOLOAD "yes"
++# define CONFIG_BOOTCOMMAND "mmc init;fatload mmc 1 0x80800000 u-boot.bin;go 0x80800000"
++# define CONFIG_ENV_IS_NOWHERE
++#else
++# define CONFIG_SYS_HUSH_PARSER /* Use HUSH parser to allow command parsing */
++# define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
++# define CONFIG_BOOTDELAY 3 /* set to negative value for no autoboot */
++# define CONFIG_SYS_AUTOLOAD "no"
++# define CONFIG_EXTRA_ENV_SETTINGS \
++ "verify=yes\0" \
++ "bootfile=uImage\0" \
++ "ramdisk_file=ramdisk.gz\0" \
++ "loadaddr=0x81000000\0" \
++ "script_addr=0x80900000\0" \
++ "loadbootscript=fatload mmc 1 ${script_addr} boot.scr\0" \
++ "bootscript= echo Running bootscript from MMC/SD to set the ENV...; " \
++ "source ${script_addr}\0" \
++
++#define CONFIG_BOOTCOMMAND \
++ "if mmc init; then " \
++ "if run loadbootscript; then " \
++ "run bootscript; " \
++ "else " \
++ "echo In case ENV on MMC/SD is required; "\
++ "echo Please put a valid script named boot.scr on the card; " \
++ "echo Refer to the User Guide on how to generate the image; " \
++ "fi; " \
++ "else " \
++ "echo Please set bootargs and bootcmd before booting the kernel; " \
++ "echo If that has already been done please ignore this message; "\
++ "fi"
++
++
++#endif
++
++/*
++ * Miscellaneous configurable options
++ */
++/* allow overwriting serial config and ethaddr */
++#define CONFIG_ENV_OVERWRITE
++/* Undef to save memory */
++#define CONFIG_SYS_LONGHELP
++/* Monitor Command Prompt */
++#define CONFIG_SYS_PROMPT "TI8168_EVM#"
++/* Console I/O Buffer Size */
++#define CONFIG_SYS_CBSIZE 512
++/* Print Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \
++ + sizeof(CONFIG_SYS_PROMPT) + 16)
++/* max number of command args */
++#define CONFIG_SYS_MAXARGS 32
++/* Boot Argument Buffer Size */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
++/* memtest works on 8 MB in DRAM after skipping 32MB from start addr of ram disk*/
++#define CONFIG_SYS_MEMTEST_START (PHYS_DRAM_1 + (64 *1024 *1024))
++#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START \
++ + (8 * 1024 * 1024))
++
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#define CONFIG_SYS_LOAD_ADDR 0x81000000 /* Default load address */
++
++/* Hardware related */
++
++/**
++ * Physical Memory Map
++ */
++#define CONFIG_NR_DRAM_BANKS 2 /* we have 2 banks of DRAM */
++#define PHYS_DRAM_1 0x80000000 /* DRAM Bank #1 */
++#define PHYS_DRAM_1_SIZE 0x40000000 /* 1 GB */
++#define PHYS_DRAM_2 0xC0000000 /* DRAM Bank #2 */
++#define PHYS_DRAM_2_SIZE 0x40000000 /* 1 GB */
++
++
++/**
++ * Clock related defines
++ */
++#define V_OSCK 27000000
++#define V_SCLK (V_OSCK >> 1)
++#define CONFIG_SYS_TIMERBASE 0x4802E000
++#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */
++#define CONFIG_SYS_HZ 1000 /* 1ms clock */
++
++/*
++ * NS16550 Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE (-4)
++#define CONFIG_SYS_NS16550_CLK (48000000)
++#define CONFIG_SYS_NS16550_COM1 0x48024000 /* Base EVM has UART2 */
++
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 110, 300, 600, 1200, 2400, \
++4800, 9600, 14400, 19200, 28800, 38400, 56000, 57600, 115200 }
++
++/*
++ * select serial console configuration
++ */
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 1
++#define CONFIG_SYS_CONSOLE_INFO_QUIET
++
++#if defined(CONFIG_NO_ETH)
++# undef CONFIG_CMD_NET
++#else
++# define CONFIG_CMD_DHCP
++# define CONFIG_CMD_PING
++#endif
++
++#if defined(CONFIG_CMD_NET)
++# 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_BOOTP_GATEWAY
++# define CONFIG_BOOTP_SUBNETMASK
++# define CONFIG_NET_RETRY_COUNT 10
++# define CONFIG_NET_MULTI
++#endif
++
++#if defined(CONFIG_SYS_NO_FLASH)
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++/* NAND support */
++#ifdef CONFIG_NAND
++#define CONFIG_CMD_NAND
++#define CONFIG_NAND_TI81XX
++#define GPMC_NAND_ECC_LP_x16_LAYOUT 1
++#define NAND_BASE (0x08000000) /* FIXME not sure */
++#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */
++ /* to access nand */
++#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */
++ /* to access nand at */
++ /* CS0 */
++#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */
++ /* devices */
++# define CONFIG_ENV_IS_IN_NAND
++#endif /* devices */
++
++/* ENV in NAND */
++#if defined(CONFIG_NAND_ENV)
++# undef CONFIG_ENV_IS_NOWHERE
++# define CONFIG_ENV_IS_IN_NAND
++# ifdef CONFIG_ENV_IS_IN_NAND
++# define CONFIG_SYS_MAX_FLASH_SECT 520 /* max number of sectors in a chip */
++# define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max number of flash banks */
++# define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */
++# define CONFIG_SYS_FLASH_BASE PISMO1_NAND_BASE
++/* Monitor at start of flash */
++# define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
++# define MNAND_ENV_OFFSET 0x260000 /* environment starts here */
++# define CONFIG_SYS_ENV_SECT_SIZE (128 << 10) /* 128 KiB */
++# define CONFIG_ENV_OFFSET MNAND_ENV_OFFSET
++# define CONFIG_ENV_ADDR MNAND_ENV_OFFSET
++# define CONFIG_NOFLASH
++# endif
++#endif /* NAND support */
++
++/* SPI support */
++#ifdef CONFIG_SPI
++#define CONFIG_OMAP3_SPI
++#define CONFIG_MTD_DEVICE
++#define CONFIG_SPI_FLASH
++#define CONFIG_SPI_FLASH_WINBOND
++#define CONFIG_CMD_SF
++#define CONFIG_SF_DEFAULT_SPEED (75000000)
++#endif
++
++/* ENV in SPI */
++#if defined(CONFIG_SPI_ENV)
++# undef CONFIG_ENV_IS_NOWHERE
++# define CONFIG_ENV_IS_IN_SPI_FLASH 1
++# ifdef CONFIG_ENV_IS_IN_SPI_FLASH
++# define CONFIG_SYS_FLASH_BASE (0)
++# define SPI_FLASH_ERASE_SIZE (4 * 1024) /* sector size of SPI flash */
++# define CONFIG_SYS_ENV_SECT_SIZE (2 * SPI_FLASH_ERASE_SIZE) /* env size */
++# define CONFIG_ENV_SECT_SIZE (CONFIG_SYS_ENV_SECT_SIZE)
++# define CONFIG_ENV_OFFSET (64 * SPI_FLASH_ERASE_SIZE)
++# define CONFIG_ENV_ADDR (CONFIG_ENV_OFFSET)
++# define CONFIG_SYS_MAX_FLASH_SECT (1024) /* no of sectors in SPI flash */
++# define CONFIG_SYS_MAX_FLASH_BANKS (1)
++# endif
++#endif /* SPI support */
++
++/* NOR support */
++#if defined(CONFIG_NOR)
++# undef CONFIG_CMD_NAND /* Remove NAND support */
++# undef CONFIG_NAND_TI81XX
++# ifdef CONFIG_SYS_MALLOC_LEN
++# undef CONFIG_SYS_MALLOC_LEN
++# endif
++# define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1
++# define CONFIG_SYS_MALLOC_LEN (0x100000)
++# define CONFIG_SYS_FLASH_CFI
++# define CONFIG_FLASH_CFI_DRIVER
++# define CONFIG_FLASH_CFI_MTD
++# define CONFIG_SYS_MAX_FLASH_SECT 512
++# define CONFIG_SYS_MAX_FLASH_BANKS 1
++# define CONFIG_SYS_FLASH_BASE (0x08000000)
++# define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
++# define CONFIG_ENV_IS_IN_FLASH 1
++# define NOR_SECT_SIZE (128 * 1024)
++# define CONFIG_SYS_ENV_SECT_SIZE (NOR_SECT_SIZE)
++# define CONFIG_ENV_SECT_SIZE (NOR_SECT_SIZE)
++# define CONFIG_ENV_OFFSET (2 * NOR_SECT_SIZE)
++# define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
++# define CONFIG_MTD_DEVICE
++#endif /* NOR support */
++
++/* I2C support */
++#ifdef CONFIG_I2C
++#define CONFIG_CMD_I2C
++#define CONFIG_HARD_I2C 1
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_SYS_I2C_BUS 0
++#define CONFIG_SYS_I2C_BUS_SELECT 1
++#define CONFIG_DRIVER_TI81XX_I2C 1
++
++/* EEPROM definitions */
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 3
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
++#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6
++#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 20
++#endif
++
++/* HSMMC Definitions */
++#ifdef CONFIG_MMC
++#define CONFIG_GENERIC_MMC
++#define CONFIG_OMAP_HSMMC
++#define CONFIG_CMD_MMC
++#define CONFIG_DOS_PARTITION
++#define CONFIG_CMD_FAT
++#endif
++
++/* Unsupported features */
++#undef CONFIG_USE_IRQ
++
++/* additions for new relocation code, must added to all boards */
++#undef CONFIG_SYS_ARM_WITHOUT_RELOC /* This board is tested with relocation support */
++#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
++#define CONFIG_SYS_INIT_SP_ADDR ((SRAM0_START + SRAM0_SIZE - SRAM_GPMC_STACK_SIZE) - CONFIG_SYS_GBL_DATA_SIZE)
++
++#endif /* ! __CONFIG_TI816X_EVM_H */
++
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index 987a2ec..a785d70 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -132,6 +132,8 @@ typedef enum {
+ NAND_ECC_HW,
+ NAND_ECC_HW_SYNDROME,
+ NAND_ECC_HW_OOB_FIRST,
++ NAND_ECC_4BIT_SOFT,
++ NAND_ECC_8BIT_SOFT
+ } nand_ecc_modes_t;
+
+ /*
+diff --git a/include/nand.h b/include/nand.h
+index 8d94b5c..b4140794 100644
+--- a/include/nand.h
++++ b/include/nand.h
+@@ -132,6 +132,12 @@ int nand_lock( nand_info_t *meminfo, int tight );
+ int nand_unlock( nand_info_t *meminfo, ulong start, ulong length );
+ int nand_get_lock_status(nand_info_t *meminfo, loff_t offset);
+
++int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst);
++void nand_deselect(void);
++
++void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
++void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
++
+ #ifdef CONFIG_SYS_NAND_SELECT_DEVICE
+ void board_nand_select_device(struct nand_chip *nand, int chip);
+ #endif
+diff --git a/include/netdev.h b/include/netdev.h
+index 96c7b9b..c7fe482 100644
+--- a/include/netdev.h
++++ b/include/netdev.h
+@@ -185,4 +185,40 @@ struct mv88e61xx_config {
+ int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig);
+ #endif /* CONFIG_MV88E61XX_SWITCH */
+
++#ifdef CONFIG_DRIVER_TI_CPSW
++
++enum {
++ CPSW_CTRL_VERSION_1 = 0, /* version1 devices */
++ CPSW_CTRL_VERSION_2 /* version2 devices */
++};
++
++struct cpsw_slave_data {
++ u32 slave_reg_ofs;
++ u32 sliver_reg_ofs;
++ int phy_id;
++};
++
++struct cpsw_platform_data {
++ u32 mdio_base;
++ u32 cpsw_base;
++ int mdio_div;
++ int channels; /* number of cpdma channels (symmetric) */
++ u32 cpdma_reg_ofs; /* cpdma register offset */
++ int slaves; /* number of slave cpgmac ports */
++ u32 ale_reg_ofs; /* address lookup engine reg offset */
++ int ale_entries; /* ale table size */
++ u32 host_port_reg_ofs; /* cpdma host port registers */
++ u32 hw_stats_reg_ofs; /* cpsw hw stats counters */
++ u32 mac_control;
++ struct cpsw_slave_data *slave_data;
++ void (*control)(int enabled);
++ void (*phy_init)(char *name, int addr);
++ u32 host_port_num;
++ u8 version;
++};
++
++int cpsw_register(struct cpsw_platform_data *data);
++
++#endif /* CONFIG_DRIVER_TI_CPSW */
++
+ #endif /* _NETDEV_H_ */
+diff --git a/include/serial.h b/include/serial.h
+index ff1ce99..df833b2 100644
+--- a/include/serial.h
++++ b/include/serial.h
+@@ -31,7 +31,7 @@ extern struct serial_device * default_serial_console (void);
+ defined(CONFIG_MB86R0x) || defined(CONFIG_MPC5xxx) || \
+ defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) || \
+ defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) || \
+- defined(CONFIG_TEGRA2)
++ defined(CONFIG_TEGRA2) || defined(CONFIG_AM335X)
+ extern struct serial_device serial0_device;
+ extern struct serial_device serial1_device;
+ #if defined(CONFIG_SYS_NS16550_SERIAL)
+diff --git a/include/twl4030.h b/include/twl4030.h
+index 930c285..64250a6 100644
+--- a/include/twl4030.h
++++ b/include/twl4030.h
+@@ -518,6 +518,9 @@ void twl4030_pmrecv_vsel_cfg(u8 vsel_reg, u8 vsel_val,
+ void twl4030_power_init(void);
+ /* For initializing mmc power */
+ void twl4030_power_mmc_init(void);
++/* Generic function to select Device Group and Voltage */
++void twl4030_pmrecv_vsel_cfg(u8 vsel_reg, u8 vsel_val,
++ u8 dev_grp, u8 dev_grp_sel);
+
+ /*
+ * LED
+diff --git a/lib/Makefile b/lib/Makefile
+index 884f64c..1173792 100644
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -51,6 +51,9 @@ COBJS-y += strmhz.o
+ COBJS-$(CONFIG_RBTREE) += rbtree.o
+ endif
+
++ifdef CONFIG_SPL_BUILD
++COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
++endif
+ COBJS-y += ctype.o
+ COBJS-y += div64.o
+ COBJS-y += string.o
+diff --git a/spl/Makefile b/spl/Makefile
+index 95ecce1..022d43f 100644
+--- a/spl/Makefile
++++ b/spl/Makefile
+@@ -46,7 +46,12 @@ LIBS-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += drivers/mtd/spi/libspi_flash.o
+ LIBS-$(CONFIG_SPL_SPI_SUPPORT) += drivers/spi/libspi.o
+ LIBS-$(CONFIG_SPL_FAT_SUPPORT) += fs/fat/libfat.o
+ LIBS-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/libgeneric.o
++LIBS-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/libpower.o
++LIBS-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/libnand.o
+
++ifeq ($(SOC),ti81xx)
++LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
++endif
+ ifeq ($(SOC),omap3)
+ LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
+ endif
+@@ -90,6 +95,11 @@ $(OBJTREE)/MLO: $(obj)u-boot-spl.bin
+ $(OBJTREE)/tools/mkimage -T omapimage \
+ -a $(CONFIG_SPL_TEXT_BASE) -d $< $@
+ endif
++ifdef CONFIG_TI81XX
++$(OBJTREE)/MLO: $(obj)u-boot-spl.bin
++ $(OBJTREE)/tools/mkimage -T omapimage \
++ -a $(CONFIG_SPL_TEXT_BASE) -d $< $@
++endif
+
+ ALL-y += $(obj)u-boot-spl.bin
+
+diff --git a/tools/gdb/Makefile b/tools/gdb/Makefile
+index 90037c7..134819c 100644
+--- a/tools/gdb/Makefile
++++ b/tools/gdb/Makefile
+@@ -48,6 +48,9 @@ $(obj).depend:
+
+ else # ! CYGWIN
+
++COBJS-$(CONFIG_EMIF4) += emif4.o
++COBJS-$(CONFIG_SDRC) += sdrc.o
++
+ all: $(obj).depend $(BINS)
+
+ $(obj)gdbsend: $(obj)gdbsend.o $(obj)error.o $(obj)remote.o $(obj)serial.o