From cdc3fbf2cfe5a14c04d3a1454aef98d8be73f201 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Mon, 23 Jan 2012 14:53:20 -0800 Subject: [PATCH] Calibrate internal oscillator using hibernate clock This works around a chip errata where the internal oscillator on early EC parts (as used on proto0) is untrimmed. Signed-off-by: Randall Spangler BUG=chrome-os-partner:7693 TEST=if it runs, it works Change-Id: Ie82a524543f4cf25efd0de7998dbdae103bd126b --- chip/lm4/clock.c | 8 ++++++++ chip/lm4/registers.h | 4 +++- common/main.c | 15 ++++++++------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/chip/lm4/clock.c b/chip/lm4/clock.c index c9afa57760..fcf0da99e1 100644 --- a/chip/lm4/clock.c +++ b/chip/lm4/clock.c @@ -169,6 +169,14 @@ static void clock_init_pll(uint32_t value) /* Enable main and precision internal oscillators */ LM4_SYSTEM_RCC &= ~0x3; + + /* Perform an auto calibration of the internal oscillator, using the + * 32.768KHz hibernate clock. */ + /* TODO: (crosbug.com/p/7693) This is only needed on early chips which + * aren't factory trimmed. */ + LM4_SYSTEM_PIOSCCAL = 0x80000000; + LM4_SYSTEM_PIOSCCAL = 0x80000200; + /* wait 1 million CPU cycles */ wait_cycles(512 * 1024); diff --git a/chip/lm4/registers.h b/chip/lm4/registers.h index ac7f21bd95..0e8b341a36 100644 --- a/chip/lm4/registers.h +++ b/chip/lm4/registers.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -160,6 +160,8 @@ static inline int lm4_fan_addr(int ch, int offset) #define LM4_SYSTEM_RESC LM4REG(0x400fe05c) #define LM4_SYSTEM_RCC LM4REG(0x400fe060) #define LM4_SYSTEM_RCC2 LM4REG(0x400fe070) +#define LM4_SYSTEM_PIOSCCAL LM4REG(0x400fe150) +#define LM4_SYSTEM_PIOSCSTAT LM4REG(0x400fe154) #define LM4_SYSTEM_PLLSTAT LM4REG(0x400fe168) #define LM4_SYSTEM_RCGCWD LM4REG(0x400fe600) #define LM4_SYSTEM_RCGCTIMER LM4REG(0x400fe604) diff --git a/common/main.c b/common/main.c index e400dfde7d..30faa87066 100644 --- a/common/main.c +++ b/common/main.c @@ -1,9 +1,8 @@ -/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. - * Copyright 2011 Google Inc. * - * Example of EC main loop + * Main routine for Chrome EC */ #include "registers.h" @@ -36,6 +35,7 @@ #include "usb_charge.h" /* example task blinking the user LED */ +/* TODO: This also kicks the watchdog, so MUST be present! */ void UserLedBlink(void) { while (1) { @@ -58,6 +58,11 @@ int main(void) /* Configure the pin multiplexers */ configure_board(); jtag_pre_init(); + + /* Initialize the system module. This enables the hibernate clock + * source we need to calibrate the internal oscillator. */ + system_pre_init(); + /* Set the CPU clocks / PLLs */ clock_init(); @@ -65,13 +70,9 @@ int main(void) * another image if necessary. This must be done as early as * possible, so that the minimum number of components get * re-initialized if we jump to another image. */ - system_pre_init(); gpio_pre_init(); vboot_pre_init(); - /* TODO (crosbug.com/p/7456)- race condition on enabling - * interrupts. Module inits should call task_IntEnable(int) - * when they're ready... */ task_init(); watchdog_init(1100);