From patchwork Tue Jun 18 08:38:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen Wang X-Patchwork-Id: 13701967 Received: from mail-oi1-f177.google.com (mail-oi1-f177.google.com [209.85.167.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 01D0D1AD9E8; Tue, 18 Jun 2024 08:38:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718699899; cv=none; b=YC4KNLMmmClH2sDeHSOdxODrMDar3kF1zgCcBa5ZzYLFWUvOcXnkwVr0Q8vw7MMzf/XFW3xwE5ZNe9OxmRJUWY2ySyW7lTnfY+RCljNT7KPUNjBwwypQS0zeRYCLGZZf9h8CrsPb9ALBrgYgeiCIXonNmK8c6brNd+ldjBK6WuU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718699899; c=relaxed/simple; bh=zGrVELegxTwYpE7Tx2HLj3k3s07G0g/aLTZLafMtzCA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=He+t0HijhcjCLN6H3OZDHLjwfbQEYKaj5Hbe+xwgKGRJ8+f8k2CuBdapqwjwWxEnunsV6aNeIp/P+79JFFAbTk/zyKWhD8IKeKdSD4PtLUlRM5V5sAC/ECKhuNZSvKMnn7rPUsgWkbmmlzNw6V6e0zk1n8yGzC5FCqQgYDRqGXg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VkAvAj46; arc=none smtp.client-ip=209.85.167.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VkAvAj46" Received: by mail-oi1-f177.google.com with SMTP id 5614622812f47-3d518cdb252so2561b6e.1; Tue, 18 Jun 2024 01:38:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718699897; x=1719304697; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ECThPbcvOu3FHd4BdiepiF51r0sj/i4bV2Q+q/uVMzo=; b=VkAvAj46/cYNqGCT6viY5U+NP8TCwKakV2lkJroLO+2NZmn1FcBJ3TJemKVniyZRrY wFHGbmLxB7VAwsDmFw/wMSrFM0hJPrP5ejWtChMbpeUMokHsITIrQcf2361SY42DSAdn 8XcHy9+i4giXgNbxXpKIh8Ko+D9eC+nlwEVhiQ+frT761K2Sy7j24WNSdeyScejcxZmO 71vXDDQPGXHwV+sNcALhRV/uoQm9AVrfA10faOldYhsp69LG/6/ZywdhrcwVa8n1M2fD 4OhfIoXDjyaQ5p0HytQIPMlwnpa5t9K0a87CNFLWHQbzxN5k5sjVusu46UXkSOWXcWMM dxuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718699897; x=1719304697; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ECThPbcvOu3FHd4BdiepiF51r0sj/i4bV2Q+q/uVMzo=; b=dequpnzNMLGnzE2p4vIICkXA/0htd2EvLL83utHRRG3IIZqgvffh0gk0jMeECPSVWh AI+DvSrhQ9gsNMeOxLd+PDikbAZcprn0VX2WrmeIUfOD9DaaqVqHU1RbBuhgzkJmCQUI GO9B98HRd2tKZuOtJBvTW18oZiUvJRUHUhYbsrPtIY//3fDHiROlKiHZsJj841Q2MHsl F5iHqCP14H97tXMMxco02o8XZWF++6p0MWFAUlmoOxrDopUlCZIdSgaDSGE6YVU8/JM7 3lOEDXIW0QklauKLK3D0xmITqw+xNLMn+hjOpt339p5i6lAstCUeFeTkbtgYRie63T5C Wrwg== X-Forwarded-Encrypted: i=1; AJvYcCWCgpTTiF6eJ7HKQjWwaXSkPMBFi94A08+isplzSWyEl4kyYmC9cvjgwbnUESfCUH5eHYDDv9rWw6yD7kT5Wq3PCVlbV/G5nqUT/Y7EmSGImPDcvh0thr4mAl2QLZvr0mCzem0Qo7oiIoKpXvilPdp+24/V4fagbCXLnux+T/KYEtfB6A== X-Gm-Message-State: AOJu0YwF+hbt3xYkg49pBWmZ8sjX8mRmhr5VYZRc/8uYmPMjbM16JRh9 JE/k/LmtYYYTslzCQAcw50FO2nj5a2xaYnEXKkXX8xzneE6ROnX6 X-Google-Smtp-Source: AGHT+IFe4JbigvdCClcJUDzutBVbMosAkqtbwNRTXz9wf52wHFboWcMvUCsbYnrbLhw4n/YKXXSZUQ== X-Received: by 2002:a05:6808:2395:b0:3d2:212e:71a0 with SMTP id 5614622812f47-3d24e8a7272mr12677407b6e.6.1718699896874; Tue, 18 Jun 2024 01:38:16 -0700 (PDT) Received: from localhost.localdomain ([122.8.183.87]) by smtp.gmail.com with ESMTPSA id 5614622812f47-3d2476e37d0sm1729951b6e.51.2024.06.18.01.38.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jun 2024 01:38:15 -0700 (PDT) From: Chen Wang To: adrian.hunter@intel.com, aou@eecs.berkeley.edu, conor+dt@kernel.org, guoren@kernel.org, inochiama@outlook.com, jszhang@kernel.org, krzysztof.kozlowski+dt@linaro.org, palmer@dabbelt.com, paul.walmsley@sifive.com, robh@kernel.org, ulf.hansson@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-riscv@lists.infradead.org, chao.wei@sophgo.com, haijiao.liu@sophgo.com, xiaoguang.xing@sophgo.com, tingzhu.wang@sophgo.com Cc: Chen Wang Subject: [PATCH v4 1/4] mmc: sdhci-of-dwcmshc: add callback functions for dwcmshc Date: Tue, 18 Jun 2024 16:38:07 +0800 Message-Id: <8d13fcec6059b640dc126def05515ca582542c11.1718697954.git.unicorn_wang@outlook.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-mmc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Chen Wang The current framework is not easily extended to support new SOCs. For example, in the current code we see that the SOC-level structure `rk35xx_priv` and related logic are distributed in functions such as dwcmshc_probe/dwcmshc_remove/dwcmshc_suspend/......, which is inappropriate. The solution is to abstract some possible common operations of soc as dwcmshc platform data. Each soc implements the corresponding callback function according to its own needs. dwcmshc framework is responsible for calling these callback functions in those dwcmshc_xxx functions at proper positions. Signed-off-by: Chen Wang --- drivers/mmc/host/sdhci-of-dwcmshc.c | 327 ++++++++++++++++------------ 1 file changed, 184 insertions(+), 143 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index e79aa4b3b6c3..f6d6903a0e36 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -206,6 +206,7 @@ struct rk35xx_priv { u8 txclk_tapnum; }; +struct dwcmshc_pltfm_data; struct dwcmshc_priv { struct clk *bus_clk; int vendor_specific_area1; /* P_VENDOR_SPECIFIC_AREA1 reg */ @@ -214,6 +215,16 @@ struct dwcmshc_priv { void *priv; /* pointer to SoC private stuff */ u16 delay_line; u16 flags; + + const struct dwcmshc_pltfm_data *pltfm_data; +}; + +struct dwcmshc_pltfm_data { + const struct sdhci_pltfm_data pdata; + int (*init)(struct device *dev, struct sdhci_host *host, struct dwcmshc_priv *dwc_priv); + void (*postinit)(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv); + int (*clks_enable)(struct dwcmshc_priv *dwc_priv); + void (*clks_disable)(struct dwcmshc_priv *dwc_priv); }; /* @@ -681,6 +692,92 @@ static void rk35xx_sdhci_reset(struct sdhci_host *host, u8 mask) sdhci_reset(host, mask); } +static int dwcmshc_rk35xx_init(struct device *dev, struct sdhci_host *host, + struct dwcmshc_priv *dwc_priv) +{ + int err; + struct rk35xx_priv *priv; + + priv = devm_kzalloc(dev, sizeof(struct rk35xx_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + if (of_device_is_compatible(dev->of_node, "rockchip,rk3588-dwcmshc")) + priv->devtype = DWCMSHC_RK3588; + else + priv->devtype = DWCMSHC_RK3568; + + priv->reset = devm_reset_control_array_get_optional_exclusive(mmc_dev(host->mmc)); + if (IS_ERR(priv->reset)) { + err = PTR_ERR(priv->reset); + dev_err(mmc_dev(host->mmc), "failed to get reset control %d\n", err); + return err; + } + + priv->rockchip_clks[0].id = "axi"; + priv->rockchip_clks[1].id = "block"; + priv->rockchip_clks[2].id = "timer"; + err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), RK35xx_MAX_CLKS, + priv->rockchip_clks); + if (err) { + dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err); + return err; + } + + err = clk_bulk_prepare_enable(RK35xx_MAX_CLKS, priv->rockchip_clks); + if (err) { + dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err); + return err; + } + + if (of_property_read_u8(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum", + &priv->txclk_tapnum)) + priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT; + + /* Disable cmd conflict check */ + sdhci_writel(host, 0x0, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3); + /* Reset previous settings */ + sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK); + sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_STRBIN); + + dwc_priv->priv = priv; + + return 0; +} + +static void dwcmshc_rk35xx_postinit(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv) +{ + /* + * Don't support highspeed bus mode with low clk speed as we + * cannot use DLL for this condition. + */ + if (host->mmc->f_max <= 52000000) { + dev_info(mmc_dev(host->mmc), "Disabling HS200/HS400, frequency too low (%d)\n", + host->mmc->f_max); + host->mmc->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400); + host->mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR); + } +} + +static int rk35xx_clks_enable(struct dwcmshc_priv *dwc_priv) +{ + struct rk35xx_priv *priv = dwc_priv->priv; + int ret = 0; + + if (priv) + ret = clk_bulk_prepare_enable(RK35xx_MAX_CLKS, priv->rockchip_clks); + return ret; +} + +static void rk35xx_clks_disable(struct dwcmshc_priv *dwc_priv) +{ + struct rk35xx_priv *priv = dwc_priv->priv; + + if (priv) + clk_bulk_disable_unprepare(RK35xx_MAX_CLKS, + priv->rockchip_clks); +} + static int th1520_execute_tuning(struct sdhci_host *host, u32 opcode) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -755,6 +852,35 @@ static void th1520_sdhci_reset(struct sdhci_host *host, u8 mask) } } +static int th1520_init(struct device *dev, + struct sdhci_host *host, + struct dwcmshc_priv *dwc_priv) +{ + dwc_priv->delay_line = PHY_SDCLKDL_DC_DEFAULT; + + if (device_property_read_bool(dev, "mmc-ddr-1_8v") || + device_property_read_bool(dev, "mmc-hs200-1_8v") || + device_property_read_bool(dev, "mmc-hs400-1_8v")) + dwc_priv->flags |= FLAG_IO_FIXED_1V8; + else + dwc_priv->flags &= ~FLAG_IO_FIXED_1V8; + + /* + * start_signal_voltage_switch() will try 3.3V first + * then 1.8V. Use SDHCI_SIGNALING_180 rather than + * SDHCI_SIGNALING_330 to avoid setting voltage to 3.3V + * in sdhci_start_signal_voltage_switch(). + */ + if (dwc_priv->flags & FLAG_IO_FIXED_1V8) { + host->flags &= ~SDHCI_SIGNALING_330; + host->flags |= SDHCI_SIGNALING_180; + } + + sdhci_enable_v4_mode(host); + + return 0; +} + static void cv18xx_sdhci_reset(struct sdhci_host *host, u8 mask) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -932,39 +1058,54 @@ static const struct sdhci_ops sdhci_dwcmshc_cv18xx_ops = { .platform_execute_tuning = cv18xx_sdhci_execute_tuning, }; -static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { - .ops = &sdhci_dwcmshc_ops, - .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, +static const struct dwcmshc_pltfm_data sdhci_dwcmshc_pdata = { + .pdata = { + .ops = &sdhci_dwcmshc_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + }, }; #ifdef CONFIG_ACPI -static const struct sdhci_pltfm_data sdhci_dwcmshc_bf3_pdata = { - .ops = &sdhci_dwcmshc_ops, - .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | - SDHCI_QUIRK2_ACMD23_BROKEN, +static const struct dwcmshc_pltfm_data sdhci_dwcmshc_bf3_pdata = { + .pdata = { + .ops = &sdhci_dwcmshc_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_ACMD23_BROKEN, + }, }; #endif -static const struct sdhci_pltfm_data sdhci_dwcmshc_rk35xx_pdata = { - .ops = &sdhci_dwcmshc_rk35xx_ops, - .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | - SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | - SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, +static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk35xx_pdata = { + .pdata = { + .ops = &sdhci_dwcmshc_rk35xx_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, + }, + .init = dwcmshc_rk35xx_init, + .postinit = dwcmshc_rk35xx_postinit, + .clks_enable = rk35xx_clks_enable, + .clks_disable = rk35xx_clks_disable, }; -static const struct sdhci_pltfm_data sdhci_dwcmshc_th1520_pdata = { - .ops = &sdhci_dwcmshc_th1520_ops, - .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, +static const struct dwcmshc_pltfm_data sdhci_dwcmshc_th1520_pdata = { + .pdata = { + .ops = &sdhci_dwcmshc_th1520_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + }, + .init = th1520_init, }; -static const struct sdhci_pltfm_data sdhci_dwcmshc_cv18xx_pdata = { - .ops = &sdhci_dwcmshc_cv18xx_ops, - .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, +static const struct dwcmshc_pltfm_data sdhci_dwcmshc_cv18xx_pdata = { + .pdata = { + .ops = &sdhci_dwcmshc_cv18xx_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + }, }; static const struct cqhci_host_ops dwcmshc_cqhci_ops = { @@ -1034,61 +1175,6 @@ static void dwcmshc_cqhci_init(struct sdhci_host *host, struct platform_device * host->mmc->caps2 &= ~(MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD); } -static int dwcmshc_rk35xx_init(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv) -{ - int err; - struct rk35xx_priv *priv = dwc_priv->priv; - - priv->reset = devm_reset_control_array_get_optional_exclusive(mmc_dev(host->mmc)); - if (IS_ERR(priv->reset)) { - err = PTR_ERR(priv->reset); - dev_err(mmc_dev(host->mmc), "failed to get reset control %d\n", err); - return err; - } - - priv->rockchip_clks[0].id = "axi"; - priv->rockchip_clks[1].id = "block"; - priv->rockchip_clks[2].id = "timer"; - err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), RK35xx_MAX_CLKS, - priv->rockchip_clks); - if (err) { - dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err); - return err; - } - - err = clk_bulk_prepare_enable(RK35xx_MAX_CLKS, priv->rockchip_clks); - if (err) { - dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err); - return err; - } - - if (of_property_read_u8(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum", - &priv->txclk_tapnum)) - priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT; - - /* Disable cmd conflict check */ - sdhci_writel(host, 0x0, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3); - /* Reset previous settings */ - sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK); - sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_STRBIN); - - return 0; -} - -static void dwcmshc_rk35xx_postinit(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv) -{ - /* - * Don't support highspeed bus mode with low clk speed as we - * cannot use DLL for this condition. - */ - if (host->mmc->f_max <= 52000000) { - dev_info(mmc_dev(host->mmc), "Disabling HS200/HS400, frequency too low (%d)\n", - host->mmc->f_max); - host->mmc->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400); - host->mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR); - } -} - static const struct of_device_id sdhci_dwcmshc_dt_ids[] = { { .compatible = "rockchip,rk3588-dwcmshc", @@ -1135,8 +1221,7 @@ static int dwcmshc_probe(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host; struct sdhci_host *host; struct dwcmshc_priv *priv; - struct rk35xx_priv *rk_priv = NULL; - const struct sdhci_pltfm_data *pltfm_data; + const struct dwcmshc_pltfm_data *pltfm_data; int err; u32 extra, caps; @@ -1146,7 +1231,7 @@ static int dwcmshc_probe(struct platform_device *pdev) return -ENODEV; } - host = sdhci_pltfm_init(pdev, pltfm_data, + host = sdhci_pltfm_init(pdev, &pltfm_data->pdata, sizeof(struct dwcmshc_priv)); if (IS_ERR(host)) return PTR_ERR(host); @@ -1161,6 +1246,7 @@ static int dwcmshc_probe(struct platform_device *pdev) pltfm_host = sdhci_priv(host); priv = sdhci_pltfm_priv(pltfm_host); + priv->pltfm_data = pltfm_data; if (dev->of_node) { pltfm_host->clk = devm_clk_get(dev, "core"); @@ -1191,49 +1277,12 @@ static int dwcmshc_probe(struct platform_device *pdev) host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe; host->mmc_host_ops.execute_tuning = dwcmshc_execute_tuning; - if (pltfm_data == &sdhci_dwcmshc_rk35xx_pdata) { - rk_priv = devm_kzalloc(&pdev->dev, sizeof(struct rk35xx_priv), GFP_KERNEL); - if (!rk_priv) { - err = -ENOMEM; - goto err_clk; - } - - if (of_device_is_compatible(pdev->dev.of_node, "rockchip,rk3588-dwcmshc")) - rk_priv->devtype = DWCMSHC_RK3588; - else - rk_priv->devtype = DWCMSHC_RK3568; - - priv->priv = rk_priv; - - err = dwcmshc_rk35xx_init(host, priv); + if (pltfm_data->init) { + err = pltfm_data->init(&pdev->dev, host, priv); if (err) goto err_clk; } - if (pltfm_data == &sdhci_dwcmshc_th1520_pdata) { - priv->delay_line = PHY_SDCLKDL_DC_DEFAULT; - - if (device_property_read_bool(dev, "mmc-ddr-1_8v") || - device_property_read_bool(dev, "mmc-hs200-1_8v") || - device_property_read_bool(dev, "mmc-hs400-1_8v")) - priv->flags |= FLAG_IO_FIXED_1V8; - else - priv->flags &= ~FLAG_IO_FIXED_1V8; - - /* - * start_signal_voltage_switch() will try 3.3V first - * then 1.8V. Use SDHCI_SIGNALING_180 rather than - * SDHCI_SIGNALING_330 to avoid setting voltage to 3.3V - * in sdhci_start_signal_voltage_switch(). - */ - if (priv->flags & FLAG_IO_FIXED_1V8) { - host->flags &= ~SDHCI_SIGNALING_330; - host->flags |= SDHCI_SIGNALING_180; - } - - sdhci_enable_v4_mode(host); - } - #ifdef CONFIG_ACPI if (pltfm_data == &sdhci_dwcmshc_bf3_pdata) sdhci_enable_v4_mode(host); @@ -1261,8 +1310,8 @@ static int dwcmshc_probe(struct platform_device *pdev) dwcmshc_cqhci_init(host, pdev); } - if (rk_priv) - dwcmshc_rk35xx_postinit(host, priv); + if (pltfm_data->postinit) + pltfm_data->postinit(host, priv); err = __sdhci_add_host(host); if (err) @@ -1280,9 +1329,8 @@ static int dwcmshc_probe(struct platform_device *pdev) err_clk: clk_disable_unprepare(pltfm_host->clk); clk_disable_unprepare(priv->bus_clk); - if (rk_priv) - clk_bulk_disable_unprepare(RK35xx_MAX_CLKS, - rk_priv->rockchip_clks); + if (pltfm_data->clks_disable) + pltfm_data->clks_disable(priv); free_pltfm: sdhci_pltfm_free(pdev); return err; @@ -1304,7 +1352,6 @@ static void dwcmshc_remove(struct platform_device *pdev) struct sdhci_host *host = platform_get_drvdata(pdev); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host); - struct rk35xx_priv *rk_priv = priv->priv; pm_runtime_get_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -1316,9 +1363,8 @@ static void dwcmshc_remove(struct platform_device *pdev) clk_disable_unprepare(pltfm_host->clk); clk_disable_unprepare(priv->bus_clk); - if (rk_priv) - clk_bulk_disable_unprepare(RK35xx_MAX_CLKS, - rk_priv->rockchip_clks); + if (priv->pltfm_data->clks_disable) + priv->pltfm_data->clks_disable(priv); sdhci_pltfm_free(pdev); } @@ -1328,7 +1374,6 @@ static int dwcmshc_suspend(struct device *dev) struct sdhci_host *host = dev_get_drvdata(dev); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host); - struct rk35xx_priv *rk_priv = priv->priv; int ret; pm_runtime_resume(dev); @@ -1347,9 +1392,8 @@ static int dwcmshc_suspend(struct device *dev) if (!IS_ERR(priv->bus_clk)) clk_disable_unprepare(priv->bus_clk); - if (rk_priv) - clk_bulk_disable_unprepare(RK35xx_MAX_CLKS, - rk_priv->rockchip_clks); + if (priv->pltfm_data->clks_disable) + priv->pltfm_data->clks_disable(priv); return ret; } @@ -1359,7 +1403,6 @@ static int dwcmshc_resume(struct device *dev) struct sdhci_host *host = dev_get_drvdata(dev); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host); - struct rk35xx_priv *rk_priv = priv->priv; int ret; ret = clk_prepare_enable(pltfm_host->clk); @@ -1372,29 +1415,27 @@ static int dwcmshc_resume(struct device *dev) goto disable_clk; } - if (rk_priv) { - ret = clk_bulk_prepare_enable(RK35xx_MAX_CLKS, - rk_priv->rockchip_clks); + if (priv->pltfm_data->clks_enable) { + ret = priv->pltfm_data->clks_enable(priv); if (ret) goto disable_bus_clk; } ret = sdhci_resume_host(host); if (ret) - goto disable_rockchip_clks; + goto disable_soc_clks; if (host->mmc->caps2 & MMC_CAP2_CQE) { ret = cqhci_resume(host->mmc); if (ret) - goto disable_rockchip_clks; + goto disable_soc_clks; } return 0; -disable_rockchip_clks: - if (rk_priv) - clk_bulk_disable_unprepare(RK35xx_MAX_CLKS, - rk_priv->rockchip_clks); +disable_soc_clks: + if (priv->pltfm_data->clks_disable) + priv->pltfm_data->clks_disable(priv); disable_bus_clk: if (!IS_ERR(priv->bus_clk)) clk_disable_unprepare(priv->bus_clk); From patchwork Tue Jun 18 08:38:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen Wang X-Patchwork-Id: 13701968 Received: from mail-ot1-f48.google.com (mail-ot1-f48.google.com [209.85.210.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 326EB1AED3A; Tue, 18 Jun 2024 08:38:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718699921; cv=none; b=ekjeRBQYXt/rta9S4SxUXoZtuza9pk9Y1JMqch1+CZPsagdTcDCnrf8R+IrpA3pDgyGmiE7nGotG+mnnALdpufRhWMynDot1PSnANkOLvBLZq768Ts2X+CDXwElM1oK/rFu97VhjmojlNjyL479ZJvPHJqWTK7Emp9NuLTxHhsg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718699921; c=relaxed/simple; bh=B+llYKiMHvIXBuJSTjGy7QGQWVdZRavexk8e4cQMxWA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UUc8wuNeeQE2oqVm39ykwPkx5JkOIPNz0InoQoxTUwUZV9vdTtLiMugfmaQV3eCxzPSPRCJ/wXimHLtRHO/LaAbGAgXjACaf1sSXX1Z8Vao0EPvGc+RTl1OemqpVQprGJEqAgcpCgVOyOe/0MsWpb5QbPfcaeAqhoFGwQ0rxmQE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FKTjJ2LL; arc=none smtp.client-ip=209.85.210.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FKTjJ2LL" Received: by mail-ot1-f48.google.com with SMTP id 46e09a7af769-6fa11ac8695so2917787a34.3; Tue, 18 Jun 2024 01:38:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718699919; x=1719304719; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=f1GjDUQ3o3b4+jeUyqmth+0z9OUp8eftPqc5a3xc1TU=; b=FKTjJ2LLTLr/pXCYTlBZ+8SYs4VHTtPRdN9Pbn9N0J1UjnfJv/m+QQqSEGyQLddMgD AC4/PvX82YcFqBzYgmjwWKmnG8GNq+UdaG4rNyQjF8zfbh1nKiXgZEVC4qYlMHRktNT8 5DS8qCpR94s4ksB0RBtcCqVcsQ4w3px0NwVgHB31c/QLMoEj2jJUlU4WTqm8D8QAXUNt QGY5caah0AecYcHi6npH0o0ZDjBHrjYNXwuPOVM65SQYbag2Dsfq/Q90nLFCjP5p0Mu0 rUjrKzJ27Hy2Shg+OOzcJ299xvbBvHzDaAOcZni6LsQhz9jbWRLzn5uxnXaQ56JDB/Sm xuYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718699919; x=1719304719; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=f1GjDUQ3o3b4+jeUyqmth+0z9OUp8eftPqc5a3xc1TU=; b=hf29OjZxNBNEHVw2toYtlUR6a5nJDxZAMEqrSfyA4x1uPTTsTailTcC4IVwdul6xXS gL+fEm7AFK74NRXCtZJWQ1aslRsOkc7HyDwevOTrGtKl2sItLwMS6r54H5XcaraGmFrf dUhBkNoz3BjvpicVe+Jvm9Fv0s8JMSrgTfAlg7rLK2WonCp5xdVGdm3ajnqa1AVzMNMa FqxmQyYdxIOt4CzGJtHq7IsinZGoZ+lfqhAuVYbc65CETaohI6/29/c18CyWkgYtxRRF KD9cfi39KbSjFOUE5k5fWrh32qakV/tKkMim1b0LUJhzzxJ0RyS8/axTc77uo4+1vjxK JrVw== X-Forwarded-Encrypted: i=1; AJvYcCUPLDwShqQnGFSg6Ii5F4X+8kwODdEMG3Vh8i5YtbvuvtDBvjfPTdcrnPvDtOEg05ehOaKMiApyOLwlqzhyTHGgP1nhuwa4mF7ampQ+sGU9JQ1+0IzLd4za4SOMPhMfH0gjh2H4iv0jijCuB8kpLMRw/CktGVtvXSdIzD1sB92/hiKV4Q== X-Gm-Message-State: AOJu0YzRZeOT/Vtz9TPMeVo37zwyCtGh1JJjHv1t/PVYit/xJUevjqZW Weq3GknX0M0QWjWVIDU6xzILVVQ5+Kev9s1jy5rR/IjTycV+3rx49Rn3uIFw X-Google-Smtp-Source: AGHT+IFALoxJytTixSUwVOhyfDsBA+wYcZg2xiod4lujmIbAlaE/efLxS/7TXcwcLL+d05UFBkl5gw== X-Received: by 2002:a05:6830:1e70:b0:6f9:f231:3909 with SMTP id 46e09a7af769-6fb939f0984mr12894884a34.29.1718699919166; Tue, 18 Jun 2024 01:38:39 -0700 (PDT) Received: from localhost.localdomain ([122.8.183.87]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-6fb5b1b0bd9sm1779441a34.27.2024.06.18.01.38.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jun 2024 01:38:37 -0700 (PDT) From: Chen Wang To: adrian.hunter@intel.com, aou@eecs.berkeley.edu, conor+dt@kernel.org, guoren@kernel.org, inochiama@outlook.com, jszhang@kernel.org, krzysztof.kozlowski+dt@linaro.org, palmer@dabbelt.com, paul.walmsley@sifive.com, robh@kernel.org, ulf.hansson@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-riscv@lists.infradead.org, chao.wei@sophgo.com, haijiao.liu@sophgo.com, xiaoguang.xing@sophgo.com, tingzhu.wang@sophgo.com Cc: Chen Wang Subject: [PATCH v4 2/4] dt-bindings: mmc: sdhci-of-dwcmhsc: Add Sophgo SG2042 support Date: Tue, 18 Jun 2024 16:38:30 +0800 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-mmc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Chen Wang SG2042 use Synopsys dwcnshc IP for SD/eMMC controllers. SG2042 defines 3 clocks for SD/eMMC controllers. - AXI_EMMC/AXI_SD for aclk/hclk(Bus interface clocks in DWC_mshc) and blck(Core Base Clock in DWC_mshc), these 3 clocks share one source, so reuse existing "core". - 100K_EMMC/100K_SD for cqetmclk(Timer clocks in DWC_mshc), so reuse existing "timer" which was added for rockchip specified. - EMMC_100M/SD_100M for cclk(Card clocks in DWC_mshc), add new "card". Adding example for sg2042. Signed-off-by: Chen Wang --- .../bindings/mmc/snps,dwcmshc-sdhci.yaml | 69 +++++++++++++------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml b/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml index 4d3031d9965f..b53f20733f79 100644 --- a/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml @@ -21,6 +21,7 @@ properties: - snps,dwcmshc-sdhci - sophgo,cv1800b-dwcmshc - sophgo,sg2002-dwcmshc + - sophgo,sg2042-dwcmshc - thead,th1520-dwcmshc reg: @@ -29,25 +30,6 @@ properties: interrupts: maxItems: 1 - clocks: - minItems: 1 - items: - - description: core clock - - description: bus clock for optional - - description: axi clock for rockchip specified - - description: block clock for rockchip specified - - description: timer clock for rockchip specified - - - clock-names: - minItems: 1 - items: - - const: core - - const: bus - - const: axi - - const: block - - const: timer - resets: maxItems: 5 @@ -63,6 +45,43 @@ properties: description: Specify the number of delay for tx sampling. $ref: /schemas/types.yaml#/definitions/uint8 +if: + properties: + compatible: + contains: + const: sophgo,sg2042-dwcmshc +then: + properties: + clocks: + items: + - description: core clock + - description: timer clock + - description: card clock + + clock-names: + items: + - const: core + - const: timer + - const: card +else: + properties: + clocks: + minItems: 1 + items: + - description: core clock + - description: bus clock for optional + - description: axi clock for rockchip specified + - description: block clock for rockchip specified + - description: timer clock for rockchip specified + + clock-names: + minItems: 1 + items: + - const: core + - const: bus + - const: axi + - const: block + - const: timer required: - compatible @@ -96,5 +115,15 @@ examples: #address-cells = <1>; #size-cells = <0>; }; - + - | + mmc@bb0000 { + compatible = "sophgo,sg2042-dwcmshc"; + reg = <0xcc000 0x1000>; + interrupts = <0 25 0x4>; + clocks = <&cru 17>, <&cru 18>, <&cru 19>; + clock-names = "core", "timer", "card"; + bus-width = <8>; + #address-cells = <1>; + #size-cells = <0>; + }; ... From patchwork Tue Jun 18 08:38:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen Wang X-Patchwork-Id: 13701969 Received: from mail-ot1-f53.google.com (mail-ot1-f53.google.com [209.85.210.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A5B514F137; Tue, 18 Jun 2024 08:39:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718699949; cv=none; b=NSmxs5Z/n2cW/YXFDUWbnQvY9/pi8wWSadSsiyJXdc/qqERn8oF+oFm/0tyJOfO5Nhlk+9kE5AizBaHXokFptOT1NXo3ryg2UnYSvQmE11iMz9Va8MqA4AMFvdLgf+1wiiTIQmAG+bKnb+rceHgnZ1sE7ec3NVJkO76cYEer2/4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718699949; c=relaxed/simple; bh=ancHuUsk8egwqBOugu3wsD2p2kGqmq4p0h0LiYukHcs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=pChCizbG+NmR0zMn+de+WeDNTLQb3Gk4LyNy865y3+za4riQ1HGAd8Vg5tDGcilNE+0IcfCiPWR+yoTUDfG5PNYSlMXFZn1gcEemlo8k+eiDBvV1BiDhnhh67yQVh8kdgrsymf4f56PL+SW6Jax4qhIO7LztL2YnLTl3QgRGAVI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Vp+KEg0k; arc=none smtp.client-ip=209.85.210.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Vp+KEg0k" Received: by mail-ot1-f53.google.com with SMTP id 46e09a7af769-6f855b2499cso2870181a34.1; Tue, 18 Jun 2024 01:39:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718699946; x=1719304746; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fqNE9BQXbQMY9LnYcxBOu7BaOTd6cy5mJT0V1mtLz+0=; b=Vp+KEg0kJCtTCEWpBztbG1Wxd5P072WRjFxAsPV1nRjaeLQF7ID9J/v4y3j1mxM6lA H47Zf+Q13b/xpOokkGvaIxnWQYX922kDkyx3puOxblAkYENrUSK0KeGtxJIjpXTILAaD mCX1jfW8eJWZCR2N8ucP8lH9YQh9qTSr2FLqnBMLrcZFWwI8vVpY3DmzLxHXSZAG+yDO Iq1RrqMGHZu5RCIFG/QORb/by+ZNoWip6viHZS3WypitO0SHSaKHeMSlJulWXk7sq8Wp tX/FXxMwTeIwerDJt4MvDPrSP7H4T65gZuj81ZiPXaDvkCXGTx7rO0NXqhn6DSx0HDUn 8O3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718699946; x=1719304746; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fqNE9BQXbQMY9LnYcxBOu7BaOTd6cy5mJT0V1mtLz+0=; b=FvyqjUebUcmz5rNFN47kT1r+5nO789OOwOF9hizfaEFrRQzPfN1SI/US65hL1xR4zZ zhRqQa+N3yuMNDlIKFQ/M3DCuOQV7R/x6fO5jFV6NsQWdm1fZQf+s06IC2J3dY0XmQ9I MwHpZCazOLCrdJELIiDduD/vh/fG6wcHo1qmotoowaNVBkwkIl4XQszBLlAwPmWXdchH uiACY5LjRwgOy/ei18eb+S6sA5jS/H5xF+4yFpRZCJM6SUSw/A48xe4Dt+AubhhHVcl9 xl5sHOFXhcNbDRHwlTwU4WRL/7nNEHQeFL4UjL+6sx82CT2NCXT1PamWBddT9JHkWVx2 uMsA== X-Forwarded-Encrypted: i=1; AJvYcCUuHyTPmYJu+IXjULeJORU1fepQP7UgVL2dv/P/RSDuoinmmZMvL3QYgL507pZ1efodfsp8vmEoPq0IDJwYuKDNWKeWdTxaWt20InN1Luxw+C5Usaj41YEj1IlG/b7EeVc26mnMhjVqOSH75chAQnWKvJq9XMzJ7iy3g/uXTV/VpYIdDg== X-Gm-Message-State: AOJu0YwfpC2DKpHNc9eVAgkKkU53Pdb4O8boR9O8go+/CW6OyGbXEs4i X/KCHodfnynpW/9FxpDiOtronOuUqEv/jDUQ4hV4yA7K8jlSpjfK5XTv84V8 X-Google-Smtp-Source: AGHT+IFrDIzuSkJZBQmony515u1eRDgXxiL0D+F4Cidloyg3pJW1+8xd63nDB5YUb6XJE7T9z7viig== X-Received: by 2002:a9d:6d0c:0:b0:6fc:f2b:d45 with SMTP id 46e09a7af769-6fc0f2b0e49mr12815399a34.3.1718699946434; Tue, 18 Jun 2024 01:39:06 -0700 (PDT) Received: from localhost.localdomain ([122.8.183.87]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-6fb5afa9f62sm1779101a34.3.2024.06.18.01.39.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jun 2024 01:39:04 -0700 (PDT) From: Chen Wang To: adrian.hunter@intel.com, aou@eecs.berkeley.edu, conor+dt@kernel.org, guoren@kernel.org, inochiama@outlook.com, jszhang@kernel.org, krzysztof.kozlowski+dt@linaro.org, palmer@dabbelt.com, paul.walmsley@sifive.com, robh@kernel.org, ulf.hansson@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-riscv@lists.infradead.org, chao.wei@sophgo.com, haijiao.liu@sophgo.com, xiaoguang.xing@sophgo.com, tingzhu.wang@sophgo.com Cc: Chen Wang Subject: [PATCH v4 3/4] mmc: sdhci-of-dwcmshc: Add support for Sophgo SG2042 Date: Tue, 18 Jun 2024 16:38:56 +0800 Message-Id: <66af68e1c1be09fb3300ec0ed72acff752f7d799.1718697954.git.unicorn_wang@outlook.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-mmc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Chen Wang Add support for the mmc controller of Sophgo SG2042. SG2042 uses Synopsys PHY the same as TH1520 so we reuse the tuning logic from TH1520. Besides this, this patch implement some SG2042 specific work, such as clocks and reset ops. Signed-off-by: Chen Wang --- drivers/mmc/host/sdhci-of-dwcmshc.c | 172 ++++++++++++++++++++++++++-- 1 file changed, 165 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index f6d6903a0e36..e18a7f97c994 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -114,12 +114,15 @@ #define DWC_MSHC_PTR_PHY_R 0x300 /* PHY general configuration */ -#define PHY_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x00) -#define PHY_CNFG_RSTN_DEASSERT 0x1 /* Deassert PHY reset */ -#define PHY_CNFG_PAD_SP_MASK GENMASK(19, 16) /* bits [19:16] */ -#define PHY_CNFG_PAD_SP 0x0c /* PMOS TX drive strength */ -#define PHY_CNFG_PAD_SN_MASK GENMASK(23, 20) /* bits [23:20] */ -#define PHY_CNFG_PAD_SN 0x0c /* NMOS TX drive strength */ +#define PHY_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x00) +#define PHY_CNFG_RSTN_DEASSERT 0x1 /* Deassert PHY reset */ +#define PHY_CNFG_PHY_PWRGOOD_MASK BIT_MASK(1) /* bit [1] */ +#define PHY_CNFG_PAD_SP_MASK GENMASK(19, 16) /* bits [19:16] */ +#define PHY_CNFG_PAD_SP 0x0c /* PMOS TX drive strength */ +#define PHY_CNFG_PAD_SP_SG2042 0x09 /* PMOS TX drive strength for SG2042 */ +#define PHY_CNFG_PAD_SN_MASK GENMASK(23, 20) /* bits [23:20] */ +#define PHY_CNFG_PAD_SN 0x0c /* NMOS TX drive strength */ +#define PHY_CNFG_PAD_SN_SG2042 0x08 /* NMOS TX drive strength for SG2042 */ /* PHY command/response pad settings */ #define PHY_CMDPAD_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x04) @@ -148,10 +151,12 @@ #define PHY_PAD_TXSLEW_CTRL_P 0x3 /* Slew control for P-Type pad TX */ #define PHY_PAD_TXSLEW_CTRL_N_MASK GENMASK(12, 9) /* bits [12:9] */ #define PHY_PAD_TXSLEW_CTRL_N 0x3 /* Slew control for N-Type pad TX */ +#define PHY_PAD_TXSLEW_CTRL_N_SG2042 0x2 /* Slew control for N-Type pad TX for SG2042 */ /* PHY CLK delay line settings */ #define PHY_SDCLKDL_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x1d) -#define PHY_SDCLKDL_CNFG_UPDATE BIT(4) /* set before writing to SDCLKDL_DC */ +#define PHY_SDCLKDL_CNFG_EXTDLY_EN BIT(0) +#define PHY_SDCLKDL_CNFG_UPDATE BIT(4) /* set before writing to SDCLKDL_DC */ /* PHY CLK delay line delay code */ #define PHY_SDCLKDL_DC_R (DWC_MSHC_PTR_PHY_R + 0x1e) @@ -159,10 +164,14 @@ #define PHY_SDCLKDL_DC_DEFAULT 0x32 /* default delay code */ #define PHY_SDCLKDL_DC_HS400 0x18 /* delay code for HS400 mode */ +#define PHY_SMPLDL_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x20) +#define PHY_SMPLDL_CNFG_BYPASS_EN BIT(1) + /* PHY drift_cclk_rx delay line configuration setting */ #define PHY_ATDL_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x21) #define PHY_ATDL_CNFG_INPSEL_MASK GENMASK(3, 2) /* bits [3:2] */ #define PHY_ATDL_CNFG_INPSEL 0x3 /* delay line input source */ +#define PHY_ATDL_CNFG_INPSEL_SG2042 0x2 /* delay line input source for SG2042 */ /* PHY DLL control settings */ #define PHY_DLL_CTRL_R (DWC_MSHC_PTR_PHY_R + 0x24) @@ -206,6 +215,11 @@ struct rk35xx_priv { u8 txclk_tapnum; }; +#define SG2042_MAX_CLKS 2 +struct sg2042_priv { + struct clk_bulk_data clks[SG2042_MAX_CLKS]; +}; + struct dwcmshc_pltfm_data; struct dwcmshc_priv { struct clk *bus_clk; @@ -1017,6 +1031,125 @@ static int cv18xx_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) return ret; } +static inline void sg2042_sdhci_phy_init(struct sdhci_host *host) +{ + u32 val; + + /* Asset phy reset & set tx drive strength */ + val = sdhci_readl(host, PHY_CNFG_R); + val &= ~PHY_CNFG_RSTN_DEASSERT; + val |= FIELD_PREP(PHY_CNFG_PHY_PWRGOOD_MASK, 1); + val |= FIELD_PREP(PHY_CNFG_PAD_SP_MASK, PHY_CNFG_PAD_SP_SG2042); + val |= FIELD_PREP(PHY_CNFG_PAD_SN_MASK, PHY_CNFG_PAD_SN_SG2042); + sdhci_writel(host, val, PHY_CNFG_R); + + /* Configure phy pads */ + val = PHY_PAD_RXSEL_3V3; + val |= FIELD_PREP(PHY_PAD_WEAKPULL_MASK, PHY_PAD_WEAKPULL_PULLUP); + val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P); + val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N_SG2042); + sdhci_writew(host, val, PHY_CMDPAD_CNFG_R); + sdhci_writew(host, val, PHY_DATAPAD_CNFG_R); + sdhci_writew(host, val, PHY_RSTNPAD_CNFG_R); + + val = PHY_PAD_RXSEL_3V3; + val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P); + val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N_SG2042); + sdhci_writew(host, val, PHY_CLKPAD_CNFG_R); + + val = PHY_PAD_RXSEL_3V3; + val |= FIELD_PREP(PHY_PAD_WEAKPULL_MASK, PHY_PAD_WEAKPULL_PULLDOWN); + val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P); + val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N_SG2042); + sdhci_writew(host, val, PHY_STBPAD_CNFG_R); + + /* Configure delay line */ + /* Enable fixed delay */ + sdhci_writeb(host, PHY_SDCLKDL_CNFG_EXTDLY_EN, PHY_SDCLKDL_CNFG_R); + /* + * Set delay line. + * Its recommended that bit UPDATE_DC[4] is 1 when SDCLKDL_DC is being written. + * Ensure UPDATE_DC[4] is '0' when not updating code. + */ + val = sdhci_readb(host, PHY_SDCLKDL_CNFG_R); + val |= PHY_SDCLKDL_CNFG_UPDATE; + sdhci_writeb(host, val, PHY_SDCLKDL_CNFG_R); + /* Add 10 * 70ps = 0.7ns for output delay */ + sdhci_writeb(host, 10, PHY_SDCLKDL_DC_R); + val = sdhci_readb(host, PHY_SDCLKDL_CNFG_R); + val &= ~(PHY_SDCLKDL_CNFG_UPDATE); + sdhci_writeb(host, val, PHY_SDCLKDL_CNFG_R); + + /* Set SMPLDL_CNFG, Bypass */ + sdhci_writeb(host, PHY_SMPLDL_CNFG_BYPASS_EN, PHY_SMPLDL_CNFG_R); + + /* Set ATDL_CNFG, tuning clk not use for init */ + val = FIELD_PREP(PHY_ATDL_CNFG_INPSEL_MASK, PHY_ATDL_CNFG_INPSEL_SG2042); + sdhci_writeb(host, val, PHY_ATDL_CNFG_R); + + /* Deasset phy reset */ + val = sdhci_readl(host, PHY_CNFG_R); + val |= PHY_CNFG_RSTN_DEASSERT; + sdhci_writel(host, val, PHY_CNFG_R); +} + +static void sg2042_sdhci_reset(struct sdhci_host *host, u8 mask) +{ + sdhci_reset(host, mask); + + if (mask & SDHCI_RESET_ALL) + sg2042_sdhci_phy_init(host); +} + +static int sg2042_clks_enable(struct dwcmshc_priv *dwc_priv) +{ + int ret = 0; + struct sg2042_priv *soc = dwc_priv->priv; + + if (soc) + ret = clk_bulk_prepare_enable(SG2042_MAX_CLKS, soc->clks); + return ret; +} + +static void sg2042_clks_disable(struct dwcmshc_priv *dwc_priv) +{ + struct sg2042_priv *soc = dwc_priv->priv; + + if (soc) + clk_bulk_disable_unprepare(SG2042_MAX_CLKS, + soc->clks); +} + +static int sg2042_init(struct device *dev, struct sdhci_host *host, + struct dwcmshc_priv *dwc_priv) +{ + int err; + struct sg2042_priv *soc = NULL; + + soc = devm_kzalloc(dev, sizeof(struct sg2042_priv), GFP_KERNEL); + if (!soc) + return -ENOMEM; + + soc->clks[0].id = "card"; + soc->clks[1].id = "timer"; + err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), SG2042_MAX_CLKS, + soc->clks); + if (err) { + dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err); + return err; + } + + err = clk_bulk_prepare_enable(SG2042_MAX_CLKS, soc->clks); + if (err) { + dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err); + return err; + } + + dwc_priv->priv = soc; + + return 0; +} + static const struct sdhci_ops sdhci_dwcmshc_ops = { .set_clock = sdhci_set_clock, .set_bus_width = sdhci_set_bus_width, @@ -1066,6 +1199,16 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_pdata = { }, }; +static const struct sdhci_ops sdhci_dwcmshc_sg2042_ops = { + .set_clock = sdhci_set_clock, + .set_bus_width = sdhci_set_bus_width, + .set_uhs_signaling = dwcmshc_set_uhs_signaling, + .get_max_clock = dwcmshc_get_max_clock, + .reset = sg2042_sdhci_reset, + .adma_write_desc = dwcmshc_adma_write_desc, + .platform_execute_tuning = th1520_execute_tuning, +}; + #ifdef CONFIG_ACPI static const struct dwcmshc_pltfm_data sdhci_dwcmshc_bf3_pdata = { .pdata = { @@ -1108,6 +1251,17 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_cv18xx_pdata = { }, }; +static const struct dwcmshc_pltfm_data sdhci_dwcmshc_sg2042_pdata = { + .pdata = { + .ops = &sdhci_dwcmshc_sg2042_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + }, + .init = sg2042_init, + .clks_enable = sg2042_clks_enable, + .clks_disable = sg2042_clks_disable, +}; + static const struct cqhci_host_ops dwcmshc_cqhci_ops = { .enable = dwcmshc_sdhci_cqe_enable, .disable = sdhci_cqe_disable, @@ -1200,6 +1354,10 @@ static const struct of_device_id sdhci_dwcmshc_dt_ids[] = { .compatible = "thead,th1520-dwcmshc", .data = &sdhci_dwcmshc_th1520_pdata, }, + { + .compatible = "sophgo,sg2042-dwcmshc", + .data = &sdhci_dwcmshc_sg2042_pdata, + }, {}, }; MODULE_DEVICE_TABLE(of, sdhci_dwcmshc_dt_ids); From patchwork Tue Jun 18 08:39:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen Wang X-Patchwork-Id: 13701970 Received: from mail-ot1-f53.google.com (mail-ot1-f53.google.com [209.85.210.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C22281BF38; Tue, 18 Jun 2024 08:39:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718699972; cv=none; b=VZOanuChLmHO7HWKZvdK+sAY3rCrbTMg1I6b4ukTt5cwzemaFVi6Fjb4r9w+EXkzSU5+BLKzMJj67MMV+lK7MDrgWwNfIHg6rSMkQESDGHgYiTuSN4D53R9RKpp6hNz82lm7NA69qKPSo4MxrKJiePK5qU8kjYpJMmQTpqJ/qMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718699972; c=relaxed/simple; bh=WYq2OHBK0AdgEaVT9jkh0Es0lUwnAC4FuwB4yD1Lrnk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=j/nsrS7OT60kuBMH/OB8rHJTtvFKm8Bowq31lX1qzN4f+dWR/O8819HVBqgSRveU3DZypktqfmuwvLr3ImFdFgO7ykK7QE7ERjWnxtO6m50zz6dpQ6FFKlblr6ZdVDpb8ppiq+y20Nehpebo+awSwXDkVbqldYkKsWI1PqjIL+Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PPJk9Yyx; arc=none smtp.client-ip=209.85.210.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PPJk9Yyx" Received: by mail-ot1-f53.google.com with SMTP id 46e09a7af769-6f986b92acaso2973853a34.2; Tue, 18 Jun 2024 01:39:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718699970; x=1719304770; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fcoMCm+enNSGbUuJXoL2d96+fYWSHPTojOmLTIxiMc4=; b=PPJk9YyxdrgzyAPjoaudZS4nn30J56Yip3AZP7FPaPpJ3IZGpqxfzi5aWCNK/byuQI kaBzBxTH/TIyLtQiAnVgc8r0LTkAaGi6a70jt6anabW6AVmnY/Z7+KxQQeCrL5nlSx7B IwwQB9m8XNqX7zBT4O1miL/yToYXwFMtX3AKzq5mS1uS2sxZV/j0u7v4bNVtNOb5vwPW 5O2pW7AnYaUpH358eO9YfZbJB4bYeJQoWYU9Bu4gBICFglkxnNwh9HDy0S5OdfXj7DOR qEIRsFQfluiAN64IAoKpjv/iebNVHbobvZ01k93DqaGboB92lzPwN6PuuAnHQMIMI890 uOBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718699970; x=1719304770; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fcoMCm+enNSGbUuJXoL2d96+fYWSHPTojOmLTIxiMc4=; b=qtqxz4rVEZVvCa01wWRVFVbNtvo8tLJh3wbC/Itu0cZIvB2IXXHSbWt5h4M3zyWxqz XOfncTvQhWVwEJq0sEPly8ZCR2byY0eTPkQAhVSaD9YXG4hwXE9/nzUNaLoXDIySjYgX zoaOqFyNoAcIXWPrs/XcdG+6GFyctTBzzrpoTdZ5gnh5LvGnhCIGY0UqlU9Qym631wf2 iknDETBsIDzXqaQ9Oa44G1hO4niefIl3cjXgUC6PHGhyMgx/RWPCQW9bu2+5GM/vSS1p HwGXm7/NcScNhjXq3uZWTvhqICsqt9wmcX6IEZhbeJLaeLjHY7iyAvVqr66qgSWnrzt7 VbUw== X-Forwarded-Encrypted: i=1; AJvYcCWNnkasyr37sjBu4Z9gzfoKOvS8TLzxCJJihv2vkhl2aOpFGzJSIr+5wCRWb/ZRqwCMXhz9KMw21U1IJPdDLshtQKvI3gm7+veLY9zEIB0mGxDom2CNFyTKVP9i3JbIuWCb0SlJxajZByhWga6MNJZtUuR2RRBVIwiAh/yEVD/kM7EhuA== X-Gm-Message-State: AOJu0YxG8mo6WPIYVxL66ivhTG2rlA7VuCBL/hx8+F4VLjeoaKUQ21KN EqPO8MQp8Rc768NsL0Kco1cChdbuGhUw45492HYYBQsARU5rewC6 X-Google-Smtp-Source: AGHT+IFcy1nbT2issyZB1cEgm/lfGKAVteBPOb6Fg8eo1DnNX6U9jgGHQwHqqALGVpgz4hatJydTPA== X-Received: by 2002:a05:6830:43a9:b0:6f9:90ba:6646 with SMTP id 46e09a7af769-6fb939f328bmr15303711a34.26.1718699969712; Tue, 18 Jun 2024 01:39:29 -0700 (PDT) Received: from localhost.localdomain ([122.8.183.87]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-6fb5b75563csm1770804a34.66.2024.06.18.01.39.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jun 2024 01:39:28 -0700 (PDT) From: Chen Wang To: adrian.hunter@intel.com, aou@eecs.berkeley.edu, conor+dt@kernel.org, guoren@kernel.org, inochiama@outlook.com, jszhang@kernel.org, krzysztof.kozlowski+dt@linaro.org, palmer@dabbelt.com, paul.walmsley@sifive.com, robh@kernel.org, ulf.hansson@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-riscv@lists.infradead.org, chao.wei@sophgo.com, haijiao.liu@sophgo.com, xiaoguang.xing@sophgo.com, tingzhu.wang@sophgo.com Cc: Chen Wang Subject: [PATCH v4 4/4] riscv: dts: add mmc controllers for Sophgo SG2042 SoC Date: Tue, 18 Jun 2024 16:39:20 +0800 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-mmc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Chen Wang SG2042 has two MMC controller, one for emmc, another for sd-card. Signed-off-by: Chen Wang --- .../boot/dts/sophgo/sg2042-milkv-pioneer.dts | 17 ++++++++++ arch/riscv/boot/dts/sophgo/sg2042.dtsi | 32 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts index 49b4b9c2c101..164db23586e0 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts +++ b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts @@ -14,6 +14,23 @@ chosen { }; }; +&emmc { + bus-width = <4>; + no-sdio; + no-sd; + non-removable; + wp-inverted; + status = "okay"; +}; + +&sd { + bus-width = <4>; + no-sdio; + no-mmc; + wp-inverted; + status = "okay"; +}; + &uart0 { status = "okay"; }; diff --git a/arch/riscv/boot/dts/sophgo/sg2042.dtsi b/arch/riscv/boot/dts/sophgo/sg2042.dtsi index 81fda312f988..bfdfd6f32912 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042.dtsi +++ b/arch/riscv/boot/dts/sophgo/sg2042.dtsi @@ -346,5 +346,37 @@ uart0: serial@7040000000 { resets = <&rstgen RST_UART0>; status = "disabled"; }; + + emmc: mmc@704002a000 { + compatible = "sophgo,sg2042-dwcmshc"; + reg = <0x70 0x4002A000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <134 IRQ_TYPE_LEVEL_HIGH>; + clocks = + <&clkgen GATE_CLK_AXI_EMMC>, + <&clkgen GATE_CLK_100K_EMMC>, + <&clkgen GATE_CLK_EMMC_100M>; + clock-names = + "core", + "timer", + "card"; + status = "disabled"; + }; + + sd: mmc@704002b000 { + compatible = "sophgo,sg2042-dwcmshc"; + reg = <0x70 0x4002B000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <136 IRQ_TYPE_LEVEL_HIGH>; + clocks = + <&clkgen GATE_CLK_AXI_SD>, + <&clkgen GATE_CLK_100K_SD>, + <&clkgen GATE_CLK_SD_100M>; + clock-names = + "core", + "timer", + "card"; + status = "disabled"; + }; }; };