summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/soc/nvidia/tegra132/Kconfig32
-rw-r--r--src/soc/nvidia/tegra132/Makefile.inc16
-rw-r--r--src/soc/nvidia/tegra132/bootblock.c59
-rw-r--r--src/soc/nvidia/tegra132/bootblock_asm.S89
-rw-r--r--src/soc/nvidia/tegra132/clk_rst.h551
-rw-r--r--src/soc/nvidia/tegra132/clock.c662
-rw-r--r--src/soc/nvidia/tegra132/flow.h79
-rw-r--r--src/soc/nvidia/tegra132/include/soc/clock.h43
-rw-r--r--src/soc/nvidia/tegra132/maincpu.S55
-rw-r--r--src/soc/nvidia/tegra132/maincpu.h29
-rw-r--r--src/soc/nvidia/tegra132/pinmux.h260
-rw-r--r--src/soc/nvidia/tegra132/pmc.h389
-rw-r--r--src/soc/nvidia/tegra132/power.h29
-rw-r--r--src/soc/nvidia/tegra132/sysctr.h55
-rw-r--r--src/soc/nvidia/tegra132/uart.c161
15 files changed, 2501 insertions, 8 deletions
diff --git a/src/soc/nvidia/tegra132/Kconfig b/src/soc/nvidia/tegra132/Kconfig
index d90b8aaa8a..23f7c6e7f2 100644
--- a/src/soc/nvidia/tegra132/Kconfig
+++ b/src/soc/nvidia/tegra132/Kconfig
@@ -7,9 +7,21 @@ config SOC_NVIDIA_TEGRA132
select ARCH_RAMSTAGE_ARMV8_64
select ARM_LPAE
select DYNAMIC_CBMEM
+ select BOOTBLOCK_CONSOLE
+ select HAVE_UART_SPECIAL
+ select HAVE_UART_MEMORY_MAPPED
+ select ARM_BOOTBLOCK_CUSTOM
if SOC_NVIDIA_TEGRA132
+config BOOTBLOCK_CPU_INIT
+ string
+ default "soc/nvidia/tegra132/bootblock.c"
+ help
+ CPU/SoC-specific bootblock code. This is useful if the
+ bootblock must load microcode or copy data from ROM before
+ searching for the bootblock.
+
config BOOTBLOCK_ROM_OFFSET
hex
default 0x0
@@ -22,4 +34,24 @@ config CBFS_ROM_OFFSET
hex "offset of CBFS data in ROM"
default 0x40080
+config BOOTBLOCK_BASE
+ hex
+ default 0x40020000
+
+config ROMSTAGE_BASE
+ hex
+ default 0x4002c000
+
+config RAMSTAGE_BASE
+ hex
+ default 0x80200000
+
+config STACK_TOP
+ hex
+ default 0x40020000
+
+config STACK_BOTTOM
+ hex
+ default 0x4001c000
+
endif
diff --git a/src/soc/nvidia/tegra132/Makefile.inc b/src/soc/nvidia/tegra132/Makefile.inc
index b03833920a..5c6fe81a1a 100644
--- a/src/soc/nvidia/tegra132/Makefile.inc
+++ b/src/soc/nvidia/tegra132/Makefile.inc
@@ -1,13 +1,29 @@
+bootblock-y += bootblock.c
+bootblock-y += bootblock_asm.S
bootblock-y += cbfs.c
bootblock-y += timer.c
+bootblock-y += clock.c
+bootblock-y += ../tegra/gpio.c
+bootblock-y += ../tegra/pingroup.c
+bootblock-y += ../tegra/pinmux.c
+bootblock-y += ../tegra/apbmisc.c
+ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y)
+bootblock-$(CONFIG_DRIVERS_UART) += uart.c
+endif
romstage-y += cbfs.c
romstage-y += cbmem.c
romstage-y += timer.c
+romstage-y += ../tegra/gpio.c
+romstage-y += ../tegra/pinmux.c
+romstage-$(CONFIG_DRIVERS_UART) += uart.c
ramstage-y += cbfs.c
ramstage-y += cbmem.c
ramstage-y += timer.c
+ramstage-y += ../tegra/gpio.c
+ramstage-y += ../tegra/pinmux.c
+ramstage-$(CONFIG_DRIVERS_UART) += uart.c
CPPFLAGS_common += -Isrc/soc/nvidia/tegra132/include/
diff --git a/src/soc/nvidia/tegra132/bootblock.c b/src/soc/nvidia/tegra132/bootblock.c
new file mode 100644
index 0000000000..2d8c10ff94
--- /dev/null
+++ b/src/soc/nvidia/tegra132/bootblock.c
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/exception.h>
+#include <arch/hlt.h>
+#include <bootblock_common.h>
+#include <cbfs.h>
+#include <console/console.h>
+#include <soc/clock.h>
+#include <soc/nvidia/tegra/apbmisc.h>
+
+#include "pinmux.h"
+#include "power.h"
+
+void main(void)
+{
+ // enable pinmux clamp inputs
+ clamp_tristate_inputs();
+
+ // enable JTAG at the earliest stage
+ enable_jtag();
+
+ clock_early_uart();
+
+ // Serial out, tristate off.
+ pinmux_set_config(PINMUX_KB_ROW9_INDEX, PINMUX_KB_ROW9_FUNC_UA3);
+ // Serial in, tristate_on.
+ pinmux_set_config(PINMUX_KB_ROW10_INDEX, PINMUX_KB_ROW10_FUNC_UA3 |
+ PINMUX_PULL_UP |
+ PINMUX_INPUT_ENABLE);
+ // Mux some pins away from uart A.
+ pinmux_set_config(PINMUX_UART2_CTS_N_INDEX,
+ PINMUX_UART2_CTS_N_FUNC_UB3 |
+ PINMUX_INPUT_ENABLE);
+ pinmux_set_config(PINMUX_UART2_RTS_N_INDEX,
+ PINMUX_UART2_RTS_N_FUNC_UB3);
+
+ if (CONFIG_BOOTBLOCK_CONSOLE) {
+ console_init();
+ exception_init();
+ printk(BIOS_INFO, "Tegra132: Bootblock here\n");
+ }
+}
diff --git a/src/soc/nvidia/tegra132/bootblock_asm.S b/src/soc/nvidia/tegra132/bootblock_asm.S
new file mode 100644
index 0000000000..ebd64a7425
--- /dev/null
+++ b/src/soc/nvidia/tegra132/bootblock_asm.S
@@ -0,0 +1,89 @@
+/*
+ * Early initialization code for ARM architecture.
+ *
+ * This file is based off of the OMAP3530/ARM Cortex start.S file from Das
+ * U-Boot, which itself got the file from armboot.
+ *
+ * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
+ * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (c) 2003 Kshitij <kshitij@ti.com>
+ * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
+ * Copyright (c) 2013 The Chromium OS Authors
+ *
+ * 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; version 2 of
+ * the License.
+ *
+ * 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
+ */
+
+#include <arch/asm.h>
+
+ENTRY(_start)
+ /*
+ * Set the cpu to System mode with IRQ and FIQ disabled. Prefetch/Data
+ * aborts may happen early and crash before the abort handlers are
+ * installed, but at least the problem will show up near the code that
+ * causes it.
+ */
+ msr cpsr_cxf, #0xdf
+
+ /*
+ * Initialize the stack to a known value. This is used to check for
+ * stack overflow later in the boot process.
+ */
+ ldr r0, .Stack
+ ldr r1, .Stack_size
+ sub r0, r0, r1
+ ldr r1, .Stack
+ ldr r2, =0xdeadbeef
+init_stack_loop:
+ str r2, [r0]
+ add r0, #4
+ cmp r0, r1
+ bne init_stack_loop
+
+/* Set stackpointer in internal RAM to call bootblock main() */
+call_bootblock:
+ ldr sp, .Stack /* Set up stack pointer */
+ ldr r0,=0x00000000
+ /*
+ * The current design of cpu_info places the
+ * struct at the top of the stack. The number of
+ * words pushed must be at least as large as that
+ * struct.
+ */
+ push {r0-r2}
+ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
+ /*
+ * Use "bl" instead of "b" even though we do not intend to return.
+ * "bl" gets compiled to "blx" if we're transitioning from ARM to
+ * Thumb. However, "b" will not and GCC may attempt to create a
+ * wrapper which is currently broken.
+ */
+ bl main
+ENDPROC(_start)
+
+/* we do it this way because it's a 32-bit constant and
+ * in some cases too far away to be loaded as just an offset
+ * from IP
+ */
+.align 2
+.Stack:
+ .word CONFIG_STACK_TOP
+.align 2
+/* create this size the same way we do in ramstage.ld: top-bottom */
+.Stack_size:
+ .word CONFIG_STACK_TOP - CONFIG_STACK_BOTTOM
diff --git a/src/soc/nvidia/tegra132/clk_rst.h b/src/soc/nvidia/tegra132/clk_rst.h
new file mode 100644
index 0000000000..9e2b33f4d7
--- /dev/null
+++ b/src/soc/nvidia/tegra132/clk_rst.h
@@ -0,0 +1,551 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TEGRA132_CLK_RST_H_
+#define _TEGRA132_CLK_RST_H_
+
+/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
+struct __attribute__ ((__packed__)) clk_rst_ctlr {
+ u32 rst_src; /* _RST_SOURCE, 0x000 */
+ u32 rst_dev_l; /* _RST_DEVICES_L, 0x004 */
+ u32 rst_dev_h; /* _RST_DEVICES_H, 0x008 */
+ u32 rst_dev_u; /* _RST_DEVICES_U, 0x00c */
+ u32 clk_out_enb_l; /* _CLK_OUT_ENB_L, 0x010 */
+ u32 clk_out_enb_h; /* _CLK_OUT_ENB_H, 0x014 */
+ u32 clk_out_enb_u; /* _CLK_OUT_ENB_U, 0x018 */
+ u32 _rsv0; /* 0x01c */
+ u32 cclk_brst_pol; /* _CCLK_BURST_POLICY, 0x020 */
+ u32 super_cclk_div; /* _SUPER_CCLK_DIVIDER, 0x024 */
+ u32 sclk_brst_pol; /* _SCLK_BURST_POLICY, 0x028 */
+ u32 super_sclk_div; /* _SUPER_SCLK_DIVIDER, 0x02C */
+ u32 clk_sys_rate; /* _CLK_SYSTEM_RATE, 0x030 */
+ u32 _rsv1[3]; /* 0x034-03c */
+ u32 cop_clk_skip_plcy; /* _COP_CLK_SKIP_POLICY, 0x040 */
+ u32 clk_mask_arm; /* _CLK_MASK_ARM, 0x044 */
+ u32 misc_clk_enb; /* _MISC_CLK_ENB, 0x048 */
+ u32 clk_cpu_cmplx; /* _CLK_CPU_CMPLX, 0x04C */
+ u32 osc_ctrl; /* _OSC_CTRL, 0x050 */
+ u32 pll_lfsr; /* _PLL_LFSR, 0x054 */
+ u32 osc_freq_det; /* _OSC_FREQ_DET, 0x058 */
+ u32 osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS, 0x05C */
+ u32 _rsv2[8]; /* 0x060-07C */
+ u32 pllc_base; /* _PLLC_BASE, 0x080 */
+ u32 pllc_out; /* _PLLC_OUT, 0x084 */
+ u32 pllc_misc2; /* _PLLC_MISC2, 0x088 */
+ u32 pllc_misc; /* _PLLC_MISC, 0x08c */
+ u32 pllm_base; /* _PLLM_BASE, 0x090 */
+ u32 pllm_out; /* _PLLM_OUT, 0x094 */
+ u32 pllm_misc1; /* _PLLM_MISC1, 0x098 */
+ u32 pllm_misc2; /* _PLLM_MISC2, 0x09c */
+ u32 pllp_base; /* _PLLP_BASE, 0x0a0 */
+ u32 pllp_outa; /* _PLLP_OUTA, 0x0a4 */
+ u32 pllp_outb; /* _PLLP_OUTB, 0x0a8 */
+ u32 pllp_misc; /* _PLLP_MISC, 0x0ac */
+ u32 plla_base; /* _PLLA_BASE, 0x0b0 */
+ u32 plla_out; /* _PLLA_OUT, 0x0b4 */
+ u32 _rsv3; /* 0x0b8 */
+ u32 plla_misc; /* _PLLA_MISC, 0x0bc */
+ u32 pllu_base; /* _PLLU_BASE, 0x0c0 */
+ u32 _rsv4[2]; /* 0x0c4-0c8 */
+ u32 pllu_misc; /* _PLLU_MISC, 0x0cc */
+ u32 plld_base; /* _PLLD_BASE, 0x0d0 */
+ u32 _rsv5[2]; /* 0x0d4-0d8 */
+ u32 plld_misc; /* _PLLD_MISC, 0x0dc */
+ u32 pllx_base; /* _PLLX_BASE, 0x0e0 */
+ u32 pllx_misc; /* _PLLX_MISC, 0x0e4 */
+ u32 plle_base; /* _PLLE_BASE, 0x0e8 */
+ u32 plle_misc; /* _PLLE_MISC, 0x0ec */
+ u32 plls_base; /* _PLLS_BASE, 0x0f0 */
+ u32 plls_misc; /* _PLLS_MISC, 0x0f4 */
+ u32 _rsv6[2]; /* 0x0f8-0fc */
+ u32 clk_src_i2s1; /* _CLK_SOURCE_I2S1, 0x100 */
+ u32 clk_src_i2s2; /* _CLK_SOURCE_I2S2, 0x104 */
+ u32 clk_src_spdif_out; /* _CLK_SOURCE_SPDIF_OUT, 0x108 */
+ u32 clk_src_spdif_in; /* _CLK_SOURCE_SPDIF_IN, 0x10c */
+ u32 clk_src_pwm; /* _CLK_SOURCE_PWM, 0x110 */
+ u32 _rsv7; /* 0x114 */
+ u32 clk_src_sbc2; /* _CLK_SOURCE_SBC2, 0x118 */
+ u32 clk_src_sbc3; /* _CLK_SOURCE_SBC3, 0x11c */
+ u32 _rsv8; /* 0x120 */
+ u32 clk_src_i2c1; /* _CLK_SOURCE_I2C1, 0x124 */
+ u32 clk_src_i2c5; /* _CLK_SOURCE_I2C5, 0x128 */
+ u32 _rsv9[2]; /* 0x12c-130 */
+ u32 clk_src_sbc1; /* _CLK_SOURCE_SBC1, 0x134 */
+ u32 clk_src_disp1; /* _CLK_SOURCE_DISP1, 0x138 */
+ u32 clk_src_disp2; /* _CLK_SOURCE_DISP2, 0x13c */
+ u32 _rsv10[2]; /* 0x140-144 */
+ u32 clk_src_vi; /* _CLK_SOURCE_VI, 0x148 */
+ u32 _rsv11; /* 0x14c */
+ u32 clk_src_sdmmc1; /* _CLK_SOURCE_SDMMC1, 0x150 */
+ u32 clk_src_sdmmc2; /* _CLK_SOURCE_SDMMC2, 0x154 */
+ u32 clk_src_g3d; /* _CLK_SOURCE_G3D, 0x158 */
+ u32 clk_src_g2d; /* _CLK_SOURCE_G2D, 0x15c */
+ u32 clk_src_ndflash; /* _CLK_SOURCE_NDFLASH, 0x160 */
+ u32 clk_src_sdmmc4; /* _CLK_SOURCE_SDMMC4, 0x164 */
+ u32 clk_src_vfir; /* _CLK_SOURCE_VFIR, 0x168 */
+ u32 clk_src_epp; /* _CLK_SOURCE_EPP, 0x16c */
+ u32 clk_src_mpe; /* _CLK_SOURCE_MPE, 0x170 */
+ u32 clk_src_hsi; /* _CLK_SOURCE_HSI, 0x174 */
+ u32 clk_src_uarta; /* _CLK_SOURCE_UARTA, 0x178 */
+ u32 clk_src_uartb; /* _CLK_SOURCE_UARTB, 0x17c */
+ u32 clk_src_host1x; /* _CLK_SOURCE_HOST1X, 0x180 */
+ u32 _rsv12[2]; /* 0x184-188 */
+ u32 clk_src_hdmi; /* _CLK_SOURCE_HDMI, 0x18c */
+ u32 _rsv13[2]; /* 0x190-194 */
+ u32 clk_src_i2c2; /* _CLK_SOURCE_I2C2, 0x198 */
+ u32 clk_src_emc; /* _CLK_SOURCE_EMC, 0x19c */
+ u32 clk_src_uartc; /* _CLK_SOURCE_UARTC, 0x1a0 */
+ u32 _rsv14; /* 0x1a4 */
+ u32 clk_src_vi_sensor; /* _CLK_SOURCE_VI_SENSOR, 0x1a8 */
+ u32 _rsv15[2]; /* 0x1ac-1b0 */
+ u32 clk_src_sbc4; /* _CLK_SOURCE_SBC4, 0x1b4 */
+ u32 clk_src_i2c3; /* _CLK_SOURCE_I2C3, 0x1b8 */
+ u32 clk_src_sdmmc3; /* _CLK_SOURCE_SDMMC3, 0x1bc */
+ u32 clk_src_uartd; /* _CLK_SOURCE_UARTD, 0x1c0 */
+ u32 clk_src_uarte; /* _CLK_SOURCE_UARTE, 0x1c4 */
+ u32 clk_src_vde; /* _CLK_SOURCE_VDE, 0x1c8 */
+ u32 clk_src_owr; /* _CLK_SOURCE_OWR, 0x1cc */
+ u32 clk_src_nor; /* _CLK_SOURCE_NOR, 0x1d0 */
+ u32 clk_src_csite; /* _CLK_SOURCE_CSITE, 0x1d4 */
+ u32 clk_src_i2s0; /* _CLK_SOURCE_I2S0, 0x1d8 */
+ u32 clk_src_dtv; /* _CLK_SOURCE_DTV, 0x1dc */
+ u32 _rsv16[4]; /* 0x1e0-1ec */
+ u32 clk_src_msenc; /* _CLK_SOURCE_MSENC, 0x1f0 */
+ u32 clk_src_tsec; /* _CLK_SOURCE_TSEC, 0x1f4 */
+ u32 _rsv17; /* 0x1f8 */
+ u32 clk_src_osc; /* _CLK_SOURCE_OSC, 0x1fc */
+ u32 _rsv18[32]; /* 0x200-27c */
+ u32 clk_out_enb_x; /* _CLK_OUT_ENB_X_0, 0x280 */
+ u32 clk_enb_x_set; /* _CLK_ENB_X_SET_0, 0x284 */
+ u32 clk_enb_x_clr; /* _CLK_ENB_X_CLR_0, 0x288 */
+ u32 rst_devices_x; /* _RST_DEVICES_X_0, 0x28c */
+ u32 rst_dev_x_set; /* _RST_DEV_X_SET_0, 0x290 */
+ u32 rst_dev_x_clr; /* _RST_DEV_X_CLR_0, 0x294 */
+ u32 _rsv19[23]; /* 0x298-2f0 */
+ u32 dfll_base; /* _DFLL_BASE_0, 0x2f4 */
+ u32 _rsv20[2]; /* 0x2f8-2fc */
+ u32 rst_dev_l_set; /* _RST_DEV_L_SET 0x300 */
+ u32 rst_dev_l_clr; /* _RST_DEV_L_CLR 0x304 */
+ u32 rst_dev_h_set; /* _RST_DEV_H_SET 0x308 */
+ u32 rst_dev_h_clr; /* _RST_DEV_H_CLR 0x30c */
+ u32 rst_dev_u_set; /* _RST_DEV_U_SET 0x310 */
+ u32 rst_dev_u_clr; /* _RST_DEV_U_CLR 0x314 */
+ u32 _rsv21[2]; /* 0x318-31c */
+ u32 clk_enb_l_set; /* _CLK_ENB_L_SET 0x320 */
+ u32 clk_enb_l_clr; /* _CLK_ENB_L_CLR 0x324 */
+ u32 clk_enb_h_set; /* _CLK_ENB_H_SET 0x328 */
+ u32 clk_enb_h_clr; /* _CLK_ENB_H_CLR 0x32c */
+ u32 clk_enb_u_set; /* _CLK_ENB_U_SET 0x330 */
+ u32 clk_enb_u_clk; /* _CLK_ENB_U_CLR 0x334 */
+ u32 _rsv22; /* 0x338 */
+ u32 ccplex_pg_sm_ovrd; /* _CCPLEX_PG_SM_OVRD, 0x33c */
+ u32 rst_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET, 0x340 */
+ u32 rst_cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR, 0x344 */
+ u32 clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET, 0x348 */
+ u32 clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET, 0x34c */
+ u32 _rsv23[2]; /* 0x350-354 */
+ u32 rst_dev_v; /* _RST_DEVICES_V, 0x358 */
+ u32 rst_dev_w; /* _RST_DEVICES_W, 0x35c */
+ u32 clk_out_enb_v; /* _CLK_OUT_ENB_V, 0x360 */
+ u32 clk_out_enb_w; /* _CLK_OUT_ENB_W, 0x364 */
+ u32 cclkg_brst_pol; /* _CCLKG_BURST_POLICY, 0x368 */
+ u32 super_cclkg_div; /* _SUPER_CCLKG_DIVIDER, 0x36c */
+ u32 cclklp_brst_pol; /* _CCLKLP_BURST_POLICY, 0x370 */
+ u32 super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER, 0x374 */
+ u32 clk_cpug_cmplx; /* _CLK_CPUG_CMPLX, 0x378 */
+ u32 clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX, 0x37c */
+ u32 cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL, 0x380 */
+ u32 cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTRL1, 0x384 */
+ u32 cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2, 0x388 */
+ u32 _rsv24[9]; /* 0x38c-3ac */
+ u32 clk_src_g3d2; /* _CLK_SOURCE_G3D2, 0x3b0 */
+ u32 clk_src_mselect; /* _CLK_SOURCE_MSELECT, 0x3b4 */
+ u32 clk_src_tsensor; /* _CLK_SOURCE_TSENSOR, 0x3b8 */
+ u32 clk_src_i2s3; /* _CLK_SOURCE_I2S3, 0x3bc */
+ u32 clk_src_i2s4; /* _CLK_SOURCE_I2S4, 0x3c0 */
+ u32 clk_src_i2c4; /* _CLK_SOURCE_I2C4, 0x3c4 */
+ u32 clk_src_sbc5; /* _CLK_SOURCE_SBC5, 0x3c8 */
+ u32 clk_src_sbc6; /* _CLK_SOURCE_SBC6, 0x3cc */
+ u32 clk_src_audio; /* _CLK_SOURCE_AUDIO, 0x3d0 */
+ u32 _rsv25; /* 0x3d4 */
+ u32 clk_src_dam0; /* _CLK_SOURCE_DAM0, 0x3d8 */
+ u32 clk_src_dam1; /* _CLK_SOURCE_DAM1, 0x3dc */
+ u32 clk_src_dam2; /* _CLK_SOURCE_DAM2, 0x3e0 */
+ u32 clk_src_hda2codec_2x; /* _CLK_SOURCE_HDA2CODEC_2X,0x3e4 */
+ u32 clk_src_actmon; /* _CLK_SOURCE_ACTMON, 0x3e8 */
+ u32 clk_src_extperiph1; /* _CLK_SOURCE_EXTPERIPH1, 0x3ec */
+ u32 clk_src_extperiph2; /* _CLK_SOURCE_EXTPERIPH2, 0x3f0 */
+ u32 clk_src_extperiph3; /* _CLK_SOURCE_EXTPERIPH3, 0x3f4 */
+ u32 clk_src_nand_speed; /* _CLK_SOURCE_NAND_SPEED, 0x3f8 */
+ u32 clk_src_i2c_slow; /* _CLK_SOURCE_I2C_SLOW, 0x3fc */
+ u32 clk_src_sys; /* _CLK_SOURCE_SYS, 0x400 */
+ u32 _rsv26[4]; /* 0x404-410 */
+ u32 clk_src_sor; /* _CLK_SOURCE_SOR_0, 0x414 */
+ u32 _rsv261[2]; /* 0x404-410 */
+ u32 clk_src_sata_oob; /* _CLK_SOURCE_SATA_OOB, 0x420 */
+ u32 clk_src_sata; /* _CLK_SOURCE_SATA, 0x424 */
+ u32 clk_src_hda; /* _CLK_SOURCE_HDA, 0x428 */
+ u32 _rsv27; /* 0x42c */
+ u32 rst_dev_v_set; /* _RST_DEV_V_SET, 0x430 */
+ u32 rst_dev_v_clr; /* _RST_DEV_V_CLR, 0x434 */
+ u32 rst_dev_w_set; /* _RST_DEV_W_SET, 0x438 */
+ u32 rst_dev_w_clr; /* _RST_DEV_W_CLR, 0x43c */
+ u32 clk_enb_v_set; /* _CLK_ENB_V_SET, 0x440 */
+ u32 clk_enb_v_clr; /* _CLK_ENB_V_CLR, 0x444 */
+ u32 clk_enb_w_set; /* _CLK_ENB_W_SET, 0x448 */
+ u32 clk_enb_w_clr; /* _CLK_ENB_W_CLR, 0x44c */
+ u32 rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET, 0x450 */
+ u32 rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR, 0x454 */
+ u32 rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET, 0x458 */
+ u32 rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR, 0x45C */
+ u32 clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET, 0x460 */
+ u32 clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR, 0x464 */
+ u32 clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET, 0x468 */
+ u32 clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR, 0x46c */
+ u32 cpu_cmplx_status; /* _CPU_CMPLX_STATUS, 0x470 */
+ u32 _rsv28; /* 0x474 */
+ u32 intstatus; /* _INTSTATUS, 0x478 */
+ u32 intmask; /* _INTMASK, 0x47c */
+ u32 utmip_pll_cfg0; /* _UTMIP_PLL_CFG0, 0x480 */
+ u32 utmip_pll_cfg1; /* _UTMIP_PLL_CFG1, 0x484 */
+ u32 utmip_pll_cfg2; /* _UTMIP_PLL_CFG2, 0x488 */
+ u32 plle_aux; /* _PLLE_AUX, 0x48c */
+ u32 sata_pll_cfg0; /* _SATA_PLL_CFG0, 0x490 */
+ u32 sata_pll_cfg1; /* _SATA_PLL_CFG1, 0x494 */
+ u32 pcie_pll_cfg0; /* _PCIE_PLL_CFG0, 0x498 */
+ u32 prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK, 0x49c */
+ u32 audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0, 0x4a0 */
+ u32 audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1, 0x4a4 */
+ u32 audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2, 0x4a8 */
+ u32 audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3, 0x4ac */
+ u32 audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4, 0x4b0 */
+ u32 audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF, 0x4b4 */
+ u32 plld2_base; /* _PLLD2_BASE, 0x4b8 */
+ u32 plld2_misc; /* _PLLD2_MISC, 0x4bc */
+ u32 utmip_pll_cfg3; /* _UTMIP_PLL_CFG3, 0x4c0 */
+ u32 pllrefe_base; /* _PLLREFE_BASE, 0x4c4 */
+ u32 pllrefe_misc; /* _PLLREFE_MISC, 0x4c8 */
+ u32 _rsv29[7]; /* 0x4cc-4e4 */
+ u32 pllc2_base; /* _PLLC2_BASE, 0x4e8 */
+ u32 pllc2_misc0; /* _PLLC2_MISC_0, 0x4ec */
+ u32 pllc2_misc1; /* _PLLC2_MISC_1, 0x4f0 */
+ u32 pllc2_misc2; /* _PLLC2_MISC_2, 0x4f4 */
+ u32 pllc2_misc3; /* _PLLC2_MISC_3, 0x4f8 */
+ u32 pllc3_base; /* _PLLC3_BASE, 0x4fc */
+ u32 pllc3_misc0; /* _PLLC3_MISC_0, 0x500 */
+ u32 pllc3_misc1; /* _PLLC3_MISC_1, 0x504 */
+ u32 pllc3_misc2; /* _PLLC3_MISC_2, 0x508 */
+ u32 pllc3_misc3; /* _PLLC3_MISC_3, 0x50c */
+ u32 pllx_misc1; /* _PLLX_MISC_1, 0x510 */
+ u32 pllx_misc2; /* _PLLX_MISC_2, 0x514 */
+ u32 pllx_misc3; /* _PLLX_MISC_3, 0x518 */
+ u32 xusbio_pll_cfg0; /* _XUSBIO_PLL_CFG0, 0x51c */
+ u32 xusbio_pll_cfg1; /* _XUSBIO_PLL_CFG1, 0x520 */
+ u32 plle_aux1; /* _PLLE_AUX1, 0x524 */
+ u32 pllp_reshift; /* _PLLP_RESHIFT, 0x528 */
+ u32 utmipll_hw_pwrdn_cfg0; /* _UTMIPLL_HW_PWRDN_CFG0, 0x52c */
+ u32 pllu_hw_pwrdn_cfg0; /* _PLLU_HW_PWRDN_CFG0, 0x530 */
+ u32 xusb_pll_cfg0; /* _XUSB_PLL_CFG0, 0x534 */
+ u32 _rsv30; /* 0x538 */
+ u32 clk_cpu_misc; /* _CLK_CPU_MISC, 0x53c */
+ u32 clk_cpug_misc; /* _CLK_CPUG_MISC, 0x540 */
+ u32 clk_cpulp_misc; /* _CLK_CPULP_MISC, 0x544 */
+ u32 pllx_hw_ctrl_cfg; /* _PLLX_HW_CTRL_CFG, 0x548 */
+ u32 pllx_sw_ramp_cfg; /* _PLLX_SW_RAMP_CFG, 0x54c */
+ u32 pllx_hw_ctrl_status; /* _PLLX_HW_CTRL_STATUS, 0x550 */
+ u32 _rsv31; /* 0x554 */
+ u32 super_gr3d_clk_div; /* _SUPER_GR3D_CLK_DIVIDER, 0x558 */
+ u32 spare_reg0; /* _SPARE_REG0, 0x55c */
+ u32 _rsv32[4]; /* 0x560-0x56c */
+ u32 plld2_ss_cfg; /* _PLLD2_SS_CFG 0x570 */
+ u32 _rsv32_1[7]; /* 0x574-58c */
+ u32 plldp_base; /* _PLLDP_BASE, 0x590 */
+ u32 plldp_misc; /* _PLLDP_MISC, 0x594 */
+ u32 plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */
+ u32 _rsrv32_2[25];
+ u32 clk_src_xusb_core_host; /* _CLK_SOURCE_XUSB_CORE_HOST 0x600 */
+ u32 clk_src_xusb_falcon; /* _CLK_SOURCE_XUSB_FALCON 0x604 */
+ u32 clk_src_xusb_fs; /* _CLK_SOURCE_XUSB_FS 0x608 */
+ u32 clk_src_xusb_core_dev; /* _CLK_SOURCE_XUSB_CORE_DEV 0x60c */
+ u32 clk_src_xusb_ss; /* _CLK_SOURCE_XUSB_SS 0x610 */
+ u32 clk_src_cilab; /* _CLK_SOURCE_CILAB 0x614 */
+ u32 clk_src_cilcd; /* _CLK_SOURCE_CILCD 0x618 */
+ u32 clk_src_cile; /* _CLK_SOURCE_CILE 0x61c */
+ u32 clk_src_dsia_lp; /* _CLK_SOURCE_DSIA_LP 0x620 */
+ u32 clk_src_dsib_lp; /* _CLK_SOURCE_DSIB_LP 0x624 */
+ u32 clk_src_entropy; /* _CLK_SOURCE_ENTROPY 0x628 */
+ u32 clk_src_dvfs_ref; /* _CLK_SOURCE_DVFS_REF 0x62c */
+ u32 clk_src_dvfs_soc; /* _CLK_SOURCE_DVFS_SOC 0x630 */
+ u32 clk_src_traceclkin; /* _CLK_SOURCE_TRACECLKIN 0x634 */
+ u32 clk_src_adx0; /* _CLK_SOURCE_ADX0 0x638 */
+ u32 clk_src_amx0; /* _CLK_SOURCE_AMX0 0x63c */
+ u32 clk_src_emc_latency; /* _CLK_SOURCE_EMC_LATENCY 0x640 */
+ u32 clk_src_soc_therm; /* _CLK_SOURCE_SOC_THERM 0x644 */
+};
+check_member(clk_rst_ctlr, clk_src_soc_therm, 0x644);
+
+#define TEGRA_DEV_L 0
+#define TEGRA_DEV_H 1
+#define TEGRA_DEV_U 2
+#define TEGRA_DEV_V 0
+#define TEGRA_DEV_W 1
+
+#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE)
+
+/* Bits to enable/reset modules */
+#define CLK_ENB_CPU (1 << 0)
+#define SWR_TRIG_SYS_RST (1 << 2)
+#define SWR_CSITE_RST (1 << 9)
+#define CLK_ENB_CSITE (1 << 9)
+
+/* CRC_SUPER_CCLK_DIVIDER_0 0x24 */
+#define SUPER_CDIV_ENB_ENABLE (1 << 31)
+
+/* CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48 */
+#define EN_PPSB_STOPCLK (1 << 0)
+
+/* CLK_RST_CONTROLLER_CLK_CPU_CMPLX_0 (0x4C) */
+#define CPU3_CLK_STP_SHIFT 11
+#define CPU2_CLK_STP_SHIFT 10
+#define CPU1_CLK_STP_SHIFT 9
+#define CPU0_CLK_STP_SHIFT 8
+#define CPU0_CLK_STP_MASK (1U << CPU0_CLK_STP_SHIFT)
+
+/* CRC_OSC_CTRL_0 0x50 */
+#define OSC_FREQ_SHIFT 28
+#define OSC_FREQ_MASK (0xf << OSC_FREQ_SHIFT)
+#define OSC_PREDIV_SHIFT 26
+#define OSC_PREDIV_MASK (0x3 << OSC_PREDIV_SHIFT)
+#define OSC_XOFS_SHIFT 4
+#define OSC_XOFS_MASK (0x3F << OSC_XOFS_SHIFT)
+#define OSC_DRIVE_STRENGTH 7
+#define OSC_XOBP (1 << 1)
+#define OSC_XOE (1 << 0)
+
+enum {
+ OSC_FREQ_12 = 8, /* 12.0MHz */
+ OSC_FREQ_13 = 0, /* 13.0MHz */
+ OSC_FREQ_16P8 = 1, /* 16.8MHz */
+ OSC_FREQ_19P2 = 4, /* 19.2MHz */
+ OSC_FREQ_26 = 12, /* 26.0MHz */
+ OSC_FREQ_38P4 = 5, /* 38.4MHz */
+ OSC_FREQ_48 = 9, /* 48.0MHz */
+};
+
+/* CLK_RST_CONTROLLER_PLL*_BASE_0 */
+#define PLL_BASE_BYPASS (1U << 31)
+#define PLL_BASE_ENABLE (1U << 30)
+#define PLL_BASE_REF_DIS (1U << 29)
+#define PLL_BASE_OVRRIDE (1U << 28)
+#define PLL_BASE_LOCK (1U << 27)
+
+#define PLL_BASE_DIVP_SHIFT 20
+#define PLL_BASE_DIVP_MASK (7U << PLL_BASE_DIVP_SHIFT)
+
+#define PLL_BASE_DIVN_SHIFT 8
+#define PLL_BASE_DIVN_MASK (0x3ffU << PLL_BASE_DIVN_SHIFT)
+
+#define PLL_BASE_DIVM_SHIFT 0
+#define PLL_BASE_DIVM_MASK (0x1f << PLL_BASE_DIVM_SHIFT)
+
+/* SPECIAL CASE: PLLM, PLLC and PLLX use different-sized fields here */
+#define PLLCX_BASE_DIVP_MASK (0xfU << PLL_BASE_DIVP_SHIFT)
+#define PLLM_BASE_DIVP_MASK (0x1U << PLL_BASE_DIVP_SHIFT)
+#define PLLCMX_BASE_DIVN_MASK (0xffU << PLL_BASE_DIVN_SHIFT)
+#define PLLCMX_BASE_DIVM_MASK (0xffU << PLL_BASE_DIVM_SHIFT)
+
+/* PLLM specific registers */
+#define PLLM_MISC1_SETUP_SHIFT 0
+#define PLLM_MISC1_PD_LSHIFT_PH45_SHIFT 28
+#define PLLM_MISC1_PD_LSHIFT_PH90_SHIFT 29
+#define PLLM_MISC1_PD_LSHIFT_PH135_SHIFT 30
+#define PLLM_MISC2_KCP_SHIFT 1
+#define PLLM_MISC2_KVCO_SHIFT 0
+#define PLLM_OUT1_RSTN_RESET_DISABLE (1 << 0)
+
+/* Generic, indiscriminate divisor mask. May catch some innocent bystander bits
+ * on the side that we don't particularly care about. */
+#define PLL_BASE_DIV_MASK (0xffffff)
+
+/* CLK_RST_CONTROLLER_PLL*_OUT*_0 */
+#define PLL_OUT_RSTN (1 << 0)
+#define PLL_OUT_CLKEN (1 << 1)
+#define PLL_OUT_OVR (1 << 2)
+
+#define PLL_OUT_RATIO_SHIFT 8
+#define PLL_OUT_RATIO_MASK (0xffU << PLL_OUT_RATIO_SHIFT)
+
+#define PLL_OUT1_SHIFT 0
+#define PLL_OUT2_SHIFT 16
+#define PLL_OUT3_SHIFT 0
+#define PLL_OUT4_SHIFT 16
+
+/* CLK_RST_CONTROLLER_PLL*_MISC_0 */
+#define PLL_MISC_DCCON (1 << 20)
+
+#define PLL_MISC_CPCON_SHIFT 8
+#define PLL_MISC_CPCON_MASK (0xfU << PLL_MISC_CPCON_SHIFT)
+
+#define PLL_MISC_LFCON_SHIFT 4
+#define PLL_MISC_LFCON_MASK (0xfU << PLL_MISC_LFCON_SHIFT)
+
+/* This bit is different all over the place. Oh joy... */
+#define PLLDPD2_MISC_LOCK_ENABLE (1 << 30)
+#define PLLC_MISC_LOCK_ENABLE (1 << 24)
+#define PLLUD_MISC_LOCK_ENABLE (1 << 22)
+#define PLLD_MISC_CLK_ENABLE (1 << 30)
+#define PLLPAXS_MISC_LOCK_ENABLE (1 << 18)
+#define PLLE_MISC_LOCK_ENABLE (1 << 9)
+
+#define PLLU_MISC_VCO_FREQ (1 << 20)
+
+/* PLLX_BASE_0 0xe0 */
+#define PLLX_BASE_PLLX_ENABLE (1 << 30)
+
+/* CLK_RST_CONTROLLER_PLLX_MISC_3 */
+#define PLLX_IDDQ_SHIFT 3
+#define PLLX_IDDQ_MASK (1U << PLLX_IDDQ_SHIFT)
+
+#define CLK_DIVISOR_MASK (0xffff)
+
+#define CLK_SOURCE_SHIFT 29
+#define CLK_SOURCE_MASK (0x7 << CLK_SOURCE_SHIFT)
+
+#define CLK_SOURCE_EMC_MC_EMC_SAME_FREQ (1 << 16)
+
+#define CLK_UART_DIV_OVERRIDE (1 << 24)
+
+/* CLK_RST_CONTROLLER_SCLK_BURST_POLICY */
+#define SCLK_SYS_STATE_SHIFT 28U
+#define SCLK_SYS_STATE_MASK (15U << SCLK_SYS_STATE_SHIFT)
+enum {
+ SCLK_SYS_STATE_STDBY,
+ SCLK_SYS_STATE_IDLE,
+ SCLK_SYS_STATE_RUN,
+ SCLK_SYS_STATE_IRQ = 4U,
+ SCLK_SYS_STATE_FIQ = 8U,
+};
+#define SCLK_COP_FIQ_MASK (1 << 27)
+#define SCLK_CPU_FIQ_MASK (1 << 26)
+#define SCLK_COP_IRQ_MASK (1 << 25)
+#define SCLK_CPU_IRQ_MASK (1 << 24)
+
+#define SCLK_FIQ_SHIFT 12
+#define SCLK_FIQ_MASK (7 << SCLK_FIQ_SHIFT)
+#define SCLK_IRQ_SHIFT 8
+#define SCLK_IRQ_MASK (7 << SCLK_FIQ_SHIFT)
+#define SCLK_RUN_SHIFT 4
+#define SCLK_RUN_MASK (7 << SCLK_FIQ_SHIFT)
+#define SCLK_IDLE_SHIFT 0
+#define SCLK_IDLE_MASK (7 << SCLK_FIQ_SHIFT)
+enum {
+ SCLK_SOURCE_CLKM,
+ SCLK_SOURCE_PLLC_OUT1,
+ SCLK_SOURCE_PLLP_OUT4,
+ SCLK_SOURCE_PLLP_OUT3,
+ SCLK_SOURCE_PLLP_OUT2,
+ SCLK_SOURCE_PLLC_OUT0,
+ SCLK_SOURCE_CLKS,
+ SCLK_SOURCE_PLLM_OUT1,
+};
+
+/* CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2c */
+#define SCLK_DIV_ENB (1 << 31)
+#define SCLK_DIVIDEND_SHIFT 8
+#define SCLK_DIVIDEND_MASK (0xff << SCLK_DIVIDEND_SHIFT)
+#define SCLK_DIVISOR_SHIFT 0
+#define SCLK_DIVISOR_MASK (0xff << SCLK_DIVISOR_SHIFT)
+
+/* CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30 */
+#define HCLK_DISABLE (1 << 7)
+#define HCLK_DIVISOR_SHIFT 4
+#define HCLK_DIVISOR_MASK (3 << AHB_RATE_SHIFT)
+#define PCLK_DISABLE (1 << 3)
+#define PCLK_DIVISOR_SHIFT 0
+#define PCLK_DIVISOR_MASK (3 << AHB_RATE_SHIFT)
+
+/* CRC_CLK_SOURCE_MSELECT_0 0x3b4 */
+#define MSELECT_CLK_SRC_PLLP_OUT0 (0 << 29)
+
+/* CRC_CLK_ENB_V_SET_0 0x440 */
+#define SET_CLK_ENB_CPUG_ENABLE (1 << 0)
+#define SET_CLK_ENB_CPULP_ENABLE (1 << 1)
+#define SET_CLK_ENB_MSELECT_ENABLE (1 << 3)
+
+/* CLK_RST_CONTROLLER_UTMIP_PLL_CFG1_0 0x484 */
+#define PLLU_POWERDOWN (1 << 16)
+#define PLL_ENABLE_POWERDOWN (1 << 14)
+#define PLL_ACTIVE_POWERDOWN (1 << 12)
+
+/* CLK_RST_CONTROLLER_UTMIP_PLL_CFG2_0 0x488 */
+#define UTMIP_FORCE_PD_SAMP_C_POWERDOWN (1 << 4)
+#define UTMIP_FORCE_PD_SAMP_B_POWERDOWN (1 << 2)
+#define UTMIP_FORCE_PD_SAMP_A_POWERDOWN (1 << 0)
+
+// CCLK_BRST_POL
+enum {
+ CRC_CCLK_BRST_POL_PLLX_OUT0 = 0x8,
+ CRC_CCLK_BRST_POL_CPU_STATE_RUN = 0x2
+};
+
+// SUPER_CCLK_DIVIDER
+enum {
+ CRC_SUPER_CCLK_DIVIDER_SUPER_CDIV_ENB = 1 << 31
+};
+
+// CLK_CPU_CMPLX_CLR
+enum {
+ CRC_CLK_CLR_CPU0_STP = 0x1 << 8,
+ CRC_CLK_CLR_CPU1_STP = 0x1 << 9,
+ CRC_CLK_CLR_CPU2_STP = 0x1 << 10,
+ CRC_CLK_CLR_CPU3_STP = 0x1 << 11
+};
+
+// RST_CPUG_CMPLX_CLR
+enum {
+ CRC_RST_CPUG_CLR_CPU0 = 0x1 << 0,
+ CRC_RST_CPUG_CLR_CPU1 = 0x1 << 1,
+ CRC_RST_CPUG_CLR_CPU2 = 0x1 << 2,
+ CRC_RST_CPUG_CLR_CPU3 = 0x1 << 3,
+ CRC_RST_CPUG_CLR_DBG0 = 0x1 << 12,
+ CRC_RST_CPUG_CLR_DBG1 = 0x1 << 13,
+ CRC_RST_CPUG_CLR_DBG2 = 0x1 << 14,
+ CRC_RST_CPUG_CLR_DBG3 = 0x1 << 15,
+ CRC_RST_CPUG_CLR_CORE0 = 0x1 << 16,
+ CRC_RST_CPUG_CLR_CORE1 = 0x1 << 17,
+ CRC_RST_CPUG_CLR_CORE2 = 0x1 << 18,
+ CRC_RST_CPUG_CLR_CORE3 = 0x1 << 19,
+ CRC_RST_CPUG_CLR_CX0 = 0x1 << 20,
+ CRC_RST_CPUG_CLR_CX1 = 0x1 << 21,
+ CRC_RST_CPUG_CLR_CX2 = 0x1 << 22,
+ CRC_RST_CPUG_CLR_CX3 = 0x1 << 23,
+ CRC_RST_CPUG_CLR_L2 = 0x1 << 24,
+ CRC_RST_CPUG_CLR_NONCPU = 0x1 << 29,
+ CRC_RST_CPUG_CLR_PDBG = 0x1 << 30,
+};
+
+// RST_CPULP_CMPLX_CLR
+enum {
+ CRC_RST_CPULP_CLR_CPU0 = 0x1 << 0,
+ CRC_RST_CPULP_CLR_DBG0 = 0x1 << 12,
+ CRC_RST_CPULP_CLR_CORE0 = 0x1 << 16,
+ CRC_RST_CPULP_CLR_CX0 = 0x1 << 20,
+ CRC_RST_CPULP_CLR_L2 = 0x1 << 24,
+ CRC_RST_CPULP_CLR_NONCPU = 0x1 << 29,
+ CRC_RST_CPULP_CLR_PDBG = 0x1 << 30,
+};
+
+#endif /* _TEGRA132_CLK_RST_H_ */
diff --git a/src/soc/nvidia/tegra132/clock.c b/src/soc/nvidia/tegra132/clock.c
new file mode 100644
index 0000000000..5237712ef3
--- /dev/null
+++ b/src/soc/nvidia/tegra132/clock.c
@@ -0,0 +1,662 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <console/console.h>
+#include <delay.h>
+#include <arch/io.h>
+#include <soc/addressmap.h>
+#include <soc/clock.h>
+#include <stdlib.h>
+#include "clk_rst.h"
+#include "flow.h"
+#include "maincpu.h"
+#include "pmc.h"
+#include "sysctr.h"
+
+static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
+static struct flow_ctlr *flow = (void *)TEGRA_FLOW_BASE;
+static struct tegra_pmc_regs *pmc = (void *)TEGRA_PMC_BASE;
+static struct sysctr_regs *sysctr = (void *)TEGRA_SYSCTR0_BASE;
+
+struct pll_dividers {
+ u32 n : 10;
+ u32 m : 8;
+ u32 p : 4;
+ u32 cpcon : 4;
+ u32 lfcon : 4;
+ u32 : 2;
+};
+
+/* Some PLLs have more restrictive divider bit lengths or are missing some
+ * fields. Make sure to use the right struct in the osc_table definition to get
+ * compile-time checking, but keep the bits aligned with struct pll_dividers so
+ * they can be used interchangeably at run time. Add new formats as required. */
+struct pllcx_dividers {
+ u32 n : 8;
+ u32 : 2;
+ u32 m : 8;
+ u32 p : 4;
+ u32 : 10;
+};
+struct pllpad_dividers {
+ u32 n : 10;
+ u32 m : 5;
+ u32 : 3;
+ u32 p : 3;
+ u32 : 1;
+ u32 cpcon : 4;
+ u32 : 6;
+};
+struct pllu_dividers {
+ u32 n : 10;
+ u32 m : 5;
+ u32 : 3;
+ u32 p : 1;
+ u32 : 3;
+ u32 cpcon : 4;
+ u32 lfcon : 4;
+ u32 : 2;
+};
+
+union __attribute__((transparent_union)) pll_fields {
+ u32 raw;
+ struct pll_dividers div;
+ struct pllcx_dividers cx;
+ struct pllpad_dividers pad;
+ struct pllu_dividers u;
+};
+
+/* This table defines the frequency dividers for every PLL to turn the external
+ * OSC clock into the frequencies defined by TEGRA_PLL*_KHZ in soc/clock.h.
+ * All PLLs have three dividers (n, m and p), with the governing formula for
+ * the output frequency being CF = (IN / m), VCO = CF * n and OUT = VCO / (2^p).
+ * All divisor configurations must meet the PLL's constraints for VCO and CF:
+ * PLLX: 12 MHz < CF < 50 MHz, 700 MHz < VCO < 3000 MHz
+ * PLLC: 12 MHz < CF < 50 MHz, 600 MHz < VCO < 1400 MHz
+ * PLLM: 12 MHz < CF < 50 MHz, 400 MHz < VCO < 1066 MHz
+ * PLLP: 1 MHz < CF < 6 MHz, 200 MHz < VCO < 700 MHz
+ * PLLD: 1 MHz < CF < 6 MHz, 500 MHz < VCO < 1000 MHz
+ * PLLU: 1 MHz < CF < 6 MHz, 480 MHz < VCO < 960 MHz
+ * PLLDP: 12 MHz < CF < 38 MHz, 600 MHz < VCO < 1200 MHz
+ * (values taken from Linux' drivers/clk/tegra/clk-tegra124.c). */
+struct {
+ int khz;
+ struct pllcx_dividers pllx; /* target: CONFIG_PLLX_KHZ */
+ struct pllcx_dividers pllc; /* target: 600 MHz */
+ /* PLLM is set up dynamically by clock_sdram(). */
+ /* PLLP is hardwired to 408 MHz in HW (unless we set BASE_OVRD). */
+ struct pllu_dividers pllu; /* target; 960 MHz */
+ struct pllcx_dividers plldp; /* target; 270 MHz */
+ /* PLLDP treats p differently (OUT = VCO / (p + 1) for p < 6). */
+} static const osc_table[16] = {
+ [OSC_FREQ_12]{
+ .khz = 12000,
+ .pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
+ .pllc = {.n = 50, .m = 1, .p = 0},
+ .pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
+ .plldp = {.n = 90, .m = 1, .p = 3},
+ },
+ [OSC_FREQ_13]{
+ .khz = 13000,
+ .pllx = {.n = TEGRA_PLLX_KHZ / 13000, .m = 1, .p = 0},
+ .pllc = {.n = 46, .m = 1, .p = 0}, /* 598.0 MHz */
+ .pllu = {.n = 960, .m = 13, .p = 0, .cpcon = 12, .lfcon = 2},
+ .plldp = {.n = 83, .m = 1, .p = 3}, /* 269.8 MHz */
+ },
+ [OSC_FREQ_16P8]{
+ .khz = 16800,
+ .pllx = {.n = TEGRA_PLLX_KHZ / 16800, .m = 1, .p = 0},
+ .pllc = {.n = 71, .m = 1, .p = 1}, /* 596.4 MHz */
+ .pllu = {.n = 400, .m = 7, .p = 0, .cpcon = 5, .lfcon = 2},
+ .plldp = {.n = 64, .m = 1, .p = 3}, /* 268.8 MHz */
+ },
+ [OSC_FREQ_19P2]{
+ .khz = 19200,
+ .pllx = {.n = TEGRA_PLLX_KHZ / 19200, .m = 1, .p = 0},
+ .pllc = {.n = 62, .m = 1, .p = 1}, /* 595.2 MHz */
+ .pllu = {.n = 200, .m = 4, .p = 0, .cpcon = 3, .lfcon = 2},
+ .plldp = {.n = 56, .m = 1, .p = 3}, /* 268.8 MHz */
+ },
+ [OSC_FREQ_26]{
+ .khz = 26000,
+ .pllx = {.n = TEGRA_PLLX_KHZ / 26000, .m = 1, .p = 0},
+ .pllc = {.n = 23, .m = 1, .p = 0}, /* 598.0 MHz */
+ .pllu = {.n = 960, .m = 26, .p = 0, .cpcon = 12, .lfcon = 2},
+ .plldp = {.n = 83, .m = 2, .p = 3}, /* 269.8 MHz */
+ },
+ /* These oscillators get predivided as PLL inputs... n/m/p divisors for
+ * 38.4 should always match 19.2, and 48 should always match 12. */
+ [OSC_FREQ_38P4]{
+ .khz = 38400,
+ .pllx = {.n = TEGRA_PLLX_KHZ / 19200, .m = 1, .p = 0},
+ .pllc = {.n = 62, .m = 1, .p = 1}, /* 595.2 MHz */
+ .pllu = {.n = 200, .m = 4, .p = 0, .cpcon = 3, .lfcon = 2},
+ .plldp = {.n = 56, .m = 1, .p = 3}, /* 268.8 MHz */
+ },
+ [OSC_FREQ_48]{
+ .khz = 48000,
+ .pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
+ .pllc = {.n = 50, .m = 1, .p = 0},
+ .pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
+ .plldp = {.n = 90, .m = 1, .p = 3},
+ },
+};
+
+/* Get the oscillator frequency, from the corresponding hardware
+ * configuration field. This is actually a per-soc thing. Avoid the
+ * temptation to make it common.
+ */
+static u32 clock_get_osc_bits(void)
+{
+ return (readl(&clk_rst->osc_ctrl) & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
+}
+
+int clock_get_osc_khz(void)
+{
+ return osc_table[clock_get_osc_bits()].khz;
+}
+
+int clock_get_pll_input_khz(void)
+{
+ u32 osc_ctrl = readl(&clk_rst->osc_ctrl);
+ u32 osc_bits = (osc_ctrl & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
+ u32 pll_ref_div = (osc_ctrl & OSC_PREDIV_MASK) >> OSC_PREDIV_SHIFT;
+ return osc_table[osc_bits].khz >> pll_ref_div;
+}
+
+void clock_init_arm_generic_timer(void)
+{
+ uint32_t freq = clock_get_osc_khz() * 1000;
+ // Set the cntfrq register.
+ __asm__ __volatile__("mcr p15, 0, %0, c14, c0, 0\n" :: "r"(freq));
+
+ // Record the system timer frequency.
+ write32(freq, &sysctr->cntfid0);
+ // Enable the system counter.
+ uint32_t cntcr = read32(&sysctr->cntcr);
+ cntcr |= SYSCTR_CNTCR_EN | SYSCTR_CNTCR_HDBG;
+ write32(cntcr, &sysctr->cntcr);
+}
+
+#define SOR0_CLK_SEL0 (1 << 14)
+#define SOR0_CLK_SEL1 (1 << 15)
+
+void sor_clock_stop(void)
+{
+ /* The Serial Output Resource clock has to be off
+ * before we start the plldp. Learned the hard way.
+ * FIXME: this has to be cleaned up a bit more.
+ * Waiting on some new info from Nvidia.
+ */
+ clrbits_le32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0 | SOR0_CLK_SEL1);
+}
+
+void sor_clock_start(void)
+{
+ /* uses PLLP, has a non-standard bit layout. */
+ setbits_le32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0);
+}
+
+static void init_pll(u32 *base, u32 *misc, const union pll_fields pll, u32 lock)
+{
+ u32 dividers = pll.div.n << PLL_BASE_DIVN_SHIFT |
+ pll.div.m << PLL_BASE_DIVM_SHIFT |
+ pll.div.p << PLL_BASE_DIVP_SHIFT;
+ u32 misc_con = pll.div.cpcon << PLL_MISC_CPCON_SHIFT |
+ pll.div.lfcon << PLL_MISC_LFCON_SHIFT;
+
+ /* Write dividers but BYPASS the PLL while we're messing with it. */
+ writel(dividers | PLL_BASE_BYPASS, base);
+ /*
+ * Set Lock bit, CPCON and LFCON fields (default to 0 if it doesn't
+ * exist for this PLL)
+ */
+ writel(lock | misc_con, misc);
+
+ /* Enable PLL and take it back out of BYPASS */
+ writel(dividers | PLL_BASE_ENABLE, base);
+
+ /* Wait for lock ready */
+ while (!(readl(base) & PLL_BASE_LOCK));
+}
+
+static void init_utmip_pll(void)
+{
+ int khz = clock_get_pll_input_khz();
+
+ /* Shut off PLL crystal clock while we mess with it */
+ clrbits_le32(&clk_rst->utmip_pll_cfg2, 1 << 30); /* PHY_XTAL_CLKEN */
+ udelay(1);
+
+ write32(80 << 16 | /* (rst) phy_divn */
+ 1 << 8 | /* (rst) phy_divm */
+ 0, &clk_rst->utmip_pll_cfg0); /* 960MHz * 1 / 80 == 12 MHz */
+
+ write32(div_round_up(khz, 8000) << 27 | /* pllu_enbl_cnt / 8 (1us) */
+ 0 << 16 | /* PLLU pwrdn */
+ 0 << 14 | /* pll_enable pwrdn */
+ 0 << 12 | /* pll_active pwrdn */
+ div_round_up(khz, 102) << 0 | /* phy_stbl_cnt / 256 (2.5ms) */
+ 0, &clk_rst->utmip_pll_cfg1);
+
+ /* TODO: TRM can't decide if actv is 5us or 10us, keep an eye on it */
+ write32(0 << 24 | /* SAMP_D/XDEV pwrdn */
+ div_round_up(khz, 3200) << 18 | /* phy_actv_cnt / 16 (5us) */
+ div_round_up(khz, 256) << 6 | /* pllu_stbl_cnt / 256 (1ms) */
+ 0 << 4 | /* SAMP_C/USB3 pwrdn */
+ 0 << 2 | /* SAMP_B/XHOST pwrdn */
+ 0 << 0 | /* SAMP_A/USBD pwrdn */
+ 0, &clk_rst->utmip_pll_cfg2);
+
+ setbits_le32(&clk_rst->utmip_pll_cfg2, 1 << 30); /* PHY_XTAL_CLKEN */
+}
+
+/* Graphics just has to be different. There's a few more bits we
+ * need to set in here, but it makes sense just to restrict all the
+ * special bits to this one function.
+ */
+static void graphics_pll(void)
+{
+ int osc = clock_get_osc_bits();
+ u32 *cfg = &clk_rst->plldp_ss_cfg;
+ /* the vendor code sets the dither bit (28)
+ * an undocumented bit (24)
+ * and clamp while we mess with it (22)
+ * Dither is pretty important to display port
+ * so we really do need to handle these bits.
+ * I'm not willing to not clamp it, even if
+ * it might "mostly work" with it not set,
+ * I don't want to find out in a few months
+ * that it is needed.
+ */
+ u32 scfg = (1<<28) | (1<<24) | (1<<22);
+ writel(scfg, cfg);
+ init_pll(&clk_rst->plldp_base, &clk_rst->plldp_misc,
+ osc_table[osc].plldp, PLLDPD2_MISC_LOCK_ENABLE);
+ /* leave dither and undoc bits set, release clamp */
+ scfg = (1<<28) | (1<<24);
+ writel(scfg, cfg);
+
+ /* disp1 will be set when panel information (pixel clock) is
+ * retrieved (clock_display).
+ */
+}
+
+/* Init PLLD clock source. */
+int
+clock_display(u32 frequency)
+{
+ /**
+ * plld (fo) = vco >> p, where 500MHz < vco < 1000MHz
+ * = (cf * n) >> p, where 1MHz < cf < 6MHz
+ * = ((ref / m) * n) >> p
+ *
+ * Iterate the possible values of p (3 bits, 2^7) to find out a minimum
+ * safe vco, then find best (m, n). since m has only 5 bits, we can
+ * iterate all possible values. Note Tegra 124 supports 11 bits for n,
+ * but our pll_fields has only 10 bits for n.
+ *
+ * Note values undershoot or overshoot target output frequency may not
+ * work if the values are not in "safe" range by panel specification.
+ */
+ struct pllpad_dividers plld = { 0 };
+ u32 ref = clock_get_pll_input_khz() * 1000, m, n, p = 0;
+ u32 cf, vco;
+ u32 diff, best_diff;
+ const u32 max_m = 1 << 5, max_n = 1 << 10, max_p = 1 << 3,
+ mhz = 1000 * 1000, min_vco = 500 * mhz, max_vco = 1000 * mhz,
+ min_cf = 1 * mhz, max_cf = 6 * mhz;
+
+ for (vco = frequency; vco < min_vco && p < max_p; p++)
+ vco <<= 1;
+
+ if (vco < min_vco || vco > max_vco) {
+ printk(BIOS_ERR, "%s: Cannot find out a supported VCO"
+ " for Frequency (%u).\n", __func__, frequency);
+ return -1;
+ }
+
+ plld.p = p;
+ best_diff = vco;
+
+ for (m = 1; m < max_m && best_diff; m++) {
+ cf = ref / m;
+ if (cf < min_cf)
+ break;
+ if (cf > max_cf)
+ continue;
+
+ n = vco / cf;
+ if (n >= max_n)
+ continue;
+
+ diff = vco - n * cf;
+ if (n + 1 < max_n && diff > cf / 2) {
+ n++;
+ diff = cf - diff;
+ }
+
+ if (diff >= best_diff)
+ continue;
+
+ best_diff = diff;
+ plld.m = m;
+ plld.n = n;
+ }
+
+ if (plld.n < 50)
+ plld.cpcon = 2;
+ else if (plld.n < 300)
+ plld.cpcon = 3;
+ else if (plld.n < 600)
+ plld.cpcon = 8;
+ else
+ plld.cpcon = 12;
+
+ if (best_diff) {
+ printk(BIOS_ERR, "%s: Failed to match output frequency %u, "
+ "best difference is %u.\n", __func__, frequency,
+ best_diff);
+ }
+
+ printk(BIOS_DEBUG, "%s: PLLD=%u ref=%u, m/n/p/cpcon=%u/%u/%u/%u\n",
+ __func__, (ref / plld.m * plld.n) >> plld.p, ref, plld.m, plld.n,
+ plld.p, plld.cpcon);
+
+ init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, plld,
+ (PLLUD_MISC_LOCK_ENABLE | PLLD_MISC_CLK_ENABLE));
+ return 0;
+}
+
+/* Initialize the UART and put it on CLK_M so we can use it during clock_init().
+ * Will later move it to PLLP in clock_config(). The divisor must be very small
+ * to accomodate 12KHz OSCs, so we override the 16.0 UART divider with the 15.1
+ * CLK_SOURCE divider to get more precision. (This might still not be enough for
+ * some OSCs... if you use 13KHz, be prepared to have a bad time.) The 1900 has
+ * been determined through trial and error (must lead to div 13 at 24MHz). */
+void clock_early_uart(void)
+{
+ write32(CLK_M << CLK_SOURCE_SHIFT | CLK_UART_DIV_OVERRIDE |
+ CLK_DIVIDER(TEGRA_CLK_M_KHZ, 1900), &clk_rst->clk_src_uarta);
+ setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_UARTA);
+ udelay(2);
+ clrbits_le32(&clk_rst->rst_dev_l, CLK_L_UARTA);
+}
+
+/* Enable output clock (CLK1~3) for external peripherals. */
+void clock_external_output(int clk_id)
+{
+ switch (clk_id) {
+ case 1:
+ setbits_le32(&pmc->clk_out_cntrl, 1 << 2);
+ break;
+ case 2:
+ setbits_le32(&pmc->clk_out_cntrl, 1 << 10);
+ break;
+ case 3:
+ setbits_le32(&pmc->clk_out_cntrl, 1 << 18);
+ break;
+ default:
+ printk(BIOS_CRIT, "ERROR: Unknown output clock id %d\n",
+ clk_id);
+ break;
+ }
+}
+
+/* Start PLLM for SDRAM. */
+void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90,
+ u32 ph135, u32 kvco, u32 kcp, u32 stable_time, u32 emc_source,
+ u32 same_freq)
+{
+ u32 misc1 = ((setup << PLLM_MISC1_SETUP_SHIFT) |
+ (ph45 << PLLM_MISC1_PD_LSHIFT_PH45_SHIFT) |
+ (ph90 << PLLM_MISC1_PD_LSHIFT_PH90_SHIFT) |
+ (ph135 << PLLM_MISC1_PD_LSHIFT_PH135_SHIFT)),
+ misc2 = ((kvco << PLLM_MISC2_KVCO_SHIFT) |
+ (kcp << PLLM_MISC2_KCP_SHIFT)),
+ base;
+
+ if (same_freq)
+ emc_source |= CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
+ else
+ emc_source &= ~CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
+
+ /*
+ * Note PLLM_BASE.PLLM_OUT1_RSTN must be in RESET_ENABLE mode, and
+ * PLLM_BASE.ENABLE must be in DISABLE state (both are the default
+ * values after coldboot reset).
+ */
+
+ writel(misc1, &clk_rst->pllm_misc1);
+ writel(misc2, &clk_rst->pllm_misc2);
+
+ /* PLLM.BASE needs BYPASS=0, different from general init_pll */
+ base = readl(&clk_rst->pllm_base);
+ base &= ~(PLLCMX_BASE_DIVN_MASK | PLLCMX_BASE_DIVM_MASK |
+ PLLM_BASE_DIVP_MASK | PLL_BASE_BYPASS);
+ base |= ((m << PLL_BASE_DIVM_SHIFT) | (n << PLL_BASE_DIVN_SHIFT) |
+ (p << PLL_BASE_DIVP_SHIFT));
+ writel(base, &clk_rst->pllm_base);
+
+ setbits_le32(&clk_rst->pllm_base, PLL_BASE_ENABLE);
+ /* stable_time is required, before we can start to check lock. */
+ udelay(stable_time);
+
+ while (!(readl(&clk_rst->pllm_base) & PLL_BASE_LOCK)) {
+ udelay(1);
+ }
+ /*
+ * After PLLM reports being locked, we have to delay 10us before
+ * enabling PLLM_OUT.
+ */
+ udelay(10);
+
+ /* Put OUT1 out of reset state (start to output). */
+ setbits_le32(&clk_rst->pllm_out, PLLM_OUT1_RSTN_RESET_DISABLE);
+
+ /* Enable and start MEM(MC) and EMC. */
+ clock_enable_clear_reset(0, CLK_H_MEM | CLK_H_EMC, 0, 0, 0, 0);
+ writel(emc_source, &clk_rst->clk_src_emc);
+ udelay(IO_STABILIZATION_DELAY);
+}
+
+void clock_cpu0_config_and_reset(void *entry)
+{
+ void * const evp_cpu_reset = (uint8_t *)TEGRA_EVP_BASE + 0x100;
+
+ write32(CONFIG_STACK_TOP, &maincpu_stack_pointer);
+ write32((uintptr_t)entry, &maincpu_entry_point);
+ write32((uintptr_t)&maincpu_setup, evp_cpu_reset);
+
+ /* Set active CPU cluster to G */
+ clrbits_le32(&flow->cluster_control, 1);
+
+ // Set up cclk_brst and divider.
+ write32((CRC_CCLK_BRST_POL_PLLX_OUT0 << 0) |
+ (CRC_CCLK_BRST_POL_PLLX_OUT0 << 4) |
+ (CRC_CCLK_BRST_POL_PLLX_OUT0 << 8) |
+ (CRC_CCLK_BRST_POL_PLLX_OUT0 << 12) |
+ (CRC_CCLK_BRST_POL_CPU_STATE_RUN << 28),
+ &clk_rst->cclk_brst_pol);
+ write32(CRC_SUPER_CCLK_DIVIDER_SUPER_CDIV_ENB,
+ &clk_rst->super_cclk_div);
+
+ // Enable the clocks for CPUs 0-3.
+ uint32_t cpu_cmplx_clr = read32(&clk_rst->clk_cpu_cmplx_clr);
+ cpu_cmplx_clr |= CRC_CLK_CLR_CPU0_STP | CRC_CLK_CLR_CPU1_STP |
+ CRC_CLK_CLR_CPU2_STP | CRC_CLK_CLR_CPU3_STP;
+ write32(cpu_cmplx_clr, &clk_rst->clk_cpu_cmplx_clr);
+
+ // Enable other CPU related clocks.
+ setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_CPU);
+ setbits_le32(&clk_rst->clk_out_enb_v, CLK_V_CPUG);
+ setbits_le32(&clk_rst->clk_out_enb_v, CLK_V_CPULP);
+
+ // Disable the reset on the non-CPU parts of the fast cluster.
+ write32(CRC_RST_CPUG_CLR_NONCPU,
+ &clk_rst->rst_cpug_cmplx_clr);
+ // Disable the various resets on the CPUs.
+ write32(CRC_RST_CPUG_CLR_CPU0 | CRC_RST_CPUG_CLR_CPU1 |
+ CRC_RST_CPUG_CLR_CPU2 | CRC_RST_CPUG_CLR_CPU3 |
+ CRC_RST_CPUG_CLR_DBG0 | CRC_RST_CPUG_CLR_DBG1 |
+ CRC_RST_CPUG_CLR_DBG2 | CRC_RST_CPUG_CLR_DBG3 |
+ CRC_RST_CPUG_CLR_CORE0 | CRC_RST_CPUG_CLR_CORE1 |
+ CRC_RST_CPUG_CLR_CORE2 | CRC_RST_CPUG_CLR_CORE3 |
+ CRC_RST_CPUG_CLR_CX0 | CRC_RST_CPUG_CLR_CX1 |
+ CRC_RST_CPUG_CLR_CX2 | CRC_RST_CPUG_CLR_CX3 |
+ CRC_RST_CPUG_CLR_L2 | CRC_RST_CPUG_CLR_PDBG,
+ &clk_rst->rst_cpug_cmplx_clr);
+
+ // Disable the reset on the non-CPU parts of the slow cluster.
+ write32(CRC_RST_CPULP_CLR_NONCPU,
+ &clk_rst->rst_cpulp_cmplx_clr);
+ // Disable the various resets on the LP CPU.
+ write32(CRC_RST_CPULP_CLR_CPU0 | CRC_RST_CPULP_CLR_DBG0 |
+ CRC_RST_CPULP_CLR_CORE0 | CRC_RST_CPULP_CLR_CX0 |
+ CRC_RST_CPULP_CLR_L2 | CRC_RST_CPULP_CLR_PDBG,
+ &clk_rst->rst_cpulp_cmplx_clr);
+}
+
+void clock_halt_avp(void)
+{
+ for (;;) {
+ write32(FLOW_EVENT_JTAG | FLOW_EVENT_LIC_IRQ |
+ FLOW_EVENT_GIC_IRQ | FLOW_MODE_WAITEVENT,
+ &flow->halt_cop_events);
+ }
+}
+
+void clock_init(void)
+{
+ u32 osc = clock_get_osc_bits();
+
+ /* Set PLLC dynramp_step A to 0x2b and B to 0xb (from U-Boot -- why? */
+ writel(0x2b << 17 | 0xb << 9, &clk_rst->pllc_misc2);
+
+ /* Max out the AVP clock before everything else (need PLLC for that). */
+ init_pll(&clk_rst->pllc_base, &clk_rst->pllc_misc,
+ osc_table[osc].pllc, PLLC_MISC_LOCK_ENABLE);
+
+ /* Typical ratios are 1:2:2 or 1:2:3 sclk:hclk:pclk (See: APB DMA
+ * features section in the TRM). */
+ write32(1 << HCLK_DIVISOR_SHIFT | 0 << PCLK_DIVISOR_SHIFT,
+ &clk_rst->clk_sys_rate); /* pclk = hclk = sclk/2 */
+ write32(CLK_DIVIDER(TEGRA_PLLC_KHZ, 300000) << PLL_OUT_RATIO_SHIFT |
+ PLL_OUT_CLKEN | PLL_OUT_RSTN, &clk_rst->pllc_out);
+ write32(SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT |
+ SCLK_SOURCE_PLLC_OUT1 << SCLK_RUN_SHIFT,
+ &clk_rst->sclk_brst_pol); /* sclk = 300 MHz */
+
+ /* Change the oscillator drive strength (from U-Boot -- why?) */
+ clrsetbits_le32(&clk_rst->osc_ctrl, OSC_XOFS_MASK,
+ OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT);
+
+ /*
+ * Ambiguous quote from u-boot. TODO: what's this mean?
+ * "should update same value in PMC_OSC_EDPD_OVER XOFS
+ * field for warmboot "
+ */
+ clrsetbits_le32(&pmc->osc_edpd_over, PMC_OSC_EDPD_OVER_XOFS_MASK,
+ OSC_DRIVE_STRENGTH << PMC_OSC_EDPD_OVER_XOFS_SHIFT);
+
+ /* Disable IDDQ for PLLX before we set it up (from U-Boot -- why?) */
+ clrbits_le32(&clk_rst->pllx_misc3, PLLX_IDDQ_MASK);
+
+ /* Set up PLLP_OUT(1|2|3|4) divisor to generate (9.6|48|102|204)MHz */
+ write32((CLK_DIVIDER(TEGRA_PLLP_KHZ, 9600) << PLL_OUT_RATIO_SHIFT |
+ PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT1_SHIFT |
+ (CLK_DIVIDER(TEGRA_PLLP_KHZ, 48000) << PLL_OUT_RATIO_SHIFT |
+ PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT2_SHIFT,
+ &clk_rst->pllp_outa);
+ write32((CLK_DIVIDER(TEGRA_PLLP_KHZ, 102000) << PLL_OUT_RATIO_SHIFT |
+ PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT3_SHIFT |
+ (CLK_DIVIDER(TEGRA_PLLP_KHZ, 204000) << PLL_OUT_RATIO_SHIFT |
+ PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT4_SHIFT,
+ &clk_rst->pllp_outb);
+
+ /* init pllx */
+ init_pll(&clk_rst->pllx_base, &clk_rst->pllx_misc,
+ osc_table[osc].pllx, PLLPAXS_MISC_LOCK_ENABLE);
+
+ /* init pllu */
+ init_pll(&clk_rst->pllu_base, &clk_rst->pllu_misc,
+ osc_table[osc].pllu, PLLUD_MISC_LOCK_ENABLE);
+
+ init_utmip_pll();
+ graphics_pll();
+}
+
+void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x)
+{
+ if (l) writel(l, &clk_rst->clk_enb_l_set);
+ if (h) writel(h, &clk_rst->clk_enb_h_set);
+ if (u) writel(u, &clk_rst->clk_enb_u_set);
+ if (v) writel(v, &clk_rst->clk_enb_v_set);
+ if (w) writel(w, &clk_rst->clk_enb_w_set);
+ if (x) writel(x, &clk_rst->clk_enb_x_set);
+
+ /* Give clocks time to stabilize. */
+ udelay(IO_STABILIZATION_DELAY);
+
+ if (l) writel(l, &clk_rst->rst_dev_l_clr);
+ if (h) writel(h, &clk_rst->rst_dev_h_clr);
+ if (u) writel(u, &clk_rst->rst_dev_u_clr);
+ if (v) writel(v, &clk_rst->rst_dev_v_clr);
+ if (w) writel(w, &clk_rst->rst_dev_w_clr);
+ if (x) writel(x, &clk_rst->rst_dev_x_clr);
+}
+
+void clock_reset_l(u32 bit)
+{
+ writel(bit, &clk_rst->rst_dev_l_set);
+ udelay(1);
+ writel(bit, &clk_rst->rst_dev_l_clr);
+}
+
+void clock_reset_h(u32 bit)
+{
+ writel(bit, &clk_rst->rst_dev_h_set);
+ udelay(1);
+ writel(bit, &clk_rst->rst_dev_h_clr);
+}
+
+void clock_reset_u(u32 bit)
+{
+ writel(bit, &clk_rst->rst_dev_u_set);
+ udelay(1);
+ writel(bit, &clk_rst->rst_dev_u_clr);
+}
+
+void clock_reset_v(u32 bit)
+{
+ writel(bit, &clk_rst->rst_dev_v_set);
+ udelay(1);
+ writel(bit, &clk_rst->rst_dev_v_clr);
+}
+
+void clock_reset_w(u32 bit)
+{
+ writel(bit, &clk_rst->rst_dev_w_set);
+ udelay(1);
+ writel(bit, &clk_rst->rst_dev_w_clr);
+}
+
+void clock_reset_x(u32 bit)
+{
+ writel(bit, &clk_rst->rst_dev_x_set);
+ udelay(1);
+ writel(bit, &clk_rst->rst_dev_x_clr);
+}
diff --git a/src/soc/nvidia/tegra132/flow.h b/src/soc/nvidia/tegra132/flow.h
new file mode 100644
index 0000000000..01dbc14208
--- /dev/null
+++ b/src/soc/nvidia/tegra132/flow.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TEGRA132_FLOW_H_
+#define _TEGRA132_FLOW_H_
+
+struct flow_ctlr {
+ u32 halt_cpu_events; /* offset 0x00 */
+ u32 halt_cop_events; /* offset 0x04 */
+ u32 cpu_csr; /* offset 0x08 */
+ u32 cop_csr; /* offset 0x0c */
+ u32 xrq_events; /* offset 0x10 */
+ u32 halt_cpu1_events; /* offset 0x14 */
+ u32 cpu1_csr; /* offset 0x18 */
+ u32 halt_cpu2_events; /* offset 0x1c */
+ u32 cpu2_csr; /* offset 0x20 */
+ u32 halt_cpu3_events; /* offset 0x24 */
+ u32 cpu3_csr; /* offset 0x28 */
+ u32 cluster_control; /* offset 0x2c */
+ u32 halt_cop1_events; /* offset 0x30 */
+ u32 halt_cop1_csr; /* offset 0x34 */
+ u32 cpu_pwr_csr; /* offset 0x38 */
+ u32 mpid; /* offset 0x3c */
+ u32 ram_repair; /* offset 0x40 */
+};
+check_member(flow_ctlr, ram_repair, 0x40);
+
+enum {
+ FLOW_MODE_SHIFT = 29,
+ FLOW_MODE_MASK = 0x7 << FLOW_MODE_SHIFT,
+
+ FLOW_MODE_NONE = 0 << FLOW_MODE_SHIFT,
+ FLOW_MODE_RUN_AND_INT = 1 << FLOW_MODE_SHIFT,
+ FLOW_MODE_WAITEVENT = 2 << FLOW_MODE_SHIFT,
+ FLOW_MODE_WAITEVENT_AND_INT = 3 << FLOW_MODE_SHIFT,
+ FLOW_MODE_STOP_UNTIL_IRQ = 4 << FLOW_MODE_SHIFT,
+ FLOW_MODE_STOP_UNTIL_IRQ_AND_INT = 5 << FLOW_MODE_SHIFT,
+ FLOW_MODE_STOP_UNTIL_EVENT_AND_IRQ = 6 << FLOW_MODE_SHIFT,
+};
+
+/* HALT_COP_EVENTS_0, 0x04 */
+enum {
+ FLOW_EVENT_GIC_FIQ = 1 << 8,
+ FLOW_EVENT_GIC_IRQ = 1 << 9,
+ FLOW_EVENT_LIC_FIQ = 1 << 10,
+ FLOW_EVENT_LIC_IRQ = 1 << 11,
+ FLOW_EVENT_IBF = 1 << 12,
+ FLOW_EVENT_IBE = 1 << 13,
+ FLOW_EVENT_OBF = 1 << 14,
+ FLOW_EVENT_OBE = 1 << 15,
+ FLOW_EVENT_XRQ_A = 1 << 16,
+ FLOW_EVENT_XRQ_B = 1 << 17,
+ FLOW_EVENT_XRQ_C = 1 << 18,
+ FLOW_EVENT_XRQ_D = 1 << 19,
+ FLOW_EVENT_SMP30 = 1 << 20,
+ FLOW_EVENT_SMP31 = 1 << 21,
+ FLOW_EVENT_X_RDY = 1 << 22,
+ FLOW_EVENT_SEC = 1 << 23,
+ FLOW_EVENT_MSEC = 1 << 24,
+ FLOW_EVENT_USEC = 1 << 25,
+ FLOW_EVENT_X32K = 1 << 26,
+ FLOW_EVENT_SCLK = 1 << 27,
+ FLOW_EVENT_JTAG = 1 << 28
+};
+
+#endif /* _TEGRA132_FLOW_H_ */
diff --git a/src/soc/nvidia/tegra132/include/soc/clock.h b/src/soc/nvidia/tegra132/include/soc/clock.h
index 5fc10c3ca4..6f69fefbc6 100644
--- a/src/soc/nvidia/tegra132/include/soc/clock.h
+++ b/src/soc/nvidia/tegra132/include/soc/clock.h
@@ -18,7 +18,12 @@
#ifndef __SOC_NVIDIA_TEGRA132_CLOCK_H__
#define __SOC_NVIDIA_TEGRA132_CLOCK_H__
+#include <arch/hlt.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <soc/nvidia/tegra132/clk_rst.h>
#include <stdint.h>
+#include <stdlib.h>
enum {
CLK_L_CPU = 0x1 << 0,
@@ -174,6 +179,7 @@ enum {
#define CLOCK_PLL_STABLE_DELAY_US 300
#define IO_STABILIZATION_DELAY (2)
+
/* Calculate clock fractional divider value from ref and target frequencies.
* This is for a U7.1 format. This is not well written up in the book and
* there have been some questions about this macro, so here we go.
@@ -195,7 +201,7 @@ enum {
* and voila, upper 7 bits are (ref/freq-1), and lowest bit is h. Since you
* will assign this to a u8, it gets nicely truncated for you.
*/
-#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / (FREQ)) - 2)
+#define CLK_DIVIDER(REF, FREQ) (div_round_up(((REF) * 2), (FREQ)) - 2)
/* Calculate clock frequency value from reference and clock divider value
* The discussion in the book is pretty lacking.
@@ -216,11 +222,23 @@ enum {
*/
#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / ((REG) + 2))
+static inline void _clock_set_div(u32 *reg, const char *name, u32 div,
+ u32 div_mask, u32 src)
+{
+ // The I2C and UART divisors are 16 bit while all the others are 8 bit.
+ // The I2C clocks are handled by the specialized macro below, but the
+ // UART clocks aren't. Don't use this function on UART clocks.
+ if (div & ~div_mask) {
+ printk(BIOS_ERR, "%s clock divisor overflow!", name);
+ hlt();
+ }
+ clrsetbits_le32(reg, CLK_SOURCE_MASK | CLK_DIVISOR_MASK,
+ src << CLK_SOURCE_SHIFT | div);
+}
+
#define clock_configure_irregular_source(device, src, freq, src_id) \
- clrsetbits_le32(&clk_rst->clk_src_##device, \
- CLK_SOURCE_MASK | CLK_DIVISOR_MASK, \
- src_id << CLK_SOURCE_SHIFT | \
- CLK_DIVIDER(TEGRA_##src##_KHZ, freq))
+ _clock_set_div(&clk_rst->clk_src_##device, #device, \
+ CLK_DIVIDER(TEGRA_##src##_KHZ, freq), 0xff, src_id)
/* Warning: Some devices just use different bits for the same sources for no
* apparent reason. *Always* double-check the TRM before trusting this macro. */
@@ -232,11 +250,12 @@ enum {
* We can deal with those here and make it easier to select what the actual
* bus frequency will be. The 0x19 value is the default divisor in the
* clk_divisor register in the controller, and 8 is just a magic number in the
- * documentation. Multiplying by 2 compensates for the different format of the
- * divisor.
+ * documentation.
*/
#define clock_configure_i2c_scl_freq(device, src, freq) \
- clock_configure_source(device, src, (freq) * (0x19 + 1) * 8 * 2)
+ _clock_set_div(&clk_rst->clk_src_##device, #device, \
+ div_round_up(TEGRA_##src##_KHZ, (freq) * (0x19 + 1) * 8) - 1, \
+ 0xffff, src)
enum clock_source { /* Careful: Not true for all sources, always check TRM! */
PLLP = 0,
@@ -259,6 +278,8 @@ enum clock_source { /* Careful: Not true for all sources, always check TRM! */
#define TEGRA_PLLU_KHZ (960000)
int clock_get_osc_khz(void);
+int clock_get_pll_input_khz(void);
+int clock_display(u32 frequency);
void clock_early_uart(void);
void clock_external_output(int clk_id);
void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90,
@@ -267,6 +288,12 @@ void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90,
void clock_cpu0_config_and_reset(void * entry);
void clock_halt_avp(void);
void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x);
+void clock_reset_l(u32 l);
+void clock_reset_h(u32 h);
+void clock_reset_u(u32 u);
+void clock_reset_v(u32 v);
+void clock_reset_w(u32 w);
+void clock_reset_x(u32 x);
void clock_init(void);
void clock_init_arm_generic_timer(void);
void sor_clock_stop(void);
diff --git a/src/soc/nvidia/tegra132/maincpu.S b/src/soc/nvidia/tegra132/maincpu.S
new file mode 100644
index 0000000000..898d821d7e
--- /dev/null
+++ b/src/soc/nvidia/tegra132/maincpu.S
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <arch/asm.h>
+
+ENTRY(maincpu_setup)
+ /*
+ * Set the cpu to System mode with IRQ and FIQ disabled. Prefetch/Data
+ * aborts may happen early and crash before the abort handlers are
+ * installed, but at least the problem will show up near the code that
+ * causes it.
+ */
+ msr cpsr, #0xdf
+
+ ldr sp, maincpu_stack_pointer
+ eor lr, lr
+ ldr r0, maincpu_entry_point
+ bx r0
+ENDPROC(maincpu_setup)
+
+ .align 2
+
+ .global maincpu_stack_pointer
+maincpu_stack_pointer:
+ .word 0
+
+ .global maincpu_entry_point
+maincpu_entry_point:
+ .word 0
diff --git a/src/soc/nvidia/tegra132/maincpu.h b/src/soc/nvidia/tegra132/maincpu.h
new file mode 100644
index 0000000000..1f795dfc66
--- /dev/null
+++ b/src/soc/nvidia/tegra132/maincpu.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __SOC_NVIDIA_TEGRA132_MAINCPU_H__
+#define __SOC_NVIDIA_TEGRA132_MAINCPU_H__
+
+#include <stdint.h>
+
+extern u32 maincpu_stack_pointer;
+extern u32 maincpu_entry_point;
+void maincpu_setup(void);
+
+#endif /* __SOC_NVIDIA_TEGRA132_MAINCPU_H__ */
diff --git a/src/soc/nvidia/tegra132/pinmux.h b/src/soc/nvidia/tegra132/pinmux.h
new file mode 100644
index 0000000000..2bed25381a
--- /dev/null
+++ b/src/soc/nvidia/tegra132/pinmux.h
@@ -0,0 +1,260 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __SOC_NVIDIA_TEGRA132_PINMUX_H__
+#define __SOC_NVIDIA_TEGRA132_PINMUX_H__
+
+#include <soc/nvidia/tegra/pinmux.h>
+#include <stdint.h>
+
+#define PINMUX_CONSTANTS(index, name, gpio, func0, func1, func2, func3) \
+ PINMUX_##name##_INDEX = index, \
+ PINMUX_##name##_FUNC_##func0 = 0, \
+ PINMUX_##name##_FUNC_##func1 = 1, \
+ PINMUX_##name##_FUNC_##func2 = 2, \
+ PINMUX_##name##_FUNC_##func3 = 3, \
+ PINMUX_GPIO_##gpio = PINMUX_##name##_INDEX
+
+enum {
+ PINMUX_CONSTANTS(0, ULPI_DATA0, O1, SPI3, HSI, UA3, ULPI),
+ PINMUX_CONSTANTS(1, ULPI_DATA1, O2, SPI3, HSI, UA3, ULPI),
+ PINMUX_CONSTANTS(2, ULPI_DATA2, O3, SPI3, HSI, UA3, ULPI),
+ PINMUX_CONSTANTS(3, ULPI_DATA3, O4, SPI3, HSI, UA3, ULPI),
+ PINMUX_CONSTANTS(4, ULPI_DATA4, O5, SPI2, HSI, UA3, ULPI),
+ PINMUX_CONSTANTS(5, ULPI_DATA5, O6, SPI2, HSI, UA3, ULPI),
+ PINMUX_CONSTANTS(6, ULPI_DATA6, O7, SPI2, HSI, UA3, ULPI),
+ PINMUX_CONSTANTS(7, ULPI_DATA7, O0, SPI2, HSI, UA3, ULPI),
+ PINMUX_CONSTANTS(8, ULPI_CLK, Y0, SPI1, SPI5, UD3, ULPI),
+ PINMUX_CONSTANTS(9, ULPI_DIR, Y1, SPI1, SPI5, UD3, ULPI),
+ PINMUX_CONSTANTS(10, ULPI_NXT, Y2, SPI1, SPI5, UD3, ULPI),
+ PINMUX_CONSTANTS(11, ULPI_STP, Y3, SPI1, SPI5, UD3, ULPI),
+ PINMUX_CONSTANTS(12, DAP3_FS, P0, I2S2, SPI5, DCA, DCB),
+ PINMUX_CONSTANTS(13, DAP3_DIN, P1, I2S2, SPI5, DCA, DCB),
+ PINMUX_CONSTANTS(14, DAP3_DOUT, P2, I2S2, SPI5, DCA, RES3),
+ PINMUX_CONSTANTS(15, DAP3_SCLK, P3, I2S2, SPI5, RES2, DCB),
+ PINMUX_CONSTANTS(16, GPIO_PV0, V0, RES0, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(17, GPIO_PV1, V1, RES0, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(18, SDMMC1_CLK, Z0, SDMMC1, CLK12M, RES2, RES3),
+ PINMUX_CONSTANTS(19, SDMMC1_CMD, Z1, SDMMC1, SPDIF, SPI4, UA3),
+ PINMUX_CONSTANTS(20, SDMMC1_DAT3, Y4, SDMMC1, SPDIF, SPI4, UA3),
+ PINMUX_CONSTANTS(21, SDMMC1_DAT2, Y5, SDMMC1, PWM0, SPI4, UA3),
+ PINMUX_CONSTANTS(22, SDMMC1_DAT1, Y6, SDMMC1, PWM1, SPI4, UA3),
+ PINMUX_CONSTANTS(23, SDMMC1_DAT0, Y7, SDMMC1, RES1, SPI4, UA3),
+ PINMUX_CONSTANTS(26, CLK2_OUT, W5, EXTPERIPH2, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(27, CLK2_REQ, CC5, DAP, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(68, HDMI_INT, N7, RES0, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(69, DDC_SCL, V4, I2C4, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(70, DDC_SDA, V5, I2C4, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(89, UART2_RXD, C3, IR3, SPDIF, UA3, SPI4),
+ PINMUX_CONSTANTS(90, UART2_TXD, C2, IR3, SPDIF, UA3, SPI4),
+ PINMUX_CONSTANTS(91, UART2_RTS_N, J6, UA3, UB3, NOR, SPI4),
+ PINMUX_CONSTANTS(92, UART2_CTS_N, J5, UA3, UB3, NOR, SPI4),
+ PINMUX_CONSTANTS(93, UART3_TXD, W6, UC3, RES1, NOR, SPI4),
+ PINMUX_CONSTANTS(94, UART3_RXD, W7, UC3, RES1, NOR, SPI4),
+ PINMUX_CONSTANTS(95, UART3_CTS_N, A1, UC3, SDMMC1, DTV, NOR),
+ PINMUX_CONSTANTS(96, UART3_RTS_N, C0, UC3, PWM0, DTV, NOR),
+ PINMUX_CONSTANTS(97, GPIO_PU0, U0, OWR, UA3, NOR, RES3),
+ PINMUX_CONSTANTS(98, GPIO_PU1, U1, RES0, UA3, NOR, RES3),
+ PINMUX_CONSTANTS(99, GPIO_PU2, U2, RES0, UA3, NOR, RES3),
+ PINMUX_CONSTANTS(100, GPIO_PU3, U3, PWM0, UA3, NOR, DCB),
+ PINMUX_CONSTANTS(101, GPIO_PU4, U4, PWM1, UA3, NOR, DCB),
+ PINMUX_CONSTANTS(102, GPIO_PU5, U5, PWM2, UA3, NOR, DCB),
+ PINMUX_CONSTANTS(103, GPIO_PU6, U6, PWM3, UA3, RES2, NOR),
+ PINMUX_CONSTANTS(104, GEN1_I2C_SDA, C5, I2C1, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(105, GEN1_I2C_SCL, C4, I2C1, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(106, DAP4_FS, P4, I2S3, NOR, DTV, RES3),
+ PINMUX_CONSTANTS(107, DAP4_DIN, P5, I2S3, NOR, RES2, RES3),
+ PINMUX_CONSTANTS(108, DAP4_DOUT, P6, I2S3, NOR, DTV, RES3),
+ PINMUX_CONSTANTS(109, DAP4_SCLK, P7, I2S3, NOR, RES2, RES3),
+ PINMUX_CONSTANTS(110, CLK3_OUT, EE0, EXTPERIPH3, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(111, CLK3_REQ, EE1, DEV3, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(112, GPIO_PC7, C7, RES0, RES1, NOR_WP_N, NOR_INT1),
+ PINMUX_CONSTANTS(113, GPIO_PI5, I5, SDMMC2, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(114, GPIO_PI7, I7, RES0, TRACE, NOR, DTV),
+ PINMUX_CONSTANTS(115, GPIO_PK0, K0, RES0, SDMMC3, NOR, SOC_THERM),
+ PINMUX_CONSTANTS(116, GPIO_PK1, K1, SDMMC2, TRACE, NOR, RES3),
+ PINMUX_CONSTANTS(117, GPIO_PJ0, J0, RES0, RES1, NOR, USB),
+ PINMUX_CONSTANTS(118, GPIO_PJ2, J2, RES0, RES1, NOR, SOC_THERM),
+ PINMUX_CONSTANTS(119, GPIO_PK3, K3, SDMMC2, TRACE, NOR, CCLA),
+ PINMUX_CONSTANTS(120, GPIO_PK4, K4, SDMMC2, RES1, NOR_AD22, NOR_INT1),
+ PINMUX_CONSTANTS(121, GPIO_PK2, K2, RES0, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(122, GPIO_PI3, I3, RES0, RES1, NOR, SPI4),
+ PINMUX_CONSTANTS(123, GPIO_PI6, I6, RES0, RES1, NOR, SDMMC2),
+ PINMUX_CONSTANTS(124, GPIO_PG0, G0, RES0, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(125, GPIO_PG1, G1, RES0, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(126, GPIO_PG2, G2, RES0, TRACE, NOR, RES3),
+ PINMUX_CONSTANTS(127, GPIO_PG3, G3, RES0, TRACE, NOR, RES3),
+ PINMUX_CONSTANTS(128, GPIO_PG4, G4, RES0, TMDS, NOR, SPI4),
+ PINMUX_CONSTANTS(129, GPIO_PG5, G5, RES0, RES1, NOR, SPI4),
+ PINMUX_CONSTANTS(130, GPIO_PG6, G6, RES0, RES1, NOR, SPI4),
+ PINMUX_CONSTANTS(131, GPIO_PG7, G7, RES0, RES1, NOR, SPI4),
+ PINMUX_CONSTANTS(132, GPIO_PH0, H0, PWM0, TRACE, NOR, DTV),
+ PINMUX_CONSTANTS(133, GPIO_PH1, H1, PWM1, TMDS, NOR, DCA),
+ PINMUX_CONSTANTS(134, GPIO_PH2, H2, PWM2, TDMS, NOR, CLDVFS),
+ PINMUX_CONSTANTS(135, GPIO_PH3, H3, PWM3, SPI4, NOR, CLDVFS),
+ PINMUX_CONSTANTS(136, GPIO_PH4, H4, SDMMC2, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(137, GPIO_PH5, H5, SDMMC2, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(138, GPIO_PH6, H6, SDMMC2, TRACE, NOR, DTV),
+ PINMUX_CONSTANTS(139, GPIO_PH7, H7, SDMMC2, TRACE, NOR, DTV),
+ PINMUX_CONSTANTS(140, GPIO_PJ7, J7, UD3, RES1, NOR_AD16, NOR_INT2),
+ PINMUX_CONSTANTS(141, GPIO_PB0, B0, UD3, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(142, GPIO_PB1, B1, UD3, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(143, GPIO_PK7, K7, UD3, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(144, GPIO_PI0, I0, RES0, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(145, GPIO_PI1, I1, RES0, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(146, GPIO_PI2, I2, SDMMC2, TRACE, NOR, RES3),
+ PINMUX_CONSTANTS(147, GPIO_PI4, I4, SPI4, TRACE, NOR, DCA),
+ PINMUX_CONSTANTS(148, GEN2_I2C_SCL, T5, I2C2, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(149, GEN2_I2C_SDA, T6, I2C2, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(150, SDMMC4_CLK, CC4, SDMMC4, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(151, SDMMC4_CMD, T7, SDMMC4, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(152, SDMMC4_DAT0, AA0, SDMMC4, SPI3, NOR, RES3),
+ PINMUX_CONSTANTS(153, SDMMC4_DAT1, AA1, SDMMC4, SPI3, NOR, RES3),
+ PINMUX_CONSTANTS(154, SDMMC4_DAT2, AA2, SDMMC4, SPI3, NOR, RES3),
+ PINMUX_CONSTANTS(155, SDMMC4_DAT3, AA3, SDMMC4, SPI3, NOR, RES3),
+ PINMUX_CONSTANTS(156, SDMMC4_DAT4, AA4, SDMMC4, SPI3, NOR, RES3),
+ PINMUX_CONSTANTS(157, SDMMC4_DAT5, AA5, SDMMC4, SPI3, RES2, RES3),
+ PINMUX_CONSTANTS(158, SDMMC4_DAT6, AA6, SDMMC4, SPI3, NOR, RES3),
+ PINMUX_CONSTANTS(159, SDMMC4_DAT7, AA7, SDMMC4, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(161, CAM_MCLK, CC0, VIMCLK_PRI, VIMCLK_ALT1,
+ VIMCLK_ALT3, SDMMC2),
+ PINMUX_CONSTANTS(162, GPIO_PCC1, CC1, I2S4, RES1, RES2, SDMMC2),
+ PINMUX_CONSTANTS(163, GPIO_PBB0, BB0, VGP6, VIMCLK2_PRI, SDMMC2,
+ VIMCLK2_ALT3),
+ PINMUX_CONSTANTS(164, CAM_I2C_SCL, BB1, VGP1, I2C3, RES2, SDMMC2),
+ PINMUX_CONSTANTS(165, CAM_I2C_SDA, BB2, VGP2, I2C3, RES2, SDMMC2),
+ PINMUX_CONSTANTS(166, GPIO_PBB3, BB3, VGP3, DCA, DCB, SDMMC2),
+ PINMUX_CONSTANTS(167, GPIO_PBB4, BB4, VGP4, DCA, DCB, SDMMC2),
+ PINMUX_CONSTANTS(168, GPIO_PBB5, BB5, VGP5, DCA, RES2, SDMMC2),
+ PINMUX_CONSTANTS(169, GPIO_PBB6, BB6, I2S4, RES1, DCB, SDMMC2),
+ PINMUX_CONSTANTS(170, GPIO_PBB7, BB7, I2S4, RES1, RES2, SDMMC2),
+ PINMUX_CONSTANTS(171, GPIO_PCC2, CC2, I2S4, RES1, SDMMC3, SDMMC2),
+ PINMUX_CONSTANTS(172, JTAG_RTCK, NONE172, RTCK, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(173, PWR_I2C_SCL, Z6, I2CPMU, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(174, PWR_I2C_SDA, Z7, I2CPMU, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(175, KB_ROW0, R0, RES0, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(176, KB_ROW1, R1, RES0, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(177, KB_ROW2, R2, RES0, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(178, KB_ROW3, R3, RES0, DCA, SYS_CLK, DCB),
+ PINMUX_CONSTANTS(179, KB_ROW4, R4, RES0, DCA, RES2, DCB),
+ PINMUX_CONSTANTS(180, KB_ROW5, R5, RES0, DCA, RES2, DCB),
+ PINMUX_CONSTANTS(181, KB_ROW6, R6, RES0, DCA_LSC0, DCA_LSPII, DCB),
+ PINMUX_CONSTANTS(182, KB_ROW7, R7, RES0, RES1, CLDVFS, UA3),
+ PINMUX_CONSTANTS(183, KB_ROW8, S0, RES0, RES1, CLDVFS, UA3),
+ PINMUX_CONSTANTS(184, KB_ROW9, S1, RES0, RES1, RES2, UA3),
+ PINMUX_CONSTANTS(185, KB_ROW10, S2, RES0, RES1, RES2, UA3),
+ PINMUX_CONSTANTS(186, KB_ROW11, S3, RES0, RES1, RES2, IR3),
+ PINMUX_CONSTANTS(187, KB_ROW12, S4, RES0, RES1, RES2, IR3),
+ PINMUX_CONSTANTS(188, KB_ROW13, S5, RES0, RES1, SPI2, RES3),
+ PINMUX_CONSTANTS(189, KB_ROW14, S6, RES0, RES1, SPI2, RES3),
+ PINMUX_CONSTANTS(190, KB_ROW15, S7, RES0, SOC_THERM, RES2, RES3),
+ PINMUX_CONSTANTS(191, KB_COL0, Q0, RES0, RES1, SPI2, RES3),
+ PINMUX_CONSTANTS(192, KB_COL1, Q1, RES0, RES1, SPI2, RES3),
+ PINMUX_CONSTANTS(193, KB_COL2, Q2, RES0, RES1, SPI2, RES3),
+ PINMUX_CONSTANTS(194, KB_COL3, Q3, RES0, DCA, PWM2, UA3),
+ PINMUX_CONSTANTS(195, KB_COL4, Q4, RES0, OWR, SDMMC3, UA3),
+ PINMUX_CONSTANTS(196, KB_COL5, Q5, RES0, RES1, SDMMC3, RES3),
+ PINMUX_CONSTANTS(197, KB_COL6, Q6, RES0, RES1, SPI2, UD3),
+ PINMUX_CONSTANTS(198, KB_COL7, Q7, RES0, RES1, SPI2, UD3),
+ PINMUX_CONSTANTS(199, CLK_32K_OUT, A0, BLINK, SOC_THERM, RES2, RES3),
+ PINMUX_CONSTANTS(201, CORE_PWR_REQ, NONE201, PWRON, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(202, CPU_PWR_REQ, NONE202, CPU, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(203, PWR_INT_N, NONE203, PMICINTR, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(204, CLK_32K_IN, NONE204, CLK_32K_IN, RES1, RES2,
+ RES3),
+ PINMUX_CONSTANTS(205, OWR, NONE205, OWR, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(206, DAP1_FS, N0, I2S0, DAP1, NOR, RES3),
+ PINMUX_CONSTANTS(207, DAP1_DIN, N1, I2S0, DAP1, NOR, RES3),
+ PINMUX_CONSTANTS(208, DAP1_DOUT, N2, I2S0, DAP1, NOR, SATA),
+ PINMUX_CONSTANTS(209, DAP1_SCLK, N3, I2S0, DAP1, NOR, RES3),
+ PINMUX_CONSTANTS(210, DAP_MCLK1_REQ, EE2, DAP, DAP1, SATA, RES3),
+ PINMUX_CONSTANTS(211, DAP_MCLK1, W4, EXTPERIPH1, DAP2, RES2, RES3),
+ PINMUX_CONSTANTS(212, SPDIF_IN, K6, SPDIF, RES1, RES2, I2C3),
+ PINMUX_CONSTANTS(213, SPDIF_OUT, K5, SPDIF, RES1, RES2, I2C3),
+ PINMUX_CONSTANTS(214, DAP2_FS, A2, I2S1, DAP2, NOR, RES3),
+ PINMUX_CONSTANTS(215, DAP2_DIN, A4, I2S1, DAP2, NOR, RES3),
+ PINMUX_CONSTANTS(216, DAP2_DOUT, A5, I2S1, DAP2, NOR, RES3),
+ PINMUX_CONSTANTS(217, DAP2_SCLK, A3, I2S1, SAP2, NOR, RES3),
+ PINMUX_CONSTANTS(218, DVFS_PWM, X0, SPI6, CLDVFS, NOR, RES3),
+ PINMUX_CONSTANTS(219, GPIO_X1_AUD, X1, SPI6, RES1, NOR, RES3),
+ PINMUX_CONSTANTS(220, GPIO_X3_AUD, X3, SPI6, SPI1, NOR, RES3),
+ PINMUX_CONSTANTS(221, DVFS_CLK, X2, SPI6, CLDVFS_CLK, NOR, RES3),
+ PINMUX_CONSTANTS(222, GPIO_X4_AUD, X4, NOR, SPI1, SPI2, DAP2),
+ PINMUX_CONSTANTS(223, GPIO_X5_AUD, X5, NOR, SPI1, SPI2, RES3),
+ PINMUX_CONSTANTS(224, GPIO_X6_AUD, X6, SPI6, SPI1, SPI2, NOR),
+ PINMUX_CONSTANTS(225, GPIO_X7_AUD, X7, RES0, SPI1, SPI2, RES3),
+ PINMUX_CONSTANTS(228, SDMMC3_CLK, A6, SDMMC3, RES1, RES2, SPI3),
+ PINMUX_CONSTANTS(229, SDMMC3_CMD, A7, SDMMC3, PWM3, UA3, SPI3),
+ PINMUX_CONSTANTS(230, SDMMC3_DAT0, B7, SDMMC3, RES1, RES2, SPI3),
+ PINMUX_CONSTANTS(231, SDMMC3_DAT1, B6, SDMMC3, PWM2, UA3, SPI3),
+ PINMUX_CONSTANTS(232, SDMMC3_DAT2, B5, SDMMC3, PWM1, DCA, SPI3),
+ PINMUX_CONSTANTS(233, SDMMC3_DAT3, B4, SDMMC3, PWM0, DCB, SPI3),
+ PINMUX_CONSTANTS(239, PEX_L0_RST_N, DD1, PE0, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(240, PEX_L0_CLKREQ_N, DD2, PE0, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(241, PEX_WAKE_N, DD3, PE, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(243, PEX_L1_RST_N, DD5, PE1, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(244, PEX_L1_CLKREQ_N, DD6, PE1, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(248, HDMI_CEC, EE3, CEC, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(249, SDMMC1_WP_N, V3, SDMMC1, CLK12M, SPI4, UA3),
+ PINMUX_CONSTANTS(250, SDMMC3_CD_N, V2, SDMMC3, OWR, RES2, RES3),
+ PINMUX_CONSTANTS(251, GPIO_W2_AUD, W2, SPI6, RES1, SPI2, I2C1),
+ PINMUX_CONSTANTS(252, GPIO_W3_AUD, W3, SPI6, SPI1, SPI2, I2C1),
+ PINMUX_CONSTANTS(253, USB_VBUS_EN0, N4, USB, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(254, USB_VBUS_EN1, N5, USB, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(255, SDMMC3_CLK_LB_IN, EE5, SDMMC3, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(256, SDMMC3_CLK_LB_OUT, EE4, SDMMC3, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(258, RESET_OUT_N, NONE258, RES0, RES1, RES2, RESET),
+ PINMUX_CONSTANTS(259, KB_ROW16, T0, RES0, RES1, RES2, UC3),
+ PINMUX_CONSTANTS(260, KB_ROW17, T1, RES0, RES1, RES2, UC3),
+ PINMUX_CONSTANTS(261, USB_VBUS_EN2, FF1, USB, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(262, GPIO_PFF2, FF2, SATA, RES1, RES2, RES3),
+ PINMUX_CONSTANTS(268, DP_HPD, FF0, DP, RES1, RES2, RES3),
+
+ // Where do these go?
+ /*
+ PINMUX_JTAG_TRST_N_JTAG_TRST_N = 0,
+
+ PINMUX_JTAG_TDO_JTAG_TDO = 0,
+
+ PINMUX_JTAG_TMS_JTAG_TMS = 0,
+
+ PINMUX_JTAG_TCK_JTAG_TCK = 0,
+ // What do functions 1 and 2 do?
+
+ PINMUX_JTAG_TDI_JTAG_TDI = 0,
+ PINMUX_JTAG_TDI_PWR_BREAK = 1,
+
+ PINMUX_TEST_MODE_EN_TEST_MODE_EN = 0,
+ PINMUX_TEST_MODE_EN_VIMCLK_PRI = 1,
+ PINMUX_TEST_MODE_EN_VIMCLK_ALT1 = 2,
+ PINMUX_TEST_MODE_EN_VIMCLK_ALT3 = 3,
+
+ PINMUX_DP_AUX_CH0_P_I2C_CLK = 0,
+ PINMUX_DP_AUX_CH0_P_SDMMC3_DAT3 = 1,
+ PINMUX_DP_AUX_CH0_P_PM3_PWM0 = 2,
+ PINMUX_DP_AUX_CH0_P_DCB_LPM0 = 3,
+
+ PINMUX_DP_AUX_CH0_N_I2C6_DAT = 0,
+ PINMUX_DP_AUX_CH0_N_SDMMC3_DAT2 = 1,
+ PINMUX_DP_AUX_CH0_N_PM3_PWM1 = 2,
+ PINMUX_DP_AUX_CH0_N_DCA_LPM0 = 3,
+ */
+};
+
+#endif /* __SOC_NVIDIA_TEGRA132_PINMUX_H__ */
diff --git a/src/soc/nvidia/tegra132/pmc.h b/src/soc/nvidia/tegra132/pmc.h
new file mode 100644
index 0000000000..e9fbcd602e
--- /dev/null
+++ b/src/soc/nvidia/tegra132/pmc.h
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2010 - 2013, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TEGRA132_PMC_H_
+#define _TEGRA132_PMC_H_
+
+#include <stdint.h>
+
+enum {
+ POWER_PARTID_CRAIL = 0,
+ POWER_PARTID_TD = 1,
+ POWER_PARTID_VE = 2,
+ POWER_PARTID_VDE = 4,
+ POWER_PARTID_L2C = 5,
+ POWER_PARTID_MPE = 6,
+ POWER_PARTID_HEG = 7,
+ POWER_PARTID_CE1 = 9,
+ POWER_PARTID_CE2 = 10,
+ POWER_PARTID_CE3 = 11,
+ POWER_PARTID_CELP = 12,
+ POWER_PARTID_CE0 = 14,
+ POWER_PARTID_C0NC = 15,
+ POWER_PARTID_C1NC = 16,
+ POWER_PARTID_DIS = 18,
+ POWER_PARTID_DISB = 19,
+ POWER_PARTID_XUSBA = 20,
+ POWER_PARTID_XUSBB = 21,
+ POWER_PARTID_XUSBC = 22
+};
+
+struct tegra_pmc_regs {
+ u32 cntrl;
+ u32 sec_disable;
+ u32 pmc_swrst;
+ u32 wake_mask;
+ u32 wake_lvl;
+ u32 wake_status;
+ u32 sw_wake_status;
+ u32 dpd_pads_oride;
+ u32 dpd_sample;
+ u32 dpd_enable;
+ u32 pwrgate_timer_off;
+ u32 clamp_status;
+ u32 pwrgate_toggle;
+ u32 remove_clamping_cmd;
+ u32 pwrgate_status;
+ u32 pwrgood_timer;
+ u32 blink_timer;
+ u32 no_iopower;
+ u32 pwr_det;
+ u32 pwr_det_latch;
+ u32 scratch0;
+ u32 scratch1;
+ u32 scratch2;
+ u32 scratch3;
+ u32 scratch4;
+ u32 scratch5;
+ u32 scratch6;
+ u32 scratch7;
+ u32 scratch8;
+ u32 scratch9;
+ u32 scratch10;
+ u32 scratch11;
+ u32 scratch12;
+ u32 scratch13;
+ u32 scratch14;
+ u32 scratch15;
+ u32 scratch16;
+ u32 scratch17;
+ u32 scratch18;
+ u32 scratch19;
+ u32 odmdata;
+ u32 scratch21;
+ u32 scratch22;
+ u32 scratch23;
+ u32 secure_scratch0;
+ u32 secure_scratch1;
+ u32 secure_scratch2;
+ u32 secure_scratch3;
+ u32 secure_scratch4;
+ u32 secure_scratch5;
+ u32 cpupwrgood_timer;
+ u32 cpupwroff_timer;
+ u32 pg_mask;
+ u32 pg_mask_1;
+ u32 auto_wake_lvl;
+ u32 auto_wake_lvl_mask;
+ u32 wake_delay;
+ u32 pwr_det_val;
+ u32 ddr_pwr;
+ u32 usb_debounce_del;
+ u32 usb_a0;
+ u32 crypto_op;
+ u32 pllp_wb0_override;
+ u32 scratch24;
+ u32 scratch25;
+ u32 scratch26;
+ u32 scratch27;
+ u32 scratch28;
+ u32 scratch29;
+ u32 scratch30;
+ u32 scratch31;
+ u32 scratch32;
+ u32 scratch33;
+ u32 scratch34;
+ u32 scratch35;
+ u32 scratch36;
+ u32 scratch37;
+ u32 scratch38;
+ u32 scratch39;
+ u32 scratch40;
+ u32 scratch41;
+ u32 scratch42;
+ u32 bondout_mirror[3];
+ u32 sys_33v_en;
+ u32 bondout_mirror_access;
+ u32 gate;
+ u32 wake2_mask;
+ u32 wake2_lvl;
+ u32 wake2_status;
+ u32 sw_wake2_status;
+ u32 auto_wake2_lvl_mask;
+ u32 pg_mask_2;
+ u32 pg_mask_ce1;
+ u32 pg_mask_ce2;
+ u32 pg_mask_ce3;
+ u32 pwrgate_timer_ce[7];
+ u32 pcx_edpd_cntrl;
+ u32 osc_edpd_over;
+ u32 clk_out_cntrl;
+ u32 sata_pwrgt;
+ u32 sensor_ctrl;
+ u32 rst_status;
+ u32 io_dpd_req;
+ u32 io_dpd_status;
+ u32 io_dpd2_req;
+ u32 io_dpd2_status;
+ u32 sel_dpd_tim;
+ u32 vddp_sel;
+ u32 ddr_cfg;
+ u32 e_no_vttgen;
+ u8 _rsv0[4];
+ u32 pllm_wb0_override_freq;
+ u32 test_pwrgate;
+ u32 pwrgate_timer_mult;
+ u32 dis_sel_dpd;
+ u32 utmip_uhsic_triggers;
+ u32 utmip_uhsic_saved_state;
+ u32 utmip_pad_cfg;
+ u32 utmip_term_pad_cfg;
+ u32 utmip_uhsic_sleep_cfg;
+ u32 utmip_uhsic_sleepwalk_cfg;
+ u32 utmip_sleepwalk_p[3];
+ u32 uhsic_sleepwalk_p0;
+ u32 utmip_uhsic_status;
+ u32 utmip_uhsic_fake;
+ u32 bondout_mirror3[5 - 3];
+ u32 secure_scratch6;
+ u32 secure_scratch7;
+ u32 scratch43;
+ u32 scratch44;
+ u32 scratch45;
+ u32 scratch46;
+ u32 scratch47;
+ u32 scratch48;
+ u32 scratch49;
+ u32 scratch50;
+ u32 scratch51;
+ u32 scratch52;
+ u32 scratch53;
+ u32 scratch54;
+ u32 scratch55;
+ u32 scratch0_eco;
+ u32 por_dpd_ctrl;
+ u32 scratch2_eco;
+ u32 utmip_uhsic_line_wakeup;
+ u32 utmip_bias_master_cntrl;
+ u32 utmip_master_config;
+ u32 td_pwrgate_inter_part_timer;
+ u32 utmip_uhsic2_triggers;
+ u32 utmip_uhsic2_saved_state;
+ u32 utmip_uhsic2_sleep_cfg;
+ u32 utmip_uhsic2_sleepwalk_cfg;
+ u32 uhsic2_sleepwalk_p1;
+ u32 utmip_uhsic2_status;
+ u32 utmip_uhsic2_fake;
+ u32 utmip_uhsic2_line_wakeup;
+ u32 utmip_master2_config;
+ u32 utmip_uhsic_rpd_cfg;
+ u32 pg_mask_ce0;
+ u32 pg_mask3[5 - 3];
+ u32 pllm_wb0_override2;
+ u32 tsc_mult;
+ u32 cpu_vsense_override;
+ u32 glb_amap_cfg;
+ u32 sticky_bits;
+ u32 sec_disable2;
+ u32 weak_bias;
+ u32 reg_short;
+ u32 pg_mask_andor;
+ u8 _rsv1[0x2c];
+ u32 secure_scratch8;
+ u32 secure_scratch9;
+ u32 secure_scratch10;
+ u32 secure_scratch11;
+ u32 secure_scratch12;
+ u32 secure_scratch13;
+ u32 secure_scratch14;
+ u32 secure_scratch15;
+ u32 secure_scratch16;
+ u32 secure_scratch17;
+ u32 secure_scratch18;
+ u32 secure_scratch19;
+ u32 secure_scratch20;
+ u32 secure_scratch21;
+ u32 secure_scratch22;
+ u32 secure_scratch23;
+ u32 secure_scratch24;
+ u32 secure_scratch25;
+ u32 secure_scratch26;
+ u32 secure_scratch27;
+ u32 secure_scratch28;
+ u32 secure_scratch29;
+ u32 secure_scratch30;
+ u32 secure_scratch31;
+ u32 secure_scratch32;
+ u32 secure_scratch33;
+ u32 secure_scratch34;
+ u32 secure_scratch35;
+ u8 _rsv2[0xd0];
+ u32 cntrl2;
+ u8 _rsv3[0x18];
+ u32 io_dpd3_req;
+ u32 io_dqd3_status;
+ u32 strapping_opt_a;
+ u8 _rsv4[0x198];
+ u32 scratch56;
+ u32 scratch57;
+ u32 scratch58;
+ u32 scratch59;
+ u32 scratch60;
+ u32 scratch61;
+ u32 scratch62;
+ u32 scratch63;
+ u32 scratch64;
+ u32 scratch65;
+ u32 scratch66;
+ u32 scratch67;
+ u32 scratch68;
+ u32 scratch69;
+ u32 scratch70;
+ u32 scratch71;
+ u32 scratch72;
+ u32 scratch73;
+ u32 scratch74;
+ u32 scratch75;
+ u32 scratch76;
+ u32 scratch77;
+ u32 scratch78;
+ u32 scratch79;
+ u32 scratch80;
+ u32 scratch81;
+ u32 scratch82;
+ u32 scratch83;
+ u32 scratch84;
+ u32 scratch85;
+ u32 scratch86;
+ u32 scratch87;
+ u32 scratch88;
+ u32 scratch89;
+ u32 scratch90;
+ u32 scratch91;
+ u32 scratch92;
+ u32 scratch93;
+ u32 scratch94;
+ u32 scratch95;
+ u32 scratch96;
+ u32 scratch97;
+ u32 scratch98;
+ u32 scratch99;
+ u32 scratch100;
+ u32 scratch101;
+ u32 scratch102;
+ u32 scratch103;
+ u32 scratch104;
+ u32 scratch105;
+ u32 scratch106;
+ u32 scratch107;
+ u32 scratch108;
+ u32 scratch109;
+ u32 scratch110;
+ u32 scratch111;
+ u32 scratch112;
+ u32 scratch113;
+ u32 scratch114;
+ u32 scratch115;
+ u32 scratch116;
+ u32 scratch117;
+ u32 scratch118;
+ u32 scratch119;
+};
+
+check_member(tegra_pmc_regs, scratch119, 0x6fc);
+
+enum {
+ PMC_PWRGATE_TOGGLE_PARTID_MASK = 0x1f,
+ PMC_PWRGATE_TOGGLE_PARTID_SHIFT = 0,
+ PMC_PWRGATE_TOGGLE_START = 0x1 << 8
+};
+
+enum {
+ PMC_CNTRL_KBC_CLK_DIS = 0x1 << 0,
+ PMC_CNTRL_RTC_CLK_DIS = 0x1 << 1,
+ PMC_CNTRL_RTC_RST = 0x1 << 2,
+ PMC_CNTRL_KBC_RST = 0x1 << 3,
+ PMC_CNTRL_MAIN_RST = 0x1 << 4,
+ PMC_CNTRL_LATCHWAKE_EN = 0x1 << 5,
+ PMC_CNTRL_GLITCHDET_DIS = 0x1 << 6,
+ PMC_CNTRL_BLINK_EN = 0x1 << 7,
+ PMC_CNTRL_PWRREQ_POLARITY = 0x1 << 8,
+ PMC_CNTRL_PWRREQ_OE = 0x1 << 9,
+ PMC_CNTRL_SYSCLK_POLARITY = 0x1 << 10,
+ PMC_CNTRL_SYSCLK_OE = 0x1 << 11,
+ PMC_CNTRL_PWRGATE_DIS = 0x1 << 12,
+ PMC_CNTRL_AOINIT = 0x1 << 13,
+ PMC_CNTRL_SIDE_EFFECT_LP0 = 0x1 << 14,
+ PMC_CNTRL_CPUPWRREQ_POLARITY = 0x1 << 15,
+ PMC_CNTRL_CPUPWRREQ_OE = 0x1 << 16,
+ PMC_CNTRL_INTR_POLARITY = 0x1 << 17,
+ PMC_CNTRL_FUSE_OVERRIDE = 0x1 << 18,
+ PMC_CNTRL_CPUPWRGOOD_EN = 0x1 << 19,
+ PMC_CNTRL_CPUPWRGOOD_SEL_SHIFT = 20,
+ PMC_CNTRL_CPUPWRGOOD_SEL_MASK =
+ 0x3 << PMC_CNTRL_CPUPWRGOOD_SEL_SHIFT
+};
+
+enum {
+ PMC_DDR_PWR_EMMC_MASK = 1 << 1,
+ PMC_DDR_PWR_VAL_MASK = 1 << 0,
+};
+
+enum {
+ PMC_DDR_CFG_PKG_MASK = 1 << 0,
+ PMC_DDR_CFG_IF_MASK = 1 << 1,
+ PMC_DDR_CFG_XM0_RESET_TRI_MASK = 1 << 12,
+ PMC_DDR_CFG_XM0_RESET_DPDIO_MASK = 1 << 13,
+};
+
+enum {
+ PMC_NO_IOPOWER_MEM_MASK = 1 << 7,
+ PMC_NO_IOPOWER_MEM_COMP_MASK = 1 << 16,
+};
+
+enum {
+ PMC_POR_DPD_CTRL_MEM0_ADDR0_CLK_SEL_DPD_MASK = 1 << 0,
+ PMC_POR_DPD_CTRL_MEM0_ADDR1_CLK_SEL_DPD_MASK = 1 << 1,
+ PMC_POR_DPD_CTRL_MEM0_HOLD_CKE_LOW_OVR_MASK = 1 << 31,
+};
+
+enum {
+ PMC_CNTRL2_HOLD_CKE_LOW_EN = 0x1 << 12
+};
+
+enum {
+ PMC_OSC_EDPD_OVER_XOFS_SHIFT = 1,
+ PMC_OSC_EDPD_OVER_XOFS_MASK =
+ 0x3f << PMC_OSC_EDPD_OVER_XOFS_SHIFT
+};
+
+enum {
+ PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT = 4,
+ PMC_STRAPPING_OPT_A_RAM_CODE_MASK =
+ 0xf << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT,
+};
+
+#endif /* _TEGRA132_PMC_H_ */
diff --git a/src/soc/nvidia/tegra132/power.h b/src/soc/nvidia/tegra132/power.h
new file mode 100644
index 0000000000..9283b5583a
--- /dev/null
+++ b/src/soc/nvidia/tegra132/power.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __SOC_NVIDIA_TEGRA132_POWER_H__
+#define __SOC_NVIDIA_TEGRA132_POWER_H__
+
+// This function does not enable the external power to the rail, it enables
+// the rail itself internal to the SOC.
+void power_enable_cpu_rail(void);
+
+void power_ungate_cpu(void);
+
+#endif /* __SOC_NVIDIA_TEGRA132_POWER_H__ */
diff --git a/src/soc/nvidia/tegra132/sysctr.h b/src/soc/nvidia/tegra132/sysctr.h
new file mode 100644
index 0000000000..ea9746ddf2
--- /dev/null
+++ b/src/soc/nvidia/tegra132/sysctr.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __SOC_NVIDIA_TEGRA132_SYSCTR_H__
+#define __SOC_NVIDIA_TEGRA132_SYSCTR_H__
+
+#include <stdint.h>
+
+enum {
+ SYSCTR_CNTCR_EN = 1 << 0,
+ SYSCTR_CNTCR_HDBG = 1 << 1,
+ SYSCTR_CNTCR_FCREQ = 1 << 8
+};
+
+struct sysctr_regs {
+ uint32_t cntcr;
+ uint32_t cntsr;
+ uint32_t cntcv0;
+ uint32_t cntcv1;
+ uint8_t _rsv0[0x10];
+ uint32_t cntfid0;
+ uint32_t cntfid1;
+ uint8_t _rsv1[0xfa8];
+ uint32_t counterid4;
+ uint32_t counterid5;
+ uint32_t counterid6;
+ uint32_t counterid7;
+ uint32_t counterid0;
+ uint32_t counterid1;
+ uint32_t counterid2;
+ uint32_t counterid3;
+ uint32_t counterid8;
+ uint32_t counterid9;
+ uint32_t counterid10;
+ uint32_t counterid11;
+};
+check_member(sysctr_regs, counterid11, 0xffc);
+
+#endif /* __SOC_NVIDIA_TEGRA132_SYSCTR_H__ */
diff --git a/src/soc/nvidia/tegra132/uart.c b/src/soc/nvidia/tegra132/uart.c
new file mode 100644
index 0000000000..80328af9bf
--- /dev/null
+++ b/src/soc/nvidia/tegra132/uart.c
@@ -0,0 +1,161 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/uart.h>
+#include <arch/io.h>
+#include <boot/coreboot_tables.h>
+#include <console/console.h> /* for __console definition */
+#include <stdint.h>
+#include <drivers/uart/uart8250reg.h>
+
+/*
+ * TODO: Use DRIVERS_UART_8250MEM driver instead.
+ * There is an issue in the IO call functions where x86 and ARM
+ * ordering is reversed. This 8250MEM driver uses the x86 convention.
+ * This driver can be replaced once the IO calls are sorted.
+ */
+struct tegra132_uart {
+ union {
+ uint32_t thr; // Transmit holding register.
+ uint32_t rbr; // Receive buffer register.
+ uint32_t dll; // Divisor latch lsb.
+ };
+ union {
+ uint32_t ier; // Interrupt enable register.
+ uint32_t dlm; // Divisor latch msb.
+ };
+ union {
+ uint32_t iir; // Interrupt identification register.
+ uint32_t fcr; // FIFO control register.
+ };
+ uint32_t lcr; // Line control register.
+ uint32_t mcr; // Modem control register.
+ uint32_t lsr; // Line status register.
+ uint32_t msr; // Modem status register.
+} __attribute__ ((packed));
+
+static void tegra132_uart_tx_flush(struct tegra132_uart *uart_ptr);
+static int tegra132_uart_tst_byte(struct tegra132_uart *uart_ptr);
+
+static void tegra132_uart_init(struct tegra132_uart *uart_ptr)
+{
+ const uint8_t line_config = UART8250_LCR_WLS_8; // 8n1
+
+ uint16_t divisor = (u16) uart_baudrate_divisor(default_baudrate(),
+ uart_platform_refclk(), 16);
+
+ tegra132_uart_tx_flush(uart_ptr);
+
+ // Disable interrupts.
+ write8(0, &uart_ptr->ier);
+ // Force DTR and RTS to high.
+ write8(UART8250_MCR_DTR | UART8250_MCR_RTS, &uart_ptr->mcr);
+ // Set line configuration, access divisor latches.
+ write8(UART8250_LCR_DLAB | line_config, &uart_ptr->lcr);
+ // Set the divisor.
+ write8(divisor & 0xff, &uart_ptr->dll);
+ write8((divisor >> 8) & 0xff, &uart_ptr->dlm);
+ // Hide the divisor latches.
+ write8(line_config, &uart_ptr->lcr);
+ // Enable FIFOs, and clear receive and transmit.
+ write8(UART8250_FCR_FIFO_EN |
+ UART8250_FCR_CLEAR_RCVR |
+ UART8250_FCR_CLEAR_XMIT, &uart_ptr->fcr);
+}
+
+static unsigned char tegra132_uart_rx_byte(struct tegra132_uart *uart_ptr)
+{
+ if (!tegra132_uart_tst_byte(uart_ptr))
+ return 0;
+ return read8(&uart_ptr->rbr);
+}
+
+static void tegra132_uart_tx_byte(struct tegra132_uart *uart_ptr, unsigned char data)
+{
+ while (!(read8(&uart_ptr->lsr) & UART8250_LSR_THRE));
+ write8(data, &uart_ptr->thr);
+}
+
+static void tegra132_uart_tx_flush(struct tegra132_uart *uart_ptr)
+{
+ while (!(read8(&uart_ptr->lsr) & UART8250_LSR_TEMT));
+}
+
+static int tegra132_uart_tst_byte(struct tegra132_uart *uart_ptr)
+{
+ return (read8(&uart_ptr->lsr) & UART8250_LSR_DR) == UART8250_LSR_DR;
+}
+
+/* FIXME: Add mainboard override */
+unsigned int uart_platform_refclk(void)
+{
+ return 408000000;
+}
+
+uintptr_t uart_platform_base(int idx)
+{
+ /* Default to UART A */
+ unsigned int base = 0x70006000;
+ /* UARTs A - E are mapped as index 0 - 4 */
+ if ((idx < 5) && (idx >= 0)) {
+ if (idx != 1) { /* Not UART B */
+ base += idx * 0x100;
+ } else {
+ base += 0x40;
+ }
+ }
+ return base;
+}
+
+void uart_init(int idx)
+{
+ struct tegra132_uart *uart_ptr = uart_platform_baseptr(idx);
+ tegra132_uart_init(uart_ptr);
+}
+
+unsigned char uart_rx_byte(int idx)
+{
+ struct tegra132_uart *uart_ptr = uart_platform_baseptr(idx);
+ return tegra132_uart_rx_byte(uart_ptr);
+}
+
+void uart_tx_byte(int idx, unsigned char data)
+{
+ struct tegra132_uart *uart_ptr = uart_platform_baseptr(idx);
+ tegra132_uart_tx_byte(uart_ptr, data);
+}
+
+void uart_tx_flush(int idx)
+{
+ struct tegra132_uart *uart_ptr = uart_platform_baseptr(idx);
+ tegra132_uart_tx_flush(uart_ptr);
+}
+
+#ifndef __PRE_RAM__
+void uart_fill_lb(void *data)
+{
+ struct lb_serial serial;
+ serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED;
+ serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
+ serial.baud = default_baudrate();
+ lb_add_serial(&serial, data);
+
+ lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data);
+}
+#endif