From nobody Mon Feb 9 23:44:55 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0389AC83F1F for ; Wed, 30 Aug 2023 03:19:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241880AbjH3DTc convert rfc822-to-8bit (ORCPT ); Tue, 29 Aug 2023 23:19:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238547AbjH3DSz (ORCPT ); Tue, 29 Aug 2023 23:18:55 -0400 Received: from ex01.ufhost.com (ex01.ufhost.com [61.152.239.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8EE66113; Tue, 29 Aug 2023 20:18:52 -0700 (PDT) Received: from EXMBX166.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX166", Issuer "EXMBX166" (not verified)) by ex01.ufhost.com (Postfix) with ESMTP id 5AA7024E282; Wed, 30 Aug 2023 11:18:49 +0800 (CST) Received: from EXMBX168.cuchost.com (172.16.6.78) by EXMBX166.cuchost.com (172.16.6.76) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Wed, 30 Aug 2023 11:18:49 +0800 Received: from williamqiu-virtual-machine.starfivetech.com (171.223.208.138) by EXMBX168.cuchost.com (172.16.6.78) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Wed, 30 Aug 2023 11:18:48 +0800 From: William Qiu To: , , , CC: Emil Renner Berthing , Rob Herring , Jaehoon Chung , Ulf Hansson , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , "Palmer Dabbelt" , Albert Ou , William Qiu Subject: [PATCH v1 2/3] mmc: starfive: Change tuning implementation Date: Wed, 30 Aug 2023 11:18:45 +0800 Message-ID: <20230830031846.127957-3-william.qiu@starfivetech.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230830031846.127957-1-william.qiu@starfivetech.com> References: <20230830031846.127957-1-william.qiu@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [171.223.208.138] X-ClientProxiedBy: EXCAS064.cuchost.com (172.16.6.24) To EXMBX168.cuchost.com (172.16.6.78) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Before, we used syscon to achieve tuning, but the actual measurement showed little effect, so the tuning implementation was modified here, and it was realized by reading and writing the UHS_REG_EXT register. Signed-off-by: William Qiu --- drivers/mmc/host/dw_mmc-starfive.c | 131 ++++++++--------------------- 1 file changed, 37 insertions(+), 94 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-starfive.c b/drivers/mmc/host/dw_mmc-s= tarfive.c index fd05a648a8bb..593c995e49f5 100644 --- a/drivers/mmc/host/dw_mmc-starfive.c +++ b/drivers/mmc/host/dw_mmc-starfive.c @@ -20,14 +20,6 @@ #define ALL_INT_CLR 0x1ffff #define MAX_DELAY_CHAIN 32 =20 -struct starfive_priv { - struct device *dev; - struct regmap *reg_syscon; - u32 syscon_offset; - u32 syscon_shift; - u32 syscon_mask; -}; - static void dw_mci_starfive_set_ios(struct dw_mci *host, struct mmc_ios *i= os) { int ret; @@ -44,117 +36,68 @@ static void dw_mci_starfive_set_ios(struct dw_mci *hos= t, struct mmc_ios *ios) } } =20 +static void dw_mci_starfive_hs_set_bits(struct dw_mci *host, u32 smpl_phas= e) +{ + /* change driver phase and sample phase */ + u32 mask =3D 0x1f; + u32 reg_value; + + reg_value =3D mci_readl(host, UHS_REG_EXT); + + /* In UHS_REG_EXT, only 5 bits valid in DRV_PHASE and SMPL_PHASE */ + reg_value &=3D ~(mask << 16); + reg_value |=3D (smpl_phase << 16); + mci_writel(host, UHS_REG_EXT, reg_value); + + /* We should delay 1ms wait for timing setting finished. */ + mdelay(1); +} + static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot, u32 opcode) { static const int grade =3D MAX_DELAY_CHAIN; struct dw_mci *host =3D slot->host; - struct starfive_priv *priv =3D host->priv; - int rise_point =3D -1, fall_point =3D -1; - int err, prev_err =3D 0; + int err =3D -1; + int smpl_phase, smpl_raise =3D -1, smpl_fall =3D -1; int i; - bool found =3D 0; - u32 regval; - - /* - * Use grade as the max delay chain, and use the rise_point and - * fall_point to ensure the best sampling point of a data input - * signals. - */ + for (i =3D 0; i < grade; i++) { - regval =3D i << priv->syscon_shift; - err =3D regmap_update_bits(priv->reg_syscon, priv->syscon_offset, - priv->syscon_mask, regval); - if (err) - return err; + smpl_phase =3D i; + dw_mci_starfive_hs_set_bits(host, smpl_phase); mci_writel(host, RINTSTS, ALL_INT_CLR); =20 err =3D mmc_send_tuning(slot->mmc, opcode, NULL); - if (!err) - found =3D 1; - - if (i > 0) { - if (err && !prev_err) - fall_point =3D i - 1; - if (!err && prev_err) - rise_point =3D i; - } =20 - if (rise_point !=3D -1 && fall_point !=3D -1) - goto tuning_out; - - prev_err =3D err; - err =3D 0; - } - -tuning_out: - if (found) { - if (rise_point =3D=3D -1) - rise_point =3D 0; - if (fall_point =3D=3D -1) - fall_point =3D grade - 1; - if (fall_point < rise_point) { - if ((rise_point + fall_point) > - (grade - 1)) - i =3D fall_point / 2; - else - i =3D (rise_point + grade - 1) / 2; - } else { - i =3D (rise_point + fall_point) / 2; + if (!err && smpl_raise < 0) { + smpl_raise =3D i; + } else if (err && smpl_raise >=3D 0) { + smpl_fall =3D i - 1; + break; } + } =20 - regval =3D i << priv->syscon_shift; - err =3D regmap_update_bits(priv->reg_syscon, priv->syscon_offset, - priv->syscon_mask, regval); - if (err) - return err; - mci_writel(host, RINTSTS, ALL_INT_CLR); + if (i >=3D grade && smpl_raise >=3D 0) + smpl_fall =3D grade - 1; =20 - dev_info(host->dev, "Found valid delay chain! use it [delay=3D%d]\n", i); - } else { + if (smpl_raise < 0) { dev_err(host->dev, "No valid delay chain! use default\n"); + dw_mci_starfive_hs_set_bits(host, 0); err =3D -EINVAL; + } else { + smpl_phase =3D (smpl_raise + smpl_fall) / 2; + dw_mci_starfive_hs_set_bits(host, smpl_phase); + dev_dbg(host->dev, "Found valid delay chain! use it [delay=3D%d]\n", smp= l_phase); + err =3D 0; } =20 mci_writel(host, RINTSTS, ALL_INT_CLR); return err; } =20 -static int dw_mci_starfive_parse_dt(struct dw_mci *host) -{ - struct of_phandle_args args; - struct starfive_priv *priv; - int ret; - - priv =3D devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - ret =3D of_parse_phandle_with_fixed_args(host->dev->of_node, - "starfive,sysreg", 3, 0, &args); - if (ret) { - dev_err(host->dev, "Failed to parse starfive,sysreg\n"); - return -EINVAL; - } - - priv->reg_syscon =3D syscon_node_to_regmap(args.np); - of_node_put(args.np); - if (IS_ERR(priv->reg_syscon)) - return PTR_ERR(priv->reg_syscon); - - priv->syscon_offset =3D args.args[0]; - priv->syscon_shift =3D args.args[1]; - priv->syscon_mask =3D args.args[2]; - - host->priv =3D priv; - - return 0; -} - static const struct dw_mci_drv_data starfive_data =3D { .common_caps =3D MMC_CAP_CMD23, .set_ios =3D dw_mci_starfive_set_ios, - .parse_dt =3D dw_mci_starfive_parse_dt, .execute_tuning =3D dw_mci_starfive_execute_tuning, }; =20 --=20 2.34.1