summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink.c')
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/rm_spi_slink.c575
1 files changed, 330 insertions, 245 deletions
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 59cd15dae155..2e191e863428 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
@@ -32,11 +32,9 @@
/**
* @file
- * @brief <b>NVIDIA Driver Development Kit:
- * Spi Driver implementation</b>
+ * @brief <b>NVIDIA Driver Development Kit: Spi Driver implementation</b>
*
- * @b Description: Implementation of the NvRm SPI API of the OAL and non-OAL
- * version.
+ * @b Description: Implementation of the NvRm SPI API for linux.
*
*/
@@ -44,7 +42,6 @@
#include "nvrm_power.h"
#include "nvrm_interrupt.h"
#include "nvrm_memmgr.h"
-#include "nvrm_dma.h"
#include "nvodm_query.h"
#include "nvodm_query_discovery.h"
#include "rm_spi_slink_hw_private.h"
@@ -58,6 +55,9 @@
#include "nvrm_priv_ap_general.h"
#include "ap15/ap15rm_private.h"
+#include "linux/module.h"
+#include "mach/dma.h"
+
// Combined maximum spi/slink controllers
#define MAX_SPI_SLINK_INSTANCE (MAX_SLINK_CONTROLLERS + MAX_SPI_CONTROLLERS)
@@ -69,15 +69,7 @@
// The maximum slave size request in words. Maximum 64KB/64K packet
#define MAXIMUM_SLAVE_TRANSFER_WORD (1 << (16-2))
-// Maximum number which is return by the NvOsGetTimeMS().
-// For NV_OAL, NvOsGetTimeMS() returns the MicroSecond Timer count divided by 1000.
-// and microsecond timer have the maximum count of 0xFFFFFFFF.
-// For Non-NV_OAL, it returned maximum of 0xFFFFFFFF
-#if NV_OAL
-#define MAX_TIME_IN_MS (0xFFFFFFFF/1000)
-#else
#define MAX_TIME_IN_MS 0xFFFFFFFF
-#endif
// The maximum request size for one transaction using the dma
enum {DEFAULT_DMA_BUFFER_SIZE = (0x4000)}; // 16KB
@@ -96,6 +88,10 @@ enum {SLINK_POLLING_HIGH_THRESOLD = 64};
// The dma buffer alignment requirement.
enum {DMA_BUFFER_ALIGNMENT = 0x10};
+// Slink isr comes first then dma isr and so dma complete can be call later
+// Wait for dma complete call back to process the transferred data
+#define LATENCY_BETWEEN_SLINK_ISR_DMA_COMPLETE_MS 1000
+
// Combined the Details of the current transfer information.
typedef struct
{
@@ -153,19 +149,20 @@ typedef struct NvRmSpiRec
// completion.
NvOsSemaphoreHandle hSynchSema;
- // Mutex to access this channel to provide the mutual exclusion.
- NvOsMutexHandle hChannelAccessMutex;
+ // Synchronous sempahore Id which need to be signalled on Tx transfer
+ // completion.
+ NvOsSemaphoreHandle hSynchTxDmaSema;
- // Tells whether the dma mode is supported or not.
- NvBool IsApbDmaAllocated;
+ // Synchronous sempahore Id which need to be signalled on Rx transfer
+ // completion.
+ NvOsSemaphoreHandle hSynchRxDmaSema;
- NvU32 TransCountFromLastDmaUsage;
- // Read dma handle.
- NvRmDmaHandle hRmRxDma;
+ // Mutex to access this channel to provide the mutual exclusion.
+ NvOsMutexHandle hChannelAccessMutex;
- // Write dma handle.
- NvRmDmaHandle hRmTxDma;
+ // Number of transfer count from last dma usage.
+ NvU32 TransCountFromLastDmaUsage;
// Memory handle to create the uncached memory.
NvRmMemHandle hRmMemory;
@@ -185,15 +182,24 @@ typedef struct NvRmSpiRec
// Current Dma transfer size for the Rx and tx
NvU32 DmaBufferSize;
- // Dma request for Tx
- NvRmDmaClientBuffer TxDmaReq;
-
- // Dma request for rx
- NvRmDmaClientBuffer RxDmaReq;
+ // Tells whether the dma mode is supported or not.
+ NvBool IsApbDmaAllocated;
// Tell whether it is using the apb dma for the transfer or not.
NvBool IsUsingApbDma;
+ // Dma request for Tx
+ struct tegra_dma_req TxDmaReq;
+
+ // Tx dma channel handle.
+ struct tegra_dma_channel *hTxDma;
+
+ // Dma request for Rx
+ struct tegra_dma_req RxDmaReq;
+
+ // Rx dma channel handle
+ struct tegra_dma_channel *hRxDma;
+
// Buffer which will be used when cpu does the data receving.
NvU32 *pRxCpuBuffer;
@@ -248,6 +254,8 @@ typedef struct NvRmSpiRec
// Tells whether frequency is boosted or not.
NvBool IsFreqBoosted;
+
+ NvBool IsIntDoneDue;
} NvRmSpi;
/**
@@ -275,6 +283,21 @@ static NvRmPrivSpiSlinkInfo s_SpiSlinkInfo;
static HwInterface s_SpiHwInterface;
static HwInterface s_SlinkHwInterface;
+static const NvU32 s_Slink_Trigger[] = {
+ TEGRA_DMA_REQ_SEL_SL2B1,
+ TEGRA_DMA_REQ_SEL_SL2B2,
+ TEGRA_DMA_REQ_SEL_SL2B3,
+ TEGRA_DMA_REQ_SEL_SL2B4,
+};
+
+static const NvU32 s_Spi_Trigger[] = {
+ TEGRA_DMA_REQ_SEL_SPI,
+};
+
+// Way to reset the semaphore count.
+#define ResetSemaphoreCount(hSema) \
+ while(NvOsSemaphoreWaitTimeout(hSema, 0) != NvError_Timeout)
+
/**
* Get the interfacing property for the device connected to given chip select Id.
* Returns whether this is supported or not.
@@ -346,7 +369,6 @@ SpiSlinkIsPmuInterface(
return NV_FALSE;
}
-
/**
* Create the dma buffer memory handle.
*/
@@ -368,8 +390,7 @@ CreateDmaBufferMemoryHandle(
// Allocates the memory from the sdram
if (!Error)
- Error = NvRmMemAlloc(hNewMemHandle, NULL,
- 0, DMA_BUFFER_ALIGNMENT,
+ Error = NvRmMemAlloc(hNewMemHandle, NULL, 0, DMA_BUFFER_ALIGNMENT,
NvOsMemAttribute_Uncached);
// Pin the memory allocation so that it should not move by memory manager.
@@ -434,7 +455,7 @@ CreateDmaTransferBuffer(
// Create the dma buffer memory for receive and transmit.
// It will be double of the OneBufferSize
Error = CreateDmaBufferMemoryHandle(hRmDevice, &hRmMemory, &BuffPhysAddr,
- (OneBufferSize <<1));
+ (OneBufferSize <<1));
if (!Error)
{
// 0 to OneBufferSize-1 is buffer 1 and OneBufferSize to 2*OneBufferSize
@@ -484,6 +505,70 @@ DestroyDmaTransferBuffer(
DestroyDmaBufferMemoryHandle(hRmMemory);
}
}
+static NvError AllocateDmas(NvRmSpiHandle hRmSpiSlink)
+{
+ hRmSpiSlink->TransCountFromLastDmaUsage = 0;
+ hRmSpiSlink->IsApbDmaAllocated = NV_FALSE;
+ hRmSpiSlink->hRxDma = NULL;
+ hRmSpiSlink->hTxDma = NULL;
+
+ hRmSpiSlink->hRxDma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
+ if (hRmSpiSlink->hRxDma)
+ {
+ hRmSpiSlink->hTxDma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
+ if (!hRmSpiSlink->hTxDma)
+ {
+ tegra_dma_free_channel(hRmSpiSlink->hRxDma);
+ hRmSpiSlink->hRxDma = NULL;
+ return NvError_DmaChannelNotAvailable;
+ }
+ hRmSpiSlink->IsApbDmaAllocated = NV_TRUE;
+ }
+ return NvSuccess;
+}
+
+static void FreeDmas(NvRmSpiHandle hRmSpiSlink)
+{
+ if (hRmSpiSlink->hRxDma)
+ tegra_dma_free_channel(hRmSpiSlink->hRxDma);
+
+ if (hRmSpiSlink->hTxDma)
+ tegra_dma_free_channel(hRmSpiSlink->hTxDma);
+
+ hRmSpiSlink->TransCountFromLastDmaUsage = 0;
+ hRmSpiSlink->IsApbDmaAllocated = NV_FALSE;
+ hRmSpiSlink->hRxDma = NULL;
+ hRmSpiSlink->hTxDma = NULL;
+}
+static NvError StartDma(struct tegra_dma_channel *ch, struct tegra_dma_req *req)
+{
+ if (tegra_dma_enqueue_req(ch, req))
+ {
+ pr_debug("Could not enqueue Rx DMA req\n");
+ return NvError_BadParameter;
+ }
+ return NvSuccess;
+}
+static void AbortDma(struct tegra_dma_channel *ch)
+{
+ tegra_dma_dequeue(ch);
+}
+
+static void SpiTxDmaCompleteCallback(struct tegra_dma_req *req)
+{
+ NvRmSpiHandle hRmSpiSlink = req->dev;
+ if (req->status == -TEGRA_DMA_REQ_ERROR_ABORTED)
+ return;
+ NvOsSemaphoreSignal(hRmSpiSlink->hSynchTxDmaSema);
+}
+
+static void SpiRxDmaCompleteCallback(struct tegra_dma_req *req)
+{
+ NvRmSpiHandle hRmSpiSlink = req->dev;
+ if (req->status == -TEGRA_DMA_REQ_ERROR_ABORTED)
+ return;
+ NvOsSemaphoreSignal(hRmSpiSlink->hSynchRxDmaSema);
+}
static NvBool HandleTransferCompletion(NvRmSpiHandle hRmSpiSlink)
{
@@ -578,9 +663,19 @@ static void SpiSlinkIsr(void *args)
NvRmSpiHandle hRmSpiSlink = args;
NvBool IsTransferCompleted;
+ /* If apb dma is used then postpone the handling in caller context */
+ if (hRmSpiSlink->IsUsingApbDma)
+ {
+ NvOsSemaphoreSignal(hRmSpiSlink->hSynchSema);
+ hRmSpiSlink->IsIntDoneDue = NV_TRUE;
+ return;
+ }
+
+ /* Handle the transfer completion here only for non dma transfer */
IsTransferCompleted = HandleTransferCompletion(hRmSpiSlink);
if (IsTransferCompleted)
NvOsSemaphoreSignal(hRmSpiSlink->hSynchSema);
+ hRmSpiSlink->IsIntDoneDue = NV_FALSE;
NvRmInterruptDone(hRmSpiSlink->SpiInterruptHandle);
}
@@ -605,17 +700,14 @@ WaitForTransferCompletion(
NvU32 WordsAvailbleInFifo;
NvU32 WordsRead;
NvU32 *pUpdatedRxBuffer = NULL;
-#if NV_OAL
- // For oal version, we only use the polling method.
- IsPoll = NV_TRUE;
-#endif
+ HwInterfaceHandle hHwInt = hRmSpiSlink->hHwInterface;
if (IsPoll)
{
StartTime = NvOsGetTimeMS();
while (IsWait)
{
- IsReady = hRmSpiSlink->hHwInterface->HwIsTransferCompletedFxn(&hRmSpiSlink->HwRegs);
+ IsReady = hHwInt->HwIsTransferCompletedFxn(&hRmSpiSlink->HwRegs);
if (IsReady)
{
IsTransferComplete = HandleTransferCompletion(hRmSpiSlink);
@@ -632,17 +724,6 @@ WaitForTransferCompletion(
}
Error = (IsTransferComplete)? NvError_Success: NvError_Timeout;
-#if NV_OAL
- // If no error and apb dma based transfer then stop the dma transfer to
- // make the state dma state machine as non busy.
- if ((!Error) && (hRmSpiSlink->IsUsingApbDma))
- {
- if (hRmSpiSlink->CurrentDirection & SerialHwDataFlow_Rx)
- NvRmDmaAbort(hRmSpiSlink->hRmRxDma);
- if (hRmSpiSlink->CurrentDirection & SerialHwDataFlow_Tx)
- NvRmDmaAbort(hRmSpiSlink->hRmTxDma);
- }
-#endif
}
else
{
@@ -653,7 +734,7 @@ WaitForTransferCompletion(
if (Error == NvError_Timeout)
{
// Disable the data flow first.
- hRmSpiSlink->hHwInterface->HwSetDataFlowFxn(&hRmSpiSlink->HwRegs,
+ hHwInt->HwSetDataFlowFxn(&hRmSpiSlink->HwRegs,
hRmSpiSlink->CurrentDirection, NV_FALSE);
// Get the transfer count now.
@@ -661,21 +742,20 @@ WaitForTransferCompletion(
{
if (hRmSpiSlink->CurrentDirection & SerialHwDataFlow_Rx)
{
- NvError DmaError;
- // Get the Rx transfer count transferred by Dma.
- DmaError = NvRmDmaGetTransferredCount(hRmSpiSlink->hRmRxDma,
- &DmaRxTransferCountBytes, NV_TRUE);
- NV_ASSERT(DmaError == NvSuccess);
- if (DmaError != NvSuccess)
- DmaRxTransferCountBytes = 0;
+ AbortDma(hRmSpiSlink->hRxDma);
+ ResetSemaphoreCount(hRmSpiSlink->hSynchRxDmaSema);
+ DmaRxTransferCountBytes = hRmSpiSlink->RxDmaReq.bytes_transferred;
PacketTransferedFromFifoYet = (DmaRxTransferCountBytes >> 2) *
hRmSpiSlink->CurrTransInfo.PacketsPerWord;
- pUpdatedRxBuffer = hRmSpiSlink->pRxDmaBuffer + (DmaRxTransferCountBytes >> 2);
- NvRmDmaAbort(hRmSpiSlink->hRmRxDma);
+ pUpdatedRxBuffer = hRmSpiSlink->pRxDmaBuffer +
+ (DmaRxTransferCountBytes >> 2);
}
if (hRmSpiSlink->CurrentDirection & SerialHwDataFlow_Tx)
- NvRmDmaAbort(hRmSpiSlink->hRmTxDma);
+ {
+ AbortDma(hRmSpiSlink->hTxDma);
+ ResetSemaphoreCount(hRmSpiSlink->hSynchTxDmaSema);
+ }
}
else
{
@@ -687,7 +767,7 @@ WaitForTransferCompletion(
// It may be possible that transfer is completed when we reach here.
// If transfer is completed then we may read 0 from the status
// register
- IsReady = hRmSpiSlink->hHwInterface->HwIsTransferCompletedFxn(&hRmSpiSlink->HwRegs);
+ IsReady = hHwInt->HwIsTransferCompletedFxn(&hRmSpiSlink->HwRegs);
if (IsReady)
{
// All requested transfer has been done.
@@ -698,7 +778,7 @@ WaitForTransferCompletion(
{
// Get the transfer count from status register.
CurrentSlinkPacketTransfer =
- hRmSpiSlink->hHwInterface->HwGetTransferdCountFxn(&hRmSpiSlink->HwRegs);
+ hHwInt->HwGetTransferdCountFxn(&hRmSpiSlink->HwRegs);
// If it is in packed mode and number of received packet is non word
// aligned then ignore the packet which does not able to make the word.
@@ -717,7 +797,7 @@ WaitForTransferCompletion(
// Disable the interrupt.
if (!IsPoll)
- hRmSpiSlink->hHwInterface->HwSetInterruptSourceFxn(&hRmSpiSlink->HwRegs,
+ hHwInt->HwSetInterruptSourceFxn(&hRmSpiSlink->HwRegs,
hRmSpiSlink->CurrentDirection, NV_FALSE);
// For Rx: Dma will always transfer equal to or less than slink has
@@ -738,7 +818,7 @@ WaitForTransferCompletion(
WordsAvailbleInFifo =
(PacketsInRxFifo + hRmSpiSlink->CurrTransInfo.PacketsPerWord -1)/
hRmSpiSlink->CurrTransInfo.PacketsPerWord;
- WordsRead = hRmSpiSlink->hHwInterface->HwReadFromReceiveFifoFxn(
+ WordsRead = hHwInt->HwReadFromReceiveFifoFxn(
&hRmSpiSlink->HwRegs, pUpdatedRxBuffer, WordsAvailbleInFifo);
// Expecting the WordsRead should be equal to WordsAvailbleInFifo
@@ -749,34 +829,89 @@ WaitForTransferCompletion(
}
}
-
// The busy bit will still show the busy status so need to reset the
// controller. .. Hw Bug
NvRmModuleReset(hRmSpiSlink->hDevice,
NVRM_MODULE_ID(hRmSpiSlink->RmModuleId, hRmSpiSlink->InstanceId));
hRmSpiSlink->CurrentDirection = SerialHwDataFlow_None;
+ if ((!IsPoll) && (hRmSpiSlink->IsIntDoneDue))
+ NvRmInterruptDone(hRmSpiSlink->SpiInterruptHandle);
+
+ return Error;
}
- return Error;
-}
-#if NV_OAL
-static void OalMasterSpiSlinkPoll(NvRmSpiHandle hRmSpiSlink)
-{
- NvBool IsReady;
- NvBool TransferComplete = NV_FALSE;
- //Check for the transfer complete in infinite loop
- while (1)
+ /* If non dma based transfer then return as the slink status has already
+ * been handled.
+ */
+ if (!hRmSpiSlink->IsUsingApbDma)
+ return Error;
+
+ hRmSpiSlink->RxTransferStatus = NvSuccess;
+ hRmSpiSlink->TxTransferStatus = NvSuccess;
+ Error = NvSuccess;
+ if (hRmSpiSlink->CurrentDirection & SerialHwDataFlow_Rx)
{
- IsReady = hRmSpiSlink->hHwInterface->HwIsTransferCompletedFxn(&hRmSpiSlink->HwRegs);
- if (IsReady)
+ hRmSpiSlink->RxTransferStatus =
+ hHwInt->HwGetTransferStatusFxn(&hRmSpiSlink->HwRegs, SerialHwDataFlow_Rx);
+ if (hRmSpiSlink->RxTransferStatus)
{
- TransferComplete = HandleTransferCompletion(hRmSpiSlink);
- if(TransferComplete)
- break;
+ pr_err("Spi: RxTransfer Error\n");
+ AbortDma(hRmSpiSlink->hRxDma);
+ ResetSemaphoreCount(hRmSpiSlink->hSynchRxDmaSema);
+ }
+ else
+ {
+ if (NvOsSemaphoreWaitTimeout(hRmSpiSlink->hSynchRxDmaSema,
+ LATENCY_BETWEEN_SLINK_ISR_DMA_COMPLETE_MS))
+ {
+ pr_err("Spi: RxDmaSync Error \n");
+ AbortDma(hRmSpiSlink->hRxDma);
+ ResetSemaphoreCount(hRmSpiSlink->hSynchRxDmaSema);
+ hRmSpiSlink->RxTransferStatus = NvError_SpiReceiveError;
+ }
+ }
+ }
+
+ if (hRmSpiSlink->CurrentDirection & SerialHwDataFlow_Tx)
+ {
+ hRmSpiSlink->TxTransferStatus =
+ hHwInt->HwGetTransferStatusFxn(&hRmSpiSlink->HwRegs, SerialHwDataFlow_Tx);
+
+ if (hRmSpiSlink->TxTransferStatus)
+ {
+ pr_err("Spi: TxTransfer Error\n");
+ AbortDma(hRmSpiSlink->hTxDma);
+ ResetSemaphoreCount(hRmSpiSlink->hSynchTxDmaSema);
+ }
+ else
+ {
+ if (NvOsSemaphoreWaitTimeout(hRmSpiSlink->hSynchTxDmaSema,
+ LATENCY_BETWEEN_SLINK_ISR_DMA_COMPLETE_MS))
+ {
+ pr_err("Spi: TxDmaSync Error \n");
+ AbortDma(hRmSpiSlink->hTxDma);
+ ResetSemaphoreCount(hRmSpiSlink->hSynchTxDmaSema);
+ hRmSpiSlink->TxTransferStatus = NvError_SpiTransmitError;
+ }
}
}
+
+ hHwInt->HwClearTransferStatusFxn(&hRmSpiSlink->HwRegs, hRmSpiSlink->CurrentDirection);
+
+ if (hRmSpiSlink->RxTransferStatus || hRmSpiSlink->TxTransferStatus)
+ {
+ hHwInt->HwSetDataFlowFxn(&hRmSpiSlink->HwRegs, hRmSpiSlink->CurrentDirection, NV_FALSE);
+ hHwInt->HwResetFifoFxn(&hRmSpiSlink->HwRegs, SerialHwFifo_Both);
+ hRmSpiSlink->CurrTransInfo.PacketTransferred +=
+ hHwInt->HwGetTransferdCountFxn(&hRmSpiSlink->HwRegs);
+ hRmSpiSlink->CurrentDirection = SerialHwDataFlow_None;
+ Error = (hRmSpiSlink->RxTransferStatus)? hRmSpiSlink->RxTransferStatus:
+ hRmSpiSlink->TxTransferStatus;
+ }
+ if ((!IsPoll) && (hRmSpiSlink->IsIntDoneDue))
+ NvRmInterruptDone(hRmSpiSlink->SpiInterruptHandle);
+ return Error;
}
-#endif
/**
* Register the spi interrupt.
@@ -889,28 +1024,15 @@ static NvError SetPowerControl(NvRmSpiHandle hRmSpiSlink, NvBool IsEnable)
static void DestroySpiSlinkChannelHandle(NvRmSpiHandle hRmSpiSlink)
{
NvU32 HandleStartIndex;
-#if !NV_OAL
+
NvRmInterruptUnregister(hRmSpiSlink->hDevice, hRmSpiSlink->SpiInterruptHandle);
hRmSpiSlink->SpiInterruptHandle = NULL;
-#endif
-
// Unmap the virtual mapping of the spi hw register.
NvRmPhysicalMemUnmap(hRmSpiSlink->HwRegs.pRegsBaseAdd, hRmSpiSlink->HwRegs.RegBankSize);
- // the clocks should already be disabled for Non-oal. don't disable it here for non-oal
- // For oal disable here.
-#if NV_OAL
-
- // Resetting the Emc/Ahb/Apb/Cpu frequency
- BoostFrequency(hRmSpiSlink, NV_FALSE, 0, 0);
- (void)SetPowerControl(hRmSpiSlink, NV_FALSE);
-#endif
-
-#if !NV_OAL
// Unregister for the power manager.
NvRmPowerUnRegister(hRmSpiSlink->hDevice, hRmSpiSlink->RmPowerClientId);
-#endif
// Tri-State the pin-mux pins
NV_ASSERT_SUCCESS(NvRmSetModuleTristate(hRmSpiSlink->hDevice,
@@ -919,28 +1041,28 @@ static void DestroySpiSlinkChannelHandle(NvRmSpiHandle hRmSpiSlink)
NvOsFree(hRmSpiSlink->pTxCpuBuffer);
NvOsFree(hRmSpiSlink->pRxCpuBuffer);
- if (hRmSpiSlink->hRmRxDma)
- {
- NvRmDmaAbort(hRmSpiSlink->hRmRxDma);
- NvRmDmaFree(hRmSpiSlink->hRmRxDma);
- }
+ if (hRmSpiSlink->hRxDma)
+ AbortDma(hRmSpiSlink->hRxDma);
- if (hRmSpiSlink->hRmTxDma)
- {
- NvRmDmaAbort(hRmSpiSlink->hRmTxDma);
- NvRmDmaFree(hRmSpiSlink->hRmTxDma);
- }
+ if (hRmSpiSlink->hTxDma)
+ AbortDma(hRmSpiSlink->hTxDma);
+
+ FreeDmas(hRmSpiSlink);
DestroyDmaTransferBuffer(hRmSpiSlink->hRmMemory, hRmSpiSlink->pRxDmaBuffer,
hRmSpiSlink->pTxDmaBuffer, hRmSpiSlink->DmaBufferSize);
-#if !NV_OAL
// Destroy the mutex allocated for the channel accss.
NvOsMutexDestroy(hRmSpiSlink->hChannelAccessMutex);
// Destroy the sync sempahores.
NvOsSemaphoreDestroy(hRmSpiSlink->hSynchSema);
-#endif
+
+ // Destroy the sync sempahores.
+ NvOsSemaphoreDestroy(hRmSpiSlink->hSynchTxDmaSema);
+
+ // Destroy the sync sempahores.
+ NvOsSemaphoreDestroy(hRmSpiSlink->hSynchRxDmaSema);
HandleStartIndex = (hRmSpiSlink->IsSpiChannel)? 0: MAX_SPI_CONTROLLERS;
s_SpiSlinkInfo.hSpiSlinkChannelList[HandleStartIndex + hRmSpiSlink->InstanceId] = NULL;
@@ -969,8 +1091,8 @@ static NvError CreateSpiSlinkChannelHandle(
const NvU32 *pOdmConfigs;
NvU32 NumOdmConfigs;
NvU32 CpuBufferSize;
- NvRmDmaModuleID DmaModuleId;
const NvOdmQuerySpiIdleSignalState *pSignalState = NULL;
+ int DmaReq;
*phSpiSlinkChannel = NULL;
@@ -991,9 +1113,9 @@ static NvError CreateSpiSlinkChannelHandle(
hRmSpiSlink->OpenCount = 1;
hRmSpiSlink->IsApbDmaAllocated = NV_FALSE;
hRmSpiSlink->TransCountFromLastDmaUsage = 0;
- hRmSpiSlink->hRmRxDma = NULL;
+ hRmSpiSlink->hRxDma = NULL;
hRmSpiSlink->hRmMemory = NULL;
- hRmSpiSlink->hRmTxDma = NULL;
+ hRmSpiSlink->hTxDma = NULL;
hRmSpiSlink->DmaRxBuffPhysAdd = 0;
hRmSpiSlink->DmaTxBuffPhysAdd = 0;
hRmSpiSlink->pRxDmaBuffer = NULL;
@@ -1008,6 +1130,10 @@ static NvError CreateSpiSlinkChannelHandle(
hRmSpiSlink->IsChipSelConfigured = NV_FALSE;
hRmSpiSlink->IsCurrentlySwBasedChipSel = NV_TRUE;
+ hRmSpiSlink->hSynchSema = NULL;
+ hRmSpiSlink->hSynchTxDmaSema = NULL;
+ hRmSpiSlink->hSynchRxDmaSema = NULL;
+
// Initialize the frequncy requirements array
hRmSpiSlink->BusyHints[0].ClockId = NvRmDfsClockId_Emc;
hRmSpiSlink->BusyHints[0].BoostDurationMs = NV_WAIT_INFINITE;
@@ -1078,7 +1204,6 @@ static NvError CreateSpiSlinkChannelHandle(
hRmSpiSlink->hHwInterface->HwRegisterInitializeFxn(InstanceId, &hRmSpiSlink->HwRegs);
-#if !NV_OAL
// Create the mutex for channel access.
if (!Error)
Error = NvOsMutexCreate(&hRmSpiSlink->hChannelAccessMutex);
@@ -1086,7 +1211,14 @@ static NvError CreateSpiSlinkChannelHandle(
// Create the synchronous semaphores.
if (!Error)
Error = NvOsSemaphoreCreate(&hRmSpiSlink->hSynchSema, 0);
-#endif
+
+ // Create the synchronous semaphores.
+ if (!Error)
+ Error = NvOsSemaphoreCreate(&hRmSpiSlink->hSynchTxDmaSema, 0);
+
+ // Create the synchronous semaphores.
+ if (!Error)
+ Error = NvOsSemaphoreCreate(&hRmSpiSlink->hSynchRxDmaSema, 0);
// Get the spi hw physical base address and map in virtual memory space.
if (!Error)
@@ -1106,50 +1238,21 @@ static NvError CreateSpiSlinkChannelHandle(
// Allocate the dma buffer and the dma channel
if (!Error)
{
- hRmSpiSlink->IsApbDmaAllocated = NV_TRUE;
-
- // Don't go to the dma allocation if the oal and master mode.
- // It creates the download issue using the spi kitl if dma mode is used.
-#if NV_OAL
- if (IsMasterMode)
- {
- Error = NvError_NotSupported;
- }
- else
- {
- Error = CreateDmaTransferBuffer(hRmSpiSlink->hDevice, &hRmSpiSlink->hRmMemory,
- &hRmSpiSlink->DmaRxBuffPhysAdd, (void **)&hRmSpiSlink->pRxDmaBuffer,
- &hRmSpiSlink->DmaTxBuffPhysAdd, (void **)&hRmSpiSlink->pTxDmaBuffer,
- DEFAULT_DMA_BUFFER_SIZE);
- }
-#else
Error = CreateDmaTransferBuffer(hRmSpiSlink->hDevice, &hRmSpiSlink->hRmMemory,
&hRmSpiSlink->DmaRxBuffPhysAdd, (void **)&hRmSpiSlink->pRxDmaBuffer,
&hRmSpiSlink->DmaTxBuffPhysAdd, (void **)&hRmSpiSlink->pTxDmaBuffer,
DEFAULT_DMA_BUFFER_SIZE);
-#endif
if (!Error)
{
hRmSpiSlink->DmaBufferSize = DEFAULT_DMA_BUFFER_SIZE;
- DmaModuleId = (IsSpiChannel)?NvRmDmaModuleID_Spi: NvRmDmaModuleID_Slink;
// Allocate the dma (for Rx and for Tx) with high priority
// Allocate dma now only for the slave mode handle.
- // For master mode, it will be allaocated based on the transaction size
+ // For master mode, it will be allocated based on the transaction size
// to make it adaptive.
if (!IsMasterMode)
{
- Error = NvRmDmaAllocate(hRmSpiSlink->hDevice, &hRmSpiSlink->hRmRxDma,
- NV_FALSE, NvRmDmaPriority_High, DmaModuleId,
- hRmSpiSlink->InstanceId);
- if (!Error)
- {
- Error = NvRmDmaAllocate(hRmSpiSlink->hDevice, &hRmSpiSlink->hRmTxDma,
- NV_FALSE, NvRmDmaPriority_High, DmaModuleId,
- hRmSpiSlink->InstanceId);
- if (Error)
- NvRmDmaFree(hRmSpiSlink->hRmRxDma);
- }
+ Error = AllocateDmas(hRmSpiSlink);
if (Error)
{
DestroyDmaTransferBuffer(hRmSpiSlink->hRmMemory,
@@ -1160,33 +1263,55 @@ static NvError CreateSpiSlinkChannelHandle(
else
{
hRmSpiSlink->IsApbDmaAllocated = NV_FALSE;
- hRmSpiSlink->hRmRxDma = NULL;
- hRmSpiSlink->hRmTxDma = NULL;
+ hRmSpiSlink->hRxDma = NULL;
+ hRmSpiSlink->hTxDma = NULL;
}
}
if (Error)
{
hRmSpiSlink->IsApbDmaAllocated = NV_FALSE;
- hRmSpiSlink->hRmRxDma = NULL;
+ hRmSpiSlink->hRxDma = NULL;
hRmSpiSlink->hRmMemory = NULL;
- hRmSpiSlink->hRmTxDma = NULL;
+ hRmSpiSlink->hTxDma = NULL;
hRmSpiSlink->DmaRxBuffPhysAdd = 0;
hRmSpiSlink->DmaTxBuffPhysAdd = 0;
hRmSpiSlink->pRxDmaBuffer = NULL;
hRmSpiSlink->pTxDmaBuffer = NULL;
+ hRmSpiSlink->DmaBufferSize = 0;
Error = NvSuccess;
}
else
{
- hRmSpiSlink->RxDmaReq.SourceBufferPhyAddress= hRmSpiSlink->HwRegs.HwRxFifoAdd;
- hRmSpiSlink->RxDmaReq.DestinationBufferPhyAddress = hRmSpiSlink->DmaRxBuffPhysAdd;
- hRmSpiSlink->RxDmaReq.SourceAddressWrapSize = 4;
- hRmSpiSlink->RxDmaReq.DestinationAddressWrapSize = 0;
-
- hRmSpiSlink->TxDmaReq.SourceBufferPhyAddress= hRmSpiSlink->DmaTxBuffPhysAdd;
- hRmSpiSlink->TxDmaReq.DestinationBufferPhyAddress = hRmSpiSlink->HwRegs.HwTxFifoAdd;
- hRmSpiSlink->TxDmaReq.SourceAddressWrapSize = 0;
- hRmSpiSlink->TxDmaReq.DestinationAddressWrapSize = 4;
+ DmaReq = (IsSpiChannel)?s_Spi_Trigger[InstanceId]:
+ s_Slink_Trigger[InstanceId];
+
+ NvOsMemset(&hRmSpiSlink->RxDmaReq, 0, sizeof(hRmSpiSlink->RxDmaReq));
+ hRmSpiSlink->RxDmaReq.source_addr = (unsigned long)hRmSpiSlink->HwRegs.HwRxFifoAdd;
+ hRmSpiSlink->RxDmaReq.source_wrap = 4;
+ hRmSpiSlink->RxDmaReq.dest_addr = (unsigned long)hRmSpiSlink->DmaRxBuffPhysAdd;
+ hRmSpiSlink->RxDmaReq.dest_wrap = 0;
+ hRmSpiSlink->RxDmaReq.virt_addr = hRmSpiSlink->pRxDmaBuffer;
+ hRmSpiSlink->RxDmaReq.to_memory = 1;
+ hRmSpiSlink->RxDmaReq.source_bus_width = 32;
+ hRmSpiSlink->RxDmaReq.dest_bus_width = 32;
+ hRmSpiSlink->RxDmaReq.req_sel = DmaReq;
+ hRmSpiSlink->RxDmaReq.complete = SpiRxDmaCompleteCallback;
+ hRmSpiSlink->RxDmaReq.threshold = NULL;
+ hRmSpiSlink->RxDmaReq.dev = hRmSpiSlink;
+
+ NvOsMemset(&hRmSpiSlink->TxDmaReq, 0, sizeof(hRmSpiSlink->TxDmaReq));
+ hRmSpiSlink->TxDmaReq.source_addr = (unsigned long)hRmSpiSlink->DmaTxBuffPhysAdd;
+ hRmSpiSlink->TxDmaReq.source_wrap = 0;
+ hRmSpiSlink->TxDmaReq.dest_addr = (unsigned long)hRmSpiSlink->HwRegs.HwTxFifoAdd;
+ hRmSpiSlink->TxDmaReq.dest_wrap = 4;
+ hRmSpiSlink->TxDmaReq.virt_addr = hRmSpiSlink->pTxDmaBuffer;
+ hRmSpiSlink->TxDmaReq.to_memory = 0;
+ hRmSpiSlink->TxDmaReq.source_bus_width = 32;
+ hRmSpiSlink->TxDmaReq.dest_bus_width = 32;
+ hRmSpiSlink->TxDmaReq.req_sel = DmaReq;
+ hRmSpiSlink->TxDmaReq.complete = SpiTxDmaCompleteCallback;
+ hRmSpiSlink->TxDmaReq.threshold = NULL;
+ hRmSpiSlink->TxDmaReq.dev = hRmSpiSlink;
}
}
@@ -1211,14 +1336,12 @@ static NvError CreateSpiSlinkChannelHandle(
hRmSpiSlink->CpuBufferSizeInWords = CpuBufferSize >> 2;
}
-#if !NV_OAL
// Register slink/spi for Rm power client
if (!Error)
{
hRmSpiSlink->RmPowerClientId = NVRM_POWER_CLIENT_TAG('S','P','I',' ');
Error = NvRmPowerRegister(hRmSpiSlink->hDevice, NULL, &hRmSpiSlink->RmPowerClientId);
}
-#endif
// Enable Power/Clock.
if (!Error)
@@ -1228,11 +1351,9 @@ static NvError CreateSpiSlinkChannelHandle(
if (!Error)
NvRmModuleReset(hDevice, ModuleId);
-#if !NV_OAL
// Register the interrupt.
if (!Error)
Error = RegisterSpiSlinkInterrupt(hDevice, hRmSpiSlink, InstanceId);
-#endif
// Initialize the controller register.
if (!Error)
@@ -1256,10 +1377,8 @@ static NvError CreateSpiSlinkChannelHandle(
}
// Let chipselect to be stable for 1 ms before doing any transaction.
NvOsWaitUS(1000);
-#if !NV_OAL
// switch off clock and power to the slink module by default.
Error = SetPowerControl(hRmSpiSlink, NV_FALSE);
-#endif
}
// If error then destroy all the allocation done here.
@@ -1805,11 +1924,9 @@ MasterModeReadWriteCpu(
hRmSpiSlink->hHwInterface->HwSetDmaTransferSizeFxn(&hRmSpiSlink->HwRegs,
hRmSpiSlink->CurrTransInfo.CurrPacketCount);
hRmSpiSlink->hHwInterface->HwStartTransferFxn(&hRmSpiSlink->HwRegs, NV_TRUE);
-#if NV_OAL
- OalMasterSpiSlinkPoll(hRmSpiSlink);
-#else
+
WaitForTransferCompletion(hRmSpiSlink, NV_WAIT_INFINITE, IsPolling);
-#endif
+
Error = (hRmSpiSlink->RxTransferStatus)? hRmSpiSlink->RxTransferStatus:
hRmSpiSlink->TxTransferStatus;
if (Error)
@@ -1866,6 +1983,9 @@ static NvError MasterModeReadWriteDma(
PacketsRemaining = PacketsRequested;
while (PacketsRemaining)
{
+ ResetSemaphoreCount(hRmSpiSlink->hSynchTxDmaSema);
+ ResetSemaphoreCount(hRmSpiSlink->hSynchRxDmaSema);
+
MaxPacketTransPossible = NV_MIN(PacketsRemaining, MaxPacketPerTrans);
// If hw does not support the nonword alined packed mode then
@@ -1936,14 +2056,16 @@ static NvError MasterModeReadWriteDma(
hRmSpiSlink->pTxDmaBuffer, CurrentTransPacket*BytesPerPacket,
PacketBitLength, IsPackedMode);
hRmSpiSlink->CurrTransInfo.pTxBuff = hRmSpiSlink->pTxDmaBuffer;
- hRmSpiSlink->TxDmaReq.TransferSize = CurrentTransWord *4;
+ hRmSpiSlink->TxDmaReq.size = CurrentTransWord *4;
// If transfer word is more than fifo size the use the dma
// otherwise direct write into the fifo.
if (CurrentTransWord >= hRmSpiSlink->HwRegs.MaxWordTransfer)
{
- Error = NvRmDmaStartDmaTransfer(hRmSpiSlink->hRmTxDma,
- &hRmSpiSlink->TxDmaReq, NvRmDmaDirection_Forward, 0, NULL);
+ wmb();
+ dsb();
+ outer_sync();
+ Error = StartDma(hRmSpiSlink->hTxDma, &hRmSpiSlink->TxDmaReq);
// Wait till fifo full if the transfer size is more than fifo size
if (!Error)
{
@@ -1970,11 +2092,13 @@ static NvError MasterModeReadWriteDma(
if ((!Error) && (pClientRxBuffer))
{
- hRmSpiSlink->RxDmaReq.TransferSize = CurrentTransWord *4;
- Error = NvRmDmaStartDmaTransfer(hRmSpiSlink->hRmRxDma, &hRmSpiSlink->RxDmaReq,
- NvRmDmaDirection_Forward, 0, NULL);
+ hRmSpiSlink->RxDmaReq.size = CurrentTransWord *4;
+ Error = StartDma(hRmSpiSlink->hRxDma, &hRmSpiSlink->RxDmaReq);
if ((Error) && (pClientTxBuffer))
- NvRmDmaAbort(hRmSpiSlink->hRmTxDma);
+ {
+ AbortDma(hRmSpiSlink->hTxDma);
+ ResetSemaphoreCount(hRmSpiSlink->hSynchTxDmaSema);
+ }
}
if (!Error)
@@ -1986,15 +2110,13 @@ static NvError MasterModeReadWriteDma(
Error = (hRmSpiSlink->RxTransferStatus)? hRmSpiSlink->RxTransferStatus:
hRmSpiSlink->TxTransferStatus;
if (Error)
- {
- if (pClientRxBuffer)
- NvRmDmaAbort(hRmSpiSlink->hRmRxDma);
- if (pClientTxBuffer)
- NvRmDmaAbort(hRmSpiSlink->hRmTxDma);
break;
- }
+
if (pClientRxBuffer)
{
+ rmb();
+ dsb();
+ outer_sync();
MakeMasterClientBufferFromSpiBuffer(pClientRxBuffer + BufferOffset,
hRmSpiSlink->pRxDmaBuffer, CurrentTransPacket*BytesPerPacket,
PacketBitLength, IsPackedMode);
@@ -2109,6 +2231,8 @@ static NvError SlaveModeSpiStartReadWriteDma(
TotalWordsRequested = (PacketsRequested + PacketsPerWord -1)/PacketsPerWord;
hRmSpiSlink->IsUsingApbDma = NV_TRUE;
+ ResetSemaphoreCount(hRmSpiSlink->hSynchTxDmaSema);
+ ResetSemaphoreCount(hRmSpiSlink->hSynchRxDmaSema);
// Create the buffer if the required size of the buffer is not available.
if (hRmSpiSlink->DmaBufferSize < (TotalWordsRequested*4))
@@ -2119,6 +2243,7 @@ static NvError SlaveModeSpiStartReadWriteDma(
hRmSpiSlink->hRmMemory = NULL;
hRmSpiSlink->pRxDmaBuffer = NULL;
hRmSpiSlink->DmaRxBuffPhysAdd = 0;
+ hRmSpiSlink->DmaTxBuffPhysAdd = 0;
// Better to findout the neearest 2powern
NewBufferSize = NV_MAX(hRmSpiSlink->DmaBufferSize, (TotalWordsRequested*4));
@@ -2132,9 +2257,12 @@ static NvError SlaveModeSpiStartReadWriteDma(
hRmSpiSlink->DmaBufferSize = 0;
return Error;
}
- hRmSpiSlink->RxDmaReq.DestinationBufferPhyAddress = hRmSpiSlink->DmaRxBuffPhysAdd;
- hRmSpiSlink->TxDmaReq.SourceBufferPhyAddress = hRmSpiSlink->DmaTxBuffPhysAdd;
+ hRmSpiSlink->RxDmaReq.dest_addr = (unsigned long)hRmSpiSlink->DmaRxBuffPhysAdd;
+ hRmSpiSlink->TxDmaReq.source_addr = (unsigned long)hRmSpiSlink->DmaTxBuffPhysAdd;
+ hRmSpiSlink->RxDmaReq.virt_addr = hRmSpiSlink->pRxDmaBuffer;
+ hRmSpiSlink->TxDmaReq.virt_addr = hRmSpiSlink->pTxDmaBuffer;
hRmSpiSlink->DmaBufferSize = NewBufferSize;
+ pr_err("allocated new buffers of size %d\n",NewBufferSize);
}
hRmSpiSlink->CurrTransInfo.PacketsPerWord = PacketsPerWord;
@@ -2168,9 +2296,11 @@ static NvError SlaveModeSpiStartReadWriteDma(
CurrentTransPacket*BytesPerPacket,
PacketBitLength, IsPackedMode);
hRmSpiSlink->CurrTransInfo.pTxBuff = hRmSpiSlink->pTxDmaBuffer;
- hRmSpiSlink->TxDmaReq.TransferSize = CurrentTransWord *4;
- Error = NvRmDmaStartDmaTransfer(hRmSpiSlink->hRmTxDma, &hRmSpiSlink->TxDmaReq,
- NvRmDmaDirection_Forward, 0, NULL);
+ hRmSpiSlink->TxDmaReq.size = CurrentTransWord *4;
+ wmb();
+ dsb();
+ outer_sync();
+ Error = StartDma(hRmSpiSlink->hTxDma, &hRmSpiSlink->TxDmaReq);
do
{
if (hRmSpiSlink->hHwInterface->HwIsTransmitFifoFull(&hRmSpiSlink->HwRegs))
@@ -2180,14 +2310,16 @@ static NvError SlaveModeSpiStartReadWriteDma(
if ((!Error) && (IsReadTransfer))
{
- hRmSpiSlink->RxDmaReq.TransferSize = CurrentTransWord *4;
+ hRmSpiSlink->RxDmaReq.size = CurrentTransWord *4;
hRmSpiSlink->CurrTransInfo.RxPacketsRemaining = CurrentTransPacket;
hRmSpiSlink->CurrTransInfo.pRxBuff = hRmSpiSlink->pRxDmaBuffer;
- Error = NvRmDmaStartDmaTransfer(hRmSpiSlink->hRmRxDma, &hRmSpiSlink->RxDmaReq,
- NvRmDmaDirection_Forward, 0, NULL);
+ Error = StartDma(hRmSpiSlink->hRxDma, &hRmSpiSlink->RxDmaReq);
if ((Error) && (pClientTxBuffer))
- NvRmDmaAbort(hRmSpiSlink->hRmTxDma);
+ {
+ AbortDma(hRmSpiSlink->hTxDma);
+ ResetSemaphoreCount(hRmSpiSlink->hSynchTxDmaSema);
+ }
}
if (!Error)
@@ -2227,6 +2359,9 @@ static NvError SlaveModeSpiCompleteReadWrite(
{
pRxBuffer = (hRmSpiSlink->IsUsingApbDma)?hRmSpiSlink->pRxDmaBuffer:
hRmSpiSlink->pRxCpuBuffer;
+ rmb();
+ dsb();
+ outer_sync();
MakeSlaveClientBufferFromSpiBuffer(pClientRxBuffer,
pRxBuffer, ReqSizeInBytes,
hRmSpiSlink->CurrTransInfo.PacketBitLength,
@@ -2350,6 +2485,7 @@ NvRmSpiOpen(
*phRmSpi = NULL;
+ pr_err("NvRmSpiOpen() Opening channel Inst %d and IsMaster %d\n",InstanceId, IsMasterMode);
IsSpiChannel = (IoModule == NvOdmIoModule_Sflash)? NV_TRUE: NV_FALSE;
// SPI controller does not support the slave mode
@@ -2389,6 +2525,7 @@ NvRmSpiOpen(
}
else
{
+ pr_err("The channel is already allocated\n");
Error = NvError_AlreadyAllocated;
goto FuncExit;
}
@@ -2433,7 +2570,6 @@ void NvRmSpiMultipleTransactions(
NvU32 TotalPacketsRequsted;
NvU32 TotalWordsRequested;
NvU32 i;
- NvRmDmaModuleID DmaModuleId;
NvRmSpiTransactionInfo *pTrans = t;
NvU32 TotalTransByte = 0;
NvBool IsOnlySwCs = NV_TRUE;
@@ -2520,28 +2656,12 @@ void NvRmSpiMultipleTransactions(
// Allocate the dma here if transaction size is more than cpu based
// transaction thresold.
if ((TotalWordsRequested > hRmSpi->HwRegs.MaxWordTransfer) &&
- (hRmSpi->DmaBufferSize) &&
- (!hRmSpi->IsApbDmaAllocated))
+ (hRmSpi->DmaBufferSize) && (!hRmSpi->IsApbDmaAllocated))
{
- hRmSpi->TransCountFromLastDmaUsage = 0;
- hRmSpi->IsApbDmaAllocated = NV_TRUE;
- DmaModuleId = (hRmSpi->IsSpiChannel)?NvRmDmaModuleID_Spi: NvRmDmaModuleID_Slink;
- Error = NvRmDmaAllocate(hRmSpi->hDevice, &hRmSpi->hRmRxDma,
- NV_FALSE, NvRmDmaPriority_High, DmaModuleId,
- hRmSpi->InstanceId);
- if (!Error)
- {
- Error = NvRmDmaAllocate(hRmSpi->hDevice, &hRmSpi->hRmTxDma,
- NV_FALSE, NvRmDmaPriority_High, DmaModuleId,
- hRmSpi->InstanceId);
- if (Error)
- NvRmDmaFree(hRmSpi->hRmRxDma);
- }
+ Error = AllocateDmas(hRmSpi);
if (Error)
{
- hRmSpi->hRmRxDma = NULL;
- hRmSpi->hRmTxDma = NULL;
- hRmSpi->IsApbDmaAllocated = NV_FALSE;
+ pr_debug("Dma not allocated\n");
Error = NvSuccess;
}
}
@@ -2595,13 +2715,7 @@ cleanup:
}
if ((hRmSpi->IsApbDmaAllocated) &&
(hRmSpi->TransCountFromLastDmaUsage > MAX_DMA_HOLD_TIME))
- {
- NvRmDmaFree(hRmSpi->hRmRxDma);
- NvRmDmaFree(hRmSpi->hRmTxDma);
- hRmSpi->hRmRxDma = NULL;
- hRmSpi->hRmTxDma = NULL;
- hRmSpi->IsApbDmaAllocated = NV_FALSE;
- }
+ FreeDmas(hRmSpi);
SetPowerControl(hRmSpi, NV_FALSE);
NvOsMutexUnlock(hRmSpi->hChannelAccessMutex);
@@ -2628,7 +2742,6 @@ void NvRmSpiTransaction(
NvU32 PacketsPerWord;
NvU32 TotalPacketsRequsted;
NvU32 TotalWordsRequested;
- NvRmDmaModuleID DmaModuleId;
NV_ASSERT(hRmSpi);
NV_ASSERT(pReadBuffer || pWriteBuffer);
@@ -2656,7 +2769,6 @@ void NvRmSpiTransaction(
PacketsPerWord = (IsPackedMode)? 4/BytesPerPackets: 1;
TotalWordsRequested = (TotalPacketsRequsted + PacketsPerWord -1)/PacketsPerWord;
-#if !NV_OAL
// Lock the channel access by other client till this client finishes the ops
NvOsMutexLock(hRmSpi->hChannelAccessMutex);
@@ -2667,9 +2779,6 @@ void NvRmSpiTransaction(
goto cleanup;
BoostFrequency(hRmSpi, NV_TRUE, BytesRequested, ClockSpeedInKHz);
-#else
- hRmSpi->CurrTransferChipSelId = ChipSelectId;
-#endif
hRmSpi->CurrTransInfo.PacketsPerWord = PacketsPerWord;
// Enable the transmit if the Tx buffer is supplied.
@@ -2705,28 +2814,12 @@ void NvRmSpiTransaction(
// Allocate the dma here if transaction size is more than cpu based
// transaction thresold.
if ((TotalWordsRequested > hRmSpi->HwRegs.MaxWordTransfer) &&
- (hRmSpi->DmaBufferSize) &&
- (!hRmSpi->IsApbDmaAllocated))
+ (hRmSpi->DmaBufferSize) && (!hRmSpi->IsApbDmaAllocated))
{
- hRmSpi->TransCountFromLastDmaUsage = 0;
- hRmSpi->IsApbDmaAllocated = NV_TRUE;
- DmaModuleId = (hRmSpi->IsSpiChannel)?NvRmDmaModuleID_Spi: NvRmDmaModuleID_Slink;
- Error = NvRmDmaAllocate(hRmSpi->hDevice, &hRmSpi->hRmRxDma,
- NV_FALSE, NvRmDmaPriority_High, DmaModuleId,
- hRmSpi->InstanceId);
- if (!Error)
- {
- Error = NvRmDmaAllocate(hRmSpi->hDevice, &hRmSpi->hRmTxDma,
- NV_FALSE, NvRmDmaPriority_High, DmaModuleId,
- hRmSpi->InstanceId);
- if (Error)
- NvRmDmaFree(hRmSpi->hRmRxDma);
- }
+ Error = AllocateDmas(hRmSpi);
if (Error)
{
- hRmSpi->hRmRxDma = NULL;
- hRmSpi->hRmTxDma = NULL;
- hRmSpi->IsApbDmaAllocated = NV_FALSE;
+ pr_debug("Dma Allocation failed\n");
Error = NvSuccess;
}
}
@@ -2784,18 +2877,10 @@ cleanup:
if ((hRmSpi->IsApbDmaAllocated) &&
(hRmSpi->TransCountFromLastDmaUsage > MAX_DMA_HOLD_TIME))
- {
- NvRmDmaFree(hRmSpi->hRmRxDma);
- NvRmDmaFree(hRmSpi->hRmTxDma);
- hRmSpi->hRmRxDma = NULL;
- hRmSpi->hRmTxDma = NULL;
- hRmSpi->IsApbDmaAllocated = NV_FALSE;
- }
+ FreeDmas(hRmSpi);
-#if !NV_OAL
SetPowerControl(hRmSpi, NV_FALSE);
NvOsMutexUnlock(hRmSpi->hChannelAccessMutex);
-#endif
NV_ASSERT(Error == NvSuccess);