瀏覽代碼

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 年之前
父節點
當前提交
6ead9a1ad1
共有 6 個文件被更改,包括 1674 次插入1661 次删除
  1. 二進制
      fpga/output_files/max80.jbc
  2. 二進制
      fpga/output_files/max80.jic
  3. 二進制
      fpga/output_files/max80.pof
  4. 二進制
      fpga/output_files/max80.sof
  5. 1645 1645
      fw/boot.mif
  6. 29 16
      fw/sdcard.c

二進制
fpga/output_files/max80.jbc


二進制
fpga/output_files/max80.jic


二進制
fpga/output_files/max80.pof


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

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