UINTN CmdInterruptEnable;
UINTN CmdArgument;
VOID *BufferMap;
- EFI_PHYSICAL_ADDRESS BufferAddress;
+ EFI_PHYSICAL_ADDRESS BufferAddress;
OMAP_DMA4 Dma4;
DMA_MAP_OPERATION DmaOperation;
+ EFI_STATUS MmcStatus;
+ UINTN RetryCount = 0;
CpuDeadLoop ();
// Map passed in buffer for DMA xfer
}
ZeroMem (&DmaOperation, sizeof (DMA_MAP_OPERATION));
- \r
- Dma4.DataType = 2; // DMA4_CSDPi[1:0] 32-bit elements from MMCHS_DATA\r
- Dma4.SourceEndiansim = 0; // DMA4_CSDPi[21] \r
- Dma4.DestinationEndianism = 0; // DMA4_CSDPi[19]\r
- Dma4.SourcePacked = 0; // DMA4_CSDPi[6]\r
- Dma4.DestinationPacked = 0; // DMA4_CSDPi[13]\r
- Dma4.NumberOfElementPerFrame = This->Media->BlockSize/4; // DMA4_CENi (TRM 4K is optimum value) \r
- Dma4.NumberOfFramePerTransferBlock = BlockCount; // DMA4_CFNi \r
- Dma4.ReadPriority = 0; // DMA4_CCRi[6] Low priority read \r
- Dma4.WritePriority = 0; // DMA4_CCRi[23] Prefetech disabled\r
+
+
+ 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) {
CmdInterruptEnable = CMD18_INT_EN;
DmaOperation = MapOperationBusMasterCommonBuffer;
- Dma4.ReadPortAccessType =0 ; // DMA4_CSDPi[8:7] Can not burst MMCHS_DATA reg\r
- Dma4.WritePortAccessType = 3; // DMA4_CSDPi[15:14] Memory burst 16x32\r
- Dma4.WriteMode = 1; // DMA4_CSDPi[17:16] Write posted\r
- \r
- Dma4.SourceStartAddress = MMCHS_DATA; // DMA4_CSSAi\r
- Dma4.DestinationStartAddress = (UINT32)BufferAddress; // DMA4_CDSAi\r
- Dma4.SourceElementIndex = 1; // DMA4_CSEi\r
- Dma4.SourceFrameIndex = 0x200; // DMA4_CSFi\r
- Dma4.DestinationElementIndex = 1; // DMA4_CDEi\r
- Dma4.DestinationFrameIndex = 0; // DMA4_CDFi\r
-\r
- Dma4.ReadPortAccessMode = 0; // DMA4_CCRi[13:12] Always read MMCHS_DATA\r
- Dma4.WritePortAccessMode = 1; // DMA4_CCRi[15:14] Post increment memory address\r
- Dma4.ReadRequestNumber = 0x1e; // DMA4_CCRi[4:0] Syncro with MMCA_DMA_RX (61) \r
+ 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) {
CmdInterruptEnable = CMD25_INT_EN;
DmaOperation = MapOperationBusMasterRead;
- Dma4.ReadPortAccessType = 3; // DMA4_CSDPi[8:7] Memory burst 16x32\r
- Dma4.WritePortAccessType = 0; // DMA4_CSDPi[15:14] Can not burst MMCHS_DATA reg\r
- Dma4.WriteMode = 1; // DMA4_CSDPi[17:16] Write posted ???\r
- \r
- Dma4.SourceStartAddress = (UINT32)BufferAddress; // DMA4_CSSAi\r
- Dma4.DestinationStartAddress = MMCHS_DATA; // DMA4_CDSAi\r
- Dma4.SourceElementIndex = 1; // DMA4_CSEi\r
- Dma4.SourceFrameIndex = 0x200; // DMA4_CSFi\r
- Dma4.DestinationElementIndex = 1; // DMA4_CDEi\r
- Dma4.DestinationFrameIndex = 0; // DMA4_CDFi\r
-\r
- Dma4.ReadPortAccessMode = 1; // DMA4_CCRi[13:12] Post increment memory address\r
- Dma4.WritePortAccessMode = 0; // DMA4_CCRi[15:14] Always write MMCHS_DATA\r
- Dma4.ReadRequestNumber = 0x1d; // DMA4_CCRi[4:0] Syncro with MMCA_DMA_TX (60) \r
+ 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 Status;
}
+ //Check for the Transfer completion.
+ while (RetryCount < MAX_RETRY_COUNT) {
+ //Read Status
+ do {
+ MmcStatus = MmioRead32 (MMCHS_STAT);
+ } while (MmcStatus == 0);
+
+ //Check if Transfer complete (TC) bit is set?
+ if (MmcStatus & TC) {
+ break;
+ } else {
+ DEBUG ((EFI_D_ERROR, "MmcStatus for TC: %x\n", MmcStatus));
+ //Check if DEB, DCRC or DTO interrupt occured.
+ if ((MmcStatus & DEB) | (MmcStatus & DCRC) | (MmcStatus & DTO)) {
+ //There was an error during the data transfer.
+
+ //Set SRD bit to 1 and wait until it return to 0x0.
+ MmioOr32 (MMCHS_SYSCTL, SRD);
+ while((MmioRead32 (MMCHS_SYSCTL) & SRD) != 0x0);
+
+ DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR);
+ DmaUnmap (BufferMap);
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ RetryCount++;
+ }
+
DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR);
Status = DmaUnmap (BufferMap);
+ if (RetryCount == MAX_RETRY_COUNT) {
+ DEBUG ((EFI_D_ERROR, "TransferBlockData timed out.\n"));
+ return EFI_TIMEOUT;
+ }
+
return Status;
}
UINTN BlockCount;
UINTN BytesToBeTranferedThisPass = 0;
UINTN BytesRemainingToBeTransfered;
- EFI_TPL OldTpl;\r
- BOOLEAN Update;\r
+ EFI_TPL OldTpl;
+
+ BOOLEAN Update;
+
Update = FALSE;
if (Update) {
DEBUG ((EFI_D_INFO, "SD Card ReinstallProtocolInterface ()\n"));
- gBS->ReinstallProtocolInterface (\r
- gImageHandle,\r
- &gEfiBlockIoProtocolGuid,\r
- &gBlockIo,\r
- &gBlockIo\r
- );\r
+ gBS->ReinstallProtocolInterface (
+ gImageHandle,
+ &gEfiBlockIoProtocolGuid,
+ &gBlockIo,
+ &gBlockIo
+ );
+ return EFI_MEDIA_CHANGED;
}
if (EFI_ERROR (Status)) {
goto DoneRestoreTPL;
}
- //BytesToBeTranferedThisPass = (BytesToBeTranferedThisPass >= MAX_MMCHS_TRANSFER_SIZE) ? MAX_MMCHS_TRANSFER_SIZE : BytesRemainingToBeTransfered;
+ // Turn OFF DMA path until it is debugged
+ // BytesToBeTranferedThisPass = (BytesToBeTranferedThisPass >= MAX_MMCHS_TRANSFER_SIZE) ? MAX_MMCHS_TRANSFER_SIZE : BytesRemainingToBeTransfered;
BytesToBeTranferedThisPass = This->Media->BlockSize;
BlockCount = BytesToBeTranferedThisPass/This->Media->BlockSize;
Buffer = (UINT8 *)Buffer + This->Media->BlockSize;
}
-DoneRestoreTPL:\r
- gBS->RestoreTPL (OldTpl);\r
-Done:\r
- return Status;\r
+DoneRestoreTPL:
+
+ gBS->RestoreTPL (OldTpl);
+
+Done:
+
+ return Status;
+
}
-/**\r
- Reset the Block Device.\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param ExtendedVerification Driver may perform diagnostics on reset.\r
-\r
- @retval EFI_SUCCESS The device was reset.\r
- @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
- not be reset.\r
-\r
+/**
+
+ Reset the Block Device.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+ @param ExtendedVerification Driver may perform diagnostics on reset.
+
+
+
+ @retval EFI_SUCCESS The device was reset.
+
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+
+ not be reset.
+
+
+
**/
EFI_STATUS
EFIAPI
}
-/**\r
- Read BufferSize bytes from Lba into Buffer.\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param MediaId Id of the media, changes every time the media is replaced.\r
- @param Lba The starting Logical Block Address to read from\r
- @param BufferSize Size of Buffer, must be a multiple of device block size.\r
- @param Buffer A pointer to the destination buffer for the data. The caller is\r
- responsible for either having implicit or explicit ownership of the buffer.\r
-\r
- @retval EFI_SUCCESS The data was read correctly from the device.\r
- @retval EFI_DEVICE_ERROR The device reported an error while performing the read.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.\r
- @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
- @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, \r
- or the buffer is not on proper alignment.\r
+/**
+
+ Read BufferSize bytes from Lba into Buffer.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+ @param MediaId Id of the media, changes every time the media is replaced.
+
+ @param Lba The starting Logical Block Address to read from
+
+ @param BufferSize Size of Buffer, must be a multiple of device block size.
+
+ @param Buffer A pointer to the destination buffer for the data. The caller is
+
+ responsible for either having implicit or explicit ownership of the buffer.
+
+
+
+ @retval EFI_SUCCESS The data was read correctly from the device.
+
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
+
+ @retval EFI_NO_MEDIA There is no media in the device.
+
+ @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
+
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
+
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
+
+ or the buffer is not on proper alignment.
+
EFI_STATUS
**/
//Perform Read operation.
Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, READ);
- return Status;\r
+ return Status;
+
}
-/**\r
- Write BufferSize bytes from Lba into Buffer.\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param MediaId The media ID that the write request is for.\r
- @param Lba The starting logical block address to be written. The caller is\r
- responsible for writing to only legitimate locations.\r
- @param BufferSize Size of Buffer, must be a multiple of device block size.\r
- @param Buffer A pointer to the source buffer for the data.\r
-\r
- @retval EFI_SUCCESS The data was written correctly to the device.\r
- @retval EFI_WRITE_PROTECTED The device can not be written to.\r
- @retval EFI_DEVICE_ERROR The device reported an error while performing the write.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.\r
- @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
- @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, \r
- or the buffer is not on proper alignment.\r
-\r
+/**
+
+ Write BufferSize bytes from Lba into Buffer.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+ @param MediaId The media ID that the write request is for.
+
+ @param Lba The starting logical block address to be written. The caller is
+
+ responsible for writing to only legitimate locations.
+
+ @param BufferSize Size of Buffer, must be a multiple of device block size.
+
+ @param Buffer A pointer to the source buffer for the data.
+
+
+
+ @retval EFI_SUCCESS The data was written correctly to the device.
+
+ @retval EFI_WRITE_PROTECTED The device can not be written to.
+
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
+
+ @retval EFI_NO_MEDIA There is no media in the device.
+
+ @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
+
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
+
+ @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
+
+ or the buffer is not on proper alignment.
+
+
+
**/
EFI_STATUS
EFIAPI
//Perform write operation.
Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, WRITE);
-\r
- return Status;\r
+
+
+ return Status;
+
}
-/**\r
- Flush the Block Device.\r
-\r
- @param This Indicates a pointer to the calling context.\r
-\r
- @retval EFI_SUCCESS All outstanding data was written to the device\r
- @retval EFI_DEVICE_ERROR The device reported an error while writting back the data\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
-\r
+/**
+
+ Flush the Block Device.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+
+
+ @retval EFI_SUCCESS All outstanding data was written to the device
+
+ @retval EFI_DEVICE_ERROR The device reported an error while writting back the data
+
+ @retval EFI_NO_MEDIA There is no media in the device.
+
+
+
**/
EFI_STATUS
EFIAPI
};
-/**\r
- Timer callback to convert card present hardware into a boolean that indicates\r
- a media change event has happened. If you just check the GPIO you could see \r
- card 1 and then check again after card 1 was removed and card 2 was inserted\r
- and you would still see media present. Thus you need the timer tick to catch\r
- the toggle event.\r
-\r
- @param Event Event whose notification function is being invoked.\r
- @param Context The pointer to the notification function's context,\r
- which is implementation-dependent. Not used.\r
-\r
+/**
+
+ Timer callback to convert card present hardware into a boolean that indicates
+
+ a media change event has happened. If you just check the GPIO you could see
+
+ card 1 and then check again after card 1 was removed and card 2 was inserted
+
+ and you would still see media present. Thus you need the timer tick to catch
+
+ the toggle event.
+
+
+
+ @param Event Event whose notification function is being invoked.
+
+ @param Context The pointer to the notification function's context,
+
+ which is implementation-dependent. Not used.
+
+
+
**/
VOID
EFIAPI