xref: /openbmc/linux/drivers/mmc/host/mmci.c (revision 2eb277c2)
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>
40b1a66593SUlf Hansson #include <linux/workqueue.h>
411c6a0718SPierre Ossman 
421c6a0718SPierre Ossman #include <asm/div64.h>
431c6a0718SPierre Ossman #include <asm/io.h>
441c6a0718SPierre Ossman 
451c6a0718SPierre Ossman #include "mmci.h"
461c6a0718SPierre Ossman 
471c6a0718SPierre Ossman #define DRIVER_NAME "mmci-pl18x"
481c6a0718SPierre Ossman 
4971953e0eSUlf Hansson static void mmci_variant_init(struct mmci_host *host);
50cb0335b7SLudovic Barre static void ux500_variant_init(struct mmci_host *host);
51b3fb9d64SLudovic Barre static void ux500v2_variant_init(struct mmci_host *host);
52c3647fdcSLudovic Barre 
531c6a0718SPierre Ossman static unsigned int fmax = 515633;
541c6a0718SPierre Ossman 
554956e109SRabin Vincent static struct variant_data variant_arm = {
568301bb68SRabin Vincent 	.fifosize		= 16 * 4,
578301bb68SRabin Vincent 	.fifohalfsize		= 8 * 4,
580f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
590f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
600f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
610f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
6208458ef6SRabin Vincent 	.datalength_bits	= 16,
63c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
647d72a1d4SUlf Hansson 	.pwrreg_powerup		= MCI_PWR_UP,
65dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
667878289bSUlf Hansson 	.reversed_irq_handling	= true,
676ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
6859db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
697f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
7011dfb970SPatrice Chotard 	.opendrain		= MCI_ROD,
71c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
724956e109SRabin Vincent };
734956e109SRabin Vincent 
74768fbc18SPawel Moll static struct variant_data variant_arm_extended_fifo = {
75768fbc18SPawel Moll 	.fifosize		= 128 * 4,
76768fbc18SPawel Moll 	.fifohalfsize		= 64 * 4,
770f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
780f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
790f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
800f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
81768fbc18SPawel Moll 	.datalength_bits	= 16,
82c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
837d72a1d4SUlf Hansson 	.pwrreg_powerup		= MCI_PWR_UP,
84dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
856ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
8659db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
877f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
8811dfb970SPatrice Chotard 	.opendrain		= MCI_ROD,
89c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
90768fbc18SPawel Moll };
91768fbc18SPawel Moll 
923a37298aSPawel Moll static struct variant_data variant_arm_extended_fifo_hwfc = {
933a37298aSPawel Moll 	.fifosize		= 128 * 4,
943a37298aSPawel Moll 	.fifohalfsize		= 64 * 4,
953a37298aSPawel Moll 	.clkreg_enable		= MCI_ARM_HWFCEN,
960f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
970f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
980f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
990f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
1003a37298aSPawel Moll 	.datalength_bits	= 16,
101c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
1023a37298aSPawel Moll 	.pwrreg_powerup		= MCI_PWR_UP,
103dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
1046ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
10559db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
1067f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
10711dfb970SPatrice Chotard 	.opendrain		= MCI_ROD,
108c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
1093a37298aSPawel Moll };
1103a37298aSPawel Moll 
1114956e109SRabin Vincent static struct variant_data variant_u300 = {
1128301bb68SRabin Vincent 	.fifosize		= 16 * 4,
1138301bb68SRabin Vincent 	.fifohalfsize		= 8 * 4,
11449ac215eSLinus Walleij 	.clkreg_enable		= MCI_ST_U300_HWFCEN,
115e1412d85SSrinivas Kandagatla 	.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
1160f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
1170f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
1180f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
1190f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
12008458ef6SRabin Vincent 	.datalength_bits	= 16,
121c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
1225db3eee7SLinus Walleij 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
123c7354133SSrinivas Kandagatla 	.st_sdio			= true,
1247d72a1d4SUlf Hansson 	.pwrreg_powerup		= MCI_PWR_ON,
125dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
1264d1a3a0dSUlf Hansson 	.signal_direction	= true,
127f4670daeSUlf Hansson 	.pwrreg_clkgate		= true,
1281ff44433SUlf Hansson 	.pwrreg_nopower		= true,
1296ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
13059db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
1317f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
13211dfb970SPatrice Chotard 	.opendrain		= MCI_OD,
133c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
1344956e109SRabin Vincent };
1354956e109SRabin Vincent 
13634fd4213SLinus Walleij static struct variant_data variant_nomadik = {
13734fd4213SLinus Walleij 	.fifosize		= 16 * 4,
13834fd4213SLinus Walleij 	.fifohalfsize		= 8 * 4,
13934fd4213SLinus Walleij 	.clkreg			= MCI_CLK_ENABLE,
140f5abc767SLinus Walleij 	.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
1410f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
1420f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
1430f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
1440f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
14534fd4213SLinus Walleij 	.datalength_bits	= 24,
146c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
1475db3eee7SLinus Walleij 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
148c7354133SSrinivas Kandagatla 	.st_sdio		= true,
14934fd4213SLinus Walleij 	.st_clkdiv		= true,
15034fd4213SLinus Walleij 	.pwrreg_powerup		= MCI_PWR_ON,
151dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
15234fd4213SLinus Walleij 	.signal_direction	= true,
153f4670daeSUlf Hansson 	.pwrreg_clkgate		= true,
1541ff44433SUlf Hansson 	.pwrreg_nopower		= true,
1556ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
15659db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
1577f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
15811dfb970SPatrice Chotard 	.opendrain		= MCI_OD,
159c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
16034fd4213SLinus Walleij };
16134fd4213SLinus Walleij 
1624956e109SRabin Vincent static struct variant_data variant_ux500 = {
1638301bb68SRabin Vincent 	.fifosize		= 30 * 4,
1648301bb68SRabin Vincent 	.fifohalfsize		= 8 * 4,
1654956e109SRabin Vincent 	.clkreg			= MCI_CLK_ENABLE,
16649ac215eSLinus Walleij 	.clkreg_enable		= MCI_ST_UX500_HWFCEN,
167e1412d85SSrinivas Kandagatla 	.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
168e8740644SSrinivas Kandagatla 	.clkreg_neg_edge_enable	= MCI_ST_UX500_NEG_EDGE,
1690f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
1700f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
1710f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
1720f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
17308458ef6SRabin Vincent 	.datalength_bits	= 24,
174c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
1752253ed4bSLinus Walleij 	.datactrl_any_blocksz	= true,
1762253ed4bSLinus Walleij 	.dma_power_of_2		= true,
1775db3eee7SLinus Walleij 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
178c7354133SSrinivas Kandagatla 	.st_sdio		= true,
179b70a67f9SLinus Walleij 	.st_clkdiv		= true,
1807d72a1d4SUlf Hansson 	.pwrreg_powerup		= MCI_PWR_ON,
181dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
1824d1a3a0dSUlf Hansson 	.signal_direction	= true,
183f4670daeSUlf Hansson 	.pwrreg_clkgate		= true,
18401259620SUlf Hansson 	.busy_detect		= true,
18549adc0caSLinus Walleij 	.busy_dpsm_flag		= MCI_DPSM_ST_BUSYMODE,
18649adc0caSLinus Walleij 	.busy_detect_flag	= MCI_ST_CARDBUSY,
18749adc0caSLinus Walleij 	.busy_detect_mask	= MCI_ST_BUSYENDMASK,
1881ff44433SUlf Hansson 	.pwrreg_nopower		= true,
1896ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
19059db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
1917f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
19211dfb970SPatrice Chotard 	.opendrain		= MCI_OD,
193cb0335b7SLudovic Barre 	.init			= ux500_variant_init,
1944956e109SRabin Vincent };
195b70a67f9SLinus Walleij 
1961784b157SPhilippe Langlais static struct variant_data variant_ux500v2 = {
1971784b157SPhilippe Langlais 	.fifosize		= 30 * 4,
1981784b157SPhilippe Langlais 	.fifohalfsize		= 8 * 4,
1991784b157SPhilippe Langlais 	.clkreg			= MCI_CLK_ENABLE,
2001784b157SPhilippe Langlais 	.clkreg_enable		= MCI_ST_UX500_HWFCEN,
201e1412d85SSrinivas Kandagatla 	.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
202e8740644SSrinivas Kandagatla 	.clkreg_neg_edge_enable	= MCI_ST_UX500_NEG_EDGE,
2030f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
2040f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
2050f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
2060f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
2075db3eee7SLinus Walleij 	.datactrl_mask_ddrmode	= MCI_DPSM_ST_DDRMODE,
2081784b157SPhilippe Langlais 	.datalength_bits	= 24,
209c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
2102253ed4bSLinus Walleij 	.datactrl_any_blocksz	= true,
2112253ed4bSLinus Walleij 	.dma_power_of_2		= true,
2125db3eee7SLinus Walleij 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
213c7354133SSrinivas Kandagatla 	.st_sdio		= true,
2141784b157SPhilippe Langlais 	.st_clkdiv		= true,
2157d72a1d4SUlf Hansson 	.pwrreg_powerup		= MCI_PWR_ON,
216dc6500bfSSrinivas Kandagatla 	.f_max			= 100000000,
2174d1a3a0dSUlf Hansson 	.signal_direction	= true,
218f4670daeSUlf Hansson 	.pwrreg_clkgate		= true,
21901259620SUlf Hansson 	.busy_detect		= true,
22049adc0caSLinus Walleij 	.busy_dpsm_flag		= MCI_DPSM_ST_BUSYMODE,
22149adc0caSLinus Walleij 	.busy_detect_flag	= MCI_ST_CARDBUSY,
22249adc0caSLinus Walleij 	.busy_detect_mask	= MCI_ST_BUSYENDMASK,
2231ff44433SUlf Hansson 	.pwrreg_nopower		= true,
2246ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
22559db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
2267f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
22711dfb970SPatrice Chotard 	.opendrain		= MCI_OD,
228b3fb9d64SLudovic Barre 	.init			= ux500v2_variant_init,
2291784b157SPhilippe Langlais };
2301784b157SPhilippe Langlais 
2312a9d6c80SPatrice Chotard static struct variant_data variant_stm32 = {
2322a9d6c80SPatrice Chotard 	.fifosize		= 32 * 4,
2332a9d6c80SPatrice Chotard 	.fifohalfsize		= 8 * 4,
2342a9d6c80SPatrice Chotard 	.clkreg			= MCI_CLK_ENABLE,
2352a9d6c80SPatrice Chotard 	.clkreg_enable		= MCI_ST_UX500_HWFCEN,
2362a9d6c80SPatrice Chotard 	.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
2372a9d6c80SPatrice Chotard 	.clkreg_neg_edge_enable	= MCI_ST_UX500_NEG_EDGE,
2380f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
2390f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
2400f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
2410f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
24259db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
2432a9d6c80SPatrice Chotard 	.datalength_bits	= 24,
244c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
2452a9d6c80SPatrice Chotard 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
2462a9d6c80SPatrice Chotard 	.st_sdio		= true,
2472a9d6c80SPatrice Chotard 	.st_clkdiv		= true,
2482a9d6c80SPatrice Chotard 	.pwrreg_powerup		= MCI_PWR_ON,
2492a9d6c80SPatrice Chotard 	.f_max			= 48000000,
2502a9d6c80SPatrice Chotard 	.pwrreg_clkgate		= true,
2512a9d6c80SPatrice Chotard 	.pwrreg_nopower		= true,
252c3647fdcSLudovic Barre 	.init			= mmci_variant_init,
2532a9d6c80SPatrice Chotard };
2542a9d6c80SPatrice Chotard 
25546b723ddSLudovic Barre static struct variant_data variant_stm32_sdmmc = {
25646b723ddSLudovic Barre 	.fifosize		= 16 * 4,
25746b723ddSLudovic Barre 	.fifohalfsize		= 8 * 4,
25846b723ddSLudovic Barre 	.f_max			= 208000000,
25946b723ddSLudovic Barre 	.stm32_clkdiv		= true,
26046b723ddSLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_STM32_ENABLE,
26146b723ddSLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_STM32_LRSP_CRC,
26246b723ddSLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_STM32_SRSP_CRC,
26346b723ddSLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_STM32_SRSP,
264c8073e52SLudovic Barre 	.cmdreg_stop		= MCI_CPSM_STM32_CMDSTOP,
26546b723ddSLudovic Barre 	.data_cmd_enable	= MCI_CPSM_STM32_CMDTRANS,
26646b723ddSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_STM32_MASK,
26746b723ddSLudovic Barre 	.datactrl_first		= true,
26846b723ddSLudovic Barre 	.datacnt_useless	= true,
26946b723ddSLudovic Barre 	.datalength_bits	= 25,
27046b723ddSLudovic Barre 	.datactrl_blocksz	= 14,
2712253ed4bSLinus Walleij 	.datactrl_any_blocksz	= true,
27281a77ee9SLudovic Barre 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
27346b723ddSLudovic Barre 	.stm32_idmabsize_mask	= GENMASK(12, 5),
27488167e6cSYann Gautier 	.stm32_idmabsize_align	= BIT(5),
2750e68de6aSLudovic Barre 	.busy_timeout		= true,
2760e68de6aSLudovic Barre 	.busy_detect		= true,
2770e68de6aSLudovic Barre 	.busy_detect_flag	= MCI_STM32_BUSYD0,
2780e68de6aSLudovic Barre 	.busy_detect_mask	= MCI_STM32_BUSYD0ENDMASK,
27946b723ddSLudovic Barre 	.init			= sdmmc_variant_init,
28046b723ddSLudovic Barre };
28146b723ddSLudovic Barre 
2827a2a98beSLudovic Barre static struct variant_data variant_stm32_sdmmcv2 = {
2837a2a98beSLudovic Barre 	.fifosize		= 16 * 4,
2847a2a98beSLudovic Barre 	.fifohalfsize		= 8 * 4,
2854481ab60SYann Gautier 	.f_max			= 267000000,
2867a2a98beSLudovic Barre 	.stm32_clkdiv		= true,
2877a2a98beSLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_STM32_ENABLE,
2887a2a98beSLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_STM32_LRSP_CRC,
2897a2a98beSLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_STM32_SRSP_CRC,
2907a2a98beSLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_STM32_SRSP,
2917a2a98beSLudovic Barre 	.cmdreg_stop		= MCI_CPSM_STM32_CMDSTOP,
2927a2a98beSLudovic Barre 	.data_cmd_enable	= MCI_CPSM_STM32_CMDTRANS,
2937a2a98beSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_STM32_MASK,
2947a2a98beSLudovic Barre 	.datactrl_first		= true,
2957a2a98beSLudovic Barre 	.datacnt_useless	= true,
2967a2a98beSLudovic Barre 	.datalength_bits	= 25,
2977a2a98beSLudovic Barre 	.datactrl_blocksz	= 14,
2987a2a98beSLudovic Barre 	.datactrl_any_blocksz	= true,
29981a77ee9SLudovic Barre 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
3007a2a98beSLudovic Barre 	.stm32_idmabsize_mask	= GENMASK(16, 5),
30188167e6cSYann Gautier 	.stm32_idmabsize_align	= BIT(5),
3027a2a98beSLudovic Barre 	.dma_lli		= true,
3037a2a98beSLudovic Barre 	.busy_timeout		= true,
3047a2a98beSLudovic Barre 	.busy_detect		= true,
3057a2a98beSLudovic Barre 	.busy_detect_flag	= MCI_STM32_BUSYD0,
3067a2a98beSLudovic Barre 	.busy_detect_mask	= MCI_STM32_BUSYD0ENDMASK,
3077a2a98beSLudovic Barre 	.init			= sdmmc_variant_init,
3087a2a98beSLudovic Barre };
3097a2a98beSLudovic Barre 
310ea9ca041SYann Gautier static struct variant_data variant_stm32_sdmmcv3 = {
311ea9ca041SYann Gautier 	.fifosize		= 256 * 4,
312ea9ca041SYann Gautier 	.fifohalfsize		= 128 * 4,
313ea9ca041SYann Gautier 	.f_max			= 267000000,
314ea9ca041SYann Gautier 	.stm32_clkdiv		= true,
315ea9ca041SYann Gautier 	.cmdreg_cpsm_enable	= MCI_CPSM_STM32_ENABLE,
316ea9ca041SYann Gautier 	.cmdreg_lrsp_crc	= MCI_CPSM_STM32_LRSP_CRC,
317ea9ca041SYann Gautier 	.cmdreg_srsp_crc	= MCI_CPSM_STM32_SRSP_CRC,
318ea9ca041SYann Gautier 	.cmdreg_srsp		= MCI_CPSM_STM32_SRSP,
319ea9ca041SYann Gautier 	.cmdreg_stop		= MCI_CPSM_STM32_CMDSTOP,
320ea9ca041SYann Gautier 	.data_cmd_enable	= MCI_CPSM_STM32_CMDTRANS,
321ea9ca041SYann Gautier 	.irq_pio_mask		= MCI_IRQ_PIO_STM32_MASK,
322ea9ca041SYann Gautier 	.datactrl_first		= true,
323ea9ca041SYann Gautier 	.datacnt_useless	= true,
324ea9ca041SYann Gautier 	.datalength_bits	= 25,
325ea9ca041SYann Gautier 	.datactrl_blocksz	= 14,
326ea9ca041SYann Gautier 	.datactrl_any_blocksz	= true,
327ea9ca041SYann Gautier 	.datactrl_mask_sdio	= MCI_DPSM_ST_SDIOEN,
328ea9ca041SYann Gautier 	.stm32_idmabsize_mask	= GENMASK(16, 6),
329ea9ca041SYann Gautier 	.stm32_idmabsize_align	= BIT(6),
330ea9ca041SYann Gautier 	.dma_lli		= true,
331ea9ca041SYann Gautier 	.busy_timeout		= true,
332ea9ca041SYann Gautier 	.busy_detect		= true,
333ea9ca041SYann Gautier 	.busy_detect_flag	= MCI_STM32_BUSYD0,
334ea9ca041SYann Gautier 	.busy_detect_mask	= MCI_STM32_BUSYD0ENDMASK,
335ea9ca041SYann Gautier 	.init			= sdmmc_variant_init,
336ea9ca041SYann Gautier };
337ea9ca041SYann Gautier 
33855b604aeSSrinivas Kandagatla static struct variant_data variant_qcom = {
33955b604aeSSrinivas Kandagatla 	.fifosize		= 16 * 4,
34055b604aeSSrinivas Kandagatla 	.fifohalfsize		= 8 * 4,
34155b604aeSSrinivas Kandagatla 	.clkreg			= MCI_CLK_ENABLE,
34255b604aeSSrinivas Kandagatla 	.clkreg_enable		= MCI_QCOM_CLK_FLOWENA |
34355b604aeSSrinivas Kandagatla 				  MCI_QCOM_CLK_SELECT_IN_FBCLK,
34455b604aeSSrinivas Kandagatla 	.clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,
34555b604aeSSrinivas Kandagatla 	.datactrl_mask_ddrmode	= MCI_QCOM_CLK_SELECT_IN_DDR_MODE,
3460f244804SLudovic Barre 	.cmdreg_cpsm_enable	= MCI_CPSM_ENABLE,
3470f244804SLudovic Barre 	.cmdreg_lrsp_crc	= MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP,
3480f244804SLudovic Barre 	.cmdreg_srsp_crc	= MCI_CPSM_RESPONSE,
3490f244804SLudovic Barre 	.cmdreg_srsp		= MCI_CPSM_RESPONSE,
3505db3eee7SLinus Walleij 	.data_cmd_enable	= MCI_CPSM_QCOM_DATCMD,
35155b604aeSSrinivas Kandagatla 	.datalength_bits	= 24,
352c931d495SLudovic Barre 	.datactrl_blocksz	= 11,
3532253ed4bSLinus Walleij 	.datactrl_any_blocksz	= true,
35455b604aeSSrinivas Kandagatla 	.pwrreg_powerup		= MCI_PWR_UP,
35555b604aeSSrinivas Kandagatla 	.f_max			= 208000000,
35655b604aeSSrinivas Kandagatla 	.explicit_mclk_control	= true,
35755b604aeSSrinivas Kandagatla 	.qcom_fifo		= true,
3589cb15142SSrinivas Kandagatla 	.qcom_dml		= true,
3596ea9cdf3SPatrice Chotard 	.mmcimask1		= true,
36059db5e2dSLudovic Barre 	.irq_pio_mask		= MCI_IRQ_PIO_MASK,
3617f7b5503SPatrice Chotard 	.start_err		= MCI_STARTBITERR,
36211dfb970SPatrice Chotard 	.opendrain		= MCI_ROD,
36329aba07aSUlf Hansson 	.init			= qcom_variant_init,
36455b604aeSSrinivas Kandagatla };
36555b604aeSSrinivas Kandagatla 
36649adc0caSLinus Walleij /* Busy detection for the ST Micro variant */
mmci_card_busy(struct mmc_host * mmc)36701259620SUlf Hansson static int mmci_card_busy(struct mmc_host *mmc)
36801259620SUlf Hansson {
36901259620SUlf Hansson 	struct mmci_host *host = mmc_priv(mmc);
37001259620SUlf Hansson 	unsigned long flags;
37101259620SUlf Hansson 	int busy = 0;
37201259620SUlf Hansson 
37301259620SUlf Hansson 	spin_lock_irqsave(&host->lock, flags);
37449adc0caSLinus Walleij 	if (readl(host->base + MMCISTATUS) & host->variant->busy_detect_flag)
37501259620SUlf Hansson 		busy = 1;
37601259620SUlf Hansson 	spin_unlock_irqrestore(&host->lock, flags);
37701259620SUlf Hansson 
37801259620SUlf Hansson 	return busy;
37901259620SUlf Hansson }
38001259620SUlf Hansson 
mmci_reg_delay(struct mmci_host * host)381f829c042SUlf Hansson static void mmci_reg_delay(struct mmci_host *host)
382f829c042SUlf Hansson {
383f829c042SUlf Hansson 	/*
384f829c042SUlf Hansson 	 * According to the spec, at least three feedback clock cycles
385f829c042SUlf Hansson 	 * of max 52 MHz must pass between two writes to the MMCICLOCK reg.
386f829c042SUlf Hansson 	 * Three MCLK clock cycles must pass between two MMCIPOWER reg writes.
387f829c042SUlf Hansson 	 * Worst delay time during card init is at 100 kHz => 30 us.
388f829c042SUlf Hansson 	 * Worst delay time when up and running is at 25 MHz => 120 ns.
389f829c042SUlf Hansson 	 */
390f829c042SUlf Hansson 	if (host->cclk < 25000000)
391f829c042SUlf Hansson 		udelay(30);
392f829c042SUlf Hansson 	else
393f829c042SUlf Hansson 		ndelay(120);
394f829c042SUlf Hansson }
395f829c042SUlf Hansson 
396653a761eSUlf Hansson /*
397a6a6464aSLinus Walleij  * This must be called with host->lock held
398a6a6464aSLinus Walleij  */
mmci_write_clkreg(struct mmci_host * host,u32 clk)399cd3ee8c5SLudovic Barre void mmci_write_clkreg(struct mmci_host *host, u32 clk)
4007437cfa5SUlf Hansson {
4017437cfa5SUlf Hansson 	if (host->clk_reg != clk) {
4027437cfa5SUlf Hansson 		host->clk_reg = clk;
4037437cfa5SUlf Hansson 		writel(clk, host->base + MMCICLOCK);
4047437cfa5SUlf Hansson 	}
4057437cfa5SUlf Hansson }
4067437cfa5SUlf Hansson 
4077437cfa5SUlf Hansson /*
4087437cfa5SUlf Hansson  * This must be called with host->lock held
4097437cfa5SUlf Hansson  */
mmci_write_pwrreg(struct mmci_host * host,u32 pwr)410cd3ee8c5SLudovic Barre void mmci_write_pwrreg(struct mmci_host *host, u32 pwr)
4117437cfa5SUlf Hansson {
4127437cfa5SUlf Hansson 	if (host->pwr_reg != pwr) {
4137437cfa5SUlf Hansson 		host->pwr_reg = pwr;
4147437cfa5SUlf Hansson 		writel(pwr, host->base + MMCIPOWER);
4157437cfa5SUlf Hansson 	}
4167437cfa5SUlf Hansson }
4177437cfa5SUlf Hansson 
4187437cfa5SUlf Hansson /*
4197437cfa5SUlf Hansson  * This must be called with host->lock held
4207437cfa5SUlf Hansson  */
mmci_write_datactrlreg(struct mmci_host * host,u32 datactrl)4219cc639a2SUlf Hansson static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl)
4229cc639a2SUlf Hansson {
42349adc0caSLinus Walleij 	/* Keep busy mode in DPSM if enabled */
42449adc0caSLinus Walleij 	datactrl |= host->datactrl_reg & host->variant->busy_dpsm_flag;
42501259620SUlf Hansson 
4269cc639a2SUlf Hansson 	if (host->datactrl_reg != datactrl) {
4279cc639a2SUlf Hansson 		host->datactrl_reg = datactrl;
4289cc639a2SUlf Hansson 		writel(datactrl, host->base + MMCIDATACTRL);
4299cc639a2SUlf Hansson 	}
4309cc639a2SUlf Hansson }
4319cc639a2SUlf Hansson 
4329cc639a2SUlf Hansson /*
4339cc639a2SUlf Hansson  * This must be called with host->lock held
4349cc639a2SUlf Hansson  */
mmci_set_clkreg(struct mmci_host * host,unsigned int desired)435a6a6464aSLinus Walleij static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
436a6a6464aSLinus Walleij {
4374956e109SRabin Vincent 	struct variant_data *variant = host->variant;
4384956e109SRabin Vincent 	u32 clk = variant->clkreg;
439a6a6464aSLinus Walleij 
440c58a8509SUlf Hansson 	/* Make sure cclk reflects the current calculated clock */
441c58a8509SUlf Hansson 	host->cclk = 0;
442c58a8509SUlf Hansson 
443a6a6464aSLinus Walleij 	if (desired) {
4443f4e6f7bSSrinivas Kandagatla 		if (variant->explicit_mclk_control) {
4453f4e6f7bSSrinivas Kandagatla 			host->cclk = host->mclk;
4463f4e6f7bSSrinivas Kandagatla 		} else if (desired >= host->mclk) {
447a6a6464aSLinus Walleij 			clk = MCI_CLK_BYPASS;
448399bc486SLinus Walleij 			if (variant->st_clkdiv)
449399bc486SLinus Walleij 				clk |= MCI_ST_UX500_NEG_EDGE;
450a6a6464aSLinus Walleij 			host->cclk = host->mclk;
451b70a67f9SLinus Walleij 		} else if (variant->st_clkdiv) {
452b70a67f9SLinus Walleij 			/*
453b70a67f9SLinus Walleij 			 * DB8500 TRM says f = mclk / (clkdiv + 2)
454b70a67f9SLinus Walleij 			 * => clkdiv = (mclk / f) - 2
455b70a67f9SLinus Walleij 			 * Round the divider up so we don't exceed the max
456b70a67f9SLinus Walleij 			 * frequency
457b70a67f9SLinus Walleij 			 */
458b70a67f9SLinus Walleij 			clk = DIV_ROUND_UP(host->mclk, desired) - 2;
459b70a67f9SLinus Walleij 			if (clk >= 256)
460b70a67f9SLinus Walleij 				clk = 255;
461b70a67f9SLinus Walleij 			host->cclk = host->mclk / (clk + 2);
462a6a6464aSLinus Walleij 		} else {
463b70a67f9SLinus Walleij 			/*
464b70a67f9SLinus Walleij 			 * PL180 TRM says f = mclk / (2 * (clkdiv + 1))
465b70a67f9SLinus Walleij 			 * => clkdiv = mclk / (2 * f) - 1
466b70a67f9SLinus Walleij 			 */
467a6a6464aSLinus Walleij 			clk = host->mclk / (2 * desired) - 1;
468a6a6464aSLinus Walleij 			if (clk >= 256)
469a6a6464aSLinus Walleij 				clk = 255;
470a6a6464aSLinus Walleij 			host->cclk = host->mclk / (2 * (clk + 1));
471a6a6464aSLinus Walleij 		}
4724380c14fSRabin Vincent 
4734380c14fSRabin Vincent 		clk |= variant->clkreg_enable;
474a6a6464aSLinus Walleij 		clk |= MCI_CLK_ENABLE;
475a6a6464aSLinus Walleij 		/* This hasn't proven to be worthwhile */
476a6a6464aSLinus Walleij 		/* clk |= MCI_CLK_PWRSAVE; */
477a6a6464aSLinus Walleij 	}
478a6a6464aSLinus Walleij 
479c58a8509SUlf Hansson 	/* Set actual clock for debug */
480c58a8509SUlf Hansson 	host->mmc->actual_clock = host->cclk;
481c58a8509SUlf Hansson 
4829e6c82cdSLinus Walleij 	if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
483771dc157SLinus Walleij 		clk |= MCI_4BIT_BUS;
484771dc157SLinus Walleij 	if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
485e1412d85SSrinivas Kandagatla 		clk |= variant->clkreg_8bit_bus_enable;
4869e6c82cdSLinus Walleij 
4876dad6c95SSeungwon Jeon 	if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 ||
4886dad6c95SSeungwon Jeon 	    host->mmc->ios.timing == MMC_TIMING_MMC_DDR52)
489e8740644SSrinivas Kandagatla 		clk |= variant->clkreg_neg_edge_enable;
4906dbb6ee0SUlf Hansson 
4917437cfa5SUlf Hansson 	mmci_write_clkreg(host, clk);
492a6a6464aSLinus Walleij }
493a6a6464aSLinus Walleij 
mmci_dma_release(struct mmci_host * host)494e2b98d83SBen Dooks static void mmci_dma_release(struct mmci_host *host)
495c3647fdcSLudovic Barre {
496c3647fdcSLudovic Barre 	if (host->ops && host->ops->dma_release)
497c3647fdcSLudovic Barre 		host->ops->dma_release(host);
498c3647fdcSLudovic Barre 
499c3647fdcSLudovic Barre 	host->use_dma = false;
500c3647fdcSLudovic Barre }
501c3647fdcSLudovic Barre 
mmci_dma_setup(struct mmci_host * host)502e2b98d83SBen Dooks static void mmci_dma_setup(struct mmci_host *host)
503c3647fdcSLudovic Barre {
504c3647fdcSLudovic Barre 	if (!host->ops || !host->ops->dma_setup)
505c3647fdcSLudovic Barre 		return;
506c3647fdcSLudovic Barre 
507c3647fdcSLudovic Barre 	if (host->ops->dma_setup(host))
508c3647fdcSLudovic Barre 		return;
509c3647fdcSLudovic Barre 
510a813f2a2SLudovic Barre 	/* initialize pre request cookie */
511a813f2a2SLudovic Barre 	host->next_cookie = 1;
512a813f2a2SLudovic Barre 
513c3647fdcSLudovic Barre 	host->use_dma = true;
514c3647fdcSLudovic Barre }
515c3647fdcSLudovic Barre 
516e0da1721SLudovic Barre /*
517e0da1721SLudovic Barre  * Validate mmc prerequisites
518e0da1721SLudovic Barre  */
mmci_validate_data(struct mmci_host * host,struct mmc_data * data)519e0da1721SLudovic Barre static int mmci_validate_data(struct mmci_host *host,
520e0da1721SLudovic Barre 			      struct mmc_data *data)
521e0da1721SLudovic Barre {
5222253ed4bSLinus Walleij 	struct variant_data *variant = host->variant;
5232253ed4bSLinus Walleij 
524e0da1721SLudovic Barre 	if (!data)
525e0da1721SLudovic Barre 		return 0;
5262253ed4bSLinus Walleij 	if (!is_power_of_2(data->blksz) && !variant->datactrl_any_blocksz) {
527e0da1721SLudovic Barre 		dev_err(mmc_dev(host->mmc),
528e0da1721SLudovic Barre 			"unsupported block size (%d bytes)\n", data->blksz);
529e0da1721SLudovic Barre 		return -EINVAL;
530e0da1721SLudovic Barre 	}
531e0da1721SLudovic Barre 
532e0da1721SLudovic Barre 	if (host->ops && host->ops->validate_data)
533e0da1721SLudovic Barre 		return host->ops->validate_data(host, data);
534e0da1721SLudovic Barre 
535e0da1721SLudovic Barre 	return 0;
536e0da1721SLudovic Barre }
537e0da1721SLudovic Barre 
mmci_prep_data(struct mmci_host * host,struct mmc_data * data,bool next)538e2b98d83SBen Dooks static int mmci_prep_data(struct mmci_host *host, struct mmc_data *data, bool next)
53947983510SLudovic Barre {
54047983510SLudovic Barre 	int err;
54147983510SLudovic Barre 
54247983510SLudovic Barre 	if (!host->ops || !host->ops->prep_data)
54347983510SLudovic Barre 		return 0;
54447983510SLudovic Barre 
54547983510SLudovic Barre 	err = host->ops->prep_data(host, data, next);
54647983510SLudovic Barre 
54747983510SLudovic Barre 	if (next && !err)
54847983510SLudovic Barre 		data->host_cookie = ++host->next_cookie < 0 ?
54947983510SLudovic Barre 			1 : host->next_cookie;
55047983510SLudovic Barre 
55147983510SLudovic Barre 	return err;
55247983510SLudovic Barre }
55347983510SLudovic Barre 
mmci_unprep_data(struct mmci_host * host,struct mmc_data * data,int err)554e2b98d83SBen Dooks static void mmci_unprep_data(struct mmci_host *host, struct mmc_data *data,
55547983510SLudovic Barre 		      int err)
55647983510SLudovic Barre {
55747983510SLudovic Barre 	if (host->ops && host->ops->unprep_data)
55847983510SLudovic Barre 		host->ops->unprep_data(host, data, err);
55947983510SLudovic Barre 
56047983510SLudovic Barre 	data->host_cookie = 0;
56147983510SLudovic Barre }
56247983510SLudovic Barre 
mmci_get_next_data(struct mmci_host * host,struct mmc_data * data)563e2b98d83SBen Dooks static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data)
56402769968SLudovic Barre {
56502769968SLudovic Barre 	WARN_ON(data->host_cookie && data->host_cookie != host->next_cookie);
56602769968SLudovic Barre 
56702769968SLudovic Barre 	if (host->ops && host->ops->get_next_data)
56802769968SLudovic Barre 		host->ops->get_next_data(host, data);
56902769968SLudovic Barre }
57002769968SLudovic Barre 
mmci_dma_start(struct mmci_host * host,unsigned int datactrl)571e2b98d83SBen Dooks static int mmci_dma_start(struct mmci_host *host, unsigned int datactrl)
572135ea30eSLudovic Barre {
573135ea30eSLudovic Barre 	struct mmc_data *data = host->data;
574135ea30eSLudovic Barre 	int ret;
575135ea30eSLudovic Barre 
576135ea30eSLudovic Barre 	if (!host->use_dma)
577135ea30eSLudovic Barre 		return -EINVAL;
578135ea30eSLudovic Barre 
579135ea30eSLudovic Barre 	ret = mmci_prep_data(host, data, false);
580135ea30eSLudovic Barre 	if (ret)
581135ea30eSLudovic Barre 		return ret;
582135ea30eSLudovic Barre 
583135ea30eSLudovic Barre 	if (!host->ops || !host->ops->dma_start)
584135ea30eSLudovic Barre 		return -EINVAL;
585135ea30eSLudovic Barre 
586135ea30eSLudovic Barre 	/* Okay, go for it. */
587135ea30eSLudovic Barre 	dev_vdbg(mmc_dev(host->mmc),
588135ea30eSLudovic Barre 		 "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n",
589135ea30eSLudovic Barre 		 data->sg_len, data->blksz, data->blocks, data->flags);
590135ea30eSLudovic Barre 
5912253ed4bSLinus Walleij 	ret = host->ops->dma_start(host, &datactrl);
5922253ed4bSLinus Walleij 	if (ret)
5932253ed4bSLinus Walleij 		return ret;
594135ea30eSLudovic Barre 
595135ea30eSLudovic Barre 	/* Trigger the DMA transfer */
596135ea30eSLudovic Barre 	mmci_write_datactrlreg(host, datactrl);
597135ea30eSLudovic Barre 
598135ea30eSLudovic Barre 	/*
599135ea30eSLudovic Barre 	 * Let the MMCI say when the data is ended and it's time
600135ea30eSLudovic Barre 	 * to fire next DMA request. When that happens, MMCI will
601135ea30eSLudovic Barre 	 * call mmci_data_end()
602135ea30eSLudovic Barre 	 */
603135ea30eSLudovic Barre 	writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK,
604135ea30eSLudovic Barre 	       host->base + MMCIMASK0);
605135ea30eSLudovic Barre 	return 0;
606135ea30eSLudovic Barre }
607135ea30eSLudovic Barre 
mmci_dma_finalize(struct mmci_host * host,struct mmc_data * data)608e2b98d83SBen Dooks static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data)
6095a9f10c3SLudovic Barre {
6105a9f10c3SLudovic Barre 	if (!host->use_dma)
6115a9f10c3SLudovic Barre 		return;
6125a9f10c3SLudovic Barre 
6135a9f10c3SLudovic Barre 	if (host->ops && host->ops->dma_finalize)
6145a9f10c3SLudovic Barre 		host->ops->dma_finalize(host, data);
6155a9f10c3SLudovic Barre }
6165a9f10c3SLudovic Barre 
mmci_dma_error(struct mmci_host * host)617e2b98d83SBen Dooks static void mmci_dma_error(struct mmci_host *host)
618cfccc6acSLudovic Barre {
619cfccc6acSLudovic Barre 	if (!host->use_dma)
620cfccc6acSLudovic Barre 		return;
621cfccc6acSLudovic Barre 
622cfccc6acSLudovic Barre 	if (host->ops && host->ops->dma_error)
623cfccc6acSLudovic Barre 		host->ops->dma_error(host);
624cfccc6acSLudovic Barre }
625cfccc6acSLudovic Barre 
6261c6a0718SPierre Ossman static void
mmci_request_end(struct mmci_host * host,struct mmc_request * mrq)6271c6a0718SPierre Ossman mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
6281c6a0718SPierre Ossman {
6291c6a0718SPierre Ossman 	writel(0, host->base + MMCICOMMAND);
6301c6a0718SPierre Ossman 
6311c6a0718SPierre Ossman 	BUG_ON(host->data);
6321c6a0718SPierre Ossman 
6331c6a0718SPierre Ossman 	host->mrq = NULL;
6341c6a0718SPierre Ossman 	host->cmd = NULL;
6351c6a0718SPierre Ossman 
6361c6a0718SPierre Ossman 	mmc_request_done(host->mmc, mrq);
6371c6a0718SPierre Ossman }
6381c6a0718SPierre Ossman 
mmci_set_mask1(struct mmci_host * host,unsigned int mask)6392686b4b4SLinus Walleij static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
6402686b4b4SLinus Walleij {
6412686b4b4SLinus Walleij 	void __iomem *base = host->base;
6426ea9cdf3SPatrice Chotard 	struct variant_data *variant = host->variant;
6432686b4b4SLinus Walleij 
6442686b4b4SLinus Walleij 	if (host->singleirq) {
6452686b4b4SLinus Walleij 		unsigned int mask0 = readl(base + MMCIMASK0);
6462686b4b4SLinus Walleij 
64759db5e2dSLudovic Barre 		mask0 &= ~variant->irq_pio_mask;
6482686b4b4SLinus Walleij 		mask0 |= mask;
6492686b4b4SLinus Walleij 
6502686b4b4SLinus Walleij 		writel(mask0, base + MMCIMASK0);
6512686b4b4SLinus Walleij 	}
6522686b4b4SLinus Walleij 
6536ea9cdf3SPatrice Chotard 	if (variant->mmcimask1)
6542686b4b4SLinus Walleij 		writel(mask, base + MMCIMASK1);
6556ea9cdf3SPatrice Chotard 
6566ea9cdf3SPatrice Chotard 	host->mask1_reg = mask;
6572686b4b4SLinus Walleij }
6582686b4b4SLinus Walleij 
mmci_stop_data(struct mmci_host * host)6591c6a0718SPierre Ossman static void mmci_stop_data(struct mmci_host *host)
6601c6a0718SPierre Ossman {
6619cc639a2SUlf Hansson 	mmci_write_datactrlreg(host, 0);
6622686b4b4SLinus Walleij 	mmci_set_mask1(host, 0);
6631c6a0718SPierre Ossman 	host->data = NULL;
6641c6a0718SPierre Ossman }
6651c6a0718SPierre Ossman 
mmci_init_sg(struct mmci_host * host,struct mmc_data * data)6664ce1d6cbSRabin Vincent static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
6674ce1d6cbSRabin Vincent {
6684ce1d6cbSRabin Vincent 	unsigned int flags = SG_MITER_ATOMIC;
6694ce1d6cbSRabin Vincent 
6704ce1d6cbSRabin Vincent 	if (data->flags & MMC_DATA_READ)
6714ce1d6cbSRabin Vincent 		flags |= SG_MITER_TO_SG;
6724ce1d6cbSRabin Vincent 	else
6734ce1d6cbSRabin Vincent 		flags |= SG_MITER_FROM_SG;
6744ce1d6cbSRabin Vincent 
6754ce1d6cbSRabin Vincent 	sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
6764ce1d6cbSRabin Vincent }
6774ce1d6cbSRabin Vincent 
mmci_get_dctrl_cfg(struct mmci_host * host)678b3fb9d64SLudovic Barre static u32 mmci_get_dctrl_cfg(struct mmci_host *host)
679b3fb9d64SLudovic Barre {
680b3fb9d64SLudovic Barre 	return MCI_DPSM_ENABLE | mmci_dctrl_blksz(host);
681b3fb9d64SLudovic Barre }
682b3fb9d64SLudovic Barre 
ux500v2_get_dctrl_cfg(struct mmci_host * host)683b3fb9d64SLudovic Barre static u32 ux500v2_get_dctrl_cfg(struct mmci_host *host)
684b3fb9d64SLudovic Barre {
685b3fb9d64SLudovic Barre 	return MCI_DPSM_ENABLE | (host->data->blksz << 16);
686b3fb9d64SLudovic Barre }
687b3fb9d64SLudovic Barre 
ux500_busy_clear_mask_done(struct mmci_host * host)6884711c6abSLinus Walleij static void ux500_busy_clear_mask_done(struct mmci_host *host)
6894711c6abSLinus Walleij {
6904711c6abSLinus Walleij 	void __iomem *base = host->base;
6914711c6abSLinus Walleij 
6924711c6abSLinus Walleij 	writel(host->variant->busy_detect_mask, base + MMCICLEAR);
6934711c6abSLinus Walleij 	writel(readl(base + MMCIMASK0) &
6944711c6abSLinus Walleij 	       ~host->variant->busy_detect_mask, base + MMCIMASK0);
6954711c6abSLinus Walleij 	host->busy_state = MMCI_BUSY_DONE;
6964711c6abSLinus Walleij 	host->busy_status = 0;
6974711c6abSLinus Walleij }
6984711c6abSLinus Walleij 
699479d8e61SLinus Walleij /*
700479d8e61SLinus Walleij  * ux500_busy_complete() - this will wait until the busy status
701479d8e61SLinus Walleij  * goes off, saving any status that occur in the meantime into
702479d8e61SLinus Walleij  * host->busy_status until we know the card is not busy any more.
703479d8e61SLinus Walleij  * The function returns true when the busy detection is ended
704479d8e61SLinus Walleij  * and we should continue processing the command.
705479d8e61SLinus Walleij  *
706479d8e61SLinus Walleij  * The Ux500 typically fires two IRQs over a busy cycle like this:
707479d8e61SLinus Walleij  *
708479d8e61SLinus Walleij  *  DAT0 busy          +-----------------+
709479d8e61SLinus Walleij  *                     |                 |
710479d8e61SLinus Walleij  *  DAT0 not busy  ----+                 +--------
711479d8e61SLinus Walleij  *
712479d8e61SLinus Walleij  *                     ^                 ^
713479d8e61SLinus Walleij  *                     |                 |
714479d8e61SLinus Walleij  *                    IRQ1              IRQ2
715479d8e61SLinus Walleij  */
ux500_busy_complete(struct mmci_host * host,struct mmc_command * cmd,u32 status,u32 err_msk)716b1a66593SUlf Hansson static bool ux500_busy_complete(struct mmci_host *host, struct mmc_command *cmd,
717b1a66593SUlf Hansson 				u32 status, u32 err_msk)
718cb0335b7SLudovic Barre {
719cb0335b7SLudovic Barre 	void __iomem *base = host->base;
7207892497fSLinus Walleij 	int retries = 10;
721cb0335b7SLudovic Barre 
722e1a2485cSLinus Walleij 	if (status & err_msk) {
723e1a2485cSLinus Walleij 		/* Stop any ongoing busy detection if an error occurs */
7244711c6abSLinus Walleij 		ux500_busy_clear_mask_done(host);
725e85fecc3SLinus Walleij 		goto out_ret_state;
726e1a2485cSLinus Walleij 	}
727e1a2485cSLinus Walleij 
728cb0335b7SLudovic Barre 	/*
729ddb5a92dSLinus Walleij 	 * The state transitions are encoded in a state machine crossing
730ddb5a92dSLinus Walleij 	 * the edges in this switch statement.
731ddb5a92dSLinus Walleij 	 */
732ddb5a92dSLinus Walleij 	switch (host->busy_state) {
733ddb5a92dSLinus Walleij 
734ddb5a92dSLinus Walleij 	/*
735cb0335b7SLudovic Barre 	 * Before unmasking for the busy end IRQ, confirm that the
736cb0335b7SLudovic Barre 	 * command was sent successfully. To keep track of having a
737cb0335b7SLudovic Barre 	 * command in-progress, waiting for busy signaling to end,
738cb0335b7SLudovic Barre 	 * store the status in host->busy_status.
739cb0335b7SLudovic Barre 	 *
740cb0335b7SLudovic Barre 	 * Note that, the card may need a couple of clock cycles before
741cb0335b7SLudovic Barre 	 * it starts signaling busy on DAT0, hence re-read the
742cb0335b7SLudovic Barre 	 * MMCISTATUS register here, to allow the busy bit to be set.
743cb0335b7SLudovic Barre 	 */
744ddb5a92dSLinus Walleij 	case MMCI_BUSY_DONE:
7457892497fSLinus Walleij 		/*
7467892497fSLinus Walleij 		 * Save the first status register read to be sure to catch
7477892497fSLinus Walleij 		 * all bits that may be lost will retrying. If the command
7487892497fSLinus Walleij 		 * is still busy this will result in assigning 0 to
7497892497fSLinus Walleij 		 * host->busy_status, which is what it should be in IDLE.
7507892497fSLinus Walleij 		 */
7517892497fSLinus Walleij 		host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND);
7527892497fSLinus Walleij 		while (retries) {
753479d8e61SLinus Walleij 			status = readl(base + MMCISTATUS);
7547892497fSLinus Walleij 			/* Keep accumulating status bits */
7557892497fSLinus Walleij 			host->busy_status |= status & (MCI_CMDSENT | MCI_CMDRESPEND);
756479d8e61SLinus Walleij 			if (status & host->variant->busy_detect_flag) {
757cb0335b7SLudovic Barre 				writel(readl(base + MMCIMASK0) |
758cb0335b7SLudovic Barre 				       host->variant->busy_detect_mask,
759cb0335b7SLudovic Barre 				       base + MMCIMASK0);
7607be5ac5fSLinus Walleij 				host->busy_state = MMCI_BUSY_WAITING_FOR_START_IRQ;
761b1a66593SUlf Hansson 				schedule_delayed_work(&host->ux500_busy_timeout_work,
762b1a66593SUlf Hansson 				      msecs_to_jiffies(cmd->busy_timeout));
763e85fecc3SLinus Walleij 				goto out_ret_state;
764cb0335b7SLudovic Barre 			}
7657892497fSLinus Walleij 			retries--;
7667892497fSLinus Walleij 		}
767*2eb277c2SLinus Walleij 		dev_dbg(mmc_dev(host->mmc),
768*2eb277c2SLinus Walleij 			"no busy signalling in time CMD%02x\n", cmd->opcode);
7694711c6abSLinus Walleij 		ux500_busy_clear_mask_done(host);
770ddb5a92dSLinus Walleij 		break;
771cb0335b7SLudovic Barre 
772cb0335b7SLudovic Barre 	/*
773cb0335b7SLudovic Barre 	 * If there is a command in-progress that has been successfully
774cb0335b7SLudovic Barre 	 * sent, then bail out if busy status is set and wait for the
775cb0335b7SLudovic Barre 	 * busy end IRQ.
776cb0335b7SLudovic Barre 	 *
777cb0335b7SLudovic Barre 	 * Note that, the HW triggers an IRQ on both edges while
778cb0335b7SLudovic Barre 	 * monitoring DAT0 for busy completion, but there is only one
779cb0335b7SLudovic Barre 	 * status bit in MMCISTATUS for the busy state. Therefore
780cb0335b7SLudovic Barre 	 * both the start and the end interrupts needs to be cleared,
781cb0335b7SLudovic Barre 	 * one after the other. So, clear the busy start IRQ here.
782cb0335b7SLudovic Barre 	 */
783ddb5a92dSLinus Walleij 	case MMCI_BUSY_WAITING_FOR_START_IRQ:
7847be5ac5fSLinus Walleij 		if (status & host->variant->busy_detect_flag) {
7858a6a9e79SLinus Walleij 			host->busy_status |= status & (MCI_CMDSENT | MCI_CMDRESPEND);
786cb0335b7SLudovic Barre 			writel(host->variant->busy_detect_mask, base + MMCICLEAR);
7877be5ac5fSLinus Walleij 			host->busy_state = MMCI_BUSY_WAITING_FOR_END_IRQ;
7887be5ac5fSLinus Walleij 		} else {
7897be5ac5fSLinus Walleij 			dev_dbg(mmc_dev(host->mmc),
790*2eb277c2SLinus Walleij 				"lost busy status when waiting for busy start IRQ CMD%02x\n",
791*2eb277c2SLinus Walleij 				cmd->opcode);
792b1a66593SUlf Hansson 			cancel_delayed_work(&host->ux500_busy_timeout_work);
7934711c6abSLinus Walleij 			ux500_busy_clear_mask_done(host);
7947be5ac5fSLinus Walleij 		}
795ddb5a92dSLinus Walleij 		break;
7967be5ac5fSLinus Walleij 
797ddb5a92dSLinus Walleij 	case MMCI_BUSY_WAITING_FOR_END_IRQ:
7987be5ac5fSLinus Walleij 		if (!(status & host->variant->busy_detect_flag)) {
7997be5ac5fSLinus Walleij 			host->busy_status |= status & (MCI_CMDSENT | MCI_CMDRESPEND);
8004711c6abSLinus Walleij 			writel(host->variant->busy_detect_mask, base + MMCICLEAR);
801b1a66593SUlf Hansson 			cancel_delayed_work(&host->ux500_busy_timeout_work);
8024711c6abSLinus Walleij 			ux500_busy_clear_mask_done(host);
8037be5ac5fSLinus Walleij 		} else {
8047be5ac5fSLinus Walleij 			dev_dbg(mmc_dev(host->mmc),
805*2eb277c2SLinus Walleij 				"busy status still asserted when handling busy end IRQ - will keep waiting CMD%02x\n",
806*2eb277c2SLinus Walleij 				cmd->opcode);
8077be5ac5fSLinus Walleij 		}
808ddb5a92dSLinus Walleij 		break;
809cb0335b7SLudovic Barre 
810ddb5a92dSLinus Walleij 	default:
811*2eb277c2SLinus Walleij 		dev_dbg(mmc_dev(host->mmc), "fell through on state %d, CMD%02x\n",
812*2eb277c2SLinus Walleij 			host->busy_state, cmd->opcode);
813ddb5a92dSLinus Walleij 		break;
814ddb5a92dSLinus Walleij 	}
815e85fecc3SLinus Walleij 
816e85fecc3SLinus Walleij out_ret_state:
817e85fecc3SLinus Walleij 	return (host->busy_state == MMCI_BUSY_DONE);
818cb0335b7SLudovic Barre }
819cb0335b7SLudovic Barre 
820c8ebae37SRussell King /*
821c8ebae37SRussell King  * All the DMA operation mode stuff goes inside this ifdef.
822c8ebae37SRussell King  * This assumes that you have a generic DMA device interface,
823c8ebae37SRussell King  * no custom DMA interfaces are supported.
824c8ebae37SRussell King  */
825c8ebae37SRussell King #ifdef CONFIG_DMA_ENGINE
826a813f2a2SLudovic Barre struct mmci_dmae_next {
827a813f2a2SLudovic Barre 	struct dma_async_tx_descriptor *desc;
828a813f2a2SLudovic Barre 	struct dma_chan	*chan;
829a813f2a2SLudovic Barre };
830a813f2a2SLudovic Barre 
831a813f2a2SLudovic Barre struct mmci_dmae_priv {
832a813f2a2SLudovic Barre 	struct dma_chan	*cur;
833a813f2a2SLudovic Barre 	struct dma_chan	*rx_channel;
834a813f2a2SLudovic Barre 	struct dma_chan	*tx_channel;
835a813f2a2SLudovic Barre 	struct dma_async_tx_descriptor	*desc_current;
836a813f2a2SLudovic Barre 	struct mmci_dmae_next next_data;
837a813f2a2SLudovic Barre };
838a813f2a2SLudovic Barre 
mmci_dmae_setup(struct mmci_host * host)839c3647fdcSLudovic Barre int mmci_dmae_setup(struct mmci_host *host)
840c8ebae37SRussell King {
841c8ebae37SRussell King 	const char *rxname, *txname;
842a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae;
843c8ebae37SRussell King 
844a813f2a2SLudovic Barre 	dmae = devm_kzalloc(mmc_dev(host->mmc), sizeof(*dmae), GFP_KERNEL);
845a813f2a2SLudovic Barre 	if (!dmae)
846a813f2a2SLudovic Barre 		return -ENOMEM;
847c8ebae37SRussell King 
848a813f2a2SLudovic Barre 	host->dma_priv = dmae;
849a813f2a2SLudovic Barre 
850716d0205SPeter Ujfalusi 	dmae->rx_channel = dma_request_chan(mmc_dev(host->mmc), "rx");
851716d0205SPeter Ujfalusi 	if (IS_ERR(dmae->rx_channel)) {
852716d0205SPeter Ujfalusi 		int ret = PTR_ERR(dmae->rx_channel);
853716d0205SPeter Ujfalusi 		dmae->rx_channel = NULL;
854716d0205SPeter Ujfalusi 		return ret;
855716d0205SPeter Ujfalusi 	}
856716d0205SPeter Ujfalusi 
857716d0205SPeter Ujfalusi 	dmae->tx_channel = dma_request_chan(mmc_dev(host->mmc), "tx");
858716d0205SPeter Ujfalusi 	if (IS_ERR(dmae->tx_channel)) {
859716d0205SPeter Ujfalusi 		if (PTR_ERR(dmae->tx_channel) == -EPROBE_DEFER)
860716d0205SPeter Ujfalusi 			dev_warn(mmc_dev(host->mmc),
861716d0205SPeter Ujfalusi 				 "Deferred probe for TX channel ignored\n");
862716d0205SPeter Ujfalusi 		dmae->tx_channel = NULL;
863716d0205SPeter Ujfalusi 	}
86458c7ccbfSPer Forlin 
8651fd83f0eSLee Jones 	/*
8661fd83f0eSLee Jones 	 * If only an RX channel is specified, the driver will
867f78bc9f2SXiang wangx 	 * attempt to use it bidirectionally, however if it
8681fd83f0eSLee Jones 	 * is specified but cannot be located, DMA will be disabled.
8691fd83f0eSLee Jones 	 */
870a813f2a2SLudovic Barre 	if (dmae->rx_channel && !dmae->tx_channel)
871a813f2a2SLudovic Barre 		dmae->tx_channel = dmae->rx_channel;
872c8ebae37SRussell King 
873a813f2a2SLudovic Barre 	if (dmae->rx_channel)
874a813f2a2SLudovic Barre 		rxname = dma_chan_name(dmae->rx_channel);
875c8ebae37SRussell King 	else
876c8ebae37SRussell King 		rxname = "none";
877c8ebae37SRussell King 
878a813f2a2SLudovic Barre 	if (dmae->tx_channel)
879a813f2a2SLudovic Barre 		txname = dma_chan_name(dmae->tx_channel);
880c8ebae37SRussell King 	else
881c8ebae37SRussell King 		txname = "none";
882c8ebae37SRussell King 
883c8ebae37SRussell King 	dev_info(mmc_dev(host->mmc), "DMA channels RX %s, TX %s\n",
884c8ebae37SRussell King 		 rxname, txname);
885c8ebae37SRussell King 
886c8ebae37SRussell King 	/*
887c8ebae37SRussell King 	 * Limit the maximum segment size in any SG entry according to
888c8ebae37SRussell King 	 * the parameters of the DMA engine device.
889c8ebae37SRussell King 	 */
890a813f2a2SLudovic Barre 	if (dmae->tx_channel) {
891a813f2a2SLudovic Barre 		struct device *dev = dmae->tx_channel->device->dev;
892c8ebae37SRussell King 		unsigned int max_seg_size = dma_get_max_seg_size(dev);
893c8ebae37SRussell King 
894c8ebae37SRussell King 		if (max_seg_size < host->mmc->max_seg_size)
895c8ebae37SRussell King 			host->mmc->max_seg_size = max_seg_size;
896c8ebae37SRussell King 	}
897a813f2a2SLudovic Barre 	if (dmae->rx_channel) {
898a813f2a2SLudovic Barre 		struct device *dev = dmae->rx_channel->device->dev;
899c8ebae37SRussell King 		unsigned int max_seg_size = dma_get_max_seg_size(dev);
900c8ebae37SRussell King 
901c8ebae37SRussell King 		if (max_seg_size < host->mmc->max_seg_size)
902c8ebae37SRussell King 			host->mmc->max_seg_size = max_seg_size;
903c8ebae37SRussell King 	}
9049cb15142SSrinivas Kandagatla 
905a813f2a2SLudovic Barre 	if (!dmae->tx_channel || !dmae->rx_channel) {
906c3647fdcSLudovic Barre 		mmci_dmae_release(host);
907c3647fdcSLudovic Barre 		return -EINVAL;
908c3647fdcSLudovic Barre 	}
909c3647fdcSLudovic Barre 
910c3647fdcSLudovic Barre 	return 0;
911c8ebae37SRussell King }
912c8ebae37SRussell King 
913c8ebae37SRussell King /*
9146e0ee714SBill Pemberton  * This is used in or so inline it
915c8ebae37SRussell King  * so it can be discarded.
916c8ebae37SRussell King  */
mmci_dmae_release(struct mmci_host * host)917c3647fdcSLudovic Barre void mmci_dmae_release(struct mmci_host *host)
918c8ebae37SRussell King {
919a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
920a813f2a2SLudovic Barre 
921a813f2a2SLudovic Barre 	if (dmae->rx_channel)
922a813f2a2SLudovic Barre 		dma_release_channel(dmae->rx_channel);
923a813f2a2SLudovic Barre 	if (dmae->tx_channel)
924a813f2a2SLudovic Barre 		dma_release_channel(dmae->tx_channel);
925a813f2a2SLudovic Barre 	dmae->rx_channel = dmae->tx_channel = NULL;
926c8ebae37SRussell King }
927c8ebae37SRussell King 
mmci_dma_unmap(struct mmci_host * host,struct mmc_data * data)928c8ebae37SRussell King static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data)
929c8ebae37SRussell King {
930a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
931653a761eSUlf Hansson 	struct dma_chan *chan;
932653a761eSUlf Hansson 
933feeef096SHeiner Kallweit 	if (data->flags & MMC_DATA_READ)
934a813f2a2SLudovic Barre 		chan = dmae->rx_channel;
935feeef096SHeiner Kallweit 	else
936a813f2a2SLudovic Barre 		chan = dmae->tx_channel;
937653a761eSUlf Hansson 
938feeef096SHeiner Kallweit 	dma_unmap_sg(chan->device->dev, data->sg, data->sg_len,
939feeef096SHeiner Kallweit 		     mmc_get_dma_dir(data));
940653a761eSUlf Hansson }
941653a761eSUlf Hansson 
mmci_dmae_error(struct mmci_host * host)942cfccc6acSLudovic Barre void mmci_dmae_error(struct mmci_host *host)
9437b2a6d51SLudovic Barre {
944a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
945a813f2a2SLudovic Barre 
946cfccc6acSLudovic Barre 	if (!dma_inprogress(host))
947cdea1947SLudovic Barre 		return;
948cdea1947SLudovic Barre 
9497b2a6d51SLudovic Barre 	dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n");
950a813f2a2SLudovic Barre 	dmaengine_terminate_all(dmae->cur);
9517b2a6d51SLudovic Barre 	host->dma_in_progress = false;
952a813f2a2SLudovic Barre 	dmae->cur = NULL;
953a813f2a2SLudovic Barre 	dmae->desc_current = NULL;
9547b2a6d51SLudovic Barre 	host->data->host_cookie = 0;
9557b2a6d51SLudovic Barre 
9567b2a6d51SLudovic Barre 	mmci_dma_unmap(host, host->data);
9577b2a6d51SLudovic Barre }
9587b2a6d51SLudovic Barre 
mmci_dmae_finalize(struct mmci_host * host,struct mmc_data * data)9595a9f10c3SLudovic Barre void mmci_dmae_finalize(struct mmci_host *host, struct mmc_data *data)
960653a761eSUlf Hansson {
961a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
962c8ebae37SRussell King 	u32 status;
963c8ebae37SRussell King 	int i;
964c8ebae37SRussell King 
9655a9f10c3SLudovic Barre 	if (!dma_inprogress(host))
966cdea1947SLudovic Barre 		return;
967cdea1947SLudovic Barre 
968c8ebae37SRussell King 	/* Wait up to 1ms for the DMA to complete */
969c8ebae37SRussell King 	for (i = 0; ; i++) {
970c8ebae37SRussell King 		status = readl(host->base + MMCISTATUS);
971c8ebae37SRussell King 		if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100)
972c8ebae37SRussell King 			break;
973c8ebae37SRussell King 		udelay(10);
974c8ebae37SRussell King 	}
975c8ebae37SRussell King 
976c8ebae37SRussell King 	/*
977c8ebae37SRussell King 	 * Check to see whether we still have some data left in the FIFO -
978c8ebae37SRussell King 	 * this catches DMA controllers which are unable to monitor the
979c8ebae37SRussell King 	 * DMALBREQ and DMALSREQ signals while allowing us to DMA to non-
980c8ebae37SRussell King 	 * contiguous buffers.  On TX, we'll get a FIFO underrun error.
981c8ebae37SRussell King 	 */
982c8ebae37SRussell King 	if (status & MCI_RXDATAAVLBLMASK) {
983cfccc6acSLudovic Barre 		mmci_dma_error(host);
984c8ebae37SRussell King 		if (!data->error)
985c8ebae37SRussell King 			data->error = -EIO;
9867b2a6d51SLudovic Barre 	} else if (!data->host_cookie) {
987653a761eSUlf Hansson 		mmci_dma_unmap(host, data);
9887b2a6d51SLudovic Barre 	}
989c8ebae37SRussell King 
990c8ebae37SRussell King 	/*
991c8ebae37SRussell King 	 * Use of DMA with scatter-gather is impossible.
992c8ebae37SRussell King 	 * Give up with DMA and switch back to PIO mode.
993c8ebae37SRussell King 	 */
994c8ebae37SRussell King 	if (status & MCI_RXDATAAVLBLMASK) {
995c8ebae37SRussell King 		dev_err(mmc_dev(host->mmc), "buggy DMA detected. Taking evasive action.\n");
996c8ebae37SRussell King 		mmci_dma_release(host);
997c8ebae37SRussell King 	}
998653a761eSUlf Hansson 
999e13934bdSLinus Walleij 	host->dma_in_progress = false;
1000a813f2a2SLudovic Barre 	dmae->cur = NULL;
1001a813f2a2SLudovic Barre 	dmae->desc_current = NULL;
1002c8ebae37SRussell King }
1003c8ebae37SRussell King 
1004653a761eSUlf Hansson /* prepares DMA channel and DMA descriptor, returns non-zero on failure */
_mmci_dmae_prep_data(struct mmci_host * host,struct mmc_data * data,struct dma_chan ** dma_chan,struct dma_async_tx_descriptor ** dma_desc)100547983510SLudovic Barre static int _mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data,
1006653a761eSUlf Hansson 				struct dma_chan **dma_chan,
1007653a761eSUlf Hansson 				struct dma_async_tx_descriptor **dma_desc)
1008c8ebae37SRussell King {
1009a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
1010c8ebae37SRussell King 	struct variant_data *variant = host->variant;
1011c8ebae37SRussell King 	struct dma_slave_config conf = {
1012c8ebae37SRussell King 		.src_addr = host->phybase + MMCIFIFO,
1013c8ebae37SRussell King 		.dst_addr = host->phybase + MMCIFIFO,
1014c8ebae37SRussell King 		.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
1015c8ebae37SRussell King 		.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
1016c8ebae37SRussell King 		.src_maxburst = variant->fifohalfsize >> 2, /* # of words */
1017c8ebae37SRussell King 		.dst_maxburst = variant->fifohalfsize >> 2, /* # of words */
1018258aea76SViresh Kumar 		.device_fc = false,
1019c8ebae37SRussell King 	};
1020c8ebae37SRussell King 	struct dma_chan *chan;
1021c8ebae37SRussell King 	struct dma_device *device;
1022c8ebae37SRussell King 	struct dma_async_tx_descriptor *desc;
1023c8ebae37SRussell King 	int nr_sg;
10249cb15142SSrinivas Kandagatla 	unsigned long flags = DMA_CTRL_ACK;
1025c8ebae37SRussell King 
1026c8ebae37SRussell King 	if (data->flags & MMC_DATA_READ) {
102705f5799cSVinod Koul 		conf.direction = DMA_DEV_TO_MEM;
1028a813f2a2SLudovic Barre 		chan = dmae->rx_channel;
1029c8ebae37SRussell King 	} else {
103005f5799cSVinod Koul 		conf.direction = DMA_MEM_TO_DEV;
1031a813f2a2SLudovic Barre 		chan = dmae->tx_channel;
1032c8ebae37SRussell King 	}
1033c8ebae37SRussell King 
1034c8ebae37SRussell King 	/* If there's no DMA channel, fall back to PIO */
1035c8ebae37SRussell King 	if (!chan)
1036c8ebae37SRussell King 		return -EINVAL;
1037c8ebae37SRussell King 
1038c8ebae37SRussell King 	/* If less than or equal to the fifo size, don't bother with DMA */
103958c7ccbfSPer Forlin 	if (data->blksz * data->blocks <= variant->fifosize)
1040c8ebae37SRussell King 		return -EINVAL;
1041c8ebae37SRussell King 
10422253ed4bSLinus Walleij 	/*
10432253ed4bSLinus Walleij 	 * This is necessary to get SDIO working on the Ux500. We do not yet
10442253ed4bSLinus Walleij 	 * know if this is a bug in:
10452253ed4bSLinus Walleij 	 * - The Ux500 DMA controller (DMA40)
10462253ed4bSLinus Walleij 	 * - The MMCI DMA interface on the Ux500
10472253ed4bSLinus Walleij 	 * some power of two blocks (such as 64 bytes) are sent regularly
10482253ed4bSLinus Walleij 	 * during SDIO traffic and those work fine so for these we enable DMA
10492253ed4bSLinus Walleij 	 * transfers.
10502253ed4bSLinus Walleij 	 */
10512253ed4bSLinus Walleij 	if (host->variant->dma_power_of_2 && !is_power_of_2(data->blksz))
10522253ed4bSLinus Walleij 		return -EINVAL;
10532253ed4bSLinus Walleij 
1054c8ebae37SRussell King 	device = chan->device;
1055feeef096SHeiner Kallweit 	nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len,
1056feeef096SHeiner Kallweit 			   mmc_get_dma_dir(data));
1057c8ebae37SRussell King 	if (nr_sg == 0)
1058c8ebae37SRussell King 		return -EINVAL;
1059c8ebae37SRussell King 
10609cb15142SSrinivas Kandagatla 	if (host->variant->qcom_dml)
10619cb15142SSrinivas Kandagatla 		flags |= DMA_PREP_INTERRUPT;
10629cb15142SSrinivas Kandagatla 
1063c8ebae37SRussell King 	dmaengine_slave_config(chan, &conf);
106416052827SAlexandre Bounine 	desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg,
10659cb15142SSrinivas Kandagatla 					    conf.direction, flags);
1066c8ebae37SRussell King 	if (!desc)
1067c8ebae37SRussell King 		goto unmap_exit;
1068c8ebae37SRussell King 
1069653a761eSUlf Hansson 	*dma_chan = chan;
1070653a761eSUlf Hansson 	*dma_desc = desc;
1071c8ebae37SRussell King 
107258c7ccbfSPer Forlin 	return 0;
107358c7ccbfSPer Forlin 
107458c7ccbfSPer Forlin  unmap_exit:
1075feeef096SHeiner Kallweit 	dma_unmap_sg(device->dev, data->sg, data->sg_len,
1076feeef096SHeiner Kallweit 		     mmc_get_dma_dir(data));
107758c7ccbfSPer Forlin 	return -ENOMEM;
107858c7ccbfSPer Forlin }
107958c7ccbfSPer Forlin 
mmci_dmae_prep_data(struct mmci_host * host,struct mmc_data * data,bool next)108047983510SLudovic Barre int mmci_dmae_prep_data(struct mmci_host *host,
1081ad7b8918SLudovic Barre 			struct mmc_data *data,
1082ad7b8918SLudovic Barre 			bool next)
1083653a761eSUlf Hansson {
1084a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
1085ad7b8918SLudovic Barre 	struct mmci_dmae_next *nd = &dmae->next_data;
1086a813f2a2SLudovic Barre 
108747983510SLudovic Barre 	if (!host->use_dma)
108847983510SLudovic Barre 		return -EINVAL;
108947983510SLudovic Barre 
1090ad7b8918SLudovic Barre 	if (next)
109147983510SLudovic Barre 		return _mmci_dmae_prep_data(host, data, &nd->chan, &nd->desc);
1092653a761eSUlf Hansson 	/* Check if next job is already prepared. */
1093a813f2a2SLudovic Barre 	if (dmae->cur && dmae->desc_current)
1094653a761eSUlf Hansson 		return 0;
1095653a761eSUlf Hansson 
1096653a761eSUlf Hansson 	/* No job were prepared thus do it now. */
109747983510SLudovic Barre 	return _mmci_dmae_prep_data(host, data, &dmae->cur,
1098a813f2a2SLudovic Barre 				    &dmae->desc_current);
1099653a761eSUlf Hansson }
1100653a761eSUlf Hansson 
mmci_dmae_start(struct mmci_host * host,unsigned int * datactrl)1101135ea30eSLudovic Barre int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl)
110258c7ccbfSPer Forlin {
1103a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
11042253ed4bSLinus Walleij 	int ret;
110558c7ccbfSPer Forlin 
1106e13934bdSLinus Walleij 	host->dma_in_progress = true;
11072253ed4bSLinus Walleij 	ret = dma_submit_error(dmaengine_submit(dmae->desc_current));
11082253ed4bSLinus Walleij 	if (ret < 0) {
11092253ed4bSLinus Walleij 		host->dma_in_progress = false;
11102253ed4bSLinus Walleij 		return ret;
11112253ed4bSLinus Walleij 	}
1112a813f2a2SLudovic Barre 	dma_async_issue_pending(dmae->cur);
1113c8ebae37SRussell King 
1114135ea30eSLudovic Barre 	*datactrl |= MCI_DPSM_DMAENABLE;
1115c8ebae37SRussell King 
1116c8ebae37SRussell King 	return 0;
1117c8ebae37SRussell King }
111858c7ccbfSPer Forlin 
mmci_dmae_get_next_data(struct mmci_host * host,struct mmc_data * data)111902769968SLudovic Barre void mmci_dmae_get_next_data(struct mmci_host *host, struct mmc_data *data)
112058c7ccbfSPer Forlin {
1121a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
1122a813f2a2SLudovic Barre 	struct mmci_dmae_next *next = &dmae->next_data;
112358c7ccbfSPer Forlin 
1124c3647fdcSLudovic Barre 	if (!host->use_dma)
1125c3647fdcSLudovic Barre 		return;
1126c3647fdcSLudovic Barre 
1127a813f2a2SLudovic Barre 	WARN_ON(!data->host_cookie && (next->desc || next->chan));
112858c7ccbfSPer Forlin 
1129a813f2a2SLudovic Barre 	dmae->desc_current = next->desc;
1130a813f2a2SLudovic Barre 	dmae->cur = next->chan;
1131a813f2a2SLudovic Barre 	next->desc = NULL;
1132a813f2a2SLudovic Barre 	next->chan = NULL;
113358c7ccbfSPer Forlin }
113458c7ccbfSPer Forlin 
mmci_dmae_unprep_data(struct mmci_host * host,struct mmc_data * data,int err)113547983510SLudovic Barre void mmci_dmae_unprep_data(struct mmci_host *host,
113647983510SLudovic Barre 			   struct mmc_data *data, int err)
113747983510SLudovic Barre 
113858c7ccbfSPer Forlin {
1139a813f2a2SLudovic Barre 	struct mmci_dmae_priv *dmae = host->dma_priv;
114058c7ccbfSPer Forlin 
114147983510SLudovic Barre 	if (!host->use_dma)
114258c7ccbfSPer Forlin 		return;
114358c7ccbfSPer Forlin 
1144653a761eSUlf Hansson 	mmci_dma_unmap(host, data);
1145653a761eSUlf Hansson 
1146653a761eSUlf Hansson 	if (err) {
1147a813f2a2SLudovic Barre 		struct mmci_dmae_next *next = &dmae->next_data;
1148653a761eSUlf Hansson 		struct dma_chan *chan;
1149653a761eSUlf Hansson 		if (data->flags & MMC_DATA_READ)
1150a813f2a2SLudovic Barre 			chan = dmae->rx_channel;
1151653a761eSUlf Hansson 		else
1152a813f2a2SLudovic Barre 			chan = dmae->tx_channel;
115358c7ccbfSPer Forlin 		dmaengine_terminate_all(chan);
1154653a761eSUlf Hansson 
1155a813f2a2SLudovic Barre 		if (dmae->desc_current == next->desc)
1156a813f2a2SLudovic Barre 			dmae->desc_current = NULL;
1157b5c16a60SSrinivas Kandagatla 
1158a813f2a2SLudovic Barre 		if (dmae->cur == next->chan) {
1159e13934bdSLinus Walleij 			host->dma_in_progress = false;
1160a813f2a2SLudovic Barre 			dmae->cur = NULL;
1161e13934bdSLinus Walleij 		}
1162b5c16a60SSrinivas Kandagatla 
1163a813f2a2SLudovic Barre 		next->desc = NULL;
1164a813f2a2SLudovic Barre 		next->chan = NULL;
116558c7ccbfSPer Forlin 	}
116658c7ccbfSPer Forlin }
116758c7ccbfSPer Forlin 
1168c3647fdcSLudovic Barre static struct mmci_host_ops mmci_variant_ops = {
116947983510SLudovic Barre 	.prep_data = mmci_dmae_prep_data,
117047983510SLudovic Barre 	.unprep_data = mmci_dmae_unprep_data,
1171b3fb9d64SLudovic Barre 	.get_datactrl_cfg = mmci_get_dctrl_cfg,
117202769968SLudovic Barre 	.get_next_data = mmci_dmae_get_next_data,
1173c3647fdcSLudovic Barre 	.dma_setup = mmci_dmae_setup,
1174c3647fdcSLudovic Barre 	.dma_release = mmci_dmae_release,
1175135ea30eSLudovic Barre 	.dma_start = mmci_dmae_start,
11765a9f10c3SLudovic Barre 	.dma_finalize = mmci_dmae_finalize,
1177cfccc6acSLudovic Barre 	.dma_error = mmci_dmae_error,
1178c3647fdcSLudovic Barre };
1179b3fb9d64SLudovic Barre #else
1180b3fb9d64SLudovic Barre static struct mmci_host_ops mmci_variant_ops = {
1181b3fb9d64SLudovic Barre 	.get_datactrl_cfg = mmci_get_dctrl_cfg,
1182b3fb9d64SLudovic Barre };
1183b3fb9d64SLudovic Barre #endif
1184c3647fdcSLudovic Barre 
mmci_variant_init(struct mmci_host * host)1185e2b98d83SBen Dooks static void mmci_variant_init(struct mmci_host *host)
1186c3647fdcSLudovic Barre {
1187c3647fdcSLudovic Barre 	host->ops = &mmci_variant_ops;
1188c3647fdcSLudovic Barre }
1189b3fb9d64SLudovic Barre 
ux500_variant_init(struct mmci_host * host)1190cb0335b7SLudovic Barre static void ux500_variant_init(struct mmci_host *host)
1191cb0335b7SLudovic Barre {
1192cb0335b7SLudovic Barre 	host->ops = &mmci_variant_ops;
1193cb0335b7SLudovic Barre 	host->ops->busy_complete = ux500_busy_complete;
1194cb0335b7SLudovic Barre }
1195cb0335b7SLudovic Barre 
ux500v2_variant_init(struct mmci_host * host)1196e2b98d83SBen Dooks static void ux500v2_variant_init(struct mmci_host *host)
1197b3fb9d64SLudovic Barre {
1198b3fb9d64SLudovic Barre 	host->ops = &mmci_variant_ops;
1199cb0335b7SLudovic Barre 	host->ops->busy_complete = ux500_busy_complete;
1200b3fb9d64SLudovic Barre 	host->ops->get_datactrl_cfg = ux500v2_get_dctrl_cfg;
1201b3fb9d64SLudovic Barre }
1202c8ebae37SRussell King 
mmci_pre_request(struct mmc_host * mmc,struct mmc_request * mrq)120347983510SLudovic Barre static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq)
120447983510SLudovic Barre {
120547983510SLudovic Barre 	struct mmci_host *host = mmc_priv(mmc);
120647983510SLudovic Barre 	struct mmc_data *data = mrq->data;
120747983510SLudovic Barre 
120847983510SLudovic Barre 	if (!data)
120947983510SLudovic Barre 		return;
121047983510SLudovic Barre 
121147983510SLudovic Barre 	WARN_ON(data->host_cookie);
121247983510SLudovic Barre 
121347983510SLudovic Barre 	if (mmci_validate_data(host, data))
121447983510SLudovic Barre 		return;
121547983510SLudovic Barre 
121647983510SLudovic Barre 	mmci_prep_data(host, data, true);
121747983510SLudovic Barre }
121847983510SLudovic Barre 
mmci_post_request(struct mmc_host * mmc,struct mmc_request * mrq,int err)121947983510SLudovic Barre static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq,
122047983510SLudovic Barre 			      int err)
122147983510SLudovic Barre {
122247983510SLudovic Barre 	struct mmci_host *host = mmc_priv(mmc);
122347983510SLudovic Barre 	struct mmc_data *data = mrq->data;
122447983510SLudovic Barre 
122547983510SLudovic Barre 	if (!data || !data->host_cookie)
122647983510SLudovic Barre 		return;
122747983510SLudovic Barre 
122847983510SLudovic Barre 	mmci_unprep_data(host, data, err);
122947983510SLudovic Barre }
123047983510SLudovic Barre 
mmci_start_data(struct mmci_host * host,struct mmc_data * data)12311c6a0718SPierre Ossman static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
12321c6a0718SPierre Ossman {
12338301bb68SRabin Vincent 	struct variant_data *variant = host->variant;
12341c6a0718SPierre Ossman 	unsigned int datactrl, timeout, irqmask;
12351c6a0718SPierre Ossman 	unsigned long long clks;
12361c6a0718SPierre Ossman 	void __iomem *base;
12371c6a0718SPierre Ossman 
123864de0289SLinus Walleij 	dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n",
12391c6a0718SPierre Ossman 		data->blksz, data->blocks, data->flags);
12401c6a0718SPierre Ossman 
12411c6a0718SPierre Ossman 	host->data = data;
1242528320dbSRabin Vincent 	host->size = data->blksz * data->blocks;
124351d4375dSRussell King 	data->bytes_xfered = 0;
12441c6a0718SPierre Ossman 
12451c6a0718SPierre Ossman 	clks = (unsigned long long)data->timeout_ns * host->cclk;
1246c4a35769SSrinivas Kandagatla 	do_div(clks, NSEC_PER_SEC);
12471c6a0718SPierre Ossman 
12481c6a0718SPierre Ossman 	timeout = data->timeout_clks + (unsigned int)clks;
12491c6a0718SPierre Ossman 
12501c6a0718SPierre Ossman 	base = host->base;
12511c6a0718SPierre Ossman 	writel(timeout, base + MMCIDATATIMER);
12521c6a0718SPierre Ossman 	writel(host->size, base + MMCIDATALENGTH);
12531c6a0718SPierre Ossman 
125441ed65e7SLudovic Barre 	datactrl = host->ops->get_datactrl_cfg(host);
125541ed65e7SLudovic Barre 	datactrl |= host->data->flags & MMC_DATA_READ ? MCI_DPSM_DIRECTION : 0;
1256c8ebae37SRussell King 
1257c7354133SSrinivas Kandagatla 	if (host->mmc->card && mmc_card_sdio(host->mmc->card)) {
125806c1a121SUlf Hansson 		u32 clk;
1259c7354133SSrinivas Kandagatla 
12605df014dfSSrinivas Kandagatla 		datactrl |= variant->datactrl_mask_sdio;
12617258db7eSUlf Hansson 
1262c8ebae37SRussell King 		/*
126370ac0935SUlf Hansson 		 * The ST Micro variant for SDIO small write transfers
126470ac0935SUlf Hansson 		 * needs to have clock H/W flow control disabled,
126570ac0935SUlf Hansson 		 * otherwise the transfer will not start. The threshold
126670ac0935SUlf Hansson 		 * depends on the rate of MCLK.
126706c1a121SUlf Hansson 		 */
1268c7354133SSrinivas Kandagatla 		if (variant->st_sdio && data->flags & MMC_DATA_WRITE &&
126970ac0935SUlf Hansson 		    (host->size < 8 ||
127070ac0935SUlf Hansson 		     (host->size <= 8 && host->mclk > 50000000)))
127106c1a121SUlf Hansson 			clk = host->clk_reg & ~variant->clkreg_enable;
127206c1a121SUlf Hansson 		else
127306c1a121SUlf Hansson 			clk = host->clk_reg | variant->clkreg_enable;
127406c1a121SUlf Hansson 
127506c1a121SUlf Hansson 		mmci_write_clkreg(host, clk);
127606c1a121SUlf Hansson 	}
127706c1a121SUlf Hansson 
12786dad6c95SSeungwon Jeon 	if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 ||
12796dad6c95SSeungwon Jeon 	    host->mmc->ios.timing == MMC_TIMING_MMC_DDR52)
1280e17dca2bSSrinivas Kandagatla 		datactrl |= variant->datactrl_mask_ddrmode;
12816dbb6ee0SUlf Hansson 
128206c1a121SUlf Hansson 	/*
1283c8ebae37SRussell King 	 * Attempt to use DMA operation mode, if this
1284c8ebae37SRussell King 	 * should fail, fall back to PIO mode
1285c8ebae37SRussell King 	 */
1286135ea30eSLudovic Barre 	if (!mmci_dma_start(host, datactrl))
1287c8ebae37SRussell King 		return;
1288c8ebae37SRussell King 
1289c8ebae37SRussell King 	/* IRQ mode, map the SG list for CPU reading/writing */
1290c8ebae37SRussell King 	mmci_init_sg(host, data);
1291c8ebae37SRussell King 
1292c8ebae37SRussell King 	if (data->flags & MMC_DATA_READ) {
12931c6a0718SPierre Ossman 		irqmask = MCI_RXFIFOHALFFULLMASK;
12941c6a0718SPierre Ossman 
12951c6a0718SPierre Ossman 		/*
1296c4d877c1SRussell King 		 * If we have less than the fifo 'half-full' threshold to
1297c4d877c1SRussell King 		 * transfer, trigger a PIO interrupt as soon as any data
1298c4d877c1SRussell King 		 * is available.
12991c6a0718SPierre Ossman 		 */
1300c4d877c1SRussell King 		if (host->size < variant->fifohalfsize)
13011c6a0718SPierre Ossman 			irqmask |= MCI_RXDATAAVLBLMASK;
13021c6a0718SPierre Ossman 	} else {
13031c6a0718SPierre Ossman 		/*
13041c6a0718SPierre Ossman 		 * We don't actually need to include "FIFO empty" here
13051c6a0718SPierre Ossman 		 * since its implicit in "FIFO half empty".
13061c6a0718SPierre Ossman 		 */
13071c6a0718SPierre Ossman 		irqmask = MCI_TXFIFOHALFEMPTYMASK;
13081c6a0718SPierre Ossman 	}
13091c6a0718SPierre Ossman 
13109cc639a2SUlf Hansson 	mmci_write_datactrlreg(host, datactrl);
13111c6a0718SPierre Ossman 	writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
13122686b4b4SLinus Walleij 	mmci_set_mask1(host, irqmask);
13131c6a0718SPierre Ossman }
13141c6a0718SPierre Ossman 
13151c6a0718SPierre Ossman static void
mmci_start_command(struct mmci_host * host,struct mmc_command * cmd,u32 c)13161c6a0718SPierre Ossman mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
13171c6a0718SPierre Ossman {
13181c6a0718SPierre Ossman 	void __iomem *base = host->base;
1319b1a66593SUlf Hansson 	bool busy_resp = cmd->flags & MMC_RSP_BUSY;
13208266c585SLudovic Barre 	unsigned long long clks;
13211c6a0718SPierre Ossman 
132264de0289SLinus Walleij 	dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n",
13231c6a0718SPierre Ossman 	    cmd->opcode, cmd->arg, cmd->flags);
13241c6a0718SPierre Ossman 
13250f244804SLudovic Barre 	if (readl(base + MMCICOMMAND) & host->variant->cmdreg_cpsm_enable) {
13261c6a0718SPierre Ossman 		writel(0, base + MMCICOMMAND);
13276adb2a80SSrinivas Kandagatla 		mmci_reg_delay(host);
13281c6a0718SPierre Ossman 	}
13291c6a0718SPierre Ossman 
1330c8073e52SLudovic Barre 	if (host->variant->cmdreg_stop &&
1331c8073e52SLudovic Barre 	    cmd->opcode == MMC_STOP_TRANSMISSION)
1332c8073e52SLudovic Barre 		c |= host->variant->cmdreg_stop;
1333c8073e52SLudovic Barre 
13340f244804SLudovic Barre 	c |= cmd->opcode | host->variant->cmdreg_cpsm_enable;
13351c6a0718SPierre Ossman 	if (cmd->flags & MMC_RSP_PRESENT) {
13361c6a0718SPierre Ossman 		if (cmd->flags & MMC_RSP_136)
13370f244804SLudovic Barre 			c |= host->variant->cmdreg_lrsp_crc;
13380f244804SLudovic Barre 		else if (cmd->flags & MMC_RSP_CRC)
13390f244804SLudovic Barre 			c |= host->variant->cmdreg_srsp_crc;
13400f244804SLudovic Barre 		else
13410f244804SLudovic Barre 			c |= host->variant->cmdreg_srsp;
13421c6a0718SPierre Ossman 	}
13438266c585SLudovic Barre 
13442673493fSLinus Walleij 	host->busy_status = 0;
13457be5ac5fSLinus Walleij 	host->busy_state = MMCI_BUSY_DONE;
13467be5ac5fSLinus Walleij 
1347b1a66593SUlf Hansson 	/* Assign a default timeout if the core does not provide one */
1348b1a66593SUlf Hansson 	if (busy_resp && !cmd->busy_timeout)
13498266c585SLudovic Barre 		cmd->busy_timeout = 10 * MSEC_PER_SEC;
13508266c585SLudovic Barre 
1351b1a66593SUlf Hansson 	if (busy_resp && host->variant->busy_timeout) {
1352774514bfSYann Gautier 		if (cmd->busy_timeout > host->mmc->max_busy_timeout)
1353774514bfSYann Gautier 			clks = (unsigned long long)host->mmc->max_busy_timeout * host->cclk;
1354774514bfSYann Gautier 		else
13558266c585SLudovic Barre 			clks = (unsigned long long)cmd->busy_timeout * host->cclk;
1356774514bfSYann Gautier 
13578266c585SLudovic Barre 		do_div(clks, MSEC_PER_SEC);
13588266c585SLudovic Barre 		writel_relaxed(clks, host->base + MMCIDATATIMER);
13598266c585SLudovic Barre 	}
13608266c585SLudovic Barre 
136175773165SLudovic Barre 	if (host->ops->pre_sig_volt_switch && cmd->opcode == SD_SWITCH_VOLTAGE)
136275773165SLudovic Barre 		host->ops->pre_sig_volt_switch(host);
136375773165SLudovic Barre 
13641c6a0718SPierre Ossman 	if (/*interrupt*/0)
13651c6a0718SPierre Ossman 		c |= MCI_CPSM_INTERRUPT;
13661c6a0718SPierre Ossman 
1367ae7b0061SSrinivas Kandagatla 	if (mmc_cmd_type(cmd) == MMC_CMD_ADTC)
1368ae7b0061SSrinivas Kandagatla 		c |= host->variant->data_cmd_enable;
1369ae7b0061SSrinivas Kandagatla 
13701c6a0718SPierre Ossman 	host->cmd = cmd;
13711c6a0718SPierre Ossman 
13721c6a0718SPierre Ossman 	writel(cmd->arg, base + MMCIARGUMENT);
13731c6a0718SPierre Ossman 	writel(c, base + MMCICOMMAND);
13741c6a0718SPierre Ossman }
13751c6a0718SPierre Ossman 
mmci_stop_command(struct mmci_host * host)1376e9968c6fSUlf Hansson static void mmci_stop_command(struct mmci_host *host)
1377e9968c6fSUlf Hansson {
1378e9968c6fSUlf Hansson 	host->stop_abort.error = 0;
1379e9968c6fSUlf Hansson 	mmci_start_command(host, &host->stop_abort, 0);
1380e9968c6fSUlf Hansson }
1381e9968c6fSUlf Hansson 
13821c6a0718SPierre Ossman static void
mmci_data_irq(struct mmci_host * host,struct mmc_data * data,unsigned int status)13831c6a0718SPierre Ossman mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
13841c6a0718SPierre Ossman 	      unsigned int status)
13851c6a0718SPierre Ossman {
1386daf9713cSLudovic Barre 	unsigned int status_err;
1387daf9713cSLudovic Barre 
13881cb9da50SUlf Hansson 	/* Make sure we have data to handle */
13891cb9da50SUlf Hansson 	if (!data)
13901cb9da50SUlf Hansson 		return;
13911cb9da50SUlf Hansson 
1392f20f8f21SLinus Walleij 	/* First check for errors */
1393daf9713cSLudovic Barre 	status_err = status & (host->variant->start_err |
1394daf9713cSLudovic Barre 			       MCI_DATACRCFAIL | MCI_DATATIMEOUT |
1395daf9713cSLudovic Barre 			       MCI_TXUNDERRUN | MCI_RXOVERRUN);
1396daf9713cSLudovic Barre 
1397daf9713cSLudovic Barre 	if (status_err) {
13988cb28155SLinus Walleij 		u32 remain, success;
1399f20f8f21SLinus Walleij 
1400c8ebae37SRussell King 		/* Terminate the DMA transfer */
1401cfccc6acSLudovic Barre 		mmci_dma_error(host);
1402c8ebae37SRussell King 
1403c8afc9d5SRussell King 		/*
1404c8afc9d5SRussell King 		 * Calculate how far we are into the transfer.  Note that
1405c8afc9d5SRussell King 		 * the data counter gives the number of bytes transferred
1406c8afc9d5SRussell King 		 * on the MMC bus, not on the host side.  On reads, this
1407c8afc9d5SRussell King 		 * can be as much as a FIFO-worth of data ahead.  This
1408c8afc9d5SRussell King 		 * matters for FIFO overruns only.
1409c8afc9d5SRussell King 		 */
1410b79220b3SLudovic Barre 		if (!host->variant->datacnt_useless) {
1411f5a106d9SLinus Walleij 			remain = readl(host->base + MMCIDATACNT);
14128cb28155SLinus Walleij 			success = data->blksz * data->blocks - remain;
1413b79220b3SLudovic Barre 		} else {
1414b79220b3SLudovic Barre 			success = 0;
1415b79220b3SLudovic Barre 		}
14168cb28155SLinus Walleij 
1417c8afc9d5SRussell King 		dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ, status 0x%08x at 0x%08x\n",
1418daf9713cSLudovic Barre 			status_err, success);
1419daf9713cSLudovic Barre 		if (status_err & MCI_DATACRCFAIL) {
14208cb28155SLinus Walleij 			/* Last block was not successful */
1421c8afc9d5SRussell King 			success -= 1;
142217b0429dSPierre Ossman 			data->error = -EILSEQ;
1423daf9713cSLudovic Barre 		} else if (status_err & MCI_DATATIMEOUT) {
142417b0429dSPierre Ossman 			data->error = -ETIMEDOUT;
1425daf9713cSLudovic Barre 		} else if (status_err & MCI_STARTBITERR) {
1426757df746SLinus Walleij 			data->error = -ECOMM;
1427daf9713cSLudovic Barre 		} else if (status_err & MCI_TXUNDERRUN) {
142817b0429dSPierre Ossman 			data->error = -EIO;
1429daf9713cSLudovic Barre 		} else if (status_err & MCI_RXOVERRUN) {
1430c8afc9d5SRussell King 			if (success > host->variant->fifosize)
1431c8afc9d5SRussell King 				success -= host->variant->fifosize;
1432c8afc9d5SRussell King 			else
1433c8afc9d5SRussell King 				success = 0;
14348cb28155SLinus Walleij 			data->error = -EIO;
14354ce1d6cbSRabin Vincent 		}
143651d4375dSRussell King 		data->bytes_xfered = round_down(success, data->blksz);
14371c6a0718SPierre Ossman 	}
1438f20f8f21SLinus Walleij 
14398cb28155SLinus Walleij 	if (status & MCI_DATABLOCKEND)
14408cb28155SLinus Walleij 		dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n");
1441f20f8f21SLinus Walleij 
1442ccff9b51SRussell King 	if (status & MCI_DATAEND || data->error) {
1443653a761eSUlf Hansson 		mmci_dma_finalize(host, data);
1444cdea1947SLudovic Barre 
14451c6a0718SPierre Ossman 		mmci_stop_data(host);
14461c6a0718SPierre Ossman 
14478cb28155SLinus Walleij 		if (!data->error)
14488cb28155SLinus Walleij 			/* The error clause is handled above, success! */
144951d4375dSRussell King 			data->bytes_xfered = data->blksz * data->blocks;
1450f20f8f21SLinus Walleij 
1451e9968c6fSUlf Hansson 		if (!data->stop) {
1452e9968c6fSUlf Hansson 			if (host->variant->cmdreg_stop && data->error)
1453e9968c6fSUlf Hansson 				mmci_stop_command(host);
145409b4f706SLudovic Barre 			else
1455e9968c6fSUlf Hansson 				mmci_request_end(host, data->mrq);
1456e9968c6fSUlf Hansson 		} else if (host->mrq->sbc && !data->error) {
1457e9968c6fSUlf Hansson 			mmci_request_end(host, data->mrq);
1458e9968c6fSUlf Hansson 		} else {
14591c6a0718SPierre Ossman 			mmci_start_command(host, data->stop, 0);
14601c6a0718SPierre Ossman 		}
14611c6a0718SPierre Ossman 	}
1462e9968c6fSUlf Hansson }
14631c6a0718SPierre Ossman 
14641c6a0718SPierre Ossman static void
mmci_cmd_irq(struct mmci_host * host,struct mmc_command * cmd,unsigned int status)14651c6a0718SPierre Ossman mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
14661c6a0718SPierre Ossman 	     unsigned int status)
14671c6a0718SPierre Ossman {
14688266c585SLudovic Barre 	u32 err_msk = MCI_CMDCRCFAIL | MCI_CMDTIMEOUT;
14691c6a0718SPierre Ossman 	void __iomem *base = host->base;
1470812513c7SLudovic Barre 	bool sbc, busy_resp;
1471ad82bfeaSUlf Hansson 
1472ad82bfeaSUlf Hansson 	if (!cmd)
1473ad82bfeaSUlf Hansson 		return;
1474ad82bfeaSUlf Hansson 
1475ad82bfeaSUlf Hansson 	sbc = (cmd == host->mrq->sbc);
1476812513c7SLudovic Barre 	busy_resp = !!(cmd->flags & MMC_RSP_BUSY);
1477ad82bfeaSUlf Hansson 
147849adc0caSLinus Walleij 	/*
147949adc0caSLinus Walleij 	 * We need to be one of these interrupts to be considered worth
148049adc0caSLinus Walleij 	 * handling. Note that we tag on any latent IRQs postponed
148149adc0caSLinus Walleij 	 * due to waiting for busy status.
148249adc0caSLinus Walleij 	 */
14838266c585SLudovic Barre 	if (host->variant->busy_timeout && busy_resp)
14848266c585SLudovic Barre 		err_msk |= MCI_DATATIMEOUT;
14858266c585SLudovic Barre 
148649adc0caSLinus Walleij 	if (!((status | host->busy_status) &
14878266c585SLudovic Barre 	      (err_msk | MCI_CMDSENT | MCI_CMDRESPEND)))
1488ad82bfeaSUlf Hansson 		return;
14898d94b54dSUlf Hansson 
1490a9cbd79cSUlf Hansson 	/* Handle busy detection on DAT0 if the variant supports it. */
1491cb0335b7SLudovic Barre 	if (busy_resp && host->variant->busy_detect)
1492b1a66593SUlf Hansson 		if (!host->ops->busy_complete(host, cmd, status, err_msk))
14938d94b54dSUlf Hansson 			return;
14941c6a0718SPierre Ossman 
14951c6a0718SPierre Ossman 	host->cmd = NULL;
14961c6a0718SPierre Ossman 
14971c6a0718SPierre Ossman 	if (status & MCI_CMDTIMEOUT) {
149817b0429dSPierre Ossman 		cmd->error = -ETIMEDOUT;
14991c6a0718SPierre Ossman 	} else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) {
150017b0429dSPierre Ossman 		cmd->error = -EILSEQ;
15018266c585SLudovic Barre 	} else if (host->variant->busy_timeout && busy_resp &&
15028266c585SLudovic Barre 		   status & MCI_DATATIMEOUT) {
15038266c585SLudovic Barre 		cmd->error = -ETIMEDOUT;
1504546b73abSLinus Walleij 		/*
1505546b73abSLinus Walleij 		 * This will wake up mmci_irq_thread() which will issue
1506546b73abSLinus Walleij 		 * a hardware reset of the MMCI block.
1507546b73abSLinus Walleij 		 */
1508ee157abeSLudovic Barre 		host->irq_action = IRQ_WAKE_THREAD;
15099047b435SRussell King - ARM Linux 	} else {
15109047b435SRussell King - ARM Linux 		cmd->resp[0] = readl(base + MMCIRESPONSE0);
15119047b435SRussell King - ARM Linux 		cmd->resp[1] = readl(base + MMCIRESPONSE1);
15129047b435SRussell King - ARM Linux 		cmd->resp[2] = readl(base + MMCIRESPONSE2);
15139047b435SRussell King - ARM Linux 		cmd->resp[3] = readl(base + MMCIRESPONSE3);
15141c6a0718SPierre Ossman 	}
15151c6a0718SPierre Ossman 
1516024629c6SUlf Hansson 	if ((!sbc && !cmd->data) || cmd->error) {
15173b6e3c73SUlf Hansson 		if (host->data) {
15183b6e3c73SUlf Hansson 			/* Terminate the DMA transfer */
1519cfccc6acSLudovic Barre 			mmci_dma_error(host);
15207b2a6d51SLudovic Barre 
15211c6a0718SPierre Ossman 			mmci_stop_data(host);
1522e9968c6fSUlf Hansson 			if (host->variant->cmdreg_stop && cmd->error) {
1523e9968c6fSUlf Hansson 				mmci_stop_command(host);
1524e9968c6fSUlf Hansson 				return;
1525e9968c6fSUlf Hansson 			}
15263b6e3c73SUlf Hansson 		}
1527ee157abeSLudovic Barre 
1528ee157abeSLudovic Barre 		if (host->irq_action != IRQ_WAKE_THREAD)
1529024629c6SUlf Hansson 			mmci_request_end(host, host->mrq);
1530ee157abeSLudovic Barre 
1531024629c6SUlf Hansson 	} else if (sbc) {
1532024629c6SUlf Hansson 		mmci_start_command(host, host->mrq->cmd, 0);
1533d2141547SLudovic Barre 	} else if (!host->variant->datactrl_first &&
1534d2141547SLudovic Barre 		   !(cmd->data->flags & MMC_DATA_READ)) {
15351c6a0718SPierre Ossman 		mmci_start_data(host, cmd->data);
15361c6a0718SPierre Ossman 	}
15371c6a0718SPierre Ossman }
15381c6a0718SPierre Ossman 
ux500_state_str(struct mmci_host * host)1539*2eb277c2SLinus Walleij static char *ux500_state_str(struct mmci_host *host)
1540*2eb277c2SLinus Walleij {
1541*2eb277c2SLinus Walleij 	switch (host->busy_state) {
1542*2eb277c2SLinus Walleij 	case MMCI_BUSY_WAITING_FOR_START_IRQ:
1543*2eb277c2SLinus Walleij 		return "waiting for start IRQ";
1544*2eb277c2SLinus Walleij 	case MMCI_BUSY_WAITING_FOR_END_IRQ:
1545*2eb277c2SLinus Walleij 		return "waiting for end IRQ";
1546*2eb277c2SLinus Walleij 	case MMCI_BUSY_DONE:
1547*2eb277c2SLinus Walleij 		return "not waiting for IRQs";
1548*2eb277c2SLinus Walleij 	default:
1549*2eb277c2SLinus Walleij 		return "unknown";
1550*2eb277c2SLinus Walleij 	}
1551*2eb277c2SLinus Walleij }
1552*2eb277c2SLinus Walleij 
1553b1a66593SUlf Hansson /*
1554b1a66593SUlf Hansson  * This busy timeout worker is used to "kick" the command IRQ if a
1555b1a66593SUlf Hansson  * busy detect IRQ fails to appear in reasonable time. Only used on
1556b1a66593SUlf Hansson  * variants with busy detection IRQ delivery.
1557b1a66593SUlf Hansson  */
ux500_busy_timeout_work(struct work_struct * work)1558b1a66593SUlf Hansson static void ux500_busy_timeout_work(struct work_struct *work)
1559b1a66593SUlf Hansson {
1560b1a66593SUlf Hansson 	struct mmci_host *host = container_of(work, struct mmci_host,
1561b1a66593SUlf Hansson 					ux500_busy_timeout_work.work);
1562b1a66593SUlf Hansson 	unsigned long flags;
1563b1a66593SUlf Hansson 	u32 status;
1564b1a66593SUlf Hansson 
1565b1a66593SUlf Hansson 	spin_lock_irqsave(&host->lock, flags);
1566b1a66593SUlf Hansson 
1567b1a66593SUlf Hansson 	if (host->cmd) {
1568b1a66593SUlf Hansson 		/* If we are still busy let's tag on a cmd-timeout error. */
1569b1a66593SUlf Hansson 		status = readl(host->base + MMCISTATUS);
1570*2eb277c2SLinus Walleij 		if (status & host->variant->busy_detect_flag) {
1571b1a66593SUlf Hansson 			status |= MCI_CMDTIMEOUT;
1572*2eb277c2SLinus Walleij 			dev_err(mmc_dev(host->mmc),
1573*2eb277c2SLinus Walleij 				"timeout in state %s still busy with CMD%02x\n",
1574*2eb277c2SLinus Walleij 				ux500_state_str(host), host->cmd->opcode);
1575*2eb277c2SLinus Walleij 		} else {
1576*2eb277c2SLinus Walleij 			dev_err(mmc_dev(host->mmc),
1577*2eb277c2SLinus Walleij 				"timeout in state %s waiting for busy CMD%02x\n",
1578*2eb277c2SLinus Walleij 				ux500_state_str(host), host->cmd->opcode);
1579*2eb277c2SLinus Walleij 		}
1580b1a66593SUlf Hansson 
1581b1a66593SUlf Hansson 		mmci_cmd_irq(host, host->cmd, status);
1582b1a66593SUlf Hansson 	}
1583b1a66593SUlf Hansson 
1584b1a66593SUlf Hansson 	spin_unlock_irqrestore(&host->lock, flags);
1585b1a66593SUlf Hansson }
1586b1a66593SUlf Hansson 
mmci_get_rx_fifocnt(struct mmci_host * host,u32 status,int remain)15879c34b73dSSrinivas Kandagatla static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain)
15889c34b73dSSrinivas Kandagatla {
15899c34b73dSSrinivas Kandagatla 	return remain - (readl(host->base + MMCIFIFOCNT) << 2);
15909c34b73dSSrinivas Kandagatla }
15919c34b73dSSrinivas Kandagatla 
mmci_qcom_get_rx_fifocnt(struct mmci_host * host,u32 status,int r)15929c34b73dSSrinivas Kandagatla static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, int r)
15939c34b73dSSrinivas Kandagatla {
15949c34b73dSSrinivas Kandagatla 	/*
15959c34b73dSSrinivas Kandagatla 	 * on qcom SDCC4 only 8 words are used in each burst so only 8 addresses
15969c34b73dSSrinivas Kandagatla 	 * from the fifo range should be used
15979c34b73dSSrinivas Kandagatla 	 */
15989c34b73dSSrinivas Kandagatla 	if (status & MCI_RXFIFOHALFFULL)
15999c34b73dSSrinivas Kandagatla 		return host->variant->fifohalfsize;
16009c34b73dSSrinivas Kandagatla 	else if (status & MCI_RXDATAAVLBL)
16019c34b73dSSrinivas Kandagatla 		return 4;
16029c34b73dSSrinivas Kandagatla 
16039c34b73dSSrinivas Kandagatla 	return 0;
16049c34b73dSSrinivas Kandagatla }
16059c34b73dSSrinivas Kandagatla 
mmci_pio_read(struct mmci_host * host,char * buffer,unsigned int remain)16061c6a0718SPierre Ossman static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain)
16071c6a0718SPierre Ossman {
16081c6a0718SPierre Ossman 	void __iomem *base = host->base;
16091c6a0718SPierre Ossman 	char *ptr = buffer;
16109c34b73dSSrinivas Kandagatla 	u32 status = readl(host->base + MMCISTATUS);
161126eed9a5SLinus Walleij 	int host_remain = host->size;
16121c6a0718SPierre Ossman 
16131c6a0718SPierre Ossman 	do {
16149c34b73dSSrinivas Kandagatla 		int count = host->get_rx_fifocnt(host, status, host_remain);
16151c6a0718SPierre Ossman 
16161c6a0718SPierre Ossman 		if (count > remain)
16171c6a0718SPierre Ossman 			count = remain;
16181c6a0718SPierre Ossman 
16191c6a0718SPierre Ossman 		if (count <= 0)
16201c6a0718SPierre Ossman 			break;
16211c6a0718SPierre Ossman 
1622393e5e24SUlf Hansson 		/*
1623393e5e24SUlf Hansson 		 * SDIO especially may want to send something that is
1624393e5e24SUlf Hansson 		 * not divisible by 4 (as opposed to card sectors
1625393e5e24SUlf Hansson 		 * etc). Therefore make sure to always read the last bytes
1626393e5e24SUlf Hansson 		 * while only doing full 32-bit reads towards the FIFO.
1627393e5e24SUlf Hansson 		 */
1628393e5e24SUlf Hansson 		if (unlikely(count & 0x3)) {
1629393e5e24SUlf Hansson 			if (count < 4) {
1630393e5e24SUlf Hansson 				unsigned char buf[4];
16314b85da08SDavide Ciminaghi 				ioread32_rep(base + MMCIFIFO, buf, 1);
1632393e5e24SUlf Hansson 				memcpy(ptr, buf, count);
1633393e5e24SUlf Hansson 			} else {
16344b85da08SDavide Ciminaghi 				ioread32_rep(base + MMCIFIFO, ptr, count >> 2);
1635393e5e24SUlf Hansson 				count &= ~0x3;
1636393e5e24SUlf Hansson 			}
1637393e5e24SUlf Hansson 		} else {
16384b85da08SDavide Ciminaghi 			ioread32_rep(base + MMCIFIFO, ptr, count >> 2);
1639393e5e24SUlf Hansson 		}
16401c6a0718SPierre Ossman 
16411c6a0718SPierre Ossman 		ptr += count;
16421c6a0718SPierre Ossman 		remain -= count;
164326eed9a5SLinus Walleij 		host_remain -= count;
16441c6a0718SPierre Ossman 
16451c6a0718SPierre Ossman 		if (remain == 0)
16461c6a0718SPierre Ossman 			break;
16471c6a0718SPierre Ossman 
16481c6a0718SPierre Ossman 		status = readl(base + MMCISTATUS);
16491c6a0718SPierre Ossman 	} while (status & MCI_RXDATAAVLBL);
16501c6a0718SPierre Ossman 
16511c6a0718SPierre Ossman 	return ptr - buffer;
16521c6a0718SPierre Ossman }
16531c6a0718SPierre Ossman 
mmci_pio_write(struct mmci_host * host,char * buffer,unsigned int remain,u32 status)16541c6a0718SPierre Ossman static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status)
16551c6a0718SPierre Ossman {
16568301bb68SRabin Vincent 	struct variant_data *variant = host->variant;
16571c6a0718SPierre Ossman 	void __iomem *base = host->base;
16581c6a0718SPierre Ossman 	char *ptr = buffer;
16591c6a0718SPierre Ossman 
16601c6a0718SPierre Ossman 	do {
16611c6a0718SPierre Ossman 		unsigned int count, maxcnt;
16621c6a0718SPierre Ossman 
16638301bb68SRabin Vincent 		maxcnt = status & MCI_TXFIFOEMPTY ?
16648301bb68SRabin Vincent 			 variant->fifosize : variant->fifohalfsize;
16651c6a0718SPierre Ossman 		count = min(remain, maxcnt);
16661c6a0718SPierre Ossman 
166734177802SLinus Walleij 		/*
166834177802SLinus Walleij 		 * SDIO especially may want to send something that is
166934177802SLinus Walleij 		 * not divisible by 4 (as opposed to card sectors
167034177802SLinus Walleij 		 * etc), and the FIFO only accept full 32-bit writes.
167134177802SLinus Walleij 		 * So compensate by adding +3 on the count, a single
167234177802SLinus Walleij 		 * byte become a 32bit write, 7 bytes will be two
167334177802SLinus Walleij 		 * 32bit writes etc.
167434177802SLinus Walleij 		 */
16754b85da08SDavide Ciminaghi 		iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2);
16761c6a0718SPierre Ossman 
16771c6a0718SPierre Ossman 		ptr += count;
16781c6a0718SPierre Ossman 		remain -= count;
16791c6a0718SPierre Ossman 
16801c6a0718SPierre Ossman 		if (remain == 0)
16811c6a0718SPierre Ossman 			break;
16821c6a0718SPierre Ossman 
16831c6a0718SPierre Ossman 		status = readl(base + MMCISTATUS);
16841c6a0718SPierre Ossman 	} while (status & MCI_TXFIFOHALFEMPTY);
16851c6a0718SPierre Ossman 
16861c6a0718SPierre Ossman 	return ptr - buffer;
16871c6a0718SPierre Ossman }
16881c6a0718SPierre Ossman 
16891c6a0718SPierre Ossman /*
16901c6a0718SPierre Ossman  * PIO data transfer IRQ handler.
16911c6a0718SPierre Ossman  */
mmci_pio_irq(int irq,void * dev_id)16921c6a0718SPierre Ossman static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
16931c6a0718SPierre Ossman {
16941c6a0718SPierre Ossman 	struct mmci_host *host = dev_id;
16954ce1d6cbSRabin Vincent 	struct sg_mapping_iter *sg_miter = &host->sg_miter;
16968301bb68SRabin Vincent 	struct variant_data *variant = host->variant;
16971c6a0718SPierre Ossman 	void __iomem *base = host->base;
16981c6a0718SPierre Ossman 	u32 status;
16991c6a0718SPierre Ossman 
17001c6a0718SPierre Ossman 	status = readl(base + MMCISTATUS);
17011c6a0718SPierre Ossman 
170264de0289SLinus Walleij 	dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status);
17031c6a0718SPierre Ossman 
17041c6a0718SPierre Ossman 	do {
17051c6a0718SPierre Ossman 		unsigned int remain, len;
17061c6a0718SPierre Ossman 		char *buffer;
17071c6a0718SPierre Ossman 
17081c6a0718SPierre Ossman 		/*
17091c6a0718SPierre Ossman 		 * For write, we only need to test the half-empty flag
17101c6a0718SPierre Ossman 		 * here - if the FIFO is completely empty, then by
17111c6a0718SPierre Ossman 		 * definition it is more than half empty.
17121c6a0718SPierre Ossman 		 *
17131c6a0718SPierre Ossman 		 * For read, check for data available.
17141c6a0718SPierre Ossman 		 */
17151c6a0718SPierre Ossman 		if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL)))
17161c6a0718SPierre Ossman 			break;
17171c6a0718SPierre Ossman 
17184ce1d6cbSRabin Vincent 		if (!sg_miter_next(sg_miter))
17194ce1d6cbSRabin Vincent 			break;
17204ce1d6cbSRabin Vincent 
17214ce1d6cbSRabin Vincent 		buffer = sg_miter->addr;
17224ce1d6cbSRabin Vincent 		remain = sg_miter->length;
17231c6a0718SPierre Ossman 
17241c6a0718SPierre Ossman 		len = 0;
17251c6a0718SPierre Ossman 		if (status & MCI_RXACTIVE)
17261c6a0718SPierre Ossman 			len = mmci_pio_read(host, buffer, remain);
17271c6a0718SPierre Ossman 		if (status & MCI_TXACTIVE)
17281c6a0718SPierre Ossman 			len = mmci_pio_write(host, buffer, remain, status);
17291c6a0718SPierre Ossman 
17304ce1d6cbSRabin Vincent 		sg_miter->consumed = len;
17311c6a0718SPierre Ossman 
17321c6a0718SPierre Ossman 		host->size -= len;
17331c6a0718SPierre Ossman 		remain -= len;
17341c6a0718SPierre Ossman 
17351c6a0718SPierre Ossman 		if (remain)
17361c6a0718SPierre Ossman 			break;
17371c6a0718SPierre Ossman 
17381c6a0718SPierre Ossman 		status = readl(base + MMCISTATUS);
17391c6a0718SPierre Ossman 	} while (1);
17401c6a0718SPierre Ossman 
17414ce1d6cbSRabin Vincent 	sg_miter_stop(sg_miter);
17424ce1d6cbSRabin Vincent 
17431c6a0718SPierre Ossman 	/*
1744c4d877c1SRussell King 	 * If we have less than the fifo 'half-full' threshold to transfer,
1745c4d877c1SRussell King 	 * trigger a PIO interrupt as soon as any data is available.
17461c6a0718SPierre Ossman 	 */
1747c4d877c1SRussell King 	if (status & MCI_RXACTIVE && host->size < variant->fifohalfsize)
17482686b4b4SLinus Walleij 		mmci_set_mask1(host, MCI_RXDATAAVLBLMASK);
17491c6a0718SPierre Ossman 
17501c6a0718SPierre Ossman 	/*
17511c6a0718SPierre Ossman 	 * If we run out of data, disable the data IRQs; this
17521c6a0718SPierre Ossman 	 * prevents a race where the FIFO becomes empty before
17531c6a0718SPierre Ossman 	 * the chip itself has disabled the data path, and
17541c6a0718SPierre Ossman 	 * stops us racing with our data end IRQ.
17551c6a0718SPierre Ossman 	 */
17561c6a0718SPierre Ossman 	if (host->size == 0) {
17572686b4b4SLinus Walleij 		mmci_set_mask1(host, 0);
17581c6a0718SPierre Ossman 		writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0);
17591c6a0718SPierre Ossman 	}
17601c6a0718SPierre Ossman 
17611c6a0718SPierre Ossman 	return IRQ_HANDLED;
17621c6a0718SPierre Ossman }
17631c6a0718SPierre Ossman 
17641c6a0718SPierre Ossman /*
17651c6a0718SPierre Ossman  * Handle completion of command and data transfers.
17661c6a0718SPierre Ossman  */
mmci_irq(int irq,void * dev_id)17671c6a0718SPierre Ossman static irqreturn_t mmci_irq(int irq, void *dev_id)
17681c6a0718SPierre Ossman {
17691c6a0718SPierre Ossman 	struct mmci_host *host = dev_id;
17701c6a0718SPierre Ossman 	u32 status;
17711c6a0718SPierre Ossman 
17721c6a0718SPierre Ossman 	spin_lock(&host->lock);
1773ee157abeSLudovic Barre 	host->irq_action = IRQ_HANDLED;
17741c6a0718SPierre Ossman 
17751c6a0718SPierre Ossman 	do {
17761c6a0718SPierre Ossman 		status = readl(host->base + MMCISTATUS);
1777f7ad7504SLinus Walleij 		if (!status)
1778f7ad7504SLinus Walleij 			break;
17792686b4b4SLinus Walleij 
17802686b4b4SLinus Walleij 		if (host->singleirq) {
17816ea9cdf3SPatrice Chotard 			if (status & host->mask1_reg)
17822686b4b4SLinus Walleij 				mmci_pio_irq(irq, dev_id);
17832686b4b4SLinus Walleij 
178459db5e2dSLudovic Barre 			status &= ~host->variant->irq_pio_mask;
17852686b4b4SLinus Walleij 		}
17862686b4b4SLinus Walleij 
17878d94b54dSUlf Hansson 		/*
1788a9cbd79cSUlf Hansson 		 * Busy detection is managed by mmci_cmd_irq(), including to
1789a9cbd79cSUlf Hansson 		 * clear the corresponding IRQ.
17908d94b54dSUlf Hansson 		 */
17911c6a0718SPierre Ossman 		status &= readl(host->base + MMCIMASK0);
17925cad24d8SJean-Nicolas Graux 		if (host->variant->busy_detect)
17935cad24d8SJean-Nicolas Graux 			writel(status & ~host->variant->busy_detect_mask,
17945cad24d8SJean-Nicolas Graux 			       host->base + MMCICLEAR);
17955cad24d8SJean-Nicolas Graux 		else
17961c6a0718SPierre Ossman 			writel(status, host->base + MMCICLEAR);
17971c6a0718SPierre Ossman 
179864de0289SLinus Walleij 		dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
17991c6a0718SPierre Ossman 
18007878289bSUlf Hansson 		if (host->variant->reversed_irq_handling) {
18017878289bSUlf Hansson 			mmci_data_irq(host, host->data, status);
18027878289bSUlf Hansson 			mmci_cmd_irq(host, host->cmd, status);
18037878289bSUlf Hansson 		} else {
1804ad82bfeaSUlf Hansson 			mmci_cmd_irq(host, host->cmd, status);
18051cb9da50SUlf Hansson 			mmci_data_irq(host, host->data, status);
18067878289bSUlf Hansson 		}
18071c6a0718SPierre Ossman 
180849adc0caSLinus Walleij 		/*
18098520ce1eSLudovic Barre 		 * Busy detection has been handled by mmci_cmd_irq() above.
18108520ce1eSLudovic Barre 		 * Clear the status bit to prevent polling in IRQ context.
181149adc0caSLinus Walleij 		 */
18128520ce1eSLudovic Barre 		if (host->variant->busy_detect_flag)
181349adc0caSLinus Walleij 			status &= ~host->variant->busy_detect_flag;
18148d94b54dSUlf Hansson 
18151c6a0718SPierre Ossman 	} while (status);
18161c6a0718SPierre Ossman 
18171c6a0718SPierre Ossman 	spin_unlock(&host->lock);
18181c6a0718SPierre Ossman 
1819ee157abeSLudovic Barre 	return host->irq_action;
1820ee157abeSLudovic Barre }
1821ee157abeSLudovic Barre 
1822ee157abeSLudovic Barre /*
1823ee157abeSLudovic Barre  * mmci_irq_thread() - A threaded IRQ handler that manages a reset of the HW.
1824ee157abeSLudovic Barre  *
1825ee157abeSLudovic Barre  * A reset is needed for some variants, where a datatimeout for a R1B request
1826ee157abeSLudovic Barre  * causes the DPSM to stay busy (non-functional).
1827ee157abeSLudovic Barre  */
mmci_irq_thread(int irq,void * dev_id)1828ee157abeSLudovic Barre static irqreturn_t mmci_irq_thread(int irq, void *dev_id)
1829ee157abeSLudovic Barre {
1830ee157abeSLudovic Barre 	struct mmci_host *host = dev_id;
1831ee157abeSLudovic Barre 	unsigned long flags;
1832ee157abeSLudovic Barre 
1833ee157abeSLudovic Barre 	if (host->rst) {
1834ee157abeSLudovic Barre 		reset_control_assert(host->rst);
1835ee157abeSLudovic Barre 		udelay(2);
1836ee157abeSLudovic Barre 		reset_control_deassert(host->rst);
1837ee157abeSLudovic Barre 	}
1838ee157abeSLudovic Barre 
1839ee157abeSLudovic Barre 	spin_lock_irqsave(&host->lock, flags);
1840ee157abeSLudovic Barre 	writel(host->clk_reg, host->base + MMCICLOCK);
1841ee157abeSLudovic Barre 	writel(host->pwr_reg, host->base + MMCIPOWER);
1842ee157abeSLudovic Barre 	writel(MCI_IRQENABLE | host->variant->start_err,
1843ee157abeSLudovic Barre 	       host->base + MMCIMASK0);
1844ee157abeSLudovic Barre 
1845ee157abeSLudovic Barre 	host->irq_action = IRQ_HANDLED;
1846ee157abeSLudovic Barre 	mmci_request_end(host, host->mrq);
1847ee157abeSLudovic Barre 	spin_unlock_irqrestore(&host->lock, flags);
1848ee157abeSLudovic Barre 
1849ee157abeSLudovic Barre 	return host->irq_action;
18501c6a0718SPierre Ossman }
18511c6a0718SPierre Ossman 
mmci_request(struct mmc_host * mmc,struct mmc_request * mrq)18521c6a0718SPierre Ossman static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
18531c6a0718SPierre Ossman {
18541c6a0718SPierre Ossman 	struct mmci_host *host = mmc_priv(mmc);
18559e943021SLinus Walleij 	unsigned long flags;
18561c6a0718SPierre Ossman 
18571c6a0718SPierre Ossman 	WARN_ON(host->mrq != NULL);
18581c6a0718SPierre Ossman 
1859653a761eSUlf Hansson 	mrq->cmd->error = mmci_validate_data(host, mrq->data);
1860653a761eSUlf Hansson 	if (mrq->cmd->error) {
1861255d01afSPierre Ossman 		mmc_request_done(mmc, mrq);
1862255d01afSPierre Ossman 		return;
1863255d01afSPierre Ossman 	}
1864255d01afSPierre Ossman 
18659e943021SLinus Walleij 	spin_lock_irqsave(&host->lock, flags);
18661c6a0718SPierre Ossman 
18671c6a0718SPierre Ossman 	host->mrq = mrq;
18681c6a0718SPierre Ossman 
186958c7ccbfSPer Forlin 	if (mrq->data)
187058c7ccbfSPer Forlin 		mmci_get_next_data(host, mrq->data);
187158c7ccbfSPer Forlin 
1872d2141547SLudovic Barre 	if (mrq->data &&
1873d2141547SLudovic Barre 	    (host->variant->datactrl_first || mrq->data->flags & MMC_DATA_READ))
18741c6a0718SPierre Ossman 		mmci_start_data(host, mrq->data);
18751c6a0718SPierre Ossman 
1876024629c6SUlf Hansson 	if (mrq->sbc)
1877024629c6SUlf Hansson 		mmci_start_command(host, mrq->sbc, 0);
1878024629c6SUlf Hansson 	else
18791c6a0718SPierre Ossman 		mmci_start_command(host, mrq->cmd, 0);
18801c6a0718SPierre Ossman 
18819e943021SLinus Walleij 	spin_unlock_irqrestore(&host->lock, flags);
18821c6a0718SPierre Ossman }
18831c6a0718SPierre Ossman 
mmci_set_max_busy_timeout(struct mmc_host * mmc)18848266c585SLudovic Barre static void mmci_set_max_busy_timeout(struct mmc_host *mmc)
18858266c585SLudovic Barre {
18868266c585SLudovic Barre 	struct mmci_host *host = mmc_priv(mmc);
18878266c585SLudovic Barre 	u32 max_busy_timeout = 0;
18888266c585SLudovic Barre 
18898266c585SLudovic Barre 	if (!host->variant->busy_detect)
18908266c585SLudovic Barre 		return;
18918266c585SLudovic Barre 
18928266c585SLudovic Barre 	if (host->variant->busy_timeout && mmc->actual_clock)
189347b3ad6bSChristophe Kerello 		max_busy_timeout = U32_MAX / DIV_ROUND_UP(mmc->actual_clock,
189447b3ad6bSChristophe Kerello 							  MSEC_PER_SEC);
18958266c585SLudovic Barre 
18968266c585SLudovic Barre 	mmc->max_busy_timeout = max_busy_timeout;
18978266c585SLudovic Barre }
18988266c585SLudovic Barre 
mmci_set_ios(struct mmc_host * mmc,struct mmc_ios * ios)18991c6a0718SPierre Ossman static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
19001c6a0718SPierre Ossman {
19011c6a0718SPierre Ossman 	struct mmci_host *host = mmc_priv(mmc);
19027d72a1d4SUlf Hansson 	struct variant_data *variant = host->variant;
1903a6a6464aSLinus Walleij 	u32 pwr = 0;
1904a6a6464aSLinus Walleij 	unsigned long flags;
1905db90f91fSLee Jones 	int ret;
19061c6a0718SPierre Ossman 
19071c6a0718SPierre Ossman 	switch (ios->power_mode) {
19081c6a0718SPierre Ossman 	case MMC_POWER_OFF:
1909599c1d5cSUlf Hansson 		if (!IS_ERR(mmc->supply.vmmc))
1910599c1d5cSUlf Hansson 			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
1911237fb5e6SLee Jones 
19127c0136efSUlf Hansson 		if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) {
1913237fb5e6SLee Jones 			regulator_disable(mmc->supply.vqmmc);
19147c0136efSUlf Hansson 			host->vqmmc_enabled = false;
19157c0136efSUlf Hansson 		}
1916237fb5e6SLee Jones 
19171c6a0718SPierre Ossman 		break;
19181c6a0718SPierre Ossman 	case MMC_POWER_UP:
1919599c1d5cSUlf Hansson 		if (!IS_ERR(mmc->supply.vmmc))
1920599c1d5cSUlf Hansson 			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
1921599c1d5cSUlf Hansson 
19227d72a1d4SUlf Hansson 		/*
19237d72a1d4SUlf Hansson 		 * The ST Micro variant doesn't have the PL180s MCI_PWR_UP
19247d72a1d4SUlf Hansson 		 * and instead uses MCI_PWR_ON so apply whatever value is
19257d72a1d4SUlf Hansson 		 * configured in the variant data.
19267d72a1d4SUlf Hansson 		 */
19277d72a1d4SUlf Hansson 		pwr |= variant->pwrreg_powerup;
19287d72a1d4SUlf Hansson 
19291c6a0718SPierre Ossman 		break;
19301c6a0718SPierre Ossman 	case MMC_POWER_ON:
19317c0136efSUlf Hansson 		if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) {
1932db90f91fSLee Jones 			ret = regulator_enable(mmc->supply.vqmmc);
1933db90f91fSLee Jones 			if (ret < 0)
1934db90f91fSLee Jones 				dev_err(mmc_dev(mmc),
1935db90f91fSLee Jones 					"failed to enable vqmmc regulator\n");
19367c0136efSUlf Hansson 			else
19377c0136efSUlf Hansson 				host->vqmmc_enabled = true;
1938db90f91fSLee Jones 		}
1939237fb5e6SLee Jones 
19401c6a0718SPierre Ossman 		pwr |= MCI_PWR_ON;
19411c6a0718SPierre Ossman 		break;
19421c6a0718SPierre Ossman 	}
19431c6a0718SPierre Ossman 
19444d1a3a0dSUlf Hansson 	if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) {
19454d1a3a0dSUlf Hansson 		/*
19464d1a3a0dSUlf Hansson 		 * The ST Micro variant has some additional bits
19474d1a3a0dSUlf Hansson 		 * indicating signal direction for the signals in
19484d1a3a0dSUlf Hansson 		 * the SD/MMC bus and feedback-clock usage.
19494d1a3a0dSUlf Hansson 		 */
19504593df29SUlf Hansson 		pwr |= host->pwr_reg_add;
19514d1a3a0dSUlf Hansson 
19524d1a3a0dSUlf Hansson 		if (ios->bus_width == MMC_BUS_WIDTH_4)
19534d1a3a0dSUlf Hansson 			pwr &= ~MCI_ST_DATA74DIREN;
19544d1a3a0dSUlf Hansson 		else if (ios->bus_width == MMC_BUS_WIDTH_1)
19554d1a3a0dSUlf Hansson 			pwr &= (~MCI_ST_DATA74DIREN &
19564d1a3a0dSUlf Hansson 				~MCI_ST_DATA31DIREN &
19574d1a3a0dSUlf Hansson 				~MCI_ST_DATA2DIREN);
19584d1a3a0dSUlf Hansson 	}
19594d1a3a0dSUlf Hansson 
1960f9bb304cSPatrice Chotard 	if (variant->opendrain) {
1961f9bb304cSPatrice Chotard 		if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
196211dfb970SPatrice Chotard 			pwr |= variant->opendrain;
1963f9bb304cSPatrice Chotard 	} else {
1964f9bb304cSPatrice Chotard 		/*
1965f9bb304cSPatrice Chotard 		 * If the variant cannot configure the pads by its own, then we
1966f9bb304cSPatrice Chotard 		 * expect the pinctrl to be able to do that for us
1967f9bb304cSPatrice Chotard 		 */
1968f9bb304cSPatrice Chotard 		if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
1969f9bb304cSPatrice Chotard 			pinctrl_select_state(host->pinctrl, host->pins_opendrain);
1970f9bb304cSPatrice Chotard 		else
197105344ffeSUlf Hansson 			pinctrl_select_default_state(mmc_dev(mmc));
1972f9bb304cSPatrice Chotard 	}
19731c6a0718SPierre Ossman 
1974f4670daeSUlf Hansson 	/*
1975f4670daeSUlf Hansson 	 * If clock = 0 and the variant requires the MMCIPOWER to be used for
1976f4670daeSUlf Hansson 	 * gating the clock, the MCI_PWR_ON bit is cleared.
1977f4670daeSUlf Hansson 	 */
1978f4670daeSUlf Hansson 	if (!ios->clock && variant->pwrreg_clkgate)
1979f4670daeSUlf Hansson 		pwr &= ~MCI_PWR_ON;
1980f4670daeSUlf Hansson 
19813f4e6f7bSSrinivas Kandagatla 	if (host->variant->explicit_mclk_control &&
19823f4e6f7bSSrinivas Kandagatla 	    ios->clock != host->clock_cache) {
19833f4e6f7bSSrinivas Kandagatla 		ret = clk_set_rate(host->clk, ios->clock);
19843f4e6f7bSSrinivas Kandagatla 		if (ret < 0)
19853f4e6f7bSSrinivas Kandagatla 			dev_err(mmc_dev(host->mmc),
19863f4e6f7bSSrinivas Kandagatla 				"Error setting clock rate (%d)\n", ret);
19873f4e6f7bSSrinivas Kandagatla 		else
19883f4e6f7bSSrinivas Kandagatla 			host->mclk = clk_get_rate(host->clk);
19893f4e6f7bSSrinivas Kandagatla 	}
19903f4e6f7bSSrinivas Kandagatla 	host->clock_cache = ios->clock;
19913f4e6f7bSSrinivas Kandagatla 
1992a6a6464aSLinus Walleij 	spin_lock_irqsave(&host->lock, flags);
1993a6a6464aSLinus Walleij 
1994cd3ee8c5SLudovic Barre 	if (host->ops && host->ops->set_clkreg)
1995cd3ee8c5SLudovic Barre 		host->ops->set_clkreg(host, ios->clock);
1996cd3ee8c5SLudovic Barre 	else
1997a6a6464aSLinus Walleij 		mmci_set_clkreg(host, ios->clock);
1998cd3ee8c5SLudovic Barre 
19998266c585SLudovic Barre 	mmci_set_max_busy_timeout(mmc);
20008266c585SLudovic Barre 
2001cd3ee8c5SLudovic Barre 	if (host->ops && host->ops->set_pwrreg)
2002cd3ee8c5SLudovic Barre 		host->ops->set_pwrreg(host, pwr);
2003cd3ee8c5SLudovic Barre 	else
20047437cfa5SUlf Hansson 		mmci_write_pwrreg(host, pwr);
2005cd3ee8c5SLudovic Barre 
2006f829c042SUlf Hansson 	mmci_reg_delay(host);
2007a6a6464aSLinus Walleij 
2008a6a6464aSLinus Walleij 	spin_unlock_irqrestore(&host->lock, flags);
20091c6a0718SPierre Ossman }
20101c6a0718SPierre Ossman 
mmci_get_cd(struct mmc_host * mmc)201189001446SRussell King static int mmci_get_cd(struct mmc_host *mmc)
201289001446SRussell King {
201389001446SRussell King 	struct mmci_host *host = mmc_priv(mmc);
201429719445SRabin Vincent 	struct mmci_platform_data *plat = host->plat;
2015d2762090SUlf Hansson 	unsigned int status = mmc_gpio_get_cd(mmc);
201689001446SRussell King 
2017d2762090SUlf Hansson 	if (status == -ENOSYS) {
20184b8caec0SRabin Vincent 		if (!plat->status)
20194b8caec0SRabin Vincent 			return 1; /* Assume always present */
20204b8caec0SRabin Vincent 
202129719445SRabin Vincent 		status = plat->status(mmc_dev(host->mmc));
2022d2762090SUlf Hansson 	}
202374bc8093SRussell King 	return status;
202489001446SRussell King }
202589001446SRussell King 
mmci_sig_volt_switch(struct mmc_host * mmc,struct mmc_ios * ios)20260f3ed7f7SUlf Hansson static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios)
20270f3ed7f7SUlf Hansson {
202875773165SLudovic Barre 	struct mmci_host *host = mmc_priv(mmc);
20293e09a81eSMarek Vasut 	int ret;
20300f3ed7f7SUlf Hansson 
20313e09a81eSMarek Vasut 	ret = mmc_regulator_set_vqmmc(mmc, ios);
20320f3ed7f7SUlf Hansson 
203375773165SLudovic Barre 	if (!ret && host->ops && host->ops->post_sig_volt_switch)
203475773165SLudovic Barre 		ret = host->ops->post_sig_volt_switch(host, ios);
20353e09a81eSMarek Vasut 	else if (ret)
20363e09a81eSMarek Vasut 		ret = 0;
203775773165SLudovic Barre 
20383e09a81eSMarek Vasut 	if (ret < 0)
20390f3ed7f7SUlf Hansson 		dev_warn(mmc_dev(mmc), "Voltage switch failed\n");
20400f3ed7f7SUlf Hansson 
20410f3ed7f7SUlf Hansson 	return ret;
20420f3ed7f7SUlf Hansson }
20430f3ed7f7SUlf Hansson 
204401259620SUlf Hansson static struct mmc_host_ops mmci_ops = {
20451c6a0718SPierre Ossman 	.request	= mmci_request,
204658c7ccbfSPer Forlin 	.pre_req	= mmci_pre_request,
204758c7ccbfSPer Forlin 	.post_req	= mmci_post_request,
20481c6a0718SPierre Ossman 	.set_ios	= mmci_set_ios,
2049d2762090SUlf Hansson 	.get_ro		= mmc_gpio_get_ro,
205089001446SRussell King 	.get_cd		= mmci_get_cd,
20510f3ed7f7SUlf Hansson 	.start_signal_voltage_switch = mmci_sig_volt_switch,
20521c6a0718SPierre Ossman };
20531c6a0718SPierre Ossman 
mmci_probe_level_translator(struct mmc_host * mmc)20546351cac9SMarek Vasut static void mmci_probe_level_translator(struct mmc_host *mmc)
20556351cac9SMarek Vasut {
20566351cac9SMarek Vasut 	struct device *dev = mmc_dev(mmc);
20576351cac9SMarek Vasut 	struct mmci_host *host = mmc_priv(mmc);
20586351cac9SMarek Vasut 	struct gpio_desc *cmd_gpio;
20596351cac9SMarek Vasut 	struct gpio_desc *ck_gpio;
20606351cac9SMarek Vasut 	struct gpio_desc *ckin_gpio;
20616351cac9SMarek Vasut 	int clk_hi, clk_lo;
20626351cac9SMarek Vasut 
20636351cac9SMarek Vasut 	/*
20646351cac9SMarek Vasut 	 * Assume the level translator is present if st,use-ckin is set.
20656351cac9SMarek Vasut 	 * This is to cater for DTs which do not implement this test.
20666351cac9SMarek Vasut 	 */
20676351cac9SMarek Vasut 	host->clk_reg_add |= MCI_STM32_CLK_SELCKIN;
20686351cac9SMarek Vasut 
20696351cac9SMarek Vasut 	cmd_gpio = gpiod_get(dev, "st,cmd", GPIOD_OUT_HIGH);
20706351cac9SMarek Vasut 	if (IS_ERR(cmd_gpio))
20716351cac9SMarek Vasut 		goto exit_cmd;
20726351cac9SMarek Vasut 
20736351cac9SMarek Vasut 	ck_gpio = gpiod_get(dev, "st,ck", GPIOD_OUT_HIGH);
20746351cac9SMarek Vasut 	if (IS_ERR(ck_gpio))
20756351cac9SMarek Vasut 		goto exit_ck;
20766351cac9SMarek Vasut 
20776351cac9SMarek Vasut 	ckin_gpio = gpiod_get(dev, "st,ckin", GPIOD_IN);
20786351cac9SMarek Vasut 	if (IS_ERR(ckin_gpio))
20796351cac9SMarek Vasut 		goto exit_ckin;
20806351cac9SMarek Vasut 
20816351cac9SMarek Vasut 	/* All GPIOs are valid, test whether level translator works */
20826351cac9SMarek Vasut 
20836351cac9SMarek Vasut 	/* Sample CKIN */
20846351cac9SMarek Vasut 	clk_hi = !!gpiod_get_value(ckin_gpio);
20856351cac9SMarek Vasut 
20866351cac9SMarek Vasut 	/* Set CK low */
20876351cac9SMarek Vasut 	gpiod_set_value(ck_gpio, 0);
20886351cac9SMarek Vasut 
20896351cac9SMarek Vasut 	/* Sample CKIN */
20906351cac9SMarek Vasut 	clk_lo = !!gpiod_get_value(ckin_gpio);
20916351cac9SMarek Vasut 
20926351cac9SMarek Vasut 	/* Tristate all */
20936351cac9SMarek Vasut 	gpiod_direction_input(cmd_gpio);
20946351cac9SMarek Vasut 	gpiod_direction_input(ck_gpio);
20956351cac9SMarek Vasut 
20966351cac9SMarek Vasut 	/* Level translator is present if CK signal is propagated to CKIN */
20976351cac9SMarek Vasut 	if (!clk_hi || clk_lo) {
20986351cac9SMarek Vasut 		host->clk_reg_add &= ~MCI_STM32_CLK_SELCKIN;
20996351cac9SMarek Vasut 		dev_warn(dev,
21006351cac9SMarek Vasut 			 "Level translator inoperable, CK signal not detected on CKIN, disabling.\n");
21016351cac9SMarek Vasut 	}
21026351cac9SMarek Vasut 
21036351cac9SMarek Vasut 	gpiod_put(ckin_gpio);
21046351cac9SMarek Vasut 
21056351cac9SMarek Vasut exit_ckin:
21066351cac9SMarek Vasut 	gpiod_put(ck_gpio);
21076351cac9SMarek Vasut exit_ck:
21086351cac9SMarek Vasut 	gpiod_put(cmd_gpio);
21096351cac9SMarek Vasut exit_cmd:
21106351cac9SMarek Vasut 	pinctrl_select_default_state(dev);
21116351cac9SMarek Vasut }
21126351cac9SMarek Vasut 
mmci_of_parse(struct device_node * np,struct mmc_host * mmc)211378f87df2SUlf Hansson static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc)
211478f87df2SUlf Hansson {
21154593df29SUlf Hansson 	struct mmci_host *host = mmc_priv(mmc);
211678f87df2SUlf Hansson 	int ret = mmc_of_parse(mmc);
2117000bc9d5SLee Jones 
211878f87df2SUlf Hansson 	if (ret)
211978f87df2SUlf Hansson 		return ret;
2120000bc9d5SLee Jones 
2121ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir-dat0"))
21224593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_DATA0DIREN;
2123ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir-dat2"))
21244593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_DATA2DIREN;
2125ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir-dat31"))
21264593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_DATA31DIREN;
2127ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir-dat74"))
21284593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_DATA74DIREN;
2129ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir-cmd"))
21304593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_CMDDIREN;
2131ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-pin-fbclk"))
21324593df29SUlf Hansson 		host->pwr_reg_add |= MCI_ST_FBCLKEN;
2133ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,sig-dir"))
213446b723ddSLudovic Barre 		host->pwr_reg_add |= MCI_STM32_DIRPOL;
2135ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,neg-edge"))
213646b723ddSLudovic Barre 		host->clk_reg_add |= MCI_STM32_CLK_NEGEDGE;
2137ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "st,use-ckin"))
21386351cac9SMarek Vasut 		mmci_probe_level_translator(mmc);
21394593df29SUlf Hansson 
2140ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "mmc-cap-mmc-highspeed"))
214178f87df2SUlf Hansson 		mmc->caps |= MMC_CAP_MMC_HIGHSPEED;
2142ca6b5fe2SRob Herring 	if (of_property_read_bool(np, "mmc-cap-sd-highspeed"))
214378f87df2SUlf Hansson 		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
2144000bc9d5SLee Jones 
214578f87df2SUlf Hansson 	return 0;
2146000bc9d5SLee Jones }
2147000bc9d5SLee Jones 
mmci_probe(struct amba_device * dev,const struct amba_id * id)2148c3be1efdSBill Pemberton static int mmci_probe(struct amba_device *dev,
2149aa25afadSRussell King 	const struct amba_id *id)
21501c6a0718SPierre Ossman {
21516ef297f8SLinus Walleij 	struct mmci_platform_data *plat = dev->dev.platform_data;
2152000bc9d5SLee Jones 	struct device_node *np = dev->dev.of_node;
21534956e109SRabin Vincent 	struct variant_data *variant = id->data;
21541c6a0718SPierre Ossman 	struct mmci_host *host;
21551c6a0718SPierre Ossman 	struct mmc_host *mmc;
21561c6a0718SPierre Ossman 	int ret;
21571c6a0718SPierre Ossman 
2158000bc9d5SLee Jones 	/* Must have platform data or Device Tree. */
2159000bc9d5SLee Jones 	if (!plat && !np) {
2160000bc9d5SLee Jones 		dev_err(&dev->dev, "No plat data or DT found\n");
2161000bc9d5SLee Jones 		return -EINVAL;
21621c6a0718SPierre Ossman 	}
21631c6a0718SPierre Ossman 
2164b9b52918SLee Jones 	if (!plat) {
2165b9b52918SLee Jones 		plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL);
2166b9b52918SLee Jones 		if (!plat)
2167b9b52918SLee Jones 			return -ENOMEM;
2168b9b52918SLee Jones 	}
2169b9b52918SLee Jones 
21701c6a0718SPierre Ossman 	mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);
2171ef289982SUlf Hansson 	if (!mmc)
2172ef289982SUlf Hansson 		return -ENOMEM;
21731c6a0718SPierre Ossman 
21741c6a0718SPierre Ossman 	host = mmc_priv(mmc);
21754ea580f1SRabin Vincent 	host->mmc = mmc;
21767b9716a0SLudovic Barre 	host->mmc_ops = &mmci_ops;
21777b9716a0SLudovic Barre 	mmc->ops = &mmci_ops;
2178012b7d33SRussell King 
21796351cac9SMarek Vasut 	ret = mmci_of_parse(np, mmc);
21806351cac9SMarek Vasut 	if (ret)
21816351cac9SMarek Vasut 		goto host_free;
21826351cac9SMarek Vasut 
2183f9bb304cSPatrice Chotard 	/*
2184f9bb304cSPatrice Chotard 	 * Some variant (STM32) doesn't have opendrain bit, nevertheless
2185f9bb304cSPatrice Chotard 	 * pins can be set accordingly using pinctrl
2186f9bb304cSPatrice Chotard 	 */
2187f9bb304cSPatrice Chotard 	if (!variant->opendrain) {
2188f9bb304cSPatrice Chotard 		host->pinctrl = devm_pinctrl_get(&dev->dev);
2189f9bb304cSPatrice Chotard 		if (IS_ERR(host->pinctrl)) {
2190f9bb304cSPatrice Chotard 			dev_err(&dev->dev, "failed to get pinctrl");
2191310eb252SWei Yongjun 			ret = PTR_ERR(host->pinctrl);
2192f9bb304cSPatrice Chotard 			goto host_free;
2193f9bb304cSPatrice Chotard 		}
2194f9bb304cSPatrice Chotard 
2195f9bb304cSPatrice Chotard 		host->pins_opendrain = pinctrl_lookup_state(host->pinctrl,
2196f9bb304cSPatrice Chotard 							    MMCI_PINCTRL_STATE_OPENDRAIN);
2197f9bb304cSPatrice Chotard 		if (IS_ERR(host->pins_opendrain)) {
2198f9bb304cSPatrice Chotard 			dev_err(mmc_dev(mmc), "Can't select opendrain pins\n");
2199310eb252SWei Yongjun 			ret = PTR_ERR(host->pins_opendrain);
2200f9bb304cSPatrice Chotard 			goto host_free;
2201f9bb304cSPatrice Chotard 		}
2202f9bb304cSPatrice Chotard 	}
2203f9bb304cSPatrice Chotard 
2204012b7d33SRussell King 	host->hw_designer = amba_manf(dev);
2205012b7d33SRussell King 	host->hw_revision = amba_rev(dev);
220664de0289SLinus Walleij 	dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
220764de0289SLinus Walleij 	dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision);
2208012b7d33SRussell King 
2209665ba56fSUlf Hansson 	host->clk = devm_clk_get(&dev->dev, NULL);
22101c6a0718SPierre Ossman 	if (IS_ERR(host->clk)) {
22111c6a0718SPierre Ossman 		ret = PTR_ERR(host->clk);
22121c6a0718SPierre Ossman 		goto host_free;
22131c6a0718SPierre Ossman 	}
22141c6a0718SPierre Ossman 
2215ac940938SJulia Lawall 	ret = clk_prepare_enable(host->clk);
22161c6a0718SPierre Ossman 	if (ret)
2217665ba56fSUlf Hansson 		goto host_free;
22181c6a0718SPierre Ossman 
22199c34b73dSSrinivas Kandagatla 	if (variant->qcom_fifo)
22209c34b73dSSrinivas Kandagatla 		host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt;
22219c34b73dSSrinivas Kandagatla 	else
22229c34b73dSSrinivas Kandagatla 		host->get_rx_fifocnt = mmci_get_rx_fifocnt;
22239c34b73dSSrinivas Kandagatla 
22241c6a0718SPierre Ossman 	host->plat = plat;
22254956e109SRabin Vincent 	host->variant = variant;
22261c6a0718SPierre Ossman 	host->mclk = clk_get_rate(host->clk);
2227c8df9a53SLinus Walleij 	/*
2228c8df9a53SLinus Walleij 	 * According to the spec, mclk is max 100 MHz,
2229c8df9a53SLinus Walleij 	 * so we try to adjust the clock down to this,
2230c8df9a53SLinus Walleij 	 * (if possible).
2231c8df9a53SLinus Walleij 	 */
2232dc6500bfSSrinivas Kandagatla 	if (host->mclk > variant->f_max) {
2233dc6500bfSSrinivas Kandagatla 		ret = clk_set_rate(host->clk, variant->f_max);
2234c8df9a53SLinus Walleij 		if (ret < 0)
2235c8df9a53SLinus Walleij 			goto clk_disable;
2236c8df9a53SLinus Walleij 		host->mclk = clk_get_rate(host->clk);
223764de0289SLinus Walleij 		dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n",
223864de0289SLinus Walleij 			host->mclk);
2239c8df9a53SLinus Walleij 	}
2240ef289982SUlf Hansson 
2241c8ebae37SRussell King 	host->phybase = dev->res.start;
2242ef289982SUlf Hansson 	host->base = devm_ioremap_resource(&dev->dev, &dev->res);
2243ef289982SUlf Hansson 	if (IS_ERR(host->base)) {
2244ef289982SUlf Hansson 		ret = PTR_ERR(host->base);
22451c6a0718SPierre Ossman 		goto clk_disable;
22461c6a0718SPierre Ossman 	}
22471c6a0718SPierre Ossman 
2248ed9067fdSUlf Hansson 	if (variant->init)
2249ed9067fdSUlf Hansson 		variant->init(host);
2250ed9067fdSUlf Hansson 
22517f294e49SLinus Walleij 	/*
22527f294e49SLinus Walleij 	 * The ARM and ST versions of the block have slightly different
22537f294e49SLinus Walleij 	 * clock divider equations which means that the minimum divider
22547f294e49SLinus Walleij 	 * differs too.
22553f4e6f7bSSrinivas Kandagatla 	 * on Qualcomm like controllers get the nearest minimum clock to 100Khz
22567f294e49SLinus Walleij 	 */
22577f294e49SLinus Walleij 	if (variant->st_clkdiv)
22587f294e49SLinus Walleij 		mmc->f_min = DIV_ROUND_UP(host->mclk, 257);
225900e930d8SLudovic Barre 	else if (variant->stm32_clkdiv)
226000e930d8SLudovic Barre 		mmc->f_min = DIV_ROUND_UP(host->mclk, 2046);
22613f4e6f7bSSrinivas Kandagatla 	else if (variant->explicit_mclk_control)
22623f4e6f7bSSrinivas Kandagatla 		mmc->f_min = clk_round_rate(host->clk, 100000);
22637f294e49SLinus Walleij 	else
22647f294e49SLinus Walleij 		mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
2265808d97ccSLinus Walleij 	/*
226678f87df2SUlf Hansson 	 * If no maximum operating frequency is supplied, fall back to use
226778f87df2SUlf Hansson 	 * the module parameter, which has a (low) default value in case it
226878f87df2SUlf Hansson 	 * is not specified. Either value must not exceed the clock rate into
22695080a08dSUlf Hansson 	 * the block, of course.
2270808d97ccSLinus Walleij 	 */
227178f87df2SUlf Hansson 	if (mmc->f_max)
22723f4e6f7bSSrinivas Kandagatla 		mmc->f_max = variant->explicit_mclk_control ?
22733f4e6f7bSSrinivas Kandagatla 				min(variant->f_max, mmc->f_max) :
22743f4e6f7bSSrinivas Kandagatla 				min(host->mclk, mmc->f_max);
2275808d97ccSLinus Walleij 	else
22763f4e6f7bSSrinivas Kandagatla 		mmc->f_max = variant->explicit_mclk_control ?
22773f4e6f7bSSrinivas Kandagatla 				fmax : min(host->mclk, fmax);
22783f4e6f7bSSrinivas Kandagatla 
22793f4e6f7bSSrinivas Kandagatla 
228064de0289SLinus Walleij 	dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
228164de0289SLinus Walleij 
228215878e58SLudovic Barre 	host->rst = devm_reset_control_get_optional_exclusive(&dev->dev, NULL);
228315878e58SLudovic Barre 	if (IS_ERR(host->rst)) {
228415878e58SLudovic Barre 		ret = PTR_ERR(host->rst);
228515878e58SLudovic Barre 		goto clk_disable;
228615878e58SLudovic Barre 	}
2287575cf104SLinus Walleij 	ret = reset_control_deassert(host->rst);
2288575cf104SLinus Walleij 	if (ret)
2289575cf104SLinus Walleij 		dev_err(mmc_dev(mmc), "failed to de-assert reset\n");
229015878e58SLudovic Barre 
2291599c1d5cSUlf Hansson 	/* Get regulators and the supported OCR mask */
22929369c97cSBjorn Andersson 	ret = mmc_regulator_get_supply(mmc);
229351006952SWolfram Sang 	if (ret)
22949369c97cSBjorn Andersson 		goto clk_disable;
22959369c97cSBjorn Andersson 
2296599c1d5cSUlf Hansson 	if (!mmc->ocr_avail)
22971c6a0718SPierre Ossman 		mmc->ocr_avail = plat->ocr_mask;
2298599c1d5cSUlf Hansson 	else if (plat->ocr_mask)
2299599c1d5cSUlf Hansson 		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
2300599c1d5cSUlf Hansson 
23019dd8a8b8SUlf Hansson 	/* We support these capabilities. */
23029dd8a8b8SUlf Hansson 	mmc->caps |= MMC_CAP_CMD23;
23039dd8a8b8SUlf Hansson 
230449adc0caSLinus Walleij 	/*
230549adc0caSLinus Walleij 	 * Enable busy detection.
230649adc0caSLinus Walleij 	 */
23078d94b54dSUlf Hansson 	if (variant->busy_detect) {
23088d94b54dSUlf Hansson 		mmci_ops.card_busy = mmci_card_busy;
230949adc0caSLinus Walleij 		/*
231049adc0caSLinus Walleij 		 * Not all variants have a flag to enable busy detection
231149adc0caSLinus Walleij 		 * in the DPSM, but if they do, set it here.
231249adc0caSLinus Walleij 		 */
231349adc0caSLinus Walleij 		if (variant->busy_dpsm_flag)
231449adc0caSLinus Walleij 			mmci_write_datactrlreg(host,
231549adc0caSLinus Walleij 					       host->variant->busy_dpsm_flag);
23168d94b54dSUlf Hansson 		mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
23178d94b54dSUlf Hansson 	}
23188d94b54dSUlf Hansson 
2319774514bfSYann Gautier 	/* Variants with mandatory busy timeout in HW needs R1B responses. */
2320774514bfSYann Gautier 	if (variant->busy_timeout)
2321774514bfSYann Gautier 		mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
2322774514bfSYann Gautier 
2323e9968c6fSUlf Hansson 	/* Prepare a CMD12 - needed to clear the DPSM on some variants. */
2324e9968c6fSUlf Hansson 	host->stop_abort.opcode = MMC_STOP_TRANSMISSION;
2325e9968c6fSUlf Hansson 	host->stop_abort.arg = 0;
2326e9968c6fSUlf Hansson 	host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC;
2327e9968c6fSUlf Hansson 
232870be208fSUlf Hansson 	/* We support these PM capabilities. */
232978f87df2SUlf Hansson 	mmc->pm_caps |= MMC_PM_KEEP_POWER;
233070be208fSUlf Hansson 
23311c6a0718SPierre Ossman 	/*
23321c6a0718SPierre Ossman 	 * We can do SGIO
23331c6a0718SPierre Ossman 	 */
2334a36274e0SMartin K. Petersen 	mmc->max_segs = NR_SG;
23351c6a0718SPierre Ossman 
23361c6a0718SPierre Ossman 	/*
233708458ef6SRabin Vincent 	 * Since only a certain number of bits are valid in the data length
233808458ef6SRabin Vincent 	 * register, we must ensure that we don't exceed 2^num-1 bytes in a
233908458ef6SRabin Vincent 	 * single request.
23401c6a0718SPierre Ossman 	 */
234108458ef6SRabin Vincent 	mmc->max_req_size = (1 << variant->datalength_bits) - 1;
23421c6a0718SPierre Ossman 
23431c6a0718SPierre Ossman 	/*
23441c6a0718SPierre Ossman 	 * Set the maximum segment size.  Since we aren't doing DMA
23451c6a0718SPierre Ossman 	 * (yet) we are only limited by the data length register.
23461c6a0718SPierre Ossman 	 */
23471c6a0718SPierre Ossman 	mmc->max_seg_size = mmc->max_req_size;
23481c6a0718SPierre Ossman 
23491c6a0718SPierre Ossman 	/*
23501c6a0718SPierre Ossman 	 * Block size can be up to 2048 bytes, but must be a power of two.
23511c6a0718SPierre Ossman 	 */
2352c931d495SLudovic Barre 	mmc->max_blk_size = 1 << variant->datactrl_blocksz;
23531c6a0718SPierre Ossman 
23541c6a0718SPierre Ossman 	/*
23558f7f6b7eSWill Deacon 	 * Limit the number of blocks transferred so that we don't overflow
23568f7f6b7eSWill Deacon 	 * the maximum request size.
23571c6a0718SPierre Ossman 	 */
2358c931d495SLudovic Barre 	mmc->max_blk_count = mmc->max_req_size >> variant->datactrl_blocksz;
23591c6a0718SPierre Ossman 
23601c6a0718SPierre Ossman 	spin_lock_init(&host->lock);
23611c6a0718SPierre Ossman 
23621c6a0718SPierre Ossman 	writel(0, host->base + MMCIMASK0);
23636ea9cdf3SPatrice Chotard 
23646ea9cdf3SPatrice Chotard 	if (variant->mmcimask1)
23651c6a0718SPierre Ossman 		writel(0, host->base + MMCIMASK1);
23666ea9cdf3SPatrice Chotard 
23671c6a0718SPierre Ossman 	writel(0xfff, host->base + MMCICLEAR);
23681c6a0718SPierre Ossman 
2369ce437aa4SLinus Walleij 	/*
2370ce437aa4SLinus Walleij 	 * If:
2371ce437aa4SLinus Walleij 	 * - not using DT but using a descriptor table, or
2372ce437aa4SLinus Walleij 	 * - using a table of descriptors ALONGSIDE DT, or
2373ce437aa4SLinus Walleij 	 * look up these descriptors named "cd" and "wp" right here, fail
23749ef986a6SLinus Walleij 	 * silently of these do not exist
2375ce437aa4SLinus Walleij 	 */
2376ce437aa4SLinus Walleij 	if (!np) {
2377d0052ad9SMichał Mirosław 		ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0);
2378ce437aa4SLinus Walleij 		if (ret == -EPROBE_DEFER)
2379ce437aa4SLinus Walleij 			goto clk_disable;
2380ce437aa4SLinus Walleij 
2381d0052ad9SMichał Mirosław 		ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0);
2382ce437aa4SLinus Walleij 		if (ret == -EPROBE_DEFER)
2383ce437aa4SLinus Walleij 			goto clk_disable;
2384ce437aa4SLinus Walleij 	}
238589001446SRussell King 
2386ee157abeSLudovic Barre 	ret = devm_request_threaded_irq(&dev->dev, dev->irq[0], mmci_irq,
2387ee157abeSLudovic Barre 					mmci_irq_thread, IRQF_SHARED,
2388ef289982SUlf Hansson 					DRIVER_NAME " (cmd)", host);
23891c6a0718SPierre Ossman 	if (ret)
2390ef289982SUlf Hansson 		goto clk_disable;
23911c6a0718SPierre Ossman 
2392dfb85185SRussell King 	if (!dev->irq[1])
23932686b4b4SLinus Walleij 		host->singleirq = true;
23942686b4b4SLinus Walleij 	else {
2395ef289982SUlf Hansson 		ret = devm_request_irq(&dev->dev, dev->irq[1], mmci_pio_irq,
2396ef289982SUlf Hansson 				IRQF_SHARED, DRIVER_NAME " (pio)", host);
23971c6a0718SPierre Ossman 		if (ret)
2398ef289982SUlf Hansson 			goto clk_disable;
23992686b4b4SLinus Walleij 	}
24001c6a0718SPierre Ossman 
2401b1a66593SUlf Hansson 	if (host->variant->busy_detect)
2402b1a66593SUlf Hansson 		INIT_DELAYED_WORK(&host->ux500_busy_timeout_work,
2403b1a66593SUlf Hansson 				  ux500_busy_timeout_work);
2404b1a66593SUlf Hansson 
2405daf9713cSLudovic Barre 	writel(MCI_IRQENABLE | variant->start_err, host->base + MMCIMASK0);
24061c6a0718SPierre Ossman 
24071c6a0718SPierre Ossman 	amba_set_drvdata(dev, mmc);
24081c6a0718SPierre Ossman 
2409c8ebae37SRussell King 	dev_info(&dev->dev, "%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n",
2410c8ebae37SRussell King 		 mmc_hostname(mmc), amba_part(dev), amba_manf(dev),
2411c8ebae37SRussell King 		 amba_rev(dev), (unsigned long long)dev->res.start,
2412c8ebae37SRussell King 		 dev->irq[0], dev->irq[1]);
2413c8ebae37SRussell King 
2414c8ebae37SRussell King 	mmci_dma_setup(host);
24151c6a0718SPierre Ossman 
24162cd976c4SUlf Hansson 	pm_runtime_set_autosuspend_delay(&dev->dev, 50);
24172cd976c4SUlf Hansson 	pm_runtime_use_autosuspend(&dev->dev);
24181c3be369SRussell King 
2419b38a20f2SYang Yingliang 	ret = mmc_add_host(mmc);
2420b38a20f2SYang Yingliang 	if (ret)
2421b38a20f2SYang Yingliang 		goto clk_disable;
24228c11a94dSRussell King 
24236f2d3c89SUlf Hansson 	pm_runtime_put(&dev->dev);
24241c6a0718SPierre Ossman 	return 0;
24251c6a0718SPierre Ossman 
24261c6a0718SPierre Ossman  clk_disable:
2427ac940938SJulia Lawall 	clk_disable_unprepare(host->clk);
24281c6a0718SPierre Ossman  host_free:
24291c6a0718SPierre Ossman 	mmc_free_host(mmc);
24301c6a0718SPierre Ossman 	return ret;
24311c6a0718SPierre Ossman }
24321c6a0718SPierre Ossman 
mmci_remove(struct amba_device * dev)24333fd269e7SUwe Kleine-König static void mmci_remove(struct amba_device *dev)
24341c6a0718SPierre Ossman {
24351c6a0718SPierre Ossman 	struct mmc_host *mmc = amba_get_drvdata(dev);
24361c6a0718SPierre Ossman 
24371c6a0718SPierre Ossman 	if (mmc) {
24381c6a0718SPierre Ossman 		struct mmci_host *host = mmc_priv(mmc);
24396ea9cdf3SPatrice Chotard 		struct variant_data *variant = host->variant;
24401c6a0718SPierre Ossman 
24411c3be369SRussell King 		/*
24421c3be369SRussell King 		 * Undo pm_runtime_put() in probe.  We use the _sync
24431c3be369SRussell King 		 * version here so that we can access the primecell.
24441c3be369SRussell King 		 */
24451c3be369SRussell King 		pm_runtime_get_sync(&dev->dev);
24461c3be369SRussell King 
24471c6a0718SPierre Ossman 		mmc_remove_host(mmc);
24481c6a0718SPierre Ossman 
24491c6a0718SPierre Ossman 		writel(0, host->base + MMCIMASK0);
24506ea9cdf3SPatrice Chotard 
24516ea9cdf3SPatrice Chotard 		if (variant->mmcimask1)
24521c6a0718SPierre Ossman 			writel(0, host->base + MMCIMASK1);
24531c6a0718SPierre Ossman 
24541c6a0718SPierre Ossman 		writel(0, host->base + MMCICOMMAND);
24551c6a0718SPierre Ossman 		writel(0, host->base + MMCIDATACTRL);
24561c6a0718SPierre Ossman 
2457c8ebae37SRussell King 		mmci_dma_release(host);
2458ac940938SJulia Lawall 		clk_disable_unprepare(host->clk);
24591c6a0718SPierre Ossman 		mmc_free_host(mmc);
24601c6a0718SPierre Ossman 	}
24611c6a0718SPierre Ossman }
24621c6a0718SPierre Ossman 
2463571dce4fSUlf Hansson #ifdef CONFIG_PM
mmci_save(struct mmci_host * host)24641ff44433SUlf Hansson static void mmci_save(struct mmci_host *host)
24651ff44433SUlf Hansson {
24661ff44433SUlf Hansson 	unsigned long flags;
24671ff44433SUlf Hansson 
24681ff44433SUlf Hansson 	spin_lock_irqsave(&host->lock, flags);
24691ff44433SUlf Hansson 
24701ff44433SUlf Hansson 	writel(0, host->base + MMCIMASK0);
247142dcc89aSUlf Hansson 	if (host->variant->pwrreg_nopower) {
24721ff44433SUlf Hansson 		writel(0, host->base + MMCIDATACTRL);
24731ff44433SUlf Hansson 		writel(0, host->base + MMCIPOWER);
24741ff44433SUlf Hansson 		writel(0, host->base + MMCICLOCK);
247542dcc89aSUlf Hansson 	}
24761ff44433SUlf Hansson 	mmci_reg_delay(host);
24771ff44433SUlf Hansson 
24781ff44433SUlf Hansson 	spin_unlock_irqrestore(&host->lock, flags);
24791ff44433SUlf Hansson }
24801ff44433SUlf Hansson 
mmci_restore(struct mmci_host * host)24811ff44433SUlf Hansson static void mmci_restore(struct mmci_host *host)
24821ff44433SUlf Hansson {
24831ff44433SUlf Hansson 	unsigned long flags;
24841ff44433SUlf Hansson 
24851ff44433SUlf Hansson 	spin_lock_irqsave(&host->lock, flags);
24861ff44433SUlf Hansson 
248742dcc89aSUlf Hansson 	if (host->variant->pwrreg_nopower) {
24881ff44433SUlf Hansson 		writel(host->clk_reg, host->base + MMCICLOCK);
24891ff44433SUlf Hansson 		writel(host->datactrl_reg, host->base + MMCIDATACTRL);
24901ff44433SUlf Hansson 		writel(host->pwr_reg, host->base + MMCIPOWER);
249142dcc89aSUlf Hansson 	}
2492daf9713cSLudovic Barre 	writel(MCI_IRQENABLE | host->variant->start_err,
2493daf9713cSLudovic Barre 	       host->base + MMCIMASK0);
24941ff44433SUlf Hansson 	mmci_reg_delay(host);
24951ff44433SUlf Hansson 
24961ff44433SUlf Hansson 	spin_unlock_irqrestore(&host->lock, flags);
24971ff44433SUlf Hansson }
24981ff44433SUlf Hansson 
mmci_runtime_suspend(struct device * dev)24998259293aSUlf Hansson static int mmci_runtime_suspend(struct device *dev)
25008259293aSUlf Hansson {
25018259293aSUlf Hansson 	struct amba_device *adev = to_amba_device(dev);
25028259293aSUlf Hansson 	struct mmc_host *mmc = amba_get_drvdata(adev);
25038259293aSUlf Hansson 
25048259293aSUlf Hansson 	if (mmc) {
25058259293aSUlf Hansson 		struct mmci_host *host = mmc_priv(mmc);
2506e36bd9c6SUlf Hansson 		pinctrl_pm_select_sleep_state(dev);
25071ff44433SUlf Hansson 		mmci_save(host);
25088259293aSUlf Hansson 		clk_disable_unprepare(host->clk);
25098259293aSUlf Hansson 	}
25108259293aSUlf Hansson 
25118259293aSUlf Hansson 	return 0;
25128259293aSUlf Hansson }
25138259293aSUlf Hansson 
mmci_runtime_resume(struct device * dev)25148259293aSUlf Hansson static int mmci_runtime_resume(struct device *dev)
25158259293aSUlf Hansson {
25168259293aSUlf Hansson 	struct amba_device *adev = to_amba_device(dev);
25178259293aSUlf Hansson 	struct mmc_host *mmc = amba_get_drvdata(adev);
25188259293aSUlf Hansson 
25198259293aSUlf Hansson 	if (mmc) {
25208259293aSUlf Hansson 		struct mmci_host *host = mmc_priv(mmc);
25218259293aSUlf Hansson 		clk_prepare_enable(host->clk);
25221ff44433SUlf Hansson 		mmci_restore(host);
252305344ffeSUlf Hansson 		pinctrl_select_default_state(dev);
25248259293aSUlf Hansson 	}
25258259293aSUlf Hansson 
25268259293aSUlf Hansson 	return 0;
25278259293aSUlf Hansson }
25288259293aSUlf Hansson #endif
25298259293aSUlf Hansson 
253048fa7003SUlf Hansson static const struct dev_pm_ops mmci_dev_pm_ops = {
2531f3737fa3SUlf Hansson 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
2532f3737fa3SUlf Hansson 				pm_runtime_force_resume)
25336ed23b80SRafael J. Wysocki 	SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL)
253448fa7003SUlf Hansson };
253548fa7003SUlf Hansson 
253688411deaSArvind Yadav static const struct amba_id mmci_ids[] = {
25371c6a0718SPierre Ossman 	{
25381c6a0718SPierre Ossman 		.id	= 0x00041180,
2539768fbc18SPawel Moll 		.mask	= 0xff0fffff,
25404956e109SRabin Vincent 		.data	= &variant_arm,
25411c6a0718SPierre Ossman 	},
25421c6a0718SPierre Ossman 	{
2543768fbc18SPawel Moll 		.id	= 0x01041180,
2544768fbc18SPawel Moll 		.mask	= 0xff0fffff,
2545768fbc18SPawel Moll 		.data	= &variant_arm_extended_fifo,
2546768fbc18SPawel Moll 	},
2547768fbc18SPawel Moll 	{
25483a37298aSPawel Moll 		.id	= 0x02041180,
25493a37298aSPawel Moll 		.mask	= 0xff0fffff,
25503a37298aSPawel Moll 		.data	= &variant_arm_extended_fifo_hwfc,
25513a37298aSPawel Moll 	},
25523a37298aSPawel Moll 	{
25531c6a0718SPierre Ossman 		.id	= 0x00041181,
25541c6a0718SPierre Ossman 		.mask	= 0x000fffff,
25554956e109SRabin Vincent 		.data	= &variant_arm,
25561c6a0718SPierre Ossman 	},
2557cc30d60eSLinus Walleij 	/* ST Micro variants */
2558cc30d60eSLinus Walleij 	{
2559cc30d60eSLinus Walleij 		.id     = 0x00180180,
2560cc30d60eSLinus Walleij 		.mask   = 0x00ffffff,
25614956e109SRabin Vincent 		.data	= &variant_u300,
2562cc30d60eSLinus Walleij 	},
2563cc30d60eSLinus Walleij 	{
256434fd4213SLinus Walleij 		.id     = 0x10180180,
256534fd4213SLinus Walleij 		.mask   = 0xf0ffffff,
256634fd4213SLinus Walleij 		.data	= &variant_nomadik,
256734fd4213SLinus Walleij 	},
256834fd4213SLinus Walleij 	{
2569cc30d60eSLinus Walleij 		.id     = 0x00280180,
2570cc30d60eSLinus Walleij 		.mask   = 0x00ffffff,
25710bcb7efdSLinus Walleij 		.data	= &variant_nomadik,
25724956e109SRabin Vincent 	},
25734956e109SRabin Vincent 	{
25744956e109SRabin Vincent 		.id     = 0x00480180,
25751784b157SPhilippe Langlais 		.mask   = 0xf0ffffff,
25764956e109SRabin Vincent 		.data	= &variant_ux500,
2577cc30d60eSLinus Walleij 	},
25781784b157SPhilippe Langlais 	{
25791784b157SPhilippe Langlais 		.id     = 0x10480180,
25801784b157SPhilippe Langlais 		.mask   = 0xf0ffffff,
25811784b157SPhilippe Langlais 		.data	= &variant_ux500v2,
25821784b157SPhilippe Langlais 	},
25832a9d6c80SPatrice Chotard 	{
25842a9d6c80SPatrice Chotard 		.id     = 0x00880180,
25852a9d6c80SPatrice Chotard 		.mask   = 0x00ffffff,
25862a9d6c80SPatrice Chotard 		.data	= &variant_stm32,
25872a9d6c80SPatrice Chotard 	},
258846b723ddSLudovic Barre 	{
258946b723ddSLudovic Barre 		.id     = 0x10153180,
259046b723ddSLudovic Barre 		.mask	= 0xf0ffffff,
259146b723ddSLudovic Barre 		.data	= &variant_stm32_sdmmc,
259246b723ddSLudovic Barre 	},
25937a2a98beSLudovic Barre 	{
25947a2a98beSLudovic Barre 		.id     = 0x00253180,
25957a2a98beSLudovic Barre 		.mask	= 0xf0ffffff,
25967a2a98beSLudovic Barre 		.data	= &variant_stm32_sdmmcv2,
25977a2a98beSLudovic Barre 	},
25985471fe8bSYann Gautier 	{
25995471fe8bSYann Gautier 		.id     = 0x20253180,
26005471fe8bSYann Gautier 		.mask	= 0xf0ffffff,
26015471fe8bSYann Gautier 		.data	= &variant_stm32_sdmmcv2,
26025471fe8bSYann Gautier 	},
2603ea9ca041SYann Gautier 	{
2604ea9ca041SYann Gautier 		.id     = 0x00353180,
2605ea9ca041SYann Gautier 		.mask	= 0xf0ffffff,
2606ea9ca041SYann Gautier 		.data	= &variant_stm32_sdmmcv3,
2607ea9ca041SYann Gautier 	},
260855b604aeSSrinivas Kandagatla 	/* Qualcomm variants */
260955b604aeSSrinivas Kandagatla 	{
261055b604aeSSrinivas Kandagatla 		.id     = 0x00051180,
261155b604aeSSrinivas Kandagatla 		.mask	= 0x000fffff,
261255b604aeSSrinivas Kandagatla 		.data	= &variant_qcom,
261355b604aeSSrinivas Kandagatla 	},
26141c6a0718SPierre Ossman 	{ 0, 0 },
26151c6a0718SPierre Ossman };
26161c6a0718SPierre Ossman 
26179f99835fSDave Martin MODULE_DEVICE_TABLE(amba, mmci_ids);
26189f99835fSDave Martin 
26191c6a0718SPierre Ossman static struct amba_driver mmci_driver = {
26201c6a0718SPierre Ossman 	.drv		= {
26211c6a0718SPierre Ossman 		.name	= DRIVER_NAME,
262248fa7003SUlf Hansson 		.pm	= &mmci_dev_pm_ops,
26233108eb2eSUlf Hansson 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
26241c6a0718SPierre Ossman 	},
26251c6a0718SPierre Ossman 	.probe		= mmci_probe,
26260433c143SBill Pemberton 	.remove		= mmci_remove,
26271c6a0718SPierre Ossman 	.id_table	= mmci_ids,
26281c6a0718SPierre Ossman };
26291c6a0718SPierre Ossman 
26309e5ed094Sviresh kumar module_amba_driver(mmci_driver);
26311c6a0718SPierre Ossman 
26321c6a0718SPierre Ossman module_param(fmax, uint, 0444);
26331c6a0718SPierre Ossman 
26341c6a0718SPierre Ossman MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver");
26351c6a0718SPierre Ossman MODULE_LICENSE("GPL");
2636