summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2016-06-03 16:36:07 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-06-08 14:02:22 -0700
commitbb6918cbdfd521dc30316deaa03788db569fadc5 (patch)
tree87b1bac41177735d0dc1f359f93ff0e133f81042
parent8b961f9c75549cf7f4178e849cee681ffbab8dbf (diff)
downloadchrome-ec-bb6918cbdfd521dc30316deaa03788db569fadc5.tar.gz
g: Enable SOF calibration after first SOF token
Instead of enabling the SOF calibration at usb_init(), enable it only when the first SOF packet is seen following the usb_init(), as suggested in the recommendations document linked from the bug report. Also fix the code to do the right thing. The original reference code had errors. BUG=chrome-os-partner:50800 BRANCH=none TEST=make buildall; test on Cr50 After adding some instrumentation code, I see the SOF being detected and the calibration started. It only happens once after each usb_init() and only when the USB traffic begins. Change-Id: Id2b9a41d90ce9cc9e467fb759463d69a57bb5540 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/350371 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r--chip/g/jitter.c18
-rw-r--r--chip/g/usb.c13
2 files changed, 23 insertions, 8 deletions
diff --git a/chip/g/jitter.c b/chip/g/jitter.c
index b864bf6db9..35bf8142c3 100644
--- a/chip/g/jitter.c
+++ b/chip/g/jitter.c
@@ -134,8 +134,10 @@ static void timer_sof_calibration_underrun_int(void)
{
unsigned coarseTrimValue = GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM);
- CPRINTS("%s: coarseTrimValue 0x%02x", __func__, coarseTrimValue);
- GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM) = coarseTrimValue + 1;
+ CPRINTS("%s: 0x%02x", __func__, coarseTrimValue);
+
+ if (coarseTrimValue > 0x00)
+ GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM) = coarseTrimValue - 1;
GREG32(XO, DXO_INT_STATE) =
GC_XO_DXO_INT_STATE_SLOW_CALIB_UNDERRUN_MASK;
@@ -149,9 +151,17 @@ DECLARE_IRQ(GC_IRQNUM_XO0_SLOW_CALIB_UNDERRUN_INT,
static void timer_sof_calibration_overflow_int(void)
{
unsigned coarseTrimValue = GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM);
+ unsigned max;
+
+ CPRINTS("%s: 0x%02x", __func__, coarseTrimValue);
+
+ if (GREAD_FIELD(XO, CLK_TIMER_CALIB_TRIM_CTRL, MAX_TRIM_SEL))
+ max = 0x1f;
+ else
+ max = 0xff;
- CPRINTS("%s: coarseTrimValue 0x%02x", __func__, coarseTrimValue);
- GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM) = coarseTrimValue - 1;
+ if (coarseTrimValue < max)
+ GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM) = coarseTrimValue + 1;
GREG32(XO, DXO_INT_STATE) =
GC_XO_DXO_INT_STATE_SLOW_CALIB_OVERFLOW_MASK;
diff --git a/chip/g/usb.c b/chip/g/usb.c
index d47912dd02..0acacb8fa2 100644
--- a/chip/g/usb.c
+++ b/chip/g/usb.c
@@ -1074,9 +1074,6 @@ static void usb_reset(void)
/* Reinitialize all the endpoints */
usb_init_endpoints();
-
- /* Init the clock calibrator */
- init_sof_clock();
}
static void usb_resetdet(void)
@@ -1123,6 +1120,12 @@ void usb_interrupt(void)
if (status & GINTSTS(USBRST))
usb_reset();
+ /* Initialize the SOF clock calibrator only on the first SOF */
+ if (GR_USB_GINTMSK & GINTMSK(SOF) && status & GINTSTS(SOF)) {
+ init_sof_clock();
+ GR_USB_GINTMSK &= ~GINTMSK(SOF);
+ }
+
/* Endpoint interrupts */
if (oepint || iepint) {
/* Note: It seems that the DAINT bits are only trustworthy for
@@ -1327,7 +1330,9 @@ void usb_init(void)
/* Reset detected while suspended. Need to wake up. */
GINTMSK(RESETDET) | /* TODO: Do we need this? */
/* Idle, Suspend detected. Should go to sleep. */
- GINTMSK(ERLYSUSP) | GINTMSK(USBSUSP);
+ GINTMSK(ERLYSUSP) | GINTMSK(USBSUSP) |
+ /* Watch for first SOF */
+ GINTMSK(SOF);
/* Device registers have been setup */
GR_USB_DCTL |= DCTL_PWRONPRGDONE;