From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 13 May 2024 10:30:14 +0000
Subject: [PATCH] modify sin led gpio

---
 kernel/drivers/mmc/host/dw_mmc.c |  315 +++++++++++++++++++++++++++++++--------------------
 1 files changed, 190 insertions(+), 125 deletions(-)

diff --git a/kernel/drivers/mmc/host/dw_mmc.c b/kernel/drivers/mmc/host/dw_mmc.c
index 51dee0a..5997010 100644
--- a/kernel/drivers/mmc/host/dw_mmc.c
+++ b/kernel/drivers/mmc/host/dw_mmc.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Synopsys DesignWare Multimedia Card Interface driver
  *  (Based on NXP driver for lpc 31xx)
  *
  * Copyright (C) 2009 NXP Semiconductors
  * Copyright (C) 2009, 2010 Imagination Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/blkdev.h>
@@ -40,6 +36,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/mmc/slot-gpio.h>
+#include <linux/soc/rockchip/rk_sdmmc.h>
 #include <linux/soc/rockchip/rockchip_decompress.h>
 
 #include "dw_mmc.h"
@@ -109,6 +106,26 @@
 /* Each descriptor can transfer up to 4KB of data in chained mode */
 #define DW_MCI_DESC_DATA_LENGTH	0x1000
 
+#if IS_ENABLED(CONFIG_CPU_RV1106)
+static spinlock_t *g_sdmmc_ispvicap_lock;
+
+void rv1106_sdmmc_get_lock(void)
+{
+	if (g_sdmmc_ispvicap_lock)
+		spin_lock(g_sdmmc_ispvicap_lock);
+}
+EXPORT_SYMBOL(rv1106_sdmmc_get_lock);
+
+void rv1106_sdmmc_put_lock(void)
+{
+	if (g_sdmmc_ispvicap_lock)
+		spin_unlock(g_sdmmc_ispvicap_lock);
+}
+EXPORT_SYMBOL(rv1106_sdmmc_put_lock);
+#endif
+
+#define RV1106_RAMDON_DATA_SIZE 508
+
 #if defined(CONFIG_DEBUG_FS)
 static int dw_mci_req_show(struct seq_file *s, void *v)
 {
@@ -175,40 +192,18 @@
 	struct mmc_host	*mmc = slot->mmc;
 	struct dw_mci *host = slot->host;
 	struct dentry *root;
-	struct dentry *node;
 
 	root = mmc->debugfs_root;
 	if (!root)
 		return;
 
-	node = debugfs_create_file("regs", S_IRUSR, root, host,
-				   &dw_mci_regs_fops);
-	if (!node)
-		goto err;
-
-	node = debugfs_create_file("req", S_IRUSR, root, slot,
-				   &dw_mci_req_fops);
-	if (!node)
-		goto err;
-
-	node = debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state);
-	if (!node)
-		goto err;
-
-	node = debugfs_create_x32("pending_events", S_IRUSR, root,
-				  (u32 *)&host->pending_events);
-	if (!node)
-		goto err;
-
-	node = debugfs_create_x32("completed_events", S_IRUSR, root,
-				  (u32 *)&host->completed_events);
-	if (!node)
-		goto err;
-
-	return;
-
-err:
-	dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n");
+	debugfs_create_file("regs", S_IRUSR, root, host, &dw_mci_regs_fops);
+	debugfs_create_file("req", S_IRUSR, root, slot, &dw_mci_req_fops);
+	debugfs_create_u32("state", S_IRUSR, root, &host->state);
+	debugfs_create_xul("pending_events", S_IRUSR, root,
+			   &host->pending_events);
+	debugfs_create_xul("completed_events", S_IRUSR, root,
+			   &host->completed_events);
 }
 #endif /* defined(CONFIG_DEBUG_FS) */
 
@@ -246,8 +241,9 @@
 	 * ...also allow sending for SDMMC_CMD_VOLT_SWITCH where busy is
 	 * expected.
 	 */
-#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
-	if (host->slot->mmc->restrict_caps & RESTRICT_CARD_TYPE_EMMC)
+#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_MMC
+	if (host->slot->mmc->caps2 & MMC_CAP2_NO_SD &&
+	    host->slot->mmc->caps2 & MMC_CAP2_NO_SDIO)
 		delay = 0;
 #endif
 	if ((cmd_flags & SDMMC_CMD_PRV_DAT_WAIT) &&
@@ -488,14 +484,20 @@
 
 	/* Disable and reset the IDMAC interface */
 	temp = mci_readl(host, CTRL);
-	temp &= ~SDMMC_CTRL_USE_IDMAC;
+	if (!host->is_rv1106_sd)
+		temp &= ~SDMMC_CTRL_USE_IDMAC;
+
 	temp |= SDMMC_CTRL_DMA_RESET;
 	mci_writel(host, CTRL, temp);
 
 	/* Stop the IDMAC running */
 	temp = mci_readl(host, BMOD);
-	temp &= ~(SDMMC_IDMAC_ENABLE | SDMMC_IDMAC_FB);
-	temp |= SDMMC_IDMAC_SWRESET;
+	if (host->is_rv1106_sd) {
+		temp |= SDMMC_IDMAC_SWRESET;
+	} else {
+		temp &= ~(SDMMC_IDMAC_ENABLE | SDMMC_IDMAC_FB);
+		temp |= SDMMC_IDMAC_SWRESET;
+	}
 	mci_writel(host, BMOD, temp);
 }
 
@@ -525,8 +527,7 @@
 		tasklet_schedule(&host->tasklet);
 	}
 
-	if (host->need_xfer_timer &&
-	    host->dir_status == DW_MCI_RECV_STATUS)
+	if (host->need_xfer_timer)
 		del_timer(&host->xfer_timer);
 }
 
@@ -736,6 +737,13 @@
 		}
 	}
 
+	if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE)) {
+		desc->des0 = desc_last->des0;
+		desc->des2 = desc_last->des2;
+		desc->des1 = RV1106_RAMDON_DATA_SIZE; /* Random dirty data for last one desc */
+		desc_last = desc;
+	}
+
 	/* Set first descriptor */
 	desc_first->des0 |= cpu_to_le32(IDMAC_DES0_FD);
 
@@ -871,12 +879,14 @@
 	if (!host->dms)
 		return -ENOMEM;
 
-	host->dms->ch = dma_request_slave_channel(host->dev, "rx-tx");
-	if (!host->dms->ch) {
+	host->dms->ch = dma_request_chan(host->dev, "rx-tx");
+	if (IS_ERR(host->dms->ch)) {
+		int ret = PTR_ERR(host->dms->ch);
+
 		dev_err(host->dev, "Failed to get external DMA channel.\n");
 		kfree(host->dms);
 		host->dms = NULL;
-		return -ENXIO;
+		return ret;
 	}
 
 	return 0;
@@ -918,7 +928,7 @@
 	 * non-word-aligned buffers or lengths. Also, we don't bother
 	 * with all the DMA setup overhead for short transfers.
 	 */
-	if (data->blocks * data->blksz < DW_MCI_DMA_THRESHOLD)
+	if (data->blocks * data->blksz < DW_MCI_DMA_THRESHOLD && !host->is_rv1106_sd)
 		return -EINVAL;
 
 	if (data->blksz & 3)
@@ -976,39 +986,12 @@
 	data->host_cookie = COOKIE_UNMAPPED;
 }
 
-static int dw_mci_set_sdio_status(struct mmc_host *mmc, int val)
-{
-	struct dw_mci_slot *slot = mmc_priv(mmc);
-	struct dw_mci *host = slot->host;
-
-	if (!(mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO))
-		return 0;
-
-	spin_lock_bh(&host->lock);
-
-	if (val)
-		set_bit(DW_MMC_CARD_PRESENT, &slot->flags);
-	else
-		clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
-
-	spin_unlock_bh(&host->lock);
-
-	mmc_detect_change(slot->mmc, 20);
-
-	return 0;
-}
-
 static int dw_mci_get_cd(struct mmc_host *mmc)
 {
 	int present;
 	struct dw_mci_slot *slot = mmc_priv(mmc);
 	struct dw_mci *host = slot->host;
 	int gpio_cd = mmc_gpio_get_cd(mmc);
-
-#ifdef CONFIG_SDIO_KEEPALIVE
-	if (mmc->logic_remove_card)
-		return test_bit(DW_MMC_CARD_PRESENT, &slot->flags);
-#endif
 
 	/* Use platform get_cd function, else try onboard card detect */
 	if (((mmc->caps & MMC_CAP_NEEDS_POLL)
@@ -1358,10 +1341,16 @@
 	host->data_status = 0;
 	host->dir_status = 0;
 
+	if (host->is_rv1106_sd)
+		mci_writel(host, CTYPE, (slot->ctype << slot->id));
+
 	data = cmd->data;
 	if (data) {
 		mci_writel(host, TMOUT, 0xFFFFFFFF);
-		mci_writel(host, BYTCNT, data->blksz*data->blocks);
+		if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE))
+			mci_writel(host, BYTCNT, 0);
+		else
+			mci_writel(host, BYTCNT, data->blksz*data->blocks);
 		mci_writel(host, BLKSIZ, data->blksz);
 	}
 
@@ -1439,6 +1428,7 @@
 	}
 }
 
+static bool dw_mci_reset(struct dw_mci *host);
 static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct dw_mci_slot *slot = mmc_priv(mmc);
@@ -1460,6 +1450,9 @@
 
 	spin_lock_bh(&host->lock);
 
+	if (host->is_rv1106_sd)
+		dw_mci_reset(host);
+
 	dw_mci_queue_request(host, slot, mrq);
 
 	spin_unlock_bh(&host->lock);
@@ -1469,7 +1462,7 @@
 {
 	struct dw_mci_slot *slot = mmc_priv(mmc);
 	const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
-	u32 regs;
+	u32 regs, power_off_delay;
 	int ret;
 
 	switch (ios->bus_width) {
@@ -1508,6 +1501,15 @@
 
 	switch (ios->power_mode) {
 	case MMC_POWER_UP:
+		if (dw_mci_get_cd(mmc) && !IS_ERR_OR_NULL(slot->host->pinctrl)) {
+			if (!pinctrl_select_state(slot->host->pinctrl, slot->host->idle_state)) {
+				if (device_property_read_u32(slot->host->dev, "power-off-delay-ms",
+				    &power_off_delay))
+					power_off_delay = 200;
+				msleep(power_off_delay);
+			}
+		}
+
 		if (!IS_ERR(mmc->supply.vmmc)) {
 			ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
 					ios->vdd);
@@ -1524,6 +1526,9 @@
 		mci_writel(slot->host, PWREN, regs);
 		break;
 	case MMC_POWER_ON:
+		if (!IS_ERR_OR_NULL(slot->host->pinctrl))
+			pinctrl_select_state(slot->host->pinctrl, slot->host->normal_state);
+
 		if (!slot->host->vqmmc_enabled) {
 			if (!IS_ERR(mmc->supply.vqmmc)) {
 				ret = regulator_enable(mmc->supply.vqmmc);
@@ -1538,9 +1543,11 @@
 				slot->host->vqmmc_enabled = true;
 			}
 
+#ifndef CONFIG_ROCKCHIP_THUNDER_BOOT_MMC
 			/* Reset our state machine after powering on */
 			dw_mci_ctrl_reset(slot->host,
 					  SDMMC_CTRL_ALL_RESET_FLAGS);
+#endif
 		}
 
 		/* Adjust clock / bus width after power is up */
@@ -1548,17 +1555,17 @@
 
 		break;
 	case MMC_POWER_OFF:
+		if (!IS_ERR_OR_NULL(slot->host->pinctrl))
+			pinctrl_select_state(slot->host->pinctrl, slot->host->idle_state);
+
 		/* Turn clock off before power goes down */
 		dw_mci_setup_bus(slot, false);
 
 		if (!IS_ERR(mmc->supply.vmmc))
 			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
 
-		if (!IS_ERR(mmc->supply.vqmmc) && slot->host->vqmmc_enabled) {
-			ios->signal_voltage = MMC_SIGNAL_VOLTAGE_330;
-			mmc_regulator_set_vqmmc(mmc, ios);
+		if (!IS_ERR(mmc->supply.vqmmc) && slot->host->vqmmc_enabled)
 			regulator_disable(mmc->supply.vqmmc);
-		}
 		slot->host->vqmmc_enabled = false;
 
 		regs = mci_readl(slot->host, PWREN);
@@ -1612,8 +1619,7 @@
 
 	if (!IS_ERR(mmc->supply.vqmmc)) {
 		ret = mmc_regulator_set_vqmmc(mmc, ios);
-
-		if (ret) {
+		if (ret < 0) {
 			dev_dbg(&mmc->class_dev,
 					 "Regulator set error %d - %s V\n",
 					 ret, uhs & v18 ? "1.8" : "3.3");
@@ -1843,7 +1849,6 @@
 	.pre_req		= dw_mci_pre_req,
 	.post_req		= dw_mci_post_req,
 	.set_ios		= dw_mci_set_ios,
-	.set_sdio_status	= dw_mci_set_sdio_status,
 	.get_ro			= dw_mci_get_ro,
 	.get_cd			= dw_mci_get_cd,
 	.hw_reset               = dw_mci_hw_reset,
@@ -1865,6 +1870,9 @@
 
 	WARN_ON(host->cmd || host->data);
 
+	if (host->need_xfer_timer)
+		del_timer(&host->xfer_timer);
+
 	host->slot->mrq = NULL;
 	host->mrq = NULL;
 	if (!list_empty(&host->queue)) {
@@ -1885,6 +1893,7 @@
 	}
 
 	spin_unlock(&host->lock);
+
 	mmc_request_done(prev_mmc, mrq);
 	spin_lock(&host->lock);
 }
@@ -1926,6 +1935,9 @@
 {
 	u32 status = host->data_status;
 
+	if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE) && (status & SDMMC_INT_DATA_OVER))
+		goto finish;
+
 	if (status & DW_MCI_DATA_ERROR_FLAGS) {
 		if (status & SDMMC_INT_DRTO) {
 			data->error = -ETIMEDOUT;
@@ -1958,6 +1970,7 @@
 		 */
 		dw_mci_reset(host);
 	} else {
+finish:
 		data->bytes_xfered = data->blocks * data->blksz;
 		data->error = 0;
 	}
@@ -2005,8 +2018,10 @@
 				   host->bus_hz);
 
 	/* add a bit spare time */
-	xfer_ms += 100;
-
+	if (host->dir_status == DW_MCI_RECV_STATUS)
+		xfer_ms += 100;
+	else
+		xfer_ms += 2500;
 	spin_lock_irqsave(&host->irq_lock, irqflags);
 	if (!test_bit(EVENT_XFER_COMPLETE, &host->pending_events))
 		mod_timer(&host->xfer_timer,
@@ -2123,7 +2138,7 @@
 			}
 
 			prev_state = state = STATE_SENDING_DATA;
-			/* fall through */
+			fallthrough;
 
 		case STATE_SENDING_DATA:
 			/*
@@ -2141,6 +2156,13 @@
 					send_stop_abort(host, data);
 				dw_mci_stop_dma(host);
 				state = STATE_DATA_ERROR;
+				if (host->dir_status == DW_MCI_SEND_STATUS) {
+					data->bytes_xfered = 0;
+					data->error = -ETIMEDOUT;
+					host->data = NULL;
+					dw_mci_request_end(host, mrq);
+					goto unlock;
+				}
 				break;
 			}
 
@@ -2152,8 +2174,7 @@
 				 */
 				if (host->dir_status == DW_MCI_RECV_STATUS)
 					dw_mci_set_drto(host);
-				if (host->need_xfer_timer &&
-				    host->dir_status == DW_MCI_RECV_STATUS)
+				if (host->need_xfer_timer)
 					dw_mci_set_xfer_timeout(host);
 				break;
 			}
@@ -2184,7 +2205,7 @@
 			}
 			prev_state = state = STATE_DATA_BUSY;
 
-			/* fall through */
+			fallthrough;
 
 		case STATE_DATA_BUSY:
 			if (!dw_mci_clear_pending_data_complete(host)) {
@@ -2195,6 +2216,8 @@
 				 */
 				if (host->dir_status == DW_MCI_RECV_STATUS)
 					dw_mci_set_drto(host);
+				if (host->need_xfer_timer && host->dir_status == DW_MCI_SEND_STATUS)
+					dw_mci_set_xfer_timeout(host);
 				break;
 			}
 
@@ -2211,8 +2234,19 @@
 				}
 
 				/* stop command for open-ended transfer*/
-				if (data->stop)
+				if (data->stop) {
+					if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE)) {
+						int fifo_count;
+
+						if (readl_poll_timeout_atomic(host->regs + SDMMC_STATUS, fifo_count,
+								((fifo_count >> 17) & 0x7FF) <= RV1106_RAMDON_DATA_SIZE / 4,
+								0, 5000 * USEC_PER_MSEC))
+							data->error = -ETIMEDOUT;
+						udelay(1);
+						dw_mci_reset(host);
+					}
 					send_stop_abort(host, data);
+				}
 			} else {
 				/*
 				 * If we don't have a command complete now we'll
@@ -2237,7 +2271,7 @@
 			 */
 			prev_state = state = STATE_SENDING_STOP;
 
-			/* fall through */
+			fallthrough;
 
 		case STATE_SENDING_STOP:
 			if (!dw_mci_clear_pending_cmd_complete(host))
@@ -2743,8 +2777,7 @@
 			del_timer(&host->cto_timer);
 			mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS);
 			host->cmd_status = pending;
-			if ((host->need_xfer_timer) &&
-			     host->dir_status == DW_MCI_RECV_STATUS)
+			if (host->need_xfer_timer)
 				del_timer(&host->xfer_timer);
 			smp_wmb(); /* drain writebuffer */
 			set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
@@ -2762,11 +2795,14 @@
 		}
 
 		if (pending & SDMMC_INT_DATA_OVER) {
+rv1106_sd:
 			spin_lock_irqsave(&host->irq_lock, irqflags);
 
 			del_timer(&host->dto_timer);
 
 			mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER);
+			if (host->is_rv1106_sd)
+				pending |= SDMMC_INT_DATA_OVER;
 			if (!host->data_status)
 				host->data_status = pending;
 			smp_wmb(); /* drain writebuffer */
@@ -2836,6 +2872,9 @@
 			mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
 			if (!test_bit(EVENT_DATA_ERROR, &host->pending_events))
 				host->dma_ops->complete((void *)host);
+
+			if (host->is_rv1106_sd && (pending & SDMMC_IDMAC_INT_TI))
+				goto rv1106_sd;
 		}
 	}
 
@@ -2851,12 +2890,6 @@
 
 	if (host->pdata->caps)
 		mmc->caps = host->pdata->caps;
-
-	/*
-	 * Support MMC_CAP_ERASE by default.
-	 * It needs to use trim/discard/erase commands.
-	 */
-	mmc->caps |= MMC_CAP_ERASE;
 
 	if (host->pdata->pm_caps)
 		mmc->pm_caps = host->pdata->pm_caps;
@@ -2875,15 +2908,7 @@
 				ctrl_id);
 			return -EINVAL;
 		}
-		/*
-		 * Some sd cards violate the spec. They claim to support
-		 * CMD23 but actually not. We don't have a good method to
-		 * work around them except for adding MMC_QUIRK_BLK_NO_CMD23
-		 * one by one. But it's not a acceptable way for our custmors.
-		 * So removing CMD23 support for all sd cards to solve it.
-		 */
-		if (!(mmc->restrict_caps & RESTRICT_CARD_TYPE_SD))
-			mmc->caps |= drv_data->caps[ctrl_id];
+		mmc->caps |= drv_data->caps[ctrl_id];
 	}
 
 	if (host->pdata->caps2)
@@ -2937,6 +2962,10 @@
 
 	/* Useful defaults if platform data is unset. */
 	if (host->use_dma == TRANS_MODE_IDMAC) {
+		/* Reserve last desc for dirty data */
+		if (host->is_rv1106_sd)
+			host->ring_size--;
+
 		mmc->max_segs = host->ring_size;
 		mmc->max_blk_size = 65535;
 		mmc->max_seg_size = 0x1000;
@@ -2960,11 +2989,6 @@
 	}
 
 	dw_mci_get_cd(mmc);
-
-#ifdef CONFIG_SDIO_KEEPALIVE
-	if (mmc->logic_remove_card)
-		clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
-#endif
 
 	ret = mmc_add_host(mmc);
 	if (ret)
@@ -3272,6 +3296,22 @@
 			return ERR_PTR(ret);
 	}
 
+	host->pinctrl = devm_pinctrl_get(host->dev);
+	if (!IS_ERR(host->pinctrl)) {
+		host->normal_state = pinctrl_lookup_state(host->pinctrl, "normal");
+		if (IS_ERR(host->normal_state))
+			dev_warn(dev, "No normal pinctrl state\n");
+
+		host->idle_state = pinctrl_lookup_state(host->pinctrl, "idle");
+		if (IS_ERR(host->idle_state))
+			dev_warn(dev, "No idle pinctrl state\n");
+
+		if (!IS_ERR(host->normal_state) && !IS_ERR(host->idle_state))
+			pinctrl_select_state(host->pinctrl, host->idle_state);
+		else
+			host->pinctrl = NULL;
+	}
+
 	return pdata;
 }
 
@@ -3311,12 +3351,9 @@
 
 	if (!host->pdata) {
 		host->pdata = dw_mci_parse_dt(host);
-		if (PTR_ERR(host->pdata) == -EPROBE_DEFER) {
-			return -EPROBE_DEFER;
-		} else if (IS_ERR(host->pdata)) {
-			dev_err(host->dev, "platform data not available\n");
-			return -EINVAL;
-		}
+		if (IS_ERR(host->pdata))
+			return dev_err_probe(host->dev, PTR_ERR(host->pdata),
+					     "platform data not available\n");
 	}
 
 	host->biu_clk = devm_clk_get(host->dev, "biu");
@@ -3329,8 +3366,10 @@
 			return ret;
 		}
 	}
-#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
-	if (device_property_read_bool(host->dev, "supports-emmc")) {
+
+#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_MMC
+	if (device_property_read_bool(host->dev, "no-sd") &&
+	    device_property_read_bool(host->dev, "no-sdio")) {
 		if (readl_poll_timeout(host->regs + SDMMC_STATUS,
 				fifo_size,
 				!(fifo_size & (BIT(10) | GENMASK(7, 4))),
@@ -3507,6 +3546,24 @@
 		goto err_dmaunmap;
 	}
 
+	if (host->is_rv1106_sd) {
+#if IS_ENABLED(CONFIG_CPU_RV1106)
+		g_sdmmc_ispvicap_lock = &host->lock;
+#endif
+		/* Select IDMAC interface */
+		fifo_size = mci_readl(host, CTRL);
+		fifo_size |= SDMMC_CTRL_USE_IDMAC;
+		mci_writel(host, CTRL, fifo_size);
+
+		fifo_size = mci_readl(host, INTMASK);
+		fifo_size &= ~SDMMC_INT_HTO;
+		mci_writel(host, INTMASK, fifo_size);
+
+		host->slot->mmc->caps &= ~(MMC_CAP_UHS_DDR50 | MMC_CAP_UHS_SDR104 |
+					   MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
+					   MMC_CAP_UHS_SDR12);
+	}
+
 	/* Now that slots are all setup, we can enable card detect */
 	dw_mci_enable_cd(host);
 
@@ -3604,20 +3661,28 @@
 	 * Restore the initial value at FIFOTH register
 	 * And Invalidate the prev_blksz with zero
 	 */
-	 mci_writel(host, FIFOTH, host->fifoth_val);
-	 host->prev_blksz = 0;
+	mci_writel(host, FIFOTH, host->fifoth_val);
+	host->prev_blksz = 0;
 
 	/* Put in max timeout */
 	mci_writel(host, TMOUT, 0xFFFFFFFF);
 
 	mci_writel(host, RINTSTS, 0xFFFFFFFF);
-	mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
-		   SDMMC_INT_TXDR | SDMMC_INT_RXDR |
-		   DW_MCI_ERROR_FLAGS);
+	mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | DW_MCI_ERROR_FLAGS);
 	mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE);
 
+	if (host->is_rv1106_sd) {
+		/* Select IDMAC interface */
+		ret = mci_readl(host, CTRL);
+		ret |= SDMMC_CTRL_USE_IDMAC;
+		mci_writel(host, CTRL, ret);
 
-	if (host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER)
+		ret = mci_readl(host, INTMASK);
+		ret &= ~SDMMC_INT_HTO;
+		mci_writel(host, INTMASK, ret);
+	}
+
+	if (host->slot && host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER)
 		dw_mci_set_ios(host->slot->mmc, &host->slot->mmc->ios);
 
 	/* Force setup bus to guarantee available clock output */

--
Gitblit v1.6.2