|
@@ -233,3 +233,107 @@ int psc_disable_domain(u32 domain_num)
|
|
|
|
|
|
return psc_wait(domain_num);
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 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;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 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;
|
|
|
+}
|