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

Pull MMC updates from Ulf Hansson:
 "MMC core:
   - Add support for the asynchronous SDIO wakeup interrupts
   - Skip redundant evaluation of eMMC HS400 caps when no-MMC-cap
   - Add support to store error stats from host drivers
   - Extend debugfs to show error stats from host drivers
   - Add single I/O read support in the recovery path for 4k sector cards

  MMC host:
   - dw_mmc-exynos: Convert corresponding DT bindings to the dtschema
   - dw_mmc-rockchip: Add support for the Rockchip RV1126 variant
   - mmc_spi: Convert corresponding DT bindings to the dtschema
   - mtk-sd: Extend support for interrupts/pinctrls for SDIO low-power mode
   - mtk-sd: Add support for SDIO wake irqs
   - mtk-sd: Add support for the Mediatek MT8188 variant
   - renesas_sdhi: Drop redundant manual tap correction for newer SoCs
   - renesas_sdhi: Add support for the R-Car S4-8 and generic Gen4 variants
   - sdhci/cqhci: Add support to capture stats from host errors
   - sdhci-brcmstb: Add ability to increase max clock rate for SDIO on 72116b0
   - sdhci-msm: Add support for the MSM8998 and SM8450 variant
   - sdhci-of-at91: Fixup UHS-I mode by rewriting of MC1R
   - sdhci-of-dwcmshc: Add support for the Rockchip rk3588 variant
   - sdhci-of-dwcmshc: Enable reset support for the Rockchip variants
   - sdhci-pci-gli: Improve I/O read/write performance for GL9763E
   - sdhci-s3c: Convert corresponding DT bindings to the dtschema
   - tmio: Avoid glitches when resetting

  MEMSTICK core:
   - A couple of minor fixes and cleanups"

* tag 'mmc-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (61 commits)
  mmc: mediatek: add support for SDIO eint wakup IRQ
  mmc: core: Add support for SDIO wakeup interrupt
  dt-bindings: mmc: mtk-sd: extend interrupts and pinctrls properties
  dt-bindings: mmc: rockchip-dw-mshc: Document Rockchip RV1126
  mmc: renesas_sdhi: newer SoCs don't need manual tap correction
  mmc: cavium-thunderx: Add of_node_put() when breaking out of loop
  mmc: cavium-octeon: Add of_node_put() when breaking out of loop
  mmc: core: quirks: Add of_node_put() when breaking out of loop
  mmc: sdhci-brcmstb: use clk_get_rate(base_clk) in PM resume
  dt-bindings: mmc: sdhci-msm: Document the SM8450 compatible
  mmc: sdhci-msm: drop redundant of_device_id entries
  dt-bindings: mmc: sdhci-msm: add MSM8998
  mmc: block: Add single read for 4k sector cards
  mmc: mxcmmc: Use mmc_card_sdio macro
  mmc: core: Use mmc_card_* macro and add a new for the sd_combo type
  dt-bindings: mmc: sdhci-msm: constrain reg-names per variants
  dt-bindings: mmc: sdhci-msm: fix reg-names entries
  dt-bindings: mmc: Add compatible for MediaTek MT8188
  dt-bindings: mmc: sdhci-msm: document resets
  mmc: sdhci-of-at91: fix set_uhs_signaling rewriting of MC1R
  ...
This commit is contained in:
Linus Torvalds
2022-08-04 19:41:09 -07:00
49 changed files with 1152 additions and 362 deletions

View File

@@ -10,9 +10,6 @@ maintainers:
- Al Cooper <alcooperx@gmail.com>
- Florian Fainelli <f.fainelli@gmail.com>
allOf:
- $ref: mmc-controller.yaml#
properties:
compatible:
oneOf:
@@ -42,23 +39,46 @@ properties:
maxItems: 1
clocks:
maxItems: 1
description:
handle to core clock for the sdhci controller.
minItems: 1
items:
- description: handle to core clock for the sdhci controller
- description: handle to improved 150Mhz clock for sdhci controller (Optional clock)
clock-names:
minItems: 1
items:
- const: sw_sdio
- const: sdio_freq # Optional clock
clock-frequency:
description:
Maximum operating frequency of sdio_freq sdhci controller clock
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 100000000
maximum: 150000000
sdhci,auto-cmd12:
type: boolean
description: Specifies that controller should use auto CMD12
allOf:
- $ref: mmc-controller.yaml#
- if:
properties:
clock-names:
contains:
const: sdio_freq
then:
required:
- clock-frequency
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
unevaluatedProperties: false

View File

@@ -1,94 +0,0 @@
* Samsung Exynos specific extensions to the Synopsys Designware Mobile
Storage Host Controller
The Synopsys designware mobile storage host controller is used to interface
a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
differences between the core Synopsys dw mshc controller properties described
by synopsys-dw-mshc.txt and the properties used by the Samsung Exynos specific
extensions to the Synopsys Designware Mobile Storage Host Controller.
Required Properties:
* compatible: should be
- "samsung,exynos4210-dw-mshc": for controllers with Samsung Exynos4210
specific extensions.
- "samsung,exynos4412-dw-mshc": for controllers with Samsung Exynos4412
specific extensions.
- "samsung,exynos5250-dw-mshc": for controllers with Samsung Exynos5250
specific extensions.
- "samsung,exynos5420-dw-mshc": for controllers with Samsung Exynos5420
specific extensions.
- "samsung,exynos7-dw-mshc": for controllers with Samsung Exynos7
specific extensions.
- "samsung,exynos7-dw-mshc-smu": for controllers with Samsung Exynos7
specific extensions having an SMU.
- "axis,artpec8-dw-mshc": for controllers with ARTPEC-8 specific
extensions.
* samsung,dw-mshc-ciu-div: Specifies the divider value for the card interface
unit (ciu) clock. This property is applicable only for Exynos5 SoC's and
ignored for Exynos4 SoC's. The valid range of divider value is 0 to 7.
* samsung,dw-mshc-sdr-timing: Specifies the value of CIU clock phase shift value
in transmit mode and CIU clock phase shift value in receive mode for single
data rate mode operation. Refer notes below for the order of the cells and the
valid values.
* samsung,dw-mshc-ddr-timing: Specifies the value of CUI clock phase shift value
in transmit mode and CIU clock phase shift value in receive mode for double
data rate mode operation. Refer notes below for the order of the cells and the
valid values.
* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase
shift value for hs400 mode operation.
Notes for the sdr-timing and ddr-timing values:
The order of the cells should be
- First Cell: CIU clock phase shift value for tx mode.
- Second Cell: CIU clock phase shift value for rx mode.
Valid values for SDR and DDR CIU clock timing for Exynos5250:
- valid value for tx phase shift and rx phase shift is 0 to 7.
- when CIU clock divider value is set to 3, all possible 8 phase shift
values can be used.
- if CIU clock divider value is 0 (that is divide by 1), both tx and rx
phase shift clocks should be 0.
* samsung,read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode
(Latency value for delay line in Read path)
Required properties for a slot (Deprecated - Recommend to use one slot per host):
* gpios: specifies a list of gpios used for command, clock and data bus. The
first gpio is the command line and the second gpio is the clock line. The
rest of the gpios (depending on the bus-width property) are the data lines in
no particular order. The format of the gpio specifier depends on the gpio
controller.
(Deprecated - Refer to Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt)
Example:
The MSHC controller node can be split into two portions, SoC specific and
board specific portions as listed below.
dwmmc0@12200000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12200000 0x1000>;
interrupts = <0 75 0>;
#address-cells = <1>;
#size-cells = <0>;
};
dwmmc0@12200000 {
cap-mmc-highspeed;
cap-sd-highspeed;
broken-cd;
fifo-depth = <0x80>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <2 3>;
samsung,dw-mshc-ddr-timing = <1 2>;
samsung,dw-mshc-hs400-timing = <0 2>;
samsung,read-strobe-delay = <90>;
bus-width = <8>;
};

View File

@@ -1,29 +0,0 @@
MMC/SD/SDIO slot directly connected to a SPI bus
This file documents differences between the core properties described
by mmc.txt and the properties used by the mmc_spi driver.
Required properties:
- spi-max-frequency : maximum frequency for this device (Hz).
Optional properties:
- voltage-ranges : two cells are required, first cell specifies minimum
slot voltage (mV), second cell specifies maximum slot voltage (mV).
Several ranges could be specified. If not provided, 3.2v..3.4v is assumed.
- gpios : may specify GPIOs in this order: Card-Detect GPIO,
Write-Protect GPIO. Note that this does not follow the
binding from mmc.txt, for historical reasons.
Example:
mmc-slot@0 {
compatible = "fsl,mpc8323rdb-mmc-slot",
"mmc-spi-slot";
reg = <0>;
gpios = <&qe_pio_d 14 1
&qe_pio_d 15 0>;
voltage-ranges = <3300 3300>;
spi-max-frequency = <50000000>;
interrupts = <42>;
interrupt-parent = <&PIC>;
};

View File

@@ -0,0 +1,77 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mmc/mmc-spi-slot.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MMC/SD/SDIO slot directly connected to a SPI bus
maintainers:
- Ulf Hansson <ulf.hansson@linaro.org>
allOf:
- $ref: "mmc-controller.yaml"
- $ref: /schemas/spi/spi-peripheral-props.yaml
description: |
The extra properties used by an mmc connected via SPI.
properties:
compatible:
const: mmc-spi-slot
reg:
maxItems: 1
spi-max-frequency: true
interrupts:
maxItems: 1
voltage-ranges:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: |
Two cells are required, first cell specifies minimum slot voltage (mV),
second cell specifies maximum slot voltage (mV).
items:
- description: |
value for minimum slot voltage in mV
default: 3200
- description: |
value for maximum slot voltage in mV
default: 3400
gpios:
description: |
For historical reasons, this does not follow the generic mmc-controller
binding.
minItems: 1
items:
- description: Card-Detect GPIO
- description: Write-Protect GPIO
required:
- compatible
- reg
- spi-max-frequency
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
mmc@0 {
compatible = "mmc-spi-slot";
reg = <0>;
gpios = <&gpio 14 GPIO_ACTIVE_LOW>, <&gpio 15 GPIO_ACTIVE_HIGH>;
voltage-ranges = <3300 3300>;
spi-max-frequency = <50000000>;
interrupts = <42>;
interrupt-parent = <&PIC>;
};
};
...

View File

@@ -30,13 +30,11 @@ properties:
- const: mediatek,mt7623-mmc
- const: mediatek,mt2701-mmc
- items:
- const: mediatek,mt8186-mmc
- const: mediatek,mt8183-mmc
- items:
- const: mediatek,mt8192-mmc
- const: mediatek,mt8183-mmc
- items:
- const: mediatek,mt8195-mmc
- enum:
- mediatek,mt8186-mmc
- mediatek,mt8188-mmc
- mediatek,mt8192-mmc
- mediatek,mt8195-mmc
- const: mediatek,mt8183-mmc
reg:
@@ -72,12 +70,27 @@ properties:
- const: ahb_cg
interrupts:
maxItems: 1
description:
Should at least contain MSDC GIC interrupt. To support SDIO in-band wakeup, an extended
interrupt is required and be configured as wakeup source irq.
minItems: 1
maxItems: 2
interrupt-names:
items:
- const: msdc
- const: sdio_wakeup
pinctrl-names:
description:
Should at least contain default and state_uhs. To support SDIO in-band wakeup, dat1 pin
will be switched between GPIO mode and SDIO DAT1 mode, state_eint is mandatory in this
scenario.
minItems: 2
items:
- const: default
- const: state_uhs
- const: state_eint
pinctrl-0:
description:
@@ -89,6 +102,11 @@ properties:
should contain uhs mode pin ctrl.
maxItems: 1
pinctrl-2:
description:
should switch dat1 pin to GPIO mode.
maxItems: 1
assigned-clocks:
description:
PLL of the source clock.
@@ -208,4 +226,32 @@ examples:
mediatek,hs400-cmd-resp-sel-rising;
};
mmc3: mmc@11260000 {
compatible = "mediatek,mt8173-mmc";
reg = <0x11260000 0x1000>;
clock-names = "source", "hclk";
clocks = <&pericfg CLK_PERI_MSDC30_3>,
<&topckgen CLK_TOP_MSDC50_2_H_SEL>;
interrupt-names = "msdc", "sdio_wakeup";
interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_LOW 0>,
<&pio 23 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default", "state_uhs", "state_eint";
pinctrl-0 = <&mmc2_pins_default>;
pinctrl-1 = <&mmc2_pins_uhs>;
pinctrl-2 = <&mmc2_pins_eint>;
bus-width = <4>;
max-frequency = <200000000>;
cap-sd-highspeed;
sd-uhs-sdr104;
keep-power-in-suspend;
wakeup-source;
cap-sdio-irq;
no-mmc;
no-sd;
non-removable;
vmmc-supply = <&sdio_fixed_3v3>;
vqmmc-supply = <&mt6397_vgp3_reg>;
mmc-pwrseq = <&wifi_pwrseq>;
};
...

View File

@@ -56,11 +56,15 @@ properties:
- renesas,sdhi-r8a77980 # R-Car V3H
- renesas,sdhi-r8a77990 # R-Car E3
- renesas,sdhi-r8a77995 # R-Car D3
- renesas,sdhi-r8a779a0 # R-Car V3U
- renesas,sdhi-r9a07g043 # RZ/G2UL
- renesas,sdhi-r9a07g044 # RZ/G2{L,LC}
- renesas,sdhi-r9a07g054 # RZ/V2L
- const: renesas,rcar-gen3-sdhi # R-Car Gen3 or RZ/G2
- items:
- enum:
- renesas,sdhi-r8a779a0 # R-Car V3U
- renesas,sdhi-r8a779f0 # R-Car S4-8
- const: renesas,rcar-gen4-sdhi # R-Car Gen4
reg:
maxItems: 1
@@ -141,6 +145,7 @@ allOf:
enum:
- renesas,rcar-gen2-sdhi
- renesas,rcar-gen3-sdhi
- renesas,rcar-gen4-sdhi
then:
properties:
clocks:

View File

@@ -39,6 +39,7 @@ properties:
- rockchip,rk3399-dw-mshc
- rockchip,rk3568-dw-mshc
- rockchip,rv1108-dw-mshc
- rockchip,rv1126-dw-mshc
- const: rockchip,rk3288-dw-mshc
reg:

View File

@@ -0,0 +1,160 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/mmc/samsung,exynos-dw-mshc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title:
Samsung Exynos SoC specific extensions to the Synopsys Designware Mobile
Storage Host Controller
maintainers:
- Jaehoon Chung <jh80.chung@samsung.com>
- Krzysztof Kozlowski <krzk@kernel.org>
properties:
compatible:
enum:
- samsung,exynos4210-dw-mshc
- samsung,exynos4412-dw-mshc
- samsung,exynos5250-dw-mshc
- samsung,exynos5420-dw-mshc
- samsung,exynos5420-dw-mshc-smu
- samsung,exynos7-dw-mshc
- samsung,exynos7-dw-mshc-smu
- axis,artpec8-dw-mshc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 2
description:
Handle to "biu" and "ciu" clocks for the
bus interface unit clock and the card interface unit clock.
clock-names:
items:
- const: biu
- const: ciu
samsung,dw-mshc-ciu-div:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 7
description:
The divider value for the card interface unit (ciu) clock.
samsung,dw-mshc-ddr-timing:
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
- description: CIU clock phase shift value for tx mode
minimum: 0
maximum: 7
- description: CIU clock phase shift value for rx mode
minimum: 0
maximum: 7
description:
The value of CUI clock phase shift value in transmit mode and CIU clock
phase shift value in receive mode for double data rate mode operation.
See also samsung,dw-mshc-hs400-timing property.
samsung,dw-mshc-hs400-timing:
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
- description: CIU clock phase shift value for tx mode
minimum: 0
maximum: 7
- description: CIU clock phase shift value for rx mode
minimum: 0
maximum: 7
description: |
The value of CIU TX and RX clock phase shift value for HS400 mode
operation.
Valid values for SDR and DDR CIU clock timing::
- valid value for tx phase shift and rx phase shift is 0 to 7.
- when CIU clock divider value is set to 3, all possible 8 phase shift
values can be used.
- if CIU clock divider value is 0 (that is divide by 1), both tx and rx
phase shift clocks should be 0.
If missing, values from samsung,dw-mshc-ddr-timing property are used.
samsung,dw-mshc-sdr-timing:
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
- description: CIU clock phase shift value for tx mode
minimum: 0
maximum: 7
- description: CIU clock phase shift value for rx mode
minimum: 0
maximum: 7
description:
The value of CIU clock phase shift value in transmit mode and CIU clock
phase shift value in receive mode for single data rate mode operation.
See also samsung,dw-mshc-hs400-timing property.
samsung,read-strobe-delay:
$ref: /schemas/types.yaml#/definitions/uint32
description:
RCLK (Data strobe) delay to control HS400 mode (Latency value for delay
line in Read path). If missing, default from hardware is used.
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- samsung,dw-mshc-ddr-timing
- samsung,dw-mshc-sdr-timing
allOf:
- $ref: "synopsys-dw-mshc-common.yaml#"
- if:
properties:
compatible:
contains:
enum:
- samsung,exynos5250-dw-mshc
- samsung,exynos5420-dw-mshc
- samsung,exynos7-dw-mshc
- samsung,exynos7-dw-mshc-smu
- axis,artpec8-dw-mshc
then:
required:
- samsung,dw-mshc-ciu-div
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/exynos5420.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
mmc@12220000 {
compatible = "samsung,exynos5420-dw-mshc";
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x12220000 0x1000>;
clocks = <&clock CLK_MMC2>, <&clock CLK_SCLK_MMC2>;
clock-names = "biu", "ciu";
fifo-depth = <0x40>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <0 4>;
samsung,dw-mshc-ddr-timing = <0 2>;
pinctrl-names = "default";
pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_wp &sd2_bus1 &sd2_bus4>;
bus-width = <4>;
cap-sd-highspeed;
max-frequency = <200000000>;
vmmc-supply = <&ldo19_reg>;
vqmmc-supply = <&ldo13_reg>;
sd-uhs-sdr50;
sd-uhs-sdr104;
sd-uhs-ddr50;
};

View File

@@ -0,0 +1,81 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/mmc/samsung,s3c6410-sdhci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung SoC SDHCI Controller
maintainers:
- Jaehoon Chung <jh80.chung@samsung.com>
- Krzysztof Kozlowski <krzk@kernel.org>
properties:
compatible:
enum:
- samsung,s3c6410-sdhci
- samsung,exynos4210-sdhci
reg:
maxItems: 1
clocks:
minItems: 2
maxItems: 5
clock-names:
minItems: 2
items:
- const: hsmmc
- pattern: "^mmc_busclk.[0-3]$"
- pattern: "^mmc_busclk.[0-3]$"
- pattern: "^mmc_busclk.[0-3]$"
- pattern: "^mmc_busclk.[0-3]$"
interrupts:
maxItems: 1
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
allOf:
- $ref: mmc-controller.yaml#
- if:
properties:
compatible:
contains:
enum:
- samsung,exynos4210-sdhci
then:
properties:
clocks:
maxItems: 2
clock-names:
items:
- const: hsmmc
- const: mmc_busclk.2
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/exynos4.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
mmc@12510000 {
compatible = "samsung,exynos4210-sdhci";
reg = <0x12510000 0x100>;
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SDMMC0>, <&clock CLK_SCLK_MMC0>;
clock-names = "hsmmc", "mmc_busclk.2";
bus-width = <4>;
cd-gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sdhci2_cd>;
pinctrl-names = "default";
vmmc-supply = <&ldo21_reg>;
};

View File

@@ -1,32 +0,0 @@
* Samsung's SDHCI Controller device tree bindings
Samsung's SDHCI controller is used as a connectivity interface with external
MMC, SD and eMMC storage mediums. This file documents differences between the
core mmc properties described by mmc.txt and the properties used by the
Samsung implementation of the SDHCI controller.
Required SoC Specific Properties:
- compatible: should be one of the following
- "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci
controller.
- "samsung,exynos4210-sdhci": For controllers compatible with Exynos4 sdhci
controller.
Required Board Specific Properties:
- pinctrl-0: Should specify pin control groups used for this controller.
- pinctrl-names: Should contain only one value - "default".
Example:
sdhci@12530000 {
compatible = "samsung,exynos4210-sdhci";
reg = <0x12530000 0x100>;
interrupts = <0 75 0>;
bus-width = <4>;
cd-gpios = <&gpk2 2 0>;
pinctrl-names = "default";
pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>;
};
Note: This example shows both SoC specific and board specific properties
in a single device node. The properties can be actually be separated
into SoC specific node and board specific node.

View File

@@ -17,6 +17,9 @@ description:
properties:
compatible:
oneOf:
- enum:
- qcom,sdhci-msm-v4
deprecated: true
- items:
- enum:
- qcom,apq8084-sdhci
@@ -27,6 +30,10 @@ properties:
- qcom,msm8992-sdhci
- qcom,msm8994-sdhci
- qcom,msm8996-sdhci
- qcom,msm8998-sdhci
- const: qcom,sdhci-msm-v4 # for sdcc versions less than 5.0
- items:
- enum:
- qcom,qcs404-sdhci
- qcom,sc7180-sdhci
- qcom,sc7280-sdhci
@@ -38,20 +45,16 @@ properties:
- qcom,sm6350-sdhci
- qcom,sm8150-sdhci
- qcom,sm8250-sdhci
- enum:
- qcom,sdhci-msm-v4 # for sdcc versions less than 5.0
- qcom,sdhci-msm-v5 # for sdcc version 5.0
- items:
- const: qcom,sdhci-msm-v4 # Deprecated (only for backward compatibility)
# for sdcc versions less than 5.0
- qcom,sm8450-sdhci
- const: qcom,sdhci-msm-v5 # for sdcc version 5.0
reg:
minItems: 1
items:
- description: Host controller register map
- description: SD Core register map
- description: CQE register map
- description: Inline Crypto Engine register map
maxItems: 4
reg-names:
minItems: 1
maxItems: 4
clocks:
minItems: 3
@@ -93,6 +96,9 @@ properties:
description:
Should specify pin control groups used for this controller.
resets:
maxItems: 1
qcom,ddr-config:
$ref: /schemas/types.yaml#/definitions/uint32
description: platform specific settings for DDR_CONFIG reg.
@@ -121,6 +127,16 @@ properties:
description: A phandle to sdhci power domain node
maxItems: 1
mmc-ddr-1_8v: true
mmc-hs200-1_8v: true
mmc-hs400-1_8v: true
bus-width: true
max-frequency: true
patternProperties:
'^opp-table(-[a-z0-9]+)?$':
if:
@@ -140,7 +156,47 @@ required:
- clock-names
- interrupts
additionalProperties: true
allOf:
- $ref: mmc-controller.yaml#
- if:
properties:
compatible:
contains:
enum:
- qcom,sdhci-msm-v4
then:
properties:
reg:
minItems: 2
items:
- description: Host controller register map
- description: SD Core register map
- description: CQE register map
- description: Inline Crypto Engine register map
reg-names:
minItems: 2
items:
- const: hc
- const: core
- const: cqhci
- const: ice
else:
properties:
reg:
minItems: 1
items:
- description: Host controller register map
- description: CQE register map
- description: Inline Crypto Engine register map
reg-names:
minItems: 1
items:
- const: hc
- const: cqhci
- const: ice
unevaluatedProperties: false
examples:
- |
@@ -149,7 +205,7 @@ examples:
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
sdhc_2: sdhci@8804000 {
sdhc_2: mmc@8804000 {
compatible = "qcom,sm8250-sdhci", "qcom,sdhci-msm-v5";
reg = <0 0x08804000 0 0x1000>;

View File

@@ -1341,17 +1341,17 @@ static int msb_ftl_initialize(struct msb_data *msb)
msb->zone_count = msb->block_count / MS_BLOCKS_IN_ZONE;
msb->logical_block_count = msb->zone_count * 496 - 2;
msb->used_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL);
msb->erased_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL);
msb->used_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL);
msb->erased_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL);
msb->lba_to_pba_table =
kmalloc_array(msb->logical_block_count, sizeof(u16),
GFP_KERNEL);
if (!msb->used_blocks_bitmap || !msb->lba_to_pba_table ||
!msb->erased_blocks_bitmap) {
kfree(msb->used_blocks_bitmap);
bitmap_free(msb->used_blocks_bitmap);
bitmap_free(msb->erased_blocks_bitmap);
kfree(msb->lba_to_pba_table);
kfree(msb->erased_blocks_bitmap);
return -ENOMEM;
}
@@ -1946,7 +1946,8 @@ static DEFINE_MUTEX(msb_disk_lock); /* protects against races in open/release */
static void msb_data_clear(struct msb_data *msb)
{
kfree(msb->boot_page);
kfree(msb->used_blocks_bitmap);
bitmap_free(msb->used_blocks_bitmap);
bitmap_free(msb->erased_blocks_bitmap);
kfree(msb->lba_to_pba_table);
kfree(msb->cache);
msb->card = NULL;
@@ -2243,8 +2244,8 @@ static int msb_resume(struct memstick_dev *card)
goto out;
if (msb->block_count != new_msb->block_count ||
memcmp(msb->used_blocks_bitmap, new_msb->used_blocks_bitmap,
msb->block_count / 8))
!bitmap_equal(msb->used_blocks_bitmap, new_msb->used_blocks_bitmap,
msb->block_count))
goto out;
card_dead = false;

View File

@@ -176,7 +176,7 @@ static inline int mmc_blk_part_switch(struct mmc_card *card,
unsigned int part_type);
static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
struct mmc_card *card,
int disable_multi,
int recovery_mode,
struct mmc_queue *mq);
static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
@@ -1302,7 +1302,7 @@ static void mmc_blk_eval_resp_error(struct mmc_blk_request *brq)
}
static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
int disable_multi, bool *do_rel_wr_p,
int recovery_mode, bool *do_rel_wr_p,
bool *do_data_tag_p)
{
struct mmc_blk_data *md = mq->blkdata;
@@ -1368,12 +1368,12 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
brq->data.blocks--;
/*
* After a read error, we redo the request one sector
* After a read error, we redo the request one (native) sector
* at a time in order to accurately determine which
* sectors can be read successfully.
*/
if (disable_multi)
brq->data.blocks = 1;
if (recovery_mode)
brq->data.blocks = queue_physical_block_size(mq->queue) >> 9;
/*
* Some controllers have HW issues while operating
@@ -1590,7 +1590,7 @@ static int mmc_blk_cqe_issue_rw_rq(struct mmc_queue *mq, struct request *req)
static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
struct mmc_card *card,
int disable_multi,
int recovery_mode,
struct mmc_queue *mq)
{
u32 readcmd, writecmd;
@@ -1599,7 +1599,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
struct mmc_blk_data *md = mq->blkdata;
bool do_rel_wr, do_data_tag;
mmc_blk_data_prep(mq, mqrq, disable_multi, &do_rel_wr, &do_data_tag);
mmc_blk_data_prep(mq, mqrq, recovery_mode, &do_rel_wr, &do_data_tag);
brq->mrq.cmd = &brq->cmd;
@@ -1690,7 +1690,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req)
#define MMC_READ_SINGLE_RETRIES 2
/* Single sector read during recovery */
/* Single (native) sector read during recovery */
static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
{
struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
@@ -1698,6 +1698,7 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
struct mmc_card *card = mq->card;
struct mmc_host *host = card->host;
blk_status_t error = BLK_STS_OK;
size_t bytes_per_read = queue_physical_block_size(mq->queue);
do {
u32 status;
@@ -1732,13 +1733,13 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
else
error = BLK_STS_OK;
} while (blk_update_request(req, error, 512));
} while (blk_update_request(req, error, bytes_per_read));
return;
error_exit:
mrq->data->bytes_xfered = 0;
blk_update_request(req, BLK_STS_IOERR, 512);
blk_update_request(req, BLK_STS_IOERR, bytes_per_read);
/* Let it try the remaining request again */
if (mqrq->retries > MMC_MAX_RETRIES - 1)
mqrq->retries = MMC_MAX_RETRIES - 1;
@@ -1879,10 +1880,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
return;
}
/* FIXME: Missing single sector read for large sector size */
if (!mmc_large_sector(card) && rq_data_dir(req) == READ &&
brq->data.blocks > 1) {
/* Read one sector at a time */
if (rq_data_dir(req) == READ && brq->data.blocks >
queue_physical_block_size(mq->queue) >> 9) {
/* Read one (native) sector at a time */
mmc_blk_read_single(mq, req);
return;
}
@@ -2988,7 +2988,7 @@ static int mmc_blk_probe(struct mmc_card *card)
* Don't enable runtime PM for SD-combo cards here. Leave that
* decision to be taken during the SDIO init sequence instead.
*/
if (card->type != MMC_TYPE_SD_COMBO) {
if (!mmc_card_sd_combo(card)) {
pm_runtime_set_active(&card->dev);
pm_runtime_enable(&card->dev);
}
@@ -3015,7 +3015,7 @@ static void mmc_blk_remove(struct mmc_card *card)
mmc_blk_part_switch(card, md->part_type);
mmc_release_host(card->host);
}
if (card->type != MMC_TYPE_SD_COMBO)
if (!mmc_card_sd_combo(card))
pm_runtime_disable(&card->dev);
pm_runtime_put_noidle(&card->dev);
mmc_blk_remove_req(md);

View File

@@ -85,7 +85,7 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
return retval;
}
if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) {
if (mmc_card_sdio(card) || mmc_card_sd_combo(card)) {
retval = add_uevent_var(env, "SDIO_ID=%04X:%04X",
card->cis.vendor, card->cis.device);
if (retval)
@@ -107,7 +107,7 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
* SDIO (non-combo) cards are not handled by mmc_block driver and do not
* have accessible CID register which used by mmc_card_name() function.
*/
if (card->type == MMC_TYPE_SDIO)
if (mmc_card_sdio(card))
return 0;
retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card));

View File

@@ -943,9 +943,11 @@ int mmc_execute_tuning(struct mmc_card *card)
}
/* Only print error when we don't check for card removal */
if (!host->detect_change)
if (!host->detect_change) {
pr_err("%s: tuning execution failed: %d\n",
mmc_hostname(host), err);
mmc_debugfs_err_stats_inc(host, MMC_ERR_TUNING);
}
return err;
}
@@ -2244,6 +2246,12 @@ void mmc_rescan(struct work_struct *work)
if (freqs[i] <= host->f_min)
break;
}
/*
* Ignore the command timeout errors observed during
* the card init as those are excepted.
*/
host->err_stats[MMC_ERR_CMD_TIMEOUT] = 0;
mmc_release_host(host);
out:

View File

@@ -223,6 +223,81 @@ static int mmc_clock_opt_set(void *data, u64 val)
DEFINE_DEBUGFS_ATTRIBUTE(mmc_clock_fops, mmc_clock_opt_get, mmc_clock_opt_set,
"%llu\n");
static int mmc_err_state_get(void *data, u64 *val)
{
struct mmc_host *host = data;
int i;
if (!host)
return -EINVAL;
*val = 0;
for (i = 0; i < MMC_ERR_MAX; i++) {
if (host->err_stats[i]) {
*val = 1;
break;
}
}
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(mmc_err_state, mmc_err_state_get, NULL, "%llu\n");
static int mmc_err_stats_show(struct seq_file *file, void *data)
{
struct mmc_host *host = (struct mmc_host *)file->private;
const char *desc[MMC_ERR_MAX] = {
[MMC_ERR_CMD_TIMEOUT] = "Command Timeout Occurred",
[MMC_ERR_CMD_CRC] = "Command CRC Errors Occurred",
[MMC_ERR_DAT_TIMEOUT] = "Data Timeout Occurred",
[MMC_ERR_DAT_CRC] = "Data CRC Errors Occurred",
[MMC_ERR_AUTO_CMD] = "Auto-Cmd Error Occurred",
[MMC_ERR_ADMA] = "ADMA Error Occurred",
[MMC_ERR_TUNING] = "Tuning Error Occurred",
[MMC_ERR_CMDQ_RED] = "CMDQ RED Errors",
[MMC_ERR_CMDQ_GCE] = "CMDQ GCE Errors",
[MMC_ERR_CMDQ_ICCE] = "CMDQ ICCE Errors",
[MMC_ERR_REQ_TIMEOUT] = "Request Timedout",
[MMC_ERR_CMDQ_REQ_TIMEOUT] = "CMDQ Request Timedout",
[MMC_ERR_ICE_CFG] = "ICE Config Errors",
[MMC_ERR_CTRL_TIMEOUT] = "Controller Timedout errors",
[MMC_ERR_UNEXPECTED_IRQ] = "Unexpected IRQ errors",
};
int i;
for (i = 0; i < MMC_ERR_MAX; i++) {
if (desc[i])
seq_printf(file, "# %s:\t %d\n",
desc[i], host->err_stats[i]);
}
return 0;
}
static int mmc_err_stats_open(struct inode *inode, struct file *file)
{
return single_open(file, mmc_err_stats_show, inode->i_private);
}
static ssize_t mmc_err_stats_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
struct mmc_host *host = filp->f_mapping->host->i_private;
pr_debug("%s: Resetting MMC error statistics\n", __func__);
memset(host->err_stats, 0, sizeof(host->err_stats));
return cnt;
}
static const struct file_operations mmc_err_stats_fops = {
.open = mmc_err_stats_open,
.read = seq_read,
.write = mmc_err_stats_write,
.release = single_release,
};
void mmc_add_host_debugfs(struct mmc_host *host)
{
struct dentry *root;
@@ -236,6 +311,11 @@ void mmc_add_host_debugfs(struct mmc_host *host)
debugfs_create_file_unsafe("clock", S_IRUSR | S_IWUSR, root, host,
&mmc_clock_fops);
debugfs_create_file_unsafe("err_state", 0600, root, host,
&mmc_err_state);
debugfs_create_file("err_stats", 0600, root, host,
&mmc_err_stats_fops);
#ifdef CONFIG_FAIL_MMC_REQUEST
if (fail_request)
setup_fault_attr(&fail_default_attr, fail_request);

View File

@@ -599,7 +599,7 @@ static int mmc_validate_host_caps(struct mmc_host *host)
}
if (caps2 & (MMC_CAP2_HS400_ES | MMC_CAP2_HS400) &&
!(caps & MMC_CAP_8_BIT_DATA)) {
!(caps & MMC_CAP_8_BIT_DATA) && !(caps2 & MMC_CAP2_NO_MMC)) {
dev_warn(dev, "drop HS400 support since no 8-bit bus\n");
host->caps2 = caps2 & ~MMC_CAP2_HS400_ES & ~MMC_CAP2_HS400;
}

View File

@@ -163,8 +163,10 @@ static inline bool mmc_fixup_of_compatible_match(struct mmc_card *card,
struct device_node *np;
for_each_child_of_node(mmc_dev(card->host)->of_node, np) {
if (of_device_is_compatible(np, compatible))
if (of_device_is_compatible(np, compatible)) {
of_node_put(np);
return true;
}
}
return false;

View File

@@ -793,7 +793,7 @@ static umode_t sd_std_is_visible(struct kobject *kobj, struct attribute *attr,
attr == &dev_attr_info2.attr ||
attr == &dev_attr_info3.attr ||
attr == &dev_attr_info4.attr
) && card->type != MMC_TYPE_SD_COMBO)
) &&!mmc_card_sd_combo(card))
return 0;
return attr->mode;
@@ -870,7 +870,7 @@ try_again:
* the CCS bit is set as well. We deliberately deviate from the spec in
* regards to this, which allows UHS-I to be supported for SDSC cards.
*/
if (!mmc_host_is_spi(host) && rocr && (*rocr & 0x01000000)) {
if (!mmc_host_is_spi(host) && rocr && (*rocr & SD_ROCR_S18A)) {
err = mmc_set_uhs_voltage(host, pocr);
if (err == -EAGAIN) {
retries--;

View File

@@ -226,6 +226,20 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
if (data & SDIO_DRIVE_SDTD)
card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTERRUPT_EXT, 0, &data);
if (ret)
goto out;
if (data & SDIO_INTERRUPT_EXT_SAI) {
data |= SDIO_INTERRUPT_EXT_EAI;
ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_INTERRUPT_EXT,
data, NULL);
if (ret)
goto out;
card->cccr.enable_async_irq = 1;
}
}
/* if no uhs mode ensure we check for high speed */
@@ -335,7 +349,7 @@ static int sdio_disable_4bit_bus(struct mmc_card *card)
{
int err;
if (card->type == MMC_TYPE_SDIO)
if (mmc_card_sdio(card))
goto out;
if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
@@ -360,7 +374,7 @@ static int sdio_enable_4bit_bus(struct mmc_card *card)
err = sdio_enable_wide(card);
if (err <= 0)
return err;
if (card->type == MMC_TYPE_SDIO)
if (mmc_card_sdio(card))
goto out;
if (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) {
@@ -415,7 +429,7 @@ static int sdio_enable_hs(struct mmc_card *card)
int ret;
ret = mmc_sdio_switch_hs(card, true);
if (ret <= 0 || card->type == MMC_TYPE_SDIO)
if (ret <= 0 || mmc_card_sdio(card))
return ret;
ret = mmc_sd_switch_hs(card);
@@ -441,7 +455,7 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card)
max_dtr = card->cis.max_dtr;
}
if (card->type == MMC_TYPE_SD_COMBO)
if (mmc_card_sd_combo(card))
max_dtr = min(max_dtr, mmc_sd_get_max_clock(card));
return max_dtr;
@@ -689,7 +703,7 @@ try_again:
mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) {
card->type = MMC_TYPE_SD_COMBO;
if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
if (oldcard && (!mmc_card_sd_combo(oldcard) ||
memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) {
err = -ENOENT;
goto mismatch;
@@ -697,7 +711,7 @@ try_again:
} else {
card->type = MMC_TYPE_SDIO;
if (oldcard && oldcard->type != MMC_TYPE_SDIO) {
if (oldcard && !mmc_card_sdio(oldcard)) {
err = -ENOENT;
goto mismatch;
}
@@ -754,7 +768,7 @@ try_again:
/*
* Read CSD, before selecting the card
*/
if (!oldcard && card->type == MMC_TYPE_SD_COMBO) {
if (!oldcard && mmc_card_sd_combo(card)) {
err = mmc_sd_get_csd(card);
if (err)
goto remove;
@@ -827,7 +841,7 @@ try_again:
mmc_fixup_device(card, sdio_fixup_methods);
if (card->type == MMC_TYPE_SD_COMBO) {
if (mmc_card_sd_combo(card)) {
err = mmc_sd_setup_card(host, card, oldcard != NULL);
/* handle as SDIO-only card if memory init failed */
if (err) {

Some files were not shown because too many files have changed in this diff Show More