board.c 5.1 KB
Newer Older
1 2 3 4
/*
 *  (C) Copyright 2010,2011
 *  NVIDIA Corporation <www.nvidia.com>
 *
5
 * SPDX-License-Identifier:	GPL-2.0+
6 7 8 9
 */

#include <common.h>
#include <ns16550.h>
10
#include <linux/compiler.h>
11
#include <asm/io.h>
S
Simon Glass 已提交
12
#include <asm/arch/clock.h>
13
#ifdef CONFIG_LCD
14
#include <asm/arch/display.h>
15
#endif
L
Lucas Stach 已提交
16
#include <asm/arch/funcmux.h>
17
#include <asm/arch/pinmux.h>
18
#include <asm/arch/pmu.h>
19
#ifdef CONFIG_PWM_TEGRA
S
Simon Glass 已提交
20
#include <asm/arch/pwm.h>
21
#endif
22 23 24 25 26 27 28
#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>
29 30 31 32
#ifdef CONFIG_TEGRA_CLOCK_SCALING
#include <asm/arch/emc.h>
#endif
#ifdef CONFIG_USB_EHCI_TEGRA
33
#include <asm/arch-tegra/usb.h>
34
#include <usb.h>
35
#endif
36
#ifdef CONFIG_TEGRA_MMC
37
#include <asm/arch-tegra/tegra_mmc.h>
38 39
#include <asm/arch-tegra/mmc.h>
#endif
40
#include <i2c.h>
41
#include <spi.h>
42
#include "emc.h"
43 44 45

DECLARE_GLOBAL_DATA_PTR;

46 47
const struct tegra_sysinfo sysinfo = {
	CONFIG_TEGRA_BOARD_STRING
48 49
};

50 51 52 53 54 55
void __pinmux_init(void)
{
}

void pinmux_init(void) __attribute__((weak, alias("__pinmux_init")));

56 57 58 59 60 61
void __pin_mux_usb(void)
{
}

void pin_mux_usb(void) __attribute__((weak, alias("__pin_mux_usb")));

62 63 64 65 66 67
void __pin_mux_spi(void)
{
}

void pin_mux_spi(void) __attribute__((weak, alias("__pin_mux_spi")));

L
Lucas Stach 已提交
68 69 70 71 72 73 74
void __gpio_early_init_uart(void)
{
}

void gpio_early_init_uart(void)
__attribute__((weak, alias("__gpio_early_init_uart")));

75
#if defined(CONFIG_TEGRA_NAND)
L
Lucas Stach 已提交
76 77 78 79 80 81
void __pin_mux_nand(void)
{
	funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT);
}

void pin_mux_nand(void) __attribute__((weak, alias("__pin_mux_nand")));
82
#endif
L
Lucas Stach 已提交
83

M
Marc Dietrich 已提交
84 85 86 87 88 89
void __pin_mux_display(void)
{
}

void pin_mux_display(void) __attribute__((weak, alias("__pin_mux_display")));

90 91 92 93 94 95
/*
 * Routine: power_det_init
 * Description: turn off power detects
 */
static void power_det_init(void)
{
A
Allen Martin 已提交
96
#if defined(CONFIG_TEGRA20)
97
	struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
98 99 100 101 102 103 104

	/* turn off power detects */
	writel(0, &pmc->pmc_pwr_det_latch);
	writel(0, &pmc->pmc_pwr_det);
#endif
}

105 106 107 108 109 110
/*
 * Routine: board_init
 * Description: Early hardware init.
 */
int board_init(void)
{
111 112
	__maybe_unused int err;

113
	/* Do clocks and UART first so that printf() works */
S
Simon Glass 已提交
114 115 116
	clock_init();
	clock_verify();

117
#ifdef CONFIG_TEGRA_SPI
118
	pin_mux_spi();
S
Simon Glass 已提交
119
#endif
A
Allen Martin 已提交
120

S
Simon Glass 已提交
121 122 123
#ifdef CONFIG_PWM_TEGRA
	if (pwm_init(gd->fdt_blob))
		debug("%s: Failed to init pwm\n", __func__);
124 125
#endif
#ifdef CONFIG_LCD
M
Marc Dietrich 已提交
126
	pin_mux_display();
127
	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
128
#endif
129 130
	/* boot param addr */
	gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
131 132 133

	power_det_init();

134
#ifdef CONFIG_SYS_I2C_TEGRA
135 136 137 138
#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();
139 140 141
# ifdef CONFIG_TEGRA_PMU
	if (pmu_set_nominal())
		debug("Failed to select nominal voltages\n");
142 143 144 145 146 147
#  ifdef CONFIG_TEGRA_CLOCK_SCALING
	err = board_emc_init();
	if (err)
		debug("Memory controller init failed: %d\n", err);
#  endif
# endif /* CONFIG_TEGRA_PMU */
148
#endif /* CONFIG_SYS_I2C_TEGRA */
149

150 151
#ifdef CONFIG_USB_EHCI_TEGRA
	pin_mux_usb();
152
	usb_process_devicetree(gd->fdt_blob);
153
#endif
154

155 156 157
#ifdef CONFIG_LCD
	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
#endif
158

L
Lucas Stach 已提交
159 160 161 162
#ifdef CONFIG_TEGRA_NAND
	pin_mux_nand();
#endif

163
#ifdef CONFIG_TEGRA_LP0
164 165 166
	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
	warmboot_save_sdram_params();

167 168 169 170
	/* prepare the WB code to LP0 location */
	warmboot_prepare_code(TEGRA_LP0_ADDR, TEGRA_LP0_SIZE);
#endif

171 172
	return 0;
}
173

S
Simon Glass 已提交
174
#ifdef CONFIG_BOARD_EARLY_INIT_F
175 176 177 178 179 180
static void __gpio_early_init(void)
{
}

void gpio_early_init(void) __attribute__((weak, alias("__gpio_early_init")));

S
Simon Glass 已提交
181 182
int board_early_init_f(void)
{
183
	pinmux_init();
184
	board_init_uart_f();
S
Simon Glass 已提交
185 186

	/* Initialize periph GPIOs */
187
	gpio_early_init();
188
	gpio_early_init_uart();
189 190 191
#ifdef CONFIG_LCD
	tegra_lcd_early_init(gd->fdt_blob);
#endif
L
Lucas Stach 已提交
192

S
Simon Glass 已提交
193 194 195
	return 0;
}
#endif	/* EARLY_INIT */
196 197 198 199 200 201 202 203 204

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;
}
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

#if defined(CONFIG_TEGRA_MMC)
void __pin_mux_mmc(void)
{
}

void pin_mux_mmc(void) __attribute__((weak, alias("__pin_mux_mmc")));

/* 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;
}
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254

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 */