Re: [PATCH] mfd: axp20x: Change volatile ranges on axp803

From: Ondřej Jirman

Date: Sat Mar 21 2026 - 14:27:02 EST


On Sat, Mar 21, 2026 at 07:25:49AM +0100, Jernej Škrabec wrote:
> Dne nedelja, 15. marec 2026 ob 13:49:31 Srednjeevropski standardni čas je Ondřej Jirman napisal(a):
> > From: Ondrej Jirman <megi@xxxxxx>
> >
> > Regulator control registers can be cached. They don't update by
> > themselves. Enable cache on them, to speed up voltage changes,
> > particularly DCDC2 which needs to be handled quickly due to being used
> > for CPUX cores and is changed very frequently by some cpufreq schedulers.
>
> That's not really the case, DCDC2-DCDC6 registers have DVM finished status
> bit, which is volatile and it is right to have them in volatile range.
> However, it is true that other registers are non-volatile, so that range can
> be considerably shrinked. It seems that AXP288 have same register layout
> but I can't say for sure (I only found datasheet for AXP288C), so it's best
> to leave it alone and apply changes only to AXP803.

While true, it's not used by any kernel drivers, and having the whole register
marked volatile for a single unused bit is contributing 10s of % of permanent
CPU load just from cpufreq DVFS operations alone when using schedutil governor,
which is doing DVFS hundred or more times per second.

If someone will want to use this bit in the regulator driver, they can use eg.
regmap_read_bypassed() to access the bit, while keepig the other parts of
regulator implementation performant.

But I guess it may deserve a comment in the code.

Kind regards,
o.

> Best regards,
> Jernej
>
> >
> > This shrinks register access over RSB bus to one write per voltage
> > change (down from 4 or so).
> >
> > Signed-off-by: Ondrej Jirman <megi@xxxxxx>
> > ---
> > drivers/mfd/axp20x.c | 28 +++++++++++++++++++++++++++-
> > 1 file changed, 27 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> > index 0d0d40972eb8..2ea409029d2f 100644
> > --- a/drivers/mfd/axp20x.c
> > +++ b/drivers/mfd/axp20x.c
> > @@ -172,6 +172,18 @@ static const struct regmap_range axp288_volatile_ranges[] = {
> > regmap_reg_range(AXP20X_FG_RES, AXP288_FG_CC_CAP_REG),
> > };
> >
> > +static const struct regmap_range axp803_volatile_ranges[] = {
> > + regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
> > + regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
> > + regmap_reg_range(AXP288_BC_DET_STAT, AXP20X_VBUS_IPSOUT_MGMT),
> > + regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL),
> > + regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
> > + regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
> > + regmap_reg_range(AXP20X_GPIO1_CTRL, AXP22X_GPIO_STATE),
> > + regmap_reg_range(AXP288_RT_BATT_V_H, AXP288_RT_BATT_V_L),
> > + regmap_reg_range(AXP20X_FG_RES, AXP288_FG_CC_CAP_REG),
> > +};
> > +
> > static const struct regmap_access_table axp288_writeable_table = {
> > .yes_ranges = axp288_writeable_ranges,
> > .n_yes_ranges = ARRAY_SIZE(axp288_writeable_ranges),
> > @@ -182,6 +194,11 @@ static const struct regmap_access_table axp288_volatile_table = {
> > .n_yes_ranges = ARRAY_SIZE(axp288_volatile_ranges),
> > };
> >
> > +static const struct regmap_access_table axp803_volatile_table = {
> > + .yes_ranges = axp803_volatile_ranges,
> > + .n_yes_ranges = ARRAY_SIZE(axp803_volatile_ranges),
> > +};
> > +
> > static const struct regmap_range axp806_writeable_ranges[] = {
> > regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_DATACACHE(3)),
> > regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL),
> > @@ -456,6 +473,15 @@ static const struct regmap_config axp22x_regmap_config = {
> > .cache_type = REGCACHE_MAPLE,
> > };
> >
> > +static const struct regmap_config axp803_regmap_config = {
> > + .reg_bits = 8,
> > + .val_bits = 8,
> > + .wr_table = &axp288_writeable_table,
> > + .volatile_table = &axp803_volatile_table,
> > + .max_register = AXP288_FG_TUNE5,
> > + .cache_type = REGCACHE_MAPLE,
> > +};
> > +
> > static const struct regmap_config axp288_regmap_config = {
> > .reg_bits = 8,
> > .val_bits = 8,
> > @@ -1368,7 +1394,7 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
> > case AXP803_ID:
> > axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
> > axp20x->cells = axp803_cells;
> > - axp20x->regmap_cfg = &axp288_regmap_config;
> > + axp20x->regmap_cfg = &axp803_regmap_config;
> > axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
> > break;
> > case AXP806_ID:
> >
>
>
>
>