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

pmdomain: mediatek: Add support for modem power sequences

Add support for the modem power domains by adding its specific
power sequence in functions scpsys_modem_pwrseq_{on,off}() and
call them if the flag MTK_SCPD_MODEM_PWRSEQ is present.

While at it, since some SoC models need to skip setting/clearing
the PWR_RST_B_BIT, also add a MTK_SCPD_SKIP_RESET_B flag for that.

Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20250805074746.29457-8-angelogioacchino.delregno@collabora.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

AngeloGioacchino Del Regno and committed by
Ulf Hansson
16d861d2 0e8e6b5f

+41 -2
+39 -2
drivers/pmdomain/mediatek/mtk-pm-domains.c
··· 279 279 regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); 280 280 } 281 281 282 + static int scpsys_modem_pwrseq_on(struct scpsys_domain *pd) 283 + { 284 + struct scpsys *scpsys = pd->scpsys; 285 + bool tmp; 286 + int ret; 287 + 288 + if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SKIP_RESET_B)) 289 + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); 290 + 291 + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); 292 + 293 + /* wait until PWR_ACK = 1 */ 294 + ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, tmp, MTK_POLL_DELAY_US, 295 + MTK_POLL_TIMEOUT); 296 + if (ret < 0) 297 + return ret; 298 + 299 + return 0; 300 + } 301 + 302 + static void scpsys_modem_pwrseq_off(struct scpsys_domain *pd) 303 + { 304 + struct scpsys *scpsys = pd->scpsys; 305 + 306 + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); 307 + 308 + if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SKIP_RESET_B)) 309 + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); 310 + } 311 + 282 312 static int scpsys_power_on(struct generic_pm_domain *genpd) 283 313 { 284 314 struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd); ··· 327 297 regmap_clear_bits(scpsys->base, pd->data->ext_buck_iso_offs, 328 298 pd->data->ext_buck_iso_mask); 329 299 330 - ret = scpsys_ctl_pwrseq_on(pd); 300 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ)) 301 + ret = scpsys_modem_pwrseq_on(pd); 302 + else 303 + ret = scpsys_ctl_pwrseq_on(pd); 304 + 331 305 if (ret) 332 306 goto err_pwr_ack; 333 307 ··· 400 366 401 367 clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks); 402 368 403 - scpsys_ctl_pwrseq_off(pd); 369 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ)) 370 + scpsys_modem_pwrseq_off(pd); 371 + else 372 + scpsys_ctl_pwrseq_off(pd); 404 373 405 374 /* wait until PWR_ACK = 0 */ 406 375 ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, !tmp, MTK_POLL_DELAY_US,
+2
drivers/pmdomain/mediatek/mtk-pm-domains.h
··· 14 14 #define MTK_SCPD_HAS_INFRA_NAO BIT(7) 15 15 #define MTK_SCPD_STRICT_BUS_PROTECTION BIT(8) 16 16 #define MTK_SCPD_SRAM_PDN_INVERTED BIT(9) 17 + #define MTK_SCPD_MODEM_PWRSEQ BIT(10) 18 + #define MTK_SCPD_SKIP_RESET_B BIT(11) 17 19 #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) 18 20 19 21 #define SPM_VDE_PWR_CON 0x0210