Hi,
Please follow below instructions and share necessary info.
- Please add below patch and see if issue is still.
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index a5c80a6..9352e99 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -2637,6 +2637,7 @@
SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
SDHCI_QUIRK2_HOST_OFF_CARD_ON |
+ SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER |
SDHCI_QUIRK2_SEL_SDR104_UHS_MODE_IN_SDR50,
.ops = &tegra_sdhci_ops,
};
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a90fad4..df4d419 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3,6 +3,7 @@
* linux/drivers/mmc/host/sdhci.c - Secure Digital Host Controller Interface driver
*
* Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
+ * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
*
* Thanks to the following companies for their support:
*
@@ -3152,9 +3153,14 @@
* Spec says we should do both at the same time, but Ricoh
* controllers do not like that.
*/
- sdhci_do_reset(host, SDHCI_RESET_CMD);
- sdhci_do_reset(host, SDHCI_RESET_DATA);
-
+ if (host->quirks2 &
+ SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER) {
+ sdhci_do_reset(host, SDHCI_RESET_CMD |
+ SDHCI_RESET_DATA);
+ } else {
+ sdhci_do_reset(host, SDHCI_RESET_CMD);
+ sdhci_do_reset(host, SDHCI_RESET_DATA);
+ }
host->pending_reset = false;
}
- If issue is still there, please also add this debug patch to driver and share new dmesg.
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 91e987a..1c02be9 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -390,7 +390,7 @@
u32 trim_delay;
u8 i;
- pr_debug("======= %s: Tuning windows =======\n",
+ pr_info("======= %s: Tuning windows =======\n",
mmc_hostname(host->mmc));
reg = sdhci_readl(host, SDHCI_VNDR_TUN_CTRL0_0);
for (i = 0; i <= SDHCI_VNDR_TUN_CTRL0_TUN_WORD_SEL_MASK; i++) {
@@ -399,7 +399,7 @@
sdhci_writel(host, reg, SDHCI_VNDR_TUN_CTRL0_0);
tuning_status = sdhci_readl(host,
SDHCI_TEGRA_VNDR_TUNING_STATUS0);
- pr_debug("%s: tuning window[%d]: %#x\n",
+ pr_info("%s: tuning window[%d]: %#x\n",
mmc_hostname(host->mmc), i, tuning_status);
}
reg = sdhci_readl(host, SDHCI_TEGRA_VENDOR_CLOCK_CTRL);
@@ -407,33 +407,33 @@
tap_delay >>= SDHCI_CLOCK_CTRL_TAP_SHIFT;
trim_delay = reg & SDHCI_CLOCK_CTRL_TRIM_MASK;
trim_delay >>= SDHCI_CLOCK_CTRL_TRIM_SHIFT;
- pr_debug("sdhci: Tap value: %u | Trim value: %u\n", tap_delay,
+ pr_info("sdhci: Tap value: %u | Trim value: %u\n", tap_delay,
trim_delay);
- pr_debug("==================================\n");
+ pr_info("==================================\n");
- pr_debug("Vendor clock ctrl: %#x\n",
+ pr_info("Vendor clock ctrl: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_CLOCK_CTRL));
- pr_debug("Vendor SysSW ctrl: %#x\n",
+ pr_info("Vendor SysSW ctrl: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL));
- pr_debug("Vendor Err interrupt status : %#x\n",
+ pr_info("Vendor Err interrupt status : %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_ERR_INTR_STATUS));
- pr_debug("Vendor Cap overrides: %#x\n",
+ pr_info("Vendor Cap overrides: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_CAP_OVERRIDES));
- pr_debug("Vendor Misc ctrl: %#x\n",
+ pr_info("Vendor Misc ctrl: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_MISC_CTRL));
- pr_debug("Vendor Misc ctrl_1: %#x\n",
+ pr_info("Vendor Misc ctrl_1: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_MISC_CTRL_1));
- pr_debug("Vendor Misc ctrl_2: %#x\n",
+ pr_info("Vendor Misc ctrl_2: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_MISC_CTRL_2));
- pr_debug("Vendor IO trim ctrl: %#x\n",
+ pr_info("Vendor IO trim ctrl: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_IO_TRIM_CTRL_0));
- pr_debug("Vendor Tuning ctrl: %#x\n",
+ pr_info("Vendor Tuning ctrl: %#x\n",
sdhci_readl(host, SDHCI_VNDR_TUN_CTRL0_0));
- pr_debug("SDMEM comp padctrl: %#x\n",
+ pr_info("SDMEM comp padctrl: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_SDMEM_COMP_PADCTRL));
- pr_debug("Autocal config: %#x\n",
+ pr_info("Autocal config: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG));
- pr_debug("Autocal status: %#x\n",
+ pr_info("Autocal status: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_STATUS));
}
@@ -771,7 +771,7 @@
tegra_sdhci_set_tap(host, tegra_host->tuned_tap_delay);
tegra_host->tuning_status = TUNING_STATUS_DONE;
- pr_debug("%s: hw tuning done ...\n", mmc_hostname(host->mmc));
+ pr_info("%s: hw tuning done ...\n", mmc_hostname(host->mmc));
tegra_sdhci_dump_vendor_regs(host);
}
- Also, we need you to add similar patch to your rel-32 version software and dump the same register so that we can compare the registers. Below patch is for rel-32.
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index f2e6ed3..261220e 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -403,7 +403,7 @@
u32 trim_delay;
u8 i;
- pr_debug("======= %s: Tuning windows =======\n",
+ pr_err("======= %s: Tuning windows =======\n",
mmc_hostname(host->mmc));
reg = sdhci_readl(host, SDHCI_VNDR_TUN_CTRL0_0);
for (i = 0; i <= TUNING_WORD_SEL_MASK; i++) {
@@ -411,7 +411,7 @@
reg |= i;
sdhci_writel(host, reg, SDHCI_VNDR_TUN_CTRL0_0);
tuning_status = sdhci_readl(host, SDHCI_TEGRA_VNDR_TUNING_STATUS0);
- pr_debug("%s: tuning window[%d]: %#x\n",
+ pr_err("%s: tuning window[%d]: %#x\n",
mmc_hostname(host->mmc), i, tuning_status);
}
reg = sdhci_readl(host, SDHCI_TEGRA_VENDOR_CLOCK_CTRL);
@@ -419,35 +419,35 @@
tap_delay &= SDHCI_CLOCK_CTRL_TAP_MASK;
trim_delay = reg >> SDHCI_CLOCK_CTRL_TRIM_SHIFT;
trim_delay &= SDHCI_CLOCK_CTRL_TRIM_MASK;
- pr_debug("sdhci: Tap value: %u | Trim value: %u\n", tap_delay,
+ pr_err("sdhci: Tap value: %u | Trim value: %u\n", tap_delay,
trim_delay);
- pr_debug("==================================\n");
+ pr_err("==================================\n");
- pr_debug("Vendor clock ctrl: %#x\n",
+ pr_err("Vendor clock ctrl: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_CLOCK_CTRL));
- pr_debug("Vendor SysSW ctrl: %#x\n",
+ pr_err("Vendor SysSW ctrl: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL));
- pr_debug("Vendor Err interrupt status : %#x\n",
+ pr_err("Vendor Err interrupt status : %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_ERR_INTR_STATUS));
- pr_debug("Vendor Cap overrides: %#x\n",
+ pr_err("Vendor Cap overrides: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_CAP_OVERRIDES));
- pr_debug("Vendor Misc ctrl: %#x\n",
+ pr_err("Vendor Misc ctrl: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_MISC_CTRL));
- pr_debug("Vendor Misc ctrl_1: %#x\n",
+ pr_err("Vendor Misc ctrl_1: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_MISC_CTRL_1));
- pr_debug("Vendor Misc ctrl_2: %#x\n",
+ pr_err("Vendor Misc ctrl_2: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VENDOR_MISC_CTRL_2));
- pr_debug("Vendor IO trim ctrl: %#x\n",
+ pr_err("Vendor IO trim ctrl: %#x\n",
sdhci_readl(host, SDMMC_VNDR_IO_TRIM_CTRL_0));
- pr_debug("Vendor Tuning ctrl: %#x\n",
+ pr_err("Vendor Tuning ctrl: %#x\n",
sdhci_readl(host, SDHCI_VNDR_TUN_CTRL0_0));
- pr_debug("SDMEM comp padctrl: %#x\n",
+ pr_err("SDMEM comp padctrl: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_SDMEM_COMP_PADCTRL));
- pr_debug("Autocal config: %#x\n",
+ pr_err("Autocal config: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG));
- pr_debug("Autocal status: %#x\n",
+ pr_err("Autocal status: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_STATUS));
- pr_debug("Tuning Status1: %#x\n",
+ pr_err("Tuning Status1: %#x\n",
sdhci_readl(host, SDHCI_TEGRA_VNDR_TUNING_STATUS1));
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index e355775..0c3bfed 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2772,6 +2772,7 @@
else {
pr_err("%s: CMD CRC or end bit error, int mask %#x\n",
mmc_hostname(host->mmc), (unsigned)intmask);
+ sdhci_dumpregs(host);
host->cmd->error = -EILSEQ;
}