diff options
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.c | 575 |
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); |