Skip to content

Commit

Permalink
Merge tag 'mmc-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:

 - Fix HS400 tuning for ACPI ID AMDI0040

 - Fix reset of CQHCI for Intel GLK-based controllers

 - Use correct timeout clock for Tegra186/194/210

 - Fix eMMC mounting on mt7622/Bpi-64

* tag 'mmc-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  sdhci: tegra: Add missing TMCLK for data timeout
  arm64: tegra: Add missing timeout clock to Tegra194 SDMMC nodes
  arm64: tegra: Add missing timeout clock to Tegra186 SDMMC nodes
  arm64: tegra: Add missing timeout clock to Tegra210 SDMMC
  dt-bindings: mmc: tegra: Add tmclk for Tegra210 and later
  sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra186
  sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra210
  arm64: dts: mt7622: add reset node for mmc device
  dt-bindings: mmc: Add missing description for clk_in/out_sd1
  mmc: mediatek: add optional module reset property
  mmc: dt-bindings: Add resets/reset-names for Mediatek MMC bindings
  mmc: sdhci-pci: Fix SDHCI_RESET_ALL for CQHCI for Intel GLK-based controllers
  mmc: sdhci-acpi: Fix HS400 tuning for AMDI0040
  • Loading branch information
Linus Torvalds committed Aug 31, 2020
2 parents f75aef3 + 8048822 commit 59815d6
Show file tree
Hide file tree
Showing 11 changed files with 203 additions and 43 deletions.
10 changes: 7 additions & 3 deletions Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ allOf:
then:
properties:
clock-output-names:
items:
- const: clk_out_sd0
- const: clk_in_sd0
oneOf:
- items:
- const: clk_out_sd0
- const: clk_in_sd0
- items:
- const: clk_out_sd1
- const: clk_in_sd1

properties:
compatible:
Expand Down
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/mmc/mtk-sd.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Optional properties:
error caused by stop clock(fifo full)
Valid range = [0:0x7]. if not present, default value is 0.
applied to compatible "mediatek,mt2701-mmc".
- resets: Phandle and reset specifier pair to softreset line of MSDC IP.
- reset-names: Should be "hrst".

Examples:
mmc0: mmc@11230000 {
Expand Down
32 changes: 29 additions & 3 deletions Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ Required properties:
- "nvidia,tegra210-sdhci": for Tegra210
- "nvidia,tegra186-sdhci": for Tegra186
- "nvidia,tegra194-sdhci": for Tegra194
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- clocks: For Tegra210, Tegra186 and Tegra194 must contain two entries.
One for the module clock and one for the timeout clock.
For all other Tegra devices, must contain a single entry for
the module clock. See ../clocks/clock-bindings.txt for details.
- clock-names: For Tegra210, Tegra186 and Tegra194 must contain the
strings 'sdhci' and 'tmclk' to represent the module and
the timeout clocks, respectively.
For all other Tegra devices must contain the string 'sdhci'
to represent the module clock.
- resets : Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
Expand Down Expand Up @@ -99,7 +106,7 @@ Optional properties for Tegra210, Tegra186 and Tegra194:

Example:
sdhci@700b0000 {
compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
compatible = "nvidia,tegra124-sdhci";
reg = <0x0 0x700b0000 0x0 0x200>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>;
Expand All @@ -115,3 +122,22 @@ sdhci@700b0000 {
nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>;
status = "disabled";
};

sdhci@700b0000 {
compatible = "nvidia,tegra210-sdhci";
reg = <0x0 0x700b0000 0x0 0x200>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>,
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
clock-names = "sdhci", "tmclk";
resets = <&tegra_car 14>;
reset-names = "sdhci";
pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
pinctrl-0 = <&sdmmc1_3v3>;
pinctrl-1 = <&sdmmc1_1v8>;
nvidia,pad-autocal-pull-up-offset-3v3 = <0x00>;
nvidia,pad-autocal-pull-down-offset-3v3 = <0x7d>;
nvidia,pad-autocal-pull-up-offset-1v8 = <0x7b>;
nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>;
status = "disabled";
};
2 changes: 2 additions & 0 deletions arch/arm64/boot/dts/mediatek/mt7622.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,8 @@
clocks = <&pericfg CLK_PERI_MSDC30_0_PD>,
<&topckgen CLK_TOP_MSDC50_0_SEL>;
clock-names = "source", "hclk";
resets = <&pericfg MT7622_PERI_MSDC0_SW_RST>;
reset-names = "hrst";
status = "disabled";
};

Expand Down
20 changes: 12 additions & 8 deletions arch/arm64/boot/dts/nvidia/tegra186.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,9 @@
compatible = "nvidia,tegra186-sdhci";
reg = <0x0 0x03400000 0x0 0x10000>;
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA186_CLK_SDMMC1>;
clock-names = "sdhci";
clocks = <&bpmp TEGRA186_CLK_SDMMC1>,
<&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
clock-names = "sdhci", "tmclk";
resets = <&bpmp TEGRA186_RESET_SDMMC1>;
reset-names = "sdhci";
interconnects = <&mc TEGRA186_MEMORY_CLIENT_SDMMCRA &emc>,
Expand Down Expand Up @@ -366,8 +367,9 @@
compatible = "nvidia,tegra186-sdhci";
reg = <0x0 0x03420000 0x0 0x10000>;
interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA186_CLK_SDMMC2>;
clock-names = "sdhci";
clocks = <&bpmp TEGRA186_CLK_SDMMC2>,
<&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
clock-names = "sdhci", "tmclk";
resets = <&bpmp TEGRA186_RESET_SDMMC2>;
reset-names = "sdhci";
interconnects = <&mc TEGRA186_MEMORY_CLIENT_SDMMCRAA &emc>,
Expand All @@ -390,8 +392,9 @@
compatible = "nvidia,tegra186-sdhci";
reg = <0x0 0x03440000 0x0 0x10000>;
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA186_CLK_SDMMC3>;
clock-names = "sdhci";
clocks = <&bpmp TEGRA186_CLK_SDMMC3>,
<&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
clock-names = "sdhci", "tmclk";
resets = <&bpmp TEGRA186_RESET_SDMMC3>;
reset-names = "sdhci";
interconnects = <&mc TEGRA186_MEMORY_CLIENT_SDMMCR &emc>,
Expand All @@ -416,8 +419,9 @@
compatible = "nvidia,tegra186-sdhci";
reg = <0x0 0x03460000 0x0 0x10000>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA186_CLK_SDMMC4>;
clock-names = "sdhci";
clocks = <&bpmp TEGRA186_CLK_SDMMC4>,
<&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
clock-names = "sdhci", "tmclk";
assigned-clocks = <&bpmp TEGRA186_CLK_SDMMC4>,
<&bpmp TEGRA186_CLK_PLLC4_VCO>;
assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLC4_VCO>;
Expand Down
15 changes: 9 additions & 6 deletions arch/arm64/boot/dts/nvidia/tegra194.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,9 @@
compatible = "nvidia,tegra194-sdhci";
reg = <0x03400000 0x10000>;
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA194_CLK_SDMMC1>;
clock-names = "sdhci";
clocks = <&bpmp TEGRA194_CLK_SDMMC1>,
<&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>;
clock-names = "sdhci", "tmclk";
resets = <&bpmp TEGRA194_RESET_SDMMC1>;
reset-names = "sdhci";
interconnects = <&mc TEGRA194_MEMORY_CLIENT_SDMMCRA &emc>,
Expand All @@ -485,8 +486,9 @@
compatible = "nvidia,tegra194-sdhci";
reg = <0x03440000 0x10000>;
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA194_CLK_SDMMC3>;
clock-names = "sdhci";
clocks = <&bpmp TEGRA194_CLK_SDMMC3>,
<&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>;
clock-names = "sdhci", "tmclk";
resets = <&bpmp TEGRA194_RESET_SDMMC3>;
reset-names = "sdhci";
interconnects = <&mc TEGRA194_MEMORY_CLIENT_SDMMCR &emc>,
Expand All @@ -511,8 +513,9 @@
compatible = "nvidia,tegra194-sdhci";
reg = <0x03460000 0x10000>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA194_CLK_SDMMC4>;
clock-names = "sdhci";
clocks = <&bpmp TEGRA194_CLK_SDMMC4>,
<&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>;
clock-names = "sdhci", "tmclk";
assigned-clocks = <&bpmp TEGRA194_CLK_SDMMC4>,
<&bpmp TEGRA194_CLK_PLLC4>;
assigned-clock-parents =
Expand Down
20 changes: 12 additions & 8 deletions arch/arm64/boot/dts/nvidia/tegra210.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -1194,8 +1194,9 @@
compatible = "nvidia,tegra210-sdhci";
reg = <0x0 0x700b0000 0x0 0x200>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>;
clock-names = "sdhci";
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>,
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
clock-names = "sdhci", "tmclk";
resets = <&tegra_car 14>;
reset-names = "sdhci";
pinctrl-names = "sdmmc-3v3", "sdmmc-1v8",
Expand All @@ -1222,8 +1223,9 @@
compatible = "nvidia,tegra210-sdhci";
reg = <0x0 0x700b0200 0x0 0x200>;
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC2>;
clock-names = "sdhci";
clocks = <&tegra_car TEGRA210_CLK_SDMMC2>,
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
clock-names = "sdhci", "tmclk";
resets = <&tegra_car 9>;
reset-names = "sdhci";
pinctrl-names = "sdmmc-1v8-drv";
Expand All @@ -1239,8 +1241,9 @@
compatible = "nvidia,tegra210-sdhci";
reg = <0x0 0x700b0400 0x0 0x200>;
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC3>;
clock-names = "sdhci";
clocks = <&tegra_car TEGRA210_CLK_SDMMC3>,
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
clock-names = "sdhci", "tmclk";
resets = <&tegra_car 69>;
reset-names = "sdhci";
pinctrl-names = "sdmmc-3v3", "sdmmc-1v8",
Expand All @@ -1262,8 +1265,9 @@
compatible = "nvidia,tegra210-sdhci";
reg = <0x0 0x700b0600 0x0 0x200>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC4>;
clock-names = "sdhci";
clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
clock-names = "sdhci", "tmclk";
resets = <&tegra_car 15>;
reset-names = "sdhci";
pinctrl-names = "sdmmc-3v3-drv", "sdmmc-1v8-drv";
Expand Down
13 changes: 13 additions & 0 deletions drivers/mmc/host/mtk-sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/reset.h>

#include <linux/mmc/card.h>
#include <linux/mmc/core.h>
Expand Down Expand Up @@ -419,6 +420,7 @@ struct msdc_host {
struct pinctrl_state *pins_uhs;
struct delayed_work req_timeout;
int irq; /* host interrupt */
struct reset_control *reset;

struct clk *src_clk; /* msdc source clock */
struct clk *h_clk; /* msdc h_clk */
Expand Down Expand Up @@ -1592,6 +1594,12 @@ static void msdc_init_hw(struct msdc_host *host)
u32 val;
u32 tune_reg = host->dev_comp->pad_tune_reg;

if (host->reset) {
reset_control_assert(host->reset);
usleep_range(10, 50);
reset_control_deassert(host->reset);
}

/* Configure to MMC/SD mode, clock free running */
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN);

Expand Down Expand Up @@ -2390,6 +2398,11 @@ static int msdc_drv_probe(struct platform_device *pdev)
if (IS_ERR(host->src_clk_cg))
host->src_clk_cg = NULL;

host->reset = devm_reset_control_get_optional_exclusive(&pdev->dev,
"hrst");
if (IS_ERR(host->reset))
return PTR_ERR(host->reset);

host->irq = platform_get_irq(pdev, 0);
if (host->irq < 0) {
ret = -EINVAL;
Expand Down
67 changes: 57 additions & 10 deletions drivers/mmc/host/sdhci-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,11 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_qcom_sd = {
.caps = MMC_CAP_NONREMOVABLE,
};

struct amd_sdhci_host {
bool tuned_clock;
bool dll_enabled;
};

/* AMD sdhci reset dll register. */
#define SDHCI_AMD_RESET_DLL_REGISTER 0x908

Expand All @@ -555,26 +560,66 @@ static void sdhci_acpi_amd_hs400_dll(struct sdhci_host *host)
}

/*
* For AMD Platform it is required to disable the tuning
* bit first controller to bring to HS Mode from HS200
* mode, later enable to tune to HS400 mode.
* The initialization sequence for HS400 is:
* HS->HS200->Perform Tuning->HS->HS400
*
* The re-tuning sequence is:
* HS400->DDR52->HS->HS200->Perform Tuning->HS->HS400
*
* The AMD eMMC Controller can only use the tuned clock while in HS200 and HS400
* mode. If we switch to a different mode, we need to disable the tuned clock.
* If we have previously performed tuning and switch back to HS200 or
* HS400, we can re-enable the tuned clock.
*
*/
static void amd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct sdhci_host *host = mmc_priv(mmc);
struct sdhci_acpi_host *acpi_host = sdhci_priv(host);
struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host);
unsigned int old_timing = host->timing;
u16 val;

sdhci_set_ios(mmc, ios);
if (old_timing == MMC_TIMING_MMC_HS200 &&
ios->timing == MMC_TIMING_MMC_HS)
sdhci_writew(host, 0x9, SDHCI_HOST_CONTROL2);
if (old_timing != MMC_TIMING_MMC_HS400 &&
ios->timing == MMC_TIMING_MMC_HS400) {
sdhci_writew(host, 0x80, SDHCI_HOST_CONTROL2);
sdhci_acpi_amd_hs400_dll(host);

if (old_timing != host->timing && amd_host->tuned_clock) {
if (host->timing == MMC_TIMING_MMC_HS400 ||
host->timing == MMC_TIMING_MMC_HS200) {
val = sdhci_readw(host, SDHCI_HOST_CONTROL2);
val |= SDHCI_CTRL_TUNED_CLK;
sdhci_writew(host, val, SDHCI_HOST_CONTROL2);
} else {
val = sdhci_readw(host, SDHCI_HOST_CONTROL2);
val &= ~SDHCI_CTRL_TUNED_CLK;
sdhci_writew(host, val, SDHCI_HOST_CONTROL2);
}

/* DLL is only required for HS400 */
if (host->timing == MMC_TIMING_MMC_HS400 &&
!amd_host->dll_enabled) {
sdhci_acpi_amd_hs400_dll(host);
amd_host->dll_enabled = true;
}
}
}

static int amd_sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
int err;
struct sdhci_host *host = mmc_priv(mmc);
struct sdhci_acpi_host *acpi_host = sdhci_priv(host);
struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host);

amd_host->tuned_clock = false;

err = sdhci_execute_tuning(mmc, opcode);

if (!err && !host->tuning_err)
amd_host->tuned_clock = true;

return err;
}

static const struct sdhci_ops sdhci_acpi_ops_amd = {
.set_clock = sdhci_set_clock,
.set_bus_width = sdhci_set_bus_width,
Expand Down Expand Up @@ -602,6 +647,7 @@ static int sdhci_acpi_emmc_amd_probe_slot(struct platform_device *pdev,

host->mmc_host_ops.select_drive_strength = amd_select_drive_strength;
host->mmc_host_ops.set_ios = amd_set_ios;
host->mmc_host_ops.execute_tuning = amd_sdhci_execute_tuning;
return 0;
}

Expand All @@ -613,6 +659,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_amd_emmc = {
SDHCI_QUIRK_32BIT_ADMA_SIZE,
.quirks2 = SDHCI_QUIRK2_BROKEN_64_BIT_DMA,
.probe_slot = sdhci_acpi_emmc_amd_probe_slot,
.priv_size = sizeof(struct amd_sdhci_host),
};

struct sdhci_acpi_uid_slot {
Expand Down
10 changes: 9 additions & 1 deletion drivers/mmc/host/sdhci-pci-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@ static void sdhci_pci_dumpregs(struct mmc_host *mmc)
sdhci_dumpregs(mmc_priv(mmc));
}

static void sdhci_cqhci_reset(struct sdhci_host *host, u8 mask)
{
if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL) &&
host->mmc->cqe_private)
cqhci_deactivate(host->mmc);
sdhci_reset(host, mask);
}

/*****************************************************************************\
* *
* Hardware specific quirk handling *
Expand Down Expand Up @@ -718,7 +726,7 @@ static const struct sdhci_ops sdhci_intel_glk_ops = {
.set_power = sdhci_intel_set_power,
.enable_dma = sdhci_pci_enable_dma,
.set_bus_width = sdhci_set_bus_width,
.reset = sdhci_reset,
.reset = sdhci_cqhci_reset,
.set_uhs_signaling = sdhci_set_uhs_signaling,
.hw_reset = sdhci_pci_hw_reset,
.irq = sdhci_cqhci_irq,
Expand Down
Loading

0 comments on commit 59815d6

Please sign in to comment.