Message ID | 20231012184041.1837455-2-avri.altman@wdc.com |
---|---|
State | New |
Headers | show |
Series | mmc: host: Disable auto-cmd12 during ffu | expand |
On 12/10/23 21:40, Avri Altman wrote: > Field Firmware Update (ffu) may use close-ended or open ended sequence. > Each such sequence is comprised of a write commands enclosed between 2 > switch commands - to and from ffu mode. > > Some platforms generate auto command error interrupt when it shouldn't, > e.g. auto-cmd12 while in close-ended ffu sequence. > > Therefore, add a quirk that disable auto-cmd12 while close-ended ffu is > in progress. If you hook the request function, maybe the existing SDHCI_AUTO_CMD12 flag could be used instead of introducing a new quirk: void sdhci_msm_request(etc) { if data-mrq and using-auto-cmd-12 if ffu host->flags &= ~SDHCI_AUTO_CMD12; else host->flags |= SDHCI_AUTO_CMD12; sdhci_request(etc) } > > Signed-off-by: Avri Altman <avri.altman@wdc.com> > --- > drivers/mmc/host/sdhci.c | 8 +++++++- > drivers/mmc/host/sdhci.h | 2 ++ > include/linux/mmc/core.h | 3 +++ > 3 files changed, 12 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c > index ff41aa56564e..6d58f71f926e 100644 > --- a/drivers/mmc/host/sdhci.c > +++ b/drivers/mmc/host/sdhci.c > @@ -1389,11 +1389,17 @@ void sdhci_switch_external_dma(struct sdhci_host *host, bool en) > } > EXPORT_SYMBOL_GPL(sdhci_switch_external_dma); > > +static inline bool sdhci_dont_auto_cmd12_ffu(struct sdhci_host *host, > + struct mmc_request *mrq) { > + return (host->quirks2 & SDHCI_QUIRK2_FFU_ACMD12) && mrq->ffu; > +} > + > static inline bool sdhci_auto_cmd12(struct sdhci_host *host, > struct mmc_request *mrq) > { > return !mrq->sbc && (host->flags & SDHCI_AUTO_CMD12) && > - !mrq->cap_cmd_during_tfr; > + !mrq->cap_cmd_during_tfr && > + !sdhci_dont_auto_cmd12_ffu(host, mrq); > } > > static inline bool sdhci_auto_cmd23(struct sdhci_host *host, > diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h > index f219bdea8f28..ccab3a76883c 100644 > --- a/drivers/mmc/host/sdhci.h > +++ b/drivers/mmc/host/sdhci.h > @@ -485,6 +485,8 @@ struct sdhci_host { > #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) > +/* Controller generates auto-cmd error interrupt during close-ended ffu */ > +#define SDHCI_QUIRK2_FFU_ACMD12 (1<<20) > > int irq; /* Device IRQ */ > void __iomem *ioaddr; /* Mapped address */ > diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h > index 6efec0b9820c..aca4e84f648c 100644 > --- a/include/linux/mmc/core.h > +++ b/include/linux/mmc/core.h > @@ -161,6 +161,9 @@ struct mmc_request { > /* Allow other commands during this ongoing data transfer or busy wait */ > bool cap_cmd_during_tfr; > > + /* Be aware that ffu is in progress and avoid auto-cmd12 */ > + bool ffu; > + > int tag; > > #ifdef CONFIG_MMC_CRYPTO
> > On 12/10/23 21:40, Avri Altman wrote: > > Field Firmware Update (ffu) may use close-ended or open ended sequence. > > Each such sequence is comprised of a write commands enclosed between 2 > > switch commands - to and from ffu mode. > > > > Some platforms generate auto command error interrupt when it > > shouldn't, e.g. auto-cmd12 while in close-ended ffu sequence. > > > > Therefore, add a quirk that disable auto-cmd12 while close-ended ffu > > is in progress. > > If you hook the request function, maybe the existing SDHCI_AUTO_CMD12 > flag could be used instead of introducing a new quirk: > > void sdhci_msm_request(etc) > { > if data-mrq and using-auto-cmd-12 > if ffu > host->flags &= ~SDHCI_AUTO_CMD12; > else > host->flags |= SDHCI_AUTO_CMD12; > sdhci_request(etc) > } Thanks - will do. Thanks, Avri
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ff41aa56564e..6d58f71f926e 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1389,11 +1389,17 @@ void sdhci_switch_external_dma(struct sdhci_host *host, bool en) } EXPORT_SYMBOL_GPL(sdhci_switch_external_dma); +static inline bool sdhci_dont_auto_cmd12_ffu(struct sdhci_host *host, + struct mmc_request *mrq) { + return (host->quirks2 & SDHCI_QUIRK2_FFU_ACMD12) && mrq->ffu; +} + static inline bool sdhci_auto_cmd12(struct sdhci_host *host, struct mmc_request *mrq) { return !mrq->sbc && (host->flags & SDHCI_AUTO_CMD12) && - !mrq->cap_cmd_during_tfr; + !mrq->cap_cmd_during_tfr && + !sdhci_dont_auto_cmd12_ffu(host, mrq); } static inline bool sdhci_auto_cmd23(struct sdhci_host *host, diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index f219bdea8f28..ccab3a76883c 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -485,6 +485,8 @@ struct sdhci_host { #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) +/* Controller generates auto-cmd error interrupt during close-ended ffu */ +#define SDHCI_QUIRK2_FFU_ACMD12 (1<<20) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 6efec0b9820c..aca4e84f648c 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -161,6 +161,9 @@ struct mmc_request { /* Allow other commands during this ongoing data transfer or busy wait */ bool cap_cmd_during_tfr; + /* Be aware that ffu is in progress and avoid auto-cmd12 */ + bool ffu; + int tag; #ifdef CONFIG_MMC_CRYPTO
Field Firmware Update (ffu) may use close-ended or open ended sequence. Each such sequence is comprised of a write commands enclosed between 2 switch commands - to and from ffu mode. Some platforms generate auto command error interrupt when it shouldn't, e.g. auto-cmd12 while in close-ended ffu sequence. Therefore, add a quirk that disable auto-cmd12 while close-ended ffu is in progress. Signed-off-by: Avri Altman <avri.altman@wdc.com> --- drivers/mmc/host/sdhci.c | 8 +++++++- drivers/mmc/host/sdhci.h | 2 ++ include/linux/mmc/core.h | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-)