mmc/sd: support for SD v2.0 cards
Older cards did not implement CMD8, so handle the command stalling, and proceed with initialization (not querying about SDHC support in that case, as per the spec). Change-Id: Ie842effc2f99e1adf1990b3215be79db493138b5 Reviewed-on: https://review.haiku-os.org/c/1056 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
ff76d2df8e
commit
518af33f33
@ -89,8 +89,12 @@ MMCBus::WorkerThread(void* cookie)
|
||||
// SD v1 cards will also not reply, but we can proceed to ACMD41
|
||||
// If ACMD41 also does not work, it may be an SDIO card, too
|
||||
uint32_t probe = (1 << 8) | 0x55;
|
||||
bus->ExecuteCommand(8, probe, &response);
|
||||
if (response != probe) {
|
||||
uint32_t hcs = 1 << 30;
|
||||
if (bus->ExecuteCommand(8, probe, &response) != B_OK) {
|
||||
TRACE("Card does not implement CMD8, may be a V1 SD card\n");
|
||||
// Do not check for SDHC support in this case
|
||||
hcs = 0;
|
||||
} else if (response != probe) {
|
||||
ERROR("Card does not support voltage range (expected %x, reply %x)\n",
|
||||
probe, response);
|
||||
// TODO what now?
|
||||
@ -111,7 +115,7 @@ MMCBus::WorkerThread(void* cookie)
|
||||
if ((cardStatus & (1 << 5)) == 0)
|
||||
ERROR("Card did not enter ACMD mode");
|
||||
|
||||
bus->ExecuteCommand(41, (1 << 30) | 0xFF8000, &ocr);
|
||||
bus->ExecuteCommand(41, hcs | 0xFF8000, &ocr);
|
||||
|
||||
if ((ocr & (1 << 31)) == 0) {
|
||||
TRACE("Card is busy\n");
|
||||
@ -119,11 +123,11 @@ MMCBus::WorkerThread(void* cookie)
|
||||
}
|
||||
} while (((ocr & (1 << 31)) == 0));
|
||||
|
||||
if (ocr & (1 << 30))
|
||||
if (ocr & hcs != 0)
|
||||
TRACE("Card is SDHC");
|
||||
if (ocr & (1 << 29))
|
||||
if (ocr & (1 << 29) != 0)
|
||||
TRACE("Card supports UHS-II");
|
||||
if (ocr & (1 << 24))
|
||||
if (ocr & (1 << 24) != 0)
|
||||
TRACE("Card supports 1.8v");
|
||||
TRACE("Voltage range: %x\n", ocr & 0xFFFFFF);
|
||||
|
||||
|
@ -120,6 +120,7 @@ SdhciBus::SdhciBus(struct registers* registers, uint8_t irq)
|
||||
| SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | SDHCI_INT_INDEX
|
||||
| SDHCI_INT_BUS_POWER | SDHCI_INT_END_BIT);
|
||||
|
||||
fRegisters->interrupt_status_enable |= SDHCI_INT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -224,6 +225,21 @@ SdhciBus::ExecuteCommand(uint8_t command, uint32_t argument, uint32_t* response)
|
||||
fRegisters->command.SendCommand(command, replyType);
|
||||
acquire_sem(fSemaphore);
|
||||
|
||||
if (fRegisters->interrupt_status & SDHCI_INT_ERROR) {
|
||||
fRegisters->interrupt_status |= SDHCI_INT_ERROR;
|
||||
ERROR("Command execution failed\n");
|
||||
// TODO look at errors in interrupt_status register for more details
|
||||
// and return a more appropriate error code
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (fRegisters->present_state.CommandInhibit()) {
|
||||
TRACE("Command execution failed, card stalled\n");
|
||||
// Clear the stall
|
||||
fRegisters->software_reset.ResetCommandLine();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (replyType == Command::kNoReplyType) {
|
||||
// No response
|
||||
} else if (replyType == Command::kR2Type) {
|
||||
@ -437,7 +453,7 @@ SdhciBus::RecoverError()
|
||||
| SDHCI_INT_TRANS_CMP | SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM);
|
||||
|
||||
if (fRegisters->interrupt_status & 7)
|
||||
fRegisters->software_reset.ResetTransaction();
|
||||
fRegisters->software_reset.ResetCommandLine();
|
||||
|
||||
int16_t error_status = fRegisters->interrupt_status;
|
||||
fRegisters->interrupt_status &= ~(error_status);
|
||||
|
@ -113,7 +113,7 @@ class SoftwareReset {
|
||||
while(fBits & 1);
|
||||
}
|
||||
|
||||
void ResetTransaction() {
|
||||
void ResetCommandLine() {
|
||||
fBits |= 2;
|
||||
while(fBits & 2);
|
||||
}
|
||||
@ -128,6 +128,7 @@ class SoftwareReset {
|
||||
#define SDHCI_INT_TRANS_CMP 0x00000002 // transfer complete enable
|
||||
#define SDHCI_INT_CARD_INS 0x00000040 // card insertion enable
|
||||
#define SDHCI_INT_CARD_REM 0x00000080 // card removal enable
|
||||
#define SDHCI_INT_ERROR 0x00008000 // error
|
||||
#define SDHCI_INT_TIMEOUT 0x00010000 // Timeout error
|
||||
#define SDHCI_INT_CRC 0x00020000 // CRC error
|
||||
#define SDHCI_INT_END_BIT 0x00040000 // end bit error
|
||||
|
Loading…
Reference in New Issue
Block a user