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/clock_recovery.h b/services/common_time/clock_recovery.h
index b7362be..20fbf96 100644
--- a/services/common_time/clock_recovery.h
+++ b/services/common_time/clock_recovery.h
@@ -26,6 +26,8 @@
 #include "diag_thread.h"
 #endif
 
+#include "utils.h"
+
 namespace android {
 
 class CommonClock;
@@ -42,6 +44,11 @@
                              int64_t data_point_rtt);
     int32_t getLastErrorEstimate();
 
+    // Applies the next step in any ongoing slew change operation.  Returns a
+    // timeout suitable for use with poll/select indicating the number of mSec
+    // until the next change should be applied.
+    int applyRateLimitedSlew();
+
   private:
 
     // Tuned using the "Good Gain" method.
@@ -87,7 +94,8 @@
     static uint32_t findMinRTTNdx(DisciplineDataPoint* data, uint32_t count);
 
     void reset_l(bool position, bool frequency);
-    void applySlew();
+    void setTargetCorrection_l(int32_t tgt);
+    bool applySlew_l();
 
     // The local clock HW abstraction we use as the basis for common time.
     LocalClock* local_clock_;
@@ -104,7 +112,11 @@
     int32_t last_delta_;
     float last_delta_f_;
     int32_t integrated_error_;
-    int32_t correction_cur_;
+    int32_t tgt_correction_;
+    int32_t cur_correction_;
+    LinearTransform time_to_cur_slew_;
+    int64_t slew_change_end_time_;
+    Timeout next_slew_change_timeout_;
 
     // Contoller Output.
     float CO;
@@ -128,6 +140,15 @@
     DisciplineDataPoint startup_filter_data_[kStartupFilterSize];
     uint32_t startup_filter_wr_;
 
+    // Minimum number of milliseconds over which we allow a full range change
+    // (from rail to rail) of the VCXO control signal.  This is the rate
+    // limiting factor which keeps us from changing the clock rate so fast that
+    // we get in trouble with certain HDMI sinks.
+    static const uint32_t kMinFullRangeSlewChange_mSec;
+
+    // How much time (in msec) to wait 
+    static const int kSlewChangeStepPeriod_mSec;
+
 #ifdef TIME_SERVICE_DEBUG
     sp<DiagThread> diag_thread_;
 #endif