mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-04-12 00:47:49 -04:00
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:
parent
e8b75a52ab
commit
41567532a1
2 changed files with 13 additions and 62 deletions
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue