[BACKPORT] mmcsd: eMMC 4-bit wide bus support for STM32 - #390
Open
13022591351 wants to merge 9 commits into
Open
[BACKPORT] mmcsd: eMMC 4-bit wide bus support for STM32#39013022591351 wants to merge 9 commits into
13022591351 wants to merge 9 commits into
Conversation
- Fix DMA addressing issues within litex_sendsetup/litex_recvsetup - Extend with handling specific to eMMC commands during init & use. - Cleanup of 4-bit BUS handling for SD and eMMC - For eMMC, Send CMD0 during init as per JEDEC v4.41 for pre-idle Backport note: the CMD1 failure recovery context differed on this branch (intermediate upstream commit 0797b03 is not present); resolved to the upstream end state of this region. (cherry picked from commit 50a8ec6)
Commit 50a8ec6 broke many mmc devices. Only if the flag priv->caps & SDIO_CAPS_4BIT_ONLY was set, it migth work. Without the flag, the mmc clock is never set (mmcsd_widebus() call is terminated early stopping the clock). This flag is probably not very generic because most mmc hw support 1, 4 and 8 bit modes. JEDEC specifies a bus width selection procedure, but it's not implemented in this mmcsd_sdio.c driver. Thus, it's not known whether the hw supports 1, 4 anf 8 bit modes or a combination of them. However, with priv->caps & SDIO_CAPS_4BIT_ONLY the driver suddenly assigns priv->buswidth = MMCSD_SCR_BUSWIDTH_4BIT making it the only way to have the driver working. Fix this by relaxing the above mentioned restrictions. Signed-off-by: Eero Nurkkala <eero.nurkkala@offcode.fi> (cherry picked from commit db13d5e)
…ce to 4-bit bus width mode All eMMC devices support 4-bit bus width, so we should mark the device as supporting 4-bit bus width after detecting that the device type is eMMC. Signed-off-by: Yinzhe Wu <Yinzhe.Wu@sony.com> Reviewed-by: Yuezhang Mo <Yuezhang.Mo@sony.com> Reviewed-by: Jacky Cao <Jacky.Cao@sony.com> Tested-by: Yinzhe Wu <Yinzhe.Wu@sony.com> (cherry picked from commit 4f7f751)
…EXT_CSD CMD6 can use these macros to set any writable EXT_CSD field, not just the bus width, so optimize these macro definitions to make them general. Signed-off-by: Yinzhe Wu <Yinzhe.Wu@sony.com> Reviewed-by: Yuezhang Mo <Yuezhang.Mo@sony.com> Reviewed-by: Jacky Cao <Jacky.Cao@sony.com> Tested-by: Yinzhe Wu <Yinzhe.Wu@sony.com> Backport note: the CMD6 call site on this branch used the pre-existing open-coded argument form; conflict resolved to the upstream macro form. (cherry picked from commit 08ce36d)
…MC high speed SDR mode According to the eMMC specification, in Backwards Compatibility with legacy MMC card mode, the frequency of the SD clock must be 0-26 MHZ; in high speed SDR mode, it must be 0-52MHZ. So we should switch to high speed SDR mode if the clock frequency is higher than 26MHZ. Signed-off-by: Yinzhe Wu <Yinzhe.Wu@sony.com> Reviewed-by: Yuezhang Mo <Yuezhang.Mo@sony.com> Reviewed-by: Jacky Cao <Jacky.Cao@sony.com> Tested-by: Yinzhe Wu <Yinzhe.Wu@sony.com> Backport note: struct mmcsd_state_s lives in mmcsd_sdio.c on this branch (upstream moved it to mmcsd.h); the mode:2 -> mode:4 bitfield change is applied there instead. (cherry picked from commit 49cbcfb)
…D cards This corrects the setting widebus for SD cards, which was recently broken in 4f7f751. The if checking the priv->caps, priv->buswidth and IS_MMC has been wrong for some time. The proper logic is that for MMC only the priv->caps is checked. For SD card, both priv->caps and priv->buswidth need to be checked. Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae> (cherry picked from commit 5238c3b)
…add 8-bit support The MMC CMD6 bus width switch was gated on priv->buswidth which is derived from the SD SCR register. For MMC cards this field is never set (unless SDIO_CAPS_4BIT_ONLY), so the CMD6 was skipped while the host PROCTL DTW was still changed - causing a bus width mismatch and data transfer timeouts. Fix by checking priv->caps instead of priv->buswidth for MMC cards. Also select EXT_CSD_BUS_WIDTH_8 when host reports SDIO_CAPS_8BIT. Signed-off-by: buxiasen <buxiasen@xiaomi.com> (cherry picked from commit 9feaa4d)
…or MMC/eMMC cards The STM32H7, STM32F7, STM32L4 and common STM32 SDIO/SDMMC drivers failed to program the WIDBUS bits when switching MMC/eMMC cards to 4-bit mode, and the MMC transfer clock presets were hardwired to 1-bit bus width. Add CLOCK_MMC_TRANSFER_4BIT to the common SDIO clock enum, add 4-bit MMC clock presets, and update stm32_widebus() to use modifyreg32/ sdmmc_modifyreg32 to set the host controller bus width. Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com> Backport note: upstream's arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c exists as arch/arm/src/stm32/stm32_sdio.c on this branch; the common-driver change is applied there. (cherry picked from commit 82ab33a)
Two sequencing problems in the MMC wide bus path break eMMC 4-bit operation on hosts that program the bus width in the SDIO widebus / clock callbacks (e.g. STM32H7): 1. The SWITCH command (CMD6) is issued before the host has switched to wide bus operation. When the card completes the switch while the host is still in 1-bit mode the switch never takes effect and every following data transfer times out. Switch the host to wide bus operation before issuing CMD6. 2. The transfer clock is selected only at the end of mmcsd_widebus(), so the whole switch sequence runs at ID-mode clock and, on the affected hosts, the final clock update does not take effect either, leaving the bus at ~400 kHz. Select the MMC transfer clock before calling mmcsd_widebus(), and pick CLOCK_MMC_TRANSFER_4BIT when wide bus operation is active (mirroring the SD card path) so a later clock selection cannot revert the host to 1-bit. No behavior change for SD cards, and no change on hosts whose widebus callback only records the requested state. Tested on a custom STM32H743 board with eMMC: sd_bench sequential write ~4.1 MB/s, sequential read ~6.3 MB/s (previously all data transfers timed out). Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com> Backport note: MMCSD_USLEEP does not exist on this branch (introduced upstream by 4435195, not backported); nxsig_usleep is used instead, matching the surrounding code. (cherry picked from commit e84259c)
Contributor
|
BTW we are upgrading to a newer NuttX soon, in case you wanted to test your board against this branch |
Contributor
Author
From this perspective, there is indeed no need to backport too much future code to the px4_firmware_nuttx-10.3.0+ branch. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Backport the eMMC/MMC 4-bit wide bus support from upstream NuttX to
px4_firmware_nuttx-10.3.0+.This supersedes #387, which implemented the same feature as a single
squashed commit that did not follow the PX4/NuttX backport conventions.
The two upstream commits carrying this feature have since been merged in
apache/nuttx, so this PR redoes the change as proper
[BACKPORT]cherry-picks with full upstream traceability.
Backported upstream commits (in dependency order):
The first seven are prerequisites of the final two: they introduce the
MMC CMD6 bus-width switch path, the EXT_CSD access macros, and the
SDIO_WIDEBUS condition fix that the sequencing fix modifies. Without
5238c3b the chain would also regress SD card 4-bit operation.
Deviations from upstream (documented in the respective commit messages):
struct mmcsd_state_sstill lives inmmcsd_sdio.con this branch;the
mode:2 -> mode:4bitfield change is applied there.MMCSD_USLEEPdoes not exist on this branch;nxsig_usleepis usedinstead, matching the surrounding code.
arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.cexists asarch/arm/src/stm32/stm32_sdio.con this branch; the common-driverchange is applied there.
Impact
switched to wide bus before CMD6, and the transfer clock is selected
before the switch sequence, fixing data transfer timeouts and the bus
being stuck at ~400 kHz.
handling, and no change on hosts whose widebus callback only records
the requested state.
Testing
STM32H743 board with eMMC: sd_bench sequential write ~4.1 MB/s,
sequential read ~6.3 MB/s (previously all data transfers timed out).