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