nvidia/tegra210: add new SoC
This includes Chrome OS downstream up to Change-Id: Ic89ed54c. Change-Id: I81853434600390d643160fe57554495b2bfe60ab Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Reviewed-on: http://review.coreboot.org/10633 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
7f641e68f2
commit
40a3e321d4
143
src/soc/nvidia/tegra210/Kconfig
Normal file
143
src/soc/nvidia/tegra210/Kconfig
Normal file
@ -0,0 +1,143 @@
|
||||
config SOC_NVIDIA_TEGRA210
|
||||
bool
|
||||
default n
|
||||
select ARCH_BOOTBLOCK_ARMV4
|
||||
select ARCH_VERSTAGE_ARMV4
|
||||
select ARCH_ROMSTAGE_ARMV4
|
||||
select ARCH_RAMSTAGE_ARMV8_64
|
||||
select ARCH_ARM64_CPU_CORTEX_A57
|
||||
select ARCH_ARM64_CORTEX_A57_POWER_DOWN_SUPPORT
|
||||
select BOOTBLOCK_CONSOLE
|
||||
select GIC
|
||||
select HAVE_MONOTONIC_TIMER
|
||||
select GENERIC_UDELAY
|
||||
select HAVE_HARD_RESET
|
||||
select HAVE_UART_SPECIAL
|
||||
select HAVE_UART_MEMORY_MAPPED
|
||||
select EARLY_CONSOLE
|
||||
select ARM_BOOTBLOCK_CUSTOM
|
||||
select DYNAMIC_CBMEM
|
||||
select ARM64_USE_ARM_TRUSTED_FIRMWARE
|
||||
select HAS_PRECBMEM_TIMESTAMP_REGION
|
||||
select CHROMEOS_RAMOOPS_NON_ACPI
|
||||
select GENERIC_GPIO_LIB
|
||||
|
||||
if SOC_NVIDIA_TEGRA210
|
||||
|
||||
config MAINBOARD_DO_DSI_INIT
|
||||
bool "Use dsi graphics interface"
|
||||
depends on MAINBOARD_DO_NATIVE_VGA_INIT
|
||||
default n
|
||||
help
|
||||
Initialize dsi display
|
||||
|
||||
config MAINBOARD_DO_SOR_INIT
|
||||
bool "Use dp graphics interface"
|
||||
depends on MAINBOARD_DO_NATIVE_VGA_INIT
|
||||
default n
|
||||
help
|
||||
Initialize dp display
|
||||
|
||||
config BOOTBLOCK_CPU_INIT
|
||||
string
|
||||
default "soc/nvidia/tegra210/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 MAX_CPUS
|
||||
int
|
||||
default 4
|
||||
|
||||
choice CONSOLE_SERIAL_TEGRA210_UART_CHOICES
|
||||
prompt "Serial Console UART"
|
||||
default CONSOLE_SERIAL_TEGRA210_UARTA
|
||||
depends on CONSOLE_SERIAL_UART
|
||||
|
||||
config CONSOLE_SERIAL_TEGRA210_UARTA
|
||||
bool "UARTA"
|
||||
help
|
||||
Serial console on UART A.
|
||||
|
||||
config CONSOLE_SERIAL_TEGRA210_UARTB
|
||||
bool "UARTB"
|
||||
help
|
||||
Serial console on UART B.
|
||||
|
||||
config CONSOLE_SERIAL_TEGRA210_UARTC
|
||||
bool "UARTC"
|
||||
help
|
||||
Serial console on UART C.
|
||||
|
||||
config CONSOLE_SERIAL_TEGRA210_UARTD
|
||||
bool "UARTD"
|
||||
help
|
||||
Serial console on UART D.
|
||||
|
||||
config CONSOLE_SERIAL_TEGRA210_UARTE
|
||||
bool "UARTE"
|
||||
help
|
||||
Serial console on UART E.
|
||||
|
||||
endchoice
|
||||
|
||||
config CONSOLE_SERIAL_TEGRA210_UART_ADDRESS
|
||||
hex
|
||||
depends on CONSOLE_SERIAL_UART
|
||||
default 0x70006000 if CONSOLE_SERIAL_TEGRA210_UARTA
|
||||
default 0x70006040 if CONSOLE_SERIAL_TEGRA210_UARTB
|
||||
default 0x70006200 if CONSOLE_SERIAL_TEGRA210_UARTC
|
||||
default 0x70006300 if CONSOLE_SERIAL_TEGRA210_UARTD
|
||||
default 0x70006400 if CONSOLE_SERIAL_TEGRA210_UARTE
|
||||
help
|
||||
Map the UART names to the respective MMIO addres.
|
||||
|
||||
config BOOTROM_SDRAM_INIT
|
||||
bool "SoC BootROM does SDRAM init with full BCT"
|
||||
default n
|
||||
help
|
||||
Use during Foster LPDDR4 bringup.
|
||||
|
||||
config TRUSTZONE_CARVEOUT_SIZE_MB
|
||||
hex "Size of Trust Zone region"
|
||||
default 0x14
|
||||
help
|
||||
Size of Trust Zone area in MiB to reserve in memory map.
|
||||
|
||||
# Default to 700MHz. This value is based on nv bootloader setting.
|
||||
config PLLX_KHZ
|
||||
int
|
||||
default 700000
|
||||
endif
|
||||
|
||||
config HAVE_MTC
|
||||
bool "Add external Memory controller Training Code binary"
|
||||
default n
|
||||
depends on USE_BLOBS
|
||||
help
|
||||
Select this option to add emc training firmware
|
||||
|
||||
if HAVE_MTC
|
||||
|
||||
config MTC_FILE
|
||||
string "tegra mtc firmware filename"
|
||||
default "tegra_mtc.bin"
|
||||
help
|
||||
The filename of the mtc firmware
|
||||
|
||||
config MTC_DIRECTORY
|
||||
string "Directory where MTC firmware file is located"
|
||||
default "."
|
||||
help
|
||||
Path to directory where MTC firmware file is located.
|
||||
|
||||
config MTC_ADDRESS
|
||||
hex
|
||||
default 0x81000000
|
||||
help
|
||||
The DRAM location where MTC firmware to be loaded in. This location
|
||||
needs to be consistent with the location defined in tegra_mtc.ld
|
||||
|
||||
endif # HAVE_MTC
|
||||
|
159
src/soc/nvidia/tegra210/Makefile.inc
Normal file
159
src/soc/nvidia/tegra210/Makefile.inc
Normal file
@ -0,0 +1,159 @@
|
||||
ifeq ($(CONFIG_SOC_NVIDIA_TEGRA210),y)
|
||||
|
||||
CBOOTIMAGE_OPTS = --soc tegra210
|
||||
|
||||
bootblock-y += bootblock.c
|
||||
bootblock-y += bootblock_asm.S
|
||||
bootblock-y += clock.c
|
||||
bootblock-y += spi.c
|
||||
bootblock-y += i2c.c
|
||||
bootblock-y += dma.c
|
||||
bootblock-y += monotonic_timer.c
|
||||
bootblock-y += padconfig.c
|
||||
bootblock-y += power.c
|
||||
bootblock-y += funitcfg.c
|
||||
bootblock-y += reset.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
|
||||
bootblock-y += ../tegra/usb.c
|
||||
ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y)
|
||||
bootblock-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
endif
|
||||
|
||||
verstage-y += verstage.c
|
||||
verstage-y += dma.c
|
||||
verstage-y += monotonic_timer.c
|
||||
verstage-y += spi.c
|
||||
verstage-y += padconfig.c
|
||||
verstage-y += funitcfg.c
|
||||
verstage-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
verstage-y += ../tegra/gpio.c
|
||||
verstage-y += ../tegra/i2c.c
|
||||
verstage-y += ../tegra/pinmux.c
|
||||
verstage-y += clock.c
|
||||
verstage-y += i2c.c
|
||||
|
||||
romstage-y += romstage_asm.S
|
||||
romstage-y += addressmap.c
|
||||
romstage-y += cbmem.c
|
||||
romstage-y += ccplex.c
|
||||
romstage-y += clock.c
|
||||
romstage-y += cpu.c
|
||||
romstage-y += reset.c
|
||||
romstage-y += spi.c
|
||||
romstage-y += i2c.c
|
||||
romstage-y += dma.c
|
||||
romstage-y += monotonic_timer.c
|
||||
romstage-y += padconfig.c
|
||||
romstage-y += funitcfg.c
|
||||
romstage-y += romstage.c
|
||||
romstage-y += power.c
|
||||
romstage-y += ram_code.c
|
||||
ifneq ($(CONFIG_BOOTROM_SDRAM_INIT),y)
|
||||
romstage-y += sdram.c
|
||||
ifeq ($(CONFIG_LP0_SUPPORT),y)
|
||||
romstage-y += sdram_lp0.c
|
||||
endif
|
||||
endif
|
||||
romstage-y += ../tegra/gpio.c
|
||||
romstage-y += ../tegra/i2c.c
|
||||
romstage-y += ../tegra/pinmux.c
|
||||
romstage-y += ../tegra/usb.c
|
||||
romstage-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
|
||||
ramstage-y += addressmap.c
|
||||
ramstage-y += cbmem.c
|
||||
ramstage-y += cpu.c
|
||||
ramstage-y += cpu_lib.S
|
||||
ramstage-y += clock.c
|
||||
ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += dc.c
|
||||
ramstage-$(CONFIG_MAINBOARD_DO_DSI_INIT) += dsi.c
|
||||
ramstage-$(CONFIG_MAINBOARD_DO_DSI_INIT) += mipi_dsi.c
|
||||
ramstage-$(CONFIG_MAINBOARD_DO_DSI_INIT) += mipi.c
|
||||
ramstage-$(CONFIG_MAINBOARD_DO_DSI_INIT) += mipi-phy.c
|
||||
ramstage-$(CONFIG_MAINBOARD_DO_DSI_INIT) += ./jdi_25x18_display/panel-jdi-lpm102a188a.c
|
||||
ramstage-$(CONFIG_MAINBOARD_DO_SOR_INIT) += dp.c
|
||||
ramstage-$(CONFIG_MAINBOARD_DO_SOR_INIT) += sor.c
|
||||
|
||||
ramstage-y += soc.c
|
||||
ramstage-y += spi.c
|
||||
ramstage-y += i2c.c
|
||||
ramstage-y += i2c6.c
|
||||
ramstage-y += ape.c
|
||||
ramstage-y += power.c
|
||||
ramstage-y += dma.c
|
||||
ramstage-y += gic.c
|
||||
ramstage-y += monotonic_timer.c
|
||||
ramstage-y += padconfig.c
|
||||
ramstage-y += funitcfg.c
|
||||
ramstage-y += reset.c
|
||||
ramstage-y += ram_code.c
|
||||
ramstage-y += ../tegra/apbmisc.c
|
||||
ramstage-y += ../tegra/gpio.c
|
||||
ramstage-y += ../tegra/i2c.c
|
||||
ramstage-y += ../tegra/pinmux.c
|
||||
ramstage-y += ramstage.c
|
||||
ramstage-y += mmu_operations.c
|
||||
ramstage-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
ramstage-y += ../tegra/usb.c
|
||||
ramstage-$(CONFIG_ARM64_USE_SECURE_MONITOR) += secmon.c
|
||||
ramstage-$(CONFIG_HAVE_MTC) += mtc.c
|
||||
|
||||
secmon-y += cpu.c
|
||||
secmon-y += cpu_lib.S
|
||||
secmon-y += flow_ctrl.c
|
||||
secmon-y += power.c
|
||||
secmon-y += psci.c
|
||||
secmon-y += reset_handler.S
|
||||
secmon-y += uart.c
|
||||
secmon-y += gic.c
|
||||
|
||||
rmodules_arm-y += monotonic_timer.c
|
||||
VBOOT_STUB_DEPS += $(obj)/soc/nvidia/tegra210/monotonic_timer.rmodules_arm.o
|
||||
|
||||
CPPFLAGS_common += -Isrc/soc/nvidia/tegra210/include/
|
||||
|
||||
# We want to grab the bootblock right before it goes into the image and wrap
|
||||
# it inside a BCT, but ideally we would do that without making special, one
|
||||
# use modifications to the main ARM Makefile. We do this in two ways. First,
|
||||
# we copy bootblock.elf to bootblock.raw.elf and allow the %.bin: %.elf
|
||||
# template rule to turn it into bootblock.raw.bin. This makes sure whatever
|
||||
# processing is supposed to happen to turn an .elf into a .bin happens.
|
||||
#
|
||||
# Second, we add our own rule for creating bootblock.bin from
|
||||
# bootblock.raw.bin which displaces the template rule. When other rules that
|
||||
# package up the image pull in bootblock.bin, it will be this wrapped version
|
||||
# instead of the raw bootblock.
|
||||
|
||||
$(objcbfs)/bootblock.raw.elf: $(objcbfs)/bootblock.elf
|
||||
cp $< $@
|
||||
|
||||
$(obj)/generated/bct.bin: $(obj)/generated/bct.cfg $(CBOOTIMAGE)
|
||||
@printf " CBOOTIMAGE $(subst $(obj)/,,$(@))\n"
|
||||
$(CBOOTIMAGE) -gbct $(CBOOTIMAGE_OPTS) $< $@
|
||||
|
||||
BCT_BIN = $(obj)/generated/bct.bin
|
||||
BCT_WRAPPER = $(obj)/generated/bct.wrapper
|
||||
$(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw.bin $(BCT_BIN)
|
||||
echo "Version = 1;" > $(BCT_WRAPPER)
|
||||
echo "Redundancy = 1;" >> $(BCT_WRAPPER)
|
||||
echo "Bctcopy = 1;" >> $(BCT_WRAPPER)
|
||||
echo "Bctfile = $(BCT_BIN);" >> $(BCT_WRAPPER)
|
||||
echo "BootLoader = $<,$(call loadaddr,bootblock),$(call loadaddr,bootblock),Complete;" >> $(BCT_WRAPPER)
|
||||
@printf " CBOOTIMAGE $(subst $(obj)/,,$(@))\n"
|
||||
$(CBOOTIMAGE) $(CBOOTIMAGE_OPTS) $(BCT_WRAPPER) $@
|
||||
|
||||
BL31_MAKEARGS += PLAT=tegra TARGET_SOC=t210
|
||||
|
||||
# MTC fw
|
||||
MTC_DIR = $(CONFIG_MTC_DIRECTORY)
|
||||
MTC_FILE = $(MTC_DIR)/$(CONFIG_MTC_FILE)
|
||||
MTC_FILE_CBFS = $(CONFIG_MTC_FILE)
|
||||
cbfs-files-$(CONFIG_HAVE_MTC) += $(MTC_FILE_CBFS)
|
||||
$(MTC_FILE_CBFS)-file := $(MTC_FILE)
|
||||
$(MTC_FILE_CBFS)-type := 0x50
|
||||
|
||||
endif
|
283
src/soc/nvidia/tegra210/addressmap.c
Normal file
283
src/soc/nvidia/tegra210/addressmap.c
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <arch/io.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/id.h>
|
||||
#include <soc/mc.h>
|
||||
#include <soc/sdram.h>
|
||||
#include <stdlib.h>
|
||||
#include <symbols.h>
|
||||
#include <soc/nvidia/tegra/types.h>
|
||||
|
||||
static uintptr_t tz_base_mib;
|
||||
static const size_t tz_size_mib = CONFIG_TRUSTZONE_CARVEOUT_SIZE_MB;
|
||||
|
||||
/* returns total amount of DRAM (in MB) from memory controller registers */
|
||||
int sdram_size_mb(void)
|
||||
{
|
||||
struct tegra_mc_regs *mc = (struct tegra_mc_regs *)TEGRA_MC_BASE;
|
||||
static int total_size = 0;
|
||||
|
||||
if (total_size)
|
||||
return total_size;
|
||||
|
||||
/*
|
||||
* This obtains memory size from the External Memory Aperture
|
||||
* Configuration register. Nvidia confirmed that it is safe to assume
|
||||
* this value represents the total physical DRAM size.
|
||||
*/
|
||||
total_size = (read32(&mc->emem_cfg) >>
|
||||
MC_EMEM_CFG_SIZE_MB_SHIFT) & MC_EMEM_CFG_SIZE_MB_MASK;
|
||||
|
||||
return total_size;
|
||||
}
|
||||
|
||||
static void carveout_from_regs(uintptr_t *base_mib, size_t *size_mib,
|
||||
uint32_t bom, uint32_t bom_hi, uint32_t size)
|
||||
{
|
||||
|
||||
/* All size regs of carveouts are in MiB. */
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
*size_mib = size;
|
||||
bom >>= 20;
|
||||
bom |= bom_hi << (32 - 20);
|
||||
|
||||
*base_mib = bom;
|
||||
}
|
||||
|
||||
void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib)
|
||||
{
|
||||
*base_mib = 0;
|
||||
*size_mib = 0;
|
||||
struct tegra_mc_regs * const mc = (struct tegra_mc_regs *)TEGRA_MC_BASE;
|
||||
size_t region_size_mb;
|
||||
|
||||
switch (id) {
|
||||
case CARVEOUT_TZ:
|
||||
*base_mib = tz_base_mib;
|
||||
*size_mib = tz_size_mib;
|
||||
break;
|
||||
case CARVEOUT_SEC:
|
||||
carveout_from_regs(base_mib, size_mib,
|
||||
read32(&mc->sec_carveout_bom),
|
||||
read32(&mc->sec_carveout_adr_hi),
|
||||
read32(&mc->sec_carveout_size_mb));
|
||||
break;
|
||||
case CARVEOUT_MTS:
|
||||
carveout_from_regs(base_mib, size_mib,
|
||||
read32(&mc->mts_carveout_bom),
|
||||
read32(&mc->mts_carveout_adr_hi),
|
||||
read32(&mc->mts_carveout_size_mb));
|
||||
break;
|
||||
case CARVEOUT_VPR:
|
||||
carveout_from_regs(base_mib, size_mib,
|
||||
read32(&mc->video_protect_bom),
|
||||
read32(&mc->video_protect_bom_adr_hi),
|
||||
read32(&mc->video_protect_size_mb));
|
||||
break;
|
||||
case CARVEOUT_GPU:
|
||||
/* These carveout regs use 128KB granularity - convert to MB */
|
||||
region_size_mb = DIV_ROUND_UP(read32(&mc->security_carveout2_size_128kb), 8);
|
||||
|
||||
/* BOM address set in gpu_region_init, below */
|
||||
carveout_from_regs(base_mib, size_mib,
|
||||
read32(&mc->security_carveout2_bom),
|
||||
read32(&mc->security_carveout2_bom_hi),
|
||||
region_size_mb);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void print_carveouts(void)
|
||||
{
|
||||
int i;
|
||||
printk(BIOS_INFO, "Carveout ranges:\n");
|
||||
for (i = 0; i < CARVEOUT_NUM; i++) {
|
||||
uintptr_t base, end;
|
||||
size_t size;
|
||||
carveout_range(i, &base, &size);
|
||||
end = base + size;
|
||||
if (end && base)
|
||||
printk(BIOS_INFO, "ID:%d [%lx - %lx)\n", i,
|
||||
(unsigned long)base * MiB,
|
||||
(unsigned long)end * MiB);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Memory Map is as follows
|
||||
*
|
||||
* ------------------------------ <-- Start of DRAM
|
||||
* | |
|
||||
* | Available DRAM |
|
||||
* |____________________________|
|
||||
* | |
|
||||
* | CBMEM |
|
||||
* |____________________________|
|
||||
* | |
|
||||
* | Other carveouts |
|
||||
* | (with dynamic allocation) |
|
||||
* |____________________________|
|
||||
* | |
|
||||
* | TZ carveout of size |
|
||||
* | TRUSTZONE_CARVEOUT_SIZE_MB |
|
||||
* |____________________________| <-- 0x100000000
|
||||
* | |
|
||||
* | Available DRAM |
|
||||
* | |
|
||||
* ------------------------------ <-- End of DRAM
|
||||
*
|
||||
*/
|
||||
static void memory_in_range(uintptr_t *base_mib, uintptr_t *end_mib,
|
||||
int ignore_carveout_id)
|
||||
{
|
||||
uintptr_t base;
|
||||
uintptr_t end;
|
||||
int i;
|
||||
|
||||
base = (uintptr_t)_dram / MiB;
|
||||
end = base + sdram_size_mb();
|
||||
|
||||
/* Requested limits out of range. */
|
||||
if (*end_mib <= base || *base_mib >= end) {
|
||||
*end_mib = *base_mib = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clip region to passed in limits. */
|
||||
if (*end_mib < end)
|
||||
end = *end_mib;
|
||||
if (*base_mib > base)
|
||||
base = *base_mib;
|
||||
|
||||
for (i = 0; i < CARVEOUT_NUM; i++) {
|
||||
uintptr_t carveout_base;
|
||||
uintptr_t carveout_end;
|
||||
size_t carveout_size;
|
||||
|
||||
if (i == ignore_carveout_id)
|
||||
continue;
|
||||
|
||||
carveout_range(i, &carveout_base, &carveout_size);
|
||||
|
||||
if (carveout_size == 0)
|
||||
continue;
|
||||
|
||||
carveout_end = carveout_base + carveout_size;
|
||||
|
||||
/* Bypass carveouts out of requested range. */
|
||||
if (carveout_base >= end || carveout_end <= base)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* This is crude, but the assumption is that carveouts live
|
||||
* at the upper range of physical memory. Therefore, update
|
||||
* the end address to be equal to the base of the carveout.
|
||||
*/
|
||||
end = carveout_base;
|
||||
}
|
||||
|
||||
*base_mib = base;
|
||||
*end_mib = end;
|
||||
}
|
||||
|
||||
void memory_in_range_below_4gb(uintptr_t *base_mib, uintptr_t *end_mib)
|
||||
{
|
||||
*base_mib = 0;
|
||||
*end_mib = 4096;
|
||||
memory_in_range(base_mib, end_mib, CARVEOUT_NUM);
|
||||
}
|
||||
|
||||
void memory_in_range_above_4gb(uintptr_t *base_mib, uintptr_t *end_mib)
|
||||
{
|
||||
*base_mib = 4096;
|
||||
*end_mib = ~0UL;
|
||||
memory_in_range(base_mib, end_mib, CARVEOUT_NUM);
|
||||
}
|
||||
|
||||
void trustzone_region_init(void)
|
||||
{
|
||||
struct tegra_mc_regs * const mc = (void *)(uintptr_t)TEGRA_MC_BASE;
|
||||
uintptr_t end = 4096;
|
||||
|
||||
/* Already has been initialized. */
|
||||
if (tz_size_mib != 0 && tz_base_mib != 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Get memory layout below 4GiB ignoring the TZ carveout because
|
||||
* that's the one to initialize.
|
||||
*/
|
||||
tz_base_mib = end - tz_size_mib;
|
||||
memory_in_range(&tz_base_mib, &end, CARVEOUT_TZ);
|
||||
|
||||
/*
|
||||
* IMPORTANT!!!!!
|
||||
* We need to ensure that trustzone region is located at the end of
|
||||
* 32-bit address space. If any carveout is allocated space before
|
||||
* trustzone_region_init is called, then this assert will ensure that
|
||||
* the boot flow fails. If you are here because of this assert, please
|
||||
* move your call to initialize carveout after trustzone_region_init in
|
||||
* romstage and ramstage.
|
||||
*/
|
||||
assert(end == 4096);
|
||||
|
||||
/* AVP cannot set the TZ registers proper as it is always non-secure. */
|
||||
if (context_avp())
|
||||
return;
|
||||
|
||||
/* Set the carveout region. */
|
||||
write32(&mc->security_cfg0, tz_base_mib << 20);
|
||||
write32(&mc->security_cfg1, tz_size_mib);
|
||||
|
||||
/* Enable SMMU translations */
|
||||
write32(&mc->smmu_config, MC_SMMU_CONFIG_ENABLE);
|
||||
}
|
||||
|
||||
void gpu_region_init(void)
|
||||
{
|
||||
struct tegra_mc_regs * const mc = (void *)(uintptr_t)TEGRA_MC_BASE;
|
||||
uintptr_t gpu_base_mib = 0, end = 4096;
|
||||
size_t gpu_size_mib = GPU_CARVEOUT_SIZE_MB;
|
||||
|
||||
/* Get memory layout below 4GiB */
|
||||
memory_in_range(&gpu_base_mib, &end, CARVEOUT_GPU);
|
||||
gpu_base_mib = end - gpu_size_mib;
|
||||
|
||||
/* Set the carveout2 base address. Everything else has been set in the BCT cfg/inc */
|
||||
write32(&mc->security_carveout2_bom, gpu_base_mib << 20);
|
||||
write32(&mc->security_carveout2_bom_hi, 0);
|
||||
|
||||
/* Set the locked bit. This will lock out any other writes! */
|
||||
setbits_le32(&mc->security_carveout2_cfg0, MC_SECURITY_CARVEOUT_LOCKED);
|
||||
|
||||
/* Set the carveout3 base to 0, unused */
|
||||
write32(&mc->security_carveout3_bom, 0);
|
||||
write32(&mc->security_carveout3_bom_hi, 0);
|
||||
|
||||
/* Set the locked bit. This will lock out any other writes! */
|
||||
setbits_le32(&mc->security_carveout3_cfg0, MC_SECURITY_CARVEOUT_LOCKED);
|
||||
}
|
55
src/soc/nvidia/tegra210/ape.c
Normal file
55
src/soc/nvidia/tegra210/ape.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (c) 2015, NVIDIA CORPORATION.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <delay.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clk_rst.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/padconfig.h>
|
||||
#include <soc/power.h>
|
||||
|
||||
static void enable_ape_periph_clocks(void)
|
||||
{
|
||||
clock_enable(0, 0, 0, CLK_V_APB2APE, 0, 0, CLK_Y_APE);
|
||||
|
||||
/* Give clocks time to stabilize. */
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
}
|
||||
|
||||
static void unreset_ape_periphs(void)
|
||||
{
|
||||
clock_clr_reset(0, 0, 0, CLK_V_APB2APE, 0, 0, CLK_Y_APE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Audio on Tegra210 requires some special init.
|
||||
* The APE block must be unpowergated, and a couple of
|
||||
* audio-based peripherals must be clocked and taken
|
||||
* out of reset so that I2S/AXBAR/APB2APE registers can
|
||||
* be configured to enable audio flow.
|
||||
*/
|
||||
|
||||
void soc_configure_ape(void)
|
||||
{
|
||||
power_ungate_partition(POWER_PARTID_APE);
|
||||
|
||||
enable_ape_periph_clocks();
|
||||
remove_clamps(POWER_PARTID_APE);
|
||||
unreset_ape_periphs();
|
||||
}
|
97
src/soc/nvidia/tegra210/bootblock.c
Normal file
97
src/soc/nvidia/tegra210/bootblock.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/exception.h>
|
||||
#include <arch/hlt.h>
|
||||
#include <bootblock_common.h>
|
||||
#include <console/console.h>
|
||||
#include <program_loading.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/nvidia/tegra/apbmisc.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/power.h>
|
||||
#include <timestamp.h>
|
||||
|
||||
#define BCT_OFFSET_IN_BIT 0x50
|
||||
#define ODMDATA_OFFSET_IN_BCT 0x6A8
|
||||
#define TEGRA_SRAM_MAX (TEGRA_SRAM_BASE + TEGRA_SRAM_SIZE)
|
||||
|
||||
static void save_odmdata(void)
|
||||
{
|
||||
struct tegra_pmc_regs *pmc = (struct tegra_pmc_regs*)TEGRA_PMC_BASE;
|
||||
uintptr_t bct_offset;
|
||||
u32 odmdata;
|
||||
|
||||
// pmc.odmdata: [18:19]: console type, [15:17]: UART id.
|
||||
// TODO(twarren) ODMDATA is stored in the BCT, from bct/odmdata.cfg.
|
||||
// I use the BCT offset in the BIT in SRAM to locate the BCT, and
|
||||
// pick up the ODMDATA word at BCT offset 0x6A8. I could use a BCT
|
||||
// struct header from cbootimage, but it seems like overkill for this.
|
||||
|
||||
bct_offset = read32((void *)(TEGRA_SRAM_BASE + BCT_OFFSET_IN_BIT));
|
||||
if (bct_offset > TEGRA_SRAM_BASE && bct_offset < TEGRA_SRAM_MAX) {
|
||||
odmdata = read32((void *)(bct_offset + ODMDATA_OFFSET_IN_BCT));
|
||||
write32(&pmc->odmdata, odmdata);
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__((weak)) bootblock_mainboard_early_init(void)
|
||||
{
|
||||
/* Empty default implementation. */
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// enable JTAG at the earliest stage
|
||||
enable_jtag();
|
||||
|
||||
clock_early_uart();
|
||||
|
||||
/* Configure mselect clock. */
|
||||
clock_configure_source(mselect, PLLP, 102000);
|
||||
|
||||
/* Enable AVP cache, timer, APB dma, and mselect blocks. */
|
||||
clock_enable_clear_reset(CLK_L_CACHE2 | CLK_L_TMR,
|
||||
CLK_H_APBDMA,
|
||||
0, CLK_V_MSELECT, 0, 0, 0);
|
||||
|
||||
/* Find ODMDATA in IRAM and save it to scratch reg */
|
||||
save_odmdata();
|
||||
|
||||
bootblock_mainboard_early_init();
|
||||
|
||||
if (CONFIG_BOOTBLOCK_CONSOLE) {
|
||||
console_init();
|
||||
exception_init();
|
||||
printk(BIOS_INFO, "T210: Bootblock here\n");
|
||||
}
|
||||
|
||||
clock_init();
|
||||
|
||||
printk(BIOS_INFO, "T210 bootblock: Clock init done\n");
|
||||
|
||||
pmc_print_rst_status();
|
||||
|
||||
bootblock_mainboard_init();
|
||||
|
||||
printk(BIOS_INFO, "T210 bootblock: Mainboard bootblock init done\n");
|
||||
|
||||
run_romstage();
|
||||
}
|
45
src/soc/nvidia/tegra210/bootblock_asm.S
Normal file
45
src/soc/nvidia/tegra210/bootblock_asm.S
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/asm.h>
|
||||
|
||||
#include "stack.S"
|
||||
|
||||
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
|
||||
|
||||
stack_init stack_top=_estack stack_bottom=_stack seed=1 func=main
|
||||
ENDPROC(_start)
|
40
src/soc/nvidia/tegra210/cbmem.c
Normal file
40
src/soc/nvidia/tegra210/cbmem.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <cbmem.h>
|
||||
#include <soc/addressmap.h>
|
||||
|
||||
void *cbmem_top(void)
|
||||
{
|
||||
static uintptr_t addr;
|
||||
|
||||
if (addr == 0) {
|
||||
uintptr_t begin_mib;
|
||||
uintptr_t end_mib;
|
||||
|
||||
memory_in_range_below_4gb(&begin_mib, &end_mib);
|
||||
/* Make sure we consume everything up to 4GIB. */
|
||||
if (end_mib == 4096)
|
||||
addr = ~(uint32_t)0;
|
||||
else
|
||||
addr = end_mib << 20;
|
||||
}
|
||||
|
||||
return (void *)addr;
|
||||
}
|
122
src/soc/nvidia/tegra210/ccplex.c
Normal file
122
src/soc/nvidia/tegra210/ccplex.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <cbfs.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/clk_rst.h>
|
||||
#include <soc/ccplex.h>
|
||||
#include <soc/cpu.h>
|
||||
#include <soc/flow.h>
|
||||
#include <soc/mc.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/power.h>
|
||||
#include <soc/romstage.h>
|
||||
#include <string.h>
|
||||
#include <timer.h>
|
||||
|
||||
#define PMC_REGS (void *)(uintptr_t)(TEGRA_PMC_BASE)
|
||||
|
||||
static void enable_cpu_clocks(void)
|
||||
{
|
||||
clock_enable(CLK_ENB_CPU, 0, 0, SET_CLK_ENB_CPUG_ENABLE |
|
||||
SET_CLK_ENB_CPULP_ENABLE, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void enable_cpu_power_partitions(void)
|
||||
{
|
||||
/* Bring up fast cluster, non-CPU, CPU0, CPU1, CPU2 and CPU3 parts. */
|
||||
power_ungate_partition(POWER_PARTID_CRAIL);
|
||||
power_ungate_partition(POWER_PARTID_C0NC);
|
||||
power_ungate_partition(POWER_PARTID_CE0);
|
||||
if (IS_ENABLED(CONFIG_ARM64_USE_SECURE_MONITOR)) {
|
||||
power_ungate_partition(POWER_PARTID_CE1);
|
||||
power_ungate_partition(POWER_PARTID_CE2);
|
||||
power_ungate_partition(POWER_PARTID_CE3);
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE)) {
|
||||
/*
|
||||
* Deassert reset signal of all the secondary CPUs.
|
||||
* PMC and flow controller will take over the power sequence
|
||||
* controller in the ATF.
|
||||
*/
|
||||
uint32_t reg = CRC_RST_CPUG_CLR_CPU1 | CRC_RST_CPUG_CLR_DBG1 |
|
||||
CRC_RST_CPUG_CLR_CORE1 | CRC_RST_CPUG_CLR_CX1 |
|
||||
CRC_RST_CPUG_CLR_CPU2 | CRC_RST_CPUG_CLR_DBG2 |
|
||||
CRC_RST_CPUG_CLR_CORE2 | CRC_RST_CPUG_CLR_CX2 |
|
||||
CRC_RST_CPUG_CLR_CPU3 | CRC_RST_CPUG_CLR_DBG3 |
|
||||
CRC_RST_CPUG_CLR_CORE3 | CRC_RST_CPUG_CLR_CX3;
|
||||
write32(CLK_RST_REG(rst_cpug_cmplx_clr), reg);
|
||||
}
|
||||
}
|
||||
|
||||
static void request_ram_repair(void)
|
||||
{
|
||||
struct flow_ctlr * const flow = (void *)(uintptr_t)TEGRA_FLOW_BASE;
|
||||
const uint32_t req = 1 << 0;
|
||||
const uint32_t sts = 1 << 1;
|
||||
uint32_t reg;
|
||||
struct stopwatch sw;
|
||||
|
||||
printk(BIOS_DEBUG, "Requesting RAM repair.\n");
|
||||
|
||||
stopwatch_init(&sw);
|
||||
|
||||
/* Perform ram repair */
|
||||
reg = read32(&flow->ram_repair);
|
||||
reg |= req;
|
||||
write32(&flow->ram_repair, reg);
|
||||
while ((read32(&flow->ram_repair) & sts) != sts)
|
||||
;
|
||||
|
||||
printk(BIOS_DEBUG, "RAM repair complete in %ld usecs.\n",
|
||||
stopwatch_duration_usecs(&sw));
|
||||
}
|
||||
|
||||
void ccplex_cpu_prepare(void)
|
||||
{
|
||||
enable_cpu_clocks();
|
||||
enable_cpu_power_partitions();
|
||||
|
||||
mainboard_configure_pmc();
|
||||
mainboard_enable_vdd_cpu();
|
||||
|
||||
request_ram_repair();
|
||||
}
|
||||
|
||||
static void start_common_clocks(void)
|
||||
{
|
||||
/* Clear fast CPU partition reset. */
|
||||
write32(CLK_RST_REG(rst_cpug_cmplx_clr), CRC_RST_CPUG_CLR_NONCPU);
|
||||
|
||||
/* Clear reset of L2 and CoreSight components. */
|
||||
write32(CLK_RST_REG(rst_cpug_cmplx_clr),
|
||||
CRC_RST_CPUG_CLR_L2 | CRC_RST_CPUG_CLR_PDBG);
|
||||
}
|
||||
|
||||
void ccplex_cpu_start(void *entry_addr)
|
||||
{
|
||||
/* Enable common clocks for the shared resources between the cores. */
|
||||
start_common_clocks();
|
||||
|
||||
start_cpu(0, entry_addr);
|
||||
}
|
99
src/soc/nvidia/tegra210/chip.h
Normal file
99
src/soc/nvidia/tegra210/chip.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_CHIP_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_CHIP_H__
|
||||
#include <soc/addressmap.h>
|
||||
#include <stdint.h>
|
||||
#include <soc/nvidia/tegra/dc.h>
|
||||
|
||||
struct soc_nvidia_tegra210_config {
|
||||
/* Address to monitor if spintable employed. */
|
||||
uintptr_t spintable_addr;
|
||||
|
||||
/*
|
||||
* panel resolution
|
||||
* The two parameters below provides dc about panel spec.
|
||||
*/
|
||||
u32 xres; /* the width of H display active area */
|
||||
u32 yres; /* the height of V display active area */
|
||||
u32 framebuffer_bits_per_pixel;
|
||||
u32 color_depth; /* color format */
|
||||
|
||||
u64 display_controller; /* dc block base address */
|
||||
u32 framebuffer_base;
|
||||
|
||||
/*
|
||||
* Technically, we can compute this. At the same time, some platforms
|
||||
* might want to specify a specific size for their own reasons. If it
|
||||
* is zero the soc code will compute it as
|
||||
* xres*yres*framebuffer_bits_per_pixel/8
|
||||
*/
|
||||
u32 framebuffer_size;
|
||||
|
||||
/*
|
||||
* Framebuffer resolution
|
||||
* The two parameters below provides dc about framebuffer's sdram size.
|
||||
* When they are not the same as panel resolution, we need to program
|
||||
* dc's DDA_INCREMENT and some other registers to resize dc output.
|
||||
*/
|
||||
u32 display_xres;
|
||||
u32 display_yres;
|
||||
|
||||
int href_to_sync; /* HSYNC position with respect to line start */
|
||||
int hsync_width; /* the width of HSYNC pulses */
|
||||
int hback_porch; /* the distance between HSYNC trailing edge to
|
||||
beginning of H display active area */
|
||||
int hfront_porch; /* the distance between end of H display active
|
||||
area to the leading edge of HSYNC */
|
||||
int vref_to_sync;
|
||||
int vsync_width;
|
||||
int vback_porch;
|
||||
int vfront_porch;
|
||||
int refresh; /* display refresh rate */
|
||||
|
||||
int pixel_clock; /* dc pixel clock source rate */
|
||||
|
||||
u32 panel_bits_per_pixel;
|
||||
|
||||
/* dp specific fields */
|
||||
struct {
|
||||
/* pwm to use to set display contrast */
|
||||
int pwm;
|
||||
|
||||
/* HPD related timing */
|
||||
int vdd_to_hpd_delay_ms;
|
||||
int hpd_unplug_min_us;
|
||||
int hpd_plug_min_us;
|
||||
int hpd_irq_min_us;
|
||||
|
||||
/* The minimum link configuraton settings */
|
||||
u32 lane_count;
|
||||
u32 enhanced_framing;
|
||||
u32 link_bw;
|
||||
u32 drive_current;
|
||||
u32 preemphasis;
|
||||
u32 postcursor;
|
||||
} dp;
|
||||
|
||||
int win_opt;
|
||||
void *dc_data;
|
||||
};
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_CHIP_H__ */
|
794
src/soc/nvidia/tegra210/clock.c
Normal file
794
src/soc/nvidia/tegra210/clock.c
Normal file
@ -0,0 +1,794 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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 <arch/io.h>
|
||||
#include <assert.h>
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <stdlib.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clk_rst.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/clst_clk.h>
|
||||
#include <soc/flow.h>
|
||||
#include <soc/maincpu.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/sysctr.h>
|
||||
|
||||
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;
|
||||
|
||||
enum {
|
||||
PLLX_INDEX,
|
||||
PLLC_INDEX,
|
||||
PLLU_INDEX,
|
||||
PLLDP_INDEX,
|
||||
PLLD_INDEX,
|
||||
PLL_MAX_INDEX,
|
||||
};
|
||||
|
||||
struct pll_reg_info {
|
||||
u32 *base_reg;
|
||||
u32 *lock_enb_reg;
|
||||
u32 lock_enb_val;
|
||||
u32 *pll_lock_reg;
|
||||
u32 pll_lock_val;
|
||||
u32 *kcp_kvco_reg;
|
||||
u32 n_shift:5; /* n bits location */
|
||||
u32 m_shift:5; /* m bits location */
|
||||
u32 p_shift:5; /* p bits location */
|
||||
u32 kcp_shift:5; /* kcp bits location */
|
||||
u32 kvco_shift:5; /* kvco bit location */
|
||||
u32 rsvd:7;
|
||||
} static const pll_reg_table[] = {
|
||||
[PLLX_INDEX] = { .base_reg = CLK_RST_REG(pllx_base),
|
||||
.lock_enb_reg = CLK_RST_REG(pllx_misc),
|
||||
.lock_enb_val = PLLPAXS_MISC_LOCK_ENABLE,
|
||||
.pll_lock_reg = CLK_RST_REG(pllx_base),
|
||||
.pll_lock_val = PLL_BASE_LOCK,
|
||||
.kcp_kvco_reg = CLK_RST_REG(pllx_misc3),
|
||||
.n_shift = 8, .m_shift = 0, .p_shift = 20,
|
||||
.kcp_shift = 1, .kvco_shift = 0, },
|
||||
[PLLC_INDEX] = { .base_reg = CLK_RST_REG(pllc_base),
|
||||
.lock_enb_reg = CLK_RST_REG(pllc_misc),
|
||||
.pll_lock_reg = CLK_RST_REG(pllc_base),
|
||||
.pll_lock_val = PLL_BASE_LOCK,
|
||||
.n_shift = 10, .m_shift = 0, .p_shift = 20, },
|
||||
[PLLU_INDEX] = { .base_reg = CLK_RST_REG(pllu_base),
|
||||
.lock_enb_reg = CLK_RST_REG(pllu_misc),
|
||||
.lock_enb_val = PLLU_MISC_LOCK_ENABLE,
|
||||
.pll_lock_reg = CLK_RST_REG(pllu_base),
|
||||
.pll_lock_val = PLL_BASE_LOCK,
|
||||
.kcp_kvco_reg = CLK_RST_REG(pllu_misc),
|
||||
.n_shift = 8, .m_shift = 0, .p_shift = 16,
|
||||
.kcp_shift = 25, .kvco_shift = 24, },
|
||||
[PLLDP_INDEX] = { .base_reg = CLK_RST_REG(plldp_base),
|
||||
.lock_enb_reg = CLK_RST_REG(plldp_misc),
|
||||
.lock_enb_val = PLLDPD2_MISC_LOCK_ENABLE,
|
||||
.pll_lock_reg = CLK_RST_REG(plldp_base),
|
||||
.pll_lock_val = PLL_BASE_LOCK,
|
||||
.kcp_kvco_reg = CLK_RST_REG(plldp_misc),
|
||||
.n_shift = 8, .m_shift = 0, .p_shift = 19,
|
||||
.kcp_shift = 25, .kvco_shift = 24, },
|
||||
[PLLD_INDEX] = { .base_reg = CLK_RST_REG(plld_base),
|
||||
.lock_enb_reg = CLK_RST_REG(plld_misc),
|
||||
.lock_enb_val = PLLD_MISC_LOCK_ENABLE | PLLD_MISC_CLK_ENABLE,
|
||||
.pll_lock_reg = CLK_RST_REG(plld_base),
|
||||
.pll_lock_val = PLL_BASE_LOCK,
|
||||
.kcp_kvco_reg = CLK_RST_REG(plld_misc),
|
||||
.n_shift = 11, .m_shift = 0, .p_shift = 20,
|
||||
.kcp_shift = 23, .kvco_shift = 22, },
|
||||
};
|
||||
|
||||
struct pll_fields {
|
||||
u32 n:8; /* the feedback divider bits width */
|
||||
u32 m:8; /* the input divider bits width */
|
||||
u32 p:5; /* the post divider bits witch */
|
||||
u32 kcp:2; /* charge pump gain control */
|
||||
u32 kvco:1; /* vco gain */
|
||||
u32 rsvd:8;
|
||||
};
|
||||
|
||||
#define PLL_HAS_KCP_KVCO(_n, _m, _p, _kcp, _kvco) \
|
||||
{.n = _n, .m = _m, .p = _p, .kcp = _kcp, .kvco = _kvco,}
|
||||
#define PLL_NO_KCP_KVCO(_n, _m, _p) \
|
||||
{.n = _n, .m = _m, .p = _p,}
|
||||
|
||||
#define PLLX(_n, _m, _p, _kcp, _kvco) \
|
||||
[PLLX_INDEX] = PLL_HAS_KCP_KVCO(_n, _m, _p, _kcp, _kvco)
|
||||
#define PLLC(_n, _m, _p) \
|
||||
[PLLC_INDEX] = PLL_NO_KCP_KVCO(_n, _m, _p)
|
||||
#define PLLU(_n, _m, _p, _kcp, _kvco) \
|
||||
[PLLU_INDEX] = PLL_HAS_KCP_KVCO(_n, _m, _p, _kcp, _kvco)
|
||||
#define PLLDP(_n, _m, _p, _kcp, _kvco) \
|
||||
[PLLDP_INDEX] = PLL_HAS_KCP_KVCO(_n, _m, _p, _kcp, _kvco)
|
||||
#define PLLD(_n, _m, _p, _kcp, _kvco) \
|
||||
[PLLD_INDEX] = PLL_HAS_KCP_KVCO(_n, _m, _p, _kcp, _kvco)
|
||||
|
||||
/* 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).
|
||||
* Target Frequencies:
|
||||
* PLLX = CONFIG_PLLX_KHZ
|
||||
* PLLC = 600 MHz
|
||||
* PLLU = 240 MHz (As per TRM, m and n should be programmed to generate 480MHz
|
||||
* VCO, and p should be programmed to do div-by-2.)
|
||||
* PLLDP = 270 MHz (PLLDP treats p differently (OUT = VCO / (p + 1) for p < 6)).
|
||||
* PLLM is set up dynamically by clock_sdram().
|
||||
* PLLP is hardwired to 408 MHz in HW (unless we set BASE_OVRD).
|
||||
*/
|
||||
struct {
|
||||
int khz;
|
||||
struct pll_fields plls[PLL_MAX_INDEX];
|
||||
} static osc_table[16] = {
|
||||
[OSC_FREQ_12]{
|
||||
.khz = 12000,
|
||||
.plls = {
|
||||
PLLX(TEGRA_PLLX_KHZ / 12000, 1, 0, 0, 0),
|
||||
PLLC(50, 1, 0), /* 600 MHz */
|
||||
PLLU(40, 1, 1, 0, 0), /* 240 MHz */
|
||||
PLLDP(90, 1, 2, 0, 0), /* 270 MHz */
|
||||
},
|
||||
},
|
||||
[OSC_FREQ_13]{
|
||||
.khz = 13000,
|
||||
.plls = {
|
||||
PLLX(TEGRA_PLLX_KHZ / 13000, 1, 0, 0, 0),
|
||||
PLLC(46, 1, 0), /* 598.0 MHz */
|
||||
PLLU(74, 2, 1, 0, 0), /* 240.5 MHz */
|
||||
PLLDP(83, 1, 3, 0, 0), /* 269.8 MHz */
|
||||
},
|
||||
},
|
||||
[OSC_FREQ_16P8]{
|
||||
.khz = 16800,
|
||||
.plls = {
|
||||
PLLX(TEGRA_PLLX_KHZ / 16800, 1, 0, 0, 0),
|
||||
PLLC(71, 1, 1), /* 596.4 MHz */
|
||||
PLLU(115, 4, 1, 0, 0), /* 241.5 MHz */
|
||||
PLLDP(64, 1, 2, 0, 0), /* 268.8 MHz */
|
||||
},
|
||||
},
|
||||
[OSC_FREQ_19P2]{
|
||||
.khz = 19200,
|
||||
.plls = {
|
||||
PLLX(TEGRA_PLLX_KHZ / 19200, 1, 0, 0, 0),
|
||||
PLLC(62, 1, 1), /* 595.2 MHz */
|
||||
PLLU(25, 1, 1, 0, 0), /* 240.0 MHz */
|
||||
PLLDP(56, 1, 2, 0, 0), /* 268.8 MHz */
|
||||
},
|
||||
},
|
||||
[OSC_FREQ_26]{
|
||||
.khz = 26000,
|
||||
.plls = {
|
||||
PLLX(TEGRA_PLLX_KHZ / 26000, 1, 0, 0, 0),
|
||||
PLLC(23, 1, 0), /* 598.0 MHz */
|
||||
PLLU(37, 2, 1, 0, 0), /* 240.5 MHz */
|
||||
PLLDP(83, 2, 2, 0, 0), /* 269.8 MHz */
|
||||
},
|
||||
},
|
||||
[OSC_FREQ_38P4]{
|
||||
.khz = 38400,
|
||||
.plls = {
|
||||
PLLX(TEGRA_PLLX_KHZ / 38400, 1, 0, 0, 0),
|
||||
PLLC(62, 2, 1), /* 595.2 MHz */
|
||||
PLLU(25, 2, 1, 0, 0), /* 240 MHz */
|
||||
PLLDP(56, 2, 2, 0, 0), /* 268.8 MHz */
|
||||
},
|
||||
},
|
||||
[OSC_FREQ_48]{
|
||||
.khz = 48000,
|
||||
.plls = {
|
||||
PLLX(TEGRA_PLLX_KHZ / 48000, 1, 0, 0, 0),
|
||||
PLLC(50, 2, 1), /* 600 MHz */
|
||||
PLLU(40, 4, 1, 0, 0), /* 240 MHz */
|
||||
PLLDP(90, 2, 3, 0, 0), /* 270 MHz */
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* 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 (read32(CLK_RST_REG(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 = read32(CLK_RST_REG(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 = TEGRA_CLK_M_KHZ * 1000;
|
||||
|
||||
// Record the system timer frequency.
|
||||
write32(&sysctr->cntfid0, freq);
|
||||
// Enable the system counter.
|
||||
uint32_t cntcr = read32(&sysctr->cntcr);
|
||||
cntcr |= SYSCTR_CNTCR_EN | SYSCTR_CNTCR_HDBG;
|
||||
write32(&sysctr->cntcr, 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_REG(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_REG(clk_src_sor), SOR0_CLK_SEL0);
|
||||
}
|
||||
|
||||
static void init_pll(u32 index, u32 osc)
|
||||
{
|
||||
assert(index <= PLL_MAX_INDEX);
|
||||
|
||||
struct pll_fields *pll = &osc_table[osc].plls[index];
|
||||
const struct pll_reg_info *pll_reg = &pll_reg_table[index];
|
||||
|
||||
u32 dividers = pll->n << pll_reg->n_shift |
|
||||
pll->m << pll_reg->m_shift |
|
||||
pll->p << pll_reg->p_shift;
|
||||
|
||||
/* Write dividers but BYPASS the PLL while we're messing with it. */
|
||||
write32(pll_reg->base_reg, dividers | PLL_BASE_BYPASS);
|
||||
|
||||
/* Set Lock bit if needed. */
|
||||
if (pll_reg->lock_enb_val)
|
||||
setbits_le32(pll_reg->lock_enb_reg, pll_reg->lock_enb_val);
|
||||
|
||||
/* Set KCP/KVCO if needed. */
|
||||
if (pll_reg->kcp_kvco_reg)
|
||||
setbits_le32(pll_reg->kcp_kvco_reg,
|
||||
pll->kcp << pll_reg->kcp_shift |
|
||||
pll->kvco << pll_reg->kvco_shift);
|
||||
|
||||
/* Enable PLL and take it back out of BYPASS */
|
||||
write32(pll_reg->base_reg, dividers | PLL_BASE_ENABLE);
|
||||
|
||||
/* Wait for lock ready */
|
||||
if (pll_reg->lock_enb_val)
|
||||
while (!(read32(pll_reg->pll_lock_reg) & pll_reg->pll_lock_val))
|
||||
;
|
||||
}
|
||||
|
||||
static void init_pllc(u32 osc)
|
||||
{
|
||||
/* Clear PLLC reset */
|
||||
clrbits_le32(CLK_RST_REG(pllc_misc), PLLC_MISC_RESET);
|
||||
|
||||
/* Clear PLLC IDDQ */
|
||||
clrbits_le32(CLK_RST_REG(pllc_misc_1), PLLC_MISC_1_IDDQ);
|
||||
|
||||
/* Max out the AVP clock before everything else (need PLLC for that). */
|
||||
init_pll(PLLC_INDEX, osc);
|
||||
|
||||
/* wait for pllc_lock (not the normal bit 27) */
|
||||
while (!(read32(CLK_RST_REG(pllc_base)) & PLLC_BASE_LOCK))
|
||||
;
|
||||
}
|
||||
|
||||
static void init_pllu(u32 osc)
|
||||
{
|
||||
/* Clear PLLU IDDQ */
|
||||
clrbits_le32(CLK_RST_REG(pllu_misc), PLLU_MISC_IDDQ);
|
||||
|
||||
/* Wait 5 us */
|
||||
udelay(5);
|
||||
|
||||
init_pll(PLLU_INDEX, osc);
|
||||
}
|
||||
|
||||
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_REG(utmip_pll_cfg2), UTMIP_CFG2_PHY_XTAL_CLOCKEN);
|
||||
udelay(1);
|
||||
|
||||
/* CFG0 */
|
||||
u32 div_n = div_round_up(960000, khz);
|
||||
write32(CLK_RST_REG(utmip_pll_cfg0), /* 960 MHz VCO */
|
||||
1 << UTMIP_CFG0_PLL_MDIV_SHIFT |
|
||||
div_n << UTMIP_CFG0_PLL_NDIV_SHIFT);
|
||||
|
||||
/* CFG1 */
|
||||
u32 pllu_enb_ct = div_round_up(khz, 8000); /* pllu_enb_ct / 8 (1us) */
|
||||
u32 phy_stb_ct = div_round_up(khz, 102); /* phy_stb_ct / 256(2.5ms) */
|
||||
write32(CLK_RST_REG(utmip_pll_cfg1),
|
||||
pllu_enb_ct << UTMIP_CFG1_PLLU_ENABLE_DLY_COUNT_SHIFT |
|
||||
UTMIP_CFG1_FORCE_PLLU_POWERDOWN_ENABLE |
|
||||
UTMIP_CFG1_FORCE_PLL_ENABLE_POWERDOWN_DISABLE |
|
||||
UTMIP_CFG1_FORCE_PLL_ACTIVE_POWERDOWN_DISABLE |
|
||||
UTMIP_CFG1_FORCE_PLL_ENABLE_POWERUP_ENABLE |
|
||||
phy_stb_ct << UTMIP_CFG1_XTAL_FREQ_COUNT_SHIFT);
|
||||
|
||||
/* CFG2 */
|
||||
u32 pllu_stb_ct = div_round_up(khz, 256); /* pllu_stb_ct / 256 (1ms) */
|
||||
u32 phy_act_ct = div_round_up(khz, 3200); /* phy_act_ct / 16 (5us) */
|
||||
write32(CLK_RST_REG(utmip_pll_cfg2),
|
||||
phy_act_ct << UTMIP_CFG2_PLL_ACTIVE_DLY_COUNT_SHIFT |
|
||||
pllu_stb_ct << UTMIP_CFG2_PLLU_STABLE_COUNT_SHIFT |
|
||||
UTMIP_CFG2_FORCE_PD_SAMP_C_POWERDOWN_DISABLE |
|
||||
UTMIP_CFG2_FORCE_PD_SAMP_B_POWERDOWN_DISABLE |
|
||||
UTMIP_CFG2_FORCE_PD_SAMP_A_POWERDOWN_DISABLE);
|
||||
|
||||
setbits_le32(CLK_RST_REG(utmip_pll_cfg2), UTMIP_CFG2_PHY_XTAL_CLOCKEN);
|
||||
}
|
||||
|
||||
/* 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_REG(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);
|
||||
write32(cfg, scfg);
|
||||
init_pll(PLLDP_INDEX, osc);
|
||||
/* leave dither and undoc bits set, release clamp */
|
||||
scfg = (1<<28) | (1<<24);
|
||||
write32(cfg, scfg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Init PLLD clock source.
|
||||
*
|
||||
* @frequency: the requested plld frequency
|
||||
*
|
||||
* Return the plld frequency if success, otherwise return 0.
|
||||
*/
|
||||
u32 clock_configure_plld(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 Tegra1xx 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 pll_fields *plld;
|
||||
u32 ref = clock_get_pll_input_khz() * 1000, m, n, p = 0;
|
||||
u32 cf, vco, rounded_rate = frequency;
|
||||
u32 diff, best_diff;
|
||||
const u32 max_m = 1 << 8, max_n = 1 << 8, max_p = 1 << 3,
|
||||
mhz = 1000 * 1000, min_vco = 500 * mhz, max_vco = 1000 * mhz,
|
||||
min_cf = 1 * mhz, max_cf = 6 * mhz;
|
||||
u32 osc = clock_get_osc_bits();
|
||||
|
||||
plld = &osc_table[osc].plls[PLLD_INDEX];
|
||||
|
||||
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 0;
|
||||
}
|
||||
|
||||
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 (best_diff) {
|
||||
printk(BIOS_WARNING, "%s: Failed to match output frequency %u, "
|
||||
"best difference is %u.\n", __func__, frequency,
|
||||
best_diff);
|
||||
rounded_rate = (ref / plld->m * plld->n) >> plld->p;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "%s: PLLD=%u ref=%u, m/n/p=%u/%u/%u\n",
|
||||
__func__, rounded_rate, ref, plld->m, plld->n, plld->p);
|
||||
|
||||
/* Write misc1 and misc */
|
||||
write32(CLK_RST_REG(plld_misc1), PLLD_MISC1_SETUP);
|
||||
write32(CLK_RST_REG(plld_misc), (PLLD_MISC_EN_SDM | PLLD_MISC_SDM_DIN));
|
||||
|
||||
/* configure PLLD */
|
||||
init_pll(PLLD_INDEX, osc);
|
||||
|
||||
if (rounded_rate != frequency)
|
||||
printk(BIOS_DEBUG, "PLLD rate: %u vs %u\n", rounded_rate,
|
||||
frequency);
|
||||
|
||||
return rounded_rate;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the UART and use PLLP as clock source. PLLP is hardwired to 408
|
||||
* MHz in HW (unless we set BASE_OVRD). We override the 16.0 UART divider with
|
||||
* the 15.1 CLK_SOURCE divider to get more precision. The 1843(KHZ) is
|
||||
* calculated thru BAUD_RATE*16/1000, ie, 115200*16/1000.
|
||||
*/
|
||||
void clock_early_uart(void)
|
||||
{
|
||||
write32(CLK_RST_REG(clk_src_uarta),
|
||||
CLK_SRC_DEV_ID(UARTA, PLLP) << CLK_SOURCE_SHIFT |
|
||||
CLK_UART_DIV_OVERRIDE |
|
||||
CLK_DIVIDER(TEGRA_PLLP_KHZ, 1843));
|
||||
|
||||
clock_enable_clear_reset_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 kvco, u32 kcp,
|
||||
u32 stable_time, u32 emc_source, u32 same_freq)
|
||||
{
|
||||
u32 misc1 = ((setup << PLLM_MISC1_SETUP_SHIFT)),
|
||||
misc2 = ((kvco << PLLM_MISC2_KVCO_SHIFT) |
|
||||
(kcp << PLLM_MISC2_KCP_SHIFT) |
|
||||
PLLM_EN_LCKDET),
|
||||
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).
|
||||
*/
|
||||
|
||||
write32(CLK_RST_REG(pllm_misc1), misc1);
|
||||
write32(CLK_RST_REG(pllm_misc2), misc2);
|
||||
|
||||
/* PLLM.BASE needs BYPASS=0, different from general init_pll */
|
||||
base = read32(CLK_RST_REG(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));
|
||||
write32(CLK_RST_REG(pllm_base), base);
|
||||
|
||||
setbits_le32(CLK_RST_REG(pllm_base), PLL_BASE_ENABLE);
|
||||
/* stable_time is required, before we can start to check lock. */
|
||||
udelay(stable_time);
|
||||
|
||||
while (!(read32(CLK_RST_REG(pllm_base)) & PLL_BASE_LOCK))
|
||||
udelay(1);
|
||||
|
||||
/*
|
||||
* After PLLM reports being locked, we have to delay 10us before
|
||||
* enabling PLLM_OUT.
|
||||
*/
|
||||
udelay(10);
|
||||
|
||||
/* Enable and start MEM(MC) and EMC. */
|
||||
clock_enable_clear_reset(0, CLK_H_MEM | CLK_H_EMC, 0, 0, 0, 0, 0);
|
||||
write32(CLK_RST_REG(clk_src_emc), emc_source);
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
}
|
||||
|
||||
void clock_halt_avp(void)
|
||||
{
|
||||
for (;;) {
|
||||
write32(&flow->halt_cop_events,
|
||||
FLOW_EVENT_JTAG | FLOW_EVENT_LIC_IRQ |
|
||||
FLOW_EVENT_GIC_IRQ | FLOW_MODE_WAITEVENT);
|
||||
}
|
||||
}
|
||||
|
||||
void clock_init(void)
|
||||
{
|
||||
u32 osc = clock_get_osc_bits();
|
||||
/* clk_m = osc/2 */
|
||||
clrsetbits_le32(CLK_RST_REG(spare_reg0), CLK_M_DIVISOR_MASK,
|
||||
CLK_M_DIVISOR_BY_2);
|
||||
|
||||
/* TIMERUS needs to be adjusted for new 19.2MHz CLK_M rate */
|
||||
write32((void *)TEGRA_TMRUS_BASE + TIMERUS_USEC_CFG,
|
||||
TIMERUS_USEC_CFG_19P2_CLK_M);
|
||||
|
||||
init_pllc(osc);
|
||||
|
||||
/* Typical ratios are 1:2:2 or 1:2:3 sclk:hclk:pclk (See: APB DMA
|
||||
* features section in the TRM). */
|
||||
write32(CLK_RST_REG(clk_sys_rate), /* pclk = hclk = sclk/2 */
|
||||
1 << HCLK_DIVISOR_SHIFT | 0 << PCLK_DIVISOR_SHIFT);
|
||||
write32(CLK_RST_REG(pllc_out),
|
||||
CLK_DIVIDER(TEGRA_PLLC_KHZ, 300000) << PLL_OUT_RATIO_SHIFT |
|
||||
PLL_OUT_CLKEN | PLL_OUT_RSTN);
|
||||
write32(CLK_RST_REG(sclk_brst_pol), /* sclk = 300 MHz */
|
||||
SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT |
|
||||
SCLK_SOURCE_PLLC_OUT1 << SCLK_RUN_SHIFT);
|
||||
|
||||
/* Change the oscillator drive strength (from U-Boot -- why?) */
|
||||
clrsetbits_le32(CLK_RST_REG(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_REG(pllx_misc3), PLLX_IDDQ_MASK);
|
||||
|
||||
/* Set up PLLP_OUT(1|2|3|4) divisor to generate (9.6|48|102|204)MHz */
|
||||
write32(CLK_RST_REG(pllp_outa),
|
||||
(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);
|
||||
write32(CLK_RST_REG(pllp_outb),
|
||||
(CLK_DIVIDER(TEGRA_PLLP_KHZ, TEGRA_PLLP_OUT3_KHZ) <<
|
||||
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);
|
||||
|
||||
/* init pllx */
|
||||
init_pll(PLLX_INDEX, osc);
|
||||
write32(CLK_RST_REG(cclk_brst_pol), CCLK_BURST_POLICY_VAL);
|
||||
|
||||
/* init pllu */
|
||||
init_pllu(osc);
|
||||
|
||||
init_utmip_pll();
|
||||
graphics_pll();
|
||||
}
|
||||
|
||||
void clock_grp_enable_clear_reset(u32 val, u32* clk_enb_set_reg,
|
||||
u32 *rst_dev_clr_reg)
|
||||
{
|
||||
write32(clk_enb_set_reg, val);
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
write32(rst_dev_clr_reg, val);
|
||||
}
|
||||
|
||||
static u32 * const clk_enb_set_arr[DEV_CONFIG_BLOCKS] = {
|
||||
CLK_RST_REG(clk_enb_l_set),
|
||||
CLK_RST_REG(clk_enb_h_set),
|
||||
CLK_RST_REG(clk_enb_u_set),
|
||||
CLK_RST_REG(clk_enb_v_set),
|
||||
CLK_RST_REG(clk_enb_w_set),
|
||||
CLK_RST_REG(clk_enb_x_set),
|
||||
CLK_RST_REG(clk_enb_y_set),
|
||||
};
|
||||
|
||||
static u32 * const clk_enb_clr_arr[DEV_CONFIG_BLOCKS] = {
|
||||
CLK_RST_REG(clk_enb_l_clr),
|
||||
CLK_RST_REG(clk_enb_h_clr),
|
||||
CLK_RST_REG(clk_enb_u_clr),
|
||||
CLK_RST_REG(clk_enb_v_clr),
|
||||
CLK_RST_REG(clk_enb_w_clr),
|
||||
CLK_RST_REG(clk_enb_x_clr),
|
||||
CLK_RST_REG(clk_enb_y_clr),
|
||||
};
|
||||
|
||||
static u32 * const rst_dev_set_arr[DEV_CONFIG_BLOCKS] = {
|
||||
CLK_RST_REG(rst_dev_l_set),
|
||||
CLK_RST_REG(rst_dev_h_set),
|
||||
CLK_RST_REG(rst_dev_u_set),
|
||||
CLK_RST_REG(rst_dev_v_set),
|
||||
CLK_RST_REG(rst_dev_w_set),
|
||||
CLK_RST_REG(rst_dev_x_set),
|
||||
CLK_RST_REG(rst_dev_y_set),
|
||||
};
|
||||
|
||||
static u32 * const rst_dev_clr_arr[DEV_CONFIG_BLOCKS] = {
|
||||
CLK_RST_REG(rst_dev_l_clr),
|
||||
CLK_RST_REG(rst_dev_h_clr),
|
||||
CLK_RST_REG(rst_dev_u_clr),
|
||||
CLK_RST_REG(rst_dev_v_clr),
|
||||
CLK_RST_REG(rst_dev_w_clr),
|
||||
CLK_RST_REG(rst_dev_x_clr),
|
||||
CLK_RST_REG(rst_dev_y_clr),
|
||||
};
|
||||
|
||||
static void clock_write_regs(u32 * const regs[DEV_CONFIG_BLOCKS],
|
||||
u32 bits[DEV_CONFIG_BLOCKS])
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (; i < DEV_CONFIG_BLOCKS; i++)
|
||||
if (bits[i])
|
||||
write32(regs[i], bits[i]);
|
||||
}
|
||||
|
||||
void clock_enable_regs(u32 bits[DEV_CONFIG_BLOCKS])
|
||||
{
|
||||
clock_write_regs(clk_enb_set_arr, bits);
|
||||
}
|
||||
|
||||
void clock_disable_regs(u32 bits[DEV_CONFIG_BLOCKS])
|
||||
{
|
||||
clock_write_regs(clk_enb_clr_arr, bits);
|
||||
}
|
||||
|
||||
void clock_set_reset_regs(u32 bits[DEV_CONFIG_BLOCKS])
|
||||
{
|
||||
clock_write_regs(rst_dev_set_arr, bits);
|
||||
}
|
||||
|
||||
void clock_clr_reset_regs(u32 bits[DEV_CONFIG_BLOCKS])
|
||||
{
|
||||
clock_write_regs(rst_dev_clr_arr, bits);
|
||||
}
|
||||
|
||||
void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x, u32 y)
|
||||
{
|
||||
clock_enable(l, h, u, v, w, x, y);
|
||||
|
||||
/* Give clocks time to stabilize. */
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
|
||||
clock_clr_reset(l, h, u, v, w, x, y);
|
||||
}
|
||||
|
||||
static void clock_reset_dev(u32 *setaddr, u32 *clraddr, u32 bit)
|
||||
{
|
||||
write32(setaddr, bit);
|
||||
udelay(LOGIC_STABILIZATION_DELAY);
|
||||
write32(clraddr, bit);
|
||||
}
|
||||
|
||||
void clock_reset_l(u32 bit)
|
||||
{
|
||||
clock_reset_dev(CLK_RST_REG(rst_dev_l_set), CLK_RST_REG(rst_dev_l_clr),
|
||||
bit);
|
||||
}
|
||||
|
||||
void clock_reset_h(u32 bit)
|
||||
{
|
||||
clock_reset_dev(CLK_RST_REG(rst_dev_h_set), CLK_RST_REG(rst_dev_h_clr),
|
||||
bit);
|
||||
}
|
||||
|
||||
void clock_reset_u(u32 bit)
|
||||
{
|
||||
clock_reset_dev(CLK_RST_REG(rst_dev_u_set), CLK_RST_REG(rst_dev_u_clr),
|
||||
bit);
|
||||
}
|
||||
|
||||
void clock_reset_v(u32 bit)
|
||||
{
|
||||
clock_reset_dev(CLK_RST_REG(rst_dev_v_set), CLK_RST_REG(rst_dev_v_clr),
|
||||
bit);
|
||||
}
|
||||
|
||||
void clock_reset_w(u32 bit)
|
||||
{
|
||||
clock_reset_dev(CLK_RST_REG(rst_dev_w_set), CLK_RST_REG(rst_dev_w_clr),
|
||||
bit);
|
||||
}
|
||||
|
||||
void clock_reset_x(u32 bit)
|
||||
{
|
||||
clock_reset_dev(CLK_RST_REG(rst_dev_x_set), CLK_RST_REG(rst_dev_x_clr),
|
||||
bit);
|
||||
}
|
||||
|
||||
void clock_reset_y(u32 bit)
|
||||
{
|
||||
clock_reset_dev(CLK_RST_REG(rst_dev_y_set), CLK_RST_REG(rst_dev_y_clr),
|
||||
bit);
|
||||
}
|
||||
|
||||
/* Enable/unreset all audio toys under AHUB */
|
||||
void clock_enable_audio(void)
|
||||
{
|
||||
/*
|
||||
* As per NVIDIA hardware team, we need to take ALL audio devices
|
||||
* connected to AHUB (AHUB, APB2APE, I2S, SPDIF, etc.) out of reset
|
||||
* and clock-enabled, otherwise reading AHUB devices (in our case,
|
||||
* I2S/APBIF/AUDIO<XBAR>) will hang.
|
||||
*/
|
||||
clock_enable_clear_reset(CLK_L_I2S1 | CLK_L_I2S2 | CLK_L_I2S3 | CLK_L_SPDIF,
|
||||
0, 0,
|
||||
CLK_V_I2S4 | CLK_V_I2S5 | CLK_V_AHUB | CLK_V_APB2APE,
|
||||
0, 0, 0);
|
||||
}
|
79
src/soc/nvidia/tegra210/cpu.c
Normal file
79
src/soc/nvidia/tegra210/cpu.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <assert.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clk_rst.h>
|
||||
#include <soc/cpu.h>
|
||||
#include <soc/secure_boot.h>
|
||||
|
||||
static void enable_core_clocks(int cpu)
|
||||
{
|
||||
const uint32_t cpu_clocks[CONFIG_MAX_CPUS] = {
|
||||
[0] = CRC_RST_CPUG_CLR_CPU0 | CRC_RST_CPUG_CLR_DBG0 |
|
||||
CRC_RST_CPUG_CLR_CORE0 | CRC_RST_CPUG_CLR_CX0,
|
||||
[1] = CRC_RST_CPUG_CLR_CPU1 | CRC_RST_CPUG_CLR_DBG1 |
|
||||
CRC_RST_CPUG_CLR_CORE1 | CRC_RST_CPUG_CLR_CX1,
|
||||
[2] = CRC_RST_CPUG_CLR_CPU2 | CRC_RST_CPUG_CLR_DBG2 |
|
||||
CRC_RST_CPUG_CLR_CORE2 | CRC_RST_CPUG_CLR_CX2,
|
||||
[3] = CRC_RST_CPUG_CLR_CPU3 | CRC_RST_CPUG_CLR_DBG3 |
|
||||
CRC_RST_CPUG_CLR_CORE3 | CRC_RST_CPUG_CLR_CX3,
|
||||
};
|
||||
|
||||
assert (cpu < CONFIG_MAX_CPUS);
|
||||
|
||||
/* Clear reset of CPU components. */
|
||||
write32(CLK_RST_REG(rst_cpug_cmplx_clr), cpu_clocks[cpu]);
|
||||
}
|
||||
|
||||
void cpu_prepare_startup(void *entry_64)
|
||||
{
|
||||
struct tegra_secure_boot *sb =
|
||||
(struct tegra_secure_boot *)TEGRA_SB_BASE;
|
||||
|
||||
/*
|
||||
* T210 TRM, section 12.4.4.2: "SB_AA64_RESET_LOW_0[0:0] is used to
|
||||
* decide between CPU boot up in AARCH32 (=0) or AARCH64 (=1) mode.
|
||||
* This bit .. is sampled only during 'cold reset of CPU'. Before the
|
||||
* CPU is powered up, the CPU reset vector is loaded in
|
||||
* EVP_CPU_REST_VECTOR_0 for 32-bit boot mode .... However, the CPU
|
||||
* decides to boot in 32-/64-bit mode based on
|
||||
* SB_AA64_RESET_LOW_0[0:0]. If this bit is set (=1), the CPU boots in
|
||||
* 64-bit mode using SB_AA64_RESET_* as the reset address. If this bit
|
||||
* is clear (=0), CPU boots in 32-bit mode using EVP_CPU_RESET_VECTOR."
|
||||
*/
|
||||
|
||||
write32(&sb->sb_aa64_reset_low, (uintptr_t)entry_64);
|
||||
setbits_le32(&sb->sb_aa64_reset_low, 1);
|
||||
write32(&sb->sb_aa64_reset_high, 0);
|
||||
}
|
||||
|
||||
void start_cpu_silent(int cpu, void *entry_64)
|
||||
{
|
||||
cpu_prepare_startup(entry_64);
|
||||
enable_core_clocks(cpu);
|
||||
}
|
||||
|
||||
void start_cpu(int cpu, void *entry_64)
|
||||
{
|
||||
printk(BIOS_DEBUG, "Starting CPU%d @ %p.\n", cpu, entry_64);
|
||||
start_cpu_silent(cpu, entry_64);
|
||||
}
|
27
src/soc/nvidia/tegra210/cpu_lib.S
Normal file
27
src/soc/nvidia/tegra210/cpu_lib.S
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
.text
|
||||
.global smp_processor_id
|
||||
smp_processor_id:
|
||||
/* Core 0 and 1 are encoded in the Aff0 (7:0) field of MPIDR_EL1. */
|
||||
mrs x0, mpidr_el1
|
||||
uxtb w0, w0
|
||||
ret
|
249
src/soc/nvidia/tegra210/dc.c
Normal file
249
src/soc/nvidia/tegra210/dc.c
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include <console/console.h>
|
||||
#include <arch/io.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <edid.h>
|
||||
#include <device/device.h>
|
||||
#include <soc/nvidia/tegra/dc.h>
|
||||
#include "chip.h"
|
||||
#include <soc/display.h>
|
||||
|
||||
int dump = 0;
|
||||
unsigned long READL(void * p)
|
||||
{
|
||||
unsigned long value;
|
||||
|
||||
/*
|
||||
* In case of hard hung on readl(p), we can set dump > 1 to print out
|
||||
* the address accessed.
|
||||
*/
|
||||
if (dump > 1)
|
||||
printk(BIOS_SPEW, "readl %p\n", p);
|
||||
|
||||
value = read32(p);
|
||||
if (dump)
|
||||
printk(BIOS_SPEW, "readl %p %08lx\n", p, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void WRITEL(unsigned long value, void * p)
|
||||
{
|
||||
if (dump)
|
||||
printk(BIOS_SPEW, "writel %p %08lx\n", p, value);
|
||||
write32(p, value);
|
||||
}
|
||||
|
||||
/* return in 1000ths of a Hertz */
|
||||
static int tegra_calc_refresh(const struct soc_nvidia_tegra210_config *config)
|
||||
{
|
||||
int refresh;
|
||||
int h_total = htotal(config);
|
||||
int v_total = vtotal(config);
|
||||
int pclk = config->pixel_clock;
|
||||
|
||||
if (!pclk || !h_total || !v_total)
|
||||
return 0;
|
||||
refresh = pclk / h_total;
|
||||
refresh *= 1000;
|
||||
refresh /= v_total;
|
||||
return refresh;
|
||||
}
|
||||
|
||||
static void print_mode(const struct soc_nvidia_tegra210_config *config)
|
||||
{
|
||||
if (config) {
|
||||
int refresh = tegra_calc_refresh(config);
|
||||
printk(BIOS_ERR,
|
||||
"Panel Mode: %dx%d@%d.%03uHz pclk=%d\n",
|
||||
config->xres, config->yres,
|
||||
refresh / 1000, refresh % 1000,
|
||||
config->pixel_clock);
|
||||
}
|
||||
}
|
||||
|
||||
int update_display_mode(struct display_controller *disp_ctrl,
|
||||
struct soc_nvidia_tegra210_config *config)
|
||||
{
|
||||
print_mode(config);
|
||||
|
||||
printk(BIOS_ERR, "config: xres:yres: %d x %d\n ",
|
||||
config->xres, config->yres);
|
||||
printk(BIOS_ERR, " href_sync:vref_sync: %d x %d\n ",
|
||||
config->href_to_sync, config->vref_to_sync);
|
||||
printk(BIOS_ERR, " hsyn_width:vsyn_width: %d x %d\n ",
|
||||
config->hsync_width, config->vsync_width);
|
||||
printk(BIOS_ERR, " hfnt_porch:vfnt_porch: %d x %d\n ",
|
||||
config->hfront_porch, config->vfront_porch);
|
||||
printk(BIOS_ERR, " hbk_porch:vbk_porch: %d x %d\n ",
|
||||
config->hback_porch, config->vback_porch);
|
||||
|
||||
WRITEL(0x0, &disp_ctrl->disp.disp_timing_opt);
|
||||
WRITEL(0x0, &disp_ctrl->disp.disp_color_ctrl);
|
||||
|
||||
/* select win opt */
|
||||
WRITEL(config->win_opt, &disp_ctrl->disp.disp_win_opt);
|
||||
|
||||
WRITEL(config->vref_to_sync << 16 | config->href_to_sync,
|
||||
&disp_ctrl->disp.ref_to_sync);
|
||||
|
||||
WRITEL(config->vsync_width << 16 | config->hsync_width,
|
||||
&disp_ctrl->disp.sync_width);
|
||||
|
||||
|
||||
WRITEL((config->vback_porch << 16) | config->hback_porch,
|
||||
&disp_ctrl->disp.back_porch);
|
||||
|
||||
WRITEL((config->vfront_porch << 16) | config->hfront_porch,
|
||||
&disp_ctrl->disp.front_porch);
|
||||
|
||||
WRITEL(config->xres | (config->yres << 16),
|
||||
&disp_ctrl->disp.disp_active);
|
||||
|
||||
/*
|
||||
* PixelClock = (PLLD / 2) / ShiftClockDiv / PixelClockDiv.
|
||||
*
|
||||
* default: Set both shift_clk_div and pixel_clock_div to 1
|
||||
*/
|
||||
update_display_shift_clock_divider(disp_ctrl, SHIFT_CLK_DIVIDER(1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void update_display_shift_clock_divider(struct display_controller *disp_ctrl,
|
||||
u32 shift_clock_div)
|
||||
{
|
||||
WRITEL((PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT) |
|
||||
(shift_clock_div & 0xff) << SHIFT_CLK_DIVIDER_SHIFT,
|
||||
&disp_ctrl->disp.disp_clk_ctrl);
|
||||
printk(BIOS_DEBUG, "%s: ShiftClockDiv=%u\n",
|
||||
__func__, shift_clock_div);
|
||||
}
|
||||
|
||||
/*
|
||||
* update_window:
|
||||
* set up window registers and activate window except two:
|
||||
* frame buffer base address register (WINBUF_START_ADDR) and
|
||||
* display enable register (_DISP_DISP_WIN_OPTIONS). This is
|
||||
* becasue framebuffer is not available until payload stage.
|
||||
*/
|
||||
void update_window(const struct soc_nvidia_tegra210_config *config)
|
||||
{
|
||||
struct display_controller *disp_ctrl =
|
||||
(void *)config->display_controller;
|
||||
u32 val;
|
||||
|
||||
WRITEL(WINDOW_A_SELECT, &disp_ctrl->cmd.disp_win_header);
|
||||
|
||||
WRITEL(((config->yres << 16) | config->xres), &disp_ctrl->win.size);
|
||||
|
||||
WRITEL(((config->display_yres << 16) |
|
||||
(config->display_xres *
|
||||
config->framebuffer_bits_per_pixel / 8)),
|
||||
&disp_ctrl->win.prescaled_size);
|
||||
|
||||
val = ALIGN_UP((config->display_xres *
|
||||
config->framebuffer_bits_per_pixel / 8), 64);
|
||||
WRITEL(val, &disp_ctrl->win.line_stride);
|
||||
|
||||
WRITEL(config->color_depth, &disp_ctrl->win.color_depth);
|
||||
WRITEL(COLOR_BLACK, &disp_ctrl->disp.blend_background_color);
|
||||
|
||||
WRITEL(((DDA_INC(config->display_yres, config->yres) << 16) |
|
||||
DDA_INC(config->display_xres, config->xres)),
|
||||
&disp_ctrl->win.dda_increment);
|
||||
|
||||
WRITEL(DISP_CTRL_MODE_C_DISPLAY, &disp_ctrl->cmd.disp_cmd);
|
||||
|
||||
WRITEL(WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access);
|
||||
|
||||
WRITEL(0, &disp_ctrl->win.buffer_addr_mode);
|
||||
|
||||
val = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
|
||||
PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
|
||||
WRITEL(val, &disp_ctrl->cmd.disp_pow_ctrl);
|
||||
|
||||
val = GENERAL_UPDATE | WIN_A_UPDATE;
|
||||
WRITEL(val, &disp_ctrl->cmd.state_ctrl);
|
||||
|
||||
val = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
|
||||
WRITEL(val, &disp_ctrl->cmd.state_ctrl);
|
||||
}
|
||||
|
||||
int tegra_dc_init(struct display_controller *disp_ctrl)
|
||||
{
|
||||
/* do not accept interrupts during initialization */
|
||||
WRITEL(0x00000000, &disp_ctrl->cmd.int_mask);
|
||||
WRITEL(WRITE_MUX_ASSEMBLY | READ_MUX_ASSEMBLY,
|
||||
&disp_ctrl->cmd.state_access);
|
||||
WRITEL(WINDOW_A_SELECT, &disp_ctrl->cmd.disp_win_header);
|
||||
WRITEL(0x00000000, &disp_ctrl->win.win_opt);
|
||||
WRITEL(0x00000000, &disp_ctrl->win.byte_swap);
|
||||
WRITEL(0x00000000, &disp_ctrl->win.buffer_ctrl);
|
||||
|
||||
WRITEL(0x00000000, &disp_ctrl->win.pos);
|
||||
WRITEL(0x00000000, &disp_ctrl->win.h_initial_dda);
|
||||
WRITEL(0x00000000, &disp_ctrl->win.v_initial_dda);
|
||||
WRITEL(0x00000000, &disp_ctrl->win.dda_increment);
|
||||
WRITEL(0x00000000, &disp_ctrl->win.dv_ctrl);
|
||||
|
||||
WRITEL(0x01000000, &disp_ctrl->win.blend_layer_ctrl);
|
||||
WRITEL(0x00000000, &disp_ctrl->win.blend_match_select);
|
||||
WRITEL(0x00000000, &disp_ctrl->win.blend_nomatch_select);
|
||||
WRITEL(0x00000000, &disp_ctrl->win.blend_alpha_1bit);
|
||||
|
||||
WRITEL(0x00000000, &disp_ctrl->winbuf.start_addr_hi);
|
||||
WRITEL(0x00000000, &disp_ctrl->winbuf.addr_h_offset);
|
||||
WRITEL(0x00000000, &disp_ctrl->winbuf.addr_v_offset);
|
||||
|
||||
WRITEL(0x00000000, &disp_ctrl->com.crc_checksum);
|
||||
WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[0]);
|
||||
WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[1]);
|
||||
WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[2]);
|
||||
WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[3]);
|
||||
WRITEL(0x00000000, &disp_ctrl->disp.disp_signal_opt0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save mode to cb tables
|
||||
*/
|
||||
void pass_mode_info_to_payload(
|
||||
struct soc_nvidia_tegra210_config *config)
|
||||
{
|
||||
struct edid edid;
|
||||
/* Align bytes_per_line to 64 bytes as required by dc */
|
||||
edid.bytes_per_line = ALIGN_UP((config->display_xres *
|
||||
config->framebuffer_bits_per_pixel / 8), 64);
|
||||
edid.x_resolution = edid.bytes_per_line /
|
||||
(config->framebuffer_bits_per_pixel / 8);
|
||||
edid.y_resolution = config->display_yres;
|
||||
edid.framebuffer_bits_per_pixel = config->framebuffer_bits_per_pixel;
|
||||
|
||||
printk(BIOS_INFO, "%s: bytes_per_line: %d, bits_per_pixel: %d\n "
|
||||
" x_res x y_res: %d x %d, size: %d\n",
|
||||
__func__, edid.bytes_per_line,
|
||||
edid.framebuffer_bits_per_pixel,
|
||||
edid.x_resolution, edid.y_resolution,
|
||||
(edid.bytes_per_line * edid.y_resolution));
|
||||
|
||||
set_vbe_mode_info_valid(&edid, 0);
|
||||
}
|
147
src/soc/nvidia/tegra210/dma.c
Normal file
147
src/soc/nvidia/tegra210/dma.c
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* (C) Copyright 2010,2011
|
||||
* NVIDIA Corporation <www.nvidia.com>
|
||||
* 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 <arch/io.h>
|
||||
#include <console/console.h>
|
||||
#include <inttypes.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/dma.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct apb_dma * const apb_dma = (struct apb_dma *)TEGRA_APB_DMA_BASE;
|
||||
|
||||
#define APB_DMA_OFFSET(n) \
|
||||
(struct apb_dma_channel_regs *)(TEGRA_APB_DMA_BASE + n)
|
||||
struct apb_dma_channel apb_dma_channels[] = {
|
||||
{ .num = 0, .regs = APB_DMA_OFFSET(0x1000) },
|
||||
{ .num = 1, .regs = APB_DMA_OFFSET(0x1040) },
|
||||
{ .num = 2, .regs = APB_DMA_OFFSET(0x1080) },
|
||||
{ .num = 3, .regs = APB_DMA_OFFSET(0x10c0) },
|
||||
{ .num = 4, .regs = APB_DMA_OFFSET(0x1100) },
|
||||
{ .num = 5, .regs = APB_DMA_OFFSET(0x1140) },
|
||||
{ .num = 6, .regs = APB_DMA_OFFSET(0x1180) },
|
||||
{ .num = 7, .regs = APB_DMA_OFFSET(0x11c0) },
|
||||
{ .num = 8, .regs = APB_DMA_OFFSET(0x1200) },
|
||||
{ .num = 9, .regs = APB_DMA_OFFSET(0x1240) },
|
||||
{ .num = 10, .regs = APB_DMA_OFFSET(0x1280) },
|
||||
{ .num = 11, .regs = APB_DMA_OFFSET(0x12c0) },
|
||||
{ .num = 12, .regs = APB_DMA_OFFSET(0x1300) },
|
||||
{ .num = 13, .regs = APB_DMA_OFFSET(0x1340) },
|
||||
{ .num = 14, .regs = APB_DMA_OFFSET(0x1380) },
|
||||
{ .num = 15, .regs = APB_DMA_OFFSET(0x13c0) },
|
||||
{ .num = 16, .regs = APB_DMA_OFFSET(0x1400) },
|
||||
{ .num = 17, .regs = APB_DMA_OFFSET(0x1440) },
|
||||
{ .num = 18, .regs = APB_DMA_OFFSET(0x1480) },
|
||||
{ .num = 19, .regs = APB_DMA_OFFSET(0x14c0) },
|
||||
{ .num = 20, .regs = APB_DMA_OFFSET(0x1500) },
|
||||
{ .num = 21, .regs = APB_DMA_OFFSET(0x1540) },
|
||||
{ .num = 22, .regs = APB_DMA_OFFSET(0x1580) },
|
||||
{ .num = 23, .regs = APB_DMA_OFFSET(0x15c0) },
|
||||
{ .num = 24, .regs = APB_DMA_OFFSET(0x1600) },
|
||||
{ .num = 25, .regs = APB_DMA_OFFSET(0x1640) },
|
||||
{ .num = 26, .regs = APB_DMA_OFFSET(0x1680) },
|
||||
{ .num = 27, .regs = APB_DMA_OFFSET(0x16c0) },
|
||||
{ .num = 28, .regs = APB_DMA_OFFSET(0x1700) },
|
||||
{ .num = 29, .regs = APB_DMA_OFFSET(0x1740) },
|
||||
{ .num = 30, .regs = APB_DMA_OFFSET(0x1780) },
|
||||
{ .num = 31, .regs = APB_DMA_OFFSET(0x17c0) },
|
||||
};
|
||||
|
||||
int dma_busy(struct apb_dma_channel * const channel)
|
||||
{
|
||||
/*
|
||||
* In continuous mode, the BSY_n bit in APB_DMA_STATUS and
|
||||
* BSY in APBDMACHAN_CHANNEL_n_STA_0 will remain set as '1' so long
|
||||
* as the channel is enabled. So for this function we'll use the
|
||||
* DMA_ACTIVITY bit.
|
||||
*/
|
||||
return read32(&channel->regs->sta) & APB_STA_DMA_ACTIVITY ? 1 : 0;
|
||||
}
|
||||
/* claim a DMA channel */
|
||||
struct apb_dma_channel * const dma_claim(void)
|
||||
{
|
||||
int i;
|
||||
struct apb_dma_channel_regs *regs = NULL;
|
||||
|
||||
/*
|
||||
* Set global enable bit, otherwise register access to channel
|
||||
* DMA registers will not be possible.
|
||||
*/
|
||||
setbits_le32(&apb_dma->command, APB_COMMAND_GEN);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(apb_dma_channels); i++) {
|
||||
regs = apb_dma_channels[i].regs;
|
||||
|
||||
if (!apb_dma_channels[i].in_use) {
|
||||
u32 status = read32(®s->sta);
|
||||
if (status & (1 << i)) {
|
||||
/* FIXME: should this be fatal? */
|
||||
printk(BIOS_DEBUG, "%s: DMA channel %d busy?\n",
|
||||
__func__, i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(apb_dma_channels))
|
||||
return NULL;
|
||||
|
||||
apb_dma_channels[i].in_use = 1;
|
||||
return &apb_dma_channels[i];
|
||||
}
|
||||
|
||||
/* release a DMA channel */
|
||||
void dma_release(struct apb_dma_channel * const channel)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* FIXME: make this "thread" friendly */
|
||||
while (dma_busy(channel))
|
||||
;
|
||||
|
||||
channel->in_use = 0;
|
||||
|
||||
/* clear the global enable bit if no channels are in use */
|
||||
for (i = 0; i < ARRAY_SIZE(apb_dma_channels); i++) {
|
||||
if (apb_dma_channels[i].in_use)
|
||||
return;
|
||||
}
|
||||
|
||||
clrbits_le32(&apb_dma->command, APB_COMMAND_GEN);
|
||||
}
|
||||
|
||||
int dma_start(struct apb_dma_channel * const channel)
|
||||
{
|
||||
struct apb_dma_channel_regs *regs = channel->regs;
|
||||
|
||||
/* Set ENB bit for this channel */
|
||||
setbits_le32(®s->csr, APB_CSR_ENB);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dma_stop(struct apb_dma_channel * const channel)
|
||||
{
|
||||
struct apb_dma_channel_regs *regs = channel->regs;
|
||||
|
||||
/* Clear ENB bit for this channel */
|
||||
clrbits_le32(®s->csr, APB_CSR_ENB);
|
||||
|
||||
return 0;
|
||||
}
|
1663
src/soc/nvidia/tegra210/dp.c
Normal file
1663
src/soc/nvidia/tegra210/dp.c
Normal file
File diff suppressed because it is too large
Load Diff
1045
src/soc/nvidia/tegra210/dsi.c
Normal file
1045
src/soc/nvidia/tegra210/dsi.c
Normal file
File diff suppressed because it is too large
Load Diff
113
src/soc/nvidia/tegra210/flow_ctrl.c
Normal file
113
src/soc/nvidia/tegra210/flow_ctrl.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/flow_ctrl.h>
|
||||
|
||||
#define FLOW_CTRL_HALT_CPU0_EVENTS 0x0
|
||||
#define FLOW_CTRL_WAITEVENT (2 << 29)
|
||||
#define FLOW_CTRL_WAIT_FOR_INTERRUPT (4 << 29)
|
||||
#define FLOW_CTRL_HALT_SCLK (1 << 27)
|
||||
#define FLOW_CTRL_HALT_LIC_IRQ (1 << 11)
|
||||
#define FLOW_CTRL_HALT_LIC_FIQ (1 << 10)
|
||||
#define FLOW_CTRL_HALT_GIC_IRQ (1 << 9)
|
||||
#define FLOW_CTRL_HALT_GIC_FIQ (1 << 8)
|
||||
#define FLOW_CTRL_CPU0_CSR 0x8
|
||||
#define FLOW_CTRL_CSR_INTR_FLAG (1 << 15)
|
||||
#define FLOW_CTRL_CSR_EVENT_FLAG (1 << 14)
|
||||
#define FLOW_CTRL_CSR_WFI_CPU0 (1 << 8)
|
||||
#define FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8)
|
||||
#define FLOW_CTRL_CSR_WFE_BITMAP (0xF << 4)
|
||||
#define FLOW_CTRL_CSR_ENABLE (1 << 0)
|
||||
#define FLOW_CTRL_HALT_CPU1_EVENTS 0x14
|
||||
#define FLOW_CTRL_CPU1_CSR 0x18
|
||||
#define FLOW_CTRL_CC4_CORE0_CTRL 0x6c
|
||||
|
||||
static void *tegra_flowctrl_base = (void*)TEGRA_FLOW_BASE;
|
||||
|
||||
static const uint8_t flowctrl_offset_halt_cpu[] = {
|
||||
FLOW_CTRL_HALT_CPU0_EVENTS,
|
||||
FLOW_CTRL_HALT_CPU1_EVENTS,
|
||||
FLOW_CTRL_HALT_CPU1_EVENTS + 8,
|
||||
FLOW_CTRL_HALT_CPU1_EVENTS + 16
|
||||
};
|
||||
|
||||
static const uint8_t flowctrl_offset_cpu_csr[] = {
|
||||
FLOW_CTRL_CPU0_CSR,
|
||||
FLOW_CTRL_CPU1_CSR,
|
||||
FLOW_CTRL_CPU1_CSR + 8,
|
||||
FLOW_CTRL_CPU1_CSR + 16
|
||||
};
|
||||
|
||||
static const uint8_t flowctrl_offset_cc4_ctrl[] = {
|
||||
FLOW_CTRL_CC4_CORE0_CTRL,
|
||||
FLOW_CTRL_CC4_CORE0_CTRL + 4,
|
||||
FLOW_CTRL_CC4_CORE0_CTRL + 8,
|
||||
FLOW_CTRL_CC4_CORE0_CTRL + 12
|
||||
};
|
||||
|
||||
void flowctrl_write_cpu_csr(int cpu, uint32_t val)
|
||||
{
|
||||
write32(tegra_flowctrl_base + flowctrl_offset_cpu_csr[cpu], val);
|
||||
val = read32(tegra_flowctrl_base + flowctrl_offset_cpu_csr[cpu]);
|
||||
}
|
||||
|
||||
void flowctrl_write_cpu_halt(int cpu, uint32_t val)
|
||||
{
|
||||
write32(tegra_flowctrl_base + flowctrl_offset_halt_cpu[cpu], val);
|
||||
val = read32(tegra_flowctrl_base + flowctrl_offset_halt_cpu[cpu]);
|
||||
}
|
||||
|
||||
void flowctrl_write_cc4_ctrl(int cpu, uint32_t val)
|
||||
{
|
||||
write32(tegra_flowctrl_base + flowctrl_offset_cc4_ctrl[cpu], val);
|
||||
val = read32(tegra_flowctrl_base + flowctrl_offset_cc4_ctrl[cpu]);
|
||||
}
|
||||
|
||||
void flowctrl_cpu_off(int cpu)
|
||||
{
|
||||
uint32_t val = FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG |
|
||||
FLOW_CTRL_CSR_ENABLE | (FLOW_CTRL_CSR_WFI_CPU0 << cpu);
|
||||
|
||||
flowctrl_write_cpu_csr(cpu, val);
|
||||
flowctrl_write_cpu_halt(cpu, FLOW_CTRL_WAITEVENT);
|
||||
flowctrl_write_cc4_ctrl(cpu, 0);
|
||||
}
|
||||
|
||||
void flowctrl_cpu_on(int cpu)
|
||||
{
|
||||
flowctrl_write_cpu_csr(cpu, FLOW_CTRL_CSR_ENABLE);
|
||||
flowctrl_write_cpu_halt(cpu, FLOW_CTRL_WAITEVENT |
|
||||
FLOW_CTRL_HALT_SCLK);
|
||||
}
|
||||
|
||||
void flowctrl_cpu_suspend(int cpu)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = FLOW_CTRL_HALT_GIC_IRQ | FLOW_CTRL_HALT_GIC_FIQ |
|
||||
FLOW_CTRL_HALT_LIC_IRQ | FLOW_CTRL_HALT_LIC_FIQ |
|
||||
FLOW_CTRL_WAITEVENT;
|
||||
flowctrl_write_cpu_halt(cpu, val);
|
||||
|
||||
val = FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG |
|
||||
FLOW_CTRL_CSR_ENABLE | (FLOW_CTRL_CSR_WFI_CPU0 << cpu);
|
||||
flowctrl_write_cpu_csr(cpu, val);
|
||||
}
|
186
src/soc/nvidia/tegra210/funitcfg.c
Normal file
186
src/soc/nvidia/tegra210/funitcfg.c
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/funitcfg.h>
|
||||
#include <soc/nvidia/tegra/usb.h>
|
||||
#include <soc/padconfig.h>
|
||||
#include <string.h>
|
||||
|
||||
struct clk_dev_control {
|
||||
uint32_t *clk_enb_set;
|
||||
uint32_t *rst_dev_clr;
|
||||
};
|
||||
|
||||
struct funit_cfg_data {
|
||||
const char *name;
|
||||
void *ctlr_base;
|
||||
uint32_t *clk_src_reg;
|
||||
const struct clk_dev_control * const dev_control;
|
||||
uint32_t clk_enb_val;
|
||||
};
|
||||
|
||||
enum {
|
||||
CLK_L_SET = 0,
|
||||
CLK_H_SET = 1,
|
||||
CLK_U_SET = 2,
|
||||
CLK_V_SET = 3,
|
||||
CLK_W_SET = 4,
|
||||
CLK_X_SET = 5,
|
||||
CLK_Y_SET = 6,
|
||||
};
|
||||
|
||||
#define CLK_SET_REGS(x) \
|
||||
{ \
|
||||
CLK_RST_REG(clk_enb_##x##_set), \
|
||||
CLK_RST_REG(rst_dev_##x##_clr), \
|
||||
}
|
||||
|
||||
static const struct clk_dev_control clk_data_arr[] = {
|
||||
[CLK_L_SET] = CLK_SET_REGS(l),
|
||||
[CLK_H_SET] = CLK_SET_REGS(h),
|
||||
[CLK_U_SET] = CLK_SET_REGS(u),
|
||||
[CLK_V_SET] = CLK_SET_REGS(v),
|
||||
[CLK_W_SET] = CLK_SET_REGS(w),
|
||||
[CLK_X_SET] = CLK_SET_REGS(x),
|
||||
[CLK_Y_SET] = CLK_SET_REGS(y),
|
||||
};
|
||||
|
||||
#define FUNIT_DATA(funit_, loname_, clk_set_) \
|
||||
[FUNIT_INDEX(funit_)] = { \
|
||||
.name = STRINGIFY(loname_), \
|
||||
.ctlr_base = (void *)(uintptr_t)TEGRA_##funit_##_BASE, \
|
||||
.clk_src_reg = CLK_RST_REG(clk_src_##loname_), \
|
||||
.dev_control = &clk_data_arr[CLK_##clk_set_##_SET], \
|
||||
.clk_enb_val = CLK_##clk_set_##_##funit_, \
|
||||
}
|
||||
|
||||
#define FUNIT_DATA_USB(funit_, clk_set_) \
|
||||
[FUNIT_INDEX(funit_)] = { \
|
||||
.name = STRINGIFY(funit_), \
|
||||
.ctlr_base = (void *)(uintptr_t)TEGRA_##funit_##_BASE, \
|
||||
.dev_control = &clk_data_arr[CLK_##clk_set_##_SET], \
|
||||
.clk_enb_val = CLK_##clk_set_##_##funit_, \
|
||||
}
|
||||
|
||||
static const struct funit_cfg_data funit_data[] = {
|
||||
FUNIT_DATA(I2C1, i2c1, L),
|
||||
FUNIT_DATA(I2C2, i2c2, H),
|
||||
FUNIT_DATA(I2C3, i2c3, U),
|
||||
FUNIT_DATA(I2C5, i2c5, H),
|
||||
FUNIT_DATA(I2C6, i2c6, X),
|
||||
FUNIT_DATA(SDMMC1, sdmmc1, L),
|
||||
FUNIT_DATA(SDMMC4, sdmmc4, L),
|
||||
FUNIT_DATA_USB(USBD, L),
|
||||
FUNIT_DATA_USB(USB2, H),
|
||||
FUNIT_DATA(QSPI, qspi, Y),
|
||||
FUNIT_DATA(I2S1, i2s1, L),
|
||||
};
|
||||
_Static_assert(ARRAY_SIZE(funit_data) == FUNIT_INDEX_MAX,
|
||||
"funit_cfg_data array not filled out!");
|
||||
|
||||
static inline uint32_t get_clk_src_freq(uint32_t clk_src_freq_id)
|
||||
{
|
||||
uint32_t freq = 0;
|
||||
|
||||
switch (clk_src_freq_id) {
|
||||
case CLK_M:
|
||||
freq = TEGRA_CLK_M_KHZ;
|
||||
break;
|
||||
case PLLP:
|
||||
freq = TEGRA_PLLP_KHZ;
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_SPEW, "%s ERROR: Unknown clk_src %d\n",
|
||||
__func__, clk_src_freq_id);
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
static void configure_clock(const struct funit_cfg * const entry,
|
||||
const struct funit_cfg_data * const funit)
|
||||
{
|
||||
const char *funit_i2c = "i2c";
|
||||
uint32_t clk_div;
|
||||
uint32_t clk_div_mask;
|
||||
uint32_t clk_src_freq;
|
||||
|
||||
clk_src_freq = get_clk_src_freq(entry->clk_src_freq_id);
|
||||
|
||||
if (strncmp(funit->name, funit_i2c, strlen(funit_i2c)) == 0) {
|
||||
/* I2C funit */
|
||||
clk_div = get_i2c_clk_div(clk_src_freq,
|
||||
entry->clk_dev_freq_khz);
|
||||
clk_div_mask = CLK_DIV_MASK_I2C;
|
||||
} else {
|
||||
/* Non I2C */
|
||||
clk_div = get_clk_div(clk_src_freq, entry->clk_dev_freq_khz);
|
||||
clk_div_mask = CLK_DIV_MASK;
|
||||
}
|
||||
|
||||
_clock_set_div(funit->clk_src_reg, funit->name, clk_div,
|
||||
clk_div_mask, entry->clk_src_id);
|
||||
}
|
||||
|
||||
static inline int is_usb(uint32_t idx)
|
||||
{
|
||||
return (idx == FUNIT_USBD || idx == FUNIT_USB2);
|
||||
}
|
||||
|
||||
void soc_configure_funits(const struct funit_cfg * const entries, size_t num)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
const struct funit_cfg * const entry = &entries[i];
|
||||
const struct funit_cfg_data *funit;
|
||||
const struct clk_dev_control *dev_control;
|
||||
int funit_usb = is_usb(entry->funit_index);
|
||||
|
||||
if (entry->funit_index >= FUNIT_INDEX_MAX) {
|
||||
printk(BIOS_ERR, "Error: Index out of bounds\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
funit = &funit_data[entry->funit_index];
|
||||
dev_control = funit->dev_control;
|
||||
|
||||
/* USB controllers have a fixed clock source. */
|
||||
if (!funit_usb)
|
||||
configure_clock(entry, funit);
|
||||
|
||||
clock_grp_enable_clear_reset(funit->clk_enb_val,
|
||||
dev_control->clk_enb_set,
|
||||
dev_control->rst_dev_clr);
|
||||
|
||||
if (funit_usb)
|
||||
usb_setup_utmip(funit->ctlr_base);
|
||||
|
||||
soc_configure_pads(entry->pad_cfg,entry->pad_cfg_size);
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__((weak)) usb_setup_utmip(void *usb_base)
|
||||
{
|
||||
/* default empty implementation required if usb.c is not included */
|
||||
printk(BIOS_ERR, "USB setup is not supported in current stage\n");
|
||||
}
|
31
src/soc/nvidia/tegra210/gic.c
Normal file
31
src/soc/nvidia/tegra210/gic.c
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <gic.h>
|
||||
#include <soc/addressmap.h>
|
||||
|
||||
void *gicd_base(void)
|
||||
{
|
||||
return (void *)(uintptr_t)TEGRA_GICD_BASE;
|
||||
}
|
||||
|
||||
void *gicc_base(void)
|
||||
{
|
||||
return (void *)(uintptr_t)TEGRA_GICC_BASE;
|
||||
}
|
57
src/soc/nvidia/tegra210/i2c.c
Normal file
57
src/soc/nvidia/tegra210/i2c.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/nvidia/tegra/i2c.h>
|
||||
|
||||
struct tegra_i2c_bus_info tegra_i2c_info[] = {
|
||||
{
|
||||
.base = (void *)TEGRA_I2C1_BASE,
|
||||
.reset_bit = CLK_L_I2C1,
|
||||
.reset_func = &clock_reset_l
|
||||
},
|
||||
{
|
||||
.base = (void *)TEGRA_I2C2_BASE,
|
||||
.reset_bit = CLK_H_I2C2,
|
||||
.reset_func = &clock_reset_h
|
||||
},
|
||||
{
|
||||
.base = (void *)TEGRA_I2C3_BASE,
|
||||
.reset_bit = CLK_U_I2C3,
|
||||
.reset_func = &clock_reset_u
|
||||
},
|
||||
{
|
||||
.base = (void *)TEGRA_I2C4_BASE,
|
||||
.reset_bit = CLK_V_I2C4,
|
||||
.reset_func = &clock_reset_v
|
||||
},
|
||||
{
|
||||
.base = (void *)TEGRA_I2C5_BASE,
|
||||
.reset_bit = CLK_H_I2C5,
|
||||
.reset_func = &clock_reset_h
|
||||
},
|
||||
{
|
||||
.base = (void *)TEGRA_I2C6_BASE,
|
||||
.reset_bit = CLK_X_I2C6,
|
||||
.reset_func = &clock_reset_x
|
||||
}
|
||||
};
|
||||
|
||||
unsigned g_num_i2c_buses = ARRAY_SIZE(tegra_i2c_info);
|
95
src/soc/nvidia/tegra210/i2c6.c
Normal file
95
src/soc/nvidia/tegra210/i2c6.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <delay.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clk_rst.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/nvidia/tegra/i2c.h>
|
||||
#include <soc/padconfig.h>
|
||||
#include <soc/power.h>
|
||||
|
||||
#define I2C6_PADCTL 0xC001
|
||||
#define DPAUX_HYBRID_PADCTL 0x545C0124
|
||||
#define DPAUX_HYBRID_SPARE 0x545C0134
|
||||
|
||||
static void enable_sor_periph_clocks(void)
|
||||
{
|
||||
clock_enable(CLK_L_HOST1X, 0, 0, 0, 0, CLK_X_DPAUX, 0);
|
||||
|
||||
/* Give clocks time to stabilize. */
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
}
|
||||
|
||||
static void disable_sor_periph_clocks(void)
|
||||
{
|
||||
clock_disable(CLK_L_HOST1X, 0, 0, 0, 0, CLK_X_DPAUX, 0);
|
||||
|
||||
/* Give clocks time to stabilize. */
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
}
|
||||
|
||||
static void unreset_sor_periphs(void)
|
||||
{
|
||||
clock_clr_reset(CLK_L_HOST1X, 0, 0, 0, 0, CLK_X_DPAUX, 0);
|
||||
}
|
||||
|
||||
void soc_configure_i2c6pad(void)
|
||||
{
|
||||
/*
|
||||
* I2C6 on Tegra1xx requires some special init.
|
||||
* The SOR block must be unpowergated, and a couple of
|
||||
* display-based peripherals must be clocked and taken
|
||||
* out of reset so that a DPAUX register can be
|
||||
* configured to enable the I2C6 mux routing.
|
||||
* Afterwards, we can disable clocks to the display blocks
|
||||
* and put Host1X back in reset. DPAUX must remain out of
|
||||
* reset and the SOR partition must remained unpowergated.
|
||||
*/
|
||||
soc_configure_host1x();
|
||||
|
||||
/* Now we can write the I2C6 mux in DPAUX */
|
||||
write32((void *)DPAUX_HYBRID_PADCTL, I2C6_PADCTL);
|
||||
/* Finally, power up the pads */
|
||||
write32((void *)DPAUX_HYBRID_SPARE, 0);
|
||||
|
||||
/*
|
||||
* Delay before turning off Host1X/DPAUX clocks.
|
||||
* This delay is needed to keep the sequence from
|
||||
* hanging the system.
|
||||
*/
|
||||
udelay(CLOCK_PLL_STABLE_DELAY_US);
|
||||
|
||||
/* Stop Host1X/DPAUX clocks and reset Host1X */
|
||||
disable_sor_periph_clocks();
|
||||
clock_set_reset_l(CLK_L_HOST1X);
|
||||
}
|
||||
|
||||
void soc_configure_host1x(void)
|
||||
{
|
||||
power_ungate_partition(POWER_PARTID_SOR);
|
||||
|
||||
/* Host1X needs a valid clock source so DPAUX can be accessed. */
|
||||
clock_configure_source(host1x, PLLP, 204000);
|
||||
|
||||
enable_sor_periph_clocks();
|
||||
remove_clamps(POWER_PARTID_SOR);
|
||||
unreset_sor_periphs();
|
||||
}
|
143
src/soc/nvidia/tegra210/include/soc/addressmap.h
Normal file
143
src/soc/nvidia/tegra210/include/soc/addressmap.h
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* (C) Copyright 2010,2011
|
||||
* NVIDIA Corporation <www.nvidia.com>
|
||||
*
|
||||
* 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 __SOC_NVIDIA_TEGRA210_INCLUDE_SOC_ADDRESS_MAP_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_INCLUDE_SOC_ADDRESS_MAP_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
TEGRA_SRAM_BASE = 0x40000000,
|
||||
TEGRA_SRAM_SIZE = 0x40000
|
||||
};
|
||||
|
||||
enum {
|
||||
TEGRA_ARM_PERIPHBASE = 0x50040000,
|
||||
TEGRA_GICD_BASE = 0x50041000,
|
||||
TEGRA_GICC_BASE = 0x50042000,
|
||||
TEGRA_ARM_DISPLAYA = 0x54200000,
|
||||
TEGRA_ARM_DISPLAYB = 0x54240000,
|
||||
TEGRA_DSIA_BASE = 0x54300000,
|
||||
TEGRA_DSIB_BASE = 0x54400000,
|
||||
TEGRA_ARM_SOR = 0x54540000,
|
||||
TEGRA_ARM_DPAUX = 0x545c0000,
|
||||
TEGRA_PG_UP_BASE = 0x60000000,
|
||||
TEGRA_TMRUS_BASE = 0x60005010,
|
||||
TEGRA_CLK_RST_BASE = 0x60006000,
|
||||
TEGRA_FLOW_BASE = 0x60007000,
|
||||
TEGRA_SB_BASE = 0x6000C200,
|
||||
TEGRA_GPIO_BASE = 0x6000D000,
|
||||
TEGRA_EVP_BASE = 0x6000F000,
|
||||
TEGRA_APB_DMA_BASE = 0x60020000,
|
||||
TEGRA_APB_MISC_BASE = 0x70000000,
|
||||
TEGRA_APB_MISC_GP_BASE = TEGRA_APB_MISC_BASE + 0x0800,
|
||||
TEGRA_APB_PINGROUP_BASE = TEGRA_APB_MISC_BASE + 0x0868,
|
||||
TEGRA_APB_PINMUX_BASE = TEGRA_APB_MISC_BASE + 0x3000,
|
||||
TEGRA_APB_UARTA_BASE = TEGRA_APB_MISC_BASE + 0x6000,
|
||||
TEGRA_APB_UARTB_BASE = TEGRA_APB_MISC_BASE + 0x6040,
|
||||
TEGRA_APB_UARTC_BASE = TEGRA_APB_MISC_BASE + 0x6200,
|
||||
TEGRA_APB_UARTD_BASE = TEGRA_APB_MISC_BASE + 0x6300,
|
||||
TEGRA_APB_UARTE_BASE = TEGRA_APB_MISC_BASE + 0x6400,
|
||||
TEGRA_NAND_BASE = TEGRA_APB_MISC_BASE + 0x8000,
|
||||
TEGRA_PWM_BASE = TEGRA_APB_MISC_BASE + 0xA000,
|
||||
TEGRA_I2C1_BASE = TEGRA_APB_MISC_BASE + 0xC000,
|
||||
TEGRA_SPI_BASE = TEGRA_APB_MISC_BASE + 0xC380,
|
||||
TEGRA_I2C2_BASE = TEGRA_APB_MISC_BASE + 0xC400,
|
||||
TEGRA_I2C3_BASE = TEGRA_APB_MISC_BASE + 0xC500,
|
||||
TEGRA_I2C4_BASE = TEGRA_APB_MISC_BASE + 0xC700,
|
||||
TEGRA_I2C5_BASE = TEGRA_APB_MISC_BASE + 0xD000,
|
||||
TEGRA_I2C6_BASE = TEGRA_APB_MISC_BASE + 0xD100,
|
||||
TEGRA_SPI1_BASE = TEGRA_APB_MISC_BASE + 0xD400,
|
||||
TEGRA_SPI2_BASE = TEGRA_APB_MISC_BASE + 0xD600,
|
||||
TEGRA_SPI3_BASE = TEGRA_APB_MISC_BASE + 0xD800,
|
||||
TEGRA_SPI4_BASE = TEGRA_APB_MISC_BASE + 0xDA00,
|
||||
TEGRA_SPI5_BASE = TEGRA_APB_MISC_BASE + 0xDC00,
|
||||
TEGRA_SPI6_BASE = TEGRA_APB_MISC_BASE + 0xDE00,
|
||||
TEGRA_SBC1_BASE = TEGRA_SPI1_BASE,
|
||||
TEGRA_SBC2_BASE = TEGRA_SPI2_BASE,
|
||||
TEGRA_SBC3_BASE = TEGRA_SPI3_BASE,
|
||||
TEGRA_SBC4_BASE = TEGRA_SPI4_BASE,
|
||||
TEGRA_SBC5_BASE = TEGRA_SPI5_BASE,
|
||||
TEGRA_SBC6_BASE = TEGRA_SPI6_BASE,
|
||||
TEGRA_PMC_BASE = TEGRA_APB_MISC_BASE + 0xE400,
|
||||
TEGRA_FUSE_BASE = TEGRA_APB_MISC_BASE + 0xF800,
|
||||
TEGRA_MC_BASE = 0x70019000,
|
||||
TEGRA_EMC_BASE = 0x7001B000,
|
||||
TEGRA_CLUSTER_CLOCK_BASE = 0x70040000,
|
||||
TEGRA_QSPI_BASE = 0x70410000,
|
||||
TEGRA_CSITE_BASE = 0x70800000,
|
||||
TEGRA_SDMMC_BASE = 0x700b0000,
|
||||
TEGRA_SDMMC1_BASE = TEGRA_SDMMC_BASE + 0x0000,
|
||||
TEGRA_SDMMC2_BASE = TEGRA_SDMMC_BASE + 0x0200,
|
||||
TEGRA_SDMMC3_BASE = TEGRA_SDMMC_BASE + 0x0400,
|
||||
TEGRA_SDMMC4_BASE = TEGRA_SDMMC_BASE + 0x0600,
|
||||
TEGRA_MIPI_CAL_BASE = 0x700E3000,
|
||||
TEGRA_SYSCTR0_BASE = 0x700F0000,
|
||||
TEGRA_I2S1_BASE = 0x70301100,
|
||||
TEGRA_USBD_BASE = 0x7D000000,
|
||||
TEGRA_USB2_BASE = 0x7D004000,
|
||||
TEGRA_USB3_BASE = 0x7D008000,
|
||||
};
|
||||
|
||||
enum {
|
||||
TEGRA_I2C_BASE_COUNT = 6,
|
||||
};
|
||||
|
||||
#define GPU_CARVEOUT_SIZE_MB 1
|
||||
|
||||
/* Return total size of DRAM memory configured on the platform. */
|
||||
int sdram_size_mb(void);
|
||||
|
||||
/* Find memory below and above 4GiB boundary repsectively. All units 1MiB. */
|
||||
void memory_in_range_below_4gb(uintptr_t *base_mib, uintptr_t *end_mib);
|
||||
void memory_in_range_above_4gb(uintptr_t *base_mib, uintptr_t *end_mib);
|
||||
|
||||
enum {
|
||||
CARVEOUT_TZ,
|
||||
CARVEOUT_SEC,
|
||||
CARVEOUT_MTS,
|
||||
CARVEOUT_VPR,
|
||||
CARVEOUT_GPU,
|
||||
CARVEOUT_NUM,
|
||||
};
|
||||
|
||||
/* Provided the careout id, obtain the base and size in 1MiB units. */
|
||||
void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib);
|
||||
void print_carveouts(void);
|
||||
|
||||
/*
|
||||
* Add any board-specific memory ranges to the address map when executing
|
||||
* on aarchv8 core.
|
||||
*/
|
||||
struct memranges;
|
||||
void mainboard_add_memory_ranges(struct memranges *map);
|
||||
|
||||
/*
|
||||
* There are complications accessing the Trust Zone carveout region. The
|
||||
* AVP cannot access these registers and the CPU can't access this register
|
||||
* as a non-secure access. When the page tables live in non-secure memory
|
||||
* these registers cannot be accessed either. Thus, this function handles
|
||||
* both the AVP case and non-secured access case by keeping global state.
|
||||
*/
|
||||
void trustzone_region_init(void);
|
||||
void gpu_region_init(void);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_INCLUDE_SOC_ADDRESS_MAP_H__ */
|
33
src/soc/nvidia/tegra210/include/soc/ccplex.h
Normal file
33
src/soc/nvidia/tegra210/include/soc/ccplex.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_CCPLEX_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_CCPLEX_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MTS_LOAD_ADDRESS 0x82000000
|
||||
|
||||
/* Prepare the clocks and rails to start the cpu. */
|
||||
void ccplex_cpu_prepare(void);
|
||||
|
||||
/* Start cpu0 and have it start executing at entry_addr */
|
||||
void ccplex_cpu_start(void *entry_addr);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_CCPLEX_H__ */
|
607
src/soc/nvidia/tegra210/include/soc/clk_rst.h
Normal file
607
src/soc/nvidia/tegra210/include/soc/clk_rst.h
Normal file
@ -0,0 +1,607 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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 _TEGRA210_CLK_RST_H_
|
||||
#define _TEGRA210_CLK_RST_H_
|
||||
#include <stdint.h>
|
||||
#include <stddef.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_misc; /* _PLLC_MISC, 0x088 */
|
||||
u32 pllc_misc_1; /* _PLLC_MISC_1, 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[1]; /* 0x0d4 */
|
||||
u32 plld_misc1; /* _PLLD_MISC1, 0x0d8 */
|
||||
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_dev_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 clk_out_enb_y; /* _CLK_OUT_ENB_Y_0, 0x298 */
|
||||
u32 clk_enb_y_set; /* _CLK_ENB_Y_SET_0, 0x29C */
|
||||
u32 clk_enb_y_clr; /* _CLK_ENB_Y_CLR_0, 0x2A0 */
|
||||
u32 rst_dev_y; /* _RST_DEVICES_Y_0, 0x2A4 */
|
||||
u32 rst_dev_y_set; /* _RST_DEV_Y_SET_0, 0x2A8 */
|
||||
u32 rst_dev_y_clr; /* _RST_DEV_Y_CLR_0, 0x2AC */
|
||||
u32 _rsv19[17]; /* 0x2B0-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_clr; /* _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 */
|
||||
u32 _rsv33[5]; /* 0x648-658 */
|
||||
u32 clk_src_i2c6; /* _CLK_SOURCE_I2C6, 0x65c */
|
||||
u32 clk_src_mipibif; /* _CLK_SOURCE_MIPIBIF, 0x660 */
|
||||
u32 clk_src_emc_dll; /* _CLK_SOURCE_EMC_DLL, 0x664 */
|
||||
u32 _rsv34; /* 0x668 */
|
||||
u32 clk_src_uart_fst_mipi_cal; /* _CLK_SOURCE_UART_FST_MIP_CAL, 0x66c */
|
||||
u32 _rsv35[21]; /* 0x670-6c0 */
|
||||
u32 clk_src_qspi; /* _CLK_SOURCE_QSPI 0x6C4 */
|
||||
};
|
||||
check_member(clk_rst_ctlr, clk_src_qspi, 0x6C4);
|
||||
|
||||
#define CLK_RST_REG(field_) \
|
||||
(&(((struct clk_rst_ctlr *)TEGRA_CLK_RST_BASE)->field_))
|
||||
|
||||
/* L, H, U, V, W, X, Y */
|
||||
#define DEV_CONFIG_BLOCKS 7
|
||||
|
||||
#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)
|
||||
#define CLK_ENB_EMC_DLL (1 << 14)
|
||||
|
||||
/* _CCLK_BURST_POLICY 0x20 */
|
||||
#define CCLK_BURST_POLICY_VAL 0x20008888
|
||||
/* CLK_M divisor */
|
||||
#define CLK_M_DIVISOR_MASK (0x3 << 2)
|
||||
#define CLK_M_DIVISOR_BY_2 (1 << 2)
|
||||
|
||||
/* 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 PLLC_BASE_LOCK (1U << 26)
|
||||
|
||||
#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 (0x1fU << PLL_BASE_DIVP_SHIFT)
|
||||
#define PLLCMX_BASE_DIVN_MASK (0xffU << PLL_BASE_DIVN_SHIFT)
|
||||
#define PLLCMX_BASE_DIVM_MASK (0xffU << PLL_BASE_DIVM_SHIFT)
|
||||
|
||||
/* Added based on T210 TRM */
|
||||
#define PLLC_MISC_RESET (1U << 30)
|
||||
#define PLLC_MISC_1_IDDQ (1U << 27)
|
||||
#define PLLD_N_SHIFT 11
|
||||
#define PLLD_M_SHIFT 0
|
||||
#define PLLD_P_SHIFT 20
|
||||
#define PLLD_MISC1_SETUP 0x20
|
||||
#define PLLD_MISC_EN_SDM (1 << 16)
|
||||
#define PLLD_MISC_SDM_DIN 0x9aa
|
||||
|
||||
/* 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)
|
||||
#define PLLM_EN_LCKDET (1 << 4)
|
||||
|
||||
/* PLLU specific registers */
|
||||
#define PLLU_MISC_IDDQ (1U << 31)
|
||||
|
||||
/* UTMIP PLL specific registers */
|
||||
#define UTMIP_CFG0_PLL_MDIV_SHIFT (8)
|
||||
#define UTMIP_CFG0_PLL_NDIV_SHIFT (16)
|
||||
#define UTMIP_CFG1_XTAL_FREQ_COUNT_SHIFT (0)
|
||||
#define UTMIP_CFG1_FORCE_PLL_ACTIVE_POWERDOWN_DISABLE (0 << 12)
|
||||
#define UTMIP_CFG1_FORCE_PLL_ENABLE_POWERDOWN_DISABLE (0 << 14)
|
||||
#define UTMIP_CFG1_FORCE_PLL_ENABLE_POWERUP_ENABLE (1 << 15)
|
||||
#define UTMIP_CFG1_FORCE_PLLU_POWERDOWN_ENABLE (1 << 16)
|
||||
#define UTMIP_CFG1_PLLU_ENABLE_DLY_COUNT_SHIFT (27)
|
||||
#define UTMIP_CFG2_FORCE_PD_SAMP_A_POWERDOWN_DISABLE (0 << 0)
|
||||
#define UTMIP_CFG2_FORCE_PD_SAMP_B_POWERDOWN_DISABLE (0 << 2)
|
||||
#define UTMIP_CFG2_FORCE_PD_SAMP_C_POWERDOWN_DISABLE (0 << 4)
|
||||
#define UTMIP_CFG2_PLLU_STABLE_COUNT_SHIFT (6)
|
||||
#define UTMIP_CFG2_PLL_ACTIVE_DLY_COUNT_SHIFT (18)
|
||||
#define UTMIP_CFG2_PHY_XTAL_CLOCKEN (1U << 30)
|
||||
|
||||
/* 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
|
||||
|
||||
/* This bit is different all over the place. */
|
||||
#define PLLDPD2_MISC_LOCK_ENABLE (1 << 30)
|
||||
#define PLLU_MISC_LOCK_ENABLE (1 << 29)
|
||||
#define PLLD_MISC_LOCK_ENABLE (1 << 18)
|
||||
#define PLLD_MISC_CLK_ENABLE (1 << 21)
|
||||
#define PLLPAXS_MISC_LOCK_ENABLE (1 << 18)
|
||||
#define PLLE_MISC_LOCK_ENABLE (1 << 9)
|
||||
|
||||
/* 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 EMC_2X_CLK_SRC_SHIFT 29
|
||||
#define PLLM_UD 4
|
||||
|
||||
#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,
|
||||
};
|
||||
|
||||
#define TIMERUS_CNTR_1US 0x0
|
||||
#define TIMERUS_USEC_CFG 0x4
|
||||
#define TIMERUS_USEC_CFG_19P2_CLK_M 0x045F
|
||||
|
||||
#endif /* _TEGRA210_CLK_RST_H_ */
|
442
src/soc/nvidia/tegra210/include/soc/clock.h
Normal file
442
src/soc/nvidia/tegra210/include/soc/clock.h
Normal file
@ -0,0 +1,442 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
* Copyright (c) 2013-2015, 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 __SOC_NVIDIA_TEGRA210_CLOCK_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_CLOCK_H__
|
||||
|
||||
#include <arch/hlt.h>
|
||||
#include <arch/io.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/clk_rst.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
enum {
|
||||
CLK_L_CPU = 0x1 << 0,
|
||||
CLK_L_COP = 0x1 << 1,
|
||||
CLK_L_TRIG_SYS = 0x1 << 2,
|
||||
CLK_L_RTC = 0x1 << 4,
|
||||
CLK_L_TMR = 0x1 << 5,
|
||||
CLK_L_UARTA = 0x1 << 6,
|
||||
CLK_L_UARTB = 0x1 << 7,
|
||||
CLK_L_GPIO = 0x1 << 8,
|
||||
CLK_L_SDMMC2 = 0x1 << 9,
|
||||
CLK_L_SPDIF = 0x1 << 10,
|
||||
CLK_L_I2S2 = 0x1 << 11,
|
||||
CLK_L_I2C1 = 0x1 << 12,
|
||||
CLK_L_NDFLASH = 0x1 << 13,
|
||||
CLK_L_SDMMC1 = 0x1 << 14,
|
||||
CLK_L_SDMMC4 = 0x1 << 15,
|
||||
CLK_L_PWM = 0x1 << 17,
|
||||
CLK_L_I2S3 = 0x1 << 18,
|
||||
CLK_L_EPP = 0x1 << 19,
|
||||
CLK_L_VI = 0x1 << 20,
|
||||
CLK_L_2D = 0x1 << 21,
|
||||
CLK_L_USBD = 0x1 << 22,
|
||||
CLK_L_ISP = 0x1 << 23,
|
||||
CLK_L_3D = 0x1 << 24,
|
||||
CLK_L_DISP2 = 0x1 << 26,
|
||||
CLK_L_DISP1 = 0x1 << 27,
|
||||
CLK_L_HOST1X = 0x1 << 28,
|
||||
CLK_L_VCP = 0x1 << 29,
|
||||
CLK_L_I2S1 = 0x1 << 30,
|
||||
CLK_L_CACHE2 = 0x1 << 31,
|
||||
|
||||
CLK_H_MEM = 0x1 << 0,
|
||||
CLK_H_AHBDMA = 0x1 << 1,
|
||||
CLK_H_APBDMA = 0x1 << 2,
|
||||
CLK_H_KBC = 0x1 << 4,
|
||||
CLK_H_STAT_MON = 0x1 << 5,
|
||||
CLK_H_PMC = 0x1 << 6,
|
||||
CLK_H_FUSE = 0x1 << 7,
|
||||
CLK_H_KFUSE = 0x1 << 8,
|
||||
CLK_H_SBC1 = 0x1 << 9,
|
||||
CLK_H_SNOR = 0x1 << 10,
|
||||
CLK_H_JTAG2TBC = 0x1 << 11,
|
||||
CLK_H_SBC2 = 0x1 << 12,
|
||||
CLK_H_SBC3 = 0x1 << 14,
|
||||
CLK_H_I2C5 = 0x1 << 15,
|
||||
CLK_H_DSI = 0x1 << 16,
|
||||
CLK_H_HSI = 0x1 << 18,
|
||||
CLK_H_HDMI = 0x1 << 19,
|
||||
CLK_H_CSI = 0x1 << 20,
|
||||
CLK_H_I2C2 = 0x1 << 22,
|
||||
CLK_H_UARTC = 0x1 << 23,
|
||||
CLK_H_MIPI_CAL = 0x1 << 24,
|
||||
CLK_H_EMC = 0x1 << 25,
|
||||
CLK_H_USB2 = 0x1 << 26,
|
||||
CLK_H_USB3 = 0x1 << 27,
|
||||
CLK_H_MPE = 0x1 << 28,
|
||||
CLK_H_VDE = 0x1 << 29,
|
||||
CLK_H_BSEA = 0x1 << 30,
|
||||
CLK_H_BSEV = 0x1 << 31,
|
||||
|
||||
CLK_U_UARTD = 0x1 << 1,
|
||||
CLK_U_UARTE = 0x1 << 2,
|
||||
CLK_U_I2C3 = 0x1 << 3,
|
||||
CLK_U_SBC4 = 0x1 << 4,
|
||||
CLK_U_SDMMC3 = 0x1 << 5,
|
||||
CLK_U_PCIE = 0x1 << 6,
|
||||
CLK_U_OWR = 0x1 << 7,
|
||||
CLK_U_AFI = 0x1 << 8,
|
||||
CLK_U_CSITE = 0x1 << 9,
|
||||
CLK_U_PCIEXCLK = 0x1 << 10,
|
||||
CLK_U_AVPUCQ = 0x1 << 11,
|
||||
CLK_U_TRACECLKIN = 0x1 << 13,
|
||||
CLK_U_SOC_THERM = 0x1 << 14,
|
||||
CLK_U_DTV = 0x1 << 15,
|
||||
CLK_U_NAND_SPEED = 0x1 << 16,
|
||||
CLK_U_I2C_SLOW = 0x1 << 17,
|
||||
CLK_U_DSIB = 0x1 << 18,
|
||||
CLK_U_TSEC = 0x1 << 19,
|
||||
CLK_U_IRAMA = 0x1 << 20,
|
||||
CLK_U_IRAMB = 0x1 << 21,
|
||||
CLK_U_IRAMC = 0x1 << 22,
|
||||
|
||||
// Clock reset.
|
||||
CLK_U_EMUCIF = 0x1 << 23,
|
||||
// Clock enable.
|
||||
CLK_U_IRAMD = 0x1 << 23,
|
||||
|
||||
CLK_U_CRAM2 = 0x2 << 24,
|
||||
CLK_U_XUSB_HOST = 0x1 << 25,
|
||||
CLK_U_MSENC = 0x1 << 27,
|
||||
CLK_U_SUS_OUT = 0x1 << 28,
|
||||
CLK_U_DEV2_OUT = 0x1 << 29,
|
||||
CLK_U_DEV1_OUT = 0x1 << 30,
|
||||
CLK_U_XUSB_DEV = 0x1 << 31,
|
||||
|
||||
CLK_V_CPUG = 0x1 << 0,
|
||||
CLK_V_CPULP = 0x1 << 1,
|
||||
CLK_V_3D2 = 0x1 << 2,
|
||||
CLK_V_MSELECT = 0x1 << 3,
|
||||
CLK_V_I2S4 = 0x1 << 5,
|
||||
CLK_V_I2S5 = 0x1 << 6,
|
||||
CLK_V_I2C4 = 0x1 << 7,
|
||||
CLK_V_SBC5 = 0x1 << 8,
|
||||
CLK_V_SBC6 = 0x1 << 9,
|
||||
CLK_V_AHUB = 0x1 << 10,
|
||||
CLK_V_APB2APE = 0x1 << 11,
|
||||
CLK_V_HDA2CODEC_2X = 0x1 << 15,
|
||||
CLK_V_ATOMICS = 0x1 << 16,
|
||||
CLK_V_ACTMON = 0x1 << 23,
|
||||
CLK_V_EXTPERIPH1 = 0x1 << 24,
|
||||
CLK_V_SATA = 0x1 << 28,
|
||||
CLK_V_HDA = 0x1 << 29,
|
||||
|
||||
CLK_W_HDA2HDMICODEC = 0x1 << 0,
|
||||
CLK_W_SATACOLD = 0x1 << 1,
|
||||
CLK_W_CEC = 0x1 << 8,
|
||||
CLK_W_XUSB_PADCTL = 0x1 << 14,
|
||||
CLK_W_ENTROPY = 0x1 << 21,
|
||||
CLK_W_DVFS = 0x1 << 27,
|
||||
CLK_W_XUSB_SS = 0x1 << 28,
|
||||
|
||||
CLK_X_GPU = 0x1 << 24,
|
||||
CLK_X_SOR1 = 0x1 << 23,
|
||||
CLK_X_SOR0 = 0x1 << 22,
|
||||
CLK_X_DPAUX = 0x1 << 21,
|
||||
CLK_X_VIC = 0x1 << 18,
|
||||
CLK_X_UART_FST_MIPI_CAL = 0x1 << 17,
|
||||
CLK_X_MIPIBIF = 0x1 << 13,
|
||||
CLK_X_I2C6 = 0x1 << 6,
|
||||
CLK_X_ETR = 0x1 << 3,
|
||||
CLK_X_SPARE = 0x1 << 0,
|
||||
|
||||
CLK_Y_APE = 0x1 << 6,
|
||||
CLK_Y_QSPI = 0x1 << 19,
|
||||
};
|
||||
|
||||
enum {
|
||||
PLLP = 0,
|
||||
PLLC2 = 1,
|
||||
PLLC = 2,
|
||||
PLLC_OUT1 = 3,
|
||||
PLLM = 4,
|
||||
CLK_M = 5,
|
||||
CLK_S = 6,
|
||||
PLLE = 7,
|
||||
PLLA = 8,
|
||||
PLLD = 9,
|
||||
PLLD2 = 10,
|
||||
PLLC4_OUT0 = 11,
|
||||
PLLC4_OUT1 = 12,
|
||||
PLLC4_OUT2 = 13,
|
||||
PLLC4_OUT3 = 14,
|
||||
PLLC4_OUT0_L = 15,
|
||||
PLLC4_OUT1_L = 16,
|
||||
PLLC4_OUT2_L = 17,
|
||||
PLLD_OUT0 = 18,
|
||||
PLLP_OUT3 = 19,
|
||||
PLLC2_OUT0 = 20,
|
||||
UNUSED0 = 100,
|
||||
UNUSED1 = 101,
|
||||
UNUSED2 = 102,
|
||||
UNUSED3 = 103,
|
||||
UNUSED4 = 104,
|
||||
UNUSED5 = 105,
|
||||
UNUSED6 = 106,
|
||||
UNUSED7 = 107,
|
||||
};
|
||||
|
||||
#define CLK_SRC_DEV_ID(dev, src) CLK_SRC_##dev##_##src
|
||||
#define CLK_SRC_FREQ_ID(dev, src) CLK_SRC_FREQ_##dev##_##src
|
||||
|
||||
#define CLK_SRC_DEVICE(dev, a, b, c, d, e, f, g, h) \
|
||||
CLK_SRC_DEV_ID(dev, a) = 0, \
|
||||
CLK_SRC_DEV_ID(dev, b) = 1, \
|
||||
CLK_SRC_DEV_ID(dev, c) = 2, \
|
||||
CLK_SRC_DEV_ID(dev, d) = 3, \
|
||||
CLK_SRC_DEV_ID(dev, e) = 4, \
|
||||
CLK_SRC_DEV_ID(dev, f) = 5, \
|
||||
CLK_SRC_DEV_ID(dev, g) = 6, \
|
||||
CLK_SRC_DEV_ID(dev, h) = 7, \
|
||||
CLK_SRC_FREQ_ID(dev, a) = a, \
|
||||
CLK_SRC_FREQ_ID(dev, b) = b, \
|
||||
CLK_SRC_FREQ_ID(dev, c) = c, \
|
||||
CLK_SRC_FREQ_ID(dev, d) = d, \
|
||||
CLK_SRC_FREQ_ID(dev, e) = e, \
|
||||
CLK_SRC_FREQ_ID(dev, f) = f, \
|
||||
CLK_SRC_FREQ_ID(dev, g) = g, \
|
||||
CLK_SRC_FREQ_ID(dev, h) = h
|
||||
|
||||
enum {
|
||||
CLK_SRC_DEVICE(disp1, PLLP, PLLD, PLLD_OUT0, UNUSED3, UNUSED4, PLLD2,
|
||||
CLK_M, UNUSED7),
|
||||
CLK_SRC_DEVICE(host1x, PLLC4_OUT1, PLLC2, PLLC, PLLC4_OUT2, PLLP, CLK_M,
|
||||
PLLA, PLLC4_OUT0),
|
||||
CLK_SRC_DEVICE(I2C1, PLLP, PLLC2, PLLC, PLLC4_OUT0, UNUSED4, PLLC4_OUT1,
|
||||
CLK_M, PLLC4_OUT2),
|
||||
CLK_SRC_DEVICE(I2C2, PLLP, PLLC2, PLLC, PLLC4_OUT0, UNUSED4, PLLC4_OUT1,
|
||||
CLK_M, PLLC4_OUT2),
|
||||
CLK_SRC_DEVICE(I2C3, PLLP, PLLC2, PLLC, PLLC4_OUT0, UNUSED4, PLLC4_OUT1,
|
||||
CLK_M, PLLC4_OUT2),
|
||||
CLK_SRC_DEVICE(I2C5, PLLP, PLLC2, PLLC, PLLC4_OUT0, UNUSED4, PLLC4_OUT1,
|
||||
CLK_M, PLLC4_OUT2),
|
||||
CLK_SRC_DEVICE(I2C6, PLLP, PLLC2, PLLC, PLLC4_OUT0, UNUSED4, PLLC4_OUT1,
|
||||
CLK_M, PLLC4_OUT2),
|
||||
CLK_SRC_DEVICE(I2S1, PLLA, UNUSED1, CLK_S, UNUSED3, PLLP, UNUSED5,
|
||||
CLK_M, UNUSED7),
|
||||
CLK_SRC_DEVICE(mselect, PLLP, PLLC2, PLLC, PLLC4_OUT2, PLLC4_OUT1,
|
||||
CLK_S, CLK_M, PLLC4_OUT0),
|
||||
CLK_SRC_DEVICE(SPI1, PLLP, PLLC2, PLLC, PLLC4_OUT0, UNUSED4, PLLC4_OUT1,
|
||||
CLK_M, PLLC4_OUT2),
|
||||
CLK_SRC_DEVICE(SPI4, PLLP, PLLC2, PLLC, PLLC4_OUT0, UNUSED4, PLLC4_OUT1,
|
||||
CLK_M, PLLC4_OUT2),
|
||||
CLK_SRC_DEVICE(SDMMC1, PLLP, PLLA, PLLC, PLLC4_OUT2, PLLM, PLLE, CLK_M,
|
||||
PLLC4_OUT0),
|
||||
CLK_SRC_DEVICE(SDMMC4, PLLP, PLLC4_OUT2_L, PLLC4_OUT0_L, PLLC4_OUT2,
|
||||
PLLC4_OUT1, PLLC4_OUT1_L, CLK_M, PLLC4_OUT0),
|
||||
CLK_SRC_DEVICE(UARTA, PLLP, PLLC2, PLLC, PLLC4_OUT0, UNUSED4,
|
||||
PLLC4_OUT1, CLK_M, PLLC4_OUT2),
|
||||
CLK_SRC_DEVICE(i2s1, PLLA, UNUSED1, CLK_S, UNUSED3, PLLP, UNUSED5,
|
||||
CLK_M, UNUSED7),
|
||||
CLK_SRC_DEVICE(extperiph1, PLLA, CLK_S, PLLP, CLK_M, PLLE, UNUSED5,
|
||||
UNUSED6, UNUSED7),
|
||||
CLK_SRC_DEVICE(QSPI, PLLP, PLLC_OUT1, PLLC, UNUSED3, PLLC4_OUT2,
|
||||
PLLC4_OUT1, CLK_M, PLLC4_OUT0),
|
||||
CLK_SRC_DEVICE(uart_fst_mipi_cal, PLLP_OUT3, PLLP, PLLC, UNUSED3, PLLC2_OUT0,
|
||||
UNUSED5, CLK_M, UNUSED7),
|
||||
};
|
||||
|
||||
/* PLL stabilization delay in usec */
|
||||
#define CLOCK_PLL_STABLE_DELAY_US 300
|
||||
|
||||
#define IO_STABILIZATION_DELAY (2)
|
||||
#define LOGIC_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.
|
||||
* U7.1 format is defined as (ddddddd+1) + (h*.5)
|
||||
* The lowest order bit is actually a fractional bit.
|
||||
* Hence, the divider can be thought of as 9 bits.
|
||||
* So:
|
||||
* divider = ((ref/freq) << 1 - 1) (upper 7 bits) |
|
||||
* (ref/freq & 1) (low order half-bit)
|
||||
* however we can't do fractional arithmetic ... these are integers!
|
||||
* So we normalize by shifting the result left 1 bit, and extracting
|
||||
* ddddddd and h directly to the returned u8.
|
||||
* divider = 2*(ref/freq);
|
||||
* We want to
|
||||
* preserve 7 bits of divisor and one bit of fraction, in 8 bits, as well as
|
||||
* subtract one from ddddddd. Since we computed ref*2, the dddddd is now nicely
|
||||
* situated in the upper 7 bits, and the h is sitting there in the low order
|
||||
* bit. To subtract 1 from ddddddd, just subtract 2 from the 8-bit number
|
||||
* 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) (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.
|
||||
* The idea is that we need to divide a ref clock by a divisor
|
||||
* in U7.1 format, where 7 upper bits are the integer
|
||||
* and lowest order bit is a fraction.
|
||||
* from the book, U7.1 is (ddddddd+1) + (h*.5)
|
||||
* To normalize to an actual number, we might do this:
|
||||
* ((d>>7+1)&0x7f) + (d&1 >> 1)
|
||||
* but as you might guess, the low order bit would be lost.
|
||||
* Since we can't express the fractional bit, we need to multiply it all by 2.
|
||||
* ((d + 2)&0xfe) + (d & 1)
|
||||
* Since we're just adding +2, the lowest order bit is preserved. Hence
|
||||
* (d+2) is the same as ((d + 2)&0xfe) + (d & 1)
|
||||
*
|
||||
* Since you multiply denominator * 2 (by NOT shifting it),
|
||||
* you multiply numerator * 2 to cancel it out.
|
||||
*/
|
||||
#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 get_i2c_clk_div(src,freq) (div_round_up(src, (freq) * (0x19 + 1) * 8) - 1)
|
||||
#define get_clk_div(src,freq) CLK_DIVIDER(src,freq)
|
||||
#define CLK_DIV_MASK 0xff
|
||||
#define CLK_DIV_MASK_I2C 0xffff
|
||||
|
||||
#define clock_configure_source(device, src, freq) \
|
||||
_clock_set_div(CLK_RST_REG(clk_src_##device), #device, \
|
||||
get_clk_div(TEGRA_##src##_KHZ, freq), CLK_DIV_MASK, \
|
||||
CLK_SRC_DEV_ID(device, src))
|
||||
|
||||
/* soc-specific */
|
||||
#define TEGRA_CLK_M_KHZ (clock_get_osc_khz()/2)
|
||||
#define TEGRA_PLLX_KHZ CONFIG_PLLX_KHZ
|
||||
#define TEGRA_PLLP_KHZ (408000)
|
||||
#define TEGRA_PLLP_OUT3_KHZ (68000)
|
||||
#define TEGRA_PLLC_KHZ (600000)
|
||||
#define TEGRA_PLLD_KHZ (925000)
|
||||
#define TEGRA_PLLD_OUT0_KHZ (TEGRA_PLLD_KHZ/2)
|
||||
#define TEGRA_PLLU_KHZ (960000)
|
||||
|
||||
#define clock_enable(l, h, u, v, w, x, y) \
|
||||
do { \
|
||||
u32 bits[DEV_CONFIG_BLOCKS] = {l, h, u, v, w, x, y}; \
|
||||
clock_enable_regs(bits); \
|
||||
} while (0)
|
||||
|
||||
#define clock_disable(l, h, u, v, w, x, y) \
|
||||
do { \
|
||||
u32 bits[DEV_CONFIG_BLOCKS] = {l, h, u, v, w, x, y}; \
|
||||
clock_disable_regs(bits); \
|
||||
} while (0)
|
||||
|
||||
#define clock_set_reset(l, h, u, v, w, x, y) \
|
||||
do { \
|
||||
u32 bits[DEV_CONFIG_BLOCKS] = {l, h, u, v, w, x, y}; \
|
||||
clock_set_reset_regs(bits); \
|
||||
} while (0)
|
||||
|
||||
#define clock_clr_reset(l, h, u, v, w, x, y) \
|
||||
do { \
|
||||
u32 bits[DEV_CONFIG_BLOCKS] = {l, h, u, v, w, x, y}; \
|
||||
clock_clr_reset_regs(bits); \
|
||||
} while (0)
|
||||
|
||||
#define clock_enable_l(l) clock_enable(l, 0, 0, 0, 0, 0, 0)
|
||||
#define clock_enable_h(h) clock_enable(0, h, 0, 0, 0, 0, 0)
|
||||
#define clock_enable_u(u) clock_enable(0, 0, u, 0, 0, 0, 0)
|
||||
#define clock_enable_v(v) clock_enable(0, 0, 0, v, 0, 0, 0)
|
||||
#define clock_enable_w(w) clock_enable(0, 0, 0, 0, w, 0, 0)
|
||||
#define clock_enable_x(x) clock_enable(0, 0, 0, 0, 0, x, 0)
|
||||
#define clock_enable_y(y) clock_enable(0, 0, 0, 0, 0, 0, y)
|
||||
|
||||
#define clock_disable_l(l) clock_disable(l, 0, 0, 0, 0, 0, 0)
|
||||
#define clock_disable_h(h) clock_disable(0, h, 0, 0, 0, 0, 0)
|
||||
#define clock_disable_u(u) clock_disable(0, 0, u, 0, 0, 0, 0)
|
||||
#define clock_disable_v(v) clock_disable(0, 0, 0, v, 0, 0, 0)
|
||||
#define clock_disable_w(w) clock_disable(0, 0, 0, 0, w, 0, 0)
|
||||
#define clock_disable_x(x) clock_disable(0, 0, 0, 0, 0, x, 0)
|
||||
#define clock_disable_y(y) clock_disable(0, 0, 0, 0, 0, 0, y)
|
||||
|
||||
#define clock_set_reset_l(l) clock_set_reset(l, 0, 0, 0, 0, 0, 0)
|
||||
#define clock_set_reset_h(h) clock_set_reset(0, h, 0, 0, 0, 0, 0)
|
||||
#define clock_set_reset_u(u) clock_set_reset(0, 0, u, 0, 0, 0, 0)
|
||||
#define clock_set_reset_v(v) clock_set_reset(0, 0, 0, v, 0, 0, 0)
|
||||
#define clock_set_reset_w(w) clock_set_reset(0, 0, 0, 0, w, 0, 0)
|
||||
#define clock_set_reset_x(x) clock_set_reset(0, 0, 0, 0, 0, x, 0)
|
||||
#define clock_set_reset_y(x) clock_set_reset(0, 0, 0, 0, 0, y, 0)
|
||||
|
||||
#define clock_clr_reset_l(l) clock_clr_reset(l, 0, 0, 0, 0, 0, 0)
|
||||
#define clock_clr_reset_h(h) clock_clr_reset(0, h, 0, 0, 0, 0, 0)
|
||||
#define clock_clr_reset_u(u) clock_clr_reset(0, 0, u, 0, 0, 0, 0)
|
||||
#define clock_clr_reset_v(v) clock_clr_reset(0, 0, 0, v, 0, 0, 0)
|
||||
#define clock_clr_reset_w(w) clock_clr_reset(0, 0, 0, 0, w, 0, 0)
|
||||
#define clock_clr_reset_x(x) clock_clr_reset(0, 0, 0, 0, 0, x, 0)
|
||||
#define clock_clr_reset_y(y) clock_clr_reset(0, 0, 0, 0, 0, 0, y)
|
||||
|
||||
#define clock_enable_clear_reset_l(l) \
|
||||
clock_enable_clear_reset(l, 0, 0, 0, 0, 0, 0)
|
||||
#define clock_enable_clear_reset_h(h) \
|
||||
clock_enable_clear_reset(0, h, 0, 0, 0, 0, 0)
|
||||
#define clock_enable_clear_reset_u(u) \
|
||||
clock_enable_clear_reset(0, 0, u, 0, 0, 0, 0)
|
||||
#define clock_enable_clear_reset_v(v) \
|
||||
clock_enable_clear_reset(0, 0, 0, v, 0, 0, 0)
|
||||
#define clock_enable_clear_reset_w(w) \
|
||||
clock_enable_clear_reset(0, 0, 0, 0, w, 0, 0)
|
||||
#define clock_enable_clear_reset_x(x) \
|
||||
clock_enable_clear_reset(0, 0, 0, 0, 0, x, 0)
|
||||
#define clock_enable_clear_reset_y(y) \
|
||||
clock_enable_clear_reset(0, 0, 0, 0, 0, 0, y)
|
||||
|
||||
int clock_get_osc_khz(void);
|
||||
int clock_get_pll_input_khz(void);
|
||||
/*
|
||||
* Configure PLLD to requested frequency. Returned value is closest match
|
||||
* within the PLLD's constraints or 0 if an error.
|
||||
*/
|
||||
u32 clock_configure_plld(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 kvco, u32 kcp,
|
||||
u32 stable_time, u32 emc_source, u32 same_freq);
|
||||
void clock_cpu0_config(void);
|
||||
void clock_halt_avp(void);
|
||||
void clock_enable_regs(u32 bits[DEV_CONFIG_BLOCKS]);
|
||||
void clock_disable_regs(u32 bits[DEV_CONFIG_BLOCKS]);
|
||||
void clock_set_reset_regs(u32 bits[DEV_CONFIG_BLOCKS]);
|
||||
void clock_clr_reset_regs(u32 bits[DEV_CONFIG_BLOCKS]);
|
||||
void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x, u32 y);
|
||||
void clock_grp_enable_clear_reset(u32 val, u32* clk_enb_set_reg, u32* rst_dev_clr_reg);
|
||||
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_reset_y(u32 y);
|
||||
void clock_init(void);
|
||||
void clock_init_arm_generic_timer(void);
|
||||
void sor_clock_stop(void);
|
||||
void sor_clock_start(void);
|
||||
void clock_enable_audio(void);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_CLOCK_H__ */
|
||||
|
61
src/soc/nvidia/tegra210/include/soc/clst_clk.h
Normal file
61
src/soc/nvidia/tegra210/include/soc/clst_clk.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, 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 _TEGRA210_CLST_CLK_H_
|
||||
#define _TEGRA210_CLST_CLK_H_
|
||||
|
||||
/* Cluster Clock (CLUSTER_CLOCKS_PUBLIC_) regs */
|
||||
struct __attribute__ ((__packed__)) clst_clk_ctlr {
|
||||
u32 pllx_base; /* _PLLX_BASE, 0x000 */
|
||||
u32 pllx_misc; /* _PLLX_MISC, 0x004 */
|
||||
u32 pllx_misc1; /* _PLLX_MISC_1, 0x008 */
|
||||
u32 pllx_misc2; /* _PLLX_MISC_2, 0x00c */
|
||||
u32 pllx_misc3; /* _PLLX_MISC_3, 0x010 */
|
||||
u32 pllx_hw_ctrl_cfg; /* _PLLX_HW_CTRL_CFG, 0x014 */
|
||||
u32 pllx_sw_ramp_cfg; /* _PLLX_SW_RAMP_CFG, 0x018 */
|
||||
u32 pllx_hw_ctrl_status; /* _PLLX_HW_CTRL_STATUS, 0x01c */
|
||||
u32 cclk_brst_pol; /* _CCLK_BURST_POLICY, 0x020 */
|
||||
u32 super_cclk_div; /* _SUPER_CCLK_DIVIDER, 0x024 */
|
||||
u32 _rsv1[10]; /* 0x028-04c */
|
||||
u32 shaper; /* _SHAPER, 0x050 */
|
||||
u32 shaper1; /* _SHAPER_1, 0x054 */
|
||||
u32 _rsv2[80]; /* 0x058-194 */
|
||||
u32 misc_ctrl; /* _MISC_CTRL, 0x198 */
|
||||
};
|
||||
check_member(clst_clk_ctlr, misc_ctrl, 0x198);
|
||||
|
||||
/* CC_CCLK_BRST_POL */
|
||||
enum {
|
||||
CC_CCLK_BRST_POL_PLLX_OUT0_LJ = 0x8,
|
||||
};
|
||||
|
||||
/* CC_SUPER_CCLK_DIVIDER */
|
||||
enum {
|
||||
CC_SUPER_CCLK_DIVIDER_SUPER_CDIV_ENB = 1 << 31
|
||||
};
|
||||
|
||||
/* PLLX_MISC3 */
|
||||
enum {
|
||||
PLLX_IDDQ = 1 << 3,
|
||||
};
|
||||
|
||||
/* MISC_CTRL */
|
||||
enum {
|
||||
CLK_SWITCH_MATCH = 1 << 5,
|
||||
};
|
||||
|
||||
#define CLK_SWITCH_TIMEOUT_US 1000
|
||||
#endif /* _TEGRA210_CLST_CLK_H_ */
|
33
src/soc/nvidia/tegra210/include/soc/cpu.h
Normal file
33
src/soc/nvidia/tegra210/include/soc/cpu.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_CPU_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_CPU_H__
|
||||
|
||||
/*
|
||||
* Start a core in 64-bit mode at the entry_64 address. Note that entry_64
|
||||
* should be a 32-bit address.
|
||||
*/
|
||||
void start_cpu(int cpu, void *entry_64);
|
||||
/* Start CPU wthout any log messages. */
|
||||
void start_cpu_silent(int cpu, void *entry_64);
|
||||
/* Prepare SoC for starting a CPU. Initialize the global state of the SoC. */
|
||||
void cpu_prepare_startup(void *entry_64);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_CPU_H__ */
|
60
src/soc/nvidia/tegra210/include/soc/display.h
Normal file
60
src/soc/nvidia/tegra210/include/soc/display.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_INCLUDE_SOC_DISPLAY_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_INCLUDE_SOC_DISPLAY_H__
|
||||
|
||||
#define COLOR_WHITE 0xFFFFFF
|
||||
#define COLOR_BLACK 0x000000
|
||||
|
||||
#define hsync_start(mode) \
|
||||
(mode->xres + mode->hfront_porch)
|
||||
|
||||
#define hsync_end(mode) \
|
||||
(mode->xres + mode->hfront_porch + mode->hsync_width)
|
||||
|
||||
#define htotal(mode) \
|
||||
(mode->xres + mode->hfront_porch + \
|
||||
mode->hsync_width + mode->hback_porch)
|
||||
|
||||
#define vtotal(mode) \
|
||||
(mode->yres + mode->vfront_porch + \
|
||||
mode->vsync_width + mode->vback_porch)
|
||||
|
||||
enum {
|
||||
/* norrin64 */
|
||||
TEGRA_EDID_I2C_ADDRESS = 0x50,
|
||||
};
|
||||
|
||||
/* refresh rate = 60/s */
|
||||
#define FRAME_IN_MS 17
|
||||
|
||||
/* forward declaration */
|
||||
struct soc_nvidia_tegra210_config;
|
||||
struct display_controller;
|
||||
|
||||
void dsi_display_startup(device_t dev);
|
||||
void dp_display_startup(device_t dev);
|
||||
|
||||
int tegra_dc_init(struct display_controller *disp_ctrl);
|
||||
int update_display_mode(struct display_controller *disp_ctrl,
|
||||
struct soc_nvidia_tegra210_config *config);
|
||||
void update_window(const struct soc_nvidia_tegra210_config *config);
|
||||
void update_display_shift_clock_divider(struct display_controller *disp_ctrl,
|
||||
u32 shift_clock_div);
|
||||
void pass_mode_info_to_payload(
|
||||
struct soc_nvidia_tegra210_config *config);
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_INCLUDE_SOC_DISPLAY_H__ */
|
192
src/soc/nvidia/tegra210/include/soc/dma.h
Normal file
192
src/soc/nvidia/tegra210/include/soc/dma.h
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* (C) Copyright 2010-2015 NVIDIA Corporation <www.nvidia.com>
|
||||
* Copyright (C) 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __NVIDIA_TEGRA210_DMA_H__
|
||||
#define __NVIDIA_TEGRA210_DMA_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <soc/addressmap.h>
|
||||
|
||||
/*
|
||||
* The DMA engine operates on 4 bytes at a time, so make sure any data
|
||||
* passed via DMA is aligned to avoid underrun/overrun.
|
||||
*/
|
||||
#define TEGRA_DMA_ALIGN_BYTES 4
|
||||
|
||||
/*
|
||||
* Note: Many APB DMA controller registers are laid out such that each
|
||||
* bit controls or represents the status for the corresponding channel.
|
||||
* So we will not bother to list each individual bit in this case.
|
||||
*/
|
||||
#define APB_COMMAND_GEN (1 << 31)
|
||||
|
||||
#define APB_CNTRL_REG_COUNT_VALUE_MASK 0xffff
|
||||
#define APB_CNTRL_REG_COUNT_VALUE_SHIFT 0
|
||||
|
||||
/*
|
||||
* Note: Many APB DMA controller registers are laid out such that each
|
||||
* bit controls or represents the status for the corresponding channel.
|
||||
* So we will not bother to list each individual bit in this case.
|
||||
*/
|
||||
#define APB_COMMAND_GEN (1 << 31)
|
||||
|
||||
#define APB_CNTRL_REG_COUNT_VALUE_MASK 0xffff
|
||||
#define APB_CNTRL_REG_COUNT_VALUE_SHIFT 0
|
||||
struct apb_dma {
|
||||
u32 command; /* 0x00 */
|
||||
u32 status; /* 0x04 */
|
||||
u32 rsvd1[2];
|
||||
u32 cntrl_reg; /* 0x10 */
|
||||
u32 irq_sta_cpu; /* 0x14 */
|
||||
u32 irq_sta_cop; /* 0x18 */
|
||||
u32 irq_mask; /* 0x1c */
|
||||
u32 irq_mask_set; /* 0x20 */
|
||||
u32 irq_mask_clr; /* 0x24 */
|
||||
u32 trig_reg; /* 0x28 */
|
||||
u32 channel_trig_reg; /* 0x2c */
|
||||
u32 dma_status; /* 0x30 */
|
||||
u32 channel_en_reg; /* 0x34 */
|
||||
u32 security_reg; /* 0x38 */
|
||||
u32 channel_swid; /* 0x3c */
|
||||
u32 rsvd[1];
|
||||
u32 chan_wt_reg0; /* 0x44 */
|
||||
u32 chan_wt_reg1; /* 0x48 */
|
||||
u32 chan_wt_reg2; /* 0x4c */
|
||||
u32 chan_wr_reg3; /* 0x50 */
|
||||
u32 channel_swid1; /* 0x54 */
|
||||
} __attribute__((packed));
|
||||
check_member(apb_dma, channel_swid1, 0x54);
|
||||
|
||||
/* Security enable for DMA channel */
|
||||
#define SECURITY_EN_BIT(ch) (1 << ch)
|
||||
|
||||
/*
|
||||
* Naming in the doc included a superfluous _CHANNEL_n_ for
|
||||
* each entry and was left out for the sake of conciseness.
|
||||
*/
|
||||
#define APB_CSR_ENB (1 << 31)
|
||||
#define APB_CSR_IE_EOC (1 << 30)
|
||||
#define APB_CSR_HOLD (1 << 29)
|
||||
#define APB_CSR_DIR (1 << 28)
|
||||
#define APB_CSR_ONCE (1 << 27)
|
||||
#define APB_CSR_FLOW (1 << 21)
|
||||
#define APB_CSR_REQ_SEL_MASK 0x1f
|
||||
#define APB_CSR_REQ_SEL_SHIFT 16
|
||||
|
||||
enum apbdmachan_req_sel {
|
||||
APBDMA_SLAVE_CNTR_REQ = 0,
|
||||
APBDMA_SLAVE_APBIF_CH0 = 1,
|
||||
APBDMA_SLAVE_APBIF_CH1 = 2,
|
||||
APBDMA_SLAVE_APBIF_CH2 = 3,
|
||||
APBDMA_SLAVE_APBIF_CH3 = 4,
|
||||
APBDMA_SLAVE_QSPI = 5,
|
||||
APBDMA_SLAVE_APBIF_CH4 = 6,
|
||||
APBDMA_SLAVE_APBIF_CH5 = 7,
|
||||
APBDMA_SLAVE_UART_A = 8,
|
||||
APBDMA_SLAVE_UART_B = 9,
|
||||
APBDMA_SLAVE_UART_C = 10,
|
||||
APBDMA_SLAVE_DTV = 11,
|
||||
APBDMA_SLAVE_APBIF_CH6 = 12,
|
||||
APBDMA_SLAVE_APBIF_CH7 = 13,
|
||||
APBDMA_SLAVE_APBIF_CH8 = 14,
|
||||
APBDMA_SLAVE_SL2B1 = 15,
|
||||
APBDMA_SLAVE_SL2B2 = 16,
|
||||
APBDMA_SLAVE_SL2B3 = 17,
|
||||
APBDMA_SLAVE_SL2B4 = 18,
|
||||
APBDMA_SLAVE_UART_D = 19,
|
||||
APBDMA_SLAVE_UART_E = 20,
|
||||
APBDMA_SLAVE_I2C = 21,
|
||||
APBDMA_SLAVE_I2C2 = 22,
|
||||
APBDMA_SLAVE_I2C3 = 23,
|
||||
APBDMA_SLAVE_DVC_I2C = 24,
|
||||
APBDMA_SLAVE_OWR = 25,
|
||||
APBDMA_SLAVE_I2C4 = 26,
|
||||
APBDMA_SLAVE_SL2B5 = 27,
|
||||
APBDMA_SLAVE_SL2B6 = 28,
|
||||
APBDMA_SLAVE_APBIF_CH9 = 29,
|
||||
APBDMA_SLAVE_I2C6 = 30,
|
||||
APBDMA_SLAVE_NA31 = 31,
|
||||
};
|
||||
|
||||
#define APB_STA_BSY (1 << 31)
|
||||
#define APB_STA_ISE_EOC (1 << 30)
|
||||
#define APB_STA_HALT (1 << 29)
|
||||
#define APB_STA_PING_PONG_STA (1 << 28)
|
||||
#define APB_STA_DMA_ACTIVITY (1 << 27)
|
||||
#define APB_STA_CHANNEL_PAUSE (1 << 26)
|
||||
|
||||
#define APB_CSRE_CHANNEL_PAUSE (1 << 31)
|
||||
#define APB_CSRE_TRIG_SEL_MASK 0x3f
|
||||
#define APB_CSRE_TRIG_SEL_SHIFT 14
|
||||
|
||||
#define AHB_PTR_MASK (0x3fffffff)
|
||||
#define AHB_PTR_SHIFT 2
|
||||
|
||||
#define AHB_SEQ_INTR_ENB (1 << 31)
|
||||
#define AHB_BUS_WIDTH_MASK 0x7
|
||||
#define AHB_BUS_WIDTH_SHIFT 28
|
||||
#define AHB_DATA_SWAP (1 << 27)
|
||||
#define AHB_BURST_MASK 0x7
|
||||
#define AHB_BURST_SHIFT 24
|
||||
#define AHB_SEQ_DBL_BUF (1 << 19)
|
||||
#define AHB_SEQ_WRAP_MASK 0x7
|
||||
#define AHB_SEQ_WRAP_SHIFT 16
|
||||
|
||||
#define APB_PTR_MASK 0x3fffffff
|
||||
#define APB_PTR_SHIFT 2
|
||||
|
||||
#define APB_BUS_WIDTH_MASK 0x7
|
||||
#define APB_BUS_WIDTH_SHIFT 28
|
||||
#define APB_DATA_SWAP (1 << 27)
|
||||
#define APB_ADDR_WRAP_MASK 0x7
|
||||
#define APB_ADDR_WRAP_SHIFT 16
|
||||
|
||||
#define APB_WORD_TRANSFER_MASK 0x0fffffff
|
||||
#define APB_WORD_TRANSFER_SHIFT 2
|
||||
|
||||
struct apb_dma_channel_regs {
|
||||
u32 csr; /* 0x00 */
|
||||
u32 sta; /* 0x04 */
|
||||
u32 dma_byte_sta; /* 0x08 */
|
||||
u32 csre; /* 0x0c */
|
||||
u32 ahb_ptr; /* 0x10 */
|
||||
u32 ahb_seq; /* 0x14 */
|
||||
u32 apb_ptr; /* 0x18 */
|
||||
u32 apb_seq; /* 0x1c */
|
||||
u32 wcount; /* 0x20 */
|
||||
u32 word_transfer; /* 0x24 */
|
||||
} __attribute__((packed));
|
||||
check_member(apb_dma_channel_regs, word_transfer, 0x24);
|
||||
|
||||
struct apb_dma_channel {
|
||||
const int num;
|
||||
struct apb_dma_channel_regs *regs;
|
||||
|
||||
/*
|
||||
* Basic high-level semaphore that can be used to "claim"
|
||||
* a DMA channel e.g. by SPI, I2C, or other peripheral driver.
|
||||
*/
|
||||
int in_use;
|
||||
};
|
||||
|
||||
struct apb_dma_channel * const dma_claim(void);
|
||||
void dma_release(struct apb_dma_channel * const channel);
|
||||
int dma_start(struct apb_dma_channel * const channel);
|
||||
int dma_stop(struct apb_dma_channel * const channel);
|
||||
int dma_busy(struct apb_dma_channel * const channel);
|
||||
|
||||
#endif /* __NVIDIA_TEGRA210_DMA_H__ */
|
475
src/soc/nvidia/tegra210/include/soc/emc.h
Normal file
475
src/soc/nvidia/tegra210/include/soc/emc.h
Normal file
@ -0,0 +1,475 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (C) 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_EMC_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_EMC_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
EMC_PIN_RESET_MASK = 1 << 8,
|
||||
EMC_PIN_RESET_ACTIVE = 0 << 8,
|
||||
EMC_PIN_RESET_INACTIVE = 1 << 8,
|
||||
EMC_PIN_DQM_MASK = 1 << 4,
|
||||
EMC_PIN_DQM_NORMAL = 0 << 4,
|
||||
EMC_PIN_DQM_INACTIVE = 1 << 4,
|
||||
EMC_PIN_CKE_MASK = 1 << 0,
|
||||
EMC_PIN_CKE_POWERDOWN = 0 << 0,
|
||||
EMC_PIN_CKE_NORMAL = 1 << 0,
|
||||
|
||||
EMC_REF_CMD_MASK = 1 << 0,
|
||||
EMC_REF_CMD_REFRESH = 1 << 0,
|
||||
EMC_REF_NORMAL_MASK = 1 << 1,
|
||||
EMC_REF_NORMAL_INIT = 0 << 1,
|
||||
EMC_REF_NORMAL_ENABLED = 1 << 1,
|
||||
EMC_REF_NUM_SHIFT = 8,
|
||||
EMC_REF_NUM_MASK = 0xFF << EMC_REF_NUM_SHIFT,
|
||||
EMC_REF_DEV_SELECTN_SHIFT = 30,
|
||||
EMC_REF_DEV_SELECTN_MASK = 3 << EMC_REF_DEV_SELECTN_SHIFT,
|
||||
|
||||
EMC_REFCTRL_REF_VALID_MASK = 1 << 31,
|
||||
EMC_REFCTRL_REF_VALID_DISABLED = 0 << 31,
|
||||
EMC_REFCTRL_REF_VALID_ENABLED = 1 << 31,
|
||||
|
||||
EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE_MASK = 1 << 1,
|
||||
EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1_MASK = 1 << 2,
|
||||
EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2_MASK = 1 << 3,
|
||||
|
||||
EMC_NOP_CMD_SHIFT = 0,
|
||||
EMC_NOP_CMD_MASK = 1 << EMC_NOP_CMD_SHIFT,
|
||||
EMC_NOP_DEV_SELECTN_SHIFT = 30,
|
||||
EMC_NOP_DEV_SELECTN_MASK = 3 << EMC_NOP_DEV_SELECTN_SHIFT,
|
||||
|
||||
EMC_TIMING_CONTROL_TIMING_UPDATE = 1,
|
||||
|
||||
EMC_PIN_GPIOEN_SHIFT = 16,
|
||||
EMC_PIN_GPIO_SHIFT = 12,
|
||||
EMC_PMACRO_BRICK_CTRL_RFU1_RESET_VAL = 0x1FFF1FFF,
|
||||
|
||||
AUTOCAL_MEASURE_STALL_ENABLE = 1 << 9,
|
||||
WRITE_MUX_ACTIVE = 1 << 1,
|
||||
CFG_ADR_EN_LOCKED = 1 << 1,
|
||||
};
|
||||
|
||||
struct tegra_emc_regs {
|
||||
uint32_t intstatus; /* 0x0 */
|
||||
uint32_t intmask; /* 0x4 */
|
||||
uint32_t dbg; /* 0x8 */
|
||||
uint32_t cfg; /* 0xc */
|
||||
uint32_t adr_cfg; /* 0x10 */
|
||||
uint32_t rsvd_0x14[3]; /* 0x14-0x1C */
|
||||
|
||||
uint32_t refctrl; /* 0x20 */
|
||||
uint32_t pin; /* 0x24 */
|
||||
uint32_t timing_control; /* 0x28 */
|
||||
uint32_t rc; /* 0x2c */
|
||||
uint32_t rfc; /* 0x30 */
|
||||
uint32_t ras; /* 0x34 */
|
||||
uint32_t rp; /* 0x38 */
|
||||
uint32_t r2w; /* 0x3c */
|
||||
uint32_t w2r; /* 0x40 */
|
||||
uint32_t r2p; /* 0x44 */
|
||||
uint32_t w2p; /* 0x48 */
|
||||
uint32_t rd_rcd; /* 0x4c */
|
||||
uint32_t wr_rcd; /* 0x50 */
|
||||
uint32_t rrd; /* 0x54 */
|
||||
uint32_t rext; /* 0x58 */
|
||||
uint32_t wdv; /* 0x5c */
|
||||
uint32_t quse; /* 0x60 */
|
||||
uint32_t qrst; /* 0x64 */
|
||||
uint32_t qsafe; /* 0x68 */
|
||||
uint32_t rdv; /* 0x6c */
|
||||
uint32_t refresh; /* 0x70 */
|
||||
uint32_t burst_refresh_num; /* 0x74 */
|
||||
uint32_t pdex2wr; /* 0x78 */
|
||||
uint32_t pdex2rd; /* 0x7c */
|
||||
uint32_t pchg2pden; /* 0x80 */
|
||||
uint32_t act2pden; /* 0x84 */
|
||||
uint32_t ar2pden; /* 0x88 */
|
||||
uint32_t rw2pden; /* 0x8c */
|
||||
uint32_t txsr; /* 0x90 */
|
||||
uint32_t tcke; /* 0x94 */
|
||||
uint32_t tfaw; /* 0x98 */
|
||||
uint32_t trpab; /* 0x9c */
|
||||
uint32_t tclkstable; /* 0xa0 */
|
||||
uint32_t tclkstop; /* 0xa4 */
|
||||
uint32_t trefbw; /* 0xa8 */
|
||||
uint32_t tppd; /* 0xac */
|
||||
uint32_t odt_write; /* 0xb0 */
|
||||
uint32_t pdex2mrr; /* 0xb4 */
|
||||
uint32_t wext; /* 0xb8 */
|
||||
uint32_t ctt; /* 0xbc */
|
||||
uint32_t rfc_slr; /* 0xc0 */
|
||||
uint32_t mrs_wait_cnt2; /* 0xc4 */
|
||||
uint32_t mrs_wait_cnt; /* 0xc8 */
|
||||
uint32_t mrs; /* 0xcc */
|
||||
uint32_t emrs; /* 0xd0 */
|
||||
uint32_t ref; /* 0xd4 */
|
||||
uint32_t pre; /* 0xd8 */
|
||||
uint32_t nop; /* 0xdc */
|
||||
uint32_t self_ref; /* 0xe0 */
|
||||
uint32_t dpd; /* 0xe4 */
|
||||
uint32_t mrw; /* 0xe8 */
|
||||
uint32_t mrr; /* 0xec */
|
||||
uint32_t cmdq; /* 0xf0 */
|
||||
uint32_t mc2emcq; /* 0xf4 */
|
||||
uint32_t xm2dqspadctrl3; /* 0xf8 */
|
||||
uint32_t rsvd_0xfc[1]; /* 0xfc */
|
||||
uint32_t fbio_spare; /* 0x100 */
|
||||
uint32_t fbio_cfg5; /* 0x104 */
|
||||
uint32_t fbio_wrptr_eq_2; /* 0x108 */
|
||||
uint32_t rsvd_0x10c[2]; /* 0x10c-0x110 */
|
||||
|
||||
uint32_t fbio_cfg6; /* 0x114 */
|
||||
uint32_t pdex2cke; /* 0x118 */
|
||||
uint32_t cke2pden; /* 0x11C */
|
||||
uint32_t cfg_rsv; /* 0x120 */
|
||||
uint32_t acpd_control; /* 0x124 */
|
||||
uint32_t rsvd_0x128[1]; /* 0x128 */
|
||||
uint32_t emrs2; /* 0x12c */
|
||||
uint32_t emrs3; /* 0x130 */
|
||||
uint32_t mrw2; /* 0x134 */
|
||||
uint32_t mrw3; /* 0x138 */
|
||||
uint32_t mrw4; /* 0x13c */
|
||||
uint32_t clken_override; /* 0x140 */
|
||||
uint32_t r2r; /* 0x144 */
|
||||
uint32_t w2w; /* 0x148 */
|
||||
uint32_t einput; /* 0x14c */
|
||||
uint32_t einput_duration; /* 0x150 */
|
||||
uint32_t puterm_extra; /* 0x154 */
|
||||
uint32_t tckesr; /* 0x158 */
|
||||
uint32_t tpd; /* 0x15c */
|
||||
uint32_t rsvd_0x160[81]; /* 0x160-0x2A0 */
|
||||
|
||||
uint32_t auto_cal_config; /* 0x2a4 */
|
||||
uint32_t auto_cal_interval; /* 0x2a8 */
|
||||
uint32_t auto_cal_status; /* 0x2ac */
|
||||
uint32_t req_ctrl; /* 0x2b0 */
|
||||
uint32_t status; /* 0x2b4 */
|
||||
uint32_t cfg_2; /* 0x2b8 */
|
||||
uint32_t cfg_dig_dll; /* 0x2bc */
|
||||
uint32_t cfg_dig_dll_period; /* 0x2c0 */
|
||||
uint32_t dig_dll_status; /* 0x2C4 */
|
||||
uint32_t cfg_dig_dll_1; /* 0x2C8 */
|
||||
uint32_t rdv_mask; /* 0x2cc */
|
||||
uint32_t wdv_mask; /* 0x2d0 */
|
||||
uint32_t rdv_early_mask; /* 0x2d4 */
|
||||
uint32_t rdv_early; /* 0x2d8 */
|
||||
uint32_t auto_cal_config8; /* 0x2DC */
|
||||
uint32_t zcal_interval; /* 0x2e0 */
|
||||
uint32_t zcal_wait_cnt; /* 0x2e4 */
|
||||
uint32_t zcal_mrw_cmd; /* 0x2e8 */
|
||||
uint32_t zq_cal; /* 0x2ec */
|
||||
uint32_t xm2cmdpadctrl; /* 0x2f0 */
|
||||
uint32_t xm2comppadctrl3; /* 0x2f4 */
|
||||
uint32_t auto_cal_vref_sel0; /* 0x2f8 */
|
||||
uint32_t xm2dqspadctrl2; /* 0x2fc */
|
||||
uint32_t auto_cal_vref_sel1; /* 0x300 */
|
||||
uint32_t xm2dqpadctrl2; /* 0x304 */
|
||||
uint32_t xm2clkpadctrl; /* 0x308 */
|
||||
uint32_t xm2comppadctrl; /* 0x30c */
|
||||
uint32_t fdpd_ctrl_dq; /* 0x310 */
|
||||
uint32_t fdpd_ctrl_cmd; /* 0x314 */
|
||||
uint32_t pmacro_cmd_brick_ctrl_fdpd; /* 0x318 */
|
||||
uint32_t pmacro_data_brick_ctrl_fdpd; /* 0x31c */
|
||||
uint32_t xm2dqspadctrl4; /* 0x320 */
|
||||
uint32_t scratch0; /* 0x324 */
|
||||
uint32_t rsvd_0x328[2]; /* 0x328-0x32C */
|
||||
|
||||
uint32_t pmacro_brick_ctrl_rfu1; /* 0x330 */
|
||||
uint32_t pmacro_brick_ctrl_rfu2; /* 0x334 */
|
||||
uint32_t rsvd_0x338[18]; /* 0x338-0x37C */
|
||||
|
||||
uint32_t cmd_mapping_cmd0_0; /* 0x380 */
|
||||
uint32_t cmd_mapping_cmd0_1; /* 0x384 */
|
||||
uint32_t cmd_mapping_cmd0_2; /* 0x388 */
|
||||
uint32_t cmd_mapping_cmd1_0; /* 0x38c */
|
||||
uint32_t cmd_mapping_cmd1_1; /* 0x390 */
|
||||
uint32_t cmd_mapping_cmd1_2; /* 0x394 */
|
||||
uint32_t cmd_mapping_cmd2_0; /* 0x398 */
|
||||
uint32_t cmd_mapping_cmd2_1; /* 0x39C */
|
||||
uint32_t cmd_mapping_cmd2_2; /* 0x3A0 */
|
||||
uint32_t cmd_mapping_cmd3_0; /* 0x3A4 */
|
||||
uint32_t cmd_mapping_cmd3_1; /* 0x3A8 */
|
||||
uint32_t cmd_mapping_cmd3_2; /* 0x3AC */
|
||||
uint32_t cmd_mapping_byte; /* 0x3B0 */
|
||||
uint32_t tr_timing_0; /* 0x3B4 */
|
||||
uint32_t tr_ctrl_0; /* 0x3B8 */
|
||||
uint32_t tr_ctrl_1; /* 0x3BC */
|
||||
uint32_t switch_back_ctrl; /* 0x3C0 */
|
||||
uint32_t tr_rdv; /* 0x3C4 */
|
||||
uint32_t stall_then_exe_before_clkchange; /* 0x3c8 */
|
||||
uint32_t stall_then_exe_after_clkchange; /* 0x3cc */
|
||||
uint32_t unstall_rw_after_clkchange; /* 0x3d0 */
|
||||
uint32_t auto_cal_clk_status; /* 0x3d4 */
|
||||
uint32_t sel_dpd_ctrl; /* 0x3d8 */
|
||||
uint32_t pre_refresh_req_cnt; /* 0x3dc */
|
||||
uint32_t dyn_self_ref_control; /* 0x3e0 */
|
||||
uint32_t txsrdll; /* 0x3e4 */
|
||||
uint32_t ccfifo_addr; /* 0x3e8 */
|
||||
uint32_t ccfifo_data; /* 0x3ec */
|
||||
uint32_t ccfifo_status; /* 0x3f0 */
|
||||
uint32_t cdb_cntl_1; /* 0x3f4 */
|
||||
uint32_t cdb_cntl_2; /* 0x3f8 */
|
||||
uint32_t xm2clkpadctrl2; /* 0x3fc */
|
||||
uint32_t swizzle_rank0_byte_cfg; /* 0x400 */
|
||||
uint32_t swizzle_rank0_byte0; /* 0x404 */
|
||||
uint32_t swizzle_rank0_byte1; /* 0x408 */
|
||||
uint32_t swizzle_rank0_byte2; /* 0x40c */
|
||||
uint32_t swizzle_rank0_byte3; /* 0x410 */
|
||||
uint32_t swizzle_rank1_byte_cfg; /* 0x414 */
|
||||
uint32_t swizzle_rank1_byte0; /* 0x418 */
|
||||
uint32_t swizzle_rank1_byte1; /* 0x41c */
|
||||
uint32_t swizzle_rank1_byte2; /* 0x420 */
|
||||
uint32_t swizzle_rank1_byte3; /* 0x424 */
|
||||
uint32_t issue_qrst; /* 0x428 */
|
||||
uint32_t rsvd_0x42C[5]; /* 0x42C-0x43C */
|
||||
uint32_t pmc_scratch1; /* 0x440 */
|
||||
uint32_t pmc_scratch2; /* 0x444 */
|
||||
uint32_t pmc_scratch3; /* 0x448 */
|
||||
uint32_t rsvd_0x44C[3]; /* 0x44C-0x454 */
|
||||
uint32_t auto_cal_config2; /* 0x458 */
|
||||
uint32_t auto_cal_config3; /* 0x45c */
|
||||
uint32_t auto_cal_status2; /* 0x460 */
|
||||
uint32_t auto_cal_channel; /* 0x464 */
|
||||
uint32_t ibdly; /* 0x468 */
|
||||
uint32_t obdly; /* 0x46c */
|
||||
uint32_t rsvd_0x470[3]; /* 0x470-0x478 */
|
||||
|
||||
uint32_t dsr_vttgen_drv; /* 0x47c */
|
||||
uint32_t txdsrvttgen; /* 0x480 */
|
||||
uint32_t xm2cmdpadctrl4; /* 0x484 */
|
||||
uint32_t xm2cmdpadctrl5; /* 0x488 */
|
||||
uint32_t we_duration; /* 0x48C */
|
||||
uint32_t ws_duration; /* 0x490 */
|
||||
uint32_t wev; /* 0x494 */
|
||||
uint32_t wsv; /* 0x498 */
|
||||
uint32_t cfg_3; /* 0x49C */
|
||||
uint32_t mrw5; /* 0x4A0 */
|
||||
uint32_t mrw6; /* 0x4A4 */
|
||||
uint32_t mrw7; /* 0x4A8 */
|
||||
uint32_t mrw8; /* 0x4AC */
|
||||
uint32_t mrw9; /* 0x4B0 */
|
||||
uint32_t mrw10; /* 0x4B4 */
|
||||
uint32_t mrw11; /* 0x4B8 */
|
||||
uint32_t mrw12; /* 0x4BC */
|
||||
uint32_t mrw13; /* 0x4C0 */
|
||||
uint32_t mrw14; /* 0x4C4 */
|
||||
uint32_t rsvd_0x4c8[2]; /* 0x4C8-0x4CC */
|
||||
|
||||
uint32_t mrw15; /* 0x4D0 */
|
||||
uint32_t cfg_sync; /* 0x4D4 */
|
||||
uint32_t fdpd_ctrl_cmd_no_ramp; /* 0x4D8 */
|
||||
uint32_t rsvd_0x4dc[1]; /* 0x4DC */
|
||||
uint32_t wdv_chk; /* 0x4E0 */
|
||||
uint32_t rsvd_0x4e4[28]; /* 0x4E4-0x550 */
|
||||
|
||||
uint32_t cfg_pipe2; /* 0x554 */
|
||||
uint32_t cfg_pipe_clk; /* 0x558 */
|
||||
uint32_t cfg_pipe1; /* 0x55C */
|
||||
uint32_t cfg_pipe; /* 0x560 */
|
||||
uint32_t qpop; /* 0x564 */
|
||||
uint32_t quse_width; /* 0x568 */
|
||||
uint32_t puterm_width; /* 0x56c */
|
||||
uint32_t bgbias_ctl0; /* 0x570 */
|
||||
uint32_t auto_cal_config7; /* 0x574 */
|
||||
uint32_t xm2comppadctrl2; /* 0x578 */
|
||||
uint32_t comppadswctrl; /* 0x57C */
|
||||
uint32_t refctrl2; /* 0x580 */
|
||||
uint32_t fbio_cfg7; /* 0x584 */
|
||||
uint32_t data_brlshft_0; /* 0x588 */
|
||||
uint32_t data_brlshft_1; /* 0x58C */
|
||||
uint32_t rfcpb; /* 0x590 */
|
||||
uint32_t dqs_brlshft_0; /* 0x594 */
|
||||
uint32_t dqs_brlshft_1; /* 0x598 */
|
||||
uint32_t cmd_brlshft_0; /* 0x59C */
|
||||
uint32_t cmd_brlshft_1; /* 0x5A0 */
|
||||
uint32_t cmd_brlshft_2; /* 0x5A4 */
|
||||
uint32_t cmd_brlshft_3; /* 0x5A8 */
|
||||
uint32_t quse_brlshft_0; /* 0x5AC */
|
||||
uint32_t auto_cal_config4; /* 0x5B0 */
|
||||
uint32_t auto_cal_config5; /* 0x5B4 */
|
||||
uint32_t quse_brlshft_1; /* 0x5B8 */
|
||||
uint32_t quse_brlshft_2; /* 0x5BC */
|
||||
uint32_t ccdmw; /* 0x5C0 */
|
||||
uint32_t quse_brlshft_3; /* 0x5C4 */
|
||||
uint32_t fbio_cfg8; /* 0x5C8 */
|
||||
uint32_t auto_cal_config6; /* 0x5CC */
|
||||
uint32_t protobist_config_addr_1; /* 0x5D0 */
|
||||
uint32_t protobist_config_addr_2; /* 0x5D4 */
|
||||
uint32_t protobist_misc; /* 0x5D8 */
|
||||
uint32_t protobist_wdata_lower; /* 0x5DC */
|
||||
uint32_t protobist_wdata_upper; /* 0x5E0 */
|
||||
uint32_t dll_cfg0; /* 0x5E4 */
|
||||
uint32_t dll_cfg1; /* 0x5E8 */
|
||||
uint32_t protobist_rdata; /* 0x5EC */
|
||||
uint32_t config_sample_delay; /* 0x5F0 */
|
||||
uint32_t cfg_update; /* 0x5F4 */
|
||||
uint32_t rsvd_0x5f8[2]; /* 0x5F8-0x5FC */
|
||||
|
||||
uint32_t pmacro_quse_ddll_rank0_0; /* 0x600 */
|
||||
uint32_t pmacro_quse_ddll_rank0_1; /* 0x604 */
|
||||
uint32_t pmacro_quse_ddll_rank0_2; /* 0x608 */
|
||||
uint32_t pmacro_quse_ddll_rank0_3; /* 0x60C */
|
||||
uint32_t pmacro_quse_ddll_rank0_4; /* 0x610 */
|
||||
uint32_t pmacro_quse_ddll_rank0_5; /* 0x614 */
|
||||
uint32_t rsvd_0x618[2]; /* 0x618-0x61C */
|
||||
|
||||
uint32_t pmacro_quse_ddll_rank1_0; /* 0x620 */
|
||||
uint32_t pmacro_quse_ddll_rank1_1; /* 0x624 */
|
||||
uint32_t pmacro_quse_ddll_rank1_2; /* 0x628 */
|
||||
uint32_t pmacro_quse_ddll_rank1_3; /* 0x62C */
|
||||
uint32_t pmacro_quse_ddll_rank1_4; /* 0x630 */
|
||||
uint32_t pmacro_quse_ddll_rank1_5; /* 0x634 */
|
||||
uint32_t rsvd_0x638[2]; /* 0x638-0x63C */
|
||||
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank0_0; /* 0x640 */
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank0_1; /* 0x644 */
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank0_2; /* 0x648 */
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank0_3; /* 0x64C */
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank0_4; /* 0x650 */
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank0_5; /* 0x654 */
|
||||
uint32_t rsvd_0x658[2]; /* 0x658-0x65C */
|
||||
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank1_0; /* 0x660 */
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank1_1; /* 0x664 */
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank1_2; /* 0x668 */
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank1_3; /* 0x66C */
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank1_4; /* 0x670 */
|
||||
uint32_t pmacro_ob_ddll_long_dq_rank1_5; /* 0x674 */
|
||||
uint32_t rsvd_0x678[2]; /* 0x678-0x67C */
|
||||
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank0_0; /* 0x680 */
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank0_1; /* 0x684 */
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank0_2; /* 0x688 */
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank0_3; /* 0x68C */
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank0_4; /* 0x690 */
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank0_5; /* 0x694 */
|
||||
uint32_t rsvd_0x698[2]; /* 0x698-0x69C */
|
||||
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank1_0; /* 0x6A0 */
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank1_1; /* 0x6A4 */
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank1_2; /* 0x6A8 */
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank1_3; /* 0x6AC */
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank1_4; /* 0x6B0 */
|
||||
uint32_t pmacro_ob_ddll_long_dqs_rank1_5; /* 0x6B4 */
|
||||
uint32_t rsvd_0x6B8[2]; /* 0x6B8-0x6BC */
|
||||
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank0_0; /* 0x6C0 */
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank0_1; /* 0x6C4 */
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank0_2; /* 0x6C8 */
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank0_3; /* 0x6CC */
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank0_4; /* 0x6D0 */
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank0_5; /* 0x6D4 */
|
||||
uint32_t rsvd_0x6D8[2]; /* 0x6D8-0x6DC */
|
||||
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank1_0; /* 0x6E0 */
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank1_1; /* 0x6E4 */
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank1_2; /* 0x6E8 */
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank1_3; /* 0x6EC */
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank1_4; /* 0x6F0 */
|
||||
uint32_t pmacro_ib_ddll_long_dqs_rank1_5; /* 0x6F4 */
|
||||
uint32_t rsvd_0x6F8[2]; /* 0x6F8-0x6FC */
|
||||
|
||||
uint32_t pmacro_autocal_cfg0; /* 0x700 */
|
||||
uint32_t pmacro_autocal_cfg1; /* 0x704 */
|
||||
uint32_t pmacro_autocal_cfg2; /* 0x708 */
|
||||
uint32_t rsvd_0x70C[5]; /* 0x70C-0x71C */
|
||||
|
||||
uint32_t pmacro_tx_pwrd_0; /* 0x720 */
|
||||
uint32_t pmacro_tx_pwrd_1; /* 0x724 */
|
||||
uint32_t pmacro_tx_pwrd_2; /* 0x728 */
|
||||
uint32_t pmacro_tx_pwrd_3; /* 0x72C */
|
||||
uint32_t pmacro_tx_pwrd_4; /* 0x730 */
|
||||
uint32_t pmacro_tx_pwrd_5; /* 0x734 */
|
||||
uint32_t rsvd_0x738[2]; /* 0x738-0x73C */
|
||||
|
||||
uint32_t pmacro_tx_sel_clk_src_0; /* 0x740 */
|
||||
uint32_t pmacro_tx_sel_clk_src_1; /* 0x744 */
|
||||
uint32_t pmacro_tx_sel_clk_src_2; /* 0x748 */
|
||||
uint32_t pmacro_tx_sel_clk_src_3; /* 0x74C */
|
||||
uint32_t pmacro_tx_sel_clk_src_4; /* 0x750 */
|
||||
uint32_t pmacro_tx_sel_clk_src_5; /* 0x754 */
|
||||
uint32_t rsvd_0x758[2]; /* 0x758-0x75C */
|
||||
|
||||
uint32_t pmacro_ddll_bypass; /* 0x760 */
|
||||
uint32_t rsvd_0x764[3]; /* 0x764-0x76C */
|
||||
|
||||
uint32_t pmacro_ddll_pwrd_0; /* 0x770 */
|
||||
uint32_t pmacro_ddll_pwrd_1; /* 0x774 */
|
||||
uint32_t pmacro_ddll_pwrd_2; /* 0x778 */
|
||||
uint32_t rsvd_0x77C[1]; /* 0x77C */
|
||||
uint32_t pmacro_cmd_ctrl_0; /* 0x780 */
|
||||
uint32_t pmacro_cmd_ctrl_1; /* 0x784 */
|
||||
uint32_t pmacro_cmd_ctrl_2; /* 0x788 */
|
||||
uint32_t rsvd_0x78C[277]; /* 0x78C-0xBDC */
|
||||
|
||||
uint32_t pmacro_ib_vref_dq_0; /* 0xBE0 */
|
||||
uint32_t pmacro_ib_vref_dq_1; /* 0xBE4 */
|
||||
uint32_t pmacro_ib_vref_dq_2; /* 0xBE8 */
|
||||
uint32_t rsvd_0xBEC[1]; /* 0xBEC */
|
||||
uint32_t pmacro_ib_vref_dqs_0; /* 0xBF0 */
|
||||
uint32_t pmacro_ib_vref_dqs_1; /* 0xBF4 */
|
||||
uint32_t pmacro_ib_vref_dqs_2; /* 0xBF8 */
|
||||
uint32_t rsvd_0xBFC[1]; /* 0xBFC */
|
||||
uint32_t pmacro_ddll_long_cmd_0; /* 0xC00 */
|
||||
uint32_t pmacro_ddll_long_cmd_1; /* 0xC04 */
|
||||
uint32_t pmacro_ddll_long_cmd_2; /* 0xC08 */
|
||||
uint32_t pmacro_ddll_long_cmd_3; /* 0xC0C */
|
||||
uint32_t pmacro_ddll_long_cmd_4; /* 0xC10 */
|
||||
uint32_t pmacro_ddll_long_cmd_5; /* 0xC14 */
|
||||
uint32_t rsvd_0xC18[2]; /* 0xC18-0xC1C */
|
||||
|
||||
uint32_t pmacro_ddll_short_cmd_0; /* 0xC20 */
|
||||
uint32_t pmacro_ddll_short_cmd_1; /* 0xC24 */
|
||||
uint32_t pmacro_ddll_short_cmd_2; /* 0xC28 */
|
||||
uint32_t rsvd_0xC2C[2]; /* 0xC2C-0xC30 */
|
||||
|
||||
uint32_t pmacro_vttgen_ctrl0; /* 0xC34 */
|
||||
uint32_t pmacro_vttgen_ctrl1; /* 0xC38 */
|
||||
uint32_t pmacro_bg_bias_ctrl_0; /* 0xC3C */
|
||||
uint32_t pmacro_pad_cfg_ctrl; /* 0xC40 */
|
||||
uint32_t pmacro_zctrl; /* 0xC44 */
|
||||
uint32_t pmacro_rx_term; /* 0xC48 */
|
||||
uint32_t pmacro_cmd_tx_drv; /* 0xC4C */
|
||||
uint32_t pmacro_cmd_pad_rx_ctrl; /* 0xC50 */
|
||||
uint32_t pmacro_data_pad_rx_ctrl; /* 0xC54 */
|
||||
uint32_t pmacro_cmd_rx_term_mode; /* 0xC58 */
|
||||
uint32_t pmacro_data_rx_term_mode; /* 0xC5C */
|
||||
uint32_t pmacro_cmd_pad_tx_ctrl; /* 0xC60 */
|
||||
uint32_t pmacro_data_pad_tx_ctrl; /* 0xC64 */
|
||||
uint32_t pmacro_common_pad_tx_ctrl; /* 0xC68 */
|
||||
uint32_t rsvd_0xC6C[1]; /* 0xC6C */
|
||||
uint32_t pmacro_dq_tx_drv; /* 0xC70 */
|
||||
uint32_t pmacro_ca_tx_drv; /* 0xC74 */
|
||||
uint32_t pmacro_autocal_cfg_common; /* 0xC78 */
|
||||
uint32_t rsvd_0xC7C[1]; /* 0xC7C */
|
||||
uint32_t pmacro_brick_mapping0; /* 0xC80 */
|
||||
uint32_t pmacro_brick_mapping1; /* 0xC84 */
|
||||
uint32_t pmacro_brick_mapping2; /* 0xC88 */
|
||||
uint32_t rsvd_0xC8C[25]; /* 0xC8C-0xCEC */
|
||||
|
||||
uint32_t pmacro_vttgen_ctrl2; /* 0xCF0 */
|
||||
uint32_t pmacro_ib_rxrt; /* 0xCF4 */
|
||||
uint32_t pmacro_training_ctrl0; /* 0xCF8 */
|
||||
uint32_t pmacro_training_ctrl1; /* 0xCFC */
|
||||
} __attribute__((packed));
|
||||
|
||||
check_member(tegra_emc_regs, pmacro_training_ctrl1, 0xCFC);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_EMC_H__ */
|
86
src/soc/nvidia/tegra210/include/soc/flow.h
Normal file
86
src/soc/nvidia/tegra210/include/soc/flow.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2015, 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 _TEGRA210_FLOW_H_
|
||||
#define _TEGRA210_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 */
|
||||
u32 flow_dbg_sel; /* offset 0x44 */
|
||||
u32 flow_dbg_cnt0; /* offset 0x48 */
|
||||
u32 flow_dbg_cnt1; /* offset 0x4c */
|
||||
u32 flow_dbg_qual; /* offset 0x50 */
|
||||
u32 flow_ctlr_spare; /* offset 0x54 */
|
||||
u32 reserved; /* offset 0x58 */
|
||||
u32 fc_seq_intercept; /* offset 0x5c */
|
||||
};
|
||||
check_member(flow_ctlr, fc_seq_intercept, 0x5c);
|
||||
|
||||
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 /* _TEGRA210_FLOW_H_ */
|
30
src/soc/nvidia/tegra210/include/soc/flow_ctrl.h
Normal file
30
src/soc/nvidia/tegra210/include/soc/flow_ctrl.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA210_FLOW_CTRL_H_
|
||||
#define _TEGRA210_FLOW_CTRL_H_
|
||||
|
||||
void flowctrl_cpu_off(int cpu);
|
||||
void flowctrl_cpu_on(int cpu);
|
||||
void flowctrl_cpu_suspend(int cpu);
|
||||
void flowctrl_write_cc4_ctrl(int cpu, uint32_t val);
|
||||
void flowctrl_write_cpu_csr(int cpu, uint32_t val);
|
||||
void flowctrl_write_cpu_halt(int cpu, uint32_t val);
|
||||
|
||||
#endif
|
94
src/soc/nvidia/tegra210/include/soc/funitcfg.h
Normal file
94
src/soc/nvidia/tegra210/include/soc/funitcfg.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_FUNIT_CFG_H
|
||||
#define __SOC_NVIDIA_TEGRA210_FUNIT_CFG_H
|
||||
|
||||
#include <soc/clock.h>
|
||||
#include <soc/padconfig.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define FUNIT_INDEX(_name) FUNIT_##_name
|
||||
|
||||
enum {
|
||||
FUNIT_INDEX(I2C1),
|
||||
FUNIT_INDEX(I2C2),
|
||||
FUNIT_INDEX(I2C3),
|
||||
FUNIT_INDEX(I2C5),
|
||||
FUNIT_INDEX(I2C6),
|
||||
FUNIT_INDEX(SDMMC1),
|
||||
FUNIT_INDEX(SDMMC4),
|
||||
FUNIT_INDEX(USBD),
|
||||
FUNIT_INDEX(USB2),
|
||||
FUNIT_INDEX(QSPI),
|
||||
FUNIT_INDEX(I2S1),
|
||||
FUNIT_INDEX_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* Note: these bus numbers are dependent on the driver implementations, and
|
||||
* currently the I2C is 0-based and SPI is 1-based in its indexing.
|
||||
*/
|
||||
enum {
|
||||
|
||||
I2C1_BUS = 0,
|
||||
I2C2_BUS = 1,
|
||||
I2C3_BUS = 2,
|
||||
I2C5_BUS = 4,
|
||||
I2CPWR_BUS = I2C5_BUS,
|
||||
I2C6_BUS = 5,
|
||||
QSPI_BUS = 7,
|
||||
|
||||
SPI1_BUS = 1,
|
||||
SPI4_BUS = 4,
|
||||
};
|
||||
|
||||
struct funit_cfg {
|
||||
uint32_t funit_index;
|
||||
uint32_t clk_src_id;
|
||||
uint32_t clk_src_freq_id;
|
||||
uint32_t clk_dev_freq_khz;
|
||||
struct pad_config const* pad_cfg;
|
||||
size_t pad_cfg_size;
|
||||
};
|
||||
|
||||
#define FUNIT_CFG(_funit,_clk_src,_clk_freq,_cfg,_cfg_size) \
|
||||
{ \
|
||||
.funit_index = FUNIT_INDEX(_funit), \
|
||||
.clk_src_id = CLK_SRC_DEV_ID(_funit, _clk_src), \
|
||||
.clk_src_freq_id = CLK_SRC_FREQ_ID(_funit, _clk_src), \
|
||||
.clk_dev_freq_khz = _clk_freq, \
|
||||
.pad_cfg = _cfg, \
|
||||
.pad_cfg_size = _cfg_size, \
|
||||
}
|
||||
|
||||
#define FUNIT_CFG_USB(_funit) \
|
||||
{ \
|
||||
.funit_index = FUNIT_INDEX(_funit), \
|
||||
.pad_cfg = NULL, \
|
||||
.pad_cfg_size = 0, \
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure the funits associated with entry according to the configuration.
|
||||
*/
|
||||
void soc_configure_funits(const struct funit_cfg * const entries, size_t num);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_FUNIT_CFG_H */
|
25
src/soc/nvidia/tegra210/include/soc/gpio.h
Normal file
25
src/soc/nvidia/tegra210/include/soc/gpio.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_GPIO_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_GPIO_H__
|
||||
|
||||
#include <soc/pinmux.h>
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_GPIO_H__ */
|
35
src/soc/nvidia/tegra210/include/soc/id.h
Normal file
35
src/soc/nvidia/tegra210/include/soc/id.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_INCLUDE_SOC_ID_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_INCLUDE_SOC_ID_H__
|
||||
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <soc/addressmap.h>
|
||||
|
||||
static inline int context_avp(void)
|
||||
{
|
||||
const uint32_t avp_id = 0xaaaaaaaa;
|
||||
void * const uptag = (void *)(uintptr_t)TEGRA_PG_UP_BASE;
|
||||
|
||||
return read32(uptag) == avp_id;
|
||||
}
|
||||
|
||||
#endif /* define __SOC_NVIDIA_TEGRA210_INCLUDE_SOC_ID_H__ */
|
29
src/soc/nvidia/tegra210/include/soc/maincpu.h
Normal file
29
src/soc/nvidia/tegra210/include/soc/maincpu.h
Normal 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_MAINCPU_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_MAINCPU_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern u32 maincpu_stack_pointer;
|
||||
extern u32 maincpu_entry_point;
|
||||
void maincpu_setup(void);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_MAINCPU_H__ */
|
231
src/soc/nvidia/tegra210/include/soc/mc.h
Normal file
231
src/soc/nvidia/tegra210/include/soc/mc.h
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (C) 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_MC_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_MC_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Memory Controller registers we need/care about
|
||||
|
||||
struct tegra_mc_regs {
|
||||
uint32_t rsvd_0x0[4]; /* 0x00 */
|
||||
uint32_t smmu_config; /* 0x10 */
|
||||
uint32_t smmu_tlb_config; /* 0x14 */
|
||||
uint32_t smmu_ptc_config; /* 0x18 */
|
||||
uint32_t smmu_ptb_asid; /* 0x1c */
|
||||
uint32_t smmu_ptb_data; /* 0x20 */
|
||||
uint32_t rsvd_0x24[3]; /* 0x24 */
|
||||
uint32_t smmu_tlb_flush; /* 0x30 */
|
||||
uint32_t smmu_ptc_flush; /* 0x34 */
|
||||
uint32_t rsvd_0x38[6]; /* 0x38 */
|
||||
uint32_t emem_cfg; /* 0x50 */
|
||||
uint32_t emem_adr_cfg; /* 0x54 */
|
||||
uint32_t emem_adr_cfg_dev0; /* 0x58 */
|
||||
uint32_t emem_adr_cfg_dev1; /* 0x5c */
|
||||
uint32_t emem_adr_cfg_channel_mask; /* 0x60 */
|
||||
uint32_t emem_adr_cfg_bank_mask_0; /* 0x64 */
|
||||
uint32_t emem_adr_cfg_bank_mask_1; /* 0x68 */
|
||||
uint32_t emem_adr_cfg_bank_mask_2; /* 0x6c */
|
||||
uint32_t security_cfg0; /* 0x70 */
|
||||
uint32_t security_cfg1; /* 0x74 */
|
||||
uint32_t rsvd_0x78[6]; /* 0x78 */
|
||||
uint32_t emem_arb_cfg; /* 0x90 */
|
||||
uint32_t emem_arb_outstanding_req; /* 0x94 */
|
||||
uint32_t emem_arb_timing_rcd; /* 0x98 */
|
||||
uint32_t emem_arb_timing_rp; /* 0x9c */
|
||||
uint32_t emem_arb_timing_rc; /* 0xa0 */
|
||||
uint32_t emem_arb_timing_ras; /* 0xa4 */
|
||||
uint32_t emem_arb_timing_faw; /* 0xa8 */
|
||||
uint32_t emem_arb_timing_rrd; /* 0xac */
|
||||
uint32_t emem_arb_timing_rap2pre; /* 0xb0 */
|
||||
uint32_t emem_arb_timing_wap2pre; /* 0xb4 */
|
||||
uint32_t emem_arb_timing_r2r; /* 0xb8 */
|
||||
uint32_t emem_arb_timing_w2w; /* 0xbc */
|
||||
uint32_t emem_arb_timing_r2w; /* 0xc0 */
|
||||
uint32_t emem_arb_timing_w2r; /* 0xc4 */
|
||||
uint32_t emem_arb_misc2; /* 0xC8 */
|
||||
uint32_t rsvd_0xcc[1]; /* 0xCC */
|
||||
uint32_t emem_arb_da_turns; /* 0xd0 */
|
||||
uint32_t emem_arb_da_covers; /* 0xd4 */
|
||||
uint32_t emem_arb_misc0; /* 0xd8 */
|
||||
uint32_t emem_arb_misc1; /* 0xdc */
|
||||
uint32_t emem_arb_ring1_throttle; /* 0xe0 */
|
||||
uint32_t emem_arb_ring3_throttle; /* 0xe4 */
|
||||
uint32_t emem_arb_override; /* 0xe8 */
|
||||
uint32_t emem_arb_rsv; /* 0xec */
|
||||
uint32_t rsvd_0xf0[1]; /* 0xf0 */
|
||||
uint32_t clken_override; /* 0xf4 */
|
||||
uint32_t timing_control_dbg; /* 0xf8 */
|
||||
uint32_t timing_control; /* 0xfc */
|
||||
uint32_t stat_control; /* 0x100 */
|
||||
uint32_t rsvd_0x104[65]; /* 0x104 */
|
||||
uint32_t emem_arb_isochronous_0; /* 0x208 */
|
||||
uint32_t emem_arb_isochronous_1; /* 0x20c */
|
||||
uint32_t emem_arb_isochronous_2; /* 0x210 */
|
||||
uint32_t rsvd_0x214[38]; /* 0x214 */
|
||||
uint32_t dis_extra_snap_levels; /* 0x2ac */
|
||||
uint32_t rsvd_0x2b0[90]; /* 0x2b0 */
|
||||
uint32_t video_protect_vpr_override; /* 0x418 */
|
||||
uint32_t rsvd_0x41c[93]; /* 0x41c */
|
||||
uint32_t video_protect_vpr_override1; /* 0x590 */
|
||||
uint32_t rsvd_0x594[29]; /* 0x594 */
|
||||
uint32_t display_snap_ring; /* 0x608 */
|
||||
uint32_t rsvd_0x60c[15]; /* 0x60c */
|
||||
uint32_t video_protect_bom; /* 0x648 */
|
||||
uint32_t video_protect_size_mb; /* 0x64c */
|
||||
uint32_t video_protect_reg_ctrl; /* 0x650 */
|
||||
uint32_t rsvd_0x654[4]; /* 0x654 */
|
||||
uint32_t emem_cfg_access_ctrl; /* 0x664 */
|
||||
uint32_t rsvd_0x668[2]; /* 0x668 */
|
||||
uint32_t sec_carveout_bom; /* 0x670 */
|
||||
uint32_t sec_carveout_size_mb; /* 0x674 */
|
||||
uint32_t sec_carveout_reg_ctrl; /* 0x678 */
|
||||
uint32_t rsvd_0x67c[17]; /* 0x67C-0x6BC */
|
||||
|
||||
uint32_t emem_arb_timing_rfcpb; /* 0x6C0 */
|
||||
uint32_t emem_arb_timing_ccdmw; /* 0x6C4 */
|
||||
uint32_t rsvd_0x6c8[10]; /* 0x6C8-0x6EC */
|
||||
|
||||
uint32_t emem_arb_refpb_hp_ctrl; /* 0x6F0 */
|
||||
uint32_t emem_arb_refpb_bank_ctrl; /* 0x6F4 */
|
||||
uint32_t rsvd_0x6f8[156]; /* 0x6F8-0x964 */
|
||||
|
||||
uint32_t emem_arb_override_1; /* 0x968 */
|
||||
uint32_t rsvd_0x96c[3]; /* 0x96c */
|
||||
uint32_t video_protect_bom_adr_hi; /* 0x978 */
|
||||
uint32_t rsvd_0x97c[2]; /* 0x97c */
|
||||
uint32_t video_protect_gpu_override_0; /* 0x984 */
|
||||
uint32_t video_protect_gpu_override_1; /* 0x988 */
|
||||
uint32_t rsvd_0x98c[5]; /* 0x98c */
|
||||
uint32_t mts_carveout_bom; /* 0x9a0 */
|
||||
uint32_t mts_carveout_size_mb; /* 0x9a4 */
|
||||
uint32_t mts_carveout_adr_hi; /* 0x9a8 */
|
||||
uint32_t mts_carveout_reg_ctrl; /* 0x9ac */
|
||||
uint32_t rsvd_0x9b0[4]; /* 0x9b0 */
|
||||
uint32_t emem_bank_swizzle_cfg0; /* 0x9c0 */
|
||||
uint32_t emem_bank_swizzle_cfg1; /* 0x9c4 */
|
||||
uint32_t emem_bank_swizzle_cfg2; /* 0x9c8 */
|
||||
uint32_t emem_bank_swizzle_cfg3; /* 0x9cc */
|
||||
uint32_t rsvd_0x9d0[1]; /* 0x9d0 */
|
||||
uint32_t sec_carveout_adr_hi; /* 0x9d4 */
|
||||
uint32_t rsvd_0x9d8; /* 0x9D8 */
|
||||
uint32_t da_config0; /* 0x9DC */
|
||||
uint32_t rsvd_0x9c0[138]; /* 0x9E0-0xc04 */
|
||||
|
||||
uint32_t security_carveout1_cfg0; /* 0xc08 */
|
||||
uint32_t security_carveout1_bom; /* 0xc0c */
|
||||
uint32_t security_carveout1_bom_hi; /* 0xc10 */
|
||||
uint32_t security_carveout1_size_128kb; /* 0xc14 */
|
||||
uint32_t security_carveout1_ca0; /* 0xc18 */
|
||||
uint32_t security_carveout1_ca1; /* 0xc1c */
|
||||
uint32_t security_carveout1_ca2; /* 0xc20 */
|
||||
uint32_t security_carveout1_ca3; /* 0xc24 */
|
||||
uint32_t security_carveout1_ca4; /* 0xc28 */
|
||||
uint32_t security_carveout1_cfia0; /* 0xc2c */
|
||||
uint32_t security_carveout1_cfia1; /* 0xc30 */
|
||||
uint32_t security_carveout1_cfia2; /* 0xc34 */
|
||||
uint32_t security_carveout1_cfia3; /* 0xc38 */
|
||||
uint32_t security_carveout1_cfia4; /* 0xc3c */
|
||||
uint32_t rsvd_0xc40[6]; /* 0xc40-0xc54 */
|
||||
|
||||
uint32_t security_carveout2_cfg0; /* 0xc58 */
|
||||
uint32_t security_carveout2_bom; /* 0xc5c */
|
||||
uint32_t security_carveout2_bom_hi; /* 0xc60 */
|
||||
uint32_t security_carveout2_size_128kb; /* 0xc64 */
|
||||
uint32_t security_carveout2_ca0; /* 0xc68 */
|
||||
uint32_t security_carveout2_ca1; /* 0xc6c */
|
||||
uint32_t security_carveout2_ca2; /* 0xc70 */
|
||||
uint32_t security_carveout2_ca3; /* 0xc74 */
|
||||
uint32_t security_carveout2_ca4; /* 0xc78 */
|
||||
uint32_t security_carveout2_cfia0; /* 0xc7c */
|
||||
uint32_t security_carveout2_cfia1; /* 0xc80 */
|
||||
uint32_t security_carveout2_cfia2; /* 0xc84 */
|
||||
uint32_t security_carveout2_cfia3; /* 0xc88 */
|
||||
uint32_t security_carveout2_cfia4; /* 0xc8c */
|
||||
uint32_t rsvd_0xc90[6]; /* 0xc90-0xca4 */
|
||||
|
||||
uint32_t security_carveout3_cfg0; /* 0xca8 */
|
||||
uint32_t security_carveout3_bom; /* 0xcac */
|
||||
uint32_t security_carveout3_bom_hi; /* 0xcb0 */
|
||||
uint32_t security_carveout3_size_128kb; /* 0xcb4 */
|
||||
uint32_t security_carveout3_ca0; /* 0xcb8 */
|
||||
uint32_t security_carveout3_ca1; /* 0xcbc */
|
||||
uint32_t security_carveout3_ca2; /* 0xcc0 */
|
||||
uint32_t security_carveout3_ca3; /* 0xcc4 */
|
||||
uint32_t security_carveout3_ca4; /* 0xcc8 */
|
||||
uint32_t security_carveout3_cfia0; /* 0xccc */
|
||||
uint32_t security_carveout3_cfia1; /* 0xcd0 */
|
||||
uint32_t security_carveout3_cfia2; /* 0xcd4 */
|
||||
uint32_t security_carveout3_cfia3; /* 0xcd8 */
|
||||
uint32_t security_carveout3_cfia4; /* 0xcdc */
|
||||
uint32_t rsvd_0xce0[6]; /* 0xce0-0xcf4 */
|
||||
|
||||
uint32_t security_carveout4_cfg0; /* 0xcf8 */
|
||||
uint32_t security_carveout4_bom; /* 0xcfc */
|
||||
uint32_t security_carveout4_bom_hi; /* 0xd00 */
|
||||
uint32_t security_carveout4_size_128kb; /* 0xd04 */
|
||||
uint32_t security_carveout4_ca0; /* 0xd08 */
|
||||
uint32_t security_carveout4_ca1; /* 0xd0c */
|
||||
uint32_t security_carveout4_ca2; /* 0xd10 */
|
||||
uint32_t security_carveout4_ca3; /* 0xd14 */
|
||||
uint32_t security_carveout4_ca4; /* 0xd18 */
|
||||
uint32_t security_carveout4_cfia0; /* 0xd1c */
|
||||
uint32_t security_carveout4_cfia1; /* 0xd20 */
|
||||
uint32_t security_carveout4_cfia2; /* 0xd24 */
|
||||
uint32_t security_carveout4_cfia3; /* 0xd28 */
|
||||
uint32_t security_carveout4_cfia4; /* 0xd2c */
|
||||
uint32_t rsvd_0xd30[6]; /* 0xd30-0xd44 */
|
||||
|
||||
uint32_t security_carveout5_cfg0; /* 0xd48 */
|
||||
uint32_t security_carveout5_bom; /* 0xd4c */
|
||||
uint32_t security_carveout5_bom_hi; /* 0xd50 */
|
||||
uint32_t security_carveout5_size_128kb; /* 0xd54 */
|
||||
uint32_t security_carveout5_ca0; /* 0xd58 */
|
||||
uint32_t security_carveout5_ca1; /* 0xd5c */
|
||||
uint32_t security_carveout5_ca2; /* 0xd60 */
|
||||
uint32_t security_carveout5_ca3; /* 0xd64 */
|
||||
uint32_t security_carveout5_ca4; /* 0xd68 */
|
||||
uint32_t security_carveout5_cfia0; /* 0xd6c */
|
||||
uint32_t security_carveout5_cfia1; /* 0xd70 */
|
||||
uint32_t security_carveout5_cfia2; /* 0xd74 */
|
||||
uint32_t security_carveout5_cfia3; /* 0xd78 */
|
||||
uint32_t security_carveout5_cfia4; /* 0xd7c */
|
||||
};
|
||||
|
||||
enum {
|
||||
MC_SMMU_CONFIG_ENABLE = 1,
|
||||
|
||||
MC_EMEM_CFG_SIZE_MB_SHIFT = 0,
|
||||
MC_EMEM_CFG_SIZE_MB_MASK = 0x3fff,
|
||||
|
||||
MC_EMEM_ARB_MISC0_MC_EMC_SAME_FREQ_SHIFT = 27,
|
||||
MC_EMEM_ARB_MISC0_MC_EMC_SAME_FREQ_MASK = 1 << 27,
|
||||
|
||||
MC_EMEM_CFG_ACCESS_CTRL_WRITE_ACCESS_DISABLED = 1,
|
||||
|
||||
MC_TIMING_CONTROL_TIMING_UPDATE = 1,
|
||||
};
|
||||
|
||||
#define MC_SECURITY_CARVEOUT_LOCKED (1 << 1)
|
||||
#define MC_VPR_WR_ACCESS_DISABLE (1 << 0)
|
||||
#define MC_VPR_ALLOW_TZ_WR_ACCESS_ENABLE (1 << 1)
|
||||
|
||||
check_member(tegra_mc_regs, security_carveout5_cfia4, 0xd7c);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_MC_H__ */
|
44
src/soc/nvidia/tegra210/include/soc/memlayout.ld
Normal file
44
src/soc/nvidia/tegra210/include/soc/memlayout.ld
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <memlayout.h>
|
||||
|
||||
#include <arch/header.ld>
|
||||
|
||||
/*
|
||||
* Note: The BootROM uses the address range [0x4000_0000:0x4000_E000) itself,
|
||||
* so the bootblock loading address must be placed after that. After the
|
||||
* handoff that area may be reclaimed for other uses, e.g. CBFS cache.
|
||||
* TODO: Did this change on Tegra210? What's the new valid range?
|
||||
*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
SRAM_START(0x40000000)
|
||||
PRERAM_CBMEM_CONSOLE(0x40000000, 8K)
|
||||
PRERAM_CBFS_CACHE(0x40002000, 84K)
|
||||
STACK(0x40017000, 16K)
|
||||
BOOTBLOCK(0x4001B000, 26K)
|
||||
ROMSTAGE(0x40022000, 120K)
|
||||
SRAM_END(0x40040000)
|
||||
|
||||
DRAM_START(0x80000000)
|
||||
POSTRAM_CBFS_CACHE(0x80100000, 1M)
|
||||
RAMSTAGE(0x80200000, 256K)
|
||||
}
|
47
src/soc/nvidia/tegra210/include/soc/memlayout_vboot2.ld
Normal file
47
src/soc/nvidia/tegra210/include/soc/memlayout_vboot2.ld
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <memlayout.h>
|
||||
#include <vendorcode/google/chromeos/memlayout.h>
|
||||
|
||||
#include <arch/header.ld>
|
||||
|
||||
/*
|
||||
* Note: The BootROM uses the address range [0x4000_0000:0x4000_E000) itself,
|
||||
* so the bootblock loading address must be placed after that. After the
|
||||
* handoff that area may be reclaimed for other uses, e.g. CBFS cache.
|
||||
* TODO: Did this change on Tegra210? What's the new valid range?
|
||||
*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
SRAM_START(0x40000000)
|
||||
PRERAM_CBMEM_CONSOLE(0x40000000, 8K)
|
||||
PRERAM_CBFS_CACHE(0x40002000, 72K)
|
||||
VBOOT2_WORK(0x40014000, 16K)
|
||||
STACK(0x40018000, 2K)
|
||||
BOOTBLOCK(0x40019000, 24K)
|
||||
VERSTAGE(0x4001F000, 56K)
|
||||
ROMSTAGE(0x4002D000, 76K)
|
||||
SRAM_END(0x40040000)
|
||||
|
||||
DRAM_START(0x80000000)
|
||||
POSTRAM_CBFS_CACHE(0x80100000, 1M)
|
||||
RAMSTAGE(0x80200000, 256K)
|
||||
}
|
46
src/soc/nvidia/tegra210/include/soc/mipi-phy.h
Normal file
46
src/soc/nvidia/tegra210/include/soc/mipi-phy.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef _TEGRA_MIPI_PHY_H
|
||||
#define _TEGRA_MIPI_PHY_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Macros for calculating the phy timings
|
||||
*/
|
||||
/* Period of one bit time in nano seconds */
|
||||
#define DSI_TBIT_Factorized(Freq) (((1000) * (1000))/(Freq))
|
||||
#define DSI_TBIT(Freq) (DSI_TBIT_Factorized(Freq)/(1000))
|
||||
|
||||
//#define NV_MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/* Period of one byte time in nano seconds */
|
||||
#define DSI_TBYTE(Freq) ((DSI_TBIT_Factorized(Freq)) * (8))
|
||||
#define DSI_PHY_TIMING_DIV(X, Freq) ((X*1000) / (DSI_TBYTE(Freq)))
|
||||
|
||||
/*
|
||||
* As per Mipi spec (minimum):
|
||||
* (3 + MAX(8 * DSI_TBIT, 60 + 4 * DSI_TBIT) / DSI_TBYTE)
|
||||
*/
|
||||
#define DSI_THSTRAIL_VAL(Freq) \
|
||||
(MAX(((8) * (DSI_TBIT(Freq))), ((60) + ((4) * (DSI_TBIT(Freq))))))
|
||||
|
||||
int mipi_dphy_set_timing(struct tegra_dsi *dsi);
|
||||
|
||||
#endif
|
148
src/soc/nvidia/tegra210/include/soc/mipi_display.h
Normal file
148
src/soc/nvidia/tegra210/include/soc/mipi_display.h
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Defines for Mobile Industry Processor Interface (MIPI(R))
|
||||
* Display Working Group standards: DSI, DCS, DBI, DPI
|
||||
*
|
||||
* Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
|
||||
* Copyright (C) 2006 Nokia Corporation
|
||||
* Author: Imre Deak <imre.deak@nokia.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef MIPI_DISPLAY_H
|
||||
#define MIPI_DISPLAY_H
|
||||
|
||||
/* MIPI DSI Processor-to-Peripheral transaction types */
|
||||
enum {
|
||||
MIPI_DSI_V_SYNC_START = 0x01,
|
||||
MIPI_DSI_V_SYNC_END = 0x11,
|
||||
MIPI_DSI_H_SYNC_START = 0x21,
|
||||
MIPI_DSI_H_SYNC_END = 0x31,
|
||||
|
||||
MIPI_DSI_COLOR_MODE_OFF = 0x02,
|
||||
MIPI_DSI_COLOR_MODE_ON = 0x12,
|
||||
MIPI_DSI_SHUTDOWN_PERIPHERAL = 0x22,
|
||||
MIPI_DSI_TURN_ON_PERIPHERAL = 0x32,
|
||||
|
||||
MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM = 0x03,
|
||||
MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM = 0x13,
|
||||
MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM = 0x23,
|
||||
|
||||
MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM = 0x04,
|
||||
MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM = 0x14,
|
||||
MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM = 0x24,
|
||||
|
||||
MIPI_DSI_DCS_SHORT_WRITE = 0x05,
|
||||
MIPI_DSI_DCS_SHORT_WRITE_PARAM = 0x15,
|
||||
|
||||
MIPI_DSI_DCS_READ = 0x06,
|
||||
|
||||
MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37,
|
||||
|
||||
MIPI_DSI_END_OF_TRANSMISSION = 0x08,
|
||||
|
||||
MIPI_DSI_NULL_PACKET = 0x09,
|
||||
MIPI_DSI_BLANKING_PACKET = 0x19,
|
||||
MIPI_DSI_GENERIC_LONG_WRITE = 0x29,
|
||||
MIPI_DSI_DCS_LONG_WRITE = 0x39,
|
||||
|
||||
MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 = 0x0c,
|
||||
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 = 0x1c,
|
||||
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 = 0x2c,
|
||||
|
||||
MIPI_DSI_PACKED_PIXEL_STREAM_30 = 0x0d,
|
||||
MIPI_DSI_PACKED_PIXEL_STREAM_36 = 0x1d,
|
||||
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 = 0x3d,
|
||||
|
||||
MIPI_DSI_PACKED_PIXEL_STREAM_16 = 0x0e,
|
||||
MIPI_DSI_PACKED_PIXEL_STREAM_18 = 0x1e,
|
||||
MIPI_DSI_PIXEL_STREAM_3BYTE_18 = 0x2e,
|
||||
MIPI_DSI_PACKED_PIXEL_STREAM_24 = 0x3e,
|
||||
};
|
||||
|
||||
/* MIPI DSI Peripheral-to-Processor transaction types */
|
||||
enum {
|
||||
MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT = 0x02,
|
||||
MIPI_DSI_RX_END_OF_TRANSMISSION = 0x08,
|
||||
MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE = 0x11,
|
||||
MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE = 0x12,
|
||||
MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE = 0x1a,
|
||||
MIPI_DSI_RX_DCS_LONG_READ_RESPONSE = 0x1c,
|
||||
MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE = 0x21,
|
||||
MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE = 0x22,
|
||||
};
|
||||
|
||||
/* MIPI DCS commands */
|
||||
enum {
|
||||
MIPI_DCS_NOP = 0x00,
|
||||
MIPI_DCS_SOFT_RESET = 0x01,
|
||||
MIPI_DCS_GET_DISPLAY_ID = 0x04,
|
||||
MIPI_DCS_GET_RED_CHANNEL = 0x06,
|
||||
MIPI_DCS_GET_GREEN_CHANNEL = 0x07,
|
||||
MIPI_DCS_GET_BLUE_CHANNEL = 0x08,
|
||||
MIPI_DCS_GET_DISPLAY_STATUS = 0x09,
|
||||
MIPI_DCS_GET_POWER_MODE = 0x0A,
|
||||
MIPI_DCS_GET_ADDRESS_MODE = 0x0B,
|
||||
MIPI_DCS_GET_PIXEL_FORMAT = 0x0C,
|
||||
MIPI_DCS_GET_DISPLAY_MODE = 0x0D,
|
||||
MIPI_DCS_GET_SIGNAL_MODE = 0x0E,
|
||||
MIPI_DCS_GET_DIAGNOSTIC_RESULT = 0x0F,
|
||||
MIPI_DCS_ENTER_SLEEP_MODE = 0x10,
|
||||
MIPI_DCS_EXIT_SLEEP_MODE = 0x11,
|
||||
MIPI_DCS_ENTER_PARTIAL_MODE = 0x12,
|
||||
MIPI_DCS_ENTER_NORMAL_MODE = 0x13,
|
||||
MIPI_DCS_EXIT_INVERT_MODE = 0x20,
|
||||
MIPI_DCS_ENTER_INVERT_MODE = 0x21,
|
||||
MIPI_DCS_SET_GAMMA_CURVE = 0x26,
|
||||
MIPI_DCS_SET_DISPLAY_OFF = 0x28,
|
||||
MIPI_DCS_SET_DISPLAY_ON = 0x29,
|
||||
MIPI_DCS_SET_COLUMN_ADDRESS = 0x2A,
|
||||
MIPI_DCS_SET_PAGE_ADDRESS = 0x2B,
|
||||
MIPI_DCS_WRITE_MEMORY_START = 0x2C,
|
||||
MIPI_DCS_WRITE_LUT = 0x2D,
|
||||
MIPI_DCS_READ_MEMORY_START = 0x2E,
|
||||
MIPI_DCS_SET_PARTIAL_AREA = 0x30,
|
||||
MIPI_DCS_SET_SCROLL_AREA = 0x33,
|
||||
MIPI_DCS_SET_TEAR_OFF = 0x34,
|
||||
MIPI_DCS_SET_TEAR_ON = 0x35,
|
||||
MIPI_DCS_SET_ADDRESS_MODE = 0x36,
|
||||
MIPI_DCS_SET_SCROLL_START = 0x37,
|
||||
MIPI_DCS_EXIT_IDLE_MODE = 0x38,
|
||||
MIPI_DCS_ENTER_IDLE_MODE = 0x39,
|
||||
MIPI_DCS_SET_PIXEL_FORMAT = 0x3A,
|
||||
MIPI_DCS_WRITE_MEMORY_CONTINUE = 0x3C,
|
||||
MIPI_DCS_READ_MEMORY_CONTINUE = 0x3E,
|
||||
MIPI_DCS_SET_TEAR_SCANLINE = 0x44,
|
||||
MIPI_DCS_GET_SCANLINE = 0x45,
|
||||
MIPI_DCS_READ_DDB_START = 0xA1,
|
||||
MIPI_DCS_READ_DDB_CONTINUE = 0xA8,
|
||||
};
|
||||
|
||||
/* MIPI DCS pixel formats */
|
||||
#define MIPI_DCS_PIXEL_FMT_24BIT 7
|
||||
#define MIPI_DCS_PIXEL_FMT_18BIT 6
|
||||
#define MIPI_DCS_PIXEL_FMT_16BIT 5
|
||||
#define MIPI_DCS_PIXEL_FMT_12BIT 3
|
||||
#define MIPI_DCS_PIXEL_FMT_8BIT 2
|
||||
#define MIPI_DCS_PIXEL_FMT_3BIT 1
|
||||
|
||||
#endif
|
316
src/soc/nvidia/tegra210/include/soc/mipi_dsi.h
Normal file
316
src/soc/nvidia/tegra210/include/soc/mipi_dsi.h
Normal file
@ -0,0 +1,316 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* MIPI DSI Bus
|
||||
*
|
||||
* Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd.
|
||||
* Andrzej Hajda <a.hajda@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __MIPI_DSI_H__
|
||||
#define __MIPI_DSI_H__
|
||||
|
||||
struct mipi_dsi_host;
|
||||
struct mipi_dsi_device;
|
||||
|
||||
/* request ACK from peripheral */
|
||||
#define MIPI_DSI_MSG_REQ_ACK BIT(0)
|
||||
/* use Low Power Mode to transmit message */
|
||||
#define MIPI_DSI_MSG_USE_LPM BIT(1)
|
||||
|
||||
/**
|
||||
* struct mipi_dsi_msg - read/write DSI buffer
|
||||
* @channel: virtual channel id
|
||||
* @type: payload data type
|
||||
* @flags: flags controlling this message transmission
|
||||
* @tx_len: length of @tx_buf
|
||||
* @tx_buf: data to be written
|
||||
* @rx_len: length of @rx_buf
|
||||
* @rx_buf: data to be read, or NULL
|
||||
*/
|
||||
struct mipi_dsi_msg {
|
||||
u8 channel;
|
||||
u8 type;
|
||||
u16 flags;
|
||||
|
||||
size_t tx_len;
|
||||
const void *tx_buf;
|
||||
|
||||
size_t rx_len;
|
||||
void *rx_buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mipi_dsi_host_ops - DSI bus operations
|
||||
* @attach: attach DSI device to DSI host
|
||||
* @detach: detach DSI device from DSI host
|
||||
* @transfer: transmit a DSI packet
|
||||
*
|
||||
* DSI packets transmitted by .transfer() are passed in as mipi_dsi_msg
|
||||
* structures. This structure contains information about the type of packet
|
||||
* being transmitted as well as the transmit and receive buffers. When an
|
||||
* error is encountered during transmission, this function will return a
|
||||
* negative error code. On success it shall return the number of bytes
|
||||
* transmitted for write packets or the number of bytes received for read
|
||||
* packets.
|
||||
*
|
||||
* Note that typically DSI packet transmission is atomic, so the .transfer()
|
||||
* function will seldomly return anything other than the number of bytes
|
||||
* contained in the transmit buffer on success.
|
||||
*/
|
||||
struct mipi_dsi_host_ops {
|
||||
int (*attach)(struct mipi_dsi_host *host,
|
||||
struct mipi_dsi_device *dsi);
|
||||
int (*detach)(struct mipi_dsi_host *host,
|
||||
struct mipi_dsi_device *dsi);
|
||||
ssize_t (*transfer)(struct mipi_dsi_host *host,
|
||||
const struct mipi_dsi_msg *msg);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mipi_dsi_host - DSI host device
|
||||
* @dev: driver model device node for this DSI host
|
||||
* @ops: DSI host operations
|
||||
*/
|
||||
struct mipi_dsi_host {
|
||||
//struct device *dev;
|
||||
void *dev;
|
||||
const struct mipi_dsi_host_ops *ops;
|
||||
};
|
||||
|
||||
int mipi_dsi_host_register(struct mipi_dsi_host *host);
|
||||
|
||||
/* DSI mode flags */
|
||||
|
||||
/* video mode */
|
||||
#define MIPI_DSI_MODE_VIDEO BIT(0)
|
||||
/* video burst mode */
|
||||
#define MIPI_DSI_MODE_VIDEO_BURST BIT(1)
|
||||
/* video pulse mode */
|
||||
#define MIPI_DSI_MODE_VIDEO_SYNC_PULSE BIT(2)
|
||||
/* enable auto vertical count mode */
|
||||
#define MIPI_DSI_MODE_VIDEO_AUTO_VERT BIT(3)
|
||||
/* enable hsync-end packets in vsync-pulse and v-porch area */
|
||||
#define MIPI_DSI_MODE_VIDEO_HSE BIT(4)
|
||||
/* disable hfront-porch area */
|
||||
#define MIPI_DSI_MODE_VIDEO_HFP BIT(5)
|
||||
/* disable hback-porch area */
|
||||
#define MIPI_DSI_MODE_VIDEO_HBP BIT(6)
|
||||
/* disable hsync-active area */
|
||||
#define MIPI_DSI_MODE_VIDEO_HSA BIT(7)
|
||||
/* flush display FIFO on vsync pulse */
|
||||
#define MIPI_DSI_MODE_VSYNC_FLUSH BIT(8)
|
||||
/* disable EoT packets in HS mode */
|
||||
#define MIPI_DSI_MODE_EOT_PACKET BIT(9)
|
||||
/* device supports non-continuous clock behavior (DSI spec 5.6.1) */
|
||||
#define MIPI_DSI_CLOCK_NON_CONTINUOUS BIT(10)
|
||||
|
||||
enum mipi_dsi_pixel_format {
|
||||
MIPI_DSI_FMT_RGB888,
|
||||
MIPI_DSI_FMT_RGB666,
|
||||
MIPI_DSI_FMT_RGB666_PACKED,
|
||||
MIPI_DSI_FMT_RGB565,
|
||||
};
|
||||
|
||||
struct mipi_dsi_master_ops {
|
||||
int (*enslave)(struct mipi_dsi_device *master,
|
||||
struct mipi_dsi_device *slave);
|
||||
int (*liberate)(struct mipi_dsi_device *master,
|
||||
struct mipi_dsi_device *slave);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mipi_dsi_device - DSI peripheral device
|
||||
* @host: DSI host for this peripheral
|
||||
* @dev: driver model device node for this peripheral
|
||||
* @channel: virtual channel assigned to the peripheral
|
||||
* @format: pixel format for video mode
|
||||
* @lanes: number of active data lanes
|
||||
* @mode_flags: DSI operation mode related flags
|
||||
* @ops: callbacks for master/slave setup
|
||||
* @master: master interface for dual-channel peripherals
|
||||
* @slave: slave interface for dual-channel peripherals
|
||||
*
|
||||
* For dual-channel interfaces, the master interface can be identified by the
|
||||
* fact that it's .slave field is set to non-NULL. The slave interface will
|
||||
* have the .master field set to non-NULL.
|
||||
*/
|
||||
struct mipi_dsi_device {
|
||||
struct mipi_dsi_host *host;
|
||||
|
||||
unsigned int channel;
|
||||
unsigned int lanes;
|
||||
enum mipi_dsi_pixel_format format;
|
||||
unsigned long mode_flags;
|
||||
|
||||
const struct mipi_dsi_master_ops *ops;
|
||||
struct mipi_dsi_device *master;
|
||||
struct mipi_dsi_device *slave;
|
||||
};
|
||||
|
||||
int mipi_dsi_attach(struct mipi_dsi_device *dsi);
|
||||
int mipi_dsi_detach(struct mipi_dsi_device *dsi);
|
||||
int mipi_dsi_enslave(struct mipi_dsi_device *master,
|
||||
struct mipi_dsi_device *slave);
|
||||
int mipi_dsi_liberate(struct mipi_dsi_device *master,
|
||||
struct mipi_dsi_device *slave);
|
||||
|
||||
/**
|
||||
* enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
|
||||
* @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
|
||||
* information only
|
||||
* @MIPI_DSI_DCS_TEAR_MODE_VHBLANK : the TE output line consists of both
|
||||
* V-Blanking and H-Blanking information
|
||||
*/
|
||||
enum mipi_dsi_dcs_tear_mode {
|
||||
MIPI_DSI_DCS_TEAR_MODE_VBLANK,
|
||||
MIPI_DSI_DCS_TEAR_MODE_VHBLANK,
|
||||
};
|
||||
|
||||
#define MIPI_DSI_DCS_POWER_MODE_DISPLAY (1 << 2)
|
||||
#define MIPI_DSI_DCS_POWER_MODE_NORMAL (1 << 3)
|
||||
#define MIPI_DSI_DCS_POWER_MODE_SLEEP (1 << 4)
|
||||
#define MIPI_DSI_DCS_POWER_MODE_PARTIAL (1 << 5)
|
||||
#define MIPI_DSI_DCS_POWER_MODE_IDLE (1 << 6)
|
||||
|
||||
ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
|
||||
const void *data, size_t len);
|
||||
int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi);
|
||||
int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi);
|
||||
int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
|
||||
u16 end);
|
||||
int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
|
||||
u16 end);
|
||||
int mipi_dsi_dcs_set_address_mode(struct mipi_dsi_device *dsi,
|
||||
bool reverse_page_address,
|
||||
bool reverse_col_address,
|
||||
bool reverse_page_col_address,
|
||||
bool refresh_from_bottom,
|
||||
bool reverse_rgb,
|
||||
bool latch_right_to_left,
|
||||
bool flip_horizontal,
|
||||
bool flip_vertical);
|
||||
int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
|
||||
enum mipi_dsi_dcs_tear_mode mode);
|
||||
int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format);
|
||||
|
||||
#define MIPI_CAL_CTRL 0x00
|
||||
#define MIPI_CAL_CTRL_NOISE_FILTER(x) (((x) & 0xf) << 26)
|
||||
#define MIPI_CAL_CTRL_PRESCALE(x) (((x) & 0x3) << 24)
|
||||
#define MIPI_CAL_CTRL_CLKEN_OVR (1 << 4)
|
||||
#define MIPI_CAL_CTRL_START (1 << 0)
|
||||
|
||||
#define MIPI_CAL_AUTOCAL_CTRL 0x01
|
||||
|
||||
#define MIPI_CAL_STATUS 0x02
|
||||
#define MIPI_CAL_STATUS_DONE (1 << 16)
|
||||
#define MIPI_CAL_STATUS_ACTIVE (1 << 0)
|
||||
|
||||
#define MIPI_CAL_CONFIG_CSIA 0x05
|
||||
#define MIPI_CAL_CONFIG_CSIB 0x06
|
||||
#define MIPI_CAL_CONFIG_CSIC 0x07
|
||||
#define MIPI_CAL_CONFIG_CSID 0x08
|
||||
#define MIPI_CAL_CONFIG_CSIE 0x09
|
||||
#define MIPI_CAL_CONFIG_CSIF 0x0a
|
||||
#define MIPI_CAL_CONFIG_DSIA 0x0e
|
||||
#define MIPI_CAL_CONFIG_DSIB 0x0f
|
||||
#define MIPI_CAL_CONFIG_DSIC 0x10
|
||||
#define MIPI_CAL_CONFIG_DSID 0x11
|
||||
|
||||
#define MIPI_CAL_CONFIG_DSIA_CLK 0x19
|
||||
#define MIPI_CAL_CONFIG_DSIB_CLK 0x1a
|
||||
#define MIPI_CAL_CONFIG_CSIAB_CLK 0x1b
|
||||
#define MIPI_CAL_CONFIG_DSIC_CLK 0x1c
|
||||
#define MIPI_CAL_CONFIG_CSICD_CLK 0x1c
|
||||
#define MIPI_CAL_CONFIG_DSID_CLK 0x1d
|
||||
#define MIPI_CAL_CONFIG_CSIE_CLK 0x1d
|
||||
|
||||
/* for data and clock lanes */
|
||||
#define MIPI_CAL_CONFIG_SELECT (1 << 21)
|
||||
|
||||
/* for data lanes */
|
||||
#define MIPI_CAL_CONFIG_HSPDOS(x) (((x) & 0x1f) << 16)
|
||||
#define MIPI_CAL_CONFIG_HSPUOS(x) (((x) & 0x1f) << 8)
|
||||
#define MIPI_CAL_CONFIG_TERMOS(x) (((x) & 0x1f) << 0)
|
||||
|
||||
/* for clock lanes */
|
||||
#define MIPI_CAL_CONFIG_HSCLKPDOSD(x) (((x) & 0x1f) << 8)
|
||||
#define MIPI_CAL_CONFIG_HSCLKPUOSD(x) (((x) & 0x1f) << 0)
|
||||
|
||||
#define MIPI_CAL_BIAS_PAD_CFG0 0x16
|
||||
#define MIPI_CAL_BIAS_PAD_PDVCLAMP (1 << 1)
|
||||
#define MIPI_CAL_BIAS_PAD_E_VCLAMP_REF (1 << 0)
|
||||
|
||||
#define MIPI_CAL_BIAS_PAD_CFG1 0x17
|
||||
#define MIPI_CAL_BIAS_PAD_DRV_DN_REF(x) (((x) & 0x7) << 16)
|
||||
#define MIPI_CAL_BIAS_PAD_DRV_UP_REF(x) (((x) & 0x7) << 8)
|
||||
|
||||
#define MIPI_CAL_BIAS_PAD_CFG2 0x18
|
||||
#define MIPI_CAL_BIAS_PAD_VCLAMP(x) (((x) & 0x7) << 16)
|
||||
#define MIPI_CAL_BIAS_PAD_VAUXP(x) (((x) & 0x7) << 4)
|
||||
#define MIPI_CAL_BIAS_PAD_PDVREG (1 << 1)
|
||||
|
||||
struct tegra_mipi_pad {
|
||||
unsigned long data;
|
||||
unsigned long clk;
|
||||
};
|
||||
|
||||
struct tegra_mipi_soc {
|
||||
int has_clk_lane;
|
||||
const struct tegra_mipi_pad *pads;
|
||||
unsigned int num_pads;
|
||||
|
||||
int clock_enable_override;
|
||||
int needs_vclamp_ref;
|
||||
|
||||
/* bias pad configuration settings */
|
||||
u8 pad_drive_down_ref;
|
||||
u8 pad_drive_up_ref;
|
||||
|
||||
u8 pad_vclamp_level;
|
||||
u8 pad_vauxp_level;
|
||||
|
||||
/* calibration settings for data lanes */
|
||||
u8 hspdos;
|
||||
u8 hspuos;
|
||||
u8 termos;
|
||||
|
||||
/* calibration settings for clock lanes */
|
||||
u8 hsclkpdos;
|
||||
u8 hsclkpuos;
|
||||
};
|
||||
|
||||
struct tegra_mipi {
|
||||
const struct tegra_mipi_soc *soc;
|
||||
void *regs;
|
||||
};
|
||||
|
||||
struct tegra_mipi_device {
|
||||
struct tegra_mipi *mipi;
|
||||
unsigned long pads;
|
||||
};
|
||||
|
||||
struct tegra_mipi_device *tegra_mipi_request(struct tegra_mipi_device *device,
|
||||
int device_index);
|
||||
int tegra_mipi_calibrate(struct tegra_mipi_device *device);
|
||||
#endif /* __MIPI_DSI_H__ */
|
28
src/soc/nvidia/tegra210/include/soc/mmu_operations.h
Normal file
28
src/soc/nvidia/tegra210/include/soc/mmu_operations.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_MMU_OPERATIONS_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_MMU_OPERATIONS_H__
|
||||
|
||||
void tegra210_mmu_init(void);
|
||||
|
||||
/* Default ttb size of 4MiB */
|
||||
#define TTB_SIZE 0x4
|
||||
|
||||
#endif //__SOC_NVIDIA_TEGRA210_MMU_OPERATIONS_H__
|
37
src/soc/nvidia/tegra210/include/soc/mtc.h
Normal file
37
src/soc/nvidia/tegra210/include/soc/mtc.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_MTC_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_MTC_H__
|
||||
|
||||
#include <boot/coreboot_tables.h>
|
||||
|
||||
#if CONFIG_HAVE_MTC
|
||||
|
||||
int tegra210_run_mtc(void);
|
||||
void soc_add_mtc(struct lb_header *header);
|
||||
|
||||
#else
|
||||
|
||||
static inline int tegra210_run_mtc(void) { return -1; }
|
||||
static inline void soc_add_mtc(struct lb_header *header) {}
|
||||
|
||||
#endif /* CONFIG_HAVE_MTC */
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_MTC_H__ */
|
94
src/soc/nvidia/tegra210/include/soc/padconfig.h
Normal file
94
src/soc/nvidia/tegra210/include/soc/padconfig.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_PAD_CFG_H
|
||||
#define __SOC_NVIDIA_TEGRA210_PAD_CFG_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <soc/pinmux.h>
|
||||
|
||||
struct pad_config {
|
||||
uint16_t pinmux_flags; /* PU/PU, OD, INPUT, SFIO, etc */
|
||||
uint8_t gpio_index; /* bank, port, index */
|
||||
uint16_t pinmux_index:9;
|
||||
uint16_t unused:1;
|
||||
uint16_t sfio:1;
|
||||
uint16_t gpio_out0:1;
|
||||
uint16_t gpio_out1:1;
|
||||
uint16_t pad_has_gpio:1;
|
||||
uint16_t por_pullup:1;
|
||||
};
|
||||
|
||||
#define PAD_CFG_GPIO_INPUT(ball_, pinmux_flgs_) \
|
||||
{ \
|
||||
.pinmux_flags = pinmux_flgs_ | PINMUX_INPUT_ENABLE, \
|
||||
.gpio_index = PAD_TO_GPIO_##ball_, \
|
||||
.pinmux_index = PINMUX_##ball_##_INDEX, \
|
||||
.sfio = 0, \
|
||||
.pad_has_gpio = PAD_HAS_GPIO_##ball_, \
|
||||
}
|
||||
|
||||
#define PAD_CFG_GPIO_OUT0(ball_, pinmux_flgs_) \
|
||||
{ \
|
||||
.pinmux_flags = pinmux_flgs_, \
|
||||
.gpio_index = PAD_TO_GPIO_##ball_, \
|
||||
.pinmux_index = PINMUX_##ball_##_INDEX, \
|
||||
.sfio = 0, \
|
||||
.gpio_out0 = 1, \
|
||||
.pad_has_gpio = PAD_HAS_GPIO_##ball_, \
|
||||
}
|
||||
|
||||
#define PAD_CFG_GPIO_OUT1(ball_, pinmux_flgs_) \
|
||||
{ \
|
||||
.pinmux_flags = pinmux_flgs_, \
|
||||
.gpio_index = PAD_TO_GPIO_##ball_, \
|
||||
.pinmux_index = PINMUX_##ball_##_INDEX, \
|
||||
.sfio = 0, \
|
||||
.gpio_out1 = 1, \
|
||||
.pad_has_gpio = PAD_HAS_GPIO_##ball_, \
|
||||
}
|
||||
|
||||
#define PAD_CFG_SFIO(ball_, pinmux_flgs_, sfio_) \
|
||||
{ \
|
||||
.pinmux_flags = pinmux_flgs_ | \
|
||||
PINMUX_##ball_##_FUNC_##sfio_, \
|
||||
.gpio_index = PAD_TO_GPIO_##ball_, \
|
||||
.pinmux_index = PINMUX_##ball_##_INDEX, \
|
||||
.sfio = 1, \
|
||||
.pad_has_gpio = PAD_HAS_GPIO_##ball_, \
|
||||
}
|
||||
|
||||
#define PAD_CFG_UNUSED(ball_) \
|
||||
{ \
|
||||
.gpio_index = PAD_TO_GPIO_##ball_, \
|
||||
.pinmux_index = PINMUX_##ball_##_INDEX, \
|
||||
.unused = 1, \
|
||||
.pad_has_gpio = PAD_HAS_GPIO_##ball_, \
|
||||
}
|
||||
/*
|
||||
* Configure the pads associated with entry according to the configuration.
|
||||
*/
|
||||
void soc_configure_pads(const struct pad_config * const entries, size_t num);
|
||||
/* I2C6 requires special init as its pad lives int the SOR/DPAUX block */
|
||||
void soc_configure_i2c6pad(void);
|
||||
void soc_configure_host1x(void);
|
||||
/* APE (Audio Processing Engine) requires special init */
|
||||
void soc_configure_ape(void);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_PAD_CFG_H */
|
285
src/soc/nvidia/tegra210/include/soc/pinmux.h
Normal file
285
src/soc/nvidia/tegra210/include/soc/pinmux.h
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_PINMUX_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_PINMUX_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <soc/nvidia/tegra/gpio.h>
|
||||
#include <soc/nvidia/tegra/pinmux.h>
|
||||
|
||||
enum {
|
||||
PINMUX_FUNC_MASK = 3 << 0,
|
||||
|
||||
PINMUX_PULL_MASK = 3 << 2,
|
||||
PINMUX_PULL_NONE = 0 << 2,
|
||||
PINMUX_PULL_DOWN = 1 << 2,
|
||||
PINMUX_PULL_UP = 2 << 2,
|
||||
|
||||
PINMUX_TRISTATE = 1 << 4,
|
||||
PINMUX_PARKED = 1 << 5,
|
||||
PINMUX_INPUT_ENABLE = 1 << 6,
|
||||
PINMUX_LOCK = 1 << 7,
|
||||
PINMUX_LPDR = 1 << 8,
|
||||
PINMUX_HSM = 1 << 9,
|
||||
PINMUX_IO_HV = 1 << 10,
|
||||
PINMUX_OPEN_DRAIN = 1 << 11,
|
||||
PINMUX_SCHMT = 1 << 12,
|
||||
};
|
||||
|
||||
/* GPIO index constants. */
|
||||
|
||||
#define GPIO_PORT_CONSTANTS(port) \
|
||||
GPIO_##port##0_INDEX, GPIO_##port##1_INDEX, GPIO_##port##2_INDEX, \
|
||||
GPIO_##port##3_INDEX, GPIO_##port##4_INDEX, GPIO_##port##5_INDEX, \
|
||||
GPIO_##port##6_INDEX, GPIO_##port##7_INDEX
|
||||
|
||||
enum {
|
||||
GPIO_PORT_CONSTANTS(A),
|
||||
GPIO_PORT_CONSTANTS(B),
|
||||
GPIO_PORT_CONSTANTS(C),
|
||||
GPIO_PORT_CONSTANTS(D),
|
||||
GPIO_PORT_CONSTANTS(E),
|
||||
GPIO_PORT_CONSTANTS(F),
|
||||
GPIO_PORT_CONSTANTS(G),
|
||||
GPIO_PORT_CONSTANTS(H),
|
||||
GPIO_PORT_CONSTANTS(I),
|
||||
GPIO_PORT_CONSTANTS(J),
|
||||
GPIO_PORT_CONSTANTS(K),
|
||||
GPIO_PORT_CONSTANTS(L),
|
||||
GPIO_PORT_CONSTANTS(M),
|
||||
GPIO_PORT_CONSTANTS(N),
|
||||
GPIO_PORT_CONSTANTS(O),
|
||||
GPIO_PORT_CONSTANTS(P),
|
||||
GPIO_PORT_CONSTANTS(Q),
|
||||
GPIO_PORT_CONSTANTS(R),
|
||||
GPIO_PORT_CONSTANTS(S),
|
||||
GPIO_PORT_CONSTANTS(T),
|
||||
GPIO_PORT_CONSTANTS(U),
|
||||
GPIO_PORT_CONSTANTS(V),
|
||||
GPIO_PORT_CONSTANTS(W),
|
||||
GPIO_PORT_CONSTANTS(X),
|
||||
GPIO_PORT_CONSTANTS(Y),
|
||||
GPIO_PORT_CONSTANTS(Z),
|
||||
GPIO_PORT_CONSTANTS(AA),
|
||||
GPIO_PORT_CONSTANTS(BB),
|
||||
GPIO_PORT_CONSTANTS(CC),
|
||||
GPIO_PORT_CONSTANTS(DD),
|
||||
GPIO_PORT_CONSTANTS(EE),
|
||||
GPIO_PORT_CONSTANTS(FF),
|
||||
GPIO_NONE_INDEX = 0,
|
||||
};
|
||||
|
||||
#define PINMUX_CONSTANTS_GPIO(name, gpio) \
|
||||
PINMUX_GPIO_##gpio = PINMUX_##name##_INDEX
|
||||
|
||||
#define PINMUX_CONSTANTS(index, name, por_pu, gpio, has_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, \
|
||||
PAD_TO_GPIO_##name = GPIO_##gpio##_INDEX, \
|
||||
PAD_HAS_GPIO_##name = has_gpio, \
|
||||
PAD_POR_PU_##name = por_pu
|
||||
|
||||
#define PAD_GPIO(index, name, por_pu, gpio, func0, func1, func2, func3) \
|
||||
PINMUX_CONSTANTS(index, name, por_pu, gpio, 1, \
|
||||
func0, func1, func2, func3), \
|
||||
PINMUX_CONSTANTS_GPIO(name, gpio)
|
||||
|
||||
#define PAD_NO_GPIO(index, name, por_pu, func0, func1, func2, func3) \
|
||||
PINMUX_CONSTANTS(index, name, por_pu, NONE, 0, \
|
||||
func0, func1, func2, func3)
|
||||
|
||||
enum {
|
||||
/* Power-on-reset pull states. */
|
||||
POR_PU = 2,
|
||||
POR_PD = 1,
|
||||
POR_NP = 0,
|
||||
|
||||
PAD_GPIO(0, SDMMC1_CLK, POR_PD, M0, SDMMC1, RES1, RES2, RES3),
|
||||
PAD_GPIO(1, SDMMC1_CMD, POR_PU, M1, SDMMC1, RES1, RES2, RES3),
|
||||
PAD_GPIO(2, SDMMC1_DAT3, POR_PU, M2, SDMMC1, RES1, RES2, RES3),
|
||||
PAD_GPIO(3, SDMMC1_DAT2, POR_PU, M3, SDMMC1, RES1, RES2, RES3),
|
||||
PAD_GPIO(4, SDMMC1_DAT1, POR_PU, M4, SDMMC1, RES1, RES2, RES3),
|
||||
PAD_GPIO(5, SDMMC1_DAT0, POR_PU, M5, SDMMC1, RES1, RES2, RES3),
|
||||
PAD_GPIO(6, SDMMC3_CLK, POR_PD, P0, SDMMC3, RES1, RES2, RES3),
|
||||
PAD_GPIO(7, SDMMC3_CMD, POR_PU, P1, SDMMC3, RES1, RES2, RES3),
|
||||
PAD_GPIO(8, SDMMC3_DAT0, POR_PU, P2, SDMMC3, RES1, RES2, RES3),
|
||||
PAD_GPIO(9, SDMMC3_DAT1, POR_PU, P3, SDMMC3, RES1, RES2, RES3),
|
||||
PAD_GPIO(10, SDMMC3_DAT2, POR_PU, P4, SDMMC3, RES1, RES2, RES3),
|
||||
PAD_GPIO(11, SDMMC3_DAT3, POR_PU, P5, SDMMC3, RES1, RES2, RES3),
|
||||
/* GPIO12 - unused */
|
||||
/* GPIO13 - unused */
|
||||
PAD_GPIO(14, PEX_L0_RST_N, POR_NP, A0, PE0, RES1, RES2, RES3),
|
||||
PAD_GPIO(15, PEX_L0_CLKREQ_N, POR_NP, A1, PE0, RES1, RES2, RES3),
|
||||
PAD_GPIO(16, PEX_WAKE_N, POR_NP, A2, PE, RES1, RES2, RES3),
|
||||
PAD_GPIO(17, PEX_L1_RST_N, POR_NP, A3, PE1, RES1, RES2, RES3),
|
||||
PAD_GPIO(18, PEX_L1_CLKREQ_N, POR_NP, A4, PE1, RES1, RES2, RES3),
|
||||
PAD_GPIO(19, SATA_LED_ACTIVE, POR_NP, A5, SATA, RES1, RES2, RES3),
|
||||
PAD_GPIO(20, SPI1_MOSI, POR_PD, C0, SPI1, RES1, RES2, RES3),
|
||||
PAD_GPIO(21, SPI1_MISO, POR_PD, C1, SPI1, RES1, RES2, RES3),
|
||||
PAD_GPIO(22, SPI1_SCK, POR_PD, C2, SPI1, RES1, RES2, RES3),
|
||||
PAD_GPIO(23, SPI1_CS0, POR_PU, C3, SPI1, RES1, RES2, RES3),
|
||||
PAD_GPIO(24, SPI1_CS1, POR_PU, C4, SPI1, RES1, RES2, RES3),
|
||||
PAD_GPIO(25, SPI2_MOSI, POR_PD, B4, SPI2, DTV, RES2, RES3),
|
||||
PAD_GPIO(26, SPI2_MISO, POR_PD, B5, SPI2, DTV, RES2, RES3),
|
||||
PAD_GPIO(27, SPI2_SCK, POR_PD, B6, SPI2, DTV, RES2, RES3),
|
||||
PAD_GPIO(28, SPI2_CS0, POR_PU, B7, SPI2, DTV, RES2, RES3),
|
||||
PAD_GPIO(29, SPI2_CS1, POR_PU, DD0, SPI2, RES1, RES2, RES3),
|
||||
PAD_GPIO(30, SPI4_MOSI, POR_PD, C7, SPI4, RES1, RES2, RES3),
|
||||
PAD_GPIO(31, SPI4_MISO, POR_PD, D0, SPI4, RES1, RES2, RES3),
|
||||
PAD_GPIO(32, SPI4_SCK, POR_PD, C5, SPI4, RES1, RES2, RES3),
|
||||
PAD_GPIO(33, SPI4_CS0, POR_PU, C6, SPI4, RES1, RES2, RES3),
|
||||
PAD_GPIO(34, QSPI_SCK, POR_PU, EE0, QSPI, RES1, RES2, RES3),
|
||||
PAD_GPIO(35, QSPI_CS_N, POR_PU, EE1, QSPI, RES1, RES2, RES3),
|
||||
PAD_GPIO(36, QSPI_IO0, POR_PU, EE2, QSPI, RES1, RES2, RES3),
|
||||
PAD_GPIO(37, QSPI_IO1, POR_PU, EE3, QSPI, RES1, RES2, RES3),
|
||||
PAD_GPIO(38, QSPI_IO2, POR_PU, EE4, QSPI, RES1, RES2, RES3),
|
||||
PAD_GPIO(39, QSPI_IO3, POR_PU, EE5, QSPI, RES1, RES2, RES3),
|
||||
/* GPIO40 - unused */
|
||||
PAD_GPIO(41, DMIC1_CLK, POR_PD, E0, DMIC1, I2S3, RES2, RES3),
|
||||
PAD_GPIO(42, DMIC1_DAT, POR_PD, E1, DMIC1, I2S3, RES2, RES3),
|
||||
PAD_GPIO(43, DMIC2_CLK, POR_PD, E2, DMIC2, I2S3, RES2, RES3),
|
||||
PAD_GPIO(44, DMIC2_DAT, POR_PD, E3, DMIC2, I2S3, RES2, RES3),
|
||||
PAD_GPIO(45, DMIC3_CLK, POR_PD, E4, DMIC3, I2S5A, RES2, RES3),
|
||||
PAD_GPIO(46, DMIC3_DAT, POR_PD, E5, DMIC3, I2S5A, RES2, RES3),
|
||||
PAD_GPIO(47, GEN1_I2C_SDA, POR_NP, J0, I2C1, RES1, RES2, RES3),
|
||||
PAD_GPIO(48, GEN1_I2C_SCL, POR_NP, J1, I2C1, RES1, RES2, RES3),
|
||||
PAD_GPIO(49, GEN2_I2C_SCL, POR_NP, J2, I2C2, RES1, RES2, RES3),
|
||||
PAD_GPIO(50, GEN2_I2C_SDA, POR_NP, J3, I2C2, RES1, RES2, RES3),
|
||||
PAD_GPIO(51, GEN3_I2C_SCL, POR_NP, F0, I2C3, RES1, RES2, RES3),
|
||||
PAD_GPIO(52, GEN3_I2C_SDA, POR_NP, F1, I2C3, RES1, RES2, RES3),
|
||||
PAD_GPIO(53, CAM_I2C_SCL, POR_NP, S2, I2C3, I2CVI, RES2, RES3),
|
||||
PAD_GPIO(54, CAM_I2C_SDA, POR_NP, S3, I2C3, I2CVI, RES2, RES3),
|
||||
PAD_GPIO(55, PWR_I2C_SCL, POR_NP, Y3, I2CPMU, RES1, RES2, RES3),
|
||||
PAD_GPIO(56, PWR_I2C_SDA, POR_NP, Y4, I2CPMU, RES1, RES2, RES3),
|
||||
PAD_GPIO(57, UART1_TX, POR_PD, U0, UARTA, RES1, RES2, RES3),
|
||||
PAD_GPIO(58, UART1_RX, POR_PD, U1, UARTA, RES1, RES2, RES3),
|
||||
PAD_GPIO(59, UART1_RTS, POR_PD, U2, UARTA, RES1, RES2, RES3),
|
||||
PAD_GPIO(60, UART1_CTS, POR_PD, U3, UARTA, RES1, RES2, RES3),
|
||||
PAD_GPIO(61, UART2_TX, POR_PD, G0, UARTB, I2S4A, SPDIF, UART),
|
||||
PAD_GPIO(62, UART2_RX, POR_PD, G1, UARTB, I2S4A, SPDIF, UART),
|
||||
PAD_GPIO(63, UART2_RTS, POR_PD, G2, UARTB, I2S4A, RES2, UART),
|
||||
PAD_GPIO(64, UART2_CTS, POR_PD, G3, UARTB, I2S4A, RES2, UART),
|
||||
PAD_GPIO(65, UART3_TX, POR_PD, D1, UARTC, SPI4, RES2, RES3),
|
||||
PAD_GPIO(66, UART3_RX, POR_PD, D2, UARTC, SPI4, RES2, RES3),
|
||||
PAD_GPIO(67, UART3_RTS, POR_PD, D3, UARTC, SPI4, RES2, RES3),
|
||||
PAD_GPIO(68, UART3_CTS, POR_PD, D4, UARTC, SPI4, RES2, RES3),
|
||||
PAD_GPIO(69, UART4_TX, POR_PD, I4, UARTD, UART, RES2, RES3),
|
||||
PAD_GPIO(70, UART4_RX, POR_PD, I5, UARTD, UART, RES2, RES3),
|
||||
PAD_GPIO(71, UART4_RTS, POR_PD, I6, UARTD, UART, RES2, RES3),
|
||||
PAD_GPIO(72, UART4_CTS, POR_PD, I7, UARTD, UART, RES2, RES3),
|
||||
PAD_GPIO(73, DAP1_FS, POR_PD, B0, I2S1, RES1, RES2, RES3),
|
||||
PAD_GPIO(74, DAP1_DIN, POR_PD, B1, I2S1, RES1, RES2, RES3),
|
||||
PAD_GPIO(75, DAP1_DOUT, POR_PD, B2, I2S1, RES1, RES2, RES3),
|
||||
PAD_GPIO(76, DAP1_SCLK, POR_PD, B3, I2S1, RES1, RES2, RES3),
|
||||
PAD_GPIO(77, DAP2_FS, POR_PD, AA0, I2S2, RES1, RES2, RES3),
|
||||
PAD_GPIO(78, DAP2_DIN, POR_PD, AA1, I2S2, RES1, RES2, RES3),
|
||||
PAD_GPIO(79, DAP2_DOUT, POR_PD, AA2, I2S2, RES1, RES2, RES3),
|
||||
PAD_GPIO(80, DAP2_SCLK, POR_PD, AA3, I2S2, RES1, RES2, RES3),
|
||||
PAD_GPIO(81, DAP4_FS, POR_PD, J4, I2S4B, RES1, RES2, RES3),
|
||||
PAD_GPIO(82, DAP4_DIN, POR_PD, J5, I2S4B, RES1, RES2, RES3),
|
||||
PAD_GPIO(83, DAP4_DOUT, POR_PD, J6, I2S4B, RES1, RES2, RES3),
|
||||
PAD_GPIO(84, DAP4_SCLK, POR_PD, J7, I2S4B, RES1, RES2, RES3),
|
||||
PAD_GPIO(85, CAM1_MCLK, POR_PD, S0, EXTPERIPH3, RES1, RES2, RES3),
|
||||
PAD_GPIO(86, CAM2_MCLK, POR_PD, S1, EXTPERIPH3, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(87, JTAG_RTCK, POR_PU, JTAG, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(88, CLK_32K_IN, POR_NP, CLK_32K_IN, RES1, RES2, RES3),
|
||||
PAD_GPIO(89, CLK_32K_OUT, POR_PD, Y5, SOC, BLINK, RES2, RES3),
|
||||
PAD_NO_GPIO(90, BATT_BCL, POR_NP, BCL, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(91, CLK_REQ, POR_NP, CLK_REQ, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(92, CPU_PWR_REQ, POR_NP, CPU, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(93, PWR_INT_N, POR_NP, PMI, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(94, SHUTDOWN, POR_NP, SHUTDOWN, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(95, CORE_PWR_REQ, POR_NP, PWRON, RES1, RES2, RES3),
|
||||
PAD_GPIO(96, AUD_MCLK, POR_PD, BB0, AUD, RES1, RES2, RES3),
|
||||
PAD_GPIO(97, DVFS_PWM, POR_PD, BB1, RES0, CLDVFS, SPI3, RES3),
|
||||
PAD_GPIO(98, DVFS_CLK, POR_PU, BB2, RES0, CLDVFS, SPI3, RES3),
|
||||
PAD_GPIO(99, GPIO_X1_AUD, POR_PD, BB3, RES0, RES1, SPI3, RES3),
|
||||
PAD_GPIO(100, GPIO_X3_AUD, POR_PU, BB4, RES0, RES1, SPI3, RES3),
|
||||
PAD_NO_GPIO(101, GPIO_PCC7, POR_NP, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(102, HDMI_CEC, POR_NP, CC0, CEC, RES1, RES2, RES3),
|
||||
PAD_GPIO(103, HDMI_INT_DP_HPD, POR_PD, CC1, DP, RES1, RES2, RES3),
|
||||
PAD_GPIO(104, SPDIF_OUT, POR_PU, CC2, SPDIF, RES1, RES2, I2C3),
|
||||
PAD_GPIO(105, SPDIF_IN, POR_PD, CC3, SPDIF, RES1, RES2, I2C3),
|
||||
PAD_GPIO(106, USB_VBUS_EN0, POR_NP, CC4, USB, RES1, RES2, RES3),
|
||||
PAD_GPIO(107, USB_VBUS_EN1, POR_NP, CC5, USB, RES1, RES2, RES3),
|
||||
PAD_GPIO(108, DP_HPD0, POR_PD, CC6, DP, RES1, RES2, RES3),
|
||||
PAD_GPIO(109, WIFI_EN, POR_PD, H0, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(110, WIFI_RST, POR_PD, H1, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(111, WIFI_WAKE_AP, POR_PD, H2, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(112, AP_WAKE_BT, POR_PD, H3, RES0, UARTB, SPDIF, RES3),
|
||||
PAD_GPIO(113, BT_RST, POR_PD, H4, RES0, UARTB, SPDIF, RES3),
|
||||
PAD_GPIO(114, BT_WAKE_AP, POR_PD, H5, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(115, AP_WAKE_NFC, POR_PD, H7, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(116, NFC_EN, POR_PD, I0, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(117, NFC_INT, POR_PD, I1, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(118, GPS_EN, POR_PD, I2, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(119, GPS_RST, POR_PD, I3, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(120, CAM_RST, POR_PD, S4, VGP1, RES1, RES2, RES3),
|
||||
PAD_GPIO(121, CAM_AF_EN, POR_PD, S5, VIMCLK, VGP2, RES2, RES3),
|
||||
PAD_GPIO(122, CAM_FLASH_EN, POR_PD, S6, VIMCLK, VGP3, RES2, RES3),
|
||||
PAD_GPIO(123, CAM1_PWDN, POR_PD, S7, VGP4, RES1, RES2, RES3),
|
||||
PAD_GPIO(124, CAM2_PWDN, POR_PD, T0, VGP5, RES1, RES2, RES3),
|
||||
PAD_GPIO(125, CAM1_STROBE, POR_PD, T1, VGP6, RES1, RES2, RES3),
|
||||
PAD_GPIO(126, LCD_TE, POR_PD, Y2, DISPLAYA, RES1, RES2, RES3),
|
||||
PAD_GPIO(127, LCD_BL_PWM, POR_PD, V0, DISPLAYA, PWM0, SOR0, RES3),
|
||||
PAD_GPIO(128, LCD_BL_EN, POR_PD, V1, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(129, LCD_RST, POR_PD, V2, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(130, LCD_GPIO1, POR_PD, V3, DISPLAYB, RES1, RES2, RES3),
|
||||
PAD_GPIO(131, LCD_GPIO2, POR_PD, V4, DISPLAYB, PWM1, RES2, SOR1),
|
||||
PAD_GPIO(132, AP_READY, POR_PD, V5, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(133, TOUCH_RST, POR_PD, V6, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(134, TOUCH_CLK, POR_PD, V7, TOUCH, RES1, RES2, RES3),
|
||||
PAD_GPIO(135, MODEM_WAKE_AP, POR_PD, X0, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(136, TOUCH_INT, POR_PD, X1, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(137, MOTION_INT, POR_PD, X2, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(138, ALS_PROX_INT, POR_PD, X3, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(139, TEMP_ALERT, POR_PD, X4, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(140, BUTTON_POWER_ON, POR_PU, X5, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(141, BUTTON_VOL_UP, POR_PU, X6, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(142, BUTTON_VOL_DOWN, POR_PU, X7, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(143, BUTTON_SLIDE_SW, POR_PU, Y0, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(144, BUTTON_HOME, POR_PU, Y1, RES0, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(145, GPIO_PA6, POR_NP, SATA, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(146, GPIO_PE6, POR_PD, RES0, I2S5A, PWM2, RES3),
|
||||
PAD_NO_GPIO(147, GPIO_PE7, POR_PD, RES0, I2S5A, PWM3, RES3),
|
||||
PAD_NO_GPIO(148, GPIO_PH6, POR_PD, RES0, RES1, RES2, RES3),
|
||||
PAD_GPIO(149, GPIO_PK0, POR_PD, K0, IQC0, I2S5B, RES2, RES3),
|
||||
PAD_GPIO(150, GPIO_PK1, POR_PD, K1, IQC0, I2S5B, RES2, RES3),
|
||||
PAD_GPIO(151, GPIO_PK2, POR_PD, K2, IQC0, I2S5B, RES2, RES3),
|
||||
PAD_NO_GPIO(152, GPIO_PK3, POR_PD, IQC0, I2S5B, RES2, RES3),
|
||||
PAD_NO_GPIO(153, GPIO_PK4, POR_PD, IQC1, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(154, GPIO_PK5, POR_PD, IQC1, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(155, GPIO_PK6, POR_PD, IQC1, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(156, GPIO_PK7, POR_PD, IQC1, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(157, GPIO_PL0, POR_PD, RES0, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(158, GPIO_PL1, POR_PD, SOC, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(159, GPIO_PZ0, POR_PD, VIMCLK2, RES1, RES2, RES3),
|
||||
PAD_GPIO(160, GPIO_PZ1, POR_PD, Z1, VIMCLK2, SDMMC1, RES2, RES3),
|
||||
PAD_NO_GPIO(161, GPIO_PZ2, POR_PD, SDMMC3, CCLA, RES2, RES3),
|
||||
PAD_NO_GPIO(162, GPIO_PZ3, POR_PD, SDMMC3, RES1, RES2, RES3),
|
||||
PAD_GPIO(163, GPIO_PZ4, POR_PD, Z4, SDMMC1, RES1, RES2, RES3),
|
||||
PAD_NO_GPIO(164, GPIO_PZ5, POR_PD, SOC, RES1, RES2, RES3),
|
||||
};
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_PINMUX_H__ */
|
697
src/soc/nvidia/tegra210/include/soc/pmc.h
Normal file
697
src/soc/nvidia/tegra210/include/soc/pmc.h
Normal file
@ -0,0 +1,697 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2015, 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 _TEGRA210_PMC_H_
|
||||
#define _TEGRA210_PMC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
POWER_PARTID_CRAIL = 0,
|
||||
POWER_PARTID_TD = 1,
|
||||
POWER_PARTID_VE = 2,
|
||||
POWER_PARTID_PCX = 3,
|
||||
POWER_PARTID_C0L2 = 5,
|
||||
POWER_PARTID_MPE = 6,
|
||||
POWER_PARTID_HEG = 7,
|
||||
POWER_PARTID_SAX = 8,
|
||||
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_SOR = 17,
|
||||
POWER_PARTID_DIS = 18,
|
||||
POWER_PARTID_DISB = 19,
|
||||
POWER_PARTID_XUSBA = 20,
|
||||
POWER_PARTID_XUSBB = 21,
|
||||
POWER_PARTID_XUSBC = 22,
|
||||
POWER_PARTID_VIC = 23,
|
||||
POWER_PARTID_IRAM = 24,
|
||||
POWER_PARTID_NVDEC = 25,
|
||||
POWER_PARTID_NVJPG = 26,
|
||||
POWER_PARTID_APE = 27,
|
||||
POWER_PARTID_DFD = 28,
|
||||
POWER_PARTID_VE2 = 29,
|
||||
};
|
||||
|
||||
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; /* offset 0x300 */
|
||||
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;
|
||||
u32 secure_scratch36;
|
||||
u32 secure_scratch37;
|
||||
u32 secure_scratch38;
|
||||
u32 secure_scratch39;
|
||||
u32 secure_scratch40;
|
||||
u32 secure_scratch41;
|
||||
u32 secure_scratch42;
|
||||
u32 secure_scratch43;
|
||||
u32 secure_scratch44;
|
||||
u32 secure_scratch45;
|
||||
u32 secure_scratch46;
|
||||
u32 secure_scratch47;
|
||||
u32 secure_scratch48;
|
||||
u32 secure_scratch49;
|
||||
u32 secure_scratch50;
|
||||
u32 secure_scratch51;
|
||||
u32 secure_scratch52;
|
||||
u32 secure_scratch53;
|
||||
u32 secure_scratch54;
|
||||
u32 secure_scratch55;
|
||||
u32 secure_scratch56;
|
||||
u32 secure_scratch57;
|
||||
u32 secure_scratch58;
|
||||
u32 secure_scratch59;
|
||||
u32 secure_scratch60;
|
||||
u32 secure_scratch61;
|
||||
u32 secure_scratch62;
|
||||
u32 secure_scratch63;
|
||||
u32 secure_scratch64;
|
||||
u32 secure_scratch65;
|
||||
u32 secure_scratch66;
|
||||
u32 secure_scratch67;
|
||||
u32 secure_scratch68;
|
||||
u32 secure_scratch69;
|
||||
u32 secure_scratch70;
|
||||
u32 secure_scratch71;
|
||||
u32 secure_scratch72;
|
||||
u32 secure_scratch73;
|
||||
u32 secure_scratch74;
|
||||
u32 secure_scratch75;
|
||||
u32 secure_scratch76;
|
||||
u32 secure_scratch77;
|
||||
u32 secure_scratch78;
|
||||
u32 secure_scratch79;
|
||||
u32 _rsv0x420[8];
|
||||
u32 cntrl2; /* 0x440 */
|
||||
u32 _rsv0x444[2];
|
||||
u32 event_counter; /* 0x44C */
|
||||
u32 fuse_control;
|
||||
u32 scratch1_eco;
|
||||
u32 _rsv0x458[1];
|
||||
u32 io_dpd3_req; /* 0x45C */
|
||||
u32 io_dpd3_status;
|
||||
u32 io_dpd4_req;
|
||||
u32 io_dpd4_status;
|
||||
u32 _rsv0x46C[30];
|
||||
u32 ddr_cntrl; /* 0x4E4 */
|
||||
u32 _rsv0x4E8[70];
|
||||
u32 scratch56; /* 0x600 */
|
||||
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;
|
||||
u32 scratch120; /* 0x700 */
|
||||
u32 scratch121;
|
||||
u32 scratch122;
|
||||
u32 scratch123;
|
||||
u32 scratch124;
|
||||
u32 scratch125;
|
||||
u32 scratch126;
|
||||
u32 scratch127;
|
||||
u32 scratch128;
|
||||
u32 scratch129;
|
||||
u32 scratch130;
|
||||
u32 scratch131;
|
||||
u32 scratch132;
|
||||
u32 scratch133;
|
||||
u32 scratch134;
|
||||
u32 scratch135;
|
||||
u32 scratch136;
|
||||
u32 scratch137;
|
||||
u32 scratch138;
|
||||
u32 scratch139;
|
||||
u32 scratch140;
|
||||
u32 scratch141;
|
||||
u32 scratch142;
|
||||
u32 scratch143;
|
||||
u32 scratch144;
|
||||
u32 scratch145;
|
||||
u32 scratch146;
|
||||
u32 scratch147;
|
||||
u32 scratch148;
|
||||
u32 scratch149;
|
||||
u32 scratch150;
|
||||
u32 scratch151;
|
||||
u32 scratch152;
|
||||
u32 scratch153;
|
||||
u32 scratch154;
|
||||
u32 scratch155;
|
||||
u32 scratch156;
|
||||
u32 scratch157;
|
||||
u32 scratch158;
|
||||
u32 scratch159;
|
||||
u32 scratch160;
|
||||
u32 scratch161;
|
||||
u32 scratch162;
|
||||
u32 scratch163;
|
||||
u32 scratch164;
|
||||
u32 scratch165;
|
||||
u32 scratch166;
|
||||
u32 scratch167;
|
||||
u32 scratch168;
|
||||
u32 scratch169;
|
||||
u32 scratch170;
|
||||
u32 scratch171;
|
||||
u32 scratch172;
|
||||
u32 scratch173;
|
||||
u32 scratch174;
|
||||
u32 scratch175;
|
||||
u32 scratch176;
|
||||
u32 scratch177;
|
||||
u32 scratch178;
|
||||
u32 scratch179;
|
||||
u32 scratch180;
|
||||
u32 scratch181;
|
||||
u32 scratch182;
|
||||
u32 scratch183;
|
||||
u32 scratch184;
|
||||
u32 scratch185;
|
||||
u32 scratch186;
|
||||
u32 scratch187;
|
||||
u32 scratch188;
|
||||
u32 scratch189;
|
||||
u32 scratch190;
|
||||
u32 scratch191;
|
||||
u32 scratch192;
|
||||
u32 scratch193;
|
||||
u32 scratch194;
|
||||
u32 scratch195;
|
||||
u32 scratch196;
|
||||
u32 scratch197;
|
||||
u32 scratch198;
|
||||
u32 scratch199;
|
||||
u32 scratch200;
|
||||
u32 scratch201;
|
||||
u32 scratch202;
|
||||
u32 scratch203;
|
||||
u32 scratch204;
|
||||
u32 scratch205;
|
||||
u32 scratch206;
|
||||
u32 scratch207;
|
||||
u32 scratch208;
|
||||
u32 scratch209;
|
||||
u32 scratch210;
|
||||
u32 scratch211;
|
||||
u32 scratch212;
|
||||
u32 scratch213;
|
||||
u32 scratch214;
|
||||
u32 scratch215;
|
||||
u32 scratch216;
|
||||
u32 scratch217;
|
||||
u32 scratch218;
|
||||
u32 scratch219;
|
||||
u32 scratch220;
|
||||
u32 scratch221;
|
||||
u32 scratch222;
|
||||
u32 scratch223;
|
||||
u32 scratch224;
|
||||
u32 scratch225;
|
||||
u32 scratch226;
|
||||
u32 scratch227;
|
||||
u32 scratch228;
|
||||
u32 scratch229;
|
||||
u32 scratch230;
|
||||
u32 scratch231;
|
||||
u32 scratch232;
|
||||
u32 scratch233;
|
||||
u32 scratch234;
|
||||
u32 scratch235;
|
||||
u32 scratch236;
|
||||
u32 scratch237;
|
||||
u32 scratch238;
|
||||
u32 scratch239;
|
||||
u32 scratch240;
|
||||
u32 scratch241;
|
||||
u32 scratch242;
|
||||
u32 scratch243;
|
||||
u32 scratch244;
|
||||
u32 scratch245;
|
||||
u32 scratch246;
|
||||
u32 scratch247;
|
||||
u32 scratch248;
|
||||
u32 scratch249;
|
||||
u32 scratch250;
|
||||
u32 scratch251;
|
||||
u32 scratch252;
|
||||
u32 scratch253;
|
||||
u32 scratch254;
|
||||
u32 scratch255;
|
||||
u32 scratch256;
|
||||
u32 scratch257;
|
||||
u32 scratch258;
|
||||
u32 scratch259;
|
||||
u32 scratch260;
|
||||
u32 scratch261;
|
||||
u32 scratch262;
|
||||
u32 scratch263;
|
||||
u32 scratch264;
|
||||
u32 scratch265;
|
||||
u32 scratch266;
|
||||
u32 scratch267;
|
||||
u32 scratch268;
|
||||
u32 scratch269;
|
||||
u32 scratch270;
|
||||
u32 scratch271;
|
||||
u32 scratch272;
|
||||
u32 scratch273;
|
||||
u32 scratch274;
|
||||
u32 scratch275;
|
||||
u32 scratch276;
|
||||
u32 scratch277;
|
||||
u32 scratch278;
|
||||
u32 scratch279;
|
||||
u32 scratch280;
|
||||
u32 scratch281;
|
||||
u32 scratch282;
|
||||
u32 scratch283;
|
||||
u32 scratch284;
|
||||
u32 scratch285;
|
||||
u32 scratch286;
|
||||
u32 scratch287;
|
||||
u32 scratch288;
|
||||
u32 scratch289;
|
||||
u32 scratch290;
|
||||
u32 scratch291;
|
||||
u32 scratch292;
|
||||
u32 scratch293;
|
||||
u32 scratch294;
|
||||
u32 scratch295;
|
||||
u32 scratch296;
|
||||
u32 scratch297;
|
||||
u32 scratch298;
|
||||
u32 scratch299; /* 0x9CC */
|
||||
u32 _rsv0x9D0[50];
|
||||
u32 secure_scratch80; /* 0xa98 */
|
||||
u32 secure_scratch81;
|
||||
u32 secure_scratch82;
|
||||
u32 secure_scratch83;
|
||||
u32 secure_scratch84;
|
||||
u32 secure_scratch85;
|
||||
u32 secure_scratch86;
|
||||
u32 secure_scratch87;
|
||||
u32 secure_scratch88;
|
||||
u32 secure_scratch89;
|
||||
u32 secure_scratch90;
|
||||
u32 secure_scratch91;
|
||||
u32 secure_scratch92;
|
||||
u32 secure_scratch93;
|
||||
u32 secure_scratch94;
|
||||
u32 secure_scratch95;
|
||||
u32 secure_scratch96;
|
||||
u32 secure_scratch97;
|
||||
u32 secure_scratch98;
|
||||
u32 secure_scratch99;
|
||||
u32 secure_scratch100;
|
||||
u32 secure_scratch101;
|
||||
u32 secure_scratch102;
|
||||
u32 secure_scratch103;
|
||||
u32 secure_scratch104;
|
||||
u32 secure_scratch105;
|
||||
u32 secure_scratch106;
|
||||
u32 secure_scratch107;
|
||||
u32 secure_scratch108;
|
||||
u32 secure_scratch109;
|
||||
u32 secure_scratch110;
|
||||
u32 secure_scratch111;
|
||||
u32 secure_scratch112;
|
||||
u32 secure_scratch113;
|
||||
u32 secure_scratch114;
|
||||
u32 secure_scratch115;
|
||||
u32 secure_scratch116;
|
||||
u32 secure_scratch117;
|
||||
u32 secure_scratch118;
|
||||
u32 secure_scratch119;
|
||||
};
|
||||
|
||||
check_member(tegra_pmc_regs, secure_scratch119, 0xB34);
|
||||
|
||||
enum {
|
||||
PMC_RST_STATUS_SOURCE_MASK = 0x7,
|
||||
PMC_RST_STATUS_SOURCE_POR = 0x0,
|
||||
PMC_RST_STATUS_SOURCE_WATCHDOG = 0x1,
|
||||
PMC_RST_STATUS_SOURCE_SENSOR = 0x2,
|
||||
PMC_RST_STATUS_SOURCE_SW_MAIN = 0x3,
|
||||
PMC_RST_STATUS_SOURCE_LP0 = 0x4,
|
||||
PMC_RST_STATUS_NUM_SOURCES = 0x5,
|
||||
};
|
||||
|
||||
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_CMD_HOLD_LOW_BR00_11_MASK = 0x0007FF80,
|
||||
DPD_OFF = 1 << 30,
|
||||
DPD_ON = 2 << 30,
|
||||
};
|
||||
|
||||
enum {
|
||||
PMC_GPIO_RAIL_AO_SHIFT = 21,
|
||||
PMC_GPIO_RAIL_AO_MASK = (1 << PMC_GPIO_RAIL_AO_SHIFT),
|
||||
PMC_GPIO_RAIL_AO_DISABLE = (0 << PMC_GPIO_RAIL_AO_SHIFT),
|
||||
PMC_GPIO_RAIL_AO_ENABLE = (1 << PMC_GPIO_RAIL_AO_SHIFT),
|
||||
|
||||
PMC_AUDIO_RAIL_AO_SHIFT = 18,
|
||||
PMC_AUDIO_RAIL_AO_MASK = (1 << PMC_AUDIO_RAIL_AO_SHIFT),
|
||||
PMC_AUDIO_RAIL_AO_DISABLE = (0 << PMC_AUDIO_RAIL_AO_SHIFT),
|
||||
PMC_AUDIO_RAIL_AO_ENABLE = (1 << PMC_AUDIO_RAIL_AO_SHIFT),
|
||||
|
||||
PMC_SDMMC3_RAIL_AO_SHIFT = 13,
|
||||
PMC_SDMMC3_RAIL_AO_MASK = (1 << PMC_SDMMC3_RAIL_AO_SHIFT),
|
||||
PMC_SDMMC3_RAIL_AO_DISABLE = (0 << PMC_SDMMC3_RAIL_AO_SHIFT),
|
||||
PMC_SDMMC3_RAIL_AO_ENABLE = (1 << PMC_SDMMC3_RAIL_AO_SHIFT),
|
||||
};
|
||||
|
||||
#endif /* _TEGRA210_PMC_H_ */
|
33
src/soc/nvidia/tegra210/include/soc/power.h
Normal file
33
src/soc/nvidia/tegra210/include/soc/power.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_POWER_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_POWER_H__
|
||||
|
||||
#include <soc/pmc.h>
|
||||
|
||||
void power_ungate_partition(uint32_t id);
|
||||
void power_gate_partition(uint32_t id);
|
||||
|
||||
uint8_t pmc_rst_status(void);
|
||||
void pmc_print_rst_status(void);
|
||||
void remove_clamps(int id);
|
||||
void pmc_override_pwr_det(uint32_t bits, uint32_t override);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_POWER_H__ */
|
29
src/soc/nvidia/tegra210/include/soc/romstage.h
Normal file
29
src/soc/nvidia/tegra210/include/soc/romstage.h
Normal 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_SOC_ROMSTAGE_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_SOC_ROMSTAGE_H__
|
||||
|
||||
void romstage(void);
|
||||
void romstage_mainboard_init(void);
|
||||
|
||||
void mainboard_configure_pmc(void);
|
||||
void mainboard_enable_vdd_cpu(void);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_SOC_ROMSTAGE_H__ */
|
31
src/soc/nvidia/tegra210/include/soc/sdram.h
Normal file
31
src/soc/nvidia/tegra210/include/soc/sdram.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_SDRAM_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_SDRAM_H__
|
||||
|
||||
#include <soc/sdram_param.h>
|
||||
|
||||
uint32_t sdram_get_ram_code(void);
|
||||
void sdram_init(const struct sdram_params *param);
|
||||
|
||||
/* Save params to PMC scratch registers for use by BootROM on LP0 resume. */
|
||||
void sdram_lp0_save_params(const struct sdram_params *sdram);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_SDRAM_H__ */
|
28
src/soc/nvidia/tegra210/include/soc/sdram_configs.h
Normal file
28
src/soc/nvidia/tegra210/include/soc/sdram_configs.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_SDRAM_CONFIGS_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_SDRAM_CONFIGS_H__
|
||||
|
||||
#include <soc/sdram.h>
|
||||
|
||||
/* Loads SDRAM configurations for current system. */
|
||||
const struct sdram_params *get_sdram_config(void);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_SDRAM_CONFIGS_H__ */
|
979
src/soc/nvidia/tegra210/include/soc/sdram_param.h
Normal file
979
src/soc/nvidia/tegra210/include/soc/sdram_param.h
Normal file
@ -0,0 +1,979 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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/>.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines the SDRAM parameter structure.
|
||||
*
|
||||
* Note that PLLM is used by EMC. The field names are in camel case to ease
|
||||
* directly converting BCT config files (*.cfg) into C structure.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
/* Specifies the memory type to be undefined */
|
||||
NvBootMemoryType_None = 0,
|
||||
|
||||
/* Specifies the memory type to be DDR SDRAM */
|
||||
NvBootMemoryType_Ddr = 0,
|
||||
|
||||
/* Specifies the memory type to be LPDDR SDRAM */
|
||||
NvBootMemoryType_LpDdr = 0,
|
||||
|
||||
/* Specifies the memory type to be DDR2 SDRAM */
|
||||
NvBootMemoryType_Ddr2 = 0,
|
||||
|
||||
/* Specifies the memory type to be LPDDR2 SDRAM */
|
||||
NvBootMemoryType_LpDdr2,
|
||||
|
||||
/* Specifies the memory type to be DDR3 SDRAM */
|
||||
NvBootMemoryType_Ddr3,
|
||||
|
||||
/* Specifies the memory type to be LPDDR4 SDRAM */
|
||||
NvBootMemoryType_LpDdr4,
|
||||
|
||||
NvBootMemoryType_Num,
|
||||
|
||||
/* Specifies an entry in the ram_code table that's not in use */
|
||||
NvBootMemoryType_Unused = 0X7FFFFFF,
|
||||
};
|
||||
|
||||
enum {
|
||||
BOOT_ROM_PATCH_CONTROL_ENABLE_MASK = 0x1 << 31,
|
||||
BOOT_ROM_PATCH_CONTROL_OFFSET_SHIFT = 0,
|
||||
BOOT_ROM_PATCH_CONTROL_OFFSET_MASK = 0x7FFFFFFF << 0,
|
||||
BOOT_ROM_PATCH_CONTROL_BASE_ADDRESS = 0x70000000,
|
||||
|
||||
EMC_ZCAL_WARM_COLD_BOOT_ENABLES_COLDBOOT_MASK = 1 << 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines the SDRAM parameter structure
|
||||
*/
|
||||
struct sdram_params {
|
||||
|
||||
/* Specifies the type of memory device */
|
||||
uint32_t MemoryType;
|
||||
|
||||
/* MC/EMC clock source configuration */
|
||||
|
||||
/* Specifies the M value for PllM */
|
||||
uint32_t PllMInputDivider;
|
||||
/* Specifies the N value for PllM */
|
||||
uint32_t PllMFeedbackDivider;
|
||||
/* Specifies the time to wait for PLLM to lock (in microseconds) */
|
||||
uint32_t PllMStableTime;
|
||||
/* Specifies misc. control bits */
|
||||
uint32_t PllMSetupControl;
|
||||
/* Specifies the P value for PLLM */
|
||||
uint32_t PllMPostDivider;
|
||||
/* Specifies value for Charge Pump Gain Control */
|
||||
uint32_t PllMKCP;
|
||||
/* Specifies VCO gain */
|
||||
uint32_t PllMKVCO;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare0;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare1;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare2;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare3;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare4;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare5;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare6;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare7;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare8;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare9;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare10;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare11;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare12;
|
||||
/* Spare BCT param */
|
||||
uint32_t EmcBctSpare13;
|
||||
|
||||
/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
|
||||
uint32_t EmcClockSource;
|
||||
uint32_t EmcClockSourceDll;
|
||||
|
||||
/* Defines possible override for PLLLM_MISC2 */
|
||||
uint32_t ClkRstControllerPllmMisc2Override;
|
||||
/* enables override for PLLLM_MISC2 */
|
||||
uint32_t ClkRstControllerPllmMisc2OverrideEnable;
|
||||
/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
|
||||
uint32_t ClearClk2Mc1;
|
||||
|
||||
/* Auto-calibration of EMC pads */
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_INTERVAL */
|
||||
uint32_t EmcAutoCalInterval;
|
||||
/*
|
||||
* Specifies the value for EMC_AUTO_CAL_CONFIG
|
||||
* Note: Trigger bits are set by the SDRAM code.
|
||||
*/
|
||||
uint32_t EmcAutoCalConfig;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
|
||||
uint32_t EmcAutoCalConfig2;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
|
||||
uint32_t EmcAutoCalConfig3;
|
||||
|
||||
/* Specifies the values for EMC_AUTO_CAL_CONFIG4-8 */
|
||||
uint32_t EmcAutoCalConfig4;
|
||||
uint32_t EmcAutoCalConfig5;
|
||||
uint32_t EmcAutoCalConfig6;
|
||||
uint32_t EmcAutoCalConfig7;
|
||||
uint32_t EmcAutoCalConfig8;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
|
||||
uint32_t EmcAutoCalVrefSel0;
|
||||
uint32_t EmcAutoCalVrefSel1;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CHANNEL */
|
||||
uint32_t EmcAutoCalChannel;
|
||||
|
||||
/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
|
||||
uint32_t EmcPmacroAutocalCfg0;
|
||||
uint32_t EmcPmacroAutocalCfg1;
|
||||
uint32_t EmcPmacroAutocalCfg2;
|
||||
uint32_t EmcPmacroRxTerm;
|
||||
uint32_t EmcPmacroDqTxDrv;
|
||||
uint32_t EmcPmacroCaTxDrv;
|
||||
uint32_t EmcPmacroCmdTxDrv;
|
||||
uint32_t EmcPmacroAutocalCfgCommon;
|
||||
uint32_t EmcPmacroZctrl;
|
||||
|
||||
/*
|
||||
* Specifies the time for the calibration
|
||||
* to stabilize (in microseconds)
|
||||
*/
|
||||
uint32_t EmcAutoCalWait;
|
||||
|
||||
uint32_t EmcXm2CompPadCtrl;
|
||||
uint32_t EmcXm2CompPadCtrl2;
|
||||
uint32_t EmcXm2CompPadCtrl3;
|
||||
|
||||
/*
|
||||
* DRAM size information
|
||||
* Specifies the value for EMC_ADR_CFG
|
||||
*/
|
||||
uint32_t EmcAdrCfg;
|
||||
|
||||
/*
|
||||
* Specifies the time to wait after asserting pin
|
||||
* CKE (in microseconds)
|
||||
*/
|
||||
uint32_t EmcPinProgramWait;
|
||||
/* Specifies the extra delay before/after pin RESET/CKE command */
|
||||
uint32_t EmcPinExtraWait;
|
||||
|
||||
uint32_t EmcPinGpioEn;
|
||||
uint32_t EmcPinGpio;
|
||||
|
||||
/*
|
||||
* Specifies the extra delay after the first writing
|
||||
* of EMC_TIMING_CONTROL
|
||||
*/
|
||||
uint32_t EmcTimingControlWait;
|
||||
|
||||
/* Timing parameters required for the SDRAM */
|
||||
|
||||
/* Specifies the value for EMC_RC */
|
||||
uint32_t EmcRc;
|
||||
/* Specifies the value for EMC_RFC */
|
||||
uint32_t EmcRfc;
|
||||
/* Specifies the value for EMC_RFC_PB */
|
||||
uint32_t EmcRfcPb;
|
||||
/* Specifies the value for EMC_RFC_CTRL2 */
|
||||
uint32_t EmcRefctrl2;
|
||||
/* Specifies the value for EMC_RFC_SLR */
|
||||
uint32_t EmcRfcSlr;
|
||||
/* Specifies the value for EMC_RAS */
|
||||
uint32_t EmcRas;
|
||||
/* Specifies the value for EMC_RP */
|
||||
uint32_t EmcRp;
|
||||
/* Specifies the value for EMC_R2R */
|
||||
uint32_t EmcR2r;
|
||||
/* Specifies the value for EMC_W2W */
|
||||
uint32_t EmcW2w;
|
||||
/* Specifies the value for EMC_R2W */
|
||||
uint32_t EmcR2w;
|
||||
/* Specifies the value for EMC_W2R */
|
||||
uint32_t EmcW2r;
|
||||
/* Specifies the value for EMC_R2P */
|
||||
uint32_t EmcR2p;
|
||||
/* Specifies the value for EMC_W2P */
|
||||
uint32_t EmcW2p;
|
||||
|
||||
uint32_t EmcTppd;
|
||||
uint32_t EmcCcdmw;
|
||||
|
||||
/* Specifies the value for EMC_RD_RCD */
|
||||
uint32_t EmcRdRcd;
|
||||
/* Specifies the value for EMC_WR_RCD */
|
||||
uint32_t EmcWrRcd;
|
||||
/* Specifies the value for EMC_RRD */
|
||||
uint32_t EmcRrd;
|
||||
/* Specifies the value for EMC_REXT */
|
||||
uint32_t EmcRext;
|
||||
/* Specifies the value for EMC_WEXT */
|
||||
uint32_t EmcWext;
|
||||
/* Specifies the value for EMC_WDV */
|
||||
uint32_t EmcWdv;
|
||||
|
||||
uint32_t EmcWdvChk;
|
||||
uint32_t EmcWsv;
|
||||
uint32_t EmcWev;
|
||||
|
||||
/* Specifies the value for EMC_WDV_MASK */
|
||||
uint32_t EmcWdvMask;
|
||||
|
||||
uint32_t EmcWsDuration;
|
||||
uint32_t EmcWeDuration;
|
||||
|
||||
/* Specifies the value for EMC_QUSE */
|
||||
uint32_t EmcQUse;
|
||||
/* Specifies the value for EMC_QUSE_WIDTH */
|
||||
uint32_t EmcQuseWidth;
|
||||
/* Specifies the value for EMC_IBDLY */
|
||||
uint32_t EmcIbdly;
|
||||
/* Specifies the value for EMC_OBDLY */
|
||||
uint32_t EmcObdly;
|
||||
/* Specifies the value for EMC_EINPUT */
|
||||
uint32_t EmcEInput;
|
||||
/* Specifies the value for EMC_EINPUT_DURATION */
|
||||
uint32_t EmcEInputDuration;
|
||||
/* Specifies the value for EMC_PUTERM_EXTRA */
|
||||
uint32_t EmcPutermExtra;
|
||||
/* Specifies the value for EMC_PUTERM_WIDTH */
|
||||
uint32_t EmcPutermWidth;
|
||||
/* Specifies the value for EMC_PUTERM_ADJ */
|
||||
uint32_t EmcPutermAdj;
|
||||
|
||||
/* Specifies the value for EMC_QRST */
|
||||
uint32_t EmcQRst;
|
||||
/* Specifies the value for EMC_QSAFE */
|
||||
uint32_t EmcQSafe;
|
||||
/* Specifies the value for EMC_RDV */
|
||||
uint32_t EmcRdv;
|
||||
/* Specifies the value for EMC_RDV_MASK */
|
||||
uint32_t EmcRdvMask;
|
||||
/* Specifies the value for EMC_RDV_EARLY */
|
||||
uint32_t EmcRdvEarly;
|
||||
/* Specifies the value for EMC_RDV_EARLY_MASK */
|
||||
uint32_t EmcRdvEarlyMask;
|
||||
/* Specifies the value for EMC_QPOP */
|
||||
uint32_t EmcQpop;
|
||||
|
||||
/* Specifies the value for EMC_REFRESH */
|
||||
uint32_t EmcRefresh;
|
||||
/* Specifies the value for EMC_BURST_REFRESH_NUM */
|
||||
uint32_t EmcBurstRefreshNum;
|
||||
/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
|
||||
uint32_t EmcPreRefreshReqCnt;
|
||||
/* Specifies the value for EMC_PDEX2WR */
|
||||
uint32_t EmcPdEx2Wr;
|
||||
/* Specifies the value for EMC_PDEX2RD */
|
||||
uint32_t EmcPdEx2Rd;
|
||||
/* Specifies the value for EMC_PCHG2PDEN */
|
||||
uint32_t EmcPChg2Pden;
|
||||
/* Specifies the value for EMC_ACT2PDEN */
|
||||
uint32_t EmcAct2Pden;
|
||||
/* Specifies the value for EMC_AR2PDEN */
|
||||
uint32_t EmcAr2Pden;
|
||||
/* Specifies the value for EMC_RW2PDEN */
|
||||
uint32_t EmcRw2Pden;
|
||||
/* Specifies the value for EMC_CKE2PDEN */
|
||||
uint32_t EmcCke2Pden;
|
||||
/* Specifies the value for EMC_PDEX2CKE */
|
||||
uint32_t EmcPdex2Cke;
|
||||
/* Specifies the value for EMC_PDEX2MRR */
|
||||
uint32_t EmcPdex2Mrr;
|
||||
/* Specifies the value for EMC_TXSR */
|
||||
uint32_t EmcTxsr;
|
||||
/* Specifies the value for EMC_TXSRDLL */
|
||||
uint32_t EmcTxsrDll;
|
||||
/* Specifies the value for EMC_TCKE */
|
||||
uint32_t EmcTcke;
|
||||
/* Specifies the value for EMC_TCKESR */
|
||||
uint32_t EmcTckesr;
|
||||
/* Specifies the value for EMC_TPD */
|
||||
uint32_t EmcTpd;
|
||||
/* Specifies the value for EMC_TFAW */
|
||||
uint32_t EmcTfaw;
|
||||
/* Specifies the value for EMC_TRPAB */
|
||||
uint32_t EmcTrpab;
|
||||
/* Specifies the value for EMC_TCLKSTABLE */
|
||||
uint32_t EmcTClkStable;
|
||||
/* Specifies the value for EMC_TCLKSTOP */
|
||||
uint32_t EmcTClkStop;
|
||||
/* Specifies the value for EMC_TREFBW */
|
||||
uint32_t EmcTRefBw;
|
||||
|
||||
/* FBIO configuration values */
|
||||
|
||||
/* Specifies the value for EMC_FBIO_CFG5 */
|
||||
uint32_t EmcFbioCfg5;
|
||||
/* Specifies the value for EMC_FBIO_CFG7 */
|
||||
uint32_t EmcFbioCfg7;
|
||||
/* Specifies the value for EMC_FBIO_CFG8 */
|
||||
uint32_t EmcFbioCfg8;
|
||||
|
||||
/* Command mapping for CMD brick 0 */
|
||||
uint32_t EmcCmdMappingCmd0_0;
|
||||
uint32_t EmcCmdMappingCmd0_1;
|
||||
uint32_t EmcCmdMappingCmd0_2;
|
||||
uint32_t EmcCmdMappingCmd1_0;
|
||||
uint32_t EmcCmdMappingCmd1_1;
|
||||
uint32_t EmcCmdMappingCmd1_2;
|
||||
uint32_t EmcCmdMappingCmd2_0;
|
||||
uint32_t EmcCmdMappingCmd2_1;
|
||||
uint32_t EmcCmdMappingCmd2_2;
|
||||
uint32_t EmcCmdMappingCmd3_0;
|
||||
uint32_t EmcCmdMappingCmd3_1;
|
||||
uint32_t EmcCmdMappingCmd3_2;
|
||||
uint32_t EmcCmdMappingByte;
|
||||
|
||||
/* Specifies the value for EMC_FBIO_SPARE */
|
||||
uint32_t EmcFbioSpare;
|
||||
|
||||
/* Specifies the value for EMC_CFG_RSV */
|
||||
uint32_t EmcCfgRsv;
|
||||
|
||||
/* MRS command values */
|
||||
|
||||
/* Specifies the value for EMC_MRS */
|
||||
uint32_t EmcMrs;
|
||||
/* Specifies the MP0 command to initialize mode registers */
|
||||
uint32_t EmcEmrs;
|
||||
/* Specifies the MP2 command to initialize mode registers */
|
||||
uint32_t EmcEmrs2;
|
||||
/* Specifies the MP3 command to initialize mode registers */
|
||||
uint32_t EmcEmrs3;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
|
||||
uint32_t EmcMrw1;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
|
||||
uint32_t EmcMrw2;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
|
||||
uint32_t EmcMrw3;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
|
||||
uint32_t EmcMrw4;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 3? at cold boot */
|
||||
uint32_t EmcMrw6;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
|
||||
uint32_t EmcMrw8;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 11? at cold boot */
|
||||
uint32_t EmcMrw9;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 12 at cold boot */
|
||||
uint32_t EmcMrw10;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 14 at cold boot */
|
||||
uint32_t EmcMrw12;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 14? at cold boot */
|
||||
uint32_t EmcMrw13;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 22 at cold boot */
|
||||
uint32_t EmcMrw14;
|
||||
/*
|
||||
* Specifies the programming to extra LPDDR2 Mode Register
|
||||
* at cold boot
|
||||
*/
|
||||
uint32_t EmcMrwExtra;
|
||||
/*
|
||||
* Specifies the programming to extra LPDDR2 Mode Register
|
||||
* at warm boot
|
||||
*/
|
||||
uint32_t EmcWarmBootMrwExtra;
|
||||
/*
|
||||
* Specify the enable of extra Mode Register programming at
|
||||
* warm boot
|
||||
*/
|
||||
uint32_t EmcWarmBootExtraModeRegWriteEnable;
|
||||
/*
|
||||
* Specify the enable of extra Mode Register programming at
|
||||
* cold boot
|
||||
*/
|
||||
uint32_t EmcExtraModeRegWriteEnable;
|
||||
|
||||
/* Specifies the EMC_MRW reset command value */
|
||||
uint32_t EmcMrwResetCommand;
|
||||
/* Specifies the EMC Reset wait time (in microseconds) */
|
||||
uint32_t EmcMrwResetNInitWait;
|
||||
/* Specifies the value for EMC_MRS_WAIT_CNT */
|
||||
uint32_t EmcMrsWaitCnt;
|
||||
/* Specifies the value for EMC_MRS_WAIT_CNT2 */
|
||||
uint32_t EmcMrsWaitCnt2;
|
||||
|
||||
/* EMC miscellaneous configurations */
|
||||
|
||||
/* Specifies the value for EMC_CFG */
|
||||
uint32_t EmcCfg;
|
||||
/* Specifies the value for EMC_CFG_2 */
|
||||
uint32_t EmcCfg2;
|
||||
/* Specifies the pipe bypass controls */
|
||||
uint32_t EmcCfgPipe;
|
||||
uint32_t EmcCfgPipeClk;
|
||||
uint32_t EmcFdpdCtrlCmdNoRamp;
|
||||
uint32_t EmcCfgUpdate;
|
||||
|
||||
/* Specifies the value for EMC_DBG */
|
||||
uint32_t EmcDbg;
|
||||
uint32_t EmcDbgWriteMux;
|
||||
|
||||
/* Specifies the value for EMC_CMDQ */
|
||||
uint32_t EmcCmdQ;
|
||||
/* Specifies the value for EMC_MC2EMCQ */
|
||||
uint32_t EmcMc2EmcQ;
|
||||
/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
|
||||
uint32_t EmcDynSelfRefControl;
|
||||
|
||||
/* Specifies the value for MEM_INIT_DONE */
|
||||
uint32_t AhbArbitrationXbarCtrlMemInitDone;
|
||||
|
||||
/* Specifies the value for EMC_CFG_DIG_DLL */
|
||||
uint32_t EmcCfgDigDll;
|
||||
uint32_t EmcCfgDigDll_1;
|
||||
/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
|
||||
uint32_t EmcCfgDigDllPeriod;
|
||||
/* Specifies the value of *DEV_SELECTN of various EMC registers */
|
||||
uint32_t EmcDevSelect;
|
||||
|
||||
/* Specifies the value for EMC_SEL_DPD_CTRL */
|
||||
uint32_t EmcSelDpdCtrl;
|
||||
|
||||
/* Pads trimmer delays */
|
||||
uint32_t EmcFdpdCtrlDq;
|
||||
uint32_t EmcFdpdCtrlCmd;
|
||||
uint32_t EmcPmacroIbVrefDq_0;
|
||||
uint32_t EmcPmacroIbVrefDq_1;
|
||||
uint32_t EmcPmacroIbVrefDqs_0;
|
||||
uint32_t EmcPmacroIbVrefDqs_1;
|
||||
uint32_t EmcPmacroIbRxrt;
|
||||
uint32_t EmcCfgPipe1;
|
||||
uint32_t EmcCfgPipe2;
|
||||
|
||||
/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
|
||||
uint32_t EmcPmacroQuseDdllRank0_0;
|
||||
uint32_t EmcPmacroQuseDdllRank0_1;
|
||||
uint32_t EmcPmacroQuseDdllRank0_2;
|
||||
uint32_t EmcPmacroQuseDdllRank0_3;
|
||||
uint32_t EmcPmacroQuseDdllRank0_4;
|
||||
uint32_t EmcPmacroQuseDdllRank0_5;
|
||||
uint32_t EmcPmacroQuseDdllRank1_0;
|
||||
uint32_t EmcPmacroQuseDdllRank1_1;
|
||||
uint32_t EmcPmacroQuseDdllRank1_2;
|
||||
uint32_t EmcPmacroQuseDdllRank1_3;
|
||||
uint32_t EmcPmacroQuseDdllRank1_4;
|
||||
uint32_t EmcPmacroQuseDdllRank1_5;
|
||||
|
||||
uint32_t EmcPmacroObDdllLongDqRank0_0;
|
||||
uint32_t EmcPmacroObDdllLongDqRank0_1;
|
||||
uint32_t EmcPmacroObDdllLongDqRank0_2;
|
||||
uint32_t EmcPmacroObDdllLongDqRank0_3;
|
||||
uint32_t EmcPmacroObDdllLongDqRank0_4;
|
||||
uint32_t EmcPmacroObDdllLongDqRank0_5;
|
||||
uint32_t EmcPmacroObDdllLongDqRank1_0;
|
||||
uint32_t EmcPmacroObDdllLongDqRank1_1;
|
||||
uint32_t EmcPmacroObDdllLongDqRank1_2;
|
||||
uint32_t EmcPmacroObDdllLongDqRank1_3;
|
||||
uint32_t EmcPmacroObDdllLongDqRank1_4;
|
||||
uint32_t EmcPmacroObDdllLongDqRank1_5;
|
||||
|
||||
uint32_t EmcPmacroObDdllLongDqsRank0_0;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank0_1;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank0_2;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank0_3;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank0_4;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank0_5;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank1_0;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank1_1;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank1_2;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank1_3;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank1_4;
|
||||
uint32_t EmcPmacroObDdllLongDqsRank1_5;
|
||||
|
||||
uint32_t EmcPmacroIbDdllLongDqsRank0_0;
|
||||
uint32_t EmcPmacroIbDdllLongDqsRank0_1;
|
||||
uint32_t EmcPmacroIbDdllLongDqsRank0_2;
|
||||
uint32_t EmcPmacroIbDdllLongDqsRank0_3;
|
||||
uint32_t EmcPmacroIbDdllLongDqsRank1_0;
|
||||
uint32_t EmcPmacroIbDdllLongDqsRank1_1;
|
||||
uint32_t EmcPmacroIbDdllLongDqsRank1_2;
|
||||
uint32_t EmcPmacroIbDdllLongDqsRank1_3;
|
||||
|
||||
uint32_t EmcPmacroDdllLongCmd_0;
|
||||
uint32_t EmcPmacroDdllLongCmd_1;
|
||||
uint32_t EmcPmacroDdllLongCmd_2;
|
||||
uint32_t EmcPmacroDdllLongCmd_3;
|
||||
uint32_t EmcPmacroDdllLongCmd_4;
|
||||
uint32_t EmcPmacroDdllShortCmd_0;
|
||||
uint32_t EmcPmacroDdllShortCmd_1;
|
||||
uint32_t EmcPmacroDdllShortCmd_2;
|
||||
|
||||
/*
|
||||
* Specifies the delay after asserting CKE pin during a WarmBoot0
|
||||
* sequence (in microseconds)
|
||||
*/
|
||||
uint32_t WarmBootWait;
|
||||
|
||||
/* Specifies the value for EMC_ODT_WRITE */
|
||||
uint32_t EmcOdtWrite;
|
||||
|
||||
/* Periodic ZQ calibration */
|
||||
|
||||
/*
|
||||
* Specifies the value for EMC_ZCAL_INTERVAL
|
||||
* Value 0 disables ZQ calibration
|
||||
*/
|
||||
uint32_t EmcZcalInterval;
|
||||
/* Specifies the value for EMC_ZCAL_WAIT_CNT */
|
||||
uint32_t EmcZcalWaitCnt;
|
||||
/* Specifies the value for EMC_ZCAL_MRW_CMD */
|
||||
uint32_t EmcZcalMrwCmd;
|
||||
|
||||
/* DRAM initialization sequence flow control */
|
||||
|
||||
/* Specifies the MRS command value for resetting DLL */
|
||||
uint32_t EmcMrsResetDll;
|
||||
/* Specifies the command for ZQ initialization of device 0 */
|
||||
uint32_t EmcZcalInitDev0;
|
||||
/* Specifies the command for ZQ initialization of device 1 */
|
||||
uint32_t EmcZcalInitDev1;
|
||||
/*
|
||||
* Specifies the wait time after programming a ZQ initialization
|
||||
* command (in microseconds)
|
||||
*/
|
||||
uint32_t EmcZcalInitWait;
|
||||
/*
|
||||
* Specifies the enable for ZQ calibration at cold boot [bit 0]
|
||||
* and warm boot [bit 1]
|
||||
*/
|
||||
uint32_t EmcZcalWarmColdBootEnables;
|
||||
|
||||
/*
|
||||
* Specifies the MRW command to LPDDR2 for ZQ calibration
|
||||
* on warmboot
|
||||
*/
|
||||
/* Is issued to both devices separately */
|
||||
uint32_t EmcMrwLpddr2ZcalWarmBoot;
|
||||
/*
|
||||
* Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
|
||||
* Is issued to both devices separately
|
||||
*/
|
||||
uint32_t EmcZqCalDdr3WarmBoot;
|
||||
uint32_t EmcZqCalLpDdr4WarmBoot;
|
||||
/*
|
||||
* Specifies the wait time for ZQ calibration on warmboot
|
||||
* (in microseconds)
|
||||
*/
|
||||
uint32_t EmcZcalWarmBootWait;
|
||||
/*
|
||||
* Specifies the enable for DRAM Mode Register programming
|
||||
* at warm boot
|
||||
*/
|
||||
uint32_t EmcMrsWarmBootEnable;
|
||||
/*
|
||||
* Specifies the wait time after sending an MRS DLL reset command
|
||||
* in microseconds)
|
||||
*/
|
||||
uint32_t EmcMrsResetDllWait;
|
||||
/* Specifies the extra MRS command to initialize mode registers */
|
||||
uint32_t EmcMrsExtra;
|
||||
/* Specifies the extra MRS command at warm boot */
|
||||
uint32_t EmcWarmBootMrsExtra;
|
||||
/* Specifies the EMRS command to enable the DDR2 DLL */
|
||||
uint32_t EmcEmrsDdr2DllEnable;
|
||||
/* Specifies the MRS command to reset the DDR2 DLL */
|
||||
uint32_t EmcMrsDdr2DllReset;
|
||||
/* Specifies the EMRS command to set OCD calibration */
|
||||
uint32_t EmcEmrsDdr2OcdCalib;
|
||||
/*
|
||||
* Specifies the wait between initializing DDR and setting OCD
|
||||
* calibration (in microseconds)
|
||||
*/
|
||||
uint32_t EmcDdr2Wait;
|
||||
/* Specifies the value for EMC_CLKEN_OVERRIDE */
|
||||
uint32_t EmcClkenOverride;
|
||||
|
||||
/*
|
||||
* Specifies LOG2 of the extra refresh numbers after booting
|
||||
* Program 0 to disable
|
||||
*/
|
||||
uint32_t EmcExtraRefreshNum;
|
||||
/* Specifies the master override for all EMC clocks */
|
||||
uint32_t EmcClkenOverrideAllWarmBoot;
|
||||
/* Specifies the master override for all MC clocks */
|
||||
uint32_t McClkenOverrideAllWarmBoot;
|
||||
/* Specifies digital dll period, choosing between 4 to 64 ms */
|
||||
uint32_t EmcCfgDigDllPeriodWarmBoot;
|
||||
|
||||
/* Pad controls */
|
||||
|
||||
/* Specifies the value for PMC_VDDP_SEL */
|
||||
uint32_t PmcVddpSel;
|
||||
/* Specifies the wait time after programming PMC_VDDP_SEL */
|
||||
uint32_t PmcVddpSelWait;
|
||||
/* Specifies the value for PMC_DDR_PWR */
|
||||
uint32_t PmcDdrPwr;
|
||||
/* Specifies the value for PMC_DDR_CFG */
|
||||
uint32_t PmcDdrCfg;
|
||||
/* Specifies the value for PMC_IO_DPD3_REQ */
|
||||
uint32_t PmcIoDpd3Req;
|
||||
/* Specifies the wait time after programming PMC_IO_DPD3_REQ */
|
||||
uint32_t PmcIoDpd3ReqWait;
|
||||
uint32_t PmcIoDpd4ReqWait;
|
||||
|
||||
/* Specifies the value for PMC_REG_SHORT */
|
||||
uint32_t PmcRegShort;
|
||||
/* Specifies the value for PMC_NO_IOPOWER */
|
||||
uint32_t PmcNoIoPower;
|
||||
|
||||
uint32_t PmcDdrCntrlWait;
|
||||
uint32_t PmcDdrCntrl;
|
||||
|
||||
/* Specifies the value for EMC_ACPD_CONTROL */
|
||||
uint32_t EmcAcpdControl;
|
||||
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE_CFG */
|
||||
uint32_t EmcSwizzleRank0ByteCfg;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
|
||||
uint32_t EmcSwizzleRank0Byte0;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
|
||||
uint32_t EmcSwizzleRank0Byte1;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
|
||||
uint32_t EmcSwizzleRank0Byte2;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
|
||||
uint32_t EmcSwizzleRank0Byte3;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE_CFG */
|
||||
uint32_t EmcSwizzleRank1ByteCfg;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
|
||||
uint32_t EmcSwizzleRank1Byte0;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
|
||||
uint32_t EmcSwizzleRank1Byte1;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
|
||||
uint32_t EmcSwizzleRank1Byte2;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
|
||||
uint32_t EmcSwizzleRank1Byte3;
|
||||
|
||||
/* Specifies the value for EMC_TXDSRVTTGEN */
|
||||
uint32_t EmcTxdsrvttgen;
|
||||
|
||||
/* Specifies the value for EMC_DATA_BRLSHFT_0 */
|
||||
uint32_t EmcDataBrlshft0;
|
||||
uint32_t EmcDataBrlshft1;
|
||||
|
||||
uint32_t EmcDqsBrlshft0;
|
||||
uint32_t EmcDqsBrlshft1;
|
||||
|
||||
uint32_t EmcCmdBrlshft0;
|
||||
uint32_t EmcCmdBrlshft1;
|
||||
uint32_t EmcCmdBrlshft2;
|
||||
uint32_t EmcCmdBrlshft3;
|
||||
|
||||
uint32_t EmcQuseBrlshft0;
|
||||
uint32_t EmcQuseBrlshft1;
|
||||
uint32_t EmcQuseBrlshft2;
|
||||
uint32_t EmcQuseBrlshft3;
|
||||
|
||||
uint32_t EmcDllCfg0;
|
||||
uint32_t EmcDllCfg1;
|
||||
|
||||
uint32_t EmcPmcScratch1;
|
||||
uint32_t EmcPmcScratch2;
|
||||
uint32_t EmcPmcScratch3;
|
||||
|
||||
uint32_t EmcPmacroPadCfgCtrl;
|
||||
|
||||
uint32_t EmcPmacroVttgenCtrl0;
|
||||
uint32_t EmcPmacroVttgenCtrl1;
|
||||
uint32_t EmcPmacroVttgenCtrl2;
|
||||
|
||||
uint32_t EmcPmacroBrickCtrlRfu1;
|
||||
uint32_t EmcPmacroCmdBrickCtrlFdpd;
|
||||
uint32_t EmcPmacroBrickCtrlRfu2;
|
||||
uint32_t EmcPmacroDataBrickCtrlFdpd;
|
||||
uint32_t EmcPmacroBgBiasCtrl0;
|
||||
uint32_t EmcPmacroDataPadRxCtrl;
|
||||
uint32_t EmcPmacroCmdPadRxCtrl;
|
||||
uint32_t EmcPmacroDataRxTermMode;
|
||||
uint32_t EmcPmacroCmdRxTermMode;
|
||||
uint32_t EmcPmacroDataPadTxCtrl;
|
||||
uint32_t EmcPmacroCommonPadTxCtrl;
|
||||
uint32_t EmcPmacroCmdPadTxCtrl;
|
||||
uint32_t EmcCfg3;
|
||||
|
||||
uint32_t EmcPmacroTxPwrd0;
|
||||
uint32_t EmcPmacroTxPwrd1;
|
||||
uint32_t EmcPmacroTxPwrd2;
|
||||
uint32_t EmcPmacroTxPwrd3;
|
||||
uint32_t EmcPmacroTxPwrd4;
|
||||
uint32_t EmcPmacroTxPwrd5;
|
||||
|
||||
uint32_t EmcConfigSampleDelay;
|
||||
|
||||
uint32_t EmcPmacroBrickMapping0;
|
||||
uint32_t EmcPmacroBrickMapping1;
|
||||
uint32_t EmcPmacroBrickMapping2;
|
||||
|
||||
uint32_t EmcPmacroTxSelClkSrc0;
|
||||
uint32_t EmcPmacroTxSelClkSrc1;
|
||||
uint32_t EmcPmacroTxSelClkSrc2;
|
||||
uint32_t EmcPmacroTxSelClkSrc3;
|
||||
uint32_t EmcPmacroTxSelClkSrc4;
|
||||
uint32_t EmcPmacroTxSelClkSrc5;
|
||||
|
||||
uint32_t EmcPmacroDdllBypass;
|
||||
|
||||
uint32_t EmcPmacroDdllPwrd0;
|
||||
uint32_t EmcPmacroDdllPwrd1;
|
||||
uint32_t EmcPmacroDdllPwrd2;
|
||||
|
||||
uint32_t EmcPmacroCmdCtrl0;
|
||||
uint32_t EmcPmacroCmdCtrl1;
|
||||
uint32_t EmcPmacroCmdCtrl2;
|
||||
|
||||
/* DRAM size information */
|
||||
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG */
|
||||
uint32_t McEmemAdrCfg;
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
|
||||
uint32_t McEmemAdrCfgDev0;
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
|
||||
uint32_t McEmemAdrCfgDev1;
|
||||
uint32_t McEmemAdrCfgChannelMask;
|
||||
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLECfg0 */
|
||||
uint32_t McEmemAdrCfgBankMask0;
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
|
||||
uint32_t McEmemAdrCfgBankMask1;
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
|
||||
uint32_t McEmemAdrCfgBankMask2;
|
||||
|
||||
/*
|
||||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||
* size (in KBytes)
|
||||
*/
|
||||
uint32_t McEmemCfg;
|
||||
|
||||
/* MC arbitration configuration */
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_CFG */
|
||||
uint32_t McEmemArbCfg;
|
||||
/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
|
||||
uint32_t McEmemArbOutstandingReq;
|
||||
|
||||
uint32_t McEmemArbRefpbHpCtrl;
|
||||
uint32_t McEmemArbRefpbBankCtrl;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
|
||||
uint32_t McEmemArbTimingRcd;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RP */
|
||||
uint32_t McEmemArbTimingRp;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RC */
|
||||
uint32_t McEmemArbTimingRc;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
|
||||
uint32_t McEmemArbTimingRas;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
|
||||
uint32_t McEmemArbTimingFaw;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
|
||||
uint32_t McEmemArbTimingRrd;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
|
||||
uint32_t McEmemArbTimingRap2Pre;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
|
||||
uint32_t McEmemArbTimingWap2Pre;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
|
||||
uint32_t McEmemArbTimingR2R;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
|
||||
uint32_t McEmemArbTimingW2W;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
|
||||
uint32_t McEmemArbTimingR2W;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
|
||||
uint32_t McEmemArbTimingW2R;
|
||||
|
||||
uint32_t McEmemArbTimingRFCPB;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_DA_TURNS */
|
||||
uint32_t McEmemArbDaTurns;
|
||||
/* Specifies the value for MC_EMEM_ARB_DA_COVERS */
|
||||
uint32_t McEmemArbDaCovers;
|
||||
/* Specifies the value for MC_EMEM_ARB_MISC0 */
|
||||
uint32_t McEmemArbMisc0;
|
||||
/* Specifies the value for MC_EMEM_ARB_MISC1 */
|
||||
uint32_t McEmemArbMisc1;
|
||||
uint32_t McEmemArbMisc2;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
|
||||
uint32_t McEmemArbRing1Throttle;
|
||||
/* Specifies the value for MC_EMEM_ARB_OVERRIDE */
|
||||
uint32_t McEmemArbOverride;
|
||||
/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
|
||||
uint32_t McEmemArbOverride1;
|
||||
/* Specifies the value for MC_EMEM_ARB_RSV */
|
||||
uint32_t McEmemArbRsv;
|
||||
|
||||
uint32_t McDaCfg0;
|
||||
uint32_t McEmemArbTimingCcdmw;
|
||||
|
||||
/* Specifies the value for MC_CLKEN_OVERRIDE */
|
||||
uint32_t McClkenOverride;
|
||||
|
||||
/* Specifies the value for MC_STAT_CONTROL */
|
||||
uint32_t McStatControl;
|
||||
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_BOM */
|
||||
uint32_t McVideoProtectBom;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
|
||||
uint32_t McVideoProtectBomAdrHi;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
|
||||
uint32_t McVideoProtectSizeMb;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
|
||||
uint32_t McVideoProtectVprOverride;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
|
||||
uint32_t McVideoProtectVprOverride1;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
|
||||
uint32_t McVideoProtectGpuOverride0;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
|
||||
uint32_t McVideoProtectGpuOverride1;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_BOM */
|
||||
uint32_t McSecCarveoutBom;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
|
||||
uint32_t McSecCarveoutAdrHi;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
|
||||
uint32_t McSecCarveoutSizeMb;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.
|
||||
VIDEO_PROTECT_WRITEAccess */
|
||||
uint32_t McVideoProtectWriteAccess;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.
|
||||
SEC_CARVEOUT_WRITEAccess */
|
||||
uint32_t McSecCarveoutProtectWriteAccess;
|
||||
|
||||
/* Write-Protect Regions (WPR) */
|
||||
uint32_t McGeneralizedCarveout1Bom;
|
||||
uint32_t McGeneralizedCarveout1BomHi;
|
||||
uint32_t McGeneralizedCarveout1Size128kb;
|
||||
uint32_t McGeneralizedCarveout1Access0;
|
||||
uint32_t McGeneralizedCarveout1Access1;
|
||||
uint32_t McGeneralizedCarveout1Access2;
|
||||
uint32_t McGeneralizedCarveout1Access3;
|
||||
uint32_t McGeneralizedCarveout1Access4;
|
||||
uint32_t McGeneralizedCarveout1ForceInternalAccess0;
|
||||
uint32_t McGeneralizedCarveout1ForceInternalAccess1;
|
||||
uint32_t McGeneralizedCarveout1ForceInternalAccess2;
|
||||
uint32_t McGeneralizedCarveout1ForceInternalAccess3;
|
||||
uint32_t McGeneralizedCarveout1ForceInternalAccess4;
|
||||
uint32_t McGeneralizedCarveout1Cfg0;
|
||||
|
||||
uint32_t McGeneralizedCarveout2Bom;
|
||||
uint32_t McGeneralizedCarveout2BomHi;
|
||||
uint32_t McGeneralizedCarveout2Size128kb;
|
||||
uint32_t McGeneralizedCarveout2Access0;
|
||||
uint32_t McGeneralizedCarveout2Access1;
|
||||
uint32_t McGeneralizedCarveout2Access2;
|
||||
uint32_t McGeneralizedCarveout2Access3;
|
||||
uint32_t McGeneralizedCarveout2Access4;
|
||||
uint32_t McGeneralizedCarveout2ForceInternalAccess0;
|
||||
uint32_t McGeneralizedCarveout2ForceInternalAccess1;
|
||||
uint32_t McGeneralizedCarveout2ForceInternalAccess2;
|
||||
uint32_t McGeneralizedCarveout2ForceInternalAccess3;
|
||||
uint32_t McGeneralizedCarveout2ForceInternalAccess4;
|
||||
uint32_t McGeneralizedCarveout2Cfg0;
|
||||
|
||||
uint32_t McGeneralizedCarveout3Bom;
|
||||
uint32_t McGeneralizedCarveout3BomHi;
|
||||
uint32_t McGeneralizedCarveout3Size128kb;
|
||||
uint32_t McGeneralizedCarveout3Access0;
|
||||
uint32_t McGeneralizedCarveout3Access1;
|
||||
uint32_t McGeneralizedCarveout3Access2;
|
||||
uint32_t McGeneralizedCarveout3Access3;
|
||||
uint32_t McGeneralizedCarveout3Access4;
|
||||
uint32_t McGeneralizedCarveout3ForceInternalAccess0;
|
||||
uint32_t McGeneralizedCarveout3ForceInternalAccess1;
|
||||
uint32_t McGeneralizedCarveout3ForceInternalAccess2;
|
||||
uint32_t McGeneralizedCarveout3ForceInternalAccess3;
|
||||
uint32_t McGeneralizedCarveout3ForceInternalAccess4;
|
||||
uint32_t McGeneralizedCarveout3Cfg0;
|
||||
|
||||
uint32_t McGeneralizedCarveout4Bom;
|
||||
uint32_t McGeneralizedCarveout4BomHi;
|
||||
uint32_t McGeneralizedCarveout4Size128kb;
|
||||
uint32_t McGeneralizedCarveout4Access0;
|
||||
uint32_t McGeneralizedCarveout4Access1;
|
||||
uint32_t McGeneralizedCarveout4Access2;
|
||||
uint32_t McGeneralizedCarveout4Access3;
|
||||
uint32_t McGeneralizedCarveout4Access4;
|
||||
uint32_t McGeneralizedCarveout4ForceInternalAccess0;
|
||||
uint32_t McGeneralizedCarveout4ForceInternalAccess1;
|
||||
uint32_t McGeneralizedCarveout4ForceInternalAccess2;
|
||||
uint32_t McGeneralizedCarveout4ForceInternalAccess3;
|
||||
uint32_t McGeneralizedCarveout4ForceInternalAccess4;
|
||||
uint32_t McGeneralizedCarveout4Cfg0;
|
||||
|
||||
uint32_t McGeneralizedCarveout5Bom;
|
||||
uint32_t McGeneralizedCarveout5BomHi;
|
||||
uint32_t McGeneralizedCarveout5Size128kb;
|
||||
uint32_t McGeneralizedCarveout5Access0;
|
||||
uint32_t McGeneralizedCarveout5Access1;
|
||||
uint32_t McGeneralizedCarveout5Access2;
|
||||
uint32_t McGeneralizedCarveout5Access3;
|
||||
uint32_t McGeneralizedCarveout5Access4;
|
||||
uint32_t McGeneralizedCarveout5ForceInternalAccess0;
|
||||
uint32_t McGeneralizedCarveout5ForceInternalAccess1;
|
||||
uint32_t McGeneralizedCarveout5ForceInternalAccess2;
|
||||
uint32_t McGeneralizedCarveout5ForceInternalAccess3;
|
||||
uint32_t McGeneralizedCarveout5ForceInternalAccess4;
|
||||
uint32_t McGeneralizedCarveout5Cfg0;
|
||||
|
||||
/* Specifies enable for CA training */
|
||||
uint32_t EmcCaTrainingEnable;
|
||||
|
||||
/* Set if bit 6 select is greater than bit 7 select; uses aremc.
|
||||
spec packet SWIZZLE_BIT6_GT_BIT7 */
|
||||
uint32_t SwizzleRankByteEncode;
|
||||
/* Specifies enable and offset for patched boot rom write */
|
||||
uint32_t BootRomPatchControl;
|
||||
/* Specifies data for patched boot rom write */
|
||||
uint32_t BootRomPatchData;
|
||||
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_BOM */
|
||||
uint32_t McMtsCarveoutBom;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
|
||||
uint32_t McMtsCarveoutAdrHi;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
|
||||
uint32_t McMtsCarveoutSizeMb;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
|
||||
uint32_t McMtsCarveoutRegCtrl;
|
||||
|
||||
/* End */
|
||||
};
|
||||
|
||||
check_member(sdram_params, McMtsCarveoutRegCtrl, 0x770);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__ */
|
37
src/soc/nvidia/tegra210/include/soc/secure_boot.h
Normal file
37
src/soc/nvidia/tegra210/include/soc/secure_boot.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2015, 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 _TEGRA210_SECURE_BOOT_H_
|
||||
#define _TEGRA210_SECURE_BOOT_H_
|
||||
|
||||
struct tegra_secure_boot {
|
||||
u32 sb_csr; /* offset 0x00 */
|
||||
u32 sb_pirom_start; /* offset 0x04 */
|
||||
u32 sb_pfcfg; /* offset 0x08 */
|
||||
u32 sb_secure_spare_0; /* offset 0x0c */
|
||||
u32 sb_secure_spare_1; /* offset 0x10 */
|
||||
u32 sb_secure_spare_2; /* offset 0x14 */
|
||||
u32 sb_secure_spare_3; /* offset 0x18 */
|
||||
u32 sb_secure_spare_4; /* offset 0x1c */
|
||||
u32 sb_secure_spare_5; /* offset 0x20 */
|
||||
u32 sb_secure_spare_6; /* offset 0x24 */
|
||||
u32 sb_secure_spare_7; /* offset 0x28 */
|
||||
u32 rsvd; /* offset 0x2c */
|
||||
u32 sb_aa64_reset_low; /* offset 0x30 */
|
||||
u32 sb_aa64_reset_high; /* offset 0x3c */
|
||||
};
|
||||
|
||||
#endif /* _TEGRA210_SECURE_BOOT_H_ */
|
930
src/soc/nvidia/tegra210/include/soc/sor.h
Normal file
930
src/soc/nvidia/tegra210/include/soc/sor.h
Normal file
@ -0,0 +1,930 @@
|
||||
/*
|
||||
* drivers/video/tegra/dc/sor_regs.h
|
||||
*
|
||||
* Copyright (c) 2011-2015, NVIDIA Corporation.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA210_SOR_H__
|
||||
#define __TEGRA210_SOR_H__
|
||||
|
||||
#define NV_SOR_SUPER_STATE0 (0x1)
|
||||
#define NV_SOR_SUPER_STATE0_UPDATE_SHIFT (0)
|
||||
#define NV_SOR_SUPER_STATE0_UPDATE_DEFAULT_MASK (0x1)
|
||||
#define NV_SOR_SUPER_STATE1 (0x2)
|
||||
#define NV_SOR_SUPER_STATE1_ATTACHED_SHIFT (3)
|
||||
#define NV_SOR_SUPER_STATE1_ATTACHED_NO (0 << 3)
|
||||
#define NV_SOR_SUPER_STATE1_ATTACHED_YES (1 << 3)
|
||||
#define NV_SOR_SUPER_STATE1_ASY_ORMODE_SHIFT (2)
|
||||
#define NV_SOR_SUPER_STATE1_ASY_ORMODE_SAFE (0 << 2)
|
||||
#define NV_SOR_SUPER_STATE1_ASY_ORMODE_NORMAL (1 << 2)
|
||||
#define NV_SOR_SUPER_STATE1_ASY_HEAD_OP_SHIFT (0)
|
||||
#define NV_SOR_SUPER_STATE1_ASY_HEAD_OP_DEFAULT_MASK (0x3)
|
||||
#define NV_SOR_SUPER_STATE1_ASY_HEAD_OP_SLEEP (0)
|
||||
#define NV_SOR_SUPER_STATE1_ASY_HEAD_OP_SNOOZE (1)
|
||||
#define NV_SOR_SUPER_STATE1_ASY_HEAD_OP_AWAKE (2)
|
||||
#define NV_SOR_STATE0 (0x3)
|
||||
#define NV_SOR_STATE0_UPDATE_SHIFT (0)
|
||||
#define NV_SOR_STATE0_UPDATE_DEFAULT_MASK (0x1)
|
||||
#define NV_SOR_STATE1 (0x4)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_SHIFT (17)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_DEFAULT_MASK (0xf << 17)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_16_422 (1 << 17)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_18_444 (2 << 17)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_20_422 (3 << 17)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_24_422 (4 << 17)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_24_444 (5 << 17)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_30_444 (6 << 17)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_32_422 (7 << 17)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_36_444 (8 << 17)
|
||||
#define NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_48_444 (9 << 17)
|
||||
#define NV_SOR_STATE1_ASY_REPLICATE_SHIFT (15)
|
||||
#define NV_SOR_STATE1_ASY_REPLICATE_DEFAULT_MASK (0x3 << 15)
|
||||
#define NV_SOR_STATE1_ASY_REPLICATE_OFF (0 << 15)
|
||||
#define NV_SOR_STATE1_ASY_REPLICATE_X2 (1 << 15)
|
||||
#define NV_SOR_STATE1_ASY_REPLICATE_X4 (2 << 15)
|
||||
#define NV_SOR_STATE1_ASY_DEPOL_SHIFT (14)
|
||||
#define NV_SOR_STATE1_ASY_DEPOL_DEFAULT_MASK (0x1 << 14)
|
||||
#define NV_SOR_STATE1_ASY_DEPOL_POSITIVE_TRUE (0 << 14)
|
||||
#define NV_SOR_STATE1_ASY_DEPOL_NEGATIVE_TRUE (1 << 14)
|
||||
#define NV_SOR_STATE1_ASY_VSYNCPOL_SHIFT (13)
|
||||
#define NV_SOR_STATE1_ASY_VSYNCPOL_DEFAULT_MASK (0x1 << 13)
|
||||
#define NV_SOR_STATE1_ASY_VSYNCPOL_POSITIVE_TRUE (0 << 13)
|
||||
#define NV_SOR_STATE1_ASY_VSYNCPOL_NEGATIVE_TRUE (1 << 13)
|
||||
#define NV_SOR_STATE1_ASY_HSYNCPOL_SHIFT (12)
|
||||
#define NV_SOR_STATE1_ASY_HSYNCPOL_DEFAULT_MASK (0x1 << 12)
|
||||
#define NV_SOR_STATE1_ASY_HSYNCPOL_POSITIVE_TRUE (0 << 12)
|
||||
#define NV_SOR_STATE1_ASY_HSYNCPOL_NEGATIVE_TRUE (1 << 12)
|
||||
#define NV_SOR_STATE1_ASY_PROTOCOL_SHIFT (8)
|
||||
#define NV_SOR_STATE1_ASY_PROTOCOL_DEFAULT_MASK (0xf << 8)
|
||||
#define NV_SOR_STATE1_ASY_PROTOCOL_LVDS_CUSTOM (0 << 8)
|
||||
#define NV_SOR_STATE1_ASY_PROTOCOL_DP_A (8 << 8)
|
||||
#define NV_SOR_STATE1_ASY_PROTOCOL_DP_B (9 << 8)
|
||||
#define NV_SOR_STATE1_ASY_PROTOCOL_CUSTOM (15 << 8)
|
||||
#define NV_SOR_STATE1_ASY_CRCMODE_SHIFT (6)
|
||||
#define NV_SOR_STATE1_ASY_CRCMODE_DEFAULT_MASK (0x3 << 6)
|
||||
#define NV_SOR_STATE1_ASY_CRCMODE_ACTIVE_RASTER (0 << 6)
|
||||
#define NV_SOR_STATE1_ASY_CRCMODE_COMPLETE_RASTER (1 << 6)
|
||||
#define NV_SOR_STATE1_ASY_CRCMODE_NON_ACTIVE_RASTER (2 << 6)
|
||||
#define NV_SOR_STATE1_ASY_SUBOWNER_SHIFT (4)
|
||||
#define NV_SOR_STATE1_ASY_SUBOWNER_DEFAULT_MASK (0x3 << 4)
|
||||
#define NV_SOR_STATE1_ASY_SUBOWNER_NONE (0 << 4)
|
||||
#define NV_SOR_STATE1_ASY_SUBOWNER_SUBHEAD0 (1 << 4)
|
||||
#define NV_SOR_STATE1_ASY_SUBOWNER_SUBHEAD1 (2 << 4)
|
||||
#define NV_SOR_STATE1_ASY_SUBOWNER_BOTH (3 << 4)
|
||||
#define NV_SOR_STATE1_ASY_OWNER_SHIFT (0)
|
||||
#define NV_SOR_STATE1_ASY_OWNER_DEFAULT_MASK (0xf)
|
||||
#define NV_SOR_STATE1_ASY_OWNER_NONE (0)
|
||||
#define NV_SOR_STATE1_ASY_OWNER_HEAD0 (1)
|
||||
#define NV_SOR_STATE1_ASY_OWNER_HEAD1 (2)
|
||||
#define NV_HEAD_STATE0(i) (0x5)
|
||||
#define NV_HEAD_STATE0_INTERLACED_SHIFT (4)
|
||||
#define NV_HEAD_STATE0_INTERLACED_DEFAULT_MASK (0x3 << 4)
|
||||
#define NV_HEAD_STATE0_INTERLACED_PROGRESSIVE (0 << 4)
|
||||
#define NV_HEAD_STATE0_INTERLACED_INTERLACED (1 << 4)
|
||||
#define NV_HEAD_STATE0_RANGECOMPRESS_SHIFT (3)
|
||||
#define NV_HEAD_STATE0_RANGECOMPRESS_DEFAULT_MASK (0x1 << 3)
|
||||
#define NV_HEAD_STATE0_RANGECOMPRESS_DISABLE (0 << 3)
|
||||
#define NV_HEAD_STATE0_RANGECOMPRESS_ENABLE (1 << 3)
|
||||
#define NV_HEAD_STATE0_DYNRANGE_SHIFT (2)
|
||||
#define NV_HEAD_STATE0_DYNRANGE_DEFAULT_MASK (0x1 << 2)
|
||||
#define NV_HEAD_STATE0_DYNRANGE_VESA (0 << 2)
|
||||
#define NV_HEAD_STATE0_DYNRANGE_CEA (1 << 2)
|
||||
#define NV_HEAD_STATE0_COLORSPACE_SHIFT (0)
|
||||
#define NV_HEAD_STATE0_COLORSPACE_DEFAULT_MASK (0x3)
|
||||
#define NV_HEAD_STATE0_COLORSPACE_RGB (0)
|
||||
#define NV_HEAD_STATE0_COLORSPACE_YUV_601 (1)
|
||||
#define NV_HEAD_STATE0_COLORSPACE_YUV_709 (2)
|
||||
#define NV_HEAD_STATE1(i) (0x7 + i)
|
||||
#define NV_HEAD_STATE1_VTOTAL_SHIFT (16)
|
||||
#define NV_HEAD_STATE1_VTOTAL_DEFAULT_MASK (0x7fff << 16)
|
||||
#define NV_HEAD_STATE1_HTOTAL_SHIFT (0)
|
||||
#define NV_HEAD_STATE1_HTOTAL_DEFAULT_MASK (0x7fff)
|
||||
#define NV_HEAD_STATE2(i) (0x9 + i)
|
||||
#define NV_HEAD_STATE2_VSYNC_END_SHIFT (16)
|
||||
#define NV_HEAD_STATE2_VSYNC_END_DEFAULT_MASK (0x7fff << 16)
|
||||
#define NV_HEAD_STATE2_HSYNC_END_SHIFT (0)
|
||||
#define NV_HEAD_STATE2_HSYNC_END_DEFAULT_MASK (0x7fff)
|
||||
#define NV_HEAD_STATE3(i) (0xb + i)
|
||||
#define NV_HEAD_STATE3_VBLANK_END_SHIFT (16)
|
||||
#define NV_HEAD_STATE3_VBLANK_END_DEFAULT_MASK (0x7fff << 16)
|
||||
#define NV_HEAD_STATE3_HBLANK_END_SHIFT (0)
|
||||
#define NV_HEAD_STATE3_HBLANK_END_DEFAULT_MASK (0x7fff)
|
||||
#define NV_HEAD_STATE4(i) (0xd + i)
|
||||
#define NV_HEAD_STATE4_VBLANK_START_SHIFT (16)
|
||||
#define NV_HEAD_STATE4_VBLANK_START_DEFAULT_MASK (0x7fff << 16)
|
||||
#define NV_HEAD_STATE4_HBLANK_START_SHIFT (0)
|
||||
#define NV_HEAD_STATE4_HBLANK_START_DEFAULT_MASK (0x7fff)
|
||||
#define NV_HEAD_STATE5(i) (0xf + i)
|
||||
#define NV_SOR_CRC_CNTRL (0x11)
|
||||
#define NV_SOR_CRC_CNTRL_ARM_CRC_ENABLE_SHIFT (0)
|
||||
#define NV_SOR_CRC_CNTRL_ARM_CRC_ENABLE_NO (0)
|
||||
#define NV_SOR_CRC_CNTRL_ARM_CRC_ENABLE_YES (1)
|
||||
#define NV_SOR_CRC_CNTRL_ARM_CRC_ENABLE_DIS (0)
|
||||
#define NV_SOR_CRC_CNTRL_ARM_CRC_ENABLE_EN (1)
|
||||
#define NV_SOR_CLK_CNTRL (0x13)
|
||||
#define NV_SOR_CLK_CNTRL_DP_CLK_SEL_SHIFT (0)
|
||||
#define NV_SOR_CLK_CNTRL_DP_CLK_SEL_MASK (0x3)
|
||||
#define NV_SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_PCLK (0)
|
||||
#define NV_SOR_CLK_CNTRL_DP_CLK_SEL_DIFF_PCLK (1)
|
||||
#define NV_SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK (2)
|
||||
#define NV_SOR_CLK_CNTRL_DP_CLK_SEL_DIFF_DPCLK (3)
|
||||
#define NV_SOR_CLK_CNTRL_DP_LINK_SPEED_SHIFT (2)
|
||||
#define NV_SOR_CLK_CNTRL_DP_LINK_SPEED_MASK (0x1f << 2)
|
||||
#define NV_SOR_CLK_CNTRL_DP_LINK_SPEED_G1_62 (6 << 2)
|
||||
#define NV_SOR_CLK_CNTRL_DP_LINK_SPEED_G2_7 (10 << 2)
|
||||
#define NV_SOR_CLK_CNTRL_DP_LINK_SPEED_LVDS (7 << 2)
|
||||
#define NV_SOR_CAP (0x14)
|
||||
#define NV_SOR_CAP_DP_A_SHIFT (24)
|
||||
#define NV_SOR_CAP_DP_A_DEFAULT_MASK (0x1 << 24)
|
||||
#define NV_SOR_CAP_DP_A_FALSE (0 << 24)
|
||||
#define NV_SOR_CAP_DP_A_TRUE (1 << 24)
|
||||
#define NV_SOR_CAP_DP_B_SHIFT (25)
|
||||
#define NV_SOR_CAP_DP_B_DEFAULT_MASK (0x1 << 24)
|
||||
#define NV_SOR_CAP_DP_B_FALSE (0 << 24)
|
||||
#define NV_SOR_CAP_DP_B_TRUE (1 << 24)
|
||||
#define NV_SOR_PWR (0x15)
|
||||
#define NV_SOR_PWR_SETTING_NEW_SHIFT (31)
|
||||
#define NV_SOR_PWR_SETTING_NEW_DEFAULT_MASK (0x1 << 31)
|
||||
#define NV_SOR_PWR_SETTING_NEW_DONE (0 << 31)
|
||||
#define NV_SOR_PWR_SETTING_NEW_PENDING (1 << 31)
|
||||
#define NV_SOR_PWR_SETTING_NEW_TRIGGER (1 << 31)
|
||||
#define NV_SOR_PWR_MODE_SHIFT (28)
|
||||
#define NV_SOR_PWR_MODE_DEFAULT_MASK (0x1 << 28)
|
||||
#define NV_SOR_PWR_MODE_NORMAL (0 << 28)
|
||||
#define NV_SOR_PWR_MODE_SAFE (1 << 28)
|
||||
#define NV_SOR_PWR_HALT_DELAY_SHIFT (24)
|
||||
#define NV_SOR_PWR_HALT_DELAY_DEFAULT_MASK (0x1 << 24)
|
||||
#define NV_SOR_PWR_HALT_DELAY_DONE (0 << 24)
|
||||
#define NV_SOR_PWR_HALT_DELAY_ACTIVE (1 << 24)
|
||||
#define NV_SOR_PWR_SAFE_START_SHIFT (17)
|
||||
#define NV_SOR_PWR_SAFE_START_DEFAULT_MASK (0x1 << 17)
|
||||
#define NV_SOR_PWR_SAFE_START_NORMAL (0 << 17)
|
||||
#define NV_SOR_PWR_SAFE_START_ALT (1 << 17)
|
||||
#define NV_SOR_PWR_SAFE_STATE_SHIFT (16)
|
||||
#define NV_SOR_PWR_SAFE_STATE_DEFAULT_MASK (0x1 << 16)
|
||||
#define NV_SOR_PWR_SAFE_STATE_PD (0 << 16)
|
||||
#define NV_SOR_PWR_SAFE_STATE_PU (1 << 16)
|
||||
#define NV_SOR_PWR_NORMAL_START_SHIFT (1)
|
||||
#define NV_SOR_PWR_NORMAL_START_DEFAULT_MASK (0x1 << 1)
|
||||
#define NV_SOR_PWR_NORMAL_START_NORMAL (0 << 16)
|
||||
#define NV_SOR_PWR_NORMAL_START_ALT (1 << 16)
|
||||
#define NV_SOR_PWR_NORMAL_STATE_SHIFT (0)
|
||||
#define NV_SOR_PWR_NORMAL_STATE_DEFAULT_MASK (0x1)
|
||||
#define NV_SOR_PWR_NORMAL_STATE_PD (0)
|
||||
#define NV_SOR_PWR_NORMAL_STATE_PU (1)
|
||||
#define NV_SOR_TEST (0x16)
|
||||
#define NV_SOR_TEST_TESTMUX_SHIFT (24)
|
||||
#define NV_SOR_TEST_TESTMUX_DEFAULT_MASK (0xff << 24)
|
||||
#define NV_SOR_TEST_TESTMUX_AVSS (0 << 24)
|
||||
#define NV_SOR_TEST_TESTMUX_CLOCKIN (2 << 24)
|
||||
#define NV_SOR_TEST_TESTMUX_PLL_VOL (4 << 24)
|
||||
#define NV_SOR_TEST_TESTMUX_SLOWCLKINT (8 << 24)
|
||||
#define NV_SOR_TEST_TESTMUX_AVDD (16 << 24)
|
||||
#define NV_SOR_TEST_TESTMUX_VDDREG (32 << 24)
|
||||
#define NV_SOR_TEST_TESTMUX_REGREF_VDDREG (64 << 24)
|
||||
#define NV_SOR_TEST_TESTMUX_REGREF_AVDD (128 << 24)
|
||||
#define NV_SOR_TEST_CRC_SHIFT (23)
|
||||
#define NV_SOR_TEST_CRC_PRE_SERIALIZE (0 << 23)
|
||||
#define NV_SOR_TEST_CRC_POST_DESERIALIZE (1 << 23)
|
||||
#define NV_SOR_TEST_TPAT_SHIFT (20)
|
||||
#define NV_SOR_TEST_TPAT_DEFAULT_MASK (0x7 << 20)
|
||||
#define NV_SOR_TEST_TPAT_LO (0 << 20)
|
||||
#define NV_SOR_TEST_TPAT_TDAT (1 << 20)
|
||||
#define NV_SOR_TEST_TPAT_RAMP (2 << 20)
|
||||
#define NV_SOR_TEST_TPAT_WALK (3 << 20)
|
||||
#define NV_SOR_TEST_TPAT_MAXSTEP (4 << 20)
|
||||
#define NV_SOR_TEST_TPAT_MINSTEP (5 << 20)
|
||||
#define NV_SOR_TEST_DSRC_SHIFT (16)
|
||||
#define NV_SOR_TEST_DSRC_DEFAULT_MASK (0x3 << 16)
|
||||
#define NV_SOR_TEST_DSRC_NORMAL (0 << 16)
|
||||
#define NV_SOR_TEST_DSRC_DEBUG (1 << 16)
|
||||
#define NV_SOR_TEST_DSRC_TGEN (2 << 16)
|
||||
#define NV_SOR_TEST_HEAD_NUMBER_SHIFT (12)
|
||||
#define NV_SOR_TEST_HEAD_NUMBER_DEFAULT_MASK (0x3 << 12)
|
||||
#define NV_SOR_TEST_HEAD_NUMBER_NONE (0 << 12)
|
||||
#define NV_SOR_TEST_HEAD_NUMBER_HEAD0 (1 << 12)
|
||||
#define NV_SOR_TEST_HEAD_NUMBER_HEAD1 (2 << 12)
|
||||
#define NV_SOR_TEST_ATTACHED_SHIFT (10)
|
||||
#define NV_SOR_TEST_ATTACHED_DEFAULT_MASK (0x1 << 10)
|
||||
#define NV_SOR_TEST_ATTACHED_FALSE (0 << 10)
|
||||
#define NV_SOR_TEST_ATTACHED_TRUE (1 << 10)
|
||||
#define NV_SOR_TEST_ACT_HEAD_OPMODE_SHIFT (8)
|
||||
#define NV_SOR_TEST_ACT_HEAD_OPMODE_DEFAULT_MASK (0x3 << 8)
|
||||
#define NV_SOR_TEST_ACT_HEAD_OPMODE_SLEEP (0 << 8)
|
||||
#define NV_SOR_TEST_ACT_HEAD_OPMODE_SNOOZE (1 << 8)
|
||||
#define NV_SOR_TEST_ACT_HEAD_OPMODE_AWAKE (2 << 8)
|
||||
#define NV_SOR_TEST_INVD_SHIFT (6)
|
||||
#define NV_SOR_TEST_INVD_DISABLE (0 << 6)
|
||||
#define NV_SOR_TEST_INVD_ENABLE (1 << 6)
|
||||
#define NV_SOR_TEST_TEST_ENABLE_SHIFT (1)
|
||||
#define NV_SOR_TEST_TEST_ENABLE_DISABLE (0 << 1)
|
||||
#define NV_SOR_TEST_TEST_ENABLE_ENABLE (1 << 1)
|
||||
#define NV_SOR_PLL0 (0x17)
|
||||
#define NV_SOR_PLL0_ICHPMP_SHFIT (24)
|
||||
#define NV_SOR_PLL0_ICHPMP_DEFAULT_MASK (0xf << 24)
|
||||
#define NV_SOR_PLL0_VCOCAP_SHIFT (8)
|
||||
#define NV_SOR_PLL0_VCOCAP_DEFAULT_MASK (0xf << 8)
|
||||
#define NV_SOR_PLL0_PLLREG_LEVEL_SHIFT (6)
|
||||
#define NV_SOR_PLL0_PLLREG_LEVEL_DEFAULT_MASK (0x3 << 6)
|
||||
#define NV_SOR_PLL0_PLLREG_LEVEL_V25 (0 << 6)
|
||||
#define NV_SOR_PLL0_PLLREG_LEVEL_V15 (1 << 6)
|
||||
#define NV_SOR_PLL0_PLLREG_LEVEL_V35 (2 << 6)
|
||||
#define NV_SOR_PLL0_PLLREG_LEVEL_V45 (3 << 6)
|
||||
#define NV_SOR_PLL0_PULLDOWN_SHIFT (5)
|
||||
#define NV_SOR_PLL0_PULLDOWN_DEFAULT_MASK (0x1 << 5)
|
||||
#define NV_SOR_PLL0_PULLDOWN_DISABLE (0 << 5)
|
||||
#define NV_SOR_PLL0_PULLDOWN_ENABLE (1 << 5)
|
||||
#define NV_SOR_PLL0_RESISTORSEL_SHIFT (4)
|
||||
#define NV_SOR_PLL0_RESISTORSEL_DEFAULT_MASK (0x1 << 4)
|
||||
#define NV_SOR_PLL0_RESISTORSEL_INT (0 << 4)
|
||||
#define NV_SOR_PLL0_RESISTORSEL_EXT (1 << 4)
|
||||
#define NV_SOR_PLL0_VCOPD_SHIFT (2)
|
||||
#define NV_SOR_PLL0_VCOPD_MASK (1 << 2)
|
||||
#define NV_SOR_PLL0_VCOPD_RESCIND (0 << 2)
|
||||
#define NV_SOR_PLL0_VCOPD_ASSERT (1 << 2)
|
||||
#define NV_SOR_PLL0_PWR_SHIFT (0)
|
||||
#define NV_SOR_PLL0_PWR_MASK (1)
|
||||
#define NV_SOR_PLL0_PWR_ON (0)
|
||||
#define NV_SOR_PLL0_PWR_OFF (1)
|
||||
#define NV_SOR_PLL1_TMDS_TERM_SHIFT (8)
|
||||
#define NV_SOR_PLL1_TMDS_TERM_DISABLE (0 << 8)
|
||||
#define NV_SOR_PLL1_TMDS_TERM_ENABLE (1 << 8)
|
||||
#define NV_SOR_PLL1 (0x18)
|
||||
#define NV_SOR_PLL1_TERM_COMPOUT_SHIFT (15)
|
||||
#define NV_SOR_PLL1_TERM_COMPOUT_LOW (0 << 15)
|
||||
#define NV_SOR_PLL1_TERM_COMPOUT_HIGH (1 << 15)
|
||||
#define NV_SOR_PLL2 (0x19)
|
||||
#define NV_SOR_PLL2_DCIR_PLL_RESET_SHIFT (0)
|
||||
#define NV_SOR_PLL2_DCIR_PLL_RESET_OVERRIDE (0 << 0)
|
||||
#define NV_SOR_PLL2_DCIR_PLL_RESET_ALLOW (1 << 0)
|
||||
#define NV_SOR_PLL2_AUX1_SHIFT (17)
|
||||
#define NV_SOR_PLL2_AUX1_SEQ_MASK (1 << 17)
|
||||
#define NV_SOR_PLL2_AUX1_SEQ_PLLCAPPD_ALLOW (0 << 17)
|
||||
#define NV_SOR_PLL2_AUX1_SEQ_PLLCAPPD_OVERRIDE (1 << 17)
|
||||
#define NV_SOR_PLL2_AUX2_SHIFT (18)
|
||||
#define NV_SOR_PLL2_AUX2_MASK (1 << 18)
|
||||
#define NV_SOR_PLL2_AUX2_OVERRIDE_POWERDOWN (0 << 18)
|
||||
#define NV_SOR_PLL2_AUX2_ALLOW_POWERDOWN (1 << 18)
|
||||
#define NV_SOR_PLL2_AUX6_SHIFT (22)
|
||||
#define NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_MASK (1 << 22)
|
||||
#define NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE (0 << 22)
|
||||
#define NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_ENABLE (1 << 22)
|
||||
#define NV_SOR_PLL2_AUX7_SHIFT (23)
|
||||
#define NV_SOR_PLL2_AUX7_PORT_POWERDOWN_MASK (1 << 23)
|
||||
#define NV_SOR_PLL2_AUX7_PORT_POWERDOWN_DISABLE (0 << 23)
|
||||
#define NV_SOR_PLL2_AUX7_PORT_POWERDOWN_ENABLE (1 << 23)
|
||||
#define NV_SOR_PLL2_AUX8_SHIFT (24)
|
||||
#define NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK (1 << 24)
|
||||
#define NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE (0 << 24)
|
||||
#define NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_ENABLE (1 << 24)
|
||||
#define NV_SOR_PLL2_AUX9_SHIFT (25)
|
||||
#define NV_SOR_PLL2_AUX9_LVDSEN_ALLOW (0 << 25)
|
||||
#define NV_SOR_PLL2_AUX9_LVDSEN_OVERRIDE (1 << 25)
|
||||
#define NV_SOR_PLL3 (0x1a)
|
||||
#define NV_SOR_PLL3_PLLVDD_MODE_SHIFT (13)
|
||||
#define NV_SOR_PLL3_PLLVDD_MODE_MASK (1 << 13)
|
||||
#define NV_SOR_PLL3_PLLVDD_MODE_V1_8 (0 << 13)
|
||||
#define NV_SOR_PLL3_PLLVDD_MODE_V3_3 (1 << 13)
|
||||
#define NV_SOR_CSTM (0x1b)
|
||||
#define NV_SOR_CSTM_ROTDAT_SHIFT (28)
|
||||
#define NV_SOR_CSTM_ROTDAT_DEFAULT_MASK (0x7 << 28)
|
||||
#define NV_SOR_CSTM_ROTCLK_SHIFT (24)
|
||||
#define NV_SOR_CSTM_ROTCLK_DEFAULT_MASK (0xf << 24)
|
||||
#define NV_SOR_CSTM_LVDS_EN_SHIFT (16)
|
||||
#define NV_SOR_CSTM_LVDS_EN_DISABLE (0 << 16)
|
||||
#define NV_SOR_CSTM_LVDS_EN_ENABLE (1 << 16)
|
||||
#define NV_SOR_CSTM_LINKACTB_SHIFT (15)
|
||||
#define NV_SOR_CSTM_LINKACTB_DISABLE (0 << 15)
|
||||
#define NV_SOR_CSTM_LINKACTB_ENABLE (1 << 15)
|
||||
#define NV_SOR_CSTM_LINKACTA_SHIFT (14)
|
||||
#define NV_SOR_CSTM_LINKACTA_DISABLE (0 << 14)
|
||||
#define NV_SOR_CSTM_LINKACTA_ENABLE (1 << 14)
|
||||
#define NV_SOR_LVDS (0x1c)
|
||||
#define NV_SOR_LVDS_ROTDAT_SHIFT (28)
|
||||
#define NV_SOR_LVDS_ROTDAT_DEFAULT_MASK (0x7 << 28)
|
||||
#define NV_SOR_LVDS_ROTDAT_RST (0 << 28)
|
||||
#define NV_SOR_LVDS_ROTCLK_SHIFT (24)
|
||||
#define NV_SOR_LVDS_ROTCLK_DEFAULT_MASK (0xf << 24)
|
||||
#define NV_SOR_LVDS_ROTCLK_RST (0 << 24)
|
||||
#define NV_SOR_LVDS_PLLDIV_SHIFT (21)
|
||||
#define NV_SOR_LVDS_PLLDIV_DEFAULT_MASK (0x1 << 21)
|
||||
#define NV_SOR_LVDS_PLLDIV_BY_7 (0 << 21)
|
||||
#define NV_SOR_LVDS_BALANCED_SHIFT (19)
|
||||
#define NV_SOR_LVDS_BALANCED_DEFAULT_MASK (0x1 << 19)
|
||||
#define NV_SOR_LVDS_BALANCED_DISABLE (0 << 19)
|
||||
#define NV_SOR_LVDS_BALANCED_ENABLE (1 << 19)
|
||||
#define NV_SOR_LVDS_NEW_MODE_SHIFT (18)
|
||||
#define NV_SOR_LVDS_NEW_MODE_DEFAULT_MASK (0x1 << 18)
|
||||
#define NV_SOR_LVDS_NEW_MODE_DISABLE (0 << 18)
|
||||
#define NV_SOR_LVDS_NEW_MODE_ENABLE (1 << 18)
|
||||
#define NV_SOR_LVDS_DUP_SYNC_SHIFT (17)
|
||||
#define NV_SOR_LVDS_DUP_SYNC_DEFAULT_MASK (0x1 << 17)
|
||||
#define NV_SOR_LVDS_DUP_SYNC_DISABLE (0 << 17)
|
||||
#define NV_SOR_LVDS_DUP_SYNC_ENABLE (1 << 17)
|
||||
#define NV_SOR_LVDS_LVDS_EN_SHIFT (16)
|
||||
#define NV_SOR_LVDS_LVDS_EN_DEFAULT_MASK (0x1 << 16)
|
||||
#define NV_SOR_LVDS_LVDS_EN_ENABLE (1 << 16)
|
||||
#define NV_SOR_LVDS_LINKACTB_SHIFT (15)
|
||||
#define NV_SOR_LVDS_LINKACTB_DEFAULT_MASK (0x1 << 15)
|
||||
#define NV_SOR_LVDS_LINKACTB_DISABLE (0 << 15)
|
||||
#define NV_SOR_LVDS_LINKACTB_ENABLE (1 << 15)
|
||||
#define NV_SOR_LVDS_LINKACTA_SHIFT (14)
|
||||
#define NV_SOR_LVDS_LINKACTA_DEFAULT_MASK (0x1 << 14)
|
||||
#define NV_SOR_LVDS_LINKACTA_ENABLE (1 << 14)
|
||||
#define NV_SOR_LVDS_MODE_SHIFT (12)
|
||||
#define NV_SOR_LVDS_MODE_DEFAULT_MASK (0x3 << 12)
|
||||
#define NV_SOR_LVDS_MODE_LVDS (0 << 12)
|
||||
#define NV_SOR_LVDS_UPPER_SHIFT (11)
|
||||
#define NV_SOR_LVDS_UPPER_DEFAULT_MASK (0x1 << 11)
|
||||
#define NV_SOR_LVDS_UPPER_FALSE (0 << 11)
|
||||
#define NV_SOR_LVDS_UPPER_TRUE (1 << 11)
|
||||
#define NV_SOR_LVDS_PD_TXCB_SHIFT (9)
|
||||
#define NV_SOR_LVDS_PD_TXCB_DEFAULT_MASK (0x1 << 9)
|
||||
#define NV_SOR_LVDS_PD_TXCB_ENABLE (0 << 9)
|
||||
#define NV_SOR_LVDS_PD_TXCB_DISABLE (1 << 9)
|
||||
#define NV_SOR_LVDS_PD_TXCA_SHIFT (8)
|
||||
#define NV_SOR_LVDS_PD_TXCA_DEFAULT_MASK (0x1 << 8)
|
||||
#define NV_SOR_LVDS_PD_TXCA_ENABLE (0 << 8)
|
||||
#define NV_SOR_LVDS_PD_TXDB_3_SHIFT (7)
|
||||
#define NV_SOR_LVDS_PD_TXDB_3_DEFAULT_MASK (0x1 << 7)
|
||||
#define NV_SOR_LVDS_PD_TXDB_3_ENABLE (0 << 7)
|
||||
#define NV_SOR_LVDS_PD_TXDB_3_DISABLE (1 << 7)
|
||||
#define NV_SOR_LVDS_PD_TXDB_2_SHIFT (6)
|
||||
#define NV_SOR_LVDS_PD_TXDB_2_DEFAULT_MASK (0x1 << 6)
|
||||
#define NV_SOR_LVDS_PD_TXDB_2_ENABLE (0 << 6)
|
||||
#define NV_SOR_LVDS_PD_TXDB_2_DISABLE (1 << 6)
|
||||
#define NV_SOR_LVDS_PD_TXDB_1_SHIFT (5)
|
||||
#define NV_SOR_LVDS_PD_TXDB_1_DEFAULT_MASK (0x1 << 5)
|
||||
#define NV_SOR_LVDS_PD_TXDB_1_ENABLE (0 << 5)
|
||||
#define NV_SOR_LVDS_PD_TXDB_1_DISABLE (1 << 5)
|
||||
#define NV_SOR_LVDS_PD_TXDB_0_SHIFT (4)
|
||||
#define NV_SOR_LVDS_PD_TXDB_0_DEFAULT_MASK (0x1 << 4)
|
||||
#define NV_SOR_LVDS_PD_TXDB_0_ENABLE (0 << 4)
|
||||
#define NV_SOR_LVDS_PD_TXDB_0_DISABLE (1 << 4)
|
||||
#define NV_SOR_LVDS_PD_TXDA_3_SHIFT (3)
|
||||
#define NV_SOR_LVDS_PD_TXDA_3_DEFAULT_MASK (0x1 << 3)
|
||||
#define NV_SOR_LVDS_PD_TXDA_3_ENABLE (0 << 3)
|
||||
#define NV_SOR_LVDS_PD_TXDA_3_DISABLE (1 << 3)
|
||||
#define NV_SOR_LVDS_PD_TXDA_2_SHIFT (2)
|
||||
#define NV_SOR_LVDS_PD_TXDA_2_DEFAULT_MASK (0x1 << 2)
|
||||
#define NV_SOR_LVDS_PD_TXDA_2_ENABLE (0 << 2)
|
||||
#define NV_SOR_LVDS_PD_TXDA_1_SHIFT (1)
|
||||
#define NV_SOR_LVDS_PD_TXDA_1_DEFAULT_MASK (0x1 << 1)
|
||||
#define NV_SOR_LVDS_PD_TXDA_1_ENABLE (0 << 1)
|
||||
#define NV_SOR_LVDS_PD_TXDA_0_SHIFT (0)
|
||||
#define NV_SOR_LVDS_PD_TXDA_0_DEFAULT_MASK (0x1)
|
||||
#define NV_SOR_LVDS_PD_TXDA_0_ENABLE (0)
|
||||
#define NV_SOR_CRCA (0x1d)
|
||||
#define NV_SOR_CRCA_VALID_FALSE (0)
|
||||
#define NV_SOR_CRCA_VALID_TRUE (1)
|
||||
#define NV_SOR_CRCA_VALID_RST (1)
|
||||
#define NV_SOR_CRCB (0x1e)
|
||||
#define NV_SOR_CRCB_CRC_DEFAULT_MASK (0xffffffff)
|
||||
#define NV_SOR_SEQ_CTL (0x20)
|
||||
#define NV_SOR_SEQ_CTL_SWITCH_SHIFT (30)
|
||||
#define NV_SOR_SEQ_CTL_SWITCH_MASK (0x1 << 30)
|
||||
#define NV_SOR_SEQ_CTL_SWITCH_WAIT (0 << 30)
|
||||
#define NV_SOR_SEQ_CTL_SWITCH_FORCE (1 << 30)
|
||||
#define NV_SOR_SEQ_CTL_STATUS_SHIFT (28)
|
||||
#define NV_SOR_SEQ_CTL_STATUS_MASK (0x1 << 28)
|
||||
#define NV_SOR_SEQ_CTL_STATUS_STOPPED (0 << 28)
|
||||
#define NV_SOR_SEQ_CTL_STATUS_RUNNING (1 << 28)
|
||||
#define NV_SOR_SEQ_CTL_PC_SHIFT (16)
|
||||
#define NV_SOR_SEQ_CTL_PC_MASK (0xf << 16)
|
||||
#define NV_SOR_SEQ_CTL_PD_PC_ALT_SHIFT (12)
|
||||
#define NV_SOR_SEQ_CTL_PD_PC_ALT_MASK (0xf << 12)
|
||||
#define NV_SOR_SEQ_CTL_PD_PC_SHIFT (8)
|
||||
#define NV_SOR_SEQ_CTL_PD_PC_MASK (0xf << 8)
|
||||
#define NV_SOR_SEQ_CTL_PU_PC_ALT_SHIFT (4)
|
||||
#define NV_SOR_SEQ_CTL_PU_PC_ALT_MASK (0xf << 4)
|
||||
#define NV_SOR_SEQ_CTL_PU_PC_SHIFT (0)
|
||||
#define NV_SOR_SEQ_CTL_PU_PC_MASK (0xf)
|
||||
#define NV_SOR_LANE_SEQ_CTL (0x21)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SETTING_NEW_SHIFT (31)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SETTING_MASK (1 << 31)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SETTING_NEW_DONE (0 << 31)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SETTING_NEW_PENDING (1 << 31)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SETTING_NEW_TRIGGER (1 << 31)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SEQ_STATE_SHIFT (28)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SEQ_STATE_IDLE (0 << 28)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SEQ_STATE_BUSY (1 << 28)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SEQUENCE_SHIFT (20)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SEQUENCE_UP (0 << 20)
|
||||
#define NV_SOR_LANE_SEQ_CTL_SEQUENCE_DOWN (1 << 20)
|
||||
#define NV_SOR_LANE_SEQ_CTL_NEW_POWER_STATE_SHIFT (16)
|
||||
#define NV_SOR_LANE_SEQ_CTL_NEW_POWER_STATE_PU (0 << 16)
|
||||
#define NV_SOR_LANE_SEQ_CTL_NEW_POWER_STATE_PD (1 << 16)
|
||||
#define NV_SOR_LANE_SEQ_CTL_DELAY_SHIFT (12)
|
||||
#define NV_SOR_LANE_SEQ_CTL_DELAY_DEFAULT_MASK (0xf << 12)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE9_STATE_SHIFT (9)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE9_STATE_POWERUP (0 << 9)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE9_STATE_POWERDOWN (1 << 9)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE8_STATE_SHIFT (8)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE8_STATE_POWERUP (0 << 8)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE8_STATE_POWERDOWN (1 << 8)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE7_STATE_SHIFT (7)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE7_STATE_POWERUP (0 << 7)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE7_STATE_POWERDOWN (1 << 7)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE6_STATE_SHIFT (6)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE6_STATE_POWERUP (0 << 6)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE6_STATE_POWERDOWN (1 << 6)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE5_STATE_SHIFT (5)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE5_STATE_POWERUP (0 << 5)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE5_STATE_POWERDOWN (1 << 5)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE4_STATE_SHIFT (4)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE4_STATE_POWERUP (0 << 4)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE4_STATE_POWERDOWN (1 << 4)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE3_STATE_SHIFT (3)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE3_STATE_POWERUP (0 << 3)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE3_STATE_POWERDOWN (1 << 3)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE2_STATE_SHIFT (2)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE2_STATE_POWERUP (0 << 2)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE2_STATE_POWERDOWN (1 << 2)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE1_STATE_SHIFT (1)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE1_STATE_POWERUP (0 << 1)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE1_STATE_POWERDOWN (1 << 1)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE0_STATE_SHIFT (0)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE0_STATE_POWERUP (0)
|
||||
#define NV_SOR_LANE_SEQ_CTL_LANE0_STATE_POWERDOWN (1)
|
||||
#define NV_SOR_SEQ_INST(i) (0x22 + i)
|
||||
#define NV_SOR_SEQ_INST_PLL_PULLDOWN_SHIFT (31)
|
||||
#define NV_SOR_SEQ_INST_PLL_PULLDOWN_DISABLE (0 << 31)
|
||||
#define NV_SOR_SEQ_INST_PLL_PULLDOWN_ENABLE (1 << 31)
|
||||
#define NV_SOR_SEQ_INST_POWERDOWN_MACRO_SHIFT (30)
|
||||
#define NV_SOR_SEQ_INST_POWERDOWN_MACRO_NORMAL (0 << 30)
|
||||
#define NV_SOR_SEQ_INST_POWERDOWN_MACRO_POWERDOWN (1 << 30)
|
||||
#define NV_SOR_SEQ_INST_ASSERT_PLL_RESET_SHIFT (29)
|
||||
#define NV_SOR_SEQ_INST_ASSERT_PLL_RESET_NORMAL (0 << 29)
|
||||
#define NV_SOR_SEQ_INST_ASSERT_PLL_RESET_RST (1 << 29)
|
||||
#define NV_SOR_SEQ_INST_BLANK_V_SHIFT (28)
|
||||
#define NV_SOR_SEQ_INST_BLANK_V_NORMAL (0 << 28)
|
||||
#define NV_SOR_SEQ_INST_BLANK_V_INACTIVE (1 << 28)
|
||||
#define NV_SOR_SEQ_INST_BLANK_H_SHIFT (27)
|
||||
#define NV_SOR_SEQ_INST_BLANK_H_NORMAL (0 << 27)
|
||||
#define NV_SOR_SEQ_INST_BLANK_H_INACTIVE (1 << 27)
|
||||
#define NV_SOR_SEQ_INST_BLANK_DE_SHIFT (26)
|
||||
#define NV_SOR_SEQ_INST_BLANK_DE_NORMAL (0 << 26)
|
||||
#define NV_SOR_SEQ_INST_BLANK_DE_INACTIVE (1 << 26)
|
||||
#define NV_SOR_SEQ_INST_BLACK_DATA_SHIFT (25)
|
||||
#define NV_SOR_SEQ_INST_BLACK_DATA_NORMAL (0 << 25)
|
||||
#define NV_SOR_SEQ_INST_BLACK_DATA_BLACK (1 << 25)
|
||||
#define NV_SOR_SEQ_INST_TRISTATE_IOS_SHIFT (24)
|
||||
#define NV_SOR_SEQ_INST_TRISTATE_IOS_ENABLE_PINS (0 << 24)
|
||||
#define NV_SOR_SEQ_INST_TRISTATE_IOS_TRISTATE (1 << 24)
|
||||
#define NV_SOR_SEQ_INST_DRIVE_PWM_OUT_LO_SHIFT (23)
|
||||
#define NV_SOR_SEQ_INST_DRIVE_PWM_OUT_LO_FALSE (0 << 23)
|
||||
#define NV_SOR_SEQ_INST_DRIVE_PWM_OUT_LO_TRUE (1 << 23)
|
||||
#define NV_SOR_SEQ_INST_PIN_B_SHIFT (22)
|
||||
#define NV_SOR_SEQ_INST_PIN_B_LOW (0 << 22)
|
||||
#define NV_SOR_SEQ_INST_PIN_B_HIGH (1 << 22)
|
||||
#define NV_SOR_SEQ_INST_PIN_A_SHIFT (21)
|
||||
#define NV_SOR_SEQ_INST_PIN_A_LOW (0 << 21)
|
||||
#define NV_SOR_SEQ_INST_PIN_A_HIGH (1 << 21)
|
||||
#define NV_SOR_SEQ_INST_SEQUENCE_SHIFT (19)
|
||||
#define NV_SOR_SEQ_INST_SEQUENCE_UP (0 << 19)
|
||||
#define NV_SOR_SEQ_INST_SEQUENCE_DOWN (1 << 19)
|
||||
#define NV_SOR_SEQ_INST_LANE_SEQ_SHIFT (18)
|
||||
#define NV_SOR_SEQ_INST_LANE_SEQ_STOP (0 << 18)
|
||||
#define NV_SOR_SEQ_INST_LANE_SEQ_RUN (1 << 18)
|
||||
#define NV_SOR_SEQ_INST_PDPORT_SHIFT (17)
|
||||
#define NV_SOR_SEQ_INST_PDPORT_NO (0 << 17)
|
||||
#define NV_SOR_SEQ_INST_PDPORT_YES (1 << 17)
|
||||
#define NV_SOR_SEQ_INST_PDPLL_SHIFT (16)
|
||||
#define NV_SOR_SEQ_INST_PDPLL_NO (0 << 16)
|
||||
#define NV_SOR_SEQ_INST_PDPLL_YES (1 << 16)
|
||||
#define NV_SOR_SEQ_INST_HALT_SHIFT (15)
|
||||
#define NV_SOR_SEQ_INST_HALT_FALSE (0 << 15)
|
||||
#define NV_SOR_SEQ_INST_HALT_TRUE (1 << 15)
|
||||
#define NV_SOR_SEQ_INST_WAIT_UNITS_SHIFT (12)
|
||||
#define NV_SOR_SEQ_INST_WAIT_UNITS_DEFAULT_MASK (0x3 << 12)
|
||||
#define NV_SOR_SEQ_INST_WAIT_UNITS_US (0 << 12)
|
||||
#define NV_SOR_SEQ_INST_WAIT_UNITS_MS (1 << 12)
|
||||
#define NV_SOR_SEQ_INST_WAIT_UNITS_VSYNC (2 << 12)
|
||||
#define NV_SOR_SEQ_INST_WAIT_TIME_SHIFT (0)
|
||||
#define NV_SOR_SEQ_INST_WAIT_TIME_DEFAULT_MASK (0x3ff)
|
||||
#define NV_SOR_PWM_DIV (0x32)
|
||||
#define NV_SOR_PWM_DIV_DIVIDE_DEFAULT_MASK (0xffffff)
|
||||
#define NV_SOR_PWM_CTL (0x33)
|
||||
#define NV_SOR_PWM_CTL_SETTING_NEW_SHIFT (31)
|
||||
#define NV_SOR_PWM_CTL_SETTING_NEW_DONE (0 << 31)
|
||||
#define NV_SOR_PWM_CTL_SETTING_NEW_PENDING (1 << 31)
|
||||
#define NV_SOR_PWM_CTL_SETTING_NEW_TRIGGER (1 << 31)
|
||||
#define NV_SOR_PWM_CTL_CLKSEL_SHIFT (30)
|
||||
#define NV_SOR_PWM_CTL_CLKSEL_PCLK (0 << 30)
|
||||
#define NV_SOR_PWM_CTL_CLKSEL_XTAL (1 << 30)
|
||||
#define NV_SOR_PWM_CTL_DUTY_CYCLE_SHIFT (0)
|
||||
#define NV_SOR_PWM_CTL_DUTY_CYCLE_MASK (0xffffff)
|
||||
#define NV_SOR_MSCHECK (0x49)
|
||||
#define NV_SOR_MSCHECK_CTL_SHIFT (31)
|
||||
#define NV_SOR_MSCHECK_CTL_CLEAR (0 << 31)
|
||||
#define NV_SOR_MSCHECK_CTL_RUN (1 << 31)
|
||||
#define NV_SOR_XBAR_CTRL (0x4a)
|
||||
#define NV_SOR_DP_LINKCTL(i) (0x4c + (i))
|
||||
#define NV_SOR_DP_LINKCTL_FORCE_IDLEPTTRN_SHIFT (31)
|
||||
#define NV_SOR_DP_LINKCTL_FORCE_IDLEPTTRN_NO (0 << 31)
|
||||
#define NV_SOR_DP_LINKCTL_FORCE_IDLEPTTRN_YES (1 << 31)
|
||||
#define NV_SOR_DP_LINKCTL_COMPLIANCEPTTRN_SHIFT (28)
|
||||
#define NV_SOR_DP_LINKCTL_COMPLIANCEPTTRN_NOPATTERN (0 << 28)
|
||||
#define NV_SOR_DP_LINKCTL_COMPLIANCEPTTRN_COLORSQARE (1 << 28)
|
||||
#define NV_SOR_DP_LINKCTL_LANECOUNT_SHIFT (16)
|
||||
#define NV_SOR_DP_LINKCTL_LANECOUNT_MASK (0x1f << 16)
|
||||
#define NV_SOR_DP_LINKCTL_LANECOUNT_ZERO (0 << 16)
|
||||
#define NV_SOR_DP_LINKCTL_LANECOUNT_ONE (1 << 16)
|
||||
#define NV_SOR_DP_LINKCTL_LANECOUNT_TWO (3 << 16)
|
||||
#define NV_SOR_DP_LINKCTL_LANECOUNT_FOUR (15 << 16)
|
||||
#define NV_SOR_DP_LINKCTL_ENHANCEDFRAME_SHIFT (14)
|
||||
#define NV_SOR_DP_LINKCTL_ENHANCEDFRAME_DISABLE (0 << 14)
|
||||
#define NV_SOR_DP_LINKCTL_ENHANCEDFRAME_ENABLE (1 << 14)
|
||||
#define NV_SOR_DP_LINKCTL_SYNCMODE_SHIFT (10)
|
||||
#define NV_SOR_DP_LINKCTL_SYNCMODE_DISABLE (0 << 10)
|
||||
#define NV_SOR_DP_LINKCTL_SYNCMODE_ENABLE (1 << 10)
|
||||
#define NV_SOR_DP_LINKCTL_TUSIZE_SHIFT (2)
|
||||
#define NV_SOR_DP_LINKCTL_TUSIZE_MASK (0x7f << 2)
|
||||
#define NV_SOR_DP_LINKCTL_ENABLE_SHIFT (0)
|
||||
#define NV_SOR_DP_LINKCTL_ENABLE_NO (0)
|
||||
#define NV_SOR_DP_LINKCTL_ENABLE_YES (1)
|
||||
#define NV_SOR_DC(i) (0x4e + (i))
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_SHIFT (24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_MASK (0xff << 24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_P0_LEVEL0 (17 << 24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_P1_LEVEL0 (21 << 24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_P2_LEVEL0 (26 << 24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_P3_LEVEL0 (34 << 24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_P0_LEVEL1 (26 << 24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_P1_LEVEL1 (32 << 24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_P2_LEVEL1 (39 << 24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_P0_LEVEL2 (34 << 24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_P1_LEVEL2 (43 << 24)
|
||||
#define NV_SOR_DC_LANE3_DP_LANE3_P0_LEVEL3 (51 << 24)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_SHIFT (16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_MASK (0xff << 16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_P0_LEVEL0 (17 << 16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_P1_LEVEL0 (21 << 16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_P2_LEVEL0 (26 << 16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_P3_LEVEL0 (34 << 16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_P0_LEVEL1 (26 << 16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_P1_LEVEL1 (32 << 16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_P2_LEVEL1 (39 << 16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_P0_LEVEL2 (34 << 16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_P1_LEVEL2 (43 << 16)
|
||||
#define NV_SOR_DC_LANE2_DP_LANE0_P0_LEVEL3 (51 << 16)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_SHIFT (8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_MASK (0xff << 8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_P0_LEVEL0 (17 << 8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_P1_LEVEL0 (21 << 8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_P2_LEVEL0 (26 << 8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_P3_LEVEL0 (34 << 8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_P0_LEVEL1 (26 << 8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_P1_LEVEL1 (32 << 8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_P2_LEVEL1 (39 << 8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_P0_LEVEL2 (34 << 8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_P1_LEVEL2 (43 << 8)
|
||||
#define NV_SOR_DC_LANE1_DP_LANE1_P0_LEVEL3 (51 << 8)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_SHIFT (0)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_MASK (0xff)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_P0_LEVEL0 (17)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_P1_LEVEL0 (21)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_P2_LEVEL0 (26)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_P3_LEVEL0 (34)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_P0_LEVEL1 (26)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_P1_LEVEL1 (32)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_P2_LEVEL1 (39)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_P0_LEVEL2 (34)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_P1_LEVEL2 (43)
|
||||
#define NV_SOR_DC_LANE0_DP_LANE2_P0_LEVEL3 (51)
|
||||
#define NV_SOR_LANE_DRIVE_CURRENT(i) (0x4e + (i))
|
||||
#define NV_SOR_PR(i) (0x52 + (i))
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_SHIFT (24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_MASK (0xff << 24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_D0_LEVEL0 (0 << 24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_D1_LEVEL0 (0 << 24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_D2_LEVEL0 (0 << 24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_D3_LEVEL0 (0 << 24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_D0_LEVEL1 (4 << 24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_D1_LEVEL1 (6 << 24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_D2_LEVEL1 (17 << 24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_D0_LEVEL2 (8 << 24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_D1_LEVEL2 (13 << 24)
|
||||
#define NV_SOR_PR_LANE3_DP_LANE3_D0_LEVEL3 (17 << 24)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_SHIFT (16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_MASK (0xff << 16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_D0_LEVEL0 (0 << 16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_D1_LEVEL0 (0 << 16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_D2_LEVEL0 (0 << 16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_D3_LEVEL0 (0 << 16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_D0_LEVEL1 (4 << 16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_D1_LEVEL1 (6 << 16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_D2_LEVEL1 (17 << 16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_D0_LEVEL2 (8 << 16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_D1_LEVEL2 (13 << 16)
|
||||
#define NV_SOR_PR_LANE2_DP_LANE0_D0_LEVEL3 (17 << 16)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_SHIFT (8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_MASK (0xff >> 8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_D0_LEVEL0 (0 >> 8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_D1_LEVEL0 (0 >> 8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_D2_LEVEL0 (0 >> 8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_D3_LEVEL0 (0 >> 8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_D0_LEVEL1 (4 >> 8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_D1_LEVEL1 (6 >> 8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_D2_LEVEL1 (17 >> 8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_D0_LEVEL2 (8 >> 8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_D1_LEVEL2 (13 >> 8)
|
||||
#define NV_SOR_PR_LANE1_DP_LANE1_D0_LEVEL3 (17 >> 8)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_SHIFT (0)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_MASK (0xff)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_D0_LEVEL0 (0)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_D1_LEVEL0 (0)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_D2_LEVEL0 (0)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_D3_LEVEL0 (0)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_D0_LEVEL1 (4)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_D1_LEVEL1 (6)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_D2_LEVEL1 (17)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_D0_LEVEL2 (8)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_D1_LEVEL2 (13)
|
||||
#define NV_SOR_PR_LANE0_DP_LANE2_D0_LEVEL3 (17)
|
||||
#define NV_SOR_LANE4_PREEMPHASIS(i) (0x54 + (i))
|
||||
#define NV_SOR_POSTCURSOR(i) (0x56 + (i))
|
||||
#define NV_SOR_DP_CONFIG(i) (0x58 + (i))
|
||||
#define NV_SOR_DP_CONFIG_RD_RESET_VAL_SHIFT (31)
|
||||
#define NV_SOR_DP_CONFIG_RD_RESET_VAL_POSITIVE (0 << 31)
|
||||
#define NV_SOR_DP_CONFIG_RD_RESET_VAL_NEGATIVE (1 << 31)
|
||||
#define NV_SOR_DP_CONFIG_IDLE_BEFORE_ATTACH_SHIFT (28)
|
||||
#define NV_SOR_DP_CONFIG_IDLE_BEFORE_ATTACH_DISABLE (0 << 28)
|
||||
#define NV_SOR_DP_CONFIG_IDLE_BEFORE_ATTACH_ENABLE (1 << 28)
|
||||
#define NV_SOR_DP_CONFIG_ACTIVESYM_CNTL_SHIFT (26)
|
||||
#define NV_SOR_DP_CONFIG_ACTIVESYM_CNTL_DISABLE (0 << 26)
|
||||
#define NV_SOR_DP_CONFIG_ACTIVESYM_CNTL_ENABLE (1 << 26)
|
||||
#define NV_SOR_DP_CONFIG_ACTIVESYM_POLARITY_SHIFT (24)
|
||||
#define NV_SOR_DP_CONFIG_ACTIVESYM_POLARITY_NEGATIVE (0 << 24)
|
||||
#define NV_SOR_DP_CONFIG_ACTIVESYM_POLARITY_POSITIVE (1 << 24)
|
||||
#define NV_SOR_DP_CONFIG_ACTIVESYM_FRAC_SHIFT (16)
|
||||
#define NV_SOR_DP_CONFIG_ACTIVESYM_FRAC_MASK (0xf << 16)
|
||||
#define NV_SOR_DP_CONFIG_ACTIVESYM_COUNT_SHIFT (8)
|
||||
#define NV_SOR_DP_CONFIG_ACTIVESYM_COUNT_MASK (0x7f << 8)
|
||||
#define NV_SOR_DP_CONFIG_WATERMARK_SHIFT (0)
|
||||
#define NV_SOR_DP_CONFIG_WATERMARK_MASK (0x3f)
|
||||
#define NV_SOR_DP_MN(i) (0x5a + i)
|
||||
#define NV_SOR_DP_MN_M_MOD_SHIFT (30)
|
||||
#define NV_SOR_DP_MN_M_MOD_DEFAULT_MASK (0x3 << 30)
|
||||
#define NV_SOR_DP_MN_M_MOD_NONE (0 << 30)
|
||||
#define NV_SOR_DP_MN_M_MOD_INC (1 << 30)
|
||||
#define NV_SOR_DP_MN_M_MOD_DEC (2 << 30)
|
||||
#define NV_SOR_DP_MN_M_DELTA_SHIFT (24)
|
||||
#define NV_SOR_DP_MN_M_DELTA_DEFAULT_MASK (0xf << 24)
|
||||
#define NV_SOR_DP_MN_N_VAL_SHIFT (0)
|
||||
#define NV_SOR_DP_MN_N_VAL_DEFAULT_MASK (0xffffff)
|
||||
#define NV_SOR_DP_PADCTL(i) (0x5c + (i))
|
||||
#define NV_SOR_DP_PADCTL_SPARE_SHIFT (25)
|
||||
#define NV_SOR_DP_PADCTL_SPARE_DEFAULT_MASK (0x7f << 25)
|
||||
#define NV_SOR_DP_PADCTL_VCO_2X_SHIFT (24)
|
||||
#define NV_SOR_DP_PADCTL_VCO_2X_DISABLE (0 << 24)
|
||||
#define NV_SOR_DP_PADCTL_VCO_2X_ENABLE (1 << 24)
|
||||
#define NV_SOR_DP_PADCTL_PAD_CAL_PD_SHIFT (23)
|
||||
#define NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERUP (0 << 23)
|
||||
#define NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERDOWN (1 << 23)
|
||||
#define NV_SOR_DP_PADCTL_TX_PU_SHIFT (22)
|
||||
#define NV_SOR_DP_PADCTL_TX_PU_DISABLE (0 << 22)
|
||||
#define NV_SOR_DP_PADCTL_TX_PU_ENABLE (1 << 22)
|
||||
#define NV_SOR_DP_PADCTL_TX_PU_MASK (1 << 22)
|
||||
#define NV_SOR_DP_PADCTL_REG_CTRL_SHIFT (20)
|
||||
#define NV_SOR_DP_PADCTL_REG_CTRL_DEFAULT_MASK (0x3 << 20)
|
||||
#define NV_SOR_DP_PADCTL_VCMMODE_SHIFT (16)
|
||||
#define NV_SOR_DP_PADCTL_VCMMODE_DEFAULT_MASK (0xf << 16)
|
||||
#define NV_SOR_DP_PADCTL_VCMMODE_TRISTATE (0 << 16)
|
||||
#define NV_SOR_DP_PADCTL_VCMMODE_TEST_MUX (1 << 16)
|
||||
#define NV_SOR_DP_PADCTL_VCMMODE_WEAK_PULLDOWN (2 << 16)
|
||||
#define NV_SOR_DP_PADCTL_VCMMODE_STRONG_PULLDOWN (4 << 16)
|
||||
#define NV_SOR_DP_PADCTL_TX_PU_VALUE_SHIFT (8)
|
||||
#define NV_SOR_DP_PADCTL_TX_PU_VALUE_DEFAULT_MASK (0xff << 8)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_3_DP_TXD_3_SHIFT (7)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_3_DP_TXD_3_DISABLE (0 << 7)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_3_DP_TXD_3_ENABLE (1 << 7)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_2_DP_TXD_0_SHIFT (6)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_2_DP_TXD_0_DISABLE (0 << 6)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_2_DP_TXD_0_ENABLE (1 << 6)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_1_DP_TXD_1_SHIFT (5)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_1_DP_TXD_1_DISABLE (0 << 5)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_1_DP_TXD_1_ENABLE (1 << 5)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT (4)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_DISABLE (0 << 4)
|
||||
#define NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_ENABLE (1 << 4)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_3_SHIFT (3)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_3_YES (0 << 3)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_3_NO (1 << 3)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_0_SHIFT (2)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_0_YES (0 << 2)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_0_NO (1 << 2)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_1_SHIFT (1)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_1_YES (0 << 1)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_1_NO (1 << 1)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_2_SHIFT (0)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_2_YES (0)
|
||||
#define NV_SOR_DP_PADCTL_PD_TXD_2_NO (1)
|
||||
#define NV_SOR_DP_DEBUG(i) (0x5e + i)
|
||||
#define NV_SOR_DP_SPARE(i) (0x60 + (i))
|
||||
#define NV_SOR_DP_SPARE_REG_SHIFT (3)
|
||||
#define NV_SOR_DP_SPARE_REG_DEFAULT_MASK (0x1fffffff << 3)
|
||||
#define NV_SOR_DP_SPARE_SOR_CLK_SEL_SHIFT (2)
|
||||
#define NV_SOR_DP_SPARE_SOR_CLK_SEL_DEFAULT_MASK (0x1 << 2)
|
||||
#define NV_SOR_DP_SPARE_SOR_CLK_SEL_SAFE_SORCLK (0 << 2)
|
||||
#define NV_SOR_DP_SPARE_SOR_CLK_SEL_MACRO_SORCLK (1 << 2)
|
||||
#define NV_SOR_DP_SPARE_PANEL_SHIFT (1)
|
||||
#define NV_SOR_DP_SPARE_PANEL_EXTERNAL (0 << 1)
|
||||
#define NV_SOR_DP_SPARE_PANEL_INTERNAL (1 << 1)
|
||||
#define NV_SOR_DP_SPARE_SEQ_ENABLE_SHIFT (0)
|
||||
#define NV_SOR_DP_SPARE_SEQ_ENABLE_NO (0)
|
||||
#define NV_SOR_DP_SPARE_SEQ_ENABLE_YES (1)
|
||||
#define NV_SOR_DP_AUDIO_CTRL (0x62)
|
||||
#define NV_SOR_DP_AUDIO_HBLANK_SYMBOLS (0x63)
|
||||
#define NV_SOR_DP_AUDIO_HBLANK_SYMBOLS_MASK (0x1ffff)
|
||||
#define NV_SOR_DP_AUDIO_HBLANK_SYMBOLS_VALUE_SHIFT (0)
|
||||
#define NV_SOR_DP_AUDIO_VBLANK_SYMBOLS (0x64)
|
||||
#define NV_SOR_DP_AUDIO_VBLANK_SYMBOLS_MASK (0x1ffff)
|
||||
#define NV_SOR_DP_AUDIO_VBLANK_SYMBOLS_SHIFT (0)
|
||||
#define NV_SOR_DP_GENERIC_INFOFRAME_HEADER (0x65)
|
||||
#define NV_SOR_DP_GENERIC_INFOFRAME_SUBPACK(i) (0x66 + (i))
|
||||
#define NV_SOR_DP_TPG (0x6d)
|
||||
#define NV_SOR_DP_TPG_LANE3_CHANNELCODING_SHIFT (30)
|
||||
#define NV_SOR_DP_TPG_LANE3_CHANNELCODING_DISABLE (0 << 30)
|
||||
#define NV_SOR_DP_TPG_LANE3_CHANNELCODING_ENABLE (1 << 30)
|
||||
#define NV_SOR_DP_TPG_LANE3_SCRAMBLEREN_SHIFT (28)
|
||||
#define NV_SOR_DP_TPG_LANE3_SCRAMBLEREN_ENABLE_GALIOS (1 << 28)
|
||||
#define NV_SOR_DP_TPG_LANE3_SCRAMBLEREN_ENABLE_FIBONACCI (2 << 28)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_SHIFT (24)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_DEFAULT_MASK (0xf << 24)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_NOPATTERN (0 << 24)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_TRAINING1 (1 << 24)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_TRAINING2 (2 << 24)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_TRAINING3 (3 << 24)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_D102 (4 << 24)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_SBLERRRATE (5 << 24)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_PRBS7 (6 << 24)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_CSTM (7 << 24)
|
||||
#define NV_SOR_DP_TPG_LANE3_PATTERN_HBR2_COMPLIANCE (8 << 24)
|
||||
#define NV_SOR_DP_TPG_LANE2_CHANNELCODING_SHIFT (22)
|
||||
#define NV_SOR_DP_TPG_LANE2_CHANNELCODING_DISABLE (0 << 22)
|
||||
#define NV_SOR_DP_TPG_LANE2_CHANNELCODING_ENABLE (1 << 22)
|
||||
#define NV_SOR_DP_TPG_LANE2_SCRAMBLEREN_SHIFT (20)
|
||||
#define NV_SOR_DP_TPG_LANE2_SCRAMBLEREN_DEFAULT_MASK (0x3 << 20)
|
||||
#define NV_SOR_DP_TPG_LANE2_SCRAMBLEREN_DISABLE (0 << 20)
|
||||
#define NV_SOR_DP_TPG_LANE2_SCRAMBLEREN_ENABLE_GALIOS (1 << 20)
|
||||
#define NV_SOR_DP_TPG_LANE2_SCRAMBLEREN_ENABLE_FIBONACCI (2 << 20)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_SHIFT (16)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_DEFAULT_MASK (0xf << 16)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_NOPATTERN (0 << 16)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_TRAINING1 (1 << 16)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_TRAINING2 (2 << 16)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_TRAINING3 (3 << 16)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_D102 (4 << 16)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_SBLERRRATE (5 << 16)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_PRBS7 (6 << 16)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_CSTM (7 << 16)
|
||||
#define NV_SOR_DP_TPG_LANE2_PATTERN_HBR2_COMPLIANCE (8 << 16)
|
||||
#define NV_SOR_DP_TPG_LANE1_CHANNELCODING_SHIFT (14)
|
||||
#define NV_SOR_DP_TPG_LANE1_CHANNELCODING_DISABLE (0 << 14)
|
||||
#define NV_SOR_DP_TPG_LANE1_CHANNELCODING_ENABLE (1 << 14)
|
||||
#define NV_SOR_DP_TPG_LANE1_SCRAMBLEREN_SHIFT (12)
|
||||
#define NV_SOR_DP_TPG_LANE1_SCRAMBLEREN_DEFAULT_MASK (0x3 << 12)
|
||||
#define NV_SOR_DP_TPG_LANE1_SCRAMBLEREN_DISABLE (0 << 12)
|
||||
#define NV_SOR_DP_TPG_LANE1_SCRAMBLEREN_ENABLE_GALIOS (1 << 12)
|
||||
#define NV_SOR_DP_TPG_LANE1_SCRAMBLEREN_ENABLE_FIBONACCI (2 << 12)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_SHIFT (8)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_DEFAULT_MASK (0xf << 8)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_NOPATTERN (0 << 8)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_TRAINING1 (1 << 8)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_TRAINING2 (2 << 8)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_TRAINING3 (3 << 8)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_D102 (4 << 8)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_SBLERRRATE (5 << 8)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_PRBS7 (6 << 8)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_CSTM (7 << 8)
|
||||
#define NV_SOR_DP_TPG_LANE1_PATTERN_HBR2_COMPLIANCE (8 << 8)
|
||||
#define NV_SOR_DP_TPG_LANE0_CHANNELCODING_SHIFT (6)
|
||||
#define NV_SOR_DP_TPG_LANE0_CHANNELCODING_DISABLE (0 << 6)
|
||||
#define NV_SOR_DP_TPG_LANE0_CHANNELCODING_ENABLE (1 << 6)
|
||||
#define NV_SOR_DP_TPG_LANE0_SCRAMBLEREN_SHIFT (4)
|
||||
#define NV_SOR_DP_TPG_LANE0_SCRAMBLEREN_DEFAULT_MASK (0x3 << 4)
|
||||
#define NV_SOR_DP_TPG_LANE0_SCRAMBLEREN_DISABLE (0 << 4)
|
||||
#define NV_SOR_DP_TPG_LANE0_SCRAMBLEREN_ENABLE_GALIOS (1 << 4)
|
||||
#define NV_SOR_DP_TPG_LANE0_SCRAMBLEREN_ENABLE_FIBONACCI (2 << 4)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_SHIFT (0)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_DEFAULT_MASK (0xf)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_NOPATTERN (0)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_TRAINING1 (1)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_TRAINING2 (2)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_TRAINING3 (3)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_D102 (4)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_SBLERRRATE (5)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_PRBS7 (6)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_CSTM (7)
|
||||
#define NV_SOR_DP_TPG_LANE0_PATTERN_HBR2_COMPLIANCE (8)
|
||||
|
||||
enum {
|
||||
training_pattern_disabled = 0,
|
||||
training_pattern_1 = 1,
|
||||
training_pattern_2 = 2,
|
||||
training_pattern_3 = 3,
|
||||
training_pattern_none = 0xff
|
||||
};
|
||||
|
||||
enum tegra_dc_sor_protocol {
|
||||
SOR_DP,
|
||||
SOR_LVDS,
|
||||
};
|
||||
|
||||
#define SOR_LINK_SPEED_G1_62 6
|
||||
#define SOR_LINK_SPEED_G2_7 10
|
||||
#define SOR_LINK_SPEED_G5_4 20
|
||||
#define SOR_LINK_SPEED_LVDS 7
|
||||
|
||||
/* todo: combine this and the intel_dp struct into one struct. */
|
||||
struct tegra_dc_dp_link_config {
|
||||
int is_valid;
|
||||
|
||||
/* Supported configuration */
|
||||
u8 max_link_bw;
|
||||
u8 max_lane_count;
|
||||
int downspread;
|
||||
int support_enhanced_framing;
|
||||
u32 bits_per_pixel;
|
||||
int alt_scramber_reset_cap; /* true for eDP */
|
||||
int only_enhanced_framing; /* enhanced_frame_en ignored */
|
||||
|
||||
/* Actual configuration */
|
||||
u8 link_bw;
|
||||
u8 lane_count;
|
||||
int enhanced_framing;
|
||||
int scramble_ena;
|
||||
|
||||
u32 activepolarity;
|
||||
u32 active_count;
|
||||
u32 tu_size;
|
||||
u32 active_frac;
|
||||
u32 watermark;
|
||||
|
||||
s32 hblank_sym;
|
||||
s32 vblank_sym;
|
||||
|
||||
/* Training data */
|
||||
u32 drive_current;
|
||||
u32 preemphasis;
|
||||
u32 postcursor;
|
||||
u8 aux_rd_interval;
|
||||
u8 tps3_supported;
|
||||
};
|
||||
|
||||
/* TODO: just pull these up into one struct? Need to see how this impacts
|
||||
* having two channels.
|
||||
*/
|
||||
struct tegra_dc_sor_data {
|
||||
struct tegra_dc *dc;
|
||||
void *base;
|
||||
void *pmc_base;
|
||||
u8 portnum; /* 0 or 1 */
|
||||
struct tegra_dc_dp_link_config *link_cfg;
|
||||
int power_is_up;
|
||||
};
|
||||
|
||||
#define TEGRA_SOR_TIMEOUT_MS 1000
|
||||
#define TEGRA_SOR_ATTACH_TIMEOUT_MS 1000
|
||||
#define TEGRA_DC_POLL_TIMEOUT_MS 50
|
||||
|
||||
#define CHECK_RET(x) \
|
||||
do { \
|
||||
ret = (x); \
|
||||
if (ret != 0) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
void tegra_dc_sor_enable_dp(struct tegra_dc_sor_data *sor);
|
||||
int tegra_dc_sor_set_power_state(struct tegra_dc_sor_data *sor, int pu_pd);
|
||||
void tegra_dc_sor_set_dp_linkctl(struct tegra_dc_sor_data *sor, int ena,
|
||||
u8 training_pattern, const struct tegra_dc_dp_link_config *link_cfg);
|
||||
void tegra_dc_sor_set_link_bandwidth(struct tegra_dc_sor_data *sor, u8 link_bw);
|
||||
void tegra_dc_sor_set_lane_count(struct tegra_dc_sor_data *sor, u8 lane_count);
|
||||
void tegra_dc_sor_set_panel_power(struct tegra_dc_sor_data *sor,
|
||||
int power_up);
|
||||
void tegra_dc_sor_set_internal_panel(struct tegra_dc_sor_data *sor, int is_int);
|
||||
void tegra_dc_sor_read_link_config(struct tegra_dc_sor_data *sor, u8 *link_bw,
|
||||
u8 *lane_count);
|
||||
void tegra_dc_sor_attach(struct tegra_dc_sor_data *sor);
|
||||
void tegra_dc_sor_set_lane_parm(struct tegra_dc_sor_data *sor,
|
||||
const struct tegra_dc_dp_link_config *link_cfg);
|
||||
void tegra_dc_sor_power_down_unused_lanes(struct tegra_dc_sor_data *sor);
|
||||
void tegra_dc_sor_set_voltage_swing(struct tegra_dc_sor_data *sor);
|
||||
void tegra_sor_precharge_lanes(struct tegra_dc_sor_data *sor);
|
||||
void tegra_dp_disable_tx_pu(struct tegra_dc_sor_data *sor);
|
||||
void tegra_dp_set_pe_vs_pc(struct tegra_dc_sor_data *sor, u32 mask,
|
||||
u32 pe_reg, u32 vs_reg, u32 pc_reg, u8 pc_supported);
|
||||
void tegra_dc_detach(struct tegra_dc_sor_data *sor);
|
||||
#endif /*__TEGRA210_SOR_H__ */
|
67
src/soc/nvidia/tegra210/include/soc/spi.h
Normal file
67
src/soc/nvidia/tegra210/include/soc/spi.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
* Copyright (c) 2013-2015, 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 __NVIDIA_TEGRA210_SPI_H__
|
||||
#define __NVIDIA_TEGRA210_SPI_H__
|
||||
|
||||
#include <soc/dma.h>
|
||||
#include <spi-generic.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct tegra_spi_regs {
|
||||
u32 command1; /* 0x000: SPI_COMMAND1 */
|
||||
u32 command2; /* 0x004: SPI_COMMAND2 */
|
||||
u32 timing1; /* 0x008: SPI_CS_TIM1 */
|
||||
u32 timing2; /* 0x00c: SPI_CS_TIM2 */
|
||||
u32 trans_status; /* 0x010: SPI_TRANS_STATUS */
|
||||
u32 fifo_status; /* 0x014: SPI_FIFO_STATUS */
|
||||
u32 tx_data; /* 0x018: SPI_TX_DATA */
|
||||
u32 rx_data; /* 0x01c: SPI_RX_DATA */
|
||||
u32 dma_ctl; /* 0x020: SPI_DMA_CTL */
|
||||
u32 dma_blk; /* 0x024: SPI_DMA_BLK */
|
||||
u32 rsvd[56]; /* 0x028-0x107: reserved */
|
||||
u32 tx_fifo; /* 0x108: SPI_FIFO1 */
|
||||
u32 rsvd2[31]; /* 0x10c-0x187 reserved */
|
||||
u32 rx_fifo; /* 0x188: SPI_FIFO2 */
|
||||
u32 spare_ctl; /* 0x18c: SPI_SPARE_CTRL */
|
||||
} __attribute__((packed));
|
||||
check_member(tegra_spi_regs, spare_ctl, 0x18c);
|
||||
|
||||
enum spi_xfer_mode {
|
||||
XFER_MODE_NONE = 0,
|
||||
XFER_MODE_PIO,
|
||||
XFER_MODE_DMA,
|
||||
};
|
||||
|
||||
struct tegra_spi_channel {
|
||||
struct tegra_spi_regs *regs;
|
||||
|
||||
/* static configuration */
|
||||
struct spi_slave slave;
|
||||
unsigned int req_sel;
|
||||
|
||||
int dual_mode; /* for x2 transfers with bit interleaving */
|
||||
|
||||
/* context (used internally) */
|
||||
u8 *in_buf, *out_buf;
|
||||
struct apb_dma_channel *dma_out, *dma_in;
|
||||
enum spi_xfer_mode xfer_mode;
|
||||
};
|
||||
|
||||
struct tegra_spi_channel *tegra_spi_init(unsigned int bus);
|
||||
|
||||
#endif /* __NVIDIA_TEGRA210_SPI_H__ */
|
55
src/soc/nvidia/tegra210/include/soc/sysctr.h
Normal file
55
src/soc/nvidia/tegra210/include/soc/sysctr.h
Normal 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_SYSCTR_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_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_TEGRA210_SYSCTR_H__ */
|
223
src/soc/nvidia/tegra210/include/soc/tegra_dsi.h
Normal file
223
src/soc/nvidia/tegra210/include/soc/tegra_dsi.h
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __TEGRA_DSI_H__
|
||||
#define __TEGRA_DSI_H__
|
||||
|
||||
#define DSI_INCR_SYNCPT 0x00
|
||||
#define DSI_INCR_SYNCPT_CONTROL 0x01
|
||||
#define DSI_INCR_SYNCPT_ERROR 0x02
|
||||
#define DSI_CTXSW 0x08
|
||||
#define DSI_RD_DATA 0x09
|
||||
#define DSI_WR_DATA 0x0a
|
||||
#define DSI_POWER_CONTROL 0x0b
|
||||
#define DSI_POWER_CONTROL_ENABLE (1 << 0)
|
||||
#define DSI_INT_ENABLE 0x0c
|
||||
#define DSI_INT_STATUS 0x0d
|
||||
#define DSI_INT_MASK 0x0e
|
||||
#define DSI_HOST_CONTROL 0x0f
|
||||
#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21)
|
||||
#define DSI_HOST_CONTROL_CRC_RESET (1 << 20)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
|
||||
#define DSI_HOST_CONTROL_RAW (1 << 6)
|
||||
#define DSI_HOST_CONTROL_HS (1 << 5)
|
||||
#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
|
||||
#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
|
||||
#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
|
||||
#define DSI_HOST_CONTROL_CS (1 << 1)
|
||||
#define DSI_HOST_CONTROL_ECC (1 << 0)
|
||||
#define DSI_CONTROL 0x10
|
||||
#define DSI_CONTROL_HS_CLK_CTRL (1 << 20)
|
||||
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
|
||||
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
|
||||
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
|
||||
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
|
||||
#define DSI_CONTROL_DCS_ENABLE (1 << 3)
|
||||
#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
|
||||
#define DSI_CONTROL_VIDEO_ENABLE (1 << 1)
|
||||
#define DSI_CONTROL_HOST_ENABLE (1 << 0)
|
||||
#define DSI_SOL_DELAY 0x11
|
||||
#define DSI_MAX_THRESHOLD 0x12
|
||||
#define DSI_TRIGGER 0x13
|
||||
#define DSI_TRIGGER_HOST (1 << 1)
|
||||
#define DSI_TRIGGER_VIDEO (1 << 0)
|
||||
#define DSI_TX_CRC 0x14
|
||||
#define DSI_STATUS 0x15
|
||||
#define DSI_STATUS_IDLE (1 << 10)
|
||||
#define DSI_STATUS_UNDERFLOW (1 << 9)
|
||||
#define DSI_STATUS_OVERFLOW (1 << 8)
|
||||
#define DSI_INIT_SEQ_CONTROL 0x1a
|
||||
#define DSI_INIT_SEQ_DATA_0 0x1b
|
||||
#define DSI_INIT_SEQ_DATA_1 0x1c
|
||||
#define DSI_INIT_SEQ_DATA_2 0x1d
|
||||
#define DSI_INIT_SEQ_DATA_3 0x1e
|
||||
#define DSI_INIT_SEQ_DATA_4 0x1f
|
||||
#define DSI_INIT_SEQ_DATA_5 0x20
|
||||
#define DSI_INIT_SEQ_DATA_6 0x21
|
||||
#define DSI_INIT_SEQ_DATA_7 0x22
|
||||
#define DSI_PKT_SEQ_0_LO 0x23
|
||||
#define DSI_PKT_SEQ_0_HI 0x24
|
||||
#define DSI_PKT_SEQ_1_LO 0x25
|
||||
#define DSI_PKT_SEQ_1_HI 0x26
|
||||
#define DSI_PKT_SEQ_2_LO 0x27
|
||||
#define DSI_PKT_SEQ_2_HI 0x28
|
||||
#define DSI_PKT_SEQ_3_LO 0x29
|
||||
#define DSI_PKT_SEQ_3_HI 0x2a
|
||||
#define DSI_PKT_SEQ_4_LO 0x2b
|
||||
#define DSI_PKT_SEQ_4_HI 0x2c
|
||||
#define DSI_PKT_SEQ_5_LO 0x2d
|
||||
#define DSI_PKT_SEQ_5_HI 0x2e
|
||||
#define DSI_DCS_CMDS 0x33
|
||||
#define DSI_PKT_LEN_0_1 0x34
|
||||
#define DSI_PKT_LEN_2_3 0x35
|
||||
#define DSI_PKT_LEN_4_5 0x36
|
||||
#define DSI_PKT_LEN_6_7 0x37
|
||||
#define DSI_PHY_TIMING_0 0x3c
|
||||
#define DSI_PHY_TIMING_1 0x3d
|
||||
#define DSI_PHY_TIMING_2 0x3e
|
||||
#define DSI_BTA_TIMING 0x3f
|
||||
|
||||
#define DSI_TIMING_FIELD(value, period, hwinc) \
|
||||
((DIV_ROUND_CLOSEST(value, period) - (hwinc)) & 0xff)
|
||||
|
||||
#define DSI_TIMEOUT_0 0x44
|
||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
|
||||
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
|
||||
#define DSI_TIMEOUT_1 0x45
|
||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
|
||||
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
|
||||
#define DSI_TO_TALLY 0x46
|
||||
#define DSI_TALLY_TA(x) (((x) & 0xff) << 16)
|
||||
#define DSI_TALLY_LRX(x) (((x) & 0xff) << 8)
|
||||
#define DSI_TALLY_HTX(x) (((x) & 0xff) << 0)
|
||||
#define DSI_PAD_CONTROL_0 0x4b
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)
|
||||
#define DSI_PAD_CONTROL_CD 0x4c
|
||||
#define DSI_PAD_CD_STATUS 0x4d
|
||||
#define DSI_VIDEO_MODE_CONTROL 0x4e
|
||||
#define DSI_PAD_CONTROL_1 0x4f
|
||||
#define DSI_PAD_CONTROL_2 0x50
|
||||
#define DSI_PAD_OUT_CLK(x) (((x) & 0x7) << 0)
|
||||
#define DSI_PAD_LP_DN(x) (((x) & 0x7) << 4)
|
||||
#define DSI_PAD_LP_UP(x) (((x) & 0x7) << 8)
|
||||
#define DSI_PAD_SLEW_DN(x) (((x) & 0x7) << 12)
|
||||
#define DSI_PAD_SLEW_UP(x) (((x) & 0x7) << 16)
|
||||
#define DSI_PAD_CONTROL_3 0x51
|
||||
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
|
||||
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
|
||||
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
|
||||
#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
|
||||
#define DSI_PAD_CONTROL_4 0x52
|
||||
#define DSI_GANGED_MODE_CONTROL 0x53
|
||||
#define DSI_GANGED_MODE_CONTROL_ENABLE (1 << 0)
|
||||
#define DSI_GANGED_MODE_START 0x54
|
||||
#define DSI_GANGED_MODE_SIZE 0x55
|
||||
#define DSI_RAW_DATA_BYTE_COUNT 0x56
|
||||
#define DSI_ULTRA_LOW_POWER_CONTROL 0x57
|
||||
#define DSI_INIT_SEQ_DATA_8 0x58
|
||||
#define DSI_INIT_SEQ_DATA_9 0x59
|
||||
#define DSI_INIT_SEQ_DATA_10 0x5a
|
||||
#define DSI_INIT_SEQ_DATA_11 0x5b
|
||||
#define DSI_INIT_SEQ_DATA_12 0x5c
|
||||
#define DSI_INIT_SEQ_DATA_13 0x5d
|
||||
#define DSI_INIT_SEQ_DATA_14 0x5e
|
||||
#define DSI_INIT_SEQ_DATA_15 0x5f
|
||||
|
||||
#define PKT_ID0(id) ((((id) & 0x3f) << 3) | (1 << 9))
|
||||
#define PKT_LEN0(len) (((len) & 0x07) << 0)
|
||||
#define PKT_ID1(id) ((((id) & 0x3f) << 13) | (1 << 19))
|
||||
#define PKT_LEN1(len) (((len) & 0x07) << 10)
|
||||
#define PKT_ID2(id) ((((id) & 0x3f) << 23) | (1 << 29))
|
||||
#define PKT_LEN2(len) (((len) & 0x07) << 20)
|
||||
|
||||
#define PKT_LP (1 << 30)
|
||||
#define NUM_PKT_SEQ 12
|
||||
|
||||
#define APB_MISC_GP_MIPI_PAD_CTRL_0 (TEGRA_APB_MISC_GP_BASE + 0x20)
|
||||
#define DSIB_MODE_SHIFT 1
|
||||
#define DSIB_MODE_CSI (0 << DSIB_MODE_SHIFT)
|
||||
#define DSIB_MODE_DSI (1 << DSIB_MODE_SHIFT)
|
||||
|
||||
/*
|
||||
* pixel format as used in the DSI_CONTROL_FORMAT field
|
||||
*/
|
||||
enum tegra_dsi_format {
|
||||
TEGRA_DSI_FORMAT_16P,
|
||||
TEGRA_DSI_FORMAT_18NP,
|
||||
TEGRA_DSI_FORMAT_18P,
|
||||
TEGRA_DSI_FORMAT_24P,
|
||||
};
|
||||
|
||||
enum dsi_dev {
|
||||
DSI_A = 0,
|
||||
DSI_B,
|
||||
NUM_DSI,
|
||||
};
|
||||
|
||||
struct panel_jdi;
|
||||
struct tegra_mipi_device;
|
||||
struct mipi_dsi_host;
|
||||
struct mipi_dsi_msg;
|
||||
|
||||
#define MAX_DSI_VIDEO_FIFO_DEPTH 96
|
||||
#define MAX_DSI_HOST_FIFO_DEPTH 64
|
||||
|
||||
struct tegra_dsi {
|
||||
struct panel_jdi *panel;
|
||||
//struct tegra_output output;
|
||||
void *regs;
|
||||
u8 channel;
|
||||
unsigned long clk_rate;
|
||||
|
||||
unsigned long flags;
|
||||
enum mipi_dsi_pixel_format format;
|
||||
unsigned int lanes;
|
||||
|
||||
struct tegra_mipi_device *mipi;
|
||||
struct mipi_dsi_host host;
|
||||
bool enabled;
|
||||
|
||||
unsigned int video_fifo_depth;
|
||||
unsigned int host_fifo_depth;
|
||||
|
||||
/* for ganged-mode support */
|
||||
unsigned int ganged_lanes;
|
||||
struct tegra_dsi *slave;
|
||||
int ganged_mode;
|
||||
|
||||
struct tegra_dsi *master;
|
||||
};
|
||||
|
||||
static inline unsigned long tegra_dsi_readl(struct tegra_dsi *dsi,
|
||||
unsigned long reg)
|
||||
{
|
||||
return read32(dsi->regs + (reg << 2));
|
||||
}
|
||||
|
||||
static inline void tegra_dsi_writel(struct tegra_dsi *dsi, unsigned long value,
|
||||
unsigned long reg)
|
||||
{
|
||||
write32(dsi->regs + (reg << 2), value);
|
||||
}
|
||||
|
||||
#endif /* __TEGRA_DSI_H__ */
|
25
src/soc/nvidia/tegra210/include/soc/verstage.h
Normal file
25
src/soc/nvidia/tegra210/include/soc/verstage.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__
|
||||
|
||||
void verstage_mainboard_init(void);
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__ */
|
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
#include <console/console.h>
|
||||
#include <arch/io.h>
|
||||
#include <stdint.h>
|
||||
#include <lib.h>
|
||||
#include <stdlib.h>
|
||||
#include <delay.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <device/device.h>
|
||||
#include <soc/nvidia/tegra/types.h>
|
||||
#include "../chip.h"
|
||||
#include <soc/display.h>
|
||||
#include <soc/mipi_dsi.h>
|
||||
#include <soc/tegra_dsi.h>
|
||||
#include "panel-jdi-lpm102a188a.h"
|
||||
|
||||
struct panel_jdi jdi_data[NUM_DSI];
|
||||
|
||||
int panel_jdi_prepare(struct panel_jdi *jdi)
|
||||
{
|
||||
int ret;
|
||||
u8 data;
|
||||
|
||||
if (jdi->enabled)
|
||||
return 0;
|
||||
|
||||
ret = mipi_dsi_dcs_set_column_address(jdi->dsi, 0,
|
||||
jdi->mode->xres / 2 - 1); // 2560/2
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set column address: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_set_column_address(jdi->dsi->slave, 0,
|
||||
jdi->mode->xres / 2 - 1);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set column address: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_set_page_address(jdi->dsi, 0,
|
||||
jdi->mode->yres - 1);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set page address: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_set_page_address(jdi->dsi->slave, 0,
|
||||
jdi->mode->yres - 1);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set page address: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_set_tear_on(jdi->dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set tear on: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_set_tear_on(jdi->dsi->slave,
|
||||
MIPI_DSI_DCS_TEAR_MODE_VBLANK);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set tear on: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_set_address_mode(jdi->dsi, false, false, false,
|
||||
false, false, false, false, false);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set address mode: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_set_address_mode(jdi->dsi->slave, false, false,
|
||||
false, false, false, false, false, false);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set address mode: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_set_pixel_format(jdi->dsi, 0x77);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set pixel format: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_set_pixel_format(jdi->dsi->slave, 0x77);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set pixel format: %d\n", ret);
|
||||
|
||||
data = 0xFF;
|
||||
ret = mipi_dsi_dcs_write(jdi->dsi, 0x51, &data, 1);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set 0x51: %d\n", ret);
|
||||
|
||||
data = 0xFF;
|
||||
ret = mipi_dsi_dcs_write(jdi->dsi->slave, 0x51, &data, 1);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set 0x51: %d\n", ret);
|
||||
|
||||
data = 0x24;
|
||||
ret = mipi_dsi_dcs_write(jdi->dsi, 0x53, &data, 1);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set 0x53: %d\n", ret);
|
||||
|
||||
data = 0x24;
|
||||
ret = mipi_dsi_dcs_write(jdi->dsi->slave, 0x53, &data, 1);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set 0x53: %d\n", ret);
|
||||
|
||||
data = 0x00;
|
||||
ret = mipi_dsi_dcs_write(jdi->dsi, 0x55, &data, 1);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set 0x55: %d\n", ret);
|
||||
|
||||
data = 0x00;
|
||||
ret = mipi_dsi_dcs_write(jdi->dsi->slave, 0x55, &data, 1);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set 0x55: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(jdi->dsi);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to exit sleep mode: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(jdi->dsi->slave);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to exit sleep mode: %d\n", ret);
|
||||
mdelay(150);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(jdi->dsi);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set display on: %d\n", ret);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(jdi->dsi->slave);
|
||||
if (ret < 0)
|
||||
printk(BIOS_ERR, "failed to set display on: %d\n", ret);
|
||||
mdelay(50);
|
||||
|
||||
jdi->enabled = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int panel_jdi_enslave(struct mipi_dsi_device *master,
|
||||
struct mipi_dsi_device *slave)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_attach(master);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int panel_jdi_liberate(struct mipi_dsi_device *master,
|
||||
struct mipi_dsi_device *slave)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_detach(master);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mipi_dsi_master_ops panel_jdi_master_ops = {
|
||||
.enslave = panel_jdi_enslave,
|
||||
.liberate = panel_jdi_liberate,
|
||||
};
|
||||
|
||||
struct panel_jdi *panel_jdi_dsi_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
static int index = 0;
|
||||
struct panel_jdi *jdi;
|
||||
int ret;
|
||||
|
||||
if (index >= NUM_DSI)
|
||||
return (void *)-EPTR;
|
||||
|
||||
jdi = &jdi_data[index++];
|
||||
|
||||
jdi->dsi = dsi;
|
||||
|
||||
dsi->lanes = 4;
|
||||
dsi->format = MIPI_DSI_FMT_RGB888;
|
||||
dsi->mode_flags = 0;
|
||||
|
||||
if (dsi->master) {
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0) {
|
||||
printk(BIOS_ERR, "mipi_dsi_attach() failed: %d\n", ret);
|
||||
return (void *)-EPTR;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_enslave(dsi->master, dsi);
|
||||
if (ret < 0) {
|
||||
printk(BIOS_ERR, "mipi_dsi_enslave() failed: %d\n",
|
||||
ret);
|
||||
return (void *)-EPTR;
|
||||
}
|
||||
|
||||
return jdi;
|
||||
}
|
||||
|
||||
dsi->ops = &panel_jdi_master_ops;
|
||||
|
||||
jdi->enabled = 0;
|
||||
jdi->width_mm = 211;
|
||||
jdi->height_mm = 148;
|
||||
|
||||
return jdi;
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
#ifndef _PANEL_JDI_LPM102A188A_H_
|
||||
#define _PANEL_JDI_LPM102A188A_H_
|
||||
|
||||
#define LP8557_MAX_BRIGHTNESS 0xFFF;
|
||||
|
||||
#define LP8557_COMMAND 0x00
|
||||
#define LP8557_COMMAND_ON (1 << 0)
|
||||
|
||||
#define LP8557_BRIGHTNESS_LOW 0x03
|
||||
#define LP8557_BRIGHTNESS_LOW_MASK(x) (((x) & 0xF) << 4)
|
||||
|
||||
#define LP8557_BRIGHTNESS_HIGH 0x04
|
||||
#define LP8557_BRIGHTNESS_HIGH_MASK(x) (((x) & 0xFF0) >> 4)
|
||||
|
||||
enum lp8557_config_brightness_mode {
|
||||
LP8557_CONFIG_BRTMODE_PWM = 0x0,
|
||||
LP8557_CONFIG_BRTMODE_REG,
|
||||
LP8557_CONFIG_BRTMODE_PWM_REG_SHAPE_PWM,
|
||||
LP8557_CONFIG_BRTMODE_PWM_REG_SHAPE_BRIGHTNESS,
|
||||
LP8557_CONFIG_BRTMODE_MAX,
|
||||
};
|
||||
#define LP8557_CONFIG 0x10
|
||||
#define LP8557_CONFIG_BRTMODE(x) (((x) & 0x3) << 0)
|
||||
#define LP8557_CONFIG_AUTO_DETECT_LED (1 << 2)
|
||||
#define LP8557_CONFIG_PWM_STANDBY (1 << 7)
|
||||
|
||||
enum lp8557_current {
|
||||
LP8557_CURRENT_5_MA = 0x0,
|
||||
LP8557_CURRENT_10_MA,
|
||||
LP8557_CURRENT_13_MA,
|
||||
LP8557_CURRENT_15_MA,
|
||||
LP8557_CURRENT_18_MA,
|
||||
LP8557_CURRENT_20_MA,
|
||||
LP8557_CURRENT_23_MA,
|
||||
LP8557_CURRENT_25_MA,
|
||||
LP8557_CURRENT_MAX,
|
||||
};
|
||||
#define LP8557_CURRENT 0x11
|
||||
#define LP8557_CURRENT_MAXCURR(x) (((x) & 0x7) << 0)
|
||||
#define LP8557_CURRENT_ISET (1 << 7)
|
||||
|
||||
enum lp8557_pgen_frequency {
|
||||
LP8557_PGEN_FREQ_4_9_KHZ = 0x0,
|
||||
LP8557_PGEN_FREQ_9_8_KHZ,
|
||||
LP8557_PGEN_FREQ_14_6_KHZ,
|
||||
LP8557_PGEN_FREQ_19_5_KHZ,
|
||||
LP8557_PGEN_FREQ_24_4_KHZ,
|
||||
LP8557_PGEN_FREQ_29_3_KHZ,
|
||||
LP8557_PGEN_FREQ_34_2_KHZ,
|
||||
LP8557_PGEN_FREQ_39_1_KHZ,
|
||||
LP8557_PGEN_FREQ_MAX,
|
||||
};
|
||||
#define LP8557_PGEN 0x12
|
||||
#define LP8557_PGEN_FREQ(x) (((x) & 0x7) << 0)
|
||||
#define LP8557_PGEN_MAGIC (5 << 3)
|
||||
#define LP8557_PGEN_FSET (1 << 7)
|
||||
|
||||
enum lp8557_boost_freq {
|
||||
LP8557_BOOST_FREQ_500_KHZ = 0x0,
|
||||
LP8557_BOOST_FREQ_1_MHZ,
|
||||
LP8557_BOOST_FREQ_MAX,
|
||||
};
|
||||
enum lp8557_boost_bcomp {
|
||||
LP8557_BOOST_BCOMP_OPTION_0 = 0x0,
|
||||
LP8557_BOOST_BCOMP_OPTION_1,
|
||||
LP8557_BOOST_BCOMP_MAX,
|
||||
};
|
||||
#define LP8557_BOOST 0x13
|
||||
#define LP8557_BOOST_FREQ(x) (((x) & 0x1) << 0)
|
||||
#define LP8557_BOOST_BCOMP(x) (((x) & 0x1) << 1)
|
||||
#define LP8557_BOOST_BCSET (1 << 6)
|
||||
#define LP8557_BOOST_BFSET (1 << 7)
|
||||
|
||||
#define LP8557_LED_ENABLE 0x14
|
||||
#define LP8557_LED_ENABLE_SINKS(x) (((x) & 0x3F) << 0)
|
||||
#define LP8557_LED_ENABLE_MAGIC (2 << 6)
|
||||
|
||||
enum lp8557_step_ramp {
|
||||
LP8557_STEP_RAMP_0_MS = 0x0,
|
||||
LP8557_STEP_RAMP_50_MS,
|
||||
LP8557_STEP_RAMP_100_MS,
|
||||
LP8557_STEP_RAMP_200_MS,
|
||||
LP8557_STEP_RAMP_MAX,
|
||||
};
|
||||
enum lp8557_step_smoothing {
|
||||
LP8557_STEP_SMOOTHING_NONE = 0x0,
|
||||
LP8557_STEP_SMOOTHING_LIGHT,
|
||||
LP8557_STEP_SMOOTHING_MEDIUM,
|
||||
LP8557_STEP_SMOOTHING_HEAVY,
|
||||
LP8557_STEP_SMOOTHING_MAX,
|
||||
};
|
||||
#define LP8557_STEP 0x15
|
||||
#define LP8557_STEP_RAMP(x) (((x) & 0x3) << 0)
|
||||
#define LP8557_STEP_SMOOTHING(x) (((x) & 0x3) << 6)
|
||||
|
||||
struct mipi_dsi_device;
|
||||
struct soc_nvidia_tegra210_config;
|
||||
|
||||
struct panel_jdi {
|
||||
struct mipi_dsi_device *dsi;
|
||||
const struct soc_nvidia_tegra210_config *mode;
|
||||
|
||||
/* Physical size */
|
||||
unsigned int width_mm;
|
||||
unsigned int height_mm;
|
||||
|
||||
int enabled;
|
||||
};
|
||||
|
||||
struct panel_jdi *panel_jdi_dsi_probe(struct mipi_dsi_device *dsi);
|
||||
int panel_jdi_prepare(struct panel_jdi *jdi);
|
||||
|
||||
#endif
|
58
src/soc/nvidia/tegra210/lp0/Makefile
Normal file
58
src/soc/nvidia/tegra210/lp0/Makefile
Normal file
@ -0,0 +1,58 @@
|
||||
################################################################################
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
################################################################################
|
||||
|
||||
CC = $(GCC_PREFIX)gcc
|
||||
NM = $(GCC_PREFIX)nm
|
||||
OBJCOPY = $(GCC_PREFIX)objcopy
|
||||
|
||||
OPENSSL = openssl
|
||||
DD = dd
|
||||
CP = cp
|
||||
MV = mv
|
||||
RM = rm
|
||||
|
||||
SIGKEY = 00000000000000000000000000000000
|
||||
|
||||
.PHONY: all
|
||||
all: tegra_lp0_resume.fw
|
||||
|
||||
tegra_lp0_resume.elf: tegra_lp0_resume.ld tegra_lp0_resume.c
|
||||
$(CC) -marm -march=armv4t -mno-unaligned-access -nostdlib -static \
|
||||
-Os -fpie -Wl,--build-id=none -ggdb3 -T tegra_lp0_resume.ld \
|
||||
-o $@ $(filter %.c,$+)
|
||||
|
||||
tegra_lp0_resume.fw: tegra_lp0_resume.elf
|
||||
@# Get rid of any files we're about to create.
|
||||
$(RM) -f $@.nosig $@.sig $@.tosig
|
||||
@# Convert the ELF image into a binary image.
|
||||
$(OBJCOPY) -O binary $< $@.nosig
|
||||
@# Extract the part of the binary which needs to be signed.
|
||||
$(DD) bs=1 skip=544 if=$@.nosig of=$@.tosig
|
||||
@# Calculate a signature for that part.
|
||||
$(OPENSSL) dgst -mac cmac -macopt cipher:aes-128-cbc \
|
||||
-macopt hexkey:$(SIGKEY) -md5 -binary \
|
||||
$@.tosig > $@.sig
|
||||
@# Inject the signature into the binary image's header.
|
||||
$(DD) conv=notrunc bs=1 seek=272 count=16 if=$@.sig of=$@.nosig
|
||||
@# Copy the signed binary to the target file name.
|
||||
$(MV) $@.nosig $@
|
||||
|
||||
clean:
|
||||
$(RM) -f tegra_lp0_resume.fw tegra_lp0_resume.fw.sig
|
||||
$(RM) -f tegra_lp0_resume.fw.tosig tegra_lp0_resume.elf
|
691
src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c
Normal file
691
src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c
Normal file
@ -0,0 +1,691 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
* Copyright 2013-2015, 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/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Function unit addresses. */
|
||||
enum {
|
||||
UP_TAG_BASE = 0X60000000,
|
||||
TIMER_BASE = 0X60005000,
|
||||
CLK_RST_BASE = 0X60006000,
|
||||
FLOW_CTLR_BASE = 0X60007000,
|
||||
TEGRA_EVP_BASE = 0x6000f000,
|
||||
APB_MISC_BASE = 0x70000000,
|
||||
PMC_CTLR_BASE = 0X7000e400,
|
||||
MC_CTLR_BASE = 0X70019000,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* UP tag registers. */
|
||||
static uint32_t *up_tag_ptr = (void *)(UP_TAG_BASE + 0x0);
|
||||
enum {
|
||||
UP_TAG_AVP = 0xaaaaaaaa
|
||||
};
|
||||
|
||||
|
||||
/* APB Misc JTAG Configuration Register */
|
||||
static uint32_t *misc_pp_config_ctl_ptr = (void *)(APB_MISC_BASE + 0x24);
|
||||
enum {
|
||||
PP_CONFIG_CTL_JTAG = 0x1 << 6
|
||||
};
|
||||
|
||||
|
||||
/* Timer registers. */
|
||||
static uint32_t *timer_us_ptr = (void *)(TIMER_BASE + 0x10);
|
||||
|
||||
|
||||
|
||||
/* Clock and reset controller registers. */
|
||||
static uint32_t *clk_rst_rst_devices_l_ptr = (void *)(CLK_RST_BASE + 0x4);
|
||||
enum {
|
||||
SWR_TRIG_SYS_RST = 0x1 << 2
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_cclk_burst_policy_ptr = (void *)(CLK_RST_BASE + 0x20);
|
||||
enum {
|
||||
CCLK_PLLP_BURST_POLICY = 0x20004444
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_super_cclk_div_ptr = (void *)(CLK_RST_BASE + 0x24);
|
||||
enum {
|
||||
SUPER_CDIV_ENB = 0x1 << 31
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_osc_ctrl_ptr = (void *)(CLK_RST_BASE + 0x50);
|
||||
enum {
|
||||
OSC_XOE = 0x1 << 0,
|
||||
OSC_XOFS_SHIFT = 4,
|
||||
OSC_XOFS_MASK = 0x3f << OSC_XOFS_SHIFT,
|
||||
OSC_FREQ_SHIFT = 28,
|
||||
OSC_FREQ_MASK = 0xf << OSC_FREQ_SHIFT
|
||||
};
|
||||
enum {
|
||||
OSC_FREQ_13 = 0,
|
||||
OSC_FREQ_16P8 = 1,
|
||||
OSC_FREQ_19P2 = 4,
|
||||
OSC_FREQ_38P4 = 5,
|
||||
OSC_FREQ_12 = 8,
|
||||
OSC_FREQ_48 = 9,
|
||||
OSC_FREQ_26 = 12
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_pllu_base_ptr = (void *)(CLK_RST_BASE + 0xc0);
|
||||
enum {
|
||||
PLLU_DIVM_SHIFT = 0,
|
||||
PLLU_DIVN_SHIFT = 8,
|
||||
PLLU_OVERRIDE = 0x1 << 24,
|
||||
PLLU_ENABLE = 0x1 << 30,
|
||||
PLLU_BYPASS = 0x1 << 31
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_pllu_misc_ptr = (void *)(CLK_RST_BASE + 0xcc);
|
||||
enum {
|
||||
PLLU_LFCON_SHIFT = 4,
|
||||
PLLU_CPCON_SHIFT = 8,
|
||||
PLLU_LOCK_ENABLE = 22
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_pllx_base_ptr = (void *)(CLK_RST_BASE + 0xe0);
|
||||
enum {
|
||||
PLLX_ENABLE = 0x1 << 30
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_rst_dev_u_clr_ptr = (void *)(CLK_RST_BASE + 0x314);
|
||||
enum {
|
||||
SWR_CSITE_RST = 0x1 << 9
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_clk_enb_l_set_ptr = (void *)(CLK_RST_BASE + 0x320);
|
||||
enum {
|
||||
CLK_ENB_CPU = 0x1 << 0
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_clk_out_enb_u_set_ptr =
|
||||
(void *)(CLK_RST_BASE + 0x330);
|
||||
enum {
|
||||
CLK_ENB_CSITE = 0x1 << 9
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_cpu_softrst_ctrl2_ptr =
|
||||
(void *)(CLK_RST_BASE + 0x388);
|
||||
enum {
|
||||
CAR2PMC_CPU_ACK_WIDTH_SHIFT = 0,
|
||||
CAR2PMC_CPU_ACK_WIDTH_MASK = 0xfff << CAR2PMC_CPU_ACK_WIDTH_SHIFT
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_clk_enb_v_set_ptr = (void *)(CLK_RST_BASE + 0x440);
|
||||
enum {
|
||||
CLK_ENB_CPUG = 0x1 << 0,
|
||||
CLK_ENB_CPULP = 0x1 << 1,
|
||||
};
|
||||
|
||||
static uint32_t *clk_rst_rst_cpulp_cmplx_set_ptr =
|
||||
(void *)(CLK_RST_BASE + 0x450);
|
||||
enum {
|
||||
SET_CXRESET0 = 0x1 << 20,
|
||||
SET_CXRESET1 = 0x1 << 21
|
||||
};
|
||||
static uint32_t *clk_rst_rst_cpug_cmplx_clr_ptr =
|
||||
(void *)(CLK_RST_BASE + 0x454);
|
||||
enum {
|
||||
CLR_CPURESET0 = 0x1 << 0,
|
||||
CLR_CPURESET1 = 0x1 << 1,
|
||||
CLR_CPURESET2 = 0x1 << 2,
|
||||
CLR_CPURESET3 = 0x1 << 3,
|
||||
CLR_DBGRESET0 = 0x1 << 12,
|
||||
CLR_DBGRESET1 = 0x1 << 13,
|
||||
CLR_DBGRESET2 = 0x1 << 14,
|
||||
CLR_DBGRESET3 = 0x1 << 15,
|
||||
CLR_CORERESET0 = 0x1 << 16,
|
||||
CLR_CORERESET1 = 0x1 << 17,
|
||||
CLR_CORERESET2 = 0x1 << 18,
|
||||
CLR_CORERESET3 = 0x1 << 19,
|
||||
CLR_CXRESET0 = 0x1 << 20,
|
||||
CLR_CXRESET1 = 0x1 << 21,
|
||||
CLR_CXRESET2 = 0x1 << 22,
|
||||
CLR_CXRESET3 = 0x1 << 23,
|
||||
CLR_L2RESET = 0x1 << 24,
|
||||
CLR_NONCPURESET = 0x1 << 29,
|
||||
CLR_PRESETDBG = 0x1 << 30
|
||||
};
|
||||
|
||||
|
||||
/* Reset vector. */
|
||||
|
||||
static uint32_t *evp_cpu_reset_ptr = (void *)(TEGRA_EVP_BASE + 0x100);
|
||||
|
||||
|
||||
|
||||
/* Flow controller registers. */
|
||||
static uint32_t *flow_ctlr_halt_cop_events_ptr =
|
||||
(void *)(FLOW_CTLR_BASE + 0x4);
|
||||
enum {
|
||||
EVENT_MSEC = 0x1 << 24,
|
||||
EVENT_JTAG = 0x1 << 28,
|
||||
FLOW_MODE_SHIFT = 29,
|
||||
FLOW_MODE_STOP = 2 << FLOW_MODE_SHIFT,
|
||||
};
|
||||
|
||||
static uint32_t *flow_ctlr_cluster_control_ptr =
|
||||
(void *)(FLOW_CTLR_BASE + 0x2c);
|
||||
enum {
|
||||
FLOW_CLUSTER_ACTIVE_LP = 0x1 << 0
|
||||
};
|
||||
|
||||
static uint32_t *flow_ctlr_ram_repair_ptr =
|
||||
(void *)(FLOW_CTLR_BASE + 0x40);
|
||||
static uint32_t *flow_ctlr_ram_repair_cluster1_ptr =
|
||||
(void *)(FLOW_CTLR_BASE + 0x58);
|
||||
enum {
|
||||
RAM_REPAIR_REQ = 0x1 << 0,
|
||||
RAM_REPAIR_STS = 0x1 << 1,
|
||||
};
|
||||
|
||||
|
||||
/* Power management controller registers. */
|
||||
enum {
|
||||
PARTID_CRAIL = 0,
|
||||
PARTID_CE0 = 14,
|
||||
PARTID_C0NC = 15,
|
||||
};
|
||||
|
||||
static uint32_t *pmc_ctlr_clamp_status_ptr = (void *)(PMC_CTLR_BASE + 0x2c);
|
||||
|
||||
static uint32_t *pmc_ctlr_pwrgate_toggle_ptr = (void *)(PMC_CTLR_BASE + 0x30);
|
||||
enum {
|
||||
PWRGATE_TOGGLE_START = 0x1 << 8
|
||||
};
|
||||
|
||||
static uint32_t *pmc_ctlr_pwrgate_status_ptr = (void *)(PMC_CTLR_BASE + 0x38);
|
||||
|
||||
static uint32_t *pmc_ctlr_cpupwrgood_timer_ptr =
|
||||
(void *)(PMC_CTLR_BASE + 0xc8);
|
||||
|
||||
static uint32_t *pmc_odmdata_ptr = (void *)(PMC_CTLR_BASE + 0xa0);
|
||||
|
||||
static uint32_t *pmc_ctlr_scratch41_ptr = (void *)(PMC_CTLR_BASE + 0x140);
|
||||
static uint32_t *pmc_ctlr_secure_scratch34_ptr = (void *)(PMC_CTLR_BASE + 0x368);
|
||||
static uint32_t *pmc_ctlr_secure_scratch35_ptr = (void *)(PMC_CTLR_BASE + 0x36c);
|
||||
|
||||
static uint32_t *pmc_ctlr_osc_edpd_over_ptr = (void *)(PMC_CTLR_BASE + 0x1a4);
|
||||
enum {
|
||||
PMC_XOFS_SHIFT = 1,
|
||||
PMC_XOFS_MASK = 0x3f << PMC_XOFS_SHIFT
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Memory controller registers. */
|
||||
static uint32_t *mc_video_protect_size_mb_ptr = (void *)(MC_CTLR_BASE + 0x64c);
|
||||
|
||||
static uint32_t *mc_video_protect_reg_ctrl_ptr =
|
||||
(void *)(MC_CTLR_BASE + 0x650);
|
||||
enum {
|
||||
VIDEO_PROTECT_WRITE_ACCESS_DISABLE = 0x1 << 0,
|
||||
VIDEO_PROTECT_ALLOW_TZ_WRITE_ACCESS = 0x1 << 1
|
||||
};
|
||||
|
||||
|
||||
/* Utility functions. */
|
||||
|
||||
static inline void __attribute__((always_inline))
|
||||
__attribute__((noreturn)) halt(void)
|
||||
{
|
||||
for (;;);
|
||||
}
|
||||
|
||||
inline static uint32_t read32(const void *addr)
|
||||
{
|
||||
return *(volatile uint32_t *)addr;
|
||||
}
|
||||
|
||||
inline static void write32(uint32_t val, void *addr)
|
||||
{
|
||||
*(volatile uint32_t *)addr = val;
|
||||
}
|
||||
|
||||
inline static void setbits32(uint32_t bits, void *addr)
|
||||
{
|
||||
write32(addr, read32(addr) | bits);
|
||||
}
|
||||
|
||||
inline static void clrbits32(uint32_t bits, void *addr)
|
||||
{
|
||||
write32(addr, read32(addr) & ~bits);
|
||||
}
|
||||
|
||||
static void __attribute__((noreturn)) reset(void)
|
||||
{
|
||||
write32(clk_rst_rst_devices_l_ptr, SWR_TRIG_SYS_RST);
|
||||
halt();
|
||||
}
|
||||
|
||||
static void udelay(unsigned usecs)
|
||||
{
|
||||
uint32_t start = read32(timer_us_ptr);
|
||||
while (read32(timer_us_ptr) - start < usecs)
|
||||
;
|
||||
}
|
||||
|
||||
/* UART related defines */
|
||||
static uint32_t *uart_clk_out_enb_regs[4] = {
|
||||
(uint32_t *)0x60006010,
|
||||
(uint32_t *)0x60006010,
|
||||
(uint32_t *)0x60006014,
|
||||
(uint32_t *)0x60006018
|
||||
};
|
||||
|
||||
static uint32_t *uart_rst_devices_regs[4] = {
|
||||
(uint32_t *)0x60006004,
|
||||
(uint32_t *)0x60006004,
|
||||
(uint32_t *)0x60006008,
|
||||
(uint32_t *)0x6000600c
|
||||
};
|
||||
|
||||
static uint32_t uart_enable_mask[4] = {
|
||||
1 << 6,
|
||||
1 << 7,
|
||||
1 << 23,
|
||||
1 << 1
|
||||
};
|
||||
|
||||
static uint32_t *uart_clk_source_regs[4] = {
|
||||
(uint32_t *)0x60006178,
|
||||
(uint32_t *)0x6000617c,
|
||||
(uint32_t *)0x600061a0,
|
||||
(uint32_t *)0x600061c0,
|
||||
};
|
||||
|
||||
static uint32_t *uart_base_regs[4] = {
|
||||
(uint32_t *)0x70006000,
|
||||
(uint32_t *)0x70006040,
|
||||
(uint32_t *)0x70006200,
|
||||
(uint32_t *)0x70006300,
|
||||
};
|
||||
enum {
|
||||
UART_THR_DLAB = 0x0,
|
||||
UART_IER_DLAB = 0x1,
|
||||
UART_IIR_FCR = 0x2,
|
||||
UART_LCR = 0x3
|
||||
};
|
||||
enum {
|
||||
UART_RATE_115200 = (408000000/115200/16), /* based on 408000000 PLLP */
|
||||
FCR_TX_CLR = 0x4, /* bit 2 of FCR : clear TX FIFO */
|
||||
FCR_RX_CLR = 0x2, /* bit 1 of FCR : clear RX FIFO */
|
||||
FCR_EN_FIFO = 0x1, /* bit 0 of FCR : enable TX & RX FIFO */
|
||||
LCR_DLAB = 0x80, /* bit 7 of LCR : Divisor Latch Access Bit */
|
||||
LCR_WD_SIZE_8 = 0x3, /* bit 1:0 of LCR : word length of 8 */
|
||||
};
|
||||
|
||||
static void enable_uart(void)
|
||||
{
|
||||
uint32_t *uart_clk_enb_reg;
|
||||
uint32_t *uart_rst_reg;
|
||||
uint32_t *uart_clk_source;
|
||||
uint32_t uart_port;
|
||||
uint32_t uart_mask;
|
||||
uint32_t *uart_base;
|
||||
|
||||
/*
|
||||
* Read odmdata (stored in pmc->odmdata) to determine debug uart port.
|
||||
*
|
||||
* Bits 15-17 of odmdata contains debug uart port.
|
||||
* 0 : UARTA
|
||||
* 1 : UARTB
|
||||
* 2 : UARTC
|
||||
* 3 : UARTD
|
||||
*/
|
||||
uart_port = (read32(pmc_odmdata_ptr) >> 15) & 0x7;
|
||||
|
||||
/* Default to UARTA if uart_port is out of range */
|
||||
if (uart_port >= 4)
|
||||
uart_port = 0;
|
||||
|
||||
uart_clk_enb_reg = uart_clk_out_enb_regs[uart_port];
|
||||
uart_rst_reg = uart_rst_devices_regs[uart_port];
|
||||
uart_mask = uart_enable_mask[uart_port];
|
||||
uart_clk_source = uart_clk_source_regs[uart_port];
|
||||
uart_base = uart_base_regs[uart_port];
|
||||
|
||||
/* Enable UART clock */
|
||||
setbits32(uart_mask, uart_clk_enb_reg);
|
||||
|
||||
/* Reset and unreset UART */
|
||||
setbits32(uart_mask, uart_rst_reg);
|
||||
clrbits32(uart_mask, uart_rst_reg);
|
||||
|
||||
/* Program UART clock source: PLLP (408000000) */
|
||||
write32(uart_clk_source, 0);
|
||||
|
||||
/* Program 115200n8 to the uart port */
|
||||
/* baud-rate of 115200 */
|
||||
write32((uart_base + UART_LCR), LCR_DLAB);
|
||||
write32((uart_base + UART_THR_DLAB), (UART_RATE_115200 & 0xff));
|
||||
write32((uart_base + UART_IER_DLAB), (UART_RATE_115200 >> 8));
|
||||
/* 8-bit and no parity */
|
||||
write32((uart_base + UART_LCR), LCR_WD_SIZE_8);
|
||||
/* enable and clear RX/TX FIFO */
|
||||
write32((uart_base + UART_IIR_FCR),
|
||||
(FCR_TX_CLR + FCR_RX_CLR + FCR_EN_FIFO));
|
||||
}
|
||||
|
||||
/* Accessors. */
|
||||
|
||||
static uint32_t get_wakeup_vector(void)
|
||||
{
|
||||
return read32(pmc_ctlr_scratch41_ptr);
|
||||
}
|
||||
|
||||
static unsigned get_osc_freq(void)
|
||||
{
|
||||
return (read32(clk_rst_osc_ctrl_ptr) & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
}
|
||||
|
||||
|
||||
/* Jtag configuration. */
|
||||
|
||||
static void enable_jtag(void)
|
||||
{
|
||||
write32(misc_pp_config_ctl_ptr, PP_CONFIG_CTL_JTAG);
|
||||
}
|
||||
|
||||
/* Clock configuration. */
|
||||
|
||||
static void config_oscillator(void)
|
||||
{
|
||||
// Read oscillator drive strength from OSC_EDPD_OVER.XOFS and copy
|
||||
// to OSC_CTRL.XOFS and set XOE.
|
||||
uint32_t xofs = (read32(pmc_ctlr_osc_edpd_over_ptr) &
|
||||
PMC_XOFS_MASK) >> PMC_XOFS_SHIFT;
|
||||
|
||||
uint32_t osc_ctrl = read32(clk_rst_osc_ctrl_ptr);
|
||||
osc_ctrl &= ~OSC_XOFS_MASK;
|
||||
osc_ctrl |= (xofs << OSC_XOFS_SHIFT);
|
||||
osc_ctrl |= OSC_XOE;
|
||||
write32(clk_rst_osc_ctrl_ptr, osc_ctrl);
|
||||
}
|
||||
|
||||
static void config_pllu(void)
|
||||
{
|
||||
// Figure out what parameters to use for PLLU.
|
||||
uint32_t divm, divn, cpcon, lfcon;
|
||||
switch (get_osc_freq()) {
|
||||
case OSC_FREQ_12:
|
||||
case OSC_FREQ_48:
|
||||
divm = 0x0c;
|
||||
divn = 0x3c0;
|
||||
cpcon = 0x0c;
|
||||
lfcon = 0x02;
|
||||
break;
|
||||
case OSC_FREQ_16P8:
|
||||
divm = 0x07;
|
||||
divn = 0x190;
|
||||
cpcon = 0x05;
|
||||
lfcon = 0x02;
|
||||
break;
|
||||
case OSC_FREQ_19P2:
|
||||
case OSC_FREQ_38P4:
|
||||
divm = 0x04;
|
||||
divn = 0xc8;
|
||||
cpcon = 0x03;
|
||||
lfcon = 0x02;
|
||||
break;
|
||||
case OSC_FREQ_26:
|
||||
divm = 0x1a;
|
||||
divn = 0x3c0;
|
||||
cpcon = 0x0c;
|
||||
lfcon = 0x02;
|
||||
break;
|
||||
default:
|
||||
// Map anything that's not recognized to 13MHz.
|
||||
divm = 0x0d;
|
||||
divn = 0x3c0;
|
||||
cpcon = 0x0c;
|
||||
lfcon = 0x02;
|
||||
}
|
||||
|
||||
// Configure PLLU.
|
||||
uint32_t base = PLLU_BYPASS | PLLU_OVERRIDE |
|
||||
(divn << PLLU_DIVN_SHIFT) | (divm << PLLU_DIVM_SHIFT);
|
||||
write32(clk_rst_pllu_base_ptr, base);
|
||||
uint32_t misc = (cpcon << PLLU_CPCON_SHIFT) |
|
||||
(lfcon << PLLU_LFCON_SHIFT);
|
||||
write32(clk_rst_pllu_misc_ptr, misc);
|
||||
|
||||
// Enable PLLU.
|
||||
base &= ~PLLU_BYPASS;
|
||||
base |= PLLU_ENABLE;
|
||||
write32(clk_rst_pllu_base_ptr, base);
|
||||
misc |= PLLU_LOCK_ENABLE;
|
||||
write32(clk_rst_pllu_misc_ptr, misc);
|
||||
}
|
||||
|
||||
static void enable_cpu_clocks(void)
|
||||
{
|
||||
// Enable the CPU complex clock.
|
||||
write32(clk_rst_clk_enb_l_set_ptr, CLK_ENB_CPU);
|
||||
write32(clk_rst_clk_enb_v_set_ptr, CLK_ENB_CPUG | CLK_ENB_CPULP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Function unit configuration. */
|
||||
|
||||
static void config_core_sight(void)
|
||||
{
|
||||
// Enable the CoreSight clock.
|
||||
write32(clk_rst_clk_out_enb_u_set_ptr, CLK_ENB_CSITE);
|
||||
|
||||
/*
|
||||
* De-assert CoreSight reset.
|
||||
* NOTE: We're leaving the CoreSight clock on the oscillator for
|
||||
* now. It will be restored to its original clock source
|
||||
* when the CPU-side restoration code runs.
|
||||
*/
|
||||
write32(clk_rst_rst_dev_u_clr_ptr, SWR_CSITE_RST);
|
||||
}
|
||||
|
||||
|
||||
/* Resets. */
|
||||
|
||||
static void clear_cpu_resets(void)
|
||||
{
|
||||
/* Hold CPU1 in reset */
|
||||
setbits32(SET_CXRESET1, clk_rst_rst_cpulp_cmplx_set_ptr);
|
||||
|
||||
write32(clk_rst_rst_cpug_cmplx_clr_ptr,
|
||||
CLR_NONCPURESET | CLR_L2RESET | CLR_PRESETDBG);
|
||||
|
||||
write32(clk_rst_rst_cpug_cmplx_clr_ptr,
|
||||
CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* RAM repair */
|
||||
|
||||
void ram_repair(void)
|
||||
{
|
||||
// Request Cluster0 RAM repair.
|
||||
setbits32(RAM_REPAIR_REQ, flow_ctlr_ram_repair_ptr);
|
||||
// Poll for Cluster0 RAM repair status.
|
||||
while (!(read32(flow_ctlr_ram_repair_ptr) & RAM_REPAIR_STS))
|
||||
;
|
||||
|
||||
// Request Cluster1 RAM repair.
|
||||
setbits32(RAM_REPAIR_REQ, flow_ctlr_ram_repair_cluster1_ptr);
|
||||
// Poll for Cluster1 RAM repair status.
|
||||
while (!(read32(flow_ctlr_ram_repair_cluster1_ptr) & RAM_REPAIR_STS))
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
/* Power. */
|
||||
|
||||
static void power_on_partition(unsigned id)
|
||||
{
|
||||
uint32_t bit = 0x1 << id;
|
||||
if (!(read32(pmc_ctlr_pwrgate_status_ptr) & bit)) {
|
||||
// Partition is not on. Turn it on.
|
||||
write32(pmc_ctlr_pwrgate_toggle_ptr,
|
||||
id | PWRGATE_TOGGLE_START);
|
||||
|
||||
// Wait until the partition is powerd on.
|
||||
while (!(read32(pmc_ctlr_pwrgate_status_ptr) & bit))
|
||||
;
|
||||
|
||||
// Wait until clamp is off.
|
||||
while (read32(pmc_ctlr_clamp_status_ptr) & bit)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static void power_on_main_cpu(void)
|
||||
{
|
||||
/*
|
||||
* Reprogram PMC_CPUPWRGOOD_TIMER register:
|
||||
*
|
||||
* XXX This is a fragile assumption. XXX
|
||||
* The kernel prepares PMC_CPUPWRGOOD_TIMER based on a 32768Hz clock.
|
||||
* Note that PMC_CPUPWRGOOD_TIMER is running at pclk.
|
||||
*
|
||||
* We need to reprogram PMC_CPUPWRGOOD_TIMER based on the current pclk
|
||||
* which is at 204Mhz (pclk = sclk = pllp_out2) after BootROM. Multiply
|
||||
* PMC_CPUPWRGOOD_TIMER by 204M / 32K.
|
||||
*
|
||||
* Save the original PMC_CPUPWRGOOD_TIMER register which we need to
|
||||
* restore after the CPU is powered up.
|
||||
*/
|
||||
uint32_t orig_timer = read32(pmc_ctlr_cpupwrgood_timer_ptr);
|
||||
|
||||
write32(pmc_ctlr_cpupwrgood_timer_ptr,
|
||||
orig_timer * (204000000 / 32768));
|
||||
|
||||
power_on_partition(PARTID_CRAIL);
|
||||
power_on_partition(PARTID_C0NC);
|
||||
power_on_partition(PARTID_CE0);
|
||||
|
||||
// Restore the original PMC_CPUPWRGOOD_TIMER.
|
||||
write32(pmc_ctlr_cpupwrgood_timer_ptr, orig_timer);
|
||||
}
|
||||
|
||||
|
||||
static void aarch64_trampoline(void)
|
||||
{
|
||||
uint32_t val = 3; /* bit1: to warm reset; bit0: AARCH64*/
|
||||
|
||||
asm volatile ("mcr p15, 0, %0, c12, c0, 2" : : "r" (val));
|
||||
|
||||
/* unreachable */
|
||||
halt();
|
||||
}
|
||||
|
||||
|
||||
/* Entry point. */
|
||||
|
||||
void lp0_resume(void)
|
||||
{
|
||||
// If not on the AVP, reset.
|
||||
if (read32(up_tag_ptr) != UP_TAG_AVP)
|
||||
reset();
|
||||
|
||||
// Enable JTAG
|
||||
enable_jtag();
|
||||
|
||||
config_oscillator();
|
||||
|
||||
// Program SUPER_CCLK_DIVIDER.
|
||||
write32(clk_rst_super_cclk_div_ptr, SUPER_CDIV_ENB);
|
||||
|
||||
config_core_sight();
|
||||
|
||||
enable_uart();
|
||||
|
||||
config_pllu();
|
||||
|
||||
/*
|
||||
* Set the CPU reset vector.
|
||||
*
|
||||
* T210 always resets to AARCH32 and SW needs to write RMR_EL3
|
||||
* to bootstrap into AARCH64.
|
||||
*/
|
||||
write32(pmc_ctlr_secure_scratch34_ptr, get_wakeup_vector());
|
||||
write32(pmc_ctlr_secure_scratch35_ptr, 0);
|
||||
write32(evp_cpu_reset_ptr, (uint32_t)aarch64_trampoline);
|
||||
|
||||
// Select CPU complex clock source.
|
||||
write32(clk_rst_cclk_burst_policy_ptr, CCLK_PLLP_BURST_POLICY);
|
||||
|
||||
// Disable PLLX since it isn't used as CPU clock source.
|
||||
clrbits32(PLLX_ENABLE, clk_rst_pllx_base_ptr);
|
||||
|
||||
// Set CAR2PMC_CPU_ACK_WIDTH to 408.
|
||||
uint32_t ack_width = read32(clk_rst_cpu_softrst_ctrl2_ptr);
|
||||
ack_width &= ~CAR2PMC_CPU_ACK_WIDTH_MASK;
|
||||
ack_width |= 408 << CAR2PMC_CPU_ACK_WIDTH_SHIFT;
|
||||
write32(clk_rst_cpu_softrst_ctrl2_ptr, ack_width);
|
||||
|
||||
// Disable VPR.
|
||||
write32(mc_video_protect_size_mb_ptr, 0);
|
||||
write32(mc_video_protect_reg_ctrl_ptr,
|
||||
VIDEO_PROTECT_WRITE_ACCESS_DISABLE);
|
||||
|
||||
enable_cpu_clocks();
|
||||
|
||||
power_on_main_cpu();
|
||||
|
||||
// Perform ram repair after cpu is powered on.
|
||||
ram_repair();
|
||||
|
||||
clear_cpu_resets();
|
||||
|
||||
// Halt the AVP.
|
||||
while (1)
|
||||
write32(flow_ctlr_halt_cop_events_ptr,
|
||||
FLOW_MODE_STOP | EVENT_JTAG);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Header. */
|
||||
|
||||
extern uint8_t blob_data;
|
||||
extern uint8_t blob_data_size;
|
||||
extern uint8_t blob_total_size;
|
||||
|
||||
struct lp0_header {
|
||||
uint32_t length_insecure; // Insecure total length.
|
||||
uint32_t reserved[3];
|
||||
uint8_t rsa_modulus[256]; // RSA key modulus.
|
||||
uint8_t aes_signature[16]; // AES signature.
|
||||
uint8_t rsa_signature[256]; // RSA-PSS signature.
|
||||
uint8_t random_aes_block[16]; // Random data, may be zero.
|
||||
uint32_t length_secure; // Secure total length.
|
||||
uint32_t destination; // Where to load the blob in iRAM.
|
||||
uint32_t entry_point; // Entry point for the blob.
|
||||
uint32_t code_length; // Length of just the data.
|
||||
} __attribute__((packed));
|
||||
|
||||
struct lp0_header header __attribute__((section(".header"))) =
|
||||
{
|
||||
.length_insecure = (uintptr_t)&blob_total_size,
|
||||
.length_secure = (uintptr_t)&blob_total_size,
|
||||
.destination = (uintptr_t)&blob_data,
|
||||
.entry_point = (uintptr_t)&lp0_resume,
|
||||
.code_length = (uintptr_t)&blob_data_size
|
||||
};
|
73
src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.ld
Normal file
73
src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.ld
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* We use ELF as output format. So that we can debug the code in some form. */
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
to_load PT_LOAD;
|
||||
}
|
||||
|
||||
ENTRY(lp0_resume)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x40020000 - 0x240;
|
||||
|
||||
/*
|
||||
* The lp0 blob header is built as a static data structure and put
|
||||
* in the .header section.
|
||||
*/
|
||||
.header_start = .;
|
||||
.header . : {
|
||||
*(.header);
|
||||
} : to_load = 0xff
|
||||
.header_end = .;
|
||||
|
||||
. = 0x40020000;
|
||||
|
||||
/* The actual lp0 blob code. */
|
||||
.data_start = .;
|
||||
.data . : {
|
||||
*(.text);
|
||||
*(.text.*);
|
||||
*(.rodata);
|
||||
*(.rodata.*);
|
||||
*(.data);
|
||||
*(.data.*);
|
||||
*(.bss);
|
||||
*(.bss.*);
|
||||
*(.sbss);
|
||||
*(.sbss.*);
|
||||
. = ALIGN(16);
|
||||
}
|
||||
.data_end = .;
|
||||
|
||||
/* Some values we need in the header. */
|
||||
blob_data = .data_start;
|
||||
blob_data_size = .data_end - .data_start;
|
||||
blob_total_size = .data_end - .header_start;
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.note)
|
||||
*(.comment.*)
|
||||
*(.note.*)
|
||||
*(.ARM.*)
|
||||
}
|
||||
}
|
55
src/soc/nvidia/tegra210/maincpu.S
Normal file
55
src/soc/nvidia/tegra210/maincpu.S
Normal 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
|
92
src/soc/nvidia/tegra210/mipi-phy.c
Normal file
92
src/soc/nvidia/tegra210/mipi-phy.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include <console/console.h>
|
||||
#include <arch/io.h>
|
||||
#include <stdint.h>
|
||||
#include <lib.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <device/device.h>
|
||||
#include <soc/nvidia/tegra/types.h>
|
||||
#include <soc/display.h>
|
||||
#include <soc/mipi_dsi.h>
|
||||
#include <soc/mipi_display.h>
|
||||
#include <soc/tegra_dsi.h>
|
||||
#include <soc/mipi-phy.h>
|
||||
|
||||
int mipi_dphy_set_timing(struct tegra_dsi *dsi)
|
||||
{
|
||||
|
||||
u32 freq = (dsi->clk_rate * 2) / 1000000;
|
||||
|
||||
u32 thsdexit = (DSI_PHY_TIMING_DIV(120, (freq)));
|
||||
u32 thstrial = (((3) + (DSI_PHY_TIMING_DIV((DSI_THSTRAIL_VAL(freq)),
|
||||
freq))));
|
||||
u32 tdatzero = DSI_PHY_TIMING_DIV(((145) + (5 * (DSI_TBIT(freq)))),
|
||||
(freq));
|
||||
u32 thsprepare = DSI_PHY_TIMING_DIV((65 + (5*(DSI_TBIT(freq)))), freq);
|
||||
u32 tclktrial = (DSI_PHY_TIMING_DIV(80, freq));
|
||||
u32 tclkpost = ((DSI_PHY_TIMING_DIV(((70) + ((52) * (DSI_TBIT(freq)))),
|
||||
freq)));
|
||||
u32 tclkzero = (DSI_PHY_TIMING_DIV(260, freq));
|
||||
u32 ttlpx = (DSI_PHY_TIMING_DIV(60, freq)) ;
|
||||
u32 tclkprepare = (DSI_PHY_TIMING_DIV(60, freq));
|
||||
u32 tclkpre = 1; //min = 8*UI per mipi spec, tclk_pre=0 should be ok, but using 1 value
|
||||
u32 twakeup = 0x7F; //min = 1ms
|
||||
|
||||
u32 ttaget;
|
||||
u32 ttassure;
|
||||
u32 ttago;
|
||||
u32 value;
|
||||
|
||||
if (!ttlpx) {
|
||||
ttaget = 5;
|
||||
ttassure = 2;
|
||||
ttago = 4;
|
||||
} else {
|
||||
ttaget = 5 * ttlpx;
|
||||
ttassure = 2 * ttlpx;
|
||||
ttago = 4 * ttlpx;
|
||||
}
|
||||
|
||||
value = (thsdexit << 24) |
|
||||
(thstrial << 16) |
|
||||
(tdatzero << 8) |
|
||||
(thsprepare << 0);
|
||||
tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_0);
|
||||
|
||||
value = (tclktrial << 24) |
|
||||
(tclkpost << 16) |
|
||||
(tclkzero << 8) |
|
||||
(ttlpx << 0);
|
||||
tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_1);
|
||||
|
||||
value = (tclkprepare << 16) |
|
||||
(tclkpre << 8) |
|
||||
(twakeup << 0);
|
||||
tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_2);
|
||||
|
||||
value = (ttaget << 16) |
|
||||
(ttassure << 8) |
|
||||
(ttago << 0),
|
||||
tegra_dsi_writel(dsi, value, DSI_BTA_TIMING);
|
||||
return 0;
|
||||
}
|
204
src/soc/nvidia/tegra210/mipi.c
Normal file
204
src/soc/nvidia/tegra210/mipi.c
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include <console/console.h>
|
||||
#include <arch/io.h>
|
||||
#include <stdint.h>
|
||||
#include <lib.h>
|
||||
#include <stdlib.h>
|
||||
#include <delay.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <device/device.h>
|
||||
#include <soc/nvidia/tegra/types.h>
|
||||
#include <soc/display.h>
|
||||
#include <soc/mipi_dsi.h>
|
||||
#include <soc/tegra_dsi.h>
|
||||
#include "jdi_25x18_display/panel-jdi-lpm102a188a.h"
|
||||
|
||||
static unsigned long dsi_pads[] = {
|
||||
0x0c0, /* DSIA channel A & B pads */
|
||||
0x300, /* DSIB channel A & B pads */
|
||||
};
|
||||
|
||||
static struct tegra_mipi mipi_data = {
|
||||
.regs = (void *)TEGRA_MIPI_CAL_BASE,
|
||||
};
|
||||
|
||||
static inline unsigned long tegra_mipi_readl(struct tegra_mipi *mipi,
|
||||
unsigned long reg)
|
||||
{
|
||||
return read32(mipi->regs + (reg << 2));
|
||||
}
|
||||
|
||||
static inline void tegra_mipi_writel(struct tegra_mipi *mipi,
|
||||
unsigned long value, unsigned long reg)
|
||||
{
|
||||
write32(mipi->regs + (reg << 2), value);
|
||||
}
|
||||
|
||||
static const struct tegra_mipi_pad tegra210_mipi_pads[] = {
|
||||
{ .data = MIPI_CAL_CONFIG_CSIA, .clk = 0 },
|
||||
{ .data = MIPI_CAL_CONFIG_CSIB, .clk = 0 },
|
||||
{ .data = MIPI_CAL_CONFIG_CSIC, .clk = 0 },
|
||||
{ .data = MIPI_CAL_CONFIG_CSID, .clk = 0 },
|
||||
{ .data = MIPI_CAL_CONFIG_CSIE, .clk = 0 },
|
||||
{ .data = MIPI_CAL_CONFIG_CSIF, .clk = 0 },
|
||||
{ .data = MIPI_CAL_CONFIG_DSIA, .clk = MIPI_CAL_CONFIG_DSIA_CLK },
|
||||
{ .data = MIPI_CAL_CONFIG_DSIB, .clk = MIPI_CAL_CONFIG_DSIB_CLK },
|
||||
{ .data = MIPI_CAL_CONFIG_DSIC, .clk = MIPI_CAL_CONFIG_DSIC_CLK },
|
||||
{ .data = MIPI_CAL_CONFIG_DSID, .clk = MIPI_CAL_CONFIG_DSID_CLK },
|
||||
};
|
||||
|
||||
static const struct tegra_mipi_soc tegra210_mipi_soc = {
|
||||
.has_clk_lane = 1,
|
||||
.pads = tegra210_mipi_pads,
|
||||
.num_pads = ARRAY_SIZE(tegra210_mipi_pads),
|
||||
.clock_enable_override = 1,
|
||||
.needs_vclamp_ref = 0,
|
||||
.pad_drive_down_ref = 0x0,
|
||||
.pad_drive_up_ref = 0x3,
|
||||
.pad_vclamp_level = 0x1,
|
||||
.pad_vauxp_level = 0x1,
|
||||
.hspdos = 0x0,
|
||||
.hspuos = 0x2,
|
||||
.termos = 0x0,
|
||||
.hsclkpdos = 0x0,
|
||||
.hsclkpuos = 0x2,
|
||||
};
|
||||
|
||||
struct tegra_mipi_device *tegra_mipi_request(struct tegra_mipi_device *device,
|
||||
int device_index)
|
||||
{
|
||||
device->mipi = &mipi_data;
|
||||
device->mipi->soc = &tegra210_mipi_soc;
|
||||
device->pads = dsi_pads[device_index];
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static int tegra_mipi_wait(struct tegra_mipi *mipi)
|
||||
{
|
||||
u32 poll_interval_us = 1000;
|
||||
u32 timeout_us = 250 * 1000;
|
||||
unsigned long value;
|
||||
|
||||
do {
|
||||
value = tegra_mipi_readl(mipi, MIPI_CAL_STATUS);
|
||||
if ((value & MIPI_CAL_STATUS_ACTIVE) == 0 &&
|
||||
(value & MIPI_CAL_STATUS_DONE) != 0)
|
||||
return 0;
|
||||
|
||||
if (timeout_us > poll_interval_us)
|
||||
timeout_us -= poll_interval_us;
|
||||
else
|
||||
break;
|
||||
|
||||
udelay(poll_interval_us);
|
||||
} while (1);
|
||||
|
||||
printk(BIOS_ERR, "%s: ERROR: timeout\n", __func__);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
int tegra_mipi_calibrate(struct tegra_mipi_device *device)
|
||||
{
|
||||
const struct tegra_mipi_soc *soc = device->mipi->soc;
|
||||
unsigned int i;
|
||||
u32 value;
|
||||
int err;
|
||||
|
||||
value = tegra_mipi_readl(device->mipi, MIPI_CAL_BIAS_PAD_CFG0);
|
||||
value &= ~MIPI_CAL_BIAS_PAD_PDVCLAMP;
|
||||
|
||||
if (soc->needs_vclamp_ref)
|
||||
value |= MIPI_CAL_BIAS_PAD_E_VCLAMP_REF;
|
||||
|
||||
tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG0);
|
||||
|
||||
value = MIPI_CAL_BIAS_PAD_DRV_DN_REF(soc->pad_drive_down_ref) |
|
||||
MIPI_CAL_BIAS_PAD_DRV_UP_REF(soc->pad_drive_up_ref);
|
||||
tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG1);
|
||||
|
||||
value = tegra_mipi_readl(device->mipi, MIPI_CAL_BIAS_PAD_CFG2);
|
||||
value &= ~MIPI_CAL_BIAS_PAD_PDVREG;
|
||||
tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG2);
|
||||
|
||||
value = tegra_mipi_readl(device->mipi, MIPI_CAL_BIAS_PAD_CFG2);
|
||||
value &= ~MIPI_CAL_BIAS_PAD_VCLAMP(0x7);
|
||||
value &= ~MIPI_CAL_BIAS_PAD_VAUXP(0x7);
|
||||
value |= MIPI_CAL_BIAS_PAD_VCLAMP(soc->pad_vclamp_level);
|
||||
value |= MIPI_CAL_BIAS_PAD_VAUXP(soc->pad_vauxp_level);
|
||||
tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG2);
|
||||
|
||||
for (i = 0; i < soc->num_pads; i++) {
|
||||
u32 clk = 0, data = 0;
|
||||
|
||||
if (device->pads & BIT(i)) {
|
||||
data = MIPI_CAL_CONFIG_SELECT |
|
||||
MIPI_CAL_CONFIG_HSPDOS(soc->hspdos) |
|
||||
MIPI_CAL_CONFIG_HSPUOS(soc->hspuos) |
|
||||
MIPI_CAL_CONFIG_TERMOS(soc->termos);
|
||||
clk = MIPI_CAL_CONFIG_SELECT |
|
||||
MIPI_CAL_CONFIG_HSCLKPDOSD(soc->hsclkpdos) |
|
||||
MIPI_CAL_CONFIG_HSCLKPUOSD(soc->hsclkpuos);
|
||||
}
|
||||
|
||||
tegra_mipi_writel(device->mipi, data, soc->pads[i].data);
|
||||
|
||||
if (soc->has_clk_lane && soc->pads[i].clk != 0)
|
||||
tegra_mipi_writel(device->mipi, clk, soc->pads[i].clk);
|
||||
}
|
||||
|
||||
value = tegra_mipi_readl(device->mipi, MIPI_CAL_CTRL);
|
||||
value &= ~MIPI_CAL_CTRL_NOISE_FILTER(0xf);
|
||||
value &= ~MIPI_CAL_CTRL_PRESCALE(0x3);
|
||||
value |= MIPI_CAL_CTRL_NOISE_FILTER(0xa);
|
||||
value |= MIPI_CAL_CTRL_PRESCALE(0x2);
|
||||
|
||||
if (!soc->clock_enable_override)
|
||||
value &= ~MIPI_CAL_CTRL_CLKEN_OVR;
|
||||
else
|
||||
value |= MIPI_CAL_CTRL_CLKEN_OVR;
|
||||
|
||||
tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);
|
||||
|
||||
/* clear any pending status bits */
|
||||
value = tegra_mipi_readl(device->mipi, MIPI_CAL_STATUS);
|
||||
tegra_mipi_writel(device->mipi, value, MIPI_CAL_STATUS);
|
||||
|
||||
value = tegra_mipi_readl(device->mipi, MIPI_CAL_CTRL);
|
||||
value |= MIPI_CAL_CTRL_START;
|
||||
tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);
|
||||
|
||||
err = tegra_mipi_wait(device->mipi);
|
||||
if (err < 0)
|
||||
printk(BIOS_ERR, "failed to calibrate MIPI pads: %d\n", err);
|
||||
else
|
||||
printk(BIOS_INFO, "MIPI calibration done\n");
|
||||
|
||||
value = tegra_mipi_readl(device->mipi, MIPI_CAL_BIAS_PAD_CFG0);
|
||||
|
||||
if (soc->needs_vclamp_ref)
|
||||
value &= ~MIPI_CAL_BIAS_PAD_E_VCLAMP_REF;
|
||||
|
||||
value |= MIPI_CAL_BIAS_PAD_PDVCLAMP;
|
||||
tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG0);
|
||||
|
||||
return err;
|
||||
}
|
431
src/soc/nvidia/tegra210/mipi_dsi.c
Normal file
431
src/soc/nvidia/tegra210/mipi_dsi.c
Normal file
@ -0,0 +1,431 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* MIPI DSI Bus
|
||||
*
|
||||
* Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd.
|
||||
* Andrzej Hajda <a.hajda@samsung.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <console/console.h>
|
||||
#include <arch/io.h>
|
||||
#include <stdint.h>
|
||||
#include <lib.h>
|
||||
#include <stdlib.h>
|
||||
#include <delay.h>
|
||||
#include <string.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <device/device.h>
|
||||
#include <soc/nvidia/tegra/types.h>
|
||||
#include <soc/display.h>
|
||||
#include <soc/mipi_dsi.h>
|
||||
#include <soc/mipi_display.h>
|
||||
#include <soc/tegra_dsi.h>
|
||||
|
||||
struct mipi_dsi_device mipi_dsi_device_data[NUM_DSI] = {
|
||||
{
|
||||
.master = NULL,
|
||||
.slave = &mipi_dsi_device_data[DSI_B],
|
||||
},
|
||||
{
|
||||
.master = &mipi_dsi_device_data[DSI_A],
|
||||
.slave = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mipi_dsi_device *
|
||||
mipi_dsi_device_alloc(struct mipi_dsi_host *host)
|
||||
{
|
||||
static int index = 0;
|
||||
struct mipi_dsi_device *dsi;
|
||||
|
||||
if (index >= NUM_DSI)
|
||||
return (void *)-EPTR;
|
||||
|
||||
dsi = &mipi_dsi_device_data[index++];
|
||||
dsi->host = host;
|
||||
return dsi;
|
||||
}
|
||||
|
||||
static struct mipi_dsi_device *
|
||||
of_mipi_dsi_device_add(struct mipi_dsi_host *host)
|
||||
{
|
||||
struct mipi_dsi_device *dsi;
|
||||
u32 reg = 0;
|
||||
|
||||
dsi = mipi_dsi_device_alloc(host);
|
||||
if (IS_ERR_PTR(dsi)) {
|
||||
printk(BIOS_ERR, "failed to allocate DSI device\n");
|
||||
return dsi;
|
||||
}
|
||||
|
||||
dsi->channel = reg;
|
||||
host->dev = (void *)dsi;
|
||||
|
||||
return dsi;
|
||||
}
|
||||
|
||||
int mipi_dsi_host_register(struct mipi_dsi_host *host)
|
||||
{
|
||||
of_mipi_dsi_device_add(host);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_attach - attach a DSI device to its DSI host
|
||||
* @dsi: DSI peripheral
|
||||
*/
|
||||
int mipi_dsi_attach(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
|
||||
|
||||
if (!ops || !ops->attach)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->attach(dsi->host, dsi);
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_detach - detach a DSI device from its DSI host
|
||||
* @dsi: DSI peripheral
|
||||
*/
|
||||
int mipi_dsi_detach(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
|
||||
|
||||
if (!ops || !ops->detach)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->detach(dsi->host, dsi);
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_enslave() - use a MIPI DSI peripheral as slave for dual-channel
|
||||
* operation
|
||||
* @master: master DSI peripheral device
|
||||
* @slave: slave DSI peripheral device
|
||||
*
|
||||
* Return: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int mipi_dsi_enslave(struct mipi_dsi_device *master,
|
||||
struct mipi_dsi_device *slave)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
slave->master = master;
|
||||
master->slave = slave;
|
||||
|
||||
if (master->ops && master->ops->enslave)
|
||||
err = master->ops->enslave(master, slave);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_liberate() - stop using a MIPI DSI peripheral as slave for dual-
|
||||
* channel operation
|
||||
* @master: master DSI peripheral device
|
||||
* @slave: slave DSI peripheral device
|
||||
*
|
||||
* Return: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int mipi_dsi_liberate(struct mipi_dsi_device *master,
|
||||
struct mipi_dsi_device *slave)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (master->ops && master->ops->liberate)
|
||||
err = master->ops->liberate(master, slave);
|
||||
|
||||
master->slave = NULL;
|
||||
slave->master = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_dcs_write() - send DCS write command
|
||||
* @dsi: DSI peripheral device
|
||||
* @cmd: DCS command
|
||||
* @data: buffer containing the command payload
|
||||
* @len: command payload length
|
||||
*
|
||||
* This function will automatically choose the right data type depending on
|
||||
* the command payload length.
|
||||
*
|
||||
* Return: The number of bytes successfully transmitted or a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
struct mipi_dsi_msg msg;
|
||||
ssize_t err;
|
||||
size_t size;
|
||||
|
||||
u8 buffer[MAX_DSI_HOST_FIFO_DEPTH + 4];
|
||||
u8 *tx = buffer;
|
||||
|
||||
if (len > MAX_DSI_HOST_FIFO_DEPTH) {
|
||||
printk(BIOS_ERR, "%s: Error: too large payload length: %zu\n",
|
||||
__func__, len);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
unsigned int offset = 0;
|
||||
|
||||
/*
|
||||
* DCS long write packets contain the word count in the header
|
||||
* bytes 1 and 2 and have a payload containing the DCS command
|
||||
* byte folowed by word count minus one bytes.
|
||||
*
|
||||
* DCS short write packets encode the DCS command and up to
|
||||
* one parameter in header bytes 1 and 2.
|
||||
*/
|
||||
if (len > 1)
|
||||
size = 3 + len;
|
||||
else
|
||||
size = 1 + len;
|
||||
|
||||
/* write word count to header for DCS long write packets */
|
||||
if (len > 1) {
|
||||
tx[offset++] = ((1 + len) >> 0) & 0xff;
|
||||
tx[offset++] = ((1 + len) >> 8) & 0xff;
|
||||
}
|
||||
|
||||
/* write the DCS command byte followed by the payload */
|
||||
tx[offset++] = cmd;
|
||||
memcpy(tx + offset, data, len);
|
||||
} else {
|
||||
tx = &cmd;
|
||||
size = 1;
|
||||
}
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.flags = MIPI_DSI_MSG_USE_LPM;
|
||||
msg.channel = dsi->channel;
|
||||
msg.tx_len = size;
|
||||
msg.tx_buf = tx;
|
||||
|
||||
switch (len) {
|
||||
case 0:
|
||||
msg.type = MIPI_DSI_DCS_SHORT_WRITE;
|
||||
break;
|
||||
case 1:
|
||||
msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
|
||||
break;
|
||||
default:
|
||||
msg.type = MIPI_DSI_DCS_LONG_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
err = dsi->host->ops->transfer(dsi->host, &msg);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display
|
||||
* module
|
||||
* @dsi: DSI peripheral device
|
||||
*
|
||||
* Return: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
ssize_t err;
|
||||
|
||||
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_dcs_set_display_on() - start displaying the image data on the
|
||||
* display device
|
||||
* @dsi: DSI peripheral device
|
||||
*
|
||||
* Return: 0 on success or a negative error code on failure
|
||||
*/
|
||||
int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
ssize_t err;
|
||||
|
||||
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_dcs_set_column_address() - define the column extent of the frame
|
||||
* memory accessed by the host processor
|
||||
* @dsi: DSI peripheral device
|
||||
* @start: first column of frame memory
|
||||
* @end: last column of frame memory
|
||||
*
|
||||
* Return: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
|
||||
u16 end)
|
||||
{
|
||||
u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
|
||||
ssize_t err;
|
||||
|
||||
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload,
|
||||
sizeof(payload));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_dcs_set_page_address() - define the page extent of the frame
|
||||
* memory accessed by the host processor
|
||||
* @dsi: DSI peripheral device
|
||||
* @start: first page of frame memory
|
||||
* @end: last page of frame memory
|
||||
*
|
||||
* Return: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
|
||||
u16 end)
|
||||
{
|
||||
u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
|
||||
ssize_t err;
|
||||
|
||||
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload,
|
||||
sizeof(payload));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
|
||||
* output signal on the TE signal line.
|
||||
* @dsi: DSI peripheral device
|
||||
* @mode: the Tearing Effect Output Line mode
|
||||
*
|
||||
* Return: 0 on success or a negative error code on failure
|
||||
*/
|
||||
int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
|
||||
enum mipi_dsi_dcs_tear_mode mode)
|
||||
{
|
||||
u8 value = mode;
|
||||
ssize_t err;
|
||||
|
||||
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value,
|
||||
sizeof(value));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
|
||||
* data used by the interface
|
||||
* @dsi: DSI peripheral device
|
||||
* @format: pixel format
|
||||
*
|
||||
* Return: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
|
||||
{
|
||||
ssize_t err;
|
||||
|
||||
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format,
|
||||
sizeof(format));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dsi_dcs_set_address_mode() - sets the data order for forward transfers
|
||||
* from the host to the peripheral
|
||||
* @dsi: DSI peripheral device
|
||||
* @reverse_page_address: reverses the page addressing to bottom->top
|
||||
* @reverse_col_address: reverses the column addressing to right->left
|
||||
* @reverse_page_col_address: reverses the page/column addressing order
|
||||
* @refresh_from_bottom: refresh the display bottom to top
|
||||
* @reverse_rgb: send pixel data bgr instead of rgb
|
||||
* @latch_right_to_left: latch the incoming display data right to left
|
||||
* @flip_horizontal: flip the image horizontally, left to right
|
||||
* @flip_vertical: flip the image vertically, top to bottom
|
||||
*
|
||||
* Return: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int mipi_dsi_dcs_set_address_mode(struct mipi_dsi_device *dsi,
|
||||
bool reverse_page_address,
|
||||
bool reverse_col_address,
|
||||
bool reverse_page_col_address,
|
||||
bool refresh_from_bottom,
|
||||
bool reverse_rgb,
|
||||
bool latch_right_to_left,
|
||||
bool flip_horizontal,
|
||||
bool flip_vertical)
|
||||
{
|
||||
ssize_t err;
|
||||
u8 data;
|
||||
|
||||
data = ((flip_vertical ? 1 : 0) << 0) |
|
||||
((flip_horizontal ? 1 : 0) << 1) |
|
||||
((latch_right_to_left ? 1 : 0) << 2) |
|
||||
((reverse_rgb ? 1 : 0) << 3) |
|
||||
((refresh_from_bottom ? 1 : 0) << 4) |
|
||||
((reverse_page_col_address ? 1 : 0) << 5) |
|
||||
((reverse_col_address ? 1 : 0) << 6) |
|
||||
((reverse_page_address ? 1 : 0) << 7);
|
||||
|
||||
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_ADDRESS_MODE, &data, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
83
src/soc/nvidia/tegra210/mmu_operations.c
Normal file
83
src/soc/nvidia/tegra210/mmu_operations.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/mmu.h>
|
||||
#include <memrange.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/mmu_operations.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* This structure keeps track of all the mmap memory ranges for t210 */
|
||||
static struct memranges t210_mmap_ranges;
|
||||
|
||||
static void tegra210_memrange_init(struct memranges *map)
|
||||
{
|
||||
uint64_t start,end;
|
||||
const unsigned long devmem = MA_DEV | MA_S | MA_RW;
|
||||
const unsigned long cachedmem = MA_MEM | MA_NS | MA_RW;
|
||||
const unsigned long secure_mem = MA_MEM | MA_S | MA_RW;
|
||||
uintptr_t tz_base_mib;
|
||||
size_t tz_size_mib;
|
||||
|
||||
print_carveouts();
|
||||
|
||||
memranges_init_empty(map);
|
||||
|
||||
memory_in_range_below_4gb(&start,&end);
|
||||
|
||||
/* Device memory below DRAM */
|
||||
memranges_insert(map, 0, start * MiB, devmem);
|
||||
|
||||
/* DRAM */
|
||||
memranges_insert(map, start * MiB, (end-start) * MiB, cachedmem);
|
||||
|
||||
memory_in_range_above_4gb(&start,&end);
|
||||
|
||||
memranges_insert(map, start * MiB, (end-start) * MiB, cachedmem);
|
||||
|
||||
/* SRAM */
|
||||
memranges_insert(map, TEGRA_SRAM_BASE, TEGRA_SRAM_SIZE, cachedmem);
|
||||
|
||||
/* Add TZ carveout. */
|
||||
carveout_range(CARVEOUT_TZ, &tz_base_mib, &tz_size_mib);
|
||||
memranges_insert(map, tz_base_mib * MiB, tz_size_mib * MiB, secure_mem);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) mainboard_add_memory_ranges(struct memranges *map)
|
||||
{
|
||||
/* Don't add any ranges by default. */
|
||||
}
|
||||
|
||||
void tegra210_mmu_init(void)
|
||||
{
|
||||
uintptr_t tz_base_mib;
|
||||
size_t tz_size_mib;
|
||||
size_t ttb_size_mib;
|
||||
struct memranges *map = &t210_mmap_ranges;
|
||||
|
||||
tegra210_memrange_init(map);
|
||||
mainboard_add_memory_ranges(map);
|
||||
/* Place page tables at the base of the trust zone region. */
|
||||
carveout_range(CARVEOUT_TZ, &tz_base_mib, &tz_size_mib);
|
||||
tz_base_mib *= MiB;
|
||||
ttb_size_mib = TTB_SIZE * MiB;
|
||||
mmu_init(map, (void *)tz_base_mib, ttb_size_mib);
|
||||
mmu_enable();
|
||||
}
|
27
src/soc/nvidia/tegra210/monotonic_timer.c
Normal file
27
src/soc/nvidia/tegra210/monotonic_timer.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <timer.h>
|
||||
|
||||
void timer_monotonic_get(struct mono_time *mt)
|
||||
{
|
||||
mono_time_set_usecs(mt, read32((void *)TEGRA_TMRUS_BASE));
|
||||
}
|
89
src/soc/nvidia/tegra210/mtc.c
Normal file
89
src/soc/nvidia/tegra210/mtc.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
#include <cbfs.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/mtc.h>
|
||||
#include <string.h>
|
||||
|
||||
static size_t mtc_table_size;
|
||||
|
||||
#define MAX_MTC_TABLE_ENTRIES 20
|
||||
#define MTC_TABLE_ENTRY_SIZE 4880
|
||||
#define MTC_TABLE_MAX_SIZE (MAX_MTC_TABLE_ENTRIES * MTC_TABLE_ENTRY_SIZE)
|
||||
|
||||
int tegra210_run_mtc(void)
|
||||
{
|
||||
ssize_t nread;
|
||||
struct region_device fh;
|
||||
|
||||
void * const mtc = (void *)(uintptr_t)CONFIG_MTC_ADDRESS;
|
||||
void *dvfs_table;
|
||||
size_t (*mtc_fw)(void **dvfs_table) = (void *)mtc;
|
||||
|
||||
if (cbfs_boot_locate(&fh, "tegra_mtc.bin", NULL)) {
|
||||
printk(BIOS_ERR, "MTC file not found: tegra_mtc.bin\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read MTC file into predefined region. */
|
||||
nread = rdev_readat(&fh, mtc, 0, region_device_sz(&fh));
|
||||
|
||||
if (nread != region_device_sz(&fh)) {
|
||||
printk(BIOS_ERR, "MTC bytes read (%zu) != file length(%zu)!\n",
|
||||
nread, region_device_sz(&fh));
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk(BIOS_INFO, "MTC: %zu bytes loaded @ %p\n", nread, mtc);
|
||||
|
||||
mtc_table_size = (*mtc_fw)(&dvfs_table);
|
||||
|
||||
if ((mtc_table_size == 0) || (mtc_table_size > MTC_TABLE_MAX_SIZE)) {
|
||||
printk(BIOS_ERR, "MTC Training table size is invalid.!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk(BIOS_INFO, "MTC: Done. Entries size 0x%zx located at %p\n",
|
||||
mtc_table_size, dvfs_table);
|
||||
|
||||
void *cbmem_tab = cbmem_add(CBMEM_ID_MTC, mtc_table_size);
|
||||
if (cbmem_tab == NULL) {
|
||||
printk(BIOS_ERR, "MTC table allocation in cbmem failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(cbmem_tab, dvfs_table, mtc_table_size);
|
||||
printk(BIOS_INFO, "MTC: Copied 0x%zx bytes from %p to %p\n",
|
||||
mtc_table_size, dvfs_table, cbmem_tab);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void soc_add_mtc(struct lb_header *header)
|
||||
{
|
||||
struct lb_range *mtc;
|
||||
mtc = (struct lb_range *)lb_new_record(header);
|
||||
mtc->tag = LB_TAG_MTC;
|
||||
mtc->size = sizeof(*mtc);
|
||||
|
||||
mtc->range_start = (uintptr_t)cbmem_find(CBMEM_ID_MTC);
|
||||
mtc->range_size = mtc_table_size;
|
||||
}
|
137
src/soc/nvidia/tegra210/padconfig.c
Normal file
137
src/soc/nvidia/tegra210/padconfig.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/padconfig.h>
|
||||
|
||||
static uint32_t * const pinmux_regs = (void *)(uintptr_t)TEGRA_APB_PINMUX_BASE;
|
||||
static struct gpio_bank * const gpio_regs = (void *)(uintptr_t)TEGRA_GPIO_BASE;
|
||||
|
||||
static inline struct gpio_bank * const get_gpio_bank_regs(int index)
|
||||
{
|
||||
return &gpio_regs[gpio_index_to_bank(index)];
|
||||
}
|
||||
|
||||
static inline uint32_t pad_get_pinmux(int index)
|
||||
{
|
||||
return read32(&pinmux_regs[index]);
|
||||
}
|
||||
|
||||
static inline void pad_set_pinmux(int index, uint32_t reg)
|
||||
{
|
||||
return write32(&pinmux_regs[index], reg);
|
||||
}
|
||||
|
||||
static inline void pad_set_gpio_out(int gpio_index, int val)
|
||||
{
|
||||
struct gpio_bank * const regs = get_gpio_bank_regs(gpio_index);
|
||||
int port = gpio_index_to_port(gpio_index);
|
||||
int bit = gpio_to_bit(gpio_index);
|
||||
|
||||
write32(®s->out_value_mask[port],
|
||||
(1 << (bit + GPIO_GPIOS_PER_PORT)) | (val << bit));
|
||||
write32(®s->out_enable_mask[port],
|
||||
(1 << (bit + GPIO_GPIOS_PER_PORT)) | (1 << bit));
|
||||
}
|
||||
|
||||
static inline void pad_set_mode(int gpio_index, int sfio_or_gpio)
|
||||
{
|
||||
struct gpio_bank * const regs = get_gpio_bank_regs(gpio_index);
|
||||
int port = gpio_index_to_port(gpio_index);
|
||||
int bit = gpio_to_bit(gpio_index);
|
||||
|
||||
write32(®s->config_mask[port],
|
||||
(1 << (bit + GPIO_GPIOS_PER_PORT)) | (sfio_or_gpio << bit));
|
||||
}
|
||||
|
||||
static inline void pad_set_gpio_mode(int gpio_index)
|
||||
{
|
||||
pad_set_mode(gpio_index, 1);
|
||||
}
|
||||
|
||||
static inline void pad_set_sfio_mode(int gpio_index)
|
||||
{
|
||||
pad_set_mode(gpio_index, 0);
|
||||
}
|
||||
|
||||
static void configure_unused_pad(const struct pad_config * const entry)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
/*
|
||||
* Tristate the pad and disable input. If power-on-reset state is a
|
||||
* pullup maintain that. Otherwise enable pulldown.
|
||||
*/
|
||||
reg = pad_get_pinmux(entry->pinmux_index);
|
||||
reg &= ~PINMUX_INPUT_ENABLE;
|
||||
reg |= PINMUX_TRISTATE;
|
||||
reg &= ~PINMUX_PULL_MASK;
|
||||
if (entry->por_pullup)
|
||||
reg |= PINMUX_PULL_UP;
|
||||
else
|
||||
reg |= PINMUX_PULL_DOWN;
|
||||
pad_set_pinmux(entry->pinmux_index, reg);
|
||||
|
||||
/*
|
||||
* Set to GPIO mode if GPIO available to bypass collisions of
|
||||
* controller signals going to more than one pad.
|
||||
*/
|
||||
if (entry->pad_has_gpio)
|
||||
pad_set_gpio_mode(entry->gpio_index);
|
||||
}
|
||||
|
||||
static void configure_sfio_pad(const struct pad_config * const entry)
|
||||
{
|
||||
pad_set_pinmux(entry->pinmux_index, entry->pinmux_flags);
|
||||
pad_set_sfio_mode(entry->gpio_index);
|
||||
}
|
||||
|
||||
static void configure_gpio_pad(const struct pad_config * const entry)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
if (entry->gpio_out0 || entry->gpio_out1)
|
||||
pad_set_gpio_out(entry->gpio_index, entry->gpio_out1 ? 1 : 0);
|
||||
|
||||
/* Keep the original SFIO selection. */
|
||||
reg = pinmux_get_config(entry->pinmux_index);
|
||||
reg &= PINMUX_FUNC_MASK;
|
||||
reg |= entry->pinmux_flags;
|
||||
|
||||
pad_set_pinmux(entry->pinmux_index, reg);
|
||||
pad_set_gpio_mode(entry->gpio_index);
|
||||
}
|
||||
|
||||
void soc_configure_pads(const struct pad_config * const entries, size_t num)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
const struct pad_config * const entry = &entries[i];
|
||||
|
||||
if (entry->unused) {
|
||||
configure_unused_pad(entry);
|
||||
} else if (entry->sfio) {
|
||||
configure_sfio_pad(entry);
|
||||
} else {
|
||||
configure_gpio_pad(entry);
|
||||
}
|
||||
}
|
||||
}
|
137
src/soc/nvidia/tegra210/power.c
Normal file
137
src/soc/nvidia/tegra210/power.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2013 Google Inc.
|
||||
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <assert.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/power.h>
|
||||
|
||||
static struct tegra_pmc_regs * const pmc = (void *)TEGRA_PMC_BASE;
|
||||
|
||||
enum {
|
||||
POWER_GATE = 0,
|
||||
POWER_UNGATE = 1,
|
||||
};
|
||||
|
||||
static int partition_powered(int id)
|
||||
{
|
||||
if (read32(&pmc->pwrgate_status) & (0x1 << id))
|
||||
return POWER_UNGATE;
|
||||
|
||||
return POWER_GATE;
|
||||
}
|
||||
|
||||
static const char * const power_gate_string[] = {
|
||||
[POWER_GATE] = "Gat",
|
||||
[POWER_UNGATE] = "Ungat",
|
||||
};
|
||||
|
||||
static void power_gate_toggle_request(uint32_t id, int request)
|
||||
{
|
||||
printk(BIOS_INFO, "%sing power partition %d.\n",
|
||||
power_gate_string[request], id);
|
||||
|
||||
int part_powered = partition_powered(id);
|
||||
|
||||
if (request == part_powered) {
|
||||
printk(BIOS_INFO, "Partition %d already %sed.\n", id,
|
||||
power_gate_string[request]);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t pwrgate_toggle = read32(&pmc->pwrgate_toggle);
|
||||
pwrgate_toggle &= ~(PMC_PWRGATE_TOGGLE_PARTID_MASK);
|
||||
pwrgate_toggle |= (id << PMC_PWRGATE_TOGGLE_PARTID_SHIFT);
|
||||
pwrgate_toggle |= PMC_PWRGATE_TOGGLE_START;
|
||||
write32(&pmc->pwrgate_toggle, pwrgate_toggle);
|
||||
|
||||
// Wait for the request to be accepted.
|
||||
while (read32(&pmc->pwrgate_toggle) & PMC_PWRGATE_TOGGLE_START)
|
||||
;
|
||||
printk(BIOS_INFO, "Power gate toggle request accepted.\n");
|
||||
|
||||
while (1) {
|
||||
part_powered = partition_powered(id);
|
||||
if (request == part_powered) {
|
||||
printk(BIOS_INFO, "Partition %d %sed.\n", id,
|
||||
power_gate_string[request]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void power_gate_partition(uint32_t id)
|
||||
{
|
||||
power_gate_toggle_request(id, POWER_GATE);
|
||||
}
|
||||
|
||||
void power_ungate_partition(uint32_t id)
|
||||
{
|
||||
power_gate_toggle_request(id, POWER_UNGATE);
|
||||
}
|
||||
|
||||
uint8_t pmc_rst_status(void)
|
||||
{
|
||||
return read32(&pmc->rst_status) & PMC_RST_STATUS_SOURCE_MASK;
|
||||
}
|
||||
|
||||
static const char *pmc_rst_status_str[PMC_RST_STATUS_NUM_SOURCES] = {
|
||||
[PMC_RST_STATUS_SOURCE_POR] = "POR",
|
||||
[PMC_RST_STATUS_SOURCE_WATCHDOG] = "Watchdog",
|
||||
[PMC_RST_STATUS_SOURCE_SENSOR] = "Sensor",
|
||||
[PMC_RST_STATUS_SOURCE_SW_MAIN] = "SW Main",
|
||||
[PMC_RST_STATUS_SOURCE_LP0] = "LP0",
|
||||
};
|
||||
|
||||
void pmc_print_rst_status(void)
|
||||
{
|
||||
uint8_t rst_status = pmc_rst_status();
|
||||
assert(rst_status < PMC_RST_STATUS_NUM_SOURCES);
|
||||
printk(BIOS_INFO, "PMC Reset Status: %s\n",
|
||||
pmc_rst_status_str[rst_status]);
|
||||
}
|
||||
|
||||
static int partition_clamp_on(int id)
|
||||
{
|
||||
return read32(&pmc->clamp_status) & (1 << id);
|
||||
}
|
||||
|
||||
void remove_clamps(int id)
|
||||
{
|
||||
if (!partition_clamp_on(id))
|
||||
return;
|
||||
|
||||
/* Remove clamp */
|
||||
write32(&pmc->remove_clamping_cmd, (1 << id));
|
||||
|
||||
/* Wait for clamp off */
|
||||
while (partition_clamp_on(id))
|
||||
;
|
||||
}
|
||||
|
||||
void pmc_override_pwr_det(uint32_t bits, uint32_t override)
|
||||
{
|
||||
uint32_t val = read32(&pmc->pwr_det_val);
|
||||
val &= ~bits;
|
||||
val |= (override & bits);
|
||||
write32(&pmc->pwr_det_val, val);
|
||||
}
|
194
src/soc/nvidia/tegra210/psci.c
Normal file
194
src/soc/nvidia/tegra210/psci.c
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <arch/io.h>
|
||||
#include <arch/psci.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clk_rst.h>
|
||||
#include <soc/cpu.h>
|
||||
#include <soc/flow_ctrl.h>
|
||||
#include <soc/power.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <console/console.h>
|
||||
|
||||
extern void tegra210_reset_handler(void);
|
||||
|
||||
#define TEGRA210_PM_STATE_C7 7
|
||||
|
||||
static void *cpu_on_entry_point;
|
||||
|
||||
void psci_soc_init(uintptr_t cpu_on_entry)
|
||||
{
|
||||
/*
|
||||
* Stash secmon entry point for CPUs starting up. The 32-bit reset
|
||||
* vector register is accessible in < EL3 so one has to attempt to
|
||||
* plug the potential race for that register being changed out from
|
||||
* under us. Therefore, we set the appropriate registers here, but
|
||||
* it is also done on each CPU_ON request.
|
||||
*/
|
||||
cpu_on_entry_point = tegra210_reset_handler;
|
||||
cpu_prepare_startup(cpu_on_entry_point);
|
||||
}
|
||||
|
||||
static size_t children_at_level(int parent_level, uint64_t mpidr)
|
||||
{
|
||||
if (mpidr != 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* T210 has 2 clusters. Each cluster has 4 cores. Currently we are
|
||||
* concentrating only on one of the clusters i.e. A57 cluster. For A53
|
||||
* bringup, correct the cluster details for A53 cluster as well.
|
||||
* Since, A57 cluster has 4 cores, level 1 has 4 children at level 0.
|
||||
* TODO(furquan): Update for A53.
|
||||
*/
|
||||
switch (parent_level) {
|
||||
case PSCI_AFFINITY_ROOT:
|
||||
return 1;
|
||||
case PSCI_AFFINITY_LEVEL_3:
|
||||
return 1;
|
||||
case PSCI_AFFINITY_LEVEL_2:
|
||||
return 1;
|
||||
case PSCI_AFFINITY_LEVEL_1:
|
||||
return 4;
|
||||
case PSCI_AFFINITY_LEVEL_0:
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void prepare_cpu_on(int cpu)
|
||||
{
|
||||
cpu_prepare_startup(cpu_on_entry_point);
|
||||
}
|
||||
|
||||
static void prepare_cpu_suspend(int cpu, uint32_t state_id)
|
||||
{
|
||||
flowctrl_write_cc4_ctrl(cpu, 0xffffffff);
|
||||
switch (state_id) {
|
||||
case TEGRA210_PM_STATE_C7:
|
||||
flowctrl_cpu_suspend(cpu);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void prepare_cpu_resume(int cpu)
|
||||
{
|
||||
flowctrl_write_cpu_csr(cpu, 0);
|
||||
flowctrl_write_cpu_halt(cpu, 0);
|
||||
flowctrl_write_cc4_ctrl(cpu, 0);
|
||||
}
|
||||
|
||||
static void cpu_suspend_commit(int cpu, uint32_t state_id)
|
||||
{
|
||||
int l2_flush;
|
||||
|
||||
switch (state_id) {
|
||||
case TEGRA210_PM_STATE_C7:
|
||||
l2_flush = NO_L2_FLUSH;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
cortex_a57_cpu_power_down(l2_flush);
|
||||
/* should never be here */
|
||||
}
|
||||
|
||||
static int cmd_prepare(struct psci_cmd *cmd)
|
||||
{
|
||||
int ret;
|
||||
struct cpu_info *ci;
|
||||
|
||||
ci = cmd->target->cpu_state.ci;
|
||||
|
||||
switch (cmd->type) {
|
||||
case PSCI_CMD_SUSPEND:
|
||||
cmd->state_id = cmd->state->id;
|
||||
prepare_cpu_on(ci->id);
|
||||
prepare_cpu_suspend(ci->id, cmd->state_id);
|
||||
ret = PSCI_RET_SUCCESS;
|
||||
break;
|
||||
case PSCI_CMD_RESUME:
|
||||
prepare_cpu_resume(ci->id);
|
||||
ret = PSCI_RET_SUCCESS;
|
||||
break;
|
||||
case PSCI_CMD_ON:
|
||||
prepare_cpu_on(ci->id);
|
||||
ret = PSCI_RET_SUCCESS;
|
||||
break;
|
||||
case PSCI_CMD_OFF:
|
||||
if (cmd->state_id != -1) {
|
||||
ret = PSCI_RET_INVALID_PARAMETERS;
|
||||
break;
|
||||
}
|
||||
ret = PSCI_RET_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
ret = PSCI_RET_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cmd_commit(struct psci_cmd *cmd)
|
||||
{
|
||||
int ret;
|
||||
struct cpu_info *ci;
|
||||
|
||||
ci = cmd->target->cpu_state.ci;
|
||||
|
||||
switch (cmd->type) {
|
||||
case PSCI_CMD_SUSPEND:
|
||||
cpu_suspend_commit(ci->id, cmd->state_id);
|
||||
ret = PSCI_RET_SUCCESS;
|
||||
break;
|
||||
case PSCI_CMD_RESUME:
|
||||
ret = PSCI_RET_SUCCESS;
|
||||
break;
|
||||
case PSCI_CMD_ON:
|
||||
/* Take CPU out of reset */
|
||||
flowctrl_cpu_on(ci->id);
|
||||
ret = PSCI_RET_SUCCESS;
|
||||
break;
|
||||
case PSCI_CMD_OFF:
|
||||
flowctrl_cpu_off(ci->id);
|
||||
cortex_a57_cpu_power_down(NO_L2_FLUSH);
|
||||
/* Never reach here */
|
||||
ret = PSCI_RET_NOT_SUPPORTED;
|
||||
printk(BIOS_ERR, "t210 CPU%d PSCI_CMD_OFF fail\n", ci->id);
|
||||
break;
|
||||
default:
|
||||
ret = PSCI_RET_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct psci_soc_ops soc_psci_ops = {
|
||||
.children_at_level = &children_at_level,
|
||||
.cmd_prepare = &cmd_prepare,
|
||||
.cmd_commit = &cmd_commit,
|
||||
};
|
29
src/soc/nvidia/tegra210/ram_code.c
Normal file
29
src/soc/nvidia/tegra210/ram_code.c
Normal 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/sdram.h>
|
||||
#include <soc/nvidia/tegra/apbmisc.h>
|
||||
|
||||
uint32_t sdram_get_ram_code(void)
|
||||
{
|
||||
struct apbmisc *misc = (struct apbmisc *)TEGRA_APB_MISC_BASE;
|
||||
|
||||
return (read32(&misc->pp_strapping_opt_a) &
|
||||
PP_STRAPPING_OPT_A_RAM_CODE_MASK) >>
|
||||
PP_STRAPPING_OPT_A_RAM_CODE_SHIFT;
|
||||
}
|
39
src/soc/nvidia/tegra210/ramstage.c
Normal file
39
src/soc/nvidia/tegra210/ramstage.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/clock.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <arch/stages.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/mmu_operations.h>
|
||||
|
||||
void arm64_arch_timer_init(void)
|
||||
{
|
||||
uint32_t freq = clock_get_osc_khz() * 1000;
|
||||
// Set the cntfrq register.
|
||||
set_cntfrq(freq);
|
||||
}
|
||||
|
||||
void arm64_soc_init(void)
|
||||
{
|
||||
trustzone_region_init();
|
||||
|
||||
tegra210_mmu_init();
|
||||
}
|
29
src/soc/nvidia/tegra210/reset.c
Normal file
29
src/soc/nvidia/tegra210/reset.c
Normal 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.
|
||||
*/
|
||||
|
||||
#include <reset.h>
|
||||
|
||||
/*
|
||||
* Promote cpu_reset() to a hard_reset(). A shallower reset can be added,
|
||||
* if needed, at a later time.
|
||||
*/
|
||||
void cpu_reset(void)
|
||||
{
|
||||
hard_reset();
|
||||
}
|
75
src/soc/nvidia/tegra210/reset_handler.S
Normal file
75
src/soc/nvidia/tegra210/reset_handler.S
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/asm.h>
|
||||
|
||||
#define CPUACTLR_EL1 s3_1_c15_c2_0
|
||||
|
||||
CPU_RESET_ENTRY(tegra210_reset_handler)
|
||||
/*
|
||||
* Invalidate BTB along with I$ to remove any stale entries
|
||||
* from the branch predictor array.
|
||||
*/
|
||||
mrs x0, CPUACTLR_EL1
|
||||
orr x0, x0, #1
|
||||
msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
|
||||
dsb sy
|
||||
isb
|
||||
ic iallu /* invalidate */
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
bic x0, x0, #1
|
||||
msr CPUACTLR_EL1, x0 /* restore original CPUACTLR_EL1 */
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
.rept 7
|
||||
nop /* wait */
|
||||
.endr
|
||||
|
||||
/*
|
||||
* Extract OSLK bit and check if it is '1'. This bit remains '0'
|
||||
* for A53. If '1', turn off regional clock gating and request
|
||||
* warm reset.
|
||||
*/
|
||||
mrs x0, oslsr_el1
|
||||
and x0, x0, #2 /* extract oslk bit */
|
||||
mrs x1, mpidr_el1
|
||||
bics xzr, x0, x1, lsr #7 /* 0 if slow cluster */
|
||||
b.eq __restore_oslock
|
||||
mov x0, xzr
|
||||
msr oslar_el1, x0 /* os lock stays 0 across warm reset */
|
||||
mov x3, #3
|
||||
movz x4, #0x8000, lsl #48
|
||||
msr CPUACTLR_EL1, x4 /* turn off RCG */
|
||||
isb
|
||||
msr rmr_el3, x3 /* request warm reset */
|
||||
isb
|
||||
dsb sy
|
||||
wfi
|
||||
|
||||
/*
|
||||
* These nops are here so that speculative execution won't harm us
|
||||
* before we are done warm reset.
|
||||
*/
|
||||
.rept 65
|
||||
nop
|
||||
.endr
|
||||
|
||||
__restore_oslock:
|
||||
mov x0, #1
|
||||
msr oslar_el1, x0
|
||||
|
||||
b arm64_cpu_startup_resume
|
||||
ENDPROC(tegra210_reset_handler)
|
92
src/soc/nvidia/tegra210/romstage.c
Normal file
92
src/soc/nvidia/tegra210/romstage.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/exception.h>
|
||||
#include <arch/stages.h>
|
||||
#include <cbfs.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/cbmem_console.h>
|
||||
#include <console/console.h>
|
||||
#include <program_loading.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/ccplex.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/sdram.h>
|
||||
#include <soc/sdram_configs.h>
|
||||
#include <soc/romstage.h>
|
||||
#include <soc/nvidia/tegra/apbmisc.h>
|
||||
#include <timer.h>
|
||||
#include <timestamp.h>
|
||||
#include <vendorcode/google/chromeos/chromeos.h>
|
||||
|
||||
void __attribute__((weak)) romstage_mainboard_init(void)
|
||||
{
|
||||
/* Default empty implementation. */
|
||||
}
|
||||
|
||||
void romstage(void)
|
||||
{
|
||||
console_init();
|
||||
exception_init();
|
||||
|
||||
printk(BIOS_INFO, "T210: romstage here\n");
|
||||
|
||||
#if CONFIG_BOOTROM_SDRAM_INIT
|
||||
printk(BIOS_INFO, "T210 romstage: SDRAM init done by BootROM, RAMCODE = %d\n",
|
||||
sdram_get_ram_code());
|
||||
#else
|
||||
sdram_init(get_sdram_config());
|
||||
printk(BIOS_INFO, "T210 romstage: sdram_init done\n");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IMPORTANT:
|
||||
* DO NOT INITIALIZE ANY CARVEOUT BEFORE TZ.
|
||||
*
|
||||
* Trust Zone needs to be initialized after the DRAM initialization
|
||||
* because carveout registers are programmed during DRAM init.
|
||||
* cbmem_initialize() is dependent on the Trust Zone region
|
||||
* initalization because CBMEM lives right below the Trust Zone which
|
||||
* needs to be properly identified.
|
||||
*/
|
||||
trustzone_region_init();
|
||||
|
||||
gpu_region_init();
|
||||
|
||||
/*
|
||||
* When romstage is running it's always on the reboot path -- never a
|
||||
* resume path where cbmem recovery is required. Therefore, always
|
||||
* initialize the cbmem area to be empty.
|
||||
*/
|
||||
cbmem_initialize_empty();
|
||||
|
||||
ccplex_cpu_prepare();
|
||||
printk(BIOS_INFO, "T210 romstage: cpu prepare done\n");
|
||||
|
||||
romstage_mainboard_init();
|
||||
|
||||
run_ramstage();
|
||||
}
|
||||
|
||||
void platform_prog_run(struct prog *prog)
|
||||
{
|
||||
ccplex_cpu_start(prog_entry(prog));
|
||||
|
||||
clock_halt_avp();
|
||||
}
|
27
src/soc/nvidia/tegra210/romstage_asm.S
Normal file
27
src/soc/nvidia/tegra210/romstage_asm.S
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/asm.h>
|
||||
#include "stack.S"
|
||||
|
||||
.section ".text", "ax", %progbits
|
||||
|
||||
ENTRY(main)
|
||||
stack_init stack_top=_estack stack_bottom=_stack seed=0 func=romstage
|
||||
ENDPROC(main)
|
1082
src/soc/nvidia/tegra210/sdram.c
Normal file
1082
src/soc/nvidia/tegra210/sdram.c
Normal file
File diff suppressed because it is too large
Load Diff
628
src/soc/nvidia/tegra210/sdram_lp0.c
Normal file
628
src/soc/nvidia/tegra210/sdram_lp0.c
Normal file
@ -0,0 +1,628 @@
|
||||
/*
|
||||
* 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 <arch/cache.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clk_rst.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/sdram.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* This function reads SDRAM parameters (and a few CLK_RST regsiter values) from
|
||||
* the common BCT format and writes them into PMC scratch registers (where the
|
||||
* BootROM expects them on LP0 resume). Since those store the same values in a
|
||||
* different format, we follow a "translation table" taken from Nvidia's U-Boot
|
||||
* implementation to shift bits into the right position.
|
||||
*
|
||||
* Contrary to U-Boot, we transform the same macros directly into hardcoded
|
||||
* assignments (without any pesky function calls or volatile qualifiers) to give
|
||||
* the compiler as much room for optimization as possible. For that reason, we
|
||||
* also intentionally avoid <arch/io.h> read/write macros, under the assumption
|
||||
* that PMC scratch register accesses should not have side effects and can be
|
||||
* arbitrarily reordered. For the few accesses that do have side-effects, the
|
||||
* code must contain explicit memory barriers.
|
||||
*/
|
||||
void sdram_lp0_save_params(const struct sdram_params *sdram)
|
||||
{
|
||||
struct tegra_pmc_regs * pmc = (void *)TEGRA_PMC_BASE;
|
||||
struct clk_rst_ctlr * clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
||||
|
||||
#define pack(src, src_bits, dst, dst_bits) { \
|
||||
_Static_assert((1 ? src_bits) >= (0 ? src_bits) && (1 ? dst_bits) >= \
|
||||
(0 ? dst_bits), "byte range flipped (must be MSB:LSB)" ); \
|
||||
_Static_assert((1 ? src_bits) - (0 ? src_bits) == (1 ? dst_bits) - \
|
||||
(0 ? dst_bits), "src and dst byte range lengths differ" ); \
|
||||
u32 mask = 0xffffffff >> (31 - ((1 ? src_bits) - (0 ? src_bits))); \
|
||||
dst &= ~(mask << (0 ? dst_bits)); \
|
||||
dst |= ((src >> (0 ? src_bits)) & mask) << (0 ? dst_bits); \
|
||||
}
|
||||
|
||||
#define s(param, src_bits, pmcreg, dst_bits) \
|
||||
pack(sdram->param, src_bits, pmc->pmcreg, dst_bits)
|
||||
|
||||
#define m(clkreg, src_bits, pmcreg, dst_bits) \
|
||||
pack(clk_rst->clkreg, src_bits, pmc->pmcreg, dst_bits)
|
||||
|
||||
#define c(value, pmcreg, dst_bits) \
|
||||
pack(value, (1 ? dst_bits) - (0 ? dst_bits) : 0, pmc->pmcreg, dst_bits)
|
||||
|
||||
s(EmcClockSource, 7:0, scratch6, 15:8);
|
||||
s(EmcClockSource, 31:29, scratch6, 18:16);
|
||||
s(EmcClockSource, 26:26, scratch6, 19:19);
|
||||
s(EmcOdtWrite, 5:0, scratch6, 25:20);
|
||||
s(EmcOdtWrite, 11:8, scratch6, 29:26);
|
||||
s(EmcOdtWrite, 30:30, scratch6, 30:30);
|
||||
s(EmcOdtWrite, 31:31, scratch6, 31:31);
|
||||
s(EmcXm2DqPadCtrl2, 18:16, scratch7, 22:20);
|
||||
s(EmcXm2DqPadCtrl2, 22:20, scratch7, 25:23);
|
||||
s(EmcXm2DqPadCtrl2, 26:24, scratch7, 28:26);
|
||||
s(EmcXm2DqPadCtrl2, 30:28, scratch7, 31:29);
|
||||
s(EmcXm2DqPadCtrl3, 18:16, scratch8, 22:20);
|
||||
s(EmcXm2DqPadCtrl3, 22:20, scratch8, 25:23);
|
||||
s(EmcXm2DqPadCtrl3, 26:24, scratch8, 28:26);
|
||||
s(EmcXm2DqPadCtrl3, 30:28, scratch8, 31:29);
|
||||
s(EmcTxsrDll, 11:0, scratch9, 31:20);
|
||||
c(0, scratch10, 31:0);
|
||||
s(EmcDsrVttgenDrv, 5:0, scratch10, 25:20);
|
||||
s(EmcDsrVttgenDrv, 18:16, scratch10, 28:26);
|
||||
s(EmcDsrVttgenDrv, 26:24, scratch10, 31:29);
|
||||
s(EmcFbioSpare, 31:24, scratch11, 7:0);
|
||||
s(EmcFbioSpare, 23:16, scratch11, 15:8);
|
||||
s(EmcFbioSpare, 15:8, scratch11, 23:16);
|
||||
s(EmcFbioSpare, 7:0, scratch11, 31:24);
|
||||
s(EmcCfgRsv, 31:0, scratch12, 31:0);
|
||||
s(EmcCdbCntl2, 31:0, scratch13, 31:0);
|
||||
s(McEmemArbDaTurns, 31:0, scratch14, 31:0);
|
||||
s(EmcCfgDigDll, 0:0, scratch17, 0:0);
|
||||
s(EmcCfgDigDll, 25:2, scratch17, 24:1);
|
||||
s(EmcCfgDigDll, 31:27, scratch17, 29:25);
|
||||
s(EmcCdbCntl1, 29:0, scratch18, 29:0);
|
||||
s(McEmemArbMisc0, 14:0, scratch19, 14:0);
|
||||
s(McEmemArbMisc0, 30:16, scratch19, 29:15);
|
||||
s(EmcXm2DqsPadCtrl, 4:0, scratch22, 4:0);
|
||||
s(EmcXm2DqsPadCtrl, 12:8, scratch22, 9:5);
|
||||
s(EmcXm2DqsPadCtrl, 31:14, scratch22, 27:10);
|
||||
s(EmcRrd, 3:0, scratch22, 31:28);
|
||||
s(EmcXm2DqPadCtrl, 31:4, scratch23, 27:0);
|
||||
s(EmcRext, 3:0, scratch23, 31:28);
|
||||
s(EmcXm2CompPadCtrl, 16:0, scratch24, 16:0);
|
||||
s(EmcXm2CompPadCtrl, 24:20, scratch24, 21:17);
|
||||
s(EmcXm2CompPadCtrl, 27:27, scratch24, 22:22);
|
||||
s(EmcXm2CompPadCtrl, 31:28, scratch24, 26:23);
|
||||
s(EmcR2w, 4:0, scratch24, 31:27);
|
||||
s(EmcCfg, 9:1, scratch25, 8:0);
|
||||
s(EmcCfg, 26:16, scratch25, 19:9);
|
||||
s(EmcCfg, 31:28, scratch25, 23:20);
|
||||
s(EmcXm2VttGenPadCtrl, 0:0, scratch25, 24:24);
|
||||
s(EmcXm2VttGenPadCtrl, 2:2, scratch25, 25:25);
|
||||
s(EmcXm2VttGenPadCtrl, 18:16, scratch25, 28:26);
|
||||
s(EmcXm2VttGenPadCtrl, 26:24, scratch25, 31:29);
|
||||
s(EmcZcalInterval, 23:10, scratch26, 13:0);
|
||||
s(EmcZcalInterval, 9:0, scratch26, 23:14);
|
||||
s(EmcSelDpdCtrl, 5:2, scratch26, 27:24);
|
||||
s(EmcSelDpdCtrl, 8:8, scratch26, 28:28);
|
||||
s(EmcSelDpdCtrl, 18:16, scratch26, 31:29);
|
||||
s(EmcXm2VttGenPadCtrl3, 22:0, scratch27, 22:0);
|
||||
s(EmcXm2VttGenPadCtrl3, 24:24, scratch27, 23:23);
|
||||
s(EmcSwizzleRank0ByteCfg, 1:0, scratch27, 25:24);
|
||||
s(EmcSwizzleRank0ByteCfg, 5:4, scratch27, 27:26);
|
||||
s(EmcSwizzleRank0ByteCfg, 9:8, scratch27, 29:28);
|
||||
s(EmcSwizzleRank0ByteCfg, 13:12, scratch27, 31:30);
|
||||
s(EmcXm2ClkPadCtrl2, 5:0, scratch28, 5:0);
|
||||
s(EmcXm2ClkPadCtrl2, 13:8, scratch28, 11:6);
|
||||
s(EmcXm2ClkPadCtrl2, 20:16, scratch28, 16:12);
|
||||
s(EmcXm2ClkPadCtrl2, 23:23, scratch28, 17:17);
|
||||
s(EmcXm2ClkPadCtrl2, 28:24, scratch28, 22:18);
|
||||
s(EmcXm2ClkPadCtrl2, 31:31, scratch28, 23:23);
|
||||
s(EmcSwizzleRank1ByteCfg, 1:0, scratch28, 25:24);
|
||||
s(EmcSwizzleRank1ByteCfg, 5:4, scratch28, 27:26);
|
||||
s(EmcSwizzleRank1ByteCfg, 9:8, scratch28, 29:28);
|
||||
s(EmcSwizzleRank1ByteCfg, 13:12, scratch28, 31:30);
|
||||
s(McEmemArbDaCovers, 23:0, scratch29, 23:0);
|
||||
s(McEmemArbRsv, 7:0, scratch29, 31:24);
|
||||
s(EmcAutoCalConfig, 4:0, scratch30, 4:0);
|
||||
s(EmcAutoCalConfig, 12:8, scratch30, 9:5);
|
||||
s(EmcAutoCalConfig, 18:16, scratch30, 12:10);
|
||||
s(EmcAutoCalConfig, 25:20, scratch30, 18:13);
|
||||
s(EmcAutoCalConfig, 31:28, scratch30, 22:19);
|
||||
s(EmcRfc, 8:0, scratch30, 31:23);
|
||||
s(EmcXm2DqsPadCtrl2, 21:0, scratch31, 21:0);
|
||||
s(EmcXm2DqsPadCtrl2, 24:24, scratch31, 22:22);
|
||||
s(EmcAr2Pden, 8:0, scratch31, 31:23);
|
||||
s(EmcXm2ClkPadCtrl, 0:0, scratch32, 0:0);
|
||||
s(EmcXm2ClkPadCtrl, 4:2, scratch32, 3:1);
|
||||
s(EmcXm2ClkPadCtrl, 7:7, scratch32, 4:4);
|
||||
s(EmcXm2ClkPadCtrl, 31:14, scratch32, 22:5);
|
||||
s(EmcRfcSlr, 8:0, scratch32, 31:23);
|
||||
s(EmcXm2DqsPadCtrl3, 0:0, scratch33, 0:0);
|
||||
s(EmcXm2DqsPadCtrl3, 5:5, scratch33, 1:1);
|
||||
s(EmcXm2DqsPadCtrl3, 12:8, scratch33, 6:2);
|
||||
s(EmcXm2DqsPadCtrl3, 18:14, scratch33, 11:7);
|
||||
s(EmcXm2DqsPadCtrl3, 24:20, scratch33, 16:12);
|
||||
s(EmcXm2DqsPadCtrl3, 30:26, scratch33, 21:17);
|
||||
s(EmcTxsr, 9:0, scratch33, 31:22);
|
||||
s(McEmemArbCfg, 8:0, scratch40, 8:0);
|
||||
s(McEmemArbCfg, 20:16, scratch40, 13:9);
|
||||
s(McEmemArbCfg, 27:24, scratch40, 17:14);
|
||||
s(McEmemArbCfg, 31:28, scratch40, 21:18);
|
||||
s(EmcMc2EmcQ, 2:0, scratch40, 24:22);
|
||||
s(EmcMc2EmcQ, 10:8, scratch40, 27:25);
|
||||
s(EmcMc2EmcQ, 27:24, scratch40, 31:28);
|
||||
s(EmcAutoCalInterval, 20:0, scratch42, 20:0);
|
||||
s(McEmemArbOutstandingReq, 8:0, scratch42, 29:21);
|
||||
s(McEmemArbOutstandingReq, 31:30, scratch42, 31:30);
|
||||
s(EmcMrsWaitCnt2, 9:0, scratch44, 9:0);
|
||||
s(EmcMrsWaitCnt2, 25:16, scratch44, 19:10);
|
||||
s(EmcTxdsrvttgen, 11:0, scratch44, 31:20);
|
||||
s(EmcMrsWaitCnt, 9:0, scratch45, 9:0);
|
||||
s(EmcMrsWaitCnt, 25:16, scratch45, 19:10);
|
||||
s(EmcCfgPipe, 1:0, scratch45, 21:20);
|
||||
s(EmcCfgPipe, 9:4, scratch45, 27:22);
|
||||
s(EmcCfgPipe, 15:12, scratch45, 31:28);
|
||||
s(EmcXm2DqsPadCtrl4, 22:18, scratch46, 4:0);
|
||||
s(EmcXm2DqsPadCtrl4, 16:12, scratch46, 9:5);
|
||||
s(EmcXm2DqsPadCtrl4, 10:6, scratch46, 14:10);
|
||||
s(EmcXm2DqsPadCtrl4, 4:0, scratch46, 19:15);
|
||||
s(EmcZcalWaitCnt, 9:0, scratch46, 29:20);
|
||||
s(EmcXm2DqsPadCtrl5, 22:18, scratch47, 4:0);
|
||||
s(EmcXm2DqsPadCtrl5, 16:12, scratch47, 9:5);
|
||||
s(EmcXm2DqsPadCtrl5, 10:6, scratch47, 14:10);
|
||||
s(EmcXm2DqsPadCtrl5, 4:0, scratch47, 19:15);
|
||||
s(EmcXm2VttGenPadCtrl2, 5:0, scratch47, 25:20);
|
||||
s(EmcXm2VttGenPadCtrl2, 31:28, scratch47, 29:26);
|
||||
s(EmcXm2DqsPadCtrl6, 12:8, scratch48, 4:0);
|
||||
s(EmcXm2DqsPadCtrl6, 18:14, scratch48, 9:5);
|
||||
s(EmcXm2DqsPadCtrl6, 24:20, scratch48, 14:10);
|
||||
s(EmcXm2DqsPadCtrl6, 30:26, scratch48, 19:15);
|
||||
s(EmcAutoCalConfig3, 4:0, scratch48, 24:20);
|
||||
s(EmcAutoCalConfig3, 12:8, scratch48, 29:25);
|
||||
s(EmcFbioCfg5, 1:0, scratch48, 31:30);
|
||||
s(EmcDllXformQUse8, 4:0, scratch50, 4:0);
|
||||
s(EmcDllXformQUse8, 22:8, scratch50, 19:5);
|
||||
s(McEmemArbRing1Throttle, 4:0, scratch50, 24:20);
|
||||
s(McEmemArbRing1Throttle, 20:16, scratch50, 29:25);
|
||||
s(EmcFbioCfg5, 3:2, scratch50, 31:30);
|
||||
s(EmcDllXformQUse9, 4:0, scratch51, 4:0);
|
||||
s(EmcDllXformQUse9, 22:8, scratch51, 19:5);
|
||||
s(EmcCttTermCtrl, 2:0, scratch51, 22:20);
|
||||
s(EmcCttTermCtrl, 12:8, scratch51, 27:23);
|
||||
s(EmcCttTermCtrl, 31:31, scratch51, 28:28);
|
||||
s(EmcFbioCfg6, 2:0, scratch51, 31:29);
|
||||
s(EmcDllXformQUse10, 4:0, scratch56, 4:0);
|
||||
s(EmcDllXformQUse10, 22:8, scratch56, 19:5);
|
||||
s(EmcXm2CmdPadCtrl, 10:3, scratch56, 27:20);
|
||||
s(EmcXm2CmdPadCtrl, 28:28, scratch56, 28:28);
|
||||
s(EmcPutermAdj, 1:0, scratch56, 30:29);
|
||||
s(EmcPutermAdj, 7:7, scratch56, 31:31);
|
||||
s(EmcDllXformQUse11, 4:0, scratch57, 4:0);
|
||||
s(EmcDllXformQUse11, 22:8, scratch57, 19:5);
|
||||
s(EmcWdv, 3:0, scratch57, 31:28);
|
||||
s(EmcDllXformQUse12, 4:0, scratch58, 4:0);
|
||||
s(EmcDllXformQUse12, 22:8, scratch58, 19:5);
|
||||
s(EmcBurstRefreshNum, 3:0, scratch58, 31:28);
|
||||
s(EmcDllXformQUse13, 4:0, scratch59, 4:0);
|
||||
s(EmcDllXformQUse13, 22:8, scratch59, 19:5);
|
||||
s(EmcWext, 3:0, scratch59, 31:28);
|
||||
s(EmcDllXformQUse14, 4:0, scratch60, 4:0);
|
||||
s(EmcDllXformQUse14, 22:8, scratch60, 19:5);
|
||||
s(EmcClkenOverride, 3:1, scratch60, 30:28);
|
||||
s(EmcClkenOverride, 6:6, scratch60, 31:31);
|
||||
s(EmcDllXformQUse15, 4:0, scratch61, 4:0);
|
||||
s(EmcDllXformQUse15, 22:8, scratch61, 19:5);
|
||||
s(EmcR2r, 3:0, scratch61, 31:28);
|
||||
s(EmcDllXformDq4, 4:0, scratch62, 4:0);
|
||||
s(EmcDllXformDq4, 22:8, scratch62, 19:5);
|
||||
s(EmcRc, 6:0, scratch62, 26:20);
|
||||
s(EmcW2r, 4:0, scratch62, 31:27);
|
||||
s(EmcDllXformDq5, 4:0, scratch63, 4:0);
|
||||
s(EmcDllXformDq5, 22:8, scratch63, 19:5);
|
||||
s(EmcTfaw, 6:0, scratch63, 26:20);
|
||||
s(EmcR2p, 4:0, scratch63, 31:27);
|
||||
s(EmcDllXformDq6, 4:0, scratch64, 4:0);
|
||||
s(EmcDllXformDq6, 22:8, scratch64, 19:5);
|
||||
s(EmcDliTrimTxDqs0, 6:0, scratch64, 26:20);
|
||||
s(EmcQSafe, 4:0, scratch64, 31:27);
|
||||
s(EmcDllXformDq7, 4:0, scratch65, 4:0);
|
||||
s(EmcDllXformDq7, 22:8, scratch65, 19:5);
|
||||
s(EmcDliTrimTxDqs1, 6:0, scratch65, 26:20);
|
||||
s(EmcTClkStable, 4:0, scratch65, 31:27);
|
||||
s(EmcAutoCalConfig2, 4:0, scratch66, 4:0);
|
||||
s(EmcAutoCalConfig2, 12:8, scratch66, 9:5);
|
||||
s(EmcAutoCalConfig2, 20:16, scratch66, 14:10);
|
||||
s(EmcAutoCalConfig2, 28:24, scratch66, 19:15);
|
||||
s(EmcDliTrimTxDqs2, 6:0, scratch66, 26:20);
|
||||
s(EmcTClkStop, 4:0, scratch66, 31:27);
|
||||
s(McEmemArbMisc1, 1:0, scratch67, 1:0);
|
||||
s(McEmemArbMisc1, 12:4, scratch67, 10:2);
|
||||
s(McEmemArbMisc1, 25:21, scratch67, 15:11);
|
||||
s(McEmemArbMisc1, 31:28, scratch67, 19:16);
|
||||
s(EmcDliTrimTxDqs3, 6:0, scratch67, 26:20);
|
||||
s(EmcEInputDuration, 4:0, scratch67, 31:27);
|
||||
s(EmcZcalMrwCmd, 7:0, scratch68, 7:0);
|
||||
s(EmcZcalMrwCmd, 23:16, scratch68, 15:8);
|
||||
s(EmcZcalMrwCmd, 31:30, scratch68, 17:16);
|
||||
s(EmcTRefBw, 13:0, scratch68, 31:18);
|
||||
s(EmcXm2CmdPadCtrl2, 31:14, scratch69, 17:0);
|
||||
s(EmcDliTrimTxDqs4, 6:0, scratch69, 24:18);
|
||||
s(EmcDliTrimTxDqs5, 6:0, scratch69, 31:25);
|
||||
s(EmcXm2CmdPadCtrl3, 31:14, scratch70, 17:0);
|
||||
s(EmcDliTrimTxDqs6, 6:0, scratch70, 24:18);
|
||||
s(EmcDliTrimTxDqs7, 6:0, scratch70, 31:25);
|
||||
s(EmcXm2CmdPadCtrl5, 2:0, scratch71, 2:0);
|
||||
s(EmcXm2CmdPadCtrl5, 6:4, scratch71, 5:3);
|
||||
s(EmcXm2CmdPadCtrl5, 10:8, scratch71, 8:6);
|
||||
s(EmcXm2CmdPadCtrl5, 14:12, scratch71, 11:9);
|
||||
s(EmcXm2CmdPadCtrl5, 18:16, scratch71, 14:12);
|
||||
s(EmcXm2CmdPadCtrl5, 22:20, scratch71, 17:15);
|
||||
s(EmcDliTrimTxDqs8, 6:0, scratch71, 24:18);
|
||||
s(EmcDliTrimTxDqs9, 6:0, scratch71, 31:25);
|
||||
s(EmcCdbCntl3, 17:0, scratch72, 17:0);
|
||||
s(EmcDliTrimTxDqs10, 6:0, scratch72, 24:18);
|
||||
s(EmcDliTrimTxDqs11, 6:0, scratch72, 31:25);
|
||||
s(EmcSwizzleRank0Byte0, 2:0, scratch73, 2:0);
|
||||
s(EmcSwizzleRank0Byte0, 6:4, scratch73, 5:3);
|
||||
s(EmcSwizzleRank0Byte0, 10:8, scratch73, 8:6);
|
||||
s(EmcSwizzleRank0Byte0, 14:12, scratch73, 11:9);
|
||||
s(EmcSwizzleRank0Byte0, 18:16, scratch73, 14:12);
|
||||
s(EmcSwizzleRank0Byte0, 22:20, scratch73, 17:15);
|
||||
s(EmcDliTrimTxDqs12, 6:0, scratch73, 24:18);
|
||||
s(EmcDliTrimTxDqs13, 6:0, scratch73, 31:25);
|
||||
s(EmcSwizzleRank0Byte1, 2:0, scratch74, 2:0);
|
||||
s(EmcSwizzleRank0Byte1, 6:4, scratch74, 5:3);
|
||||
s(EmcSwizzleRank0Byte1, 10:8, scratch74, 8:6);
|
||||
s(EmcSwizzleRank0Byte1, 14:12, scratch74, 11:9);
|
||||
s(EmcSwizzleRank0Byte1, 18:16, scratch74, 14:12);
|
||||
s(EmcSwizzleRank0Byte1, 22:20, scratch74, 17:15);
|
||||
s(EmcDliTrimTxDqs14, 6:0, scratch74, 24:18);
|
||||
s(EmcDliTrimTxDqs15, 6:0, scratch74, 31:25);
|
||||
s(EmcSwizzleRank0Byte2, 2:0, scratch75, 2:0);
|
||||
s(EmcSwizzleRank0Byte2, 6:4, scratch75, 5:3);
|
||||
s(EmcSwizzleRank0Byte2, 10:8, scratch75, 8:6);
|
||||
s(EmcSwizzleRank0Byte2, 14:12, scratch75, 11:9);
|
||||
s(EmcSwizzleRank0Byte2, 18:16, scratch75, 14:12);
|
||||
s(EmcSwizzleRank0Byte2, 22:20, scratch75, 17:15);
|
||||
s(McEmemArbTimingRp, 6:0, scratch75, 24:18);
|
||||
s(McEmemArbTimingRc, 6:0, scratch75, 31:25);
|
||||
s(EmcSwizzleRank0Byte3, 2:0, scratch76, 2:0);
|
||||
s(EmcSwizzleRank0Byte3, 6:4, scratch76, 5:3);
|
||||
s(EmcSwizzleRank0Byte3, 10:8, scratch76, 8:6);
|
||||
s(EmcSwizzleRank0Byte3, 14:12, scratch76, 11:9);
|
||||
s(EmcSwizzleRank0Byte3, 18:16, scratch76, 14:12);
|
||||
s(EmcSwizzleRank0Byte3, 22:20, scratch76, 17:15);
|
||||
s(McEmemArbTimingFaw, 6:0, scratch76, 24:18);
|
||||
s(McEmemArbTimingWap2Pre, 6:0, scratch76, 31:25);
|
||||
s(EmcSwizzleRank1Byte0, 2:0, scratch77, 2:0);
|
||||
s(EmcSwizzleRank1Byte0, 6:4, scratch77, 5:3);
|
||||
s(EmcSwizzleRank1Byte0, 10:8, scratch77, 8:6);
|
||||
s(EmcSwizzleRank1Byte0, 14:12, scratch77, 11:9);
|
||||
s(EmcSwizzleRank1Byte0, 18:16, scratch77, 14:12);
|
||||
s(EmcSwizzleRank1Byte0, 22:20, scratch77, 17:15);
|
||||
s(EmcRas, 5:0, scratch77, 23:18);
|
||||
s(EmcRp, 5:0, scratch77, 29:24);
|
||||
s(EmcCfg2, 9:8, scratch77, 31:30);
|
||||
s(EmcSwizzleRank1Byte1, 2:0, scratch78, 2:0);
|
||||
s(EmcSwizzleRank1Byte1, 6:4, scratch78, 5:3);
|
||||
s(EmcSwizzleRank1Byte1, 10:8, scratch78, 8:6);
|
||||
s(EmcSwizzleRank1Byte1, 14:12, scratch78, 11:9);
|
||||
s(EmcSwizzleRank1Byte1, 18:16, scratch78, 14:12);
|
||||
s(EmcSwizzleRank1Byte1, 22:20, scratch78, 17:15);
|
||||
s(EmcW2p, 5:0, scratch78, 23:18);
|
||||
s(EmcRdRcd, 5:0, scratch78, 29:24);
|
||||
s(EmcCfg2, 27:26, scratch78, 31:30);
|
||||
s(EmcSwizzleRank1Byte2, 2:0, scratch79, 2:0);
|
||||
s(EmcSwizzleRank1Byte2, 6:4, scratch79, 5:3);
|
||||
s(EmcSwizzleRank1Byte2, 10:8, scratch79, 8:6);
|
||||
s(EmcSwizzleRank1Byte2, 14:12, scratch79, 11:9);
|
||||
s(EmcSwizzleRank1Byte2, 18:16, scratch79, 14:12);
|
||||
s(EmcSwizzleRank1Byte2, 22:20, scratch79, 17:15);
|
||||
s(EmcWrRcd, 5:0, scratch79, 23:18);
|
||||
s(EmcQUse, 5:0, scratch79, 29:24);
|
||||
s(EmcFbioCfg5, 4:4, scratch79, 31:31);
|
||||
s(EmcSwizzleRank1Byte3, 2:0, scratch80, 2:0);
|
||||
s(EmcSwizzleRank1Byte3, 6:4, scratch80, 5:3);
|
||||
s(EmcSwizzleRank1Byte3, 10:8, scratch80, 8:6);
|
||||
s(EmcSwizzleRank1Byte3, 14:12, scratch80, 11:9);
|
||||
s(EmcSwizzleRank1Byte3, 18:16, scratch80, 14:12);
|
||||
s(EmcSwizzleRank1Byte3, 22:20, scratch80, 17:15);
|
||||
s(EmcQRst, 5:0, scratch80, 23:18);
|
||||
s(EmcRdv, 5:0, scratch80, 29:24);
|
||||
s(EmcFbioCfg5, 6:5, scratch80, 31:30);
|
||||
s(EmcDynSelfRefControl, 15:0, scratch81, 15:0);
|
||||
s(EmcDynSelfRefControl, 31:31, scratch81, 16:16);
|
||||
s(EmcPdEx2Wr, 5:0, scratch81, 22:17);
|
||||
s(EmcPdEx2Rd, 5:0, scratch81, 28:23);
|
||||
s(EmcRefresh, 5:0, scratch82, 5:0);
|
||||
s(EmcRefresh, 15:6, scratch82, 15:6);
|
||||
s(EmcCmdQ, 4:0, scratch82, 20:16);
|
||||
s(EmcCmdQ, 10:8, scratch82, 23:21);
|
||||
s(EmcCmdQ, 14:12, scratch82, 26:24);
|
||||
s(EmcCmdQ, 28:24, scratch82, 31:27);
|
||||
s(EmcAcpdControl, 15:0, scratch83, 15:0);
|
||||
s(EmcCfgDigDllPeriod, 15:0, scratch83, 31:16);
|
||||
s(EmcDllXformDqs0, 4:0, scratch84, 4:0);
|
||||
s(EmcDllXformDqs0, 22:12, scratch84, 15:5);
|
||||
s(EmcDllXformDqs1, 4:0, scratch84, 20:16);
|
||||
s(EmcDllXformDqs1, 22:12, scratch84, 31:21);
|
||||
s(EmcDllXformDqs2, 4:0, scratch85, 4:0);
|
||||
s(EmcDllXformDqs2, 22:12, scratch85, 15:5);
|
||||
s(EmcDllXformDqs3, 4:0, scratch85, 20:16);
|
||||
s(EmcDllXformDqs3, 22:12, scratch85, 31:21);
|
||||
s(EmcDllXformDqs4, 4:0, scratch86, 4:0);
|
||||
s(EmcDllXformDqs4, 22:12, scratch86, 15:5);
|
||||
s(EmcDllXformDqs5, 4:0, scratch86, 20:16);
|
||||
s(EmcDllXformDqs5, 22:12, scratch86, 31:21);
|
||||
s(EmcDllXformDqs6, 4:0, scratch87, 4:0);
|
||||
s(EmcDllXformDqs6, 22:12, scratch87, 15:5);
|
||||
s(EmcDllXformDqs7, 4:0, scratch87, 20:16);
|
||||
s(EmcDllXformDqs7, 22:12, scratch87, 31:21);
|
||||
s(EmcDllXformDqs8, 4:0, scratch88, 4:0);
|
||||
s(EmcDllXformDqs8, 22:12, scratch88, 15:5);
|
||||
s(EmcDllXformDqs9, 4:0, scratch88, 20:16);
|
||||
s(EmcDllXformDqs9, 22:12, scratch88, 31:21);
|
||||
s(EmcDllXformDqs10, 4:0, scratch89, 4:0);
|
||||
s(EmcDllXformDqs10, 22:12, scratch89, 15:5);
|
||||
s(EmcDllXformDqs11, 4:0, scratch89, 20:16);
|
||||
s(EmcDllXformDqs11, 22:12, scratch89, 31:21);
|
||||
s(EmcDllXformDqs12, 4:0, scratch90, 4:0);
|
||||
s(EmcDllXformDqs12, 22:12, scratch90, 15:5);
|
||||
s(EmcDllXformDqs13, 4:0, scratch90, 20:16);
|
||||
s(EmcDllXformDqs13, 22:12, scratch90, 31:21);
|
||||
s(EmcDllXformDqs14, 4:0, scratch91, 4:0);
|
||||
s(EmcDllXformDqs14, 22:12, scratch91, 15:5);
|
||||
s(EmcDllXformDqs15, 4:0, scratch91, 20:16);
|
||||
s(EmcDllXformDqs15, 22:12, scratch91, 31:21);
|
||||
s(EmcDllXformQUse0, 4:0, scratch92, 4:0);
|
||||
s(EmcDllXformQUse0, 22:12, scratch92, 15:5);
|
||||
s(EmcDllXformQUse1, 4:0, scratch92, 20:16);
|
||||
s(EmcDllXformQUse1, 22:12, scratch92, 31:21);
|
||||
s(EmcDllXformQUse2, 4:0, scratch93, 4:0);
|
||||
s(EmcDllXformQUse2, 22:12, scratch93, 15:5);
|
||||
s(EmcDllXformQUse3, 4:0, scratch93, 20:16);
|
||||
s(EmcDllXformQUse3, 22:12, scratch93, 31:21);
|
||||
s(EmcDllXformQUse4, 4:0, scratch94, 4:0);
|
||||
s(EmcDllXformQUse4, 22:12, scratch94, 15:5);
|
||||
s(EmcDllXformQUse5, 4:0, scratch94, 20:16);
|
||||
s(EmcDllXformQUse5, 22:12, scratch94, 31:21);
|
||||
s(EmcDllXformQUse6, 4:0, scratch95, 4:0);
|
||||
s(EmcDllXformQUse6, 22:12, scratch95, 15:5);
|
||||
s(EmcDllXformQUse7, 4:0, scratch95, 20:16);
|
||||
s(EmcDllXformQUse7, 22:12, scratch95, 31:21);
|
||||
s(EmcDllXformDq0, 4:0, scratch96, 4:0);
|
||||
s(EmcDllXformDq0, 22:12, scratch96, 15:5);
|
||||
s(EmcDllXformDq1, 4:0, scratch96, 20:16);
|
||||
s(EmcDllXformDq1, 22:12, scratch96, 31:21);
|
||||
s(EmcDllXformDq2, 4:0, scratch97, 4:0);
|
||||
s(EmcDllXformDq2, 22:12, scratch97, 15:5);
|
||||
s(EmcDllXformDq3, 4:0, scratch97, 20:16);
|
||||
s(EmcDllXformDq3, 22:12, scratch97, 31:21);
|
||||
s(EmcPreRefreshReqCnt, 15:0, scratch98, 15:0);
|
||||
s(EmcDllXformAddr0, 4:0, scratch98, 20:16);
|
||||
s(EmcDllXformAddr0, 22:12, scratch98, 31:21);
|
||||
s(EmcDllXformAddr1, 4:0, scratch99, 4:0);
|
||||
s(EmcDllXformAddr1, 22:12, scratch99, 15:5);
|
||||
s(EmcDllXformAddr2, 4:0, scratch99, 20:16);
|
||||
s(EmcDllXformAddr2, 22:12, scratch99, 31:21);
|
||||
s(EmcDllXformAddr3, 4:0, scratch100, 4:0);
|
||||
s(EmcDllXformAddr3, 22:12, scratch100, 15:5);
|
||||
s(EmcDllXformAddr4, 4:0, scratch100, 20:16);
|
||||
s(EmcDllXformAddr4, 22:12, scratch100, 31:21);
|
||||
s(EmcDllXformAddr5, 4:0, scratch101, 4:0);
|
||||
s(EmcDllXformAddr5, 22:12, scratch101, 15:5);
|
||||
s(EmcPChg2Pden, 5:0, scratch102, 5:0);
|
||||
s(EmcAct2Pden, 5:0, scratch102, 11:6);
|
||||
s(EmcRw2Pden, 5:0, scratch102, 17:12);
|
||||
s(EmcTcke, 5:0, scratch102, 23:18);
|
||||
s(EmcTrpab, 5:0, scratch102, 29:24);
|
||||
s(EmcFbioCfg5, 8:7, scratch102, 31:30);
|
||||
s(EmcCtt, 5:0, scratch103, 5:0);
|
||||
s(EmcEInput, 5:0, scratch103, 11:6);
|
||||
s(EmcPutermExtra, 21:16, scratch103, 17:12);
|
||||
s(EmcTckesr, 5:0, scratch103, 23:18);
|
||||
s(EmcTpd, 5:0, scratch103, 29:24);
|
||||
s(EmcFbioCfg5, 10:9, scratch103, 31:30);
|
||||
s(EmcRdvMask, 5:0, scratch104, 5:0);
|
||||
s(EmcXm2CmdPadCtrl4, 0:0, scratch104, 6:6);
|
||||
s(EmcXm2CmdPadCtrl4, 2:2, scratch104, 7:7);
|
||||
s(EmcXm2CmdPadCtrl4, 4:4, scratch104, 8:8);
|
||||
s(EmcXm2CmdPadCtrl4, 6:6, scratch104, 9:9);
|
||||
s(EmcXm2CmdPadCtrl4, 8:8, scratch104, 10:10);
|
||||
s(EmcXm2CmdPadCtrl4, 10:10, scratch104, 11:11);
|
||||
s(EmcQpop, 5:0, scratch104, 17:12);
|
||||
s(McEmemArbTimingRcd, 5:0, scratch104, 23:18);
|
||||
s(McEmemArbTimingRas, 5:0, scratch104, 29:24);
|
||||
s(EmcFbioCfg5, 12:11, scratch104, 31:30);
|
||||
s(McEmemArbTimingRap2Pre, 5:0, scratch105, 5:0);
|
||||
s(McEmemArbTimingR2W, 5:0, scratch105, 11:6);
|
||||
s(McEmemArbTimingW2R, 5:0, scratch105, 17:12);
|
||||
s(EmcIbdly, 4:0, scratch105, 22:18);
|
||||
s(McEmemArbTimingR2R, 4:0, scratch105, 27:23);
|
||||
s(EmcW2w, 3:0, scratch105, 31:28);
|
||||
s(McEmemArbTimingW2W, 4:0, scratch106, 4:0);
|
||||
s(McEmemArbOverride, 27:27, scratch106, 5:5);
|
||||
s(McEmemArbOverride, 26:26, scratch106, 6:6);
|
||||
s(McEmemArbOverride, 16:16, scratch106, 7:7);
|
||||
s(McEmemArbOverride, 10:10, scratch106, 8:8);
|
||||
s(McEmemArbOverride, 4:4, scratch106, 9:9);
|
||||
s(EmcWdvMask, 3:0, scratch106, 13:10);
|
||||
s(EmcCttDuration, 3:0, scratch106, 17:14);
|
||||
s(EmcQuseWidth, 3:0, scratch106, 21:18);
|
||||
s(EmcPutermWidth, 3:0, scratch106, 25:22);
|
||||
s(EmcBgbiasCtl0, 3:0, scratch106, 29:26);
|
||||
s(EmcFbioCfg5, 25:24, scratch106, 31:30);
|
||||
s(McEmemArbTimingRrd, 3:0, scratch107, 3:0);
|
||||
s(EmcFbioCfg5, 23:20, scratch107, 10:7);
|
||||
s(EmcFbioCfg5, 15:13, scratch107, 13:11);
|
||||
s(EmcCfg2, 5:3, scratch107, 16:14);
|
||||
s(EmcFbioCfg5, 26:26, scratch107, 17:17);
|
||||
s(EmcFbioCfg5, 28:28, scratch107, 18:18);
|
||||
s(EmcCfg2, 2:0, scratch107, 21:19);
|
||||
s(EmcCfg2, 7:6, scratch107, 23:22);
|
||||
s(EmcCfg2, 15:10, scratch107, 29:24);
|
||||
s(EmcCfg2, 23:22, scratch107, 31:30);
|
||||
s(EmcCfg2, 25:24, scratch108, 1:0);
|
||||
s(EmcCfg2, 31:28, scratch108, 5:2);
|
||||
s(BootRomPatchData, 31:0, scratch15, 31:0);
|
||||
s(BootRomPatchControl, 31:0, scratch16, 31:0);
|
||||
s(EmcDevSelect, 1:0, scratch17, 31:30);
|
||||
s(EmcZcalWarmColdBootEnables, 1:0, scratch18, 31:30);
|
||||
s(EmcCfgDigDllPeriodWarmBoot, 1:0, scratch19, 31:30);
|
||||
s(EmcWarmBootExtraModeRegWriteEnable, 0:0, scratch46, 30:30);
|
||||
s(McClkenOverrideAllWarmBoot, 0:0, scratch46, 31:31);
|
||||
s(EmcClkenOverrideAllWarmBoot, 0:0, scratch47, 30:30);
|
||||
s(EmcMrsWarmBootEnable, 0:0, scratch47, 31:31);
|
||||
s(EmcTimingControlWait, 7:0, scratch57, 27:20);
|
||||
s(EmcZcalWarmBootWait, 7:0, scratch58, 27:20);
|
||||
s(EmcAutoCalWait, 7:0, scratch59, 27:20);
|
||||
s(WarmBootWait, 7:0, scratch60, 27:20);
|
||||
s(EmcPinProgramWait, 7:0, scratch61, 27:20);
|
||||
s(AhbArbitrationXbarCtrlMemInitDone, 0:0, scratch79, 30:30);
|
||||
s(EmcExtraRefreshNum, 2:0, scratch81, 31:29);
|
||||
s(SwizzleRankByteEncode, 15:0, scratch101, 31:16);
|
||||
s(MemoryType, 2:0, scratch107, 6:4);
|
||||
|
||||
switch (sdram->MemoryType) {
|
||||
case NvBootMemoryType_LpDdr2:
|
||||
s(EmcMrwLpddr2ZcalWarmBoot, 23:16, scratch5, 7:0);
|
||||
s(EmcMrwLpddr2ZcalWarmBoot, 7:0, scratch5, 15:8);
|
||||
s(EmcWarmBootMrwExtra, 23:16, scratch5, 23:16);
|
||||
s(EmcWarmBootMrwExtra, 7:0, scratch5, 31:24);
|
||||
s(EmcMrwLpddr2ZcalWarmBoot, 31:30, scratch6, 1:0);
|
||||
s(EmcWarmBootMrwExtra, 31:30, scratch6, 3:2);
|
||||
s(EmcMrwLpddr2ZcalWarmBoot, 27:26, scratch6, 5:4);
|
||||
s(EmcWarmBootMrwExtra, 27:26, scratch6, 7:6);
|
||||
s(EmcMrw1, 7:0, scratch7, 7:0);
|
||||
s(EmcMrw1, 23:16, scratch7, 15:8);
|
||||
s(EmcMrw1, 27:26, scratch7, 17:16);
|
||||
s(EmcMrw1, 31:30, scratch7, 19:18);
|
||||
s(EmcMrw2, 7:0, scratch8, 7:0);
|
||||
s(EmcMrw2, 23:16, scratch8, 15:8);
|
||||
s(EmcMrw2, 27:26, scratch8, 17:16);
|
||||
s(EmcMrw2, 31:30, scratch8, 19:18);
|
||||
s(EmcMrw3, 7:0, scratch9, 7:0);
|
||||
s(EmcMrw3, 23:16, scratch9, 15:8);
|
||||
s(EmcMrw3, 27:26, scratch9, 17:16);
|
||||
s(EmcMrw3, 31:30, scratch9, 19:18);
|
||||
s(EmcMrw4, 7:0, scratch10, 7:0);
|
||||
s(EmcMrw4, 23:16, scratch10, 15:8);
|
||||
s(EmcMrw4, 27:26, scratch10, 17:16);
|
||||
s(EmcMrw4, 31:30, scratch10, 19:18);
|
||||
break;
|
||||
case NvBootMemoryType_Ddr3:
|
||||
s(EmcMrs, 13:0, scratch5, 13:0);
|
||||
s(EmcEmrs, 13:0, scratch5, 27:14);
|
||||
s(EmcMrs, 21:20, scratch5, 29:28);
|
||||
s(EmcMrs, 31:30, scratch5, 31:30);
|
||||
s(EmcEmrs2, 13:0, scratch7, 13:0);
|
||||
s(EmcEmrs, 21:20, scratch7, 15:14);
|
||||
s(EmcEmrs, 31:30, scratch7, 17:16);
|
||||
s(EmcEmrs2, 21:20, scratch7, 19:18);
|
||||
s(EmcEmrs3, 13:0, scratch8, 13:0);
|
||||
s(EmcEmrs2, 31:30, scratch8, 15:14);
|
||||
s(EmcEmrs3, 21:20, scratch8, 17:16);
|
||||
s(EmcEmrs3, 31:30, scratch8, 19:18);
|
||||
s(EmcWarmBootMrsExtra, 13:0, scratch9, 13:0);
|
||||
s(EmcWarmBootMrsExtra, 31:30, scratch9, 15:14);
|
||||
s(EmcWarmBootMrsExtra, 21:20, scratch9, 17:16);
|
||||
s(EmcZqCalDdr3WarmBoot, 31:30, scratch9, 19:18);
|
||||
s(EmcMrs, 27:26, scratch10, 1:0);
|
||||
s(EmcEmrs, 27:26, scratch10, 3:2);
|
||||
s(EmcEmrs2, 27:26, scratch10, 5:4);
|
||||
s(EmcEmrs3, 27:26, scratch10, 7:6);
|
||||
s(EmcWarmBootMrsExtra, 27:27, scratch10, 8:8);
|
||||
s(EmcWarmBootMrsExtra, 26:26, scratch10, 9:9);
|
||||
s(EmcZqCalDdr3WarmBoot, 0:0, scratch10, 10:10);
|
||||
s(EmcZqCalDdr3WarmBoot, 4:4, scratch10, 11:11);
|
||||
c(0, scratch116, 31:0);
|
||||
c(0, scratch117, 31:0);
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_CRIT, "ERROR: %s() unrecognized MemoryType %d!\n",
|
||||
__func__, sdram->MemoryType);
|
||||
}
|
||||
|
||||
s(McVideoProtectGpuOverride0, 31:0, secure_scratch8, 31:0);
|
||||
s(McVideoProtectVprOverride, 3:0, secure_scratch9, 3:0);
|
||||
s(McVideoProtectVprOverride, 11:6, secure_scratch9, 9:4);
|
||||
s(McVideoProtectVprOverride, 23:14, secure_scratch9, 19:10);
|
||||
s(McVideoProtectVprOverride, 26:26, secure_scratch9, 20:20);
|
||||
s(McVideoProtectVprOverride, 31:29, secure_scratch9, 23:21);
|
||||
s(EmcFbioCfg5, 19:16, secure_scratch9, 27:24);
|
||||
s(McDisplaySnapRing, 1:0, secure_scratch9, 29:28);
|
||||
s(McDisplaySnapRing, 31:31, secure_scratch9, 30:30);
|
||||
s(EmcAdrCfg, 0:0, secure_scratch9, 31:31);
|
||||
s(McVideoProtectGpuOverride1, 15:0, secure_scratch10, 15:0);
|
||||
s(McEmemAdrCfgBankMask0, 15:0, secure_scratch10, 31:16);
|
||||
s(McEmemAdrCfgBankMask1, 15:0, secure_scratch11, 15:0);
|
||||
s(McEmemAdrCfgBankMask2, 15:0, secure_scratch11, 31:16);
|
||||
s(McEmemCfg, 13:0, secure_scratch12, 13:0);
|
||||
s(McEmemCfg, 31:31, secure_scratch12, 14:14);
|
||||
s(McVideoProtectBom, 31:20, secure_scratch12, 26:15);
|
||||
s(McVideoProtectVprOverride1, 1:0, secure_scratch12, 28:27);
|
||||
s(McVideoProtectVprOverride1, 4:4, secure_scratch12, 29:29);
|
||||
s(McVideoProtectBomAdrHi, 1:0, secure_scratch12, 31:30);
|
||||
s(McVideoProtectSizeMb, 11:0, secure_scratch13, 11:0);
|
||||
s(McSecCarveoutBom, 31:20, secure_scratch13, 23:12);
|
||||
s(McEmemAdrCfgBankSwizzle3, 2:0, secure_scratch13, 26:24);
|
||||
s(McVideoProtectWriteAccess, 1:0, secure_scratch13, 28:27);
|
||||
s(McSecCarveoutAdrHi, 1:0, secure_scratch13, 30:29);
|
||||
s(McEmemAdrCfg, 0:0, secure_scratch13, 31:31);
|
||||
s(McSecCarveoutSizeMb, 11:0, secure_scratch14, 11:0);
|
||||
s(McMtsCarveoutBom, 31:20, secure_scratch14, 23:12);
|
||||
s(McMtsCarveoutAdrHi, 1:0, secure_scratch14, 25:24);
|
||||
s(McSecCarveoutProtectWriteAccess, 0:0, secure_scratch14, 26:26);
|
||||
s(McMtsCarveoutRegCtrl, 0:0, secure_scratch14, 27:27);
|
||||
s(McMtsCarveoutSizeMb, 11:0, secure_scratch15, 11:0);
|
||||
s(McEmemAdrCfgDev0, 2:0, secure_scratch15, 14:12);
|
||||
s(McEmemAdrCfgDev0, 9:8, secure_scratch15, 16:15);
|
||||
s(McEmemAdrCfgDev0, 19:16, secure_scratch15, 20:17);
|
||||
s(McEmemAdrCfgDev1, 2:0, secure_scratch15, 23:21);
|
||||
s(McEmemAdrCfgDev1, 9:8, secure_scratch15, 25:24);
|
||||
s(McEmemAdrCfgDev1, 19:16, secure_scratch15, 29:26);
|
||||
|
||||
c(0x1555555, sec_disable2, 25:0);
|
||||
c(0xff, sec_disable, 19:12);
|
||||
|
||||
c(0, scratch2, 31:0);
|
||||
m(pllm_base, 15:0, scratch2, 15:0);
|
||||
m(pllm_base, 20:20, scratch2, 16:16);
|
||||
m(pllm_misc2, 2:0, scratch2, 19:17);
|
||||
c(0, scratch35, 31:0);
|
||||
m(pllm_misc1, 23:0, scratch35, 23:0);
|
||||
m(pllm_misc1, 30:28, scratch35, 30:28);
|
||||
c(0, scratch3, 31:0);
|
||||
s(PllMInputDivider, 7:0, scratch3, 7:0);
|
||||
c(0x3e, scratch3, 15:8);
|
||||
c(0, scratch3, 19:16);
|
||||
s(PllMKVCO, 0:0, scratch3, 20:20);
|
||||
s(PllMKCP, 1:0, scratch3, 22:21);
|
||||
c(0, scratch36, 31:0);
|
||||
s(PllMSetupControl, 23:0, scratch36, 23:0);
|
||||
c(0, scratch4, 31:0);
|
||||
s(PllMStableTime, 9:0, scratch4, 9:0);
|
||||
s(PllMStableTime, 9:0, scratch4, 19:10);
|
||||
|
||||
s(PllMSelectDiv2, 0:0, pllm_wb0_override2, 27:27);
|
||||
s(PllMKVCO, 0:0, pllm_wb0_override2, 26:26);
|
||||
s(PllMKCP, 1:0, pllm_wb0_override2, 25:24);
|
||||
s(PllMSetupControl, 23:0, pllm_wb0_override2, 23:0);
|
||||
s(PllMFeedbackDivider, 7:0, pllm_wb0_override_freq, 15:8);
|
||||
s(PllMInputDivider, 7:0, pllm_wb0_override_freq, 7:0);
|
||||
|
||||
c(3, pllp_wb0_override, 12:11);
|
||||
}
|
50
src/soc/nvidia/tegra210/secmon.c
Normal file
50
src/soc/nvidia/tegra210/secmon.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/secmon.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/mmu_operations.h>
|
||||
|
||||
static void soc_get_secure_mem(uint64_t *base, size_t *size)
|
||||
{
|
||||
uintptr_t tz_base_mib;
|
||||
size_t tz_size_mib;
|
||||
|
||||
carveout_range(CARVEOUT_TZ, &tz_base_mib, &tz_size_mib);
|
||||
|
||||
tz_base_mib *= MiB;
|
||||
tz_size_mib *= MiB;
|
||||
|
||||
*base = tz_base_mib;
|
||||
*size = tz_size_mib;
|
||||
}
|
||||
|
||||
void soc_get_secmon_base_size(uint64_t *base, size_t *size)
|
||||
{
|
||||
uintptr_t tz_base;
|
||||
size_t ttb_size, tz_size;
|
||||
|
||||
soc_get_secure_mem(&tz_base, &tz_size);
|
||||
|
||||
ttb_size = TTB_SIZE * MiB;
|
||||
|
||||
*base = tz_base + ttb_size;
|
||||
*size = tz_size - ttb_size;
|
||||
}
|
191
src/soc/nvidia/tegra210/soc.c
Normal file
191
src/soc/nvidia/tegra210/soc.c
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <arch/cache.h>
|
||||
#include <arch/spintable.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <bootstate.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <soc/nvidia/tegra/dc.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/cpu.h>
|
||||
#include <soc/mc.h>
|
||||
#include <soc/mtc.h>
|
||||
#include <soc/nvidia/tegra/apbmisc.h>
|
||||
#include <string.h>
|
||||
#include <timer.h>
|
||||
#include <vendorcode/google/chromeos/chromeos.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
static void soc_read_resources(device_t dev)
|
||||
{
|
||||
unsigned long index = 0;
|
||||
int i; uintptr_t begin, end;
|
||||
size_t size;
|
||||
|
||||
for (i = 0; i < CARVEOUT_NUM; i++) {
|
||||
carveout_range(i, &begin, &size);
|
||||
if (size == 0)
|
||||
continue;
|
||||
reserved_ram_resource(dev, index++, begin * KiB, size * KiB);
|
||||
}
|
||||
|
||||
memory_in_range_below_4gb(&begin, &end);
|
||||
size = end - begin;
|
||||
ram_resource(dev, index++, begin * KiB, size * KiB);
|
||||
|
||||
memory_in_range_above_4gb(&begin, &end);
|
||||
size = end - begin;
|
||||
ram_resource(dev, index++, begin * KiB, size * KiB);
|
||||
}
|
||||
|
||||
static size_t cntrl_total_cpus(void)
|
||||
{
|
||||
return CONFIG_MAX_CPUS;
|
||||
}
|
||||
|
||||
static int cntrl_start_cpu(unsigned int id, void (*entry)(void))
|
||||
{
|
||||
if (id >= CONFIG_MAX_CPUS)
|
||||
return -1;
|
||||
start_cpu(id, entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpu_control_ops cntrl_ops = {
|
||||
.total_cpus = cntrl_total_cpus,
|
||||
.start_cpu = cntrl_start_cpu,
|
||||
};
|
||||
|
||||
|
||||
static void lock_down_vpr(void)
|
||||
{
|
||||
struct tegra_mc_regs *regs = (void *)(uintptr_t)TEGRA_MC_BASE;
|
||||
|
||||
write32(®s->video_protect_bom, 0);
|
||||
write32(®s->video_protect_size_mb, 0);
|
||||
|
||||
write32(®s->video_protect_gpu_override_0, 1);
|
||||
/*
|
||||
* Set both _ACCESS bits so that kernel/secure code
|
||||
* can reconfig VPR careveout as needed from the TrustZone.
|
||||
*/
|
||||
|
||||
write32(®s->video_protect_reg_ctrl,
|
||||
(MC_VPR_WR_ACCESS_DISABLE | MC_VPR_ALLOW_TZ_WR_ACCESS_ENABLE));
|
||||
}
|
||||
|
||||
static void soc_init(device_t dev)
|
||||
{
|
||||
struct soc_nvidia_tegra210_config *cfg;
|
||||
|
||||
clock_init_arm_generic_timer();
|
||||
|
||||
cfg = dev->chip_info;
|
||||
spintable_init((void *)cfg->spintable_addr);
|
||||
arch_initialize_cpus(dev, &cntrl_ops);
|
||||
|
||||
/* Lock down VPR */
|
||||
lock_down_vpr();
|
||||
|
||||
#if IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT)
|
||||
if (vboot_skip_display_init())
|
||||
printk(BIOS_INFO, "Skipping display init.\n");
|
||||
else
|
||||
display_startup(dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void soc_noop(device_t dev)
|
||||
{
|
||||
}
|
||||
|
||||
static struct device_operations soc_ops = {
|
||||
.read_resources = soc_read_resources,
|
||||
.set_resources = soc_noop,
|
||||
.enable_resources = soc_noop,
|
||||
.init = soc_init,
|
||||
.scan_bus = NULL,
|
||||
};
|
||||
|
||||
static void enable_tegra210_dev(device_t dev)
|
||||
{
|
||||
if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
|
||||
dev->ops = &soc_ops;
|
||||
}
|
||||
|
||||
static void tegra210_init(void *chip_info)
|
||||
{
|
||||
struct tegra_revision rev;
|
||||
|
||||
tegra_revision_info(&rev);
|
||||
|
||||
printk(BIOS_INFO, "chip %x rev %02x.%x\n",
|
||||
rev.chip_id, rev.major, rev.minor);
|
||||
}
|
||||
|
||||
struct chip_operations soc_nvidia_tegra210_ops = {
|
||||
CHIP_NAME("SOC Nvidia Tegra210")
|
||||
.init = tegra210_init,
|
||||
.enable_dev = enable_tegra210_dev,
|
||||
};
|
||||
|
||||
static void tegra210_cpu_init(device_t cpu)
|
||||
{
|
||||
if (cpu_is_bsp())
|
||||
if (tegra210_run_mtc() != 0)
|
||||
printk(BIOS_ERR, "MTC: Training failed\n");
|
||||
}
|
||||
|
||||
static const struct cpu_device_id ids[] = {
|
||||
{ 0x411fd071 },
|
||||
{ CPU_ID_END },
|
||||
};
|
||||
|
||||
static struct device_operations cpu_dev_ops = {
|
||||
.init = tegra210_cpu_init,
|
||||
};
|
||||
|
||||
static const struct cpu_driver driver __cpu_driver = {
|
||||
.ops = &cpu_dev_ops,
|
||||
.id_table = ids,
|
||||
};
|
||||
|
||||
static void enable_plld(void *unused)
|
||||
{
|
||||
/*
|
||||
* Configure a conservative 300MHz clock for PLLD. The kernel cannot
|
||||
* handle PLLD not being configured so enable PLLD unconditionally
|
||||
* with a default clock rate.
|
||||
*/
|
||||
clock_configure_plld(300 * MHz);
|
||||
}
|
||||
|
||||
/*
|
||||
* The PLLD being enabled is done at BS_DEV_INIT time because mainboard_init()
|
||||
* is the first thing called. This ensures PLLD is up and functional before
|
||||
* anything that mainboard can do that implicitly relies on PLLD.
|
||||
*/
|
||||
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, enable_plld, NULL);
|
1100
src/soc/nvidia/tegra210/sor.c
Normal file
1100
src/soc/nvidia/tegra210/sor.c
Normal file
File diff suppressed because it is too large
Load Diff
960
src/soc/nvidia/tegra210/spi.c
Normal file
960
src/soc/nvidia/tegra210/spi.c
Normal file
@ -0,0 +1,960 @@
|
||||
/*
|
||||
* NVIDIA Tegra SPI controller (T114 and later)
|
||||
*
|
||||
* Copyright (c) 2010-2013 NVIDIA Corporation
|
||||
* Copyright (C) 2013 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.
|
||||
*/
|
||||
|
||||
#include <arch/cache.h>
|
||||
#include <arch/io.h>
|
||||
#include <assert.h>
|
||||
#include <boot_device.h>
|
||||
#include <cbfs.h>
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <inttypes.h>
|
||||
#include <spi-generic.h>
|
||||
#include <spi_flash.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/dma.h>
|
||||
#include <soc/spi.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <symbols.h>
|
||||
#include <timer.h>
|
||||
|
||||
|
||||
#if defined(CONFIG_DEBUG_SPI) && CONFIG_DEBUG_SPI
|
||||
# define DEBUG_SPI(x,...) printk(BIOS_DEBUG, "TEGRA_SPI: " x)
|
||||
#else
|
||||
# define DEBUG_SPI(x,...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 64 packets in FIFO mode, BLOCK_SIZE packets in DMA mode. Packets can vary
|
||||
* in size from 4 to 32 bits. To keep things simple we'll use 8-bit packets.
|
||||
*/
|
||||
#define SPI_PACKET_SIZE_BYTES 1
|
||||
#define SPI_MAX_TRANSFER_BYTES_FIFO (64 * SPI_PACKET_SIZE_BYTES)
|
||||
#define SPI_MAX_TRANSFER_BYTES_DMA (65535 * SPI_PACKET_SIZE_BYTES)
|
||||
|
||||
/*
|
||||
* This is used to workaround an issue seen where it may take some time for
|
||||
* packets to show up in the FIFO after they have been received and the
|
||||
* BLOCK_COUNT has been incremented.
|
||||
*/
|
||||
#define SPI_FIFO_XFER_TIMEOUT_US 1000
|
||||
|
||||
/* COMMAND1 */
|
||||
#define SPI_CMD1_GO (1 << 31)
|
||||
#define SPI_CMD1_M_S (1 << 30)
|
||||
#define SPI_CMD1_MODE_MASK 0x3
|
||||
#define SPI_CMD1_MODE_SHIFT 28
|
||||
#define SPI_CMD1_CS_SEL_MASK 0x3
|
||||
#define SPI_CMD1_CS_SEL_SHIFT 26
|
||||
#define SPI_CMD1_CS_POL_INACTIVE3 (1 << 25)
|
||||
#define SPI_CMD1_CS_POL_INACTIVE2 (1 << 24)
|
||||
#define SPI_CMD1_CS_POL_INACTIVE1 (1 << 23)
|
||||
#define SPI_CMD1_CS_POL_INACTIVE0 (1 << 22)
|
||||
#define SPI_CMD1_CS_SW_HW (1 << 21)
|
||||
#define SPI_CMD1_CS_SW_VAL (1 << 20)
|
||||
#define SPI_CMD1_IDLE_SDA_MASK 0x3
|
||||
#define SPI_CMD1_IDLE_SDA_SHIFT 18
|
||||
#define SPI_CMD1_BIDIR (1 << 17)
|
||||
#define SPI_CMD1_LSBI_FE (1 << 16)
|
||||
#define SPI_CMD1_LSBY_FE (1 << 15)
|
||||
#define SPI_CMD1_BOTH_EN_BIT (1 << 14)
|
||||
#define SPI_CMD1_BOTH_EN_BYTE (1 << 13)
|
||||
#define SPI_CMD1_RX_EN (1 << 12)
|
||||
#define SPI_CMD1_TX_EN (1 << 11)
|
||||
#define SPI_CMD1_PACKED (1 << 5)
|
||||
#define SPI_CMD1_BIT_LEN_MASK 0x1f
|
||||
#define SPI_CMD1_BIT_LEN_SHIFT 0
|
||||
|
||||
/* COMMAND2 */
|
||||
#define SPI_CMD2_TX_CLK_TAP_DELAY (1 << 6)
|
||||
#define SPI_CMD2_TX_CLK_TAP_DELAY_MASK (0x3F << 6)
|
||||
#define SPI_CMD2_RX_CLK_TAP_DELAY (1 << 0)
|
||||
#define SPI_CMD2_RX_CLK_TAP_DELAY_MASK (0x3F << 0)
|
||||
|
||||
/* SPI_TRANS_STATUS */
|
||||
#define SPI_STATUS_RDY (1 << 30)
|
||||
#define SPI_STATUS_SLV_IDLE_COUNT_MASK 0xff
|
||||
#define SPI_STATUS_SLV_IDLE_COUNT_SHIFT 16
|
||||
#define SPI_STATUS_BLOCK_COUNT 0xffff
|
||||
#define SPI_STATUS_BLOCK_COUNT_SHIFT 0
|
||||
|
||||
/* SPI_FIFO_STATUS */
|
||||
#define SPI_FIFO_STATUS_CS_INACTIVE (1 << 31)
|
||||
#define SPI_FIFO_STATUS_FRAME_END (1 << 30)
|
||||
#define SPI_FIFO_STATUS_RX_FIFO_FULL_COUNT_MASK 0x7f
|
||||
#define SPI_FIFO_STATUS_RX_FIFO_FULL_COUNT_SHIFT 23
|
||||
#define SPI_FIFO_STATUS_TX_FIFO_EMPTY_COUNT_MASK 0x7f
|
||||
#define SPI_FIFO_STATUS_TX_FIFO_EMPTY_COUNT_SHIFT 16
|
||||
#define SPI_FIFO_STATUS_RX_FIFO_FLUSH (1 << 15)
|
||||
#define SPI_FIFO_STATUS_TX_FIFO_FLUSH (1 << 14)
|
||||
#define SPI_FIFO_STATUS_ERR (1 << 8)
|
||||
#define SPI_FIFO_STATUS_TX_FIFO_OVF (1 << 7)
|
||||
#define SPI_FIFO_STATUS_TX_FIFO_UNR (1 << 6)
|
||||
#define SPI_FIFO_STATUS_RX_FIFO_OVF (1 << 5)
|
||||
#define SPI_FIFO_STATUS_RX_FIFO_UNR (1 << 4)
|
||||
#define SPI_FIFO_STATUS_TX_FIFO_FULL (1 << 3)
|
||||
#define SPI_FIFO_STATUS_TX_FIFO_EMPTY (1 << 2)
|
||||
#define SPI_FIFO_STATUS_RX_FIFO_FULL (1 << 1)
|
||||
#define SPI_FIFO_STATUS_RX_FIFO_EMPTY (1 << 0)
|
||||
|
||||
/* SPI_DMA_CTL */
|
||||
#define SPI_DMA_CTL_DMA (1 << 31)
|
||||
#define SPI_DMA_CTL_CONT (1 << 30)
|
||||
#define SPI_DMA_CTL_IE_RX (1 << 29)
|
||||
#define SPI_DMA_CTL_IE_TX (1 << 28)
|
||||
#define SPI_DMA_CTL_RX_TRIG_MASK 0x3
|
||||
#define SPI_DMA_CTL_RX_TRIG_SHIFT 19
|
||||
#define SPI_DMA_CTL_TX_TRIG_MASK 0x3
|
||||
#define SPI_DMA_CTL_TX_TRIG_SHIFT 15
|
||||
|
||||
/* SPI_DMA_BLK */
|
||||
#define SPI_DMA_CTL_BLOCK_SIZE_MASK 0xffff
|
||||
#define SPI_DMA_CTL_BLOCK_SIZE_SHIFT 0
|
||||
|
||||
static struct tegra_spi_channel tegra_spi_channels[] = {
|
||||
/*
|
||||
* Note: Tegra pinmux must be setup for corresponding SPI channel in
|
||||
* order for its registers to be accessible. If pinmux has not been
|
||||
* set up, access to the channel's registers will simply hang.
|
||||
*
|
||||
* TODO(dhendrix): Clarify or remove this comment (is clock setup
|
||||
* necessary first, or just pinmux, or both?)
|
||||
*/
|
||||
{
|
||||
.slave = { .bus = 1, },
|
||||
.regs = (struct tegra_spi_regs *)TEGRA_SPI1_BASE,
|
||||
.req_sel = APBDMA_SLAVE_SL2B1,
|
||||
},
|
||||
{
|
||||
.slave = { .bus = 2, },
|
||||
.regs = (struct tegra_spi_regs *)TEGRA_SPI2_BASE,
|
||||
.req_sel = APBDMA_SLAVE_SL2B2,
|
||||
},
|
||||
{
|
||||
.slave = { .bus = 3, },
|
||||
.regs = (struct tegra_spi_regs *)TEGRA_SPI3_BASE,
|
||||
.req_sel = APBDMA_SLAVE_SL2B3,
|
||||
},
|
||||
{
|
||||
.slave = { .bus = 4, },
|
||||
.regs = (struct tegra_spi_regs *)TEGRA_SPI4_BASE,
|
||||
.req_sel = APBDMA_SLAVE_SL2B4,
|
||||
},
|
||||
{
|
||||
.slave = { .bus = 5, },
|
||||
.regs = (struct tegra_spi_regs *)TEGRA_SPI5_BASE,
|
||||
.req_sel = APBDMA_SLAVE_SL2B5,
|
||||
},
|
||||
{
|
||||
.slave = { .bus = 6, },
|
||||
.regs = (struct tegra_spi_regs *)TEGRA_SPI6_BASE,
|
||||
.req_sel = APBDMA_SLAVE_SL2B6,
|
||||
},
|
||||
{
|
||||
.slave = { .bus = 7, },
|
||||
.regs = (struct tegra_spi_regs *)TEGRA_QSPI_BASE,
|
||||
.req_sel = APBDMA_SLAVE_QSPI,
|
||||
},
|
||||
};
|
||||
|
||||
enum spi_direction {
|
||||
SPI_SEND,
|
||||
SPI_RECEIVE,
|
||||
};
|
||||
|
||||
struct tegra_spi_channel *tegra_spi_init(unsigned int bus)
|
||||
{
|
||||
int i;
|
||||
struct tegra_spi_channel *spi = NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tegra_spi_channels); i++) {
|
||||
if (tegra_spi_channels[i].slave.bus == bus) {
|
||||
spi = &tegra_spi_channels[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!spi)
|
||||
return NULL;
|
||||
|
||||
/* software drives chip-select, set value to high */
|
||||
setbits_le32(&spi->regs->command1,
|
||||
SPI_CMD1_CS_SW_HW | SPI_CMD1_CS_SW_VAL);
|
||||
|
||||
/* 8-bit transfers, unpacked mode, most significant bit first */
|
||||
clrbits_le32(&spi->regs->command1,
|
||||
SPI_CMD1_BIT_LEN_MASK | SPI_CMD1_PACKED);
|
||||
setbits_le32(&spi->regs->command1, 7 << SPI_CMD1_BIT_LEN_SHIFT);
|
||||
|
||||
return spi;
|
||||
}
|
||||
|
||||
static struct tegra_spi_channel * const to_tegra_spi(int bus) {
|
||||
return &tegra_spi_channels[bus - 1];
|
||||
}
|
||||
|
||||
static unsigned int tegra_spi_speed(unsigned int bus)
|
||||
{
|
||||
/* FIXME: implement this properly, for now use max value (50MHz) */
|
||||
return 50000000;
|
||||
}
|
||||
|
||||
int spi_claim_bus(struct spi_slave *slave)
|
||||
{
|
||||
struct tegra_spi_regs *regs = to_tegra_spi(slave->bus)->regs;
|
||||
u32 val;
|
||||
|
||||
tegra_spi_init(slave->bus);
|
||||
|
||||
val = read32(®s->command1);
|
||||
|
||||
/* select appropriate chip-select line */
|
||||
val &= ~(SPI_CMD1_CS_SEL_MASK << SPI_CMD1_CS_SEL_SHIFT);
|
||||
val |= (slave->cs << SPI_CMD1_CS_SEL_SHIFT);
|
||||
|
||||
/* drive chip-select with the inverse of the "inactive" value */
|
||||
if (val & (SPI_CMD1_CS_POL_INACTIVE0 << slave->cs))
|
||||
val &= ~SPI_CMD1_CS_SW_VAL;
|
||||
else
|
||||
val |= SPI_CMD1_CS_SW_VAL;
|
||||
|
||||
write32(®s->command1, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spi_release_bus(struct spi_slave *slave)
|
||||
{
|
||||
struct tegra_spi_regs *regs = to_tegra_spi(slave->bus)->regs;
|
||||
u32 val;
|
||||
|
||||
val = read32(®s->command1);
|
||||
|
||||
if (val & (SPI_CMD1_CS_POL_INACTIVE0 << slave->cs))
|
||||
val |= SPI_CMD1_CS_SW_VAL;
|
||||
else
|
||||
val &= ~SPI_CMD1_CS_SW_VAL;
|
||||
|
||||
write32(®s->command1, val);
|
||||
}
|
||||
|
||||
static void dump_fifo_status(struct tegra_spi_channel *spi)
|
||||
{
|
||||
u32 status = read32(&spi->regs->fifo_status);
|
||||
|
||||
printk(BIOS_INFO, "Raw FIFO status: 0x%08x\n", status);
|
||||
if (status & SPI_FIFO_STATUS_TX_FIFO_OVF)
|
||||
printk(BIOS_INFO, "\tTx overflow detected\n");
|
||||
if (status & SPI_FIFO_STATUS_TX_FIFO_UNR)
|
||||
printk(BIOS_INFO, "\tTx underrun detected\n");
|
||||
if (status & SPI_FIFO_STATUS_RX_FIFO_OVF)
|
||||
printk(BIOS_INFO, "\tRx overflow detected\n");
|
||||
if (status & SPI_FIFO_STATUS_RX_FIFO_UNR)
|
||||
printk(BIOS_INFO, "\tRx underrun detected\n");
|
||||
|
||||
printk(BIOS_INFO, "TX_FIFO: 0x%08x, TX_DATA: 0x%08x\n",
|
||||
read32(&spi->regs->tx_fifo), read32(&spi->regs->tx_data));
|
||||
printk(BIOS_INFO, "RX_FIFO: 0x%08x, RX_DATA: 0x%08x\n",
|
||||
read32(&spi->regs->rx_fifo), read32(&spi->regs->rx_data));
|
||||
}
|
||||
|
||||
static void clear_fifo_status(struct tegra_spi_channel *spi)
|
||||
{
|
||||
clrbits_le32(&spi->regs->fifo_status,
|
||||
SPI_FIFO_STATUS_ERR |
|
||||
SPI_FIFO_STATUS_TX_FIFO_OVF |
|
||||
SPI_FIFO_STATUS_TX_FIFO_UNR |
|
||||
SPI_FIFO_STATUS_RX_FIFO_OVF |
|
||||
SPI_FIFO_STATUS_RX_FIFO_UNR);
|
||||
}
|
||||
|
||||
static void dump_spi_regs(struct tegra_spi_channel *spi)
|
||||
{
|
||||
printk(BIOS_INFO, "SPI regs:\n"
|
||||
"\tdma_blk: 0x%08x\n"
|
||||
"\tcommand1: 0x%08x\n"
|
||||
"\tdma_ctl: 0x%08x\n"
|
||||
"\ttrans_status: 0x%08x\n",
|
||||
read32(&spi->regs->dma_blk),
|
||||
read32(&spi->regs->command1),
|
||||
read32(&spi->regs->dma_ctl),
|
||||
read32(&spi->regs->trans_status));
|
||||
}
|
||||
|
||||
static void dump_dma_regs(struct apb_dma_channel *dma)
|
||||
{
|
||||
printk(BIOS_INFO, "DMA regs:\n"
|
||||
"\tahb_ptr: 0x%08x\n"
|
||||
"\tapb_ptr: 0x%08x\n"
|
||||
"\tahb_seq: 0x%08x\n"
|
||||
"\tapb_seq: 0x%08x\n"
|
||||
"\tcsr: 0x%08x\n"
|
||||
"\tcsre: 0x%08x\n"
|
||||
"\twcount: 0x%08x\n"
|
||||
"\tdma_byte_sta: 0x%08x\n"
|
||||
"\tword_transfer: 0x%08x\n",
|
||||
read32(&dma->regs->ahb_ptr),
|
||||
read32(&dma->regs->apb_ptr),
|
||||
read32(&dma->regs->ahb_seq),
|
||||
read32(&dma->regs->apb_seq),
|
||||
read32(&dma->regs->csr),
|
||||
read32(&dma->regs->csre),
|
||||
read32(&dma->regs->wcount),
|
||||
read32(&dma->regs->dma_byte_sta),
|
||||
read32(&dma->regs->word_transfer));
|
||||
}
|
||||
|
||||
static inline unsigned int spi_byte_count(struct tegra_spi_channel *spi)
|
||||
{
|
||||
/* FIXME: Make this take total packet size into account */
|
||||
return read32(&spi->regs->trans_status) &
|
||||
(SPI_STATUS_BLOCK_COUNT << SPI_STATUS_BLOCK_COUNT_SHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* This calls udelay() with a calculated value based on the SPI speed and
|
||||
* number of bytes remaining to be transferred. It assumes that if the
|
||||
* calculated delay period is less than MIN_DELAY_US then it is probably
|
||||
* not worth the overhead of yielding.
|
||||
*/
|
||||
#define MIN_DELAY_US 250
|
||||
static void spi_delay(struct tegra_spi_channel *spi,
|
||||
unsigned int bytes_remaining)
|
||||
{
|
||||
unsigned int ns_per_byte, delay_us;
|
||||
|
||||
ns_per_byte = 1000000000 / (tegra_spi_speed(spi->slave.bus) / 8);
|
||||
delay_us = (ns_per_byte * bytes_remaining) / 1000;
|
||||
|
||||
if (delay_us < MIN_DELAY_US)
|
||||
return;
|
||||
|
||||
udelay(delay_us);
|
||||
}
|
||||
|
||||
static void tegra_spi_wait(struct tegra_spi_channel *spi)
|
||||
{
|
||||
unsigned int count, dma_blk;
|
||||
|
||||
dma_blk = 1 + (read32(&spi->regs->dma_blk) &
|
||||
(SPI_DMA_CTL_BLOCK_SIZE_MASK << SPI_DMA_CTL_BLOCK_SIZE_SHIFT));
|
||||
|
||||
while ((count = spi_byte_count(spi)) != dma_blk)
|
||||
spi_delay(spi, dma_blk - count);
|
||||
}
|
||||
|
||||
|
||||
static int fifo_error(struct tegra_spi_channel *spi)
|
||||
{
|
||||
return read32(&spi->regs->fifo_status) & SPI_FIFO_STATUS_ERR ? 1 : 0;
|
||||
}
|
||||
|
||||
static int tegra_spi_pio_prepare(struct tegra_spi_channel *spi,
|
||||
unsigned int bytes, enum spi_direction dir)
|
||||
{
|
||||
u8 *p = spi->out_buf;
|
||||
unsigned int todo = MIN(bytes, SPI_MAX_TRANSFER_BYTES_FIFO);
|
||||
u32 flush_mask, enable_mask;
|
||||
|
||||
if (dir == SPI_SEND) {
|
||||
flush_mask = SPI_FIFO_STATUS_TX_FIFO_FLUSH;
|
||||
enable_mask = SPI_CMD1_TX_EN;
|
||||
} else {
|
||||
flush_mask = SPI_FIFO_STATUS_RX_FIFO_FLUSH;
|
||||
enable_mask = SPI_CMD1_RX_EN;
|
||||
}
|
||||
|
||||
setbits_le32(&spi->regs->fifo_status, flush_mask);
|
||||
while (read32(&spi->regs->fifo_status) & flush_mask)
|
||||
;
|
||||
|
||||
/*
|
||||
* BLOCK_SIZE in SPI_DMA_BLK register applies to both DMA and
|
||||
* PIO transfers. And, it should be programmed before RX_EN or
|
||||
* TX_EN is set.
|
||||
*/
|
||||
write32(&spi->regs->dma_blk, todo - 1);
|
||||
|
||||
setbits_le32(&spi->regs->command1, enable_mask);
|
||||
|
||||
if (dir == SPI_SEND) {
|
||||
unsigned int to_fifo = bytes;
|
||||
while (to_fifo) {
|
||||
write32(&spi->regs->tx_fifo, *p);
|
||||
p++;
|
||||
to_fifo--;
|
||||
}
|
||||
}
|
||||
|
||||
return todo;
|
||||
}
|
||||
|
||||
static void tegra_spi_pio_start(struct tegra_spi_channel *spi)
|
||||
{
|
||||
setbits_le32(&spi->regs->trans_status, SPI_STATUS_RDY);
|
||||
/*
|
||||
* Need to stabilize other reg bit before GO bit set.
|
||||
*
|
||||
* From IAS:
|
||||
* For successful operation at various freq combinations, min of 4-5
|
||||
* spi_clk cycle delay might be required before enabling PIO or DMA bit.
|
||||
* This is needed to overcome the MCP between core and pad_macro.
|
||||
* The worst case delay calculation can be done considering slowest
|
||||
* qspi_clk as 1 MHz. based on that 1 us delay should be enough before
|
||||
* enabling pio or dma.
|
||||
*/
|
||||
udelay(2);
|
||||
setbits_le32(&spi->regs->command1, SPI_CMD1_GO);
|
||||
/* Need to wait a few cycles before command1 register is read */
|
||||
udelay(1);
|
||||
/* Make sure the write to command1 completes. */
|
||||
read32(&spi->regs->command1);
|
||||
}
|
||||
|
||||
static inline u32 rx_fifo_count(struct tegra_spi_channel *spi)
|
||||
{
|
||||
return (read32(&spi->regs->fifo_status) >>
|
||||
SPI_FIFO_STATUS_RX_FIFO_FULL_COUNT_SHIFT) &
|
||||
SPI_FIFO_STATUS_RX_FIFO_FULL_COUNT_MASK;
|
||||
}
|
||||
|
||||
static int tegra_spi_pio_finish(struct tegra_spi_channel *spi)
|
||||
{
|
||||
u8 *p = spi->in_buf;
|
||||
struct stopwatch sw;
|
||||
|
||||
clrbits_le32(&spi->regs->command1, SPI_CMD1_RX_EN | SPI_CMD1_TX_EN);
|
||||
|
||||
/*
|
||||
* Allow some time in case the Rx FIFO does not yet have
|
||||
* all packets pushed into it. See chrome-os-partner:24215.
|
||||
*/
|
||||
stopwatch_init_usecs_expire(&sw, SPI_FIFO_XFER_TIMEOUT_US);
|
||||
do {
|
||||
if (rx_fifo_count(spi) == spi_byte_count(spi))
|
||||
break;
|
||||
} while (!stopwatch_expired(&sw));
|
||||
|
||||
while (!(read32(&spi->regs->fifo_status) &
|
||||
SPI_FIFO_STATUS_RX_FIFO_EMPTY)) {
|
||||
*p = read8(&spi->regs->rx_fifo);
|
||||
p++;
|
||||
}
|
||||
|
||||
if (fifo_error(spi)) {
|
||||
printk(BIOS_ERR, "%s: ERROR:\n", __func__);
|
||||
dump_spi_regs(spi);
|
||||
dump_fifo_status(spi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_dma_params(struct tegra_spi_channel *spi,
|
||||
struct apb_dma_channel *dma)
|
||||
{
|
||||
/* APB bus width = 8-bits, address wrap for each word */
|
||||
clrbits_le32(&dma->regs->apb_seq,
|
||||
APB_BUS_WIDTH_MASK << APB_BUS_WIDTH_SHIFT);
|
||||
/* AHB 1 word burst, bus width = 32 bits (fixed in hardware),
|
||||
* no address wrapping */
|
||||
clrsetbits_le32(&dma->regs->ahb_seq,
|
||||
(AHB_BURST_MASK << AHB_BURST_SHIFT),
|
||||
4 << AHB_BURST_SHIFT);
|
||||
|
||||
/* Set ONCE mode to transfer one "block" at a time (64KB) and enable
|
||||
* flow control. */
|
||||
clrbits_le32(&dma->regs->csr,
|
||||
APB_CSR_REQ_SEL_MASK << APB_CSR_REQ_SEL_SHIFT);
|
||||
setbits_le32(&dma->regs->csr, APB_CSR_ONCE | APB_CSR_FLOW |
|
||||
(spi->req_sel << APB_CSR_REQ_SEL_SHIFT));
|
||||
}
|
||||
|
||||
static int tegra_spi_dma_prepare(struct tegra_spi_channel *spi,
|
||||
unsigned int bytes, enum spi_direction dir)
|
||||
{
|
||||
unsigned int todo, wcount;
|
||||
|
||||
/*
|
||||
* For DMA we need to think of things in terms of word count.
|
||||
* AHB width is fixed at 32-bits. To avoid overrunning
|
||||
* the in/out buffers we must align down. (Note: lowest 2-bits
|
||||
* in WCOUNT register are ignored, and WCOUNT seems to count
|
||||
* words starting at n-1)
|
||||
*
|
||||
* Example: If "bytes" is 7 and we are transferring 1-byte at a time,
|
||||
* WCOUNT should be 4. The remaining 3 bytes must be transferred
|
||||
* using PIO.
|
||||
*/
|
||||
todo = MIN(bytes, SPI_MAX_TRANSFER_BYTES_DMA - TEGRA_DMA_ALIGN_BYTES);
|
||||
todo = ALIGN_DOWN(todo, TEGRA_DMA_ALIGN_BYTES);
|
||||
wcount = ALIGN_DOWN(todo - TEGRA_DMA_ALIGN_BYTES, TEGRA_DMA_ALIGN_BYTES);
|
||||
|
||||
if (dir == SPI_SEND) {
|
||||
spi->dma_out = dma_claim();
|
||||
if (!spi->dma_out)
|
||||
return -1;
|
||||
|
||||
/* ensure bytes to send will be visible to DMA controller */
|
||||
dcache_clean_by_mva(spi->out_buf, bytes);
|
||||
|
||||
write32(&spi->dma_out->regs->apb_ptr,
|
||||
(uintptr_t) & spi->regs->tx_fifo);
|
||||
write32(&spi->dma_out->regs->ahb_ptr, (uintptr_t)spi->out_buf);
|
||||
setbits_le32(&spi->dma_out->regs->csr, APB_CSR_DIR);
|
||||
setup_dma_params(spi, spi->dma_out);
|
||||
write32(&spi->dma_out->regs->wcount, wcount);
|
||||
} else {
|
||||
spi->dma_in = dma_claim();
|
||||
if (!spi->dma_in)
|
||||
return -1;
|
||||
|
||||
/* avoid data collisions */
|
||||
dcache_clean_invalidate_by_mva(spi->in_buf, bytes);
|
||||
|
||||
write32(&spi->dma_in->regs->apb_ptr,
|
||||
(uintptr_t)&spi->regs->rx_fifo);
|
||||
write32(&spi->dma_in->regs->ahb_ptr, (uintptr_t)spi->in_buf);
|
||||
clrbits_le32(&spi->dma_in->regs->csr, APB_CSR_DIR);
|
||||
setup_dma_params(spi, spi->dma_in);
|
||||
write32(&spi->dma_in->regs->wcount, wcount);
|
||||
}
|
||||
|
||||
/* BLOCK_SIZE starts at n-1 */
|
||||
write32(&spi->regs->dma_blk, todo - 1);
|
||||
return todo;
|
||||
}
|
||||
|
||||
static void tegra_spi_dma_start(struct tegra_spi_channel *spi)
|
||||
{
|
||||
/*
|
||||
* The RDY bit in SPI_TRANS_STATUS needs to be cleared manually
|
||||
* (set bit to clear) between each transaction. Otherwise the next
|
||||
* transaction does not start.
|
||||
*/
|
||||
setbits_le32(&spi->regs->trans_status, SPI_STATUS_RDY);
|
||||
|
||||
struct apb_dma * const apb_dma = (struct apb_dma *)TEGRA_APB_DMA_BASE;
|
||||
|
||||
/*
|
||||
* The DMA triggers have units of packets. As each packet is currently
|
||||
* 1 byte the triggers need to be set to 4 packets (0b01) to match
|
||||
* the AHB 32-bit (4 byte) tranfser. Otherwise the FIFO errors can
|
||||
* occur.
|
||||
*/
|
||||
if (spi->dma_out) {
|
||||
/* Enable secure access for the channel. */
|
||||
setbits_le32(&apb_dma->security_reg,
|
||||
SECURITY_EN_BIT(spi->dma_out->num));
|
||||
clrsetbits_le32(&spi->regs->dma_ctl,
|
||||
SPI_DMA_CTL_TX_TRIG_MASK << SPI_DMA_CTL_TX_TRIG_SHIFT,
|
||||
1 << SPI_DMA_CTL_TX_TRIG_SHIFT);
|
||||
setbits_le32(&spi->regs->command1, SPI_CMD1_TX_EN);
|
||||
}
|
||||
if (spi->dma_in) {
|
||||
/* Enable secure access for the channel. */
|
||||
setbits_le32(&apb_dma->security_reg,
|
||||
SECURITY_EN_BIT(spi->dma_in->num));
|
||||
clrsetbits_le32(&spi->regs->dma_ctl,
|
||||
SPI_DMA_CTL_RX_TRIG_MASK << SPI_DMA_CTL_RX_TRIG_SHIFT,
|
||||
1 << SPI_DMA_CTL_RX_TRIG_SHIFT);
|
||||
setbits_le32(&spi->regs->command1, SPI_CMD1_RX_EN);
|
||||
}
|
||||
|
||||
/*
|
||||
* To avoid underrun conditions, enable APB DMA before SPI DMA for
|
||||
* Tx and enable SPI DMA before APB DMA before Rx.
|
||||
*/
|
||||
if (spi->dma_out)
|
||||
dma_start(spi->dma_out);
|
||||
setbits_le32(&spi->regs->dma_ctl, SPI_DMA_CTL_DMA);
|
||||
if (spi->dma_in)
|
||||
dma_start(spi->dma_in);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int tegra_spi_dma_finish(struct tegra_spi_channel *spi)
|
||||
{
|
||||
int ret;
|
||||
unsigned int todo;
|
||||
|
||||
struct apb_dma * const apb_dma = (struct apb_dma *)TEGRA_APB_DMA_BASE;
|
||||
|
||||
todo = read32(&spi->dma_in->regs->wcount);
|
||||
|
||||
if (spi->dma_in) {
|
||||
while ((read32(&spi->dma_in->regs->dma_byte_sta) < todo) ||
|
||||
dma_busy(spi->dma_in))
|
||||
; /* this shouldn't take long, no udelay */
|
||||
dma_stop(spi->dma_in);
|
||||
clrbits_le32(&spi->regs->command1, SPI_CMD1_RX_EN);
|
||||
/* Disable secure access for the channel. */
|
||||
clrbits_le32(&apb_dma->security_reg,
|
||||
SECURITY_EN_BIT(spi->dma_in->num));
|
||||
dma_release(spi->dma_in);
|
||||
}
|
||||
|
||||
if (spi->dma_out) {
|
||||
while ((read32(&spi->dma_out->regs->dma_byte_sta) < todo) ||
|
||||
dma_busy(spi->dma_out))
|
||||
spi_delay(spi, todo - spi_byte_count(spi));
|
||||
clrbits_le32(&spi->regs->command1, SPI_CMD1_TX_EN);
|
||||
dma_stop(spi->dma_out);
|
||||
/* Disable secure access for the channel. */
|
||||
clrbits_le32(&apb_dma->security_reg,
|
||||
SECURITY_EN_BIT(spi->dma_out->num));
|
||||
dma_release(spi->dma_out);
|
||||
}
|
||||
|
||||
if (fifo_error(spi)) {
|
||||
printk(BIOS_ERR, "%s: ERROR:\n", __func__);
|
||||
dump_dma_regs(spi->dma_out);
|
||||
dump_dma_regs(spi->dma_in);
|
||||
dump_spi_regs(spi);
|
||||
dump_fifo_status(spi);
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
done:
|
||||
spi->dma_in = NULL;
|
||||
spi->dma_out = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_setup() prepares a transfer. It does sanity checking, alignment, and
|
||||
* sets transfer mode used by this channel (if not set already).
|
||||
*
|
||||
* A few caveats to watch out for:
|
||||
* - The number of bytes which can be transferred may be smaller than the
|
||||
* number of bytes the caller specifies. The number of bytes ready for
|
||||
* a transfer will be returned (unless an error occurs).
|
||||
*
|
||||
* - Only one mode can be used for both RX and TX. The transfer mode of the
|
||||
* SPI channel (spi->xfer_mode) is checked each time this function is called.
|
||||
* If conflicting modes are detected, spi->xfer_mode will be set to
|
||||
* XFER_MODE_NONE and an error will be returned.
|
||||
*
|
||||
* Returns bytes ready for transfer if successful, <0 to indicate error.
|
||||
*/
|
||||
static int xfer_setup(struct tegra_spi_channel *spi, void *buf,
|
||||
unsigned int bytes, enum spi_direction dir)
|
||||
{
|
||||
unsigned int line_size = dcache_line_bytes();
|
||||
unsigned int align;
|
||||
int ret = -1;
|
||||
|
||||
if (!bytes)
|
||||
return 0;
|
||||
|
||||
if (dir == SPI_SEND)
|
||||
spi->out_buf = buf;
|
||||
else if (dir == SPI_RECEIVE)
|
||||
spi->in_buf = buf;
|
||||
|
||||
/*
|
||||
* Alignment consideratons:
|
||||
* When we enable caching we'll need to clean/invalidate portions of
|
||||
* memory. So we need to be careful about memory alignment. Also, DMA
|
||||
* likes to operate on 4-bytes at a time on the AHB side. So for
|
||||
* example, if we only want to receive 1 byte, 4 bytes will be be
|
||||
* written in memory even if those extra 3 bytes are beyond the length
|
||||
* we want.
|
||||
*
|
||||
* For now we'll use PIO to send/receive unaligned bytes. We may
|
||||
* consider setting aside some space for a kind of bounce buffer to
|
||||
* stay in DMA mode once we have a chance to benchmark the two
|
||||
* approaches.
|
||||
*/
|
||||
|
||||
if (bytes < line_size) {
|
||||
if (spi->xfer_mode == XFER_MODE_DMA) {
|
||||
spi->xfer_mode = XFER_MODE_NONE;
|
||||
ret = -1;
|
||||
} else {
|
||||
spi->xfer_mode = XFER_MODE_PIO;
|
||||
ret = tegra_spi_pio_prepare(spi, bytes, dir);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* transfer bytes before the aligned boundary */
|
||||
align = line_size - ((uintptr_t)buf % line_size);
|
||||
if ((align != 0) && (align != line_size)) {
|
||||
if (spi->xfer_mode == XFER_MODE_DMA) {
|
||||
spi->xfer_mode = XFER_MODE_NONE;
|
||||
ret = -1;
|
||||
} else {
|
||||
spi->xfer_mode = XFER_MODE_PIO;
|
||||
ret = tegra_spi_pio_prepare(spi, align, dir);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* do aligned DMA transfer */
|
||||
align = (((uintptr_t)buf + bytes) % line_size);
|
||||
if (bytes - align > 0) {
|
||||
unsigned int dma_bytes = bytes - align;
|
||||
|
||||
if (spi->xfer_mode == XFER_MODE_PIO) {
|
||||
spi->xfer_mode = XFER_MODE_NONE;
|
||||
ret = -1;
|
||||
} else {
|
||||
spi->xfer_mode = XFER_MODE_DMA;
|
||||
ret = tegra_spi_dma_prepare(spi, dma_bytes, dir);
|
||||
}
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* transfer any remaining unaligned bytes */
|
||||
if (align) {
|
||||
if (spi->xfer_mode == XFER_MODE_DMA) {
|
||||
spi->xfer_mode = XFER_MODE_NONE;
|
||||
ret = -1;
|
||||
} else {
|
||||
spi->xfer_mode = XFER_MODE_PIO;
|
||||
ret = tegra_spi_pio_prepare(spi, align, dir);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void xfer_start(struct tegra_spi_channel *spi)
|
||||
{
|
||||
if (spi->xfer_mode == XFER_MODE_DMA)
|
||||
tegra_spi_dma_start(spi);
|
||||
else
|
||||
tegra_spi_pio_start(spi);
|
||||
}
|
||||
|
||||
static void xfer_wait(struct tegra_spi_channel *spi)
|
||||
{
|
||||
tegra_spi_wait(spi);
|
||||
}
|
||||
|
||||
static int xfer_finish(struct tegra_spi_channel *spi)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (spi->xfer_mode == XFER_MODE_DMA)
|
||||
ret = tegra_spi_dma_finish(spi);
|
||||
else
|
||||
ret = tegra_spi_pio_finish(spi);
|
||||
|
||||
spi->xfer_mode = XFER_MODE_NONE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
|
||||
{
|
||||
return buf_len;
|
||||
}
|
||||
|
||||
int spi_xfer(struct spi_slave *slave, const void *dout,
|
||||
unsigned int out_bytes, void *din, unsigned int in_bytes)
|
||||
{
|
||||
struct tegra_spi_channel *spi = to_tegra_spi(slave->bus);
|
||||
u8 *out_buf = (u8 *)dout;
|
||||
u8 *in_buf = (u8 *)din;
|
||||
unsigned int todo;
|
||||
int ret = 0;
|
||||
|
||||
/* tegra bus numbers start at 1 */
|
||||
ASSERT(slave->bus >= 1 && slave->bus <= ARRAY_SIZE(tegra_spi_channels));
|
||||
|
||||
while (out_bytes || in_bytes) {
|
||||
int x = 0;
|
||||
|
||||
if (out_bytes == 0)
|
||||
todo = in_bytes;
|
||||
else if (in_bytes == 0)
|
||||
todo = out_bytes;
|
||||
else
|
||||
todo = MIN(out_bytes, in_bytes);
|
||||
|
||||
if (out_bytes) {
|
||||
x = xfer_setup(spi, out_buf, todo, SPI_SEND);
|
||||
if (x < 0) {
|
||||
if (spi->xfer_mode == XFER_MODE_NONE) {
|
||||
spi->xfer_mode = XFER_MODE_PIO;
|
||||
continue;
|
||||
} else {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (in_bytes) {
|
||||
x = xfer_setup(spi, in_buf, todo, SPI_RECEIVE);
|
||||
if (x < 0) {
|
||||
if (spi->xfer_mode == XFER_MODE_NONE) {
|
||||
spi->xfer_mode = XFER_MODE_PIO;
|
||||
continue;
|
||||
} else {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: Some devices (such as Chrome EC) are sensitive to
|
||||
* delays, so be careful when adding debug prints not to
|
||||
* cause timeouts between transfers.
|
||||
*/
|
||||
xfer_start(spi);
|
||||
xfer_wait(spi);
|
||||
if (xfer_finish(spi)) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Post-processing. */
|
||||
if (out_bytes) {
|
||||
out_bytes -= x;
|
||||
out_buf += x;
|
||||
}
|
||||
if (in_bytes) {
|
||||
in_bytes -= x;
|
||||
in_buf += x;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
printk(BIOS_ERR, "%s: Error detected\n", __func__);
|
||||
printk(BIOS_ERR, "Transaction size: %u, bytes remaining: "
|
||||
"%u out / %u in\n", todo, out_bytes, in_bytes);
|
||||
clear_fifo_status(spi);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define JEDEC_READ 0x03
|
||||
#define JEDEC_READ_OUTSIZE 0x04
|
||||
#define JEDEC_FAST_READ_DUAL 0x3b
|
||||
#define JEDEC_FAST_READ_DUAL_OUTSIZE 0x05
|
||||
|
||||
static struct spi_slave *boot_slave;
|
||||
|
||||
static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest,
|
||||
size_t offset, size_t count)
|
||||
{
|
||||
u8 spi_read_cmd[JEDEC_FAST_READ_DUAL_OUTSIZE];
|
||||
unsigned int read_cmd_bytes;
|
||||
int ret = count;
|
||||
struct tegra_spi_channel *channel;
|
||||
|
||||
channel = to_tegra_spi(boot_slave->bus);
|
||||
|
||||
if (channel->dual_mode) {
|
||||
/*
|
||||
* Command 0x3b will interleave data only, command 0xbb will
|
||||
* interleave the address as well. It's nice to see the address
|
||||
* plainly when debugging, and we're mostly concerned with
|
||||
* large transfers so the optimization of using 0xbb isn't
|
||||
* really worthwhile.
|
||||
*/
|
||||
spi_read_cmd[0] = JEDEC_FAST_READ_DUAL;
|
||||
spi_read_cmd[4] = 0x00; /* dummy byte */
|
||||
read_cmd_bytes = JEDEC_FAST_READ_DUAL_OUTSIZE;
|
||||
} else {
|
||||
spi_read_cmd[0] = JEDEC_READ;
|
||||
read_cmd_bytes = JEDEC_READ_OUTSIZE;
|
||||
}
|
||||
spi_read_cmd[1] = (offset >> 16) & 0xff;
|
||||
spi_read_cmd[2] = (offset >> 8) & 0xff;
|
||||
spi_read_cmd[3] = offset & 0xff;
|
||||
|
||||
spi_claim_bus(boot_slave);
|
||||
|
||||
if (spi_xfer(boot_slave, spi_read_cmd,
|
||||
read_cmd_bytes, NULL, 0) < 0) {
|
||||
ret = -1;
|
||||
printk(BIOS_ERR, "%s: Failed to transfer %zu bytes\n",
|
||||
__func__, sizeof(spi_read_cmd));
|
||||
goto tegra_spi_cbfs_read_exit;
|
||||
}
|
||||
|
||||
if (channel->dual_mode) {
|
||||
setbits_le32(&channel->regs->command1, SPI_CMD1_BOTH_EN_BIT);
|
||||
}
|
||||
if (spi_xfer(boot_slave, NULL, 0, dest, count)) {
|
||||
ret = -1;
|
||||
printk(BIOS_ERR, "%s: Failed to transfer %zu bytes\n",
|
||||
__func__, count);
|
||||
}
|
||||
if (channel->dual_mode)
|
||||
clrbits_le32(&channel->regs->command1, SPI_CMD1_BOTH_EN_BIT);
|
||||
|
||||
tegra_spi_cbfs_read_exit:
|
||||
/* de-assert /CS */
|
||||
spi_release_bus(boot_slave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
|
||||
{
|
||||
struct tegra_spi_channel *channel = to_tegra_spi(bus);
|
||||
if (!channel)
|
||||
return NULL;
|
||||
|
||||
return &channel->slave;
|
||||
}
|
||||
|
||||
static const struct region_device_ops tegra_spi_ops = {
|
||||
.mmap = mmap_helper_rdev_mmap,
|
||||
.munmap = mmap_helper_rdev_munmap,
|
||||
.readat = tegra_spi_readat,
|
||||
};
|
||||
|
||||
__attribute__((unused))
|
||||
static struct mmap_helper_region_device mdev =
|
||||
MMAP_HELPER_REGION_INIT(&tegra_spi_ops, 0, CONFIG_ROM_SIZE);
|
||||
|
||||
#if !IS_ENABLED(CONFIG_COMMON_CBFS_SPI_WRAPPER)
|
||||
const struct region_device *boot_device_ro(void)
|
||||
{
|
||||
return &mdev.rdev;
|
||||
}
|
||||
|
||||
void boot_device_init(void)
|
||||
{
|
||||
struct tegra_spi_channel *boot_chan;
|
||||
|
||||
boot_chan = &tegra_spi_channels[CONFIG_BOOT_MEDIA_SPI_BUS - 1];
|
||||
boot_chan->slave.cs = CONFIG_BOOT_MEDIA_SPI_CHIP_SELECT;
|
||||
|
||||
#if CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B == 1
|
||||
boot_chan->dual_mode = 1;
|
||||
#endif
|
||||
boot_slave = &boot_chan->slave;
|
||||
|
||||
mmap_helper_device_init(&mdev, _cbfs_cache, _cbfs_cache_size);
|
||||
}
|
||||
#endif
|
45
src/soc/nvidia/tegra210/stack.S
Normal file
45
src/soc/nvidia/tegra210/stack.S
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Macro to initialize stack, perform seeding if required and finally call the
|
||||
* function provided
|
||||
* @stack_top : First address above the stack
|
||||
* @stack_bottom : Lowest address on the stack
|
||||
* @seed : Stack seeding required (1=yes/otherwise=no)
|
||||
* @func : Function to call after initializing stack
|
||||
*/
|
||||
.macro stack_init stack_top, stack_bottom, seed, func
|
||||
/* Check if stack seeding is required */
|
||||
mov r0, #\seed
|
||||
cmp r0, #1
|
||||
bne call_func
|
||||
/* Stack seeding */
|
||||
ldr r0, =\stack_bottom
|
||||
ldr r1, =\stack_top
|
||||
ldr r2, =0xdeadbeef
|
||||
init_stack_loop:
|
||||
str r2, [r0]
|
||||
add r0, #4
|
||||
cmp r0, r1
|
||||
bne init_stack_loop
|
||||
|
||||
call_func:
|
||||
ldr sp, =\stack_top /* Set up stack pointer */
|
||||
bl \func
|
||||
.endm
|
135
src/soc/nvidia/tegra210/uart.c
Normal file
135
src/soc/nvidia/tegra210/uart.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <boot/coreboot_tables.h>
|
||||
#include <console/console.h> /* for __console definition */
|
||||
#include <console/uart.h>
|
||||
#include <drivers/uart/uart8250reg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct tegra210_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 tegra210_uart * const uart_ptr =
|
||||
(void *)CONFIG_CONSOLE_SERIAL_TEGRA210_UART_ADDRESS;
|
||||
|
||||
static void tegra210_uart_tx_flush(void);
|
||||
static int tegra210_uart_tst_byte(void);
|
||||
|
||||
static void tegra210_uart_init(void)
|
||||
{
|
||||
// Use a hardcoded divisor for now.
|
||||
const unsigned divisor = 221;
|
||||
const uint8_t line_config = UART8250_LCR_WLS_8; // 8n1
|
||||
|
||||
tegra210_uart_tx_flush();
|
||||
|
||||
// Disable interrupts.
|
||||
write8(&uart_ptr->ier, 0);
|
||||
// Force DTR and RTS to high.
|
||||
write8(&uart_ptr->mcr, UART8250_MCR_DTR | UART8250_MCR_RTS);
|
||||
// Set line configuration, access divisor latches.
|
||||
write8(&uart_ptr->lcr, UART8250_LCR_DLAB | line_config);
|
||||
// Set the divisor.
|
||||
write8(&uart_ptr->dll, divisor & 0xff);
|
||||
write8(&uart_ptr->dlm, (divisor >> 8) & 0xff);
|
||||
// Hide the divisor latches.
|
||||
write8(&uart_ptr->lcr, line_config);
|
||||
// Enable FIFOs, and clear receive and transmit.
|
||||
write8(&uart_ptr->fcr,
|
||||
UART8250_FCR_FIFO_EN |
|
||||
UART8250_FCR_CLEAR_RCVR |
|
||||
UART8250_FCR_CLEAR_XMIT);
|
||||
}
|
||||
|
||||
static void tegra210_uart_tx_byte(unsigned char data)
|
||||
{
|
||||
while (!(read8(&uart_ptr->lsr) & UART8250_LSR_THRE));
|
||||
write8(&uart_ptr->thr, data);
|
||||
}
|
||||
|
||||
static void tegra210_uart_tx_flush(void)
|
||||
{
|
||||
while (!(read8(&uart_ptr->lsr) & UART8250_LSR_TEMT));
|
||||
}
|
||||
|
||||
static unsigned char tegra210_uart_rx_byte(void)
|
||||
{
|
||||
if (!tegra210_uart_tst_byte())
|
||||
return 0;
|
||||
return read8(&uart_ptr->rbr);
|
||||
}
|
||||
|
||||
static int tegra210_uart_tst_byte(void)
|
||||
{
|
||||
return (read8(&uart_ptr->lsr) & UART8250_LSR_DR) == UART8250_LSR_DR;
|
||||
}
|
||||
|
||||
void uart_init(int idx)
|
||||
{
|
||||
tegra210_uart_init();
|
||||
}
|
||||
|
||||
void uart_tx_byte(int idx, unsigned char data)
|
||||
{
|
||||
tegra210_uart_tx_byte(data);
|
||||
}
|
||||
|
||||
void uart_tx_flush(int idx)
|
||||
{
|
||||
tegra210_uart_tx_flush();
|
||||
}
|
||||
|
||||
unsigned char uart_rx_byte(int idx)
|
||||
{
|
||||
return tegra210_uart_rx_byte();
|
||||
}
|
||||
|
||||
#ifndef __PRE_RAM__
|
||||
void uart_fill_lb(void *data)
|
||||
{
|
||||
struct lb_serial serial;
|
||||
serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED;
|
||||
serial.baseaddr = CONFIG_CONSOLE_SERIAL_TEGRA210_UART_ADDRESS;
|
||||
serial.baud = default_baudrate();
|
||||
serial.regwidth = 1;
|
||||
lb_add_serial(&serial, data);
|
||||
|
||||
lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data);
|
||||
}
|
||||
#endif
|
47
src/soc/nvidia/tegra210/verstage.c
Normal file
47
src/soc/nvidia/tegra210/verstage.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/cache.h>
|
||||
#include <arch/exception.h>
|
||||
#include <arch/hlt.h>
|
||||
#include <arch/stages.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/verstage.h>
|
||||
#include <timestamp.h>
|
||||
#include <vendorcode/google/chromeos/chromeos.h>
|
||||
|
||||
void __attribute__((weak)) verstage_mainboard_init(void)
|
||||
{
|
||||
/* Default empty implementation. */
|
||||
}
|
||||
|
||||
static void verstage(void)
|
||||
{
|
||||
console_init();
|
||||
exception_init();
|
||||
verstage_mainboard_init();
|
||||
|
||||
run_romstage();
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
verstage();
|
||||
hlt();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user