2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

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>
This commit is contained in:
Fabrice Gasnier 2025-04-29 14:51:28 +02:00 committed by Lee Jones
parent 3f9ce9d076
commit 4f8ceb0302
2 changed files with 66 additions and 4 deletions

View File

@ -6,6 +6,7 @@
* Inspired by Benjamin Gaignard's stm32-timers driver
*/
#include <linux/bitfield.h>
#include <linux/mfd/stm32-lptimer.h>
#include <linux/module.h>
#include <linux/of_platform.h>
@ -49,6 +50,36 @@ static int stm32_lptimer_detect_encoder(struct stm32_lptimer *ddata)
return 0;
}
static int stm32_lptimer_detect_hwcfgr(struct stm32_lptimer *ddata)
{
u32 val;
int ret;
ret = regmap_read(ddata->regmap, STM32_LPTIM_VERR, &ddata->version);
if (ret)
return ret;
/* Try to guess parameters from HWCFGR: e.g. encoder mode (STM32MP15) */
ret = regmap_read(ddata->regmap, STM32_LPTIM_HWCFGR1, &val);
if (ret)
return ret;
/* Fallback to legacy init if HWCFGR isn't present */
if (!val)
return stm32_lptimer_detect_encoder(ddata);
ddata->has_encoder = FIELD_GET(STM32_LPTIM_HWCFGR1_ENCODER, val);
ret = regmap_read(ddata->regmap, STM32_LPTIM_HWCFGR2, &val);
if (ret)
return ret;
/* Number of capture/compare channels */
ddata->num_cc_chans = FIELD_GET(STM32_LPTIM_HWCFGR2_CHAN_NUM, val);
return 0;
}
static int stm32_lptimer_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@ -73,7 +104,7 @@ static int stm32_lptimer_probe(struct platform_device *pdev)
if (IS_ERR(ddata->clk))
return PTR_ERR(ddata->clk);
ret = stm32_lptimer_detect_encoder(ddata);
ret = stm32_lptimer_detect_hwcfgr(ddata);
if (ret)
return ret;

View File

@ -17,20 +17,30 @@
#define STM32_LPTIM_IER 0x08 /* Interrupt Enable Reg */
#define STM32_LPTIM_CFGR 0x0C /* Configuration Reg */
#define STM32_LPTIM_CR 0x10 /* Control Reg */
#define STM32_LPTIM_CMP 0x14 /* Compare Reg */
#define STM32_LPTIM_CMP 0x14 /* Compare Reg (MP25 CCR1) */
#define STM32_LPTIM_ARR 0x18 /* Autoreload Reg */
#define STM32_LPTIM_CNT 0x1C /* Counter Reg */
#define STM32_LPTIM_CCMR1 0x2C /* Capture/Compare Mode MP25 */
#define STM32_LPTIM_CCR2 0x34 /* Compare Reg2 MP25 */
#define STM32_LPTIM_HWCFGR2 0x3EC /* Hardware configuration register 2 - MP25 */
#define STM32_LPTIM_HWCFGR1 0x3F0 /* Hardware configuration register 1 - MP15 */
#define STM32_LPTIM_VERR 0x3F4 /* Version identification register - MP15 */
/* STM32_LPTIM_ISR - bit fields */
#define STM32_LPTIM_DIEROK_ARROK (BIT(24) | BIT(4)) /* MP25 */
#define STM32_LPTIM_CMP2_ARROK (BIT(19) | BIT(4))
#define STM32_LPTIM_CMPOK_ARROK GENMASK(4, 3)
#define STM32_LPTIM_ARROK BIT(4)
#define STM32_LPTIM_CMPOK BIT(3)
/* STM32_LPTIM_ICR - bit fields */
#define STM32_LPTIM_ARRMCF BIT(1)
#define STM32_LPTIM_DIEROKCF_ARROKCF (BIT(24) | BIT(4)) /* MP25 */
#define STM32_LPTIM_CMP2OKCF_ARROKCF (BIT(19) | BIT(4))
#define STM32_LPTIM_CMPOKCF_ARROKCF GENMASK(4, 3)
#define STM32_LPTIM_ARRMCF BIT(1)
/* STM32_LPTIM_IER - bit flieds */
/* STM32_LPTIM_IER - bit fields */
#define STM32_LPTIM_ARRMIE BIT(1)
/* STM32_LPTIM_CR - bit fields */
@ -53,16 +63,37 @@
/* STM32_LPTIM_ARR */
#define STM32_LPTIM_MAX_ARR 0xFFFF
/* STM32_LPTIM_CCMR1 */
#define STM32_LPTIM_CC2P GENMASK(19, 18)
#define STM32_LPTIM_CC2E BIT(17)
#define STM32_LPTIM_CC2SEL BIT(16)
#define STM32_LPTIM_CC1P GENMASK(3, 2)
#define STM32_LPTIM_CC1E BIT(1)
#define STM32_LPTIM_CC1SEL BIT(0)
/* STM32_LPTIM_HWCFGR1 */
#define STM32_LPTIM_HWCFGR1_ENCODER BIT(16)
/* STM32_LPTIM_HWCFGR2 */
#define STM32_LPTIM_HWCFGR2_CHAN_NUM GENMASK(3, 0)
/* STM32_LPTIM_VERR */
#define STM32_LPTIM_VERR_23 0x23 /* STM32MP25 */
/**
* struct stm32_lptimer - STM32 Low-Power Timer data assigned by parent device
* @clk: clock reference for this instance
* @regmap: register map reference for this instance
* @has_encoder: indicates this Low-Power Timer supports encoder mode
* @num_cc_chans: indicates the number of capture/compare channels
* @version: indicates the major and minor revision of the controller
*/
struct stm32_lptimer {
struct clk *clk;
struct regmap *regmap;
bool has_encoder;
unsigned int num_cc_chans;
u32 version;
};
#endif