Anyone willing to review this? I'd like to get it pulled in to Albert's arm repo ASAP.
Thanks, Tom On Wed, Feb 16, 2011 at 1:26 PM, Tom Warren <twarren.nvi...@gmail.com> wrote: > Signed-off-by: Tom Warren <twar...@nvidia.com> > --- > arch/arm/cpu/armv7/start.S | 6 + > arch/arm/cpu/armv7/tegra2/Makefile | 2 +- > arch/arm/cpu/armv7/tegra2/ap20.c | 490 > ++++++++++++++++++++++++++++ > arch/arm/cpu/armv7/tegra2/ap20.h | 105 ++++++ > arch/arm/include/asm/arch-tegra2/clk_rst.h | 27 ++ > arch/arm/include/asm/arch-tegra2/pmc.h | 8 + > arch/arm/include/asm/arch-tegra2/scu.h | 43 +++ > arch/arm/include/asm/arch-tegra2/tegra2.h | 5 + > board/nvidia/common/board.c | 10 + > board/nvidia/common/board.h | 29 ++ > include/configs/harmony.h | 1 + > include/configs/seaboard.h | 1 + > include/configs/tegra2-common.h | 2 + > 13 files changed, 728 insertions(+), 1 deletions(-) > create mode 100644 arch/arm/cpu/armv7/tegra2/ap20.c > create mode 100644 arch/arm/cpu/armv7/tegra2/ap20.h > create mode 100644 arch/arm/include/asm/arch-tegra2/scu.h > create mode 100644 board/nvidia/common/board.h > > diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S > index 684f2d2..50a1725 100644 > --- a/arch/arm/cpu/armv7/start.S > +++ b/arch/arm/cpu/armv7/start.S > @@ -70,6 +70,12 @@ _end_vect: > _TEXT_BASE: > .word CONFIG_SYS_TEXT_BASE > > +#ifdef CONFIG_TEGRA2 > +.globl _armboot_start > +_armboot_start: > + .word _start > +#endif > + > /* > * These are defined in the board-specific linker script. > */ > diff --git a/arch/arm/cpu/armv7/tegra2/Makefile > b/arch/arm/cpu/armv7/tegra2/Makefile > index 687c887..f1ea915 100644 > --- a/arch/arm/cpu/armv7/tegra2/Makefile > +++ b/arch/arm/cpu/armv7/tegra2/Makefile > @@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk > LIB = $(obj)lib$(SOC).o > > SOBJS := lowlevel_init.o > -COBJS := board.o sys_info.o timer.o > +COBJS := ap20.o board.o sys_info.o timer.o > > SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) > OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) > diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c > b/arch/arm/cpu/armv7/tegra2/ap20.c > new file mode 100644 > index 0000000..89d0d5e > --- /dev/null > +++ b/arch/arm/cpu/armv7/tegra2/ap20.c > @@ -0,0 +1,490 @@ > +/* > +* (C) Copyright 2010-2011 > +* NVIDIA Corporation <www.nvidia.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 "ap20.h" > +#include <asm/io.h> > +#include <asm/arch/tegra2.h> > +#include <asm/arch/clk_rst.h> > +#include <asm/arch/pmc.h> > +#include <asm/arch/pinmux.h> > +#include <asm/arch/scu.h> > +#include <common.h> > + > +static void init_pll_x(void) > +{ > + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr > *)NV_PA_CLK_RST_BASE; > + u32 reg; > + > + /* Is PLL-X already running? */ > + reg = readl(&clkrst->crc_pllx_base); > + if (reg & PLL_ENABLE) > + return; > + > + /* Do PLLX init if it isn't running, but BootROM sets it, so TBD */ > +} > + > +static void set_cpu_reset_vector(u32 vector) > +{ > + writel(vector, EXCEP_VECTOR_CPU_RESET_VECTOR); > +} > + > +static void enable_cpu_clock(int enable) > +{ > + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr > *)NV_PA_CLK_RST_BASE; > + u32 reg, clk; > + > + /* > + * NOTE: > + * Regardless of whether the request is to enable or disable the CPU > + * clock, every processor in the CPU complex except the master (CPU 0) > + * will have it's clock stopped because the AVP only talks to the > + * master. The AVP does not know (nor does it need to know) that there > + * are multiple processors in the CPU complex. > + */ > + > + /* Need to initialize PLLX? */ > + if (enable) { > + /* Initialize PLL */ > + init_pll_x(); > + > + /* Wait until stable */ > + udelay(NVBOOT_CLOCKS_PLL_STABILIZATION_DELAY); > + > + reg = CCLK_BURST_POLICY; > + writel(reg, &clkrst->crc_cclk_brst_pol); > + > + reg = SUPER_CCLK_DIVIDER; > + writel(reg, &clkrst->crc_super_cclk_div); > + } > + > + /* Fetch the register containing the main CPU complex clock enable */ > + reg = readl(&clkrst->crc_clk_out_enb_l); > + > + /* > + * Read the register containing the individual CPU clock enables and > + * always stop the clock to CPU 1. > + */ > + clk = readl(&clkrst->crc_clk_cpu_cmplx); > + clk |= CPU1_CLK_STP; > + > + if (enable) { > + /* Enable the CPU clock */ > + reg = readl(&clkrst->crc_clk_out_enb_l); > + reg |= CLK_ENB_CPU; > + clk = readl(&clkrst->crc_clk_cpu_cmplx); > + clk &= ~CPU0_CLK_STP; > + } else { > + /* Disable the CPU clock */ > + reg = readl(&clkrst->crc_clk_out_enb_l); > + reg |= CLK_ENB_CPU; > + clk = readl(&clkrst->crc_clk_cpu_cmplx); > + clk |= CPU0_CLK_STP; > + } > + > + writel(clk, &clkrst->crc_clk_cpu_cmplx); > + writel(reg, &clkrst->crc_clk_out_enb_l); > +} > + > +static int is_cpu_powered(void) > +{ > + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; > + u32 reg; > + > + reg = readl(&pmc->pmc_pwrgate_status); > + > + if (reg & CPU_PWRED) > + return TRUE; > + > + return FALSE; > +} > + > +static void remove_cpu_io_clamps(void) > +{ > + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; > + u32 reg; > + > + /* Remove the clamps on the CPU I/O signals */ > + reg = readl(&pmc->pmc_remove_clamping); > + reg |= CPU_CLMP; > + writel(reg, &pmc->pmc_remove_clamping); > + > + /* Give I/O signals time to stabilize */ > + udelay(1000); > +} > + > +static void powerup_cpu(void) > +{ > + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; > + u32 reg; > + > + if (!is_cpu_powered()) { > + /* Toggle the CPU power state (OFF -> ON) */ > + reg = readl(&pmc->pmc_pwrgate_toggle); > + reg &= (PARTID_CP); > + reg |= START_CP; > + writel(reg, &pmc->pmc_pwrgate_toggle); > + > + /* Wait for the power to come up */ > + while (!is_cpu_powered()) > + ; /* Do nothing */ > + > + /* > + * Remove the I/O clamps from CPU power partition. > + * Recommended only on a Warm boot, if the CPU partition gets > + * power gated. Shouldn't cause any harm when called after a > + * cold boot according to HW, probably just redundant. > + */ > + remove_cpu_io_clamps(); > + } > +} > + > +static void enable_cpu_power_rail(void) > +{ > + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; > + u32 reg; > + > + reg = readl(&pmc->pmc_cntrl); > + reg |= CPUPWRREQ_OE; > + writel(reg, &pmc->pmc_cntrl); > + > + /* Delay to allow for stable power (CPU_PWR_REQ -> VDD_CPU from PMU) > */ > + udelay(3750); > +} > + > +static void reset_A9_cpu(int reset) > +{ > + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr > *)NV_PA_CLK_RST_BASE; > + u32 reg, cpu; > + > + /* > + * NOTE: Regardless of whether the request is to hold the CPU in reset > + * or take it out of reset, every processor in the CPU complex > + * except the master (CPU 0) will be held in reset because the > + * AVP only talks to the master. The AVP does not know that > there > + * are multiple processors in the CPU complex. > + */ > + > + /* Hold CPU 1 in reset */ > + cpu = SET_DBGRESET1 | SET_DERESET1 | SET_CPURESET1; > + writel(cpu, &clkrst->crc_cpu_cmplx_set); > + > + reg = readl(&clkrst->crc_rst_dev_l); > + if (reset) { > + /* Place CPU0 into reset */ > + cpu = SET_DBGRESET0 | SET_DERESET0 | SET_CPURESET0; > + writel(cpu, &clkrst->crc_cpu_cmplx_set); > + > + /* Enable master CPU reset */ > + reg |= SWR_CPU_RST; > + > + } else { > + /* Take CPU0 out of reset */ > + cpu = CLR_DBGRESET0 | CLR_DERESET0 | CLR_CPURESET0; > + writel(cpu, &clkrst->crc_cpu_cmplx_clr); > + > + /* Disable master CPU reset */ > + reg &= ~SWR_CPU_RST; > + } > + > + writel(reg, &clkrst->crc_rst_dev_l); > +} > + > +static void clock_enable_coresight(int enable) > +{ > + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr > *)NV_PA_CLK_RST_BASE; > + u32 rst, clk, src; > + > + rst = readl(&clkrst->crc_rst_dev_u); > + clk = readl(&clkrst->crc_clk_out_enb_u); > + > + if (enable) { > + rst &= ~SWR_CSITE_RST; > + clk |= CLK_ENB_CSITE; > + } else { > + rst |= SWR_CSITE_RST; > + clk &= ~CLK_ENB_CSITE; > + } > + > + writel(clk, &clkrst->crc_clk_out_enb_u); > + writel(rst, &clkrst->crc_rst_dev_u); > + > + if (enable) { > + /* > + * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by > + * 1.5, giving an effective frequency of 144MHz. > + * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor > + * (bits 7:0), so 00000001b == 1.5 (n+1 + .5) > + */ > + src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); > + writel(src, &clkrst->crc_clk_src_csite); > + > + /* Unlock the CPU CoreSight interfaces */ > + rst = 0xC5ACCE55; > + writel(rst, CSITE_CPU_DBG0_LAR); > + writel(rst, CSITE_CPU_DBG1_LAR); > + } > +} > + > +void start_cpu(u32 reset_vector) > +{ > + /* Enable VDD_CPU */ > + enable_cpu_power_rail(); > + > + /* Hold the CPUs in reset */ > + reset_A9_cpu(TRUE); > + > + /* Disable the CPU clock */ > + enable_cpu_clock(FALSE); > + > + /* Enable CoreSight */ > + clock_enable_coresight(TRUE); > + > + /* > + * Set the entry point for CPU execution from reset, > + * if it's a non-zero value. > + */ > + if (reset_vector) > + set_cpu_reset_vector(reset_vector); > + > + /* Enable the CPU clock */ > + enable_cpu_clock(TRUE); > + > + /* If the CPU doesn't already have power, power it up */ > + if (!is_cpu_powered()) > + powerup_cpu(); > + > + /* Take the CPU out of reset */ > + reset_A9_cpu(FALSE); > +} > + > + > +void halt_avp(void) > +{ > + u32 reg; > + > + for (;;) { > + reg = HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \ > + | HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29); > + writel(reg, FLOW_CTLR_HALT_COP_EVENTS); > + } > + /* Should never get here */ > + for (;;) > + ; > +} > + > +void startup_cpu(void) > +{ > + /* Initialize the AVP, clocks, and memory controller */ > + /* SDRAM is guaranteed to be on at this point */ > + > + asm volatile( > + > + /* Start the CPU */ > + /* R0 = reset vector for CPU */ > + "ldr r0, =cold_boot \n" > + "bl start_cpu \n" > + > + /* Transfer control to the AVP code */ > + "bl halt_avp \n" > + > + /* Should never get here */ > + "b . \n" > + ); > +} > + > +extern ulong _armboot_start; > +u32 cpu_boot_stack = CPU_EARLY_BOOT_STACK_LIMIT; > +u32 avp_boot_stack = AVP_EARLY_BOOT_STACK_LIMIT; > +u32 proc_tag = PG_UP_TAG_0_PID_CPU & 0xFF; > +u32 deadbeef = 0xdeadbeef; > + > +void cold_boot(void) > +{ > + asm volatile( > + > + "msr cpsr_c, #0xd3 \n" > + /* > + * Check current processor: CPU or AVP? > + * If AVP, go to AVP boot code, else continue on. > + */ > + "mov r0, %0 \n" > + "ldrb r2, [r0, %1] \n" > + /* are we the CPU? */ > + "cmp r2, %2 \n" > + "mov sp, %3 \n" > + /* leave in some symbols for release debugging */ > + "mov r3, %6 \n" > + "str r3, [sp, #-4]! \n" > + "str r3, [sp, #-4]! \n" > + /* yep, we are the CPU */ > + "bxeq %4 \n" > + /* AVP Initialization follows this path */ > + "mov sp, %5 \n" > + /* leave in some symbols for release debugging */ > + "mov r3, %6 \n" > + "str r3, [sp, #-4]! \n" > + "str r3, [sp, #-4]! \n" > + > + /* Init and Start CPU */ > + "b startup_cpu \n" > + : > + : "i"(NV_PA_PG_UP_BASE), > + "i"(PG_UP_TAG_0), > + "r"(proc_tag), > + "r"(cpu_boot_stack), > + "r"(_armboot_start), > + "r"(avp_boot_stack), > + "r"(deadbeef) > + : "r0", "r2", "r3", "cc", "lr" > + ); > +} > + > +void enable_scu(void) > +{ > + struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE; > + u32 reg; > + > + reg = readl(&scu->scu_ctrl); > + if (reg & SCU_ENABLE) { > + /* SCU already enabled, return */ > + return; > + } > + > + /* Invalidate all ways for all processors */ > + writel(0xFFFF, &scu->scu_inv_all); > + > + /* Enable SCU - bit 0 */ > + reg = readl(&scu->scu_ctrl); > + reg |= SCU_ENABLE; > + writel(reg, &scu->scu_ctrl); > + > + return; > +} > + > +void cache_configure(void) > +{ > + asm volatile( > + > + "stmdb r13!,{r14} \n" > + /* invalidate instruction cache */ > + "mov r1, #0 \n" > + "mcr p15, 0, r1, c7, c5, 0 \n" > + > + /* invalidate the i&d tlb entries */ > + "mcr p15, 0, r1, c8, c5, 0 \n" > + "mcr p15, 0, r1, c8, c6, 0 \n" > + > + /* enable instruction cache */ > + "mrc p15, 0, r1, c1, c0, 0 \n" > + "orr r1, r1, #(1<<12) \n" > + "mcr p15, 0, r1, c1, c0, 0 \n" > + > + "bl enable_scu \n" > + > + /* enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg */ > + "mrc p15, 0, r0, c1, c0, 1 \n" > + "orr r0, r0, #0x41 \n" > + "mcr p15, 0, r0, c1, c0, 1 \n" > + > + /* Now flush the Dcache */ > + "mov r0, #0 \n" > + /* 256 cache lines */ > + "mov r1, #256 \n" > + > + "invalidate_loop: \n" > + > + "add r1, r1, #-1 \n" > + "mov r0, r1, lsl #5 \n" > + /* invalidate d-cache using line (way0) */ > + "mcr p15, 0, r0, c7, c6, 2 \n" > + > + "orr r2, r0, #(1<<30) \n" > + /* invalidate d-cache using line (way1) */ > + "mcr p15, 0, r2, c7, c6, 2 \n" > + > + "orr r2, r0, #(2<<30) \n" > + /* invalidate d-cache using line (way2) */ > + "mcr p15, 0, r2, c7, c6, 2 \n" > + > + "orr r2, r0, #(3<<30) \n" > + /* invalidate d-cache using line (way3) */ > + "mcr p15, 0, r2, c7, c6, 2 \n" > + "cmp r1, #0 \n" > + "bne invalidate_loop \n" > + > + /* FIXME: should have ap20's L2 disabled too */ > + "invalidate_done: \n" > + "ldmia r13!,{pc} \n" > + ".ltorg \n" > + ); > +} > + > +void init_pmc_scratch(void) > +{ > + struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; > + > + /* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */ > + memset(&pmc->pmc_scratch1, 0, 23*4); > + writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20); > +} > + > +u32 s_first_boot = 1; > + > +void cpu_start(void) > +{ > + struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr > *)NV_PA_APB_MISC_BASE; > + > + /* enable JTAG */ > + writel(0xC0, &pmt->pmt_cfg_ctl); > + > + if (s_first_boot) { > + /* > + * Need to set this before cold-booting, > + * otherwise we'll end up in an infinite loop. > + */ > + s_first_boot = 0; > + cold_boot(); > + } > + > + return; > +} > + > +void tegra2_start() > +{ > + if (s_first_boot) { > + /* Init Debug UART Port (115200 8n1) */ > + uart_init(); > + > + /* Init PMC scratch memory */ > + init_pmc_scratch(); > + } > + > +#ifdef CONFIG_ENABLE_CORTEXA9 > + /* take the mpcore out of reset */ > + cpu_start(); > + > + /* configure cache */ > + cache_configure(); > +#endif > +} > + > diff --git a/arch/arm/cpu/armv7/tegra2/ap20.h > b/arch/arm/cpu/armv7/tegra2/ap20.h > new file mode 100644 > index 0000000..de7622d > --- /dev/null > +++ b/arch/arm/cpu/armv7/tegra2/ap20.h > @@ -0,0 +1,105 @@ > +/* > + * (C) Copyright 2010-2011 > + * NVIDIA Corporation <www.nvidia.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 <asm/types.h> > + > +#ifndef FALSE > +#define FALSE 0 > +#endif > +#ifndef TRUE > +#define TRUE 1 > +#endif > + > +#define NVBL_PLLP_KHZ (432000/2) > +/* The stabilization delay in usec */ > +#define NVBOOT_CLOCKS_PLL_STABILIZATION_DELAY (300) > + > +#define PLLX_ENABLED (1 << 30) > +#define CCLK_BURST_POLICY 0x20008888 > +#define SUPER_CCLK_DIVIDER 0x80000000 > + > +/* Calculate clock fractional divider value from ref and target frequencies > */ > +#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / FREQ) - 2) > + > +/* Calculate clock frequency value from reference and clock divider value */ > +#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2)) > + > +/* AVP/CPU ID */ > +#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" > */ > +#define PG_UP_TAG_0 0x0 > + > +/* AP20-Specific Base Addresses */ > + > +/* AP20 Base physical address of SDRAM. */ > +#define AP20_BASE_PA_SDRAM 0x00000000 > +/* AP20 Base physical address of internal SRAM. */ > +#define AP20_BASE_PA_SRAM 0x40000000 > +/* AP20 Size of internal SRAM (256KB). */ > +#define AP20_BASE_PA_SRAM_SIZE 0x00040000 > +/* AP20 Base physical address of flash. */ > +#define AP20_BASE_PA_NOR_FLASH 0xD0000000 > +/* AP20 Base physical address of boot information table. */ > +#define AP20_BASE_PA_BOOT_INFO AP20_BASE_PA_SRAM > + > +/* > + * Super-temporary stacks for EXTREMELY early startup. The values chosen for > + * these addresses must be valid on ALL SOCs because this value is used > before > + * we are able to differentiate between the SOC types. > + * > + * NOTE: The since CPU's stack will eventually be moved from IRAM to SDRAM, > its > + * stack is placed below the AVP stack. Once the CPU stack has been > moved, > + * the AVP is free to use the IRAM the CPU stack previously occupied if > + * it should need to do so. > + * > + * NOTE: In multi-processor CPU complex configurations, each processor will > have > + * its own stack of size CPU_EARLY_BOOT_STACK_SIZE. CPU 0 will have a > + * limit of CPU_EARLY_BOOT_STACK_LIMIT. Each successive CPU will have a > + * stack limit that is CPU_EARLY_BOOT_STACK_SIZE less then the previous > + * CPU. > + */ > + > +/* Common AVP early boot stack limit */ > +#define AVP_EARLY_BOOT_STACK_LIMIT \ > + (AP20_BASE_PA_SRAM + (AP20_BASE_PA_SRAM_SIZE/2)) > +/* Common AVP early boot stack size */ > +#define AVP_EARLY_BOOT_STACK_SIZE 0x1000 > +/* Common CPU early boot stack limit */ > +#define CPU_EARLY_BOOT_STACK_LIMIT \ > + (AVP_EARLY_BOOT_STACK_LIMIT - AVP_EARLY_BOOT_STACK_SIZE) > +/* Common CPU early boot stack size */ > +#define CPU_EARLY_BOOT_STACK_SIZE 0x1000 > + > +#define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100) > +#define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0) > +#define CSITE_CPU_DBG1_LAR (NV_PA_CSITE_BASE + 0x12FB0) > + > +#define FLOW_CTLR_HALT_COP_EVENTS (NV_PA_FLOW_BASE + 4) > +#define FLOW_MODE_STOP 2 > +#define HALT_COP_EVENT_JTAG (1 << 28) > +#define HALT_COP_EVENT_IRQ_1 (1 << 11) > +#define HALT_COP_EVENT_FIQ_1 (1 << 9) > + > +/* Prototypes */ > + > +void tegra2_start(void); > +void uart_init(void); > +void udelay(unsigned long); > diff --git a/arch/arm/include/asm/arch-tegra2/clk_rst.h > b/arch/arm/include/asm/arch-tegra2/clk_rst.h > index 6d573bf..d67a5d7 100644 > --- a/arch/arm/include/asm/arch-tegra2/clk_rst.h > +++ b/arch/arm/include/asm/arch-tegra2/clk_rst.h > @@ -149,6 +149,9 @@ struct clk_rst_ctlr { > uint crc_clk_src_csite; /*_CSITE_0, 0x1D4 */ > uint crc_reserved19[9]; /* 0x1D8-1F8 */ > uint crc_clk_src_osc; /*_OSC_0, 0x1FC */ > + uint crc_reserved20[80]; /* 0x200-33C */ > + uint crc_cpu_cmplx_set; /* _CPU_CMPLX_SET_0, 0x340 */ > + uint crc_cpu_cmplx_clr; /* _CPU_CMPLX_CLR_0, 0x344 */ > }; > > #define PLL_BYPASS (1 << 31) > @@ -162,4 +165,28 @@ struct clk_rst_ctlr { > #define SWR_UARTA_RST (1 << 6) > #define CLK_ENB_UARTA (1 << 6) > > +#define SWR_CPU_RST (1 << 0) > +#define CLK_ENB_CPU (1 << 0) > +#define SWR_CSITE_RST (1 << 9) > +#define CLK_ENB_CSITE (1 << 9) > + > +#define SET_CPURESET0 (1 << 0) > +#define SET_DERESET0 (1 << 4) > +#define SET_DBGRESET0 (1 << 12) > + > +#define SET_CPURESET1 (1 << 1) > +#define SET_DERESET1 (1 << 5) > +#define SET_DBGRESET1 (1 << 13) > + > +#define CLR_CPURESET0 (1 << 0) > +#define CLR_DERESET0 (1 << 4) > +#define CLR_DBGRESET0 (1 << 12) > + > +#define CLR_CPURESET1 (1 << 1) > +#define CLR_DERESET1 (1 << 5) > +#define CLR_DBGRESET1 (1 << 13) > + > +#define CPU0_CLK_STP (1 << 8) > +#define CPU1_CLK_STP (1 << 9) > + > #endif /* CLK_RST_H */ > diff --git a/arch/arm/include/asm/arch-tegra2/pmc.h > b/arch/arm/include/asm/arch-tegra2/pmc.h > index 7ec9eeb..b1d47cd 100644 > --- a/arch/arm/include/asm/arch-tegra2/pmc.h > +++ b/arch/arm/include/asm/arch-tegra2/pmc.h > @@ -121,4 +121,12 @@ struct pmc_ctlr { > uint pmc_gate; /* _GATE_0, offset 15C */ > }; > > +#define CPU_PWRED 1 > +#define CPU_CLMP 1 > + > +#define PARTID_CP 0xFFFFFFF8 > +#define START_CP (1 << 8) > + > +#define CPUPWRREQ_OE (1 << 16) > + > #endif /* PMC_H */ > diff --git a/arch/arm/include/asm/arch-tegra2/scu.h > b/arch/arm/include/asm/arch-tegra2/scu.h > new file mode 100644 > index 0000000..d2faa6f > --- /dev/null > +++ b/arch/arm/include/asm/arch-tegra2/scu.h > @@ -0,0 +1,43 @@ > +/* > + * (C) Copyright 2010,2011 > + * NVIDIA Corporation <www.nvidia.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 _SCU_H_ > +#define _SCU_H_ > + > +/* ARM Snoop Control Unit (SCU) registers */ > +struct scu_ctlr { > + uint scu_ctrl; /* SCU Control Register, offset 00 */ > + uint scu_cfg; /* SCU Config Register, offset 04 */ > + uint scu_cpu_pwr_stat; /* SCU CPU Power Status Register, offset 08 */ > + uint scu_inv_all; /* SCU Invalidate All Register, offset 0C */ > + uint scu_reserved0[12]; /* reserved, offset 10-3C */ > + uint scu_filt_start; /* SCU Filtering Start Address Reg, offset 40 > */ > + uint scu_filt_end; /* SCU Filtering End Address Reg, offset 44 */ > + uint scu_reserved1[2]; /* reserved, offset 48-4C */ > + uint scu_acc_ctl; /* SCU Access Control Register, offset 50 */ > + uint scu_ns_acc_ctl; /* SCU Non-secure Access Cntrl Reg, offset 54 > */ > +}; > + > +#define SCU_ENABLE 1 > + > +#endif /* SCU_H */ > diff --git a/arch/arm/include/asm/arch-tegra2/tegra2.h > b/arch/arm/include/asm/arch-tegra2/tegra2.h > index 9001b68..5813cd9 100644 > --- a/arch/arm/include/asm/arch-tegra2/tegra2.h > +++ b/arch/arm/include/asm/arch-tegra2/tegra2.h > @@ -25,8 +25,12 @@ > #define _TEGRA2_H_ > > #define NV_PA_SDRAM_BASE 0x00000000 > +#define NV_PA_ARM_PERIPHBASE 0x50040000 > +#define NV_PA_PG_UP_BASE 0x60000000 > #define NV_PA_TMRUS_BASE 0x60005010 > #define NV_PA_CLK_RST_BASE 0x60006000 > +#define NV_PA_FLOW_BASE 0x60007000 > +#define NV_PA_EVP_BASE 0x6000F000 > #define NV_PA_APB_MISC_BASE 0x70000000 > #define NV_PA_APB_UARTA_BASE (NV_PA_APB_MISC_BASE + 0x6000) > #define NV_PA_APB_UARTB_BASE (NV_PA_APB_MISC_BASE + 0x6040) > @@ -34,6 +38,7 @@ > #define NV_PA_APB_UARTD_BASE (NV_PA_APB_MISC_BASE + 0x6300) > #define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400) > #define NV_PA_PMC_BASE 0x7000E400 > +#define NV_PA_CSITE_BASE 0x70040000 > > #define TEGRA2_SDRC_CS0 NV_PA_SDRAM_BASE > #define LOW_LEVEL_SRAM_STACK 0x4000FFFC > diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c > index b2c412c..078547b 100644 > --- a/board/nvidia/common/board.c > +++ b/board/nvidia/common/board.c > @@ -30,6 +30,7 @@ > #include <asm/arch/clk_rst.h> > #include <asm/arch/pinmux.h> > #include <asm/arch/uart.h> > +#include "board.h" > > DECLARE_GLOBAL_DATA_PTR; > > @@ -37,6 +38,15 @@ const struct tegra2_sysinfo sysinfo = { > CONFIG_TEGRA2_BOARD_STRING > }; > > +#ifdef CONFIG_BOARD_EARLY_INIT_F > +int board_early_init_f(void) > +{ > + debug("Board Early Init\n"); > + tegra2_start(); > + return 0; > +} > +#endif /* EARLY_INIT */ > + > /* > * Routine: timer_init > * Description: init the timestamp and lastinc value > diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h > new file mode 100644 > index 0000000..47c7885 > --- /dev/null > +++ b/board/nvidia/common/board.h > @@ -0,0 +1,29 @@ > +/* > + * (C) Copyright 2010,2011 > + * NVIDIA Corporation <www.nvidia.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 _BOARD_H_ > +#define _BOARD_H_ > + > +void tegra2_start(void); > + > +#endif /* BOARD_H */ > diff --git a/include/configs/harmony.h b/include/configs/harmony.h > index d004f31..34bd899 100644 > --- a/include/configs/harmony.h > +++ b/include/configs/harmony.h > @@ -46,4 +46,5 @@ > #define CONFIG_MACH_TYPE MACH_TYPE_HARMONY > #define CONFIG_SYS_BOARD_ODMDATA 0x300d8011 /* lp1, 1GB */ > > +#define CONFIG_BOARD_EARLY_INIT_F > #endif /* __CONFIG_H */ > diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h > index fd87560..b7b72bb 100644 > --- a/include/configs/seaboard.h > +++ b/include/configs/seaboard.h > @@ -40,4 +40,5 @@ > #define CONFIG_MACH_TYPE MACH_TYPE_TEGRA_SEABOARD > #define CONFIG_SYS_BOARD_ODMDATA 0x300d8011 /* lp1, 1GB */ > > +#define CONFIG_BOARD_EARLY_INIT_F > #endif /* __CONFIG_H */ > diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h > index 4f4374a..2924325 100644 > --- a/include/configs/tegra2-common.h > +++ b/include/configs/tegra2-common.h > @@ -33,6 +33,8 @@ > #define CONFIG_MACH_TEGRA_GENERIC /* which is a Tegra generic machine */ > #define CONFIG_L2_OFF /* No L2 cache */ > > +#define CONFIG_ENABLE_CORTEXA9 /* enable CPU (A9 complex) */ > + > #include <asm/arch/tegra2.h> /* get chip and board defs */ > > /* > -- > 1.7.4.1 > > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot