diff --git a/Omap35xxPkg/Include/Library/OmapDmaLib.h b/Omap35xxPkg/Include/Library/OmapDmaLib.h index 9c60d44ee5..d4daf6d364 100755 --- a/Omap35xxPkg/Include/Library/OmapDmaLib.h +++ b/Omap35xxPkg/Include/Library/OmapDmaLib.h @@ -88,6 +88,8 @@ EnableDmaChannel ( Turn of DMA channel configured by EnableDma(). @param Channel DMA Channel to configure + @param SuccesMask Bits in DMA4_CSR register indicate EFI_SUCCESS + @param ErrorMask Bits in DMA4_CSR register indicate EFI_DEVICE_ERROR @retval EFI_SUCCESS DMA hardware disabled @retval EFI_INVALID_PARAMETER Channel is not valid @@ -97,7 +99,9 @@ EnableDmaChannel ( EFI_STATUS EFIAPI DisableDmaChannel ( - IN UINTN Channel + IN UINTN Channel, + IN UINT32 SuccessMask, + IN UINT32 ErrorMask ); diff --git a/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h b/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h index 4e397d52e5..242c325331 100755 --- a/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h +++ b/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h @@ -22,6 +22,7 @@ #define DMA4_CCR(_i) (0x48056080 + (0x60*(_i))) #define DMA4_CICR(_i) (0x48056088 + (0x60*(_i))) +#define DMA4_CSR(_i) (0x4805608c + (0x60*(_i))) #define DMA4_CSDP(_i) (0x48056090 + (0x60*(_i))) #define DMA4_CEN(_i) (0x48056094 + (0x60*(_i))) #define DMA4_CFN(_i) (0x48056098 + (0x60*(_i))) @@ -106,5 +107,24 @@ #define DMA4_CCR_SEL_SRC_DEST_SYNC_SOURCE BIT24 +#define DMA4_CSR_DROP BIT1 +#define DMA4_CSR_HALF BIT2 +#define DMA4_CSR_FRAME BIT3 +#define DMA4_CSR_LAST BIT4 +#define DMA4_CSR_BLOCK BIT5 +#define DMA4_CSR_SYNC BIT6 +#define DMA4_CSR_PKT BIT7 +#define DMA4_CSR_TRANS_ERR BIT8 +#define DMA4_CSR_SECURE_ERR BIT9 +#define DMA4_CSR_SUPERVISOR_ERR BIT10 +#define DMA4_CSR_MISALIGNED_ADRS_ERR BIT11 +#define DMA4_CSR_DRAIN_END BIT12 +#define DMA4_CSR_RESET 0x1FE +#define DMA4_CSR_ERR (DMA4_CSR_TRANS_ERR | DMA4_CSR_SECURE_ERR | DMA4_CSR_SUPERVISOR_ERR | DMA4_CSR_MISALIGNED_ADRS_ERR) + +// same mapping as CSR except for SYNC. Enable all since we are polling +#define DMA4_CICR_ENABLE_ALL 0x1FBE + + #endif diff --git a/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c b/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c index f979b9444a..fa4bce8853 100755 --- a/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c +++ b/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c @@ -125,11 +125,17 @@ EnableDmaChannel ( /* - Set the destination frame index CDFI[31:0]*/ MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex); - + + MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex); + + // Enable all the status bits since we are polling + MmioWrite32 (DMA4_CICR (Channel), DMA4_CICR_ENABLE_ALL); + MmioWrite32 (DMA4_CSR (Channel), DMA4_CSR_RESET); + /* 2) Start the DMA transfer by Setting the enable bit CCR[7]=1 */ /*--------------------------------------------------------------*/ //write enable bit - MmioOr32 (DMA4_CCR(0), DMA4_CCR_ENABLE); //Launch transfer + MmioOr32 (DMA4_CCR(Channel), DMA4_CCR_ENABLE); //Launch transfer return EFI_SUCCESS; } @@ -138,6 +144,8 @@ EnableDmaChannel ( Turn of DMA channel configured by EnableDma(). @param Channel DMA Channel to configure + @param SuccesMask Bits in DMA4_CSR register indicate EFI_SUCCESS + @param ErrorMask Bits in DMA4_CSR register indicate EFI_DEVICE_ERROR @retval EFI_SUCCESS DMA hardware disabled @retval EFI_INVALID_PARAMETER Channel is not valid @@ -147,17 +155,39 @@ EnableDmaChannel ( EFI_STATUS EFIAPI DisableDmaChannel ( - IN UINTN Channel + IN UINTN Channel, + IN UINT32 SuccessMask, + IN UINT32 ErrorMask ) { + EFI_STATUS Status = EFI_SUCCESS; + UINT32 Reg; + + if (Channel > DMA4_MAX_CHANNEL) { return EFI_INVALID_PARAMETER; } + do { + Reg = MmioRead32 (DMA4_CSR(Channel)); + if ((Reg & ErrorMask) != 0) { + Status = EFI_DEVICE_ERROR; + DEBUG ((EFI_D_ERROR, "DMA Error (%d) %x\n", Channel, Reg)); + break; + } + } while ((Reg & SuccessMask) != SuccessMask); + + + // Disable all status bits and clear them + MmioWrite32 (DMA4_CICR (Channel), 0); + MmioWrite32 (DMA4_CSR (Channel), DMA4_CSR_RESET); + MmioAnd32 (DMA4_CCR(0), ~(DMA4_CCR_ENABLE | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE)); - return EFI_SUCCESS; + return Status; } + + /** Provides the DMA controller-specific addresses needed to access system memory. diff --git a/Omap35xxPkg/MMCHSDxe/MMCHS.c b/Omap35xxPkg/MMCHSDxe/MMCHS.c index 3238d61829..54e24d9825 100644 --- a/Omap35xxPkg/MMCHSDxe/MMCHS.c +++ b/Omap35xxPkg/MMCHSDxe/MMCHS.c @@ -740,7 +740,7 @@ DmaBlocks ( ) { EFI_STATUS Status; - UINTN RetryCount = 0; + UINTN DmaSize = 0; UINTN Cmd = 0; UINTN CmdInterruptEnable; UINTN CmdArgument; @@ -749,66 +749,73 @@ DmaBlocks ( OMAP_DMA4 Dma4; DMA_MAP_OPERATION DmaOperation; +CpuDeadLoop (); + // Map passed in buffer for DMA xfer + DmaSize = BlockCount * This->Media->BlockSize; + Status = DmaMap (DmaOperation, Buffer, &DmaSize, &BufferAddress, &BufferMap); + if (EFI_ERROR (Status)) { + return Status; + } + + ZeroMem (&DmaOperation, sizeof (DMA_MAP_OPERATION)); + + Dma4.DataType = 2; // DMA4_CSDPi[1:0] 32-bit elements from MMCHS_DATA + Dma4.SourceEndiansim = 0; // DMA4_CSDPi[21] + Dma4.DestinationEndianism = 0; // DMA4_CSDPi[19] + Dma4.SourcePacked = 0; // DMA4_CSDPi[6] + Dma4.DestinationPacked = 0; // DMA4_CSDPi[13] + Dma4.NumberOfElementPerFrame = This->Media->BlockSize/4; // DMA4_CENi (TRM 4K is optimum value) + Dma4.NumberOfFramePerTransferBlock = BlockCount; // DMA4_CFNi + Dma4.ReadPriority = 0; // DMA4_CCRi[6] Low priority read + Dma4.WritePriority = 0; // DMA4_CCRi[23] Prefetech disabled //Populate the command information based on the operation type. if (OperationType == READ) { Cmd = CMD18; //Multiple block read CmdInterruptEnable = CMD18_INT_EN; DmaOperation = MapOperationBusMasterCommonBuffer; + + Dma4.ReadPortAccessType =0 ; // DMA4_CSDPi[8:7] Can not burst MMCHS_DATA reg + Dma4.WritePortAccessType = 3; // DMA4_CSDPi[15:14] Memory burst 16x32 + Dma4.WriteMode = 1; // DMA4_CSDPi[17:16] Write posted + + Dma4.SourceStartAddress = MMCHS_DATA; // DMA4_CSSAi + Dma4.DestinationStartAddress = (UINT32)BufferAddress; // DMA4_CDSAi + Dma4.SourceElementIndex = 1; // DMA4_CSEi + Dma4.SourceFrameIndex = 0x200; // DMA4_CSFi + Dma4.DestinationElementIndex = 1; // DMA4_CDEi + Dma4.DestinationFrameIndex = 0; // DMA4_CDFi + + Dma4.ReadPortAccessMode = 0; // DMA4_CCRi[13:12] Always read MMCHS_DATA + Dma4.WritePortAccessMode = 1; // DMA4_CCRi[15:14] Post increment memory address + Dma4.ReadRequestNumber = 0x1e; // DMA4_CCRi[4:0] Syncro with MMCA_DMA_RX (61) + Dma4.WriteRequestNumber = 1; // DMA4_CCRi[20:19] Syncro upper 0x3e == 62 (one based) + } else if (OperationType == WRITE) { Cmd = CMD25; //Multiple block write CmdInterruptEnable = CMD25_INT_EN; DmaOperation = MapOperationBusMasterRead; + + Dma4.ReadPortAccessType = 3; // DMA4_CSDPi[8:7] Memory burst 16x32 + Dma4.WritePortAccessType = 0; // DMA4_CSDPi[15:14] Can not burst MMCHS_DATA reg + Dma4.WriteMode = 1; // DMA4_CSDPi[17:16] Write posted ??? + + Dma4.SourceStartAddress = (UINT32)BufferAddress; // DMA4_CSSAi + Dma4.DestinationStartAddress = MMCHS_DATA; // DMA4_CDSAi + Dma4.SourceElementIndex = 1; // DMA4_CSEi + Dma4.SourceFrameIndex = 0x200; // DMA4_CSFi + Dma4.DestinationElementIndex = 1; // DMA4_CDEi + Dma4.DestinationFrameIndex = 0; // DMA4_CDFi + + Dma4.ReadPortAccessMode = 1; // DMA4_CCRi[13:12] Post increment memory address + Dma4.WritePortAccessMode = 0; // DMA4_CCRi[15:14] Always write MMCHS_DATA + Dma4.ReadRequestNumber = 0x1d; // DMA4_CCRi[4:0] Syncro with MMCA_DMA_TX (60) + Dma4.WriteRequestNumber = 1; // DMA4_CCRi[20:19] Syncro upper 0x3d == 61 (one based) + } else { return EFI_INVALID_PARAMETER; } - // Map passed in buffer for DMA xfer - RetryCount = BlockCount * This->Media->BlockSize; - Status = DmaMap (DmaOperation, Buffer, &RetryCount, &BufferAddress, &BufferMap); - if (EFI_ERROR (Status)) { - return Status; - } - - #if 0 - MmioWrite32 (DMA4_CSDP(0), DMA4_CSDP_DATA_TYPE32 | DMA4_CSDP_SRC_BURST_EN64 | DMA4_CSDP_WRITE_MODE_POSTED); - MmioWrite32 (DMA4_CEN(0), 0x4096); // Channel Element number - MmioWrite32 (DMA4_CFN(0), 0x1); // Channel Frame number - if () { - MmioWrite32 (DMA4_CCR(0), X | DMA4_CCR_FS_PACKET | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE | DMA4_CCR_DST_AMODE_POST_INC | DMA4_CCR_SEL_SRC_DEST_SYNC_SOURCE); - MmioWrite32 (DMA4_CSSA(0), MMCHS_DATA); // Src is SD Card - MmioWrite32 (DMA4_CDSA(0), (UINT32)BufferAddress); // Dst memory - } else { - MmioWrite32 (DMA4_CCR(0), X | DMA4_CCR_FS_PACKET | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE | DMA4_CCR_SRC_AMODE_POST_INC); - MmioWrite32 (DMA4_CSSA(0), (UINT32)BufferAddress); // Src memory - MmioWrite32 (DMA4_CDSA(0), MMCHS_DATA); // Dst SD Card - } - MmioWrite32 (DMA4_CSE(0), 1); - MmioWrite32 (DMA4_CSF(0), This->Media->BlockSize); - MmioWrite32 (DMA4_CDE(0), 1); -#endif - Dma4.DataType = 0; // DMA4_CSDPi[1:0] - Dma4.ReadPortAccessType =0; // DMA4_CSDPi[8:7] - Dma4.WritePortAccessType =0; // DMA4_CSDPi[15:14] - Dma4.SourceEndiansim = 0; // DMA4_CSDPi[21] - Dma4.DestinationEndianism = 0; // DMA4_CSDPi[19] - Dma4.WriteMode = 0; // DMA4_CSDPi[17:16] - Dma4.SourcePacked = 0; // DMA4_CSDPi[6] - Dma4.DestinationPacked = 0; // DMA4_CSDPi[13] - Dma4.NumberOfElementPerFrame = 0; // DMA4_CENi - Dma4.NumberOfFramePerTransferBlock = 0; // DMA4_CFNi - Dma4.SourceStartAddress = 0; // DMA4_CSSAi - Dma4.DestinationStartAddress = 0; // DMA4_CDSAi - Dma4.SourceElementIndex = 0; // DMA4_CSEi - Dma4.SourceFrameIndex = 0; // DMA4_CSFi - Dma4.DestinationElementIndex = 0; // DMA4_CDEi - Dma4.DestinationFrameIndex = 0; // DMA4_CDFi - Dma4.ReadPortAccessMode = 0; // DMA4_CCRi[13:12] - Dma4.WritePortAccessMode = 0; // DMA4_CCRi[15:14] - Dma4.ReadPriority = 0; // DMA4_CCRi[6] - Dma4.WritePriority = 0; // DMA4_CCRi[23] - Dma4.ReadRequestNumber = 0; // DMA4_CCRi[4:0] - Dma4.WriteRequestNumber = 0; // DMA4_CCRi[20:19] EnableDmaChannel (2, &Dma4); @@ -827,7 +834,7 @@ DmaBlocks ( return Status; } - DisableDmaChannel (2); + DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR); Status = DmaUnmap (BufferMap); return Status; @@ -1029,6 +1036,7 @@ DetectCard ( return Status; } +#define MAX_MMCHS_TRANSFER_SIZE 0x4000 EFI_STATUS SdReadWrite ( @@ -1042,7 +1050,7 @@ SdReadWrite ( EFI_STATUS Status = EFI_SUCCESS; UINTN RetryCount = 0; UINTN BlockCount; - UINTN BytesToBeTranferedThisPass; + UINTN BytesToBeTranferedThisPass = 0; UINTN BytesRemainingToBeTransfered; EFI_TPL OldTpl; BOOLEAN Update; @@ -1323,7 +1331,7 @@ MMCHSInitialize ( Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TimerCallback, NULL, &gTimerEvent); ASSERT_EFI_ERROR (Status); - Status = gBS->SetTimer (gTimerEvent, TimerPeriodic, 1000000ULL); // make me a PCD + Status = gBS->SetTimer (gTimerEvent, TimerPeriodic, FixedPcdGet32 (PcdMmchsTimerFreq100NanoSeconds)); ASSERT_EFI_ERROR (Status); //Publish BlockIO. diff --git a/Omap35xxPkg/MMCHSDxe/MMCHS.inf b/Omap35xxPkg/MMCHSDxe/MMCHS.inf index 43327777b7..3313ddd44f 100644 --- a/Omap35xxPkg/MMCHSDxe/MMCHS.inf +++ b/Omap35xxPkg/MMCHSDxe/MMCHS.inf @@ -47,6 +47,7 @@ [Pcd] gOmap35xxTokenSpaceGuid.PcdOmap35xxMMCHS1Base + gOmap35xxTokenSpaceGuid.PcdMmchsTimerFreq100NanoSeconds [depex] gEmbeddedExternalDeviceProtocolGuid diff --git a/Omap35xxPkg/Omap35xxPkg.dec b/Omap35xxPkg/Omap35xxPkg.dec index e7884590a5..4285ea1850 100644 --- a/Omap35xxPkg/Omap35xxPkg.dec +++ b/Omap35xxPkg/Omap35xxPkg.dec @@ -54,4 +54,5 @@ gOmap35xxTokenSpaceGuid.PcdOmap35xxFreeTimer|4|UINT32|0x00000206 gOmap35xxTokenSpaceGuid.PcdOmap35xxDebugAgentTimer|5|UINT32|0x00000207 gOmap35xxTokenSpaceGuid.PcdDebugAgentTimerFreqNanoSeconds|77|UINT32|0x00000208 + gOmap35xxTokenSpaceGuid.PcdMmchsTimerFreq100NanoSeconds|1000000|UINT32|0x00000209