rpi3: sdhost: SDHost driver improvement
authorYing-Chun Liu (PaulLiu) <paulliu@debian.org>
Tue, 12 Feb 2019 14:41:06 +0000 (22:41 +0800)
committerYing-Chun Liu (PaulLiu) <paulliu@debian.org>
Tue, 26 Feb 2019 17:06:57 +0000 (01:06 +0800)
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: Ying-Chun Liu (PaulLiu) <paulliu@debian.org>
drivers/rpi3/sdhost/rpi3_sdhost.c
include/drivers/rpi3/sdhost/rpi3_sdhost.h
plat/rpi3/rpi3_bl2_setup.c

index efcd6dbb0eb64328328e057aec77e5c085fc1817..c4b6fcafeca87093fe0a90eae335203f1ad3a9b1 100644 (file)
@@ -272,8 +272,6 @@ static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd)
        }
 
        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;
        if (cmd_idx == MMC_ACMD(51)) {
@@ -364,8 +362,12 @@ static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd)
                mmio_write_32(reg_base + HC_HOSTSTATUS,
                              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)
-                   || (cmd_idx != MMC_ACMD(51))) {
+                   || (cmd_idx != MMC_CMD(1))) {
                        if (sdhsts & HC_HSTST_TIMEOUT_CMD) {
                                ERROR("rpi3_sdhost: timeout status 0x%x\n",
                                      sdhsts);
@@ -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))
                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;
 }
 
@@ -617,16 +604,20 @@ void rpi3_sdhost_init(struct rpi3_sdhost_params *params,
        }
 
        /* setting pull resistors for 48 to 53.
-        * GPIO 48 (SD_CLK) to GPIO_PULL_UP
-        * GPIO 49 (SD_CMD) to GPIO_PULL_NONE
-        * GPIO 50 (SD_D0)  to GPIO_PULL_NONE
-        * GPIO 51 (SD_D1)  to GPIO_PULL_NONE
-        * GPIO 52 (SD_D2)  to GPIO_PULL_NONE
-        * GPIO 53 (SD_D3)  to GPIO_PULL_NONE
+        * It is debatable to set SD_CLK to UP or NONE. We massively
+        * tested different brands of SD Cards and found NONE works
+        * most stable.
+        *
+        * GPIO 48 (SD_CLK) 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++)
-               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 */
        for (int i = 48; i <= 53; i++)
@@ -675,15 +666,14 @@ void rpi3_sdhost_stop(void)
                                     rpi3_sdhost_params.gpio48_pinselect[i-48]);
        }
 
-       /* Must reset the pull resistors for u-boot to work.
-        * GPIO 48 (SD_CLK) to GPIO_PULL_NONE
+       /* Reset the pull resistors before entering BL33.
+        * GPIO 48 (SD_CLK) to GPIO_PULL_UP
         * 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_NONE);
-       for (int i = 49; i <= 53; i++)
+       for (int i = 48; i <= 53; i++)
                gpio_set_pull(i, GPIO_PULL_UP);
 }
index bc906e3949fc7e49c6e26297133def94a7b64d3e..1653240c899709736a66fc4d8160fe1e14204a3d 100644 (file)
@@ -21,7 +21,6 @@ struct rpi3_sdhost_params {
        uint8_t         cmdbusy;
        uint8_t         mmc_app_cmd;
        uint32_t        ns_per_fifo_word;
-       uint32_t        crc_err_retries;
 
        uint32_t        sdcard_rca;
        uint32_t        gpio48_pinselect[6];
index 3d1f8f9185c787bc34bce41a8bde4d83f3b59fdd..b5e58352aba665b3d7097bc0f34764b624f37606 100644 (file)
@@ -44,8 +44,8 @@ static void rpi3_sdhost_setup(void)
 
        memset(&params, 0, sizeof(struct rpi3_sdhost_params));
        params.reg_base = RPI3_SDHOST_BASE;
-       params.bus_width = MMC_BUS_WIDTH_4;
-       params.clk_rate = 392464;
+       params.bus_width = MMC_BUS_WIDTH_1;
+       params.clk_rate = 50000000;
        mmc_info.mmc_dev_type = MMC_IS_SD_HC;
        rpi3_sdhost_init(&params, &mmc_info);
 }