diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-05 19:11:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-05 19:11:43 -0400 |
commit | f60342fac9fae20ada2cd5faadbc2a1337cae03f (patch) | |
tree | fe64b1cb3ea699d819e5e808264903aee2d8dc9a | |
parent | 5231804cf9e584f3e7e763a0d6d2fffe011c1bce (diff) | |
parent | ef5332c10d4f332a2ac79e9ad5452f4e89d1815a (diff) |
Merge tag 'mmc-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson:
"MMC core:
- Decrease polling rate for erase/trim/discard
- Allow non-sleeping GPIOs for card detect
- Improve mmc block removal path
- Enable support for mmc_sw_reset() for SDIO cards
- Add mmc_sw_reset() to allow users to do a soft reset of the card
- Allow power delay to be tunable via DT
- Allow card detect debounce delay to be tunable via DT
- Enable new quirk to limit clock rate for Marvell 8887 chip
- Don't show eMMC RPMB and BOOT areas in /proc/partitions
- Add capability to avoid 3.3V signaling for fragile HWs
MMC host:
- Improve/fixup support for handle highmem pages
- Remove depends on HAS_DMA in case of platform dependency
- mvsdio: Enable support for erase/trim/discard
- rtsx_usb: Enable support for erase/trim/discard
- renesas_sdhi: Fix WP logic regressions
- renesas_sdhi: Add r8a77965 support
- renesas_sdhi: Add R8A77980 to whitelist
- meson: Add optional support for device reset
- meson: Add support for the Meson-AXG platform
- dw_mmc: Add new driver for BlueField DW variant
- mediatek: Add support for 64G DRAM DMA
- sunxi: Deploy runtime PM support
- jz4740: Add support for JZ4780
- jz4740: Enable support for DT based platforms
- sdhci: Various improvement to timeout handling
- sdhci: Disable support for HS200/HS400/UHS when no 1.8V support
- sdhci-omap: Add support for controller in k2g SoC
- sdhci-omap: Add workarounds for a couple of Erratas
- sdhci-omap: Enable support for generic sdhci DT properties
- sdhci-cadence: Re-send tune request to deal with errata
- sdhci-pci: Fix 3.3V voltage switch for some BYT-based Intel controllers
- sdhci-pci: Avoid 3.3V signaling on some NI 904x
- sdhci-esdhc-imx: Use watermark levels for PIO access
- sdhci-msm: Improve card detection handling
- sdhci-msm: Add support voltage pad switching"
* tag 'mmc-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (104 commits)
mmc: renesas_sdhi: really fix WP logic regressions
mmc: mvsdio: Enable MMC_CAP_ERASE
mmc: mvsdio: Respect card busy time out from mmc core
mmc: sdhci-msm: Remove NO_CARD_NO_RESET quirk
mmc: sunxi: Use ifdef rather than __maybe_unused
mmc: mxmmc: Use ifdef rather than __maybe_unused
mmc: mxmmc: include linux/highmem.h
mmc: sunxi: mark PM functions as __maybe_unused
mmc: Throttle calls to MMC_SEND_STATUS during mmc_do_erase()
mmc: au1xmmc: handle highmem pages
mmc: Allow non-sleeping GPIO cd
mmc: sdhci-*: Don't emit error msg if sdhci_add_host() fails
mmc: sd: Define name for default speed dtr
mmc: core: Move calls to ->prepare_hs400_tuning() closer to mmc code
mmc: sdhci-xenon: use match_string() helper
mmc: wbsd: handle highmem pages
mmc: ushc: handle highmem pages
mmc: mxcmmc: handle highmem pages
mmc: atmel-mci: use sg_copy_{from,to}_buffer
mmc: android-goldfish: use sg_copy_{from,to}_buffer
...
66 files changed, 1382 insertions, 431 deletions
diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt index 50bf611a4d2c..13e70409e8ac 100644 --- a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt +++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt | |||
@@ -12,6 +12,7 @@ Required properties: | |||
12 | - "amlogic,meson-gxbb-mmc" | 12 | - "amlogic,meson-gxbb-mmc" |
13 | - "amlogic,meson-gxl-mmc" | 13 | - "amlogic,meson-gxl-mmc" |
14 | - "amlogic,meson-gxm-mmc" | 14 | - "amlogic,meson-gxm-mmc" |
15 | - "amlogic,meson-axg-mmc" | ||
15 | - clocks : A list of phandle + clock-specifier pairs for the clocks listed in clock-names. | 16 | - clocks : A list of phandle + clock-specifier pairs for the clocks listed in clock-names. |
16 | - clock-names: Should contain the following: | 17 | - clock-names: Should contain the following: |
17 | "core" - Main peripheral bus clock | 18 | "core" - Main peripheral bus clock |
@@ -19,6 +20,7 @@ Required properties: | |||
19 | "clkin1" - Other parent clock of internal mux | 20 | "clkin1" - Other parent clock of internal mux |
20 | The driver has an internal mux clock which switches between clkin0 and clkin1 depending on the | 21 | The driver has an internal mux clock which switches between clkin0 and clkin1 depending on the |
21 | clock rate requested by the MMC core. | 22 | clock rate requested by the MMC core. |
23 | - resets : phandle of the internal reset line | ||
22 | 24 | ||
23 | Example: | 25 | Example: |
24 | 26 | ||
@@ -29,4 +31,5 @@ Example: | |||
29 | clocks = <&clkc CLKID_SD_EMMC_A>, <&xtal>, <&clkc CLKID_FCLK_DIV2>; | 31 | clocks = <&clkc CLKID_SD_EMMC_A>, <&xtal>, <&clkc CLKID_FCLK_DIV2>; |
30 | clock-names = "core", "clkin0", "clkin1"; | 32 | clock-names = "core", "clkin0", "clkin1"; |
31 | pinctrl-0 = <&emmc_pins>; | 33 | pinctrl-0 = <&emmc_pins>; |
34 | resets = <&reset RESET_SD_EMMC_A>; | ||
32 | }; | 35 | }; |
diff --git a/Documentation/devicetree/bindings/mmc/bluefield-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/bluefield-dw-mshc.txt new file mode 100644 index 000000000000..b0f0999ea1a9 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/bluefield-dw-mshc.txt | |||
@@ -0,0 +1,29 @@ | |||
1 | * Mellanox Bluefield SoC specific extensions to the Synopsys Designware | ||
2 | Mobile Storage Host Controller | ||
3 | |||
4 | Read synopsys-dw-mshc.txt for more details | ||
5 | |||
6 | The Synopsys designware mobile storage host controller is used to interface | ||
7 | a SoC with storage medium such as eMMC or SD/MMC cards. This file documents | ||
8 | differences between the core Synopsys dw mshc controller properties described | ||
9 | by synopsys-dw-mshc.txt and the properties used by the Mellanox Bluefield SoC | ||
10 | specific extensions to the Synopsys Designware Mobile Storage Host Controller. | ||
11 | |||
12 | Required Properties: | ||
13 | |||
14 | * compatible: should be one of the following. | ||
15 | - "mellanox,bluefield-dw-mshc": for controllers with Mellanox Bluefield SoC | ||
16 | specific extensions. | ||
17 | |||
18 | Example: | ||
19 | |||
20 | /* Mellanox Bluefield SoC MMC */ | ||
21 | mmc@6008000 { | ||
22 | compatible = "mellanox,bluefield-dw-mshc"; | ||
23 | reg = <0x6008000 0x400>; | ||
24 | interrupts = <32>; | ||
25 | fifo-depth = <0x100>; | ||
26 | clock-frequency = <24000000>; | ||
27 | bus-width = <8>; | ||
28 | cap-mmc-highspeed; | ||
29 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/jz4740.txt b/Documentation/devicetree/bindings/mmc/jz4740.txt new file mode 100644 index 000000000000..7cd8c432d7c8 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/jz4740.txt | |||
@@ -0,0 +1,38 @@ | |||
1 | * Ingenic JZ47xx MMC controllers | ||
2 | |||
3 | This file documents the device tree properties used for the MMC controller in | ||
4 | Ingenic JZ4740/JZ4780 SoCs. These are in addition to the core MMC properties | ||
5 | described in mmc.txt. | ||
6 | |||
7 | Required properties: | ||
8 | - compatible: Should be one of the following: | ||
9 | - "ingenic,jz4740-mmc" for the JZ4740 | ||
10 | - "ingenic,jz4780-mmc" for the JZ4780 | ||
11 | - reg: Should contain the MMC controller registers location and length. | ||
12 | - interrupts: Should contain the interrupt specifier of the MMC controller. | ||
13 | - clocks: Clock for the MMC controller. | ||
14 | |||
15 | Optional properties: | ||
16 | - dmas: List of DMA specifiers with the controller specific format | ||
17 | as described in the generic DMA client binding. A tx and rx | ||
18 | specifier is required. | ||
19 | - dma-names: RX and TX DMA request names. | ||
20 | Should be "rx" and "tx", in that order. | ||
21 | |||
22 | For additional details on DMA client bindings see ../dma/dma.txt. | ||
23 | |||
24 | Example: | ||
25 | |||
26 | mmc0: mmc@13450000 { | ||
27 | compatible = "ingenic,jz4780-mmc"; | ||
28 | reg = <0x13450000 0x1000>; | ||
29 | |||
30 | interrupt-parent = <&intc>; | ||
31 | interrupts = <37>; | ||
32 | |||
33 | clocks = <&cgu JZ4780_CLK_MSC0>; | ||
34 | clock-names = "mmc"; | ||
35 | |||
36 | dmas = <&dma JZ4780_DMA_MSC0_RX 0xffffffff>, <&dma JZ4780_DMA_MSC0_TX 0xffffffff>; | ||
37 | dma-names = "rx", "tx"; | ||
38 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index 467cd7b147ce..f5a0923b34ca 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt | |||
@@ -19,6 +19,8 @@ Optional properties: | |||
19 | - wp-gpios: Specify GPIOs for write protection, see gpio binding | 19 | - wp-gpios: Specify GPIOs for write protection, see gpio binding |
20 | - cd-inverted: when present, polarity on the CD line is inverted. See the note | 20 | - cd-inverted: when present, polarity on the CD line is inverted. See the note |
21 | below for the case, when a GPIO is used for the CD line | 21 | below for the case, when a GPIO is used for the CD line |
22 | - cd-debounce-delay-ms: Set delay time before detecting card after card insert interrupt. | ||
23 | It's only valid when cd-gpios is present. | ||
22 | - wp-inverted: when present, polarity on the WP line is inverted. See the note | 24 | - wp-inverted: when present, polarity on the WP line is inverted. See the note |
23 | below for the case, when a GPIO is used for the WP line | 25 | below for the case, when a GPIO is used for the WP line |
24 | - disable-wp: When set no physical WP line is present. This property should | 26 | - disable-wp: When set no physical WP line is present. This property should |
@@ -56,6 +58,10 @@ Optional properties: | |||
56 | - fixed-emmc-driver-type: for non-removable eMMC, enforce this driver type. | 58 | - fixed-emmc-driver-type: for non-removable eMMC, enforce this driver type. |
57 | The value <n> is the driver type as specified in the eMMC specification | 59 | The value <n> is the driver type as specified in the eMMC specification |
58 | (table 206 in spec version 5.1). | 60 | (table 206 in spec version 5.1). |
61 | - post-power-on-delay-ms : It was invented for MMC pwrseq-simple which could | ||
62 | be referred to mmc-pwrseq-simple.txt. But now it's reused as a tunable delay | ||
63 | waiting for I/O signalling and card power supply to be stable, regardless of | ||
64 | whether pwrseq-simple is used. Default to 10ms if no available. | ||
59 | 65 | ||
60 | *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line | 66 | *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line |
61 | polarity properties, we have to fix the meaning of the "normal" and "inverted" | 67 | polarity properties, we have to fix the meaning of the "normal" and "inverted" |
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt index 51775a372c06..393848c2138e 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt | |||
@@ -4,7 +4,14 @@ Refer to mmc.txt for standard MMC bindings. | |||
4 | 4 | ||
5 | Required properties: | 5 | Required properties: |
6 | - compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers | 6 | - compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers |
7 | Should be "ti,k2g-sdhci" for K2G | ||
7 | - ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1 | 8 | - ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1 |
9 | (Not required for K2G). | ||
10 | - pinctrl-names: Should be subset of "default", "hs", "sdr12", "sdr25", "sdr50", | ||
11 | "ddr50-rev11", "sdr104-rev11", "ddr50", "sdr104", | ||
12 | "ddr_1_8v-rev11", "ddr_1_8v" or "ddr_3_3v", "hs200_1_8v-rev11", | ||
13 | "hs200_1_8v", | ||
14 | - pinctrl-<n> : Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt | ||
8 | 15 | ||
9 | Example: | 16 | Example: |
10 | mmc1: mmc@4809c000 { | 17 | mmc1: mmc@4809c000 { |
diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt index 2d5287eeed95..ee978c95189d 100644 --- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt +++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt | |||
@@ -26,6 +26,8 @@ Required properties: | |||
26 | "renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC | 26 | "renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC |
27 | "renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC | 27 | "renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC |
28 | "renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC | 28 | "renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC |
29 | "renesas,sdhi-r8a77965" - SDHI IP on R8A77965 SoC | ||
30 | "renesas,sdhi-r8a77980" - SDHI IP on R8A77980 SoC | ||
29 | "renesas,sdhi-r8a77995" - SDHI IP on R8A77995 SoC | 31 | "renesas,sdhi-r8a77995" - SDHI IP on R8A77995 SoC |
30 | "renesas,sdhi-shmobile" - a generic sh-mobile SDHI controller | 32 | "renesas,sdhi-shmobile" - a generic sh-mobile SDHI controller |
31 | "renesas,rcar-gen1-sdhi" - a generic R-Car Gen1 SDHI controller | 33 | "renesas,rcar-gen1-sdhi" - a generic R-Car Gen1 SDHI controller |
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts index 38078594cf97..50cff3cbcc6d 100644 --- a/arch/mips/boot/dts/ingenic/ci20.dts +++ b/arch/mips/boot/dts/ingenic/ci20.dts | |||
@@ -36,6 +36,28 @@ | |||
36 | clock-frequency = <48000000>; | 36 | clock-frequency = <48000000>; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | &mmc0 { | ||
40 | status = "okay"; | ||
41 | |||
42 | bus-width = <4>; | ||
43 | max-frequency = <50000000>; | ||
44 | |||
45 | pinctrl-names = "default"; | ||
46 | pinctrl-0 = <&pins_mmc0>; | ||
47 | |||
48 | cd-gpios = <&gpf 20 GPIO_ACTIVE_LOW>; | ||
49 | }; | ||
50 | |||
51 | &mmc1 { | ||
52 | status = "okay"; | ||
53 | |||
54 | bus-width = <4>; | ||
55 | max-frequency = <50000000>; | ||
56 | |||
57 | pinctrl-names = "default"; | ||
58 | pinctrl-0 = <&pins_mmc1>; | ||
59 | }; | ||
60 | |||
39 | &uart0 { | 61 | &uart0 { |
40 | status = "okay"; | 62 | status = "okay"; |
41 | 63 | ||
@@ -203,4 +225,16 @@ | |||
203 | groups = "nemc-cs6"; | 225 | groups = "nemc-cs6"; |
204 | bias-disable; | 226 | bias-disable; |
205 | }; | 227 | }; |
228 | |||
229 | pins_mmc0: mmc0 { | ||
230 | function = "mmc0"; | ||
231 | groups = "mmc0-1bit-e", "mmc0-4bit-e"; | ||
232 | bias-disable; | ||
233 | }; | ||
234 | |||
235 | pins_mmc1: mmc1 { | ||
236 | function = "mmc1"; | ||
237 | groups = "mmc1-1bit-d", "mmc1-4bit-d"; | ||
238 | bias-disable; | ||
239 | }; | ||
206 | }; | 240 | }; |
diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi index 9b5794667aee..b72e53bb7292 100644 --- a/arch/mips/boot/dts/ingenic/jz4780.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi | |||
@@ -1,5 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <dt-bindings/clock/jz4780-cgu.h> | 2 | #include <dt-bindings/clock/jz4780-cgu.h> |
3 | #include <dt-bindings/dma/jz4780-dma.h> | ||
3 | 4 | ||
4 | / { | 5 | / { |
5 | #address-cells = <1>; | 6 | #address-cells = <1>; |
@@ -241,6 +242,57 @@ | |||
241 | status = "disabled"; | 242 | status = "disabled"; |
242 | }; | 243 | }; |
243 | 244 | ||
245 | dma: dma@13420000 { | ||
246 | compatible = "ingenic,jz4780-dma"; | ||
247 | reg = <0x13420000 0x10000>; | ||
248 | #dma-cells = <2>; | ||
249 | |||
250 | interrupt-parent = <&intc>; | ||
251 | interrupts = <10>; | ||
252 | |||
253 | clocks = <&cgu JZ4780_CLK_PDMA>; | ||
254 | }; | ||
255 | |||
256 | mmc0: mmc@13450000 { | ||
257 | compatible = "ingenic,jz4780-mmc"; | ||
258 | reg = <0x13450000 0x1000>; | ||
259 | |||
260 | interrupt-parent = <&intc>; | ||
261 | interrupts = <37>; | ||
262 | |||
263 | clocks = <&cgu JZ4780_CLK_MSC0>; | ||
264 | clock-names = "mmc"; | ||
265 | |||
266 | cap-sd-highspeed; | ||
267 | cap-mmc-highspeed; | ||
268 | cap-sdio-irq; | ||
269 | dmas = <&dma JZ4780_DMA_MSC0_RX 0xffffffff>, | ||
270 | <&dma JZ4780_DMA_MSC0_TX 0xffffffff>; | ||
271 | dma-names = "rx", "tx"; | ||
272 | |||
273 | status = "disabled"; | ||
274 | }; | ||
275 | |||
276 | mmc1: mmc@13460000 { | ||
277 | compatible = "ingenic,jz4780-mmc"; | ||
278 | reg = <0x13460000 0x1000>; | ||
279 | |||
280 | interrupt-parent = <&intc>; | ||
281 | interrupts = <36>; | ||
282 | |||
283 | clocks = <&cgu JZ4780_CLK_MSC1>; | ||
284 | clock-names = "mmc"; | ||
285 | |||
286 | cap-sd-highspeed; | ||
287 | cap-mmc-highspeed; | ||
288 | cap-sdio-irq; | ||
289 | dmas = <&dma JZ4780_DMA_MSC1_RX 0xffffffff>, | ||
290 | <&dma JZ4780_DMA_MSC1_TX 0xffffffff>; | ||
291 | dma-names = "rx", "tx"; | ||
292 | |||
293 | status = "disabled"; | ||
294 | }; | ||
295 | |||
244 | bch: bch@134d0000 { | 296 | bch: bch@134d0000 { |
245 | compatible = "ingenic,jz4780-bch"; | 297 | compatible = "ingenic,jz4780-bch"; |
246 | reg = <0x134d0000 0x10000>; | 298 | reg = <0x134d0000 0x10000>; |
diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig index b5f4ad8f2c45..be23fd25eeaa 100644 --- a/arch/mips/configs/ci20_defconfig +++ b/arch/mips/configs/ci20_defconfig | |||
@@ -104,10 +104,14 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y | |||
104 | # CONFIG_HID is not set | 104 | # CONFIG_HID is not set |
105 | # CONFIG_USB_SUPPORT is not set | 105 | # CONFIG_USB_SUPPORT is not set |
106 | CONFIG_MMC=y | 106 | CONFIG_MMC=y |
107 | CONFIG_MMC_JZ4740=y | ||
107 | CONFIG_RTC_CLASS=y | 108 | CONFIG_RTC_CLASS=y |
108 | CONFIG_RTC_DRV_JZ4740=y | 109 | CONFIG_RTC_DRV_JZ4740=y |
110 | CONFIG_DMADEVICES=y | ||
111 | CONFIG_DMA_JZ4780=y | ||
109 | # CONFIG_IOMMU_SUPPORT is not set | 112 | # CONFIG_IOMMU_SUPPORT is not set |
110 | CONFIG_MEMORY=y | 113 | CONFIG_MEMORY=y |
114 | CONFIG_EXT4_FS=y | ||
111 | # CONFIG_DNOTIFY is not set | 115 | # CONFIG_DNOTIFY is not set |
112 | CONFIG_PROC_KCORE=y | 116 | CONFIG_PROC_KCORE=y |
113 | # CONFIG_PROC_PAGE_MONITOR is not set | 117 | # CONFIG_PROC_PAGE_MONITOR is not set |
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index d89e17829527..a0b9102c4c6e 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c | |||
@@ -2351,7 +2351,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
2351 | set_disk_ro(md->disk, md->read_only || default_ro); | 2351 | set_disk_ro(md->disk, md->read_only || default_ro); |
2352 | md->disk->flags = GENHD_FL_EXT_DEVT; | 2352 | md->disk->flags = GENHD_FL_EXT_DEVT; |
2353 | if (area_type & (MMC_BLK_DATA_AREA_RPMB | MMC_BLK_DATA_AREA_BOOT)) | 2353 | if (area_type & (MMC_BLK_DATA_AREA_RPMB | MMC_BLK_DATA_AREA_BOOT)) |
2354 | md->disk->flags |= GENHD_FL_NO_PART_SCAN; | 2354 | md->disk->flags |= GENHD_FL_NO_PART_SCAN |
2355 | | GENHD_FL_SUPPRESS_PARTITION_INFO; | ||
2355 | 2356 | ||
2356 | /* | 2357 | /* |
2357 | * As discussed on lkml, GENHD_FL_REMOVABLE should: | 2358 | * As discussed on lkml, GENHD_FL_REMOVABLE should: |
@@ -2965,9 +2966,11 @@ static void mmc_blk_remove(struct mmc_card *card) | |||
2965 | mmc_blk_remove_debugfs(card, md); | 2966 | mmc_blk_remove_debugfs(card, md); |
2966 | mmc_blk_remove_parts(card, md); | 2967 | mmc_blk_remove_parts(card, md); |
2967 | pm_runtime_get_sync(&card->dev); | 2968 | pm_runtime_get_sync(&card->dev); |
2968 | mmc_claim_host(card->host); | 2969 | if (md->part_curr != md->part_type) { |
2969 | mmc_blk_part_switch(card, md->part_type); | 2970 | mmc_claim_host(card->host); |
2970 | mmc_release_host(card->host); | 2971 | mmc_blk_part_switch(card, md->part_type); |
2972 | mmc_release_host(card->host); | ||
2973 | } | ||
2971 | if (card->type != MMC_TYPE_SD_COMBO) | 2974 | if (card->type != MMC_TYPE_SD_COMBO) |
2972 | pm_runtime_disable(&card->dev); | 2975 | pm_runtime_disable(&card->dev); |
2973 | pm_runtime_put_noidle(&card->dev); | 2976 | pm_runtime_put_noidle(&card->dev); |
diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index 9c821eedd156..1170feb8f969 100644 --- a/drivers/mmc/core/card.h +++ b/drivers/mmc/core/card.h | |||
@@ -149,6 +149,12 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) | |||
149 | card->quirks &= ~data; | 149 | card->quirks &= ~data; |
150 | } | 150 | } |
151 | 151 | ||
152 | static inline void __maybe_unused add_limit_rate_quirk(struct mmc_card *card, | ||
153 | int data) | ||
154 | { | ||
155 | card->quirk_max_rate = data; | ||
156 | } | ||
157 | |||
152 | /* | 158 | /* |
153 | * Quirk add/remove for MMC products. | 159 | * Quirk add/remove for MMC products. |
154 | */ | 160 | */ |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 121ce50b6d5e..281826d1fcca 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -50,9 +50,6 @@ | |||
50 | #include "sd_ops.h" | 50 | #include "sd_ops.h" |
51 | #include "sdio_ops.h" | 51 | #include "sdio_ops.h" |
52 | 52 | ||
53 | /* If the device is not responding */ | ||
54 | #define MMC_CORE_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ | ||
55 | |||
56 | /* The max erase timeout, used when host->max_busy_timeout isn't specified */ | 53 | /* The max erase timeout, used when host->max_busy_timeout isn't specified */ |
57 | #define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */ | 54 | #define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */ |
58 | 55 | ||
@@ -1484,6 +1481,17 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) | |||
1484 | 1481 | ||
1485 | } | 1482 | } |
1486 | 1483 | ||
1484 | void mmc_set_initial_signal_voltage(struct mmc_host *host) | ||
1485 | { | ||
1486 | /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ | ||
1487 | if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330)) | ||
1488 | dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n"); | ||
1489 | else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)) | ||
1490 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n"); | ||
1491 | else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120)) | ||
1492 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n"); | ||
1493 | } | ||
1494 | |||
1487 | int mmc_host_set_uhs_voltage(struct mmc_host *host) | 1495 | int mmc_host_set_uhs_voltage(struct mmc_host *host) |
1488 | { | 1496 | { |
1489 | u32 clock; | 1497 | u32 clock; |
@@ -1646,19 +1654,13 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) | |||
1646 | /* Set initial state and call mmc_set_ios */ | 1654 | /* Set initial state and call mmc_set_ios */ |
1647 | mmc_set_initial_state(host); | 1655 | mmc_set_initial_state(host); |
1648 | 1656 | ||
1649 | /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ | 1657 | mmc_set_initial_signal_voltage(host); |
1650 | if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330)) | ||
1651 | dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n"); | ||
1652 | else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)) | ||
1653 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n"); | ||
1654 | else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120)) | ||
1655 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n"); | ||
1656 | 1658 | ||
1657 | /* | 1659 | /* |
1658 | * This delay should be sufficient to allow the power supply | 1660 | * This delay should be sufficient to allow the power supply |
1659 | * to reach the minimum voltage. | 1661 | * to reach the minimum voltage. |
1660 | */ | 1662 | */ |
1661 | mmc_delay(10); | 1663 | mmc_delay(host->ios.power_delay_ms); |
1662 | 1664 | ||
1663 | mmc_pwrseq_post_power_on(host); | 1665 | mmc_pwrseq_post_power_on(host); |
1664 | 1666 | ||
@@ -1671,7 +1673,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) | |||
1671 | * This delay must be at least 74 clock sizes, or 1 ms, or the | 1673 | * This delay must be at least 74 clock sizes, or 1 ms, or the |
1672 | * time required to reach a stable voltage. | 1674 | * time required to reach a stable voltage. |
1673 | */ | 1675 | */ |
1674 | mmc_delay(10); | 1676 | mmc_delay(host->ios.power_delay_ms); |
1675 | } | 1677 | } |
1676 | 1678 | ||
1677 | void mmc_power_off(struct mmc_host *host) | 1679 | void mmc_power_off(struct mmc_host *host) |
@@ -1967,6 +1969,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, | |||
1967 | unsigned int qty = 0, busy_timeout = 0; | 1969 | unsigned int qty = 0, busy_timeout = 0; |
1968 | bool use_r1b_resp = false; | 1970 | bool use_r1b_resp = false; |
1969 | unsigned long timeout; | 1971 | unsigned long timeout; |
1972 | int loop_udelay=64, udelay_max=32768; | ||
1970 | int err; | 1973 | int err; |
1971 | 1974 | ||
1972 | mmc_retune_hold(card->host); | 1975 | mmc_retune_hold(card->host); |
@@ -2091,9 +2094,15 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, | |||
2091 | err = -EIO; | 2094 | err = -EIO; |
2092 | goto out; | 2095 | goto out; |
2093 | } | 2096 | } |
2097 | if ((cmd.resp[0] & R1_READY_FOR_DATA) && | ||
2098 | R1_CURRENT_STATE(cmd.resp[0]) != R1_STATE_PRG) | ||
2099 | break; | ||
2100 | |||
2101 | usleep_range(loop_udelay, loop_udelay*2); | ||
2102 | if (loop_udelay < udelay_max) | ||
2103 | loop_udelay *= 2; | ||
2104 | } while (1); | ||
2094 | 2105 | ||
2095 | } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || | ||
2096 | (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG)); | ||
2097 | out: | 2106 | out: |
2098 | mmc_retune_release(card->host); | 2107 | mmc_retune_release(card->host); |
2099 | return err; | 2108 | return err; |
@@ -2435,22 +2444,46 @@ int mmc_hw_reset(struct mmc_host *host) | |||
2435 | return -EINVAL; | 2444 | return -EINVAL; |
2436 | 2445 | ||
2437 | mmc_bus_get(host); | 2446 | mmc_bus_get(host); |
2438 | if (!host->bus_ops || host->bus_dead || !host->bus_ops->reset) { | 2447 | if (!host->bus_ops || host->bus_dead || !host->bus_ops->hw_reset) { |
2439 | mmc_bus_put(host); | 2448 | mmc_bus_put(host); |
2440 | return -EOPNOTSUPP; | 2449 | return -EOPNOTSUPP; |
2441 | } | 2450 | } |
2442 | 2451 | ||
2443 | ret = host->bus_ops->reset(host); | 2452 | ret = host->bus_ops->hw_reset(host); |
2444 | mmc_bus_put(host); | 2453 | mmc_bus_put(host); |
2445 | 2454 | ||
2446 | if (ret) | 2455 | if (ret) |
2447 | pr_warn("%s: tried to reset card, got error %d\n", | 2456 | pr_warn("%s: tried to HW reset card, got error %d\n", |
2448 | mmc_hostname(host), ret); | 2457 | mmc_hostname(host), ret); |
2449 | 2458 | ||
2450 | return ret; | 2459 | return ret; |
2451 | } | 2460 | } |
2452 | EXPORT_SYMBOL(mmc_hw_reset); | 2461 | EXPORT_SYMBOL(mmc_hw_reset); |
2453 | 2462 | ||
2463 | int mmc_sw_reset(struct mmc_host *host) | ||
2464 | { | ||
2465 | int ret; | ||
2466 | |||
2467 | if (!host->card) | ||
2468 | return -EINVAL; | ||
2469 | |||
2470 | mmc_bus_get(host); | ||
2471 | if (!host->bus_ops || host->bus_dead || !host->bus_ops->sw_reset) { | ||
2472 | mmc_bus_put(host); | ||
2473 | return -EOPNOTSUPP; | ||
2474 | } | ||
2475 | |||
2476 | ret = host->bus_ops->sw_reset(host); | ||
2477 | mmc_bus_put(host); | ||
2478 | |||
2479 | if (ret) | ||
2480 | pr_warn("%s: tried to SW reset card, got error %d\n", | ||
2481 | mmc_hostname(host), ret); | ||
2482 | |||
2483 | return ret; | ||
2484 | } | ||
2485 | EXPORT_SYMBOL(mmc_sw_reset); | ||
2486 | |||
2454 | static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) | 2487 | static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) |
2455 | { | 2488 | { |
2456 | host->f_init = freq; | 2489 | host->f_init = freq; |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index d6303d69071b..9d8f09ac0821 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -32,7 +32,8 @@ struct mmc_bus_ops { | |||
32 | int (*power_restore)(struct mmc_host *); | 32 | int (*power_restore)(struct mmc_host *); |
33 | int (*alive)(struct mmc_host *); | 33 | int (*alive)(struct mmc_host *); |
34 | int (*shutdown)(struct mmc_host *); | 34 | int (*shutdown)(struct mmc_host *); |
35 | int (*reset)(struct mmc_host *); | 35 | int (*hw_reset)(struct mmc_host *); |
36 | int (*sw_reset)(struct mmc_host *); | ||
36 | }; | 37 | }; |
37 | 38 | ||
38 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | 39 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); |
@@ -51,6 +52,7 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); | |||
51 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr); | 52 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr); |
52 | int mmc_host_set_uhs_voltage(struct mmc_host *host); | 53 | int mmc_host_set_uhs_voltage(struct mmc_host *host); |
53 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); | 54 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); |
55 | void mmc_set_initial_signal_voltage(struct mmc_host *host); | ||
54 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); | 56 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); |
55 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); | 57 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); |
56 | int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr, | 58 | int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr, |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 64b03d6eaf18..abf9e884386c 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -143,9 +143,6 @@ int mmc_retune(struct mmc_host *host) | |||
143 | goto out; | 143 | goto out; |
144 | 144 | ||
145 | return_to_hs400 = true; | 145 | return_to_hs400 = true; |
146 | |||
147 | if (host->ops->prepare_hs400_tuning) | ||
148 | host->ops->prepare_hs400_tuning(host, &host->ios); | ||
149 | } | 146 | } |
150 | 147 | ||
151 | err = mmc_execute_tuning(host->card); | 148 | err = mmc_execute_tuning(host->card); |
@@ -179,7 +176,7 @@ static void mmc_retune_timer(struct timer_list *t) | |||
179 | int mmc_of_parse(struct mmc_host *host) | 176 | int mmc_of_parse(struct mmc_host *host) |
180 | { | 177 | { |
181 | struct device *dev = host->parent; | 178 | struct device *dev = host->parent; |
182 | u32 bus_width, drv_type; | 179 | u32 bus_width, drv_type, cd_debounce_delay_ms; |
183 | int ret; | 180 | int ret; |
184 | bool cd_cap_invert, cd_gpio_invert = false; | 181 | bool cd_cap_invert, cd_gpio_invert = false; |
185 | bool ro_cap_invert, ro_gpio_invert = false; | 182 | bool ro_cap_invert, ro_gpio_invert = false; |
@@ -230,11 +227,16 @@ int mmc_of_parse(struct mmc_host *host) | |||
230 | } else { | 227 | } else { |
231 | cd_cap_invert = device_property_read_bool(dev, "cd-inverted"); | 228 | cd_cap_invert = device_property_read_bool(dev, "cd-inverted"); |
232 | 229 | ||
230 | if (device_property_read_u32(dev, "cd-debounce-delay-ms", | ||
231 | &cd_debounce_delay_ms)) | ||
232 | cd_debounce_delay_ms = 200; | ||
233 | |||
233 | if (device_property_read_bool(dev, "broken-cd")) | 234 | if (device_property_read_bool(dev, "broken-cd")) |
234 | host->caps |= MMC_CAP_NEEDS_POLL; | 235 | host->caps |= MMC_CAP_NEEDS_POLL; |
235 | 236 | ||
236 | ret = mmc_gpiod_request_cd(host, "cd", 0, true, | 237 | ret = mmc_gpiod_request_cd(host, "cd", 0, true, |
237 | 0, &cd_gpio_invert); | 238 | cd_debounce_delay_ms, |
239 | &cd_gpio_invert); | ||
238 | if (!ret) | 240 | if (!ret) |
239 | dev_info(host->parent, "Got CD GPIO\n"); | 241 | dev_info(host->parent, "Got CD GPIO\n"); |
240 | else if (ret != -ENOENT && ret != -ENOSYS) | 242 | else if (ret != -ENOENT && ret != -ENOSYS) |
@@ -338,6 +340,9 @@ int mmc_of_parse(struct mmc_host *host) | |||
338 | host->dsr_req = 0; | 340 | host->dsr_req = 0; |
339 | } | 341 | } |
340 | 342 | ||
343 | device_property_read_u32(dev, "post-power-on-delay-ms", | ||
344 | &host->ios.power_delay_ms); | ||
345 | |||
341 | return mmc_pwrseq_alloc(host); | 346 | return mmc_pwrseq_alloc(host); |
342 | } | 347 | } |
343 | 348 | ||
@@ -403,6 +408,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
403 | host->max_blk_count = PAGE_SIZE / 512; | 408 | host->max_blk_count = PAGE_SIZE / 512; |
404 | 409 | ||
405 | host->fixed_drv_type = -EINVAL; | 410 | host->fixed_drv_type = -EINVAL; |
411 | host->ios.power_delay_ms = 10; | ||
406 | 412 | ||
407 | return host; | 413 | return host; |
408 | } | 414 | } |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 6f8ebd6caa4c..4466f5de54d4 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -1282,6 +1282,10 @@ int mmc_hs400_to_hs200(struct mmc_card *card) | |||
1282 | 1282 | ||
1283 | mmc_set_bus_speed(card); | 1283 | mmc_set_bus_speed(card); |
1284 | 1284 | ||
1285 | /* Prepare tuning for HS400 mode. */ | ||
1286 | if (host->ops->prepare_hs400_tuning) | ||
1287 | host->ops->prepare_hs400_tuning(host, &host->ios); | ||
1288 | |||
1285 | return 0; | 1289 | return 0; |
1286 | 1290 | ||
1287 | out_err: | 1291 | out_err: |
@@ -1830,6 +1834,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1830 | } | 1834 | } |
1831 | } | 1835 | } |
1832 | 1836 | ||
1837 | if (host->caps2 & MMC_CAP2_AVOID_3_3V && | ||
1838 | host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) { | ||
1839 | pr_err("%s: Host failed to negotiate down from 3.3V\n", | ||
1840 | mmc_hostname(host)); | ||
1841 | err = -EINVAL; | ||
1842 | goto free_card; | ||
1843 | } | ||
1844 | |||
1833 | if (!oldcard) | 1845 | if (!oldcard) |
1834 | host->card = card; | 1846 | host->card = card; |
1835 | 1847 | ||
@@ -2117,7 +2129,7 @@ static int mmc_can_reset(struct mmc_card *card) | |||
2117 | return 1; | 2129 | return 1; |
2118 | } | 2130 | } |
2119 | 2131 | ||
2120 | static int mmc_reset(struct mmc_host *host) | 2132 | static int _mmc_hw_reset(struct mmc_host *host) |
2121 | { | 2133 | { |
2122 | struct mmc_card *card = host->card; | 2134 | struct mmc_card *card = host->card; |
2123 | 2135 | ||
@@ -2151,7 +2163,7 @@ static const struct mmc_bus_ops mmc_ops = { | |||
2151 | .runtime_resume = mmc_runtime_resume, | 2163 | .runtime_resume = mmc_runtime_resume, |
2152 | .alive = mmc_alive, | 2164 | .alive = mmc_alive, |
2153 | .shutdown = mmc_shutdown, | 2165 | .shutdown = mmc_shutdown, |
2154 | .reset = mmc_reset, | 2166 | .hw_reset = _mmc_hw_reset, |
2155 | }; | 2167 | }; |
2156 | 2168 | ||
2157 | /* | 2169 | /* |
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c index 13ef162cf066..a8b9fee4d62a 100644 --- a/drivers/mmc/core/pwrseq_simple.c +++ b/drivers/mmc/core/pwrseq_simple.c | |||
@@ -40,14 +40,18 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, | |||
40 | struct gpio_descs *reset_gpios = pwrseq->reset_gpios; | 40 | struct gpio_descs *reset_gpios = pwrseq->reset_gpios; |
41 | 41 | ||
42 | if (!IS_ERR(reset_gpios)) { | 42 | if (!IS_ERR(reset_gpios)) { |
43 | int i; | 43 | int i, *values; |
44 | int values[reset_gpios->ndescs]; | 44 | int nvalues = reset_gpios->ndescs; |
45 | 45 | ||
46 | for (i = 0; i < reset_gpios->ndescs; i++) | 46 | values = kmalloc_array(nvalues, sizeof(int), GFP_KERNEL); |
47 | if (!values) | ||
48 | return; | ||
49 | |||
50 | for (i = 0; i < nvalues; i++) | ||
47 | values[i] = value; | 51 | values[i] = value; |
48 | 52 | ||
49 | gpiod_set_array_value_cansleep( | 53 | gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc, values); |
50 | reset_gpios->ndescs, reset_gpios->desc, values); | 54 | kfree(values); |
51 | } | 55 | } |
52 | } | 56 | } |
53 | 57 | ||
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index 5153577754f0..dd2f73af8f2c 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h | |||
@@ -132,6 +132,9 @@ static const struct mmc_fixup sdio_fixup_methods[] = { | |||
132 | SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0, | 132 | SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0, |
133 | add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING), | 133 | add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING), |
134 | 134 | ||
135 | SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8887WLAN, | ||
136 | add_limit_rate_quirk, 150000000), | ||
137 | |||
135 | END_FIXUP | 138 | END_FIXUP |
136 | }; | 139 | }; |
137 | 140 | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index baf3d5da4ccb..d0d9f90e7cdf 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -1058,6 +1058,14 @@ retry: | |||
1058 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | 1058 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); |
1059 | } | 1059 | } |
1060 | } | 1060 | } |
1061 | |||
1062 | if (host->caps2 & MMC_CAP2_AVOID_3_3V && | ||
1063 | host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) { | ||
1064 | pr_err("%s: Host failed to negotiate down from 3.3V\n", | ||
1065 | mmc_hostname(host)); | ||
1066 | err = -EINVAL; | ||
1067 | goto free_card; | ||
1068 | } | ||
1061 | done: | 1069 | done: |
1062 | host->card = card; | 1070 | host->card = card; |
1063 | return 0; | 1071 | return 0; |
@@ -1214,7 +1222,7 @@ static int mmc_sd_runtime_resume(struct mmc_host *host) | |||
1214 | return 0; | 1222 | return 0; |
1215 | } | 1223 | } |
1216 | 1224 | ||
1217 | static int mmc_sd_reset(struct mmc_host *host) | 1225 | static int mmc_sd_hw_reset(struct mmc_host *host) |
1218 | { | 1226 | { |
1219 | mmc_power_cycle(host, host->card->ocr); | 1227 | mmc_power_cycle(host, host->card->ocr); |
1220 | return mmc_sd_init_card(host, host->card->ocr, host->card); | 1228 | return mmc_sd_init_card(host, host->card->ocr, host->card); |
@@ -1229,7 +1237,7 @@ static const struct mmc_bus_ops mmc_sd_ops = { | |||
1229 | .resume = mmc_sd_resume, | 1237 | .resume = mmc_sd_resume, |
1230 | .alive = mmc_sd_alive, | 1238 | .alive = mmc_sd_alive, |
1231 | .shutdown = mmc_sd_suspend, | 1239 | .shutdown = mmc_sd_suspend, |
1232 | .reset = mmc_sd_reset, | 1240 | .hw_reset = mmc_sd_hw_reset, |
1233 | }; | 1241 | }; |
1234 | 1242 | ||
1235 | /* | 1243 | /* |
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index c599a628a387..a86490dbca70 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -444,6 +444,7 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) | |||
444 | unsigned int bus_speed, timing; | 444 | unsigned int bus_speed, timing; |
445 | int err; | 445 | int err; |
446 | unsigned char speed; | 446 | unsigned char speed; |
447 | unsigned int max_rate; | ||
447 | 448 | ||
448 | /* | 449 | /* |
449 | * If the host doesn't support any of the UHS-I modes, fallback on | 450 | * If the host doesn't support any of the UHS-I modes, fallback on |
@@ -500,9 +501,12 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) | |||
500 | if (err) | 501 | if (err) |
501 | return err; | 502 | return err; |
502 | 503 | ||
504 | max_rate = min_not_zero(card->quirk_max_rate, | ||
505 | card->sw_caps.uhs_max_dtr); | ||
506 | |||
503 | if (bus_speed) { | 507 | if (bus_speed) { |
504 | mmc_set_timing(card->host, timing); | 508 | mmc_set_timing(card->host, timing); |
505 | mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr); | 509 | mmc_set_clock(card->host, max_rate); |
506 | } | 510 | } |
507 | 511 | ||
508 | return 0; | 512 | return 0; |
@@ -788,6 +792,14 @@ try_again: | |||
788 | if (err) | 792 | if (err) |
789 | goto remove; | 793 | goto remove; |
790 | } | 794 | } |
795 | |||
796 | if (host->caps2 & MMC_CAP2_AVOID_3_3V && | ||
797 | host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) { | ||
798 | pr_err("%s: Host failed to negotiate down from 3.3V\n", | ||
799 | mmc_hostname(host)); | ||
800 | err = -EINVAL; | ||
801 | goto remove; | ||
802 | } | ||
791 | finish: | 803 | finish: |
792 | if (!oldcard) | 804 | if (!oldcard) |
793 | host->card = card; | 805 | host->card = card; |
@@ -801,6 +813,22 @@ err: | |||
801 | return err; | 813 | return err; |
802 | } | 814 | } |
803 | 815 | ||
816 | static int mmc_sdio_reinit_card(struct mmc_host *host, bool powered_resume) | ||
817 | { | ||
818 | int ret; | ||
819 | |||
820 | sdio_reset(host); | ||
821 | mmc_go_idle(host); | ||
822 | mmc_send_if_cond(host, host->card->ocr); | ||
823 | |||
824 | ret = mmc_send_io_op_cond(host, 0, NULL); | ||
825 | if (ret) | ||
826 | return ret; | ||
827 | |||
828 | return mmc_sdio_init_card(host, host->card->ocr, host->card, | ||
829 | powered_resume); | ||
830 | } | ||
831 | |||
804 | /* | 832 | /* |
805 | * Host is being removed. Free up the current card. | 833 | * Host is being removed. Free up the current card. |
806 | */ | 834 | */ |
@@ -948,14 +976,7 @@ static int mmc_sdio_resume(struct mmc_host *host) | |||
948 | 976 | ||
949 | /* No need to reinitialize powered-resumed nonremovable cards */ | 977 | /* No need to reinitialize powered-resumed nonremovable cards */ |
950 | if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { | 978 | if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { |
951 | sdio_reset(host); | 979 | err = mmc_sdio_reinit_card(host, mmc_card_keep_power(host)); |
952 | mmc_go_idle(host); | ||
953 | mmc_send_if_cond(host, host->card->ocr); | ||
954 | err = mmc_send_io_op_cond(host, 0, NULL); | ||
955 | if (!err) | ||
956 | err = mmc_sdio_init_card(host, host->card->ocr, | ||
957 | host->card, | ||
958 | mmc_card_keep_power(host)); | ||
959 | } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { | 980 | } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { |
960 | /* We may have switched to 1-bit mode during suspend */ | 981 | /* We may have switched to 1-bit mode during suspend */ |
961 | err = sdio_enable_4bit_bus(host->card); | 982 | err = sdio_enable_4bit_bus(host->card); |
@@ -978,8 +999,6 @@ static int mmc_sdio_power_restore(struct mmc_host *host) | |||
978 | { | 999 | { |
979 | int ret; | 1000 | int ret; |
980 | 1001 | ||
981 | mmc_claim_host(host); | ||
982 | |||
983 | /* | 1002 | /* |
984 | * Reset the card by performing the same steps that are taken by | 1003 | * Reset the card by performing the same steps that are taken by |
985 | * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. | 1004 | * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. |
@@ -997,20 +1016,12 @@ static int mmc_sdio_power_restore(struct mmc_host *host) | |||
997 | * | 1016 | * |
998 | */ | 1017 | */ |
999 | 1018 | ||
1000 | sdio_reset(host); | 1019 | mmc_claim_host(host); |
1001 | mmc_go_idle(host); | ||
1002 | mmc_send_if_cond(host, host->card->ocr); | ||
1003 | |||
1004 | ret = mmc_send_io_op_cond(host, 0, NULL); | ||
1005 | if (ret) | ||
1006 | goto out; | ||
1007 | 1020 | ||
1008 | ret = mmc_sdio_init_card(host, host->card->ocr, host->card, | 1021 | ret = mmc_sdio_reinit_card(host, mmc_card_keep_power(host)); |
1009 | mmc_card_keep_power(host)); | ||
1010 | if (!ret && host->sdio_irqs) | 1022 | if (!ret && host->sdio_irqs) |
1011 | mmc_signal_sdio_irq(host); | 1023 | mmc_signal_sdio_irq(host); |
1012 | 1024 | ||
1013 | out: | ||
1014 | mmc_release_host(host); | 1025 | mmc_release_host(host); |
1015 | 1026 | ||
1016 | return ret; | 1027 | return ret; |
@@ -1039,12 +1050,24 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host) | |||
1039 | return ret; | 1050 | return ret; |
1040 | } | 1051 | } |
1041 | 1052 | ||
1042 | static int mmc_sdio_reset(struct mmc_host *host) | 1053 | static int mmc_sdio_hw_reset(struct mmc_host *host) |
1043 | { | 1054 | { |
1044 | mmc_power_cycle(host, host->card->ocr); | 1055 | mmc_power_cycle(host, host->card->ocr); |
1045 | return mmc_sdio_power_restore(host); | 1056 | return mmc_sdio_power_restore(host); |
1046 | } | 1057 | } |
1047 | 1058 | ||
1059 | static int mmc_sdio_sw_reset(struct mmc_host *host) | ||
1060 | { | ||
1061 | mmc_set_clock(host, host->f_init); | ||
1062 | sdio_reset(host); | ||
1063 | mmc_go_idle(host); | ||
1064 | |||
1065 | mmc_set_initial_state(host); | ||
1066 | mmc_set_initial_signal_voltage(host); | ||
1067 | |||
1068 | return mmc_sdio_reinit_card(host, 0); | ||
1069 | } | ||
1070 | |||
1048 | static const struct mmc_bus_ops mmc_sdio_ops = { | 1071 | static const struct mmc_bus_ops mmc_sdio_ops = { |
1049 | .remove = mmc_sdio_remove, | 1072 | .remove = mmc_sdio_remove, |
1050 | .detect = mmc_sdio_detect, | 1073 | .detect = mmc_sdio_detect, |
@@ -1055,7 +1078,8 @@ static const struct mmc_bus_ops mmc_sdio_ops = { | |||
1055 | .runtime_resume = mmc_sdio_runtime_resume, | 1078 | .runtime_resume = mmc_sdio_runtime_resume, |
1056 | .power_restore = mmc_sdio_power_restore, | 1079 | .power_restore = mmc_sdio_power_restore, |
1057 | .alive = mmc_sdio_alive, | 1080 | .alive = mmc_sdio_alive, |
1058 | .reset = mmc_sdio_reset, | 1081 | .hw_reset = mmc_sdio_hw_reset, |
1082 | .sw_reset = mmc_sdio_sw_reset, | ||
1059 | }; | 1083 | }; |
1060 | 1084 | ||
1061 | 1085 | ||
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index 31f7dbb15668..ef05e0039378 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c | |||
@@ -28,15 +28,17 @@ struct mmc_gpio { | |||
28 | irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id); | 28 | irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id); |
29 | char *ro_label; | 29 | char *ro_label; |
30 | char cd_label[0]; | 30 | char cd_label[0]; |
31 | u32 cd_debounce_delay_ms; | ||
31 | }; | 32 | }; |
32 | 33 | ||
33 | static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) | 34 | static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) |
34 | { | 35 | { |
35 | /* Schedule a card detection after a debounce timeout */ | 36 | /* Schedule a card detection after a debounce timeout */ |
36 | struct mmc_host *host = dev_id; | 37 | struct mmc_host *host = dev_id; |
38 | struct mmc_gpio *ctx = host->slot.handler_priv; | ||
37 | 39 | ||
38 | host->trigger_card_event = true; | 40 | host->trigger_card_event = true; |
39 | mmc_detect_change(host, msecs_to_jiffies(200)); | 41 | mmc_detect_change(host, msecs_to_jiffies(ctx->cd_debounce_delay_ms)); |
40 | 42 | ||
41 | return IRQ_HANDLED; | 43 | return IRQ_HANDLED; |
42 | } | 44 | } |
@@ -49,6 +51,7 @@ int mmc_gpio_alloc(struct mmc_host *host) | |||
49 | 51 | ||
50 | if (ctx) { | 52 | if (ctx) { |
51 | ctx->ro_label = ctx->cd_label + len; | 53 | ctx->ro_label = ctx->cd_label + len; |
54 | ctx->cd_debounce_delay_ms = 200; | ||
52 | snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); | 55 | snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); |
53 | snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); | 56 | snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); |
54 | host->slot.handler_priv = ctx; | 57 | host->slot.handler_priv = ctx; |
@@ -76,15 +79,22 @@ EXPORT_SYMBOL(mmc_gpio_get_ro); | |||
76 | int mmc_gpio_get_cd(struct mmc_host *host) | 79 | int mmc_gpio_get_cd(struct mmc_host *host) |
77 | { | 80 | { |
78 | struct mmc_gpio *ctx = host->slot.handler_priv; | 81 | struct mmc_gpio *ctx = host->slot.handler_priv; |
82 | int cansleep; | ||
79 | 83 | ||
80 | if (!ctx || !ctx->cd_gpio) | 84 | if (!ctx || !ctx->cd_gpio) |
81 | return -ENOSYS; | 85 | return -ENOSYS; |
82 | 86 | ||
83 | if (ctx->override_cd_active_level) | 87 | cansleep = gpiod_cansleep(ctx->cd_gpio); |
84 | return !gpiod_get_raw_value_cansleep(ctx->cd_gpio) ^ | 88 | if (ctx->override_cd_active_level) { |
85 | !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH); | 89 | int value = cansleep ? |
90 | gpiod_get_raw_value_cansleep(ctx->cd_gpio) : | ||
91 | gpiod_get_raw_value(ctx->cd_gpio); | ||
92 | return !value ^ !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH); | ||
93 | } | ||
86 | 94 | ||
87 | return gpiod_get_value_cansleep(ctx->cd_gpio); | 95 | return cansleep ? |
96 | gpiod_get_value_cansleep(ctx->cd_gpio) : | ||
97 | gpiod_get_value(ctx->cd_gpio); | ||
88 | } | 98 | } |
89 | EXPORT_SYMBOL(mmc_gpio_get_cd); | 99 | EXPORT_SYMBOL(mmc_gpio_get_cd); |
90 | 100 | ||
@@ -261,7 +271,7 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, | |||
261 | if (debounce) { | 271 | if (debounce) { |
262 | ret = gpiod_set_debounce(desc, debounce); | 272 | ret = gpiod_set_debounce(desc, debounce); |
263 | if (ret < 0) | 273 | if (ret < 0) |
264 | return ret; | 274 | ctx->cd_debounce_delay_ms = debounce; |
265 | } | 275 | } |
266 | 276 | ||
267 | if (gpio_invert) | 277 | if (gpio_invert) |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 9589f9c9046f..0581c199c996 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -345,11 +345,11 @@ config MMC_SDHCI_IPROC | |||
345 | If unsure, say N. | 345 | If unsure, say N. |
346 | 346 | ||
347 | config MMC_MESON_GX | 347 | config MMC_MESON_GX |
348 | tristate "Amlogic S905/GX* SD/MMC Host Controller support" | 348 | tristate "Amlogic S905/GX*/AXG SD/MMC Host Controller support" |
349 | depends on ARCH_MESON && MMC | 349 | depends on ARCH_MESON && MMC |
350 | help | 350 | help |
351 | This selects support for the Amlogic SD/MMC Host Controller | 351 | This selects support for the Amlogic SD/MMC Host Controller |
352 | found on the S905/GX* family of SoCs. This controller is | 352 | found on the S905/GX*/AXG family of SoCs. This controller is |
353 | MMC 5.1 compliant and supports SD, eMMC and SDIO interfaces. | 353 | MMC 5.1 compliant and supports SD, eMMC and SDIO interfaces. |
354 | 354 | ||
355 | If you have a controller with this interface, say Y here. | 355 | If you have a controller with this interface, say Y here. |
@@ -358,7 +358,6 @@ config MMC_MESON_MX_SDIO | |||
358 | tristate "Amlogic Meson6/Meson8/Meson8b SD/MMC Host Controller support" | 358 | tristate "Amlogic Meson6/Meson8/Meson8b SD/MMC Host Controller support" |
359 | depends on ARCH_MESON || COMPILE_TEST | 359 | depends on ARCH_MESON || COMPILE_TEST |
360 | depends on COMMON_CLK | 360 | depends on COMMON_CLK |
361 | depends on HAS_DMA | ||
362 | depends on OF | 361 | depends on OF |
363 | help | 362 | help |
364 | This selects support for the SD/MMC Host Controller on | 363 | This selects support for the SD/MMC Host Controller on |
@@ -401,7 +400,6 @@ config MMC_OMAP | |||
401 | 400 | ||
402 | config MMC_OMAP_HS | 401 | config MMC_OMAP_HS |
403 | tristate "TI OMAP High Speed Multimedia Card Interface support" | 402 | tristate "TI OMAP High Speed Multimedia Card Interface support" |
404 | depends on HAS_DMA | ||
405 | depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST | 403 | depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST |
406 | help | 404 | help |
407 | This selects the TI OMAP High Speed Multimedia card Interface. | 405 | This selects the TI OMAP High Speed Multimedia card Interface. |
@@ -511,7 +509,6 @@ config MMC_DAVINCI | |||
511 | 509 | ||
512 | config MMC_GOLDFISH | 510 | config MMC_GOLDFISH |
513 | tristate "goldfish qemu Multimedia Card Interface support" | 511 | tristate "goldfish qemu Multimedia Card Interface support" |
514 | depends on HAS_DMA | ||
515 | depends on GOLDFISH || COMPILE_TEST | 512 | depends on GOLDFISH || COMPILE_TEST |
516 | help | 513 | help |
517 | This selects the Goldfish Multimedia card Interface emulation | 514 | This selects the Goldfish Multimedia card Interface emulation |
@@ -605,7 +602,7 @@ config MMC_SDHI | |||
605 | 602 | ||
606 | config MMC_SDHI_SYS_DMAC | 603 | config MMC_SDHI_SYS_DMAC |
607 | tristate "DMA for SDHI SD/SDIO controllers using SYS-DMAC" | 604 | tristate "DMA for SDHI SD/SDIO controllers using SYS-DMAC" |
608 | depends on MMC_SDHI && HAS_DMA | 605 | depends on MMC_SDHI |
609 | default MMC_SDHI if (SUPERH || ARM) | 606 | default MMC_SDHI if (SUPERH || ARM) |
610 | help | 607 | help |
611 | This provides DMA support for SDHI SD/SDIO controllers | 608 | This provides DMA support for SDHI SD/SDIO controllers |
@@ -615,7 +612,7 @@ config MMC_SDHI_SYS_DMAC | |||
615 | config MMC_SDHI_INTERNAL_DMAC | 612 | config MMC_SDHI_INTERNAL_DMAC |
616 | tristate "DMA for SDHI SD/SDIO controllers using on-chip bus mastering" | 613 | tristate "DMA for SDHI SD/SDIO controllers using on-chip bus mastering" |
617 | depends on ARM64 || COMPILE_TEST | 614 | depends on ARM64 || COMPILE_TEST |
618 | depends on MMC_SDHI && HAS_DMA | 615 | depends on MMC_SDHI |
619 | default MMC_SDHI if ARM64 | 616 | default MMC_SDHI if ARM64 |
620 | help | 617 | help |
621 | This provides DMA support for SDHI SD/SDIO controllers | 618 | This provides DMA support for SDHI SD/SDIO controllers |
@@ -669,7 +666,6 @@ config MMC_CAVIUM_THUNDERX | |||
669 | 666 | ||
670 | config MMC_DW | 667 | config MMC_DW |
671 | tristate "Synopsys DesignWare Memory Card Interface" | 668 | tristate "Synopsys DesignWare Memory Card Interface" |
672 | depends on HAS_DMA | ||
673 | depends on ARC || ARM || ARM64 || MIPS || COMPILE_TEST | 669 | depends on ARC || ARM || ARM64 || MIPS || COMPILE_TEST |
674 | help | 670 | help |
675 | This selects support for the Synopsys DesignWare Mobile Storage IP | 671 | This selects support for the Synopsys DesignWare Mobile Storage IP |
@@ -690,6 +686,15 @@ config MMC_DW_PLTFM | |||
690 | 686 | ||
691 | If unsure, say Y. | 687 | If unsure, say Y. |
692 | 688 | ||
689 | config MMC_DW_BLUEFIELD | ||
690 | tristate "BlueField specific extensions for Synopsys DW Memory Card Interface" | ||
691 | depends on MMC_DW | ||
692 | select MMC_DW_PLTFM | ||
693 | help | ||
694 | This selects support for Mellanox BlueField SoC specific extensions to | ||
695 | the Synopsys DesignWare Memory Card Interface driver. Select this | ||
696 | option for platforms based on Mellanox BlueField SoC's. | ||
697 | |||
693 | config MMC_DW_EXYNOS | 698 | config MMC_DW_EXYNOS |
694 | tristate "Exynos specific extensions for Synopsys DW Memory Card Interface" | 699 | tristate "Exynos specific extensions for Synopsys DW Memory Card Interface" |
695 | depends on MMC_DW | 700 | depends on MMC_DW |
@@ -748,7 +753,6 @@ config MMC_DW_ZX | |||
748 | 753 | ||
749 | config MMC_SH_MMCIF | 754 | config MMC_SH_MMCIF |
750 | tristate "SuperH Internal MMCIF support" | 755 | tristate "SuperH Internal MMCIF support" |
751 | depends on HAS_DMA | ||
752 | depends on SUPERH || ARCH_RENESAS || COMPILE_TEST | 756 | depends on SUPERH || ARCH_RENESAS || COMPILE_TEST |
753 | help | 757 | help |
754 | This selects the MMC Host Interface controller (MMCIF) found in various | 758 | This selects the MMC Host Interface controller (MMCIF) found in various |
@@ -756,11 +760,12 @@ config MMC_SH_MMCIF | |||
756 | 760 | ||
757 | 761 | ||
758 | config MMC_JZ4740 | 762 | config MMC_JZ4740 |
759 | tristate "JZ4740 SD/Multimedia Card Interface support" | 763 | tristate "Ingenic JZ47xx SD/Multimedia Card Interface support" |
760 | depends on MACH_JZ4740 | 764 | depends on MACH_JZ4740 || MACH_JZ4780 |
761 | help | 765 | help |
762 | This selects support for the SD/MMC controller on Ingenic JZ4740 | 766 | This selects support for the SD/MMC controller on Ingenic |
763 | SoCs. | 767 | JZ4740, JZ4750, JZ4770 and JZ4780 SoCs. |
768 | |||
764 | If you have a board based on such a SoC and with a SD/MMC slot, | 769 | If you have a board based on such a SoC and with a SD/MMC slot, |
765 | say Y or M here. | 770 | say Y or M here. |
766 | 771 | ||
@@ -868,7 +873,6 @@ config MMC_TOSHIBA_PCI | |||
868 | config MMC_BCM2835 | 873 | config MMC_BCM2835 |
869 | tristate "Broadcom BCM2835 SDHOST MMC Controller support" | 874 | tristate "Broadcom BCM2835 SDHOST MMC Controller support" |
870 | depends on ARCH_BCM2835 || COMPILE_TEST | 875 | depends on ARCH_BCM2835 || COMPILE_TEST |
871 | depends on HAS_DMA | ||
872 | help | 876 | help |
873 | This selects the BCM2835 SDHOST MMC controller. If you have | 877 | This selects the BCM2835 SDHOST MMC controller. If you have |
874 | a BCM2835 platform with SD or MMC devices, say Y or M here. | 878 | a BCM2835 platform with SD or MMC devices, say Y or M here. |
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 6aead24879b4..85dc1322c3de 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -49,6 +49,7 @@ thunderx-mmc-objs := cavium.o cavium-thunderx.o | |||
49 | obj-$(CONFIG_MMC_CAVIUM_THUNDERX) += thunderx-mmc.o | 49 | obj-$(CONFIG_MMC_CAVIUM_THUNDERX) += thunderx-mmc.o |
50 | obj-$(CONFIG_MMC_DW) += dw_mmc.o | 50 | obj-$(CONFIG_MMC_DW) += dw_mmc.o |
51 | obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o | 51 | obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o |
52 | obj-$(CONFIG_MMC_DW_BLUEFIELD) += dw_mmc-bluefield.o | ||
52 | obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o | 53 | obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o |
53 | obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o | 54 | obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o |
54 | obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o | 55 | obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o |
diff --git a/drivers/mmc/host/android-goldfish.c b/drivers/mmc/host/android-goldfish.c index 63d27589cd89..294de177632c 100644 --- a/drivers/mmc/host/android-goldfish.c +++ b/drivers/mmc/host/android-goldfish.c | |||
@@ -217,8 +217,8 @@ static void goldfish_mmc_xfer_done(struct goldfish_mmc_host *host, | |||
217 | * We don't really have DMA, so we need | 217 | * We don't really have DMA, so we need |
218 | * to copy from our platform driver buffer | 218 | * to copy from our platform driver buffer |
219 | */ | 219 | */ |
220 | uint8_t *dest = (uint8_t *)sg_virt(data->sg); | 220 | sg_copy_to_buffer(data->sg, 1, host->virt_base, |
221 | memcpy(dest, host->virt_base, data->sg->length); | 221 | data->sg->length); |
222 | } | 222 | } |
223 | host->data->bytes_xfered += data->sg->length; | 223 | host->data->bytes_xfered += data->sg->length; |
224 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, | 224 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, |
@@ -393,8 +393,8 @@ static void goldfish_mmc_prepare_data(struct goldfish_mmc_host *host, | |||
393 | * We don't really have DMA, so we need to copy to our | 393 | * We don't really have DMA, so we need to copy to our |
394 | * platform driver buffer | 394 | * platform driver buffer |
395 | */ | 395 | */ |
396 | const uint8_t *src = (uint8_t *)sg_virt(data->sg); | 396 | sg_copy_from_buffer(data->sg, 1, host->virt_base, |
397 | memcpy(host->virt_base, src, data->sg->length); | 397 | data->sg->length); |
398 | } | 398 | } |
399 | } | 399 | } |
400 | 400 | ||
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index e55f3932d580..5aa2c9404e92 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -1967,7 +1967,6 @@ static void atmci_tasklet_func(unsigned long priv) | |||
1967 | static void atmci_read_data_pio(struct atmel_mci *host) | 1967 | static void atmci_read_data_pio(struct atmel_mci *host) |
1968 | { | 1968 | { |
1969 | struct scatterlist *sg = host->sg; | 1969 | struct scatterlist *sg = host->sg; |
1970 | void *buf = sg_virt(sg); | ||
1971 | unsigned int offset = host->pio_offset; | 1970 | unsigned int offset = host->pio_offset; |
1972 | struct mmc_data *data = host->data; | 1971 | struct mmc_data *data = host->data; |
1973 | u32 value; | 1972 | u32 value; |
@@ -1977,7 +1976,7 @@ static void atmci_read_data_pio(struct atmel_mci *host) | |||
1977 | do { | 1976 | do { |
1978 | value = atmci_readl(host, ATMCI_RDR); | 1977 | value = atmci_readl(host, ATMCI_RDR); |
1979 | if (likely(offset + 4 <= sg->length)) { | 1978 | if (likely(offset + 4 <= sg->length)) { |
1980 | put_unaligned(value, (u32 *)(buf + offset)); | 1979 | sg_pcopy_to_buffer(sg, 1, &value, sizeof(u32), offset); |
1981 | 1980 | ||
1982 | offset += 4; | 1981 | offset += 4; |
1983 | nbytes += 4; | 1982 | nbytes += 4; |
@@ -1990,11 +1989,11 @@ static void atmci_read_data_pio(struct atmel_mci *host) | |||
1990 | goto done; | 1989 | goto done; |
1991 | 1990 | ||
1992 | offset = 0; | 1991 | offset = 0; |
1993 | buf = sg_virt(sg); | ||
1994 | } | 1992 | } |
1995 | } else { | 1993 | } else { |
1996 | unsigned int remaining = sg->length - offset; | 1994 | unsigned int remaining = sg->length - offset; |
1997 | memcpy(buf + offset, &value, remaining); | 1995 | |
1996 | sg_pcopy_to_buffer(sg, 1, &value, remaining, offset); | ||
1998 | nbytes += remaining; | 1997 | nbytes += remaining; |
1999 | 1998 | ||
2000 | flush_dcache_page(sg_page(sg)); | 1999 | flush_dcache_page(sg_page(sg)); |
@@ -2004,8 +2003,8 @@ static void atmci_read_data_pio(struct atmel_mci *host) | |||
2004 | goto done; | 2003 | goto done; |
2005 | 2004 | ||
2006 | offset = 4 - remaining; | 2005 | offset = 4 - remaining; |
2007 | buf = sg_virt(sg); | 2006 | sg_pcopy_to_buffer(sg, 1, (u8 *)&value + remaining, |
2008 | memcpy(buf, (u8 *)&value + remaining, offset); | 2007 | offset, 0); |
2009 | nbytes += offset; | 2008 | nbytes += offset; |
2010 | } | 2009 | } |
2011 | 2010 | ||
@@ -2035,7 +2034,6 @@ done: | |||
2035 | static void atmci_write_data_pio(struct atmel_mci *host) | 2034 | static void atmci_write_data_pio(struct atmel_mci *host) |
2036 | { | 2035 | { |
2037 | struct scatterlist *sg = host->sg; | 2036 | struct scatterlist *sg = host->sg; |
2038 | void *buf = sg_virt(sg); | ||
2039 | unsigned int offset = host->pio_offset; | 2037 | unsigned int offset = host->pio_offset; |
2040 | struct mmc_data *data = host->data; | 2038 | struct mmc_data *data = host->data; |
2041 | u32 value; | 2039 | u32 value; |
@@ -2044,7 +2042,7 @@ static void atmci_write_data_pio(struct atmel_mci *host) | |||
2044 | 2042 | ||
2045 | do { | 2043 | do { |
2046 | if (likely(offset + 4 <= sg->length)) { | 2044 | if (likely(offset + 4 <= sg->length)) { |
2047 | value = get_unaligned((u32 *)(buf + offset)); | 2045 | sg_pcopy_from_buffer(sg, 1, &value, sizeof(u32), offset); |
2048 | atmci_writel(host, ATMCI_TDR, value); | 2046 | atmci_writel(host, ATMCI_TDR, value); |
2049 | 2047 | ||
2050 | offset += 4; | 2048 | offset += 4; |
@@ -2056,13 +2054,12 @@ static void atmci_write_data_pio(struct atmel_mci *host) | |||
2056 | goto done; | 2054 | goto done; |
2057 | 2055 | ||
2058 | offset = 0; | 2056 | offset = 0; |
2059 | buf = sg_virt(sg); | ||
2060 | } | 2057 | } |
2061 | } else { | 2058 | } else { |
2062 | unsigned int remaining = sg->length - offset; | 2059 | unsigned int remaining = sg->length - offset; |
2063 | 2060 | ||
2064 | value = 0; | 2061 | value = 0; |
2065 | memcpy(&value, buf + offset, remaining); | 2062 | sg_pcopy_from_buffer(sg, 1, &value, remaining, offset); |
2066 | nbytes += remaining; | 2063 | nbytes += remaining; |
2067 | 2064 | ||
2068 | host->sg = sg = sg_next(sg); | 2065 | host->sg = sg = sg_next(sg); |
@@ -2073,8 +2070,8 @@ static void atmci_write_data_pio(struct atmel_mci *host) | |||
2073 | } | 2070 | } |
2074 | 2071 | ||
2075 | offset = 4 - remaining; | 2072 | offset = 4 - remaining; |
2076 | buf = sg_virt(sg); | 2073 | sg_pcopy_from_buffer(sg, 1, (u8 *)&value + remaining, |
2077 | memcpy((u8 *)&value + remaining, buf, offset); | 2074 | offset, 0); |
2078 | atmci_writel(host, ATMCI_TDR, value); | 2075 | atmci_writel(host, ATMCI_TDR, value); |
2079 | nbytes += offset; | 2076 | nbytes += offset; |
2080 | } | 2077 | } |
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index ed77fbfa4774..9b4be67330dd 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
41 | #include <linux/dma-mapping.h> | 41 | #include <linux/dma-mapping.h> |
42 | #include <linux/scatterlist.h> | 42 | #include <linux/scatterlist.h> |
43 | #include <linux/highmem.h> | ||
43 | #include <linux/leds.h> | 44 | #include <linux/leds.h> |
44 | #include <linux/mmc/host.h> | 45 | #include <linux/mmc/host.h> |
45 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
@@ -405,7 +406,7 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host) | |||
405 | 406 | ||
406 | /* This is the pointer to the data buffer */ | 407 | /* This is the pointer to the data buffer */ |
407 | sg = &data->sg[host->pio.index]; | 408 | sg = &data->sg[host->pio.index]; |
408 | sg_ptr = sg_virt(sg) + host->pio.offset; | 409 | sg_ptr = kmap_atomic(sg_page(sg)) + sg->offset + host->pio.offset; |
409 | 410 | ||
410 | /* This is the space left inside the buffer */ | 411 | /* This is the space left inside the buffer */ |
411 | sg_len = data->sg[host->pio.index].length - host->pio.offset; | 412 | sg_len = data->sg[host->pio.index].length - host->pio.offset; |
@@ -421,11 +422,12 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host) | |||
421 | if (!(status & SD_STATUS_TH)) | 422 | if (!(status & SD_STATUS_TH)) |
422 | break; | 423 | break; |
423 | 424 | ||
424 | val = *sg_ptr++; | 425 | val = sg_ptr[count]; |
425 | 426 | ||
426 | __raw_writel((unsigned long)val, HOST_TXPORT(host)); | 427 | __raw_writel((unsigned long)val, HOST_TXPORT(host)); |
427 | wmb(); /* drain writebuffer */ | 428 | wmb(); /* drain writebuffer */ |
428 | } | 429 | } |
430 | kunmap_atomic(sg_ptr); | ||
429 | 431 | ||
430 | host->pio.len -= count; | 432 | host->pio.len -= count; |
431 | host->pio.offset += count; | 433 | host->pio.offset += count; |
@@ -462,7 +464,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) | |||
462 | 464 | ||
463 | if (host->pio.index < host->dma.len) { | 465 | if (host->pio.index < host->dma.len) { |
464 | sg = &data->sg[host->pio.index]; | 466 | sg = &data->sg[host->pio.index]; |
465 | sg_ptr = sg_virt(sg) + host->pio.offset; | 467 | sg_ptr = kmap_atomic(sg_page(sg)) + sg->offset + host->pio.offset; |
466 | 468 | ||
467 | /* This is the space left inside the buffer */ | 469 | /* This is the space left inside the buffer */ |
468 | sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset; | 470 | sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset; |
@@ -501,8 +503,10 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) | |||
501 | val = __raw_readl(HOST_RXPORT(host)); | 503 | val = __raw_readl(HOST_RXPORT(host)); |
502 | 504 | ||
503 | if (sg_ptr) | 505 | if (sg_ptr) |
504 | *sg_ptr++ = (unsigned char)(val & 0xFF); | 506 | sg_ptr[count] = (unsigned char)(val & 0xFF); |
505 | } | 507 | } |
508 | if (sg_ptr) | ||
509 | kunmap_atomic(sg_ptr); | ||
506 | 510 | ||
507 | host->pio.len -= count; | 511 | host->pio.len -= count; |
508 | host->pio.offset += count; | 512 | host->pio.offset += count; |
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 8e363174f9d6..9e68c3645e22 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c | |||
@@ -1377,8 +1377,7 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev) | |||
1377 | #ifdef CONFIG_PM | 1377 | #ifdef CONFIG_PM |
1378 | static int davinci_mmcsd_suspend(struct device *dev) | 1378 | static int davinci_mmcsd_suspend(struct device *dev) |
1379 | { | 1379 | { |
1380 | struct platform_device *pdev = to_platform_device(dev); | 1380 | struct mmc_davinci_host *host = dev_get_drvdata(dev); |
1381 | struct mmc_davinci_host *host = platform_get_drvdata(pdev); | ||
1382 | 1381 | ||
1383 | writel(0, host->base + DAVINCI_MMCIM); | 1382 | writel(0, host->base + DAVINCI_MMCIM); |
1384 | mmc_davinci_reset_ctrl(host, 1); | 1383 | mmc_davinci_reset_ctrl(host, 1); |
@@ -1389,8 +1388,7 @@ static int davinci_mmcsd_suspend(struct device *dev) | |||
1389 | 1388 | ||
1390 | static int davinci_mmcsd_resume(struct device *dev) | 1389 | static int davinci_mmcsd_resume(struct device *dev) |
1391 | { | 1390 | { |
1392 | struct platform_device *pdev = to_platform_device(dev); | 1391 | struct mmc_davinci_host *host = dev_get_drvdata(dev); |
1393 | struct mmc_davinci_host *host = platform_get_drvdata(pdev); | ||
1394 | 1392 | ||
1395 | clk_enable(host->clk); | 1393 | clk_enable(host->clk); |
1396 | mmc_davinci_reset_ctrl(host, 0); | 1394 | mmc_davinci_reset_ctrl(host, 0); |
diff --git a/drivers/mmc/host/dw_mmc-bluefield.c b/drivers/mmc/host/dw_mmc-bluefield.c new file mode 100644 index 000000000000..54c3fbb4a391 --- /dev/null +++ b/drivers/mmc/host/dw_mmc-bluefield.c | |||
@@ -0,0 +1,81 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (C) 2018 Mellanox Technologies. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include <linux/bitfield.h> | ||
12 | #include <linux/bitops.h> | ||
13 | #include <linux/mmc/host.h> | ||
14 | #include <linux/mmc/mmc.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/pm_runtime.h> | ||
19 | |||
20 | #include "dw_mmc.h" | ||
21 | #include "dw_mmc-pltfm.h" | ||
22 | |||
23 | #define UHS_REG_EXT_SAMPLE_MASK GENMASK(22, 16) | ||
24 | #define UHS_REG_EXT_DRIVE_MASK GENMASK(29, 23) | ||
25 | #define BLUEFIELD_UHS_REG_EXT_SAMPLE 2 | ||
26 | #define BLUEFIELD_UHS_REG_EXT_DRIVE 4 | ||
27 | |||
28 | static void dw_mci_bluefield_set_ios(struct dw_mci *host, struct mmc_ios *ios) | ||
29 | { | ||
30 | u32 reg; | ||
31 | |||
32 | /* Update the Drive and Sample fields in register UHS_REG_EXT. */ | ||
33 | reg = mci_readl(host, UHS_REG_EXT); | ||
34 | reg &= ~UHS_REG_EXT_SAMPLE_MASK; | ||
35 | reg |= FIELD_PREP(UHS_REG_EXT_SAMPLE_MASK, | ||
36 | BLUEFIELD_UHS_REG_EXT_SAMPLE); | ||
37 | reg &= ~UHS_REG_EXT_DRIVE_MASK; | ||
38 | reg |= FIELD_PREP(UHS_REG_EXT_DRIVE_MASK, BLUEFIELD_UHS_REG_EXT_DRIVE); | ||
39 | mci_writel(host, UHS_REG_EXT, reg); | ||
40 | } | ||
41 | |||
42 | static const struct dw_mci_drv_data bluefield_drv_data = { | ||
43 | .set_ios = dw_mci_bluefield_set_ios | ||
44 | }; | ||
45 | |||
46 | static const struct of_device_id dw_mci_bluefield_match[] = { | ||
47 | { .compatible = "mellanox,bluefield-dw-mshc", | ||
48 | .data = &bluefield_drv_data }, | ||
49 | {}, | ||
50 | }; | ||
51 | MODULE_DEVICE_TABLE(of, dw_mci_bluefield_match); | ||
52 | |||
53 | static int dw_mci_bluefield_probe(struct platform_device *pdev) | ||
54 | { | ||
55 | const struct dw_mci_drv_data *drv_data = NULL; | ||
56 | const struct of_device_id *match; | ||
57 | |||
58 | if (pdev->dev.of_node) { | ||
59 | match = of_match_node(dw_mci_bluefield_match, | ||
60 | pdev->dev.of_node); | ||
61 | drv_data = match->data; | ||
62 | } | ||
63 | |||
64 | return dw_mci_pltfm_register(pdev, drv_data); | ||
65 | } | ||
66 | |||
67 | static struct platform_driver dw_mci_bluefield_pltfm_driver = { | ||
68 | .probe = dw_mci_bluefield_probe, | ||
69 | .remove = dw_mci_pltfm_remove, | ||
70 | .driver = { | ||
71 | .name = "dwmmc_bluefield", | ||
72 | .of_match_table = dw_mci_bluefield_match, | ||
73 | .pm = &dw_mci_pltfm_pmops, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | module_platform_driver(dw_mci_bluefield_pltfm_driver); | ||
78 | |||
79 | MODULE_DESCRIPTION("BlueField DW Multimedia Card driver"); | ||
80 | MODULE_AUTHOR("Mellanox Technologies"); | ||
81 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 40d7de2eea12..8c86a800a8fd 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c | |||
@@ -44,9 +44,8 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) | |||
44 | * bus_hz = cclkin / RK3288_CLKGEN_DIV | 44 | * bus_hz = cclkin / RK3288_CLKGEN_DIV |
45 | * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div)) | 45 | * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div)) |
46 | * | 46 | * |
47 | * Note: div can only be 0 or 1 | 47 | * Note: div can only be 0 or 1, but div must be set to 1 for eMMC |
48 | * if DDR50 8bit mode(only emmc work in 8bit mode), | 48 | * DDR52 8-bit mode. |
49 | * div must be set 1 | ||
50 | */ | 49 | */ |
51 | if (ios->bus_width == MMC_BUS_WIDTH_8 && | 50 | if (ios->bus_width == MMC_BUS_WIDTH_8 && |
52 | ios->timing == MMC_TIMING_MMC_DDR52) | 51 | ios->timing == MMC_TIMING_MMC_DDR52) |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 29a1afa81f66..623f4d27fa01 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -1230,6 +1230,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) | |||
1230 | if (host->state == STATE_WAITING_CMD11_DONE) | 1230 | if (host->state == STATE_WAITING_CMD11_DONE) |
1231 | sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH; | 1231 | sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH; |
1232 | 1232 | ||
1233 | slot->mmc->actual_clock = 0; | ||
1234 | |||
1233 | if (!clock) { | 1235 | if (!clock) { |
1234 | mci_writel(host, CLKENA, 0); | 1236 | mci_writel(host, CLKENA, 0); |
1235 | mci_send_cmd(slot, sdmmc_cmd_bits, 0); | 1237 | mci_send_cmd(slot, sdmmc_cmd_bits, 0); |
@@ -1288,6 +1290,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) | |||
1288 | 1290 | ||
1289 | /* keep the last clock value that was requested from core */ | 1291 | /* keep the last clock value that was requested from core */ |
1290 | slot->__clk_old = clock; | 1292 | slot->__clk_old = clock; |
1293 | slot->mmc->actual_clock = div ? ((host->bus_hz / div) >> 1) : | ||
1294 | host->bus_hz; | ||
1291 | } | 1295 | } |
1292 | 1296 | ||
1293 | host->current_speed = clock; | 1297 | host->current_speed = clock; |
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index a0168e9e4fce..993386c9ea50 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> | 2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> |
3 | * Copyright (C) 2013, Imagination Technologies | ||
4 | * | ||
3 | * JZ4740 SD/MMC controller driver | 5 | * JZ4740 SD/MMC controller driver |
4 | * | 6 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
@@ -13,24 +15,25 @@ | |||
13 | * | 15 | * |
14 | */ | 16 | */ |
15 | 17 | ||
16 | #include <linux/mmc/host.h> | 18 | #include <linux/bitops.h> |
17 | #include <linux/mmc/slot-gpio.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/delay.h> | ||
21 | #include <linux/dmaengine.h> | ||
22 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <linux/gpio.h> | ||
25 | #include <linux/interrupt.h> | ||
19 | #include <linux/io.h> | 26 | #include <linux/io.h> |
20 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
21 | #include <linux/interrupt.h> | 28 | #include <linux/mmc/host.h> |
29 | #include <linux/mmc/slot-gpio.h> | ||
22 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/of_device.h> | ||
23 | #include <linux/pinctrl/consumer.h> | 32 | #include <linux/pinctrl/consumer.h> |
24 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
25 | #include <linux/delay.h> | ||
26 | #include <linux/scatterlist.h> | 34 | #include <linux/scatterlist.h> |
27 | #include <linux/clk.h> | ||
28 | 35 | ||
29 | #include <linux/bitops.h> | ||
30 | #include <linux/gpio.h> | ||
31 | #include <asm/cacheflush.h> | 36 | #include <asm/cacheflush.h> |
32 | #include <linux/dma-mapping.h> | ||
33 | #include <linux/dmaengine.h> | ||
34 | 37 | ||
35 | #include <asm/mach-jz4740/dma.h> | 38 | #include <asm/mach-jz4740/dma.h> |
36 | #include <asm/mach-jz4740/jz4740_mmc.h> | 39 | #include <asm/mach-jz4740/jz4740_mmc.h> |
@@ -51,6 +54,7 @@ | |||
51 | #define JZ_REG_MMC_RESP_FIFO 0x34 | 54 | #define JZ_REG_MMC_RESP_FIFO 0x34 |
52 | #define JZ_REG_MMC_RXFIFO 0x38 | 55 | #define JZ_REG_MMC_RXFIFO 0x38 |
53 | #define JZ_REG_MMC_TXFIFO 0x3C | 56 | #define JZ_REG_MMC_TXFIFO 0x3C |
57 | #define JZ_REG_MMC_DMAC 0x44 | ||
54 | 58 | ||
55 | #define JZ_MMC_STRPCL_EXIT_MULTIPLE BIT(7) | 59 | #define JZ_MMC_STRPCL_EXIT_MULTIPLE BIT(7) |
56 | #define JZ_MMC_STRPCL_EXIT_TRANSFER BIT(6) | 60 | #define JZ_MMC_STRPCL_EXIT_TRANSFER BIT(6) |
@@ -104,9 +108,17 @@ | |||
104 | #define JZ_MMC_IRQ_PRG_DONE BIT(1) | 108 | #define JZ_MMC_IRQ_PRG_DONE BIT(1) |
105 | #define JZ_MMC_IRQ_DATA_TRAN_DONE BIT(0) | 109 | #define JZ_MMC_IRQ_DATA_TRAN_DONE BIT(0) |
106 | 110 | ||
111 | #define JZ_MMC_DMAC_DMA_SEL BIT(1) | ||
112 | #define JZ_MMC_DMAC_DMA_EN BIT(0) | ||
107 | 113 | ||
108 | #define JZ_MMC_CLK_RATE 24000000 | 114 | #define JZ_MMC_CLK_RATE 24000000 |
109 | 115 | ||
116 | enum jz4740_mmc_version { | ||
117 | JZ_MMC_JZ4740, | ||
118 | JZ_MMC_JZ4750, | ||
119 | JZ_MMC_JZ4780, | ||
120 | }; | ||
121 | |||
110 | enum jz4740_mmc_state { | 122 | enum jz4740_mmc_state { |
111 | JZ4740_MMC_STATE_READ_RESPONSE, | 123 | JZ4740_MMC_STATE_READ_RESPONSE, |
112 | JZ4740_MMC_STATE_TRANSFER_DATA, | 124 | JZ4740_MMC_STATE_TRANSFER_DATA, |
@@ -125,6 +137,8 @@ struct jz4740_mmc_host { | |||
125 | struct jz4740_mmc_platform_data *pdata; | 137 | struct jz4740_mmc_platform_data *pdata; |
126 | struct clk *clk; | 138 | struct clk *clk; |
127 | 139 | ||
140 | enum jz4740_mmc_version version; | ||
141 | |||
128 | int irq; | 142 | int irq; |
129 | int card_detect_irq; | 143 | int card_detect_irq; |
130 | 144 | ||
@@ -137,7 +151,7 @@ struct jz4740_mmc_host { | |||
137 | 151 | ||
138 | uint32_t cmdat; | 152 | uint32_t cmdat; |
139 | 153 | ||
140 | uint16_t irq_mask; | 154 | uint32_t irq_mask; |
141 | 155 | ||
142 | spinlock_t lock; | 156 | spinlock_t lock; |
143 | 157 | ||
@@ -159,6 +173,32 @@ struct jz4740_mmc_host { | |||
159 | #define JZ4740_MMC_FIFO_HALF_SIZE 8 | 173 | #define JZ4740_MMC_FIFO_HALF_SIZE 8 |
160 | }; | 174 | }; |
161 | 175 | ||
176 | static void jz4740_mmc_write_irq_mask(struct jz4740_mmc_host *host, | ||
177 | uint32_t val) | ||
178 | { | ||
179 | if (host->version >= JZ_MMC_JZ4750) | ||
180 | return writel(val, host->base + JZ_REG_MMC_IMASK); | ||
181 | else | ||
182 | return writew(val, host->base + JZ_REG_MMC_IMASK); | ||
183 | } | ||
184 | |||
185 | static void jz4740_mmc_write_irq_reg(struct jz4740_mmc_host *host, | ||
186 | uint32_t val) | ||
187 | { | ||
188 | if (host->version >= JZ_MMC_JZ4780) | ||
189 | return writel(val, host->base + JZ_REG_MMC_IREG); | ||
190 | else | ||
191 | return writew(val, host->base + JZ_REG_MMC_IREG); | ||
192 | } | ||
193 | |||
194 | static uint32_t jz4740_mmc_read_irq_reg(struct jz4740_mmc_host *host) | ||
195 | { | ||
196 | if (host->version >= JZ_MMC_JZ4780) | ||
197 | return readl(host->base + JZ_REG_MMC_IREG); | ||
198 | else | ||
199 | return readw(host->base + JZ_REG_MMC_IREG); | ||
200 | } | ||
201 | |||
162 | /*----------------------------------------------------------------------------*/ | 202 | /*----------------------------------------------------------------------------*/ |
163 | /* DMA infrastructure */ | 203 | /* DMA infrastructure */ |
164 | 204 | ||
@@ -173,31 +213,23 @@ static void jz4740_mmc_release_dma_channels(struct jz4740_mmc_host *host) | |||
173 | 213 | ||
174 | static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host) | 214 | static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host) |
175 | { | 215 | { |
176 | dma_cap_mask_t mask; | 216 | host->dma_tx = dma_request_chan(mmc_dev(host->mmc), "tx"); |
177 | 217 | if (IS_ERR(host->dma_tx)) { | |
178 | dma_cap_zero(mask); | ||
179 | dma_cap_set(DMA_SLAVE, mask); | ||
180 | |||
181 | host->dma_tx = dma_request_channel(mask, NULL, host); | ||
182 | if (!host->dma_tx) { | ||
183 | dev_err(mmc_dev(host->mmc), "Failed to get dma_tx channel\n"); | 218 | dev_err(mmc_dev(host->mmc), "Failed to get dma_tx channel\n"); |
184 | return -ENODEV; | 219 | return PTR_ERR(host->dma_tx); |
185 | } | 220 | } |
186 | 221 | ||
187 | host->dma_rx = dma_request_channel(mask, NULL, host); | 222 | host->dma_rx = dma_request_chan(mmc_dev(host->mmc), "rx"); |
188 | if (!host->dma_rx) { | 223 | if (IS_ERR(host->dma_rx)) { |
189 | dev_err(mmc_dev(host->mmc), "Failed to get dma_rx channel\n"); | 224 | dev_err(mmc_dev(host->mmc), "Failed to get dma_rx channel\n"); |
190 | goto free_master_write; | 225 | dma_release_channel(host->dma_tx); |
226 | return PTR_ERR(host->dma_rx); | ||
191 | } | 227 | } |
192 | 228 | ||
193 | /* Initialize DMA pre request cookie */ | 229 | /* Initialize DMA pre request cookie */ |
194 | host->next_data.cookie = 1; | 230 | host->next_data.cookie = 1; |
195 | 231 | ||
196 | return 0; | 232 | return 0; |
197 | |||
198 | free_master_write: | ||
199 | dma_release_channel(host->dma_tx); | ||
200 | return -ENODEV; | ||
201 | } | 233 | } |
202 | 234 | ||
203 | static inline struct dma_chan *jz4740_mmc_get_dma_chan(struct jz4740_mmc_host *host, | 235 | static inline struct dma_chan *jz4740_mmc_get_dma_chan(struct jz4740_mmc_host *host, |
@@ -363,7 +395,7 @@ static void jz4740_mmc_set_irq_enabled(struct jz4740_mmc_host *host, | |||
363 | else | 395 | else |
364 | host->irq_mask |= irq; | 396 | host->irq_mask |= irq; |
365 | 397 | ||
366 | writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK); | 398 | jz4740_mmc_write_irq_mask(host, host->irq_mask); |
367 | spin_unlock_irqrestore(&host->lock, flags); | 399 | spin_unlock_irqrestore(&host->lock, flags); |
368 | } | 400 | } |
369 | 401 | ||
@@ -415,10 +447,10 @@ static unsigned int jz4740_mmc_poll_irq(struct jz4740_mmc_host *host, | |||
415 | unsigned int irq) | 447 | unsigned int irq) |
416 | { | 448 | { |
417 | unsigned int timeout = 0x800; | 449 | unsigned int timeout = 0x800; |
418 | uint16_t status; | 450 | uint32_t status; |
419 | 451 | ||
420 | do { | 452 | do { |
421 | status = readw(host->base + JZ_REG_MMC_IREG); | 453 | status = jz4740_mmc_read_irq_reg(host); |
422 | } while (!(status & irq) && --timeout); | 454 | } while (!(status & irq) && --timeout); |
423 | 455 | ||
424 | if (timeout == 0) { | 456 | if (timeout == 0) { |
@@ -518,7 +550,7 @@ static bool jz4740_mmc_read_data(struct jz4740_mmc_host *host, | |||
518 | void __iomem *fifo_addr = host->base + JZ_REG_MMC_RXFIFO; | 550 | void __iomem *fifo_addr = host->base + JZ_REG_MMC_RXFIFO; |
519 | uint32_t *buf; | 551 | uint32_t *buf; |
520 | uint32_t d; | 552 | uint32_t d; |
521 | uint16_t status; | 553 | uint32_t status; |
522 | size_t i, j; | 554 | size_t i, j; |
523 | unsigned int timeout; | 555 | unsigned int timeout; |
524 | 556 | ||
@@ -654,8 +686,25 @@ static void jz4740_mmc_send_command(struct jz4740_mmc_host *host, | |||
654 | cmdat |= JZ_MMC_CMDAT_DATA_EN; | 686 | cmdat |= JZ_MMC_CMDAT_DATA_EN; |
655 | if (cmd->data->flags & MMC_DATA_WRITE) | 687 | if (cmd->data->flags & MMC_DATA_WRITE) |
656 | cmdat |= JZ_MMC_CMDAT_WRITE; | 688 | cmdat |= JZ_MMC_CMDAT_WRITE; |
657 | if (host->use_dma) | 689 | if (host->use_dma) { |
658 | cmdat |= JZ_MMC_CMDAT_DMA_EN; | 690 | /* |
691 | * The 4780's MMC controller has integrated DMA ability | ||
692 | * in addition to being able to use the external DMA | ||
693 | * controller. It moves DMA control bits to a separate | ||
694 | * register. The DMA_SEL bit chooses the external | ||
695 | * controller over the integrated one. Earlier SoCs | ||
696 | * can only use the external controller, and have a | ||
697 | * single DMA enable bit in CMDAT. | ||
698 | */ | ||
699 | if (host->version >= JZ_MMC_JZ4780) { | ||
700 | writel(JZ_MMC_DMAC_DMA_EN | JZ_MMC_DMAC_DMA_SEL, | ||
701 | host->base + JZ_REG_MMC_DMAC); | ||
702 | } else { | ||
703 | cmdat |= JZ_MMC_CMDAT_DMA_EN; | ||
704 | } | ||
705 | } else if (host->version >= JZ_MMC_JZ4780) { | ||
706 | writel(0, host->base + JZ_REG_MMC_DMAC); | ||
707 | } | ||
659 | 708 | ||
660 | writew(cmd->data->blksz, host->base + JZ_REG_MMC_BLKLEN); | 709 | writew(cmd->data->blksz, host->base + JZ_REG_MMC_BLKLEN); |
661 | writew(cmd->data->blocks, host->base + JZ_REG_MMC_NOB); | 710 | writew(cmd->data->blocks, host->base + JZ_REG_MMC_NOB); |
@@ -736,7 +785,7 @@ static irqreturn_t jz_mmc_irq_worker(int irq, void *devid) | |||
736 | host->state = JZ4740_MMC_STATE_SEND_STOP; | 785 | host->state = JZ4740_MMC_STATE_SEND_STOP; |
737 | break; | 786 | break; |
738 | } | 787 | } |
739 | writew(JZ_MMC_IRQ_DATA_TRAN_DONE, host->base + JZ_REG_MMC_IREG); | 788 | jz4740_mmc_write_irq_reg(host, JZ_MMC_IRQ_DATA_TRAN_DONE); |
740 | 789 | ||
741 | case JZ4740_MMC_STATE_SEND_STOP: | 790 | case JZ4740_MMC_STATE_SEND_STOP: |
742 | if (!req->stop) | 791 | if (!req->stop) |
@@ -766,9 +815,10 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid) | |||
766 | { | 815 | { |
767 | struct jz4740_mmc_host *host = devid; | 816 | struct jz4740_mmc_host *host = devid; |
768 | struct mmc_command *cmd = host->cmd; | 817 | struct mmc_command *cmd = host->cmd; |
769 | uint16_t irq_reg, status, tmp; | 818 | uint32_t irq_reg, status, tmp; |
770 | 819 | ||
771 | irq_reg = readw(host->base + JZ_REG_MMC_IREG); | 820 | status = readl(host->base + JZ_REG_MMC_STATUS); |
821 | irq_reg = jz4740_mmc_read_irq_reg(host); | ||
772 | 822 | ||
773 | tmp = irq_reg; | 823 | tmp = irq_reg; |
774 | irq_reg &= ~host->irq_mask; | 824 | irq_reg &= ~host->irq_mask; |
@@ -777,10 +827,10 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid) | |||
777 | JZ_MMC_IRQ_PRG_DONE | JZ_MMC_IRQ_DATA_TRAN_DONE); | 827 | JZ_MMC_IRQ_PRG_DONE | JZ_MMC_IRQ_DATA_TRAN_DONE); |
778 | 828 | ||
779 | if (tmp != irq_reg) | 829 | if (tmp != irq_reg) |
780 | writew(tmp & ~irq_reg, host->base + JZ_REG_MMC_IREG); | 830 | jz4740_mmc_write_irq_reg(host, tmp & ~irq_reg); |
781 | 831 | ||
782 | if (irq_reg & JZ_MMC_IRQ_SDIO) { | 832 | if (irq_reg & JZ_MMC_IRQ_SDIO) { |
783 | writew(JZ_MMC_IRQ_SDIO, host->base + JZ_REG_MMC_IREG); | 833 | jz4740_mmc_write_irq_reg(host, JZ_MMC_IRQ_SDIO); |
784 | mmc_signal_sdio_irq(host->mmc); | 834 | mmc_signal_sdio_irq(host->mmc); |
785 | irq_reg &= ~JZ_MMC_IRQ_SDIO; | 835 | irq_reg &= ~JZ_MMC_IRQ_SDIO; |
786 | } | 836 | } |
@@ -789,8 +839,6 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid) | |||
789 | if (test_and_clear_bit(0, &host->waiting)) { | 839 | if (test_and_clear_bit(0, &host->waiting)) { |
790 | del_timer(&host->timeout_timer); | 840 | del_timer(&host->timeout_timer); |
791 | 841 | ||
792 | status = readl(host->base + JZ_REG_MMC_STATUS); | ||
793 | |||
794 | if (status & JZ_MMC_STATUS_TIMEOUT_RES) { | 842 | if (status & JZ_MMC_STATUS_TIMEOUT_RES) { |
795 | cmd->error = -ETIMEDOUT; | 843 | cmd->error = -ETIMEDOUT; |
796 | } else if (status & JZ_MMC_STATUS_CRC_RES_ERR) { | 844 | } else if (status & JZ_MMC_STATUS_CRC_RES_ERR) { |
@@ -803,7 +851,7 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid) | |||
803 | } | 851 | } |
804 | 852 | ||
805 | jz4740_mmc_set_irq_enabled(host, irq_reg, false); | 853 | jz4740_mmc_set_irq_enabled(host, irq_reg, false); |
806 | writew(irq_reg, host->base + JZ_REG_MMC_IREG); | 854 | jz4740_mmc_write_irq_reg(host, irq_reg); |
807 | 855 | ||
808 | return IRQ_WAKE_THREAD; | 856 | return IRQ_WAKE_THREAD; |
809 | } | 857 | } |
@@ -818,7 +866,7 @@ static int jz4740_mmc_set_clock_rate(struct jz4740_mmc_host *host, int rate) | |||
818 | int real_rate; | 866 | int real_rate; |
819 | 867 | ||
820 | jz4740_mmc_clock_disable(host); | 868 | jz4740_mmc_clock_disable(host); |
821 | clk_set_rate(host->clk, JZ_MMC_CLK_RATE); | 869 | clk_set_rate(host->clk, host->mmc->f_max); |
822 | 870 | ||
823 | real_rate = clk_get_rate(host->clk); | 871 | real_rate = clk_get_rate(host->clk); |
824 | 872 | ||
@@ -837,9 +885,7 @@ static void jz4740_mmc_request(struct mmc_host *mmc, struct mmc_request *req) | |||
837 | 885 | ||
838 | host->req = req; | 886 | host->req = req; |
839 | 887 | ||
840 | writew(0xffff, host->base + JZ_REG_MMC_IREG); | 888 | jz4740_mmc_write_irq_reg(host, ~0); |
841 | |||
842 | writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG); | ||
843 | jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, true); | 889 | jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, true); |
844 | 890 | ||
845 | host->state = JZ4740_MMC_STATE_READ_RESPONSE; | 891 | host->state = JZ4740_MMC_STATE_READ_RESPONSE; |
@@ -857,7 +903,7 @@ static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
857 | switch (ios->power_mode) { | 903 | switch (ios->power_mode) { |
858 | case MMC_POWER_UP: | 904 | case MMC_POWER_UP: |
859 | jz4740_mmc_reset(host); | 905 | jz4740_mmc_reset(host); |
860 | if (gpio_is_valid(host->pdata->gpio_power)) | 906 | if (host->pdata && gpio_is_valid(host->pdata->gpio_power)) |
861 | gpio_set_value(host->pdata->gpio_power, | 907 | gpio_set_value(host->pdata->gpio_power, |
862 | !host->pdata->power_active_low); | 908 | !host->pdata->power_active_low); |
863 | host->cmdat |= JZ_MMC_CMDAT_INIT; | 909 | host->cmdat |= JZ_MMC_CMDAT_INIT; |
@@ -866,7 +912,7 @@ static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
866 | case MMC_POWER_ON: | 912 | case MMC_POWER_ON: |
867 | break; | 913 | break; |
868 | default: | 914 | default: |
869 | if (gpio_is_valid(host->pdata->gpio_power)) | 915 | if (host->pdata && gpio_is_valid(host->pdata->gpio_power)) |
870 | gpio_set_value(host->pdata->gpio_power, | 916 | gpio_set_value(host->pdata->gpio_power, |
871 | host->pdata->power_active_low); | 917 | host->pdata->power_active_low); |
872 | clk_disable_unprepare(host->clk); | 918 | clk_disable_unprepare(host->clk); |
@@ -926,7 +972,7 @@ static int jz4740_mmc_request_gpio(struct device *dev, int gpio, | |||
926 | static int jz4740_mmc_request_gpios(struct mmc_host *mmc, | 972 | static int jz4740_mmc_request_gpios(struct mmc_host *mmc, |
927 | struct platform_device *pdev) | 973 | struct platform_device *pdev) |
928 | { | 974 | { |
929 | struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data; | 975 | struct jz4740_mmc_platform_data *pdata = dev_get_platdata(&pdev->dev); |
930 | int ret = 0; | 976 | int ret = 0; |
931 | 977 | ||
932 | if (!pdata) | 978 | if (!pdata) |
@@ -955,7 +1001,7 @@ static int jz4740_mmc_request_gpios(struct mmc_host *mmc, | |||
955 | 1001 | ||
956 | static void jz4740_mmc_free_gpios(struct platform_device *pdev) | 1002 | static void jz4740_mmc_free_gpios(struct platform_device *pdev) |
957 | { | 1003 | { |
958 | struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data; | 1004 | struct jz4740_mmc_platform_data *pdata = dev_get_platdata(&pdev->dev); |
959 | 1005 | ||
960 | if (!pdata) | 1006 | if (!pdata) |
961 | return; | 1007 | return; |
@@ -964,14 +1010,22 @@ static void jz4740_mmc_free_gpios(struct platform_device *pdev) | |||
964 | gpio_free(pdata->gpio_power); | 1010 | gpio_free(pdata->gpio_power); |
965 | } | 1011 | } |
966 | 1012 | ||
1013 | static const struct of_device_id jz4740_mmc_of_match[] = { | ||
1014 | { .compatible = "ingenic,jz4740-mmc", .data = (void *) JZ_MMC_JZ4740 }, | ||
1015 | { .compatible = "ingenic,jz4780-mmc", .data = (void *) JZ_MMC_JZ4780 }, | ||
1016 | {}, | ||
1017 | }; | ||
1018 | MODULE_DEVICE_TABLE(of, jz4740_mmc_of_match); | ||
1019 | |||
967 | static int jz4740_mmc_probe(struct platform_device* pdev) | 1020 | static int jz4740_mmc_probe(struct platform_device* pdev) |
968 | { | 1021 | { |
969 | int ret; | 1022 | int ret; |
970 | struct mmc_host *mmc; | 1023 | struct mmc_host *mmc; |
971 | struct jz4740_mmc_host *host; | 1024 | struct jz4740_mmc_host *host; |
1025 | const struct of_device_id *match; | ||
972 | struct jz4740_mmc_platform_data *pdata; | 1026 | struct jz4740_mmc_platform_data *pdata; |
973 | 1027 | ||
974 | pdata = pdev->dev.platform_data; | 1028 | pdata = dev_get_platdata(&pdev->dev); |
975 | 1029 | ||
976 | mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev); | 1030 | mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev); |
977 | if (!mmc) { | 1031 | if (!mmc) { |
@@ -982,6 +1036,27 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
982 | host = mmc_priv(mmc); | 1036 | host = mmc_priv(mmc); |
983 | host->pdata = pdata; | 1037 | host->pdata = pdata; |
984 | 1038 | ||
1039 | match = of_match_device(jz4740_mmc_of_match, &pdev->dev); | ||
1040 | if (match) { | ||
1041 | host->version = (enum jz4740_mmc_version)match->data; | ||
1042 | ret = mmc_of_parse(mmc); | ||
1043 | if (ret) { | ||
1044 | if (ret != -EPROBE_DEFER) | ||
1045 | dev_err(&pdev->dev, | ||
1046 | "could not parse of data: %d\n", ret); | ||
1047 | goto err_free_host; | ||
1048 | } | ||
1049 | } else { | ||
1050 | /* JZ4740 should be the only one using legacy probe */ | ||
1051 | host->version = JZ_MMC_JZ4740; | ||
1052 | mmc->caps |= MMC_CAP_SDIO_IRQ; | ||
1053 | if (!(pdata && pdata->data_1bit)) | ||
1054 | mmc->caps |= MMC_CAP_4_BIT_DATA; | ||
1055 | ret = jz4740_mmc_request_gpios(mmc, pdev); | ||
1056 | if (ret) | ||
1057 | goto err_free_host; | ||
1058 | } | ||
1059 | |||
985 | host->irq = platform_get_irq(pdev, 0); | 1060 | host->irq = platform_get_irq(pdev, 0); |
986 | if (host->irq < 0) { | 1061 | if (host->irq < 0) { |
987 | ret = host->irq; | 1062 | ret = host->irq; |
@@ -1004,16 +1079,11 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
1004 | goto err_free_host; | 1079 | goto err_free_host; |
1005 | } | 1080 | } |
1006 | 1081 | ||
1007 | ret = jz4740_mmc_request_gpios(mmc, pdev); | ||
1008 | if (ret) | ||
1009 | goto err_release_dma; | ||
1010 | |||
1011 | mmc->ops = &jz4740_mmc_ops; | 1082 | mmc->ops = &jz4740_mmc_ops; |
1012 | mmc->f_min = JZ_MMC_CLK_RATE / 128; | 1083 | if (!mmc->f_max) |
1013 | mmc->f_max = JZ_MMC_CLK_RATE; | 1084 | mmc->f_max = JZ_MMC_CLK_RATE; |
1085 | mmc->f_min = mmc->f_max / 128; | ||
1014 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 1086 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
1015 | mmc->caps = (pdata && pdata->data_1bit) ? 0 : MMC_CAP_4_BIT_DATA; | ||
1016 | mmc->caps |= MMC_CAP_SDIO_IRQ; | ||
1017 | 1087 | ||
1018 | mmc->max_blk_size = (1 << 10) - 1; | 1088 | mmc->max_blk_size = (1 << 10) - 1; |
1019 | mmc->max_blk_count = (1 << 15) - 1; | 1089 | mmc->max_blk_count = (1 << 15) - 1; |
@@ -1025,7 +1095,9 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
1025 | host->mmc = mmc; | 1095 | host->mmc = mmc; |
1026 | host->pdev = pdev; | 1096 | host->pdev = pdev; |
1027 | spin_lock_init(&host->lock); | 1097 | spin_lock_init(&host->lock); |
1028 | host->irq_mask = 0xffff; | 1098 | host->irq_mask = ~0; |
1099 | |||
1100 | jz4740_mmc_reset(host); | ||
1029 | 1101 | ||
1030 | ret = request_threaded_irq(host->irq, jz_mmc_irq, jz_mmc_irq_worker, 0, | 1102 | ret = request_threaded_irq(host->irq, jz_mmc_irq, jz_mmc_irq_worker, 0, |
1031 | dev_name(&pdev->dev), host); | 1103 | dev_name(&pdev->dev), host); |
@@ -1034,20 +1106,20 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
1034 | goto err_free_gpios; | 1106 | goto err_free_gpios; |
1035 | } | 1107 | } |
1036 | 1108 | ||
1037 | jz4740_mmc_reset(host); | ||
1038 | jz4740_mmc_clock_disable(host); | 1109 | jz4740_mmc_clock_disable(host); |
1039 | timer_setup(&host->timeout_timer, jz4740_mmc_timeout, 0); | 1110 | timer_setup(&host->timeout_timer, jz4740_mmc_timeout, 0); |
1040 | 1111 | ||
1041 | host->use_dma = true; | 1112 | ret = jz4740_mmc_acquire_dma_channels(host); |
1042 | if (host->use_dma && jz4740_mmc_acquire_dma_channels(host) != 0) | 1113 | if (ret == -EPROBE_DEFER) |
1043 | host->use_dma = false; | 1114 | goto err_free_irq; |
1115 | host->use_dma = !ret; | ||
1044 | 1116 | ||
1045 | platform_set_drvdata(pdev, host); | 1117 | platform_set_drvdata(pdev, host); |
1046 | ret = mmc_add_host(mmc); | 1118 | ret = mmc_add_host(mmc); |
1047 | 1119 | ||
1048 | if (ret) { | 1120 | if (ret) { |
1049 | dev_err(&pdev->dev, "Failed to add mmc host: %d\n", ret); | 1121 | dev_err(&pdev->dev, "Failed to add mmc host: %d\n", ret); |
1050 | goto err_free_irq; | 1122 | goto err_release_dma; |
1051 | } | 1123 | } |
1052 | dev_info(&pdev->dev, "JZ SD/MMC card driver registered\n"); | 1124 | dev_info(&pdev->dev, "JZ SD/MMC card driver registered\n"); |
1053 | 1125 | ||
@@ -1057,13 +1129,13 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
1057 | 1129 | ||
1058 | return 0; | 1130 | return 0; |
1059 | 1131 | ||
1132 | err_release_dma: | ||
1133 | if (host->use_dma) | ||
1134 | jz4740_mmc_release_dma_channels(host); | ||
1060 | err_free_irq: | 1135 | err_free_irq: |
1061 | free_irq(host->irq, host); | 1136 | free_irq(host->irq, host); |
1062 | err_free_gpios: | 1137 | err_free_gpios: |
1063 | jz4740_mmc_free_gpios(pdev); | 1138 | jz4740_mmc_free_gpios(pdev); |
1064 | err_release_dma: | ||
1065 | if (host->use_dma) | ||
1066 | jz4740_mmc_release_dma_channels(host); | ||
1067 | err_free_host: | 1139 | err_free_host: |
1068 | mmc_free_host(mmc); | 1140 | mmc_free_host(mmc); |
1069 | 1141 | ||
@@ -1116,6 +1188,7 @@ static struct platform_driver jz4740_mmc_driver = { | |||
1116 | .remove = jz4740_mmc_remove, | 1188 | .remove = jz4740_mmc_remove, |
1117 | .driver = { | 1189 | .driver = { |
1118 | .name = "jz4740-mmc", | 1190 | .name = "jz4740-mmc", |
1191 | .of_match_table = of_match_ptr(jz4740_mmc_of_match), | ||
1119 | .pm = JZ4740_MMC_PM_OPS, | 1192 | .pm = JZ4740_MMC_PM_OPS, |
1120 | }, | 1193 | }, |
1121 | }; | 1194 | }; |
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 4f972b879fe6..c201c378537e 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/clk-provider.h> | 36 | #include <linux/clk-provider.h> |
37 | #include <linux/regulator/consumer.h> | 37 | #include <linux/regulator/consumer.h> |
38 | #include <linux/reset.h> | ||
38 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
39 | #include <linux/bitfield.h> | 40 | #include <linux/bitfield.h> |
40 | #include <linux/pinctrl/consumer.h> | 41 | #include <linux/pinctrl/consumer.h> |
@@ -47,15 +48,29 @@ | |||
47 | #define CLK_CORE_PHASE_MASK GENMASK(9, 8) | 48 | #define CLK_CORE_PHASE_MASK GENMASK(9, 8) |
48 | #define CLK_TX_PHASE_MASK GENMASK(11, 10) | 49 | #define CLK_TX_PHASE_MASK GENMASK(11, 10) |
49 | #define CLK_RX_PHASE_MASK GENMASK(13, 12) | 50 | #define CLK_RX_PHASE_MASK GENMASK(13, 12) |
50 | #define CLK_TX_DELAY_MASK GENMASK(19, 16) | 51 | #define CLK_V2_TX_DELAY_MASK GENMASK(19, 16) |
51 | #define CLK_RX_DELAY_MASK GENMASK(23, 20) | 52 | #define CLK_V2_RX_DELAY_MASK GENMASK(23, 20) |
53 | #define CLK_V2_ALWAYS_ON BIT(24) | ||
54 | |||
55 | #define CLK_V3_TX_DELAY_MASK GENMASK(21, 16) | ||
56 | #define CLK_V3_RX_DELAY_MASK GENMASK(27, 22) | ||
57 | #define CLK_V3_ALWAYS_ON BIT(28) | ||
58 | |||
52 | #define CLK_DELAY_STEP_PS 200 | 59 | #define CLK_DELAY_STEP_PS 200 |
53 | #define CLK_PHASE_STEP 30 | 60 | #define CLK_PHASE_STEP 30 |
54 | #define CLK_PHASE_POINT_NUM (360 / CLK_PHASE_STEP) | 61 | #define CLK_PHASE_POINT_NUM (360 / CLK_PHASE_STEP) |
55 | #define CLK_ALWAYS_ON BIT(24) | 62 | |
63 | #define CLK_TX_DELAY_MASK(h) (h->data->tx_delay_mask) | ||
64 | #define CLK_RX_DELAY_MASK(h) (h->data->rx_delay_mask) | ||
65 | #define CLK_ALWAYS_ON(h) (h->data->always_on) | ||
56 | 66 | ||
57 | #define SD_EMMC_DELAY 0x4 | 67 | #define SD_EMMC_DELAY 0x4 |
58 | #define SD_EMMC_ADJUST 0x8 | 68 | #define SD_EMMC_ADJUST 0x8 |
69 | |||
70 | #define SD_EMMC_DELAY1 0x4 | ||
71 | #define SD_EMMC_DELAY2 0x8 | ||
72 | #define SD_EMMC_V3_ADJUST 0xc | ||
73 | |||
59 | #define SD_EMMC_CALOUT 0x10 | 74 | #define SD_EMMC_CALOUT 0x10 |
60 | #define SD_EMMC_START 0x40 | 75 | #define SD_EMMC_START 0x40 |
61 | #define START_DESC_INIT BIT(0) | 76 | #define START_DESC_INIT BIT(0) |
@@ -122,6 +137,12 @@ | |||
122 | 137 | ||
123 | #define MUX_CLK_NUM_PARENTS 2 | 138 | #define MUX_CLK_NUM_PARENTS 2 |
124 | 139 | ||
140 | struct meson_mmc_data { | ||
141 | unsigned int tx_delay_mask; | ||
142 | unsigned int rx_delay_mask; | ||
143 | unsigned int always_on; | ||
144 | }; | ||
145 | |||
125 | struct sd_emmc_desc { | 146 | struct sd_emmc_desc { |
126 | u32 cmd_cfg; | 147 | u32 cmd_cfg; |
127 | u32 cmd_arg; | 148 | u32 cmd_arg; |
@@ -131,6 +152,7 @@ struct sd_emmc_desc { | |||
131 | 152 | ||
132 | struct meson_host { | 153 | struct meson_host { |
133 | struct device *dev; | 154 | struct device *dev; |
155 | struct meson_mmc_data *data; | ||
134 | struct mmc_host *mmc; | 156 | struct mmc_host *mmc; |
135 | struct mmc_command *cmd; | 157 | struct mmc_command *cmd; |
136 | 158 | ||
@@ -474,7 +496,7 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
474 | 496 | ||
475 | /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ | 497 | /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ |
476 | clk_reg = 0; | 498 | clk_reg = 0; |
477 | clk_reg |= CLK_ALWAYS_ON; | 499 | clk_reg |= CLK_ALWAYS_ON(host); |
478 | clk_reg |= CLK_DIV_MASK; | 500 | clk_reg |= CLK_DIV_MASK; |
479 | writel(clk_reg, host->regs + SD_EMMC_CLOCK); | 501 | writel(clk_reg, host->regs + SD_EMMC_CLOCK); |
480 | 502 | ||
@@ -574,7 +596,7 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
574 | 596 | ||
575 | tx->reg = host->regs + SD_EMMC_CLOCK; | 597 | tx->reg = host->regs + SD_EMMC_CLOCK; |
576 | tx->phase_mask = CLK_TX_PHASE_MASK; | 598 | tx->phase_mask = CLK_TX_PHASE_MASK; |
577 | tx->delay_mask = CLK_TX_DELAY_MASK; | 599 | tx->delay_mask = CLK_TX_DELAY_MASK(host); |
578 | tx->delay_step_ps = CLK_DELAY_STEP_PS; | 600 | tx->delay_step_ps = CLK_DELAY_STEP_PS; |
579 | tx->hw.init = &init; | 601 | tx->hw.init = &init; |
580 | 602 | ||
@@ -597,7 +619,7 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
597 | 619 | ||
598 | rx->reg = host->regs + SD_EMMC_CLOCK; | 620 | rx->reg = host->regs + SD_EMMC_CLOCK; |
599 | rx->phase_mask = CLK_RX_PHASE_MASK; | 621 | rx->phase_mask = CLK_RX_PHASE_MASK; |
600 | rx->delay_mask = CLK_RX_DELAY_MASK; | 622 | rx->delay_mask = CLK_RX_DELAY_MASK(host); |
601 | rx->delay_step_ps = CLK_DELAY_STEP_PS; | 623 | rx->delay_step_ps = CLK_DELAY_STEP_PS; |
602 | rx->hw.init = &init; | 624 | rx->hw.init = &init; |
603 | 625 | ||
@@ -1184,6 +1206,21 @@ static int meson_mmc_probe(struct platform_device *pdev) | |||
1184 | goto free_host; | 1206 | goto free_host; |
1185 | } | 1207 | } |
1186 | 1208 | ||
1209 | host->data = (struct meson_mmc_data *) | ||
1210 | of_device_get_match_data(&pdev->dev); | ||
1211 | if (!host->data) { | ||
1212 | ret = -EINVAL; | ||
1213 | goto free_host; | ||
1214 | } | ||
1215 | |||
1216 | ret = device_reset_optional(&pdev->dev); | ||
1217 | if (ret) { | ||
1218 | if (ret != -EPROBE_DEFER) | ||
1219 | dev_err(&pdev->dev, "device reset failed: %d\n", ret); | ||
1220 | |||
1221 | return ret; | ||
1222 | } | ||
1223 | |||
1187 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1224 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1188 | host->regs = devm_ioremap_resource(&pdev->dev, res); | 1225 | host->regs = devm_ioremap_resource(&pdev->dev, res); |
1189 | if (IS_ERR(host->regs)) { | 1226 | if (IS_ERR(host->regs)) { |
@@ -1315,11 +1352,24 @@ static int meson_mmc_remove(struct platform_device *pdev) | |||
1315 | return 0; | 1352 | return 0; |
1316 | } | 1353 | } |
1317 | 1354 | ||
1355 | static const struct meson_mmc_data meson_gx_data = { | ||
1356 | .tx_delay_mask = CLK_V2_TX_DELAY_MASK, | ||
1357 | .rx_delay_mask = CLK_V2_RX_DELAY_MASK, | ||
1358 | .always_on = CLK_V2_ALWAYS_ON, | ||
1359 | }; | ||
1360 | |||
1361 | static const struct meson_mmc_data meson_axg_data = { | ||
1362 | .tx_delay_mask = CLK_V3_TX_DELAY_MASK, | ||
1363 | .rx_delay_mask = CLK_V3_RX_DELAY_MASK, | ||
1364 | .always_on = CLK_V3_ALWAYS_ON, | ||
1365 | }; | ||
1366 | |||
1318 | static const struct of_device_id meson_mmc_of_match[] = { | 1367 | static const struct of_device_id meson_mmc_of_match[] = { |
1319 | { .compatible = "amlogic,meson-gx-mmc", }, | 1368 | { .compatible = "amlogic,meson-gx-mmc", .data = &meson_gx_data }, |
1320 | { .compatible = "amlogic,meson-gxbb-mmc", }, | 1369 | { .compatible = "amlogic,meson-gxbb-mmc", .data = &meson_gx_data }, |
1321 | { .compatible = "amlogic,meson-gxl-mmc", }, | 1370 | { .compatible = "amlogic,meson-gxl-mmc", .data = &meson_gx_data }, |
1322 | { .compatible = "amlogic,meson-gxm-mmc", }, | 1371 | { .compatible = "amlogic,meson-gxm-mmc", .data = &meson_gx_data }, |
1372 | { .compatible = "amlogic,meson-axg-mmc", .data = &meson_axg_data }, | ||
1323 | {} | 1373 | {} |
1324 | }; | 1374 | }; |
1325 | MODULE_DEVICE_TABLE(of, meson_mmc_of_match); | 1375 | MODULE_DEVICE_TABLE(of, meson_mmc_of_match); |
@@ -1335,6 +1385,6 @@ static struct platform_driver meson_mmc_driver = { | |||
1335 | 1385 | ||
1336 | module_platform_driver(meson_mmc_driver); | 1386 | module_platform_driver(meson_mmc_driver); |
1337 | 1387 | ||
1338 | MODULE_DESCRIPTION("Amlogic S905*/GX* SD/eMMC driver"); | 1388 | MODULE_DESCRIPTION("Amlogic S905*/GX*/AXG SD/eMMC driver"); |
1339 | MODULE_AUTHOR("Kevin Hilman <khilman@baylibre.com>"); | 1389 | MODULE_AUTHOR("Kevin Hilman <khilman@baylibre.com>"); |
1340 | MODULE_LICENSE("GPL v2"); | 1390 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 70b0df8b9c78..f1849775e47e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -1253,15 +1253,12 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) | |||
1253 | struct sg_mapping_iter *sg_miter = &host->sg_miter; | 1253 | struct sg_mapping_iter *sg_miter = &host->sg_miter; |
1254 | struct variant_data *variant = host->variant; | 1254 | struct variant_data *variant = host->variant; |
1255 | void __iomem *base = host->base; | 1255 | void __iomem *base = host->base; |
1256 | unsigned long flags; | ||
1257 | u32 status; | 1256 | u32 status; |
1258 | 1257 | ||
1259 | status = readl(base + MMCISTATUS); | 1258 | status = readl(base + MMCISTATUS); |
1260 | 1259 | ||
1261 | dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); | 1260 | dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); |
1262 | 1261 | ||
1263 | local_irq_save(flags); | ||
1264 | |||
1265 | do { | 1262 | do { |
1266 | unsigned int remain, len; | 1263 | unsigned int remain, len; |
1267 | char *buffer; | 1264 | char *buffer; |
@@ -1301,8 +1298,6 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) | |||
1301 | 1298 | ||
1302 | sg_miter_stop(sg_miter); | 1299 | sg_miter_stop(sg_miter); |
1303 | 1300 | ||
1304 | local_irq_restore(flags); | ||
1305 | |||
1306 | /* | 1301 | /* |
1307 | * If we have less than the fifo 'half-full' threshold to transfer, | 1302 | * If we have less than the fifo 'half-full' threshold to transfer, |
1308 | * trigger a PIO interrupt as soon as any data is available. | 1303 | * trigger a PIO interrupt as soon as any data is available. |
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index cb274e822293..04841386b65d 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/ioport.h> | 19 | #include <linux/ioport.h> |
20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
22 | #include <linux/of_device.h> | ||
22 | #include <linux/of_irq.h> | 23 | #include <linux/of_irq.h> |
23 | #include <linux/of_gpio.h> | 24 | #include <linux/of_gpio.h> |
24 | #include <linux/pinctrl/consumer.h> | 25 | #include <linux/pinctrl/consumer.h> |
@@ -70,6 +71,7 @@ | |||
70 | #define SDC_ADV_CFG0 0x64 | 71 | #define SDC_ADV_CFG0 0x64 |
71 | #define EMMC_IOCON 0x7c | 72 | #define EMMC_IOCON 0x7c |
72 | #define SDC_ACMD_RESP 0x80 | 73 | #define SDC_ACMD_RESP 0x80 |
74 | #define DMA_SA_H4BIT 0x8c | ||
73 | #define MSDC_DMA_SA 0x90 | 75 | #define MSDC_DMA_SA 0x90 |
74 | #define MSDC_DMA_CTRL 0x98 | 76 | #define MSDC_DMA_CTRL 0x98 |
75 | #define MSDC_DMA_CFG 0x9c | 77 | #define MSDC_DMA_CFG 0x9c |
@@ -194,6 +196,9 @@ | |||
194 | /* SDC_ADV_CFG0 mask */ | 196 | /* SDC_ADV_CFG0 mask */ |
195 | #define SDC_RX_ENHANCE_EN (0x1 << 20) /* RW */ | 197 | #define SDC_RX_ENHANCE_EN (0x1 << 20) /* RW */ |
196 | 198 | ||
199 | /* DMA_SA_H4BIT mask */ | ||
200 | #define DMA_ADDR_HIGH_4BIT (0xf << 0) /* RW */ | ||
201 | |||
197 | /* MSDC_DMA_CTRL mask */ | 202 | /* MSDC_DMA_CTRL mask */ |
198 | #define MSDC_DMA_CTRL_START (0x1 << 0) /* W */ | 203 | #define MSDC_DMA_CTRL_START (0x1 << 0) /* W */ |
199 | #define MSDC_DMA_CTRL_STOP (0x1 << 1) /* W */ | 204 | #define MSDC_DMA_CTRL_STOP (0x1 << 1) /* W */ |
@@ -227,6 +232,7 @@ | |||
227 | 232 | ||
228 | #define MSDC_PATCH_BIT2_CFGRESP (0x1 << 15) /* RW */ | 233 | #define MSDC_PATCH_BIT2_CFGRESP (0x1 << 15) /* RW */ |
229 | #define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28) /* RW */ | 234 | #define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28) /* RW */ |
235 | #define MSDC_PB2_SUPPORT_64G (0x1 << 1) /* RW */ | ||
230 | #define MSDC_PB2_RESPWAIT (0x3 << 2) /* RW */ | 236 | #define MSDC_PB2_RESPWAIT (0x3 << 2) /* RW */ |
231 | #define MSDC_PB2_RESPSTSENSEL (0x7 << 16) /* RW */ | 237 | #define MSDC_PB2_RESPSTSENSEL (0x7 << 16) /* RW */ |
232 | #define MSDC_PB2_CRCSTSENSEL (0x7 << 29) /* RW */ | 238 | #define MSDC_PB2_CRCSTSENSEL (0x7 << 29) /* RW */ |
@@ -280,6 +286,8 @@ struct mt_gpdma_desc { | |||
280 | #define GPDMA_DESC_BDP (0x1 << 1) | 286 | #define GPDMA_DESC_BDP (0x1 << 1) |
281 | #define GPDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ | 287 | #define GPDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ |
282 | #define GPDMA_DESC_INT (0x1 << 16) | 288 | #define GPDMA_DESC_INT (0x1 << 16) |
289 | #define GPDMA_DESC_NEXT_H4 (0xf << 24) | ||
290 | #define GPDMA_DESC_PTR_H4 (0xf << 28) | ||
283 | u32 next; | 291 | u32 next; |
284 | u32 ptr; | 292 | u32 ptr; |
285 | u32 gpd_data_len; | 293 | u32 gpd_data_len; |
@@ -296,6 +304,8 @@ struct mt_bdma_desc { | |||
296 | #define BDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ | 304 | #define BDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ |
297 | #define BDMA_DESC_BLKPAD (0x1 << 17) | 305 | #define BDMA_DESC_BLKPAD (0x1 << 17) |
298 | #define BDMA_DESC_DWPAD (0x1 << 18) | 306 | #define BDMA_DESC_DWPAD (0x1 << 18) |
307 | #define BDMA_DESC_NEXT_H4 (0xf << 24) | ||
308 | #define BDMA_DESC_PTR_H4 (0xf << 28) | ||
299 | u32 next; | 309 | u32 next; |
300 | u32 ptr; | 310 | u32 ptr; |
301 | u32 bd_data_len; | 311 | u32 bd_data_len; |
@@ -334,6 +344,7 @@ struct mtk_mmc_compatible { | |||
334 | bool busy_check; | 344 | bool busy_check; |
335 | bool stop_clk_fix; | 345 | bool stop_clk_fix; |
336 | bool enhance_rx; | 346 | bool enhance_rx; |
347 | bool support_64g; | ||
337 | }; | 348 | }; |
338 | 349 | ||
339 | struct msdc_tune_para { | 350 | struct msdc_tune_para { |
@@ -403,6 +414,7 @@ static const struct mtk_mmc_compatible mt8135_compat = { | |||
403 | .busy_check = false, | 414 | .busy_check = false, |
404 | .stop_clk_fix = false, | 415 | .stop_clk_fix = false, |
405 | .enhance_rx = false, | 416 | .enhance_rx = false, |
417 | .support_64g = false, | ||
406 | }; | 418 | }; |
407 | 419 | ||
408 | static const struct mtk_mmc_compatible mt8173_compat = { | 420 | static const struct mtk_mmc_compatible mt8173_compat = { |
@@ -414,6 +426,7 @@ static const struct mtk_mmc_compatible mt8173_compat = { | |||
414 | .busy_check = false, | 426 | .busy_check = false, |
415 | .stop_clk_fix = false, | 427 | .stop_clk_fix = false, |
416 | .enhance_rx = false, | 428 | .enhance_rx = false, |
429 | .support_64g = false, | ||
417 | }; | 430 | }; |
418 | 431 | ||
419 | static const struct mtk_mmc_compatible mt2701_compat = { | 432 | static const struct mtk_mmc_compatible mt2701_compat = { |
@@ -425,6 +438,7 @@ static const struct mtk_mmc_compatible mt2701_compat = { | |||
425 | .busy_check = false, | 438 | .busy_check = false, |
426 | .stop_clk_fix = false, | 439 | .stop_clk_fix = false, |
427 | .enhance_rx = false, | 440 | .enhance_rx = false, |
441 | .support_64g = false, | ||
428 | }; | 442 | }; |
429 | 443 | ||
430 | static const struct mtk_mmc_compatible mt2712_compat = { | 444 | static const struct mtk_mmc_compatible mt2712_compat = { |
@@ -436,6 +450,7 @@ static const struct mtk_mmc_compatible mt2712_compat = { | |||
436 | .busy_check = true, | 450 | .busy_check = true, |
437 | .stop_clk_fix = true, | 451 | .stop_clk_fix = true, |
438 | .enhance_rx = true, | 452 | .enhance_rx = true, |
453 | .support_64g = true, | ||
439 | }; | 454 | }; |
440 | 455 | ||
441 | static const struct mtk_mmc_compatible mt7622_compat = { | 456 | static const struct mtk_mmc_compatible mt7622_compat = { |
@@ -447,6 +462,7 @@ static const struct mtk_mmc_compatible mt7622_compat = { | |||
447 | .busy_check = true, | 462 | .busy_check = true, |
448 | .stop_clk_fix = true, | 463 | .stop_clk_fix = true, |
449 | .enhance_rx = true, | 464 | .enhance_rx = true, |
465 | .support_64g = false, | ||
450 | }; | 466 | }; |
451 | 467 | ||
452 | static const struct of_device_id msdc_of_ids[] = { | 468 | static const struct of_device_id msdc_of_ids[] = { |
@@ -556,7 +572,12 @@ static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, | |||
556 | /* init bd */ | 572 | /* init bd */ |
557 | bd[j].bd_info &= ~BDMA_DESC_BLKPAD; | 573 | bd[j].bd_info &= ~BDMA_DESC_BLKPAD; |
558 | bd[j].bd_info &= ~BDMA_DESC_DWPAD; | 574 | bd[j].bd_info &= ~BDMA_DESC_DWPAD; |
559 | bd[j].ptr = (u32)dma_address; | 575 | bd[j].ptr = lower_32_bits(dma_address); |
576 | if (host->dev_comp->support_64g) { | ||
577 | bd[j].bd_info &= ~BDMA_DESC_PTR_H4; | ||
578 | bd[j].bd_info |= (upper_32_bits(dma_address) & 0xf) | ||
579 | << 28; | ||
580 | } | ||
560 | bd[j].bd_data_len &= ~BDMA_DESC_BUFLEN; | 581 | bd[j].bd_data_len &= ~BDMA_DESC_BUFLEN; |
561 | bd[j].bd_data_len |= (dma_len & BDMA_DESC_BUFLEN); | 582 | bd[j].bd_data_len |= (dma_len & BDMA_DESC_BUFLEN); |
562 | 583 | ||
@@ -575,7 +596,10 @@ static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, | |||
575 | dma_ctrl &= ~(MSDC_DMA_CTRL_BRUSTSZ | MSDC_DMA_CTRL_MODE); | 596 | dma_ctrl &= ~(MSDC_DMA_CTRL_BRUSTSZ | MSDC_DMA_CTRL_MODE); |
576 | dma_ctrl |= (MSDC_BURST_64B << 12 | 1 << 8); | 597 | dma_ctrl |= (MSDC_BURST_64B << 12 | 1 << 8); |
577 | writel_relaxed(dma_ctrl, host->base + MSDC_DMA_CTRL); | 598 | writel_relaxed(dma_ctrl, host->base + MSDC_DMA_CTRL); |
578 | writel((u32)dma->gpd_addr, host->base + MSDC_DMA_SA); | 599 | if (host->dev_comp->support_64g) |
600 | sdr_set_field(host->base + DMA_SA_H4BIT, DMA_ADDR_HIGH_4BIT, | ||
601 | upper_32_bits(dma->gpd_addr) & 0xf); | ||
602 | writel(lower_32_bits(dma->gpd_addr), host->base + MSDC_DMA_SA); | ||
579 | } | 603 | } |
580 | 604 | ||
581 | static void msdc_prepare_data(struct msdc_host *host, struct mmc_request *mrq) | 605 | static void msdc_prepare_data(struct msdc_host *host, struct mmc_request *mrq) |
@@ -1366,6 +1390,9 @@ static void msdc_init_hw(struct msdc_host *host) | |||
1366 | MSDC_PATCH_BIT2_CFGCRCSTS); | 1390 | MSDC_PATCH_BIT2_CFGCRCSTS); |
1367 | } | 1391 | } |
1368 | 1392 | ||
1393 | if (host->dev_comp->support_64g) | ||
1394 | sdr_set_bits(host->base + MSDC_PATCH_BIT2, | ||
1395 | MSDC_PB2_SUPPORT_64G); | ||
1369 | if (host->dev_comp->data_tune) { | 1396 | if (host->dev_comp->data_tune) { |
1370 | sdr_set_bits(host->base + tune_reg, | 1397 | sdr_set_bits(host->base + tune_reg, |
1371 | MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); | 1398 | MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); |
@@ -1407,19 +1434,32 @@ static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma) | |||
1407 | { | 1434 | { |
1408 | struct mt_gpdma_desc *gpd = dma->gpd; | 1435 | struct mt_gpdma_desc *gpd = dma->gpd; |
1409 | struct mt_bdma_desc *bd = dma->bd; | 1436 | struct mt_bdma_desc *bd = dma->bd; |
1437 | dma_addr_t dma_addr; | ||
1410 | int i; | 1438 | int i; |
1411 | 1439 | ||
1412 | memset(gpd, 0, sizeof(struct mt_gpdma_desc) * 2); | 1440 | memset(gpd, 0, sizeof(struct mt_gpdma_desc) * 2); |
1413 | 1441 | ||
1442 | dma_addr = dma->gpd_addr + sizeof(struct mt_gpdma_desc); | ||
1414 | gpd->gpd_info = GPDMA_DESC_BDP; /* hwo, cs, bd pointer */ | 1443 | gpd->gpd_info = GPDMA_DESC_BDP; /* hwo, cs, bd pointer */ |
1415 | gpd->ptr = (u32)dma->bd_addr; /* physical address */ | ||
1416 | /* gpd->next is must set for desc DMA | 1444 | /* gpd->next is must set for desc DMA |
1417 | * That's why must alloc 2 gpd structure. | 1445 | * That's why must alloc 2 gpd structure. |
1418 | */ | 1446 | */ |
1419 | gpd->next = (u32)dma->gpd_addr + sizeof(struct mt_gpdma_desc); | 1447 | gpd->next = lower_32_bits(dma_addr); |
1448 | if (host->dev_comp->support_64g) | ||
1449 | gpd->gpd_info |= (upper_32_bits(dma_addr) & 0xf) << 24; | ||
1450 | |||
1451 | dma_addr = dma->bd_addr; | ||
1452 | gpd->ptr = lower_32_bits(dma->bd_addr); /* physical address */ | ||
1453 | if (host->dev_comp->support_64g) | ||
1454 | gpd->gpd_info |= (upper_32_bits(dma_addr) & 0xf) << 28; | ||
1455 | |||
1420 | memset(bd, 0, sizeof(struct mt_bdma_desc) * MAX_BD_NUM); | 1456 | memset(bd, 0, sizeof(struct mt_bdma_desc) * MAX_BD_NUM); |
1421 | for (i = 0; i < (MAX_BD_NUM - 1); i++) | 1457 | for (i = 0; i < (MAX_BD_NUM - 1); i++) { |
1422 | bd[i].next = (u32)dma->bd_addr + sizeof(*bd) * (i + 1); | 1458 | dma_addr = dma->bd_addr + sizeof(*bd) * (i + 1); |
1459 | bd[i].next = lower_32_bits(dma_addr); | ||
1460 | if (host->dev_comp->support_64g) | ||
1461 | bd[i].bd_info |= (upper_32_bits(dma_addr) & 0xf) << 24; | ||
1462 | } | ||
1423 | } | 1463 | } |
1424 | 1464 | ||
1425 | static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 1465 | static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
@@ -1820,7 +1860,6 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
1820 | struct mmc_host *mmc; | 1860 | struct mmc_host *mmc; |
1821 | struct msdc_host *host; | 1861 | struct msdc_host *host; |
1822 | struct resource *res; | 1862 | struct resource *res; |
1823 | const struct of_device_id *of_id; | ||
1824 | int ret; | 1863 | int ret; |
1825 | 1864 | ||
1826 | if (!pdev->dev.of_node) { | 1865 | if (!pdev->dev.of_node) { |
@@ -1828,9 +1867,6 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
1828 | return -EINVAL; | 1867 | return -EINVAL; |
1829 | } | 1868 | } |
1830 | 1869 | ||
1831 | of_id = of_match_node(msdc_of_ids, pdev->dev.of_node); | ||
1832 | if (!of_id) | ||
1833 | return -EINVAL; | ||
1834 | /* Allocate MMC host for this device */ | 1870 | /* Allocate MMC host for this device */ |
1835 | mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); | 1871 | mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); |
1836 | if (!mmc) | 1872 | if (!mmc) |
@@ -1899,7 +1935,7 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
1899 | msdc_of_property_parse(pdev, host); | 1935 | msdc_of_property_parse(pdev, host); |
1900 | 1936 | ||
1901 | host->dev = &pdev->dev; | 1937 | host->dev = &pdev->dev; |
1902 | host->dev_comp = of_id->data; | 1938 | host->dev_comp = of_device_get_match_data(&pdev->dev); |
1903 | host->mmc = mmc; | 1939 | host->mmc = mmc; |
1904 | host->src_clk_freq = clk_get_rate(host->src_clk); | 1940 | host->src_clk_freq = clk_get_rate(host->src_clk); |
1905 | /* Set host parameters to mmc */ | 1941 | /* Set host parameters to mmc */ |
@@ -1916,7 +1952,10 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
1916 | mmc->max_blk_size = 2048; | 1952 | mmc->max_blk_size = 2048; |
1917 | mmc->max_req_size = 512 * 1024; | 1953 | mmc->max_req_size = 512 * 1024; |
1918 | mmc->max_blk_count = mmc->max_req_size / 512; | 1954 | mmc->max_blk_count = mmc->max_req_size / 512; |
1919 | host->dma_mask = DMA_BIT_MASK(32); | 1955 | if (host->dev_comp->support_64g) |
1956 | host->dma_mask = DMA_BIT_MASK(36); | ||
1957 | else | ||
1958 | host->dma_mask = DMA_BIT_MASK(32); | ||
1920 | mmc_dev(mmc)->dma_mask = &host->dma_mask; | 1959 | mmc_dev(mmc)->dma_mask = &host->dma_mask; |
1921 | 1960 | ||
1922 | host->timeout_clks = 3 * 1048576; | 1961 | host->timeout_clks = 3 * 1048576; |
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index 210247b3d11a..e22bbff89c8d 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c | |||
@@ -143,6 +143,7 @@ static void mvsd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
143 | struct mmc_command *cmd = mrq->cmd; | 143 | struct mmc_command *cmd = mrq->cmd; |
144 | u32 cmdreg = 0, xfer = 0, intr = 0; | 144 | u32 cmdreg = 0, xfer = 0, intr = 0; |
145 | unsigned long flags; | 145 | unsigned long flags; |
146 | unsigned int timeout; | ||
146 | 147 | ||
147 | BUG_ON(host->mrq != NULL); | 148 | BUG_ON(host->mrq != NULL); |
148 | host->mrq = mrq; | 149 | host->mrq = mrq; |
@@ -234,7 +235,8 @@ static void mvsd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
234 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); | 235 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); |
235 | mvsd_write(MVSD_ERR_INTR_EN, 0xffff); | 236 | mvsd_write(MVSD_ERR_INTR_EN, 0xffff); |
236 | 237 | ||
237 | mod_timer(&host->timer, jiffies + 5 * HZ); | 238 | timeout = cmd->busy_timeout ? cmd->busy_timeout : 5000; |
239 | mod_timer(&host->timer, jiffies + msecs_to_jiffies(timeout)); | ||
238 | 240 | ||
239 | spin_unlock_irqrestore(&host->lock, flags); | 241 | spin_unlock_irqrestore(&host->lock, flags); |
240 | } | 242 | } |
@@ -755,6 +757,8 @@ static int mvsd_probe(struct platform_device *pdev) | |||
755 | if (maxfreq) | 757 | if (maxfreq) |
756 | mmc->f_max = maxfreq; | 758 | mmc->f_max = maxfreq; |
757 | 759 | ||
760 | mmc->caps |= MMC_CAP_ERASE; | ||
761 | |||
758 | spin_lock_init(&host->lock); | 762 | spin_lock_init(&host->lock); |
759 | 763 | ||
760 | host->base = devm_ioremap_resource(&pdev->dev, r); | 764 | host->base = devm_ioremap_resource(&pdev->dev, r); |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 5ff8ef7223cc..75f781c11e89 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/highmem.h> | ||
24 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
25 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
26 | #include <linux/blkdev.h> | 27 | #include <linux/blkdev.h> |
@@ -291,8 +292,10 @@ static void mxcmci_swap_buffers(struct mmc_data *data) | |||
291 | struct scatterlist *sg; | 292 | struct scatterlist *sg; |
292 | int i; | 293 | int i; |
293 | 294 | ||
294 | for_each_sg(data->sg, sg, data->sg_len, i) | 295 | for_each_sg(data->sg, sg, data->sg_len, i) { |
295 | buffer_swap32(sg_virt(sg), sg->length); | 296 | void *buf = kmap_atomic(sg_page(sg) + sg->offset; |
297 | buffer_swap32(buf, sg->length); | ||
298 | kunmap_atomic(buf); | ||
296 | } | 299 | } |
297 | #else | 300 | #else |
298 | static inline void mxcmci_swap_buffers(struct mmc_data *data) {} | 301 | static inline void mxcmci_swap_buffers(struct mmc_data *data) {} |
@@ -609,6 +612,7 @@ static int mxcmci_transfer_data(struct mxcmci_host *host) | |||
609 | { | 612 | { |
610 | struct mmc_data *data = host->req->data; | 613 | struct mmc_data *data = host->req->data; |
611 | struct scatterlist *sg; | 614 | struct scatterlist *sg; |
615 | void *buf; | ||
612 | int stat, i; | 616 | int stat, i; |
613 | 617 | ||
614 | host->data = data; | 618 | host->data = data; |
@@ -616,14 +620,18 @@ static int mxcmci_transfer_data(struct mxcmci_host *host) | |||
616 | 620 | ||
617 | if (data->flags & MMC_DATA_READ) { | 621 | if (data->flags & MMC_DATA_READ) { |
618 | for_each_sg(data->sg, sg, data->sg_len, i) { | 622 | for_each_sg(data->sg, sg, data->sg_len, i) { |
619 | stat = mxcmci_pull(host, sg_virt(sg), sg->length); | 623 | buf = kmap_atomic(sg_page(sg) + sg->offset); |
624 | stat = mxcmci_pull(host, buf, sg->length); | ||
625 | kunmap(buf); | ||
620 | if (stat) | 626 | if (stat) |
621 | return stat; | 627 | return stat; |
622 | host->datasize += sg->length; | 628 | host->datasize += sg->length; |
623 | } | 629 | } |
624 | } else { | 630 | } else { |
625 | for_each_sg(data->sg, sg, data->sg_len, i) { | 631 | for_each_sg(data->sg, sg, data->sg_len, i) { |
626 | stat = mxcmci_push(host, sg_virt(sg), sg->length); | 632 | buf = kmap_atomic(sg_page(sg) + sg->offset); |
633 | stat = mxcmci_push(host, buf, sg->length); | ||
634 | kunmap(buf); | ||
627 | if (stat) | 635 | if (stat) |
628 | return stat; | 636 | return stat; |
629 | host->datasize += sg->length; | 637 | host->datasize += sg->length; |
@@ -1206,7 +1214,8 @@ static int mxcmci_remove(struct platform_device *pdev) | |||
1206 | return 0; | 1214 | return 0; |
1207 | } | 1215 | } |
1208 | 1216 | ||
1209 | static int __maybe_unused mxcmci_suspend(struct device *dev) | 1217 | #ifdef CONFIG_PM_SLEEP |
1218 | static int mxcmci_suspend(struct device *dev) | ||
1210 | { | 1219 | { |
1211 | struct mmc_host *mmc = dev_get_drvdata(dev); | 1220 | struct mmc_host *mmc = dev_get_drvdata(dev); |
1212 | struct mxcmci_host *host = mmc_priv(mmc); | 1221 | struct mxcmci_host *host = mmc_priv(mmc); |
@@ -1216,7 +1225,7 @@ static int __maybe_unused mxcmci_suspend(struct device *dev) | |||
1216 | return 0; | 1225 | return 0; |
1217 | } | 1226 | } |
1218 | 1227 | ||
1219 | static int __maybe_unused mxcmci_resume(struct device *dev) | 1228 | static int mxcmci_resume(struct device *dev) |
1220 | { | 1229 | { |
1221 | struct mmc_host *mmc = dev_get_drvdata(dev); | 1230 | struct mmc_host *mmc = dev_get_drvdata(dev); |
1222 | struct mxcmci_host *host = mmc_priv(mmc); | 1231 | struct mxcmci_host *host = mmc_priv(mmc); |
@@ -1232,6 +1241,7 @@ static int __maybe_unused mxcmci_resume(struct device *dev) | |||
1232 | 1241 | ||
1233 | return ret; | 1242 | return ret; |
1234 | } | 1243 | } |
1244 | #endif | ||
1235 | 1245 | ||
1236 | static SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume); | 1246 | static SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume); |
1237 | 1247 | ||
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index 51e01f03fb99..45c015da2e75 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/of_device.h> | 28 | #include <linux/of_device.h> |
29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/mmc/host.h> | 30 | #include <linux/mmc/host.h> |
31 | #include <linux/mmc/slot-gpio.h> | ||
31 | #include <linux/mfd/tmio.h> | 32 | #include <linux/mfd/tmio.h> |
32 | #include <linux/sh_dma.h> | 33 | #include <linux/sh_dma.h> |
33 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
@@ -534,6 +535,10 @@ int renesas_sdhi_probe(struct platform_device *pdev, | |||
534 | host->multi_io_quirk = renesas_sdhi_multi_io_quirk; | 535 | host->multi_io_quirk = renesas_sdhi_multi_io_quirk; |
535 | host->dma_ops = dma_ops; | 536 | host->dma_ops = dma_ops; |
536 | 537 | ||
538 | /* For some SoC, we disable internal WP. GPIO may override this */ | ||
539 | if (mmc_can_gpio_ro(host->mmc)) | ||
540 | mmc_data->capabilities2 &= ~MMC_CAP2_NO_WRITE_PROTECT; | ||
541 | |||
537 | /* SDR speeds are only available on Gen2+ */ | 542 | /* SDR speeds are only available on Gen2+ */ |
538 | if (mmc_data->flags & TMIO_MMC_MIN_RCAR2) { | 543 | if (mmc_data->flags & TMIO_MMC_MIN_RCAR2) { |
539 | /* card_busy caused issues on r8a73a4 (pre-Gen2) CD-less SDHI */ | 544 | /* card_busy caused issues on r8a73a4 (pre-Gen2) CD-less SDHI */ |
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index 6af946d16d24..f7f9773d161f 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c | |||
@@ -87,11 +87,12 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { | |||
87 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, | 87 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, |
88 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | | 88 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
89 | MMC_CAP_CMD23, | 89 | MMC_CAP_CMD23, |
90 | .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, | ||
90 | .bus_shift = 2, | 91 | .bus_shift = 2, |
91 | .scc_offset = 0x1000, | 92 | .scc_offset = 0x1000, |
92 | .taps = rcar_gen3_scc_taps, | 93 | .taps = rcar_gen3_scc_taps, |
93 | .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps), | 94 | .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps), |
94 | /* Gen3 SDHI DMAC can handle 0xffffffff blk count, but seg = 1 */ | 95 | /* DMAC can handle 0xffffffff blk count but only 1 segment */ |
95 | .max_blk_count = 0xffffffff, | 96 | .max_blk_count = 0xffffffff, |
96 | .max_segs = 1, | 97 | .max_segs = 1, |
97 | }; | 98 | }; |
@@ -157,38 +158,34 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, | |||
157 | { | 158 | { |
158 | struct scatterlist *sg = host->sg_ptr; | 159 | struct scatterlist *sg = host->sg_ptr; |
159 | u32 dtran_mode = DTRAN_MODE_BUS_WID_TH | DTRAN_MODE_ADDR_MODE; | 160 | u32 dtran_mode = DTRAN_MODE_BUS_WID_TH | DTRAN_MODE_ADDR_MODE; |
160 | enum dma_data_direction dir; | ||
161 | int ret; | ||
162 | 161 | ||
163 | /* This DMAC cannot handle if sg_len is not 1 */ | 162 | if (!dma_map_sg(&host->pdev->dev, sg, host->sg_len, |
164 | WARN_ON(host->sg_len > 1); | 163 | mmc_get_dma_dir(data))) |
164 | goto force_pio; | ||
165 | 165 | ||
166 | /* This DMAC cannot handle if buffer is not 8-bytes alignment */ | 166 | /* This DMAC cannot handle if buffer is not 8-bytes alignment */ |
167 | if (!IS_ALIGNED(sg->offset, 8)) | 167 | if (!IS_ALIGNED(sg_dma_address(sg), 8)) { |
168 | dma_unmap_sg(&host->pdev->dev, sg, host->sg_len, | ||
169 | mmc_get_dma_dir(data)); | ||
168 | goto force_pio; | 170 | goto force_pio; |
171 | } | ||
169 | 172 | ||
170 | if (data->flags & MMC_DATA_READ) { | 173 | if (data->flags & MMC_DATA_READ) { |
171 | dtran_mode |= DTRAN_MODE_CH_NUM_CH1; | 174 | dtran_mode |= DTRAN_MODE_CH_NUM_CH1; |
172 | dir = DMA_FROM_DEVICE; | ||
173 | if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) && | 175 | if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) && |
174 | test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags)) | 176 | test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags)) |
175 | goto force_pio; | 177 | goto force_pio; |
176 | } else { | 178 | } else { |
177 | dtran_mode |= DTRAN_MODE_CH_NUM_CH0; | 179 | dtran_mode |= DTRAN_MODE_CH_NUM_CH0; |
178 | dir = DMA_TO_DEVICE; | ||
179 | } | 180 | } |
180 | 181 | ||
181 | ret = dma_map_sg(&host->pdev->dev, sg, host->sg_len, dir); | ||
182 | if (ret == 0) | ||
183 | goto force_pio; | ||
184 | |||
185 | renesas_sdhi_internal_dmac_enable_dma(host, true); | 182 | renesas_sdhi_internal_dmac_enable_dma(host, true); |
186 | 183 | ||
187 | /* set dma parameters */ | 184 | /* set dma parameters */ |
188 | renesas_sdhi_internal_dmac_dm_write(host, DM_CM_DTRAN_MODE, | 185 | renesas_sdhi_internal_dmac_dm_write(host, DM_CM_DTRAN_MODE, |
189 | dtran_mode); | 186 | dtran_mode); |
190 | renesas_sdhi_internal_dmac_dm_write(host, DM_DTRAN_ADDR, | 187 | renesas_sdhi_internal_dmac_dm_write(host, DM_DTRAN_ADDR, |
191 | sg->dma_address); | 188 | sg_dma_address(sg)); |
192 | 189 | ||
193 | return; | 190 | return; |
194 | 191 | ||
@@ -272,12 +269,17 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_internal_dmac_dma_ops = { | |||
272 | * implementation as others may use a different implementation. | 269 | * implementation as others may use a different implementation. |
273 | */ | 270 | */ |
274 | static const struct soc_device_attribute gen3_soc_whitelist[] = { | 271 | static const struct soc_device_attribute gen3_soc_whitelist[] = { |
272 | /* specific ones */ | ||
275 | { .soc_id = "r8a7795", .revision = "ES1.*", | 273 | { .soc_id = "r8a7795", .revision = "ES1.*", |
276 | .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) }, | 274 | .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) }, |
277 | { .soc_id = "r8a7795", .revision = "ES2.0" }, | ||
278 | { .soc_id = "r8a7796", .revision = "ES1.0", | 275 | { .soc_id = "r8a7796", .revision = "ES1.0", |
279 | .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) }, | 276 | .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) }, |
280 | { .soc_id = "r8a77995", .revision = "ES1.0" }, | 277 | /* generic ones */ |
278 | { .soc_id = "r8a7795" }, | ||
279 | { .soc_id = "r8a7796" }, | ||
280 | { .soc_id = "r8a77965" }, | ||
281 | { .soc_id = "r8a77980" }, | ||
282 | { .soc_id = "r8a77995" }, | ||
281 | { /* sentinel */ } | 283 | { /* sentinel */ } |
282 | }; | 284 | }; |
283 | 285 | ||
diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c index 848e50c1638a..4bb46c489d71 100644 --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c | |||
@@ -42,6 +42,7 @@ static const struct renesas_sdhi_of_data of_rz_compatible = { | |||
42 | static const struct renesas_sdhi_of_data of_rcar_gen1_compatible = { | 42 | static const struct renesas_sdhi_of_data of_rcar_gen1_compatible = { |
43 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL, | 43 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL, |
44 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, | 44 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, |
45 | .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, | ||
45 | }; | 46 | }; |
46 | 47 | ||
47 | /* Definitions for sampling clocks */ | 48 | /* Definitions for sampling clocks */ |
@@ -61,6 +62,7 @@ static const struct renesas_sdhi_of_data of_rcar_gen2_compatible = { | |||
61 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, | 62 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, |
62 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | | 63 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
63 | MMC_CAP_CMD23, | 64 | MMC_CAP_CMD23, |
65 | .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, | ||
64 | .dma_buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES, | 66 | .dma_buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES, |
65 | .dma_rx_offset = 0x2000, | 67 | .dma_rx_offset = 0x2000, |
66 | .scc_offset = 0x0300, | 68 | .scc_offset = 0x0300, |
@@ -81,6 +83,7 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { | |||
81 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, | 83 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, |
82 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | | 84 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
83 | MMC_CAP_CMD23, | 85 | MMC_CAP_CMD23, |
86 | .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, | ||
84 | .bus_shift = 2, | 87 | .bus_shift = 2, |
85 | .scc_offset = 0x1000, | 88 | .scc_offset = 0x1000, |
86 | .taps = rcar_gen3_scc_taps, | 89 | .taps = rcar_gen3_scc_taps, |
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c index 78422079ecfa..9a3ff22dd0fe 100644 --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
27 | #include <linux/mmc/mmc.h> | 27 | #include <linux/mmc/mmc.h> |
28 | #include <linux/mmc/sd.h> | 28 | #include <linux/mmc/sd.h> |
29 | #include <linux/mmc/sdio.h> | ||
30 | #include <linux/mmc/card.h> | 29 | #include <linux/mmc/card.h> |
31 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
32 | #include <linux/pm_runtime.h> | 31 | #include <linux/pm_runtime.h> |
@@ -343,7 +342,7 @@ static void sd_send_cmd_get_rsp(struct rtsx_usb_sdmmc *host, | |||
343 | } | 342 | } |
344 | 343 | ||
345 | if (rsp_type == SD_RSP_TYPE_R1b) | 344 | if (rsp_type == SD_RSP_TYPE_R1b) |
346 | timeout = 3000; | 345 | timeout = cmd->busy_timeout ? cmd->busy_timeout : 3000; |
347 | 346 | ||
348 | if (cmd->opcode == SD_SWITCH_VOLTAGE) { | 347 | if (cmd->opcode == SD_SWITCH_VOLTAGE) { |
349 | err = rtsx_usb_write_register(ucr, SD_BUS_STAT, | 348 | err = rtsx_usb_write_register(ucr, SD_BUS_STAT, |
@@ -839,17 +838,6 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
839 | goto finish_detect_card; | 838 | goto finish_detect_card; |
840 | } | 839 | } |
841 | 840 | ||
842 | /* | ||
843 | * Reject SDIO CMDs to speed up card identification | ||
844 | * since unsupported | ||
845 | */ | ||
846 | if (cmd->opcode == SD_IO_SEND_OP_COND || | ||
847 | cmd->opcode == SD_IO_RW_DIRECT || | ||
848 | cmd->opcode == SD_IO_RW_EXTENDED) { | ||
849 | cmd->error = -EINVAL; | ||
850 | goto finish; | ||
851 | } | ||
852 | |||
853 | mutex_lock(&ucr->dev_mutex); | 841 | mutex_lock(&ucr->dev_mutex); |
854 | 842 | ||
855 | mutex_lock(&host->host_mutex); | 843 | mutex_lock(&host->host_mutex); |
@@ -1332,8 +1320,9 @@ static void rtsx_usb_init_host(struct rtsx_usb_sdmmc *host) | |||
1332 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | | 1320 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | |
1333 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST | | 1321 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST | |
1334 | MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 | | 1322 | MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 | |
1335 | MMC_CAP_NEEDS_POLL; | 1323 | MMC_CAP_NEEDS_POLL | MMC_CAP_ERASE; |
1336 | mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE; | 1324 | mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE | |
1325 | MMC_CAP2_NO_SDIO; | ||
1337 | 1326 | ||
1338 | mmc->max_current_330 = 400; | 1327 | mmc->max_current_330 = 400; |
1339 | mmc->max_current_180 = 800; | 1328 | mmc->max_current_180 = 800; |
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c index 11ca95c60bcf..bdbd4897c0f7 100644 --- a/drivers/mmc/host/sdhci-bcm-kona.c +++ b/drivers/mmc/host/sdhci-bcm-kona.c | |||
@@ -284,10 +284,8 @@ static int sdhci_bcm_kona_probe(struct platform_device *pdev) | |||
284 | sdhci_bcm_kona_sd_init(host); | 284 | sdhci_bcm_kona_sd_init(host); |
285 | 285 | ||
286 | ret = sdhci_add_host(host); | 286 | ret = sdhci_add_host(host); |
287 | if (ret) { | 287 | if (ret) |
288 | dev_err(dev, "Failed sdhci_add_host\n"); | ||
289 | goto err_reset; | 288 | goto err_reset; |
290 | } | ||
291 | 289 | ||
292 | /* if device is eMMC, emulate card insert right here */ | 290 | /* if device is eMMC, emulate card insert right here */ |
293 | if (!mmc_card_is_removable(host->mmc)) { | 291 | if (!mmc_card_is_removable(host->mmc)) { |
diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index 0f589e26ee63..7a343b87b5e5 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c | |||
@@ -253,6 +253,7 @@ static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val) | |||
253 | struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); | 253 | struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); |
254 | void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS06; | 254 | void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS06; |
255 | u32 tmp; | 255 | u32 tmp; |
256 | int i, ret; | ||
256 | 257 | ||
257 | if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE, val))) | 258 | if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE, val))) |
258 | return -EINVAL; | 259 | return -EINVAL; |
@@ -260,11 +261,24 @@ static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val) | |||
260 | tmp = readl(reg); | 261 | tmp = readl(reg); |
261 | tmp &= ~SDHCI_CDNS_HRS06_TUNE; | 262 | tmp &= ~SDHCI_CDNS_HRS06_TUNE; |
262 | tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_TUNE, val); | 263 | tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_TUNE, val); |
263 | tmp |= SDHCI_CDNS_HRS06_TUNE_UP; | ||
264 | writel(tmp, reg); | ||
265 | 264 | ||
266 | return readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS06_TUNE_UP), | 265 | /* |
267 | 0, 1); | 266 | * Workaround for IP errata: |
267 | * The IP6116 SD/eMMC PHY design has a timing issue on receive data | ||
268 | * path. Send tune request twice. | ||
269 | */ | ||
270 | for (i = 0; i < 2; i++) { | ||
271 | tmp |= SDHCI_CDNS_HRS06_TUNE_UP; | ||
272 | writel(tmp, reg); | ||
273 | |||
274 | ret = readl_poll_timeout(reg, tmp, | ||
275 | !(tmp & SDHCI_CDNS_HRS06_TUNE_UP), | ||
276 | 0, 1); | ||
277 | if (ret) | ||
278 | return ret; | ||
279 | } | ||
280 | |||
281 | return 0; | ||
268 | } | 282 | } |
269 | 283 | ||
270 | static int sdhci_cdns_execute_tuning(struct mmc_host *mmc, u32 opcode) | 284 | static int sdhci_cdns_execute_tuning(struct mmc_host *mmc, u32 opcode) |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index cd2b5f643a15..d6aef70d34fa 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -41,6 +41,12 @@ | |||
41 | #define ESDHC_VENDOR_SPEC_FRC_SDCLK_ON (1 << 8) | 41 | #define ESDHC_VENDOR_SPEC_FRC_SDCLK_ON (1 << 8) |
42 | #define ESDHC_WTMK_LVL 0x44 | 42 | #define ESDHC_WTMK_LVL 0x44 |
43 | #define ESDHC_WTMK_DEFAULT_VAL 0x10401040 | 43 | #define ESDHC_WTMK_DEFAULT_VAL 0x10401040 |
44 | #define ESDHC_WTMK_LVL_RD_WML_MASK 0x000000FF | ||
45 | #define ESDHC_WTMK_LVL_RD_WML_SHIFT 0 | ||
46 | #define ESDHC_WTMK_LVL_WR_WML_MASK 0x00FF0000 | ||
47 | #define ESDHC_WTMK_LVL_WR_WML_SHIFT 16 | ||
48 | #define ESDHC_WTMK_LVL_WML_VAL_DEF 64 | ||
49 | #define ESDHC_WTMK_LVL_WML_VAL_MAX 128 | ||
44 | #define ESDHC_MIX_CTRL 0x48 | 50 | #define ESDHC_MIX_CTRL 0x48 |
45 | #define ESDHC_MIX_CTRL_DDREN (1 << 3) | 51 | #define ESDHC_MIX_CTRL_DDREN (1 << 3) |
46 | #define ESDHC_MIX_CTRL_AC23EN (1 << 7) | 52 | #define ESDHC_MIX_CTRL_AC23EN (1 << 7) |
@@ -516,6 +522,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) | |||
516 | } | 522 | } |
517 | 523 | ||
518 | if (esdhc_is_usdhc(imx_data)) { | 524 | if (esdhc_is_usdhc(imx_data)) { |
525 | u32 wml; | ||
519 | u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); | 526 | u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); |
520 | /* Swap AC23 bit */ | 527 | /* Swap AC23 bit */ |
521 | if (val & SDHCI_TRNS_AUTO_CMD23) { | 528 | if (val & SDHCI_TRNS_AUTO_CMD23) { |
@@ -524,6 +531,21 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) | |||
524 | } | 531 | } |
525 | m = val | (m & ~ESDHC_MIX_CTRL_SDHCI_MASK); | 532 | m = val | (m & ~ESDHC_MIX_CTRL_SDHCI_MASK); |
526 | writel(m, host->ioaddr + ESDHC_MIX_CTRL); | 533 | writel(m, host->ioaddr + ESDHC_MIX_CTRL); |
534 | |||
535 | /* Set watermark levels for PIO access to maximum value | ||
536 | * (128 words) to accommodate full 512 bytes buffer. | ||
537 | * For DMA access restore the levels to default value. | ||
538 | */ | ||
539 | m = readl(host->ioaddr + ESDHC_WTMK_LVL); | ||
540 | if (val & SDHCI_TRNS_DMA) | ||
541 | wml = ESDHC_WTMK_LVL_WML_VAL_DEF; | ||
542 | else | ||
543 | wml = ESDHC_WTMK_LVL_WML_VAL_MAX; | ||
544 | m &= ~(ESDHC_WTMK_LVL_RD_WML_MASK | | ||
545 | ESDHC_WTMK_LVL_WR_WML_MASK); | ||
546 | m |= (wml << ESDHC_WTMK_LVL_RD_WML_SHIFT) | | ||
547 | (wml << ESDHC_WTMK_LVL_WR_WML_SHIFT); | ||
548 | writel(m, host->ioaddr + ESDHC_WTMK_LVL); | ||
527 | } else { | 549 | } else { |
528 | /* | 550 | /* |
529 | * Postpone this write, we must do it together with a | 551 | * Postpone this write, we must do it together with a |
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index c283291db705..646bf377ba77 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/pm_runtime.h> | 21 | #include <linux/pm_runtime.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/iopoll.h> | 23 | #include <linux/iopoll.h> |
24 | #include <linux/regulator/consumer.h> | ||
24 | 25 | ||
25 | #include "sdhci-pltfm.h" | 26 | #include "sdhci-pltfm.h" |
26 | 27 | ||
@@ -77,10 +78,16 @@ | |||
77 | #define CORE_HC_MCLK_SEL_DFLT (2 << 8) | 78 | #define CORE_HC_MCLK_SEL_DFLT (2 << 8) |
78 | #define CORE_HC_MCLK_SEL_HS400 (3 << 8) | 79 | #define CORE_HC_MCLK_SEL_HS400 (3 << 8) |
79 | #define CORE_HC_MCLK_SEL_MASK (3 << 8) | 80 | #define CORE_HC_MCLK_SEL_MASK (3 << 8) |
81 | #define CORE_IO_PAD_PWR_SWITCH_EN (1 << 15) | ||
82 | #define CORE_IO_PAD_PWR_SWITCH (1 << 16) | ||
80 | #define CORE_HC_SELECT_IN_EN BIT(18) | 83 | #define CORE_HC_SELECT_IN_EN BIT(18) |
81 | #define CORE_HC_SELECT_IN_HS400 (6 << 19) | 84 | #define CORE_HC_SELECT_IN_HS400 (6 << 19) |
82 | #define CORE_HC_SELECT_IN_MASK (7 << 19) | 85 | #define CORE_HC_SELECT_IN_MASK (7 << 19) |
83 | 86 | ||
87 | #define CORE_3_0V_SUPPORT (1 << 25) | ||
88 | #define CORE_1_8V_SUPPORT (1 << 26) | ||
89 | #define CORE_VOLT_SUPPORT (CORE_3_0V_SUPPORT | CORE_1_8V_SUPPORT) | ||
90 | |||
84 | #define CORE_CSR_CDC_CTLR_CFG0 0x130 | 91 | #define CORE_CSR_CDC_CTLR_CFG0 0x130 |
85 | #define CORE_SW_TRIG_FULL_CALIB BIT(16) | 92 | #define CORE_SW_TRIG_FULL_CALIB BIT(16) |
86 | #define CORE_HW_AUTOCAL_ENA BIT(17) | 93 | #define CORE_HW_AUTOCAL_ENA BIT(17) |
@@ -148,6 +155,7 @@ struct sdhci_msm_host { | |||
148 | u32 curr_io_level; | 155 | u32 curr_io_level; |
149 | wait_queue_head_t pwr_irq_wait; | 156 | wait_queue_head_t pwr_irq_wait; |
150 | bool pwr_irq_flag; | 157 | bool pwr_irq_flag; |
158 | u32 caps_0; | ||
151 | }; | 159 | }; |
152 | 160 | ||
153 | static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host, | 161 | static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host, |
@@ -1103,8 +1111,8 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) | |||
1103 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | 1111 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
1104 | u32 irq_status, irq_ack = 0; | 1112 | u32 irq_status, irq_ack = 0; |
1105 | int retry = 10; | 1113 | int retry = 10; |
1106 | int pwr_state = 0, io_level = 0; | 1114 | u32 pwr_state = 0, io_level = 0; |
1107 | 1115 | u32 config; | |
1108 | 1116 | ||
1109 | irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS); | 1117 | irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS); |
1110 | irq_status &= INT_MASK; | 1118 | irq_status &= INT_MASK; |
@@ -1161,6 +1169,38 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) | |||
1161 | */ | 1169 | */ |
1162 | writel_relaxed(irq_ack, msm_host->core_mem + CORE_PWRCTL_CTL); | 1170 | writel_relaxed(irq_ack, msm_host->core_mem + CORE_PWRCTL_CTL); |
1163 | 1171 | ||
1172 | /* | ||
1173 | * If we don't have info regarding the voltage levels supported by | ||
1174 | * regulators, don't change the IO PAD PWR SWITCH. | ||
1175 | */ | ||
1176 | if (msm_host->caps_0 & CORE_VOLT_SUPPORT) { | ||
1177 | u32 new_config; | ||
1178 | /* | ||
1179 | * We should unset IO PAD PWR switch only if the register write | ||
1180 | * can set IO lines high and the regulator also switches to 3 V. | ||
1181 | * Else, we should keep the IO PAD PWR switch set. | ||
1182 | * This is applicable to certain targets where eMMC vccq supply | ||
1183 | * is only 1.8V. In such targets, even during REQ_IO_HIGH, the | ||
1184 | * IO PAD PWR switch must be kept set to reflect actual | ||
1185 | * regulator voltage. This way, during initialization of | ||
1186 | * controllers with only 1.8V, we will set the IO PAD bit | ||
1187 | * without waiting for a REQ_IO_LOW. | ||
1188 | */ | ||
1189 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
1190 | new_config = config; | ||
1191 | |||
1192 | if ((io_level & REQ_IO_HIGH) && | ||
1193 | (msm_host->caps_0 & CORE_3_0V_SUPPORT)) | ||
1194 | new_config &= ~CORE_IO_PAD_PWR_SWITCH; | ||
1195 | else if ((io_level & REQ_IO_LOW) || | ||
1196 | (msm_host->caps_0 & CORE_1_8V_SUPPORT)) | ||
1197 | new_config |= CORE_IO_PAD_PWR_SWITCH; | ||
1198 | |||
1199 | if (config ^ new_config) | ||
1200 | writel_relaxed(new_config, | ||
1201 | host->ioaddr + CORE_VENDOR_SPEC); | ||
1202 | } | ||
1203 | |||
1164 | if (pwr_state) | 1204 | if (pwr_state) |
1165 | msm_host->curr_pwr_state = pwr_state; | 1205 | msm_host->curr_pwr_state = pwr_state; |
1166 | if (io_level) | 1206 | if (io_level) |
@@ -1313,6 +1353,45 @@ static void sdhci_msm_writeb(struct sdhci_host *host, u8 val, int reg) | |||
1313 | sdhci_msm_check_power_status(host, req_type); | 1353 | sdhci_msm_check_power_status(host, req_type); |
1314 | } | 1354 | } |
1315 | 1355 | ||
1356 | static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host) | ||
1357 | { | ||
1358 | struct mmc_host *mmc = msm_host->mmc; | ||
1359 | struct regulator *supply = mmc->supply.vqmmc; | ||
1360 | u32 caps = 0, config; | ||
1361 | struct sdhci_host *host = mmc_priv(mmc); | ||
1362 | |||
1363 | if (!IS_ERR(mmc->supply.vqmmc)) { | ||
1364 | if (regulator_is_supported_voltage(supply, 1700000, 1950000)) | ||
1365 | caps |= CORE_1_8V_SUPPORT; | ||
1366 | if (regulator_is_supported_voltage(supply, 2700000, 3600000)) | ||
1367 | caps |= CORE_3_0V_SUPPORT; | ||
1368 | |||
1369 | if (!caps) | ||
1370 | pr_warn("%s: 1.8/3V not supported for vqmmc\n", | ||
1371 | mmc_hostname(mmc)); | ||
1372 | } | ||
1373 | |||
1374 | if (caps) { | ||
1375 | /* | ||
1376 | * Set the PAD_PWR_SWITCH_EN bit so that the PAD_PWR_SWITCH | ||
1377 | * bit can be used as required later on. | ||
1378 | */ | ||
1379 | u32 io_level = msm_host->curr_io_level; | ||
1380 | |||
1381 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
1382 | config |= CORE_IO_PAD_PWR_SWITCH_EN; | ||
1383 | |||
1384 | if ((io_level & REQ_IO_HIGH) && (caps & CORE_3_0V_SUPPORT)) | ||
1385 | config &= ~CORE_IO_PAD_PWR_SWITCH; | ||
1386 | else if ((io_level & REQ_IO_LOW) || (caps & CORE_1_8V_SUPPORT)) | ||
1387 | config |= CORE_IO_PAD_PWR_SWITCH; | ||
1388 | |||
1389 | writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC); | ||
1390 | } | ||
1391 | msm_host->caps_0 |= caps; | ||
1392 | pr_debug("%s: supported caps: 0x%08x\n", mmc_hostname(mmc), caps); | ||
1393 | } | ||
1394 | |||
1316 | static const struct of_device_id sdhci_msm_dt_match[] = { | 1395 | static const struct of_device_id sdhci_msm_dt_match[] = { |
1317 | { .compatible = "qcom,sdhci-msm-v4" }, | 1396 | { .compatible = "qcom,sdhci-msm-v4" }, |
1318 | {}, | 1397 | {}, |
@@ -1333,7 +1412,6 @@ static const struct sdhci_ops sdhci_msm_ops = { | |||
1333 | 1412 | ||
1334 | static const struct sdhci_pltfm_data sdhci_msm_pdata = { | 1413 | static const struct sdhci_pltfm_data sdhci_msm_pdata = { |
1335 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | | 1414 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | |
1336 | SDHCI_QUIRK_NO_CARD_NO_RESET | | ||
1337 | SDHCI_QUIRK_SINGLE_POWER_WRITE | | 1415 | SDHCI_QUIRK_SINGLE_POWER_WRITE | |
1338 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, | 1416 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, |
1339 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, | 1417 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, |
@@ -1530,6 +1608,7 @@ static int sdhci_msm_probe(struct platform_device *pdev) | |||
1530 | ret = sdhci_add_host(host); | 1608 | ret = sdhci_add_host(host); |
1531 | if (ret) | 1609 | if (ret) |
1532 | goto pm_runtime_disable; | 1610 | goto pm_runtime_disable; |
1611 | sdhci_msm_set_regulator_caps(msm_host); | ||
1533 | 1612 | ||
1534 | pm_runtime_mark_last_busy(&pdev->dev); | 1613 | pm_runtime_mark_last_busy(&pdev->dev); |
1535 | pm_runtime_put_autosuspend(&pdev->dev); | 1614 | pm_runtime_put_autosuspend(&pdev->dev); |
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index c33a5f7393bd..e3332a522a5d 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c | |||
@@ -290,7 +290,8 @@ static const struct sdhci_pltfm_data sdhci_arasan_pdata = { | |||
290 | .ops = &sdhci_arasan_ops, | 290 | .ops = &sdhci_arasan_ops, |
291 | .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, | 291 | .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, |
292 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | 292 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
293 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, | 293 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | |
294 | SDHCI_QUIRK2_STOP_WITH_TC, | ||
294 | }; | 295 | }; |
295 | 296 | ||
296 | static u32 sdhci_arasan_cqhci_irq(struct sdhci_host *host, u32 intmask) | 297 | static u32 sdhci_arasan_cqhci_irq(struct sdhci_host *host, u32 intmask) |
@@ -359,8 +360,7 @@ static const struct sdhci_pltfm_data sdhci_arasan_cqe_pdata = { | |||
359 | */ | 360 | */ |
360 | static int sdhci_arasan_suspend(struct device *dev) | 361 | static int sdhci_arasan_suspend(struct device *dev) |
361 | { | 362 | { |
362 | struct platform_device *pdev = to_platform_device(dev); | 363 | struct sdhci_host *host = dev_get_drvdata(dev); |
363 | struct sdhci_host *host = platform_get_drvdata(pdev); | ||
364 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 364 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
365 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | 365 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); |
366 | int ret; | 366 | int ret; |
@@ -403,8 +403,7 @@ static int sdhci_arasan_suspend(struct device *dev) | |||
403 | */ | 403 | */ |
404 | static int sdhci_arasan_resume(struct device *dev) | 404 | static int sdhci_arasan_resume(struct device *dev) |
405 | { | 405 | { |
406 | struct platform_device *pdev = to_platform_device(dev); | 406 | struct sdhci_host *host = dev_get_drvdata(dev); |
407 | struct sdhci_host *host = platform_get_drvdata(pdev); | ||
408 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 407 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
409 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | 408 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); |
410 | int ret; | 409 | int ret; |
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c index 1456abd5eeb9..f3a7c8ece4be 100644 --- a/drivers/mmc/host/sdhci-omap.c +++ b/drivers/mmc/host/sdhci-omap.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
27 | #include <linux/regulator/consumer.h> | 27 | #include <linux/regulator/consumer.h> |
28 | #include <linux/pinctrl/consumer.h> | 28 | #include <linux/pinctrl/consumer.h> |
29 | #include <linux/sys_soc.h> | ||
29 | 30 | ||
30 | #include "sdhci-pltfm.h" | 31 | #include "sdhci-pltfm.h" |
31 | 32 | ||
@@ -35,6 +36,7 @@ | |||
35 | #define CON_DDR BIT(19) | 36 | #define CON_DDR BIT(19) |
36 | #define CON_CLKEXTFREE BIT(16) | 37 | #define CON_CLKEXTFREE BIT(16) |
37 | #define CON_PADEN BIT(15) | 38 | #define CON_PADEN BIT(15) |
39 | #define CON_CTPL BIT(11) | ||
38 | #define CON_INIT BIT(1) | 40 | #define CON_INIT BIT(1) |
39 | #define CON_OD BIT(0) | 41 | #define CON_OD BIT(0) |
40 | 42 | ||
@@ -100,6 +102,7 @@ struct sdhci_omap_data { | |||
100 | }; | 102 | }; |
101 | 103 | ||
102 | struct sdhci_omap_host { | 104 | struct sdhci_omap_host { |
105 | char *version; | ||
103 | void __iomem *base; | 106 | void __iomem *base; |
104 | struct device *dev; | 107 | struct device *dev; |
105 | struct regulator *pbias; | 108 | struct regulator *pbias; |
@@ -224,6 +227,23 @@ static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host, | |||
224 | } | 227 | } |
225 | } | 228 | } |
226 | 229 | ||
230 | static void sdhci_omap_enable_sdio_irq(struct mmc_host *mmc, int enable) | ||
231 | { | ||
232 | struct sdhci_host *host = mmc_priv(mmc); | ||
233 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
234 | struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); | ||
235 | u32 reg; | ||
236 | |||
237 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); | ||
238 | if (enable) | ||
239 | reg |= (CON_CTPL | CON_CLKEXTFREE); | ||
240 | else | ||
241 | reg &= ~(CON_CTPL | CON_CLKEXTFREE); | ||
242 | sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); | ||
243 | |||
244 | sdhci_enable_sdio_irq(mmc, enable); | ||
245 | } | ||
246 | |||
227 | static inline void sdhci_omap_set_dll(struct sdhci_omap_host *omap_host, | 247 | static inline void sdhci_omap_set_dll(struct sdhci_omap_host *omap_host, |
228 | int count) | 248 | int count) |
229 | { | 249 | { |
@@ -713,10 +733,15 @@ static const struct sdhci_pltfm_data sdhci_omap_pdata = { | |||
713 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC, | 733 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC, |
714 | .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN | | 734 | .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN | |
715 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | 735 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
716 | SDHCI_QUIRK2_RSP_136_HAS_CRC, | 736 | SDHCI_QUIRK2_RSP_136_HAS_CRC | |
737 | SDHCI_QUIRK2_DISABLE_HW_TIMEOUT, | ||
717 | .ops = &sdhci_omap_ops, | 738 | .ops = &sdhci_omap_ops, |
718 | }; | 739 | }; |
719 | 740 | ||
741 | static const struct sdhci_omap_data k2g_data = { | ||
742 | .offset = 0x200, | ||
743 | }; | ||
744 | |||
720 | static const struct sdhci_omap_data dra7_data = { | 745 | static const struct sdhci_omap_data dra7_data = { |
721 | .offset = 0x200, | 746 | .offset = 0x200, |
722 | .flags = SDHCI_OMAP_REQUIRE_IODELAY, | 747 | .flags = SDHCI_OMAP_REQUIRE_IODELAY, |
@@ -724,6 +749,7 @@ static const struct sdhci_omap_data dra7_data = { | |||
724 | 749 | ||
725 | static const struct of_device_id omap_sdhci_match[] = { | 750 | static const struct of_device_id omap_sdhci_match[] = { |
726 | { .compatible = "ti,dra7-sdhci", .data = &dra7_data }, | 751 | { .compatible = "ti,dra7-sdhci", .data = &dra7_data }, |
752 | { .compatible = "ti,k2g-sdhci", .data = &k2g_data }, | ||
727 | {}, | 753 | {}, |
728 | }; | 754 | }; |
729 | MODULE_DEVICE_TABLE(of, omap_sdhci_match); | 755 | MODULE_DEVICE_TABLE(of, omap_sdhci_match); |
@@ -733,12 +759,21 @@ static struct pinctrl_state | |||
733 | u32 *caps, u32 capmask) | 759 | u32 *caps, u32 capmask) |
734 | { | 760 | { |
735 | struct device *dev = omap_host->dev; | 761 | struct device *dev = omap_host->dev; |
762 | char *version = omap_host->version; | ||
736 | struct pinctrl_state *pinctrl_state = ERR_PTR(-ENODEV); | 763 | struct pinctrl_state *pinctrl_state = ERR_PTR(-ENODEV); |
764 | char str[20]; | ||
737 | 765 | ||
738 | if (!(*caps & capmask)) | 766 | if (!(*caps & capmask)) |
739 | goto ret; | 767 | goto ret; |
740 | 768 | ||
741 | pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, mode); | 769 | if (version) { |
770 | snprintf(str, 20, "%s-%s", mode, version); | ||
771 | pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, str); | ||
772 | } | ||
773 | |||
774 | if (IS_ERR(pinctrl_state)) | ||
775 | pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, mode); | ||
776 | |||
742 | if (IS_ERR(pinctrl_state)) { | 777 | if (IS_ERR(pinctrl_state)) { |
743 | dev_err(dev, "no pinctrl state for %s mode", mode); | 778 | dev_err(dev, "no pinctrl state for %s mode", mode); |
744 | *caps &= ~capmask; | 779 | *caps &= ~capmask; |
@@ -807,8 +842,15 @@ static int sdhci_omap_config_iodelay_pinctrl_state(struct sdhci_omap_host | |||
807 | 842 | ||
808 | state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr_1_8v", caps, | 843 | state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr_1_8v", caps, |
809 | MMC_CAP_1_8V_DDR); | 844 | MMC_CAP_1_8V_DDR); |
810 | if (!IS_ERR(state)) | 845 | if (!IS_ERR(state)) { |
811 | pinctrl_state[MMC_TIMING_MMC_DDR52] = state; | 846 | pinctrl_state[MMC_TIMING_MMC_DDR52] = state; |
847 | } else { | ||
848 | state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr_3_3v", | ||
849 | caps, | ||
850 | MMC_CAP_3_3V_DDR); | ||
851 | if (!IS_ERR(state)) | ||
852 | pinctrl_state[MMC_TIMING_MMC_DDR52] = state; | ||
853 | } | ||
812 | 854 | ||
813 | state = sdhci_omap_iodelay_pinctrl_state(omap_host, "hs", caps, | 855 | state = sdhci_omap_iodelay_pinctrl_state(omap_host, "hs", caps, |
814 | MMC_CAP_SD_HIGHSPEED); | 856 | MMC_CAP_SD_HIGHSPEED); |
@@ -830,6 +872,16 @@ static int sdhci_omap_config_iodelay_pinctrl_state(struct sdhci_omap_host | |||
830 | return 0; | 872 | return 0; |
831 | } | 873 | } |
832 | 874 | ||
875 | static const struct soc_device_attribute sdhci_omap_soc_devices[] = { | ||
876 | { | ||
877 | .machine = "DRA7[45]*", | ||
878 | .revision = "ES1.[01]", | ||
879 | }, | ||
880 | { | ||
881 | /* sentinel */ | ||
882 | } | ||
883 | }; | ||
884 | |||
833 | static int sdhci_omap_probe(struct platform_device *pdev) | 885 | static int sdhci_omap_probe(struct platform_device *pdev) |
834 | { | 886 | { |
835 | int ret; | 887 | int ret; |
@@ -841,6 +893,7 @@ static int sdhci_omap_probe(struct platform_device *pdev) | |||
841 | struct mmc_host *mmc; | 893 | struct mmc_host *mmc; |
842 | const struct of_device_id *match; | 894 | const struct of_device_id *match; |
843 | struct sdhci_omap_data *data; | 895 | struct sdhci_omap_data *data; |
896 | const struct soc_device_attribute *soc; | ||
844 | 897 | ||
845 | match = of_match_device(omap_sdhci_match, dev); | 898 | match = of_match_device(omap_sdhci_match, dev); |
846 | if (!match) | 899 | if (!match) |
@@ -871,10 +924,22 @@ static int sdhci_omap_probe(struct platform_device *pdev) | |||
871 | host->ioaddr += offset; | 924 | host->ioaddr += offset; |
872 | 925 | ||
873 | mmc = host->mmc; | 926 | mmc = host->mmc; |
927 | sdhci_get_of_property(pdev); | ||
874 | ret = mmc_of_parse(mmc); | 928 | ret = mmc_of_parse(mmc); |
875 | if (ret) | 929 | if (ret) |
876 | goto err_pltfm_free; | 930 | goto err_pltfm_free; |
877 | 931 | ||
932 | soc = soc_device_match(sdhci_omap_soc_devices); | ||
933 | if (soc) { | ||
934 | omap_host->version = "rev11"; | ||
935 | if (!strcmp(dev_name(dev), "4809c000.mmc")) | ||
936 | mmc->f_max = 96000000; | ||
937 | if (!strcmp(dev_name(dev), "480b4000.mmc")) | ||
938 | mmc->f_max = 48000000; | ||
939 | if (!strcmp(dev_name(dev), "480ad000.mmc")) | ||
940 | mmc->f_max = 48000000; | ||
941 | } | ||
942 | |||
878 | pltfm_host->clk = devm_clk_get(dev, "fck"); | 943 | pltfm_host->clk = devm_clk_get(dev, "fck"); |
879 | if (IS_ERR(pltfm_host->clk)) { | 944 | if (IS_ERR(pltfm_host->clk)) { |
880 | ret = PTR_ERR(pltfm_host->clk); | 945 | ret = PTR_ERR(pltfm_host->clk); |
@@ -916,26 +981,31 @@ static int sdhci_omap_probe(struct platform_device *pdev) | |||
916 | goto err_put_sync; | 981 | goto err_put_sync; |
917 | } | 982 | } |
918 | 983 | ||
919 | ret = sdhci_omap_config_iodelay_pinctrl_state(omap_host); | ||
920 | if (ret) | ||
921 | goto err_put_sync; | ||
922 | |||
923 | host->mmc_host_ops.get_ro = mmc_gpio_get_ro; | 984 | host->mmc_host_ops.get_ro = mmc_gpio_get_ro; |
924 | host->mmc_host_ops.start_signal_voltage_switch = | 985 | host->mmc_host_ops.start_signal_voltage_switch = |
925 | sdhci_omap_start_signal_voltage_switch; | 986 | sdhci_omap_start_signal_voltage_switch; |
926 | host->mmc_host_ops.set_ios = sdhci_omap_set_ios; | 987 | host->mmc_host_ops.set_ios = sdhci_omap_set_ios; |
927 | host->mmc_host_ops.card_busy = sdhci_omap_card_busy; | 988 | host->mmc_host_ops.card_busy = sdhci_omap_card_busy; |
928 | host->mmc_host_ops.execute_tuning = sdhci_omap_execute_tuning; | 989 | host->mmc_host_ops.execute_tuning = sdhci_omap_execute_tuning; |
990 | host->mmc_host_ops.enable_sdio_irq = sdhci_omap_enable_sdio_irq; | ||
929 | 991 | ||
930 | sdhci_read_caps(host); | 992 | ret = sdhci_setup_host(host); |
931 | host->caps |= SDHCI_CAN_DO_ADMA2; | ||
932 | |||
933 | ret = sdhci_add_host(host); | ||
934 | if (ret) | 993 | if (ret) |
935 | goto err_put_sync; | 994 | goto err_put_sync; |
936 | 995 | ||
996 | ret = sdhci_omap_config_iodelay_pinctrl_state(omap_host); | ||
997 | if (ret) | ||
998 | goto err_cleanup_host; | ||
999 | |||
1000 | ret = __sdhci_add_host(host); | ||
1001 | if (ret) | ||
1002 | goto err_cleanup_host; | ||
1003 | |||
937 | return 0; | 1004 | return 0; |
938 | 1005 | ||
1006 | err_cleanup_host: | ||
1007 | sdhci_cleanup_host(host); | ||
1008 | |||
939 | err_put_sync: | 1009 | err_put_sync: |
940 | pm_runtime_put_sync(dev); | 1010 | pm_runtime_put_sync(dev); |
941 | 1011 | ||
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 78c25ad35fd2..77dd3521daae 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c | |||
@@ -453,6 +453,7 @@ static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = { | |||
453 | enum { | 453 | enum { |
454 | INTEL_DSM_FNS = 0, | 454 | INTEL_DSM_FNS = 0, |
455 | INTEL_DSM_V18_SWITCH = 3, | 455 | INTEL_DSM_V18_SWITCH = 3, |
456 | INTEL_DSM_V33_SWITCH = 4, | ||
456 | INTEL_DSM_DRV_STRENGTH = 9, | 457 | INTEL_DSM_DRV_STRENGTH = 9, |
457 | INTEL_DSM_D3_RETUNE = 10, | 458 | INTEL_DSM_D3_RETUNE = 10, |
458 | }; | 459 | }; |
@@ -620,17 +621,37 @@ static void intel_hs400_enhanced_strobe(struct mmc_host *mmc, | |||
620 | sdhci_writel(host, val, INTEL_HS400_ES_REG); | 621 | sdhci_writel(host, val, INTEL_HS400_ES_REG); |
621 | } | 622 | } |
622 | 623 | ||
623 | static void sdhci_intel_voltage_switch(struct sdhci_host *host) | 624 | static int intel_start_signal_voltage_switch(struct mmc_host *mmc, |
625 | struct mmc_ios *ios) | ||
624 | { | 626 | { |
627 | struct device *dev = mmc_dev(mmc); | ||
628 | struct sdhci_host *host = mmc_priv(mmc); | ||
625 | struct sdhci_pci_slot *slot = sdhci_priv(host); | 629 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
626 | struct intel_host *intel_host = sdhci_pci_priv(slot); | 630 | struct intel_host *intel_host = sdhci_pci_priv(slot); |
627 | struct device *dev = &slot->chip->pdev->dev; | 631 | unsigned int fn; |
628 | u32 result = 0; | 632 | u32 result = 0; |
629 | int err; | 633 | int err; |
630 | 634 | ||
631 | err = intel_dsm(intel_host, dev, INTEL_DSM_V18_SWITCH, &result); | 635 | err = sdhci_start_signal_voltage_switch(mmc, ios); |
632 | pr_debug("%s: %s DSM error %d result %u\n", | 636 | if (err) |
633 | mmc_hostname(host->mmc), __func__, err, result); | 637 | return err; |
638 | |||
639 | switch (ios->signal_voltage) { | ||
640 | case MMC_SIGNAL_VOLTAGE_330: | ||
641 | fn = INTEL_DSM_V33_SWITCH; | ||
642 | break; | ||
643 | case MMC_SIGNAL_VOLTAGE_180: | ||
644 | fn = INTEL_DSM_V18_SWITCH; | ||
645 | break; | ||
646 | default: | ||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | err = intel_dsm(intel_host, dev, fn, &result); | ||
651 | pr_debug("%s: %s DSM fn %u error %d result %u\n", | ||
652 | mmc_hostname(mmc), __func__, fn, err, result); | ||
653 | |||
654 | return 0; | ||
634 | } | 655 | } |
635 | 656 | ||
636 | static const struct sdhci_ops sdhci_intel_byt_ops = { | 657 | static const struct sdhci_ops sdhci_intel_byt_ops = { |
@@ -641,7 +662,6 @@ static const struct sdhci_ops sdhci_intel_byt_ops = { | |||
641 | .reset = sdhci_reset, | 662 | .reset = sdhci_reset, |
642 | .set_uhs_signaling = sdhci_set_uhs_signaling, | 663 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
643 | .hw_reset = sdhci_pci_hw_reset, | 664 | .hw_reset = sdhci_pci_hw_reset, |
644 | .voltage_switch = sdhci_intel_voltage_switch, | ||
645 | }; | 665 | }; |
646 | 666 | ||
647 | static const struct sdhci_ops sdhci_intel_glk_ops = { | 667 | static const struct sdhci_ops sdhci_intel_glk_ops = { |
@@ -652,7 +672,6 @@ static const struct sdhci_ops sdhci_intel_glk_ops = { | |||
652 | .reset = sdhci_reset, | 672 | .reset = sdhci_reset, |
653 | .set_uhs_signaling = sdhci_set_uhs_signaling, | 673 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
654 | .hw_reset = sdhci_pci_hw_reset, | 674 | .hw_reset = sdhci_pci_hw_reset, |
655 | .voltage_switch = sdhci_intel_voltage_switch, | ||
656 | .irq = sdhci_cqhci_irq, | 675 | .irq = sdhci_cqhci_irq, |
657 | }; | 676 | }; |
658 | 677 | ||
@@ -691,6 +710,7 @@ static void byt_probe_slot(struct sdhci_pci_slot *slot) | |||
691 | byt_read_dsm(slot); | 710 | byt_read_dsm(slot); |
692 | 711 | ||
693 | ops->execute_tuning = intel_execute_tuning; | 712 | ops->execute_tuning = intel_execute_tuning; |
713 | ops->start_signal_voltage_switch = intel_start_signal_voltage_switch; | ||
694 | } | 714 | } |
695 | 715 | ||
696 | static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) | 716 | static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) |
@@ -832,6 +852,10 @@ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) | |||
832 | slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_GLK_SD) | 852 | slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_GLK_SD) |
833 | slot->host->mmc_host_ops.get_cd = bxt_get_cd; | 853 | slot->host->mmc_host_ops.get_cd = bxt_get_cd; |
834 | 854 | ||
855 | if (slot->chip->pdev->subsystem_vendor == PCI_VENDOR_ID_NI && | ||
856 | slot->chip->pdev->subsystem_device == PCI_SUBDEVICE_ID_NI_78E3) | ||
857 | slot->host->mmc->caps2 |= MMC_CAP2_AVOID_3_3V; | ||
858 | |||
835 | return 0; | 859 | return 0; |
836 | } | 860 | } |
837 | 861 | ||
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index 5cbcdc448f98..db9cb54ef700 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h | |||
@@ -54,6 +54,7 @@ | |||
54 | #define PCI_DEVICE_ID_REALTEK_5250 0x5250 | 54 | #define PCI_DEVICE_ID_REALTEK_5250 0x5250 |
55 | 55 | ||
56 | #define PCI_SUBDEVICE_ID_NI_7884 0x7884 | 56 | #define PCI_SUBDEVICE_ID_NI_7884 0x7884 |
57 | #define PCI_SUBDEVICE_ID_NI_78E3 0x78e3 | ||
57 | 58 | ||
58 | #define PCI_VENDOR_ID_ARASAN 0x16e6 | 59 | #define PCI_VENDOR_ID_ARASAN 0x16e6 |
59 | #define PCI_DEVICE_ID_ARASAN_PHY_EMMC 0x0670 | 60 | #define PCI_DEVICE_ID_ARASAN_PHY_EMMC 0x0670 |
diff --git a/drivers/mmc/host/sdhci-pic32.c b/drivers/mmc/host/sdhci-pic32.c index a6caa49ca25a..a11e6397d4ff 100644 --- a/drivers/mmc/host/sdhci-pic32.c +++ b/drivers/mmc/host/sdhci-pic32.c | |||
@@ -200,10 +200,8 @@ static int pic32_sdhci_probe(struct platform_device *pdev) | |||
200 | } | 200 | } |
201 | 201 | ||
202 | ret = sdhci_add_host(host); | 202 | ret = sdhci_add_host(host); |
203 | if (ret) { | 203 | if (ret) |
204 | dev_err(&pdev->dev, "error adding host\n"); | ||
205 | goto err_base_clk; | 204 | goto err_base_clk; |
206 | } | ||
207 | 205 | ||
208 | dev_info(&pdev->dev, "Successfully added sdhci host\n"); | 206 | dev_info(&pdev->dev, "Successfully added sdhci host\n"); |
209 | return 0; | 207 | return 0; |
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index 8986f9d9cf98..2c3827f54927 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c | |||
@@ -221,10 +221,8 @@ static int sdhci_pxav2_probe(struct platform_device *pdev) | |||
221 | host->ops = &pxav2_sdhci_ops; | 221 | host->ops = &pxav2_sdhci_ops; |
222 | 222 | ||
223 | ret = sdhci_add_host(host); | 223 | ret = sdhci_add_host(host); |
224 | if (ret) { | 224 | if (ret) |
225 | dev_err(&pdev->dev, "failed to add host\n"); | ||
226 | goto disable_clk; | 225 | goto disable_clk; |
227 | } | ||
228 | 226 | ||
229 | return 0; | 227 | return 0; |
230 | 228 | ||
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index a34434166ca7..b8e96f392428 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -472,10 +472,8 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
472 | pm_suspend_ignore_children(&pdev->dev, 1); | 472 | pm_suspend_ignore_children(&pdev->dev, 1); |
473 | 473 | ||
474 | ret = sdhci_add_host(host); | 474 | ret = sdhci_add_host(host); |
475 | if (ret) { | 475 | if (ret) |
476 | dev_err(&pdev->dev, "failed to add host\n"); | ||
477 | goto err_add_host; | 476 | goto err_add_host; |
478 | } | ||
479 | 477 | ||
480 | if (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ) | 478 | if (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ) |
481 | device_init_wakeup(&pdev->dev, 1); | 479 | device_init_wakeup(&pdev->dev, 1); |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index cda83ccb2702..9ef89d00970e 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -655,10 +655,8 @@ static int sdhci_s3c_probe(struct platform_device *pdev) | |||
655 | goto err_req_regs; | 655 | goto err_req_regs; |
656 | 656 | ||
657 | ret = sdhci_add_host(host); | 657 | ret = sdhci_add_host(host); |
658 | if (ret) { | 658 | if (ret) |
659 | dev_err(dev, "sdhci_add_host() failed\n"); | ||
660 | goto err_req_regs; | 659 | goto err_req_regs; |
661 | } | ||
662 | 660 | ||
663 | #ifdef CONFIG_PM | 661 | #ifdef CONFIG_PM |
664 | if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) | 662 | if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) |
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c index 14511526a3a8..9247d51f2eed 100644 --- a/drivers/mmc/host/sdhci-spear.c +++ b/drivers/mmc/host/sdhci-spear.c | |||
@@ -126,10 +126,8 @@ static int sdhci_probe(struct platform_device *pdev) | |||
126 | } | 126 | } |
127 | 127 | ||
128 | ret = sdhci_add_host(host); | 128 | ret = sdhci_add_host(host); |
129 | if (ret) { | 129 | if (ret) |
130 | dev_dbg(&pdev->dev, "error adding host\n"); | ||
131 | goto disable_clk; | 130 | goto disable_clk; |
132 | } | ||
133 | 131 | ||
134 | platform_set_drvdata(pdev, host); | 132 | platform_set_drvdata(pdev, host); |
135 | 133 | ||
diff --git a/drivers/mmc/host/sdhci-st.c b/drivers/mmc/host/sdhci-st.c index c32daed0d418..8f95647195d9 100644 --- a/drivers/mmc/host/sdhci-st.c +++ b/drivers/mmc/host/sdhci-st.c | |||
@@ -422,10 +422,8 @@ static int sdhci_st_probe(struct platform_device *pdev) | |||
422 | st_mmcss_cconfig(np, host); | 422 | st_mmcss_cconfig(np, host); |
423 | 423 | ||
424 | ret = sdhci_add_host(host); | 424 | ret = sdhci_add_host(host); |
425 | if (ret) { | 425 | if (ret) |
426 | dev_err(&pdev->dev, "Failed sdhci_add_host\n"); | ||
427 | goto err_out; | 426 | goto err_out; |
428 | } | ||
429 | 427 | ||
430 | host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION)); | 428 | host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION)); |
431 | 429 | ||
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index b877c13184c2..970d38f68939 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
@@ -231,7 +231,7 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host, | |||
231 | if (timing == MMC_TIMING_UHS_DDR50) | 231 | if (timing == MMC_TIMING_UHS_DDR50) |
232 | tegra_host->ddr_signaling = true; | 232 | tegra_host->ddr_signaling = true; |
233 | 233 | ||
234 | return sdhci_set_uhs_signaling(host, timing); | 234 | sdhci_set_uhs_signaling(host, timing); |
235 | } | 235 | } |
236 | 236 | ||
237 | static unsigned int tegra_sdhci_get_max_clock(struct sdhci_host *host) | 237 | static unsigned int tegra_sdhci_get_max_clock(struct sdhci_host *host) |
diff --git a/drivers/mmc/host/sdhci-xenon-phy.c b/drivers/mmc/host/sdhci-xenon-phy.c index ec8794335241..a35804b203a7 100644 --- a/drivers/mmc/host/sdhci-xenon-phy.c +++ b/drivers/mmc/host/sdhci-xenon-phy.c | |||
@@ -814,15 +814,10 @@ static int xenon_add_phy(struct device_node *np, struct sdhci_host *host, | |||
814 | { | 814 | { |
815 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 815 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
816 | struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); | 816 | struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); |
817 | int i, ret; | 817 | int ret; |
818 | 818 | ||
819 | for (i = 0; i < NR_PHY_TYPES; i++) { | 819 | priv->phy_type = match_string(phy_types, NR_PHY_TYPES, phy_name); |
820 | if (!strcmp(phy_name, phy_types[i])) { | 820 | if (priv->phy_type < 0) { |
821 | priv->phy_type = i; | ||
822 | break; | ||
823 | } | ||
824 | } | ||
825 | if (i == NR_PHY_TYPES) { | ||
826 | dev_err(mmc_dev(host->mmc), | 821 | dev_err(mmc_dev(host->mmc), |
827 | "Unable to determine PHY name %s. Use default eMMC 5.1 PHY\n", | 822 | "Unable to determine PHY name %s. Use default eMMC 5.1 PHY\n", |
828 | phy_name); | 823 | phy_name); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 2ededa7f43df..1c828e0e9905 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -709,29 +709,16 @@ static u32 sdhci_sdma_address(struct sdhci_host *host) | |||
709 | return sg_dma_address(host->data->sg); | 709 | return sg_dma_address(host->data->sg); |
710 | } | 710 | } |
711 | 711 | ||
712 | static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) | 712 | static unsigned int sdhci_target_timeout(struct sdhci_host *host, |
713 | struct mmc_command *cmd, | ||
714 | struct mmc_data *data) | ||
713 | { | 715 | { |
714 | u8 count; | 716 | unsigned int target_timeout; |
715 | struct mmc_data *data = cmd->data; | ||
716 | unsigned target_timeout, current_timeout; | ||
717 | |||
718 | /* | ||
719 | * If the host controller provides us with an incorrect timeout | ||
720 | * value, just skip the check and use 0xE. The hardware may take | ||
721 | * longer to time out, but that's much better than having a too-short | ||
722 | * timeout value. | ||
723 | */ | ||
724 | if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) | ||
725 | return 0xE; | ||
726 | |||
727 | /* Unspecified timeout, assume max */ | ||
728 | if (!data && !cmd->busy_timeout) | ||
729 | return 0xE; | ||
730 | 717 | ||
731 | /* timeout in us */ | 718 | /* timeout in us */ |
732 | if (!data) | 719 | if (!data) { |
733 | target_timeout = cmd->busy_timeout * 1000; | 720 | target_timeout = cmd->busy_timeout * 1000; |
734 | else { | 721 | } else { |
735 | target_timeout = DIV_ROUND_UP(data->timeout_ns, 1000); | 722 | target_timeout = DIV_ROUND_UP(data->timeout_ns, 1000); |
736 | if (host->clock && data->timeout_clks) { | 723 | if (host->clock && data->timeout_clks) { |
737 | unsigned long long val; | 724 | unsigned long long val; |
@@ -748,6 +735,67 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) | |||
748 | } | 735 | } |
749 | } | 736 | } |
750 | 737 | ||
738 | return target_timeout; | ||
739 | } | ||
740 | |||
741 | static void sdhci_calc_sw_timeout(struct sdhci_host *host, | ||
742 | struct mmc_command *cmd) | ||
743 | { | ||
744 | struct mmc_data *data = cmd->data; | ||
745 | struct mmc_host *mmc = host->mmc; | ||
746 | struct mmc_ios *ios = &mmc->ios; | ||
747 | unsigned char bus_width = 1 << ios->bus_width; | ||
748 | unsigned int blksz; | ||
749 | unsigned int freq; | ||
750 | u64 target_timeout; | ||
751 | u64 transfer_time; | ||
752 | |||
753 | target_timeout = sdhci_target_timeout(host, cmd, data); | ||
754 | target_timeout *= NSEC_PER_USEC; | ||
755 | |||
756 | if (data) { | ||
757 | blksz = data->blksz; | ||
758 | freq = host->mmc->actual_clock ? : host->clock; | ||
759 | transfer_time = (u64)blksz * NSEC_PER_SEC * (8 / bus_width); | ||
760 | do_div(transfer_time, freq); | ||
761 | /* multiply by '2' to account for any unknowns */ | ||
762 | transfer_time = transfer_time * 2; | ||
763 | /* calculate timeout for the entire data */ | ||
764 | host->data_timeout = data->blocks * target_timeout + | ||
765 | transfer_time; | ||
766 | } else { | ||
767 | host->data_timeout = target_timeout; | ||
768 | } | ||
769 | |||
770 | if (host->data_timeout) | ||
771 | host->data_timeout += MMC_CMD_TRANSFER_TIME; | ||
772 | } | ||
773 | |||
774 | static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd, | ||
775 | bool *too_big) | ||
776 | { | ||
777 | u8 count; | ||
778 | struct mmc_data *data = cmd->data; | ||
779 | unsigned target_timeout, current_timeout; | ||
780 | |||
781 | *too_big = true; | ||
782 | |||
783 | /* | ||
784 | * If the host controller provides us with an incorrect timeout | ||
785 | * value, just skip the check and use 0xE. The hardware may take | ||
786 | * longer to time out, but that's much better than having a too-short | ||
787 | * timeout value. | ||
788 | */ | ||
789 | if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) | ||
790 | return 0xE; | ||
791 | |||
792 | /* Unspecified timeout, assume max */ | ||
793 | if (!data && !cmd->busy_timeout) | ||
794 | return 0xE; | ||
795 | |||
796 | /* timeout in us */ | ||
797 | target_timeout = sdhci_target_timeout(host, cmd, data); | ||
798 | |||
751 | /* | 799 | /* |
752 | * Figure out needed cycles. | 800 | * Figure out needed cycles. |
753 | * We do this in steps in order to fit inside a 32 bit int. | 801 | * We do this in steps in order to fit inside a 32 bit int. |
@@ -768,9 +816,12 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) | |||
768 | } | 816 | } |
769 | 817 | ||
770 | if (count >= 0xF) { | 818 | if (count >= 0xF) { |
771 | DBG("Too large timeout 0x%x requested for CMD%d!\n", | 819 | if (!(host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT)) |
772 | count, cmd->opcode); | 820 | DBG("Too large timeout 0x%x requested for CMD%d!\n", |
821 | count, cmd->opcode); | ||
773 | count = 0xE; | 822 | count = 0xE; |
823 | } else { | ||
824 | *too_big = false; | ||
774 | } | 825 | } |
775 | 826 | ||
776 | return count; | 827 | return count; |
@@ -790,6 +841,16 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host) | |||
790 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); | 841 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); |
791 | } | 842 | } |
792 | 843 | ||
844 | static void sdhci_set_data_timeout_irq(struct sdhci_host *host, bool enable) | ||
845 | { | ||
846 | if (enable) | ||
847 | host->ier |= SDHCI_INT_DATA_TIMEOUT; | ||
848 | else | ||
849 | host->ier &= ~SDHCI_INT_DATA_TIMEOUT; | ||
850 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); | ||
851 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); | ||
852 | } | ||
853 | |||
793 | static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) | 854 | static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) |
794 | { | 855 | { |
795 | u8 count; | 856 | u8 count; |
@@ -797,7 +858,18 @@ static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) | |||
797 | if (host->ops->set_timeout) { | 858 | if (host->ops->set_timeout) { |
798 | host->ops->set_timeout(host, cmd); | 859 | host->ops->set_timeout(host, cmd); |
799 | } else { | 860 | } else { |
800 | count = sdhci_calc_timeout(host, cmd); | 861 | bool too_big = false; |
862 | |||
863 | count = sdhci_calc_timeout(host, cmd, &too_big); | ||
864 | |||
865 | if (too_big && | ||
866 | host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT) { | ||
867 | sdhci_calc_sw_timeout(host, cmd); | ||
868 | sdhci_set_data_timeout_irq(host, false); | ||
869 | } else if (!(host->ier & SDHCI_INT_DATA_TIMEOUT)) { | ||
870 | sdhci_set_data_timeout_irq(host, true); | ||
871 | } | ||
872 | |||
801 | sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); | 873 | sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); |
802 | } | 874 | } |
803 | } | 875 | } |
@@ -807,6 +879,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) | |||
807 | u8 ctrl; | 879 | u8 ctrl; |
808 | struct mmc_data *data = cmd->data; | 880 | struct mmc_data *data = cmd->data; |
809 | 881 | ||
882 | host->data_timeout = 0; | ||
883 | |||
810 | if (sdhci_data_line_cmd(cmd)) | 884 | if (sdhci_data_line_cmd(cmd)) |
811 | sdhci_set_timeout(host, cmd); | 885 | sdhci_set_timeout(host, cmd); |
812 | 886 | ||
@@ -1160,13 +1234,6 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) | |||
1160 | mdelay(1); | 1234 | mdelay(1); |
1161 | } | 1235 | } |
1162 | 1236 | ||
1163 | timeout = jiffies; | ||
1164 | if (!cmd->data && cmd->busy_timeout > 9000) | ||
1165 | timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; | ||
1166 | else | ||
1167 | timeout += 10 * HZ; | ||
1168 | sdhci_mod_timer(host, cmd->mrq, timeout); | ||
1169 | |||
1170 | host->cmd = cmd; | 1237 | host->cmd = cmd; |
1171 | if (sdhci_data_line_cmd(cmd)) { | 1238 | if (sdhci_data_line_cmd(cmd)) { |
1172 | WARN_ON(host->data_cmd); | 1239 | WARN_ON(host->data_cmd); |
@@ -1206,6 +1273,15 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) | |||
1206 | cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) | 1273 | cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) |
1207 | flags |= SDHCI_CMD_DATA; | 1274 | flags |= SDHCI_CMD_DATA; |
1208 | 1275 | ||
1276 | timeout = jiffies; | ||
1277 | if (host->data_timeout) | ||
1278 | timeout += nsecs_to_jiffies(host->data_timeout); | ||
1279 | else if (!cmd->data && cmd->busy_timeout > 9000) | ||
1280 | timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; | ||
1281 | else | ||
1282 | timeout += 10 * HZ; | ||
1283 | sdhci_mod_timer(host, cmd->mrq, timeout); | ||
1284 | |||
1209 | sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); | 1285 | sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); |
1210 | } | 1286 | } |
1211 | EXPORT_SYMBOL_GPL(sdhci_send_command); | 1287 | EXPORT_SYMBOL_GPL(sdhci_send_command); |
@@ -3616,6 +3692,10 @@ int sdhci_setup_host(struct sdhci_host *host) | |||
3616 | mmc->max_busy_timeout /= host->timeout_clk; | 3692 | mmc->max_busy_timeout /= host->timeout_clk; |
3617 | } | 3693 | } |
3618 | 3694 | ||
3695 | if (host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT && | ||
3696 | !host->ops->get_max_timeout_count) | ||
3697 | mmc->max_busy_timeout = 0; | ||
3698 | |||
3619 | mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; | 3699 | mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; |
3620 | mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; | 3700 | mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; |
3621 | 3701 | ||
@@ -3672,6 +3752,16 @@ int sdhci_setup_host(struct sdhci_host *host) | |||
3672 | if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) { | 3752 | if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) { |
3673 | host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | | 3753 | host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | |
3674 | SDHCI_SUPPORT_DDR50); | 3754 | SDHCI_SUPPORT_DDR50); |
3755 | /* | ||
3756 | * The SDHCI controller in a SoC might support HS200/HS400 | ||
3757 | * (indicated using mmc-hs200-1_8v/mmc-hs400-1_8v dt property), | ||
3758 | * but if the board is modeled such that the IO lines are not | ||
3759 | * connected to 1.8v then HS200/HS400 cannot be supported. | ||
3760 | * Disable HS200/HS400 if the board does not have 1.8v connected | ||
3761 | * to the IO lines. (Applicable for other modes in 1.8v) | ||
3762 | */ | ||
3763 | mmc->caps2 &= ~(MMC_CAP2_HSX00_1_8V | MMC_CAP2_HS400_ES); | ||
3764 | mmc->caps &= ~(MMC_CAP_1_8V_DDR | MMC_CAP_UHS); | ||
3675 | } | 3765 | } |
3676 | 3766 | ||
3677 | /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */ | 3767 | /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */ |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index c95b0a4a7594..23966f887da6 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -332,6 +332,14 @@ struct sdhci_adma2_64_desc { | |||
332 | /* Allow for a a command request and a data request at the same time */ | 332 | /* Allow for a a command request and a data request at the same time */ |
333 | #define SDHCI_MAX_MRQS 2 | 333 | #define SDHCI_MAX_MRQS 2 |
334 | 334 | ||
335 | /* | ||
336 | * 48bit command and 136 bit response in 100KHz clock could take upto 2.48ms. | ||
337 | * However since the start time of the command, the time between | ||
338 | * command and response, and the time between response and start of data is | ||
339 | * not known, set the command transfer time to 10ms. | ||
340 | */ | ||
341 | #define MMC_CMD_TRANSFER_TIME (10 * NSEC_PER_MSEC) /* max 10 ms */ | ||
342 | |||
335 | enum sdhci_cookie { | 343 | enum sdhci_cookie { |
336 | COOKIE_UNMAPPED, | 344 | COOKIE_UNMAPPED, |
337 | COOKIE_PRE_MAPPED, /* mapped by sdhci_pre_req() */ | 345 | COOKIE_PRE_MAPPED, /* mapped by sdhci_pre_req() */ |
@@ -437,6 +445,11 @@ struct sdhci_host { | |||
437 | #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) | 445 | #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) |
438 | /* Controller has CRC in 136 bit Command Response */ | 446 | /* Controller has CRC in 136 bit Command Response */ |
439 | #define SDHCI_QUIRK2_RSP_136_HAS_CRC (1<<16) | 447 | #define SDHCI_QUIRK2_RSP_136_HAS_CRC (1<<16) |
448 | /* | ||
449 | * Disable HW timeout if the requested timeout is more than the maximum | ||
450 | * obtainable timeout. | ||
451 | */ | ||
452 | #define SDHCI_QUIRK2_DISABLE_HW_TIMEOUT (1<<17) | ||
440 | 453 | ||
441 | int irq; /* Device IRQ */ | 454 | int irq; /* Device IRQ */ |
442 | void __iomem *ioaddr; /* Mapped address */ | 455 | void __iomem *ioaddr; /* Mapped address */ |
@@ -550,6 +563,8 @@ struct sdhci_host { | |||
550 | /* Host SDMA buffer boundary. */ | 563 | /* Host SDMA buffer boundary. */ |
551 | u32 sdma_boundary; | 564 | u32 sdma_boundary; |
552 | 565 | ||
566 | u64 data_timeout; | ||
567 | |||
553 | unsigned long private[0] ____cacheline_aligned; | 568 | unsigned long private[0] ____cacheline_aligned; |
554 | }; | 569 | }; |
555 | 570 | ||
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index 20cfb20418f3..e7472590f2ed 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c | |||
@@ -13,36 +13,34 @@ | |||
13 | * the License, or (at your option) any later version. | 13 | * the License, or (at your option) any later version. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/err.h> | ||
23 | |||
24 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
25 | #include <linux/clk/sunxi-ng.h> | 17 | #include <linux/clk/sunxi-ng.h> |
26 | #include <linux/gpio.h> | 18 | #include <linux/delay.h> |
27 | #include <linux/platform_device.h> | 19 | #include <linux/device.h> |
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/scatterlist.h> | ||
30 | #include <linux/dma-mapping.h> | 20 | #include <linux/dma-mapping.h> |
31 | #include <linux/slab.h> | 21 | #include <linux/err.h> |
32 | #include <linux/reset.h> | 22 | #include <linux/gpio.h> |
33 | #include <linux/regulator/consumer.h> | 23 | #include <linux/interrupt.h> |
34 | 24 | #include <linux/io.h> | |
35 | #include <linux/of_address.h> | 25 | #include <linux/kernel.h> |
36 | #include <linux/of_gpio.h> | 26 | #include <linux/mmc/card.h> |
37 | #include <linux/of_platform.h> | 27 | #include <linux/mmc/core.h> |
38 | |||
39 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
29 | #include <linux/mmc/mmc.h> | ||
40 | #include <linux/mmc/sd.h> | 30 | #include <linux/mmc/sd.h> |
41 | #include <linux/mmc/sdio.h> | 31 | #include <linux/mmc/sdio.h> |
42 | #include <linux/mmc/mmc.h> | ||
43 | #include <linux/mmc/core.h> | ||
44 | #include <linux/mmc/card.h> | ||
45 | #include <linux/mmc/slot-gpio.h> | 32 | #include <linux/mmc/slot-gpio.h> |
33 | #include <linux/module.h> | ||
34 | #include <linux/of_address.h> | ||
35 | #include <linux/of_gpio.h> | ||
36 | #include <linux/of_platform.h> | ||
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/pm_runtime.h> | ||
39 | #include <linux/regulator/consumer.h> | ||
40 | #include <linux/reset.h> | ||
41 | #include <linux/scatterlist.h> | ||
42 | #include <linux/slab.h> | ||
43 | #include <linux/spinlock.h> | ||
46 | 44 | ||
47 | /* register offset definitions */ | 45 | /* register offset definitions */ |
48 | #define SDXC_REG_GCTRL (0x00) /* SMC Global Control Register */ | 46 | #define SDXC_REG_GCTRL (0x00) /* SMC Global Control Register */ |
@@ -322,10 +320,9 @@ static int sunxi_mmc_reset_host(struct sunxi_mmc_host *host) | |||
322 | return 0; | 320 | return 0; |
323 | } | 321 | } |
324 | 322 | ||
325 | static int sunxi_mmc_init_host(struct mmc_host *mmc) | 323 | static int sunxi_mmc_init_host(struct sunxi_mmc_host *host) |
326 | { | 324 | { |
327 | u32 rval; | 325 | u32 rval; |
328 | struct sunxi_mmc_host *host = mmc_priv(mmc); | ||
329 | 326 | ||
330 | if (sunxi_mmc_reset_host(host)) | 327 | if (sunxi_mmc_reset_host(host)) |
331 | return -EIO; | 328 | return -EIO; |
@@ -859,17 +856,48 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, | |||
859 | return 0; | 856 | return 0; |
860 | } | 857 | } |
861 | 858 | ||
862 | static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 859 | static void sunxi_mmc_set_bus_width(struct sunxi_mmc_host *host, |
860 | unsigned char width) | ||
861 | { | ||
862 | switch (width) { | ||
863 | case MMC_BUS_WIDTH_1: | ||
864 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH1); | ||
865 | break; | ||
866 | case MMC_BUS_WIDTH_4: | ||
867 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH4); | ||
868 | break; | ||
869 | case MMC_BUS_WIDTH_8: | ||
870 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH8); | ||
871 | break; | ||
872 | } | ||
873 | } | ||
874 | |||
875 | static void sunxi_mmc_set_clk(struct sunxi_mmc_host *host, struct mmc_ios *ios) | ||
863 | { | 876 | { |
864 | struct sunxi_mmc_host *host = mmc_priv(mmc); | ||
865 | u32 rval; | 877 | u32 rval; |
866 | 878 | ||
867 | /* Set the power state */ | 879 | /* set ddr mode */ |
868 | switch (ios->power_mode) { | 880 | rval = mmc_readl(host, REG_GCTRL); |
869 | case MMC_POWER_ON: | 881 | if (ios->timing == MMC_TIMING_UHS_DDR50 || |
870 | break; | 882 | ios->timing == MMC_TIMING_MMC_DDR52) |
883 | rval |= SDXC_DDR_MODE; | ||
884 | else | ||
885 | rval &= ~SDXC_DDR_MODE; | ||
886 | mmc_writel(host, REG_GCTRL, rval); | ||
887 | |||
888 | host->ferror = sunxi_mmc_clk_set_rate(host, ios); | ||
889 | /* Android code had a usleep_range(50000, 55000); here */ | ||
890 | } | ||
871 | 891 | ||
892 | static void sunxi_mmc_card_power(struct sunxi_mmc_host *host, | ||
893 | struct mmc_ios *ios) | ||
894 | { | ||
895 | struct mmc_host *mmc = host->mmc; | ||
896 | |||
897 | switch (ios->power_mode) { | ||
872 | case MMC_POWER_UP: | 898 | case MMC_POWER_UP: |
899 | dev_dbg(mmc_dev(mmc), "Powering card up\n"); | ||
900 | |||
873 | if (!IS_ERR(mmc->supply.vmmc)) { | 901 | if (!IS_ERR(mmc->supply.vmmc)) { |
874 | host->ferror = mmc_regulator_set_ocr(mmc, | 902 | host->ferror = mmc_regulator_set_ocr(mmc, |
875 | mmc->supply.vmmc, | 903 | mmc->supply.vmmc, |
@@ -887,53 +915,33 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
887 | } | 915 | } |
888 | host->vqmmc_enabled = true; | 916 | host->vqmmc_enabled = true; |
889 | } | 917 | } |
890 | |||
891 | host->ferror = sunxi_mmc_init_host(mmc); | ||
892 | if (host->ferror) | ||
893 | return; | ||
894 | |||
895 | dev_dbg(mmc_dev(mmc), "power on!\n"); | ||
896 | break; | 918 | break; |
897 | 919 | ||
898 | case MMC_POWER_OFF: | 920 | case MMC_POWER_OFF: |
899 | dev_dbg(mmc_dev(mmc), "power off!\n"); | 921 | dev_dbg(mmc_dev(mmc), "Powering card off\n"); |
900 | sunxi_mmc_reset_host(host); | 922 | |
901 | if (!IS_ERR(mmc->supply.vmmc)) | 923 | if (!IS_ERR(mmc->supply.vmmc)) |
902 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); | 924 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); |
903 | 925 | ||
904 | if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) | 926 | if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) |
905 | regulator_disable(mmc->supply.vqmmc); | 927 | regulator_disable(mmc->supply.vqmmc); |
928 | |||
906 | host->vqmmc_enabled = false; | 929 | host->vqmmc_enabled = false; |
907 | break; | 930 | break; |
908 | } | ||
909 | 931 | ||
910 | /* set bus width */ | 932 | default: |
911 | switch (ios->bus_width) { | 933 | dev_dbg(mmc_dev(mmc), "Ignoring unknown card power state\n"); |
912 | case MMC_BUS_WIDTH_1: | ||
913 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH1); | ||
914 | break; | ||
915 | case MMC_BUS_WIDTH_4: | ||
916 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH4); | ||
917 | break; | ||
918 | case MMC_BUS_WIDTH_8: | ||
919 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH8); | ||
920 | break; | 934 | break; |
921 | } | 935 | } |
936 | } | ||
922 | 937 | ||
923 | /* set ddr mode */ | 938 | static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
924 | rval = mmc_readl(host, REG_GCTRL); | 939 | { |
925 | if (ios->timing == MMC_TIMING_UHS_DDR50 || | 940 | struct sunxi_mmc_host *host = mmc_priv(mmc); |
926 | ios->timing == MMC_TIMING_MMC_DDR52) | ||
927 | rval |= SDXC_DDR_MODE; | ||
928 | else | ||
929 | rval &= ~SDXC_DDR_MODE; | ||
930 | mmc_writel(host, REG_GCTRL, rval); | ||
931 | 941 | ||
932 | /* set up clock */ | 942 | sunxi_mmc_card_power(host, ios); |
933 | if (ios->power_mode) { | 943 | sunxi_mmc_set_bus_width(host, ios->bus_width); |
934 | host->ferror = sunxi_mmc_clk_set_rate(host, ios); | 944 | sunxi_mmc_set_clk(host, ios); |
935 | /* Android code had a usleep_range(50000, 55000); here */ | ||
936 | } | ||
937 | } | 945 | } |
938 | 946 | ||
939 | static int sunxi_mmc_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) | 947 | static int sunxi_mmc_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) |
@@ -955,6 +963,9 @@ static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
955 | unsigned long flags; | 963 | unsigned long flags; |
956 | u32 imask; | 964 | u32 imask; |
957 | 965 | ||
966 | if (enable) | ||
967 | pm_runtime_get_noresume(host->dev); | ||
968 | |||
958 | spin_lock_irqsave(&host->lock, flags); | 969 | spin_lock_irqsave(&host->lock, flags); |
959 | 970 | ||
960 | imask = mmc_readl(host, REG_IMASK); | 971 | imask = mmc_readl(host, REG_IMASK); |
@@ -967,6 +978,9 @@ static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
967 | } | 978 | } |
968 | mmc_writel(host, REG_IMASK, imask); | 979 | mmc_writel(host, REG_IMASK, imask); |
969 | spin_unlock_irqrestore(&host->lock, flags); | 980 | spin_unlock_irqrestore(&host->lock, flags); |
981 | |||
982 | if (!enable) | ||
983 | pm_runtime_put_noidle(host->mmc->parent); | ||
970 | } | 984 | } |
971 | 985 | ||
972 | static void sunxi_mmc_hw_reset(struct mmc_host *mmc) | 986 | static void sunxi_mmc_hw_reset(struct mmc_host *mmc) |
@@ -1380,6 +1394,15 @@ static int sunxi_mmc_probe(struct platform_device *pdev) | |||
1380 | if (ret) | 1394 | if (ret) |
1381 | goto error_free_dma; | 1395 | goto error_free_dma; |
1382 | 1396 | ||
1397 | ret = sunxi_mmc_init_host(host); | ||
1398 | if (ret) | ||
1399 | goto error_free_dma; | ||
1400 | |||
1401 | pm_runtime_set_active(&pdev->dev); | ||
1402 | pm_runtime_set_autosuspend_delay(&pdev->dev, 50); | ||
1403 | pm_runtime_use_autosuspend(&pdev->dev); | ||
1404 | pm_runtime_enable(&pdev->dev); | ||
1405 | |||
1383 | ret = mmc_add_host(mmc); | 1406 | ret = mmc_add_host(mmc); |
1384 | if (ret) | 1407 | if (ret) |
1385 | goto error_free_dma; | 1408 | goto error_free_dma; |
@@ -1400,6 +1423,7 @@ static int sunxi_mmc_remove(struct platform_device *pdev) | |||
1400 | struct sunxi_mmc_host *host = mmc_priv(mmc); | 1423 | struct sunxi_mmc_host *host = mmc_priv(mmc); |
1401 | 1424 | ||
1402 | mmc_remove_host(mmc); | 1425 | mmc_remove_host(mmc); |
1426 | pm_runtime_force_suspend(&pdev->dev); | ||
1403 | disable_irq(host->irq); | 1427 | disable_irq(host->irq); |
1404 | sunxi_mmc_disable(host); | 1428 | sunxi_mmc_disable(host); |
1405 | dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); | 1429 | dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); |
@@ -1408,10 +1432,47 @@ static int sunxi_mmc_remove(struct platform_device *pdev) | |||
1408 | return 0; | 1432 | return 0; |
1409 | } | 1433 | } |
1410 | 1434 | ||
1435 | #ifdef CONFIG_PM | ||
1436 | static int sunxi_mmc_runtime_resume(struct device *dev) | ||
1437 | { | ||
1438 | struct mmc_host *mmc = dev_get_drvdata(dev); | ||
1439 | struct sunxi_mmc_host *host = mmc_priv(mmc); | ||
1440 | int ret; | ||
1441 | |||
1442 | ret = sunxi_mmc_enable(host); | ||
1443 | if (ret) | ||
1444 | return ret; | ||
1445 | |||
1446 | sunxi_mmc_init_host(host); | ||
1447 | sunxi_mmc_set_bus_width(host, mmc->ios.bus_width); | ||
1448 | sunxi_mmc_set_clk(host, &mmc->ios); | ||
1449 | |||
1450 | return 0; | ||
1451 | } | ||
1452 | |||
1453 | static int sunxi_mmc_runtime_suspend(struct device *dev) | ||
1454 | { | ||
1455 | struct mmc_host *mmc = dev_get_drvdata(dev); | ||
1456 | struct sunxi_mmc_host *host = mmc_priv(mmc); | ||
1457 | |||
1458 | sunxi_mmc_reset_host(host); | ||
1459 | sunxi_mmc_disable(host); | ||
1460 | |||
1461 | return 0; | ||
1462 | } | ||
1463 | #endif | ||
1464 | |||
1465 | static const struct dev_pm_ops sunxi_mmc_pm_ops = { | ||
1466 | SET_RUNTIME_PM_OPS(sunxi_mmc_runtime_suspend, | ||
1467 | sunxi_mmc_runtime_resume, | ||
1468 | NULL) | ||
1469 | }; | ||
1470 | |||
1411 | static struct platform_driver sunxi_mmc_driver = { | 1471 | static struct platform_driver sunxi_mmc_driver = { |
1412 | .driver = { | 1472 | .driver = { |
1413 | .name = "sunxi-mmc", | 1473 | .name = "sunxi-mmc", |
1414 | .of_match_table = of_match_ptr(sunxi_mmc_of_match), | 1474 | .of_match_table = of_match_ptr(sunxi_mmc_of_match), |
1475 | .pm = &sunxi_mmc_pm_ops, | ||
1415 | }, | 1476 | }, |
1416 | .probe = sunxi_mmc_probe, | 1477 | .probe = sunxi_mmc_probe, |
1417 | .remove = sunxi_mmc_remove, | 1478 | .remove = sunxi_mmc_remove, |
diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c index 81dac17064d7..b2b379b10dfa 100644 --- a/drivers/mmc/host/ushc.c +++ b/drivers/mmc/host/ushc.c | |||
@@ -300,8 +300,10 @@ static void ushc_request(struct mmc_host *mmc, struct mmc_request *req) | |||
300 | pipe = usb_sndbulkpipe(ushc->usb_dev, 2); | 300 | pipe = usb_sndbulkpipe(ushc->usb_dev, 2); |
301 | 301 | ||
302 | usb_fill_bulk_urb(ushc->data_urb, ushc->usb_dev, pipe, | 302 | usb_fill_bulk_urb(ushc->data_urb, ushc->usb_dev, pipe, |
303 | sg_virt(data->sg), data->sg->length, | 303 | NULL, data->sg->length, |
304 | data_callback, ushc); | 304 | data_callback, ushc); |
305 | ushc->data_urb->num_sgs = 1; | ||
306 | ushc->data_urb->sg = data->sg; | ||
305 | ret = usb_submit_urb(ushc->data_urb, GFP_ATOMIC); | 307 | ret = usb_submit_urb(ushc->data_urb, GFP_ATOMIC); |
306 | if (ret < 0) | 308 | if (ret < 0) |
307 | goto out; | 309 | goto out; |
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index f4233576153b..1e54bbf13d75 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
@@ -268,43 +268,29 @@ static inline int wbsd_next_sg(struct wbsd_host *host) | |||
268 | return host->num_sg; | 268 | return host->num_sg; |
269 | } | 269 | } |
270 | 270 | ||
271 | static inline char *wbsd_sg_to_buffer(struct wbsd_host *host) | 271 | static inline char *wbsd_map_sg(struct wbsd_host *host) |
272 | { | 272 | { |
273 | return sg_virt(host->cur_sg); | 273 | return kmap_atomic(sg_page(host->cur_sg)) + host->cur_sg->offset; |
274 | } | 274 | } |
275 | 275 | ||
276 | static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) | 276 | static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) |
277 | { | 277 | { |
278 | unsigned int len, i; | 278 | size_t len = 0; |
279 | struct scatterlist *sg; | 279 | int i; |
280 | char *dmabuf = host->dma_buffer; | 280 | |
281 | char *sgbuf; | 281 | for (i = 0; i < data->sg_len; i++) |
282 | 282 | len += data->sg[i].length; | |
283 | sg = data->sg; | 283 | sg_copy_to_buffer(data->sg, data->sg_len, host->dma_buffer, len); |
284 | len = data->sg_len; | ||
285 | |||
286 | for (i = 0; i < len; i++) { | ||
287 | sgbuf = sg_virt(&sg[i]); | ||
288 | memcpy(dmabuf, sgbuf, sg[i].length); | ||
289 | dmabuf += sg[i].length; | ||
290 | } | ||
291 | } | 284 | } |
292 | 285 | ||
293 | static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) | 286 | static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) |
294 | { | 287 | { |
295 | unsigned int len, i; | 288 | size_t len = 0; |
296 | struct scatterlist *sg; | 289 | int i; |
297 | char *dmabuf = host->dma_buffer; | 290 | |
298 | char *sgbuf; | 291 | for (i = 0; i < data->sg_len; i++) |
299 | 292 | len += data->sg[i].length; | |
300 | sg = data->sg; | 293 | sg_copy_from_buffer(data->sg, data->sg_len, host->dma_buffer, len); |
301 | len = data->sg_len; | ||
302 | |||
303 | for (i = 0; i < len; i++) { | ||
304 | sgbuf = sg_virt(&sg[i]); | ||
305 | memcpy(sgbuf, dmabuf, sg[i].length); | ||
306 | dmabuf += sg[i].length; | ||
307 | } | ||
308 | } | 294 | } |
309 | 295 | ||
310 | /* | 296 | /* |
@@ -418,7 +404,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
418 | { | 404 | { |
419 | struct mmc_data *data = host->mrq->cmd->data; | 405 | struct mmc_data *data = host->mrq->cmd->data; |
420 | char *buffer; | 406 | char *buffer; |
421 | int i, fsr, fifo; | 407 | int i, idx, fsr, fifo; |
422 | 408 | ||
423 | /* | 409 | /* |
424 | * Handle excessive data. | 410 | * Handle excessive data. |
@@ -426,7 +412,8 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
426 | if (host->num_sg == 0) | 412 | if (host->num_sg == 0) |
427 | return; | 413 | return; |
428 | 414 | ||
429 | buffer = wbsd_sg_to_buffer(host) + host->offset; | 415 | buffer = wbsd_map_sg(host) + host->offset; |
416 | idx = 0; | ||
430 | 417 | ||
431 | /* | 418 | /* |
432 | * Drain the fifo. This has a tendency to loop longer | 419 | * Drain the fifo. This has a tendency to loop longer |
@@ -445,8 +432,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
445 | fifo = 1; | 432 | fifo = 1; |
446 | 433 | ||
447 | for (i = 0; i < fifo; i++) { | 434 | for (i = 0; i < fifo; i++) { |
448 | *buffer = inb(host->base + WBSD_DFR); | 435 | buffer[idx++] = inb(host->base + WBSD_DFR); |
449 | buffer++; | ||
450 | host->offset++; | 436 | host->offset++; |
451 | host->remain--; | 437 | host->remain--; |
452 | 438 | ||
@@ -456,16 +442,19 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
456 | * End of scatter list entry? | 442 | * End of scatter list entry? |
457 | */ | 443 | */ |
458 | if (host->remain == 0) { | 444 | if (host->remain == 0) { |
445 | kunmap_atomic(buffer); | ||
459 | /* | 446 | /* |
460 | * Get next entry. Check if last. | 447 | * Get next entry. Check if last. |
461 | */ | 448 | */ |
462 | if (!wbsd_next_sg(host)) | 449 | if (!wbsd_next_sg(host)) |
463 | return; | 450 | return; |
464 | 451 | ||
465 | buffer = wbsd_sg_to_buffer(host); | 452 | buffer = wbsd_map_sg(host); |
453 | idx = 0; | ||
466 | } | 454 | } |
467 | } | 455 | } |
468 | } | 456 | } |
457 | kunmap_atomic(buffer); | ||
469 | 458 | ||
470 | /* | 459 | /* |
471 | * This is a very dirty hack to solve a | 460 | * This is a very dirty hack to solve a |
@@ -480,7 +469,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
480 | { | 469 | { |
481 | struct mmc_data *data = host->mrq->cmd->data; | 470 | struct mmc_data *data = host->mrq->cmd->data; |
482 | char *buffer; | 471 | char *buffer; |
483 | int i, fsr, fifo; | 472 | int i, idx, fsr, fifo; |
484 | 473 | ||
485 | /* | 474 | /* |
486 | * Check that we aren't being called after the | 475 | * Check that we aren't being called after the |
@@ -489,7 +478,8 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
489 | if (host->num_sg == 0) | 478 | if (host->num_sg == 0) |
490 | return; | 479 | return; |
491 | 480 | ||
492 | buffer = wbsd_sg_to_buffer(host) + host->offset; | 481 | buffer = wbsd_map_sg(host) + host->offset; |
482 | idx = 0; | ||
493 | 483 | ||
494 | /* | 484 | /* |
495 | * Fill the fifo. This has a tendency to loop longer | 485 | * Fill the fifo. This has a tendency to loop longer |
@@ -508,8 +498,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
508 | fifo = 15; | 498 | fifo = 15; |
509 | 499 | ||
510 | for (i = 16; i > fifo; i--) { | 500 | for (i = 16; i > fifo; i--) { |
511 | outb(*buffer, host->base + WBSD_DFR); | 501 | outb(buffer[idx], host->base + WBSD_DFR); |
512 | buffer++; | ||
513 | host->offset++; | 502 | host->offset++; |
514 | host->remain--; | 503 | host->remain--; |
515 | 504 | ||
@@ -519,16 +508,19 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
519 | * End of scatter list entry? | 508 | * End of scatter list entry? |
520 | */ | 509 | */ |
521 | if (host->remain == 0) { | 510 | if (host->remain == 0) { |
511 | kunmap_atomic(buffer); | ||
522 | /* | 512 | /* |
523 | * Get next entry. Check if last. | 513 | * Get next entry. Check if last. |
524 | */ | 514 | */ |
525 | if (!wbsd_next_sg(host)) | 515 | if (!wbsd_next_sg(host)) |
526 | return; | 516 | return; |
527 | 517 | ||
528 | buffer = wbsd_sg_to_buffer(host); | 518 | buffer = wbsd_map_sg(host); |
519 | idx = 0; | ||
529 | } | 520 | } |
530 | } | 521 | } |
531 | } | 522 | } |
523 | kunmap_atomic(buffer); | ||
532 | 524 | ||
533 | /* | 525 | /* |
534 | * The controller stops sending interrupts for | 526 | * The controller stops sending interrupts for |
diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c index fd30ac7da5e5..3ba42f508014 100644 --- a/drivers/mmc/host/wmt-sdmmc.c +++ b/drivers/mmc/host/wmt-sdmmc.c | |||
@@ -928,8 +928,7 @@ static int wmt_mci_remove(struct platform_device *pdev) | |||
928 | static int wmt_mci_suspend(struct device *dev) | 928 | static int wmt_mci_suspend(struct device *dev) |
929 | { | 929 | { |
930 | u32 reg_tmp; | 930 | u32 reg_tmp; |
931 | struct platform_device *pdev = to_platform_device(dev); | 931 | struct mmc_host *mmc = dev_get_drvdata(dev); |
932 | struct mmc_host *mmc = platform_get_drvdata(pdev); | ||
933 | struct wmt_mci_priv *priv; | 932 | struct wmt_mci_priv *priv; |
934 | 933 | ||
935 | if (!mmc) | 934 | if (!mmc) |
@@ -953,8 +952,7 @@ static int wmt_mci_suspend(struct device *dev) | |||
953 | static int wmt_mci_resume(struct device *dev) | 952 | static int wmt_mci_resume(struct device *dev) |
954 | { | 953 | { |
955 | u32 reg_tmp; | 954 | u32 reg_tmp; |
956 | struct platform_device *pdev = to_platform_device(dev); | 955 | struct mmc_host *mmc = dev_get_drvdata(dev); |
957 | struct mmc_host *mmc = platform_get_drvdata(pdev); | ||
958 | struct wmt_mci_priv *priv; | 956 | struct wmt_mci_priv *priv; |
959 | 957 | ||
960 | if (mmc) { | 958 | if (mmc) { |
diff --git a/include/dt-bindings/dma/jz4780-dma.h b/include/dt-bindings/dma/jz4780-dma.h new file mode 100644 index 000000000000..df017fdfb44e --- /dev/null +++ b/include/dt-bindings/dma/jz4780-dma.h | |||
@@ -0,0 +1,49 @@ | |||
1 | #ifndef __DT_BINDINGS_DMA_JZ4780_DMA_H__ | ||
2 | #define __DT_BINDINGS_DMA_JZ4780_DMA_H__ | ||
3 | |||
4 | /* | ||
5 | * Request type numbers for the JZ4780 DMA controller (written to the DRTn | ||
6 | * register for the channel). | ||
7 | */ | ||
8 | #define JZ4780_DMA_I2S1_TX 0x4 | ||
9 | #define JZ4780_DMA_I2S1_RX 0x5 | ||
10 | #define JZ4780_DMA_I2S0_TX 0x6 | ||
11 | #define JZ4780_DMA_I2S0_RX 0x7 | ||
12 | #define JZ4780_DMA_AUTO 0x8 | ||
13 | #define JZ4780_DMA_SADC_RX 0x9 | ||
14 | #define JZ4780_DMA_UART4_TX 0xc | ||
15 | #define JZ4780_DMA_UART4_RX 0xd | ||
16 | #define JZ4780_DMA_UART3_TX 0xe | ||
17 | #define JZ4780_DMA_UART3_RX 0xf | ||
18 | #define JZ4780_DMA_UART2_TX 0x10 | ||
19 | #define JZ4780_DMA_UART2_RX 0x11 | ||
20 | #define JZ4780_DMA_UART1_TX 0x12 | ||
21 | #define JZ4780_DMA_UART1_RX 0x13 | ||
22 | #define JZ4780_DMA_UART0_TX 0x14 | ||
23 | #define JZ4780_DMA_UART0_RX 0x15 | ||
24 | #define JZ4780_DMA_SSI0_TX 0x16 | ||
25 | #define JZ4780_DMA_SSI0_RX 0x17 | ||
26 | #define JZ4780_DMA_SSI1_TX 0x18 | ||
27 | #define JZ4780_DMA_SSI1_RX 0x19 | ||
28 | #define JZ4780_DMA_MSC0_TX 0x1a | ||
29 | #define JZ4780_DMA_MSC0_RX 0x1b | ||
30 | #define JZ4780_DMA_MSC1_TX 0x1c | ||
31 | #define JZ4780_DMA_MSC1_RX 0x1d | ||
32 | #define JZ4780_DMA_MSC2_TX 0x1e | ||
33 | #define JZ4780_DMA_MSC2_RX 0x1f | ||
34 | #define JZ4780_DMA_PCM0_TX 0x20 | ||
35 | #define JZ4780_DMA_PCM0_RX 0x21 | ||
36 | #define JZ4780_DMA_SMB0_TX 0x24 | ||
37 | #define JZ4780_DMA_SMB0_RX 0x25 | ||
38 | #define JZ4780_DMA_SMB1_TX 0x26 | ||
39 | #define JZ4780_DMA_SMB1_RX 0x27 | ||
40 | #define JZ4780_DMA_SMB2_TX 0x28 | ||
41 | #define JZ4780_DMA_SMB2_RX 0x29 | ||
42 | #define JZ4780_DMA_SMB3_TX 0x2a | ||
43 | #define JZ4780_DMA_SMB3_RX 0x2b | ||
44 | #define JZ4780_DMA_SMB4_TX 0x2c | ||
45 | #define JZ4780_DMA_SMB4_RX 0x2d | ||
46 | #define JZ4780_DMA_DES_TX 0x2e | ||
47 | #define JZ4780_DMA_DES_RX 0x2f | ||
48 | |||
49 | #endif /* __DT_BINDINGS_DMA_JZ4780_DMA_H__ */ | ||
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 279b39008a33..de7377815b6b 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -156,6 +156,7 @@ struct sd_switch_caps { | |||
156 | #define UHS_DDR50_MAX_DTR 50000000 | 156 | #define UHS_DDR50_MAX_DTR 50000000 |
157 | #define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR | 157 | #define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR |
158 | #define UHS_SDR12_MAX_DTR 25000000 | 158 | #define UHS_SDR12_MAX_DTR 25000000 |
159 | #define DEFAULT_SPEED_MAX_DTR UHS_SDR12_MAX_DTR | ||
159 | unsigned int sd3_bus_mode; | 160 | unsigned int sd3_bus_mode; |
160 | #define UHS_SDR12_BUS_SPEED 0 | 161 | #define UHS_SDR12_BUS_SPEED 0 |
161 | #define HIGH_SPEED_BUS_SPEED 1 | 162 | #define HIGH_SPEED_BUS_SPEED 1 |
@@ -252,6 +253,7 @@ struct mmc_card { | |||
252 | #define MMC_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */ | 253 | #define MMC_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */ |
253 | unsigned int state; /* (our) card state */ | 254 | unsigned int state; /* (our) card state */ |
254 | unsigned int quirks; /* card quirks */ | 255 | unsigned int quirks; /* card quirks */ |
256 | unsigned int quirk_max_rate; /* max rate set by quirks */ | ||
255 | #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ | 257 | #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ |
256 | #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ | 258 | #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ |
257 | /* for byte mode */ | 259 | /* for byte mode */ |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 927519385482..134a6483347a 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
@@ -177,6 +177,7 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, | |||
177 | int retries); | 177 | int retries); |
178 | 178 | ||
179 | int mmc_hw_reset(struct mmc_host *host); | 179 | int mmc_hw_reset(struct mmc_host *host); |
180 | int mmc_sw_reset(struct mmc_host *host); | ||
180 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card); | 181 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card); |
181 | 182 | ||
182 | #endif /* LINUX_MMC_CORE_H */ | 183 | #endif /* LINUX_MMC_CORE_H */ |
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 85146235231e..64300a48dcce 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -22,6 +22,7 @@ | |||
22 | struct mmc_ios { | 22 | struct mmc_ios { |
23 | unsigned int clock; /* clock rate */ | 23 | unsigned int clock; /* clock rate */ |
24 | unsigned short vdd; | 24 | unsigned short vdd; |
25 | unsigned int power_delay_ms; /* waiting for stable power */ | ||
25 | 26 | ||
26 | /* vdd stores the bit number of the selected voltage range from below. */ | 27 | /* vdd stores the bit number of the selected voltage range from below. */ |
27 | 28 | ||
@@ -320,6 +321,9 @@ struct mmc_host { | |||
320 | #define MMC_CAP_UHS_SDR50 (1 << 18) /* Host supports UHS SDR50 mode */ | 321 | #define MMC_CAP_UHS_SDR50 (1 << 18) /* Host supports UHS SDR50 mode */ |
321 | #define MMC_CAP_UHS_SDR104 (1 << 19) /* Host supports UHS SDR104 mode */ | 322 | #define MMC_CAP_UHS_SDR104 (1 << 19) /* Host supports UHS SDR104 mode */ |
322 | #define MMC_CAP_UHS_DDR50 (1 << 20) /* Host supports UHS DDR50 mode */ | 323 | #define MMC_CAP_UHS_DDR50 (1 << 20) /* Host supports UHS DDR50 mode */ |
324 | #define MMC_CAP_UHS (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | \ | ||
325 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | \ | ||
326 | MMC_CAP_UHS_DDR50) | ||
323 | /* (1 << 21) is free for reuse */ | 327 | /* (1 << 21) is free for reuse */ |
324 | #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ | 328 | #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ |
325 | #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ | 329 | #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ |
@@ -345,6 +349,7 @@ struct mmc_host { | |||
345 | #define MMC_CAP2_HS400_1_2V (1 << 16) /* Can support HS400 1.2V */ | 349 | #define MMC_CAP2_HS400_1_2V (1 << 16) /* Can support HS400 1.2V */ |
346 | #define MMC_CAP2_HS400 (MMC_CAP2_HS400_1_8V | \ | 350 | #define MMC_CAP2_HS400 (MMC_CAP2_HS400_1_8V | \ |
347 | MMC_CAP2_HS400_1_2V) | 351 | MMC_CAP2_HS400_1_2V) |
352 | #define MMC_CAP2_HSX00_1_8V (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS400_1_8V) | ||
348 | #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) | 353 | #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) |
349 | #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) | 354 | #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) |
350 | #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ | 355 | #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ |
@@ -354,6 +359,7 @@ struct mmc_host { | |||
354 | #define MMC_CAP2_NO_MMC (1 << 22) /* Do not send (e)MMC commands during initialization */ | 359 | #define MMC_CAP2_NO_MMC (1 << 22) /* Do not send (e)MMC commands during initialization */ |
355 | #define MMC_CAP2_CQE (1 << 23) /* Has eMMC command queue engine */ | 360 | #define MMC_CAP2_CQE (1 << 23) /* Has eMMC command queue engine */ |
356 | #define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */ | 361 | #define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */ |
362 | #define MMC_CAP2_AVOID_3_3V (1 << 25) /* Host must negotiate down from 3.3V */ | ||
357 | 363 | ||
358 | int fixed_drv_type; /* fixed driver type for non-removable media */ | 364 | int fixed_drv_type; /* fixed driver type for non-removable media */ |
359 | 365 | ||
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index cdd66a5fbd5e..2836a96e014a 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h | |||
@@ -55,6 +55,7 @@ | |||
55 | #define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 | 55 | #define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 |
56 | #define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 | 56 | #define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 |
57 | #define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128 | 57 | #define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128 |
58 | #define SDIO_DEVICE_ID_MARVELL_8887WLAN 0x9134 | ||
58 | 59 | ||
59 | #define SDIO_VENDOR_ID_SIANO 0x039a | 60 | #define SDIO_VENDOR_ID_SIANO 0x039a |
60 | #define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201 | 61 | #define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201 |