Fix for bug 6691452
Hand merge from ics-aah
> Fix for bug 6691452 : DO NOT MERGE
>
> As it so happens, there seem to be panels out there who disapprove of
> sudden changes in their HDMI clock rate. In particular, Sony LCD
> panels made from around 2010-2011 (including the Sony GTV panel) seem
> to dislike this behavior. When exposed to a large jump in the clock
> rate (say from -100pmm to +100ppm in about 30mSec), they seem to
> panic, blank their audio and video, and then resync. The whole
> panic process takes about 2 seconds.
>
> The HDMI spec says that its clock jitter requirements are defined by
> their differential signalling eye diagram requirements relative to an
> "Ideal Recovery Clock" (see section 4.2.3.1 of the HDMI 1.3a spec).
> Basically, if you pass the eye diagram tests, you pass the clock
> jitter requirements. We have determined in lab that even being
> extremely aggressive in our VCXO rate changes does not come even close
> to violating the HDMI eye diagrams. Its just this era of Sony panels
> which seem to be upset by this behavior.
>
> One way or the other, experiments which the GTV devices have seemed to
> indicate that a full range sweep of the VCXO done in 10mSec steps over
> anything faster than 190mSec can cause trouble. Adding a healthy
> degree of margin to this finding, the fix is to limit the rate of VCXO
> control change such that it never goes at a rate faster than
> FullRange/300mSec.
>
> Change flagged as do not merge due to the code structure changes to master.
> This will need to be merged by hand.
>
> Signed-off-by: John Grossman <johngro@google.com>
> Change-Id: Ibfd361fe1cc2cbd4909489e3317fb12e005c6a75
Change-Id: If62f791c826f1145262a6b546b1dc1f9776c37d8
Signed-off-by: John Grossman <johngro@google.com>
diff --git a/services/common_time/common_time_server.cpp b/services/common_time/common_time_server.cpp
index 7a4986b..4e5d16e 100644
--- a/services/common_time/common_time_server.cpp
+++ b/services/common_time/common_time_server.cpp
@@ -202,9 +202,11 @@
// run the state machine
while (!exitPending()) {
struct pollfd pfds[2];
- int rc;
+ int rc, timeout;
int eventCnt = 0;
int64_t wakeupTime;
+ uint32_t t1, t2;
+ bool needHandleTimeout = false;
// We are always interested in our wakeup FD.
pfds[eventCnt].fd = mWakeupThreadFD;
@@ -221,10 +223,14 @@
eventCnt++;
}
+ t1 = static_cast<uint32_t>(mCurTimeout.msecTillTimeout());
+ t2 = static_cast<uint32_t>(mClockRecovery.applyRateLimitedSlew());
+ timeout = static_cast<int>(t1 < t2 ? t1 : t2);
+
// Note, we were holding mLock when this function was called. We
// release it only while we are blocking and hold it at all other times.
mLock.unlock();
- rc = poll(pfds, eventCnt, mCurTimeout.msecTillTimeout());
+ rc = poll(pfds, eventCnt, timeout);
wakeupTime = mLocalClock.getLocalTime();
mLock.lock();
@@ -238,8 +244,11 @@
return false;
}
- if (rc == 0)
- mCurTimeout.setTimeout(kInfiniteTimeout);
+ if (rc == 0) {
+ needHandleTimeout = !mCurTimeout.msecTillTimeout();
+ if (needHandleTimeout)
+ mCurTimeout.setTimeout(kInfiniteTimeout);
+ }
// Were we woken up on purpose? If so, clear the eventfd with a read.
if (pfds[0].revents)
@@ -336,9 +345,8 @@
continue;
}
- // Did we wakeup with no signalled events across all of our FDs? If so,
- // we must have hit our timeout.
- if (rc == 0) {
+ // Time to handle the timeouts?
+ if (needHandleTimeout) {
if (!handleTimeout())
ALOGE("handleTimeout failed");
continue;
@@ -1326,29 +1334,6 @@
}
}
-void CommonTimeServer::TimeoutHelper::setTimeout(int msec) {
- mTimeoutValid = (msec >= 0);
- if (mTimeoutValid)
- mEndTime = systemTime() +
- (static_cast<nsecs_t>(msec) * 1000000);
-}
-
-int CommonTimeServer::TimeoutHelper::msecTillTimeout() {
- if (!mTimeoutValid)
- return kInfiniteTimeout;
-
- nsecs_t now = systemTime();
- if (now >= mEndTime)
- return 0;
-
- uint64_t deltaMsec = (((mEndTime - now) + 999999) / 1000000);
-
- if (deltaMsec > static_cast<uint64_t>(MAX_INT))
- return MAX_INT;
-
- return static_cast<int>(deltaMsec);
-}
-
bool CommonTimeServer::shouldPanicNotGettingGoodData() {
if (mClient_FirstSyncTX) {
int64_t now = mLocalClock.getLocalTime();