diff options
author | Paul Kocialkowski <contact@paulk.fr> | 2014-09-06 22:31:49 +0200 |
---|---|---|
committer | Paul Kocialkowski <contact@paulk.fr> | 2014-09-06 22:33:42 +0200 |
commit | d04fab752bd789a479efeaa4310f8e4afd839cd0 (patch) | |
tree | 5c6531e0f863e4965dab3b4f590d61216624d876 /board | |
parent | ef50ce9e2fd41e06805b561e9e5a2f523bf76efb (diff) | |
download | x-loader-sniper-d04fab752bd789a479efeaa4310f8e4afd839cd0.tar.gz x-loader-sniper-d04fab752bd789a479efeaa4310f8e4afd839cd0.tar.bz2 x-loader-sniper-d04fab752bd789a479efeaa4310f8e4afd839cd0.zip |
LG Optimus Black (P970) supportmaster
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
Diffstat (limited to 'board')
-rw-r--r-- | board/sniper/Makefile | 51 | ||||
-rw-r--r-- | board/sniper/config.mk | 12 | ||||
-rwxr-xr-x | board/sniper/platform.S | 264 | ||||
-rw-r--r-- | board/sniper/sniper.c | 596 | ||||
-rw-r--r-- | board/sniper/x-load.lds | 54 |
5 files changed, 977 insertions, 0 deletions
diff --git a/board/sniper/Makefile b/board/sniper/Makefile new file mode 100644 index 0000000..6b02630 --- /dev/null +++ b/board/sniper/Makefile @@ -0,0 +1,51 @@ +# +# (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 = $(obj)lib$(BOARD).a + +COBJS := sniper.o +SOBJS := platform.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) $(SOBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/sniper/config.mk b/board/sniper/config.mk new file mode 100644 index 0000000..0a8ec71 --- /dev/null +++ b/board/sniper/config.mk @@ -0,0 +1,12 @@ +# (C) Copyright 2014 Paul Kocialkowski <contact@paulk.fr> +# +# During peripheral booting, X-Loader is loaded at 0x40200000 (SRAM start). +# However, stack is moved below X-Loader, so we need to relocate on SRAM too. +# +# Relocate to SRAM: +# TEXT_BASE = 0x40206000 +# +# Relocate to DDR/SDRAM: +# TEXT_BASE = 0x80e80000 + +TEXT_BASE = 0x80e80000 diff --git a/board/sniper/platform.S b/board/sniper/platform.S new file mode 100755 index 0000000..9d4d91e --- /dev/null +++ b/board/sniper/platform.S @@ -0,0 +1,264 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004-2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_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 */ + +/* **************************************************************************** + * NOTE: 3430 X-loader currently does not use this code. +* It could be removed its is kept for compatabily with u-boot. + * + * 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 */ +.word 50, 0, 0, 1 +/* 13MHz */ +.word 600, 12, 0, 1 +/* 19.2MHz */ +.word 125, 3, 0, 1 +/* 26MHz */ +.word 300, 12, 0, 1 +/* 38.4MHz */ +.word 125, 7, 0, 1 + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +.word 130, 2, 0, 1 +/* 13MHz */ +.word 40, 0, 0, 1 +/* 19.2MHz */ +.word 325, 11, 0, 1 +/* 26MHz */ +.word 20, 0, 0, 1 +/* 38.4MHz */ +.word 325, 23, 0, 1 + +.globl get_iva_dpll_param +get_iva_dpll_param: + adr r0, iva_dpll_param + mov pc, lr + +core_dpll_param: +/* 12MHz */ +.word 100, 2, 0, 1 +/* 13MHz */ +.word 400, 12, 0, 1 +/* 19.2MHz */ +.word 375, 17, 0, 1 +/* 26MHz */ +.word 200, 12, 0, 1 +/* 38.4MHz */ +.word 375, 35, 0, 1 + +.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: +/* Default to 96 MHz M2 */ +/* sys(kHz), m, n, clkin, sd, dco, m2, m3, m4, m5, m6, m2div */ +.word 12000, 360, 4, 0, 4, 2, 9, 16, 5, 4, 3, 1 +.word 13000, 432, 0, 1, 4, 2, 9, 16, 5, 4, 3, 1 +.word 19200, 360, 7, 0, 4, 2, 9, 16, 5, 4, 3, 1 +.word 26000, 432, 12, 0, 4, 2, 9, 16, 5, 4, 3, 1 +.word 38400, 360, 15, 0, 4, 2, 9, 16, 5, 4, 3, 1 +.word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr + diff --git a/board/sniper/sniper.c b/board/sniper/sniper.c new file mode 100644 index 0000000..037e260 --- /dev/null +++ b/board/sniper/sniper.c @@ -0,0 +1,596 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * (C) Copyright 2008-2010 LGE Inc. from omap3430labrador.c + * (C) Copyright 2014 Paul Kocialkowski <contact@paulk.fr> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <part.h> +#include <fat.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/gpio.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> +#include <asm/arch/mem.h> + +/* Used to index into DPLL parameter tables */ +struct dpll_param { + unsigned int m; + unsigned int n; + unsigned int fsel; + unsigned int m2; +}; + +typedef struct dpll_param dpll_param; + +struct dpll_per_param { + unsigned int sys_clk; + unsigned int m; + unsigned int n; + unsigned int clkin; + unsigned int sd; + unsigned int dco; + unsigned int m2; + unsigned int m3; + unsigned int m4; + unsigned int m5; + unsigned int m6; + unsigned int m2div; +}; + +typedef struct dpll_per_param dpll_per_param; + +/* Following functions are exported from lowlevel_init.S */ +extern dpll_param *get_mpu_dpll_param(); +extern dpll_param *get_iva_dpll_param(); +extern dpll_param *get_core_dpll_param(); +extern dpll_per_param *get_per_dpll_param(); + +#define __raw_readl(a) (*(volatile unsigned int *)(a)) +#define __raw_writel(v, a) (*(volatile unsigned int *)(a) = (v)) +#define __raw_readw(a) (*(volatile unsigned short *)(a)) +#define __raw_writew(v, a) (*(volatile unsigned short *)(a) = (v)) + +/******************************************************* + * 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)); +} + +void udelay (unsigned long usecs) { + delay(usecs); +} + +/***************************************** + * Routine: board_init + * Description: Early hardware init. + *****************************************/ +int board_init(void) +{ + return 0; +} + +/************************************************************* + * Routine: get_mem_type(void) - returns the kind of memory connected + * to GPMC that we are trying to boot form. Uses SYS BOOT settings. + *************************************************************/ +u32 get_mem_type(void) +{ + return GPMC_NONE; +} + +#ifdef CFG_SNIPER_DDR +/********************************************************************* + * config_sniper_ddr() - Init DDR + *********************************************************************/ +void config_sniper_ddr(void) +{ + /* check if its h/w or s/w reset for warm reset workaround */ + if (__raw_readl(PRM_RSTTST) & 0x2) { + /* Enable SDRC clock & wait SDRC idle status to access*/ + sr32(CM_ICLKEN1_CORE, 1, 1, 0x1); + wait_on_value(BIT1, 0, CM_IDLEST1_CORE, LDELAY); + } + else { + /* do a SDRC reset between types to clear regs */ + __raw_writel(SOFTRESET, SDRC_SYSCONFIG);/* reset sdrc */ + /* wait on reset */ + wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); + __raw_writel(0, SDRC_SYSCONFIG);/* clear soft reset */ + } + /* Clear reset sources */ + __raw_writel(0xfff, PRM_RSTTST); + + /* setup sdrc to ball mux */ + __raw_writel(SDP_SDRC_SHARING, SDRC_SHARING); + + /* Configure the first chip select */ + /* set mdcfg */ + __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_0); /* CS0 */ + __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_1); /* CS1 */ + + /* 2 * 128M = 256M for cs1 */ + __raw_writel(0x2, SDRC_CS_CFG); + + /* set timing */ + __raw_writel(SNIPER_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_0); /* CS0 */ + __raw_writel(SNIPER_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_0); /* CS0 */ + __raw_writel(SDP_SDRC_RFR_CTRL, SDRC_RFR_CTRL_0); + + __raw_writel(SNIPER_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_1); /* CS1 */ + __raw_writel(SNIPER_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_1); /* CS1 */ + __raw_writel(SDP_SDRC_RFR_CTRL, SDRC_RFR_CTRL_1); + + /* init sequence for mDDR/mSDR using manual commands (DDR is different) */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0); + delay(5000); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + + /* set mr0 */ + __raw_writel(SDP_SDRC_MR_0_DDR, SDRC_MR_0); + + /* drive strength weak */ + __raw_writel(0x20, 0x6D00008C); //SDRC_EMR2_0 + + /* init sequence for mDDR/mSDR using manual commands (DDR is different) */ + __raw_writel(CMD_NOP, SDRC_MANUAL_1); + delay(5000); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_1); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_1); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_1); + + /* set mr0 */ + __raw_writel(SDP_SDRC_MR_0_DDR, SDRC_MR_1); + + /* drive strength weak */ + __raw_writel(0x20, 0x6D0000BC); //SDRC_EMR2_1 + + __raw_writel(0x2, SDRC_CS_CFG); + + /* set up dllB-CS1 */ + __raw_writel(SDP_SDRC_DLLAB_CTRL, SDRC_DLLB_CTRL); + delay(0x2000); /* give time to lock */ + + /* set up dllA-CS0 */ + __raw_writel(SDP_SDRC_DLLAB_CTRL, SDRC_DLLA_CTRL); + delay(0x2000); /* give time to lock */ +} +#endif // CFG_SNIPER_DDR + +/************************************************************* + * 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, cdiv, val; + + val = __raw_readl(PRM_CLKSRC_CTRL); + + if (val & SYSCLKDIV_2) + cdiv = 2; + else + cdiv = 1; + + /* 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 */ + /* enabled out of reset */ + /* 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 */ + cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get start sys_clk count */ + while (__raw_readl(S32K_CR) < (start + 20)) ; /* wait for 40 cycles */ + cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + cdiff *= cdiv; + + /* 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; +} + +/****************************************************************************** + * prcm_init() - inits clocks for PRCM as defined in clocks.h + * -- called from SRAM, or Flash (using temp SRAM stack). + *****************************************************************************/ +void prcm_init(void) +{ + u32 osc_clk = 0, sys_clkin_sel; + dpll_per_param *dpll_per_param_p; + dpll_param *dpll_param_p; + u32 clk_index, sil_index; + + /* 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 */ + sr32(PRM_CLKSRC_CTRL, 6, 2, 1); /* input clock divider */ + clk_index = sys_clkin_sel; + + sr32(PRM_CLKSRC_CTRL, 0, 2, 0);/* Bypass mode: T2 inputs a square clock */ + + /* 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() == CPU_3XX_ES10); + + /* 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 + 1 * clk_index + sil_index; + /* 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 3430 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); + + /* Getting the base address to PER DPLL param table */ + dpll_per_param_p = (dpll_per_param *) get_per_dpll_param(); + /* Moving it to the right sysclk base */ + dpll_per_param_p = dpll_per_param_p + clk_index; + /* PER DPLL */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + sr32(CM_CLKSEL2_PLL, 8, 12, dpll_per_param_p->m); + sr32(CM_CLKSEL2_PLL, 0, 7, dpll_per_param_p->n); + sr32(PRM_CLKSRC_CTRL, 8, 1, dpll_per_param_p->clkin); + sr32(CM_CLKSEL2_PLL, 24, 7, dpll_per_param_p->sd); + sr32(CM_CLKSEL2_PLL, 21, 3, dpll_per_param_p->dco); + sr32(CM_CLKSEL3_PLL, 0, 5, dpll_per_param_p->m2); + sr32(CM_CLKSEL_DSS, 8, 6, dpll_per_param_p->m3); + sr32(CM_CLKSEL_DSS, 0, 6, dpll_per_param_p->m4); + sr32(CM_CLKSEL_CAM, 0, 6, dpll_per_param_p->m5); + sr32(CM_CLKSEL1_EMU, 24, 6, dpll_per_param_p->m6); + sr32(CM_CLKSEL_CORE, 12, 2, dpll_per_param_p->m2div); + + 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 + 1 * clk_index + sil_index; + + /* MPU DPLL (unlocked already) */ + 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_CLKSEL2_PLL_MPU, 0, 5, dpll_param_p->m2); /* Set M2 */ + + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); + + /* Set up GPTimers to sys_clk source only */ + sr32(CM_CLKSEL_PER, 0, 8, 0xff); + sr32(CM_CLKSEL_WKUP, 0, 1, 1); + + delay(5000); +} + +/********************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called at time when only stack is available. + **********************************************************/ + +void s_init(void) +{ + watchdog_init(); + try_unlock_memory(); + set_muxconf_regs(); + delay(100); + per_clocks_enable(); + prcm_init(); + config_sniper_ddr(); +} + +/******************************************************* + * Routine: misc_init_r + * Description: Init ethernet (done here so udelay works) + ********************************************************/ +int misc_init_r(void) +{ + unsigned char data; + + /* In order to boot from MMC1 (microsd card), the LP870 3.0V_MMC + * regulator has to be enabled. The LP870 is accessed through I2C3. + * + * Enabling 3.0V_MOTION and 1.8V_MOTION_VIO is required to power the + * sensors that are slaves on I2C3. When not powered, these sensors + * cause I2C3 SCK to stay low. */ + + i2c_set_bus_num(0); + + /* TWL4030 VAUX2: 3.0V_MOTION */ + + data = 0x20; + i2c_write(0x4b, 0x76, 1, &data, 1); + data = 0x9; + i2c_write(0x4b, 0x79, 1, &data, 1); + + /* TWL4030 VDAC: 1.8V_MOTION_VIO */ + + data = 0x20; + i2c_write(0x4b, 0x96, 1, &data, 1); + data = 0x2; + i2c_write(0x4b, 0x99, 1, &data, 1); + + /* LP870 CAM_SUBPM_EN */ + + omap_request_gpio(37); + omap_set_gpio_direction(37, 0); + omap_set_gpio_dataout(37, 1); + + i2c_set_bus_num(2); + + /* LP870 LDO1: 3.0V_MMC */ + + data = 0x1d; + i2c_write(0x7d, 0x1, 1, &data, 1); + data = 0x1; + i2c_write(0x7d, 0x8, 1, &data, 1); + + i2c_set_bus_num(0); + + /* TWL4030 VMMC2: 1.8V_MMC_EN */ + + data = 0x20; + i2c_write(0x4B, 0x86, 1, &data, 1); + data = 0xB; + i2c_write(0x4B, 0x89, 1, &data, 1); + + 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: dram_init + * Description: sets uboots idea of sdram size + **********************************************/ +int dram_init(void) +{ + return 0; +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: 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 + /* UART 3 Clocks */ + sr32(CM_FCLKEN_PER, 11, 1, 0x1); + sr32(CM_ICLKEN_PER, 11, 1, 0x1); + +#endif + +#ifdef CONFIG_DRIVER_OMAP34XX_I2C + /* 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); + + /* GPIO1 clocks */ + sr32(CM_FCLKEN_PER, 13, 1, 0x1); + sr32(CM_ICLKEN_PER, 13, 1, 0x1); + + /* MMC1 clocks */ + sr32(CM_FCLKEN1_CORE, 24, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 24, 1, 0x1); + + /* MMC2 clocks */ + sr32(CM_FCLKEN1_CORE, 25, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 25, 1, 0x1); + + delay(1000); +} + +#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_SNIPER()\ + MUX_VAL(CP(GPMC_A4), (IDIS | PTU | DIS | M4)) /* GPIO_37: CAM_SUBPM_EN */\ + MUX_VAL(CP(MMC1_CLK), (IEN | PTU | EN | M0)) /* MMC1_CLK */\ + MUX_VAL(CP(MMC1_CMD), (IEN | PTU | EN | M0)) /* MMC1_CMD */\ + MUX_VAL(CP(MMC1_DAT0), (IEN | PTU | EN | M0)) /* MMC1_DAT0 */\ + MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | EN | M0)) /* MMC1_DAT1 */\ + MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | EN | M0)) /* MMC1_DAT2 */\ + MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | EN | M0)) /* MMC1_DAT3 */\ + MUX_VAL(CP(MMC1_DAT4), (IEN | PTU | EN | M0)) /* MMC1_DAT4 */\ + MUX_VAL(CP(MMC1_DAT5), (IEN | PTU | EN | M0)) /* MMC1_DAT5 */\ + MUX_VAL(CP(MMC1_DAT6), (IEN | PTU | EN | M0)) /* MMC1_DAT6 */\ + MUX_VAL(CP(MMC1_DAT7), (IEN | PTU | EN | M0)) /* MMC1_DAT7 */\ + MUX_VAL(CP(MMC2_CLK), (IEN | PTU | EN | M0)) /* MMC2_CLK */\ + MUX_VAL(CP(MMC2_CMD), (IEN | PTU | EN | M0)) /* MMC2_CMD */\ + MUX_VAL(CP(MMC2_DAT0), (IEN | PTU | EN | M0)) /* MMC2_DAT0 */\ + MUX_VAL(CP(MMC2_DAT1), (IEN | PTU | EN | M0)) /* MMC2_DAT1 */\ + MUX_VAL(CP(MMC2_DAT2), (IEN | PTU | EN | M0)) /* MMC2_DAT2 */\ + MUX_VAL(CP(MMC2_DAT3), (IEN | PTU | EN | M0)) /* MMC2_DAT3 */\ + MUX_VAL(CP(MMC2_DAT4), (IEN | PTU | EN | M0)) /* MMC2_DAT4 */\ + MUX_VAL(CP(MMC2_DAT5), (IEN | PTU | EN | M0)) /* MMC2_DAT5 */\ + MUX_VAL(CP(MMC2_DAT6), (IEN | PTU | EN | M0)) /* MMC2_DAT6 */\ + MUX_VAL(CP(MMC2_DAT7), (IEN | PTU | EN | M0)) /* MMC2_DAT7 */\ + MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTD | EN | M0)) /* UART3_CTS_RCTX */\ + MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTD | DIS | M0)) /* UART3_RTS_SD */\ + MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0)) /* UART3_RX_IRRX */\ + MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0)) /* UART3_TX_IRTX */\ + MUX_VAL(CP(I2C1_SCL), (IEN | PTU | EN | M0)) /* I2C1_SCL */\ + MUX_VAL(CP(I2C1_SDA), (IEN | PTU | EN | M0)) /* I2C1_SDA */\ + MUX_VAL(CP(I2C3_SCL), (IEN | PTU | DIS | M0)) /* I2C3_SCL */\ + MUX_VAL(CP(I2C3_SDA), (IEN | PTU | DIS | M0)) /* I2C3_SDA */ + +/********************************************************** + * Routine: set_muxconf_regs + * Description: Setting up the configuration Mux registers + * specific to the hardware. Many pins need + * to be moved from protect to primary mode. + *********************************************************/ +void set_muxconf_regs(void) +{ + MUX_SNIPER(); +} + +/********************************************************** + * Routine: nand+_init + * Description: Set up nand for nand and jffs2 commands + *********************************************************/ + +int nand_init(void) +{ + return 0; +} + +/* optionally do something like blinking LED */ +void board_hang(void) +{ + return; +} + +/****************************************************************************** + * Dummy function to handle errors for EABI incompatibility + *****************************************************************************/ +void raise(void) +{ +} + +/****************************************************************************** + * Dummy function to handle errors for EABI incompatibility + *****************************************************************************/ +void abort(void) +{ +} diff --git a/board/sniper/x-load.lds b/board/sniper/x-load.lds new file mode 100644 index 0000000..5f352d3 --- /dev/null +++ b/board/sniper/x-load.lds @@ -0,0 +1,54 @@ +/* + * November 2006 - Changed to support 3430sdp device + * Copyright (c) 2004-2006 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@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 + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/omap3/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} |