Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751294AbdCQNLN (ORCPT ); Fri, 17 Mar 2017 09:11:13 -0400 Received: from mx0a-0014ca01.pphosted.com ([208.84.65.235]:34818 "EHLO mx0a-0014ca01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751039AbdCQNLK (ORCPT ); Fri, 17 Mar 2017 09:11:10 -0400 X-CrossPremisesHeadersFilteredBySendConnector: maileu3.global.cadence.com From: Piotr Sroka To: CC: Adrian Hunter , Ulf Hansson , , Masahiro Yamada , Piotr Sroka Subject: [v3 3/3] mmc: sdhci-cadence: Update PHY delay configuration Date: Fri, 17 Mar 2017 12:41:43 +0000 Message-ID: <1489754503-16559-1-git-send-email-piotrs@cadence.com> X-Mailer: git-send-email 2.2.2 In-Reply-To: <1489754302-10996-1-git-send-email-piotrs@cadence.com> References: <1489754302-10996-1-git-send-email-piotrs@cadence.com> MIME-Version: 1.0 Content-Type: text/plain X-OrganizationHeadersPreserved: maileu3.global.cadence.com Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4124 Lines: 130 DTS properties are used instead of fixed data because PHY settings can be different for different chips/boards. Signed-off-by: Piotr Sroka --- Changes for v2: - dts part was removed from this patch - most delays were moved from dts file to data associated with an SoC specific compatible - remove unrelated changes --- Changes for v3: - move all delays back to dts because they are also boards dependent - prefix all of the Cadence-specific properties with cdns prefix - put checking delay properties inside the for loop instead of using a lot of single if expressions --- drivers/mmc/host/sdhci-cadence.c | 57 +++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index b2334ec..7728ce6 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "sdhci-pltfm.h" @@ -54,6 +55,9 @@ #define SDHCI_CDNS_PHY_DLY_EMMC_LEGACY 0x06 #define SDHCI_CDNS_PHY_DLY_EMMC_SDR 0x07 #define SDHCI_CDNS_PHY_DLY_EMMC_DDR 0x08 +#define SDHCI_CDNS_PHY_DLY_SDCLK 0x0b +#define SDHCI_CDNS_PHY_DLY_HSMMC 0x0c +#define SDHCI_CDNS_PHY_DLY_STROBE 0x0d /* * The tuned val register is 6 bit-wide, but not the whole of the range is @@ -62,10 +66,33 @@ */ #define SDHCI_CDNS_MAX_TUNING_LOOP 40 +static const struct of_device_id sdhci_cdns_match[]; + struct sdhci_cdns_priv { void __iomem *hrs_addr; }; + +struct sdhci_cdns_phy_cfg { + const char *property; + u8 addr; +}; + +static const struct sdhci_cdns_phy_cfg sdhci_cdns_phy_cfgs[] = { + { "cdns,phy-input-delay-sd-highspeed", SDHCI_CDNS_PHY_DLY_SD_HS, }, + { "cdns,phy-input-delay-sd-legacy", SDHCI_CDNS_PHY_DLY_SD_DEFAULT, }, + { "cdns,phy-input-delay-sd-uhs-sdr12", SDHCI_CDNS_PHY_DLY_UHS_SDR12, }, + { "cdns,phy-input-delay-sd-uhs-sdr25", SDHCI_CDNS_PHY_DLY_UHS_SDR25, }, + { "cdns,phy-input-delay-sd-uhs-sdr50", SDHCI_CDNS_PHY_DLY_UHS_SDR50, }, + { "cdns,phy-input-delay-sd-uhs-ddr50", SDHCI_CDNS_PHY_DLY_UHS_DDR50, }, + { "cdns,phy-input-delay-mmc-highspeed", SDHCI_CDNS_PHY_DLY_EMMC_SDR, }, + { "cdns,phy-input-delay-mmc-ddr", SDHCI_CDNS_PHY_DLY_EMMC_DDR, }, + { "cdns,phy-dll-delay-sdclk", SDHCI_CDNS_PHY_DLY_SDCLK, }, + { "cdns,phy-dll-delay-sdclk-hsmmc", SDHCI_CDNS_PHY_DLY_HSMMC, }, + { "cdns,phy-dll-delay-strobe", SDHCI_CDNS_PHY_DLY_STROBE, }, +}; + + static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv, u8 addr, u8 data) { @@ -90,13 +117,26 @@ static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv, return 0; } -static void sdhci_cdns_phy_init(struct sdhci_cdns_priv *priv) +static int sdhci_cdns_phy_init(struct device_node *np, + struct sdhci_cdns_priv *priv) { - sdhci_cdns_write_phy_reg(priv, SDHCI_CDNS_PHY_DLY_SD_HS, 4); - sdhci_cdns_write_phy_reg(priv, SDHCI_CDNS_PHY_DLY_SD_DEFAULT, 4); - sdhci_cdns_write_phy_reg(priv, SDHCI_CDNS_PHY_DLY_EMMC_LEGACY, 9); - sdhci_cdns_write_phy_reg(priv, SDHCI_CDNS_PHY_DLY_EMMC_SDR, 2); - sdhci_cdns_write_phy_reg(priv, SDHCI_CDNS_PHY_DLY_EMMC_DDR, 3); + u32 val; + int ret, i; + + for (i = 0; i < ARRAY_SIZE(sdhci_cdns_phy_cfgs); i++) { + ret = of_property_read_u32(np, sdhci_cdns_phy_cfgs[i].property, + &val); + if (ret) + continue; + + ret = sdhci_cdns_write_phy_reg(priv, + sdhci_cdns_phy_cfgs[i].addr, + val); + if (ret) + return ret; + } + + return 0; } static inline void *sdhci_cdns_priv(struct sdhci_host *host) @@ -227,6 +267,7 @@ static int sdhci_cdns_probe(struct platform_device *pdev) struct sdhci_cdns_priv *priv; struct clk *clk; int ret; + struct device *dev = &pdev->dev; clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) @@ -254,7 +295,9 @@ static int sdhci_cdns_probe(struct platform_device *pdev) if (ret) goto free; - sdhci_cdns_phy_init(priv); + ret = sdhci_cdns_phy_init(dev->of_node, priv); + if (ret) + goto free; ret = sdhci_add_host(host); if (ret) -- 2.2.2