xref: /openbmc/linux/drivers/mmc/host/mmci.c (revision ca6b5fe2)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21c6a0718SPierre Ossman /*
370f10482SPierre Ossman  *  linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver
41c6a0718SPierre Ossman  *
51c6a0718SPierre Ossman  *  Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
6c8ebae37SRussell King  *  Copyright (C) 2010 ST-Ericsson SA
71c6a0718SPierre Ossman  */
81c6a0718SPierre Ossman #include <linux/module.h>
91c6a0718SPierre Ossman #include <linux/moduleparam.h>
101c6a0718SPierre Ossman #include <linux/init.h>
111c6a0718SPierre Ossman #include <linux/ioport.h>
121c6a0718SPierre Ossman #include <linux/device.h>
13ef289982SUlf Hansson #include <linux/io.h>
141c6a0718SPierre Ossman #include <linux/interrupt.h>
15613b152cSRussell King #include <linux/kernel.h>
16000bc9d5SLee Jones #include <linux/slab.h>
171c6a0718SPierre Ossman #include <linux/delay.h>
181c6a0718SPierre Ossman #include <linux/err.h>
191c6a0718SPierre Ossman #include <linux/highmem.h>
20019a5f56SNicolas Pitre #include <linux/log2.h>
21c8073e52SLudovic Barre #include <linux/mmc/mmc.h>
2270be208fSUlf Hansson #include <linux/mmc/pm.h>
231c6a0718SPierre Ossman #include <linux/mmc/host.h>
2434177802SLinus Walleij #include <linux/mmc/card.h>
2575773165SLudovic Barre #include <linux/mmc/sd.h>
26d2762090SUlf Hansson #include <linux/mmc/slot-gpio.h>
271c6a0718SPierre Ossman #include <linux/amba/bus.h>
281c6a0718SPierre Ossman #include <linux/clk.h>
29bd6dee6fSJens Axboe #include <linux/scatterlist.h>
309ef986a6SLinus Walleij #include <linux/of.h>
3134e84f39SLinus Walleij #include <linux/regulator/consumer.h>
32c8ebae37SRussell King #include <linux/dmaengine.h>
33c8ebae37SRussell King #include <linux/dma-mapping.h>
34c8ebae37SRussell King #include <linux/amba/mmci.h>
351c3be369SRussell King #include <linux/pm_runtime.h>
36258aea76SViresh Kumar #include <linux/types.h>
37a9a83785SLinus Walleij #include <linux/pinctrl/consumer.h>
3815878e58SLudovic Barre #include <linux/reset.h>
396351cac9SMarek Vasut #include <linux/gpio/consumer.h>
401c6a0718SPierre Ossman 
411c6a0718SPierre Ossman #include <asm/div64.h>
421c6a0718SPierre Ossman #include <asm/io.h>
431c6a0718SPierre Ossman 
441c6a0718SPierre Ossman #include "mmci.h"
451c6a0718SPierre Ossman 
461c6a0718SPierre Ossman #define DRIVER_NAME "mmci-pl18x"
471c6a0718SPierre Ossman 
4871953e0eSUlf Hansson static void mmci_variant_init(struct mmci_host *host);
49cb0335b7SLudovic Barre static void ux500_variant_init(struct mmci_host *host);
50b3fb9d64SLudovic Barre static void ux500v2_variant_init(struct mmci_host *host);
51c3647fdcSLudovic Barre 
521c6a0718SPierre Ossman static unsigned int fmax = 515633;
531c6a0718SPierre Ossman 
544956e109SRabin Vincent static struct variant_data variant_arm = {
558301bb68SRabin Vincent 	.fifosize		= 16 * 4,
568301bb68SRabin Vincent 	.fifohalfsize		= 8 * 4,
570f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
580f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
590f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
600f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
6108458ef6SRabin Vincent 	.datalength_bits	= 16,
62c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
637d72a1d4SUlf Hansson 	.pwrreg_powerup		= MCI_PWR_UP,
64dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
657878289bSUlf Hansson 	.reversed_irq_handling	= true,
666ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
6759db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
687f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
6911dfb970SPatrice Chotard 	.opendrain		= MCI_ROD,
70c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
714956e109SRabin Vincent };
724956e109SRabin Vincent 
73768fbc18SPawel Moll static struct variant_data variant_arm_extended_fifo = {
74768fbc18SPawel Moll 	.fifosize		= 128 * 4,
75768fbc18SPawel Moll 	.fifohalfsize		= 64 * 4,
760f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
770f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
780f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
790f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
80768fbc18SPawel Moll 	.datalength_bits	= 16,
81c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
827d72a1d4SUlf Hansson 	.pwrreg_powerup		= MCI_PWR_UP,
83dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
846ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
8559db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
867f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
8711dfb970SPatrice Chotard 	.opendrain		= MCI_ROD,
88c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
89768fbc18SPawel Moll };
90768fbc18SPawel Moll 
913a37298aSPawel Moll static struct variant_data variant_arm_extended_fifo_hwfc = {
923a37298aSPawel Moll 	.fifosize		= 128 * 4,
933a37298aSPawel Moll 	.fifohalfsize		= 64 * 4,
943a37298aSPawel Moll 	.clkreg_enable		= MCI_ARM_HWFCEN,
950f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
960f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
970f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
980f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
993a37298aSPawel Moll 	.datalength_bits	= 16,
100c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
1013a37298aSPawel Moll 	.pwrreg_powerup		= MCI_PWR_UP,
102dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
1036ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
10459db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
1057f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
10611dfb970SPatrice Chotard 	.opendrain		= MCI_ROD,
107c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
1083a37298aSPawel Moll };
1093a37298aSPawel Moll 
1104956e109SRabin Vincent static struct variant_data variant_u300 = {
1118301bb68SRabin Vincent 	.fifosize		= 16 * 4,
1128301bb68SRabin Vincent 	.fifohalfsize		= 8 * 4,
11349ac215eSLinus Walleij 	.clkreg_enable		= MCI_ST_U300_HWFCEN,
114e1412d85SSrinivas Kandagatla 	.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
1150f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
1160f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
1170f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
1180f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
11908458ef6SRabin Vincent 	.datalength_bits	= 16,
120c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
1215db3eee7SLinus Walleij 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
122c7354133SSrinivas Kandagatla 	.st_sdio			= true,
1237d72a1d4SUlf Hansson 	.pwrreg_powerup		= MCI_PWR_ON,
124dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
1254d1a3a0dSUlf Hansson 	.signal_direction	= true,
126f4670daeSUlf Hansson 	.pwrreg_clkgate		= true,
1271ff44433SUlf Hansson 	.pwrreg_nopower		= true,
1286ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
12959db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
1307f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
13111dfb970SPatrice Chotard 	.opendrain		= MCI_OD,
132c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
1334956e109SRabin Vincent };
1344956e109SRabin Vincent 
13534fd4213SLinus Walleij static struct variant_data variant_nomadik = {
13634fd4213SLinus Walleij 	.fifosize		= 16 * 4,
13734fd4213SLinus Walleij 	.fifohalfsize		= 8 * 4,
13834fd4213SLinus Walleij 	.clkreg			= MCI_CLK_ENABLE,
139f5abc767SLinus Walleij 	.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
1400f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
1410f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
1420f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
1430f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
14434fd4213SLinus Walleij 	.datalength_bits	= 24,
145c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
1465db3eee7SLinus Walleij 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
147c7354133SSrinivas Kandagatla 	.st_sdio		= true,
14834fd4213SLinus Walleij 	.st_clkdiv		= true,
14934fd4213SLinus Walleij 	.pwrreg_powerup		= MCI_PWR_ON,
150dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
15134fd4213SLinus Walleij 	.signal_direction	= true,
152f4670daeSUlf Hansson 	.pwrreg_clkgate		= true,
1531ff44433SUlf Hansson 	.pwrreg_nopower		= true,
1546ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
15559db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
1567f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
15711dfb970SPatrice Chotard 	.opendrain		= MCI_OD,
158c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
15934fd4213SLinus Walleij };
16034fd4213SLinus Walleij 
1614956e109SRabin Vincent static struct variant_data variant_ux500 = {
1628301bb68SRabin Vincent 	.fifosize		= 30 * 4,
1638301bb68SRabin Vincent 	.fifohalfsize		= 8 * 4,
1644956e109SRabin Vincent 	.clkreg			= MCI_CLK_ENABLE,
16549ac215eSLinus Walleij 	.clkreg_enable		= MCI_ST_UX500_HWFCEN,
166e1412d85SSrinivas Kandagatla 	.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
167e8740644SSrinivas Kandagatla 	.clkreg_neg_edge_enable	= MCI_ST_UX500_NEG_EDGE,
1680f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
1690f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
1700f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
1710f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
17208458ef6SRabin Vincent 	.datalength_bits	= 24,
173c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
1742253ed4bSLinus Walleij 	.datactrl_any_blocksz	= true,
1752253ed4bSLinus Walleij 	.dma_power_of_2		= true,
1765db3eee7SLinus Walleij 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
177c7354133SSrinivas Kandagatla 	.st_sdio		= true,
178b70a67f9SLinus Walleij 	.st_clkdiv		= true,
1797d72a1d4SUlf Hansson 	.pwrreg_powerup		= MCI_PWR_ON,
180dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
1814d1a3a0dSUlf Hansson 	.signal_direction	= true,
182f4670daeSUlf Hansson 	.pwrreg_clkgate		= true,
18301259620SUlf Hansson 	.busy_detect		= true,
18449adc0caSLinus Walleij 	.busy_dpsm_flag		= MCI_DPSM_ST_BUSYMODE,
18549adc0caSLinus Walleij 	.busy_detect_flag	= MCI_ST_CARDBUSY,
18649adc0caSLinus Walleij 	.busy_detect_mask	= MCI_ST_BUSYENDMASK,
1871ff44433SUlf Hansson 	.pwrreg_nopower		= true,
1886ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
18959db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
1907f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
19111dfb970SPatrice Chotard 	.opendrain		= MCI_OD,
192cb0335b7SLudovic Barre 	.init			= ux500_variant_init,
1934956e109SRabin Vincent };
194b70a67f9SLinus Walleij 
1951784b157SPhilippe Langlais static struct variant_data variant_ux500v2 = {
1961784b157SPhilippe Langlais 	.fifosize		= 30 * 4,
1971784b157SPhilippe Langlais 	.fifohalfsize		= 8 * 4,
1981784b157SPhilippe Langlais 	.clkreg			= MCI_CLK_ENABLE,
1991784b157SPhilippe Langlais 	.clkreg_enable		= MCI_ST_UX500_HWFCEN,
200e1412d85SSrinivas Kandagatla 	.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
201e8740644SSrinivas Kandagatla 	.clkreg_neg_edge_enable	= MCI_ST_UX500_NEG_EDGE,
2020f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
2030f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
2040f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
2050f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
2065db3eee7SLinus Walleij 	.datactrl_mask_ddrmode	= MCI_DPSM_ST_DDRMODE,
2071784b157SPhilippe Langlais 	.datalength_bits	= 24,
208c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
2092253ed4bSLinus Walleij 	.datactrl_any_blocksz	= true,
2102253ed4bSLinus Walleij 	.dma_power_of_2		= true,
2115db3eee7SLinus Walleij 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
212c7354133SSrinivas Kandagatla 	.st_sdio		= true,
2131784b157SPhilippe Langlais 	.st_clkdiv		= true,
2147d72a1d4SUlf Hansson 	.pwrreg_powerup		= MCI_PWR_ON,
215dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
2164d1a3a0dSUlf Hansson 	.signal_direction	= true,
217f4670daeSUlf Hansson 	.pwrreg_clkgate		= true,
21801259620SUlf Hansson 	.busy_detect		= true,
21949adc0caSLinus Walleij 	.busy_dpsm_flag		= MCI_DPSM_ST_BUSYMODE,
22049adc0caSLinus Walleij 	.busy_detect_flag	= MCI_ST_CARDBUSY,
22149adc0caSLinus Walleij 	.busy_detect_mask	= MCI_ST_BUSYENDMASK,
2221ff44433SUlf Hansson 	.pwrreg_nopower		= true,
2236ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
22459db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
2257f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
22611dfb970SPatrice Chotard 	.opendrain		= MCI_OD,
227b3fb9d64SLudovic Barre 	.init			= ux500v2_variant_init,
2281784b157SPhilippe Langlais };
2291784b157SPhilippe Langlais 
2302a9d6c80SPatrice Chotard static struct variant_data variant_stm32 = {
2312a9d6c80SPatrice Chotard 	.fifosize		= 32 * 4,
2322a9d6c80SPatrice Chotard 	.fifohalfsize		= 8 * 4,
2332a9d6c80SPatrice Chotard 	.clkreg			= MCI_CLK_ENABLE,
2342a9d6c80SPatrice Chotard 	.clkreg_enable		= MCI_ST_UX500_HWFCEN,
2352a9d6c80SPatrice Chotard 	.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
2362a9d6c80SPatrice Chotard 	.clkreg_neg_edge_enable	= MCI_ST_UX500_NEG_EDGE,
2370f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
2380f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
2390f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
2400f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
24159db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
2422a9d6c80SPatrice Chotard 	.datalength_bits	= 24,
243c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
2442a9d6c80SPatrice Chotard 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
2452a9d6c80SPatrice Chotard 	.st_sdio		= true,
2462a9d6c80SPatrice Chotard 	.st_clkdiv		= true,
2472a9d6c80SPatrice Chotard 	.pwrreg_powerup		= MCI_PWR_ON,
2482a9d6c80SPatrice Chotard 	.f_max			= 48000000,
2492a9d6c80SPatrice Chotard 	.pwrreg_clkgate		= true,
2502a9d6c80SPatrice Chotard 	.pwrreg_nopower		= true,
251c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
2522a9d6c80SPatrice Chotard };
2532a9d6c80SPatrice Chotard 
25446b723ddSLudovic Barre static struct variant_data variant_stm32_sdmmc = {
25546b723ddSLudovic Barre 	.fifosize		= 16 * 4,
25646b723ddSLudovic Barre 	.fifohalfsize		= 8 * 4,
25746b723ddSLudovic Barre 	.f_max			= 208000000,
25846b723ddSLudovic Barre 	.stm32_clkdiv		= true,
25946b723ddSLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_STM32_ENABLE,
26046b723ddSLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_STM32_LRSP_CRC,
26146b723ddSLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_STM32_SRSP_CRC,
26246b723ddSLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_STM32_SRSP,
263c8073e52SLudovic Barre 	.cmdreg_stop		= MCI_CPSM_STM32_CMDSTOP,
26446b723ddSLudovic Barre 	.data_cmd_enable	= MCI_CPSM_STM32_CMDTRANS,
26546b723ddSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_STM32_MASK,
26646b723ddSLudovic Barre 	.datactrl_first		= true,
26746b723ddSLudovic Barre 	.datacnt_useless	= true,
26846b723ddSLudovic Barre 	.datalength_bits	= 25,
26946b723ddSLudovic Barre 	.datactrl_blocksz	= 14,
2702253ed4bSLinus Walleij 	.datactrl_any_blocksz	= true,
27181a77ee9SLudovic Barre 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
27246b723ddSLudovic Barre 	.stm32_idmabsize_mask	= GENMASK(12, 5),
2730e68de6aSLudovic Barre 	.busy_timeout		= true,
2740e68de6aSLudovic Barre 	.busy_detect		= true,
2750e68de6aSLudovic Barre 	.busy_detect_flag	= MCI_STM32_BUSYD0,
2760e68de6aSLudovic Barre 	.busy_detect_mask	= MCI_STM32_BUSYD0ENDMASK,
27746b723ddSLudovic Barre 	.init			= sdmmc_variant_init,
27846b723ddSLudovic Barre };
27946b723ddSLudovic Barre 
2807a2a98beSLudovic Barre static struct variant_data variant_stm32_sdmmcv2 = {
2817a2a98beSLudovic Barre 	.fifosize		= 16 * 4,
2827a2a98beSLudovic Barre 	.fifohalfsize		= 8 * 4,
2834481ab60SYann Gautier 	.f_max			= 267000000,
2847a2a98beSLudovic Barre 	.stm32_clkdiv		= true,
2857a2a98beSLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_STM32_ENABLE,
2867a2a98beSLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_STM32_LRSP_CRC,
2877a2a98beSLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_STM32_SRSP_CRC,
2887a2a98beSLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_STM32_SRSP,
2897a2a98beSLudovic Barre 	.cmdreg_stop		= MCI_CPSM_STM32_CMDSTOP,
2907a2a98beSLudovic Barre 	.data_cmd_enable	= MCI_CPSM_STM32_CMDTRANS,
2917a2a98beSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_STM32_MASK,
2927a2a98beSLudovic Barre 	.datactrl_first		= true,
2937a2a98beSLudovic Barre 	.datacnt_useless	= true,
2947a2a98beSLudovic Barre 	.datalength_bits	= 25,
2957a2a98beSLudovic Barre 	.datactrl_blocksz	= 14,
2967a2a98beSLudovic Barre 	.datactrl_any_blocksz	= true,
29781a77ee9SLudovic Barre 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
2987a2a98beSLudovic Barre 	.stm32_idmabsize_mask	= GENMASK(16, 5),
2997a2a98beSLudovic Barre 	.dma_lli		= true,
3007a2a98beSLudovic Barre 	.busy_timeout		= true,
3017a2a98beSLudovic Barre 	.busy_detect		= true,
3027a2a98beSLudovic Barre 	.busy_detect_flag	= MCI_STM32_BUSYD0,
3037a2a98beSLudovic Barre 	.busy_detect_mask	= MCI_STM32_BUSYD0ENDMASK,
3047a2a98beSLudovic Barre 	.init			= sdmmc_variant_init,
3057a2a98beSLudovic Barre };
3067a2a98beSLudovic Barre 
30755b604aeSSrinivas Kandagatla static struct variant_data variant_qcom = {
30855b604aeSSrinivas Kandagatla 	.fifosize		= 16 * 4,
30955b604aeSSrinivas Kandagatla 	.fifohalfsize		= 8 * 4,
31055b604aeSSrinivas Kandagatla 	.clkreg			= MCI_CLK_ENABLE,
31155b604aeSSrinivas Kandagatla 	.clkreg_enable		= MCI_QCOM_CLK_FLOWENA |
31255b604aeSSrinivas Kandagatla 				  MCI_QCOM_CLK_SELECT_IN_FBCLK,
31355b604aeSSrinivas Kandagatla 	.clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,
31455b604aeSSrinivas Kandagatla 	.datactrl_mask_ddrmode	= MCI_QCOM_CLK_SELECT_IN_DDR_MODE,
3150f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
3160f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
3170f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
3180f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
3195db3eee7SLinus Walleij 	.data_cmd_enable	= MCI_CPSM_QCOM_DATCMD,
32055b604aeSSrinivas Kandagatla 	.datalength_bits	= 24,
321c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
3222253ed4bSLinus Walleij 	.datactrl_any_blocksz	= true,
32355b604aeSSrinivas Kandagatla 	.pwrreg_powerup		= MCI_PWR_UP,
32455b604aeSSrinivas Kandagatla 	.f_max			= 208000000,
32555b604aeSSrinivas Kandagatla 	.explicit_mclk_control	= true,
32655b604aeSSrinivas Kandagatla 	.qcom_fifo		= true,
3279cb15142SSrinivas Kandagatla 	.qcom_dml		= true,
3286ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
32959db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
3307f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
33111dfb970SPatrice Chotard 	.opendrain		= MCI_ROD,
33229aba07aSUlf Hansson 	.init			= qcom_variant_init,
33355b604aeSSrinivas Kandagatla };
33455b604aeSSrinivas Kandagatla 
33549adc0caSLinus Walleij /* Busy detection for the ST Micro variant */
33601259620SUlf Hansson static int mmci_card_busy(struct mmc_host *mmc)
33701259620SUlf Hansson {
33801259620SUlf Hansson 	struct mmci_host *host = mmc_priv(mmc);
33901259620SUlf Hansson 	unsigned long flags;
34001259620SUlf Hansson 	int busy = 0;
34101259620SUlf Hansson 
34201259620SUlf Hansson 	spin_lock_irqsave(&host->lock, flags);
34349adc0caSLinus Walleij 	if (readl(host->base + MMCISTATUS) & host->variant->busy_detect_flag)
34401259620SUlf Hansson 		busy = 1;
34501259620SUlf Hansson 	spin_unlock_irqrestore(&host->lock, flags);
34601259620SUlf Hansson 
34701259620SUlf Hansson 	return busy;
34801259620SUlf Hansson }
34901259620SUlf Hansson 
350f829c042SUlf Hansson static void mmci_reg_delay(struct mmci_host *host)
351f829c042SUlf Hansson {
352f829c042SUlf Hansson 	/*
353f829c042SUlf Hansson 	 * According to the spec, at least three feedback clock cycles
354f829c042SUlf Hansson 	 * of max 52 MHz must pass between two writes to the MMCICLOCK reg.
355f829c042SUlf Hansson 	 * Three MCLK clock cycles must pass between two MMCIPOWER reg writes.
356f829c042SUlf Hansson 	 * Worst delay time during card init is at 100 kHz => 30 us.
357f829c042SUlf Hansson 	 * Worst delay time when up and running is at 25 MHz => 120 ns.
358f829c042SUlf Hansson 	 */
359f829c042SUlf Hansson 	if (host->cclk < 25000000)
360f829c042SUlf Hansson 		udelay(30);
361f829c042SUlf Hansson 	else
362f829c042SUlf Hansson 		ndelay(120);
363f829c042SUlf Hansson }
364f829c042SUlf Hansson 
365653a761eSUlf Hansson /*
366a6a6464aSLinus Walleij  * This must be called with host->lock held
367a6a6464aSLinus Walleij  */
368cd3ee8c5SLudovic Barre void mmci_write_clkreg(struct mmci_host *host, u32 clk)
3697437cfa5SUlf Hansson {
3707437cfa5SUlf Hansson 	if (host->clk_reg != clk) {
3717437cfa5SUlf Hansson 		host->clk_reg = clk;
3727437cfa5SUlf Hansson 		writel(clk, host->base + MMCICLOCK);
3737437cfa5SUlf Hansson 	}
3747437cfa5SUlf Hansson }
3757437cfa5SUlf Hansson 
3767437cfa5SUlf Hansson /*
3777437cfa5SUlf Hansson  * This must be called with host->lock held
3787437cfa5SUlf Hansson  */
379cd3ee8c5SLudovic Barre void mmci_write_pwrreg(struct mmci_host *host, u32 pwr)
3807437cfa5SUlf Hansson {
3817437cfa5SUlf Hansson 	if (host->pwr_reg != pwr) {
3827437cfa5SUlf Hansson 		host->pwr_reg = pwr;
3837437cfa5SUlf Hansson 		writel(pwr, host->base + MMCIPOWER);
3847437cfa5SUlf Hansson 	}
3857437cfa5SUlf Hansson }
3867437cfa5SUlf Hansson 
3877437cfa5SUlf Hansson /*
3887437cfa5SUlf Hansson  * This must be called with host->lock held
3897437cfa5SUlf Hansson  */
3909cc639a2SUlf Hansson static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl)
3919cc639a2SUlf Hansson {
39249adc0caSLinus Walleij 	/* Keep busy mode in DPSM if enabled */
39349adc0caSLinus Walleij 	datactrl |= host->datactrl_reg & host->variant->busy_dpsm_flag;
39401259620SUlf Hansson 
3959cc639a2SUlf Hansson 	if (host->datactrl_reg != datactrl) {
3969cc639a2SUlf Hansson 		host->datactrl_reg = datactrl;
3979cc639a2SUlf Hansson 		writel(datactrl, host->base + MMCIDATACTRL);
3989cc639a2SUlf Hansson 	}
3999cc639a2SUlf Hansson }
4009cc639a2SUlf Hansson 
4019cc639a2SUlf Hansson /*
4029cc639a2SUlf Hansson  * This must be called with host->lock held
4039cc639a2SUlf Hansson  */
404a6a6464aSLinus Walleij static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
405a6a6464aSLinus Walleij {
4064956e109SRabin Vincent 	struct variant_data *variant = host->variant;
4074956e109SRabin Vincent 	u32 clk = variant->clkreg;
408a6a6464aSLinus Walleij 
409c58a8509SUlf Hansson 	/* Make sure cclk reflects the current calculated clock */
410c58a8509SUlf Hansson 	host->cclk = 0;
411c58a8509SUlf Hansson 
412a6a6464aSLinus Walleij 	if (desired) {
4133f4e6f7bSSrinivas Kandagatla 		if (variant->explicit_mclk_control) {
4143f4e6f7bSSrinivas Kandagatla 			host->cclk = host->mclk;
4153f4e6f7bSSrinivas Kandagatla 		} else if (desired >= host->mclk) {
416a6a6464aSLinus Walleij 			clk = MCI_CLK_BYPASS;
417399bc486SLinus Walleij 			if (variant->st_clkdiv)
418399bc486SLinus Walleij 				clk |= MCI_ST_UX500_NEG_EDGE;
419a6a6464aSLinus Walleij 			host->cclk = host->mclk;
420b70a67f9SLinus Walleij 		} else if (variant->st_clkdiv) {
421b70a67f9SLinus Walleij 			/*
422b70a67f9SLinus Walleij 			 * DB8500 TRM says f = mclk / (clkdiv + 2)
423b70a67f9SLinus Walleij 			 * => clkdiv = (mclk / f) - 2
424b70a67f9SLinus Walleij 			 * Round the divider up so we don't exceed the max
425b70a67f9SLinus Walleij 			 * frequency
426b70a67f9SLinus Walleij 			 */
427b70a67f9SLinus Walleij 			clk = DIV_ROUND_UP(host->mclk, desired) - 2;
428b70a67f9SLinus Walleij 			if (clk >= 256)
429b70a67f9SLinus Walleij 				clk = 255;
430b70a67f9SLinus Walleij 			host->cclk = host->mclk / (clk + 2);
431a6a6464aSLinus Walleij 		} else {
432b70a67f9SLinus Walleij 			/*
433b70a67f9SLinus Walleij 			 * PL180 TRM says f = mclk / (2 * (clkdiv + 1))
434b70a67f9SLinus Walleij 			 * => clkdiv = mclk / (2 * f) - 1
435b70a67f9SLinus Walleij 			 */
436a6a6464aSLinus Walleij 			clk = host->mclk / (2 * desired) - 1;
437a6a6464aSLinus Walleij 			if (clk >= 256)
438a6a6464aSLinus Walleij 				clk = 255;
439a6a6464aSLinus Walleij 			host->cclk = host->mclk / (2 * (clk + 1));
440a6a6464aSLinus Walleij 		}
4414380c14fSRabin Vincent 
4424380c14fSRabin Vincent 		clk |= variant->clkreg_enable;
443a6a6464aSLinus Walleij 		clk |= MCI_CLK_ENABLE;
444a6a6464aSLinus Walleij 		/* This hasn't proven to be worthwhile */
445a6a6464aSLinus Walleij 		/* clk |= MCI_CLK_PWRSAVE; */
446a6a6464aSLinus Walleij 	}
447a6a6464aSLinus Walleij 
448c58a8509SUlf Hansson 	/* Set actual clock for debug */
449c58a8509SUlf Hansson 	host->mmc->actual_clock = host->cclk;
450c58a8509SUlf Hansson 
4519e6c82cdSLinus Walleij 	if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
452771dc157SLinus Walleij 		clk |= MCI_4BIT_BUS;
453771dc157SLinus Walleij 	if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
454e1412d85SSrinivas Kandagatla 		clk |= variant->clkreg_8bit_bus_enable;
4559e6c82cdSLinus Walleij 
4566dad6c95SSeungwon Jeon 	if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 ||
4576dad6c95SSeungwon Jeon 	    host->mmc->ios.timing == MMC_TIMING_MMC_DDR52)
458e8740644SSrinivas Kandagatla 		clk |= variant->clkreg_neg_edge_enable;
4596dbb6ee0SUlf Hansson 
4607437cfa5SUlf Hansson 	mmci_write_clkreg(host, clk);
461a6a6464aSLinus Walleij }
462a6a6464aSLinus Walleij 
463e2b98d83SBen Dooks static void mmci_dma_release(struct mmci_host *host)
464c3647fdcSLudovic Barre {
465c3647fdcSLudovic Barre 	if (host->ops && host->ops->dma_release)
466c3647fdcSLudovic Barre 		host->ops->dma_release(host);
467c3647fdcSLudovic Barre 
468c3647fdcSLudovic Barre 	host->use_dma = false;
469c3647fdcSLudovic Barre }
470c3647fdcSLudovic Barre 
471e2b98d83SBen Dooks static void mmci_dma_setup(struct mmci_host *host)
472c3647fdcSLudovic Barre {
473c3647fdcSLudovic Barre 	if (!host->ops || !host->ops->dma_setup)
474c3647fdcSLudovic Barre 		return;
475c3647fdcSLudovic Barre 
476c3647fdcSLudovic Barre 	if (host->ops->dma_setup(host))
477c3647fdcSLudovic Barre 		return;
478c3647fdcSLudovic Barre 
479a813f2a2SLudovic Barre 	/* initialize pre request cookie */
480a813f2a2SLudovic Barre 	host->next_cookie = 1;
481a813f2a2SLudovic Barre 
482c3647fdcSLudovic Barre 	host->use_dma = true;
483c3647fdcSLudovic Barre }
484c3647fdcSLudovic Barre 
485e0da1721SLudovic Barre /*
486e0da1721SLudovic Barre  * Validate mmc prerequisites
487e0da1721SLudovic Barre  */
488e0da1721SLudovic Barre static int mmci_validate_data(struct mmci_host *host,
489e0da1721SLudovic Barre 			      struct mmc_data *data)
490e0da1721SLudovic Barre {
4912253ed4bSLinus Walleij 	struct variant_data *variant = host->variant;
4922253ed4bSLinus Walleij 
493e0da1721SLudovic Barre 	if (!data)
494e0da1721SLudovic Barre 		return 0;
4952253ed4bSLinus Walleij 	if (!is_power_of_2(data->blksz) && !variant->datactrl_any_blocksz) {
496e0da1721SLudovic Barre 		dev_err(mmc_dev(host->mmc),
497e0da1721SLudovic Barre 			"unsupported block size (%d bytes)\n", data->blksz);
498e0da1721SLudovic Barre 		return -EINVAL;
499e0da1721SLudovic Barre 	}
500e0da1721SLudovic Barre 
501e0da1721SLudovic Barre 	if (host->ops && host->ops->validate_data)
502e0da1721SLudovic Barre 		return host->ops->validate_data(host, data);
503e0da1721SLudovic Barre 
504e0da1721SLudovic Barre 	return 0;
505e0da1721SLudovic Barre }
506e0da1721SLudovic Barre 
507e2b98d83SBen Dooks static int mmci_prep_data(struct mmci_host *host, struct mmc_data *data, bool next)
50847983510SLudovic Barre {
50947983510SLudovic Barre 	int err;
51047983510SLudovic Barre 
51147983510SLudovic Barre 	if (!host->ops || !host->ops->prep_data)
51247983510SLudovic Barre 		return 0;
51347983510SLudovic Barre 
51447983510SLudovic Barre 	err = host->ops->prep_data(host, data, next);
51547983510SLudovic Barre 
51647983510SLudovic Barre 	if (next && !err)
51747983510SLudovic Barre 		data->host_cookie = ++host->next_cookie < 0 ?
51847983510SLudovic Barre 			1 : host->next_cookie;
51947983510SLudovic Barre 
52047983510SLudovic Barre 	return err;
52147983510SLudovic Barre }
52247983510SLudovic Barre 
523e2b98d83SBen Dooks static void mmci_unprep_data(struct mmci_host *host, struct mmc_data *data,
52447983510SLudovic Barre 		      int err)
52547983510SLudovic Barre {
52647983510SLudovic Barre 	if (host->ops && host->ops->unprep_data)
52747983510SLudovic Barre 		host->ops->unprep_data(host, data, err);
52847983510SLudovic Barre 
52947983510SLudovic Barre 	data->host_cookie = 0;
53047983510SLudovic Barre }
53147983510SLudovic Barre 
532e2b98d83SBen Dooks static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data)
53302769968SLudovic Barre {
53402769968SLudovic Barre 	WARN_ON(data->host_cookie && data->host_cookie != host->next_cookie);
53502769968SLudovic Barre 
53602769968SLudovic Barre 	if (host->ops && host->ops->get_next_data)
53702769968SLudovic Barre 		host->ops->get_next_data(host, data);
53802769968SLudovic Barre }
53902769968SLudovic Barre 
540e2b98d83SBen Dooks static int mmci_dma_start(struct mmci_host *host, unsigned int datactrl)
541135ea30eSLudovic Barre {
542135ea30eSLudovic Barre 	struct mmc_data *data = host->data;
543135ea30eSLudovic Barre 	int ret;
544135ea30eSLudovic Barre 
545135ea30eSLudovic Barre 	if (!host->use_dma)
546135ea30eSLudovic Barre 		return -EINVAL;
547135ea30eSLudovic Barre 
548135ea30eSLudovic Barre 	ret = mmci_prep_data(host, data, false);
549135ea30eSLudovic Barre 	if (ret)
550135ea30eSLudovic Barre 		return ret;
551135ea30eSLudovic Barre 
552135ea30eSLudovic Barre 	if (!host->ops || !host->ops->dma_start)
553135ea30eSLudovic Barre 		return -EINVAL;
554135ea30eSLudovic Barre 
555135ea30eSLudovic Barre 	/* Okay, go for it. */
556135ea30eSLudovic Barre 	dev_vdbg(mmc_dev(host->mmc),
557135ea30eSLudovic Barre 		 "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n",
558135ea30eSLudovic Barre 		 data->sg_len, data->blksz, data->blocks, data->flags);
559135ea30eSLudovic Barre 
5602253ed4bSLinus Walleij 	ret = host->ops->dma_start(host, &datactrl);
5612253ed4bSLinus Walleij 	if (ret)
5622253ed4bSLinus Walleij 		return ret;
563135ea30eSLudovic Barre 
564135ea30eSLudovic Barre 	/* Trigger the DMA transfer */
565135ea30eSLudovic Barre 	mmci_write_datactrlreg(host, datactrl);
566135ea30eSLudovic Barre 
567135ea30eSLudovic Barre 	/*
568135ea30eSLudovic Barre 	 * Let the MMCI say when the data is ended and it's time
569135ea30eSLudovic Barre 	 * to fire next DMA request. When that happens, MMCI will
570135ea30eSLudovic Barre 	 * call mmci_data_end()
571135ea30eSLudovic Barre 	 */
572135ea30eSLudovic Barre 	writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK,
573135ea30eSLudovic Barre 	       host->base + MMCIMASK0);
574135ea30eSLudovic Barre 	return 0;
575135ea30eSLudovic Barre }
576135ea30eSLudovic Barre 
577e2b98d83SBen Dooks static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data)
5785a9f10c3SLudovic Barre {
5795a9f10c3SLudovic Barre 	if (!host->use_dma)
5805a9f10c3SLudovic Barre 		return;
5815a9f10c3SLudovic Barre 
5825a9f10c3SLudovic Barre 	if (host->ops && host->ops->dma_finalize)
5835a9f10c3SLudovic Barre 		host->ops->dma_finalize(host, data);
5845a9f10c3SLudovic Barre }
5855a9f10c3SLudovic Barre 
586e2b98d83SBen Dooks static void mmci_dma_error(struct mmci_host *host)
587cfccc6acSLudovic Barre {
588cfccc6acSLudovic Barre 	if (!host->use_dma)
589cfccc6acSLudovic Barre 		return;
590cfccc6acSLudovic Barre 
591cfccc6acSLudovic Barre 	if (host->ops && host->ops->dma_error)
592cfccc6acSLudovic Barre 		host->ops->dma_error(host);
593cfccc6acSLudovic Barre }
594cfccc6acSLudovic Barre 
5951c6a0718SPierre Ossman static void
5961c6a0718SPierre Ossman mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
5971c6a0718SPierre Ossman {
5981c6a0718SPierre Ossman 	writel(0, host->base + MMCICOMMAND);
5991c6a0718SPierre Ossman 
6001c6a0718SPierre Ossman 	BUG_ON(host->data);
6011c6a0718SPierre Ossman 
6021c6a0718SPierre Ossman 	host->mrq = NULL;
6031c6a0718SPierre Ossman 	host->cmd = NULL;
6041c6a0718SPierre Ossman 
6051c6a0718SPierre Ossman 	mmc_request_done(host->mmc, mrq);
6061c6a0718SPierre Ossman }
6071c6a0718SPierre Ossman 
6082686b4b4SLinus Walleij static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
6092686b4b4SLinus Walleij {
6102686b4b4SLinus Walleij 	void __iomem *base = host->base;
6116ea9cdf3SPatrice Chotard 	struct variant_data *variant = host->variant;
6122686b4b4SLinus Walleij 
6132686b4b4SLinus Walleij 	if (host->singleirq) {
6142686b4b4SLinus Walleij 		unsigned int mask0 = readl(base + MMCIMASK0);
6152686b4b4SLinus Walleij 
61659db5e2dSLudovic Barre 		mask0 &= ~variant->irq_pio_mask;
6172686b4b4SLinus Walleij 		mask0 |= mask;
6182686b4b4SLinus Walleij 
6192686b4b4SLinus Walleij 		writel(mask0, base + MMCIMASK0);
6202686b4b4SLinus Walleij 	}
6212686b4b4SLinus Walleij 
6226ea9cdf3SPatrice Chotard 	if (variant->mmcimask1)
6232686b4b4SLinus Walleij 		writel(mask, base + MMCIMASK1);
6246ea9cdf3SPatrice Chotard 
6256ea9cdf3SPatrice Chotard 	host->mask1_reg = mask;
6262686b4b4SLinus Walleij }
6272686b4b4SLinus Walleij 
6281c6a0718SPierre Ossman static void mmci_stop_data(struct mmci_host *host)
6291c6a0718SPierre Ossman {
6309cc639a2SUlf Hansson 	mmci_write_datactrlreg(host, 0);
6312686b4b4SLinus Walleij 	mmci_set_mask1(host, 0);
6321c6a0718SPierre Ossman 	host->data = NULL;
6331c6a0718SPierre Ossman }
6341c6a0718SPierre Ossman 
6354ce1d6cbSRabin Vincent static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
6364ce1d6cbSRabin Vincent {
6374ce1d6cbSRabin Vincent 	unsigned int flags = SG_MITER_ATOMIC;
6384ce1d6cbSRabin Vincent 
6394ce1d6cbSRabin Vincent 	if (data->flags & MMC_DATA_READ)
6404ce1d6cbSRabin Vincent 		flags |= SG_MITER_TO_SG;
6414ce1d6cbSRabin Vincent 	else
6424ce1d6cbSRabin Vincent 		flags |= SG_MITER_FROM_SG;
6434ce1d6cbSRabin Vincent 
6444ce1d6cbSRabin Vincent 	sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
6454ce1d6cbSRabin Vincent }
6464ce1d6cbSRabin Vincent 
647b3fb9d64SLudovic Barre static u32 mmci_get_dctrl_cfg(struct mmci_host *host)
648b3fb9d64SLudovic Barre {
649b3fb9d64SLudovic Barre 	return MCI_DPSM_ENABLE | mmci_dctrl_blksz(host);
650b3fb9d64SLudovic Barre }
651b3fb9d64SLudovic Barre 
652b3fb9d64SLudovic Barre static u32 ux500v2_get_dctrl_cfg(struct mmci_host *host)
653b3fb9d64SLudovic Barre {
654b3fb9d64SLudovic Barre 	return MCI_DPSM_ENABLE | (host->data->blksz << 16);
655b3fb9d64SLudovic Barre }
656b3fb9d64SLudovic Barre 
657cb0335b7SLudovic Barre static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk)
658cb0335b7SLudovic Barre {
659cb0335b7SLudovic Barre 	void __iomem *base = host->base;
660cb0335b7SLudovic Barre 
661cb0335b7SLudovic Barre 	/*
662cb0335b7SLudovic Barre 	 * Before unmasking for the busy end IRQ, confirm that the
663cb0335b7SLudovic Barre 	 * command was sent successfully. To keep track of having a
664cb0335b7SLudovic Barre 	 * command in-progress, waiting for busy signaling to end,
665cb0335b7SLudovic Barre 	 * store the status in host->busy_status.
666cb0335b7SLudovic Barre 	 *
667cb0335b7SLudovic Barre 	 * Note that, the card may need a couple of clock cycles before
668cb0335b7SLudovic Barre 	 * it starts signaling busy on DAT0, hence re-read the
669cb0335b7SLudovic Barre 	 * MMCISTATUS register here, to allow the busy bit to be set.
670cb0335b7SLudovic Barre 	 * Potentially we may even need to poll the register for a
671cb0335b7SLudovic Barre 	 * while, to allow it to be set, but tests indicates that it
672cb0335b7SLudovic Barre 	 * isn't needed.
673cb0335b7SLudovic Barre 	 */
674cb0335b7SLudovic Barre 	if (!host->busy_status && !(status & err_msk) &&
675cb0335b7SLudovic Barre 	    (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) {
676cb0335b7SLudovic Barre 		writel(readl(base + MMCIMASK0) |
677cb0335b7SLudovic Barre 		       host->variant->busy_detect_mask,
678cb0335b7SLudovic Barre 		       base + MMCIMASK0);
679cb0335b7SLudovic Barre 
680cb0335b7SLudovic Barre 		host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND);
681cb0335b7SLudovic Barre 		return false;
682cb0335b7SLudovic Barre 	}
683cb0335b7SLudovic Barre 
684cb0335b7SLudovic Barre 	/*
685cb0335b7SLudovic Barre 	 * If there is a command in-progress that has been successfully
686cb0335b7SLudovic Barre 	 * sent, then bail out if busy status is set and wait for the
687cb0335b7SLudovic Barre 	 * busy end IRQ.
688cb0335b7SLudovic Barre 	 *
689cb0335b7SLudovic Barre 	 * Note that, the HW triggers an IRQ on both edges while
690cb0335b7SLudovic Barre 	 * monitoring DAT0 for busy completion, but there is only one
691cb0335b7SLudovic Barre 	 * status bit in MMCISTATUS for the busy state. Therefore
692cb0335b7SLudovic Barre 	 * both the start and the end interrupts needs to be cleared,
693cb0335b7SLudovic Barre 	 * one after the other. So, clear the busy start IRQ here.
694cb0335b7SLudovic Barre 	 */
695cb0335b7SLudovic Barre 	if (host->busy_status &&
696cb0335b7SLudovic Barre 	    (status & host->variant->busy_detect_flag)) {
697cb0335b7SLudovic Barre 		writel(host->variant->busy_detect_mask, base + MMCICLEAR);
698cb0335b7SLudovic Barre 		return false;
699cb0335b7SLudovic Barre 	}
700cb0335b7SLudovic Barre 
701cb0335b7SLudovic Barre 	/*
702cb0335b7SLudovic Barre 	 * If there is a command in-progress that has been successfully
703cb0335b7SLudovic Barre 	 * sent and the busy bit isn't set, it means we have received
704cb0335b7SLudovic Barre 	 * the busy end IRQ. Clear and mask the IRQ, then continue to
705cb0335b7SLudovic Barre 	 * process the command.
706cb0335b7SLudovic Barre 	 */
707cb0335b7SLudovic Barre 	if (host->busy_status) {
708cb0335b7SLudovic Barre 		writel(host->variant->busy_detect_mask, base + MMCICLEAR);
709cb0335b7SLudovic Barre 
710cb0335b7SLudovic Barre 		writel(readl(base + MMCIMASK0) &
711cb0335b7SLudovic Barre 		       ~host->variant->busy_detect_mask, base + MMCIMASK0);
712cb0335b7SLudovic Barre 		host->busy_status = 0;
713cb0335b7SLudovic Barre 	}
714cb0335b7SLudovic Barre 
715cb0335b7SLudovic Barre 	return true;
716cb0335b7SLudovic Barre }
717cb0335b7SLudovic Barre 
718c8ebae37SRussell King /*
719c8ebae37SRussell King  * All the DMA operation mode stuff goes inside this ifdef.
720c8ebae37SRussell King  * This assumes that you have a generic DMA device interface,
721c8ebae37SRussell King  * no custom DMA interfaces are supported.
722c8ebae37SRussell King  */
723c8ebae37SRussell King #ifdef CONFIG_DMA_ENGINE
724a813f2a2SLudovic Barre struct mmci_dmae_next {
725a813f2a2SLudovic Barre 	struct dma_async_tx_descriptor *desc;
726a813f2a2SLudovic Barre 	struct dma_chan	*chan;
727a813f2a2SLudovic Barre };
728a813f2a2SLudovic Barre 
729a813f2a2SLudovic Barre struct mmci_dmae_priv {
730a813f2a2SLudovic Barre 	struct dma_chan	*cur;
731a813f2a2SLudovic Barre 	struct dma_chan	*rx_channel;
732a813f2a2SLudovic Barre 	struct dma_chan	*tx_channel;
733a813f2a2SLudovic Barre 	struct dma_async_tx_descriptor	*desc_current;
734a813f2a2SLudovic Barre 	struct mmci_dmae_next next_data;
735a813f2a2SLudovic Barre };
736a813f2a2SLudovic Barre 
737c3647fdcSLudovic Barre int mmci_dmae_setup(struct mmci_host *host)
738c8ebae37SRussell King {
739c8ebae37SRussell King 	const char *rxname, *txname;
740a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae;
741c8ebae37SRussell King 
742a813f2a2SLudovic Barre 	dmae = devm_kzalloc(mmc_dev(host->mmc), sizeof(*dmae), GFP_KERNEL);
743a813f2a2SLudovic Barre 	if (!dmae)
744a813f2a2SLudovic Barre 		return -ENOMEM;
745c8ebae37SRussell King 
746a813f2a2SLudovic Barre 	host->dma_priv = dmae;
747a813f2a2SLudovic Barre 
748716d0205SPeter Ujfalusi 	dmae->rx_channel = dma_request_chan(mmc_dev(host->mmc), "rx");
749716d0205SPeter Ujfalusi 	if (IS_ERR(dmae->rx_channel)) {
750716d0205SPeter Ujfalusi 		int ret = PTR_ERR(dmae->rx_channel);
751716d0205SPeter Ujfalusi 		dmae->rx_channel = NULL;
752716d0205SPeter Ujfalusi 		return ret;
753716d0205SPeter Ujfalusi 	}
754716d0205SPeter Ujfalusi 
755716d0205SPeter Ujfalusi 	dmae->tx_channel = dma_request_chan(mmc_dev(host->mmc), "tx");
756716d0205SPeter Ujfalusi 	if (IS_ERR(dmae->tx_channel)) {
757716d0205SPeter Ujfalusi 		if (PTR_ERR(dmae->tx_channel) == -EPROBE_DEFER)
758716d0205SPeter Ujfalusi 			dev_warn(mmc_dev(host->mmc),
759716d0205SPeter Ujfalusi 				 "Deferred probe for TX channel ignored\n");
760716d0205SPeter Ujfalusi 		dmae->tx_channel = NULL;
761716d0205SPeter Ujfalusi 	}
76258c7ccbfSPer Forlin 
7631fd83f0eSLee Jones 	/*
7641fd83f0eSLee Jones 	 * If only an RX channel is specified, the driver will
765f78bc9f2SXiang wangx 	 * attempt to use it bidirectionally, however if it
7661fd83f0eSLee Jones 	 * is specified but cannot be located, DMA will be disabled.
7671fd83f0eSLee Jones 	 */
768a813f2a2SLudovic Barre 	if (dmae->rx_channel && !dmae->tx_channel)
769a813f2a2SLudovic Barre 		dmae->tx_channel = dmae->rx_channel;
770c8ebae37SRussell King 
771a813f2a2SLudovic Barre 	if (dmae->rx_channel)
772a813f2a2SLudovic Barre 		rxname = dma_chan_name(dmae->rx_channel);
773c8ebae37SRussell King 	else
774c8ebae37SRussell King 		rxname = "none";
775c8ebae37SRussell King 
776a813f2a2SLudovic Barre 	if (dmae->tx_channel)
777a813f2a2SLudovic Barre 		txname = dma_chan_name(dmae->tx_channel);
778c8ebae37SRussell King 	else
779c8ebae37SRussell King 		txname = "none";
780c8ebae37SRussell King 
781c8ebae37SRussell King 	dev_info(mmc_dev(host->mmc), "DMA channels RX %s, TX %s\n",
782c8ebae37SRussell King 		 rxname, txname);
783c8ebae37SRussell King 
784c8ebae37SRussell King 	/*
785c8ebae37SRussell King 	 * Limit the maximum segment size in any SG entry according to
786c8ebae37SRussell King 	 * the parameters of the DMA engine device.
787c8ebae37SRussell King 	 */
788a813f2a2SLudovic Barre 	if (dmae->tx_channel) {
789a813f2a2SLudovic Barre 		struct device *dev = dmae->tx_channel->device->dev;
790c8ebae37SRussell King 		unsigned int max_seg_size = dma_get_max_seg_size(dev);
791c8ebae37SRussell King 
792c8ebae37SRussell King 		if (max_seg_size < host->mmc->max_seg_size)
793c8ebae37SRussell King 			host->mmc->max_seg_size = max_seg_size;
794c8ebae37SRussell King 	}
795a813f2a2SLudovic Barre 	if (dmae->rx_channel) {
796a813f2a2SLudovic Barre 		struct device *dev = dmae->rx_channel->device->dev;
797c8ebae37SRussell King 		unsigned int max_seg_size = dma_get_max_seg_size(dev);
798c8ebae37SRussell King 
799c8ebae37SRussell King 		if (max_seg_size < host->mmc->max_seg_size)
800c8ebae37SRussell King 			host->mmc->max_seg_size = max_seg_size;
801c8ebae37SRussell King 	}
8029cb15142SSrinivas Kandagatla 
803a813f2a2SLudovic Barre 	if (!dmae->tx_channel || !dmae->rx_channel) {
804c3647fdcSLudovic Barre 		mmci_dmae_release(host);
805c3647fdcSLudovic Barre 		return -EINVAL;
806c3647fdcSLudovic Barre 	}
807c3647fdcSLudovic Barre 
808c3647fdcSLudovic Barre 	return 0;
809c8ebae37SRussell King }
810c8ebae37SRussell King 
811c8ebae37SRussell King /*
8126e0ee714SBill Pemberton  * This is used in or so inline it
813c8ebae37SRussell King  * so it can be discarded.
814c8ebae37SRussell King  */
815c3647fdcSLudovic Barre void mmci_dmae_release(struct mmci_host *host)
816c8ebae37SRussell King {
817a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
818a813f2a2SLudovic Barre 
819a813f2a2SLudovic Barre 	if (dmae->rx_channel)
820a813f2a2SLudovic Barre 		dma_release_channel(dmae->rx_channel);
821a813f2a2SLudovic Barre 	if (dmae->tx_channel)
822a813f2a2SLudovic Barre 		dma_release_channel(dmae->tx_channel);
823a813f2a2SLudovic Barre 	dmae->rx_channel = dmae->tx_channel = NULL;
824c8ebae37SRussell King }
825c8ebae37SRussell King 
826c8ebae37SRussell King static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data)
827c8ebae37SRussell King {
828a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
829653a761eSUlf Hansson 	struct dma_chan *chan;
830653a761eSUlf Hansson 
831feeef096SHeiner Kallweit 	if (data->flags & MMC_DATA_READ)
832a813f2a2SLudovic Barre 		chan = dmae->rx_channel;
833feeef096SHeiner Kallweit 	else
834a813f2a2SLudovic Barre 		chan = dmae->tx_channel;
835653a761eSUlf Hansson 
836feeef096SHeiner Kallweit 	dma_unmap_sg(chan->device->dev, data->sg, data->sg_len,
837feeef096SHeiner Kallweit 		     mmc_get_dma_dir(data));
838653a761eSUlf Hansson }
839653a761eSUlf Hansson 
840cfccc6acSLudovic Barre void mmci_dmae_error(struct mmci_host *host)
8417b2a6d51SLudovic Barre {
842a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
843a813f2a2SLudovic Barre 
844cfccc6acSLudovic Barre 	if (!dma_inprogress(host))
845cdea1947SLudovic Barre 		return;
846cdea1947SLudovic Barre 
8477b2a6d51SLudovic Barre 	dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n");
848a813f2a2SLudovic Barre 	dmaengine_terminate_all(dmae->cur);
8497b2a6d51SLudovic Barre 	host->dma_in_progress = false;
850a813f2a2SLudovic Barre 	dmae->cur = NULL;
851a813f2a2SLudovic Barre 	dmae->desc_current = NULL;
8527b2a6d51SLudovic Barre 	host->data->host_cookie = 0;
8537b2a6d51SLudovic Barre 
8547b2a6d51SLudovic Barre 	mmci_dma_unmap(host, host->data);
8557b2a6d51SLudovic Barre }
8567b2a6d51SLudovic Barre 
8575a9f10c3SLudovic Barre void mmci_dmae_finalize(struct mmci_host *host, struct mmc_data *data)
858653a761eSUlf Hansson {
859a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
860c8ebae37SRussell King 	u32 status;
861c8ebae37SRussell King 	int i;
862c8ebae37SRussell King 
8635a9f10c3SLudovic Barre 	if (!dma_inprogress(host))
864cdea1947SLudovic Barre 		return;
865cdea1947SLudovic Barre 
866c8ebae37SRussell King 	/* Wait up to 1ms for the DMA to complete */
867c8ebae37SRussell King 	for (i = 0; ; i++) {
868c8ebae37SRussell King 		status = readl(host->base + MMCISTATUS);
869c8ebae37SRussell King 		if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100)
870c8ebae37SRussell King 			break;
871c8ebae37SRussell King 		udelay(10);
872c8ebae37SRussell King 	}
873c8ebae37SRussell King 
874c8ebae37SRussell King 	/*
875c8ebae37SRussell King 	 * Check to see whether we still have some data left in the FIFO -
876c8ebae37SRussell King 	 * this catches DMA controllers which are unable to monitor the
877c8ebae37SRussell King 	 * DMALBREQ and DMALSREQ signals while allowing us to DMA to non-
878c8ebae37SRussell King 	 * contiguous buffers.  On TX, we'll get a FIFO underrun error.
879c8ebae37SRussell King 	 */
880c8ebae37SRussell King 	if (status & MCI_RXDATAAVLBLMASK) {
881cfccc6acSLudovic Barre 		mmci_dma_error(host);
882c8ebae37SRussell King 		if (!data->error)
883c8ebae37SRussell King 			data->error = -EIO;
8847b2a6d51SLudovic Barre 	} else if (!data->host_cookie) {
885653a761eSUlf Hansson 		mmci_dma_unmap(host, data);
8867b2a6d51SLudovic Barre 	}
887c8ebae37SRussell King 
888c8ebae37SRussell King 	/*
889c8ebae37SRussell King 	 * Use of DMA with scatter-gather is impossible.
890c8ebae37SRussell King 	 * Give up with DMA and switch back to PIO mode.
891c8ebae37SRussell King 	 */
892c8ebae37SRussell King 	if (status & MCI_RXDATAAVLBLMASK) {
893c8ebae37SRussell King 		dev_err(mmc_dev(host->mmc), "buggy DMA detected. Taking evasive action.\n");
894c8ebae37SRussell King 		mmci_dma_release(host);
895c8ebae37SRussell King 	}
896653a761eSUlf Hansson 
897e13934bdSLinus Walleij 	host->dma_in_progress = false;
898a813f2a2SLudovic Barre 	dmae->cur = NULL;
899a813f2a2SLudovic Barre 	dmae->desc_current = NULL;
900c8ebae37SRussell King }
901c8ebae37SRussell King 
902653a761eSUlf Hansson /* prepares DMA channel and DMA descriptor, returns non-zero on failure */
90347983510SLudovic Barre static int _mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data,
904653a761eSUlf Hansson 				struct dma_chan **dma_chan,
905653a761eSUlf Hansson 				struct dma_async_tx_descriptor **dma_desc)
906c8ebae37SRussell King {
907a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
908c8ebae37SRussell King 	struct variant_data *variant = host->variant;
909c8ebae37SRussell King 	struct dma_slave_config conf = {
910c8ebae37SRussell King 		.src_addr = host->phybase + MMCIFIFO,
911c8ebae37SRussell King 		.dst_addr = host->phybase + MMCIFIFO,
912c8ebae37SRussell King 		.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
913c8ebae37SRussell King 		.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
914c8ebae37SRussell King 		.src_maxburst = variant->fifohalfsize >> 2, /* # of words */
915c8ebae37SRussell King 		.dst_maxburst = variant->fifohalfsize >> 2, /* # of words */
916258aea76SViresh Kumar 		.device_fc = false,
917c8ebae37SRussell King 	};
918c8ebae37SRussell King 	struct dma_chan *chan;
919c8ebae37SRussell King 	struct dma_device *device;
920c8ebae37SRussell King 	struct dma_async_tx_descriptor *desc;
921c8ebae37SRussell King 	int nr_sg;
9229cb15142SSrinivas Kandagatla 	unsigned long flags = DMA_CTRL_ACK;
923c8ebae37SRussell King 
924c8ebae37SRussell King 	if (data->flags & MMC_DATA_READ) {
92505f5799cSVinod Koul 		conf.direction = DMA_DEV_TO_MEM;
926a813f2a2SLudovic Barre 		chan = dmae->rx_channel;
927c8ebae37SRussell King 	} else {
92805f5799cSVinod Koul 		conf.direction = DMA_MEM_TO_DEV;
929a813f2a2SLudovic Barre 		chan = dmae->tx_channel;
930c8ebae37SRussell King 	}
931c8ebae37SRussell King 
932c8ebae37SRussell King 	/* If there's no DMA channel, fall back to PIO */
933c8ebae37SRussell King 	if (!chan)
934c8ebae37SRussell King 		return -EINVAL;
935c8ebae37SRussell King 
936c8ebae37SRussell King 	/* If less than or equal to the fifo size, don't bother with DMA */
93758c7ccbfSPer Forlin 	if (data->blksz * data->blocks <= variant->fifosize)
938c8ebae37SRussell King 		return -EINVAL;
939c8ebae37SRussell King 
9402253ed4bSLinus Walleij 	/*
9412253ed4bSLinus Walleij 	 * This is necessary to get SDIO working on the Ux500. We do not yet
9422253ed4bSLinus Walleij 	 * know if this is a bug in:
9432253ed4bSLinus Walleij 	 * - The Ux500 DMA controller (DMA40)
9442253ed4bSLinus Walleij 	 * - The MMCI DMA interface on the Ux500
9452253ed4bSLinus Walleij 	 * some power of two blocks (such as 64 bytes) are sent regularly
9462253ed4bSLinus Walleij 	 * during SDIO traffic and those work fine so for these we enable DMA
9472253ed4bSLinus Walleij 	 * transfers.
9482253ed4bSLinus Walleij 	 */
9492253ed4bSLinus Walleij 	if (host->variant->dma_power_of_2 && !is_power_of_2(data->blksz))
9502253ed4bSLinus Walleij 		return -EINVAL;
9512253ed4bSLinus Walleij 
952c8ebae37SRussell King 	device = chan->device;
953feeef096SHeiner Kallweit 	nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len,
954feeef096SHeiner Kallweit 			   mmc_get_dma_dir(data));
955c8ebae37SRussell King 	if (nr_sg == 0)
956c8ebae37SRussell King 		return -EINVAL;
957c8ebae37SRussell King 
9589cb15142SSrinivas Kandagatla 	if (host->variant->qcom_dml)
9599cb15142SSrinivas Kandagatla 		flags |= DMA_PREP_INTERRUPT;
9609cb15142SSrinivas Kandagatla 
961c8ebae37SRussell King 	dmaengine_slave_config(chan, &conf);
96216052827SAlexandre Bounine 	desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg,
9639cb15142SSrinivas Kandagatla 					    conf.direction, flags);
964c8ebae37SRussell King 	if (!desc)
965c8ebae37SRussell King 		goto unmap_exit;
966c8ebae37SRussell King 
967653a761eSUlf Hansson 	*dma_chan = chan;
968653a761eSUlf Hansson 	*dma_desc = desc;
969c8ebae37SRussell King 
97058c7ccbfSPer Forlin 	return 0;
97158c7ccbfSPer Forlin 
97258c7ccbfSPer Forlin  unmap_exit:
973feeef096SHeiner Kallweit 	dma_unmap_sg(device->dev, data->sg, data->sg_len,
974feeef096SHeiner Kallweit 		     mmc_get_dma_dir(data));
97558c7ccbfSPer Forlin 	return -ENOMEM;
97658c7ccbfSPer Forlin }
97758c7ccbfSPer Forlin 
97847983510SLudovic Barre int mmci_dmae_prep_data(struct mmci_host *host,
979ad7b8918SLudovic Barre 			struct mmc_data *data,
980ad7b8918SLudovic Barre 			bool next)
981653a761eSUlf Hansson {
982a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
983ad7b8918SLudovic Barre 	struct mmci_dmae_next *nd = &dmae->next_data;
984a813f2a2SLudovic Barre 
98547983510SLudovic Barre 	if (!host->use_dma)
98647983510SLudovic Barre 		return -EINVAL;
98747983510SLudovic Barre 
988ad7b8918SLudovic Barre 	if (next)
98947983510SLudovic Barre 		return _mmci_dmae_prep_data(host, data, &nd->chan, &nd->desc);
990653a761eSUlf Hansson 	/* Check if next job is already prepared. */
991a813f2a2SLudovic Barre 	if (dmae->cur && dmae->desc_current)
992653a761eSUlf Hansson 		return 0;
993653a761eSUlf Hansson 
994653a761eSUlf Hansson 	/* No job were prepared thus do it now. */
99547983510SLudovic Barre 	return _mmci_dmae_prep_data(host, data, &dmae->cur,
996a813f2a2SLudovic Barre 				    &dmae->desc_current);
997653a761eSUlf Hansson }
998653a761eSUlf Hansson 
999135ea30eSLudovic Barre int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl)
100058c7ccbfSPer Forlin {
1001a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
10022253ed4bSLinus Walleij 	int ret;
100358c7ccbfSPer Forlin 
1004e13934bdSLinus Walleij 	host->dma_in_progress = true;
10052253ed4bSLinus Walleij 	ret = dma_submit_error(dmaengine_submit(dmae->desc_current));
10062253ed4bSLinus Walleij 	if (ret < 0) {
10072253ed4bSLinus Walleij 		host->dma_in_progress = false;
10082253ed4bSLinus Walleij 		return ret;
10092253ed4bSLinus Walleij 	}
1010a813f2a2SLudovic Barre 	dma_async_issue_pending(dmae->cur);
1011c8ebae37SRussell King 
1012135ea30eSLudovic Barre 	*datactrl |= MCI_DPSM_DMAENABLE;
1013c8ebae37SRussell King 
1014c8ebae37SRussell King 	return 0;
1015c8ebae37SRussell King }
101658c7ccbfSPer Forlin 
101702769968SLudovic Barre void mmci_dmae_get_next_data(struct mmci_host *host, struct mmc_data *data)
101858c7ccbfSPer Forlin {
1019a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
1020a813f2a2SLudovic Barre 	struct mmci_dmae_next *next = &dmae->next_data;
102158c7ccbfSPer Forlin 
1022c3647fdcSLudovic Barre 	if (!host->use_dma)
1023c3647fdcSLudovic Barre 		return;
1024c3647fdcSLudovic Barre 
1025a813f2a2SLudovic Barre 	WARN_ON(!data->host_cookie && (next->desc || next->chan));
102658c7ccbfSPer Forlin 
1027a813f2a2SLudovic Barre 	dmae->desc_current = next->desc;
1028a813f2a2SLudovic Barre 	dmae->cur = next->chan;
1029a813f2a2SLudovic Barre 	next->desc = NULL;
1030a813f2a2SLudovic Barre 	next->chan = NULL;
103158c7ccbfSPer Forlin }
103258c7ccbfSPer Forlin 
103347983510SLudovic Barre void mmci_dmae_unprep_data(struct mmci_host *host,
103447983510SLudovic Barre 			   struct mmc_data *data, int err)
103547983510SLudovic Barre 
103658c7ccbfSPer Forlin {
1037a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
103858c7ccbfSPer Forlin 
103947983510SLudovic Barre 	if (!host->use_dma)
104058c7ccbfSPer Forlin 		return;
104158c7ccbfSPer Forlin 
1042653a761eSUlf Hansson 	mmci_dma_unmap(host, data);
1043653a761eSUlf Hansson 
1044653a761eSUlf Hansson 	if (err) {
1045a813f2a2SLudovic Barre 		struct mmci_dmae_next *next = &dmae->next_data;
1046653a761eSUlf Hansson 		struct dma_chan *chan;
1047653a761eSUlf Hansson 		if (data->flags & MMC_DATA_READ)
1048a813f2a2SLudovic Barre 			chan = dmae->rx_channel;
1049653a761eSUlf Hansson 		else
1050a813f2a2SLudovic Barre 			chan = dmae->tx_channel;
105158c7ccbfSPer Forlin 		dmaengine_terminate_all(chan);
1052653a761eSUlf Hansson 
1053a813f2a2SLudovic Barre 		if (dmae->desc_current == next->desc)
1054a813f2a2SLudovic Barre 			dmae->desc_current = NULL;
1055b5c16a60SSrinivas Kandagatla 
1056a813f2a2SLudovic Barre 		if (dmae->cur == next->chan) {
1057e13934bdSLinus Walleij 			host->dma_in_progress = false;
1058a813f2a2SLudovic Barre 			dmae->cur = NULL;
1059e13934bdSLinus Walleij 		}
1060b5c16a60SSrinivas Kandagatla 
1061a813f2a2SLudovic Barre 		next->desc = NULL;
1062a813f2a2SLudovic Barre 		next->chan = NULL;
106358c7ccbfSPer Forlin 	}
106458c7ccbfSPer Forlin }
106558c7ccbfSPer Forlin 
1066c3647fdcSLudovic Barre static struct mmci_host_ops mmci_variant_ops = {
106747983510SLudovic Barre 	.prep_data = mmci_dmae_prep_data,
106847983510SLudovic Barre 	.unprep_data = mmci_dmae_unprep_data,
1069b3fb9d64SLudovic Barre 	.get_datactrl_cfg = mmci_get_dctrl_cfg,
107002769968SLudovic Barre 	.get_next_data = mmci_dmae_get_next_data,
1071c3647fdcSLudovic Barre 	.dma_setup = mmci_dmae_setup,
1072c3647fdcSLudovic Barre 	.dma_release = mmci_dmae_release,
1073135ea30eSLudovic Barre 	.dma_start = mmci_dmae_start,
10745a9f10c3SLudovic Barre 	.dma_finalize = mmci_dmae_finalize,
1075cfccc6acSLudovic Barre 	.dma_error = mmci_dmae_error,
1076c3647fdcSLudovic Barre };
1077b3fb9d64SLudovic Barre #else
1078b3fb9d64SLudovic Barre static struct mmci_host_ops mmci_variant_ops = {
1079b3fb9d64SLudovic Barre 	.get_datactrl_cfg = mmci_get_dctrl_cfg,
1080b3fb9d64SLudovic Barre };
1081b3fb9d64SLudovic Barre #endif
1082c3647fdcSLudovic Barre 
1083e2b98d83SBen Dooks static void mmci_variant_init(struct mmci_host *host)
1084c3647fdcSLudovic Barre {
1085c3647fdcSLudovic Barre 	host->ops = &mmci_variant_ops;
1086c3647fdcSLudovic Barre }
1087b3fb9d64SLudovic Barre 
1088cb0335b7SLudovic Barre static void ux500_variant_init(struct mmci_host *host)
1089cb0335b7SLudovic Barre {
1090cb0335b7SLudovic Barre 	host->ops = &mmci_variant_ops;
1091cb0335b7SLudovic Barre 	host->ops->busy_complete = ux500_busy_complete;
1092cb0335b7SLudovic Barre }
1093cb0335b7SLudovic Barre 
1094e2b98d83SBen Dooks static void ux500v2_variant_init(struct mmci_host *host)
1095b3fb9d64SLudovic Barre {
1096b3fb9d64SLudovic Barre 	host->ops = &mmci_variant_ops;
1097cb0335b7SLudovic Barre 	host->ops->busy_complete = ux500_busy_complete;
1098b3fb9d64SLudovic Barre 	host->ops->get_datactrl_cfg = ux500v2_get_dctrl_cfg;
1099b3fb9d64SLudovic Barre }
1100c8ebae37SRussell King 
110147983510SLudovic Barre static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq)
110247983510SLudovic Barre {
110347983510SLudovic Barre 	struct mmci_host *host = mmc_priv(mmc);
110447983510SLudovic Barre 	struct mmc_data *data = mrq->data;
110547983510SLudovic Barre 
110647983510SLudovic Barre 	if (!data)
110747983510SLudovic Barre 		return;
110847983510SLudovic Barre 
110947983510SLudovic Barre 	WARN_ON(data->host_cookie);
111047983510SLudovic Barre 
111147983510SLudovic Barre 	if (mmci_validate_data(host, data))
111247983510SLudovic Barre 		return;
111347983510SLudovic Barre 
111447983510SLudovic Barre 	mmci_prep_data(host, data, true);
111547983510SLudovic Barre }
111647983510SLudovic Barre 
111747983510SLudovic Barre static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq,
111847983510SLudovic Barre 			      int err)
111947983510SLudovic Barre {
112047983510SLudovic Barre 	struct mmci_host *host = mmc_priv(mmc);
112147983510SLudovic Barre 	struct mmc_data *data = mrq->data;
112247983510SLudovic Barre 
112347983510SLudovic Barre 	if (!data || !data->host_cookie)
112447983510SLudovic Barre 		return;
112547983510SLudovic Barre 
112647983510SLudovic Barre 	mmci_unprep_data(host, data, err);
112747983510SLudovic Barre }
112847983510SLudovic Barre 
11291c6a0718SPierre Ossman static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
11301c6a0718SPierre Ossman {
11318301bb68SRabin Vincent 	struct variant_data *variant = host->variant;
11321c6a0718SPierre Ossman 	unsigned int datactrl, timeout, irqmask;
11331c6a0718SPierre Ossman 	unsigned long long clks;
11341c6a0718SPierre Ossman 	void __iomem *base;
11351c6a0718SPierre Ossman 
113664de0289SLinus Walleij 	dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n",
11371c6a0718SPierre Ossman 		data->blksz, data->blocks, data->flags);
11381c6a0718SPierre Ossman 
11391c6a0718SPierre Ossman 	host->data = data;
1140528320dbSRabin Vincent 	host->size = data->blksz * data->blocks;
114151d4375dSRussell King 	data->bytes_xfered = 0;
11421c6a0718SPierre Ossman 
11431c6a0718SPierre Ossman 	clks = (unsigned long long)data->timeout_ns * host->cclk;
1144c4a35769SSrinivas Kandagatla 	do_div(clks, NSEC_PER_SEC);
11451c6a0718SPierre Ossman 
11461c6a0718SPierre Ossman 	timeout = data->timeout_clks + (unsigned int)clks;
11471c6a0718SPierre Ossman 
11481c6a0718SPierre Ossman 	base = host->base;
11491c6a0718SPierre Ossman 	writel(timeout, base + MMCIDATATIMER);
11501c6a0718SPierre Ossman 	writel(host->size, base + MMCIDATALENGTH);
11511c6a0718SPierre Ossman 
115241ed65e7SLudovic Barre 	datactrl = host->ops->get_datactrl_cfg(host);
115341ed65e7SLudovic Barre 	datactrl |= host->data->flags & MMC_DATA_READ ? MCI_DPSM_DIRECTION : 0;
1154c8ebae37SRussell King 
1155c7354133SSrinivas Kandagatla 	if (host->mmc->card && mmc_card_sdio(host->mmc->card)) {
115606c1a121SUlf Hansson 		u32 clk;
1157c7354133SSrinivas Kandagatla 
11585df014dfSSrinivas Kandagatla 		datactrl |= variant->datactrl_mask_sdio;
11597258db7eSUlf Hansson 
1160c8ebae37SRussell King 		/*
116170ac0935SUlf Hansson 		 * The ST Micro variant for SDIO small write transfers
116270ac0935SUlf Hansson 		 * needs to have clock H/W flow control disabled,
116370ac0935SUlf Hansson 		 * otherwise the transfer will not start. The threshold
116470ac0935SUlf Hansson 		 * depends on the rate of MCLK.
116506c1a121SUlf Hansson 		 */
1166c7354133SSrinivas Kandagatla 		if (variant->st_sdio && data->flags & MMC_DATA_WRITE &&
116770ac0935SUlf Hansson 		    (host->size < 8 ||
116870ac0935SUlf Hansson 		     (host->size <= 8 && host->mclk > 50000000)))
116906c1a121SUlf Hansson 			clk = host->clk_reg & ~variant->clkreg_enable;
117006c1a121SUlf Hansson 		else
117106c1a121SUlf Hansson 			clk = host->clk_reg | variant->clkreg_enable;
117206c1a121SUlf Hansson 
117306c1a121SUlf Hansson 		mmci_write_clkreg(host, clk);
117406c1a121SUlf Hansson 	}
117506c1a121SUlf Hansson 
11766dad6c95SSeungwon Jeon 	if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 ||
11776dad6c95SSeungwon Jeon 	    host->mmc->ios.timing == MMC_TIMING_MMC_DDR52)
1178e17dca2bSSrinivas Kandagatla 		datactrl |= variant->datactrl_mask_ddrmode;
11796dbb6ee0SUlf Hansson 
118006c1a121SUlf Hansson 	/*
1181c8ebae37SRussell King 	 * Attempt to use DMA operation mode, if this
1182c8ebae37SRussell King 	 * should fail, fall back to PIO mode
1183c8ebae37SRussell King 	 */
1184135ea30eSLudovic Barre 	if (!mmci_dma_start(host, datactrl))
1185c8ebae37SRussell King 		return;
1186c8ebae37SRussell King 
1187c8ebae37SRussell King 	/* IRQ mode, map the SG list for CPU reading/writing */
1188c8ebae37SRussell King 	mmci_init_sg(host, data);
1189c8ebae37SRussell King 
1190c8ebae37SRussell King 	if (data->flags & MMC_DATA_READ) {
11911c6a0718SPierre Ossman 		irqmask = MCI_RXFIFOHALFFULLMASK;
11921c6a0718SPierre Ossman 
11931c6a0718SPierre Ossman 		/*
1194c4d877c1SRussell King 		 * If we have less than the fifo 'half-full' threshold to
1195c4d877c1SRussell King 		 * transfer, trigger a PIO interrupt as soon as any data
1196c4d877c1SRussell King 		 * is available.
11971c6a0718SPierre Ossman 		 */
1198c4d877c1SRussell King 		if (host->size < variant->fifohalfsize)
11991c6a0718SPierre Ossman 			irqmask |= MCI_RXDATAAVLBLMASK;
12001c6a0718SPierre Ossman 	} else {
12011c6a0718SPierre Ossman 		/*
12021c6a0718SPierre Ossman 		 * We don't actually need to include "FIFO empty" here
12031c6a0718SPierre Ossman 		 * since its implicit in "FIFO half empty".
12041c6a0718SPierre Ossman 		 */
12051c6a0718SPierre Ossman 		irqmask = MCI_TXFIFOHALFEMPTYMASK;
12061c6a0718SPierre Ossman 	}
12071c6a0718SPierre Ossman 
12089cc639a2SUlf Hansson 	mmci_write_datactrlreg(host, datactrl);
12091c6a0718SPierre Ossman 	writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
12102686b4b4SLinus Walleij 	mmci_set_mask1(host, irqmask);
12111c6a0718SPierre Ossman }
12121c6a0718SPierre Ossman 
12131c6a0718SPierre Ossman static void
12141c6a0718SPierre Ossman mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
12151c6a0718SPierre Ossman {
12161c6a0718SPierre Ossman 	void __iomem *base = host->base;
12178266c585SLudovic Barre 	unsigned long long clks;
12181c6a0718SPierre Ossman 
121964de0289SLinus Walleij 	dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n",
12201c6a0718SPierre Ossman 	    cmd->opcode, cmd->arg, cmd->flags);
12211c6a0718SPierre Ossman 
12220f244804SLudovic Barre 	if (readl(base + MMCICOMMAND) & host->variant->cmdreg_cpsm_enable) {
12231c6a0718SPierre Ossman 		writel(0, base + MMCICOMMAND);
12246adb2a80SSrinivas Kandagatla 		mmci_reg_delay(host);
12251c6a0718SPierre Ossman 	}
12261c6a0718SPierre Ossman 
1227c8073e52SLudovic Barre 	if (host->variant->cmdreg_stop &&
1228c8073e52SLudovic Barre 	    cmd->opcode == MMC_STOP_TRANSMISSION)
1229c8073e52SLudovic Barre 		c |= host->variant->cmdreg_stop;
1230c8073e52SLudovic Barre 
12310f244804SLudovic Barre 	c |= cmd->opcode | host->variant->cmdreg_cpsm_enable;
12321c6a0718SPierre Ossman 	if (cmd->flags & MMC_RSP_PRESENT) {
12331c6a0718SPierre Ossman 		if (cmd->flags & MMC_RSP_136)
12340f244804SLudovic Barre 			c |= host->variant->cmdreg_lrsp_crc;
12350f244804SLudovic Barre 		else if (cmd->flags & MMC_RSP_CRC)
12360f244804SLudovic Barre 			c |= host->variant->cmdreg_srsp_crc;
12370f244804SLudovic Barre 		else
12380f244804SLudovic Barre 			c |= host->variant->cmdreg_srsp;
12391c6a0718SPierre Ossman 	}
12408266c585SLudovic Barre 
12418266c585SLudovic Barre 	if (host->variant->busy_timeout && cmd->flags & MMC_RSP_BUSY) {
12428266c585SLudovic Barre 		if (!cmd->busy_timeout)
12438266c585SLudovic Barre 			cmd->busy_timeout = 10 * MSEC_PER_SEC;
12448266c585SLudovic Barre 
1245774514bfSYann Gautier 		if (cmd->busy_timeout > host->mmc->max_busy_timeout)
1246774514bfSYann Gautier 			clks = (unsigned long long)host->mmc->max_busy_timeout * host->cclk;
1247774514bfSYann Gautier 		else
12488266c585SLudovic Barre 			clks = (unsigned long long)cmd->busy_timeout * host->cclk;
1249774514bfSYann Gautier 
12508266c585SLudovic Barre 		do_div(clks, MSEC_PER_SEC);
12518266c585SLudovic Barre 		writel_relaxed(clks, host->base + MMCIDATATIMER);
12528266c585SLudovic Barre 	}
12538266c585SLudovic Barre 
125475773165SLudovic Barre 	if (host->ops->pre_sig_volt_switch && cmd->opcode == SD_SWITCH_VOLTAGE)
125575773165SLudovic Barre 		host->ops->pre_sig_volt_switch(host);
125675773165SLudovic Barre 
12571c6a0718SPierre Ossman 	if (/*interrupt*/0)
12581c6a0718SPierre Ossman 		c |= MCI_CPSM_INTERRUPT;
12591c6a0718SPierre Ossman 
1260ae7b0061SSrinivas Kandagatla 	if (mmc_cmd_type(cmd) == MMC_CMD_ADTC)
1261ae7b0061SSrinivas Kandagatla 		c |= host->variant->data_cmd_enable;
1262ae7b0061SSrinivas Kandagatla 
12631c6a0718SPierre Ossman 	host->cmd = cmd;
12641c6a0718SPierre Ossman 
12651c6a0718SPierre Ossman 	writel(cmd->arg, base + MMCIARGUMENT);
12661c6a0718SPierre Ossman 	writel(c, base + MMCICOMMAND);
12671c6a0718SPierre Ossman }
12681c6a0718SPierre Ossman 
1269e9968c6fSUlf Hansson static void mmci_stop_command(struct mmci_host *host)
1270e9968c6fSUlf Hansson {
1271e9968c6fSUlf Hansson 	host->stop_abort.error = 0;
1272e9968c6fSUlf Hansson 	mmci_start_command(host, &host->stop_abort, 0);
1273e9968c6fSUlf Hansson }
1274e9968c6fSUlf Hansson 
12751c6a0718SPierre Ossman static void
12761c6a0718SPierre Ossman mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
12771c6a0718SPierre Ossman 	      unsigned int status)
12781c6a0718SPierre Ossman {
1279daf9713cSLudovic Barre 	unsigned int status_err;
1280daf9713cSLudovic Barre 
12811cb9da50SUlf Hansson 	/* Make sure we have data to handle */
12821cb9da50SUlf Hansson 	if (!data)
12831cb9da50SUlf Hansson 		return;
12841cb9da50SUlf Hansson 
1285f20f8f21SLinus Walleij 	/* First check for errors */
1286daf9713cSLudovic Barre 	status_err = status & (host->variant->start_err |
1287daf9713cSLudovic Barre 			       MCI_DATACRCFAIL | MCI_DATATIMEOUT |
1288daf9713cSLudovic Barre 			       MCI_TXUNDERRUN | MCI_RXOVERRUN);
1289daf9713cSLudovic Barre 
1290daf9713cSLudovic Barre 	if (status_err) {
12918cb28155SLinus Walleij 		u32 remain, success;
1292f20f8f21SLinus Walleij 
1293c8ebae37SRussell King 		/* Terminate the DMA transfer */
1294cfccc6acSLudovic Barre 		mmci_dma_error(host);
1295c8ebae37SRussell King 
1296c8afc9d5SRussell King 		/*
1297c8afc9d5SRussell King 		 * Calculate how far we are into the transfer.  Note that
1298c8afc9d5SRussell King 		 * the data counter gives the number of bytes transferred
1299c8afc9d5SRussell King 		 * on the MMC bus, not on the host side.  On reads, this
1300c8afc9d5SRussell King 		 * can be as much as a FIFO-worth of data ahead.  This
1301c8afc9d5SRussell King 		 * matters for FIFO overruns only.
1302c8afc9d5SRussell King 		 */
1303b79220b3SLudovic Barre 		if (!host->variant->datacnt_useless) {
1304f5a106d9SLinus Walleij 			remain = readl(host->base + MMCIDATACNT);
13058cb28155SLinus Walleij 			success = data->blksz * data->blocks - remain;
1306b79220b3SLudovic Barre 		} else {
1307b79220b3SLudovic Barre 			success = 0;
1308b79220b3SLudovic Barre 		}
13098cb28155SLinus Walleij 
1310c8afc9d5SRussell King 		dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ, status 0x%08x at 0x%08x\n",
1311daf9713cSLudovic Barre 			status_err, success);
1312daf9713cSLudovic Barre 		if (status_err & MCI_DATACRCFAIL) {
13138cb28155SLinus Walleij 			/* Last block was not successful */
1314c8afc9d5SRussell King 			success -= 1;
131517b0429dSPierre Ossman 			data->error = -EILSEQ;
1316daf9713cSLudovic Barre 		} else if (status_err & MCI_DATATIMEOUT) {
131717b0429dSPierre Ossman 			data->error = -ETIMEDOUT;
1318daf9713cSLudovic Barre 		} else if (status_err & MCI_STARTBITERR) {
1319757df746SLinus Walleij 			data->error = -ECOMM;
1320daf9713cSLudovic Barre 		} else if (status_err & MCI_TXUNDERRUN) {
132117b0429dSPierre Ossman 			data->error = -EIO;
1322daf9713cSLudovic Barre 		} else if (status_err & MCI_RXOVERRUN) {
1323c8afc9d5SRussell King 			if (success > host->variant->fifosize)
1324c8afc9d5SRussell King 				success -= host->variant->fifosize;
1325c8afc9d5SRussell King 			else
1326c8afc9d5SRussell King 				success = 0;
13278cb28155SLinus Walleij 			data->error = -EIO;
13284ce1d6cbSRabin Vincent 		}
132951d4375dSRussell King 		data->bytes_xfered = round_down(success, data->blksz);
13301c6a0718SPierre Ossman 	}
1331f20f8f21SLinus Walleij 
13328cb28155SLinus Walleij 	if (status & MCI_DATABLOCKEND)
13338cb28155SLinus Walleij 		dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n");
1334f20f8f21SLinus Walleij 
1335ccff9b51SRussell King 	if (status & MCI_DATAEND || data->error) {
1336653a761eSUlf Hansson 		mmci_dma_finalize(host, data);
1337cdea1947SLudovic Barre 
13381c6a0718SPierre Ossman 		mmci_stop_data(host);
13391c6a0718SPierre Ossman 
13408cb28155SLinus Walleij 		if (!data->error)
13418cb28155SLinus Walleij 			/* The error clause is handled above, success! */
134251d4375dSRussell King 			data->bytes_xfered = data->blksz * data->blocks;
1343f20f8f21SLinus Walleij 
1344e9968c6fSUlf Hansson 		if (!data->stop) {
1345e9968c6fSUlf Hansson 			if (host->variant->cmdreg_stop && data->error)
1346e9968c6fSUlf Hansson 				mmci_stop_command(host);
134709b4f706SLudovic Barre 			else
1348e9968c6fSUlf Hansson 				mmci_request_end(host, data->mrq);
1349e9968c6fSUlf Hansson 		} else if (host->mrq->sbc && !data->error) {
1350e9968c6fSUlf Hansson 			mmci_request_end(host, data->mrq);
1351e9968c6fSUlf Hansson 		} else {
13521c6a0718SPierre Ossman 			mmci_start_command(host, data->stop, 0);
13531c6a0718SPierre Ossman 		}
13541c6a0718SPierre Ossman 	}
1355e9968c6fSUlf Hansson }
13561c6a0718SPierre Ossman 
13571c6a0718SPierre Ossman static void
13581c6a0718SPierre Ossman mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
13591c6a0718SPierre Ossman 	     unsigned int status)
13601c6a0718SPierre Ossman {
13618266c585SLudovic Barre 	u32 err_msk = MCI_CMDCRCFAIL | MCI_CMDTIMEOUT;
13621c6a0718SPierre Ossman 	void __iomem *base = host->base;
1363812513c7SLudovic Barre 	bool sbc, busy_resp;
1364ad82bfeaSUlf Hansson 
1365ad82bfeaSUlf Hansson 	if (!cmd)
1366ad82bfeaSUlf Hansson 		return;
1367ad82bfeaSUlf Hansson 
1368ad82bfeaSUlf Hansson 	sbc = (cmd == host->mrq->sbc);
1369812513c7SLudovic Barre 	busy_resp = !!(cmd->flags & MMC_RSP_BUSY);
1370ad82bfeaSUlf Hansson 
137149adc0caSLinus Walleij 	/*
137249adc0caSLinus Walleij 	 * We need to be one of these interrupts to be considered worth
137349adc0caSLinus Walleij 	 * handling. Note that we tag on any latent IRQs postponed
137449adc0caSLinus Walleij 	 * due to waiting for busy status.
137549adc0caSLinus Walleij 	 */
13768266c585SLudovic Barre 	if (host->variant->busy_timeout && busy_resp)
13778266c585SLudovic Barre 		err_msk |= MCI_DATATIMEOUT;
13788266c585SLudovic Barre 
137949adc0caSLinus Walleij 	if (!((status | host->busy_status) &
13808266c585SLudovic Barre 	      (err_msk | MCI_CMDSENT | MCI_CMDRESPEND)))
1381ad82bfeaSUlf Hansson 		return;
13828d94b54dSUlf Hansson 
1383a9cbd79cSUlf Hansson 	/* Handle busy detection on DAT0 if the variant supports it. */
1384cb0335b7SLudovic Barre 	if (busy_resp && host->variant->busy_detect)
1385cb0335b7SLudovic Barre 		if (!host->ops->busy_complete(host, status, err_msk))
13868d94b54dSUlf Hansson 			return;
13871c6a0718SPierre Ossman 
13881c6a0718SPierre Ossman 	host->cmd = NULL;
13891c6a0718SPierre Ossman 
13901c6a0718SPierre Ossman 	if (status & MCI_CMDTIMEOUT) {
139117b0429dSPierre Ossman 		cmd->error = -ETIMEDOUT;
13921c6a0718SPierre Ossman 	} else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) {
139317b0429dSPierre Ossman 		cmd->error = -EILSEQ;
13948266c585SLudovic Barre 	} else if (host->variant->busy_timeout && busy_resp &&
13958266c585SLudovic Barre 		   status & MCI_DATATIMEOUT) {
13968266c585SLudovic Barre 		cmd->error = -ETIMEDOUT;
1397546b73abSLinus Walleij 		/*
1398546b73abSLinus Walleij 		 * This will wake up mmci_irq_thread() which will issue
1399546b73abSLinus Walleij 		 * a hardware reset of the MMCI block.
1400546b73abSLinus Walleij 		 */
1401ee157abeSLudovic Barre 		host->irq_action = IRQ_WAKE_THREAD;
14029047b435SRussell King - ARM Linux 	} else {
14039047b435SRussell King - ARM Linux 		cmd->resp[0] = readl(base + MMCIRESPONSE0);
14049047b435SRussell King - ARM Linux 		cmd->resp[1] = readl(base + MMCIRESPONSE1);
14059047b435SRussell King - ARM Linux 		cmd->resp[2] = readl(base + MMCIRESPONSE2);
14069047b435SRussell King - ARM Linux 		cmd->resp[3] = readl(base + MMCIRESPONSE3);
14071c6a0718SPierre Ossman 	}
14081c6a0718SPierre Ossman 
1409024629c6SUlf Hansson 	if ((!sbc && !cmd->data) || cmd->error) {
14103b6e3c73SUlf Hansson 		if (host->data) {
14113b6e3c73SUlf Hansson 			/* Terminate the DMA transfer */
1412cfccc6acSLudovic Barre 			mmci_dma_error(host);
14137b2a6d51SLudovic Barre 
14141c6a0718SPierre Ossman 			mmci_stop_data(host);
1415e9968c6fSUlf Hansson 			if (host->variant->cmdreg_stop && cmd->error) {
1416e9968c6fSUlf Hansson 				mmci_stop_command(host);
1417e9968c6fSUlf Hansson 				return;
1418e9968c6fSUlf Hansson 			}
14193b6e3c73SUlf Hansson 		}
1420ee157abeSLudovic Barre 
1421ee157abeSLudovic Barre 		if (host->irq_action != IRQ_WAKE_THREAD)
1422024629c6SUlf Hansson 			mmci_request_end(host, host->mrq);
1423ee157abeSLudovic Barre 
1424024629c6SUlf Hansson 	} else if (sbc) {
1425024629c6SUlf Hansson 		mmci_start_command(host, host->mrq->cmd, 0);
1426d2141547SLudovic Barre 	} else if (!host->variant->datactrl_first &&
1427d2141547SLudovic Barre 		   !(cmd->data->flags & MMC_DATA_READ)) {
14281c6a0718SPierre Ossman 		mmci_start_data(host, cmd->data);
14291c6a0718SPierre Ossman 	}
14301c6a0718SPierre Ossman }
14311c6a0718SPierre Ossman 
14329c34b73dSSrinivas Kandagatla static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain)
14339c34b73dSSrinivas Kandagatla {
14349c34b73dSSrinivas Kandagatla 	return remain - (readl(host->base + MMCIFIFOCNT) << 2);
14359c34b73dSSrinivas Kandagatla }
14369c34b73dSSrinivas Kandagatla 
14379c34b73dSSrinivas Kandagatla static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, int r)
14389c34b73dSSrinivas Kandagatla {
14399c34b73dSSrinivas Kandagatla 	/*
14409c34b73dSSrinivas Kandagatla 	 * on qcom SDCC4 only 8 words are used in each burst so only 8 addresses
14419c34b73dSSrinivas Kandagatla 	 * from the fifo range should be used
14429c34b73dSSrinivas Kandagatla 	 */
14439c34b73dSSrinivas Kandagatla 	if (status & MCI_RXFIFOHALFFULL)
14449c34b73dSSrinivas Kandagatla 		return host->variant->fifohalfsize;
14459c34b73dSSrinivas Kandagatla 	else if (status & MCI_RXDATAAVLBL)
14469c34b73dSSrinivas Kandagatla 		return 4;
14479c34b73dSSrinivas Kandagatla 
14489c34b73dSSrinivas Kandagatla 	return 0;
14499c34b73dSSrinivas Kandagatla }
14509c34b73dSSrinivas Kandagatla 
14511c6a0718SPierre Ossman static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain)
14521c6a0718SPierre Ossman {
14531c6a0718SPierre Ossman 	void __iomem *base = host->base;
14541c6a0718SPierre Ossman 	char *ptr = buffer;
14559c34b73dSSrinivas Kandagatla 	u32 status = readl(host->base + MMCISTATUS);
145626eed9a5SLinus Walleij 	int host_remain = host->size;
14571c6a0718SPierre Ossman 
14581c6a0718SPierre Ossman 	do {
14599c34b73dSSrinivas Kandagatla 		int count = host->get_rx_fifocnt(host, status, host_remain);
14601c6a0718SPierre Ossman 
14611c6a0718SPierre Ossman 		if (count > remain)
14621c6a0718SPierre Ossman 			count = remain;
14631c6a0718SPierre Ossman 
14641c6a0718SPierre Ossman 		if (count <= 0)
14651c6a0718SPierre Ossman 			break;
14661c6a0718SPierre Ossman 
1467393e5e24SUlf Hansson 		/*
1468393e5e24SUlf Hansson 		 * SDIO especially may want to send something that is
1469393e5e24SUlf Hansson 		 * not divisible by 4 (as opposed to card sectors
1470393e5e24SUlf Hansson 		 * etc). Therefore make sure to always read the last bytes
1471393e5e24SUlf Hansson 		 * while only doing full 32-bit reads towards the FIFO.
1472393e5e24SUlf Hansson 		 */
1473393e5e24SUlf Hansson 		if (unlikely(count & 0x3)) {
1474393e5e24SUlf Hansson 			if (count < 4) {
1475393e5e24SUlf Hansson 				unsigned char buf[4];
14764b85da08SDavide Ciminaghi 				ioread32_rep(base + MMCIFIFO, buf, 1);
1477393e5e24SUlf Hansson 				memcpy(ptr, buf, count);
1478393e5e24SUlf Hansson 			} else {
14794b85da08SDavide Ciminaghi 				ioread32_rep(base + MMCIFIFO, ptr, count >> 2);
1480393e5e24SUlf Hansson 				count &= ~0x3;
1481393e5e24SUlf Hansson 			}
1482393e5e24SUlf Hansson 		} else {
14834b85da08SDavide Ciminaghi 			ioread32_rep(base + MMCIFIFO, ptr, count >> 2);
1484393e5e24SUlf Hansson 		}
14851c6a0718SPierre Ossman 
14861c6a0718SPierre Ossman 		ptr += count;
14871c6a0718SPierre Ossman 		remain -= count;
148826eed9a5SLinus Walleij 		host_remain -= count;
14891c6a0718SPierre Ossman 
14901c6a0718SPierre Ossman 		if (remain == 0)
14911c6a0718SPierre Ossman 			break;
14921c6a0718SPierre Ossman 
14931c6a0718SPierre Ossman 		status = readl(base + MMCISTATUS);
14941c6a0718SPierre Ossman 	} while (status & MCI_RXDATAAVLBL);
14951c6a0718SPierre Ossman 
14961c6a0718SPierre Ossman 	return ptr - buffer;
14971c6a0718SPierre Ossman }
14981c6a0718SPierre Ossman 
14991c6a0718SPierre Ossman static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status)
15001c6a0718SPierre Ossman {
15018301bb68SRabin Vincent 	struct variant_data *variant = host->variant;
15021c6a0718SPierre Ossman 	void __iomem *base = host->base;
15031c6a0718SPierre Ossman 	char *ptr = buffer;
15041c6a0718SPierre Ossman 
15051c6a0718SPierre Ossman 	do {
15061c6a0718SPierre Ossman 		unsigned int count, maxcnt;
15071c6a0718SPierre Ossman 
15088301bb68SRabin Vincent 		maxcnt = status & MCI_TXFIFOEMPTY ?
15098301bb68SRabin Vincent 			 variant->fifosize : variant->fifohalfsize;
15101c6a0718SPierre Ossman 		count = min(remain, maxcnt);
15111c6a0718SPierre Ossman 
151234177802SLinus Walleij 		/*
151334177802SLinus Walleij 		 * SDIO especially may want to send something that is
151434177802SLinus Walleij 		 * not divisible by 4 (as opposed to card sectors
151534177802SLinus Walleij 		 * etc), and the FIFO only accept full 32-bit writes.
151634177802SLinus Walleij 		 * So compensate by adding +3 on the count, a single
151734177802SLinus Walleij 		 * byte become a 32bit write, 7 bytes will be two
151834177802SLinus Walleij 		 * 32bit writes etc.
151934177802SLinus Walleij 		 */
15204b85da08SDavide Ciminaghi 		iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2);
15211c6a0718SPierre Ossman 
15221c6a0718SPierre Ossman 		ptr += count;
15231c6a0718SPierre Ossman 		remain -= count;
15241c6a0718SPierre Ossman 
15251c6a0718SPierre Ossman 		if (remain == 0)
15261c6a0718SPierre Ossman 			break;
15271c6a0718SPierre Ossman 
15281c6a0718SPierre Ossman 		status = readl(base + MMCISTATUS);
15291c6a0718SPierre Ossman 	} while (status & MCI_TXFIFOHALFEMPTY);
15301c6a0718SPierre Ossman 
15311c6a0718SPierre Ossman 	return ptr - buffer;
15321c6a0718SPierre Ossman }
15331c6a0718SPierre Ossman 
15341c6a0718SPierre Ossman /*
15351c6a0718SPierre Ossman  * PIO data transfer IRQ handler.
15361c6a0718SPierre Ossman  */
15371c6a0718SPierre Ossman static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
15381c6a0718SPierre Ossman {
15391c6a0718SPierre Ossman 	struct mmci_host *host = dev_id;
15404ce1d6cbSRabin Vincent 	struct sg_mapping_iter *sg_miter = &host->sg_miter;
15418301bb68SRabin Vincent 	struct variant_data *variant = host->variant;
15421c6a0718SPierre Ossman 	void __iomem *base = host->base;
15431c6a0718SPierre Ossman 	u32 status;
15441c6a0718SPierre Ossman 
15451c6a0718SPierre Ossman 	status = readl(base + MMCISTATUS);
15461c6a0718SPierre Ossman 
154764de0289SLinus Walleij 	dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status);
15481c6a0718SPierre Ossman 
15491c6a0718SPierre Ossman 	do {
15501c6a0718SPierre Ossman 		unsigned int remain, len;
15511c6a0718SPierre Ossman 		char *buffer;
15521c6a0718SPierre Ossman 
15531c6a0718SPierre Ossman 		/*
15541c6a0718SPierre Ossman 		 * For write, we only need to test the half-empty flag
15551c6a0718SPierre Ossman 		 * here - if the FIFO is completely empty, then by
15561c6a0718SPierre Ossman 		 * definition it is more than half empty.
15571c6a0718SPierre Ossman 		 *
15581c6a0718SPierre Ossman 		 * For read, check for data available.
15591c6a0718SPierre Ossman 		 */
15601c6a0718SPierre Ossman 		if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL)))
15611c6a0718SPierre Ossman 			break;
15621c6a0718SPierre Ossman 
15634ce1d6cbSRabin Vincent 		if (!sg_miter_next(sg_miter))
15644ce1d6cbSRabin Vincent 			break;
15654ce1d6cbSRabin Vincent 
15664ce1d6cbSRabin Vincent 		buffer = sg_miter->addr;
15674ce1d6cbSRabin Vincent 		remain = sg_miter->length;
15681c6a0718SPierre Ossman 
15691c6a0718SPierre Ossman 		len = 0;
15701c6a0718SPierre Ossman 		if (status & MCI_RXACTIVE)
15711c6a0718SPierre Ossman 			len = mmci_pio_read(host, buffer, remain);
15721c6a0718SPierre Ossman 		if (status & MCI_TXACTIVE)
15731c6a0718SPierre Ossman 			len = mmci_pio_write(host, buffer, remain, status);
15741c6a0718SPierre Ossman 
15754ce1d6cbSRabin Vincent 		sg_miter->consumed = len;
15761c6a0718SPierre Ossman 
15771c6a0718SPierre Ossman 		host->size -= len;
15781c6a0718SPierre Ossman 		remain -= len;
15791c6a0718SPierre Ossman 
15801c6a0718SPierre Ossman 		if (remain)
15811c6a0718SPierre Ossman 			break;
15821c6a0718SPierre Ossman 
15831c6a0718SPierre Ossman 		status = readl(base + MMCISTATUS);
15841c6a0718SPierre Ossman 	} while (1);
15851c6a0718SPierre Ossman 
15864ce1d6cbSRabin Vincent 	sg_miter_stop(sg_miter);
15874ce1d6cbSRabin Vincent 
15881c6a0718SPierre Ossman 	/*
1589c4d877c1SRussell King 	 * If we have less than the fifo 'half-full' threshold to transfer,
1590c4d877c1SRussell King 	 * trigger a PIO interrupt as soon as any data is available.
15911c6a0718SPierre Ossman 	 */
1592c4d877c1SRussell King 	if (status & MCI_RXACTIVE && host->size < variant->fifohalfsize)
15932686b4b4SLinus Walleij 		mmci_set_mask1(host, MCI_RXDATAAVLBLMASK);
15941c6a0718SPierre Ossman 
15951c6a0718SPierre Ossman 	/*
15961c6a0718SPierre Ossman 	 * If we run out of data, disable the data IRQs; this
15971c6a0718SPierre Ossman 	 * prevents a race where the FIFO becomes empty before
15981c6a0718SPierre Ossman 	 * the chip itself has disabled the data path, and
15991c6a0718SPierre Ossman 	 * stops us racing with our data end IRQ.
16001c6a0718SPierre Ossman 	 */
16011c6a0718SPierre Ossman 	if (host->size == 0) {
16022686b4b4SLinus Walleij 		mmci_set_mask1(host, 0);
16031c6a0718SPierre Ossman 		writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0);
16041c6a0718SPierre Ossman 	}
16051c6a0718SPierre Ossman 
16061c6a0718SPierre Ossman 	return IRQ_HANDLED;
16071c6a0718SPierre Ossman }
16081c6a0718SPierre Ossman 
16091c6a0718SPierre Ossman /*
16101c6a0718SPierre Ossman  * Handle completion of command and data transfers.
16111c6a0718SPierre Ossman  */
16121c6a0718SPierre Ossman static irqreturn_t mmci_irq(int irq, void *dev_id)
16131c6a0718SPierre Ossman {
16141c6a0718SPierre Ossman 	struct mmci_host *host = dev_id;
16151c6a0718SPierre Ossman 	u32 status;
16161c6a0718SPierre Ossman 
16171c6a0718SPierre Ossman 	spin_lock(&host->lock);
1618ee157abeSLudovic Barre 	host->irq_action = IRQ_HANDLED;
16191c6a0718SPierre Ossman 
16201c6a0718SPierre Ossman 	do {
16211c6a0718SPierre Ossman 		status = readl(host->base + MMCISTATUS);
1622f7ad7504SLinus Walleij 		if (!status)
1623f7ad7504SLinus Walleij 			break;
16242686b4b4SLinus Walleij 
16252686b4b4SLinus Walleij 		if (host->singleirq) {
16266ea9cdf3SPatrice Chotard 			if (status & host->mask1_reg)
16272686b4b4SLinus Walleij 				mmci_pio_irq(irq, dev_id);
16282686b4b4SLinus Walleij 
162959db5e2dSLudovic Barre 			status &= ~host->variant->irq_pio_mask;
16302686b4b4SLinus Walleij 		}
16312686b4b4SLinus Walleij 
16328d94b54dSUlf Hansson 		/*
1633a9cbd79cSUlf Hansson 		 * Busy detection is managed by mmci_cmd_irq(), including to
1634a9cbd79cSUlf Hansson 		 * clear the corresponding IRQ.
16358d94b54dSUlf Hansson 		 */
16361c6a0718SPierre Ossman 		status &= readl(host->base + MMCIMASK0);
16375cad24d8SJean-Nicolas Graux 		if (host->variant->busy_detect)
16385cad24d8SJean-Nicolas Graux 			writel(status & ~host->variant->busy_detect_mask,
16395cad24d8SJean-Nicolas Graux 			       host->base + MMCICLEAR);
16405cad24d8SJean-Nicolas Graux 		else
16411c6a0718SPierre Ossman 			writel(status, host->base + MMCICLEAR);
16421c6a0718SPierre Ossman 
164364de0289SLinus Walleij 		dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
16441c6a0718SPierre Ossman 
16457878289bSUlf Hansson 		if (host->variant->reversed_irq_handling) {
16467878289bSUlf Hansson 			mmci_data_irq(host, host->data, status);
16477878289bSUlf Hansson 			mmci_cmd_irq(host, host->cmd, status);
16487878289bSUlf Hansson 		} else {
1649ad82bfeaSUlf Hansson 			mmci_cmd_irq(host, host->cmd, status);
16501cb9da50SUlf Hansson 			mmci_data_irq(host, host->data, status);
16517878289bSUlf Hansson 		}
16521c6a0718SPierre Ossman 
165349adc0caSLinus Walleij 		/*
16548520ce1eSLudovic Barre 		 * Busy detection has been handled by mmci_cmd_irq() above.
16558520ce1eSLudovic Barre 		 * Clear the status bit to prevent polling in IRQ context.
165649adc0caSLinus Walleij 		 */
16578520ce1eSLudovic Barre 		if (host->variant->busy_detect_flag)
165849adc0caSLinus Walleij 			status &= ~host->variant->busy_detect_flag;
16598d94b54dSUlf Hansson 
16601c6a0718SPierre Ossman 	} while (status);
16611c6a0718SPierre Ossman 
16621c6a0718SPierre Ossman 	spin_unlock(&host->lock);
16631c6a0718SPierre Ossman 
1664ee157abeSLudovic Barre 	return host->irq_action;
1665ee157abeSLudovic Barre }
1666ee157abeSLudovic Barre 
1667ee157abeSLudovic Barre /*
1668ee157abeSLudovic Barre  * mmci_irq_thread() - A threaded IRQ handler that manages a reset of the HW.
1669ee157abeSLudovic Barre  *
1670ee157abeSLudovic Barre  * A reset is needed for some variants, where a datatimeout for a R1B request
1671ee157abeSLudovic Barre  * causes the DPSM to stay busy (non-functional).
1672ee157abeSLudovic Barre  */
1673ee157abeSLudovic Barre static irqreturn_t mmci_irq_thread(int irq, void *dev_id)
1674ee157abeSLudovic Barre {
1675ee157abeSLudovic Barre 	struct mmci_host *host = dev_id;
1676ee157abeSLudovic Barre 	unsigned long flags;
1677ee157abeSLudovic Barre 
1678ee157abeSLudovic Barre 	if (host->rst) {
1679ee157abeSLudovic Barre 		reset_control_assert(host->rst);
1680ee157abeSLudovic Barre 		udelay(2);
1681ee157abeSLudovic Barre 		reset_control_deassert(host->rst);
1682ee157abeSLudovic Barre 	}
1683ee157abeSLudovic Barre 
1684ee157abeSLudovic Barre 	spin_lock_irqsave(&host->lock, flags);
1685ee157abeSLudovic Barre 	writel(host->clk_reg, host->base + MMCICLOCK);
1686ee157abeSLudovic Barre 	writel(host->pwr_reg, host->base + MMCIPOWER);
1687ee157abeSLudovic Barre 	writel(MCI_IRQENABLE | host->variant->start_err,
1688ee157abeSLudovic Barre 	       host->base + MMCIMASK0);
1689ee157abeSLudovic Barre 
1690ee157abeSLudovic Barre 	host->irq_action = IRQ_HANDLED;
1691ee157abeSLudovic Barre 	mmci_request_end(host, host->mrq);
1692ee157abeSLudovic Barre 	spin_unlock_irqrestore(&host->lock, flags);
1693ee157abeSLudovic Barre 
1694ee157abeSLudovic Barre 	return host->irq_action;
16951c6a0718SPierre Ossman }
16961c6a0718SPierre Ossman 
16971c6a0718SPierre Ossman static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
16981c6a0718SPierre Ossman {
16991c6a0718SPierre Ossman 	struct mmci_host *host = mmc_priv(mmc);
17009e943021SLinus Walleij 	unsigned long flags;
17011c6a0718SPierre Ossman 
17021c6a0718SPierre Ossman 	WARN_ON(host->mrq != NULL);
17031c6a0718SPierre Ossman 
1704653a761eSUlf Hansson 	mrq->cmd->error = mmci_validate_data(host, mrq->data);
1705653a761eSUlf Hansson 	if (mrq->cmd->error) {
1706255d01afSPierre Ossman 		mmc_request_done(mmc, mrq);
1707255d01afSPierre Ossman 		return;
1708255d01afSPierre Ossman 	}
1709255d01afSPierre Ossman 
17109e943021SLinus Walleij 	spin_lock_irqsave(&host->lock, flags);
17111c6a0718SPierre Ossman 
17121c6a0718SPierre Ossman 	host->mrq = mrq;
17131c6a0718SPierre Ossman 
171458c7ccbfSPer Forlin 	if (mrq->data)
171558c7ccbfSPer Forlin 		mmci_get_next_data(host, mrq->data);
171658c7ccbfSPer Forlin 
1717d2141547SLudovic Barre 	if (mrq->data &&
1718d2141547SLudovic Barre 	    (host->variant->datactrl_first || mrq->data->flags & MMC_DATA_READ))
17191c6a0718SPierre Ossman 		mmci_start_data(host, mrq->data);
17201c6a0718SPierre Ossman 
1721024629c6SUlf Hansson 	if (mrq->sbc)
1722024629c6SUlf Hansson 		mmci_start_command(host, mrq->sbc, 0);
1723024629c6SUlf Hansson 	else
17241c6a0718SPierre Ossman 		mmci_start_command(host, mrq->cmd, 0);
17251c6a0718SPierre Ossman 
17269e943021SLinus Walleij 	spin_unlock_irqrestore(&host->lock, flags);
17271c6a0718SPierre Ossman }
17281c6a0718SPierre Ossman 
17298266c585SLudovic Barre static void mmci_set_max_busy_timeout(struct mmc_host *mmc)
17308266c585SLudovic Barre {
17318266c585SLudovic Barre 	struct mmci_host *host = mmc_priv(mmc);
17328266c585SLudovic Barre 	u32 max_busy_timeout = 0;
17338266c585SLudovic Barre 
17348266c585SLudovic Barre 	if (!host->variant->busy_detect)
17358266c585SLudovic Barre 		return;
17368266c585SLudovic Barre 
17378266c585SLudovic Barre 	if (host->variant->busy_timeout && mmc->actual_clock)
17388266c585SLudovic Barre 		max_busy_timeout = ~0UL / (mmc->actual_clock / MSEC_PER_SEC);
17398266c585SLudovic Barre 
17408266c585SLudovic Barre 	mmc->max_busy_timeout = max_busy_timeout;
17418266c585SLudovic Barre }
17428266c585SLudovic Barre 
17431c6a0718SPierre Ossman static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
17441c6a0718SPierre Ossman {
17451c6a0718SPierre Ossman 	struct mmci_host *host = mmc_priv(mmc);
17467d72a1d4SUlf Hansson 	struct variant_data *variant = host->variant;
1747a6a6464aSLinus Walleij 	u32 pwr = 0;
1748a6a6464aSLinus Walleij 	unsigned long flags;
1749db90f91fSLee Jones 	int ret;
17501c6a0718SPierre Ossman 
17511c6a0718SPierre Ossman 	switch (ios->power_mode) {
17521c6a0718SPierre Ossman 	case MMC_POWER_OFF:
1753599c1d5cSUlf Hansson 		if (!IS_ERR(mmc->supply.vmmc))
1754599c1d5cSUlf Hansson 			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
1755237fb5e6SLee Jones 
17567c0136efSUlf Hansson 		if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) {
1757237fb5e6SLee Jones 			regulator_disable(mmc->supply.vqmmc);
17587c0136efSUlf Hansson 			host->vqmmc_enabled = false;
17597c0136efSUlf Hansson 		}
1760237fb5e6SLee Jones 
17611c6a0718SPierre Ossman 		break;
17621c6a0718SPierre Ossman 	case MMC_POWER_UP:
1763599c1d5cSUlf Hansson 		if (!IS_ERR(mmc->supply.vmmc))
1764599c1d5cSUlf Hansson 			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
1765599c1d5cSUlf Hansson 
17667d72a1d4SUlf Hansson 		/*
17677d72a1d4SUlf Hansson 		 * The ST Micro variant doesn't have the PL180s MCI_PWR_UP
17687d72a1d4SUlf Hansson 		 * and instead uses MCI_PWR_ON so apply whatever value is
17697d72a1d4SUlf Hansson 		 * configured in the variant data.
17707d72a1d4SUlf Hansson 		 */
17717d72a1d4SUlf Hansson 		pwr |= variant->pwrreg_powerup;
17727d72a1d4SUlf Hansson 
17731c6a0718SPierre Ossman 		break;
17741c6a0718SPierre Ossman 	case MMC_POWER_ON:
17757c0136efSUlf Hansson 		if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) {
1776db90f91fSLee Jones 			ret = regulator_enable(mmc->supply.vqmmc);
1777db90f91fSLee Jones 			if (ret < 0)
1778db90f91fSLee Jones 				dev_err(mmc_dev(mmc),
1779db90f91fSLee Jones 					"failed to enable vqmmc regulator\n");
17807c0136efSUlf Hansson 			else
17817c0136efSUlf Hansson 				host->vqmmc_enabled = true;
1782db90f91fSLee Jones 		}
1783237fb5e6SLee Jones 
17841c6a0718SPierre Ossman 		pwr |= MCI_PWR_ON;
17851c6a0718SPierre Ossman 		break;
17861c6a0718SPierre Ossman 	}
17871c6a0718SPierre Ossman 
17884d1a3a0dSUlf Hansson 	if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) {
17894d1a3a0dSUlf Hansson 		/*
17904d1a3a0dSUlf Hansson 		 * The ST Micro variant has some additional bits
17914d1a3a0dSUlf Hansson 		 * indicating signal direction for the signals in
17924d1a3a0dSUlf Hansson 		 * the SD/MMC bus and feedback-clock usage.
17934d1a3a0dSUlf Hansson 		 */
17944593df29SUlf Hansson 		pwr |= host->pwr_reg_add;
17954d1a3a0dSUlf Hansson 
17964d1a3a0dSUlf Hansson 		if (ios->bus_width == MMC_BUS_WIDTH_4)
17974d1a3a0dSUlf Hansson 			pwr &= ~MCI_ST_DATA74DIREN;
17984d1a3a0dSUlf Hansson 		else if (ios->bus_width == MMC_BUS_WIDTH_1)
17994d1a3a0dSUlf Hansson 			pwr &= (~MCI_ST_DATA74DIREN &
18004d1a3a0dSUlf Hansson 				~MCI_ST_DATA31DIREN &
18014d1a3a0dSUlf Hansson 				~MCI_ST_DATA2DIREN);
18024d1a3a0dSUlf Hansson 	}
18034d1a3a0dSUlf Hansson 
1804f9bb304cSPatrice Chotard 	if (variant->opendrain) {
1805f9bb304cSPatrice Chotard 		if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
180611dfb970SPatrice Chotard 			pwr |= variant->opendrain;
1807f9bb304cSPatrice Chotard 	} else {
1808f9bb304cSPatrice Chotard 		/*
1809f9bb304cSPatrice Chotard 		 * If the variant cannot configure the pads by its own, then we
1810f9bb304cSPatrice Chotard 		 * expect the pinctrl to be able to do that for us
1811f9bb304cSPatrice Chotard 		 */
1812f9bb304cSPatrice Chotard 		if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
1813f9bb304cSPatrice Chotard 			pinctrl_select_state(host->pinctrl, host->pins_opendrain);
1814f9bb304cSPatrice Chotard 		else
181505344ffeSUlf Hansson 			pinctrl_select_default_state(mmc_dev(mmc));
1816f9bb304cSPatrice Chotard 	}
18171c6a0718SPierre Ossman 
1818f4670daeSUlf Hansson 	/*
1819f4670daeSUlf Hansson 	 * If clock = 0 and the variant requires the MMCIPOWER to be used for
1820f4670daeSUlf Hansson 	 * gating the clock, the MCI_PWR_ON bit is cleared.
1821f4670daeSUlf Hansson 	 */
1822f4670daeSUlf Hansson 	if (!ios->clock && variant->pwrreg_clkgate)
1823f4670daeSUlf Hansson 		pwr &= ~MCI_PWR_ON;
1824f4670daeSUlf Hansson 
18253f4e6f7bSSrinivas Kandagatla 	if (host->variant->explicit_mclk_control &&
18263f4e6f7bSSrinivas Kandagatla 	    ios->clock != host->clock_cache) {
18273f4e6f7bSSrinivas Kandagatla 		ret = clk_set_rate(host->clk, ios->clock);
18283f4e6f7bSSrinivas Kandagatla 		if (ret < 0)
18293f4e6f7bSSrinivas Kandagatla 			dev_err(mmc_dev(host->mmc),
18303f4e6f7bSSrinivas Kandagatla 				"Error setting clock rate (%d)\n", ret);
18313f4e6f7bSSrinivas Kandagatla 		else
18323f4e6f7bSSrinivas Kandagatla 			host->mclk = clk_get_rate(host->clk);
18333f4e6f7bSSrinivas Kandagatla 	}
18343f4e6f7bSSrinivas Kandagatla 	host->clock_cache = ios->clock;
18353f4e6f7bSSrinivas Kandagatla 
1836a6a6464aSLinus Walleij 	spin_lock_irqsave(&host->lock, flags);
1837a6a6464aSLinus Walleij 
1838cd3ee8c5SLudovic Barre 	if (host->ops && host->ops->set_clkreg)
1839cd3ee8c5SLudovic Barre 		host->ops->set_clkreg(host, ios->clock);
1840cd3ee8c5SLudovic Barre 	else
1841a6a6464aSLinus Walleij 		mmci_set_clkreg(host, ios->clock);
1842cd3ee8c5SLudovic Barre 
18438266c585SLudovic Barre 	mmci_set_max_busy_timeout(mmc);
18448266c585SLudovic Barre 
1845cd3ee8c5SLudovic Barre 	if (host->ops && host->ops->set_pwrreg)
1846cd3ee8c5SLudovic Barre 		host->ops->set_pwrreg(host, pwr);
1847cd3ee8c5SLudovic Barre 	else
18487437cfa5SUlf Hansson 		mmci_write_pwrreg(host, pwr);
1849cd3ee8c5SLudovic Barre 
1850f829c042SUlf Hansson 	mmci_reg_delay(host);
1851a6a6464aSLinus Walleij 
1852a6a6464aSLinus Walleij 	spin_unlock_irqrestore(&host->lock, flags);
18531c6a0718SPierre Ossman }
18541c6a0718SPierre Ossman 
185589001446SRussell King static int mmci_get_cd(struct mmc_host *mmc)
185689001446SRussell King {
185789001446SRussell King 	struct mmci_host *host = mmc_priv(mmc);
185829719445SRabin Vincent 	struct mmci_platform_data *plat = host->plat;
1859d2762090SUlf Hansson 	unsigned int status = mmc_gpio_get_cd(mmc);
186089001446SRussell King 
1861d2762090SUlf Hansson 	if (status == -ENOSYS) {
18624b8caec0SRabin Vincent 		if (!plat->status)
18634b8caec0SRabin Vincent 			return 1; /* Assume always present */
18644b8caec0SRabin Vincent 
186529719445SRabin Vincent 		status = plat->status(mmc_dev(host->mmc));
1866d2762090SUlf Hansson 	}
186774bc8093SRussell King 	return status;
186889001446SRussell King }
186989001446SRussell King 
18700f3ed7f7SUlf Hansson static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios)
18710f3ed7f7SUlf Hansson {
187275773165SLudovic Barre 	struct mmci_host *host = mmc_priv(mmc);
18733e09a81eSMarek Vasut 	int ret;
18740f3ed7f7SUlf Hansson 
18753e09a81eSMarek Vasut 	ret = mmc_regulator_set_vqmmc(mmc, ios);
18760f3ed7f7SUlf Hansson 
187775773165SLudovic Barre 	if (!ret && host->ops && host->ops->post_sig_volt_switch)
187875773165SLudovic Barre 		ret = host->ops->post_sig_volt_switch(host, ios);
18793e09a81eSMarek Vasut 	else if (ret)
18803e09a81eSMarek Vasut 		ret = 0;
188175773165SLudovic Barre 
18823e09a81eSMarek Vasut 	if (ret < 0)
18830f3ed7f7SUlf Hansson 		dev_warn(mmc_dev(mmc), "Voltage switch failed\n");
18840f3ed7f7SUlf Hansson 
18850f3ed7f7SUlf Hansson 	return ret;
18860f3ed7f7SUlf Hansson }
18870f3ed7f7SUlf Hansson 
188801259620SUlf Hansson static struct mmc_host_ops mmci_ops = {
18891c6a0718SPierre Ossman 	.request	= mmci_request,
189058c7ccbfSPer Forlin 	.pre_req	= mmci_pre_request,
189158c7ccbfSPer Forlin 	.post_req	= mmci_post_request,
18921c6a0718SPierre Ossman 	.set_ios	= mmci_set_ios,
1893d2762090SUlf Hansson 	.get_ro		= mmc_gpio_get_ro,
189489001446SRussell King 	.get_cd		= mmci_get_cd,
18950f3ed7f7SUlf Hansson 	.start_signal_voltage_switch = mmci_sig_volt_switch,
18961c6a0718SPierre Ossman };
18971c6a0718SPierre Ossman 
18986351cac9SMarek Vasut static void mmci_probe_level_translator(struct mmc_host *mmc)
18996351cac9SMarek Vasut {
19006351cac9SMarek Vasut 	struct device *dev = mmc_dev(mmc);
19016351cac9SMarek Vasut 	struct mmci_host *host = mmc_priv(mmc);
19026351cac9SMarek Vasut 	struct gpio_desc *cmd_gpio;
19036351cac9SMarek Vasut 	struct gpio_desc *ck_gpio;
19046351cac9SMarek Vasut 	struct gpio_desc *ckin_gpio;
19056351cac9SMarek Vasut 	int clk_hi, clk_lo;
19066351cac9SMarek Vasut 
19076351cac9SMarek Vasut 	/*
19086351cac9SMarek Vasut 	 * Assume the level translator is present if st,use-ckin is set.
19096351cac9SMarek Vasut 	 * This is to cater for DTs which do not implement this test.
19106351cac9SMarek Vasut 	 */
19116351cac9SMarek Vasut 	host->clk_reg_add |= MCI_STM32_CLK_SELCKIN;
19126351cac9SMarek Vasut 
19136351cac9SMarek Vasut 	cmd_gpio = gpiod_get(dev, "st,cmd", GPIOD_OUT_HIGH);
19146351cac9SMarek Vasut 	if (IS_ERR(cmd_gpio))
19156351cac9SMarek Vasut 		goto exit_cmd;
19166351cac9SMarek Vasut 
19176351cac9SMarek Vasut 	ck_gpio = gpiod_get(dev, "st,ck", GPIOD_OUT_HIGH);
19186351cac9SMarek Vasut 	if (IS_ERR(ck_gpio))
19196351cac9SMarek Vasut 		goto exit_ck;
19206351cac9SMarek Vasut 
19216351cac9SMarek Vasut 	ckin_gpio = gpiod_get(dev, "st,ckin", GPIOD_IN);
19226351cac9SMarek Vasut 	if (IS_ERR(ckin_gpio))
19236351cac9SMarek Vasut 		goto exit_ckin;
19246351cac9SMarek Vasut 
19256351cac9SMarek Vasut 	/* All GPIOs are valid, test whether level translator works */
19266351cac9SMarek Vasut 
19276351cac9SMarek Vasut 	/* Sample CKIN */
19286351cac9SMarek Vasut 	clk_hi = !!gpiod_get_value(ckin_gpio);
19296351cac9SMarek Vasut 
19306351cac9SMarek Vasut 	/* Set CK low */
19316351cac9SMarek Vasut 	gpiod_set_value(ck_gpio, 0);
19326351cac9SMarek Vasut 
19336351cac9SMarek Vasut 	/* Sample CKIN */
19346351cac9SMarek Vasut 	clk_lo = !!gpiod_get_value(ckin_gpio);
19356351cac9SMarek Vasut 
19366351cac9SMarek Vasut 	/* Tristate all */
19376351cac9SMarek Vasut 	gpiod_direction_input(cmd_gpio);
19386351cac9SMarek Vasut 	gpiod_direction_input(ck_gpio);
19396351cac9SMarek Vasut 
19406351cac9SMarek Vasut 	/* Level translator is present if CK signal is propagated to CKIN */
19416351cac9SMarek Vasut 	if (!clk_hi || clk_lo) {
19426351cac9SMarek Vasut 		host->clk_reg_add &= ~MCI_STM32_CLK_SELCKIN;
19436351cac9SMarek Vasut 		dev_warn(dev,
19446351cac9SMarek Vasut 			 "Level translator inoperable, CK signal not detected on CKIN, disabling.\n");
19456351cac9SMarek Vasut 	}
19466351cac9SMarek Vasut 
19476351cac9SMarek Vasut 	gpiod_put(ckin_gpio);
19486351cac9SMarek Vasut 
19496351cac9SMarek Vasut exit_ckin:
19506351cac9SMarek Vasut 	gpiod_put(ck_gpio);
19516351cac9SMarek Vasut exit_ck:
19526351cac9SMarek Vasut 	gpiod_put(cmd_gpio);
19536351cac9SMarek Vasut exit_cmd:
19546351cac9SMarek Vasut 	pinctrl_select_default_state(dev);
19556351cac9SMarek Vasut }
19566351cac9SMarek Vasut 
195778f87df2SUlf Hansson static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc)
195878f87df2SUlf Hansson {
19594593df29SUlf Hansson 	struct mmci_host *host = mmc_priv(mmc);
196078f87df2SUlf Hansson 	int ret = mmc_of_parse(mmc);
1961000bc9d5SLee Jones 
196278f87df2SUlf Hansson 	if (ret)
196378f87df2SUlf Hansson 		return ret;
1964000bc9d5SLee Jones 
1965*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir-dat0"))
19664593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_DATA0DIREN;
1967*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir-dat2"))
19684593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_DATA2DIREN;
1969*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir-dat31"))
19704593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_DATA31DIREN;
1971*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir-dat74"))
19724593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_DATA74DIREN;
1973*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir-cmd"))
19744593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_CMDDIREN;
1975*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-pin-fbclk"))
19764593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_FBCLKEN;
1977*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir"))
197846b723ddSLudovic Barre 		host->pwr_reg_add |= MCI_STM32_DIRPOL;
1979*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,neg-edge"))
198046b723ddSLudovic Barre 		host->clk_reg_add |= MCI_STM32_CLK_NEGEDGE;
1981*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,use-ckin"))
19826351cac9SMarek Vasut 		mmci_probe_level_translator(mmc);
19834593df29SUlf Hansson 
1984*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "mmc-cap-mmc-highspeed"))
198578f87df2SUlf Hansson 		mmc->caps |= MMC_CAP_MMC_HIGHSPEED;
1986*ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "mmc-cap-sd-highspeed"))
198778f87df2SUlf Hansson 		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
1988000bc9d5SLee Jones 
198978f87df2SUlf Hansson 	return 0;
1990000bc9d5SLee Jones }
1991000bc9d5SLee Jones 
1992c3be1efdSBill Pemberton static int mmci_probe(struct amba_device *dev,
1993aa25afadSRussell King 	const struct amba_id *id)
19941c6a0718SPierre Ossman {
19956ef297f8SLinus Walleij 	struct mmci_platform_data *plat = dev->dev.platform_data;
1996000bc9d5SLee Jones 	struct device_node *np = dev->dev.of_node;
19974956e109SRabin Vincent 	struct variant_data *variant = id->data;
19981c6a0718SPierre Ossman 	struct mmci_host *host;
19991c6a0718SPierre Ossman 	struct mmc_host *mmc;
20001c6a0718SPierre Ossman 	int ret;
20011c6a0718SPierre Ossman 
2002000bc9d5SLee Jones 	/* Must have platform data or Device Tree. */
2003000bc9d5SLee Jones 	if (!plat && !np) {
2004000bc9d5SLee Jones 		dev_err(&dev->dev, "No plat data or DT found\n");
2005000bc9d5SLee Jones 		return -EINVAL;
20061c6a0718SPierre Ossman 	}
20071c6a0718SPierre Ossman 
2008b9b52918SLee Jones 	if (!plat) {
2009b9b52918SLee Jones 		plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL);
2010b9b52918SLee Jones 		if (!plat)
2011b9b52918SLee Jones 			return -ENOMEM;
2012b9b52918SLee Jones 	}
2013b9b52918SLee Jones 
20141c6a0718SPierre Ossman 	mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);
2015ef289982SUlf Hansson 	if (!mmc)
2016ef289982SUlf Hansson 		return -ENOMEM;
20171c6a0718SPierre Ossman 
20181c6a0718SPierre Ossman 	host = mmc_priv(mmc);
20194ea580f1SRabin Vincent 	host->mmc = mmc;
20207b9716a0SLudovic Barre 	host->mmc_ops = &mmci_ops;
20217b9716a0SLudovic Barre 	mmc->ops = &mmci_ops;
2022012b7d33SRussell King 
20236351cac9SMarek Vasut 	ret = mmci_of_parse(np, mmc);
20246351cac9SMarek Vasut 	if (ret)
20256351cac9SMarek Vasut 		goto host_free;
20266351cac9SMarek Vasut 
2027f9bb304cSPatrice Chotard 	/*
2028f9bb304cSPatrice Chotard 	 * Some variant (STM32) doesn't have opendrain bit, nevertheless
2029f9bb304cSPatrice Chotard 	 * pins can be set accordingly using pinctrl
2030f9bb304cSPatrice Chotard 	 */
2031f9bb304cSPatrice Chotard 	if (!variant->opendrain) {
2032f9bb304cSPatrice Chotard 		host->pinctrl = devm_pinctrl_get(&dev->dev);
2033f9bb304cSPatrice Chotard 		if (IS_ERR(host->pinctrl)) {
2034f9bb304cSPatrice Chotard 			dev_err(&dev->dev, "failed to get pinctrl");
2035310eb252SWei Yongjun 			ret = PTR_ERR(host->pinctrl);
2036f9bb304cSPatrice Chotard 			goto host_free;
2037f9bb304cSPatrice Chotard 		}
2038f9bb304cSPatrice Chotard 
2039f9bb304cSPatrice Chotard 		host->pins_opendrain = pinctrl_lookup_state(host->pinctrl,
2040f9bb304cSPatrice Chotard 							    MMCI_PINCTRL_STATE_OPENDRAIN);
2041f9bb304cSPatrice Chotard 		if (IS_ERR(host->pins_opendrain)) {
2042f9bb304cSPatrice Chotard 			dev_err(mmc_dev(mmc), "Can't select opendrain pins\n");
2043310eb252SWei Yongjun 			ret = PTR_ERR(host->pins_opendrain);
2044f9bb304cSPatrice Chotard 			goto host_free;
2045f9bb304cSPatrice Chotard 		}
2046f9bb304cSPatrice Chotard 	}
2047f9bb304cSPatrice Chotard 
2048012b7d33SRussell King 	host->hw_designer = amba_manf(dev);
2049012b7d33SRussell King 	host->hw_revision = amba_rev(dev);
205064de0289SLinus Walleij 	dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
205164de0289SLinus Walleij 	dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision);
2052012b7d33SRussell King 
2053665ba56fSUlf Hansson 	host->clk = devm_clk_get(&dev->dev, NULL);
20541c6a0718SPierre Ossman 	if (IS_ERR(host->clk)) {
20551c6a0718SPierre Ossman 		ret = PTR_ERR(host->clk);
20561c6a0718SPierre Ossman 		goto host_free;
20571c6a0718SPierre Ossman 	}
20581c6a0718SPierre Ossman 
2059ac940938SJulia Lawall 	ret = clk_prepare_enable(host->clk);
20601c6a0718SPierre Ossman 	if (ret)
2061665ba56fSUlf Hansson 		goto host_free;
20621c6a0718SPierre Ossman 
20639c34b73dSSrinivas Kandagatla 	if (variant->qcom_fifo)
20649c34b73dSSrinivas Kandagatla 		host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt;
20659c34b73dSSrinivas Kandagatla 	else
20669c34b73dSSrinivas Kandagatla 		host->get_rx_fifocnt = mmci_get_rx_fifocnt;
20679c34b73dSSrinivas Kandagatla 
20681c6a0718SPierre Ossman 	host->plat = plat;
20694956e109SRabin Vincent 	host->variant = variant;
20701c6a0718SPierre Ossman 	host->mclk = clk_get_rate(host->clk);
2071c8df9a53SLinus Walleij 	/*
2072c8df9a53SLinus Walleij 	 * According to the spec, mclk is max 100 MHz,
2073c8df9a53SLinus Walleij 	 * so we try to adjust the clock down to this,
2074c8df9a53SLinus Walleij 	 * (if possible).
2075c8df9a53SLinus Walleij 	 */
2076dc6500bfSSrinivas Kandagatla 	if (host->mclk > variant->f_max) {
2077dc6500bfSSrinivas Kandagatla 		ret = clk_set_rate(host->clk, variant->f_max);
2078c8df9a53SLinus Walleij 		if (ret < 0)
2079c8df9a53SLinus Walleij 			goto clk_disable;
2080c8df9a53SLinus Walleij 		host->mclk = clk_get_rate(host->clk);
208164de0289SLinus Walleij 		dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n",
208264de0289SLinus Walleij 			host->mclk);
2083c8df9a53SLinus Walleij 	}
2084ef289982SUlf Hansson 
2085c8ebae37SRussell King 	host->phybase = dev->res.start;
2086ef289982SUlf Hansson 	host->base = devm_ioremap_resource(&dev->dev, &dev->res);
2087ef289982SUlf Hansson 	if (IS_ERR(host->base)) {
2088ef289982SUlf Hansson 		ret = PTR_ERR(host->base);
20891c6a0718SPierre Ossman 		goto clk_disable;
20901c6a0718SPierre Ossman 	}
20911c6a0718SPierre Ossman 
2092ed9067fdSUlf Hansson 	if (variant->init)
2093ed9067fdSUlf Hansson 		variant->init(host);
2094ed9067fdSUlf Hansson 
20957f294e49SLinus Walleij 	/*
20967f294e49SLinus Walleij 	 * The ARM and ST versions of the block have slightly different
20977f294e49SLinus Walleij 	 * clock divider equations which means that the minimum divider
20987f294e49SLinus Walleij 	 * differs too.
20993f4e6f7bSSrinivas Kandagatla 	 * on Qualcomm like controllers get the nearest minimum clock to 100Khz
21007f294e49SLinus Walleij 	 */
21017f294e49SLinus Walleij 	if (variant->st_clkdiv)
21027f294e49SLinus Walleij 		mmc->f_min = DIV_ROUND_UP(host->mclk, 257);
210300e930d8SLudovic Barre 	else if (variant->stm32_clkdiv)
210400e930d8SLudovic Barre 		mmc->f_min = DIV_ROUND_UP(host->mclk, 2046);
21053f4e6f7bSSrinivas Kandagatla 	else if (variant->explicit_mclk_control)
21063f4e6f7bSSrinivas Kandagatla 		mmc->f_min = clk_round_rate(host->clk, 100000);
21077f294e49SLinus Walleij 	else
21087f294e49SLinus Walleij 		mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
2109808d97ccSLinus Walleij 	/*
211078f87df2SUlf Hansson 	 * If no maximum operating frequency is supplied, fall back to use
211178f87df2SUlf Hansson 	 * the module parameter, which has a (low) default value in case it
211278f87df2SUlf Hansson 	 * is not specified. Either value must not exceed the clock rate into
21135080a08dSUlf Hansson 	 * the block, of course.
2114808d97ccSLinus Walleij 	 */
211578f87df2SUlf Hansson 	if (mmc->f_max)
21163f4e6f7bSSrinivas Kandagatla 		mmc->f_max = variant->explicit_mclk_control ?
21173f4e6f7bSSrinivas Kandagatla 				min(variant->f_max, mmc->f_max) :
21183f4e6f7bSSrinivas Kandagatla 				min(host->mclk, mmc->f_max);
2119808d97ccSLinus Walleij 	else
21203f4e6f7bSSrinivas Kandagatla 		mmc->f_max = variant->explicit_mclk_control ?
21213f4e6f7bSSrinivas Kandagatla 				fmax : min(host->mclk, fmax);
21223f4e6f7bSSrinivas Kandagatla 
21233f4e6f7bSSrinivas Kandagatla 
212464de0289SLinus Walleij 	dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
212564de0289SLinus Walleij 
212615878e58SLudovic Barre 	host->rst = devm_reset_control_get_optional_exclusive(&dev->dev, NULL);
212715878e58SLudovic Barre 	if (IS_ERR(host->rst)) {
212815878e58SLudovic Barre 		ret = PTR_ERR(host->rst);
212915878e58SLudovic Barre 		goto clk_disable;
213015878e58SLudovic Barre 	}
2131575cf104SLinus Walleij 	ret = reset_control_deassert(host->rst);
2132575cf104SLinus Walleij 	if (ret)
2133575cf104SLinus Walleij 		dev_err(mmc_dev(mmc), "failed to de-assert reset\n");
213415878e58SLudovic Barre 
2135599c1d5cSUlf Hansson 	/* Get regulators and the supported OCR mask */
21369369c97cSBjorn Andersson 	ret = mmc_regulator_get_supply(mmc);
213751006952SWolfram Sang 	if (ret)
21389369c97cSBjorn Andersson 		goto clk_disable;
21399369c97cSBjorn Andersson 
2140599c1d5cSUlf Hansson 	if (!mmc->ocr_avail)
21411c6a0718SPierre Ossman 		mmc->ocr_avail = plat->ocr_mask;
2142599c1d5cSUlf Hansson 	else if (plat->ocr_mask)
2143599c1d5cSUlf Hansson 		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
2144599c1d5cSUlf Hansson 
21459dd8a8b8SUlf Hansson 	/* We support these capabilities. */
21469dd8a8b8SUlf Hansson 	mmc->caps |= MMC_CAP_CMD23;
21479dd8a8b8SUlf Hansson 
214849adc0caSLinus Walleij 	/*
214949adc0caSLinus Walleij 	 * Enable busy detection.
215049adc0caSLinus Walleij 	 */
21518d94b54dSUlf Hansson 	if (variant->busy_detect) {
21528d94b54dSUlf Hansson 		mmci_ops.card_busy = mmci_card_busy;
215349adc0caSLinus Walleij 		/*
215449adc0caSLinus Walleij 		 * Not all variants have a flag to enable busy detection
215549adc0caSLinus Walleij 		 * in the DPSM, but if they do, set it here.
215649adc0caSLinus Walleij 		 */
215749adc0caSLinus Walleij 		if (variant->busy_dpsm_flag)
215849adc0caSLinus Walleij 			mmci_write_datactrlreg(host,
215949adc0caSLinus Walleij 					       host->variant->busy_dpsm_flag);
21608d94b54dSUlf Hansson 		mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
21618d94b54dSUlf Hansson 	}
21628d94b54dSUlf Hansson 
2163774514bfSYann Gautier 	/* Variants with mandatory busy timeout in HW needs R1B responses. */
2164774514bfSYann Gautier 	if (variant->busy_timeout)
2165774514bfSYann Gautier 		mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
2166774514bfSYann Gautier 
2167e9968c6fSUlf Hansson 	/* Prepare a CMD12 - needed to clear the DPSM on some variants. */
2168e9968c6fSUlf Hansson 	host->stop_abort.opcode = MMC_STOP_TRANSMISSION;
2169e9968c6fSUlf Hansson 	host->stop_abort.arg = 0;
2170e9968c6fSUlf Hansson 	host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC;
2171e9968c6fSUlf Hansson 
217270be208fSUlf Hansson 	/* We support these PM capabilities. */
217378f87df2SUlf Hansson 	mmc->pm_caps |= MMC_PM_KEEP_POWER;
217470be208fSUlf Hansson 
21751c6a0718SPierre Ossman 	/*
21761c6a0718SPierre Ossman 	 * We can do SGIO
21771c6a0718SPierre Ossman 	 */
2178a36274e0SMartin K. Petersen 	mmc->max_segs = NR_SG;
21791c6a0718SPierre Ossman 
21801c6a0718SPierre Ossman 	/*
218108458ef6SRabin Vincent 	 * Since only a certain number of bits are valid in the data length
218208458ef6SRabin Vincent 	 * register, we must ensure that we don't exceed 2^num-1 bytes in a
218308458ef6SRabin Vincent 	 * single request.
21841c6a0718SPierre Ossman 	 */
218508458ef6SRabin Vincent 	mmc->max_req_size = (1 << variant->datalength_bits) - 1;
21861c6a0718SPierre Ossman 
21871c6a0718SPierre Ossman 	/*
21881c6a0718SPierre Ossman 	 * Set the maximum segment size.  Since we aren't doing DMA
21891c6a0718SPierre Ossman 	 * (yet) we are only limited by the data length register.
21901c6a0718SPierre Ossman 	 */
21911c6a0718SPierre Ossman 	mmc->max_seg_size = mmc->max_req_size;
21921c6a0718SPierre Ossman 
21931c6a0718SPierre Ossman 	/*
21941c6a0718SPierre Ossman 	 * Block size can be up to 2048 bytes, but must be a power of two.
21951c6a0718SPierre Ossman 	 */
2196c931d495SLudovic Barre 	mmc->max_blk_size = 1 << variant->datactrl_blocksz;
21971c6a0718SPierre Ossman 
21981c6a0718SPierre Ossman 	/*
21998f7f6b7eSWill Deacon 	 * Limit the number of blocks transferred so that we don't overflow
22008f7f6b7eSWill Deacon 	 * the maximum request size.
22011c6a0718SPierre Ossman 	 */
2202c931d495SLudovic Barre 	mmc->max_blk_count = mmc->max_req_size >> variant->datactrl_blocksz;
22031c6a0718SPierre Ossman 
22041c6a0718SPierre Ossman 	spin_lock_init(&host->lock);
22051c6a0718SPierre Ossman 
22061c6a0718SPierre Ossman 	writel(0, host->base + MMCIMASK0);
22076ea9cdf3SPatrice Chotard 
22086ea9cdf3SPatrice Chotard 	if (variant->mmcimask1)
22091c6a0718SPierre Ossman 		writel(0, host->base + MMCIMASK1);
22106ea9cdf3SPatrice Chotard 
22111c6a0718SPierre Ossman 	writel(0xfff, host->base + MMCICLEAR);
22121c6a0718SPierre Ossman 
2213ce437aa4SLinus Walleij 	/*
2214ce437aa4SLinus Walleij 	 * If:
2215ce437aa4SLinus Walleij 	 * - not using DT but using a descriptor table, or
2216ce437aa4SLinus Walleij 	 * - using a table of descriptors ALONGSIDE DT, or
2217ce437aa4SLinus Walleij 	 * look up these descriptors named "cd" and "wp" right here, fail
22189ef986a6SLinus Walleij 	 * silently of these do not exist
2219ce437aa4SLinus Walleij 	 */
2220ce437aa4SLinus Walleij 	if (!np) {
2221d0052ad9SMichał Mirosław 		ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0);
2222ce437aa4SLinus Walleij 		if (ret == -EPROBE_DEFER)
2223ce437aa4SLinus Walleij 			goto clk_disable;
2224ce437aa4SLinus Walleij 
2225d0052ad9SMichał Mirosław 		ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0);
2226ce437aa4SLinus Walleij 		if (ret == -EPROBE_DEFER)
2227ce437aa4SLinus Walleij 			goto clk_disable;
2228ce437aa4SLinus Walleij 	}
222989001446SRussell King 
2230ee157abeSLudovic Barre 	ret = devm_request_threaded_irq(&dev->dev, dev->irq[0], mmci_irq,
2231ee157abeSLudovic Barre 					mmci_irq_thread, IRQF_SHARED,
2232ef289982SUlf Hansson 					DRIVER_NAME " (cmd)", host);
22331c6a0718SPierre Ossman 	if (ret)
2234ef289982SUlf Hansson 		goto clk_disable;
22351c6a0718SPierre Ossman 
2236dfb85185SRussell King 	if (!dev->irq[1])
22372686b4b4SLinus Walleij 		host->singleirq = true;
22382686b4b4SLinus Walleij 	else {
2239ef289982SUlf Hansson 		ret = devm_request_irq(&dev->dev, dev->irq[1], mmci_pio_irq,
2240ef289982SUlf Hansson 				IRQF_SHARED, DRIVER_NAME " (pio)", host);
22411c6a0718SPierre Ossman 		if (ret)
2242ef289982SUlf Hansson 			goto clk_disable;
22432686b4b4SLinus Walleij 	}
22441c6a0718SPierre Ossman 
2245daf9713cSLudovic Barre 	writel(MCI_IRQENABLE | variant->start_err, host->base + MMCIMASK0);
22461c6a0718SPierre Ossman 
22471c6a0718SPierre Ossman 	amba_set_drvdata(dev, mmc);
22481c6a0718SPierre Ossman 
2249c8ebae37SRussell King 	dev_info(&dev->dev, "%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n",
2250c8ebae37SRussell King 		 mmc_hostname(mmc), amba_part(dev), amba_manf(dev),
2251c8ebae37SRussell King 		 amba_rev(dev), (unsigned long long)dev->res.start,
2252c8ebae37SRussell King 		 dev->irq[0], dev->irq[1]);
2253c8ebae37SRussell King 
2254c8ebae37SRussell King 	mmci_dma_setup(host);
22551c6a0718SPierre Ossman 
22562cd976c4SUlf Hansson 	pm_runtime_set_autosuspend_delay(&dev->dev, 50);
22572cd976c4SUlf Hansson 	pm_runtime_use_autosuspend(&dev->dev);
22581c3be369SRussell King 
2259b38a20f2SYang Yingliang 	ret = mmc_add_host(mmc);
2260b38a20f2SYang Yingliang 	if (ret)
2261b38a20f2SYang Yingliang 		goto clk_disable;
22628c11a94dSRussell King 
22636f2d3c89SUlf Hansson 	pm_runtime_put(&dev->dev);
22641c6a0718SPierre Ossman 	return 0;
22651c6a0718SPierre Ossman 
22661c6a0718SPierre Ossman  clk_disable:
2267ac940938SJulia Lawall 	clk_disable_unprepare(host->clk);
22681c6a0718SPierre Ossman  host_free:
22691c6a0718SPierre Ossman 	mmc_free_host(mmc);
22701c6a0718SPierre Ossman 	return ret;
22711c6a0718SPierre Ossman }
22721c6a0718SPierre Ossman 
22733fd269e7SUwe Kleine-König static void mmci_remove(struct amba_device *dev)
22741c6a0718SPierre Ossman {
22751c6a0718SPierre Ossman 	struct mmc_host *mmc = amba_get_drvdata(dev);
22761c6a0718SPierre Ossman 
22771c6a0718SPierre Ossman 	if (mmc) {
22781c6a0718SPierre Ossman 		struct mmci_host *host = mmc_priv(mmc);
22796ea9cdf3SPatrice Chotard 		struct variant_data *variant = host->variant;
22801c6a0718SPierre Ossman 
22811c3be369SRussell King 		/*
22821c3be369SRussell King 		 * Undo pm_runtime_put() in probe.  We use the _sync
22831c3be369SRussell King 		 * version here so that we can access the primecell.
22841c3be369SRussell King 		 */
22851c3be369SRussell King 		pm_runtime_get_sync(&dev->dev);
22861c3be369SRussell King 
22871c6a0718SPierre Ossman 		mmc_remove_host(mmc);
22881c6a0718SPierre Ossman 
22891c6a0718SPierre Ossman 		writel(0, host->base + MMCIMASK0);
22906ea9cdf3SPatrice Chotard 
22916ea9cdf3SPatrice Chotard 		if (variant->mmcimask1)
22921c6a0718SPierre Ossman 			writel(0, host->base + MMCIMASK1);
22931c6a0718SPierre Ossman 
22941c6a0718SPierre Ossman 		writel(0, host->base + MMCICOMMAND);
22951c6a0718SPierre Ossman 		writel(0, host->base + MMCIDATACTRL);
22961c6a0718SPierre Ossman 
2297c8ebae37SRussell King 		mmci_dma_release(host);
2298ac940938SJulia Lawall 		clk_disable_unprepare(host->clk);
22991c6a0718SPierre Ossman 		mmc_free_host(mmc);
23001c6a0718SPierre Ossman 	}
23011c6a0718SPierre Ossman }
23021c6a0718SPierre Ossman 
2303571dce4fSUlf Hansson #ifdef CONFIG_PM
23041ff44433SUlf Hansson static void mmci_save(struct mmci_host *host)
23051ff44433SUlf Hansson {
23061ff44433SUlf Hansson 	unsigned long flags;
23071ff44433SUlf Hansson 
23081ff44433SUlf Hansson 	spin_lock_irqsave(&host->lock, flags);
23091ff44433SUlf Hansson 
23101ff44433SUlf Hansson 	writel(0, host->base + MMCIMASK0);
231142dcc89aSUlf Hansson 	if (host->variant->pwrreg_nopower) {
23121ff44433SUlf Hansson 		writel(0, host->base + MMCIDATACTRL);
23131ff44433SUlf Hansson 		writel(0, host->base + MMCIPOWER);
23141ff44433SUlf Hansson 		writel(0, host->base + MMCICLOCK);
231542dcc89aSUlf Hansson 	}
23161ff44433SUlf Hansson 	mmci_reg_delay(host);
23171ff44433SUlf Hansson 
23181ff44433SUlf Hansson 	spin_unlock_irqrestore(&host->lock, flags);
23191ff44433SUlf Hansson }
23201ff44433SUlf Hansson 
23211ff44433SUlf Hansson static void mmci_restore(struct mmci_host *host)
23221ff44433SUlf Hansson {
23231ff44433SUlf Hansson 	unsigned long flags;
23241ff44433SUlf Hansson 
23251ff44433SUlf Hansson 	spin_lock_irqsave(&host->lock, flags);
23261ff44433SUlf Hansson 
232742dcc89aSUlf Hansson 	if (host->variant->pwrreg_nopower) {
23281ff44433SUlf Hansson 		writel(host->clk_reg, host->base + MMCICLOCK);
23291ff44433SUlf Hansson 		writel(host->datactrl_reg, host->base + MMCIDATACTRL);
23301ff44433SUlf Hansson 		writel(host->pwr_reg, host->base + MMCIPOWER);
233142dcc89aSUlf Hansson 	}
2332daf9713cSLudovic Barre 	writel(MCI_IRQENABLE | host->variant->start_err,
2333daf9713cSLudovic Barre 	       host->base + MMCIMASK0);
23341ff44433SUlf Hansson 	mmci_reg_delay(host);
23351ff44433SUlf Hansson 
23361ff44433SUlf Hansson 	spin_unlock_irqrestore(&host->lock, flags);
23371ff44433SUlf Hansson }
23381ff44433SUlf Hansson 
23398259293aSUlf Hansson static int mmci_runtime_suspend(struct device *dev)
23408259293aSUlf Hansson {
23418259293aSUlf Hansson 	struct amba_device *adev = to_amba_device(dev);
23428259293aSUlf Hansson 	struct mmc_host *mmc = amba_get_drvdata(adev);
23438259293aSUlf Hansson 
23448259293aSUlf Hansson 	if (mmc) {
23458259293aSUlf Hansson 		struct mmci_host *host = mmc_priv(mmc);
2346e36bd9c6SUlf Hansson 		pinctrl_pm_select_sleep_state(dev);
23471ff44433SUlf Hansson 		mmci_save(host);
23488259293aSUlf Hansson 		clk_disable_unprepare(host->clk);
23498259293aSUlf Hansson 	}
23508259293aSUlf Hansson 
23518259293aSUlf Hansson 	return 0;
23528259293aSUlf Hansson }
23538259293aSUlf Hansson 
23548259293aSUlf Hansson static int mmci_runtime_resume(struct device *dev)
23558259293aSUlf Hansson {
23568259293aSUlf Hansson 	struct amba_device *adev = to_amba_device(dev);
23578259293aSUlf Hansson 	struct mmc_host *mmc = amba_get_drvdata(adev);
23588259293aSUlf Hansson 
23598259293aSUlf Hansson 	if (mmc) {
23608259293aSUlf Hansson 		struct mmci_host *host = mmc_priv(mmc);
23618259293aSUlf Hansson 		clk_prepare_enable(host->clk);
23621ff44433SUlf Hansson 		mmci_restore(host);
236305344ffeSUlf Hansson 		pinctrl_select_default_state(dev);
23648259293aSUlf Hansson 	}
23658259293aSUlf Hansson 
23668259293aSUlf Hansson 	return 0;
23678259293aSUlf Hansson }
23688259293aSUlf Hansson #endif
23698259293aSUlf Hansson 
237048fa7003SUlf Hansson static const struct dev_pm_ops mmci_dev_pm_ops = {
2371f3737fa3SUlf Hansson 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
2372f3737fa3SUlf Hansson 				pm_runtime_force_resume)
23736ed23b80SRafael J. Wysocki 	SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL)
237448fa7003SUlf Hansson };
237548fa7003SUlf Hansson 
237688411deaSArvind Yadav static const struct amba_id mmci_ids[] = {
23771c6a0718SPierre Ossman 	{
23781c6a0718SPierre Ossman 		.id	= 0x00041180,
2379768fbc18SPawel Moll 		.mask	= 0xff0fffff,
23804956e109SRabin Vincent 		.data	= &variant_arm,
23811c6a0718SPierre Ossman 	},
23821c6a0718SPierre Ossman 	{
2383768fbc18SPawel Moll 		.id	= 0x01041180,
2384768fbc18SPawel Moll 		.mask	= 0xff0fffff,
2385768fbc18SPawel Moll 		.data	= &variant_arm_extended_fifo,
2386768fbc18SPawel Moll 	},
2387768fbc18SPawel Moll 	{
23883a37298aSPawel Moll 		.id	= 0x02041180,
23893a37298aSPawel Moll 		.mask	= 0xff0fffff,
23903a37298aSPawel Moll 		.data	= &variant_arm_extended_fifo_hwfc,
23913a37298aSPawel Moll 	},
23923a37298aSPawel Moll 	{
23931c6a0718SPierre Ossman 		.id	= 0x00041181,
23941c6a0718SPierre Ossman 		.mask	= 0x000fffff,
23954956e109SRabin Vincent 		.data	= &variant_arm,
23961c6a0718SPierre Ossman 	},
2397cc30d60eSLinus Walleij 	/* ST Micro variants */
2398cc30d60eSLinus Walleij 	{
2399cc30d60eSLinus Walleij 		.id     = 0x00180180,
2400cc30d60eSLinus Walleij 		.mask   = 0x00ffffff,
24014956e109SRabin Vincent 		.data	= &variant_u300,
2402cc30d60eSLinus Walleij 	},
2403cc30d60eSLinus Walleij 	{
240434fd4213SLinus Walleij 		.id     = 0x10180180,
240534fd4213SLinus Walleij 		.mask   = 0xf0ffffff,
240634fd4213SLinus Walleij 		.data	= &variant_nomadik,
240734fd4213SLinus Walleij 	},
240834fd4213SLinus Walleij 	{
2409cc30d60eSLinus Walleij 		.id     = 0x00280180,
2410cc30d60eSLinus Walleij 		.mask   = 0x00ffffff,
24110bcb7efdSLinus Walleij 		.data	= &variant_nomadik,
24124956e109SRabin Vincent 	},
24134956e109SRabin Vincent 	{
24144956e109SRabin Vincent 		.id     = 0x00480180,
24151784b157SPhilippe Langlais 		.mask   = 0xf0ffffff,
24164956e109SRabin Vincent 		.data	= &variant_ux500,
2417cc30d60eSLinus Walleij 	},
24181784b157SPhilippe Langlais 	{
24191784b157SPhilippe Langlais 		.id     = 0x10480180,
24201784b157SPhilippe Langlais 		.mask   = 0xf0ffffff,
24211784b157SPhilippe Langlais 		.data	= &variant_ux500v2,
24221784b157SPhilippe Langlais 	},
24232a9d6c80SPatrice Chotard 	{
24242a9d6c80SPatrice Chotard 		.id     = 0x00880180,
24252a9d6c80SPatrice Chotard 		.mask   = 0x00ffffff,
24262a9d6c80SPatrice Chotard 		.data	= &variant_stm32,
24272a9d6c80SPatrice Chotard 	},
242846b723ddSLudovic Barre 	{
242946b723ddSLudovic Barre 		.id     = 0x10153180,
243046b723ddSLudovic Barre 		.mask	= 0xf0ffffff,
243146b723ddSLudovic Barre 		.data	= &variant_stm32_sdmmc,
243246b723ddSLudovic Barre 	},
24337a2a98beSLudovic Barre 	{
24347a2a98beSLudovic Barre 		.id     = 0x00253180,
24357a2a98beSLudovic Barre 		.mask	= 0xf0ffffff,
24367a2a98beSLudovic Barre 		.data	= &variant_stm32_sdmmcv2,
24377a2a98beSLudovic Barre 	},
24385471fe8bSYann Gautier 	{
24395471fe8bSYann Gautier 		.id     = 0x20253180,
24405471fe8bSYann Gautier 		.mask	= 0xf0ffffff,
24415471fe8bSYann Gautier 		.data	= &variant_stm32_sdmmcv2,
24425471fe8bSYann Gautier 	},
244355b604aeSSrinivas Kandagatla 	/* Qualcomm variants */
244455b604aeSSrinivas Kandagatla 	{
244555b604aeSSrinivas Kandagatla 		.id     = 0x00051180,
244655b604aeSSrinivas Kandagatla 		.mask	= 0x000fffff,
244755b604aeSSrinivas Kandagatla 		.data	= &variant_qcom,
244855b604aeSSrinivas Kandagatla 	},
24491c6a0718SPierre Ossman 	{ 0, 0 },
24501c6a0718SPierre Ossman };
24511c6a0718SPierre Ossman 
24529f99835fSDave Martin MODULE_DEVICE_TABLE(amba, mmci_ids);
24539f99835fSDave Martin 
24541c6a0718SPierre Ossman static struct amba_driver mmci_driver = {
24551c6a0718SPierre Ossman 	.drv		= {
24561c6a0718SPierre Ossman 		.name	= DRIVER_NAME,
245748fa7003SUlf Hansson 		.pm	= &mmci_dev_pm_ops,
24581c6a0718SPierre Ossman 	},
24591c6a0718SPierre Ossman 	.probe		= mmci_probe,
24600433c143SBill Pemberton 	.remove		= mmci_remove,
24611c6a0718SPierre Ossman 	.id_table	= mmci_ids,
24621c6a0718SPierre Ossman };
24631c6a0718SPierre Ossman 
24649e5ed094Sviresh kumar module_amba_driver(mmci_driver);
24651c6a0718SPierre Ossman 
24661c6a0718SPierre Ossman module_param(fmax, uint, 0444);
24671c6a0718SPierre Ossman 
24681c6a0718SPierre Ossman MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver");
24691c6a0718SPierre Ossman MODULE_LICENSE("GPL");
2470