Message ID | 20221221112853.789675-4-haibo.chen@nxp.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | fix the sdio device DATA/CMD CRC and Timeout issue after tuning | expand |
On 21/12/22 13:28, haibo.chen@nxp.com wrote: > From: Haibo Chen <haibo.chen@nxp.com> > > USDHC IP has one limitation: the tuning circuit can't handle the async > sdio device interrupt correctly. When sdio device use 4 data lines, > async sdio interrupt will use the shared DAT[1], if enable auto tuning > circuit to check these 4 data lines, include the DAT[1], this circuit > will detect this interrupt, take this as data on DAT[1], and adjust the > delay cell wrongly, finally will cause the DATA/CMD CRC error. > So for SDIO device, only enable DAT[0] and CMD line for auto tuning. > > Signed-off-by: Haibo Chen <haibo.chen@nxp.com> > --- > drivers/mmc/host/sdhci-esdhc-imx.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c > index bf8d6f60a9ee..d6ce4c8d23dc 100644 > --- a/drivers/mmc/host/sdhci-esdhc-imx.c > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c > @@ -448,6 +448,20 @@ static inline void usdhc_auto_tuning_mode_sel_and_en(struct sdhci_host *host) > break; > } > > + /* > + * For USDHC, auto tuning circuit can not handle the async sdio > + * device interrupt correctly. When sdio device use 4 data lines, > + * async sdio interrupt will use the shared DAT[1], if enable auto > + * tuning circuit check these 4 data lines, include the DAT[1], > + * this circuit will detect this interrupt, take this as a data on > + * DAT[1], and adjust the delay cell wrongly. > + * This is the hardware design limitation, to avoid this, for sdio > + * device, config the auto tuning circuit only check DAT[0] and CMD > + * line. > + */ > + if (!host->mmc->card && mmc_card_sdio(host->mmc->card)) Looks like !host->mmc->card should be host->mmc->card > + auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; > + > esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK, > auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN, > ESDHC_VEND_SPEC2);
> -----Original Message----- > From: Adrian Hunter <adrian.hunter@intel.com> > Sent: 2022年12月21日 22:21 > To: Bough Chen <haibo.chen@nxp.com> > Cc: shawnguo@kernel.org; s.hauer@pengutronix.de; kernel@pengutronix.de; > festevam@gmail.com; dl-linux-imx <linux-imx@nxp.com>; > linux-mmc@vger.kernel.org; kgroeneveld@lenbrook.com; > ulf.hansson@linaro.org > Subject: Re: [PATCH v2 3/3] mmc: sdhci-esdhc-imx: only enable DAT[0] and > CMD line auto tuning for SDIO device > > On 21/12/22 13:28, haibo.chen@nxp.com wrote: > > From: Haibo Chen <haibo.chen@nxp.com> > > > > USDHC IP has one limitation: the tuning circuit can't handle the async > > sdio device interrupt correctly. When sdio device use 4 data lines, > > async sdio interrupt will use the shared DAT[1], if enable auto tuning > > circuit to check these 4 data lines, include the DAT[1], this circuit > > will detect this interrupt, take this as data on DAT[1], and adjust > > the delay cell wrongly, finally will cause the DATA/CMD CRC error. > > So for SDIO device, only enable DAT[0] and CMD line for auto tuning. > > > > Signed-off-by: Haibo Chen <haibo.chen@nxp.com> > > --- > > drivers/mmc/host/sdhci-esdhc-imx.c | 14 ++++++++++++++ > > 1 file changed, 14 insertions(+) > > > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c > > b/drivers/mmc/host/sdhci-esdhc-imx.c > > index bf8d6f60a9ee..d6ce4c8d23dc 100644 > > --- a/drivers/mmc/host/sdhci-esdhc-imx.c > > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c > > @@ -448,6 +448,20 @@ static inline void > usdhc_auto_tuning_mode_sel_and_en(struct sdhci_host *host) > > break; > > } > > > > + /* > > + * For USDHC, auto tuning circuit can not handle the async sdio > > + * device interrupt correctly. When sdio device use 4 data lines, > > + * async sdio interrupt will use the shared DAT[1], if enable auto > > + * tuning circuit check these 4 data lines, include the DAT[1], > > + * this circuit will detect this interrupt, take this as a data on > > + * DAT[1], and adjust the delay cell wrongly. > > + * This is the hardware design limitation, to avoid this, for sdio > > + * device, config the auto tuning circuit only check DAT[0] and CMD > > + * line. > > + */ > > + if (!host->mmc->card && mmc_card_sdio(host->mmc->card)) > > Looks like !host->mmc->card should be host->mmc->card Yes, my mistake, my local test version is correct, I will fix this. Best Regards Haibo Chen > > > + auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; > > + > > esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK, > > auto_tune_buswidth | > ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN, > > ESDHC_VEND_SPEC2);
Hi, https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/haibo-chen-nxp-com/fix-the-sdio-device-DATA-CMD-CRC-and-Timeout-issue-after-tuning/20221221-193033 patch link: https://lore.kernel.org/r/20221221112853.789675-4-haibo.chen%40nxp.com patch subject: [PATCH v2 3/3] mmc: sdhci-esdhc-imx: only enable DAT[0] and CMD line auto tuning for SDIO device config: parisc-randconfig-m031-20221225 compiler: hppa-linux-gcc (GCC) 12.1.0 If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> | Reported-by: Dan Carpenter <error27@gmail.com> smatch warnings: drivers/mmc/host/sdhci-esdhc-imx.c:462 usdhc_auto_tuning_mode_sel_and_en() error: we previously assumed 'host->mmc->card' could be null (see line 462) vim +462 drivers/mmc/host/sdhci-esdhc-imx.c 45334ee13858de Haibo Chen 2021-08-18 431 /* Enable the auto tuning circuit to check the CMD line and BUS line */ 235cd41770bdcb Haibo Chen 2022-12-21 432 static inline void usdhc_auto_tuning_mode_sel_and_en(struct sdhci_host *host) 45334ee13858de Haibo Chen 2021-08-18 433 { 45334ee13858de Haibo Chen 2021-08-18 434 u32 buswidth, auto_tune_buswidth; 235cd41770bdcb Haibo Chen 2022-12-21 435 u32 reg; 45334ee13858de Haibo Chen 2021-08-18 436 45334ee13858de Haibo Chen 2021-08-18 437 buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL)); 45334ee13858de Haibo Chen 2021-08-18 438 45334ee13858de Haibo Chen 2021-08-18 439 switch (buswidth) { 45334ee13858de Haibo Chen 2021-08-18 440 case ESDHC_CTRL_8BITBUS: 45334ee13858de Haibo Chen 2021-08-18 441 auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN; 45334ee13858de Haibo Chen 2021-08-18 442 break; 45334ee13858de Haibo Chen 2021-08-18 443 case ESDHC_CTRL_4BITBUS: 45334ee13858de Haibo Chen 2021-08-18 444 auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN; 45334ee13858de Haibo Chen 2021-08-18 445 break; 45334ee13858de Haibo Chen 2021-08-18 446 default: /* 1BITBUS */ 45334ee13858de Haibo Chen 2021-08-18 447 auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; 45334ee13858de Haibo Chen 2021-08-18 448 break; 45334ee13858de Haibo Chen 2021-08-18 449 } 45334ee13858de Haibo Chen 2021-08-18 450 e088d1496d45c2 Haibo Chen 2022-12-21 451 /* e088d1496d45c2 Haibo Chen 2022-12-21 452 * For USDHC, auto tuning circuit can not handle the async sdio e088d1496d45c2 Haibo Chen 2022-12-21 453 * device interrupt correctly. When sdio device use 4 data lines, e088d1496d45c2 Haibo Chen 2022-12-21 454 * async sdio interrupt will use the shared DAT[1], if enable auto e088d1496d45c2 Haibo Chen 2022-12-21 455 * tuning circuit check these 4 data lines, include the DAT[1], e088d1496d45c2 Haibo Chen 2022-12-21 456 * this circuit will detect this interrupt, take this as a data on e088d1496d45c2 Haibo Chen 2022-12-21 457 * DAT[1], and adjust the delay cell wrongly. e088d1496d45c2 Haibo Chen 2022-12-21 458 * This is the hardware design limitation, to avoid this, for sdio e088d1496d45c2 Haibo Chen 2022-12-21 459 * device, config the auto tuning circuit only check DAT[0] and CMD e088d1496d45c2 Haibo Chen 2022-12-21 460 * line. e088d1496d45c2 Haibo Chen 2022-12-21 461 */ e088d1496d45c2 Haibo Chen 2022-12-21 @462 if (!host->mmc->card && mmc_card_sdio(host->mmc->card)) Presumably the ! is a mistake? mmc_card_sdio() dereferences host->mmc->card. e088d1496d45c2 Haibo Chen 2022-12-21 463 auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; e088d1496d45c2 Haibo Chen 2022-12-21 464 45334ee13858de Haibo Chen 2021-08-18 465 esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK, 45334ee13858de Haibo Chen 2021-08-18 466 auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN, 45334ee13858de Haibo Chen 2021-08-18 467 ESDHC_VEND_SPEC2); 235cd41770bdcb Haibo Chen 2022-12-21 468 235cd41770bdcb Haibo Chen 2022-12-21 469 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); 235cd41770bdcb Haibo Chen 2022-12-21 470 reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN; 235cd41770bdcb Haibo Chen 2022-12-21 471 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); 45334ee13858de Haibo Chen 2021-08-18 472 }
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index bf8d6f60a9ee..d6ce4c8d23dc 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -448,6 +448,20 @@ static inline void usdhc_auto_tuning_mode_sel_and_en(struct sdhci_host *host) break; } + /* + * For USDHC, auto tuning circuit can not handle the async sdio + * device interrupt correctly. When sdio device use 4 data lines, + * async sdio interrupt will use the shared DAT[1], if enable auto + * tuning circuit check these 4 data lines, include the DAT[1], + * this circuit will detect this interrupt, take this as a data on + * DAT[1], and adjust the delay cell wrongly. + * This is the hardware design limitation, to avoid this, for sdio + * device, config the auto tuning circuit only check DAT[0] and CMD + * line. + */ + if (!host->mmc->card && mmc_card_sdio(host->mmc->card)) + auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; + esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK, auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN, ESDHC_VEND_SPEC2);