From patchwork Tue Jun 7 22:44:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 9162769 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 726ED60467 for ; Tue, 7 Jun 2016 22:48:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 638BC28360 for ; Tue, 7 Jun 2016 22:48:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 57F652836E; Tue, 7 Jun 2016 22:48:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CE6B228360 for ; Tue, 7 Jun 2016 22:48:29 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1bAPm7-00071Y-Ug; Tue, 07 Jun 2016 22:47:07 +0000 Received: from mail-pf0-x232.google.com ([2607:f8b0:400e:c00::232]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1bAPkg-0005S5-2o for linux-arm-kernel@lists.infradead.org; Tue, 07 Jun 2016 22:45:42 +0000 Received: by mail-pf0-x232.google.com with SMTP id c2so9269667pfa.2 for ; Tue, 07 Jun 2016 15:45:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3H/pJjZFMVcgMfYX2WtHfN91/b37KIeqIhzAdZT3JwM=; b=IzsDkgdP7TSRqSF4xUCtaa7v7JVHHz9C5hr4LipzB1CDyqoN2ZqewBbTqQXPG8F+Aq vjo9z4k1NKFW2wfryGZP2UcOkQXpoD45nvBDDkBjOm/qHrEkTij3TK3zPr2WgJ0PmB4a MYt4BgJLMEm5YNTKduVdmzu+9Z/JG5l2nTNhE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3H/pJjZFMVcgMfYX2WtHfN91/b37KIeqIhzAdZT3JwM=; b=W87914b/NR5lHoUMlJQcL3cIbQT28jAzf0TaN7ZmDAATZutkUpL4fBA/+S4rERv4Mz JXlxkD1NcSqqvLzHd1SAtrGav69EaM2DzjA9WqDWH4WnPBWAIlebUUe/uNRWHzOHIGHW m3PfErPRWcTrXijjeloqK3M9/wNJhbnzzSjGVAcl4YNY8TroE7AcRjZ4946k6rZBjBBU cpiSeT7yIcYRwy9TIgVD4qM5zlihCMI/qbtSn6pz6AVw17RuP2Igy0WwW6gOUTLIbHFF zgpZeg/p8tnF2IyiPIl24l5xvFeqjrS1jg/+BVpIqei5CB+3B3ty8op5QM8L5fPRnjHx c/lA== X-Gm-Message-State: ALyK8tLx8PY9z+IuKoYV3Kznq9w1xbolJGqn7cejuclw2K+W3rHCBMUhyG3L1zQiRD9Nv66E X-Received: by 10.98.5.133 with SMTP id 127mr1943566pff.110.1465339517165; Tue, 07 Jun 2016 15:45:17 -0700 (PDT) Received: from tictac.mtv.corp.google.com ([172.22.65.76]) by smtp.gmail.com with ESMTPSA id 4sm37641782pfm.15.2016.06.07.15.45.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 07 Jun 2016 15:45:16 -0700 (PDT) From: Douglas Anderson To: ulf.hansson@linaro.org, kishon@ti.com, Heiko Stuebner , robh+dt@kernel.org Subject: [PATCH 09/11] phy: rockchip-emmc: Set phyctrl_frqsel based on card clock Date: Tue, 7 Jun 2016 15:44:42 -0700 Message-Id: <1465339484-969-10-git-send-email-dianders@chromium.org> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1465339484-969-1-git-send-email-dianders@chromium.org> References: <1465339484-969-1-git-send-email-dianders@chromium.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160607_154538_488232_00D30CF6 X-CRM114-Status: GOOD ( 21.84 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, xzy.xu@rock-chips.com, linux-kernel@vger.kernel.org, shawn.lin@rock-chips.com, briannorris@chromium.org, linux-mmc@vger.kernel.org, adrian.hunter@intel.com, Douglas Anderson , linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The "phyctrl_frqsel" is described in the Arasan datasheet [1] as "the frequency range of DLL operation". Although the Rockchip variant of this PHY has different ranges than the reference Arasan PHY it appears as if the functionality is similar. We should set this phyctrl field properly. Note: as per Rockchip engineers, apparently the "phyctrl_frqsel" is actually only useful in HS200 / HS400 modes even though the DLL itself it used for some purposes in all modes. See the discussion in the earlier change in this series: ("mmc: sdhci-of-arasan: Always power the PHY off/on when clock changes"). In any case, it shouldn't hurt to set this always. Note that this change should allow boards to run at HS200 / HS400 speed modes while running at 100 MHz or 150 MHz. In fact, running HS400 at 150 MHz (giving 300 MB/s) is the main motivation of this series, since performance is still good but signal integrity problems are less prevelant at 150 MHz. [1]: https://arasan.com/wp-content/media/eMMC-5-1-Total-Solution_Rev-1-3.pdf Signed-off-by: Douglas Anderson --- drivers/phy/phy-rockchip-emmc.c | 74 +++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 17 deletions(-) diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c index 8336053aea5c..0fce7359d468 100644 --- a/drivers/phy/phy-rockchip-emmc.c +++ b/drivers/phy/phy-rockchip-emmc.c @@ -14,6 +14,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -78,16 +79,61 @@ struct rockchip_emmc_phy { unsigned int reg_offset; struct regmap *reg_base; + struct clk *emmcclk; }; -static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy, - bool on_off) +static int rockchip_emmc_phy_power(struct phy *phy, bool on_off) { + struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy); unsigned int caldone; unsigned int dllrdy; + unsigned int freqsel = PHYCTRL_FREQSEL_200M; unsigned long timeout; /* + * We purposely get the clock here and not in probe to avoid the + * circular dependency problem. We expect: + * - PHY driver to probe + * - USB driver to start probe + * - USB driver to register it's clock + * - USB driver to get the PHY + * - USB driver to power on the PHY + */ + if (!rk_phy->emmcclk) { + rk_phy->emmcclk = devm_clk_get(&phy->dev, "emmcclk"); + + /* Don't expect defer at this point; try next time */ + if (PTR_ERR(rk_phy->emmcclk) == -EPROBE_DEFER) { + dev_warn(&phy->dev, "Unexpected emmcclk defer\n"); + rk_phy->emmcclk = NULL; + } + } + + if (!IS_ERR_OR_NULL(rk_phy->emmcclk)) { + unsigned long rate = clk_get_rate(rk_phy->emmcclk); + + switch (rate) { + case 0 ... 74999999: + /* Nominal 50 MHz */ + freqsel = PHYCTRL_FREQSEL_50M; + break; + case 75000000 ... 124999999: + /* Nominal 100 MHz */ + freqsel = PHYCTRL_FREQSEL_100M; + break; + case 125000000 ... 174999999: + /* Nominal 150 MHz */ + freqsel = PHYCTRL_FREQSEL_150M; + break; + default: + if (rate > 200000000) + dev_warn(&phy->dev, "Unsupported rate: %lu\n", + rate); + break; + }; + } + + /* * Keep phyctrl_pdb and phyctrl_endll low to allow * initialization of CALIO state M/C DFFs */ @@ -132,6 +178,13 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy, return -ETIMEDOUT; } + /* Set the frequency of the DLL operation */ + regmap_write(rk_phy->reg_base, + rk_phy->reg_offset + GRF_EMMCPHY_CON0, + HIWORD_UPDATE(freqsel, PHYCTRL_FREQSEL_MASK, + PHYCTRL_FREQSEL_SHIFT)); + + /* Turn on the DLL */ regmap_write(rk_phy->reg_base, rk_phy->reg_offset + GRF_EMMCPHY_CON6, HIWORD_UPDATE(PHYCTRL_ENDLL_ENABLE, @@ -167,15 +220,8 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy, static int rockchip_emmc_phy_power_off(struct phy *phy) { - struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy); - int ret = 0; - /* Power down emmc phy analog blocks */ - ret = rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_OFF); - if (ret) - return ret; - - return 0; + return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_OFF); } static int rockchip_emmc_phy_power_on(struct phy *phy) @@ -183,12 +229,6 @@ static int rockchip_emmc_phy_power_on(struct phy *phy) struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy); int ret = 0; - /* DLL operation: 200 MHz */ - regmap_write(rk_phy->reg_base, - rk_phy->reg_offset + GRF_EMMCPHY_CON0, - HIWORD_UPDATE(PHYCTRL_FREQSEL_200M, - PHYCTRL_FREQSEL_MASK, - PHYCTRL_FREQSEL_SHIFT)); /* Drive impedance: 50 Ohm */ regmap_write(rk_phy->reg_base, @@ -212,7 +252,7 @@ static int rockchip_emmc_phy_power_on(struct phy *phy) PHYCTRL_OTAPDLYSEL_SHIFT)); /* Power up emmc phy analog blocks */ - ret = rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_ON); + ret = rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_ON); if (ret) return ret;