Commit 838a860a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v5.5-rc2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "A couple of MMC host fixes:

   - sdhci: Fix minimum clock rate for v3 controllers

   - sdhci-tegra: Fix SDR50 tuning override

   - sdhci_am654: Fixup tuning issues and support for CQHCI

   - sdhci_am654: Remove wrong write protect flag"

* tag 'mmc-v5.5-rc2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci: fix minimum clock rate for v3 controller
  mmc: tegra: fix SDR50 tuning override
  mmc: sdhci_am654: Fix Command Queuing in AM65x
  mmc: sdhci_am654: Reset Command and Data line after tuning
  mmc: sdhci_am654: Remove Inverted Write Protect flag
parents 4703d911 2a187d03
...@@ -386,7 +386,7 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask) ...@@ -386,7 +386,7 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
misc_ctrl |= SDHCI_MISC_CTRL_ENABLE_DDR50; misc_ctrl |= SDHCI_MISC_CTRL_ENABLE_DDR50;
if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR104) if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR104)
misc_ctrl |= SDHCI_MISC_CTRL_ENABLE_SDR104; misc_ctrl |= SDHCI_MISC_CTRL_ENABLE_SDR104;
if (soc_data->nvquirks & SDHCI_MISC_CTRL_ENABLE_SDR50) if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR50)
clk_ctrl |= SDHCI_CLOCK_CTRL_SDR50_TUNING_OVERRIDE; clk_ctrl |= SDHCI_CLOCK_CTRL_SDR50_TUNING_OVERRIDE;
} }
......
...@@ -3913,11 +3913,13 @@ int sdhci_setup_host(struct sdhci_host *host) ...@@ -3913,11 +3913,13 @@ int sdhci_setup_host(struct sdhci_host *host)
if (host->ops->get_min_clock) if (host->ops->get_min_clock)
mmc->f_min = host->ops->get_min_clock(host); mmc->f_min = host->ops->get_min_clock(host);
else if (host->version >= SDHCI_SPEC_300) { else if (host->version >= SDHCI_SPEC_300) {
if (host->clk_mul) { if (host->clk_mul)
mmc->f_min = (host->max_clk * host->clk_mul) / 1024;
max_clk = host->max_clk * host->clk_mul; max_clk = host->max_clk * host->clk_mul;
} else /*
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; * Divided Clock Mode minimum clock rate is always less than
* Programmable Clock Mode minimum clock rate.
*/
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
} else } else
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
......
...@@ -240,6 +240,35 @@ static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg) ...@@ -240,6 +240,35 @@ static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg)
writeb(val, host->ioaddr + reg); writeb(val, host->ioaddr + reg);
} }
static int sdhci_am654_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
struct sdhci_host *host = mmc_priv(mmc);
int err = sdhci_execute_tuning(mmc, opcode);
if (err)
return err;
/*
* Tuning data remains in the buffer after tuning.
* Do a command and data reset to get rid of it
*/
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
return 0;
}
static u32 sdhci_am654_cqhci_irq(struct sdhci_host *host, u32 intmask)
{
int cmd_error = 0;
int data_error = 0;
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
return 0;
}
static struct sdhci_ops sdhci_am654_ops = { static struct sdhci_ops sdhci_am654_ops = {
.get_max_clock = sdhci_pltfm_clk_get_max_clock, .get_max_clock = sdhci_pltfm_clk_get_max_clock,
.get_timeout_clock = sdhci_pltfm_clk_get_max_clock, .get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
...@@ -248,13 +277,13 @@ static struct sdhci_ops sdhci_am654_ops = { ...@@ -248,13 +277,13 @@ static struct sdhci_ops sdhci_am654_ops = {
.set_power = sdhci_am654_set_power, .set_power = sdhci_am654_set_power,
.set_clock = sdhci_am654_set_clock, .set_clock = sdhci_am654_set_clock,
.write_b = sdhci_am654_write_b, .write_b = sdhci_am654_write_b,
.irq = sdhci_am654_cqhci_irq,
.reset = sdhci_reset, .reset = sdhci_reset,
}; };
static const struct sdhci_pltfm_data sdhci_am654_pdata = { static const struct sdhci_pltfm_data sdhci_am654_pdata = {
.ops = &sdhci_am654_ops, .ops = &sdhci_am654_ops,
.quirks = SDHCI_QUIRK_INVERTED_WRITE_PROTECT | .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
}; };
...@@ -263,19 +292,6 @@ static const struct sdhci_am654_driver_data sdhci_am654_drvdata = { ...@@ -263,19 +292,6 @@ static const struct sdhci_am654_driver_data sdhci_am654_drvdata = {
.flags = IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT | DLL_PRESENT, .flags = IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT | DLL_PRESENT,
}; };
static u32 sdhci_am654_cqhci_irq(struct sdhci_host *host, u32 intmask)
{
int cmd_error = 0;
int data_error = 0;
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
return 0;
}
static struct sdhci_ops sdhci_j721e_8bit_ops = { static struct sdhci_ops sdhci_j721e_8bit_ops = {
.get_max_clock = sdhci_pltfm_clk_get_max_clock, .get_max_clock = sdhci_pltfm_clk_get_max_clock,
.get_timeout_clock = sdhci_pltfm_clk_get_max_clock, .get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
...@@ -290,8 +306,7 @@ static struct sdhci_ops sdhci_j721e_8bit_ops = { ...@@ -290,8 +306,7 @@ static struct sdhci_ops sdhci_j721e_8bit_ops = {
static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = { static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = {
.ops = &sdhci_j721e_8bit_ops, .ops = &sdhci_j721e_8bit_ops,
.quirks = SDHCI_QUIRK_INVERTED_WRITE_PROTECT | .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
}; };
...@@ -314,8 +329,7 @@ static struct sdhci_ops sdhci_j721e_4bit_ops = { ...@@ -314,8 +329,7 @@ static struct sdhci_ops sdhci_j721e_4bit_ops = {
static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata = { static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata = {
.ops = &sdhci_j721e_4bit_ops, .ops = &sdhci_j721e_4bit_ops,
.quirks = SDHCI_QUIRK_INVERTED_WRITE_PROTECT | .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
}; };
...@@ -549,6 +563,8 @@ static int sdhci_am654_probe(struct platform_device *pdev) ...@@ -549,6 +563,8 @@ static int sdhci_am654_probe(struct platform_device *pdev)
goto pm_runtime_put; goto pm_runtime_put;
} }
host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning;
ret = sdhci_am654_init(host); ret = sdhci_am654_init(host);
if (ret) if (ret)
goto pm_runtime_put; goto pm_runtime_put;
......
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