Hi all,
Just updated to version 6.14.01 of the CE BSP, and am seeing an issue with suspend/resume in EHCIPDD.
Symptom is that resume from suspend does not work reliably.
Resume from suspend either
- just works, which is of course good, or
- seems to work, but EVM wakes up with backlight dimmed, or
- does not work at all, board drawing more current after resume, but display and other devices are not switched back on
I have implemented a workaround (see below), but would appreciate if someone with a better understanding of the code could comment on my observations and perhaps work out a real fix.
We are using EVM2 rev G boards with CPU board rev C and Power Module rev D.
No expansion boards connected.
Software is a modified version of the Texas BSP, CE6R3 and all updates up until and including March 2010.
This problem was not seen with BSP version 6.14.00.
EHCIPDD
The problem area seems to be in the handling of IOCTL_POWER_SET in HcdPdd_IOControl() in the file
C:\WINCE600\PLATFORM\COMMON\SRC\SOC\OMAP35XX_TPS659XX_TI_V1\omap35xx\USB\EHCIPDD\system.c
1) The Sleep(200) call in line 1068 sometimes causes the system to hang when resuming.
I am wondering if HcdPdd_IOControl is called in a power handler context where blocking calls such as Sleep are not allowed.
Replacing the Sleep call with DelayMilliSeconds(200, g_fOmapEhciSuspended) seems to fix this.
2) Data Abort when reading pUHHRegs->SYSCONFIG during IOCTL_POWER_SET (D0) handling immediately after resume.
Exception 'Data Abort' (4): Thread-Id=027f0002(pth=8ad1c468), Proc-Id=00400002(pprc=8c011448) 'NK.EXE',
VM-active=06a50002(pprc=88fd0900) 'servicesd.exe' PC=d6322e2c(ehcihcd.dll+0x00002e2c)
RA=d6322e2c(ehcihcd.dll+0x00002e2c) SP=d5ddf000, BVA=00000000
EHCI: Exception in IOCTL_POWER_SET
Interestingly, the Data Abort only occurs if SetDevicePowerState is called before the pUHHRegs access.
The pUHHRegs pointer looks valid, it has the value 0xd0544000.
IOCTL_POWER_SET (D0) is called twice during suspend resume (why?).
The second time around the pUHHRegs pointer gets mapped to the same address (0xd0544000), but this time the access succeeds, no Data Abort.
Workaround
This workaround makes suspend/resume work reliably again, but probably also negates some of the power management improvements that 6.14.01 was supposed to bring.
1) The SetDevicePowerState and Sleep calls are only executed depending on the BusSuspendResume parameter in registry, which is set to FALSE by default.
2) Moved SetDevicePowerState and DeviceIoControl calls from HcdPdd_PowerDown to HcdPdd_IOControl to avoid system calls in the power handler.
This is the modified part of HcdPdd_IOControl:
switch (ReqDx)
{
case D0:
DeviceIoControl(pPddObject->hRootBus, IOCTL_BUS_REQUEST_CLOCK, &dwClock, sizeof(dwClock), NULL, 0, NULL, NULL);
if (pPddObject->BusSuspendResume)
{
SetDevicePowerState(pPddObject->hParentBusHandle, D0, NULL);
Sleep(200);
}
RegVal = pUHHRegs->SYSCONFIG & ~(UHH_SYSCONFIG_MIDLEMODE(0x03) | UHH_SYSCONFIG_SIDLEMODE(0x03));
pUHHRegs->SYSCONFIG = RegVal | UHH_SYSCONFIG_MIDLEMODE(MIDLE_SMART) | UHH_SYSCONFIG_SIDLEMODE(SIDLE_SMART);
HcdMdd_PowerUp(pPddObject->lpvEHCDMddObject);
g_fOmapEhciSuspended = FALSE;
pPddObject->dwActualPowerState = ReqDx;
#if DUMP_REGS
dumpRegs();
#endif
break;
case D4:
HcdMdd_PowerDown(pPddObject->lpvEHCDMddObject);
g_fOmapEhciSuspended = TRUE;
pUHHRegs->SYSCONFIG &= ~(UHH_SYSCONFIG_MIDLEMODE(0x03) | UHH_SYSCONFIG_SIDLEMODE(0x03));
pUHHRegs->SYSCONFIG |= (UHH_SYSCONFIG_MIDLEMODE(MIDLE_FORCE) | UHH_SYSCONFIG_SIDLEMODE(SIDLE_FORCE));
if (pPddObject->BusSuspendResume)
{
SetDevicePowerState(pPddObject->hParentBusHandle, D4, NULL);
}
DeviceIoControl(pPddObject->hRootBus, IOCTL_BUS_RELEASE_CLOCK, &dwClock, sizeof(dwClock), NULL, 0, NULL, NULL);
pPddObject->dwActualPowerState = ReqDx;
break;
}
Incompatible transceiver
There is a comment in platform.reg to the effect that the USB transceiver used on the EVM is incompatible with the OMAP.
; The EVM2 ECHI port uses a transceiver that has problems with the EHCI
; controller PHY interface, it will fail after USB bus suspend/resume.
Please could anyone shed some light on this?
Does that mean that suspend/resume cannot be implemented on a design that uses this transceiver?
Best regards,
Carsten