summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2010-07-22 18:40:41 +0530
committerGary King <gking@nvidia.com>2010-07-23 20:26:18 -0700
commit02c0a803376731f8ad3a1330db61c44c3177e5a9 (patch)
treeca4a4c52c07ae8295ab00cd7b840f340d0497694
parentf658aa740ee09861856fadfd8094e48641c27a14 (diff)
[arm/tegra] spi: Use native dma for data transfer
The rm spi driver is using the nvrm dma driver which is wrapper over the native dma. Using directly the native dma driver to get rid of one more level of wrapper call from spi driver. Making sure that prev dma operation is completed before starting new transfer. Removed the code which was specific to OAL as this is not required any more. Calling the write buffer barriers after writing into the write dma buffer and before starting the transmit dma to make sure that all written data is available in physical memory before dma start. Change-Id: Iabcd86f0d63b2decffda0ad6da6f1b22161e9d3b Reviewed-on: http://git-master/r/2670 Reviewed-by: Michael Hsu <mhsu@nvidia.com> Tested-by: Michael Hsu <mhsu@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com>
-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);