On 8/9/2026 2:00 pm, Kathpalia, Tanmay wrote:
Hi Tze,
On 9/3/2026 2:46 PM, NG, TZE YEE wrote:
On 28/8/2026 11:35 pm, Kathpalia, Tanmay wrote:
On 8/21/2026 1:38 PM, [email protected] wrote:
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);
Did you ever hit a case where a PHY readback after a burst of writes did
not match what you wrote (HRS04 = target SFR, readl(HRS05) != expected
value)? Do you have a capture of that, with and without the dummy
HRS05 read?
Hi Tanmay,
No, I don't have a capture of read(HRS05) returning a value other than
what was written. Every indirect‑register read‑back I did during
bring‑up matched the programmed/expected values; the corruption I
captured was always at the first data transfer after a mode switch
(CRC/timeout), not at the register level.
Thanks for the clarification. Since every PHY readback matched the
programmed value, and the observed failures were CRC/timeout errors on
the first transfer after a mode switch rather than a lost SFR write.
With the corrected timing, the failure no longer reproduces without
this change.
UG section 7.2.11 state that the next HRS04/HRS05 operation start after
the previous operation has completed; it does not require a readback
after every write. Also, the commit message says that back-to-back
HRS04/HRS05 writes can race, while the comment says reads and writes to
the same slave are not reordered. These statements seem inconsistent.
If the interconnect already preserves ordering for the pair, the dummy
readl(HRS05) does not address a race.
NAK on this patch. Please drop it.
Thanks,
Tanmay
Agreed, and thanks for the careful review. Please drop this patch.
Thanks,
Tze Yee