board.c 5.21 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>
12
#include <asm/arch/clock.h>
13
#ifdef CONFIG_LCD
14
#include <asm/arch/display.h>
15
#endif
16
#include <asm/arch/funcmux.h>
17
#include <asm/arch/pinmux.h>
18
#include <asm/arch/pmu.h>
19
#ifdef CONFIG_PWM_TEGRA
Simon Glass's avatar
Simon Glass committed
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 <asm/arch/usb.h>
35
#include <usb.h>
36
#endif
37
#ifdef CONFIG_TEGRA_MMC
38
#include <asm/arch-tegra/tegra_mmc.h>
39 40
#include <asm/arch-tegra/mmc.h>
#endif
41
#include <i2c.h>
42
#include <spi.h>
43
#include "emc.h"
44 45 46

DECLARE_GLOBAL_DATA_PTR;

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

51
#ifndef CONFIG_SPL_BUILD
52 53 54 55 56 57 58 59
/*
 * Routine: timer_init
 * Description: init the timestamp and lastinc value
 */
int timer_init(void)
{
	return 0;
}
60
#endif
61

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

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

68 69 70 71 72 73
void __pin_mux_spi(void)
{
}

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

74 75 76 77 78 79 80
void __gpio_early_init_uart(void)
{
}

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

81 82 83 84 85 86 87
void __pin_mux_nand(void)
{
	funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT);
}

void pin_mux_nand(void) __attribute__((weak, alias("__pin_mux_nand")));

88 89 90 91 92 93
void __pin_mux_display(void)
{
}

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

94 95 96 97 98 99
/*
 * Routine: power_det_init
 * Description: turn off power detects
 */
static void power_det_init(void)
{
100
#if defined(CONFIG_TEGRA20)
101
	struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
102 103 104 105 106 107 108

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

109 110 111 112 113 114
/*
 * Routine: board_init
 * Description: Early hardware init.
 */
int board_init(void)
{
115 116
	__maybe_unused int err;

117
	/* Do clocks and UART first so that printf() works */
118 119 120
	clock_init();
	clock_verify();

121
#ifdef CONFIG_FDT_SPI
122
	pin_mux_spi();
123
	spi_init();
Simon Glass's avatar
Simon Glass committed
124
#endif
125

Simon Glass's avatar
Simon Glass committed
126 127 128
#ifdef CONFIG_PWM_TEGRA
	if (pwm_init(gd->fdt_blob))
		debug("%s: Failed to init pwm\n", __func__);
129 130
#endif
#ifdef CONFIG_LCD
131
	pin_mux_display();
132
	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
133
#endif
134 135
	/* boot param addr */
	gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
136 137 138

	power_det_init();

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

155 156
#ifdef CONFIG_USB_EHCI_TEGRA
	pin_mux_usb();
157
	usb_process_devicetree(gd->fdt_blob);
158
#endif
159

160 161 162
#ifdef CONFIG_LCD
	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
#endif
163

164 165 166 167
#ifdef CONFIG_TEGRA_NAND
	pin_mux_nand();
#endif

168
#ifdef CONFIG_TEGRA_LP0
169 170 171
	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
	warmboot_save_sdram_params();

172 173 174 175
	/* prepare the WB code to LP0 location */
	warmboot_prepare_code(TEGRA_LP0_ADDR, TEGRA_LP0_SIZE);
#endif

176 177
	return 0;
}
178

179
#ifdef CONFIG_BOARD_EARLY_INIT_F
180 181 182 183 184 185
static void __gpio_early_init(void)
{
}

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

186 187
int board_early_init_f(void)
{
188
#if !defined(CONFIG_TEGRA20)
189 190
	pinmux_init();
#endif
191
	board_init_uart_f();
192 193

	/* Initialize periph GPIOs */
194
	gpio_early_init();
195
	gpio_early_init_uart();
196 197 198
#ifdef CONFIG_LCD
	tegra_lcd_early_init(gd->fdt_blob);
#endif
199

200 201 202
	return 0;
}
#endif	/* EARLY_INIT */
203 204 205 206 207 208 209 210 211

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;
}
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232

#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;
}
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261

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