xref: /openbmc/linux/drivers/mmc/host/sdhci.c (revision 2ee4f620)
11c6a0718SPierre Ossman /*
270f10482SPierre Ossman  *  linux/drivers/mmc/host/sdhci.c - Secure Digital Host Controller Interface driver
31c6a0718SPierre Ossman  *
4b69c9058SPierre Ossman  *  Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
51c6a0718SPierre Ossman  *
61c6a0718SPierre Ossman  * This program is free software; you can redistribute it and/or modify
71c6a0718SPierre Ossman  * it under the terms of the GNU General Public License as published by
81c6a0718SPierre Ossman  * the Free Software Foundation; either version 2 of the License, or (at
91c6a0718SPierre Ossman  * your option) any later version.
1084c46a53SPierre Ossman  *
1184c46a53SPierre Ossman  * Thanks to the following companies for their support:
1284c46a53SPierre Ossman  *
1384c46a53SPierre Ossman  *     - JMicron (hardware and technical support)
141c6a0718SPierre Ossman  */
151c6a0718SPierre Ossman 
161c6a0718SPierre Ossman #include <linux/delay.h>
175a436cc0SAdrian Hunter #include <linux/ktime.h>
181c6a0718SPierre Ossman #include <linux/highmem.h>
19b8c86fc5SPierre Ossman #include <linux/io.h>
2088b47679SPaul Gortmaker #include <linux/module.h>
211c6a0718SPierre Ossman #include <linux/dma-mapping.h>
225a0e3ad6STejun Heo #include <linux/slab.h>
2311763609SRalf Baechle #include <linux/scatterlist.h>
249bea3c85SMarek Szyprowski #include <linux/regulator/consumer.h>
2566fd8ad5SAdrian Hunter #include <linux/pm_runtime.h>
2692e0c44bSZach Brown #include <linux/of.h>
271c6a0718SPierre Ossman 
282f730fecSPierre Ossman #include <linux/leds.h>
292f730fecSPierre Ossman 
3022113efdSAries Lee #include <linux/mmc/mmc.h>
311c6a0718SPierre Ossman #include <linux/mmc/host.h>
32473b095aSAaron Lu #include <linux/mmc/card.h>
3385cc1c33SCorneliu Doban #include <linux/mmc/sdio.h>
34bec9d4e5SGuennadi Liakhovetski #include <linux/mmc/slot-gpio.h>
351c6a0718SPierre Ossman 
361c6a0718SPierre Ossman #include "sdhci.h"
371c6a0718SPierre Ossman 
381c6a0718SPierre Ossman #define DRIVER_NAME "sdhci"
391c6a0718SPierre Ossman 
401c6a0718SPierre Ossman #define DBG(f, x...) \
41f421865dSAdrian Hunter 	pr_debug("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x)
421c6a0718SPierre Ossman 
4385ad90e2SAdrian Hunter #define SDHCI_DUMP(f, x...) \
4485ad90e2SAdrian Hunter 	pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x)
4585ad90e2SAdrian Hunter 
46b513ea25SArindam Nath #define MAX_TUNING_LOOP 40
47b513ea25SArindam Nath 
481c6a0718SPierre Ossman static unsigned int debug_quirks = 0;
4966fd8ad5SAdrian Hunter static unsigned int debug_quirks2;
501c6a0718SPierre Ossman 
511c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *);
521c6a0718SPierre Ossman 
5352983382SKevin Liu static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
541c6a0718SPierre Ossman 
55d2898172SAdrian Hunter void sdhci_dumpregs(struct sdhci_host *host)
561c6a0718SPierre Ossman {
5785ad90e2SAdrian Hunter 	SDHCI_DUMP("============ SDHCI REGISTER DUMP ===========\n");
581c6a0718SPierre Ossman 
5985ad90e2SAdrian Hunter 	SDHCI_DUMP("Sys addr:  0x%08x | Version:  0x%08x\n",
604e4141a5SAnton Vorontsov 		   sdhci_readl(host, SDHCI_DMA_ADDRESS),
614e4141a5SAnton Vorontsov 		   sdhci_readw(host, SDHCI_HOST_VERSION));
6285ad90e2SAdrian Hunter 	SDHCI_DUMP("Blk size:  0x%08x | Blk cnt:  0x%08x\n",
634e4141a5SAnton Vorontsov 		   sdhci_readw(host, SDHCI_BLOCK_SIZE),
644e4141a5SAnton Vorontsov 		   sdhci_readw(host, SDHCI_BLOCK_COUNT));
6585ad90e2SAdrian Hunter 	SDHCI_DUMP("Argument:  0x%08x | Trn mode: 0x%08x\n",
664e4141a5SAnton Vorontsov 		   sdhci_readl(host, SDHCI_ARGUMENT),
674e4141a5SAnton Vorontsov 		   sdhci_readw(host, SDHCI_TRANSFER_MODE));
6885ad90e2SAdrian Hunter 	SDHCI_DUMP("Present:   0x%08x | Host ctl: 0x%08x\n",
694e4141a5SAnton Vorontsov 		   sdhci_readl(host, SDHCI_PRESENT_STATE),
704e4141a5SAnton Vorontsov 		   sdhci_readb(host, SDHCI_HOST_CONTROL));
7185ad90e2SAdrian Hunter 	SDHCI_DUMP("Power:     0x%08x | Blk gap:  0x%08x\n",
724e4141a5SAnton Vorontsov 		   sdhci_readb(host, SDHCI_POWER_CONTROL),
734e4141a5SAnton Vorontsov 		   sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
7485ad90e2SAdrian Hunter 	SDHCI_DUMP("Wake-up:   0x%08x | Clock:    0x%08x\n",
754e4141a5SAnton Vorontsov 		   sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
764e4141a5SAnton Vorontsov 		   sdhci_readw(host, SDHCI_CLOCK_CONTROL));
7785ad90e2SAdrian Hunter 	SDHCI_DUMP("Timeout:   0x%08x | Int stat: 0x%08x\n",
784e4141a5SAnton Vorontsov 		   sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
794e4141a5SAnton Vorontsov 		   sdhci_readl(host, SDHCI_INT_STATUS));
8085ad90e2SAdrian Hunter 	SDHCI_DUMP("Int enab:  0x%08x | Sig enab: 0x%08x\n",
814e4141a5SAnton Vorontsov 		   sdhci_readl(host, SDHCI_INT_ENABLE),
824e4141a5SAnton Vorontsov 		   sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
8385ad90e2SAdrian Hunter 	SDHCI_DUMP("AC12 err:  0x%08x | Slot int: 0x%08x\n",
844e4141a5SAnton Vorontsov 		   sdhci_readw(host, SDHCI_ACMD12_ERR),
854e4141a5SAnton Vorontsov 		   sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
8685ad90e2SAdrian Hunter 	SDHCI_DUMP("Caps:      0x%08x | Caps_1:   0x%08x\n",
874e4141a5SAnton Vorontsov 		   sdhci_readl(host, SDHCI_CAPABILITIES),
88e8120ad1SPhilip Rakity 		   sdhci_readl(host, SDHCI_CAPABILITIES_1));
8985ad90e2SAdrian Hunter 	SDHCI_DUMP("Cmd:       0x%08x | Max curr: 0x%08x\n",
90e8120ad1SPhilip Rakity 		   sdhci_readw(host, SDHCI_COMMAND),
914e4141a5SAnton Vorontsov 		   sdhci_readl(host, SDHCI_MAX_CURRENT));
9285ad90e2SAdrian Hunter 	SDHCI_DUMP("Resp[0]:   0x%08x | Resp[1]:  0x%08x\n",
937962302fSAdrian Hunter 		   sdhci_readl(host, SDHCI_RESPONSE),
947962302fSAdrian Hunter 		   sdhci_readl(host, SDHCI_RESPONSE + 4));
9585ad90e2SAdrian Hunter 	SDHCI_DUMP("Resp[2]:   0x%08x | Resp[3]:  0x%08x\n",
967962302fSAdrian Hunter 		   sdhci_readl(host, SDHCI_RESPONSE + 8),
977962302fSAdrian Hunter 		   sdhci_readl(host, SDHCI_RESPONSE + 12));
9885ad90e2SAdrian Hunter 	SDHCI_DUMP("Host ctl2: 0x%08x\n",
99f2119df6SArindam Nath 		   sdhci_readw(host, SDHCI_HOST_CONTROL2));
1001c6a0718SPierre Ossman 
101e57a5f61SAdrian Hunter 	if (host->flags & SDHCI_USE_ADMA) {
10285ad90e2SAdrian Hunter 		if (host->flags & SDHCI_USE_64_BIT_DMA) {
10385ad90e2SAdrian Hunter 			SDHCI_DUMP("ADMA Err:  0x%08x | ADMA Ptr: 0x%08x%08x\n",
104c71024deSAdrian Hunter 				   sdhci_readl(host, SDHCI_ADMA_ERROR),
105c71024deSAdrian Hunter 				   sdhci_readl(host, SDHCI_ADMA_ADDRESS_HI),
106c71024deSAdrian Hunter 				   sdhci_readl(host, SDHCI_ADMA_ADDRESS));
10785ad90e2SAdrian Hunter 		} else {
10885ad90e2SAdrian Hunter 			SDHCI_DUMP("ADMA Err:  0x%08x | ADMA Ptr: 0x%08x\n",
109c71024deSAdrian Hunter 				   sdhci_readl(host, SDHCI_ADMA_ERROR),
110c71024deSAdrian Hunter 				   sdhci_readl(host, SDHCI_ADMA_ADDRESS));
111e57a5f61SAdrian Hunter 		}
11285ad90e2SAdrian Hunter 	}
113be3f4ae0SBen Dooks 
11485ad90e2SAdrian Hunter 	SDHCI_DUMP("============================================\n");
1151c6a0718SPierre Ossman }
116d2898172SAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_dumpregs);
1171c6a0718SPierre Ossman 
1181c6a0718SPierre Ossman /*****************************************************************************\
1191c6a0718SPierre Ossman  *                                                                           *
1201c6a0718SPierre Ossman  * Low level functions                                                       *
1211c6a0718SPierre Ossman  *                                                                           *
1221c6a0718SPierre Ossman \*****************************************************************************/
1231c6a0718SPierre Ossman 
12456a590dcSAdrian Hunter static inline bool sdhci_data_line_cmd(struct mmc_command *cmd)
12556a590dcSAdrian Hunter {
12656a590dcSAdrian Hunter 	return cmd->data || cmd->flags & MMC_RSP_BUSY;
12756a590dcSAdrian Hunter }
12856a590dcSAdrian Hunter 
1297260cf5eSAnton Vorontsov static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
1307260cf5eSAnton Vorontsov {
1315b4f1f6cSRussell King 	u32 present;
1327260cf5eSAnton Vorontsov 
133c79396c1SAdrian Hunter 	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
134860951c5SJaehoon Chung 	    !mmc_card_is_removable(host->mmc))
13566fd8ad5SAdrian Hunter 		return;
13666fd8ad5SAdrian Hunter 
1375b4f1f6cSRussell King 	if (enable) {
138d25928d1SShawn Guo 		present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
139d25928d1SShawn Guo 				      SDHCI_CARD_PRESENT;
140d25928d1SShawn Guo 
1415b4f1f6cSRussell King 		host->ier |= present ? SDHCI_INT_CARD_REMOVE :
1425b4f1f6cSRussell King 				       SDHCI_INT_CARD_INSERT;
1435b4f1f6cSRussell King 	} else {
1445b4f1f6cSRussell King 		host->ier &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
1455b4f1f6cSRussell King 	}
146b537f94cSRussell King 
147b537f94cSRussell King 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
148b537f94cSRussell King 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
1497260cf5eSAnton Vorontsov }
1507260cf5eSAnton Vorontsov 
1517260cf5eSAnton Vorontsov static void sdhci_enable_card_detection(struct sdhci_host *host)
1527260cf5eSAnton Vorontsov {
1537260cf5eSAnton Vorontsov 	sdhci_set_card_detection(host, true);
1547260cf5eSAnton Vorontsov }
1557260cf5eSAnton Vorontsov 
1567260cf5eSAnton Vorontsov static void sdhci_disable_card_detection(struct sdhci_host *host)
1577260cf5eSAnton Vorontsov {
1587260cf5eSAnton Vorontsov 	sdhci_set_card_detection(host, false);
1597260cf5eSAnton Vorontsov }
1607260cf5eSAnton Vorontsov 
16102d0b685SUlf Hansson static void sdhci_runtime_pm_bus_on(struct sdhci_host *host)
16202d0b685SUlf Hansson {
16302d0b685SUlf Hansson 	if (host->bus_on)
16402d0b685SUlf Hansson 		return;
16502d0b685SUlf Hansson 	host->bus_on = true;
16602d0b685SUlf Hansson 	pm_runtime_get_noresume(host->mmc->parent);
16702d0b685SUlf Hansson }
16802d0b685SUlf Hansson 
16902d0b685SUlf Hansson static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
17002d0b685SUlf Hansson {
17102d0b685SUlf Hansson 	if (!host->bus_on)
17202d0b685SUlf Hansson 		return;
17302d0b685SUlf Hansson 	host->bus_on = false;
17402d0b685SUlf Hansson 	pm_runtime_put_noidle(host->mmc->parent);
17502d0b685SUlf Hansson }
17602d0b685SUlf Hansson 
17703231f9bSRussell King void sdhci_reset(struct sdhci_host *host, u8 mask)
1781c6a0718SPierre Ossman {
1795a436cc0SAdrian Hunter 	ktime_t timeout;
180393c1a34SPhilip Rakity 
1814e4141a5SAnton Vorontsov 	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
1821c6a0718SPierre Ossman 
183f0710a55SAdrian Hunter 	if (mask & SDHCI_RESET_ALL) {
1841c6a0718SPierre Ossman 		host->clock = 0;
185f0710a55SAdrian Hunter 		/* Reset-all turns off SD Bus Power */
186f0710a55SAdrian Hunter 		if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
187f0710a55SAdrian Hunter 			sdhci_runtime_pm_bus_off(host);
188f0710a55SAdrian Hunter 	}
1891c6a0718SPierre Ossman 
1901c6a0718SPierre Ossman 	/* Wait max 100 ms */
1915a436cc0SAdrian Hunter 	timeout = ktime_add_ms(ktime_get(), 100);
1921c6a0718SPierre Ossman 
1931c6a0718SPierre Ossman 	/* hw clears the bit when it's done */
1944e4141a5SAnton Vorontsov 	while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
1955a436cc0SAdrian Hunter 		if (ktime_after(ktime_get(), timeout)) {
196a3c76eb9SGirish K S 			pr_err("%s: Reset 0x%x never completed.\n",
1971c6a0718SPierre Ossman 				mmc_hostname(host->mmc), (int)mask);
1981c6a0718SPierre Ossman 			sdhci_dumpregs(host);
1991c6a0718SPierre Ossman 			return;
2001c6a0718SPierre Ossman 		}
2015a436cc0SAdrian Hunter 		udelay(10);
2021c6a0718SPierre Ossman 	}
20303231f9bSRussell King }
20403231f9bSRussell King EXPORT_SYMBOL_GPL(sdhci_reset);
205063a9dbbSAnton Vorontsov 
20603231f9bSRussell King static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
20703231f9bSRussell King {
20803231f9bSRussell King 	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
209d3940f27SAdrian Hunter 		struct mmc_host *mmc = host->mmc;
210d3940f27SAdrian Hunter 
211d3940f27SAdrian Hunter 		if (!mmc->ops->get_cd(mmc))
21203231f9bSRussell King 			return;
21303231f9bSRussell King 	}
21403231f9bSRussell King 
21503231f9bSRussell King 	host->ops->reset(host, mask);
216393c1a34SPhilip Rakity 
217da91a8f9SRussell King 	if (mask & SDHCI_RESET_ALL) {
2183abc1e80SShaohui Xie 		if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
219da91a8f9SRussell King 			if (host->ops->enable_dma)
2203abc1e80SShaohui Xie 				host->ops->enable_dma(host);
2213abc1e80SShaohui Xie 		}
222da91a8f9SRussell King 
223da91a8f9SRussell King 		/* Resetting the controller clears many */
224da91a8f9SRussell King 		host->preset_enabled = false;
225da91a8f9SRussell King 	}
2261c6a0718SPierre Ossman }
2271c6a0718SPierre Ossman 
228f5c1ab82SAdrian Hunter static void sdhci_set_default_irqs(struct sdhci_host *host)
2291c6a0718SPierre Ossman {
230b537f94cSRussell King 	host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
231b537f94cSRussell King 		    SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
232b537f94cSRussell King 		    SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC |
233b537f94cSRussell King 		    SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END |
234b537f94cSRussell King 		    SDHCI_INT_RESPONSE;
235b537f94cSRussell King 
236f37b20ebSDong Aisheng 	if (host->tuning_mode == SDHCI_TUNING_MODE_2 ||
237f37b20ebSDong Aisheng 	    host->tuning_mode == SDHCI_TUNING_MODE_3)
238f37b20ebSDong Aisheng 		host->ier |= SDHCI_INT_RETUNE;
239f37b20ebSDong Aisheng 
240b537f94cSRussell King 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
241b537f94cSRussell King 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
242f5c1ab82SAdrian Hunter }
243f5c1ab82SAdrian Hunter 
244f5c1ab82SAdrian Hunter static void sdhci_init(struct sdhci_host *host, int soft)
245f5c1ab82SAdrian Hunter {
246f5c1ab82SAdrian Hunter 	struct mmc_host *mmc = host->mmc;
247f5c1ab82SAdrian Hunter 
248f5c1ab82SAdrian Hunter 	if (soft)
249f5c1ab82SAdrian Hunter 		sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
250f5c1ab82SAdrian Hunter 	else
251f5c1ab82SAdrian Hunter 		sdhci_do_reset(host, SDHCI_RESET_ALL);
252f5c1ab82SAdrian Hunter 
253f5c1ab82SAdrian Hunter 	sdhci_set_default_irqs(host);
2542f4cbb3dSNicolas Pitre 
255f12e39dbSAdrian Hunter 	host->cqe_on = false;
256f12e39dbSAdrian Hunter 
2572f4cbb3dSNicolas Pitre 	if (soft) {
2582f4cbb3dSNicolas Pitre 		/* force clock reconfiguration */
2592f4cbb3dSNicolas Pitre 		host->clock = 0;
260d3940f27SAdrian Hunter 		mmc->ops->set_ios(mmc, &mmc->ios);
2612f4cbb3dSNicolas Pitre 	}
2627260cf5eSAnton Vorontsov }
2631c6a0718SPierre Ossman 
2647260cf5eSAnton Vorontsov static void sdhci_reinit(struct sdhci_host *host)
2657260cf5eSAnton Vorontsov {
2662f4cbb3dSNicolas Pitre 	sdhci_init(host, 0);
2677260cf5eSAnton Vorontsov 	sdhci_enable_card_detection(host);
2681c6a0718SPierre Ossman }
2691c6a0718SPierre Ossman 
270061d17a6SAdrian Hunter static void __sdhci_led_activate(struct sdhci_host *host)
2711c6a0718SPierre Ossman {
2721c6a0718SPierre Ossman 	u8 ctrl;
2731c6a0718SPierre Ossman 
2744e4141a5SAnton Vorontsov 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
2751c6a0718SPierre Ossman 	ctrl |= SDHCI_CTRL_LED;
2764e4141a5SAnton Vorontsov 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
2771c6a0718SPierre Ossman }
2781c6a0718SPierre Ossman 
279061d17a6SAdrian Hunter static void __sdhci_led_deactivate(struct sdhci_host *host)
2801c6a0718SPierre Ossman {
2811c6a0718SPierre Ossman 	u8 ctrl;
2821c6a0718SPierre Ossman 
2834e4141a5SAnton Vorontsov 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
2841c6a0718SPierre Ossman 	ctrl &= ~SDHCI_CTRL_LED;
2854e4141a5SAnton Vorontsov 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
2861c6a0718SPierre Ossman }
2871c6a0718SPierre Ossman 
2884f78230fSMasahiro Yamada #if IS_REACHABLE(CONFIG_LEDS_CLASS)
2892f730fecSPierre Ossman static void sdhci_led_control(struct led_classdev *led,
2902f730fecSPierre Ossman 			      enum led_brightness brightness)
2912f730fecSPierre Ossman {
2922f730fecSPierre Ossman 	struct sdhci_host *host = container_of(led, struct sdhci_host, led);
2932f730fecSPierre Ossman 	unsigned long flags;
2942f730fecSPierre Ossman 
2952f730fecSPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
2962f730fecSPierre Ossman 
29766fd8ad5SAdrian Hunter 	if (host->runtime_suspended)
29866fd8ad5SAdrian Hunter 		goto out;
29966fd8ad5SAdrian Hunter 
3002f730fecSPierre Ossman 	if (brightness == LED_OFF)
301061d17a6SAdrian Hunter 		__sdhci_led_deactivate(host);
3022f730fecSPierre Ossman 	else
303061d17a6SAdrian Hunter 		__sdhci_led_activate(host);
30466fd8ad5SAdrian Hunter out:
3052f730fecSPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
3062f730fecSPierre Ossman }
307061d17a6SAdrian Hunter 
308061d17a6SAdrian Hunter static int sdhci_led_register(struct sdhci_host *host)
309061d17a6SAdrian Hunter {
310061d17a6SAdrian Hunter 	struct mmc_host *mmc = host->mmc;
311061d17a6SAdrian Hunter 
312061d17a6SAdrian Hunter 	snprintf(host->led_name, sizeof(host->led_name),
313061d17a6SAdrian Hunter 		 "%s::", mmc_hostname(mmc));
314061d17a6SAdrian Hunter 
315061d17a6SAdrian Hunter 	host->led.name = host->led_name;
316061d17a6SAdrian Hunter 	host->led.brightness = LED_OFF;
317061d17a6SAdrian Hunter 	host->led.default_trigger = mmc_hostname(mmc);
318061d17a6SAdrian Hunter 	host->led.brightness_set = sdhci_led_control;
319061d17a6SAdrian Hunter 
320061d17a6SAdrian Hunter 	return led_classdev_register(mmc_dev(mmc), &host->led);
321061d17a6SAdrian Hunter }
322061d17a6SAdrian Hunter 
323061d17a6SAdrian Hunter static void sdhci_led_unregister(struct sdhci_host *host)
324061d17a6SAdrian Hunter {
325061d17a6SAdrian Hunter 	led_classdev_unregister(&host->led);
326061d17a6SAdrian Hunter }
327061d17a6SAdrian Hunter 
328061d17a6SAdrian Hunter static inline void sdhci_led_activate(struct sdhci_host *host)
329061d17a6SAdrian Hunter {
330061d17a6SAdrian Hunter }
331061d17a6SAdrian Hunter 
332061d17a6SAdrian Hunter static inline void sdhci_led_deactivate(struct sdhci_host *host)
333061d17a6SAdrian Hunter {
334061d17a6SAdrian Hunter }
335061d17a6SAdrian Hunter 
336061d17a6SAdrian Hunter #else
337061d17a6SAdrian Hunter 
338061d17a6SAdrian Hunter static inline int sdhci_led_register(struct sdhci_host *host)
339061d17a6SAdrian Hunter {
340061d17a6SAdrian Hunter 	return 0;
341061d17a6SAdrian Hunter }
342061d17a6SAdrian Hunter 
343061d17a6SAdrian Hunter static inline void sdhci_led_unregister(struct sdhci_host *host)
344061d17a6SAdrian Hunter {
345061d17a6SAdrian Hunter }
346061d17a6SAdrian Hunter 
347061d17a6SAdrian Hunter static inline void sdhci_led_activate(struct sdhci_host *host)
348061d17a6SAdrian Hunter {
349061d17a6SAdrian Hunter 	__sdhci_led_activate(host);
350061d17a6SAdrian Hunter }
351061d17a6SAdrian Hunter 
352061d17a6SAdrian Hunter static inline void sdhci_led_deactivate(struct sdhci_host *host)
353061d17a6SAdrian Hunter {
354061d17a6SAdrian Hunter 	__sdhci_led_deactivate(host);
355061d17a6SAdrian Hunter }
356061d17a6SAdrian Hunter 
3572f730fecSPierre Ossman #endif
3582f730fecSPierre Ossman 
3591c6a0718SPierre Ossman /*****************************************************************************\
3601c6a0718SPierre Ossman  *                                                                           *
3611c6a0718SPierre Ossman  * Core functions                                                            *
3621c6a0718SPierre Ossman  *                                                                           *
3631c6a0718SPierre Ossman \*****************************************************************************/
3641c6a0718SPierre Ossman 
3651c6a0718SPierre Ossman static void sdhci_read_block_pio(struct sdhci_host *host)
3661c6a0718SPierre Ossman {
3677659150cSPierre Ossman 	unsigned long flags;
3687659150cSPierre Ossman 	size_t blksize, len, chunk;
3697244b85bSSteven Noonan 	u32 uninitialized_var(scratch);
3707659150cSPierre Ossman 	u8 *buf;
3711c6a0718SPierre Ossman 
3721c6a0718SPierre Ossman 	DBG("PIO reading\n");
3731c6a0718SPierre Ossman 
3741c6a0718SPierre Ossman 	blksize = host->data->blksz;
3757659150cSPierre Ossman 	chunk = 0;
3761c6a0718SPierre Ossman 
3777659150cSPierre Ossman 	local_irq_save(flags);
3781c6a0718SPierre Ossman 
3791c6a0718SPierre Ossman 	while (blksize) {
380bf3a35acSFabio Estevam 		BUG_ON(!sg_miter_next(&host->sg_miter));
3817659150cSPierre Ossman 
3827659150cSPierre Ossman 		len = min(host->sg_miter.length, blksize);
3837659150cSPierre Ossman 
3847659150cSPierre Ossman 		blksize -= len;
3857659150cSPierre Ossman 		host->sg_miter.consumed = len;
3867659150cSPierre Ossman 
3877659150cSPierre Ossman 		buf = host->sg_miter.addr;
3887659150cSPierre Ossman 
3897659150cSPierre Ossman 		while (len) {
3907659150cSPierre Ossman 			if (chunk == 0) {
3914e4141a5SAnton Vorontsov 				scratch = sdhci_readl(host, SDHCI_BUFFER);
3927659150cSPierre Ossman 				chunk = 4;
3931c6a0718SPierre Ossman 			}
3941c6a0718SPierre Ossman 
3957659150cSPierre Ossman 			*buf = scratch & 0xFF;
3961c6a0718SPierre Ossman 
3977659150cSPierre Ossman 			buf++;
3987659150cSPierre Ossman 			scratch >>= 8;
3997659150cSPierre Ossman 			chunk--;
4007659150cSPierre Ossman 			len--;
4017659150cSPierre Ossman 		}
4021c6a0718SPierre Ossman 	}
4031c6a0718SPierre Ossman 
4047659150cSPierre Ossman 	sg_miter_stop(&host->sg_miter);
4057659150cSPierre Ossman 
4067659150cSPierre Ossman 	local_irq_restore(flags);
4071c6a0718SPierre Ossman }
4081c6a0718SPierre Ossman 
4091c6a0718SPierre Ossman static void sdhci_write_block_pio(struct sdhci_host *host)
4101c6a0718SPierre Ossman {
4117659150cSPierre Ossman 	unsigned long flags;
4127659150cSPierre Ossman 	size_t blksize, len, chunk;
4137659150cSPierre Ossman 	u32 scratch;
4147659150cSPierre Ossman 	u8 *buf;
4151c6a0718SPierre Ossman 
4161c6a0718SPierre Ossman 	DBG("PIO writing\n");
4171c6a0718SPierre Ossman 
4181c6a0718SPierre Ossman 	blksize = host->data->blksz;
4197659150cSPierre Ossman 	chunk = 0;
4207659150cSPierre Ossman 	scratch = 0;
4211c6a0718SPierre Ossman 
4227659150cSPierre Ossman 	local_irq_save(flags);
4231c6a0718SPierre Ossman 
4241c6a0718SPierre Ossman 	while (blksize) {
425bf3a35acSFabio Estevam 		BUG_ON(!sg_miter_next(&host->sg_miter));
4261c6a0718SPierre Ossman 
4277659150cSPierre Ossman 		len = min(host->sg_miter.length, blksize);
4281c6a0718SPierre Ossman 
4297659150cSPierre Ossman 		blksize -= len;
4307659150cSPierre Ossman 		host->sg_miter.consumed = len;
4317659150cSPierre Ossman 
4327659150cSPierre Ossman 		buf = host->sg_miter.addr;
4337659150cSPierre Ossman 
4347659150cSPierre Ossman 		while (len) {
4357659150cSPierre Ossman 			scratch |= (u32)*buf << (chunk * 8);
4367659150cSPierre Ossman 
4377659150cSPierre Ossman 			buf++;
4387659150cSPierre Ossman 			chunk++;
4397659150cSPierre Ossman 			len--;
4407659150cSPierre Ossman 
4417659150cSPierre Ossman 			if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
4424e4141a5SAnton Vorontsov 				sdhci_writel(host, scratch, SDHCI_BUFFER);
4437659150cSPierre Ossman 				chunk = 0;
4447659150cSPierre Ossman 				scratch = 0;
4457659150cSPierre Ossman 			}
4467659150cSPierre Ossman 		}
4471c6a0718SPierre Ossman 	}
4481c6a0718SPierre Ossman 
4497659150cSPierre Ossman 	sg_miter_stop(&host->sg_miter);
4501c6a0718SPierre Ossman 
4517659150cSPierre Ossman 	local_irq_restore(flags);
4521c6a0718SPierre Ossman }
4531c6a0718SPierre Ossman 
4541c6a0718SPierre Ossman static void sdhci_transfer_pio(struct sdhci_host *host)
4551c6a0718SPierre Ossman {
4561c6a0718SPierre Ossman 	u32 mask;
4571c6a0718SPierre Ossman 
4587659150cSPierre Ossman 	if (host->blocks == 0)
4591c6a0718SPierre Ossman 		return;
4601c6a0718SPierre Ossman 
4611c6a0718SPierre Ossman 	if (host->data->flags & MMC_DATA_READ)
4621c6a0718SPierre Ossman 		mask = SDHCI_DATA_AVAILABLE;
4631c6a0718SPierre Ossman 	else
4641c6a0718SPierre Ossman 		mask = SDHCI_SPACE_AVAILABLE;
4651c6a0718SPierre Ossman 
4664a3cba32SPierre Ossman 	/*
4674a3cba32SPierre Ossman 	 * Some controllers (JMicron JMB38x) mess up the buffer bits
4684a3cba32SPierre Ossman 	 * for transfers < 4 bytes. As long as it is just one block,
4694a3cba32SPierre Ossman 	 * we can ignore the bits.
4704a3cba32SPierre Ossman 	 */
4714a3cba32SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) &&
4724a3cba32SPierre Ossman 		(host->data->blocks == 1))
4734a3cba32SPierre Ossman 		mask = ~0;
4744a3cba32SPierre Ossman 
4754e4141a5SAnton Vorontsov 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
4763e3bf207SAnton Vorontsov 		if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
4773e3bf207SAnton Vorontsov 			udelay(100);
4783e3bf207SAnton Vorontsov 
4791c6a0718SPierre Ossman 		if (host->data->flags & MMC_DATA_READ)
4801c6a0718SPierre Ossman 			sdhci_read_block_pio(host);
4811c6a0718SPierre Ossman 		else
4821c6a0718SPierre Ossman 			sdhci_write_block_pio(host);
4831c6a0718SPierre Ossman 
4847659150cSPierre Ossman 		host->blocks--;
4857659150cSPierre Ossman 		if (host->blocks == 0)
4861c6a0718SPierre Ossman 			break;
4871c6a0718SPierre Ossman 	}
4881c6a0718SPierre Ossman 
4891c6a0718SPierre Ossman 	DBG("PIO transfer complete.\n");
4901c6a0718SPierre Ossman }
4911c6a0718SPierre Ossman 
49248857d9bSRussell King static int sdhci_pre_dma_transfer(struct sdhci_host *host,
493c0999b72SRussell King 				  struct mmc_data *data, int cookie)
49448857d9bSRussell King {
49548857d9bSRussell King 	int sg_count;
49648857d9bSRussell King 
49794538e51SRussell King 	/*
49894538e51SRussell King 	 * If the data buffers are already mapped, return the previous
49994538e51SRussell King 	 * dma_map_sg() result.
50094538e51SRussell King 	 */
50194538e51SRussell King 	if (data->host_cookie == COOKIE_PRE_MAPPED)
50248857d9bSRussell King 		return data->sg_count;
50348857d9bSRussell King 
50448857d9bSRussell King 	sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
505feeef096SHeiner Kallweit 			      mmc_get_dma_dir(data));
50648857d9bSRussell King 
50748857d9bSRussell King 	if (sg_count == 0)
50848857d9bSRussell King 		return -ENOSPC;
50948857d9bSRussell King 
51048857d9bSRussell King 	data->sg_count = sg_count;
511c0999b72SRussell King 	data->host_cookie = cookie;
51248857d9bSRussell King 
51348857d9bSRussell King 	return sg_count;
51448857d9bSRussell King }
51548857d9bSRussell King 
5162134a922SPierre Ossman static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
5172134a922SPierre Ossman {
5182134a922SPierre Ossman 	local_irq_save(*flags);
519482fce99SCong Wang 	return kmap_atomic(sg_page(sg)) + sg->offset;
5202134a922SPierre Ossman }
5212134a922SPierre Ossman 
5222134a922SPierre Ossman static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
5232134a922SPierre Ossman {
524482fce99SCong Wang 	kunmap_atomic(buffer);
5252134a922SPierre Ossman 	local_irq_restore(*flags);
5262134a922SPierre Ossman }
5272134a922SPierre Ossman 
528e57a5f61SAdrian Hunter static void sdhci_adma_write_desc(struct sdhci_host *host, void *desc,
529e57a5f61SAdrian Hunter 				  dma_addr_t addr, int len, unsigned cmd)
530118cd17dSBen Dooks {
531e57a5f61SAdrian Hunter 	struct sdhci_adma2_64_desc *dma_desc = desc;
532118cd17dSBen Dooks 
533e57a5f61SAdrian Hunter 	/* 32-bit and 64-bit descriptors have these members in same position */
5340545230fSAdrian Hunter 	dma_desc->cmd = cpu_to_le16(cmd);
5350545230fSAdrian Hunter 	dma_desc->len = cpu_to_le16(len);
536e57a5f61SAdrian Hunter 	dma_desc->addr_lo = cpu_to_le32((u32)addr);
537e57a5f61SAdrian Hunter 
538e57a5f61SAdrian Hunter 	if (host->flags & SDHCI_USE_64_BIT_DMA)
539e57a5f61SAdrian Hunter 		dma_desc->addr_hi = cpu_to_le32((u64)addr >> 32);
540118cd17dSBen Dooks }
541118cd17dSBen Dooks 
542b5ffa674SAdrian Hunter static void sdhci_adma_mark_end(void *desc)
543b5ffa674SAdrian Hunter {
544e57a5f61SAdrian Hunter 	struct sdhci_adma2_64_desc *dma_desc = desc;
545b5ffa674SAdrian Hunter 
546e57a5f61SAdrian Hunter 	/* 32-bit and 64-bit descriptors have 'cmd' in same position */
5470545230fSAdrian Hunter 	dma_desc->cmd |= cpu_to_le16(ADMA2_END);
548b5ffa674SAdrian Hunter }
549b5ffa674SAdrian Hunter 
55060c64762SRussell King static void sdhci_adma_table_pre(struct sdhci_host *host,
55160c64762SRussell King 	struct mmc_data *data, int sg_count)
5522134a922SPierre Ossman {
5532134a922SPierre Ossman 	struct scatterlist *sg;
5542134a922SPierre Ossman 	unsigned long flags;
555acc3ad13SRussell King 	dma_addr_t addr, align_addr;
556acc3ad13SRussell King 	void *desc, *align;
557acc3ad13SRussell King 	char *buffer;
558acc3ad13SRussell King 	int len, offset, i;
5592134a922SPierre Ossman 
5602134a922SPierre Ossman 	/*
5612134a922SPierre Ossman 	 * The spec does not specify endianness of descriptor table.
5622134a922SPierre Ossman 	 * We currently guess that it is LE.
5632134a922SPierre Ossman 	 */
5642134a922SPierre Ossman 
56560c64762SRussell King 	host->sg_count = sg_count;
5662134a922SPierre Ossman 
5674efaa6fbSAdrian Hunter 	desc = host->adma_table;
5682134a922SPierre Ossman 	align = host->align_buffer;
5692134a922SPierre Ossman 
5702134a922SPierre Ossman 	align_addr = host->align_addr;
5712134a922SPierre Ossman 
5722134a922SPierre Ossman 	for_each_sg(data->sg, sg, host->sg_count, i) {
5732134a922SPierre Ossman 		addr = sg_dma_address(sg);
5742134a922SPierre Ossman 		len = sg_dma_len(sg);
5752134a922SPierre Ossman 
5762134a922SPierre Ossman 		/*
577acc3ad13SRussell King 		 * The SDHCI specification states that ADMA addresses must
578acc3ad13SRussell King 		 * be 32-bit aligned. If they aren't, then we use a bounce
579acc3ad13SRussell King 		 * buffer for the (up to three) bytes that screw up the
5802134a922SPierre Ossman 		 * alignment.
5812134a922SPierre Ossman 		 */
58204a5ae6fSAdrian Hunter 		offset = (SDHCI_ADMA2_ALIGN - (addr & SDHCI_ADMA2_MASK)) &
58304a5ae6fSAdrian Hunter 			 SDHCI_ADMA2_MASK;
5842134a922SPierre Ossman 		if (offset) {
5852134a922SPierre Ossman 			if (data->flags & MMC_DATA_WRITE) {
5862134a922SPierre Ossman 				buffer = sdhci_kmap_atomic(sg, &flags);
5872134a922SPierre Ossman 				memcpy(align, buffer, offset);
5882134a922SPierre Ossman 				sdhci_kunmap_atomic(buffer, &flags);
5892134a922SPierre Ossman 			}
5902134a922SPierre Ossman 
591118cd17dSBen Dooks 			/* tran, valid */
592e57a5f61SAdrian Hunter 			sdhci_adma_write_desc(host, desc, align_addr, offset,
593739d46dcSAdrian Hunter 					      ADMA2_TRAN_VALID);
5942134a922SPierre Ossman 
5952134a922SPierre Ossman 			BUG_ON(offset > 65536);
5962134a922SPierre Ossman 
59704a5ae6fSAdrian Hunter 			align += SDHCI_ADMA2_ALIGN;
59804a5ae6fSAdrian Hunter 			align_addr += SDHCI_ADMA2_ALIGN;
5992134a922SPierre Ossman 
60076fe379aSAdrian Hunter 			desc += host->desc_sz;
6012134a922SPierre Ossman 
6022134a922SPierre Ossman 			addr += offset;
6032134a922SPierre Ossman 			len -= offset;
6042134a922SPierre Ossman 		}
6052134a922SPierre Ossman 
6062134a922SPierre Ossman 		BUG_ON(len > 65536);
6072134a922SPierre Ossman 
608347ea32dSAdrian Hunter 		if (len) {
609118cd17dSBen Dooks 			/* tran, valid */
610347ea32dSAdrian Hunter 			sdhci_adma_write_desc(host, desc, addr, len,
611347ea32dSAdrian Hunter 					      ADMA2_TRAN_VALID);
61276fe379aSAdrian Hunter 			desc += host->desc_sz;
613347ea32dSAdrian Hunter 		}
6142134a922SPierre Ossman 
6152134a922SPierre Ossman 		/*
6162134a922SPierre Ossman 		 * If this triggers then we have a calculation bug
6172134a922SPierre Ossman 		 * somewhere. :/
6182134a922SPierre Ossman 		 */
61976fe379aSAdrian Hunter 		WARN_ON((desc - host->adma_table) >= host->adma_table_sz);
6202134a922SPierre Ossman 	}
6212134a922SPierre Ossman 
62270764a90SThomas Abraham 	if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) {
623acc3ad13SRussell King 		/* Mark the last descriptor as the terminating descriptor */
6244efaa6fbSAdrian Hunter 		if (desc != host->adma_table) {
62576fe379aSAdrian Hunter 			desc -= host->desc_sz;
626b5ffa674SAdrian Hunter 			sdhci_adma_mark_end(desc);
62770764a90SThomas Abraham 		}
62870764a90SThomas Abraham 	} else {
629acc3ad13SRussell King 		/* Add a terminating entry - nop, end, valid */
630e57a5f61SAdrian Hunter 		sdhci_adma_write_desc(host, desc, 0, 0, ADMA2_NOP_END_VALID);
63170764a90SThomas Abraham 	}
6322134a922SPierre Ossman }
6332134a922SPierre Ossman 
6342134a922SPierre Ossman static void sdhci_adma_table_post(struct sdhci_host *host,
6352134a922SPierre Ossman 	struct mmc_data *data)
6362134a922SPierre Ossman {
6372134a922SPierre Ossman 	struct scatterlist *sg;
6382134a922SPierre Ossman 	int i, size;
6391c3d5f6dSAdrian Hunter 	void *align;
6402134a922SPierre Ossman 	char *buffer;
6412134a922SPierre Ossman 	unsigned long flags;
6422134a922SPierre Ossman 
64347fa9613SRussell King 	if (data->flags & MMC_DATA_READ) {
64447fa9613SRussell King 		bool has_unaligned = false;
64547fa9613SRussell King 
646de0b65a7SRussell King 		/* Do a quick scan of the SG list for any unaligned mappings */
647de0b65a7SRussell King 		for_each_sg(data->sg, sg, host->sg_count, i)
64804a5ae6fSAdrian Hunter 			if (sg_dma_address(sg) & SDHCI_ADMA2_MASK) {
649de0b65a7SRussell King 				has_unaligned = true;
650de0b65a7SRussell King 				break;
651de0b65a7SRussell King 			}
652de0b65a7SRussell King 
65347fa9613SRussell King 		if (has_unaligned) {
6542134a922SPierre Ossman 			dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
655f55c98f7SRussell King 					    data->sg_len, DMA_FROM_DEVICE);
6562134a922SPierre Ossman 
6572134a922SPierre Ossman 			align = host->align_buffer;
6582134a922SPierre Ossman 
6592134a922SPierre Ossman 			for_each_sg(data->sg, sg, host->sg_count, i) {
66004a5ae6fSAdrian Hunter 				if (sg_dma_address(sg) & SDHCI_ADMA2_MASK) {
66104a5ae6fSAdrian Hunter 					size = SDHCI_ADMA2_ALIGN -
66204a5ae6fSAdrian Hunter 					       (sg_dma_address(sg) & SDHCI_ADMA2_MASK);
6632134a922SPierre Ossman 
6642134a922SPierre Ossman 					buffer = sdhci_kmap_atomic(sg, &flags);
6652134a922SPierre Ossman 					memcpy(buffer, align, size);
6662134a922SPierre Ossman 					sdhci_kunmap_atomic(buffer, &flags);
6672134a922SPierre Ossman 
66804a5ae6fSAdrian Hunter 					align += SDHCI_ADMA2_ALIGN;
6692134a922SPierre Ossman 				}
6702134a922SPierre Ossman 			}
6712134a922SPierre Ossman 		}
67247fa9613SRussell King 	}
6732134a922SPierre Ossman }
6742134a922SPierre Ossman 
675a3c7778fSAndrei Warkentin static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
6761c6a0718SPierre Ossman {
6771c6a0718SPierre Ossman 	u8 count;
678a3c7778fSAndrei Warkentin 	struct mmc_data *data = cmd->data;
6791c6a0718SPierre Ossman 	unsigned target_timeout, current_timeout;
6801c6a0718SPierre Ossman 
681ee53ab5dSPierre Ossman 	/*
682ee53ab5dSPierre Ossman 	 * If the host controller provides us with an incorrect timeout
683ee53ab5dSPierre Ossman 	 * value, just skip the check and use 0xE.  The hardware may take
684ee53ab5dSPierre Ossman 	 * longer to time out, but that's much better than having a too-short
685ee53ab5dSPierre Ossman 	 * timeout value.
686ee53ab5dSPierre Ossman 	 */
68711a2f1b7SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
688ee53ab5dSPierre Ossman 		return 0xE;
689e538fbe8SPierre Ossman 
690a3c7778fSAndrei Warkentin 	/* Unspecified timeout, assume max */
6911d4d7744SUlf Hansson 	if (!data && !cmd->busy_timeout)
692a3c7778fSAndrei Warkentin 		return 0xE;
693a3c7778fSAndrei Warkentin 
6941c6a0718SPierre Ossman 	/* timeout in us */
695a3c7778fSAndrei Warkentin 	if (!data)
6961d4d7744SUlf Hansson 		target_timeout = cmd->busy_timeout * 1000;
69778a2ca27SAndy Shevchenko 	else {
698fafcfda9SRussell King 		target_timeout = DIV_ROUND_UP(data->timeout_ns, 1000);
6997f05538aSRussell King 		if (host->clock && data->timeout_clks) {
7007f05538aSRussell King 			unsigned long long val;
7017f05538aSRussell King 
7027f05538aSRussell King 			/*
7037f05538aSRussell King 			 * data->timeout_clks is in units of clock cycles.
7047f05538aSRussell King 			 * host->clock is in Hz.  target_timeout is in us.
7057f05538aSRussell King 			 * Hence, us = 1000000 * cycles / Hz.  Round up.
7067f05538aSRussell King 			 */
70702265cd6SHaibo Chen 			val = 1000000ULL * data->timeout_clks;
7087f05538aSRussell King 			if (do_div(val, host->clock))
7097f05538aSRussell King 				target_timeout++;
7107f05538aSRussell King 			target_timeout += val;
7117f05538aSRussell King 		}
71278a2ca27SAndy Shevchenko 	}
7131c6a0718SPierre Ossman 
7141c6a0718SPierre Ossman 	/*
7151c6a0718SPierre Ossman 	 * Figure out needed cycles.
7161c6a0718SPierre Ossman 	 * We do this in steps in order to fit inside a 32 bit int.
7171c6a0718SPierre Ossman 	 * The first step is the minimum timeout, which will have a
7181c6a0718SPierre Ossman 	 * minimum resolution of 6 bits:
7191c6a0718SPierre Ossman 	 * (1) 2^13*1000 > 2^22,
7201c6a0718SPierre Ossman 	 * (2) host->timeout_clk < 2^16
7211c6a0718SPierre Ossman 	 *     =>
7221c6a0718SPierre Ossman 	 *     (1) / (2) > 2^6
7231c6a0718SPierre Ossman 	 */
7241c6a0718SPierre Ossman 	count = 0;
7251c6a0718SPierre Ossman 	current_timeout = (1 << 13) * 1000 / host->timeout_clk;
7261c6a0718SPierre Ossman 	while (current_timeout < target_timeout) {
7271c6a0718SPierre Ossman 		count++;
7281c6a0718SPierre Ossman 		current_timeout <<= 1;
7291c6a0718SPierre Ossman 		if (count >= 0xF)
7301c6a0718SPierre Ossman 			break;
7311c6a0718SPierre Ossman 	}
7321c6a0718SPierre Ossman 
7331c6a0718SPierre Ossman 	if (count >= 0xF) {
734f421865dSAdrian Hunter 		DBG("Too large timeout 0x%x requested for CMD%d!\n",
735f421865dSAdrian Hunter 		    count, cmd->opcode);
7361c6a0718SPierre Ossman 		count = 0xE;
7371c6a0718SPierre Ossman 	}
7381c6a0718SPierre Ossman 
739ee53ab5dSPierre Ossman 	return count;
740ee53ab5dSPierre Ossman }
741ee53ab5dSPierre Ossman 
7426aa943abSAnton Vorontsov static void sdhci_set_transfer_irqs(struct sdhci_host *host)
7436aa943abSAnton Vorontsov {
7446aa943abSAnton Vorontsov 	u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
7456aa943abSAnton Vorontsov 	u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
7466aa943abSAnton Vorontsov 
7476aa943abSAnton Vorontsov 	if (host->flags & SDHCI_REQ_USE_DMA)
748b537f94cSRussell King 		host->ier = (host->ier & ~pio_irqs) | dma_irqs;
7496aa943abSAnton Vorontsov 	else
750b537f94cSRussell King 		host->ier = (host->ier & ~dma_irqs) | pio_irqs;
751b537f94cSRussell King 
752b537f94cSRussell King 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
753b537f94cSRussell King 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
7546aa943abSAnton Vorontsov }
7556aa943abSAnton Vorontsov 
756b45e668aSAisheng Dong static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
757ee53ab5dSPierre Ossman {
758ee53ab5dSPierre Ossman 	u8 count;
759b45e668aSAisheng Dong 
760b45e668aSAisheng Dong 	if (host->ops->set_timeout) {
761b45e668aSAisheng Dong 		host->ops->set_timeout(host, cmd);
762b45e668aSAisheng Dong 	} else {
763b45e668aSAisheng Dong 		count = sdhci_calc_timeout(host, cmd);
764b45e668aSAisheng Dong 		sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
765b45e668aSAisheng Dong 	}
766b45e668aSAisheng Dong }
767b45e668aSAisheng Dong 
768b45e668aSAisheng Dong static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
769b45e668aSAisheng Dong {
7702134a922SPierre Ossman 	u8 ctrl;
771a3c7778fSAndrei Warkentin 	struct mmc_data *data = cmd->data;
772ee53ab5dSPierre Ossman 
77356a590dcSAdrian Hunter 	if (sdhci_data_line_cmd(cmd))
774b45e668aSAisheng Dong 		sdhci_set_timeout(host, cmd);
775a3c7778fSAndrei Warkentin 
776a3c7778fSAndrei Warkentin 	if (!data)
777ee53ab5dSPierre Ossman 		return;
778ee53ab5dSPierre Ossman 
77943dea098SAdrian Hunter 	WARN_ON(host->data);
78043dea098SAdrian Hunter 
781ee53ab5dSPierre Ossman 	/* Sanity checks */
782ee53ab5dSPierre Ossman 	BUG_ON(data->blksz * data->blocks > 524288);
783ee53ab5dSPierre Ossman 	BUG_ON(data->blksz > host->mmc->max_blk_size);
784ee53ab5dSPierre Ossman 	BUG_ON(data->blocks > 65535);
785ee53ab5dSPierre Ossman 
786ee53ab5dSPierre Ossman 	host->data = data;
787ee53ab5dSPierre Ossman 	host->data_early = 0;
788f6a03cbfSMikko Vinni 	host->data->bytes_xfered = 0;
789ee53ab5dSPierre Ossman 
790fce14421SRussell King 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
791fce14421SRussell King 		struct scatterlist *sg;
792fce14421SRussell King 		unsigned int length_mask, offset_mask;
793fce14421SRussell King 		int i;
794fce14421SRussell King 
795c9fddbc4SPierre Ossman 		host->flags |= SDHCI_REQ_USE_DMA;
796c9fddbc4SPierre Ossman 
7972134a922SPierre Ossman 		/*
7982134a922SPierre Ossman 		 * FIXME: This doesn't account for merging when mapping the
7992134a922SPierre Ossman 		 * scatterlist.
800df953925SRussell King 		 *
801df953925SRussell King 		 * The assumption here being that alignment and lengths are
802df953925SRussell King 		 * the same after DMA mapping to device address space.
8032134a922SPierre Ossman 		 */
804a0eaf0f9SRussell King 		length_mask = 0;
805df953925SRussell King 		offset_mask = 0;
8062134a922SPierre Ossman 		if (host->flags & SDHCI_USE_ADMA) {
807df953925SRussell King 			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE) {
808a0eaf0f9SRussell King 				length_mask = 3;
809df953925SRussell King 				/*
810df953925SRussell King 				 * As we use up to 3 byte chunks to work
811df953925SRussell King 				 * around alignment problems, we need to
812df953925SRussell King 				 * check the offset as well.
813df953925SRussell King 				 */
814df953925SRussell King 				offset_mask = 3;
815df953925SRussell King 			}
8162134a922SPierre Ossman 		} else {
8172134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE)
818a0eaf0f9SRussell King 				length_mask = 3;
819df953925SRussell King 			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR)
820df953925SRussell King 				offset_mask = 3;
8212134a922SPierre Ossman 		}
8222134a922SPierre Ossman 
823df953925SRussell King 		if (unlikely(length_mask | offset_mask)) {
8242134a922SPierre Ossman 			for_each_sg(data->sg, sg, data->sg_len, i) {
825a0eaf0f9SRussell King 				if (sg->length & length_mask) {
8262e4456f0SMarek Vasut 					DBG("Reverting to PIO because of transfer size (%d)\n",
8272134a922SPierre Ossman 					    sg->length);
828c9fddbc4SPierre Ossman 					host->flags &= ~SDHCI_REQ_USE_DMA;
8292134a922SPierre Ossman 					break;
8302134a922SPierre Ossman 				}
831a0eaf0f9SRussell King 				if (sg->offset & offset_mask) {
8322e4456f0SMarek Vasut 					DBG("Reverting to PIO because of bad alignment\n");
833c9fddbc4SPierre Ossman 					host->flags &= ~SDHCI_REQ_USE_DMA;
8342134a922SPierre Ossman 					break;
8352134a922SPierre Ossman 				}
8362134a922SPierre Ossman 			}
8372134a922SPierre Ossman 		}
8382134a922SPierre Ossman 	}
8392134a922SPierre Ossman 
8408f1934ceSPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
841c0999b72SRussell King 		int sg_cnt = sdhci_pre_dma_transfer(host, data, COOKIE_MAPPED);
8428f1934ceSPierre Ossman 
84362a7f368SJiri Slaby 		if (sg_cnt <= 0) {
8448f1934ceSPierre Ossman 			/*
8458f1934ceSPierre Ossman 			 * This only happens when someone fed
8468f1934ceSPierre Ossman 			 * us an invalid request.
8478f1934ceSPierre Ossman 			 */
8488f1934ceSPierre Ossman 			WARN_ON(1);
849ebd6d357SPierre Ossman 			host->flags &= ~SDHCI_REQ_USE_DMA;
85060c64762SRussell King 		} else if (host->flags & SDHCI_USE_ADMA) {
85160c64762SRussell King 			sdhci_adma_table_pre(host, data, sg_cnt);
85260c64762SRussell King 
85360c64762SRussell King 			sdhci_writel(host, host->adma_addr, SDHCI_ADMA_ADDRESS);
85460c64762SRussell King 			if (host->flags & SDHCI_USE_64_BIT_DMA)
85560c64762SRussell King 				sdhci_writel(host,
85660c64762SRussell King 					     (u64)host->adma_addr >> 32,
85760c64762SRussell King 					     SDHCI_ADMA_ADDRESS_HI);
8588f1934ceSPierre Ossman 		} else {
859719a61b4SPierre Ossman 			WARN_ON(sg_cnt != 1);
8604e4141a5SAnton Vorontsov 			sdhci_writel(host, sg_dma_address(data->sg),
8614e4141a5SAnton Vorontsov 				SDHCI_DMA_ADDRESS);
8628f1934ceSPierre Ossman 		}
8638f1934ceSPierre Ossman 	}
8648f1934ceSPierre Ossman 
8652134a922SPierre Ossman 	/*
8662134a922SPierre Ossman 	 * Always adjust the DMA selection as some controllers
8672134a922SPierre Ossman 	 * (e.g. JMicron) can't do PIO properly when the selection
8682134a922SPierre Ossman 	 * is ADMA.
8692134a922SPierre Ossman 	 */
8702134a922SPierre Ossman 	if (host->version >= SDHCI_SPEC_200) {
8714e4141a5SAnton Vorontsov 		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
8722134a922SPierre Ossman 		ctrl &= ~SDHCI_CTRL_DMA_MASK;
8732134a922SPierre Ossman 		if ((host->flags & SDHCI_REQ_USE_DMA) &&
874e57a5f61SAdrian Hunter 			(host->flags & SDHCI_USE_ADMA)) {
875e57a5f61SAdrian Hunter 			if (host->flags & SDHCI_USE_64_BIT_DMA)
876e57a5f61SAdrian Hunter 				ctrl |= SDHCI_CTRL_ADMA64;
8772134a922SPierre Ossman 			else
878e57a5f61SAdrian Hunter 				ctrl |= SDHCI_CTRL_ADMA32;
879e57a5f61SAdrian Hunter 		} else {
8802134a922SPierre Ossman 			ctrl |= SDHCI_CTRL_SDMA;
881e57a5f61SAdrian Hunter 		}
8824e4141a5SAnton Vorontsov 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
883c9fddbc4SPierre Ossman 	}
884c9fddbc4SPierre Ossman 
8858f1934ceSPierre Ossman 	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
886da60a91dSSebastian Andrzej Siewior 		int flags;
887da60a91dSSebastian Andrzej Siewior 
888da60a91dSSebastian Andrzej Siewior 		flags = SG_MITER_ATOMIC;
889da60a91dSSebastian Andrzej Siewior 		if (host->data->flags & MMC_DATA_READ)
890da60a91dSSebastian Andrzej Siewior 			flags |= SG_MITER_TO_SG;
891da60a91dSSebastian Andrzej Siewior 		else
892da60a91dSSebastian Andrzej Siewior 			flags |= SG_MITER_FROM_SG;
893da60a91dSSebastian Andrzej Siewior 		sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
8947659150cSPierre Ossman 		host->blocks = data->blocks;
8951c6a0718SPierre Ossman 	}
8961c6a0718SPierre Ossman 
8976aa943abSAnton Vorontsov 	sdhci_set_transfer_irqs(host);
8986aa943abSAnton Vorontsov 
899f6a03cbfSMikko Vinni 	/* Set the DMA boundary value and block size */
900c846a00fSSrinivas Kandagatla 	sdhci_writew(host, SDHCI_MAKE_BLKSZ(host->sdma_boundary, data->blksz),
901c846a00fSSrinivas Kandagatla 		     SDHCI_BLOCK_SIZE);
9024e4141a5SAnton Vorontsov 	sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
9031c6a0718SPierre Ossman }
9041c6a0718SPierre Ossman 
9050293d501SAdrian Hunter static inline bool sdhci_auto_cmd12(struct sdhci_host *host,
9060293d501SAdrian Hunter 				    struct mmc_request *mrq)
9070293d501SAdrian Hunter {
90820845befSAdrian Hunter 	return !mrq->sbc && (host->flags & SDHCI_AUTO_CMD12) &&
90920845befSAdrian Hunter 	       !mrq->cap_cmd_during_tfr;
9100293d501SAdrian Hunter }
9110293d501SAdrian Hunter 
9121c6a0718SPierre Ossman static void sdhci_set_transfer_mode(struct sdhci_host *host,
913e89d456fSAndrei Warkentin 	struct mmc_command *cmd)
9141c6a0718SPierre Ossman {
915d3fc5d71SVincent Yang 	u16 mode = 0;
916e89d456fSAndrei Warkentin 	struct mmc_data *data = cmd->data;
9171c6a0718SPierre Ossman 
9182b558c13SDong Aisheng 	if (data == NULL) {
9199b8ffea6SVincent Wan 		if (host->quirks2 &
9209b8ffea6SVincent Wan 			SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD) {
9219b8ffea6SVincent Wan 			sdhci_writew(host, 0x0, SDHCI_TRANSFER_MODE);
9229b8ffea6SVincent Wan 		} else {
9232b558c13SDong Aisheng 		/* clear Auto CMD settings for no data CMDs */
9242b558c13SDong Aisheng 			mode = sdhci_readw(host, SDHCI_TRANSFER_MODE);
9252b558c13SDong Aisheng 			sdhci_writew(host, mode & ~(SDHCI_TRNS_AUTO_CMD12 |
9262b558c13SDong Aisheng 				SDHCI_TRNS_AUTO_CMD23), SDHCI_TRANSFER_MODE);
9279b8ffea6SVincent Wan 		}
9281c6a0718SPierre Ossman 		return;
9292b558c13SDong Aisheng 	}
9301c6a0718SPierre Ossman 
931e538fbe8SPierre Ossman 	WARN_ON(!host->data);
932e538fbe8SPierre Ossman 
933d3fc5d71SVincent Yang 	if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE))
9341c6a0718SPierre Ossman 		mode = SDHCI_TRNS_BLK_CNT_EN;
935d3fc5d71SVincent Yang 
936e89d456fSAndrei Warkentin 	if (mmc_op_multi(cmd->opcode) || data->blocks > 1) {
937d3fc5d71SVincent Yang 		mode = SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_MULTI;
938e89d456fSAndrei Warkentin 		/*
939e89d456fSAndrei Warkentin 		 * If we are sending CMD23, CMD12 never gets sent
940e89d456fSAndrei Warkentin 		 * on successful completion (so no Auto-CMD12).
941e89d456fSAndrei Warkentin 		 */
9420293d501SAdrian Hunter 		if (sdhci_auto_cmd12(host, cmd->mrq) &&
94385cc1c33SCorneliu Doban 		    (cmd->opcode != SD_IO_RW_EXTENDED))
944e89d456fSAndrei Warkentin 			mode |= SDHCI_TRNS_AUTO_CMD12;
945a4c73abaSAdrian Hunter 		else if (cmd->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) {
9468edf6371SAndrei Warkentin 			mode |= SDHCI_TRNS_AUTO_CMD23;
947a4c73abaSAdrian Hunter 			sdhci_writel(host, cmd->mrq->sbc->arg, SDHCI_ARGUMENT2);
948c4512f79SJerry Huang 		}
9498edf6371SAndrei Warkentin 	}
9508edf6371SAndrei Warkentin 
9511c6a0718SPierre Ossman 	if (data->flags & MMC_DATA_READ)
9521c6a0718SPierre Ossman 		mode |= SDHCI_TRNS_READ;
953c9fddbc4SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA)
9541c6a0718SPierre Ossman 		mode |= SDHCI_TRNS_DMA;
9551c6a0718SPierre Ossman 
9564e4141a5SAnton Vorontsov 	sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
9571c6a0718SPierre Ossman }
9581c6a0718SPierre Ossman 
9590cc563ceSAdrian Hunter static bool sdhci_needs_reset(struct sdhci_host *host, struct mmc_request *mrq)
9600cc563ceSAdrian Hunter {
9610cc563ceSAdrian Hunter 	return (!(host->flags & SDHCI_DEVICE_DEAD) &&
9620cc563ceSAdrian Hunter 		((mrq->cmd && mrq->cmd->error) ||
9630cc563ceSAdrian Hunter 		 (mrq->sbc && mrq->sbc->error) ||
9640cc563ceSAdrian Hunter 		 (mrq->data && ((mrq->data->error && !mrq->data->stop) ||
9650cc563ceSAdrian Hunter 				(mrq->data->stop && mrq->data->stop->error))) ||
9660cc563ceSAdrian Hunter 		 (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)));
9670cc563ceSAdrian Hunter }
9680cc563ceSAdrian Hunter 
9694e9f8fe5SAdrian Hunter static void __sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq)
9704e9f8fe5SAdrian Hunter {
9714e9f8fe5SAdrian Hunter 	int i;
9724e9f8fe5SAdrian Hunter 
9734e9f8fe5SAdrian Hunter 	for (i = 0; i < SDHCI_MAX_MRQS; i++) {
9744e9f8fe5SAdrian Hunter 		if (host->mrqs_done[i] == mrq) {
9754e9f8fe5SAdrian Hunter 			WARN_ON(1);
9764e9f8fe5SAdrian Hunter 			return;
9774e9f8fe5SAdrian Hunter 		}
9784e9f8fe5SAdrian Hunter 	}
9794e9f8fe5SAdrian Hunter 
9804e9f8fe5SAdrian Hunter 	for (i = 0; i < SDHCI_MAX_MRQS; i++) {
9814e9f8fe5SAdrian Hunter 		if (!host->mrqs_done[i]) {
9824e9f8fe5SAdrian Hunter 			host->mrqs_done[i] = mrq;
9834e9f8fe5SAdrian Hunter 			break;
9844e9f8fe5SAdrian Hunter 		}
9854e9f8fe5SAdrian Hunter 	}
9864e9f8fe5SAdrian Hunter 
9874e9f8fe5SAdrian Hunter 	WARN_ON(i >= SDHCI_MAX_MRQS);
9884e9f8fe5SAdrian Hunter 
9894e9f8fe5SAdrian Hunter 	tasklet_schedule(&host->finish_tasklet);
9904e9f8fe5SAdrian Hunter }
9914e9f8fe5SAdrian Hunter 
992a6d3bdd5SAdrian Hunter static void sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq)
993a6d3bdd5SAdrian Hunter {
9945a8a3fefSAdrian Hunter 	if (host->cmd && host->cmd->mrq == mrq)
9955a8a3fefSAdrian Hunter 		host->cmd = NULL;
9965a8a3fefSAdrian Hunter 
9975a8a3fefSAdrian Hunter 	if (host->data_cmd && host->data_cmd->mrq == mrq)
9985a8a3fefSAdrian Hunter 		host->data_cmd = NULL;
9995a8a3fefSAdrian Hunter 
10005a8a3fefSAdrian Hunter 	if (host->data && host->data->mrq == mrq)
10015a8a3fefSAdrian Hunter 		host->data = NULL;
10025a8a3fefSAdrian Hunter 
1003ed1563deSAdrian Hunter 	if (sdhci_needs_reset(host, mrq))
1004ed1563deSAdrian Hunter 		host->pending_reset = true;
1005ed1563deSAdrian Hunter 
10064e9f8fe5SAdrian Hunter 	__sdhci_finish_mrq(host, mrq);
1007a6d3bdd5SAdrian Hunter }
1008a6d3bdd5SAdrian Hunter 
10091c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *host)
10101c6a0718SPierre Ossman {
101133a57adbSAdrian Hunter 	struct mmc_command *data_cmd = host->data_cmd;
101233a57adbSAdrian Hunter 	struct mmc_data *data = host->data;
10131c6a0718SPierre Ossman 
10141c6a0718SPierre Ossman 	host->data = NULL;
10157c89a3d9SAdrian Hunter 	host->data_cmd = NULL;
10161c6a0718SPierre Ossman 
1017add8913dSRussell King 	if ((host->flags & (SDHCI_REQ_USE_DMA | SDHCI_USE_ADMA)) ==
1018add8913dSRussell King 	    (SDHCI_REQ_USE_DMA | SDHCI_USE_ADMA))
10192134a922SPierre Ossman 		sdhci_adma_table_post(host, data);
1020f55c98f7SRussell King 
10211c6a0718SPierre Ossman 	/*
1022c9b74c5bSPierre Ossman 	 * The specification states that the block count register must
1023c9b74c5bSPierre Ossman 	 * be updated, but it does not specify at what point in the
1024c9b74c5bSPierre Ossman 	 * data flow. That makes the register entirely useless to read
1025c9b74c5bSPierre Ossman 	 * back so we have to assume that nothing made it to the card
1026c9b74c5bSPierre Ossman 	 * in the event of an error.
10271c6a0718SPierre Ossman 	 */
1028c9b74c5bSPierre Ossman 	if (data->error)
1029c9b74c5bSPierre Ossman 		data->bytes_xfered = 0;
10301c6a0718SPierre Ossman 	else
1031c9b74c5bSPierre Ossman 		data->bytes_xfered = data->blksz * data->blocks;
10321c6a0718SPierre Ossman 
1033e89d456fSAndrei Warkentin 	/*
1034e89d456fSAndrei Warkentin 	 * Need to send CMD12 if -
1035e89d456fSAndrei Warkentin 	 * a) open-ended multiblock transfer (no CMD23)
1036e89d456fSAndrei Warkentin 	 * b) error in multiblock transfer
1037e89d456fSAndrei Warkentin 	 */
1038e89d456fSAndrei Warkentin 	if (data->stop &&
1039e89d456fSAndrei Warkentin 	    (data->error ||
1040a4c73abaSAdrian Hunter 	     !data->mrq->sbc)) {
1041e89d456fSAndrei Warkentin 
10421c6a0718SPierre Ossman 		/*
10431c6a0718SPierre Ossman 		 * The controller needs a reset of internal state machines
10441c6a0718SPierre Ossman 		 * upon error conditions.
10451c6a0718SPierre Ossman 		 */
104617b0429dSPierre Ossman 		if (data->error) {
104733a57adbSAdrian Hunter 			if (!host->cmd || host->cmd == data_cmd)
104803231f9bSRussell King 				sdhci_do_reset(host, SDHCI_RESET_CMD);
104903231f9bSRussell King 			sdhci_do_reset(host, SDHCI_RESET_DATA);
10501c6a0718SPierre Ossman 		}
10511c6a0718SPierre Ossman 
105220845befSAdrian Hunter 		/*
105320845befSAdrian Hunter 		 * 'cap_cmd_during_tfr' request must not use the command line
105420845befSAdrian Hunter 		 * after mmc_command_done() has been called. It is upper layer's
105520845befSAdrian Hunter 		 * responsibility to send the stop command if required.
105620845befSAdrian Hunter 		 */
105720845befSAdrian Hunter 		if (data->mrq->cap_cmd_during_tfr) {
105820845befSAdrian Hunter 			sdhci_finish_mrq(host, data->mrq);
105920845befSAdrian Hunter 		} else {
10608842fd17SAdrian Hunter 			/* Avoid triggering warning in sdhci_send_command() */
10618842fd17SAdrian Hunter 			host->cmd = NULL;
10621c6a0718SPierre Ossman 			sdhci_send_command(host, data->stop);
106320845befSAdrian Hunter 		}
1064a6d3bdd5SAdrian Hunter 	} else {
1065a6d3bdd5SAdrian Hunter 		sdhci_finish_mrq(host, data->mrq);
1066a6d3bdd5SAdrian Hunter 	}
10671c6a0718SPierre Ossman }
10681c6a0718SPierre Ossman 
1069d7422fb4SAdrian Hunter static void sdhci_mod_timer(struct sdhci_host *host, struct mmc_request *mrq,
1070d7422fb4SAdrian Hunter 			    unsigned long timeout)
1071d7422fb4SAdrian Hunter {
1072d7422fb4SAdrian Hunter 	if (sdhci_data_line_cmd(mrq->cmd))
1073d7422fb4SAdrian Hunter 		mod_timer(&host->data_timer, timeout);
1074d7422fb4SAdrian Hunter 	else
1075d7422fb4SAdrian Hunter 		mod_timer(&host->timer, timeout);
1076d7422fb4SAdrian Hunter }
1077d7422fb4SAdrian Hunter 
1078d7422fb4SAdrian Hunter static void sdhci_del_timer(struct sdhci_host *host, struct mmc_request *mrq)
1079d7422fb4SAdrian Hunter {
1080d7422fb4SAdrian Hunter 	if (sdhci_data_line_cmd(mrq->cmd))
1081d7422fb4SAdrian Hunter 		del_timer(&host->data_timer);
1082d7422fb4SAdrian Hunter 	else
1083d7422fb4SAdrian Hunter 		del_timer(&host->timer);
1084d7422fb4SAdrian Hunter }
1085d7422fb4SAdrian Hunter 
1086c0e55129SDong Aisheng void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
10871c6a0718SPierre Ossman {
10881c6a0718SPierre Ossman 	int flags;
10891c6a0718SPierre Ossman 	u32 mask;
10901c6a0718SPierre Ossman 	unsigned long timeout;
10911c6a0718SPierre Ossman 
10921c6a0718SPierre Ossman 	WARN_ON(host->cmd);
10931c6a0718SPierre Ossman 
109496776200SRussell King 	/* Initially, a command has no error */
109596776200SRussell King 	cmd->error = 0;
109696776200SRussell King 
1097fc605f1dSAdrian Hunter 	if ((host->quirks2 & SDHCI_QUIRK2_STOP_WITH_TC) &&
1098fc605f1dSAdrian Hunter 	    cmd->opcode == MMC_STOP_TRANSMISSION)
1099fc605f1dSAdrian Hunter 		cmd->flags |= MMC_RSP_BUSY;
1100fc605f1dSAdrian Hunter 
11011c6a0718SPierre Ossman 	/* Wait max 10 ms */
11021c6a0718SPierre Ossman 	timeout = 10;
11031c6a0718SPierre Ossman 
11041c6a0718SPierre Ossman 	mask = SDHCI_CMD_INHIBIT;
110556a590dcSAdrian Hunter 	if (sdhci_data_line_cmd(cmd))
11061c6a0718SPierre Ossman 		mask |= SDHCI_DATA_INHIBIT;
11071c6a0718SPierre Ossman 
11081c6a0718SPierre Ossman 	/* We shouldn't wait for data inihibit for stop commands, even
11091c6a0718SPierre Ossman 	   though they might use busy signaling */
1110a4c73abaSAdrian Hunter 	if (cmd->mrq->data && (cmd == cmd->mrq->data->stop))
11111c6a0718SPierre Ossman 		mask &= ~SDHCI_DATA_INHIBIT;
11121c6a0718SPierre Ossman 
11134e4141a5SAnton Vorontsov 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
11141c6a0718SPierre Ossman 		if (timeout == 0) {
11152e4456f0SMarek Vasut 			pr_err("%s: Controller never released inhibit bit(s).\n",
11162e4456f0SMarek Vasut 			       mmc_hostname(host->mmc));
11171c6a0718SPierre Ossman 			sdhci_dumpregs(host);
111817b0429dSPierre Ossman 			cmd->error = -EIO;
1119a6d3bdd5SAdrian Hunter 			sdhci_finish_mrq(host, cmd->mrq);
11201c6a0718SPierre Ossman 			return;
11211c6a0718SPierre Ossman 		}
11221c6a0718SPierre Ossman 		timeout--;
11231c6a0718SPierre Ossman 		mdelay(1);
11241c6a0718SPierre Ossman 	}
11251c6a0718SPierre Ossman 
11263e1a6892SAdrian Hunter 	timeout = jiffies;
11271d4d7744SUlf Hansson 	if (!cmd->data && cmd->busy_timeout > 9000)
11281d4d7744SUlf Hansson 		timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ;
11293e1a6892SAdrian Hunter 	else
11303e1a6892SAdrian Hunter 		timeout += 10 * HZ;
1131d7422fb4SAdrian Hunter 	sdhci_mod_timer(host, cmd->mrq, timeout);
11321c6a0718SPierre Ossman 
11331c6a0718SPierre Ossman 	host->cmd = cmd;
113456a590dcSAdrian Hunter 	if (sdhci_data_line_cmd(cmd)) {
11357c89a3d9SAdrian Hunter 		WARN_ON(host->data_cmd);
11367c89a3d9SAdrian Hunter 		host->data_cmd = cmd;
11377c89a3d9SAdrian Hunter 	}
11381c6a0718SPierre Ossman 
1139a3c7778fSAndrei Warkentin 	sdhci_prepare_data(host, cmd);
11401c6a0718SPierre Ossman 
11414e4141a5SAnton Vorontsov 	sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
11421c6a0718SPierre Ossman 
1143e89d456fSAndrei Warkentin 	sdhci_set_transfer_mode(host, cmd);
11441c6a0718SPierre Ossman 
11451c6a0718SPierre Ossman 	if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
1146a3c76eb9SGirish K S 		pr_err("%s: Unsupported response type!\n",
11471c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
114817b0429dSPierre Ossman 		cmd->error = -EINVAL;
1149a6d3bdd5SAdrian Hunter 		sdhci_finish_mrq(host, cmd->mrq);
11501c6a0718SPierre Ossman 		return;
11511c6a0718SPierre Ossman 	}
11521c6a0718SPierre Ossman 
11531c6a0718SPierre Ossman 	if (!(cmd->flags & MMC_RSP_PRESENT))
11541c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_NONE;
11551c6a0718SPierre Ossman 	else if (cmd->flags & MMC_RSP_136)
11561c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_LONG;
11571c6a0718SPierre Ossman 	else if (cmd->flags & MMC_RSP_BUSY)
11581c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_SHORT_BUSY;
11591c6a0718SPierre Ossman 	else
11601c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_SHORT;
11611c6a0718SPierre Ossman 
11621c6a0718SPierre Ossman 	if (cmd->flags & MMC_RSP_CRC)
11631c6a0718SPierre Ossman 		flags |= SDHCI_CMD_CRC;
11641c6a0718SPierre Ossman 	if (cmd->flags & MMC_RSP_OPCODE)
11651c6a0718SPierre Ossman 		flags |= SDHCI_CMD_INDEX;
1166b513ea25SArindam Nath 
1167b513ea25SArindam Nath 	/* CMD19 is special in that the Data Present Select should be set */
1168069c9f14SGirish K S 	if (cmd->data || cmd->opcode == MMC_SEND_TUNING_BLOCK ||
1169069c9f14SGirish K S 	    cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200)
11701c6a0718SPierre Ossman 		flags |= SDHCI_CMD_DATA;
11711c6a0718SPierre Ossman 
11724e4141a5SAnton Vorontsov 	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
11731c6a0718SPierre Ossman }
1174c0e55129SDong Aisheng EXPORT_SYMBOL_GPL(sdhci_send_command);
11751c6a0718SPierre Ossman 
11764a5fc119SAdrian Hunter static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
11774a5fc119SAdrian Hunter {
11784a5fc119SAdrian Hunter 	int i, reg;
11794a5fc119SAdrian Hunter 
11804a5fc119SAdrian Hunter 	for (i = 0; i < 4; i++) {
11814a5fc119SAdrian Hunter 		reg = SDHCI_RESPONSE + (3 - i) * 4;
11824a5fc119SAdrian Hunter 		cmd->resp[i] = sdhci_readl(host, reg);
11834a5fc119SAdrian Hunter 	}
11844a5fc119SAdrian Hunter 
11851284c248SKishon Vijay Abraham I 	if (host->quirks2 & SDHCI_QUIRK2_RSP_136_HAS_CRC)
11861284c248SKishon Vijay Abraham I 		return;
11871284c248SKishon Vijay Abraham I 
11884a5fc119SAdrian Hunter 	/* CRC is stripped so we need to do some shifting */
11894a5fc119SAdrian Hunter 	for (i = 0; i < 4; i++) {
11904a5fc119SAdrian Hunter 		cmd->resp[i] <<= 8;
11914a5fc119SAdrian Hunter 		if (i != 3)
11924a5fc119SAdrian Hunter 			cmd->resp[i] |= cmd->resp[i + 1] >> 24;
11934a5fc119SAdrian Hunter 	}
11944a5fc119SAdrian Hunter }
11954a5fc119SAdrian Hunter 
11961c6a0718SPierre Ossman static void sdhci_finish_command(struct sdhci_host *host)
11971c6a0718SPierre Ossman {
1198e0a5640aSAdrian Hunter 	struct mmc_command *cmd = host->cmd;
11991c6a0718SPierre Ossman 
1200e0a5640aSAdrian Hunter 	host->cmd = NULL;
1201e0a5640aSAdrian Hunter 
1202e0a5640aSAdrian Hunter 	if (cmd->flags & MMC_RSP_PRESENT) {
1203e0a5640aSAdrian Hunter 		if (cmd->flags & MMC_RSP_136) {
12044a5fc119SAdrian Hunter 			sdhci_read_rsp_136(host, cmd);
12051c6a0718SPierre Ossman 		} else {
1206e0a5640aSAdrian Hunter 			cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
12071c6a0718SPierre Ossman 		}
12081c6a0718SPierre Ossman 	}
12091c6a0718SPierre Ossman 
121020845befSAdrian Hunter 	if (cmd->mrq->cap_cmd_during_tfr && cmd == cmd->mrq->cmd)
121120845befSAdrian Hunter 		mmc_command_done(host->mmc, cmd->mrq);
121220845befSAdrian Hunter 
12136bde8681SAdrian Hunter 	/*
12146bde8681SAdrian Hunter 	 * The host can send and interrupt when the busy state has
12156bde8681SAdrian Hunter 	 * ended, allowing us to wait without wasting CPU cycles.
12166bde8681SAdrian Hunter 	 * The busy signal uses DAT0 so this is similar to waiting
12176bde8681SAdrian Hunter 	 * for data to complete.
12186bde8681SAdrian Hunter 	 *
12196bde8681SAdrian Hunter 	 * Note: The 1.0 specification is a bit ambiguous about this
12206bde8681SAdrian Hunter 	 *       feature so there might be some problems with older
12216bde8681SAdrian Hunter 	 *       controllers.
12226bde8681SAdrian Hunter 	 */
1223e0a5640aSAdrian Hunter 	if (cmd->flags & MMC_RSP_BUSY) {
1224e0a5640aSAdrian Hunter 		if (cmd->data) {
12256bde8681SAdrian Hunter 			DBG("Cannot wait for busy signal when also doing a data transfer");
12266bde8681SAdrian Hunter 		} else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
1227ea968023SAdrian Hunter 			   cmd == host->data_cmd) {
1228ea968023SAdrian Hunter 			/* Command complete before busy is ended */
12296bde8681SAdrian Hunter 			return;
12306bde8681SAdrian Hunter 		}
12316bde8681SAdrian Hunter 	}
12326bde8681SAdrian Hunter 
1233e89d456fSAndrei Warkentin 	/* Finished CMD23, now send actual command. */
1234a4c73abaSAdrian Hunter 	if (cmd == cmd->mrq->sbc) {
1235a4c73abaSAdrian Hunter 		sdhci_send_command(host, cmd->mrq->cmd);
1236e89d456fSAndrei Warkentin 	} else {
1237e89d456fSAndrei Warkentin 
1238e89d456fSAndrei Warkentin 		/* Processed actual command. */
1239e538fbe8SPierre Ossman 		if (host->data && host->data_early)
1240e538fbe8SPierre Ossman 			sdhci_finish_data(host);
1241e538fbe8SPierre Ossman 
1242e0a5640aSAdrian Hunter 		if (!cmd->data)
1243a6d3bdd5SAdrian Hunter 			sdhci_finish_mrq(host, cmd->mrq);
12441c6a0718SPierre Ossman 	}
1245e89d456fSAndrei Warkentin }
12461c6a0718SPierre Ossman 
124752983382SKevin Liu static u16 sdhci_get_preset_value(struct sdhci_host *host)
124852983382SKevin Liu {
1249d975f121SRussell King 	u16 preset = 0;
125052983382SKevin Liu 
1251d975f121SRussell King 	switch (host->timing) {
1252d975f121SRussell King 	case MMC_TIMING_UHS_SDR12:
125352983382SKevin Liu 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
125452983382SKevin Liu 		break;
1255d975f121SRussell King 	case MMC_TIMING_UHS_SDR25:
125652983382SKevin Liu 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25);
125752983382SKevin Liu 		break;
1258d975f121SRussell King 	case MMC_TIMING_UHS_SDR50:
125952983382SKevin Liu 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50);
126052983382SKevin Liu 		break;
1261d975f121SRussell King 	case MMC_TIMING_UHS_SDR104:
1262d975f121SRussell King 	case MMC_TIMING_MMC_HS200:
126352983382SKevin Liu 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
126452983382SKevin Liu 		break;
1265d975f121SRussell King 	case MMC_TIMING_UHS_DDR50:
12660dafa60eSJisheng Zhang 	case MMC_TIMING_MMC_DDR52:
126752983382SKevin Liu 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
126852983382SKevin Liu 		break;
1269e9fb05d5SAdrian Hunter 	case MMC_TIMING_MMC_HS400:
1270e9fb05d5SAdrian Hunter 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_HS400);
1271e9fb05d5SAdrian Hunter 		break;
127252983382SKevin Liu 	default:
127352983382SKevin Liu 		pr_warn("%s: Invalid UHS-I mode selected\n",
127452983382SKevin Liu 			mmc_hostname(host->mmc));
127552983382SKevin Liu 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
127652983382SKevin Liu 		break;
127752983382SKevin Liu 	}
127852983382SKevin Liu 	return preset;
127952983382SKevin Liu }
128052983382SKevin Liu 
1281fb9ee047SLudovic Desroches u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
1282fb9ee047SLudovic Desroches 		   unsigned int *actual_clock)
12831c6a0718SPierre Ossman {
1284c3ed3877SArindam Nath 	int div = 0; /* Initialized for compiler warning */
1285df16219fSGiuseppe CAVALLARO 	int real_div = div, clk_mul = 1;
1286c3ed3877SArindam Nath 	u16 clk = 0;
12875497159cSludovic.desroches@atmel.com 	bool switch_base_clk = false;
12881c6a0718SPierre Ossman 
128985105c53SZhangfei Gao 	if (host->version >= SDHCI_SPEC_300) {
1290da91a8f9SRussell King 		if (host->preset_enabled) {
129152983382SKevin Liu 			u16 pre_val;
129252983382SKevin Liu 
129352983382SKevin Liu 			clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
129452983382SKevin Liu 			pre_val = sdhci_get_preset_value(host);
129552983382SKevin Liu 			div = (pre_val & SDHCI_PRESET_SDCLK_FREQ_MASK)
129652983382SKevin Liu 				>> SDHCI_PRESET_SDCLK_FREQ_SHIFT;
129752983382SKevin Liu 			if (host->clk_mul &&
129852983382SKevin Liu 				(pre_val & SDHCI_PRESET_CLKGEN_SEL_MASK)) {
129952983382SKevin Liu 				clk = SDHCI_PROG_CLOCK_MODE;
130052983382SKevin Liu 				real_div = div + 1;
130152983382SKevin Liu 				clk_mul = host->clk_mul;
130252983382SKevin Liu 			} else {
130352983382SKevin Liu 				real_div = max_t(int, 1, div << 1);
130452983382SKevin Liu 			}
130552983382SKevin Liu 			goto clock_set;
130652983382SKevin Liu 		}
130752983382SKevin Liu 
1308c3ed3877SArindam Nath 		/*
1309c3ed3877SArindam Nath 		 * Check if the Host Controller supports Programmable Clock
1310c3ed3877SArindam Nath 		 * Mode.
1311c3ed3877SArindam Nath 		 */
1312c3ed3877SArindam Nath 		if (host->clk_mul) {
1313c3ed3877SArindam Nath 			for (div = 1; div <= 1024; div++) {
131452983382SKevin Liu 				if ((host->max_clk * host->clk_mul / div)
131552983382SKevin Liu 					<= clock)
1316c3ed3877SArindam Nath 					break;
1317c3ed3877SArindam Nath 			}
13185497159cSludovic.desroches@atmel.com 			if ((host->max_clk * host->clk_mul / div) <= clock) {
1319c3ed3877SArindam Nath 				/*
1320c3ed3877SArindam Nath 				 * Set Programmable Clock Mode in the Clock
1321c3ed3877SArindam Nath 				 * Control register.
1322c3ed3877SArindam Nath 				 */
1323c3ed3877SArindam Nath 				clk = SDHCI_PROG_CLOCK_MODE;
1324df16219fSGiuseppe CAVALLARO 				real_div = div;
1325df16219fSGiuseppe CAVALLARO 				clk_mul = host->clk_mul;
1326c3ed3877SArindam Nath 				div--;
1327c3ed3877SArindam Nath 			} else {
13285497159cSludovic.desroches@atmel.com 				/*
13295497159cSludovic.desroches@atmel.com 				 * Divisor can be too small to reach clock
13305497159cSludovic.desroches@atmel.com 				 * speed requirement. Then use the base clock.
13315497159cSludovic.desroches@atmel.com 				 */
13325497159cSludovic.desroches@atmel.com 				switch_base_clk = true;
13335497159cSludovic.desroches@atmel.com 			}
13345497159cSludovic.desroches@atmel.com 		}
13355497159cSludovic.desroches@atmel.com 
13365497159cSludovic.desroches@atmel.com 		if (!host->clk_mul || switch_base_clk) {
133785105c53SZhangfei Gao 			/* Version 3.00 divisors must be a multiple of 2. */
133885105c53SZhangfei Gao 			if (host->max_clk <= clock)
133985105c53SZhangfei Gao 				div = 1;
134085105c53SZhangfei Gao 			else {
1341c3ed3877SArindam Nath 				for (div = 2; div < SDHCI_MAX_DIV_SPEC_300;
1342c3ed3877SArindam Nath 				     div += 2) {
134385105c53SZhangfei Gao 					if ((host->max_clk / div) <= clock)
134485105c53SZhangfei Gao 						break;
134585105c53SZhangfei Gao 				}
134685105c53SZhangfei Gao 			}
1347df16219fSGiuseppe CAVALLARO 			real_div = div;
1348c3ed3877SArindam Nath 			div >>= 1;
1349d1955c3aSSuneel Garapati 			if ((host->quirks2 & SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN)
1350d1955c3aSSuneel Garapati 				&& !div && host->max_clk <= 25000000)
1351d1955c3aSSuneel Garapati 				div = 1;
1352c3ed3877SArindam Nath 		}
135385105c53SZhangfei Gao 	} else {
135485105c53SZhangfei Gao 		/* Version 2.00 divisors must be a power of 2. */
13550397526dSZhangfei Gao 		for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) {
13561c6a0718SPierre Ossman 			if ((host->max_clk / div) <= clock)
13571c6a0718SPierre Ossman 				break;
13581c6a0718SPierre Ossman 		}
1359df16219fSGiuseppe CAVALLARO 		real_div = div;
13601c6a0718SPierre Ossman 		div >>= 1;
1361c3ed3877SArindam Nath 	}
13621c6a0718SPierre Ossman 
136352983382SKevin Liu clock_set:
136403d6f5ffSAisheng Dong 	if (real_div)
1365fb9ee047SLudovic Desroches 		*actual_clock = (host->max_clk * clk_mul) / real_div;
1366c3ed3877SArindam Nath 	clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
136785105c53SZhangfei Gao 	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
136885105c53SZhangfei Gao 		<< SDHCI_DIVIDER_HI_SHIFT;
1369fb9ee047SLudovic Desroches 
1370fb9ee047SLudovic Desroches 	return clk;
1371fb9ee047SLudovic Desroches }
1372fb9ee047SLudovic Desroches EXPORT_SYMBOL_GPL(sdhci_calc_clk);
1373fb9ee047SLudovic Desroches 
1374fec79673SRitesh Harjani void sdhci_enable_clk(struct sdhci_host *host, u16 clk)
1375fb9ee047SLudovic Desroches {
13765a436cc0SAdrian Hunter 	ktime_t timeout;
1377fb9ee047SLudovic Desroches 
13781c6a0718SPierre Ossman 	clk |= SDHCI_CLOCK_INT_EN;
13794e4141a5SAnton Vorontsov 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
13801c6a0718SPierre Ossman 
138127f6cb16SChris Ball 	/* Wait max 20 ms */
13825a436cc0SAdrian Hunter 	timeout = ktime_add_ms(ktime_get(), 20);
13834e4141a5SAnton Vorontsov 	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
13841c6a0718SPierre Ossman 		& SDHCI_CLOCK_INT_STABLE)) {
13855a436cc0SAdrian Hunter 		if (ktime_after(ktime_get(), timeout)) {
13862e4456f0SMarek Vasut 			pr_err("%s: Internal clock never stabilised.\n",
13872e4456f0SMarek Vasut 			       mmc_hostname(host->mmc));
13881c6a0718SPierre Ossman 			sdhci_dumpregs(host);
13891c6a0718SPierre Ossman 			return;
13901c6a0718SPierre Ossman 		}
13915a436cc0SAdrian Hunter 		udelay(10);
13921c6a0718SPierre Ossman 	}
13931c6a0718SPierre Ossman 
13941c6a0718SPierre Ossman 	clk |= SDHCI_CLOCK_CARD_EN;
13954e4141a5SAnton Vorontsov 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
13961c6a0718SPierre Ossman }
1397fec79673SRitesh Harjani EXPORT_SYMBOL_GPL(sdhci_enable_clk);
1398fec79673SRitesh Harjani 
1399fec79673SRitesh Harjani void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
1400fec79673SRitesh Harjani {
1401fec79673SRitesh Harjani 	u16 clk;
1402fec79673SRitesh Harjani 
1403fec79673SRitesh Harjani 	host->mmc->actual_clock = 0;
1404fec79673SRitesh Harjani 
1405fec79673SRitesh Harjani 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
1406fec79673SRitesh Harjani 
1407fec79673SRitesh Harjani 	if (clock == 0)
1408fec79673SRitesh Harjani 		return;
1409fec79673SRitesh Harjani 
1410fec79673SRitesh Harjani 	clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
1411fec79673SRitesh Harjani 	sdhci_enable_clk(host, clk);
1412fec79673SRitesh Harjani }
14131771059cSRussell King EXPORT_SYMBOL_GPL(sdhci_set_clock);
14141c6a0718SPierre Ossman 
14151dceb041SAdrian Hunter static void sdhci_set_power_reg(struct sdhci_host *host, unsigned char mode,
141624fbb3caSRussell King 				unsigned short vdd)
14171c6a0718SPierre Ossman {
14183a48edc4STim Kryger 	struct mmc_host *mmc = host->mmc;
14191dceb041SAdrian Hunter 
14201dceb041SAdrian Hunter 	mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
14211dceb041SAdrian Hunter 
14221dceb041SAdrian Hunter 	if (mode != MMC_POWER_OFF)
14231dceb041SAdrian Hunter 		sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
14241dceb041SAdrian Hunter 	else
14251dceb041SAdrian Hunter 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
14261dceb041SAdrian Hunter }
14271dceb041SAdrian Hunter 
1428606d3131SAdrian Hunter void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode,
14291dceb041SAdrian Hunter 			   unsigned short vdd)
14301dceb041SAdrian Hunter {
14318364248aSGiuseppe Cavallaro 	u8 pwr = 0;
14321c6a0718SPierre Ossman 
143324fbb3caSRussell King 	if (mode != MMC_POWER_OFF) {
143424fbb3caSRussell King 		switch (1 << vdd) {
1435ae628903SPierre Ossman 		case MMC_VDD_165_195:
1436ae628903SPierre Ossman 			pwr = SDHCI_POWER_180;
1437ae628903SPierre Ossman 			break;
1438ae628903SPierre Ossman 		case MMC_VDD_29_30:
1439ae628903SPierre Ossman 		case MMC_VDD_30_31:
1440ae628903SPierre Ossman 			pwr = SDHCI_POWER_300;
1441ae628903SPierre Ossman 			break;
1442ae628903SPierre Ossman 		case MMC_VDD_32_33:
1443ae628903SPierre Ossman 		case MMC_VDD_33_34:
1444ae628903SPierre Ossman 			pwr = SDHCI_POWER_330;
1445ae628903SPierre Ossman 			break;
1446ae628903SPierre Ossman 		default:
14479d5de93fSAdrian Hunter 			WARN(1, "%s: Invalid vdd %#x\n",
14489d5de93fSAdrian Hunter 			     mmc_hostname(host->mmc), vdd);
14499d5de93fSAdrian Hunter 			break;
1450ae628903SPierre Ossman 		}
1451ae628903SPierre Ossman 	}
1452ae628903SPierre Ossman 
1453ae628903SPierre Ossman 	if (host->pwr == pwr)
1454e921a8b6SRussell King 		return;
14551c6a0718SPierre Ossman 
1456ae628903SPierre Ossman 	host->pwr = pwr;
1457ae628903SPierre Ossman 
1458ae628903SPierre Ossman 	if (pwr == 0) {
14594e4141a5SAnton Vorontsov 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1460f0710a55SAdrian Hunter 		if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
1461f0710a55SAdrian Hunter 			sdhci_runtime_pm_bus_off(host);
1462e921a8b6SRussell King 	} else {
14631c6a0718SPierre Ossman 		/*
14641c6a0718SPierre Ossman 		 * Spec says that we should clear the power reg before setting
14651c6a0718SPierre Ossman 		 * a new value. Some controllers don't seem to like this though.
14661c6a0718SPierre Ossman 		 */
1467b8c86fc5SPierre Ossman 		if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
14684e4141a5SAnton Vorontsov 			sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
14691c6a0718SPierre Ossman 
1470e08c1694SAndres Salomon 		/*
1471e921a8b6SRussell King 		 * At least the Marvell CaFe chip gets confused if we set the
1472e921a8b6SRussell King 		 * voltage and set turn on power at the same time, so set the
1473e921a8b6SRussell King 		 * voltage first.
1474e08c1694SAndres Salomon 		 */
147511a2f1b7SPierre Ossman 		if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
14764e4141a5SAnton Vorontsov 			sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
14771c6a0718SPierre Ossman 
1478ae628903SPierre Ossman 		pwr |= SDHCI_POWER_ON;
1479ae628903SPierre Ossman 
1480ae628903SPierre Ossman 		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1481557b0697SHarald Welte 
1482f0710a55SAdrian Hunter 		if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
1483f0710a55SAdrian Hunter 			sdhci_runtime_pm_bus_on(host);
1484f0710a55SAdrian Hunter 
1485557b0697SHarald Welte 		/*
1486e921a8b6SRussell King 		 * Some controllers need an extra 10ms delay of 10ms before
1487e921a8b6SRussell King 		 * they can apply clock after applying power
1488557b0697SHarald Welte 		 */
148911a2f1b7SPierre Ossman 		if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
1490557b0697SHarald Welte 			mdelay(10);
1491e921a8b6SRussell King 	}
1492918f4cbdSJisheng Zhang }
1493606d3131SAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_set_power_noreg);
14941dceb041SAdrian Hunter 
1495606d3131SAdrian Hunter void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
14961dceb041SAdrian Hunter 		     unsigned short vdd)
14971dceb041SAdrian Hunter {
1498606d3131SAdrian Hunter 	if (IS_ERR(host->mmc->supply.vmmc))
1499606d3131SAdrian Hunter 		sdhci_set_power_noreg(host, mode, vdd);
15001dceb041SAdrian Hunter 	else
1501606d3131SAdrian Hunter 		sdhci_set_power_reg(host, mode, vdd);
15021c6a0718SPierre Ossman }
1503606d3131SAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_set_power);
15041c6a0718SPierre Ossman 
15051c6a0718SPierre Ossman /*****************************************************************************\
15061c6a0718SPierre Ossman  *                                                                           *
15071c6a0718SPierre Ossman  * MMC callbacks                                                             *
15081c6a0718SPierre Ossman  *                                                                           *
15091c6a0718SPierre Ossman \*****************************************************************************/
15101c6a0718SPierre Ossman 
15111c6a0718SPierre Ossman static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
15121c6a0718SPierre Ossman {
15131c6a0718SPierre Ossman 	struct sdhci_host *host;
1514505a8680SShawn Guo 	int present;
15151c6a0718SPierre Ossman 	unsigned long flags;
15161c6a0718SPierre Ossman 
15171c6a0718SPierre Ossman 	host = mmc_priv(mmc);
15181c6a0718SPierre Ossman 
151904e079cfSScott Branden 	/* Firstly check card presence */
15208d28b7a7SAdrian Hunter 	present = mmc->ops->get_cd(mmc);
15212836766aSKrzysztof Kozlowski 
15221c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
15231c6a0718SPierre Ossman 
1524061d17a6SAdrian Hunter 	sdhci_led_activate(host);
1525e89d456fSAndrei Warkentin 
1526e89d456fSAndrei Warkentin 	/*
1527e89d456fSAndrei Warkentin 	 * Ensure we don't send the STOP for non-SET_BLOCK_COUNTED
1528e89d456fSAndrei Warkentin 	 * requests if Auto-CMD12 is enabled.
1529e89d456fSAndrei Warkentin 	 */
15300293d501SAdrian Hunter 	if (sdhci_auto_cmd12(host, mrq)) {
1531c4512f79SJerry Huang 		if (mrq->stop) {
1532c4512f79SJerry Huang 			mrq->data->stop = NULL;
1533c4512f79SJerry Huang 			mrq->stop = NULL;
1534c4512f79SJerry Huang 		}
1535c4512f79SJerry Huang 	}
15361c6a0718SPierre Ossman 
153768d1fb7eSAnton Vorontsov 	if (!present || host->flags & SDHCI_DEVICE_DEAD) {
1538a4c73abaSAdrian Hunter 		mrq->cmd->error = -ENOMEDIUM;
1539a6d3bdd5SAdrian Hunter 		sdhci_finish_mrq(host, mrq);
1540cf2b5eeaSArindam Nath 	} else {
15418edf6371SAndrei Warkentin 		if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
1542e89d456fSAndrei Warkentin 			sdhci_send_command(host, mrq->sbc);
1543e89d456fSAndrei Warkentin 		else
15441c6a0718SPierre Ossman 			sdhci_send_command(host, mrq->cmd);
1545cf2b5eeaSArindam Nath 	}
15461c6a0718SPierre Ossman 
15471c6a0718SPierre Ossman 	mmiowb();
15481c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
15491c6a0718SPierre Ossman }
15501c6a0718SPierre Ossman 
15512317f56cSRussell King void sdhci_set_bus_width(struct sdhci_host *host, int width)
15522317f56cSRussell King {
15532317f56cSRussell King 	u8 ctrl;
15542317f56cSRussell King 
15552317f56cSRussell King 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
15562317f56cSRussell King 	if (width == MMC_BUS_WIDTH_8) {
15572317f56cSRussell King 		ctrl &= ~SDHCI_CTRL_4BITBUS;
15582317f56cSRussell King 		ctrl |= SDHCI_CTRL_8BITBUS;
15592317f56cSRussell King 	} else {
156098f94ea6SMichał Mirosław 		if (host->mmc->caps & MMC_CAP_8_BIT_DATA)
15612317f56cSRussell King 			ctrl &= ~SDHCI_CTRL_8BITBUS;
15622317f56cSRussell King 		if (width == MMC_BUS_WIDTH_4)
15632317f56cSRussell King 			ctrl |= SDHCI_CTRL_4BITBUS;
15642317f56cSRussell King 		else
15652317f56cSRussell King 			ctrl &= ~SDHCI_CTRL_4BITBUS;
15662317f56cSRussell King 	}
15672317f56cSRussell King 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
15682317f56cSRussell King }
15692317f56cSRussell King EXPORT_SYMBOL_GPL(sdhci_set_bus_width);
15702317f56cSRussell King 
157196d7b78cSRussell King void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
157296d7b78cSRussell King {
157396d7b78cSRussell King 	u16 ctrl_2;
157496d7b78cSRussell King 
157596d7b78cSRussell King 	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
157696d7b78cSRussell King 	/* Select Bus Speed Mode for host */
157796d7b78cSRussell King 	ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
157896d7b78cSRussell King 	if ((timing == MMC_TIMING_MMC_HS200) ||
157996d7b78cSRussell King 	    (timing == MMC_TIMING_UHS_SDR104))
158096d7b78cSRussell King 		ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
158196d7b78cSRussell King 	else if (timing == MMC_TIMING_UHS_SDR12)
158296d7b78cSRussell King 		ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
158396d7b78cSRussell King 	else if (timing == MMC_TIMING_UHS_SDR25)
158496d7b78cSRussell King 		ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
158596d7b78cSRussell King 	else if (timing == MMC_TIMING_UHS_SDR50)
158696d7b78cSRussell King 		ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
158796d7b78cSRussell King 	else if ((timing == MMC_TIMING_UHS_DDR50) ||
158896d7b78cSRussell King 		 (timing == MMC_TIMING_MMC_DDR52))
158996d7b78cSRussell King 		ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
1590e9fb05d5SAdrian Hunter 	else if (timing == MMC_TIMING_MMC_HS400)
1591e9fb05d5SAdrian Hunter 		ctrl_2 |= SDHCI_CTRL_HS400; /* Non-standard */
159296d7b78cSRussell King 	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
159396d7b78cSRussell King }
159496d7b78cSRussell King EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
159596d7b78cSRussell King 
15966a6d4cebSHu Ziji void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
15971c6a0718SPierre Ossman {
1598ded97e0bSDong Aisheng 	struct sdhci_host *host = mmc_priv(mmc);
15991c6a0718SPierre Ossman 	u8 ctrl;
16001c6a0718SPierre Ossman 
160184ec048bSAdrian Hunter 	if (ios->power_mode == MMC_POWER_UNDEFINED)
160284ec048bSAdrian Hunter 		return;
160384ec048bSAdrian Hunter 
1604ceb6143bSAdrian Hunter 	if (host->flags & SDHCI_DEVICE_DEAD) {
16053a48edc4STim Kryger 		if (!IS_ERR(mmc->supply.vmmc) &&
16063a48edc4STim Kryger 		    ios->power_mode == MMC_POWER_OFF)
16074e743f1fSMarkus Mayer 			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
1608ceb6143bSAdrian Hunter 		return;
1609ceb6143bSAdrian Hunter 	}
16101e72859eSPierre Ossman 
16111c6a0718SPierre Ossman 	/*
16121c6a0718SPierre Ossman 	 * Reset the chip on each power off.
16131c6a0718SPierre Ossman 	 * Should clear out any weird states.
16141c6a0718SPierre Ossman 	 */
16151c6a0718SPierre Ossman 	if (ios->power_mode == MMC_POWER_OFF) {
16164e4141a5SAnton Vorontsov 		sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
16177260cf5eSAnton Vorontsov 		sdhci_reinit(host);
16181c6a0718SPierre Ossman 	}
16191c6a0718SPierre Ossman 
162052983382SKevin Liu 	if (host->version >= SDHCI_SPEC_300 &&
1621372c4634SDong Aisheng 		(ios->power_mode == MMC_POWER_UP) &&
1622372c4634SDong Aisheng 		!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
162352983382SKevin Liu 		sdhci_enable_preset_value(host, false);
162452983382SKevin Liu 
1625373073efSRussell King 	if (!ios->clock || ios->clock != host->clock) {
16261771059cSRussell King 		host->ops->set_clock(host, ios->clock);
1627373073efSRussell King 		host->clock = ios->clock;
162803d6f5ffSAisheng Dong 
162903d6f5ffSAisheng Dong 		if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK &&
163003d6f5ffSAisheng Dong 		    host->clock) {
163103d6f5ffSAisheng Dong 			host->timeout_clk = host->mmc->actual_clock ?
163203d6f5ffSAisheng Dong 						host->mmc->actual_clock / 1000 :
163303d6f5ffSAisheng Dong 						host->clock / 1000;
163403d6f5ffSAisheng Dong 			host->mmc->max_busy_timeout =
163503d6f5ffSAisheng Dong 				host->ops->get_max_timeout_count ?
163603d6f5ffSAisheng Dong 				host->ops->get_max_timeout_count(host) :
163703d6f5ffSAisheng Dong 				1 << 27;
163803d6f5ffSAisheng Dong 			host->mmc->max_busy_timeout /= host->timeout_clk;
163903d6f5ffSAisheng Dong 		}
1640373073efSRussell King 	}
16411c6a0718SPierre Ossman 
1642606d3131SAdrian Hunter 	if (host->ops->set_power)
1643606d3131SAdrian Hunter 		host->ops->set_power(host, ios->power_mode, ios->vdd);
1644606d3131SAdrian Hunter 	else
1645606d3131SAdrian Hunter 		sdhci_set_power(host, ios->power_mode, ios->vdd);
16461c6a0718SPierre Ossman 
1647643a81ffSPhilip Rakity 	if (host->ops->platform_send_init_74_clocks)
1648643a81ffSPhilip Rakity 		host->ops->platform_send_init_74_clocks(host, ios->power_mode);
1649643a81ffSPhilip Rakity 
16502317f56cSRussell King 	host->ops->set_bus_width(host, ios->bus_width);
165115ec4461SPhilip Rakity 
165215ec4461SPhilip Rakity 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
16531c6a0718SPierre Ossman 
1654501639bfSyangbo lu 	if (!(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) {
1655501639bfSyangbo lu 		if (ios->timing == MMC_TIMING_SD_HS ||
1656273c5414SJaehoon Chung 		     ios->timing == MMC_TIMING_MMC_HS ||
1657273c5414SJaehoon Chung 		     ios->timing == MMC_TIMING_MMC_HS400 ||
1658273c5414SJaehoon Chung 		     ios->timing == MMC_TIMING_MMC_HS200 ||
1659273c5414SJaehoon Chung 		     ios->timing == MMC_TIMING_MMC_DDR52 ||
1660273c5414SJaehoon Chung 		     ios->timing == MMC_TIMING_UHS_SDR50 ||
1661273c5414SJaehoon Chung 		     ios->timing == MMC_TIMING_UHS_SDR104 ||
1662273c5414SJaehoon Chung 		     ios->timing == MMC_TIMING_UHS_DDR50 ||
1663273c5414SJaehoon Chung 		     ios->timing == MMC_TIMING_UHS_SDR25)
16641c6a0718SPierre Ossman 			ctrl |= SDHCI_CTRL_HISPD;
16651c6a0718SPierre Ossman 		else
16661c6a0718SPierre Ossman 			ctrl &= ~SDHCI_CTRL_HISPD;
1667501639bfSyangbo lu 	}
16681c6a0718SPierre Ossman 
1669d6d50a15SArindam Nath 	if (host->version >= SDHCI_SPEC_300) {
167049c468fcSArindam Nath 		u16 clk, ctrl_2;
167149c468fcSArindam Nath 
1672da91a8f9SRussell King 		if (!host->preset_enabled) {
1673758535c4SArindam Nath 			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1674d6d50a15SArindam Nath 			/*
1675d6d50a15SArindam Nath 			 * We only need to set Driver Strength if the
1676d6d50a15SArindam Nath 			 * preset value enable is not set.
1677d6d50a15SArindam Nath 			 */
1678da91a8f9SRussell King 			ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1679d6d50a15SArindam Nath 			ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK;
1680d6d50a15SArindam Nath 			if (ios->drv_type == MMC_SET_DRIVER_TYPE_A)
1681d6d50a15SArindam Nath 				ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A;
168243e943a0SPetri Gynther 			else if (ios->drv_type == MMC_SET_DRIVER_TYPE_B)
168343e943a0SPetri Gynther 				ctrl_2 |= SDHCI_CTRL_DRV_TYPE_B;
1684d6d50a15SArindam Nath 			else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C)
1685d6d50a15SArindam Nath 				ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C;
168643e943a0SPetri Gynther 			else if (ios->drv_type == MMC_SET_DRIVER_TYPE_D)
168743e943a0SPetri Gynther 				ctrl_2 |= SDHCI_CTRL_DRV_TYPE_D;
168843e943a0SPetri Gynther 			else {
16892e4456f0SMarek Vasut 				pr_warn("%s: invalid driver type, default to driver type B\n",
16902e4456f0SMarek Vasut 					mmc_hostname(mmc));
169143e943a0SPetri Gynther 				ctrl_2 |= SDHCI_CTRL_DRV_TYPE_B;
169243e943a0SPetri Gynther 			}
1693d6d50a15SArindam Nath 
1694d6d50a15SArindam Nath 			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
1695758535c4SArindam Nath 		} else {
1696758535c4SArindam Nath 			/*
1697758535c4SArindam Nath 			 * According to SDHC Spec v3.00, if the Preset Value
1698758535c4SArindam Nath 			 * Enable in the Host Control 2 register is set, we
1699758535c4SArindam Nath 			 * need to reset SD Clock Enable before changing High
1700758535c4SArindam Nath 			 * Speed Enable to avoid generating clock gliches.
1701758535c4SArindam Nath 			 */
1702758535c4SArindam Nath 
1703758535c4SArindam Nath 			/* Reset SD Clock Enable */
1704758535c4SArindam Nath 			clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1705758535c4SArindam Nath 			clk &= ~SDHCI_CLOCK_CARD_EN;
1706758535c4SArindam Nath 			sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
1707758535c4SArindam Nath 
1708758535c4SArindam Nath 			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1709758535c4SArindam Nath 
1710758535c4SArindam Nath 			/* Re-enable SD Clock */
17111771059cSRussell King 			host->ops->set_clock(host, host->clock);
1712d6d50a15SArindam Nath 		}
171349c468fcSArindam Nath 
17146322cdd0SPhilip Rakity 		/* Reset SD Clock Enable */
17156322cdd0SPhilip Rakity 		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
17166322cdd0SPhilip Rakity 		clk &= ~SDHCI_CLOCK_CARD_EN;
17176322cdd0SPhilip Rakity 		sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
17186322cdd0SPhilip Rakity 
17196322cdd0SPhilip Rakity 		host->ops->set_uhs_signaling(host, ios->timing);
1720d975f121SRussell King 		host->timing = ios->timing;
172149c468fcSArindam Nath 
172252983382SKevin Liu 		if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
172352983382SKevin Liu 				((ios->timing == MMC_TIMING_UHS_SDR12) ||
172452983382SKevin Liu 				 (ios->timing == MMC_TIMING_UHS_SDR25) ||
172552983382SKevin Liu 				 (ios->timing == MMC_TIMING_UHS_SDR50) ||
172652983382SKevin Liu 				 (ios->timing == MMC_TIMING_UHS_SDR104) ||
17270dafa60eSJisheng Zhang 				 (ios->timing == MMC_TIMING_UHS_DDR50) ||
17280dafa60eSJisheng Zhang 				 (ios->timing == MMC_TIMING_MMC_DDR52))) {
172952983382SKevin Liu 			u16 preset;
173052983382SKevin Liu 
173152983382SKevin Liu 			sdhci_enable_preset_value(host, true);
173252983382SKevin Liu 			preset = sdhci_get_preset_value(host);
173352983382SKevin Liu 			ios->drv_type = (preset & SDHCI_PRESET_DRV_MASK)
173452983382SKevin Liu 				>> SDHCI_PRESET_DRV_SHIFT;
173552983382SKevin Liu 		}
173652983382SKevin Liu 
173749c468fcSArindam Nath 		/* Re-enable SD Clock */
17381771059cSRussell King 		host->ops->set_clock(host, host->clock);
1739758535c4SArindam Nath 	} else
1740758535c4SArindam Nath 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1741d6d50a15SArindam Nath 
1742b8352260SLeandro Dorileo 	/*
1743b8352260SLeandro Dorileo 	 * Some (ENE) controllers go apeshit on some ios operation,
1744b8352260SLeandro Dorileo 	 * signalling timeout and CRC errors even on CMD0. Resetting
1745b8352260SLeandro Dorileo 	 * it on each ios seems to solve the problem.
1746b8352260SLeandro Dorileo 	 */
1747b8c86fc5SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
174803231f9bSRussell King 		sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
1749b8352260SLeandro Dorileo 
17501c6a0718SPierre Ossman 	mmiowb();
17511c6a0718SPierre Ossman }
17526a6d4cebSHu Ziji EXPORT_SYMBOL_GPL(sdhci_set_ios);
17531c6a0718SPierre Ossman 
1754ded97e0bSDong Aisheng static int sdhci_get_cd(struct mmc_host *mmc)
175566fd8ad5SAdrian Hunter {
175666fd8ad5SAdrian Hunter 	struct sdhci_host *host = mmc_priv(mmc);
1757ded97e0bSDong Aisheng 	int gpio_cd = mmc_gpio_get_cd(mmc);
175894144a46SKevin Liu 
175994144a46SKevin Liu 	if (host->flags & SDHCI_DEVICE_DEAD)
176094144a46SKevin Liu 		return 0;
176194144a46SKevin Liu 
176288af5655SIvan T. Ivanov 	/* If nonremovable, assume that the card is always present. */
1763860951c5SJaehoon Chung 	if (!mmc_card_is_removable(host->mmc))
176494144a46SKevin Liu 		return 1;
176594144a46SKevin Liu 
176688af5655SIvan T. Ivanov 	/*
176788af5655SIvan T. Ivanov 	 * Try slot gpio detect, if defined it take precedence
176888af5655SIvan T. Ivanov 	 * over build in controller functionality
176988af5655SIvan T. Ivanov 	 */
1770287980e4SArnd Bergmann 	if (gpio_cd >= 0)
177194144a46SKevin Liu 		return !!gpio_cd;
177294144a46SKevin Liu 
177388af5655SIvan T. Ivanov 	/* If polling, assume that the card is always present. */
177488af5655SIvan T. Ivanov 	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
177588af5655SIvan T. Ivanov 		return 1;
177688af5655SIvan T. Ivanov 
177794144a46SKevin Liu 	/* Host native card detect */
177894144a46SKevin Liu 	return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
177994144a46SKevin Liu }
178094144a46SKevin Liu 
178166fd8ad5SAdrian Hunter static int sdhci_check_ro(struct sdhci_host *host)
17821c6a0718SPierre Ossman {
17831c6a0718SPierre Ossman 	unsigned long flags;
17842dfb579cSWolfram Sang 	int is_readonly;
17851c6a0718SPierre Ossman 
17861c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
17871c6a0718SPierre Ossman 
17881e72859eSPierre Ossman 	if (host->flags & SDHCI_DEVICE_DEAD)
17892dfb579cSWolfram Sang 		is_readonly = 0;
17902dfb579cSWolfram Sang 	else if (host->ops->get_ro)
17912dfb579cSWolfram Sang 		is_readonly = host->ops->get_ro(host);
17921e72859eSPierre Ossman 	else
17932dfb579cSWolfram Sang 		is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
17942dfb579cSWolfram Sang 				& SDHCI_WRITE_PROTECT);
17951c6a0718SPierre Ossman 
17961c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
17971c6a0718SPierre Ossman 
17982dfb579cSWolfram Sang 	/* This quirk needs to be replaced by a callback-function later */
17992dfb579cSWolfram Sang 	return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
18002dfb579cSWolfram Sang 		!is_readonly : is_readonly;
18011c6a0718SPierre Ossman }
18021c6a0718SPierre Ossman 
180382b0e23aSTakashi Iwai #define SAMPLE_COUNT	5
180482b0e23aSTakashi Iwai 
1805ded97e0bSDong Aisheng static int sdhci_get_ro(struct mmc_host *mmc)
180682b0e23aSTakashi Iwai {
1807ded97e0bSDong Aisheng 	struct sdhci_host *host = mmc_priv(mmc);
180882b0e23aSTakashi Iwai 	int i, ro_count;
180982b0e23aSTakashi Iwai 
181082b0e23aSTakashi Iwai 	if (!(host->quirks & SDHCI_QUIRK_UNSTABLE_RO_DETECT))
181166fd8ad5SAdrian Hunter 		return sdhci_check_ro(host);
181282b0e23aSTakashi Iwai 
181382b0e23aSTakashi Iwai 	ro_count = 0;
181482b0e23aSTakashi Iwai 	for (i = 0; i < SAMPLE_COUNT; i++) {
181566fd8ad5SAdrian Hunter 		if (sdhci_check_ro(host)) {
181682b0e23aSTakashi Iwai 			if (++ro_count > SAMPLE_COUNT / 2)
181782b0e23aSTakashi Iwai 				return 1;
181882b0e23aSTakashi Iwai 		}
181982b0e23aSTakashi Iwai 		msleep(30);
182082b0e23aSTakashi Iwai 	}
182182b0e23aSTakashi Iwai 	return 0;
182282b0e23aSTakashi Iwai }
182382b0e23aSTakashi Iwai 
182420758b66SAdrian Hunter static void sdhci_hw_reset(struct mmc_host *mmc)
182520758b66SAdrian Hunter {
182620758b66SAdrian Hunter 	struct sdhci_host *host = mmc_priv(mmc);
182720758b66SAdrian Hunter 
182820758b66SAdrian Hunter 	if (host->ops && host->ops->hw_reset)
182920758b66SAdrian Hunter 		host->ops->hw_reset(host);
183020758b66SAdrian Hunter }
183120758b66SAdrian Hunter 
183266fd8ad5SAdrian Hunter static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
183366fd8ad5SAdrian Hunter {
1834be138554SRussell King 	if (!(host->flags & SDHCI_DEVICE_DEAD)) {
183566fd8ad5SAdrian Hunter 		if (enable)
1836b537f94cSRussell King 			host->ier |= SDHCI_INT_CARD_INT;
18377260cf5eSAnton Vorontsov 		else
1838b537f94cSRussell King 			host->ier &= ~SDHCI_INT_CARD_INT;
1839b537f94cSRussell King 
1840b537f94cSRussell King 		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
1841b537f94cSRussell King 		sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
1842f75979b7SPierre Ossman 		mmiowb();
184366fd8ad5SAdrian Hunter 	}
1844ef104333SRussell King }
1845f75979b7SPierre Ossman 
18462f05b6abSHu Ziji void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
184766fd8ad5SAdrian Hunter {
184866fd8ad5SAdrian Hunter 	struct sdhci_host *host = mmc_priv(mmc);
184966fd8ad5SAdrian Hunter 	unsigned long flags;
185066fd8ad5SAdrian Hunter 
1851923713b3SHans de Goede 	if (enable)
1852923713b3SHans de Goede 		pm_runtime_get_noresume(host->mmc->parent);
1853923713b3SHans de Goede 
185466fd8ad5SAdrian Hunter 	spin_lock_irqsave(&host->lock, flags);
1855ef104333SRussell King 	if (enable)
1856ef104333SRussell King 		host->flags |= SDHCI_SDIO_IRQ_ENABLED;
1857ef104333SRussell King 	else
1858ef104333SRussell King 		host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
1859ef104333SRussell King 
186066fd8ad5SAdrian Hunter 	sdhci_enable_sdio_irq_nolock(host, enable);
1861f75979b7SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
1862923713b3SHans de Goede 
1863923713b3SHans de Goede 	if (!enable)
1864923713b3SHans de Goede 		pm_runtime_put_noidle(host->mmc->parent);
1865f75979b7SPierre Ossman }
18662f05b6abSHu Ziji EXPORT_SYMBOL_GPL(sdhci_enable_sdio_irq);
1867f75979b7SPierre Ossman 
1868c376ea9eSHu Ziji int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
186921f5998fSFabio Estevam 				      struct mmc_ios *ios)
1870f2119df6SArindam Nath {
1871ded97e0bSDong Aisheng 	struct sdhci_host *host = mmc_priv(mmc);
187220b92a30SKevin Liu 	u16 ctrl;
18736231f3deSPhilip Rakity 	int ret;
1874f2119df6SArindam Nath 
187520b92a30SKevin Liu 	/*
187620b92a30SKevin Liu 	 * Signal Voltage Switching is only applicable for Host Controllers
187720b92a30SKevin Liu 	 * v3.00 and above.
187820b92a30SKevin Liu 	 */
187920b92a30SKevin Liu 	if (host->version < SDHCI_SPEC_300)
188020b92a30SKevin Liu 		return 0;
188120b92a30SKevin Liu 
188220b92a30SKevin Liu 	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
188320b92a30SKevin Liu 
188421f5998fSFabio Estevam 	switch (ios->signal_voltage) {
188520b92a30SKevin Liu 	case MMC_SIGNAL_VOLTAGE_330:
18868cb851a4SAdrian Hunter 		if (!(host->flags & SDHCI_SIGNALING_330))
18878cb851a4SAdrian Hunter 			return -EINVAL;
1888f2119df6SArindam Nath 		/* Set 1.8V Signal Enable in the Host Control2 register to 0 */
1889f2119df6SArindam Nath 		ctrl &= ~SDHCI_CTRL_VDD_180;
1890f2119df6SArindam Nath 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1891f2119df6SArindam Nath 
18923a48edc4STim Kryger 		if (!IS_ERR(mmc->supply.vqmmc)) {
1893761daa36SDong Aisheng 			ret = mmc_regulator_set_vqmmc(mmc, ios);
18946231f3deSPhilip Rakity 			if (ret) {
18956606110dSJoe Perches 				pr_warn("%s: Switching to 3.3V signalling voltage failed\n",
18966606110dSJoe Perches 					mmc_hostname(mmc));
18976231f3deSPhilip Rakity 				return -EIO;
18986231f3deSPhilip Rakity 			}
18996231f3deSPhilip Rakity 		}
1900f2119df6SArindam Nath 		/* Wait for 5ms */
1901f2119df6SArindam Nath 		usleep_range(5000, 5500);
1902f2119df6SArindam Nath 
1903f2119df6SArindam Nath 		/* 3.3V regulator output should be stable within 5 ms */
1904f2119df6SArindam Nath 		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1905f2119df6SArindam Nath 		if (!(ctrl & SDHCI_CTRL_VDD_180))
1906f2119df6SArindam Nath 			return 0;
19076231f3deSPhilip Rakity 
19086606110dSJoe Perches 		pr_warn("%s: 3.3V regulator output did not became stable\n",
19094e743f1fSMarkus Mayer 			mmc_hostname(mmc));
19106231f3deSPhilip Rakity 
191120b92a30SKevin Liu 		return -EAGAIN;
191220b92a30SKevin Liu 	case MMC_SIGNAL_VOLTAGE_180:
19138cb851a4SAdrian Hunter 		if (!(host->flags & SDHCI_SIGNALING_180))
19148cb851a4SAdrian Hunter 			return -EINVAL;
19153a48edc4STim Kryger 		if (!IS_ERR(mmc->supply.vqmmc)) {
1916761daa36SDong Aisheng 			ret = mmc_regulator_set_vqmmc(mmc, ios);
191720b92a30SKevin Liu 			if (ret) {
19186606110dSJoe Perches 				pr_warn("%s: Switching to 1.8V signalling voltage failed\n",
19196606110dSJoe Perches 					mmc_hostname(mmc));
1920f2119df6SArindam Nath 				return -EIO;
1921f2119df6SArindam Nath 			}
192220b92a30SKevin Liu 		}
19236231f3deSPhilip Rakity 
1924f2119df6SArindam Nath 		/*
1925f2119df6SArindam Nath 		 * Enable 1.8V Signal Enable in the Host Control2
1926f2119df6SArindam Nath 		 * register
1927f2119df6SArindam Nath 		 */
1928f2119df6SArindam Nath 		ctrl |= SDHCI_CTRL_VDD_180;
1929f2119df6SArindam Nath 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1930f2119df6SArindam Nath 
19319d967a61SVincent Yang 		/* Some controller need to do more when switching */
19329d967a61SVincent Yang 		if (host->ops->voltage_switch)
19339d967a61SVincent Yang 			host->ops->voltage_switch(host);
19349d967a61SVincent Yang 
193520b92a30SKevin Liu 		/* 1.8V regulator output should be stable within 5 ms */
1936f2119df6SArindam Nath 		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
193720b92a30SKevin Liu 		if (ctrl & SDHCI_CTRL_VDD_180)
1938f2119df6SArindam Nath 			return 0;
1939f2119df6SArindam Nath 
19406606110dSJoe Perches 		pr_warn("%s: 1.8V regulator output did not became stable\n",
19414e743f1fSMarkus Mayer 			mmc_hostname(mmc));
19426231f3deSPhilip Rakity 
1943f2119df6SArindam Nath 		return -EAGAIN;
194420b92a30SKevin Liu 	case MMC_SIGNAL_VOLTAGE_120:
19458cb851a4SAdrian Hunter 		if (!(host->flags & SDHCI_SIGNALING_120))
19468cb851a4SAdrian Hunter 			return -EINVAL;
19473a48edc4STim Kryger 		if (!IS_ERR(mmc->supply.vqmmc)) {
1948761daa36SDong Aisheng 			ret = mmc_regulator_set_vqmmc(mmc, ios);
194920b92a30SKevin Liu 			if (ret) {
19506606110dSJoe Perches 				pr_warn("%s: Switching to 1.2V signalling voltage failed\n",
19516606110dSJoe Perches 					mmc_hostname(mmc));
195220b92a30SKevin Liu 				return -EIO;
19536231f3deSPhilip Rakity 			}
195420b92a30SKevin Liu 		}
19556231f3deSPhilip Rakity 		return 0;
195620b92a30SKevin Liu 	default:
1957f2119df6SArindam Nath 		/* No signal voltage switch required */
1958f2119df6SArindam Nath 		return 0;
1959f2119df6SArindam Nath 	}
196020b92a30SKevin Liu }
1961c376ea9eSHu Ziji EXPORT_SYMBOL_GPL(sdhci_start_signal_voltage_switch);
1962f2119df6SArindam Nath 
196320b92a30SKevin Liu static int sdhci_card_busy(struct mmc_host *mmc)
196420b92a30SKevin Liu {
196520b92a30SKevin Liu 	struct sdhci_host *host = mmc_priv(mmc);
196620b92a30SKevin Liu 	u32 present_state;
196720b92a30SKevin Liu 
1968e613cc47SAdrian Hunter 	/* Check whether DAT[0] is 0 */
196920b92a30SKevin Liu 	present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
197020b92a30SKevin Liu 
1971e613cc47SAdrian Hunter 	return !(present_state & SDHCI_DATA_0_LVL_MASK);
197220b92a30SKevin Liu }
197320b92a30SKevin Liu 
1974b5540ce1SAdrian Hunter static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
1975b5540ce1SAdrian Hunter {
1976b5540ce1SAdrian Hunter 	struct sdhci_host *host = mmc_priv(mmc);
1977b5540ce1SAdrian Hunter 	unsigned long flags;
1978b5540ce1SAdrian Hunter 
1979b5540ce1SAdrian Hunter 	spin_lock_irqsave(&host->lock, flags);
1980b5540ce1SAdrian Hunter 	host->flags |= SDHCI_HS400_TUNING;
1981b5540ce1SAdrian Hunter 	spin_unlock_irqrestore(&host->lock, flags);
1982b5540ce1SAdrian Hunter 
1983b5540ce1SAdrian Hunter 	return 0;
1984b5540ce1SAdrian Hunter }
1985b5540ce1SAdrian Hunter 
1986da4bc4f2SAdrian Hunter static void sdhci_start_tuning(struct sdhci_host *host)
1987da4bc4f2SAdrian Hunter {
1988da4bc4f2SAdrian Hunter 	u16 ctrl;
1989da4bc4f2SAdrian Hunter 
1990da4bc4f2SAdrian Hunter 	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1991da4bc4f2SAdrian Hunter 	ctrl |= SDHCI_CTRL_EXEC_TUNING;
1992da4bc4f2SAdrian Hunter 	if (host->quirks2 & SDHCI_QUIRK2_TUNING_WORK_AROUND)
1993da4bc4f2SAdrian Hunter 		ctrl |= SDHCI_CTRL_TUNED_CLK;
1994da4bc4f2SAdrian Hunter 	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1995da4bc4f2SAdrian Hunter 
1996da4bc4f2SAdrian Hunter 	/*
1997da4bc4f2SAdrian Hunter 	 * As per the Host Controller spec v3.00, tuning command
1998da4bc4f2SAdrian Hunter 	 * generates Buffer Read Ready interrupt, so enable that.
1999da4bc4f2SAdrian Hunter 	 *
2000da4bc4f2SAdrian Hunter 	 * Note: The spec clearly says that when tuning sequence
2001da4bc4f2SAdrian Hunter 	 * is being performed, the controller does not generate
2002da4bc4f2SAdrian Hunter 	 * interrupts other than Buffer Read Ready interrupt. But
2003da4bc4f2SAdrian Hunter 	 * to make sure we don't hit a controller bug, we _only_
2004da4bc4f2SAdrian Hunter 	 * enable Buffer Read Ready interrupt here.
2005da4bc4f2SAdrian Hunter 	 */
2006da4bc4f2SAdrian Hunter 	sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
2007da4bc4f2SAdrian Hunter 	sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
2008da4bc4f2SAdrian Hunter }
2009da4bc4f2SAdrian Hunter 
2010da4bc4f2SAdrian Hunter static void sdhci_end_tuning(struct sdhci_host *host)
2011da4bc4f2SAdrian Hunter {
2012da4bc4f2SAdrian Hunter 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
2013da4bc4f2SAdrian Hunter 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
2014da4bc4f2SAdrian Hunter }
2015da4bc4f2SAdrian Hunter 
2016da4bc4f2SAdrian Hunter static void sdhci_reset_tuning(struct sdhci_host *host)
2017da4bc4f2SAdrian Hunter {
2018da4bc4f2SAdrian Hunter 	u16 ctrl;
2019da4bc4f2SAdrian Hunter 
2020da4bc4f2SAdrian Hunter 	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
2021da4bc4f2SAdrian Hunter 	ctrl &= ~SDHCI_CTRL_TUNED_CLK;
2022da4bc4f2SAdrian Hunter 	ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
2023da4bc4f2SAdrian Hunter 	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
2024da4bc4f2SAdrian Hunter }
2025da4bc4f2SAdrian Hunter 
20262a85ef25SAdrian Hunter static void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode)
2027da4bc4f2SAdrian Hunter {
2028da4bc4f2SAdrian Hunter 	sdhci_reset_tuning(host);
2029da4bc4f2SAdrian Hunter 
2030da4bc4f2SAdrian Hunter 	sdhci_do_reset(host, SDHCI_RESET_CMD);
2031da4bc4f2SAdrian Hunter 	sdhci_do_reset(host, SDHCI_RESET_DATA);
2032da4bc4f2SAdrian Hunter 
2033da4bc4f2SAdrian Hunter 	sdhci_end_tuning(host);
2034da4bc4f2SAdrian Hunter 
2035da4bc4f2SAdrian Hunter 	mmc_abort_tuning(host->mmc, opcode);
2036da4bc4f2SAdrian Hunter }
2037da4bc4f2SAdrian Hunter 
2038da4bc4f2SAdrian Hunter /*
2039da4bc4f2SAdrian Hunter  * We use sdhci_send_tuning() because mmc_send_tuning() is not a good fit. SDHCI
2040da4bc4f2SAdrian Hunter  * tuning command does not have a data payload (or rather the hardware does it
2041da4bc4f2SAdrian Hunter  * automatically) so mmc_send_tuning() will return -EIO. Also the tuning command
2042da4bc4f2SAdrian Hunter  * interrupt setup is different to other commands and there is no timeout
2043da4bc4f2SAdrian Hunter  * interrupt so special handling is needed.
2044da4bc4f2SAdrian Hunter  */
20452a85ef25SAdrian Hunter static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
2046da4bc4f2SAdrian Hunter {
2047da4bc4f2SAdrian Hunter 	struct mmc_host *mmc = host->mmc;
2048c7836d15SMasahiro Yamada 	struct mmc_command cmd = {};
2049c7836d15SMasahiro Yamada 	struct mmc_request mrq = {};
20502a85ef25SAdrian Hunter 	unsigned long flags;
2051c846a00fSSrinivas Kandagatla 	u32 b = host->sdma_boundary;
20522a85ef25SAdrian Hunter 
20532a85ef25SAdrian Hunter 	spin_lock_irqsave(&host->lock, flags);
2054da4bc4f2SAdrian Hunter 
2055da4bc4f2SAdrian Hunter 	cmd.opcode = opcode;
2056da4bc4f2SAdrian Hunter 	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
2057da4bc4f2SAdrian Hunter 	cmd.mrq = &mrq;
2058da4bc4f2SAdrian Hunter 
2059da4bc4f2SAdrian Hunter 	mrq.cmd = &cmd;
2060da4bc4f2SAdrian Hunter 	/*
2061da4bc4f2SAdrian Hunter 	 * In response to CMD19, the card sends 64 bytes of tuning
2062da4bc4f2SAdrian Hunter 	 * block to the Host Controller. So we set the block size
2063da4bc4f2SAdrian Hunter 	 * to 64 here.
2064da4bc4f2SAdrian Hunter 	 */
206585336109SAdrian Hunter 	if (cmd.opcode == MMC_SEND_TUNING_BLOCK_HS200 &&
206685336109SAdrian Hunter 	    mmc->ios.bus_width == MMC_BUS_WIDTH_8)
2067c846a00fSSrinivas Kandagatla 		sdhci_writew(host, SDHCI_MAKE_BLKSZ(b, 128), SDHCI_BLOCK_SIZE);
206885336109SAdrian Hunter 	else
2069c846a00fSSrinivas Kandagatla 		sdhci_writew(host, SDHCI_MAKE_BLKSZ(b, 64), SDHCI_BLOCK_SIZE);
2070da4bc4f2SAdrian Hunter 
2071da4bc4f2SAdrian Hunter 	/*
2072da4bc4f2SAdrian Hunter 	 * The tuning block is sent by the card to the host controller.
2073da4bc4f2SAdrian Hunter 	 * So we set the TRNS_READ bit in the Transfer Mode register.
2074da4bc4f2SAdrian Hunter 	 * This also takes care of setting DMA Enable and Multi Block
2075da4bc4f2SAdrian Hunter 	 * Select in the same register to 0.
2076da4bc4f2SAdrian Hunter 	 */
2077da4bc4f2SAdrian Hunter 	sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
2078da4bc4f2SAdrian Hunter 
2079da4bc4f2SAdrian Hunter 	sdhci_send_command(host, &cmd);
2080da4bc4f2SAdrian Hunter 
2081da4bc4f2SAdrian Hunter 	host->cmd = NULL;
2082da4bc4f2SAdrian Hunter 
2083da4bc4f2SAdrian Hunter 	sdhci_del_timer(host, &mrq);
2084da4bc4f2SAdrian Hunter 
2085da4bc4f2SAdrian Hunter 	host->tuning_done = 0;
2086da4bc4f2SAdrian Hunter 
20872a85ef25SAdrian Hunter 	mmiowb();
2088da4bc4f2SAdrian Hunter 	spin_unlock_irqrestore(&host->lock, flags);
2089da4bc4f2SAdrian Hunter 
2090da4bc4f2SAdrian Hunter 	/* Wait for Buffer Read Ready interrupt */
2091da4bc4f2SAdrian Hunter 	wait_event_timeout(host->buf_ready_int, (host->tuning_done == 1),
2092da4bc4f2SAdrian Hunter 			   msecs_to_jiffies(50));
2093da4bc4f2SAdrian Hunter 
2094da4bc4f2SAdrian Hunter }
2095da4bc4f2SAdrian Hunter 
20962a85ef25SAdrian Hunter static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
20976b11e70bSAdrian Hunter {
20986b11e70bSAdrian Hunter 	int i;
20996b11e70bSAdrian Hunter 
21006b11e70bSAdrian Hunter 	/*
21016b11e70bSAdrian Hunter 	 * Issue opcode repeatedly till Execute Tuning is set to 0 or the number
21026b11e70bSAdrian Hunter 	 * of loops reaches 40 times.
21036b11e70bSAdrian Hunter 	 */
21046b11e70bSAdrian Hunter 	for (i = 0; i < MAX_TUNING_LOOP; i++) {
21056b11e70bSAdrian Hunter 		u16 ctrl;
21066b11e70bSAdrian Hunter 
21072a85ef25SAdrian Hunter 		sdhci_send_tuning(host, opcode);
21086b11e70bSAdrian Hunter 
21096b11e70bSAdrian Hunter 		if (!host->tuning_done) {
21106b11e70bSAdrian Hunter 			pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n",
21116b11e70bSAdrian Hunter 				mmc_hostname(host->mmc));
21122a85ef25SAdrian Hunter 			sdhci_abort_tuning(host, opcode);
21136b11e70bSAdrian Hunter 			return;
21146b11e70bSAdrian Hunter 		}
21156b11e70bSAdrian Hunter 
21166b11e70bSAdrian Hunter 		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
21176b11e70bSAdrian Hunter 		if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) {
21186b11e70bSAdrian Hunter 			if (ctrl & SDHCI_CTRL_TUNED_CLK)
21196b11e70bSAdrian Hunter 				return; /* Success! */
21206b11e70bSAdrian Hunter 			break;
21216b11e70bSAdrian Hunter 		}
21226b11e70bSAdrian Hunter 
212383b600b8SAdrian Hunter 		/* Spec does not require a delay between tuning cycles */
212483b600b8SAdrian Hunter 		if (host->tuning_delay > 0)
212583b600b8SAdrian Hunter 			mdelay(host->tuning_delay);
21266b11e70bSAdrian Hunter 	}
21276b11e70bSAdrian Hunter 
21286b11e70bSAdrian Hunter 	pr_info("%s: Tuning failed, falling back to fixed sampling clock\n",
21296b11e70bSAdrian Hunter 		mmc_hostname(host->mmc));
21306b11e70bSAdrian Hunter 	sdhci_reset_tuning(host);
21316b11e70bSAdrian Hunter }
21326b11e70bSAdrian Hunter 
213385a882c2SMasahiro Yamada int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
2134b513ea25SArindam Nath {
21354b6f37d3SRussell King 	struct sdhci_host *host = mmc_priv(mmc);
2136b513ea25SArindam Nath 	int err = 0;
213738e40bf5SAdrian Hunter 	unsigned int tuning_count = 0;
2138b5540ce1SAdrian Hunter 	bool hs400_tuning;
2139b513ea25SArindam Nath 
2140b5540ce1SAdrian Hunter 	hs400_tuning = host->flags & SDHCI_HS400_TUNING;
2141b5540ce1SAdrian Hunter 
214238e40bf5SAdrian Hunter 	if (host->tuning_mode == SDHCI_TUNING_MODE_1)
214338e40bf5SAdrian Hunter 		tuning_count = host->tuning_count;
214438e40bf5SAdrian Hunter 
2145b513ea25SArindam Nath 	/*
21469faac7b9SWeijun Yang 	 * The Host Controller needs tuning in case of SDR104 and DDR50
21479faac7b9SWeijun Yang 	 * mode, and for SDR50 mode when Use Tuning for SDR50 is set in
21489faac7b9SWeijun Yang 	 * the Capabilities register.
2149069c9f14SGirish K S 	 * If the Host Controller supports the HS200 mode then the
2150069c9f14SGirish K S 	 * tuning function has to be executed.
2151b513ea25SArindam Nath 	 */
21524b6f37d3SRussell King 	switch (host->timing) {
2153b5540ce1SAdrian Hunter 	/* HS400 tuning is done in HS200 mode */
2154e9fb05d5SAdrian Hunter 	case MMC_TIMING_MMC_HS400:
2155b5540ce1SAdrian Hunter 		err = -EINVAL;
21562a85ef25SAdrian Hunter 		goto out;
2157b5540ce1SAdrian Hunter 
21584b6f37d3SRussell King 	case MMC_TIMING_MMC_HS200:
2159b5540ce1SAdrian Hunter 		/*
2160b5540ce1SAdrian Hunter 		 * Periodic re-tuning for HS400 is not expected to be needed, so
2161b5540ce1SAdrian Hunter 		 * disable it here.
2162b5540ce1SAdrian Hunter 		 */
2163b5540ce1SAdrian Hunter 		if (hs400_tuning)
2164b5540ce1SAdrian Hunter 			tuning_count = 0;
2165b5540ce1SAdrian Hunter 		break;
2166b5540ce1SAdrian Hunter 
21674b6f37d3SRussell King 	case MMC_TIMING_UHS_SDR104:
21689faac7b9SWeijun Yang 	case MMC_TIMING_UHS_DDR50:
21694b6f37d3SRussell King 		break;
2170069c9f14SGirish K S 
21714b6f37d3SRussell King 	case MMC_TIMING_UHS_SDR50:
21724228b213SAdrian Hunter 		if (host->flags & SDHCI_SDR50_NEEDS_TUNING)
21734b6f37d3SRussell King 			break;
21744b6f37d3SRussell King 		/* FALLTHROUGH */
21754b6f37d3SRussell King 
21764b6f37d3SRussell King 	default:
21772a85ef25SAdrian Hunter 		goto out;
2178b513ea25SArindam Nath 	}
2179b513ea25SArindam Nath 
218045251812SDong Aisheng 	if (host->ops->platform_execute_tuning) {
21818a8fa879SRitesh Harjani 		err = host->ops->platform_execute_tuning(host, opcode);
21822a85ef25SAdrian Hunter 		goto out;
218345251812SDong Aisheng 	}
218445251812SDong Aisheng 
21856b11e70bSAdrian Hunter 	host->mmc->retune_period = tuning_count;
21866b11e70bSAdrian Hunter 
218783b600b8SAdrian Hunter 	if (host->tuning_delay < 0)
218883b600b8SAdrian Hunter 		host->tuning_delay = opcode == MMC_SEND_TUNING_BLOCK;
218983b600b8SAdrian Hunter 
2190da4bc4f2SAdrian Hunter 	sdhci_start_tuning(host);
2191b513ea25SArindam Nath 
21922a85ef25SAdrian Hunter 	__sdhci_execute_tuning(host, opcode);
2193cf2b5eeaSArindam Nath 
2194da4bc4f2SAdrian Hunter 	sdhci_end_tuning(host);
21952a85ef25SAdrian Hunter out:
21968a8fa879SRitesh Harjani 	host->flags &= ~SDHCI_HS400_TUNING;
21976b11e70bSAdrian Hunter 
2198b513ea25SArindam Nath 	return err;
2199b513ea25SArindam Nath }
220085a882c2SMasahiro Yamada EXPORT_SYMBOL_GPL(sdhci_execute_tuning);
2201b513ea25SArindam Nath 
220252983382SKevin Liu static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
22034d55c5a1SArindam Nath {
22044d55c5a1SArindam Nath 	/* Host Controller v3.00 defines preset value registers */
22054d55c5a1SArindam Nath 	if (host->version < SDHCI_SPEC_300)
22064d55c5a1SArindam Nath 		return;
22074d55c5a1SArindam Nath 
22084d55c5a1SArindam Nath 	/*
22094d55c5a1SArindam Nath 	 * We only enable or disable Preset Value if they are not already
22104d55c5a1SArindam Nath 	 * enabled or disabled respectively. Otherwise, we bail out.
22114d55c5a1SArindam Nath 	 */
2212da91a8f9SRussell King 	if (host->preset_enabled != enable) {
2213da91a8f9SRussell King 		u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
2214da91a8f9SRussell King 
2215da91a8f9SRussell King 		if (enable)
22164d55c5a1SArindam Nath 			ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
2217da91a8f9SRussell King 		else
22184d55c5a1SArindam Nath 			ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
2219da91a8f9SRussell King 
22204d55c5a1SArindam Nath 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
2221da91a8f9SRussell King 
2222da91a8f9SRussell King 		if (enable)
2223da91a8f9SRussell King 			host->flags |= SDHCI_PV_ENABLED;
2224da91a8f9SRussell King 		else
222566fd8ad5SAdrian Hunter 			host->flags &= ~SDHCI_PV_ENABLED;
2226da91a8f9SRussell King 
2227da91a8f9SRussell King 		host->preset_enabled = enable;
22284d55c5a1SArindam Nath 	}
222966fd8ad5SAdrian Hunter }
223066fd8ad5SAdrian Hunter 
2231348487cbSHaibo Chen static void sdhci_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
2232348487cbSHaibo Chen 				int err)
2233348487cbSHaibo Chen {
2234348487cbSHaibo Chen 	struct sdhci_host *host = mmc_priv(mmc);
2235348487cbSHaibo Chen 	struct mmc_data *data = mrq->data;
2236348487cbSHaibo Chen 
2237f48f039cSRussell King 	if (data->host_cookie != COOKIE_UNMAPPED)
2238348487cbSHaibo Chen 		dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
2239feeef096SHeiner Kallweit 			     mmc_get_dma_dir(data));
2240771a3dc2SRussell King 
2241d31911b9SHaibo Chen 	data->host_cookie = COOKIE_UNMAPPED;
2242348487cbSHaibo Chen }
2243348487cbSHaibo Chen 
2244d3c6aac3SLinus Walleij static void sdhci_pre_req(struct mmc_host *mmc, struct mmc_request *mrq)
2245348487cbSHaibo Chen {
2246348487cbSHaibo Chen 	struct sdhci_host *host = mmc_priv(mmc);
2247348487cbSHaibo Chen 
2248d31911b9SHaibo Chen 	mrq->data->host_cookie = COOKIE_UNMAPPED;
2249348487cbSHaibo Chen 
2250348487cbSHaibo Chen 	if (host->flags & SDHCI_REQ_USE_DMA)
225194538e51SRussell King 		sdhci_pre_dma_transfer(host, mrq->data, COOKIE_PRE_MAPPED);
2252348487cbSHaibo Chen }
2253348487cbSHaibo Chen 
22545d0d11c5SAdrian Hunter static inline bool sdhci_has_requests(struct sdhci_host *host)
22555d0d11c5SAdrian Hunter {
22565d0d11c5SAdrian Hunter 	return host->cmd || host->data_cmd;
22575d0d11c5SAdrian Hunter }
22585d0d11c5SAdrian Hunter 
22595d0d11c5SAdrian Hunter static void sdhci_error_out_mrqs(struct sdhci_host *host, int err)
22605d0d11c5SAdrian Hunter {
22615d0d11c5SAdrian Hunter 	if (host->data_cmd) {
22625d0d11c5SAdrian Hunter 		host->data_cmd->error = err;
22635d0d11c5SAdrian Hunter 		sdhci_finish_mrq(host, host->data_cmd->mrq);
22645d0d11c5SAdrian Hunter 	}
22655d0d11c5SAdrian Hunter 
22665d0d11c5SAdrian Hunter 	if (host->cmd) {
22675d0d11c5SAdrian Hunter 		host->cmd->error = err;
22685d0d11c5SAdrian Hunter 		sdhci_finish_mrq(host, host->cmd->mrq);
22695d0d11c5SAdrian Hunter 	}
22705d0d11c5SAdrian Hunter }
22715d0d11c5SAdrian Hunter 
227271e69211SGuennadi Liakhovetski static void sdhci_card_event(struct mmc_host *mmc)
22731c6a0718SPierre Ossman {
227471e69211SGuennadi Liakhovetski 	struct sdhci_host *host = mmc_priv(mmc);
22751c6a0718SPierre Ossman 	unsigned long flags;
22762836766aSKrzysztof Kozlowski 	int present;
22771c6a0718SPierre Ossman 
2278722e1280SChristian Daudt 	/* First check if client has provided their own card event */
2279722e1280SChristian Daudt 	if (host->ops->card_event)
2280722e1280SChristian Daudt 		host->ops->card_event(host);
2281722e1280SChristian Daudt 
2282d3940f27SAdrian Hunter 	present = mmc->ops->get_cd(mmc);
22832836766aSKrzysztof Kozlowski 
22841c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
22851c6a0718SPierre Ossman 
22865d0d11c5SAdrian Hunter 	/* Check sdhci_has_requests() first in case we are runtime suspended */
22875d0d11c5SAdrian Hunter 	if (sdhci_has_requests(host) && !present) {
2288a3c76eb9SGirish K S 		pr_err("%s: Card removed during transfer!\n",
22891c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
2290a3c76eb9SGirish K S 		pr_err("%s: Resetting controller.\n",
22911c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
22921c6a0718SPierre Ossman 
229303231f9bSRussell King 		sdhci_do_reset(host, SDHCI_RESET_CMD);
229403231f9bSRussell King 		sdhci_do_reset(host, SDHCI_RESET_DATA);
22951c6a0718SPierre Ossman 
22965d0d11c5SAdrian Hunter 		sdhci_error_out_mrqs(host, -ENOMEDIUM);
22971c6a0718SPierre Ossman 	}
22981c6a0718SPierre Ossman 
22991c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
230071e69211SGuennadi Liakhovetski }
230171e69211SGuennadi Liakhovetski 
230271e69211SGuennadi Liakhovetski static const struct mmc_host_ops sdhci_ops = {
230371e69211SGuennadi Liakhovetski 	.request	= sdhci_request,
2304348487cbSHaibo Chen 	.post_req	= sdhci_post_req,
2305348487cbSHaibo Chen 	.pre_req	= sdhci_pre_req,
230671e69211SGuennadi Liakhovetski 	.set_ios	= sdhci_set_ios,
230794144a46SKevin Liu 	.get_cd		= sdhci_get_cd,
230871e69211SGuennadi Liakhovetski 	.get_ro		= sdhci_get_ro,
230971e69211SGuennadi Liakhovetski 	.hw_reset	= sdhci_hw_reset,
231071e69211SGuennadi Liakhovetski 	.enable_sdio_irq = sdhci_enable_sdio_irq,
231171e69211SGuennadi Liakhovetski 	.start_signal_voltage_switch	= sdhci_start_signal_voltage_switch,
2312b5540ce1SAdrian Hunter 	.prepare_hs400_tuning		= sdhci_prepare_hs400_tuning,
231371e69211SGuennadi Liakhovetski 	.execute_tuning			= sdhci_execute_tuning,
231471e69211SGuennadi Liakhovetski 	.card_event			= sdhci_card_event,
231520b92a30SKevin Liu 	.card_busy	= sdhci_card_busy,
231671e69211SGuennadi Liakhovetski };
231771e69211SGuennadi Liakhovetski 
231871e69211SGuennadi Liakhovetski /*****************************************************************************\
231971e69211SGuennadi Liakhovetski  *                                                                           *
232071e69211SGuennadi Liakhovetski  * Tasklets                                                                  *
232171e69211SGuennadi Liakhovetski  *                                                                           *
232271e69211SGuennadi Liakhovetski \*****************************************************************************/
232371e69211SGuennadi Liakhovetski 
23244e9f8fe5SAdrian Hunter static bool sdhci_request_done(struct sdhci_host *host)
23251c6a0718SPierre Ossman {
23261c6a0718SPierre Ossman 	unsigned long flags;
23271c6a0718SPierre Ossman 	struct mmc_request *mrq;
23284e9f8fe5SAdrian Hunter 	int i;
23291c6a0718SPierre Ossman 
233066fd8ad5SAdrian Hunter 	spin_lock_irqsave(&host->lock, flags);
233166fd8ad5SAdrian Hunter 
23324e9f8fe5SAdrian Hunter 	for (i = 0; i < SDHCI_MAX_MRQS; i++) {
23334e9f8fe5SAdrian Hunter 		mrq = host->mrqs_done[i];
23346ebebeabSAdrian Hunter 		if (mrq)
23354e9f8fe5SAdrian Hunter 			break;
23364e9f8fe5SAdrian Hunter 	}
23371c6a0718SPierre Ossman 
23384e9f8fe5SAdrian Hunter 	if (!mrq) {
23394e9f8fe5SAdrian Hunter 		spin_unlock_irqrestore(&host->lock, flags);
23404e9f8fe5SAdrian Hunter 		return true;
23414e9f8fe5SAdrian Hunter 	}
23421c6a0718SPierre Ossman 
2343d7422fb4SAdrian Hunter 	sdhci_del_timer(host, mrq);
2344d7422fb4SAdrian Hunter 
23451c6a0718SPierre Ossman 	/*
2346054cedffSRussell King 	 * Always unmap the data buffers if they were mapped by
2347054cedffSRussell King 	 * sdhci_prepare_data() whenever we finish with a request.
2348054cedffSRussell King 	 * This avoids leaking DMA mappings on error.
2349054cedffSRussell King 	 */
2350054cedffSRussell King 	if (host->flags & SDHCI_REQ_USE_DMA) {
2351054cedffSRussell King 		struct mmc_data *data = mrq->data;
2352054cedffSRussell King 
2353054cedffSRussell King 		if (data && data->host_cookie == COOKIE_MAPPED) {
2354054cedffSRussell King 			dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
2355feeef096SHeiner Kallweit 				     mmc_get_dma_dir(data));
2356054cedffSRussell King 			data->host_cookie = COOKIE_UNMAPPED;
2357054cedffSRussell King 		}
2358054cedffSRussell King 	}
2359054cedffSRussell King 
2360054cedffSRussell King 	/*
23611c6a0718SPierre Ossman 	 * The controller needs a reset of internal state machines
23621c6a0718SPierre Ossman 	 * upon error conditions.
23631c6a0718SPierre Ossman 	 */
23640cc563ceSAdrian Hunter 	if (sdhci_needs_reset(host, mrq)) {
23656ebebeabSAdrian Hunter 		/*
23666ebebeabSAdrian Hunter 		 * Do not finish until command and data lines are available for
23676ebebeabSAdrian Hunter 		 * reset. Note there can only be one other mrq, so it cannot
23686ebebeabSAdrian Hunter 		 * also be in mrqs_done, otherwise host->cmd and host->data_cmd
23696ebebeabSAdrian Hunter 		 * would both be null.
23706ebebeabSAdrian Hunter 		 */
23716ebebeabSAdrian Hunter 		if (host->cmd || host->data_cmd) {
23726ebebeabSAdrian Hunter 			spin_unlock_irqrestore(&host->lock, flags);
23736ebebeabSAdrian Hunter 			return true;
23746ebebeabSAdrian Hunter 		}
23756ebebeabSAdrian Hunter 
23761c6a0718SPierre Ossman 		/* Some controllers need this kick or reset won't work here */
23778213af3bSAndy Shevchenko 		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
23781c6a0718SPierre Ossman 			/* This is to force an update */
23791771059cSRussell King 			host->ops->set_clock(host, host->clock);
23801c6a0718SPierre Ossman 
23811c6a0718SPierre Ossman 		/* Spec says we should do both at the same time, but Ricoh
23821c6a0718SPierre Ossman 		   controllers do not like that. */
238303231f9bSRussell King 		sdhci_do_reset(host, SDHCI_RESET_CMD);
238403231f9bSRussell King 		sdhci_do_reset(host, SDHCI_RESET_DATA);
2385ed1563deSAdrian Hunter 
2386ed1563deSAdrian Hunter 		host->pending_reset = false;
23871c6a0718SPierre Ossman 	}
23881c6a0718SPierre Ossman 
23894e9f8fe5SAdrian Hunter 	if (!sdhci_has_requests(host))
2390061d17a6SAdrian Hunter 		sdhci_led_deactivate(host);
23911c6a0718SPierre Ossman 
23926ebebeabSAdrian Hunter 	host->mrqs_done[i] = NULL;
23936ebebeabSAdrian Hunter 
23941c6a0718SPierre Ossman 	mmiowb();
23951c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
23961c6a0718SPierre Ossman 
23971c6a0718SPierre Ossman 	mmc_request_done(host->mmc, mrq);
23984e9f8fe5SAdrian Hunter 
23994e9f8fe5SAdrian Hunter 	return false;
24004e9f8fe5SAdrian Hunter }
24014e9f8fe5SAdrian Hunter 
24024e9f8fe5SAdrian Hunter static void sdhci_tasklet_finish(unsigned long param)
24034e9f8fe5SAdrian Hunter {
24044e9f8fe5SAdrian Hunter 	struct sdhci_host *host = (struct sdhci_host *)param;
24054e9f8fe5SAdrian Hunter 
24064e9f8fe5SAdrian Hunter 	while (!sdhci_request_done(host))
24074e9f8fe5SAdrian Hunter 		;
24081c6a0718SPierre Ossman }
24091c6a0718SPierre Ossman 
24102ee4f620SKees Cook static void sdhci_timeout_timer(struct timer_list *t)
24111c6a0718SPierre Ossman {
24121c6a0718SPierre Ossman 	struct sdhci_host *host;
24131c6a0718SPierre Ossman 	unsigned long flags;
24141c6a0718SPierre Ossman 
24152ee4f620SKees Cook 	host = from_timer(host, t, timer);
24161c6a0718SPierre Ossman 
24171c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
24181c6a0718SPierre Ossman 
2419d7422fb4SAdrian Hunter 	if (host->cmd && !sdhci_data_line_cmd(host->cmd)) {
2420d7422fb4SAdrian Hunter 		pr_err("%s: Timeout waiting for hardware cmd interrupt.\n",
2421d7422fb4SAdrian Hunter 		       mmc_hostname(host->mmc));
2422d7422fb4SAdrian Hunter 		sdhci_dumpregs(host);
2423d7422fb4SAdrian Hunter 
2424d7422fb4SAdrian Hunter 		host->cmd->error = -ETIMEDOUT;
2425d7422fb4SAdrian Hunter 		sdhci_finish_mrq(host, host->cmd->mrq);
2426d7422fb4SAdrian Hunter 	}
2427d7422fb4SAdrian Hunter 
2428d7422fb4SAdrian Hunter 	mmiowb();
2429d7422fb4SAdrian Hunter 	spin_unlock_irqrestore(&host->lock, flags);
2430d7422fb4SAdrian Hunter }
2431d7422fb4SAdrian Hunter 
24322ee4f620SKees Cook static void sdhci_timeout_data_timer(struct timer_list *t)
2433d7422fb4SAdrian Hunter {
2434d7422fb4SAdrian Hunter 	struct sdhci_host *host;
2435d7422fb4SAdrian Hunter 	unsigned long flags;
2436d7422fb4SAdrian Hunter 
24372ee4f620SKees Cook 	host = from_timer(host, t, data_timer);
2438d7422fb4SAdrian Hunter 
2439d7422fb4SAdrian Hunter 	spin_lock_irqsave(&host->lock, flags);
2440d7422fb4SAdrian Hunter 
2441d7422fb4SAdrian Hunter 	if (host->data || host->data_cmd ||
2442d7422fb4SAdrian Hunter 	    (host->cmd && sdhci_data_line_cmd(host->cmd))) {
24432e4456f0SMarek Vasut 		pr_err("%s: Timeout waiting for hardware interrupt.\n",
24442e4456f0SMarek Vasut 		       mmc_hostname(host->mmc));
24451c6a0718SPierre Ossman 		sdhci_dumpregs(host);
24461c6a0718SPierre Ossman 
24471c6a0718SPierre Ossman 		if (host->data) {
244817b0429dSPierre Ossman 			host->data->error = -ETIMEDOUT;
24491c6a0718SPierre Ossman 			sdhci_finish_data(host);
2450d7422fb4SAdrian Hunter 		} else if (host->data_cmd) {
2451d7422fb4SAdrian Hunter 			host->data_cmd->error = -ETIMEDOUT;
2452d7422fb4SAdrian Hunter 			sdhci_finish_mrq(host, host->data_cmd->mrq);
24531c6a0718SPierre Ossman 		} else {
245417b0429dSPierre Ossman 			host->cmd->error = -ETIMEDOUT;
2455d7422fb4SAdrian Hunter 			sdhci_finish_mrq(host, host->cmd->mrq);
24561c6a0718SPierre Ossman 		}
24571c6a0718SPierre Ossman 	}
24581c6a0718SPierre Ossman 
24591c6a0718SPierre Ossman 	mmiowb();
24601c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
24611c6a0718SPierre Ossman }
24621c6a0718SPierre Ossman 
24631c6a0718SPierre Ossman /*****************************************************************************\
24641c6a0718SPierre Ossman  *                                                                           *
24651c6a0718SPierre Ossman  * Interrupt handling                                                        *
24661c6a0718SPierre Ossman  *                                                                           *
24671c6a0718SPierre Ossman \*****************************************************************************/
24681c6a0718SPierre Ossman 
2469fc605f1dSAdrian Hunter static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
24701c6a0718SPierre Ossman {
24711c6a0718SPierre Ossman 	if (!host->cmd) {
2472ed1563deSAdrian Hunter 		/*
2473ed1563deSAdrian Hunter 		 * SDHCI recovers from errors by resetting the cmd and data
2474ed1563deSAdrian Hunter 		 * circuits.  Until that is done, there very well might be more
2475ed1563deSAdrian Hunter 		 * interrupts, so ignore them in that case.
2476ed1563deSAdrian Hunter 		 */
2477ed1563deSAdrian Hunter 		if (host->pending_reset)
2478ed1563deSAdrian Hunter 			return;
24792e4456f0SMarek Vasut 		pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n",
2480b67ac3f3SPierre Ossman 		       mmc_hostname(host->mmc), (unsigned)intmask);
24811c6a0718SPierre Ossman 		sdhci_dumpregs(host);
24821c6a0718SPierre Ossman 		return;
24831c6a0718SPierre Ossman 	}
24841c6a0718SPierre Ossman 
2485ec014cbaSRussell King 	if (intmask & (SDHCI_INT_TIMEOUT | SDHCI_INT_CRC |
2486ec014cbaSRussell King 		       SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) {
24871c6a0718SPierre Ossman 		if (intmask & SDHCI_INT_TIMEOUT)
248817b0429dSPierre Ossman 			host->cmd->error = -ETIMEDOUT;
2489ec014cbaSRussell King 		else
249017b0429dSPierre Ossman 			host->cmd->error = -EILSEQ;
24911c6a0718SPierre Ossman 
249271fcbda0SRussell King 		/*
249371fcbda0SRussell King 		 * If this command initiates a data phase and a response
249471fcbda0SRussell King 		 * CRC error is signalled, the card can start transferring
249571fcbda0SRussell King 		 * data - the card may have received the command without
249671fcbda0SRussell King 		 * error.  We must not terminate the mmc_request early.
249771fcbda0SRussell King 		 *
249871fcbda0SRussell King 		 * If the card did not receive the command or returned an
249971fcbda0SRussell King 		 * error which prevented it sending data, the data phase
250071fcbda0SRussell King 		 * will time out.
250171fcbda0SRussell King 		 */
250271fcbda0SRussell King 		if (host->cmd->data &&
250371fcbda0SRussell King 		    (intmask & (SDHCI_INT_CRC | SDHCI_INT_TIMEOUT)) ==
250471fcbda0SRussell King 		     SDHCI_INT_CRC) {
250571fcbda0SRussell King 			host->cmd = NULL;
250671fcbda0SRussell King 			return;
250771fcbda0SRussell King 		}
250871fcbda0SRussell King 
2509a6d3bdd5SAdrian Hunter 		sdhci_finish_mrq(host, host->cmd->mrq);
2510e809517fSPierre Ossman 		return;
2511e809517fSPierre Ossman 	}
2512e809517fSPierre Ossman 
2513e809517fSPierre Ossman 	if (intmask & SDHCI_INT_RESPONSE)
251443b58b36SPierre Ossman 		sdhci_finish_command(host);
25151c6a0718SPierre Ossman }
25161c6a0718SPierre Ossman 
251708621b18SAdrian Hunter static void sdhci_adma_show_error(struct sdhci_host *host)
25186882a8c0SBen Dooks {
25191c3d5f6dSAdrian Hunter 	void *desc = host->adma_table;
25206882a8c0SBen Dooks 
25216882a8c0SBen Dooks 	sdhci_dumpregs(host);
25226882a8c0SBen Dooks 
25236882a8c0SBen Dooks 	while (true) {
2524e57a5f61SAdrian Hunter 		struct sdhci_adma2_64_desc *dma_desc = desc;
25256882a8c0SBen Dooks 
2526e57a5f61SAdrian Hunter 		if (host->flags & SDHCI_USE_64_BIT_DMA)
2527f421865dSAdrian Hunter 			DBG("%p: DMA 0x%08x%08x, LEN 0x%04x, Attr=0x%02x\n",
2528f421865dSAdrian Hunter 			    desc, le32_to_cpu(dma_desc->addr_hi),
2529e57a5f61SAdrian Hunter 			    le32_to_cpu(dma_desc->addr_lo),
2530e57a5f61SAdrian Hunter 			    le16_to_cpu(dma_desc->len),
2531e57a5f61SAdrian Hunter 			    le16_to_cpu(dma_desc->cmd));
2532e57a5f61SAdrian Hunter 		else
2533f421865dSAdrian Hunter 			DBG("%p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n",
2534f421865dSAdrian Hunter 			    desc, le32_to_cpu(dma_desc->addr_lo),
25350545230fSAdrian Hunter 			    le16_to_cpu(dma_desc->len),
25360545230fSAdrian Hunter 			    le16_to_cpu(dma_desc->cmd));
25376882a8c0SBen Dooks 
253876fe379aSAdrian Hunter 		desc += host->desc_sz;
25396882a8c0SBen Dooks 
25400545230fSAdrian Hunter 		if (dma_desc->cmd & cpu_to_le16(ADMA2_END))
25416882a8c0SBen Dooks 			break;
25426882a8c0SBen Dooks 	}
25436882a8c0SBen Dooks }
25446882a8c0SBen Dooks 
25451c6a0718SPierre Ossman static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
25461c6a0718SPierre Ossman {
2547069c9f14SGirish K S 	u32 command;
25481c6a0718SPierre Ossman 
2549b513ea25SArindam Nath 	/* CMD19 generates _only_ Buffer Read Ready interrupt */
2550b513ea25SArindam Nath 	if (intmask & SDHCI_INT_DATA_AVAIL) {
2551069c9f14SGirish K S 		command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND));
2552069c9f14SGirish K S 		if (command == MMC_SEND_TUNING_BLOCK ||
2553069c9f14SGirish K S 		    command == MMC_SEND_TUNING_BLOCK_HS200) {
2554b513ea25SArindam Nath 			host->tuning_done = 1;
2555b513ea25SArindam Nath 			wake_up(&host->buf_ready_int);
2556b513ea25SArindam Nath 			return;
2557b513ea25SArindam Nath 		}
2558b513ea25SArindam Nath 	}
2559b513ea25SArindam Nath 
25601c6a0718SPierre Ossman 	if (!host->data) {
25617c89a3d9SAdrian Hunter 		struct mmc_command *data_cmd = host->data_cmd;
25627c89a3d9SAdrian Hunter 
25631c6a0718SPierre Ossman 		/*
2564e809517fSPierre Ossman 		 * The "data complete" interrupt is also used to
2565e809517fSPierre Ossman 		 * indicate that a busy state has ended. See comment
2566e809517fSPierre Ossman 		 * above in sdhci_cmd_irq().
25671c6a0718SPierre Ossman 		 */
25687c89a3d9SAdrian Hunter 		if (data_cmd && (data_cmd->flags & MMC_RSP_BUSY)) {
2569c5abd5e8SMatthieu CASTET 			if (intmask & SDHCI_INT_DATA_TIMEOUT) {
257069b962a6SAdrian Hunter 				host->data_cmd = NULL;
25717c89a3d9SAdrian Hunter 				data_cmd->error = -ETIMEDOUT;
2572a6d3bdd5SAdrian Hunter 				sdhci_finish_mrq(host, data_cmd->mrq);
2573c5abd5e8SMatthieu CASTET 				return;
2574c5abd5e8SMatthieu CASTET 			}
2575e809517fSPierre Ossman 			if (intmask & SDHCI_INT_DATA_END) {
257669b962a6SAdrian Hunter 				host->data_cmd = NULL;
2577e99783a4SChanho Min 				/*
2578e99783a4SChanho Min 				 * Some cards handle busy-end interrupt
2579e99783a4SChanho Min 				 * before the command completed, so make
2580e99783a4SChanho Min 				 * sure we do things in the proper order.
2581e99783a4SChanho Min 				 */
2582ea968023SAdrian Hunter 				if (host->cmd == data_cmd)
2583ea968023SAdrian Hunter 					return;
2584ea968023SAdrian Hunter 
2585a6d3bdd5SAdrian Hunter 				sdhci_finish_mrq(host, data_cmd->mrq);
25861c6a0718SPierre Ossman 				return;
2587e809517fSPierre Ossman 			}
2588e809517fSPierre Ossman 		}
25891c6a0718SPierre Ossman 
2590ed1563deSAdrian Hunter 		/*
2591ed1563deSAdrian Hunter 		 * SDHCI recovers from errors by resetting the cmd and data
2592ed1563deSAdrian Hunter 		 * circuits. Until that is done, there very well might be more
2593ed1563deSAdrian Hunter 		 * interrupts, so ignore them in that case.
2594ed1563deSAdrian Hunter 		 */
2595ed1563deSAdrian Hunter 		if (host->pending_reset)
2596ed1563deSAdrian Hunter 			return;
2597ed1563deSAdrian Hunter 
25982e4456f0SMarek Vasut 		pr_err("%s: Got data interrupt 0x%08x even though no data operation was in progress.\n",
2599b67ac3f3SPierre Ossman 		       mmc_hostname(host->mmc), (unsigned)intmask);
26001c6a0718SPierre Ossman 		sdhci_dumpregs(host);
26011c6a0718SPierre Ossman 
26021c6a0718SPierre Ossman 		return;
26031c6a0718SPierre Ossman 	}
26041c6a0718SPierre Ossman 
26051c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_DATA_TIMEOUT)
260617b0429dSPierre Ossman 		host->data->error = -ETIMEDOUT;
260722113efdSAries Lee 	else if (intmask & SDHCI_INT_DATA_END_BIT)
260822113efdSAries Lee 		host->data->error = -EILSEQ;
260922113efdSAries Lee 	else if ((intmask & SDHCI_INT_DATA_CRC) &&
261022113efdSAries Lee 		SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))
261122113efdSAries Lee 			!= MMC_BUS_TEST_R)
261217b0429dSPierre Ossman 		host->data->error = -EILSEQ;
26136882a8c0SBen Dooks 	else if (intmask & SDHCI_INT_ADMA_ERROR) {
2614a3c76eb9SGirish K S 		pr_err("%s: ADMA error\n", mmc_hostname(host->mmc));
261508621b18SAdrian Hunter 		sdhci_adma_show_error(host);
26162134a922SPierre Ossman 		host->data->error = -EIO;
2617a4071fbbSHaijun Zhang 		if (host->ops->adma_workaround)
2618a4071fbbSHaijun Zhang 			host->ops->adma_workaround(host, intmask);
26196882a8c0SBen Dooks 	}
26201c6a0718SPierre Ossman 
262117b0429dSPierre Ossman 	if (host->data->error)
26221c6a0718SPierre Ossman 		sdhci_finish_data(host);
26231c6a0718SPierre Ossman 	else {
26241c6a0718SPierre Ossman 		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
26251c6a0718SPierre Ossman 			sdhci_transfer_pio(host);
26261c6a0718SPierre Ossman 
26276ba736a1SPierre Ossman 		/*
26286ba736a1SPierre Ossman 		 * We currently don't do anything fancy with DMA
26296ba736a1SPierre Ossman 		 * boundaries, but as we can't disable the feature
26306ba736a1SPierre Ossman 		 * we need to at least restart the transfer.
2631f6a03cbfSMikko Vinni 		 *
2632f6a03cbfSMikko Vinni 		 * According to the spec sdhci_readl(host, SDHCI_DMA_ADDRESS)
2633f6a03cbfSMikko Vinni 		 * should return a valid address to continue from, but as
2634f6a03cbfSMikko Vinni 		 * some controllers are faulty, don't trust them.
26356ba736a1SPierre Ossman 		 */
2636f6a03cbfSMikko Vinni 		if (intmask & SDHCI_INT_DMA_END) {
2637f6a03cbfSMikko Vinni 			u32 dmastart, dmanow;
2638f6a03cbfSMikko Vinni 			dmastart = sg_dma_address(host->data->sg);
2639f6a03cbfSMikko Vinni 			dmanow = dmastart + host->data->bytes_xfered;
2640f6a03cbfSMikko Vinni 			/*
2641f6a03cbfSMikko Vinni 			 * Force update to the next DMA block boundary.
2642f6a03cbfSMikko Vinni 			 */
2643f6a03cbfSMikko Vinni 			dmanow = (dmanow &
2644f6a03cbfSMikko Vinni 				~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) +
2645f6a03cbfSMikko Vinni 				SDHCI_DEFAULT_BOUNDARY_SIZE;
2646f6a03cbfSMikko Vinni 			host->data->bytes_xfered = dmanow - dmastart;
2647f421865dSAdrian Hunter 			DBG("DMA base 0x%08x, transferred 0x%06x bytes, next 0x%08x\n",
2648f421865dSAdrian Hunter 			    dmastart, host->data->bytes_xfered, dmanow);
2649f6a03cbfSMikko Vinni 			sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
2650f6a03cbfSMikko Vinni 		}
26516ba736a1SPierre Ossman 
2652e538fbe8SPierre Ossman 		if (intmask & SDHCI_INT_DATA_END) {
26537c89a3d9SAdrian Hunter 			if (host->cmd == host->data_cmd) {
2654e538fbe8SPierre Ossman 				/*
2655e538fbe8SPierre Ossman 				 * Data managed to finish before the
2656e538fbe8SPierre Ossman 				 * command completed. Make sure we do
2657e538fbe8SPierre Ossman 				 * things in the proper order.
2658e538fbe8SPierre Ossman 				 */
2659e538fbe8SPierre Ossman 				host->data_early = 1;
2660e538fbe8SPierre Ossman 			} else {
26611c6a0718SPierre Ossman 				sdhci_finish_data(host);
26621c6a0718SPierre Ossman 			}
26631c6a0718SPierre Ossman 		}
2664e538fbe8SPierre Ossman 	}
2665e538fbe8SPierre Ossman }
26661c6a0718SPierre Ossman 
26671c6a0718SPierre Ossman static irqreturn_t sdhci_irq(int irq, void *dev_id)
26681c6a0718SPierre Ossman {
2669781e989cSRussell King 	irqreturn_t result = IRQ_NONE;
26701c6a0718SPierre Ossman 	struct sdhci_host *host = dev_id;
267141005003SRussell King 	u32 intmask, mask, unexpected = 0;
2672781e989cSRussell King 	int max_loops = 16;
26731c6a0718SPierre Ossman 
26741c6a0718SPierre Ossman 	spin_lock(&host->lock);
26751c6a0718SPierre Ossman 
2676be138554SRussell King 	if (host->runtime_suspended && !sdhci_sdio_irq_enabled(host)) {
267766fd8ad5SAdrian Hunter 		spin_unlock(&host->lock);
2678655bca76SAdrian Hunter 		return IRQ_NONE;
267966fd8ad5SAdrian Hunter 	}
268066fd8ad5SAdrian Hunter 
26814e4141a5SAnton Vorontsov 	intmask = sdhci_readl(host, SDHCI_INT_STATUS);
26821c6a0718SPierre Ossman 	if (!intmask || intmask == 0xffffffff) {
26831c6a0718SPierre Ossman 		result = IRQ_NONE;
26841c6a0718SPierre Ossman 		goto out;
26851c6a0718SPierre Ossman 	}
26861c6a0718SPierre Ossman 
268741005003SRussell King 	do {
2688f12e39dbSAdrian Hunter 		DBG("IRQ status 0x%08x\n", intmask);
2689f12e39dbSAdrian Hunter 
2690f12e39dbSAdrian Hunter 		if (host->ops->irq) {
2691f12e39dbSAdrian Hunter 			intmask = host->ops->irq(host, intmask);
2692f12e39dbSAdrian Hunter 			if (!intmask)
2693f12e39dbSAdrian Hunter 				goto cont;
2694f12e39dbSAdrian Hunter 		}
2695f12e39dbSAdrian Hunter 
269641005003SRussell King 		/* Clear selected interrupts. */
269741005003SRussell King 		mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
269841005003SRussell King 				  SDHCI_INT_BUS_POWER);
269941005003SRussell King 		sdhci_writel(host, mask, SDHCI_INT_STATUS);
270041005003SRussell King 
27011c6a0718SPierre Ossman 		if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
2702d25928d1SShawn Guo 			u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
2703d25928d1SShawn Guo 				      SDHCI_CARD_PRESENT;
2704d25928d1SShawn Guo 
2705d25928d1SShawn Guo 			/*
270641005003SRussell King 			 * There is a observation on i.mx esdhc.  INSERT
270741005003SRussell King 			 * bit will be immediately set again when it gets
270841005003SRussell King 			 * cleared, if a card is inserted.  We have to mask
270941005003SRussell King 			 * the irq to prevent interrupt storm which will
271041005003SRussell King 			 * freeze the system.  And the REMOVE gets the
271141005003SRussell King 			 * same situation.
2712d25928d1SShawn Guo 			 *
271341005003SRussell King 			 * More testing are needed here to ensure it works
271441005003SRussell King 			 * for other platforms though.
2715d25928d1SShawn Guo 			 */
2716b537f94cSRussell King 			host->ier &= ~(SDHCI_INT_CARD_INSERT |
2717d25928d1SShawn Guo 				       SDHCI_INT_CARD_REMOVE);
2718b537f94cSRussell King 			host->ier |= present ? SDHCI_INT_CARD_REMOVE :
2719b537f94cSRussell King 					       SDHCI_INT_CARD_INSERT;
2720b537f94cSRussell King 			sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
2721b537f94cSRussell King 			sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
2722d25928d1SShawn Guo 
27234e4141a5SAnton Vorontsov 			sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
27244e4141a5SAnton Vorontsov 				     SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
27253560db8eSRussell King 
27263560db8eSRussell King 			host->thread_isr |= intmask & (SDHCI_INT_CARD_INSERT |
27273560db8eSRussell King 						       SDHCI_INT_CARD_REMOVE);
27283560db8eSRussell King 			result = IRQ_WAKE_THREAD;
27291c6a0718SPierre Ossman 		}
27301c6a0718SPierre Ossman 
273141005003SRussell King 		if (intmask & SDHCI_INT_CMD_MASK)
2732fc605f1dSAdrian Hunter 			sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
27331c6a0718SPierre Ossman 
273441005003SRussell King 		if (intmask & SDHCI_INT_DATA_MASK)
27351c6a0718SPierre Ossman 			sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
27361c6a0718SPierre Ossman 
273741005003SRussell King 		if (intmask & SDHCI_INT_BUS_POWER)
2738a3c76eb9SGirish K S 			pr_err("%s: Card is consuming too much power!\n",
27391c6a0718SPierre Ossman 				mmc_hostname(host->mmc));
27401c6a0718SPierre Ossman 
2741f37b20ebSDong Aisheng 		if (intmask & SDHCI_INT_RETUNE)
2742f37b20ebSDong Aisheng 			mmc_retune_needed(host->mmc);
2743f37b20ebSDong Aisheng 
2744161e6d44SGabriel Krisman Bertazi 		if ((intmask & SDHCI_INT_CARD_INT) &&
2745161e6d44SGabriel Krisman Bertazi 		    (host->ier & SDHCI_INT_CARD_INT)) {
2746781e989cSRussell King 			sdhci_enable_sdio_irq_nolock(host, false);
2747781e989cSRussell King 			host->thread_isr |= SDHCI_INT_CARD_INT;
2748781e989cSRussell King 			result = IRQ_WAKE_THREAD;
2749781e989cSRussell King 		}
2750f75979b7SPierre Ossman 
275141005003SRussell King 		intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
275241005003SRussell King 			     SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
275341005003SRussell King 			     SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER |
2754f37b20ebSDong Aisheng 			     SDHCI_INT_RETUNE | SDHCI_INT_CARD_INT);
2755f75979b7SPierre Ossman 
27561c6a0718SPierre Ossman 		if (intmask) {
27576379b237SAlexander Stein 			unexpected |= intmask;
27584e4141a5SAnton Vorontsov 			sdhci_writel(host, intmask, SDHCI_INT_STATUS);
27591c6a0718SPierre Ossman 		}
2760f12e39dbSAdrian Hunter cont:
2761781e989cSRussell King 		if (result == IRQ_NONE)
27621c6a0718SPierre Ossman 			result = IRQ_HANDLED;
27631c6a0718SPierre Ossman 
27646379b237SAlexander Stein 		intmask = sdhci_readl(host, SDHCI_INT_STATUS);
276541005003SRussell King 	} while (intmask && --max_loops);
27661c6a0718SPierre Ossman out:
27671c6a0718SPierre Ossman 	spin_unlock(&host->lock);
27681c6a0718SPierre Ossman 
27696379b237SAlexander Stein 	if (unexpected) {
27706379b237SAlexander Stein 		pr_err("%s: Unexpected interrupt 0x%08x.\n",
27716379b237SAlexander Stein 			   mmc_hostname(host->mmc), unexpected);
27726379b237SAlexander Stein 		sdhci_dumpregs(host);
27736379b237SAlexander Stein 	}
2774f75979b7SPierre Ossman 
27751c6a0718SPierre Ossman 	return result;
27761c6a0718SPierre Ossman }
27771c6a0718SPierre Ossman 
2778781e989cSRussell King static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
2779781e989cSRussell King {
2780781e989cSRussell King 	struct sdhci_host *host = dev_id;
2781781e989cSRussell King 	unsigned long flags;
2782781e989cSRussell King 	u32 isr;
2783781e989cSRussell King 
2784781e989cSRussell King 	spin_lock_irqsave(&host->lock, flags);
2785781e989cSRussell King 	isr = host->thread_isr;
2786781e989cSRussell King 	host->thread_isr = 0;
2787781e989cSRussell King 	spin_unlock_irqrestore(&host->lock, flags);
2788781e989cSRussell King 
27893560db8eSRussell King 	if (isr & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
2790d3940f27SAdrian Hunter 		struct mmc_host *mmc = host->mmc;
2791d3940f27SAdrian Hunter 
2792d3940f27SAdrian Hunter 		mmc->ops->card_event(mmc);
2793d3940f27SAdrian Hunter 		mmc_detect_change(mmc, msecs_to_jiffies(200));
27943560db8eSRussell King 	}
27953560db8eSRussell King 
2796781e989cSRussell King 	if (isr & SDHCI_INT_CARD_INT) {
2797781e989cSRussell King 		sdio_run_irqs(host->mmc);
2798781e989cSRussell King 
2799781e989cSRussell King 		spin_lock_irqsave(&host->lock, flags);
2800781e989cSRussell King 		if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
2801781e989cSRussell King 			sdhci_enable_sdio_irq_nolock(host, true);
2802781e989cSRussell King 		spin_unlock_irqrestore(&host->lock, flags);
2803781e989cSRussell King 	}
2804781e989cSRussell King 
2805781e989cSRussell King 	return isr ? IRQ_HANDLED : IRQ_NONE;
2806781e989cSRussell King }
2807781e989cSRussell King 
28081c6a0718SPierre Ossman /*****************************************************************************\
28091c6a0718SPierre Ossman  *                                                                           *
28101c6a0718SPierre Ossman  * Suspend/resume                                                            *
28111c6a0718SPierre Ossman  *                                                                           *
28121c6a0718SPierre Ossman \*****************************************************************************/
28131c6a0718SPierre Ossman 
28141c6a0718SPierre Ossman #ifdef CONFIG_PM
281584d62605SLudovic Desroches /*
281684d62605SLudovic Desroches  * To enable wakeup events, the corresponding events have to be enabled in
281784d62605SLudovic Desroches  * the Interrupt Status Enable register too. See 'Table 1-6: Wakeup Signal
281884d62605SLudovic Desroches  * Table' in the SD Host Controller Standard Specification.
281984d62605SLudovic Desroches  * It is useless to restore SDHCI_INT_ENABLE state in
282084d62605SLudovic Desroches  * sdhci_disable_irq_wakeups() since it will be set by
282184d62605SLudovic Desroches  * sdhci_enable_card_detection() or sdhci_init().
282284d62605SLudovic Desroches  */
2823ad080d79SKevin Liu void sdhci_enable_irq_wakeups(struct sdhci_host *host)
2824ad080d79SKevin Liu {
2825ad080d79SKevin Liu 	u8 val;
2826ad080d79SKevin Liu 	u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE
2827ad080d79SKevin Liu 			| SDHCI_WAKE_ON_INT;
282884d62605SLudovic Desroches 	u32 irq_val = SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
282984d62605SLudovic Desroches 		      SDHCI_INT_CARD_INT;
2830ad080d79SKevin Liu 
2831ad080d79SKevin Liu 	val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
2832ad080d79SKevin Liu 	val |= mask ;
2833ad080d79SKevin Liu 	/* Avoid fake wake up */
283484d62605SLudovic Desroches 	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) {
2835ad080d79SKevin Liu 		val &= ~(SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE);
283684d62605SLudovic Desroches 		irq_val &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
283784d62605SLudovic Desroches 	}
2838ad080d79SKevin Liu 	sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
283984d62605SLudovic Desroches 	sdhci_writel(host, irq_val, SDHCI_INT_ENABLE);
2840ad080d79SKevin Liu }
2841ad080d79SKevin Liu EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups);
2842ad080d79SKevin Liu 
28430b10f478SFabio Estevam static void sdhci_disable_irq_wakeups(struct sdhci_host *host)
2844ad080d79SKevin Liu {
2845ad080d79SKevin Liu 	u8 val;
2846ad080d79SKevin Liu 	u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE
2847ad080d79SKevin Liu 			| SDHCI_WAKE_ON_INT;
2848ad080d79SKevin Liu 
2849ad080d79SKevin Liu 	val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
2850ad080d79SKevin Liu 	val &= ~mask;
2851ad080d79SKevin Liu 	sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
2852ad080d79SKevin Liu }
28531c6a0718SPierre Ossman 
285429495aa0SManuel Lauss int sdhci_suspend_host(struct sdhci_host *host)
28551c6a0718SPierre Ossman {
28567260cf5eSAnton Vorontsov 	sdhci_disable_card_detection(host);
28577260cf5eSAnton Vorontsov 
285866c39dfcSAdrian Hunter 	mmc_retune_timer_stop(host->mmc);
2859cf2b5eeaSArindam Nath 
2860ad080d79SKevin Liu 	if (!device_may_wakeup(mmc_dev(host->mmc))) {
2861b537f94cSRussell King 		host->ier = 0;
2862b537f94cSRussell King 		sdhci_writel(host, 0, SDHCI_INT_ENABLE);
2863b537f94cSRussell King 		sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
2864b8c86fc5SPierre Ossman 		free_irq(host->irq, host);
2865ad080d79SKevin Liu 	} else {
2866ad080d79SKevin Liu 		sdhci_enable_irq_wakeups(host);
2867ad080d79SKevin Liu 		enable_irq_wake(host->irq);
2868ad080d79SKevin Liu 	}
28694ee14ec6SUlf Hansson 	return 0;
2870b8c86fc5SPierre Ossman }
2871b8c86fc5SPierre Ossman 
2872b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_suspend_host);
2873b8c86fc5SPierre Ossman 
2874b8c86fc5SPierre Ossman int sdhci_resume_host(struct sdhci_host *host)
2875b8c86fc5SPierre Ossman {
2876d3940f27SAdrian Hunter 	struct mmc_host *mmc = host->mmc;
28774ee14ec6SUlf Hansson 	int ret = 0;
2878b8c86fc5SPierre Ossman 
2879a13abc7bSRichard Röjfors 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
2880b8c86fc5SPierre Ossman 		if (host->ops->enable_dma)
2881b8c86fc5SPierre Ossman 			host->ops->enable_dma(host);
2882b8c86fc5SPierre Ossman 	}
2883b8c86fc5SPierre Ossman 
28846308d290SAdrian Hunter 	if ((host->mmc->pm_flags & MMC_PM_KEEP_POWER) &&
28856308d290SAdrian Hunter 	    (host->quirks2 & SDHCI_QUIRK2_HOST_OFF_CARD_ON)) {
28866308d290SAdrian Hunter 		/* Card keeps power but host controller does not */
28876308d290SAdrian Hunter 		sdhci_init(host, 0);
28886308d290SAdrian Hunter 		host->pwr = 0;
28896308d290SAdrian Hunter 		host->clock = 0;
2890d3940f27SAdrian Hunter 		mmc->ops->set_ios(mmc, &mmc->ios);
28916308d290SAdrian Hunter 	} else {
28922f4cbb3dSNicolas Pitre 		sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER));
28931c6a0718SPierre Ossman 		mmiowb();
28946308d290SAdrian Hunter 	}
2895b8c86fc5SPierre Ossman 
289614a7b416SHaibo Chen 	if (!device_may_wakeup(mmc_dev(host->mmc))) {
289714a7b416SHaibo Chen 		ret = request_threaded_irq(host->irq, sdhci_irq,
289814a7b416SHaibo Chen 					   sdhci_thread_irq, IRQF_SHARED,
289914a7b416SHaibo Chen 					   mmc_hostname(host->mmc), host);
290014a7b416SHaibo Chen 		if (ret)
290114a7b416SHaibo Chen 			return ret;
290214a7b416SHaibo Chen 	} else {
290314a7b416SHaibo Chen 		sdhci_disable_irq_wakeups(host);
290414a7b416SHaibo Chen 		disable_irq_wake(host->irq);
290514a7b416SHaibo Chen 	}
290614a7b416SHaibo Chen 
29077260cf5eSAnton Vorontsov 	sdhci_enable_card_detection(host);
29087260cf5eSAnton Vorontsov 
29092f4cbb3dSNicolas Pitre 	return ret;
29101c6a0718SPierre Ossman }
29111c6a0718SPierre Ossman 
2912b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_resume_host);
291366fd8ad5SAdrian Hunter 
291466fd8ad5SAdrian Hunter int sdhci_runtime_suspend_host(struct sdhci_host *host)
291566fd8ad5SAdrian Hunter {
291666fd8ad5SAdrian Hunter 	unsigned long flags;
291766fd8ad5SAdrian Hunter 
291866c39dfcSAdrian Hunter 	mmc_retune_timer_stop(host->mmc);
291966fd8ad5SAdrian Hunter 
292066fd8ad5SAdrian Hunter 	spin_lock_irqsave(&host->lock, flags);
2921b537f94cSRussell King 	host->ier &= SDHCI_INT_CARD_INT;
2922b537f94cSRussell King 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
2923b537f94cSRussell King 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
292466fd8ad5SAdrian Hunter 	spin_unlock_irqrestore(&host->lock, flags);
292566fd8ad5SAdrian Hunter 
2926781e989cSRussell King 	synchronize_hardirq(host->irq);
292766fd8ad5SAdrian Hunter 
292866fd8ad5SAdrian Hunter 	spin_lock_irqsave(&host->lock, flags);
292966fd8ad5SAdrian Hunter 	host->runtime_suspended = true;
293066fd8ad5SAdrian Hunter 	spin_unlock_irqrestore(&host->lock, flags);
293166fd8ad5SAdrian Hunter 
29328a125badSMarkus Pargmann 	return 0;
293366fd8ad5SAdrian Hunter }
293466fd8ad5SAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_runtime_suspend_host);
293566fd8ad5SAdrian Hunter 
293666fd8ad5SAdrian Hunter int sdhci_runtime_resume_host(struct sdhci_host *host)
293766fd8ad5SAdrian Hunter {
2938d3940f27SAdrian Hunter 	struct mmc_host *mmc = host->mmc;
293966fd8ad5SAdrian Hunter 	unsigned long flags;
29408a125badSMarkus Pargmann 	int host_flags = host->flags;
294166fd8ad5SAdrian Hunter 
294266fd8ad5SAdrian Hunter 	if (host_flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
294366fd8ad5SAdrian Hunter 		if (host->ops->enable_dma)
294466fd8ad5SAdrian Hunter 			host->ops->enable_dma(host);
294566fd8ad5SAdrian Hunter 	}
294666fd8ad5SAdrian Hunter 
294766fd8ad5SAdrian Hunter 	sdhci_init(host, 0);
294866fd8ad5SAdrian Hunter 
294970bc85adSZhoujie Wu 	if (mmc->ios.power_mode != MMC_POWER_UNDEFINED &&
295070bc85adSZhoujie Wu 	    mmc->ios.power_mode != MMC_POWER_OFF) {
295166fd8ad5SAdrian Hunter 		/* Force clock and power re-program */
295266fd8ad5SAdrian Hunter 		host->pwr = 0;
295366fd8ad5SAdrian Hunter 		host->clock = 0;
2954d3940f27SAdrian Hunter 		mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios);
2955d3940f27SAdrian Hunter 		mmc->ops->set_ios(mmc, &mmc->ios);
295666fd8ad5SAdrian Hunter 
295752983382SKevin Liu 		if ((host_flags & SDHCI_PV_ENABLED) &&
295852983382SKevin Liu 		    !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) {
295952983382SKevin Liu 			spin_lock_irqsave(&host->lock, flags);
296052983382SKevin Liu 			sdhci_enable_preset_value(host, true);
296152983382SKevin Liu 			spin_unlock_irqrestore(&host->lock, flags);
296252983382SKevin Liu 		}
296366fd8ad5SAdrian Hunter 
2964086b0ddbSAdrian Hunter 		if ((mmc->caps2 & MMC_CAP2_HS400_ES) &&
2965086b0ddbSAdrian Hunter 		    mmc->ops->hs400_enhanced_strobe)
2966086b0ddbSAdrian Hunter 			mmc->ops->hs400_enhanced_strobe(mmc, &mmc->ios);
296784ec048bSAdrian Hunter 	}
2968086b0ddbSAdrian Hunter 
296966fd8ad5SAdrian Hunter 	spin_lock_irqsave(&host->lock, flags);
297066fd8ad5SAdrian Hunter 
297166fd8ad5SAdrian Hunter 	host->runtime_suspended = false;
297266fd8ad5SAdrian Hunter 
297366fd8ad5SAdrian Hunter 	/* Enable SDIO IRQ */
2974ef104333SRussell King 	if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
297566fd8ad5SAdrian Hunter 		sdhci_enable_sdio_irq_nolock(host, true);
297666fd8ad5SAdrian Hunter 
297766fd8ad5SAdrian Hunter 	/* Enable Card Detection */
297866fd8ad5SAdrian Hunter 	sdhci_enable_card_detection(host);
297966fd8ad5SAdrian Hunter 
298066fd8ad5SAdrian Hunter 	spin_unlock_irqrestore(&host->lock, flags);
298166fd8ad5SAdrian Hunter 
29828a125badSMarkus Pargmann 	return 0;
298366fd8ad5SAdrian Hunter }
298466fd8ad5SAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_runtime_resume_host);
298566fd8ad5SAdrian Hunter 
2986162d6f98SRafael J. Wysocki #endif /* CONFIG_PM */
298766fd8ad5SAdrian Hunter 
29881c6a0718SPierre Ossman /*****************************************************************************\
29891c6a0718SPierre Ossman  *                                                                           *
2990f12e39dbSAdrian Hunter  * Command Queue Engine (CQE) helpers                                        *
2991f12e39dbSAdrian Hunter  *                                                                           *
2992f12e39dbSAdrian Hunter \*****************************************************************************/
2993f12e39dbSAdrian Hunter 
2994f12e39dbSAdrian Hunter void sdhci_cqe_enable(struct mmc_host *mmc)
2995f12e39dbSAdrian Hunter {
2996f12e39dbSAdrian Hunter 	struct sdhci_host *host = mmc_priv(mmc);
2997f12e39dbSAdrian Hunter 	unsigned long flags;
2998f12e39dbSAdrian Hunter 	u8 ctrl;
2999f12e39dbSAdrian Hunter 
3000f12e39dbSAdrian Hunter 	spin_lock_irqsave(&host->lock, flags);
3001f12e39dbSAdrian Hunter 
3002f12e39dbSAdrian Hunter 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
3003f12e39dbSAdrian Hunter 	ctrl &= ~SDHCI_CTRL_DMA_MASK;
3004f12e39dbSAdrian Hunter 	if (host->flags & SDHCI_USE_64_BIT_DMA)
3005f12e39dbSAdrian Hunter 		ctrl |= SDHCI_CTRL_ADMA64;
3006f12e39dbSAdrian Hunter 	else
3007f12e39dbSAdrian Hunter 		ctrl |= SDHCI_CTRL_ADMA32;
3008f12e39dbSAdrian Hunter 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
3009f12e39dbSAdrian Hunter 
3010c846a00fSSrinivas Kandagatla 	sdhci_writew(host, SDHCI_MAKE_BLKSZ(host->sdma_boundary, 512),
3011f12e39dbSAdrian Hunter 		     SDHCI_BLOCK_SIZE);
3012f12e39dbSAdrian Hunter 
3013f12e39dbSAdrian Hunter 	/* Set maximum timeout */
3014f12e39dbSAdrian Hunter 	sdhci_writeb(host, 0xE, SDHCI_TIMEOUT_CONTROL);
3015f12e39dbSAdrian Hunter 
3016f12e39dbSAdrian Hunter 	host->ier = host->cqe_ier;
3017f12e39dbSAdrian Hunter 
3018f12e39dbSAdrian Hunter 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
3019f12e39dbSAdrian Hunter 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
3020f12e39dbSAdrian Hunter 
3021f12e39dbSAdrian Hunter 	host->cqe_on = true;
3022f12e39dbSAdrian Hunter 
3023f12e39dbSAdrian Hunter 	pr_debug("%s: sdhci: CQE on, IRQ mask %#x, IRQ status %#x\n",
3024f12e39dbSAdrian Hunter 		 mmc_hostname(mmc), host->ier,
3025f12e39dbSAdrian Hunter 		 sdhci_readl(host, SDHCI_INT_STATUS));
3026f12e39dbSAdrian Hunter 
3027f12e39dbSAdrian Hunter 	mmiowb();
3028f12e39dbSAdrian Hunter 	spin_unlock_irqrestore(&host->lock, flags);
3029f12e39dbSAdrian Hunter }
3030f12e39dbSAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_cqe_enable);
3031f12e39dbSAdrian Hunter 
3032f12e39dbSAdrian Hunter void sdhci_cqe_disable(struct mmc_host *mmc, bool recovery)
3033f12e39dbSAdrian Hunter {
3034f12e39dbSAdrian Hunter 	struct sdhci_host *host = mmc_priv(mmc);
3035f12e39dbSAdrian Hunter 	unsigned long flags;
3036f12e39dbSAdrian Hunter 
3037f12e39dbSAdrian Hunter 	spin_lock_irqsave(&host->lock, flags);
3038f12e39dbSAdrian Hunter 
3039f12e39dbSAdrian Hunter 	sdhci_set_default_irqs(host);
3040f12e39dbSAdrian Hunter 
3041f12e39dbSAdrian Hunter 	host->cqe_on = false;
3042f12e39dbSAdrian Hunter 
3043f12e39dbSAdrian Hunter 	if (recovery) {
3044f12e39dbSAdrian Hunter 		sdhci_do_reset(host, SDHCI_RESET_CMD);
3045f12e39dbSAdrian Hunter 		sdhci_do_reset(host, SDHCI_RESET_DATA);
3046f12e39dbSAdrian Hunter 	}
3047f12e39dbSAdrian Hunter 
3048f12e39dbSAdrian Hunter 	pr_debug("%s: sdhci: CQE off, IRQ mask %#x, IRQ status %#x\n",
3049f12e39dbSAdrian Hunter 		 mmc_hostname(mmc), host->ier,
3050f12e39dbSAdrian Hunter 		 sdhci_readl(host, SDHCI_INT_STATUS));
3051f12e39dbSAdrian Hunter 
3052f12e39dbSAdrian Hunter 	mmiowb();
3053f12e39dbSAdrian Hunter 	spin_unlock_irqrestore(&host->lock, flags);
3054f12e39dbSAdrian Hunter }
3055f12e39dbSAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_cqe_disable);
3056f12e39dbSAdrian Hunter 
3057f12e39dbSAdrian Hunter bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error,
3058f12e39dbSAdrian Hunter 		   int *data_error)
3059f12e39dbSAdrian Hunter {
3060f12e39dbSAdrian Hunter 	u32 mask;
3061f12e39dbSAdrian Hunter 
3062f12e39dbSAdrian Hunter 	if (!host->cqe_on)
3063f12e39dbSAdrian Hunter 		return false;
3064f12e39dbSAdrian Hunter 
3065f12e39dbSAdrian Hunter 	if (intmask & (SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC))
3066f12e39dbSAdrian Hunter 		*cmd_error = -EILSEQ;
3067f12e39dbSAdrian Hunter 	else if (intmask & SDHCI_INT_TIMEOUT)
3068f12e39dbSAdrian Hunter 		*cmd_error = -ETIMEDOUT;
3069f12e39dbSAdrian Hunter 	else
3070f12e39dbSAdrian Hunter 		*cmd_error = 0;
3071f12e39dbSAdrian Hunter 
3072f12e39dbSAdrian Hunter 	if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC))
3073f12e39dbSAdrian Hunter 		*data_error = -EILSEQ;
3074f12e39dbSAdrian Hunter 	else if (intmask & SDHCI_INT_DATA_TIMEOUT)
3075f12e39dbSAdrian Hunter 		*data_error = -ETIMEDOUT;
3076f12e39dbSAdrian Hunter 	else if (intmask & SDHCI_INT_ADMA_ERROR)
3077f12e39dbSAdrian Hunter 		*data_error = -EIO;
3078f12e39dbSAdrian Hunter 	else
3079f12e39dbSAdrian Hunter 		*data_error = 0;
3080f12e39dbSAdrian Hunter 
3081f12e39dbSAdrian Hunter 	/* Clear selected interrupts. */
3082f12e39dbSAdrian Hunter 	mask = intmask & host->cqe_ier;
3083f12e39dbSAdrian Hunter 	sdhci_writel(host, mask, SDHCI_INT_STATUS);
3084f12e39dbSAdrian Hunter 
3085f12e39dbSAdrian Hunter 	if (intmask & SDHCI_INT_BUS_POWER)
3086f12e39dbSAdrian Hunter 		pr_err("%s: Card is consuming too much power!\n",
3087f12e39dbSAdrian Hunter 		       mmc_hostname(host->mmc));
3088f12e39dbSAdrian Hunter 
3089f12e39dbSAdrian Hunter 	intmask &= ~(host->cqe_ier | SDHCI_INT_ERROR);
3090f12e39dbSAdrian Hunter 	if (intmask) {
3091f12e39dbSAdrian Hunter 		sdhci_writel(host, intmask, SDHCI_INT_STATUS);
3092f12e39dbSAdrian Hunter 		pr_err("%s: CQE: Unexpected interrupt 0x%08x.\n",
3093f12e39dbSAdrian Hunter 		       mmc_hostname(host->mmc), intmask);
3094f12e39dbSAdrian Hunter 		sdhci_dumpregs(host);
3095f12e39dbSAdrian Hunter 	}
3096f12e39dbSAdrian Hunter 
3097f12e39dbSAdrian Hunter 	return true;
3098f12e39dbSAdrian Hunter }
3099f12e39dbSAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_cqe_irq);
3100f12e39dbSAdrian Hunter 
3101f12e39dbSAdrian Hunter /*****************************************************************************\
3102f12e39dbSAdrian Hunter  *                                                                           *
3103b8c86fc5SPierre Ossman  * Device allocation/registration                                            *
31041c6a0718SPierre Ossman  *                                                                           *
31051c6a0718SPierre Ossman \*****************************************************************************/
31061c6a0718SPierre Ossman 
3107b8c86fc5SPierre Ossman struct sdhci_host *sdhci_alloc_host(struct device *dev,
3108b8c86fc5SPierre Ossman 	size_t priv_size)
31091c6a0718SPierre Ossman {
31101c6a0718SPierre Ossman 	struct mmc_host *mmc;
31111c6a0718SPierre Ossman 	struct sdhci_host *host;
31121c6a0718SPierre Ossman 
3113b8c86fc5SPierre Ossman 	WARN_ON(dev == NULL);
31141c6a0718SPierre Ossman 
3115b8c86fc5SPierre Ossman 	mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev);
31161c6a0718SPierre Ossman 	if (!mmc)
3117b8c86fc5SPierre Ossman 		return ERR_PTR(-ENOMEM);
31181c6a0718SPierre Ossman 
31191c6a0718SPierre Ossman 	host = mmc_priv(mmc);
31201c6a0718SPierre Ossman 	host->mmc = mmc;
3121bf60e592SAdrian Hunter 	host->mmc_host_ops = sdhci_ops;
3122bf60e592SAdrian Hunter 	mmc->ops = &host->mmc_host_ops;
31231c6a0718SPierre Ossman 
31248cb851a4SAdrian Hunter 	host->flags = SDHCI_SIGNALING_330;
31258cb851a4SAdrian Hunter 
3126f12e39dbSAdrian Hunter 	host->cqe_ier     = SDHCI_CQE_INT_MASK;
3127f12e39dbSAdrian Hunter 	host->cqe_err_ier = SDHCI_CQE_INT_ERR_MASK;
3128f12e39dbSAdrian Hunter 
312983b600b8SAdrian Hunter 	host->tuning_delay = -1;
313083b600b8SAdrian Hunter 
3131c846a00fSSrinivas Kandagatla 	host->sdma_boundary = SDHCI_DEFAULT_BOUNDARY_ARG;
3132c846a00fSSrinivas Kandagatla 
3133b8c86fc5SPierre Ossman 	return host;
31341c6a0718SPierre Ossman }
31351c6a0718SPierre Ossman 
3136b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_alloc_host);
3137b8c86fc5SPierre Ossman 
31387b91369bSAlexandre Courbot static int sdhci_set_dma_mask(struct sdhci_host *host)
31397b91369bSAlexandre Courbot {
31407b91369bSAlexandre Courbot 	struct mmc_host *mmc = host->mmc;
31417b91369bSAlexandre Courbot 	struct device *dev = mmc_dev(mmc);
31427b91369bSAlexandre Courbot 	int ret = -EINVAL;
31437b91369bSAlexandre Courbot 
31447b91369bSAlexandre Courbot 	if (host->quirks2 & SDHCI_QUIRK2_BROKEN_64_BIT_DMA)
31457b91369bSAlexandre Courbot 		host->flags &= ~SDHCI_USE_64_BIT_DMA;
31467b91369bSAlexandre Courbot 
31477b91369bSAlexandre Courbot 	/* Try 64-bit mask if hardware is capable  of it */
31487b91369bSAlexandre Courbot 	if (host->flags & SDHCI_USE_64_BIT_DMA) {
31497b91369bSAlexandre Courbot 		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
31507b91369bSAlexandre Courbot 		if (ret) {
31517b91369bSAlexandre Courbot 			pr_warn("%s: Failed to set 64-bit DMA mask.\n",
31527b91369bSAlexandre Courbot 				mmc_hostname(mmc));
31537b91369bSAlexandre Courbot 			host->flags &= ~SDHCI_USE_64_BIT_DMA;
31547b91369bSAlexandre Courbot 		}
31557b91369bSAlexandre Courbot 	}
31567b91369bSAlexandre Courbot 
31577b91369bSAlexandre Courbot 	/* 32-bit mask as default & fallback */
31587b91369bSAlexandre Courbot 	if (ret) {
31597b91369bSAlexandre Courbot 		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
31607b91369bSAlexandre Courbot 		if (ret)
31617b91369bSAlexandre Courbot 			pr_warn("%s: Failed to set 32-bit DMA mask.\n",
31627b91369bSAlexandre Courbot 				mmc_hostname(mmc));
31637b91369bSAlexandre Courbot 	}
31647b91369bSAlexandre Courbot 
31657b91369bSAlexandre Courbot 	return ret;
31667b91369bSAlexandre Courbot }
31677b91369bSAlexandre Courbot 
31686132a3bfSAdrian Hunter void __sdhci_read_caps(struct sdhci_host *host, u16 *ver, u32 *caps, u32 *caps1)
31696132a3bfSAdrian Hunter {
31706132a3bfSAdrian Hunter 	u16 v;
317192e0c44bSZach Brown 	u64 dt_caps_mask = 0;
317292e0c44bSZach Brown 	u64 dt_caps = 0;
31736132a3bfSAdrian Hunter 
31746132a3bfSAdrian Hunter 	if (host->read_caps)
31756132a3bfSAdrian Hunter 		return;
31766132a3bfSAdrian Hunter 
31776132a3bfSAdrian Hunter 	host->read_caps = true;
31786132a3bfSAdrian Hunter 
31796132a3bfSAdrian Hunter 	if (debug_quirks)
31806132a3bfSAdrian Hunter 		host->quirks = debug_quirks;
31816132a3bfSAdrian Hunter 
31826132a3bfSAdrian Hunter 	if (debug_quirks2)
31836132a3bfSAdrian Hunter 		host->quirks2 = debug_quirks2;
31846132a3bfSAdrian Hunter 
31856132a3bfSAdrian Hunter 	sdhci_do_reset(host, SDHCI_RESET_ALL);
31866132a3bfSAdrian Hunter 
318792e0c44bSZach Brown 	of_property_read_u64(mmc_dev(host->mmc)->of_node,
318892e0c44bSZach Brown 			     "sdhci-caps-mask", &dt_caps_mask);
318992e0c44bSZach Brown 	of_property_read_u64(mmc_dev(host->mmc)->of_node,
319092e0c44bSZach Brown 			     "sdhci-caps", &dt_caps);
319192e0c44bSZach Brown 
31926132a3bfSAdrian Hunter 	v = ver ? *ver : sdhci_readw(host, SDHCI_HOST_VERSION);
31936132a3bfSAdrian Hunter 	host->version = (v & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT;
31946132a3bfSAdrian Hunter 
31956132a3bfSAdrian Hunter 	if (host->quirks & SDHCI_QUIRK_MISSING_CAPS)
31966132a3bfSAdrian Hunter 		return;
31976132a3bfSAdrian Hunter 
319892e0c44bSZach Brown 	if (caps) {
319992e0c44bSZach Brown 		host->caps = *caps;
320092e0c44bSZach Brown 	} else {
320192e0c44bSZach Brown 		host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
320292e0c44bSZach Brown 		host->caps &= ~lower_32_bits(dt_caps_mask);
320392e0c44bSZach Brown 		host->caps |= lower_32_bits(dt_caps);
320492e0c44bSZach Brown 	}
32056132a3bfSAdrian Hunter 
32066132a3bfSAdrian Hunter 	if (host->version < SDHCI_SPEC_300)
32076132a3bfSAdrian Hunter 		return;
32086132a3bfSAdrian Hunter 
320992e0c44bSZach Brown 	if (caps1) {
321092e0c44bSZach Brown 		host->caps1 = *caps1;
321192e0c44bSZach Brown 	} else {
321292e0c44bSZach Brown 		host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
321392e0c44bSZach Brown 		host->caps1 &= ~upper_32_bits(dt_caps_mask);
321492e0c44bSZach Brown 		host->caps1 |= upper_32_bits(dt_caps);
321592e0c44bSZach Brown 	}
32166132a3bfSAdrian Hunter }
32176132a3bfSAdrian Hunter EXPORT_SYMBOL_GPL(__sdhci_read_caps);
32186132a3bfSAdrian Hunter 
321952f5336dSAdrian Hunter int sdhci_setup_host(struct sdhci_host *host)
3220b8c86fc5SPierre Ossman {
3221b8c86fc5SPierre Ossman 	struct mmc_host *mmc;
3222f2119df6SArindam Nath 	u32 max_current_caps;
3223f2119df6SArindam Nath 	unsigned int ocr_avail;
3224f5fa92e5SAdrian Hunter 	unsigned int override_timeout_clk;
322559241757SDong Aisheng 	u32 max_clk;
3226b8c86fc5SPierre Ossman 	int ret;
3227b8c86fc5SPierre Ossman 
3228b8c86fc5SPierre Ossman 	WARN_ON(host == NULL);
3229b8c86fc5SPierre Ossman 	if (host == NULL)
3230b8c86fc5SPierre Ossman 		return -EINVAL;
3231b8c86fc5SPierre Ossman 
3232b8c86fc5SPierre Ossman 	mmc = host->mmc;
3233b8c86fc5SPierre Ossman 
3234efba142bSJon Hunter 	/*
3235efba142bSJon Hunter 	 * If there are external regulators, get them. Note this must be done
3236efba142bSJon Hunter 	 * early before resetting the host and reading the capabilities so that
3237efba142bSJon Hunter 	 * the host can take the appropriate action if regulators are not
3238efba142bSJon Hunter 	 * available.
3239efba142bSJon Hunter 	 */
3240efba142bSJon Hunter 	ret = mmc_regulator_get_supply(mmc);
32412a63303dSWolfram Sang 	if (ret)
3242efba142bSJon Hunter 		return ret;
3243efba142bSJon Hunter 
324406ebc601SShawn Lin 	DBG("Version:   0x%08x | Present:  0x%08x\n",
324506ebc601SShawn Lin 	    sdhci_readw(host, SDHCI_HOST_VERSION),
324606ebc601SShawn Lin 	    sdhci_readl(host, SDHCI_PRESENT_STATE));
324706ebc601SShawn Lin 	DBG("Caps:      0x%08x | Caps_1:   0x%08x\n",
324806ebc601SShawn Lin 	    sdhci_readl(host, SDHCI_CAPABILITIES),
324906ebc601SShawn Lin 	    sdhci_readl(host, SDHCI_CAPABILITIES_1));
325006ebc601SShawn Lin 
32516132a3bfSAdrian Hunter 	sdhci_read_caps(host);
3252b8c86fc5SPierre Ossman 
3253f5fa92e5SAdrian Hunter 	override_timeout_clk = host->timeout_clk;
3254f5fa92e5SAdrian Hunter 
325585105c53SZhangfei Gao 	if (host->version > SDHCI_SPEC_300) {
32562e4456f0SMarek Vasut 		pr_err("%s: Unknown controller version (%d). You may experience problems.\n",
32572e4456f0SMarek Vasut 		       mmc_hostname(mmc), host->version);
32581c6a0718SPierre Ossman 	}
32591c6a0718SPierre Ossman 
3260b8c86fc5SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
3261a13abc7bSRichard Röjfors 		host->flags |= SDHCI_USE_SDMA;
326228da3589SAdrian Hunter 	else if (!(host->caps & SDHCI_CAN_DO_SDMA))
3263a13abc7bSRichard Röjfors 		DBG("Controller doesn't have SDMA capability\n");
32641c6a0718SPierre Ossman 	else
3265a13abc7bSRichard Röjfors 		host->flags |= SDHCI_USE_SDMA;
32661c6a0718SPierre Ossman 
3267b8c86fc5SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
3268a13abc7bSRichard Röjfors 		(host->flags & SDHCI_USE_SDMA)) {
3269cee687ceSRolf Eike Beer 		DBG("Disabling DMA as it is marked broken\n");
3270a13abc7bSRichard Röjfors 		host->flags &= ~SDHCI_USE_SDMA;
32717c168e3dSFeng Tang 	}
32727c168e3dSFeng Tang 
3273f2119df6SArindam Nath 	if ((host->version >= SDHCI_SPEC_200) &&
327428da3589SAdrian Hunter 		(host->caps & SDHCI_CAN_DO_ADMA2))
32752134a922SPierre Ossman 		host->flags |= SDHCI_USE_ADMA;
32762134a922SPierre Ossman 
32772134a922SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
32782134a922SPierre Ossman 		(host->flags & SDHCI_USE_ADMA)) {
32792134a922SPierre Ossman 		DBG("Disabling ADMA as it is marked broken\n");
32802134a922SPierre Ossman 		host->flags &= ~SDHCI_USE_ADMA;
32812134a922SPierre Ossman 	}
32822134a922SPierre Ossman 
3283e57a5f61SAdrian Hunter 	/*
3284e57a5f61SAdrian Hunter 	 * It is assumed that a 64-bit capable device has set a 64-bit DMA mask
3285e57a5f61SAdrian Hunter 	 * and *must* do 64-bit DMA.  A driver has the opportunity to change
3286e57a5f61SAdrian Hunter 	 * that during the first call to ->enable_dma().  Similarly
3287e57a5f61SAdrian Hunter 	 * SDHCI_QUIRK2_BROKEN_64_BIT_DMA must be left to the drivers to
3288e57a5f61SAdrian Hunter 	 * implement.
3289e57a5f61SAdrian Hunter 	 */
329028da3589SAdrian Hunter 	if (host->caps & SDHCI_CAN_64BIT)
3291e57a5f61SAdrian Hunter 		host->flags |= SDHCI_USE_64_BIT_DMA;
3292e57a5f61SAdrian Hunter 
3293a13abc7bSRichard Röjfors 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
32947b91369bSAlexandre Courbot 		ret = sdhci_set_dma_mask(host);
32957b91369bSAlexandre Courbot 
32967b91369bSAlexandre Courbot 		if (!ret && host->ops->enable_dma)
32977b91369bSAlexandre Courbot 			ret = host->ops->enable_dma(host);
32987b91369bSAlexandre Courbot 
32997b91369bSAlexandre Courbot 		if (ret) {
33006606110dSJoe Perches 			pr_warn("%s: No suitable DMA available - falling back to PIO\n",
3301b8c86fc5SPierre Ossman 				mmc_hostname(mmc));
33027b91369bSAlexandre Courbot 			host->flags &= ~(SDHCI_USE_SDMA | SDHCI_USE_ADMA);
33037b91369bSAlexandre Courbot 
33047b91369bSAlexandre Courbot 			ret = 0;
33051c6a0718SPierre Ossman 		}
3306b8c86fc5SPierre Ossman 	}
33071c6a0718SPierre Ossman 
3308e57a5f61SAdrian Hunter 	/* SDMA does not support 64-bit DMA */
3309e57a5f61SAdrian Hunter 	if (host->flags & SDHCI_USE_64_BIT_DMA)
3310e57a5f61SAdrian Hunter 		host->flags &= ~SDHCI_USE_SDMA;
3311e57a5f61SAdrian Hunter 
33122134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA) {
3313e66e61cbSRussell King 		dma_addr_t dma;
3314e66e61cbSRussell King 		void *buf;
3315e66e61cbSRussell King 
33162134a922SPierre Ossman 		/*
331776fe379aSAdrian Hunter 		 * The DMA descriptor table size is calculated as the maximum
331876fe379aSAdrian Hunter 		 * number of segments times 2, to allow for an alignment
331976fe379aSAdrian Hunter 		 * descriptor for each segment, plus 1 for a nop end descriptor,
332076fe379aSAdrian Hunter 		 * all multipled by the descriptor size.
33212134a922SPierre Ossman 		 */
3322e57a5f61SAdrian Hunter 		if (host->flags & SDHCI_USE_64_BIT_DMA) {
3323e57a5f61SAdrian Hunter 			host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) *
3324e57a5f61SAdrian Hunter 					      SDHCI_ADMA2_64_DESC_SZ;
3325e57a5f61SAdrian Hunter 			host->desc_sz = SDHCI_ADMA2_64_DESC_SZ;
3326e57a5f61SAdrian Hunter 		} else {
3327739d46dcSAdrian Hunter 			host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) *
3328739d46dcSAdrian Hunter 					      SDHCI_ADMA2_32_DESC_SZ;
3329739d46dcSAdrian Hunter 			host->desc_sz = SDHCI_ADMA2_32_DESC_SZ;
3330e57a5f61SAdrian Hunter 		}
3331e66e61cbSRussell King 
333204a5ae6fSAdrian Hunter 		host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN;
3333e66e61cbSRussell King 		buf = dma_alloc_coherent(mmc_dev(mmc), host->align_buffer_sz +
3334e66e61cbSRussell King 					 host->adma_table_sz, &dma, GFP_KERNEL);
3335e66e61cbSRussell King 		if (!buf) {
33366606110dSJoe Perches 			pr_warn("%s: Unable to allocate ADMA buffers - falling back to standard DMA\n",
33372134a922SPierre Ossman 				mmc_hostname(mmc));
33382134a922SPierre Ossman 			host->flags &= ~SDHCI_USE_ADMA;
3339e66e61cbSRussell King 		} else if ((dma + host->align_buffer_sz) &
3340e66e61cbSRussell King 			   (SDHCI_ADMA2_DESC_ALIGN - 1)) {
33416606110dSJoe Perches 			pr_warn("%s: unable to allocate aligned ADMA descriptor\n",
3342d1e49f77SRussell King 				mmc_hostname(mmc));
3343d1e49f77SRussell King 			host->flags &= ~SDHCI_USE_ADMA;
3344e66e61cbSRussell King 			dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz +
3345e66e61cbSRussell King 					  host->adma_table_sz, buf, dma);
3346e66e61cbSRussell King 		} else {
3347e66e61cbSRussell King 			host->align_buffer = buf;
3348e66e61cbSRussell King 			host->align_addr = dma;
3349edd63fccSRussell King 
3350e66e61cbSRussell King 			host->adma_table = buf + host->align_buffer_sz;
3351e66e61cbSRussell King 			host->adma_addr = dma + host->align_buffer_sz;
3352e66e61cbSRussell King 		}
33532134a922SPierre Ossman 	}
33542134a922SPierre Ossman 
33557659150cSPierre Ossman 	/*
33567659150cSPierre Ossman 	 * If we use DMA, then it's up to the caller to set the DMA
33577659150cSPierre Ossman 	 * mask, but PIO does not need the hw shim so we set a new
33587659150cSPierre Ossman 	 * mask here in that case.
33597659150cSPierre Ossman 	 */
3360a13abc7bSRichard Röjfors 	if (!(host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) {
33617659150cSPierre Ossman 		host->dma_mask = DMA_BIT_MASK(64);
33624e743f1fSMarkus Mayer 		mmc_dev(mmc)->dma_mask = &host->dma_mask;
33637659150cSPierre Ossman 	}
33641c6a0718SPierre Ossman 
3365c4687d5fSZhangfei Gao 	if (host->version >= SDHCI_SPEC_300)
336628da3589SAdrian Hunter 		host->max_clk = (host->caps & SDHCI_CLOCK_V3_BASE_MASK)
3367c4687d5fSZhangfei Gao 			>> SDHCI_CLOCK_BASE_SHIFT;
3368c4687d5fSZhangfei Gao 	else
336928da3589SAdrian Hunter 		host->max_clk = (host->caps & SDHCI_CLOCK_BASE_MASK)
3370c4687d5fSZhangfei Gao 			>> SDHCI_CLOCK_BASE_SHIFT;
3371c4687d5fSZhangfei Gao 
33724240ff0aSBen Dooks 	host->max_clk *= 1000000;
3373f27f47efSAnton Vorontsov 	if (host->max_clk == 0 || host->quirks &
3374f27f47efSAnton Vorontsov 			SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) {
33754240ff0aSBen Dooks 		if (!host->ops->get_max_clock) {
33762e4456f0SMarek Vasut 			pr_err("%s: Hardware doesn't specify base clock frequency.\n",
33772e4456f0SMarek Vasut 			       mmc_hostname(mmc));
3378eb5c20deSAdrian Hunter 			ret = -ENODEV;
3379eb5c20deSAdrian Hunter 			goto undma;
33801c6a0718SPierre Ossman 		}
33814240ff0aSBen Dooks 		host->max_clk = host->ops->get_max_clock(host);
33824240ff0aSBen Dooks 	}
33831c6a0718SPierre Ossman 
33841c6a0718SPierre Ossman 	/*
3385c3ed3877SArindam Nath 	 * In case of Host Controller v3.00, find out whether clock
3386c3ed3877SArindam Nath 	 * multiplier is supported.
3387c3ed3877SArindam Nath 	 */
338828da3589SAdrian Hunter 	host->clk_mul = (host->caps1 & SDHCI_CLOCK_MUL_MASK) >>
3389c3ed3877SArindam Nath 			SDHCI_CLOCK_MUL_SHIFT;
3390c3ed3877SArindam Nath 
3391c3ed3877SArindam Nath 	/*
3392c3ed3877SArindam Nath 	 * In case the value in Clock Multiplier is 0, then programmable
3393c3ed3877SArindam Nath 	 * clock mode is not supported, otherwise the actual clock
3394c3ed3877SArindam Nath 	 * multiplier is one more than the value of Clock Multiplier
3395c3ed3877SArindam Nath 	 * in the Capabilities Register.
3396c3ed3877SArindam Nath 	 */
3397c3ed3877SArindam Nath 	if (host->clk_mul)
3398c3ed3877SArindam Nath 		host->clk_mul += 1;
3399c3ed3877SArindam Nath 
3400c3ed3877SArindam Nath 	/*
34011c6a0718SPierre Ossman 	 * Set host parameters.
34021c6a0718SPierre Ossman 	 */
340359241757SDong Aisheng 	max_clk = host->max_clk;
340459241757SDong Aisheng 
3405ce5f036bSMarek Szyprowski 	if (host->ops->get_min_clock)
3406a9e58f25SAnton Vorontsov 		mmc->f_min = host->ops->get_min_clock(host);
3407c3ed3877SArindam Nath 	else if (host->version >= SDHCI_SPEC_300) {
3408c3ed3877SArindam Nath 		if (host->clk_mul) {
3409c3ed3877SArindam Nath 			mmc->f_min = (host->max_clk * host->clk_mul) / 1024;
341059241757SDong Aisheng 			max_clk = host->max_clk * host->clk_mul;
3411c3ed3877SArindam Nath 		} else
34120397526dSZhangfei Gao 			mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
3413c3ed3877SArindam Nath 	} else
34140397526dSZhangfei Gao 		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
341515ec4461SPhilip Rakity 
3416d310ae49SAdrian Hunter 	if (!mmc->f_max || mmc->f_max > max_clk)
341759241757SDong Aisheng 		mmc->f_max = max_clk;
341859241757SDong Aisheng 
341928aab053SAisheng Dong 	if (!(host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
342028da3589SAdrian Hunter 		host->timeout_clk = (host->caps & SDHCI_TIMEOUT_CLK_MASK) >>
342128aab053SAisheng Dong 					SDHCI_TIMEOUT_CLK_SHIFT;
34228cc35289SShawn Lin 
34238cc35289SShawn Lin 		if (host->caps & SDHCI_TIMEOUT_CLK_UNIT)
34248cc35289SShawn Lin 			host->timeout_clk *= 1000;
34258cc35289SShawn Lin 
3426272308caSAndy Shevchenko 		if (host->timeout_clk == 0) {
34278cc35289SShawn Lin 			if (!host->ops->get_timeout_clock) {
342828aab053SAisheng Dong 				pr_err("%s: Hardware doesn't specify timeout clock frequency.\n",
342928aab053SAisheng Dong 					mmc_hostname(mmc));
3430eb5c20deSAdrian Hunter 				ret = -ENODEV;
3431eb5c20deSAdrian Hunter 				goto undma;
3432272308caSAndy Shevchenko 			}
343328aab053SAisheng Dong 
34348cc35289SShawn Lin 			host->timeout_clk =
34358cc35289SShawn Lin 				DIV_ROUND_UP(host->ops->get_timeout_clock(host),
34368cc35289SShawn Lin 					     1000);
34378cc35289SShawn Lin 		}
3438272308caSAndy Shevchenko 
343999513624SAdrian Hunter 		if (override_timeout_clk)
344099513624SAdrian Hunter 			host->timeout_clk = override_timeout_clk;
344199513624SAdrian Hunter 
3442a6ff5aebSAisheng Dong 		mmc->max_busy_timeout = host->ops->get_max_timeout_count ?
3443a6ff5aebSAisheng Dong 			host->ops->get_max_timeout_count(host) : 1 << 27;
3444a6ff5aebSAisheng Dong 		mmc->max_busy_timeout /= host->timeout_clk;
344528aab053SAisheng Dong 	}
344658d1246dSAdrian Hunter 
3447e89d456fSAndrei Warkentin 	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
3448781e989cSRussell King 	mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
3449e89d456fSAndrei Warkentin 
3450e89d456fSAndrei Warkentin 	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
3451e89d456fSAndrei Warkentin 		host->flags |= SDHCI_AUTO_CMD12;
34525fe23c7fSAnton Vorontsov 
34538edf6371SAndrei Warkentin 	/* Auto-CMD23 stuff only works in ADMA or PIO. */
34544f3d3e9bSAndrei Warkentin 	if ((host->version >= SDHCI_SPEC_300) &&
34558edf6371SAndrei Warkentin 	    ((host->flags & SDHCI_USE_ADMA) ||
34563bfa6f03SScott Branden 	     !(host->flags & SDHCI_USE_SDMA)) &&
34573bfa6f03SScott Branden 	     !(host->quirks2 & SDHCI_QUIRK2_ACMD23_BROKEN)) {
34588edf6371SAndrei Warkentin 		host->flags |= SDHCI_AUTO_CMD23;
3459f421865dSAdrian Hunter 		DBG("Auto-CMD23 available\n");
34608edf6371SAndrei Warkentin 	} else {
3461f421865dSAdrian Hunter 		DBG("Auto-CMD23 unavailable\n");
34628edf6371SAndrei Warkentin 	}
34638edf6371SAndrei Warkentin 
346415ec4461SPhilip Rakity 	/*
346515ec4461SPhilip Rakity 	 * A controller may support 8-bit width, but the board itself
346615ec4461SPhilip Rakity 	 * might not have the pins brought out.  Boards that support
346715ec4461SPhilip Rakity 	 * 8-bit width must set "mmc->caps |= MMC_CAP_8_BIT_DATA;" in
346815ec4461SPhilip Rakity 	 * their platform code before calling sdhci_add_host(), and we
346915ec4461SPhilip Rakity 	 * won't assume 8-bit width for hosts without that CAP.
347015ec4461SPhilip Rakity 	 */
34715fe23c7fSAnton Vorontsov 	if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
347215ec4461SPhilip Rakity 		mmc->caps |= MMC_CAP_4_BIT_DATA;
34731c6a0718SPierre Ossman 
347463ef5d8cSJerry Huang 	if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23)
347563ef5d8cSJerry Huang 		mmc->caps &= ~MMC_CAP_CMD23;
347663ef5d8cSJerry Huang 
347728da3589SAdrian Hunter 	if (host->caps & SDHCI_CAN_DO_HISPD)
3478a29e7e18SZhangfei Gao 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
34791c6a0718SPierre Ossman 
3480176d1ed4SJaehoon Chung 	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) &&
3481860951c5SJaehoon Chung 	    mmc_card_is_removable(mmc) &&
3482287980e4SArnd Bergmann 	    mmc_gpio_get_cd(host->mmc) < 0)
348368d1fb7eSAnton Vorontsov 		mmc->caps |= MMC_CAP_NEEDS_POLL;
348468d1fb7eSAnton Vorontsov 
34856231f3deSPhilip Rakity 	/* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
34863a48edc4STim Kryger 	if (!IS_ERR(mmc->supply.vqmmc)) {
34873a48edc4STim Kryger 		ret = regulator_enable(mmc->supply.vqmmc);
34883a48edc4STim Kryger 		if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 1700000,
3489cec2e216SKevin Liu 						    1950000))
349028da3589SAdrian Hunter 			host->caps1 &= ~(SDHCI_SUPPORT_SDR104 |
34918363c374SKevin Liu 					 SDHCI_SUPPORT_SDR50 |
34926231f3deSPhilip Rakity 					 SDHCI_SUPPORT_DDR50);
3493a3361abaSChris Ball 		if (ret) {
3494a3361abaSChris Ball 			pr_warn("%s: Failed to enable vqmmc regulator: %d\n",
3495a3361abaSChris Ball 				mmc_hostname(mmc), ret);
34964bb74313SAdrian Hunter 			mmc->supply.vqmmc = ERR_PTR(-EINVAL);
3497a3361abaSChris Ball 		}
34988363c374SKevin Liu 	}
34996231f3deSPhilip Rakity 
350028da3589SAdrian Hunter 	if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) {
350128da3589SAdrian Hunter 		host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
35026a66180aSDaniel Drake 				 SDHCI_SUPPORT_DDR50);
350328da3589SAdrian Hunter 	}
35046a66180aSDaniel Drake 
35054188bba0SAl Cooper 	/* Any UHS-I mode in caps implies SDR12 and SDR25 support. */
350628da3589SAdrian Hunter 	if (host->caps1 & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
35074188bba0SAl Cooper 			   SDHCI_SUPPORT_DDR50))
3508f2119df6SArindam Nath 		mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
3509f2119df6SArindam Nath 
3510f2119df6SArindam Nath 	/* SDR104 supports also implies SDR50 support */
351128da3589SAdrian Hunter 	if (host->caps1 & SDHCI_SUPPORT_SDR104) {
3512f2119df6SArindam Nath 		mmc->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50;
3513156e14b1SGiuseppe CAVALLARO 		/* SD3.0: SDR104 is supported so (for eMMC) the caps2
3514156e14b1SGiuseppe CAVALLARO 		 * field can be promoted to support HS200.
3515156e14b1SGiuseppe CAVALLARO 		 */
3516549c0b18SAdrian Hunter 		if (!(host->quirks2 & SDHCI_QUIRK2_BROKEN_HS200))
3517156e14b1SGiuseppe CAVALLARO 			mmc->caps2 |= MMC_CAP2_HS200;
351828da3589SAdrian Hunter 	} else if (host->caps1 & SDHCI_SUPPORT_SDR50) {
3519f2119df6SArindam Nath 		mmc->caps |= MMC_CAP_UHS_SDR50;
352028da3589SAdrian Hunter 	}
3521f2119df6SArindam Nath 
3522e9fb05d5SAdrian Hunter 	if (host->quirks2 & SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 &&
352328da3589SAdrian Hunter 	    (host->caps1 & SDHCI_SUPPORT_HS400))
3524e9fb05d5SAdrian Hunter 		mmc->caps2 |= MMC_CAP2_HS400;
3525e9fb05d5SAdrian Hunter 
3526549c0b18SAdrian Hunter 	if ((mmc->caps2 & MMC_CAP2_HSX00_1_2V) &&
3527549c0b18SAdrian Hunter 	    (IS_ERR(mmc->supply.vqmmc) ||
3528549c0b18SAdrian Hunter 	     !regulator_is_supported_voltage(mmc->supply.vqmmc, 1100000,
3529549c0b18SAdrian Hunter 					     1300000)))
3530549c0b18SAdrian Hunter 		mmc->caps2 &= ~MMC_CAP2_HSX00_1_2V;
3531549c0b18SAdrian Hunter 
353228da3589SAdrian Hunter 	if ((host->caps1 & SDHCI_SUPPORT_DDR50) &&
35339107ebbfSMicky Ching 	    !(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50))
3534f2119df6SArindam Nath 		mmc->caps |= MMC_CAP_UHS_DDR50;
3535f2119df6SArindam Nath 
3536069c9f14SGirish K S 	/* Does the host need tuning for SDR50? */
353728da3589SAdrian Hunter 	if (host->caps1 & SDHCI_USE_SDR50_TUNING)
3538b513ea25SArindam Nath 		host->flags |= SDHCI_SDR50_NEEDS_TUNING;
3539b513ea25SArindam Nath 
3540d6d50a15SArindam Nath 	/* Driver Type(s) (A, C, D) supported by the host */
354128da3589SAdrian Hunter 	if (host->caps1 & SDHCI_DRIVER_TYPE_A)
3542d6d50a15SArindam Nath 		mmc->caps |= MMC_CAP_DRIVER_TYPE_A;
354328da3589SAdrian Hunter 	if (host->caps1 & SDHCI_DRIVER_TYPE_C)
3544d6d50a15SArindam Nath 		mmc->caps |= MMC_CAP_DRIVER_TYPE_C;
354528da3589SAdrian Hunter 	if (host->caps1 & SDHCI_DRIVER_TYPE_D)
3546d6d50a15SArindam Nath 		mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
3547d6d50a15SArindam Nath 
3548cf2b5eeaSArindam Nath 	/* Initial value for re-tuning timer count */
354928da3589SAdrian Hunter 	host->tuning_count = (host->caps1 & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
3550cf2b5eeaSArindam Nath 			     SDHCI_RETUNING_TIMER_COUNT_SHIFT;
3551cf2b5eeaSArindam Nath 
3552cf2b5eeaSArindam Nath 	/*
3553cf2b5eeaSArindam Nath 	 * In case Re-tuning Timer is not disabled, the actual value of
3554cf2b5eeaSArindam Nath 	 * re-tuning timer will be 2 ^ (n - 1).
3555cf2b5eeaSArindam Nath 	 */
3556cf2b5eeaSArindam Nath 	if (host->tuning_count)
3557cf2b5eeaSArindam Nath 		host->tuning_count = 1 << (host->tuning_count - 1);
3558cf2b5eeaSArindam Nath 
3559cf2b5eeaSArindam Nath 	/* Re-tuning mode supported by the Host Controller */
356028da3589SAdrian Hunter 	host->tuning_mode = (host->caps1 & SDHCI_RETUNING_MODE_MASK) >>
3561cf2b5eeaSArindam Nath 			     SDHCI_RETUNING_MODE_SHIFT;
3562cf2b5eeaSArindam Nath 
35638f230f45STakashi Iwai 	ocr_avail = 0;
3564bad37e1aSPhilip Rakity 
3565f2119df6SArindam Nath 	/*
3566f2119df6SArindam Nath 	 * According to SD Host Controller spec v3.00, if the Host System
3567f2119df6SArindam Nath 	 * can afford more than 150mA, Host Driver should set XPC to 1. Also
3568f2119df6SArindam Nath 	 * the value is meaningful only if Voltage Support in the Capabilities
3569f2119df6SArindam Nath 	 * register is set. The actual current value is 4 times the register
3570f2119df6SArindam Nath 	 * value.
3571f2119df6SArindam Nath 	 */
3572f2119df6SArindam Nath 	max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT);
35733a48edc4STim Kryger 	if (!max_current_caps && !IS_ERR(mmc->supply.vmmc)) {
3574ae906037SChuanxiao.Dong 		int curr = regulator_get_current_limit(mmc->supply.vmmc);
3575bad37e1aSPhilip Rakity 		if (curr > 0) {
3576bad37e1aSPhilip Rakity 
3577bad37e1aSPhilip Rakity 			/* convert to SDHCI_MAX_CURRENT format */
3578bad37e1aSPhilip Rakity 			curr = curr/1000;  /* convert to mA */
3579bad37e1aSPhilip Rakity 			curr = curr/SDHCI_MAX_CURRENT_MULTIPLIER;
3580bad37e1aSPhilip Rakity 
3581bad37e1aSPhilip Rakity 			curr = min_t(u32, curr, SDHCI_MAX_CURRENT_LIMIT);
3582bad37e1aSPhilip Rakity 			max_current_caps =
3583bad37e1aSPhilip Rakity 				(curr << SDHCI_MAX_CURRENT_330_SHIFT) |
3584bad37e1aSPhilip Rakity 				(curr << SDHCI_MAX_CURRENT_300_SHIFT) |
3585bad37e1aSPhilip Rakity 				(curr << SDHCI_MAX_CURRENT_180_SHIFT);
3586bad37e1aSPhilip Rakity 		}
3587bad37e1aSPhilip Rakity 	}
3588f2119df6SArindam Nath 
358928da3589SAdrian Hunter 	if (host->caps & SDHCI_CAN_VDD_330) {
35908f230f45STakashi Iwai 		ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34;
3591f2119df6SArindam Nath 
359255c4665eSAaron Lu 		mmc->max_current_330 = ((max_current_caps &
3593f2119df6SArindam Nath 				   SDHCI_MAX_CURRENT_330_MASK) >>
3594f2119df6SArindam Nath 				   SDHCI_MAX_CURRENT_330_SHIFT) *
3595f2119df6SArindam Nath 				   SDHCI_MAX_CURRENT_MULTIPLIER;
3596f2119df6SArindam Nath 	}
359728da3589SAdrian Hunter 	if (host->caps & SDHCI_CAN_VDD_300) {
35988f230f45STakashi Iwai 		ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31;
3599f2119df6SArindam Nath 
360055c4665eSAaron Lu 		mmc->max_current_300 = ((max_current_caps &
3601f2119df6SArindam Nath 				   SDHCI_MAX_CURRENT_300_MASK) >>
3602f2119df6SArindam Nath 				   SDHCI_MAX_CURRENT_300_SHIFT) *
3603f2119df6SArindam Nath 				   SDHCI_MAX_CURRENT_MULTIPLIER;
3604f2119df6SArindam Nath 	}
360528da3589SAdrian Hunter 	if (host->caps & SDHCI_CAN_VDD_180) {
36068f230f45STakashi Iwai 		ocr_avail |= MMC_VDD_165_195;
36078f230f45STakashi Iwai 
360855c4665eSAaron Lu 		mmc->max_current_180 = ((max_current_caps &
3609f2119df6SArindam Nath 				   SDHCI_MAX_CURRENT_180_MASK) >>
3610f2119df6SArindam Nath 				   SDHCI_MAX_CURRENT_180_SHIFT) *
3611f2119df6SArindam Nath 				   SDHCI_MAX_CURRENT_MULTIPLIER;
3612f2119df6SArindam Nath 	}
3613f2119df6SArindam Nath 
36145fd26c7eSUlf Hansson 	/* If OCR set by host, use it instead. */
36155fd26c7eSUlf Hansson 	if (host->ocr_mask)
36165fd26c7eSUlf Hansson 		ocr_avail = host->ocr_mask;
36175fd26c7eSUlf Hansson 
36185fd26c7eSUlf Hansson 	/* If OCR set by external regulators, give it highest prio. */
36193a48edc4STim Kryger 	if (mmc->ocr_avail)
362052221610STim Kryger 		ocr_avail = mmc->ocr_avail;
36213a48edc4STim Kryger 
36228f230f45STakashi Iwai 	mmc->ocr_avail = ocr_avail;
36238f230f45STakashi Iwai 	mmc->ocr_avail_sdio = ocr_avail;
36248f230f45STakashi Iwai 	if (host->ocr_avail_sdio)
36258f230f45STakashi Iwai 		mmc->ocr_avail_sdio &= host->ocr_avail_sdio;
36268f230f45STakashi Iwai 	mmc->ocr_avail_sd = ocr_avail;
36278f230f45STakashi Iwai 	if (host->ocr_avail_sd)
36288f230f45STakashi Iwai 		mmc->ocr_avail_sd &= host->ocr_avail_sd;
36298f230f45STakashi Iwai 	else /* normal SD controllers don't support 1.8V */
36308f230f45STakashi Iwai 		mmc->ocr_avail_sd &= ~MMC_VDD_165_195;
36318f230f45STakashi Iwai 	mmc->ocr_avail_mmc = ocr_avail;
36328f230f45STakashi Iwai 	if (host->ocr_avail_mmc)
36338f230f45STakashi Iwai 		mmc->ocr_avail_mmc &= host->ocr_avail_mmc;
36341c6a0718SPierre Ossman 
36351c6a0718SPierre Ossman 	if (mmc->ocr_avail == 0) {
36362e4456f0SMarek Vasut 		pr_err("%s: Hardware doesn't report any support voltages.\n",
36372e4456f0SMarek Vasut 		       mmc_hostname(mmc));
3638eb5c20deSAdrian Hunter 		ret = -ENODEV;
3639eb5c20deSAdrian Hunter 		goto unreg;
36401c6a0718SPierre Ossman 	}
36411c6a0718SPierre Ossman 
36428cb851a4SAdrian Hunter 	if ((mmc->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
36438cb851a4SAdrian Hunter 			  MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
36448cb851a4SAdrian Hunter 			  MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR)) ||
36458cb851a4SAdrian Hunter 	    (mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS400_1_8V)))
36468cb851a4SAdrian Hunter 		host->flags |= SDHCI_SIGNALING_180;
36478cb851a4SAdrian Hunter 
36488cb851a4SAdrian Hunter 	if (mmc->caps2 & MMC_CAP2_HSX00_1_2V)
36498cb851a4SAdrian Hunter 		host->flags |= SDHCI_SIGNALING_120;
36508cb851a4SAdrian Hunter 
36511c6a0718SPierre Ossman 	spin_lock_init(&host->lock);
36521c6a0718SPierre Ossman 
36531c6a0718SPierre Ossman 	/*
36542134a922SPierre Ossman 	 * Maximum number of segments. Depends on if the hardware
36552134a922SPierre Ossman 	 * can do scatter/gather or not.
36561c6a0718SPierre Ossman 	 */
36572134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA)
36584fb213f8SAdrian Hunter 		mmc->max_segs = SDHCI_MAX_SEGS;
3659a13abc7bSRichard Röjfors 	else if (host->flags & SDHCI_USE_SDMA)
3660a36274e0SMartin K. Petersen 		mmc->max_segs = 1;
36612134a922SPierre Ossman 	else /* PIO */
36624fb213f8SAdrian Hunter 		mmc->max_segs = SDHCI_MAX_SEGS;
36631c6a0718SPierre Ossman 
36641c6a0718SPierre Ossman 	/*
3665ac00531dSAdrian Hunter 	 * Maximum number of sectors in one transfer. Limited by SDMA boundary
3666ac00531dSAdrian Hunter 	 * size (512KiB). Note some tuning modes impose a 4MiB limit, but this
3667ac00531dSAdrian Hunter 	 * is less anyway.
36681c6a0718SPierre Ossman 	 */
36691c6a0718SPierre Ossman 	mmc->max_req_size = 524288;
36701c6a0718SPierre Ossman 
36711c6a0718SPierre Ossman 	/*
36721c6a0718SPierre Ossman 	 * Maximum segment size. Could be one segment with the maximum number
36732134a922SPierre Ossman 	 * of bytes. When doing hardware scatter/gather, each entry cannot
36742134a922SPierre Ossman 	 * be larger than 64 KiB though.
36751c6a0718SPierre Ossman 	 */
367630652aa3SOlof Johansson 	if (host->flags & SDHCI_USE_ADMA) {
367730652aa3SOlof Johansson 		if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC)
367830652aa3SOlof Johansson 			mmc->max_seg_size = 65535;
36792134a922SPierre Ossman 		else
368030652aa3SOlof Johansson 			mmc->max_seg_size = 65536;
368130652aa3SOlof Johansson 	} else {
36821c6a0718SPierre Ossman 		mmc->max_seg_size = mmc->max_req_size;
368330652aa3SOlof Johansson 	}
36841c6a0718SPierre Ossman 
36851c6a0718SPierre Ossman 	/*
36861c6a0718SPierre Ossman 	 * Maximum block size. This varies from controller to controller and
36871c6a0718SPierre Ossman 	 * is specified in the capabilities register.
36881c6a0718SPierre Ossman 	 */
36890633f654SAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
36900633f654SAnton Vorontsov 		mmc->max_blk_size = 2;
36910633f654SAnton Vorontsov 	} else {
369228da3589SAdrian Hunter 		mmc->max_blk_size = (host->caps & SDHCI_MAX_BLOCK_MASK) >>
36930633f654SAnton Vorontsov 				SDHCI_MAX_BLOCK_SHIFT;
36941c6a0718SPierre Ossman 		if (mmc->max_blk_size >= 3) {
36956606110dSJoe Perches 			pr_warn("%s: Invalid maximum block size, assuming 512 bytes\n",
36966606110dSJoe Perches 				mmc_hostname(mmc));
36970633f654SAnton Vorontsov 			mmc->max_blk_size = 0;
36980633f654SAnton Vorontsov 		}
36990633f654SAnton Vorontsov 	}
37000633f654SAnton Vorontsov 
37011c6a0718SPierre Ossman 	mmc->max_blk_size = 512 << mmc->max_blk_size;
37021c6a0718SPierre Ossman 
37031c6a0718SPierre Ossman 	/*
37041c6a0718SPierre Ossman 	 * Maximum block count.
37051c6a0718SPierre Ossman 	 */
37061388eefdSBen Dooks 	mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
37071c6a0718SPierre Ossman 
370852f5336dSAdrian Hunter 	return 0;
370952f5336dSAdrian Hunter 
371052f5336dSAdrian Hunter unreg:
371152f5336dSAdrian Hunter 	if (!IS_ERR(mmc->supply.vqmmc))
371252f5336dSAdrian Hunter 		regulator_disable(mmc->supply.vqmmc);
371352f5336dSAdrian Hunter undma:
371452f5336dSAdrian Hunter 	if (host->align_buffer)
371552f5336dSAdrian Hunter 		dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz +
371652f5336dSAdrian Hunter 				  host->adma_table_sz, host->align_buffer,
371752f5336dSAdrian Hunter 				  host->align_addr);
371852f5336dSAdrian Hunter 	host->adma_table = NULL;
371952f5336dSAdrian Hunter 	host->align_buffer = NULL;
372052f5336dSAdrian Hunter 
372152f5336dSAdrian Hunter 	return ret;
372252f5336dSAdrian Hunter }
372352f5336dSAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_setup_host);
372452f5336dSAdrian Hunter 
37254180ffa8SAdrian Hunter void sdhci_cleanup_host(struct sdhci_host *host)
37264180ffa8SAdrian Hunter {
37274180ffa8SAdrian Hunter 	struct mmc_host *mmc = host->mmc;
37284180ffa8SAdrian Hunter 
37294180ffa8SAdrian Hunter 	if (!IS_ERR(mmc->supply.vqmmc))
37304180ffa8SAdrian Hunter 		regulator_disable(mmc->supply.vqmmc);
37314180ffa8SAdrian Hunter 
37324180ffa8SAdrian Hunter 	if (host->align_buffer)
37334180ffa8SAdrian Hunter 		dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz +
37344180ffa8SAdrian Hunter 				  host->adma_table_sz, host->align_buffer,
37354180ffa8SAdrian Hunter 				  host->align_addr);
37364180ffa8SAdrian Hunter 	host->adma_table = NULL;
37374180ffa8SAdrian Hunter 	host->align_buffer = NULL;
37384180ffa8SAdrian Hunter }
37394180ffa8SAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_cleanup_host);
37404180ffa8SAdrian Hunter 
374152f5336dSAdrian Hunter int __sdhci_add_host(struct sdhci_host *host)
374252f5336dSAdrian Hunter {
374352f5336dSAdrian Hunter 	struct mmc_host *mmc = host->mmc;
374452f5336dSAdrian Hunter 	int ret;
374552f5336dSAdrian Hunter 
37461c6a0718SPierre Ossman 	/*
37471c6a0718SPierre Ossman 	 * Init tasklets.
37481c6a0718SPierre Ossman 	 */
37491c6a0718SPierre Ossman 	tasklet_init(&host->finish_tasklet,
37501c6a0718SPierre Ossman 		sdhci_tasklet_finish, (unsigned long)host);
37511c6a0718SPierre Ossman 
37522ee4f620SKees Cook 	timer_setup(&host->timer, sdhci_timeout_timer, 0);
37532ee4f620SKees Cook 	timer_setup(&host->data_timer, sdhci_timeout_data_timer, 0);
37541c6a0718SPierre Ossman 
3755b513ea25SArindam Nath 	init_waitqueue_head(&host->buf_ready_int);
3756b513ea25SArindam Nath 
37572af502caSShawn Guo 	sdhci_init(host, 0);
37582af502caSShawn Guo 
3759781e989cSRussell King 	ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,
3760781e989cSRussell King 				   IRQF_SHARED,	mmc_hostname(mmc), host);
37610fc81ee3SMark Brown 	if (ret) {
37620fc81ee3SMark Brown 		pr_err("%s: Failed to request IRQ %d: %d\n",
37630fc81ee3SMark Brown 		       mmc_hostname(mmc), host->irq, ret);
37641c6a0718SPierre Ossman 		goto untasklet;
37650fc81ee3SMark Brown 	}
37661c6a0718SPierre Ossman 
3767061d17a6SAdrian Hunter 	ret = sdhci_led_register(host);
37680fc81ee3SMark Brown 	if (ret) {
37690fc81ee3SMark Brown 		pr_err("%s: Failed to register LED device: %d\n",
37700fc81ee3SMark Brown 		       mmc_hostname(mmc), ret);
3771eb5c20deSAdrian Hunter 		goto unirq;
37720fc81ee3SMark Brown 	}
37732f730fecSPierre Ossman 
37741c6a0718SPierre Ossman 	mmiowb();
37751c6a0718SPierre Ossman 
3776eb5c20deSAdrian Hunter 	ret = mmc_add_host(mmc);
3777eb5c20deSAdrian Hunter 	if (ret)
3778eb5c20deSAdrian Hunter 		goto unled;
37791c6a0718SPierre Ossman 
3780a3c76eb9SGirish K S 	pr_info("%s: SDHCI controller on %s [%s] using %s\n",
3781d1b26863SKay Sievers 		mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
3782e57a5f61SAdrian Hunter 		(host->flags & SDHCI_USE_ADMA) ?
3783e57a5f61SAdrian Hunter 		(host->flags & SDHCI_USE_64_BIT_DMA) ? "ADMA 64-bit" : "ADMA" :
3784a13abc7bSRichard Röjfors 		(host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
37851c6a0718SPierre Ossman 
37867260cf5eSAnton Vorontsov 	sdhci_enable_card_detection(host);
37877260cf5eSAnton Vorontsov 
37881c6a0718SPierre Ossman 	return 0;
37891c6a0718SPierre Ossman 
3790eb5c20deSAdrian Hunter unled:
3791061d17a6SAdrian Hunter 	sdhci_led_unregister(host);
3792eb5c20deSAdrian Hunter unirq:
379303231f9bSRussell King 	sdhci_do_reset(host, SDHCI_RESET_ALL);
3794b537f94cSRussell King 	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
3795b537f94cSRussell King 	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
37962f730fecSPierre Ossman 	free_irq(host->irq, host);
37971c6a0718SPierre Ossman untasklet:
37981c6a0718SPierre Ossman 	tasklet_kill(&host->finish_tasklet);
379952f5336dSAdrian Hunter 
38001c6a0718SPierre Ossman 	return ret;
38011c6a0718SPierre Ossman }
380252f5336dSAdrian Hunter EXPORT_SYMBOL_GPL(__sdhci_add_host);
38031c6a0718SPierre Ossman 
380452f5336dSAdrian Hunter int sdhci_add_host(struct sdhci_host *host)
380552f5336dSAdrian Hunter {
380652f5336dSAdrian Hunter 	int ret;
380752f5336dSAdrian Hunter 
380852f5336dSAdrian Hunter 	ret = sdhci_setup_host(host);
380952f5336dSAdrian Hunter 	if (ret)
381052f5336dSAdrian Hunter 		return ret;
381152f5336dSAdrian Hunter 
38124180ffa8SAdrian Hunter 	ret = __sdhci_add_host(host);
38134180ffa8SAdrian Hunter 	if (ret)
38144180ffa8SAdrian Hunter 		goto cleanup;
38154180ffa8SAdrian Hunter 
38164180ffa8SAdrian Hunter 	return 0;
38174180ffa8SAdrian Hunter 
38184180ffa8SAdrian Hunter cleanup:
38194180ffa8SAdrian Hunter 	sdhci_cleanup_host(host);
38204180ffa8SAdrian Hunter 
38214180ffa8SAdrian Hunter 	return ret;
382252f5336dSAdrian Hunter }
3823b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_add_host);
3824b8c86fc5SPierre Ossman 
38251e72859eSPierre Ossman void sdhci_remove_host(struct sdhci_host *host, int dead)
38261c6a0718SPierre Ossman {
38273a48edc4STim Kryger 	struct mmc_host *mmc = host->mmc;
38281e72859eSPierre Ossman 	unsigned long flags;
38291e72859eSPierre Ossman 
38301e72859eSPierre Ossman 	if (dead) {
38311e72859eSPierre Ossman 		spin_lock_irqsave(&host->lock, flags);
38321e72859eSPierre Ossman 
38331e72859eSPierre Ossman 		host->flags |= SDHCI_DEVICE_DEAD;
38341e72859eSPierre Ossman 
38355d0d11c5SAdrian Hunter 		if (sdhci_has_requests(host)) {
3836a3c76eb9SGirish K S 			pr_err("%s: Controller removed during "
38374e743f1fSMarkus Mayer 				" transfer!\n", mmc_hostname(mmc));
38385d0d11c5SAdrian Hunter 			sdhci_error_out_mrqs(host, -ENOMEDIUM);
38391e72859eSPierre Ossman 		}
38401e72859eSPierre Ossman 
38411e72859eSPierre Ossman 		spin_unlock_irqrestore(&host->lock, flags);
38421e72859eSPierre Ossman 	}
38431e72859eSPierre Ossman 
38447260cf5eSAnton Vorontsov 	sdhci_disable_card_detection(host);
38457260cf5eSAnton Vorontsov 
38464e743f1fSMarkus Mayer 	mmc_remove_host(mmc);
38471c6a0718SPierre Ossman 
3848061d17a6SAdrian Hunter 	sdhci_led_unregister(host);
38492f730fecSPierre Ossman 
38501e72859eSPierre Ossman 	if (!dead)
385103231f9bSRussell King 		sdhci_do_reset(host, SDHCI_RESET_ALL);
38521c6a0718SPierre Ossman 
3853b537f94cSRussell King 	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
3854b537f94cSRussell King 	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
38551c6a0718SPierre Ossman 	free_irq(host->irq, host);
38561c6a0718SPierre Ossman 
38571c6a0718SPierre Ossman 	del_timer_sync(&host->timer);
3858d7422fb4SAdrian Hunter 	del_timer_sync(&host->data_timer);
38591c6a0718SPierre Ossman 
38601c6a0718SPierre Ossman 	tasklet_kill(&host->finish_tasklet);
38612134a922SPierre Ossman 
38623a48edc4STim Kryger 	if (!IS_ERR(mmc->supply.vqmmc))
38633a48edc4STim Kryger 		regulator_disable(mmc->supply.vqmmc);
38646231f3deSPhilip Rakity 
3865edd63fccSRussell King 	if (host->align_buffer)
3866e66e61cbSRussell King 		dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz +
3867e66e61cbSRussell King 				  host->adma_table_sz, host->align_buffer,
3868e66e61cbSRussell King 				  host->align_addr);
38692134a922SPierre Ossman 
38704efaa6fbSAdrian Hunter 	host->adma_table = NULL;
38712134a922SPierre Ossman 	host->align_buffer = NULL;
38721c6a0718SPierre Ossman }
38731c6a0718SPierre Ossman 
3874b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_remove_host);
3875b8c86fc5SPierre Ossman 
3876b8c86fc5SPierre Ossman void sdhci_free_host(struct sdhci_host *host)
38771c6a0718SPierre Ossman {
3878b8c86fc5SPierre Ossman 	mmc_free_host(host->mmc);
38791c6a0718SPierre Ossman }
38801c6a0718SPierre Ossman 
3881b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_free_host);
38821c6a0718SPierre Ossman 
38831c6a0718SPierre Ossman /*****************************************************************************\
38841c6a0718SPierre Ossman  *                                                                           *
38851c6a0718SPierre Ossman  * Driver init/exit                                                          *
38861c6a0718SPierre Ossman  *                                                                           *
38871c6a0718SPierre Ossman \*****************************************************************************/
38881c6a0718SPierre Ossman 
38891c6a0718SPierre Ossman static int __init sdhci_drv_init(void)
38901c6a0718SPierre Ossman {
3891a3c76eb9SGirish K S 	pr_info(DRIVER_NAME
38921c6a0718SPierre Ossman 		": Secure Digital Host Controller Interface driver\n");
3893a3c76eb9SGirish K S 	pr_info(DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
38941c6a0718SPierre Ossman 
3895b8c86fc5SPierre Ossman 	return 0;
38961c6a0718SPierre Ossman }
38971c6a0718SPierre Ossman 
38981c6a0718SPierre Ossman static void __exit sdhci_drv_exit(void)
38991c6a0718SPierre Ossman {
39001c6a0718SPierre Ossman }
39011c6a0718SPierre Ossman 
39021c6a0718SPierre Ossman module_init(sdhci_drv_init);
39031c6a0718SPierre Ossman module_exit(sdhci_drv_exit);
39041c6a0718SPierre Ossman 
39051c6a0718SPierre Ossman module_param(debug_quirks, uint, 0444);
390666fd8ad5SAdrian Hunter module_param(debug_quirks2, uint, 0444);
39071c6a0718SPierre Ossman 
390832710e8fSPierre Ossman MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
3909b8c86fc5SPierre Ossman MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver");
39101c6a0718SPierre Ossman MODULE_LICENSE("GPL");
39111c6a0718SPierre Ossman 
39121c6a0718SPierre Ossman MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
391366fd8ad5SAdrian Hunter MODULE_PARM_DESC(debug_quirks2, "Force certain other quirks.");
3914