/** * psc_module_release_from_reset() - Release the module from reset * @mod_num: LPSC module number * * This is the follow through for the command 'psc_module_keep_in_reset_enabled' * Allowing the module to be released from reset once all required inits are * complete for the module. Typically, this allows the processor module to start * execution. */ int psc_module_release_from_reset(u32 mod_num) { u32 mdctl, mdstat; int domain_num = psc_get_domain_num(mod_num); int timeout = 100000; /* Wait for any previous transitions to complete */ psc_wait(domain_num); mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); /* Should be set to 1 to de-assert Local reset */ if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0))) { mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1); __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); /* Wait for transition to take place */ psc_wait(domain_num); } mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num)); while (timeout) { mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num)); if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) && PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) && PSC_REG_MDSTAT_GET_LRSTDONE(mdstat)) break; timeout--; } if (!timeout) { printf("%s: Timedout waiting for mdstat(0x%08x) to change\n", __func__, mdstat); return -ETIMEDOUT; } return 0; }
/** * psc_module_keep_in_reset_enabled() - Keep module in enabled,in-reset state * @mod_num: LPSC module number * @gate_clocks: Can the clocks be gated on this module? * * Enable the module, but do not release the module from local reset. This is * necessary for many processor systems on keystone SoCs to allow for system * initialization from a master processor prior to releasing the processor * from reset. */ int psc_module_keep_in_reset_enabled(u32 mod_num, bool gate_clocks) { u32 mdctl, ptcmd, mdstat; u32 next_state; int domain_num = psc_get_domain_num(mod_num); int timeout = 100000; /* Wait for any previous transitions to complete */ psc_wait(domain_num); mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); /* Should be set 0 to assert Local reset */ if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1))) { mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0); __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); /* Wait for transition to take place */ psc_wait(domain_num); } /* Clear Module reset */ mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); next_state = gate_clocks ? PSC_REG_VAL_MDCTL_NEXT_OFF : PSC_REG_VAL_MDCTL_NEXT_ON; mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, next_state); __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); /* Trigger PD transition */ ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD); ptcmd |= (u32)(1 << domain_num); __raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD); psc_wait(domain_num); mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num)); while (timeout) { mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num)); if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) && PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) && PSC_REG_MDSTAT_GET_LRSTDONE(mdstat)) break; timeout--; } if (!timeout) { printf("%s: Timedout waiting for mdstat(0x%08x) to change\n", __func__, mdstat); return -ETIMEDOUT; } return 0; }
/* * FUNCTION PURPOSE: Power down a module * * DESCRIPTION: Powers down the requested module. * * Returns 0 on success, -1 on failure or timeout. */ int psc_disable_module(u32 mod_num) { u32 mdctl; /* Set the bit to apply reset */ mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num)); if ((mdctl & 0x3f) == 0) return 0; mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0); DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl); return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE); }
/** * psc_disable_module() - Power down a module * @mod_num: LPSC module number * * Return: 0 on success, -1 on failure or timeout. */ int psc_disable_module(u32 mod_num) { u32 mdctl; /* Set the bit to apply reset */ mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); if ((mdctl & 0x3f) == 0) return 0; mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0); __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE); }