summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2010-08-21 00:13:54 +0530
committerBharat Nihalani <bnihalani@nvidia.com>2010-08-30 01:35:19 -0700
commit66ca1f58150a96167143b1f43f76110d770f6251 (patch)
treef623837c3b5816bd4122b431962ea081c41e8402
parent8e6626c08ef0a8f99d716f5b8e6a0e2191616719 (diff)
[arm/tegra] spi: Configuring desired CS for slave communication.
The desired chipselect id which is passed from the slave transaction api is not getting set and so it was not possible to do slave communication on different CS other than 0. Fixing this issue. Change-Id: I91d3b10b7ec01af98a4912ed05f9068491626ba9 Reviewed-on: http://git-master/r/5425 Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> Tested-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/rm_common_slink_hw_private.c50
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_hw_private.c14
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink.c19
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink_hw_private.h9
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