coreboot tegra132: Enable bootblock support in tegra132 including UART support

BUG=None
BRANCH=None
TEST=Compiles successfully

Change-Id: Ia9420cfec5333dd5477f04cf080bdad8a37db025
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://chromium-review.googlesource.com/203143
Tested-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Commit-Queue: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Furquan Shaikh 2014-06-09 13:20:04 -07:00 committed by chrome-internal-fetch
commit a1037f203c
15 changed files with 2528 additions and 9 deletions

View file

@ -5,9 +5,21 @@ config SOC_NVIDIA_TEGRA132
select ARCH_ROMSTAGE_ARM_V8_64
select ARCH_RAMSTAGE_ARM_V8_64
select ARM_LPAE
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
@ -20,4 +32,67 @@ config CBFS_ROM_OFFSET
hex "offset of CBFS data in ROM"
default 0x18080
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
choice CONSOLE_SERIAL_TEGRA132_UART_CHOICES
prompt "Serial Console UART"
default CONSOLE_SERIAL_UARTA
depends on CONSOLE_SERIAL_UART
config CONSOLE_SERIAL_UARTA
bool "UARTA"
help
Serial console on UART A.
config CONSOLE_SERIAL_UARTB
bool "UARTB"
help
Serial console on UART B.
config CONSOLE_SERIAL_UARTC
bool "UARTC"
help
Serial console on UART C.
config CONSOLE_SERIAL_UARTD
bool "UARTD"
help
Serial console on UART D.
config CONSOLE_SERIAL_UARTE
bool "UARTE"
help
Serial console on UART E.
endchoice
config CONSOLE_SERIAL_UART_ADDRESS
hex
depends on CONSOLE_SERIAL_UART
default 0x70006000 if CONSOLE_SERIAL_UARTA
default 0x70006040 if CONSOLE_SERIAL_UARTB
default 0x70006200 if CONSOLE_SERIAL_UARTC
default 0x70006300 if CONSOLE_SERIAL_UARTD
default 0x70006400 if CONSOLE_SERIAL_UARTE
help
Map the UART names to the respective MMIO addres.
endif

View file

@ -1,10 +1,33 @@
CBOOTIMAGE = cbootimage
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/i2c.c
bootblock-y += ../tegra/pingroup.c
bootblock-y += ../tegra/pinmux.c
bootblock-y += ../tegra/apbmisc.c
ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y)
bootblock-$(CONFIG_CONSOLE_SERIAL_UART) += uart.c
endif
romstage-y += cbfs.c
romstage-y += timer.c
romstage-y += ../tegra/gpio.c
romstage-y += ../tegra/i2c.c
romstage-y += ../tegra/pinmux.c
ifeq ($(CONFIG_EARLY_CONSOLE),y)
romstage-$(CONFIG_CONSOLE_SERIAL_UART) += uart.c
endif
ramstage-y += cbfs.c
ramstage-y += timer.c
ramstage-y += ../tegra/gpio.c
ramstage-y += ../tegra/i2c.c
ramstage-y += ../tegra/pinmux.c
ramstage-$(CONFIG_CONSOLE_SERIAL_UART) += uart.c
INCLUDES += -Isrc/soc/nvidia/tegra132/include/
INCLUDES += -Isrc/soc/nvidia/tegra132/include/

View file

@ -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");
}
}

View file

@ -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

View file

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

View file

@ -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);
}

View file

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

View file

@ -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);

View file

@ -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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,137 @@
/*
* 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 <uart.h>
#include <arch/io.h>
#include <console/console.h> /* for __console definition */
#include <stdint.h>
#include <uart8250.h>
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 struct tegra132_uart * const uart_ptr =
(void *)CONFIG_CONSOLE_SERIAL_UART_ADDRESS;
static void tegra132_uart_tx_flush(void);
static int tegra132_uart_tst_byte(void);
static void tegra132_uart_init(void)
{
// Use a hardcoded divisor for now.
const unsigned divisor = 221;
const uint8_t line_config = UART8250_LCR_WLS_8; // 8n1
tegra132_uart_tx_flush();
// 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 void tegra132_uart_tx_byte(unsigned char data)
{
while (!(read8(&uart_ptr->lsr) & UART8250_LSR_THRE));
write8(data, &uart_ptr->thr);
}
static void tegra132_uart_tx_flush(void)
{
while (!(read8(&uart_ptr->lsr) & UART8250_LSR_TEMT));
}
static unsigned char tegra132_uart_rx_byte(void)
{
if (!tegra132_uart_tst_byte())
return 0;
return read8(&uart_ptr->rbr);
}
static int tegra132_uart_tst_byte(void)
{
return (read8(&uart_ptr->lsr) & UART8250_LSR_DR) == UART8250_LSR_DR;
}
#if !defined(__PRE_RAM__)
static const struct console_driver tegra132_uart_console __console = {
.init = tegra132_uart_init,
.tx_byte = tegra132_uart_tx_byte,
.tx_flush = tegra132_uart_tx_flush,
.rx_byte = tegra132_uart_rx_byte,
.tst_byte = tegra132_uart_tst_byte,
};
uint32_t uartmem_getbaseaddr(void)
{
return (uintptr_t)uart_ptr;
}
#else
void uart_init(void)
{
tegra132_uart_init();
}
void uart_tx_byte(unsigned char data)
{
tegra132_uart_tx_byte(data);
}
void uart_tx_flush(void)
{
tegra132_uart_tx_flush();
}
unsigned char uart_rx_byte(void)
{
return tegra132_uart_rx_byte();
}
#endif