|
@@ -153,7 +153,7 @@ static int sdcard_send_cmd(uint8_t opcode, uint32_t argument)
|
|
|
if (!opcode)
|
|
|
return 0; /* No command */
|
|
|
|
|
|
- dbg_printf("sdcard: CMD%02u arg %08x:", opcode ^ 0x40, argument);
|
|
|
+ dbg_printf("sdcard: CMD%u arg %08x:", opcode ^ 0x40, argument);
|
|
|
|
|
|
sd_writeb(opcode, SD_GO8|SD_CLEARCRC);
|
|
|
sd_writel(argument, SD_BE|SD_GO32);
|
|
@@ -335,7 +335,7 @@ int sdcard_read_sectors(void *buf, uint32_t lba, int count)
|
|
|
|
|
|
sdcard_led_on();
|
|
|
|
|
|
- con_printf("sdcard: reading %d sector%s at %u to %p\n",
|
|
|
+ dbg_printf("sdcard: reading %d sector%s at %u to %p\n",
|
|
|
count, (count != 1) ? "s" : "", lba, buf);
|
|
|
|
|
|
if (sdc.card_type == 1)
|
|
@@ -448,7 +448,7 @@ int sdcard_write_sectors(const void *buf, uint32_t lba, int count)
|
|
|
|
|
|
sdcard_led_on();
|
|
|
|
|
|
- con_printf("sdcard: writing %d sectors at %u from %p\n", count, lba, buf);
|
|
|
+ dbg_printf("sdcard: writing %d sectors at %u from %p\n", count, lba, buf);
|
|
|
|
|
|
if (sdc.card_type == 1)
|
|
|
lba <<= SECTOR_SHIFT; /* Convert to a byte address */
|
|
@@ -610,44 +610,52 @@ static const char *sdcard_type_name(uint8_t type)
|
|
|
return names[type];
|
|
|
}
|
|
|
|
|
|
+static int sdcard_switch_func_cmd(uint32_t arg, void *buf)
|
|
|
+{
|
|
|
+ uint32_t rv = sdcard_send_cmd(CMD_SWITCH_FUNC, arg);
|
|
|
+ if (rv & ~1) {
|
|
|
+ dbg_printf("sdcard: CMD6 %08x returned %02x\n", arg, rv);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (sdcard_read_block(buf, 64, 200000, 0, 0)) {
|
|
|
+ dbg_printf("sdcard: no CMD6 %08x query reply\n", arg);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+#ifdef DEBUG
|
|
|
+ dbg_puts("sdcard: CMD6:");
|
|
|
+ for (int i = 0; i < 64; i++)
|
|
|
+ dbg_printf(" %02x", ((uint8_t *)buf)[i]);
|
|
|
+ dbg_putc('\n');
|
|
|
+#endif
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* Try to switch to high speed mode (50 MHz) */
|
|
|
static void sdcard_try_high_speed(void)
|
|
|
{
|
|
|
int rv;
|
|
|
uint8_t tran_speed;
|
|
|
+ uint8_t cmd6data[64];
|
|
|
|
|
|
- return;
|
|
|
-
|
|
|
- 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 & ~1) {
|
|
|
- dbg_printf("sdcard: CMD6 returned %02x\n", rv);
|
|
|
+ /* Verify support for CMD6, part of command group 10 */
|
|
|
+ if (!(sdc.csd.raw[1] & (1 << 30))) {
|
|
|
+ dbg_printf("sdcard: CMD6 not supported\n");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (1) {
|
|
|
- /*
|
|
|
- * Despite the spec, this doesn't seem to actually happen
|
|
|
- * in SPI mode?
|
|
|
- */
|
|
|
- uint8_t swdata[64]; /* Response from CMD6 */
|
|
|
- int i;
|
|
|
-
|
|
|
- for (i = 0; i < 64; i++)
|
|
|
- swdata[i] = sd_readb(SD_GO8);
|
|
|
+ /* Try to switch to access mode 1 */
|
|
|
+ if (sdcard_switch_func_cmd(0x80fffff1, cmd6data))
|
|
|
+ return;
|
|
|
|
|
|
- if ((swdata[47] & 0x0f) != 1) {
|
|
|
- dbg_printf("sdcard: CMD6 reported %X for high speed request\n",
|
|
|
- swdata[47] & 0x0f);
|
|
|
- return; /* Failed to switch to high speed mode */
|
|
|
- }
|
|
|
+ /* Did we? */
|
|
|
+ if ((cmd6data[16] & 0x0f) != 1) {
|
|
|
+ dbg_printf("sdcard: switch to high speed mode rejected\n");
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Success, we should have switched mode.
|
|
|
- * This should be refleded in the TRAN_SPEED field in the CSD.
|
|
|
+ * If we succeeded, we will have switched mode.
|
|
|
+ * This should be reflected in the TRAN_SPEED field in the CSD.
|
|
|
*/
|
|
|
sd_readl(SD_GO32); /* Issue at least 8 clocks; go for 32 */
|
|
|
|
|
@@ -661,7 +669,7 @@ static void sdcard_try_high_speed(void)
|
|
|
((tran_speed & 7) == 2 && (tran_speed >> 3) < 0xb)) {
|
|
|
dbg_printf("sdcard: speed switch failed, tran_speed %02x\n",
|
|
|
tran_speed);
|
|
|
- return; /* High speed not available */
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
sd_set_mode(SD_50MHZ, true);
|
|
@@ -872,5 +880,7 @@ int disk_init(void)
|
|
|
con_printf("sdcard: %u/%u clusters free, clusters = %u bytes\n",
|
|
|
freeclust, fs->n_fatent - 2, fs->csize << 9);
|
|
|
|
|
|
+ mount_abcdrives();
|
|
|
+
|
|
|
return 0;
|
|
|
}
|