diff options
Diffstat (limited to 'arch/arm/cpu/armv7')
21 files changed, 341 insertions, 160 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile index 6beafbbece..7768912603 100644 --- a/arch/arm/cpu/armv7/am33xx/Makefile +++ b/arch/arm/cpu/armv7/am33xx/Makefile @@ -16,8 +16,6 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o -SOBJS := lowlevel_init.o - COBJS += clock.o COBJS += sys_info.o COBJS += ddr.o diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index 2d6d359e5f..d64ae6936c 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -19,19 +19,31 @@ #include <common.h> #include <asm/arch/cpu.h> #include <asm/arch/hardware.h> +#include <asm/arch/omap.h> #include <asm/arch/ddr_defs.h> #include <asm/arch/clock.h> +#include <asm/arch/mmc_host_def.h> +#include <asm/arch/common_def.h> #include <asm/io.h> +#include <asm/omap_common.h> DECLARE_GLOBAL_DATA_PTR; struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; -struct timer_reg *timerreg = (struct timer_reg *)DM_TIMER2_BASE; +struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE; +struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE; + +/* UART Defines */ +#ifdef CONFIG_SPL_BUILD +#define UART_RESET (0x1 << 1) +#define UART_CLK_RUNNING_MASK 0x1 +#define UART_SMART_IDLE_EN (0x1 << 0x3) +#endif /* * early system init of muxing and clocks. */ -void s_init(u32 in_ddr) +void s_init(void) { /* WDT1 is already running when the bootloader gets control * Disable it to avoid "random" resets @@ -43,24 +55,62 @@ void s_init(u32 in_ddr) while (readl(&wdtimer->wdtwwps) != 0x0) ; +#ifdef CONFIG_SPL_BUILD /* Setup the PLLs and the clocks for the peripherals */ -#ifdef CONFIG_SETUP_PLL pll_init(); + + /* UART softreset */ + u32 regVal; + + enable_uart0_pin_mux(); + + regVal = readl(&uart_base->uartsyscfg); + regVal |= UART_RESET; + writel(regVal, &uart_base->uartsyscfg); + while ((readl(&uart_base->uartsyssts) & + UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK) + ; + + /* Disable smart idle */ + regVal = readl(&uart_base->uartsyscfg); + regVal |= UART_SMART_IDLE_EN; + writel(regVal, &uart_base->uartsyscfg); + + /* Initialize the Timer */ + init_timer(); + + preloader_console_init(); + + config_ddr(); #endif - if (!in_ddr) - config_ddr(); + + /* Enable MMC0 */ + enable_mmc0_pin_mux(); } /* Initialize timer */ void init_timer(void) { /* Reset the Timer */ - writel(0x2, (&timerreg->tsicrreg)); + writel(0x2, (&timer_base->tscir)); /* Wait until the reset is done */ - while (readl(&timerreg->tiocpcfgreg) & 1) + while (readl(&timer_base->tiocp_cfg) & 1) ; /* Start the Timer */ - writel(0x1, (&timerreg->tclrreg)); + writel(0x1, (&timer_base->tclr)); +} + +#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD) +int board_mmc_init(bd_t *bis) +{ + return omap_mmc_init(0); +} +#endif + +void setup_clocks_for_console(void) +{ + /* Not yet implemented */ + return; } diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c index 4ca6c45349..98cfd93814 100644 --- a/arch/arm/cpu/armv7/am33xx/clock.c +++ b/arch/arm/cpu/armv7/am33xx/clock.c @@ -101,10 +101,18 @@ static void enable_per_clocks(void) while (readl(&cmper->timer2clkctrl) != PRCM_MOD_EN) ; + /* Select the Master osc 24 MHZ as Timer2 clock source */ + writel(0x1, &cmdpll->clktimer2clk); + /* UART0 */ writel(PRCM_MOD_EN, &cmwkup->wkup_uart0ctrl); while (readl(&cmwkup->wkup_uart0ctrl) != PRCM_MOD_EN) ; + + /* MMC0*/ + writel(PRCM_MOD_EN, &cmper->mmc0clkctrl); + while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN) + ; } static void mpu_pll_config(void) diff --git a/arch/arm/cpu/armv7/am33xx/config.mk b/arch/arm/cpu/armv7/am33xx/config.mk new file mode 100644 index 0000000000..5750bbdcb6 --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/config.mk @@ -0,0 +1,18 @@ +# +# 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. +# +ifdef CONFIG_SPL_BUILD +ALL-y += $(OBJTREE)/MLO +else +ALL-y += $(obj)u-boot.img +endif diff --git a/arch/arm/cpu/armv7/am33xx/emif4.c b/arch/arm/cpu/armv7/am33xx/emif4.c index 1318365a4a..2f4164df82 100644 --- a/arch/arm/cpu/armv7/am33xx/emif4.c +++ b/arch/arm/cpu/armv7/am33xx/emif4.c @@ -46,7 +46,7 @@ void dram_init_banksize(void) } -#ifdef CONFIG_AM335X_CONFIG_DDR +#ifdef CONFIG_SPL_BUILD static void data_macro_config(int dataMacroNum) { struct ddr_data data; diff --git a/arch/arm/cpu/armv7/am33xx/lowlevel_init.S b/arch/arm/cpu/armv7/am33xx/lowlevel_init.S deleted file mode 100644 index 17c962ff71..0000000000 --- a/arch/arm/cpu/armv7/am33xx/lowlevel_init.S +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c index b143535972..fa3a124807 100644 --- a/arch/arm/cpu/armv7/mx6/clock.c +++ b/arch/arm/cpu/armv7/mx6/clock.c @@ -285,6 +285,11 @@ u32 imx_get_uartclk(void) return get_uart_clk(); } +u32 imx_get_fecclk(void) +{ + return decode_pll(PLL_ENET, CONFIG_SYS_MX6_HCLK); +} + unsigned int mxc_get_clock(enum mxc_clock clk) { switch (clk) { diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index dff5e4efd7..2ac74b5945 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -40,18 +40,35 @@ u32 get_cpu_rev(void) #ifdef CONFIG_ARCH_CPU_INIT void init_aips(void) { - u32 reg = AIPS1_BASE_ADDR; + struct aipstz_regs *aips1, *aips2; + + aips1 = (struct aipstz_regs *)AIPS1_BASE_ADDR; + aips2 = (struct aipstz_regs *)AIPS2_BASE_ADDR; /* * Set all MPROTx to be non-bufferable, trusted for R/W, * not forced to user-mode. */ - writel(0x77777777, reg + 0x00); - writel(0x77777777, reg + 0x04); + writel(0x77777777, &aips1->mprot0); + writel(0x77777777, &aips1->mprot1); + writel(0x77777777, &aips2->mprot0); + writel(0x77777777, &aips2->mprot1); - reg = AIPS2_BASE_ADDR; - writel(0x77777777, reg + 0x00); - writel(0x77777777, reg + 0x04); + /* + * Set all OPACRx to be non-bufferable, not require + * supervisor privilege level for access,allow for + * write access and untrusted master access. + */ + writel(0x00000000, &aips1->opacr0); + writel(0x00000000, &aips1->opacr1); + writel(0x00000000, &aips1->opacr2); + writel(0x00000000, &aips1->opacr3); + writel(0x00000000, &aips1->opacr4); + writel(0x00000000, &aips2->opacr0); + writel(0x00000000, &aips2->opacr1); + writel(0x00000000, &aips2->opacr2); + writel(0x00000000, &aips2->opacr3); + writel(0x00000000, &aips2->opacr4); } int arch_cpu_init(void) @@ -63,20 +80,22 @@ int arch_cpu_init(void) #endif #if defined(CONFIG_FEC_MXC) -void imx_get_mac_from_fuse(unsigned char *mac) +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) { struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; struct fuse_bank *bank = &iim->bank[4]; struct fuse_bank4_regs *fuse = (struct fuse_bank4_regs *)bank->fuse_regs; - u32 mac_lo = readl(&fuse->mac_addr_low); - u32 mac_hi = readl(&fuse->mac_addr_high); - - *(u32 *)mac = mac_lo; + u32 value = readl(&fuse->mac_addr_high); + mac[0] = (value >> 8); + mac[1] = value ; - mac[4] = mac_hi & 0xff; - mac[5] = (mac_hi >> 8) & 0xff; + value = readl(&fuse->mac_addr_low); + mac[2] = value >> 24 ; + mac[3] = value >> 16 ; + mac[4] = value >> 8 ; + mac[5] = value ; } #endif diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index a684611265..3f7a0b25f0 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -37,6 +37,10 @@ ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) COBJS += hwinit-common.o COBJS += clocks-common.o COBJS += emif-common.o +endif + +ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) +COBJS += boot-common.o SOBJS += lowlevel_init.o endif diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c new file mode 100644 index 0000000000..f211f7670c --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -0,0 +1,49 @@ +/* + * boot-common.c + * + * Common bootmode functions for omap 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/omap_common.h> +#include <asm/arch/omap.h> + +/* + * This is used to verify if the configuration header + * was executed by rom code prior to control of transfer + * to the bootloader. SPL is responsible for saving and + * passing the boot_params pointer to the u-boot. + */ +struct omap_boot_parameters boot_params __attribute__ ((section(".data"))); + +#ifdef CONFIG_SPL_BUILD +/* + * We use static variables because global data is not ready yet. + * Initialized data is available in SPL right from the beginning. + * We would not typically need to save these parameters in regular + * U-Boot. This is needed only in SPL at the moment. + */ +u32 omap_bootmode = MMCSD_MODE_FAT; + +u32 omap_boot_device(void) +{ + return (u32) (boot_params.omap_bootdevice); +} + +u32 omap_boot_mode(void) +{ + return omap_bootmode; +} +#endif diff --git a/arch/arm/cpu/armv7/omap-common/gpio.c b/arch/arm/cpu/armv7/omap-common/gpio.c index 75a02da877..fc89f2a42b 100644 --- a/arch/arm/cpu/armv7/omap-common/gpio.c +++ b/arch/arm/cpu/armv7/omap-common/gpio.c @@ -36,7 +36,7 @@ * published by the Free Software Foundation. */ #include <common.h> -#include <asm/arch/gpio.h> +#include <asm/gpio.h> #include <asm/io.h> #include <asm/errno.h> @@ -56,17 +56,17 @@ static inline int get_gpio_index(int gpio) static inline int gpio_valid(int gpio) { if (gpio < 0) - return -EINVAL; + return -1; if (gpio < 192) return 0; - return -EINVAL; + return -1; } static int check_gpio(int gpio) { if (gpio_valid(gpio) < 0) { printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); - return -EINVAL; + return -1; } return 0; } @@ -106,7 +106,7 @@ static int _get_gpio_direction(const struct gpio_bank *bank, int gpio) reg += OMAP_GPIO_OE; break; default: - return -EINVAL; + return -1; } v = __raw_readl(reg); @@ -142,27 +142,29 @@ static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio, /** * Set value of the specified gpio */ -void gpio_set_value(int gpio, int value) +int gpio_set_value(unsigned gpio, int value) { const struct gpio_bank *bank; if (check_gpio(gpio) < 0) - return; + return -1; bank = get_gpio_bank(gpio); _set_gpio_dataout(bank, get_gpio_index(gpio), value); + + return 0; } /** * Get value of the specified gpio */ -int gpio_get_value(int gpio) +int gpio_get_value(unsigned gpio) { const struct gpio_bank *bank; void *reg; int input; if (check_gpio(gpio) < 0) - return -EINVAL; + return -1; bank = get_gpio_bank(gpio); reg = bank->base; switch (bank->method) { @@ -176,11 +178,11 @@ int gpio_get_value(int gpio) reg += OMAP_GPIO_DATAOUT; break; default: - return -EINVAL; + return -1; } break; default: - return -EINVAL; + return -1; } return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; @@ -194,7 +196,7 @@ int gpio_direction_input(unsigned gpio) const struct gpio_bank *bank; if (check_gpio(gpio) < 0) - return -EINVAL; + return -1; bank = get_gpio_bank(gpio); _set_gpio_direction(bank, get_gpio_index(gpio), 1); @@ -210,7 +212,7 @@ int gpio_direction_output(unsigned gpio, int value) const struct gpio_bank *bank; if (check_gpio(gpio) < 0) - return -EINVAL; + return -1; bank = get_gpio_bank(gpio); _set_gpio_dataout(bank, get_gpio_index(gpio), value); @@ -224,10 +226,10 @@ int gpio_direction_output(unsigned gpio, int value) * * NOTE: Argument 'label' is unused. */ -int gpio_request(int gpio, const char *label) +int gpio_request(unsigned gpio, const char *label) { if (check_gpio(gpio) < 0) - return -EINVAL; + return -1; return 0; } @@ -235,6 +237,7 @@ int gpio_request(int gpio, const char *label) /** * Reset and free the gpio after using it. */ -void gpio_free(unsigned gpio) +int gpio_free(unsigned gpio) { + return 0; } diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index f65705db12..49cdc3936e 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -35,34 +35,6 @@ DECLARE_GLOBAL_DATA_PTR; -/* - * This is used to verify if the configuration header - * was executed by rom code prior to control of transfer - * to the bootloader. SPL is responsible for saving and - * passing the boot_params pointer to the u-boot. - */ -struct omap_boot_parameters boot_params __attribute__ ((section(".data"))); - -#ifdef CONFIG_SPL_BUILD -/* - * We use static variables because global data is not ready yet. - * Initialized data is available in SPL right from the beginning. - * We would not typically need to save these parameters in regular - * U-Boot. This is needed only in SPL at the moment. - */ -u32 omap_bootmode = MMCSD_MODE_FAT; - -u32 omap_boot_device(void) -{ - return (u32) (boot_params.omap_bootdevice); -} - -u32 omap_boot_mode(void) -{ - return omap_bootmode; -} -#endif - void do_set_mux(u32 base, struct pad_conf_entry const *array, int size) { int i; @@ -104,14 +76,14 @@ u32 cortex_rev(void) return rev; } -void omap_rev_string(char *omap_rev_string) +void omap_rev_string(void) { u32 omap_rev = omap_revision(); u32 omap_variant = (omap_rev & 0xFFFF0000) >> 16; u32 major_rev = (omap_rev & 0x00000F00) >> 8; u32 minor_rev = (omap_rev & 0x000000F0) >> 4; - sprintf(omap_rev_string, "OMAP%x ES%x.%x", omap_variant, major_rev, + printf("OMAP%x ES%x.%x\n", omap_variant, major_rev, minor_rev); } @@ -251,10 +223,8 @@ u32 get_device_type(void) */ int print_cpuinfo(void) { - char rev_string_buffer[50]; - - omap_rev_string(rev_string_buffer); - printf("CPU : %s\n", rev_string_buffer); + puts("CPU : "); + omap_rev_string(); return 0; } diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 9c35a09038..9c1f7e3eda 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <i2c.h> #include <image.h> #include <malloc.h> +#include <linux/compiler.h> DECLARE_GLOBAL_DATA_PTR; @@ -115,8 +116,6 @@ void board_init_r(gd_t *id, ulong dummy) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, CONFIG_SYS_SPL_MALLOC_SIZE); - timer_init(); - #ifdef CONFIG_SPL_BOARD_INIT spl_board_init(); #endif @@ -156,7 +155,6 @@ void board_init_r(gd_t *id, ulong dummy) void preloader_console_init(void) { const char *u_boot_rev = U_BOOT_VERSION; - char rev_string_buffer[50]; gd = &gdata; gd->bd = &bdata; @@ -172,14 +170,10 @@ void preloader_console_init(void) printf("\nU-Boot SPL %s (%s - %s)\n", u_boot_rev, U_BOOT_DATE, U_BOOT_TIME); - omap_rev_string(rev_string_buffer); - printf("Texas Instruments %s\n", rev_string_buffer); + omap_rev_string(); } -void __omap_rev_string(char *str) +void __weak omap_rev_string() { - sprintf(str, "Revision detection unimplemented"); + printf("Texas Instruments Revision detection unimplemented\n"); } - -void omap_rev_string(char *str) - __attribute__((weak, alias("__omap_rev_string"))); diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 1f33c6398c..871aa37df8 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -230,6 +230,8 @@ void s_init(void) #ifdef CONFIG_SPL_BUILD preloader_console_init(); + + timer_init(); #endif if (!in_sdram) diff --git a/arch/arm/cpu/armv7/omap3/sys_info.c b/arch/arm/cpu/armv7/omap3/sys_info.c index 22887aec05..3c80113502 100644 --- a/arch/arm/cpu/armv7/omap3/sys_info.c +++ b/arch/arm/cpu/armv7/omap3/sys_info.c @@ -30,6 +30,7 @@ #include <asm/arch/mem.h> /* get mem tables */ #include <asm/arch/sys_proto.h> #include <i2c.h> +#include <linux/compiler.h> extern omap3_sysinfo sysinfo; static struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE; @@ -197,7 +198,7 @@ u32 get_gpmc0_width(void) * 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) +u32 __weak get_board_rev(void) { return 0x20; } diff --git a/arch/arm/cpu/armv7/omap4/hwinit.c b/arch/arm/cpu/armv7/omap4/hwinit.c index 37a86b4c2f..91f83205ed 100644 --- a/arch/arm/cpu/armv7/omap4/hwinit.c +++ b/arch/arm/cpu/armv7/omap4/hwinit.c @@ -110,10 +110,10 @@ void do_io_settings(void) * i. unconditionally for all 4430 * ii. only if un-trimmed for 4460 */ - if ((omap4_rev < OMAP4460_ES1_0) || !readl(&ctrl->control_efuse_1)) + if (!readl(&ctrl->control_efuse_1)) writel(CONTROL_EFUSE_1_OVERRIDE, &ctrl->control_efuse_1); - if (!readl(&ctrl->control_efuse_2)) + if ((omap4_rev < OMAP4460_ES1_0) || !readl(&ctrl->control_efuse_2)) writel(CONTROL_EFUSE_2_OVERRIDE, &ctrl->control_efuse_2); } #endif diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile index 955c3b6dc4..f668a818fb 100644 --- a/arch/arm/cpu/armv7/tegra2/Makefile +++ b/arch/arm/cpu/armv7/tegra2/Makefile @@ -33,7 +33,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o -COBJS := ap20.o board.o clock.o pinmux.o sys_info.o timer.o +COBJS := ap20.o board.o clock.o funcmux.o pinmux.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/board.c b/arch/arm/cpu/armv7/tegra2/board.c index 59dce8f8de..ea06570bfa 100644 --- a/arch/arm/cpu/armv7/tegra2/board.c +++ b/arch/arm/cpu/armv7/tegra2/board.c @@ -24,12 +24,22 @@ #include <common.h> #include <asm/io.h> #include "ap20.h" +#include <asm/arch/clock.h> +#include <asm/arch/funcmux.h> #include <asm/arch/sys_proto.h> #include <asm/arch/tegra2.h> #include <asm/arch/pmc.h> DECLARE_GLOBAL_DATA_PTR; +enum { + /* UARTs which we can enable */ + UARTA = 1 << 0, + UARTB = 1 << 1, + UARTD = 1 << 3, + UART_COUNT = 4, +}; + /* * Boot ROM initializes the odmdata in APBDEV_PMC_SCRATCH20_0, * so we are using this value to identify memory size. @@ -80,6 +90,54 @@ int arch_cpu_init(void) { /* Fire up the Cortex A9 */ tegra2_start(); + + /* We didn't do this init in start.S, so do it now */ + cpu_init_cp15(); + + /* Initialize essential common plls */ + clock_early_init(); + return 0; } #endif + +/** + * Set up the specified uarts + * + * @param uarts_ids Mask containing UARTs to init (UARTx) + */ +static void setup_uarts(int uart_ids) +{ + static enum periph_id id_for_uart[] = { + PERIPH_ID_UART1, + PERIPH_ID_UART2, + PERIPH_ID_UART3, + PERIPH_ID_UART4, + }; + size_t i; + + for (i = 0; i < UART_COUNT; i++) { + if (uart_ids & (1 << i)) { + enum periph_id id = id_for_uart[i]; + + funcmux_select(id, 0); + clock_ll_start_uart(id); + } + } +} + +void board_init_uart_f(void) +{ + int uart_ids = 0; /* bit mask of which UART ids to enable */ + +#ifdef CONFIG_TEGRA2_ENABLE_UARTA + uart_ids |= UARTA; +#endif +#ifdef CONFIG_TEGRA2_ENABLE_UARTB + uart_ids |= UARTB; +#endif +#ifdef CONFIG_TEGRA2_ENABLE_UARTD + uart_ids |= UARTD; +#endif + setup_uarts(uart_ids); +} diff --git a/arch/arm/cpu/armv7/tegra2/clock.c b/arch/arm/cpu/armv7/tegra2/clock.c index 03ac1e3ed0..11d2346d83 100644 --- a/arch/arm/cpu/armv7/tegra2/clock.c +++ b/arch/arm/cpu/armv7/tegra2/clock.c @@ -904,6 +904,20 @@ static int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) return 0; } +void clock_ll_start_uart(enum periph_id periph_id) +{ + /* Assert UART reset and enable clock */ + reset_set_enable(periph_id, 1); + clock_enable(periph_id); + clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */ + + /* wait for 2us */ + udelay(2); + + /* De-assert reset to UART */ + reset_set_enable(periph_id, 0); +} + int clock_verify(void) { struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH); diff --git a/arch/arm/cpu/armv7/tegra2/config.mk b/arch/arm/cpu/armv7/tegra2/config.mk index 8f9bdc9ff0..2303dba079 100644 --- a/arch/arm/cpu/armv7/tegra2/config.mk +++ b/arch/arm/cpu/armv7/tegra2/config.mk @@ -29,3 +29,5 @@ ifdef CONFIG_TEGRA2 CFLAGS_arch/arm/lib/board.o += -march=armv4t endif + +USE_PRIVATE_LIBGCC = yes diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/armv7/tegra2/funcmux.c new file mode 100644 index 0000000000..0878f51110 --- /dev/null +++ b/arch/arm/cpu/armv7/tegra2/funcmux.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * 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 + */ + +/* Tegra2 high-level function multiplexing */ +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/arch/pinmux.h> + +int funcmux_select(enum periph_id id, int config) +{ + if (config != 0) { + debug("%s: invalid config %d for periph_id %d", __func__, + config, id); + return -1; + } + switch (id) { + case PERIPH_ID_UART1: + pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PINGRP_IRRX); + pinmux_tristate_disable(PINGRP_IRTX); + break; + + case PERIPH_ID_UART2: + pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA); + pinmux_tristate_disable(PINGRP_UAD); + break; + + case PERIPH_ID_UART4: + pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD); + pinmux_tristate_disable(PINGRP_GMC); + break; + + default: + debug("%s: invalid periph_id %d", __func__, id); + return -1; + } + + return 0; +} |