Hi all:
We have faced this problem quite a while,when we tested the suspend/wakeup features by pressing the pwr key on our custom board(almost the same as evm-2,difference lies on IO pads,OMAP3515+TPS65930),the BSP is BSP_WINCE_ARM_A8_01_01_00.Sometimes it wakes up immediately,and output the trace wake due to sysintr -1(which is SYSINTR_UNDEFINED).Sometime the system hangs up behind outputting "-OTG SetPowerState".Two cases may happen together,very like the link:http://e2e.ti.com/support/embedded/f/353/t/74839.aspx.we tested without anything connected to OTG and EHCI ports too.
We track the issue,find out the cause:Interrupt controller is Not Working!Exiting from OEMPowerOff(),Wince calls drivers's PowerUp(),then PM calls power manageble driver's IOCtrol to set power state.It happens when PM calls EHCI driver's HcdPdd_IOControl to set D0 state:
DeviceIoControl(pPddObject->hRootBus, IOCTL_BUS_REQUEST_CLOCK, &dwClock, sizeof(dwClock), NULL, 0, NULL, NULL);(1)
SetDevicePowerState(pPddObject->hParentBusHandle, D0, NULL);(2)
DelayMilliSeconds(200, FALSE);(3)
DelayMilliSeconds(200, FALSE) call sleep() to release ownership to wait for 200ms,then can't get back,system loops in OEMIdle(),No timer ticks occur in OEMInterruptHandler().We doubt about the interrupt controller not working,so adds follow code before (1) and bellow (2):
OALMSG(1, (L"MIR1="));
OALMSG(1, (L"%08x %08x %08x\n",INREG32(&s_intr->INTC_MIR0)));
DeviceIoControl(pPddObject->hRootBus, IOCTL_BUS_REQUEST_CLOCK, &dwClock, sizeof(dwClock), NULL, 0, NULL, NULL);(1)
SetDevicePowerState(pPddObject->hParentBusHandle, D0, NULL);(2)
OALMSG(1, (L"MIR2="));
OALMSG(1, (L"%08x %08x %08x\n",INREG32(&s_intr->INTC_MIR0)));
DelayMilliSeconds(200, FALSE);(3)
Normally,accessing INTC_SYSCONFIG reg success,the system works fine.But sometimes can access INTC_SYSCONFIG before (1),can't access INTC_SYSCONFIG behind (2),output:MIR2=,and nothing shows up,the timer ticks also not occur in OEMInterruptHandler(),The system seems locked!!
We continue track deeper,It happens in _PrcmDomainHwUpdate() function in Prcm_domain.c file.When system wakeups,it set wakeup and sleep dependency with MPU,snippet:
static
BOOL
_PrcmDomainHwUpdate(
UINT powerDomain,
UINT ffMask
)
{
BOOL rc = TRUE;
UINT pm_wkdep;
UINT pm_pwstctrl;
UINT cm_sleepdep;
UINT cm_clkstctrl;
UINT32 test = 0;
OMAP_CM_REGS *pCmRegs;
OMAP_PRM_REGS *pPrmRegs;
ClockDomainInfo_t *pClockStates;
PowerDomainState_t *pDomainState;
// update the following hw registers
// PM_WKDEP_xxx
// CM_SLEEPDEP_xxx
// PM_PWSTCTRL_xxx.POWERSTATE
// CM_CLKSTCTRL_xxx
pCmRegs = GetCmRegisterSet(powerDomain);
pPrmRegs = GetPrmRegisterSet(powerDomain);
pClockStates = s_DomainTable[powerDomain].pClockStates;
pDomainState = s_DomainTable[powerDomain].pDomainState;
if (pDomainState != NULL)
{
if (ffMask & DOMAIN_UPDATE_WKUPDEP)
{
if((POWERDOMAIN_USBHOST == powerDomain) && (pDomainState->wakeDependency != 0))
{
OALMSG(1,(L"W1"));
test = INREG32(&g_pIntr->pICLRegs->INTC_SYSCONFIG);
OALMSG(1,(L":"));
OALMSG(1, (L"%08x\n",test));
}
pm_wkdep = INREG32(&pPrmRegs->PM_WKDEP_xxx) & ~WKDEP_MASK;
pm_wkdep |= pDomainState->wakeDependency << WKDEP_SHIFT;
OUTREG32(&pPrmRegs->PM_WKDEP_xxx, pm_wkdep);
if((POWERDOMAIN_USBHOST == powerDomain) && (pDomainState->wakeDependency != 0))
{
OALMSG(1,(L"W2"));
test = INREG32(&g_pIntr->pICLRegs->INTC_SYSCONFIG);
OALMSG(1,(L":"));
OALMSG(1, (L"%08x\n",test));
}
}
if (ffMask & DOMAIN_UPDATE_SLEEPDEP)
{
if((POWERDOMAIN_USBHOST == powerDomain) && (pDomainState->sleepDependency != 0))
{
OALMSG(1,(L"S1"));
test = INREG32(&g_pIntr->pICLRegs->INTC_SYSCONFIG);
OALMSG(1,(L":"));
OALMSG(1, (L"%08x\n",test));
//DumpPrcmRegsSnapshot();
}
cm_sleepdep = INREG32(&pCmRegs->CM_SLEEPDEP_xxx) & ~SLEEPDEP_MASK;
cm_sleepdep |= pDomainState->sleepDependency << SLEEPDEP_SHIFT;
OUTREG32(&pCmRegs->CM_SLEEPDEP_xxx, cm_sleepdep);
if((POWERDOMAIN_USBHOST == powerDomain) && (pDomainState->sleepDependency != 0))
{
OALMSG(1,(L"S2:"));
// PrcmRegsSnapshot();
// DumpPrcmRegsSnapshot();
test = INREG32(&g_pIntr->pICLRegs->INTC_SYSCONFIG);
OALMSG(1,(L":"));
OALMSG(1, (L"%08x\n",test));
}
}
if (ffMask & DOMAIN_UPDATE_POWERSTATE)
{
pm_pwstctrl = INREG32(&pPrmRegs->PM_PWSTCTRL_xxx) & ~(POWERSTATE_MASK | LOGICRETSTATE_MASK);
pm_pwstctrl |= pDomainState->powerState << POWERSTATE_SHIFT;
pm_pwstctrl |= pDomainState->logicState;
OUTREG32(&pPrmRegs->PM_PWSTCTRL_xxx, pm_pwstctrl);
}
}
if (pClockStates != NULL)
{
if (ffMask & DOMAIN_UPDATE_CLOCKSTATE)
{
UINT i;
cm_clkstctrl = INREG32(&pCmRegs->CM_CLKSTCTRL_xxx);
for (i = 0; i < pClockStates->count; ++i)
{
cm_clkstctrl &= ~(CLKSTCTRL_MASK << pClockStates->rgClockDomains[i].clockShift);
cm_clkstctrl |= (pClockStates->rgClockDomains[i].clockState << pClockStates->rgClockDomains[i].clockShift) << CLKSTCTRL_SHIFT;
}
OUTREG32(&pCmRegs->CM_CLKSTCTRL_xxx, cm_clkstctrl);
// save context
if (powerDomain == POWERDOMAIN_MPU)
{
OUTREG32(&g_pPrcmRestore->CM_CLKSTCTRL_MPU, cm_clkstctrl);
}
else if (powerDomain == POWERDOMAIN_CORE)
{
OUTREG32(&g_pPrcmRestore->CM_CLKSTCTRL_CORE, cm_clkstctrl);
}
}
}
return rc;
}
Under normal circumstances,output:
S1:00000000
S2::00000000
W1:00000000
W2:00000000
But sometimes,output:
S1:00000000
S2::00000000
W1:00000000
W2:
then nothing shows up,system seems locked,interrupts not fire(gptimer1,and gpio interrupt).We printed prcm regs before suspend and in _PrcmDomainHwUpdate() using DumpPrcmRegsSnapshot() and PrcmRegsSnapshot();the attachment three cases's outputs,before enter suspend,the prcm regs are exactly the same,but the wakeup prcm regs are different.
We compared the three results,differences[(before suspend) (wakeup in _PrcmDomainHwUpdate) ]:
normal and immediately wakeup:
1、CM_AUTOIDLE_DSS [01 00]==>[01 01] Display Sub-System interface clock is automatically enabled
2、PRM_IRQSTATUS_MPU [11 00]==>[11 10] Software supervised transition completed,event is true (pending)
3、RM_RSTST_USBHOST [04 00]==>[04 04] USB HOST domain has been reset following an USB HOST power domain wake-up.
immediately wakeup and dead locked:
1、PRM_IRQSTATUS_MPU [11 10]==>[11 11] Wake-up event is true (pending)
2、PM_WKST_WKUP [00 00]==>[00 01] GPTIMER 1 wakeup occurred.
Please could anyone shed some light on this?
Best regards