Hi Hiago,

On 09.09.26 22:18, Hiago De Franco wrote:
> Hi Andrei,
> 
> On Wed, Sep 09, 2026 at 05:21:12PM +0200, Andrei Lalaev wrote:
>> Some samples of the Milk-V Duo and Duo 256M have issues with SD card
>> communication. As a result, the SD card is not detected, or the correct
>> mode is not selected.
>>
>> Configure SDHCI PHY in the same way as in downstream, to ensure
>> that the PHY is initialized properly.
> 
> Thanks for the v2 patch.
> 
> I tested this locally with my Milk-V Duo 256MB, same tests as before, and
> it works without issues. So:
> 
> Tested-by: Hiago De Franco <[email protected]> # Milk-V Duo 256M

Thank you for the tag :)

> My only minor comment would be related to the 'CV18XX_*' defines, the
> others do not see to have this prefix, so I would drop them and keep it
> like 'SDHCI_MSHC_CTRL'.

To be honest, I would rename the other defines as they are not generic SDHCI,
but CV1800B-specific, so I think it makes sense to prepend CV18XX.
No strong opinion, though.

> However, as usual, I also asked and AI agent (Claude Sonnet 5 - high, in
> this case) to review this patch and looks like it found something
> useful:
> 
> ```
> This always sets PHY_TX_BPS and writes TX_SRC_INVERT | RX_SRC_INVERT,
> and it only runs once, from probe(). Sophgo's own driver treats this
> as mode-dependent, not a fixed value - cvi_general_reset() in their
> tree branches on the live SDHCI_HOST_CONTROL2 UHS bits:
> 
>     if SDR104:
>         PHY_CONFIG    &= ~BIT(0)                 /* TX_BPS off */
>         PHY_TX_RX_DLY  = 0x00000100              /* TX_SRC_INVERT only, tap=0 
> */
>     else:
>         PHY_CONFIG    |= BIT(0)                  /* TX_BPS on */
>         PHY_TX_RX_DLY  = 0x01000100              /* TX_SRC_INVERT | 
> RX_SRC_INVERT */
> 
> and it does this on every reset, not once. With this patch, a board
> that actually negotiates SDR104 (LicheeRV Nano, or any cv1800b board
> without no-1-8-v in the DT) would go into the tuning sweep with
> TX_BPS stuck on - cv1800b_execute_tuning() never touches offset 0x24c.
> 
> I don't think this affects Duo or Duo 256M today - both set no-1-8-v,
> so they stay in HS and only ever want the else-branch values, which is
> exactly what's tested above. But since cv1800b_sdhci.c is shared with
> LicheeRV Nano, it seemed worth flagging rather than silently baking in
> a value that's only correct for one mode."
> ```
> 
> I can't test this since I do not have other boards apart from Milk-V duo
> with me, maybe you can take a look at this review to check if it is
> valid or not?

I don't have a LicheeRC Nano either, but both DTSes have 'no-1-8-v' property:
  - arch/riscv/dts/sg2002-licheerv-nano-b.dts +38
  - dts/upstream/src/riscv/sophgo/sg2002-licheerv-nano-b.dts +85

So it shouldn't break the board.

That said, since I'd prefer not to introduce changes I can't test
myself (like SDR104 mode), we can do something like this instead:

```
diff --git a/drivers/mmc/cv1800b_sdhci.c b/drivers/mmc/cv1800b_sdhci.c
index b756649f90f3..2512352383b2 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 SDHCI_MSHC_CTRL      0x200
+#define 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 PHY_LATANCY_1T BIT(1)
+#define PHY_TX_BPS BIT(0)
 
 struct cv1800b_sdhci_plat {
        struct mmc_config cfg;
@@ -64,10 +70,34 @@ static int cv1800b_execute_tuning(struct mmc *mmc, u8 
opcode)
 }
 #endif
 
+static int cv1800b_set_ios_post(struct sdhci_host *host)
+{
+       struct mmc *mmc = host->mmc;
+       u32 val;
+
+       if (mmc->selected_mode != MMC_LEGACY && mmc->selected_mode != MMC_HS &&
+           mmc->selected_mode != SD_HS)
+               return 0;
+
+       val = sdhci_readl(host, SDHCI_MSHC_CTRL);
+       val |= PHY_LATANCY_1T;
+       sdhci_writel(host, val, SDHCI_MSHC_CTRL);
+
+       val = sdhci_readl(host, SDHCI_PHY_CONFIG);
+       val |= PHY_TX_BPS;
+       sdhci_writel(host, val, 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
+       .set_ios_post = cv1800b_set_ios_post,
 };
 
 static int cv1800b_sdhci_bind(struct udevice *dev)
```


> According to the agent, a possible fix would be:
> ...
> 
> Regards,


-- 
Best regards,
Andrei Lalaev

Reply via email to