From 55acada06b6e0a678e8d45334a395ba28ce506a6 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 13 Jun 2008 15:04:03 +0000 Subject: u-boot: add TI 1.1.4 for beagleboard and Steve's 1.3.x git version --- packages/u-boot/u-boot-git/.mtn2git_empty | 0 .../u-boot/u-boot-git/beagleboard/.mtn2git_empty | 0 .../u-boot/u-boot-git/beagleboard/armv7-a.patch | 11 + packages/u-boot/u-boot-git/beagleboard/base.patch | 7030 ++++++++++++++++++++ packages/u-boot/u-boot-git/beagleboard/name.patch | 14 + .../u-boot-omap3beagleboard-1.1.4/.mtn2git_empty | 0 .../500mhz-l2enable.patch | 42 + .../u-boot-omap3beagleboard-1.1.4/armv7-a.patch | 11 + .../disable-tone-logo.patch | 46 + .../u-boot/u-boot-omap3beagleboard-1.1.4/env.patch | 13 + .../u-boot-omap3beagleboard-1.1.4/name.patch | 13 + packages/u-boot/u-boot-omap3beagleboard_1.1.4.bb | 16 + packages/u-boot/u-boot_git.bb | 9 +- 13 files changed, 7203 insertions(+), 2 deletions(-) create mode 100644 packages/u-boot/u-boot-git/.mtn2git_empty create mode 100644 packages/u-boot/u-boot-git/beagleboard/.mtn2git_empty create mode 100644 packages/u-boot/u-boot-git/beagleboard/armv7-a.patch create mode 100644 packages/u-boot/u-boot-git/beagleboard/base.patch create mode 100644 packages/u-boot/u-boot-git/beagleboard/name.patch create mode 100644 packages/u-boot/u-boot-omap3beagleboard-1.1.4/.mtn2git_empty create mode 100644 packages/u-boot/u-boot-omap3beagleboard-1.1.4/500mhz-l2enable.patch create mode 100644 packages/u-boot/u-boot-omap3beagleboard-1.1.4/armv7-a.patch create mode 100644 packages/u-boot/u-boot-omap3beagleboard-1.1.4/disable-tone-logo.patch create mode 100644 packages/u-boot/u-boot-omap3beagleboard-1.1.4/env.patch create mode 100644 packages/u-boot/u-boot-omap3beagleboard-1.1.4/name.patch create mode 100644 packages/u-boot/u-boot-omap3beagleboard_1.1.4.bb diff --git a/packages/u-boot/u-boot-git/.mtn2git_empty b/packages/u-boot/u-boot-git/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/u-boot/u-boot-git/beagleboard/.mtn2git_empty b/packages/u-boot/u-boot-git/beagleboard/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/u-boot/u-boot-git/beagleboard/armv7-a.patch b/packages/u-boot/u-boot-git/beagleboard/armv7-a.patch new file mode 100644 index 0000000000..49f8de0879 --- /dev/null +++ b/packages/u-boot/u-boot-git/beagleboard/armv7-a.patch @@ -0,0 +1,11 @@ +--- u-boot/cpu/omap3/config.mk-orig 2008-05-27 16:46:45.000000000 -0700 ++++ u-boot/cpu/omap3/config.mk 2008-05-29 12:50:49.000000000 -0700 +@@ -23,7 +23,7 @@ + PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ + -msoft-float + +-PLATFORM_CPPFLAGS += -march=armv7a ++PLATFORM_CPPFLAGS += -march=armv7-a + # ========================================================================= + # + # Supply options according to compiler version diff --git a/packages/u-boot/u-boot-git/beagleboard/base.patch b/packages/u-boot/u-boot-git/beagleboard/base.patch new file mode 100644 index 0000000000..a5f118275b --- /dev/null +++ b/packages/u-boot/u-boot-git/beagleboard/base.patch @@ -0,0 +1,7030 @@ +diff --git a/Makefile b/Makefile +index cc988e1..16701c5 100644 +--- a/Makefile ++++ b/Makefile +@@ -141,7 +141,7 @@ ifeq ($(ARCH),ppc) + CROSS_COMPILE = ppc_8xx- + endif + ifeq ($(ARCH),arm) +-CROSS_COMPILE = arm-linux- ++CROSS_COMPILE = arm-none-linux-gnueabi- + endif + ifeq ($(ARCH),i386) + CROSS_COMPILE = i386-linux- +@@ -252,7 +252,7 @@ LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a + LIBBOARD := $(addprefix $(obj),$(LIBBOARD)) + + # Add GCC lib +-PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc ++PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc -lgcc_eh + + # The "tools" are needed early, so put this first + # Don't include stuff already done in $(LIBS) +@@ -2562,6 +2562,12 @@ SMN42_config : unconfig + @$(MKCONFIG) $(@:_config=) arm arm720t SMN42 siemens lpc2292 + + ######################################################################### ++## ARM CORTEX Systems ++######################################################################### ++omap3530beagle_config : unconfig ++ @./mkconfig $(@:_config=) arm omap3 omap3530beagle ++ ++######################################################################### + ## XScale Systems + ######################################################################### + +diff --git a/board/omap3530beagle/Makefile b/board/omap3530beagle/Makefile +new file mode 100644 +index 0000000..7065345 +--- /dev/null ++++ b/board/omap3530beagle/Makefile +@@ -0,0 +1,47 @@ ++# ++# (C) Copyright 2000, 2001, 2002 ++# Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++# ++# See file CREDITS for list of people who contributed to this ++# project. ++# ++# This program is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License as ++# published by the Free Software Foundation; either version 2 of ++# the License, or (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++# MA 02111-1307 USA ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = lib$(BOARD).a ++ ++OBJS := omap3530beagle.o mem.o clock.o syslib.o sys_info.o nand.o ++SOBJS := lowlevel_init.o ++ ++$(LIB): $(OBJS) $(SOBJS) ++ $(AR) crv $@ $^ ++ ++clean: ++ rm -f $(SOBJS) $(OBJS) ++ ++distclean: clean ++ rm -f $(LIB) core *.bak .depend ++ ++######################################################################### ++ ++.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) ++ $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ ++ ++-include .depend ++ ++######################################################################### +diff --git a/board/omap3530beagle/clock.c b/board/omap3530beagle/clock.c +new file mode 100644 +index 0000000..964525b +--- /dev/null ++++ b/board/omap3530beagle/clock.c +@@ -0,0 +1,316 @@ ++/* ++ * (C) Copyright 2008 ++ * Texas Instruments, ++ * ++ * Author : ++ * Sunil Kumar ++ * Shashi Ranjan ++ * ++ * Derived from Beagle Board and OMAP3 SDP code by ++ * Richard Woodruff ++ * Syed Mohammed Khasim ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/****************************************************************************** ++ * get_sys_clk_speed() - determine reference oscillator speed ++ * based on known 32kHz clock and gptimer. ++ *****************************************************************************/ ++u32 get_osc_clk_speed(void) ++{ ++ u32 start, cstart, cend, cdiff, val; ++ ++ val = __raw_readl(PRM_CLKSRC_CTRL); ++ ++ /* If SYS_CLK is being divided by 2, remove for now */ ++ val = (val & (~BIT7)) | BIT6; ++ __raw_writel(val, PRM_CLKSRC_CTRL); ++ ++ /* enable timer2 */ ++ val = __raw_readl(CM_CLKSEL_WKUP) | BIT0; ++ __raw_writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */ ++ ++ /* Enable I and F Clocks for GPT1 */ ++ val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2; ++ __raw_writel(val, CM_ICLKEN_WKUP); ++ val = __raw_readl(CM_FCLKEN_WKUP) | BIT0; ++ __raw_writel(val, CM_FCLKEN_WKUP); ++ ++ __raw_writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */ ++ __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */ ++ ++ /* enable 32kHz source, determine sys_clk via gauging */ ++ start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles */ ++ while (__raw_readl(S32K_CR) < start) ; /* dead loop till start time */ ++ /* get start sys_clk count */ ++ cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); ++ /* wait for 40 cycles */ ++ while (__raw_readl(S32K_CR) < (start + 20)) ; ++ cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ ++ cdiff = cend - cstart; /* get elapsed ticks */ ++ ++ /* based on number of ticks assign speed */ ++ if (cdiff > 19000) ++ return (S38_4M); ++ else if (cdiff > 15200) ++ return (S26M); ++ else if (cdiff > 13000) ++ return (S24M); ++ else if (cdiff > 9000) ++ return (S19_2M); ++ else if (cdiff > 7600) ++ return (S13M); ++ else ++ return (S12M); ++} ++ ++/****************************************************************************** ++ * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on ++ * input oscillator clock frequency. ++ *****************************************************************************/ ++void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel) ++{ ++ if (osc_clk == S38_4M) ++ *sys_clkin_sel = 4; ++ else if (osc_clk == S26M) ++ *sys_clkin_sel = 3; ++ else if (osc_clk == S19_2M) ++ *sys_clkin_sel = 2; ++ else if (osc_clk == S13M) ++ *sys_clkin_sel = 1; ++ else if (osc_clk == S12M) ++ *sys_clkin_sel = 0; ++} ++ ++/****************************************************************************** ++ * prcm_init() - inits clocks for PRCM as defined in clocks.h ++ * called from SRAM, or Flash (using temp SRAM stack). ++ *****************************************************************************/ ++void prcm_init(void) ++{ ++ void (*f_lock_pll) (u32, u32, u32, u32); ++ int xip_safe, p0, p1, p2, p3; ++ u32 osc_clk = 0, sys_clkin_sel; ++ u32 clk_index, sil_index; ++ dpll_param *dpll_param_p; ++ ++ f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start + ++ SRAM_VECT_CODE); ++ ++ xip_safe = running_in_sram(); ++ ++ /* Gauge the input clock speed and find out the sys_clkin_sel ++ * value corresponding to the input clock. ++ */ ++ osc_clk = get_osc_clk_speed(); ++ get_sys_clkin_sel(osc_clk, &sys_clkin_sel); ++ ++ sr32(PRM_CLKSEL, 0, 3, sys_clkin_sel); /* set input crystal speed */ ++ ++ /* If the input clock is greater than 19.2M always divide/2 */ ++ if (sys_clkin_sel > 2) { ++ sr32(PRM_CLKSRC_CTRL, 6, 2, 2); /* input clock divider */ ++ clk_index = sys_clkin_sel / 2; ++ } else { ++ sr32(PRM_CLKSRC_CTRL, 6, 2, 1); /* input clock divider */ ++ clk_index = sys_clkin_sel; ++ } ++ ++ /* The DPLL tables are defined according to sysclk value and ++ * silicon revision. The clk_index value will be used to get ++ * the values for that input sysclk from the DPLL param table ++ * and sil_index will get the values for that SysClk for the ++ * appropriate silicon rev. ++ */ ++ sil_index = get_cpu_rev() - 1; ++ /* Unlock MPU DPLL (slows things down, and needed later) */ ++ sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); ++ wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); ++ ++ /* Getting the base address of Core DPLL param table */ ++ dpll_param_p = (dpll_param *) get_core_dpll_param(); ++ /* Moving it to the right sysclk and ES rev base */ ++ dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; ++ if (xip_safe) { ++ /* CORE DPLL */ ++ /* sr32(CM_CLKSEL2_EMU) set override to work when asleep */ ++ sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); ++ wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); ++ /* For OMAP3 ES1.0 Errata 1.50, default value directly doesnt ++ work. write another value and then default value. */ ++ sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2 + 1); /* m3x2 */ ++ sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); /* m3x2 */ ++ sr32(CM_CLKSEL1_PLL, 27, 2, dpll_param_p->m2); /* Set M2 */ ++ sr32(CM_CLKSEL1_PLL, 16, 11, dpll_param_p->m); /* Set M */ ++ sr32(CM_CLKSEL1_PLL, 8, 7, dpll_param_p->n); /* Set N */ ++ sr32(CM_CLKSEL1_PLL, 6, 1, 0); /* 96M Src */ ++ sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ ++ sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ ++ sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ ++ sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ ++ sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV); /* gfx */ ++ sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ ++ sr32(CM_CLKEN_PLL, 4, 4, dpll_param_p->fsel); /* FREQSEL */ ++ sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ ++ wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); ++ } else if (running_in_flash()) { ++ /* if running from flash, jump to small relocated code ++ area in SRAM. */ ++ p0 = __raw_readl(CM_CLKEN_PLL); ++ sr32((u32) &p0, 0, 3, PLL_FAST_RELOCK_BYPASS); ++ sr32((u32) &p0, 4, 4, dpll_param_p->fsel); /* FREQSEL */ ++ ++ p1 = __raw_readl(CM_CLKSEL1_PLL); ++ sr32((u32) &p1, 27, 2, dpll_param_p->m2); /* Set M2 */ ++ sr32((u32) &p1, 16, 11, dpll_param_p->m); /* Set M */ ++ sr32((u32) &p1, 8, 7, dpll_param_p->n); /* Set N */ ++ sr32((u32) &p1, 6, 1, 0); /* set source for 96M */ ++ p2 = __raw_readl(CM_CLKSEL_CORE); ++ sr32((u32) &p2, 8, 4, CORE_SSI_DIV); /* ssi */ ++ sr32((u32) &p2, 4, 2, CORE_FUSB_DIV); /* fsusb */ ++ sr32((u32) &p2, 2, 2, CORE_L4_DIV); /* l4 */ ++ sr32((u32) &p2, 0, 2, CORE_L3_DIV); /* l3 */ ++ ++ p3 = CM_IDLEST_CKGEN; ++ ++ (*f_lock_pll) (p0, p1, p2, p3); ++ } ++ ++ /* PER DPLL */ ++ sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); ++ wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); ++ ++ /* Getting the base address to PER DPLL param table */ ++ /* Set N */ ++ dpll_param_p = (dpll_param *) get_per_dpll_param(); ++ /* Moving it to the right sysclk base */ ++ dpll_param_p = dpll_param_p + clk_index; ++ /* Errata 1.50 Workaround for OMAP3 ES1.0 only */ ++ /* If using default divisors, write default divisor + 1 ++ and then the actual divisor value */ ++ /* Need to change it to silicon and revision check */ ++ if (1) { ++ sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2 + 1); /* set M6 */ ++ sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ ++ sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2 + 1); /* set M5 */ ++ sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ ++ sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2 + 1); /* set M4 */ ++ sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ ++ sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2 + 1); /* set M3 */ ++ sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ ++ sr32(CM_CLKSEL3_PLL, 0, 5, dpll_param_p->m2 + 1); /* set M2 */ ++ sr32(CM_CLKSEL3_PLL, 0, 5, dpll_param_p->m2); /* set M2 */ ++ } else { ++ sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ ++ sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ ++ sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ ++ sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ ++ sr32(CM_CLKSEL3_PLL, 0, 5, dpll_param_p->m2); /* set M2 */ ++ } ++ sr32(CM_CLKSEL2_PLL, 8, 11, dpll_param_p->m); /* set m */ ++ sr32(CM_CLKSEL2_PLL, 0, 7, dpll_param_p->n); /* set n */ ++ sr32(CM_CLKEN_PLL, 20, 4, dpll_param_p->fsel); /* FREQSEL */ ++ sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); /* lock mode */ ++ wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); ++ ++ /* Getting the base address to MPU DPLL param table */ ++ dpll_param_p = (dpll_param *) get_mpu_dpll_param(); ++ /* Moving it to the right sysclk and ES rev base */ ++ dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; ++ /* MPU DPLL (unlocked already) */ ++ sr32(CM_CLKSEL2_PLL_MPU, 0, 5, dpll_param_p->m2); /* Set M2 */ ++ sr32(CM_CLKSEL1_PLL_MPU, 8, 11, dpll_param_p->m); /* Set M */ ++ sr32(CM_CLKSEL1_PLL_MPU, 0, 7, dpll_param_p->n); /* Set N */ ++ sr32(CM_CLKEN_PLL_MPU, 4, 4, dpll_param_p->fsel); /* FREQSEL */ ++ sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); /* lock mode */ ++ wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); ++ ++ /* Getting the base address to IVA DPLL param table */ ++ dpll_param_p = (dpll_param *) get_iva_dpll_param(); ++ /* Moving it to the right sysclk and ES rev base */ ++ dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; ++ /* IVA DPLL (set to 12*20=240MHz) */ ++ sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); ++ wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); ++ sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, dpll_param_p->m2); /* set M2 */ ++ sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, dpll_param_p->m); /* set M */ ++ sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, dpll_param_p->n); /* set N */ ++ sr32(CM_CLKEN_PLL_IVA2, 4, 4, dpll_param_p->fsel); /* FREQSEL */ ++ sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); /* lock mode */ ++ wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); ++ ++ /* Set up GPTimers to sys_clk source only */ ++ sr32(CM_CLKSEL_PER, 0, 8, 0xff); ++ sr32(CM_CLKSEL_WKUP, 0, 1, 1); ++ ++ sdelay(5000); ++} ++ ++/****************************************************************************** ++ * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...) ++ *****************************************************************************/ ++void per_clocks_enable(void) ++{ ++ /* Enable GP2 timer. */ ++ sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */ ++ sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */ ++ sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */ ++ ++#ifdef CFG_NS16550 ++ /* Enable UART1 clocks */ ++ sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); ++ sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); ++ ++ /* UART 3 Clocks */ ++ sr32(CM_FCLKEN_PER, 11, 1, 0x1); ++ sr32(CM_ICLKEN_PER, 11, 1, 0x1); ++#endif ++#ifdef CONFIG_DRIVER_OMAP34XX_I2C ++ /* Turn on all 3 I2C clocks */ ++ sr32(CM_FCLKEN1_CORE, 15, 3, 0x7); ++ sr32(CM_ICLKEN1_CORE, 15, 3, 0x7); /* I2C1,2,3 = on */ ++#endif ++ /* Enable the ICLK for 32K Sync Timer as its used in udelay */ ++ sr32(CM_ICLKEN_WKUP, 2, 1, 0x1); ++ ++ sr32(CM_FCLKEN_IVA2, 0, 32, FCK_IVA2_ON); ++ sr32(CM_FCLKEN1_CORE, 0, 32, FCK_CORE1_ON); ++ sr32(CM_ICLKEN1_CORE, 0, 32, ICK_CORE1_ON); ++ sr32(CM_ICLKEN2_CORE, 0, 32, ICK_CORE2_ON); ++ sr32(CM_FCLKEN_WKUP, 0, 32, FCK_WKUP_ON); ++ sr32(CM_ICLKEN_WKUP, 0, 32, ICK_WKUP_ON); ++ sr32(CM_FCLKEN_DSS, 0, 32, FCK_DSS_ON); ++ sr32(CM_ICLKEN_DSS, 0, 32, ICK_DSS_ON); ++ sr32(CM_FCLKEN_CAM, 0, 32, FCK_CAM_ON); ++ sr32(CM_ICLKEN_CAM, 0, 32, ICK_CAM_ON); ++ sr32(CM_FCLKEN_PER, 0, 32, FCK_PER_ON); ++ sr32(CM_ICLKEN_PER, 0, 32, ICK_PER_ON); ++ ++ sdelay(1000); ++} +diff --git a/board/omap3530beagle/config.mk b/board/omap3530beagle/config.mk +new file mode 100644 +index 0000000..9639c43 +--- /dev/null ++++ b/board/omap3530beagle/config.mk +@@ -0,0 +1,17 @@ ++# ++# (C) Copyright 2006 ++# Texas Instruments, ++# ++# Begale Board uses OMAP3 (ARM-CortexA8) cpu ++# see http://www.ti.com/ for more information on Texas Instruments ++# ++# Physical Address: ++# 8000'0000 (bank0) ++# A000/0000 (bank1) ++# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 ++# (mem base + reserved) ++ ++# For use with external or internal boots. ++TEXT_BASE = 0x80e80000 ++ ++ +diff --git a/board/omap3530beagle/lowlevel_init.S b/board/omap3530beagle/lowlevel_init.S +new file mode 100644 +index 0000000..7ec4d05 +--- /dev/null ++++ b/board/omap3530beagle/lowlevel_init.S +@@ -0,0 +1,361 @@ ++/* ++ * Board specific setup info ++ * ++ * (C) Copyright 2008 ++ * Texas Instruments, ++ * ++ * Initial Code by: ++ * Richard Woodruff ++ * Syed Mohammed Khasim ++ * ++ * 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 ++#include ++#include ++#include ++#include ++ ++_TEXT_BASE: ++ .word TEXT_BASE /* sdram load addr from config.mk */ ++ ++#if !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) ++/************************************************************************** ++ * cpy_clk_code: relocates clock code into SRAM where its safer to execute ++ * R1 = SRAM destination address. ++ *************************************************************************/ ++.global cpy_clk_code ++ cpy_clk_code: ++ /* Copy DPLL code into SRAM */ ++ adr r0, go_to_speed /* get addr of clock setting code */ ++ mov r2, #384 /* r2 size to copy (div by 32 bytes) */ ++ mov r1, r1 /* 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 ++ mov pc, lr /* back to caller */ ++ ++/* *************************************************************************** ++ * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed ++ * -executed from SRAM. ++ * R0 = CM_CLKEN_PLL-bypass value ++ * R1 = CM_CLKSEL1_PLL-m, n, and divider values ++ * R2 = CM_CLKSEL_CORE-divider values ++ * R3 = CM_IDLEST_CKGEN - addr dpll lock wait ++ * ++ * Note: If core unlocks/relocks and SDRAM is running fast already it gets ++ * confused. A reset of the controller gets it back. Taking away its ++ * L3 when its not in self refresh seems bad for it. Normally, this ++ * code runs from flash before SDR is init so that should be ok. ++ ****************************************************************************/ ++.global go_to_speed ++ go_to_speed: ++ stmfd sp!, {r4-r6} ++ ++ /* move into fast relock bypass */ ++ ldr r4, pll_ctl_add ++ str r0, [r4] ++wait1: ++ ldr r5, [r3] /* get status */ ++ and r5, r5, #0x1 /* isolate core status */ ++ cmp r5, #0x1 /* still locked? */ ++ beq wait1 /* if lock, loop */ ++ ++ /* set new dpll dividers _after_ in bypass */ ++ ldr r5, pll_div_add1 ++ str r1, [r5] /* set m, n, m2 */ ++ ldr r5, pll_div_add2 ++ str r2, [r5] /* set l3/l4/.. dividers*/ ++ ldr r5, pll_div_add3 /* wkup */ ++ ldr r2, pll_div_val3 /* rsm val */ ++ str r2, [r5] ++ ldr r5, pll_div_add4 /* gfx */ ++ ldr r2, pll_div_val4 ++ str r2, [r5] ++ ldr r5, pll_div_add5 /* emu */ ++ ldr r2, pll_div_val5 ++ str r2, [r5] ++ ++ /* now prepare GPMC (flash) for new dpll speed */ ++ /* flash needs to be stable when we jump back to it */ ++ ldr r5, flash_cfg3_addr ++ ldr r2, flash_cfg3_val ++ str r2, [r5] ++ ldr r5, flash_cfg4_addr ++ ldr r2, flash_cfg4_val ++ str r2, [r5] ++ ldr r5, flash_cfg5_addr ++ ldr r2, flash_cfg5_val ++ str r2, [r5] ++ ldr r5, flash_cfg1_addr ++ ldr r2, [r5] ++ orr r2, r2, #0x3 /* up gpmc divider */ ++ str r2, [r5] ++ ++ /* lock DPLL3 and wait a bit */ ++ orr r0, r0, #0x7 /* set up for lock mode */ ++ str r0, [r4] /* lock */ ++ nop /* ARM slow at this point working at sys_clk */ ++ nop ++ nop ++ nop ++wait2: ++ ldr r5, [r3] /* get status */ ++ and r5, r5, #0x1 /* isolate core status */ ++ cmp r5, #0x1 /* still locked? */ ++ bne wait2 /* if lock, loop */ ++ nop ++ nop ++ nop ++ nop ++ ldmfd sp!, {r4-r6} ++ mov pc, lr /* back to caller, locked */ ++ ++_go_to_speed: .word go_to_speed ++ ++/* these constants need to be close for PIC code */ ++/* The Nor has to be in the Flash Base CS0 for this condition to happen */ ++flash_cfg1_addr: ++ .word (GPMC_CONFIG_CS0 + GPMC_CONFIG1) ++flash_cfg3_addr: ++ .word (GPMC_CONFIG_CS0 + GPMC_CONFIG3) ++flash_cfg3_val: ++ .word STNOR_GPMC_CONFIG3 ++flash_cfg4_addr: ++ .word (GPMC_CONFIG_CS0 + GPMC_CONFIG4) ++flash_cfg4_val: ++ .word STNOR_GPMC_CONFIG4 ++flash_cfg5_val: ++ .word STNOR_GPMC_CONFIG5 ++flash_cfg5_addr: ++ .word (GPMC_CONFIG_CS0 + GPMC_CONFIG5) ++pll_ctl_add: ++ .word CM_CLKEN_PLL ++pll_div_add1: ++ .word CM_CLKSEL1_PLL ++pll_div_add2: ++ .word CM_CLKSEL_CORE ++pll_div_add3: ++ .word CM_CLKSEL_WKUP ++pll_div_val3: ++ .word (WKUP_RSM << 1) ++pll_div_add4: ++ .word CM_CLKSEL_GFX ++pll_div_val4: ++ .word (GFX_DIV << 0) ++pll_div_add5: ++ .word CM_CLKSEL1_EMU ++pll_div_val5: ++ .word CLSEL1_EMU_VAL ++ ++#endif ++ ++.globl lowlevel_init ++lowlevel_init: ++ ldr sp, SRAM_STACK ++ str ip, [sp] /* stash old link register */ ++ mov ip, lr /* save link reg across call */ ++ bl s_init /* go setup pll,mux,memory */ ++ ldr ip, [sp] /* restore save ip */ ++ mov lr, ip /* restore link reg */ ++ ++ /* back to arch calling code */ ++ mov pc, lr ++ ++ /* the literal pools origin */ ++ .ltorg ++ ++REG_CONTROL_STATUS: ++ .word CONTROL_STATUS ++SRAM_STACK: ++ .word LOW_LEVEL_SRAM_STACK ++ ++/* DPLL(1-4) PARAM TABLES */ ++/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal ++ * OPP (1.2V). The fields are defined according to dpll_param struct(clock.c). ++ * The values are defined for all possible sysclk and for ES1 and ES2. ++ */ ++ ++mpu_dpll_param: ++/* 12MHz */ ++/* ES1 */ ++.word 0x0FE,0x07,0x05,0x01 ++/* ES2 */ ++.word 0x0FA,0x05,0x07,0x01 ++/* 3410 */ ++.word 0x085,0x05,0x07,0x01 ++ ++/* 13MHz */ ++/* ES1 */ ++.word 0x17D,0x0C,0x03,0x01 ++/* ES2 */ ++.word 0x1F4,0x0C,0x03,0x01 ++/* 3410 */ ++.word 0x10A,0x0C,0x03,0x01 ++ ++/* 19.2MHz */ ++/* ES1 */ ++.word 0x179,0x12,0x04,0x01 ++/* ES2 */ ++.word 0x271,0x17,0x03,0x01 ++/* 3410 */ ++.word 0x14C,0x17,0x03,0x01 ++ ++/* 26MHz */ ++/* ES1 */ ++.word 0x17D,0x19,0x03,0x01 ++/* ES2 */ ++.word 0x0FA,0x0C,0x07,0x01 ++/* 3410 */ ++.word 0x085,0x0C,0x07,0x01 ++ ++/* 38.4MHz */ ++/* ES1 */ ++.word 0x1FA,0x32,0x03,0x01 ++/* ES2 */ ++.word 0x271,0x2F,0x03,0x01 ++/* 3410 */ ++.word 0x14C,0x2F,0x03,0x01 ++ ++ ++.globl get_mpu_dpll_param ++get_mpu_dpll_param: ++ adr r0, mpu_dpll_param ++ mov pc, lr ++ ++iva_dpll_param: ++/* 12MHz */ ++/* ES1 */ ++.word 0x07D,0x05,0x07,0x01 ++/* ES2 */ ++.word 0x0B4,0x05,0x07,0x01 ++/* 3410 */ ++.word 0x085,0x05,0x07,0x01 ++ ++/* 13MHz */ ++/* ES1 */ ++.word 0x0FA,0x0C,0x03,0x01 ++/* ES2 */ ++.word 0x168,0x0C,0x03,0x01 ++/* 3410 */ ++.word 0x10A,0x0C,0x03,0x01 ++ ++/* 19.2MHz */ ++/* ES1 */ ++.word 0x082,0x09,0x07,0x01 ++/* ES2 */ ++.word 0x0E1,0x0B,0x06,0x01 ++/* 3410 */ ++.word 0x14C,0x17,0x03,0x01 ++ ++/* 26MHz */ ++/* ES1 */ ++.word 0x07D,0x0C,0x07,0x01 ++/* ES2 */ ++.word 0x0B4,0x0C,0x07,0x01 ++/* 3410 */ ++.word 0x085,0x0C,0x07,0x01 ++ ++/* 38.4MHz */ ++/* ES1 */ ++.word 0x13F,0x30,0x03,0x01 ++/* ES2 */ ++.word 0x0E1,0x17,0x06,0x01 ++/* 3410 */ ++.word 0x14C,0x2F,0x03,0x01 ++ ++ ++.globl get_iva_dpll_param ++get_iva_dpll_param: ++ adr r0, iva_dpll_param ++ mov pc, lr ++ ++/* Core DPLL targets for L3 at 166 & L133 */ ++core_dpll_param: ++/* 12MHz */ ++/* ES1 */ ++.word M_12_ES1,M_12_ES1,FSL_12_ES1,M2_12_ES1 ++/* ES2 */ ++.word M_12,N_12,FSEL_12,M2_12 ++/* 3410 */ ++.word M_12,N_12,FSEL_12,M2_12 ++ ++/* 13MHz */ ++/* ES1 */ ++.word M_13_ES1,N_13_ES1,FSL_13_ES1,M2_13_ES1 ++/* ES2 */ ++.word M_13,N_13,FSEL_13,M2_13 ++/* 3410 */ ++.word M_13,N_13,FSEL_13,M2_13 ++ ++/* 19.2MHz */ ++/* ES1 */ ++.word M_19p2_ES1,N_19p2_ES1,FSL_19p2_ES1,M2_19p2_ES1 ++/* ES2 */ ++.word M_19p2,N_19p2,FSEL_19p2,M2_19p2 ++/* 3410 */ ++.word M_19p2,N_19p2,FSEL_19p2,M2_19p2 ++ ++/* 26MHz */ ++/* ES1 */ ++.word M_26_ES1,N_26_ES1,FSL_26_ES1,M2_26_ES1 ++/* ES2 */ ++.word M_26,N_26,FSEL_26,M2_26 ++/* 3410 */ ++.word M_26,N_26,FSEL_26,M2_26 ++ ++/* 38.4MHz */ ++/* ES1 */ ++.word M_38p4_ES1,N_38p4_ES1,FSL_38p4_ES1,M2_38p4_ES1 ++/* ES2 */ ++.word M_38p4,N_38p4,FSEL_38p4,M2_38p4 ++/* 3410 */ ++.word M_38p4,N_38p4,FSEL_38p4,M2_38p4 ++ ++.globl get_core_dpll_param ++get_core_dpll_param: ++ adr r0, core_dpll_param ++ mov pc, lr ++ ++/* PER DPLL values are same for both ES1 and ES2 */ ++per_dpll_param: ++/* 12MHz */ ++.word 0xD8,0x05,0x07,0x09 ++ ++/* 13MHz */ ++.word 0x1B0,0x0C,0x03,0x09 ++ ++/* 19.2MHz */ ++.word 0xE1,0x09,0x07,0x09 ++ ++/* 26MHz */ ++.word 0xD8,0x0C,0x07,0x09 ++ ++/* 38.4MHz */ ++.word 0xE1,0x13,0x07,0x09 ++ ++.globl get_per_dpll_param ++get_per_dpll_param: ++ adr r0, per_dpll_param ++ mov pc, lr ++ +diff --git a/board/omap3530beagle/mem.c b/board/omap3530beagle/mem.c +new file mode 100644 +index 0000000..bee96c3 +--- /dev/null ++++ b/board/omap3530beagle/mem.c +@@ -0,0 +1,251 @@ ++/* ++ * (C) Copyright 2008 ++ * Texas Instruments, ++ * ++ * Initial Code from: ++ * Richard Woodruff ++ * Syed Mohammed Khasim ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Only One NAND allowed on board at a time. ++ * The GPMC CS Base for the same ++ */ ++unsigned int nand_cs_base; ++unsigned int boot_flash_base; ++unsigned int boot_flash_off; ++unsigned int boot_flash_sec; ++unsigned int boot_flash_type; ++volatile unsigned int boot_flash_env_addr; ++ ++/* help common/env_flash.c */ ++#ifdef ENV_IS_VARIABLE ++ ++uchar(*boot_env_get_char_spec) (int index); ++int (*boot_env_init) (void); ++int (*boot_saveenv) (void); ++void (*boot_env_relocate_spec) (void); ++ ++/* 16 bit NAND */ ++uchar env_get_char_spec(int index); ++int env_init(void); ++int saveenv(void); ++void env_relocate_spec(void); ++extern char *env_name_spec; ++ ++u8 is_nand; ++ ++#endif /* ENV_IS_VARIABLE */ ++ ++static 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 ++}; ++ ++/************************************************************************** ++ * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow ++ * command line mem=xyz use all memory with out discontinuous support ++ * compiled in. Could do it at the ATAG, but there really is two banks... ++ * Called as part of 2nd phase DDR init. ++ **************************************************************************/ ++void make_cs1_contiguous(void) ++{ ++ u32 size, a_add_low, a_add_high; ++ ++ size = get_sdr_cs_size(SDRC_CS0_OSET); ++ size /= SZ_32M; /* find size to offset CS1 */ ++ a_add_high = (size & 3) << 8; /* set up low field */ ++ a_add_low = (size & 0x3C) >> 2; /* set up high field */ ++ __raw_writel((a_add_high | a_add_low), SDRC_CS_CFG); ++ ++} ++ ++/******************************************************** ++ * mem_ok() - test used to see if timings are correct ++ * for a part. Helps in guessing which part ++ * we are currently using. ++ *******************************************************/ ++u32 mem_ok(void) ++{ ++ u32 val1, val2, addr; ++ u32 pattern = 0x12345678; ++ ++ addr = OMAP34XX_SDRC_CS0; ++ ++ __raw_writel(0x0, addr + 0x400); /* clear pos A */ ++ __raw_writel(pattern, addr); /* pattern to pos B */ ++ __raw_writel(0x0, addr + 4); /* remove pattern off the bus */ ++ val1 = __raw_readl(addr + 0x400); /* get pos A value */ ++ val2 = __raw_readl(addr); /* get val2 */ ++ ++ if ((val1 != 0) || (val2 != pattern)) /* see if pos A value changed */ ++ return (0); ++ else ++ return (1); ++} ++ ++/******************************************************** ++ * sdrc_init() - init the sdrc chip selects CS0 and CS1 ++ * - early init routines, called from flash or ++ * SRAM. ++ *******************************************************/ ++void sdrc_init(void) ++{ ++ /* only init up first bank here */ ++ do_sdrc_init(SDRC_CS0_OSET, EARLY_INIT); ++} ++ ++/************************************************************************* ++ * do_sdrc_init(): initialize the SDRAM for use. ++ * -code sets up SDRAM basic SDRC timings for CS0 ++ * -optimal settings can be placed here, or redone after i2c ++ * inspection of board info ++ * ++ * - code called ones in C-Stack only context for CS0 and a possible 2nd ++ * time depending on memory configuration from stack+global context ++ **************************************************************************/ ++ ++void do_sdrc_init(u32 offset, u32 early) ++{ ++ ++ /* reset sdrc controller */ ++ __raw_writel(SOFTRESET, SDRC_SYSCONFIG); ++ wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); ++ __raw_writel(0, SDRC_SYSCONFIG); ++ ++ /* setup sdrc to ball mux */ ++ __raw_writel(SDP_SDRC_SHARING, SDRC_SHARING); ++ ++ /* SDRC_MCFG0 register */ ++ (*(unsigned int *) 0x6D000080) = 0x02584099; /* from Micron */ ++ ++ /* SDRC_RFR_CTRL0 register */ ++ (*(unsigned int *) 0x6D0000a4) = 0x54601; /* for 166M */ ++ ++ /* SDRC_ACTIM_CTRLA0 register */ ++ (*(unsigned int *) 0x6D00009c) = 0xa29db4c6; /* for 166M */ ++ ++ /* SDRC_ACTIM_CTRLB0 register */ ++ (*(unsigned int *) 0x6D0000a0) = 0x12214; /* for 166M */ ++ ++ /* Disble Power Down of CKE cuz of 1 CKE on combo part */ ++ (*(unsigned int *) 0x6D000070) = 0x00000081; ++ ++ /* SDRC_Manual command register */ ++ (*(unsigned int *) 0x6D0000a8) = 0x00000000; /* NOP command */ ++ (*(unsigned int *) 0x6D0000a8) = 0x00000001; /* Precharge command */ ++ (*(unsigned int *) 0x6D0000a8) = 0x00000002; /* Auto-refresh command */ ++ (*(unsigned int *) 0x6D0000a8) = 0x00000002; /* Auto-refresh command */ ++ ++ /* SDRC MR0 register */ ++ (*(int *) 0x6D000084) = 0x00000032; /* Burst length = 4 */ ++ /* CAS latency = 3, Write Burst = Read Burst Serial Mode */ ++ ++ /* SDRC DLLA control register */ ++ (*(unsigned int *) 0x6D000060) = 0x0000A; ++ sdelay(0x20000); ++} ++ ++void enable_gpmc_config(u32 *gpmc_config, u32 gpmc_base, u32 base, u32 size) ++{ ++ __raw_writel(0, GPMC_CONFIG7 + gpmc_base); ++ sdelay(1000); ++ /* Delay for settling */ ++ __raw_writel(gpmc_config[0], GPMC_CONFIG1 + gpmc_base); ++ __raw_writel(gpmc_config[1], GPMC_CONFIG2 + gpmc_base); ++ __raw_writel(gpmc_config[2], GPMC_CONFIG3 + gpmc_base); ++ __raw_writel(gpmc_config[3], GPMC_CONFIG4 + gpmc_base); ++ __raw_writel(gpmc_config[4], GPMC_CONFIG5 + gpmc_base); ++ __raw_writel(gpmc_config[5], GPMC_CONFIG6 + gpmc_base); ++ /* Enable the config */ ++ __raw_writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) | ++ (1 << 6)), GPMC_CONFIG7 + gpmc_base); ++ 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 */ ++ u32 mux = 0, mwidth; ++ u32 *gpmc_config = NULL; ++ u32 gpmc_base = 0; ++ u32 base = 0; ++ u32 size = 0; ++ u32 f_off = CFG_MONITOR_LEN; ++ u32 f_sec = 0; ++ u32 config = 0; ++ ++ mux = BIT9; ++ mwidth = get_gpmc0_width(); ++ ++ /* global settings */ ++ __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ ++ __raw_writel(0, GPMC_TIMEOUT_CONTROL); /* timeout disable */ ++ ++ config = __raw_readl(GPMC_CONFIG); ++ config &= (~0xf00); ++ __raw_writel(config, GPMC_CONFIG); ++ ++ /* Disable the GPMC0 config set by ROM code ++ * It conflicts with our MPDB (both at 0x08000000) ++ */ ++ __raw_writel(0, GPMC_CONFIG7 + GPMC_CONFIG_CS0); ++ sdelay(1000); ++ ++ /* CS 0 */ ++ gpmc_config = gpmc_m_nand; ++ gpmc_base = GPMC_CONFIG_CS0 + (0 * GPMC_CONFIG_WIDTH); ++ base = PISMO1_NAND_BASE; ++ size = PISMO1_NAND_SIZE; ++ enable_gpmc_config(gpmc_config, gpmc_base, base, size); ++ ++ f_off = SMNAND_ENV_OFFSET; ++ f_sec = SZ_128K; ++ is_nand = 1; ++ nand_cs_base = gpmc_base; ++ ++ /* env setup */ ++ boot_flash_base = base; ++ boot_flash_off = f_off; ++ boot_flash_sec = f_sec; ++ boot_flash_env_addr = f_off; ++ ++#ifdef ENV_IS_VARIABLE ++ boot_env_get_char_spec = env_get_char_spec; ++ boot_env_init = env_init; ++ boot_saveenv = saveenv; ++ boot_env_relocate_spec = env_relocate_spec; ++#endif ++ ++} +diff --git a/board/omap3530beagle/nand.c b/board/omap3530beagle/nand.c +new file mode 100644 +index 0000000..4a8b6e4 +--- /dev/null ++++ b/board/omap3530beagle/nand.c +@@ -0,0 +1,409 @@ ++/* ++ * (C) Copyright 2004-2008 Texas Instruments, ++ * Rohit Choraria ++ * ++ * 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 ++#include ++#include ++#include ++#include ++ ++#if defined(CONFIG_CMD_NAND) ++ ++#include ++ ++unsigned char cs; ++volatile unsigned long gpmc_cs_base_add; ++ ++#define GPMC_BUF_EMPTY 0 ++#define GPMC_BUF_FULL 1 ++ ++#define ECC_P1_128_E(val) ((val) & 0x000000FF) /* Bit 0 to 7 */ ++#define ECC_P512_2048_E(val) (((val) & 0x00000F00)>>8) /* Bit 8 to 11 */ ++#define ECC_P1_128_O(val) (((val) & 0x00FF0000)>>16) /* Bit 16 to Bit 23 */ ++#define ECC_P512_2048_O(val) (((val) & 0x0F000000)>>24) /* Bit 24 to Bit 27 */ ++ ++/* ++ * omap_nand_hwcontrol - Set the address pointers corretly for the ++ * following address/data/command operation ++ * @mtd: MTD device structure ++ * @ctrl: Says whether Address or Command or Data is following. ++ */ ++static void omap_nand_hwcontrol(struct mtd_info *mtd, int 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_CTL_SETCLE: ++ this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_CMD; ++ this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT; ++ break; ++ case NAND_CTL_SETALE: ++ this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_ADR; ++ this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT; ++ break; ++ case NAND_CTL_CLRCLE: ++ this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_DAT; ++ this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT; ++ break; ++ case NAND_CTL_CLRALE: ++ this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_DAT; ++ this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT; ++ break; ++ } ++} ++ ++/* ++ * omap_nand_wait - called primarily after a program/erase operation ++ * so that we access NAND again only after the device ++ * is ready again. ++ * @mtd: MTD device structure ++ * @chip: nand_chip structure ++ * @state: State from which wait function is being called i.e write/erase. ++ */ ++static int omap_nand_wait(struct mtd_info *mtd, struct nand_chip *chip, ++ int state) ++{ ++ register struct nand_chip *this = mtd->priv; ++ int status = 0; ++ ++ this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_CMD; ++ this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT; ++ /* Send the status command and loop until the device is free */ ++ while (!(status & 0x40)) { ++ __raw_writeb(NAND_CMD_STATUS & 0xFF, this->IO_ADDR_W); ++ status = __raw_readb(this->IO_ADDR_R); ++ } ++ return status; ++} ++ ++#ifdef CFG_NAND_WIDTH_16 ++/* ++ * omap_nand_write_buf16 - [DEFAULT] write buffer to chip ++ * @mtd: MTD device structure ++ * @buf: data buffer ++ * @len: number of bytes to write ++ * ++ * Default write function for 16bit buswith ++ */ ++static void omap_nand_write_buf(struct mtd_info *mtd, const u_char *buf, ++ int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ u16 *p = (u16 *) buf; ++ len >>= 1; ++ ++ for (i = 0; i < len; i++) { ++ writew(p[i], this->IO_ADDR_W); ++ while (GPMC_BUF_EMPTY == (readl(GPMC_STATUS) & GPMC_BUF_FULL)) ; ++ } ++} ++ ++/* ++ * nand_read_buf16 - [DEFAULT] read chip data into buffer ++ * @mtd: MTD device structure ++ * @buf: buffer to store date ++ * @len: number of bytes to read ++ * ++ * Default read function for 16bit buswith ++ */ ++static void omap_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ u16 *p = (u16 *) buf; ++ len >>= 1; ++ ++ for (i = 0; i < len; i++) ++ p[i] = readw(this->IO_ADDR_R); ++} ++ ++#else ++/* ++ * omap_nand_write_buf - write buffer to NAND controller ++ * @mtd: MTD device structure ++ * @buf: data buffer ++ * @len: number of bytes to write ++ * ++ */ ++static void omap_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, ++ int len) ++{ ++ int i; ++ int j = 0; ++ struct nand_chip *chip = mtd->priv; ++ ++ for (i = 0; i < len; i++) { ++ writeb(buf[i], chip->IO_ADDR_W); ++ for (j = 0; j < 10; j++) ; ++ } ++ ++} ++ ++/* ++ * omap_nand_read_buf - read data from NAND controller into buffer ++ * @mtd: MTD device structure ++ * @buf: buffer to store date ++ * @len: number of bytes to read ++ * ++ */ ++static void omap_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) ++{ ++ int i; ++ int j = 0; ++ struct nand_chip *chip = mtd->priv; ++ ++ for (i = 0; i < len; i++) { ++ buf[i] = readb(chip->IO_ADDR_R); ++ while (GPMC_BUF_EMPTY == (readl(GPMC_STATUS) & GPMC_BUF_FULL)); ++ } ++} ++#endif /* CFG_NAND_WIDTH_16 */ ++ ++/* ++ * omap_hwecc_init - Initialize the Hardware ECC for NAND flash in ++ * GPMC controller ++ * @mtd: MTD device structure ++ * ++ */ ++static void omap_hwecc_init(struct nand_chip *chip) ++{ ++ unsigned long val = 0x0; ++ ++ /* Init ECC Control Register */ ++ /* Clear all ECC | Enable Reg1 */ ++ val = ((0x00000001 << 8) | 0x00000001); ++ __raw_writel(val, GPMC_BASE + GPMC_ECC_CONTROL); ++ __raw_writel(0x3fcff000, GPMC_BASE + GPMC_ECC_SIZE_CONFIG); ++} ++ ++/* ++ * omap_correct_data - 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 ++ * @calc_ecc: ecc read from ECC registers ++ */ ++static int omap_correct_data(struct mtd_info *mtd, u_char *dat, ++ u_char *read_ecc, u_char *calc_ecc) ++{ ++ return 0; ++} ++ ++/* ++ * omap_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. ++ * @mtd: MTD structure ++ * @dat: unused ++ * @ecc_code: ecc_code buffer ++ */ ++static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, ++ u_char *ecc_code) ++{ ++ unsigned long val = 0x0; ++ unsigned long reg; ++ ++ /* Start Reading from HW ECC1_Result = 0x200 */ ++ reg = (unsigned long) (GPMC_BASE + GPMC_ECC1_RESULT); ++ val = __raw_readl(reg); ++ ++ *ecc_code++ = ECC_P1_128_E(val); ++ *ecc_code++ = ECC_P1_128_O(val); ++ *ecc_code++ = ECC_P512_2048_E(val) | ECC_P512_2048_O(val) << 4; ++ ++ return 0; ++} ++ ++/* ++ * omap_enable_ecc - This function enables the hardware ecc functionality ++ * @mtd: MTD device structure ++ * @mode: Read/Write mode ++ */ ++static void omap_enable_hwecc(struct mtd_info *mtd, int mode) ++{ ++ struct nand_chip *chip = mtd->priv; ++ unsigned int val = __raw_readl(GPMC_BASE + GPMC_ECC_CONFIG); ++ unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1; ++ ++ switch (mode) { ++ case NAND_ECC_READ: ++ __raw_writel(0x101, GPMC_BASE + GPMC_ECC_CONTROL); ++ /* ECC col width | CS | ECC Enable */ ++ val = (dev_width << 7) | (cs << 1) | (0x1); ++ break; ++ case NAND_ECC_READSYN: ++ __raw_writel(0x100, GPMC_BASE + GPMC_ECC_CONTROL); ++ /* ECC col width | CS | ECC Enable */ ++ val = (dev_width << 7) | (cs << 1) | (0x1); ++ break; ++ case NAND_ECC_WRITE: ++ __raw_writel(0x101, GPMC_BASE + GPMC_ECC_CONTROL); ++ /* ECC col width | CS | ECC Enable */ ++ val = (dev_width << 7) | (cs << 1) | (0x1); ++ break; ++ default: ++ printf("Error: Unrecognized Mode[%d]!\n", mode); ++ break; ++ } ++ ++ __raw_writel(val, GPMC_BASE + GPMC_ECC_CONFIG); ++} ++ ++static struct nand_oobinfo hw_nand_oob_64 = { ++ .useecc = MTD_NANDECC_AUTOPLACE, ++ .eccbytes = 12, ++ .eccpos = { ++ 2, 3, 4, 5, ++ 6, 7, 8, 9, ++ 10, 11, 12, 13}, ++ .oobfree = { {20, 50} } /* don't care */ ++}; ++ ++static struct nand_oobinfo sw_nand_oob_64 = { ++ .useecc = MTD_NANDECC_AUTOPLACE, ++ .eccbytes = 24, ++ .eccpos = { ++ 40, 41, 42, 43, 44, 45, 46, 47, ++ 48, 49, 50, 51, 52, 53, 54, 55, ++ 56, 57, 58, 59, 60, 61, 62, 63}, ++ .oobfree = { {2, 38} } ++}; ++ ++void omap_nand_switch_ecc(struct mtd_info *mtd, int hardware) ++{ ++ struct nand_chip *nand = mtd->priv; ++ ++ if (!hardware) { ++ nand->eccmode = NAND_ECC_SOFT; ++ nand->autooob = &sw_nand_oob_64; ++ nand->eccsize = 256; /* set default eccsize */ ++ nand->eccbytes = 3; ++ nand->eccsteps = 8; ++ nand->enable_hwecc = 0; ++ nand->calculate_ecc = nand_calculate_ecc; ++ nand->correct_data = nand_correct_data; ++ } else { ++ nand->eccmode = NAND_ECC_HW3_512; ++ nand->autooob = &hw_nand_oob_64; ++ nand->eccsize = 512; ++ nand->eccbytes = 3; ++ nand->eccsteps = 4; ++ nand->enable_hwecc = omap_enable_hwecc; ++ nand->correct_data = omap_correct_data; ++ nand->calculate_ecc = omap_calculate_ecc; ++ ++ omap_hwecc_init(nand); ++ } ++ ++ mtd->eccsize = nand->eccsize; ++ nand->oobdirty = 1; ++ ++ if (nand->options & NAND_BUSWIDTH_16) { ++ mtd->oobavail = mtd->oobsize - (nand->autooob->eccbytes + 2); ++ if (nand->autooob->eccbytes & 0x01) ++ mtd->oobavail--; ++ } else ++ mtd->oobavail = mtd->oobsize - (nand->autooob->eccbytes + 1); ++} ++ ++/* ++ * Board-specific NAND initialization. The following members of the ++ * argument are board-specific (per include/linux/mtd/nand_new.h): ++ * - 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 ++ * - hwcontrol: hardwarespecific function for accesing control-lines ++ * - dev_ready: hardwarespecific function for accesing device ready/busy line ++ * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must ++ * only be provided if a hardware ECC is available ++ * - eccmode: 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 ++ * Members with a "?" were not set in the merged testing-NAND branch, ++ * so they are not set here either. ++ */ ++int board_nand_init(struct nand_chip *nand) ++{ ++ int gpmc_config = 0; ++ cs = 0; ++ while (cs <= GPMC_MAX_CS) { ++ /* Each GPMC set for a single CS is at offset 0x30 */ ++ /* already remapped for us */ ++ gpmc_cs_base_add = (GPMC_CONFIG_CS0 + (cs * 0x30)); ++ /* xloader/Uboot would have written the NAND type for us ++ * NOTE: This is a temporary measure and cannot handle ONENAND. ++ * The proper way of doing this is to pass the setup of ++ * u-boot up to kernel using kernel params - something on ++ * the lines of machineID ++ */ ++ /* Check if NAND type is set */ ++ if ((__raw_readl(gpmc_cs_base_add + GPMC_CONFIG1) & 0xC00) == ++ 0x800) { ++ /* Found it!! */ ++ break; ++ } ++ cs++; ++ } ++ if (cs > GPMC_MAX_CS) { ++ printf("NAND: Unable to find NAND settings in " \ ++ "GPMC Configuration - quitting\n"); ++ } ++ ++ gpmc_config = __raw_readl(GPMC_CONFIG); ++ /* Disable Write protect */ ++ gpmc_config |= 0x10; ++ __raw_writel(gpmc_config, GPMC_CONFIG); ++ ++ nand->IO_ADDR_R = (int *) gpmc_cs_base_add + GPMC_NAND_DAT; ++ nand->IO_ADDR_W = (int *) gpmc_cs_base_add + GPMC_NAND_CMD; ++ ++ nand->hwcontrol = omap_nand_hwcontrol; ++ nand->options = NAND_NO_PADDING | NAND_CACHEPRG | NAND_NO_AUTOINCR | ++ NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR; ++ nand->read_buf = omap_nand_read_buf; ++ nand->write_buf = omap_nand_write_buf; ++ nand->eccmode = NAND_ECC_SOFT; ++ /* if RDY/BSY line is connected to OMAP then use the omap ready ++ * function and the generic nand_wait function which reads the ++ * status register after monitoring the RDY/BSY line. Otherwise ++ * use a standard chip delay which is slightly more than tR ++ * (AC Timing) of the NAND device and read the status register ++ * until you get a failure or success ++ */ ++ nand->waitfunc = omap_nand_wait; ++ nand->chip_delay = 50; ++ ++ return 0; ++} ++#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ +diff --git a/board/omap3530beagle/omap3530beagle.c b/board/omap3530beagle/omap3530beagle.c +new file mode 100644 +index 0000000..1daf42c +--- /dev/null ++++ b/board/omap3530beagle/omap3530beagle.c +@@ -0,0 +1,781 @@ ++/* ++ * (C) Copyright 2004-2008 ++ * Texas Instruments, ++ * ++ * Author : ++ * Sunil Kumar ++ * Shashi Ranjan ++ * ++ * Derived from Beagle Board and 3430 SDP code by ++ * Richard Woodruff ++ * Syed Mohammed Khasim ++ * ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if (CONFIG_COMMANDS & CFG_CMD_NAND) && defined(CFG_NAND_LEGACY) ++#include ++extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; ++#endif ++ ++/* ++ * Dummy functions to handle errors for EABI incompatibility ++ */ ++void raise(void) ++{ ++} ++ ++void abort(void) ++{ ++} ++ ++ ++/******************************************************* ++ * 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)); ++} ++ ++/***************************************** ++ * Routine: board_init ++ * Description: Early hardware init. ++ *****************************************/ ++int board_init(void) ++{ ++ DECLARE_GLOBAL_DATA_PTR; ++ ++ gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ ++ gd->bd->bi_arch_number = MACH_TYPE_OMAP3_BEAGLE; /* board id for Linux */ ++ gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); /* boot param addr */ ++ ++ return 0; ++} ++ ++/***************************************** ++ * Routine: secure_unlock ++ * Description: Setup security registers for access ++ * (GP Device only) ++ *****************************************/ ++void secure_unlock_mem(void) ++{ ++ /* Permission values for registers -Full fledged permissions to all */ ++#define UNLOCK_1 0xFFFFFFFF ++#define UNLOCK_2 0x00000000 ++#define UNLOCK_3 0x0000FFFF ++ /* Protection Module Register Target APE (PM_RT) */ ++ __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1); ++ __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0); ++ __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0); ++ __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1); ++ ++ __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0); ++ __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0); ++ __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0); ++ ++ __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0); ++ __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0); ++ __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0); ++ __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2); ++ ++ /* IVA Changes */ ++ __raw_writel(UNLOCK_3, IVA2_REQ_INFO_PERMISSION_0); ++ __raw_writel(UNLOCK_3, IVA2_READ_PERMISSION_0); ++ __raw_writel(UNLOCK_3, IVA2_WRITE_PERMISSION_0); ++ ++ __raw_writel(UNLOCK_1, SMS_RG_ATT0); /* SDRC region 0 public */ ++} ++ ++/********************************************************** ++ * Routine: secureworld_exit() ++ * Description: If chip is EMU and boot type is external ++ * configure secure registers and exit secure world ++ * general use. ++ ***********************************************************/ ++void secureworld_exit() ++{ ++ unsigned long i; ++ ++ /* configrue non-secure access control register */ ++ __asm__ __volatile__("mrc p15, 0, %0, c1, c1, 2":"=r"(i)); ++ /* enabling co-processor CP10 and CP11 accesses in NS world */ ++ __asm__ __volatile__("orr %0, %0, #0xC00":"=r"(i)); ++ /* allow allocation of locked TLBs and L2 lines in NS world */ ++ /* allow use of PLE registers in NS world also */ ++ __asm__ __volatile__("orr %0, %0, #0x70000":"=r"(i)); ++ __asm__ __volatile__("mcr p15, 0, %0, c1, c1, 2":"=r"(i)); ++ ++ /* Enable ASA in ACR register */ ++ __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i)); ++ __asm__ __volatile__("orr %0, %0, #0x10":"=r"(i)); ++ __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i)); ++ ++ /* Exiting secure world */ ++ __asm__ __volatile__("mrc p15, 0, %0, c1, c1, 0":"=r"(i)); ++ __asm__ __volatile__("orr %0, %0, #0x31":"=r"(i)); ++ __asm__ __volatile__("mcr p15, 0, %0, c1, c1, 0":"=r"(i)); ++} ++ ++/********************************************************** ++ * Routine: setup_auxcr() ++ * Description: Write to AuxCR desired value using SMI. ++ * general use. ++ ***********************************************************/ ++void setup_auxcr() ++{ ++ unsigned long i; ++ volatile unsigned int j; ++ /* Save r0, r12 and restore them after usage */ ++ __asm__ __volatile__("mov %0, r12":"=r"(j)); ++ __asm__ __volatile__("mov %0, r0":"=r"(i)); ++ ++ /* GP Device ROM code API usage here */ ++ /* r12 = AUXCR Write function and r0 value */ ++ __asm__ __volatile__("mov r12, #0x3"); ++ __asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1"); ++ /* Enabling ASA */ ++ __asm__ __volatile__("orr r0, r0, #0x10"); ++ /* SMI instruction to call ROM Code API */ ++ __asm__ __volatile__(".word 0xE1600070"); ++ __asm__ __volatile__("mov r0, %0":"=r"(i)); ++ __asm__ __volatile__("mov r12, %0":"=r"(j)); ++} ++ ++/********************************************************** ++ * Routine: try_unlock_sram() ++ * Description: If chip is GP/EMU(special) type, unlock the SRAM for ++ * general use. ++ ***********************************************************/ ++void try_unlock_memory() ++{ ++ int mode; ++ int in_sdram = running_in_sdram(); ++ ++ /* if GP device unlock device SRAM for general use */ ++ /* secure code breaks for Secure/Emulation device - HS/E/T */ ++ mode = get_device_type(); ++ if (mode == GP_DEVICE) { ++ secure_unlock_mem(); ++ } ++ /* If device is EMU and boot is XIP external booting ++ * Unlock firewalls and disable L2 and put chip ++ * out of secure world ++ */ ++ /* Assuming memories are unlocked by the demon who put us in SDRAM */ ++ if ((mode <= EMU_DEVICE) && (get_boot_type() == 0x1F) ++ && (!in_sdram)) { ++ secure_unlock_mem(); ++ secureworld_exit(); ++ } ++ ++ return; ++} ++ ++/********************************************************** ++ * Routine: s_init ++ * Description: Does early system init of muxing and clocks. ++ * - Called path is with SRAM stack. ++ **********************************************************/ ++void s_init(void) ++{ ++ int in_sdram = running_in_sdram(); ++ ++#ifdef CONFIG_3430VIRTIO ++ in_sdram = 0; /* allow setup from memory for Virtio */ ++#endif ++ watchdog_init(); ++ ++ try_unlock_memory(); ++ ++ /* Right now flushing at low MPU speed. Need to move after clock init */ ++ v7_flush_dcache_all(get_device_type()); ++#ifndef CONFIG_ICACHE_OFF ++ icache_enable(); ++#endif ++ ++#ifdef CONFIG_L2_OFF ++ l2cache_disable(); ++#else ++ l2cache_enable(); ++#endif ++ /* Writing to AuxCR in U-boot using SMI for GP DEV */ ++ /* Currently SMI in Kernel on ES2 devices seems to have an isse ++ * Once that is resolved, we can postpone this config to kernel ++ */ ++ if (get_device_type() == GP_DEVICE) ++ setup_auxcr(); ++ ++ set_muxconf_regs(); ++ delay(100); ++ ++ prcm_init(); ++ ++ per_clocks_enable(); ++ ++ if (!in_sdram) ++ sdrc_init(); ++} ++/******************************************************* ++ * Routine: misc_init_r ++ * Description: Init ethernet (done here so udelay works) ++ ********************************************************/ ++int misc_init_r(void) ++{ ++ unsigned char byte; ++ ++#ifdef CONFIG_DRIVER_OMAP34XX_I2C ++ i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); ++#endif ++ byte = 0x20; ++ i2c_write(0x4B, 0x7A, 1, &byte, 1); ++ byte = 0x03; ++ i2c_write(0x4B, 0x7D, 1, &byte, 1); ++ byte = 0xE0; ++ i2c_write(0x4B, 0x8E, 1, &byte, 1); ++ byte = 0x05; ++ i2c_write(0x4B, 0x91, 1, &byte, 1); ++ byte = 0x20; ++ i2c_write(0x4B, 0x96, 1, &byte, 1); ++ byte = 0x03; ++ i2c_write(0x4B, 0x99, 1, &byte, 1); ++ byte = 0x33; ++ i2c_write(0x4A, 0xEE, 1, &byte, 1); ++ ++ *((uint *) 0x49058034) = 0xFFFFFAF9; ++ *((uint *) 0x49056034) = 0x0F9F0FFF; ++ *((uint *) 0x49058094) = 0x00000506; ++ *((uint *) 0x49056094) = 0xF060F000; ++ ++ return (0); ++} ++ ++/****************************************************** ++ * Routine: wait_for_command_complete ++ * Description: Wait for posting to finish on watchdog ++ ******************************************************/ ++void wait_for_command_complete(unsigned int wd_base) ++{ ++ int pending = 1; ++ do { ++ pending = __raw_readl(wd_base + WWPS); ++ } while (pending); ++} ++ ++/**************************************** ++ * Routine: watchdog_init ++ * Description: Shut down watch dogs ++ *****************************************/ ++void watchdog_init(void) ++{ ++ /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is ++ * either taken care of by ROM (HS/EMU) or not accessible (GP). ++ * We need to take care of WD2-MPU or take a PRCM reset. WD3 ++ * should not be running and does not generate a PRCM reset. ++ */ ++ ++ sr32(CM_FCLKEN_WKUP, 5, 1, 1); ++ sr32(CM_ICLKEN_WKUP, 5, 1, 1); ++ wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5); /* some issue here */ ++ ++ __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); ++ wait_for_command_complete(WD2_BASE); ++ __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); ++} ++ ++/******************************************************************* ++ * Routine:ether_init ++ * Description: take the Ethernet controller out of reset and wait ++ * for the EEPROM load to complete. ++ ******************************************************************/ ++void ether_init(void) ++{ ++#ifdef CONFIG_DRIVER_LAN91C96 ++ int cnt = 20; ++ ++ __raw_writew(0x0, LAN_RESET_REGISTER); ++ do { ++ __raw_writew(0x1, LAN_RESET_REGISTER); ++ udelay(100); ++ if (cnt == 0) ++ goto h4reset_err_out; ++ --cnt; ++ } while (__raw_readw(LAN_RESET_REGISTER) != 0x1); ++ ++ cnt = 20; ++ ++ do { ++ __raw_writew(0x0, LAN_RESET_REGISTER); ++ udelay(100); ++ if (cnt == 0) ++ goto h4reset_err_out; ++ --cnt; ++ } while (__raw_readw(LAN_RESET_REGISTER) != 0x0000); ++ udelay(1000); ++ ++ *((volatile unsigned char *) ETH_CONTROL_REG) &= ~0x01; ++ udelay(1000); ++ ++ h4reset_err_out: ++ return; ++#endif ++} ++ ++/********************************************** ++ * Routine: dram_init ++ * Description: sets uboots idea of sdram size ++ **********************************************/ ++int dram_init(void) ++{ ++#define NOT_EARLY 0 ++ DECLARE_GLOBAL_DATA_PTR; ++ unsigned int size0 = 0, size1 = 0; ++ u32 mtype, btype; ++ ++ btype = get_board_type(); ++ mtype = get_mem_type(); ++#ifndef CONFIG_3430ZEBU ++ /* fixme... dont know why this func is crashing in ZeBu */ ++ display_board_info(btype); ++#endif ++ /* If a second bank of DDR is attached to CS1 this is ++ * where it can be started. Early init code will init ++ * memory on CS0. ++ */ ++ if ((mtype == DDR_COMBO) || (mtype == DDR_STACKED)) { ++ do_sdrc_init(SDRC_CS1_OSET, NOT_EARLY); ++ } ++ size0 = get_sdr_cs_size(SDRC_CS0_OSET); ++ size1 = get_sdr_cs_size(SDRC_CS1_OSET); ++ ++ gd->bd->bi_dram[0].start = PHYS_SDRAM_1; ++ gd->bd->bi_dram[0].size = size0; ++ gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + size0; ++ gd->bd->bi_dram[1].size = size1; ++ ++ return 0; ++} ++ ++#define MUX_VAL(OFFSET,VALUE)\ ++ __raw_writew((VALUE), OMAP34XX_CTRL_BASE + (OFFSET)); ++ ++#define CP(x) (CONTROL_PADCONF_##x) ++/* ++ * 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 ++ * The commented string gives the final mux configuration for that pin ++ */ ++#define MUX_DEFAULT_ES2()\ ++ /*SDRC*/\ ++ MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /*SDRC_D0*/\ ++ MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)) /*SDRC_D1*/\ ++ MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)) /*SDRC_D2*/\ ++ MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)) /*SDRC_D3*/\ ++ MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)) /*SDRC_D4*/\ ++ MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)) /*SDRC_D5*/\ ++ MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)) /*SDRC_D6*/\ ++ MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)) /*SDRC_D7*/\ ++ MUX_VAL(CP