[U-Boot] [PATCH 0/7] Add T30 Cardhu support

This patch series adds basic (boot to cmd prompt) support for Tegra30. This is based on the Tegra20 SPL, which inits the AVP (ARM7TDMI boot proc) first, then control is transferred to the CPU (A9 quad core). It is based on current u-boot-tegra/next.
Future patches will add support/drivers for MMC/USB/I2C/SPI/etc. The Cardhu T30 board is supported initially.
./MAKEALL -a arm OK; checkpatch.pl is clean except for 1 bogus error where it misread a string as a macro needing parens.
git format-patch -7 -M -C -C was used, to help show renames/copies.
Tom Warren (7): Tegra30: Add AVP (arm720t) files Tegra30: Add CPU (armv7) files Tegra30: Add common CPU (shared) files Tegra30: Add arch-tegra30 include files Tegra30: Cardhu: Add DT files Tegra30: Add generic Tegra30 build support Tegra30: Add/enable Cardhu build (T30 reference board)
Makefile | 6 +- arch/arm/cpu/arm720t/tegra-common/cpu.h | 48 +- arch/arm/cpu/arm720t/tegra-common/spl.c | 3 +- arch/arm/cpu/arm720t/tegra30/Makefile | 41 + arch/arm/cpu/arm720t/tegra30/config.mk | 19 + arch/arm/cpu/arm720t/tegra30/cpu.c | 516 +++++++++ arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/start.S | 4 +- arch/arm/cpu/armv7/tegra30/Makefile | 40 + arch/arm/cpu/armv7/tegra30/config.mk | 19 + arch/arm/cpu/tegra-common/ap.c | 22 +- arch/arm/cpu/tegra-common/board.c | 25 +- arch/arm/cpu/tegra-common/sys_info.c | 5 +- arch/arm/cpu/tegra20-common/warmboot.c | 2 +- arch/arm/cpu/tegra30-common/Makefile | 44 + arch/arm/cpu/tegra30-common/clock.c | 1092 ++++++++++++++++++++ arch/arm/cpu/tegra30-common/funcmux.c | 57 + arch/arm/cpu/tegra30-common/pinmux.c | 501 +++++++++ arch/arm/dts/tegra30.dtsi | 30 + arch/arm/include/asm/arch-tegra/ap.h | 50 +- arch/arm/include/asm/arch-tegra/clk_rst.h | 148 +++- arch/arm/include/asm/arch-tegra/clock.h | 8 +- arch/arm/include/asm/arch-tegra/gp_padctrl.h | 37 + arch/arm/include/asm/arch-tegra/tegra.h | 11 +- arch/arm/include/asm/arch-tegra20/gp_padctrl.h | 17 +- arch/arm/include/asm/arch-tegra30/clock-tables.h | 378 +++++++ arch/arm/include/asm/arch-tegra30/clock.h | 24 + arch/arm/include/asm/arch-tegra30/emc.h | 106 ++ arch/arm/include/asm/arch-tegra30/flow.h | 35 + arch/arm/include/asm/arch-tegra30/funcmux.h | 47 + arch/arm/include/asm/arch-tegra30/gp_padctrl.h | 59 ++ arch/arm/include/asm/arch-tegra30/gpio.h | 304 ++++++ arch/arm/include/asm/arch-tegra30/hardware.h | 22 + .../asm/arch-tegra30/pinmux-config-common.h | 339 ++++++ arch/arm/include/asm/arch-tegra30/pinmux.h | 603 +++++++++++ arch/arm/include/asm/arch-tegra30/pmu.h | 23 + arch/arm/include/asm/arch-tegra30/tegra.h | 26 + board/nvidia/cardhu/Makefile | 48 + board/nvidia/cardhu/cardhu.c | 25 + board/nvidia/common/board.c | 26 +- board/nvidia/dts/tegra30-cardhu.dts | 35 + boards.cfg | 1 + include/configs/cardhu.h | 52 + include/configs/tegra30-common.h | 180 ++++ include/serial.h | 2 +- spl/Makefile | 2 +- 46 files changed, 4950 insertions(+), 134 deletions(-) create mode 100644 arch/arm/cpu/arm720t/tegra30/Makefile create mode 100644 arch/arm/cpu/arm720t/tegra30/config.mk create mode 100644 arch/arm/cpu/arm720t/tegra30/cpu.c create mode 100644 arch/arm/cpu/armv7/tegra30/Makefile create mode 100644 arch/arm/cpu/armv7/tegra30/config.mk create mode 100644 arch/arm/cpu/tegra30-common/Makefile create mode 100644 arch/arm/cpu/tegra30-common/clock.c create mode 100644 arch/arm/cpu/tegra30-common/funcmux.c create mode 100644 arch/arm/cpu/tegra30-common/pinmux.c create mode 100644 arch/arm/dts/tegra30.dtsi create mode 100644 arch/arm/include/asm/arch-tegra/gp_padctrl.h create mode 100644 arch/arm/include/asm/arch-tegra30/clock-tables.h create mode 100644 arch/arm/include/asm/arch-tegra30/clock.h create mode 100644 arch/arm/include/asm/arch-tegra30/emc.h create mode 100644 arch/arm/include/asm/arch-tegra30/flow.h create mode 100644 arch/arm/include/asm/arch-tegra30/funcmux.h create mode 100644 arch/arm/include/asm/arch-tegra30/gp_padctrl.h create mode 100644 arch/arm/include/asm/arch-tegra30/gpio.h create mode 100644 arch/arm/include/asm/arch-tegra30/hardware.h create mode 100644 arch/arm/include/asm/arch-tegra30/pinmux-config-common.h create mode 100644 arch/arm/include/asm/arch-tegra30/pinmux.h create mode 100644 arch/arm/include/asm/arch-tegra30/pmu.h create mode 100644 arch/arm/include/asm/arch-tegra30/tegra.h create mode 100644 board/nvidia/cardhu/Makefile create mode 100644 board/nvidia/cardhu/cardhu.c create mode 100644 board/nvidia/dts/tegra30-cardhu.dts create mode 100644 include/configs/cardhu.h create mode 100644 include/configs/tegra30-common.h

This provides SPL support for T30 boards - AVP early init, plus CPU (A9) init/jump to main U-Boot.
Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/cpu/arm720t/tegra-common/cpu.h | 48 +-- arch/arm/cpu/arm720t/tegra-common/spl.c | 3 +- .../arm/cpu/arm720t/tegra30}/Makefile | 20 +- arch/arm/cpu/arm720t/tegra30/config.mk | 19 + arch/arm/cpu/arm720t/tegra30/cpu.c | 516 ++++++++++++++++++++ 5 files changed, 554 insertions(+), 52 deletions(-) copy {board/compal/paz00 => arch/arm/cpu/arm720t/tegra30}/Makefile (68%) create mode 100644 arch/arm/cpu/arm720t/tegra30/config.mk create mode 100644 arch/arm/cpu/arm720t/tegra30/cpu.c
diff --git a/arch/arm/cpu/arm720t/tegra-common/cpu.h b/arch/arm/cpu/arm720t/tegra-common/cpu.h index 6804cd7..0d9a3c2 100644 --- a/arch/arm/cpu/arm720t/tegra-common/cpu.h +++ b/arch/arm/cpu/arm720t/tegra-common/cpu.h @@ -44,50 +44,11 @@
#define CORESIGHT_UNLOCK 0xC5ACCE55;
-/* AP20-Specific Base Addresses */ - -/* AP20 Base physical address of SDRAM. */ -#define AP20_BASE_PA_SDRAM 0x00000000 -/* AP20 Base physical address of internal SRAM. */ -#define AP20_BASE_PA_SRAM 0x40000000 -/* AP20 Size of internal SRAM (256KB). */ -#define AP20_BASE_PA_SRAM_SIZE 0x00040000 -/* AP20 Base physical address of flash. */ -#define AP20_BASE_PA_NOR_FLASH 0xD0000000 -/* AP20 Base physical address of boot information table. */ -#define AP20_BASE_PA_BOOT_INFO AP20_BASE_PA_SRAM - -/* - * Super-temporary stacks for EXTREMELY early startup. The values chosen for - * these addresses must be valid on ALL SOCs because this value is used before - * we are able to differentiate between the SOC types. - * - * NOTE: The since CPU's stack will eventually be moved from IRAM to SDRAM, its - * stack is placed below the AVP stack. Once the CPU stack has been moved, - * the AVP is free to use the IRAM the CPU stack previously occupied if - * it should need to do so. - * - * NOTE: In multi-processor CPU complex configurations, each processor will have - * its own stack of size CPU_EARLY_BOOT_STACK_SIZE. CPU 0 will have a - * limit of CPU_EARLY_BOOT_STACK_LIMIT. Each successive CPU will have a - * stack limit that is CPU_EARLY_BOOT_STACK_SIZE less then the previous - * CPU. - */ - -/* Common AVP early boot stack limit */ -#define AVP_EARLY_BOOT_STACK_LIMIT \ - (AP20_BASE_PA_SRAM + (AP20_BASE_PA_SRAM_SIZE/2)) -/* Common AVP early boot stack size */ -#define AVP_EARLY_BOOT_STACK_SIZE 0x1000 -/* Common CPU early boot stack limit */ -#define CPU_EARLY_BOOT_STACK_LIMIT \ - (AVP_EARLY_BOOT_STACK_LIMIT - AVP_EARLY_BOOT_STACK_SIZE) -/* Common CPU early boot stack size */ -#define CPU_EARLY_BOOT_STACK_SIZE 0x1000 - #define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100) #define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0) #define CSITE_CPU_DBG1_LAR (NV_PA_CSITE_BASE + 0x12FB0) +#define CSITE_CPU_DBG2_LAR (NV_PA_CSITE_BASE + 0x14FB0) +#define CSITE_CPU_DBG3_LAR (NV_PA_CSITE_BASE + 0x16FB0)
#define FLOW_CTLR_HALT_COP_EVENTS (NV_PA_FLOW_BASE + 4) #define FLOW_MODE_STOP 2 @@ -95,6 +56,11 @@ #define HALT_COP_EVENT_IRQ_1 (1 << 11) #define HALT_COP_EVENT_FIQ_1 (1 << 9)
+#define FLOW_MODE_NONE 0 + +#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE) +#define GP_HIDREV 0x804 + void start_cpu(u32 reset_vector); int ap20_cpu_is_cortexa9(void); void halt_avp(void) __attribute__ ((noreturn)); diff --git a/arch/arm/cpu/arm720t/tegra-common/spl.c b/arch/arm/cpu/arm720t/tegra-common/spl.c index 0d37ce8..2e8d9ca 100644 --- a/arch/arm/cpu/arm720t/tegra-common/spl.c +++ b/arch/arm/cpu/arm720t/tegra-common/spl.c @@ -33,8 +33,6 @@ #include <image.h> #include <malloc.h> #include <linux/compiler.h> -#include "cpu.h" - #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/pinmux.h> @@ -44,6 +42,7 @@ #include <asm/arch-tegra/pmc.h> #include <asm/arch-tegra/scu.h> #include <asm/arch-tegra/sys_proto.h> +#include "cpu.h"
DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/compal/paz00/Makefile b/arch/arm/cpu/arm720t/tegra30/Makefile similarity index 68% copy from board/compal/paz00/Makefile copy to arch/arm/cpu/arm720t/tegra30/Makefile index 7f7287e..bd96997 100644 --- a/board/compal/paz00/Makefile +++ b/arch/arm/cpu/arm720t/tegra30/Makefile @@ -1,8 +1,8 @@ # # Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. # -# See file CREDITS for list of people who contributed to this -# project. +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, @@ -13,20 +13,22 @@ # 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 $(TOPDIR)/config.mk
-$(shell mkdir -p $(obj)../../nvidia/common) +LIB = $(obj)lib$(SOC).o
-LIB = $(obj)lib$(BOARD).o +COBJS-y += cpu.o
-COBJS := $(BOARD).o -COBJS += ../../nvidia/common/board.o +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y))
-SRCS := $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) +all: $(obj).depend $(LIB)
-$(LIB): $(obj).depend $(OBJS) +$(LIB): $(OBJS) $(call cmd_link_o_target, $(OBJS))
######################################################################### diff --git a/arch/arm/cpu/arm720t/tegra30/config.mk b/arch/arm/cpu/arm720t/tegra30/config.mk new file mode 100644 index 0000000..2388c56 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/config.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, garyj@denx.de +# +# 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/. +# +USE_PRIVATE_LIBGCC = yes diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c new file mode 100644 index 0000000..e0821ef --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/cpu.c @@ -0,0 +1,516 @@ +/* + * Copyright (c) 2010-2012, 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 <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/flow.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/tegra.h> +#include <asm/arch-tegra/clk_rst.h> +#include <asm/arch-tegra/fuse.h> +#include <asm/arch-tegra/pmc.h> +#include <asm/arch-tegra/scu.h> +#include <asm/arch-tegra/tegra_i2c.h> +#include "../tegra-common/cpu.h" + +struct clk_pll_table { + u16 n; + u16 m; + u8 p; + u8 cpcon; +}; + +/* ~0=uninitialized/unknown, 0=false, 1=true */ +uint32_t is_tegra_processor_reset = 0xffffffff; + +/* + * Timing tables for each SOC for all four oscillator options. + */ +static struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_COUNT] + [CLOCK_OSC_FREQ_COUNT] = { + /* T20: 1 GHz */ + {{ 1000, 13, 0, 12}, /* OSC 13M */ + { 625, 12, 0, 8}, /* OSC 19.2M */ + { 1000, 12, 0, 12}, /* OSC 12M */ + { 1000, 26, 0, 12}, /* OSC 26M */ + }, + + /* T25: 1.2 GHz */ + {{ 923, 10, 0, 12}, + { 750, 12, 0, 8}, + { 600, 6, 0, 12}, + { 600, 13, 0, 12}, + }, + + /* T30(slow): 1.0 GHz */ + {{ 1000, 13, 0, 8}, + { 625, 12, 0, 4}, + { 1000, 12, 0, 8}, + { 1000, 26, 0, 8}, + }, + + /* T30(high): 1.4 GHz */ + {{ 862, 8, 0, 8}, + { 583, 8, 0, 4}, + { 700, 6, 0, 8}, + { 700, 13, 0, 8}, + }, + + /* TEGRA_SOC2_SLOW: 312 MHz */ + {{ 312, 13, 0, 12}, /* OSC 13M */ + { 260, 16, 0, 8}, /* OSC 19.2M */ + { 312, 12, 0, 12}, /* OSC 12M */ + { 312, 26, 0, 12}, /* OSC 26M */ + }, +}; + +enum tegra_family_t { + TEGRA_FAMILY_T2x, + TEGRA_FAMILY_T3x, +}; + +static int get_chip_type(void) +{ + /* + * T30 has two options. We will return TEGRA_SOC_T30 until + * we have the fdt set up when it may change to + * TEGRA_SOC_T30_408MHZ depending on what we set PLLP to. + */ + if (clock_get_rate(CLOCK_ID_PERIPH) == 408000000) + return TEGRA_SOC_T30_408MHZ; + else + return TEGRA_SOC_T30; +} + +static enum tegra_family_t get_family(void) +{ + u32 reg, chip_id; + + debug("tegra_get_family entry\n"); + reg = readl(NV_PA_APB_MISC_BASE + GP_HIDREV); + + chip_id = reg >> 8; + chip_id &= 0xff; + debug(" tegra_get_family: chip_id = %x\n", chip_id); + if (chip_id == 0x30) + return TEGRA_FAMILY_T3x; + else + return TEGRA_FAMILY_T2x; +} + +int get_num_cpus(void) +{ + return get_family() == TEGRA_FAMILY_T3x ? 4 : 2; +} + +static void adjust_pllp_out_freqs(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH]; + u32 reg; + + /* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */ + reg = readl(&pll->pll_out[0]); /* OUTA, contains OUT2 / OUT1 */ + reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR + | (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR; + writel(reg, &pll->pll_out[0]); + + reg = readl(&pll->pll_out[1]); /* OUTB, contains OUT4 / OUT3 */ + reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR + | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR; + writel(reg, &pll->pll_out[1]); +} + +static int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm, + u32 divp, u32 cpcon) +{ + u32 reg; + + /* If PLLX is already enabled, just return */ + if (readl(&pll->pll_base) & PLL_ENABLE_MASK) { + debug("pllx_set_rate: PLLX already enabled, returning\n"); + return 0; + } + + debug(" pllx_set_rate entry\n"); + + /* Set BYPASS, m, n and p to PLLX_BASE */ + reg = PLL_BYPASS_MASK | (divm << PLL_DIVM_SHIFT); + reg |= ((divn << PLL_DIVN_SHIFT) | (divp << PLL_DIVP_SHIFT)); + writel(reg, &pll->pll_base); + + /* Set cpcon to PLLX_MISC */ + reg = (cpcon << PLL_CPCON_SHIFT); + + /* Set dccon to PLLX_MISC if freq > 600MHz */ + if (divn > 600) + reg |= (1 << PLL_DCCON_SHIFT); + writel(reg, &pll->pll_misc); + + /* Enable PLLX */ + reg = readl(&pll->pll_base); + reg |= PLL_ENABLE_MASK; + + /* Disable BYPASS */ + reg &= ~PLL_BYPASS_MASK; + writel(reg, &pll->pll_base); + + /* Set lock_enable to PLLX_MISC */ + reg = readl(&pll->pll_misc); + reg |= PLL_LOCK_ENABLE_MASK; + writel(reg, &pll->pll_misc); + + return 0; +} + +void init_pllx(int slow) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct clk_pll_simple *pll = &clkrst->crc_pll_simple[SIMPLE_PLLX]; + int chip_type; + enum clock_osc_freq osc; + struct clk_pll_table *sel; + + debug("init_pllx entry\n"); + + /* get chip type. If unknown, assign to T30 */ + chip_type = get_chip_type(); + debug(" init_pllx: chip_type = %d\n", chip_type); + + /* get osc freq */ + osc = clock_get_osc_freq(); + debug(" init_pllx: osc = %d\n", osc); + + /* set pllx */ + sel = &tegra_pll_x_table[chip_type][osc]; + pllx_set_rate(pll, sel->n, sel->m, sel->p, sel->cpcon); + + /* once we are out of slow mode, set up the T30 PLLs also */ + if (!slow && chip_type == TEGRA_SOC_T30_408MHZ) { + debug(" init_pllx: adjusting PLLP out freqs\n"); + adjust_pllp_out_freqs(); + } +} + +static void enable_cpu_clock(int enable) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 clk; + + debug("enable_cpu_clock entry, enable = %d\n", enable); + /* + * NOTE: + * Regardless of whether the request is to enable or disable the CPU + * clock, every processor in the CPU complex except the master (CPU 0) + * will have it's clock stopped because the AVP only talks to the + * master. The AVP does not know (nor does it need to know) that there + * are multiple processors in the CPU complex. + */ + + if (enable) { + /* Initialize PLLX in 'slow' mode */ + init_pllx(1); + + /* Wait until all clocks are stable */ + udelay(PLL_STABILIZATION_DELAY); + + writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); + writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); + } + + /* + * Read the register containing the individual CPU clock enables and + * always stop the clock to CPUs 1, 2 & 3. + */ + clk = readl(&clkrst->crc_clk_cpu_cmplx); + clk |= 1 << CPU1_CLK_STP_SHIFT; + clk |= 1 << CPU2_CLK_STP_SHIFT; + clk |= 1 << CPU3_CLK_STP_SHIFT; + + /* Stop/Unstop the CPU clock */ + clk &= ~CPU0_CLK_STP_MASK; + clk |= !enable << CPU0_CLK_STP_SHIFT; + writel(clk, &clkrst->crc_clk_cpu_cmplx); + + clock_enable(PERIPH_ID_CPU); + debug("enable_cpu_clock entry, enabled CPU clock\n"); +} + +static int is_cpu_powered(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + debug("is_cpu_powered entry\n"); + return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0; +} + +static void remove_cpu_io_clamps(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + debug("remove_cpu_io_clamps entry\n"); + /* Remove the clamps on the CPU I/O signals */ + reg = readl(&pmc->pmc_remove_clamping); + reg |= CPU_CLMP; + writel(reg, &pmc->pmc_remove_clamping); + + /* Give I/O signals time to stabilize */ + udelay(IO_STABILIZATION_DELAY); +} + +static void powerup_cpu(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + int timeout = IO_STABILIZATION_DELAY; + + debug("powerup_cpu entry\n"); + if (!is_cpu_powered()) { + /* Toggle the CPU power state (OFF -> ON) */ + reg = readl(&pmc->pmc_pwrgate_toggle); + reg &= PARTID_CP; + reg |= START_CP; + writel(reg, &pmc->pmc_pwrgate_toggle); + + /* Wait for the power to come up */ + while (!is_cpu_powered()) { + if (timeout-- == 0) + printf("CPU failed to power up!\n"); + else + udelay(10); + } + + /* + * Remove the I/O clamps from CPU power partition. + * Recommended only on a Warm boot, if the CPU partition gets + * power gated. Shouldn't cause any harm when called after a + * cold boot according to HW, probably just redundant. + */ + remove_cpu_io_clamps(); + } +} + +void tegra_i2c_ll_write_addr(uint addr, uint config) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(addr, ®->cmd_addr0); + writel(config, ®->cnfg); +} + +void tegra_i2c_ll_write_data(uint data, uint config) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(data, ®->cmd_data1); + writel(config, ®->cnfg); +} + +static void enable_cpu_power_rail(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + debug("enable_cpu_power_rail entry\n"); + reg = readl(&pmc->pmc_cntrl); + reg |= CPUPWRREQ_OE; + writel(reg, &pmc->pmc_cntrl); + + /* + * Pulse PWRREQ via I2C. We need to find out what this is + * doing, tidy up the code and maybe find a better place for it. + */ + tegra_i2c_ll_write_addr(0x005a, 0x0002); + tegra_i2c_ll_write_data(0x2328, 0x0a02); + udelay(1000); + tegra_i2c_ll_write_data(0x0127, 0x0a02); + udelay(10 * 1000); +} + +static void reset_A9_cpu(int reset) +{ + /* + * NOTE: Regardless of whether the request is to hold the CPU in reset + * or take it out of reset, every processor in the CPU complex + * except the master (CPU 0) will be held in reset because the + * AVP only talks to the master. The AVP does not know that there + * are multiple processors in the CPU complex. + */ + int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug; + int num_cpus = get_num_cpus(); + int cpu; + + debug("reset_a9_cpu entry\n"); + /* Hold CPUs 1 onwards in reset, and CPU 0 if asked */ + for (cpu = 1; cpu < num_cpus; cpu++) + reset_cmplx_set_enable(cpu, mask, 1); + reset_cmplx_set_enable(0, mask, reset); + + /* Enable/Disable master CPU reset */ + reset_set_enable(PERIPH_ID_CPU, reset); +} + +/** + * The T30 requires some special clock initialization, including setting up + * the dvc i2c, turning on mselect and selecting the G CPU cluster + */ +void t30_init_clocks(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + u32 val; + + debug("t30_init_clocks entry\n"); + /* Set active CPU cluster to G */ + clrbits_le32(flow->cluster_control, 1 << 0); + + /* + * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run + * at 108 MHz. This is glitch free as only the source is changed, no + * special precaution needed. + */ + val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) | + (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) | + (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) | + (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) | + (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT); + writel(val, &clkrst->crc_sclk_brst_pol); + + writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div); + + val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) | + (1 << CLK_SYS_RATE_AHB_RATE_SHIFT) | + (0 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) | + (0 << CLK_SYS_RATE_APB_RATE_SHIFT); + writel(val, &clkrst->crc_clk_sys_rate); + + /* Put i2c, mselect in reset and enable clocks */ + reset_set_enable(PERIPH_ID_DVC_I2C, 1); + clock_set_enable(PERIPH_ID_DVC_I2C, 1); + reset_set_enable(PERIPH_ID_MSELECT, 1); + clock_set_enable(PERIPH_ID_MSELECT, 1); + + /* Switch MSELECT clock to PLLP (00) */ + clock_ll_set_source(PERIPH_ID_MSELECT, 0); + + /* + * Our high-level clock routines are not available prior to + * relocation. We use the low-level functions which require a + * hard-coded divisor. Use CLK_M with divide by (n + 1 = 17) + */ + clock_ll_set_source_divisor(PERIPH_ID_DVC_I2C, 3, 16); + + /* + * Give clocks time to stabilize, then take i2c and mselect out of + * reset + */ + udelay(1000); + reset_set_enable(PERIPH_ID_DVC_I2C, 0); + reset_set_enable(PERIPH_ID_MSELECT, 0); +} + +static void clock_enable_coresight(int enable) +{ + u32 rst, src; + + debug("clock_enable_coresight entry\n"); + clock_set_enable(PERIPH_ID_CORESIGHT, enable); + reset_set_enable(PERIPH_ID_CORESIGHT, !enable); + + if (enable) { + /* + * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by + * 1.5, giving an effective frequency of 144MHz. + * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor + * (bits 7:0), so 00000001b == 1.5 (n+1 + .5) + * + * Clock divider request for 204MHz would setup CSITE clock as + * 144MHz for PLLP base 216MHz and 204MHz for PLLP base 408MHz + */ + if (get_chip_type() == TEGRA_SOC_T30_408MHZ) + src = CLK_DIVIDER(NVBL_PLLP_KHZ, 204000); + else + src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); + clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src); + + /* Unlock the CPU CoreSight interfaces */ + rst = CORESIGHT_UNLOCK; + writel(rst, CSITE_CPU_DBG0_LAR); + writel(rst, CSITE_CPU_DBG1_LAR); + writel(rst, CSITE_CPU_DBG2_LAR); + writel(rst, CSITE_CPU_DBG3_LAR); + } +} + +static void set_cpu_running(int run) +{ + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + + debug("set_cpu_running entry, run = %d\n", run); + writel(run ? FLOW_MODE_NONE : FLOW_MODE_STOP, &flow->halt_cpu_events); +} + +void start_cpu(u32 reset_vector) +{ + debug("start_cpu entry, reset_vector = %x\n", reset_vector); + t30_init_clocks(); + + /* Enable VDD_CPU */ + enable_cpu_power_rail(); + + set_cpu_running(0); + + /* Hold the CPUs in reset */ + reset_A9_cpu(1); + + /* Disable the CPU clock */ + enable_cpu_clock(0); + + /* Enable CoreSight */ + clock_enable_coresight(1); + + /* + * Set the entry point for CPU execution from reset, + * if it's a non-zero value. + */ + if (reset_vector) + writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); + + /* Enable the CPU clock */ + enable_cpu_clock(1); + + /* If the CPU doesn't already have power, power it up */ + powerup_cpu(); + + /* Take the CPU out of reset */ + reset_A9_cpu(0); + + set_cpu_running(1); +} + + +void halt_avp(void) +{ + debug("halt_avp entry\n"); + for (;;) { + writel((HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \ + | HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29)), + FLOW_CTLR_HALT_COP_EVENTS); + } +}

On 10/02/2012 04:45 PM, Tom Warren wrote:
This provides SPL support for T30 boards - AVP early init, plus CPU (A9) init/jump to main U-Boot.
diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c
+/*
- Timing tables for each SOC for all four oscillator options.
- */
+static struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_COUNT]
[CLOCK_OSC_FREQ_COUNT] = {
- /* T20: 1 GHz */
This is odd; it's a Tegra30-specific file, yet has data tables for Tegra20 too, and various code that only makes sense to differentiate Tegra20 and Tegra30 at runtime.
Either everything in this file should be Tegra30-specific, or whatever new code is being added here should be added to a file in tegra-common if it needs to handle both SoCs.
+static int get_chip_type(void) +{
- /*
* T30 has two options. We will return TEGRA_SOC_T30 until
* we have the fdt set up when it may change to
* TEGRA_SOC_T30_408MHZ depending on what we set PLLP to.
*/
I'm not sure what the FDT has to do with it? Certainly at this point in the series, I doubt that comment is accurate. Do we actually reprogram the PLLs based on FDT later?
- if (clock_get_rate(CLOCK_ID_PERIPH) == 408000000)
return TEGRA_SOC_T30_408MHZ;
- else
return TEGRA_SOC_T30;
I thought we'd decided not to support one of those options, but perhaps it's used somewhere...
+static void adjust_pllp_out_freqs(void) +{
- struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
- struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH];
- u32 reg;
- /* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */
- reg = readl(&pll->pll_out[0]); /* OUTA, contains OUT2 / OUT1 */
- reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR
| (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR;
- writel(reg, &pll->pll_out[0]);
- reg = readl(&pll->pll_out[1]); /* OUTB, contains OUT4 / OUT3 */
- reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR
| (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR;
- writel(reg, &pll->pll_out[1]);
+}
I don't think that code is ever used, since init_pllx() below is only ever called with slow==1, so never calls it.
+void tegra_i2c_ll_write_addr(uint addr, uint config) +{
- struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
- writel(addr, ®->cmd_addr0);
- writel(config, ®->cnfg);
+}
+void tegra_i2c_ll_write_data(uint data, uint config) +{
- struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
- writel(data, ®->cmd_data1);
- writel(config, ®->cnfg);
+}
+static void enable_cpu_power_rail(void) +{
- struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
- u32 reg;
- debug("enable_cpu_power_rail entry\n");
- reg = readl(&pmc->pmc_cntrl);
- reg |= CPUPWRREQ_OE;
- writel(reg, &pmc->pmc_cntrl);
- /*
* Pulse PWRREQ via I2C. We need to find out what this is
* doing, tidy up the code and maybe find a better place for it.
*/
- tegra_i2c_ll_write_addr(0x005a, 0x0002);
- tegra_i2c_ll_write_data(0x2328, 0x0a02);
With a TPS65911x attached to the DVC I2C bus, that sets VDD to 1.4V (I assume that's both the VDD1 and VDD2 outputs, but the PMIC datasheet isn't too clear on that at a quick glance), and:
- udelay(1000);
- tegra_i2c_ll_write_data(0x0127, 0x0a02);
... and this enables the VDD regulator.
So, this is: a) Entirely specific to a TPS65911x regulator. I think this warrants a very large FIXME comment. b) Nothing to do with pulsing PWRREQ via I2C. c) Really should be done via programming the EEPROM on the PMIC so that SW doesn't have to do this, but I guess that didn't happen.
+static void reset_A9_cpu(int reset) +{
- /*
- NOTE: Regardless of whether the request is to hold the CPU in reset
or take it out of reset, every processor in the CPU complex
except the master (CPU 0) will be held in reset because the
AVP only talks to the master. The AVP does not know that there
are multiple processors in the CPU complex.
- */
At least the last sentence there is false; this code is running on the AVP and there's explicit code above that determines the number of CPUs in the main CPU complex (get_num_cpus) and sets separate reset bits for each of them (enable_cpu_clock). Oh, and ~7 lines below, there's a loop over num_cpus:
- int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug;
- int num_cpus = get_num_cpus();
- int cpu;
- debug("reset_a9_cpu entry\n");
- /* Hold CPUs 1 onwards in reset, and CPU 0 if asked */
- for (cpu = 1; cpu < num_cpus; cpu++)
reset_cmplx_set_enable(cpu, mask, 1);
- reset_cmplx_set_enable(0, mask, reset);

Stephen,
On Wed, Oct 3, 2012 at 11:23 AM, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/02/2012 04:45 PM, Tom Warren wrote:
This provides SPL support for T30 boards - AVP early init, plus CPU (A9) init/jump to main U-Boot.
diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c
+/*
- Timing tables for each SOC for all four oscillator options.
- */
+static struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_COUNT]
[CLOCK_OSC_FREQ_COUNT] = {
/* T20: 1 GHz */
This is odd; it's a Tegra30-specific file, yet has data tables for Tegra20 too, and various code that only makes sense to differentiate Tegra20 and Tegra30 at runtime.
I'd meant to pull this out, or commonize the cpu.c files in arm720t, but forgot about it.
I'll move common code to arm720t/tegra/cpu.c and leave HW-specific stuff in tegra[23]0/cpu.c on the next rev.
Either everything in this file should be Tegra30-specific, or whatever new code is being added here should be added to a file in tegra-common if it needs to handle both SoCs.
+static int get_chip_type(void) +{
/*
* T30 has two options. We will return TEGRA_SOC_T30 until
* we have the fdt set up when it may change to
* TEGRA_SOC_T30_408MHZ depending on what we set PLLP to.
*/
I'm not sure what the FDT has to do with it? Certainly at this point in the series, I doubt that comment is accurate. Do we actually reprogram the PLLs based on FDT later?
Most of this file was brought in during a merge with our internal T30 U-Boot repo, so most of these comments aren't from me, but from the folks that brought up T30 in-house. I chose to start at the slower PLLX rate (216?) for bringup, and planned to phase in 408MHz support later, once I was sure of a stable SW base.
if (clock_get_rate(CLOCK_ID_PERIPH) == 408000000)
return TEGRA_SOC_T30_408MHZ;
else
return TEGRA_SOC_T30;
I thought we'd decided not to support one of those options, but perhaps it's used somewhere...
See above. Once 408MHz is ported/working, I can remove the slower clock rate entirely.
+static void adjust_pllp_out_freqs(void) +{
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH];
u32 reg;
/* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */
reg = readl(&pll->pll_out[0]); /* OUTA, contains OUT2 / OUT1 */
reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR
| (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR;
writel(reg, &pll->pll_out[0]);
reg = readl(&pll->pll_out[1]); /* OUTB, contains OUT4 / OUT3 */
reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR
| (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR;
writel(reg, &pll->pll_out[1]);
+}
I don't think that code is ever used, since init_pllx() below is only ever called with slow==1, so never calls it.
Yeah, this'll be used later to get to 408MHz. I'd planned to use it but didn't get around to it. I can remove it in v2, or try for full speed (408MHz) instead. Depends on bandwidth & priorities.
+void tegra_i2c_ll_write_addr(uint addr, uint config) +{
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
writel(addr, ®->cmd_addr0);
writel(config, ®->cnfg);
+}
+void tegra_i2c_ll_write_data(uint data, uint config) +{
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
writel(data, ®->cmd_data1);
writel(config, ®->cnfg);
+}
+static void enable_cpu_power_rail(void) +{
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
u32 reg;
debug("enable_cpu_power_rail entry\n");
reg = readl(&pmc->pmc_cntrl);
reg |= CPUPWRREQ_OE;
writel(reg, &pmc->pmc_cntrl);
/*
* Pulse PWRREQ via I2C. We need to find out what this is
* doing, tidy up the code and maybe find a better place for it.
*/
tegra_i2c_ll_write_addr(0x005a, 0x0002);
tegra_i2c_ll_write_data(0x2328, 0x0a02);
With a TPS65911x attached to the DVC I2C bus, that sets VDD to 1.4V (I assume that's both the VDD1 and VDD2 outputs, but the PMIC datasheet isn't too clear on that at a quick glance), and:
udelay(1000);
tegra_i2c_ll_write_data(0x0127, 0x0a02);
... and this enables the VDD regulator.
So, this is: a) Entirely specific to a TPS65911x regulator. I think this warrants a very large FIXME comment. b) Nothing to do with pulsing PWRREQ via I2C. c) Really should be done via programming the EEPROM on the PMIC so that SW doesn't have to do this, but I guess that didn't happen.
Again, this comes from our internal repo & wasn't done by me, so I had no knowledge of what exactly it was doing. But removing it resulted in a hung system, so I had to leave it in. Your comments are helpful - I'll revise this in v2 with new comments and better reg/data defines, etc.
+static void reset_A9_cpu(int reset) +{
/*
* NOTE: Regardless of whether the request is to hold the CPU in reset
* or take it out of reset, every processor in the CPU complex
* except the master (CPU 0) will be held in reset because the
* AVP only talks to the master. The AVP does not know that there
* are multiple processors in the CPU complex.
*/
At least the last sentence there is false; this code is running on the AVP and there's explicit code above that determines the number of CPUs in the main CPU complex (get_num_cpus) and sets separate reset bits for each of them (enable_cpu_clock). Oh, and ~7 lines below, there's a loop over num_cpus:
Again, a comment from a previous dev, not me. I think they're just saying that the AVP is only working on 1 CPU, and doesn't do full init of the other ones, since they're aren't needed for U-Boot to find/fetch a kernel, etc.
int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug;
int num_cpus = get_num_cpus();
int cpu;
debug("reset_a9_cpu entry\n");
/* Hold CPUs 1 onwards in reset, and CPU 0 if asked */
for (cpu = 1; cpu < num_cpus; cpu++)
reset_cmplx_set_enable(cpu, mask, 1);
reset_cmplx_set_enable(0, mask, reset);
Thanks for the thorough review,
Tom

Hi Stephen,
On Wed, Oct 3, 2012 at 11:23 AM, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/02/2012 04:45 PM, Tom Warren wrote:
This provides SPL support for T30 boards - AVP early init, plus CPU (A9) init/jump to main U-Boot.
diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c
+static int get_chip_type(void) +{
/*
* T30 has two options. We will return TEGRA_SOC_T30 until
* we have the fdt set up when it may change to
* TEGRA_SOC_T30_408MHZ depending on what we set PLLP to.
*/
I'm not sure what the FDT has to do with it? Certainly at this point in the series, I doubt that comment is accurate. Do we actually reprogram the PLLs based on FDT later?
Yes, and that changes the SOC here. It's a bit odd but the AVP couldn't know what speed we wanted so we updated it later when the Cortex-A9 was running.
if (clock_get_rate(CLOCK_ID_PERIPH) == 408000000)
return TEGRA_SOC_T30_408MHZ;
else
return TEGRA_SOC_T30;
I thought we'd decided not to support one of those options, but perhaps it's used somewhere...
Yes, in fact we started using 408MHz exclusively. Not sure if that is possible upstream - unless anyone knows for sure I suggest we leave it as is and remove it later if no one needs it.
+static void adjust_pllp_out_freqs(void) +{
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH];
u32 reg;
/* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */
reg = readl(&pll->pll_out[0]); /* OUTA, contains OUT2 / OUT1 */
reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR
| (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR;
writel(reg, &pll->pll_out[0]);
reg = readl(&pll->pll_out[1]); /* OUTB, contains OUT4 / OUT3 */
reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR
| (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR;
writel(reg, &pll->pll_out[1]);
+}
I don't think that code is ever used, since init_pllx() below is only ever called with slow==1, so never calls it.
This probably came from this function that we had in arch/arm/cpu/armv7/tegra-common/board.c:
void arch_full_speed(void) { ap20_init_pllx(0); debug("CPU at %d\n", clock_get_rate(CLOCK_ID_XCPU)); debug("Memory at %d\n", clock_get_rate(CLOCK_ID_MEMORY)); debug("Periph at %d\n", clock_get_rate(CLOCK_ID_PERIPH)); }
It was called from board/nvidia/common/board.
If you like, take a look at the chromeos-v2011.06 branch of U-Boot for anything about this.
+void tegra_i2c_ll_write_addr(uint addr, uint config) +{
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
writel(addr, ®->cmd_addr0);
writel(config, ®->cnfg);
+}
+void tegra_i2c_ll_write_data(uint data, uint config) +{
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
writel(data, ®->cmd_data1);
writel(config, ®->cnfg);
+}
Well this is a lot better than the ugliness I had. I don't think you can put this into the i2c driver since the AVP doesn't have it, right?
+static void enable_cpu_power_rail(void) +{
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
u32 reg;
debug("enable_cpu_power_rail entry\n");
reg = readl(&pmc->pmc_cntrl);
reg |= CPUPWRREQ_OE;
writel(reg, &pmc->pmc_cntrl);
/*
* Pulse PWRREQ via I2C. We need to find out what this is
* doing, tidy up the code and maybe find a better place for it.
*/
tegra_i2c_ll_write_addr(0x005a, 0x0002);
tegra_i2c_ll_write_data(0x2328, 0x0a02);
With a TPS65911x attached to the DVC I2C bus, that sets VDD to 1.4V (I assume that's both the VDD1 and VDD2 outputs, but the PMIC datasheet isn't too clear on that at a quick glance), and:
udelay(1000);
tegra_i2c_ll_write_data(0x0127, 0x0a02);
... and this enables the VDD regulator.
So, this is: a) Entirely specific to a TPS65911x regulator. I think this warrants a very large FIXME comment. b) Nothing to do with pulsing PWRREQ via I2C. c) Really should be done via programming the EEPROM on the PMIC so that SW doesn't have to do this, but I guess that didn't happen.
+static void reset_A9_cpu(int reset) +{
/*
* NOTE: Regardless of whether the request is to hold the CPU in reset
* or take it out of reset, every processor in the CPU complex
* except the master (CPU 0) will be held in reset because the
* AVP only talks to the master. The AVP does not know that there
* are multiple processors in the CPU complex.
*/
At least the last sentence there is false; this code is running on the AVP and there's explicit code above that determines the number of CPUs in the main CPU complex (get_num_cpus) and sets separate reset bits for each of them (enable_cpu_clock). Oh, and ~7 lines below, there's a loop over num_cpus:
int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug;
int num_cpus = get_num_cpus();
int cpu;
debug("reset_a9_cpu entry\n");
/* Hold CPUs 1 onwards in reset, and CPU 0 if asked */
for (cpu = 1; cpu < num_cpus; cpu++)
reset_cmplx_set_enable(cpu, mask, 1);
reset_cmplx_set_enable(0, mask, reset);
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Regards, Simon

Hi Tom,
On Tue, Oct 2, 2012 at 3:45 PM, Tom Warren twarren.nvidia@gmail.com wrote:
This provides SPL support for T30 boards - AVP early init, plus CPU (A9) init/jump to main U-Boot.
Signed-off-by: Tom Warren twarren@nvidia.com
arch/arm/cpu/arm720t/tegra-common/cpu.h | 48 +-- arch/arm/cpu/arm720t/tegra-common/spl.c | 3 +- .../arm/cpu/arm720t/tegra30}/Makefile | 20 +- arch/arm/cpu/arm720t/tegra30/config.mk | 19 + arch/arm/cpu/arm720t/tegra30/cpu.c | 516 ++++++++++++++++++++ 5 files changed, 554 insertions(+), 52 deletions(-) copy {board/compal/paz00 => arch/arm/cpu/arm720t/tegra30}/Makefile (68%) create mode 100644 arch/arm/cpu/arm720t/tegra30/config.mk create mode 100644 arch/arm/cpu/arm720t/tegra30/cpu.c
I just have a few additional comments.
diff --git a/arch/arm/cpu/arm720t/tegra-common/cpu.h b/arch/arm/cpu/arm720t/tegra-common/cpu.h index 6804cd7..0d9a3c2 100644
diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c new file mode 100644 index 0000000..e0821ef --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/cpu.c @@ -0,0 +1,516 @@ +/*
- Copyright (c) 2010-2012, 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 <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/flow.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/tegra.h> +#include <asm/arch-tegra/clk_rst.h> +#include <asm/arch-tegra/fuse.h> +#include <asm/arch-tegra/pmc.h> +#include <asm/arch-tegra/scu.h> +#include <asm/arch-tegra/tegra_i2c.h> +#include "../tegra-common/cpu.h"
+struct clk_pll_table {
u16 n;
u16 m;
u8 p;
u8 cpcon;
+};
+/* ~0=uninitialized/unknown, 0=false, 1=true */ +uint32_t is_tegra_processor_reset = 0xffffffff;
+/*
- Timing tables for each SOC for all four oscillator options.
- */
+static struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_COUNT]
[CLOCK_OSC_FREQ_COUNT] = {
/* T20: 1 GHz */
{{ 1000, 13, 0, 12}, /* OSC 13M */
{ 625, 12, 0, 8}, /* OSC 19.2M */
{ 1000, 12, 0, 12}, /* OSC 12M */
{ 1000, 26, 0, 12}, /* OSC 26M */
},
/* T25: 1.2 GHz */
{{ 923, 10, 0, 12},
{ 750, 12, 0, 8},
{ 600, 6, 0, 12},
{ 600, 13, 0, 12},
},
/* T30(slow): 1.0 GHz */
{{ 1000, 13, 0, 8},
{ 625, 12, 0, 4},
{ 1000, 12, 0, 8},
{ 1000, 26, 0, 8},
},
/* T30(high): 1.4 GHz */
{{ 862, 8, 0, 8},
{ 583, 8, 0, 4},
{ 700, 6, 0, 8},
{ 700, 13, 0, 8},
},
/* TEGRA_SOC2_SLOW: 312 MHz */
{{ 312, 13, 0, 12}, /* OSC 13M */
{ 260, 16, 0, 8}, /* OSC 19.2M */
{ 312, 12, 0, 12}, /* OSC 12M */
{ 312, 26, 0, 12}, /* OSC 26M */
},
+};
+enum tegra_family_t {
TEGRA_FAMILY_T2x,
TEGRA_FAMILY_T3x,
+};
This is fine here since the function that uses it is static. I wonder if we want to export that function one day?
+static int get_chip_type(void) +{
/*
* T30 has two options. We will return TEGRA_SOC_T30 until
* we have the fdt set up when it may change to
* TEGRA_SOC_T30_408MHZ depending on what we set PLLP to.
*/
if (clock_get_rate(CLOCK_ID_PERIPH) == 408000000)
return TEGRA_SOC_T30_408MHZ;
else
return TEGRA_SOC_T30;
+}
+static enum tegra_family_t get_family(void) +{
u32 reg, chip_id;
debug("tegra_get_family entry\n");
reg = readl(NV_PA_APB_MISC_BASE + GP_HIDREV);
chip_id = reg >> 8;
chip_id &= 0xff;
debug(" tegra_get_family: chip_id = %x\n", chip_id);
if (chip_id == 0x30)
return TEGRA_FAMILY_T3x;
else
return TEGRA_FAMILY_T2x;
+}
+int get_num_cpus(void) +{
return get_family() == TEGRA_FAMILY_T3x ? 4 : 2;
+}
+static void adjust_pllp_out_freqs(void) +{
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH];
u32 reg;
/* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */
reg = readl(&pll->pll_out[0]); /* OUTA, contains OUT2 / OUT1 */
reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR
| (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR;
writel(reg, &pll->pll_out[0]);
reg = readl(&pll->pll_out[1]); /* OUTB, contains OUT4 / OUT3 */
reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR
| (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR;
writel(reg, &pll->pll_out[1]);
+}
+static int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm,
u32 divp, u32 cpcon)
From this function on I see quite a bit of similarity with the tegra20
version. IMO the number of cpus can just be the result of get_num_cpus(), most of the clocks are the same, and differences can either be in this file or behind a conditional check for the family. Otherwise we have duplicated code here.
Regards, Simon

These files are for code that runs on the CPU (A9) on T30 boards. At this time, it's only the RCM (Recovery Mode) cmd file, which is in tegra-common. As T30-specific run-time code is added, it'll go here.
Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/cpu/{arm720t => armv7}/tegra30/Makefile | 13 ++++++------- arch/arm/cpu/{arm720t => armv7}/tegra30/config.mk | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) copy arch/arm/cpu/{arm720t => armv7}/tegra30/Makefile (86%) copy arch/arm/cpu/{arm720t => armv7}/tegra30/config.mk (95%)
diff --git a/arch/arm/cpu/arm720t/tegra30/Makefile b/arch/arm/cpu/armv7/tegra30/Makefile similarity index 86% copy from arch/arm/cpu/arm720t/tegra30/Makefile copy to arch/arm/cpu/armv7/tegra30/Makefile index bd96997..b04732d 100644 --- a/arch/arm/cpu/arm720t/tegra30/Makefile +++ b/arch/arm/cpu/armv7/tegra30/Makefile @@ -1,7 +1,7 @@ # # Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. # -# (C) Copyright 2000-2008 +# (C) Copyright 2000-2003 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # # This program is free software; you can redistribute it and/or modify it @@ -19,14 +19,13 @@
include $(TOPDIR)/config.mk
-LIB = $(obj)lib$(SOC).o +LIB = $(obj)lib$(SOC).o
-COBJS-y += cpu.o +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS))
-SRCS := $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS-y)) - -all: $(obj).depend $(LIB) +all: $(obj).depend $(LIB)
$(LIB): $(OBJS) $(call cmd_link_o_target, $(OBJS)) diff --git a/arch/arm/cpu/arm720t/tegra30/config.mk b/arch/arm/cpu/armv7/tegra30/config.mk similarity index 95% copy from arch/arm/cpu/arm720t/tegra30/config.mk copy to arch/arm/cpu/armv7/tegra30/config.mk index 2388c56..719ca81 100644 --- a/arch/arm/cpu/arm720t/tegra30/config.mk +++ b/arch/arm/cpu/armv7/tegra30/config.mk @@ -16,4 +16,4 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # -USE_PRIVATE_LIBGCC = yes +CONFIG_ARCH_DEVICE_TREE := tegra30

On 10/02/2012 04:45 PM, Tom Warren wrote:
These files are for code that runs on the CPU (A9) on T30 boards. At this time, it's only the RCM (Recovery Mode) cmd file, which is in tegra-common. As T30-specific run-time code is added, it'll go here.
diff --git a/arch/arm/cpu/arm720t/tegra30/Makefile b/arch/arm/cpu/armv7/tegra30/Makefile
-LIB = $(obj)lib$(SOC).o +LIB = $(obj)lib$(SOC).o
Looks like there are two spaces after the = there.
-all: $(obj).depend $(LIB) +all: $(obj).depend $(LIB)
And a space after the TAB there.
Does U-Boot compile at this point in the series? Hopefully "git bisect" is maintained across the series. I suppose there aren't any boards.cfg entries for Tegra30 yet, so the fact that e.g. CONFIG_ARCH_DEVICE_TREE points at a file that doesn't yet exist is impossible to notice.

Stephen,
On Wed, Oct 3, 2012 at 11:26 AM, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/02/2012 04:45 PM, Tom Warren wrote:
These files are for code that runs on the CPU (A9) on T30 boards. At this time, it's only the RCM (Recovery Mode) cmd file, which is in tegra-common. As T30-specific run-time code is added, it'll go here.
diff --git a/arch/arm/cpu/arm720t/tegra30/Makefile b/arch/arm/cpu/armv7/tegra30/Makefile
-LIB = $(obj)lib$(SOC).o +LIB = $(obj)lib$(SOC).o
Looks like there are two spaces after the = there.
-all: $(obj).depend $(LIB) +all: $(obj).depend $(LIB)
And a space after the TAB there.
Right on both counts. Despite what git format-patch said about the origin of this file, it was really copied over from armv7/tegra20/Makefile, and the spacing errors are in that file originally. Guess checkpatch doesn't look at Makefiles.
I'll correct this on the next rev. Thanks.
Does U-Boot compile at this point in the series? Hopefully "git bisect" is maintained across the series. I suppose there aren't any boards.cfg entries for Tegra30 yet, so the fact that e.g. CONFIG_ARCH_DEVICE_TREE points at a file that doesn't yet exist is impossible to notice.
I haven't done a git bisect on the series, but I did do individual git am's on each patch with ./MAKEALL -s tegra20 between each, and saw no problems when I did the first port. I did go in and rebase/amend a few commits, though, during a final clean-up effort, so I may have broken bisect. I'll be sure to test each patch/bisect on the next rev.
Thanks,
Tom

These files are used by both SPL and main U-Boot. Also made minor changes to shared Tegra code to support T30 differences.
Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/cpu/tegra-common/ap.c | 22 +- arch/arm/cpu/tegra-common/board.c | 25 +- arch/arm/cpu/tegra-common/sys_info.c | 5 +- arch/arm/cpu/tegra20-common/warmboot.c | 2 +- .../{arm720t/tegra30 => tegra30-common}/Makefile | 11 +- .../cpu/{tegra20-common => tegra30-common}/clock.c | 508 +++++++++----------- arch/arm/cpu/tegra30-common/funcmux.c | 57 +++ arch/arm/cpu/tegra30-common/pinmux.c | 501 +++++++++++++++++++ arch/arm/include/asm/arch-tegra/ap.h | 50 +-- 9 files changed, 851 insertions(+), 330 deletions(-) copy arch/arm/cpu/{arm720t/tegra30 => tegra30-common}/Makefile (80%) copy arch/arm/cpu/{tegra20-common => tegra30-common}/clock.c (75%) create mode 100644 arch/arm/cpu/tegra30-common/funcmux.c create mode 100644 arch/arm/cpu/tegra30-common/pinmux.c
diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c index c4eb137..e1a400c 100644 --- a/arch/arm/cpu/tegra-common/ap.c +++ b/arch/arm/cpu/tegra-common/ap.c @@ -20,10 +20,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ + +/* Tegra AP (Application Processor) code */ + #include <common.h> #include <asm/io.h> #include <asm/arch/gp_padctrl.h> #include <asm/arch-tegra/ap.h> +#include <asm/arch-tegra/clock.h> #include <asm/arch-tegra/fuse.h> #include <asm/arch-tegra/pmc.h> #include <asm/arch-tegra/scu.h> @@ -58,6 +62,20 @@ int tegra_get_chip_type(void) return TEGRA_SOC_T25; } break; + case CHIPID_TEGRA30: + switch (tegra_sku_id) { + case SKU_ID_T30: + /* + * T30 has two options. We will return TEGRA_SOC_T30 + * until we have the fdt set up when it may change to + * TEGRA_SOC_T30_408MHZ depending on the PLLP freq. + */ + if (clock_get_rate(CLOCK_ID_PERIPH) == 408000000) + return TEGRA_SOC_T30_408MHZ; + else + return TEGRA_SOC_T30; + } + break; } /* unknown sku id */ return TEGRA_SOC_UNKNOWN; @@ -93,7 +111,7 @@ static u32 get_odmdata(void)
u32 bct_start, odmdata;
- bct_start = readl(AP20_BASE_PA_SRAM + NVBOOTINFOTABLE_BCTPTR); + bct_start = readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BCTPTR); odmdata = readl(bct_start + BCT_ODMDATA_OFFSET);
return odmdata; @@ -127,5 +145,5 @@ void s_init(void) "orr r0, r0, #0x41\n" "mcr p15, 0, r0, c1, c0, 1\n");
- /* FIXME: should have ap20's L2 disabled too? */ + /* FIXME: should have SoC's L2 disabled too? */ } diff --git a/arch/arm/cpu/tegra-common/board.c b/arch/arm/cpu/tegra-common/board.c index b2e10c6..1214bc0 100644 --- a/arch/arm/cpu/tegra-common/board.c +++ b/arch/arm/cpu/tegra-common/board.c @@ -59,9 +59,12 @@ unsigned int query_sdram_size(void) case 1: return 0x10000000; /* 256 MB */ case 2: - default: return 0x20000000; /* 512 MB */ - case 3: + case 4: + return 0x40000000; /* 1GB */ + case 8: + return 0x7ff00000; /* 2GB - 1MB */ + default: return 0x40000000; /* 1GB */ } } @@ -82,19 +85,27 @@ int checkboard(void) #endif /* CONFIG_DISPLAY_BOARDINFO */
static int uart_configs[] = { -#if defined(CONFIG_TEGRA_UARTA_UAA_UAB) +#if defined(CONFIG_TEGRA20) + #if defined(CONFIG_TEGRA_UARTA_UAA_UAB) FUNCMUX_UART1_UAA_UAB, -#elif defined(CONFIG_TEGRA_UARTA_GPU) + #elif defined(CONFIG_TEGRA_UARTA_GPU) FUNCMUX_UART1_GPU, -#elif defined(CONFIG_TEGRA_UARTA_SDIO1) + #elif defined(CONFIG_TEGRA_UARTA_SDIO1) FUNCMUX_UART1_SDIO1, -#else + #else FUNCMUX_UART1_IRRX_IRTX, -#endif + #endif FUNCMUX_UART2_IRDA, -1, FUNCMUX_UART4_GMC, -1, +#else /* Tegra30 */ + FUNCMUX_UART1_ULPI, /* UARTA */ + -1, + -1, + -1, + -1, +#endif };
/** diff --git a/arch/arm/cpu/tegra-common/sys_info.c b/arch/arm/cpu/tegra-common/sys_info.c index 1a0bb56..60d1de5 100644 --- a/arch/arm/cpu/tegra-common/sys_info.c +++ b/arch/arm/cpu/tegra-common/sys_info.c @@ -27,8 +27,11 @@ /* Print CPU information */ int print_cpuinfo(void) { +#if defined(CONFIG_TEGRA20) puts("TEGRA20\n"); - +#else /* Tegra30 */ + puts("TEGRA30\n"); +#endif /* TBD: Add printf of major/minor rev info, stepping, etc. */ return 0; } diff --git a/arch/arm/cpu/tegra20-common/warmboot.c b/arch/arm/cpu/tegra20-common/warmboot.c index 157b9ab..0d472cf 100644 --- a/arch/arm/cpu/tegra20-common/warmboot.c +++ b/arch/arm/cpu/tegra20-common/warmboot.c @@ -46,7 +46,7 @@ DECLARE_GLOBAL_DATA_PTR; * This is the place in SRAM where the SDRAM parameters are stored. There * are 4 blocks, one for each RAM code */ -#define SDRAM_PARAMS_BASE (AP20_BASE_PA_SRAM + 0x188) +#define SDRAM_PARAMS_BASE (NV_PA_BASE_SRAM + 0x188)
/* TODO: If we later add support for the Misc GP controller, refactor this */ union xm2cfga_reg { diff --git a/arch/arm/cpu/arm720t/tegra30/Makefile b/arch/arm/cpu/tegra30-common/Makefile similarity index 80% copy from arch/arm/cpu/arm720t/tegra30/Makefile copy to arch/arm/cpu/tegra30-common/Makefile index bd96997..75fef32 100644 --- a/arch/arm/cpu/arm720t/tegra30/Makefile +++ b/arch/arm/cpu/tegra30-common/Makefile @@ -19,12 +19,15 @@
include $(TOPDIR)/config.mk
-LIB = $(obj)lib$(SOC).o +# The AVP is ARMv4T architecture so we must use special compiler +# flags for any startup files it might use.
-COBJS-y += cpu.o +LIB = $(obj)lib$(SOC)-common.o
-SRCS := $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS-y)) +COBJS-y += clock.o funcmux.o pinmux.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
all: $(obj).depend $(LIB)
diff --git a/arch/arm/cpu/tegra20-common/clock.c b/arch/arm/cpu/tegra30-common/clock.c similarity index 75% copy from arch/arm/cpu/tegra20-common/clock.c copy to arch/arm/cpu/tegra30-common/clock.c index 12987a6..9f0551a 100644 --- a/arch/arm/cpu/tegra20-common/clock.c +++ b/arch/arm/cpu/tegra30-common/clock.c @@ -1,25 +1,20 @@ /* - * Copyright (c) 2011 The Chromium OS Authors. - * See file CREDITS for list of people who contributed to this - * project. + * Copyright (c) 2010-2012, 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; either version 2 of - * the License, or (at your option) any later version. + * 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 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. + * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * along with this program. If not, see http://www.gnu.org/licenses/. */
-/* Tegra20 Clock control functions */ +/* Tegra30 Clock control functions */
#include <common.h> #include <asm/io.h> @@ -49,7 +44,7 @@ static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = { };
/* - * Clock types that we can use as a source. The Tegra20 has muxes for the + * Clock types that we can use as a source. The Tegra3 has muxes for the * peripheral clocks, and in most cases there are four options for the clock * source. This gives us a clock 'type' and exploits what commonality exists * in the device. @@ -68,9 +63,11 @@ enum clock_type_id { CLOCK_TYPE_MCPT, CLOCK_TYPE_PCM, CLOCK_TYPE_PCMT, - CLOCK_TYPE_PCMT16, /* CLOCK_TYPE_PCMT with 16-bit divider */ - CLOCK_TYPE_PCXTS, CLOCK_TYPE_PDCT, + CLOCK_TYPE_ACPT, + CLOCK_TYPE_ASPTE, + CLOCK_TYPE_PMDACD2T, + CLOCK_TYPE_PCST,
CLOCK_TYPE_COUNT, CLOCK_TYPE_NONE = -1, /* invalid clock type */ @@ -83,113 +80,55 @@ enum clock_type_id { char pllp_valid = 1; /* PLLP is set up correctly */
enum { - CLOCK_MAX_MUX = 4 /* number of source options for each clock */ + CLOCK_MAX_MUX = 8 /* number of source options for each clock */ };
-/* - * Clock source mux for each clock type. This just converts our enum into - * a list of mux sources for use by the code. Note that CLOCK_TYPE_PCXTS - * is special as it has 5 sources. Since it also has a different number of - * bits in its register for the source, we just handle it with a special - * case in the code. - */ -#define CLK(x) CLOCK_ID_ ## x -static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX] = { - { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC) }, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO) }, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(XCPU), CLK(OSC) }, - { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC) }, +enum { + MASK_BITS_31_30 = 2, /* num of bits used to specify clock source */ + MASK_BITS_31_29, + MASK_BITS_29_28, };
/* - * Clock peripheral IDs which sadly don't match up with PERIPH_ID. This is - * not in the header file since it is for purely internal use - we want - * callers to use the PERIPH_ID for all access to peripheral clocks to avoid - * confusion bewteen PERIPH_ID_... and PERIPHC_... - * - * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be - * confusing. + * Clock source mux for each clock type. This just converts our enum into + * a list of mux sources for use by the code. * - * Note to SOC vendors: perhaps define a unified numbering for peripherals and - * use it for reset, clock enable, clock source/divider and even pinmuxing - * if you can. + * Note: + * The extra column in each clock source array is used to store the mask + * bits in its register for the source. */ -enum periphc_internal_id { - /* 0x00 */ - PERIPHC_I2S1, - PERIPHC_I2S2, - PERIPHC_SPDIF_OUT, - PERIPHC_SPDIF_IN, - PERIPHC_PWM, - PERIPHC_SPI1, - PERIPHC_SPI2, - PERIPHC_SPI3, - - /* 0x08 */ - PERIPHC_XIO, - PERIPHC_I2C1, - PERIPHC_DVC_I2C, - PERIPHC_TWC, - PERIPHC_0c, - PERIPHC_10, /* PERIPHC_SPI1, what is this really? */ - PERIPHC_DISP1, - PERIPHC_DISP2, - - /* 0x10 */ - PERIPHC_CVE, - PERIPHC_IDE0, - PERIPHC_VI, - PERIPHC_1c, - PERIPHC_SDMMC1, - PERIPHC_SDMMC2, - PERIPHC_G3D, - PERIPHC_G2D, - - /* 0x18 */ - PERIPHC_NDFLASH, - PERIPHC_SDMMC4, - PERIPHC_VFIR, - PERIPHC_EPP, - PERIPHC_MPE, - PERIPHC_MIPI, - PERIPHC_UART1, - PERIPHC_UART2, - - /* 0x20 */ - PERIPHC_HOST1X, - PERIPHC_21, - PERIPHC_TVO, - PERIPHC_HDMI, - PERIPHC_24, - PERIPHC_TVDAC, - PERIPHC_I2C2, - PERIPHC_EMC, - - /* 0x28 */ - PERIPHC_UART3, - PERIPHC_29, - PERIPHC_VI_SENSOR, - PERIPHC_2b, - PERIPHC_2c, - PERIPHC_SPI4, - PERIPHC_I2C3, - PERIPHC_SDMMC3, - - /* 0x30 */ - PERIPHC_UART4, - PERIPHC_UART5, - PERIPHC_VDE, - PERIPHC_OWR, - PERIPHC_NOR, - PERIPHC_CSITE, - - PERIPHC_COUNT, - - PERIPHC_NONE = -1, +#define CLK(x) CLOCK_ID_ ## x +static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { + { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), + CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), + CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_29_28} };
/* return 1 if a periphc_internal_id is in range */ @@ -207,24 +146,24 @@ static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), - TYPE(PERIPHC_PWM, CLOCK_TYPE_PCXTS), - TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SPI22, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SPI3, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_PWM, CLOCK_TYPE_PCST), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT),
/* 0x08 */ - TYPE(PERIPHC_XIO, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_TWC, CLOCK_TYPE_PCMT), TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_DISP1, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_DISP2, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T),
/* 0x10 */ TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_IDE0, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), @@ -246,10 +185,10 @@ static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_HDMI, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT), TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT),
/* 0x28 */ @@ -258,8 +197,8 @@ static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SPI4, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT), TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT),
/* 0x30 */ @@ -269,6 +208,43 @@ static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + + /* 0x38h */ + TYPE(PERIPHC_G3D2, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PCM), + TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2C4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC6, CLOCK_TYPE_PCMT), + + /* 0x40 */ + TYPE(PERIPHC_AUDIO, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_DAM0, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_DAM1, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_DAM2, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PCM), + TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), + + /* 0x48 */ + TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SPEEDO, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + + /* 0x50 */ + TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_HDA, CLOCK_TYPE_PCMT), };
/* @@ -284,15 +260,15 @@ static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { /* Low word: 31:0 */ NONE(CPU), - NONE(RESERVED1), - NONE(RESERVED2), - NONE(AC97), - NONE(RTC), + NONE(COP), + NONE(TRIGSYS), + NONE(RESERVED3), + NONE(RESERVED4), NONE(TMR), PERIPHC_UART1, PERIPHC_UART2, /* and vfir 0x68 */
- /* 0x08 */ + /* 8 */ NONE(GPIO), PERIPHC_SDMMC2, NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ @@ -302,8 +278,8 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { PERIPHC_SDMMC1, PERIPHC_SDMMC4,
- /* 0x10 */ - PERIPHC_TWC, + /* 16 */ + NONE(RESERVED16), PERIPHC_PWM, PERIPHC_I2S2, PERIPHC_EPP, @@ -312,14 +288,14 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { NONE(USBD), NONE(ISP),
- /* 0x18 */ + /* 24 */ PERIPHC_G3D, - PERIPHC_IDE0, + NONE(RESERVED25), PERIPHC_DISP2, PERIPHC_DISP1, PERIPHC_HOST1X, NONE(VCP), - NONE(RESERVED30), + PERIPHC_I2S0, NONE(CACHE2),
/* Middle word: 63:32 */ @@ -327,32 +303,32 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { NONE(AHBDMA), NONE(APBDMA), NONE(RESERVED35), - NONE(KBC), + NONE(RESERVED36), NONE(STAT_MON), - NONE(PMC), - NONE(FUSE), + NONE(RESERVED38), + NONE(RESERVED39),
- /* 0x28 */ + /* 40 */ NONE(KFUSE), NONE(SBC1), /* SBC1, 0x34, is this SPI1? */ PERIPHC_NOR, - PERIPHC_SPI1, - PERIPHC_SPI2, - PERIPHC_XIO, - PERIPHC_SPI3, + NONE(RESERVED43), + PERIPHC_SBC2, + NONE(RESERVED45), + PERIPHC_SBC3, PERIPHC_DVC_I2C,
- /* 0x30 */ + /* 48 */ NONE(DSI), PERIPHC_TVO, /* also CVE 0x40 */ PERIPHC_MIPI, PERIPHC_HDMI, - PERIPHC_CSITE, + NONE(CSI), PERIPHC_TVDAC, PERIPHC_I2C2, PERIPHC_UART3,
- /* 0x38 */ + /* 56 */ NONE(RESERVED56), PERIPHC_EMC, NONE(USB2), @@ -363,47 +339,104 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { NONE(BSEV),
/* Upper word 95:64 */ - NONE(SPEEDO), + PERIPHC_SPEEDO, PERIPHC_UART4, PERIPHC_UART5, PERIPHC_I2C3, - PERIPHC_SPI4, + PERIPHC_SBC4, PERIPHC_SDMMC3, NONE(PCIE), PERIPHC_OWR,
- /* 0x48 */ + /* 72 */ NONE(AFI), - NONE(CORESIGHT), - NONE(RESERVED74), + PERIPHC_CSITE, + NONE(PCIEXCLK), NONE(AVPUCQ), NONE(RESERVED76), NONE(RESERVED77), NONE(RESERVED78), - NONE(RESERVED79), + NONE(DTV),
- /* 0x50 */ - NONE(RESERVED80), - NONE(RESERVED81), - NONE(RESERVED82), + /* 80 */ + PERIPHC_NANDSPEED, + PERIPHC_I2CSLOW, + NONE(DSIB), NONE(RESERVED83), NONE(IRAMA), NONE(IRAMB), NONE(IRAMC), NONE(IRAMD),
- /* 0x58 */ + /* 88 */ NONE(CRAM2), -}; - -/* number of clock outputs of a PLL */ -static const u8 pll_num_clkouts[] = { - 1, /* PLLC */ - 1, /* PLLM */ - 4, /* PLLP */ - 1, /* PLLA */ - 0, /* PLLU */ - 0, /* PLLD */ + NONE(RESERVED89), + NONE(MDOUBLER), + NONE(RESERVED91), + NONE(SUSOUT), + NONE(RESERVED93), + NONE(RESERVED94), + NONE(RESERVED95), + + /* V word: 31:0 */ + NONE(CPUG), + NONE(CPULP), + PERIPHC_G3D2, + PERIPHC_MSELECT, + PERIPHC_TSENSOR, + PERIPHC_I2S3, + PERIPHC_I2S4, + PERIPHC_I2C4, + + /* 08 */ + PERIPHC_SBC5, + PERIPHC_SBC6, + PERIPHC_AUDIO, + NONE(APBIF), + PERIPHC_DAM0, + PERIPHC_DAM1, + PERIPHC_DAM2, + PERIPHC_HDA2CODEC2X, + + /* 16 */ + NONE(ATOMICS), + NONE(RESERVED17), + NONE(RESERVED18), + NONE(RESERVED19), + NONE(RESERVED20), + NONE(RESERVED21), + NONE(RESERVED22), + PERIPHC_ACTMON, + + /* 24 */ + NONE(RESERVED24), + NONE(RESERVED25), + NONE(RESERVED26), + NONE(RESERVED27), + PERIPHC_SATA, + PERIPHC_HDA, + NONE(RESERVED30), + NONE(RESERVED31), + + /* W word: 31:0 */ + NONE(HDA2HDMICODEC), + NONE(SATACOLD), + NONE(RESERVED0_PCIERX0), + NONE(RESERVED1_PCIERX1), + NONE(RESERVED2_PCIERX2), + NONE(RESERVED3_PCIERX3), + NONE(RESERVED4_PCIERX4), + NONE(RESERVED5_PCIERX5), + + /* 40 */ + NONE(CEC), + NONE(RESERVED6_PCIE2), + NONE(RESERVED7_EMC), + NONE(RESERVED8_HDMI), + NONE(RESERVED9_SATA), + NONE(RESERVED10_MIPI), + NONE(EX_RESERVED46), + NONE(EX_RESERVED47), };
/* @@ -458,7 +491,6 @@ int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, data = readl(&pll->pll_misc); *cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT; *lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT; - return 0; }
@@ -491,37 +523,6 @@ unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US; }
-/* return 1 if a peripheral ID is in range and valid */ -static int clock_periph_id_isvalid(enum periph_id id) -{ - if (id < PERIPH_ID_FIRST || id >= PERIPH_ID_COUNT) - printf("Peripheral id %d out of range\n", id); - else { - switch (id) { - case PERIPH_ID_RESERVED1: - case PERIPH_ID_RESERVED2: - case PERIPH_ID_RESERVED30: - case PERIPH_ID_RESERVED35: - case PERIPH_ID_RESERVED56: - case PERIPH_ID_RESERVED74: - case PERIPH_ID_RESERVED76: - case PERIPH_ID_RESERVED77: - case PERIPH_ID_RESERVED78: - case PERIPH_ID_RESERVED79: - case PERIPH_ID_RESERVED80: - case PERIPH_ID_RESERVED81: - case PERIPH_ID_RESERVED82: - case PERIPH_ID_RESERVED83: - case PERIPH_ID_RESERVED91: - printf("Peripheral id %d is reserved\n", id); - break; - default: - return 1; - } - } - return 0; -} - /* Returns a pointer to the clock source register for a peripheral */ static u32 *get_periph_source_reg(enum periph_id periph_id) { @@ -529,10 +530,18 @@ static u32 *get_periph_source_reg(enum periph_id periph_id) (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; enum periphc_internal_id internal_id;
- assert(clock_periph_id_isvalid(periph_id)); + /* Coresight is a special case */ + if (periph_id == PERIPH_ID_CSI) + return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; + + assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); internal_id = periph_id_to_internal_id[periph_id]; assert(internal_id != -1); - return &clkrst->crc_clk_src[internal_id]; + if (internal_id >= PERIPHC_VW_FIRST) { + internal_id -= PERIPHC_VW_FIRST; + return &clkrst->crc_clk_src_vw[internal_id]; + } else + return &clkrst->crc_clk_src[internal_id]; }
void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source, @@ -614,34 +623,6 @@ unsigned long clock_get_periph_rate(enum periph_id periph_id, (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT); }
-int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate) -{ - struct clk_pll *pll = get_pll(clkid); - int data = 0, div = 0, offset = 0; - - if (!clock_id_is_pll(clkid)) - return -1; - - if (pllout + 1 > pll_num_clkouts[clkid]) - return -1; - - div = clk_get_divider(8, pll_rate[clkid], rate); - - if (div < 0) - return -1; - - /* out2 and out4 are in the high part of the register */ - if (pllout == PLL_OUT2 || pllout == PLL_OUT4) - offset = 16; - - data = (div << PLL_OUT_RATIO_SHIFT) | - PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN; - clrsetbits_le32(&pll->pll_out[pllout >> 1], - PLL_OUT_RATIO_MASK << offset, data << offset); - - return 0; -} - /** * Find the best available 7.1 format divisor given a parent clock rate and * required child clock rate. This function assumes that a second-stage @@ -710,33 +691,12 @@ static int get_periph_clock_source(enum periph_id periph_id, type = clock_periph_type[internal_id]; assert(clock_type_id_isvalid(type));
- /* - * Special cases here for the clock with a 4-bit source mux and I2C - * with its 16-bit divisor - */ - if (type == CLOCK_TYPE_PCXTS) - *mux_bits = 4; - else - *mux_bits = 2; - if (type == CLOCK_TYPE_PCMT16) - *divider_bits = 16; - else - *divider_bits = 8; + *mux_bits = clock_source[type][CLOCK_MAX_MUX];
for (mux = 0; mux < CLOCK_MAX_MUX; mux++) if (clock_source[type][mux] == parent) return mux;
- /* - * Not found: it might be looking for the 'S' in CLOCK_TYPE_PCXTS - * which is not in our table. If not, then they are asking for a - * source which this peripheral can't access through its mux. - */ - assert(type == CLOCK_TYPE_PCXTS); - assert(parent == CLOCK_ID_SFROM32KHZ); - if (type == CLOCK_TYPE_PCXTS && parent == CLOCK_ID_SFROM32KHZ) - return 4; /* mux value for this clock */ - /* if we get here, either us or the caller has made a mistake */ printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, parent); @@ -780,8 +740,8 @@ unsigned clock_adjust_periph_pll_div(enum periph_id periph_id, enum clock_id parent, unsigned rate, int *extra_div) { unsigned effective_rate; - int mux_bits, divider_bits, source; - int divider; + int mux_bits, source; + int divider, divider_bits = 0;
/* work out the source clock and set it */ source = get_periph_clock_source(periph_id, parent, &mux_bits, @@ -829,11 +789,15 @@ void clock_set_enable(enum periph_id periph_id, int enable) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; + u32 *clk; u32 reg;
/* Enable/disable the clock to this peripheral */ assert(clock_periph_id_isvalid(periph_id)); + if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) + clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; + else + clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; reg = readl(clk); if (enable) reg |= PERIPH_MASK(periph_id); @@ -856,11 +820,15 @@ void reset_set_enable(enum periph_id periph_id, int enable) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; + u32 *reset; u32 reg;
/* Enable/disable reset to the peripheral */ assert(clock_periph_id_isvalid(periph_id)); + if (periph_id < PERIPH_ID_VW_FIRST) + reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; + else + reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; reg = readl(reset); if (enable) reg |= PERIPH_MASK(periph_id); @@ -887,8 +855,8 @@ void reset_cmplx_set_enable(int cpu, int which, int reset) (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; u32 mask;
- /* Form the mask, which depends on the cpu chosen. Tegra20 has 2 */ - assert(cpu >= 0 && cpu < 2); + /* Form the mask, which depends on the cpu chosen. Tegra3 has 4 */ + assert(cpu >= 0 && cpu < 4); mask = which << cpu;
/* either enable or disable those reset for that CPU */ @@ -1082,15 +1050,13 @@ int clock_verify(void) void clock_early_init(void) { /* - * PLLP output frequency set to 216MHz - * PLLC output frequency set to 600Mhz - * - * TODO: Can we calculate these values instead of hard-coding? + * PLLP output frequency set to 216Mh + * PLLC output frequency set to 228Mhz */ switch (clock_get_osc_freq()) { case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ clock_set_rate(CLOCK_ID_PERIPH, 432, 12, 1, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 456, 12, 1, 8); break;
case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ diff --git a/arch/arm/cpu/tegra30-common/funcmux.c b/arch/arm/cpu/tegra30-common/funcmux.c new file mode 100644 index 0000000..e24c57e --- /dev/null +++ b/arch/arm/cpu/tegra30-common/funcmux.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010-2012, 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/. + */ + +/* Tegra30 high-level function multiplexing */ + +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/arch/funcmux.h> +#include <asm/arch/pinmux.h> + +int funcmux_select(enum periph_id id, int config) +{ + int bad_config = config != FUNCMUX_DEFAULT; + + switch (id) { + case PERIPH_ID_UART1: + switch (config) { + case FUNCMUX_UART1_ULPI: + pinmux_set_func(PINGRP_ULPI_DATA0, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_ULPI_DATA1, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_ULPI_DATA2, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_ULPI_DATA3, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PINGRP_ULPI_DATA0); + pinmux_tristate_disable(PINGRP_ULPI_DATA1); + pinmux_tristate_disable(PINGRP_ULPI_DATA2); + pinmux_tristate_disable(PINGRP_ULPI_DATA3); + break; + } + break; + + /* Add other periph IDs here as needed */ + + default: + debug("%s: invalid periph_id %d", __func__, id); + return -1; + } + + if (bad_config) { + debug("%s: invalid config %d for periph_id %d", __func__, + config, id); + return -1; + } + return 0; +} diff --git a/arch/arm/cpu/tegra30-common/pinmux.c b/arch/arm/cpu/tegra30-common/pinmux.c new file mode 100644 index 0000000..c04f4ba --- /dev/null +++ b/arch/arm/cpu/tegra30-common/pinmux.c @@ -0,0 +1,501 @@ +/* + * Copyright (c) 2010-2012, 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/. + */ + +/* Tegra30 pin multiplexing functions */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/tegra.h> +#include <asm/arch/pinmux.h> + +struct tegra_pingroup_desc { + const char *name; + enum pmux_func funcs[4]; + enum pmux_func func_safe; + enum pmux_vddio vddio; + enum pmux_pin_io io; +}; + +#define PMUX_MUXCTL_SHIFT 0 +#define PMUX_PULL_SHIFT 2 +#define PMUX_TRISTATE_SHIFT 4 +#define PMUX_TRISTATE_MASK (1 << PMUX_TRISTATE_SHIFT) +#define PMUX_IO_SHIFT 5 +#define PMUX_OD_SHIFT 6 +#define PMUX_LOCK_SHIFT 7 +#define PMUX_IO_RESET_SHIFT 8 + +/* Convenient macro for defining pin group properties */ +#define PIN(pg_name, vdd, f0, f1, f2, f3, iod) \ + { \ + .vddio = PMUX_VDDIO_ ## vdd, \ + .funcs = { \ + PMUX_FUNC_ ## f0, \ + PMUX_FUNC_ ## f1, \ + PMUX_FUNC_ ## f2, \ + PMUX_FUNC_ ## f3, \ + }, \ + .func_safe = PMUX_FUNC_RSVD, \ + .io = PMUX_PIN_ ## iod, \ + } + +/* Input and output pins */ +#define PINI(pg_name, vdd, f0, f1, f2, f3) \ + PIN(pg_name, vdd, f0, f1, f2, f3, INPUT) +#define PINO(pg_name, vdd, f0, f1, f2, f3) \ + PIN(pg_name, vdd, f0, f1, f2, f3, OUTPUT) + +const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = { + /* NAME VDD f0 f1 f2 f3 fSafe io */ + PINI(ULPI_DATA0, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA1, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA2, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA3, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA4, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_DATA5, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_DATA6, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_DATA7, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_CLK, BB, SPI1, RSVD, UARTD, ULPI), + PINI(ULPI_DIR, BB, SPI1, RSVD, UARTD, ULPI), + PINI(ULPI_NXT, BB, SPI1, RSVD, UARTD, ULPI), + PINI(ULPI_STP, BB, SPI1, RSVD, UARTD, ULPI), + PINI(DAP3_FS, BB, I2S2, RSVD1, DISPA, DISPB), + PINI(DAP3_DIN, BB, I2S2, RSVD1, DISPA, DISPB), + PINI(DAP3_DOUT, BB, I2S2, RSVD1, DISPA, DISPB), + PINI(DAP3_SCLK, BB, I2S2, RSVD1, DISPA, DISPB), + PINI(GPIO_PV0, BB, RSVD, RSVD, RSVD, RSVD), + PINI(GPIO_PV1, BB, RSVD, RSVD, RSVD, RSVD), + PINI(SDMMC1_CLK, SDMMC1, SDMMC1, RSVD1, RSVD2, BAD), + PINI(SDMMC1_CMD, SDMMC1, SDMMC1, RSVD1, RSVD2, BAD), + PINI(SDMMC1_DAT3, SDMMC1, SDMMC1, RSVD1, UARTE, BAD), + PINI(SDMMC1_DAT2, SDMMC1, SDMMC1, RSVD1, UARTE, BAD), + PINI(SDMMC1_DAT1, SDMMC1, SDMMC1, RSVD1, UARTE, BAD), + PINI(SDMMC1_DAT0, SDMMC1, SDMMC1, RSVD1, UARTE, BAD), + PINI(GPIO_PV2, SDMMC1, OWR, RSVD1, RSVD2, RSVD3), + PINI(GPIO_PV3, SDMMC1, BAD, RSVD1, RSVD2, RSVD3), + PINI(CLK2_OUT, SDMMC1, EXTPERIPH2, RSVD1, RSVD2, RSVD3), + PINI(CLK2_REQ, SDMMC1, DAP, RSVD1, RSVD2, RSVD3), + PINO(LCD_PWR1, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_PWR2, LCD, DISPA, DISPB, SPI5, BAD), + PINO(LCD_SDIN, LCD, DISPA, DISPB, SPI5, RSVD), + PINO(LCD_SDOUT, LCD, DISPA, DISPB, SPI5, BAD), + PINO(LCD_WR_N, LCD, DISPA, DISPB, SPI5, BAD), + PINO(LCD_CS0_N, LCD, DISPA, DISPB, SPI5, RSVD), + PINO(LCD_DC0, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_SCK, LCD, DISPA, DISPB, SPI5, BAD), + PINO(LCD_PWR0, LCD, DISPA, DISPB, SPI5, BAD), + PINO(LCD_PCLK, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_DE, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_HSYNC, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_VSYNC, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D0, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D1, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D2, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D3, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D4, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D5, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D6, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D7, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D8, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D9, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D10, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D11, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D12, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D13, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D14, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D15, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D16, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D17, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D18, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D19, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D20, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D21, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D22, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_D23, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_CS1_N, LCD, DISPA, DISPB, SPI5, RSVD2), + PINO(LCD_M1, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINO(LCD_DC1, LCD, DISPA, DISPB, RSVD1, RSVD2), + PINI(HDMI_INT, LCD, RSVD, RSVD, RSVD, RSVD), + PINI(DDC_SCL, LCD, I2C4, RSVD1, RSVD2, RSVD3), + PINI(DDC_SDA, LCD, I2C4, RSVD1, RSVD2, RSVD3), + PINI(CRT_HSYNC, LCD, CRT, RSVD1, RSVD2, RSVD3), + PINI(CRT_VSYNC, LCD, CRT, RSVD1, RSVD2, RSVD3), + PINI(VI_D0, VI, BAD, RSVD1, VI, RSVD2), + PINI(VI_D1, VI, BAD, SDMMC2, VI, RSVD1), + PINI(VI_D2, VI, BAD, SDMMC2, VI, RSVD1), + PINI(VI_D3, VI, BAD, SDMMC2, VI, RSVD1), + PINI(VI_D4, VI, BAD, SDMMC2, VI, RSVD1), + PINI(VI_D5, VI, BAD, SDMMC2, VI, RSVD1), + PINI(VI_D6, VI, BAD, SDMMC2, VI, RSVD1), + PINI(VI_D7, VI, BAD, SDMMC2, VI, RSVD1), + PINI(VI_D8, VI, BAD, SDMMC2, VI, RSVD1), + PINI(VI_D9, VI, BAD, SDMMC2, VI, RSVD1), + PINI(VI_D10, VI, BAD, RSVD1, VI, RSVD2), + PINI(VI_D11, VI, BAD, RSVD1, VI, RSVD2), + PINI(VI_PCLK, VI, RSVD1, SDMMC2, VI, RSVD2), + PINI(VI_MCLK, VI, VI, BAD, BAD, BAD), + PINI(VI_VSYNC, VI, BAD, RSVD1, VI, RSVD2), + PINI(VI_HSYNC, VI, BAD, RSVD1, VI, RSVD2), + PINI(UART2_RXD, UART, IRDA, SPDIF, UARTA, SPI4), + PINI(UART2_TXD, UART, IRDA, SPDIF, UARTA, SPI4), + PINI(UART2_RTS_N, UART, UARTA, UARTB, GMI, SPI4), + PINI(UART2_CTS_N, UART, UARTA, UARTB, GMI, SPI4), + PINI(UART3_TXD, UART, UARTC, RSVD1, GMI, RSVD2), + PINI(UART3_RXD, UART, UARTC, RSVD1, GMI, RSVD2), + PINI(UART3_CTS_N, UART, UARTC, RSVD1, GMI, RSVD2), + PINI(UART3_RTS_N, UART, UARTC, PWM0, GMI, RSVD2), + PINI(GPIO_PU0, UART, OWR, UARTA, GMI, RSVD1), + PINI(GPIO_PU1, UART, RSVD1, UARTA, GMI, RSVD2), + PINI(GPIO_PU2, UART, RSVD1, UARTA, GMI, RSVD2), + PINI(GPIO_PU3, UART, PWM0, UARTA, GMI, RSVD1), + PINI(GPIO_PU4, UART, PWM1, UARTA, GMI, RSVD1), + PINI(GPIO_PU5, UART, PWM2, UARTA, GMI, RSVD1), + PINI(GPIO_PU6, UART, PWM3, UARTA, GMI, RSVD1), + PINI(GEN1_I2C_SDA, UART, I2C1, RSVD1, RSVD2, RSVD3), + PINI(GEN1_I2C_SCL, UART, I2C1, RSVD1, RSVD2, RSVD3), + PINI(DAP4_FS, UART, I2S3, RSVD1, GMI, RSVD2), + PINI(DAP4_DIN, UART, I2S3, RSVD1, GMI, RSVD2), + PINI(DAP4_DOUT, UART, I2S3, RSVD1, GMI, RSVD2), + PINI(DAP4_SCLK, UART, I2S3, RSVD1, GMI, RSVD2), + PINI(CLK3_OUT, UART, EXTPERIPH3, RSVD1, RSVD2, RSVD3), + PINI(CLK3_REQ, UART, DEV3, RSVD1, RSVD2, RSVD3), + PINI(GMI_WP_N, GMI, RSVD1, NAND, GMI, GMI_ALT), + PINI(GMI_IORDY, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_WAIT, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_ADV_N, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_CLK, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_CS0_N, GMI, RSVD1, NAND, GMI, BAD), + PINI(GMI_CS1_N, GMI, RSVD1, NAND, GMI, DTV), + PINI(GMI_CS2_N, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_CS3_N, GMI, RSVD1, NAND, GMI, GMI_ALT), + PINI(GMI_CS4_N, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_CS6_N, GMI, NAND, NAND_ALT, GMI, SATA), + PINI(GMI_CS7_N, GMI, NAND, NAND_ALT, GMI, GMI_ALT), + PINI(GMI_AD0, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD1, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD2, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD3, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD4, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD5, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD6, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD7, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD8, GMI, PWM0, NAND, GMI, RSVD2), + PINI(GMI_AD9, GMI, PWM1, NAND, GMI, RSVD2), + PINI(GMI_AD10, GMI, PWM2, NAND, GMI, RSVD2), + PINI(GMI_AD11, GMI, PWM3, NAND, GMI, RSVD2), + PINI(GMI_AD12, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD13, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD14, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_AD15, GMI, RSVD1, NAND, GMI, RSVD2), + PINI(GMI_A16, GMI, UARTD, SPI4, GMI, GMI_ALT), + PINI(GMI_A17, GMI, UARTD, SPI4, GMI, BAD), + PINI(GMI_A18, GMI, UARTD, SPI4, GMI, BAD), + PINI(GMI_A19, GMI, UARTD, SPI4, GMI, RSVD3), + PINI(GMI_WR_N, GMI, RSVD1, NAND, GMI, RSVD3), + PINI(GMI_OE_N, GMI, RSVD1, NAND, GMI, RSVD3), + PINI(GMI_DQS, GMI, RSVD1, NAND, GMI, RSVD3), + PINI(GMI_RST_N, GMI, NAND, NAND_ALT, GMI, RSVD3), + PINI(GEN2_I2C_SCL, GMI, I2C2, BAD, GMI, RSVD3), + PINI(GEN2_I2C_SDA, GMI, I2C2, BAD, GMI, RSVD3), + PINI(SDMMC4_CLK, SDMMC4, BAD, NAND, GMI, SDMMC4), + PINI(SDMMC4_CMD, SDMMC4, I2C3, NAND, GMI, SDMMC4), + PINI(SDMMC4_DAT0, SDMMC4, UARTE, SPI3, GMI, SDMMC4), + PINI(SDMMC4_DAT1, SDMMC4, UARTE, SPI3, GMI, SDMMC4), + PINI(SDMMC4_DAT2, SDMMC4, UARTE, SPI3, GMI, SDMMC4), + PINI(SDMMC4_DAT3, SDMMC4, UARTE, SPI3, GMI, SDMMC4), + PINI(SDMMC4_DAT4, SDMMC4, I2C3, I2S4, GMI, SDMMC4), + PINI(SDMMC4_DAT5, SDMMC4, VGP3, I2S4, GMI, SDMMC4), + PINI(SDMMC4_DAT6, SDMMC4, VGP4, I2S4, GMI, SDMMC4), + PINI(SDMMC4_DAT7, SDMMC4, VGP5, I2S4, GMI, SDMMC4), + PINI(SDMMC4_RST_N, SDMMC4, VGP6, RSVD1, RSVD2, POPSDMMC4), + PINI(CAM_MCLK, CAM, VI, BAD, VI_ALT2, POPSDMMC4), + PINI(GPIO_PCC1, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4), + PINI(GPIO_PBB0, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4), + PINI(CAM_I2C_SCL, CAM, BAD, I2C3, RSVD2, POPSDMMC4), + PINI(CAM_I2C_SDA, CAM, BAD, I2C3, RSVD2, POPSDMMC4), + PINI(GPIO_PBB3, CAM, VGP3, DISPA, DISPB, POPSDMMC4), + PINI(GPIO_PBB4, CAM, VGP4, DISPA, DISPB, POPSDMMC4), + PINI(GPIO_PBB5, CAM, VGP5, DISPA, DISPB, POPSDMMC4), + PINI(GPIO_PBB6, CAM, VGP6, DISPA, DISPB, POPSDMMC4), + PINI(GPIO_PBB7, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4), + PINI(GPIO_PCC2, CAM, I2S4, RSVD1, RSVD2, RSVD3), + PINI(JTAG_RTCK, SYS, RTCK, RSVD1, RSVD2, RSVD3), + PINI(PWR_I2C_SCL, SYS, I2CPWR, RSVD1, RSVD2, RSVD3), + PINI(PWR_I2C_SDA, SYS, I2CPWR, RSVD1, RSVD2, RSVD3), + PINI(KB_ROW0, SYS, KBC, BAD, RSVD2, RSVD3), + PINI(KB_ROW1, SYS, KBC, BAD, RSVD2, RSVD3), + PINI(KB_ROW2, SYS, KBC, BAD, RSVD2, RSVD3), + PINI(KB_ROW3, SYS, KBC, BAD, RSVD2, BAD), + PINI(KB_ROW4, SYS, KBC, BAD, TRACE, RSVD3), + PINI(KB_ROW5, SYS, KBC, BAD, TRACE, OWR), + PINI(KB_ROW6, SYS, KBC, BAD, SDMMC2, BAD), + PINI(KB_ROW7, SYS, KBC, BAD, SDMMC2, BAD), + PINI(KB_ROW8, SYS, KBC, BAD, SDMMC2, BAD), + PINI(KB_ROW9, SYS, KBC, BAD, SDMMC2, BAD), + PINI(KB_ROW10, SYS, KBC, BAD, SDMMC2, BAD), + PINI(KB_ROW11, SYS, KBC, BAD, SDMMC2, BAD), + PINI(KB_ROW12, SYS, KBC, BAD, SDMMC2, BAD), + PINI(KB_ROW13, SYS, KBC, BAD, SDMMC2, BAD), + PINI(KB_ROW14, SYS, KBC, BAD, SDMMC2, BAD), + PINI(KB_ROW15, SYS, KBC, BAD, SDMMC2, BAD), + PINI(KB_COL0, SYS, KBC, BAD, TRACE, BAD), + PINI(KB_COL1, SYS, KBC, BAD, TRACE, BAD), + PINI(KB_COL2, SYS, KBC, BAD, TRACE, RSVD), + PINI(KB_COL3, SYS, KBC, BAD, TRACE, RSVD), + PINI(KB_COL4, SYS, KBC, BAD, TRACE, RSVD), + PINI(KB_COL5, SYS, KBC, BAD, TRACE, RSVD), + PINI(KB_COL6, SYS, KBC, BAD, TRACE, BAD), + PINI(KB_COL7, SYS, KBC, BAD, TRACE, BAD), + PINI(CLK_32K_OUT, SYS, BLINK, RSVD1, RSVD2, RSVD3), + PINI(SYS_CLK_REQ, SYS, SYSCLK, RSVD1, RSVD2, RSVD3), + PINI(CORE_PWR_REQ, SYS, RSVD, RSVD, RSVD, RSVD), + PINI(CPU_PWR_REQ, SYS, RSVD, RSVD, RSVD, RSVD), + PINI(PWR_INT_N, SYS, RSVD, RSVD, RSVD, RSVD), + PINI(CLK_32K_IN, SYS, RSVD, RSVD, RSVD, RSVD), + PINI(OWR, SYS, OWR, RSVD, RSVD, RSVD), + PINI(DAP1_FS, AUDIO, I2S0, HDA, GMI, SDMMC2), + PINI(DAP1_DIN, AUDIO, I2S0, HDA, GMI, SDMMC2), + PINI(DAP1_DOUT, AUDIO, I2S0, HDA, GMI, SDMMC2), + PINI(DAP1_SCLK, AUDIO, I2S0, HDA, GMI, SDMMC2), + PINI(CLK1_REQ, AUDIO, DAP, HDA, RSVD2, RSVD3), + PINI(CLK1_OUT, AUDIO, EXTPERIPH1, RSVD1, RSVD2, RSVD3), + PINI(SPDIF_IN, AUDIO, SPDIF, HDA, BAD, DAPSDMMC2), + PINI(SPDIF_OUT, AUDIO, SPDIF, RSVD1, BAD, DAPSDMMC2), + PINI(DAP2_FS, AUDIO, I2S1, HDA, RSVD2, GMI), + PINI(DAP2_DIN, AUDIO, I2S1, HDA, RSVD2, GMI), + PINI(DAP2_DOUT, AUDIO, I2S1, HDA, RSVD2, GMI), + PINI(DAP2_SCLK, AUDIO, I2S1, HDA, RSVD2, GMI), + PINI(SPI2_MOSI, AUDIO, SPI6, SPI2, BAD, GMI), + PINI(SPI2_MISO, AUDIO, SPI6, SPI2, BAD, GMI), + PINI(SPI2_CS0_N, AUDIO, SPI6, SPI2, BAD, GMI), + PINI(SPI2_SCK, AUDIO, SPI6, SPI2, BAD, GMI), + PINI(SPI1_MOSI, AUDIO, SPI2, SPI1, BAD, GMI), + PINI(SPI1_SCK, AUDIO, SPI2, SPI1, BAD, GMI), + PINI(SPI1_CS0_N, AUDIO, SPI2, SPI1, BAD, GMI), + PINI(SPI1_MISO, AUDIO, BAD, SPI1, BAD, RSVD3), + PINI(SPI2_CS1_N, AUDIO, BAD, SPI2, BAD, BAD), + PINI(SPI2_CS2_N, AUDIO, BAD, SPI2, BAD, BAD), + PINI(SDMMC3_CLK, SDMMC3, UARTA, PWM2, SDMMC3, BAD), + PINI(SDMMC3_CMD, SDMMC3, UARTA, PWM3, SDMMC3, BAD), + PINI(SDMMC3_DAT0, SDMMC3, RSVD0, RSVD1, SDMMC3, BAD), + PINI(SDMMC3_DAT1, SDMMC3, RSVD0, RSVD1, SDMMC3, BAD), + PINI(SDMMC3_DAT2, SDMMC3, RSVD0, PWM1, SDMMC3, BAD), + PINI(SDMMC3_DAT3, SDMMC3, RSVD0, PWM0, SDMMC3, BAD), + PINI(SDMMC3_DAT4, SDMMC3, PWM1, BAD, SDMMC3, BAD), + PINI(SDMMC3_DAT5, SDMMC3, PWM0, BAD, SDMMC3, BAD), + PINI(SDMMC3_DAT6, SDMMC3, SPDIF, BAD, SDMMC3, BAD), + PINI(SDMMC3_DAT7, SDMMC3, SPDIF, BAD, SDMMC3, BAD), + PINI(PEX_L0_PRSNT_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3), + PINI(PEX_L0_RST_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3), + PINI(PEX_L0_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3), + PINI(PEX_WAKE_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3), + PINI(PEX_L1_PRSNT_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3), + PINI(PEX_L1_RST_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3), + PINI(PEX_L1_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3), + PINI(PEX_L2_PRSNT_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3), + PINI(PEX_L2_RST_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3), + PINI(PEX_L2_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3), + PINI(HDMI_CEC, SYS, CEC, RSVD1, RSVD2, RSVD3), +}; + +void pinmux_set_tristate(enum pmux_pingrp pin, int enable) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *tri = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin */ + assert(pmux_pingrp_isvalid(pin)); + + reg = readl(tri); + if (enable) + reg |= PMUX_TRISTATE_MASK; + else + reg &= ~PMUX_TRISTATE_MASK; + writel(reg, tri); +} + +void pinmux_tristate_enable(enum pmux_pingrp pin) +{ + pinmux_set_tristate(pin, 1); +} + +void pinmux_tristate_disable(enum pmux_pingrp pin) +{ + pinmux_set_tristate(pin, 0); +} + +void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pull = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and pupd */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_pupd_isvalid(pupd)); + + reg = readl(pull); + reg &= ~(0x3 << PMUX_PULL_SHIFT); + reg |= (pupd << PMUX_PULL_SHIFT); + writel(reg, pull); +} + +void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *muxctl = &pmt->pmt_ctl[pin]; + int i, mux = -1; + u32 reg; + + /* Error check on pin and func */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_func_isvalid(func)); + + /* Handle special values */ + if (func == PMUX_FUNC_SAFE) + func = tegra_soc_pingroups[pin].func_safe; + + if (func & PMUX_FUNC_RSVD) { + mux = func & 0x3; + } else { + /* Search for the appropriate function */ + for (i = 0; i < 4; i++) { + if (tegra_soc_pingroups[pin].funcs[i] == func) { + mux = i; + break; + } + } + } + assert(mux != -1); + + reg = readl(muxctl); + reg &= ~(0x3 << PMUX_MUXCTL_SHIFT); + reg |= (mux << PMUX_MUXCTL_SHIFT); + writel(reg, muxctl); + +} + +void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_io = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and io */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_io_isvalid(io)); + + reg = readl(pin_io); + reg &= ~(0x1 << PMUX_IO_SHIFT); + reg |= (io & 0x1) << PMUX_IO_SHIFT; + writel(reg, pin_io); +} + +static int pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_lock = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and lock */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_lock_isvalid(lock)); + + if (lock == PMUX_PIN_LOCK_DEFAULT) + return 0; + + reg = readl(pin_lock); + reg &= ~(0x1 << PMUX_LOCK_SHIFT); + if (lock == PMUX_PIN_LOCK_ENABLE) + reg |= (0x1 << PMUX_LOCK_SHIFT); + writel(reg, pin_lock); + + return 0; +} + +static int pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_od = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and od */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_od_isvalid(od)); + + if (od == PMUX_PIN_OD_DEFAULT) + return 0; + + reg = readl(pin_od); + reg &= ~(0x1 << PMUX_OD_SHIFT); + if (od == PMUX_PIN_OD_ENABLE) + reg |= (0x1 << PMUX_OD_SHIFT); + writel(reg, pin_od); + + return 0; +} + +static int pinmux_set_ioreset(enum pmux_pingrp pin, + enum pmux_pin_ioreset ioreset) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_ioreset = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and ioreset */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_ioreset_isvalid(ioreset)); + + if (ioreset == PMUX_PIN_IO_RESET_DEFAULT) + return 0; + + reg = readl(pin_ioreset); + reg &= ~(0x1 << PMUX_IO_RESET_SHIFT); + if (ioreset == PMUX_PIN_IO_RESET_ENABLE) + reg |= (0x1 << PMUX_IO_RESET_SHIFT); + writel(reg, pin_ioreset); + + return 0; +} + +void pinmux_config_pingroup(struct pingroup_config *config) +{ + enum pmux_pingrp pin = config->pingroup; + + pinmux_set_func(pin, config->func); + pinmux_set_pullupdown(pin, config->pull); + pinmux_set_tristate(pin, config->tristate); + pinmux_set_io(pin, config->io); + pinmux_set_lock(pin, config->lock); + pinmux_set_od(pin, config->od); + pinmux_set_ioreset(pin, config->ioreset); +} + +void pinmux_config_table(struct pingroup_config *config, int len) +{ + int i; + + for (i = 0; i < len; i++) + pinmux_config_pingroup(&config[i]); +} diff --git a/arch/arm/include/asm/arch-tegra/ap.h b/arch/arm/include/asm/arch-tegra/ap.h index 70d94c5..c41eeb9 100644 --- a/arch/arm/include/asm/arch-tegra/ap.h +++ b/arch/arm/include/asm/arch-tegra/ap.h @@ -23,7 +23,7 @@ #include <asm/types.h>
/* Stabilization delays, in usec */ -#define PLL_STABILIZATION_DELAY (300) +#define PLL_STABILIZATION_DELAY (300) #define IO_STABILIZATION_DELAY (1000)
#define NVBL_PLLP_KHZ (216000) @@ -33,57 +33,19 @@ #define SUPER_CCLK_DIVIDER 0x80000000
/* Calculate clock fractional divider value from ref and target frequencies */ -#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / FREQ) - 2) +#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / FREQ) - 2)
/* Calculate clock frequency value from reference and clock divider value */ -#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2)) +#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2))
/* AVP/CPU ID */ #define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */ -#define PG_UP_TAG_0 0x0 +#define PG_UP_TAG_0 0x0
#define CORESIGHT_UNLOCK 0xC5ACCE55;
-/* AP20-Specific Base Addresses */ - -/* AP20 Base physical address of SDRAM. */ -#define AP20_BASE_PA_SDRAM 0x00000000 -/* AP20 Base physical address of internal SRAM. */ -#define AP20_BASE_PA_SRAM 0x40000000 -/* AP20 Size of internal SRAM (256KB). */ -#define AP20_BASE_PA_SRAM_SIZE 0x00040000 -/* AP20 Base physical address of flash. */ -#define AP20_BASE_PA_NOR_FLASH 0xD0000000 -/* AP20 Base physical address of boot information table. */ -#define AP20_BASE_PA_BOOT_INFO AP20_BASE_PA_SRAM - -/* - * Super-temporary stacks for EXTREMELY early startup. The values chosen for - * these addresses must be valid on ALL SOCs because this value is used before - * we are able to differentiate between the SOC types. - * - * NOTE: The since CPU's stack will eventually be moved from IRAM to SDRAM, its - * stack is placed below the AVP stack. Once the CPU stack has been moved, - * the AVP is free to use the IRAM the CPU stack previously occupied if - * it should need to do so. - * - * NOTE: In multi-processor CPU complex configurations, each processor will have - * its own stack of size CPU_EARLY_BOOT_STACK_SIZE. CPU 0 will have a - * limit of CPU_EARLY_BOOT_STACK_LIMIT. Each successive CPU will have a - * stack limit that is CPU_EARLY_BOOT_STACK_SIZE less then the previous - * CPU. - */ - -/* Common AVP early boot stack limit */ -#define AVP_EARLY_BOOT_STACK_LIMIT \ - (AP20_BASE_PA_SRAM + (AP20_BASE_PA_SRAM_SIZE/2)) -/* Common AVP early boot stack size */ -#define AVP_EARLY_BOOT_STACK_SIZE 0x1000 -/* Common CPU early boot stack limit */ -#define CPU_EARLY_BOOT_STACK_LIMIT \ - (AVP_EARLY_BOOT_STACK_LIMIT - AVP_EARLY_BOOT_STACK_SIZE) -/* Common CPU early boot stack size */ -#define CPU_EARLY_BOOT_STACK_SIZE 0x1000 +/* AP base physical address of internal SRAM */ +#define NV_PA_BASE_SRAM 0x40000000
#define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100) #define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0)

On 10/02/2012 04:45 PM, Tom Warren wrote:
These files are used by both SPL and main U-Boot. Also made minor changes to shared Tegra code to support T30 differences.
diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c
@@ -58,6 +62,20 @@ int tegra_get_chip_type(void) return TEGRA_SOC_T25; } break;
- case CHIPID_TEGRA30:
switch (tegra_sku_id) {
case SKU_ID_T30:
/*
* T30 has two options. We will return TEGRA_SOC_T30
* until we have the fdt set up when it may change to
* TEGRA_SOC_T30_408MHZ depending on the PLLP freq.
*/
if (clock_get_rate(CLOCK_ID_PERIPH) == 408000000)
return TEGRA_SOC_T30_408MHZ;
else
return TEGRA_SOC_T30;
Hmmm. I wonder why this doesn't return just the actual chip type; isn't the different in PLL_P rates a SW option and not a facet of the HW? The whole TEGRA_SOC_T30_408MHZ thing seems strange to me.
diff --git a/arch/arm/cpu/tegra-common/board.c b/arch/arm/cpu/tegra-common/board.c
@@ -59,9 +59,12 @@ unsigned int query_sdram_size(void) case 1: return 0x10000000; /* 256 MB */ case 2:
- default: return 0x20000000; /* 512 MB */
- case 3:
- case 4:
return 0x40000000; /* 1GB */
- case 8:
return 0x7ff00000; /* 2GB - 1MB */
- default: return 0x40000000; /* 1GB */ }
}
I think we should be a little more explicit about the Tegra20/Tegra30 differences here. At least for case 0, there's a difference in what this field means for the two chips.
Value Tegra20 Tegra30 0 512 256 1 256 256 2 512 512 3 1024 768 4 undef 1024 5 undef undef 6 undef undef 7 undef undef 8 n/a 2048-1
At least the Toshiba AC100 uses value "0" in this field and has 512MB not 1GB of RAM.
I also note that for Tegra30, this field is bits 31:28, whereas for Tegra20 it's bits 30:28; we aren't masking off the top bit as we should in the current code. Again, the Toshiba AC100 appears to set this extra top bit, and only succeeds in getting 512M as the result of this function because of the default case.
diff --git a/arch/arm/cpu/tegra30-common/pinmux.c b/arch/arm/cpu/tegra30-common/pinmux.c
Hmmm. The header file this relies on doesn't exist yet. But perhaps this is OK since there's no boards.cfg entry for Tegra30 yet.
+const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
- /* NAME VDD f0 f1 f2 f3 fSafe io */
"fSafe io" should be deleted; those columns don't exist in the table.
I compared this table to that in the upstream kernel, which I spent a lot of time on correlating with the various documentation sources and our downstream kernel. Some changes should be made:
- PINI(DAP3_FS, BB, I2S2, RSVD1, DISPA, DISPB),
- PINI(DAP3_DIN, BB, I2S2, RSVD1, DISPA, DISPB),
- PINI(DAP3_DOUT, BB, I2S2, RSVD1, DISPA, DISPB),
- PINI(DAP3_SCLK, BB, I2S2, RSVD1, DISPA, DISPB),
In the kernel at least, the RSVD values are only used in particular slots, i.e. RSVD1 always yields function 0, RSVD2==func1, RSVD3==func2, RSVD4==func3. That way, when representing the "safe" value, one can use RSVDn to guarantee to get func(n-1). I suspect, it'd be a good idea for U-Boot to adopt the same policy. So, s/RSVD1/RSVD2/ above, and make similar changes throughout this table.
- PINI(GPIO_PV0, BB, RSVD, RSVD, RSVD, RSVD),
- PINI(GPIO_PV1, BB, RSVD, RSVD, RSVD, RSVD),
And likewise, plain "RSVD" doesn't exist. If you duplicate RSVD into each column of the table, there's no way to know which function pinmux_set_func(foo, RSVD) might pick, since it matches them all.
- PINI(SDMMC1_CLK, SDMMC1, SDMMC1, RSVD1, RSVD2, BAD),
- PINI(SDMMC1_CMD, SDMMC1, SDMMC1, RSVD1, RSVD2, BAD),
- PINI(SDMMC1_DAT3, SDMMC1, SDMMC1, RSVD1, UARTE, BAD),
- PINI(SDMMC1_DAT2, SDMMC1, SDMMC1, RSVD1, UARTE, BAD),
- PINI(SDMMC1_DAT1, SDMMC1, SDMMC1, RSVD1, UARTE, BAD),
- PINI(SDMMC1_DAT0, SDMMC1, SDMMC1, RSVD1, UARTE, BAD),
I believe the final column for all those entries should be UARTA.
- PINI(GPIO_PV3, SDMMC1, BAD, RSVD1, RSVD2, RSVD3),
BAD should be CLK_12M_OUT.
- PINO(LCD_PWR2, LCD, DISPA, DISPB, SPI5, BAD),
- PINO(LCD_SDOUT, LCD, DISPA, DISPB, SPI5, BAD),
- PINO(LCD_WR_N, LCD, DISPA, DISPB, SPI5, BAD),
- PINO(LCD_SCK, LCD, DISPA, DISPB, SPI5, BAD),
- PINO(LCD_PWR0, LCD, DISPA, DISPB, SPI5, BAD),
BAD should be HDCP for all of those.
- PINI(HDMI_INT, LCD, RSVD, RSVD, RSVD, RSVD),
The first reserved should be HDMI.
- PINI(VI_D0, VI, BAD, RSVD1, VI, RSVD2),
- PINI(VI_D1, VI, BAD, SDMMC2, VI, RSVD1),
- PINI(VI_D2, VI, BAD, SDMMC2, VI, RSVD1),
- PINI(VI_D3, VI, BAD, SDMMC2, VI, RSVD1),
- PINI(VI_D4, VI, BAD, SDMMC2, VI, RSVD1),
- PINI(VI_D5, VI, BAD, SDMMC2, VI, RSVD1),
- PINI(VI_D6, VI, BAD, SDMMC2, VI, RSVD1),
- PINI(VI_D7, VI, BAD, SDMMC2, VI, RSVD1),
- PINI(VI_D8, VI, BAD, SDMMC2, VI, RSVD1),
- PINI(VI_D9, VI, BAD, SDMMC2, VI, RSVD1),
+ PINI(VI_D10, VI, BAD, RSVD1, VI, RSVD2),
- PINI(VI_D11, VI, BAD, RSVD1, VI, RSVD2),
BAD should be DDR for all of those.
- PINI(VI_MCLK, VI, VI, BAD, BAD, BAD),
All the functions for this pin select VI.
- PINI(VI_VSYNC, VI, BAD, RSVD1, VI, RSVD2),
- PINI(VI_HSYNC, VI, BAD, RSVD1, VI, RSVD2),
BAD should be DDR for both of those.
- PINI(UART2_RXD, UART, IRDA, SPDIF, UARTA, SPI4),
- PINI(UART2_TXD, UART, IRDA, SPDIF, UARTA, SPI4),
IRDA just means UARTB, so I think remove IRDA, and replace all usage with UARTB everywhere.
- PINI(GMI_CS0_N, GMI, RSVD1, NAND, GMI, BAD),
- PINI(GMI_A17, GMI, UARTD, SPI4, GMI, BAD),
- PINI(GMI_A18, GMI, UARTD, SPI4, GMI, BAD),
BAD should be DTV in all of those.
- PINI(GEN2_I2C_SCL, GMI, I2C2, BAD, GMI, RSVD3),
- PINI(GEN2_I2C_SDA, GMI, I2C2, BAD, GMI, RSVD3),
BAD should be HDCP in both of those.
- PINI(CAM_MCLK, CAM, VI, BAD, VI_ALT2, POPSDMMC4),
We should rename POPSDMMC4 to just SDMMC4 throughout; there's just a single SDMMC4 controller; no a separate POPSDMMC4 controller.
- PINI(CAM_I2C_SCL, CAM, BAD, I2C3, RSVD2, POPSDMMC4),
- PINI(CAM_I2C_SDA, CAM, BAD, I2C3, RSVD2, POPSDMMC4),
BAD should be VGP1 and VGP2 in those two lines.
- PINI(KB_ROW3, SYS, KBC, BAD, RSVD2, BAD),
For all of KBC_ROW* and KBC_COL*, the BAD in func1 (i.e. the first BAD) should be NAND.
The second BAD there should be RSVD4.
- PINI(KB_ROW6, SYS, KBC, BAD, SDMMC2, BAD),
- PINI(KB_ROW7, SYS, KBC, BAD, SDMMC2, BAD),
- PINI(KB_ROW8, SYS, KBC, BAD, SDMMC2, BAD),
- PINI(KB_ROW9, SYS, KBC, BAD, SDMMC2, BAD),
- PINI(KB_ROW10, SYS, KBC, BAD, SDMMC2, BAD),
- PINI(KB_ROW11, SYS, KBC, BAD, SDMMC2, BAD),
- PINI(KB_ROW12, SYS, KBC, BAD, SDMMC2, BAD),
- PINI(KB_ROW13, SYS, KBC, BAD, SDMMC2, BAD),
- PINI(KB_ROW14, SYS, KBC, BAD, SDMMC2, BAD),
- PINI(KB_ROW15, SYS, KBC, BAD, SDMMC2, BAD),
The second bad (final column) for all of those should be MIO.
- PINI(KB_COL0, SYS, KBC, BAD, TRACE, BAD),
- PINI(KB_COL1, SYS, KBC, BAD, TRACE, BAD),
The second bad (final column) for both of those should be TEST.
- PINI(KB_COL6, SYS, KBC, BAD, TRACE, BAD),
- PINI(KB_COL7, SYS, KBC, BAD, TRACE, BAD),
The second bad (final column) for both of those should be MIO.
- PINI(CORE_PWR_REQ, SYS, RSVD, RSVD, RSVD, RSVD),
func0 (the first RSVD) should be CORE_PWR_REQ.
- PINI(CPU_PWR_REQ, SYS, RSVD, RSVD, RSVD, RSVD),
func0 (the first RSVD) should be CPU_PWR_REQ.
- PINI(PWR_INT_N, SYS, RSVD, RSVD, RSVD, RSVD),
func0 (the first RSVD) should be PWR_INT_N.
- PINI(CLK_32K_IN, SYS, RSVD, RSVD, RSVD, RSVD),
func0 (the first RSVD) should be CLK_32K_IN.
- PINI(OWR, SYS, OWR, RSVD, RSVD, RSVD),
func1 (the first RSVD) should be CEC.
- PINI(SPDIF_IN, AUDIO, SPDIF, HDA, BAD, DAPSDMMC2),
- PINI(SPDIF_OUT, AUDIO, SPDIF, RSVD1, BAD, DAPSDMMC2),
BAD should be I2C1 for both of those.
Rename DAPSDMMC2 to SDMMC2.
- PINI(SPI2_MOSI, AUDIO, SPI6, SPI2, BAD, GMI),
- PINI(SPI2_MISO, AUDIO, SPI6, SPI2, BAD, GMI),
- PINI(SPI2_CS0_N, AUDIO, SPI6, SPI2, BAD, GMI),
- PINI(SPI2_SCK, AUDIO, SPI6, SPI2, BAD, GMI),
BAD should be GMI for all of those.
- PINI(SPI1_MOSI, AUDIO, SPI2, SPI1, BAD, GMI),
- PINI(SPI1_SCK, AUDIO, SPI2, SPI1, BAD, GMI),
- PINI(SPI1_CS0_N, AUDIO, SPI2, SPI1, BAD, GMI),
- PINI(SPI1_MISO, AUDIO, BAD, SPI1, BAD, RSVD3),
SPI1_MISO's first BAD should be SPI3.
For all of those 4, func2's BAD should be SPI2 or rather SPI2_ALT.
- PINI(SPI2_CS1_N, AUDIO, BAD, SPI2, BAD, BAD),
- PINI(SPI2_CS2_N, AUDIO, BAD, SPI2, BAD, BAD),
In both of those, the first BAD should be SPI3, the second BAD SPI2_ALT, and the third BAD I2C1.
- PINI(SDMMC3_CLK, SDMMC3, UARTA, PWM2, SDMMC3, BAD),
BAD should be SPI3.
- PINI(SDMMC3_CMD, SDMMC3, UARTA, PWM3, SDMMC3, BAD),
BAD should be SPI2.
- PINI(SDMMC3_DAT0, SDMMC3, RSVD0, RSVD1, SDMMC3, BAD),
- PINI(SDMMC3_DAT1, SDMMC3, RSVD0, RSVD1, SDMMC3, BAD),
- PINI(SDMMC3_DAT2, SDMMC3, RSVD0, PWM1, SDMMC3, BAD),
- PINI(SDMMC3_DAT3, SDMMC3, RSVD0, PWM0, SDMMC3, BAD),
BAD should be SPI3 in all of those.
- PINI(SDMMC3_DAT4, SDMMC3, PWM1, BAD, SDMMC3, BAD),
- PINI(SDMMC3_DAT5, SDMMC3, PWM0, BAD, SDMMC3, BAD),
- PINI(SDMMC3_DAT6, SDMMC3, SPDIF, BAD, SDMMC3, BAD),
- PINI(SDMMC3_DAT7, SDMMC3, SPDIF, BAD, SDMMC3, BAD),
func1's BAD should be SPI4 in all of those.
func3's BAD should be SPI2 in all of those.
+void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
- /* Handle special values */
- if (func == PMUX_FUNC_SAFE)
func = tegra_soc_pingroups[pin].func_safe;
- if (func & PMUX_FUNC_RSVD) {
mux = func & 0x3;
Indeed, this is the way the code should work, but in order for this code to work correctly, RSVD1 must only be used in the func0 column in the data, RSVD2 in the func1 column, etc.
+static int pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock)
- reg = readl(pin_lock);
- reg &= ~(0x1 << PMUX_LOCK_SHIFT);
- if (lock == PMUX_PIN_LOCK_ENABLE)
reg |= (0x1 << PMUX_LOCK_SHIFT);
- writel(reg, pin_lock);
Note that the LOCK bit, once set, can never be set back to zero. Perhaps a diagnostic should be issued and/or an error returned if this is attempted? The kernel does that.

Stephen,
On Wed, Oct 3, 2012 at 12:49 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/02/2012 04:45 PM, Tom Warren wrote:
These files are used by both SPL and main U-Boot. Also made minor changes to shared Tegra code to support T30 differences.
diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c
@@ -58,6 +62,20 @@ int tegra_get_chip_type(void) return TEGRA_SOC_T25; } break;
case CHIPID_TEGRA30:
switch (tegra_sku_id) {
case SKU_ID_T30:
/*
* T30 has two options. We will return TEGRA_SOC_T30
* until we have the fdt set up when it may change to
* TEGRA_SOC_T30_408MHZ depending on the PLLP freq.
*/
if (clock_get_rate(CLOCK_ID_PERIPH) == 408000000)
return TEGRA_SOC_T30_408MHZ;
else
return TEGRA_SOC_T30;
Hmmm. I wonder why this doesn't return just the actual chip type; isn't the different in PLL_P rates a SW option and not a facet of the HW? The whole TEGRA_SOC_T30_408MHZ thing seems strange to me.
As I remember the history of early T30 & our internal U-Boot bringup, we started out at the slower clock rate (216MHz, IIRC), and then phased in 408MHz once things were stable, chips rev'd, etc. I can look into going directly to 408MHz, or phase it in in the next pass so boards have an option of using either speed, much as we have in Tegra20 with T20 and T25.
diff --git a/arch/arm/cpu/tegra-common/board.c b/arch/arm/cpu/tegra-common/board.c
@@ -59,9 +59,12 @@ unsigned int query_sdram_size(void) case 1: return 0x10000000; /* 256 MB */ case 2:
default: return 0x20000000; /* 512 MB */
case 3:
case 4:
return 0x40000000; /* 1GB */
case 8:
return 0x7ff00000; /* 2GB - 1MB */
default: return 0x40000000; /* 1GB */ }
}
I think we should be a little more explicit about the Tegra20/Tegra30 differences here. At least for case 0, there's a difference in what this field means for the two chips.
Value Tegra20 Tegra30 0 512 256 1 256 256 2 512 512 3 1024 768 4 undef 1024 5 undef undef 6 undef undef 7 undef undef 8 n/a 2048-1
At least the Toshiba AC100 uses value "0" in this field and has 512MB not 1GB of RAM.
Good point - I've only dealt with 1GB boards here so I'd missed the impact of changing the 'default' option. I'll redo it in V2.
I also note that for Tegra30, this field is bits 31:28, whereas for Tegra20 it's bits 30:28; we aren't masking off the top bit as we should in the current code. Again, the Toshiba AC100 appears to set this extra top bit, and only succeeds in getting 512M as the result of this function because of the default case.
I thought that we'd made the ODMDATA definitions compatible between T20 and T30. Must have missed it. I'll fix this too in V2.
diff --git a/arch/arm/cpu/tegra30-common/pinmux.c b/arch/arm/cpu/tegra30-common/pinmux.c
Hmmm. The header file this relies on doesn't exist yet. But perhaps this is OK since there's no boards.cfg entry for Tegra30 yet.
Should be OK. As I said in another thread, I'll double-check with git bisect/git am before posting V2.
+const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
/* NAME VDD f0 f1 f2 f3 fSafe io */
"fSafe io" should be deleted; those columns don't exist in the table.
I compared this table to that in the upstream kernel, which I spent a lot of time on correlating with the various documentation sources and our downstream kernel. Some changes should be made:
PINI(DAP3_FS, BB, I2S2, RSVD1, DISPA, DISPB),
PINI(DAP3_DIN, BB, I2S2, RSVD1, DISPA, DISPB),
PINI(DAP3_DOUT, BB, I2S2, RSVD1, DISPA, DISPB),
PINI(DAP3_SCLK, BB, I2S2, RSVD1, DISPA, DISPB),
In the kernel at least, the RSVD values are only used in particular slots, i.e. RSVD1 always yields function 0, RSVD2==func1, RSVD3==func2, RSVD4==func3. That way, when representing the "safe" value, one can use RSVDn to guarantee to get func(n-1). I suspect, it'd be a good idea for U-Boot to adopt the same policy. So, s/RSVD1/RSVD2/ above, and make similar changes throughout this table.
PINI(GPIO_PV0, BB, RSVD, RSVD, RSVD, RSVD),
PINI(GPIO_PV1, BB, RSVD, RSVD, RSVD, RSVD),
And likewise, plain "RSVD" doesn't exist. If you duplicate RSVD into each column of the table, there's no way to know which function pinmux_set_func(foo, RSVD) might pick, since it matches them all.
PINI(SDMMC1_CLK, SDMMC1, SDMMC1, RSVD1, RSVD2, BAD),
PINI(SDMMC1_CMD, SDMMC1, SDMMC1, RSVD1, RSVD2, BAD),
PINI(SDMMC1_DAT3, SDMMC1, SDMMC1, RSVD1, UARTE, BAD),
PINI(SDMMC1_DAT2, SDMMC1, SDMMC1, RSVD1, UARTE, BAD),
PINI(SDMMC1_DAT1, SDMMC1, SDMMC1, RSVD1, UARTE, BAD),
PINI(SDMMC1_DAT0, SDMMC1, SDMMC1, RSVD1, UARTE, BAD),
I believe the final column for all those entries should be UARTA.
PINI(GPIO_PV3, SDMMC1, BAD, RSVD1, RSVD2, RSVD3),
BAD should be CLK_12M_OUT.
PINO(LCD_PWR2, LCD, DISPA, DISPB, SPI5, BAD),
PINO(LCD_SDOUT, LCD, DISPA, DISPB, SPI5, BAD),
PINO(LCD_WR_N, LCD, DISPA, DISPB, SPI5, BAD),
PINO(LCD_SCK, LCD, DISPA, DISPB, SPI5, BAD),
PINO(LCD_PWR0, LCD, DISPA, DISPB, SPI5, BAD),
BAD should be HDCP for all of those.
PINI(HDMI_INT, LCD, RSVD, RSVD, RSVD, RSVD),
The first reserved should be HDMI.
PINI(VI_D0, VI, BAD, RSVD1, VI, RSVD2),
PINI(VI_D1, VI, BAD, SDMMC2, VI, RSVD1),
PINI(VI_D2, VI, BAD, SDMMC2, VI, RSVD1),
PINI(VI_D3, VI, BAD, SDMMC2, VI, RSVD1),
PINI(VI_D4, VI, BAD, SDMMC2, VI, RSVD1),
PINI(VI_D5, VI, BAD, SDMMC2, VI, RSVD1),
PINI(VI_D6, VI, BAD, SDMMC2, VI, RSVD1),
PINI(VI_D7, VI, BAD, SDMMC2, VI, RSVD1),
PINI(VI_D8, VI, BAD, SDMMC2, VI, RSVD1),
PINI(VI_D9, VI, BAD, SDMMC2, VI, RSVD1),
PINI(VI_D10, VI, BAD, RSVD1, VI, RSVD2),
PINI(VI_D11, VI, BAD, RSVD1, VI, RSVD2),
BAD should be DDR for all of those.
PINI(VI_MCLK, VI, VI, BAD, BAD, BAD),
All the functions for this pin select VI.
PINI(VI_VSYNC, VI, BAD, RSVD1, VI, RSVD2),
PINI(VI_HSYNC, VI, BAD, RSVD1, VI, RSVD2),
BAD should be DDR for both of those.
PINI(UART2_RXD, UART, IRDA, SPDIF, UARTA, SPI4),
PINI(UART2_TXD, UART, IRDA, SPDIF, UARTA, SPI4),
IRDA just means UARTB, so I think remove IRDA, and replace all usage with UARTB everywhere.
PINI(GMI_CS0_N, GMI, RSVD1, NAND, GMI, BAD),
PINI(GMI_A17, GMI, UARTD, SPI4, GMI, BAD),
PINI(GMI_A18, GMI, UARTD, SPI4, GMI, BAD),
BAD should be DTV in all of those.
PINI(GEN2_I2C_SCL, GMI, I2C2, BAD, GMI, RSVD3),
PINI(GEN2_I2C_SDA, GMI, I2C2, BAD, GMI, RSVD3),
BAD should be HDCP in both of those.
PINI(CAM_MCLK, CAM, VI, BAD, VI_ALT2, POPSDMMC4),
We should rename POPSDMMC4 to just SDMMC4 throughout; there's just a single SDMMC4 controller; no a separate POPSDMMC4 controller.
PINI(CAM_I2C_SCL, CAM, BAD, I2C3, RSVD2, POPSDMMC4),
PINI(CAM_I2C_SDA, CAM, BAD, I2C3, RSVD2, POPSDMMC4),
BAD should be VGP1 and VGP2 in those two lines.
PINI(KB_ROW3, SYS, KBC, BAD, RSVD2, BAD),
For all of KBC_ROW* and KBC_COL*, the BAD in func1 (i.e. the first BAD) should be NAND.
The second BAD there should be RSVD4.
PINI(KB_ROW6, SYS, KBC, BAD, SDMMC2, BAD),
PINI(KB_ROW7, SYS, KBC, BAD, SDMMC2, BAD),
PINI(KB_ROW8, SYS, KBC, BAD, SDMMC2, BAD),
PINI(KB_ROW9, SYS, KBC, BAD, SDMMC2, BAD),
PINI(KB_ROW10, SYS, KBC, BAD, SDMMC2, BAD),
PINI(KB_ROW11, SYS, KBC, BAD, SDMMC2, BAD),
PINI(KB_ROW12, SYS, KBC, BAD, SDMMC2, BAD),
PINI(KB_ROW13, SYS, KBC, BAD, SDMMC2, BAD),
PINI(KB_ROW14, SYS, KBC, BAD, SDMMC2, BAD),
PINI(KB_ROW15, SYS, KBC, BAD, SDMMC2, BAD),
The second bad (final column) for all of those should be MIO.
PINI(KB_COL0, SYS, KBC, BAD, TRACE, BAD),
PINI(KB_COL1, SYS, KBC, BAD, TRACE, BAD),
The second bad (final column) for both of those should be TEST.
PINI(KB_COL6, SYS, KBC, BAD, TRACE, BAD),
PINI(KB_COL7, SYS, KBC, BAD, TRACE, BAD),
The second bad (final column) for both of those should be MIO.
PINI(CORE_PWR_REQ, SYS, RSVD, RSVD, RSVD, RSVD),
func0 (the first RSVD) should be CORE_PWR_REQ.
PINI(CPU_PWR_REQ, SYS, RSVD, RSVD, RSVD, RSVD),
func0 (the first RSVD) should be CPU_PWR_REQ.
PINI(PWR_INT_N, SYS, RSVD, RSVD, RSVD, RSVD),
func0 (the first RSVD) should be PWR_INT_N.
PINI(CLK_32K_IN, SYS, RSVD, RSVD, RSVD, RSVD),
func0 (the first RSVD) should be CLK_32K_IN.
PINI(OWR, SYS, OWR, RSVD, RSVD, RSVD),
func1 (the first RSVD) should be CEC.
PINI(SPDIF_IN, AUDIO, SPDIF, HDA, BAD, DAPSDMMC2),
PINI(SPDIF_OUT, AUDIO, SPDIF, RSVD1, BAD, DAPSDMMC2),
BAD should be I2C1 for both of those.
Rename DAPSDMMC2 to SDMMC2.
PINI(SPI2_MOSI, AUDIO, SPI6, SPI2, BAD, GMI),
PINI(SPI2_MISO, AUDIO, SPI6, SPI2, BAD, GMI),
PINI(SPI2_CS0_N, AUDIO, SPI6, SPI2, BAD, GMI),
PINI(SPI2_SCK, AUDIO, SPI6, SPI2, BAD, GMI),
BAD should be GMI for all of those.
PINI(SPI1_MOSI, AUDIO, SPI2, SPI1, BAD, GMI),
PINI(SPI1_SCK, AUDIO, SPI2, SPI1, BAD, GMI),
PINI(SPI1_CS0_N, AUDIO, SPI2, SPI1, BAD, GMI),
PINI(SPI1_MISO, AUDIO, BAD, SPI1, BAD, RSVD3),
SPI1_MISO's first BAD should be SPI3.
For all of those 4, func2's BAD should be SPI2 or rather SPI2_ALT.
PINI(SPI2_CS1_N, AUDIO, BAD, SPI2, BAD, BAD),
PINI(SPI2_CS2_N, AUDIO, BAD, SPI2, BAD, BAD),
In both of those, the first BAD should be SPI3, the second BAD SPI2_ALT, and the third BAD I2C1.
PINI(SDMMC3_CLK, SDMMC3, UARTA, PWM2, SDMMC3, BAD),
BAD should be SPI3.
PINI(SDMMC3_CMD, SDMMC3, UARTA, PWM3, SDMMC3, BAD),
BAD should be SPI2.
PINI(SDMMC3_DAT0, SDMMC3, RSVD0, RSVD1, SDMMC3, BAD),
PINI(SDMMC3_DAT1, SDMMC3, RSVD0, RSVD1, SDMMC3, BAD),
PINI(SDMMC3_DAT2, SDMMC3, RSVD0, PWM1, SDMMC3, BAD),
PINI(SDMMC3_DAT3, SDMMC3, RSVD0, PWM0, SDMMC3, BAD),
BAD should be SPI3 in all of those.
PINI(SDMMC3_DAT4, SDMMC3, PWM1, BAD, SDMMC3, BAD),
PINI(SDMMC3_DAT5, SDMMC3, PWM0, BAD, SDMMC3, BAD),
PINI(SDMMC3_DAT6, SDMMC3, SPDIF, BAD, SDMMC3, BAD),
PINI(SDMMC3_DAT7, SDMMC3, SPDIF, BAD, SDMMC3, BAD),
func1's BAD should be SPI4 in all of those.
func3's BAD should be SPI2 in all of those.
Holy cow! Very thorough review! Thanks - I'll make those changes. Note that this is the table we're still using in our internal T30 U-Boot (IIRC) - we should update it there, too.
+void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
/* Handle special values */
if (func == PMUX_FUNC_SAFE)
func = tegra_soc_pingroups[pin].func_safe;
if (func & PMUX_FUNC_RSVD) {
mux = func & 0x3;
Indeed, this is the way the code should work, but in order for this code to work correctly, RSVD1 must only be used in the func0 column in the data, RSVD2 in the func1 column, etc.
I ported this from our internal codebase w/o looking at it too much - it just worked (for the very limited pinmuxing done to get UART output working). I'll check all this out on the next rev. Thanks.
+static int pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock)
reg = readl(pin_lock);
reg &= ~(0x1 << PMUX_LOCK_SHIFT);
if (lock == PMUX_PIN_LOCK_ENABLE)
reg |= (0x1 << PMUX_LOCK_SHIFT);
writel(reg, pin_lock);
Note that the LOCK bit, once set, can never be set back to zero. Perhaps a diagnostic should be issued and/or an error returned if this is attempted? The kernel does that.
Good idea - I'll add it.
Thanks again for the hard work,
Tom

Common Tegra files are in arch-tegra, shared between T20 and T30. Tegra30-specific headers are in arch-tegra30. Note that some of these will be filled in as more T30 support is added (drivers, WB/LP0 support, etc.).
Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/include/asm/arch-tegra/clk_rst.h | 148 +++++- arch/arm/include/asm/arch-tegra/clock.h | 8 +- arch/arm/include/asm/arch-tegra/gp_padctrl.h | 37 ++ arch/arm/include/asm/arch-tegra/tegra.h | 11 +- arch/arm/include/asm/arch-tegra20/gp_padctrl.h | 17 +- arch/arm/include/asm/arch-tegra30/clock-tables.h | 378 ++++++++++++ arch/arm/include/asm/arch-tegra30/clock.h | 24 + arch/arm/include/asm/arch-tegra30/emc.h | 106 ++++ arch/arm/include/asm/arch-tegra30/flow.h | 35 ++ arch/arm/include/asm/arch-tegra30/funcmux.h | 47 ++ arch/arm/include/asm/arch-tegra30/gp_padctrl.h | 59 ++ arch/arm/include/asm/arch-tegra30/gpio.h | 304 ++++++++++ arch/arm/include/asm/arch-tegra30/hardware.h | 22 + .../asm/arch-tegra30/pinmux-config-common.h | 339 +++++++++++ arch/arm/include/asm/arch-tegra30/pinmux.h | 603 ++++++++++++++++++++ arch/arm/include/asm/arch-tegra30/pmu.h | 23 + arch/arm/include/asm/arch-tegra30/tegra.h | 26 + 17 files changed, 2161 insertions(+), 26 deletions(-) create mode 100644 arch/arm/include/asm/arch-tegra/gp_padctrl.h create mode 100644 arch/arm/include/asm/arch-tegra30/clock-tables.h create mode 100644 arch/arm/include/asm/arch-tegra30/clock.h create mode 100644 arch/arm/include/asm/arch-tegra30/emc.h create mode 100644 arch/arm/include/asm/arch-tegra30/flow.h create mode 100644 arch/arm/include/asm/arch-tegra30/funcmux.h create mode 100644 arch/arm/include/asm/arch-tegra30/gp_padctrl.h create mode 100644 arch/arm/include/asm/arch-tegra30/gpio.h create mode 100644 arch/arm/include/asm/arch-tegra30/hardware.h create mode 100644 arch/arm/include/asm/arch-tegra30/pinmux-config-common.h create mode 100644 arch/arm/include/asm/arch-tegra30/pinmux.h create mode 100644 arch/arm/include/asm/arch-tegra30/pmu.h create mode 100644 arch/arm/include/asm/arch-tegra30/tegra.h
diff --git a/arch/arm/include/asm/arch-tegra/clk_rst.h b/arch/arm/include/asm/arch-tegra/clk_rst.h index 7b548c2..6a6e507 100644 --- a/arch/arm/include/asm/arch-tegra/clk_rst.h +++ b/arch/arm/include/asm/arch-tegra/clk_rst.h @@ -21,8 +21,8 @@ * MA 02111-1307 USA */
-#ifndef _CLK_RST_H_ -#define _CLK_RST_H_ +#ifndef _TEGRA_CLK_RST_H_ +#define _TEGRA_CLK_RST_H_
/* PLL registers - there are several PLLs in the clock controller */ struct clk_pll { @@ -37,6 +37,12 @@ struct clk_pll_simple { uint pll_misc; /* other misc things */ };
+/* RST_DEV_(L,H,U,V,W)_(SET,CLR) and CLK_ENB_(L,H,U,V,W)_(SET,CLR) */ +struct clk_set_clr { + uint set; + uint clr; +}; + /* * Most PLLs use the clk_pll structure, but some have a simpler two-member * structure for which we use clk_pll_simple. The reason for this non- @@ -45,8 +51,10 @@ struct clk_pll_simple { enum { TEGRA_CLK_PLLS = 6, /* Number of normal PLLs */ TEGRA_CLK_SIMPLE_PLLS = 3, /* Number of simple PLLs */ - TEGRA_CLK_REGS = 3, /* Number of clock enable registers */ - TEGRA_CLK_SOURCES = 64, /* Number of peripheral clock sources */ + TEGRA_CLK_REGS = 3, /* Number of clock enable regs L/H/U */ + TEGRA_CLK_SOURCES = 64, /* Number of ppl clock sources L/H/U */ + TEGRA_CLK_REGS_VW = 2, /* Number of clock enable regs V/W */ + TEGRA_CLK_SOURCES_VW = 32, /* Number of ppl clock sources V/W*/ };
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */ @@ -82,14 +90,53 @@ struct clk_rst_ctlr { uint crc_reserved11; /* _reserved_11, 0xFC */
uint crc_clk_src[TEGRA_CLK_SOURCES]; /*_I2S1_0... 0x100-1fc */ - uint crc_reserved20[80]; /* 0x200-33C */ - uint crc_cpu_cmplx_set; /* _CPU_CMPLX_SET_0, 0x340 */ - uint crc_cpu_cmplx_clr; /* _CPU_CMPLX_CLR_0, 0x344 */ + + uint crc_reserved20[64]; /* _reserved_20, 0x200-2fc */ + + /* _RST_DEV_L/H/U_SET_0 0x300 ~ 0x314 */ + struct clk_set_clr crc_rst_dev_ex[TEGRA_CLK_REGS]; + + uint crc_reserved30[2]; /* _reserved_30, 0x318, 0x31c */ + + /* _CLK_ENB_L/H/U_CLR_0 0x320 ~ 0x334 */ + struct clk_set_clr crc_clk_enb_ex[TEGRA_CLK_REGS]; + + uint crc_reserved31[2]; /* _reserved_31, 0x338, 0x33c */ + + uint crc_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */ + uint crc_cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */ + + /* Additional (T30) registers */ + uint crc_clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */ + uint crc_clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */ + + uint crc_reserved32[2]; /* _reserved_32, 0x350,0x354 */ + + uint crc_rst_dev_vw[TEGRA_CLK_REGS_VW]; /* _RST_DEVICES_V/W_0 */ + uint crc_clk_out_enb_vw[TEGRA_CLK_REGS_VW]; /* _CLK_OUT_ENB_V/W_0 */ + uint crc_cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */ + uint crc_super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36C */ + uint crc_cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */ + uint crc_super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */ + uint crc_clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */ + uint crc_clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37C */ + uint crc_cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */ + uint crc_reserved33[11]; /* _reserved_33, 0x384-3ac */ + uint crc_clk_src_vw[TEGRA_CLK_SOURCES_VW]; /* _G3D2_0..., 0x3b0-0x42c */ + /* _RST_DEV_V/W_SET_0 0x430 ~ 0x43c */ + struct clk_set_clr crc_rst_dev_ex_vw[TEGRA_CLK_REGS_VW]; + /* _CLK_ENB_V/W_CLR_0 0x440 ~ 0x44c */ + struct clk_set_clr crc_clk_enb_ex_vw[TEGRA_CLK_REGS_VW]; + uint crc_reserved40[12]; /* _reserved_40, 0x450-47C */ + uint crc_pll_cfg0; /* _PLL_CFG0_0, 0x480 */ + uint crc_pll_cfg1; /* _PLL_CFG1_0, 0x484 */ + uint crc_pll_cfg2; /* _PLL_CFG2_0, 0x488 */ };
/* CLK_RST_CONTROLLER_CLK_CPU_CMPLX_0 */ +#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)
@@ -120,6 +167,12 @@ struct clk_rst_ctlr { #define PLL_OUT_RATIO_MASK (0xffU << PLL_OUT_RATIO_SHIFT)
/* CLK_RST_CONTROLLER_PLLx_MISC_0 */ +#define PLL_DCCON_SHIFT 20 +#define PLL_DCCON_MASK (1U << PLL_DCCON_SHIFT) + +#define PLL_LOCK_ENABLE_SHIFT 18 +#define PLL_LOCK_ENABLE_MASK (1U << PLL_LOCK_ENABLE_SHIFT) + #define PLL_CPCON_SHIFT 8 #define PLL_CPCON_MASK (15U << PLL_CPCON_SHIFT)
@@ -129,6 +182,22 @@ struct clk_rst_ctlr { #define PLLU_VCO_FREQ_SHIFT 20 #define PLLU_VCO_FREQ_MASK (1U << PLLU_VCO_FREQ_SHIFT)
+#define PLLP_OUT1_OVR (1 << 2) +#define PLLP_OUT2_OVR (1 << 18) +#define PLLP_OUT3_OVR (1 << 2) +#define PLLP_OUT4_OVR (1 << 18) +#define PLLP_OUT1_RATIO 8 +#define PLLP_OUT2_RATIO 24 +#define PLLP_OUT3_RATIO 8 +#define PLLP_OUT4_RATIO 24 + +enum { + IN_408_OUT_204_DIVISOR = 2, + IN_408_OUT_102_DIVISOR = 6, + IN_408_OUT_48_DIVISOR = 15, + IN_408_OUT_9_6_DIVISOR = 83, +}; + /* CLK_RST_CONTROLLER_OSC_CTRL_0 */ #define OSC_FREQ_SHIFT 30 #define OSC_FREQ_MASK (3U << OSC_FREQ_SHIFT) @@ -151,4 +220,65 @@ struct clk_rst_ctlr { #define OUT_CLK_SOURCE4_SHIFT 28 #define OUT_CLK_SOURCE4_MASK (15U << OUT_CLK_SOURCE4_SHIFT)
-#endif /* CLK_RST_H */ +/* 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_SWAKEUP_FIQ_SOURCE_SHIFT 12 +#define SCLK_SWAKEUP_FIQ_SOURCE_MASK \ + (7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) +#define SCLK_SWAKEUP_IRQ_SOURCE_SHIFT 8 +#define SCLK_SWAKEUP_IRQ_SOURCE_MASK \ + (7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) +#define SCLK_SWAKEUP_RUN_SOURCE_SHIFT 4 +#define SCLK_SWAKEUP_RUN_SOURCE_MASK \ + (7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) +#define SCLK_SWAKEUP_IDLE_SOURCE_SHIFT 0 + +#define SCLK_SWAKEUP_IDLE_SOURCE_MASK \ + (7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) +enum { + SCLK_SOURCE_CLKM, + SCLK_SOURCE_PLLC_OUT1, + SCLK_SOURCE_PLLP_OUT4, + SCLK_SOURCE_PLLP_OUT3, + SCLK_SOURCE_PLLP_OUT2, + SCLK_SOURCE_CLKD, + SCLK_SOURCE_CLKS, + SCLK_SOURCE_PLLM_OUT1, +}; +#define SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 (7 << 12) +#define SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 (7 << 8) +#define SCLK_SWAKE_RUN_SRC_PLLM_OUT1 (7 << 4) +#define SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 (7 << 0) + +/* CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER */ +#define SUPER_SCLK_ENB_SHIFT 31U +#define SUPER_SCLK_ENB_MASK (1U << 31) +#define SUPER_SCLK_DIVIDEND_SHIFT 8 +#define SUPER_SCLK_DIVIDEND_MASK (0xff << SUPER_SCLK_DIVIDEND_SHIFT) +#define SUPER_SCLK_DIVISOR_SHIFT 0 +#define SUPER_SCLK_DIVISOR_MASK (0xff << SUPER_SCLK_DIVISOR_SHIFT) + +/* CLK_RST_CONTROLLER_CLK_SYSTEM_RATE */ +#define CLK_SYS_RATE_HCLK_DISABLE_SHIFT 7 +#define CLK_SYS_RATE_HCLK_DISABLE_MASK (1 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) +#define CLK_SYS_RATE_AHB_RATE_SHIFT 4 +#define CLK_SYS_RATE_AHB_RATE_MASK (3 << CLK_SYS_RATE_AHB_RATE_SHIFT) +#define CLK_SYS_RATE_PCLK_DISABLE_SHIFT 3 +#define CLK_SYS_RATE_PCLK_DISABLE_MASK (1 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) +#define CLK_SYS_RATE_APB_RATE_SHIFT 0 +#define CLK_SYS_RATE_APB_RATE_MASK (3 << CLK_SYS_RATE_AHB_RATE_SHIFT) + +#endif /* _TEGRA_CLK_RST_H_ */ diff --git a/arch/arm/include/asm/arch-tegra/clock.h b/arch/arm/include/asm/arch-tegra/clock.h index eac1dc2..01f86ab 100644 --- a/arch/arm/include/asm/arch-tegra/clock.h +++ b/arch/arm/include/asm/arch-tegra/clock.h @@ -21,8 +21,8 @@
/* Tegra clock control functions */
-#ifndef _CLOCK_H -#define _CLOCK_H +#ifndef _TEGRA_CLOCK_H_ +#define _TEGRA_CLOCK_H_
/* Set of oscillator frequencies supported in the internal API. */ enum clock_osc_freq { @@ -136,7 +136,7 @@ enum crc_reset_id { /** * Put parts of the CPU complex into or out of reset.\ * - * @param cpu cpu number (0 or 1 on Tegra2) + * @param cpu cpu number (0 or 1 on Tegra2, 0-3 on Tegra3) * @param which which parts of the complex to affect (OR of crc_reset_id) * @param reset 1 to assert reset, 0 to de-assert */ @@ -262,4 +262,4 @@ void clock_init(void); /* Initialize the PLLs */ void clock_early_init(void);
-#endif /* _CLOCK_H_ */ +#endif /* _TEGRA_CLOCK_H_ */ diff --git a/arch/arm/include/asm/arch-tegra/gp_padctrl.h b/arch/arm/include/asm/arch-tegra/gp_padctrl.h new file mode 100644 index 0000000..d347e97 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/gp_padctrl.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2010-2012 + * NVIDIA Corporation <www.nvidia.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _TEGRA_GP_PADCTRL_H_ +#define _TEGRA_GP_PADCTRL_H_ + +/* bit fields definitions for APB_MISC_GP_HIDREV register */ +#define HIDREV_CHIPID_SHIFT 8 +#define HIDREV_CHIPID_MASK (0xff << HIDREV_CHIPID_SHIFT) +#define HIDREV_MAJORPREV_SHIFT 4 +#define HIDREV_MAJORPREV_MASK (0xf << HIDREV_MAJORPREV_SHIFT) + +/* CHIPID field returned from APB_MISC_GP_HIDREV register */ +#define CHIPID_TEGRA20 0x20 +#define CHIPID_TEGRA30 0x30 + +#endif /* _TEGRA_GP_PADCTRL_H_ */ diff --git a/arch/arm/include/asm/arch-tegra/tegra.h b/arch/arm/include/asm/arch-tegra/tegra.h index 6d2e62f..405abd8 100644 --- a/arch/arm/include/asm/arch-tegra/tegra.h +++ b/arch/arm/include/asm/arch-tegra/tegra.h @@ -72,12 +72,21 @@ enum { SKU_ID_T25 = 0x18, SKU_ID_AP25E = 0x1b, SKU_ID_T25E = 0x1c, + SKU_ID_T30 = 0x81, /* Cardhu value */ };
-/* These are the SOC categories that affect clocking */ +/* + * These are used to distinguish SOC types for setting up clocks. Mostly + * we can tell the clocking required by looking at the SOC sku_id, but + * for T30 it is a user option as to whether to run PLLP in fast or slow + * mode, so we have two options there. + */ enum { TEGRA_SOC_T20, TEGRA_SOC_T25, + TEGRA_SOC_T30, + TEGRA_SOC_T30_408MHZ, /* A T30 with faster PLLP */ + TEGRA_SOC2_SLOW, /* T2x needs to run at slow clock initially */
TEGRA_SOC_COUNT, TEGRA_SOC_UNKNOWN = -1, diff --git a/arch/arm/include/asm/arch-tegra20/gp_padctrl.h b/arch/arm/include/asm/arch-tegra20/gp_padctrl.h index 865af5b..eaaf903 100644 --- a/arch/arm/include/asm/arch-tegra20/gp_padctrl.h +++ b/arch/arm/include/asm/arch-tegra20/gp_padctrl.h @@ -21,8 +21,10 @@ * MA 02111-1307 USA */
-#ifndef _GP_PADCTRL_H_ -#define _GP_PADCTRL_H_ +#ifndef _TEGRA20_GP_PADCTRL_H_ +#define _TEGRA20_GP_PADCTRL_H_ + +#include <asm/arch-tegra/gp_padctrl.h>
/* APB_MISC_GP and padctrl registers */ struct apb_misc_gp_ctlr { @@ -61,13 +63,4 @@ struct apb_misc_gp_ctlr { u32 memcomp; /* 0xD4: APB_MISC_GP_MEMCOMPPADCTRL */ };
-/* bit fields definitions for APB_MISC_GP_HIDREV register */ -#define HIDREV_CHIPID_SHIFT 8 -#define HIDREV_CHIPID_MASK (0xff << HIDREV_CHIPID_SHIFT) -#define HIDREV_MAJORPREV_SHIFT 4 -#define HIDREV_MAJORPREV_MASK (0xf << HIDREV_MAJORPREV_SHIFT) - -/* CHIPID field returned from APB_MISC_GP_HIDREV register */ -#define CHIPID_TEGRA20 0x20 - -#endif +#endif /* _TEGRA20_GP_PADCTRL_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/clock-tables.h b/arch/arm/include/asm/arch-tegra30/clock-tables.h new file mode 100644 index 0000000..b55e09d --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/clock-tables.h @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2010-2012, 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/. + */ + +/* Tegra30 clock PLL tables */ + +#ifndef _TEGRA30_CLOCK_TABLES_H_ +#define _TEGRA30_CLOCK_TABLES_H_ + +/* The PLLs supported by the hardware */ +enum clock_id { + CLOCK_ID_FIRST, + CLOCK_ID_CGENERAL = CLOCK_ID_FIRST, + CLOCK_ID_MEMORY, + CLOCK_ID_PERIPH, + CLOCK_ID_AUDIO, + CLOCK_ID_USB, + CLOCK_ID_DISPLAY, + + /* now the simple ones */ + CLOCK_ID_FIRST_SIMPLE, + CLOCK_ID_XCPU = CLOCK_ID_FIRST_SIMPLE, + CLOCK_ID_EPCI, + CLOCK_ID_SFROM32KHZ, + + /* These are the base clocks (inputs to the Tegra SOC) */ + CLOCK_ID_32KHZ, + CLOCK_ID_OSC, + + CLOCK_ID_COUNT, /* number of PLLs */ + CLOCK_ID_DISPLAY2, /* Tegra3, placeholder */ + CLOCK_ID_NONE = -1, +}; + +/* The clocks supported by the hardware */ +enum periph_id { + PERIPH_ID_FIRST, + + /* Low word: 31:0 */ + PERIPH_ID_CPU = PERIPH_ID_FIRST, + PERIPH_ID_COP, + PERIPH_ID_TRIGSYS, + PERIPH_ID_RESERVED3, + PERIPH_ID_RESERVED4, + PERIPH_ID_TMR, + PERIPH_ID_UART1, + PERIPH_ID_UART2, + + /* 8 */ + PERIPH_ID_GPIO, + PERIPH_ID_SDMMC2, + PERIPH_ID_SPDIF, + PERIPH_ID_I2S1, + PERIPH_ID_I2C1, + PERIPH_ID_NDFLASH, + PERIPH_ID_SDMMC1, + PERIPH_ID_SDMMC4, + + /* 16 */ + PERIPH_ID_RESERVED16, + PERIPH_ID_PWM, + PERIPH_ID_I2S2, + PERIPH_ID_EPP, + PERIPH_ID_VI, + PERIPH_ID_2D, + PERIPH_ID_USBD, + PERIPH_ID_ISP, + + /* 24 */ + PERIPH_ID_3D, + PERIPH_ID_RESERVED24, + PERIPH_ID_DISP2, + PERIPH_ID_DISP1, + PERIPH_ID_HOST1X, + PERIPH_ID_VCP, + PERIPH_ID_I2S0, + PERIPH_ID_CACHE2, + + /* Middle word: 63:32 */ + PERIPH_ID_MEM, + PERIPH_ID_AHBDMA, + PERIPH_ID_APBDMA, + PERIPH_ID_RESERVED35, + PERIPH_ID_KBC, + PERIPH_ID_STAT_MON, + PERIPH_ID_PMC, + PERIPH_ID_FUSE, + + /* 40 */ + PERIPH_ID_KFUSE, + PERIPH_ID_SBC1, + PERIPH_ID_SNOR, + PERIPH_ID_RESERVED43, + PERIPH_ID_SBC2, + PERIPH_ID_RESERVED45, + PERIPH_ID_SBC3, + PERIPH_ID_DVC_I2C, + + /* 48 */ + PERIPH_ID_DSI, + PERIPH_ID_TVO, + PERIPH_ID_MIPI, + PERIPH_ID_HDMI, + PERIPH_ID_CSI, + PERIPH_ID_TVDAC, + PERIPH_ID_I2C2, + PERIPH_ID_UART3, + + /* 56 */ + PERIPH_ID_RESERVED56, + PERIPH_ID_EMC, + PERIPH_ID_USB2, + PERIPH_ID_USB3, + PERIPH_ID_MPE, + PERIPH_ID_VDE, + PERIPH_ID_BSEA, + PERIPH_ID_BSEV, + + /* Upper word 95:64 */ + PERIPH_ID_SPEEDO, + PERIPH_ID_UART4, + PERIPH_ID_UART5, + PERIPH_ID_I2C3, + PERIPH_ID_SBC4, + PERIPH_ID_SDMMC3, + PERIPH_ID_PCIE, + PERIPH_ID_OWR, + + /* 72 */ + PERIPH_ID_AFI, + PERIPH_ID_CORESIGHT, + PERIPH_ID_PCIEXCLK, + PERIPH_ID_AVPUCQ, + PERIPH_ID_RESERVED76, + PERIPH_ID_RESERVED77, + PERIPH_ID_RESERVED78, + PERIPH_ID_DTV, + + /* 80 */ + PERIPH_ID_NANDSPEED, + PERIPH_ID_I2CSLOW, + PERIPH_ID_DSIB, + PERIPH_ID_RESERVED83, + PERIPH_ID_IRAMA, + PERIPH_ID_IRAMB, + PERIPH_ID_IRAMC, + PERIPH_ID_IRAMD, + + /* 88 */ + PERIPH_ID_CRAM2, + PERIPH_ID_RESERVED89, + PERIPH_ID_MDOUBLER, + PERIPH_ID_RESERVED91, + PERIPH_ID_SUSOUT, + PERIPH_ID_RESERVED93, + PERIPH_ID_RESERVED94, + PERIPH_ID_RESERVED95, + + PERIPH_ID_VW_FIRST, + /* V word: 31:0 */ + PERIPH_ID_CPUG = PERIPH_ID_VW_FIRST, + PERIPH_ID_CPULP, + PERIPH_ID_3D2, + PERIPH_ID_MSELECT, + PERIPH_ID_TSENSOR, + PERIPH_ID_I2S3, + PERIPH_ID_I2S4, + PERIPH_ID_I2C4, + + /* 08 */ + PERIPH_ID_SBC5, + PERIPH_ID_SBC6, + PERIPH_ID_AUDIO, + PERIPH_ID_APBIF, + PERIPH_ID_DAM0, + PERIPH_ID_DAM1, + PERIPH_ID_DAM2, + PERIPH_ID_HDA2CODEC2X, + + /* 16 */ + PERIPH_ID_ATOMICS, + PERIPH_ID_EX_RESERVED17, + PERIPH_ID_EX_RESERVED18, + PERIPH_ID_EX_RESERVED19, + PERIPH_ID_EX_RESERVED20, + PERIPH_ID_EX_RESERVED21, + PERIPH_ID_EX_RESERVED22, + PERIPH_ID_ACTMON, + + /* 24 */ + PERIPH_ID_EX_RESERVED24, + PERIPH_ID_EX_RESERVED25, + PERIPH_ID_EX_RESERVED26, + PERIPH_ID_EX_RESERVED27, + PERIPH_ID_SATA, + PERIPH_ID_HDA, + PERIPH_ID_EX_RESERVED30, + PERIPH_ID_EX_RESERVED31, + + /* W word: 31:0 */ + PERIPH_ID_HDA2HDMICODEC, + PERIPH_ID_SATACOLD, + PERIPH_ID_RESERVED0_PCIERX0, + PERIPH_ID_RESERVED1_PCIERX1, + PERIPH_ID_RESERVED2_PCIERX2, + PERIPH_ID_RESERVED3_PCIERX3, + PERIPH_ID_RESERVED4_PCIERX4, + PERIPH_ID_RESERVED5_PCIERX5, + + /* 40 */ + PERIPH_ID_CEC, + PERIPH_ID_RESERVED6_PCIE2, + PERIPH_ID_RESERVED7_EMC, + PERIPH_ID_RESERVED8_HDMI, + PERIPH_ID_RESERVED9_SATA, + PERIPH_ID_RESERVED10_MIPI, + PERIPH_ID_EX_RESERVED46, + PERIPH_ID_EX_RESERVED47, + + PERIPH_ID_COUNT, + PERIPH_ID_NONE = -1, +}; + +enum pll_out_id { + PLL_OUT1, + PLL_OUT2, + PLL_OUT3, + PLL_OUT4 +}; + +/* + * Clock peripheral IDs which sadly don't match up with PERIPH_ID. we want + * callers to use the PERIPH_ID for all access to peripheral clocks to avoid + * confusion bewteen PERIPH_ID_... and PERIPHC_... + * + * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be + * confusing. + */ +enum periphc_internal_id { + /* 0x00 */ + PERIPHC_I2S1, + PERIPHC_I2S2, + PERIPHC_SPDIF_OUT, + PERIPHC_SPDIF_IN, + PERIPHC_PWM, + PERIPHC_05h, + PERIPHC_SBC2, + PERIPHC_SBC3, + + /* 0x08 */ + PERIPHC_08h, + PERIPHC_I2C1, + PERIPHC_DVC_I2C, + PERIPHC_0bh, + PERIPHC_0ch, + PERIPHC_SBC1, + PERIPHC_DISP1, + PERIPHC_DISP2, + + /* 0x10 */ + PERIPHC_CVE, + PERIPHC_11h, + PERIPHC_VI, + PERIPHC_13h, + PERIPHC_SDMMC1, + PERIPHC_SDMMC2, + PERIPHC_G3D, + PERIPHC_G2D, + + /* 0x18 */ + PERIPHC_NDFLASH, + PERIPHC_SDMMC4, + PERIPHC_VFIR, + PERIPHC_EPP, + PERIPHC_MPE, + PERIPHC_MIPI, + PERIPHC_UART1, + PERIPHC_UART2, + + /* 0x20 */ + PERIPHC_HOST1X, + PERIPHC_21h, + PERIPHC_TVO, + PERIPHC_HDMI, + PERIPHC_24h, + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_EMC, + + /* 0x28 */ + PERIPHC_UART3, + PERIPHC_29h, + PERIPHC_VI_SENSOR, + PERIPHC_2bh, + PERIPHC_2ch, + PERIPHC_SBC4, + PERIPHC_I2C3, + PERIPHC_SDMMC3, + + /* 0x30 */ + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_VDE, + PERIPHC_OWR, + PERIPHC_NOR, + PERIPHC_CSITE, + PERIPHC_I2S0, + PERIPHC_37h, + + PERIPHC_VW_FIRST, + /* 0x38 */ + PERIPHC_G3D2 = PERIPHC_VW_FIRST, + PERIPHC_MSELECT, + PERIPHC_TSENSOR, + PERIPHC_I2S3, + PERIPHC_I2S4, + PERIPHC_I2C4, + PERIPHC_SBC5, + PERIPHC_SBC6, + + /* 0x40 */ + PERIPHC_AUDIO, + PERIPHC_41h, + PERIPHC_DAM0, + PERIPHC_DAM1, + PERIPHC_DAM2, + PERIPHC_HDA2CODEC2X, + PERIPHC_ACTMON, + PERIPHC_EXTPERIPH1, + + /* 0x48 */ + PERIPHC_EXTPERIPH2, + PERIPHC_EXTPERIPH3, + PERIPHC_NANDSPEED, + PERIPHC_I2CSLOW, + PERIPHC_SYS, + PERIPHC_SPEEDO, + PERIPHC_4eh, + PERIPHC_4fh, + + /* 0x50 */ + PERIPHC_SATAOOB, + PERIPHC_SATA, + PERIPHC_HDA, + + PERIPHC_COUNT, + + PERIPHC_NONE = -1, +}; + +/* Converts a clock number to a clock register: 0=L, 1=H, 2=U, 0=V, 1=W */ +#define PERIPH_REG(id) \ + (id < PERIPH_ID_VW_FIRST) ? \ + ((id) >> 5) : ((id - PERIPH_ID_VW_FIRST) >> 5) + +/* Mask value for a clock (within PERIPH_REG(id)) */ +#define PERIPH_MASK(id) (1 << ((id) & 0x1f)) + +/* return 1 if a PLL ID is in range */ +#define clock_id_is_pll(id) ((id) >= CLOCK_ID_FIRST && (id) < CLOCK_ID_COUNT) + +/* return 1 if a peripheral ID is in range */ +#define clock_periph_id_isvalid(id) ((id) >= PERIPH_ID_FIRST && \ + (id) < PERIPH_ID_COUNT) + +#endif /* _TEGRA30_CLOCK_TABLES_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/clock.h b/arch/arm/include/asm/arch-tegra30/clock.h new file mode 100644 index 0000000..61fc4c8 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/clock.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010-2012, 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/. + */ + +/* Tegra30 clock control functions */ + +#ifndef _TEGRA30_CLOCK_H_ +#define _TEGRA30_CLOCK_H_ + +#include <asm/arch-tegra/clock.h> + +#endif /* _TEGRA30_CLOCK_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/emc.h b/arch/arm/include/asm/arch-tegra30/emc.h new file mode 100644 index 0000000..16b9ae0 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/emc.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010-2012, 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 _TEGRA30_EMC_H_ +#define _TEGRA30_EMC_H_ + +#include <asm/types.h> + +#define TEGRA_EMC_NUM_REGS 46 + +/* EMC Registers */ +struct emc_ctlr { + u32 cfg; /* 0x00: EMC_CFG */ + u32 reserved0[3]; /* 0x04 ~ 0x0C */ + u32 adr_cfg; /* 0x10: EMC_ADR_CFG */ + u32 adr_cfg1; /* 0x14: EMC_ADR_CFG_1 */ + u32 reserved1[2]; /* 0x18 ~ 0x18 */ + u32 refresh_ctrl; /* 0x20: EMC_REFCTRL */ + u32 pin; /* 0x24: EMC_PIN */ + u32 timing_ctrl; /* 0x28: EMC_TIMING_CONTROL */ + u32 rc; /* 0x2C: EMC_RC */ + u32 rfc; /* 0x30: EMC_RFC */ + u32 ras; /* 0x34: EMC_RAS */ + u32 rp; /* 0x38: EMC_RP */ + u32 r2w; /* 0x3C: EMC_R2W */ + u32 w2r; /* 0x40: EMC_W2R */ + u32 r2p; /* 0x44: EMC_R2P */ + u32 w2p; /* 0x48: EMC_W2P */ + u32 rd_rcd; /* 0x4C: EMC_RD_RCD */ + u32 wd_rcd; /* 0x50: EMC_WD_RCD */ + u32 rrd; /* 0x54: EMC_RRD */ + u32 rext; /* 0x58: EMC_REXT */ + u32 wdv; /* 0x5C: EMC_WDV */ + u32 quse; /* 0x60: EMC_QUSE */ + u32 qrst; /* 0x64: EMC_QRST */ + u32 qsafe; /* 0x68: EMC_QSAFE */ + u32 rdv; /* 0x6C: EMC_RDV */ + u32 refresh; /* 0x70: EMC_REFRESH */ + u32 burst_refresh_num; /* 0x74: EMC_BURST_REFRESH_NUM */ + u32 pdex2wr; /* 0x78: EMC_PDEX2WR */ + u32 pdex2rd; /* 0x7c: EMC_PDEX2RD */ + u32 pchg2pden; /* 0x80: EMC_PCHG2PDEN */ + u32 act2pden; /* 0x84: EMC_ACT2PDEN */ + u32 ar2pden; /* 0x88: EMC_AR2PDEN */ + u32 rw2pden; /* 0x8C: EMC_RW2PDEN */ + u32 txsr; /* 0x90: EMC_TXSR */ + u32 tcke; /* 0x94: EMC_TCKE */ + u32 tfaw; /* 0x98: EMC_TFAW */ + u32 trpab; /* 0x9C: EMC_TRPAB */ + u32 tclkstable; /* 0xA0: EMC_TCLKSTABLE */ + u32 tclkstop; /* 0xA4: EMC_TCLKSTOP */ + u32 trefbw; /* 0xA8: EMC_TREFBW */ + u32 quse_extra; /* 0xAC: EMC_QUSE_EXTRA */ + u32 odt_write; /* 0xB0: EMC_ODT_WRITE */ + u32 odt_read; /* 0xB4: EMC_ODT_READ */ + u32 reserved2[5]; /* 0xB8 ~ 0xC8 */ + u32 mrs; /* 0xCC: EMC_MRS */ + u32 emrs; /* 0xD0: EMC_EMRS */ + u32 ref; /* 0xD4: EMC_REF */ + u32 pre; /* 0xD8: EMC_PRE */ + u32 nop; /* 0xDC: EMC_NOP */ + u32 self_ref; /* 0xE0: EMC_SELF_REF */ + u32 dpd; /* 0xE4: EMC_DPD */ + u32 mrw; /* 0xE8: EMC_MRW */ + u32 mrr; /* 0xEC: EMC_MRR */ + u32 reserved3; /* 0xF0: */ + u32 fbio_cfg1; /* 0xF4: EMC_FBIO_CFG1 */ + u32 fbio_dqsib_dly; /* 0xF8: EMC_FBIO_DQSIB_DLY */ + u32 fbio_dqsib_dly_msb; /* 0xFC: EMC_FBIO_DQSIB_DLY_MSG */ + u32 fbio_spare; /* 0x100: SBIO_SPARE */ + /* There are more registers ... */ +}; + +/** + * Set up the EMC for the given rate. The timing parameters are retrieved + * from the device tree "nvidia,tegra20-emc" node and its + * "nvidia,tegra20-emc-table" sub-nodes. + * + * @param blob Device tree blob + * @param rate Clock speed of memory controller in Hz (=2x memory bus rate) + * @return 0 if ok, else -ve error code (look in emc.c to decode it) + */ +int tegra_set_emc(const void *blob, unsigned rate); + +/** + * Get a pointer to the EMC controller from the device tree. + * + * @param blob Device tree blob + * @return pointer to EMC controller + */ +struct emc_ctlr *emc_get_controller(const void *blob); + +#endif /* _TEGRA30_EMC_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/flow.h b/arch/arm/include/asm/arch-tegra30/flow.h new file mode 100644 index 0000000..f5966a8 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/flow.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010-2012, 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 _TEGRA30_FLOW_H_ +#define _TEGRA30_FLOW_H_ + +struct flow_ctlr { + u32 halt_cpu_events; + u32 halt_cop_events; + u32 cpu_csr; + u32 cop_csr; + u32 xrq_events; + u32 halt_cpu1_events; + u32 cpu1_csr; + u32 halt_cpu2_events; + u32 cpu2_csr; + u32 halt_cpu3_events; + u32 cpu3_csr; + u32 cluster_control; +}; + +#endif /* _TEGRA30_FLOW_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/funcmux.h b/arch/arm/include/asm/arch-tegra30/funcmux.h new file mode 100644 index 0000000..7a30c27 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/funcmux.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010-2012, 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/. + */ + +/* Tegra high-level function multiplexing */ + +#ifndef _TEGRA30_FUNCMUX_H_ +#define _TEGRA30_FUNCMUX_H_ + +/* Configs supported by the func mux */ +enum { + FUNCMUX_DEFAULT = 0, /* default config */ + + /* UART configs */ + FUNCMUX_UART1_ULPI = 0, +}; + +/** + * Select a config for a particular peripheral. + * + * Each peripheral can operate through a number of configurations, + * which are sets of pins that it uses to bring out its signals. + * The basic config is 0, and higher numbers indicate different + * pinmux settings to bring the peripheral out on other pins, + * + * This function also disables tristate for the function's pins, + * so that they operate in normal mode. + * + * @param id Peripheral id + * @param config Configuration to use (FUNCMUX_...), 0 for default + * @return 0 if ok, -1 on error (e.g. incorrect id or config) + */ +int funcmux_select(enum periph_id id, int config); + +#endif /* _TEGRA30_FUNCMUX_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/gp_padctrl.h b/arch/arm/include/asm/arch-tegra30/gp_padctrl.h new file mode 100644 index 0000000..9b383d0 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/gp_padctrl.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010-2012, 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 _TEGRA30_GP_PADCTRL_H_ +#define _TEGRA30_GP_PADCTRL_H_ + +#include <asm/arch-tegra/gp_padctrl.h> + +/* APB_MISC_GP and padctrl registers */ +struct apb_misc_gp_ctlr { + u32 modereg; /* 0x00: APB_MISC_GP_MODEREG */ + u32 hidrev; /* 0x04: APB_MISC_GP_HIDREV */ + u32 reserved0[22]; /* 0x08 - 0x5C: */ + u32 emu_revid; /* 0x60: APB_MISC_GP_EMU_REVID */ + u32 xactor_scratch; /* 0x64: APB_MISC_GP_XACTOR_SCRATCH */ + u32 aocfg1; /* 0x68: APB_MISC_GP_AOCFG1PADCTRL */ + u32 aocfg2; /* 0x6c: APB_MISC_GP_AOCFG2PADCTRL */ + u32 atcfg1; /* 0x70: APB_MISC_GP_ATCFG1PADCTRL */ + u32 atcfg2; /* 0x74: APB_MISC_GP_ATCFG2PADCTRL */ + u32 atcfg3; /* 0x78: APB_MISC_GP_ATCFG3PADCTRL */ + u32 atcfg4; /* 0x7C: APB_MISC_GP_ATCFG4PADCTRL */ + u32 atcfg5; /* 0x80: APB_MISC_GP_ATCFG5PADCTRL */ + u32 cdev1cfg; /* 0x84: APB_MISC_GP_CDEV1CFGPADCTRL */ + u32 cdev2cfg; /* 0x88: APB_MISC_GP_CDEV2CFGPADCTRL */ + u32 csuscfg; /* 0x8C: APB_MISC_GP_CSUSCFGPADCTRL */ + u32 dap1cfg; /* 0x90: APB_MISC_GP_DAP1CFGPADCTRL */ + u32 dap2cfg; /* 0x94: APB_MISC_GP_DAP2CFGPADCTRL */ + u32 dap3cfg; /* 0x98: APB_MISC_GP_DAP3CFGPADCTRL */ + u32 dap4cfg; /* 0x9C: APB_MISC_GP_DAP4CFGPADCTRL */ + u32 dbgcfg; /* 0xA0: APB_MISC_GP_DBGCFGPADCTRL */ + u32 lcdcfg1; /* 0xA4: APB_MISC_GP_LCDCFG1PADCTRL */ + u32 lcdcfg2; /* 0xA8: APB_MISC_GP_LCDCFG2PADCTRL */ + u32 sdio2cfg; /* 0xAC: APB_MISC_GP_SDIO2CFGPADCTRL */ + u32 sdio3cfg; /* 0xB0: APB_MISC_GP_SDIO3CFGPADCTRL */ + u32 spicfg; /* 0xB4: APB_MISC_GP_SPICFGPADCTRL */ + u32 uaacfg; /* 0xB8: APB_MISC_GP_UAACFGPADCTRL */ + u32 uabcfg; /* 0xBC: APB_MISC_GP_UABCFGPADCTRL */ + u32 uart2cfg; /* 0xC0: APB_MISC_GP_UART2CFGPADCTRL */ + u32 uart3cfg; /* 0xC4: APB_MISC_GP_UART3CFGPADCTRL */ + u32 vicfg1; /* 0xC8: APB_MISC_GP_VICFG1PADCTRL */ + u32 vivttgen; /* 0xCC: APB_MISC_GP_VIVTTGENPADCTRL */ + u32 reserved1[7]; /* 0xD0-0xE8: */ + u32 sdio1cfg; /* 0xEC: APB_MISC_GP_SDIO1CFGPADCTRL */ +}; + +#endif /* _TEGRA30_GP_PADCTRL_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/gpio.h b/arch/arm/include/asm/arch-tegra30/gpio.h new file mode 100644 index 0000000..d0d16b4 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/gpio.h @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2010-2012, 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 _TEGRA30_GPIO_H_ +#define _TEGRA30_GPIO_H_ + +/* + * The Tegra 3x GPIO controller has 246 GPIOS in 8 banks of 4 ports, + * each with 8 GPIOs. + */ +#define TEGRA_GPIO_PORTS 4 /* number of ports per bank */ +#define TEGRA_GPIO_BANKS 8 /* number of banks */ + +#include <asm/arch-tegra/gpio.h> + +/* GPIO Controller registers for a single bank */ +struct gpio_ctlr_bank { + uint gpio_config[TEGRA_GPIO_PORTS]; + uint gpio_dir_out[TEGRA_GPIO_PORTS]; + uint gpio_out[TEGRA_GPIO_PORTS]; + uint gpio_in[TEGRA_GPIO_PORTS]; + uint gpio_int_status[TEGRA_GPIO_PORTS]; + uint gpio_int_enable[TEGRA_GPIO_PORTS]; + uint gpio_int_level[TEGRA_GPIO_PORTS]; + uint gpio_int_clear[TEGRA_GPIO_PORTS]; + uint gpio_masked_config[TEGRA_GPIO_PORTS]; + uint gpio_masked_dir_out[TEGRA_GPIO_PORTS]; + uint gpio_masked_out[TEGRA_GPIO_PORTS]; + uint gpio_masked_in[TEGRA_GPIO_PORTS]; + uint gpio_masked_int_status[TEGRA_GPIO_PORTS]; + uint gpio_masked_int_enable[TEGRA_GPIO_PORTS]; + uint gpio_masked_int_level[TEGRA_GPIO_PORTS]; + uint gpio_masked_int_clear[TEGRA_GPIO_PORTS]; +}; + +struct gpio_ctlr { + struct gpio_ctlr_bank gpio_bank[TEGRA_GPIO_BANKS]; +}; + +enum gpio_pin { + GPIO_PA0 = 0, /* pin 0 */ + GPIO_PA1, + GPIO_PA2, + GPIO_PA3, + GPIO_PA4, + GPIO_PA5, + GPIO_PA6, + GPIO_PA7, + GPIO_PB0, /* pin 8 */ + GPIO_PB1, + GPIO_PB2, + GPIO_PB3, + GPIO_PB4, + GPIO_PB5, + GPIO_PB6, + GPIO_PB7, + GPIO_PC0, /* pin 16 */ + GPIO_PC1, + GPIO_PC2, + GPIO_PC3, + GPIO_PC4, + GPIO_PC5, + GPIO_PC6, + GPIO_PC7, + GPIO_PD0, /* pin 24 */ + GPIO_PD1, + GPIO_PD2, + GPIO_PD3, + GPIO_PD4, + GPIO_PD5, + GPIO_PD6, + GPIO_PD7, + GPIO_PE0, /* pin 32 */ + GPIO_PE1, + GPIO_PE2, + GPIO_PE3, + GPIO_PE4, + GPIO_PE5, + GPIO_PE6, + GPIO_PE7, + GPIO_PF0, /* pin 40 */ + GPIO_PF1, + GPIO_PF2, + GPIO_PF3, + GPIO_PF4, + GPIO_PF5, + GPIO_PF6, + GPIO_PF7, + GPIO_PG0, /* pin 48 */ + GPIO_PG1, + GPIO_PG2, + GPIO_PG3, + GPIO_PG4, + GPIO_PG5, + GPIO_PG6, + GPIO_PG7, + GPIO_PH0, /* pin 56 */ + GPIO_PH1, + GPIO_PH2, + GPIO_PH3, + GPIO_PH4, + GPIO_PH5, + GPIO_PH6, + GPIO_PH7, + GPIO_PI0, /* pin 64 */ + GPIO_PI1, + GPIO_PI2, + GPIO_PI3, + GPIO_PI4, + GPIO_PI5, + GPIO_PI6, + GPIO_PI7, + GPIO_PJ0, /* pin 72 */ + GPIO_PJ1, + GPIO_PJ2, + GPIO_PJ3, + GPIO_PJ4, + GPIO_PJ5, + GPIO_PJ6, + GPIO_PJ7, + GPIO_PK0, /* pin 80 */ + GPIO_PK1, + GPIO_PK2, + GPIO_PK3, + GPIO_PK4, + GPIO_PK5, + GPIO_PK6, + GPIO_PK7, + GPIO_PL0, /* pin 88 */ + GPIO_PL1, + GPIO_PL2, + GPIO_PL3, + GPIO_PL4, + GPIO_PL5, + GPIO_PL6, + GPIO_PL7, + GPIO_PM0, /* pin 96 */ + GPIO_PM1, + GPIO_PM2, + GPIO_PM3, + GPIO_PM4, + GPIO_PM5, + GPIO_PM6, + GPIO_PM7, + GPIO_PN0, /* pin 104 */ + GPIO_PN1, + GPIO_PN2, + GPIO_PN3, + GPIO_PN4, + GPIO_PN5, + GPIO_PN6, + GPIO_PN7, + GPIO_PO0, /* pin 112 */ + GPIO_PO1, + GPIO_PO2, + GPIO_PO3, + GPIO_PO4, + GPIO_PO5, + GPIO_PO6, + GPIO_PO7, + GPIO_PP0, /* pin 120 */ + GPIO_PP1, + GPIO_PP2, + GPIO_PP3, + GPIO_PP4, + GPIO_PP5, + GPIO_PP6, + GPIO_PP7, + GPIO_PQ0, /* pin 128 */ + GPIO_PQ1, + GPIO_PQ2, + GPIO_PQ3, + GPIO_PQ4, + GPIO_PQ5, + GPIO_PQ6, + GPIO_PQ7, + GPIO_PR0, /* pin 136 */ + GPIO_PR1, + GPIO_PR2, + GPIO_PR3, + GPIO_PR4, + GPIO_PR5, + GPIO_PR6, + GPIO_PR7, + GPIO_PS0, /* pin 144 */ + GPIO_PS1, + GPIO_PS2, + GPIO_PS3, + GPIO_PS4, + GPIO_PS5, + GPIO_PS6, + GPIO_PS7, + GPIO_PT0, /* pin 152 */ + GPIO_PT1, + GPIO_PT2, + GPIO_PT3, + GPIO_PT4, + GPIO_PT5, + GPIO_PT6, + GPIO_PT7, + GPIO_PU0, /* pin 160 */ + GPIO_PU1, + GPIO_PU2, + GPIO_PU3, + GPIO_PU4, + GPIO_PU5, + GPIO_PU6, + GPIO_PU7, + GPIO_PV0, /* pin 168 */ + GPIO_PV1, + GPIO_PV2, + GPIO_PV3, + GPIO_PV4, + GPIO_PV5, + GPIO_PV6, + GPIO_PV7, + GPIO_PW0, /* pin 176 */ + GPIO_PW1, + GPIO_PW2, + GPIO_PW3, + GPIO_PW4, + GPIO_PW5, + GPIO_PW6, + GPIO_PW7, + GPIO_PX0, /* pin 184 */ + GPIO_PX1, + GPIO_PX2, + GPIO_PX3, + GPIO_PX4, + GPIO_PX5, + GPIO_PX6, + GPIO_PX7, + GPIO_PY0, /* pin 192 */ + GPIO_PY1, + GPIO_PY2, + GPIO_PY3, + GPIO_PY4, + GPIO_PY5, + GPIO_PY6, + GPIO_PY7, + GPIO_PZ0, /* pin 200 */ + GPIO_PZ1, + GPIO_PZ2, + GPIO_PZ3, + GPIO_PZ4, + GPIO_PZ5, + GPIO_PZ6, + GPIO_PZ7, + GPIO_PAA0, /* pin 208 */ + GPIO_PAA1, + GPIO_PAA2, + GPIO_PAA3, + GPIO_PAA4, + GPIO_PAA5, + GPIO_PAA6, + GPIO_PAA7, + GPIO_PBB0, /* pin 216 */ + GPIO_PBB1, + GPIO_PBB2, + GPIO_PBB3, + GPIO_PBB4, + GPIO_PBB5, + GPIO_PBB6, + GPIO_PBB7, + GPIO_PCC0, /* pin 224 */ + GPIO_PCC1, + GPIO_PCC2, + GPIO_PCC3, + GPIO_PCC4, + GPIO_PCC5, + GPIO_PCC6, + GPIO_PCC7, + GPIO_PDD0, /* pin 232 */ + GPIO_PDD1, + GPIO_PDD2, + GPIO_PDD3, + GPIO_PDD4, + GPIO_PDD5, + GPIO_PDD6, + GPIO_PDD7, + GPIO_PEE0, /* pin 240 */ + GPIO_PEE1, + GPIO_PEE2, + GPIO_PEE3, + GPIO_PEE4, + GPIO_PEE5, + GPIO_PEE6, + GPIO_PEE7, /* pin 247 */ +}; + +#endif /* _TEGRA30_GPIO_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/hardware.h b/arch/arm/include/asm/arch-tegra30/hardware.h new file mode 100644 index 0000000..b1a5aa9 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/hardware.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010-2012, 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 _TEGRA30_HARDWARE_H_ +#define _TEGRA30_HARDWARE_H_ + +/* include tegra specific hardware definitions */ + +#endif /* _TEGRA30-HARDWARE_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/pinmux-config-common.h b/arch/arm/include/asm/arch-tegra30/pinmux-config-common.h new file mode 100644 index 0000000..9fa3375 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/pinmux-config-common.h @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2010-2012, 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 _TEGRA30_PINMUX_CONFIG_COMMON_H_ +#define _TEGRA30_PINMUX_CONFIG_COMMON_H_ + +#define DEFAULT_PINMUX(_pingroup, _mux, _pull, _tri, _io) \ + { \ + .pingroup = PINGRP_##_pingroup, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_DEFAULT, \ + .od = PMUX_PIN_OD_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +#define I2C_PINMUX(_pingroup, _mux, _pull, _tri, _io, _lock, _od) \ + { \ + .pingroup = PINGRP_##_pingroup, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_##_lock, \ + .od = PMUX_PIN_OD_##_od, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +#define LV_PINMUX(_pingroup, _mux, _pull, _tri, _io, _lock, _ioreset) \ + { \ + .pingroup = PINGRP_##_pingroup, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_##_lock, \ + .od = PMUX_PIN_OD_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_##_ioreset \ + } + +static struct pingroup_config tegra3_pinmux_common[] = { + /* SDMMC1 pinmux */ + DEFAULT_PINMUX(SDMMC1_CLK, SDMMC1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_CMD, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT3, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT2, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT1, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT0, SDMMC1, UP, NORMAL, INPUT), + + /* SDMMC3 pinmux */ + DEFAULT_PINMUX(SDMMC3_CLK, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_CMD, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT0, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT1, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT2, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT3, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT6, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT7, RSVD1, NORMAL, NORMAL, INPUT), + + /* SDMMC4 pinmux */ + LV_PINMUX(SDMMC4_CLK, SDMMC4, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_CMD, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT0, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT1, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT2, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT3, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT4, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT5, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT6, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_RST_N, RSVD1, DOWN, NORMAL, INPUT, DISABLE, DISABLE), + + /* I2C1 pinmux */ + I2C_PINMUX(GEN1_I2C_SCL, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(GEN1_I2C_SDA, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C2 pinmux */ + I2C_PINMUX(GEN2_I2C_SCL, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(GEN2_I2C_SDA, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C3 pinmux */ + I2C_PINMUX(CAM_I2C_SCL, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(CAM_I2C_SDA, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C4 pinmux */ + I2C_PINMUX(DDC_SCL, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(DDC_SDA, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* Power I2C pinmux */ + I2C_PINMUX(PWR_I2C_SCL, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(PWR_I2C_SDA, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + DEFAULT_PINMUX(ULPI_DATA0, UARTA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(ULPI_DATA1, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA2, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA3, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA4, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA5, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA6, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA7, UARTA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(ULPI_CLK, UARTD, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(ULPI_DIR, UARTD, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_NXT, UARTD, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_STP, UARTD, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(DAP3_FS, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_DIN, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_DOUT, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_SCLK, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PV2, OWR, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GPIO_PV3, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(CLK2_OUT, EXTPERIPH2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK2_REQ, DAP, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PWR1, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PWR2, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_SDIN, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_SDOUT, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_WR_N, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_CS0_N, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_DC0, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_SCK, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PWR0, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PCLK, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_DE, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_HSYNC, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_VSYNC, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D0, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D1, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D2, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D3, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D4, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D5, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D6, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D7, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D8, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D9, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D10, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D11, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D12, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D13, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D14, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D15, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D16, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D17, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D18, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D19, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D20, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D21, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D22, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D23, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_CS1_N, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_M1, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_DC1, DISPA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CRT_HSYNC, CRT, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(CRT_VSYNC, CRT, NORMAL, NORMAL, OUTPUT), + LV_PINMUX(VI_D0, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D1, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D2, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D3, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D4, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D5, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D7, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D10, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_MCLK, VI, UP, NORMAL, INPUT, DISABLE, DISABLE), + DEFAULT_PINMUX(UART2_RXD, IRDA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART2_TXD, IRDA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(UART2_RTS_N, UARTB, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(UART2_CTS_N, UARTB, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_TXD, UARTC, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(UART3_RXD, UARTC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_CTS_N, UARTC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_RTS_N, UARTC, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GPIO_PU0, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PU1, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GPIO_PU2, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PU3, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PU4, PWM1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GPIO_PU5, PWM2, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GPIO_PU6, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_FS, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_DIN, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_DOUT, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_SCLK, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK3_OUT, EXTPERIPH3, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(CLK3_REQ, DEV3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_WP_N, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_CS2_N, RSVD1, UP, NORMAL, INPUT), /* EN_VDD_BL1 */ + DEFAULT_PINMUX(GMI_AD8, PWM0, NORMAL, NORMAL, OUTPUT), /* LCD1_BL_PWM */ + DEFAULT_PINMUX(GMI_AD10, NAND, NORMAL, NORMAL, OUTPUT), /* LCD1_BL_EN */ + DEFAULT_PINMUX(GMI_A16, SPI4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_A17, SPI4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_A18, SPI4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_A19, SPI4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CAM_MCLK, VI_ALT2, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PCC1, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PBB0, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PBB3, VGP3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PBB5, VGP5, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PBB6, VGP6, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PBB7, I2S4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PCC2, I2S4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(JTAG_RTCK, RTCK, NORMAL, NORMAL, OUTPUT), + + /* KBC keys */ + DEFAULT_PINMUX(KB_ROW0, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW1, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW2, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW3, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW4, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW5, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW6, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW7, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW8, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW9, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW10, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW11, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW12, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW13, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW14, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW15, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL0, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL1, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL2, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL3, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL4, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL5, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL6, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL7, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PV0, RSVD, UP, NORMAL, INPUT), + + DEFAULT_PINMUX(CLK_32K_OUT, BLINK, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(SYS_CLK_REQ, SYSCLK, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(OWR, OWR, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_FS, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_DIN, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_DOUT, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_SCLK, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK1_REQ, DAP, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK1_OUT, EXTPERIPH1, NORMAL, NORMAL, INPUT), +#ifdef CONFIG_SND_HDA_CODEC_REALTEK + DEFAULT_PINMUX(SPDIF_IN, DAP2, DOWN, NORMAL, INPUT), +#else + DEFAULT_PINMUX(SPDIF_IN, SPDIF, NORMAL, NORMAL, INPUT), +#endif + DEFAULT_PINMUX(SPDIF_OUT, SPDIF, NORMAL, NORMAL, OUTPUT), +#ifdef CONFIG_SND_HDA_CODEC_REALTEK + DEFAULT_PINMUX(DAP2_FS, HDA, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_DIN, HDA, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_DOUT, HDA, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_SCLK, HDA, DOWN, NORMAL, INPUT), +#else + DEFAULT_PINMUX(DAP2_FS, I2S1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_DIN, I2S1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_DOUT, I2S1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_SCLK, I2S1, NORMAL, NORMAL, INPUT), +#endif + DEFAULT_PINMUX(SPI2_CS1_N, SPI2, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_MOSI, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_SCK, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_CS0_N, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_MISO, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L0_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L0_RST_N, PCIE, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PEX_L0_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_WAKE_N, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L1_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L1_RST_N, PCIE, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PEX_L1_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L2_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L2_RST_N, PCIE, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PEX_L2_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(HDMI_CEC, CEC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(HDMI_INT, RSVD0, NORMAL, TRISTATE, INPUT), + + /* Gpios */ + /* SDMMC1 CD gpio */ + DEFAULT_PINMUX(GMI_IORDY, RSVD1, UP, NORMAL, INPUT), + /* SDMMC1 WP gpio */ + LV_PINMUX(VI_D11, RSVD1, UP, NORMAL, INPUT, DISABLE, DISABLE), + + /* Touch panel GPIO */ + /* Touch IRQ */ + DEFAULT_PINMUX(GMI_AD12, NAND, UP, NORMAL, INPUT), + + /* Touch RESET */ + DEFAULT_PINMUX(GMI_AD14, NAND, NORMAL, NORMAL, OUTPUT), + + /* Power rails GPIO */ + DEFAULT_PINMUX(SPI2_SCK, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GPIO_PBB4, VGP4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW8, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT5, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT4, SDMMC3, UP, NORMAL, INPUT), + + LV_PINMUX(VI_D6, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D8, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D9, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_PCLK, RSVD1, UP, TRISTATE, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_HSYNC, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_VSYNC, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), +}; + +static struct pingroup_config unused_pins_lowpower[] = { + DEFAULT_PINMUX(GMI_WAIT, NAND, UP, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_ADV_N, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_CLK, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_CS3_N, NAND, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_CS7_N, NAND, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_AD0, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD1, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD2, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD3, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD4, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD5, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD6, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD7, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD9, PWM1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_AD11, NAND, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_AD13, NAND, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_WR_N, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_OE_N, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_DQS, NAND, NORMAL, TRISTATE, OUTPUT), +}; + +#endif /* _TEGRA30_PINMUX_CONFIG_COMMON_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/pinmux.h b/arch/arm/include/asm/arch-tegra30/pinmux.h new file mode 100644 index 0000000..e169c49 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/pinmux.h @@ -0,0 +1,603 @@ +/* + * Copyright (c) 2010-2012, 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 _TEGRA30_PINMUX_H_ +#define _TEGRA30_PINMUX_H_ + +/* + * Pin groups which we adjust. There are three basic attributes of each pin + * group which use this enum: + * + * - function + * - pullup / pulldown + * - tristate or normal + */ +enum pmux_pingrp { + PINGRP_ULPI_DATA0 = 0, /* offset 0x3000 */ + PINGRP_ULPI_DATA1, + PINGRP_ULPI_DATA2, + PINGRP_ULPI_DATA3, + PINGRP_ULPI_DATA4, + PINGRP_ULPI_DATA5, + PINGRP_ULPI_DATA6, + PINGRP_ULPI_DATA7, + PINGRP_ULPI_CLK, + PINGRP_ULPI_DIR, + PINGRP_ULPI_NXT, + PINGRP_ULPI_STP, + PINGRP_DAP3_FS, + PINGRP_DAP3_DIN, + PINGRP_DAP3_DOUT, + PINGRP_DAP3_SCLK, + PINGRP_GPIO_PV0, + PINGRP_GPIO_PV1, + PINGRP_SDMMC1_CLK, + PINGRP_SDMMC1_CMD, + PINGRP_SDMMC1_DAT3, + PINGRP_SDMMC1_DAT2, + PINGRP_SDMMC1_DAT1, + PINGRP_SDMMC1_DAT0, + PINGRP_GPIO_PV2, + PINGRP_GPIO_PV3, + PINGRP_CLK2_OUT, + PINGRP_CLK2_REQ, + PINGRP_LCD_PWR1, + PINGRP_LCD_PWR2, + PINGRP_LCD_SDIN, + PINGRP_LCD_SDOUT, + PINGRP_LCD_WR_N, + PINGRP_LCD_CS0_N, + PINGRP_LCD_DC0, + PINGRP_LCD_SCK, + PINGRP_LCD_PWR0, + PINGRP_LCD_PCLK, + PINGRP_LCD_DE, + PINGRP_LCD_HSYNC, + PINGRP_LCD_VSYNC, + PINGRP_LCD_D0, + PINGRP_LCD_D1, + PINGRP_LCD_D2, + PINGRP_LCD_D3, + PINGRP_LCD_D4, + PINGRP_LCD_D5, + PINGRP_LCD_D6, + PINGRP_LCD_D7, + PINGRP_LCD_D8, + PINGRP_LCD_D9, + PINGRP_LCD_D10, + PINGRP_LCD_D11, + PINGRP_LCD_D12, + PINGRP_LCD_D13, + PINGRP_LCD_D14, + PINGRP_LCD_D15, + PINGRP_LCD_D16, + PINGRP_LCD_D17, + PINGRP_LCD_D18, + PINGRP_LCD_D19, + PINGRP_LCD_D20, + PINGRP_LCD_D21, + PINGRP_LCD_D22, + PINGRP_LCD_D23, + PINGRP_LCD_CS1_N, + PINGRP_LCD_M1, + PINGRP_LCD_DC1, + PINGRP_HDMI_INT, + PINGRP_DDC_SCL, + PINGRP_DDC_SDA, + PINGRP_CRT_HSYNC, + PINGRP_CRT_VSYNC, + PINGRP_VI_D0, + PINGRP_VI_D1, + PINGRP_VI_D2, + PINGRP_VI_D3, + PINGRP_VI_D4, + PINGRP_VI_D5, + PINGRP_VI_D6, + PINGRP_VI_D7, + PINGRP_VI_D8, + PINGRP_VI_D9, + PINGRP_VI_D10, + PINGRP_VI_D11, + PINGRP_VI_PCLK, + PINGRP_VI_MCLK, + PINGRP_VI_VSYNC, + PINGRP_VI_HSYNC, + PINGRP_UART2_RXD, + PINGRP_UART2_TXD, + PINGRP_UART2_RTS_N, + PINGRP_UART2_CTS_N, + PINGRP_UART3_TXD, + PINGRP_UART3_RXD, + PINGRP_UART3_CTS_N, + PINGRP_UART3_RTS_N, + PINGRP_GPIO_PU0, + PINGRP_GPIO_PU1, + PINGRP_GPIO_PU2, + PINGRP_GPIO_PU3, + PINGRP_GPIO_PU4, + PINGRP_GPIO_PU5, + PINGRP_GPIO_PU6, + PINGRP_GEN1_I2C_SDA, + PINGRP_GEN1_I2C_SCL, + PINGRP_DAP4_FS, + PINGRP_DAP4_DIN, + PINGRP_DAP4_DOUT, + PINGRP_DAP4_SCLK, + PINGRP_CLK3_OUT, + PINGRP_CLK3_REQ, + PINGRP_GMI_WP_N, + PINGRP_GMI_IORDY, + PINGRP_GMI_WAIT, + PINGRP_GMI_ADV_N, + PINGRP_GMI_CLK, + PINGRP_GMI_CS0_N, + PINGRP_GMI_CS1_N, + PINGRP_GMI_CS2_N, + PINGRP_GMI_CS3_N, + PINGRP_GMI_CS4_N, + PINGRP_GMI_CS6_N, + PINGRP_GMI_CS7_N, + PINGRP_GMI_AD0, + PINGRP_GMI_AD1, + PINGRP_GMI_AD2, + PINGRP_GMI_AD3, + PINGRP_GMI_AD4, + PINGRP_GMI_AD5, + PINGRP_GMI_AD6, + PINGRP_GMI_AD7, + PINGRP_GMI_AD8, + PINGRP_GMI_AD9, + PINGRP_GMI_AD10, + PINGRP_GMI_AD11, + PINGRP_GMI_AD12, + PINGRP_GMI_AD13, + PINGRP_GMI_AD14, + PINGRP_GMI_AD15, + PINGRP_GMI_A16, + PINGRP_GMI_A17, + PINGRP_GMI_A18, + PINGRP_GMI_A19, + PINGRP_GMI_WR_N, + PINGRP_GMI_OE_N, + PINGRP_GMI_DQS, + PINGRP_GMI_RST_N, + PINGRP_GEN2_I2C_SCL, + PINGRP_GEN2_I2C_SDA, + PINGRP_SDMMC4_CLK, + PINGRP_SDMMC4_CMD, + PINGRP_SDMMC4_DAT0, + PINGRP_SDMMC4_DAT1, + PINGRP_SDMMC4_DAT2, + PINGRP_SDMMC4_DAT3, + PINGRP_SDMMC4_DAT4, + PINGRP_SDMMC4_DAT5, + PINGRP_SDMMC4_DAT6, + PINGRP_SDMMC4_DAT7, + PINGRP_SDMMC4_RST_N, + PINGRP_CAM_MCLK, + PINGRP_GPIO_PCC1, + PINGRP_GPIO_PBB0, + PINGRP_CAM_I2C_SCL, + PINGRP_CAM_I2C_SDA, + PINGRP_GPIO_PBB3, + PINGRP_GPIO_PBB4, + PINGRP_GPIO_PBB5, + PINGRP_GPIO_PBB6, + PINGRP_GPIO_PBB7, + PINGRP_GPIO_PCC2, + PINGRP_JTAG_RTCK, + PINGRP_PWR_I2C_SCL, + PINGRP_PWR_I2C_SDA, + PINGRP_KB_ROW0, + PINGRP_KB_ROW1, + PINGRP_KB_ROW2, + PINGRP_KB_ROW3, + PINGRP_KB_ROW4, + PINGRP_KB_ROW5, + PINGRP_KB_ROW6, + PINGRP_KB_ROW7, + PINGRP_KB_ROW8, + PINGRP_KB_ROW9, + PINGRP_KB_ROW10, + PINGRP_KB_ROW11, + PINGRP_KB_ROW12, + PINGRP_KB_ROW13, + PINGRP_KB_ROW14, + PINGRP_KB_ROW15, + PINGRP_KB_COL0, + PINGRP_KB_COL1, + PINGRP_KB_COL2, + PINGRP_KB_COL3, + PINGRP_KB_COL4, + PINGRP_KB_COL5, + PINGRP_KB_COL6, + PINGRP_KB_COL7, + PINGRP_CLK_32K_OUT, + PINGRP_SYS_CLK_REQ, + PINGRP_CORE_PWR_REQ, + PINGRP_CPU_PWR_REQ, + PINGRP_PWR_INT_N, + PINGRP_CLK_32K_IN, + PINGRP_OWR, + PINGRP_DAP1_FS, + PINGRP_DAP1_DIN, + PINGRP_DAP1_DOUT, + PINGRP_DAP1_SCLK, + PINGRP_CLK1_REQ, + PINGRP_CLK1_OUT, + PINGRP_SPDIF_IN, + PINGRP_SPDIF_OUT, + PINGRP_DAP2_FS, + PINGRP_DAP2_DIN, + PINGRP_DAP2_DOUT, + PINGRP_DAP2_SCLK, + PINGRP_SPI2_MOSI, + PINGRP_SPI2_MISO, + PINGRP_SPI2_CS0_N, + PINGRP_SPI2_SCK, + PINGRP_SPI1_MOSI, + PINGRP_SPI1_SCK, + PINGRP_SPI1_CS0_N, + PINGRP_SPI1_MISO, + PINGRP_SPI2_CS1_N, + PINGRP_SPI2_CS2_N, + PINGRP_SDMMC3_CLK, + PINGRP_SDMMC3_CMD, + PINGRP_SDMMC3_DAT0, + PINGRP_SDMMC3_DAT1, + PINGRP_SDMMC3_DAT2, + PINGRP_SDMMC3_DAT3, + PINGRP_SDMMC3_DAT4, + PINGRP_SDMMC3_DAT5, + PINGRP_SDMMC3_DAT6, + PINGRP_SDMMC3_DAT7, + PINGRP_PEX_L0_PRSNT_N, + PINGRP_PEX_L0_RST_N, + PINGRP_PEX_L0_CLKREQ_N, + PINGRP_PEX_WAKE_N, + PINGRP_PEX_L1_PRSNT_N, + PINGRP_PEX_L1_RST_N, + PINGRP_PEX_L1_CLKREQ_N, + PINGRP_PEX_L2_PRSNT_N, + PINGRP_PEX_L2_RST_N, + PINGRP_PEX_L2_CLKREQ_N, + PINGRP_HDMI_CEC, /* offset 0x33e0 */ + PINGRP_COUNT, +}; + +enum pdrive_pingrp { + PDRIVE_PINGROUP_AO1 = 0, /* offset 0x868 */ + PDRIVE_PINGROUP_AO2, + PDRIVE_PINGROUP_AT1, + PDRIVE_PINGROUP_AT2, + PDRIVE_PINGROUP_AT3, + PDRIVE_PINGROUP_AT4, + PDRIVE_PINGROUP_AT5, + PDRIVE_PINGROUP_CDEV1, + PDRIVE_PINGROUP_CDEV2, + PDRIVE_PINGROUP_CSUS, + PDRIVE_PINGROUP_DAP1, + PDRIVE_PINGROUP_DAP2, + PDRIVE_PINGROUP_DAP3, + PDRIVE_PINGROUP_DAP4, + PDRIVE_PINGROUP_DBG, + PDRIVE_PINGROUP_LCD1, + PDRIVE_PINGROUP_LCD2, + PDRIVE_PINGROUP_SDIO2, + PDRIVE_PINGROUP_SDIO3, + PDRIVE_PINGROUP_SPI, + PDRIVE_PINGROUP_UAA, + PDRIVE_PINGROUP_UAB, + PDRIVE_PINGROUP_UART2, + PDRIVE_PINGROUP_UART3, + PDRIVE_PINGROUP_VI1 = 24, /* offset 0x8c8 */ + PDRIVE_PINGROUP_SDIO1 = 33, /* offset 0x8ec */ + PDRIVE_PINGROUP_CRT = 36, /* offset 0x8f8 */ + PDRIVE_PINGROUP_DDC, + PDRIVE_PINGROUP_GMA, + PDRIVE_PINGROUP_GMB, + PDRIVE_PINGROUP_GMC, + PDRIVE_PINGROUP_GMD, + PDRIVE_PINGROUP_GME, + PDRIVE_PINGROUP_GMF, + PDRIVE_PINGROUP_GMG, + PDRIVE_PINGROUP_GMH, + PDRIVE_PINGROUP_OWR, + PDRIVE_PINGROUP_UAD, + PDRIVE_PINGROUP_GPV, + PDRIVE_PINGROUP_DEV3 = 49, /* offset 0x92c */ + PDRIVE_PINGROUP_CEC = 52, /* offset 0x938 */ + PDRIVE_PINGROUP_COUNT, +}; + +/* + * Functions which can be assigned to each of the pin groups. The values here + * bear no relation to the values programmed into pinmux registers and are + * purely a convenience. The translation is done through a table search. + */ +enum pmux_func { + PMUX_FUNC_RSVD = 0x8000, + PMUX_FUNC_RSVD0 = PMUX_FUNC_RSVD, + PMUX_FUNC_RSVD1 = 0x8000, + PMUX_FUNC_RSVD2 = 0x8001, + PMUX_FUNC_RSVD3 = 0x8002, + PMUX_FUNC_RSVD4 = 0x8003, + PMUX_FUNC_BAD = 0x4000, /* Invalid! */ + PMUX_FUNC_NONE = 0, + + PMUX_FUNC_AHB_CLK, + PMUX_FUNC_APB_CLK, + PMUX_FUNC_AUDIO_SYNC, + PMUX_FUNC_CRT, + PMUX_FUNC_DAP1, + PMUX_FUNC_DAP2, + PMUX_FUNC_DAP3, + PMUX_FUNC_DAP4, + PMUX_FUNC_DAP5, + PMUX_FUNC_DISPA, + PMUX_FUNC_DISPB, + PMUX_FUNC_EMC_TEST0_DLL, + PMUX_FUNC_EMC_TEST1_DLL, + PMUX_FUNC_GMI, + PMUX_FUNC_GMI_INT, + PMUX_FUNC_HDMI, + PMUX_FUNC_I2C, + PMUX_FUNC_I2C1 = PMUX_FUNC_I2C, + PMUX_FUNC_I2C2, + PMUX_FUNC_I2C3, + PMUX_FUNC_IDE, + PMUX_FUNC_IRDA, + PMUX_FUNC_KBC, + PMUX_FUNC_MIO, + PMUX_FUNC_MIPI_HS, + PMUX_FUNC_NAND, + PMUX_FUNC_OSC, + PMUX_FUNC_OWR, + PMUX_FUNC_PCIE, + PMUX_FUNC_PLLA_OUT, + PMUX_FUNC_PLLC_OUT1, + PMUX_FUNC_PLLM_OUT1, + PMUX_FUNC_PLLP_OUT2, + PMUX_FUNC_PLLP_OUT3, + PMUX_FUNC_PLLP_OUT4, + PMUX_FUNC_PWM, + PMUX_FUNC_PWR_INTR, + PMUX_FUNC_PWR_ON, + PMUX_FUNC_RTCK, + PMUX_FUNC_SDIO1, + PMUX_FUNC_SDMMC1 = PMUX_FUNC_SDIO1, + PMUX_FUNC_SDIO2, + PMUX_FUNC_SDMMC2 = PMUX_FUNC_SDIO2, + PMUX_FUNC_SDIO3, + PMUX_FUNC_SDMMC3 = PMUX_FUNC_SDIO3, + PMUX_FUNC_SDIO4, + PMUX_FUNC_SDMMC4 = PMUX_FUNC_SDIO4, + PMUX_FUNC_SFLASH, + PMUX_FUNC_SPDIF, + PMUX_FUNC_SPI1, + PMUX_FUNC_SPI2, + PMUX_FUNC_SPI2_ALT, + PMUX_FUNC_SPI3, + PMUX_FUNC_SPI4, + PMUX_FUNC_TRACE, + PMUX_FUNC_TWC, + PMUX_FUNC_UARTA, + PMUX_FUNC_UARTB, + PMUX_FUNC_UARTC, + PMUX_FUNC_UARTD, + PMUX_FUNC_UARTE, + PMUX_FUNC_ULPI, + PMUX_FUNC_VI, + PMUX_FUNC_VI_SENSOR_CLK, + PMUX_FUNC_XIO, + PMUX_FUNC_BLINK, + PMUX_FUNC_CEC, + PMUX_FUNC_CLK12, + PMUX_FUNC_DAP, + PMUX_FUNC_DAPSDMMC2, + PMUX_FUNC_DDR, + PMUX_FUNC_DEV3, + PMUX_FUNC_DTV, + PMUX_FUNC_VI_ALT1, + PMUX_FUNC_VI_ALT2, + PMUX_FUNC_VI_ALT3, + PMUX_FUNC_EMC_DLL, + PMUX_FUNC_EXTPERIPH1, + PMUX_FUNC_EXTPERIPH2, + PMUX_FUNC_EXTPERIPH3, + PMUX_FUNC_GMI_ALT, + PMUX_FUNC_HDA, + PMUX_FUNC_HSI, + PMUX_FUNC_I2C4, + PMUX_FUNC_I2C5, + PMUX_FUNC_I2CPWR, + PMUX_FUNC_I2S0, + PMUX_FUNC_I2S1, + PMUX_FUNC_I2S2, + PMUX_FUNC_I2S3, + PMUX_FUNC_I2S4, + PMUX_FUNC_NAND_ALT, + PMUX_FUNC_POPSDIO4, + PMUX_FUNC_POPSDMMC4, + PMUX_FUNC_PWM0, + PMUX_FUNC_PWM1, + PMUX_FUNC_PWM2, + PMUX_FUNC_PWM3, + PMUX_FUNC_SATA, + PMUX_FUNC_SPI5, + PMUX_FUNC_SPI6, + PMUX_FUNC_SYSCLK, + PMUX_FUNC_VGP1, + PMUX_FUNC_VGP2, + PMUX_FUNC_VGP3, + PMUX_FUNC_VGP4, + PMUX_FUNC_VGP5, + PMUX_FUNC_VGP6, + PMUX_FUNC_SAFE, + + PMUX_FUNC_MAX, +}; + +/* return 1 if a pmux_func is in range */ +#define pmux_func_isvalid(func) ((((func) > 0) && ((func) < PMUX_FUNC_MAX)) || \ + (((func) >= PMUX_FUNC_RSVD0) && ((func) <= PMUX_FUNC_RSVD4))) + +/* return 1 if a pingrp is in range */ +#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PINGRP_COUNT)) + +/* The pullup/pulldown state of a pin group */ +enum pmux_pull { + PMUX_PULL_NORMAL = 0, + PMUX_PULL_DOWN, + PMUX_PULL_UP, +}; +/* return 1 if a pin_pupd_is in range */ +#define pmux_pin_pupd_isvalid(pupd) (((pupd) >= PMUX_PULL_NORMAL) && \ + ((pupd) <= PMUX_PULL_UP)) + +/* Defines whether a pin group is tristated or in normal operation */ +enum pmux_tristate { + PMUX_TRI_NORMAL = 0, + PMUX_TRI_TRISTATE = 1, +}; +/* return 1 if a pin_tristate_is in range */ +#define pmux_pin_tristate_isvalid(tristate) (((tristate) >= PMUX_TRI_NORMAL) \ + && ((tristate) <= PMUX_TRI_TRISTATE)) + +enum pmux_pin_io { + PMUX_PIN_OUTPUT = 0, + PMUX_PIN_INPUT = 1, +}; +/* return 1 if a pin_io_is in range */ +#define pmux_pin_io_isvalid(io) (((io) >= PMUX_PIN_OUTPUT) && \ + ((io) <= PMUX_PIN_INPUT)) + +enum pmux_pin_lock { + PMUX_PIN_LOCK_DEFAULT = 0, + PMUX_PIN_LOCK_DISABLE, + PMUX_PIN_LOCK_ENABLE, +}; +/* return 1 if a pin_lock is in range */ +#define pmux_pin_lock_isvalid(lock) (((lock) >= PMUX_PIN_LOCK_DEFAULT) && \ + ((lock) <= PMUX_PIN_LOCK_ENABLE)) + +enum pmux_pin_od { + PMUX_PIN_OD_DEFAULT = 0, + PMUX_PIN_OD_DISABLE, + PMUX_PIN_OD_ENABLE, +}; +/* return 1 if a pin_od is in range */ +#define pmux_pin_od_isvalid(od) (((od) >= PMUX_PIN_OD_DEFAULT) && \ + ((od) <= PMUX_PIN_OD_ENABLE)) + +enum pmux_pin_ioreset { + PMUX_PIN_IO_RESET_DEFAULT = 0, + PMUX_PIN_IO_RESET_DISABLE, + PMUX_PIN_IO_RESET_ENABLE, +}; +/* return 1 if a pin_ioreset_is in range */ +#define pmux_pin_ioreset_isvalid(ioreset) \ + (((ioreset) >= PMUX_PIN_IO_RESET_DEFAULT) && \ + ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE)) + +/* Available power domains used by pin groups */ +enum pmux_vddio { + PMUX_VDDIO_BB = 0, + PMUX_VDDIO_LCD, + PMUX_VDDIO_VI, + PMUX_VDDIO_UART, + PMUX_VDDIO_DDR, + PMUX_VDDIO_NAND, + PMUX_VDDIO_SYS, + PMUX_VDDIO_AUDIO, + PMUX_VDDIO_SD, + PMUX_VDDIO_CAM, + PMUX_VDDIO_GMI, + PMUX_VDDIO_PEXCTL, + PMUX_VDDIO_SDMMC1, + PMUX_VDDIO_SDMMC3, + PMUX_VDDIO_SDMMC4, + + PMUX_VDDIO_NONE +}; + +/* t30 pin drive group and pin mux registers */ +#define PDRIVE_PINGROUP_OFFSET (0x868 >> 2) +#define PMUX_OFFSET ((0x3000 >> 2) - PDRIVE_PINGROUP_OFFSET - \ + PDRIVE_PINGROUP_COUNT) +struct pmux_tri_ctlr { + uint pmt_reserved0; /* ABP_MISC_PP_ reserved offset 00 */ + uint pmt_reserved1; /* ABP_MISC_PP_ reserved offset 04 */ + uint pmt_strap_opt_a; /* _STRAPPING_OPT_A_0, offset 08 */ + uint pmt_reserved2; /* ABP_MISC_PP_ reserved offset 0C */ + uint pmt_reserved3; /* ABP_MISC_PP_ reserved offset 10 */ + uint pmt_reserved4[4]; /* _TRI_STATE_REG_A/B/C/D in t20 */ + uint pmt_cfg_ctl; /* _CONFIG_CTL_0, offset 24 */ + + uint pmt_reserved[528]; /* ABP_MISC_PP_ reserved offs 28-864 */ + + uint pmt_drive[PDRIVE_PINGROUP_COUNT]; /* pin drive grps offs 868 */ + uint pmt_reserved5[PMUX_OFFSET]; + uint pmt_ctl[PINGRP_COUNT]; /* mux/pupd/tri regs, offset 0x3000 */ +}; + +/* + * This defines the configuration for a pin, including the function assigned, + * pull up/down settings and tristate settings. Having set up one of these + * you can call pinmux_config_pingroup() to configure a pin in one step. Also + * available is pinmux_config_table() to configure a list of pins. + */ +struct pingroup_config { + enum pmux_pingrp pingroup; /* pin group PINGRP_... */ + enum pmux_func func; /* function to assign FUNC_... */ + enum pmux_pull pull; /* pull up/down/normal PMUX_PULL_...*/ + enum pmux_tristate tristate; /* tristate or normal PMUX_TRI_... */ + enum pmux_pin_io io; /* input or output PMUX_PIN_... */ + enum pmux_pin_lock lock; /* lock enable/disable PMUX_PIN... */ + enum pmux_pin_od od; /* open-drain or push-pull driver */ + enum pmux_pin_ioreset ioreset; /* input/output reset PMUX_PIN... */ +}; + +/* Set a pin group to tristate */ +void pinmux_tristate_enable(enum pmux_pingrp pin); + +/* Set a pin group to normal (non tristate) */ +void pinmux_tristate_disable(enum pmux_pingrp pin); + +/* Set the pull up/down feature for a pin group */ +void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd); + +/* Set the mux function for a pin group */ +void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func); + +/* Set the complete configuration for a pin group */ +void pinmux_config_pingroup(struct pingroup_config *config); + +/* Set a pin group to tristate or normal */ +void pinmux_set_tristate(enum pmux_pingrp pin, int enable); + +/* Set a pin group as input or output */ +void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io); + +/** + * Confiuure a list of pin groups + * + * @param config List of config items + * @param len Number of config items in list + */ +void pinmux_config_table(struct pingroup_config *config, int len); + +#endif /* _TEGRA30_PINMUX_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/pmu.h b/arch/arm/include/asm/arch-tegra30/pmu.h new file mode 100644 index 0000000..52bea29 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/pmu.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010-2012, 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 _TEGRA30_PMU_H_ +#define _TEGRA30_PMU_H_ + +/* Set core and CPU voltages to nominal levels */ +int pmu_set_nominal(void); + +#endif /* _TEGRA30_PMU_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/tegra.h b/arch/arm/include/asm/arch-tegra30/tegra.h new file mode 100644 index 0000000..46a7474 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/tegra.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010-2012, 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 _TEGRA30_H_ +#define _TEGRA30_H_ + +#define NV_PA_SDRAM_BASE 0x80000000 /* 0x80000000 for real T30 */ + +#include <asm/arch-tegra/tegra.h> + +#define BCT_ODMDATA_OFFSET 6116 /* 12 bytes from end of BCT */ + +#endif /* TEGRA30_H */

On 10/02/2012 04:45 PM, Tom Warren wrote:
Common Tegra files are in arch-tegra, shared between T20 and T30. Tegra30-specific headers are in arch-tegra30. Note that some of these will be filled in as more T30 support is added (drivers, WB/LP0 support, etc.).
diff --git a/arch/arm/include/asm/arch-tegra/gp_padctrl.h b/arch/arm/include/asm/arch-tegra/gp_padctrl.h
+/* bit fields definitions for APB_MISC_GP_HIDREV register */ +#define HIDREV_CHIPID_SHIFT 8 +#define HIDREV_CHIPID_MASK (0xff << HIDREV_CHIPID_SHIFT) +#define HIDREV_MAJORPREV_SHIFT 4 +#define HIDREV_MAJORPREV_MASK (0xf << HIDREV_MAJORPREV_SHIFT)
Patch 1 added the following:
#define GP_HIDREV 0x804
... to arch/arm/cpu/arm720t/tegra-common/cpu.h. I wonder if that line wouldn't be better place here, alongside the macros that allow you to use it?
diff --git a/arch/arm/include/asm/arch-tegra30/emc.h b/arch/arm/include/asm/arch-tegra30/emc.h
This file seems to be:
a) An exact duplicate of the Tegra20 file. Did the register layout really not change at all? That seems unlikely. If so, shouldn't the file be shared?
b) Not used by anything in this patch series, so shouldn't be needed.
c) Incorrect; struct emc_ctlr doesn't actually match the register layout for Tegra20 or Tegra30 (at least, offset 0 is interrupt status in HW in both chips, not cfg as in the struct). Some fields match though.
diff --git a/arch/arm/include/asm/arch-tegra30/funcmux.h b/arch/arm/include/asm/arch-tegra30/funcmux.h
+/**
- Select a config for a particular peripheral.
- Each peripheral can operate through a number of configurations,
- which are sets of pins that it uses to bring out its signals.
- The basic config is 0, and higher numbers indicate different
- pinmux settings to bring the peripheral out on other pins,
- This function also disables tristate for the function's pins,
- so that they operate in normal mode.
- @param id Peripheral id
- @param config Configuration to use (FUNCMUX_...), 0 for default
- @return 0 if ok, -1 on error (e.g. incorrect id or config)
- */
+int funcmux_select(enum periph_id id, int config);
That prototype is identical to Tegra20. Shouldn't there be a common funcmux.h that defines the prototype, either include from the SoC-specific file, or itself including the SoC-specific file? This is important since common code (stuff that's not specific to Tegra20 or Tegra30) calls this function, so it shouldn't be prototyped in multiple places (with associated possibility of divergence) even if the implementation is entirely separate for the two SoCs.
diff --git a/arch/arm/include/asm/arch-tegra30/gpio.h b/arch/arm/include/asm/arch-tegra30/gpio.h
- The Tegra 3x GPIO controller has 246 GPIOS in 8 banks of 4 ports,
- each with 8 GPIOs.
Extra space there after *.
diff --git a/arch/arm/include/asm/arch-tegra30/hardware.h b/arch/arm/include/asm/arch-tegra30/hardware.h
This file is empty except for comments. Is it really useful? The Tegra20 file is empty too.
diff --git a/arch/arm/include/asm/arch-tegra30/pinmux-config-common.h b/arch/arm/include/asm/arch-tegra30/pinmux-config-common.h
The content of this file presumably describes Cardhu (which revision?) Surely it should be in board/nvidia/cardhu/*.c?
diff --git a/arch/arm/include/asm/arch-tegra30/pinmux.h b/arch/arm/include/asm/arch-tegra30/pinmux.h
+/*
- Functions which can be assigned to each of the pin groups. The values here
- bear no relation to the values programmed into pinmux registers and are
- purely a convenience. The translation is done through a table search.
- */
+enum pmux_func {
- PMUX_FUNC_RSVD = 0x8000,
- PMUX_FUNC_RSVD0 = PMUX_FUNC_RSVD,
- PMUX_FUNC_BAD = 0x4000, /* Invalid! */
- PMUX_FUNC_NONE = 0,
I think all four of those should be deleted.
- PMUX_FUNC_I2C,
- PMUX_FUNC_I2C1 = PMUX_FUNC_I2C,
I don't think there's a need for duplicate names for any of these.

Stephen,
On Wed, Oct 3, 2012 at 1:31 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/02/2012 04:45 PM, Tom Warren wrote:
Common Tegra files are in arch-tegra, shared between T20 and T30. Tegra30-specific headers are in arch-tegra30. Note that some of these will be filled in as more T30 support is added (drivers, WB/LP0 support, etc.).
diff --git a/arch/arm/include/asm/arch-tegra/gp_padctrl.h b/arch/arm/include/asm/arch-tegra/gp_padctrl.h
+/* bit fields definitions for APB_MISC_GP_HIDREV register */ +#define HIDREV_CHIPID_SHIFT 8 +#define HIDREV_CHIPID_MASK (0xff << HIDREV_CHIPID_SHIFT) +#define HIDREV_MAJORPREV_SHIFT 4 +#define HIDREV_MAJORPREV_MASK (0xf << HIDREV_MAJORPREV_SHIFT)
Patch 1 added the following:
#define GP_HIDREV 0x804
... to arch/arm/cpu/arm720t/tegra-common/cpu.h. I wonder if that line wouldn't be better place here, alongside the macros that allow you to use it?
Sure, that would be better. The code that uses this in cpu.c was munged a few times and I may have added this in the wrong file.
diff --git a/arch/arm/include/asm/arch-tegra30/emc.h b/arch/arm/include/asm/arch-tegra30/emc.h
This file seems to be:
a) An exact duplicate of the Tegra20 file. Did the register layout really not change at all? That seems unlikely. If so, shouldn't the file be shared?
b) Not used by anything in this patch series, so shouldn't be needed.
c) Incorrect; struct emc_ctlr doesn't actually match the register layout for Tegra20 or Tegra30 (at least, offset 0 is interrupt status in HW in both chips, not cfg as in the struct). Some fields match though.
I'll revisit it in our internal U-Boot source. I tried to go through all the include files and make sure any not used on T30 initially were removed, but if it's used in a common file, I didn't want to add #if defined(CONFIG_TEGRA20) fencing if not necessary.
diff --git a/arch/arm/include/asm/arch-tegra30/funcmux.h b/arch/arm/include/asm/arch-tegra30/funcmux.h
+/**
- Select a config for a particular peripheral.
- Each peripheral can operate through a number of configurations,
- which are sets of pins that it uses to bring out its signals.
- The basic config is 0, and higher numbers indicate different
- pinmux settings to bring the peripheral out on other pins,
- This function also disables tristate for the function's pins,
- so that they operate in normal mode.
- @param id Peripheral id
- @param config Configuration to use (FUNCMUX_...), 0 for default
- @return 0 if ok, -1 on error (e.g. incorrect id or config)
- */
+int funcmux_select(enum periph_id id, int config);
That prototype is identical to Tegra20. Shouldn't there be a common funcmux.h that defines the prototype, either include from the SoC-specific file, or itself including the SoC-specific file? This is important since common code (stuff that's not specific to Tegra20 or Tegra30) calls this function, so it shouldn't be prototyped in multiple places (with associated possibility of divergence) even if the implementation is entirely separate for the two SoCs.
Yep, I can do that.
diff --git a/arch/arm/include/asm/arch-tegra30/gpio.h b/arch/arm/include/asm/arch-tegra30/gpio.h
- The Tegra 3x GPIO controller has 246 GPIOS in 8 banks of 4 ports,
- each with 8 GPIOs.
Extra space there after *.
diff --git a/arch/arm/include/asm/arch-tegra30/hardware.h b/arch/arm/include/asm/arch-tegra30/hardware.h
This file is empty except for comments. Is it really useful? The Tegra20 file is empty too
It's included from include/asm/hardware.h, which is included in 3 or so arm720t files, so it's mandatory. I hate empty files, but I don't see a way around it without polluting some arm720t files with #ifdef's. the integratorap_cm720t does the same thing.
diff --git a/arch/arm/include/asm/arch-tegra30/pinmux-config-common.h b/arch/arm/include/asm/arch-tegra30/pinmux-config-common.h
The content of this file presumably describes Cardhu (which revision?) Surely it should be in board/nvidia/cardhu/*.c?
On the previous review cycle (before I commonized Tegra files), this file lived in board/nvidia/cardhu, and I think it was Tom Rini (or maybe Simon) that pointed out that it had no 'cardhu' identifiers in it, so it should be moved to a more Tegra30-centric area, hence the move to arch-tegra30. Again, this is from our internal repo, and I don't believe there's any rev info in that file (except for commented-out tables that aren't used, so I removed them). I think it's valid to say this file is common to all Tegra30 builds, and additional sparse pinmux tables could be added in board files/areas for board-specific / rev-specific mux changes.
diff --git a/arch/arm/include/asm/arch-tegra30/pinmux.h b/arch/arm/include/asm/arch-tegra30/pinmux.h
+/*
- Functions which can be assigned to each of the pin groups. The values here
- bear no relation to the values programmed into pinmux registers and are
- purely a convenience. The translation is done through a table search.
- */
+enum pmux_func {
PMUX_FUNC_RSVD = 0x8000,
PMUX_FUNC_RSVD0 = PMUX_FUNC_RSVD,
PMUX_FUNC_BAD = 0x4000, /* Invalid! */
PMUX_FUNC_NONE = 0,
I think all four of those should be deleted.
I'll look into it after the pinmux table rewrite you pointed out.
PMUX_FUNC_I2C,
PMUX_FUNC_I2C1 = PMUX_FUNC_I2C,
I don't think there's a need for duplicate names for any of these.
I'll look into it.
Thanks,
Tom

On 10/03/2012 03:48 PM, Tom Warren wrote:
Stephen,
On Wed, Oct 3, 2012 at 1:31 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/02/2012 04:45 PM, Tom Warren wrote:
Common Tegra files are in arch-tegra, shared between T20 and T30. Tegra30-specific headers are in arch-tegra30. Note that some of these will be filled in as more T30 support is added (drivers, WB/LP0 support, etc.).
...
diff --git a/arch/arm/include/asm/arch-tegra30/emc.h b/arch/arm/include/asm/arch-tegra30/emc.h
This file seems to be:
a) An exact duplicate of the Tegra20 file. Did the register layout really not change at all? That seems unlikely. If so, shouldn't the file be shared?
b) Not used by anything in this patch series, so shouldn't be needed.
c) Incorrect; struct emc_ctlr doesn't actually match the register layout for Tegra20 or Tegra30 (at least, offset 0 is interrupt status in HW in both chips, not cfg as in the struct). Some fields match though.
I'll revisit it in our internal U-Boot source. I tried to go through all the include files and make sure any not used on T30 initially were removed, but if it's used in a common file, I didn't want to add #if defined(CONFIG_TEGRA20) fencing if not necessary.
Hmm. I guess this should be conditional on something like CONFIG_TEGRA_EMC irrespective of the new Tegra30 changes; I imagine any EMC-related code is quite optional even on Tegra20 where there is a driver coded up.
diff --git a/arch/arm/include/asm/arch-tegra30/gpio.h b/arch/arm/include/asm/arch-tegra30/gpio.h
- The Tegra 3x GPIO controller has 246 GPIOS in 8 banks of 4 ports,
- each with 8 GPIOs.
Extra space there after *.
diff --git a/arch/arm/include/asm/arch-tegra30/hardware.h b/arch/arm/include/asm/arch-tegra30/hardware.h
This file is empty except for comments. Is it really useful? The Tegra20 file is empty too
It's included from include/asm/hardware.h, which is included in 3 or so arm720t files, so it's mandatory. I hate empty files, but I don't see a way around it without polluting some arm720t files with #ifdef's. the integratorap_cm720t does the same thing.
OK, makes sense.
diff --git a/arch/arm/include/asm/arch-tegra30/pinmux-config-common.h b/arch/arm/include/asm/arch-tegra30/pinmux-config-common.h
The content of this file presumably describes Cardhu (which revision?) Surely it should be in board/nvidia/cardhu/*.c?
On the previous review cycle (before I commonized Tegra files), this file lived in board/nvidia/cardhu, and I think it was Tom Rini (or maybe Simon) that pointed out that it had no 'cardhu' identifiers in it, so it should be moved to a more Tegra30-centric area, hence the move to arch-tegra30. Again, this is from our internal repo, and I don't believe there's any rev info in that file (except for commented-out tables that aren't used, so I removed them). I think it's valid to say this file is common to all Tegra30 builds, and additional sparse pinmux tables could be added in board files/areas for board-specific / rev-specific mux changes.
Sorry, there's no way those tables aren't Cardhu-specific; they're picking specific pinmux options for all/many of the pins, and there's no reason in general to believe that every Tegra30 board will use the exact same pinmux setup.
In practice, I know that e.g. Waluigi and Beaver use a very similar pinmux, but I imagine there are some differences even there. So, chunks of the table could be re-used, but certainly not the whole thing. I think the best way forward here is to put this current file into the Cardhu directory, and then implement pinmux-from-device-tree before adding support for any other boards that need a different pinmux.

These are stripped down for bringup, They'll be filled out later to match-up with the kernel DT contents, and/or as devices are brought up (mmc, usb, spi, etc.).
Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/dts/tegra30.dtsi | 30 ++++++++++++++++++++++++++++++ board/nvidia/dts/tegra30-cardhu.dts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 0 deletions(-) create mode 100644 arch/arm/dts/tegra30.dtsi create mode 100644 board/nvidia/dts/tegra30-cardhu.dts
diff --git a/arch/arm/dts/tegra30.dtsi b/arch/arm/dts/tegra30.dtsi new file mode 100644 index 0000000..122c134 --- /dev/null +++ b/arch/arm/dts/tegra30.dtsi @@ -0,0 +1,30 @@ +/include/ "skeleton.dtsi" + +/ { + model = "NVIDIA Tegra30"; + compatible = "nvidia,tegra30"; + + clocks { + #address-cells = <1>; + #size-cells = <0>; + + osc: clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + }; + + gpio: gpio@6000d000 { + compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio"; + reg = <0x6000d000 0x1000>; + #gpio-cells = <2>; + gpio-controller; + }; + + serial@70006000 { + compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; + reg = <0x70006000 0x40>; + reg-shift = <2>; + status = "disabled"; + }; +}; diff --git a/board/nvidia/dts/tegra30-cardhu.dts b/board/nvidia/dts/tegra30-cardhu.dts new file mode 100644 index 0000000..68563e8 --- /dev/null +++ b/board/nvidia/dts/tegra30-cardhu.dts @@ -0,0 +1,35 @@ +/dts-v1/; + +/memreserve/ 0x1c000000 0x04000000; +/include/ ARCH_CPU_DTS + +/ { + model = "NVIDIA Cardhu"; + compatible = "nvidia,cardhu", "nvidia,tegra30"; + + aliases { + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0xc0000000>; + }; + + clocks { + clk_32k: clk_32k { + clock_frequency = <32000>; + }; + osc { + clock-frequency = <12000000>; + }; + }; + + clock@60006000 { + clocks = <&clk_32k &osc>; + }; + + serial@70006000 { + status = "ok"; + clock-frequency = < 216000000 >; + }; +};

Am Dienstag, den 02.10.2012, 15:45 -0700 schrieb Tom Warren:
These are stripped down for bringup, They'll be filled out later to match-up with the kernel DT contents, and/or as devices are brought up (mmc, usb, spi, etc.).
Signed-off-by: Tom Warren twarren@nvidia.com
arch/arm/dts/tegra30.dtsi | 30 ++++++++++++++++++++++++++++++ board/nvidia/dts/tegra30-cardhu.dts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 0 deletions(-) create mode 100644 arch/arm/dts/tegra30.dtsi create mode 100644 board/nvidia/dts/tegra30-cardhu.dts
diff --git a/arch/arm/dts/tegra30.dtsi b/arch/arm/dts/tegra30.dtsi new file mode 100644 index 0000000..122c134 --- /dev/null +++ b/arch/arm/dts/tegra30.dtsi @@ -0,0 +1,30 @@ +/include/ "skeleton.dtsi"
+/ {
- model = "NVIDIA Tegra30";
- compatible = "nvidia,tegra30";
- clocks {
#address-cells = <1>;
#size-cells = <0>;
osc: clock {
compatible = "fixed-clock";
#clock-cells = <0>;
};
- };
- gpio: gpio@6000d000 {
compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
reg = <0x6000d000 0x1000>;
#gpio-cells = <2>;
gpio-controller;
- };
- serial@70006000 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006000 0x40>;
reg-shift = <2>;
status = "disabled";
- };
+}; diff --git a/board/nvidia/dts/tegra30-cardhu.dts b/board/nvidia/dts/tegra30-cardhu.dts new file mode 100644 index 0000000..68563e8 --- /dev/null +++ b/board/nvidia/dts/tegra30-cardhu.dts @@ -0,0 +1,35 @@ +/dts-v1/;
+/memreserve/ 0x1c000000 0x04000000; +/include/ ARCH_CPU_DTS
+/ {
- model = "NVIDIA Cardhu";
- compatible = "nvidia,cardhu", "nvidia,tegra30";
- aliases {
- };
memory {
device_type = "memory";
reg = <0x80000000 0xc0000000>;
};
- clocks {
clk_32k: clk_32k {
clock_frequency = <32000>;
};
osc {
clock-frequency = <12000000>;
};
- };
- clock@60006000 {
clocks = <&clk_32k &osc>;
- };
Is this clock thing really needed? I don't think we are doing anything with those DT entries.
- serial@70006000 {
status = "ok";
clock-frequency = < 216000000 >;
- };
+};

Lucas,
On Tue, Oct 2, 2012 at 5:07 PM, Lucas Stach dev@lynxeye.de wrote:
Am Dienstag, den 02.10.2012, 15:45 -0700 schrieb Tom Warren:
These are stripped down for bringup, They'll be filled out later to match-up with the kernel DT contents, and/or as devices are brought up (mmc, usb, spi, etc.).
Signed-off-by: Tom Warren twarren@nvidia.com
arch/arm/dts/tegra30.dtsi | 30 ++++++++++++++++++++++++++++++ board/nvidia/dts/tegra30-cardhu.dts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 0 deletions(-) create mode 100644 arch/arm/dts/tegra30.dtsi create mode 100644 board/nvidia/dts/tegra30-cardhu.dts
diff --git a/arch/arm/dts/tegra30.dtsi b/arch/arm/dts/tegra30.dtsi new file mode 100644 index 0000000..122c134 --- /dev/null +++ b/arch/arm/dts/tegra30.dtsi @@ -0,0 +1,30 @@ +/include/ "skeleton.dtsi"
+/ {
model = "NVIDIA Tegra30";
compatible = "nvidia,tegra30";
clocks {
#address-cells = <1>;
#size-cells = <0>;
osc: clock {
compatible = "fixed-clock";
#clock-cells = <0>;
};
};
gpio: gpio@6000d000 {
compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
reg = <0x6000d000 0x1000>;
#gpio-cells = <2>;
gpio-controller;
};
serial@70006000 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006000 0x40>;
reg-shift = <2>;
status = "disabled";
};
+}; diff --git a/board/nvidia/dts/tegra30-cardhu.dts b/board/nvidia/dts/tegra30-cardhu.dts new file mode 100644 index 0000000..68563e8 --- /dev/null +++ b/board/nvidia/dts/tegra30-cardhu.dts @@ -0,0 +1,35 @@ +/dts-v1/;
+/memreserve/ 0x1c000000 0x04000000; +/include/ ARCH_CPU_DTS
+/ {
model = "NVIDIA Cardhu";
compatible = "nvidia,cardhu", "nvidia,tegra30";
aliases {
};
memory {
device_type = "memory";
reg = <0x80000000 0xc0000000>;
};
clocks {
clk_32k: clk_32k {
clock_frequency = <32000>;
};
osc {
clock-frequency = <12000000>;
};
};
clock@60006000 {
clocks = <&clk_32k &osc>;
};
Is this clock thing really needed? I don't think we are doing anything with those DT entries.
During bringup, I tried stripping down our internal DT files for Cardhu to the absolute minimum that'd still boot. AFAIR, clock entries were essential. Regardless, as periphs/drivers are brought up in future days, this'll all begin to grow.
Tom
serial@70006000 {
status = "ok";
clock-frequency = < 216000000 >;
};
+};

On 10/02/2012 04:45 PM, Tom Warren wrote:
These are stripped down for bringup, They'll be filled out later to match-up with the kernel DT contents, and/or as devices are brought up (mmc, usb, spi, etc.).
diff --git a/arch/arm/dts/tegra30.dtsi b/arch/arm/dts/tegra30.dtsi
+/include/ "skeleton.dtsi"
+/ {
- model = "NVIDIA Tegra30";
- compatible = "nvidia,tegra30";
- clocks {
#address-cells = <1>;
#size-cells = <0>;
osc: clock {
compatible = "fixed-clock";
#clock-cells = <0>;
};
- };
Nothing uses any of the clock stuff; I don't think we should add this until it's needed.
- gpio: gpio@6000d000 {
compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
reg = <0x6000d000 0x1000>;
#gpio-cells = <2>;
gpio-controller;
- };
Similarly, nothing uses this.
- serial@70006000 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006000 0x40>;
reg-shift = <2>;
This needs the following extra line here:
interrupts = <0 36 0x04>;
status = "disabled";
- };
Although again, nothing uses this, so may as well omit it.
diff --git a/board/nvidia/dts/tegra30-cardhu.dts b/board/nvidia/dts/tegra30-cardhu.dts new file mode 100644 index 0000000..68563e8 --- /dev/null +++ b/board/nvidia/dts/tegra30-cardhu.dts @@ -0,0 +1,35 @@ +/dts-v1/;
+/memreserve/ 0x1c000000 0x04000000; +/include/ ARCH_CPU_DTS
+/ {
- model = "NVIDIA Cardhu";
- compatible = "nvidia,cardhu", "nvidia,tegra30";
- aliases {
- };
May as well leave that out until it's needed.
memory {
device_type = "memory";
reg = <0x80000000 0xc0000000>;
};
There's an indentation error there.
- clocks {
clk_32k: clk_32k {
clock_frequency = <32000>;
};
osc {
clock-frequency = <12000000>;
};
- };
- clock@60006000 {
clocks = <&clk_32k &osc>;
- };
- serial@70006000 {
status = "ok";
clock-frequency = < 216000000 >;
- };
+};
Similarly, I don't think anything uses any of that.

Stephen,
On Wed, Oct 3, 2012 at 1:36 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/02/2012 04:45 PM, Tom Warren wrote:
These are stripped down for bringup, They'll be filled out later to match-up with the kernel DT contents, and/or as devices are brought up (mmc, usb, spi, etc.).
diff --git a/arch/arm/dts/tegra30.dtsi b/arch/arm/dts/tegra30.dtsi
+/include/ "skeleton.dtsi"
+/ {
model = "NVIDIA Tegra30";
compatible = "nvidia,tegra30";
clocks {
#address-cells = <1>;
#size-cells = <0>;
osc: clock {
compatible = "fixed-clock";
#clock-cells = <0>;
};
};
Nothing uses any of the clock stuff; I don't think we should add this until it's needed.
gpio: gpio@6000d000 {
compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
reg = <0x6000d000 0x1000>;
#gpio-cells = <2>;
gpio-controller;
};
Similarly, nothing uses this.
serial@70006000 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006000 0x40>;
reg-shift = <2>;
This needs the following extra line here:
interrupts = <0 36 0x04>;
status = "disabled";
};
Although again, nothing uses this, so may as well omit it.
diff --git a/board/nvidia/dts/tegra30-cardhu.dts b/board/nvidia/dts/tegra30-cardhu.dts new file mode 100644 index 0000000..68563e8 --- /dev/null +++ b/board/nvidia/dts/tegra30-cardhu.dts @@ -0,0 +1,35 @@ +/dts-v1/;
+/memreserve/ 0x1c000000 0x04000000; +/include/ ARCH_CPU_DTS
+/ {
model = "NVIDIA Cardhu";
compatible = "nvidia,cardhu", "nvidia,tegra30";
aliases {
};
May as well leave that out until it's needed.
memory {
device_type = "memory";
reg = <0x80000000 0xc0000000>;
};
There's an indentation error there.
clocks {
clk_32k: clk_32k {
clock_frequency = <32000>;
};
osc {
clock-frequency = <12000000>;
};
};
clock@60006000 {
clocks = <&clk_32k &osc>;
};
serial@70006000 {
status = "ok";
clock-frequency = < 216000000 >;
};
+};
Similarly, I don't think anything uses any of that.
I stripped these both down to bare minimums as per your review, and I can still build/boot on Cardhu. When I tried to remove some of these entries earlier (clock, etc.) I guess I wasn't editing _both_ files at the same time, so it would build or would hang.
Next rev will have truly minimal DT files. Thanks.

This patch adds basic Tegra30 (T30) build support - no specific board is targeted.
Signed-off-by: Tom Warren twarren@nvidia.com --- Makefile | 6 +++--- arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/start.S | 4 ++-- board/nvidia/common/board.c | 26 ++++++++++++++++++++++++-- include/serial.h | 2 +- spl/Makefile | 2 +- 6 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile index 614f6fe..d7e2c2f 100644 --- a/Makefile +++ b/Makefile @@ -323,7 +323,7 @@ endif ifeq ($(SOC),exynos) LIBS-y += $(CPUDIR)/s5p-common/libs5p-common.o endif -ifeq ($(SOC),tegra20) +ifneq ($(CONFIG_TEGRA),) LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o LIBS-y += arch/$(ARCH)/cpu/tegra-common/libcputegra-common.o LIBS-y += $(CPUDIR)/tegra-common/libtegra-common.o @@ -387,7 +387,7 @@ ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin
# enable combined SPL/u-boot/dtb rules for tegra -ifeq ($(SOC),tegra20) +ifneq ($(CONFIG_TEGRA),) ifeq ($(CONFIG_OF_SEPARATE),y) ALL-y += $(obj)u-boot-dtb-tegra.bin else @@ -494,7 +494,7 @@ $(obj)u-boot.spr: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin conv=notrunc 2>/dev/null cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@
-ifeq ($(SOC),tegra20) +ifneq ($(CONFIG_TEGRA),) ifeq ($(CONFIG_OF_SEPARATE),y) $(obj)u-boot-dtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin $(obj)u-boot.dtb $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_TEXT_BASE) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4fdbee4..ee8c2b3 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -32,7 +32,7 @@ COBJS += cache_v7.o COBJS += cpu.o COBJS += syslib.o
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),) +ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA),) SOBJS += lowlevel_init.o endif
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index f26308d..11317b0 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -272,12 +272,12 @@ jump_2_ram: /* * Move vector table */ -#if !defined(CONFIG_TEGRA20) +#if !defined(CONFIG_TEGRA) /* Set vector address in CP15 VBAR register */ ldr r0, =_start add r0, r0, r9 mcr p15, 0, r0, c12, c0, 0 @Set VBAR -#endif /* !Tegra20 */ +#endif /* !Tegra */
ldr r0, _board_init_r_ofs adr r1, _start diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c index 2c7cd0d..151d972 100644 --- a/board/nvidia/common/board.c +++ b/board/nvidia/common/board.c @@ -31,15 +31,20 @@ #include <asm/arch/pinmux.h> #include <asm/arch/pmu.h> #include <asm/arch/tegra.h> -#include <asm/arch/usb.h> #include <asm/arch-tegra/board.h> #include <asm/arch-tegra/clk_rst.h> #include <asm/arch-tegra/pmc.h> #include <asm/arch-tegra/sys_proto.h> #include <asm/arch-tegra/uart.h> #include <asm/arch-tegra/warmboot.h> -#include <spi.h> +#ifdef CONFIG_USB_EHCI_TEGRA +#include <asm/arch/usb.h> +#endif +#ifdef CONFIG_TEGRA30 +#include <asm/arch/pinmux-config-common.h> +#endif #include <i2c.h> +#include <spi.h> #include "emc.h"
DECLARE_GLOBAL_DATA_PTR; @@ -101,6 +106,21 @@ static void power_det_init(void) }
/* + * Routine: pinmux_init + * Description: Do individual peripheral pinmux configs + */ +static void pinmux_init(void) +{ +#if defined(CONFIG_TEGRA30) + pinmux_config_table(tegra3_pinmux_common, + ARRAY_SIZE(tegra3_pinmux_common)); + + pinmux_config_table(unused_pins_lowpower, + ARRAY_SIZE(unused_pins_lowpower)); +#endif +} + +/* * Routine: board_init * Description: Early hardware init. */ @@ -169,6 +189,8 @@ void gpio_early_init(void) __attribute__((weak, alias("__gpio_early_init")));
int board_early_init_f(void) { + pinmux_init(); + board_init_uart_f();
/* Initialize periph GPIOs */ diff --git a/include/serial.h b/include/serial.h index d76d6df..75d76e6 100644 --- a/include/serial.h +++ b/include/serial.h @@ -31,7 +31,7 @@ extern struct serial_device *default_serial_console(void); defined(CONFIG_MB86R0x) || defined(CONFIG_MPC5xxx) || \ defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) || \ defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) || \ - defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT) || \ + defined(CONFIG_TEGRA) || defined(CONFIG_SYS_COREBOOT) || \ defined(CONFIG_MICROBLAZE) extern struct serial_device serial0_device; extern struct serial_device serial1_device; diff --git a/spl/Makefile b/spl/Makefile index 8c6dcbd..7d6df9d 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -62,7 +62,7 @@ ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) LIBS-y += $(CPUDIR)/omap-common/libomap-common.o endif
-ifeq ($(SOC),tegra20) +ifneq ($(CONFIG_TEGRA),) LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o LIBS-y += arch/$(ARCH)/cpu/tegra-common/libcputegra-common.o LIBS-y += $(CPUDIR)/tegra-common/libtegra-common.o

On 10/02/2012 04:45 PM, Tom Warren wrote:
This patch adds basic Tegra30 (T30) build support - no specific board is targeted.
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
+#ifdef CONFIG_USB_EHCI_TEGRA +#include <asm/arch/usb.h> +#endif
That seems unrelated.
+#ifdef CONFIG_TEGRA30 +#include <asm/arch/pinmux-config-common.h> +#endif
...
/*
- Routine: pinmux_init
- Description: Do individual peripheral pinmux configs
- */
+static void pinmux_init(void) +{ +#if defined(CONFIG_TEGRA30)
- pinmux_config_table(tegra3_pinmux_common,
ARRAY_SIZE(tegra3_pinmux_common));
- pinmux_config_table(unused_pins_lowpower,
ARRAY_SIZE(unused_pins_lowpower));
+#endif +}
I think that should be done by the Cardhu board file, since the data is Cardhu-specific.

Stephen,
On Wed, Oct 3, 2012 at 1:38 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/02/2012 04:45 PM, Tom Warren wrote:
This patch adds basic Tegra30 (T30) build support - no specific board is targeted.
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
+#ifdef CONFIG_USB_EHCI_TEGRA +#include <asm/arch/usb.h> +#endif
That seems unrelated.
It's related because I don't have a usb.h file for Tegra30 yet (not used/needed), and this is a common file, so I have to #ifdef the inclusion or Cardhu won't build. I could put an empty usb.h file in arch-tegra30, but I don't like that approach and there's a need for this if someone turns off USB support in a Tegra20 build. The code further down in the file uses the same #ifdef.
+#ifdef CONFIG_TEGRA30 +#include <asm/arch/pinmux-config-common.h> +#endif
...
/*
- Routine: pinmux_init
- Description: Do individual peripheral pinmux configs
- */
+static void pinmux_init(void) +{ +#if defined(CONFIG_TEGRA30)
pinmux_config_table(tegra3_pinmux_common,
ARRAY_SIZE(tegra3_pinmux_common));
pinmux_config_table(unused_pins_lowpower,
ARRAY_SIZE(unused_pins_lowpower));
+#endif +}
I think that should be done by the Cardhu board file, since the data is Cardhu-specific.
If I move pinmux_init to cardhu.c, I'll need matching (empty) funcs in all the other board files, since it's called in board_early_init_f later in board.c. Or it could be made a weak function that's only overridden in cardhu files. But all this is more that I wanted to change in this first pass of T30/Cardhu support - I didn't want to touch any of the Tegra20 builds that I didn't have to.
Tom

On 10/03/2012 03:56 PM, Tom Warren wrote:
Stephen,
On Wed, Oct 3, 2012 at 1:38 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/02/2012 04:45 PM, Tom Warren wrote:
This patch adds basic Tegra30 (T30) build support - no specific board is targeted.
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
+#ifdef CONFIG_USB_EHCI_TEGRA +#include <asm/arch/usb.h> +#endif
That seems unrelated.
It's related because I don't have a usb.h file for Tegra30 yet (not used/needed), and this is a common file, so I have to #ifdef the inclusion or Cardhu won't build. I could put an empty usb.h file in arch-tegra30, but I don't like that approach and there's a need for this if someone turns off USB support in a Tegra20 build. The code further down in the file uses the same #ifdef.
Ah right, that makes sense.
+#ifdef CONFIG_TEGRA30 +#include <asm/arch/pinmux-config-common.h> +#endif
...
/*
- Routine: pinmux_init
- Description: Do individual peripheral pinmux configs
- */
+static void pinmux_init(void) +{ +#if defined(CONFIG_TEGRA30)
pinmux_config_table(tegra3_pinmux_common,
ARRAY_SIZE(tegra3_pinmux_common));
pinmux_config_table(unused_pins_lowpower,
ARRAY_SIZE(unused_pins_lowpower));
+#endif +}
I think that should be done by the Cardhu board file, since the data is Cardhu-specific.
If I move pinmux_init to cardhu.c, I'll need matching (empty) funcs in all the other board files, since it's called in board_early_init_f later in board.c. Or it could be made a weak function that's only overridden in cardhu files. But all this is more that I wanted to change in this first pass of T30/Cardhu support - I didn't want to touch any of the Tegra20 builds that I didn't have to.
A weak function certainly seems the way to go; all (or at least most of) the other per-device pinmux/GPIO setup functions are all implemented this way now.

This build is stripped down. It boots to the command prompt. GPIO is the only peripheral supported. Others TBD.
Signed-off-by: Tom Warren twarren@nvidia.com --- board/nvidia/{whistler => cardhu}/Makefile | 4 ++ .../cpu/cpu.c => board/nvidia/cardhu/cardhu.c | 8 ++-- boards.cfg | 1 + .../gp_padctrl.h => include/configs/cardhu.h | 37 +++++++++---- .../configs/{tegra20-common.h => tegra30-common.h} | 54 +++++--------------- 5 files changed, 48 insertions(+), 56 deletions(-) copy board/nvidia/{whistler => cardhu}/Makefile (94%) copy arch/microblaze/cpu/cpu.c => board/nvidia/cardhu/cardhu.c (88%) copy arch/arm/include/asm/arch-tegra/gp_padctrl.h => include/configs/cardhu.h (55%) copy include/configs/{tegra20-common.h => tegra30-common.h} (77%)
diff --git a/board/nvidia/whistler/Makefile b/board/nvidia/cardhu/Makefile similarity index 94% copy from board/nvidia/whistler/Makefile copy to board/nvidia/cardhu/Makefile index 913f1ce..a910577 100644 --- a/board/nvidia/whistler/Makefile +++ b/board/nvidia/cardhu/Makefile @@ -24,6 +24,10 @@
include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)../common) +endif + LIB = $(obj)lib$(BOARD).o
COBJS := $(BOARD).o diff --git a/arch/microblaze/cpu/cpu.c b/board/nvidia/cardhu/cardhu.c similarity index 88% copy from arch/microblaze/cpu/cpu.c copy to board/nvidia/cardhu/cardhu.c index 4d2b270..69b89db 100644 --- a/arch/microblaze/cpu/cpu.c +++ b/board/nvidia/cardhu/cardhu.c @@ -1,7 +1,6 @@ /* - * (C) Copyright 2004 Atmark Techno, Inc. - * - * Yasushi SHOJI yashi@atmark-techno.com + * (C) Copyright 2010-2012 + * NVIDIA Corporation <www.nvidia.com> * * See file CREDITS for list of people who contributed to this * project. @@ -22,4 +21,5 @@ * MA 02111-1307 USA */
-/* EMPTY FILE */ +#include <common.h> + diff --git a/boards.cfg b/boards.cfg index 4ae6656..7fb17ca 100644 --- a/boards.cfg +++ b/boards.cfg @@ -270,6 +270,7 @@ harmony arm armv7:arm720t harmony nvidia seaboard arm armv7:arm720t seaboard nvidia tegra20 ventana arm armv7:arm720t ventana nvidia tegra20 whistler arm armv7:arm720t whistler nvidia tegra20 +cardhu arm armv7:arm720t cardhu nvidia tegra30 u8500_href arm armv7 u8500 st-ericsson u8500 snowball arm armv7 snowball st-ericsson u8500 actux1_4_16 arm ixp actux1 - - actux1:FLASH2X2 diff --git a/arch/arm/include/asm/arch-tegra/gp_padctrl.h b/include/configs/cardhu.h similarity index 55% copy from arch/arm/include/asm/arch-tegra/gp_padctrl.h copy to include/configs/cardhu.h index d347e97..bfadbff 100644 --- a/arch/arm/include/asm/arch-tegra/gp_padctrl.h +++ b/include/configs/cardhu.h @@ -21,17 +21,32 @@ * MA 02111-1307 USA */
-#ifndef _TEGRA_GP_PADCTRL_H_ -#define _TEGRA_GP_PADCTRL_H_ +#ifndef __CONFIG_H +#define __CONFIG_H
-/* bit fields definitions for APB_MISC_GP_HIDREV register */ -#define HIDREV_CHIPID_SHIFT 8 -#define HIDREV_CHIPID_MASK (0xff << HIDREV_CHIPID_SHIFT) -#define HIDREV_MAJORPREV_SHIFT 4 -#define HIDREV_MAJORPREV_MASK (0xf << HIDREV_MAJORPREV_SHIFT) +#include <asm/sizes.h>
-/* CHIPID field returned from APB_MISC_GP_HIDREV register */ -#define CHIPID_TEGRA20 0x20 -#define CHIPID_TEGRA30 0x30 +#include "tegra30-common.h"
-#endif /* _TEGRA_GP_PADCTRL_H_ */ +/* Enable fdt support for Cardhu. Flash the image in u-boot-dtb.bin */ +#define CONFIG_DEFAULT_DEVICE_TREE tegra30-cardhu +#define CONFIG_OF_CONTROL +#define CONFIG_OF_SEPARATE + +/* High-level configuration options */ +#define V_PROMPT "Tegra30 (Cardhu) # " +#define CONFIG_TEGRA_BOARD_STRING "NVIDIA Cardhu" + +/* Board-specific serial config */ +#define CONFIG_SERIAL_MULTI +#define CONFIG_TEGRA_ENABLE_UARTA +#define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTA_BASE + +#define CONFIG_MACH_TYPE MACH_TYPE_CARDHU + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ENV_IS_NOWHERE + +#include "tegra-common-post.h" + +#endif /* __CONFIG_H */ diff --git a/include/configs/tegra20-common.h b/include/configs/tegra30-common.h similarity index 77% copy from include/configs/tegra20-common.h copy to include/configs/tegra30-common.h index 744dc59..d281b61 100644 --- a/include/configs/tegra20-common.h +++ b/include/configs/tegra30-common.h @@ -21,8 +21,8 @@ * MA 02111-1307 USA */
-#ifndef __TEGRA20_COMMON_H -#define __TEGRA20_COMMON_H +#ifndef __TEGRA30_COMMON_H +#define __TEGRA30_COMMON_H #include <asm/sizes.h>
/* @@ -37,7 +37,7 @@ * High Level Configuration Options */ #define CONFIG_ARMCORTEXA9 /* This is an ARM V7 CPU core */ -#define CONFIG_TEGRA20 /* in a NVidia Tegra20 core */ +#define CONFIG_TEGRA30 /* in a NVidia Tegra30 core */ #define CONFIG_TEGRA /* which is a Tegra generic machine */ #define CONFIG_SYS_L2CACHE_OFF /* No L2 cache */
@@ -54,15 +54,6 @@ #define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ #define CONFIG_OF_LIBFDT /* enable passing of devicetree */
-#ifdef CONFIG_TEGRA_LP0 -#define TEGRA_LP0_ADDR 0x1C406000 -#define TEGRA_LP0_SIZE 0x2000 -#define TEGRA_LP0_VEC \ - "lp0_vec=" QUOTE(TEGRA_LP0_SIZE) "@" QUOTE(TEGRA_LP0_ADDR) " " -#else -#define TEGRA_LP0_VEC -#endif - /* Environment */ #define CONFIG_ENV_VARS_UBOOT_CONFIG #define CONFIG_ENV_SIZE 0x2000 /* Total Size Environment */ @@ -95,26 +86,9 @@ /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE #define CONFIG_BAUDRATE 115200 -#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ - 115200} - -/* - * This parameter affects a TXFILLTUNING field that controls how much data is - * sent to the latency fifo before it is sent to the wire. Without this - * parameter, the default (2) causes occasional Data Buffer Errors in OUT - * packets depending on the buffer address and size. - */ -#define CONFIG_USB_EHCI_TXFIFO_THRESH 10 -#define CONFIG_EHCI_IS_TDI -#define CONFIG_EHCI_DCACHE - -/* Total I2C ports on Tegra20 */ -#define TEGRA_I2C_NUM_CONTROLLERS 4
/* include default commands */ #include <config_cmd_default.h> -#define CONFIG_PARTITION_UUIDS -#define CONFIG_CMD_PART
/* remove unused commands */ #undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ @@ -138,7 +112,7 @@ "stdout=serial\0" \ "stderr=serial\0"
-#define CONFIG_LOADADDR 0x408000 /* def. location for kernel */ +#define CONFIG_LOADADDR 0x80408000 /* def. location for kernel */ #define CONFIG_BOOTDELAY 2 /* -1 to disable auto boot */
/* @@ -162,10 +136,10 @@ #define CONFIG_SYS_MEMTEST_START (NV_PA_SDRC_CS0 + 0x600000) #define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x100000)
-#define CONFIG_SYS_LOAD_ADDR (0xA00800) /* default */ +#define CONFIG_SYS_LOAD_ADDR (0x80A00800) /* default */ #define CONFIG_SYS_HZ 1000
-#define CONFIG_STACKBASE 0x2800000 /* 40MB */ +#define CONFIG_STACKBASE 0x82800000 /* 40MB */
/*----------------------------------------------------------------------- * Physical Memory Map @@ -174,7 +148,7 @@ #define PHYS_SDRAM_1 NV_PA_SDRC_CS0 #define PHYS_SDRAM_1_SIZE 0x20000000 /* 512M */
-#define CONFIG_SYS_TEXT_BASE 0x0010c000 +#define CONFIG_SYS_TEXT_BASE 0x8010e000 #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
#define CONFIG_SYS_INIT_RAM_ADDR CONFIG_STACKBASE @@ -191,18 +165,16 @@ /* Defines for SPL */ #define CONFIG_SPL #define CONFIG_SPL_NAND_SIMPLE -#define CONFIG_SPL_TEXT_BASE 0x00108000 -#define CONFIG_SPL_MAX_SIZE 0x00004000 -#define CONFIG_SYS_SPL_MALLOC_START 0x00090000 +#define CONFIG_SPL_TEXT_BASE 0x80108000 +#define CONFIG_SPL_MAX_SIZE 0x00006000 +#define CONFIG_SYS_SPL_MALLOC_START 0x80090000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x00010000 -#define CONFIG_SPL_STACK 0x000ffffc +#define CONFIG_SPL_STACK 0x800ffffc
#define CONFIG_SPL_LIBCOMMON_SUPPORT #define CONFIG_SPL_LIBGENERIC_SUPPORT #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_GPIO_SUPPORT -#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/tegra20/u-boot-spl.lds" - -#define CONFIG_SYS_NAND_SELF_INIT +#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/tegra30/u-boot-spl.lds"
-#endif /* __TEGRA20_COMMON_H */ +#endif /* __TEGRA30_COMMON_H */

On 10/02/2012 04:45 PM, Tom Warren wrote:
This build is stripped down. It boots to the command prompt. GPIO is the only peripheral supported. Others TBD.
diff --git a/board/nvidia/whistler/Makefile b/board/nvidia/cardhu/Makefile similarity index 94% copy from board/nvidia/whistler/Makefile copy to board/nvidia/cardhu/Makefile index 913f1ce..a910577 100644 --- a/board/nvidia/whistler/Makefile +++ b/board/nvidia/cardhu/Makefile @@ -24,6 +24,10 @@
include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)../common) +endif
Hmm. Surely both or neither Whistler and Cardhu need this? Either this isn't needed, or it's wrong in Whistler before this series.
diff --git a/arch/arm/include/asm/arch-tegra/gp_padctrl.h b/include/configs/cardhu.h similarity index 55% copy from arch/arm/include/asm/arch-tegra/gp_padctrl.h copy to include/configs/cardhu.h index d347e97..bfadbff 100644
Uggh. git format-patch is certainly being over-zealous there, and equally failing to find the presumably much more familiar other Tegra config files:-(
diff --git a/include/configs/tegra20-common.h b/include/configs/tegra30-common.h similarity index 77% copy from include/configs/tegra20-common.h copy to include/configs/tegra30-common.h
Rather than duplicating this whole file, I wonder if it wouldn't be better to have tegra*-common.h include tegra-common.h with all the common stuff, and factor it out.
-#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
115200}
We should remove that from tegra20-common.h
/* include default commands */ #include <config_cmd_default.h> -#define CONFIG_PARTITION_UUIDS -#define CONFIG_CMD_PART
Seems like this should be the same on all Tegra.
-#define CONFIG_LOADADDR 0x408000 /* def. location for kernel */ +#define CONFIG_LOADADDR 0x80408000 /* def. location for kernel */
-#define CONFIG_SYS_LOAD_ADDR (0xA00800) /* default */ +#define CONFIG_SYS_LOAD_ADDR (0x80A00800) /* default */
Should LOADADDR and SYS_LOAD_ADDR match? Is only one of those useful?
-#define CONFIG_STACKBASE 0x2800000 /* 40MB */ +#define CONFIG_STACKBASE 0x82800000 /* 40MB */
Oh, how long is that used for? I hope the stack is dynamically allocated during relocation... That (existing Tegra20) value clashes with the ramdisk_addr_r I picked in my recent patch "ARM: tegra: use standard variables to define load addresses".
-#define CONFIG_SYS_TEXT_BASE 0x0010c000 +#define CONFIG_SYS_TEXT_BASE 0x8010e000
Why not 8010c0000? Is the SPL so large it doesn't fit? I suppose it's fine to have different SPL sizes on the two SoCs.

Stephen,
On Wed, Oct 3, 2012 at 1:46 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/02/2012 04:45 PM, Tom Warren wrote:
This build is stripped down. It boots to the command prompt. GPIO is the only peripheral supported. Others TBD.
diff --git a/board/nvidia/whistler/Makefile b/board/nvidia/cardhu/Makefile similarity index 94% copy from board/nvidia/whistler/Makefile copy to board/nvidia/cardhu/Makefile index 913f1ce..a910577 100644 --- a/board/nvidia/whistler/Makefile +++ b/board/nvidia/cardhu/Makefile @@ -24,6 +24,10 @@
include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)../common) +endif
Hmm. Surely both or neither Whistler and Cardhu need this? Either this isn't needed, or it's wrong in Whistler before this series.
This work was done on current u-boot-tegra/next (actually on next-before-last, then rebased before creating the patches), but this is git-format being overzealous with -C -C - I got this Makefile from our internal repo, IIRC. The ..common stuff isn't needed, as you say. I'll remove it in v2. Whistler's Makefile in current /next is OK.
diff --git a/arch/arm/include/asm/arch-tegra/gp_padctrl.h b/include/configs/cardhu.h similarity index 55% copy from arch/arm/include/asm/arch-tegra/gp_padctrl.h copy to include/configs/cardhu.h index d347e97..bfadbff 100644
Uggh. git format-patch is certainly being over-zealous there, and equally failing to find the presumably much more familiar other Tegra config files:-(
Yep. I wanted to use -C -C because it did get the closest source right most of the time - without it every file just looks like a new file w/gazillions of new lines. In this case, though (and in cardhu.c), it got it wrong.
diff --git a/include/configs/tegra20-common.h b/include/configs/tegra30-common.h similarity index 77% copy from include/configs/tegra20-common.h copy to include/configs/tegra30-common.h
Rather than duplicating this whole file, I wonder if it wouldn't be better to have tegra*-common.h include tegra-common.h with all the common stuff, and factor it out.
It would be better, but something I was hoping to leave til later. But I'll do it in v2 of this patch series.
-#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
115200}
We should remove that from tegra20-common.h
I tried to avoid T20-only edits because I wanted this series to be T30-only as much as possible. But if I'm gonna merge 'em, I can take it out then.
/* include default commands */ #include <config_cmd_default.h> -#define CONFIG_PARTITION_UUIDS -#define CONFIG_CMD_PART
Seems like this should be the same on all Tegra.
-#define CONFIG_LOADADDR 0x408000 /* def. location for kernel */ +#define CONFIG_LOADADDR 0x80408000 /* def. location for kernel */
-#define CONFIG_SYS_LOAD_ADDR (0xA00800) /* default */ +#define CONFIG_SYS_LOAD_ADDR (0x80A00800) /* default */
Should LOADADDR and SYS_LOAD_ADDR match? Is only one of those useful?
I grepped around a bit and it seems some code uses LOADADDR and some uses SYS_LOAD_ADDR, and some config files make one == the other. So I left 'em both in, with new T30-compatible addresses. If someone wants to see if one can be dropped at a later date, that's cool.
-#define CONFIG_STACKBASE 0x2800000 /* 40MB */ +#define CONFIG_STACKBASE 0x82800000 /* 40MB */
Oh, how long is that used for? I hope the stack is dynamically allocated during relocation... That (existing Tegra20) value clashes with the ramdisk_addr_r I picked in my recent patch "ARM: tegra: use standard variables to define load addresses".
Don't know how/when it's used, just ported it to T30 addressing. I can look into it in V2.
-#define CONFIG_SYS_TEXT_BASE 0x0010c000 +#define CONFIG_SYS_TEXT_BASE 0x8010e000
Why not 8010c0000? Is the SPL so large it doesn't fit? I suppose it's fine to have different SPL sizes on the two SoCs.
Yep, in my initial porting to T30, SPL was too big to fit into 16K, so I bumped it to 24K. I'll revisit the SPL size after commonizing cpu.c to see if it's shrunk enough to fit now.
Thanks,
Tom

On 10/02/2012 04:45 PM, Tom Warren wrote:
This patch series adds basic (boot to cmd prompt) support for Tegra30. This is based on the Tegra20 SPL, which inits the AVP (ARM7TDMI boot proc) first, then control is transferred to the CPU (A9 quad core). It is based on current u-boot-tegra/next.
Future patches will add support/drivers for MMC/USB/I2C/SPI/etc. The Cardhu T30 board is supported initially.
The series, Tested-by: Stephen Warren swarren@nvidia.com
I'll provide review comments later.
participants (4)
-
Lucas Stach
-
Simon Glass
-
Stephen Warren
-
Tom Warren