summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7/am33xx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7/am33xx')
-rw-r--r--arch/arm/cpu/armv7/am33xx/Makefile48
-rw-r--r--arch/arm/cpu/armv7/am33xx/board.c66
-rw-r--r--arch/arm/cpu/armv7/am33xx/clock.c273
-rw-r--r--arch/arm/cpu/armv7/am33xx/ddr.c147
-rw-r--r--arch/arm/cpu/armv7/am33xx/emif4.c201
-rw-r--r--arch/arm/cpu/armv7/am33xx/lowlevel_init.S72
-rw-r--r--arch/arm/cpu/armv7/am33xx/sys_info.c130
7 files changed, 937 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile
new file mode 100644
index 0000000..6beafbb
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/Makefile
@@ -0,0 +1,48 @@
+#
+# 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 "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
+
+COBJS += clock.o
+COBJS += sys_info.o
+COBJS += ddr.o
+COBJS += emif4.o
+COBJS += board.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(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/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c
new file mode 100644
index 0000000..2d6d359
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/board.c
@@ -0,0 +1,66 @@
+/*
+ * board.c
+ *
+ * Common board functions for AM33XX based boards
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+struct timer_reg *timerreg = (struct timer_reg *)DM_TIMER2_BASE;
+
+/*
+ * early system init of muxing and clocks.
+ */
+void s_init(u32 in_ddr)
+{
+ /* WDT1 is already running when the bootloader gets control
+ * Disable it to avoid "random" resets
+ */
+ writel(0xAAAA, &wdtimer->wdtwspr);
+ while (readl(&wdtimer->wdtwwps) != 0x0)
+ ;
+ writel(0x5555, &wdtimer->wdtwspr);
+ while (readl(&wdtimer->wdtwwps) != 0x0)
+ ;
+
+ /* Setup the PLLs and the clocks for the peripherals */
+#ifdef CONFIG_SETUP_PLL
+ pll_init();
+#endif
+ if (!in_ddr)
+ config_ddr();
+}
+
+/* Initialize timer */
+void init_timer(void)
+{
+ /* Reset the Timer */
+ writel(0x2, (&timerreg->tsicrreg));
+
+ /* Wait until the reset is done */
+ while (readl(&timerreg->tiocpcfgreg) & 1)
+ ;
+
+ /* Start the Timer */
+ writel(0x1, (&timerreg->tclrreg));
+}
diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c
new file mode 100644
index 0000000..4ca6c45
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/clock.c
@@ -0,0 +1,273 @@
+/*
+ * clock.c
+ *
+ * clocks for AM33XX based boards
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+#define PRCM_MOD_EN 0x2
+#define PRCM_FORCE_WAKEUP 0x2
+
+#define PRCM_EMIF_CLK_ACTIVITY BIT(2)
+#define PRCM_L3_GCLK_ACTIVITY BIT(4)
+
+#define PLL_BYPASS_MODE 0x4
+#define ST_MN_BYPASS 0x00000100
+#define ST_DPLL_CLK 0x00000001
+#define CLK_SEL_MASK 0x7ffff
+#define CLK_DIV_MASK 0x1f
+#define CLK_DIV2_MASK 0x7f
+#define CLK_SEL_SHIFT 0x8
+#define CLK_MODE_SEL 0x7
+#define CLK_MODE_MASK 0xfffffff8
+#define CLK_DIV_SEL 0xFFFFFFE0
+
+
+const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
+const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
+const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
+
+static void enable_interface_clocks(void)
+{
+ /* Enable all the Interconnect Modules */
+ writel(PRCM_MOD_EN, &cmper->l3clkctrl);
+ while (readl(&cmper->l3clkctrl) != PRCM_MOD_EN)
+ ;
+
+ writel(PRCM_MOD_EN, &cmper->l4lsclkctrl);
+ while (readl(&cmper->l4lsclkctrl) != PRCM_MOD_EN)
+ ;
+
+ writel(PRCM_MOD_EN, &cmper->l4fwclkctrl);
+ while (readl(&cmper->l4fwclkctrl) != PRCM_MOD_EN)
+ ;
+
+ writel(PRCM_MOD_EN, &cmwkup->wkl4wkclkctrl);
+ while (readl(&cmwkup->wkl4wkclkctrl) != PRCM_MOD_EN)
+ ;
+
+ writel(PRCM_MOD_EN, &cmper->l3instrclkctrl);
+ while (readl(&cmper->l3instrclkctrl) != PRCM_MOD_EN)
+ ;
+
+ writel(PRCM_MOD_EN, &cmper->l4hsclkctrl);
+ while (readl(&cmper->l4hsclkctrl) != PRCM_MOD_EN)
+ ;
+}
+
+/*
+ * Force power domain wake up transition
+ * Ensure that the corresponding interface clock is active before
+ * using the peripheral
+ */
+static void power_domain_wkup_transition(void)
+{
+ writel(PRCM_FORCE_WAKEUP, &cmper->l3clkstctrl);
+ writel(PRCM_FORCE_WAKEUP, &cmper->l4lsclkstctrl);
+ writel(PRCM_FORCE_WAKEUP, &cmwkup->wkclkstctrl);
+ writel(PRCM_FORCE_WAKEUP, &cmper->l4fwclkstctrl);
+ writel(PRCM_FORCE_WAKEUP, &cmper->l3sclkstctrl);
+}
+
+/*
+ * Enable the peripheral clock for required peripherals
+ */
+static void enable_per_clocks(void)
+{
+ /* Enable the control module though RBL would have done it*/
+ writel(PRCM_MOD_EN, &cmwkup->wkctrlclkctrl);
+ while (readl(&cmwkup->wkctrlclkctrl) != PRCM_MOD_EN)
+ ;
+
+ /* Enable the module clock */
+ writel(PRCM_MOD_EN, &cmper->timer2clkctrl);
+ while (readl(&cmper->timer2clkctrl) != PRCM_MOD_EN)
+ ;
+
+ /* UART0 */
+ writel(PRCM_MOD_EN, &cmwkup->wkup_uart0ctrl);
+ while (readl(&cmwkup->wkup_uart0ctrl) != PRCM_MOD_EN)
+ ;
+}
+
+static void mpu_pll_config(void)
+{
+ u32 clkmode, clksel, div_m2;
+
+ clkmode = readl(&cmwkup->clkmoddpllmpu);
+ clksel = readl(&cmwkup->clkseldpllmpu);
+ div_m2 = readl(&cmwkup->divm2dpllmpu);
+
+ /* Set the PLL to bypass Mode */
+ writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllmpu);
+ while (readl(&cmwkup->idlestdpllmpu) != ST_MN_BYPASS)
+ ;
+
+ clksel = clksel & (~CLK_SEL_MASK);
+ clksel = clksel | ((MPUPLL_M << CLK_SEL_SHIFT) | MPUPLL_N);
+ writel(clksel, &cmwkup->clkseldpllmpu);
+
+ div_m2 = div_m2 & ~CLK_DIV_MASK;
+ div_m2 = div_m2 | MPUPLL_M2;
+ writel(div_m2, &cmwkup->divm2dpllmpu);
+
+ clkmode = clkmode | CLK_MODE_SEL;
+ writel(clkmode, &cmwkup->clkmoddpllmpu);
+
+ while (readl(&cmwkup->idlestdpllmpu) != ST_DPLL_CLK)
+ ;
+}
+
+static void core_pll_config(void)
+{
+ u32 clkmode, clksel, div_m4, div_m5, div_m6;
+
+ clkmode = readl(&cmwkup->clkmoddpllcore);
+ clksel = readl(&cmwkup->clkseldpllcore);
+ div_m4 = readl(&cmwkup->divm4dpllcore);
+ div_m5 = readl(&cmwkup->divm5dpllcore);
+ div_m6 = readl(&cmwkup->divm6dpllcore);
+
+ /* Set the PLL to bypass Mode */
+ writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllcore);
+
+ while (readl(&cmwkup->idlestdpllcore) != ST_MN_BYPASS)
+ ;
+
+ clksel = clksel & (~CLK_SEL_MASK);
+ clksel = clksel | ((COREPLL_M << CLK_SEL_SHIFT) | COREPLL_N);
+ writel(clksel, &cmwkup->clkseldpllcore);
+
+ div_m4 = div_m4 & ~CLK_DIV_MASK;
+ div_m4 = div_m4 | COREPLL_M4;
+ writel(div_m4, &cmwkup->divm4dpllcore);
+
+ div_m5 = div_m5 & ~CLK_DIV_MASK;
+ div_m5 = div_m5 | COREPLL_M5;
+ writel(div_m5, &cmwkup->divm5dpllcore);
+
+ div_m6 = div_m6 & ~CLK_DIV_MASK;
+ div_m6 = div_m6 | COREPLL_M6;
+ writel(div_m6, &cmwkup->divm6dpllcore);
+
+ clkmode = clkmode | CLK_MODE_SEL;
+ writel(clkmode, &cmwkup->clkmoddpllcore);
+
+ while (readl(&cmwkup->idlestdpllcore) != ST_DPLL_CLK)
+ ;
+}
+
+static void per_pll_config(void)
+{
+ u32 clkmode, clksel, div_m2;
+
+ clkmode = readl(&cmwkup->clkmoddpllper);
+ clksel = readl(&cmwkup->clkseldpllper);
+ div_m2 = readl(&cmwkup->divm2dpllper);
+
+ /* Set the PLL to bypass Mode */
+ writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllper);
+
+ while (readl(&cmwkup->idlestdpllper) != ST_MN_BYPASS)
+ ;
+
+ clksel = clksel & (~CLK_SEL_MASK);
+ clksel = clksel | ((PERPLL_M << CLK_SEL_SHIFT) | PERPLL_N);
+ writel(clksel, &cmwkup->clkseldpllper);
+
+ div_m2 = div_m2 & ~CLK_DIV2_MASK;
+ div_m2 = div_m2 | PERPLL_M2;
+ writel(div_m2, &cmwkup->divm2dpllper);
+
+ clkmode = clkmode | CLK_MODE_SEL;
+ writel(clkmode, &cmwkup->clkmoddpllper);
+
+ while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK)
+ ;
+}
+
+static void ddr_pll_config(void)
+{
+ u32 clkmode, clksel, div_m2;
+
+ clkmode = readl(&cmwkup->clkmoddpllddr);
+ clksel = readl(&cmwkup->clkseldpllddr);
+ div_m2 = readl(&cmwkup->divm2dpllddr);
+
+ /* Set the PLL to bypass Mode */
+ clkmode = (clkmode & CLK_MODE_MASK) | PLL_BYPASS_MODE;
+ writel(clkmode, &cmwkup->clkmoddpllddr);
+
+ /* Wait till bypass mode is enabled */
+ while ((readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS)
+ != ST_MN_BYPASS)
+ ;
+
+ clksel = clksel & (~CLK_SEL_MASK);
+ clksel = clksel | ((DDRPLL_M << CLK_SEL_SHIFT) | DDRPLL_N);
+ writel(clksel, &cmwkup->clkseldpllddr);
+
+ div_m2 = div_m2 & CLK_DIV_SEL;
+ div_m2 = div_m2 | DDRPLL_M2;
+ writel(div_m2, &cmwkup->divm2dpllddr);
+
+ clkmode = (clkmode & CLK_MODE_MASK) | CLK_MODE_SEL;
+ writel(clkmode, &cmwkup->clkmoddpllddr);
+
+ /* Wait till dpll is locked */
+ while ((readl(&cmwkup->idlestdpllddr) & ST_DPLL_CLK) != ST_DPLL_CLK)
+ ;
+}
+
+void enable_emif_clocks(void)
+{
+ /* Enable the EMIF_FW Functional clock */
+ writel(PRCM_MOD_EN, &cmper->emiffwclkctrl);
+ /* Enable EMIF0 Clock */
+ writel(PRCM_MOD_EN, &cmper->emifclkctrl);
+ /* Poll for emif_gclk & L3_G clock are active */
+ while ((readl(&cmper->l3clkstctrl) & (PRCM_EMIF_CLK_ACTIVITY |
+ PRCM_L3_GCLK_ACTIVITY)) != (PRCM_EMIF_CLK_ACTIVITY |
+ PRCM_L3_GCLK_ACTIVITY))
+ ;
+ /* Poll if module is functional */
+ while ((readl(&cmper->emifclkctrl)) != PRCM_MOD_EN)
+ ;
+}
+
+/*
+ * Configure the PLL/PRCM for necessary peripherals
+ */
+void pll_init()
+{
+ mpu_pll_config();
+ core_pll_config();
+ per_pll_config();
+ ddr_pll_config();
+
+ /* Enable the required interconnect clocks */
+ enable_interface_clocks();
+
+ /* Power domain wake up transition */
+ power_domain_wkup_transition();
+
+ /* Enable the required peripherals */
+ enable_per_clocks();
+}
diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c
new file mode 100644
index 0000000..ed982c1
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/ddr.c
@@ -0,0 +1,147 @@
+/*
+ * DDR Configuration for AM33xx devices.
+ *
+ * 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 .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 <asm/arch/cpu.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/io.h>
+
+/**
+ * Base address for EMIF instances
+ */
+static struct emif_regs *emif_reg = {
+ (struct emif_regs *)EMIF4_0_CFG_BASE};
+
+/**
+ * Base address for DDR instance
+ */
+static struct ddr_regs *ddr_reg[2] = {
+ (struct ddr_regs *)DDR_PHY_BASE_ADDR,
+ (struct ddr_regs *)DDR_PHY_BASE_ADDR2};
+
+/**
+ * Base address for ddr io control instances
+ */
+static struct ddr_cmdtctrl *ioctrl_reg = {
+ (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR};
+
+/**
+ * As a convention, all functions here return 0 on success
+ * -1 on failure.
+ */
+
+/**
+ * Configure SDRAM
+ */
+int config_sdram(struct sdram_config *cfg)
+{
+ writel(cfg->sdrcr, &emif_reg->sdrcr);
+ writel(cfg->sdrcr2, &emif_reg->sdrcr2);
+ writel(cfg->refresh, &emif_reg->sdrrcr);
+ writel(cfg->refresh_sh, &emif_reg->sdrrcsr);
+
+ return 0;
+}
+
+/**
+ * Set SDRAM timings
+ */
+int set_sdram_timings(struct sdram_timing *t)
+{
+ writel(t->time1, &emif_reg->sdrtim1);
+ writel(t->time1_sh, &emif_reg->sdrtim1sr);
+ writel(t->time2, &emif_reg->sdrtim2);
+ writel(t->time2_sh, &emif_reg->sdrtim2sr);
+ writel(t->time3, &emif_reg->sdrtim3);
+ writel(t->time3_sh, &emif_reg->sdrtim3sr);
+
+ return 0;
+}
+
+/**
+ * Configure DDR PHY
+ */
+int config_ddr_phy(struct ddr_phy_control *p)
+{
+ writel(p->reg, &emif_reg->ddrphycr);
+ writel(p->reg_sh, &emif_reg->ddrphycsr);
+
+ return 0;
+}
+
+/**
+ * Configure DDR CMD control registers
+ */
+int config_cmd_ctrl(struct cmd_control *cmd)
+{
+ writel(cmd->cmd0csratio, &ddr_reg[0]->cm0csratio);
+ writel(cmd->cmd0csforce, &ddr_reg[0]->cm0csforce);
+ writel(cmd->cmd0csdelay, &ddr_reg[0]->cm0csdelay);
+ writel(cmd->cmd0dldiff, &ddr_reg[0]->cm0dldiff);
+ writel(cmd->cmd0iclkout, &ddr_reg[0]->cm0iclkout);
+
+ writel(cmd->cmd1csratio, &ddr_reg[0]->cm1csratio);
+ writel(cmd->cmd1csforce, &ddr_reg[0]->cm1csforce);
+ writel(cmd->cmd1csdelay, &ddr_reg[0]->cm1csdelay);
+ writel(cmd->cmd1dldiff, &ddr_reg[0]->cm1dldiff);
+ writel(cmd->cmd1iclkout, &ddr_reg[0]->cm1iclkout);
+
+ writel(cmd->cmd2csratio, &ddr_reg[0]->cm2csratio);
+ writel(cmd->cmd2csforce, &ddr_reg[0]->cm2csforce);
+ writel(cmd->cmd2csdelay, &ddr_reg[0]->cm2csdelay);
+ writel(cmd->cmd2dldiff, &ddr_reg[0]->cm2dldiff);
+ writel(cmd->cmd2iclkout, &ddr_reg[0]->cm2iclkout);
+
+ return 0;
+}
+
+/**
+ * Configure DDR DATA registers
+ */
+int config_ddr_data(int macrono, struct ddr_data *data)
+{
+ writel(data->datardsratio0, &ddr_reg[macrono]->dt0rdsratio0);
+ writel(data->datardsratio1, &ddr_reg[macrono]->dt0rdsratio1);
+
+ writel(data->datawdsratio0, &ddr_reg[macrono]->dt0wdsratio0);
+ writel(data->datawdsratio1, &ddr_reg[macrono]->dt0wdsratio1);
+
+ writel(data->datawiratio0, &ddr_reg[macrono]->dt0wiratio0);
+ writel(data->datawiratio1, &ddr_reg[macrono]->dt0wiratio1);
+ writel(data->datagiratio0, &ddr_reg[macrono]->dt0giratio0);
+ writel(data->datagiratio1, &ddr_reg[macrono]->dt0giratio1);
+
+ writel(data->datafwsratio0, &ddr_reg[macrono]->dt0fwsratio0);
+ writel(data->datafwsratio1, &ddr_reg[macrono]->dt0fwsratio1);
+
+ writel(data->datawrsratio0, &ddr_reg[macrono]->dt0wrsratio0);
+ writel(data->datawrsratio1, &ddr_reg[macrono]->dt0wrsratio1);
+
+ writel(data->datadldiff0, &ddr_reg[macrono]->dt0dldiff0);
+
+ return 0;
+}
+
+int config_io_ctrl(struct ddr_ioctrl *ioctrl)
+{
+ writel(ioctrl->cmd1ctl, &ioctrl_reg->cm0ioctl);
+ writel(ioctrl->cmd2ctl, &ioctrl_reg->cm1ioctl);
+ writel(ioctrl->cmd3ctl, &ioctrl_reg->cm2ioctl);
+ writel(ioctrl->data1ctl, &ioctrl_reg->dt0ioctl);
+ writel(ioctrl->data2ctl, &ioctrl_reg->dt1ioctl);
+
+ return 0;
+}
diff --git a/arch/arm/cpu/armv7/am33xx/emif4.c b/arch/arm/cpu/armv7/am33xx/emif4.c
new file mode 100644
index 0000000..1318365
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/emif4.c
@@ -0,0 +1,201 @@
+/*
+ * emif4.c
+ *
+ * AM33XX emif4 configuration file
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct ddr_regs *ddrregs = (struct ddr_regs *)DDR_PHY_BASE_ADDR;
+struct vtp_reg *vtpreg = (struct vtp_reg *)VTP0_CTRL_ADDR;
+struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
+
+
+int dram_init(void)
+{
+ /* dram_init must store complete ramsize in gd->ram_size */
+ gd->ram_size = get_ram_size(
+ (void *)CONFIG_SYS_SDRAM_BASE,
+ CONFIG_MAX_RAM_BANK_SIZE);
+ return 0;
+}
+
+void dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ gd->bd->bi_dram[0].size = gd->ram_size;
+}
+
+
+#ifdef CONFIG_AM335X_CONFIG_DDR
+static void data_macro_config(int dataMacroNum)
+{
+ struct ddr_data data;
+
+ data.datardsratio0 = ((DDR2_RD_DQS<<30)|(DDR2_RD_DQS<<20)
+ |(DDR2_RD_DQS<<10)|(DDR2_RD_DQS<<0));
+ data.datardsratio1 = DDR2_RD_DQS>>2;
+ data.datawdsratio0 = ((DDR2_WR_DQS<<30)|(DDR2_WR_DQS<<20)
+ |(DDR2_WR_DQS<<10)|(DDR2_WR_DQS<<0));
+ data.datawdsratio1 = DDR2_WR_DQS>>2;
+ data.datawiratio0 = ((DDR2_PHY_WRLVL<<30)|(DDR2_PHY_WRLVL<<20)
+ |(DDR2_PHY_WRLVL<<10)|(DDR2_PHY_WRLVL<<0));
+ data.datawiratio1 = DDR2_PHY_WRLVL>>2;
+ data.datagiratio0 = ((DDR2_PHY_GATELVL<<30)|(DDR2_PHY_GATELVL<<20)
+ |(DDR2_PHY_GATELVL<<10)|(DDR2_PHY_GATELVL<<0));
+ data.datagiratio1 = DDR2_PHY_GATELVL>>2;
+ data.datafwsratio0 = ((DDR2_PHY_FIFO_WE<<30)|(DDR2_PHY_FIFO_WE<<20)
+ |(DDR2_PHY_FIFO_WE<<10)|(DDR2_PHY_FIFO_WE<<0));
+ data.datafwsratio1 = DDR2_PHY_FIFO_WE>>2;
+ data.datawrsratio0 = ((DDR2_PHY_WR_DATA<<30)|(DDR2_PHY_WR_DATA<<20)
+ |(DDR2_PHY_WR_DATA<<10)|(DDR2_PHY_WR_DATA<<0));
+ data.datawrsratio1 = DDR2_PHY_WR_DATA>>2;
+ data.datadldiff0 = PHY_DLL_LOCK_DIFF;
+
+ config_ddr_data(dataMacroNum, &data);
+}
+
+static void cmd_macro_config(void)
+{
+ struct cmd_control cmd;
+
+ cmd.cmd0csratio = DDR2_RATIO;
+ cmd.cmd0csforce = CMD_FORCE;
+ cmd.cmd0csdelay = CMD_DELAY;
+ cmd.cmd0dldiff = DDR2_DLL_LOCK_DIFF;
+ cmd.cmd0iclkout = DDR2_INVERT_CLKOUT;
+
+ cmd.cmd1csratio = DDR2_RATIO;
+ cmd.cmd1csforce = CMD_FORCE;
+ cmd.cmd1csdelay = CMD_DELAY;
+ cmd.cmd1dldiff = DDR2_DLL_LOCK_DIFF;
+ cmd.cmd1iclkout = DDR2_INVERT_CLKOUT;
+
+ cmd.cmd2csratio = DDR2_RATIO;
+ cmd.cmd2csforce = CMD_FORCE;
+ cmd.cmd2csdelay = CMD_DELAY;
+ cmd.cmd2dldiff = DDR2_DLL_LOCK_DIFF;
+ cmd.cmd2iclkout = DDR2_INVERT_CLKOUT;
+
+ config_cmd_ctrl(&cmd);
+
+}
+
+static void config_vtp(void)
+{
+ writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_ENABLE,
+ &vtpreg->vtp0ctrlreg);
+ writel(readl(&vtpreg->vtp0ctrlreg) & (~VTP_CTRL_START_EN),
+ &vtpreg->vtp0ctrlreg);
+ writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_START_EN,
+ &vtpreg->vtp0ctrlreg);
+
+ /* Poll for READY */
+ while ((readl(&vtpreg->vtp0ctrlreg) & VTP_CTRL_READY) !=
+ VTP_CTRL_READY)
+ ;
+}
+
+static void config_emif_ddr2(void)
+{
+ int i;
+ int ret;
+ struct sdram_config cfg;
+ struct sdram_timing tmg;
+ struct ddr_phy_control phyc;
+
+ /*Program EMIF0 CFG Registers*/
+ phyc.reg = EMIF_READ_LATENCY;
+ phyc.reg_sh = EMIF_READ_LATENCY;
+ phyc.reg2 = EMIF_READ_LATENCY;
+
+ tmg.time1 = EMIF_TIM1;
+ tmg.time1_sh = EMIF_TIM1;
+ tmg.time2 = EMIF_TIM2;
+ tmg.time2_sh = EMIF_TIM2;
+ tmg.time3 = EMIF_TIM3;
+ tmg.time3_sh = EMIF_TIM3;
+
+ cfg.sdrcr = EMIF_SDCFG;
+ cfg.sdrcr2 = EMIF_SDCFG;
+ cfg.refresh = 0x00004650;
+ cfg.refresh_sh = 0x00004650;
+
+ /* Program EMIF instance */
+ ret = config_ddr_phy(&phyc);
+ if (ret < 0)
+ printf("Couldn't configure phyc\n");
+
+ ret = config_sdram(&cfg);
+ if (ret < 0)
+ printf("Couldn't configure SDRAM\n");
+
+ ret = set_sdram_timings(&tmg);
+ if (ret < 0)
+ printf("Couldn't configure timings\n");
+
+ /* Delay */
+ for (i = 0; i < 5000; i++)
+ ;
+
+ cfg.refresh = EMIF_SDREF;
+ cfg.refresh_sh = EMIF_SDREF;
+ cfg.sdrcr = EMIF_SDCFG;
+ cfg.sdrcr2 = EMIF_SDCFG;
+
+ ret = config_sdram(&cfg);
+ if (ret < 0)
+ printf("Couldn't configure SDRAM\n");
+}
+
+void config_ddr(void)
+{
+ int data_macro_0 = 0;
+ int data_macro_1 = 1;
+ struct ddr_ioctrl ioctrl;
+
+ enable_emif_clocks();
+
+ config_vtp();
+
+ cmd_macro_config();
+
+ data_macro_config(data_macro_0);
+ data_macro_config(data_macro_1);
+
+ writel(PHY_RANK0_DELAY, &ddrregs->dt0rdelays0);
+ writel(PHY_RANK0_DELAY, &ddrregs->dt1rdelays0);
+
+ ioctrl.cmd1ctl = DDR_IOCTRL_VALUE;
+ ioctrl.cmd2ctl = DDR_IOCTRL_VALUE;
+ ioctrl.cmd3ctl = DDR_IOCTRL_VALUE;
+ ioctrl.data1ctl = DDR_IOCTRL_VALUE;
+ ioctrl.data2ctl = DDR_IOCTRL_VALUE;
+
+ config_io_ctrl(&ioctrl);
+
+ writel(readl(&ddrctrl->ddrioctrl) & 0xefffffff, &ddrctrl->ddrioctrl);
+ writel(readl(&ddrctrl->ddrckectrl) | 0x00000001, &ddrctrl->ddrckectrl);
+
+ config_emif_ddr2();
+}
+#endif
diff --git a/arch/arm/cpu/armv7/am33xx/lowlevel_init.S b/arch/arm/cpu/armv7/am33xx/lowlevel_init.S
new file mode 100644
index 0000000..17c962f
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/lowlevel_init.S
@@ -0,0 +1,72 @@
+/*
+ * lowlevel_init.S
+ *
+ * AM33XX low level initialization.
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * Initial Code by:
+ * Mansoor Ahamed <mansoor.ahamed@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 "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>
+
+_mark1:
+ .word mark1
+_lowlevel_init1:
+ .word lowlevel_init
+_s_init_start:
+ .word s_init_start
+
+_TEXT_BASE:
+ .word CONFIG_SYS_TEXT_BASE /* sdram load addr from config.mk */
+
+/*****************************************************************************
+ * lowlevel_init: - Platform low level init.
+ ****************************************************************************/
+.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_init1
+ ldr r3, _TEXT_BASE
+ sub r4, r2, r3
+ sub r0, pc, r4
+ 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() */
+
+ 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
+
+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
+
+SRAM_STACK:
+ /* Place stack at the top */
+ .word LOW_LEVEL_SRAM_STACK
diff --git a/arch/arm/cpu/armv7/am33xx/sys_info.c b/arch/arm/cpu/armv7/am33xx/sys_info.c
new file mode 100644
index 0000000..507b618
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/sys_info.c
@@ -0,0 +1,130 @@
+/*
+ * sys_info.c
+ *
+ * System information functions
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.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.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+
+struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE;
+
+/**
+ * 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 BOARD_REV_ID;
+}
+
+/**
+ * get_device_type(): tell if GP/HS/EMU/TST
+ */
+u32 get_device_type(void)
+{
+ int mode;
+ mode = readl(&cstat->statusreg) & (DEVICE_MASK);
+ return mode >>= 8;
+}
+
+/**
+ * get_sysboot_value(void) - return SYS_BOOT[4:0]
+ */
+u32 get_sysboot_value(void)
+{
+ int mode;
+ mode = readl(&cstat->statusreg) & (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 AM335X:
+ cpu_s = "AM335X";
+ 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("AM%s-%s rev %d\n",
+ cpu_s, sec_s, get_cpu_rev());
+
+ /* TODO: Print ARM and DDR frequencies */
+
+ return 0;
+}
+#endif /* CONFIG_DISPLAY_CPUINFO */