xref: /linux/drivers/mmc/host/sdhci-uhs2.c (revision 25768de50b1f2dbb6ea44bd5148a87fe2c9c3688)
12af7dd8bSVictor Shih // SPDX-License-Identifier: GPL-2.0-or-later
22af7dd8bSVictor Shih /*
32af7dd8bSVictor Shih  *  linux/drivers/mmc/host/sdhci_uhs2.c - Secure Digital Host Controller
42af7dd8bSVictor Shih  *  Interface driver
52af7dd8bSVictor Shih  *
62af7dd8bSVictor Shih  *  Copyright (C) 2014 Intel Corp, All Rights Reserved.
72af7dd8bSVictor Shih  *  Copyright (C) 2020 Genesys Logic, Inc.
82af7dd8bSVictor Shih  *  Authors: Ben Chuang <ben.chuang@genesyslogic.com.tw>
92af7dd8bSVictor Shih  *  Copyright (C) 2020 Linaro Limited
102af7dd8bSVictor Shih  *  Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
112af7dd8bSVictor Shih  */
122af7dd8bSVictor Shih 
139b1c779dSVictor Shih #include <linux/delay.h>
142af7dd8bSVictor Shih #include <linux/module.h>
159b1c779dSVictor Shih #include <linux/iopoll.h>
167e5b19f3SVictor Shih #include <linux/bitfield.h>
1706a0d072SVictor Shih #include <linux/regulator/consumer.h>
189cbb2358SVictor Shih #include <linux/mmc/mmc.h>
199cbb2358SVictor Shih #include <linux/mmc/host.h>
202af7dd8bSVictor Shih 
212af7dd8bSVictor Shih #include "sdhci.h"
222af7dd8bSVictor Shih #include "sdhci-uhs2.h"
232af7dd8bSVictor Shih 
242af7dd8bSVictor Shih #define DRIVER_NAME "sdhci_uhs2"
252af7dd8bSVictor Shih #define DBG(f, x...) \
262af7dd8bSVictor Shih 	pr_debug(DRIVER_NAME " [%s()]: " f, __func__, ## x)
270f8186f1SVictor Shih #define SDHCI_UHS2_DUMP(f, x...) \
280f8186f1SVictor Shih 	pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x)
290f8186f1SVictor Shih 
309b1c779dSVictor Shih #define UHS2_RESET_TIMEOUT_100MS		100000
314f412f79SVictor Shih #define UHS2_CHECK_DORMANT_TIMEOUT_100MS	100000
324f412f79SVictor Shih #define UHS2_INTERFACE_DETECT_TIMEOUT_100MS	100000
334f412f79SVictor Shih #define UHS2_LANE_SYNC_TIMEOUT_150MS		150000
349b1c779dSVictor Shih 
359cbb2358SVictor Shih #define UHS2_ARG_IOADR_MASK 0xfff
369cbb2358SVictor Shih 
370f8186f1SVictor Shih void sdhci_uhs2_dump_regs(struct sdhci_host *host)
380f8186f1SVictor Shih {
390f8186f1SVictor Shih 	if (!(mmc_card_uhs2(host->mmc)))
400f8186f1SVictor Shih 		return;
410f8186f1SVictor Shih 
420f8186f1SVictor Shih 	SDHCI_UHS2_DUMP("==================== UHS2 ==================\n");
430f8186f1SVictor Shih 	SDHCI_UHS2_DUMP("Blk Size:  0x%08x | Blk Cnt:  0x%08x\n",
440f8186f1SVictor Shih 			sdhci_readw(host, SDHCI_UHS2_BLOCK_SIZE),
450f8186f1SVictor Shih 			sdhci_readl(host, SDHCI_UHS2_BLOCK_COUNT));
460f8186f1SVictor Shih 	SDHCI_UHS2_DUMP("Cmd:       0x%08x | Trn mode: 0x%08x\n",
470f8186f1SVictor Shih 			sdhci_readw(host, SDHCI_UHS2_CMD),
480f8186f1SVictor Shih 			sdhci_readw(host, SDHCI_UHS2_TRANS_MODE));
490f8186f1SVictor Shih 	SDHCI_UHS2_DUMP("Int Stat:  0x%08x | Dev Sel : 0x%08x\n",
500f8186f1SVictor Shih 			sdhci_readw(host, SDHCI_UHS2_DEV_INT_STATUS),
510f8186f1SVictor Shih 			sdhci_readb(host, SDHCI_UHS2_DEV_SELECT));
520f8186f1SVictor Shih 	SDHCI_UHS2_DUMP("Dev Int Code:  0x%08x\n",
530f8186f1SVictor Shih 			sdhci_readb(host, SDHCI_UHS2_DEV_INT_CODE));
540f8186f1SVictor Shih 	SDHCI_UHS2_DUMP("Reset:     0x%08x | Timer:    0x%08x\n",
550f8186f1SVictor Shih 			sdhci_readw(host, SDHCI_UHS2_SW_RESET),
560f8186f1SVictor Shih 			sdhci_readw(host, SDHCI_UHS2_TIMER_CTRL));
570f8186f1SVictor Shih 	SDHCI_UHS2_DUMP("ErrInt:    0x%08x | ErrIntEn: 0x%08x\n",
580f8186f1SVictor Shih 			sdhci_readl(host, SDHCI_UHS2_INT_STATUS),
590f8186f1SVictor Shih 			sdhci_readl(host, SDHCI_UHS2_INT_STATUS_ENABLE));
600f8186f1SVictor Shih 	SDHCI_UHS2_DUMP("ErrSigEn:  0x%08x\n",
610f8186f1SVictor Shih 			sdhci_readl(host, SDHCI_UHS2_INT_SIGNAL_ENABLE));
620f8186f1SVictor Shih }
630f8186f1SVictor Shih EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs);
642af7dd8bSVictor Shih 
652af7dd8bSVictor Shih /*****************************************************************************\
662af7dd8bSVictor Shih  *                                                                           *
679b1c779dSVictor Shih  * Low level functions                                                       *
689b1c779dSVictor Shih  *                                                                           *
699b1c779dSVictor Shih \*****************************************************************************/
709b1c779dSVictor Shih 
719cbb2358SVictor Shih static inline u16 uhs2_dev_cmd(struct mmc_command *cmd)
729cbb2358SVictor Shih {
73*dd92de9fSVictor Shih 	return be16_to_cpu((__force __be16)cmd->uhs2_cmd->arg) & UHS2_ARG_IOADR_MASK;
749cbb2358SVictor Shih }
759cbb2358SVictor Shih 
766eb2c8e1SVictor Shih static inline int mmc_opt_regulator_set_ocr(struct mmc_host *mmc,
776eb2c8e1SVictor Shih 					    struct regulator *supply,
786eb2c8e1SVictor Shih 					    unsigned short vdd_bit)
796eb2c8e1SVictor Shih {
806eb2c8e1SVictor Shih 	return IS_ERR_OR_NULL(supply) ? 0 : mmc_regulator_set_ocr(mmc, supply, vdd_bit);
816eb2c8e1SVictor Shih }
826eb2c8e1SVictor Shih 
839b1c779dSVictor Shih /**
849b1c779dSVictor Shih  * sdhci_uhs2_reset - invoke SW reset
859b1c779dSVictor Shih  * @host: SDHCI host
869b1c779dSVictor Shih  * @mask: Control mask
879b1c779dSVictor Shih  *
889b1c779dSVictor Shih  * Invoke SW reset, depending on a bit in @mask and wait for completion.
899b1c779dSVictor Shih  */
909b1c779dSVictor Shih void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask)
919b1c779dSVictor Shih {
929b1c779dSVictor Shih 	u32 val;
939b1c779dSVictor Shih 
949b1c779dSVictor Shih 	sdhci_writew(host, mask, SDHCI_UHS2_SW_RESET);
959b1c779dSVictor Shih 
969b1c779dSVictor Shih 	if (mask & SDHCI_UHS2_SW_RESET_FULL)
979b1c779dSVictor Shih 		host->clock = 0;
989b1c779dSVictor Shih 
999b1c779dSVictor Shih 	/* hw clears the bit when it's done */
1009b1c779dSVictor Shih 	if (read_poll_timeout_atomic(sdhci_readw, val, !(val & mask), 10,
1019b1c779dSVictor Shih 				     UHS2_RESET_TIMEOUT_100MS, true, host, SDHCI_UHS2_SW_RESET)) {
1029b1c779dSVictor Shih 		pr_warn("%s: %s: Reset 0x%x never completed. %s: clean reset bit.\n", __func__,
1039b1c779dSVictor Shih 			mmc_hostname(host->mmc), (int)mask, mmc_hostname(host->mmc));
1049b1c779dSVictor Shih 		sdhci_writeb(host, 0, SDHCI_UHS2_SW_RESET);
1059b1c779dSVictor Shih 		return;
1069b1c779dSVictor Shih 	}
1079b1c779dSVictor Shih }
1089b1c779dSVictor Shih EXPORT_SYMBOL_GPL(sdhci_uhs2_reset);
1099b1c779dSVictor Shih 
110fca267f0SVictor Shih static void sdhci_uhs2_reset_cmd_data(struct sdhci_host *host)
111fca267f0SVictor Shih {
112fca267f0SVictor Shih 	sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
113fca267f0SVictor Shih 
114fca267f0SVictor Shih 	if (host->mmc->uhs2_sd_tran) {
115fca267f0SVictor Shih 		sdhci_uhs2_reset(host, SDHCI_UHS2_SW_RESET_SD);
116fca267f0SVictor Shih 
117fca267f0SVictor Shih 		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
118fca267f0SVictor Shih 		sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
119fca267f0SVictor Shih 		sdhci_uhs2_clear_set_irqs(host, SDHCI_INT_ALL_MASK, SDHCI_UHS2_INT_ERROR_MASK);
120fca267f0SVictor Shih 	}
121fca267f0SVictor Shih }
122fca267f0SVictor Shih 
1236eb2c8e1SVictor Shih void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, unsigned short vdd)
1246eb2c8e1SVictor Shih {
1256eb2c8e1SVictor Shih 	struct mmc_host *mmc = host->mmc;
1266eb2c8e1SVictor Shih 	u8 pwr = 0;
1276eb2c8e1SVictor Shih 
1286eb2c8e1SVictor Shih 	if (mode != MMC_POWER_OFF) {
1296eb2c8e1SVictor Shih 		pwr = sdhci_get_vdd_value(vdd);
1306eb2c8e1SVictor Shih 		if (!pwr)
1316eb2c8e1SVictor Shih 			WARN(1, "%s: Invalid vdd %#x\n",
1326eb2c8e1SVictor Shih 			     mmc_hostname(host->mmc), vdd);
1336eb2c8e1SVictor Shih 		pwr |= SDHCI_VDD2_POWER_180;
1346eb2c8e1SVictor Shih 	}
1356eb2c8e1SVictor Shih 
1366eb2c8e1SVictor Shih 	if (host->pwr == pwr)
1376eb2c8e1SVictor Shih 		return;
1386eb2c8e1SVictor Shih 	host->pwr = pwr;
1396eb2c8e1SVictor Shih 
1406eb2c8e1SVictor Shih 	if (pwr == 0) {
1416eb2c8e1SVictor Shih 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1426eb2c8e1SVictor Shih 
1436eb2c8e1SVictor Shih 		mmc_opt_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
1446eb2c8e1SVictor Shih 		mmc_regulator_set_vqmmc2(mmc, &mmc->ios);
1456eb2c8e1SVictor Shih 	} else {
1466eb2c8e1SVictor Shih 		mmc_opt_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
1476eb2c8e1SVictor Shih 		/* support 1.8v only for now */
1486eb2c8e1SVictor Shih 		mmc_regulator_set_vqmmc2(mmc, &mmc->ios);
1496eb2c8e1SVictor Shih 
1506eb2c8e1SVictor Shih 		/* Clear the power reg before setting a new value */
1516eb2c8e1SVictor Shih 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1526eb2c8e1SVictor Shih 
1536eb2c8e1SVictor Shih 		/* vdd first */
1546eb2c8e1SVictor Shih 		pwr |= SDHCI_POWER_ON;
1556eb2c8e1SVictor Shih 		sdhci_writeb(host, pwr & 0xf, SDHCI_POWER_CONTROL);
1566eb2c8e1SVictor Shih 		mdelay(5);
1576eb2c8e1SVictor Shih 
1586eb2c8e1SVictor Shih 		pwr |= SDHCI_VDD2_POWER_ON;
1596eb2c8e1SVictor Shih 		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1606eb2c8e1SVictor Shih 		mdelay(5);
1616eb2c8e1SVictor Shih 	}
1626eb2c8e1SVictor Shih }
1636eb2c8e1SVictor Shih EXPORT_SYMBOL_GPL(sdhci_uhs2_set_power);
1646eb2c8e1SVictor Shih 
1657e5b19f3SVictor Shih static u8 sdhci_calc_timeout_uhs2(struct sdhci_host *host, u8 *cmd_res, u8 *dead_lock)
1667e5b19f3SVictor Shih {
1677e5b19f3SVictor Shih 	/* timeout in us */
1687e5b19f3SVictor Shih 	unsigned int dead_lock_timeout = 1 * 1000 * 1000;
1697e5b19f3SVictor Shih 	unsigned int cmd_res_timeout = 5 * 1000;
1707e5b19f3SVictor Shih 	unsigned int current_timeout;
1717e5b19f3SVictor Shih 	u8 count;
1727e5b19f3SVictor Shih 
1737e5b19f3SVictor Shih 	/*
1747e5b19f3SVictor Shih 	 * Figure out needed cycles.
1757e5b19f3SVictor Shih 	 * We do this in steps in order to fit inside a 32 bit int.
1767e5b19f3SVictor Shih 	 * The first step is the minimum timeout, which will have a
1777e5b19f3SVictor Shih 	 * minimum resolution of 6 bits:
1787e5b19f3SVictor Shih 	 * (1) 2^13*1000 > 2^22,
1797e5b19f3SVictor Shih 	 * (2) host->timeout_clk < 2^16
1807e5b19f3SVictor Shih 	 *     =>
1817e5b19f3SVictor Shih 	 *     (1) / (2) > 2^6
1827e5b19f3SVictor Shih 	 */
1837e5b19f3SVictor Shih 	count = 0;
1847e5b19f3SVictor Shih 	current_timeout = (1 << 13) * 1000 / host->timeout_clk;
1857e5b19f3SVictor Shih 	while (current_timeout < cmd_res_timeout) {
1867e5b19f3SVictor Shih 		count++;
1877e5b19f3SVictor Shih 		current_timeout <<= 1;
1887e5b19f3SVictor Shih 		if (count >= 0xF)
1897e5b19f3SVictor Shih 			break;
1907e5b19f3SVictor Shih 	}
1917e5b19f3SVictor Shih 
1927e5b19f3SVictor Shih 	if (count >= 0xF) {
1937e5b19f3SVictor Shih 		DBG("%s: Too large timeout 0x%x requested for CMD_RES!\n",
1947e5b19f3SVictor Shih 		    mmc_hostname(host->mmc), count);
1957e5b19f3SVictor Shih 		count = 0xE;
1967e5b19f3SVictor Shih 	}
1977e5b19f3SVictor Shih 	*cmd_res = count;
1987e5b19f3SVictor Shih 
1997e5b19f3SVictor Shih 	count = 0;
2007e5b19f3SVictor Shih 	current_timeout = (1 << 13) * 1000 / host->timeout_clk;
2017e5b19f3SVictor Shih 	while (current_timeout < dead_lock_timeout) {
2027e5b19f3SVictor Shih 		count++;
2037e5b19f3SVictor Shih 		current_timeout <<= 1;
2047e5b19f3SVictor Shih 		if (count >= 0xF)
2057e5b19f3SVictor Shih 			break;
2067e5b19f3SVictor Shih 	}
2077e5b19f3SVictor Shih 
2087e5b19f3SVictor Shih 	if (count >= 0xF) {
2097e5b19f3SVictor Shih 		DBG("%s: Too large timeout 0x%x requested for DEADLOCK!\n",
2107e5b19f3SVictor Shih 		    mmc_hostname(host->mmc), count);
2117e5b19f3SVictor Shih 		count = 0xE;
2127e5b19f3SVictor Shih 	}
2137e5b19f3SVictor Shih 	*dead_lock = count;
2147e5b19f3SVictor Shih 
2157e5b19f3SVictor Shih 	return count;
2167e5b19f3SVictor Shih }
2177e5b19f3SVictor Shih 
2187e5b19f3SVictor Shih static void __sdhci_uhs2_set_timeout(struct sdhci_host *host)
2197e5b19f3SVictor Shih {
2207e5b19f3SVictor Shih 	u8 cmd_res, dead_lock;
2217e5b19f3SVictor Shih 
2227e5b19f3SVictor Shih 	sdhci_calc_timeout_uhs2(host, &cmd_res, &dead_lock);
2237e5b19f3SVictor Shih 	cmd_res |= FIELD_PREP(SDHCI_UHS2_TIMER_CTRL_DEADLOCK_MASK, dead_lock);
2247e5b19f3SVictor Shih 	sdhci_writeb(host, cmd_res, SDHCI_UHS2_TIMER_CTRL);
2257e5b19f3SVictor Shih }
2267e5b19f3SVictor Shih 
2277e5b19f3SVictor Shih void sdhci_uhs2_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
2287e5b19f3SVictor Shih {
2297e5b19f3SVictor Shih 	__sdhci_set_timeout(host, cmd);
2307e5b19f3SVictor Shih 
2317e5b19f3SVictor Shih 	if (mmc_card_uhs2(host->mmc))
2327e5b19f3SVictor Shih 		__sdhci_uhs2_set_timeout(host);
2337e5b19f3SVictor Shih }
2347e5b19f3SVictor Shih EXPORT_SYMBOL_GPL(sdhci_uhs2_set_timeout);
2357e5b19f3SVictor Shih 
23610c8298aSVictor Shih /**
23710c8298aSVictor Shih  * sdhci_uhs2_clear_set_irqs - set Error Interrupt Status Enable register
23810c8298aSVictor Shih  * @host:	SDHCI host
23910c8298aSVictor Shih  * @clear:	bit-wise clear mask
24010c8298aSVictor Shih  * @set:	bit-wise set mask
24110c8298aSVictor Shih  *
24210c8298aSVictor Shih  * Set/unset bits in UHS-II Error Interrupt Status Enable register
24310c8298aSVictor Shih  */
24410c8298aSVictor Shih void sdhci_uhs2_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
24510c8298aSVictor Shih {
24610c8298aSVictor Shih 	u32 ier;
24710c8298aSVictor Shih 
24810c8298aSVictor Shih 	ier = sdhci_readl(host, SDHCI_UHS2_INT_STATUS_ENABLE);
24910c8298aSVictor Shih 	ier &= ~clear;
25010c8298aSVictor Shih 	ier |= set;
25110c8298aSVictor Shih 	sdhci_writel(host, ier, SDHCI_UHS2_INT_STATUS_ENABLE);
25210c8298aSVictor Shih 	sdhci_writel(host, ier, SDHCI_UHS2_INT_SIGNAL_ENABLE);
25310c8298aSVictor Shih }
25410c8298aSVictor Shih EXPORT_SYMBOL_GPL(sdhci_uhs2_clear_set_irqs);
25510c8298aSVictor Shih 
25610c8298aSVictor Shih static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
25710c8298aSVictor Shih {
25810c8298aSVictor Shih 	struct sdhci_host *host = mmc_priv(mmc);
25910c8298aSVictor Shih 	u8 cmd_res, dead_lock;
26010c8298aSVictor Shih 	u16 ctrl_2;
26110c8298aSVictor Shih 
26210c8298aSVictor Shih 	/* UHS2 Timeout Control */
26310c8298aSVictor Shih 	sdhci_calc_timeout_uhs2(host, &cmd_res, &dead_lock);
26410c8298aSVictor Shih 
26510c8298aSVictor Shih 	/* change to use calculate value */
26610c8298aSVictor Shih 	cmd_res |= FIELD_PREP(SDHCI_UHS2_TIMER_CTRL_DEADLOCK_MASK, dead_lock);
26710c8298aSVictor Shih 
26810c8298aSVictor Shih 	sdhci_uhs2_clear_set_irqs(host,
26910c8298aSVictor Shih 				  SDHCI_UHS2_INT_CMD_TIMEOUT |
27010c8298aSVictor Shih 				  SDHCI_UHS2_INT_DEADLOCK_TIMEOUT,
27110c8298aSVictor Shih 				  0);
27210c8298aSVictor Shih 	sdhci_writeb(host, cmd_res, SDHCI_UHS2_TIMER_CTRL);
27310c8298aSVictor Shih 	sdhci_uhs2_clear_set_irqs(host, 0,
27410c8298aSVictor Shih 				  SDHCI_UHS2_INT_CMD_TIMEOUT |
27510c8298aSVictor Shih 				  SDHCI_UHS2_INT_DEADLOCK_TIMEOUT);
27610c8298aSVictor Shih 
27710c8298aSVictor Shih 	/* UHS2 timing. Note, UHS2 timing is disabled when powering off */
27810c8298aSVictor Shih 	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
27910c8298aSVictor Shih 	if (ios->power_mode != MMC_POWER_OFF &&
28010c8298aSVictor Shih 	    (ios->timing == MMC_TIMING_UHS2_SPEED_A ||
28110c8298aSVictor Shih 	     ios->timing == MMC_TIMING_UHS2_SPEED_A_HD ||
28210c8298aSVictor Shih 	     ios->timing == MMC_TIMING_UHS2_SPEED_B ||
28310c8298aSVictor Shih 	     ios->timing == MMC_TIMING_UHS2_SPEED_B_HD))
28410c8298aSVictor Shih 		ctrl_2 |= SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE;
28510c8298aSVictor Shih 	else
28610c8298aSVictor Shih 		ctrl_2 &= ~(SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE);
28710c8298aSVictor Shih 	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
28810c8298aSVictor Shih 	host->timing = ios->timing;
28910c8298aSVictor Shih 
29010c8298aSVictor Shih 	if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
29110c8298aSVictor Shih 		sdhci_enable_preset_value(host, true);
29210c8298aSVictor Shih 
29310c8298aSVictor Shih 	if (host->ops->set_power)
29410c8298aSVictor Shih 		host->ops->set_power(host, ios->power_mode, ios->vdd);
29510c8298aSVictor Shih 	else
29610c8298aSVictor Shih 		sdhci_uhs2_set_power(host, ios->power_mode, ios->vdd);
29710c8298aSVictor Shih 
29810c8298aSVictor Shih 	sdhci_set_clock(host, host->clock);
29910c8298aSVictor Shih }
30010c8298aSVictor Shih 
30110c8298aSVictor Shih static int sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
30210c8298aSVictor Shih {
30310c8298aSVictor Shih 	struct sdhci_host *host = mmc_priv(mmc);
30410c8298aSVictor Shih 
30510c8298aSVictor Shih 	pr_debug("%s: clock %uHz powermode %u Vdd %u timing %u\n",
30610c8298aSVictor Shih 		 mmc_hostname(mmc), ios->clock, ios->power_mode, ios->vdd, ios->timing);
30710c8298aSVictor Shih 
30810c8298aSVictor Shih 	if (!mmc_card_uhs2(mmc)) {
30910c8298aSVictor Shih 		sdhci_set_ios(mmc, ios);
31010c8298aSVictor Shih 		return 0;
31110c8298aSVictor Shih 	}
31210c8298aSVictor Shih 
31310c8298aSVictor Shih 	if (ios->power_mode == MMC_POWER_UNDEFINED)
31410c8298aSVictor Shih 		return 0;
31510c8298aSVictor Shih 
31610c8298aSVictor Shih 	if (host->flags & SDHCI_DEVICE_DEAD) {
31710c8298aSVictor Shih 		if (ios->power_mode == MMC_POWER_OFF) {
31810c8298aSVictor Shih 			mmc_opt_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
31910c8298aSVictor Shih 			mmc_regulator_set_vqmmc2(mmc, ios);
32010c8298aSVictor Shih 		}
32110c8298aSVictor Shih 		return -1;
32210c8298aSVictor Shih 	}
32310c8298aSVictor Shih 
32410c8298aSVictor Shih 	sdhci_set_ios_common(mmc, ios);
32510c8298aSVictor Shih 
32610c8298aSVictor Shih 	__sdhci_uhs2_set_ios(mmc, ios);
32710c8298aSVictor Shih 
32810c8298aSVictor Shih 	return 0;
32910c8298aSVictor Shih }
33010c8298aSVictor Shih 
3314f412f79SVictor Shih static int sdhci_uhs2_interface_detect(struct sdhci_host *host)
3324f412f79SVictor Shih {
3334f412f79SVictor Shih 	u32 val;
3344f412f79SVictor Shih 
3354f412f79SVictor Shih 	if (read_poll_timeout(sdhci_readl, val, (val & SDHCI_UHS2_IF_DETECT),
3364f412f79SVictor Shih 			      100, UHS2_INTERFACE_DETECT_TIMEOUT_100MS, true,
3374f412f79SVictor Shih 			      host, SDHCI_PRESENT_STATE)) {
3384f412f79SVictor Shih 		pr_warn("%s: not detect UHS2 interface in 100ms.\n", mmc_hostname(host->mmc));
3394f412f79SVictor Shih 		sdhci_dumpregs(host);
3404f412f79SVictor Shih 		return -EIO;
3414f412f79SVictor Shih 	}
3424f412f79SVictor Shih 
3434f412f79SVictor Shih 	/* Enable UHS2 error interrupts */
3444f412f79SVictor Shih 	sdhci_uhs2_clear_set_irqs(host, SDHCI_INT_ALL_MASK, SDHCI_UHS2_INT_ERROR_MASK);
3454f412f79SVictor Shih 
3464f412f79SVictor Shih 	if (read_poll_timeout(sdhci_readl, val, (val & SDHCI_UHS2_LANE_SYNC),
3474f412f79SVictor Shih 			      100, UHS2_LANE_SYNC_TIMEOUT_150MS, true, host, SDHCI_PRESENT_STATE)) {
3484f412f79SVictor Shih 		pr_warn("%s: UHS2 Lane sync fail in 150ms.\n", mmc_hostname(host->mmc));
3494f412f79SVictor Shih 		sdhci_dumpregs(host);
3504f412f79SVictor Shih 		return -EIO;
3514f412f79SVictor Shih 	}
3524f412f79SVictor Shih 
3534f412f79SVictor Shih 	DBG("%s: UHS2 Lane synchronized in UHS2 mode, PHY is initialized.\n",
3544f412f79SVictor Shih 	    mmc_hostname(host->mmc));
3554f412f79SVictor Shih 	return 0;
3564f412f79SVictor Shih }
3574f412f79SVictor Shih 
3584f412f79SVictor Shih static int sdhci_uhs2_init(struct sdhci_host *host)
3594f412f79SVictor Shih {
3604f412f79SVictor Shih 	u16 caps_ptr = 0;
3614f412f79SVictor Shih 	u32 caps_gen = 0;
3624f412f79SVictor Shih 	u32 caps_phy = 0;
3634f412f79SVictor Shih 	u32 caps_tran[2] = {0, 0};
3644f412f79SVictor Shih 	struct mmc_host *mmc = host->mmc;
3654f412f79SVictor Shih 
3664f412f79SVictor Shih 	caps_ptr = sdhci_readw(host, SDHCI_UHS2_CAPS_PTR);
3674f412f79SVictor Shih 	if (caps_ptr < 0x100 || caps_ptr > 0x1FF) {
3684f412f79SVictor Shih 		pr_err("%s: SDHCI_UHS2_CAPS_PTR(%d) is wrong.\n",
3694f412f79SVictor Shih 		       mmc_hostname(mmc), caps_ptr);
3704f412f79SVictor Shih 		return -ENODEV;
3714f412f79SVictor Shih 	}
3724f412f79SVictor Shih 	caps_gen = sdhci_readl(host, caps_ptr + SDHCI_UHS2_CAPS_OFFSET);
3734f412f79SVictor Shih 	caps_phy = sdhci_readl(host, caps_ptr + SDHCI_UHS2_CAPS_PHY_OFFSET);
3744f412f79SVictor Shih 	caps_tran[0] = sdhci_readl(host, caps_ptr + SDHCI_UHS2_CAPS_TRAN_OFFSET);
3754f412f79SVictor Shih 	caps_tran[1] = sdhci_readl(host, caps_ptr + SDHCI_UHS2_CAPS_TRAN_1_OFFSET);
3764f412f79SVictor Shih 
3774f412f79SVictor Shih 	/* General Caps */
3784f412f79SVictor Shih 	mmc->uhs2_caps.dap = caps_gen & SDHCI_UHS2_CAPS_DAP_MASK;
3794f412f79SVictor Shih 	mmc->uhs2_caps.gap = FIELD_GET(SDHCI_UHS2_CAPS_GAP_MASK, caps_gen);
3804f412f79SVictor Shih 	mmc->uhs2_caps.n_lanes = FIELD_GET(SDHCI_UHS2_CAPS_LANE_MASK, caps_gen);
3814f412f79SVictor Shih 	mmc->uhs2_caps.addr64 =	(caps_gen & SDHCI_UHS2_CAPS_ADDR_64) ? 1 : 0;
3824f412f79SVictor Shih 	mmc->uhs2_caps.card_type = FIELD_GET(SDHCI_UHS2_CAPS_DEV_TYPE_MASK, caps_gen);
3834f412f79SVictor Shih 
3844f412f79SVictor Shih 	/* PHY Caps */
3854f412f79SVictor Shih 	mmc->uhs2_caps.phy_rev = caps_phy & SDHCI_UHS2_CAPS_PHY_REV_MASK;
3864f412f79SVictor Shih 	mmc->uhs2_caps.speed_range = FIELD_GET(SDHCI_UHS2_CAPS_PHY_RANGE_MASK, caps_phy);
3874f412f79SVictor Shih 	mmc->uhs2_caps.n_lss_sync = FIELD_GET(SDHCI_UHS2_CAPS_PHY_N_LSS_SYN_MASK, caps_phy);
3884f412f79SVictor Shih 	mmc->uhs2_caps.n_lss_dir = FIELD_GET(SDHCI_UHS2_CAPS_PHY_N_LSS_DIR_MASK, caps_phy);
3894f412f79SVictor Shih 	if (mmc->uhs2_caps.n_lss_sync == 0)
3904f412f79SVictor Shih 		mmc->uhs2_caps.n_lss_sync = 16 << 2;
3914f412f79SVictor Shih 	else
3924f412f79SVictor Shih 		mmc->uhs2_caps.n_lss_sync <<= 2;
3934f412f79SVictor Shih 	if (mmc->uhs2_caps.n_lss_dir == 0)
3944f412f79SVictor Shih 		mmc->uhs2_caps.n_lss_dir = 16 << 3;
3954f412f79SVictor Shih 	else
3964f412f79SVictor Shih 		mmc->uhs2_caps.n_lss_dir <<= 3;
3974f412f79SVictor Shih 
3984f412f79SVictor Shih 	/* LINK/TRAN Caps */
3994f412f79SVictor Shih 	mmc->uhs2_caps.link_rev = caps_tran[0] & SDHCI_UHS2_CAPS_TRAN_LINK_REV_MASK;
4004f412f79SVictor Shih 	mmc->uhs2_caps.n_fcu = FIELD_GET(SDHCI_UHS2_CAPS_TRAN_N_FCU_MASK, caps_tran[0]);
4014f412f79SVictor Shih 	if (mmc->uhs2_caps.n_fcu == 0)
4024f412f79SVictor Shih 		mmc->uhs2_caps.n_fcu = 256;
4034f412f79SVictor Shih 	mmc->uhs2_caps.host_type = FIELD_GET(SDHCI_UHS2_CAPS_TRAN_HOST_TYPE_MASK, caps_tran[0]);
4044f412f79SVictor Shih 	mmc->uhs2_caps.maxblk_len = FIELD_GET(SDHCI_UHS2_CAPS_TRAN_BLK_LEN_MASK, caps_tran[0]);
4054f412f79SVictor Shih 	mmc->uhs2_caps.n_data_gap = caps_tran[1] & SDHCI_UHS2_CAPS_TRAN_1_N_DATA_GAP_MASK;
4064f412f79SVictor Shih 
4074f412f79SVictor Shih 	return 0;
4084f412f79SVictor Shih }
4094f412f79SVictor Shih 
4104f412f79SVictor Shih static int sdhci_uhs2_do_detect_init(struct mmc_host *mmc)
4114f412f79SVictor Shih {
4124f412f79SVictor Shih 	struct sdhci_host *host = mmc_priv(mmc);
4134f412f79SVictor Shih 
4144f412f79SVictor Shih 	DBG("Begin do uhs2 detect init.\n");
4154f412f79SVictor Shih 
41654ef4b39SBen Chuang 	if (host->ops->uhs2_pre_detect_init)
417379e4dc5SBen Chuang 		host->ops->uhs2_pre_detect_init(host);
418379e4dc5SBen Chuang 
4194f412f79SVictor Shih 	if (sdhci_uhs2_interface_detect(host)) {
4204f412f79SVictor Shih 		pr_warn("%s: cannot detect UHS2 interface.\n", mmc_hostname(host->mmc));
4214f412f79SVictor Shih 		return -EIO;
4224f412f79SVictor Shih 	}
4234f412f79SVictor Shih 
4244f412f79SVictor Shih 	if (sdhci_uhs2_init(host)) {
4254f412f79SVictor Shih 		pr_warn("%s: UHS2 init fail.\n", mmc_hostname(host->mmc));
4264f412f79SVictor Shih 		return -EIO;
4274f412f79SVictor Shih 	}
4284f412f79SVictor Shih 
4294f412f79SVictor Shih 	/* Init complete, do soft reset and enable UHS2 error irqs. */
4304f412f79SVictor Shih 	sdhci_uhs2_reset(host, SDHCI_UHS2_SW_RESET_SD);
4314f412f79SVictor Shih 	sdhci_uhs2_clear_set_irqs(host, SDHCI_INT_ALL_MASK, SDHCI_UHS2_INT_ERROR_MASK);
4324f412f79SVictor Shih 	/*
4334f412f79SVictor Shih 	 * N.B SDHCI_INT_ENABLE and SDHCI_SIGNAL_ENABLE was cleared
4344f412f79SVictor Shih 	 * by SDHCI_UHS2_SW_RESET_SD
4354f412f79SVictor Shih 	 */
4364f412f79SVictor Shih 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
4374f412f79SVictor Shih 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
4384f412f79SVictor Shih 
4394f412f79SVictor Shih 	return 0;
4404f412f79SVictor Shih }
4414f412f79SVictor Shih 
4424f412f79SVictor Shih static int sdhci_uhs2_disable_clk(struct mmc_host *mmc)
4434f412f79SVictor Shih {
4444f412f79SVictor Shih 	struct sdhci_host *host = mmc_priv(mmc);
4454f412f79SVictor Shih 	u16 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
4464f412f79SVictor Shih 
4474f412f79SVictor Shih 	clk &= ~SDHCI_CLOCK_CARD_EN;
4484f412f79SVictor Shih 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
4494f412f79SVictor Shih 
4504f412f79SVictor Shih 	return 0;
4514f412f79SVictor Shih }
4524f412f79SVictor Shih 
4534f412f79SVictor Shih static int sdhci_uhs2_enable_clk(struct mmc_host *mmc)
4544f412f79SVictor Shih {
4554f412f79SVictor Shih 	struct sdhci_host *host = mmc_priv(mmc);
4564f412f79SVictor Shih 	u16 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
4574f412f79SVictor Shih 	int timeout_us = 20000; /* 20ms */
4584f412f79SVictor Shih 	u32 val;
4594f412f79SVictor Shih 
4604f412f79SVictor Shih 	clk |= SDHCI_CLOCK_CARD_EN;
4614f412f79SVictor Shih 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
4624f412f79SVictor Shih 
4634f412f79SVictor Shih 	if (read_poll_timeout(sdhci_readw, val, (val & SDHCI_CLOCK_INT_STABLE),
4644f412f79SVictor Shih 			      10, timeout_us, true, host, SDHCI_CLOCK_CONTROL)) {
4654f412f79SVictor Shih 		pr_err("%s: Internal clock never stabilised.\n", mmc_hostname(host->mmc));
4664f412f79SVictor Shih 		sdhci_dumpregs(host);
4674f412f79SVictor Shih 		return -EIO;
4684f412f79SVictor Shih 	}
4694f412f79SVictor Shih 	return 0;
4704f412f79SVictor Shih }
4714f412f79SVictor Shih 
4724f412f79SVictor Shih static void sdhci_uhs2_set_config(struct sdhci_host *host)
4734f412f79SVictor Shih {
4744f412f79SVictor Shih 	u32 value;
4754f412f79SVictor Shih 	u16 sdhci_uhs2_set_ptr = sdhci_readw(host, SDHCI_UHS2_SETTINGS_PTR);
4764f412f79SVictor Shih 	u16 sdhci_uhs2_gen_set_reg	= sdhci_uhs2_set_ptr;
4774f412f79SVictor Shih 	u16 sdhci_uhs2_phy_set_reg	= sdhci_uhs2_set_ptr + 4;
4784f412f79SVictor Shih 	u16 sdhci_uhs2_tran_set_reg	= sdhci_uhs2_set_ptr + 8;
4794f412f79SVictor Shih 	u16 sdhci_uhs2_tran_set_1_reg	= sdhci_uhs2_set_ptr + 12;
4804f412f79SVictor Shih 
4814f412f79SVictor Shih 	/* Set Gen Settings */
4824f412f79SVictor Shih 	value = FIELD_PREP(SDHCI_UHS2_GEN_SETTINGS_N_LANES_MASK, host->mmc->uhs2_caps.n_lanes_set);
4834f412f79SVictor Shih 	sdhci_writel(host, value, sdhci_uhs2_gen_set_reg);
4844f412f79SVictor Shih 
4854f412f79SVictor Shih 	/* Set PHY Settings */
4864f412f79SVictor Shih 	value = FIELD_PREP(SDHCI_UHS2_PHY_N_LSS_DIR_MASK, host->mmc->uhs2_caps.n_lss_dir_set) |
4874f412f79SVictor Shih 		FIELD_PREP(SDHCI_UHS2_PHY_N_LSS_SYN_MASK, host->mmc->uhs2_caps.n_lss_sync_set);
4884f412f79SVictor Shih 	if (host->mmc->ios.timing == MMC_TIMING_UHS2_SPEED_B ||
4894f412f79SVictor Shih 	    host->mmc->ios.timing == MMC_TIMING_UHS2_SPEED_B_HD)
4904f412f79SVictor Shih 		value |= SDHCI_UHS2_PHY_SET_SPEED_B;
4914f412f79SVictor Shih 	sdhci_writel(host, value, sdhci_uhs2_phy_set_reg);
4924f412f79SVictor Shih 
4934f412f79SVictor Shih 	/* Set LINK-TRAN Settings */
4944f412f79SVictor Shih 	value = FIELD_PREP(SDHCI_UHS2_TRAN_RETRY_CNT_MASK, host->mmc->uhs2_caps.max_retry_set) |
4954f412f79SVictor Shih 		FIELD_PREP(SDHCI_UHS2_TRAN_N_FCU_MASK, host->mmc->uhs2_caps.n_fcu_set);
4964f412f79SVictor Shih 	sdhci_writel(host, value, sdhci_uhs2_tran_set_reg);
4974f412f79SVictor Shih 	sdhci_writel(host, host->mmc->uhs2_caps.n_data_gap_set, sdhci_uhs2_tran_set_1_reg);
4984f412f79SVictor Shih }
4994f412f79SVictor Shih 
5004f412f79SVictor Shih static int sdhci_uhs2_check_dormant(struct sdhci_host *host)
5014f412f79SVictor Shih {
5024f412f79SVictor Shih 	u32 val;
5034f412f79SVictor Shih 
5044f412f79SVictor Shih 	if (read_poll_timeout(sdhci_readl, val, (val & SDHCI_UHS2_IN_DORMANT_STATE),
5054f412f79SVictor Shih 			      100, UHS2_CHECK_DORMANT_TIMEOUT_100MS, true, host,
5064f412f79SVictor Shih 			      SDHCI_PRESENT_STATE)) {
5074f412f79SVictor Shih 		pr_warn("%s: UHS2 IN_DORMANT fail in 100ms.\n", mmc_hostname(host->mmc));
5084f412f79SVictor Shih 		sdhci_dumpregs(host);
5094f412f79SVictor Shih 		return -EIO;
5104f412f79SVictor Shih 	}
5114f412f79SVictor Shih 	return 0;
5124f412f79SVictor Shih }
5134f412f79SVictor Shih 
51410c8298aSVictor Shih static int sdhci_uhs2_control(struct mmc_host *mmc, enum sd_uhs2_operation op)
51510c8298aSVictor Shih {
51610c8298aSVictor Shih 	struct sdhci_host *host = mmc_priv(mmc);
51710c8298aSVictor Shih 	struct mmc_ios *ios = &mmc->ios;
51810c8298aSVictor Shih 	int err = 0;
51910c8298aSVictor Shih 
52010c8298aSVictor Shih 	DBG("Begin uhs2 control, act %d.\n", op);
52110c8298aSVictor Shih 
52210c8298aSVictor Shih 	switch (op) {
5234f412f79SVictor Shih 	case UHS2_PHY_INIT:
5244f412f79SVictor Shih 		err = sdhci_uhs2_do_detect_init(mmc);
5254f412f79SVictor Shih 		break;
5264f412f79SVictor Shih 	case UHS2_SET_CONFIG:
5274f412f79SVictor Shih 		sdhci_uhs2_set_config(host);
5284f412f79SVictor Shih 		break;
5294f412f79SVictor Shih 	case UHS2_ENABLE_INT:
5304f412f79SVictor Shih 		sdhci_uhs2_clear_set_irqs(host, 0, SDHCI_INT_CARD_INT);
5314f412f79SVictor Shih 		break;
5324f412f79SVictor Shih 	case UHS2_DISABLE_INT:
5334f412f79SVictor Shih 		sdhci_uhs2_clear_set_irqs(host, SDHCI_INT_CARD_INT, 0);
5344f412f79SVictor Shih 		break;
5354f412f79SVictor Shih 	case UHS2_CHECK_DORMANT:
5364f412f79SVictor Shih 		err = sdhci_uhs2_check_dormant(host);
5374f412f79SVictor Shih 		break;
5384f412f79SVictor Shih 	case UHS2_DISABLE_CLK:
5394f412f79SVictor Shih 		err = sdhci_uhs2_disable_clk(mmc);
5404f412f79SVictor Shih 		break;
5414f412f79SVictor Shih 	case UHS2_ENABLE_CLK:
5424f412f79SVictor Shih 		err = sdhci_uhs2_enable_clk(mmc);
5434f412f79SVictor Shih 		break;
54410c8298aSVictor Shih 	case UHS2_SET_IOS:
54510c8298aSVictor Shih 		err = sdhci_uhs2_set_ios(mmc, ios);
54610c8298aSVictor Shih 		break;
54710c8298aSVictor Shih 	default:
54810c8298aSVictor Shih 		pr_err("%s: input sd uhs2 operation %d is wrong!\n",
54910c8298aSVictor Shih 		       mmc_hostname(host->mmc), op);
55010c8298aSVictor Shih 		err = -EIO;
55110c8298aSVictor Shih 		break;
55210c8298aSVictor Shih 	}
55310c8298aSVictor Shih 
55410c8298aSVictor Shih 	return err;
55510c8298aSVictor Shih }
55610c8298aSVictor Shih 
5579b1c779dSVictor Shih /*****************************************************************************\
5589b1c779dSVictor Shih  *                                                                           *
5599cbb2358SVictor Shih  * Core functions                                                            *
5609cbb2358SVictor Shih  *                                                                           *
5619cbb2358SVictor Shih \*****************************************************************************/
5629cbb2358SVictor Shih 
5639cbb2358SVictor Shih static void sdhci_uhs2_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
5649cbb2358SVictor Shih {
5659cbb2358SVictor Shih 	struct mmc_data *data = cmd->data;
5669cbb2358SVictor Shih 
5679cbb2358SVictor Shih 	sdhci_initialize_data(host, data);
5689cbb2358SVictor Shih 
5699cbb2358SVictor Shih 	sdhci_prepare_dma(host, data);
5709cbb2358SVictor Shih 
5719cbb2358SVictor Shih 	sdhci_writew(host, data->blksz, SDHCI_UHS2_BLOCK_SIZE);
5729cbb2358SVictor Shih 	sdhci_writew(host, data->blocks, SDHCI_UHS2_BLOCK_COUNT);
5739cbb2358SVictor Shih }
5749cbb2358SVictor Shih 
5759cbb2358SVictor Shih static void sdhci_uhs2_finish_data(struct sdhci_host *host)
5769cbb2358SVictor Shih {
5779cbb2358SVictor Shih 	struct mmc_data *data = host->data;
5789cbb2358SVictor Shih 
5799cbb2358SVictor Shih 	__sdhci_finish_data_common(host, true);
5809cbb2358SVictor Shih 
5819cbb2358SVictor Shih 	__sdhci_finish_mrq(host, data->mrq);
5829cbb2358SVictor Shih }
5839cbb2358SVictor Shih 
5849cbb2358SVictor Shih static void sdhci_uhs2_set_transfer_mode(struct sdhci_host *host, struct mmc_command *cmd)
5859cbb2358SVictor Shih {
5869cbb2358SVictor Shih 	u16 mode;
5879cbb2358SVictor Shih 	struct mmc_data *data = cmd->data;
5889cbb2358SVictor Shih 
5899cbb2358SVictor Shih 	if (!data) {
5909cbb2358SVictor Shih 		/* clear Auto CMD settings for no data CMDs */
5919cbb2358SVictor Shih 		if (uhs2_dev_cmd(cmd) == UHS2_DEV_CMD_TRANS_ABORT) {
5929cbb2358SVictor Shih 			mode =  0;
5939cbb2358SVictor Shih 		} else {
5949cbb2358SVictor Shih 			mode = sdhci_readw(host, SDHCI_UHS2_TRANS_MODE);
5959cbb2358SVictor Shih 			if (cmd->opcode == MMC_STOP_TRANSMISSION || cmd->opcode == MMC_ERASE)
5969cbb2358SVictor Shih 				mode |= SDHCI_UHS2_TRNS_WAIT_EBSY;
5979cbb2358SVictor Shih 			else
5989cbb2358SVictor Shih 				/* send status mode */
5999cbb2358SVictor Shih 				if (cmd->opcode == MMC_SEND_STATUS)
6009cbb2358SVictor Shih 					mode = 0;
6019cbb2358SVictor Shih 		}
6029cbb2358SVictor Shih 
6039cbb2358SVictor Shih 		DBG("UHS2 no data trans mode is 0x%x.\n", mode);
6049cbb2358SVictor Shih 
6059cbb2358SVictor Shih 		sdhci_writew(host, mode, SDHCI_UHS2_TRANS_MODE);
6069cbb2358SVictor Shih 		return;
6079cbb2358SVictor Shih 	}
6089cbb2358SVictor Shih 
6099cbb2358SVictor Shih 	WARN_ON(!host->data);
6109cbb2358SVictor Shih 
6119cbb2358SVictor Shih 	mode = SDHCI_UHS2_TRNS_BLK_CNT_EN | SDHCI_UHS2_TRNS_WAIT_EBSY;
6129cbb2358SVictor Shih 	if (data->flags & MMC_DATA_WRITE)
6139cbb2358SVictor Shih 		mode |= SDHCI_UHS2_TRNS_DATA_TRNS_WRT;
6149cbb2358SVictor Shih 
6159cbb2358SVictor Shih 	if (data->blocks == 1 &&
6169cbb2358SVictor Shih 	    data->blksz != 512 &&
6179cbb2358SVictor Shih 	    cmd->opcode != MMC_READ_SINGLE_BLOCK &&
6189cbb2358SVictor Shih 	    cmd->opcode != MMC_WRITE_BLOCK) {
6199cbb2358SVictor Shih 		mode &= ~SDHCI_UHS2_TRNS_BLK_CNT_EN;
6209cbb2358SVictor Shih 		mode |= SDHCI_UHS2_TRNS_BLK_BYTE_MODE;
6219cbb2358SVictor Shih 	}
6229cbb2358SVictor Shih 
6239cbb2358SVictor Shih 	if (host->flags & SDHCI_REQ_USE_DMA)
6249cbb2358SVictor Shih 		mode |= SDHCI_UHS2_TRNS_DMA;
6259cbb2358SVictor Shih 
6269cbb2358SVictor Shih 	if (cmd->uhs2_cmd->tmode_half_duplex)
6279cbb2358SVictor Shih 		mode |= SDHCI_UHS2_TRNS_2L_HD;
6289cbb2358SVictor Shih 
6299cbb2358SVictor Shih 	sdhci_writew(host, mode, SDHCI_UHS2_TRANS_MODE);
6309cbb2358SVictor Shih 
6319cbb2358SVictor Shih 	DBG("UHS2 trans mode is 0x%x.\n", mode);
6329cbb2358SVictor Shih }
6339cbb2358SVictor Shih 
6349cbb2358SVictor Shih static void __sdhci_uhs2_send_command(struct sdhci_host *host, struct mmc_command *cmd)
6359cbb2358SVictor Shih {
6369cbb2358SVictor Shih 	int i, j;
6379cbb2358SVictor Shih 	int cmd_reg;
6389cbb2358SVictor Shih 
6399cbb2358SVictor Shih 	i = 0;
6409cbb2358SVictor Shih 	sdhci_writel(host,
6419cbb2358SVictor Shih 		     ((u32)cmd->uhs2_cmd->arg << 16) |
6429cbb2358SVictor Shih 				(u32)cmd->uhs2_cmd->header,
6439cbb2358SVictor Shih 		     SDHCI_UHS2_CMD_PACKET + i);
6449cbb2358SVictor Shih 	i += 4;
6459cbb2358SVictor Shih 
6469cbb2358SVictor Shih 	/*
6479cbb2358SVictor Shih 	 * Per spec, payload (config) should be MSB before sending out.
6489cbb2358SVictor Shih 	 * But we don't need convert here because had set payload as
6499cbb2358SVictor Shih 	 * MSB when preparing config read/write commands.
6509cbb2358SVictor Shih 	 */
6519cbb2358SVictor Shih 	for (j = 0; j < cmd->uhs2_cmd->payload_len / sizeof(u32); j++) {
652259d262eSVictor Shih 		sdhci_writel(host, *(__force u32 *)(cmd->uhs2_cmd->payload + j),
653259d262eSVictor Shih 			     SDHCI_UHS2_CMD_PACKET + i);
6549cbb2358SVictor Shih 		i += 4;
6559cbb2358SVictor Shih 	}
6569cbb2358SVictor Shih 
6579cbb2358SVictor Shih 	for ( ; i < SDHCI_UHS2_CMD_PACK_MAX_LEN; i += 4)
6589cbb2358SVictor Shih 		sdhci_writel(host, 0, SDHCI_UHS2_CMD_PACKET + i);
6599cbb2358SVictor Shih 
6609cbb2358SVictor Shih 	DBG("UHS2 CMD packet_len = %d.\n", cmd->uhs2_cmd->packet_len);
6619cbb2358SVictor Shih 	for (i = 0; i < cmd->uhs2_cmd->packet_len; i++)
6629cbb2358SVictor Shih 		DBG("UHS2 CMD_PACKET[%d] = 0x%x.\n", i,
6639cbb2358SVictor Shih 		    sdhci_readb(host, SDHCI_UHS2_CMD_PACKET + i));
6649cbb2358SVictor Shih 
6659cbb2358SVictor Shih 	cmd_reg = FIELD_PREP(SDHCI_UHS2_CMD_PACK_LEN_MASK, cmd->uhs2_cmd->packet_len);
6669cbb2358SVictor Shih 	if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC)
6679cbb2358SVictor Shih 		cmd_reg |= SDHCI_UHS2_CMD_DATA;
6689cbb2358SVictor Shih 	if (cmd->opcode == MMC_STOP_TRANSMISSION)
6699cbb2358SVictor Shih 		cmd_reg |= SDHCI_UHS2_CMD_CMD12;
6709cbb2358SVictor Shih 
6719cbb2358SVictor Shih 	/* UHS2 Native ABORT */
6729cbb2358SVictor Shih 	if ((cmd->uhs2_cmd->header & UHS2_NATIVE_PACKET) &&
6739cbb2358SVictor Shih 	    (uhs2_dev_cmd(cmd) == UHS2_DEV_CMD_TRANS_ABORT))
6749cbb2358SVictor Shih 		cmd_reg |= SDHCI_UHS2_CMD_TRNS_ABORT;
6759cbb2358SVictor Shih 
6769cbb2358SVictor Shih 	/* UHS2 Native DORMANT */
6779cbb2358SVictor Shih 	if ((cmd->uhs2_cmd->header & UHS2_NATIVE_PACKET) &&
6789cbb2358SVictor Shih 	    (uhs2_dev_cmd(cmd) == UHS2_DEV_CMD_GO_DORMANT_STATE))
6799cbb2358SVictor Shih 		cmd_reg |= SDHCI_UHS2_CMD_DORMANT;
6809cbb2358SVictor Shih 
6819cbb2358SVictor Shih 	DBG("0x%x is set to UHS2 CMD register.\n", cmd_reg);
6829cbb2358SVictor Shih 
6839cbb2358SVictor Shih 	sdhci_writew(host, cmd_reg, SDHCI_UHS2_CMD);
6849cbb2358SVictor Shih }
6859cbb2358SVictor Shih 
6869cbb2358SVictor Shih static bool sdhci_uhs2_send_command(struct sdhci_host *host, struct mmc_command *cmd)
6879cbb2358SVictor Shih {
6889cbb2358SVictor Shih 	u32 mask;
6899cbb2358SVictor Shih 	unsigned long timeout;
6909cbb2358SVictor Shih 
6919cbb2358SVictor Shih 	WARN_ON(host->cmd);
6929cbb2358SVictor Shih 
6939cbb2358SVictor Shih 	/* Initially, a command has no error */
6949cbb2358SVictor Shih 	cmd->error = 0;
6959cbb2358SVictor Shih 
6969cbb2358SVictor Shih 	if (cmd->opcode == MMC_STOP_TRANSMISSION)
6979cbb2358SVictor Shih 		cmd->flags |= MMC_RSP_BUSY;
6989cbb2358SVictor Shih 
6999cbb2358SVictor Shih 	mask = SDHCI_CMD_INHIBIT;
7009cbb2358SVictor Shih 
7019cbb2358SVictor Shih 	if (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask)
7029cbb2358SVictor Shih 		return false;
7039cbb2358SVictor Shih 
7049cbb2358SVictor Shih 	host->cmd = cmd;
7059cbb2358SVictor Shih 	host->data_timeout = 0;
7069cbb2358SVictor Shih 	if (sdhci_data_line_cmd(cmd)) {
7079cbb2358SVictor Shih 		WARN_ON(host->data_cmd);
7089cbb2358SVictor Shih 		host->data_cmd = cmd;
7099cbb2358SVictor Shih 		__sdhci_uhs2_set_timeout(host);
7109cbb2358SVictor Shih 	}
7119cbb2358SVictor Shih 
7129cbb2358SVictor Shih 	if (cmd->data)
7139cbb2358SVictor Shih 		sdhci_uhs2_prepare_data(host, cmd);
7149cbb2358SVictor Shih 
7159cbb2358SVictor Shih 	sdhci_uhs2_set_transfer_mode(host, cmd);
7169cbb2358SVictor Shih 
7179cbb2358SVictor Shih 	timeout = jiffies;
7189cbb2358SVictor Shih 	if (host->data_timeout)
7199cbb2358SVictor Shih 		timeout += nsecs_to_jiffies(host->data_timeout);
7209cbb2358SVictor Shih 	else if (!cmd->data && cmd->busy_timeout > 9000)
7219cbb2358SVictor Shih 		timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ;
7229cbb2358SVictor Shih 	else
7239cbb2358SVictor Shih 		timeout += 10 * HZ;
7249cbb2358SVictor Shih 	sdhci_mod_timer(host, cmd->mrq, timeout);
7259cbb2358SVictor Shih 
7269cbb2358SVictor Shih 	__sdhci_uhs2_send_command(host, cmd);
7279cbb2358SVictor Shih 
7289cbb2358SVictor Shih 	return true;
7299cbb2358SVictor Shih }
7309cbb2358SVictor Shih 
7319cbb2358SVictor Shih static bool sdhci_uhs2_send_command_retry(struct sdhci_host *host,
7329cbb2358SVictor Shih 					  struct mmc_command *cmd,
7339cbb2358SVictor Shih 					  unsigned long flags)
7349cbb2358SVictor Shih 	__releases(host->lock)
7359cbb2358SVictor Shih 	__acquires(host->lock)
7369cbb2358SVictor Shih {
7379cbb2358SVictor Shih 	struct mmc_command *deferred_cmd = host->deferred_cmd;
7389cbb2358SVictor Shih 	int timeout = 10; /* Approx. 10 ms */
7399cbb2358SVictor Shih 	bool present;
7409cbb2358SVictor Shih 
7419cbb2358SVictor Shih 	while (!sdhci_uhs2_send_command(host, cmd)) {
7429cbb2358SVictor Shih 		if (!timeout--) {
7439cbb2358SVictor Shih 			pr_err("%s: Controller never released inhibit bit(s).\n",
7449cbb2358SVictor Shih 			       mmc_hostname(host->mmc));
7459cbb2358SVictor Shih 			sdhci_dumpregs(host);
7469cbb2358SVictor Shih 			cmd->error = -EIO;
7479cbb2358SVictor Shih 			return false;
7489cbb2358SVictor Shih 		}
7499cbb2358SVictor Shih 
7509cbb2358SVictor Shih 		spin_unlock_irqrestore(&host->lock, flags);
7519cbb2358SVictor Shih 
7529cbb2358SVictor Shih 		usleep_range(1000, 1250);
7539cbb2358SVictor Shih 
7549cbb2358SVictor Shih 		present = host->mmc->ops->get_cd(host->mmc);
7559cbb2358SVictor Shih 
7569cbb2358SVictor Shih 		spin_lock_irqsave(&host->lock, flags);
7579cbb2358SVictor Shih 
7589cbb2358SVictor Shih 		/* A deferred command might disappear, handle that */
7599cbb2358SVictor Shih 		if (cmd == deferred_cmd && cmd != host->deferred_cmd)
7609cbb2358SVictor Shih 			return true;
7619cbb2358SVictor Shih 
7629cbb2358SVictor Shih 		if (sdhci_present_error(host, cmd, present))
7639cbb2358SVictor Shih 			return false;
7649cbb2358SVictor Shih 	}
7659cbb2358SVictor Shih 
7669cbb2358SVictor Shih 	if (cmd == host->deferred_cmd)
7679cbb2358SVictor Shih 		host->deferred_cmd = NULL;
7689cbb2358SVictor Shih 
7699cbb2358SVictor Shih 	return true;
7709cbb2358SVictor Shih }
7719cbb2358SVictor Shih 
7729cbb2358SVictor Shih static void __sdhci_uhs2_finish_command(struct sdhci_host *host)
7739cbb2358SVictor Shih {
7749cbb2358SVictor Shih 	struct mmc_command *cmd = host->cmd;
7759cbb2358SVictor Shih 	u8 resp;
7769cbb2358SVictor Shih 	u8 error_code;
7779cbb2358SVictor Shih 	bool breada0 = 0;
7789cbb2358SVictor Shih 	int i;
7799cbb2358SVictor Shih 
7809cbb2358SVictor Shih 	if (host->mmc->uhs2_sd_tran) {
7819cbb2358SVictor Shih 		resp = sdhci_readb(host, SDHCI_UHS2_RESPONSE + 2);
7829cbb2358SVictor Shih 		if (resp & UHS2_RES_NACK_MASK) {
7839cbb2358SVictor Shih 			error_code = (resp >> UHS2_RES_ECODE_POS) & UHS2_RES_ECODE_MASK;
7849cbb2358SVictor Shih 			pr_err("%s: NACK response, ECODE=0x%x.\n",
7859cbb2358SVictor Shih 			       mmc_hostname(host->mmc), error_code);
7869cbb2358SVictor Shih 		}
7879cbb2358SVictor Shih 		breada0 = 1;
7889cbb2358SVictor Shih 	}
7899cbb2358SVictor Shih 
7909cbb2358SVictor Shih 	if (cmd->uhs2_cmd->uhs2_resp_len) {
7919cbb2358SVictor Shih 		int len = min_t(int, cmd->uhs2_cmd->uhs2_resp_len, UHS2_MAX_RESP_LEN);
7929cbb2358SVictor Shih 
7939cbb2358SVictor Shih 		/* Get whole response of some native CCMD, like
7949cbb2358SVictor Shih 		 * DEVICE_INIT, ENUMERATE.
7959cbb2358SVictor Shih 		 */
7969cbb2358SVictor Shih 		for (i = 0; i < len; i++)
7979cbb2358SVictor Shih 			cmd->uhs2_cmd->uhs2_resp[i] = sdhci_readb(host, SDHCI_UHS2_RESPONSE + i);
7989cbb2358SVictor Shih 	} else {
7999cbb2358SVictor Shih 		/* Get SD CMD response and Payload for some read
8009cbb2358SVictor Shih 		 * CCMD, like INQUIRY_CFG.
8019cbb2358SVictor Shih 		 */
8029cbb2358SVictor Shih 		/* Per spec (p136), payload field is divided into
8039cbb2358SVictor Shih 		 * a unit of DWORD and transmission order within
8049cbb2358SVictor Shih 		 * a DWORD is big endian.
8059cbb2358SVictor Shih 		 */
8069cbb2358SVictor Shih 		if (!breada0)
8079cbb2358SVictor Shih 			sdhci_readl(host, SDHCI_UHS2_RESPONSE);
8089cbb2358SVictor Shih 		for (i = 4; i < 20; i += 4) {
8099cbb2358SVictor Shih 			cmd->resp[i / 4 - 1] =
8109cbb2358SVictor Shih 				(sdhci_readb(host,
8119cbb2358SVictor Shih 					     SDHCI_UHS2_RESPONSE + i) << 24) |
8129cbb2358SVictor Shih 				(sdhci_readb(host,
8139cbb2358SVictor Shih 					     SDHCI_UHS2_RESPONSE + i + 1)
8149cbb2358SVictor Shih 					<< 16) |
8159cbb2358SVictor Shih 				(sdhci_readb(host,
8169cbb2358SVictor Shih 					     SDHCI_UHS2_RESPONSE + i + 2)
8179cbb2358SVictor Shih 					<< 8) |
8189cbb2358SVictor Shih 				sdhci_readb(host, SDHCI_UHS2_RESPONSE + i + 3);
8199cbb2358SVictor Shih 		}
8209cbb2358SVictor Shih 	}
8219cbb2358SVictor Shih }
8229cbb2358SVictor Shih 
8239cbb2358SVictor Shih static void sdhci_uhs2_finish_command(struct sdhci_host *host)
8249cbb2358SVictor Shih {
8259cbb2358SVictor Shih 	struct mmc_command *cmd = host->cmd;
8269cbb2358SVictor Shih 
8279cbb2358SVictor Shih 	__sdhci_uhs2_finish_command(host);
8289cbb2358SVictor Shih 
8299cbb2358SVictor Shih 	host->cmd = NULL;
8309cbb2358SVictor Shih 
8319cbb2358SVictor Shih 	if (cmd->mrq->cap_cmd_during_tfr && cmd == cmd->mrq->cmd)
8329cbb2358SVictor Shih 		mmc_command_done(host->mmc, cmd->mrq);
8339cbb2358SVictor Shih 
8349cbb2358SVictor Shih 	/*
8359cbb2358SVictor Shih 	 * The host can send and interrupt when the busy state has
8369cbb2358SVictor Shih 	 * ended, allowing us to wait without wasting CPU cycles.
8379cbb2358SVictor Shih 	 * The busy signal uses DAT0 so this is similar to waiting
8389cbb2358SVictor Shih 	 * for data to complete.
8399cbb2358SVictor Shih 	 *
8409cbb2358SVictor Shih 	 * Note: The 1.0 specification is a bit ambiguous about this
8419cbb2358SVictor Shih 	 *       feature so there might be some problems with older
8429cbb2358SVictor Shih 	 *       controllers.
8439cbb2358SVictor Shih 	 */
8449cbb2358SVictor Shih 	if (cmd->flags & MMC_RSP_BUSY) {
8459cbb2358SVictor Shih 		if (cmd->data) {
8469cbb2358SVictor Shih 			DBG("Cannot wait for busy signal when also doing a data transfer");
8479cbb2358SVictor Shih 		} else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
8489cbb2358SVictor Shih 			   cmd == host->data_cmd) {
8499cbb2358SVictor Shih 			/* Command complete before busy is ended */
8509cbb2358SVictor Shih 			return;
8519cbb2358SVictor Shih 		}
8529cbb2358SVictor Shih 	}
8539cbb2358SVictor Shih 
8549cbb2358SVictor Shih 	/* Processed actual command. */
8559cbb2358SVictor Shih 	if (host->data && host->data_early)
8569cbb2358SVictor Shih 		sdhci_uhs2_finish_data(host);
8579cbb2358SVictor Shih 
8589cbb2358SVictor Shih 	if (!cmd->data)
8599cbb2358SVictor Shih 		__sdhci_finish_mrq(host, cmd->mrq);
8609cbb2358SVictor Shih }
8619cbb2358SVictor Shih 
8629cbb2358SVictor Shih static void sdhci_uhs2_request(struct mmc_host *mmc, struct mmc_request *mrq)
8639cbb2358SVictor Shih {
8649cbb2358SVictor Shih 	struct sdhci_host *host = mmc_priv(mmc);
8659cbb2358SVictor Shih 	struct mmc_command *cmd;
8669cbb2358SVictor Shih 	unsigned long flags;
8679cbb2358SVictor Shih 	bool present;
8689cbb2358SVictor Shih 
8699cbb2358SVictor Shih 	if (!(mmc_card_uhs2(mmc))) {
8709cbb2358SVictor Shih 		sdhci_request(mmc, mrq);
8719cbb2358SVictor Shih 		return;
8729cbb2358SVictor Shih 	}
8739cbb2358SVictor Shih 
8749cbb2358SVictor Shih 	mrq->stop = NULL;
8759cbb2358SVictor Shih 	mrq->sbc = NULL;
8769cbb2358SVictor Shih 	if (mrq->data)
8779cbb2358SVictor Shih 		mrq->data->stop = NULL;
8789cbb2358SVictor Shih 
8799cbb2358SVictor Shih 	/* Firstly check card presence */
8809cbb2358SVictor Shih 	present = mmc->ops->get_cd(mmc);
8819cbb2358SVictor Shih 
8829cbb2358SVictor Shih 	spin_lock_irqsave(&host->lock, flags);
8839cbb2358SVictor Shih 
8849cbb2358SVictor Shih 	if (sdhci_present_error(host, mrq->cmd, present))
8859cbb2358SVictor Shih 		goto out_finish;
8869cbb2358SVictor Shih 
8879cbb2358SVictor Shih 	cmd = mrq->cmd;
8889cbb2358SVictor Shih 
8899cbb2358SVictor Shih 	if (!sdhci_uhs2_send_command_retry(host, cmd, flags))
8909cbb2358SVictor Shih 		goto out_finish;
8919cbb2358SVictor Shih 
8929cbb2358SVictor Shih 	spin_unlock_irqrestore(&host->lock, flags);
8939cbb2358SVictor Shih 
8949cbb2358SVictor Shih 	return;
8959cbb2358SVictor Shih 
8969cbb2358SVictor Shih out_finish:
8979cbb2358SVictor Shih 	sdhci_finish_mrq(host, mrq);
8989cbb2358SVictor Shih 	spin_unlock_irqrestore(&host->lock, flags);
8999cbb2358SVictor Shih }
9009cbb2358SVictor Shih 
9019cbb2358SVictor Shih /*****************************************************************************\
9029cbb2358SVictor Shih  *                                                                           *
903fca267f0SVictor Shih  * Request done                                                              *
904fca267f0SVictor Shih  *                                                                           *
905fca267f0SVictor Shih \*****************************************************************************/
906fca267f0SVictor Shih 
907fca267f0SVictor Shih static bool sdhci_uhs2_needs_reset(struct sdhci_host *host, struct mmc_request *mrq)
908fca267f0SVictor Shih {
909fca267f0SVictor Shih 	return sdhci_needs_reset(host, mrq) ||
910fca267f0SVictor Shih 	       (!(host->flags & SDHCI_DEVICE_DEAD) && mrq->data && mrq->data->error);
911fca267f0SVictor Shih }
912fca267f0SVictor Shih 
913fca267f0SVictor Shih static bool sdhci_uhs2_request_done(struct sdhci_host *host)
914fca267f0SVictor Shih {
915fca267f0SVictor Shih 	unsigned long flags;
916fca267f0SVictor Shih 	struct mmc_request *mrq;
917fca267f0SVictor Shih 	int i;
918fca267f0SVictor Shih 
919fca267f0SVictor Shih 	spin_lock_irqsave(&host->lock, flags);
920fca267f0SVictor Shih 
921fca267f0SVictor Shih 	for (i = 0; i < SDHCI_MAX_MRQS; i++) {
922fca267f0SVictor Shih 		mrq = host->mrqs_done[i];
923fca267f0SVictor Shih 		if (mrq)
924fca267f0SVictor Shih 			break;
925fca267f0SVictor Shih 	}
926fca267f0SVictor Shih 
927fca267f0SVictor Shih 	if (!mrq) {
928fca267f0SVictor Shih 		spin_unlock_irqrestore(&host->lock, flags);
929fca267f0SVictor Shih 		return true;
930fca267f0SVictor Shih 	}
931fca267f0SVictor Shih 
932fca267f0SVictor Shih 	/*
933fca267f0SVictor Shih 	 * Always unmap the data buffers if they were mapped by
934fca267f0SVictor Shih 	 * sdhci_prepare_data() whenever we finish with a request.
935fca267f0SVictor Shih 	 * This avoids leaking DMA mappings on error.
936fca267f0SVictor Shih 	 */
937fca267f0SVictor Shih 	if (host->flags & SDHCI_REQ_USE_DMA)
938fca267f0SVictor Shih 		sdhci_request_done_dma(host, mrq);
939fca267f0SVictor Shih 
940fca267f0SVictor Shih 	/*
941fca267f0SVictor Shih 	 * The controller needs a reset of internal state machines
942fca267f0SVictor Shih 	 * upon error conditions.
943fca267f0SVictor Shih 	 */
944fca267f0SVictor Shih 	if (sdhci_uhs2_needs_reset(host, mrq)) {
945fca267f0SVictor Shih 		/*
946fca267f0SVictor Shih 		 * Do not finish until command and data lines are available for
947fca267f0SVictor Shih 		 * reset. Note there can only be one other mrq, so it cannot
948fca267f0SVictor Shih 		 * also be in mrqs_done, otherwise host->cmd and host->data_cmd
949fca267f0SVictor Shih 		 * would both be null.
950fca267f0SVictor Shih 		 */
951fca267f0SVictor Shih 		if (host->cmd || host->data_cmd) {
952fca267f0SVictor Shih 			spin_unlock_irqrestore(&host->lock, flags);
953fca267f0SVictor Shih 			return true;
954fca267f0SVictor Shih 		}
955fca267f0SVictor Shih 
956fca267f0SVictor Shih 		if (mrq->cmd->error || mrq->data->error)
957fca267f0SVictor Shih 			sdhci_uhs2_reset_cmd_data(host);
958fca267f0SVictor Shih 		else
959fca267f0SVictor Shih 			sdhci_uhs2_reset(host, SDHCI_UHS2_SW_RESET_SD);
960fca267f0SVictor Shih 		host->pending_reset = false;
961fca267f0SVictor Shih 	}
962fca267f0SVictor Shih 
963fca267f0SVictor Shih 	host->mrqs_done[i] = NULL;
964fca267f0SVictor Shih 
965fca267f0SVictor Shih 	spin_unlock_irqrestore(&host->lock, flags);
966fca267f0SVictor Shih 
967fca267f0SVictor Shih 	if (host->ops->request_done)
968fca267f0SVictor Shih 		host->ops->request_done(host, mrq);
969fca267f0SVictor Shih 	else
970fca267f0SVictor Shih 		mmc_request_done(host->mmc, mrq);
971fca267f0SVictor Shih 
972fca267f0SVictor Shih 	return false;
973fca267f0SVictor Shih }
974fca267f0SVictor Shih 
975fca267f0SVictor Shih static void sdhci_uhs2_complete_work(struct work_struct *work)
976fca267f0SVictor Shih {
977fca267f0SVictor Shih 	struct sdhci_host *host = container_of(work, struct sdhci_host,
978fca267f0SVictor Shih 					       complete_work);
979fca267f0SVictor Shih 
980fca267f0SVictor Shih 	if (!mmc_card_uhs2(host->mmc)) {
981fca267f0SVictor Shih 		sdhci_complete_work(work);
982fca267f0SVictor Shih 		return;
983fca267f0SVictor Shih 	}
984fca267f0SVictor Shih 
985fca267f0SVictor Shih 	while (!sdhci_uhs2_request_done(host))
986fca267f0SVictor Shih 		;
987fca267f0SVictor Shih }
988fca267f0SVictor Shih 
989fca267f0SVictor Shih /*****************************************************************************\
990fca267f0SVictor Shih  *                                                                           *
991fca267f0SVictor Shih  * Interrupt handling                                                        *
992fca267f0SVictor Shih  *                                                                           *
993fca267f0SVictor Shih \*****************************************************************************/
994fca267f0SVictor Shih 
995fca267f0SVictor Shih static void __sdhci_uhs2_irq(struct sdhci_host *host, u32 uhs2mask)
996fca267f0SVictor Shih {
9979cbb2358SVictor Shih 	struct mmc_command *cmd = host->cmd;
9989cbb2358SVictor Shih 
999fca267f0SVictor Shih 	DBG("*** %s got UHS2 error interrupt: 0x%08x\n",
1000fca267f0SVictor Shih 	    mmc_hostname(host->mmc), uhs2mask);
1001fca267f0SVictor Shih 
1002fca267f0SVictor Shih 	if (uhs2mask & SDHCI_UHS2_INT_CMD_ERR_MASK) {
1003fca267f0SVictor Shih 		if (!host->cmd) {
1004fca267f0SVictor Shih 			pr_err("%s: Got cmd interrupt 0x%08x but no cmd.\n",
1005fca267f0SVictor Shih 			       mmc_hostname(host->mmc),
1006fca267f0SVictor Shih 			       (unsigned int)uhs2mask);
1007fca267f0SVictor Shih 			sdhci_dumpregs(host);
1008fca267f0SVictor Shih 			return;
1009fca267f0SVictor Shih 		}
1010fca267f0SVictor Shih 		host->cmd->error = -EILSEQ;
1011fca267f0SVictor Shih 		if (uhs2mask & SDHCI_UHS2_INT_CMD_TIMEOUT)
1012fca267f0SVictor Shih 			host->cmd->error = -ETIMEDOUT;
1013fca267f0SVictor Shih 	}
1014fca267f0SVictor Shih 
1015fca267f0SVictor Shih 	if (uhs2mask & SDHCI_UHS2_INT_DATA_ERR_MASK) {
1016fca267f0SVictor Shih 		if (!host->data) {
1017fca267f0SVictor Shih 			pr_err("%s: Got data interrupt 0x%08x but no data.\n",
1018fca267f0SVictor Shih 			       mmc_hostname(host->mmc),
1019fca267f0SVictor Shih 			       (unsigned int)uhs2mask);
1020fca267f0SVictor Shih 			sdhci_dumpregs(host);
1021fca267f0SVictor Shih 			return;
1022fca267f0SVictor Shih 		}
1023fca267f0SVictor Shih 
1024fca267f0SVictor Shih 		if (uhs2mask & SDHCI_UHS2_INT_DEADLOCK_TIMEOUT) {
1025fca267f0SVictor Shih 			pr_err("%s: Got deadlock timeout interrupt 0x%08x\n",
1026fca267f0SVictor Shih 			       mmc_hostname(host->mmc),
1027fca267f0SVictor Shih 			       (unsigned int)uhs2mask);
1028fca267f0SVictor Shih 			host->data->error = -ETIMEDOUT;
1029fca267f0SVictor Shih 		} else if (uhs2mask & SDHCI_UHS2_INT_ADMA_ERROR) {
1030fca267f0SVictor Shih 			pr_err("%s: ADMA error = 0x %x\n",
1031fca267f0SVictor Shih 			       mmc_hostname(host->mmc),
1032fca267f0SVictor Shih 			       sdhci_readb(host, SDHCI_ADMA_ERROR));
1033fca267f0SVictor Shih 			host->data->error = -EIO;
1034fca267f0SVictor Shih 		} else {
1035fca267f0SVictor Shih 			host->data->error = -EILSEQ;
1036fca267f0SVictor Shih 		}
1037fca267f0SVictor Shih 	}
10389cbb2358SVictor Shih 
10399cbb2358SVictor Shih 	if (host->data && host->data->error)
10409cbb2358SVictor Shih 		sdhci_uhs2_finish_data(host);
10419cbb2358SVictor Shih 	else
10429cbb2358SVictor Shih 		sdhci_finish_mrq(host, cmd->mrq);
10439cbb2358SVictor Shih 
1044fca267f0SVictor Shih }
1045fca267f0SVictor Shih 
1046fca267f0SVictor Shih u32 sdhci_uhs2_irq(struct sdhci_host *host, u32 intmask)
1047fca267f0SVictor Shih {
1048fca267f0SVictor Shih 	u32 mask = intmask, uhs2mask;
1049fca267f0SVictor Shih 
1050fca267f0SVictor Shih 	if (!mmc_card_uhs2(host->mmc))
1051fca267f0SVictor Shih 		goto out;
1052fca267f0SVictor Shih 
1053fca267f0SVictor Shih 	if (intmask & SDHCI_INT_ERROR) {
1054fca267f0SVictor Shih 		uhs2mask = sdhci_readl(host, SDHCI_UHS2_INT_STATUS);
1055fca267f0SVictor Shih 		if (!(uhs2mask & SDHCI_UHS2_INT_ERROR_MASK))
1056fca267f0SVictor Shih 			goto cmd_irq;
1057fca267f0SVictor Shih 
1058fca267f0SVictor Shih 		/* Clear error interrupts */
1059fca267f0SVictor Shih 		sdhci_writel(host, uhs2mask & SDHCI_UHS2_INT_ERROR_MASK,
1060fca267f0SVictor Shih 			     SDHCI_UHS2_INT_STATUS);
1061fca267f0SVictor Shih 
1062fca267f0SVictor Shih 		/* Handle error interrupts */
1063fca267f0SVictor Shih 		__sdhci_uhs2_irq(host, uhs2mask);
1064fca267f0SVictor Shih 
1065fca267f0SVictor Shih 		/* Caller, sdhci_irq(), doesn't have to care about UHS-2 errors */
1066fca267f0SVictor Shih 		intmask &= ~SDHCI_INT_ERROR;
1067fca267f0SVictor Shih 		mask &= SDHCI_INT_ERROR;
1068fca267f0SVictor Shih 	}
1069fca267f0SVictor Shih 
1070fca267f0SVictor Shih cmd_irq:
1071fca267f0SVictor Shih 	if (intmask & SDHCI_INT_CMD_MASK) {
1072fca267f0SVictor Shih 		/* Clear command interrupt */
1073fca267f0SVictor Shih 		sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK, SDHCI_INT_STATUS);
1074fca267f0SVictor Shih 
10759cbb2358SVictor Shih 		/* Handle command interrupt */
10769cbb2358SVictor Shih 		if (intmask & SDHCI_INT_RESPONSE)
10779cbb2358SVictor Shih 			sdhci_uhs2_finish_command(host);
10789cbb2358SVictor Shih 
1079fca267f0SVictor Shih 		/* Caller, sdhci_irq(), doesn't have to care about UHS-2 commands */
1080fca267f0SVictor Shih 		intmask &= ~SDHCI_INT_CMD_MASK;
1081fca267f0SVictor Shih 		mask &= SDHCI_INT_CMD_MASK;
1082fca267f0SVictor Shih 	}
1083fca267f0SVictor Shih 
1084fca267f0SVictor Shih 	/* Clear already-handled interrupts. */
1085fca267f0SVictor Shih 	sdhci_writel(host, mask, SDHCI_INT_STATUS);
1086fca267f0SVictor Shih 
1087fca267f0SVictor Shih out:
1088fca267f0SVictor Shih 	return intmask;
1089fca267f0SVictor Shih }
1090fca267f0SVictor Shih EXPORT_SYMBOL_GPL(sdhci_uhs2_irq);
1091fca267f0SVictor Shih 
1092fca267f0SVictor Shih static irqreturn_t sdhci_uhs2_thread_irq(int irq, void *dev_id)
1093fca267f0SVictor Shih {
1094fca267f0SVictor Shih 	struct sdhci_host *host = dev_id;
1095fca267f0SVictor Shih 	struct mmc_command *cmd;
1096fca267f0SVictor Shih 	unsigned long flags;
1097fca267f0SVictor Shih 	u32 isr;
1098fca267f0SVictor Shih 
1099fca267f0SVictor Shih 	if (!mmc_card_uhs2(host->mmc))
1100fca267f0SVictor Shih 		return sdhci_thread_irq(irq, dev_id);
1101fca267f0SVictor Shih 
1102fca267f0SVictor Shih 	while (!sdhci_uhs2_request_done(host))
1103fca267f0SVictor Shih 		;
1104fca267f0SVictor Shih 
1105fca267f0SVictor Shih 	spin_lock_irqsave(&host->lock, flags);
1106fca267f0SVictor Shih 
1107fca267f0SVictor Shih 	isr = host->thread_isr;
1108fca267f0SVictor Shih 	host->thread_isr = 0;
1109fca267f0SVictor Shih 
1110fca267f0SVictor Shih 	cmd = host->deferred_cmd;
11119cbb2358SVictor Shih 	if (cmd && !sdhci_uhs2_send_command_retry(host, cmd, flags))
11129cbb2358SVictor Shih 		sdhci_finish_mrq(host, cmd->mrq);
1113fca267f0SVictor Shih 
1114fca267f0SVictor Shih 	spin_unlock_irqrestore(&host->lock, flags);
1115fca267f0SVictor Shih 
1116fca267f0SVictor Shih 	if (isr & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
1117fca267f0SVictor Shih 		struct mmc_host *mmc = host->mmc;
1118fca267f0SVictor Shih 
1119fca267f0SVictor Shih 		mmc->ops->card_event(mmc);
1120fca267f0SVictor Shih 		mmc_detect_change(mmc, msecs_to_jiffies(200));
1121fca267f0SVictor Shih 	}
1122fca267f0SVictor Shih 
1123fca267f0SVictor Shih 	return IRQ_HANDLED;
1124fca267f0SVictor Shih }
1125fca267f0SVictor Shih 
1126fca267f0SVictor Shih /*****************************************************************************\
1127fca267f0SVictor Shih  *                                                                           *
11282af7dd8bSVictor Shih  * Driver init/exit                                                          *
11292af7dd8bSVictor Shih  *                                                                           *
11302af7dd8bSVictor Shih \*****************************************************************************/
11312af7dd8bSVictor Shih 
113210c8298aSVictor Shih static int sdhci_uhs2_host_ops_init(struct sdhci_host *host)
113310c8298aSVictor Shih {
113410c8298aSVictor Shih 	host->mmc_host_ops.uhs2_control = sdhci_uhs2_control;
11359cbb2358SVictor Shih 	host->mmc_host_ops.request = sdhci_uhs2_request;
113610c8298aSVictor Shih 
113710c8298aSVictor Shih 	return 0;
113810c8298aSVictor Shih }
113910c8298aSVictor Shih 
11402af7dd8bSVictor Shih static int __init sdhci_uhs2_mod_init(void)
11412af7dd8bSVictor Shih {
11422af7dd8bSVictor Shih 	return 0;
11432af7dd8bSVictor Shih }
11442af7dd8bSVictor Shih module_init(sdhci_uhs2_mod_init);
11452af7dd8bSVictor Shih 
11462af7dd8bSVictor Shih static void __exit sdhci_uhs2_mod_exit(void)
11472af7dd8bSVictor Shih {
11482af7dd8bSVictor Shih }
11492af7dd8bSVictor Shih module_exit(sdhci_uhs2_mod_exit);
11502af7dd8bSVictor Shih 
115106a0d072SVictor Shih /*****************************************************************************\
115206a0d072SVictor Shih  *
115306a0d072SVictor Shih  * Device allocation/registration                                            *
115406a0d072SVictor Shih  *                                                                           *
115506a0d072SVictor Shih \*****************************************************************************/
115606a0d072SVictor Shih 
115706a0d072SVictor Shih static void __sdhci_uhs2_add_host_v4(struct sdhci_host *host, u32 caps1)
115806a0d072SVictor Shih {
115906a0d072SVictor Shih 	struct mmc_host *mmc;
116006a0d072SVictor Shih 	u32 max_current_caps2;
116106a0d072SVictor Shih 
116206a0d072SVictor Shih 	mmc = host->mmc;
116306a0d072SVictor Shih 
116406a0d072SVictor Shih 	/* Support UHS2 */
116506a0d072SVictor Shih 	if (caps1 & SDHCI_SUPPORT_UHS2)
116606a0d072SVictor Shih 		mmc->caps2 |= MMC_CAP2_SD_UHS2;
116706a0d072SVictor Shih 
116806a0d072SVictor Shih 	max_current_caps2 = sdhci_readl(host, SDHCI_MAX_CURRENT_1);
116906a0d072SVictor Shih 
117006a0d072SVictor Shih 	if ((caps1 & SDHCI_CAN_VDD2_180) &&
117106a0d072SVictor Shih 	    !max_current_caps2 &&
117206a0d072SVictor Shih 	    !IS_ERR(mmc->supply.vqmmc2)) {
117306a0d072SVictor Shih 		/* UHS2 - VDD2 */
117406a0d072SVictor Shih 		int curr = regulator_get_current_limit(mmc->supply.vqmmc2);
117506a0d072SVictor Shih 
117606a0d072SVictor Shih 		if (curr > 0) {
117706a0d072SVictor Shih 			/* convert to SDHCI_MAX_CURRENT format */
117806a0d072SVictor Shih 			curr = curr / 1000;  /* convert to mA */
117906a0d072SVictor Shih 			curr = curr / SDHCI_MAX_CURRENT_MULTIPLIER;
118006a0d072SVictor Shih 			curr = min_t(u32, curr, SDHCI_MAX_CURRENT_LIMIT);
118106a0d072SVictor Shih 			max_current_caps2 = curr;
118206a0d072SVictor Shih 		}
118306a0d072SVictor Shih 	}
118406a0d072SVictor Shih 
118506a0d072SVictor Shih 	if (!(caps1 & SDHCI_CAN_VDD2_180))
118606a0d072SVictor Shih 		mmc->caps2 &= ~MMC_CAP2_SD_UHS2;
118706a0d072SVictor Shih }
118806a0d072SVictor Shih 
118906a0d072SVictor Shih static void __sdhci_uhs2_remove_host(struct sdhci_host *host, int dead)
119006a0d072SVictor Shih {
119106a0d072SVictor Shih 	if (!mmc_card_uhs2(host->mmc))
119206a0d072SVictor Shih 		return;
119306a0d072SVictor Shih 
119406a0d072SVictor Shih 	if (!dead)
119506a0d072SVictor Shih 		sdhci_uhs2_reset(host, SDHCI_UHS2_SW_RESET_FULL);
119606a0d072SVictor Shih }
119706a0d072SVictor Shih 
119806a0d072SVictor Shih int sdhci_uhs2_add_host(struct sdhci_host *host)
119906a0d072SVictor Shih {
120006a0d072SVictor Shih 	struct mmc_host *mmc = host->mmc;
120106a0d072SVictor Shih 	int ret;
120206a0d072SVictor Shih 
120306a0d072SVictor Shih 	ret = sdhci_setup_host(host);
120406a0d072SVictor Shih 	if (ret)
120506a0d072SVictor Shih 		return ret;
120606a0d072SVictor Shih 
120706a0d072SVictor Shih 	if (host->version >= SDHCI_SPEC_400)
120806a0d072SVictor Shih 		__sdhci_uhs2_add_host_v4(host, host->caps1);
120906a0d072SVictor Shih 
121006a0d072SVictor Shih 	if ((mmc->caps2 & MMC_CAP2_SD_UHS2) && !host->v4_mode)
121106a0d072SVictor Shih 		/* host doesn't want to enable UHS2 support */
121206a0d072SVictor Shih 		mmc->caps2 &= ~MMC_CAP2_SD_UHS2;
121306a0d072SVictor Shih 
121410c8298aSVictor Shih 	/* overwrite ops */
121510c8298aSVictor Shih 	if (mmc->caps2 & MMC_CAP2_SD_UHS2)
121610c8298aSVictor Shih 		sdhci_uhs2_host_ops_init(host);
121710c8298aSVictor Shih 
1218fca267f0SVictor Shih 	host->complete_work_fn = sdhci_uhs2_complete_work;
1219fca267f0SVictor Shih 	host->thread_irq_fn    = sdhci_uhs2_thread_irq;
1220fca267f0SVictor Shih 
122106a0d072SVictor Shih 	/* LED support not implemented for UHS2 */
122206a0d072SVictor Shih 	host->quirks |= SDHCI_QUIRK_NO_LED;
122306a0d072SVictor Shih 
122406a0d072SVictor Shih 	ret = __sdhci_add_host(host);
122506a0d072SVictor Shih 	if (ret)
122606a0d072SVictor Shih 		goto cleanup;
122706a0d072SVictor Shih 
122806a0d072SVictor Shih 	return 0;
122906a0d072SVictor Shih 
123006a0d072SVictor Shih cleanup:
123106a0d072SVictor Shih 	if (host->version >= SDHCI_SPEC_400)
123206a0d072SVictor Shih 		__sdhci_uhs2_remove_host(host, 0);
123306a0d072SVictor Shih 
123406a0d072SVictor Shih 	sdhci_cleanup_host(host);
123506a0d072SVictor Shih 
123606a0d072SVictor Shih 	return ret;
123706a0d072SVictor Shih }
123806a0d072SVictor Shih EXPORT_SYMBOL_GPL(sdhci_uhs2_add_host);
123906a0d072SVictor Shih 
124006a0d072SVictor Shih void sdhci_uhs2_remove_host(struct sdhci_host *host, int dead)
124106a0d072SVictor Shih {
124206a0d072SVictor Shih 	__sdhci_uhs2_remove_host(host, dead);
124306a0d072SVictor Shih 
124406a0d072SVictor Shih 	sdhci_remove_host(host, dead);
124506a0d072SVictor Shih }
124606a0d072SVictor Shih EXPORT_SYMBOL_GPL(sdhci_uhs2_remove_host);
124706a0d072SVictor Shih 
12482af7dd8bSVictor Shih MODULE_AUTHOR("Intel, Genesys Logic, Linaro");
12492af7dd8bSVictor Shih MODULE_DESCRIPTION("MMC UHS-II Support");
12502af7dd8bSVictor Shih MODULE_LICENSE("GPL");
1251