From 02d7aa88214e73aef81474f8b7d85272d94239a0 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:54:06 +0530 Subject: mmc: dw_mmc: export dwmci_send_cmd() and dwmci_set_ios() These commands are required by struct dm_mmc_ops. Any platform specific driver may use some or all of the functions in their own ops. Make them accessible by moving the prototype to the dwmmc.h header. Signed-off-by: Kaustabh Chakraborty Reviewed-by: Peng Fan Signed-off-by: Peng Fan --- include/dwmmc.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/dwmmc.h b/include/dwmmc.h index 87ca127cd6c..639a2d28e78 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -334,6 +334,9 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk); #ifdef CONFIG_DM_MMC /* Export the operations to drivers */ int dwmci_probe(struct udevice *dev); +int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data); +int dwmci_set_ios(struct udevice *dev); extern const struct dm_mmc_ops dm_dwmci_ops; #endif -- cgit v1.2.3 From e6b66e9f338fe9c8a6bc498399e736f7ec9deb10 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:54:09 +0530 Subject: mmc: dw_mmc: add voltage switch command flag During a voltage switch command (CMD11, opcode: SD_CMD_SWITCH_UHS18V), certain hosts tend to stop responding to subsequent commands. This is addressed by introducing an additional command flag, DWMCI_CMD_VOLT_SWITCH. The associated interrupt bit is defined as DWMCI_INTMSK_VOLTSW. This is set high when a voltage switch is issued, this needs to be waited for and set to low. Implement the same in the timeout loop. Do note that since DWMCI_INTMSK_VOLTSW shares the same bit as DWMCI_INTMSK_HTO (bit 10), the interrupt bit needs to be polled for only if the volt switch command is issued. DWMCI_CMD_VOLT_SWITCH also needs to be set for subsequent clken commands after the volt switch. To ensure this, add a boolean member in the host private struct (herein named volt_switching), which informs if the last command issued was for volt switching or not. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Peng Fan --- include/dwmmc.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/dwmmc.h b/include/dwmmc.h index 639a2d28e78..47e3220985e 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -72,6 +72,7 @@ #define DWMCI_INTMSK_RTO BIT(8) #define DWMCI_INTMSK_DRTO BIT(9) #define DWMCI_INTMSK_HTO BIT(10) +#define DWMCI_INTMSK_VOLTSW BIT(10) /* overlap! */ #define DWMCI_INTMSK_FRUN BIT(11) #define DWMCI_INTMSK_HLE BIT(12) #define DWMCI_INTMSK_SBE BIT(13) @@ -104,6 +105,7 @@ #define DWMCI_CMD_ABORT_STOP BIT(14) #define DWMCI_CMD_PRV_DAT_WAIT BIT(13) #define DWMCI_CMD_UPD_CLK BIT(21) +#define DWMCI_CMD_VOLT_SWITCH BIT(28) #define DWMCI_CMD_USE_HOLD_REG BIT(29) #define DWMCI_CMD_START BIT(31) @@ -190,6 +192,7 @@ struct dwmci_idmac_regs { * @cfg: Internal MMC configuration, for !CONFIG_BLK cases * @fifo_mode: Use FIFO mode (not DMA) to read and write data * @dma_64bit_address: Whether DMA supports 64-bit address mode or not + * @volt_switching: Whether SD voltage switching is in process or not * @regs: Registers that can vary for different DW MMC block versions */ struct dwmci_host { @@ -229,6 +232,7 @@ struct dwmci_host { bool fifo_mode; bool dma_64bit_address; + bool volt_switching; const struct dwmci_idmac_regs *regs; }; -- cgit v1.2.3 From 73a85502bd2a4373d82f638b1b4c3e1f79e394e3 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:58:17 +0530 Subject: power: pmic: s2mps11: add support for allowing multiple device variants There are multiple PMICs by Samsung which are similar in architecture (register layout, interface, etc.) and is possible to be driven by a single driver. Variant specific code and data should be managed properly in the driver. And an enum which describes all supported variants. Pass the enum as the device driver data. Introduce a switch-case block on the enum for any variant specific code. Signed-off-by: Kaustabh Chakraborty Reviewed-by: Peng Fan Signed-off-by: Peng Fan --- include/power/s2mps11.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/power/s2mps11.h b/include/power/s2mps11.h index 22b38fff703..c08bea5a516 100644 --- a/include/power/s2mps11.h +++ b/include/power/s2mps11.h @@ -161,4 +161,9 @@ enum { OP_ON, }; +enum { + VARIANT_NONE, + VARIANT_S2MPS11, +}; + #endif -- cgit v1.2.3 From 2d49a7e75ce176b07288397742fb9a72d6caf134 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:58:18 +0530 Subject: power: regulator: s2mps11: declaratively define LDOs and BUCKs In the Linux kernel driver, all information related to LDO and BUCK regulators are stored in descriptive arrays. This also allows multiple variants to be supported by the same driver. Define a struct sec_regulator_desc which holds all values required by a regulator. Create an array of said struct containing all regulators. The descriptors are designed to follow a style similar to what's seen in the Linux driver, so comparing one with the other is simple. In functions such as s2mps11_{buck,ldo}_{val,mode} these values are to be used, make necessary modifications to pull them from the descriptors. Since multiple variants have varying descriptors, select them from within a switch-case block. Functions s2mps11_{buck,ldo}_{volt2hex,hex2volt} and arrays s2mps11_buck_{ctrl,out} are phased out as the calculations are now hardcoded in descriptors, thusly, it reduces clutter and enhances readability. Two macros in s2mps11.h, S2MPS11_LDO_NUM and S2MPS11_BUCK_NUM are removed as they are no longer being used. Signed-off-by: Kaustabh Chakraborty Reviewed-by: Peng Fan Signed-off-by: Peng Fan --- include/power/s2mps11.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/power/s2mps11.h b/include/power/s2mps11.h index c08bea5a516..dfbb5f1c165 100644 --- a/include/power/s2mps11.h +++ b/include/power/s2mps11.h @@ -106,9 +106,6 @@ enum s2mps11_reg { #define S2MPS11_LDO26_ENABLE 0xec -#define S2MPS11_LDO_NUM 26 -#define S2MPS11_BUCK_NUM 10 - /* Driver name */ #define S2MPS11_BUCK_DRIVER "s2mps11_buck" #define S2MPS11_OF_BUCK_PREFIX "BUCK" @@ -153,6 +150,20 @@ enum s2mps11_reg { #define S2MPS11_LDO_MODE_STANDBY_LPM (0x2 << 6) #define S2MPS11_LDO_MODE_ON (0x3 << 6) +struct sec_regulator_desc { + /* regulator mode control */ + unsigned int mode_reg; + unsigned int mode_mask; + + /* regulator voltage control */ + unsigned int volt_reg; + unsigned int volt_mask; + + unsigned int volt_min; + unsigned int volt_step; + unsigned int volt_max_hex; +}; + enum { OP_OFF = 0, OP_LPM, -- cgit v1.2.3 From defe12f306e5ca80d06a92796564f1fbef906181 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:58:20 +0530 Subject: power: regulator: s2mps11: add support for S2MPU05 PMIC Samsung's S2MPU05 PMIC is used by Exynos7870 SoC. It has 5 buck and 38 LDO regulators. Add support for this device variant in the driver. Signed-off-by: Kaustabh Chakraborty Reviewed-by: Peng Fan Signed-off-by: Peng Fan --- include/power/s2mps11.h | 112 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) (limited to 'include') diff --git a/include/power/s2mps11.h b/include/power/s2mps11.h index dfbb5f1c165..51eb79bdde1 100644 --- a/include/power/s2mps11.h +++ b/include/power/s2mps11.h @@ -150,6 +150,117 @@ enum s2mps11_reg { #define S2MPS11_LDO_MODE_STANDBY_LPM (0x2 << 6) #define S2MPS11_LDO_MODE_ON (0x3 << 6) +enum s2mpu05_reg { + S2MPU05_REG_ID, + S2MPU05_REG_INT1, + S2MPU05_REG_INT2, + S2MPU05_REG_INT3, + S2MPU05_REG_INT1M, + S2MPU05_REG_INT2M, + S2MPU05_REG_INT3M, + S2MPU05_REG_ST1, + S2MPU05_REG_ST2, + S2MPU05_REG_PWRONSRC, + S2MPU05_REG_OFFSRC, + S2MPU05_REG_BU_CHG, + S2MPU05_REG_RTC_BUF, + S2MPU05_REG_CTRL1, + S2MPU05_REG_CTRL2, + S2MPU05_REG_ETC_TEST, + S2MPU05_REG_OTP_ADRL, + S2MPU05_REG_OTP_ADRH, + S2MPU05_REG_OTP_DATA, + S2MPU05_REG_MON1SEL, + S2MPU05_REG_MON2SEL, + S2MPU05_REG_CTRL3, + S2MPU05_REG_ETC_OTP, + S2MPU05_REG_UVLO, + S2MPU05_REG_TIME_CTRL1, + S2MPU05_REG_TIME_CTRL2, + S2MPU05_REG_B1CTRL1, + S2MPU05_REG_B1CTRL2, + S2MPU05_REG_B2CTRL1, + S2MPU05_REG_B2CTRL2, + S2MPU05_REG_B2CTRL3, + S2MPU05_REG_B2CTRL4, + S2MPU05_REG_B3CTRL1, + S2MPU05_REG_B3CTRL2, + S2MPU05_REG_B3CTRL3, + S2MPU05_REG_B4CTRL1, + S2MPU05_REG_B4CTRL2, + S2MPU05_REG_B5CTRL1, + S2MPU05_REG_B5CTRL2, + S2MPU05_REG_BUCK_RAMP, + S2MPU05_REG_LDO_DVS1, + S2MPU05_REG_LDO_DVS9, + S2MPU05_REG_LDO_DVS10, + S2MPU05_REG_L1CTRL, + S2MPU05_REG_L2CTRL, + S2MPU05_REG_L3CTRL, + S2MPU05_REG_L4CTRL, + S2MPU05_REG_L5CTRL, + S2MPU05_REG_L6CTRL, + S2MPU05_REG_L7CTRL, + S2MPU05_REG_L8CTRL, + S2MPU05_REG_L9CTRL1, + S2MPU05_REG_L9CTRL2, + S2MPU05_REG_L10CTRL, + S2MPU05_REG_L11CTRL1, + S2MPU05_REG_L11CTRL2, + S2MPU05_REG_L12CTRL, + S2MPU05_REG_L13CTRL, + S2MPU05_REG_L14CTRL, + S2MPU05_REG_L15CTRL, + S2MPU05_REG_L16CTRL, + S2MPU05_REG_L17CTRL1, + S2MPU05_REG_L17CTRL2, + S2MPU05_REG_L18CTRL1, + S2MPU05_REG_L18CTRL2, + S2MPU05_REG_L19CTRL, + S2MPU05_REG_L20CTRL, + S2MPU05_REG_L21CTRL, + S2MPU05_REG_L22CTRL, + S2MPU05_REG_L23CTRL, + S2MPU05_REG_L24CTRL, + S2MPU05_REG_L25CTRL, + S2MPU05_REG_L26CTRL, + S2MPU05_REG_L27CTRL, + S2MPU05_REG_L28CTRL, + S2MPU05_REG_L29CTRL, + S2MPU05_REG_L30CTRL, + S2MPU05_REG_L31CTRL, + S2MPU05_REG_L32CTRL, + S2MPU05_REG_L33CTRL, + S2MPU05_REG_L34CTRL, + S2MPU05_REG_L35CTRL, + S2MPU05_REG_LDO_DSCH1, + S2MPU05_REG_LDO_DSCH2, + S2MPU05_REG_LDO_DSCH3, + S2MPU05_REG_LDO_DSCH4, + S2MPU05_REG_LDO_DSCH5, + S2MPU05_REG_LDO_CTRL1, + S2MPU05_REG_LDO_CTRL2, + S2MPU05_REG_TCXO_CTRL, + S2MPU05_REG_SELMIF, + S2MPU05_REG_COUNT, +}; + +#define S2MPU05_OF_BUCK_PREFIX "buck" +#define S2MPU05_OF_LDO_PREFIX "ldo" + +/* BUCK */ +#define S2MPU05_BUCK_MIN1 400000 +#define S2MPU05_BUCK_MIN2 600000 +#define S2MPU05_BUCK_STEP1 6250 +#define S2MPU05_BUCK_STEP2 12500 + +/* LDO */ +#define S2MPU05_LDO_MIN1 800000 +#define S2MPU05_LDO_MIN2 1800000 +#define S2MPU05_LDO_MIN3 400000 +#define S2MPU05_LDO_STEP1 12500 +#define S2MPU05_LDO_STEP2 25000 + struct sec_regulator_desc { /* regulator mode control */ unsigned int mode_reg; @@ -175,6 +286,7 @@ enum { enum { VARIANT_NONE, VARIANT_S2MPS11, + VARIANT_S2MPU05, }; #endif -- cgit v1.2.3 From 906ee6785b1cb5a51375b5a613a7cc56acced8c8 Mon Sep 17 00:00:00 2001 From: Tanmay Kathpalia Date: Tue, 21 Oct 2025 13:45:26 -0700 Subject: mmc: sd: Handle UHS-I voltage signaling without power cycle Some boards have SD card connectors where the power rail cannot be switched off by the driver. However there are various circumstances when a card might be re-initialized, such as after system resume, warm re-boot, or error handling. However, a UHS card will continue to use 1.8V signaling unless it is power cycled. If the card has not been power cycled, it may still be using 1.8V signaling. According to the SD spec., the Bus Speed Mode (function group 1) bits 2 to 4 are zero if the card is initialized at 3.3V signal level. Thus they can be used to determine if the card has already switched to 1.8V signaling. Detect that situation and try to initialize a UHS-I (1.8V) transfer mode. Signed-off-by: Tanmay Kathpalia Signed-off-by: Peng Fan --- include/mmc.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/mmc.h b/include/mmc.h index c6b2ab4a29f..51d3f2f8dd5 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -759,6 +759,9 @@ struct mmc { #endif u8 *ext_csd; u32 cardtype; /* cardtype read from the MMC */ +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) + u32 sd3_bus_mode; /* Supported UHS-I bus speed modes */ +#endif enum mmc_voltage current_voltage; enum bus_mode selected_mode; /* mode currently used */ enum bus_mode best_mode; /* best mode is the supported mode with the -- cgit v1.2.3 From f896f5c2523fd1dfabad3441518ced34fc4d816d Mon Sep 17 00:00:00 2001 From: Tanmay Kathpalia Date: Tue, 21 Oct 2025 13:54:10 -0700 Subject: sdhci: Reorder interrupt flags in SDHCI_INT_DATA_MASK definition Reorder the SDHCI_INT_SPACE_AVAIL and SDHCI_INT_DATA_AVAIL flags in the SDHCI_INT_DATA_MASK definition to match the bit order as defined in the SDHCI specification and maintain consistency with the register layout. The functional behavior remains unchanged as this only affects the order of OR operations in the mask definition. Signed-off-by: Tanmay Kathpalia Reviewed-by: Peng Fan Signed-off-by: Peng Fan --- include/sdhci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/sdhci.h b/include/sdhci.h index 2372697b743..d9c0597a0c1 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -143,7 +143,7 @@ #define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \ SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX) #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ - SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ + SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_AVAIL | \ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR) #define SDHCI_INT_ALL_MASK ((unsigned int)-1) -- cgit v1.2.3