Skip to main content
Graduate
August 2, 2021
Solved

How can I get the MMC timing spec higher than sd high-speed?

  • August 2, 2021
  • 40 replies
  • 30077 views

Hello,

I am having difficulties with the MMC bus and the external SDIO wifi module. We are using the wifi module jody-w263 from U-blox with the OSD32MP1, and the communication with the module works, but it is quite slow. The wifi module is capable of SDR 104 and DDR50 communication speeds, but I add the support to the DTS, the communication is broken and the device returns the -110 while initializing.

How can I add support for higher speeds?

I attach the working dts, dmesg, ios and caps, and relevant schematic.

Any suggestion will be appreciated.

Best regards,

Tomáš.

    This topic has been closed for replies.
    Best answer by Bernard PUEL

    HEre is a workaround patch. I will explain later on ...

    40 replies

    Technical Moderator
    September 30, 2021

    for uhs, the driver will need to process on rising and falling edge of the data clock. So the driver needs at least 2x the io clock.

    Technical Moderator
    September 30, 2021

    We don't see much more information in the trace unfortunately. There is a timeout at start so no communication with the external chip.

    Technical Moderator
    September 30, 2021

    Considering you already tested before in high speed @50 MHZ and you had the same timeout.

    Do you have the possibility to look at your IOs ? Do you have the right 1,8v and some data exchanged with the wlan ?

    Graduate
    September 30, 2021

    I am not sure what you mean now. We can communicate with the WLAN module (in HS mode at 50MHz) but the communication is slow (approx. 1.5~2 MB/s), this could be some timeout issue, but the PatrickF tested the speed with the MURATA module and got similar results. And as I said before, we tried this WLAN with a CPU module from NXP and the speed was around 4.5 MB/s even if the SDIO speed was limited to 22 MHz.

    I attach images and data export from the oscilloscope. The signals are:

    • yellow - clock
    • cyan - CMD
    • purple - DAT0

    The images are taken with different timebase for better readability.

    Technical Moderator
    October 1, 2021

    Ok for my understanding and to avoid to ask you some stupid questions, let's recap my understanding (please correct if I am wrong):

    • Your main issue is the perf of WLAN (half bandwidth you had with same setup on NXP platform)
    • You are trying to enable uhs at 50Mhz to double the theoric sdio bandwidth "uhs-ddr50" should be ok for that
    • In case of DTS (uhs mode):

    sd-uhs-ddr50;

    vmmc-supply = <&v3v3>;

    mmc-pwrseq = <&wifi_pwrseq>;

    The trace shows multiple try to negociate and most of the time error -110 (timeout) that shows communication with the wlan device is almost not possible.

    • In case of DTS (default mode):

    vmmc-supply = <&v3v3>;

    mmc-pwrseq = <&wifi_pwrseq>;

    You said you have some "error -110 (timeout)" in dmesg but the wlan works well (but with low bandwidth)

    Please confirm.

    Graduate
    October 1, 2021

    Mostly yes, only the last point is not correct. If we do not specify the sd-uhs-* parameter, the module works, but it is slow (compared to the NXP with the same driver and almost the same kernel - 5.4.96), and we don't know why (perhaps there are some timeouts, but we do not see them in logs). We thought that using the DDR could bring us better speed.

    The test report provided with the driver notes that the speeds can be from 55 Mbps to ~250 Mbps, so there must be some SW issue because the SDIO bus on our board has only 1 cm length.

    Technical Moderator
    October 1, 2021

    ok. Probably the firmware loaded into the wlan chipset can have also influence.

    I think you have already given a lot of information. We will try to compute and come back to you.

    Technical Moderator
    October 1, 2021

    from your trace:

    [ 236.696152] mmci-pl18x 48004000.sdmmc: mmc0: PL180 manf 53 rev1 at 0x48004000 irq 40,0 (pio)

    [ 236.702507] mmc0: clock 0Hz busmode 2 powermode 1 cs 0 Vdd 21 width 1 timing 0

    [ 236.715114] mmc0: clock 400000Hz busmode 2 powermode 2 cs 0 Vdd 21 width 1 timing 0

    [ 236.729895] mmc0: mmc_rescan_try_freq: trying to init card at 400000 Hz

    [ 236.729924] mmc0: starting CMD52 arg 00000c00 flags 00000195

    [ 236.730322] mmc0: req done (CMD52): -110: 00000000 00000000 00000000 00000000

    [ 236.735069] mmc0: starting CMD52 arg 80000c08 flags 00000195

    [ 236.735482] mmc0: req done (CMD52): -110: 00000000 00000000 00000000 00000000

    [ 236.736117] mmc0: clock 400000Hz busmode 2 powermode 2 cs 1 Vdd 21 width 1 timing 0

    [ 236.738549] mmc0: starting CMD0 arg 00000000 flags 000000c0

    [ 236.738782] mmc0: req done (CMD0): 0: 00000000 00000000 00000000 00000000

    [ 236.740235] mmc0: clock 400000Hz busmode 2 powermode 2 cs 0 Vdd 21 width 1 timing 0

    [ 236.742727] mmc0: starting CMD5 arg 00000000 flags 000002e1

    [ 236.743080] mmc0: req done (CMD5): 0: 90ff8000 00000000 00000000 00000000

    [ 236.743165] mmc0: starting CMD5 arg 01200000 flags 000002e1

    [ 236.743516] mmc0: req done (CMD5): 0: 91200000 00000000 00000000 00000000

    [ 236.743616] mmc0: starting CMD11 arg 00000000 flags 00000015

    [ 236.743954] mmc0: req done (CMD11): 0: 00001e00 00000000 00000000 00000000

    [ 236.746552] mmc0: Signal voltage switch failed, power cycling card

    [ 236.746619] mmc0: clock 0Hz busmode 2 powermode 0 cs 0 Vdd 0 width 1 timing 0

    [ 236.749419] mmc0: clock 0Hz busmode 2 powermode 1 cs 0 Vdd 21 width 1 timing 0

    [ 236.765100] mmc0: clock 400000Hz busmode 2 powermode 2 cs 0 Vdd 21 width 1 timing 0

    [ 236.778813] mmc0: starting CMD52 arg 00000c00 flags 00000195

    [ 236.779231] mmc0: req done (CMD52): -110: 00000000 00000000 00000000 00000000

    [ 236.779324] mmc0: starting CMD52 arg 80000c08 flags 00000195

    We can see the SoC tries to initiate a communication with the wlan chip but tries to switch voltage (and fails) whereas it should not (IOs are already at 1,8v).

    This leads to a reset of the sdio interface, the process restart and fails again ... (at different frequencies).

    To avoid this request, could you please try to apply this patch (present in Kernel 5.10.61). Cherry pick could be ok or you can backport manually I guess:

    commit 8f499a90e7eecafd44e8206a3ab586d024930485

    Author: Christophe Kerello <christophe.kerello@foss.st.com>

    Date:  Thu Jul 1 16:33:53 2021 +0200

      mmc: mmci: stm32: Check when the voltage switch procedure should be done

       

      [ Upstream commit d8e193f13b07e6c0ffaa1a999386f1989f2b4c5e ]

       

      If the card has not been power cycled, it may still be using 1.8V

      signaling. This situation is detected in mmc_sd_init_card function and

      should be handled in mmci stm32 variant. The host->pwr_reg variable is

      also correctly protected with spin locks.

       

      Fixes: 94b94a93e355 ("mmc: mmci_sdmmc: Implement signal voltage callbacks")

      Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>

      Signed-off-by: Yann Gautier <yann.gautier@foss.st.com>

      Cc: stable@vger.kernel.org

      Link: https://lore.kernel.org/r/20210701143353.13188-1-yann.gautier@foss.st.com

      Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

      Signed-off-by: Sasha Levin <sashal@kernel.org>

    diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c

    index 51db30acf4dc..fdaa11f92fe6 100644

    --- a/drivers/mmc/host/mmci_stm32_sdmmc.c

    +++ b/drivers/mmc/host/mmci_stm32_sdmmc.c

    @@ -479,8 +479,9 @@ static int sdmmc_post_sig_volt_switch(struct mmci_host *host,

        u32 status;

        int ret = 0;

    -    if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {

    -        spin_lock_irqsave(&host->lock, flags);

    +    spin_lock_irqsave(&host->lock, flags);

    +    if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180 &&

    +      host->pwr_reg & MCI_STM32_VSWITCHEN) {

            mmci_write_pwrreg(host, host->pwr_reg | MCI_STM32_VSWITCH);

            spin_unlock_irqrestore(&host->lock, flags);

    @@ -492,9 +493,11 @@ static int sdmmc_post_sig_volt_switch(struct mmci_host *host,

            writel_relaxed(MCI_STM32_VSWENDC | MCI_STM32_CKSTOPC,

                    host->base + MMCICLEAR);

    +        spin_lock_irqsave(&host->lock, flags);

            mmci_write_pwrreg(host, host->pwr_reg &

                     ~(MCI_STM32_VSWITCHEN | MCI_STM32_VSWITCH));

        }

    +    spin_unlock_irqrestore(&host->lock, flags);

        return ret;

     }

    Technical Moderator
    October 1, 2021

    It seems the function was reworked on 5.10 compared to 5.4.

    Could you please try (as test purpose) to patch the function: sdmmc_vswitch(struct mmci_host *host, struct mmc_ios *ios)

    so that it returns always 0 (and do nothing).

    Graduate
    October 1, 2021

    I have tried this but the result is still the same. I do not think it affects anything because the sdmmc_vswitch is used only in mmci_sig_volt_switch and the call depends on the existence of the vqmmc-supply in the DT node (if I understand correctly).

    Technical Moderator
    October 4, 2021

    could you please share the new trace (with the patch) ?

    Graduate
    October 4, 2021

    Sure.

    Graduate
    October 4, 2021

    I have tried to enable the log messages for a case when the module is recognized, and there are some timeouts while initializing on 400 kHz, but it is not logged in the standard dmesg output. I attach the output for comparison.

    Technical Moderator
    October 12, 2021

    Hello,

    from the sdio driver source code:

    * it. Per SDIO spec v3, section 3.1.2, if the voltage is already

    * 1.8v, the card sets S18A to 0 in the R4 response. So it will

    * fails to check rocr & R4_18V_PRESENT, but we still need to

    * try to init uhs card. sdio_read_cccr will take over this task

    * to make sure which speed mode should work.

    */

    So our assumption that the CMD11 command (to initiate switch voltage) initiation should not occurred was wrong.

    Analysis the first trace you sent again, we don't understand why the regulator reports an error.

    So could you please activate the dyn traces like below:

    in : /boot/mmc0_extlinux/stm32mp157f-dk2_extlinux.conf (or equivalent on your board)

    change: root=PARTUUID=e91c4e10-16e6-4c0e-bd0e-77becf4a3582 rootwait rw console=ttySTM0,115200 loglevel=8 dyndbg="file drivers/mmc/* +p"

    With dts config:

    vmmc-supply = <&v3v3>;

    vqmmc-supply = <&v1v8_ldo1>;

    mmc-pwrseq = <&wifi_pwrseq>;

    /* USER CODE END sdmmc3 */

    And kingly send back the trace.

    Graduate
    October 12, 2021

    Hello,

    thanks for your continuous support.

    I have done what you asked for and I am attaching the log. Is quite huge because the eMMC is connected also using the MMC bus.