public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Alper Nebi Yasak <alpernebiyasak@gmail.com>
To: u-boot@lists.denx.de
Cc: Jack Mitchell <ml@embed.me.uk>,
	Kever Yang <kever.yang@rock-chips.com>,
	Heinrich Schuchardt <xypron.glpk@gmx.de>,
	Yifeng Zhao <yifeng.zhao@rock-chips.com>,
	Samuel Dionne-Riel <samuel@dionne-riel.com>,
	Simon Glass <sjg@chromium.org>,
	Aswath Govindraju <a-govindraju@ti.com>,
	Philipp Tomsich <philipp.tomsich@vrull.eu>,
	Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>,
	Stephen Carlson <stcarlso@linux.microsoft.com>,
	Jaehoon Chung <jh80.chung@samsung.com>,
	Michal Simek <michal.simek@xilinx.com>,
	Faiz Abbas <faiz_abbas@ti.com>,
	Jagan Teki <jagan@amarulasolutions.com>,
	Peng Fan <peng.fan@nxp.com>,
	Peter Robinson <pbrobinson@gmail.com>,
	Alper Nebi Yasak <alpernebiyasak@gmail.com>
Subject: [PATCH v4 2/4] rockchip: sdhci: Fix RK3399 eMMC PHY power cycling
Date: Sat, 29 Jan 2022 01:42:37 +0300	[thread overview]
Message-ID: <20220128224240.4226-3-alpernebiyasak@gmail.com> (raw)
In-Reply-To: <20220128224240.4226-1-alpernebiyasak@gmail.com>

The Rockchip RK3399 eMMC PHY has to be power-cycled while changing its
clock speed to some higher speeds. This is dependent on the desired
SDHCI clock speed, and it looks like the PHY should be powered off while
setting the SDHCI clock in these cases.

Commit ac804143cfd1 ("mmc: rockchip_sdhci: add phy and clock config for
rk3399") attempts to do this in the set_ios_post() hook by setting the
SDHCI clock once more while the PHY is turned off/on as necessary, as
the SDHCI framework does not provide a way to override how it sets its
clock. However, the commit breaks reinitializing the eMMC on a few
boards including chromebook_kevin and reportedly ROCKPro64.

This patch reworks the power cycling to utilize the SDHCI framework
slightly better (using the set_control_reg() hook to power off the PHY
and set_ios_post() hook to power it back on) which happens to fix the
issue, at least on a chromebook_kevin.

Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
---
RK3568 parts only build-tested as I don't have a RK3568 board.

Changes in v4:
- Add comment for Rockchip SDHCI set_control_reg() driver data op
- Add comment for Rockchip SDHCI set_ios_post() driver data op

Changes in v2:
- Add this patch

 drivers/mmc/rockchip_sdhci.c | 76 +++++++++++++++++++++++++++++++-----
 1 file changed, 66 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index 278473899c7c..b91df05de4ff 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -90,9 +90,33 @@ struct rockchip_sdhc {
 };
 
 struct sdhci_data {
-	int (*emmc_set_clock)(struct sdhci_host *host, unsigned int clock);
 	int (*emmc_phy_init)(struct udevice *dev);
 	int (*get_phy)(struct udevice *dev);
+
+	/**
+	 * set_control_reg() - Set SDHCI control registers
+	 *
+	 * This is the set_control_reg() SDHCI operation that should be
+	 * used for the hardware this driver data is associated with.
+	 * Normally, this is used to set up control registers for
+	 * voltage level and UHS speed mode.
+	 *
+	 * @host: SDHCI host structure
+	 */
+	void (*set_control_reg)(struct sdhci_host *host);
+
+	/**
+	 * set_ios_post() - Host specific hook after set_ios() calls
+	 *
+	 * This is the set_ios_post() SDHCI operation that should be
+	 * used for the hardware this driver data is associated with.
+	 * Normally, this is a hook that is called after sdhci_set_ios()
+	 * that does any necessary host-specific configuration.
+	 *
+	 * @host: SDHCI host structure
+	 * Return: 0 if successful, -ve on error
+	 */
+	int (*set_ios_post)(struct sdhci_host *host);
 };
 
 static int rk3399_emmc_phy_init(struct udevice *dev)
@@ -182,15 +206,28 @@ static int rk3399_emmc_get_phy(struct udevice *dev)
 	return 0;
 }
 
-static int rk3399_sdhci_emmc_set_clock(struct sdhci_host *host, unsigned int clock)
+static void rk3399_sdhci_set_control_reg(struct sdhci_host *host)
 {
 	struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
+	struct mmc *mmc = host->mmc;
+	uint clock = mmc->tran_speed;
 	int cycle_phy = host->clock != clock && clock > EMMC_MIN_FREQ;
 
 	if (cycle_phy)
 		rk3399_emmc_phy_power_off(priv->phy);
 
-	sdhci_set_clock(host->mmc, clock);
+	sdhci_set_control_reg(host);
+};
+
+static int rk3399_sdhci_set_ios_post(struct sdhci_host *host)
+{
+	struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
+	struct mmc *mmc = host->mmc;
+	uint clock = mmc->tran_speed;
+	int cycle_phy = host->clock != clock && clock > EMMC_MIN_FREQ;
+
+	if (!clock)
+		clock = mmc->clock;
 
 	if (cycle_phy)
 		rk3399_emmc_phy_power_on(priv->phy, clock);
@@ -269,10 +306,8 @@ static int rk3568_emmc_get_phy(struct udevice *dev)
 	return 0;
 }
 
-static int rockchip_sdhci_set_ios_post(struct sdhci_host *host)
+static int rk3568_sdhci_set_ios_post(struct sdhci_host *host)
 {
-	struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
-	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
 	struct mmc *mmc = host->mmc;
 	uint clock = mmc->tran_speed;
 	u32 reg;
@@ -280,8 +315,7 @@ static int rockchip_sdhci_set_ios_post(struct sdhci_host *host)
 	if (!clock)
 		clock = mmc->clock;
 
-	if (data->emmc_set_clock)
-		data->emmc_set_clock(host, clock);
+	rk3568_sdhci_emmc_set_clock(host, clock);
 
 	if (mmc->selected_mode == MMC_HS_400 || mmc->selected_mode == MMC_HS_400_ES) {
 		reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
@@ -295,6 +329,26 @@ static int rockchip_sdhci_set_ios_post(struct sdhci_host *host)
 	return 0;
 }
 
+static void rockchip_sdhci_set_control_reg(struct sdhci_host *host)
+{
+	struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
+	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
+
+	if (data->set_control_reg)
+		data->set_control_reg(host);
+}
+
+static int rockchip_sdhci_set_ios_post(struct sdhci_host *host)
+{
+	struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
+	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
+
+	if (data->set_ios_post)
+		return data->set_ios_post(host);
+
+	return 0;
+}
+
 static int rockchip_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
 {
 	struct sdhci_host *host = dev_get_priv(mmc->dev);
@@ -358,6 +412,7 @@ static int rockchip_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
 static struct sdhci_ops rockchip_sdhci_ops = {
 	.set_ios_post	= rockchip_sdhci_set_ios_post,
 	.platform_execute_tuning = &rockchip_sdhci_execute_tuning,
+	.set_control_reg = rockchip_sdhci_set_control_reg,
 };
 
 static int rockchip_sdhci_probe(struct udevice *dev)
@@ -436,15 +491,16 @@ static int rockchip_sdhci_bind(struct udevice *dev)
 }
 
 static const struct sdhci_data rk3399_data = {
-	.emmc_set_clock = rk3399_sdhci_emmc_set_clock,
 	.get_phy = rk3399_emmc_get_phy,
 	.emmc_phy_init = rk3399_emmc_phy_init,
+	.set_control_reg = rk3399_sdhci_set_control_reg,
+	.set_ios_post = rk3399_sdhci_set_ios_post,
 };
 
 static const struct sdhci_data rk3568_data = {
-	.emmc_set_clock = rk3568_sdhci_emmc_set_clock,
 	.get_phy = rk3568_emmc_get_phy,
 	.emmc_phy_init = rk3568_emmc_phy_init,
+	.set_ios_post = rk3568_sdhci_set_ios_post,
 };
 
 static const struct udevice_id sdhci_ids[] = {
-- 
2.34.1


  parent reply	other threads:[~2022-01-28 22:43 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-28 22:42 [PATCH v4 0/4] rockchip: sdhci: Fix reinit and add HS400 Enhanced Strobe support Alper Nebi Yasak
2022-01-28 22:42 ` [PATCH v4 1/4] mmc: sdhci: Add " Alper Nebi Yasak
2022-01-28 22:42 ` Alper Nebi Yasak [this message]
2022-02-26 18:36   ` [PATCH v4 2/4] rockchip: sdhci: Fix RK3399 eMMC PHY power cycling Simon Glass
2022-03-14 18:14   ` Tom Rini
2022-01-28 22:42 ` [PATCH v4 3/4] rockchip: sdhci: Add HS400 Enhanced Strobe support for RK3399 Alper Nebi Yasak
2022-02-08 23:39   ` Jaehoon Chung
2022-01-28 22:42 ` [PATCH v4 4/4] rockchip: sdhci: Add HS400 Enhanced Strobe support for RK3568 Alper Nebi Yasak
2022-02-08 23:43   ` Jaehoon Chung
2022-02-26 18:36     ` Simon Glass
2022-03-03  8:29       ` Jaehoon Chung

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=20220128224240.4226-3-alpernebiyasak@gmail.com \
    --to=alpernebiyasak@gmail.com \
    --cc=a-govindraju@ti.com \
    --cc=ashok.reddy.soma@xilinx.com \
    --cc=faiz_abbas@ti.com \
    --cc=jagan@amarulasolutions.com \
    --cc=jh80.chung@samsung.com \
    --cc=kever.yang@rock-chips.com \
    --cc=michal.simek@xilinx.com \
    --cc=ml@embed.me.uk \
    --cc=pbrobinson@gmail.com \
    --cc=peng.fan@nxp.com \
    --cc=philipp.tomsich@vrull.eu \
    --cc=samuel@dionne-riel.com \
    --cc=sjg@chromium.org \
    --cc=stcarlso@linux.microsoft.com \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    --cc=yifeng.zhao@rock-chips.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox