On 2/18/19 3:51 PM, Ang, Chee Hong wrote: > On Mon, 2019-02-18 at 12:57 +0100, Marek Vasut wrote: >> On 2/18/19 5:16 AM, chee.hong....@intel.com wrote: >>> >>> From: "Ang, Chee Hong" <chee.hong....@intel.com> >>> >>> 'SET_BLOCKLEN' may occasionally fail on first attempt. >> Why ? > This is part of the workaround of mmc driver which is enabled with > 'CONFIG_MMC_QUIRKS' config. > https://github.com/u-boot/u-boot/blob/dbe70c7d4e3d5c705a98d82952e05a591 > efd0683/drivers/mmc/mmc.c#L272
OK, let's take a step back. What problem do you observe, that you're trying to fix ? >>> This patch enable a small delay in dwmci_send_cmd() on >>> busy, I/O or CRC error to allow the MMC controller recovers >>> from the failure/error on subsequent retries. >> Why 100 uS ? > This is a good question. Perhaps the driver's authors can explain this. > The driver delay 100us after dwmci_send_cmd() success with the command > sent. But it never delay 100us whenever mmc controller response to the > command sent with I/O or CRC errors. MMC drivers expect the first > 'SET_BLOCKEN' command issued by dwmci_send_cmd() may fail > intermittently so it will retry up to 4 times before it gave up and > return error. Without this 100us delay after error response, > 'SET_BLOCKEN' may sometime fail in 4 attempts in a row. Therefore, we > encountered intermittent failure in loading u-boot (SSBL) from MMC. Can you be more specific about the failure you saw ? >> Can we rather detect whether the controller recovered by polling some >> bit? > Hmmm...I can take a look at the databook of this controller and dig > further. Probably this is the limitation of the controller itself. The > mmc driver code which introduce 100us delay after every command sent in > dwmci_send_cmd() looks iffy. If you have access to it, please do. btw do you have the same problem if you disable caches ? >>> Signed-off-by: Ang, Chee Hong <chee.hong....@intel.com> >>> --- >>> drivers/mmc/dw_mmc.c | 14 ++++++++++---- >>> 1 file changed, 10 insertions(+), 4 deletions(-) >>> >>> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c >>> index 7544b84..8dcc518 100644 >>> --- a/drivers/mmc/dw_mmc.c >>> +++ b/drivers/mmc/dw_mmc.c >>> @@ -266,8 +266,11 @@ static int dwmci_send_cmd(struct mmc *mmc, >>> struct mmc_cmd *cmd, >>> if (data) >>> flags = dwmci_set_transfer_mode(host, data); >>> >>> - if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & >>> MMC_RSP_BUSY)) >>> - return -1; >>> + if ((cmd->resp_type & MMC_RSP_136) && >>> + (cmd->resp_type & MMC_RSP_BUSY)) { >>> + ret = -1; >>> + goto delay_ret; >>> + } >>> >>> if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) >>> flags |= DWMCI_CMD_ABORT_STOP; >>> @@ -316,11 +319,13 @@ static int dwmci_send_cmd(struct mmc *mmc, >>> struct mmc_cmd *cmd, >>> return -ETIMEDOUT; >>> } else if (mask & DWMCI_INTMSK_RE) { >>> debug("%s: Response Error.\n", __func__); >>> - return -EIO; >>> + ret = -EIO; >>> + goto delay_ret; >>> } else if ((cmd->resp_type & MMC_RSP_CRC) && >>> (mask & DWMCI_INTMSK_RCRC)) { >>> debug("%s: Response CRC Error.\n", __func__); >>> - return -EIO; >>> + ret = -EIO; >>> + goto delay_ret; >>> } >>> >>> >>> @@ -347,6 +352,7 @@ static int dwmci_send_cmd(struct mmc *mmc, >>> struct mmc_cmd *cmd, >>> } >>> } >>> >>> +delay_ret: >>> udelay(100); >>> >>> return ret; >>> -- Best regards, Marek Vasut _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot