[U-Boot] [PATCH 0/9] Add basic Tegra30 (T30) support

This patch series adds basic (boot to cmd prompt) support for Tegra30. This is based on the Tegra20 SPL, which initializes the AVP (ARM7TDMI boot proc) first, then control is transferred to the CPU (A9 quad cluster). It is based on current u-boot-tegra/next.
Future patches will add support/drivers for MMC, USB, I2C, SPI, NAND, and other peripherals. The Cardhu T30 board is supported initially.
Tom Warren (9): Tegra: T30: Add include files Tegra: T30: Add AVP (arm720t) files Tegra: T30: Add CPU (armv7) files Tegra: T30: Add common Tegra30 CPU files Tegra: DT: Add preliminary device tree files for T30 Cardhu Tegra30: Add Cardhu board files Tegra30: Add config files (common and Cardhu) Tegra30: Add common pinmux config in board_early_init_f Tegra30: Enable Cardhu build (SPL)
Makefile | 23 + arch/arm/cpu/{armv7 => arm720t/tegra30}/Makefile | 27 +- arch/arm/cpu/arm720t/tegra30/board.h | 25 + arch/arm/cpu/arm720t/tegra30/config.mk | 26 + arch/arm/cpu/arm720t/tegra30/cpu.c | 570 +++++++++++ arch/arm/cpu/arm720t/tegra30/cpu.h | 65 ++ arch/arm/cpu/arm720t/tegra30/spl.c | 132 +++ arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/start.S | 4 +- arch/arm/cpu/armv7/{ => tegra30}/Makefile | 23 +- arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c | 65 ++ arch/arm/cpu/armv7/tegra30/config.mk | 26 + arch/arm/cpu/{armv7 => tegra30-common}/Makefile | 28 +- arch/arm/cpu/tegra30-common/ap30.c | 98 ++ arch/arm/cpu/tegra30-common/board.c | 141 +++ arch/arm/cpu/tegra30-common/clock.c | 1099 ++++++++++++++++++++++ arch/arm/cpu/tegra30-common/funcmux.c | 74 ++ arch/arm/cpu/tegra30-common/lowlevel_init.S | 42 + arch/arm/cpu/tegra30-common/pinmux.c | 507 ++++++++++ arch/arm/cpu/tegra30-common/sys_info.c | 35 + arch/arm/cpu/tegra30-common/timer.c | 111 +++ arch/arm/dts/tegra30.dtsi | 280 ++++++ arch/arm/include/asm/arch-tegra30/ap30.h | 99 ++ arch/arm/include/asm/arch-tegra30/board.h | 30 + arch/arm/include/asm/arch-tegra30/clk_rst.h | 277 ++++++ arch/arm/include/asm/arch-tegra30/clock.h | 602 ++++++++++++ arch/arm/include/asm/arch-tegra30/emc.h | 113 +++ arch/arm/include/asm/arch-tegra30/flow.h | 42 + arch/arm/include/asm/arch-tegra30/funcmux.h | 77 ++ arch/arm/include/asm/arch-tegra30/fuse.h | 39 + arch/arm/include/asm/arch-tegra30/gp_padctrl.h | 73 ++ arch/arm/include/asm/arch-tegra30/gpio.h | 322 +++++++ arch/arm/include/asm/arch-tegra30/hardware.h | 29 + arch/arm/include/asm/arch-tegra30/mmc.h | 28 + arch/arm/include/asm/arch-tegra30/pinmux.h | 610 ++++++++++++ arch/arm/include/asm/arch-tegra30/pmc.h | 132 +++ arch/arm/include/asm/arch-tegra30/pmu.h | 30 + arch/arm/include/asm/arch-tegra30/scu.h | 43 + arch/arm/include/asm/arch-tegra30/sys_proto.h | 35 + arch/arm/include/asm/arch-tegra30/tegra30.h | 109 +++ arch/arm/include/asm/arch-tegra30/tegra_i2c.h | 164 ++++ arch/arm/include/asm/arch-tegra30/timer.h | 31 + arch/arm/include/asm/arch-tegra30/uart.h | 47 + arch/arm/include/asm/arch-tegra30/usb.h | 253 +++++ arch/arm/include/asm/arch-tegra30/warmboot.h | 150 +++ board/nvidia/cardhu/Makefile | 48 + board/nvidia/cardhu/cardhu.c | 87 ++ board/nvidia/cardhu/pinmux-config-common.h | 346 +++++++ board/nvidia/common/board.c | 27 +- board/nvidia/dts/tegra30-cardhu.dts | 92 ++ boards.cfg | 1 + drivers/gpio/tegra_gpio.c | 4 + include/configs/cardhu.h | 52 + include/configs/tegra30-common.h | 188 ++++ include/serial.h | 3 +- spl/Makefile | 3 + 56 files changed, 7536 insertions(+), 53 deletions(-) copy arch/arm/cpu/{armv7 => arm720t/tegra30}/Makefile (70%) create mode 100644 arch/arm/cpu/arm720t/tegra30/board.h 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/arm720t/tegra30/cpu.h create mode 100644 arch/arm/cpu/arm720t/tegra30/spl.c copy arch/arm/cpu/armv7/{ => tegra30}/Makefile (76%) create mode 100644 arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c create mode 100644 arch/arm/cpu/armv7/tegra30/config.mk copy arch/arm/cpu/{armv7 => tegra30-common}/Makefile (69%) create mode 100644 arch/arm/cpu/tegra30-common/ap30.c create mode 100644 arch/arm/cpu/tegra30-common/board.c 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/lowlevel_init.S create mode 100644 arch/arm/cpu/tegra30-common/pinmux.c create mode 100644 arch/arm/cpu/tegra30-common/sys_info.c create mode 100644 arch/arm/cpu/tegra30-common/timer.c create mode 100644 arch/arm/dts/tegra30.dtsi create mode 100644 arch/arm/include/asm/arch-tegra30/ap30.h create mode 100644 arch/arm/include/asm/arch-tegra30/board.h create mode 100644 arch/arm/include/asm/arch-tegra30/clk_rst.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/fuse.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/mmc.h create mode 100644 arch/arm/include/asm/arch-tegra30/pinmux.h create mode 100644 arch/arm/include/asm/arch-tegra30/pmc.h create mode 100644 arch/arm/include/asm/arch-tegra30/pmu.h create mode 100644 arch/arm/include/asm/arch-tegra30/scu.h create mode 100644 arch/arm/include/asm/arch-tegra30/sys_proto.h create mode 100644 arch/arm/include/asm/arch-tegra30/tegra30.h create mode 100644 arch/arm/include/asm/arch-tegra30/tegra_i2c.h create mode 100644 arch/arm/include/asm/arch-tegra30/timer.h create mode 100644 arch/arm/include/asm/arch-tegra30/uart.h create mode 100644 arch/arm/include/asm/arch-tegra30/usb.h create mode 100644 arch/arm/include/asm/arch-tegra30/warmboot.h create mode 100644 board/nvidia/cardhu/Makefile create mode 100644 board/nvidia/cardhu/cardhu.c create mode 100644 board/nvidia/cardhu/pinmux-config-common.h create mode 100644 board/nvidia/dts/tegra30-cardhu.dts create mode 100644 include/configs/cardhu.h create mode 100644 include/configs/tegra30-common.h

Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/include/asm/arch-tegra30/ap30.h | 99 ++++ arch/arm/include/asm/arch-tegra30/board.h | 30 ++ arch/arm/include/asm/arch-tegra30/clk_rst.h | 277 +++++++++++ arch/arm/include/asm/arch-tegra30/clock.h | 602 +++++++++++++++++++++++ arch/arm/include/asm/arch-tegra30/emc.h | 113 +++++ arch/arm/include/asm/arch-tegra30/flow.h | 42 ++ arch/arm/include/asm/arch-tegra30/funcmux.h | 77 +++ arch/arm/include/asm/arch-tegra30/fuse.h | 39 ++ arch/arm/include/asm/arch-tegra30/gp_padctrl.h | 73 +++ arch/arm/include/asm/arch-tegra30/gpio.h | 322 +++++++++++++ arch/arm/include/asm/arch-tegra30/hardware.h | 29 ++ arch/arm/include/asm/arch-tegra30/mmc.h | 28 ++ arch/arm/include/asm/arch-tegra30/pinmux.h | 610 ++++++++++++++++++++++++ arch/arm/include/asm/arch-tegra30/pmc.h | 132 +++++ arch/arm/include/asm/arch-tegra30/pmu.h | 30 ++ arch/arm/include/asm/arch-tegra30/scu.h | 43 ++ arch/arm/include/asm/arch-tegra30/sys_proto.h | 35 ++ arch/arm/include/asm/arch-tegra30/tegra30.h | 109 +++++ arch/arm/include/asm/arch-tegra30/tegra_i2c.h | 164 +++++++ arch/arm/include/asm/arch-tegra30/timer.h | 31 ++ arch/arm/include/asm/arch-tegra30/uart.h | 47 ++ arch/arm/include/asm/arch-tegra30/usb.h | 253 ++++++++++ arch/arm/include/asm/arch-tegra30/warmboot.h | 150 ++++++ 23 files changed, 3335 insertions(+), 0 deletions(-) create mode 100644 arch/arm/include/asm/arch-tegra30/ap30.h create mode 100644 arch/arm/include/asm/arch-tegra30/board.h create mode 100644 arch/arm/include/asm/arch-tegra30/clk_rst.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/fuse.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/mmc.h create mode 100644 arch/arm/include/asm/arch-tegra30/pinmux.h create mode 100644 arch/arm/include/asm/arch-tegra30/pmc.h create mode 100644 arch/arm/include/asm/arch-tegra30/pmu.h create mode 100644 arch/arm/include/asm/arch-tegra30/scu.h create mode 100644 arch/arm/include/asm/arch-tegra30/sys_proto.h create mode 100644 arch/arm/include/asm/arch-tegra30/tegra30.h create mode 100644 arch/arm/include/asm/arch-tegra30/tegra_i2c.h create mode 100644 arch/arm/include/asm/arch-tegra30/timer.h create mode 100644 arch/arm/include/asm/arch-tegra30/uart.h create mode 100644 arch/arm/include/asm/arch-tegra30/usb.h create mode 100644 arch/arm/include/asm/arch-tegra30/warmboot.h
diff --git a/arch/arm/include/asm/arch-tegra30/ap30.h b/arch/arm/include/asm/arch-tegra30/ap30.h new file mode 100644 index 0000000..70d6650 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/ap30.h @@ -0,0 +1,99 @@ +/* + * (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 + */ +#include <asm/types.h> + +/* Stabilization delays, in usec */ +#define PLL_STABILIZATION_DELAY (300) +#define IO_STABILIZATION_DELAY (1000) + +#define NVBL_PLLP_KHZ (216000) + +#define PLLX_ENABLED (1 << 30) +#define CCLK_BURST_POLICY 0x20008888 +#define SUPER_CCLK_DIVIDER 0x80000000 + +/* Calculate clock fractional divider value from ref and target frequencies */ +#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)) + +/* AVP/CPU ID */ +#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */ +#define PG_UP_TAG_0 0x0 + +#define CORESIGHT_UNLOCK 0xC5ACCE55; + +/* T30-Specific Base Addresses */ + +/* T30 Base physical address of SDRAM. */ +#define T30_BASE_PA_SDRAM 0x00000000 +/* T30 Base physical address of internal SRAM. */ +#define T30_BASE_PA_SRAM 0x40000000 +/* T30 Size of internal SRAM (256KB). */ +#define T30_BASE_PA_SRAM_SIZE 0x00040000 +/* T30 Base physical address of flash. */ +#define T30_BASE_PA_NOR_FLASH 0xD0000000 +/* T30 Base physical address of boot information table. */ +#define T30_BASE_PA_BOOT_INFO T30_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 \ + (T30_BASE_PA_SRAM + (T30_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 FLOW_CTLR_HALT_COP_EVENTS (NV_PA_FLOW_BASE + 4) +#define FLOW_MODE_STOP 2 +#define HALT_COP_EVENT_JTAG (1 << 28) +#define HALT_COP_EVENT_IRQ_1 (1 << 11) +#define HALT_COP_EVENT_FIQ_1 (1 << 9) + +/* This is the main entry into U-Boot, used by the Cortex-A9 */ +extern void _start(void); diff --git a/arch/arm/include/asm/arch-tegra30/board.h b/arch/arm/include/asm/arch-tegra30/board.h new file mode 100644 index 0000000..8cceea5 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/board.h @@ -0,0 +1,30 @@ +/* + * (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_BOARD_H_ +#define _TEGRA_BOARD_H_ + +/* Setup UARTs for the board according to the selected config */ +void board_init_uart_f(void); + +#endif diff --git a/arch/arm/include/asm/arch-tegra30/clk_rst.h b/arch/arm/include/asm/arch-tegra30/clk_rst.h new file mode 100644 index 0000000..5e10fe5 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/clk_rst.h @@ -0,0 +1,277 @@ +/* + * (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 _CLK_RST_H_ +#define _CLK_RST_H_ + +/* PLL registers - there are several PLLs in the clock controller */ +struct clk_pll { + uint pll_base; /* the control register */ + uint pll_out; /* output control */ + uint pll_out_b; /* some have output B control */ + uint pll_misc; /* other misc things */ +}; + +/* PLL registers - there are several PLLs in the clock controller */ +struct clk_pll_simple { + uint pll_base; /* the control register */ + 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- + * othogonal setup is not stated. + */ +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 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 */ +struct clk_rst_ctlr { + uint crc_rst_src; /* _RST_SOURCE_0,0x00 */ + uint crc_rst_dev[TEGRA_CLK_REGS]; /* _RST_DEVICES_L/H/U_0 */ + uint crc_clk_out_enb[TEGRA_CLK_REGS]; /* _CLK_OUT_ENB_L/H/U_0 */ + uint crc_reserved0; /* reserved_0, 0x1C */ + uint crc_cclk_brst_pol; /* _CCLK_BURST_POLICY_0,0x20 */ + uint crc_super_cclk_div; /* _SUPER_CCLK_DIVIDER_0,0x24 */ + uint crc_sclk_brst_pol; /* _SCLK_BURST_POLICY_0, 0x28 */ + uint crc_super_sclk_div; /* _SUPER_SCLK_DIVIDER_0,0x2C */ + uint crc_clk_sys_rate; /* _CLK_SYSTEM_RATE_0, 0x30 */ + uint crc_prog_dly_clk; /* _PROG_DLY_CLK_0, 0x34 */ + uint crc_aud_sync_clk_rate; /* _AUDIO_SYNC_CLK_RATE_0,0x38 */ + uint crc_reserved1; /* reserved_1, 0x3C */ + uint crc_cop_clk_skip_plcy; /* _COP_CLK_SKIP_POLICY_0,0x40 */ + uint crc_clk_mask_arm; /* _CLK_MASK_ARM_0, 0x44 */ + uint crc_misc_clk_enb; /* _MISC_CLK_ENB_0, 0x48 */ + uint crc_clk_cpu_cmplx; /* _CLK_CPU_CMPLX_0, 0x4C */ + uint crc_osc_ctrl; /* _OSC_CTRL_0, 0x50 */ + uint crc_pll_lfsr; /* _PLL_LFSR_0, 0x54 */ + uint crc_osc_freq_det; /* _OSC_FREQ_DET_0, 0x58 */ + uint crc_osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS_0,0x5C */ + uint crc_reserved2[8]; /* reserved_2[8], 0x60-7C */ + + struct clk_pll crc_pll[TEGRA_CLK_PLLS]; /* PLLs from 0x80 to 0xdc */ + + /* PLLs from 0xe0 to 0xf4 */ + struct clk_pll_simple crc_pll_simple[TEGRA_CLK_SIMPLE_PLLS]; + + uint crc_reserved10; /* _reserved_10, 0xF8 */ + uint crc_reserved11; /* _reserved_11, 0xFC */ + + uint crc_clk_src[TEGRA_CLK_SOURCES]; /*_I2S1_0... 0x100-1fc */ + + 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) + +/* CLK_RST_CONTROLLER_PLLx_BASE_0 */ +#define PLL_BYPASS_SHIFT 31 +#define PLL_BYPASS_MASK (1U << PLL_BYPASS_SHIFT) + +#define PLL_ENABLE_SHIFT 30 +#define PLL_ENABLE_MASK (1U << PLL_ENABLE_SHIFT) + +#define PLL_BASE_OVRRIDE_MASK (1U << 28) + +#define PLL_DIVP_SHIFT 20 +#define PLL_DIVP_MASK (7U << PLL_DIVP_SHIFT) + +#define PLL_DIVN_SHIFT 8 +#define PLL_DIVN_MASK (0x3ffU << PLL_DIVN_SHIFT) + +#define PLL_DIVM_SHIFT 0 +#define PLL_DIVM_MASK (0x1f << PLL_DIVM_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) + +#define PLL_LFCON_SHIFT 4 +#define PLL_LFCON_MASK (15U << PLL_LFCON_SHIFT) + +#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) +#define OSC_XOBP_SHIFT 1 +#define OSC_XOBP_MASK (1U << OSC_XOBP_SHIFT) + +/* + * CLK_RST_CONTROLLER_CLK_SOURCE_x_OUT_0 - the mask here is normally 8 bits + * but can be 16. We could use knowledge we have to restrict the mask in + * the 8-bit cases (the divider_bits value returned by + * get_periph_clock_source()) but it does not seem worth it since the code + * already checks the ranges of values it is writing, in clk_get_divider(). + */ +#define OUT_CLK_DIVISOR_SHIFT 0 +#define OUT_CLK_DIVISOR_MASK (0xffff << OUT_CLK_DIVISOR_SHIFT) + +#define OUT_CLK_SOURCE_SHIFT 30 +#define OUT_CLK_SOURCE_MASK (3U << OUT_CLK_SOURCE_SHIFT) + +#define OUT_CLK_SOURCE4_SHIFT 28 +#define OUT_CLK_SOURCE4_MASK (15U << OUT_CLK_SOURCE4_SHIFT) + +/* 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 /* CLK_RST_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..9e7eb80 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/clock.h @@ -0,0 +1,602 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (c) 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 + */ + +/* Tegra30 clock control functions */ + +#ifndef _CLOCK_H +#define _CLOCK_H + +/* Set of oscillator frequencies supported in the internal API. */ +enum clock_osc_freq { + /* All in MHz, so 13_0 is 13.0MHz */ + CLOCK_OSC_FREQ_13_0, + CLOCK_OSC_FREQ_19_2, + CLOCK_OSC_FREQ_12_0, + CLOCK_OSC_FREQ_26_0, + + CLOCK_OSC_FREQ_COUNT, +}; + +/* 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, +}; + +/* + * 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) + +/* PLL stabilization delay in usec */ +#define CLOCK_PLL_STABLE_DELAY_US 300 + +/* return the current oscillator clock frequency */ +enum clock_osc_freq clock_get_osc_freq(void); + +/** + * Start PLL using the provided configuration parameters. + * + * @param id clock id + * @param divm input divider + * @param divn feedback divider + * @param divp post divider 2^n + * @param cpcon charge pump setup control + * @param lfcon loop filter setup control + * + * @returns monotonic time in us that the PLL will be stable + */ +unsigned long clock_start_pll(enum clock_id id, u32 divm, u32 divn, + u32 divp, u32 cpcon, u32 lfcon); + +/** + * Read low-level parameters of a PLL. + * + * @param id clock id to read (note: USB is not supported) + * @param divm returns input divider + * @param divn returns feedback divider + * @param divp returns post divider 2^n + * @param cpcon returns charge pump setup control + * @param lfcon returns loop filter setup control + * + * @returns 0 if ok, -1 on error (invalid clock id) + */ +int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, + u32 *divp, u32 *cpcon, u32 *lfcon); + +/* + * Enable a clock + * + * @param id clock id + */ +void clock_enable(enum periph_id clkid); + +/* + * Disable a clock + * + * @param id clock id + */ +void clock_disable(enum periph_id clkid); + +/* + * Set whether a clock is enabled or disabled. + * + * @param id clock id + * @param enable 1 to enable, 0 to disable + */ +void clock_set_enable(enum periph_id clkid, int enable); + +/** + * Reset a peripheral. This puts it in reset, waits for a delay, then takes + * it out of reset and waits for th delay again. + * + * @param periph_id peripheral to reset + * @param us_delay time to delay in microseconds + */ +void reset_periph(enum periph_id periph_id, int us_delay); + +/** + * Put a peripheral into or out of reset. + * + * @param periph_id peripheral to reset + * @param enable 1 to put into reset, 0 to take out of reset + */ +void reset_set_enable(enum periph_id periph_id, int enable); + + +/* CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET/CLR_0 */ +enum crc_reset_id { + /* Things we can hold in reset for each CPU */ + crc_rst_cpu = 1, + crc_rst_de = 1 << 2, /* What is de? */ + crc_rst_watchdog = 1 << 3, + crc_rst_debug = 1 << 4, +}; + +/** + * Put parts of the CPU complex into or out of reset.\ + * + * @param cpu cpu number (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 + */ +void reset_cmplx_set_enable(int cpu, int which, int reset); + +/** + * Set the source for a peripheral clock. This plus the divisor sets the + * clock rate. You need to look up the datasheet to see the meaning of the + * source parameter as it changes for each peripheral. + * + * Warning: This function is only for use pre-relocation. Please use + * clock_start_periph_pll() instead. + * + * @param periph_id peripheral to adjust + * @param source source clock (0, 1, 2 or 3) + */ +void clock_ll_set_source(enum periph_id periph_id, unsigned source); + +/** + * Set the source and divisor for a peripheral clock. This sets the + * clock rate. You need to look up the datasheet to see the meaning of the + * source parameter as it changes for each peripheral. + * + * Warning: This function is only for use pre-relocation. Please use + * clock_start_periph_pll() instead. + * + * @param periph_id peripheral to adjust + * @param source source clock (0, 1, 2 or 3) + * @param divisor divisor value to use + */ +void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source, + unsigned divisor); + +/** + * Start a peripheral PLL clock at the given rate. This also resets the + * peripheral. + * + * @param periph_id peripheral to start + * @param parent PLL id of required parent clock + * @param rate Required clock rate in Hz + * @return rate selected in Hz, or -1U if something went wrong + */ +unsigned clock_start_periph_pll(enum periph_id periph_id, + enum clock_id parent, unsigned rate); + +/** + * Returns the rate of a peripheral clock in Hz. Since the caller almost + * certainly knows the parent clock (having just set it) we require that + * this be passed in so we don't need to work it out. + * + * @param periph_id peripheral to start + * @param parent PLL id of parent clock (used to calculate rate, you + * must know this!) + * @return clock rate of peripheral in Hz + */ +unsigned long clock_get_periph_rate(enum periph_id periph_id, + enum clock_id parent); + +/** + * Adjust peripheral PLL clock to the given rate. This does not reset the + * peripheral. If a second stage divisor is not available, pass NULL for + * extra_div. If it is available, then this parameter will return the + * divisor selected (which will be a power of 2 from 1 to 256). + * + * @param periph_id peripheral to start + * @param parent PLL id of required parent clock + * @param rate Required clock rate in Hz + * @param extra_div value for the second-stage divisor (NULL if one is + not available) + * @return rate selected in Hz, or -1U if something went wrong + */ +unsigned clock_adjust_periph_pll_div(enum periph_id periph_id, + enum clock_id parent, unsigned rate, int *extra_div); + +/** + * Returns the clock rate of a specified clock, in Hz. + * + * @param parent PLL id of clock to check + * @return rate of clock in Hz + */ +unsigned clock_get_rate(enum clock_id clkid); + +/** + * Start up a UART using low-level calls + * + * Prior to relocation clock_start_periph_pll() cannot be called. This + * function provides a way to set up a UART using low-level calls which + * do not require BSS. + * + * @param periph_id Peripheral ID of UART to enable (e,g, PERIPH_ID_UART1) + */ +void clock_ll_start_uart(enum periph_id periph_id); + +/** + * Decode a peripheral ID from a device tree node. + * + * This works by looking up the peripheral's 'clocks' node and reading out + * the second cell, which is the clock number / peripheral ID. + * + * @param blob FDT blob to use + * @param node Node to look at + * @return peripheral ID, or PERIPH_ID_NONE if none + */ +enum periph_id clock_decode_periph_id(const void *blob, int node); + +/** + * Checks if the oscillator bypass is enabled (XOBP bit) + * + * @return 1 if bypass is enabled, 0 if not + */ +int clock_get_osc_bypass(void); + +/* + * Checks that clocks are valid and prints a warning if not + * + * @return 0 if ok, -1 on error + */ +int clock_verify(void); + +/* Initialize the clocks */ +void clock_init(void); + +/* Initialize the PLLs */ +void clock_early_init(void); + +#endif /* _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..36b8cae --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/emc.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (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 _EMC_H_ +#define _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 /* _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..e4bab57 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/flow.h @@ -0,0 +1,42 @@ +/* + * (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 _FLOW_H_ +#define _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 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..a478ae5 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/funcmux.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (C) 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 + */ + +/* Tegra high-level function multiplexing */ + +#ifndef __FUNCMUX_H +#define __FUNCMUX_H + +/* Configs supported by the func mux */ +enum { + FUNCMUX_DEFAULT = 0, /* default config */ + + /* UART configs */ + FUNCMUX_UART1_ULPI_UART2 = 0, + FUNCMUX_UART2_IRDA = 0, + FUNCMUX_UART4_GMC = 0, + + /* I2C configs */ + FUNCMUX_DVC_I2CP = 0, + FUNCMUX_I2C1_RM = 0, + FUNCMUX_I2C2_DDC = 0, + FUNCMUX_I2C2_PTA, + FUNCMUX_I2C3_DTF = 0, + + /* SDMMC configs */ + FUNCMUX_SDMMC1_SDIO1_4BIT = 0, + FUNCMUX_SDMMC2_DTA_DTD_8BIT = 0, + FUNCMUX_SDMMC3_SDB_4BIT = 0, + FUNCMUX_SDMMC3_SDB_SLXA_8BIT, + FUNCMUX_SDMMC4_ATC_ATD_8BIT = 0, + FUNCMUX_SDMMC4_ATB_GMA_4_BIT, + FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT, + + /* USB configs */ + FUNCMUX_USB2_ULPI = 0, + + /* Serial Flash configs */ + FUNCMUX_SPI1_GMC_GMD = 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 diff --git a/arch/arm/include/asm/arch-tegra30/fuse.h b/arch/arm/include/asm/arch-tegra30/fuse.h new file mode 100644 index 0000000..23374ee --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/fuse.h @@ -0,0 +1,39 @@ +/* + * (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 _FUSE_H_ +#define _FUSE_H_ + +/* FUSE registers */ +struct fuse_regs { + u32 reserved0[64]; /* 0x00 - 0xFC: */ + u32 production_mode; /* 0x100: FUSE_PRODUCTION_MODE */ + u32 reserved1[3]; /* 0x104 - 0x10c: */ + u32 sku_info; /* 0x110 */ + u32 reserved2[13]; /* 0x114 - 0x144: */ + u32 fa; /* 0x148: FUSE_FA */ + u32 reserved3[21]; /* 0x14C - 0x19C: */ + u32 security_mode; /* 0x1A0: FUSE_SECURITY_MODE */ +}; + +#endif /* _FUSE_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..2834a98 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/gp_padctrl.h @@ -0,0 +1,73 @@ +/* + * (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 _GP_PADCTRL_H_ +#define _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 cdevcfg1; /* 0x78: APB_MISC_GP_CDEV1CFGPADCTRL */ + u32 cdevcfg2; /* 0x7C: APB_MISC_GP_CDEV2CFGPADCTRL */ + u32 csuscfg; /* 0x80: APB_MISC_GP_CSUSCFGPADCTRL */ + u32 dap1cfg; /* 0x84: APB_MISC_GP_DAP1CFGPADCTRL */ + u32 dap2cfg; /* 0x88: APB_MISC_GP_DAP2CFGPADCTRL */ + u32 dap3cfg; /* 0x8C: APB_MISC_GP_DAP3CFGPADCTRL */ + u32 dap4cfg; /* 0x90: APB_MISC_GP_DAP4CFGPADCTRL */ + u32 dbgcfg; /* 0x94: APB_MISC_GP_DBGCFGPADCTRL */ + u32 lcdcfg1; /* 0x98: APB_MISC_GP_LCDCFG1PADCTRL */ + u32 lcdcfg2; /* 0x9C: APB_MISC_GP_LCDCFG2PADCTRL */ + u32 sdmmc2_cfg; /* 0xA0: APB_MISC_GP_SDMMC2CFGPADCTRL */ + u32 sdmmc3_cfg; /* 0xA4: APB_MISC_GP_SDMMC3CFGPADCTRL */ + u32 spicfg; /* 0xA8: APB_MISC_GP_SPICFGPADCTRL */ + u32 uaacfg; /* 0xAC: APB_MISC_GP_UAACFGPADCTRL */ + u32 uabcfg; /* 0xB0: APB_MISC_GP_UABCFGPADCTRL */ + u32 uart2cfg; /* 0xB4: APB_MISC_GP_UART2CFGPADCTRL */ + u32 uart3cfg; /* 0xB8: APB_MISC_GP_UART3CFGPADCTRL */ + u32 vicfg1; /* 0xBC: APB_MISC_GP_VICFG1PADCTRL */ + u32 vicfg2; /* 0xC0: APB_MISC_GP_VICFG2PADCTRL */ + u32 xm2cfga; /* 0xC4: APB_MISC_GP_XM2CFGAPADCTRL */ + u32 xm2cfgc; /* 0xC8: APB_MISC_GP_XM2CFGCPADCTRL */ + u32 xm2cfgd; /* 0xCC: APB_MISC_GP_XM2CFGDPADCTRL */ + u32 xm2clkcfg; /* 0xD0: APB_MISC_GP_XM2CLKCFGPADCTRL */ + 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 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..892685d --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/gpio.h @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2011, Google Inc. All rights reserved. + * See file CREDITS for list of people who contributed to this + * project. + * Portions Copyright 2011-2012 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; 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_GPIO_H_ +#define _TEGRA_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 */ +#define MAX_NUM_GPIOS (TEGRA_GPIO_PORTS * TEGRA_GPIO_BANKS * 8) +#define GPIO_NAME_SIZE 20 /* gpio_request max label len */ + +/* 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]; +}; + +#define GPIO_BANK(x) ((x) >> 5) +#define GPIO_PORT(x) (((x) >> 3) & 0x3) +#define GPIO_FULLPORT(x) ((x) >> 3) +#define GPIO_BIT(x) ((x) & 0x7) + +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 */ +}; + +/* + * Tegra-specific GPIO API + */ + +void gpio_info(void); + +#define gpio_status() gpio_info() +#endif /* TEGRA_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..c58fd61 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/hardware.h @@ -0,0 +1,29 @@ +/* +* (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_HW_H +#define __TEGRA_HW_H + +/* include tegra specific hardware definitions */ + +#endif /* __TEGRA_HW_H */ diff --git a/arch/arm/include/asm/arch-tegra30/mmc.h b/arch/arm/include/asm/arch-tegra30/mmc.h new file mode 100644 index 0000000..40133bb --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/mmc.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011, Google Inc. All rights reserved. + * Copyright (C) 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 _MMC_H_ +#define _MMC_H_ + +int tegra_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio); + +#endif /* _MMC_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..44817b8 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/pinmux.h @@ -0,0 +1,610 @@ +/* + * (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 _PINMUX_H_ +#define _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]; /* offset 0x3000 */ + uint pmt_ctl[PINGRP_COUNT]; /* pin mux/pupd/tristate regs */ +}; + +/* + * 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); + +/** + * Configuure 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 /* PINMUX_H */ diff --git a/arch/arm/include/asm/arch-tegra30/pmc.h b/arch/arm/include/asm/arch-tegra30/pmc.h new file mode 100644 index 0000000..65216bc --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/pmc.h @@ -0,0 +1,132 @@ +/* + * (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 _PMC_H_ +#define _PMC_H_ + +/* Power Management Controller (APBDEV_PMC_) registers */ +struct pmc_ctlr { + uint pmc_cntrl; /* _CNTRL_0, offset 00 */ + uint pmc_sec_disable; /* _SEC_DISABLE_0, offset 04 */ + uint pmc_pmc_swrst; /* _PMC_SWRST_0, offset 08 */ + uint pmc_wake_mask; /* _WAKE_MASK_0, offset 0C */ + uint pmc_wake_lvl; /* _WAKE_LVL_0, offset 10 */ + uint pmc_wake_status; /* _WAKE_STATUS_0, offset 14 */ + uint pmc_sw_wake_status; /* _SW_WAKE_STATUS_0, offset 18 */ + uint pmc_dpd_pads_oride; /* _DPD_PADS_ORIDE_0, offset 1C */ + uint pmc_dpd_sample; /* _DPD_PADS_SAMPLE_0, offset 20 */ + uint pmc_dpd_enable; /* _DPD_PADS_ENABLE_0, offset 24 */ + uint pmc_pwrgate_timer_off; /* _PWRGATE_TIMER_OFF_0, offset 28 */ + uint pmc_pwrgate_timer_on; /* _PWRGATE_TIMER_ON_0, offset 2C */ + uint pmc_pwrgate_toggle; /* _PWRGATE_TOGGLE_0, offset 30 */ + uint pmc_remove_clamping; /* _REMOVE_CLAMPING_CMD_0, offset 34 */ + uint pmc_pwrgate_status; /* _PWRGATE_STATUS_0, offset 38 */ + uint pmc_pwrgood_timer; /* _PWRGOOD_TIMER_0, offset 3C */ + uint pmc_blink_timer; /* _BLINK_TIMER_0, offset 40 */ + uint pmc_no_iopower; /* _NO_IOPOWER_0, offset 44 */ + uint pmc_pwr_det; /* _PWR_DET_0, offset 48 */ + uint pmc_pwr_det_latch; /* _PWR_DET_LATCH_0, offset 4C */ + + uint pmc_scratch0; /* _SCRATCH0_0, offset 50 */ + uint pmc_scratch1; /* _SCRATCH1_0, offset 54 */ + uint pmc_scratch2; /* _SCRATCH2_0, offset 58 */ + uint pmc_scratch3; /* _SCRATCH3_0, offset 5C */ + uint pmc_scratch4; /* _SCRATCH4_0, offset 60 */ + uint pmc_scratch5; /* _SCRATCH5_0, offset 64 */ + uint pmc_scratch6; /* _SCRATCH6_0, offset 68 */ + uint pmc_scratch7; /* _SCRATCH7_0, offset 6C */ + uint pmc_scratch8; /* _SCRATCH8_0, offset 70 */ + uint pmc_scratch9; /* _SCRATCH9_0, offset 74 */ + uint pmc_scratch10; /* _SCRATCH10_0, offset 78 */ + uint pmc_scratch11; /* _SCRATCH11_0, offset 7C */ + uint pmc_scratch12; /* _SCRATCH12_0, offset 80 */ + uint pmc_scratch13; /* _SCRATCH13_0, offset 84 */ + uint pmc_scratch14; /* _SCRATCH14_0, offset 88 */ + uint pmc_scratch15; /* _SCRATCH15_0, offset 8C */ + uint pmc_scratch16; /* _SCRATCH16_0, offset 90 */ + uint pmc_scratch17; /* _SCRATCH17_0, offset 94 */ + uint pmc_scratch18; /* _SCRATCH18_0, offset 98 */ + uint pmc_scratch19; /* _SCRATCH19_0, offset 9C */ + uint pmc_scratch20; /* _SCRATCH20_0, offset A0 */ + uint pmc_scratch21; /* _SCRATCH21_0, offset A4 */ + uint pmc_scratch22; /* _SCRATCH22_0, offset A8 */ + uint pmc_scratch23; /* _SCRATCH23_0, offset AC */ + + uint pmc_secure_scratch0; /* _SECURE_SCRATCH0_0, offset B0 */ + uint pmc_secure_scratch1; /* _SECURE_SCRATCH1_0, offset B4 */ + uint pmc_secure_scratch2; /* _SECURE_SCRATCH2_0, offset B8 */ + uint pmc_secure_scratch3; /* _SECURE_SCRATCH3_0, offset BC */ + uint pmc_secure_scratch4; /* _SECURE_SCRATCH4_0, offset C0 */ + uint pmc_secure_scratch5; /* _SECURE_SCRATCH5_0, offset C4 */ + + uint pmc_cpupwrgood_timer; /* _CPUPWRGOOD_TIMER_0, offset C8 */ + uint pmc_cpupwroff_timer; /* _CPUPWROFF_TIMER_0, offset CC */ + uint pmc_pg_mask; /* _PG_MASK_0, offset D0 */ + uint pmc_pg_mask_1; /* _PG_MASK_1_0, offset D4 */ + uint pmc_auto_wake_lvl; /* _AUTO_WAKE_LVL_0, offset D8 */ + uint pmc_auto_wake_lvl_mask; /* _AUTO_WAKE_LVL_MASK_0, offset DC */ + uint pmc_wake_delay; /* _WAKE_DELAY_0, offset E0 */ + uint pmc_pwr_det_val; /* _PWR_DET_VAL_0, offset E4 */ + uint pmc_ddr_pwr; /* _DDR_PWR_0, offset E8 */ + uint pmc_usb_debounce_del; /* _USB_DEBOUNCE_DEL_0, offset EC */ + uint pmc_usb_ao; /* _USB_AO_0, offset F0 */ + uint pmc_crypto_op; /* _CRYPTO_OP__0, offset F4 */ + uint pmc_pllp_wb0_override; /* _PLLP_WB0_OVERRIDE_0, offset F8 */ + + uint pmc_scratch24; /* _SCRATCH24_0, offset FC */ + uint pmc_scratch25; /* _SCRATCH24_0, offset 100 */ + uint pmc_scratch26; /* _SCRATCH24_0, offset 104 */ + uint pmc_scratch27; /* _SCRATCH24_0, offset 108 */ + uint pmc_scratch28; /* _SCRATCH24_0, offset 10C */ + uint pmc_scratch29; /* _SCRATCH24_0, offset 110 */ + uint pmc_scratch30; /* _SCRATCH24_0, offset 114 */ + uint pmc_scratch31; /* _SCRATCH24_0, offset 118 */ + uint pmc_scratch32; /* _SCRATCH24_0, offset 11C */ + uint pmc_scratch33; /* _SCRATCH24_0, offset 120 */ + uint pmc_scratch34; /* _SCRATCH24_0, offset 124 */ + uint pmc_scratch35; /* _SCRATCH24_0, offset 128 */ + uint pmc_scratch36; /* _SCRATCH24_0, offset 12C */ + uint pmc_scratch37; /* _SCRATCH24_0, offset 130 */ + uint pmc_scratch38; /* _SCRATCH24_0, offset 134 */ + uint pmc_scratch39; /* _SCRATCH24_0, offset 138 */ + uint pmc_scratch40; /* _SCRATCH24_0, offset 13C */ + uint pmc_scratch41; /* _SCRATCH24_0, offset 140 */ + uint pmc_scratch42; /* _SCRATCH24_0, offset 144 */ + + uint pmc_bo_mirror0; /* _BOUNDOUT_MIRROR0_0, offset 148 */ + uint pmc_bo_mirror1; /* _BOUNDOUT_MIRROR1_0, offset 14C */ + uint pmc_bo_mirror2; /* _BOUNDOUT_MIRROR2_0, offset 150 */ + uint pmc_sys_33v_en; /* _SYS_33V_EN_0, offset 154 */ + uint pmc_bo_mirror_access; /* _BOUNDOUT_MIRROR_ACCESS_0, off158 */ + uint pmc_gate; /* _GATE_0, offset 15C */ +}; + +#define CPU_PWRED 1 +#define CPU_CLMP 1 + +#define PARTID_CP 0xFFFFFFF8 +#define START_CP (1 << 8) + +#define CPUPWRREQ_OE (1 << 16) + +#endif /* PMC_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..936782b --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/pmu.h @@ -0,0 +1,30 @@ +/* + * (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 _ARCH_PMU_H_ +#define _ARCH_PMU_H_ + +/* Set core and CPU voltages to nominal levels */ +int pmu_set_nominal(void); + +#endif /* _ARCH_PMU_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/scu.h b/arch/arm/include/asm/arch-tegra30/scu.h new file mode 100644 index 0000000..420c2d7 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/scu.h @@ -0,0 +1,43 @@ +/* + * (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 _SCU_H_ +#define _SCU_H_ + +/* ARM Snoop Control Unit (SCU) registers */ +struct scu_ctlr { + uint scu_ctrl; /* SCU Control Register, offset 00 */ + uint scu_cfg; /* SCU Config Register, offset 04 */ + uint scu_cpu_pwr_stat; /* SCU CPU Power Status Register, offset 08 */ + uint scu_inv_all; /* SCU Invalidate All Register, offset 0C */ + uint scu_reserved0[12]; /* reserved, offset 10-3C */ + uint scu_filt_start; /* SCU Filtering Start Address Reg, offset 40 */ + uint scu_filt_end; /* SCU Filtering End Address Reg, offset 44 */ + uint scu_reserved1[2]; /* reserved, offset 48-4C */ + uint scu_acc_ctl; /* SCU Access Control Register, offset 50 */ + uint scu_ns_acc_ctl; /* SCU Non-secure Access Cntrl Reg, offset 54 */ +}; + +#define SCU_CTRL_ENABLE (1 << 0) + +#endif /* SCU_H */ diff --git a/arch/arm/include/asm/arch-tegra30/sys_proto.h b/arch/arm/include/asm/arch-tegra30/sys_proto.h new file mode 100644 index 0000000..6e04e37 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/sys_proto.h @@ -0,0 +1,35 @@ +/* + * (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 _SYS_PROTO_H_ +#define _SYS_PROTO_H_ + +struct tegra_sysinfo { + char *board_string; +}; + +void invalidate_dcache(void); + +extern const struct tegra_sysinfo sysinfo; + +#endif diff --git a/arch/arm/include/asm/arch-tegra30/tegra30.h b/arch/arm/include/asm/arch-tegra30/tegra30.h new file mode 100644 index 0000000..e0cce5d --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/tegra30.h @@ -0,0 +1,109 @@ +/* + * (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 _TEGRA30_H_ +#define _TEGRA30_H_ + +#define NV_PA_SDRAM_BASE 0x80000000 /* 0x80000000 for real T30 */ +#define NV_PA_ARM_PERIPHBASE 0x50040000 +#define NV_PA_PG_UP_BASE 0x60000000 +#define NV_PA_TMRUS_BASE 0x60005010 +#define NV_PA_CLK_RST_BASE 0x60006000 +#define NV_PA_FLOW_BASE 0x60007000 +#define NV_PA_AHB_BASE 0x6000C000 +#define NV_PA_GPIO_BASE 0x6000D000 +#define NV_PA_EVP_BASE 0x6000F000 +#define NV_PA_APB_MISC_BASE 0x70000000 +#define NV_PA_APB_MISC_GP_BASE (NV_PA_APB_MISC_BASE + 0x0800) +#define NV_PA_APB_UARTA_BASE (NV_PA_APB_MISC_BASE + 0x6000) +#define NV_PA_APB_UARTB_BASE (NV_PA_APB_MISC_BASE + 0x6040) +#define NV_PA_APB_UARTC_BASE (NV_PA_APB_MISC_BASE + 0x6200) +#define NV_PA_APB_UARTD_BASE (NV_PA_APB_MISC_BASE + 0x6300) +#define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400) +#define NV_PA_SPI_BASE (NV_PA_APB_MISC_BASE + 0xC380) +#define TEGRA_DVC_BASE (NV_PA_APB_MISC_BASE + 0xD000) +#define NV_PA_PMC_BASE (NV_PA_APB_MISC_BASE + 0xE400) +#define NV_PA_EMC_BASE (NV_PA_APB_MISC_BASE + 0xF400) +#define NV_PA_FUSE_BASE (NV_PA_APB_MISC_BASE + 0xF800) +#define NV_PA_CSITE_BASE 0x70040000 +#define NV_PA_SDMMC1_BASE 0x78000000 +#define NV_PA_SDMMC2_BASE 0x78000200 +#define NV_PA_SDMMC3_BASE 0x78000400 +#define NV_PA_SDMMC4_BASE 0x78000600 +#define NV_PA_USB1_BASE 0x7D000000 +#define NV_PA_USB2_BASE 0x7D004000 +#define NV_PA_USB3_BASE 0x7D008000 +#define NV_PA_USB_ADDR_MASK 0xFFFFC000 + +#define NV_PA_SDRC_CS0 NV_PA_SDRAM_BASE +#define LOW_LEVEL_SRAM_STACK 0x4000FFFC +#define EARLY_AVP_STACK (NV_PA_SDRAM_BASE + 0x20000) +#define EARLY_CPU_STACK (EARLY_AVP_STACK - 4096) +#define PG_UP_TAG_AVP 0xAAAAAAAA + +#ifndef __ASSEMBLY__ +struct timerus { + unsigned int cntr_1us; +}; + +/* Address at which WB code runs, it must not overlap Bootrom's IRAM usage */ +#define T30_WB_RUN_ADDRESS 0x40020000 + +#define NVBOOTINFOTABLE_BCTSIZE 0x38 /* BCT size in BIT in IRAM */ +#define NVBOOTINFOTABLE_BCTPTR 0x3C /* BCT pointer in BIT in IRAM */ +#define BCT_ODMDATA_OFFSET 6116 /* 12 bytes from end of BCT */ + +/* These are the available SKUs (product types) for Tegra */ +enum { + SKU_ID_T20 = 0x8, + SKU_ID_T25SE = 0x14, + SKU_ID_AP25 = 0x17, + SKU_ID_T25 = 0x18, + SKU_ID_AP25E = 0x1b, + SKU_ID_T25E = 0x1c, + + SKU_ID_T30 = 0x81, /* Cardhu value */ +}; + +/* + * 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, +}; + +#else /* __ASSEMBLY__ */ +#define PRM_RSTCTRL NV_PA_PMC_BASE +#endif + +#endif /* TEGRA30_H */ diff --git a/arch/arm/include/asm/arch-tegra30/tegra_i2c.h b/arch/arm/include/asm/arch-tegra30/tegra_i2c.h new file mode 100644 index 0000000..cd54924 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/tegra_i2c.h @@ -0,0 +1,164 @@ +/* + * NVIDIA Tegra I2C controller + * + * Copyright 2010-2012 NVIDIA Corporation + * + * This software may be used and distributed according to the + * terms of the GNU Public License, Version 2, incorporated + * herein by reference. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * 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_I2C_H_ +#define _TEGRA_I2C_H_ + +#include <asm/types.h> + +enum { + I2C_TIMEOUT_USEC = 10000, /* Wait time for completion */ + I2C_FIFO_DEPTH = 8, /* I2C fifo depth */ +}; + +enum i2c_transaction_flags { + I2C_IS_WRITE = 0x1, /* for I2C write operation */ + I2C_IS_10_BIT_ADDRESS = 0x2, /* for 10-bit I2C slave address */ + I2C_USE_REPEATED_START = 0x4, /* for repeat start */ + I2C_NO_ACK = 0x8, /* for slave that won't generate ACK */ + I2C_SOFTWARE_CONTROLLER = 0x10, /* for I2C transfer using GPIO */ + I2C_NO_STOP = 0x20, +}; + +/* Contians the I2C transaction details */ +struct i2c_trans_info { + /* flags to indicate the transaction details */ + enum i2c_transaction_flags flags; + u32 address; /* I2C slave device address */ + u32 num_bytes; /* number of bytes to be transferred */ + /* + * Send/receive buffer. For the I2C send operation this buffer should + * be filled with the data to be sent to the slave device. For the I2C + * receive operation this buffer is filled with the data received from + * the slave device. + */ + u8 *buf; + int is_10bit_address; +}; + +struct i2c_control { + u32 tx_fifo; + u32 rx_fifo; + u32 packet_status; + u32 fifo_control; + u32 fifo_status; + u32 int_mask; + u32 int_status; +}; + +struct dvc_ctlr { + u32 ctrl1; /* 00: DVC_CTRL_REG1 */ + u32 ctrl2; /* 04: DVC_CTRL_REG2 */ + u32 ctrl3; /* 08: DVC_CTRL_REG3 */ + u32 status; /* 0C: DVC_STATUS_REG */ + u32 ctrl; /* 10: DVC_I2C_CTRL_REG */ + u32 addr_data; /* 14: DVC_I2C_ADDR_DATA_REG */ + u32 reserved_0[2]; /* 18: */ + u32 req; /* 20: DVC_REQ_REGISTER */ + u32 addr_data3; /* 24: DVC_I2C_ADDR_DATA_REG_3 */ + u32 reserved_1[6]; /* 28: */ + u32 cnfg; /* 40: DVC_I2C_CNFG */ + u32 cmd_addr0; /* 44: DVC_I2C_CMD_ADDR0 */ + u32 cmd_addr1; /* 48: DVC_I2C_CMD_ADDR1 */ + u32 cmd_data1; /* 4C: DVC_I2C_CMD_DATA1 */ + u32 cmd_data2; /* 50: DVC_I2C_CMD_DATA2 */ + u32 reserved_2[2]; /* 54: */ + u32 i2c_status; /* 5C: DVC_I2C_STATUS */ + struct i2c_control control; /* 60 ~ 78 */ +}; + +struct i2c_ctlr { + u32 cnfg; /* 00: I2C_I2C_CNFG */ + u32 cmd_addr0; /* 04: I2C_I2C_CMD_ADDR0 */ + u32 cmd_addr1; /* 08: I2C_I2C_CMD_DATA1 */ + u32 cmd_data1; /* 0C: I2C_I2C_CMD_DATA2 */ + u32 cmd_data2; /* 10: DVC_I2C_CMD_DATA2 */ + u32 reserved_0[2]; /* 14: */ + u32 status; /* 1C: I2C_I2C_STATUS */ + u32 sl_cnfg; /* 20: I2C_I2C_SL_CNFG */ + u32 sl_rcvd; /* 24: I2C_I2C_SL_RCVD */ + u32 sl_status; /* 28: I2C_I2C_SL_STATUS */ + u32 sl_addr1; /* 2C: I2C_I2C_SL_ADDR1 */ + u32 sl_addr2; /* 30: I2C_I2C_SL_ADDR2 */ + u32 reserved_1[2]; /* 34: */ + u32 sl_delay_count; /* 3C: I2C_I2C_SL_DELAY_COUNT */ + u32 reserved_2[4]; /* 40: */ + struct i2c_control control; /* 50 ~ 68 */ +}; + +/* bit fields definitions for IO Packet Header 1 format */ +#define PKT_HDR1_PROTOCOL_SHIFT 4 +#define PKT_HDR1_PROTOCOL_MASK (0xf << PKT_HDR1_PROTOCOL_SHIFT) +#define PKT_HDR1_CTLR_ID_SHIFT 12 +#define PKT_HDR1_CTLR_ID_MASK (0xf << PKT_HDR1_CTLR_ID_SHIFT) +#define PKT_HDR1_PKT_ID_SHIFT 16 +#define PKT_HDR1_PKT_ID_MASK (0xff << PKT_HDR1_PKT_ID_SHIFT) +#define PROTOCOL_TYPE_I2C 1 + +/* bit fields definitions for IO Packet Header 2 format */ +#define PKT_HDR2_PAYLOAD_SIZE_SHIFT 0 +#define PKT_HDR2_PAYLOAD_SIZE_MASK (0xfff << PKT_HDR2_PAYLOAD_SIZE_SHIFT) + +/* bit fields definitions for IO Packet Header 3 format */ +#define PKT_HDR3_READ_MODE_SHIFT 19 +#define PKT_HDR3_READ_MODE_MASK (1 << PKT_HDR3_READ_MODE_SHIFT) +#define PKT_HDR3_SLAVE_ADDR_SHIFT 0 +#define PKT_HDR3_SLAVE_ADDR_MASK (0x3ff << PKT_HDR3_SLAVE_ADDR_SHIFT) + +#define DVC_CTRL_REG3_I2C_HW_SW_PROG_SHIFT 26 +#define DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK \ + (1 << DVC_CTRL_REG3_I2C_HW_SW_PROG_SHIFT) + +/* I2C_CNFG */ +#define I2C_CNFG_NEW_MASTER_FSM_SHIFT 11 +#define I2C_CNFG_NEW_MASTER_FSM_MASK (1 << I2C_CNFG_NEW_MASTER_FSM_SHIFT) +#define I2C_CNFG_PACKET_MODE_SHIFT 10 +#define I2C_CNFG_PACKET_MODE_MASK (1 << I2C_CNFG_PACKET_MODE_SHIFT) + +/* I2C_SL_CNFG */ +#define I2C_SL_CNFG_NEWSL_SHIFT 2 +#define I2C_SL_CNFG_NEWSL_MASK (1 << I2C_SL_CNFG_NEWSL_SHIFT) + +/* I2C_FIFO_STATUS */ +#define TX_FIFO_FULL_CNT_SHIFT 0 +#define TX_FIFO_FULL_CNT_MASK (0xf << TX_FIFO_FULL_CNT_SHIFT) +#define TX_FIFO_EMPTY_CNT_SHIFT 4 +#define TX_FIFO_EMPTY_CNT_MASK (0xf << TX_FIFO_EMPTY_CNT_SHIFT) + +/* I2C_INTERRUPT_STATUS */ +#define I2C_INT_XFER_COMPLETE_SHIFT 7 +#define I2C_INT_XFER_COMPLETE_MASK (1 << I2C_INT_XFER_COMPLETE_SHIFT) +#define I2C_INT_NO_ACK_SHIFT 3 +#define I2C_INT_NO_ACK_MASK (1 << I2C_INT_NO_ACK_SHIFT) +#define I2C_INT_ARBITRATION_LOST_SHIFT 2 +#define I2C_INT_ARBITRATION_LOST_MASK (1 << I2C_INT_ARBITRATION_LOST_SHIFT) + +/** + * Returns the bus number of the DVC controller + * + * @return number of bus, or -1 if there is no DVC active + */ +int tegra_i2c_get_dvc_bus_num(void); + +#endif /* _TEGRA_I2C_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/timer.h b/arch/arm/include/asm/arch-tegra30/timer.h new file mode 100644 index 0000000..0c5ef62 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/timer.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (C) 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 + */ + +/* Tegra timer functions */ + +#ifndef _TEGRA_TIMER_H +#define _TEGRA_TIMER_H + +/* returns the current monotonic timer value in microseconds */ +unsigned long timer_get_us(void); + +#endif /* _TEGRA_TIMER_H */ diff --git a/arch/arm/include/asm/arch-tegra30/uart.h b/arch/arm/include/asm/arch-tegra30/uart.h new file mode 100644 index 0000000..b34f6d9 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/uart.h @@ -0,0 +1,47 @@ +/* + * (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 _UART_H_ +#define _UART_H_ + +/* UART registers */ +struct uart_ctlr { + uint uart_thr_dlab_0; /* UART_THR_DLAB_0_0, offset 00 */ + uint uart_ier_dlab_0; /* UART_IER_DLAB_0_0, offset 04 */ + uint uart_iir_fcr; /* UART_IIR_FCR_0, offset 08 */ + uint uart_lcr; /* UART_LCR_0, offset 0C */ + uint uart_mcr; /* UART_MCR_0, offset 10 */ + uint uart_lsr; /* UART_LSR_0, offset 14 */ + uint uart_msr; /* UART_MSR_0, offset 18 */ + uint uart_spr; /* UART_SPR_0, offset 1C */ + uint uart_irda_csr; /* UART_IRDA_CSR_0, offset 20 */ + uint uart_reserved[6]; /* Reserved, unused, offset 24-38*/ + uint uart_asr; /* UART_ASR_0, offset 3C */ +}; + +#define NVRM_PLLP_FIXED_FREQ_KHZ 216000 +#define NV_DEFAULT_DEBUG_BAUD 115200 + +#define UART_FCR_TRIGGER_3 0x30 /* Mask for trigger set at 3 */ + +#endif /* UART_H */ diff --git a/arch/arm/include/asm/arch-tegra30/usb.h b/arch/arm/include/asm/arch-tegra30/usb.h new file mode 100644 index 0000000..1f53c49 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/usb.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (C) 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_USB_H_ +#define _TEGRA_USB_H_ + + +/* USB Controller (USBx_CONTROLLER_) regs */ +struct usb_ctlr { + /* 0x000 */ + uint id; + uint reserved0; + uint host; + uint device; + + /* 0x010 */ + uint txbuf; + uint rxbuf; + uint reserved1[2]; + + /* 0x020 */ + uint reserved2[56]; + + /* 0x100 */ + u16 cap_length; + u16 hci_version; + uint hcs_params; + uint hcc_params; + uint reserved3[5]; + + /* 0x120 */ + uint dci_version; + uint dcc_params; + uint reserved4[6]; + + /* 0x140 */ + uint usb_cmd; + uint usb_sts; + uint usb_intr; + uint frindex; + + /* 0x150 */ + uint reserved5; + uint periodic_list_base; + uint async_list_addr; + uint async_tt_sts; + + /* 0x160 */ + uint burst_size; + uint tx_fill_tuning; + uint reserved6; /* is this port_sc1 on some controllers? */ + uint icusb_ctrl; + + /* 0x170 */ + uint ulpi_viewport; + uint reserved7; + uint endpt_nak; + uint endpt_nak_enable; + + /* 0x180 */ + uint reserved; + uint port_sc1; + uint reserved8[6]; + + /* 0x1a0 */ + uint reserved9; + uint otgsc; + uint usb_mode; + uint endpt_setup_stat; + + /* 0x1b0 */ + uint reserved10[20]; + + /* 0x200 */ + uint reserved11[0x80]; + + /* 0x400 */ + uint susp_ctrl; + uint phy_vbus_sensors; + uint phy_vbus_wakeup_id; + uint phy_alt_vbus_sys; + + /* 0x410 */ + uint usb1_legacy_ctrl; + uint reserved12[3]; + + /* 0x420 */ + uint reserved13[56]; + + /* 0x500 */ + uint reserved14[64 * 3]; + + /* 0x800 */ + uint utmip_pll_cfg0; + uint utmip_pll_cfg1; + uint utmip_xcvr_cfg0; + uint utmip_bias_cfg0; + + /* 0x810 */ + uint utmip_hsrx_cfg0; + uint utmip_hsrx_cfg1; + uint utmip_fslsrx_cfg0; + uint utmip_fslsrx_cfg1; + + /* 0x820 */ + uint utmip_tx_cfg0; + uint utmip_misc_cfg0; + uint utmip_misc_cfg1; + uint utmip_debounce_cfg0; + + /* 0x830 */ + uint utmip_bat_chrg_cfg0; + uint utmip_spare_cfg0; + uint utmip_xcvr_cfg1; + uint utmip_bias_cfg1; +}; + + +/* USB1_LEGACY_CTRL */ +#define USB1_NO_LEGACY_MODE 1 + +#define VBUS_SENSE_CTL_SHIFT 1 +#define VBUS_SENSE_CTL_MASK (3 << VBUS_SENSE_CTL_SHIFT) +#define VBUS_SENSE_CTL_VBUS_WAKEUP 0 +#define VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP 1 +#define VBUS_SENSE_CTL_AB_SESS_VLD 2 +#define VBUS_SENSE_CTL_A_SESS_VLD 3 + +/* USBx_IF_USB_SUSP_CTRL_0 */ +#define UTMIP_PHY_ENB (1 << 12) +#define UTMIP_RESET (1 << 11) +#define USB_PHY_CLK_VALID (1 << 7) + +/* USBx_UTMIP_MISC_CFG1 */ +#define UTMIP_PLLU_STABLE_COUNT_SHIFT 6 +#define UTMIP_PLLU_STABLE_COUNT_MASK \ + (0xfff << UTMIP_PLLU_STABLE_COUNT_SHIFT) +#define UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT 18 +#define UTMIP_PLL_ACTIVE_DLY_COUNT_MASK \ + (0x1f << UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT) +#define UTMIP_PHY_XTAL_CLOCKEN (1 << 30) + +/* USBx_UTMIP_PLL_CFG1_0 */ +#define UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT 27 +#define UTMIP_PLLU_ENABLE_DLY_COUNT_MASK \ + (0xf << UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT) +#define UTMIP_XTAL_FREQ_COUNT_SHIFT 0 +#define UTMIP_XTAL_FREQ_COUNT_MASK 0xfff + +/* USBx_UTMIP_BIAS_CFG1_0 */ +#define UTMIP_BIAS_PDTRK_COUNT_SHIFT 3 +#define UTMIP_BIAS_PDTRK_COUNT_MASK \ + (0x1f << UTMIP_BIAS_PDTRK_COUNT_SHIFT) + +#define UTMIP_DEBOUNCE_CFG0_SHIFT 0 +#define UTMIP_DEBOUNCE_CFG0_MASK 0xffff + +/* USBx_UTMIP_TX_CFG0_0 */ +#define UTMIP_FS_PREAMBLE_J (1 << 19) + +/* USBx_UTMIP_BAT_CHRG_CFG0_0 */ +#define UTMIP_PD_CHRG 1 + +/* USBx_UTMIP_XCVR_CFG0_0 */ +#define UTMIP_XCVR_LSBIAS_SE (1 << 21) + +/* USBx_UTMIP_SPARE_CFG0_0 */ +#define FUSE_SETUP_SEL (1 << 3) + +/* USBx_UTMIP_HSRX_CFG0_0 */ +#define UTMIP_IDLE_WAIT_SHIFT 15 +#define UTMIP_IDLE_WAIT_MASK (0x1f << UTMIP_IDLE_WAIT_SHIFT) +#define UTMIP_ELASTIC_LIMIT_SHIFT 10 +#define UTMIP_ELASTIC_LIMIT_MASK \ + (0x1f << UTMIP_ELASTIC_LIMIT_SHIFT) + +/* USBx_UTMIP_HSRX_CFG0_1 */ +#define UTMIP_HS_SYNC_START_DLY_SHIFT 1 +#define UTMIP_HS_SYNC_START_DLY_MASK \ + (0xf << UTMIP_HS_SYNC_START_DLY_SHIFT) + +/* USBx_CONTROLLER_2_USB2D_ICUSB_CTRL_0 */ +#define IC_ENB1 (1 << 3) + +/* SB2_CONTROLLER_2_USB2D_PORTSC1_0 */ +#define PTS_SHIFT 30 +#define PTS_MASK (3U << PTS_SHIFT) +#define PTS_UTMI 0 +#define PTS_RESERVED 1 +#define PTS_ULP 2 +#define PTS_ICUSB_SER 3 + +#define STS (1 << 29) + +/* USBx_UTMIP_XCVR_CFG0_0 */ +#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) +#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) +#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) + +/* USBx_UTMIP_XCVR_CFG1_0 */ +#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) +#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) +#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) + +/* USB3_IF_USB_PHY_VBUS_SENSORS_0 */ +#define VBUS_VLD_STS (1 << 26) + + +/* Change the USB host port into host mode */ +void usb_set_host_mode(void); + +/* Setup USB on the board */ +int board_usb_init(const void *blob); + +/** + * Start up the given port number (ports are numbered from 0 on each board). + * This returns values for the appropriate hccr and hcor addresses to use for + * USB EHCI operations. + * + * @param portnum port number to start + * @param hccr returns start address of EHCI HCCR registers + * @param hcor returns start address of EHCI HCOR registers + * @return 0 if ok, -1 on error (generally invalid port number) + */ +int tegrausb_start_port(unsigned portnum, u32 *hccr, u32 *hcor); + +/** + * Stop the current port + * + * @return 0 if ok, -1 if no port was active + */ +int tegrausb_stop_port(void); + +#endif /* _TEGRA_USB_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/warmboot.h b/arch/arm/include/asm/arch-tegra30/warmboot.h new file mode 100644 index 0000000..ff3acff --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/warmboot.h @@ -0,0 +1,150 @@ +/* + * (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 _WARM_BOOT_H_ +#define _WARM_BOOT_H_ + +#define STRAP_OPT_A_RAM_CODE_SHIFT 4 +#define STRAP_OPT_A_RAM_CODE_MASK (0xf << STRAP_OPT_A_RAM_CODE_SHIFT) + +/* Defines the supported operating modes */ +enum fuse_operating_mode { + MODE_PRODUCTION = 3, + MODE_UNDEFINED, +}; + +/* Defines the CMAC-AES-128 hash length in 32 bit words. (128 bits = 4 words) */ +enum { + HASH_LENGTH = 4 +}; + +/* Defines the storage for a hash value (128 bits) */ +struct hash { + u32 hash[HASH_LENGTH]; +}; + +/* + * Defines the code header information for the boot rom. + * + * The code immediately follows the code header. + * + * Note that the code header needs to be 16 bytes aligned to preserve + * the alignment of relevant data for hash and decryption computations without + * requiring extra copies to temporary memory areas. + */ +struct wb_header { + u32 length_insecure; /* length of the code header */ + u32 reserved[3]; + struct hash hash; /* hash of header+code, starts next field*/ + struct hash random_aes_block; /* a data block to aid security. */ + u32 length_secure; /* length of the code header */ + u32 destination; /* destination address to put the wb code */ + u32 entry_point; /* execution address of the wb code */ + u32 code_length; /* length of the code */ +}; + +/* + * The warm boot code needs direct access to these registers since it runs in + * SRAM and cannot call other U-Boot code. + */ +union osc_ctrl_reg { + struct { + u32 xoe:1; + u32 xobp:1; + u32 reserved0:2; + u32 xofs:6; + u32 reserved1:2; + u32 xods:5; + u32 reserved2:3; + u32 oscfi_spare:8; + u32 pll_ref_div:2; + u32 osc_freq:2; + }; + u32 word; +}; + +union pllx_base_reg { + struct { + u32 divm:5; + u32 reserved0:3; + u32 divn:10; + u32 reserved1:2; + u32 divp:3; + u32 reserved2:4; + u32 lock:1; + u32 reserved3:1; + u32 ref_dis:1; + u32 enable:1; + u32 bypass:1; + }; + u32 word; +}; + +union pllx_misc_reg { + struct { + u32 vcocon:4; + u32 lfcon:4; + u32 cpcon:4; + u32 lock_sel:6; + u32 reserved0:1; + u32 lock_enable:1; + u32 reserved1:1; + u32 dccon:1; + u32 pts:2; + u32 reserved2:6; + u32 out1_div_byp:1; + u32 out1_inv_clk:1; + }; + u32 word; +}; + +/* + * TODO: This register is not documented in the TRM yet. We could move this + * into the EMC and give it a proper interface, but not while it is + * undocumented. + */ +union scratch3_reg { + struct { + u32 pllx_base_divm:5; + u32 pllx_base_divn:10; + u32 pllx_base_divp:3; + u32 pllx_misc_lfcon:4; + u32 pllx_misc_cpcon:4; + }; + u32 word; +}; + + +/** + * Save warmboot memory settings for a later resume + * + * @return 0 if ok, -1 on error + */ +int warmboot_save_sdram_params(void); + +int warmboot_prepare_code(u32 seg_address, u32 seg_length); +int sign_data_block(u8 *source, u32 length, u8 *signature); +void wb_start(void); /* Start of WB assembly code */ +void wb_end(void); /* End of WB assembly code */ + +#endif

On Wed, Sep 12, 2012 at 03:10:47PM -0700, Tom Warren wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
A few things: - I see some #define FOO[space][space]val that should be [tab] - I didn't checkpatch.pl this (nor the whole series) but please do and let us know if it's clean or why the warnings are false positives. - My preference is to bring in includes and C files and Makefiles and so on all at once, when each is needed / useful. YMMV and not a big deal. - But please make sure that you aren't adding defines / structs / etc that aren't used at some point by the end of the series at least. Removing (and correcting!) structs and defines was one of the things I had to do on am33xx. If it wasn't added until the corresponding driver work was being pushed, it'd have saved me some time.

Tom,
On Thu, Sep 13, 2012 at 11:06 AM, Tom Rini trini@ti.com wrote:
On Wed, Sep 12, 2012 at 03:10:47PM -0700, Tom Warren wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
A few things:
- I see some #define FOO[space][space]val that should be [tab]
Probably copied over from Tegra20 files. I'll turn on whitespace highlighting in my editor and fix 'em up.
- I didn't checkpatch.pl this (nor the whole series) but please do and let us know if it's clean or why the warnings are false positives.
I always run checkpath before submitting. I'll put a notice to that affect in the next version. Checkpatch ran clean w/only 1 false-positive about 'macros with complex values should be enclosed in parenthesis' for the "#define CONFIG_DEFAULT_DEVICE_TREE tegra30-cardhu" line in cardhu.h.
- My preference is to bring in includes and C files and Makefiles and so on all at once, when each is needed / useful. YMMV and not a big deal.
- But please make sure that you aren't adding defines / structs / etc that aren't used at some point by the end of the series at least. Removing (and correcting!) structs and defines was one of the things I had to do on am33xx. If it wasn't added until the corresponding driver work was being pushed, it'd have saved me some time.
Sure, and that's good advice. I took a couple of passes during the port to try and remove vestigial and/or useless/unsupported files, features, and code, but I'm sure I missed some (as Stephen has already pointed out). I'll address those in V2.
Thanks,
Tom
-- Tom

Hi Tom,
On Thu, Sep 13, 2012 at 2:10 PM, Tom Warren twarren.nvidia@gmail.com wrote:
Tom,
On Thu, Sep 13, 2012 at 11:06 AM, Tom Rini trini@ti.com wrote:
On Wed, Sep 12, 2012 at 03:10:47PM -0700, Tom Warren wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
A few things:
- I see some #define FOO[space][space]val that should be [tab]
Probably copied over from Tegra20 files. I'll turn on whitespace highlighting in my editor and fix 'em up.
- I didn't checkpatch.pl this (nor the whole series) but please do and let us know if it's clean or why the warnings are false positives.
I always run checkpath before submitting. I'll put a notice to that affect in the next version. Checkpatch ran clean w/only 1 false-positive about 'macros with complex values should be enclosed in parenthesis' for the "#define CONFIG_DEFAULT_DEVICE_TREE tegra30-cardhu" line in cardhu.h.
- My preference is to bring in includes and C files and Makefiles and so on all at once, when each is needed / useful. YMMV and not a big deal.
- But please make sure that you aren't adding defines / structs / etc that aren't used at some point by the end of the series at least. Removing (and correcting!) structs and defines was one of the things I had to do on am33xx. If it wasn't added until the corresponding driver work was being pushed, it'd have saved me some time.
Sure, and that's good advice. I took a couple of passes during the port to try and remove vestigial and/or useless/unsupported files, features, and code, but I'm sure I missed some (as Stephen has already pointed out). I'll address those in V2.
Congrats on getting this out. It is a lot of work!
In the Chromium tree, we have an arch-tegra directory where a lot of the common code lives. It sounds like you are going to split that out a bit which is good. I suspect you may also want a few patches to move quite a bit of the code in arch/arm/include/arch-tegra20 to arch/arm/include/arch-tegra.
Regards, Simon
Thanks,
Tom
-- Tom
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Simon,
On Tue, Sep 18, 2012 at 12:29 PM, Simon Glass sjg@chromium.org wrote:
Hi Tom,
On Thu, Sep 13, 2012 at 2:10 PM, Tom Warren twarren.nvidia@gmail.com wrote:
Tom,
On Thu, Sep 13, 2012 at 11:06 AM, Tom Rini trini@ti.com wrote:
On Wed, Sep 12, 2012 at 03:10:47PM -0700, Tom Warren wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
A few things:
- I see some #define FOO[space][space]val that should be [tab]
Probably copied over from Tegra20 files. I'll turn on whitespace highlighting in my editor and fix 'em up.
- I didn't checkpatch.pl this (nor the whole series) but please do and let us know if it's clean or why the warnings are false positives.
I always run checkpath before submitting. I'll put a notice to that affect in the next version. Checkpatch ran clean w/only 1 false-positive about 'macros with complex values should be enclosed in parenthesis' for the "#define CONFIG_DEFAULT_DEVICE_TREE tegra30-cardhu" line in cardhu.h.
- My preference is to bring in includes and C files and Makefiles and so on all at once, when each is needed / useful. YMMV and not a big deal.
- But please make sure that you aren't adding defines / structs / etc that aren't used at some point by the end of the series at least. Removing (and correcting!) structs and defines was one of the things I had to do on am33xx. If it wasn't added until the corresponding driver work was being pushed, it'd have saved me some time.
Sure, and that's good advice. I took a couple of passes during the port to try and remove vestigial and/or useless/unsupported files, features, and code, but I'm sure I missed some (as Stephen has already pointed out). I'll address those in V2.
Congrats on getting this out. It is a lot of work!
In the Chromium tree, we have an arch-tegra directory where a lot of the common code lives. It sounds like you are going to split that out a bit which is good. I suspect you may also want a few patches to move quite a bit of the code in arch/arm/include/arch-tegra20 to arch/arm/include/arch-tegra.
As per a side-discussion with TomR and StephenW, I am in the process of recasting this T30 patchset as a move to common Tegra code. It'll mimic quite a lot of the Chromium U-Boot directory structure, I'm sure.
Thanks,
Tom
Regards, Simon
Thanks,
Tom
-- Tom
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 09/12/2012 04:10 PM, Tom Warren wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
Hmm. This is rather large to review, but I tried to at least glance through it all and spot obvious issues...
diff --git a/arch/arm/include/asm/arch-tegra30/ap30.h b/arch/arm/include/asm/arch-tegra30/ap30.h
+/* T30 Base physical address of SDRAM. */ +#define T30_BASE_PA_SDRAM 0x00000000
That should be 0x80000000. The fact anything still works with this issue implies this constant isn't used anywhere? Aha, I see NV_PA_SDRAM_BASE defined later with the correct value...
+/* T30 Base physical address of flash. */ +#define T30_BASE_PA_NOR_FLASH 0xD0000000
I don't know where NOR actually is mapped, but it can't be there; that's in the middle of SDRAM (2G..4G-1)
diff --git a/arch/arm/include/asm/arch-tegra30/board.h b/arch/arm/include/asm/arch-tegra30/board.h
+#ifndef _TEGRA_BOARD_H_ +#define _TEGRA_BOARD_H_
I wonder if include guards shouldn't say TEGRA30 not just TEGRA. That would avoid any conflict between the different arch/arm/include/asm/arch-tegra* directories. Sure, that's unlikely right now, but if we really continue to push device tree, maybe we'll end up with a unified Tegra20/Tegra30 bootloader image, and need to include both.
diff --git a/arch/arm/include/asm/arch-tegra30/clk_rst.h b/arch/arm/include/asm/arch-tegra30/clk_rst.h
+#ifndef _CLK_RST_H_ +#define _CLK_RST_H_
Hmm, and the naming format isn't consistent.
+/* The clocks supported by the hardware */ +enum periph_id {
- PERIPH_ID_FIRST,
...
+/*
- 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,
...
Can you make sure that one/both (whichever is appropriate) of these line up with the proposed Linux kernel Tegra30 clock binding clock IDs. I'm not sure if the Tegra30 proposed binding has been published yet, but Prashant Gaikwad can email you the patch off-list if you need.
+void clock_enable(enum periph_id clkid);
Hmm. I would have expected all the prototypes to be in a common header between Tegra20 and Tegra30?
diff --git a/arch/arm/include/asm/arch-tegra30/funcmux.h b/arch/arm/include/asm/arch-tegra30/funcmux.h
+/* Configs supported by the func mux */ +enum {
- FUNCMUX_DEFAULT = 0, /* default config */
- /* UART configs */
- FUNCMUX_UART1_ULPI_UART2 = 0,
- FUNCMUX_UART2_IRDA = 0,
- FUNCMUX_UART4_GMC = 0,
- /* I2C configs */
- FUNCMUX_DVC_I2CP = 0,
- FUNCMUX_I2C1_RM = 0,
- FUNCMUX_I2C2_DDC = 0,
- FUNCMUX_I2C2_PTA,
- FUNCMUX_I2C3_DTF = 0,
- /* SDMMC configs */
- FUNCMUX_SDMMC1_SDIO1_4BIT = 0,
- FUNCMUX_SDMMC2_DTA_DTD_8BIT = 0,
- FUNCMUX_SDMMC3_SDB_4BIT = 0,
- FUNCMUX_SDMMC3_SDB_SLXA_8BIT,
- FUNCMUX_SDMMC4_ATC_ATD_8BIT = 0,
- FUNCMUX_SDMMC4_ATB_GMA_4_BIT,
- FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT,
- /* USB configs */
- FUNCMUX_USB2_ULPI = 0,
- /* Serial Flash configs */
- FUNCMUX_SPI1_GMC_GMD = 0,
+};
Those all look like Tegra20 options. Tegra30 doesn't have mux pin groups (muxing is per-pin now), so names like DTA, DTD, SDB, SLXA, ATB, GMA, ... above don't make any sense (they're Tegra20 pin group names).
In turn, I wonder if a funcmux.h-style API even makes sense for Tegra30, since the number of legal configurations is probably too large to usefully enumerate, but that is perhaps another question.
diff --git a/arch/arm/include/asm/arch-tegra30/gp_padctrl.h b/arch/arm/include/asm/arch-tegra30/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 cdevcfg1; /* 0x78: APB_MISC_GP_CDEV1CFGPADCTRL */
- u32 cdevcfg2; /* 0x7C: APB_MISC_GP_CDEV2CFGPADCTRL */
- u32 csuscfg; /* 0x80: APB_MISC_GP_CSUSCFGPADCTRL */
- u32 dap1cfg; /* 0x84: APB_MISC_GP_DAP1CFGPADCTRL */
- u32 dap2cfg; /* 0x88: APB_MISC_GP_DAP2CFGPADCTRL */
- u32 dap3cfg; /* 0x8C: APB_MISC_GP_DAP3CFGPADCTRL */
- u32 dap4cfg; /* 0x90: APB_MISC_GP_DAP4CFGPADCTRL */
- u32 dbgcfg; /* 0x94: APB_MISC_GP_DBGCFGPADCTRL */
- u32 lcdcfg1; /* 0x98: APB_MISC_GP_LCDCFG1PADCTRL */
- u32 lcdcfg2; /* 0x9C: APB_MISC_GP_LCDCFG2PADCTRL */
- u32 sdmmc2_cfg; /* 0xA0: APB_MISC_GP_SDMMC2CFGPADCTRL */
- u32 sdmmc3_cfg; /* 0xA4: APB_MISC_GP_SDMMC3CFGPADCTRL */
- u32 spicfg; /* 0xA8: APB_MISC_GP_SPICFGPADCTRL */
- u32 uaacfg; /* 0xAC: APB_MISC_GP_UAACFGPADCTRL */
- u32 uabcfg; /* 0xB0: APB_MISC_GP_UABCFGPADCTRL */
- u32 uart2cfg; /* 0xB4: APB_MISC_GP_UART2CFGPADCTRL */
- u32 uart3cfg; /* 0xB8: APB_MISC_GP_UART3CFGPADCTRL */
- u32 vicfg1; /* 0xBC: APB_MISC_GP_VICFG1PADCTRL */
- u32 vicfg2; /* 0xC0: APB_MISC_GP_VICFG2PADCTRL */
- u32 xm2cfga; /* 0xC4: APB_MISC_GP_XM2CFGAPADCTRL */
- u32 xm2cfgc; /* 0xC8: APB_MISC_GP_XM2CFGCPADCTRL */
- u32 xm2cfgd; /* 0xCC: APB_MISC_GP_XM2CFGDPADCTRL */
- u32 xm2clkcfg; /* 0xD0: APB_MISC_GP_XM2CLKCFGPADCTRL */
- u32 memcomp; /* 0xD4: APB_MISC_GP_MEMCOMPPADCTRL */
+};
That is the Tegra20 layout. It's change for Tegra30. The set of fields is probably even quite different.
+/* 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
There should be a Tegra30 define here, and since that register is common between Tegra20 and Tegra30, I'd expect this to be in a common header.
diff --git a/arch/arm/include/asm/arch-tegra30/mmc.h b/arch/arm/include/asm/arch-tegra30/mmc.h
+int tegra_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio);
Wouldn't this be common too?
diff --git a/arch/arm/include/asm/arch-tegra30/pinmux.h b/arch/arm/include/asm/arch-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,
Hmmm. This enum appears to have been picked based on register order in the pin controller which I suppose is fine.
However, that order doesn't match the GPIO order, so if you ever want function gpio_request(n) to program both the GPIO controller and pin controller, then you'll need a table to convert between the two sets of IDs. For better or worse, the device tree binding for the Tegra30 pin controller lists the names based on GPIO ID order, and hence if the bindings are ever converted to integer-based rather than string-based, would probably number the pins based on GPIO order too.
I guess this means that either way you'll need a mapping table, either from gpio-or-binding-id to pinmux register, or from this enum to pinmux-register.
So I guess that means this enum is fine - it's just something to watch out for.
+/*
- 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_AHB_CLK,
- PMUX_FUNC_APB_CLK,
- PMUX_FUNC_AUDIO_SYNC,
- PMUX_FUNC_CRT,
- PMUX_FUNC_DAP1,
...
Could you possibly update the order of this enum to match the Linux kernel; see drivers/pinctrl/pinctrl-tegra30.c. Again, such an order would be more likely to match any integer-based device-tree pinmux binding.
Re-ordering this shouldn't be an issue since as the comment says there must be a conversion table anyway.
+/* 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]; /* offset 0x3000 */
- uint pmt_ctl[PINGRP_COUNT]; /* pin mux/pupd/tristate regs */
+};
Isn't pmc_ctrl at 0x3000; the second comment above appears misleading. Also, PMUX_OFFSET isn't right; the offset is 0x3000; it's more like RESERVED5_SIZE.
+/**
- Configuure a list of pin groups
Typo above.
diff --git a/arch/arm/include/asm/arch-tegra30/pmu.h b/arch/arm/include/asm/arch-tegra30/pmu.h
+/* Set core and CPU voltages to nominal levels */ +int pmu_set_nominal(void);
That also seems common. I'll stop pointing this issue out.
diff --git a/arch/arm/include/asm/arch-tegra30/tegra30.h b/arch/arm/include/asm/arch-tegra30/tegra30.h
+/* These are the available SKUs (product types) for Tegra */ +enum {
- SKU_ID_T20 = 0x8,
- SKU_ID_T25SE = 0x14,
- SKU_ID_AP25 = 0x17,
- SKU_ID_T25 = 0x18,
- SKU_ID_AP25E = 0x1b,
- SKU_ID_T25E = 0x1c,
- SKU_ID_T30 = 0x81, /* Cardhu value */
+};
There's little point defining Tegra20-specific values unless this header is shared between the two SoCs. Same for:
+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-tegra30/warmboot.h b/arch/arm/include/asm/arch-tegra30/warmboot.h
At a quick glance, this header appears identical to Tegra20, yet given the differences between sleep modes on the two SoCs, I'd expect to see quite a few differences. I know a lot of extra PMC scratch registers were added on Tegra30 in order to support the sleep mode code, and hence it works quite differently...
Overall, it might help identify problems if you passed the "-C" option to "git format-patch"; that would show up any headers that had simply been copied from Tegra20 without necessary modifications.

Stephen,
On Thu, Sep 13, 2012 at 12:35 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
Hmm. This is rather large to review, but I tried to at least glance through it all and spot obvious issues...
diff --git a/arch/arm/include/asm/arch-tegra30/ap30.h b/arch/arm/include/asm/arch-tegra30/ap30.h
+/* T30 Base physical address of SDRAM. */ +#define T30_BASE_PA_SDRAM 0x00000000
That should be 0x80000000. The fact anything still works with this issue implies this constant isn't used anywhere? Aha, I see NV_PA_SDRAM_BASE defined later with the correct value...
Yep, T30_BASE_PA_SDRAM isn't used anywhere - just converted from AP20_BASE_PA_SDRAM when I created ap30.h. I'll delete it.
+/* T30 Base physical address of flash. */ +#define T30_BASE_PA_NOR_FLASH 0xD0000000
I don't know where NOR actually is mapped, but it can't be there; that's in the middle of SDRAM (2G..4G-1)
Again, copied when converting ap20.h to ap30.h. NOR Flash is @ 0x4800:0000 on T30. I'll just delete it, as no one uses it.
diff --git a/arch/arm/include/asm/arch-tegra30/board.h b/arch/arm/include/asm/arch-tegra30/board.h
+#ifndef _TEGRA_BOARD_H_ +#define _TEGRA_BOARD_H_
I wonder if include guards shouldn't say TEGRA30 not just TEGRA. That would avoid any conflict between the different arch/arm/include/asm/arch-tegra* directories. Sure, that's unlikely right now, but if we really continue to push device tree, maybe we'll end up with a unified Tegra20/Tegra30 bootloader image, and need to include both.
I could change it to _TEGRA30_BOARD_H_. I'd haven't considered ever including both arch board.h files in a single build - as you say, it's unlikely. But I'll change it.
diff --git a/arch/arm/include/asm/arch-tegra30/clk_rst.h b/arch/arm/include/asm/arch-tegra30/clk_rst.h
+#ifndef _CLK_RST_H_ +#define _CLK_RST_H_
Hmm, and the naming format isn't consistent.
Copied from Tegra20. In the (near) future, I'll have a combined clk_rst.h include for Tegra20/Tegra30.
+/* The clocks supported by the hardware */ +enum periph_id {
PERIPH_ID_FIRST,
...
+/*
- 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,
...
Can you make sure that one/both (whichever is appropriate) of these line up with the proposed Linux kernel Tegra30 clock binding clock IDs. I'm not sure if the Tegra30 proposed binding has been published yet, but Prashant Gaikwad can email you the patch off-list if you need.
I'd rather leave it as is (copied from our internal T30 U-Boot code) for now, especially for a 'proposed' kernel change. Let's get a basic, working T30 build in there, and then we can make it match the kernel IDs as needed.
+void clock_enable(enum periph_id clkid);
Hmm. I would have expected all the prototypes to be in a common header between Tegra20 and Tegra30?
See my comment in another thread. My goal is to get a working T30 build in (to cmd prompt), and then I'll look at common-izing all of the TegraXX code.
diff --git a/arch/arm/include/asm/arch-tegra30/funcmux.h b/arch/arm/include/asm/arch-tegra30/funcmux.h
+/* Configs supported by the func mux */ +enum {
FUNCMUX_DEFAULT = 0, /* default config */
/* UART configs */
FUNCMUX_UART1_ULPI_UART2 = 0,
FUNCMUX_UART2_IRDA = 0,
FUNCMUX_UART4_GMC = 0,
/* I2C configs */
FUNCMUX_DVC_I2CP = 0,
FUNCMUX_I2C1_RM = 0,
FUNCMUX_I2C2_DDC = 0,
FUNCMUX_I2C2_PTA,
FUNCMUX_I2C3_DTF = 0,
/* SDMMC configs */
FUNCMUX_SDMMC1_SDIO1_4BIT = 0,
FUNCMUX_SDMMC2_DTA_DTD_8BIT = 0,
FUNCMUX_SDMMC3_SDB_4BIT = 0,
FUNCMUX_SDMMC3_SDB_SLXA_8BIT,
FUNCMUX_SDMMC4_ATC_ATD_8BIT = 0,
FUNCMUX_SDMMC4_ATB_GMA_4_BIT,
FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT,
/* USB configs */
FUNCMUX_USB2_ULPI = 0,
/* Serial Flash configs */
FUNCMUX_SPI1_GMC_GMD = 0,
+};
Those all look like Tegra20 options. Tegra30 doesn't have mux pin groups (muxing is per-pin now), so names like DTA, DTD, SDB, SLXA, ATB, GMA, ... above don't make any sense (they're Tegra20 pin group names).
In turn, I wonder if a funcmux.h-style API even makes sense for Tegra30, since the number of legal configurations is probably too large to usefully enumerate, but that is perhaps another question.
Up to this point, there hasn't been much need for the funcmux stuff, so I haven't looked at it too thoroughly yet. The only pinmux I've messed with is the UART, since I've only been concerned with getting to the cmd prompt. I can take a look at converting this later, as part of the combo/common Tegra effort.
diff --git a/arch/arm/include/asm/arch-tegra30/gp_padctrl.h b/arch/arm/include/asm/arch-tegra30/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 cdevcfg1; /* 0x78: APB_MISC_GP_CDEV1CFGPADCTRL */
u32 cdevcfg2; /* 0x7C: APB_MISC_GP_CDEV2CFGPADCTRL */
u32 csuscfg; /* 0x80: APB_MISC_GP_CSUSCFGPADCTRL */
u32 dap1cfg; /* 0x84: APB_MISC_GP_DAP1CFGPADCTRL */
u32 dap2cfg; /* 0x88: APB_MISC_GP_DAP2CFGPADCTRL */
u32 dap3cfg; /* 0x8C: APB_MISC_GP_DAP3CFGPADCTRL */
u32 dap4cfg; /* 0x90: APB_MISC_GP_DAP4CFGPADCTRL */
u32 dbgcfg; /* 0x94: APB_MISC_GP_DBGCFGPADCTRL */
u32 lcdcfg1; /* 0x98: APB_MISC_GP_LCDCFG1PADCTRL */
u32 lcdcfg2; /* 0x9C: APB_MISC_GP_LCDCFG2PADCTRL */
u32 sdmmc2_cfg; /* 0xA0: APB_MISC_GP_SDMMC2CFGPADCTRL */
u32 sdmmc3_cfg; /* 0xA4: APB_MISC_GP_SDMMC3CFGPADCTRL */
u32 spicfg; /* 0xA8: APB_MISC_GP_SPICFGPADCTRL */
u32 uaacfg; /* 0xAC: APB_MISC_GP_UAACFGPADCTRL */
u32 uabcfg; /* 0xB0: APB_MISC_GP_UABCFGPADCTRL */
u32 uart2cfg; /* 0xB4: APB_MISC_GP_UART2CFGPADCTRL */
u32 uart3cfg; /* 0xB8: APB_MISC_GP_UART3CFGPADCTRL */
u32 vicfg1; /* 0xBC: APB_MISC_GP_VICFG1PADCTRL */
u32 vicfg2; /* 0xC0: APB_MISC_GP_VICFG2PADCTRL */
u32 xm2cfga; /* 0xC4: APB_MISC_GP_XM2CFGAPADCTRL */
u32 xm2cfgc; /* 0xC8: APB_MISC_GP_XM2CFGCPADCTRL */
u32 xm2cfgd; /* 0xCC: APB_MISC_GP_XM2CFGDPADCTRL */
u32 xm2clkcfg; /* 0xD0: APB_MISC_GP_XM2CLKCFGPADCTRL */
u32 memcomp; /* 0xD4: APB_MISC_GP_MEMCOMPPADCTRL */
+};
That is the Tegra20 layout. It's change for Tegra30. The set of fields is probably even quite different.
Yeah, again not really used yet, just included in ap30.c - I'd made a couple of passes at removing unused include files during the bringup, but I must have missed this one. I'll remove it for now, and add it back in with the proper T30 layout/names when it's needed.
+/* 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
There should be a Tegra30 define here, and since that register is common between Tegra20 and Tegra30, I'd expect this to be in a common header.
Common will happen later, and this'll have the correct Tegra30 IDs when I replace this header.
diff --git a/arch/arm/include/asm/arch-tegra30/mmc.h b/arch/arm/include/asm/arch-tegra30/mmc.h
+int tegra_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio);
Wouldn't this be common too?
Yep, it's identical to the Tegra20 version. When I do the common-izing, it'll go in arch/arm/include/arch-tegra/, etc.
diff --git a/arch/arm/include/asm/arch-tegra30/pinmux.h b/arch/arm/include/asm/arch-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,
Hmmm. This enum appears to have been picked based on register order in the pin controller which I suppose is fine.
However, that order doesn't match the GPIO order, so if you ever want function gpio_request(n) to program both the GPIO controller and pin controller, then you'll need a table to convert between the two sets of IDs. For better or worse, the device tree binding for the Tegra30 pin controller lists the names based on GPIO ID order, and hence if the bindings are ever converted to integer-based rather than string-based, would probably number the pins based on GPIO order too.
I guess this means that either way you'll need a mapping table, either from gpio-or-binding-id to pinmux register, or from this enum to pinmux-register.
So I guess that means this enum is fine - it's just something to watch out for.
AFAIK, we don't change the pinmux on gpio_request calls in Tegra U-Boot. This may be a deficiency, but no ones mentioned the need for it before. We can certainly address that in a future patchset (for Tegra20 as well as Tegra30).
+/*
- 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_AHB_CLK,
PMUX_FUNC_APB_CLK,
PMUX_FUNC_AUDIO_SYNC,
PMUX_FUNC_CRT,
PMUX_FUNC_DAP1,
...
Could you possibly update the order of this enum to match the Linux kernel; see drivers/pinctrl/pinctrl-tegra30.c. Again, such an order would be more likely to match any integer-based device-tree pinmux binding.
Re-ordering this shouldn't be an issue since as the comment says there must be a conversion table anyway.
For now, I'd like to leave it as is. Perhaps after this patchset is in, we can revisit making it matchy-matchy with the kernel - certainly when we get around to using DT for all periph init, etc. That's still in my U-Boot task-list, albeit at a low priority (at least until T30 is upstreamed).
+/* 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]; /* offset 0x3000 */
uint pmt_ctl[PINGRP_COUNT]; /* pin mux/pupd/tristate regs */
+};
Isn't pmc_ctrl at 0x3000; the second comment above appears misleading. Also, PMUX_OFFSET isn't right; the offset is 0x3000; it's more like RESERVED5_SIZE.
Yeah, that's odd. Must have missed it during the port. I'll take a look.
+/**
- Configuure a list of pin groups
Typo above.
Copied from tegra20/pinmux.h. I'll correct it.
diff --git a/arch/arm/include/asm/arch-tegra30/pmu.h b/arch/arm/include/asm/arch-tegra30/pmu.h
+/* Set core and CPU voltages to nominal levels */ +int pmu_set_nominal(void);
That also seems common. I'll stop pointing this issue out.
Common/combined Tegra code will follow the acceptance of a working T30 build.
diff --git a/arch/arm/include/asm/arch-tegra30/tegra30.h b/arch/arm/include/asm/arch-tegra30/tegra30.h
+/* These are the available SKUs (product types) for Tegra */ +enum {
SKU_ID_T20 = 0x8,
SKU_ID_T25SE = 0x14,
SKU_ID_AP25 = 0x17,
SKU_ID_T25 = 0x18,
SKU_ID_AP25E = 0x1b,
SKU_ID_T25E = 0x1c,
SKU_ID_T30 = 0x81, /* Cardhu value */
+};
There's little point defining Tegra20-specific values unless this header is shared between the two SoCs. Same for:
+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,
+};
Yep, I meant to scrub these during the port. Thanks, I'll clean 'em up.
diff --git a/arch/arm/include/asm/arch-tegra30/warmboot.h b/arch/arm/include/asm/arch-tegra30/warmboot.h
At a quick glance, this header appears identical to Tegra20, yet given the differences between sleep modes on the two SoCs, I'd expect to see quite a few differences. I know a lot of extra PMC scratch registers were added on Tegra30 in order to support the sleep mode code, and hence it works quite differently...
It's included in common/board.c, but not used unless CONFIG_TEGRA_LP0 is enabled, which it isn't on T30. I didn't want to pollute common code too much with #ifdefs, but I'll see if adding CONFIG_TEGRA_LP0 around it's include works, and then remove it from arch-tegra30 until we port LP0, which as you say is quite a bit different than T20.
Overall, it might help identify problems if you passed the "-C" option to "git format-patch"; that would show up any headers that had simply been copied from Tegra20 without necessary modifications.
I always try to use -C w/format-patch, and according to my bash history, I did. But since I copied most of these files over from my original porting/bringup branch, I don't think it helped much.

Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/cpu/arm720t/tegra30/Makefile | 48 +++ arch/arm/cpu/arm720t/tegra30/board.h | 25 ++ arch/arm/cpu/arm720t/tegra30/config.mk | 26 ++ arch/arm/cpu/arm720t/tegra30/cpu.c | 570 ++++++++++++++++++++++++++++++++ arch/arm/cpu/arm720t/tegra30/cpu.h | 65 ++++ arch/arm/cpu/arm720t/tegra30/spl.c | 132 ++++++++ 6 files changed, 866 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/arm720t/tegra30/Makefile create mode 100644 arch/arm/cpu/arm720t/tegra30/board.h 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/arm720t/tegra30/cpu.h create mode 100644 arch/arm/cpu/arm720t/tegra30/spl.c
diff --git a/arch/arm/cpu/arm720t/tegra30/Makefile b/arch/arm/cpu/arm720t/tegra30/Makefile new file mode 100644 index 0000000..96e722c --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2010-2012 Nvidia Corporation. +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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 +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +COBJS-y += cpu.o +COBJS-$(CONFIG_SPL_BUILD) += spl.o + +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm720t/tegra30/board.h b/arch/arm/cpu/arm720t/tegra30/board.h new file mode 100644 index 0000000..fc11a7b --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/board.h @@ -0,0 +1,25 @@ +/* + * (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 + */ + +void board_init_uart_f(void); +void gpio_config_uart(void); diff --git a/arch/arm/cpu/arm720t/tegra30/config.mk b/arch/arm/cpu/arm720t/tegra30/config.mk new file mode 100644 index 0000000..ca9c6ea --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/config.mk @@ -0,0 +1,26 @@ +# +# (C) Copyright 2010-2012 +# NVIDIA Corporation <www.nvidia.com> +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, garyj@denx.de +# +# 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 +# +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..f7d9b87 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/cpu.c @@ -0,0 +1,570 @@ +/* + * (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 + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/tegra30.h> +#include <asm/arch/clk_rst.h> +#include <asm/arch/clock.h> +#include <asm/arch/flow.h> +#include <asm/arch/fuse.h> +#include <asm/arch/tegra_i2c.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/pmc.h> +#include <asm/arch/scu.h> +#include "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, +}; + +int tegra_get_chip_type(void) +{ + struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; + uint tegra_sku_id; + + debug("tegra_get_chip_type entry\n"); + tegra_sku_id = readl(&fuse->sku_info) & 0xff; + debug(" tegra_get_chip_type: sku_id = %d\n", tegra_sku_id); + + switch (tegra_sku_id) { + case SKU_ID_T20: + return TEGRA_SOC_T20; + case SKU_ID_T25SE: + case SKU_ID_AP25: + case SKU_ID_T25: + case SKU_ID_AP25E: + case SKU_ID_T25E: + return TEGRA_SOC_T25; + 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 what we set PLLP to. + */ + if (clock_get_rate(CLOCK_ID_PERIPH) == 408000000) + return TEGRA_SOC_T30_408MHZ; + else + return TEGRA_SOC_T30; + + default: + /* unknown sku id */ + return TEGRA_SOC_UNKNOWN; + } +} + +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; +} + +/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */ +int cpu_is_cortexa9(void) +{ + u32 id = readb(NV_PA_PG_UP_BASE + PG_UP_TAG_0); + return id == (PG_UP_TAG_0_PID_CPU & 0xff); +} + +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); /* 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); + + reg = readl(&pll->pll_out_b); /* 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_b); +} + +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 = tegra_get_chip_type(); + if (chip_type == TEGRA_SOC_UNKNOWN) + chip_type = TEGRA_SOC_T30; + 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); + + /* + * The TI PMU65861C needs a 3.75ms delay between enabling + * the power rail and enabling the CPU clock. This delay + * between SM1EN and SM1 is for switching time + the ramp + * up of the voltage to the CPU (VDD_CPU from PMU). We use 0xf00 as + * is is ARM-friendly (can fit in a single ARMv4T mov immmediate + * instruction). + */ + udelay(3840); +} + +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) +{ + /* + * Sadly our clock functions don't support the V and W clocks of T30 + * yet, as well as a few other functions, so use low-level register + * access for now. This eventual removal of low-level code from + * ap20.c is the same process we went through for T20. + */ + 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 (tegra_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); + } +} diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.h b/arch/arm/cpu/arm720t/tegra30/cpu.h new file mode 100644 index 0000000..a5c0474 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/cpu.h @@ -0,0 +1,65 @@ +/* + * (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 + */ +#include <asm/types.h> + +/* Stabilization delays, in usec */ +#define PLL_STABILIZATION_DELAY (300) +#define IO_STABILIZATION_DELAY (1000) + +#define NVBL_PLLP_KHZ (216000) + +#define PLLX_ENABLED (1 << 30) +#define CCLK_BURST_POLICY 0x20008888 +#define SUPER_CCLK_DIVIDER 0x80000000 + +/* Calculate clock fractional divider value from ref and target frequencies */ +#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)) + +/* AVP/CPU ID */ +#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */ +#define PG_UP_TAG_0 0x0 + +#define CORESIGHT_UNLOCK 0xC5ACCE55; + +#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 +#define HALT_COP_EVENT_JTAG (1 << 28) +#define HALT_COP_EVENT_IRQ_1 (1 << 11) +#define HALT_COP_EVENT_FIQ_1 (1 << 9) + +#define GP_HIDREV 0x804 +#define FLOW_MODE_NONE 0 + +#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE) + +void start_cpu(u32 reset_vector); +void halt_avp(void) __attribute__ ((noreturn)); diff --git a/arch/arm/cpu/arm720t/tegra30/spl.c b/arch/arm/cpu/arm720t/tegra30/spl.c new file mode 100644 index 0000000..c391746 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/spl.c @@ -0,0 +1,132 @@ +/* + * (C) Copyright 2012 + * NVIDIA Inc, <www.nvidia.com> + * + * Allen Martin amartin@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 + */ +#include <common.h> +#include <asm/u-boot.h> +#include <asm/utils.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/clock.h> +#include <nand.h> +#include <mmc.h> +#include <fat.h> +#include <version.h> +#include <i2c.h> +#include <image.h> +#include <malloc.h> +#include <linux/compiler.h> +#include "board.h" +#include "cpu.h" + +#include <asm/io.h> +#include <asm/arch/tegra30.h> +#include <asm/arch/clk_rst.h> +#include <asm/arch/clock.h> +#include <asm/arch/pmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/scu.h> +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Define global data structure pointer to it*/ +static gd_t gdata __attribute__ ((section(".data"))); +static bd_t bdata __attribute__ ((section(".data"))); + +inline void hang(void) +{ + puts("### ERROR ### Please RESET the board ###\n"); + for (;;) + ; +} + +void board_init_f(ulong dummy) +{ + board_init_uart_f(); + + /* Initialize periph GPIOs */ +#ifdef CONFIG_SPI_UART_SWITCH + gpio_early_init_uart(); +#else + gpio_config_uart(); +#endif + + /* + * We call relocate_code() with relocation target same as the + * CONFIG_SYS_SPL_TEXT_BASE. This will result in relocation getting + * skipped. Instead, only .bss initialization will happen. That's + * all we need + */ + debug(">>board_init_f()\n"); + relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); +} + +/* This requires UART clocks to be enabled */ +static void preloader_console_init(void) +{ + const char *u_boot_rev = U_BOOT_VERSION; + + gd = &gdata; + gd->bd = &bdata; + gd->flags |= GD_FLG_RELOC; + gd->baudrate = CONFIG_BAUDRATE; + + serial_init(); /* serial communications setup */ + + gd->have_console = 1; + + /* Avoid a second "U-Boot" coming from this string */ + u_boot_rev = &u_boot_rev[7]; + + printf("\nU-Boot SPL %s (%s - %s)\n", u_boot_rev, U_BOOT_DATE, + U_BOOT_TIME); +} + +void board_init_r(gd_t *id, ulong dummy) +{ + struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + + /* enable JTAG */ + writel(0xC0, &pmt->pmt_cfg_ctl); + + debug(">>spl:board_init_r()\n"); + + mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, + CONFIG_SYS_SPL_MALLOC_SIZE); + +#ifdef CONFIG_SPL_BOARD_INIT + spl_board_init(); +#endif + + clock_early_init(); + preloader_console_init(); + + start_cpu((u32)CONFIG_SYS_TEXT_BASE); + halt_avp(); + /* not reached */ +} + +int board_usb_init(const void *blob) +{ + return 0; +}

On 09/12/2012 04:10 PM, Tom Warren wrote:
Patch descriptions would be nice.
diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c
There's quite a bit of Tegra20-support in this file. Can this file be shared with Tegra20 rather than forked and enhanced?
+/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */ +int cpu_is_cortexa9(void) +{
- u32 id = readb(NV_PA_PG_UP_BASE + PG_UP_TAG_0);
- return id == (PG_UP_TAG_0_PID_CPU & 0xff);
+}
Hmm. Given this is support for the AVP/COP running SPL, shouldn't this always be true? I thought Allen's SPL patches had cleaned this up.
+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);
Those functions access the DVC I2C controller's register space, so presumably they're doing I2C accesses. Not all boards use the same PMIC, so it seems like we really do need to factor this out.
- /*
* The TI PMU65861C needs a 3.75ms delay between enabling
* the power rail and enabling the CPU clock. This delay
* between SM1EN and SM1 is for switching time + the ramp
* up of the voltage to the CPU (VDD_CPU from PMU). We use 0xf00 as
* is is ARM-friendly (can fit in a single ARMv4T mov immmediate
* instruction).
*/
- udelay(3840);
The Cardhu board at least does not use the TPS65861. At the very least the comment isn't quite right. Is this code needed?
diff --git a/arch/arm/cpu/arm720t/tegra30/spl.c b/arch/arm/cpu/arm720t/tegra30/spl.c
+void board_init_f(ulong dummy) +{
- board_init_uart_f();
- /* Initialize periph GPIOs */
+#ifdef CONFIG_SPI_UART_SWITCH
- gpio_early_init_uart();
+#else
- gpio_config_uart();
+#endif
Didn't we have patches to get rid of that mess and just use the same function consistently across all boards, or was that only discussed and never actually implemented?

Stephen,
On Thu, Sep 13, 2012 at 1:02 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
Patch descriptions would be nice.
Sure, sorry. Not sure how much more info I can add beyond what's in the commit msg, though, at least for this patch.
diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c
There's quite a bit of Tegra20-support in this file. Can this file be shared with Tegra20 rather than forked and enhanced?
+/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */ +int cpu_is_cortexa9(void) +{
u32 id = readb(NV_PA_PG_UP_BASE + PG_UP_TAG_0);
return id == (PG_UP_TAG_0_PID_CPU & 0xff);
+}
Hmm. Given this is support for the AVP/COP running SPL, shouldn't this always be true? I thought Allen's SPL patches had cleaned this up.
Copied from tegra20/cpu.c - didn't notice it never gets called (same for Tegra20). So it's vestigial and can be removed.
+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);
Those functions access the DVC I2C controller's register space, so presumably they're doing I2C accesses. Not all boards use the same PMIC, so it seems like we really do need to factor this out.
It's in the original internal T30 repo for Cardhu, with a comment from Simon Glass that I edited somewhat. I haven't tried removing it to see if the board still boots.
/*
* The TI PMU65861C needs a 3.75ms delay between enabling
* the power rail and enabling the CPU clock. This delay
* between SM1EN and SM1 is for switching time + the ramp
* up of the voltage to the CPU (VDD_CPU from PMU). We use 0xf00 as
* is is ARM-friendly (can fit in a single ARMv4T mov immmediate
* instruction).
*/
udelay(3840);
The Cardhu board at least does not use the TPS65861. At the very least the comment isn't quite right. Is this code needed?
No idea - it's in our internal T30 bringup repo, as well as Simon's. I can try removing it and see if we power up consistently.
diff --git a/arch/arm/cpu/arm720t/tegra30/spl.c b/arch/arm/cpu/arm720t/tegra30/spl.c
+void board_init_f(ulong dummy) +{
board_init_uart_f();
/* Initialize periph GPIOs */
+#ifdef CONFIG_SPI_UART_SWITCH
gpio_early_init_uart();
+#else
gpio_config_uart();
+#endif
Didn't we have patches to get rid of that mess and just use the same function consistently across all boards, or was that only discussed and never actually implemented?
Someone on the list talked about a cleanup (Lucas? Thierry?), but, AFAIK, that never happened, or I would have put it in tegra/next. At the very least, it's not needed in Tegra30/spl.c, so I'll remove it/clean it up.
Thanks,
Tom

Hi Tom,
Am Donnerstag, den 13.09.2012, 14:00 -0700 schrieb Tom Warren: [...]
diff --git a/arch/arm/cpu/arm720t/tegra30/spl.c b/arch/arm/cpu/arm720t/tegra30/spl.c
+void board_init_f(ulong dummy) +{
board_init_uart_f();
/* Initialize periph GPIOs */
+#ifdef CONFIG_SPI_UART_SWITCH
gpio_early_init_uart();
+#else
gpio_config_uart();
+#endif
Didn't we have patches to get rid of that mess and just use the same function consistently across all boards, or was that only discussed and never actually implemented?
Someone on the list talked about a cleanup (Lucas? Thierry?), but, AFAIK, that never happened, or I would have put it in tegra/next. At the very least, it's not needed in Tegra30/spl.c, so I'll remove it/clean it up.
I did the cleanup and you in fact missed it in the last round of tegra/next. Patch is called "tegra20: rework UART GPIO handling" and is already acked-by Simon Glass.
Thanks, Lucas

Lucas,
On Thu, Sep 13, 2012 at 2:47 PM, Lucas Stach dev@lynxeye.de wrote:
Hi Tom,
Am Donnerstag, den 13.09.2012, 14:00 -0700 schrieb Tom Warren: [...]
diff --git a/arch/arm/cpu/arm720t/tegra30/spl.c b/arch/arm/cpu/arm720t/tegra30/spl.c
+void board_init_f(ulong dummy) +{
board_init_uart_f();
/* Initialize periph GPIOs */
+#ifdef CONFIG_SPI_UART_SWITCH
gpio_early_init_uart();
+#else
gpio_config_uart();
+#endif
Didn't we have patches to get rid of that mess and just use the same function consistently across all boards, or was that only discussed and never actually implemented?
Someone on the list talked about a cleanup (Lucas? Thierry?), but, AFAIK, that never happened, or I would have put it in tegra/next. At the very least, it's not needed in Tegra30/spl.c, so I'll remove it/clean it up.
I did the cleanup and you in fact missed it in the last round of tegra/next. Patch is called "tegra20: rework UART GPIO handling" and is already acked-by Simon Glass.
Thanks, I see it. Now that I've re-read it, I'm remembering that I was waiting on Allen Martin to answer Stephen's question:
" .. it looks like both SPL and non-SPL end up calling gpio_early_init_uart(); is that duplication correct or problematic?"
I'll apply it to /next regardless, since Simon seems to think it's OK.
BTW, I'm not sure how patchwork is supposed to operate, but it appears that the originator of the patch needs to assign it to me, mark it as under review, etc. I don't seem to have that power for patches I haven't written. Is that how it works for other custodians? It would really help me keep track of Tegra patches if they could be marked/assigned to me so I can sort on 'em. Right now, I just use a filter with 'tegra' in it, which doesn't always find all the patches I need to know about.
Thanks,
Tom
Thanks, Lucas

Hi Tom,
On Wed, Sep 12, 2012 at 3:10 PM, Tom Warren twarren.nvidia@gmail.com wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
arch/arm/cpu/arm720t/tegra30/Makefile | 48 +++ arch/arm/cpu/arm720t/tegra30/board.h | 25 ++ arch/arm/cpu/arm720t/tegra30/config.mk | 26 ++ arch/arm/cpu/arm720t/tegra30/cpu.c | 570 ++++++++++++++++++++++++++++++++ arch/arm/cpu/arm720t/tegra30/cpu.h | 65 ++++ arch/arm/cpu/arm720t/tegra30/spl.c | 132 ++++++++
It certainly has complicated your work, with the AVP arm720t refactor going in before these patches.
I feel that quite a bit of the code here should perhaps go to arch/arm/cpu/arm720t/tegra-common or similar, so that you can share it with tegra30.
Regards, Simon

Simon,
On Tue, Sep 18, 2012 at 12:37 PM, Simon Glass sjg@chromium.org wrote:
Hi Tom,
On Wed, Sep 12, 2012 at 3:10 PM, Tom Warren twarren.nvidia@gmail.com wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
arch/arm/cpu/arm720t/tegra30/Makefile | 48 +++ arch/arm/cpu/arm720t/tegra30/board.h | 25 ++ arch/arm/cpu/arm720t/tegra30/config.mk | 26 ++ arch/arm/cpu/arm720t/tegra30/cpu.c | 570 ++++++++++++++++++++++++++++++++ arch/arm/cpu/arm720t/tegra30/cpu.h | 65 ++++ arch/arm/cpu/arm720t/tegra30/spl.c | 132 ++++++++
It certainly has complicated your work, with the AVP arm720t refactor going in before these patches.
In some ways, yes. In others, it made it easy to first get a SPL (AVP) U-Boot up and printing its sign-on, and then having a base to work from/debug A9 code for the second, CPU-init half.
I feel that quite a bit of the code here should perhaps go to arch/arm/cpu/arm720t/tegra-common or similar, so that you can share it with tegra30.
WIP. There'll be an arch/arm/cpu/arm720t/tegra-common, an arch/arm/cpu/armv7/tegra-common, and even an arch/arm/cpu/tegra-common, plus an arch/arm/include/asm/arch-tegra to hold common code & include files.
How those changes will be captured in a patchset (or 2) that show the movement of the original Tegra20 files, then the copy/edit for Tegra30 is still to be seen.
Thanks,
Tom
Regards, Simon

Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/cpu/armv7/tegra30/Makefile | 48 +++++++++++++++++++++ arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c | 65 +++++++++++++++++++++++++++++ arch/arm/cpu/armv7/tegra30/config.mk | 26 +++++++++++ 3 files changed, 139 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/armv7/tegra30/Makefile create mode 100644 arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c create mode 100644 arch/arm/cpu/armv7/tegra30/config.mk
diff --git a/arch/arm/cpu/armv7/tegra30/Makefile b/arch/arm/cpu/armv7/tegra30/Makefile new file mode 100644 index 0000000..3b98e23 --- /dev/null +++ b/arch/arm/cpu/armv7/tegra30/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 20102012 Nvidia Corporation. +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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 +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +COBJS-$(CONFIG_CMD_ENTERRCM) += cmd_enterrcm.o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c b/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c new file mode 100644 index 0000000..e146938 --- /dev/null +++ b/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * Derived from code (arch/arm/lib/reset.c) that is: + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke azu@sysgo.de + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, garyj@denx.de + * + * (C) Copyright 2004 + * DAVE Srl + * http://www.dave-tech.it + * http://www.wawnet.biz + * mailto:info@wawnet.biz + * + * (C) Copyright 2004 Texas Insturments + * + * 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, see http://www.gnu.org/licenses/. + */ + +#include <common.h> +#include <asm/arch/tegra30.h> +#include <asm/arch/pmc.h> + +static int do_enterrcm(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + puts("Entering RCM...\n"); + udelay(50000); + + pmc->pmc_scratch0 = 2; + disable_interrupts(); + reset_cpu(0); + + return 0; +} + +U_BOOT_CMD( + enterrcm, 1, 0, do_enterrcm, + "reset Tegra and enter USB Recovery Mode", + "" +); diff --git a/arch/arm/cpu/armv7/tegra30/config.mk b/arch/arm/cpu/armv7/tegra30/config.mk new file mode 100644 index 0000000..fad9efa --- /dev/null +++ b/arch/arm/cpu/armv7/tegra30/config.mk @@ -0,0 +1,26 @@ +# +# (C) Copyright 2010-2012 +# NVIDIA Corporation <www.nvidia.com> +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, garyj@denx.de +# +# 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 +# +CONFIG_ARCH_DEVICE_TREE := tegra30

Stephen,
On Thu, Sep 13, 2012 at 1:03 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
diff --git a/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c b/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c
This whole file is definitely common with Tegra20.
I'm going through your previous comments, but I'll just reply quickly to this one since it needs clearing up.
The intent of this first series of patches for Tegra30 was just to get to the command prompt on T30 in the quickest way, while impacting Tegra20 code as little as possible. Hence, I used Tegra20 files to create a Tegra30 build, and as I ported it to T30 HW, I tried to eliminate what I could that I knew for sure was T20-specific and not useful. But I've made no effort to combine common files/code in this initial pass. I think it's much easier to understand and review these files as a separate SoC build, rather than having to parse common/combined files and code. I intend to do the combination/common-izing of the TegraXX builds once I have a reasonable T30 build in u-boot-tegra, perhaps even before I start porting the drivers. But this is the initial approach I took. Hopefully it'll be an acceptable course - I'd hate to have to back-track.
Thanks for the thorough review,
Tom

On 09/13/2012 02:16 PM, Tom Warren wrote:
Stephen,
On Thu, Sep 13, 2012 at 1:03 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
diff --git a/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c b/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c
This whole file is definitely common with Tegra20.
I'm going through your previous comments, but I'll just reply quickly to this one since it needs clearing up.
The intent of this first series of patches for Tegra30 was just to get to the command prompt on T30 in the quickest way, while impacting Tegra20 code as little as possible. Hence, I used Tegra20 files to create a Tegra30 build, and as I ported it to T30 HW, I tried to eliminate what I could that I knew for sure was T20-specific and not useful. But I've made no effort to combine common files/code in this initial pass. I think it's much easier to understand and review these files as a separate SoC build, rather than having to parse common/combined files and code. I intend to do the combination/common-izing of the TegraXX builds once I have a reasonable T30 build in u-boot-tegra, perhaps even before I start porting the drivers. But this is the initial approach I took. Hopefully it'll be an acceptable course - I'd hate to have to back-track.
To be honest, it seems like the patch to add the Tegra30 deltas to the existing Tegra20 code would be massively smaller than duplicating all of Tegra20 as Tegra30 and applying those same changes. In the kernel, we have both Tegra20 and Tegra30 support with run-time differentiation, and the number of places where we have to do something different is not that large at all. With the current patch series, there's a huge amount of code to wade through, so spotting any places that haven't been updated for Tegra30, or weren't intended to be updated yet, is somewhat painful.

On 09/13/2012 01:30 PM, Stephen Warren wrote:
On 09/13/2012 02:16 PM, Tom Warren wrote:
Stephen,
On Thu, Sep 13, 2012 at 1:03 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
diff --git a/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c b/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c
This whole file is definitely common with Tegra20.
I'm going through your previous comments, but I'll just reply quickly to this one since it needs clearing up.
The intent of this first series of patches for Tegra30 was just to get to the command prompt on T30 in the quickest way, while impacting Tegra20 code as little as possible. Hence, I used Tegra20 files to create a Tegra30 build, and as I ported it to T30 HW, I tried to eliminate what I could that I knew for sure was T20-specific and not useful. But I've made no effort to combine common files/code in this initial pass. I think it's much easier to understand and review these files as a separate SoC build, rather than having to parse common/combined files and code. I intend to do the combination/common-izing of the TegraXX builds once I have a reasonable T30 build in u-boot-tegra, perhaps even before I start porting the drivers. But this is the initial approach I took. Hopefully it'll be an acceptable course - I'd hate to have to back-track.
To be honest, it seems like the patch to add the Tegra30 deltas to the existing Tegra20 code would be massively smaller than duplicating all of Tegra20 as Tegra30 and applying those same changes. In the kernel, we have both Tegra20 and Tegra30 support with run-time differentiation, and the number of places where we have to do something different is not that large at all. With the current patch series, there's a huge amount of code to wade through, so spotting any places that haven't been updated for Tegra30, or weren't intended to be updated yet, is somewhat painful.
Since we know that the delta can be small, yes, let's just do this right the first time (or so). incremental moves, additions and we can work out run-vs-build time a little further down the road.

Tom,
On Thu, Sep 13, 2012 at 1:33 PM, Tom Rini trini@ti.com wrote:
On 09/13/2012 01:30 PM, Stephen Warren wrote:
On 09/13/2012 02:16 PM, Tom Warren wrote:
Stephen,
On Thu, Sep 13, 2012 at 1:03 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
diff --git a/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c b/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c
This whole file is definitely common with Tegra20.
I'm going through your previous comments, but I'll just reply quickly to this one since it needs clearing up.
The intent of this first series of patches for Tegra30 was just to get to the command prompt on T30 in the quickest way, while impacting Tegra20 code as little as possible. Hence, I used Tegra20 files to create a Tegra30 build, and as I ported it to T30 HW, I tried to eliminate what I could that I knew for sure was T20-specific and not useful. But I've made no effort to combine common files/code in this initial pass. I think it's much easier to understand and review these files as a separate SoC build, rather than having to parse common/combined files and code. I intend to do the combination/common-izing of the TegraXX builds once I have a reasonable T30 build in u-boot-tegra, perhaps even before I start porting the drivers. But this is the initial approach I took. Hopefully it'll be an acceptable course - I'd hate to have to back-track.
To be honest, it seems like the patch to add the Tegra30 deltas to the existing Tegra20 code would be massively smaller than duplicating all of Tegra20 as Tegra30 and applying those same changes. In the kernel, we have both Tegra20 and Tegra30 support with run-time differentiation, and the number of places where we have to do something different is not that large at all. With the current patch series, there's a huge amount of code to wade through, so spotting any places that haven't been updated for Tegra30, or weren't intended to be updated yet, is somewhat painful.
Since we know that the delta can be small, yes, let's just do this right the first time (or so). incremental moves, additions and we can work out run-vs-build time a little further down the road.
Sorry, Tom. I'm not clear on exactly which way you'd like to see this go.
Are you advising that I re-cast this patchset as a set of common Tegra files/code, with deltas/diffs for the Tegra30 changes? That implies, I think, that I first have to do a patchset that re-orgs Tegra20 code into common code, and then submit a smaller version of this patchset that is just deltas for Tegra30. That means that I'll be touching everyone's Tegra20 code, and will need Ack's from all the T20 vendors before I can move forward w/T30 code.
The other approach, which is still a 2-(or more)-patchset process, is to continue with this patchset for T30, with corrections as per review, and then immediately work on a 'merge-to-common-code' set of patches to common-ize Tegra20/30. That way Tegra20 is unaffected, I can keep moving forward, and I think the end result will be the same as the approach above.
I can see value in both approaches, and it shouldn't surprise you that I'd favor the 2nd approach, since it's less chaotic for me. Let me know what you think,
Tom
-- Tom

On Thu, Sep 13, 2012 at 02:21:54PM -0700, Tom Warren wrote:
Tom,
On Thu, Sep 13, 2012 at 1:33 PM, Tom Rini trini@ti.com wrote:
On 09/13/2012 01:30 PM, Stephen Warren wrote:
On 09/13/2012 02:16 PM, Tom Warren wrote:
Stephen,
On Thu, Sep 13, 2012 at 1:03 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
diff --git a/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c b/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c
This whole file is definitely common with Tegra20.
I'm going through your previous comments, but I'll just reply quickly to this one since it needs clearing up.
The intent of this first series of patches for Tegra30 was just to get to the command prompt on T30 in the quickest way, while impacting Tegra20 code as little as possible. Hence, I used Tegra20 files to create a Tegra30 build, and as I ported it to T30 HW, I tried to eliminate what I could that I knew for sure was T20-specific and not useful. But I've made no effort to combine common files/code in this initial pass. I think it's much easier to understand and review these files as a separate SoC build, rather than having to parse common/combined files and code. I intend to do the combination/common-izing of the TegraXX builds once I have a reasonable T30 build in u-boot-tegra, perhaps even before I start porting the drivers. But this is the initial approach I took. Hopefully it'll be an acceptable course - I'd hate to have to back-track.
To be honest, it seems like the patch to add the Tegra30 deltas to the existing Tegra20 code would be massively smaller than duplicating all of Tegra20 as Tegra30 and applying those same changes. In the kernel, we have both Tegra20 and Tegra30 support with run-time differentiation, and the number of places where we have to do something different is not that large at all. With the current patch series, there's a huge amount of code to wade through, so spotting any places that haven't been updated for Tegra30, or weren't intended to be updated yet, is somewhat painful.
Since we know that the delta can be small, yes, let's just do this right the first time (or so). incremental moves, additions and we can work out run-vs-build time a little further down the road.
Sorry, Tom. I'm not clear on exactly which way you'd like to see this go.
Are you advising that I re-cast this patchset as a set of common Tegra files/code, with deltas/diffs for the Tegra30 changes? That implies, I think, that I first have to do a patchset that re-orgs Tegra20 code into common code, and then submit a smaller version of this patchset that is just deltas for Tegra30. That means that I'll be touching everyone's Tegra20 code, and will need Ack's from all the T20 vendors before I can move forward w/T30 code.
As far as I'm conerend to do a: git mv arch/arm/cpu/armv7/tegra20/cmd_enterrcm.c arch/arm/cpu/armv7/tegra-common/cmd_enterrcm.c (just looking at top of tree mainline) needs just the overall Tegra maintainer to Ack. The Custodians page says that's you, and so long as you MAKEALL -s tegra20 before and after, that's good to go. By that same token, breaking out a hypothetical set of common functions from tegra20/usb.c into tegra-common/usb.c and leaving the T20 specific bits in tegra20/usb.c and adding tegra30/usb.c later just needs you and MAKEALL happy.
The other approach, which is still a 2-(or more)-patchset process, is to continue with this patchset for T30, with corrections as per review, and then immediately work on a 'merge-to-common-code' set of patches to common-ize Tegra20/30. That way Tegra20 is unaffected, I can keep moving forward, and I think the end result will be the same as the approach above.
As has been noted, when you copy files you get a lot of re-review and it's hard to tell what's new and what's not. It IS good to post what you have posted and say "please check areas X/Y/Z, it's new code". But reviewing code that will be dropped as soon as you switch to the 'merge-to-common-code' branch being the reviewed one is hard, especially when folks with less Tegra background try and read the patches for general issues.
I can see value in both approaches, and it shouldn't surprise you that I'd favor the 2nd approach, since it's less chaotic for me. Let me know what you think,
Well, I'd argue that since you're going to need to do the 'merge-to-common-code' path at some point, it's going to save you work to do that now rather than fixup issues in two places. And again, if you don't change the code, just where the code is, MAKEALL will catch your problems for you.

Tom,
On Thu, Sep 13, 2012 at 3:04 PM, Tom Rini trini@ti.com wrote:
On Thu, Sep 13, 2012 at 02:21:54PM -0700, Tom Warren wrote:
Tom,
On Thu, Sep 13, 2012 at 1:33 PM, Tom Rini trini@ti.com wrote:
On 09/13/2012 01:30 PM, Stephen Warren wrote:
On 09/13/2012 02:16 PM, Tom Warren wrote:
Stephen,
On Thu, Sep 13, 2012 at 1:03 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
> diff --git a/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c b/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c
This whole file is definitely common with Tegra20.
I'm going through your previous comments, but I'll just reply quickly to this one since it needs clearing up.
The intent of this first series of patches for Tegra30 was just to get to the command prompt on T30 in the quickest way, while impacting Tegra20 code as little as possible. Hence, I used Tegra20 files to create a Tegra30 build, and as I ported it to T30 HW, I tried to eliminate what I could that I knew for sure was T20-specific and not useful. But I've made no effort to combine common files/code in this initial pass. I think it's much easier to understand and review these files as a separate SoC build, rather than having to parse common/combined files and code. I intend to do the combination/common-izing of the TegraXX builds once I have a reasonable T30 build in u-boot-tegra, perhaps even before I start porting the drivers. But this is the initial approach I took. Hopefully it'll be an acceptable course - I'd hate to have to back-track.
To be honest, it seems like the patch to add the Tegra30 deltas to the existing Tegra20 code would be massively smaller than duplicating all of Tegra20 as Tegra30 and applying those same changes. In the kernel, we have both Tegra20 and Tegra30 support with run-time differentiation, and the number of places where we have to do something different is not that large at all. With the current patch series, there's a huge amount of code to wade through, so spotting any places that haven't been updated for Tegra30, or weren't intended to be updated yet, is somewhat painful.
Since we know that the delta can be small, yes, let's just do this right the first time (or so). incremental moves, additions and we can work out run-vs-build time a little further down the road.
Sorry, Tom. I'm not clear on exactly which way you'd like to see this go.
Are you advising that I re-cast this patchset as a set of common Tegra files/code, with deltas/diffs for the Tegra30 changes? That implies, I think, that I first have to do a patchset that re-orgs Tegra20 code into common code, and then submit a smaller version of this patchset that is just deltas for Tegra30. That means that I'll be touching everyone's Tegra20 code, and will need Ack's from all the T20 vendors before I can move forward w/T30 code.
As far as I'm conerend to do a: git mv arch/arm/cpu/armv7/tegra20/cmd_enterrcm.c arch/arm/cpu/armv7/tegra-common/cmd_enterrcm.c (just looking at top of tree mainline) needs just the overall Tegra maintainer to Ack. The Custodians page says that's you, and so long as you MAKEALL -s tegra20 before and after, that's good to go. By that same token, breaking out a hypothetical set of common functions from tegra20/usb.c into tegra-common/usb.c and leaving the T20 specific bits in tegra20/usb.c and adding tegra30/usb.c later just needs you and MAKEALL happy.
The other approach, which is still a 2-(or more)-patchset process, is to continue with this patchset for T30, with corrections as per review, and then immediately work on a 'merge-to-common-code' set of patches to common-ize Tegra20/30. That way Tegra20 is unaffected, I can keep moving forward, and I think the end result will be the same as the approach above.
As has been noted, when you copy files you get a lot of re-review and it's hard to tell what's new and what's not. It IS good to post what you have posted and say "please check areas X/Y/Z, it's new code". But reviewing code that will be dropped as soon as you switch to the 'merge-to-common-code' branch being the reviewed one is hard, especially when folks with less Tegra background try and read the patches for general issues.
I can see value in both approaches, and it shouldn't surprise you that I'd favor the 2nd approach, since it's less chaotic for me. Let me know what you think,
Well, I'd argue that since you're going to need to do the 'merge-to-common-code' path at some point, it's going to save you work to do that now rather than fixup issues in two places. And again, if you don't change the code, just where the code is, MAKEALL will catch your problems for you.
Moving the code via git as you pointed out above is fine, but how do I hook 'tegra-common' into the boards.cfg/Makefile/MAKEALL process? I'd need a 'tegra-common' subdir for arm720t, armv7 and an 'arch-tegra' subdir for arch/arm/include/asm/. The arch-tegra common subdir is easy, as I can just have the <asm/arch/blah.h> file do an 'include <asm/arch-tegra/blah.h> when the include file is 100% common and flesh it out when it's SoC-specific. But I don't see how I can build the SPL and 'normal' U-Boot sections via boards.cfg w/common code, without having a SPL.C that says 'include ../tegra-common/spl.c', which seems messy. Not to mention that we have arch/arm/cpu/tegra20-common and ../tegra30-common, too. How do you do it on OMAP?
Tom
-- Tom

On Thu, Sep 13, 2012 at 03:16:21PM -0700, Tom Warren wrote:
Tom,
On Thu, Sep 13, 2012 at 3:04 PM, Tom Rini trini@ti.com wrote:
On Thu, Sep 13, 2012 at 02:21:54PM -0700, Tom Warren wrote:
Tom,
On Thu, Sep 13, 2012 at 1:33 PM, Tom Rini trini@ti.com wrote:
On 09/13/2012 01:30 PM, Stephen Warren wrote:
On 09/13/2012 02:16 PM, Tom Warren wrote:
Stephen,
On Thu, Sep 13, 2012 at 1:03 PM, Stephen Warren swarren@wwwdotorg.org wrote: > On 09/12/2012 04:10 PM, Tom Warren wrote: > >> diff --git a/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c b/arch/arm/cpu/armv7/tegra30/cmd_enterrcm.c > > This whole file is definitely common with Tegra20.
I'm going through your previous comments, but I'll just reply quickly to this one since it needs clearing up.
The intent of this first series of patches for Tegra30 was just to get to the command prompt on T30 in the quickest way, while impacting Tegra20 code as little as possible. Hence, I used Tegra20 files to create a Tegra30 build, and as I ported it to T30 HW, I tried to eliminate what I could that I knew for sure was T20-specific and not useful. But I've made no effort to combine common files/code in this initial pass. I think it's much easier to understand and review these files as a separate SoC build, rather than having to parse common/combined files and code. I intend to do the combination/common-izing of the TegraXX builds once I have a reasonable T30 build in u-boot-tegra, perhaps even before I start porting the drivers. But this is the initial approach I took. Hopefully it'll be an acceptable course - I'd hate to have to back-track.
To be honest, it seems like the patch to add the Tegra30 deltas to the existing Tegra20 code would be massively smaller than duplicating all of Tegra20 as Tegra30 and applying those same changes. In the kernel, we have both Tegra20 and Tegra30 support with run-time differentiation, and the number of places where we have to do something different is not that large at all. With the current patch series, there's a huge amount of code to wade through, so spotting any places that haven't been updated for Tegra30, or weren't intended to be updated yet, is somewhat painful.
Since we know that the delta can be small, yes, let's just do this right the first time (or so). incremental moves, additions and we can work out run-vs-build time a little further down the road.
Sorry, Tom. I'm not clear on exactly which way you'd like to see this go.
Are you advising that I re-cast this patchset as a set of common Tegra files/code, with deltas/diffs for the Tegra30 changes? That implies, I think, that I first have to do a patchset that re-orgs Tegra20 code into common code, and then submit a smaller version of this patchset that is just deltas for Tegra30. That means that I'll be touching everyone's Tegra20 code, and will need Ack's from all the T20 vendors before I can move forward w/T30 code.
As far as I'm conerend to do a: git mv arch/arm/cpu/armv7/tegra20/cmd_enterrcm.c arch/arm/cpu/armv7/tegra-common/cmd_enterrcm.c (just looking at top of tree mainline) needs just the overall Tegra maintainer to Ack. The Custodians page says that's you, and so long as you MAKEALL -s tegra20 before and after, that's good to go. By that same token, breaking out a hypothetical set of common functions from tegra20/usb.c into tegra-common/usb.c and leaving the T20 specific bits in tegra20/usb.c and adding tegra30/usb.c later just needs you and MAKEALL happy.
The other approach, which is still a 2-(or more)-patchset process, is to continue with this patchset for T30, with corrections as per review, and then immediately work on a 'merge-to-common-code' set of patches to common-ize Tegra20/30. That way Tegra20 is unaffected, I can keep moving forward, and I think the end result will be the same as the approach above.
As has been noted, when you copy files you get a lot of re-review and it's hard to tell what's new and what's not. It IS good to post what you have posted and say "please check areas X/Y/Z, it's new code". But reviewing code that will be dropped as soon as you switch to the 'merge-to-common-code' branch being the reviewed one is hard, especially when folks with less Tegra background try and read the patches for general issues.
I can see value in both approaches, and it shouldn't surprise you that I'd favor the 2nd approach, since it's less chaotic for me. Let me know what you think,
Well, I'd argue that since you're going to need to do the 'merge-to-common-code' path at some point, it's going to save you work to do that now rather than fixup issues in two places. And again, if you don't change the code, just where the code is, MAKEALL will catch your problems for you.
Moving the code via git as you pointed out above is fine, but how do I hook 'tegra-common' into the boards.cfg/Makefile/MAKEALL process? I'd need a 'tegra-common' subdir for arm720t, armv7 and an 'arch-tegra' subdir for arch/arm/include/asm/. The arch-tegra common subdir is easy, as I can just have the <asm/arch/blah.h> file do an 'include <asm/arch-tegra/blah.h> when the include file is 100% common and flesh it out when it's SoC-specific. But I don't see how I can build the SPL and 'normal' U-Boot sections via boards.cfg w/common code, without having a SPL.C that says 'include ../tegra-common/spl.c', which seems messy. Not to mention that we have arch/arm/cpu/tegra20-common and ../tegra30-common, too. How do you do it on OMAP?
I'd like to see <plat/blah.h> which goes to <plat/tegra/blah.h> or whatever, which is similar to what the kernel has nowadays. Solving this for TI parts (OMAP/AM33x and DaVinci share at times) is still on my TODO list. I could live with <asm/arch-foo/blah.h> or maybe even <asm/plat/blah.h> (I'm not awesome at naming things). For the C files, I thought the concensus ended up with arch/arm/cpu/tegra-common/ as the least-objectionable way to handle this problem in general. Then it's just a matter of adding a line or 5 to Makefile and spl/Makefile to say on tegra, also build in arch/arm/cpu/tegra-common. Note that on OMAP/AM33x we have arch/arm/cpu/armv7/omap-common and arch/arm/cpu/armv7/{omap3,omap4,omap5,am33xx} for armv7 but cross-SoC bits go and armv7 but SoC specific bits go. The rule for omap-common is two or more rather than all of the above.

Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/cpu/tegra30-common/Makefile | 51 ++ arch/arm/cpu/tegra30-common/ap30.c | 98 +++ arch/arm/cpu/tegra30-common/board.c | 141 ++++ arch/arm/cpu/tegra30-common/clock.c | 1099 +++++++++++++++++++++++++++ arch/arm/cpu/tegra30-common/funcmux.c | 74 ++ arch/arm/cpu/tegra30-common/lowlevel_init.S | 42 + arch/arm/cpu/tegra30-common/pinmux.c | 507 ++++++++++++ arch/arm/cpu/tegra30-common/sys_info.c | 35 + arch/arm/cpu/tegra30-common/timer.c | 111 +++ 9 files changed, 2158 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/tegra30-common/Makefile create mode 100644 arch/arm/cpu/tegra30-common/ap30.c create mode 100644 arch/arm/cpu/tegra30-common/board.c 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/lowlevel_init.S create mode 100644 arch/arm/cpu/tegra30-common/pinmux.c create mode 100644 arch/arm/cpu/tegra30-common/sys_info.c create mode 100644 arch/arm/cpu/tegra30-common/timer.c
diff --git a/arch/arm/cpu/tegra30-common/Makefile b/arch/arm/cpu/tegra30-common/Makefile new file mode 100644 index 0000000..6efc554 --- /dev/null +++ b/arch/arm/cpu/tegra30-common/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2010-2012 Nvidia Corporation. +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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 +# + +include $(TOPDIR)/config.mk + +# The AVP is ARMv4T architecture so we must use special compiler +# flags for any startup files it might use. + +LIB = $(obj)lib$(SOC)-common.o + +SOBJS += lowlevel_init.o +COBJS-y += ap30.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/tegra30-common/ap30.c b/arch/arm/cpu/tegra30-common/ap30.c new file mode 100644 index 0000000..4f07c4e --- /dev/null +++ b/arch/arm/cpu/tegra30-common/ap30.c @@ -0,0 +1,98 @@ +/* +* (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 +*/ + +#include <asm/io.h> +#include <asm/arch/ap30.h> +#include <asm/arch/fuse.h> +#include <asm/arch/gp_padctrl.h> +#include <asm/arch/pmc.h> +#include <asm/arch/scu.h> +#include <asm/arch/warmboot.h> +#include <common.h> + +static void enable_scu(void) +{ + struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE; + u32 reg; + + /* If SCU already setup/enabled, return */ + if (readl(&scu->scu_ctrl) & SCU_CTRL_ENABLE) + return; + + /* Invalidate all ways for all processors */ + writel(0xFFFF, &scu->scu_inv_all); + + /* Enable SCU - bit 0 */ + reg = readl(&scu->scu_ctrl); + reg |= SCU_CTRL_ENABLE; + writel(reg, &scu->scu_ctrl); +} + +static u32 get_odmdata(void) +{ + /* + * ODMDATA is stored in the BCT in IRAM by the BootROM. + * The BCT start and size are stored in the BIT in IRAM. + * Read the data @ bct_start + (bct_size - 12). This works + * on T20 and T30 BCTs, which are locked down. If this changes + * in new chips (T114, etc.), we can revisit this algorithm. + */ + + u32 bct_start, odmdata; + + bct_start = readl(T30_BASE_PA_SRAM + NVBOOTINFOTABLE_BCTPTR); + odmdata = readl(bct_start + BCT_ODMDATA_OFFSET); + + return odmdata; +} + +static void init_pmc_scratch(void) +{ + struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 odmdata; + int i; + + /* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */ + for (i = 0; i < 23; i++) + writel(0, &pmc->pmc_scratch1+i); + + /* ODMDATA is for kernel use to determine RAM size, LP config, etc. */ + odmdata = get_odmdata(); + writel(odmdata, &pmc->pmc_scratch20); +} + +void s_init(void) +{ + /* Init PMC scratch memory */ + init_pmc_scratch(); + + enable_scu(); + + /* enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg */ + asm volatile( + "mrc p15, 0, r0, c1, c0, 1\n" + "orr r0, r0, #0x41\n" + "mcr p15, 0, r0, c1, c0, 1\n"); + + /* FIXME: should have ap30's L2 disabled too? */ +} diff --git a/arch/arm/cpu/tegra30-common/board.c b/arch/arm/cpu/tegra30-common/board.c new file mode 100644 index 0000000..6fe017d --- /dev/null +++ b/arch/arm/cpu/tegra30-common/board.c @@ -0,0 +1,141 @@ +/* + * (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 + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/funcmux.h> +#include <asm/arch/pmc.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/tegra30.h> +#include <asm/arch/warmboot.h> + +DECLARE_GLOBAL_DATA_PTR; + +enum { + /* UARTs which we can enable */ + UARTA = 1 << 0, + UARTB = 1 << 1, + UARTD = 1 << 3, + UART_COUNT = 4, +}; + +/* + * Boot ROM initializes the odmdata in APBDEV_PMC_SCRATCH20_0, + * so we are using this value to identify memory size. + */ + +unsigned int query_sdram_size(void) +{ + struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + reg = readl(&pmc->pmc_scratch20); + debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg); + + /* bits 31:28 in OdmData are used for RAM size */ + switch ((reg) >> 28) { + case 1: + return 0x10000000; /* 256 MB */ + case 2: + return 0x20000000; /* 512 MB */ + case 4: + return 0x40000000; /* 1GB */ + case 8: + return 0x7ff00000; /* 2GB - 1MB */ + default: + return 0x40000000; /* 1GB */ + } +} + +int dram_init(void) +{ + /* We do not initialise DRAM here. We just query the size */ + gd->ram_size = query_sdram_size(); + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ + printf("Board: %s\n", sysinfo.board_string); + return 0; +} +#endif /* CONFIG_DISPLAY_BOARDINFO */ + +static int uart_configs[] = { + FUNCMUX_UART1_ULPI_UART2, /* UARTA */ + FUNCMUX_UART2_IRDA, + -1, + FUNCMUX_UART4_GMC, + -1, +}; + +/** + * Set up the specified uarts + * + * @param uarts_ids Mask containing UARTs to init (UARTx) + */ +static void setup_uarts(int uart_ids) +{ + static enum periph_id id_for_uart[] = { + PERIPH_ID_UART1, + PERIPH_ID_UART2, + PERIPH_ID_UART3, + PERIPH_ID_UART4, + }; + size_t i; + + for (i = 0; i < UART_COUNT; i++) { + if (uart_ids & (1 << i)) { + enum periph_id id = id_for_uart[i]; + + funcmux_select(id, uart_configs[i]); + clock_ll_start_uart(id); + } + } +} + +void board_init_uart_f(void) +{ + int uart_ids = 0; /* bit mask of which UART ids to enable */ + +#ifdef CONFIG_TEGRA_ENABLE_UARTA + uart_ids |= UARTA; +#endif +#ifdef CONFIG_TEGRA_ENABLE_UARTB + uart_ids |= UARTB; +#endif +#ifdef CONFIG_TEGRA_ENABLE_UARTD + uart_ids |= UARTD; +#endif + setup_uarts(uart_ids); +} + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif diff --git a/arch/arm/cpu/tegra30-common/clock.c b/arch/arm/cpu/tegra30-common/clock.c new file mode 100644 index 0000000..dd5450f --- /dev/null +++ b/arch/arm/cpu/tegra30-common/clock.c @@ -0,0 +1,1099 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (C) 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 + */ + +/* Tegra30 Clock control functions */ +#include <asm/io.h> +#include <asm/arch/clk_rst.h> +#include <asm/arch/clock.h> +#include <asm/arch/timer.h> +#include <asm/arch/tegra30.h> +#include <common.h> +#include <div64.h> +#include <fdtdec.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * This is our record of the current clock rate of each clock. We don't + * fill all of these in since we are only really interested in clocks which + * we use as parents. + */ +static unsigned pll_rate[CLOCK_ID_COUNT]; + +/* + * The oscillator frequency is fixed to one of four set values. Based on this + * the other clocks are set up appropriately. + */ +static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = { + 13000000, + 19200000, + 12000000, + 26000000, +}; + +/* + * 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. + * + * Letters are obvious, except for T which means CLK_M, and S which means the + * clock derived from 32KHz. Beware that CLK_M (also called OSC in the + * datasheet) and PLL_M are different things. The former is the basic + * clock supplied to the SOC from an external oscillator. The latter is the + * memory clock PLL. + * + * See definitions in clock_id in the header file. + */ +enum clock_type_id { + CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ + CLOCK_TYPE_MCPA, /* and so on */ + CLOCK_TYPE_MCPT, + CLOCK_TYPE_PCM, + CLOCK_TYPE_PCMT, + 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 */ +}; + +/* return 1 if a peripheral ID is in range */ +#define clock_type_id_isvalid(id) ((id) >= 0 && \ + (id) < CLOCK_TYPE_COUNT) + +char pllp_valid = 1; /* PLLP is set up correctly */ + +enum { + CLOCK_MAX_MUX = 8 /* number of source options for each clock */ +}; + +enum { + MASK_BITS_31_30 = 2, /* num of bits used to specify clock source */ + MASK_BITS_31_29, + MASK_BITS_29_28, +}; + +/* + * Clock source mux for each clock type. This just converts our enum into + * a list of mux sources for use by the code. + * + * Note: + * The extra column in each clock source array is used to store the mask + * bits in its register for the source. + */ +#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 */ +#define periphc_internal_id_isvalid(id) ((id) >= 0 && \ + (id) < PERIPHC_COUNT) + +/* + * Clock type for each peripheral clock source. We put the name in each + * record just so it is easy to match things up + */ +#define TYPE(name, type) type +static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { + /* 0x00 */ + TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), + 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_PCST), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT), + + /* 0x08 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + 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_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), + + /* 0x18 */ + TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), + + /* 0x20 */ + TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVO, 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_PCMT), + TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), + + /* 0x28 */ + TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), + + /* 0x30 */ + TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), + 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), +}; + +/* + * This array translates a periph_id to a periphc_internal_id + * + * Not present/matched up: + * uint vi_sensor; _VI_SENSOR_0, 0x1A8 + * SPDIF - which is both 0x08 and 0x0c + * + */ +#define NONE(name) (-1) +#define OFFSET(name, value) PERIPHC_ ## name +static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { + /* Low word: 31:0 */ + NONE(CPU), + NONE(COP), + NONE(TRIGSYS), + NONE(RESERVED3), + NONE(RESERVED4), + NONE(TMR), + PERIPHC_UART1, + PERIPHC_UART2, /* and vfir 0x68 */ + + /* 8 */ + NONE(GPIO), + PERIPHC_SDMMC2, + NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ + PERIPHC_I2S1, + PERIPHC_I2C1, + PERIPHC_NDFLASH, + PERIPHC_SDMMC1, + PERIPHC_SDMMC4, + + /* 16 */ + NONE(RESERVED16), + PERIPHC_PWM, + PERIPHC_I2S2, + PERIPHC_EPP, + PERIPHC_VI, + PERIPHC_G2D, + NONE(USBD), + NONE(ISP), + + /* 24 */ + PERIPHC_G3D, + NONE(RESERVED25), + PERIPHC_DISP2, + PERIPHC_DISP1, + PERIPHC_HOST1X, + NONE(VCP), + PERIPHC_I2S0, + NONE(CACHE2), + + /* Middle word: 63:32 */ + NONE(MEM), + NONE(AHBDMA), + NONE(APBDMA), + NONE(RESERVED35), + NONE(RESERVED36), + NONE(STAT_MON), + NONE(RESERVED38), + NONE(RESERVED39), + + /* 40 */ + NONE(KFUSE), + NONE(SBC1), /* SBC1, 0x34, is this SPI1? */ + PERIPHC_NOR, + NONE(RESERVED43), + PERIPHC_SBC2, + NONE(RESERVED45), + PERIPHC_SBC3, + PERIPHC_DVC_I2C, + + /* 48 */ + NONE(DSI), + PERIPHC_TVO, /* also CVE 0x40 */ + PERIPHC_MIPI, + PERIPHC_HDMI, + NONE(CSI), + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_UART3, + + /* 56 */ + NONE(RESERVED56), + PERIPHC_EMC, + NONE(USB2), + NONE(USB3), + PERIPHC_MPE, + PERIPHC_VDE, + NONE(BSEA), + NONE(BSEV), + + /* Upper word 95:64 */ + PERIPHC_SPEEDO, + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_I2C3, + PERIPHC_SBC4, + PERIPHC_SDMMC3, + NONE(PCIE), + PERIPHC_OWR, + + /* 72 */ + NONE(AFI), + PERIPHC_CSITE, + NONE(PCIEXCLK), + NONE(AVPUCQ), + NONE(RESERVED76), + NONE(RESERVED77), + NONE(RESERVED78), + NONE(DTV), + + /* 80 */ + PERIPHC_NANDSPEED, + PERIPHC_I2CSLOW, + NONE(DSIB), + NONE(RESERVED83), + NONE(IRAMA), + NONE(IRAMB), + NONE(IRAMC), + NONE(IRAMD), + + /* 88 */ + NONE(CRAM2), + 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), +}; + +/* + * Get the oscillator frequency, from the corresponding hardware configuration + * field. + */ +enum clock_osc_freq clock_get_osc_freq(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + reg = readl(&clkrst->crc_osc_ctrl); + return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; +} + +int clock_get_osc_bypass(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + reg = readl(&clkrst->crc_osc_ctrl); + return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT; +} + +/* Returns a pointer to the registers of the given pll */ +static struct clk_pll *get_pll(enum clock_id clkid) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + + assert(clock_id_is_pll(clkid)); + return &clkrst->crc_pll[clkid]; +} + +int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, + u32 *divp, u32 *cpcon, u32 *lfcon) +{ + struct clk_pll *pll = get_pll(clkid); + u32 data; + + assert(clkid != CLOCK_ID_USB); + + /* Safety check, adds to code size but is small */ + if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB) + return -1; + data = readl(&pll->pll_base); + *divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; + *divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT; + *divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; + data = readl(&pll->pll_misc); + *cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT; + *lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT; + return 0; +} + +unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, + u32 divp, u32 cpcon, u32 lfcon) +{ + struct clk_pll *pll = get_pll(clkid); + u32 data; + + /* + * We cheat by treating all PLL (except PLLU) in the same fashion. + * This works only because: + * - same fields are always mapped at same offsets, except DCCON + * - DCCON is always 0, doesn't conflict + * - M,N, P of PLLP values are ignored for PLLP + */ + data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT); + writel(data, &pll->pll_misc); + + data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) | + (0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT); + + if (clkid == CLOCK_ID_USB) + data |= divp << PLLU_VCO_FREQ_SHIFT; + else + data |= divp << PLL_DIVP_SHIFT; + writel(data, &pll->pll_base); + + /* calculate the stable time */ + return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US; +} + +/* Returns a pointer to the clock source register for a peripheral */ +static u32 *get_periph_source_reg(enum periph_id periph_id) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + enum periphc_internal_id internal_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); + 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, + unsigned divisor) +{ + u32 *reg = get_periph_source_reg(periph_id); + u32 value; + + value = readl(reg); + + value &= ~OUT_CLK_SOURCE_MASK; + value |= source << OUT_CLK_SOURCE_SHIFT; + + value &= ~OUT_CLK_DIVISOR_MASK; + value |= divisor << OUT_CLK_DIVISOR_SHIFT; + + writel(value, reg); +} + +void clock_ll_set_source(enum periph_id periph_id, unsigned source) +{ + u32 *reg = get_periph_source_reg(periph_id); + + clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK, + source << OUT_CLK_SOURCE_SHIFT); +} + +/** + * Given the parent's rate and the required rate for the children, this works + * out the peripheral clock divider to use, in 7.1 binary format. + * + * @param divider_bits number of divider bits (8 or 16) + * @param parent_rate clock rate of parent clock in Hz + * @param rate required clock rate for this clock + * @return divider which should be used + */ +static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate, + unsigned long rate) +{ + u64 divider = parent_rate * 2; + unsigned max_divider = 1 << divider_bits; + + divider += rate - 1; + do_div(divider, rate); + + if ((s64)divider - 2 < 0) + return 0; + + if ((s64)divider - 2 >= max_divider) + return -1; + + return divider - 2; +} + +/** + * Given the parent's rate and the divider in 7.1 format, this works out the + * resulting peripheral clock rate. + * + * @param parent_rate clock rate of parent clock in Hz + * @param divider which should be used in 7.1 format + * @return effective clock rate of peripheral + */ +static unsigned long get_rate_from_divider(unsigned long parent_rate, + int divider) +{ + u64 rate; + + rate = (u64)parent_rate * 2; + do_div(rate, divider + 2); + return rate; +} + +unsigned long clock_get_periph_rate(enum periph_id periph_id, + enum clock_id parent) +{ + u32 *reg = get_periph_source_reg(periph_id); + + return get_rate_from_divider(pll_rate[parent], + (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT); +} + +/** + * 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 + * divisor is available which can divide by powers of 2 from 1 to 256. + * + * @param divider_bits number of divider bits (8 or 16) + * @param parent_rate clock rate of parent clock in Hz + * @param rate required clock rate for this clock + * @param extra_div value for the second-stage divisor (not set if this + * function returns -1. + * @return divider which should be used, or -1 if nothing is valid + * + */ +static int find_best_divider(unsigned divider_bits, unsigned long parent_rate, + unsigned long rate, int *extra_div) +{ + int shift; + int best_divider = -1; + int best_error = rate; + + /* try dividers from 1 to 256 and find closest match */ + for (shift = 0; shift <= 8 && best_error > 0; shift++) { + unsigned divided_parent = parent_rate >> shift; + int divider = clk_get_divider(divider_bits, divided_parent, + rate); + unsigned effective_rate = get_rate_from_divider(divided_parent, + divider); + int error = rate - effective_rate; + + /* Given a valid divider, look for the lowest error */ + if (divider != -1 && error < best_error) { + best_error = error; + *extra_div = 1 << shift; + best_divider = divider; + } + } + + /* return what we found - *extra_div will already be set */ + return best_divider; +} + +/** + * Given a peripheral ID and the required source clock, this returns which + * value should be programmed into the source mux for that peripheral. + * + * There is special code here to handle the one source type with 5 sources. + * + * @param periph_id peripheral to start + * @param source PLL id of required parent clock + * @param mux_bits Set to number of bits in mux register: 2 or 4 + * @param divider_bits Set to number of divider bits (8 or 16) + * @return mux value (0-4, or -1 if not found) + */ +static int get_periph_clock_source(enum periph_id periph_id, + enum clock_id parent, int *mux_bits, int *divider_bits) +{ + enum clock_type_id type; + enum periphc_internal_id internal_id; + int mux; + + assert(clock_periph_id_isvalid(periph_id)); + + internal_id = periph_id_to_internal_id[periph_id]; + assert(periphc_internal_id_isvalid(internal_id)); + + type = clock_periph_type[internal_id]; + assert(clock_type_id_isvalid(type)); + + *mux_bits = clock_source[type][CLOCK_MAX_MUX]; + + for (mux = 0; mux < CLOCK_MAX_MUX; mux++) + if (clock_source[type][mux] == parent) + return mux; + + /* 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); + return -1; +} + +/** + * Adjust peripheral PLL to use the given divider and source. + * + * @param periph_id peripheral to adjust + * @param source Source number (0-3 or 0-7) + * @param mux_bits Number of mux bits (2 or 4) + * @param divider Required divider in 7.1 or 15.1 format + * @return 0 if ok, -1 on error (requesting a parent clock which is not valid + * for this peripheral) + */ +static int adjust_periph_pll(enum periph_id periph_id, int source, + int mux_bits, unsigned divider) +{ + u32 *reg = get_periph_source_reg(periph_id); + + clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK, + divider << OUT_CLK_DIVISOR_SHIFT); + udelay(1); + + /* work out the source clock and set it */ + if (source < 0) + return -1; + if (mux_bits == 4) { + clrsetbits_le32(reg, OUT_CLK_SOURCE4_MASK, + source << OUT_CLK_SOURCE4_SHIFT); + } else { + clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK, + source << OUT_CLK_SOURCE_SHIFT); + } + udelay(2); + return 0; +} + +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, source; + int divider, divider_bits = 0; + + /* work out the source clock and set it */ + source = get_periph_clock_source(periph_id, parent, &mux_bits, + ÷r_bits); + + if (extra_div) + divider = find_best_divider(divider_bits, pll_rate[parent], + rate, extra_div); + else + divider = clk_get_divider(divider_bits, pll_rate[parent], + rate); + assert(divider >= 0); + if (adjust_periph_pll(periph_id, source, mux_bits, divider)) + return -1U; + debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate, + get_periph_source_reg(periph_id), + readl(get_periph_source_reg(periph_id))); + + /* Check what we ended up with. This shouldn't matter though */ + effective_rate = clock_get_periph_rate(periph_id, parent); + if (extra_div) + effective_rate /= *extra_div; + if (rate != effective_rate) + debug("Requested clock rate %u not honored (got %u)\n", + rate, effective_rate); + return effective_rate; +} + +unsigned clock_start_periph_pll(enum periph_id periph_id, + enum clock_id parent, unsigned rate) +{ + unsigned effective_rate; + + reset_set_enable(periph_id, 1); + clock_enable(periph_id); + + effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate, + NULL); + + reset_set_enable(periph_id, 0); + return effective_rate; +} + +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; + 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); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, clk); +} + +void clock_enable(enum periph_id clkid) +{ + clock_set_enable(clkid, 1); +} + +void clock_disable(enum periph_id clkid) +{ + clock_set_enable(clkid, 0); +} + +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; + 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); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, reset); +} + +void reset_periph(enum periph_id periph_id, int us_delay) +{ + /* Put peripheral into reset */ + reset_set_enable(periph_id, 1); + udelay(us_delay); + + /* Remove reset */ + reset_set_enable(periph_id, 0); + + udelay(us_delay); +} + +void reset_cmplx_set_enable(int cpu, int which, int reset) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 mask; + + /* 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 */ + if (reset) + writel(mask, &clkrst->crc_cpu_cmplx_set); + else + writel(mask, &clkrst->crc_cpu_cmplx_clr); +} + +unsigned clock_get_rate(enum clock_id clkid) +{ + struct clk_pll *pll; + u32 base; + u32 divm; + u64 parent_rate; + u64 rate; + + parent_rate = osc_freq[clock_get_osc_freq()]; + if (clkid == CLOCK_ID_OSC) + return parent_rate; + + pll = get_pll(clkid); + base = readl(&pll->pll_base); + + /* Oh for bf_unpack()... */ + rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT); + divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; + if (clkid == CLOCK_ID_USB) + divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT; + else + divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; + do_div(rate, divm); + return rate; +} + +/** + * Set the output frequency you want for each PLL clock. + * PLL output frequencies are programmed by setting their N, M and P values. + * The governing equations are: + * VCO = (Fi / m) * n, Fo = VCO / (2^p) + * where Fo is the output frequency from the PLL. + * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi) + * 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1 + * Please see Tegra TRM section 5.3 to get the detail for PLL Programming + * + * @param n PLL feedback divider(DIVN) + * @param m PLL input divider(DIVN) + * @param p post divider(DIVP) + * @param cpcon base PLL charge pump(CPCON) + * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot + * be overriden), 1 if PLL is already correct + */ +static int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) +{ + u32 base_reg; + u32 misc_reg; + struct clk_pll *pll; + + pll = get_pll(clkid); + + base_reg = readl(&pll->pll_base); + + /* Set BYPASS, m, n and p to PLL_BASE */ + base_reg &= ~PLL_DIVM_MASK; + base_reg |= m << PLL_DIVM_SHIFT; + + base_reg &= ~PLL_DIVN_MASK; + base_reg |= n << PLL_DIVN_SHIFT; + + base_reg &= ~PLL_DIVP_MASK; + base_reg |= p << PLL_DIVP_SHIFT; + + if (clkid == CLOCK_ID_PERIPH) { + /* + * If the PLL is already set up, check that it is correct + * and record this info for clock_verify() to check. + */ + if (base_reg & PLL_BASE_OVRRIDE_MASK) { + base_reg |= PLL_ENABLE_MASK; + if (base_reg != readl(&pll->pll_base)) + pllp_valid = 0; + return pllp_valid ? 1 : -1; + } + base_reg |= PLL_BASE_OVRRIDE_MASK; + } + + base_reg |= PLL_BYPASS_MASK; + writel(base_reg, &pll->pll_base); + + /* Set cpcon to PLL_MISC */ + misc_reg = readl(&pll->pll_misc); + misc_reg &= ~PLL_CPCON_MASK; + misc_reg |= cpcon << PLL_CPCON_SHIFT; + writel(misc_reg, &pll->pll_misc); + + /* Enable PLL */ + base_reg |= PLL_ENABLE_MASK; + writel(base_reg, &pll->pll_base); + + /* Disable BYPASS */ + base_reg &= ~PLL_BYPASS_MASK; + writel(base_reg, &pll->pll_base); + + return 0; +} + +void clock_ll_start_uart(enum periph_id periph_id) +{ + /* Assert UART reset and enable clock */ + reset_set_enable(periph_id, 1); + clock_enable(periph_id); + clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */ + + /* wait for 2us */ + udelay(2); + + /* De-assert reset to UART */ + reset_set_enable(periph_id, 0); +} + +#ifdef CONFIG_OF_CONTROL +/* + * Convert a device tree clock ID to our peripheral ID. They are mostly + * the same but we are very cautious so we check that a valid clock ID is + * provided. + * + * @param clk_id Clock ID according to tegra20 device tree binding + * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid + */ +static enum periph_id clk_id_to_periph_id(int clk_id) +{ + if (clk_id > 95) + return PERIPH_ID_NONE; + + switch (clk_id) { + case 1: + case 2: + case 7: + case 10: + case 20: + case 30: + case 35: + case 49: + case 56: + case 74: + case 76: + case 77: + case 78: + case 79: + case 80: + case 81: + case 82: + case 83: + case 91: + case 95: + return PERIPH_ID_NONE; + default: + return clk_id; + } +} + +int clock_decode_periph_id(const void *blob, int node) +{ + enum periph_id id; + u32 cell[2]; + int err; + + err = fdtdec_get_int_array(blob, node, "clocks", cell, + ARRAY_SIZE(cell)); + if (err) + return -1; + id = clk_id_to_periph_id(cell[1]); + assert(clock_periph_id_isvalid(id)); + return id; +} +#endif /* CONFIG_OF_CONTROL */ + +int clock_verify(void) +{ + struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH); + u32 reg = readl(&pll->pll_base); + + if (!pllp_valid) { + printf("Warning: PLLP %x is not correct\n", reg); + return -1; + } + debug("PLLX %x is correct\n", reg); + return 0; +} + +void clock_early_init(void) +{ + /* + * 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, 456, 12, 1, 8); + break; + + case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 432, 26, 1, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); + break; + + case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 432, 13, 1, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); + break; + case CLOCK_OSC_FREQ_19_2: + default: + /* + * These are not supported. It is too early to print a + * message and the UART likely won't work anyway due to the + * oscillator being wrong. + */ + break; + } +} + +void clock_init(void) +{ + pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY); + pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH); + pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL); + pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC); + pll_rate[CLOCK_ID_SFROM32KHZ] = 32768; + debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]); + debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]); + debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]); +} diff --git a/arch/arm/cpu/tegra30-common/funcmux.c b/arch/arm/cpu/tegra30-common/funcmux.c new file mode 100644 index 0000000..6e28ac9 --- /dev/null +++ b/arch/arm/cpu/tegra30-common/funcmux.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (C) 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 + */ + +/* 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_UART2: + 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_set_func(PINGRP_ULPI_DATA4, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_ULPI_DATA5, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_ULPI_DATA6, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_UART2_RTS_N, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_UART2_CTS_N, 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); + pinmux_tristate_disable(PINGRP_ULPI_DATA4); + pinmux_tristate_disable(PINGRP_ULPI_DATA5); + pinmux_tristate_disable(PINGRP_ULPI_DATA6); + pinmux_tristate_disable(PINGRP_ULPI_DATA7); + pinmux_tristate_disable(PINGRP_UART2_RTS_N); + pinmux_tristate_disable(PINGRP_UART2_CTS_N); + 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/lowlevel_init.S b/arch/arm/cpu/tegra30-common/lowlevel_init.S new file mode 100644 index 0000000..91ff3b9 --- /dev/null +++ b/arch/arm/cpu/tegra30-common/lowlevel_init.S @@ -0,0 +1,42 @@ +/* + * SoC-specific setup info + * + * (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 + */ + +#include <config.h> +#include <version.h> +#include <linux/linkage.h> + + .align 5 +ENTRY(reset_cpu) + ldr r1, rstctl @ get addr for global reset + @ reg + ldr r3, [r1] + orr r3, r3, #0x10 + str r3, [r1] @ force reset + mov r0, r0 +_loop_forever: + b _loop_forever +rstctl: + .word PRM_RSTCTRL +ENDPROC(reset_cpu) diff --git a/arch/arm/cpu/tegra30-common/pinmux.c b/arch/arm/cpu/tegra30-common/pinmux.c new file mode 100644 index 0000000..387110e --- /dev/null +++ b/arch/arm/cpu/tegra30-common/pinmux.c @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (C) 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 + */ + +/* Tegra30 pin multiplexing functions */ + +#include <asm/io.h> +#include <asm/arch/tegra30.h> +#include <asm/arch/pinmux.h> +#include <common.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/cpu/tegra30-common/sys_info.c b/arch/arm/cpu/tegra30-common/sys_info.c new file mode 100644 index 0000000..eb638da --- /dev/null +++ b/arch/arm/cpu/tegra30-common/sys_info.c @@ -0,0 +1,35 @@ +/* + * (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 + */ + +#include <common.h> + +#ifdef CONFIG_DISPLAY_CPUINFO +/* Print CPU information */ +int print_cpuinfo(void) +{ + puts("TEGRA30\n"); + + /* TBD: Add printf of major/minor rev info, stepping, etc. */ + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ diff --git a/arch/arm/cpu/tegra30-common/timer.c b/arch/arm/cpu/tegra30-common/timer.c new file mode 100644 index 0000000..c532580 --- /dev/null +++ b/arch/arm/cpu/tegra30-common/timer.c @@ -0,0 +1,111 @@ +/* + * (C) Copyright 2010-2012 + * NVIDIA Corporation <www.nvidia.com> + * + * (C) Copyright 2008 + * Texas Instruments + * + * Richard Woodruff r-woodruff2@ti.com + * Syed Moahmmed Khasim khasim@ti.com + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * Alex Zuepke azu@sysgo.de + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, garyj@denx.de + * + * 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 + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/tegra30.h> +#include <asm/arch/timer.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* counter runs at 1MHz */ +#define TIMER_CLK 1000000 +#define TIMER_LOAD_VAL 0xffffffff + +/* timer without interrupts */ +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +/* delay x useconds */ +void __udelay(unsigned long usec) +{ + long tmo = usec * (TIMER_CLK / 1000) / 1000; + unsigned long now, last = timer_get_us(); + + while (tmo > 0) { + now = timer_get_us(); + if (last > now) /* count up timer overflow */ + tmo -= TIMER_LOAD_VAL - last + now; + else + tmo -= now - last; + last = now; + } +} + +ulong get_timer_masked(void) +{ + ulong now; + + /* current tick value */ + now = timer_get_us() / (TIMER_CLK / CONFIG_SYS_HZ); + + if (now >= gd->lastinc) /* normal mode (non roll) */ + /* move stamp forward with absolute diff ticks */ + gd->tbl += (now - gd->lastinc); + else /* we have rollover of incrementer */ + gd->tbl += ((TIMER_LOAD_VAL / (TIMER_CLK / CONFIG_SYS_HZ)) + - gd->lastinc) + now; + gd->lastinc = now; + return gd->tbl; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} + +unsigned long timer_get_us(void) +{ + struct timerus *timer_base = (struct timerus *)NV_PA_TMRUS_BASE; + + return readl(&timer_base->cntr_1us); +}

On 09/12/2012 04:10 PM, Tom Warren wrote:
diff --git a/arch/arm/cpu/tegra30-common/board.c b/arch/arm/cpu/tegra30-common/board.c
+unsigned int query_sdram_size(void) +{
- struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
- u32 reg;
- reg = readl(&pmc->pmc_scratch20);
- debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg);
- /* bits 31:28 in OdmData are used for RAM size */
- switch ((reg) >> 28) {
- case 1:
return 0x10000000; /* 256 MB */
- case 2:
return 0x20000000; /* 512 MB */
- case 4:
return 0x40000000; /* 1GB */
- case 8:
return 0x7ff00000; /* 2GB - 1MB */
- default:
return 0x40000000; /* 1GB */
- }
+}
According to our wiki, there's also a 3=768MB option here, although I have no idea if that's really true. I guess we can add it if we need it.
+static int uart_configs[] = {
- FUNCMUX_UART1_ULPI_UART2, /* UARTA */
- FUNCMUX_UART2_IRDA,
- -1,
- FUNCMUX_UART4_GMC,
- -1,
+};
I guess I'm repeating what I wrote for the funcmux.[ch] change, but those FUNCMUX_* enum names don't make sense on Tegra30.
diff --git a/arch/arm/cpu/tegra30-common/clock.c b/arch/arm/cpu/tegra30-common/clock.c
+/*
- This array translates a periph_id to a periphc_internal_id
- Not present/matched up:
- uint vi_sensor; _VI_SENSOR_0, 0x1A8
- SPDIF - which is both 0x08 and 0x0c
- */
+#define NONE(name) (-1) +#define OFFSET(name, value) PERIPHC_ ## name +static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
- /* Low word: 31:0 */
- NONE(CPU),
- NONE(COP),
- NONE(TRIGSYS),
- NONE(RESERVED3),
- NONE(RESERVED4),
- NONE(TMR),
- PERIPHC_UART1,
- PERIPHC_UART2, /* and vfir 0x68 */
Oh, there's a mapping table anyway. In that case, I would definitely recommend aligning the enum order with the kernel to allow easier DT handling in the future.
Still, as you mentioned in another email, this is something we can do later since it doesn't change any interface to anything outside U-Boot.
+#ifdef CONFIG_OF_CONTROL +/*
- Convert a device tree clock ID to our peripheral ID. They are mostly
- the same but we are very cautious so we check that a valid clock ID is
- provided.
- @param clk_id Clock ID according to tegra20 device tree binding
- @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
- */
+static enum periph_id clk_id_to_periph_id(int clk_id) +{
- if (clk_id > 95)
return PERIPH_ID_NONE;
- switch (clk_id) {
- case 1:
- case 2:
- case 7:
- case 10:
- case 20:
- case 30:
- case 35:
- case 49:
- case 56:
- case 74:
- case 76:
- case 77:
- case 78:
- case 79:
- case 80:
- case 81:
- case 82:
- case 83:
- case 91:
- case 95:
return PERIPH_ID_NONE;
- default:
return clk_id;
- }
+}
This is something that would need to be validated against the Tegra30 device tree bindings for the clock module. I guess since CONFIG_OF_CONTROL isn't enabled now, it's somewhat OK to defer this until later, but a comment here indicating that fact would be useful.
diff --git a/arch/arm/cpu/tegra30-common/funcmux.c b/arch/arm/cpu/tegra30-common/funcmux.c
+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_UART2:
pinmux_set_func(PINGRP_ULPI_DATA0, PMUX_FUNC_UARTA); txd
pinmux_set_func(PINGRP_ULPI_DATA1, PMUX_FUNC_UARTA); rxd
pinmux_set_func(PINGRP_ULPI_DATA2, PMUX_FUNC_UARTA); cts
pinmux_set_func(PINGRP_ULPI_DATA3, PMUX_FUNC_UARTA); rts
pinmux_set_func(PINGRP_ULPI_DATA4, PMUX_FUNC_UARTA); ri
pinmux_set_func(PINGRP_ULPI_DATA5, PMUX_FUNC_UARTA); dcd
pinmux_set_func(PINGRP_ULPI_DATA6, PMUX_FUNC_UARTA); dsr
pinmux_set_func(PINGRP_UART2_RTS_N, PMUX_FUNC_UARTA); txd
pinmux_set_func(PINGRP_UART2_CTS_N, PMUX_FUNC_UARTA); rxd
I've augmented the lines above with comments re: what signals are selected onto each line when those functions are selected.
Note that RXD/TXD are duplicated. I suspect you're just getting lucky that when rxd is selected on both ULPI_DATA1 and UART2_CTS_N, that it happens to take the input from the correct one of those two pins.
Looking at the schematic for Cardhu A02, you only want to configure ULPI_DATA[3:0] for UARTA. All those other pins are used for purposes other than UART.
And somewhat as an aside, this is why I wonder if a funcmux-style API is still a good idea; you could easily have the following sets of UARTA signals in use:
RXD+TXD RXD+TXD+RTS+CTS RXD+TXD+RTS+CTS+RI+DCD+DSR+DTR (or perhaps subsets of those last 3?)
... and for each of those 3 sets of signals, any of the individual signals can actually be muxed onto one of n different pins, where n is at least 2, and up to 4 in many cases. That's perhaps thousands of combinations just for UARTA!
Calling pinmux.c APIs directly from the board file seems much simpler, and avoids a level of abstraction that doesn't really exist in HW.

Hi Tom,
On Wed, Sep 12, 2012 at 3:10 PM, Tom Warren twarren.nvidia@gmail.com wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
arch/arm/cpu/tegra30-common/Makefile | 51 ++ arch/arm/cpu/tegra30-common/ap30.c | 98 +++ arch/arm/cpu/tegra30-common/board.c | 141 ++++ arch/arm/cpu/tegra30-common/clock.c | 1099 +++++++++++++++++++++++++++
Again I feel that a lot of the code here is common. We actually got away with identical code for T30 (even the tables!). Agreed that won't really work, but it should hows much can be common.
Regards, Simon

Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/dts/tegra30.dtsi | 280 +++++++++++++++++++++++++++++++++++ board/nvidia/dts/tegra30-cardhu.dts | 92 ++++++++++++ 2 files changed, 372 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..a889705 --- /dev/null +++ b/arch/arm/dts/tegra30.dtsi @@ -0,0 +1,280 @@ +/include/ "skeleton.dtsi" + +/ { + model = "NVIDIA Tegra30"; + compatible = "nvidia,tegra30"; + interrupt-parent = <&intc>; + + tegra_car: clock@60006000 { + compatible = "nvidia,tegra30-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <0>; + + osc: clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + }; + + intc: interrupt-controller@50041000 { + compatible = "nvidia,tegra30-gic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = < 0x50041000 0x1000 >, + < 0x50040100 0x0100 >; + }; + + i2c@7000c000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2c"; + reg = <0x7000C000 0x100>; + interrupts = < 70 >; + /* PERIPH_ID_I2C1, PLL_P_OUT3 */ + clocks = <&tegra_car 12>, <&tegra_car 124>; + }; + + i2c@7000c400 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2c"; + reg = <0x7000C400 0x100>; + interrupts = < 116 >; + /* PERIPH_ID_I2C2, PLL_P_OUT3 */ + clocks = <&tegra_car 54>, <&tegra_car 124>; + }; + + i2c@7000c500 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2c"; + reg = <0x7000C500 0x100>; + interrupts = < 124 >; + /* PERIPH_ID_I2C3, PLL_P_OUT3 */ + clocks = <&tegra_car 67>, <&tegra_car 124>; + }; + + i2c@7000d000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2c-dvc"; + reg = <0x7000D000 0x200>; + interrupts = < 85 >; + /* PERIPH_ID_DVC_I2C, PLL_P_OUT3 */ + clocks = <&tegra_car 47>, <&tegra_car 124>; + }; + + i2s@70002800 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2s"; + reg = <0x70002800 0x200>; + interrupts = < 45 >; + dma-channel = < 2 >; + }; + + i2s@70002a00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2s"; + reg = <0x70002a00 0x200>; + interrupts = < 35 >; + dma-channel = < 1 >; + }; + + das@70000c00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-das"; + reg = <0x70000c00 0x80>; + }; + + gpio: gpio@6000d000 { + compatible = "nvidia,tegra30-gpio"; + reg = < 0x6000d000 0x1000 >; + interrupts = < 64 65 66 67 87 119 121 >; + #gpio-cells = <2>; + gpio-controller; + }; + + pinmux: pinmux@70000000 { + compatible = "nvidia,tegra30-pinmux"; + reg = < 0x70000014 0x10 /* Tri-state registers */ + 0x70000080 0x20 /* Mux registers */ + 0x700000a0 0x14 /* Pull-up/down registers */ + 0x70000868 0xa8 >; /* Pad control registers */ + }; + + serial@70006000 { + compatible = "nvidia,tegra30-uart"; + reg = <0x70006000 0x40>; + id = <0>; + reg-shift = <2>; + interrupts = < 68 >; + status = "disabled"; + }; + + serial@70006040 { + compatible = "nvidia,tegra30-uart"; + reg = <0x70006040 0x40>; + id = <1>; + reg-shift = <2>; + interrupts = < 69 >; + status = "disabled"; + }; + + serial@70006200 { + compatible = "nvidia,tegra30-uart"; + reg = <0x70006200 0x100>; + id = <2>; + reg-shift = <2>; + interrupts = < 78 >; + status = "disabled"; + }; + + serial@70006300 { + compatible = "nvidia,tegra30-uart"; + reg = <0x70006300 0x100>; + id = <3>; + reg-shift = <2>; + interrupts = < 122 >; + status = "disabled"; + }; + + serial@70006400 { + compatible = "nvidia,tegra30-uart"; + reg = <0x70006400 0x100>; + id = <4>; + reg-shift = <2>; + interrupts = < 123 >; + status = "disabled"; + }; + + sdhci@78000000 { + compatible = "nvidia,tegra30-sdhci"; + reg = <0x78000000 0x200>; + interrupts = < 46 >; + periph-id = <14>; // PERIPH_ID_SDMMC1 + status = "disabled"; + }; + + sdhci@78000200 { + compatible = "nvidia,tegra30-sdhci"; + reg = <0x78000200 0x200>; + interrupts = < 47 >; + periph-id = <9>; // PERIPH_ID_SDMMC2 + status = "disabled"; + }; + + sdhci@78000400 { + compatible = "nvidia,tegra30-sdhci"; + reg = <0x78000400 0x200>; + interrupts = < 51 >; + periph-id = <69>; // PERIPH_ID_SDMMC3 + status = "disabled"; + }; + + sdhci@78000600 { + compatible = "nvidia,tegra30-sdhci"; + reg = <0x78000600 0x200>; + interrupts = < 63 >; + periph-id = <15>; // PERIPH_ID_SDMMC4 + status = "disabled"; + }; + + pwfm0: pwm@7000a000 { + compatible = "nvidia,tegra30-sdhci"; + reg = <0x7000a000 0x4>; + status = "disabled"; + }; + + pwfm1: pwm@7000a010 { + compatible = "nvidia,tegra30-sdhci"; + reg = <0x7000a010 0x4>; + status = "disabled"; + }; + + pwfm2: pwm@7000a020 { + compatible = "nvidia,tegra30-sdhci"; + reg = <0x7000a020 0x4>; + status = "disabled"; + }; + + pwfm3: pwm@7000a030 { + compatible = "nvidia,tegra30-sdhci"; + reg = <0x7000a030 0x4>; + status = "disabled"; + }; + + display1: display@0x54200000 { + compatible = "nvidia,tegra30-display"; + reg = <0x54200000 0x40000>; + status = "disabled"; + }; + + usb@c5000000 { + compatible = "nvidia,tegra30-ehci", "usb-ehci"; + reg = <0xc5000000 0x4000>; + interrupts = < 52 >; + phy_type = "utmi"; + clocks = <&tegra_car 22>; /* PERIPH_ID_USBD */ + nvidia,has-legacy-mode; + }; + + usbparams@0 { + compatible = "nvidia,tegra30-usbparams"; + osc-frequency = <13000000>; + /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */ + params = <0x3c0 0x0d 0x00 0xc 0 0x02 0x33 0x05 0x7f 0x7ef4 5>; + }; + + usbparams@1 { + compatible = "nvidia,tegra30-usbparams"; + osc-frequency = <19200000>; + params = <0x0c8 0x04 0x00 0x3 0 0x03 0x4b 0x06 0xbb 0xbb80 7>; + }; + + usbparams@2 { + compatible = "nvidia,tegra30-usbparams"; + osc-frequency = <12000000>; + params = <0x3c0 0x0c 0x00 0xc 0 0x02 0x2f 0x08 0x76 0x7530 5>; + }; + + usbparams@3 { + compatible = "nvidia,tegra30-usbparams"; + osc-frequency = <26000000>; + params = <0x3c0 0x1a 0x00 0xc 0 0x04 0x66 0x11 0xfe 0xfde8 9>; + }; + + usb@7d000000 { + compatible = "nvidia,tegra30-usb"; + reg = <0x7d000000 0x8000>; + interrupts = < 53 >; + phy_type = "ulpi"; + periph-id = <22>; /* PERIPH_ID_USBD */ + clocks = <&tegra_car 58>; + status = "disabled"; + }; + + usb@7d008000 { + compatible = "nvidia,tegra30-ehci", "usb-ehci"; + reg = <0x7d008000 0x8000>; + interrupts = < 129 >; + phy_type = "utmi"; + periph-id = <59>; /* PERIPH_ID_USB3 */ + clocks = <&tegra_car 59>; + status = "disabled"; + }; + + emc@7000f400 { + #address-cells = < 1 >; + #size-cells = < 0 >; + compatible = "nvidia,tegra30-emc"; + reg = <0x7000f400 0x200>; + }; +}; diff --git a/board/nvidia/dts/tegra30-cardhu.dts b/board/nvidia/dts/tegra30-cardhu.dts new file mode 100644 index 0000000..7b2ccdf --- /dev/null +++ b/board/nvidia/dts/tegra30-cardhu.dts @@ -0,0 +1,92 @@ +/dts-v1/; + +/memreserve/ 0x1c000000 0x04000000; +/include/ ARCH_CPU_DTS + +/ { + model = "NVIDIA Cardhu"; + compatible = "nvidia,cardhu", "nvidia,tegra30"; + + aliases { + /* This defines the order of our USB ports */ + usb0 = "/usb@7d008000"; + usb1 = "/usb@7d000000"; + + sdmmc0 = "/sdhci@78000600"; + sdmmc1 = "/sdhci@78000000"; + }; + + chosen { + bootargs = ""; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0xc0000000>; + }; + + /* This is not used in U-Boot, but is expected to be in kernel .dts */ + i2c@7000d000 { + clock-frequency = <100000>; + pmic@34 { + compatible = "ti,tps6586x"; + reg = <0x34>; + + clk_32k: clock { + compatible = "fixed-clock"; + /* + * leave out for now due to CPP: + * #clock-cells = <0>; + */ + clock-frequency = <32768>; + }; + }; + }; + + clocks { + osc { + clock-frequency = <12000000>; + }; + }; + + clock@60006000 { + clocks = <&clk_32k &osc>; + }; + + serial@70006000 { + status = "ok"; + clock-frequency = < 216000000 >; + }; + + sdhci@78000000 { + status = "ok"; + width = <4>; /* width of SDIO port */ + removable = <1>; + /* Parameter 3 bit 0:1=output, 0=input; bit 1:1=high, 0=low */ + cd-gpios = <&gpio 69 0>; /* card detect, gpio PI5 */ + wp-gpios = <&gpio 155 0>; /* write protect, gpio PT3 */ + power-gpios = <&gpio 31 3>; /* power enable, gpio PD7 */ + }; + + sdhci@78000600 { + status = "ok"; + width = <4>; /* width of SDIO port, s/b 8? */ + removable = <0>; + }; + usb@0x7d000000 { + status = "ok"; + host-mode = <1>; + vbus_pullup-gpio = <&gpio 233 3>; /* PDD1, EN_3V3_PU */ + }; + + usbphy: usbphy@0 { + compatible = "smsc,usb3315"; + status = "ok"; + }; + + usb@0x7d008000 { + status = "ok"; + utmi = <&usbphy>; + host-mode = <0>; + }; +};

On 09/12/2012 04:10 PM, Tom Warren wrote:
Nitpick: I think there's a lot of mixing spaces/TABs for indentation; things don't align correctly when I view this.
For this patch in particular, I would strongly request that we either start with the bare minimum content, and add nodes as drivers require them, or import that latest Linux kernel's copy of these files. The reason being that many of the bindings used here aren't up-to-date, and there is at least some stale data from Tegra20 left over. It'd avoid any review issue at all if this patch was just a copy from the kernel.

Signed-off-by: Tom Warren twarren@nvidia.com --- board/nvidia/cardhu/Makefile | 48 ++++ board/nvidia/cardhu/cardhu.c | 87 +++++++ board/nvidia/cardhu/pinmux-config-common.h | 346 ++++++++++++++++++++++++++++ 3 files changed, 481 insertions(+), 0 deletions(-) create mode 100644 board/nvidia/cardhu/Makefile create mode 100644 board/nvidia/cardhu/cardhu.c create mode 100644 board/nvidia/cardhu/pinmux-config-common.h
diff --git a/board/nvidia/cardhu/Makefile b/board/nvidia/cardhu/Makefile new file mode 100644 index 0000000..a910577 --- /dev/null +++ b/board/nvidia/cardhu/Makefile @@ -0,0 +1,48 @@ +# +# (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 +# + +include $(TOPDIR)/config.mk + +ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)../common) +endif + +LIB = $(obj)lib$(BOARD).o + +COBJS := $(BOARD).o + +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/nvidia/cardhu/cardhu.c b/board/nvidia/cardhu/cardhu.c new file mode 100644 index 0000000..f907906 --- /dev/null +++ b/board/nvidia/cardhu/cardhu.c @@ -0,0 +1,87 @@ +/* + * (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 + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/tegra30.h> +#include <asm/arch/clock.h> +#include <asm/arch/funcmux.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/mmc.h> +#include <asm/gpio.h> +#ifdef CONFIG_TEGRA_MMC +#include <mmc.h> +#endif + +/* + * Routine: gpio_config_uart + * Description: Does nothing on Cardhu - no conflict w/SPI. + */ +void gpio_config_uart(void) +{ +} + +#ifdef CONFIG_TEGRA_MMC +/* + * Routine: pin_mux_mmc + * Description: setup the pin muxes/tristate values for the SDMMC(s) + */ +static void pin_mux_mmc(void) +{ + funcmux_select(PERIPH_ID_SDMMC4, FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT); + funcmux_select(PERIPH_ID_SDMMC3, FUNCMUX_SDMMC3_SDB_4BIT); + + /* For power GPIO PI6 */ + pinmux_tristate_disable(PINGRP_ATA); + /* For CD GPIO PI5 */ + pinmux_tristate_disable(PINGRP_ATC); +} + +/* this is a weak define that we are overriding */ +int board_mmc_init(bd_t *bd) +{ + debug("board_mmc_init called\n"); + + /* Enable muxes, etc. for SDMMC controllers */ + pin_mux_mmc(); + + debug("board_mmc_init: init eMMC\n"); + /* init dev 0, eMMC chip, with 4-bit bus */ + /* The board has an 8-bit bus, but 8-bit doesn't work yet */ + tegra_mmc_init(0, 4, -1, -1); + + debug("board_mmc_init: init SD slot\n"); + /* init dev 1, SD slot, with 4-bit bus */ + tegra_mmc_init(1, 4, GPIO_PI6, GPIO_PI5); + + return 0; +} +#endif + +#ifdef CONFIG_USB_EHCI_TEGRA +void pin_mux_usb(void) +{ + /* For USB's GPIO PD0. For now, since we have no pinmux in fdt */ + pinmux_tristate_disable(PINGRP_SLXK); +} +#endif diff --git a/board/nvidia/cardhu/pinmux-config-common.h b/board/nvidia/cardhu/pinmux-config-common.h new file mode 100644 index 0000000..20583c9 --- /dev/null +++ b/board/nvidia/cardhu/pinmux-config-common.h @@ -0,0 +1,346 @@ +/* + * (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 PINMUX_CONFIG_COMMON_H +#define 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 /* PINMUX_CONFIG_COMMON_H */

On 09/12/2012 04:10 PM, Tom Warren wrote:
diff --git a/board/nvidia/cardhu/cardhu.c b/board/nvidia/cardhu/cardhu.c
+/*
- Routine: gpio_config_uart
- Description: Does nothing on Cardhu - no conflict w/SPI.
- */
+void gpio_config_uart(void) +{ +}
For reference, personally, I'd expect to see the UART pinmux set up there (at least after Lucas's cleanup of GPIO/UART/pinmux functions patch).
+#ifdef CONFIG_TEGRA_MMC +/*
- Routine: pin_mux_mmc
- Description: setup the pin muxes/tristate values for the SDMMC(s)
- */
+static void pin_mux_mmc(void) +{
- funcmux_select(PERIPH_ID_SDMMC4, FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT);
- funcmux_select(PERIPH_ID_SDMMC3, FUNCMUX_SDMMC3_SDB_4BIT);
...
+#ifdef CONFIG_USB_EHCI_TEGRA +void pin_mux_usb(void) +{
- /* For USB's GPIO PD0. For now, since we have no pinmux in fdt */
- pinmux_tristate_disable(PINGRP_SLXK);
+} +#endif
None of that would compile if the options were enabled. I'd definitely suggest removing since it needs to be completely re-written anyway. Otherwise, someone else isn't going to know and it'll seem like reference code.
diff --git a/board/nvidia/cardhu/pinmux-config-common.h b/board/nvidia/cardhu/pinmux-config-common.h
I don't think anything in this file is actually used?

Hi Tom,
On Wed, Sep 12, 2012 at 3:10 PM, Tom Warren twarren.nvidia@gmail.com wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
board/nvidia/cardhu/Makefile | 48 ++++ board/nvidia/cardhu/cardhu.c | 87 +++++++ board/nvidia/cardhu/pinmux-config-common.h | 346 ++++++++++++++++++++++++++++ 3 files changed, 481 insertions(+), 0 deletions(-) create mode 100644 board/nvidia/cardhu/Makefile create mode 100644 board/nvidia/cardhu/cardhu.c create mode 100644 board/nvidia/cardhu/pinmux-config-common.h
diff --git a/board/nvidia/cardhu/Makefile b/board/nvidia/cardhu/Makefile new file mode 100644 index 0000000..a910577 --- /dev/null +++ b/board/nvidia/cardhu/Makefile @@ -0,0 +1,48 @@ +# +# (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 +#
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)../common) +endif
+LIB = $(obj)lib$(BOARD).o
+COBJS := $(BOARD).o
+SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS))
+$(LIB): $(obj).depend $(OBJS)
$(call cmd_link_o_target, $(OBJS))
+#########################################################################
+# defines $(obj).depend target +include $(SRCTREE)/rules.mk
+sinclude $(obj).depend
+######################################################################### diff --git a/board/nvidia/cardhu/cardhu.c b/board/nvidia/cardhu/cardhu.c new file mode 100644 index 0000000..f907906 --- /dev/null +++ b/board/nvidia/cardhu/cardhu.c @@ -0,0 +1,87 @@ +/*
- (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
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/arch/tegra30.h> +#include <asm/arch/clock.h> +#include <asm/arch/funcmux.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/mmc.h> +#include <asm/gpio.h> +#ifdef CONFIG_TEGRA_MMC +#include <mmc.h> +#endif
+/*
- Routine: gpio_config_uart
- Description: Does nothing on Cardhu - no conflict w/SPI.
- */
+void gpio_config_uart(void) +{ +}
+#ifdef CONFIG_TEGRA_MMC +/*
- Routine: pin_mux_mmc
- Description: setup the pin muxes/tristate values for the SDMMC(s)
- */
+static void pin_mux_mmc(void) +{
funcmux_select(PERIPH_ID_SDMMC4, FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT);
funcmux_select(PERIPH_ID_SDMMC3, FUNCMUX_SDMMC3_SDB_4BIT);
/* For power GPIO PI6 */
pinmux_tristate_disable(PINGRP_ATA);
/* For CD GPIO PI5 */
pinmux_tristate_disable(PINGRP_ATC);
+}
+/* this is a weak define that we are overriding */ +int board_mmc_init(bd_t *bd) +{
debug("board_mmc_init called\n");
/* Enable muxes, etc. for SDMMC controllers */
pin_mux_mmc();
debug("board_mmc_init: init eMMC\n");
/* init dev 0, eMMC chip, with 4-bit bus */
/* The board has an 8-bit bus, but 8-bit doesn't work yet */
tegra_mmc_init(0, 4, -1, -1);
debug("board_mmc_init: init SD slot\n");
/* init dev 1, SD slot, with 4-bit bus */
tegra_mmc_init(1, 4, GPIO_PI6, GPIO_PI5);
return 0;
+} +#endif
+#ifdef CONFIG_USB_EHCI_TEGRA +void pin_mux_usb(void) +{
/* For USB's GPIO PD0. For now, since we have no pinmux in fdt */
pinmux_tristate_disable(PINGRP_SLXK);
+} +#endif diff --git a/board/nvidia/cardhu/pinmux-config-common.h b/board/nvidia/cardhu/pinmux-config-common.h new file mode 100644 index 0000000..20583c9 --- /dev/null +++ b/board/nvidia/cardhu/pinmux-config-common.h @@ -0,0 +1,346 @@ +/*
(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 PINMUX_CONFIG_COMMON_H +#define 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),
This is using a fixed table instead of selecting based on individual settings or the fdt, and presumably each board will need its own table. The funcmux approach is a half-way house towards the fdt. The intent with that was to define particular configurations for each peripheral, that board vendors can select from.
Regards, Simon

Signed-off-by: Tom Warren twarren@nvidia.com --- include/configs/cardhu.h | 52 +++++++++++ include/configs/tegra30-common.h | 188 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+), 0 deletions(-) create mode 100644 include/configs/cardhu.h create mode 100644 include/configs/tegra30-common.h
diff --git a/include/configs/cardhu.h b/include/configs/cardhu.h new file mode 100644 index 0000000..bfadbff --- /dev/null +++ b/include/configs/cardhu.h @@ -0,0 +1,52 @@ +/* + * (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 __CONFIG_H +#define __CONFIG_H + +#include <asm/sizes.h> + +#include "tegra30-common.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/tegra30-common.h b/include/configs/tegra30-common.h new file mode 100644 index 0000000..b23823d --- /dev/null +++ b/include/configs/tegra30-common.h @@ -0,0 +1,188 @@ +/* + * (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 __TEGRA30_COMMON_H +#define __TEGRA30_COMMON_H +#include <asm/sizes.h> + +/* + * QUOTE(m) will evaluate to a string version of the value of the macro m + * passed in. The extra level of indirection here is to first evaluate the + * macro m before applying the quoting operator. + */ +#define QUOTE_(m) #m +#define QUOTE(m) QUOTE_(m) + +/* + * High Level Configuration Options + */ +#define CONFIG_ARMCORTEXA9 /* This is an ARM V7 CPU 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 */ + +#define CONFIG_SYS_CACHELINE_SIZE 32 + +#include <asm/arch/tegra30.h> /* get chip and board defs */ + +/* + * Display CPU and Board information + */ +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ +#define CONFIG_OF_LIBFDT /* enable passing of devicetree */ + +/* Environment */ +#define CONFIG_ENV_VARS_UBOOT_CONFIG +#define CONFIG_ENV_SIZE 0x2000 /* Total Size Environment */ + +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (4 << 20) /* 4MB */ + +/* + * PllX Configuration + */ +#define CONFIG_SYS_CPU_OSC_FREQUENCY 1000000 /* Set CPU clock to 1GHz */ + +/* + * NS16550 Configuration + */ +#define V_NS16550_CLK 216000000 /* 216MHz (pllp_out0) */ + +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE (-4) +#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK + +/* + * select serial console configuration + */ +#define CONFIG_CONS_INDEX 1 + +/* 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} + +/* include default commands */ +#include <config_cmd_default.h> + +/* remove unused commands */ +#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ +#undef CONFIG_CMD_FPGA /* FPGA configuration support */ +#undef CONFIG_CMD_IMI +#undef CONFIG_CMD_IMLS +#undef CONFIG_CMD_NFS /* NFS support */ +#undef CONFIG_CMD_NET /* network support */ + +/* turn on command-line edit/hist/auto */ +#define CONFIG_CMDLINE_EDITING +#define CONFIG_COMMAND_HISTORY +#define CONFIG_AUTO_COMPLETE + +#define CONFIG_SYS_NO_FLASH + +/* Environment information, boards can override if required */ +#define CONFIG_CONSOLE_MUX +#define CONFIG_SYS_CONSOLE_IS_IN_ENV +#define TEGRA_DEVICE_SETTINGS "stdin=serial\0" \ + "stdout=serial\0" \ + "stderr=serial\0" + +#define CONFIG_LOADADDR 0x80408000 /* def. location for kernel */ +#define CONFIG_BOOTDELAY 2 /* -1 to disable auto boot */ + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT V_PROMPT +/* + * Increasing the size of the IO buffer as default nfsargs size is more + * than 256 and so it is not possible to edit it + */ +#define CONFIG_SYS_CBSIZE (256 * 2) /* Console I/O Buffer Size */ +/* Print Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE) + +#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 (0x80A00800) /* default */ +#define CONFIG_SYS_HZ 1000 + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKBASE (NV_PA_SDRAM_BASE + 0x2800000) /* 40MB */ +#define CONFIG_STACKSIZE 0x20000 /* 128K regular stack*/ + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM_1 NV_PA_SDRC_CS0 +#define PHYS_SDRAM_1_SIZE 0x20000000 /* 512M */ + +#define CONFIG_SYS_TEXT_BASE 0x8010e000 +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 + +#define CONFIG_SYS_INIT_RAM_ADDR CONFIG_STACKBASE +#define CONFIG_SYS_INIT_RAM_SIZE CONFIG_SYS_MALLOC_LEN +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ + CONFIG_SYS_INIT_RAM_SIZE - \ + GENERATED_GBL_DATA_SIZE) + +#define CONFIG_TEGRA_GPIO +#define CONFIG_CMD_GPIO +#define CONFIG_CMD_ENTERRCM +#define CONFIG_CMD_BOOTZ + +/* Defines for SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_NAND_SIMPLE +#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 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)/tegra30/u-boot-spl.lds" + +#endif /* __TEGRA30_COMMON_H */

On 09/12/2012 04:10 PM, Tom Warren wrote:
diff --git a/include/configs/tegra30-common.h b/include/configs/tegra30-common.h
+/*
- QUOTE(m) will evaluate to a string version of the value of the macro m
- passed in. The extra level of indirection here is to first evaluate the
- macro m before applying the quoting operator.
- */
+#define QUOTE_(m) #m +#define QUOTE(m) QUOTE_(m)
Seems like a good candidate for a common header (not Tegra-common, but across all of U-Boot).
+#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
115200}
IIRC, that's the default now and can be removed. There may be other variables the comment applies to - Tom Rini would know better since he pointed them out in my RPi patches.
+#define CONFIG_SYS_LOAD_ADDR (0x80A00800) /* default */
Hmmm. I notice that both here and the equivalent Tegra20 file, we define both CONFIG_LOADADDR and CONFIG_SYS_LOAD_ADDR. Should we actually be defining both, and with different values (is one unused?).

On 09/13/2012 03:33 PM, Stephen Warren wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
diff --git a/include/configs/tegra30-common.h b/include/configs/tegra30-common.h
+/*
- QUOTE(m) will evaluate to a string version of the value of the macro m
- passed in. The extra level of indirection here is to first evaluate the
- macro m before applying the quoting operator.
- */
+#define QUOTE_(m) #m +#define QUOTE(m) QUOTE_(m)
Seems like a good candidate for a common header (not Tegra-common, but across all of U-Boot).
This is __stringify() that Marek needs to address Wolfgang's comment on still, iirc.
+#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
115200}
IIRC, that's the default now and can be removed. There may be other variables the comment applies to - Tom Rini would know better since he pointed them out in my RPi patches.
That and the hush prompt one if it's there need to go.

Dear Tom Rini,
On 09/13/2012 03:33 PM, Stephen Warren wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
diff --git a/include/configs/tegra30-common.h b/include/configs/tegra30-common.h
+/*
- QUOTE(m) will evaluate to a string version of the value of the macro
m + * passed in. The extra level of indirection here is to first evaluate the + * macro m before applying the quoting operator.
- */
+#define QUOTE_(m) #m +#define QUOTE(m) QUOTE_(m)
Seems like a good candidate for a common header (not Tegra-common, but across all of U-Boot).
This is __stringify() that Marek needs to address Wolfgang's comment on still, iirc.
I need to roll out the stringify patches ... the issues should be fixed.
+#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
115200}
IIRC, that's the default now and can be removed. There may be other variables the comment applies to - Tom Rini would know better since he pointed them out in my RPi patches.
That and the hush prompt one if it's there need to go.
Best regards, Marek Vasut

Hi Tom,
On Wed, Sep 12, 2012 at 3:10 PM, Tom Warren twarren.nvidia@gmail.com wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
include/configs/cardhu.h | 52 +++++++++++ include/configs/tegra30-common.h | 188 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+), 0 deletions(-) create mode 100644 include/configs/cardhu.h create mode 100644 include/configs/tegra30-common.h
diff --git a/include/configs/cardhu.h b/include/configs/cardhu.h new file mode 100644 index 0000000..bfadbff --- /dev/null +++ b/include/configs/cardhu.h @@ -0,0 +1,52 @@ +/*
- (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 __CONFIG_H +#define __CONFIG_H
+#include <asm/sizes.h>
+#include "tegra30-common.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/tegra30-common.h b/include/configs/tegra30-common.h new file mode 100644 index 0000000..b23823d --- /dev/null +++ b/include/configs/tegra30-common.h @@ -0,0 +1,188 @@ +/*
- (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 __TEGRA30_COMMON_H +#define __TEGRA30_COMMON_H +#include <asm/sizes.h>
+/*
- QUOTE(m) will evaluate to a string version of the value of the macro m
- passed in. The extra level of indirection here is to first evaluate the
- macro m before applying the quoting operator.
- */
+#define QUOTE_(m) #m +#define QUOTE(m) QUOTE_(m)
+/*
- High Level Configuration Options
- */
+#define CONFIG_ARMCORTEXA9 /* This is an ARM V7 CPU 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 */
+#define CONFIG_SYS_CACHELINE_SIZE 32
+#include <asm/arch/tegra30.h> /* get chip and board defs */
+/*
- Display CPU and Board information
- */
+#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ +#define CONFIG_OF_LIBFDT /* enable passing of devicetree */
Do you think there should be a tegra-common.h, included by tegra20-common and tegra30-common? That was the approach we talk in the Chromium tree.
Regards, Simon

Simon,
On Tue, Sep 18, 2012 at 12:46 PM, Simon Glass sjg@chromium.org wrote:
Hi Tom,
On Wed, Sep 12, 2012 at 3:10 PM, Tom Warren twarren.nvidia@gmail.com wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
include/configs/cardhu.h | 52 +++++++++++ include/configs/tegra30-common.h | 188 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+), 0 deletions(-) create mode 100644 include/configs/cardhu.h create mode 100644 include/configs/tegra30-common.h
diff --git a/include/configs/cardhu.h b/include/configs/cardhu.h new file mode 100644 index 0000000..bfadbff --- /dev/null +++ b/include/configs/cardhu.h @@ -0,0 +1,52 @@ +/*
- (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 __CONFIG_H +#define __CONFIG_H
+#include <asm/sizes.h>
+#include "tegra30-common.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/tegra30-common.h b/include/configs/tegra30-common.h new file mode 100644 index 0000000..b23823d --- /dev/null +++ b/include/configs/tegra30-common.h @@ -0,0 +1,188 @@ +/*
- (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 __TEGRA30_COMMON_H +#define __TEGRA30_COMMON_H +#include <asm/sizes.h>
+/*
- QUOTE(m) will evaluate to a string version of the value of the macro m
- passed in. The extra level of indirection here is to first evaluate the
- macro m before applying the quoting operator.
- */
+#define QUOTE_(m) #m +#define QUOTE(m) QUOTE_(m)
+/*
- High Level Configuration Options
- */
+#define CONFIG_ARMCORTEXA9 /* This is an ARM V7 CPU 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 */
+#define CONFIG_SYS_CACHELINE_SIZE 32
+#include <asm/arch/tegra30.h> /* get chip and board defs */
+/*
- Display CPU and Board information
- */
+#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ +#define CONFIG_OF_LIBFDT /* enable passing of devicetree */
Do you think there should be a tegra-common.h, included by tegra20-common and tegra30-common? That was the approach we talk in the Chromium tree.
There can be. There's already a tegra-common-post.h header for boot stuff. I'll take a look.
Thanks
Regards, Simon

Signed-off-by: Tom Warren twarren@nvidia.com --- board/nvidia/common/board.c | 27 ++++++++++++++++++++++++++- 1 files changed, 26 insertions(+), 1 deletions(-)
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c index afe832a..4a86c30 100644 --- a/board/nvidia/common/board.c +++ b/board/nvidia/common/board.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2010,2011 + * (C) Copyright 2010-2012 * NVIDIA Corporation <www.nvidia.com> * * See file CREDITS for list of people who contributed to this @@ -25,7 +25,11 @@ #include <ns16550.h> #include <linux/compiler.h> #include <asm/io.h> +#if defined(CONFIG_TEGRA20) #include <asm/arch/tegra20.h> +#else /* Tegra30 */ +#include <asm/arch/tegra30.h> +#endif #include <asm/arch/sys_proto.h>
#include <asm/arch/board.h> @@ -87,6 +91,25 @@ static void power_det_init(void) #endif }
+#ifdef CONFIG_TEGRA30 +#include "../cardhu/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 +} + /* * Routine: board_init * Description: Early hardware init. @@ -152,6 +175,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 */

On 09/12/2012 04:10 PM, Tom Warren wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
board/nvidia/common/board.c | 27 ++++++++++++++++++++++++++- 1 files changed, 26 insertions(+), 1 deletions(-)
Common code:-) :-) But ...
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
+#ifdef CONFIG_TEGRA30 +#include "../cardhu/pinmux-config-common.h" +#endif
Not all Tegra30 will be Cardhu...
Given this is really board-specific, shouldn't the following be an empty weak definition:
+/*
- 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 +}
... and the function be overridden in board files as needed?
If we are moving to a model of a single function that sets up the entire pin mux at boot (which seems fine to me, and could eventually be driven by DT if it happened late enough), then it seems like we wouldn't need e.g. pin_mux_mmc() or pin_mux_usb() any more.

Hi,
On Thu, Sep 13, 2012 at 3:37 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
board/nvidia/common/board.c | 27 ++++++++++++++++++++++++++- 1 files changed, 26 insertions(+), 1 deletions(-)
Common code:-) :-) But ...
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
+#ifdef CONFIG_TEGRA30 +#include "../cardhu/pinmux-config-common.h" +#endif
Not all Tegra30 will be Cardhu...
Given this is really board-specific, shouldn't the following be an empty weak definition:
+/*
- 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 +}
... and the function be overridden in board files as needed?
If we are moving to a model of a single function that sets up the entire pin mux at boot (which seems fine to me, and could eventually be driven by DT if it happened late enough), then it seems like we wouldn't need e.g. pin_mux_mmc() or pin_mux_usb() any more.
While the fdt may eventually remove this discussion, I don't think forcing a one-time pinmux init is the best idea. Some peripherals will not be needed on every boot (e.g. normally boot from eMMC unless USB is available). Some peripherals may want to change their config based on run-time settings (although this is unlikely I suppose, particularly if we have the fdt).
Regards, Simon
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Simon,
On Tue, Sep 18, 2012 at 12:53 PM, Simon Glass sjg@chromium.org wrote:
Hi,
On Thu, Sep 13, 2012 at 3:37 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/12/2012 04:10 PM, Tom Warren wrote:
Signed-off-by: Tom Warren twarren@nvidia.com
board/nvidia/common/board.c | 27 ++++++++++++++++++++++++++- 1 files changed, 26 insertions(+), 1 deletions(-)
Common code:-) :-) But ...
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
+#ifdef CONFIG_TEGRA30 +#include "../cardhu/pinmux-config-common.h" +#endif
Not all Tegra30 will be Cardhu...
Given this is really board-specific, shouldn't the following be an empty weak definition:
+/*
- 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 +}
... and the function be overridden in board files as needed?
If we are moving to a model of a single function that sets up the entire pin mux at boot (which seems fine to me, and could eventually be driven by DT if it happened late enough), then it seems like we wouldn't need e.g. pin_mux_mmc() or pin_mux_usb() any more.
While the fdt may eventually remove this discussion, I don't think forcing a one-time pinmux init is the best idea. Some peripherals will not be needed on every boot (e.g. normally boot from eMMC unless USB is available). Some peripherals may want to change their config based on run-time settings (although this is unlikely I suppose, particularly if we have the fdt).
I've been basically adapting our internal T30 U-Boot code to fit within the framework of what's upstream, including Allen's SPL reorg. Pinmux on our T30 codebase (including the Chromium U-Boot code, I believe) was done in a single monolithic file, as demonstrated in this patch. The advantages are that you can construct the table to ensure there are no conflicts, no small task with 4 options per mux and over 100 muxes. Even the HW power-on defaults have conflicts. The only exception in this patchset was the UART muxing, so we can start putting out debug/status spew to the console as early as possible.
As far as I'm aware, an FDT pinmux for Tegra (which is on my plate, but quite a bit behind T30) would be essentially the same deal - one large list of mux settings per build/board.
Also, we've had bugs submitted by the kernel guys at times because U-Boot didn't do _enough_ init. While I agree with the U-Boot philosophy of doing just what's necessary to get a kernel loaded, I don't consider pinmux init from a table as a time-consuming or code-intensive operation, and see no harm in leaving it in. The driver can always remap the muxes as it chooses at a later date, based on what it discovers or knows from its config or the DT.
Thanks,
Tom
Regards, Simon
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 09/18/2012 03:32 PM, Tom Warren wrote: ...
As far as I'm aware, an FDT pinmux for Tegra (which is on my plate, but quite a bit behind T30) would be essentially the same deal - one large list of mux settings per build/board.
Initializing pinmux from DT can work either way, depending on how the DT author wrote the DT file.
The pinmux DT node can contain a pinmux configuration which is applied as soon as the pinmux driver loads. This configuration can contain as little as you want (even nothing) all the way through to containing the entire board's static pinmux configuration.
For portions of the pinmux settings which the pinmux driver's own DT node doesn't configure (if any, based on the above), the relevant individual driver DT node can configure the pinmux as required, and that configuration would be applied when the relevant driver loads and parses its DT node.
In practice, so far, all the kernel board files for Tegra almost exclusively use static muxing in the pinmux controller's own DT node. However, there are a couple small dynamic cases (e.g. Seaboard/Springbank's pinctrl-based I2C mux for example).

This builds & boots to the command prompt on a Cardhu (T30) board. This is a barebones binary - no I2C, USB, MMC, SPI, etc. Drivers for those peripherals to follow.
Signed-off-by: Tom Warren twarren@nvidia.com --- Makefile | 23 +++++++++++++++++++++++ arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/start.S | 4 ++-- boards.cfg | 1 + drivers/gpio/tegra_gpio.c | 4 ++++ include/serial.h | 3 ++- spl/Makefile | 3 +++ 7 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/Makefile b/Makefile index d6d8ab2..13f4850 100644 --- a/Makefile +++ b/Makefile @@ -322,6 +322,9 @@ endif ifeq ($(SOC),tegra20) LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o endif +ifeq ($(SOC),tegra30) +LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o +endif
LIBS := $(addprefix $(obj),$(sort $(LIBS-y))) .PHONY : $(LIBS) @@ -389,6 +392,13 @@ else ALL-y += $(obj)u-boot-nodtb-tegra.bin endif endif +ifeq ($(SOC),tegra30) +ifeq ($(CONFIG_OF_SEPARATE),y) +ALL-y += $(obj)u-boot-dtb-tegra.bin +else +ALL-y += $(obj)u-boot-nodtb-tegra.bin +endif +endif
all: $(ALL-y) $(SUBDIR_EXAMPLES)
@@ -497,6 +507,19 @@ $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin rm $(obj)spl/u-boot-spl-pad.bin endif endif +ifeq ($(SOC),tegra30) +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 + cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin $(obj)u-boot.dtb > $@ + rm $(obj)spl/u-boot-spl-pad.bin +else +$(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin + $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_TEXT_BASE) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin + cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin > $@ + rm $(obj)spl/u-boot-spl-pad.bin +endif +endif
ifeq ($(CONFIG_SANDBOX),y) GEN_UBOOT = \ diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4fdbee4..6389d52 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_TEGRA20)$(CONFIG_TEGRA30),) SOBJS += lowlevel_init.o endif
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 32658eb..b2bac3e 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -280,14 +280,14 @@ jump_2_ram: /* * Move vector table */ -#if !defined(CONFIG_TEGRA20) +#if !defined(CONFIG_TEGRA) #if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) /* Set vector address in CP15 VBAR register */ ldr r0, =_start add r0, r0, r9 mcr p15, 0, r0, c12, c0, 0 @Set VBAR #endif -#endif /* !Tegra20 */ +#endif /* !Tegra20 or 30 */
ldr r0, _board_init_r_ofs adr r1, _start diff --git a/boards.cfg b/boards.cfg index 613d6b2..8da07ea 100644 --- a/boards.cfg +++ b/boards.cfg @@ -271,6 +271,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/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c index 747f4cf..6f6dceb 100644 --- a/drivers/gpio/tegra_gpio.c +++ b/drivers/gpio/tegra_gpio.c @@ -30,7 +30,11 @@ #include <common.h> #include <asm/io.h> #include <asm/bitops.h> +#if defined(CONFIG_TEGRA20) #include <asm/arch/tegra20.h> +#else /* Tegra30 */ +#include <asm/arch/tegra30.h> +#endif #include <asm/gpio.h>
enum { diff --git a/include/serial.h b/include/serial.h index cbdf8a9..acb13de 100644 --- a/include/serial.h +++ b/include/serial.h @@ -31,7 +31,8 @@ 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_TEGRA20) || defined(CONFIG_SYS_COREBOOT) || \ + defined(CONFIG_TEGRA30) extern struct serial_device serial0_device; extern struct serial_device serial1_device; #if defined(CONFIG_SYS_NS16550_SERIAL) diff --git a/spl/Makefile b/spl/Makefile index 476a5e6..a94d381 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -64,6 +64,9 @@ endif ifeq ($(SOC),tegra20) LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o endif +ifeq ($(SOC),tegra30) +LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o +endif
# Add GCC lib ifeq ("$(USE_PRIVATE_LIBGCC)", "yes")

On 09/12/2012 03:10 PM, Tom Warren wrote:
This builds & boots to the command prompt on a Cardhu (T30) board. This is a barebones binary - no I2C, USB, MMC, SPI, etc. Drivers for those peripherals to follow.
Signed-off-by: Tom Warren twarren@nvidia.com
[snip]
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),) +ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20)$(CONFIG_TEGRA30),)
[snip]
- defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT)
- defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT) || \
- defined(CONFIG_TEGRA30)
In both of these cases I think you should just switch to CONFIG_TEGRA rather than TEGRA20 || TEGRA30 and if TEGRA40 somehow invalidates this logic we can deal with it then but assume it won't.

Tom,
On Thu, Sep 13, 2012 at 11:00 AM, Tom Rini trini@ti.com wrote:
On 09/12/2012 03:10 PM, Tom Warren wrote:
This builds & boots to the command prompt on a Cardhu (T30) board. This is a barebones binary - no I2C, USB, MMC, SPI, etc. Drivers for those peripherals to follow.
Signed-off-by: Tom Warren twarren@nvidia.com
[snip]
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),) +ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20)$(CONFIG_TEGRA30),)
[snip]
defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT)
defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT) || \
defined(CONFIG_TEGRA30)
In both of these cases I think you should just switch to CONFIG_TEGRA rather than TEGRA20 || TEGRA30 and if TEGRA40 somehow invalidates this logic we can deal with it then but assume it won't.
Done, will be in V2. Thanks.
Tom
-- Tom

On 09/12/2012 04:10 PM, Tom Warren wrote:
This builds & boots to the command prompt on a Cardhu (T30) board. This is a barebones binary - no I2C, USB, MMC, SPI, etc. Drivers for those peripherals to follow.
diff --git a/Makefile b/Makefile
ifeq ($(SOC),tegra20) LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o endif +ifeq ($(SOC),tegra30) +LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o +endif
To avoid adding more and more copies of that assignment, how about:
ifneq ($(filter $(SOC),tegra20 tegra30),) LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o endif
The same trick can be applied to the other two changes in this file, and spl/Makefile.
Or perhaps you can just use:
ifneq ($(CONFIG_TEGRA),)
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
+#if defined(CONFIG_TEGRA20) #include <asm/arch/tegra20.h> +#else /* Tegra30 */ +#include <asm/arch/tegra30.h> +#endif
If that file got renamed to tegra.h in both places, you wouldn't need ifdefs around the include.

On 09/12/2012 04:10 PM, Tom Warren wrote:
This patch series adds basic (boot to cmd prompt) support for Tegra30. This is based on the Tegra20 SPL, which initializes the AVP (ARM7TDMI boot proc) first, then control is transferred to the CPU (A9 quad cluster). It is based on current u-boot-tegra/next.
Future patches will add support/drivers for MMC, USB, I2C, SPI, NAND, and other peripherals. The Cardhu T30 board is supported initially.
I tested this on my Cardhu. I did notice one bug - the fdt_load and fdt_high environment variables (from include/configs/tegra20-common-post.h before this patch-set at least) aren't updated with correct values for Tegra30.
I did try booting a kernel (after downloading it over serial) and that didn't work, but it's quite plausible that's as much a kernel issue as a U-Boot issue, so I won't worry about that for now.
I will have some comments on the other patches in the series.

On Wed, Sep 12, 2012 at 03:10:46PM -0700, Tom Warren wrote:
This patch series adds basic (boot to cmd prompt) support for Tegra30. This is based on the Tegra20 SPL, which initializes the AVP (ARM7TDMI boot proc) first, then control is transferred to the CPU (A9 quad cluster). It is based on current u-boot-tegra/next.
Future patches will add support/drivers for MMC, USB, I2C, SPI, NAND, and other peripherals. The Cardhu T30 board is supported initially.
Let me put my TI Custodian hat on and say, I've been where you are and I have some advice. Make a local branch (or 5) of your working but needs re-factoring and re-cleaning tree, and start fresh from u-boot-tegra/next. Move more tegra20 files to the tegra common area. Strip (#if 0) the "new" include files bare. Bring it up again. If you bring in the framework so we can have <plat/foo.h> (which is in turn arch/$(ARCH)/include/plat-vendor) I will be so happy you beat me to the punch and with something a bit more (IMHO) clean than how the kernel handles <plat/>. You're masking a way a lot of things that are either identical (which is duplication which is bad) or subtly different (and you haven't hit it, yet). However you migrate from the current tree to the new tree (I've done a lot of ugly steps when I've done this locally, but it keeps the board working from change to change), do it and do it sooner rather than later. You will thank yourself in the end.

Tom,
On Thu, Sep 13, 2012 at 2:04 PM, Tom Rini trini@ti.com wrote:
On Wed, Sep 12, 2012 at 03:10:46PM -0700, Tom Warren wrote:
This patch series adds basic (boot to cmd prompt) support for Tegra30. This is based on the Tegra20 SPL, which initializes the AVP (ARM7TDMI boot proc) first, then control is transferred to the CPU (A9 quad cluster). It is based on current u-boot-tegra/next.
Future patches will add support/drivers for MMC, USB, I2C, SPI, NAND, and other peripherals. The Cardhu T30 board is supported initially.
Let me put my TI Custodian hat on and say, I've been where you are and I have some advice. Make a local branch (or 5) of your working but needs re-factoring and re-cleaning tree, and start fresh from u-boot-tegra/next. Move more tegra20 files to the tegra common area. Strip (#if 0) the "new" include files bare. Bring it up again. If you bring in the framework so we can have <plat/foo.h> (which is in turn arch/$(ARCH)/include/plat-vendor) I will be so happy you beat me to the punch and with something a bit more (IMHO) clean than how the kernel handles <plat/>. You're masking a way a lot of things that are either identical (which is duplication which is bad) or subtly different (and you haven't hit it, yet). However you migrate from the current tree to the new tree (I've done a lot of ugly steps when I've done this locally, but it keeps the board working from change to change), do it and do it sooner rather than later. You will thank yourself in the end.
Seems like good advice. I'm off tomorrow, so I'll take a look at your approach on Monday and see how it works for me.
Thanks,
Tom
-- Tom
participants (6)
-
Lucas Stach
-
Marek Vasut
-
Simon Glass
-
Stephen Warren
-
Tom Rini
-
Tom Warren