Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: stm32-lptimer: Add support for stm32mp25

Add support for STM32MP25 SoC.
A new hardware configuration register (HWCFGR2) has been added, to gather
number of capture/compare channels, autonomous mode and input capture
capability. The full feature set is implemented in LPTIM1/2/3/4. LPTIM5
supports a smaller set of features. This can now be read from HWCFGR
registers.

Add new registers to the stm32-lptimer.h: CCMR1, CCR2, HWCFGR1/2 and VERR.
Update the stm32_lptimer data struct so signal the number of
capture/compare channels to the child devices.
Also Remove some unused bit masks (CMPOK_ARROK / CMPOKCF_ARROKCF).

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Link: https://lore.kernel.org/r/20250429125133.1574167-3-fabrice.gasnier@foss.st.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Fabrice Gasnier and committed by
Lee Jones
4f8ceb03 3f9ce9d0

+66 -4
+32 -1
drivers/mfd/stm32-lptimer.c
··· 6 6 * Inspired by Benjamin Gaignard's stm32-timers driver 7 7 */ 8 8 9 + #include <linux/bitfield.h> 9 10 #include <linux/mfd/stm32-lptimer.h> 10 11 #include <linux/module.h> 11 12 #include <linux/of_platform.h> ··· 50 49 return 0; 51 50 } 52 51 52 + static int stm32_lptimer_detect_hwcfgr(struct stm32_lptimer *ddata) 53 + { 54 + u32 val; 55 + int ret; 56 + 57 + ret = regmap_read(ddata->regmap, STM32_LPTIM_VERR, &ddata->version); 58 + if (ret) 59 + return ret; 60 + 61 + /* Try to guess parameters from HWCFGR: e.g. encoder mode (STM32MP15) */ 62 + ret = regmap_read(ddata->regmap, STM32_LPTIM_HWCFGR1, &val); 63 + if (ret) 64 + return ret; 65 + 66 + /* Fallback to legacy init if HWCFGR isn't present */ 67 + if (!val) 68 + return stm32_lptimer_detect_encoder(ddata); 69 + 70 + ddata->has_encoder = FIELD_GET(STM32_LPTIM_HWCFGR1_ENCODER, val); 71 + 72 + ret = regmap_read(ddata->regmap, STM32_LPTIM_HWCFGR2, &val); 73 + if (ret) 74 + return ret; 75 + 76 + /* Number of capture/compare channels */ 77 + ddata->num_cc_chans = FIELD_GET(STM32_LPTIM_HWCFGR2_CHAN_NUM, val); 78 + 79 + return 0; 80 + } 81 + 53 82 static int stm32_lptimer_probe(struct platform_device *pdev) 54 83 { 55 84 struct device *dev = &pdev->dev; ··· 104 73 if (IS_ERR(ddata->clk)) 105 74 return PTR_ERR(ddata->clk); 106 75 107 - ret = stm32_lptimer_detect_encoder(ddata); 76 + ret = stm32_lptimer_detect_hwcfgr(ddata); 108 77 if (ret) 109 78 return ret; 110 79
+34 -3
include/linux/mfd/stm32-lptimer.h
··· 17 17 #define STM32_LPTIM_IER 0x08 /* Interrupt Enable Reg */ 18 18 #define STM32_LPTIM_CFGR 0x0C /* Configuration Reg */ 19 19 #define STM32_LPTIM_CR 0x10 /* Control Reg */ 20 - #define STM32_LPTIM_CMP 0x14 /* Compare Reg */ 20 + #define STM32_LPTIM_CMP 0x14 /* Compare Reg (MP25 CCR1) */ 21 21 #define STM32_LPTIM_ARR 0x18 /* Autoreload Reg */ 22 22 #define STM32_LPTIM_CNT 0x1C /* Counter Reg */ 23 + #define STM32_LPTIM_CCMR1 0x2C /* Capture/Compare Mode MP25 */ 24 + #define STM32_LPTIM_CCR2 0x34 /* Compare Reg2 MP25 */ 25 + 26 + #define STM32_LPTIM_HWCFGR2 0x3EC /* Hardware configuration register 2 - MP25 */ 27 + #define STM32_LPTIM_HWCFGR1 0x3F0 /* Hardware configuration register 1 - MP15 */ 28 + #define STM32_LPTIM_VERR 0x3F4 /* Version identification register - MP15 */ 23 29 24 30 /* STM32_LPTIM_ISR - bit fields */ 31 + #define STM32_LPTIM_DIEROK_ARROK (BIT(24) | BIT(4)) /* MP25 */ 32 + #define STM32_LPTIM_CMP2_ARROK (BIT(19) | BIT(4)) 25 33 #define STM32_LPTIM_CMPOK_ARROK GENMASK(4, 3) 26 34 #define STM32_LPTIM_ARROK BIT(4) 27 35 #define STM32_LPTIM_CMPOK BIT(3) 28 36 29 37 /* STM32_LPTIM_ICR - bit fields */ 30 - #define STM32_LPTIM_ARRMCF BIT(1) 38 + #define STM32_LPTIM_DIEROKCF_ARROKCF (BIT(24) | BIT(4)) /* MP25 */ 39 + #define STM32_LPTIM_CMP2OKCF_ARROKCF (BIT(19) | BIT(4)) 31 40 #define STM32_LPTIM_CMPOKCF_ARROKCF GENMASK(4, 3) 41 + #define STM32_LPTIM_ARRMCF BIT(1) 32 42 33 - /* STM32_LPTIM_IER - bit flieds */ 43 + /* STM32_LPTIM_IER - bit fields */ 34 44 #define STM32_LPTIM_ARRMIE BIT(1) 35 45 36 46 /* STM32_LPTIM_CR - bit fields */ ··· 63 53 /* STM32_LPTIM_ARR */ 64 54 #define STM32_LPTIM_MAX_ARR 0xFFFF 65 55 56 + /* STM32_LPTIM_CCMR1 */ 57 + #define STM32_LPTIM_CC2P GENMASK(19, 18) 58 + #define STM32_LPTIM_CC2E BIT(17) 59 + #define STM32_LPTIM_CC2SEL BIT(16) 60 + #define STM32_LPTIM_CC1P GENMASK(3, 2) 61 + #define STM32_LPTIM_CC1E BIT(1) 62 + #define STM32_LPTIM_CC1SEL BIT(0) 63 + 64 + /* STM32_LPTIM_HWCFGR1 */ 65 + #define STM32_LPTIM_HWCFGR1_ENCODER BIT(16) 66 + 67 + /* STM32_LPTIM_HWCFGR2 */ 68 + #define STM32_LPTIM_HWCFGR2_CHAN_NUM GENMASK(3, 0) 69 + 70 + /* STM32_LPTIM_VERR */ 71 + #define STM32_LPTIM_VERR_23 0x23 /* STM32MP25 */ 72 + 66 73 /** 67 74 * struct stm32_lptimer - STM32 Low-Power Timer data assigned by parent device 68 75 * @clk: clock reference for this instance 69 76 * @regmap: register map reference for this instance 70 77 * @has_encoder: indicates this Low-Power Timer supports encoder mode 78 + * @num_cc_chans: indicates the number of capture/compare channels 79 + * @version: indicates the major and minor revision of the controller 71 80 */ 72 81 struct stm32_lptimer { 73 82 struct clk *clk; 74 83 struct regmap *regmap; 75 84 bool has_encoder; 85 + unsigned int num_cc_chans; 86 + u32 version; 76 87 }; 77 88 78 89 #endif