From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EDCD6C433F5 for ; Fri, 28 Jan 2022 22:43:22 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1F86483813; Fri, 28 Jan 2022 23:43:14 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="M2AFExn7"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 444C783831; Fri, 28 Jan 2022 23:43:12 +0100 (CET) Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 696078380E for ; Fri, 28 Jan 2022 23:43:09 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=alpernebiyasak@gmail.com Received: by mail-wr1-x430.google.com with SMTP id v13so13491662wrv.10 for ; Fri, 28 Jan 2022 14:43:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OIAj9G6yGH9HMCOe7YrcswaLkP0Hzb24NXqJeOtz8v8=; b=M2AFExn7i4G0AtbEkdwmLFKzpHY3QJWPTuZYP09gXLQFQ/4f3tD5mpTfJxrafv+iOM PHCE79n1k9SAoj6sh3PcrqqXq/Y2b+ghPuy4Yu+FfthO91tVjYS0GeQhuHZwU52HPvA9 s3UuqXDN+RDYwMAWYvm+leI8mB7GbHF4e+kqKsZk/ipgWx4K+UMj+2zwl4gtjuUEXKVl NgTO5D/BmuSyUJEOOjtLQgd4JoLbN3wTlNQweLEQ4XsAl0sxeeIyzGeiq2dZBqQRI+6c G/buu9lvo1b54guwyU8L0Fj95ups2P5D/Vc+Ai0N92OxFfL6aS0kNcN3eTbm9HXrRLKY XNdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OIAj9G6yGH9HMCOe7YrcswaLkP0Hzb24NXqJeOtz8v8=; b=KWm2UZjKlh9Hagirv4GaNWOCh0MwfYNxVitHLG/KqsAHLvEFQz8izYxRM+vrh7jfgD OoGP88YHvnjuGgQ3eh9v4uvCbxcAWsYaMNPFo3l+4XmNfZWSSrx4Lp9MwrTTzIEiS96Q M/jVXkwgfD/RBJ9Vpbb2W/VmjfUZxyKfBmWp6hZNb6IR1s7zI9BkUPr/olnHnik7FBbP C2gIOEV11R/zLGv6jK9TOimNV9gdB3sj4YwzP2bKaUj5v2e6Hq0EaI2FEyVk2V+YmGp6 e/2m1mpwXfcwnCikZoxVLNqrbTqX+LmdzEt5w3cE6Rhl7U3qN6tLKO5tmKfAYxRdHJJg KD0g== X-Gm-Message-State: AOAM5311rcRjNktOj1z/UlDLrtnuxKKXIUoLC14aIbYSy1UW3vmaDhME D63tgavB6+dQQfCK6+JwN/If68HxlnmYKw== X-Google-Smtp-Source: ABdhPJxWogx82WTx5mdZ/yFKcoXTUkjRhelErFjGZngk0TIZYl1UjROIzs0H4BZlLyeHWInJ9bxtnw== X-Received: by 2002:a5d:4a8d:: with SMTP id o13mr8930833wrq.696.1643409789008; Fri, 28 Jan 2022 14:43:09 -0800 (PST) Received: from localhost.localdomain ([178.233.26.119]) by smtp.gmail.com with ESMTPSA id m8sm5413586wrn.106.2022.01.28.14.43.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Jan 2022 14:43:08 -0800 (PST) From: Alper Nebi Yasak To: u-boot@lists.denx.de Cc: Jack Mitchell , Kever Yang , Heinrich Schuchardt , Yifeng Zhao , Samuel Dionne-Riel , Simon Glass , Aswath Govindraju , Philipp Tomsich , Ashok Reddy Soma , Stephen Carlson , Jaehoon Chung , Michal Simek , Faiz Abbas , Jagan Teki , Peng Fan , Peter Robinson , Alper Nebi Yasak Subject: [PATCH v4 2/4] rockchip: sdhci: Fix RK3399 eMMC PHY power cycling Date: Sat, 29 Jan 2022 01:42:37 +0300 Message-Id: <20220128224240.4226-3-alpernebiyasak@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220128224240.4226-1-alpernebiyasak@gmail.com> References: <20220128224240.4226-1-alpernebiyasak@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean 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 --- 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