diff options
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.patch | 16912 |
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, ®)) ++ 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 |