Skip to content

Commit 59815d6

Browse files
committed
Merge tag 'mmc-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/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
2 parents f75aef3 + 8048822 commit 59815d6

11 files changed

Lines changed: 203 additions & 43 deletions

File tree

Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@ allOf:
3030
then:
3131
properties:
3232
clock-output-names:
33-
items:
34-
- const: clk_out_sd0
35-
- const: clk_in_sd0
33+
oneOf:
34+
- items:
35+
- const: clk_out_sd0
36+
- const: clk_in_sd0
37+
- items:
38+
- const: clk_out_sd1
39+
- const: clk_in_sd1
3640

3741
properties:
3842
compatible:

Documentation/devicetree/bindings/mmc/mtk-sd.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ Optional properties:
5050
error caused by stop clock(fifo full)
5151
Valid range = [0:0x7]. if not present, default value is 0.
5252
applied to compatible "mediatek,mt2701-mmc".
53+
- resets: Phandle and reset specifier pair to softreset line of MSDC IP.
54+
- reset-names: Should be "hrst".
5355

5456
Examples:
5557
mmc0: mmc@11230000 {

Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@ Required properties:
1515
- "nvidia,tegra210-sdhci": for Tegra210
1616
- "nvidia,tegra186-sdhci": for Tegra186
1717
- "nvidia,tegra194-sdhci": for Tegra194
18-
- clocks : Must contain one entry, for the module clock.
19-
See ../clocks/clock-bindings.txt for details.
18+
- clocks: For Tegra210, Tegra186 and Tegra194 must contain two entries.
19+
One for the module clock and one for the timeout clock.
20+
For all other Tegra devices, must contain a single entry for
21+
the module clock. See ../clocks/clock-bindings.txt for details.
22+
- clock-names: For Tegra210, Tegra186 and Tegra194 must contain the
23+
strings 'sdhci' and 'tmclk' to represent the module and
24+
the timeout clocks, respectively.
25+
For all other Tegra devices must contain the string 'sdhci'
26+
to represent the module clock.
2027
- resets : Must contain an entry for each entry in reset-names.
2128
See ../reset/reset.txt for details.
2229
- reset-names : Must include the following entries:
@@ -99,7 +106,7 @@ Optional properties for Tegra210, Tegra186 and Tegra194:
99106

100107
Example:
101108
sdhci@700b0000 {
102-
compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
109+
compatible = "nvidia,tegra124-sdhci";
103110
reg = <0x0 0x700b0000 0x0 0x200>;
104111
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
105112
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>;
@@ -115,3 +122,22 @@ sdhci@700b0000 {
115122
nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>;
116123
status = "disabled";
117124
};
125+
126+
sdhci@700b0000 {
127+
compatible = "nvidia,tegra210-sdhci";
128+
reg = <0x0 0x700b0000 0x0 0x200>;
129+
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
130+
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>,
131+
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
132+
clock-names = "sdhci", "tmclk";
133+
resets = <&tegra_car 14>;
134+
reset-names = "sdhci";
135+
pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
136+
pinctrl-0 = <&sdmmc1_3v3>;
137+
pinctrl-1 = <&sdmmc1_1v8>;
138+
nvidia,pad-autocal-pull-up-offset-3v3 = <0x00>;
139+
nvidia,pad-autocal-pull-down-offset-3v3 = <0x7d>;
140+
nvidia,pad-autocal-pull-up-offset-1v8 = <0x7b>;
141+
nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>;
142+
status = "disabled";
143+
};

arch/arm64/boot/dts/mediatek/mt7622.dtsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,8 @@
686686
clocks = <&pericfg CLK_PERI_MSDC30_0_PD>,
687687
<&topckgen CLK_TOP_MSDC50_0_SEL>;
688688
clock-names = "source", "hclk";
689+
resets = <&pericfg MT7622_PERI_MSDC0_SW_RST>;
690+
reset-names = "hrst";
689691
status = "disabled";
690692
};
691693

arch/arm64/boot/dts/nvidia/tegra186.dtsi

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,9 @@
337337
compatible = "nvidia,tegra186-sdhci";
338338
reg = <0x0 0x03400000 0x0 0x10000>;
339339
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
340-
clocks = <&bpmp TEGRA186_CLK_SDMMC1>;
341-
clock-names = "sdhci";
340+
clocks = <&bpmp TEGRA186_CLK_SDMMC1>,
341+
<&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
342+
clock-names = "sdhci", "tmclk";
342343
resets = <&bpmp TEGRA186_RESET_SDMMC1>;
343344
reset-names = "sdhci";
344345
interconnects = <&mc TEGRA186_MEMORY_CLIENT_SDMMCRA &emc>,
@@ -366,8 +367,9 @@
366367
compatible = "nvidia,tegra186-sdhci";
367368
reg = <0x0 0x03420000 0x0 0x10000>;
368369
interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
369-
clocks = <&bpmp TEGRA186_CLK_SDMMC2>;
370-
clock-names = "sdhci";
370+
clocks = <&bpmp TEGRA186_CLK_SDMMC2>,
371+
<&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
372+
clock-names = "sdhci", "tmclk";
371373
resets = <&bpmp TEGRA186_RESET_SDMMC2>;
372374
reset-names = "sdhci";
373375
interconnects = <&mc TEGRA186_MEMORY_CLIENT_SDMMCRAA &emc>,
@@ -390,8 +392,9 @@
390392
compatible = "nvidia,tegra186-sdhci";
391393
reg = <0x0 0x03440000 0x0 0x10000>;
392394
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
393-
clocks = <&bpmp TEGRA186_CLK_SDMMC3>;
394-
clock-names = "sdhci";
395+
clocks = <&bpmp TEGRA186_CLK_SDMMC3>,
396+
<&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
397+
clock-names = "sdhci", "tmclk";
395398
resets = <&bpmp TEGRA186_RESET_SDMMC3>;
396399
reset-names = "sdhci";
397400
interconnects = <&mc TEGRA186_MEMORY_CLIENT_SDMMCR &emc>,
@@ -416,8 +419,9 @@
416419
compatible = "nvidia,tegra186-sdhci";
417420
reg = <0x0 0x03460000 0x0 0x10000>;
418421
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
419-
clocks = <&bpmp TEGRA186_CLK_SDMMC4>;
420-
clock-names = "sdhci";
422+
clocks = <&bpmp TEGRA186_CLK_SDMMC4>,
423+
<&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
424+
clock-names = "sdhci", "tmclk";
421425
assigned-clocks = <&bpmp TEGRA186_CLK_SDMMC4>,
422426
<&bpmp TEGRA186_CLK_PLLC4_VCO>;
423427
assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLC4_VCO>;

arch/arm64/boot/dts/nvidia/tegra194.dtsi

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,9 @@
460460
compatible = "nvidia,tegra194-sdhci";
461461
reg = <0x03400000 0x10000>;
462462
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
463-
clocks = <&bpmp TEGRA194_CLK_SDMMC1>;
464-
clock-names = "sdhci";
463+
clocks = <&bpmp TEGRA194_CLK_SDMMC1>,
464+
<&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>;
465+
clock-names = "sdhci", "tmclk";
465466
resets = <&bpmp TEGRA194_RESET_SDMMC1>;
466467
reset-names = "sdhci";
467468
interconnects = <&mc TEGRA194_MEMORY_CLIENT_SDMMCRA &emc>,
@@ -485,8 +486,9 @@
485486
compatible = "nvidia,tegra194-sdhci";
486487
reg = <0x03440000 0x10000>;
487488
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
488-
clocks = <&bpmp TEGRA194_CLK_SDMMC3>;
489-
clock-names = "sdhci";
489+
clocks = <&bpmp TEGRA194_CLK_SDMMC3>,
490+
<&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>;
491+
clock-names = "sdhci", "tmclk";
490492
resets = <&bpmp TEGRA194_RESET_SDMMC3>;
491493
reset-names = "sdhci";
492494
interconnects = <&mc TEGRA194_MEMORY_CLIENT_SDMMCR &emc>,
@@ -511,8 +513,9 @@
511513
compatible = "nvidia,tegra194-sdhci";
512514
reg = <0x03460000 0x10000>;
513515
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
514-
clocks = <&bpmp TEGRA194_CLK_SDMMC4>;
515-
clock-names = "sdhci";
516+
clocks = <&bpmp TEGRA194_CLK_SDMMC4>,
517+
<&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>;
518+
clock-names = "sdhci", "tmclk";
516519
assigned-clocks = <&bpmp TEGRA194_CLK_SDMMC4>,
517520
<&bpmp TEGRA194_CLK_PLLC4>;
518521
assigned-clock-parents =

arch/arm64/boot/dts/nvidia/tegra210.dtsi

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,8 +1194,9 @@
11941194
compatible = "nvidia,tegra210-sdhci";
11951195
reg = <0x0 0x700b0000 0x0 0x200>;
11961196
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
1197-
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>;
1198-
clock-names = "sdhci";
1197+
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>,
1198+
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
1199+
clock-names = "sdhci", "tmclk";
11991200
resets = <&tegra_car 14>;
12001201
reset-names = "sdhci";
12011202
pinctrl-names = "sdmmc-3v3", "sdmmc-1v8",
@@ -1222,8 +1223,9 @@
12221223
compatible = "nvidia,tegra210-sdhci";
12231224
reg = <0x0 0x700b0200 0x0 0x200>;
12241225
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
1225-
clocks = <&tegra_car TEGRA210_CLK_SDMMC2>;
1226-
clock-names = "sdhci";
1226+
clocks = <&tegra_car TEGRA210_CLK_SDMMC2>,
1227+
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
1228+
clock-names = "sdhci", "tmclk";
12271229
resets = <&tegra_car 9>;
12281230
reset-names = "sdhci";
12291231
pinctrl-names = "sdmmc-1v8-drv";
@@ -1239,8 +1241,9 @@
12391241
compatible = "nvidia,tegra210-sdhci";
12401242
reg = <0x0 0x700b0400 0x0 0x200>;
12411243
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
1242-
clocks = <&tegra_car TEGRA210_CLK_SDMMC3>;
1243-
clock-names = "sdhci";
1244+
clocks = <&tegra_car TEGRA210_CLK_SDMMC3>,
1245+
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
1246+
clock-names = "sdhci", "tmclk";
12441247
resets = <&tegra_car 69>;
12451248
reset-names = "sdhci";
12461249
pinctrl-names = "sdmmc-3v3", "sdmmc-1v8",
@@ -1262,8 +1265,9 @@
12621265
compatible = "nvidia,tegra210-sdhci";
12631266
reg = <0x0 0x700b0600 0x0 0x200>;
12641267
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
1265-
clocks = <&tegra_car TEGRA210_CLK_SDMMC4>;
1266-
clock-names = "sdhci";
1268+
clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
1269+
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
1270+
clock-names = "sdhci", "tmclk";
12671271
resets = <&tegra_car 15>;
12681272
reset-names = "sdhci";
12691273
pinctrl-names = "sdmmc-3v3-drv", "sdmmc-1v8-drv";

drivers/mmc/host/mtk-sd.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/slab.h>
2323
#include <linux/spinlock.h>
2424
#include <linux/interrupt.h>
25+
#include <linux/reset.h>
2526

2627
#include <linux/mmc/card.h>
2728
#include <linux/mmc/core.h>
@@ -419,6 +420,7 @@ struct msdc_host {
419420
struct pinctrl_state *pins_uhs;
420421
struct delayed_work req_timeout;
421422
int irq; /* host interrupt */
423+
struct reset_control *reset;
422424

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

1597+
if (host->reset) {
1598+
reset_control_assert(host->reset);
1599+
usleep_range(10, 50);
1600+
reset_control_deassert(host->reset);
1601+
}
1602+
15951603
/* Configure to MMC/SD mode, clock free running */
15961604
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN);
15971605

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

2401+
host->reset = devm_reset_control_get_optional_exclusive(&pdev->dev,
2402+
"hrst");
2403+
if (IS_ERR(host->reset))
2404+
return PTR_ERR(host->reset);
2405+
23932406
host->irq = platform_get_irq(pdev, 0);
23942407
if (host->irq < 0) {
23952408
ret = -EINVAL;

drivers/mmc/host/sdhci-acpi.c

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,11 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_qcom_sd = {
535535
.caps = MMC_CAP_NONREMOVABLE,
536536
};
537537

538+
struct amd_sdhci_host {
539+
bool tuned_clock;
540+
bool dll_enabled;
541+
};
542+
538543
/* AMD sdhci reset dll register. */
539544
#define SDHCI_AMD_RESET_DLL_REGISTER 0x908
540545

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

557562
/*
558-
* For AMD Platform it is required to disable the tuning
559-
* bit first controller to bring to HS Mode from HS200
560-
* mode, later enable to tune to HS400 mode.
563+
* The initialization sequence for HS400 is:
564+
* HS->HS200->Perform Tuning->HS->HS400
565+
*
566+
* The re-tuning sequence is:
567+
* HS400->DDR52->HS->HS200->Perform Tuning->HS->HS400
568+
*
569+
* The AMD eMMC Controller can only use the tuned clock while in HS200 and HS400
570+
* mode. If we switch to a different mode, we need to disable the tuned clock.
571+
* If we have previously performed tuning and switch back to HS200 or
572+
* HS400, we can re-enable the tuned clock.
573+
*
561574
*/
562575
static void amd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
563576
{
564577
struct sdhci_host *host = mmc_priv(mmc);
578+
struct sdhci_acpi_host *acpi_host = sdhci_priv(host);
579+
struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host);
565580
unsigned int old_timing = host->timing;
581+
u16 val;
566582

567583
sdhci_set_ios(mmc, ios);
568-
if (old_timing == MMC_TIMING_MMC_HS200 &&
569-
ios->timing == MMC_TIMING_MMC_HS)
570-
sdhci_writew(host, 0x9, SDHCI_HOST_CONTROL2);
571-
if (old_timing != MMC_TIMING_MMC_HS400 &&
572-
ios->timing == MMC_TIMING_MMC_HS400) {
573-
sdhci_writew(host, 0x80, SDHCI_HOST_CONTROL2);
574-
sdhci_acpi_amd_hs400_dll(host);
584+
585+
if (old_timing != host->timing && amd_host->tuned_clock) {
586+
if (host->timing == MMC_TIMING_MMC_HS400 ||
587+
host->timing == MMC_TIMING_MMC_HS200) {
588+
val = sdhci_readw(host, SDHCI_HOST_CONTROL2);
589+
val |= SDHCI_CTRL_TUNED_CLK;
590+
sdhci_writew(host, val, SDHCI_HOST_CONTROL2);
591+
} else {
592+
val = sdhci_readw(host, SDHCI_HOST_CONTROL2);
593+
val &= ~SDHCI_CTRL_TUNED_CLK;
594+
sdhci_writew(host, val, SDHCI_HOST_CONTROL2);
595+
}
596+
597+
/* DLL is only required for HS400 */
598+
if (host->timing == MMC_TIMING_MMC_HS400 &&
599+
!amd_host->dll_enabled) {
600+
sdhci_acpi_amd_hs400_dll(host);
601+
amd_host->dll_enabled = true;
602+
}
575603
}
576604
}
577605

606+
static int amd_sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
607+
{
608+
int err;
609+
struct sdhci_host *host = mmc_priv(mmc);
610+
struct sdhci_acpi_host *acpi_host = sdhci_priv(host);
611+
struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host);
612+
613+
amd_host->tuned_clock = false;
614+
615+
err = sdhci_execute_tuning(mmc, opcode);
616+
617+
if (!err && !host->tuning_err)
618+
amd_host->tuned_clock = true;
619+
620+
return err;
621+
}
622+
578623
static const struct sdhci_ops sdhci_acpi_ops_amd = {
579624
.set_clock = sdhci_set_clock,
580625
.set_bus_width = sdhci_set_bus_width,
@@ -602,6 +647,7 @@ static int sdhci_acpi_emmc_amd_probe_slot(struct platform_device *pdev,
602647

603648
host->mmc_host_ops.select_drive_strength = amd_select_drive_strength;
604649
host->mmc_host_ops.set_ios = amd_set_ios;
650+
host->mmc_host_ops.execute_tuning = amd_sdhci_execute_tuning;
605651
return 0;
606652
}
607653

@@ -613,6 +659,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_amd_emmc = {
613659
SDHCI_QUIRK_32BIT_ADMA_SIZE,
614660
.quirks2 = SDHCI_QUIRK2_BROKEN_64_BIT_DMA,
615661
.probe_slot = sdhci_acpi_emmc_amd_probe_slot,
662+
.priv_size = sizeof(struct amd_sdhci_host),
616663
};
617664

618665
struct sdhci_acpi_uid_slot {

drivers/mmc/host/sdhci-pci-core.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,14 @@ static void sdhci_pci_dumpregs(struct mmc_host *mmc)
232232
sdhci_dumpregs(mmc_priv(mmc));
233233
}
234234

235+
static void sdhci_cqhci_reset(struct sdhci_host *host, u8 mask)
236+
{
237+
if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL) &&
238+
host->mmc->cqe_private)
239+
cqhci_deactivate(host->mmc);
240+
sdhci_reset(host, mask);
241+
}
242+
235243
/*****************************************************************************\
236244
* *
237245
* Hardware specific quirk handling *
@@ -718,7 +726,7 @@ static const struct sdhci_ops sdhci_intel_glk_ops = {
718726
.set_power = sdhci_intel_set_power,
719727
.enable_dma = sdhci_pci_enable_dma,
720728
.set_bus_width = sdhci_set_bus_width,
721-
.reset = sdhci_reset,
729+
.reset = sdhci_cqhci_reset,
722730
.set_uhs_signaling = sdhci_set_uhs_signaling,
723731
.hw_reset = sdhci_pci_hw_reset,
724732
.irq = sdhci_cqhci_irq,

0 commit comments

Comments
 (0)