2021-08-02 08:09 AM
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áš.
Solved! Go to Solution.
2021-09-30 11:49 PM
Ok for my understanding and to avoid to ask you some stupid questions, let's recap my understanding (please correct if I am wrong):
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.
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.
2021-10-01 04:33 AM
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.
2021-10-01 04:41 AM
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.
2021-10-01 06:10 AM
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;
}
2021-10-01 06:35 AM
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).
2021-10-01 08:44 AM
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).
2021-10-03 11:18 PM
could you please share the new trace (with the patch) ?
2021-10-03 11:47 PM
2021-10-04 12:17 AM
2021-10-12 02:15 AM
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.