From 1c7387579d743c02a3da7aefff1689a5a55c9b84 Mon Sep 17 00:00:00 2001 From: Luke Wang Date: Wed, 9 Apr 2025 15:55:50 +0800 Subject: [PATCH 01/16] mmc: sdhci-esdhc-imx: switch standard tuning to manual tuning Current standard tuning has some limitations: 1. Standard tuning only try 40 times to find first pass window, but this pass window maybe not the best pass window. 2. Sometimes there are two tuning pass windows and the gap between those two windows may only have one cell. If tuning step > 1, the gap may just be skipped and host assumes those two windows as a continuous windows. This will cause a bad delay cell near the gap to be selected. 3. Standard tuning logic need to detect at least one success and failure to pass the tuning. If all cells in the tuning window pass, the hardware will not set the SDHCI_CTRL_TUNED_CLK bit, causing tuning failed. 4. Standard tuning logic only check the CRC, do not really compare the data pattern. If data pins are connected incorrectly, standard will not detect this kind of issue. Switch to manual tuning to avoid those limitations Signed-off-by: Luke Wang Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/20250409075550.3413032-7-ziniu.wang_1@nxp.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-esdhc-imx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index bc84400400b3..b977d37e2684 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -275,35 +275,35 @@ static const struct esdhc_soc_data usdhc_imx6q_data = { }; static const struct esdhc_soc_data usdhc_imx6sl_data = { - .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_ERR004536 | ESDHC_FLAG_HS200 | ESDHC_FLAG_BROKEN_AUTO_CMD23, }; static const struct esdhc_soc_data usdhc_imx6sll_data = { - .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_HS400 | ESDHC_FLAG_STATE_LOST_IN_LPMODE, }; static const struct esdhc_soc_data usdhc_imx6sx_data = { - .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_STATE_LOST_IN_LPMODE | ESDHC_FLAG_BROKEN_AUTO_CMD23, }; static const struct esdhc_soc_data usdhc_imx6ull_data = { - .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_ERR010450 | ESDHC_FLAG_STATE_LOST_IN_LPMODE, }; static const struct esdhc_soc_data usdhc_imx7d_data = { - .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_HS400 | ESDHC_FLAG_STATE_LOST_IN_LPMODE @@ -319,7 +319,7 @@ static struct esdhc_soc_data usdhc_s32g2_data = { }; static struct esdhc_soc_data usdhc_imx7ulp_data = { - .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_PMQOS | ESDHC_FLAG_HS400 | ESDHC_FLAG_STATE_LOST_IN_LPMODE, @@ -332,7 +332,7 @@ static struct esdhc_soc_data usdhc_imxrt1050_data = { }; static struct esdhc_soc_data usdhc_imx8qxp_data = { - .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES | ESDHC_FLAG_STATE_LOST_IN_LPMODE @@ -341,7 +341,7 @@ static struct esdhc_soc_data usdhc_imx8qxp_data = { }; static struct esdhc_soc_data usdhc_imx8mm_data = { - .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES | ESDHC_FLAG_STATE_LOST_IN_LPMODE, -- 2.51.0 From 920e6bfa6a11baf4fae0e5ce9e3b70f59ae0d47a Mon Sep 17 00:00:00 2001 From: Axe Yang Date: Fri, 11 Apr 2025 13:40:25 +0800 Subject: [PATCH 02/16] mmc: mtk-sd: Add condition to enable 'single' burst type This change add a condition for 'single' burst type selection. Read AXI_LEN field from EMMC50_CFG2(AHB2AXI wrapper) register, if the value is not 0, it means the HWIP is using AXI as AMBA bus, which do not support 'single' burst type. Suggested-by: AngeloGioacchino Del Regno Signed-off-by: Axe Yang Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20250411054134.31822-1-axe.yang@mediatek.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/mtk-sd.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index a9bd0bc4d4eb..31eb90536bce 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -84,6 +84,7 @@ #define EMMC51_CFG0 0x204 #define EMMC50_CFG0 0x208 #define EMMC50_CFG1 0x20c +#define EMMC50_CFG2 0x21c #define EMMC50_CFG3 0x220 #define SDC_FIFO_CFG 0x228 #define CQHCI_SETTING 0x7fc @@ -306,7 +307,10 @@ /* EMMC50_CFG1 mask */ #define EMMC50_CFG1_DS_CFG BIT(28) /* RW */ -#define EMMC50_CFG3_OUTS_WR GENMASK(4, 0) /* RW */ +/* EMMC50_CFG2 mask */ +#define EMMC50_CFG2_AXI_SET_LEN GENMASK(27, 24) /* RW */ + +#define EMMC50_CFG3_OUTS_WR GENMASK(4, 0) /* RW */ #define SDC_FIFO_CFG_WRVALIDSEL BIT(24) /* RW */ #define SDC_FIFO_CFG_RDVALIDSEL BIT(25) /* RW */ @@ -1917,9 +1921,13 @@ static void msdc_init_hw(struct msdc_host *host) pb1_val |= FIELD_PREP(MSDC_PATCH_BIT1_CMDTA, 1); pb1_val |= MSDC_PB1_DDR_CMD_FIX_SEL; - /* Set single burst mode, auto sync state clear, block gap stop clk */ - pb1_val |= MSDC_PB1_SINGLE_BURST | MSDC_PB1_RSVD20 | - MSDC_PB1_AUTO_SYNCST_CLR | MSDC_PB1_MARK_POP_WATER; + /* Support 'single' burst type only when AXI_LEN is 0 */ + sdr_get_field(host->base + EMMC50_CFG2, EMMC50_CFG2_AXI_SET_LEN, &val); + if (!val) + pb1_val |= MSDC_PB1_SINGLE_BURST; + + /* Set auto sync state clear, block gap stop clk */ + pb1_val |= MSDC_PB1_RSVD20 | MSDC_PB1_AUTO_SYNCST_CLR | MSDC_PB1_MARK_POP_WATER; /* Set low power DCM, use HCLK for GDMA, use MSDC CLK for everything else */ pb1_val |= MSDC_PB1_LP_DCM_EN | MSDC_PB1_RSVD3 | -- 2.51.0 From 157d4ba8dfdfb1aebf8c2d059e5aa187abe06182 Mon Sep 17 00:00:00 2001 From: Inochi Amaoto Date: Mon, 14 Apr 2025 06:35:01 +0800 Subject: [PATCH 03/16] dt-bindings: mmc: sdhci-of-dwcmhsc: Add Sophgo SG2044 support The sdhci IP of SG2044 is similar to it of SG2042. They share the same clock and controller configuration. Add compatible string for SG2044. Signed-off-by: Inochi Amaoto Reviewed-by: Chen Wang Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250413223507.46480-8-inochiama@gmail.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml b/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml index e6e604072d3c..5fb347167004 100644 --- a/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml @@ -19,6 +19,9 @@ properties: - rockchip,rk3562-dwcmshc - rockchip,rk3576-dwcmshc - const: rockchip,rk3588-dwcmshc + - items: + - const: sophgo,sg2044-dwcmshc + - const: sophgo,sg2042-dwcmshc - enum: - rockchip,rk3568-dwcmshc - rockchip,rk3588-dwcmshc -- 2.51.0 From fe1c2abfc8a34e7e58940cb43a033fa86a785072 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 16 Apr 2025 14:02:45 +0200 Subject: [PATCH 04/16] dt-bindings: mmc: mtk-sd: Add support for Dimensity 1200 MT6893 Add a compatible for the MediaTek Dimensity 1200 (MT6893) SoC. All of the MMC/SD controllers in this chip are compatible with the ones found in MT8183, but do also make use of an optional crypto clock when enabling HW disk encryption. Signed-off-by: AngeloGioacchino Del Regno Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250416120245.147951-1-angelogioacchino.delregno@collabora.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml index 0debccbd6519..6dd26ad31491 100644 --- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml +++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml @@ -32,6 +32,7 @@ properties: - const: mediatek,mt2701-mmc - items: - enum: + - mediatek,mt6893-mmc - mediatek,mt8186-mmc - mediatek,mt8188-mmc - mediatek,mt8192-mmc @@ -299,6 +300,7 @@ allOf: properties: compatible: enum: + - mediatek,mt6893-mmc - mediatek,mt8186-mmc - mediatek,mt8188-mmc - mediatek,mt8195-mmc -- 2.51.0 From c02c658cc987537468f6b99daa1e08a25ca7e5fa Mon Sep 17 00:00:00 2001 From: Philipp Stanner Date: Thu, 17 Apr 2025 11:27:43 +0200 Subject: [PATCH 05/16] mmc: cavium-thunderx: Use non-hybrid PCI devres API cavium-thunderx enables its PCI device with pcim_enable_device(). This, implicitly, switches the function pci_request_regions() into managed mode, where it becomes a devres function. The PCI subsystem wants to remove this hybrid nature from its interfaces. To do so, users of the aforementioned combination of functions must be ported to non-hybrid functions. Moreover, since both functions are already managed in this driver, the calls to pci_release_regions() are unnecessary. Remove the calls to pci_release_regions(). Replace the call to sometimes-managed pci_request_regions() with one to the always-managed pcim_request_all_regions(). Signed-off-by: Philipp Stanner Link: https://lore.kernel.org/r/20250417092742.27887-2-phasta@kernel.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/cavium-thunderx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mmc/host/cavium-thunderx.c b/drivers/mmc/host/cavium-thunderx.c index 2e2ff984f0b3..1373deb3f531 100644 --- a/drivers/mmc/host/cavium-thunderx.c +++ b/drivers/mmc/host/cavium-thunderx.c @@ -72,7 +72,7 @@ static int thunder_mmc_probe(struct pci_dev *pdev, if (ret) return ret; - ret = pci_request_regions(pdev, KBUILD_MODNAME); + ret = pcim_request_all_regions(pdev, KBUILD_MODNAME); if (ret) return ret; @@ -164,7 +164,6 @@ error: } } clk_disable_unprepare(host->clk); - pci_release_regions(pdev); return ret; } @@ -183,7 +182,6 @@ static void thunder_mmc_remove(struct pci_dev *pdev) writeq(dma_cfg, host->dma_base + MIO_EMM_DMA_CFG(host)); clk_disable_unprepare(host->clk); - pci_release_regions(pdev); } static const struct pci_device_id thunder_mmc_id_table[] = { -- 2.51.0 From 88f2f360de9f6d8d068dd7ef084fc36d21f3cc9f Mon Sep 17 00:00:00 2001 From: Frank Li Date: Thu, 17 Apr 2025 11:13:00 -0400 Subject: [PATCH 06/16] dt-bindings: mmc: fsl,esdhc: add compatible string fsl,ls1021a-esdhc Add compatible string fsl,ls1021a-esdhc for LS1021a SoC. Signed-off-by: Frank Li Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250417151300.3570021-1-Frank.Li@nxp.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/fsl,esdhc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mmc/fsl,esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl,esdhc.yaml index b86ffb53b18b..62087cf920df 100644 --- a/Documentation/devicetree/bindings/mmc/fsl,esdhc.yaml +++ b/Documentation/devicetree/bindings/mmc/fsl,esdhc.yaml @@ -24,6 +24,7 @@ properties: - fsl,t1040-esdhc - fsl,t4240-esdhc - fsl,ls1012a-esdhc + - fsl,ls1021a-esdhc - fsl,ls1028a-esdhc - fsl,ls1088a-esdhc - fsl,ls1043a-esdhc -- 2.51.0 From a0ba0461c4f3750a310f77b1530768dccc0c8c39 Mon Sep 17 00:00:00 2001 From: Danila Tikhonov Date: Tue, 22 Apr 2025 23:17:12 +0300 Subject: [PATCH 07/16] dt-bindings: mmc: sdhci-msm: Add the SM7150 compatible Add compatible for the SDHCI block found in SM7150. Signed-off-by: Danila Tikhonov Link: https://lore.kernel.org/r/20250422-sm7150-upstream-v1-11-bf9a9081631d@jiaxyga.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/sdhci-msm.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml index eed9063e9bb3..2b2cbce2458b 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml @@ -60,6 +60,7 @@ properties: - qcom,sm6125-sdhci - qcom,sm6350-sdhci - qcom,sm6375-sdhci + - qcom,sm7150-sdhci - qcom,sm8150-sdhci - qcom,sm8250-sdhci - qcom,sm8350-sdhci -- 2.51.0 From 08f959759e1e6e9c4b898c51a7d387ac3480630b Mon Sep 17 00:00:00 2001 From: Nicolas Frattaroli Date: Wed, 23 Apr 2025 09:53:32 +0200 Subject: [PATCH 08/16] mmc: sdhci-of-dwcmshc: add PD workaround on RK3576 RK3576's power domains have a peculiar design where the PD_NVM power domain, of which the sdhci controller is a part, seemingly does not have idempotent runtime disable/enable. The end effect is that if PD_NVM gets turned off by the generic power domain logic because all the devices depending on it are suspended, then the next time the sdhci device is unsuspended, it'll hang the SoC as soon as it tries accessing the CQHCI registers. RK3576's UFS support needed a new dev_pm_genpd_rpm_always_on function added to the generic power domains API to handle what appears to be a similar hardware design. Use this new function to ask for the same treatment in the sdhci controller by giving rk3576 its own platform data with its own postinit function. The benefit of doing this instead of marking the power domains always on in the power domain core is that we only do this if we know the platform we're running on actually uses the sdhci controller. For others, keeping PD_NVM always on would be a waste, as they won't run into this specific issue. The only other IP in PD_NVM that could be affected is FSPI0. If it gets a mainline driver, it will probably want to do the same thing. Acked-by: Adrian Hunter Signed-off-by: Nicolas Frattaroli Reviewed-by: Shawn Lin Fixes: cfee1b507758 ("pmdomain: rockchip: Add support for RK3576 SoC") Cc: # v6.15+ Link: https://lore.kernel.org/r/20250423-rk3576-emmc-fix-v3-1-0bf80e29967f@collabora.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-dwcmshc.c | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index 09b9ab15e499..a20d03fdd6a9 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -745,6 +746,29 @@ static void dwcmshc_rk35xx_postinit(struct sdhci_host *host, struct dwcmshc_priv } } +static void dwcmshc_rk3576_postinit(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv) +{ + struct device *dev = mmc_dev(host->mmc); + int ret; + + /* + * This works around the design of the RK3576's power domains, which + * makes the PD_NVM power domain, which the sdhci controller on the + * RK3576 is in, never come back the same way once it's run-time + * suspended once. This can happen during early kernel boot if no driver + * is using either PD_NVM or its child power domain PD_SDGMAC for a + * short moment, leading to it being turned off to save power. By + * keeping it on, sdhci suspending won't lead to PD_NVM becoming a + * candidate for getting turned off. + */ + ret = dev_pm_genpd_rpm_always_on(dev, true); + if (ret && ret != -EOPNOTSUPP) + dev_warn(dev, "failed to set PD rpm always on, SoC may hang later: %pe\n", + ERR_PTR(ret)); + + dwcmshc_rk35xx_postinit(host, dwc_priv); +} + static int th1520_execute_tuning(struct sdhci_host *host, u32 opcode) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -1176,6 +1200,18 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk35xx_pdata = { .postinit = dwcmshc_rk35xx_postinit, }; +static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk3576_pdata = { + .pdata = { + .ops = &sdhci_dwcmshc_rk35xx_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, + }, + .init = dwcmshc_rk35xx_init, + .postinit = dwcmshc_rk3576_postinit, +}; + static const struct dwcmshc_pltfm_data sdhci_dwcmshc_th1520_pdata = { .pdata = { .ops = &sdhci_dwcmshc_th1520_ops, @@ -1274,6 +1310,10 @@ static const struct of_device_id sdhci_dwcmshc_dt_ids[] = { .compatible = "rockchip,rk3588-dwcmshc", .data = &sdhci_dwcmshc_rk35xx_pdata, }, + { + .compatible = "rockchip,rk3576-dwcmshc", + .data = &sdhci_dwcmshc_rk3576_pdata, + }, { .compatible = "rockchip,rk3568-dwcmshc", .data = &sdhci_dwcmshc_rk35xx_pdata, -- 2.51.0 From 1dfc7d1ab7839dff5b348d4f5915757203d4294c Mon Sep 17 00:00:00 2001 From: Alexey Charkov Date: Wed, 23 Apr 2025 14:53:29 +0400 Subject: [PATCH 09/16] dt-bindings: mmc: vt8500-sdmmc: Convert to YAML Rewrite the textual description for the WonderMedia SDMMC controller as YAML schema, and switch the filename to follow the compatible string. Signed-off-by: Alexey Charkov Reviewed-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250423-vt8500-sdmmc-binding-v2-1-ea4f17fd0638@gmail.com Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/vt8500-sdmmc.txt | 23 ------- .../bindings/mmc/wm,wm8505-sdhc.yaml | 66 +++++++++++++++++++ 2 files changed, 66 insertions(+), 23 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt create mode 100644 Documentation/devicetree/bindings/mmc/wm,wm8505-sdhc.yaml diff --git a/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt b/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt deleted file mode 100644 index d7fb6abb3eb8..000000000000 --- a/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt +++ /dev/null @@ -1,23 +0,0 @@ -* Wondermedia WM8505/WM8650 SD/MMC Host Controller - -This file documents differences between the core properties described -by mmc.txt and the properties used by the wmt-sdmmc driver. - -Required properties: -- compatible: Should be "wm,wm8505-sdhc". -- interrupts: Two interrupts are required - regular irq and dma irq. - -Optional properties: -- sdon-inverted: SD_ON bit is inverted on the controller - -Examples: - -sdhc@d800a000 { - compatible = "wm,wm8505-sdhc"; - reg = <0xd800a000 0x1000>; - interrupts = <20 21>; - clocks = <&sdhc>; - bus-width = <4>; - sdon-inverted; -}; - diff --git a/Documentation/devicetree/bindings/mmc/wm,wm8505-sdhc.yaml b/Documentation/devicetree/bindings/mmc/wm,wm8505-sdhc.yaml new file mode 100644 index 000000000000..5b55174e9088 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/wm,wm8505-sdhc.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mmc/wm,wm8505-sdhc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: WonderMedia SoC SDHCI Controller + +maintainers: + - Alexey Charkov + +allOf: + - $ref: mmc-controller.yaml# + +properties: + compatible: + oneOf: + - const: wm,wm8505-sdhc + - items: + - const: wm,wm8650-sdhc + - const: wm,wm8505-sdhc + - items: + - const: wm,wm8750-sdhc + - const: wm,wm8505-sdhc + - items: + - const: wm,wm8850-sdhc + - const: wm,wm8505-sdhc + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + interrupts: + items: + - description: SDMMC controller interrupt + - description: SDMMC controller DMA interrupt + + sdon-inverted: + type: boolean + description: All chips before (not including) WM8505 rev. A2 treated their + "clock stop" bit (register offset 0x08 a.k.a. SDMMC_BUSMODE, bit 0x10) + as "set 1 to disable SD clock", while all the later versions treated it + as "set 0 to disable SD clock". Set this property for later versions of + wm,wm8505-sdhc. On wm,wm8650-sdhc and later this property is implied and + does not need to be set explicitly + +required: + - compatible + - reg + - interrupts + - clocks + +unevaluatedProperties: false + +examples: + - | + mmc@d800a000 { + compatible = "wm,wm8505-sdhc"; + reg = <0xd800a000 0x1000>; + interrupts = <20>, <21>; + clocks = <&sdhc>; + bus-width = <4>; + sdon-inverted; + }; -- 2.51.0 From 5846efac138a650f7f95d68aaa4c40870bdbc352 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 23 Apr 2025 20:46:10 -0700 Subject: [PATCH 10/16] mmc: sdhci-esdhc-imx: fix defined but not used warnings Fix warnings when CONFIG_PM=y and CONFIG_PM_SLEEP is not set by surrounding the 2 functions with #ifdef CONFIG_PM_SLEEP. drivers/mmc/host/sdhci-esdhc-imx.c:1659:13: warning: 'sdhc_esdhc_tuning_restore' defined but not used [-Wunused-function] 1659 | static void sdhc_esdhc_tuning_restore(struct sdhci_host *host) drivers/mmc/host/sdhci-esdhc-imx.c:1637:13: warning: 'sdhc_esdhc_tuning_save' defined but not used [-Wunused-function] 1637 | static void sdhc_esdhc_tuning_save(struct sdhci_host *host) Fixes: 3d1eea493894 ("mmc: sdhci-esdhc-imx: Save tuning value when card stays powered in suspend") Signed-off-by: Randy Dunlap Reviewed-by: Haibo Chen Link: https://lore.kernel.org/r/20250424034610.441532-1-rdunlap@infradead.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-esdhc-imx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index b977d37e2684..c0160c69a027 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -1634,6 +1634,7 @@ static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host) } } +#ifdef CONFIG_PM_SLEEP static void sdhc_esdhc_tuning_save(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -1688,6 +1689,7 @@ static void sdhc_esdhc_tuning_restore(struct sdhci_host *host) host->ioaddr + ESDHC_TUNE_CTRL_STATUS); } } +#endif static void esdhc_cqe_enable(struct mmc_host *mmc) { -- 2.51.0 From 03b31a0638a1cb1c580de4d5054ec9f5caffdffc Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 1 May 2025 08:33:26 +0200 Subject: [PATCH 11/16] mmc: rename mmc_host_cmd23() to mmc_host_can_cmd23() It is not obvious that this functions checks capabilities. Rename it to include '_can' like other capability helpers. Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20250501063325.7262-7-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/block.c | 2 +- drivers/mmc/core/host.h | 2 +- drivers/mmc/core/mmc.c | 2 +- drivers/mmc/core/mmc_test.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 63320cc441c1..f9ad45476552 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -2618,7 +2618,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, */ md->read_only = mmc_blk_readonly(card); - if (mmc_host_cmd23(card->host)) { + if (mmc_host_can_cmd23(card->host)) { if ((mmc_card_mmc(card) && card->csd.mmca_vsn >= CSD_SPEC_VER_3) || (mmc_card_sd(card) && !mmc_card_ult_capacity(card) && diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index 48c4952512a5..c8515cb86192 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -39,7 +39,7 @@ static inline void mmc_retune_recheck(struct mmc_host *host) host->retune_now = 1; } -static inline int mmc_host_cmd23(struct mmc_host *host) +static inline int mmc_host_can_cmd23(struct mmc_host *host) { return host->caps & MMC_CAP_CMD23; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index e499835b05a9..c2b92b508438 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -578,7 +578,7 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) * RPMB regions are defined in multiples of 128K. */ card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT]; - if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_cmd23(card->host)) { + if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_can_cmd23(card->host)) { mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17, EXT_CSD_PART_CONFIG_ACC_RPMB, "rpmb", 0, false, diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c index be2d2895b4c4..80e5d87a5e50 100644 --- a/drivers/mmc/core/mmc_test.c +++ b/drivers/mmc/core/mmc_test.c @@ -191,7 +191,7 @@ static void mmc_test_prepare_sbc(struct mmc_test_card *test, { struct mmc_card *card = test->card; - if (!mrq->sbc || !mmc_host_cmd23(card->host) || + if (!mrq->sbc || !mmc_host_can_cmd23(card->host) || !mmc_test_card_cmd23(card) || !mmc_op_multi(mrq->cmd->opcode) || (card->quirks & MMC_QUIRK_BLK_NO_CMD23)) { mrq->sbc = NULL; @@ -2390,7 +2390,7 @@ static int mmc_test_ongoing_transfer(struct mmc_test_card *test, 512, write); if (use_sbc && t->blocks > 1 && !mrq->sbc) { - ret = mmc_host_cmd23(host) ? + ret = mmc_host_can_cmd23(host) ? RESULT_UNSUP_CARD : RESULT_UNSUP_HOST; goto out_free; -- 2.51.0 From dc03e2e9f05ffa3cbb9a2dfc7dfb112847d5d966 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 1 May 2025 08:33:27 +0200 Subject: [PATCH 12/16] mmc: rename mmc_host_done_complete() to mmc_host_can_done_complete() It is not obvious that this functions checks capabilities. Rename it to include '_can' like other capability helpers. Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20250501063325.7262-8-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/block.c | 6 +++--- drivers/mmc/core/host.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index f9ad45476552..585c2b274d98 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -2278,7 +2278,7 @@ void mmc_blk_mq_recovery(struct mmc_queue *mq) static void mmc_blk_mq_complete_prev_req(struct mmc_queue *mq, struct request **prev_req) { - if (mmc_host_done_complete(mq->card->host)) + if (mmc_host_can_done_complete(mq->card->host)) return; mutex_lock(&mq->complete_lock); @@ -2317,7 +2317,7 @@ static void mmc_blk_mq_req_done(struct mmc_request *mrq) struct mmc_host *host = mq->card->host; unsigned long flags; - if (!mmc_host_done_complete(host)) { + if (!mmc_host_can_done_complete(host)) { bool waiting; /* @@ -2430,7 +2430,7 @@ static int mmc_blk_mq_issue_rw_rq(struct mmc_queue *mq, mq->rw_wait = false; /* Release re-tuning here where there is no synchronization required */ - if (err || mmc_host_done_complete(host)) + if (err || mmc_host_can_done_complete(host)) mmc_retune_release(host); out_post_req: diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index c8515cb86192..00ca88389ef9 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -44,7 +44,7 @@ static inline int mmc_host_can_cmd23(struct mmc_host *host) return host->caps & MMC_CAP_CMD23; } -static inline bool mmc_host_done_complete(struct mmc_host *host) +static inline bool mmc_host_can_done_complete(struct mmc_host *host) { return host->caps & MMC_CAP_DONE_COMPLETE; } -- 2.51.0 From f55f7da62166dcdd34a0661b94a43464ff7c626a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 1 May 2025 08:33:28 +0200 Subject: [PATCH 13/16] mmc: rename mmc_host_uhs() to mmc_host_can_uhs() It is not obvious that this functions checks capabilities. Rename it to include '_can' like other capability helpers. Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20250501063325.7262-9-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/host.h | 2 +- drivers/mmc/core/sd.c | 8 ++++---- drivers/mmc/core/sdio.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index 00ca88389ef9..c112191cad6a 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -54,7 +54,7 @@ static inline int mmc_boot_partition_access(struct mmc_host *host) return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC); } -static inline int mmc_host_uhs(struct mmc_host *host) +static inline int mmc_host_can_uhs(struct mmc_host *host) { return host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 08ab076fe2f9..ec02067f03c5 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -455,7 +455,7 @@ static void sd_update_bus_speed_mode(struct mmc_card *card) * If the host doesn't support any of the UHS-I modes, fallback on * default speed. */ - if (!mmc_host_uhs(card->host)) { + if (!mmc_host_can_uhs(card->host)) { card->sd_bus_speed = 0; return; } @@ -867,7 +867,7 @@ try_again: * to switch to 1.8V signaling level. If the card has failed * repeatedly to switch however, skip this. */ - if (retries && mmc_host_uhs(host)) + if (retries && mmc_host_can_uhs(host)) ocr |= SD_OCR_S18R; /* @@ -1509,7 +1509,7 @@ retry: * signaling. Detect that situation and try to initialize a UHS-I (1.8V) * transfer mode. */ - if (!v18_fixup_failed && !mmc_host_is_spi(host) && mmc_host_uhs(host) && + if (!v18_fixup_failed && !mmc_host_is_spi(host) && mmc_host_can_uhs(host) && mmc_sd_card_using_v18(card) && host->ios.signal_voltage != MMC_SIGNAL_VOLTAGE_180) { if (mmc_host_set_uhs_voltage(host) || @@ -1524,7 +1524,7 @@ retry: } /* Initialization sequence for UHS-I cards */ - if (rocr & SD_ROCR_S18A && mmc_host_uhs(host)) { + if (rocr & SD_ROCR_S18A && mmc_host_can_uhs(host)) { err = mmc_sd_init_uhs_card(card); if (err) goto free_card; diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 4b19b8a16b09..0f753367aec1 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -198,7 +198,7 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr) if (ret) goto out; - if (mmc_host_uhs(card->host)) { + if (mmc_host_can_uhs(card->host)) { if (data & SDIO_UHS_DDR50) card->sw_caps.sd3_bus_mode |= SD_MODE_UHS_DDR50 | SD_MODE_UHS_SDR50 @@ -527,7 +527,7 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) * If the host doesn't support any of the UHS-I modes, fallback on * default speed. */ - if (!mmc_host_uhs(card->host)) + if (!mmc_host_can_uhs(card->host)) return 0; bus_speed = SDIO_SPEED_SDR12; @@ -669,7 +669,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, WARN_ON(!host->claimed); /* to query card if 1.8V signalling is supported */ - if (mmc_host_uhs(host)) + if (mmc_host_can_uhs(host)) ocr |= R4_18V_PRESENT; try_again: -- 2.51.0 From 9e654f2bf309f7ddb9ff2fb3f9b0297ae194d2cb Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 1 May 2025 08:33:29 +0200 Subject: [PATCH 14/16] mmc: rename mmc_boot_partition_access() to mmc_host_can_access_boot() It is not obvious that this functions checks capabilities. Rename it to include '_can' like other capability helpers and reword it slightly. Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20250501063325.7262-10-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/host.h | 2 +- drivers/mmc/core/mmc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index c112191cad6a..5941d68ff989 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -49,7 +49,7 @@ static inline bool mmc_host_can_done_complete(struct mmc_host *host) return host->caps & MMC_CAP_DONE_COMPLETE; } -static inline int mmc_boot_partition_access(struct mmc_host *host) +static inline int mmc_host_can_access_boot(struct mmc_host *host) { return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC); } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index c2b92b508438..5be9b42d5057 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -459,7 +459,7 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) * There are two boot regions of equal size, defined in * multiples of 128K. */ - if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_boot_partition_access(card->host)) { + if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_host_can_access_boot(card->host)) { for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) { part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; mmc_part_add(card, part_size, -- 2.51.0 From e760eab4069cd8b93e82651086324480efa3ee03 Mon Sep 17 00:00:00 2001 From: Charan Pedumuru Date: Wed, 7 May 2025 06:29:36 +0000 Subject: [PATCH 15/16] dt-binding: mmc: microchip,sdhci-pic32: convert text based binding to json schema Update text binding to YAML. Changes during conversion: Add appropriate include statements for interrupts and clock-names to resolve errors identified by `dt_binding_check` and `dtbs_check`. Signed-off-by: Charan Pedumuru Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20250507-mchp-sdhci-v1-2-ed29de05295a@gmail.com Signed-off-by: Ulf Hansson --- .../bindings/mmc/microchip,sdhci-pic32.txt | 29 -------- .../bindings/mmc/microchip,sdhci-pic32.yaml | 66 +++++++++++++++++++ 2 files changed, 66 insertions(+), 29 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt create mode 100644 Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.yaml diff --git a/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt deleted file mode 100644 index f064528effed..000000000000 --- a/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt +++ /dev/null @@ -1,29 +0,0 @@ -* Microchip PIC32 SDHCI Controller - -This file documents differences between the core properties in mmc.txt -and the properties used by the sdhci-pic32 driver. - -Required properties: -- compatible: Should be "microchip,pic32mzda-sdhci" -- interrupts: Should contain interrupt -- clock-names: Should be "base_clk", "sys_clk". - See: Documentation/devicetree/bindings/resource-names.txt -- clocks: Phandle to the clock. - See: Documentation/devicetree/bindings/clock/clock-bindings.txt -- pinctrl-names: A pinctrl state names "default" must be defined. -- pinctrl-0: Phandle referencing pin configuration of the SDHCI controller. - See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt - -Example: - - sdhci@1f8ec000 { - compatible = "microchip,pic32mzda-sdhci"; - reg = <0x1f8ec000 0x100>; - interrupts = <191 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&rootclk REF4CLK>, <&rootclk PB5CLK>; - clock-names = "base_clk", "sys_clk"; - bus-width = <4>; - cap-sd-highspeed; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdhc1>; - }; diff --git a/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.yaml b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.yaml new file mode 100644 index 000000000000..ca0ca7df9ee9 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mmc/microchip,sdhci-pic32.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip PIC32 SDHI Controller + +description: + The Microchip PIC32 family of microcontrollers (MCUs) includes models with + Secure Digital Host Controller Interface (SDHCI) controllers, allowing them + to interface with Secure Digital (SD) cards. This interface is used for reading, + writing, and managing data on SD cards, enabling storage and data transfer + capabilities in embedded systems. + +allOf: + - $ref: mmc-controller.yaml + +maintainers: + - Ulf Hansson + +properties: + compatible: + const: microchip,pic32mzda-sdhci + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: base_clk + - const: sys_clk + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - pinctrl-names + - pinctrl-0 + +unevaluatedProperties: false + +examples: + - | + #include + #include + mmc@1f8ec000 { + compatible = "microchip,pic32mzda-sdhci"; + reg = <0x1f8ec000 0x100>; + interrupts = <191 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rootclk REF4CLK>, <&rootclk PB5CLK>; + clock-names = "base_clk", "sys_clk"; + bus-width = <4>; + cap-sd-highspeed; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdhc1>; + }; +... -- 2.51.0 From f0534aace311f4fa1d25fc44a86edcbb24e3434e Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Wed, 7 May 2025 15:45:38 +0200 Subject: [PATCH 16/16] mmc: core: Scan the eMMC boot areas for partition table It appears that some vendors provision the boot areas with valid part tables (GPT) in order to have identifiable partitions for device and firmware specific data, such has the qualcomm CDT (Qualcomm Config Data Table). Additionally, these boot areas can be utilized to host device-specific IDs, calibration data, and other critical information. Signed-off-by: Loic Poulain Link: https://lore.kernel.org/r/20250507134538.575912-1-loic.poulain@oss.qualcomm.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 585c2b274d98..9cc47bf94804 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -2655,7 +2655,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, md->disk->private_data = md; md->parent = parent; set_disk_ro(md->disk, md->read_only || default_ro); - if (area_type & (MMC_BLK_DATA_AREA_RPMB | MMC_BLK_DATA_AREA_BOOT)) + if (area_type & MMC_BLK_DATA_AREA_RPMB) md->disk->flags |= GENHD_FL_NO_PART; /* -- 2.51.0