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 <rspangler@chromium.org>

BUG=chrome-os-partner:7693
TEST=if it runs, it works

Change-Id: Ie82a524543f4cf25efd0de7998dbdae103bd126b
This commit is contained in:
Randall Spangler
2012-01-23 14:53:20 -08:00
parent 51df9457f4
commit cdc3fbf2cf
3 changed files with 19 additions and 8 deletions

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);