Commit 2c8ef2ae authored by Ying-Chun Liu (PaulLiu)'s avatar Ying-Chun Liu (PaulLiu)
Browse files

rpi3: sdhost: SDHost driver improvement



This commit improves the SDHost driver for RPi3 as following:
 * Unblock MMC_CMD(17). Using MMC_CMD(17) is more efficient on
   block reading.
 * In some low probability that SEND_OP_COND might results CRC7
   error. We can consider that the command runs correctly. We don't
   need to retry this command so removing the code for retry.
 * Using MMC_BUS_WIDTH_1 as MMC default value to improve the stability.
 * Increase the clock to 50Mhz in data mode to speed up the io.
 * Change the pull resistors configuration to gain more stability.
Signed-off-by: default avatarYing-Chun Liu (PaulLiu) <paulliu@debian.org>
parent ab3d2247
...@@ -272,8 +272,6 @@ static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd) ...@@ -272,8 +272,6 @@ static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd)
} }
cmd_idx = cmd->cmd_idx & HC_CMD_COMMAND_MASK; cmd_idx = cmd->cmd_idx & HC_CMD_COMMAND_MASK;
if (cmd_idx == MMC_CMD(17))
cmd_idx = MMC_CMD(18);
cmd_arg = cmd->cmd_arg; cmd_arg = cmd->cmd_arg;
if (cmd_idx == MMC_ACMD(51)) { if (cmd_idx == MMC_ACMD(51)) {
...@@ -364,8 +362,12 @@ static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd) ...@@ -364,8 +362,12 @@ static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd)
mmio_write_32(reg_base + HC_HOSTSTATUS, mmio_write_32(reg_base + HC_HOSTSTATUS,
HC_HSTST_MASK_ERROR_ALL); HC_HSTST_MASK_ERROR_ALL);
/*
* If the command SEND_OP_COND returns with CRC7 error,
* it can be considered as having completed successfully.
*/
if (!(sdhsts & HC_HSTST_ERROR_CRC7) if (!(sdhsts & HC_HSTST_ERROR_CRC7)
|| (cmd_idx != MMC_ACMD(51))) { || (cmd_idx != MMC_CMD(1))) {
if (sdhsts & HC_HSTST_TIMEOUT_CMD) { if (sdhsts & HC_HSTST_TIMEOUT_CMD) {
ERROR("rpi3_sdhost: timeout status 0x%x\n", ERROR("rpi3_sdhost: timeout status 0x%x\n",
sdhsts); sdhsts);
...@@ -533,21 +535,6 @@ static int rpi3_sdhost_read(int lba, uintptr_t buf, size_t size) ...@@ -533,21 +535,6 @@ static int rpi3_sdhost_read(int lba, uintptr_t buf, size_t size)
if (rpi3_sdhost_params.current_cmd == MMC_CMD(18)) if (rpi3_sdhost_params.current_cmd == MMC_CMD(18))
send_command_decorated(MMC_CMD(12), 0); send_command_decorated(MMC_CMD(12), 0);
if (err == -(EILSEQ)) {
const int max_retries = 20;
int r;
rpi3_sdhost_params.crc_err_retries++;
if (rpi3_sdhost_params.crc_err_retries < max_retries) {
/* retries if there's an CRC error */
r = rpi3_sdhost_prepare(lba, buf, size);
send_command_decorated(MMC_CMD(18), lba);
r = rpi3_sdhost_read(lba, buf, size);
if (r == 0)
err = 0;
}
}
return err; return err;
} }
...@@ -617,16 +604,20 @@ void rpi3_sdhost_init(struct rpi3_sdhost_params *params, ...@@ -617,16 +604,20 @@ void rpi3_sdhost_init(struct rpi3_sdhost_params *params,
} }
/* setting pull resistors for 48 to 53. /* setting pull resistors for 48 to 53.
* GPIO 48 (SD_CLK) to GPIO_PULL_UP * It is debatable to set SD_CLK to UP or NONE. We massively
* GPIO 49 (SD_CMD) to GPIO_PULL_NONE * tested different brands of SD Cards and found NONE works
* GPIO 50 (SD_D0) to GPIO_PULL_NONE * most stable.
* GPIO 51 (SD_D1) to GPIO_PULL_NONE *
* GPIO 52 (SD_D2) to GPIO_PULL_NONE * GPIO 48 (SD_CLK) to GPIO_PULL_NONE
* GPIO 53 (SD_D3) to GPIO_PULL_NONE * GPIO 49 (SD_CMD) to GPIO_PULL_UP
* GPIO 50 (SD_D0) to GPIO_PULL_UP
* GPIO 51 (SD_D1) to GPIO_PULL_UP
* GPIO 52 (SD_D2) to GPIO_PULL_UP
* GPIO 53 (SD_D3) to GPIO_PULL_UP
*/ */
gpio_set_pull(48, GPIO_PULL_UP); gpio_set_pull(48, GPIO_PULL_NONE);
for (int i = 49; i <= 53; i++) for (int i = 49; i <= 53; i++)
gpio_set_pull(i, GPIO_PULL_NONE); gpio_set_pull(i, GPIO_PULL_UP);
/* Set pin 48-53 to alt-0. It means route SDHOST to card slot */ /* Set pin 48-53 to alt-0. It means route SDHOST to card slot */
for (int i = 48; i <= 53; i++) for (int i = 48; i <= 53; i++)
...@@ -675,15 +666,14 @@ void rpi3_sdhost_stop(void) ...@@ -675,15 +666,14 @@ void rpi3_sdhost_stop(void)
rpi3_sdhost_params.gpio48_pinselect[i-48]); rpi3_sdhost_params.gpio48_pinselect[i-48]);
} }
/* Must reset the pull resistors for u-boot to work. /* Reset the pull resistors before entering BL33.
* GPIO 48 (SD_CLK) to GPIO_PULL_NONE * GPIO 48 (SD_CLK) to GPIO_PULL_UP
* GPIO 49 (SD_CMD) to GPIO_PULL_UP * GPIO 49 (SD_CMD) to GPIO_PULL_UP
* GPIO 50 (SD_D0) to GPIO_PULL_UP * GPIO 50 (SD_D0) to GPIO_PULL_UP
* GPIO 51 (SD_D1) to GPIO_PULL_UP * GPIO 51 (SD_D1) to GPIO_PULL_UP
* GPIO 52 (SD_D2) to GPIO_PULL_UP * GPIO 52 (SD_D2) to GPIO_PULL_UP
* GPIO 53 (SD_D3) to GPIO_PULL_UP * GPIO 53 (SD_D3) to GPIO_PULL_UP
*/ */
gpio_set_pull(48, GPIO_PULL_NONE); for (int i = 48; i <= 53; i++)
for (int i = 49; i <= 53; i++)
gpio_set_pull(i, GPIO_PULL_UP); gpio_set_pull(i, GPIO_PULL_UP);
} }
...@@ -21,7 +21,6 @@ struct rpi3_sdhost_params { ...@@ -21,7 +21,6 @@ struct rpi3_sdhost_params {
uint8_t cmdbusy; uint8_t cmdbusy;
uint8_t mmc_app_cmd; uint8_t mmc_app_cmd;
uint32_t ns_per_fifo_word; uint32_t ns_per_fifo_word;
uint32_t crc_err_retries;
uint32_t sdcard_rca; uint32_t sdcard_rca;
uint32_t gpio48_pinselect[6]; uint32_t gpio48_pinselect[6];
......
...@@ -44,8 +44,8 @@ static void rpi3_sdhost_setup(void) ...@@ -44,8 +44,8 @@ static void rpi3_sdhost_setup(void)
memset(&params, 0, sizeof(struct rpi3_sdhost_params)); memset(&params, 0, sizeof(struct rpi3_sdhost_params));
params.reg_base = RPI3_SDHOST_BASE; params.reg_base = RPI3_SDHOST_BASE;
params.bus_width = MMC_BUS_WIDTH_4; params.bus_width = MMC_BUS_WIDTH_1;
params.clk_rate = 392464; params.clk_rate = 50000000;
mmc_info.mmc_dev_type = MMC_IS_SD_HC; mmc_info.mmc_dev_type = MMC_IS_SD_HC;
rpi3_sdhost_init(&params, &mmc_info); rpi3_sdhost_init(&params, &mmc_info);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment