From f97148ab5991baead2bc1459e5004fda01ef991d Mon Sep 17 00:00:00 2001 From: Shengfei Xu Date: Wed, 24 Sep 2025 10:37:00 +0800 Subject: [PATCH] regulator: rk806: Resolving rk806m abnormal power-off during DVS Mode If the RK806M DVS mode does not follow the configured timing sequence, it may cause abnormal power-off. The settings must be configured in the following order: entering voltage adjustment: first configure SLPn_FUN, then configure XXX_SLP_CTR_SEL at addresses 0x64~0x6e. exiting voltage adjustment: first clear XXX_SLP_CTR_SEL at addresses 0x64~0x6e to 0, then modify SLPn_FUN. Change-Id: I265d916b99160fddf467f7c12149490a95f75ca8 Signed-off-by: Shengfei Xu --- drivers/regulator/rk806-regulator.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/regulator/rk806-regulator.c b/drivers/regulator/rk806-regulator.c index 2672bf91dd77..3eba9d6e7957 100644 --- a/drivers/regulator/rk806-regulator.c +++ b/drivers/regulator/rk806-regulator.c @@ -1195,6 +1195,20 @@ static int __maybe_unused rk806_suspend(struct device *dev) for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++) rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_PWRCTRL1); } else { + for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++) { + if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL1) { + chip_ver = rk806_field_read(rk806, CHIP_VER); + if (chip_ver & 0x08) + rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_SLP_FUN); + else + rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_DVS_FUN); + } + if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL2) + rk806_field_write(rk806, PWRCTRL2_FUN, PWRCTRL_DVS_FUN); + if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL3) + rk806_field_write(rk806, PWRCTRL3_FUN, PWRCTRL_DVS_FUN); + } + for (i = 0; i <= RK806_ID_PLDO6 - RK806_ID_PLDO1; i++) { value = rk806_field_read(rk806, PLDO1_ON_VSEL + i); rk806_field_write(rk806, PLDO1_SLP_VSEL + i, value); @@ -1209,18 +1223,6 @@ static int __maybe_unused rk806_suspend(struct device *dev) rk806_field_write(rk806, PLDO4_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO3]); rk806_field_write(rk806, PLDO5_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO4]); rk806_field_write(rk806, PLDO6_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO5]); - - for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++) { - if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL2) - rk806_field_write(rk806, PWRCTRL2_FUN, PWRCTRL_DVS_FUN); - if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL3) - rk806_field_write(rk806, PWRCTRL3_FUN, PWRCTRL_DVS_FUN); - } - chip_ver = rk806_field_read(rk806, CHIP_VER); - if (chip_ver & 0x08) - rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_SLP_FUN); - else - rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_DVS_FUN); } return 0;