[SeaBIOS] [PATCH 5/5] sdcard: Improve SD card initialization command sequence
Kevin O'Connor
kevin at koconnor.net
Fri Jul 31 00:36:23 CEST 2015
Send the initialization commands that are specified for SD cards by
the "SD Host Controller Simplified Specification Version 2.00" spec.
Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
src/hw/sdcard.c | 44 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/src/hw/sdcard.c b/src/hw/sdcard.c
index 39cb5ba..c12c263 100644
--- a/src/hw/sdcard.c
+++ b/src/hw/sdcard.c
@@ -56,9 +56,11 @@ struct sdhci_s {
} PACKED;
// SDHCI commands
+#define SC_GO_IDLE_STATE ((0<<8) | 0x20)
#define SC_ALL_SEND_CID ((2<<8) | 0x21)
#define SC_SEND_RELATIVE_ADDR ((3<<8) | 0x22)
#define SC_SELECT_DESELECT_CARD ((7<<8) | 0x23)
+#define SC_SEND_IF_COND ((8<<8) | 0x22)
#define SC_READ_SINGLE ((17<<8) | 0x22)
#define SC_READ_MULTIPLE ((18<<8) | 0x22)
#define SC_WRITE_SINGLE ((24<<8) | 0x22)
@@ -99,9 +101,11 @@ struct sdhci_s {
#define SPC_V33 0x0e
// SDHCI result flags
-#define SR_OCR_CCS (1<<30)
+#define SR_OCR_CCS (1<<30)
+#define SR_OCR_NOTBUSY (1<<31)
// SDHCI timeouts
+#define SDHCI_POWERUP_TIMEOUT 1000
#define SDHCI_PIO_TIMEOUT 1000 // XXX - these are just made up
#define SDHCI_TRANSFER_TIMEOUT 10000
@@ -151,6 +155,8 @@ sdcard_pio(struct sdhci_s *regs, int cmd, u32 *param)
writew(®s->irq_status, SI_CMD_COMPLETE);
// Read response
memcpy(param, regs->response, sizeof(regs->response));
+ dprintf(9, "sdcard cmd %x response %x %x %x %x\n"
+ , cmd, param[0], param[1], param[2], param[3]);
return 0;
}
@@ -249,16 +255,46 @@ static int
sdcard_card_setup(struct sdhci_s *regs)
{
// XXX - works on QEMU; probably wont on real hardware!
- u32 param[4] = { 0x01 };
- int ret = sdcard_pio_app(regs, SC_APP_SEND_OP_COND, param);
+
+ // Reset card
+ u32 param[4] = { };
+ int ret = sdcard_pio_app(regs, SC_GO_IDLE_STATE, param);
+ if (ret)
+ return ret;
+ // Let card know SDHC/SDXC is supported and confirm voltage
+ param[0] = 0x1aa;
+ ret = sdcard_pio_app(regs, SC_SEND_IF_COND, param);
+ if (ret)
+ return ret;
+ u32 hcs = 0;
+ if (param[0] == 0x1aa)
+ hcs = 0x40000000;
+ // Verify SD card (instead of MMC or SDIO)
+ param[0] = 0x00;
+ ret = sdcard_pio_app(regs, SC_APP_SEND_OP_COND, param);
if (ret)
return ret;
+ // Init card
+ u32 end = timer_calc(SDHCI_POWERUP_TIMEOUT);
+ for (;;) {
+ param[0] = hcs | (1<<20); // SDHC support and voltage level
+ ret = sdcard_pio_app(regs, SC_APP_SEND_OP_COND, param);
+ if (ret)
+ return ret;
+ if (param[0] & SR_OCR_NOTBUSY)
+ break;
+ if (timer_check(end)) {
+ warn_timeout();
+ return -1;
+ }
+ }
int card_type = (param[0] & SR_OCR_CCS) ? SF_SDHC : SF_SDSC;
param[0] = 0x00;
+ // Select card
ret = sdcard_pio(regs, SC_ALL_SEND_CID, param);
if (ret)
return ret;
- param[0] = 0x01 << 16;
+ param[0] = 0x00;
ret = sdcard_pio(regs, SC_SEND_RELATIVE_ADDR, param);
if (ret)
return ret;
--
1.9.3
More information about the SeaBIOS
mailing list