void
NvRmPrivAp20EmcMonitorsStart(
    const NvRmDfs* pDfs,
    const NvRmDfsFrequencies* pDfsKHz,
    const NvU32 IntervalMs)
{
    NvU32 RegValue, SavedRegValue;
    void* pEmcRegs = pDfs->Modules[NvRmDfsModuleId_Emc].pBaseReg;

    // EMC sample period is specified in EMC clock cycles, accuracy 0-16 cycles.
    #define MEAN_EMC_LIMIT_ERROR (8)
    NvU32 cycles = IntervalMs * pDfsKHz->Domains[NvRmDfsClockId_Emc] +
                    MEAN_EMC_LIMIT_ERROR;
    /*
     * Start EMC power monitor for the next sample period: clear EMC counters,
     * set sample interval limit in EMC cycles, enable monitoring. Monitor is
     * counting EMC 1x clock cycles while any memory access is detected. 
     */
    SavedRegValue = NV_EMC_REGR(pEmcRegs, STAT_CONTROL);
    RegValue = NV_FLD_SET_DRF_DEF(EMC, STAT_CONTROL, PWR_GATHER, CLEAR, SavedRegValue);
    NV_EMC_REGW(pEmcRegs, STAT_CONTROL, RegValue);

    RegValue = NV_DRF_NUM(EMC, STAT_PWR_CLOCK_LIMIT, PWR_CLOCK_LIMIT, cycles);
    NV_EMC_REGW(pEmcRegs, STAT_PWR_CLOCK_LIMIT, RegValue);

    RegValue = NV_FLD_SET_DRF_DEF(EMC, STAT_CONTROL, PWR_GATHER, ENABLE, SavedRegValue);
    NV_EMC_REGW(pEmcRegs, STAT_CONTROL, RegValue);
}
void
NvRmPrivAp20EmcMonitorsRead(
    const NvRmDfs* pDfs,
    const NvRmDfsFrequencies* pDfsKHz,
    NvRmDfsIdleData* pIdleData)
{
    NvU32 RegValue, TotalClocks;
    NvU32 CountShift = pDfs->Modules[NvRmDfsModuleId_Emc].Scale;
    void* pEmcRegs = pDfs->Modules[NvRmDfsModuleId_Emc].pBaseReg;

    /*
     * Read EMC monitor: disable it (=stop, the readings are preserved), and
     * determine idle count based on total and active clock counts. Monitor
     * readings are multiplied by 2^M factor to determine active count, where
     * power M depends on DRAM type and bus width. Store result in the idle
     * data packet.
     */
    RegValue = NV_EMC_REGR(pEmcRegs, STAT_CONTROL);
    RegValue = NV_FLD_SET_DRF_DEF(EMC, STAT_CONTROL, PWR_GATHER, DISABLE, RegValue);
    NV_EMC_REGW(pEmcRegs, STAT_CONTROL, RegValue);

    RegValue = NV_EMC_REGR(pEmcRegs, STAT_PWR_CLOCKS);
    TotalClocks = NV_DRF_VAL(EMC, STAT_PWR_CLOCKS, PWR_CLOCKS, RegValue);
    RegValue = NV_EMC_REGR(pEmcRegs, STAT_PWR_COUNT);
    RegValue = NV_DRF_VAL(EMC, STAT_PWR_COUNT, PWR_COUNT, RegValue) << CountShift;

    pIdleData->Readings[NvRmDfsClockId_Emc] = 
        (TotalClocks > RegValue) ? (TotalClocks - RegValue) : 0;
}
/**
 * Initialize the slink register.
 */
static void
SlinkHwRegisterInitialize(
    NvU32 SlinkInstanceId,
    SerialHwRegisters *pSlinkHwRegs)
{
    NvU32 CommandReg1;
    pSlinkHwRegs->InstanceId = SlinkInstanceId;
    pSlinkHwRegs->pRegsBaseAdd = NULL;
    pSlinkHwRegs->RegBankSize = 0;
    pSlinkHwRegs->HwTxFifoAdd = SLINK_TX_FIFO_0;
    pSlinkHwRegs->HwRxFifoAdd = SLINK_RX_FIFO_0;
    pSlinkHwRegs->IsPackedMode = NV_FALSE;
    pSlinkHwRegs->PacketLength = 1;
    pSlinkHwRegs->CurrSignalMode = NvOdmQuerySpiSignalMode_Invalid;
    pSlinkHwRegs->MaxWordTransfer = MAX_SLINK_FIFO_DEPTH;
    pSlinkHwRegs->IsLsbFirst = NV_FALSE;
    pSlinkHwRegs->IsMasterMode = NV_TRUE;
    pSlinkHwRegs->IsNonWordAlignedPackModeSupported = NV_FALSE;
    pSlinkHwRegs->IsHwChipSelectSupported = NV_FALSE;

    CommandReg1 = NV_RESETVAL(SLINK, COMMAND);

    // Initialize the chip select bits to select the s/w only
    CommandReg1 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, CS_SW, SOFT, CommandReg1);

    // Set chip select to normal high level. (inverted polarity).
    CommandReg1 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND,  CS_VALUE, HIGH, CommandReg1);

    CommandReg1 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, M_S, MASTER, CommandReg1);

    if (pSlinkHwRegs->IsIdleDataOutHigh)
    {
        CommandReg1 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, ACTIVE_SDA, DRIVE_HIGH, CommandReg1);
        CommandReg1 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, IDLE_SDA, DRIVE_HIGH, CommandReg1);
    }
    else
    {
        CommandReg1 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, ACTIVE_SDA, DRIVE_LOW, CommandReg1);
        CommandReg1 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, IDLE_SDA, DRIVE_LOW, CommandReg1);
    }
    pSlinkHwRegs->HwRegs.SlinkRegs.Command1 = CommandReg1;
    pSlinkHwRegs->HwRegs.SlinkRegs.Command2 = NV_RESETVAL(SLINK, COMMAND2);
    pSlinkHwRegs->HwRegs.SlinkRegs.Status = NV_RESETVAL(SLINK, STATUS);
    pSlinkHwRegs->HwRegs.SlinkRegs.DmaControl = NV_RESETVAL(SLINK, DMA_CTL);
}
NvError NvRmPrivAp20EmcMonitorsInit(NvRmDfs* pDfs)
{
    NvU32 RegValue;
    void* pEmcRegs = pDfs->Modules[NvRmDfsModuleId_Emc].pBaseReg;
    NV_ASSERT(pEmcRegs);

    /*
     * EMC power management monitor belongs to EMC module - just reset it,
     * and do not touch anything else in EMC.
     */ 
    RegValue = NV_EMC_REGR(pEmcRegs, STAT_CONTROL);
    RegValue = NV_FLD_SET_DRF_DEF(EMC, STAT_CONTROL, PWR_GATHER, RST, RegValue);
    NV_EMC_REGW(pEmcRegs, STAT_CONTROL, RegValue);

    /*
    * EMC active clock cycles = EMC monitor reading * 2^M, where M depends
    * on DRAM type and bus width. Power M is stored as EMC readouts scale
    */
    #define COUNT_SHIFT_DDR1_X32 (1)
    RegValue = NV_EMC_REGR(pEmcRegs, FBIO_CFG5);
    switch (NV_DRF_VAL(EMC, FBIO_CFG5, DRAM_TYPE, RegValue))
    {
        case EMC_FBIO_CFG5_0_DRAM_TYPE_DDR1:
        case EMC_FBIO_CFG5_0_DRAM_TYPE_LPDDR2:
        case EMC_FBIO_CFG5_0_DRAM_TYPE_DDR2:
            pDfs->Modules[NvRmDfsModuleId_Emc].Scale = COUNT_SHIFT_DDR1_X32;
            break;
        default:
            NV_ASSERT(!"Not supported DRAM type");
    }
    if (NV_DRF_VAL(EMC, FBIO_CFG5, DRAM_WIDTH, RegValue) ==
        EMC_FBIO_CFG5_0_DRAM_WIDTH_X16)
    {
        pDfs->Modules[NvRmDfsModuleId_Emc].Scale++;
    }
    return NvSuccess;
}
/**
 * Set the chip select signal level.
 */
static void
SlinkHwSetChipSelectLevel(
    SerialHwRegisters *pSlinkHwRegs,
    NvU32 ChipSelectId,
    NvBool IsHigh)
{
    NvU32 CommandReg1 = pSlinkHwRegs->HwRegs.SlinkRegs.Command1;
    NvU32 CommandReg2 = pSlinkHwRegs->HwRegs.SlinkRegs.Command2;

    // Set the chip select level.
    if (IsHigh)
        CommandReg1 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND,  CS_VALUE, LOW, CommandReg1);
    else
        CommandReg1 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND,  CS_VALUE, HIGH, CommandReg1);

    switch (ChipSelectId)
    {
        case 0:
            CommandReg2 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND2, SS_EN, CS0, CommandReg2);
            break;

        case 1:
            CommandReg2 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND2, SS_EN, CS1, CommandReg2);
            break;

        case 2:
            CommandReg2 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND2, SS_EN, CS2, CommandReg2);
            break;

        case 3:
            CommandReg2 = NV_FLD_SET_DRF_DEF(SLINK, COMMAND2, SS_EN, CS3, CommandReg2);
            break;

        default:
            NV_ASSERT(!"Invalid ChipSelectId");
    }
    pSlinkHwRegs->HwRegs.SlinkRegs.Command1 = CommandReg1;
    pSlinkHwRegs->HwRegs.SlinkRegs.Command2 = CommandReg2;

    SLINK_REG_WRITE32(pSlinkHwRegs->pRegsBaseAdd, COMMAND2,
                            pSlinkHwRegs->HwRegs.SlinkRegs.Command2);
    SLINK_REG_WRITE32(pSlinkHwRegs->pRegsBaseAdd, COMMAND,
                            pSlinkHwRegs->HwRegs.SlinkRegs.Command1);
}
Example #6
0
void t30_UartD_Init(void)
{
    NvU32 RegData;

    // Initialization is responsible for correct pin mux configuration
    // It also needs to wait for the correct osc frequency to be known
    // IMPORTANT, there is some unspecified logic in the UART that always 
    // operate off PLLP_out3, mail from Robert Quan says that correct operation
    // of UART without starting PLLP requires
    // - to put PLLP in bypass
    // - to override the PLLP_ou3 divider to be 1 (or put in bypass)
    // This is done like that here to avoid any dependence on PLLP analog circuitry 
    // operating correctly

    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_BASE_0);
    RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_BASE, PLLP_BYPASS, ENABLE);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_BASE_0, RegData);
    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_OUTB_0);
    RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_OUTB,
        PLLP_OUT3_OVRRIDE, ENABLE);
    RegData |= NV_DRF_NUM(CLK_RST_CONTROLLER,
        PLLP_OUTB, PLLP_OUT3_RATIO, 0);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_OUTB_0, RegData);

    // Set up the pinmuxes to bring UARTD out on ULPI_clk and ULPI_dir
    // for waluigi T30.  All alternate mappings of UARTD are set to select an input other than UARTD.
    //
    //     GMI_AD16 => Alternate 1 ( SPI4 instead of UD3_TXD)
    //     GMI_AD17 => Alternate 1 ( SPI4 instead of UD3_RXD)
    //     ULPI_CLK  =>Alternate 2 (UD3_TXD)
    //     ULPI_DIR  =>Alternate 2 UD3_RXD)
    //
    // Last reviewed on 08/27/2010
    SET_PIN(GMI_A16,PM,SPI4) ;
    SET_PIN(GMI_A17,PM,SPI4) ;
    SET_PIN(ULPI_CLK,PM,UARTD) ;
    SET_PIN(ULPI_DIR,PM,UARTD) ;

    // Enable the pads.
    SET_PIN(ULPI_CLK, TRISTATE, NORMAL);
    SET_PIN(ULPI_DIR, TRISTATE, NORMAL);

    // enable UART D clock, toggle reset  
    RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_CLK_OUT_ENB_U_0);
    RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, CLK_OUT_ENB_U, 
        CLK_ENB_UARTD, ENABLE);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
                       CLK_RST_CONTROLLER_CLK_OUT_ENB_U_0, RegData);
    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_U_0);
    RegData  = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_U,
        SWR_UARTD_RST, ENABLE, RegData);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_U_0, RegData);
    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_U_0);
    RegData  = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_U,
        SWR_UARTD_RST, DISABLE, RegData);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_U_0, RegData);

    // Then there is the specific set up for UART itself, including the clock configuration.
    // configure at top for source & configure the divider, internal to uart for obscure reasons
    // when UARTD_DIV_ENB is enable DLL/DLLM programming is not required
    //.Refer to the CLK_SOURCE_UARTD reg description in arclk_rst
    // UARTD_DIV_ENB is disabled as new divisor logic is not enabled on FPGA Bug #739606 
#if 0
    NV_WRITE32(NV_ADDRESS_MAP_CAR_BASE+
        CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0 ,
        (CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_CLK_SRC_CLK_M <<
        CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_CLK_SRC_SHIFT) |
        (CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_DIV_ENB_DISABLE <<
        CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_DIV_ENB_SHIFT) |
        0);
#endif

}
Example #7
0
void t30_UartC_Init(void)
{
    NvU32 RegData;

    // Initialization is responsible for correct pin mux configuration
    // It also needs to wait for the correct osc frequency to be known
    // IMPORTANT, there is some unspecified logic in the UART that always 
    // operate off PLLP_out3, mail from Robert Quan says that correct operation
    // of UART without starting PLLP requires
    // - to put PLLP in bypass
    // - to override the PLLP_ou3 divider to be 1 (or put in bypass)
    // This is done like that here to avoid any dependence on PLLP analog circuitry 
    // operating correctly

    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_BASE_0);
    RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_BASE, PLLP_BYPASS, ENABLE);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_BASE_0, RegData);
    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_OUTB_0);
    RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_OUTB,
        PLLP_OUT3_OVRRIDE, ENABLE);
    RegData |= NV_DRF_NUM(CLK_RST_CONTROLLER,
        PLLP_OUTB, PLLP_OUT3_RATIO, 0);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_OUTB_0, RegData);

    // Set up the pinmuxes to bring UARTC out on uart3_txd and uart_rxd
    // for oregon T30.
    //
    //     UART3_TXD  =>primary 0 (UC3_TXD)
    //     UART3_RXD  =>primary 0(UC3_RXD)
    //
    SET_PIN(UART3_TXD,PM,UARTC) ;
    SET_PIN(UART3_RXD,PM,UARTC) ;
//    SET_PIN(UART3_CTS_N,PM,UARTC) ;
//    SET_PIN(UART3_RTS_N,PM,UARTC) ;

    // Enable the pads.
    SET_PIN(UART3_TXD, TRISTATE, NORMAL);
    SET_PIN(UART3_RXD, TRISTATE, NORMAL);

    // enable UART C clock, toggle reset  
    RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_CLK_OUT_ENB_H_0);
    RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, CLK_OUT_ENB_H, 
        CLK_ENB_UARTC, ENABLE);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
                       CLK_RST_CONTROLLER_CLK_OUT_ENB_H_0, RegData);
    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_H_0);
    RegData  = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_H,
        SWR_UARTC_RST, ENABLE, RegData);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_H_0, RegData);
    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_H_0);
    RegData  = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_H,
        SWR_UARTC_RST, DISABLE, RegData);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_H_0, RegData);

    // Then there is the specific set up for UART itself, including the clock configuration.
    // configure at top for source & configure the divider, internal to uart for obscure reasons
    // when UARTC_DIV_ENB is enable DLL/DLLM programming is not required
    //.Refer to the CLK_SOURCE_UARTD reg description in arclk_rst
    // UARTD_DIV_ENB is disabled as new divisor logic is not enabled on FPGA Bug #739606 
#if 0
    NV_WRITE32(NV_ADDRESS_MAP_CAR_BASE+
        CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0 ,
        (CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_CLK_SRC_CLK_M <<
        CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_CLK_SRC_SHIFT) |
        (CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_DIV_ENB_DISABLE <<
        CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_DIV_ENB_SHIFT) |
        0);
#endif

}
Example #8
0
void t30_UartA_Init(void)
{
    NvU32 RegData;

    // Initialization is responsible for correct pin mux configuration
    // It also needs to wait for the correct osc frequency to be known
    // IMPORTANT, there is some unspecified logic in the UART that always 
    // operate off PLLP_out3, mail from Robert Quan says that correct operation
    // of UART without starting PLLP requires
    // - to put PLLP in bypass
    // - to override the PLLP_ou3 divider to be 1 (or put in bypass)
    // This is done like that here to avoid any dependence on PLLP analog circuitry 
    // operating correctly

    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_BASE_0);
    RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_BASE, PLLP_BYPASS, ENABLE);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_BASE_0, RegData);
    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_OUTB_0);
    RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_OUTB,
        PLLP_OUT3_OVRRIDE, ENABLE);
    RegData |= NV_DRF_NUM(CLK_RST_CONTROLLER,
        PLLP_OUTB, PLLP_OUT3_RATIO, 0);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_PLLP_OUTB_0, RegData);

    // Set up the pinmuxes to bring UARTA out on ULPI_DATA0 and ULPI_DATA1
    // for T30.  All alternate mappings of UARTA are set to select an input other than UARTA.
    //
    //     UART2_RTS_N => Alternate 3 ( SPI4 instead of UA3_TXD)
    //     UART2_CTS_N => Alternate 3 ( SPI4 instead of UA3_TXD)
    //     ULPI_DATA0  =>Alternate 2 (UA3_TXD)
    //     ULPI_DATA1  =>Alternate 2 UA3_RXD)
    //     SDMMC1_DAT3 => Primary     (SDMMC1_DAT3 instead of UA3_TXD)
    //     SDMMC1_DAT2 => Primary     (SDMMC1_DAT2 instead of UA3_RXD)
    //     GPIO_PU0    => Alternate 2 (GMI_A6 instead of UA3_TXD)
    //     GPIO_PU1    => Alternate 2 (GMI_A7 instead of UA3_RXD)
    //     SDMMC3_CLK  => Alternate 2 (SDMMC3_SCLK instead of UA3_TXD)
    //     SDMMC3_CMD  => Alternate 2 (SDMMC3_CMD instead of UA3_RXD)
    //
    // Last reviewed on 08/27/2010
    SET_PIN(UART2_RTS_N,PM,SPI4) ;
    SET_PIN(UART2_CTS_N,PM,SPI4) ;
    SET_PIN(ULPI_DATA0,PM,UARTA) ;
    SET_PIN(ULPI_DATA1,PM,UARTA) ;
    SET_PIN(SDMMC1_DAT3,PM,SDMMC1) ;
    SET_PIN(SDMMC1_DAT2,PM,SDMMC1) ;
    SET_PIN(GPIO_PU0,PM,GMI) ;
    SET_PIN(GPIO_PU1,PM,GMI) ;
    SET_PIN(SDMMC3_CLK,  PM, SDMMC3);
    SET_PIN(SDMMC3_CMD,  PM, SDMMC3);
    // Enable the pads.
    SET_PIN(ULPI_DATA0, TRISTATE, NORMAL);
    SET_PIN(ULPI_DATA1, TRISTATE, NORMAL);

    // enable UART A clock, toggle reset  
    RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_CLK_OUT_ENB_L_0);
    RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, CLK_OUT_ENB_L, 
        CLK_ENB_UARTA, ENABLE);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
                       CLK_RST_CONTROLLER_CLK_OUT_ENB_L_0, RegData);
    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_L_0);
    RegData  = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L,
        SWR_UARTA_RST, ENABLE, RegData);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegData);
    RegData  = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_L_0);
    RegData  = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L,
        SWR_UARTA_RST, DISABLE, RegData);
    NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE +
        CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegData);

    // Then there is the specific set up for UART itself, including the clock configuration.
    // configure at top for source & configure the divider, internal to uart for obscure reasons
    // when UARTA_DIV_ENB is enable DLL/DLLM programming is not required
    //.Refer to the CLK_SOURCE_UARTA reg description in arclk_rst
    // UARTA_DIV_ENB is disabled as new divisor logic is not enabled on FPGA Bug #739606 
    NV_WRITE32(NV_ADDRESS_MAP_CAR_BASE+
        CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0 ,
        (CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0_UARTA_CLK_SRC_CLK_M <<
        CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0_UARTA_CLK_SRC_SHIFT) |
        (CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0_UARTA_DIV_ENB_DISABLE <<
        CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0_UARTA_DIV_ENB_SHIFT) |
        0);

}
/**
 * Set the signal mode of communication whether this is the mode  0, 1, 2 or 3.
 */
static void
SlinkHwSetSignalMode(
    SerialHwRegisters *pSlinkHwRegs,
    NvOdmQuerySpiSignalMode SignalMode)
{
    NvU32 CommandReg = pSlinkHwRegs->HwRegs.SlinkRegs.Command1;
    switch (SignalMode)
    {
        case NvOdmQuerySpiSignalMode_0:
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, ACTIVE_SCLK,
                DRIVE_LOW, CommandReg);
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, IDLE_SCLK,
                DRIVE_LOW, CommandReg);
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, CK_SDA, FIRST_CLK_EDGE,
                CommandReg);
            break;

        case NvOdmQuerySpiSignalMode_1:
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, ACTIVE_SCLK,
                DRIVE_LOW, CommandReg);
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, IDLE_SCLK,
                DRIVE_LOW, CommandReg);
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, CK_SDA, SECOND_CLK_EDGE,
                CommandReg);
            break;

        case NvOdmQuerySpiSignalMode_2:
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, ACTIVE_SCLK,
                DRIVE_HIGH, CommandReg);
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, IDLE_SCLK,
                DRIVE_HIGH, CommandReg);
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, CK_SDA, FIRST_CLK_EDGE,
                CommandReg);
            break;
        case NvOdmQuerySpiSignalMode_3:
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, ACTIVE_SCLK,
                DRIVE_HIGH, CommandReg);
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, IDLE_SCLK,
                DRIVE_HIGH, CommandReg);
            CommandReg = NV_FLD_SET_DRF_DEF(SLINK, COMMAND, CK_SDA, SECOND_CLK_EDGE,
                CommandReg);
            break;
        default:
            NV_ASSERT(!"Invalid SignalMode");

    }
    pSlinkHwRegs->HwRegs.SlinkRegs.Command1 = CommandReg;
    SLINK_REG_WRITE32(pSlinkHwRegs->pRegsBaseAdd, COMMAND, CommandReg);
    pSlinkHwRegs->CurrSignalMode = SignalMode;
}