diff options
4 files changed, 86 insertions, 6 deletions
diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/rm_common_slink_hw_private.c b/arch/arm/mach-tegra/nvrm/io/ap15/rm_common_slink_hw_private.c index 4351c859742e..87d9296d6250 100644 --- a/arch/arm/mach-tegra/nvrm/io/ap15/rm_common_slink_hw_private.c +++ b/arch/arm/mach-tegra/nvrm/io/ap15/rm_common_slink_hw_private.c @@ -211,6 +211,55 @@ SlinkHwSetDataFlow( pSlinkHwRegs->HwRegs.SlinkRegs.Command2); } +/** + * Set CS for slave communication. + */ +static void +SlinkHwSetSlaveCsId( + SerialHwRegisters *pSlinkHwRegs, + NvU32 CsId, + 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 (CsId) + { + 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); +} + + /** * Set the packet length and packed mode. @@ -459,6 +508,7 @@ void NvRmPrivSpiSlinkInitSlinkInterface(HwInterface *pSlinkInterface) pSlinkInterface->HwIsTransmitFifoFull = SlinkHwIsTransmitFifoFull; pSlinkInterface->HwSetTransferBitOrderFxn = SlinkHwSetTransferBitOrder; pSlinkInterface->HwStartTransferFxn = SlinkHwStartTransfer; + pSlinkInterface->HwSetSlaveCsIdFxn = SlinkHwSetSlaveCsId; pSlinkInterface->HwSetDataFlowFxn = SlinkHwSetDataFlow; pSlinkInterface->HwSetPacketLengthFxn = SlinkHwSetPacketLength; pSlinkInterface->HwSetDmaTransferSizeFxn = SlinkHwSetDmaTransferSize; diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_hw_private.c b/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_hw_private.c index 2768cec033bc..6fdfe02efb2c 100644 --- a/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_hw_private.c +++ b/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_hw_private.c @@ -364,7 +364,7 @@ SpiHwSetChipSelectLevelBasedOnPacket( } static void -SlinkHwSetCsSetupHoldTime( +SpiHwSetCsSetupHoldTime( SerialHwRegisters *pSlinkHwRegs, NvU32 CsSetupTimeInClocks, NvU32 CsHoldTimeInClocks) @@ -372,6 +372,15 @@ SlinkHwSetCsSetupHoldTime( NV_ASSERT(0); } +static void +SpiHwSetSlaveCsId( + SerialHwRegisters *pSlinkHwRegs, + NvU32 CsId, + NvBool IsHigh) +{ + NV_ASSERT(0); +} + /** * Set the packet length and packed mode. */ @@ -639,7 +648,8 @@ void NvRmPrivSpiSlinkInitSpiInterface(HwInterface *pSpiInterface) pSpiInterface->HwSetChipSelectDefaultLevelFxn = SpiHwSetChipSelectDefaultLevelFxn; pSpiInterface->HwSetChipSelectLevelFxn = SpiHwSetChipSelectLevel; pSpiInterface->HwSetChipSelectLevelBasedOnPacketFxn = SpiHwSetChipSelectLevelBasedOnPacket; - pSpiInterface->HwSetCsSetupHoldTime = SlinkHwSetCsSetupHoldTime; + pSpiInterface->HwSetCsSetupHoldTime = SpiHwSetCsSetupHoldTime; + pSpiInterface->HwSetSlaveCsIdFxn = SpiHwSetSlaveCsId; pSpiInterface->HwSetPacketLengthFxn = SpiHwSetPacketLength; pSpiInterface->HwSetDmaTransferSizeFxn = SpiHwSetDmaTransferSize; pSpiInterface->HwGetTransferdCountFxn = SpiHwGetTransferdCount; diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink.c b/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink.c index 5364fbaaeb95..26ceba05a8c2 100644 --- a/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink.c +++ b/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink.c @@ -1442,10 +1442,16 @@ SetChipSelectSignalLevel( if (hRmSpiSlink->IsMasterMode != hRmSpiSlink->HwRegs.IsMasterMode) hHwIntf->HwSetFunctionalModeFxn(&hRmSpiSlink->HwRegs, hRmSpiSlink->IsMasterMode); - if ((hRmSpiSlink->IsMasterMode) && ((IsOnlyUseSWCS) || (!hRmSpiSlink->HwRegs.IsHwChipSelectSupported) || - (!pDevInfo->CanUseHwBasedCs))) + IsHigh = (pDevInfo->ChipSelectActiveLow)? NV_FALSE: NV_TRUE; + if (!hRmSpiSlink->IsMasterMode) + { + hHwIntf->HwSetSlaveCsIdFxn(&hRmSpiSlink->HwRegs, ChipSelectId, IsHigh); + return NvSuccess; + } + + if ((IsOnlyUseSWCS) || (!hRmSpiSlink->HwRegs.IsHwChipSelectSupported) || + (!pDevInfo->CanUseHwBasedCs)) { - IsHigh = (pDevInfo->ChipSelectActiveLow)? NV_FALSE: NV_TRUE; hHwIntf->HwSetChipSelectLevelFxn(&hRmSpiSlink->HwRegs, ChipSelectId, IsHigh); hRmSpiSlink->IsChipSelConfigured = NV_TRUE; hRmSpiSlink->IsCurrentlySwBasedChipSel = NV_TRUE; @@ -1458,9 +1464,14 @@ SetChipSelectSignalLevel( } else { + IsHigh = (pDevInfo->ChipSelectActiveLow)? NV_TRUE: NV_FALSE; + if (!hRmSpiSlink->IsMasterMode) + { + hHwIntf->HwSetSlaveCsIdFxn(&hRmSpiSlink->HwRegs, ChipSelectId, IsHigh); + return NvSuccess; + } if (IsOnlyUseSWCS || hRmSpiSlink->IsCurrentlySwBasedChipSel) { - IsHigh = (pDevInfo->ChipSelectActiveLow)? NV_TRUE: NV_FALSE; hHwIntf->HwSetChipSelectLevelFxn(&hRmSpiSlink->HwRegs, ChipSelectId, IsHigh); if (hRmSpiSlink->HwRegs.IdleSignalMode != hRmSpiSlink->HwRegs.CurrSignalMode) hHwIntf->HwSetSignalModeFxn(&hRmSpiSlink->HwRegs, hRmSpiSlink->HwRegs.IdleSignalMode); diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink_hw_private.h b/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink_hw_private.h index 6cd3015de09f..7e88837d809f 100644 --- a/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink_hw_private.h +++ b/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink_hw_private.h @@ -295,6 +295,15 @@ typedef struct NvU32 CsHoldTimeInClocks); /** + * Set active CS id for slave. + */ + void + (* HwSetSlaveCsIdFxn)( + SerialHwRegisters *pHwRegs, + NvU32 CsId, + NvBool IsHigh); + + /** * Set the packet length. */ void |