* [PATCH v3 1/7] mmc: sdhci-of-k1: enable essential clock infrastructure for SD operation
2026-03-16 14:03 [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2 Iker Pedrosa
@ 2026-03-16 14:03 ` Iker Pedrosa
2026-03-17 11:32 ` Adrian Hunter
2026-03-16 14:03 ` [PATCH v3 2/7] mmc: sdhci-of-k1: add regulator and pinctrl voltage switching support Iker Pedrosa
` (6 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Iker Pedrosa @ 2026-03-16 14:03 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon
Ensure SD card pins receive clock signals by enabling pad clock
generation and overriding automatic clock gating. Required for all SD
operation modes.
The SDHC_GEN_PAD_CLK_ON setting in LEGACY_CTRL_REG is safe for both SD
and eMMC operation as both protocols use the same physical MMC interface
pins and require proper clock signal generation at the hardware level
for signal integrity and timing.
Additional SD-specific clock overrides (SDHC_OVRRD_CLK_OEN and
SDHC_FORCE_CLK_ON) are conditionally applied only for SD-only
controllers to handle removable card scenarios.
Tested-by: Anand Moon <linux.amoon@gmail.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
drivers/mmc/host/sdhci-of-k1.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c
index 455656f9842df90c7a94a290aeec22157b378fc1..0dd06fc19b8574ae1b00f7e5d09b7d4c87d06770 100644
--- a/drivers/mmc/host/sdhci-of-k1.c
+++ b/drivers/mmc/host/sdhci-of-k1.c
@@ -21,6 +21,13 @@
#include "sdhci.h"
#include "sdhci-pltfm.h"
+#define SPACEMIT_SDHC_OP_EXT_REG 0x108
+#define SDHC_OVRRD_CLK_OEN BIT(11)
+#define SDHC_FORCE_CLK_ON BIT(12)
+
+#define SPACEMIT_SDHC_LEGACY_CTRL_REG 0x10C
+#define SDHC_GEN_PAD_CLK_ON BIT(6)
+
#define SPACEMIT_SDHC_MMC_CTRL_REG 0x114
#define SDHC_MISC_INT_EN BIT(1)
#define SDHC_MISC_INT BIT(2)
@@ -101,6 +108,12 @@ static void spacemit_sdhci_reset(struct sdhci_host *host, u8 mask)
if (!(host->mmc->caps2 & MMC_CAP2_NO_MMC))
spacemit_sdhci_setbits(host, SDHC_MMC_CARD_MODE, SPACEMIT_SDHC_MMC_CTRL_REG);
+
+ spacemit_sdhci_setbits(host, SDHC_GEN_PAD_CLK_ON, SPACEMIT_SDHC_LEGACY_CTRL_REG);
+
+ if (host->mmc->caps2 & MMC_CAP2_NO_MMC)
+ spacemit_sdhci_setbits(host, SDHC_OVRRD_CLK_OEN | SDHC_FORCE_CLK_ON,
+ SPACEMIT_SDHC_OP_EXT_REG);
}
static void spacemit_sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned int timing)
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v3 1/7] mmc: sdhci-of-k1: enable essential clock infrastructure for SD operation
2026-03-16 14:03 ` [PATCH v3 1/7] mmc: sdhci-of-k1: enable essential clock infrastructure for SD operation Iker Pedrosa
@ 2026-03-17 11:32 ` Adrian Hunter
0 siblings, 0 replies; 18+ messages in thread
From: Adrian Hunter @ 2026-03-17 11:32 UTC (permalink / raw)
To: Iker Pedrosa, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Anand Moon
On 16/03/2026 16:03, Iker Pedrosa wrote:
> Ensure SD card pins receive clock signals by enabling pad clock
> generation and overriding automatic clock gating. Required for all SD
> operation modes.
>
> The SDHC_GEN_PAD_CLK_ON setting in LEGACY_CTRL_REG is safe for both SD
> and eMMC operation as both protocols use the same physical MMC interface
> pins and require proper clock signal generation at the hardware level
> for signal integrity and timing.
>
> Additional SD-specific clock overrides (SDHC_OVRRD_CLK_OEN and
> SDHC_FORCE_CLK_ON) are conditionally applied only for SD-only
> controllers to handle removable card scenarios.
>
> Tested-by: Anand Moon <linux.amoon@gmail.com>
> Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
> drivers/mmc/host/sdhci-of-k1.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c
> index 455656f9842df90c7a94a290aeec22157b378fc1..0dd06fc19b8574ae1b00f7e5d09b7d4c87d06770 100644
> --- a/drivers/mmc/host/sdhci-of-k1.c
> +++ b/drivers/mmc/host/sdhci-of-k1.c
> @@ -21,6 +21,13 @@
> #include "sdhci.h"
> #include "sdhci-pltfm.h"
>
> +#define SPACEMIT_SDHC_OP_EXT_REG 0x108
> +#define SDHC_OVRRD_CLK_OEN BIT(11)
> +#define SDHC_FORCE_CLK_ON BIT(12)
> +
> +#define SPACEMIT_SDHC_LEGACY_CTRL_REG 0x10C
> +#define SDHC_GEN_PAD_CLK_ON BIT(6)
> +
> #define SPACEMIT_SDHC_MMC_CTRL_REG 0x114
> #define SDHC_MISC_INT_EN BIT(1)
> #define SDHC_MISC_INT BIT(2)
> @@ -101,6 +108,12 @@ static void spacemit_sdhci_reset(struct sdhci_host *host, u8 mask)
>
> if (!(host->mmc->caps2 & MMC_CAP2_NO_MMC))
> spacemit_sdhci_setbits(host, SDHC_MMC_CARD_MODE, SPACEMIT_SDHC_MMC_CTRL_REG);
> +
> + spacemit_sdhci_setbits(host, SDHC_GEN_PAD_CLK_ON, SPACEMIT_SDHC_LEGACY_CTRL_REG);
> +
> + if (host->mmc->caps2 & MMC_CAP2_NO_MMC)
> + spacemit_sdhci_setbits(host, SDHC_OVRRD_CLK_OEN | SDHC_FORCE_CLK_ON,
> + SPACEMIT_SDHC_OP_EXT_REG);
> }
>
> static void spacemit_sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned int timing)
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3 2/7] mmc: sdhci-of-k1: add regulator and pinctrl voltage switching support
2026-03-16 14:03 [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2 Iker Pedrosa
2026-03-16 14:03 ` [PATCH v3 1/7] mmc: sdhci-of-k1: enable essential clock infrastructure for SD operation Iker Pedrosa
@ 2026-03-16 14:03 ` Iker Pedrosa
2026-03-17 11:28 ` Adrian Hunter
2026-03-16 14:03 ` [PATCH v3 3/7] mmc: sdhci-of-k1: add comprehensive SDR tuning support Iker Pedrosa
` (5 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Iker Pedrosa @ 2026-03-16 14:03 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon
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 <linux.amoon@gmail.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
drivers/mmc/host/sdhci-of-k1.c | 58 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c
index 0dd06fc19b8574ae1b00f7e5d09b7d4c87d06770..01afdadcf70796704b272ee5a31543afd5e01188 100644
--- a/drivers/mmc/host/sdhci-of-k1.c
+++ b/drivers/mmc/host/sdhci-of-k1.c
@@ -16,6 +16,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/reset.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#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,33 @@ static void spacemit_sdhci_pre_hs400_to_hs200(struct mmc_host *mmc)
SPACEMIT_SDHC_PHY_CTRL_REG);
}
+static void spacemit_sdhci_voltage_switch(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct spacemit_sdhci_host *sdhst = sdhci_pltfm_priv(pltfm_host);
+ struct mmc_ios *ios = &host->mmc->ios;
+ int ret;
+
+ if (!sdhst->pinctrl)
+ return;
+
+ if (ios->signal_voltage != MMC_SIGNAL_VOLTAGE_180) {
+ dev_warn(mmc_dev(host->mmc), "unsupported voltage %d\n",
+ ios->signal_voltage);
+ return;
+ }
+
+ if (sdhst->pinctrl_uhs) {
+ ret = pinctrl_select_state(sdhst->pinctrl, sdhst->pinctrl_uhs);
+ if (ret) {
+ dev_warn(mmc_dev(host->mmc),
+ "failed to select UHS pinctrl state: %d\n", ret);
+ return;
+ }
+ dev_dbg(mmc_dev(host->mmc), "switched to UHS pinctrl state\n");
+ }
+}
+
static inline int spacemit_sdhci_get_clocks(struct device *dev,
struct sdhci_pltfm_host *pltfm_host)
{
@@ -252,12 +283,37 @@ 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, "state_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,
.set_bus_width = sdhci_set_bus_width,
.set_clock = spacemit_sdhci_set_clock,
.set_uhs_signaling = spacemit_sdhci_set_uhs_signaling,
+ .voltage_switch = spacemit_sdhci_voltage_switch,
};
static const struct sdhci_pltfm_data spacemit_sdhci_k1_pdata = {
@@ -324,6 +380,8 @@ static int spacemit_sdhci_probe(struct platform_device *pdev)
host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
+ spacemit_sdhci_get_pins(dev, pltfm_host);
+
ret = spacemit_sdhci_get_clocks(dev, pltfm_host);
if (ret)
goto err_pltfm;
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v3 2/7] mmc: sdhci-of-k1: add regulator and pinctrl voltage switching support
2026-03-16 14:03 ` [PATCH v3 2/7] mmc: sdhci-of-k1: add regulator and pinctrl voltage switching support Iker Pedrosa
@ 2026-03-17 11:28 ` Adrian Hunter
2026-03-20 9:17 ` Iker Pedrosa
0 siblings, 1 reply; 18+ messages in thread
From: Adrian Hunter @ 2026-03-17 11:28 UTC (permalink / raw)
To: Iker Pedrosa, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Anand Moon
On 16/03/2026 16:03, Iker Pedrosa wrote:
> 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 <linux.amoon@gmail.com>
> Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
> ---
> drivers/mmc/host/sdhci-of-k1.c | 58 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 58 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c
> index 0dd06fc19b8574ae1b00f7e5d09b7d4c87d06770..01afdadcf70796704b272ee5a31543afd5e01188 100644
> --- a/drivers/mmc/host/sdhci-of-k1.c
> +++ b/drivers/mmc/host/sdhci-of-k1.c
> @@ -16,6 +16,7 @@
> #include <linux/of.h>
> #include <linux/of_device.h>
> #include <linux/reset.h>
> +#include <linux/pinctrl/consumer.h>
> #include <linux/platform_device.h>
>
> #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,33 @@ static void spacemit_sdhci_pre_hs400_to_hs200(struct mmc_host *mmc)
> SPACEMIT_SDHC_PHY_CTRL_REG);
> }
>
> +static void spacemit_sdhci_voltage_switch(struct sdhci_host *host)
> +{
> + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct spacemit_sdhci_host *sdhst = sdhci_pltfm_priv(pltfm_host);
> + struct mmc_ios *ios = &host->mmc->ios;
> + int ret;
> +
> + if (!sdhst->pinctrl)
> + return;
> +
> + if (ios->signal_voltage != MMC_SIGNAL_VOLTAGE_180) {
> + dev_warn(mmc_dev(host->mmc), "unsupported voltage %d\n",
> + ios->signal_voltage);
> + return;
> + }
In V2, I put "->voltage_switch() is called only for
ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180" by
which I meant that it does not allow the driver to
switch pin state back for 3.3V.
So you probably need an approach similar to the original
spacemit_sdhci_start_signal_voltage_switch() in:
https://lore.kernel.org/linux-mmc/20260302-orangepi-sd-card-uhs-v1-4-89c219973c0c@gmail.com/
> +
> + if (sdhst->pinctrl_uhs) {
> + ret = pinctrl_select_state(sdhst->pinctrl, sdhst->pinctrl_uhs);
> + if (ret) {
> + dev_warn(mmc_dev(host->mmc),
> + "failed to select UHS pinctrl state: %d\n", ret);
> + return;
> + }
> + dev_dbg(mmc_dev(host->mmc), "switched to UHS pinctrl state\n");
> + }
> +}
> +
> static inline int spacemit_sdhci_get_clocks(struct device *dev,
> struct sdhci_pltfm_host *pltfm_host)
> {
> @@ -252,12 +283,37 @@ 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, "state_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,
> .set_bus_width = sdhci_set_bus_width,
> .set_clock = spacemit_sdhci_set_clock,
> .set_uhs_signaling = spacemit_sdhci_set_uhs_signaling,
> + .voltage_switch = spacemit_sdhci_voltage_switch,
> };
>
> static const struct sdhci_pltfm_data spacemit_sdhci_k1_pdata = {
> @@ -324,6 +380,8 @@ static int spacemit_sdhci_probe(struct platform_device *pdev)
>
> host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
>
> + spacemit_sdhci_get_pins(dev, pltfm_host);
> +
> ret = spacemit_sdhci_get_clocks(dev, pltfm_host);
> if (ret)
> goto err_pltfm;
>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v3 2/7] mmc: sdhci-of-k1: add regulator and pinctrl voltage switching support
2026-03-17 11:28 ` Adrian Hunter
@ 2026-03-20 9:17 ` Iker Pedrosa
2026-03-20 11:31 ` Adrian Hunter
0 siblings, 1 reply; 18+ messages in thread
From: Iker Pedrosa @ 2026-03-20 9:17 UTC (permalink / raw)
To: Adrian Hunter
Cc: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Yixun Lan, Michael Opdenacker, Javier Martinez Canillas,
linux-mmc, devicetree, linux-riscv, spacemit, linux-kernel,
Anand Moon
El mar, 17 mar 2026 a las 12:28, Adrian Hunter
(<adrian.hunter@intel.com>) escribió:
>
> On 16/03/2026 16:03, Iker Pedrosa wrote:
> > 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 <linux.amoon@gmail.com>
> > Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
> > ---
> > drivers/mmc/host/sdhci-of-k1.c | 58 ++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 58 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c
> > index 0dd06fc19b8574ae1b00f7e5d09b7d4c87d06770..01afdadcf70796704b272ee5a31543afd5e01188 100644
> > --- a/drivers/mmc/host/sdhci-of-k1.c
> > +++ b/drivers/mmc/host/sdhci-of-k1.c
> > @@ -16,6 +16,7 @@
> > #include <linux/of.h>
> > #include <linux/of_device.h>
> > #include <linux/reset.h>
> > +#include <linux/pinctrl/consumer.h>
> > #include <linux/platform_device.h>
> >
> > #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,33 @@ static void spacemit_sdhci_pre_hs400_to_hs200(struct mmc_host *mmc)
> > SPACEMIT_SDHC_PHY_CTRL_REG);
> > }
> >
> > +static void spacemit_sdhci_voltage_switch(struct sdhci_host *host)
> > +{
> > + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > + struct spacemit_sdhci_host *sdhst = sdhci_pltfm_priv(pltfm_host);
> > + struct mmc_ios *ios = &host->mmc->ios;
> > + int ret;
> > +
> > + if (!sdhst->pinctrl)
> > + return;
> > +
> > + if (ios->signal_voltage != MMC_SIGNAL_VOLTAGE_180) {
> > + dev_warn(mmc_dev(host->mmc), "unsupported voltage %d\n",
> > + ios->signal_voltage);
> > + return;
> > + }
>
> In V2, I put "->voltage_switch() is called only for
> ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180" by
> which I meant that it does not allow the driver to
> switch pin state back for 3.3V.
>
> So you probably need an approach similar to the original
> spacemit_sdhci_start_signal_voltage_switch() in:
>
> https://lore.kernel.org/linux-mmc/20260302-orangepi-sd-card-uhs-v1-4-89c219973c0c@gmail.com/
Thank you for the feedback. I want to make sure I understand this
point correctly to avoid going in circles.
In the v2 feedback , you mentioned that "->voltage_switch() is called
only for ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180", which I
understood to mean that this callback only needs to handle switching
to 1.8V. This meant that the changes I introduced for v3 don't manage
the switching to 3.3V.
Can you clarify if I should I revert to implementing
"->start_signal_voltage_switch()" instead, which would handle both
1.8V and 3.3V cases? Or is there a way to make the
"->voltage_switch()" approach work properly for both directions?
>
> > +
> > + if (sdhst->pinctrl_uhs) {
> > + ret = pinctrl_select_state(sdhst->pinctrl, sdhst->pinctrl_uhs);
> > + if (ret) {
> > + dev_warn(mmc_dev(host->mmc),
> > + "failed to select UHS pinctrl state: %d\n", ret);
> > + return;
> > + }
> > + dev_dbg(mmc_dev(host->mmc), "switched to UHS pinctrl state\n");
> > + }
> > +}
> > +
> > static inline int spacemit_sdhci_get_clocks(struct device *dev,
> > struct sdhci_pltfm_host *pltfm_host)
> > {
> > @@ -252,12 +283,37 @@ 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, "state_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,
> > .set_bus_width = sdhci_set_bus_width,
> > .set_clock = spacemit_sdhci_set_clock,
> > .set_uhs_signaling = spacemit_sdhci_set_uhs_signaling,
> > + .voltage_switch = spacemit_sdhci_voltage_switch,
> > };
> >
> > static const struct sdhci_pltfm_data spacemit_sdhci_k1_pdata = {
> > @@ -324,6 +380,8 @@ static int spacemit_sdhci_probe(struct platform_device *pdev)
> >
> > host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
> >
> > + spacemit_sdhci_get_pins(dev, pltfm_host);
> > +
> > ret = spacemit_sdhci_get_clocks(dev, pltfm_host);
> > if (ret)
> > goto err_pltfm;
> >
>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v3 2/7] mmc: sdhci-of-k1: add regulator and pinctrl voltage switching support
2026-03-20 9:17 ` Iker Pedrosa
@ 2026-03-20 11:31 ` Adrian Hunter
0 siblings, 0 replies; 18+ messages in thread
From: Adrian Hunter @ 2026-03-20 11:31 UTC (permalink / raw)
To: Iker Pedrosa
Cc: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Yixun Lan, Michael Opdenacker, Javier Martinez Canillas,
linux-mmc, devicetree, linux-riscv, spacemit, linux-kernel,
Anand Moon
On 20/03/2026 11:17, Iker Pedrosa wrote:
> El mar, 17 mar 2026 a las 12:28, Adrian Hunter
> (<adrian.hunter@intel.com>) escribió:
>>
>> On 16/03/2026 16:03, Iker Pedrosa wrote:
>>> 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 <linux.amoon@gmail.com>
>>> Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
>>> ---
>>> drivers/mmc/host/sdhci-of-k1.c | 58 ++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 58 insertions(+)
>>>
>>> diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c
>>> index 0dd06fc19b8574ae1b00f7e5d09b7d4c87d06770..01afdadcf70796704b272ee5a31543afd5e01188 100644
>>> --- a/drivers/mmc/host/sdhci-of-k1.c
>>> +++ b/drivers/mmc/host/sdhci-of-k1.c
>>> @@ -16,6 +16,7 @@
>>> #include <linux/of.h>
>>> #include <linux/of_device.h>
>>> #include <linux/reset.h>
>>> +#include <linux/pinctrl/consumer.h>
>>> #include <linux/platform_device.h>
>>>
>>> #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,33 @@ static void spacemit_sdhci_pre_hs400_to_hs200(struct mmc_host *mmc)
>>> SPACEMIT_SDHC_PHY_CTRL_REG);
>>> }
>>>
>>> +static void spacemit_sdhci_voltage_switch(struct sdhci_host *host)
>>> +{
>>> + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>>> + struct spacemit_sdhci_host *sdhst = sdhci_pltfm_priv(pltfm_host);
>>> + struct mmc_ios *ios = &host->mmc->ios;
>>> + int ret;
>>> +
>>> + if (!sdhst->pinctrl)
>>> + return;
>>> +
>>> + if (ios->signal_voltage != MMC_SIGNAL_VOLTAGE_180) {
>>> + dev_warn(mmc_dev(host->mmc), "unsupported voltage %d\n",
>>> + ios->signal_voltage);
>>> + return;
>>> + }
>>
>> In V2, I put "->voltage_switch() is called only for
>> ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180" by
>> which I meant that it does not allow the driver to
>> switch pin state back for 3.3V.
>>
>> So you probably need an approach similar to the original
>> spacemit_sdhci_start_signal_voltage_switch() in:
>>
>> https://lore.kernel.org/linux-mmc/20260302-orangepi-sd-card-uhs-v1-4-89c219973c0c@gmail.com/
>
> Thank you for the feedback. I want to make sure I understand this
> point correctly to avoid going in circles.
>
> In the v2 feedback , you mentioned that "->voltage_switch() is called
> only for ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180", which I
> understood to mean that this callback only needs to handle switching
> to 1.8V. This meant that the changes I introduced for v3 don't manage
> the switching to 3.3V.
>
> Can you clarify if I should I revert to implementing
> "->start_signal_voltage_switch()" instead, which would handle both
> 1.8V and 3.3V cases?
Yes
Or is there a way to make the
> "->voltage_switch()" approach work properly for both directions?
>
>>
>>> +
>>> + if (sdhst->pinctrl_uhs) {
>>> + ret = pinctrl_select_state(sdhst->pinctrl, sdhst->pinctrl_uhs);
>>> + if (ret) {
>>> + dev_warn(mmc_dev(host->mmc),
>>> + "failed to select UHS pinctrl state: %d\n", ret);
>>> + return;
>>> + }
>>> + dev_dbg(mmc_dev(host->mmc), "switched to UHS pinctrl state\n");
>>> + }
>>> +}
>>> +
>>> static inline int spacemit_sdhci_get_clocks(struct device *dev,
>>> struct sdhci_pltfm_host *pltfm_host)
>>> {
>>> @@ -252,12 +283,37 @@ 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, "state_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,
>>> .set_bus_width = sdhci_set_bus_width,
>>> .set_clock = spacemit_sdhci_set_clock,
>>> .set_uhs_signaling = spacemit_sdhci_set_uhs_signaling,
>>> + .voltage_switch = spacemit_sdhci_voltage_switch,
>>> };
>>>
>>> static const struct sdhci_pltfm_data spacemit_sdhci_k1_pdata = {
>>> @@ -324,6 +380,8 @@ static int spacemit_sdhci_probe(struct platform_device *pdev)
>>>
>>> host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
>>>
>>> + spacemit_sdhci_get_pins(dev, pltfm_host);
>>> +
>>> ret = spacemit_sdhci_get_clocks(dev, pltfm_host);
>>> if (ret)
>>> goto err_pltfm;
>>>
>>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3 3/7] mmc: sdhci-of-k1: add comprehensive SDR tuning support
2026-03-16 14:03 [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2 Iker Pedrosa
2026-03-16 14:03 ` [PATCH v3 1/7] mmc: sdhci-of-k1: enable essential clock infrastructure for SD operation Iker Pedrosa
2026-03-16 14:03 ` [PATCH v3 2/7] mmc: sdhci-of-k1: add regulator and pinctrl voltage switching support Iker Pedrosa
@ 2026-03-16 14:03 ` Iker Pedrosa
2026-03-17 11:33 ` Adrian Hunter
2026-03-16 14:03 ` [PATCH v3 4/7] riscv: dts: spacemit: k1: add SD card controller and pinctrl support Iker Pedrosa
` (4 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Iker Pedrosa @ 2026-03-16 14:03 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon
Implement software tuning algorithm to enable UHS-I SDR modes for SD
card operation and HS200 mode for eMMC. This adds both TX and RX delay
line tuning based on the SpacemiT K1 controller capabilities.
Algorithm features:
- Add tuning register definitions (RX_CFG, DLINE_CTRL, DLINE_CFG)
- Conditional tuning: only for high-speed modes (≥100MHz)
- TX tuning: configure transmit delay line with optimal values
(dline_reg=0, delaycode=127) to ensure optimal signal output timing
- RX tuning: single-pass window detection algorithm testing full
delay range (0-255) to find optimal receive timing window
- Retry mechanism: multiple fallback delays within optimal window
for improved reliability
Tested-by: Anand Moon <linux.amoon@gmail.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
drivers/mmc/host/sdhci-of-k1.c | 172 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 172 insertions(+)
diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c
index 01afdadcf70796704b272ee5a31543afd5e01188..83d7f9fad5c1fba2f07624ee657cd979a1c7e25d 100644
--- a/drivers/mmc/host/sdhci-of-k1.c
+++ b/drivers/mmc/host/sdhci-of-k1.c
@@ -69,6 +69,28 @@
#define SDHC_PHY_DRIVE_SEL GENMASK(2, 0)
#define SDHC_RX_BIAS_CTRL BIT(5)
+#define SPACEMIT_SDHC_RX_CFG_REG 0x118
+#define SDHC_RX_SDCLK_SEL0_MASK GENMASK(1, 0)
+#define SDHC_RX_SDCLK_SEL1_MASK GENMASK(3, 2)
+#define SDHC_RX_SDCLK_SEL1 FIELD_PREP(SDHC_RX_SDCLK_SEL1_MASK, 1)
+
+#define SPACEMIT_SDHC_DLINE_CTRL_REG 0x130
+#define SDHC_DLINE_PU BIT(0)
+#define SDHC_RX_DLINE_CODE_MASK GENMASK(23, 16)
+#define SDHC_TX_DLINE_CODE_MASK GENMASK(31, 24)
+
+#define SPACEMIT_SDHC_DLINE_CFG_REG 0x134
+#define SDHC_RX_DLINE_REG_MASK GENMASK(7, 0)
+#define SDHC_RX_DLINE_GAIN BIT(8)
+#define SDHC_TX_DLINE_REG_MASK GENMASK(23, 16)
+
+#define SPACEMIT_RX_DLINE_REG 9
+#define SPACEMIT_RX_TUNE_DELAY_MIN 0x0
+#define SPACEMIT_RX_TUNE_DELAY_MAX 0xFF
+
+#define SPACEMIT_TX_TUNING_DLINE_REG 0x00
+#define SPACEMIT_TX_TUNING_DELAYCODE 127
+
struct spacemit_sdhci_host {
struct clk *clk_core;
struct clk *clk_io;
@@ -96,6 +118,50 @@ static inline void spacemit_sdhci_clrsetbits(struct sdhci_host *host, u32 clr, u
sdhci_writel(host, val, reg);
}
+static void spacemit_sdhci_set_rx_delay(struct sdhci_host *host, u8 delay)
+{
+ spacemit_sdhci_clrsetbits(host, SDHC_RX_DLINE_CODE_MASK,
+ FIELD_PREP(SDHC_RX_DLINE_CODE_MASK, delay),
+ SPACEMIT_SDHC_DLINE_CTRL_REG);
+}
+
+static void spacemit_sdhci_set_tx_delay(struct sdhci_host *host, u8 delay)
+{
+ spacemit_sdhci_clrsetbits(host, SDHC_TX_DLINE_CODE_MASK,
+ FIELD_PREP(SDHC_TX_DLINE_CODE_MASK, delay),
+ SPACEMIT_SDHC_DLINE_CTRL_REG);
+}
+
+static void spacemit_sdhci_set_tx_dline_reg(struct sdhci_host *host, u8 dline_reg)
+{
+ spacemit_sdhci_clrsetbits(host, SDHC_TX_DLINE_REG_MASK,
+ FIELD_PREP(SDHC_TX_DLINE_REG_MASK, dline_reg),
+ SPACEMIT_SDHC_DLINE_CFG_REG);
+}
+
+static void spacemit_sdhci_tx_tuning_prepare(struct sdhci_host *host)
+{
+ spacemit_sdhci_setbits(host, SDHC_TX_MUX_SEL, SPACEMIT_SDHC_TX_CFG_REG);
+ spacemit_sdhci_setbits(host, SDHC_DLINE_PU, SPACEMIT_SDHC_DLINE_CTRL_REG);
+ udelay(5);
+}
+
+static void spacemit_sdhci_prepare_tuning(struct sdhci_host *host)
+{
+ spacemit_sdhci_clrsetbits(host, SDHC_RX_DLINE_REG_MASK,
+ FIELD_PREP(SDHC_RX_DLINE_REG_MASK, SPACEMIT_RX_DLINE_REG),
+ SPACEMIT_SDHC_DLINE_CFG_REG);
+
+ spacemit_sdhci_setbits(host, SDHC_DLINE_PU, SPACEMIT_SDHC_DLINE_CTRL_REG);
+ udelay(5);
+
+ spacemit_sdhci_clrsetbits(host, SDHC_RX_SDCLK_SEL1_MASK, SDHC_RX_SDCLK_SEL1,
+ SPACEMIT_SDHC_RX_CFG_REG);
+
+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200)
+ spacemit_sdhci_setbits(host, SDHC_HS200_USE_RFIFO, SPACEMIT_SDHC_PHY_FUNC_REG);
+}
+
static void spacemit_sdhci_reset(struct sdhci_host *host, u8 mask)
{
sdhci_reset(host, mask);
@@ -191,6 +257,111 @@ static unsigned int spacemit_sdhci_clk_get_max_clock(struct sdhci_host *host)
return clk_get_rate(pltfm_host->clk);
}
+static int spacemit_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
+{
+ int current_len = 0, current_start = 0;
+ int max_pass_len = 0, max_pass_start = 0;
+ struct mmc_host *mmc = host->mmc;
+ struct mmc_ios ios = mmc->ios;
+ u8 final_delay;
+ int ret = 0;
+ int i;
+
+ /*
+ * Tuning is required for SDR50/SDR104, HS200/HS400 cards and
+ * if clock frequency is greater than 100MHz in these modes.
+ */
+ if (host->clock < 100 * 1000 * 1000 ||
+ !(ios.timing == MMC_TIMING_MMC_HS200 ||
+ ios.timing == MMC_TIMING_UHS_SDR50 ||
+ ios.timing == MMC_TIMING_UHS_SDR104))
+ return 0;
+
+ if (mmc->caps2 & MMC_CAP2_NO_MMC) {
+ spacemit_sdhci_set_tx_dline_reg(host, SPACEMIT_TX_TUNING_DLINE_REG);
+ spacemit_sdhci_set_tx_delay(host, SPACEMIT_TX_TUNING_DELAYCODE);
+ spacemit_sdhci_tx_tuning_prepare(host);
+
+ dev_dbg(mmc_dev(host->mmc), "TX tuning: dline_reg=%d, delaycode=%d\n",
+ SPACEMIT_TX_TUNING_DLINE_REG, SPACEMIT_TX_TUNING_DELAYCODE);
+ }
+
+ spacemit_sdhci_prepare_tuning(host);
+
+ for (i = SPACEMIT_RX_TUNE_DELAY_MIN; i <= SPACEMIT_RX_TUNE_DELAY_MAX; i++) {
+ spacemit_sdhci_set_rx_delay(host, i);
+ ret = mmc_send_tuning(host->mmc, opcode, NULL);
+
+ dev_dbg(mmc_dev(host->mmc), "RX delay %d: %s\n",
+ i, ret == 0 ? "pass" : "fail");
+
+ if (ret == 0) {
+ /* Test passed - extend current window */
+ if (current_len == 0)
+ current_start = i;
+ current_len++;
+ } else {
+ /* Test failed - check if current window is best so far */
+ if (current_len > max_pass_len) {
+ max_pass_len = current_len;
+ max_pass_start = current_start;
+ }
+ current_len = 0;
+ }
+ }
+
+ if (current_len > max_pass_len) {
+ max_pass_len = current_len;
+ max_pass_start = current_start;
+ }
+
+ if (max_pass_len < 3) {
+ dev_err(mmc_dev(host->mmc), "Tuning failed: no stable window found\n");
+ return -EIO;
+ }
+
+ final_delay = max_pass_start + max_pass_len / 2;
+ spacemit_sdhci_set_rx_delay(host, final_delay);
+ ret = mmc_send_tuning(host->mmc, opcode, NULL);
+ if (ret) {
+ u8 retry_delays[] = {
+ max_pass_start + max_pass_len / 4,
+ max_pass_start + (3 * max_pass_len) / 4,
+ max_pass_start,
+ max_pass_start + max_pass_len - 1
+ };
+ int retry_count = ARRAY_SIZE(retry_delays);
+
+ dev_warn(mmc_dev(mmc), "Primary delay %d failed, trying alternatives\n",
+ final_delay);
+
+ for (i = 0; i < retry_count; i++) {
+ if (retry_delays[i] >= SPACEMIT_RX_TUNE_DELAY_MIN &&
+ retry_delays[i] <= SPACEMIT_RX_TUNE_DELAY_MAX) {
+ spacemit_sdhci_set_rx_delay(host, retry_delays[i]);
+ ret = mmc_send_tuning(host->mmc, opcode, NULL);
+ if (!ret) {
+ final_delay = retry_delays[i];
+ dev_info(mmc_dev(mmc), "Retry successful with delay %d\n",
+ final_delay);
+ break;
+ }
+ }
+ }
+
+ if (ret) {
+ dev_err(mmc_dev(mmc), "All retry attempts failed\n");
+ return -EIO;
+ }
+ }
+
+ dev_dbg(mmc_dev(host->mmc),
+ "Tuning successful: window %d-%d, using delay %d\n",
+ max_pass_start, max_pass_start + max_pass_len - 1, final_delay);
+
+ return 0;
+}
+
static int spacemit_sdhci_pre_select_hs400(struct mmc_host *mmc)
{
struct sdhci_host *host = mmc_priv(mmc);
@@ -314,6 +485,7 @@ static const struct sdhci_ops spacemit_sdhci_ops = {
.set_clock = spacemit_sdhci_set_clock,
.set_uhs_signaling = spacemit_sdhci_set_uhs_signaling,
.voltage_switch = spacemit_sdhci_voltage_switch,
+ .platform_execute_tuning = spacemit_sdhci_execute_tuning,
};
static const struct sdhci_pltfm_data spacemit_sdhci_k1_pdata = {
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v3 3/7] mmc: sdhci-of-k1: add comprehensive SDR tuning support
2026-03-16 14:03 ` [PATCH v3 3/7] mmc: sdhci-of-k1: add comprehensive SDR tuning support Iker Pedrosa
@ 2026-03-17 11:33 ` Adrian Hunter
0 siblings, 0 replies; 18+ messages in thread
From: Adrian Hunter @ 2026-03-17 11:33 UTC (permalink / raw)
To: Iker Pedrosa, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Anand Moon
On 16/03/2026 16:03, Iker Pedrosa wrote:
> Implement software tuning algorithm to enable UHS-I SDR modes for SD
> card operation and HS200 mode for eMMC. This adds both TX and RX delay
> line tuning based on the SpacemiT K1 controller capabilities.
>
> Algorithm features:
> - Add tuning register definitions (RX_CFG, DLINE_CTRL, DLINE_CFG)
> - Conditional tuning: only for high-speed modes (≥100MHz)
> - TX tuning: configure transmit delay line with optimal values
> (dline_reg=0, delaycode=127) to ensure optimal signal output timing
> - RX tuning: single-pass window detection algorithm testing full
> delay range (0-255) to find optimal receive timing window
> - Retry mechanism: multiple fallback delays within optimal window
> for improved reliability
>
> Tested-by: Anand Moon <linux.amoon@gmail.com>
> Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
> drivers/mmc/host/sdhci-of-k1.c | 172 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 172 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c
> index 01afdadcf70796704b272ee5a31543afd5e01188..83d7f9fad5c1fba2f07624ee657cd979a1c7e25d 100644
> --- a/drivers/mmc/host/sdhci-of-k1.c
> +++ b/drivers/mmc/host/sdhci-of-k1.c
> @@ -69,6 +69,28 @@
> #define SDHC_PHY_DRIVE_SEL GENMASK(2, 0)
> #define SDHC_RX_BIAS_CTRL BIT(5)
>
> +#define SPACEMIT_SDHC_RX_CFG_REG 0x118
> +#define SDHC_RX_SDCLK_SEL0_MASK GENMASK(1, 0)
> +#define SDHC_RX_SDCLK_SEL1_MASK GENMASK(3, 2)
> +#define SDHC_RX_SDCLK_SEL1 FIELD_PREP(SDHC_RX_SDCLK_SEL1_MASK, 1)
> +
> +#define SPACEMIT_SDHC_DLINE_CTRL_REG 0x130
> +#define SDHC_DLINE_PU BIT(0)
> +#define SDHC_RX_DLINE_CODE_MASK GENMASK(23, 16)
> +#define SDHC_TX_DLINE_CODE_MASK GENMASK(31, 24)
> +
> +#define SPACEMIT_SDHC_DLINE_CFG_REG 0x134
> +#define SDHC_RX_DLINE_REG_MASK GENMASK(7, 0)
> +#define SDHC_RX_DLINE_GAIN BIT(8)
> +#define SDHC_TX_DLINE_REG_MASK GENMASK(23, 16)
> +
> +#define SPACEMIT_RX_DLINE_REG 9
> +#define SPACEMIT_RX_TUNE_DELAY_MIN 0x0
> +#define SPACEMIT_RX_TUNE_DELAY_MAX 0xFF
> +
> +#define SPACEMIT_TX_TUNING_DLINE_REG 0x00
> +#define SPACEMIT_TX_TUNING_DELAYCODE 127
> +
> struct spacemit_sdhci_host {
> struct clk *clk_core;
> struct clk *clk_io;
> @@ -96,6 +118,50 @@ static inline void spacemit_sdhci_clrsetbits(struct sdhci_host *host, u32 clr, u
> sdhci_writel(host, val, reg);
> }
>
> +static void spacemit_sdhci_set_rx_delay(struct sdhci_host *host, u8 delay)
> +{
> + spacemit_sdhci_clrsetbits(host, SDHC_RX_DLINE_CODE_MASK,
> + FIELD_PREP(SDHC_RX_DLINE_CODE_MASK, delay),
> + SPACEMIT_SDHC_DLINE_CTRL_REG);
> +}
> +
> +static void spacemit_sdhci_set_tx_delay(struct sdhci_host *host, u8 delay)
> +{
> + spacemit_sdhci_clrsetbits(host, SDHC_TX_DLINE_CODE_MASK,
> + FIELD_PREP(SDHC_TX_DLINE_CODE_MASK, delay),
> + SPACEMIT_SDHC_DLINE_CTRL_REG);
> +}
> +
> +static void spacemit_sdhci_set_tx_dline_reg(struct sdhci_host *host, u8 dline_reg)
> +{
> + spacemit_sdhci_clrsetbits(host, SDHC_TX_DLINE_REG_MASK,
> + FIELD_PREP(SDHC_TX_DLINE_REG_MASK, dline_reg),
> + SPACEMIT_SDHC_DLINE_CFG_REG);
> +}
> +
> +static void spacemit_sdhci_tx_tuning_prepare(struct sdhci_host *host)
> +{
> + spacemit_sdhci_setbits(host, SDHC_TX_MUX_SEL, SPACEMIT_SDHC_TX_CFG_REG);
> + spacemit_sdhci_setbits(host, SDHC_DLINE_PU, SPACEMIT_SDHC_DLINE_CTRL_REG);
> + udelay(5);
> +}
> +
> +static void spacemit_sdhci_prepare_tuning(struct sdhci_host *host)
> +{
> + spacemit_sdhci_clrsetbits(host, SDHC_RX_DLINE_REG_MASK,
> + FIELD_PREP(SDHC_RX_DLINE_REG_MASK, SPACEMIT_RX_DLINE_REG),
> + SPACEMIT_SDHC_DLINE_CFG_REG);
> +
> + spacemit_sdhci_setbits(host, SDHC_DLINE_PU, SPACEMIT_SDHC_DLINE_CTRL_REG);
> + udelay(5);
> +
> + spacemit_sdhci_clrsetbits(host, SDHC_RX_SDCLK_SEL1_MASK, SDHC_RX_SDCLK_SEL1,
> + SPACEMIT_SDHC_RX_CFG_REG);
> +
> + if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200)
> + spacemit_sdhci_setbits(host, SDHC_HS200_USE_RFIFO, SPACEMIT_SDHC_PHY_FUNC_REG);
> +}
> +
> static void spacemit_sdhci_reset(struct sdhci_host *host, u8 mask)
> {
> sdhci_reset(host, mask);
> @@ -191,6 +257,111 @@ static unsigned int spacemit_sdhci_clk_get_max_clock(struct sdhci_host *host)
> return clk_get_rate(pltfm_host->clk);
> }
>
> +static int spacemit_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
> +{
> + int current_len = 0, current_start = 0;
> + int max_pass_len = 0, max_pass_start = 0;
> + struct mmc_host *mmc = host->mmc;
> + struct mmc_ios ios = mmc->ios;
> + u8 final_delay;
> + int ret = 0;
> + int i;
> +
> + /*
> + * Tuning is required for SDR50/SDR104, HS200/HS400 cards and
> + * if clock frequency is greater than 100MHz in these modes.
> + */
> + if (host->clock < 100 * 1000 * 1000 ||
> + !(ios.timing == MMC_TIMING_MMC_HS200 ||
> + ios.timing == MMC_TIMING_UHS_SDR50 ||
> + ios.timing == MMC_TIMING_UHS_SDR104))
> + return 0;
> +
> + if (mmc->caps2 & MMC_CAP2_NO_MMC) {
> + spacemit_sdhci_set_tx_dline_reg(host, SPACEMIT_TX_TUNING_DLINE_REG);
> + spacemit_sdhci_set_tx_delay(host, SPACEMIT_TX_TUNING_DELAYCODE);
> + spacemit_sdhci_tx_tuning_prepare(host);
> +
> + dev_dbg(mmc_dev(host->mmc), "TX tuning: dline_reg=%d, delaycode=%d\n",
> + SPACEMIT_TX_TUNING_DLINE_REG, SPACEMIT_TX_TUNING_DELAYCODE);
> + }
> +
> + spacemit_sdhci_prepare_tuning(host);
> +
> + for (i = SPACEMIT_RX_TUNE_DELAY_MIN; i <= SPACEMIT_RX_TUNE_DELAY_MAX; i++) {
> + spacemit_sdhci_set_rx_delay(host, i);
> + ret = mmc_send_tuning(host->mmc, opcode, NULL);
> +
> + dev_dbg(mmc_dev(host->mmc), "RX delay %d: %s\n",
> + i, ret == 0 ? "pass" : "fail");
> +
> + if (ret == 0) {
> + /* Test passed - extend current window */
> + if (current_len == 0)
> + current_start = i;
> + current_len++;
> + } else {
> + /* Test failed - check if current window is best so far */
> + if (current_len > max_pass_len) {
> + max_pass_len = current_len;
> + max_pass_start = current_start;
> + }
> + current_len = 0;
> + }
> + }
> +
> + if (current_len > max_pass_len) {
> + max_pass_len = current_len;
> + max_pass_start = current_start;
> + }
> +
> + if (max_pass_len < 3) {
> + dev_err(mmc_dev(host->mmc), "Tuning failed: no stable window found\n");
> + return -EIO;
> + }
> +
> + final_delay = max_pass_start + max_pass_len / 2;
> + spacemit_sdhci_set_rx_delay(host, final_delay);
> + ret = mmc_send_tuning(host->mmc, opcode, NULL);
> + if (ret) {
> + u8 retry_delays[] = {
> + max_pass_start + max_pass_len / 4,
> + max_pass_start + (3 * max_pass_len) / 4,
> + max_pass_start,
> + max_pass_start + max_pass_len - 1
> + };
> + int retry_count = ARRAY_SIZE(retry_delays);
> +
> + dev_warn(mmc_dev(mmc), "Primary delay %d failed, trying alternatives\n",
> + final_delay);
> +
> + for (i = 0; i < retry_count; i++) {
> + if (retry_delays[i] >= SPACEMIT_RX_TUNE_DELAY_MIN &&
> + retry_delays[i] <= SPACEMIT_RX_TUNE_DELAY_MAX) {
> + spacemit_sdhci_set_rx_delay(host, retry_delays[i]);
> + ret = mmc_send_tuning(host->mmc, opcode, NULL);
> + if (!ret) {
> + final_delay = retry_delays[i];
> + dev_info(mmc_dev(mmc), "Retry successful with delay %d\n",
> + final_delay);
> + break;
> + }
> + }
> + }
> +
> + if (ret) {
> + dev_err(mmc_dev(mmc), "All retry attempts failed\n");
> + return -EIO;
> + }
> + }
> +
> + dev_dbg(mmc_dev(host->mmc),
> + "Tuning successful: window %d-%d, using delay %d\n",
> + max_pass_start, max_pass_start + max_pass_len - 1, final_delay);
> +
> + return 0;
> +}
> +
> static int spacemit_sdhci_pre_select_hs400(struct mmc_host *mmc)
> {
> struct sdhci_host *host = mmc_priv(mmc);
> @@ -314,6 +485,7 @@ static const struct sdhci_ops spacemit_sdhci_ops = {
> .set_clock = spacemit_sdhci_set_clock,
> .set_uhs_signaling = spacemit_sdhci_set_uhs_signaling,
> .voltage_switch = spacemit_sdhci_voltage_switch,
> + .platform_execute_tuning = spacemit_sdhci_execute_tuning,
> };
>
> static const struct sdhci_pltfm_data spacemit_sdhci_k1_pdata = {
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3 4/7] riscv: dts: spacemit: k1: add SD card controller and pinctrl support
2026-03-16 14:03 [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2 Iker Pedrosa
` (2 preceding siblings ...)
2026-03-16 14:03 ` [PATCH v3 3/7] mmc: sdhci-of-k1: add comprehensive SDR tuning support Iker Pedrosa
@ 2026-03-16 14:03 ` Iker Pedrosa
2026-03-16 14:03 ` [PATCH v3 5/7] riscv: dts: spacemit: k1-orangepi-rv2: add PMIC and power infrastructure Iker Pedrosa
` (3 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Iker Pedrosa @ 2026-03-16 14:03 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon
Add SD card controller infrastructure for SpacemiT K1 SoC with complete
pinctrl support for both standard and UHS modes.
- Add sdhci0 controller definition with clocks, resets and interrupts
- Add mmc1_cfg pinctrl for 3.3V standard SD operation
- Add mmc1_uhs_cfg pinctrl for 1.8V UHS high-speed operation
- Configure appropriate drive strength and power-source properties
This provides complete SD card infrastructure that K1-based boards can
enable.
Tested-by: Anand Moon <linux.amoon@gmail.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi | 40 ++++++++++++++++++++++++++++
arch/riscv/boot/dts/spacemit/k1.dtsi | 13 +++++++++
2 files changed, 53 insertions(+)
diff --git a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
index b13dcb10f4d66022d27307de73a6ea3287e97441..8d82011f1af666fb78c282a2abcc0cb88f962053 100644
--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
@@ -570,4 +570,44 @@ pwm14-1-pins {
drive-strength = <32>;
};
};
+
+ mmc1_cfg: mmc1-cfg {
+ mmc1-data-cmd-pins {
+ pinmux = <K1_PADCONF(104, 0)>, /* mmc1_d3 */
+ <K1_PADCONF(105, 0)>, /* mmc1_d2 */
+ <K1_PADCONF(106, 0)>, /* mmc1_d1 */
+ <K1_PADCONF(107, 0)>, /* mmc1_d0 */
+ <K1_PADCONF(108, 0)>; /* mmc1_cmd */
+ bias-pull-up = <1>;
+ drive-strength = <7>;
+ power-source = <3300>;
+ };
+
+ mmc1-clk-pins {
+ pinmux = <K1_PADCONF(109, 0)>; /* mmc1_clk */
+ bias-pull-down = <1>;
+ drive-strength = <7>;
+ power-source = <3300>;
+ };
+ };
+
+ mmc1_uhs_cfg: mmc1-uhs-cfg {
+ mmc1-data-cmd-pins {
+ pinmux = <K1_PADCONF(104, 0)>, /* mmc1_d3 */
+ <K1_PADCONF(105, 0)>, /* mmc1_d2 */
+ <K1_PADCONF(106, 0)>, /* mmc1_d1 */
+ <K1_PADCONF(107, 0)>, /* mmc1_d0 */
+ <K1_PADCONF(108, 0)>; /* mmc1_cmd */
+ bias-pull-up = <1>;
+ drive-strength = <13>;
+ power-source = <1800>;
+ };
+
+ mmc1-clk-pins {
+ pinmux = <K1_PADCONF(109, 0)>; /* mmc1_clk */
+ bias-pull-down = <1>;
+ drive-strength = <13>;
+ power-source = <1800>;
+ };
+ };
};
diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
index d2015201f8e5adff8bda75712036b8dc2b79bcb5..3952c4d0ecfb26e9d215955ca8791243bbd1dab7 100644
--- a/arch/riscv/boot/dts/spacemit/k1.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
@@ -1211,6 +1211,19 @@ emmc: mmc@d4281000 {
interrupts = <101>;
status = "disabled";
};
+
+ sdhci0: mmc@d4280000 {
+ compatible = "spacemit,k1-sdhci";
+ reg = <0x0 0xd4280000 0x0 0x200>;
+ clocks = <&syscon_apmu CLK_SDH_AXI>,
+ <&syscon_apmu CLK_SDH0>;
+ clock-names = "core", "io";
+ resets = <&syscon_apmu RESET_SDH_AXI>,
+ <&syscon_apmu RESET_SDH0>;
+ reset-names = "axi", "sdh";
+ interrupts = <99>;
+ status = "disabled";
+ };
};
};
};
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v3 5/7] riscv: dts: spacemit: k1-orangepi-rv2: add PMIC and power infrastructure
2026-03-16 14:03 [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2 Iker Pedrosa
` (3 preceding siblings ...)
2026-03-16 14:03 ` [PATCH v3 4/7] riscv: dts: spacemit: k1: add SD card controller and pinctrl support Iker Pedrosa
@ 2026-03-16 14:03 ` Iker Pedrosa
2026-03-17 20:24 ` Trevor Gamblin
2026-03-16 14:03 ` [PATCH v3 6/7] riscv: dts: spacemit: k1-orangepi-rv2: add SD card support with UHS modes Iker Pedrosa
` (2 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Iker Pedrosa @ 2026-03-16 14:03 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon
Add Spacemit P1 PMIC configuration and board power infrastructure for
voltage regulation support.
- Add board power regulators (12V input, 4V rail)
- Enable I2C8 for PMIC communication
- Configure PMIC with buck4 (vmmc) and aldo1 (vqmmc) regulators
- Set up regulator constraints for SD card operation
Tested-by: Anand Moon <linux.amoon@gmail.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 48 ++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
index 7b7331cb3c726f11d597f81917f3a3f5fc21e1b9..f1533c99881dbf38e16cff5e91e33253cfa7a56d 100644
--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
@@ -19,6 +19,25 @@ aliases {
ethernet1 = ð1;
};
+ reg_dc_in: dc-in-12v {
+ compatible = "regulator-fixed";
+ regulator-name = "dc_in_12v";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_vcc_4v: vcc-4v {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_4v";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <4000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ vin-supply = <®_dc_in>;
+ };
+
chosen {
stdout-path = "serial0";
};
@@ -92,3 +111,32 @@ &uart0 {
pinctrl-0 = <&uart0_2_cfg>;
status = "okay";
};
+
+&i2c8 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c8_cfg>;
+ status = "okay";
+
+ pmic@41 {
+ compatible = "spacemit,p1";
+ reg = <0x41>;
+ interrupts = <64>;
+ vin-supply = <®_vcc_4v>;
+
+ regulators {
+ buck4: buck4 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <5000>;
+ regulator-always-on;
+ };
+
+ aldo1: aldo1 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v3 5/7] riscv: dts: spacemit: k1-orangepi-rv2: add PMIC and power infrastructure
2026-03-16 14:03 ` [PATCH v3 5/7] riscv: dts: spacemit: k1-orangepi-rv2: add PMIC and power infrastructure Iker Pedrosa
@ 2026-03-17 20:24 ` Trevor Gamblin
0 siblings, 0 replies; 18+ messages in thread
From: Trevor Gamblin @ 2026-03-17 20:24 UTC (permalink / raw)
To: Iker Pedrosa, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Adrian Hunter, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Anand Moon
On 2026-03-16 10:03, Iker Pedrosa wrote:
> Add Spacemit P1 PMIC configuration and board power infrastructure for
> voltage regulation support.
>
> - Add board power regulators (12V input, 4V rail)
> - Enable I2C8 for PMIC communication
> - Configure PMIC with buck4 (vmmc) and aldo1 (vqmmc) regulators
> - Set up regulator constraints for SD card operation
>
> Tested-by: Anand Moon <linux.amoon@gmail.com>
> Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
> ---
> arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 48 ++++++++++++++++++++++++
> 1 file changed, 48 insertions(+)
>
> diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
> index 7b7331cb3c726f11d597f81917f3a3f5fc21e1b9..f1533c99881dbf38e16cff5e91e33253cfa7a56d 100644
> --- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
> +++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
> @@ -19,6 +19,25 @@ aliases {
> ethernet1 = ð1;
> };
>
> + reg_dc_in: dc-in-12v {
> + compatible = "regulator-fixed";
> + regulator-name = "dc_in_12v";
> + regulator-min-microvolt = <12000000>;
> + regulator-max-microvolt = <12000000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
Hi,
This still shows 12V instead of the 5V connector listed in the board's spec.
I was able to test it without issue, but this should be fixed up.
> +
> + reg_vcc_4v: vcc-4v {
> + compatible = "regulator-fixed";
> + regulator-name = "vcc_4v";
> + regulator-min-microvolt = <4000000>;
> + regulator-max-microvolt = <4000000>;
> + regulator-boot-on;
> + regulator-always-on;
> + vin-supply = <®_dc_in>;
> + };
> +
> chosen {
> stdout-path = "serial0";
> };
> @@ -92,3 +111,32 @@ &uart0 {
> pinctrl-0 = <&uart0_2_cfg>;
> status = "okay";
> };
> +
> +&i2c8 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c8_cfg>;
> + status = "okay";
> +
> + pmic@41 {
> + compatible = "spacemit,p1";
> + reg = <0x41>;
> + interrupts = <64>;
> + vin-supply = <®_vcc_4v>;
> +
> + regulators {
> + buck4: buck4 {
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-ramp-delay = <5000>;
> + regulator-always-on;
> + };
> +
> + aldo1: aldo1 {
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <3400000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> + };
> + };
> +};
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3 6/7] riscv: dts: spacemit: k1-orangepi-rv2: add SD card support with UHS modes
2026-03-16 14:03 [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2 Iker Pedrosa
` (4 preceding siblings ...)
2026-03-16 14:03 ` [PATCH v3 5/7] riscv: dts: spacemit: k1-orangepi-rv2: add PMIC and power infrastructure Iker Pedrosa
@ 2026-03-16 14:03 ` Iker Pedrosa
2026-03-17 15:54 ` Michael Opdenacker
2026-03-16 14:03 ` [PATCH v3 7/7] riscv: dts: spacemit: k1-bananapi-f3: " Iker Pedrosa
2026-03-17 20:23 ` [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2 Trevor Gamblin
7 siblings, 1 reply; 18+ messages in thread
From: Iker Pedrosa @ 2026-03-16 14:03 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon, Trevor Gamblin
Add complete SD card controller support with UHS high-speed modes.
- Enable sdhci0 controller with 4-bit bus width
- Configure card detect GPIO with inversion
- Connect vmmc-supply to buck4 for 3.3V card power
- Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching
- Add dual pinctrl states for voltage-dependent pin configuration
- Support UHS-I SDR25, SDR50, and SDR104 modes
This enables full SD card functionality including high-speed UHS modes
for improved performance.
Tested-by: Anand Moon <linux.amoon@gmail.com>
Tested-by: Trevor Gamblin <tgamblin@baylibre.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
index f1533c99881dbf38e16cff5e91e33253cfa7a56d..aff23846085d22d1e9cd77434bffd2816ad59e12 100644
--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
@@ -140,3 +140,22 @@ aldo1: aldo1 {
};
};
};
+
+&sdhci0 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc1_cfg>;
+ pinctrl-1 = <&mmc1_uhs_cfg>;
+ bus-width = <4>;
+ cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ no-mmc;
+ no-sdio;
+ disable-wp;
+ cap-sd-highspeed;
+ vmmc-supply = <&buck4>;
+ vqmmc-supply = <&aldo1>;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v3 6/7] riscv: dts: spacemit: k1-orangepi-rv2: add SD card support with UHS modes
2026-03-16 14:03 ` [PATCH v3 6/7] riscv: dts: spacemit: k1-orangepi-rv2: add SD card support with UHS modes Iker Pedrosa
@ 2026-03-17 15:54 ` Michael Opdenacker
0 siblings, 0 replies; 18+ messages in thread
From: Michael Opdenacker @ 2026-03-17 15:54 UTC (permalink / raw)
To: Iker Pedrosa, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Adrian Hunter, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Yixun Lan
Cc: michael.opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Anand Moon,
Trevor Gamblin
Hi Iker
Thanks for the update!
On 3/16/26 3:03 PM, Iker Pedrosa wrote:
> Add complete SD card controller support with UHS high-speed modes.
>
> - Enable sdhci0 controller with 4-bit bus width
> - Configure card detect GPIO with inversion
> - Connect vmmc-supply to buck4 for 3.3V card power
> - Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching
> - Add dual pinctrl states for voltage-dependent pin configuration
> - Support UHS-I SDR25, SDR50, and SDR104 modes
>
> This enables full SD card functionality including high-speed UHS modes
> for improved performance.
>
> Tested-by: Anand Moon <linux.amoon@gmail.com>
> Tested-by: Trevor Gamblin <tgamblin@baylibre.com>
> Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
> ---
> arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
> index f1533c99881dbf38e16cff5e91e33253cfa7a56d..aff23846085d22d1e9cd77434bffd2816ad59e12 100644
> --- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
> +++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
> @@ -140,3 +140,22 @@ aldo1: aldo1 {
> };
> };
> };
> +
> +&sdhci0 {
> + pinctrl-names = "default", "state_uhs";
> + pinctrl-0 = <&mmc1_cfg>;
> + pinctrl-1 = <&mmc1_uhs_cfg>;
> + bus-width = <4>;
> + cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_HIGH>;
> + cd-inverted;
> + no-mmc;
> + no-sdio;
> + disable-wp;
> + cap-sd-highspeed;
> + vmmc-supply = <&buck4>;
> + vqmmc-supply = <&aldo1>;
> + sd-uhs-sdr25;
> + sd-uhs-sdr50;
> + sd-uhs-sdr104;
> + status = "okay";
> +};
Tested successfully on OrangePi RV2.
Tested-by: Michael Opdenacker <michael.opdenacker@rootcommit.com>
Cheers
Michael
--
Root Commit
Embedded Linux Training and Consulting
https://rootcommit.com
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3 7/7] riscv: dts: spacemit: k1-bananapi-f3: add SD card support with UHS modes
2026-03-16 14:03 [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2 Iker Pedrosa
` (5 preceding siblings ...)
2026-03-16 14:03 ` [PATCH v3 6/7] riscv: dts: spacemit: k1-orangepi-rv2: add SD card support with UHS modes Iker Pedrosa
@ 2026-03-16 14:03 ` Iker Pedrosa
2026-03-18 20:24 ` Aurelien Jarno
2026-03-17 20:23 ` [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2 Trevor Gamblin
7 siblings, 1 reply; 18+ messages in thread
From: Iker Pedrosa @ 2026-03-16 14:03 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon
Add complete SD card controller support with UHS high-speed modes.
- Enable sdhci0 controller with 4-bit bus width
- Configure card detect GPIO with inversion
- Connect vmmc-supply to buck4 for 3.3V card power
- Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching
- Add dual pinctrl states for voltage-dependent pin configuration
- Support UHS-I SDR25, SDR50, and SDR104 modes
This enables full SD card functionality including high-speed UHS modes
for improved performance.
Suggested-by: Anand Moon <linux.amoon@gmail.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
index 404b69c47b91f8c37d74a3031dbad0d94a28d1b4..a7d480d01ccc0439dbf456ed5a81f467af68056a 100644
--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
@@ -222,7 +222,7 @@ buck3_1v8: buck3 {
regulator-always-on;
};
- buck4 {
+ buck4: buck4 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <3300000>;
regulator-ramp-delay = <5000>;
@@ -243,7 +243,7 @@ buck6 {
regulator-always-on;
};
- aldo1 {
+ aldo1: aldo1 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <3400000>;
regulator-boot-on;
@@ -369,3 +369,22 @@ hub_3_0: hub@2 {
reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>;
};
};
+
+&sdhci0 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc1_cfg>;
+ pinctrl-1 = <&mmc1_uhs_cfg>;
+ bus-width = <4>;
+ cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ no-mmc;
+ no-sdio;
+ disable-wp;
+ cap-sd-highspeed;
+ vmmc-supply = <&buck4>;
+ vqmmc-supply = <&aldo1>;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v3 7/7] riscv: dts: spacemit: k1-bananapi-f3: add SD card support with UHS modes
2026-03-16 14:03 ` [PATCH v3 7/7] riscv: dts: spacemit: k1-bananapi-f3: " Iker Pedrosa
@ 2026-03-18 20:24 ` Aurelien Jarno
2026-03-19 1:53 ` Yixun Lan
0 siblings, 1 reply; 18+ messages in thread
From: Aurelien Jarno @ 2026-03-18 20:24 UTC (permalink / raw)
To: Iker Pedrosa
Cc: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Michael Opdenacker,
Javier Martinez Canillas, linux-mmc, devicetree, linux-riscv,
spacemit, linux-kernel, Anand Moon
Hi,
On 2026-03-16 15:03, Iker Pedrosa wrote:
> Add complete SD card controller support with UHS high-speed modes.
>
> - Enable sdhci0 controller with 4-bit bus width
> - Configure card detect GPIO with inversion
> - Connect vmmc-supply to buck4 for 3.3V card power
> - Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching
> - Add dual pinctrl states for voltage-dependent pin configuration
> - Support UHS-I SDR25, SDR50, and SDR104 modes
>
> This enables full SD card functionality including high-speed UHS modes
> for improved performance.
>
> Suggested-by: Anand Moon <linux.amoon@gmail.com>
> Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
> ---
> arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 23 +++++++++++++++++++++--
> 1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> index 404b69c47b91f8c37d74a3031dbad0d94a28d1b4..a7d480d01ccc0439dbf456ed5a81f467af68056a 100644
> --- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> +++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> @@ -222,7 +222,7 @@ buck3_1v8: buck3 {
> regulator-always-on;
> };
>
> - buck4 {
> + buck4: buck4 {
> regulator-min-microvolt = <500000>;
> regulator-max-microvolt = <3300000>;
> regulator-ramp-delay = <5000>;
> @@ -243,7 +243,7 @@ buck6 {
> regulator-always-on;
> };
>
> - aldo1 {
> + aldo1: aldo1 {
> regulator-min-microvolt = <500000>;
> regulator-max-microvolt = <3400000>;
> regulator-boot-on;
> @@ -369,3 +369,22 @@ hub_3_0: hub@2 {
> reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>;
> };
> };
> +
> +&sdhci0 {
> + pinctrl-names = "default", "state_uhs";
> + pinctrl-0 = <&mmc1_cfg>;
> + pinctrl-1 = <&mmc1_uhs_cfg>;
> + bus-width = <4>;
> + cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_HIGH>;
> + cd-inverted;
Thanks for this driver. Unfortunately, this is not correct for the
Banana PI F3. The OrangePi RV2 buffers the signal from the SD card
connector through a transistor, inverting the signal. On the Banana PI
F3, the signal goes directly to the GPIO, and does not even have a
pull-up.
With the following change, I have been able to get the patchset working
as expected:
diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
index a7d480d01ccc0..72b0f75f936aa 100644
--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
@@ -375,8 +375,7 @@ &sdhci0 {
pinctrl-0 = <&mmc1_cfg>;
pinctrl-1 = <&mmc1_uhs_cfg>;
bus-width = <4>;
- cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_HIGH>;
- cd-inverted;
+ cd-gpios = <&gpio K1_GPIO(80) (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
no-mmc;
no-sdio;
disable-wp;
Regards
Aurelien
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://aurel32.net
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v3 7/7] riscv: dts: spacemit: k1-bananapi-f3: add SD card support with UHS modes
2026-03-18 20:24 ` Aurelien Jarno
@ 2026-03-19 1:53 ` Yixun Lan
0 siblings, 0 replies; 18+ messages in thread
From: Yixun Lan @ 2026-03-19 1:53 UTC (permalink / raw)
To: Iker Pedrosa, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Adrian Hunter, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Michael Opdenacker,
Javier Martinez Canillas, linux-mmc, devicetree, linux-riscv,
spacemit, linux-kernel, Anand Moon
Hi Aurelien,
On 21:24 Wed 18 Mar , Aurelien Jarno wrote:
> Hi,
>
> On 2026-03-16 15:03, Iker Pedrosa wrote:
> > Add complete SD card controller support with UHS high-speed modes.
> >
> > - Enable sdhci0 controller with 4-bit bus width
> > - Configure card detect GPIO with inversion
> > - Connect vmmc-supply to buck4 for 3.3V card power
> > - Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching
> > - Add dual pinctrl states for voltage-dependent pin configuration
> > - Support UHS-I SDR25, SDR50, and SDR104 modes
> >
> > This enables full SD card functionality including high-speed UHS modes
> > for improved performance.
> >
> > Suggested-by: Anand Moon <linux.amoon@gmail.com>
> > Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
> > ---
> > arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 23 +++++++++++++++++++++--
> > 1 file changed, 21 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> > index 404b69c47b91f8c37d74a3031dbad0d94a28d1b4..a7d480d01ccc0439dbf456ed5a81f467af68056a 100644
> > --- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> > +++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> > @@ -222,7 +222,7 @@ buck3_1v8: buck3 {
> > regulator-always-on;
> > };
> >
> > - buck4 {
> > + buck4: buck4 {
> > regulator-min-microvolt = <500000>;
> > regulator-max-microvolt = <3300000>;
> > regulator-ramp-delay = <5000>;
> > @@ -243,7 +243,7 @@ buck6 {
> > regulator-always-on;
> > };
> >
> > - aldo1 {
> > + aldo1: aldo1 {
> > regulator-min-microvolt = <500000>;
> > regulator-max-microvolt = <3400000>;
> > regulator-boot-on;
> > @@ -369,3 +369,22 @@ hub_3_0: hub@2 {
> > reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>;
> > };
> > };
> > +
> > +&sdhci0 {
> > + pinctrl-names = "default", "state_uhs";
> > + pinctrl-0 = <&mmc1_cfg>;
> > + pinctrl-1 = <&mmc1_uhs_cfg>;
> > + bus-width = <4>;
> > + cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_HIGH>;
> > + cd-inverted;
>
> Thanks for this driver. Unfortunately, this is not correct for the
> Banana PI F3. The OrangePi RV2 buffers the signal from the SD card
> connector through a transistor, inverting the signal. On the Banana PI
> F3, the signal goes directly to the GPIO, and does not even have a
> pull-up.
>
> With the following change, I have been able to get the patchset working
> as expected:
>
> diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> index a7d480d01ccc0..72b0f75f936aa 100644
> --- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> +++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> @@ -375,8 +375,7 @@ &sdhci0 {
> pinctrl-0 = <&mmc1_cfg>;
> pinctrl-1 = <&mmc1_uhs_cfg>;
> bus-width = <4>;
> - cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_HIGH>;
> - cd-inverted;
> + cd-gpios = <&gpio K1_GPIO(80) (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
Have to mention, to use the pull-up, the patch to support gpio config should be applied
https://lore.kernel.org/r/20260312-k1-gpio-set-config-v1-0-8c3541da16b1@pigmoral.tech
if you don't want to introduce the dependency, add "broken-cd" property
should also workaround this..
> no-mmc;
> no-sdio;
> disable-wp;
>
> Regards
> Aurelien
>
> --
> Aurelien Jarno GPG: 4096R/1DDD8C9B
> aurelien@aurel32.net http://aurel32.net
--
Yixun Lan (dlan)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2
2026-03-16 14:03 [PATCH v3 0/7] riscv: spacemit: enable SD card support with UHS modes for OrangePi RV2 Iker Pedrosa
` (6 preceding siblings ...)
2026-03-16 14:03 ` [PATCH v3 7/7] riscv: dts: spacemit: k1-bananapi-f3: " Iker Pedrosa
@ 2026-03-17 20:23 ` Trevor Gamblin
7 siblings, 0 replies; 18+ messages in thread
From: Trevor Gamblin @ 2026-03-17 20:23 UTC (permalink / raw)
To: Iker Pedrosa, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Adrian Hunter, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Anand Moon
On 2026-03-16 10:03, Iker Pedrosa wrote:
> This series enables complete SD card support for the Spacemit K1-based
> OrangePi RV2 board, including UHS (Ultra High Speed) modes for
> high-performance SD card operation.
>
> Background
>
> The Spacemit K1 SoC includes an SDHCI controller capable of supporting
> SD cards up to UHS-I speeds (SDR104 at 208MHz). However, mainline
> currently lacks basic SD controller configuration, SDHCI driver
> enhancements for voltage switching and tuning, and power management
> infrastructure.
>
> Implementation
>
> The series enables SD card support through coordinated layers:
>
> - Hardware infrastructure (patches 1-2): Device tree bindings for voltage
> switching hardware and essential clock infrastructure.
> - SDHCI driver enhancements (patches 3-7): Regulator framework
> integration, pinctrl state switching for voltage domains, AIB register
> programming, and comprehensive SDR tuning support for reliable UHS
> operation.
> - SoC and board integration (patches 8-10): Complete K1 SoC controller
> definitions, PMIC power infrastructure, and OrangePi RV2 board enablement
> with full UHS support.
>
> This transforms the OrangePi RV2 from having no SD card support to full
> UHS-I capability, enabling high-performance storage up to 208MHz.
Hi,
For all patches except 7/7 (k1-bananapi-f3):
Tested-by: Trevor Gamblin <tgamblin@baylibre.com>
>
> Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
> ---
> Changes in v3:
> - Rebase on mmc.git/next to resolve conflicts with "mmc: sdhci-of-k1:
> add reset support" patch.
> - Squash tuning infrastructure and implementation patches (3 and 4)
> together to form complete functionality and avoid unused function
> warnings.
> - Reduce code nesting: implemented an early return sanity check in
> spacemit_sdhci_voltage_switch() to reduce indentation and improve
> logic flow.
> - Refactor pinctrl initialization: moved pinctrl resource acquisition
> and state lookup into a dedicated helper function,
> spacemit_sdhci_get_pins().
> - Use generic regulator node names (buck4, aldo1) instead of
> device-specific aliases (sd_vmmc, sd_vqmmc) to better reflect that
> these PMIC outputs serve multiple devices.
> - Remove dead code handling 3.3V voltage switching from
> spacemit_sdhci_voltage_switch().
> - Optimize tuning algorithm to use single-pass window detection instead
> of storing results in array, reducing memory usage and complexity.
> - Remove unnecessary card detect check in execute_tuning() - rely on MMC
> core.
> - Clarify commit message to mention both SD (UHS-I) and eMMC (HS200)
> tuning support.
> - Add SD card support for Banana Pi BPI-F3 board with UHS-I capabilities
> following the same pattern as OrangePi RV2.
> - Link to v2: https://lore.kernel.org/r/20260309-orangepi-sd-card-uhs-v2-0-5bb2b574df5d@gmail.com
>
> Changes in v2:
> - Removed custom AIB voltage switching code per maintainer feedback. The
> existing pinctrl driver already handles AIB voltage switching
> automatically via power-source property changes during UHS mode
> transitions. This eliminates code duplication.
> - Squashed regulator and pinctrl commits into single voltage switching
> implementation.
> - Moved voltage switching callback from dynamic probe assignment to
> static sdhci_ops declaration. Removed redundant SDHCI core call since
> the framework handles standard voltage switching automatically.
> - Made clock override (SDHC_OVRRD_CLK_OEN | SDHC_FORCE_CLK_ON)
> conditional for SD/SDIO cards only. This follows vendor driver pattern
> of differentiating SD and eMMC card handling.
> - Include no-mmc property for SD card.
> - Link to v1: https://lore.kernel.org/r/20260302-orangepi-sd-card-uhs-v1-0-89c219973c0c@gmail.com
>
> ---
> Iker Pedrosa (7):
> mmc: sdhci-of-k1: enable essential clock infrastructure for SD operation
> mmc: sdhci-of-k1: add regulator and pinctrl voltage switching support
> mmc: sdhci-of-k1: add comprehensive SDR tuning support
> riscv: dts: spacemit: k1: add SD card controller and pinctrl support
> riscv: dts: spacemit: k1-orangepi-rv2: add PMIC and power infrastructure
> riscv: dts: spacemit: k1-orangepi-rv2: add SD card support with UHS modes
> riscv: dts: spacemit: k1-bananapi-f3: add SD card support with UHS modes
>
> arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 23 ++-
> arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 67 +++++++
> arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi | 40 ++++
> arch/riscv/boot/dts/spacemit/k1.dtsi | 13 ++
> drivers/mmc/host/sdhci-of-k1.c | 243 +++++++++++++++++++++++
> 5 files changed, 384 insertions(+), 2 deletions(-)
> ---
> base-commit: f38f518dda1f1decc7a39556fe3231b0d1b84e1e
> change-id: 20260226-orangepi-sd-card-uhs-0ecb05839b0c
>
> Best regards,
^ permalink raw reply [flat|nested] 18+ messages in thread