Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mmc-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC updates from Ulf Hansson:
" MMC core:
- Enable host caps to be modified via debugfs to test speed-modes
- Improve random I/O writes for 4k buffers for hsq enabled hosts

MMC host:
- atmel-mci/sdhci-of-at91: Aubin Constans takes over as maintainer
- dw_mmc-starfive: Re-work tuning support
- meson-gx: Fix bogus IRQ when using CMD_CFG_ERROR
- mmci: Use peripheral flow control for the STM32 variant
- renesas,sdhi: Add support for the RZ/G3S variant
- sdhci-esdhc-imx: Optimize the manual tuning logic
- sdhci-msm: Add support for the SM8650 variant
- sdhci-npcm: Add driver to support the Nuvoton NPCM BMC variant
- sdhci-pci-gli: Add workaround to allow GL9750 to enter ASPM L1.2"

* tag 'mmc-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (25 commits)
dt-bindings: mmc: sdhci-msm: document the SM8650 SDHCI Controller
mmc: meson-gx: Remove setting of CMD_CFG_ERROR
MAINTAINERS: mmc: take over as maintainer of MCI & SDHCI MICROCHIP DRIVERS
mmc: jz4740: Use device_get_match_data()
mmc: sdhci-npcm: Add NPCM SDHCI driver
dt-bindings: mmc: npcm,sdhci: Document NPCM SDHCI controller
mmc: sdhci-pltfm: Make driver OF independent
mmc: sdhci-pltfm: Drop unnecessary error messages in sdhci_pltfm_init()
mmc: sdhci-pci: Switch to use acpi_evaluate_dsm_typed()
mmc: debugfs: Allow host caps to be modified
mmc: core: Always reselect card type
mmc: mmci: use peripheral flow control for STM32
mmc: vub300: replace deprecated strncpy with strscpy
memstick: jmb38x_ms: Annotate struct jmb38x_ms with __counted_by
mmc: starfive: Change tuning implementation
dt-bindings: mmc: starfive: Remove properties from required
mmc: hsq: Improve random I/O write performance for 4k buffers
mmc: core: Allow dynamical updates of the number of requests for hsq
mmc: sdhci-pci-gli: A workaround to allow GL9750 to enter ASPM L1.2
dt-bindings: mmc: renesas,sdhi: Document RZ/G3S support
...

+387 -187
+45
Documentation/devicetree/bindings/mmc/npcm,sdhci.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mmc/npcm,sdhci.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: NPCM SDHCI Controller 8 + 9 + maintainers: 10 + - Tomer Maimon <tmaimon77@gmail.com> 11 + 12 + allOf: 13 + - $ref: mmc-controller.yaml# 14 + 15 + properties: 16 + compatible: 17 + enum: 18 + - nuvoton,npcm750-sdhci 19 + - nuvoton,npcm845-sdhci 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + interrupts: 25 + maxItems: 1 26 + 27 + clocks: 28 + maxItems: 1 29 + 30 + required: 31 + - compatible 32 + - reg 33 + - interrupts 34 + - clocks 35 + 36 + unevaluatedProperties: false 37 + 38 + examples: 39 + - | 40 + mmc@f0840000 { 41 + compatible = "nuvoton,npcm750-sdhci"; 42 + reg = <0xf0840000 0x200>; 43 + interrupts = <0 27 4>; 44 + clocks = <&clk 4>; 45 + };
+2
Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
··· 59 59 - renesas,sdhi-r9a07g043 # RZ/G2UL 60 60 - renesas,sdhi-r9a07g044 # RZ/G2{L,LC} 61 61 - renesas,sdhi-r9a07g054 # RZ/V2L 62 + - renesas,sdhi-r9a08g045 # RZ/G3S 62 63 - renesas,sdhi-r9a09g011 # RZ/V2M 63 64 - const: renesas,rcar-gen3-sdhi # R-Car Gen3 or RZ/G2 64 65 - items: ··· 123 122 - renesas,sdhi-r9a07g043 124 123 - renesas,sdhi-r9a07g044 125 124 - renesas,sdhi-r9a07g054 125 + - renesas,sdhi-r9a08g045 126 126 - renesas,sdhi-r9a09g011 127 127 then: 128 128 properties:
+5 -4
Documentation/devicetree/bindings/mmc/sdhci-msm.yaml
··· 58 58 - qcom,sm8350-sdhci 59 59 - qcom,sm8450-sdhci 60 60 - qcom,sm8550-sdhci 61 + - qcom,sm8650-sdhci 61 62 - const: qcom,sdhci-msm-v5 # for sdcc version 5.0 62 63 63 64 reg: ··· 86 85 - const: iface 87 86 - const: core 88 87 - const: xo 89 - - const: ice 90 - - const: bus 91 - - const: cal 92 - - const: sleep 88 + - enum: [ice, bus, cal, sleep] 89 + - enum: [ice, bus, cal, sleep] 90 + - enum: [ice, bus, cal, sleep] 91 + - enum: [ice, bus, cal, sleep] 93 92 94 93 dma-coherent: true 95 94
-2
Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
··· 55 55 - clocks 56 56 - clock-names 57 57 - interrupts 58 - - starfive,sysreg 59 58 60 59 unevaluatedProperties: false 61 60 ··· 72 73 fifo-depth = <32>; 73 74 fifo-watermark-aligned; 74 75 data-addr = <0>; 75 - starfive,sysreg = <&sys_syscon 0x14 0x1a 0x7c000000>; 76 76 };
+3 -2
MAINTAINERS
··· 14110 14110 F: drivers/iio/adc/mcp3911.c 14111 14111 14112 14112 MICROCHIP MMC/SD/SDIO MCI DRIVER 14113 - M: Ludovic Desroches <ludovic.desroches@microchip.com> 14113 + M: Aubin Constans <aubin.constans@microchip.com> 14114 14114 S: Maintained 14115 14115 F: drivers/mmc/host/atmel-mci.c 14116 14116 ··· 19335 19335 F: drivers/mmc/host/sdhci* 19336 19336 19337 19337 SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) MICROCHIP DRIVER 19338 - M: Eugen Hristev <eugen.hristev@microchip.com> 19338 + M: Aubin Constans <aubin.constans@microchip.com> 19339 + R: Eugen Hristev <eugen.hristev@collabora.com> 19339 19340 L: linux-mmc@vger.kernel.org 19340 19341 S: Supported 19341 19342 F: drivers/mmc/host/sdhci-of-at91.c
+1 -1
drivers/memstick/host/jmb38x_ms.c
··· 66 66 struct jmb38x_ms { 67 67 struct pci_dev *pdev; 68 68 int host_cnt; 69 - struct memstick_host *hosts[]; 69 + struct memstick_host *hosts[] __counted_by(host_cnt); 70 70 }; 71 71 72 72 #define BLOCK_COUNT_MASK 0xffff0000
+49 -2
drivers/mmc/core/debugfs.c
··· 12 12 #include <linux/slab.h> 13 13 #include <linux/stat.h> 14 14 #include <linux/fault-inject.h> 15 + #include <linux/time.h> 15 16 16 17 #include <linux/mmc/card.h> 17 18 #include <linux/mmc/host.h> 19 + #include <linux/mmc/mmc.h> 20 + #include <linux/mmc/sd.h> 18 21 19 22 #include "core.h" 20 23 #include "card.h" ··· 301 298 .release = single_release, 302 299 }; 303 300 301 + static int mmc_caps_get(void *data, u64 *val) 302 + { 303 + *val = *(u32 *)data; 304 + return 0; 305 + } 306 + 307 + static int mmc_caps_set(void *data, u64 val) 308 + { 309 + u32 *caps = data; 310 + u32 diff = *caps ^ val; 311 + u32 allowed = MMC_CAP_AGGRESSIVE_PM | 312 + MMC_CAP_SD_HIGHSPEED | 313 + MMC_CAP_MMC_HIGHSPEED | 314 + MMC_CAP_UHS | 315 + MMC_CAP_DDR; 316 + 317 + if (diff & ~allowed) 318 + return -EINVAL; 319 + 320 + *caps = val; 321 + 322 + return 0; 323 + } 324 + 325 + static int mmc_caps2_set(void *data, u64 val) 326 + { 327 + u32 allowed = MMC_CAP2_HSX00_1_8V | MMC_CAP2_HSX00_1_2V; 328 + u32 *caps = data; 329 + u32 diff = *caps ^ val; 330 + 331 + if (diff & ~allowed) 332 + return -EINVAL; 333 + 334 + *caps = val; 335 + 336 + return 0; 337 + } 338 + 339 + DEFINE_DEBUGFS_ATTRIBUTE(mmc_caps_fops, mmc_caps_get, mmc_caps_set, 340 + "0x%08llx\n"); 341 + DEFINE_DEBUGFS_ATTRIBUTE(mmc_caps2_fops, mmc_caps_get, mmc_caps2_set, 342 + "0x%08llx\n"); 343 + 304 344 void mmc_add_host_debugfs(struct mmc_host *host) 305 345 { 306 346 struct dentry *root; ··· 352 306 host->debugfs_root = root; 353 307 354 308 debugfs_create_file("ios", S_IRUSR, root, host, &mmc_ios_fops); 355 - debugfs_create_x32("caps", S_IRUSR, root, &host->caps); 356 - debugfs_create_x32("caps2", S_IRUSR, root, &host->caps2); 309 + debugfs_create_file("caps", 0600, root, &host->caps, &mmc_caps_fops); 310 + debugfs_create_file("caps2", 0600, root, &host->caps2, 311 + &mmc_caps2_fops); 357 312 debugfs_create_file_unsafe("clock", S_IRUSR | S_IWUSR, root, host, 358 313 &mmc_clock_fops); 359 314
+6 -1
drivers/mmc/core/mmc.c
··· 419 419 420 420 card->ext_csd.strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT]; 421 421 card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; 422 - mmc_select_card_type(card); 423 422 424 423 card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT]; 425 424 card->ext_csd.raw_erase_timeout_mult = ··· 1730 1731 /* Erase size depends on CSD and Extended CSD */ 1731 1732 mmc_set_erase_size(card); 1732 1733 } 1734 + 1735 + /* 1736 + * Reselect the card type since host caps could have been changed when 1737 + * debugging even if the card is not new. 1738 + */ 1739 + mmc_select_card_type(card); 1733 1740 1734 1741 /* Enable ERASE_GRP_DEF. This bit is lost after a reset or power off. */ 1735 1742 if (card->ext_csd.rev >= 3) {
+1 -5
drivers/mmc/core/queue.c
··· 260 260 } 261 261 break; 262 262 case MMC_ISSUE_ASYNC: 263 - /* 264 - * For MMC host software queue, we only allow 2 requests in 265 - * flight to avoid a long latency. 266 - */ 267 - if (host->hsq_enabled && mq->in_flight[issue_type] > 2) { 263 + if (host->hsq_enabled && mq->in_flight[issue_type] > host->hsq_depth) { 268 264 spin_unlock_irq(&mq->lock); 269 265 return BLK_STS_RESOURCE; 270 266 }
+10 -2
drivers/mmc/host/Kconfig
··· 429 429 430 430 If unsure, say N. 431 431 432 + config MMC_SDHCI_NPCM 433 + tristate "Secure Digital Host Controller Interface support for NPCM" 434 + depends on ARCH_NPCM || COMPILE_TEST 435 + depends on MMC_SDHCI_PLTFM 436 + help 437 + This provides support for the SD/eMMC controller found in 438 + NPCM BMC family SoCs. 439 + 432 440 config MMC_MESON_GX 433 441 tristate "Amlogic S905/GX*/AXG SD/MMC Host Controller support" 434 442 depends on ARCH_MESON|| COMPILE_TEST ··· 685 677 686 678 config MMC_SDHI_INTERNAL_DMAC 687 679 tristate "DMA for SDHI SD/SDIO controllers using on-chip bus mastering" 688 - depends on ARM64 || ARCH_R7S9210 || ARCH_R8A77470 || COMPILE_TEST 680 + depends on ARCH_RENESAS || COMPILE_TEST 689 681 depends on MMC_SDHI 690 - default MMC_SDHI if (ARM64 || ARCH_R7S9210 || ARCH_R8A77470) 682 + default MMC_SDHI if ARCH_RENESAS 691 683 help 692 684 This provides DMA support for SDHI SD/SDIO controllers 693 685 using on-chip bus mastering. This supports the controllers
+1
drivers/mmc/host/Makefile
··· 89 89 obj-$(CONFIG_MMC_SDHCI_OF_SPARX5) += sdhci-of-sparx5.o 90 90 obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o 91 91 obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o 92 + obj-$(CONFIG_MMC_SDHCI_NPCM) += sdhci-npcm.o 92 93 obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o 93 94 obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o 94 95 obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32) += sdhci-pic32.o
+7 -2
drivers/mmc/host/atmel-mci.c
··· 227 227 /** 228 228 * struct mci_platform_data - board-specific MMC/SDcard configuration 229 229 * @dma_slave: DMA slave interface to use in data transfers. 230 + * @dma_filter: Filtering function to filter the DMA channel 230 231 * @slot: Per-slot configuration data. 231 232 */ 232 233 struct mci_platform_data { ··· 675 674 "cd", GPIOD_IN, "cd-gpios"); 676 675 err = PTR_ERR_OR_ZERO(pdata->slot[slot_id].detect_pin); 677 676 if (err) { 678 - if (err != -ENOENT) 677 + if (err != -ENOENT) { 678 + of_node_put(cnp); 679 679 return ERR_PTR(err); 680 + } 680 681 pdata->slot[slot_id].detect_pin = NULL; 681 682 } 682 683 ··· 690 687 "wp", GPIOD_IN, "wp-gpios"); 691 688 err = PTR_ERR_OR_ZERO(pdata->slot[slot_id].wp_pin); 692 689 if (err) { 693 - if (err != -ENOENT) 690 + if (err != -ENOENT) { 691 + of_node_put(cnp); 694 692 return ERR_PTR(err); 693 + } 695 694 pdata->slot[slot_id].wp_pin = NULL; 696 695 } 697 696 }
+43 -100
drivers/mmc/host/dw_mmc-starfive.c
··· 5 5 * Copyright (c) 2022 StarFive Technology Co., Ltd. 6 6 */ 7 7 8 + #include <linux/bitfield.h> 8 9 #include <linux/clk.h> 9 10 #include <linux/delay.h> 10 11 #include <linux/mfd/syscon.h> ··· 21 20 #define ALL_INT_CLR 0x1ffff 22 21 #define MAX_DELAY_CHAIN 32 23 22 24 - struct starfive_priv { 25 - struct device *dev; 26 - struct regmap *reg_syscon; 27 - u32 syscon_offset; 28 - u32 syscon_shift; 29 - u32 syscon_mask; 30 - }; 23 + #define STARFIVE_SMPL_PHASE GENMASK(20, 16) 31 24 32 25 static void dw_mci_starfive_set_ios(struct dw_mci *host, struct mmc_ios *ios) 33 26 { ··· 39 44 } 40 45 } 41 46 47 + static void dw_mci_starfive_set_sample_phase(struct dw_mci *host, u32 smpl_phase) 48 + { 49 + /* change driver phase and sample phase */ 50 + u32 reg_value = mci_readl(host, UHS_REG_EXT); 51 + 52 + /* In UHS_REG_EXT, only 5 bits valid in DRV_PHASE and SMPL_PHASE */ 53 + reg_value &= ~STARFIVE_SMPL_PHASE; 54 + reg_value |= FIELD_PREP(STARFIVE_SMPL_PHASE, smpl_phase); 55 + mci_writel(host, UHS_REG_EXT, reg_value); 56 + 57 + /* We should delay 1ms wait for timing setting finished. */ 58 + mdelay(1); 59 + } 60 + 42 61 static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot, 43 62 u32 opcode) 44 63 { 45 64 static const int grade = MAX_DELAY_CHAIN; 46 65 struct dw_mci *host = slot->host; 47 - struct starfive_priv *priv = host->priv; 48 - int rise_point = -1, fall_point = -1; 49 - int err, prev_err = 0; 50 - int i; 51 - bool found = 0; 52 - u32 regval; 53 - 54 - /* 55 - * Use grade as the max delay chain, and use the rise_point and 56 - * fall_point to ensure the best sampling point of a data input 57 - * signals. 58 - */ 59 - for (i = 0; i < grade; i++) { 60 - regval = i << priv->syscon_shift; 61 - err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset, 62 - priv->syscon_mask, regval); 63 - if (err) 64 - return err; 65 - mci_writel(host, RINTSTS, ALL_INT_CLR); 66 - 67 - err = mmc_send_tuning(slot->mmc, opcode, NULL); 68 - if (!err) 69 - found = 1; 70 - 71 - if (i > 0) { 72 - if (err && !prev_err) 73 - fall_point = i - 1; 74 - if (!err && prev_err) 75 - rise_point = i; 76 - } 77 - 78 - if (rise_point != -1 && fall_point != -1) 79 - goto tuning_out; 80 - 81 - prev_err = err; 82 - err = 0; 83 - } 84 - 85 - tuning_out: 86 - if (found) { 87 - if (rise_point == -1) 88 - rise_point = 0; 89 - if (fall_point == -1) 90 - fall_point = grade - 1; 91 - if (fall_point < rise_point) { 92 - if ((rise_point + fall_point) > 93 - (grade - 1)) 94 - i = fall_point / 2; 95 - else 96 - i = (rise_point + grade - 1) / 2; 97 - } else { 98 - i = (rise_point + fall_point) / 2; 99 - } 100 - 101 - regval = i << priv->syscon_shift; 102 - err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset, 103 - priv->syscon_mask, regval); 104 - if (err) 105 - return err; 106 - mci_writel(host, RINTSTS, ALL_INT_CLR); 107 - 108 - dev_info(host->dev, "Found valid delay chain! use it [delay=%d]\n", i); 109 - } else { 110 - dev_err(host->dev, "No valid delay chain! use default\n"); 111 - err = -EINVAL; 112 - } 113 - 114 - mci_writel(host, RINTSTS, ALL_INT_CLR); 115 - return err; 116 - } 117 - 118 - static int dw_mci_starfive_parse_dt(struct dw_mci *host) 119 - { 120 - struct of_phandle_args args; 121 - struct starfive_priv *priv; 66 + int smpl_phase, smpl_raise = -1, smpl_fall = -1; 122 67 int ret; 123 68 124 - priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); 125 - if (!priv) 126 - return -ENOMEM; 69 + for (smpl_phase = 0; smpl_phase < grade; smpl_phase++) { 70 + dw_mci_starfive_set_sample_phase(host, smpl_phase); 71 + mci_writel(host, RINTSTS, ALL_INT_CLR); 127 72 128 - ret = of_parse_phandle_with_fixed_args(host->dev->of_node, 129 - "starfive,sysreg", 3, 0, &args); 130 - if (ret) { 131 - dev_err(host->dev, "Failed to parse starfive,sysreg\n"); 132 - return -EINVAL; 73 + ret = mmc_send_tuning(slot->mmc, opcode, NULL); 74 + 75 + if (!ret && smpl_raise < 0) { 76 + smpl_raise = smpl_phase; 77 + } else if (ret && smpl_raise >= 0) { 78 + smpl_fall = smpl_phase - 1; 79 + break; 80 + } 133 81 } 134 82 135 - priv->reg_syscon = syscon_node_to_regmap(args.np); 136 - of_node_put(args.np); 137 - if (IS_ERR(priv->reg_syscon)) 138 - return PTR_ERR(priv->reg_syscon); 83 + if (smpl_phase >= grade) 84 + smpl_fall = grade - 1; 139 85 140 - priv->syscon_offset = args.args[0]; 141 - priv->syscon_shift = args.args[1]; 142 - priv->syscon_mask = args.args[2]; 86 + if (smpl_raise < 0) { 87 + smpl_phase = 0; 88 + dev_err(host->dev, "No valid delay chain! use default\n"); 89 + ret = -EINVAL; 90 + goto out; 91 + } 143 92 144 - host->priv = priv; 93 + smpl_phase = (smpl_raise + smpl_fall) / 2; 94 + dev_dbg(host->dev, "Found valid delay chain! use it [delay=%d]\n", smpl_phase); 95 + ret = 0; 145 96 146 - return 0; 97 + out: 98 + dw_mci_starfive_set_sample_phase(host, smpl_phase); 99 + mci_writel(host, RINTSTS, ALL_INT_CLR); 100 + return ret; 147 101 } 148 102 149 103 static const struct dw_mci_drv_data starfive_data = { 150 104 .common_caps = MMC_CAP_CMD23, 151 105 .set_ios = dw_mci_starfive_set_ios, 152 - .parse_dt = dw_mci_starfive_parse_dt, 153 106 .execute_tuning = dw_mci_starfive_execute_tuning, 154 107 }; 155 108
+5 -10
drivers/mmc/host/jz4740_mmc.c
··· 18 18 #include <linux/mmc/host.h> 19 19 #include <linux/mmc/slot-gpio.h> 20 20 #include <linux/module.h> 21 - #include <linux/of_device.h> 21 + #include <linux/of.h> 22 22 #include <linux/pinctrl/consumer.h> 23 23 #include <linux/platform_device.h> 24 + #include <linux/property.h> 24 25 #include <linux/regulator/consumer.h> 25 26 #include <linux/scatterlist.h> 26 27 ··· 1041 1040 int ret; 1042 1041 struct mmc_host *mmc; 1043 1042 struct jz4740_mmc_host *host; 1044 - const struct of_device_id *match; 1045 1043 1046 1044 mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev); 1047 1045 if (!mmc) { ··· 1050 1050 1051 1051 host = mmc_priv(mmc); 1052 1052 1053 - match = of_match_device(jz4740_mmc_of_match, &pdev->dev); 1054 - if (match) { 1055 - host->version = (enum jz4740_mmc_version)match->data; 1056 - } else { 1057 - /* JZ4740 should be the only one using legacy probe */ 1058 - host->version = JZ_MMC_JZ4740; 1059 - } 1053 + /* Default if no match is JZ4740 */ 1054 + host->version = (enum jz4740_mmc_version)device_get_match_data(&pdev->dev); 1060 1055 1061 1056 ret = mmc_of_parse(mmc); 1062 1057 if (ret) { ··· 1195 1200 .driver = { 1196 1201 .name = "jz4740-mmc", 1197 1202 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 1198 - .of_match_table = of_match_ptr(jz4740_mmc_of_match), 1203 + .of_match_table = jz4740_mmc_of_match, 1199 1204 .pm = pm_sleep_ptr(&jz4740_mmc_pm_ops), 1200 1205 }, 1201 1206 };
-1
drivers/mmc/host/meson-gx-mmc.c
··· 801 801 802 802 cmd_cfg |= FIELD_PREP(CMD_CFG_CMD_INDEX_MASK, cmd->opcode); 803 803 cmd_cfg |= CMD_CFG_OWNER; /* owned by CPU */ 804 - cmd_cfg |= CMD_CFG_ERROR; /* stop in case of error */ 805 804 806 805 meson_mmc_set_response_bits(cmd, &cmd_cfg); 807 806
+22
drivers/mmc/host/mmc_hsq.c
··· 21 21 mmc->ops->request(mmc, hsq->mrq); 22 22 } 23 23 24 + static void mmc_hsq_modify_threshold(struct mmc_hsq *hsq) 25 + { 26 + struct mmc_host *mmc = hsq->mmc; 27 + struct mmc_request *mrq; 28 + unsigned int tag, need_change = 0; 29 + 30 + mmc->hsq_depth = HSQ_NORMAL_DEPTH; 31 + for (tag = 0; tag < HSQ_NUM_SLOTS; tag++) { 32 + mrq = hsq->slot[tag].mrq; 33 + if (mrq && mrq->data && 34 + (mrq->data->blksz * mrq->data->blocks == 4096) && 35 + (mrq->data->flags & MMC_DATA_WRITE) && 36 + (++need_change == 2)) { 37 + mmc->hsq_depth = HSQ_PERFORMANCE_DEPTH; 38 + break; 39 + } 40 + } 41 + } 42 + 24 43 static void mmc_hsq_pump_requests(struct mmc_hsq *hsq) 25 44 { 26 45 struct mmc_host *mmc = hsq->mmc; ··· 60 41 spin_unlock_irqrestore(&hsq->lock, flags); 61 42 return; 62 43 } 44 + 45 + mmc_hsq_modify_threshold(hsq); 63 46 64 47 slot = &hsq->slot[hsq->next_tag]; 65 48 hsq->mrq = slot->mrq; ··· 358 337 hsq->mmc = mmc; 359 338 hsq->mmc->cqe_private = hsq; 360 339 mmc->cqe_ops = &mmc_hsq_ops; 340 + mmc->hsq_depth = HSQ_NORMAL_DEPTH; 361 341 362 342 for (i = 0; i < HSQ_NUM_SLOTS; i++) 363 343 hsq->tag_slot[i] = HSQ_INVALID_TAG;
+11
drivers/mmc/host/mmc_hsq.h
··· 5 5 #define HSQ_NUM_SLOTS 64 6 6 #define HSQ_INVALID_TAG HSQ_NUM_SLOTS 7 7 8 + /* 9 + * For MMC host software queue, we only allow 2 requests in 10 + * flight to avoid a long latency. 11 + */ 12 + #define HSQ_NORMAL_DEPTH 2 13 + /* 14 + * For 4k random writes, we allow hsq_depth to increase to 5 15 + * for better performance. 16 + */ 17 + #define HSQ_PERFORMANCE_DEPTH 5 18 + 8 19 struct hsq_slot { 9 20 struct mmc_request *mrq; 10 21 };
+2 -1
drivers/mmc/host/mmci.c
··· 249 249 .f_max = 48000000, 250 250 .pwrreg_clkgate = true, 251 251 .pwrreg_nopower = true, 252 + .dma_flow_controller = true, 252 253 .init = mmci_variant_init, 253 254 }; 254 255 ··· 1016 1015 .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 1017 1016 .src_maxburst = variant->fifohalfsize >> 2, /* # of words */ 1018 1017 .dst_maxburst = variant->fifohalfsize >> 2, /* # of words */ 1019 - .device_fc = false, 1018 + .device_fc = variant->dma_flow_controller, 1020 1019 }; 1021 1020 struct dma_chan *chan; 1022 1021 struct dma_device *device;
+2
drivers/mmc/host/mmci.h
··· 332 332 * @opendrain: bitmask identifying the OPENDRAIN bit inside MMCIPOWER register 333 333 * @dma_lli: true if variant has dma link list feature. 334 334 * @stm32_idmabsize_mask: stm32 sdmmc idma buffer size. 335 + * @dma_flow_controller: use peripheral as flow controller for DMA. 335 336 */ 336 337 struct variant_data { 337 338 unsigned int clkreg; ··· 379 378 u8 dma_lli:1; 380 379 u32 stm32_idmabsize_mask; 381 380 u32 stm32_idmabsize_align; 381 + bool dma_flow_controller; 382 382 void (*init)(struct mmci_host *host); 383 383 }; 384 384
+36 -16
drivers/mmc/host/sdhci-esdhc-imx.c
··· 1154 1154 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); 1155 1155 } 1156 1156 1157 + /* 1158 + * find the largest pass window, and use the average delay of this 1159 + * largest window to get the best timing. 1160 + */ 1157 1161 static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode) 1158 1162 { 1159 1163 int min, max, avg, ret; 1164 + int win_length, target_min, target_max, target_win_length; 1160 1165 1161 - /* find the mininum delay first which can pass tuning */ 1162 1166 min = ESDHC_TUNE_CTRL_MIN; 1163 - while (min < ESDHC_TUNE_CTRL_MAX) { 1164 - esdhc_prepare_tuning(host, min); 1165 - if (!mmc_send_tuning(host->mmc, opcode, NULL)) 1166 - break; 1167 - min += ESDHC_TUNE_CTRL_STEP; 1168 - } 1169 - 1170 - /* find the maxinum delay which can not pass tuning */ 1171 - max = min + ESDHC_TUNE_CTRL_STEP; 1167 + max = ESDHC_TUNE_CTRL_MIN; 1168 + target_win_length = 0; 1172 1169 while (max < ESDHC_TUNE_CTRL_MAX) { 1173 - esdhc_prepare_tuning(host, max); 1174 - if (mmc_send_tuning(host->mmc, opcode, NULL)) { 1175 - max -= ESDHC_TUNE_CTRL_STEP; 1176 - break; 1170 + /* find the mininum delay first which can pass tuning */ 1171 + while (min < ESDHC_TUNE_CTRL_MAX) { 1172 + esdhc_prepare_tuning(host, min); 1173 + if (!mmc_send_tuning(host->mmc, opcode, NULL)) 1174 + break; 1175 + min += ESDHC_TUNE_CTRL_STEP; 1177 1176 } 1178 - max += ESDHC_TUNE_CTRL_STEP; 1177 + 1178 + /* find the maxinum delay which can not pass tuning */ 1179 + max = min + ESDHC_TUNE_CTRL_STEP; 1180 + while (max < ESDHC_TUNE_CTRL_MAX) { 1181 + esdhc_prepare_tuning(host, max); 1182 + if (mmc_send_tuning(host->mmc, opcode, NULL)) { 1183 + max -= ESDHC_TUNE_CTRL_STEP; 1184 + break; 1185 + } 1186 + max += ESDHC_TUNE_CTRL_STEP; 1187 + } 1188 + 1189 + win_length = max - min + 1; 1190 + /* get the largest pass window */ 1191 + if (win_length > target_win_length) { 1192 + target_win_length = win_length; 1193 + target_min = min; 1194 + target_max = max; 1195 + } 1196 + 1197 + /* continue to find the next pass window */ 1198 + min = max + ESDHC_TUNE_CTRL_STEP; 1179 1199 } 1180 1200 1181 1201 /* use average delay to get the best timing */ 1182 - avg = (min + max) / 2; 1202 + avg = (target_min + target_max) / 2; 1183 1203 esdhc_prepare_tuning(host, avg); 1184 1204 ret = mmc_send_tuning(host->mmc, opcode, NULL); 1185 1205 esdhc_post_tuning(host);
+94
drivers/mmc/host/sdhci-npcm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * NPCM SDHC MMC host controller driver. 4 + * 5 + * Copyright (c) 2023 Nuvoton Technology corporation. 6 + */ 7 + 8 + #include <linux/clk.h> 9 + #include <linux/err.h> 10 + #include <linux/io.h> 11 + #include <linux/mmc/host.h> 12 + #include <linux/mmc/mmc.h> 13 + #include <linux/mod_devicetable.h> 14 + #include <linux/module.h> 15 + #include <linux/of.h> 16 + 17 + #include "sdhci-pltfm.h" 18 + 19 + static const struct sdhci_pltfm_data npcm7xx_sdhci_pdata = { 20 + .quirks = SDHCI_QUIRK_DELAY_AFTER_POWER, 21 + .quirks2 = SDHCI_QUIRK2_STOP_WITH_TC | 22 + SDHCI_QUIRK2_NO_1_8_V, 23 + }; 24 + 25 + static const struct sdhci_pltfm_data npcm8xx_sdhci_pdata = { 26 + .quirks = SDHCI_QUIRK_DELAY_AFTER_POWER, 27 + .quirks2 = SDHCI_QUIRK2_STOP_WITH_TC, 28 + }; 29 + 30 + static int npcm_sdhci_probe(struct platform_device *pdev) 31 + { 32 + const struct sdhci_pltfm_data *data; 33 + struct sdhci_pltfm_host *pltfm_host; 34 + struct device *dev = &pdev->dev; 35 + struct sdhci_host *host; 36 + u32 caps; 37 + int ret; 38 + 39 + data = of_device_get_match_data(dev); 40 + if (!data) 41 + return -EINVAL; 42 + 43 + host = sdhci_pltfm_init(pdev, data, 0); 44 + if (IS_ERR(host)) 45 + return PTR_ERR(host); 46 + 47 + pltfm_host = sdhci_priv(host); 48 + 49 + pltfm_host->clk = devm_clk_get_optional_enabled(dev, NULL); 50 + if (IS_ERR(pltfm_host->clk)) { 51 + ret = PTR_ERR(pltfm_host->clk); 52 + goto err_sdhci; 53 + } 54 + 55 + caps = sdhci_readl(host, SDHCI_CAPABILITIES); 56 + if (caps & SDHCI_CAN_DO_8BIT) 57 + host->mmc->caps |= MMC_CAP_8_BIT_DATA; 58 + 59 + ret = mmc_of_parse(host->mmc); 60 + if (ret) 61 + goto err_sdhci; 62 + 63 + ret = sdhci_add_host(host); 64 + if (ret) 65 + goto err_sdhci; 66 + 67 + return 0; 68 + 69 + err_sdhci: 70 + sdhci_pltfm_free(pdev); 71 + return ret; 72 + } 73 + 74 + static const struct of_device_id npcm_sdhci_of_match[] = { 75 + { .compatible = "nuvoton,npcm750-sdhci", .data = &npcm7xx_sdhci_pdata }, 76 + { .compatible = "nuvoton,npcm845-sdhci", .data = &npcm8xx_sdhci_pdata }, 77 + { } 78 + }; 79 + MODULE_DEVICE_TABLE(of, npcm_sdhci_of_match); 80 + 81 + static struct platform_driver npcm_sdhci_driver = { 82 + .driver = { 83 + .name = "npcm-sdhci", 84 + .of_match_table = npcm_sdhci_of_match, 85 + .pm = &sdhci_pltfm_pmops, 86 + }, 87 + .probe = npcm_sdhci_probe, 88 + .remove_new = sdhci_pltfm_remove, 89 + }; 90 + module_platform_driver(npcm_sdhci_driver); 91 + 92 + MODULE_DESCRIPTION("NPCM Secure Digital Host Controller Interface driver"); 93 + MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>"); 94 + MODULE_LICENSE("GPL");
+3 -2
drivers/mmc/host/sdhci-pci-core.c
··· 483 483 int err = 0; 484 484 size_t len; 485 485 486 - obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &intel_dsm_guid, 0, fn, NULL); 486 + obj = acpi_evaluate_dsm_typed(ACPI_HANDLE(dev), &intel_dsm_guid, 0, fn, NULL, 487 + ACPI_TYPE_BUFFER); 487 488 if (!obj) 488 489 return -EOPNOTSUPP; 489 490 490 - if (obj->type != ACPI_TYPE_BUFFER || obj->buffer.length < 1) { 491 + if (obj->buffer.length < 1) { 491 492 err = -EINVAL; 492 493 goto out; 493 494 }
+14
drivers/mmc/host/sdhci-pci-gli.c
··· 25 25 #define GLI_9750_WT_EN_ON 0x1 26 26 #define GLI_9750_WT_EN_OFF 0x0 27 27 28 + #define PCI_GLI_9750_PM_CTRL 0xFC 29 + #define PCI_GLI_9750_PM_STATE GENMASK(1, 0) 30 + 28 31 #define SDHCI_GLI_9750_CFG2 0x848 29 32 #define SDHCI_GLI_9750_CFG2_L1DLY GENMASK(28, 24) 30 33 #define GLI_9750_CFG2_L1DLY_VALUE 0x1F ··· 539 536 540 537 static void gl9750_hw_setting(struct sdhci_host *host) 541 538 { 539 + struct sdhci_pci_slot *slot = sdhci_priv(host); 540 + struct pci_dev *pdev; 542 541 u32 value; 542 + 543 + pdev = slot->chip->pdev; 543 544 544 545 gl9750_wt_on(host); 545 546 ··· 553 546 value |= FIELD_PREP(SDHCI_GLI_9750_CFG2_L1DLY, 554 547 GLI_9750_CFG2_L1DLY_VALUE); 555 548 sdhci_writel(host, value, SDHCI_GLI_9750_CFG2); 549 + 550 + /* toggle PM state to allow GL9750 to enter ASPM L1.2 */ 551 + pci_read_config_dword(pdev, PCI_GLI_9750_PM_CTRL, &value); 552 + value |= PCI_GLI_9750_PM_STATE; 553 + pci_write_config_dword(pdev, PCI_GLI_9750_PM_CTRL, value); 554 + value &= ~PCI_GLI_9750_PM_STATE; 555 + pci_write_config_dword(pdev, PCI_GLI_9750_PM_CTRL, value); 556 556 557 557 gl9750_wt_off(host); 558 558 }
+13 -25
drivers/mmc/host/sdhci-pltfm.c
··· 19 19 #include <linux/err.h> 20 20 #include <linux/module.h> 21 21 #include <linux/property.h> 22 - #include <linux/of.h> 23 22 #ifdef CONFIG_PPC 24 23 #include <asm/machdep.h> 25 24 #endif ··· 55 56 56 57 static void sdhci_get_compatibility(struct platform_device *pdev) 57 58 { 59 + struct device *dev = &pdev->dev; 58 60 struct sdhci_host *host = platform_get_drvdata(pdev); 59 - struct device_node *np = pdev->dev.of_node; 60 61 61 - if (!np) 62 - return; 63 - 64 - if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc")) 62 + if (device_is_compatible(dev, "fsl,p2020-rev1-esdhc")) 65 63 host->quirks |= SDHCI_QUIRK_BROKEN_DMA; 66 64 67 - if (of_device_is_compatible(np, "fsl,p2020-esdhc") || 68 - of_device_is_compatible(np, "fsl,p1010-esdhc") || 69 - of_device_is_compatible(np, "fsl,t4240-esdhc") || 70 - of_device_is_compatible(np, "fsl,mpc8536-esdhc")) 65 + if (device_is_compatible(dev, "fsl,p2020-esdhc") || 66 + device_is_compatible(dev, "fsl,p1010-esdhc") || 67 + device_is_compatible(dev, "fsl,t4240-esdhc") || 68 + device_is_compatible(dev, "fsl,mpc8536-esdhc")) 71 69 host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; 72 70 } 73 71 ··· 111 115 { 112 116 struct sdhci_host *host; 113 117 void __iomem *ioaddr; 114 - int irq, ret; 118 + int irq; 115 119 116 120 ioaddr = devm_platform_ioremap_resource(pdev, 0); 117 - if (IS_ERR(ioaddr)) { 118 - ret = PTR_ERR(ioaddr); 119 - goto err; 120 - } 121 + if (IS_ERR(ioaddr)) 122 + return ERR_CAST(ioaddr); 121 123 122 124 irq = platform_get_irq(pdev, 0); 123 - if (irq < 0) { 124 - ret = irq; 125 - goto err; 126 - } 125 + if (irq < 0) 126 + return ERR_PTR(irq); 127 127 128 128 host = sdhci_alloc_host(&pdev->dev, 129 129 sizeof(struct sdhci_pltfm_host) + priv_size); 130 - 131 130 if (IS_ERR(host)) { 132 - ret = PTR_ERR(host); 133 - goto err; 131 + dev_err(&pdev->dev, "%s failed %pe\n", __func__, host); 132 + return ERR_CAST(host); 134 133 } 135 134 136 135 host->ioaddr = ioaddr; ··· 143 152 platform_set_drvdata(pdev, host); 144 153 145 154 return host; 146 - err: 147 - dev_err(&pdev->dev, "%s failed %d\n", __func__, ret); 148 - return ERR_PTR(ret); 149 155 } 150 156 EXPORT_SYMBOL_GPL(sdhci_pltfm_init); 151 157
+11 -11
drivers/mmc/host/vub300.c
··· 512 512 vub300->card_present = 1; 513 513 vub300->bus_width = 0; 514 514 if (disable_offload_processing) 515 - strncpy(vub300->vub_name, "EMPTY Processing Disabled", 515 + strscpy(vub300->vub_name, "EMPTY Processing Disabled", 516 516 sizeof(vub300->vub_name)); 517 517 else 518 518 vub300->vub_name[0] = 0; ··· 1216 1216 dev_err(&vub300->udev->dev, 1217 1217 "corrupt offload pseudocode in firmware %s\n", 1218 1218 vub300->vub_name); 1219 - strncpy(vub300->vub_name, "corrupt offload pseudocode", 1219 + strscpy(vub300->vub_name, "corrupt offload pseudocode", 1220 1220 sizeof(vub300->vub_name)); 1221 1221 return; 1222 1222 } ··· 1250 1250 "not enough memory for xfer buffer to send" 1251 1251 " INTERRUPT_PSEUDOCODE for %s %s\n", fw->data, 1252 1252 vub300->vub_name); 1253 - strncpy(vub300->vub_name, 1253 + strscpy(vub300->vub_name, 1254 1254 "SDIO interrupt pseudocode download failed", 1255 1255 sizeof(vub300->vub_name)); 1256 1256 return; ··· 1259 1259 dev_err(&vub300->udev->dev, 1260 1260 "corrupt interrupt pseudocode in firmware %s %s\n", 1261 1261 fw->data, vub300->vub_name); 1262 - strncpy(vub300->vub_name, "corrupt interrupt pseudocode", 1262 + strscpy(vub300->vub_name, "corrupt interrupt pseudocode", 1263 1263 sizeof(vub300->vub_name)); 1264 1264 return; 1265 1265 } ··· 1293 1293 "not enough memory for xfer buffer to send" 1294 1294 " TRANSFER_PSEUDOCODE for %s %s\n", fw->data, 1295 1295 vub300->vub_name); 1296 - strncpy(vub300->vub_name, 1296 + strscpy(vub300->vub_name, 1297 1297 "SDIO transfer pseudocode download failed", 1298 1298 sizeof(vub300->vub_name)); 1299 1299 return; ··· 1302 1302 dev_err(&vub300->udev->dev, 1303 1303 "corrupt transfer pseudocode in firmware %s %s\n", 1304 1304 fw->data, vub300->vub_name); 1305 - strncpy(vub300->vub_name, "corrupt transfer pseudocode", 1305 + strscpy(vub300->vub_name, "corrupt transfer pseudocode", 1306 1306 sizeof(vub300->vub_name)); 1307 1307 return; 1308 1308 } ··· 1336 1336 dev_err(&vub300->udev->dev, 1337 1337 "corrupt dynamic registers in firmware %s\n", 1338 1338 vub300->vub_name); 1339 - strncpy(vub300->vub_name, "corrupt dynamic registers", 1339 + strscpy(vub300->vub_name, "corrupt dynamic registers", 1340 1340 sizeof(vub300->vub_name)); 1341 1341 return; 1342 1342 } 1343 1343 1344 1344 copy_error_message: 1345 - strncpy(vub300->vub_name, "SDIO pseudocode download failed", 1345 + strscpy(vub300->vub_name, "SDIO pseudocode download failed", 1346 1346 sizeof(vub300->vub_name)); 1347 1347 } 1348 1348 ··· 1370 1370 vub300->vub_name); 1371 1371 retval = request_firmware(&fw, vub300->vub_name, &card->dev); 1372 1372 if (retval < 0) { 1373 - strncpy(vub300->vub_name, "vub_default.bin", 1373 + strscpy(vub300->vub_name, "vub_default.bin", 1374 1374 sizeof(vub300->vub_name)); 1375 1375 retval = request_firmware(&fw, vub300->vub_name, &card->dev); 1376 1376 if (retval < 0) { 1377 - strncpy(vub300->vub_name, 1377 + strscpy(vub300->vub_name, 1378 1378 "no SDIO offload firmware found", 1379 1379 sizeof(vub300->vub_name)); 1380 1380 } else { ··· 1758 1758 * has been already downloaded to the VUB300 chip 1759 1759 */ 1760 1760 } else if (0 == vub300->mmc->card->sdio_funcs) { 1761 - strncpy(vub300->vub_name, "SD memory device", 1761 + strscpy(vub300->vub_name, "SD memory device", 1762 1762 sizeof(vub300->vub_name)); 1763 1763 } else { 1764 1764 download_offload_pseudocode(vub300);
+1
include/linux/mmc/host.h
··· 526 526 527 527 /* Host Software Queue support */ 528 528 bool hsq_enabled; 529 + int hsq_depth; 529 530 530 531 u32 err_stats[MMC_ERR_MAX]; 531 532 unsigned long private[] ____cacheline_aligned;