diff options
author | Scott Williams <scwilliams@nvidia.com> | 2010-01-06 15:30:11 -0800 |
---|---|---|
committer | Scott Williams <scwilliams@nvidia.com> | 2010-01-06 16:44:49 -0800 |
commit | 243e05286721f9918b6968e84f8943673f0a5ea0 (patch) | |
tree | 9aa602939cac61915d30441842ebf3db6ea1a96f | |
parent | dbfedf55361225e34b53a29c979b1ef53e53c2db (diff) |
tegra: Refactored pin mux management
Refactor pin mux management in the Resource Manager (NVRM)
to facilitate different muxing strategies in future chips.
Bug 627809
Tested on Whistler (Aruba)
Change-Id: I4764229d5a07f7a8134a43708be375dcc23f5415
8 files changed, 937 insertions, 702 deletions
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/Makefile b/arch/arm/mach-tegra/nvrm/core/ap15/Makefile index 7649d0ef0f6e..34a7465bd6f9 100644 --- a/arch/arm/mach-tegra/nvrm/core/ap15/Makefile +++ b/arch/arm/mach-tegra/nvrm/core/ap15/Makefile @@ -17,6 +17,7 @@ obj-y += ap15rm_clocks.o obj-y += ap15rm_clock_config.o obj-y += ap15rm_clocks_info.o obj-y += nvrm_clocks.o +obj-y += ap15rm_pinmux.o obj-y += ap15rm_pinmux_tables.o obj-y += ap16rm_pinmux_tables.o obj-y += ap15rm_power.o diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_pinmux.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_pinmux.c new file mode 100644 index 000000000000..1729c98db64c --- /dev/null +++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_pinmux.c @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2009-2010 NVIDIA Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NVIDIA Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "nvcommon.h" +#include "nvrm_pinmux.h" +#include "nvrm_drf.h" +#include "nvassert.h" +#include "nvrm_hwintf.h" +#include "ap15/ap15rm_private.h" +#include "ap15/arapb_misc.h" +#include "nvrm_pinmux_utils.h" +#include "ap15/ap15rm_pinmux_utils.h" +#include "nvodm_query_pinmux.h" + +/* FindConfigStart searches through an array of configuration data to find the + * starting position of a particular configuration in a module instance array. + * The stop position is programmable, so that sub-routines can be placed after + * the last valid true configuration */ + +const NvU32* NvRmPrivAp15FindConfigStart( + const NvU32* Instance, + NvU32 Config, + NvU32 EndMarker) +{ + NvU32 Cnt = 0; + while ((Cnt < Config) && (*Instance!=EndMarker)) + { + switch (NV_DRF_VAL(MUX, ENTRY, STATE, *Instance)) + { + case PinMuxConfig_BranchLink: + case PinMuxConfig_OpcodeExtend: + if (*Instance==CONFIGEND()) + Cnt++; + Instance++; + break; + default: + Instance += NVRM_PINMUX_SET_OPCODE_SIZE; + break; + } + } + + /* Ugly postfix. In modules with bonafide subroutines, the last + * configuration CONFIGEND() will be followed by a MODULEDONE() + * token, with the first Set/Unset/Branch of the subroutine + * following that. To avoid leaving the "PC" pointing to a + * MODULEDONE() in the case where the first subroutine should be + * executed, fudge the "PC" up by one, to point to the subroutine. */ + if (EndMarker==SUBROUTINESDONE() && *Instance==MODULEDONE()) + Instance++; + + if (*Instance==EndMarker) + Instance = NULL; + + return Instance; +} + +/* NvRmSetPadTristates will increment/decrement the reference count for + * each pad group's global tristate value for each "ConfigSet" command in + * a pad group configuration, and update the register as needed */ +void NvRmPrivAp15SetPadTristates( + NvRmDeviceHandle hDevice, + const NvU32* Module, + NvU32 Config, + NvBool EnableTristate) +{ + int StackDepth = 0; + const NvU32 *Instance = NULL; + const NvU32 *ReturnStack[MAX_NESTING_DEPTH+1]; + + /* The re-multiplexing configuration is stored in program 0, + * along with the reset config. */ + if (Config==NVODM_QUERY_PINMAP_MULTIPLEXED) + Config = 0; + + Instance = NvRmPrivAp15FindConfigStart(Module, Config, MODULEDONE()); + /* The first stack return entry is NULL, so that when a ConfigEnd is + * encountered in the "main" configuration program, we pop off a NULL + * pointer, which causes the configuration loop to terminate. */ + ReturnStack[0] = NULL; + + /* This loop iterates over all of the pad groups that need to be updated, + * and updates the reference count for each appropriately. */ + + NvOsMutexLock(hDevice->mutex); + + while (Instance) + { + switch (NV_DRF_VAL(MUX,ENTRY, STATE, *Instance)) + { + case PinMuxConfig_OpcodeExtend: + /* Pop the most recent return address off of the return stack + * (which will be NULL if no values have been pushed onto the + * stack) */ + if (NV_DRF_VAL(MUX,ENTRY, OPCODE_EXTENSION, + *Instance)==PinMuxOpcode_ConfigEnd) + { + Instance = ReturnStack[StackDepth--]; + } + /* ModuleDone & SubroutinesDone should never be encountered + * during execution, for properly-formatted tables. */ + else + { + NV_ASSERT(0 && "Logical entry in table!\n"); + } + break; + case PinMuxConfig_BranchLink: + /* Push the next instruction onto the return stack if nesting space + is available, and jump to the target. */ + NV_ASSERT(StackDepth<MAX_NESTING_DEPTH); + ReturnStack[++StackDepth] = Instance+1; + Instance = NvRmPrivAp15FindConfigStart(Module, + NV_DRF_VAL(MUX,ENTRY,BRANCH_ADDRESS,*Instance), + SUBROUTINESDONE()); + NV_ASSERT(Instance && "Invalid branch configuration in table!\n"); + break; + case PinMuxConfig_Set: + { + NvS16 SkipUpdate; + NvU32 TsOffs = NV_DRF_VAL(MUX,ENTRY, TS_OFFSET, *Instance); + NvU32 TsShift = NV_DRF_VAL(MUX,ENTRY, TS_SHIFT, *Instance); + +/* abuse pre/post-increment, to ensure that skipUpdate is 0 when the + * register needs to be programmed (i.e., enabling and previous value was 0, + * or disabling and new value is 0). + */ + if (EnableTristate) +#if (SKIP_TRISTATE_REFCNT == 0) + SkipUpdate = --hDevice->TristateRefCount[TsOffs*32 + TsShift]; + else + SkipUpdate = hDevice->TristateRefCount[TsOffs*32 + TsShift]++; +#else + SkipUpdate = 1; + else + SkipUpdate = 0; +#endif + +#if (SKIP_TRISTATE_REFCNT == 0) + if (SkipUpdate < 0) + { + hDevice->TristateRefCount[TsOffs*32 + TsShift] = 0; + NV_DEBUG_PRINTF(("(%s:%s) Negative reference count detected " + "on TRISTATE_REG_%c_0, bit %u\n", + __FILE__, __LINE__, ('A'+(TsOffs)), TsShift)); + //NV_ASSERT(SkipUpdate>=0); + } +#endif + + if (!SkipUpdate) + { + NvU32 Curr = NV_REGR(hDevice, + NvRmModuleID_Misc, 0, + APB_MISC_PP_TRISTATE_REG_A_0 + 4*TsOffs); + Curr &= ~(1<<TsShift); +#if (SKIP_TRISTATE_REFCNT == 0) + Curr |= (EnableTristate?1:0)<<TsShift; +#endif + NV_REGW(hDevice, NvRmModuleID_Misc, 0, + APB_MISC_PP_TRISTATE_REG_A_0 + 4*TsOffs, Curr); + +#if NVRM_PINMUX_DEBUG_FLAG + NV_DEBUG_PRINTF(("Setting TRISTATE_REG_%s to %s\n", + (const char*)Instance[2], + (EnableTristate)?"TRISTATE" : "NORMAL")); +#endif + } + } + /* fall through. + * The "Unset" configurations are not applicable to tristate + * configuration, so skip over them. */ + case PinMuxConfig_Unset: + Instance += NVRM_PINMUX_SET_OPCODE_SIZE; + break; + } + } + NvOsMutexUnlock(hDevice->mutex); +} + +/* NvRmSetPinMuxCtl will apply new pin mux configurations to the pin mux + * control registers. */ +void NvRmPrivAp15SetPinMuxCtl( + NvRmDeviceHandle hDevice, + const NvU32* Module, + NvU32 Config) +{ + NvU32 MuxCtlOffset, MuxCtlShift, MuxCtlMask, MuxCtlSet, MuxCtlUnset; + const NvU32 *ReturnStack[MAX_NESTING_DEPTH+1]; + const NvU32 *Instance; + int StackDepth = 0; + NvU32 Curr; + + ReturnStack[0] = NULL; + Instance = Module; + + NvOsMutexLock(hDevice->mutex); + + /* The re-multiplexing configuration is stored in program 0, + * along with the reset config. */ + if (Config==NVODM_QUERY_PINMAP_MULTIPLEXED) + Config = 0; + + Instance = NvRmPrivAp15FindConfigStart(Module, Config, MODULEDONE()); + + // Apply the new configuration, setting / unsetting as appropriate + while (Instance) + { + switch (NV_DRF_VAL(MUX,ENTRY, STATE, *Instance)) + { + case PinMuxConfig_OpcodeExtend: + if (NV_DRF_VAL(MUX,ENTRY, OPCODE_EXTENSION, + *Instance)==PinMuxOpcode_ConfigEnd) + { + Instance = ReturnStack[StackDepth--]; + } + else + { + NV_ASSERT(0 && "Logical entry in table!\n"); + } + break; + case PinMuxConfig_BranchLink: + NV_ASSERT(StackDepth<MAX_NESTING_DEPTH); + ReturnStack[++StackDepth] = Instance+1; + Instance = NvRmPrivAp15FindConfigStart(Module, + NV_DRF_VAL(MUX,ENTRY,BRANCH_ADDRESS,*Instance), + SUBROUTINESDONE()); + NV_ASSERT(Instance && "Invalid branch configuration in table!\n"); + break; + default: + { + MuxCtlOffset = NV_DRF_VAL(MUX,ENTRY, MUX_CTL_OFFSET, *Instance); + MuxCtlShift = NV_DRF_VAL(MUX,ENTRY, MUX_CTL_SHIFT, *Instance); + MuxCtlUnset = NV_DRF_VAL(MUX,ENTRY, MUX_CTL_UNSET, *Instance); + MuxCtlSet = NV_DRF_VAL(MUX,ENTRY, MUX_CTL_SET, *Instance); + MuxCtlMask = NV_DRF_VAL(MUX, ENTRY, MUX_CTL_MASK, *Instance); + + Curr = NV_REGR(hDevice, NvRmModuleID_Misc, 0, + APB_MISC_PP_PIN_MUX_CTL_A_0 + 4*MuxCtlOffset); + + if (NV_DRF_VAL(MUX,ENTRY,STATE,*Instance)==PinMuxConfig_Set) + { + Curr &= ~(MuxCtlMask<<MuxCtlShift); + Curr |= (MuxCtlSet<<MuxCtlShift); +#if NVRM_PINMUX_DEBUG_FLAG + NV_DEBUG_PRINTF(("Configuring PINMUX_CTL_%s\n", + (const char *)Instance[1])); +#endif + + } + else if (((Curr>>MuxCtlShift)&MuxCtlMask)==MuxCtlUnset) + { + NV_ASSERT(NV_DRF_VAL(MUX,ENTRY,STATE, + *Instance)==PinMuxConfig_Unset); + Curr &= ~(MuxCtlMask<<MuxCtlShift); + Curr |= (MuxCtlSet<<MuxCtlShift); +#if NVRM_PINMUX_DEBUG_FLAG + NV_DEBUG_PRINTF(("Unconfiguring PINMUX_CTL_%s\n", + (const char *)Instance[1])); +#endif + } + + NV_REGW(hDevice, NvRmModuleID_Misc, 0, + APB_MISC_PP_PIN_MUX_CTL_A_0 + 4*MuxCtlOffset, Curr); + Instance += NVRM_PINMUX_SET_OPCODE_SIZE; + break; + } + } + } + NvOsMutexUnlock(hDevice->mutex); +} + +void NvRmPrivAp15InitTrisateRefCount(NvRmDeviceHandle hDevice) +{ + NvU32 i, j, curr; + + NvOsMutexLock(hDevice->mutex); + NvOsMemset(hDevice->TristateRefCount, 0, + sizeof(hDevice->TristateRefCount)); + + for (i=0; i<=((APB_MISC_PP_TRISTATE_REG_D_0- + APB_MISC_PP_TRISTATE_REG_A_0)>>2); i++) + { + curr = NV_REGR(hDevice, NvRmModuleID_Misc, 0, + APB_MISC_PP_TRISTATE_REG_A_0 + 4*i); + // swap from 0=normal, 1=tristate to 0=tristate, 1=normal + curr = ~curr; + for (j=0; curr; j++, curr>>=1) + { + /* the oppositely-named tristate reference count keeps track + * of the number of active users of each pad group, and + * enables tristate when the count reaches zero. */ + hDevice->TristateRefCount[i*32 + j] = (NvS16)(curr & 0x1); + } + } + NvOsMutexUnlock(hDevice->mutex); +} + +void NvRmPrivAp15SetGpioTristate( + NvRmDeviceHandle hDevice, + NvU32 Port, + NvU32 Pin, + NvBool EnableTristate) +{ + NvU32 Mapping = 0; + NvS16 SkipUpdate; + NvBool ret = NV_FALSE; + + NV_ASSERT(hDevice); + + switch (hDevice->ChipId.Id) + { + case 0x15: + case 0x16: + ret = NvRmAp15GetPinGroupForGpio(hDevice, Port, Pin, &Mapping); + break; + case 0x20: + ret = NvRmAp20GetPinGroupForGpio(hDevice, Port, Pin, &Mapping); + break; + default: + NV_ASSERT(!"Chip ID not supported"); + return; + } + + if (ret) + { + NvU32 TsOffs = NV_DRF_VAL(MUX, GPIOMAP, TS_OFFSET, Mapping); + NvU32 TsShift = NV_DRF_VAL(MUX, GPIOMAP, TS_SHIFT, Mapping); + + NvOsMutexLock(hDevice->mutex); + + if (EnableTristate) +#if (SKIP_TRISTATE_REFCNT == 0) + SkipUpdate = --hDevice->TristateRefCount[TsOffs*32 + TsShift]; + else + SkipUpdate = hDevice->TristateRefCount[TsOffs*32 + TsShift]++; +#else + SkipUpdate = 1; + else + SkipUpdate = 0; +#endif + +#if (SKIP_TRISTATE_REFCNT == 0) + if (SkipUpdate < 0) + { + hDevice->TristateRefCount[TsOffs*32 + TsShift] = 0; + NV_DEBUG_PRINTF(("(%s:%s) Negative reference count detected on " + "TRISTATE_REG_%c_0, bit %u\n", __FILE__, __LINE__, + ('A'+(TsOffs)), TsShift)); + //NV_ASSERT(SkipUpdate>=0); + } +#endif + + if (!SkipUpdate) + { + NvU32 Curr = NV_REGR(hDevice, + NvRmModuleID_Misc, 0, + APB_MISC_PP_TRISTATE_REG_A_0 + 4*TsOffs); + Curr &= ~(1<<TsShift); +#if (SKIP_TRISTATE_REFCNT == 0) + Curr |= (EnableTristate?1:0)<<TsShift; +#endif + NV_REGW(hDevice, NvRmModuleID_Misc, 0, + APB_MISC_PP_TRISTATE_REG_A_0 + 4*TsOffs, Curr); + } + + NvOsMutexUnlock(hDevice->mutex); + } +} + diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_pinmux_tables.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_pinmux_tables.c index 7367ed143c8f..cb9e81566ecb 100644 --- a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_pinmux_tables.c +++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_pinmux_tables.c @@ -38,7 +38,7 @@ #include "ap15rm_private.h" #include "ap15/arapb_misc.h" #include "ap15/arclk_rst.h" -#include "nvrm_pinmux_utils.h" +#include "ap15rm_pinmux_utils.h" #include "nvodm_query_pinmux.h" #include "nvrm_clocks.h" @@ -85,7 +85,7 @@ * multiple pad groups. */ - const NvU32 g_Ap15MuxI2c1[] = { +const NvU32 g_Ap15MuxI2c1[] = { // Reset config -- disown GEN1_I2C pads UNCONFIG(A, RM,I2C, RSVD1), CONFIGEND(), // I2C1, Config 1 (GEN1_I2C pads) @@ -118,34 +118,38 @@ const NvU32 g_Ap15MuxI2c2[] = { MODULEDONE() }; - const NvU32* g_Ap15MuxI2c[] = { +const NvU32* g_Ap15MuxI2c[] = { &g_Ap15MuxI2c1[0], &g_Ap15MuxI2c2[0], NULL }; - const NvU32 g_Ap15MuxI2c_Pmu[] = { + +const NvU32 g_Ap15MuxI2c_Pmu[] = { // Reset config -- disown I2CP pads UNCONFIG(C,I2CP,I2C, RSVD2), CONFIGEND(), // I2CP pads CONFIG(A,C,I2CP,I2C), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxI2cPmu[] = { + +const NvU32* g_Ap15MuxI2cPmu[] = { &g_Ap15MuxI2c_Pmu[0], NULL }; - const NvU32 g_Ap15Mux_Mmc[] = { - CONFIGEND(), // no pad groups reset to MMC, so nothing to disown for reset config +const NvU32 g_Ap15Mux_Mmc[] = { + CONFIGEND(), // no pad groups reset to MMC, so nothing to disown for reset config CONFIG(A,A,ATB,HSMMC), CONFIG(A,A,ATD,HSMMC), CONFIG(B,A,ATE,HSMMC), CONFIGEND(), - CONFIG(A,A,ATB,HSMMC),CONFIG(A,A,ATD,HSMMC),CONFIGEND(), + CONFIG(A,A,ATB,HSMMC),CONFIG(A,A,ATD,HSMMC),CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxMmc[] = { + +const NvU32* g_Ap15MuxMmc[] = { &g_Ap15Mux_Mmc[0], NULL }; - const NvU32 g_Ap15MuxSdio2[] = { + +const NvU32 g_Ap15MuxSdio2[] = { // Reset config - abandon SDB, SLXK,SLXA,SLXB,SLXC,SLXD .chosen RSVD,SLINK4B UNCONFIG(D,SDB,SDIO2,RSVD), UNCONFIG(B,SLXK,SDIO1,SLINK4B), UNCONFIG(B,SLXB,SDIO1,SLINK4B), UNCONFIG(B,SLXC,SDIO1,SLINK4B),UNCONFIG(B,SLXD,SDIO1,SLINK4B),UNCONFIG(B,SLXA,SDIO1,SLINK4B), @@ -165,8 +169,8 @@ const NvU32 g_Ap15MuxI2c2[] = { MODULEDONE() }; - const NvU32 g_Ap15MuxSdio3[] = { - // no pad groups reset to SDIO3, so nothing to disown for reset config +const NvU32 g_Ap15MuxSdio3[] = { + // no pad groups reset to SDIO3, so nothing to disown for reset config CONFIGEND(), // config1 SDD + SDC+SLXK+SLXA+SLXB pads CONFIG(B,D,SDD,SDIO2), CONFIG(B,D,SDC,SDIO2), CONFIG(B,D,SDB,SDIO2_ALT), @@ -176,13 +180,13 @@ const NvU32 g_Ap15MuxI2c2[] = { MODULEDONE() }; - const NvU32* g_Ap15MuxSdio[] = { +const NvU32* g_Ap15MuxSdio[] = { &g_Ap15MuxSdio2[0], &g_Ap15MuxSdio3[0], NULL }; - const NvU32 g_Ap15Mux_Spdif[] = { +const NvU32 g_Ap15Mux_Spdif[] = { // Reset config - abandon SPDO, SPDI .chosen RSVD. UNCONFIG(D,SPDO,SPDIF,RSVD), UNCONFIG(D,SPDI,SPDIF,RSVD),CONFIGEND(), // config1 SPDO+ SPDI pads @@ -194,10 +198,11 @@ const NvU32 g_Ap15MuxI2c2[] = { MODULEDONE() }; - const NvU32* g_Ap15MuxSpdif[] = { +const NvU32* g_Ap15MuxSpdif[] = { &g_Ap15Mux_Spdif[0], NULL }; + static const NvU32 g_Ap15MuxUart1[] = { // Reset config - abandon IRRX, IRTX & SDD UNCONFIG(C,IRRX,UARTA,RSVD2), UNCONFIG(C,IRTX,UARTA,RSVD2), UNCONFIG(D,SDD,UARTA,PWM), CONFIGEND(), @@ -215,6 +220,7 @@ static const NvU32 g_Ap15MuxUart1[] = { CONFIG(B,D,SDD,UARTA), CONFIGEND(), MODULEDONE() }; + static const NvU32 g_Ap15MuxUart2[] = { // Reset config - abandon UAD. pads.chosen SFLASH pads UNCONFIG(A,UAD,IRDA,SFLASH), CONFIGEND(), @@ -243,9 +249,10 @@ static const NvU32* g_Ap15MuxUart[] = { &g_Ap15MuxUart3[0], NULL }; - const NvU32 g_Ap15MuxSpi1[] = { + +const NvU32 g_Ap15MuxSpi1[] = { // Reset config - abandon SPIC, SPIB, SPIA, pads. - UNCONFIG(D,SPIC,SPI1,RSVD), UNCONFIG(D,SPIB,SPI1,RSVD), + UNCONFIG(D,SPIC,SPI1,RSVD), UNCONFIG(D,SPIB,SPI1,RSVD), UNCONFIG(D,SPIA,SPI1,RSVD), CONFIGEND(), // SPIE,SPIF,SPID pads CONFIG(B,D,SPIE,SPI1),CONFIG(B,D,SPIF,SPI1),CONFIG(B,D,SPID,SPI1), CONFIGEND(), @@ -259,7 +266,7 @@ static const NvU32* g_Ap15MuxUart[] = { MODULEDONE() }; - const NvU32 g_Ap15MuxSpi2[] = { +const NvU32 g_Ap15MuxSpi2[] = { // Reset config - abandon UAB, pads. MIPI_HS chosen UNCONFIG(A,UAB,SPI2,MIPI_HS), UNCONFIG(D,SPID,SPI2,RSVD), UNCONFIG(D,SPIE,SPI2,RSVD), CONFIGEND(), @@ -282,12 +289,12 @@ static const NvU32* g_Ap15MuxUart[] = { * state, so it is implemented at the end of the list using UNCONFIG * options, so that no pad groups are trying to use SPI3. */ - const NvU32 g_Ap15MuxSpi3[] = { +const NvU32 g_Ap15MuxSpi3[] = { /* Reset config - abandon UAA, SPIF, SPIG, SPIH pads. SPI2_ALT chosen * as the reset state for SPIG/SPIH, since this will either be clobbered * by Spi2 SpiPinMap_Config1, I2c1 I2cPinMap_Config3, correct (for Spi2 * SpiPinMap_Config3), or irrelevant */ - UNCONFIG(A,UAA,SPI3,MIPI_HS), UNCONFIG(D,SPIF,SPI3,RSVD), + UNCONFIG(A,UAA,SPI3,MIPI_HS), UNCONFIG(D,SPIF,SPI3,RSVD), UNCONFIG(D,SPIG,SPI3,SPI2_ALT), UNCONFIG(D,SPIH,SPI3,SPI2_ALT), // multiplex unconfiguration UNCONFIG(C,XM2A,SPI3,SPROM), // multiplex config 1 to SPROM @@ -313,7 +320,7 @@ static const NvU32* g_Ap15MuxUart[] = { MODULEDONE() }; - const NvU32* g_Ap15MuxSpi[] = { +const NvU32* g_Ap15MuxSpi[] = { &g_Ap15MuxSpi1[0], &g_Ap15MuxSpi2[0], &g_Ap15MuxSpi3[0], @@ -347,14 +354,14 @@ const NvU32 g_Ap15Mux_Sflash[] = { MODULEDONE() }; - const NvU32* g_Ap15MuxSflash[] = { +const NvU32* g_Ap15MuxSflash[] = { &g_Ap15Mux_Sflash[0], NULL }; - const NvU32 g_Ap15Mux_Twc[] = { - // no pad groups reset to TWC, so nothing to disown for reset config +const NvU32 g_Ap15Mux_Twc[] = { + // no pad groups reset to TWC, so nothing to disown for reset config CONFIGEND(), // DAP2 pads CONFIG(A,C,DAP2,TWC), CONFIGEND(), @@ -362,12 +369,13 @@ const NvU32 g_Ap15Mux_Sflash[] = { CONFIG(B,D,SDC,TWC), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxTwc[] = { + +const NvU32* g_Ap15MuxTwc[] = { &g_Ap15Mux_Twc[0], NULL }; - const NvU32 g_Ap15Mux_Ata[] = { +const NvU32 g_Ap15Mux_Ata[] = { // Reset config -- abandon ATA, ATC, ATB, ATD, ATE pads. NAND RSVD as chosenpads UNCONFIG(A,ATC,IDE,RSVD), UNCONFIG(A,ATD,IDE,NAND), UNCONFIG(A,ATE,IDE,NAND), UNCONFIG(A,ATA,IDE,RSVD), UNCONFIG(A,ATB,IDE,NAND), CONFIGEND(), @@ -376,41 +384,43 @@ const NvU32 g_Ap15Mux_Sflash[] = { CONFIG(A,A,ATB,IDE), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxAta[] = { + +const NvU32* g_Ap15MuxAta[] = { &g_Ap15Mux_Ata[0], NULL }; - const NvU32 g_Ap15Mux_Pwm[] = { +const NvU32 g_Ap15Mux_Pwm[] = { // Reset config -- disown SDC,UCB pads SDIO2, RSVD2 as chosen pads UNCONFIG(D,SDC,PWM,SDIO2), UNCONFIG(B,UCB,PWM0,RSVD2), CONFIGEND(), // PWM, Config 1 (SDC pads) CONFIG(B,D,SDC,PWM), CONFIGEND(), // PWM, Config 2 (UCB ,SDDpads) CONFIG(B,B,UCB,PWM0), CONFIG(B,D,SDD,PWM), CONFIGEND(), - // PWM, Config 2 (UCB ,SDDpads) + // PWM, Config 2 (UCB ,SDDpads) CONFIG(B,B,UCB,PWM0), CONFIGEND(), CONFIG(B,D,SDD,PWM), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxPwm[] = { + +const NvU32* g_Ap15MuxPwm[] = { &g_Ap15Mux_Pwm[0], NULL }; - const NvU32 g_Ap15Mux_Hsi[] = { - CONFIGEND(), // no pad groups reset to HSI, so nothing to disown for reset config - CONFIG(B,A,UAA,MIPI_HS), CONFIG(B,A,UAB,MIPI_HS), CONFIGEND(), +const NvU32 g_Ap15Mux_Hsi[] = { + CONFIGEND(), // no pad groups reset to HSI, so nothing to disown for reset config + CONFIG(B,A,UAA,MIPI_HS), CONFIG(B,A,UAB,MIPI_HS), CONFIGEND(), MODULEDONE() }; - const NvU32 *g_Ap15MuxHsi[] = { +const NvU32 *g_Ap15MuxHsi[] = { &g_Ap15Mux_Hsi[0], NULL }; - const NvU32 g_Ap15Mux_Nand[] = { - CONFIGEND(), // no pad groups reset to NAND, so nothing to disown for reset config +const NvU32 g_Ap15Mux_Nand[] = { + CONFIGEND(), // no pad groups reset to NAND, so nothing to disown for reset config // config 1 ATA,ATB,ATC,ATD,ATE pads CONFIG(A,A,ATA,NAND_ALT), CONFIG(A,A,ATB,NAND_ALT), CONFIG(A,A,ATC,NAND), CONFIG(A,A,ATD,NAND), CONFIG(B,A,ATE,NAND), CONFIGEND(), @@ -430,19 +440,21 @@ const NvU32 g_Ap15Mux_Sflash[] = { CONFIG(A,A,ATC,NAND), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxNand[] = { + +const NvU32* g_Ap15MuxNand[] = { &g_Ap15Mux_Nand[0], NULL }; - const NvU32 g_Ap15MuxDap1[] = { +const NvU32 g_Ap15MuxDap1[] = { // Reset config - abandon ,DAP1.. RSVD2 chosen UNCONFIG(C,DAP1,DAP1,RSVD2), CONFIGEND(), // config1 DAP1 pads CONFIG(A,C,DAP1,DAP1), CONFIGEND(), MODULEDONE() }; - const NvU32 g_Ap15MuxDap2[] = { + +const NvU32 g_Ap15MuxDap2[] = { // Reset config - abandon ,DAP2... RSVD3 chosen UNCONFIG(C,DAP2,DAP2,RSVD3), CONFIGEND(), // config1 DAP2 pads @@ -450,21 +462,24 @@ const NvU32 g_Ap15Mux_Sflash[] = { // congig 2 SLXD, SLXC pads MODULEDONE() }; - const NvU32 g_Ap15MuxDap3[] = { + +const NvU32 g_Ap15MuxDap3[] = { // Reset config - abandon ,DAP3... RSVD2 chosen UNCONFIG(C,DAP3,DAP3,RSVD2), CONFIGEND(), // config1 DAP3 pads CONFIG(A,C,DAP3,DAP3), CONFIGEND(), MODULEDONE() }; - const NvU32 g_Ap15MuxDap4[] = { + +const NvU32 g_Ap15MuxDap4[] = { // Reset config - abandon ,DAP4...RSVD2 chosen UNCONFIG(C,DAP4,DAP4,RSVD2), CONFIGEND(), // config1 DAP4 pads CONFIG(A,C,DAP4,DAP4), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxDap[] = { + +const NvU32* g_Ap15MuxDap[] = { &g_Ap15MuxDap1[0], &g_Ap15MuxDap2[0], &g_Ap15MuxDap3[0], @@ -472,15 +487,15 @@ const NvU32 g_Ap15Mux_Sflash[] = { NULL }; - const NvU32 g_Ap15Mux_Kbc[] = { +const NvU32 g_Ap15Mux_Kbc[] = { // Reset config - abandon ,RSVD2, RSVD1 chosen - UNCONFIG(C,KBCA,KBC,RSVD2), UNCONFIG(C,KBCB,KBC,RSVD2), UNCONFIG(A,KBCE,KBC,RSVD1), + UNCONFIG(C,KBCA,KBC,RSVD2), UNCONFIG(C,KBCB,KBC,RSVD2), UNCONFIG(A,KBCE,KBC,RSVD1), UNCONFIG(C,KBCC,KBC,RSVD2), UNCONFIG(G,KBCD,KBC,RSVD2), UNCONFIG(A,KBCF,KBC,RSVD1), CONFIGEND(), // KBCA,KBCB,KBCC,KBCD,KBCE,KBCF pads - CONFIG(A,C,KBCA,KBC), CONFIG(A,C,KBCB,KBC), CONFIG(A,A,KBCE,KBC), + CONFIG(A,C,KBCA,KBC), CONFIG(A,C,KBCB,KBC), CONFIG(A,A,KBCE,KBC), CONFIG(B,C,KBCC,KBC), CONFIG(D,G,KBCD,KBC), CONFIG(A,A,KBCF,KBC), CONFIGEND(), // KBCA,KBCC,KBCD,KBCE,KBCF pads - CONFIG(A,C,KBCA,KBC), CONFIG(A,A,KBCE,KBC), + CONFIG(A,C,KBCA,KBC), CONFIG(A,A,KBCE,KBC), CONFIG(B,C,KBCC,KBC), CONFIG(D,G,KBCD,KBC), CONFIG(A,A,KBCF,KBC), CONFIGEND(), // KBCA,KBCC,KBCF, pads CONFIG(A,C,KBCA,KBC), CONFIG(B,C,KBCC,KBC), CONFIG(A,A,KBCF,KBC), CONFIGEND(), @@ -488,75 +503,80 @@ const NvU32 g_Ap15Mux_Sflash[] = { CONFIG(A,C,KBCA,KBC), CONFIG(B,C,KBCC,KBC), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxKbc[] = { + +const NvU32* g_Ap15MuxKbc[] = { &g_Ap15Mux_Kbc[0], NULL }; - NvU32 g_Ap15Mux_Hdcp[] = { - CONFIGEND(), // no pad groups reset to HDCP, so nothing to disown for reset config - CONFIG(A,G,PTA,HDMI), CONFIGEND(), + +NvU32 g_Ap15Mux_Hdcp[] = { + CONFIGEND(), // no pad groups reset to HDCP, so nothing to disown for reset config + CONFIG(A,G,PTA,HDMI), CONFIGEND(), CONFIG(C,E,LSCK,HDMI), CONFIG(D,E,LSDA,HDMI), CONFIGEND(), CONFIG(D,E,LPW2,HDMI), CONFIG(D,E,LPW0,HDMI), CONFIGEND(), CONFIG(C,E,LSC1,HDMI), CONFIG(D,E,LPW0,HDMI), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxHdcp[] = { + +const NvU32* g_Ap15MuxHdcp[] = { &g_Ap15Mux_Hdcp[0], NULL }; - const NvU32 g_Ap15Mux_Hdmi[] = { +const NvU32 g_Ap15Mux_Hdmi[] = { // HDINT resets to HDINT, so move it to a reserved pin UNCONFIG(B,HDINT,RSVD1,RSVD2), CONFIGEND(), CONFIG(C,B,HDINT,RSVD1), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxHdmi[] = { +const NvU32* g_Ap15MuxHdmi[] = { &g_Ap15Mux_Hdmi[0], NULL }; - const NvU32 g_Ap15Mux_Mio[] = { - CONFIGEND(), // no pad groups reset to MIO, so nothing to disown for reset config +const NvU32 g_Ap15Mux_Mio[] = { + CONFIGEND(), // no pad groups reset to MIO, so nothing to disown for reset config CONFIG(A,A,KBCF,MIO), CONFIG(D,G,KBCD,MIO), CONFIG(A,C,KBCB,MIO), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxMio[] = { + +const NvU32* g_Ap15MuxMio[] = { &g_Ap15Mux_Mio[0], NULL }; - const NvU32 g_Ap15Mux_Slink[] = { - CONFIGEND(), // no pad groups reset to SLINK, so nothing to disown for reset config +const NvU32 g_Ap15Mux_Slink[] = { + CONFIGEND(), // no pad groups reset to SLINK, so nothing to disown for reset config CONFIG(B,B,SLXK,SLINK4B), CONFIG(B,B,SLXA,SLINK4B), CONFIG(B,B,SLXB,SLINK4B), - CONFIG(B,B,SLXC,SLINK4B), CONFIG(B,B,SLXD,SLINK4B), CONFIGEND(), + CONFIG(B,B,SLXC,SLINK4B), CONFIG(B,B,SLXD,SLINK4B), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxSlink[] = { + +const NvU32* g_Ap15MuxSlink[] = { &g_Ap15Mux_Slink[0], NULL }; - const NvU32 g_Ap15Mux_Vi[] = { - CONFIGEND(), // no pad groups reset to VI so nothing to disown for reset config +const NvU32 g_Ap15Mux_Vi[] = { + CONFIGEND(), // no pad groups reset to VI so nothing to disown for reset config // config 1 DTA - DTF pads BRANCH(NvOdmVideoInputPinMap_Config2), CONFIG(D,G,DTF,VI), CONFIGEND(), // config 2 DTA - DTE and CSUS pads CONFIG(A,B,DTA,VI), CONFIG(A,B,DTB,VI), CONFIG(A,B,DTC,VI), - CONFIG(A,B,DTD,VI), CONFIG(A,B,DTE,VI), CONFIGEND(), + CONFIG(A,B,DTD,VI), CONFIG(A,B,DTE,VI), CONFIGEND(), MODULEDONE(), SUBROUTINESDONE(), }; - const NvU32* g_Ap15MuxVi[] = { +const NvU32* g_Ap15MuxVi[] = { &g_Ap15Mux_Vi[0], NULL }; - const NvU32 g_Ap15Mux_Crt[] = { +const NvU32 g_Ap15Mux_Crt[] = { // Need to confirm and fix it ,but none of docs specifies about tv pad group - CONFIGEND(), // no pad groups reset to CRT so nothing to disown for reset config + CONFIGEND(), // no pad groups reset to CRT so nothing to disown for reset config // config 1 LHS, LVS, pads CONFIG(D,E,LHS,CRT), CONFIG(C,E,LVS,CRT), CONFIGEND(), // config 2 LHP2,LPW1 pads @@ -674,7 +694,7 @@ const NvU32 g_Ap15Mux_Display1[] = { CONFIG(C,E,LCSN,DISPLAYA), CONFIG(C,E,LM1,DISPLAYA),CONFIG(C,E,LM0,DISPLAYA), CONFIG(D,E,LPW0,DISPLAYA),CONFIG(D,E,LPW2,DISPLAYA), CONFIG(D,E,LPW1,DISPLAYA), CONFIG(C,E,LVP0,DISPLAYA), CONFIG(C,E,LDC,DISPLAYA), CONFIG(C,E,LSC1,DISPLAYA), - CONFIG(D,E,LSDI,DISPLAYA), + CONFIG(D,E,LSDI,DISPLAYA), */ }; @@ -714,13 +734,13 @@ const NvU32 g_Ap15Mux_Display2[] = { SUBROUTINESDONE(), }; - const NvU32* g_Ap15MuxDisplay[] = { +const NvU32* g_Ap15MuxDisplay[] = { &g_Ap15Mux_Display1[0], &g_Ap15Mux_Display2[0], NULL }; - const NvU32 g_Ap15Mux_Cdev1[] = { +const NvU32 g_Ap15Mux_Cdev1[] = { // reset config - no-op CONFIGEND(), CONFIG(A,C,CDEV1,PLLA_OUT), CONFIGEND(), @@ -728,20 +748,20 @@ const NvU32 g_Ap15Mux_Display2[] = { MODULEDONE() }; - const NvU32 g_Ap15Mux_Cdev2[] = { +const NvU32 g_Ap15Mux_Cdev2[] = { CONFIGEND(), CONFIG(A,C,CDEV2,AHB_CLK), CONFIGEND(), CONFIG(A,C,CDEV2,OSC), CONFIGEND(), MODULEDONE() }; - const NvU32 g_Ap15Mux_Csus[] = { +const NvU32 g_Ap15Mux_Csus[] = { CONFIGEND(), CONFIG(A,C,CSUS,VI_SENSOR_CLK), CONFIGEND(), MODULEDONE() }; - const NvU32* g_Ap15MuxCdev[] = +const NvU32* g_Ap15MuxCdev[] = { &g_Ap15Mux_Cdev1[0], &g_Ap15Mux_Cdev2[0], @@ -802,7 +822,6 @@ NvRmAp15GetPinMuxConfigs(NvRmDeviceHandle hDevice) return (const NvU32***) g_Ap15MuxControllers; } - /* Define the GPIO port/pin to tristate mappings */ const NvU16 g_Ap15GpioPadGroupMapping[] = @@ -956,7 +975,7 @@ NvRmPrivAp15GetExternalClockSourceFreq( { if (MuxCtlSet == APB_MISC_PP_PIN_MUX_CTL_C_0_CDEV1_SEL_PLLA_OUT) ClockFreqInKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllA0); - + else if (MuxCtlSet == APB_MISC_PP_PIN_MUX_CTL_C_0_CDEV1_SEL_OSC) ClockFreqInKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_ClkM); } @@ -964,7 +983,7 @@ NvRmPrivAp15GetExternalClockSourceFreq( { if (MuxCtlSet == APB_MISC_PP_PIN_MUX_CTL_C_0_CDEV2_SEL_AHB_CLK) ClockFreqInKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_Ahb); - + else if (MuxCtlSet == APB_MISC_PP_PIN_MUX_CTL_C_0_CDEV2_SEL_OSC) ClockFreqInKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_ClkM); } @@ -999,7 +1018,7 @@ NvBool NvRmPrivAp15RmModuleToOdmModule( { case NvRmPrivModuleID_Mio_Exio: *OdmModule = NvOdmIoModule_Mio; - *OdmInstance = 0; // since there is only one MIO bus on AP15/AP16. + *OdmInstance = 0; // since there is only one MIO bus on AP15/AP16. *pCnt = 1; return NV_TRUE; default: @@ -1020,130 +1039,129 @@ NvRmPrivAp15GetModuleInterfaceCaps( switch (Module) { - case NvOdmIoModule_Sdio: - { - NvRmModuleSdmmcInterfaceCaps *pSdmmcCaps = - (NvRmModuleSdmmcInterfaceCaps *)pCaps; - if (Instance==0 && - (PinMap == NvOdmSdioPinMap_Config2 || - PinMap == NvOdmSdioPinMap_Config5)) - pSdmmcCaps->MmcInterfaceWidth = 8; - else if (Instance==1 && PinMap==NvOdmSdioPinMap_Config1) - pSdmmcCaps->MmcInterfaceWidth = 8; - else - pSdmmcCaps->MmcInterfaceWidth = 4; - err = NvSuccess; - break; - } - case NvOdmIoModule_Hsmmc: - { - NvRmModuleSdmmcInterfaceCaps *pSdmmcCaps = - (NvRmModuleSdmmcInterfaceCaps *)pCaps; - if (Instance==0 && PinMap==NvOdmHsmmcPinMap_Config2) - pSdmmcCaps->MmcInterfaceWidth = 4; - else - pSdmmcCaps->MmcInterfaceWidth = 8; - err = NvSuccess; - break; - } - case NvOdmIoModule_Pwm: - { - NvRmModulePwmInterfaceCaps *pPwmCaps = - (NvRmModulePwmInterfaceCaps *)pCaps; - err = NvSuccess; - if (Instance == 0 && (PinMap == NvOdmPwmPinMap_Config1)) - pPwmCaps->PwmOutputIdSupported = 15; - else if (Instance == 0 && (PinMap == NvOdmPwmPinMap_Config2)) - pPwmCaps->PwmOutputIdSupported = 13; - else if (Instance == 0 && (PinMap == NvOdmPwmPinMap_Config3)) - pPwmCaps->PwmOutputIdSupported = 1; - else if (Instance == 0 && (PinMap == NvOdmPwmPinMap_Config4)) - pPwmCaps->PwmOutputIdSupported = 12; - else + case NvOdmIoModule_Sdio: { - pPwmCaps->PwmOutputIdSupported = 0; - err = NvError_NotSupported; - } - break; - } - case NvOdmIoModule_Nand: - { - NvRmModuleNandInterfaceCaps *pNandCaps = - (NvRmModuleNandInterfaceCaps *)pCaps; - if (Instance == 0) - { - pNandCaps->IsCombRbsyMode = NV_TRUE; - pNandCaps->NandInterfaceWidth = 8; - - if (PinMap == NvOdmNandPinMap_Config4) - pNandCaps->IsCombRbsyMode = NV_FALSE; - - if ((PinMap == NvOdmNandPinMap_Config1) || - (PinMap == NvOdmNandPinMap_Config2)) - pNandCaps->NandInterfaceWidth = 16; - - err = NvSuccess; - } - else - { - NV_ASSERT(NV_FALSE); - err = NvError_NotSupported; + NvRmModuleSdmmcInterfaceCaps *pSdmmcCaps = + (NvRmModuleSdmmcInterfaceCaps *)pCaps; + if (Instance==0 && + (PinMap == NvOdmSdioPinMap_Config2 || + PinMap == NvOdmSdioPinMap_Config5)) + pSdmmcCaps->MmcInterfaceWidth = 8; + else if (Instance==1 && PinMap==NvOdmSdioPinMap_Config1) + pSdmmcCaps->MmcInterfaceWidth = 8; + else + pSdmmcCaps->MmcInterfaceWidth = 4; + err = NvSuccess; + break; } - break; - } - case NvOdmIoModule_Uart: - { - NvRmModuleUartInterfaceCaps *pUartCaps = - (NvRmModuleUartInterfaceCaps *)pCaps; - err = NvSuccess; - if (Instance == 0) + case NvOdmIoModule_Hsmmc: { - if (PinMap == NvOdmUartPinMap_Config1) - pUartCaps->NumberOfInterfaceLines = 8; - else if (PinMap == NvOdmUartPinMap_Config3) - pUartCaps->NumberOfInterfaceLines = 7; - else if ((PinMap == NvOdmUartPinMap_Config2) || - (PinMap == NvOdmUartPinMap_Config4)) - pUartCaps->NumberOfInterfaceLines = 4; - else if ((PinMap == NvOdmUartPinMap_Config5) || - (PinMap == NvOdmUartPinMap_Config6)) - pUartCaps->NumberOfInterfaceLines = 2; + NvRmModuleSdmmcInterfaceCaps *pSdmmcCaps = + (NvRmModuleSdmmcInterfaceCaps *)pCaps; + if (Instance==0 && PinMap==NvOdmHsmmcPinMap_Config2) + pSdmmcCaps->MmcInterfaceWidth = 4; else - pUartCaps->NumberOfInterfaceLines = 0; + pSdmmcCaps->MmcInterfaceWidth = 8; + err = NvSuccess; + break; } - else if (Instance == 1) + case NvOdmIoModule_Pwm: { - if ((PinMap == NvOdmUartPinMap_Config1) || - (PinMap == NvOdmUartPinMap_Config2)) - pUartCaps->NumberOfInterfaceLines = 4; - else if (PinMap == NvOdmUartPinMap_Config3) - pUartCaps->NumberOfInterfaceLines = 2; + NvRmModulePwmInterfaceCaps *pPwmCaps = + (NvRmModulePwmInterfaceCaps *)pCaps; + err = NvSuccess; + if (Instance == 0 && (PinMap == NvOdmPwmPinMap_Config1)) + pPwmCaps->PwmOutputIdSupported = 15; + else if (Instance == 0 && (PinMap == NvOdmPwmPinMap_Config2)) + pPwmCaps->PwmOutputIdSupported = 13; + else if (Instance == 0 && (PinMap == NvOdmPwmPinMap_Config3)) + pPwmCaps->PwmOutputIdSupported = 1; + else if (Instance == 0 && (PinMap == NvOdmPwmPinMap_Config4)) + pPwmCaps->PwmOutputIdSupported = 12; else - pUartCaps->NumberOfInterfaceLines = 0; + { + pPwmCaps->PwmOutputIdSupported = 0; + err = NvError_NotSupported; + } + break; } - else if (Instance == 2) + case NvOdmIoModule_Nand: { - if (PinMap == NvOdmUartPinMap_Config1) - pUartCaps->NumberOfInterfaceLines = 4; - else if (PinMap == NvOdmUartPinMap_Config2) - pUartCaps->NumberOfInterfaceLines = 2; + NvRmModuleNandInterfaceCaps *pNandCaps = + (NvRmModuleNandInterfaceCaps *)pCaps; + if (Instance == 0) + { + pNandCaps->IsCombRbsyMode = NV_TRUE; + pNandCaps->NandInterfaceWidth = 8; + + if (PinMap == NvOdmNandPinMap_Config4) + pNandCaps->IsCombRbsyMode = NV_FALSE; + + if ((PinMap == NvOdmNandPinMap_Config1) || + (PinMap == NvOdmNandPinMap_Config2)) + pNandCaps->NandInterfaceWidth = 16; + + err = NvSuccess; + } else - pUartCaps->NumberOfInterfaceLines = 0; + { + NV_ASSERT(NV_FALSE); + err = NvError_NotSupported; + } + break; } - else + case NvOdmIoModule_Uart: { - NV_ASSERT(NV_FALSE); - err = NvError_NotSupported; + NvRmModuleUartInterfaceCaps *pUartCaps = + (NvRmModuleUartInterfaceCaps *)pCaps; + err = NvSuccess; + if (Instance == 0) + { + if (PinMap == NvOdmUartPinMap_Config1) + pUartCaps->NumberOfInterfaceLines = 8; + else if (PinMap == NvOdmUartPinMap_Config3) + pUartCaps->NumberOfInterfaceLines = 7; + else if ((PinMap == NvOdmUartPinMap_Config2) || + (PinMap == NvOdmUartPinMap_Config4)) + pUartCaps->NumberOfInterfaceLines = 4; + else if ((PinMap == NvOdmUartPinMap_Config5) || + (PinMap == NvOdmUartPinMap_Config6)) + pUartCaps->NumberOfInterfaceLines = 2; + else + pUartCaps->NumberOfInterfaceLines = 0; + } + else if (Instance == 1) + { + if ((PinMap == NvOdmUartPinMap_Config1) || + (PinMap == NvOdmUartPinMap_Config2)) + pUartCaps->NumberOfInterfaceLines = 4; + else if (PinMap == NvOdmUartPinMap_Config3) + pUartCaps->NumberOfInterfaceLines = 2; + else + pUartCaps->NumberOfInterfaceLines = 0; + } + else if (Instance == 2) + { + if (PinMap == NvOdmUartPinMap_Config1) + pUartCaps->NumberOfInterfaceLines = 4; + else if (PinMap == NvOdmUartPinMap_Config2) + pUartCaps->NumberOfInterfaceLines = 2; + else + pUartCaps->NumberOfInterfaceLines = 0; + } + else + { + NV_ASSERT(NV_FALSE); + err = NvError_NotSupported; + } + break; } - break; - } - default: - break; + default: + break; } return err; } - NvError NvRmAp15GetStraps( NvRmDeviceHandle hDevice, @@ -1164,3 +1182,4 @@ NvRmAp15GetStraps( *pStrapValue = reg; return NvSuccess; } + diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_pinmux_utils.h b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_pinmux_utils.h new file mode 100644 index 000000000000..be1402f5d645 --- /dev/null +++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_pinmux_utils.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2009-2010 NVIDIA Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NVIDIA Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef AP15RM_PINMUX_UTILS_H +#define AP15RM_PINMUX_UTILS_H + +/* + * ap15rm_pinmux_utils.h defines the pinmux macros to implement for the resource + * manager. + */ + +#include "nvrm_pinmux_utils.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* When the state is BranchLink, this is the number of words to increment + * the current "PC" + */ +#define MUX_ENTRY_0_BRANCH_ADDRESS_RANGE 31:2 +// The incr1 offset from TRISTATE_REG_A_0 to the pad group's tristate register +#define MUX_ENTRY_0_TS_OFFSET_RANGE 31:26 +// The bit position within the tristate register for the pad group +#define MUX_ENTRY_0_TS_SHIFT_RANGE 25:21 +// The incr1 offset from PIN_MUX_CTL_A_0 to the pad group's pin mux control register +#define MUX_ENTRY_0_MUX_CTL_OFFSET_RANGE 20:17 +// The bit position within the pin mux control register for the pad group +#define MUX_ENTRY_0_MUX_CTL_SHIFT_RANGE 16:12 +// The mask for the pad group -- expanded to 3b for forward-compatibility +#define MUX_ENTRY_0_MUX_CTL_MASK_RANGE 10:8 +// When a pad group needs to be owned (or disowned), this value is applied +#define MUX_ENTRY_0_MUX_CTL_SET_RANGE 7:5 +// This value is compared against, to determine if the pad group should be disowned +#define MUX_ENTRY_0_MUX_CTL_UNSET_RANGE 4:2 +// for extended opcodes, this field is set with the extended opcode +#define MUX_ENTRY_0_OPCODE_EXTENSION_RANGE 3:2 +// The state for this entry +#define MUX_ENTRY_0_STATE_RANGE 1:0 + +/* This macro is used to generate 32b value to program the tristate& pad mux control + * registers for config/unconfig for a padgroup + */ +#define PIN_MUX_ENTRY(TSOFF,TSSHIFT,MUXOFF,MUXSHIFT,MUXMASK,MUXSET,MUXUNSET,STAT) \ + (NV_DRF_NUM(MUX, ENTRY, TS_OFFSET, TSOFF) | NV_DRF_NUM(MUX, ENTRY, TS_SHIFT, TSSHIFT) | \ + NV_DRF_NUM(MUX, ENTRY, MUX_CTL_OFFSET, MUXOFF) | NV_DRF_NUM(MUX, ENTRY, MUX_CTL_SHIFT, MUXSHIFT) | \ + NV_DRF_NUM(MUX, ENTRY,MUX_CTL_MASK, MUXMASK) | NV_DRF_NUM(MUX, ENTRY,MUX_CTL_SET, MUXSET) | \ + NV_DRF_NUM(MUX, ENTRY, MUX_CTL_UNSET,MUXUNSET) | NV_DRF_NUM(MUX, ENTRY, STATE,STAT)) + +// This is used to program the tristate & pad mux control registers for a pad group +#define CONFIG_VAL(TRISTATE_REG, MUXCTL_REG, PADGROUP, MUX) \ + (PIN_MUX_ENTRY(((APB_MISC_PP_TRISTATE_REG_##TRISTATE_REG##_0 - APB_MISC_PP_TRISTATE_REG_A_0)>>2), \ + APB_MISC_PP_TRISTATE_REG_##TRISTATE_REG##_0_Z_##PADGROUP##_SHIFT, \ + ((APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0 - APB_MISC_PP_PIN_MUX_CTL_A_0) >> 2), \ + APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_SHIFT, \ + APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_DEFAULT_MASK, \ + APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_##MUX, \ + 0, PinMuxConfig_Set)) + +/* This macro is used to compare a pad group against a potentially conflicting + * enum (where the conflict is caused by setting a new config), and to resolve + * the conflict by setting the conflicting pad group to a different, + * non-conflicting option. Read this as: if (PADGROUP) is equal to + * (CONFLICTMUX), replace it with (RESOLUTIONMUX) + */ +#define UNCONFIG_VAL(MUXCTL_REG, PADGROUP, CONFLICTMUX, RESOLUTIONMUX) \ + (PIN_MUX_ENTRY(0, 0, \ + ((APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0 - APB_MISC_PP_PIN_MUX_CTL_A_0) >> 2), \ + APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_SHIFT, \ + APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_DEFAULT_MASK, \ + APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_##RESOLUTIONMUX, \ + APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_##CONFLICTMUX, \ + PinMuxConfig_Unset)) + +#if NVRM_PINMUX_DEBUG_FLAG +#define CONFIG(TRISTATE_REG, MUXCTL_REG, PADGROUP, MUX) \ + (CONFIG_VAL(TRISTATE_REG, MUXCTL_REG, PADGROUP, MUX)), \ + (NvU32)(const void*)(#MUXCTL_REG "_0_" #PADGROUP "_SEL to " #MUX), \ + (NvU32)(const void*)(#TRISTATE_REG "_0_Z_" #PADGROUP) + +#define UNCONFIG(MUXCTL_REG, PADGROUP, CONFLICTMUX, RESOLUTIONMUX) \ + (UNCONFIG_VAL(MUXCTL_REG, PADGROUP, CONFLICTMUX, RESOLUTIONMUX)), \ + (NvU32)(const void*)(#MUXCTL_REG "_0_" #PADGROUP "_SEL from " #CONFLICTMUX " to " #RESOLUTIONMUX), \ + (NvU32)(const void*)(NULL) +#else +#define CONFIG(TRISTATE_REG, MUXCTL_REG, PADGROUP, MUX) \ + (CONFIG_VAL(TRISTATE_REG, MUXCTL_REG, PADGROUP, MUX)) +#define UNCONFIG(MUXCTL_REG, PADGROUP, CONFLICTMUX, RESOLUTIONMUX) \ + (UNCONFIG_VAL(MUXCTL_REG, PADGROUP, CONFLICTMUX, RESOLUTIONMUX)) +#endif + +// The below entries define the table format for GPIO Port/Pin-to-Tristate register mappings +// Each table entry is 16b, and one is stored for every GPIO Port/Pin on the chip +#define MUX_GPIOMAP_0_TS_OFFSET_RANGE 15:10 +// Defines where in the 32b register the tristate control is located +#define MUX_GPIOMAP_0_TS_SHIFT_RANGE 4:0 + +#define TRISTATE_ENTRY(TSOFFS, TSSHIFT) \ + ((NvU16)(NV_DRF_NUM(MUX,GPIOMAP,TS_OFFSET,(TSOFFS)) | \ + NV_DRF_NUM(MUX,GPIOMAP,TS_SHIFT,(TSSHIFT)))) + +#define GPIO_TRISTATE(TRIREG,PADGROUP) \ + (TRISTATE_ENTRY(((APB_MISC_PP_TRISTATE_REG_##TRIREG##_0 - APB_MISC_PP_TRISTATE_REG_A_0)>>2), \ + APB_MISC_PP_TRISTATE_REG_##TRIREG##_0_Z_##PADGROUP##_SHIFT)) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // AP15RM_PINMUX_UTILS_H + diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap16rm_pinmux_tables.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap16rm_pinmux_tables.c index 4d2ebad4583a..09c53e93d9af 100644 --- a/arch/arm/mach-tegra/nvrm/core/ap15/ap16rm_pinmux_tables.c +++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap16rm_pinmux_tables.c @@ -38,7 +38,7 @@ #include "ap15rm_private.h" #include "ap16/arapb_misc.h" #include "ap15/arclk_rst.h" -#include "nvrm_pinmux_utils.h" +#include "ap15rm_pinmux_utils.h" #include "nvodm_query_pinmux.h" #include "nvrm_clocks.h" @@ -169,7 +169,7 @@ extern const NvU32 g_Ap15Mux_BacklightDisplay2Pwm1[]; extern const NvU32* g_Ap15MuxBacklight[]; static const NvU32 g_Ap16Mux_Ulpi[] = { - CONFIGEND(), // no pad groups reset to ULPI, so nothing to disown for reset config + CONFIGEND(), // no pad groups reset to ULPI, so nothing to disown for reset config CONFIG(B,A,UAA,ULPI), CONFIG(B,A,UAB,ULPI), CONFIG(B,A,UAC,ULPI), CONFIGEND(), MODULEDONE() }; @@ -314,12 +314,10 @@ NvRmPrivAp16GetModuleInterfaceCaps( return NvError_NotSupported; } return NvSuccess; - + default: break; } return NvRmPrivAp15GetModuleInterfaceCaps(Module, Instance, PinMap, pCaps); } - - diff --git a/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_pinmux_tables.c b/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_pinmux_tables.c index 312ca6d4f69f..8a2ac58efdf0 100644 --- a/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_pinmux_tables.c +++ b/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_pinmux_tables.c @@ -37,7 +37,7 @@ #include "nvrm_hwintf.h" #include "ap20/arapb_misc.h" #include "ap20/arclk_rst.h" -#include "nvrm_pinmux_utils.h" +#include "ap15/ap15rm_pinmux_utils.h" #include "nvrm_clocks.h" #include "nvodm_query_pinmux.h" @@ -97,7 +97,6 @@ static const NvU32* g_Ap20MuxUart[] = { NULL, }; - static const NvU32 g_Ap20Mux_Spi1[] = { /* Disown UDA,SPIA,SPIB and SPIC RSVD and GMI chosen*/ UNCONFIG(A, UDA, SPI1, RSVD),UNCONFIG(D, SPIA, SPI1, GMI), @@ -153,15 +152,14 @@ static const NvU32 g_Ap20Mux_Spi3[] = { CONFIG(B,D,SDC,SPI3),CONFIG(B,D,SDD,SPI3), CONFIGEND(), // config 7 - /* -spif,spig,and spih are added as config 7 on mux: 0 - * -spia of SPI2_MOSI as spi3_dout on mux: 2 under config 7. + /* -spif,spig,and spih are added as config 7 on mux: 0 + * -spia of SPI2_MOSI as spi3_dout on mux: 2 under config 7. */ CONFIG(B,D,SPIA,SPI3),CONFIG(B,D,SPIF,SPI3), CONFIG(B,D,SPIG,SPI3),CONFIG(B,D,SPIG,SPI3), CONFIGEND(), MODULEDONE(), }; - static const NvU32 g_Ap20Mux_Spi4[] = { CONFIGEND(), // config 1 @@ -628,7 +626,6 @@ const NvU32* g_Ap20MuxBacklight[] = { NULL, }; - static const NvU32 g_Ap20Mux_Display1[] = { CONFIGEND(), // config 1, 24b RGB. Pure superset of Config2 (18b RGB) @@ -644,7 +641,7 @@ static const NvU32 g_Ap20Mux_Display1[] = { CONFIG(C,G,LHP1,DISPLAYA), CONFIG(C,G,LHP2,DISPLAYA), CONFIG(C,G,LVP1,DISPLAYA), CONFIG(C,G,LHP0,DISPLAYA), CONFIG(D,G,LDI,DISPLAYA), CONFIG(D,G,LPP,DISPLAYA), CONFIG(D,E,LPW0,DISPLAYA), CONFIG(D,E,LPW1,DISPLAYA), CONFIG(D,E,LPW2,DISPLAYA), - CONFIG(C,E,LSC1,DISPLAYA), CONFIG(C,E,LM1,DISPLAYA), CONFIG(C,E,LVP0,DISPLAYA), + CONFIG(C,E,LSC1,DISPLAYA), CONFIG(C,E,LM1,DISPLAYA), CONFIG(C,E,LVP0,DISPLAYA), CONFIGEND(), // config 4. SPI CONFIG(D,E,LPW0,DISPLAYA), CONFIG(D,E,LPW2,DISPLAYA), CONFIG(C,E,LSC1,DISPLAYA), @@ -678,7 +675,7 @@ static const NvU32 g_Ap20Mux_Display1[] = { CONFIG(C,E,LCSN,DISPLAYA), CONFIG(C,E,LM1,DISPLAYA),CONFIG(C,E,LM0,DISPLAYA), CONFIG(D,E,LPW0,DISPLAYA),CONFIG(D,E,LPW2,DISPLAYA), CONFIG(D,E,LPW1,DISPLAYA), CONFIG(C,E,LVP0,DISPLAYA), CONFIG(C,E,LDC,DISPLAYA), CONFIG(C,E,LSC1,DISPLAYA), - CONFIG(D,E,LSDI,DISPLAYA), + CONFIG(D,E,LSDI,DISPLAYA), */ }; @@ -697,7 +694,7 @@ static const NvU32 g_Ap20Mux_Display2[] = { CONFIG(C,G,LHP1,DISPLAYB), CONFIG(C,G,LHP2,DISPLAYB), CONFIG(C,G,LVP1,DISPLAYB), CONFIG(C,G,LHP0,DISPLAYB), CONFIG(D,G,LDI,DISPLAYB), CONFIG(D,G,LPP,DISPLAYB), CONFIG(D,E,LPW0,DISPLAYB), CONFIG(D,E,LPW1,DISPLAYB), CONFIG(D,E,LPW2,DISPLAYB), - CONFIG(C,E,LSC1,DISPLAYB), CONFIG(C,E,LM1,DISPLAYB), CONFIG(C,E,LVP0,DISPLAYB), + CONFIG(C,E,LSC1,DISPLAYB), CONFIG(C,E,LM1,DISPLAYB), CONFIG(C,E,LVP0,DISPLAYB), CONFIGEND(), // config 4. SPI CONFIG(D,E,LPW0,DISPLAYB), CONFIG(D,E,LPW2,DISPLAYB), CONFIG(C,E,LSC1,DISPLAYB), @@ -715,7 +712,7 @@ static const NvU32 g_Ap20Mux_Display2[] = { CONFIG(C,F,LD12,DISPLAYB), CONFIG(C,F,LD13,DISPLAYB), CONFIG(C,F,LD14,DISPLAYB), CONFIG(C,F,LD15,DISPLAYB), CONFIG(C,G,LD16,DISPLAYB), CONFIG(C,G,LD17,DISPLAYB), CONFIG(C,E,LSC0,DISPLAYB), CONFIGEND(), - SUBROUTINESDONE(), + SUBROUTINESDONE(), }; static const NvU32* g_Ap20MuxDisplay[] = { @@ -1089,7 +1086,7 @@ NvRmPrivAp20GetModuleInterfaceCaps( { if (PinMap == NvOdmSdioPinMap_Config2 || PinMap == NvOdmSdioPinMap_Config4) ((NvRmModuleSdmmcInterfaceCaps *)pCaps)->MmcInterfaceWidth = 8; - else if (PinMap == NvOdmSdioPinMap_Config1 || + else if (PinMap == NvOdmSdioPinMap_Config1 || PinMap == NvOdmSdioPinMap_Config3 || PinMap == NvOdmSdioPinMap_Config5) ((NvRmModuleSdmmcInterfaceCaps *)pCaps)->MmcInterfaceWidth = 4; else @@ -1126,13 +1123,13 @@ NvRmPrivAp20GetModuleInterfaceCaps( } return NvError_Success; case NvOdmIoModule_Nand: - if (Instance == 0 && (PinMap == NvOdmNandPinMap_Config1 || PinMap == + if (Instance == 0 && (PinMap == NvOdmNandPinMap_Config1 || PinMap == NvOdmNandPinMap_Config3)) { ((NvRmModuleNandInterfaceCaps*)pCaps)->IsCombRbsyMode = NV_TRUE; ((NvRmModuleNandInterfaceCaps*)pCaps)->NandInterfaceWidth = 16; } - else if (Instance == 0 && (PinMap == NvOdmNandPinMap_Config2 || + else if (Instance == 0 && (PinMap == NvOdmNandPinMap_Config2 || PinMap == NvOdmNandPinMap_Config4)) { ((NvRmModuleNandInterfaceCaps*)pCaps)->IsCombRbsyMode = NV_TRUE; diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_pinmux.c b/arch/arm/mach-tegra/nvrm/core/common/nvrm_pinmux.c index a14cc3a015bf..e60e4654a413 100644 --- a/arch/arm/mach-tegra/nvrm/core/common/nvrm_pinmux.c +++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_pinmux.c @@ -30,16 +30,12 @@ * */ -#define NV_ENABLE_DEBUG_PRINTS 0 -#define SKIP_TRISTATE_REFCNT 0 - #include "nvcommon.h" #include "nvrm_pinmux.h" #include "nvrm_drf.h" #include "nvassert.h" #include "nvrm_hwintf.h" #include "ap15/ap15rm_private.h" -#include "ap15/arapb_misc.h" #include "nvrm_pinmux_utils.h" #include "nvodm_query_pinmux.h" @@ -89,255 +85,127 @@ static void NvRmPrivApplyAllModuleTypePinMuxes( NvBool ApplyReset, NvBool ApplyActual); -/* FindConfigStart searches through an array of configuration data to find the - * starting position of a particular configuration in a module instance array. - * The stop position is programmable, so that sub-routines can be placed after - * the last valid true configuration */ - -static const NvU32* NvRmPrivFindConfigStart( - const NvU32* Instance, - NvU32 Config, - NvU32 EndMarker) +typedef struct { - NvU32 Cnt = 0; - while ((Cnt < Config) && (*Instance!=EndMarker)) - { - switch (NV_DRF_VAL(MUX, ENTRY, STATE, *Instance)) { - case PinMuxConfig_BranchLink: - case PinMuxConfig_OpcodeExtend: - if (*Instance==CONFIGEND()) - Cnt++; - Instance++; - break; - default: - Instance += NVRM_PINMUX_SET_OPCODE_SIZE; - break; - } - } - - /* Ugly postfix. In modules with bonafide subroutines, the last - * configuration CONFIGEND() will be followed by a MODULEDONE() - * token, with the first Set/Unset/Branch of the subroutine - * following that. To avoid leaving the "PC" pointing to a - * MODULEDONE() in the case where the first subroutine should be - * executed, fudge the "PC" up by one, to point to the subroutine. */ - if (EndMarker==SUBROUTINESDONE() && *Instance==MODULEDONE()) - Instance++; - - if (*Instance==EndMarker) - Instance = NULL; - - return Instance; -} - -/* NvRmSetPadTristates will increment / decrement the reference count for - * each pad group's global tristate value for each "ConfigSet" command in - * a pad group configuration, and update the register as needed */ -static void NvRmPrivSetPadTristates( + void (*pfnInitTrisateRefCount)(NvRmDeviceHandle hDevice); + const NvU32*** (*pfnGetPinMuxConfigs)(NvRmDeviceHandle hDevice); + void + (*pfnSetPinMuxCtl)( NvRmDeviceHandle hDevice, - const NvU32* Module, - NvU32 Config, - NvBool EnableTristate) + const NvU32* Module, + NvU32 Config); + void + (*pfnSetPadTristates)( + NvRmDeviceHandle hDevice, + const NvU32* Module, + NvU32 Config, + NvBool EnTristate); + const NvU32* + (*pfnFindConfigStart)( + const NvU32* Instance, + NvU32 Config, + NvU32 EndMarker); + NvBool + (*pfnGetPinGroupForGpio)( + NvRmDeviceHandle hDevice, + NvU32 Port, + NvU32 Pin, + NvU32 *pMapping); + void + (*pfnSetGpioTristate)( + NvRmDeviceHandle hDevice, + NvU32 Port, + NvU32 Pin, + NvBool EnableTristate); + NvError + (*pfnInterfaceCaps)( + NvOdmIoModule Module, + NvU32 Instance, + NvU32 PinMap, + void *pCaps); + void + (*pfnEnableExtClock)( + NvRmDeviceHandle hDevice, + const NvU32* Instance, + NvU32 Config, + NvBool ClockState); + NvU32 + (*pfnGetExtClockFreq)( + NvRmDeviceHandle hDevice, + const NvU32* Instance, + NvU32 Config); + NvError + (*pfnGetStraps)( + NvRmDeviceHandle hDevice, + NvRmStrapGroup StrapGroup, + NvU32* pStrapValue); +} NvPinmuxPrivMethods; + +static NvPinmuxPrivMethods* NvRmPrivGetPinmuxMethods( + NvRmDeviceHandle hDevice); + +static NvPinmuxPrivMethods* NvRmPrivGetPinmuxMethods(NvRmDeviceHandle hDevice) { - int StackDepth = 0; - const NvU32 *Instance = NULL; - const NvU32 *ReturnStack[MAX_NESTING_DEPTH+1]; - - /* The re-multiplexing configuration is stored in program 0, - * along with the reset config. */ - if (Config==NVODM_QUERY_PINMAP_MULTIPLEXED) - Config = 0; - - Instance = NvRmPrivFindConfigStart(Module, Config, MODULEDONE()); - /* The first stack return entry is NULL, so that when a ConfigEnd is - * encountered in the "main" configuration program, we pop off a NULL - * pointer, which causes the configuration loop to terminate. */ - ReturnStack[0] = NULL; - - /* This loop iterates over all of the pad groups that need to be updated, - * and updates the reference count for each appropriately. */ - - NvOsMutexLock(hDevice->mutex); - - while (Instance) + static NvPinmuxPrivMethods *p; + static NvPinmuxPrivMethods s_Ap15Methods = { - switch (NV_DRF_VAL(MUX,ENTRY, STATE, *Instance)) { - case PinMuxConfig_OpcodeExtend: - /* Pop the most recent return address off of the return stack - * (which will be NULL if no values have been pushed onto the - * stack) */ - if (NV_DRF_VAL(MUX,ENTRY, OPCODE_EXTENSION, - *Instance)==PinMuxOpcode_ConfigEnd) - { - Instance = ReturnStack[StackDepth--]; - } - /* ModuleDone & SubroutinesDone should never be encountered - * during execution, for properly-formatted tables. */ - else - { - NV_ASSERT(0 && "Logical entry in table!\n"); - } - break; - case PinMuxConfig_BranchLink: - /* Push the next instruction onto the return stack if nesting space - is available, and jump to the target. */ - NV_ASSERT(StackDepth<MAX_NESTING_DEPTH); - ReturnStack[++StackDepth] = Instance+1; - Instance = NvRmPrivFindConfigStart(Module, - NV_DRF_VAL(MUX,ENTRY,BRANCH_ADDRESS,*Instance), - SUBROUTINESDONE()); - NV_ASSERT(Instance && "Invalid branch configuration in table!\n"); - break; - case PinMuxConfig_Set: - { - NvS16 SkipUpdate; - NvU32 TsOffs = NV_DRF_VAL(MUX,ENTRY, TS_OFFSET, *Instance); - NvU32 TsShift = NV_DRF_VAL(MUX,ENTRY, TS_SHIFT, *Instance); - -/* abuse pre/post-increment, to ensure that skipUpdate is 0 when the - * register needs to be programmed (i.e., enabling and previous value was 0, - * or disabling and new value is 0). - */ - if (EnableTristate) -#if (SKIP_TRISTATE_REFCNT == 0) - SkipUpdate = --hDevice->TristateRefCount[TsOffs*32 + TsShift]; - else - SkipUpdate = hDevice->TristateRefCount[TsOffs*32 + TsShift]++; -#else - SkipUpdate = 1; - else - SkipUpdate = 0; -#endif - -#if (SKIP_TRISTATE_REFCNT == 0) - if (SkipUpdate < 0) - { - hDevice->TristateRefCount[TsOffs*32 + TsShift] = 0; - NV_DEBUG_PRINTF(("(%s:%s) Negative reference count detected " - "on TRISTATE_REG_%c_0, bit %u\n", - __FILE__, __LINE__, ('A'+(TsOffs)), TsShift)); - //NV_ASSERT(SkipUpdate>=0); - } -#endif - - if (!SkipUpdate) - { - NvU32 Curr = NV_REGR(hDevice, NvRmModuleID_Misc, 0, - APB_MISC_PP_TRISTATE_REG_A_0 + 4*TsOffs); - Curr &= ~(1<<TsShift); -#if (SKIP_TRISTATE_REFCNT == 0) - Curr |= (EnableTristate?1:0)<<TsShift; -#endif - NV_REGW(hDevice, NvRmModuleID_Misc, 0, - APB_MISC_PP_TRISTATE_REG_A_0 + 4*TsOffs, Curr); - -#if NVRM_PINMUX_DEBUG_FLAG - NV_DEBUG_PRINTF(("Setting TRISTATE_REG_%s to %s\n", - (const char*)Instance[2], - (EnableTristate)?"TRISTATE" : "NORMAL")); -#endif - } - } - /* fall through. - * The "Unset" configurations are not applicable to tristate - * configuration, so skip over them. */ - case PinMuxConfig_Unset: - Instance += NVRM_PINMUX_SET_OPCODE_SIZE; - break; - } - } - NvOsMutexUnlock(hDevice->mutex); -} - -/* NvRmSetPinMuxCtl will apply new pin mux configurations to the pin mux - * control registers. */ -static void NvRmPrivSetPinMuxCtl( - NvRmDeviceHandle hDevice, - const NvU32* Module, - NvU32 Config) -{ - NvU32 MuxCtlOffset, MuxCtlShift, MuxCtlMask, MuxCtlSet, MuxCtlUnset; - const NvU32 *ReturnStack[MAX_NESTING_DEPTH+1]; - const NvU32 *Instance; - int StackDepth = 0; - NvU32 Curr; - - ReturnStack[0] = NULL; - Instance = Module; - - NvOsMutexLock(hDevice->mutex); - - /* The re-multiplexing configuration is stored in program 0, - * along with the reset config. */ - if (Config==NVODM_QUERY_PINMAP_MULTIPLEXED) - Config = 0; - - Instance = NvRmPrivFindConfigStart(Module, Config, MODULEDONE()); - - // Apply the new configuration, setting / unsetting as appropriate - while (Instance) + NvRmPrivAp15InitTrisateRefCount, + NvRmAp15GetPinMuxConfigs, + NvRmPrivAp15SetPinMuxCtl, + NvRmPrivAp15SetPadTristates, + NvRmPrivAp15FindConfigStart, + NvRmAp15GetPinGroupForGpio, + NvRmPrivAp15SetGpioTristate, + NvRmPrivAp15GetModuleInterfaceCaps, + NvRmPrivAp15EnableExternalClockSource, + NvRmPrivAp15GetExternalClockSourceFreq, + NvRmAp15GetStraps + }; + static NvPinmuxPrivMethods s_Ap16Methods = { - switch (NV_DRF_VAL(MUX,ENTRY, STATE, *Instance)) { - case PinMuxConfig_OpcodeExtend: - if (NV_DRF_VAL(MUX,ENTRY, OPCODE_EXTENSION, - *Instance)==PinMuxOpcode_ConfigEnd) - { - Instance = ReturnStack[StackDepth--]; - } - else - { - NV_ASSERT(0 && "Logical entry in table!\n"); - } - break; - case PinMuxConfig_BranchLink: - NV_ASSERT(StackDepth<MAX_NESTING_DEPTH); - ReturnStack[++StackDepth] = Instance+1; - Instance = NvRmPrivFindConfigStart(Module, - NV_DRF_VAL(MUX,ENTRY,BRANCH_ADDRESS,*Instance), - SUBROUTINESDONE()); - NV_ASSERT(Instance && "Invalid branch configuration in table!\n"); - break; - default: - { - MuxCtlOffset = NV_DRF_VAL(MUX,ENTRY, MUX_CTL_OFFSET, *Instance); - MuxCtlShift = NV_DRF_VAL(MUX,ENTRY, MUX_CTL_SHIFT, *Instance); - MuxCtlUnset = NV_DRF_VAL(MUX,ENTRY, MUX_CTL_UNSET, *Instance); - MuxCtlSet = NV_DRF_VAL(MUX,ENTRY, MUX_CTL_SET, *Instance); - MuxCtlMask = NV_DRF_VAL(MUX, ENTRY, MUX_CTL_MASK, *Instance); - - Curr = NV_REGR(hDevice, NvRmModuleID_Misc, 0, - APB_MISC_PP_PIN_MUX_CTL_A_0 + 4*MuxCtlOffset); - - if (NV_DRF_VAL(MUX,ENTRY,STATE,*Instance)==PinMuxConfig_Set) - { - Curr &= ~(MuxCtlMask<<MuxCtlShift); - Curr |= (MuxCtlSet<<MuxCtlShift); -#if NVRM_PINMUX_DEBUG_FLAG - NV_DEBUG_PRINTF(("Configuring PINMUX_CTL_%s\n", - (const char *)Instance[1])); -#endif + NvRmPrivAp15InitTrisateRefCount, + NvRmAp16GetPinMuxConfigs, + NvRmPrivAp15SetPinMuxCtl, + NvRmPrivAp15SetPadTristates, + NvRmPrivAp15FindConfigStart, + NvRmAp15GetPinGroupForGpio, + NvRmPrivAp15SetGpioTristate, + NvRmPrivAp16GetModuleInterfaceCaps, + NvRmPrivAp15EnableExternalClockSource, + NvRmPrivAp15GetExternalClockSourceFreq, + NvRmAp15GetStraps + }; + static NvPinmuxPrivMethods s_Ap20Methods = + { + NvRmPrivAp15InitTrisateRefCount, + NvRmAp20GetPinMuxConfigs, + NvRmPrivAp15SetPinMuxCtl, + NvRmPrivAp15SetPadTristates, + NvRmPrivAp15FindConfigStart, + NvRmAp20GetPinGroupForGpio, + NvRmPrivAp15SetGpioTristate, + NvRmPrivAp20GetModuleInterfaceCaps, + NvRmPrivAp20EnableExternalClockSource, + NvRmPrivAp20GetExternalClockSourceFreq, + NvRmAp20GetStraps + }; - } - else if (((Curr>>MuxCtlShift)&MuxCtlMask)==MuxCtlUnset) - { - NV_ASSERT(NV_DRF_VAL(MUX,ENTRY,STATE, - *Instance)==PinMuxConfig_Unset); - Curr &= ~(MuxCtlMask<<MuxCtlShift); - Curr |= (MuxCtlSet<<MuxCtlShift); -#if NVRM_PINMUX_DEBUG_FLAG - NV_DEBUG_PRINTF(("Unconfiguring PINMUX_CTL_%s\n", - (const char *)Instance[1])); -#endif - } - - NV_REGW(hDevice, NvRmModuleID_Misc, 0, - APB_MISC_PP_PIN_MUX_CTL_A_0 + 4*MuxCtlOffset, Curr); - Instance += NVRM_PINMUX_SET_OPCODE_SIZE; - break; - } - } + NV_ASSERT(hDevice); + switch (hDevice->ChipId.Id) { + case 0x15: + p = &s_Ap15Methods; + break; + case 0x16: + p = &s_Ap16Methods; + break; + case 0x20: + p = &s_Ap20Methods; + break; + default: + NV_ASSERT(!"Unsupported chip ID"); + return NULL; } - NvOsMutexUnlock(hDevice->mutex); + return p; } static void NvRmPrivApplyAllPinMuxes( @@ -370,6 +238,7 @@ static void NvRmPrivApplyAllModuleTypePinMuxes( { const NvU32 *OdmConfigs; NvU32 NumOdmConfigs; + NvPinmuxPrivMethods *p = NvRmPrivGetPinmuxMethods(hDevice); const NvU32 **ModulePrograms = hDevice->PinMuxTable[(NvU32)Module]; if (!ModulePrograms) @@ -389,10 +258,10 @@ static void NvRmPrivApplyAllModuleTypePinMuxes( * a sane state, then apply the ODM configuration, if one is specified */ if (ApplyReset) - NvRmPrivSetPinMuxCtl(hDevice, *ModulePrograms, 0); + (p->pfnSetPinMuxCtl)(hDevice, *ModulePrograms, 0); if (NumOdmConfigs && ApplyActual) { - NvRmPrivSetPinMuxCtl(hDevice, *ModulePrograms, *OdmConfigs); + (p->pfnSetPinMuxCtl)(hDevice, *ModulePrograms, *OdmConfigs); NumOdmConfigs--; OdmConfigs++; } @@ -403,7 +272,7 @@ static void NvRmPrivApplyAllModuleTypePinMuxes( * zeros for undefined modules */ while (NumOdmConfigs) { - NV_ASSERT((*OdmConfigs==0) && + NV_ASSERT((*OdmConfigs==0) && "More ODM configs than module instances!\n"); NumOdmConfigs--; OdmConfigs++; @@ -422,53 +291,21 @@ void NvRmInitPinMux( NvRmDeviceHandle hDevice, NvBool First) { - NvU32 i, j, curr; + NvPinmuxPrivMethods *p = NvRmPrivGetPinmuxMethods(hDevice); if (!hDevice->PinMuxTable) { - switch (hDevice->ChipId.Id) { - case 0x15: - hDevice->PinMuxTable = NvRmAp15GetPinMuxConfigs(hDevice); break; - case 0x16: - hDevice->PinMuxTable = NvRmAp16GetPinMuxConfigs(hDevice); break; - case 0x20: - hDevice->PinMuxTable = NvRmAp20GetPinMuxConfigs(hDevice); break; - default: - NV_ASSERT(!"Unsupported chip ID"); - hDevice->PinMuxTable = NULL; - return; - } - - NvOsMutexLock(hDevice->mutex); - NvOsMemset(hDevice->TristateRefCount, 0, - sizeof(hDevice->TristateRefCount)); - - for (i=0; i<=((APB_MISC_PP_TRISTATE_REG_D_0- - APB_MISC_PP_TRISTATE_REG_A_0)>>2); i++) - { - curr = NV_REGR(hDevice, NvRmModuleID_Misc, 0, - APB_MISC_PP_TRISTATE_REG_A_0 + 4*i); - // swap from 0=normal, 1=tristate to 0=tristate, 1=normal - curr = ~curr; - for (j=0; curr; j++, curr>>=1) - { - /* the oppositely-named tristate reference count keeps track - * of the number of active users of each pad group, and - * enables tristate when the count reaches zero. */ - hDevice->TristateRefCount[i*32 + j] = (NvS16)(curr & 0x1); - } - } - NvOsMutexUnlock(hDevice->mutex); + hDevice->PinMuxTable = (p->pfnGetPinMuxConfigs)(hDevice); + (p->pfnInitTrisateRefCount)(hDevice); } #if (!NVOS_IS_WINDOWS_CE || NV_OAL) NvRmPrivApplyAllPinMuxes(hDevice, First); #endif - } -/* RmPinMuxConfigSelect sets a specific module to a specific configuration. +/* RmPinMuxConfigSelect sets a specific module to a specific configuration. * It is used for multiplexed controllers, and should only be called by the * ODM service function NvOdmPinMuxSet */ void NvRmPinMuxConfigSelect( @@ -480,6 +317,7 @@ void NvRmPinMuxConfigSelect( const NvU32 ***ModulePrograms = NULL; const NvU32 **InstancePrograms = NULL; NvU32 i = 0; + NvPinmuxPrivMethods *p = NvRmPrivGetPinmuxMethods(hDevice); NV_ASSERT(hDevice); if (!hDevice) @@ -500,10 +338,10 @@ void NvRmPinMuxConfigSelect( i++; InstancePrograms++; } - + if (*InstancePrograms) { - NvRmPrivSetPinMuxCtl(hDevice, *InstancePrograms, Configuration); + (p->pfnSetPinMuxCtl)(hDevice, *InstancePrograms, Configuration); } } } @@ -523,13 +361,14 @@ void NvRmPinMuxConfigSetTristate( const NvU32 ***ModulePrograms = NULL; const NvU32 **InstancePrograms = NULL; NvU32 i = 0; + NvPinmuxPrivMethods *p = NvRmPrivGetPinmuxMethods(hDevice); NV_ASSERT(hDevice); if (!hDevice) return; ModulePrograms = hDevice->PinMuxTable; - + NV_ASSERT(ModulePrograms && ((NvU32)IoModule < (NvU32)NvOdmIoModule_Num)); InstancePrograms = (const NvU32**)ModulePrograms[(NvU32)IoModule]; @@ -544,7 +383,7 @@ void NvRmPinMuxConfigSetTristate( if (*InstancePrograms) { - NvRmPrivSetPadTristates(hDevice, *InstancePrograms, + (p->pfnSetPadTristates)(hDevice, *InstancePrograms, Configuration, EnableTristate); } } @@ -774,68 +613,9 @@ void NvRmSetGpioTristate( NvU32 Pin, NvBool EnableTristate) { - NvU32 Mapping = 0; - NvS16 SkipUpdate; - NvBool ret = NV_FALSE; - - NV_ASSERT(hDevice); - - switch (hDevice->ChipId.Id) { - case 0x15: - case 0x16: - ret = NvRmAp15GetPinGroupForGpio(hDevice, Port, Pin, &Mapping); - break; - case 0x20: - ret = NvRmAp20GetPinGroupForGpio(hDevice, Port, Pin, &Mapping); - break; - default: - NV_ASSERT(!"Chip ID not supported"); - return; - } - - if (ret) - { - NvU32 TsOffs = NV_DRF_VAL(MUX, GPIOMAP, TS_OFFSET, Mapping); - NvU32 TsShift = NV_DRF_VAL(MUX, GPIOMAP, TS_SHIFT, Mapping); - - NvOsMutexLock(hDevice->mutex); - - if (EnableTristate) -#if (SKIP_TRISTATE_REFCNT == 0) - SkipUpdate = --hDevice->TristateRefCount[TsOffs*32 + TsShift]; - else - SkipUpdate = hDevice->TristateRefCount[TsOffs*32 + TsShift]++; -#else - SkipUpdate = 1; - else - SkipUpdate = 0; -#endif - -#if (SKIP_TRISTATE_REFCNT == 0) - if (SkipUpdate < 0) - { - hDevice->TristateRefCount[TsOffs*32 + TsShift] = 0; - NV_DEBUG_PRINTF(("(%s:%s) Negative reference count detected on " - "TRISTATE_REG_%c_0, bit %u\n", __FILE__, __LINE__, - ('A'+(TsOffs)), TsShift)); - //NV_ASSERT(SkipUpdate>=0); - } -#endif + NvPinmuxPrivMethods *p = NvRmPrivGetPinmuxMethods(hDevice); - if (!SkipUpdate) - { - NvU32 Curr = NV_REGR(hDevice, NvRmModuleID_Misc, 0, - APB_MISC_PP_TRISTATE_REG_A_0 + 4*TsOffs); - Curr &= ~(1<<TsShift); -#if (SKIP_TRISTATE_REFCNT == 0) - Curr |= (EnableTristate?1:0)<<TsShift; -#endif - NV_REGW(hDevice, NvRmModuleID_Misc, 0, - APB_MISC_PP_TRISTATE_REG_A_0 + 4*TsOffs, Curr); - } - - NvOsMutexUnlock(hDevice->mutex); - } + (p->pfnSetGpioTristate)(hDevice, Port, Pin, EnableTristate); } NvU32 NvRmExternalClockConfig( @@ -850,30 +630,13 @@ NvU32 NvRmExternalClockConfig( const NvU32 *CdevInstance; NvU32 i = 0; NvU32 ret = 0; - - void (*pfnEnableExtClock)(NvRmDeviceHandle, const NvU32 *, NvU32, NvBool); - NvU32 (*pfnGetExtClockFreq)(NvRmDeviceHandle, const NvU32 *, NvU32); + NvPinmuxPrivMethods *p = NvRmPrivGetPinmuxMethods(hDevice); NV_ASSERT(hDevice); if (!hDevice) return NvError_BadParameter; - switch (hDevice->ChipId.Id) { - case 0x15: - case 0x16: - pfnEnableExtClock = NvRmPrivAp15EnableExternalClockSource; - pfnGetExtClockFreq = NvRmPrivAp15GetExternalClockSourceFreq; - break; - case 0x20: - pfnEnableExtClock = NvRmPrivAp20EnableExternalClockSource; - pfnGetExtClockFreq = NvRmPrivAp20GetExternalClockSourceFreq; - break; - default: - NV_ASSERT(!"Unsupported Chip ID"); - return 0; - } - ModulePrograms = hDevice->PinMuxTable; NV_ASSERT(IoModule==NvOdmIoModule_ExternalClock); @@ -893,14 +656,14 @@ NvU32 NvRmExternalClockConfig( if (*InstancePrograms) { if (!EnableTristate) - NvRmPrivSetPinMuxCtl(hDevice, *InstancePrograms, Config); + (p->pfnSetPinMuxCtl)(hDevice, *InstancePrograms, Config); - NvRmPrivSetPadTristates(hDevice, *InstancePrograms, + (p->pfnSetPadTristates)(hDevice, *InstancePrograms, Config, EnableTristate); - CdevInstance = NvRmPrivFindConfigStart(*InstancePrograms, + CdevInstance = (p->pfnFindConfigStart)(*InstancePrograms, Config, MODULEDONE()); - pfnEnableExtClock(hDevice, CdevInstance, Config, !EnableTristate); - ret = pfnGetExtClockFreq(hDevice, CdevInstance, Config); + (p->pfnEnableExtClock)(hDevice, CdevInstance, Config, !EnableTristate); + ret = (p->pfnGetExtClockFreq)(hDevice, CdevInstance, Config); } } return ret; @@ -917,29 +680,14 @@ NvError NvRmGetModuleInterfaceCapabilities( NvOdmIoModule OdmModules[4]; NvU32 OdmInstances[4]; NvU32 NumOdmModules; - NvError (*pfnInterfaceCaps)(NvOdmIoModule,NvU32,NvU32,void*); - + NvPinmuxPrivMethods *p = NvRmPrivGetPinmuxMethods(hRm); + NV_ASSERT(hRm); NV_ASSERT(pCaps); if (!hRm || !pCaps) return NvError_BadParameter; - switch (hRm->ChipId.Id) { - case 0x15: - pfnInterfaceCaps = NvRmPrivAp15GetModuleInterfaceCaps; - break; - case 0x16: - pfnInterfaceCaps = NvRmPrivAp16GetModuleInterfaceCaps; - break; - case 0x20: - pfnInterfaceCaps = NvRmPrivAp20GetModuleInterfaceCaps; - break; - default: - NV_ASSERT(!"Unsupported chip ID!"); - return NvError_NotSupported; - } - NumOdmModules = NvRmPrivRmModuleToOdmModule(hRm->ChipId.Id, ModuleId, (NvOdmIoModule *)OdmModules, OdmInstances); @@ -988,7 +736,7 @@ NvError NvRmGetModuleInterfaceCapabilities( if (OdmInstances[0]>=NumOdmConfigs || !OdmConfigs[OdmInstances[0]]) return NvError_NotSupported; - return pfnInterfaceCaps(OdmModules[0],OdmInstances[0], + return (p->pfnInterfaceCaps)(OdmModules[0],OdmInstances[0], OdmConfigs[OdmInstances[0]],pCaps); } @@ -997,19 +745,11 @@ NvError NvRmGetStraps( NvRmStrapGroup StrapGroup, NvU32* pStrapValue) { + NvPinmuxPrivMethods *p = NvRmPrivGetPinmuxMethods(hDevice); NV_ASSERT(hDevice && pStrapValue); if (!hDevice || !pStrapValue) return NvError_BadParameter; - - switch (hDevice->ChipId.Id) { - case 0x15: - case 0x16: - return NvRmAp15GetStraps(hDevice, StrapGroup, pStrapValue); - case 0x20: - return NvRmAp20GetStraps(hDevice, StrapGroup, pStrapValue); - default: - NV_ASSERT(!"Unsupported Chip ID"); - return 0; - } + return (p->pfnGetStraps)(hDevice, StrapGroup, pStrapValue); } + diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_pinmux_utils.h b/arch/arm/mach-tegra/nvrm/core/common/nvrm_pinmux_utils.h index f91170d3b07c..e22baf53f10c 100644 --- a/arch/arm/mach-tegra/nvrm/core/common/nvrm_pinmux_utils.h +++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_pinmux_utils.h @@ -44,9 +44,9 @@ #include "nvassert.h" #include "nvrm_hwintf.h" #include "nvodm_modules.h" -#include "ap15/ap15rm_private.h" -#include "ap16/arapb_misc.h" +// This is to disable trisate refcounting. +#define SKIP_TRISTATE_REFCNT 0 /* The pin mux code supports run-time trace debugging of all updates to the * pin mux & tristate registers by embedding strings (cast to NvU32s) into the @@ -81,80 +81,13 @@ typedef enum { PinMuxOpcode_SubroutinesDone = 2, } PinMuxConfigExtendOpcodes; -// When the state is BranchLink, this is the number of words to increment the current "PC" -#define MUX_ENTRY_0_BRANCH_ADDRESS_RANGE 31:2 -// The incr1 offset from TRISTATE_REG_A_0 to the pad group's tristate register -#define MUX_ENTRY_0_TS_OFFSET_RANGE 31:26 -// The bit position within the tristate register for the pad group -#define MUX_ENTRY_0_TS_SHIFT_RANGE 25:21 -// The incr1 offset from PIN_MUX_CTL_A_0 to the pad group's pin mux control register -#define MUX_ENTRY_0_MUX_CTL_OFFSET_RANGE 20:17 -// The bit position within the pin mux control register for the pad group -#define MUX_ENTRY_0_MUX_CTL_SHIFT_RANGE 16:12 -// The mask for the pad group -- expanded to 3b for forward-compatibility -#define MUX_ENTRY_0_MUX_CTL_MASK_RANGE 10:8 -// When a pad group needs to be owned (or disowned), this value is applied -#define MUX_ENTRY_0_MUX_CTL_SET_RANGE 7:5 -// This value is compared against, to determine if the pad group should be disowned -#define MUX_ENTRY_0_MUX_CTL_UNSET_RANGE 4:2 // for extended opcodes, this field is set with the extended opcode #define MUX_ENTRY_0_OPCODE_EXTENSION_RANGE 3:2 // The state for this entry #define MUX_ENTRY_0_STATE_RANGE 1:0 - #define MAX_NESTING_DEPTH 4 -/* This macro is used to generate 32b value to program the tristate& pad mux control - * registers for config/unconfig for a padgroup - */ -#define PIN_MUX_ENTRY(TSOFF,TSSHIFT,MUXOFF,MUXSHIFT,MUXMASK,MUXSET,MUXUNSET,STAT) \ - (NV_DRF_NUM(MUX, ENTRY, TS_OFFSET, TSOFF) | NV_DRF_NUM(MUX, ENTRY, TS_SHIFT, TSSHIFT) | \ - NV_DRF_NUM(MUX, ENTRY, MUX_CTL_OFFSET, MUXOFF) | NV_DRF_NUM(MUX, ENTRY, MUX_CTL_SHIFT, MUXSHIFT) | \ - NV_DRF_NUM(MUX, ENTRY,MUX_CTL_MASK, MUXMASK) | NV_DRF_NUM(MUX, ENTRY,MUX_CTL_SET, MUXSET) | \ - NV_DRF_NUM(MUX, ENTRY, MUX_CTL_UNSET,MUXUNSET) | NV_DRF_NUM(MUX, ENTRY, STATE,STAT)) - -// This is used to program the tristate & pad mux control registers for a pad group -#define CONFIG_VAL(TRISTATE_REG, MUXCTL_REG, PADGROUP, MUX) \ - (PIN_MUX_ENTRY(((APB_MISC_PP_TRISTATE_REG_##TRISTATE_REG##_0 - APB_MISC_PP_TRISTATE_REG_A_0)>>2), \ - APB_MISC_PP_TRISTATE_REG_##TRISTATE_REG##_0_Z_##PADGROUP##_SHIFT, \ - ((APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0 - APB_MISC_PP_PIN_MUX_CTL_A_0) >> 2), \ - APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_SHIFT, \ - APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_DEFAULT_MASK, \ - APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_##MUX, \ - 0, PinMuxConfig_Set)) - -/* This macro is used to compare a pad group against a potentially conflicting - * enum (where the conflict is caused by setting a new config), and to resolve the - * conflict by setting the conflicting pad group to a different, non-conflicting option. - * Read this as: if (PADGROUP) is equal to (CONFLICTMUX), replace it with (RESOLUTIONMUX) - */ -#define UNCONFIG_VAL(MUXCTL_REG, PADGROUP, CONFLICTMUX, RESOLUTIONMUX) \ - (PIN_MUX_ENTRY(0, 0, \ - ((APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0 - APB_MISC_PP_PIN_MUX_CTL_A_0) >> 2), \ - APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_SHIFT, \ - APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_DEFAULT_MASK, \ - APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_##RESOLUTIONMUX, \ - APB_MISC_PP_PIN_MUX_CTL_##MUXCTL_REG##_0_##PADGROUP##_SEL_##CONFLICTMUX, \ - PinMuxConfig_Unset)) - -#if NVRM_PINMUX_DEBUG_FLAG -#define CONFIG(TRISTATE_REG, MUXCTL_REG, PADGROUP, MUX) \ - (CONFIG_VAL(TRISTATE_REG, MUXCTL_REG, PADGROUP, MUX)), \ - (NvU32)(const void*)(#MUXCTL_REG "_0_" #PADGROUP "_SEL to " #MUX), \ - (NvU32)(const void*)(#TRISTATE_REG "_0_Z_" #PADGROUP) - -#define UNCONFIG(MUXCTL_REG, PADGROUP, CONFLICTMUX, RESOLUTIONMUX) \ - (UNCONFIG_VAL(MUXCTL_REG, PADGROUP, CONFLICTMUX, RESOLUTIONMUX)), \ - (NvU32)(const void*)(#MUXCTL_REG "_0_" #PADGROUP "_SEL from " #CONFLICTMUX " to " #RESOLUTIONMUX), \ - (NvU32)(const void*)(NULL) -#else -#define CONFIG(TRISTATE_REG, MUXCTL_REG, PADGROUP, MUX) \ - (CONFIG_VAL(TRISTATE_REG, MUXCTL_REG, PADGROUP, MUX)) -#define UNCONFIG(MUXCTL_REG, PADGROUP, CONFLICTMUX, RESOLUTIONMUX) \ - (UNCONFIG_VAL(MUXCTL_REG, PADGROUP, CONFLICTMUX, RESOLUTIONMUX)) -#endif - /* This macro is used for opcode entries in the tables */ #define PIN_MUX_OPCODE(_OP_) \ (NV_DRF_NUM(MUX,ENTRY,STATE,PinMuxConfig_OpcodeExtend) | \ @@ -177,22 +110,6 @@ typedef enum { (NV_DRF_NUM(MUX,ENTRY,STATE,PinMuxConfig_BranchLink) | \ NV_DRF_NUM(MUX,ENTRY,BRANCH_ADDRESS,(_ADDR_))) - -// The below entries define the table format for GPIO Port/Pin-to-Tristate register mappings -// Each table entry is 16b, and one is stored for every GPIO Port/Pin on the chip -#define MUX_GPIOMAP_0_TS_OFFSET_RANGE 15:10 -// Defines where in the 32b register the tristate control is located -#define MUX_GPIOMAP_0_TS_SHIFT_RANGE 4:0 - -#define TRISTATE_ENTRY(TSOFFS, TSSHIFT) \ - ((NvU16)(NV_DRF_NUM(MUX,GPIOMAP,TS_OFFSET,(TSOFFS)) | \ - NV_DRF_NUM(MUX,GPIOMAP,TS_SHIFT,(TSSHIFT)))) - -#define GPIO_TRISTATE(TRIREG,PADGROUP) \ - (TRISTATE_ENTRY(((APB_MISC_PP_TRISTATE_REG_##TRIREG##_0 - APB_MISC_PP_TRISTATE_REG_A_0)>>2), \ - APB_MISC_PP_TRISTATE_REG_##TRIREG##_0_Z_##PADGROUP##_SHIFT)) - - /** RmInitPinMux will program the pin mux settings for all IO controllers to * the ODM-selected value (or a safe reset value, if no value is defined in * the ODM query. @@ -240,7 +157,7 @@ void NvRmPinMuxConfigSetTristate( NvOdmIoModule IoModule, NvU32 Instance, NvU32 Configuration, - NvBool EnableTristate); + NvBool EnableTristate); /** NvRmSetGpioTristate will either enable or disable the tristate for GPIO ports. * RM client gpio should only call NvRmSetGpioTristate, @@ -258,7 +175,7 @@ void NvRmSetGpioTristate( NvBool EnableTristate); /** NvRmPrivRmModuleToOdmModule will perform the mapping of RM modules to - * ODM modules and instances, using the chip-specific mapping wherever + * ODM modules and instances, using the chip-specific mapping wherever * necessary */ NvU32 NvRmPrivRmModuleToOdmModule( NvU32 ChipId, @@ -269,15 +186,15 @@ NvU32 NvRmPrivRmModuleToOdmModule( // Forward declarations for all chip-specific helper functions NvError NvRmPrivAp15GetModuleInterfaceCaps( - NvOdmIoModule Module, - NvU32 Instance, - NvU32 Config, + NvOdmIoModule Module, + NvU32 Instance, + NvU32 Config, void* pCaps); NvError NvRmPrivAp16GetModuleInterfaceCaps( - NvOdmIoModule Module, - NvU32 Instance, - NvU32 Config, + NvOdmIoModule Module, + NvU32 Instance, + NvU32 Config, void* pCaps); NvError NvRmPrivAp20GetModuleInterfaceCaps( @@ -293,13 +210,13 @@ const NvU32*** NvRmAp16GetPinMuxConfigs(NvRmDeviceHandle hDevice); const NvU32*** NvRmAp20GetPinMuxConfigs(NvRmDeviceHandle hDevice); NvBool NvRmAp15GetPinGroupForGpio( - NvRmDeviceHandle hDevice, - NvU32 Port, - NvU32 Pin, + NvRmDeviceHandle hDevice, + NvU32 Port, + NvU32 Pin, NvU32 *pMapping); NvBool NvRmAp20GetPinGroupForGpio( - NvRmDeviceHandle hDevice, + NvRmDeviceHandle hDevice, NvU32 Port, NvU32 Pin, NvU32* pMapping); @@ -346,11 +263,11 @@ NvBool NvRmPrivAp20RmModuleToOdmModule( /** * Chip-specific functions to get SoC strap value for the given strap group. - * + * * @param hDevice The RM instance * @param StrapGroup Strap group to be read. * @pStrapValue A pointer to the returned strap group value. - * + * * @retval NvSuccess if strap value is read successfully * @retval NvError_NotSupported if the specified strap group does not * exist on the current SoC. @@ -367,6 +284,32 @@ NvRmAp20GetStraps( NvRmStrapGroup StrapGroup, NvU32* pStrapValue); +void NvRmPrivAp15SetPadTristates( + NvRmDeviceHandle hDevice, + const NvU32* Module, + NvU32 Config, + NvBool EnableTristate); + +void NvRmPrivAp15SetPinMuxCtl( + NvRmDeviceHandle hDevice, + const NvU32* Module, + NvU32 Config); + +void NvRmPrivAp15InitTrisateRefCount(NvRmDeviceHandle hDevice); + +const NvU32* +NvRmPrivAp15FindConfigStart( + const NvU32* Instance, + NvU32 Config, + NvU32 EndMarker); + +void +NvRmPrivAp15SetGpioTristate( + NvRmDeviceHandle hDevice, + NvU32 Port, + NvU32 Pin, + NvBool EnableTristate); + #ifdef __cplusplus } #endif /* __cplusplus */ |