[PATCH 1/2] mmc: sdhci-cadence6: flush posted writes to PHY registers

[email protected]
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.