[SeaBIOS] Failure to detect high-capacity SD card

Kevin O'Connor kevin at koconnor.net
Fri Feb 23 17:24:57 CET 2018


On Fri, Feb 23, 2018 at 07:06:24AM -0500, Chris wrote:
> On Fri, Feb 23, 2018 at 12:24 AM, Kevin O'Connor <kevin at koconnor.net> wrote:
> > This looks to be very similar to the issue Matt raised back in
> > October.  It seems the card needs to run at 1.8 volt (instead of 3.3
> > volt), but it seems to shutdown before telling seabios that.
> >
> > Can you apply the patch at:
> >
> > https://mail.coreboot.org/pipermail/seabios/2017-October/011892.html
> >
> > set the seabios debug level to 3, and send the log again?
> 
> Yes, I believe we're using the same hardware.
> 
> With the patch it still fails.
> 
> During boot devices were:
> * mmcblk0 internal 64GB SSD (detected).
> * mmcblk1 internal card reader with 64GB bootable card in it (fails to
> be detected).
> * External USB reader that has 2 slots, one is empty, the other has a
> 1GB microsd (detected).
> 
> Log:
> https://pastebin.com/L0dhPN8G
> 
> Looks like the same problem where the card won't respond and times out.

Yes - the card stops responding early in the process, which is odd.
What does the patch below report?

-Kevin


diff --git a/src/hw/sdcard.c b/src/hw/sdcard.c
index 6410340..44082bf 100644
--- a/src/hw/sdcard.c
+++ b/src/hw/sdcard.c
@@ -66,6 +66,7 @@ struct sdhci_s {
 #define SC_SEND_OP_COND         ((1<<8) | SCB_R48o)
 #define SC_ALL_SEND_CID         ((2<<8) | SCB_R136)
 #define SC_SEND_RELATIVE_ADDR   ((3<<8) | SCB_R48)
+#define SC_IO_SEND_OP_COND      ((5<<8) | SCB_R48o)
 #define SC_SELECT_DESELECT_CARD ((7<<8) | SCB_R48b)
 #define SC_SEND_IF_COND         ((8<<8) | SCB_R48)
 #define SC_SEND_EXT_CSD         ((8<<8) | SCB_R48d)
@@ -123,6 +124,17 @@ struct sdhci_s {
 #define SRF_DATA 0x04
 
 // SDHCI result flags
+#define SR_OCR_VDD_165_195 (1<<7)
+#define SR_OCR_VDD_27_28   (1<<15)
+#define SR_OCR_VDD_28_29   (1<<16)
+#define SR_OCR_VDD_29_30   (1<<17)
+#define SR_OCR_VDD_30_31   (1<<18)
+#define SR_OCR_VDD_31_32   (1<<19)
+#define SR_OCR_VDD_32_33   (1<<20)
+#define SR_OCR_VDD_33_34   (1<<21)
+#define SR_OCR_VDD_34_35   (1<<22)
+#define SR_OCR_VDD_35_36   (1<<23)
+#define SR_OCR_S18R    (1<<24)
 #define SR_OCR_CCS     (1<<30)
 #define SR_OCR_NOTBUSY (1<<31)
 
@@ -181,7 +193,7 @@ static int
 sdcard_pio(struct sdhci_s *regs, int cmd, u32 *param)
 {
     u32 state = readl(&regs->present_state);
-    dprintf(9, "sdcard_pio cmd %x %x %x\n", cmd, *param, state);
+    dprintf(1, "sdcard_pio cmd %x %x %x\n", cmd, *param, state);
     if ((state & SP_CMD_INHIBIT)
         || ((cmd & 0x03) == 0x03 && state & SP_DAT_INHIBIT)) {
         dprintf(1, "sdcard_pio not ready %x\n", state);
@@ -203,7 +215,7 @@ sdcard_pio(struct sdhci_s *regs, int cmd, u32 *param)
     writew(&regs->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"
+    dprintf(1, "sdcard cmd %x response %x %x %x %x\n"
             , cmd, param[0], param[1], param[2], param[3]);
     return 0;
 }
@@ -302,13 +314,13 @@ sdcard_set_power(struct sdhci_s *regs)
     u32 cap = readl(&regs->cap_lo);
     u32 volt, vbits;
     if (cap & SD_CAPLO_V33) {
-        volt = 1<<20;
+        volt = SR_OCR_VDD_32_33 | SR_OCR_VDD_33_34;
         vbits = SPC_V33;
     } else if (cap & SD_CAPLO_V30) {
-        volt = 1<<18;
+        volt = SR_OCR_VDD_29_30 | SR_OCR_VDD_30_31;
         vbits = SPC_V30;
     } else if (cap & SD_CAPLO_V18) {
-        volt = 1<<7;
+        volt = SR_OCR_VDD_165_195;
         vbits = SPC_V18;
     } else {
         dprintf(1, "SD controller unsupported volt range (%x)\n", cap);
@@ -399,11 +411,11 @@ sdcard_card_setup(struct sddrive_s *drive, int volt, int prio)
     if (ret)
         return ret;
     // Let card know SDHC/SDXC is supported and confirm voltage
-    u32 hcs = 0, vrange = (volt >= (1<<15) ? 0x100 : 0x200) | 0xaa;
+    u32 hcs = 0, vrange = (volt >= SR_OCR_VDD_27_28 ? 0x100 : 0x200) | 0xaa;
     param[0] = vrange;
     ret = sdcard_pio(regs, SC_SEND_IF_COND, param);
     if (!ret && param[0] == vrange)
-        hcs = (1<<30);
+        hcs = SR_OCR_CCS | (1<<28);
     // Verify SD card (instead of MMC or SDIO)
     param[0] = 0x00;
     ret = sdcard_pio_app(regs, SC_APP_SEND_OP_COND, param);
@@ -414,8 +426,17 @@ sdcard_card_setup(struct sddrive_s *drive, int volt, int prio)
         if (ret)
             return ret;
         drive->card_type |= SF_MMC;
-        hcs = (1<<30);
+        hcs = SR_OCR_CCS;
+    } else {
+        // Check for SDIO
+        param[0] = 0x00;
+        ret = sdcard_pio(regs, SC_IO_SEND_OP_COND, param);
+        dprintf(1, "Ignoring SDIO response %d\n", ret);
     }
+    // XXX
+    if (volt == (SR_OCR_VDD_32_33 | SR_OCR_VDD_33_34)
+        && hcs && readl(&regs->cap_lo) & SD_CAPLO_V18)
+        hcs |= SR_OCR_S18R;
     // Init card
     u32 end = timer_calc(SDHCI_POWERUP_TIMEOUT);
     for (;;) {
@@ -434,6 +455,10 @@ sdcard_card_setup(struct sddrive_s *drive, int volt, int prio)
         }
         msleep(5); // Avoid flooding log when debugging
     }
+    if (param[0] & SR_OCR_S18R) {
+        dprintf(1, "Card requests 1.8 volt\n");
+        return -1;
+    }
     drive->card_type |= (param[0] & SR_OCR_CCS) ? SF_HIGHCAPACITY : 0;
     // Select card (get cid, set rca, get csd, select card)
     param[0] = 0x00;



More information about the SeaBIOS mailing list