Commit 0d70787b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'mmc-v5.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "MMC core:
   - Fix init of SD cards reporting an invalid VDD range

  MMC host:
   - sprd: Fixes for clocks, card-detect, write-protect etc
   - cadence: Fix ADMA 64-bit addressing
   - tegra: Re-allow writing to SD card when GPIO pin is absent
   - at91: Fix eMMC init by clearing HS200 cap as it's not supported"

* tag 'mmc-v5.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci-cadence: enable v4_mode to fix ADMA 64-bit addressing
  mmc: sdhci-sprd: clear the UHS-I modes read from registers
  mms: sdhci-sprd: add SDHCI_QUIRK_BROKEN_CARD_DETECTION
  mmc: sdhci-sprd: add SDHCI_QUIRK2_PRESET_VALUE_BROKEN
  mmc: sdhci-sprd: add get_ro hook function
  mmc: sdhci-sprd: fixed incorrect clock divider
  mmc: core: Fix init of SD cards reporting an invalid VDD range
  mmc: sdhci-of-at91: add quirk for broken HS200
  Revert "mmc: sdhci-tegra: drop ->get_ro() implementation"
parents f69f1992 e73a3896
...@@ -1292,6 +1292,12 @@ int mmc_attach_sd(struct mmc_host *host) ...@@ -1292,6 +1292,12 @@ int mmc_attach_sd(struct mmc_host *host)
goto err; goto err;
} }
/*
* Some SD cards claims an out of spec VDD voltage range. Let's treat
* these bits as being in-valid and especially also bit7.
*/
ocr &= ~0x7FFF;
rocr = mmc_select_voltage(host, ocr); rocr = mmc_select_voltage(host, ocr);
/* /*
......
...@@ -369,6 +369,7 @@ static int sdhci_cdns_probe(struct platform_device *pdev) ...@@ -369,6 +369,7 @@ static int sdhci_cdns_probe(struct platform_device *pdev)
host->mmc_host_ops.execute_tuning = sdhci_cdns_execute_tuning; host->mmc_host_ops.execute_tuning = sdhci_cdns_execute_tuning;
host->mmc_host_ops.hs400_enhanced_strobe = host->mmc_host_ops.hs400_enhanced_strobe =
sdhci_cdns_hs400_enhanced_strobe; sdhci_cdns_hs400_enhanced_strobe;
sdhci_enable_v4_mode(host);
sdhci_get_of_property(pdev); sdhci_get_of_property(pdev);
......
...@@ -357,6 +357,9 @@ static int sdhci_at91_probe(struct platform_device *pdev) ...@@ -357,6 +357,9 @@ static int sdhci_at91_probe(struct platform_device *pdev)
pm_runtime_set_autosuspend_delay(&pdev->dev, 50); pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev);
/* HS200 is broken at this moment */
host->quirks2 = SDHCI_QUIRK2_BROKEN_HS200;
ret = sdhci_add_host(host); ret = sdhci_add_host(host);
if (ret) if (ret)
goto pm_runtime_disable; goto pm_runtime_disable;
......
...@@ -217,10 +217,11 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host, ...@@ -217,10 +217,11 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host,
struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
u32 div, val, mask; u32 div, val, mask;
div = sdhci_sprd_calc_div(sprd_host->base_rate, clk); sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
clk |= ((div & 0x300) >> 2) | ((div & 0xFF) << 8); div = sdhci_sprd_calc_div(sprd_host->base_rate, clk);
sdhci_enable_clk(host, clk); div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8);
sdhci_enable_clk(host, div);
/* enable auto gate sdhc_enable_auto_gate */ /* enable auto gate sdhc_enable_auto_gate */
val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI); val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
...@@ -373,6 +374,11 @@ static unsigned int sdhci_sprd_get_max_timeout_count(struct sdhci_host *host) ...@@ -373,6 +374,11 @@ static unsigned int sdhci_sprd_get_max_timeout_count(struct sdhci_host *host)
return 1 << 31; return 1 << 31;
} }
static unsigned int sdhci_sprd_get_ro(struct sdhci_host *host)
{
return 0;
}
static struct sdhci_ops sdhci_sprd_ops = { static struct sdhci_ops sdhci_sprd_ops = {
.read_l = sdhci_sprd_readl, .read_l = sdhci_sprd_readl,
.write_l = sdhci_sprd_writel, .write_l = sdhci_sprd_writel,
...@@ -385,6 +391,7 @@ static struct sdhci_ops sdhci_sprd_ops = { ...@@ -385,6 +391,7 @@ static struct sdhci_ops sdhci_sprd_ops = {
.set_uhs_signaling = sdhci_sprd_set_uhs_signaling, .set_uhs_signaling = sdhci_sprd_set_uhs_signaling,
.hw_reset = sdhci_sprd_hw_reset, .hw_reset = sdhci_sprd_hw_reset,
.get_max_timeout_count = sdhci_sprd_get_max_timeout_count, .get_max_timeout_count = sdhci_sprd_get_max_timeout_count,
.get_ro = sdhci_sprd_get_ro,
}; };
static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq) static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq)
...@@ -501,9 +508,12 @@ static void sdhci_sprd_phy_param_parse(struct sdhci_sprd_host *sprd_host, ...@@ -501,9 +508,12 @@ static void sdhci_sprd_phy_param_parse(struct sdhci_sprd_host *sprd_host,
} }
static const struct sdhci_pltfm_data sdhci_sprd_pdata = { static const struct sdhci_pltfm_data sdhci_sprd_pdata = {
.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK, .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
SDHCI_QUIRK_MISSING_CAPS,
.quirks2 = SDHCI_QUIRK2_BROKEN_HS200 | .quirks2 = SDHCI_QUIRK2_BROKEN_HS200 |
SDHCI_QUIRK2_USE_32BIT_BLK_CNT, SDHCI_QUIRK2_USE_32BIT_BLK_CNT |
SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
.ops = &sdhci_sprd_ops, .ops = &sdhci_sprd_ops,
}; };
...@@ -605,6 +615,16 @@ static int sdhci_sprd_probe(struct platform_device *pdev) ...@@ -605,6 +615,16 @@ static int sdhci_sprd_probe(struct platform_device *pdev)
sdhci_enable_v4_mode(host); sdhci_enable_v4_mode(host);
/*
* Supply the existing CAPS, but clear the UHS-I modes. This
* will allow these modes to be specified only by device
* tree properties through mmc_of_parse().
*/
host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 |
SDHCI_SUPPORT_DDR50);
ret = sdhci_setup_host(host); ret = sdhci_setup_host(host);
if (ret) if (ret)
goto pm_runtime_disable; goto pm_runtime_disable;
......
...@@ -258,6 +258,16 @@ static void tegra210_sdhci_writew(struct sdhci_host *host, u16 val, int reg) ...@@ -258,6 +258,16 @@ static void tegra210_sdhci_writew(struct sdhci_host *host, u16 val, int reg)
} }
} }
static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host)
{
/*
* Write-enable shall be assumed if GPIO is missing in a board's
* device-tree because SDHCI's WRITE_PROTECT bit doesn't work on
* Tegra.
*/
return mmc_gpio_get_ro(host->mmc);
}
static bool tegra_sdhci_is_pad_and_regulator_valid(struct sdhci_host *host) static bool tegra_sdhci_is_pad_and_regulator_valid(struct sdhci_host *host)
{ {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
...@@ -1224,6 +1234,7 @@ static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = { ...@@ -1224,6 +1234,7 @@ static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = {
}; };
static const struct sdhci_ops tegra_sdhci_ops = { static const struct sdhci_ops tegra_sdhci_ops = {
.get_ro = tegra_sdhci_get_ro,
.read_w = tegra_sdhci_readw, .read_w = tegra_sdhci_readw,
.write_l = tegra_sdhci_writel, .write_l = tegra_sdhci_writel,
.set_clock = tegra_sdhci_set_clock, .set_clock = tegra_sdhci_set_clock,
...@@ -1279,6 +1290,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra30 = { ...@@ -1279,6 +1290,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra30 = {
}; };
static const struct sdhci_ops tegra114_sdhci_ops = { static const struct sdhci_ops tegra114_sdhci_ops = {
.get_ro = tegra_sdhci_get_ro,
.read_w = tegra_sdhci_readw, .read_w = tegra_sdhci_readw,
.write_w = tegra_sdhci_writew, .write_w = tegra_sdhci_writew,
.write_l = tegra_sdhci_writel, .write_l = tegra_sdhci_writel,
...@@ -1332,6 +1344,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra124 = { ...@@ -1332,6 +1344,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra124 = {
}; };
static const struct sdhci_ops tegra210_sdhci_ops = { static const struct sdhci_ops tegra210_sdhci_ops = {
.get_ro = tegra_sdhci_get_ro,
.read_w = tegra_sdhci_readw, .read_w = tegra_sdhci_readw,
.write_w = tegra210_sdhci_writew, .write_w = tegra210_sdhci_writew,
.write_l = tegra_sdhci_writel, .write_l = tegra_sdhci_writel,
...@@ -1366,6 +1379,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = { ...@@ -1366,6 +1379,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = {
}; };
static const struct sdhci_ops tegra186_sdhci_ops = { static const struct sdhci_ops tegra186_sdhci_ops = {
.get_ro = tegra_sdhci_get_ro,
.read_w = tegra_sdhci_readw, .read_w = tegra_sdhci_readw,
.write_l = tegra_sdhci_writel, .write_l = tegra_sdhci_writel,
.set_clock = tegra_sdhci_set_clock, .set_clock = tegra_sdhci_set_clock,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment