From patchwork Mon Jul 17 12:51:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Piyush Malgujar X-Patchwork-Id: 121302 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp1105330vqt; Mon, 17 Jul 2023 06:17:19 -0700 (PDT) X-Google-Smtp-Source: APBJJlG+Cd/gSbLhq+FPrnGCHcNG0ahR03cUchOvGmNHP9WcxYLFR2sYkBjcZ14t8lqmKFx4D428 X-Received: by 2002:a05:6a21:900c:b0:10c:7c72:bdf9 with SMTP id tq12-20020a056a21900c00b0010c7c72bdf9mr10072382pzb.29.1689599838689; Mon, 17 Jul 2023 06:17:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689599838; cv=none; d=google.com; s=arc-20160816; b=0LlqpSCvXsesFLbW5xCewNyUdg6qS0/oO+zB1EqfCrK4qNM1qbHGvCghHA9zmHH9RC P4oZpGavi3nsM2+uWPt42SI2t1BFs1uzcmqpZCiEJ8DMbR+0zSjZY47wc4vssW/exf5X tJEeiTBtU2uGC5X1LCQT+jcj/rYKxtDa+EFlKDX3BwNksa/234q9wT+SPtyHayqmfC6M eR5uiDWi/KVCoK7XCmor81F7OqGpfjC25fNCCR2m2wZfTRcDSYf7tWPaDs5s3CPeRBPg JgQXzlUalOx+n3g1Tq3z2f/eSGaHjxMwshtsv/GvqvSaQ3QW36DMLQLqydnclMxVVNl8 gS/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1BFeljk/Xu16TpDvpPjo7fVmgH1xWGHjLKmZjHDjzns=; fh=USvMBNx43J86pnR+f1+ON+JulYM2jLfcJbvJ6gv/0aA=; b=Sn1xSEHHdFK+7SmuZh+GcRgqAwF4TpGkl44HypMW3u4xjnHQjhdFG2CLiKcIarHB7U vCNNB6usc42wvDxDFALs5fJhh1qLXjkwHfKcQ6654Uj+56halvYdmqCGvpI/6n9fuxFS O2nLkUpN4LGflQF8wqRAZ+te+gsbbVKqrHk6kPPH4kZuQ06e6YiLfkwrX6J8qZxY6sAt O54JwV0TRTf+lciZGoekamymbh2l+r/cLa5M3n06fD8+YLXWF0bzFJI7O6S3bMps8CE6 C3dftuUO9NMFlrYaD098kptP1wypb2Gs1fEDLWjVurD8j8j9pHcwdyg1NH/GLPKJKCLL mLlA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=jil63MCb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p16-20020a170902e75000b001b9ed021929si11825870plf.225.2023.07.17.06.17.05; Mon, 17 Jul 2023 06:17:18 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=jil63MCb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230448AbjGQMwh (ORCPT + 99 others); Mon, 17 Jul 2023 08:52:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229579AbjGQMwf (ORCPT ); Mon, 17 Jul 2023 08:52:35 -0400 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2403D1B0; Mon, 17 Jul 2023 05:52:34 -0700 (PDT) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 36H5TsJu020476; Mon, 17 Jul 2023 05:52:24 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=1BFeljk/Xu16TpDvpPjo7fVmgH1xWGHjLKmZjHDjzns=; b=jil63MCbVRFfrAPv3XrlbFUqKWqMD0w0vs7s0O5TdLOra2RABLkqeLjCjYwDHrs3vcmi tDVEH/jjohQ3+VfkdkNiISjBQcKUfieZHTjyhpjZuVXVjm/vm8coPgyRvk0sq87t/wZ3 82ubRN6F0YYRj+nnBaDpdD090ZJbG/Fa16H/VCthpI07opxupgvrU21H+Zw8flbECgOr +2TLOhWLqsG93lbtFNV22s5OyJsOylk6zBJ2rxvOWV4zTLGmebjYuk9sX07+3aBJTLh2 Oh8CGUnyTCEp/NmmXH2NEmvBtqKW1yeQqPt7VjpAFkj7KLQsBLa0Hfnv/2VrsUUl9o9/ 0g== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3rvyhx18kr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 17 Jul 2023 05:52:23 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Mon, 17 Jul 2023 05:52:22 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Mon, 17 Jul 2023 05:52:22 -0700 Received: from localhost.localdomain (unknown [10.110.150.250]) by maili.marvell.com (Postfix) with ESMTP id 093293F70A4; Mon, 17 Jul 2023 05:52:22 -0700 (PDT) From: Piyush Malgujar To: , , , , , , , , , CC: , , Dhananjay Kangude , Piyush Malgujar Subject: [PATCH v4 1/6] mmc: sdhci-cadence: Rename functions/structures to SD4 specific Date: Mon, 17 Jul 2023 05:51:41 -0700 Message-ID: <20230717125146.16791-2-pmalgujar@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230717125146.16791-1-pmalgujar@marvell.com> References: <20230717125146.16791-1-pmalgujar@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: akx7PtFYbmdeSvORIIbOvj_ySMiVNsez X-Proofpoint-ORIG-GUID: akx7PtFYbmdeSvORIIbOvj_ySMiVNsez X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-07-17_10,2023-07-13_01,2023-05-22_02 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771673840360494532 X-GMAIL-MSGID: 1771673840360494532 From: Dhananjay Kangude Renaming the functions and structures specific to SD4 so that it can be separated from upcoming SD6 related functionality. Signed-off-by: Dhananjay Kangude Co-developed-by: Jayanthi Annadurai Signed-off-by: Jayanthi Annadurai Signed-off-by: Piyush Malgujar --- drivers/mmc/host/sdhci-cadence.c | 92 ++++++++++++++++---------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index d2f62505468932b069e3411f2a4b7418ffece517..9bb38281bcb244b0be91ef579046c40de7a06e1f 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c @@ -16,14 +16,14 @@ #include "sdhci-pltfm.h" -/* HRS - Host Register Set (specific to Cadence) */ -#define SDHCI_CDNS_HRS04 0x10 /* PHY access port */ -#define SDHCI_CDNS_HRS04_ACK BIT(26) -#define SDHCI_CDNS_HRS04_RD BIT(25) -#define SDHCI_CDNS_HRS04_WR BIT(24) -#define SDHCI_CDNS_HRS04_RDATA GENMASK(23, 16) -#define SDHCI_CDNS_HRS04_WDATA GENMASK(15, 8) -#define SDHCI_CDNS_HRS04_ADDR GENMASK(5, 0) +/* SD 4.0 Controller HRS - Host Register Set (specific to Cadence) */ +#define SDHCI_CDNS_HRS04 0x10 /* PHY access port */ +#define SDHCI_CDNS_SD4_HRS04_ACK BIT(26) +#define SDHCI_CDNS_SD4_HRS04_RD BIT(25) +#define SDHCI_CDNS_SD4_HRS04_WR BIT(24) +#define SDHCI_CDNS_SD4_HRS04_RDATA GENMASK(23, 16) +#define SDHCI_CDNS_SD4_HRS04_WDATA GENMASK(15, 8) +#define SDHCI_CDNS_SD4_HRS04_ADDR GENMASK(5, 0) #define SDHCI_CDNS_HRS06 0x18 /* eMMC control */ #define SDHCI_CDNS_HRS06_TUNE_UP BIT(15) @@ -39,7 +39,7 @@ /* SRS - Slot Register Set (SDHCI-compatible) */ #define SDHCI_CDNS_SRS_BASE 0x200 -/* PHY */ +/* PHY registers for SD4 controller */ #define SDHCI_CDNS_PHY_DLY_SD_HS 0x00 #define SDHCI_CDNS_PHY_DLY_SD_DEFAULT 0x01 #define SDHCI_CDNS_PHY_DLY_UHS_SDR12 0x02 @@ -60,7 +60,7 @@ */ #define SDHCI_CDNS_MAX_TUNING_LOOP 40 -struct sdhci_cdns_phy_param { +struct sdhci_cdns_sd4_phy_param { u8 addr; u8 data; }; @@ -73,10 +73,10 @@ struct sdhci_cdns_priv { void (*priv_writel)(struct sdhci_cdns_priv *priv, u32 val, void __iomem *reg); struct reset_control *rst_hw; unsigned int nr_phy_params; - struct sdhci_cdns_phy_param phy_params[]; + struct sdhci_cdns_sd4_phy_param phy_params[]; }; -struct sdhci_cdns_phy_cfg { +struct sdhci_cdns_sd4_phy_cfg { const char *property; u8 addr; }; @@ -86,7 +86,7 @@ struct sdhci_cdns_drv_data { const struct sdhci_pltfm_data pltfm_data; }; -static const struct sdhci_cdns_phy_cfg sdhci_cdns_phy_cfgs[] = { +static const struct sdhci_cdns_sd4_phy_cfg sdhci_cdns_sd4_phy_cfgs[] = { { "cdns,phy-input-delay-sd-highspeed", SDHCI_CDNS_PHY_DLY_SD_HS, }, { "cdns,phy-input-delay-legacy", SDHCI_CDNS_PHY_DLY_SD_DEFAULT, }, { "cdns,phy-input-delay-sd-uhs-sdr12", SDHCI_CDNS_PHY_DLY_UHS_SDR12, }, @@ -106,76 +106,76 @@ static inline void cdns_writel(struct sdhci_cdns_priv *priv, u32 val, writel(val, reg); } -static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv, - u8 addr, u8 data) +static int sdhci_cdns_sd4_write_phy_reg(struct sdhci_cdns_priv *priv, + u8 addr, u8 data) { void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS04; u32 tmp; int ret; - ret = readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS04_ACK), + ret = readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_SD4_HRS04_ACK), 0, 10); if (ret) return ret; - tmp = FIELD_PREP(SDHCI_CDNS_HRS04_WDATA, data) | - FIELD_PREP(SDHCI_CDNS_HRS04_ADDR, addr); + tmp = FIELD_PREP(SDHCI_CDNS_SD4_HRS04_WDATA, data) | + FIELD_PREP(SDHCI_CDNS_SD4_HRS04_ADDR, addr); priv->priv_writel(priv, tmp, reg); - tmp |= SDHCI_CDNS_HRS04_WR; + tmp |= SDHCI_CDNS_SD4_HRS04_WR; priv->priv_writel(priv, tmp, reg); - ret = readl_poll_timeout(reg, tmp, tmp & SDHCI_CDNS_HRS04_ACK, 0, 10); + ret = readl_poll_timeout(reg, tmp, tmp & SDHCI_CDNS_SD4_HRS04_ACK, 0, 10); if (ret) return ret; - tmp &= ~SDHCI_CDNS_HRS04_WR; + tmp &= ~SDHCI_CDNS_SD4_HRS04_WR; priv->priv_writel(priv, tmp, reg); - ret = readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS04_ACK), + ret = readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_SD4_HRS04_ACK), 0, 10); return ret; } -static unsigned int sdhci_cdns_phy_param_count(struct device_node *np) +static unsigned int sdhci_cdns_sd4_phy_param_count(struct device_node *np) { unsigned int count = 0; int i; - for (i = 0; i < ARRAY_SIZE(sdhci_cdns_phy_cfgs); i++) - if (of_property_read_bool(np, sdhci_cdns_phy_cfgs[i].property)) + for (i = 0; i < ARRAY_SIZE(sdhci_cdns_sd4_phy_cfgs); i++) + if (of_property_read_bool(np, sdhci_cdns_sd4_phy_cfgs[i].property)) count++; return count; } -static void sdhci_cdns_phy_param_parse(struct device_node *np, - struct sdhci_cdns_priv *priv) +static void sdhci_cdns_sd4_phy_param_parse(struct device_node *np, + struct sdhci_cdns_priv *priv) { - struct sdhci_cdns_phy_param *p = priv->phy_params; + struct sdhci_cdns_sd4_phy_param *p = priv->phy_params; 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, + for (i = 0; i < ARRAY_SIZE(sdhci_cdns_sd4_phy_cfgs); i++) { + ret = of_property_read_u32(np, sdhci_cdns_sd4_phy_cfgs[i].property, &val); if (ret) continue; - p->addr = sdhci_cdns_phy_cfgs[i].addr; + p->addr = sdhci_cdns_sd4_phy_cfgs[i].addr; p->data = val; p++; } } -static int sdhci_cdns_phy_init(struct sdhci_cdns_priv *priv) +static int sdhci_cdns_sd4_phy_init(struct sdhci_cdns_priv *priv) { int ret, i; for (i = 0; i < priv->nr_phy_params; i++) { - ret = sdhci_cdns_write_phy_reg(priv, priv->phy_params[i].addr, - priv->phy_params[i].data); + ret = sdhci_cdns_sd4_write_phy_reg(priv, priv->phy_params[i].addr, + priv->phy_params[i].data); if (ret) return ret; } @@ -218,7 +218,7 @@ static u32 sdhci_cdns_get_emmc_mode(struct sdhci_cdns_priv *priv) return FIELD_GET(SDHCI_CDNS_HRS06_MODE, tmp); } -static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val) +static int sdhci_cdns_sd4_set_tune_val(struct sdhci_host *host, unsigned int val) { struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS06; @@ -271,7 +271,7 @@ static int sdhci_cdns_execute_tuning(struct sdhci_host *host, u32 opcode) return 0; for (i = 0; i < SDHCI_CDNS_MAX_TUNING_LOOP; i++) { - if (sdhci_cdns_set_tune_val(host, i) || + if (sdhci_cdns_sd4_set_tune_val(host, i) || mmc_send_tuning(host->mmc, opcode, NULL)) { /* bad */ cur_streak = 0; } else { /* good */ @@ -288,7 +288,7 @@ static int sdhci_cdns_execute_tuning(struct sdhci_host *host, u32 opcode) return -EIO; } - return sdhci_cdns_set_tune_val(host, end_of_streak - max_streak / 2); + return sdhci_cdns_sd4_set_tune_val(host, end_of_streak - max_streak / 2); } static void sdhci_cdns_set_uhs_signaling(struct sdhci_host *host, @@ -410,7 +410,7 @@ static int elba_drv_init(struct platform_device *pdev) return 0; } -static const struct sdhci_ops sdhci_cdns_ops = { +static const struct sdhci_ops sdhci_cdns_sd4_ops = { .set_clock = sdhci_set_clock, .get_timeout_clock = sdhci_cdns_get_timeout_clock, .set_bus_width = sdhci_set_bus_width, @@ -421,7 +421,7 @@ static const struct sdhci_ops sdhci_cdns_ops = { static const struct sdhci_cdns_drv_data sdhci_cdns_uniphier_drv_data = { .pltfm_data = { - .ops = &sdhci_cdns_ops, + .ops = &sdhci_cdns_sd4_ops, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, }, }; @@ -433,9 +433,9 @@ static const struct sdhci_cdns_drv_data sdhci_elba_drv_data = { }, }; -static const struct sdhci_cdns_drv_data sdhci_cdns_drv_data = { +static const struct sdhci_cdns_drv_data sdhci_cdns_sd4_drv_data = { .pltfm_data = { - .ops = &sdhci_cdns_ops, + .ops = &sdhci_cdns_sd4_ops, }, }; @@ -497,9 +497,9 @@ static int sdhci_cdns_probe(struct platform_device *pdev) data = of_device_get_match_data(dev); if (!data) - data = &sdhci_cdns_drv_data; + data = &sdhci_cdns_sd4_drv_data; - nr_phy_params = sdhci_cdns_phy_param_count(dev->of_node); + nr_phy_params = sdhci_cdns_sd4_phy_param_count(dev->of_node); host = sdhci_pltfm_init(pdev, &data->pltfm_data, struct_size(priv, phy_params, nr_phy_params)); if (IS_ERR(host)) { @@ -532,9 +532,9 @@ static int sdhci_cdns_probe(struct platform_device *pdev) if (ret) goto free; - sdhci_cdns_phy_param_parse(dev->of_node, priv); + sdhci_cdns_sd4_phy_param_parse(dev->of_node, priv); - ret = sdhci_cdns_phy_init(priv); + ret = sdhci_cdns_sd4_phy_init(priv); if (ret) goto free; @@ -574,7 +574,7 @@ static int sdhci_cdns_resume(struct device *dev) if (ret) return ret; - ret = sdhci_cdns_phy_init(priv); + ret = sdhci_cdns_sd4_phy_init(priv); if (ret) goto disable_clk; From patchwork Mon Jul 17 12:51:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Piyush Malgujar X-Patchwork-Id: 121277 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp1091745vqt; Mon, 17 Jul 2023 05:58:15 -0700 (PDT) X-Google-Smtp-Source: APBJJlFIGu/Buc6nJ3U6tA3OkIQCaT4pWnoV9Q5VyZAIC2+DkM+yXf4Ut2P5AOUZgkDbT1D2Levu X-Received: by 2002:a54:4f86:0:b0:3a4:19fd:672 with SMTP id g6-20020a544f86000000b003a419fd0672mr10495422oiy.36.1689598694954; Mon, 17 Jul 2023 05:58:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689598694; cv=none; d=google.com; s=arc-20160816; b=vPPIe29iDd2dewmjGN9fywYIHaoqNIX2cGi3IeRRVINSqU731wgRcXsdZCrYHrsiXv TLBGfLlrRJcYiILiyBDKYvR70bI5ydP6leKPPrX1XQseu7u2sPoSGIuvRUuuyMrSa6B5 GFZMmRovt4J3XTHk2coLO2Nnc3PI6HvXe38B0Y2X86vmJpSIloU0vt1gDNtlpCl4GuiB 63Og7R+V0h1dmHawqF633fsXpKGeddtuWY0RApeR9ntPVr/yatG1E4u1Zw46cFhU8yOA WRmYUdM09WCbSvXegSPJp9Jxz+Y3zA4lhkTq60dJWf9shMHlEtkEufOmDl6Hu1I+QgTq Rfag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=B0B2UkwrlR8/ITllxIICBikh3e+ZFBoBhtiHMBEoz5w=; fh=USvMBNx43J86pnR+f1+ON+JulYM2jLfcJbvJ6gv/0aA=; b=wjVVgQ/i/iKOyXM9+UjgODYZqHxZtLp4zxtyuD9gJ1ztxWBaHRrTT1uhjT4fznnm94 GP4m32S7++C8azLiya8zw3TuMdqCzf1IDt+8ilyjeZgHoC2Zs/+5KqOhMLGJOfm1Eur2 kejpWtHLEI4IbQcqRMea6LN7m9DP/sJiFUpXiGLgh9RRjbnb2vqeBR1D22Cm2xG0iVzR YxsjMmy7lulzcZA4lxnumYV7dP+JGThhZjorvIAhN/wtd3cPng92hCq+EDso+FxPaI+0 ApeE9ne6wL1X8Mco7rElLk5HrfxBmOkzc+rJk2IGubMXLsGBkq5OT/9b5EvJ6xuLVuaI e8mA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=XBYFciOw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b185-20020a6334c2000000b0055392732f62si11865285pga.495.2023.07.17.05.58.01; Mon, 17 Jul 2023 05:58:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=XBYFciOw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230440AbjGQMws (ORCPT + 99 others); Mon, 17 Jul 2023 08:52:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231129AbjGQMwp (ORCPT ); Mon, 17 Jul 2023 08:52:45 -0400 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C56B10EB; Mon, 17 Jul 2023 05:52:44 -0700 (PDT) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 36H5To5W020411; Mon, 17 Jul 2023 05:52:34 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=B0B2UkwrlR8/ITllxIICBikh3e+ZFBoBhtiHMBEoz5w=; b=XBYFciOwwYwVH3Wljb6uNE1I1e57LhewhHAqmBM6vLZbvQmo1wHpC+CA8t/VLSGsyD/p UUM5F6vVl5SEo4Gp8LFmKAYWumgonN5+u/KIXuEFbnqNV1qi4txQYS2TqpJAK4HDwhMe X1Oq/bG8wju/HvH9hP+SHTi1ju0a2+WtFPSuwQjdo0QPR7zvHHcexO05VIsdcinG9a+T IgT1z+jU7TByKfMW8jq6xegkictXYIlXqOqK3Xe5JnRqgYFDfoTgpwBqlqe+kRuRIv+Y zFpgA+ZAeq2OtW32MQ73Y+rBkvtwosxvphUToPQDsJILC8zM9lPMVR+lvCAJw+8gXMCS Uw== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3rvyhx18m9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 17 Jul 2023 05:52:33 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Mon, 17 Jul 2023 05:52:32 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Mon, 17 Jul 2023 05:52:32 -0700 Received: from localhost.localdomain (unknown [10.110.150.250]) by maili.marvell.com (Postfix) with ESMTP id 063983F70A4; Mon, 17 Jul 2023 05:52:32 -0700 (PDT) From: Piyush Malgujar To: , , , , , , , , , CC: , , Dhananjay Kangude , Piyush Malgujar Subject: [PATCH v4 2/6] mmc: sdhci-cadence: Restructure the code Date: Mon, 17 Jul 2023 05:51:42 -0700 Message-ID: <20230717125146.16791-3-pmalgujar@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230717125146.16791-1-pmalgujar@marvell.com> References: <20230717125146.16791-1-pmalgujar@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: 1PVt1DBObmhf4uSzEEYF63fg_obyPcr5 X-Proofpoint-ORIG-GUID: 1PVt1DBObmhf4uSzEEYF63fg_obyPcr5 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-07-17_10,2023-07-13_01,2023-05-22_02 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771672641050977057 X-GMAIL-MSGID: 1771672641050977057 From: Dhananjay Kangude Restructured the code, added controller version specific init for SD4 operations with no change to existing functionality. Signed-off-by: Dhananjay Kangude Co-developed-by: Jayanthi Annadurai Signed-off-by: Jayanthi Annadurai Signed-off-by: Piyush Malgujar --- drivers/mmc/host/sdhci-cadence.c | 76 ++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index 9bb38281bcb244b0be91ef579046c40de7a06e1f..98fe752bcf27a71607623f3cb1c36f1a16d688a4 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c @@ -60,11 +60,17 @@ */ #define SDHCI_CDNS_MAX_TUNING_LOOP 40 +struct sdhci_cdns_priv; + struct sdhci_cdns_sd4_phy_param { u8 addr; u8 data; }; +struct sdhci_cdns_sd4_phy { + unsigned int nr_phy_params; + struct sdhci_cdns_sd4_phy_param phy_params[]; +}; struct sdhci_cdns_priv { void __iomem *hrs_addr; void __iomem *ctl_addr; /* write control */ @@ -72,8 +78,8 @@ struct sdhci_cdns_priv { bool enhanced_strobe; void (*priv_writel)(struct sdhci_cdns_priv *priv, u32 val, void __iomem *reg); struct reset_control *rst_hw; - unsigned int nr_phy_params; - struct sdhci_cdns_sd4_phy_param phy_params[]; + const struct sdhci_cdns_drv_data *cdns_data; + void *phy; }; struct sdhci_cdns_sd4_phy_cfg { @@ -83,6 +89,8 @@ struct sdhci_cdns_sd4_phy_cfg { struct sdhci_cdns_drv_data { int (*init)(struct platform_device *pdev); + int (*phy_init)(struct sdhci_cdns_priv *priv); + int (*phy_probe)(struct platform_device *pdev, struct sdhci_cdns_priv *priv); const struct sdhci_pltfm_data pltfm_data; }; @@ -151,9 +159,9 @@ static unsigned int sdhci_cdns_sd4_phy_param_count(struct device_node *np) } static void sdhci_cdns_sd4_phy_param_parse(struct device_node *np, - struct sdhci_cdns_priv *priv) + struct sdhci_cdns_sd4_phy *phy) { - struct sdhci_cdns_sd4_phy_param *p = priv->phy_params; + struct sdhci_cdns_sd4_phy_param *p = phy->phy_params; u32 val; int ret, i; @@ -172,10 +180,11 @@ static void sdhci_cdns_sd4_phy_param_parse(struct device_node *np, static int sdhci_cdns_sd4_phy_init(struct sdhci_cdns_priv *priv) { int ret, i; + struct sdhci_cdns_sd4_phy *phy = priv->phy; - for (i = 0; i < priv->nr_phy_params; i++) { - ret = sdhci_cdns_sd4_write_phy_reg(priv, priv->phy_params[i].addr, - priv->phy_params[i].data); + for (i = 0; i < phy->nr_phy_params; i++) { + ret = sdhci_cdns_sd4_write_phy_reg(priv, phy->phy_params[i].addr, + phy->phy_params[i].data); if (ret) return ret; } @@ -218,6 +227,27 @@ static u32 sdhci_cdns_get_emmc_mode(struct sdhci_cdns_priv *priv) return FIELD_GET(SDHCI_CDNS_HRS06_MODE, tmp); } +static int sdhci_cdns_sd4_phy_probe(struct platform_device *pdev, + struct sdhci_cdns_priv *priv) +{ + unsigned int nr_phy_params; + struct sdhci_cdns_sd4_phy *phy; + struct device *dev = &pdev->dev; + + nr_phy_params = sdhci_cdns_sd4_phy_param_count(dev->of_node); + phy = devm_kzalloc(dev, struct_size(phy, phy_params, nr_phy_params), + GFP_KERNEL); + if (!phy) + return -ENOMEM; + + phy->nr_phy_params = nr_phy_params; + + sdhci_cdns_sd4_phy_param_parse(dev->of_node, phy); + priv->phy = phy; + + return 0; +} + static int sdhci_cdns_sd4_set_tune_val(struct sdhci_host *host, unsigned int val) { struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); @@ -420,6 +450,8 @@ static const struct sdhci_ops sdhci_cdns_sd4_ops = { }; static const struct sdhci_cdns_drv_data sdhci_cdns_uniphier_drv_data = { + .phy_init = sdhci_cdns_sd4_phy_init, + .phy_probe = sdhci_cdns_sd4_phy_probe, .pltfm_data = { .ops = &sdhci_cdns_sd4_ops, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, @@ -428,12 +460,16 @@ static const struct sdhci_cdns_drv_data sdhci_cdns_uniphier_drv_data = { static const struct sdhci_cdns_drv_data sdhci_elba_drv_data = { .init = elba_drv_init, + .phy_init = sdhci_cdns_sd4_phy_init, + .phy_probe = sdhci_cdns_sd4_phy_probe, .pltfm_data = { .ops = &sdhci_elba_ops, }, }; static const struct sdhci_cdns_drv_data sdhci_cdns_sd4_drv_data = { + .phy_init = sdhci_cdns_sd4_phy_init, + .phy_probe = sdhci_cdns_sd4_phy_probe, .pltfm_data = { .ops = &sdhci_cdns_sd4_ops, }, @@ -482,7 +518,6 @@ static int sdhci_cdns_probe(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host; struct sdhci_cdns_priv *priv; struct clk *clk; - unsigned int nr_phy_params; int ret; struct device *dev = &pdev->dev; static const u16 version = SDHCI_SPEC_400 << SDHCI_SPEC_VER_SHIFT; @@ -496,12 +531,12 @@ static int sdhci_cdns_probe(struct platform_device *pdev) return ret; data = of_device_get_match_data(dev); - if (!data) - data = &sdhci_cdns_sd4_drv_data; + if (!data) { + ret = -EINVAL; + goto disable_clk; + } - nr_phy_params = sdhci_cdns_sd4_phy_param_count(dev->of_node); - host = sdhci_pltfm_init(pdev, &data->pltfm_data, - struct_size(priv, phy_params, nr_phy_params)); + host = sdhci_pltfm_init(pdev, &data->pltfm_data, sizeof(*priv)); if (IS_ERR(host)) { ret = PTR_ERR(host); goto disable_clk; @@ -511,10 +546,10 @@ static int sdhci_cdns_probe(struct platform_device *pdev) pltfm_host->clk = clk; priv = sdhci_pltfm_priv(pltfm_host); - priv->nr_phy_params = nr_phy_params; priv->hrs_addr = host->ioaddr; priv->enhanced_strobe = false; priv->priv_writel = cdns_writel; + priv->cdns_data = data; host->ioaddr += SDHCI_CDNS_SRS_BASE; host->mmc_host_ops.hs400_enhanced_strobe = sdhci_cdns_hs400_enhanced_strobe; @@ -532,9 +567,11 @@ static int sdhci_cdns_probe(struct platform_device *pdev) if (ret) goto free; - sdhci_cdns_sd4_phy_param_parse(dev->of_node, priv); + ret = data->phy_probe(pdev, priv); + if (ret) + goto free; - ret = sdhci_cdns_sd4_phy_init(priv); + ret = priv->cdns_data->phy_init(priv); if (ret) goto free; @@ -574,7 +611,7 @@ static int sdhci_cdns_resume(struct device *dev) if (ret) return ret; - ret = sdhci_cdns_sd4_phy_init(priv); + ret = priv->cdns_data->phy_init(priv); if (ret) goto disable_clk; @@ -604,7 +641,10 @@ static const struct of_device_id sdhci_cdns_match[] = { .compatible = "amd,pensando-elba-sd4hc", .data = &sdhci_elba_drv_data, }, - { .compatible = "cdns,sd4hc" }, + { + .compatible = "cdns,sd4hc", + .data = &sdhci_cdns_sd4_drv_data, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sdhci_cdns_match); From patchwork Mon Jul 17 12:51:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Piyush Malgujar X-Patchwork-Id: 121358 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp1143349vqt; Mon, 17 Jul 2023 07:21:49 -0700 (PDT) X-Google-Smtp-Source: APBJJlGSY52UJvSRz87bEIVsdqL0AcDkQ4pglg8GjUjzjLEmI0taVvFVi7TaNailtEG5plNfWv/L X-Received: by 2002:a17:903:1205:b0:1b3:b998:8007 with SMTP id l5-20020a170903120500b001b3b9988007mr13372681plh.55.1689603709556; Mon, 17 Jul 2023 07:21:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689603709; cv=none; d=google.com; s=arc-20160816; b=kR+3Qr5sqkWvARw6UiOp2eRmErqwQb9j1p0k5uv7h6zAWEyK3zjkXfbdNfDP+Vp1a2 u4INelUINMk/XKlvRTZDg89D3IaTmYuoZhImUt5gcHmv8UhIFuF007Ns4QItJ2KuDKDR S8M8uxmaJCpc2Ukl4IfzumijXkKa7L+w4cYKpkkCB9NXo3LvMZIc2EWdEZk4rFM9QDpv YpL2k/au3KRx2uIaBXY3TDi87vB4xyzAsr08c4kTDu+9aFWfXXBCeNhfuluAEr75sxRL IRFGfdkr/Tw5K3wIiAKRhqFpB6Y3400VNxA8R/DuBu6syz3ZtyS2O5M6QDj1oXiMGkgi VmBg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ebvd6wXhSGA7KjMoJYUkJGAQQa1tI876HAPSHTVIukM=; fh=USvMBNx43J86pnR+f1+ON+JulYM2jLfcJbvJ6gv/0aA=; b=a/4VR4dPUBRlP6h1cdsijOi9NJD0hG+M3dQu5AAV21CPnLpw8tj7/YsJj4eHtQMr39 DW/Vlaj56kmMIQyFD87KTQvucaotmgCxhJJPrG0pJFQzfc7qy7OwNgPseXlo6HllpFaz /xoVpPL4s7UhT/WohV07KPIUjVTvUYVgmNe5r0iKaic9GW0JkRAz7rAc6F34lMhnjHjj A6fjprqDi7Uc6XahMGPmRQ1xd/RAIrQuGXsB7t/uTy0aXDDowZDljH+No+Gyb+C/XSgK rtokHktEFGJavKQ816/1HSJZasQb8Edc7FtuxgC/pjoia38t0CovsiZLX+uFvKCmPe7M lMFg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=hRatLWOa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j4-20020a170903028400b001b8ae69289dsi11862614plr.539.2023.07.17.07.21.36; Mon, 17 Jul 2023 07:21:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=hRatLWOa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229731AbjGQMxF (ORCPT + 99 others); Mon, 17 Jul 2023 08:53:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229790AbjGQMxC (ORCPT ); Mon, 17 Jul 2023 08:53:02 -0400 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5352C1B0; Mon, 17 Jul 2023 05:52:54 -0700 (PDT) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 36H5TqC3020447; Mon, 17 Jul 2023 05:52:41 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=ebvd6wXhSGA7KjMoJYUkJGAQQa1tI876HAPSHTVIukM=; b=hRatLWOaiwuQnzRd9hBchG7yP5yauB4EKbhkDLvz1M51oBLhFxvtI6601sIUG+yN8oLG Lo1gOErxmWB/rv6N86QrgzdA/qE3Facui3IQb6v8JgdyaKtTLuoAmGz3Pw0PJ+NMj7JS 0mxA/z2KOgRFNEA7xH7tNGJ+X+ajqKQ6Hmt6RstIoxY8IOU2K7mTW0UE0hL2ZtZkMgtz 2dd6SJJZyJUTo6EKs9TvJNh5AUSmWBgYJPykaAx0qPRqqXamgsNiH4cQ1gSUCV6hd1U5 QrEPZXjguLAFjY4xm1UZbiIaQAjjp+P6YQtJjO6lobcADlS4NN5mJc9nZm2xQzfFlu+q WQ== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3rvyhx18mn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 17 Jul 2023 05:52:40 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Mon, 17 Jul 2023 05:52:39 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Mon, 17 Jul 2023 05:52:39 -0700 Received: from localhost.localdomain (unknown [10.110.150.250]) by maili.marvell.com (Postfix) with ESMTP id C44A33F70A4; Mon, 17 Jul 2023 05:52:38 -0700 (PDT) From: Piyush Malgujar To: , , , , , , , , , CC: , , Dhananjay Kangude , Piyush Malgujar Subject: [PATCH v4 3/6] mmc: sdhci-cadence: SD6 controller support Date: Mon, 17 Jul 2023 05:51:43 -0700 Message-ID: <20230717125146.16791-4-pmalgujar@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230717125146.16791-1-pmalgujar@marvell.com> References: <20230717125146.16791-1-pmalgujar@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: bPB5VQkUDtzevcx6Cj4xVEQQm2mwuLkD X-Proofpoint-ORIG-GUID: bPB5VQkUDtzevcx6Cj4xVEQQm2mwuLkD X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-07-17_10,2023-07-13_01,2023-05-22_02 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771673744160255978 X-GMAIL-MSGID: 1771677899397706003 From: Dhananjay Kangude Add support for SD6 controller for Marvell CN10k SoCs and related ops along with support for HS400 and HS400ES emmc modes. Updated HS200 tuning values and support to read tune configuration from FDT and support to configure and read host side drive strength, slew from device tree. Signed-off-by: Dhananjay Kangude Co-developed-by: Jayanthi Annadurai Signed-off-by: Jayanthi Annadurai Signed-off-by: Piyush Malgujar --- drivers/mmc/host/sdhci-cadence.c | 1256 +++++++++++++++++++++++++++++- 1 file changed, 1253 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index 98fe752bcf27a71607623f3cb1c36f1a16d688a4..8bcf585185053b0afaff2625d62316cec1824fa3 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c @@ -16,8 +16,20 @@ #include "sdhci-pltfm.h" +#define SDMCLK_MAX_FREQ 200000000 + +#define DEFAULT_CMD_DELAY 16 +#define SDHCI_CDNS_TUNE_START 16 +#define SDHCI_CDNS_TUNE_STEP 6 +#define SDHCI_CDNS_TUNE_ITERATIONS 40 + +#define SDHCI_CDNS_HRS00 0x00 +#define SDHCI_CDNS_HRS00_SWR BIT(0) + +#define SDHCI_CDNS_HRS02 0x08 /* PHY access port */ +#define SDHCI_CDNS_HRS04 0x10 /* PHY access port */ + /* SD 4.0 Controller HRS - Host Register Set (specific to Cadence) */ -#define SDHCI_CDNS_HRS04 0x10 /* PHY access port */ #define SDHCI_CDNS_SD4_HRS04_ACK BIT(26) #define SDHCI_CDNS_SD4_HRS04_RD BIT(25) #define SDHCI_CDNS_SD4_HRS04_WR BIT(24) @@ -30,12 +42,89 @@ #define SDHCI_CDNS_HRS06_TUNE GENMASK(13, 8) #define SDHCI_CDNS_HRS06_MODE GENMASK(2, 0) #define SDHCI_CDNS_HRS06_MODE_SD 0x0 +#define SDHCI_CDNS_HRS06_MODE_LEGACY 0x1 #define SDHCI_CDNS_HRS06_MODE_MMC_SDR 0x2 #define SDHCI_CDNS_HRS06_MODE_MMC_DDR 0x3 #define SDHCI_CDNS_HRS06_MODE_MMC_HS200 0x4 #define SDHCI_CDNS_HRS06_MODE_MMC_HS400 0x5 #define SDHCI_CDNS_HRS06_MODE_MMC_HS400ES 0x6 +/* SD 6.0 Controller HRS - Host Register Set (Specific to Cadence) */ +#define SDHCI_CDNS_SD6_HRS04_ADDR GENMASK(15, 0) + +#define SDHCI_CDNS_HRS05 0x14 + +#define SDHCI_CDNS_HRS07 0x1C +#define SDHCI_CDNS_HRS07_RW_COMPENSATE GENMASK(20, 16) +#define SDHCI_CDNS_HRS07_IDELAY_VAL GENMASK(4, 0) + +#define SDHCI_CDNS_HRS09 0x24 +#define SDHCI_CDNS_HRS09_RDDATA_EN BIT(16) +#define SDHCI_CDNS_HRS09_RDCMD_EN BIT(15) +#define SDHCI_CDNS_HRS09_EXTENDED_WR_MODE BIT(3) +#define SDHCI_CDNS_HRS09_EXTENDED_RD_MODE BIT(2) +#define SDHCI_CDNS_HRS09_PHY_INIT_COMPLETE BIT(1) +#define SDHCI_CDNS_HRS09_PHY_SW_RESET BIT(0) + +#define SDHCI_CDNS_HRS10 0x28 +#define SDHCI_CDNS_HRS10_HCSDCLKADJ GENMASK(19, 16) + +#define SDHCI_CDNS_HRS11 0x2c +/*Reset related*/ +#define SDHCI_CDNS_SRS11_SW_RESET_ALL BIT(24) +#define SDHCI_CDNS_SRS11_SW_RESET_CMD BIT(25) +#define SDHCI_CDNS_SRS11_SW_RESET_DAT BIT(26) + +#define SDHCI_CDNS_HRS16 0x40 +#define SDHCI_CDNS_HRS16_WRDATA1_SDCLK_DLY GENMASK(31, 28) +#define SDHCI_CDNS_HRS16_WRDATA0_SDCLK_DLY GENMASK(27, 24) +#define SDHCI_CDNS_HRS16_WRCMD1_SDCLK_DLY GENMASK(23, 20) +#define SDHCI_CDNS_HRS16_WRCMD0_SDCLK_DLY GENMASK(19, 16) +#define SDHCI_CDNS_HRS16_WRDATA1_DLY GENMASK(15, 12) +#define SDHCI_CDNS_HRS16_WRDATA0_DLY GENMASK(11, 8) +#define SDHCI_CDNS_HRS16_WRCMD1_DLY GENMASK(7, 4) +#define SDHCI_CDNS_HRS16_WRCMD0_DLY GENMASK(3, 0) + +/* PHY registers for SD6 controller */ +#define SDHCI_CDNS_SD6_PHY_DQ_TIMING 0x2000 +#define SDHCI_CDNS_SD6_PHY_DQ_TIMING_IO_MASK_ALWAYS_ON BIT(31) +#define SDHCI_CDNS_SD6_PHY_DQ_TIMING_IO_MASK_END GENMASK(29, 27) +#define SDHCI_CDNS_SD6_PHY_DQ_TIMING_IO_MASK_START GENMASK(26, 24) +#define SDHCI_CDNS_SD6_PHY_DQ_TIMING_DATA_SELECT_OE_END GENMASK(2, 0) + +#define SDHCI_CDNS_SD6_PHY_DQS_TIMING 0x2004 +#define SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_EXT_LPBK_DQS BIT(22) +#define SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_LPBK_DQS BIT(21) +#define SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_PHONY_DQS BIT(20) +#define SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_PHONY_DQS_CMD BIT(19) + +#define SDHCI_CDNS_SD6_PHY_GATE_LPBK 0x2008 +#define SDHCI_CDNS_SD6_PHY_GATE_LPBK_SYNC_METHOD BIT(31) +#define SDHCI_CDNS_SD6_PHY_GATE_LPBK_SW_HALF_CYCLE_SHIFT BIT(28) +#define SDHCI_CDNS_SD6_PHY_GATE_LPBK_RD_DEL_SEL GENMASK(24, 19) +#define SDHCI_CDNS_SD6_PHY_GATE_LPBK_GATE_CFG_ALWAYS_ON BIT(6) + +#define SDHCI_CDNS_SD6_PHY_DLL_MASTER 0x200C +#define SDHCI_CDNS_SD6_PHY_DLL_MASTER_BYPASS_MODE BIT(23) +#define SDHCI_CDNS_SD6_PHY_DLL_MASTER_PHASE_DETECT_SEL GENMASK(22, 20) +#define SDHCI_CDNS_SD6_PHY_DLL_MASTER_DLL_LOCK_NUM GENMASK(18, 16) +#define SDHCI_CDNS_SD6_PHY_DLL_MASTER_DLL_START_POINT GENMASK(7, 0) + +#define SDHCI_CDNS_SD6_PHY_DLL_SLAVE 0x2010 +#define SDHCI_CDNS_SD6_PHY_DLL_SLAVE_READ_DQS_CMD_DELAY GENMASK(31, 24) +#define SDHCI_CDNS_SD6_PHY_DLL_SLAVE_CLK_WRDQS_DELAY GENMASK(23, 16) +#define SDHCI_CDNS_SD6_PHY_DLL_SLAVE_CLK_WR_DELAY GENMASK(15, 8) +#define SDHCI_CDNS_SD6_PHY_DLL_SLAVE_READ_DQS_DELAY GENMASK(7, 0) + +#define SDHCI_CDNS_SD6_PHY_CTRL 0x2080 +#define SDHCI_CDNS_SD6_PHY_CTRL_PHONY_DQS_TIMING GENMASK(9, 4) + +#define SDHCI_CDNS_SD6_PHY_GPIO_CTRL0 0x2088 +#define SDHCI_CDNS_SD6_PHY_GPIO_CTRL0_DRV GENMASK(6, 5) +#define SDHCI_CDNS_SD6_PHY_GPIO_CTRL0_DRV_OVR_EN BIT(4) +#define SDHCI_CDNS_SD6_PHY_GPIO_CTRL0_SLEW GENMASK(2, 1) +#define SDHCI_CDNS_SD6_PHY_GPIO_CTRL0_SLEW_OVR_EN BIT(0) + /* SRS - Slot Register Set (SDHCI-compatible) */ #define SDHCI_CDNS_SRS_BASE 0x200 @@ -60,6 +149,10 @@ */ #define SDHCI_CDNS_MAX_TUNING_LOOP 40 +static int tune_val_start = SDHCI_CDNS_TUNE_START; +static int tune_val_step = SDHCI_CDNS_TUNE_STEP; +static int max_tune_iter = SDHCI_CDNS_TUNE_ITERATIONS; + struct sdhci_cdns_priv; struct sdhci_cdns_sd4_phy_param { @@ -108,6 +201,558 @@ static const struct sdhci_cdns_sd4_phy_cfg sdhci_cdns_sd4_phy_cfgs[] = { { "cdns,phy-dll-delay-strobe", SDHCI_CDNS_PHY_DLY_STROBE, }, }; +enum sdhci_cdns_sd6_phy_lock_mode { + SDHCI_CDNS_SD6_PHY_LOCK_MODE_FULL_CLK = 0, + SDHCI_CDNS_SD6_PHY_LOCK_MODE_HALF_CLK = 2, + SDHCI_CDNS_SD6_PHY_LOCK_MODE_SATURATION = 3, +}; + +struct sdhci_cdns_sd6_phy_timings { + u32 t_cmd_output_min; + u32 t_cmd_output_max; + u32 t_dat_output_min; + u32 t_dat_output_max; + u32 t_cmd_input_min; + u32 t_cmd_input_max; + u32 t_dat_input_min; + u32 t_dat_input_max; + u32 t_sdclk_min; + u32 t_sdclk_max; +}; + +struct sdhci_cdns_sd6_phy_delays { + u32 phy_sdclk_delay; + u32 phy_cmd_o_delay; + u32 phy_dat_o_delay; + u32 iocell_input_delay; + u32 iocell_output_delay; + u32 delay_element_org; + u32 delay_element; +}; + +struct sdhci_cdns_sd6_phy_settings { + /* SDHCI_CDNS_SD6_PHY_DLL_SLAVE */ + u32 cp_read_dqs_cmd_delay; + u32 cp_read_dqs_delay; + u32 cp_clk_wr_delay; + u32 cp_clk_wrdqs_delay; + + /* SDHCI_CDNS_SD6_PHY_DLL_MASTER */ + u32 cp_dll_bypass_mode; + u32 cp_dll_start_point; + + /* SDHCI_CDNS_SD6_PHY_DLL_OBS_REG0 */ + u32 cp_dll_locked_mode; + + /* SDHCI_CDNS_SD6_PHY_GATE_LPBK */ + u32 cp_gate_cfg_always_on; + u32 cp_sync_method; + u32 cp_rd_del_sel; + u32 cp_sw_half_cycle_shift; + u32 cp_underrun_suppress; + + /* SDHCI_CDNS_SD6_PHY_DQ_TIMING */ + u32 cp_io_mask_always_on; + u32 cp_io_mask_end; + u32 cp_io_mask_start; + u32 cp_data_select_oe_end; + + /* SDHCI_CDNS_SD6_PHY_DQS_TIMING */ + u32 cp_use_ext_lpbk_dqs; + u32 cp_use_lpbk_dqs; + u8 cp_use_phony_dqs; + u8 cp_use_phony_dqs_cmd; + + /* HRS 09 */ + u8 sdhc_extended_rd_mode; + u8 sdhc_extended_wr_mode; + u32 sdhc_rdcmd_en; + u32 sdhc_rddata_en; + + /* HRS10 */ + u32 sdhc_hcsdclkadj; + + /* HRS 07 */ + u32 sdhc_idelay_val; + u32 sdhc_rw_compensate; + + /* SRS 11 */ + u32 sdhc_sdcfsh; + u32 sdhc_sdcfsl; + + /* HRS 16 */ + u32 sdhc_wrcmd0_dly; + u32 sdhc_wrcmd0_sdclk_dly; + u32 sdhc_wrcmd1_dly; + u32 sdhc_wrcmd1_sdclk_dly; + u32 sdhc_wrdata0_dly; + u32 sdhc_wrdata0_sdclk_dly; + u32 sdhc_wrdata1_dly; + u32 sdhc_wrdata1_sdclk_dly; + + u32 hs200_tune_val; + u32 drive; + u32 slew; +}; + +struct sdhci_cdns_sd6_phy_intermediate_results { + u32 t_sdmclk_calc; + u32 dll_max_value; +}; + +struct sdhci_cdns_sd6_phy { + struct sdhci_cdns_sd6_phy_timings t; + struct sdhci_cdns_sd6_phy_delays d; + u32 t_sdmclk; + struct sdhci_cdns_sd6_phy_settings settings; + struct sdhci_cdns_sd6_phy_intermediate_results vars; + bool ddr; + bool tune_cmd; + bool tune_dat; + bool strobe_cmd; + bool strobe_dat; + int mode; + int t_sdclk; +}; + +static void init_hs(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 2000, .t_cmd_output_max = t_sdclk - 6000, + .t_dat_output_min = 2000, .t_dat_output_max = t_sdclk - 6000, + .t_cmd_input_min = 14000, .t_cmd_input_max = t_sdclk + 2500, + .t_dat_input_min = 14000, .t_dat_input_max = t_sdclk + 2500, + .t_sdclk_min = 1000000 / 50, .t_sdclk_max = 1000000 / 0.4 + }; +} + +static void init_uhs_sdr12(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 800, .t_cmd_output_max = t_sdclk - 3000, + .t_dat_output_min = 800, .t_dat_output_max = t_sdclk - 3000, + .t_cmd_input_min = 14000, .t_cmd_input_max = t_sdclk + 1500, + .t_dat_input_min = 14000, .t_dat_input_max = t_sdclk + 1500, + .t_sdclk_min = 1000000 / 25, .t_sdclk_max = 1000000 / 0.4 + }; +} + +static void init_uhs_sdr25(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 800, .t_cmd_output_max = t_sdclk - 3000, + .t_dat_output_min = 800, .t_dat_output_max = t_sdclk - 3000, + .t_cmd_input_min = 14000, .t_cmd_input_max = t_sdclk + 1500, + .t_dat_input_min = 14000, .t_dat_input_max = t_sdclk + 1500, + .t_sdclk_min = 1000000 / 50, .t_sdclk_max = 1000000 / 0.4 + }; +} + +static void init_uhs_sdr50(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 800, .t_cmd_output_max = t_sdclk - 3000, + .t_dat_output_min = 800, .t_dat_output_max = t_sdclk - 3000, + .t_cmd_input_min = 7500, .t_cmd_input_max = t_sdclk + 1500, + .t_dat_input_min = 7500, .t_dat_input_max = t_sdclk + 1500, + .t_sdclk_min = 1000000 / 100, .t_sdclk_max = 1000000 / 0.4 + }; +} + +static void init_uhs_sdr104(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 800, .t_cmd_output_max = t_sdclk - 1400, + .t_dat_output_min = 800, .t_dat_output_max = t_sdclk - 1400, + .t_cmd_input_min = 1000, .t_cmd_input_max = t_sdclk + 1000, + .t_dat_input_min = 1000, .t_dat_input_max = t_sdclk + 1000, + .t_sdclk_min = 1000000 / 200, .t_sdclk_max = 1000000 / 100 + }; +} + +static void init_uhs_ddr50(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 800, .t_cmd_output_max = t_sdclk - 3000, + .t_dat_output_min = 800, .t_dat_output_max = t_sdclk - 3000, + .t_cmd_input_min = 13700, .t_cmd_input_max = t_sdclk + 1500, + .t_dat_input_min = 7000, .t_dat_input_max = t_sdclk + 1500, + .t_sdclk_min = 1000000 / 50, .t_sdclk_max = 1000000 / 0.4 + }; +} + +static void init_emmc_legacy(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 3000, .t_cmd_output_max = t_sdclk - 3000, + .t_dat_output_min = 3000, .t_dat_output_max = t_sdclk - 3000, + .t_cmd_input_min = 11700, .t_cmd_input_max = t_sdclk + 8300, + .t_dat_input_min = 11700, .t_dat_input_max = t_sdclk + 8300, + .t_sdclk_min = 1000000 / 25, .t_sdclk_max = 1000000 / 0.4 + }; +} + +static void init_emmc_sdr(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 3000, .t_cmd_output_max = t_sdclk - 3000, + .t_dat_output_min = 3000, .t_dat_output_max = t_sdclk - 3000, + .t_cmd_input_min = 13700, .t_cmd_input_max = t_sdclk + 2500, + .t_dat_input_min = 13700, .t_dat_input_max = t_sdclk + 2500, + .t_sdclk_min = 1000000 / 50, .t_sdclk_max = 1000000 / 0.4 + }; +} + +static void init_emmc_ddr(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 3000, .t_cmd_output_max = t_sdclk - 3000, + .t_dat_output_min = 2500, .t_dat_output_max = t_sdclk - 2500, + .t_cmd_input_min = 13700, .t_cmd_input_max = t_sdclk + 2500, + .t_dat_input_min = 7000, .t_dat_input_max = t_sdclk + 1500, + .t_sdclk_min = 1000000 / 50, .t_sdclk_max = 1000000 / 0.4 + }; +} + +static void init_emmc_hs200(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 800, .t_cmd_output_max = t_sdclk - 1400, + .t_dat_output_min = 800, .t_dat_output_max = t_sdclk - 1400, + .t_cmd_input_min = 1000, .t_cmd_input_max = t_sdclk + 1000, + .t_dat_input_min = 1000, .t_dat_input_max = t_sdclk + 1000, + .t_sdclk_min = 1000000 / 200, .t_sdclk_max = 1000000 / 100 + }; +} + +/* HS400 and HS400ES */ +static void init_emmc_hs400(struct sdhci_cdns_sd6_phy_timings *t, int t_sdclk) +{ + *t = (struct sdhci_cdns_sd6_phy_timings){ + .t_cmd_output_min = 800, .t_cmd_output_max = t_sdclk - 1400, + .t_dat_output_min = 400, .t_dat_output_max = t_sdclk - 400, + .t_cmd_input_min = 1000, .t_cmd_input_max = t_sdclk + 1000, + .t_dat_input_min = 1000, .t_dat_input_max = t_sdclk + 1000, + .t_sdclk_min = 1000000 / 200, .t_sdclk_max = 1000000 / 100 + }; +} + +static void (*init_timings[])(struct sdhci_cdns_sd6_phy_timings*, int) = { + &init_hs, &init_emmc_legacy, &init_emmc_sdr, + &init_emmc_ddr, &init_emmc_hs200, &init_emmc_hs400, + &init_uhs_sdr12, &init_uhs_sdr25, &init_uhs_sdr50, + &init_uhs_sdr104, &init_uhs_ddr50 +}; + +static u32 read_dqs_cmd_delay, clk_wrdqs_delay, clk_wr_delay, read_dqs_delay; + +static u32 sdhci_cdns_sd6_get_mode(struct sdhci_host *host, unsigned int timing); + +static int sdhci_cdns_sd6_phy_lock_dll(struct sdhci_cdns_sd6_phy *phy) +{ + u32 delay_element = phy->d.delay_element_org; + u32 delay_elements_in_sdmclk; + enum sdhci_cdns_sd6_phy_lock_mode mode; + + delay_elements_in_sdmclk = DIV_ROUND_UP(phy->t_sdmclk, delay_element); + if (delay_elements_in_sdmclk > 256) { + delay_element *= 2; + delay_elements_in_sdmclk = DIV_ROUND_UP(phy->t_sdmclk, + delay_element); + + if (delay_elements_in_sdmclk > 256) + return -1; + + mode = SDHCI_CDNS_SD6_PHY_LOCK_MODE_HALF_CLK; + phy->vars.dll_max_value = 127; + } else { + mode = SDHCI_CDNS_SD6_PHY_LOCK_MODE_FULL_CLK; + phy->vars.dll_max_value = 255; + } + + phy->vars.t_sdmclk_calc = delay_element * delay_elements_in_sdmclk; + phy->d.delay_element = delay_element; + phy->settings.cp_dll_locked_mode = mode; + phy->settings.cp_dll_bypass_mode = 0; + + return 0; +} + +static void sdhci_cdns_sd6_phy_dll_bypass(struct sdhci_cdns_sd6_phy *phy) +{ + phy->vars.dll_max_value = 256; + phy->settings.cp_dll_bypass_mode = 1; + phy->settings.cp_dll_locked_mode = + SDHCI_CDNS_SD6_PHY_LOCK_MODE_SATURATION; +} + +static void sdhci_cdns_sd6_phy_configure_dll(struct sdhci_cdns_sd6_phy *phy) +{ + if (phy->settings.sdhc_extended_wr_mode == 0) { + if (sdhci_cdns_sd6_phy_lock_dll(phy) == 0) + return; + } + sdhci_cdns_sd6_phy_dll_bypass(phy); +} + +static void sdhci_cdns_sd6_phy_calc_out(struct sdhci_cdns_sd6_phy *phy, + bool cmd_not_dat) +{ + u32 wr0_dly = 0, wr1_dly = 0, output_min, output_max, phy_o_delay, + clk_wr_delay = 0, wr0_sdclk_dly = 0, wr1_sdclk_dly = 0; + bool data_ddr = phy->ddr && !cmd_not_dat; + int t; + + if (cmd_not_dat) { + output_min = phy->t.t_cmd_output_min; + output_max = phy->t.t_cmd_output_max; + phy_o_delay = phy->d.phy_cmd_o_delay; + } else { + output_min = phy->t.t_dat_output_min; + output_max = phy->t.t_dat_output_max; + phy_o_delay = phy->d.phy_dat_o_delay; + } + + if (data_ddr) { + wr0_sdclk_dly = 1; + wr1_sdclk_dly = 1; + } + + t = phy_o_delay - phy->d.phy_sdclk_delay - output_min; + if (t < 0 && phy->settings.sdhc_extended_wr_mode == 1) { + u32 n_half_cycle = DIV_ROUND_UP(-t * 2, phy->t_sdmclk); + + wr0_dly = (n_half_cycle + 1) / 2; + if (data_ddr) + wr1_dly = (n_half_cycle + 1) / 2; + else + wr1_dly = (n_half_cycle + 1) % 2 + wr0_dly - 1; + } + + if (phy->settings.sdhc_extended_wr_mode == 0) { + u32 out_hold, out_setup, out_hold_margin; + u32 n; + + if (!data_ddr) + wr0_dly = 1; + + out_setup = output_max; + out_hold = output_min; + out_hold_margin = DIV_ROUND_UP(out_setup - out_hold, 4); + out_hold += out_hold_margin; + + if (phy->settings.cp_dll_bypass_mode == 0) + n = DIV_ROUND_UP(256 * out_hold, phy->vars.t_sdmclk_calc); + else + n = DIV_ROUND_UP(out_hold, phy->d.delay_element) - 1; + + if (n <= phy->vars.dll_max_value) + clk_wr_delay = n; + else + clk_wr_delay = 255; + } else { + /* sdhc_extended_wr_mode = 1 - PHY IO cell work in SDR mode */ + clk_wr_delay = 0; + } + + if (cmd_not_dat) { + phy->settings.sdhc_wrcmd0_dly = wr0_dly; + phy->settings.sdhc_wrcmd1_dly = wr1_dly; + phy->settings.cp_clk_wrdqs_delay = clk_wr_delay; + phy->settings.sdhc_wrcmd0_sdclk_dly = wr0_sdclk_dly; + phy->settings.sdhc_wrcmd1_sdclk_dly = wr1_sdclk_dly; + } else { + phy->settings.sdhc_wrdata0_dly = wr0_dly; + phy->settings.sdhc_wrdata1_dly = wr1_dly; + phy->settings.cp_clk_wr_delay = clk_wr_delay; + phy->settings.sdhc_wrdata0_sdclk_dly = wr0_sdclk_dly; + phy->settings.sdhc_wrdata1_sdclk_dly = wr1_sdclk_dly; + } +} + +static void sdhci_cdns_sd6_phy_calc_cmd_out(struct sdhci_cdns_sd6_phy *phy) +{ + sdhci_cdns_sd6_phy_calc_out(phy, true); +} + +static void sdhci_cdns_sd6_phy_calc_cmd_in(struct sdhci_cdns_sd6_phy *phy) +{ + phy->settings.cp_io_mask_end = + ((phy->d.iocell_output_delay + phy->d.iocell_input_delay) * 2) + / phy->t_sdmclk; + + if (phy->settings.cp_io_mask_end >= 8) + phy->settings.cp_io_mask_end = 7; + + if (phy->strobe_cmd && phy->settings.cp_io_mask_end > 0) + phy->settings.cp_io_mask_end--; + + if (phy->strobe_cmd) { + phy->settings.cp_use_phony_dqs_cmd = 0; + phy->settings.cp_read_dqs_cmd_delay = 64; + } else { + phy->settings.cp_use_phony_dqs_cmd = 1; + phy->settings.cp_read_dqs_cmd_delay = 0; + } + + if ((phy->mode == MMC_TIMING_MMC_HS400 && !phy->strobe_cmd) || + phy->mode == MMC_TIMING_MMC_HS200) + phy->settings.cp_read_dqs_cmd_delay = + phy->settings.hs200_tune_val; +} + +static void sdhci_cdns_sd6_phy_calc_dat_in(struct sdhci_cdns_sd6_phy *phy) +{ + u32 hcsdclkadj = 0; + + if (phy->strobe_dat) { + phy->settings.cp_use_phony_dqs = 0; + phy->settings.cp_read_dqs_delay = 64; + } else { + phy->settings.cp_use_phony_dqs = 1; + phy->settings.cp_read_dqs_delay = 0; + } + + if (phy->mode == MMC_TIMING_MMC_HS200) + phy->settings.cp_read_dqs_delay = + phy->settings.hs200_tune_val; + + if (phy->strobe_dat) { + /* dqs loopback input via IO cell */ + hcsdclkadj += phy->d.iocell_input_delay; + /* dfi_dqs_in: mem_dqs -> clean_dqs_mod; delay of hic_dll_dqs_nand2 */ + hcsdclkadj += phy->d.delay_element / 2; + /* delay line */ + hcsdclkadj += phy->t_sdclk / 2; + /* PHY FIFO write pointer */ + hcsdclkadj += phy->t_sdclk / 2 + phy->d.delay_element; + /* 1st synchronizer */ + hcsdclkadj += DIV_ROUND_UP(hcsdclkadj, phy->t_sdmclk) + * phy->t_sdmclk - hcsdclkadj; + /* + * 2nd synchronizer + PHY FIFO read pointer + PHY rddata + * + PHY rddata registered, + FIFO 1st ciu_en + */ + hcsdclkadj += 5 * phy->t_sdmclk; + /* FIFO 2st ciu_en */ + hcsdclkadj += phy->t_sdclk; + + hcsdclkadj /= phy->t_sdclk; + } else { + u32 n; + + /* rebar PHY delay */ + hcsdclkadj += 2 * phy->t_sdmclk; + /* rebar output via IO cell */ + hcsdclkadj += phy->d.iocell_output_delay; + /* dqs loopback input via IO cell */ + hcsdclkadj += phy->d.iocell_input_delay; + /* dfi_dqs_in: mem_dqs -> clean_dqs_mod delay of hic_dll_dqs_nand2 */ + hcsdclkadj += phy->d.delay_element / 2; + /* dll: one delay element between SIGI_0 and SIGO_0 */ + hcsdclkadj += phy->d.delay_element; + /* dfi_dqs_in: mem_dqs_delayed -> clk_dqs delay of hic_dll_dqs_nand2 */ + hcsdclkadj += phy->d.delay_element / 2; + /* deskew DLL: clk_dqs -> clk_dqN: one delay element */ + hcsdclkadj += phy->d.delay_element; + + if (phy->t_sdclk == phy->t_sdmclk) + n = (hcsdclkadj - 2 * phy->t_sdmclk) / phy->t_sdclk; + else + n = hcsdclkadj / phy->t_sdclk; + + /* phase shift within one t_sdclk clock cycle caused by rebar - lbk dqs delay */ + hcsdclkadj = hcsdclkadj % phy->t_sdclk; + /* PHY FIFO write pointer */ + hcsdclkadj += phy->t_sdclk / 2; + /* 1st synchronizer */ + hcsdclkadj += DIV_ROUND_UP(hcsdclkadj, phy->t_sdmclk) + * phy->t_sdmclk - hcsdclkadj; + /* + * 2nd synchronizer + PHY FIFO read pointer + PHY rddata + * + PHY rddata registered + */ + hcsdclkadj += 4 * phy->t_sdmclk; + + if ((phy->t_sdclk / phy->t_sdmclk) > 1) { + u32 tmp1, tmp2; + + tmp1 = hcsdclkadj; + tmp2 = (hcsdclkadj / phy->t_sdclk) * phy->t_sdclk + + phy->t_sdclk - phy->t_sdmclk; + if (tmp1 == tmp2) + tmp2 += phy->t_sdclk; + + /* FIFO aligns to clock cycle before ciu_en */ + hcsdclkadj += tmp2 - tmp1; + } + + /* FIFO 1st ciu_en */ + hcsdclkadj += phy->t_sdmclk; + /* FIFO 2nd ciu_en */ + hcsdclkadj += phy->t_sdclk; + + hcsdclkadj /= phy->t_sdclk; + + hcsdclkadj += n; + + if ((phy->t_sdclk / phy->t_sdmclk) >= 2) { + if (phy->mode == MMC_TIMING_UHS_DDR50 || + phy->mode == MMC_TIMING_MMC_DDR52) + hcsdclkadj -= 2; + else + hcsdclkadj -= 1; + } else if ((phy->t_sdclk / phy->t_sdmclk) == 1) { + hcsdclkadj += 2; + } + + if (phy->tune_dat) + hcsdclkadj -= 1; + } + + if (hcsdclkadj > 15) + hcsdclkadj = 15; + + phy->settings.sdhc_hcsdclkadj = hcsdclkadj; +} + +static void sdhci_cdns_sd6_phy_calc_dat_out(struct sdhci_cdns_sd6_phy *phy) +{ + sdhci_cdns_sd6_phy_calc_out(phy, false); +} + +static void sdhci_cdns_sd6_phy_calc_io(struct sdhci_cdns_sd6_phy *phy) +{ + u32 rw_compensate; + + rw_compensate = (phy->d.iocell_input_delay + phy->d.iocell_output_delay) + / phy->t_sdmclk + phy->settings.sdhc_wrdata0_dly + 5 + 3; + + phy->settings.sdhc_idelay_val = (2 * phy->d.iocell_input_delay) + / phy->t_sdmclk; + + phy->settings.cp_io_mask_start = 0; + if (phy->t_sdclk == phy->t_sdmclk && rw_compensate > 10) + phy->settings.cp_io_mask_start = 2 * (rw_compensate - 10); + + if (phy->mode == MMC_TIMING_UHS_SDR104) + phy->settings.cp_io_mask_start++; + + if (phy->t_sdclk == phy->t_sdmclk && phy->mode == MMC_TIMING_UHS_SDR50) + phy->settings.cp_io_mask_start++; + + phy->settings.sdhc_rw_compensate = rw_compensate; +} + +static void sdhci_cdns_sd6_phy_calc_settings(struct sdhci_cdns_sd6_phy *phy) +{ + sdhci_cdns_sd6_phy_calc_cmd_out(phy); + sdhci_cdns_sd6_phy_calc_cmd_in(phy); + sdhci_cdns_sd6_phy_calc_dat_out(phy); + sdhci_cdns_sd6_phy_calc_dat_in(phy); + sdhci_cdns_sd6_phy_calc_io(phy); +} + static inline void cdns_writel(struct sdhci_cdns_priv *priv, u32 val, void __iomem *reg) { @@ -188,7 +833,276 @@ static int sdhci_cdns_sd4_phy_init(struct sdhci_cdns_priv *priv) if (ret) return ret; } + return 0; +} +static u32 sdhci_cdns_sd6_read_phy_reg(struct sdhci_cdns_priv *priv, + u32 addr) +{ + writel(FIELD_PREP(SDHCI_CDNS_SD6_HRS04_ADDR, addr), + priv->hrs_addr + SDHCI_CDNS_HRS04); + return readl(priv->hrs_addr + SDHCI_CDNS_HRS05); +} + +static void sdhci_cdns_sd6_write_phy_reg(struct sdhci_cdns_priv *priv, + u32 addr, u32 data) +{ + writel(FIELD_PREP(SDHCI_CDNS_SD6_HRS04_ADDR, addr), + priv->hrs_addr + SDHCI_CDNS_HRS04); + writel(data, priv->hrs_addr + SDHCI_CDNS_HRS05); +} + +static int sdhci_cdns_sd6_dll_reset(struct sdhci_cdns_priv *priv, bool reset) +{ + u32 reg; + int ret = 0; + + reg = readl(priv->hrs_addr + SDHCI_CDNS_HRS09); + if (reset) + reg &= ~SDHCI_CDNS_HRS09_PHY_SW_RESET; + else + reg |= SDHCI_CDNS_HRS09_PHY_SW_RESET; + + writel(reg, priv->hrs_addr + SDHCI_CDNS_HRS09); + + if (!reset) + ret = readl_poll_timeout(priv->hrs_addr + SDHCI_CDNS_HRS09, + reg, + (reg & + SDHCI_CDNS_HRS09_PHY_INIT_COMPLETE), + 0, 0); + + return ret; +} + +static void sdhci_cdns_sd6_calc_phy(struct sdhci_cdns_sd6_phy *phy) +{ + if (phy->mode == MMC_TIMING_MMC_HS) { + phy->settings.cp_clk_wr_delay = 0; + phy->settings.cp_clk_wrdqs_delay = 0; + phy->settings.cp_data_select_oe_end = 1; + phy->settings.cp_dll_bypass_mode = 1; + phy->settings.cp_dll_locked_mode = 3; + phy->settings.cp_dll_start_point = 4; + phy->settings.cp_gate_cfg_always_on = 1; + phy->settings.cp_io_mask_always_on = 0; + phy->settings.cp_io_mask_end = 0; + phy->settings.cp_io_mask_start = 0; + phy->settings.cp_rd_del_sel = 52; + phy->settings.cp_read_dqs_cmd_delay = 0; + phy->settings.cp_read_dqs_delay = 0; + phy->settings.cp_sw_half_cycle_shift = 0; + phy->settings.cp_sync_method = 1; + phy->settings.cp_underrun_suppress = 1; + phy->settings.cp_use_ext_lpbk_dqs = 1; + phy->settings.cp_use_lpbk_dqs = 1; + phy->settings.cp_use_phony_dqs = 1; + phy->settings.cp_use_phony_dqs_cmd = 1; + phy->settings.sdhc_extended_rd_mode = 1; + phy->settings.sdhc_extended_wr_mode = 1; + phy->settings.sdhc_hcsdclkadj = 2; + phy->settings.sdhc_idelay_val = 0; + phy->settings.sdhc_rdcmd_en = 1; + phy->settings.sdhc_rddata_en = 1; + phy->settings.sdhc_rw_compensate = 9; + phy->settings.sdhc_sdcfsh = 0; + phy->settings.sdhc_sdcfsl = 4; + phy->settings.sdhc_wrcmd0_dly = 1; + phy->settings.sdhc_wrcmd0_sdclk_dly = 0; + phy->settings.sdhc_wrcmd1_dly = 0; + phy->settings.sdhc_wrcmd1_sdclk_dly = 0; + phy->settings.sdhc_wrdata0_dly = 1; + phy->settings.sdhc_wrdata0_sdclk_dly = 0; + phy->settings.sdhc_wrdata1_dly = 0; + phy->settings.sdhc_wrdata1_sdclk_dly = 0; + } +} + +static +int sdhci_cdns_sd6_get_delay_params(struct device *dev, + struct sdhci_cdns_priv *priv) +{ + struct sdhci_cdns_sd6_phy *phy = priv->phy; + int ret; + + of_property_read_u32(dev->of_node, "marvell,iocell-input-delay-ps", + &phy->d.iocell_input_delay); + of_property_read_u32(dev->of_node, "marvell,iocell-output-delay-ps", + &phy->d.iocell_output_delay); + of_property_read_u32(dev->of_node, "marvell,delay-element-ps", + &phy->d.delay_element); + ret = of_property_read_u32(dev->of_node, "marvell,read-dqs-cmd-delay-ps", + &phy->settings.cp_read_dqs_cmd_delay); + if (ret) + phy->settings.cp_read_dqs_cmd_delay = DEFAULT_CMD_DELAY; + + ret = of_property_read_u32(dev->of_node, "marvell,tune-val-start-ps", + &tune_val_start); + if (ret) + tune_val_start = SDHCI_CDNS_TUNE_START; + + ret = of_property_read_u32(dev->of_node, "marvell,tune-val-step-ps", + &tune_val_step); + if (ret) + tune_val_step = SDHCI_CDNS_TUNE_STEP; + + read_dqs_cmd_delay = phy->settings.cp_read_dqs_cmd_delay; + clk_wrdqs_delay = phy->settings.cp_clk_wrdqs_delay; + clk_wr_delay = phy->settings.cp_clk_wr_delay; + read_dqs_delay = phy->settings.cp_read_dqs_delay; + return 0; +} + +static int sdhci_cdns_sd6_phy_init(struct sdhci_cdns_priv *priv) +{ + int ret; + u32 reg; + struct sdhci_cdns_sd6_phy *phy = priv->phy; + + sdhci_cdns_sd6_dll_reset(priv, true); + + reg = sdhci_cdns_sd6_read_phy_reg(priv, SDHCI_CDNS_SD6_PHY_DQS_TIMING); + reg &= ~SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_EXT_LPBK_DQS; + reg &= ~SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_LPBK_DQS; + reg &= ~SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_PHONY_DQS; + reg &= ~SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_PHONY_DQS_CMD; + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_EXT_LPBK_DQS, + phy->settings.cp_use_ext_lpbk_dqs); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_LPBK_DQS, + phy->settings.cp_use_lpbk_dqs); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_PHONY_DQS, + phy->settings.cp_use_phony_dqs); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DQS_TIMING_USE_PHONY_DQS_CMD, + phy->settings.cp_use_phony_dqs_cmd); + sdhci_cdns_sd6_write_phy_reg(priv, SDHCI_CDNS_SD6_PHY_DQS_TIMING, reg); + + reg = sdhci_cdns_sd6_read_phy_reg(priv, SDHCI_CDNS_SD6_PHY_GATE_LPBK); + reg &= ~SDHCI_CDNS_SD6_PHY_GATE_LPBK_SYNC_METHOD; + reg &= ~SDHCI_CDNS_SD6_PHY_GATE_LPBK_SW_HALF_CYCLE_SHIFT; + reg &= ~SDHCI_CDNS_SD6_PHY_GATE_LPBK_RD_DEL_SEL; + reg &= ~SDHCI_CDNS_SD6_PHY_GATE_LPBK_GATE_CFG_ALWAYS_ON; + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_GATE_LPBK_SYNC_METHOD, + phy->settings.cp_sync_method); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_GATE_LPBK_SW_HALF_CYCLE_SHIFT, + phy->settings.cp_sw_half_cycle_shift); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_GATE_LPBK_RD_DEL_SEL, + phy->settings.cp_rd_del_sel); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_GATE_LPBK_GATE_CFG_ALWAYS_ON, + phy->settings.cp_gate_cfg_always_on); + sdhci_cdns_sd6_write_phy_reg(priv, SDHCI_CDNS_SD6_PHY_GATE_LPBK, reg); + + reg = 0x0; + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DLL_MASTER_BYPASS_MODE, + phy->settings.cp_dll_bypass_mode); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DLL_MASTER_PHASE_DETECT_SEL, 2); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DLL_MASTER_DLL_LOCK_NUM, 0); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DLL_MASTER_DLL_START_POINT, + phy->settings.cp_dll_start_point); + sdhci_cdns_sd6_write_phy_reg(priv, SDHCI_CDNS_SD6_PHY_DLL_MASTER, reg); + + reg = 0x0; + reg = FIELD_PREP(SDHCI_CDNS_SD6_PHY_DLL_SLAVE_READ_DQS_CMD_DELAY, + phy->settings.cp_read_dqs_cmd_delay); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DLL_SLAVE_CLK_WRDQS_DELAY, + phy->settings.cp_clk_wrdqs_delay); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DLL_SLAVE_CLK_WR_DELAY, + phy->settings.cp_clk_wr_delay); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DLL_SLAVE_READ_DQS_DELAY, + phy->settings.cp_read_dqs_delay); + sdhci_cdns_sd6_write_phy_reg(priv, SDHCI_CDNS_SD6_PHY_DLL_SLAVE, reg); + + reg = sdhci_cdns_sd6_read_phy_reg(priv, SDHCI_CDNS_SD6_PHY_CTRL); + reg &= ~SDHCI_CDNS_SD6_PHY_CTRL_PHONY_DQS_TIMING; + sdhci_cdns_sd6_write_phy_reg(priv, SDHCI_CDNS_SD6_PHY_CTRL, reg); + + reg = sdhci_cdns_sd6_read_phy_reg(priv, SDHCI_CDNS_SD6_PHY_GPIO_CTRL0); + reg &= ~0x77; + reg |= SDHCI_CDNS_SD6_PHY_GPIO_CTRL0_DRV_OVR_EN | + SDHCI_CDNS_SD6_PHY_GPIO_CTRL0_SLEW_OVR_EN; + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_GPIO_CTRL0_DRV, + phy->settings.drive); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_GPIO_CTRL0_SLEW, + phy->settings.slew); + sdhci_cdns_sd6_write_phy_reg(priv, SDHCI_CDNS_SD6_PHY_GPIO_CTRL0, reg); + + ret = sdhci_cdns_sd6_dll_reset(priv, false); + if (ret) + return ret; + + reg = sdhci_cdns_sd6_read_phy_reg(priv, SDHCI_CDNS_SD6_PHY_DQ_TIMING); + reg &= ~SDHCI_CDNS_SD6_PHY_DQ_TIMING_IO_MASK_ALWAYS_ON; + reg &= ~SDHCI_CDNS_SD6_PHY_DQ_TIMING_IO_MASK_END; + reg &= ~SDHCI_CDNS_SD6_PHY_DQ_TIMING_IO_MASK_START; + reg &= ~SDHCI_CDNS_SD6_PHY_DQ_TIMING_DATA_SELECT_OE_END; + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DQ_TIMING_IO_MASK_ALWAYS_ON, + phy->settings.cp_io_mask_always_on); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DQ_TIMING_IO_MASK_END, + phy->settings.cp_io_mask_end); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DQ_TIMING_IO_MASK_START, + phy->settings.cp_io_mask_start); + reg |= FIELD_PREP(SDHCI_CDNS_SD6_PHY_DQ_TIMING_DATA_SELECT_OE_END, + phy->settings.cp_data_select_oe_end); + sdhci_cdns_sd6_write_phy_reg(priv, SDHCI_CDNS_SD6_PHY_DQ_TIMING, reg); + + reg = readl(priv->hrs_addr + SDHCI_CDNS_HRS09); + if (phy->settings.sdhc_extended_wr_mode) + reg |= SDHCI_CDNS_HRS09_EXTENDED_WR_MODE; + else + reg &= ~SDHCI_CDNS_HRS09_EXTENDED_WR_MODE; + + if (phy->settings.sdhc_extended_rd_mode) + reg |= SDHCI_CDNS_HRS09_EXTENDED_RD_MODE; + else + reg &= ~SDHCI_CDNS_HRS09_EXTENDED_RD_MODE; + + if (phy->settings.sdhc_rddata_en) + reg |= SDHCI_CDNS_HRS09_RDDATA_EN; + else + reg &= ~SDHCI_CDNS_HRS09_RDDATA_EN; + + if (phy->settings.sdhc_rdcmd_en) + reg |= SDHCI_CDNS_HRS09_RDCMD_EN; + else + reg &= ~SDHCI_CDNS_HRS09_RDCMD_EN; + + writel(reg, priv->hrs_addr + SDHCI_CDNS_HRS09); + + writel(0x30004, priv->hrs_addr + SDHCI_CDNS_HRS02); + + reg = 0x0; + reg = FIELD_PREP(SDHCI_CDNS_HRS10_HCSDCLKADJ, phy->settings.sdhc_hcsdclkadj); + writel(reg, priv->hrs_addr + SDHCI_CDNS_HRS10); + + if (phy->mode != MMC_TIMING_MMC_HS && phy->mode != MMC_TIMING_MMC_DDR52) { + reg = 0x0; + reg = FIELD_PREP(SDHCI_CDNS_HRS16_WRDATA1_SDCLK_DLY, + phy->settings.sdhc_wrdata1_sdclk_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRDATA0_SDCLK_DLY, + phy->settings.sdhc_wrdata0_sdclk_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRCMD1_SDCLK_DLY, + phy->settings.sdhc_wrcmd1_sdclk_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRCMD0_SDCLK_DLY, + phy->settings.sdhc_wrcmd0_sdclk_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRDATA1_DLY, + phy->settings.sdhc_wrdata1_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRDATA0_DLY, + phy->settings.sdhc_wrdata0_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRCMD1_DLY, + phy->settings.sdhc_wrcmd1_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRCMD0_DLY, + phy->settings.sdhc_wrcmd0_dly); + } else { + reg = 0x202; + } + + writel(reg, priv->hrs_addr + SDHCI_CDNS_HRS16); + + reg = 0x0; + reg = FIELD_PREP(SDHCI_CDNS_HRS07_RW_COMPENSATE, + phy->settings.sdhc_rw_compensate); + reg |= FIELD_PREP(SDHCI_CDNS_HRS07_IDELAY_VAL, + phy->settings.sdhc_idelay_val); + writel(reg, priv->hrs_addr + SDHCI_CDNS_HRS07); return 0; } @@ -199,6 +1113,19 @@ static void *sdhci_cdns_priv(struct sdhci_host *host) return sdhci_pltfm_priv(pltfm_host); } +static int sdhci_cdns_sd6_set_tune_val(struct sdhci_host *host, + unsigned int val) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + struct sdhci_cdns_sd6_phy *phy = priv->phy; + + phy->settings.hs200_tune_val = val; + phy->settings.cp_read_dqs_cmd_delay = val; + phy->settings.cp_read_dqs_delay = val; + + return sdhci_cdns_sd6_phy_init(priv); +} + static unsigned int sdhci_cdns_get_timeout_clock(struct sdhci_host *host) { /* @@ -208,6 +1135,11 @@ static unsigned int sdhci_cdns_get_timeout_clock(struct sdhci_host *host) return host->max_clk; } +static unsigned int sdhci_cdns_get_max_clock(struct sdhci_host *host) +{ + return SDMCLK_MAX_FREQ; +} + static void sdhci_cdns_set_emmc_mode(struct sdhci_cdns_priv *priv, u32 mode) { u32 tmp; @@ -227,6 +1159,118 @@ static u32 sdhci_cdns_get_emmc_mode(struct sdhci_cdns_priv *priv) return FIELD_GET(SDHCI_CDNS_HRS06_MODE, tmp); } +static int sdhci_cdns_sd6_phy_update_timings(struct sdhci_host *host) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + struct sdhci_cdns_sd6_phy *phy = priv->phy; + int t_sdmclk = phy->t_sdmclk; + int mode; + + mode = sdhci_cdns_sd6_get_mode(host, host->mmc->ios.timing); + /* initialize input */ + init_timings[mode](&phy->t, phy->t_sdclk); + + phy->mode = host->mmc->ios.timing; + phy->strobe_dat = false; + + switch (phy->mode) { + case MMC_TIMING_UHS_SDR104: + phy->tune_cmd = true; + phy->tune_dat = true; + break; + case MMC_TIMING_UHS_DDR50: + phy->ddr = true; + break; + case MMC_TIMING_MMC_DDR52: + phy->ddr = true; + break; + case MMC_TIMING_MMC_HS200: + phy->tune_dat = true; + phy->tune_cmd = true; + break; + case MMC_TIMING_MMC_HS400: + phy->tune_cmd = true; + phy->ddr = true; + phy->strobe_dat = true; + break; + } + + if (priv->enhanced_strobe) + phy->strobe_cmd = true; + + phy->d.phy_sdclk_delay = 2 * t_sdmclk; + phy->d.phy_cmd_o_delay = 2 * t_sdmclk + t_sdmclk / 2; + phy->d.phy_dat_o_delay = 2 * t_sdmclk + t_sdmclk / 2; + + if (phy->t_sdclk == phy->t_sdmclk) { + phy->settings.sdhc_extended_wr_mode = 0; + phy->settings.sdhc_extended_rd_mode = 0; + } else { + phy->settings.sdhc_extended_wr_mode = 1; + phy->settings.sdhc_extended_rd_mode = 1; + } + + phy->settings.cp_gate_cfg_always_on = 1; + + sdhci_cdns_sd6_phy_configure_dll(phy); + + sdhci_cdns_sd6_phy_calc_settings(phy); + + return 0; +} + +static u32 sdhci_cdns_sd6_get_mode(struct sdhci_host *host, + unsigned int timing) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + u32 mode; + + switch (timing) { + case MMC_TIMING_MMC_HS: + mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR; + break; + case MMC_TIMING_MMC_DDR52: + mode = SDHCI_CDNS_HRS06_MODE_MMC_DDR; + break; + case MMC_TIMING_MMC_HS200: + mode = SDHCI_CDNS_HRS06_MODE_MMC_HS200; + break; + case MMC_TIMING_MMC_HS400: + if (priv->enhanced_strobe) + mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400ES; + else + mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400; + break; + case MMC_TIMING_SD_HS: + mode = SDHCI_CDNS_HRS06_MODE_SD; + break; + default: + mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR; + break; + } + + return mode; +} + +static void sdhci_cdns_sd6_set_clock(struct sdhci_host *host, + unsigned int clock) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + struct sdhci_cdns_sd6_phy *phy = priv->phy; + + phy->t_sdclk = DIV_ROUND_DOWN_ULL(1e12, clock); + + pr_debug("%s %d %d\n", __func__, phy->mode, clock); + + if (sdhci_cdns_sd6_phy_update_timings(host)) + pr_debug("%s: update timings failed\n", __func__); + + if (sdhci_cdns_sd6_phy_init(priv)) + pr_debug("%s: phy init failed\n", __func__); + + sdhci_set_clock(host, clock); +} + static int sdhci_cdns_sd4_phy_probe(struct platform_device *pdev, struct sdhci_cdns_priv *priv) { @@ -248,6 +1292,106 @@ static int sdhci_cdns_sd4_phy_probe(struct platform_device *pdev, return 0; } +static int sdhci_cdns_sd6_phy_probe(struct platform_device *pdev, + struct sdhci_cdns_priv *priv) +{ + struct device *dev = &pdev->dev; + struct sdhci_cdns_sd6_phy *phy; + u32 val; + struct clk *clk; + int ret; + const char *mode_name; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + clk = devm_clk_get(dev, "sdmclk"); + if (IS_ERR(clk)) { + dev_err(dev, "sdmclk get error\n"); + return PTR_ERR(clk); + } + + val = clk_get_rate(clk); + phy->t_sdmclk = DIV_ROUND_DOWN_ULL(1e12, val); + + ret = of_property_read_u32(dev->of_node, "cdns,host_slew", + &phy->settings.slew); + if (ret) + phy->settings.slew = 3; + + ret = of_property_read_u32(dev->of_node, "cdns,host_drive", + &phy->settings.drive); + if (ret) + phy->settings.drive = 2; + + ret = of_property_read_u32(dev->of_node, "cdns,iocell-input-delay", + &phy->d.iocell_input_delay); + if (ret) + phy->d.iocell_input_delay = 2500; + + ret = of_property_read_u32(dev->of_node, "cdns,iocell-output-delay", + &phy->d.iocell_output_delay); + if (ret) + phy->d.iocell_output_delay = 2500; + + ret = of_property_read_u32(dev->of_node, "cdns,delay-element", + &phy->d.delay_element); + if (ret) + phy->d.delay_element = 24; + + ret = of_property_read_string_index(dev->of_node, "cdns,mode", 0, + &mode_name); + if (!ret) { + if (!strcmp("emmc_sdr", mode_name)) + phy->mode = MMC_TIMING_MMC_HS; + else if (!strcmp("emmc_ddr", mode_name)) + phy->mode = MMC_TIMING_MMC_DDR52; + else if (!strcmp("emmc_hs200", mode_name)) + phy->mode = MMC_TIMING_MMC_HS200; + else if (!strcmp("emmc_hs400", mode_name)) + phy->mode = MMC_TIMING_MMC_HS400; + else if (!strcmp("sd_hs", mode_name)) + phy->mode = MMC_TIMING_SD_HS; + else + phy->mode = MMC_TIMING_MMC_HS; + } else { + phy->mode = MMC_TIMING_MMC_HS; + } + + phy->d.delay_element_org = phy->d.delay_element; + phy->d.iocell_input_delay = 650; + phy->d.iocell_output_delay = 1800; + + switch (phy->mode) { + case MMC_TIMING_MMC_HS: + phy->t_sdclk = 10000; + break; + case MMC_TIMING_MMC_DDR52: + phy->t_sdclk = 10000; + break; + case MMC_TIMING_MMC_HS200: + phy->t_sdclk = 5000; + break; + case MMC_TIMING_MMC_HS400: + phy->t_sdclk = 5000; + break; + case MMC_TIMING_SD_HS: + phy->t_sdclk = 100000; + break; + default: + phy->t_sdclk = 10000; + break; + } + + priv->phy = phy; + + sdhci_cdns_sd6_get_delay_params(dev, priv); + + sdhci_cdns_sd6_calc_phy(phy); + return 0; +} + static int sdhci_cdns_sd4_set_tune_val(struct sdhci_host *host, unsigned int val) { struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); @@ -281,6 +1425,57 @@ static int sdhci_cdns_sd4_set_tune_val(struct sdhci_host *host, unsigned int val return 0; } +/* + * In SD mode, software must not use the hardware tuning and instead perform + * an almost identical procedure to eMMC. + */ +static int sdhci_cdns_sd6_execute_tuning(struct sdhci_host *host, u32 opcode) +{ + int cur_streak = 0; + int max_streak = 0; + int end_of_streak = 0; + int i, midpoint, iter = 0; + + /* + * Do not execute tuning for UHS_SDR50 or UHS_DDR50. + * The delay is set by probe, based on the DT properties. + */ + if (host->timing != MMC_TIMING_MMC_HS200 && + host->timing != MMC_TIMING_UHS_SDR104) + return 0; + + for (i = tune_val_start; iter < max_tune_iter; iter++, i += tune_val_step) { + if (sdhci_cdns_sd6_set_tune_val(host, i) || + mmc_send_tuning(host->mmc, opcode, NULL)) { /* bad */ + cur_streak = 0; + } else { /* good */ + cur_streak++; + if (cur_streak > max_streak) { + max_streak = cur_streak; + end_of_streak = i; + pr_debug("%s (%d-%d = %d)", __func__, + end_of_streak - ((cur_streak - 1) * tune_val_step), + end_of_streak, cur_streak); + } else { + pr_debug("%s (%d-%d)", __func__, + i - ((cur_streak - 1) * tune_val_step), i); + } + } + } + + if (!max_streak) { + dev_err(mmc_dev(host->mmc), "no tuning point found\n"); + return -EIO; + } + + pr_debug("max_streak: %d-%d", end_of_streak - ((max_streak - 1) * tune_val_step), + end_of_streak); + + midpoint = end_of_streak - (((max_streak - 1) * tune_val_step) / 2); + + return sdhci_cdns_sd6_set_tune_val(host, midpoint); +} + /* * In SD mode, software must not use the hardware tuning and instead perform * an almost identical procedure to eMMC. @@ -343,9 +1538,12 @@ static void sdhci_cdns_set_uhs_signaling(struct sdhci_host *host, else mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400; break; - default: + case MMC_TIMING_SD_HS: mode = SDHCI_CDNS_HRS06_MODE_SD; break; + default: + mode = SDHCI_CDNS_HRS06_MODE_LEGACY; + break; } sdhci_cdns_set_emmc_mode(priv, mode); @@ -440,6 +1638,24 @@ static int elba_drv_init(struct platform_device *pdev) return 0; } +static void sdhci_cdns_sd6_set_uhs_signaling(struct sdhci_host *host, + unsigned int timing) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + struct sdhci_cdns_sd6_phy *phy = priv->phy; + + sdhci_cdns_set_uhs_signaling(host, timing); + + if ((phy->mode == -1) || (phy->t_sdclk == -1)) + return; + + if (sdhci_cdns_sd6_phy_update_timings(host)) + pr_debug("%s: update timings failed\n", __func__); + + if (sdhci_cdns_sd6_phy_init(priv)) + pr_debug("%s: phy init failed\n", __func__); +} + static const struct sdhci_ops sdhci_cdns_sd4_ops = { .set_clock = sdhci_set_clock, .get_timeout_clock = sdhci_cdns_get_timeout_clock, @@ -449,6 +1665,16 @@ static const struct sdhci_ops sdhci_cdns_sd4_ops = { .set_uhs_signaling = sdhci_cdns_set_uhs_signaling, }; +static const struct sdhci_ops sdhci_cdns_sd6_ops = { + .get_max_clock = sdhci_cdns_get_max_clock, + .set_clock = sdhci_cdns_sd6_set_clock, + .get_timeout_clock = sdhci_cdns_get_timeout_clock, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_reset, + .platform_execute_tuning = sdhci_cdns_sd6_execute_tuning, + .set_uhs_signaling = sdhci_cdns_sd6_set_uhs_signaling, +}; + static const struct sdhci_cdns_drv_data sdhci_cdns_uniphier_drv_data = { .phy_init = sdhci_cdns_sd4_phy_init, .phy_probe = sdhci_cdns_sd4_phy_probe, @@ -475,6 +1701,14 @@ static const struct sdhci_cdns_drv_data sdhci_cdns_sd4_drv_data = { }, }; +static const struct sdhci_cdns_drv_data sdhci_cdns_sd6_drv_data = { + .phy_init = sdhci_cdns_sd6_phy_init, + .phy_probe = sdhci_cdns_sd6_phy_probe, + .pltfm_data = { + .ops = &sdhci_cdns_sd6_ops, + }, +}; + static void sdhci_cdns_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) { @@ -518,8 +1752,11 @@ static int sdhci_cdns_probe(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host; struct sdhci_cdns_priv *priv; struct clk *clk; + bool sd6_ctrl; int ret; struct device *dev = &pdev->dev; + sd6_ctrl = of_device_is_compatible(dev->of_node, "marvell,cdns-sd6hc"); + static const u16 version = SDHCI_SPEC_400 << SDHCI_SPEC_VER_SHIFT; clk = devm_clk_get(dev, NULL); @@ -545,6 +1782,12 @@ static int sdhci_cdns_probe(struct platform_device *pdev) pltfm_host = sdhci_priv(host); pltfm_host->clk = clk; + if (sd6_ctrl) { + host->clk_mul = 0; + host->max_clk = SDMCLK_MAX_FREQ; + host->quirks |= SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; + host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; + } priv = sdhci_pltfm_priv(pltfm_host); priv->hrs_addr = host->ioaddr; priv->enhanced_strobe = false; @@ -559,7 +1802,10 @@ static int sdhci_cdns_probe(struct platform_device *pdev) goto free; } sdhci_enable_v4_mode(host); - __sdhci_read_caps(host, &version, NULL, NULL); + if (sd6_ctrl) + __sdhci_read_caps(host, NULL, NULL, NULL); + else + __sdhci_read_caps(host, &version, NULL, NULL); sdhci_get_of_property(pdev); @@ -645,6 +1891,10 @@ static const struct of_device_id sdhci_cdns_match[] = { .compatible = "cdns,sd4hc", .data = &sdhci_cdns_sd4_drv_data, }, + { + .compatible = "marvell,cdns-sd6hc", + .data = &sdhci_cdns_sd6_drv_data, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sdhci_cdns_match); From patchwork Mon Jul 17 12:51:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Piyush Malgujar X-Patchwork-Id: 121303 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp1105520vqt; Mon, 17 Jul 2023 06:17:36 -0700 (PDT) X-Google-Smtp-Source: APBJJlHzxrcy1VY5cCWnf+wvZFQipOZkFUwiA0nLoGrMS+elSwqZ+j7OY4Ink3524gpBLS3ayvcU X-Received: by 2002:a17:902:c410:b0:1b9:ce7a:88b4 with SMTP id k16-20020a170902c41000b001b9ce7a88b4mr15098002plk.42.1689599855899; Mon, 17 Jul 2023 06:17:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689599855; cv=none; d=google.com; s=arc-20160816; b=SPapl+LAenyU7am/T0DmN8V8bWXwAlFRB1UH1nGkxkJV2/dHvbCeRVm5pencxGnVSB i99vgAYydt8Qai9VJuiPAUuU9Pmv06WfYibvMeVsFAnTiC96B7fJ5+lyp+F5VIaQeAHv xciaPhvXTAcmutC7rdQnr8ui0ikC3cDFpS4E1rQdS4Ur/nEez96JjnPylJjcoVwP8+xs IAnji6hGTNGo69ZemrhcTehVRyjTddObyDWa1hhoJl0HVdoJg+vtVX4PTbg2n95ch2we KEiS9OQ0GN4JVRMdleRx+c184yvUHeH73xAVc+BCxikCBHM9zCFnpDVyqxlxCd2Mbkp1 d4fA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=CKZ7XtME/7XZOsmvtz8KPGVZW7vXR/qqmoCpnIai4qA=; fh=qts3kvMfs8M7by6qcqwTW0duVvYIstAxu5fawQbQU6I=; b=J6v5Y1Z0wN6x8dY6+Ip1gVRs0QZH7Dr5yuQvC1RhkHajvWJos98PAhuT930Q0h1nZ6 E1NZQ3aKdjgvYGZ5NnqW+takSu5FiIG4CYp2nBW24C3CtxcKQbNTg9LrvtMdDS1rccOM k0+q4jnc7OapHdNYYsrlPUosxZZMm68uZ0FintfL/gyJw2vo2Yilnf+//HdbjWnczR9V Z/SyrqrNVpB9r9DaMgRDi8Y9P97QmlHsI5LsvPTBAnTLTI8ZmT6UFo1gGZhxVFCkdsPK 7ROwN2q7zX0cOcY8HPurX8uT4pp4Yo/3LKkxPvSgFFVsjgoqZCQ38UrkxkAxxTRVS3y0 Tnfw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=PnlQOma3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w21-20020a170902d71500b001b9e0d0a01fsi11540364ply.256.2023.07.17.06.17.22; Mon, 17 Jul 2023 06:17:35 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=PnlQOma3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229835AbjGQMxC (ORCPT + 99 others); Mon, 17 Jul 2023 08:53:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230498AbjGQMw7 (ORCPT ); Mon, 17 Jul 2023 08:52:59 -0400 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A6CDE47; Mon, 17 Jul 2023 05:52:55 -0700 (PDT) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 36H5To5Y020411; Mon, 17 Jul 2023 05:52:46 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=CKZ7XtME/7XZOsmvtz8KPGVZW7vXR/qqmoCpnIai4qA=; b=PnlQOma3tNCLhBoKqkse7iXzb2MMijY6xK6435Np1TMZue095Ka6kMLCq8htyn9xRdJE 08kWvc74nE9uUMqvozkU8s/z3BHP2f36edyy392Ps488wn+SDkh6PypRWODIz2fNIpw+ pI135SdTPv3a8hEgQAU9SqhJzao53d6lQErUn0mqyzBjfeh1DqXZJ8sPCJEMaT+CALbG F1SyxJ23SXzoPu+Mk+G2gUe3xKz9zDG0SAY9B7U1CR223PSglSR6aUSZefdxdkKI6FKl gzWivOrkVzUTLoiGEReQZZj6xRE30ifCpU/11rGpKXCZD0JPwpD0cvdUsMfjXo58gEv5 Dw== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3rvyhx18n0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 17 Jul 2023 05:52:46 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Mon, 17 Jul 2023 05:52:44 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Mon, 17 Jul 2023 05:52:44 -0700 Received: from localhost.localdomain (unknown [10.110.150.250]) by maili.marvell.com (Postfix) with ESMTP id 631E83F70A4; Mon, 17 Jul 2023 05:52:44 -0700 (PDT) From: Piyush Malgujar To: , , , , , , , , , CC: , , Piyush Malgujar Subject: [PATCH v4 4/6] mmc: sdhci-cadence: enable MMC_SDHCI_IO_ACCESSORS support Date: Mon, 17 Jul 2023 05:51:44 -0700 Message-ID: <20230717125146.16791-5-pmalgujar@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230717125146.16791-1-pmalgujar@marvell.com> References: <20230717125146.16791-1-pmalgujar@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: yDQ-TYkcBfpsu3kVag6JqhmZXZYbXeED X-Proofpoint-ORIG-GUID: yDQ-TYkcBfpsu3kVag6JqhmZXZYbXeED X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-07-17_10,2023-07-13_01,2023-05-22_02 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771673858244621058 X-GMAIL-MSGID: 1771673858244621058 From: Jayanthi Annadurai Add support of CONFIG_MMC_SDHCI_IO_ACCESSORS to allow Marvell SoC ops for SD6 controller to overwrite the SDHCI IO memory accessors. Signed-off-by: Jayanthi Annadurai Signed-off-by: Piyush Malgujar --- drivers/mmc/host/sdhci-cadence.c | 59 ++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index 8bcf585185053b0afaff2625d62316cec1824fa3..f1e597219c603f3921439cedb22dcb2884abe68d 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c @@ -448,6 +448,59 @@ static u32 read_dqs_cmd_delay, clk_wrdqs_delay, clk_wr_delay, read_dqs_delay; static u32 sdhci_cdns_sd6_get_mode(struct sdhci_host *host, unsigned int timing); +static u32 sdhci_cdns_sd6_readl(struct sdhci_host *host, int reg) +{ + return readl(host->ioaddr + reg); +} + +static void sdhci_cdns_sd6_writel(struct sdhci_host *host, u32 val, int reg) +{ + writel(val, host->ioaddr + reg); +} + +static u16 sdhci_cdns_sd6_readw(struct sdhci_host *host, int reg) +{ + u32 val, regoff; + + regoff = reg & ~3; + + val = readl(host->ioaddr + regoff); + if ((reg & 0x3) == 0) + return (val & 0xFFFF); + else + return ((val >> 16) & 0xFFFF); +} + +static void sdhci_cdns_sd6_writew(struct sdhci_host *host, u16 val, int reg) +{ + writew(val, host->ioaddr + reg); +} + +static u8 sdhci_cdns_sd6_readb(struct sdhci_host *host, int reg) +{ + u32 val, regoff; + + regoff = reg & ~3; + + val = readl(host->ioaddr + regoff); + switch (reg & 3) { + case 0: + return (val & 0xFF); + case 1: + return ((val >> 8) & 0xFF); + case 2: + return ((val >> 16) & 0xFF); + case 3: + return ((val >> 24) & 0xFF); + } + return 0; +} + +static void sdhci_cdns_sd6_writeb(struct sdhci_host *host, u8 val, int reg) +{ + writeb(val, host->ioaddr + reg); +} + static int sdhci_cdns_sd6_phy_lock_dll(struct sdhci_cdns_sd6_phy *phy) { u32 delay_element = phy->d.delay_element_org; @@ -1666,6 +1719,12 @@ static const struct sdhci_ops sdhci_cdns_sd4_ops = { }; static const struct sdhci_ops sdhci_cdns_sd6_ops = { + .read_l = sdhci_cdns_sd6_readl, + .write_l = sdhci_cdns_sd6_writel, + .read_w = sdhci_cdns_sd6_readw, + .write_w = sdhci_cdns_sd6_writew, + .read_b = sdhci_cdns_sd6_readb, + .write_b = sdhci_cdns_sd6_writeb, .get_max_clock = sdhci_cdns_get_max_clock, .set_clock = sdhci_cdns_sd6_set_clock, .get_timeout_clock = sdhci_cdns_get_timeout_clock, From patchwork Mon Jul 17 12:51:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Piyush Malgujar X-Patchwork-Id: 121287 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp1102451vqt; Mon, 17 Jul 2023 06:12:54 -0700 (PDT) X-Google-Smtp-Source: APBJJlGwkC6GxHldiJ/9E5BhFRxV4KOhwruEAXgZDXQxpxCEttpf+ceDWXCGhnqKiawVkKXgFF71 X-Received: by 2002:a17:90a:71c6:b0:262:ecc3:ee6b with SMTP id m6-20020a17090a71c600b00262ecc3ee6bmr10303941pjs.39.1689599574295; Mon, 17 Jul 2023 06:12:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689599574; cv=none; d=google.com; s=arc-20160816; b=xUFht3DOclqMmzmdH3nDRcQD4G+1k/HSFEtKv3dUcBBITOQwmrbxlPWSIWV+6fBK6C ulvqnr1Th43yjuFiYRRXck4Spo1GUvoHDwXjCMsPqYacaeyQ+yDgYFBX+xWzOBJplgvV 4zVrTnunE4CLB2tj2cITwyP+MwUmEXsbaEMybW9FuDLe8FeXvRBfp/FcWP7zepFUod8F 6R7A6pMp3M5T/s5UwoDcyPgk0bXbz4cxi2W3LQpdconJcbKwxjlidf6DpR4x+/Nb6FvN ThoYFFuw7pgpQPMIfRHAz4SSXL3wIHtTa1GhsN8W099Tk+10JJdjkmaPPQm87MhJBfXG bmAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=OoOXrpIZdvfkubmPKjeC5jzckUP2dLYGo/Bx/R0iEnw=; fh=qts3kvMfs8M7by6qcqwTW0duVvYIstAxu5fawQbQU6I=; b=CvJA/9S3cb3mrjhsppucXHK3Uv5nF0LwB817DuVudo+uGGzBWwLVjAkqddnRFtnMar rl0Z0LDnoLvFlgsV9+cuBT0B0dAa0DHGVChibPsCNlWs2vefgCfL8sJeQpAbH8XTGBg8 XNwqziNgU1w8eKD9PFMHBVMpaDGL6O6vMyMi9Nep3CqLr7WWNXGLV2YZ5UOvlktM9cGs mDphk/Hq1UcL7x9mUh+MICZZygq9+A+VcnWMkaYd2JoSQcM6C0kbcxdKl5I4UJg7e47J NWlXoqoZWpV71Uep8bfz5K3eFg3Gj4/2t4My3mCxfJAUOQGyTj8oyIaQn0sAC56Xc55Q fv/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=Dpc4oBrl; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m13-20020a65530d000000b0051423af249fsi11492952pgq.304.2023.07.17.06.12.41; Mon, 17 Jul 2023 06:12:54 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=Dpc4oBrl; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231129AbjGQMxH (ORCPT + 99 others); Mon, 17 Jul 2023 08:53:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229379AbjGQMxD (ORCPT ); Mon, 17 Jul 2023 08:53:03 -0400 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D5F70E4C; Mon, 17 Jul 2023 05:53:00 -0700 (PDT) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 36H5TpJh020422; Mon, 17 Jul 2023 05:52:53 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=OoOXrpIZdvfkubmPKjeC5jzckUP2dLYGo/Bx/R0iEnw=; b=Dpc4oBrlQi8yhw4miIUR8hehxxsy5ZE9L4sFe0zohJk1T1Eitp0KVcl+FG/EcTQ03BL2 frkKjFcJrSQXHvy9m+3S9vDEzaqHujztQfoGX3YeA9ms3Z7L7uYLES8hKSmdh04ObvJP 0oC55JBA60xFoy6sbPiFlSqASlmh5MzMayWAZ3FCldd9fO3lwJLjauotvpIk/n7tMKSE 7FWrip56VwdnW3rxwtXJj5TNdgX7Mt2Tvbc7yvWJPoSXVT0lin72kbHXz0kNIyY4dw6e pquB6WR22jLOtsuaeOCEVJbYjRCnvulwAfpG0p2OTBJTZeX4Gu2yDqa67jZ9UEKR9Jdt ow== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3rvyhx18n7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 17 Jul 2023 05:52:52 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Mon, 17 Jul 2023 05:52:51 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Mon, 17 Jul 2023 05:52:51 -0700 Received: from localhost.localdomain (unknown [10.110.150.250]) by maili.marvell.com (Postfix) with ESMTP id 21BE53F70A4; Mon, 17 Jul 2023 05:52:51 -0700 (PDT) From: Piyush Malgujar To: , , , , , , , , , CC: , , Piyush Malgujar Subject: [PATCH v4 5/6] dt-bindings: mmc: sdhci-cadence: SD6 support Date: Mon, 17 Jul 2023 05:51:45 -0700 Message-ID: <20230717125146.16791-6-pmalgujar@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230717125146.16791-1-pmalgujar@marvell.com> References: <20230717125146.16791-1-pmalgujar@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: 55VCfbYEILUdl4A4bFkbZf4rWZbVjvbv X-Proofpoint-ORIG-GUID: 55VCfbYEILUdl4A4bFkbZf4rWZbVjvbv X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-07-17_10,2023-07-13_01,2023-05-22_02 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771673563388814085 X-GMAIL-MSGID: 1771673563388814085 From: Jayanthi Annadurai Add support for SD6 controller on Marvell CN10K series SOCs. The existing sd4hc is not compatible with the SD6 changes. Signed-off-by: Jayanthi Annadurai Signed-off-by: Piyush Malgujar --- .../devicetree/bindings/mmc/cdns,sdhci.yaml | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml b/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml index 6c40611405a08717520f4ce3a78a9cb8dd9aac69..51f44c00a50505684c7c7c49c59c1ebd8d85d5d0 100644 --- a/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml @@ -4,19 +4,23 @@ $id: http://devicetree.org/schemas/mmc/cdns,sdhci.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Cadence SD/SDIO/eMMC Host Controller (SD4HC) +title: Cadence SD/SDIO/eMMC Host Controller (SD4HC, SD6HC) maintainers: - Masahiro Yamada properties: compatible: - items: - - enum: - - amd,pensando-elba-sd4hc - - microchip,mpfs-sd4hc - - socionext,uniphier-sd4hc - - const: cdns,sd4hc + oneOf: + - items: + - enum: + - amd,pensando-elba-sd4hc + - microchip,mpfs-sd4hc + - socionext,uniphier-sd4hc + - const: cdns,sd4hc + + - items: + - const: marvell,cdns-sd6hc reg: minItems: 1 @@ -139,6 +143,40 @@ allOf: reg: maxItems: 1 + - if: + properties: + compatible: + contains: + const: marvell,cdns-sd6hc + + then: + properties: + marvell,iocell-input-delay-ps: + description: Delay in ps across the input IO cells + + marvell,iocell-output-delay-ps: + description: Delay in ps across the output IO cells + + marvell,delay-element-ps: + description: Delay element in ps used for calculating phy timings + + marvell,read-dqs-cmd-delay-ps: + description: Command delay used in HS200 tuning + + marvell,tune-val-start-ps: + description: Staring value of data delay used in HS200 tuning + + marvell,tune-val-step-ps: + description: Incremental value of data delay used in HS200 tuning + + required: + - marvell,iocell-input-delay-ps + - marvell,iocell-output-delay-ps + - marvell,delay-element-ps + - marvell,read-dqs-cmd-delay-ps + - marvell,tune-val-start-ps + - marvell,tune-val-step-ps + unevaluatedProperties: false examples: From patchwork Mon Jul 17 12:51:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Piyush Malgujar X-Patchwork-Id: 121279 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp1091957vqt; Mon, 17 Jul 2023 05:58:45 -0700 (PDT) X-Google-Smtp-Source: APBJJlGPlZo7aGDCVhWOYgj6o0rQrvI1VlndqRZKLPFT0uSsGFdF488ItB1ZFFo/hxeUfnaS/rh2 X-Received: by 2002:a17:90a:4109:b0:262:cb1c:a782 with SMTP id u9-20020a17090a410900b00262cb1ca782mr10310536pjf.37.1689598725413; Mon, 17 Jul 2023 05:58:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689598725; cv=none; d=google.com; s=arc-20160816; b=KLKPQ2ygvRvU4sxd6WphDF8tkefOKX77/2o7K6YkI3EmRlC50Va4fX/lfNY3d2/luZ VY2WsiKNKYpvvjdROw+YNeMdZTuYvYM5cj2h9MWiyAN2uNr0WmjyRsaZt0CqJhgmXi0m IhO5QoNF5jbYJ43GoHsnLEVRDczRVnbrSqunfESFIb7QLK5u4IyNrHSvbeVntqYhuvDN KPvEULmi63MQos3wBY8frQsY0rN/WTkINTxEAKG/NqHHzzhhHZkq6fDvtSprGcyuzVrG 0sI6r3ROGsU7ESbMpwEfoSHxK+3R82MYJ1WCvoVMXwpYlAy+w/wtHP5V4ExqL30bHti8 gPzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=7LK2XM3LL17DaGIHpxY204NBdCG/pN2QpZhAjPwmtg0=; fh=qts3kvMfs8M7by6qcqwTW0duVvYIstAxu5fawQbQU6I=; b=FAunV/NUlcxgswd70bXEf3QyQaR+GmWk8xPYWTpjLL1oTX2ONb5KddBUWY++YJ6fXl pgitBXu581sBlFwa7f5rtVmhbeF9nUhd18iOivih1MO2o5pxcaKMB35Ozo4Im83QrxoQ Y+kX5VD/bpNIW7+6tY4VUGZ4TgVYRtSOcPRW960nlVTfy7BS1PVc06ghZjvbfsnjk89c FddOH8T3apjamH0q17bJgDoydEZQhpftwpKCj9ySDra7bDrS0Zo9EY+p5LtroC1PgsQG Ns/JWTmMp/G+2d0y/ikveZrKA3yoJSNOFc7KWaXEvTw/sa5aGtYWILmd5S/CeS/4Rzp4 TX+Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=c6itKt8f; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bo13-20020a17090b090d00b00259c1100db5si5802132pjb.188.2023.07.17.05.58.32; Mon, 17 Jul 2023 05:58:45 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=c6itKt8f; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229808AbjGQMxY (ORCPT + 99 others); Mon, 17 Jul 2023 08:53:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34398 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231246AbjGQMxP (ORCPT ); Mon, 17 Jul 2023 08:53:15 -0400 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 139E0170B; Mon, 17 Jul 2023 05:53:08 -0700 (PDT) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 36H5Tq4r020449; Mon, 17 Jul 2023 05:52:59 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=7LK2XM3LL17DaGIHpxY204NBdCG/pN2QpZhAjPwmtg0=; b=c6itKt8f5vO/Vqzeji4OpjEa0A5FnzwTxo4189xOfuwhxUju8FqqUIM5aqJxyE9C3Bhm B9otvecfkyuKn5IWYKjYZdjpithwVegmcTS5YBY+Nv4UC0aDdX8ckJo0Hv9xYy/L8XTy 3fA5ZqEHIMtR2bt6iJAva9y6WoHVQw9Yz41+6A7/93sX1t3oKnQAv0EmtktoXHpss927 JUHe7P9upcQPJ4pZ1VWd8kLu1cXMiZuA7bT6N9jNiokARuiVE01vllkBoOF3qgR6yBEX gIYwhmOCrAgl7PCmjkc2UDk9l8WV5AQ9bvXG0NikQbEjlfFD++F8fVNtiTCEZ9RyECJH Rg== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3rvyhx18ng-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 17 Jul 2023 05:52:58 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Mon, 17 Jul 2023 05:52:57 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Mon, 17 Jul 2023 05:52:57 -0700 Received: from localhost.localdomain (unknown [10.110.150.250]) by maili.marvell.com (Postfix) with ESMTP id 03FC23F70A4; Mon, 17 Jul 2023 05:52:56 -0700 (PDT) From: Piyush Malgujar To: , , , , , , , , , CC: , , Piyush Malgujar Subject: [PATCH v4 6/6] mmc: sdhci-cadence: Add debug option for SD6 controller Date: Mon, 17 Jul 2023 05:51:46 -0700 Message-ID: <20230717125146.16791-7-pmalgujar@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230717125146.16791-1-pmalgujar@marvell.com> References: <20230717125146.16791-1-pmalgujar@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: i7lENjUZQkPZPFDaGSaXApkAiGCFiWs3 X-Proofpoint-ORIG-GUID: i7lENjUZQkPZPFDaGSaXApkAiGCFiWs3 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-07-17_10,2023-07-13_01,2023-05-22_02 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771672673005886838 X-GMAIL-MSGID: 1771672673005886838 From: Jayanthi Annadurai Add support dumping PHY and host controller register configuration if debug config enabled. Signed-off-by: Jayanthi Annadurai Signed-off-by: Piyush Malgujar --- drivers/mmc/host/sdhci-cadence.c | 156 ++++++++++++++++++++++++++++++- 1 file changed, 155 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index f1e597219c603f3921439cedb22dcb2884abe68d..337a97bf906137f0eac4122cdd603f25df7ae8d9 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c @@ -116,6 +116,10 @@ #define SDHCI_CDNS_SD6_PHY_DLL_SLAVE_CLK_WR_DELAY GENMASK(15, 8) #define SDHCI_CDNS_SD6_PHY_DLL_SLAVE_READ_DQS_DELAY GENMASK(7, 0) +#define SDHCI_CDNS_SD6_PHY_DLL_OBS_REG0 0x201C +#define SDHCI_CDNS_SD6_PHY_DLL_OBS_REG1 0x2020 +#define SDHCI_CDNS_SD6_PHY_DLL_OBS_REG2 0x2024 + #define SDHCI_CDNS_SD6_PHY_CTRL 0x2080 #define SDHCI_CDNS_SD6_PHY_CTRL_PHONY_DQS_TIMING GENMASK(9, 4) @@ -813,7 +817,7 @@ static inline void cdns_writel(struct sdhci_cdns_priv *priv, u32 val, } static int sdhci_cdns_sd4_write_phy_reg(struct sdhci_cdns_priv *priv, - u8 addr, u8 data) + u8 addr, u8 data) { void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS04; u32 tmp; @@ -971,6 +975,154 @@ static void sdhci_cdns_sd6_calc_phy(struct sdhci_cdns_sd6_phy *phy) } } +#if defined(DEBUG) || IS_ENABLED(CONFIG_DYNAMIC_DEBUG) + +static +void sdhci_cdns_sd6_phy_dump(struct sdhci_cdns_sd6_phy *phy, + struct sdhci_host *host) +{ + dev_dbg(mmc_dev(host->mmc), "PHY Timings\n"); + dev_dbg(mmc_dev(host->mmc), "mode %d t_sdclk %d\n", phy->mode, + phy->t_sdclk); + + dev_dbg(mmc_dev(host->mmc), "cp_clk_wr_delay %d\n", + phy->settings.cp_clk_wr_delay); + dev_dbg(mmc_dev(host->mmc), "cp_clk_wrdqs_delay %d\n", + phy->settings.cp_clk_wrdqs_delay); + dev_dbg(mmc_dev(host->mmc), "cp_data_select_oe_end %d\n", + phy->settings.cp_data_select_oe_end); + dev_dbg(mmc_dev(host->mmc), "cp_dll_bypass_mode %d\n", + phy->settings.cp_dll_bypass_mode); + dev_dbg(mmc_dev(host->mmc), "cp_dll_locked_mode %d\n", + phy->settings.cp_dll_locked_mode); + dev_dbg(mmc_dev(host->mmc), "cp_dll_start_point %d\n", + phy->settings.cp_dll_start_point); + dev_dbg(mmc_dev(host->mmc), "cp_io_mask_always_on %d\n", + phy->settings.cp_io_mask_always_on); + dev_dbg(mmc_dev(host->mmc), "cp_io_mask_end %d\n", + phy->settings.cp_io_mask_end); + dev_dbg(mmc_dev(host->mmc), "cp_io_mask_start %d\n", + phy->settings.cp_io_mask_start); + dev_dbg(mmc_dev(host->mmc), "cp_rd_del_sel %d\n", + phy->settings.cp_rd_del_sel); + dev_dbg(mmc_dev(host->mmc), "cp_read_dqs_cmd_delay %d\n", + phy->settings.cp_read_dqs_cmd_delay); + dev_dbg(mmc_dev(host->mmc), "cp_read_dqs_delay %d\n", + phy->settings.cp_read_dqs_delay); + dev_dbg(mmc_dev(host->mmc), "cp_sw_half_cycle_shift %d\n", + phy->settings.cp_sw_half_cycle_shift); + dev_dbg(mmc_dev(host->mmc), "cp_sync_method %d\n", + phy->settings.cp_sync_method); + dev_dbg(mmc_dev(host->mmc), "cp_use_ext_lpbk_dqs %d\n", + phy->settings.cp_use_ext_lpbk_dqs); + dev_dbg(mmc_dev(host->mmc), "cp_use_lpbk_dqs %d\n", + phy->settings.cp_use_lpbk_dqs); + dev_dbg(mmc_dev(host->mmc), "cp_use_phony_dqs %d\n", + phy->settings.cp_use_phony_dqs); + dev_dbg(mmc_dev(host->mmc), "cp_use_phony_dqs_cmd %d\n", + phy->settings.cp_use_phony_dqs_cmd); + dev_dbg(mmc_dev(host->mmc), "sdhc_extended_rd_mode %d\n", + phy->settings.sdhc_extended_rd_mode); + dev_dbg(mmc_dev(host->mmc), "sdhc_extended_wr_mode %d\n", + phy->settings.sdhc_extended_wr_mode); + + dev_dbg(mmc_dev(host->mmc), "sdhc_hcsdclkadj %d\n", + phy->settings.sdhc_hcsdclkadj); + dev_dbg(mmc_dev(host->mmc), "sdhc_idelay_val %d\n", + phy->settings.sdhc_idelay_val); + dev_dbg(mmc_dev(host->mmc), "sdhc_rdcmd_en %d\n", + phy->settings.sdhc_rdcmd_en); + dev_dbg(mmc_dev(host->mmc), "sdhc_rddata_en %d\n", + phy->settings.sdhc_rddata_en); + dev_dbg(mmc_dev(host->mmc), "sdhc_rw_compensate %d\n", + phy->settings.sdhc_rw_compensate); + dev_dbg(mmc_dev(host->mmc), "sdhc_sdcfsh %d\n", + phy->settings.sdhc_sdcfsh); + dev_dbg(mmc_dev(host->mmc), "sdhc_sdcfsl %d\n", + phy->settings.sdhc_sdcfsl); + dev_dbg(mmc_dev(host->mmc), "sdhc_wrcmd0_dly %d %d\n", + phy->settings.sdhc_wrcmd0_dly, + phy->settings.sdhc_wrcmd0_sdclk_dly); + dev_dbg(mmc_dev(host->mmc), "sdhc_wrcmd1_dly %d %d\n", + phy->settings.sdhc_wrcmd1_dly, + phy->settings.sdhc_wrcmd1_sdclk_dly); + dev_dbg(mmc_dev(host->mmc), "sdhc_wrdata0_dly %d %d\n", + phy->settings.sdhc_wrdata0_dly, + phy->settings.sdhc_wrdata0_sdclk_dly); + + dev_dbg(mmc_dev(host->mmc), "sdhc_wrdata1_dly %d %d\n", + phy->settings.sdhc_wrdata1_dly, + phy->settings.sdhc_wrdata1_sdclk_dly); + dev_dbg(mmc_dev(host->mmc), "hs200_tune_val %d\n", + phy->settings.hs200_tune_val); +} + +static +void sdhci_cdns_sd6_dump(struct sdhci_cdns_priv *priv, struct sdhci_host *host) +{ + struct sdhci_cdns_sd6_phy *phy = priv->phy; + int id; + + sdhci_cdns_sd6_phy_dump(phy); + + dev_dbg(mmc_dev(host->mmc), "Host controller Register Dump\n"); + for (id = 0; id < 14; id++) { + dev_dbg(mmc_dev(host->mmc), "HRS%d 0x%x\n", id, + readl(priv->hrs_addr + (id * 4))); + } + + id = 29; + dev_dbg(mmc_dev(host->mmc), "HRS%d 0x%x\n", id, + readl(priv->hrs_addr + (id * 4))); + id = 30; + dev_dbg(mmc_dev(host->mmc), "HRS%d 0x%x\n", id, + readl(priv->hrs_addr + (id * 4))); + + for (id = 0; id < 27; id++) { + dev_dbg(mmc_dev(host->mmc), "SRS%d 0x%x\n", id, + readl(priv->hrs_addr + 0x200 + (id * 4))); + } + + dev_dbg(mmc_dev(host->mmc), "SDHCI_CDNS_SD6_PHY_DQS_TIMING 0x%x\n", + sdhci_cdns_sd6_read_phy_reg(priv, + SDHCI_CDNS_SD6_PHY_DQS_TIMING)); + dev_dbg(mmc_dev(host->mmc), "SDHCI_CDNS_SD6_PHY_GATE_LPBK 0x%x\n", + sdhci_cdns_sd6_read_phy_reg(priv, + SDHCI_CDNS_SD6_PHY_GATE_LPBK)); + dev_dbg(mmc_dev(host->mmc), "SDHCI_CDNS_SD6_PHY_DLL_MASTER 0x%x\n", + sdhci_cdns_sd6_read_phy_reg(priv, + SDHCI_CDNS_SD6_PHY_DLL_MASTER)); + dev_dbg(mmc_dev(host->mmc), "SDHCI_CDNS_SD6_PHY_DLL_SLAVE 0x%x\n", + sdhci_cdns_sd6_read_phy_reg(priv, + SDHCI_CDNS_SD6_PHY_DLL_SLAVE)); + dev_dbg(mmc_dev(host->mmc), "SDHCI_CDNS_SD6_PHY_CTRL 0x%x\n", + sdhci_cdns_sd6_read_phy_reg(priv, SDHCI_CDNS_SD6_PHY_CTRL)); + dev_dbg(mmc_dev(host->mmc), "SDHCI_CDNS_SD6_PHY_GPIO_CTRL0 0x%x\n", + sdhci_cdns_sd6_read_phy_reg(priv, + SDHCI_CDNS_SD6_PHY_GPIO_CTRL0)); + dev_dbg(mmc_dev(host->mmc), "SDHCI_CDNS_SD6_PHY_DQ_TIMING 0x%x\n", + sdhci_cdns_sd6_read_phy_reg(priv, + SDHCI_CDNS_SD6_PHY_DQ_TIMING)); + dev_dbg(mmc_dev(host->mmc), "SDHCI_CDNS_SD6_PHY_DLL_OBS_REG0 0x%x\n", + sdhci_cdns_sd6_read_phy_reg(priv, + SDHCI_CDNS_SD6_PHY_DLL_OBS_REG0)); + dev_dbg(mmc_dev(host->mmc), "SDHCI_CDNS_SD6_PHY_DLL_OBS_REG1 0x%x\n", + sdhci_cdns_sd6_read_phy_reg(priv, + SDHCI_CDNS_SD6_PHY_DLL_OBS_REG1)); + dev_dbg(mmc_dev(host->mmc), "SDHCI_CDNS_SD6_PHY_DLL_OBS_REG2 0x%x\n", + sdhci_cdns_sd6_read_phy_reg(priv, + SDHCI_CDNS_SD6_PHY_DLL_OBS_REG2)); +} + +#else + +static inline void sdhci_cdns_sd6_dump(struct sdhci_cdns_priv *priv, + struct sdhci_host *host) +{ +} + +#endif + static int sdhci_cdns_sd6_get_delay_params(struct device *dev, struct sdhci_cdns_priv *priv) @@ -1322,6 +1474,8 @@ static void sdhci_cdns_sd6_set_clock(struct sdhci_host *host, pr_debug("%s: phy init failed\n", __func__); sdhci_set_clock(host, clock); + + sdhci_cdns_sd6_dump(priv, host); } static int sdhci_cdns_sd4_phy_probe(struct platform_device *pdev,