diff options
Diffstat (limited to 'chip/lm4/clock.c')
-rw-r--r-- | chip/lm4/clock.c | 754 |
1 files changed, 0 insertions, 754 deletions
diff --git a/chip/lm4/clock.c b/chip/lm4/clock.c deleted file mode 100644 index 39800c9034..0000000000 --- a/chip/lm4/clock.c +++ /dev/null @@ -1,754 +0,0 @@ -/* Copyright 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. - */ - -/* Clocks and power management settings */ - -#include "clock.h" -#include "common.h" -#include "console.h" -#include "cpu.h" -#include "gpio.h" -#include "hooks.h" -#include "hwtimer.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "uart.h" -#include "util.h" -#include "watchdog.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_CLOCK, outstr) -#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args) - -#define PLL_CLOCK 66666667 /* System clock = 200MHz PLL/3 = 66.667MHz */ - -#ifdef CONFIG_LOW_POWER_USE_LFIOSC -/* - * Length of time for the processor to wake up from deep sleep. Actual - * measurement gives anywhere up to 780us, depending on the mode it is coming - * out of. The datasheet gives a maximum of 846us, for coming out of deep - * sleep in our worst case deep sleep mode. - */ -#define DEEP_SLEEP_RECOVER_TIME_USEC 850 -#else -/* - * Length of time for the processor to wake up from deep sleep. Datasheet - * maximum is 145us, but in practice have seen as much as 336us. - */ -#define DEEP_SLEEP_RECOVER_TIME_USEC 400 -#endif - -/* Low power idle statistics */ -#ifdef CONFIG_LOW_POWER_IDLE -static int idle_sleep_cnt; -static int idle_dsleep_cnt; -static uint64_t idle_dsleep_time_us; -static int dsleep_recovery_margin_us = 1000000; - -/* - * Fixed amount of time to keep the console in use flag true after boot in - * order to give a permanent window in which the low speed clock is not used. - */ -#define CONSOLE_IN_USE_ON_BOOT_TIME (15*SECOND) - -static int console_in_use_timeout_sec = 60; -static timestamp_t console_expire_time; -#endif - -static int freq; - -/** - * Disable the PLL; run off internal oscillator. - */ -static void disable_pll(void) -{ - /* Switch to 16MHz internal oscillator and power down the PLL */ - LM4_SYSTEM_RCC = LM4_SYSTEM_RCC_SYSDIV(0) | - LM4_SYSTEM_RCC_BYPASS | - LM4_SYSTEM_RCC_PWRDN | - LM4_SYSTEM_RCC_OSCSRC(1) | - LM4_SYSTEM_RCC_MOSCDIS; - -#ifdef CONFIG_LOW_POWER_IDLE - /* - * If using the low power idle, then set the ACG bit, which specifies - * that the sleep and deep sleep modes are using their own clock gating - * registers SCGC and DCGS respectively instead of using the run mode - * clock gating registers RCGC. - */ - LM4_SYSTEM_RCC |= LM4_SYSTEM_RCC_ACG; -#endif - - LM4_SYSTEM_RCC2 &= ~LM4_SYSTEM_RCC2_USERCC2; - - freq = INTERNAL_CLOCK; -} - -/** - * Enable the PLL to run at full clock speed. - */ -static void enable_pll(void) -{ - /* Disable the PLL so we can reconfigure it */ - disable_pll(); - - /* - * Enable the PLL (PWRDN is no longer set) and set divider. PLL is - * still bypassed, since it hasn't locked yet. - */ - LM4_SYSTEM_RCC = LM4_SYSTEM_RCC_SYSDIV(2) | - LM4_SYSTEM_RCC_USESYSDIV | - LM4_SYSTEM_RCC_BYPASS | - LM4_SYSTEM_RCC_OSCSRC(1) | - LM4_SYSTEM_RCC_MOSCDIS; - -#ifdef CONFIG_LOW_POWER_IDLE - /* - * If using the low power idle, then set the ACG bit, which specifies - * that the sleep and deep sleep modes are using their own clock gating - * registers SCGC and DCGS respectively instead of using the run mode - * clock gating registers RCGC. - */ - LM4_SYSTEM_RCC |= LM4_SYSTEM_RCC_ACG; -#endif - - /* Wait for the PLL to lock */ - clock_wait_cycles(1024); - while (!(LM4_SYSTEM_PLLSTAT & 1)) - ; - - /* Remove bypass on PLL */ - LM4_SYSTEM_RCC &= ~LM4_SYSTEM_RCC_BYPASS; - freq = PLL_CLOCK; -} - -void clock_enable_pll(int enable, int notify) -{ - if (enable) - enable_pll(); - else - disable_pll(); - - /* Notify modules of frequency change */ - if (notify) - hook_notify(HOOK_FREQ_CHANGE); -} - -void clock_wait_cycles(uint32_t cycles) -{ - asm volatile("1: subs %0, #1\n" - " bne 1b\n" : "+r"(cycles)); -} - -int clock_get_freq(void) -{ - return freq; -} - -void clock_init(void) -{ -#ifdef BOARD_BDS - /* - * Perform an auto calibration of the internal oscillator using the - * 32.768KHz hibernate clock, unless we've already done so. This is - * only necessary on A2 silicon as on BDS; A3 silicon is all - * factory-trimmed. - */ - if ((LM4_SYSTEM_PIOSCSTAT & 0x300) != 0x100) { - /* Start calibration */ - LM4_SYSTEM_PIOSCCAL = 0x80000000; - LM4_SYSTEM_PIOSCCAL = 0x80000200; - /* Wait for result */ - clock_wait_cycles(16); - while (!(LM4_SYSTEM_PIOSCSTAT & 0x300)) - ; - } -#else - /* - * Only BDS has an external crystal; other boards don't have one, and - * can disable main oscillator control to reduce power consumption. - */ - LM4_SYSTEM_MOSCCTL = 0x04; -#endif - - /* Make sure PLL is disabled */ - disable_pll(); -} - -void clock_enable_peripheral(uint32_t offset, uint32_t mask, uint32_t mode) -{ - if (mode & CGC_MODE_RUN) - *(LM4_SYSTEM_RCGC_BASE + offset) |= mask; - - if (mode & CGC_MODE_SLEEP) - *(LM4_SYSTEM_SCGC_BASE + offset) |= mask; - - if (mode & CGC_MODE_DSLEEP) - *(LM4_SYSTEM_DCGC_BASE + offset) |= mask; - - /* Wait for clock change to take affect. */ - clock_wait_cycles(3); -} - -void clock_disable_peripheral(uint32_t offset, uint32_t mask, uint32_t mode) -{ - if (mode & CGC_MODE_RUN) - *(LM4_SYSTEM_RCGC_BASE + offset) &= ~mask; - - if (mode & CGC_MODE_SLEEP) - *(LM4_SYSTEM_SCGC_BASE + offset) &= ~mask; - - if (mode & CGC_MODE_DSLEEP) - *(LM4_SYSTEM_DCGC_BASE + offset) &= ~mask; -} - -/* - * The low power idle task does not support using the EEPROM, - * because it is dangerous to go to deep sleep while EEPROM - * transaction is in progress. To fix, LM4_EEPROM_EEDONE, should - * be checked before going in to deep sleep. - */ -#if defined(CONFIG_LOW_POWER_IDLE) && defined(CONFIG_EEPROM) -#error "Low power idle mode does not support use of EEPROM" -#endif - -#ifdef CONFIG_LOW_POWER_IDLE - -void clock_refresh_console_in_use(void) -{ - disable_sleep(SLEEP_MASK_CONSOLE); - - /* Set console in use expire time. */ - console_expire_time = get_time(); - console_expire_time.val += console_in_use_timeout_sec * SECOND; - -} - -/* Low power idle task. Executed when no tasks are ready to be scheduled. */ -void __idle(void) -{ - timestamp_t t0, t1, rtc_t0, rtc_t1; - int next_delay = 0; - int time_for_dsleep, margin_us; - int use_low_speed_clock; - - /* Enable the hibernate IRQ used to wake up from deep sleep */ - system_enable_hib_interrupt(); - - /* Set SRAM and flash power management to 'low power' in deep sleep. */ - LM4_SYSTEM_DSLPPWRCFG = 0x23; - - /* Enable JTAG interrupt which will notify us when JTAG is in use. */ - gpio_enable_interrupt(GPIO_JTAG_TCK); - - /* - * Initialize console in use to true and specify the console expire - * time in order to give a fixed window on boot in which the low speed - * clock will not be used in idle. - */ - disable_sleep(SLEEP_MASK_CONSOLE); - console_expire_time.val = get_time().val + CONSOLE_IN_USE_ON_BOOT_TIME; - - /* - * Print when the idle task starts. This is the lowest priority task, - * so this only starts once all other tasks have gotten a chance to do - * their task inits and have gone to sleep. - */ - CPRINTS("low power idle task started"); - - while (1) { - /* - * Disable interrupts before going to deep sleep in order to - * calculate the appropriate time to wake up. Note: the wfi - * instruction waits until an interrupt is pending, so it - * will still wake up even with interrupts disabled. - */ - interrupt_disable(); - - t0 = get_time(); - next_delay = __hw_clock_event_get() - t0.le.lo; - - /* Do we have enough time before next event to deep sleep. */ - time_for_dsleep = next_delay > (DEEP_SLEEP_RECOVER_TIME_USEC + - HIB_SET_RTC_MATCH_DELAY_USEC); - - if (DEEP_SLEEP_ALLOWED && time_for_dsleep) { - /* Deep-sleep in STOP mode. */ - idle_dsleep_cnt++; - - /* Check if the console use has expired. */ - if ((sleep_mask & SLEEP_MASK_CONSOLE) && - t0.val > console_expire_time.val) { - /* Enable low speed deep sleep. */ - enable_sleep(SLEEP_MASK_CONSOLE); - - /* - * Wait one clock before checking if low speed - * deep sleep is allowed to give time for - * sleep mask to update. - */ - clock_wait_cycles(1); - - if (LOW_SPEED_DEEP_SLEEP_ALLOWED) - CPRINTS("Disabling console in " - "deep sleep"); - } - - /* - * Determine if we should use a lower clock speed or - * keep the same (16MHz) clock in deep sleep. Use the - * lower speed only if the sleep mask specifies that low - * speed sleep is allowed, the console UART TX is not - * busy, and the console UART buffer is empty. - */ - use_low_speed_clock = LOW_SPEED_DEEP_SLEEP_ALLOWED && - !uart_tx_in_progress() && uart_buffer_empty(); - -#ifdef CONFIG_LOW_POWER_USE_LFIOSC - /* Set the deep sleep clock register. Use either the - * normal PIOSC (16MHz) or the LFIOSC (32kHz). */ - LM4_SYSTEM_DSLPCLKCFG = use_low_speed_clock ? - 0x32 : 0x10; -#else - /* - * Set the deep sleep clock register. Use either the - * PIOSC with no divider (16MHz) or the PIOSC with - * a /64 divider (250kHz). - */ - LM4_SYSTEM_DSLPCLKCFG = use_low_speed_clock ? - 0x1f800010 : 0x10; -#endif - - /* - * If using low speed clock, disable console. - * This will also convert the console RX pin to a GPIO - * and set an edge interrupt to wake us from deep sleep - * if any action occurs on console. - */ - if (use_low_speed_clock) - uart_enter_dsleep(); - - /* Set deep sleep bit. */ - CPU_SCB_SYSCTRL |= 0x4; - - /* Record real time before sleeping. */ - rtc_t0 = system_get_rtc(); - - /* - * Set RTC interrupt in time to wake up before - * next event. - */ - system_set_rtc_alarm(0, next_delay - - DEEP_SLEEP_RECOVER_TIME_USEC); - - /* Wait for interrupt: goes into deep sleep. */ - asm("wfi"); - - /* Clear deep sleep bit. */ - CPU_SCB_SYSCTRL &= ~0x4; - - /* Disable and clear RTC interrupt. */ - system_reset_rtc_alarm(); - - /* Fast forward timer according to RTC counter. */ - rtc_t1 = system_get_rtc(); - t1.val = t0.val + (rtc_t1.val - rtc_t0.val); - force_time(t1); - - /* If using low speed clock, re-enable the console. */ - if (use_low_speed_clock) - uart_exit_dsleep(); - - /* Record time spent in deep sleep. */ - idle_dsleep_time_us += (rtc_t1.val - rtc_t0.val); - - /* Calculate how close we were to missing deadline */ - margin_us = next_delay - (int)(rtc_t1.val - rtc_t0.val); - if (margin_us < 0) - CPRINTS("overslept by %dus", -margin_us); - - /* Record the closest to missing a deadline. */ - if (margin_us < dsleep_recovery_margin_us) - dsleep_recovery_margin_us = margin_us; - } else { - idle_sleep_cnt++; - - /* Normal idle : only CPU clock stopped. */ - asm("wfi"); - } - interrupt_enable(); - } -} -#endif /* CONFIG_LOW_POWER_IDLE */ - -/*****************************************************************************/ -/* Console commands */ - -#ifdef CONFIG_CMD_SLEEP -/** - * Measure baseline for power consumption. - * - * Levels : - * 0 : CPU running in tight loop - * 1 : CPU running in tight loop but peripherals gated - * 2 : CPU in sleep mode - * 3 : CPU in sleep mode and peripherals gated - * 4 : CPU in deep sleep mode - * 5 : CPU in deep sleep mode and peripherals gated - * - * Clocks : - * 0 : No change - * 1 : 16MHz - * 2 : 1 MHz - * 3 : 30kHz - * - * SRAM Power Management: - * 0 : Active - * 1 : Standby - * 3 : Low Power - * - * Flash Power Management: - * 0 : Active - * 2 : Low Power - */ -static int command_sleep(int argc, char **argv) -{ - int level = 0; - int clock = 0; - int sram_pm = 0; - int flash_pm = 0; - uint32_t uartibrd = 0; - uint32_t uartfbrd = 0; - - if (argc >= 2) - level = strtoi(argv[1], NULL, 10); - if (argc >= 3) - clock = strtoi(argv[2], NULL, 10); - if (argc >= 4) - sram_pm = strtoi(argv[3], NULL, 10); - if (argc >= 5) - flash_pm = strtoi(argv[4], NULL, 10); - -#ifdef BOARD_BDS - /* Remove LED current sink. */ - gpio_set_level(GPIO_DEBUG_LED, 0); -#endif - - ccprintf("Sleep : level %d, clock %d, sram pm %d, flash_pm %d...\n", - level, clock, sram_pm, flash_pm); - cflush(); - - /* Set clock speed. */ - if (clock) { - /* Use ROM code function to set the clock */ - void **func_table = (void **)*(uint32_t *)0x01000044; - void (*rom_clock_set)(uint32_t rcc) = func_table[23]; - - /* Disable interrupts. */ - asm volatile("cpsid i"); - - switch (clock) { - case 1: /* 16MHz IOSC */ - uartibrd = 17; - uartfbrd = 23; - rom_clock_set(0x00000d51); - break; - case 2: /* 1MHz IOSC */ - uartibrd = 1; - uartfbrd = 5; - rom_clock_set(0x07C00d51); - break; - case 3: /* 30 kHz */ - uartibrd = 0; - uartfbrd = 0; - rom_clock_set(0x00000d71); - break; - } - - /* - * TODO(crosbug.com/p/23795): move this to the UART module; - * ugly to have UARTisms here. Also note this only fixes - * UART0, not UART1. Should just be able to trigger - * HOOK_FREQ_CHANGE and have that take care of it. - */ - if (uartfbrd) { - /* Disable the port via UARTCTL and add HSE. */ - LM4_UART_CTL(0) = 0x0320; - /* Set the baud rate divisor. */ - LM4_UART_IBRD(0) = uartibrd; - LM4_UART_FBRD(0) = uartfbrd; - /* Poke UARTLCRH to make the new divisor take effect. */ - LM4_UART_LCRH(0) = LM4_UART_LCRH(0); - /* Enable the port. */ - LM4_UART_CTL(0) |= 0x0001; - } - asm volatile("cpsie i"); - } - - if (uartfbrd) { - ccprintf("We are still alive. RCC=%08x\n", LM4_SYSTEM_RCC); - cflush(); - } - - /* Enable interrupts. */ - asm volatile("cpsid i"); - - /* gate peripheral clocks */ - if (level & 1) { - clock_disable_peripheral(CGC_OFFSET_WD, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_TIMER, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_GPIO, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_DMA, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_HIB, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_UART, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_SSI, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_I2C, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_ADC, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_LPC, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_PECI, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_FAN, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_EEPROM, 0xffffffff, - CGC_MODE_ALL); - clock_disable_peripheral(CGC_OFFSET_WTIMER, 0xffffffff, - CGC_MODE_ALL); - } - - /* Set deep sleep bit. */ - if (level >= 4) - CPU_SCB_SYSCTRL |= 0x4; - - /* Set SRAM and flash PM for sleep and deep sleep. */ - LM4_SYSTEM_SLPPWRCFG = (flash_pm << 4) | sram_pm; - LM4_SYSTEM_DSLPPWRCFG = (flash_pm << 4) | sram_pm; - - /* Go to low power mode (forever ...) */ - if (level > 1) - while (1) { - asm("wfi"); - watchdog_reload(); - } - else - while (1) - watchdog_reload(); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(sleep, command_sleep, - "[level [clock] [sram pm] [flash pm]]", - "Drop into sleep"); -#endif /* CONFIG_CMD_SLEEP */ - -#ifdef CONFIG_CMD_PLL - -static int command_pll(int argc, char **argv) -{ - int v; - - /* Toggle the PLL */ - if (argc > 1) { - if (parse_bool(argv[1], &v)) { - clock_enable_pll(v, 1); - } else { - /* Disable PLL and set extra divider */ - char *e; - v = strtoi(argv[1], &e, 10); - if (*e) - return EC_ERROR_PARAM1; - - LM4_SYSTEM_RCC = LM4_SYSTEM_RCC_SYSDIV(v - 1) | - LM4_SYSTEM_RCC_BYPASS | - LM4_SYSTEM_RCC_PWRDN | - LM4_SYSTEM_RCC_OSCSRC(1) | - LM4_SYSTEM_RCC_MOSCDIS; - - freq = INTERNAL_CLOCK / v; - - /* Notify modules of frequency change */ - hook_notify(HOOK_FREQ_CHANGE); - } - } - - /* Print current PLL state */ - ccprintf("RCC: 0x%08x\n", LM4_SYSTEM_RCC); - ccprintf("RCC2: 0x%08x\n", LM4_SYSTEM_RCC2); - ccprintf("PLLSTAT: 0x%08x\n", LM4_SYSTEM_PLLSTAT); - ccprintf("Clock: %d Hz\n", clock_get_freq()); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(pll, command_pll, - "[ on | off | <div> ]", - "Get/set PLL state"); - -#endif /* CONFIG_CMD_PLL */ - -#ifdef CONFIG_CMD_CLOCKGATES -/** - * Print all clock gating registers - */ -static int command_clock_gating(int argc, char **argv) -{ - ccprintf(" Run , Sleep , Deep Sleep\n"); - - ccprintf("WD: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_WD)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_WD)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_WD)); - - ccprintf("TIMER: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_TIMER)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_TIMER)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_TIMER)); - - ccprintf("GPIO: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_GPIO)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_GPIO)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_GPIO)); - - ccprintf("DMA: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_DMA)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_DMA)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_DMA)); - - ccprintf("HIB: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_HIB)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_HIB)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_HIB)); - - ccprintf("UART: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_UART)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_UART)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_UART)); - - ccprintf("SSI: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_SSI)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_SSI)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_SSI)); - - ccprintf("I2C: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_I2C)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_I2C)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_I2C)); - - ccprintf("ADC: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_ADC)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_ADC)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_ADC)); - - ccprintf("LPC: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_LPC)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_LPC)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_LPC)); - - ccprintf("PECI: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_PECI)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_PECI)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_PECI)); - - ccprintf("FAN: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_FAN)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_FAN)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_FAN)); - - ccprintf("EEPROM: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_EEPROM)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_EEPROM)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_EEPROM)); - - ccprintf("WTIMER: 0x%08x, ", - *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_WTIMER)); - ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_WTIMER)); - ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_WTIMER)); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(clockgates, command_clock_gating, - "", - "Get state of the clock gating controls regs"); -#endif /* CONFIG_CMD_CLOCKGATES */ - -#ifdef CONFIG_LOW_POWER_IDLE -/** - * Print low power idle statistics - */ -static int command_idle_stats(int argc, char **argv) -{ - timestamp_t ts = get_time(); - - ccprintf("Num idle calls that sleep: %d\n", idle_sleep_cnt); - ccprintf("Num idle calls that deep-sleep: %d\n", idle_dsleep_cnt); - ccprintf("Time spent in deep-sleep: %.6llds\n", - idle_dsleep_time_us); - ccprintf("Total time on: %.6llds\n", ts.val); - ccprintf("Deep-sleep closest to wake deadline: %dus\n", - dsleep_recovery_margin_us); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(idlestats, command_idle_stats, - "", - "Print last idle stats"); - -/** - * Configure deep sleep clock settings. - */ -static int command_dsleep(int argc, char **argv) -{ - int v; - - if (argc > 1) { - if (parse_bool(argv[1], &v)) { - /* - * Force deep sleep not to use low speed clock or - * allow it to use the low speed clock. - */ - if (v) - disable_sleep(SLEEP_MASK_FORCE_NO_LOW_SPEED); - else - enable_sleep(SLEEP_MASK_FORCE_NO_LOW_SPEED); - } else { - /* Set console in use timeout. */ - char *e; - v = strtoi(argv[1], &e, 10); - if (*e) - return EC_ERROR_PARAM1; - - console_in_use_timeout_sec = v; - - /* Refresh console in use to use new timeout. */ - clock_refresh_console_in_use(); - } - } - - ccprintf("Sleep mask: %08x\n", sleep_mask); - ccprintf("Console in use timeout: %d sec\n", - console_in_use_timeout_sec); - ccprintf("DSLPCLKCFG register: 0x%08x\n", LM4_SYSTEM_DSLPCLKCFG); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(dsleep, command_dsleep, - "[ on | off | <timeout> sec]", - "Deep sleep clock settings:\nUse 'on' to force deep " - "sleep not to use low speed clock.\nUse 'off' to " - "allow deep sleep to auto-select using the low speed " - "clock.\n" - "Give a timeout value for the console in use timeout.\n" - "See also 'sleepmask'."); -#endif /* CONFIG_LOW_POWER_IDLE */ - |