Message ID | 20221014072456.28953-3-pshete@nvidia.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v8,1/3] mmc: sdhci-tegra: Separate Tegra194 and Tegra234 SoC data | expand |
Dropping 4th(following) patch in this series from previous versions as that fix is applied. [PATCH v7 4/4] mmc: sdhci-tegra: Use actual clock rate for SW tuning correction > -----Original Message----- > From: Prathamesh Shete <pshete@nvidia.com> > Sent: Friday, October 14, 2022 12:55 PM > To: adrian.hunter@intel.com; ulf.hansson@linaro.org; > thierry.reding@gmail.com; Jonathan Hunter <jonathanh@nvidia.com>; > p.zabel@pengutronix.de; linux-mmc@vger.kernel.org; linux- > tegra@vger.kernel.org; linux-kernel@vger.kernel.org > Cc: Aniruddha Tvs Rao <anrao@nvidia.com>; Suresh Mangipudi > <smangipudi@nvidia.com>; Prathamesh Shete <pshete@nvidia.com>; > Krishna Yarlagadda <kyarlagadda@nvidia.com> > Subject: [PATCH v8 3/3] mmc: sdhci-tegra: Issue CMD and DAT resets > together > > In case of error condition to avoid system crash Tegra SDMMC controller > requires CMD and DAT resets issued together. SDHCI controller FSM goes > into bad state due to rapid SD card hot-plug event. > Issuing reset on the CMD FSM before DATA FSM results in kernel panic, > hence add support to issue CMD and DAT resets together. > This is applicable to Tegra186 and later chips. > > Signed-off-by: Aniruddha TVS Rao <anrao@nvidia.com> > Signed-off-by: Prathamesh Shete <pshete@nvidia.com> > Acked-by: Adrian Hunter <adrian.hunter@intel.com> > Acked-by: Thierry Reding <treding@nvidia.com> > --- > drivers/mmc/host/sdhci-tegra.c | 3 ++- > drivers/mmc/host/sdhci.c | 5 +++++ > drivers/mmc/host/sdhci.h | 2 ++ > 3 files changed, 9 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c > index 0cd7c3f7e6f4..9fbea5bbfa4a 100644 > --- a/drivers/mmc/host/sdhci-tegra.c > +++ b/drivers/mmc/host/sdhci-tegra.c > @@ -1535,7 +1535,8 @@ static const struct sdhci_pltfm_data > sdhci_tegra186_pdata = { > SDHCI_QUIRK_NO_HISPD_BIT | > SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | > SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, > - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, > + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | > + SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER, > .ops = &tegra186_sdhci_ops, > }; > > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index > 2b5dda521b0e..8512a69f1aae 100644 > --- a/drivers/mmc/host/sdhci.c > +++ b/drivers/mmc/host/sdhci.c > @@ -270,6 +270,11 @@ enum sdhci_reset_reason { > > static void sdhci_reset_for_reason(struct sdhci_host *host, enum > sdhci_reset_reason reason) { > + if (host->quirks2 & > + SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER) { > + sdhci_do_reset(host, SDHCI_RESET_CMD | > SDHCI_RESET_DATA); > + return; > + } > switch (reason) { > case SDHCI_RESET_FOR_INIT: > sdhci_do_reset(host, SDHCI_RESET_CMD | > SDHCI_RESET_DATA); diff --git a/drivers/mmc/host/sdhci.h > b/drivers/mmc/host/sdhci.h index d750c464bd1e..6a5766774b05 100644 > --- a/drivers/mmc/host/sdhci.h > +++ b/drivers/mmc/host/sdhci.h > @@ -478,6 +478,8 @@ struct sdhci_host { > * block count. > */ > #define SDHCI_QUIRK2_USE_32BIT_BLK_CNT (1<<18) > +/* Issue CMD and DATA reset together */ > +#define SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER (1<<19) > > int irq; /* Device IRQ */ > void __iomem *ioaddr; /* Mapped address */ > -- > 2.17.1
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 0cd7c3f7e6f4..9fbea5bbfa4a 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -1535,7 +1535,8 @@ static const struct sdhci_pltfm_data sdhci_tegra186_pdata = { SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER, .ops = &tegra186_sdhci_ops, }; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 2b5dda521b0e..8512a69f1aae 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -270,6 +270,11 @@ enum sdhci_reset_reason { static void sdhci_reset_for_reason(struct sdhci_host *host, enum sdhci_reset_reason reason) { + if (host->quirks2 & + SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER) { + sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); + return; + } switch (reason) { case SDHCI_RESET_FOR_INIT: sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index d750c464bd1e..6a5766774b05 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -478,6 +478,8 @@ struct sdhci_host { * block count. */ #define SDHCI_QUIRK2_USE_32BIT_BLK_CNT (1<<18) +/* Issue CMD and DATA reset together */ +#define SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER (1<<19) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */