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: coarseTrimValue 0x%02x", __func__, coarseTrimValue); - GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM) = coarseTrimValue - 1; + CPRINTS("%s: 0x%02x", __func__, coarseTrimValue); + + if (GREAD_FIELD(XO, CLK_TIMER_CALIB_TRIM_CTRL, MAX_TRIM_SEL)) + max = 0x1f; + else + max = 0xff; + + 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;