mirror of
https://github.com/u-boot/u-boot.git
synced 2024-12-15 07:43:33 +08:00
fc8991c61c
cpu_eth_init is no longer called for dm enabled eth drivers, this was causing the sunxi gmac eth controller to no longer work in u-boot. This commit fixes this by calling the clock, reset and pinmux setup function from s_init() and enabling the phy power pin (if any) from board_init(). The enabling of phy power cannot be done from s_init because it uses dm and dm is not ready yet at this point. Note that the mdelay is dropped as the phy gets enabled much earlier now, so it is no longer needed. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Ian Campbell <ijc@hellion.org.uk> Tested-by: Karsten Merker <merker@debian.org> Tested-by: Michael Haas <haas@computerlinguist.org>
263 lines
8.1 KiB
C
263 lines
8.1 KiB
C
/*
|
|
* (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
|
|
*
|
|
* (C) Copyright 2007-2011
|
|
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
|
* Tom Cubie <tangliang@allwinnertech.com>
|
|
*
|
|
* Some init for sunxi platform.
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <mmc.h>
|
|
#include <i2c.h>
|
|
#include <serial.h>
|
|
#ifdef CONFIG_SPL_BUILD
|
|
#include <spl.h>
|
|
#endif
|
|
#include <asm/gpio.h>
|
|
#include <asm/io.h>
|
|
#include <asm/arch/clock.h>
|
|
#include <asm/arch/gpio.h>
|
|
#include <asm/arch/spl.h>
|
|
#include <asm/arch/sys_proto.h>
|
|
#include <asm/arch/timer.h>
|
|
#include <asm/arch/tzpc.h>
|
|
#include <asm/arch/mmc.h>
|
|
|
|
#include <linux/compiler.h>
|
|
|
|
struct fel_stash {
|
|
uint32_t sp;
|
|
uint32_t lr;
|
|
uint32_t cpsr;
|
|
uint32_t sctlr;
|
|
uint32_t vbar;
|
|
uint32_t cr;
|
|
};
|
|
|
|
struct fel_stash fel_stash __attribute__((section(".data")));
|
|
|
|
static int gpio_init(void)
|
|
{
|
|
#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
|
|
#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
|
|
/* disable GPB22,23 as uart0 tx,rx to avoid conflict */
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT);
|
|
#endif
|
|
#if defined(CONFIG_MACH_SUN8I)
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUN8I_GPF_UART0);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUN8I_GPF_UART0);
|
|
#else
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF_UART0);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF_UART0);
|
|
#endif
|
|
sunxi_gpio_set_pull(SUNXI_GPF(4), 1);
|
|
#elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I))
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB_UART0);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB_UART0);
|
|
sunxi_gpio_set_pull(SUNXI_GPB(23), SUNXI_GPIO_PULL_UP);
|
|
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN5I)
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB_UART0);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB_UART0);
|
|
sunxi_gpio_set_pull(SUNXI_GPB(20), SUNXI_GPIO_PULL_UP);
|
|
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN6I)
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPH(20), SUN6I_GPH_UART0);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPH(21), SUN6I_GPH_UART0);
|
|
sunxi_gpio_set_pull(SUNXI_GPH(21), SUNXI_GPIO_PULL_UP);
|
|
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A33)
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_A33_GPB_UART0);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_A33_GPB_UART0);
|
|
sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
|
|
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_H3)
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPA(4), SUN8I_H3_GPA_UART0);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPA(5), SUN8I_H3_GPA_UART0);
|
|
sunxi_gpio_set_pull(SUNXI_GPA(5), SUNXI_GPIO_PULL_UP);
|
|
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A83T)
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0);
|
|
sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP);
|
|
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN9I)
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPH(12), SUN9I_GPH_UART0);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPH(13), SUN9I_GPH_UART0);
|
|
sunxi_gpio_set_pull(SUNXI_GPH(13), SUNXI_GPIO_PULL_UP);
|
|
#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN5I)
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG_UART1);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG_UART1);
|
|
sunxi_gpio_set_pull(SUNXI_GPG(4), SUNXI_GPIO_PULL_UP);
|
|
#elif CONFIG_CONS_INDEX == 3 && defined(CONFIG_MACH_SUN8I)
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_GPB_UART2);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_GPB_UART2);
|
|
sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
|
|
#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I)
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
|
|
sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
|
|
sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
|
|
#else
|
|
#error Unsupported console port number. Please fix pin mux settings in board.c
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
int spl_board_load_image(void)
|
|
{
|
|
debug("Returning to FEL sp=%x, lr=%x\n", fel_stash.sp, fel_stash.lr);
|
|
return_to_fel(fel_stash.sp, fel_stash.lr);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void s_init(void)
|
|
{
|
|
/*
|
|
* Undocumented magic taken from boot0, without this DRAM
|
|
* access gets messed up (seems cache related).
|
|
* The boot0 sources describe this as: "config ema for cache sram"
|
|
*/
|
|
#if defined CONFIG_MACH_SUN6I
|
|
setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800);
|
|
#elif defined CONFIG_MACH_SUN8I_A23
|
|
uint version;
|
|
|
|
/* Unlock sram version info reg, read it, relock */
|
|
setbits_le32(SUNXI_SRAMC_BASE + 0x24, (1 << 15));
|
|
version = readl(SUNXI_SRAMC_BASE + 0x24);
|
|
clrbits_le32(SUNXI_SRAMC_BASE + 0x24, (1 << 15));
|
|
|
|
if ((version & 0xffff0000) == 0x16500000)
|
|
setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800);
|
|
else /* 0x1661 ? */
|
|
setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0xc0);
|
|
#endif
|
|
|
|
#if defined CONFIG_MACH_SUN6I || \
|
|
defined CONFIG_MACH_SUN7I || \
|
|
defined CONFIG_MACH_SUN8I
|
|
/* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
|
|
asm volatile(
|
|
"mrc p15, 0, r0, c1, c0, 1\n"
|
|
"orr r0, r0, #1 << 6\n"
|
|
"mcr p15, 0, r0, c1, c0, 1\n");
|
|
#endif
|
|
#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_H3
|
|
/* Enable non-secure access to some peripherals */
|
|
tzpc_init();
|
|
#endif
|
|
|
|
clock_init();
|
|
timer_init();
|
|
gpio_init();
|
|
i2c_init_board();
|
|
eth_init_board();
|
|
}
|
|
|
|
#ifdef CONFIG_SPL_BUILD
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
/* The sunxi internal brom will try to loader external bootloader
|
|
* from mmc0, nand flash, mmc2.
|
|
*/
|
|
u32 spl_boot_device(void)
|
|
{
|
|
__maybe_unused struct mmc *mmc0, *mmc1;
|
|
/*
|
|
* When booting from the SD card or NAND memory, the "eGON.BT0"
|
|
* signature is expected to be found in memory at the address 0x0004
|
|
* (see the "mksunxiboot" tool, which generates this header).
|
|
*
|
|
* When booting in the FEL mode over USB, this signature is patched in
|
|
* memory and replaced with something else by the 'fel' tool. This other
|
|
* signature is selected in such a way, that it can't be present in a
|
|
* valid bootable SD card image (because the BROM would refuse to
|
|
* execute the SPL in this case).
|
|
*
|
|
* This checks for the signature and if it is not found returns to
|
|
* the FEL code in the BROM to wait and receive the main u-boot
|
|
* binary over USB. If it is found, it determines where SPL was
|
|
* read from.
|
|
*/
|
|
if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
|
|
return BOOT_DEVICE_BOARD;
|
|
|
|
/* The BROM will try to boot from mmc0 first, so try that first. */
|
|
#ifdef CONFIG_MMC
|
|
mmc_initialize(gd->bd);
|
|
mmc0 = find_mmc_device(0);
|
|
if (sunxi_mmc_has_egon_boot_signature(mmc0))
|
|
return BOOT_DEVICE_MMC1;
|
|
#endif
|
|
|
|
/* Fallback to booting NAND if enabled. */
|
|
if (IS_ENABLED(CONFIG_SPL_NAND_SUPPORT))
|
|
return BOOT_DEVICE_NAND;
|
|
|
|
#ifdef CONFIG_MMC
|
|
if (CONFIG_MMC_SUNXI_SLOT_EXTRA == 2) {
|
|
mmc1 = find_mmc_device(1);
|
|
if (sunxi_mmc_has_egon_boot_signature(mmc1))
|
|
return BOOT_DEVICE_MMC2;
|
|
}
|
|
#endif
|
|
|
|
panic("Could not determine boot source\n");
|
|
return -1; /* Never reached */
|
|
}
|
|
|
|
/* No confirmation data available in SPL yet. Hardcode bootmode */
|
|
u32 spl_boot_mode(void)
|
|
{
|
|
return MMCSD_MODE_RAW;
|
|
}
|
|
|
|
void board_init_f(ulong dummy)
|
|
{
|
|
spl_init();
|
|
preloader_console_init();
|
|
|
|
#ifdef CONFIG_SPL_I2C_SUPPORT
|
|
/* Needed early by sunxi_board_init if PMU is enabled */
|
|
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
|
#endif
|
|
sunxi_board_init();
|
|
}
|
|
#endif
|
|
|
|
void reset_cpu(ulong addr)
|
|
{
|
|
#ifdef CONFIG_SUNXI_GEN_SUN4I
|
|
static const struct sunxi_wdog *wdog =
|
|
&((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
|
|
|
|
/* Set the watchdog for its shortest interval (.5s) and wait */
|
|
writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
|
|
writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl);
|
|
|
|
while (1) {
|
|
/* sun5i sometimes gets stuck without this */
|
|
writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
|
|
}
|
|
#endif
|
|
#ifdef CONFIG_SUNXI_GEN_SUN6I
|
|
static const struct sunxi_wdog *wdog =
|
|
((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
|
|
|
|
/* Set the watchdog for its shortest interval (.5s) and wait */
|
|
writel(WDT_CFG_RESET, &wdog->cfg);
|
|
writel(WDT_MODE_EN, &wdog->mode);
|
|
writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl);
|
|
while (1) { }
|
|
#endif
|
|
}
|
|
|
|
#ifndef CONFIG_SYS_DCACHE_OFF
|
|
void enable_caches(void)
|
|
{
|
|
/* Enable D-cache. I-cache is already enabled in start.S */
|
|
dcache_enable();
|
|
}
|
|
#endif
|