[5/5] mmc: sdhci-esdhc-imx: add DCMD support for CMDQ
diff mbox series

Message ID 20190107101757.27647-5-haibo.chen@nxp.com
State New
Headers show
Series
  • [1/5] mmc: sdhci-esdhc-imx: remove the 100MHz limitation for Strobe DLL
Related show

Commit Message

BOUGH CHEN Jan. 7, 2019, 10:11 a.m. UTC
Currently, USDHC do not generate transfer complete interrupt
when send a non-data-command with R1b response. But if want
to support DCMD in CMDQ, need to change this, the DCMD IC
logic require the USDHC to enable this function, otherwise
DCMD will never get a CC(command complete) interrupt.

This patch set ESDHC_VEND_SPEC2_EN_BUSY_IRQ and add DCMD support.

Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

Comments

Adrian Hunter Jan. 14, 2019, 1:08 p.m. UTC | #1
On 7/01/19 12:11 PM, BOUGH CHEN wrote:
> Currently, USDHC do not generate transfer complete interrupt
> when send a non-data-command with R1b response. But if want
> to support DCMD in CMDQ, need to change this, the DCMD IC
> logic require the USDHC to enable this function, otherwise
> DCMD will never get a CC(command complete) interrupt.
> 
> This patch set ESDHC_VEND_SPEC2_EN_BUSY_IRQ and add DCMD support.
> 
> Signed-off-by: Haibo Chen <haibo.chen@nxp.com>

Acked-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 3ada951f9df5..e5676beb7ec1 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -80,6 +80,9 @@
>  #define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
>  #define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
>  
> +#define ESDHC_VEND_SPEC2		0xc8
> +#define ESDHC_VEND_SPEC2_EN_BUSY_IRQ	(1 << 8)
> +
>  #define ESDHC_TUNING_CTRL		0xcc
>  #define ESDHC_STD_TUNING_EN		(1 << 24)
>  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
> @@ -1145,6 +1148,23 @@ static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host)
>  		/* disable DLL_CTRL delay line settings */
>  		writel(0x0, host->ioaddr + ESDHC_DLL_CTRL);
>  
> +		/*
> +		 * For the case of command with busy, if set the bit
> +		 * ESDHC_VEND_SPEC2_EN_BUSY_IRQ, USDHC will generate a
> +		 * transfer complete interrupt when busy is deasserted.
> +		 * When CQHCI use DCMD to send a CMD need R1b respons,
> +		 * CQHCI require to set ESDHC_VEND_SPEC2_EN_BUSY_IRQ,
> +		 * otherwise DCMD will always meet timeout waiting for
> +		 * hardware interrupt issue.
> +		 */
> +		if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) {
> +			tmp = readl(host->ioaddr + ESDHC_VEND_SPEC2);
> +			tmp |= ESDHC_VEND_SPEC2_EN_BUSY_IRQ;
> +			writel(tmp, host->ioaddr + ESDHC_VEND_SPEC2);
> +
> +			host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
> +		}
> +
>  		if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
>  			tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL);
>  			tmp |= ESDHC_STD_TUNING_EN |
> @@ -1435,7 +1455,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
>  	}
>  
>  	if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) {
> -		host->mmc->caps2 |= MMC_CAP2_CQE;
> +		host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
>  		cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL);
>  		if (IS_ERR(cq_host)) {
>  			err = PTR_ERR(cq_host);
>
Ulf Hansson Jan. 14, 2019, 1:36 p.m. UTC | #2
On Mon, 7 Jan 2019 at 11:11, BOUGH CHEN <haibo.chen@nxp.com> wrote:
>
> Currently, USDHC do not generate transfer complete interrupt
> when send a non-data-command with R1b response. But if want
> to support DCMD in CMDQ, need to change this, the DCMD IC
> logic require the USDHC to enable this function, otherwise
> DCMD will never get a CC(command complete) interrupt.
>
> This patch set ESDHC_VEND_SPEC2_EN_BUSY_IRQ and add DCMD support.
>
> Signed-off-by: Haibo Chen <haibo.chen@nxp.com>

Applied for next, thanks!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 3ada951f9df5..e5676beb7ec1 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -80,6 +80,9 @@
>  #define ESDHC_STROBE_DLL_STS_REF_LOCK  (1 << 1)
>  #define ESDHC_STROBE_DLL_STS_SLV_LOCK  0x1
>
> +#define ESDHC_VEND_SPEC2               0xc8
> +#define ESDHC_VEND_SPEC2_EN_BUSY_IRQ   (1 << 8)
> +
>  #define ESDHC_TUNING_CTRL              0xcc
>  #define ESDHC_STD_TUNING_EN            (1 << 24)
>  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
> @@ -1145,6 +1148,23 @@ static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host)
>                 /* disable DLL_CTRL delay line settings */
>                 writel(0x0, host->ioaddr + ESDHC_DLL_CTRL);
>
> +               /*
> +                * For the case of command with busy, if set the bit
> +                * ESDHC_VEND_SPEC2_EN_BUSY_IRQ, USDHC will generate a
> +                * transfer complete interrupt when busy is deasserted.
> +                * When CQHCI use DCMD to send a CMD need R1b respons,
> +                * CQHCI require to set ESDHC_VEND_SPEC2_EN_BUSY_IRQ,
> +                * otherwise DCMD will always meet timeout waiting for
> +                * hardware interrupt issue.
> +                */
> +               if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) {
> +                       tmp = readl(host->ioaddr + ESDHC_VEND_SPEC2);
> +                       tmp |= ESDHC_VEND_SPEC2_EN_BUSY_IRQ;
> +                       writel(tmp, host->ioaddr + ESDHC_VEND_SPEC2);
> +
> +                       host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
> +               }
> +
>                 if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
>                         tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL);
>                         tmp |= ESDHC_STD_TUNING_EN |
> @@ -1435,7 +1455,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
>         }
>
>         if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) {
> -               host->mmc->caps2 |= MMC_CAP2_CQE;
> +               host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
>                 cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL);
>                 if (IS_ERR(cq_host)) {
>                         err = PTR_ERR(cq_host);
> --
> 2.17.1
>

Patch
diff mbox series

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 3ada951f9df5..e5676beb7ec1 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -80,6 +80,9 @@ 
 #define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
 #define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
 
+#define ESDHC_VEND_SPEC2		0xc8
+#define ESDHC_VEND_SPEC2_EN_BUSY_IRQ	(1 << 8)
+
 #define ESDHC_TUNING_CTRL		0xcc
 #define ESDHC_STD_TUNING_EN		(1 << 24)
 /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
@@ -1145,6 +1148,23 @@  static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host)
 		/* disable DLL_CTRL delay line settings */
 		writel(0x0, host->ioaddr + ESDHC_DLL_CTRL);
 
+		/*
+		 * For the case of command with busy, if set the bit
+		 * ESDHC_VEND_SPEC2_EN_BUSY_IRQ, USDHC will generate a
+		 * transfer complete interrupt when busy is deasserted.
+		 * When CQHCI use DCMD to send a CMD need R1b respons,
+		 * CQHCI require to set ESDHC_VEND_SPEC2_EN_BUSY_IRQ,
+		 * otherwise DCMD will always meet timeout waiting for
+		 * hardware interrupt issue.
+		 */
+		if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) {
+			tmp = readl(host->ioaddr + ESDHC_VEND_SPEC2);
+			tmp |= ESDHC_VEND_SPEC2_EN_BUSY_IRQ;
+			writel(tmp, host->ioaddr + ESDHC_VEND_SPEC2);
+
+			host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
+		}
+
 		if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
 			tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL);
 			tmp |= ESDHC_STD_TUNING_EN |
@@ -1435,7 +1455,7 @@  static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	}
 
 	if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) {
-		host->mmc->caps2 |= MMC_CAP2_CQE;
+		host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
 		cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL);
 		if (IS_ERR(cq_host)) {
 			err = PTR_ERR(cq_host);