X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Farm926ejs%2Fmxs%2Fspl_boot.c;h=82fa55f6f65ea09dcf7ee48386214d5ada21d2f0;hp=ad66c57c5d396660a4428970de394da58ad6fe5d;hb=ef10f5faa7a37f6a7936ba840c4a308c924baff4;hpb=9fe2cfb43aab2225a8c970a69341534b2488da8c diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index ad66c57c5d..82fa55f6f6 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -4,23 +4,7 @@ * Copyright (C) 2011 Marek Vasut * on behalf of DENX Software Engineering GmbH * - * 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 + * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -29,60 +13,58 @@ #include #include #include +#include #include "mxs_init.h" -/* - * This delay function is intended to be used only in early stage of boot, where - * clock are not set up yet. The timer used here is reset on every boot and - * takes a few seconds to roll. The boot doesn't take that long, so to keep the - * code simple, it doesn't take rolling into consideration. - */ -void early_delay(int delay) -{ - struct mxs_digctl_regs *digctl_regs = - (struct mxs_digctl_regs *)MXS_DIGCTL_BASE; - - uint32_t st = readl(&digctl_regs->hw_digctl_microseconds); - st += delay; - while (st > readl(&digctl_regs->hw_digctl_microseconds)) - ; -} +DECLARE_GLOBAL_DATA_PTR; +static gd_t gdata __section(".data"); +#ifdef CONFIG_SPL_SERIAL_SUPPORT +static bd_t bdata __section(".data"); +#endif #define MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL) -const iomux_cfg_t iomux_boot[] = { - MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD, +static const iomux_cfg_t iomux_boot[] = { +#if defined(CONFIG_SOC_MX23) + MX23_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD, + MX23_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD, + MX23_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD, + MX23_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD, + MX23_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD, + MX23_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD, +#endif }; -uint8_t mxs_get_bootmode_index(void) +static uint8_t mxs_get_bootmode_index(void) { uint8_t bootmode = 0; int i; uint8_t masked; +#if defined(CONFIG_SOC_MX23) /* Setup IOMUX of bootmode pads to GPIO */ mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot)); /* Setup bootmode pins as GPIO input */ - gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0); - gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1); - gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2); - gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3); - gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4); - gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5); + gpio_direction_input(MX23_PAD_LCD_D00__GPIO_1_0); + gpio_direction_input(MX23_PAD_LCD_D01__GPIO_1_1); + gpio_direction_input(MX23_PAD_LCD_D02__GPIO_1_2); + gpio_direction_input(MX23_PAD_LCD_D03__GPIO_1_3); + gpio_direction_input(MX23_PAD_LCD_D05__GPIO_1_5); /* Read bootmode pads */ - bootmode |= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4) ? 1 : 0) << 4; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5; + bootmode |= (gpio_get_value(MX23_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0; + bootmode |= (gpio_get_value(MX23_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1; + bootmode |= (gpio_get_value(MX23_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2; + bootmode |= (gpio_get_value(MX23_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3; + bootmode |= (gpio_get_value(MX23_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5; +#elif defined(CONFIG_SOC_MX28) + /* The global boot mode will be detected by ROM code and its value + * is stored at the fixed address 0x00019BF0 in OCRAM. + */ +#define GLOBAL_BOOT_MODE_ADDR 0x00019BF0 + bootmode = __raw_readl(GLOBAL_BOOT_MODE_ADDR); +#endif for (i = 0; i < ARRAY_SIZE(mxs_boot_modes); i++) { masked = bootmode & mxs_boot_modes[i].boot_mask; @@ -93,14 +75,46 @@ uint8_t mxs_get_bootmode_index(void) return i; } -void mxs_common_spl_init(const iomux_cfg_t *iomux_setup, - const unsigned int iomux_size) +static void mxs_spl_fixup_vectors(void) +{ + /* + * Copy our vector table to 0x0, since due to HAB, we cannot + * be loaded to 0x0. We want to have working vectoring though, + * thus this fixup. Our vectoring table is PIC, so copying is + * fine. + */ + extern uint32_t _start; + + /* cppcheck-suppress nullPointer */ + memcpy(0x0, &_start, 0x60); +} + +static void mxs_spl_console_init(void) +{ +#ifdef CONFIG_SPL_SERIAL_SUPPORT + gd->bd = &bdata; + gd->baudrate = CONFIG_BAUDRATE; + serial_init(); + gd->have_console = 1; +#endif +} + +void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr, + const iomux_cfg_t *iomux_setup, + const unsigned int iomux_size) { struct mxs_spl_data *data = (struct mxs_spl_data *) ((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf); uint8_t bootmode = mxs_get_bootmode_index(); + gd = &gdata; + + mxs_spl_fixup_vectors(); mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size); + + mxs_spl_console_init(); + debug("SPL: Serial Console Initialised\n"); + mxs_power_init(); mxs_mem_init(); @@ -109,9 +123,14 @@ void mxs_common_spl_init(const iomux_cfg_t *iomux_setup, data->boot_mode_idx = bootmode; mxs_power_wait_pswitch(); + + if (mxs_boot_modes[data->boot_mode_idx].boot_pads == MXS_BM_JTAG) { + debug("SPL: Waiting for JTAG user\n"); + asm volatile ("x: b x"); + } } -/* Support aparatus */ +/* Support apparatus */ inline void board_init_f(unsigned long bootflag) { for (;;) @@ -123,14 +142,3 @@ inline void board_init_r(gd_t *id, ulong dest_addr) for (;;) ; } - -#ifndef CONFIG_SPL_SERIAL_SUPPORT -void serial_putc(const char c) {} -void serial_puts(const char *s) {} -#endif -void hang(void) __attribute__ ((noreturn)); -void hang(void) -{ - for (;;) - ; -}