Procházet zdrojové kódy

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 před 3 roky
rodič
revize
6ead9a1ad1
6 změnil soubory, kde provedl 1674 přidání a 1661 odebrání
  1. binární
      fpga/output_files/max80.jbc
  2. binární
      fpga/output_files/max80.jic
  3. binární
      fpga/output_files/max80.pof
  4. binární
      fpga/output_files/max80.sof
  5. 1645 1645
      fw/boot.mif
  6. 29 16
      fw/sdcard.c

binární
fpga/output_files/max80.jbc


binární
fpga/output_files/max80.jic


binární
fpga/output_files/max80.pof


binární
fpga/output_files/max80.sof


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 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);
 }
-

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů