[PATCH 1/2] mmc: sdhci-cadence6: flush posted writes to PHY registers
| Newsgroups | gmane.comp.boot-loaders.u-boot.general,gmane.comp.boot-loaders.u-boot |
|---|---|
| Message-ID | <[email protected]> |
From: Tze Yee Ng <[email protected]> Indirect PHY register writes go through HRS04/HRS05 and are posted: the write returns before the PHY has latched the value and there is no ACK handshake. Back-to-back PHY configuration writes can therefore race and leave the PHY partially programmed, corrupting the first data transfer after a mode switch. Read back HRS05 after each indirect write to flush the posted write before the next PHY access. Fixes: fe11aa0b8ca3 ("mmc: sdhci-cadence: Add support for Cadence sdmmc v6") Signed-off-by: Tze Yee Ng <[email protected]> --- drivers/mmc/sdhci-cadence6.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/mmc/sdhci-cadence6.c b/drivers/mmc/sdhci-cadence6.c index ca1086e2359..93cb19ecaaf 100644 --- a/drivers/mmc/sdhci-cadence6.c +++ b/drivers/mmc/sdhci-cadence6.c @@ -171,6 +171,16 @@ static void sdhci_cdns6_write_phy_reg(struct sdhci_cdns_plat *plat, u32 addr, u3 { writel(addr, plat->hrs_addr + SDHCI_CDNS_HRS04); writel(val, plat->hrs_addr + SDHCI_CDNS_HRS05); + + /* + * HRS04/HRS05 form the indirect PHY register port: HRS04 latches the + * target address, HRS05 the data. Both are posted writes, so read + * HRS05 back to force them to complete before the next PHY access. + * The readback also orders the preceding HRS04 write - reads and + * writes to the same slave are not reordered on this interconnect, so + * a single HRS05 readback flushes the whole address+data pair. + */ + (void)readl(plat->hrs_addr + SDHCI_CDNS_HRS05); } static int sdhci_cdns6_reset_phy_dll(struct sdhci_cdns_plat *plat, bool reset) -- 2.43.7