Jelajahi Sumber

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 tahun lalu
induk
melakukan
6ead9a1ad1
6 mengubah file dengan 1674 tambahan dan 1661 penghapusan
  1. TEMPAT SAMPAH
      fpga/output_files/max80.jbc
  2. TEMPAT SAMPAH
      fpga/output_files/max80.jic
  3. TEMPAT SAMPAH
      fpga/output_files/max80.pof
  4. TEMPAT SAMPAH
      fpga/output_files/max80.sof
  5. 1645 1645
      fw/boot.mif
  6. 29 16
      fw/sdcard.c

TEMPAT SAMPAH
fpga/output_files/max80.jbc


TEMPAT SAMPAH
fpga/output_files/max80.jic


TEMPAT SAMPAH
fpga/output_files/max80.pof


TEMPAT SAMPAH
fpga/output_files/max80.sof


File diff ditekan karena terlalu besar
+ 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);
 }
-

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini