From d931915b22bf7e0605697982dc04f9b1b5d84d79 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 9 Mar 2026 12:40:11 +0100 Subject: [PATCH 1/7] mmc: sdhci-of-k1: enable essential clock infrastructure for SD operation Ensure SD card pins receive clock signals by enabling pad clock generation and overriding automatic clock gating. Required for all SD operation modes. Signed-off-by: Iker Pedrosa Signed-off-by: Linux RISC-V bot --- 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 0cc97e23a2f9c7..585c7eca6ebf25 100644 --- a/drivers/mmc/host/sdhci-of-k1.c +++ b/drivers/mmc/host/sdhci-of-k1.c @@ -20,6 +20,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) @@ -100,6 +107,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) From 864fc93e640599ba12968220834fd24d39f88f03 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 9 Mar 2026 12:40:12 +0100 Subject: [PATCH 2/7] mmc: sdhci-of-k1: add regulator and pinctrl voltage switching support 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. Signed-off-by: Iker Pedrosa Signed-off-by: Linux RISC-V bot --- drivers/mmc/host/sdhci-of-k1.c | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c index 585c7eca6ebf25..8af117a8e271c0 100644 --- a/drivers/mmc/host/sdhci-of-k1.c +++ b/drivers/mmc/host/sdhci-of-k1.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "sdhci.h" @@ -70,6 +71,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 */ @@ -218,6 +222,42 @@ 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; + struct pinctrl_state *state; + int ret; + + /* Select appropriate pinctrl state based on signal voltage */ + if (sdhst->pinctrl) { + 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(host->mmc), "unsupported voltage %d\n", + ios->signal_voltage); + return; + } + + if (state) { + ret = pinctrl_select_state(sdhst->pinctrl, state); + if (ret) { + dev_warn(mmc_dev(host->mmc), + "failed to select pinctrl state: %d\n", ret); + return; + } + dev_dbg(mmc_dev(host->mmc), "switched to %s pinctrl state\n", + ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180 ? "UHS" : "default"); + } + } +} + static inline int spacemit_sdhci_get_clocks(struct device *dev, struct sdhci_pltfm_host *pltfm_host) { @@ -242,6 +282,7 @@ static const struct sdhci_ops spacemit_sdhci_ops = { .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 = { @@ -293,6 +334,24 @@ static int spacemit_sdhci_probe(struct platform_device *pdev) host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY; + sdhst = sdhci_pltfm_priv(pltfm_host); + sdhst->pinctrl = devm_pinctrl_get(dev); + if (!IS_ERR(sdhst->pinctrl)) { + 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); + } else { + sdhst->pinctrl = NULL; + dev_dbg(dev, "pinctrl not available, voltage switching will work without it\n"); + } + ret = spacemit_sdhci_get_clocks(dev, pltfm_host); if (ret) goto err_pltfm; From efec8e030b897f1f8ffa6191121067bf5780d136 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 9 Mar 2026 12:40:13 +0100 Subject: [PATCH 3/7] mmc: sdhci-of-k1: add SDR tuning infrastructure Add register definitions and delay line control functions to prepare for SDR50/SDR104 tuning support: - Add tuning register definitions (RX_CFG, DLINE_CTRL, DLINE_CFG) - Add delay line control helper functions - Add tuning preparation function This infrastructure prepares for implementing the SDR tuning algorithm while maintaining all existing functionality. Signed-off-by: Iker Pedrosa Signed-off-by: Linux RISC-V bot --- drivers/mmc/host/sdhci-of-k1.c | 61 ++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c index 8af117a8e271c0..79cb7c8d0b6d9c 100644 --- a/drivers/mmc/host/sdhci-of-k1.c +++ b/drivers/mmc/host/sdhci-of-k1.c @@ -68,6 +68,23 @@ #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 + struct spacemit_sdhci_host { struct clk *clk_core; struct clk *clk_io; @@ -95,6 +112,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); From 17f689b4ca69438b8ffca314c0581f84482b8462 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 9 Mar 2026 12:40:14 +0100 Subject: [PATCH 4/7] mmc: sdhci-of-k1: add comprehensive SDR tuning support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement software tuning algorithm to enable UHS-I SDR modes for SD card operation. This adds both TX and RX delay line tuning based on the SpacemiT K1 controller capabilities. Key features: - Conditional tuning: only tune when SD card is present and for high-speed modes (≥100MHz) - TX tuning: configure transmit delay line with default values (dline_reg=0, delaycode=127) to ensure optimal signal output timing - RX tuning: test full delay range (0-255) with window detection algorithm to find optimal receive timing - Retry mechanism: multiple fallback delays within optimal window for improved reliability - Complete register support: add delay line control and configuration register definitions for fine-grained timing control Signed-off-by: Iker Pedrosa Signed-off-by: Linux RISC-V bot --- drivers/mmc/host/sdhci-of-k1.c | 119 +++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c index 79cb7c8d0b6d9c..d903851b9be0e1 100644 --- a/drivers/mmc/host/sdhci-of-k1.c +++ b/drivers/mmc/host/sdhci-of-k1.c @@ -84,6 +84,12 @@ #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_RX_TUNE_DELAY_STEP 0x1 + +#define SPACEMIT_TX_TUNING_DLINE_REG 0x00 +#define SPACEMIT_TX_TUNING_DELAYCODE 127 struct spacemit_sdhci_host { struct clk *clk_core; @@ -251,6 +257,118 @@ 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 ret = 0; + int i; + bool pass_window[SPACEMIT_RX_TUNE_DELAY_MAX + 1] = {false}; + int pass_len = 0, pass_start = 0, max_pass_len = 0, max_pass_start = 0; + u8 final_delay; + struct mmc_host *mmc = host->mmc; + struct mmc_ios ios = mmc->ios; + + /* + * 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_SD) && !mmc->ops->get_cd(mmc)) + 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_RX_TUNE_DELAY_STEP) { + spacemit_sdhci_set_rx_delay(host, i); + + ret = mmc_send_tuning(host->mmc, opcode, NULL); + pass_window[i] = (ret == 0); + + dev_dbg(mmc_dev(host->mmc), "RX delay %d: %s\n", + i, pass_window[i] ? "pass" : "fail"); + } + + for (i = SPACEMIT_RX_TUNE_DELAY_MIN; i <= SPACEMIT_RX_TUNE_DELAY_MAX; + i += SPACEMIT_RX_TUNE_DELAY_STEP) { + if (pass_window[i]) { + if (pass_len == 0) + pass_start = i; + pass_len++; + } else { + if (pass_len > max_pass_len) { + max_pass_len = pass_len; + max_pass_start = pass_start; + } + pass_len = 0; + } + } + + if (pass_len > max_pass_len) { + max_pass_len = pass_len; + max_pass_start = pass_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); @@ -344,6 +462,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 = { From 84e3cf614acc01d554aa5ebfcaad79d75d01f543 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 9 Mar 2026 12:40:15 +0100 Subject: [PATCH 5/7] riscv: dts: spacemit: k1: add SD card controller and pinctrl support 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. Signed-off-by: Iker Pedrosa Signed-off-by: Linux RISC-V bot --- 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 b13dcb10f4d660..8d82011f1af666 100644 --- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi +++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi @@ -570,4 +570,44 @@ drive-strength = <32>; }; }; + + mmc1_cfg: mmc1-cfg { + mmc1-data-cmd-pins { + pinmux = , /* mmc1_d3 */ + , /* mmc1_d2 */ + , /* mmc1_d1 */ + , /* mmc1_d0 */ + ; /* mmc1_cmd */ + bias-pull-up = <1>; + drive-strength = <7>; + power-source = <3300>; + }; + + mmc1-clk-pins { + pinmux = ; /* mmc1_clk */ + bias-pull-down = <1>; + drive-strength = <7>; + power-source = <3300>; + }; + }; + + mmc1_uhs_cfg: mmc1-uhs-cfg { + mmc1-data-cmd-pins { + pinmux = , /* mmc1_d3 */ + , /* mmc1_d2 */ + , /* mmc1_d1 */ + , /* mmc1_d0 */ + ; /* mmc1_cmd */ + bias-pull-up = <1>; + drive-strength = <13>; + power-source = <1800>; + }; + + mmc1-clk-pins { + pinmux = ; /* 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 529ec68e9c23eb..1e9e4f4f41c196 100644 --- a/arch/riscv/boot/dts/spacemit/k1.dtsi +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi @@ -1207,6 +1207,19 @@ 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"; + }; }; }; }; From f07968e04d510bf2f6717e9cbcc3bfdcfab56fe2 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 9 Mar 2026 12:40:16 +0100 Subject: [PATCH 6/7] riscv: dts: spacemit: k1-orangepi-rv2: add PMIC and power infrastructure 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 Signed-off-by: Iker Pedrosa Signed-off-by: Linux RISC-V bot --- .../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 7b7331cb3c726f..414b03f5e6480f 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 @@ 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 @@ 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 { + sd_vmmc: buck4 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + sd_vqmmc: aldo1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; From 76b83bd9e9179ff4b2d3b8a8afe51660a6a5cdee Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 9 Mar 2026 12:40:17 +0100 Subject: [PATCH 7/7] riscv: dts: spacemit: k1-orangepi-rv2: add SD card support with UHS modes 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. Signed-off-by: Iker Pedrosa Signed-off-by: Linux RISC-V bot --- .../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 414b03f5e6480f..361135269801f4 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 @@ }; }; }; + +&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 = <&sd_vmmc>; + vqmmc-supply = <&sd_vqmmc>; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + status = "okay"; +};