diff mbox series

[U-Boot,[RESEND] PATCH v3 1/2] mmc: sdhci: add SDHCI_QUIRK_BROKEN_HISPD_MODE

Message ID 1524214538-1811-1-git-send-email-hannes.schmelzer@br-automation.com
State Accepted
Delegated to: Jaehoon Chung
Headers show
Series [U-Boot,[RESEND] PATCH v3 1/2] mmc: sdhci: add SDHCI_QUIRK_BROKEN_HISPD_MODE | expand

Commit Message

Hannes Schmelzer April 20, 2018, 8:55 a.m. UTC
From: Hannes Schmelzer <oe5hpm@oevsv.at>

Some IP-core implementations of the SDHCI have different troubles on the
silicon where they are placed.

On ZYNQ platform for example Xilinx doesn't accept the hold timing of an
eMMC chip which operates in High-Speed mode and must be forced to
operate in non high-speed mode. To get rid of this
"SDHCI_QUIRK_BROKEN_HISPD_MODE" is introduced.

For more details about this refer to the Xilinx answer-recor #59999
https://www.xilinx.com/support/answers/59999.html

This commit:
- doesn't set HISPD bit on the host-conroller
- reflects this fact within the host-controller capabilities

Upon this the layer above (mmc-driver) can setup the card correctly.

Otherwise the MMC card will be switched into high-speed mode and causes
possible timing violation on the host-controller side.

Signed-off-by: Hannes Schmelzer <oe5hpm@oevsv.at>

Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
---

Changes in v3:
- cleanup sign-off tag
- fix typo (sdci -> sdhci)
- combine the if instruction SDHCI_QUIRK_BROKEN_HISPD_MODE with the
  existing SDHCI_QUIRK_NO_HISPD_BIT

Changes in v2:
- don't use the SDHCI_QUIRK_NO_HISPD_BIT for getting rid of this,
since this quirk was designed for another purpose. Instead introduce the
new SDHCI_QUIRK_BROKEN_HISPD_MODE quirk.

 drivers/mmc/sdhci.c | 8 +++++++-
 include/sdhci.h     | 6 ++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

Comments

Simon Glass April 25, 2018, 5:01 a.m. UTC | #1
On 20 April 2018 at 02:55, Hannes Schmelzer <
hannes.schmelzer@br-automation.com> wrote:
> From: Hannes Schmelzer <oe5hpm@oevsv.at>
>
> Some IP-core implementations of the SDHCI have different troubles on the
> silicon where they are placed.
>
> On ZYNQ platform for example Xilinx doesn't accept the hold timing of an
> eMMC chip which operates in High-Speed mode and must be forced to
> operate in non high-speed mode. To get rid of this
> "SDHCI_QUIRK_BROKEN_HISPD_MODE" is introduced.
>
> For more details about this refer to the Xilinx answer-recor #59999
> https://www.xilinx.com/support/answers/59999.html
>
> This commit:
> - doesn't set HISPD bit on the host-conroller
> - reflects this fact within the host-controller capabilities
>
> Upon this the layer above (mmc-driver) can setup the card correctly.
>
> Otherwise the MMC card will be switched into high-speed mode and causes
> possible timing violation on the host-controller side.
>
> Signed-off-by: Hannes Schmelzer <oe5hpm@oevsv.at>
>
> Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
> ---
>
> Changes in v3:
> - cleanup sign-off tag
> - fix typo (sdci -> sdhci)
> - combine the if instruction SDHCI_QUIRK_BROKEN_HISPD_MODE with the
>   existing SDHCI_QUIRK_NO_HISPD_BIT
>
> Changes in v2:
> - don't use the SDHCI_QUIRK_NO_HISPD_BIT for getting rid of this,
> since this quirk was designed for another purpose. Instead introduce the
> new SDHCI_QUIRK_BROKEN_HISPD_MODE quirk.
>
>  drivers/mmc/sdhci.c | 8 +++++++-
>  include/sdhci.h     | 6 ++++++
>  2 files changed, 13 insertions(+), 1 deletion(-)
>

Reviewed-by: Simon Glass <sjg@chromium.org>
diff mbox series

Patch

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index d31793a..1e5e8a6 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -462,7 +462,8 @@  static int sdhci_set_ios(struct mmc *mmc)
 	else
 		ctrl &= ~SDHCI_CTRL_HISPD;
 
-	if (host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)
+	if ((host->quirks & SDHCI_QUIRK_NO_HISPD_BIT) ||
+	    (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE))
 		ctrl &= ~SDHCI_CTRL_HISPD;
 
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
@@ -602,6 +603,11 @@  int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
 			cfg->host_caps &= ~MMC_MODE_8BIT;
 	}
 
+	if (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE) {
+		cfg->host_caps &= ~MMC_MODE_HS;
+		cfg->host_caps &= ~MMC_MODE_HS_52MHz;
+	}
+
 	if (host->host_caps)
 		cfg->host_caps |= host->host_caps;
 
diff --git a/include/sdhci.h b/include/sdhci.h
index 7e84012..ed35f04 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -213,6 +213,12 @@ 
 #define SDHCI_QUIRK_BROKEN_R1B		(1 << 2)
 #define SDHCI_QUIRK_NO_HISPD_BIT	(1 << 3)
 #define SDHCI_QUIRK_BROKEN_VOLTAGE	(1 << 4)
+/*
+ * SDHCI_QUIRK_BROKEN_HISPD_MODE
+ * the hardware cannot operate correctly in high-speed mode,
+ * this quirk forces the sdhci host-controller to non high-speed mode
+ */
+#define SDHCI_QUIRK_BROKEN_HISPD_MODE	BIT(5)
 #define SDHCI_QUIRK_WAIT_SEND_CMD	(1 << 6)
 #define SDHCI_QUIRK_USE_WIDE8		(1 << 8)