aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci-cadence.c
diff options
context:
space:
mode:
authorVladimir Kondratiev <vladimir.kondratiev@intel.com>2020-05-25 10:40:53 +0300
committerUlf Hansson <ulf.hansson@linaro.org>2020-05-29 12:37:59 +0200
commitf6bc8186a588627c7faf3f2f2615e4c0e4d454a6 (patch)
treee84aa0dfa846b8d0d3dd58496a2fefc90e885333 /drivers/mmc/host/sdhci-cadence.c
parentmmc: sdio: Sort all SDIO IDs in common include file (diff)
downloadlinux-dev-f6bc8186a588627c7faf3f2f2615e4c0e4d454a6.tar.xz
linux-dev-f6bc8186a588627c7faf3f2f2615e4c0e4d454a6.zip
mmc: sdhci-cadence: fix PHY write
Accordingly to Cadence documentation, PHY write procedure is: 1. Software sets the PHY Register Address (HRS04[5:0]) and the PHY Write Data (HRS04[15:8]) fields. 2. Software sets the PHY Write Transaction Request (HRS04[24]) field to 1. 3. Software waits as the PHY Write Transaction Acknowledge (HRS04[26]) field is equal to 0. 4. Hardware performs the write transaction to PHY register where HRS04[15:8] is a data written to register under HRS04[5:0] address. 5. Hardware sets the PHY Transaction Acknowledge (HRS04[26]) to 1 when transaction is completed. 6. Software clears the PHY Write Transaction Request (HRS04[24]) to 1 after noticing that the PHY Write Transaction Acknowledge (HRS04[26]) field is equal to 1. 7. Software waits for the PHY Acknowledge Register (HRS04[26]) field is equal to 0. Add missing steps 3 and 7. Lack of these steps causes integrity errors detested by hardware. Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@intel.com> Link: https://lore.kernel.org/r/20200525074053.7309-1-vladimir.kondratiev@intel.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/sdhci-cadence.c')
-rw-r--r--drivers/mmc/host/sdhci-cadence.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c
index 6da6d4fb5edd..4a6c9ba82538 100644
--- a/drivers/mmc/host/sdhci-cadence.c
+++ b/drivers/mmc/host/sdhci-cadence.c
@@ -97,6 +97,11 @@ static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv,
u32 tmp;
int ret;
+ ret = readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS04_ACK),
+ 0, 10);
+ if (ret)
+ return ret;
+
tmp = FIELD_PREP(SDHCI_CDNS_HRS04_WDATA, data) |
FIELD_PREP(SDHCI_CDNS_HRS04_ADDR, addr);
writel(tmp, reg);
@@ -111,7 +116,10 @@ static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv,
tmp &= ~SDHCI_CDNS_HRS04_WR;
writel(tmp, reg);
- return 0;
+ ret = readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS04_ACK),
+ 0, 10);
+
+ return ret;
}
static unsigned int sdhci_cdns_phy_param_count(struct device_node *np)