u-boot-brain/board/nvidia/common/board.c
Simon Glass 0521f98427 dm: tegra: Add platform data for the GPIO driver
Add platform data for the GPIO driver. It doesn't need to contain anything
since the GPIO driver will actually use information from the CONFIGs for
now. This merely serves to ensure that the GPIO driver is bound.

Signed-off-by: Simon Glass <sjg@chromium.org>
2014-11-21 08:14:07 +01:00

234 lines
4.8 KiB
C

/*
* (C) Copyright 2010,2011
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <ns16550.h>
#include <linux/compiler.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#ifdef CONFIG_LCD
#include <asm/arch/display.h>
#endif
#include <asm/arch/funcmux.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/pmu.h>
#ifdef CONFIG_PWM_TEGRA
#include <asm/arch/pwm.h>
#endif
#include <asm/arch/tegra.h>
#include <asm/arch-tegra/board.h>
#include <asm/arch-tegra/clk_rst.h>
#include <asm/arch-tegra/pmc.h>
#include <asm/arch-tegra/sys_proto.h>
#include <asm/arch-tegra/uart.h>
#include <asm/arch-tegra/warmboot.h>
#ifdef CONFIG_TEGRA_CLOCK_SCALING
#include <asm/arch/emc.h>
#endif
#ifdef CONFIG_USB_EHCI_TEGRA
#include <asm/arch-tegra/usb.h>
#include <usb.h>
#endif
#ifdef CONFIG_TEGRA_MMC
#include <asm/arch-tegra/tegra_mmc.h>
#include <asm/arch-tegra/mmc.h>
#endif
#include <i2c.h>
#include <spi.h>
#include "emc.h"
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_SPL_BUILD
/* TODO(sjg@chromium.org): Remove once SPL supports device tree */
U_BOOT_DEVICE(tegra_gpios) = {
"gpio_tegra"
};
#endif
const struct tegra_sysinfo sysinfo = {
CONFIG_TEGRA_BOARD_STRING
};
__weak void pinmux_init(void) {}
__weak void pin_mux_usb(void) {}
__weak void pin_mux_spi(void) {}
__weak void gpio_early_init_uart(void) {}
__weak void pin_mux_display(void) {}
#if defined(CONFIG_TEGRA_NAND)
__weak void pin_mux_nand(void)
{
funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT);
}
#endif
/*
* Routine: power_det_init
* Description: turn off power detects
*/
static void power_det_init(void)
{
#if defined(CONFIG_TEGRA20)
struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
/* turn off power detects */
writel(0, &pmc->pmc_pwr_det_latch);
writel(0, &pmc->pmc_pwr_det);
#endif
}
/*
* Routine: board_init
* Description: Early hardware init.
*/
int board_init(void)
{
__maybe_unused int err;
/* Do clocks and UART first so that printf() works */
clock_init();
clock_verify();
#ifdef CONFIG_TEGRA_SPI
pin_mux_spi();
#endif
#ifdef CONFIG_PWM_TEGRA
if (pwm_init(gd->fdt_blob))
debug("%s: Failed to init pwm\n", __func__);
#endif
#ifdef CONFIG_LCD
pin_mux_display();
tegra_lcd_check_next_stage(gd->fdt_blob, 0);
#endif
/* boot param addr */
gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
power_det_init();
#ifdef CONFIG_SYS_I2C_TEGRA
#ifndef CONFIG_SYS_I2C_INIT_BOARD
#error "You must define CONFIG_SYS_I2C_INIT_BOARD to use i2c on Nvidia boards"
#endif
i2c_init_board();
# ifdef CONFIG_TEGRA_PMU
if (pmu_set_nominal())
debug("Failed to select nominal voltages\n");
# ifdef CONFIG_TEGRA_CLOCK_SCALING
err = board_emc_init();
if (err)
debug("Memory controller init failed: %d\n", err);
# endif
# endif /* CONFIG_TEGRA_PMU */
#endif /* CONFIG_SYS_I2C_TEGRA */
#ifdef CONFIG_USB_EHCI_TEGRA
pin_mux_usb();
usb_process_devicetree(gd->fdt_blob);
#endif
#ifdef CONFIG_LCD
tegra_lcd_check_next_stage(gd->fdt_blob, 0);
#endif
#ifdef CONFIG_TEGRA_NAND
pin_mux_nand();
#endif
#ifdef CONFIG_TEGRA_LP0
/* save Sdram params to PMC 2, 4, and 24 for WB0 */
warmboot_save_sdram_params();
/* prepare the WB code to LP0 location */
warmboot_prepare_code(TEGRA_LP0_ADDR, TEGRA_LP0_SIZE);
#endif
return 0;
}
#ifdef CONFIG_BOARD_EARLY_INIT_F
static void __gpio_early_init(void)
{
}
void gpio_early_init(void) __attribute__((weak, alias("__gpio_early_init")));
int board_early_init_f(void)
{
pinmux_init();
board_init_uart_f();
/* Initialize periph GPIOs */
gpio_early_init();
gpio_early_init_uart();
#ifdef CONFIG_LCD
tegra_lcd_early_init(gd->fdt_blob);
#endif
return 0;
}
#endif /* EARLY_INIT */
int board_late_init(void)
{
#ifdef CONFIG_LCD
/* Make sure we finish initing the LCD */
tegra_lcd_check_next_stage(gd->fdt_blob, 1);
#endif
return 0;
}
#if defined(CONFIG_TEGRA_MMC)
__weak void pin_mux_mmc(void)
{
}
/* this is a weak define that we are overriding */
int board_mmc_init(bd_t *bd)
{
debug("%s called\n", __func__);
/* Enable muxes, etc. for SDMMC controllers */
pin_mux_mmc();
debug("%s: init MMC\n", __func__);
tegra_mmc_init();
return 0;
}
void pad_init_mmc(struct mmc_host *host)
{
#if defined(CONFIG_TEGRA30)
enum periph_id id = host->mmc_id;
u32 val;
debug("%s: sdmmc address = %08x, id = %d\n", __func__,
(unsigned int)host->reg, id);
/* Set the pad drive strength for SDMMC1 or 3 only */
if (id != PERIPH_ID_SDMMC1 && id != PERIPH_ID_SDMMC3) {
debug("%s: settings are only valid for SDMMC1/SDMMC3!\n",
__func__);
return;
}
val = readl(&host->reg->sdmemcmppadctl);
val &= 0xFFFFFFF0;
val |= MEMCOMP_PADCTRL_VREF;
writel(val, &host->reg->sdmemcmppadctl);
val = readl(&host->reg->autocalcfg);
val &= 0xFFFF0000;
val |= AUTO_CAL_PU_OFFSET | AUTO_CAL_PD_OFFSET | AUTO_CAL_ENABLED;
writel(val, &host->reg->autocalcfg);
#endif /* T30 */
}
#endif /* MMC */