Browse Source

sdcard: fix switching to high speed mode

CMD6 doesn't seem to quite work the way it is documented when in SPI
mode. Just ignore the expected data dump and it all seems good.
H. Peter Anvin 3 years ago
parent
commit
6ead9a1ad1
6 changed files with 1674 additions and 1661 deletions
  1. BIN
      fpga/output_files/max80.jbc
  2. BIN
      fpga/output_files/max80.jic
  3. BIN
      fpga/output_files/max80.pof
  4. BIN
      fpga/output_files/max80.sof
  5. 1645 1645
      fw/boot.mif
  6. 29 16
      fw/sdcard.c

BIN
fpga/output_files/max80.jbc


BIN
fpga/output_files/max80.jic


BIN
fpga/output_files/max80.pof


BIN
fpga/output_files/max80.sof


File diff suppressed because it is too large
+ 1645 - 1645
fw/boot.mif


+ 29 - 16
fw/sdcard.c

@@ -37,7 +37,7 @@
 
 /* Command codes, including the leading 01 sequence */
 enum sdcard_cmd {
-    CMD_GO_IDLE_STATE 		= 0x40,	/* a.k.a. reset */
+    CMD_GO_IDLE_STATE		= 0x40,	/* a.k.a. reset */
     CMD_SEND_OP_COND		= 0x41,
     CMD_SWITCH_FUNC		= 0x46,
     CMD_SEND_IF_COND		= 0x48,
@@ -136,7 +136,7 @@ static int sdcard_send_cmd(uint8_t opcode, uint32_t argument)
 
     if (!opcode)
 	return 0;		/* No command */
-    
+
     sd_writeb(opcode, SD_GO8|SD_CLEARCRC);
     sd_writel(argument, SD_BE|SD_GO32);
     /*
@@ -195,7 +195,7 @@ static int sdcard_read_block(void *buf, int len, int timeout,
     int i;
 
     p.b = buf;
-    
+
     for (;;) {
 	tok = sd_readb(SD_GO8|SD_CLEARCRC);
 	if (tok == 0xfe)
@@ -215,7 +215,7 @@ static int sdcard_read_block(void *buf, int len, int timeout,
      * the input shift register. After dealing with alignment,
      * use dummy reads to shift in the rest of the first longword.
      */
-    
+
     /* Shift in bytes if needed for alignment */
     if (p.a & 1) {
 	*p.b++ = sd_readb(SD_GO8);
@@ -426,7 +426,7 @@ int sdcard_write_sectors(const void *buf, uint32_t lba, int count)
 	    sd_writel(*p.l++, SD_GO32);
 
 	podd = -podd;
-	
+
 	if (podd & 2)
 	    sd_writeh(*p.w++, SD_GO16);
 	if (podd & 1)
@@ -561,22 +561,36 @@ static const char *sdcard_type_name(uint8_t type)
 static void sdcard_try_high_speed(void)
 {
     int rv;
-    uint8_t swdata[64];		/* Response from CMD6 */
 
     if (!(sdc.csd.raw[1] & (1 << 30)))
 	return;			/* Cmd group 10 = CMD6 not supported */
 
     /* Try to switch to high speed mode */
     rv = sdcard_send_cmd(CMD_SWITCH_FUNC, 0x80fffff1);
-    if (rv)
+    if (rv) {
+	con_printf("sdcard: CMD6 returned %02x\n", rv);
 	return;
+    }
 
-    rv = sdcard_read_block(swdata, sizeof swdata, 2000, 0, 0);
-    if (rv)
-	return;
+    if (0) {
+	/*
+	 * Despite the spec, this doesn't seem to actually happen
+	 * in SPI mode?
+	 */
+	uint8_t swdata[64];		/* Response from CMD6 */
 
-    if ((swdata[47] & 0x0f) != 1)
-	return;			/* Failed to switch to high speed mode */
+	rv = sdcard_read_block(swdata, sizeof swdata, 2000, 0, 0);
+	if (rv) {
+	    con_printf("sdcard: CMD6 failed to return data\n");
+	    return;
+	}
+
+	if ((swdata[47] & 0x0f) != 1) {
+	    con_printf("sdcard: CMD6 reported %X for high speed request\n",
+		       swdata[47] & 0x0f);
+	    return;		/* Failed to switch to high speed mode */
+	}
+    }
 
     /* Success, now switch mode! */
     sd_readl(SD_GO32);		/* Issue at least 8 clocks; go for 32 */
@@ -689,7 +703,7 @@ DSTATUS disk_initialize(BYTE drive)
     if (!rv) {
 	/* ACMD41 successful; this is an SD card: can switch to 25 MHz */
 	is_sd = true;
-	
+
 	sd_set_mode(SD_25MHZ, true);
 	rv = sdcard_send_cmd(CMD_READ_OCR, try_sdhc);
 	if (rv) {
@@ -704,7 +718,7 @@ DSTATUS disk_initialize(BYTE drive)
     } else {
 	/* ACMD41 unsupported, try CMD1 */
 	is_sd = false;
-		
+
 	do {
 	    rv = sdcard_send_cmd(CMD_SEND_OP_COND, 0);
 	    if (rv & ~0x01) {
@@ -752,7 +766,7 @@ DSTATUS disk_initialize(BYTE drive)
      */
     if (is_sd)
 	sdcard_try_high_speed();
-    
+
     sdc.status = 0;
 
     sdcard_led_off();
@@ -773,4 +787,3 @@ int disk_init(void)
 {
     return f_mount(&sd_fs, "", 1);
 }
-

Some files were not shown because too many files changed in this diff