Hi Hiago,

So, I've dumped the registers using downstream U-Boot and yes, Claude was right.
By default, downstream driver configures the PHY, so the PHY registers
have the following values:

  # PHY_TX_RX_DLY
  milkv_duo_256m# md.l 0x04310240 1
  04310240: 01000100                             ....

  # PHY_CONFIG
  milkv_duo_256m# md.l 0x0431024c 1
  0431024c: 00000001                             ....


With upstream U-Boot, the same registers are always 0.

Simply setting `PHY_TX_RX_DLY` to `0x01000100` is enough to get
the SD card working.

The attached patch contains the backported PHY configuration from the downstream
driver & upstream kernel. Could you please take a look and check if it
resolves the issue on your side when increasing the clock?

Thank you!

---
 drivers/mmc/cv1800b_sdhci.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/mmc/cv1800b_sdhci.c b/drivers/mmc/cv1800b_sdhci.c
index b756649f90f3..5c129682daba 100644
--- a/drivers/mmc/cv1800b_sdhci.c
+++ b/drivers/mmc/cv1800b_sdhci.c
@@ -8,11 +8,17 @@
 #include <sdhci.h>
 #include <linux/delay.h>

+#define CV18XX_SDHCI_MSHC_CTRL  0x200
+#define CV18XX_SDHCI_PHY_CONFIG 0x24c
 #define SDHCI_PHY_TX_RX_DLY  0x240
 #define MMC_MAX_CLOCK        375000000
 #define TUNE_MAX_PHCODE      128

 #define PHY_TX_SRC_INVERT  BIT(8)
+#define PHY_RX_SRC_INVERT  BIT(24)
+
+#define CV18XX_LATANCY_1T BIT(1)
+#define CV18XX_PHY_TX_BPS BIT(0)

 struct cv1800b_sdhci_plat {
        struct mmc_config cfg;
@@ -64,10 +70,29 @@ static int cv1800b_execute_tuning(struct mmc *mmc, u8 
opcode)
 }
 #endif

+static int cv1800b_deferred_probe(struct sdhci_host *host)
+{
+       u32 val;
+
+       val = sdhci_readl(host, CV18XX_SDHCI_MSHC_CTRL);
+       val |= CV18XX_LATANCY_1T;
+       sdhci_writel(host, val, CV18XX_SDHCI_MSHC_CTRL);
+
+       val = sdhci_readl(host, CV18XX_SDHCI_PHY_CONFIG);
+       val |= CV18XX_PHY_TX_BPS;
+       sdhci_writel(host, val, CV18XX_SDHCI_PHY_CONFIG);
+
+       val = PHY_TX_SRC_INVERT | PHY_RX_SRC_INVERT;
+       sdhci_writel(host, val, SDHCI_PHY_TX_RX_DLY);
+
+       return 0;
+}
+
 const struct sdhci_ops cv1800b_sdhci_sd_ops = {
 #if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
        .platform_execute_tuning = cv1800b_execute_tuning,
 #endif
+       .deferred_probe = cv1800b_deferred_probe,
 };

 static int cv1800b_sdhci_bind(struct udevice *dev)
--
2.55.0


-- 
Best regards,
Andrei Lalaev

Reply via email to