All of lore.kernel.org
 help / color / mirror / Atom feed
From: Victor Shih <victorshihgli@gmail.com>
To: ulf.hansson@linaro.org, adrian.hunter@intel.com
Cc: linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org,
	benchuanggli@gmail.com, HL.Liu@genesyslogic.com.tw,
	Greg.tu@genesyslogic.com.tw, takahiro.akashi@linaro.org,
	dlunev@chromium.org,
	Victor Shih <victor.shih@genesyslogic.com.tw>,
	Ben Chuang <ben.chuang@genesyslogic.com.tw>
Subject: [PATCH V5 15/26] mmc: sdhci-uhs2: add set_ios()
Date: Wed, 19 Oct 2022 19:06:36 +0800	[thread overview]
Message-ID: <20221019110647.11076-16-victor.shih@genesyslogic.com.tw> (raw)
In-Reply-To: <20221019110647.11076-1-victor.shih@genesyslogic.com.tw>

This is a sdhci version of mmc's set_ios operation.
It covers both UHS-I and UHS-II.

Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw>
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw>
---
 drivers/mmc/host/sdhci-uhs2.c | 102 ++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci-uhs2.h |   1 +
 drivers/mmc/host/sdhci.c      |  40 ++++++++-----
 drivers/mmc/host/sdhci.h      |   2 +
 4 files changed, 130 insertions(+), 15 deletions(-)

diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c
index 2b90e5308764..b535a47dc55a 100644
--- a/drivers/mmc/host/sdhci-uhs2.c
+++ b/drivers/mmc/host/sdhci-uhs2.c
@@ -281,6 +281,74 @@ void sdhci_uhs2_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
 }
 EXPORT_SYMBOL_GPL(sdhci_uhs2_set_timeout);
 
+/**
+ * sdhci_uhs2_clear_set_irqs - set Error Interrupt Status Enable register
+ * @host:	SDHCI host
+ * @clear:	bit-wise clear mask
+ * @set:	bit-wise set mask
+ *
+ * Set/unset bits in UHS-II Error Interrupt Status Enable register
+ */
+void sdhci_uhs2_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
+{
+	u32 ier;
+
+	ier = sdhci_readl(host, SDHCI_UHS2_ERR_INT_STATUS_EN);
+	ier &= ~clear;
+	ier |= set;
+	sdhci_writel(host, ier, SDHCI_UHS2_ERR_INT_STATUS_EN);
+	sdhci_writel(host, ier, SDHCI_UHS2_ERR_INT_SIG_EN);
+}
+EXPORT_SYMBOL_GPL(sdhci_uhs2_clear_set_irqs);
+
+static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	u8 cmd_res, dead_lock;
+	u16 ctrl_2;
+	unsigned long flags;
+
+	/* FIXME: why lock? */
+	spin_lock_irqsave(&host->lock, flags);
+
+	/* UHS2 Timeout Control */
+	sdhci_calc_timeout_uhs2(host, &cmd_res, &dead_lock);
+
+	/* change to use calculate value */
+	cmd_res |= dead_lock << SDHCI_UHS2_TIMER_CTRL_DEADLOCK_SHIFT;
+
+	sdhci_uhs2_clear_set_irqs(host,
+				  SDHCI_UHS2_ERR_INT_STATUS_RES_TIMEOUT |
+				  SDHCI_UHS2_ERR_INT_STATUS_DEADLOCK_TIMEOUT,
+				  0);
+	sdhci_writeb(host, cmd_res, SDHCI_UHS2_TIMER_CTRL);
+	sdhci_uhs2_clear_set_irqs(host, 0,
+				  SDHCI_UHS2_ERR_INT_STATUS_RES_TIMEOUT |
+				  SDHCI_UHS2_ERR_INT_STATUS_DEADLOCK_TIMEOUT);
+
+	/* UHS2 timing */
+	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+	if (ios->timing == MMC_TIMING_SD_UHS2)
+		ctrl_2 |= SDHCI_CTRL_UHS_2 | SDHCI_CTRL_UHS2_INTERFACE_EN;
+	else
+		ctrl_2 &= ~(SDHCI_CTRL_UHS_2 | SDHCI_CTRL_UHS2_INTERFACE_EN);
+	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+
+	if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
+		sdhci_enable_preset_value(host, true);
+
+	if (host->ops->set_power)
+		host->ops->set_power(host, ios->power_mode, ios->vdd);
+	else
+		sdhci_uhs2_set_power(host, ios->power_mode, ios->vdd);
+	udelay(100);
+
+	host->timing = ios->timing;
+	sdhci_set_clock(host, host->clock);
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
 /*****************************************************************************\
  *                                                                           *
  * MMC callbacks                                                             *
@@ -302,6 +370,39 @@ static int sdhci_uhs2_start_signal_voltage_switch(struct mmc_host *mmc,
 	return sdhci_start_signal_voltage_switch(mmc, ios);
 }
 
+int sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+
+	if (!(host->version >= SDHCI_SPEC_400) ||
+	    !(host->mmc->flags & MMC_UHS2_SUPPORT &&
+	      host->mmc->caps2 & MMC_CAP2_SD_UHS2)) {
+		sdhci_set_ios(mmc, ios);
+		return 0;
+	}
+
+	if (ios->power_mode == MMC_POWER_UNDEFINED)
+		return 1;
+
+	if (host->flags & SDHCI_DEVICE_DEAD) {
+		if (!IS_ERR(mmc->supply.vmmc) &&
+		    ios->power_mode == MMC_POWER_OFF)
+			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+		if (!IS_ERR_OR_NULL(mmc->supply.vmmc2) &&
+		    ios->power_mode == MMC_POWER_OFF)
+			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc2, 0);
+		return 1;
+	}
+
+	/* FIXME: host->timing = ios->timing */
+
+	sdhci_set_ios_common(mmc, ios);
+
+	__sdhci_uhs2_set_ios(mmc, ios);
+
+	return 0;
+}
+
 /*****************************************************************************\
  *                                                                           *
  * Driver init/exit                                                          *
@@ -312,6 +413,7 @@ static int sdhci_uhs2_host_ops_init(struct sdhci_host *host)
 {
 	host->mmc_host_ops.start_signal_voltage_switch =
 		sdhci_uhs2_start_signal_voltage_switch;
+	host->mmc_host_ops.uhs2_set_ios = sdhci_uhs2_set_ios;
 
 	return 0;
 }
diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h
index 5ea235b14108..23368448ccd4 100644
--- a/drivers/mmc/host/sdhci-uhs2.h
+++ b/drivers/mmc/host/sdhci-uhs2.h
@@ -216,5 +216,6 @@ void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask);
 void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode,
 			  unsigned short vdd);
 void sdhci_uhs2_set_timeout(struct sdhci_host *host, struct mmc_command *cmd);
+void sdhci_uhs2_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set);
 
 #endif /* __SDHCI_UHS2_H */
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index dfa0939a9058..de47c71995fb 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -47,8 +47,6 @@
 static unsigned int debug_quirks = 0;
 static unsigned int debug_quirks2;
 
-static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
-
 static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd);
 
 void sdhci_dumpregs(struct sdhci_host *host)
@@ -1888,6 +1886,9 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
 	case MMC_TIMING_MMC_HS400:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_HS400);
 		break;
+	case MMC_TIMING_SD_UHS2:
+		preset = sdhci_readw(host, SDHCI_PRESET_FOR_UHS2);
+		break;
 	default:
 		pr_warn("%s: Invalid UHS-I mode selected\n",
 			mmc_hostname(host->mmc));
@@ -2305,20 +2306,9 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 }
 EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
 
-void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+void sdhci_set_ios_common(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct sdhci_host *host = mmc_priv(mmc);
-	u8 ctrl;
-
-	if (ios->power_mode == MMC_POWER_UNDEFINED)
-		return;
-
-	if (host->flags & SDHCI_DEVICE_DEAD) {
-		if (!IS_ERR(mmc->supply.vmmc) &&
-		    ios->power_mode == MMC_POWER_OFF)
-			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
-		return;
-	}
 
 	/*
 	 * Reset the chip on each power off.
@@ -2355,6 +2345,25 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		host->ops->set_power(host, ios->power_mode, ios->vdd);
 	else
 		sdhci_set_power(host, ios->power_mode, ios->vdd);
+}
+EXPORT_SYMBOL_GPL(sdhci_set_ios_common);
+
+void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	u8 ctrl;
+
+	if (ios->power_mode == MMC_POWER_UNDEFINED)
+		return;
+
+	if (host->flags & SDHCI_DEVICE_DEAD) {
+		if (!IS_ERR(mmc->supply.vmmc) &&
+		    ios->power_mode == MMC_POWER_OFF)
+			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+		return;
+	}
+
+	sdhci_set_ios_common(mmc, ios);
 
 	if (host->ops->platform_send_init_74_clocks)
 		host->ops->platform_send_init_74_clocks(host, ios->power_mode);
@@ -2935,7 +2944,7 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 }
 EXPORT_SYMBOL_GPL(sdhci_execute_tuning);
 
-static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
+void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
 {
 	/* Host Controller v3.00 defines preset value registers */
 	if (host->version < SDHCI_SPEC_300)
@@ -2963,6 +2972,7 @@ static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
 		host->preset_enabled = enable;
 	}
 }
+EXPORT_SYMBOL_GPL(sdhci_enable_preset_value);
 
 static void sdhci_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
 				int err)
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index c34ca6ffbff6..22d7f47862ae 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -871,6 +871,8 @@ void sdhci_set_bus_width(struct sdhci_host *host, int width);
 void sdhci_reset(struct sdhci_host *host, u8 mask);
 void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
 int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
+void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
+void sdhci_set_ios_common(struct mmc_host *mmc, struct mmc_ios *ios);
 void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
 int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
 				      struct mmc_ios *ios);
-- 
2.25.1


  parent reply	other threads:[~2022-10-19 12:06 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-19 11:06 [PATCH V5 00/26] Add support UHS-II for GL9755 Victor Shih
2022-10-19 11:06 ` [PATCH V5 01/26] mmc: core: Cleanup printing of speed mode at card insertion Victor Shih
2022-10-19 11:06 ` [PATCH V5 02/26] mmc: core: Prepare to support SD UHS-II cards Victor Shih
2022-11-04 12:16   ` Christophe JAILLET
2022-11-04 15:09     ` Ulf Hansson
2022-10-19 11:06 ` [PATCH V5 03/26] mmc: core: Announce successful insertion of an SD UHS-II card Victor Shih
2022-10-19 11:06 ` [PATCH V5 04/26] mmc: core: Extend support for mmc regulators with a vqmmc2 Victor Shih
2022-10-19 11:06 ` [PATCH V5 05/26] mmc: core: Add definitions for SD UHS-II cards Victor Shih
2022-11-01 17:12   ` Adrian Hunter
2022-11-16 11:06     ` Victor Shih
2022-11-16 13:48       ` Adrian Hunter
2022-11-17  6:19         ` Ben Chuang
2022-11-17 16:03           ` Adrian Hunter
2022-11-18  1:19             ` Ben Chuang
2022-12-13  8:44               ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 06/26] mmc: core: Support UHS-II card control and access Victor Shih
2022-10-19 11:06 ` [PATCH V5 07/26] mmc: sdhci: add a kernel configuration for enabling UHS-II support Victor Shih
2022-11-01 17:12   ` Adrian Hunter
2022-12-13  8:45     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 08/26] mmc: sdhci: add UHS-II related definitions in headers Victor Shih
2022-11-01 17:12   ` Adrian Hunter
2022-12-13  8:45     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 09/26] mmc: sdhci: add UHS-II module Victor Shih
2022-11-01 17:12   ` Adrian Hunter
2022-12-13  8:45     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 10/26] mmc: sdhci-uhs2: dump UHS-II registers Victor Shih
2022-11-01 17:13   ` Adrian Hunter
2022-12-13  8:45     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 11/26] mmc: sdhci-uhs2: add reset function and uhs2_mode function Victor Shih
2022-11-01 17:13   ` Adrian Hunter
2022-12-13  8:45     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 12/26] mmc: sdhci-uhs2: add set_power() to support vdd2 Victor Shih
2022-11-01 17:13   ` Adrian Hunter
2022-12-13  8:46     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 13/26] mmc: sdhci-uhs2: skip signal_voltage_switch() Victor Shih
2022-10-19 11:06 ` [PATCH V5 14/26] mmc: sdhci-uhs2: add set_timeout() Victor Shih
2022-11-01 17:14   ` Adrian Hunter
2022-12-13  8:46     ` Victor Shih
2022-10-19 11:06 ` Victor Shih [this message]
2022-11-01 17:14   ` [PATCH V5 15/26] mmc: sdhci-uhs2: add set_ios() Adrian Hunter
2022-12-13  8:46     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 16/26] mmc: sdhci-uhs2: add detect_init() to detect the interface Victor Shih
2022-11-01 17:14   ` Adrian Hunter
2022-12-13  8:47     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 17/26] mmc: sdhci-uhs2: add clock operations Victor Shih
2022-11-01 17:14   ` Adrian Hunter
2022-12-13  8:47     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 18/26] mmc: sdhci-uhs2: add uhs2_control() to initialise the interface Victor Shih
2022-11-01 17:15   ` Adrian Hunter
2022-12-13  8:47     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 19/26] mmc: sdhci-uhs2: add request() and others Victor Shih
2022-11-01 17:15   ` Adrian Hunter
2022-12-13  8:47     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 20/26] mmc: sdhci-uhs2: add irq() " Victor Shih
2022-11-01 17:15   ` Adrian Hunter
2022-12-13  8:48     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 21/26] mmc: sdhci-uhs2: add add_host() and others to set up the driver Victor Shih
2022-11-01 17:15   ` Adrian Hunter
2022-12-13  8:48     ` Victor Shih
2022-10-19 11:06 ` [PATCH V5 22/26] mmc: sdhci-uhs2: add pre-detect_init hook Victor Shih
2022-10-19 11:06 ` [PATCH V5 23/26] mmc: core: add post-mmc_attach_sd hook Victor Shih
2022-10-19 11:06 ` [PATCH V5 24/26] mmc: sdhci-uhs2: " Victor Shih
2022-10-19 11:06 ` [PATCH V5 25/26] mmc: sdhci-pci: add UHS-II support framework Victor Shih
2022-10-19 11:06 ` [PATCH V5 26/26] mmc: sdhci-pci-gli: enable UHS-II mode for GL9755 Victor Shih
2022-10-19 11:29 ` [PATCH V5 00/26] Add support UHS-II " Ulf Hansson
2022-11-01  2:24   ` Victor Shih
2022-11-01 17:28 ` Adrian Hunter
2022-11-04 10:43   ` Victor Shih
  -- strict thread matches above, loose matches on Subject: below --
2022-10-17  9:11 Victor Shih
2022-10-17  9:11 ` [PATCH V5 15/26] mmc: sdhci-uhs2: add set_ios() Victor Shih
2022-10-14 11:45 [PATCH V5 00/26] Add support UHS-II for GL9755 Victor Shih
2022-10-14 11:45 ` [PATCH V5 15/26] mmc: sdhci-uhs2: add set_ios() Victor Shih

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221019110647.11076-16-victor.shih@genesyslogic.com.tw \
    --to=victorshihgli@gmail.com \
    --cc=Greg.tu@genesyslogic.com.tw \
    --cc=HL.Liu@genesyslogic.com.tw \
    --cc=adrian.hunter@intel.com \
    --cc=ben.chuang@genesyslogic.com.tw \
    --cc=benchuanggli@gmail.com \
    --cc=dlunev@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=takahiro.akashi@linaro.org \
    --cc=ulf.hansson@linaro.org \
    --cc=victor.shih@genesyslogic.com.tw \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.