jz47xx: Further SD driver improvements

* Get rid of the SD_CIM_RESET meta-command and put all
   reset/init logic into one place
 * Don't double-issue the SD_GO_IDLE_STATE command
 * Explicitly set lowest speed upon reset

Change-Id: I5abfe9f64997e39087b8a77d525f90c77733a1a8
This commit is contained in:
Solomon Peachy 2026-02-17 17:32:03 -05:00
parent e8b75a52ab
commit 41567532a1
2 changed files with 13 additions and 62 deletions

View file

@ -92,10 +92,6 @@ enum sd_result_t
#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ #define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */
#define SD_CLOCK_HIGH 48000000 /* 48 MHz for SD Cards */ #define SD_CLOCK_HIGH 48000000 /* 48 MHz for SD Cards */
/* Extra commands for state control */
/* Use negative numbers to disambiguate */
#define SD_CIM_RESET -1
/* Proprietary commands, illegal/reserved according to SD Specification 2.00 */ /* Proprietary commands, illegal/reserved according to SD Specification 2.00 */
/* class 1 */ /* class 1 */
#define SD_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ #define SD_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
@ -650,24 +646,10 @@ static int jz_sd_exec_cmd(struct sd_request *request)
/* Stop clock when programming things */ /* Stop clock when programming things */
jz_sd_stop_clock(); /* stop SD clock */ jz_sd_stop_clock(); /* stop SD clock */
if (request->cmd == SD_CIM_RESET) {
/* On reset, 1-bit bus width */
use_4bit = 0;
/* Reset MMC/SD controller */
__msc_reset();
/* On reset, drop SD clock down */
jz_sd_set_clock(MMC_CLOCK_SLOW);
/* On reset, stop SD clock */
jz_sd_stop_clock();
}
/* Generic handling for all requests with data rx/tx */ /* Generic handling for all requests with data rx/tx */
if (has_data) { if (has_data) {
cmdat |= MSC_CMDAT_DATA_EN; cmdat |= MSC_CMDAT_DATA_EN;
// if (request->nob > 1 && use_sbc[drive]) // if (request->nob > 1 && use_sbc)
// cmdat |= MSC_CMDAT_SEND_AS_STOP; // cmdat |= MSC_CMDAT_SEND_AS_STOP;
#ifdef SD_DMA_ENABLE #ifdef SD_DMA_ENABLE
if (request->cnt >= 512) if (request->cnt >= 512)
@ -689,12 +671,10 @@ static int jz_sd_exec_cmd(struct sd_request *request)
/* Per-command type handling */ /* Per-command type handling */
switch (request->cmd) switch (request->cmd)
{ {
/* SD core extra command */
case SD_CIM_RESET:
cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */
break;
/* bc - broadcast - no response */ /* bc - broadcast - no response */
case SD_GO_IDLE_STATE: case SD_GO_IDLE_STATE:
cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */
/* Intentional Fallthrough */
case SD_SET_DSR: case SD_SET_DSR:
break; break;
@ -767,10 +747,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
} }
/* Set command index */ /* Set command index */
if (request->cmd == SD_CIM_RESET) REG_MSC_CMD = request->cmd;
REG_MSC_CMD = SD_GO_IDLE_STATE;
else
REG_MSC_CMD = request->cmd;
/* Set argument */ /* Set argument */
REG_MSC_ARG = request->arg; REG_MSC_ARG = request->arg;
@ -915,6 +892,7 @@ static void jz_sd_hardware_init(void)
SD_RESET(); /* reset mmc/sd controller */ SD_RESET(); /* reset mmc/sd controller */
SD_IRQ_MASK(); /* mask all IRQs */ SD_IRQ_MASK(); /* mask all IRQs */
jz_sd_stop_clock(); /* stop SD clock */ jz_sd_stop_clock(); /* stop SD clock */
jz_sd_set_clock(MMC_CLOCK_SLOW); /* Drop to lowest speed */
#ifdef SD_DMA_ENABLE #ifdef SD_DMA_ENABLE
// __cpm_start_dmac(); // __cpm_start_dmac();
// __dmac_enable_module(); // __dmac_enable_module();
@ -1209,6 +1187,7 @@ static int __sd_init_device(void)
memset(&card, 0, sizeof(tCardInfo)); memset(&card, 0, sizeof(tCardInfo));
use_4bit = 0; use_4bit = 0;
use_sbc = 0;
/* reset mmc/sd controller */ /* reset mmc/sd controller */
jz_sd_hardware_init(); jz_sd_hardware_init();
@ -1216,7 +1195,6 @@ static int __sd_init_device(void)
if (!card_detect_target()) if (!card_detect_target())
return 0; return 0;
sd_simple_cmd(&init_req, SD_CIM_RESET, 0, RESPONSE_NONE);
sd_simple_cmd(&init_req, SD_GO_IDLE_STATE, 0, RESPONSE_NONE); sd_simple_cmd(&init_req, SD_GO_IDLE_STATE, 0, RESPONSE_NONE);
sleep(HZ/2); /* Give the card/controller some rest */ sleep(HZ/2); /* Give the card/controller some rest */

View file

@ -107,10 +107,6 @@ enum sd_result_t
#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ #define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */
#define SD_CLOCK_HIGH 48000000 /* 48 MHz for SD Cards */ #define SD_CLOCK_HIGH 48000000 /* 48 MHz for SD Cards */
/* Extra commands for state control */
/* Use negative numbers to disambiguate */
#define SD_CIM_RESET -1
/* Proprietary commands, illegal/reserved according to SD Specification 2.00 */ /* Proprietary commands, illegal/reserved according to SD Specification 2.00 */
/* class 1 */ /* class 1 */
#define SD_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ #define SD_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
@ -729,26 +725,6 @@ static int jz_sd_exec_cmd(const int drive, struct sd_request *request)
jz_sd_stop_clock(drive); /* stop SD clock */ jz_sd_stop_clock(drive); /* stop SD clock */
#endif #endif
if (request->cmd == SD_CIM_RESET) {
/* On reset, 1-bit bus width */
use_4bit[drive] = 0;
/* On reset, stop SD clock */
jz_sd_stop_clock(drive);
/* Reset MMC/SD controller */
__msc_reset(MSC_CHN(drive));
/* Drop SD clock down to lowest speed */
jz_sd_set_clock(drive, MMC_CLOCK_SLOW);
#if SD_AUTO_CLOCK
/* Re-enable clocks */
REG_MSC_STRPCL(MSC_CHN(drive)) = MSC_STRPCL_CLOCK_CONTROL_START;
REG_MSC_LPM(drive) = MSC_SET_LPM;
#endif
}
/* Generic handling for all requests with data rx/tx */ /* Generic handling for all requests with data rx/tx */
if (has_data) { if (has_data) {
cmdat |= MSC_CMDAT_DATA_EN; cmdat |= MSC_CMDAT_DATA_EN;
@ -771,12 +747,11 @@ static int jz_sd_exec_cmd(const int drive, struct sd_request *request)
/* Per-command type handling */ /* Per-command type handling */
switch (request->cmd) switch (request->cmd)
{ {
/* SD core extra command */
case SD_CIM_RESET:
cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */
break;
/* bc - broadcast - no response */ /* bc - broadcast - no response */
case SD_GO_IDLE_STATE: case SD_GO_IDLE_STATE:
cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */
/* Intentional Fallthrough */
case SD_SET_DSR: case SD_SET_DSR:
break; break;
@ -792,7 +767,7 @@ static int jz_sd_exec_cmd(const int drive, struct sd_request *request)
case SD_READ_SINGLE_BLOCK: case SD_READ_SINGLE_BLOCK:
case SD_READ_MULTIPLE_BLOCK: case SD_READ_MULTIPLE_BLOCK:
case SD_SWITCH_FUNC: case SD_SWITCH_FUNC:
/* These READ data */ /* These READ data */
break; break;
case SD_WRITE_DAT_UNTIL_STOP: case SD_WRITE_DAT_UNTIL_STOP:
@ -859,10 +834,7 @@ static int jz_sd_exec_cmd(const int drive, struct sd_request *request)
} }
/* Set command index */ /* Set command index */
if (request->cmd == SD_CIM_RESET) REG_MSC_CMD(MSC_CHN(drive)) = request->cmd;
REG_MSC_CMD(MSC_CHN(drive)) = SD_GO_IDLE_STATE;
else
REG_MSC_CMD(MSC_CHN(drive)) = request->cmd;
/* Set argument */ /* Set argument */
REG_MSC_ARG(MSC_CHN(drive)) = request->arg; REG_MSC_ARG(MSC_CHN(drive)) = request->arg;
@ -1029,6 +1001,7 @@ static void jz_sd_hardware_init(const int drive)
#else #else
jz_sd_stop_clock(drive); /* stop SD clock */ jz_sd_stop_clock(drive); /* stop SD clock */
#endif #endif
jz_sd_set_clock(drive, MMC_CLOCK_SLOW); /* Drop to lowest speed */
} }
static void sd_send_cmd(const int drive, struct sd_request *request, int cmd, unsigned int arg, static void sd_send_cmd(const int drive, struct sd_request *request, int cmd, unsigned int arg,
@ -1317,6 +1290,7 @@ static int __sd_init_device(const int drive)
memset(&card[drive], 0, sizeof(tCardInfo)); memset(&card[drive], 0, sizeof(tCardInfo));
use_4bit[drive] = 0; use_4bit[drive] = 0;
use_sbc[drive] = 0;
active[drive] = 0; active[drive] = 0;
/* reset mmc/sd controller */ /* reset mmc/sd controller */
@ -1326,7 +1300,6 @@ static int __sd_init_device(const int drive)
if (!card_detect_target(drive)) if (!card_detect_target(drive))
return 0; return 0;
sd_simple_cmd(drive, &init_req, SD_CIM_RESET, 0, RESPONSE_NONE);
sd_simple_cmd(drive, &init_req, SD_GO_IDLE_STATE, 0, RESPONSE_NONE); sd_simple_cmd(drive, &init_req, SD_GO_IDLE_STATE, 0, RESPONSE_NONE);
sleep(HZ/2); /* Give the card/controller some rest */ sleep(HZ/2); /* Give the card/controller some rest */