From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) (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 52ECD386557 for ; Mon, 13 Apr 2026 07:26:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776065171; cv=none; b=q5Xj9uTmnDn9NTQhl+9FdCTEBwPPmEhsI+rUacdhmlDFozAAXGUY2BwJAvtx8BQE8fbexiVSO7h44J03dFh4yV58gLW+yJzjYAE/mppnRc9sg2WV/EYU5t+Z4OxGsAffChZBDrC8w8R2GP8n5LUq/Vj0tPfvtAkk7azdp/Klgts= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776065171; c=relaxed/simple; bh=lQe/1C1yUclvn5uXddSpw2OgIhgzl5fVc6scliCgVzI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=f7KYZLnC8L19f3y90Xg5cC1J1tuHAfqhRvzpGuSi3oTeVgMf0AyBSoEsnDI4AFyF5LnKuidAphEkUOunOJoL2gxAN3QAP66jw848K1Ra/oRU5MIm6cNnwI5/duOyZn1KCNaYx/yh8FnzzRcxhpre3KP2MLXq3xsoE37okQ5vZIA= 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=kaAFFG85; arc=none smtp.client-ip=209.85.128.41 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="kaAFFG85" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-488b8efed61so37774975e9.1 for ; Mon, 13 Apr 2026 00:26:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776065167; x=1776669967; 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=/k4mLTIsc5RI8xaNMKymA8VHdibedwqV8+ItxZpomdA=; b=kaAFFG857ayf4pHZykk+D2D0Hpx03GQ3dcSt9jRIoKRjdXYMRvHg1DMQqsNry5qTGE /uDLLzykpnQAU46l96VTNyE09xKy2fYk7zuB4n1In7jzaJ32Qf4FD4Y2ojnkmTyurX+4 epe7AujQ798y3idfsALrEV1y0NzfCJt9f/vNglDLFilgbCNWaxGf8jCBz/G7AbC/CikJ u+3k59t3pf++IgQb7kQRXX7/ILbyltvOGae6uTYer5oFZAc6rLaTNrIOfXp0KA1NSFi8 mdbHDomcGrwWKy0v685FEHBa/BKULeCGfQP+Xqt3igtHHmBjkNPAqoe7ZifLEuGHzcaI OZLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776065167; x=1776669967; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=/k4mLTIsc5RI8xaNMKymA8VHdibedwqV8+ItxZpomdA=; b=jV8OwtRZBEZ+NxkJYWroeEp57pMEIPM16/6oD7VBUyX3twdccdm+j84RFts+Vrzitd 9bQybpBAyOKJj+XrEomBj264pqTzUlUiY79+oGMrv3bpcNpacP5RltzKlWN2Lu9PrRuf wxCsypJTQGbZrtwhXb2Yv40o4WFMSNXpldc4R0GPi6+UmR+M91tF+YVMk0/kg/IUAa4s yxrZrYuL4iMNSZk0EvlLW8YxkgJnLbCm/rdZ7Ow/eu1GFqj5q2u101KGTXB0PaysoaRF tfOv5afzV6/B9L1EkYgOeETnvHasaBtlmO1nlOJP4PwKWv0DYThmwzWuQ8K/hysSD2fr Dp1g== X-Forwarded-Encrypted: i=1; AFNElJ/bLHzucDWUawpO1RejJJQDUXFwYAjitLGkyUzscakKXM7DB5fw7AjJzL7eshuuG+UAKQEAfuQGmk0D@vger.kernel.org X-Gm-Message-State: AOJu0YwYOSivc4v5WCQIuZSaS6cNIXmeMkXvd4TEXFeJmrhpBFZixipQ ODdkfCEs4gogguqt1SVuYU8LMW0wRS+kKE1qaxO0N8wmFkjRzSZuCscE X-Gm-Gg: AeBDieu+l1/ZQWCwoUdnwQrO6XeMR6yc5ZEhEc7O+oGdEYPzkj5mWwUQ7ewx5of7L9H 9Ayk2i9qdT+HVVPugbtwYBst6m3CEfYMvWoQ7hTAJ/eHx5Bfum9+k/SxufA8sA9Ts8+J5tp3IR6 CuH41Fs2wq5Ghbxs2eNUg1gTE7doV5ceAmXfBw5Nvk88WF2i87ze5z9fo3SSGf3AlMeuxxvF81u DT9ZrSHqWoCCXgZgYsYw8p6CHpW//PekrVx7RnIRO1LwbLk1YC8G25GuaoADvzl0HHHPEhPVEOZ C92O3uXMdAPY9BDsGz1dPcAQYfvAqv7sNSkO0ICHAeVk7rhe9uen6MCrZu5jcm007AIukEW2sRv G0VIucJ5TA0DyfvbtmjPT+vPVXA2FG92tVfxgovEn/4XgKWCLjHKHIjY5gQcmf0/faWXR5IkFtB RI2YRGdQCRMOMgOOkqB6E5u/JxhCSgsNzyL7hHTXwuGl+wlKDY0HkTeeMc/a0t6TEGKpDNHqu/K Ds= X-Received: by 2002:a05:600c:8717:b0:477:9890:9ab8 with SMTP id 5b1f17b1804b1-488d6816f5amr164955675e9.3.1776065166673; Mon, 13 Apr 2026 00:26:06 -0700 (PDT) Received: from ipedrosa-thinkpadx1carbongen12.rmtes.csb ([67.218.239.37]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-488df2a1237sm322180555e9.6.2026.04.13.00.26.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Apr 2026 00:26:06 -0700 (PDT) From: Iker Pedrosa To: Ulf Hansson , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Adrian Hunter , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Yixun Lan Cc: Iker Pedrosa , Troy Mitchell , Michael Opdenacker , Javier Martinez Canillas , linux-mmc@vger.kernel.org, devicetree@vger.kernel.org, linux-riscv@lists.infradead.org, spacemit@lists.linux.dev, linux-kernel@vger.kernel.org, Anand Moon , Trevor Gamblin , Vincent Legoll Subject: [PATCH v7 3/9] mmc: sdhci-of-k1: add regulator and pinctrl voltage switching support Date: Mon, 13 Apr 2026 09:24:45 +0200 Message-ID: <20260413-orangepi-sd-card-uhs-v7-3-16650f49c022@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260413-orangepi-sd-card-uhs-v7-0-16650f49c022@gmail.com> References: <20260413-orangepi-sd-card-uhs-v7-0-16650f49c022@gmail.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Mailer: b4 0.14.3 Content-Transfer-Encoding: 8bit Add voltage switching infrastructure for UHS-I modes by integrating both regulator framework (for supply voltage control) and pinctrl state switching (for pin drive strength optimization). - Add regulator supply parsing and voltage switching callback - Add optional pinctrl state switching between "default" (3.3V) and "state_uhs" (1.8V) configurations - Enable coordinated voltage and pin configuration changes for UHS modes This provides complete voltage switching support while maintaining backward compatibility when pinctrl states are not defined. Tested-by: Anand Moon Tested-by: Trevor Gamblin Acked-by: Adrian Hunter Reviewed-by: Troy Mitchell Tested-by: Vincent Legoll Signed-off-by: Iker Pedrosa --- drivers/mmc/host/sdhci-of-k1.c | 72 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c index 0dd06fc19b85..d9144537032a 100644 --- a/drivers/mmc/host/sdhci-of-k1.c +++ b/drivers/mmc/host/sdhci-of-k1.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "sdhci.h" @@ -71,6 +72,9 @@ struct spacemit_sdhci_host { struct clk *clk_core; struct clk *clk_io; + struct pinctrl *pinctrl; + struct pinctrl_state *pinctrl_default; + struct pinctrl_state *pinctrl_uhs; }; /* All helper functions will update clr/set while preserve rest bits */ @@ -219,6 +223,46 @@ static void spacemit_sdhci_pre_hs400_to_hs200(struct mmc_host *mmc) SPACEMIT_SDHC_PHY_CTRL_REG); } +static int spacemit_sdhci_start_signal_voltage_switch(struct mmc_host *mmc, + struct mmc_ios *ios) +{ + struct sdhci_host *host = mmc_priv(mmc); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct spacemit_sdhci_host *sdhst = sdhci_pltfm_priv(pltfm_host); + struct pinctrl_state *state; + int ret; + + ret = sdhci_start_signal_voltage_switch(mmc, ios); + if (ret) + return ret; + + if (!sdhst->pinctrl) + return 0; + + /* Select appropriate pinctrl state based on signal voltage */ + switch (ios->signal_voltage) { + case MMC_SIGNAL_VOLTAGE_330: + state = sdhst->pinctrl_default; + break; + case MMC_SIGNAL_VOLTAGE_180: + state = sdhst->pinctrl_uhs; + break; + default: + dev_warn(mmc_dev(mmc), "unsupported voltage %d\n", ios->signal_voltage); + return 0; + } + + ret = pinctrl_select_state(sdhst->pinctrl, state); + if (ret) { + dev_warn(mmc_dev(mmc), "failed to select pinctrl state: %d\n", ret); + return 0; + } + dev_dbg(mmc_dev(mmc), "switched to %s pinctrl state\n", + ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180 ? "UHS" : "default"); + + return 0; +} + static inline int spacemit_sdhci_get_clocks(struct device *dev, struct sdhci_pltfm_host *pltfm_host) { @@ -252,6 +296,30 @@ static inline int spacemit_sdhci_get_resets(struct device *dev) return 0; } +static inline void spacemit_sdhci_get_pins(struct device *dev, + struct sdhci_pltfm_host *pltfm_host) +{ + struct spacemit_sdhci_host *sdhst = sdhci_pltfm_priv(pltfm_host); + + sdhst->pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(sdhst->pinctrl)) { + sdhst->pinctrl = NULL; + dev_dbg(dev, "pinctrl not available, voltage switching will work without it\n"); + return; + } + + sdhst->pinctrl_default = pinctrl_lookup_state(sdhst->pinctrl, "default"); + if (IS_ERR(sdhst->pinctrl_default)) + sdhst->pinctrl_default = NULL; + + sdhst->pinctrl_uhs = pinctrl_lookup_state(sdhst->pinctrl, "uhs"); + if (IS_ERR(sdhst->pinctrl_uhs)) + sdhst->pinctrl_uhs = NULL; + + dev_dbg(dev, "pinctrl setup: default=%p, uhs=%p\n", + sdhst->pinctrl_default, sdhst->pinctrl_uhs); +} + static const struct sdhci_ops spacemit_sdhci_ops = { .get_max_clock = spacemit_sdhci_clk_get_max_clock, .reset = spacemit_sdhci_reset, @@ -324,6 +392,10 @@ static int spacemit_sdhci_probe(struct platform_device *pdev) host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY; + spacemit_sdhci_get_pins(dev, pltfm_host); + + host->mmc_host_ops.start_signal_voltage_switch = spacemit_sdhci_start_signal_voltage_switch; + ret = spacemit_sdhci_get_clocks(dev, pltfm_host); if (ret) goto err_pltfm; -- 2.53.0