It is possible for power domain IDs to be great than 31. If this happens, the PTCMD and PTSTAT registers must overflow into adjacent corresponding PTCMD_H and PTSTAT_H registers for each. Update the driver to account for this.
Signed-off-by: Dave Gerlach <d-gerl...@ti.com> --- drivers/power/domain/ti-power-domain.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/power/domain/ti-power-domain.c b/drivers/power/domain/ti-power-domain.c index b45e9b824539..cf20acd1a322 100644 --- a/drivers/power/domain/ti-power-domain.c +++ b/drivers/power/domain/ti-power-domain.c @@ -16,7 +16,9 @@ #include <linux/iopoll.h> #define PSC_PTCMD 0x120 +#define PSC_PTCMD_H 0x124 #define PSC_PTSTAT 0x128 +#define PSC_PTSTAT_H 0x12C #define PSC_PDSTAT 0x200 #define PSC_PDCTL 0x300 #define PSC_MDSTAT 0x800 @@ -115,10 +117,17 @@ static int ti_power_domain_probe(struct udevice *dev) static int ti_pd_wait(struct ti_pd *pd) { u32 ptstat; + u32 pdoffset = 0; + u32 ptstatreg = PSC_PTSTAT; int ret; - ret = readl_poll_timeout(pd->psc->base + PSC_PTSTAT, ptstat, - !(ptstat & BIT(pd->id)), PD_TIMEOUT); + if (pd->id > 31) { + pdoffset = 32; + ptstatreg = PSC_PTSTAT_H; + } + + ret = readl_poll_timeout(pd->psc->base + ptstatreg, ptstat, + !(ptstat & BIT(pd->id - pdoffset)), PD_TIMEOUT); if (ret) printf("%s: psc%d, pd%d failed to transition.\n", __func__, @@ -129,7 +138,15 @@ static int ti_pd_wait(struct ti_pd *pd) static void ti_pd_transition(struct ti_pd *pd) { - psc_write(BIT(pd->id), pd->psc, PSC_PTCMD); + u32 pdoffset = 0; + u32 ptcmdreg = PSC_PTCMD; + + if (pd->id > 31) { + pdoffset = 32; + ptcmdreg = PSC_PTCMD_H; + } + + psc_write(BIT(pd->id - pdoffset), pd->psc, ptcmdreg); } u8 ti_pd_state(struct ti_pd *pd) -- 2.35.0