Message ID | 20221128024407.224393-4-doug@schmorgal.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mmc: sdhci-pxav2: Add support for PXA168 | expand |
On 28/11/22 04:44, Doug Brown wrote: > The PXA168 has a documented silicon bug that results in a data abort > exception when accessing the SDHCI_HOST_VERSION register on SDH2 and > SDH4 through a 16-bit read. Implement the workaround described in the > errata, which performs a 32-bit read from a lower address instead. This > is safe to use on all four SDH peripherals. > > Signed-off-by: Doug Brown <doug@schmorgal.com> > --- > drivers/mmc/host/sdhci-pxav2.c | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > > diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c > index 2f9fa0ecbddd..d76131b8986b 100644 > --- a/drivers/mmc/host/sdhci-pxav2.c > +++ b/drivers/mmc/host/sdhci-pxav2.c > @@ -80,6 +80,18 @@ static void pxav2_reset(struct sdhci_host *host, u8 mask) > } > } > > +static inline u16 pxav1_readw(struct sdhci_host *host, int reg) > +{ > + u32 temp; > + /* Workaround for data abort exception on SDH2 and SDH4 on PXA168 */ > + if (reg == SDHCI_HOST_VERSION) { > + temp = readl(host->ioaddr + SDHCI_HOST_VERSION - 2) >> 16; > + return temp & 0xffff; Isn't this the same as just: return readl(host->ioaddr + SDHCI_HOST_VERSION - 2) >> 16; > + } > + > + return readw(host->ioaddr + reg); > +} > + > static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width) > { > u8 ctrl; > @@ -102,6 +114,7 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width) > } > > static const struct sdhci_ops pxav1_sdhci_ops = { > + .read_w = pxav1_readw, > .set_clock = sdhci_set_clock, > .get_max_clock = sdhci_pltfm_clk_get_max_clock, > .set_bus_width = pxav2_mmc_set_bus_width,
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index 2f9fa0ecbddd..d76131b8986b 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c @@ -80,6 +80,18 @@ static void pxav2_reset(struct sdhci_host *host, u8 mask) } } +static inline u16 pxav1_readw(struct sdhci_host *host, int reg) +{ + u32 temp; + /* Workaround for data abort exception on SDH2 and SDH4 on PXA168 */ + if (reg == SDHCI_HOST_VERSION) { + temp = readl(host->ioaddr + SDHCI_HOST_VERSION - 2) >> 16; + return temp & 0xffff; + } + + return readw(host->ioaddr + reg); +} + static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width) { u8 ctrl; @@ -102,6 +114,7 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width) } static const struct sdhci_ops pxav1_sdhci_ops = { + .read_w = pxav1_readw, .set_clock = sdhci_set_clock, .get_max_clock = sdhci_pltfm_clk_get_max_clock, .set_bus_width = pxav2_mmc_set_bus_width,
The PXA168 has a documented silicon bug that results in a data abort exception when accessing the SDHCI_HOST_VERSION register on SDH2 and SDH4 through a 16-bit read. Implement the workaround described in the errata, which performs a 32-bit read from a lower address instead. This is safe to use on all four SDH peripherals. Signed-off-by: Doug Brown <doug@schmorgal.com> --- drivers/mmc/host/sdhci-pxav2.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)