diff options
Diffstat (limited to 'chip/mchp/clock.c')
-rw-r--r-- | chip/mchp/clock.c | 780 |
1 files changed, 0 insertions, 780 deletions
diff --git a/chip/mchp/clock.c b/chip/mchp/clock.c deleted file mode 100644 index 362025ee1c..0000000000 --- a/chip/mchp/clock.c +++ /dev/null @@ -1,780 +0,0 @@ -/* Copyright 2017 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 "hooks.h" -#include "hwtimer.h" -#include "pwm.h" -#include "pwm_chip.h" -#include "registers.h" -#include "shared_mem.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "uart.h" -#include "util.h" -#include "tfdp_chip.h" -#include "vboot_hash.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_CLOCK, outstr) -#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args) - -#ifdef CONFIG_LOW_POWER_IDLE - -#define HTIMER_DIV_1_US_MAX (1998848) -#define HTIMER_DIV_1_1SEC (0x8012) - -/* Recovery time for HvySlp2 is 0 us */ -#define HEAVY_SLEEP_RECOVER_TIME_USEC 75 - -#define SET_HTIMER_DELAY_USEC 200 - -static int idle_sleep_cnt; -static int idle_dsleep_cnt; -static uint64_t total_idle_dsleep_time_us; - -#ifdef CONFIG_MCHP_DEEP_SLP_DEBUG -static uint32_t pcr_slp_en[MCHP_PCR_SLP_RST_REG_MAX]; -static uint32_t pcr_clk_req[MCHP_PCR_SLP_RST_REG_MAX]; -static uint32_t ecia_result[MCHP_INT_GIRQ_NUM]; -#endif - -/* - * Fixed amount of time to keep the console in use flag true after - * boot in order to give a permanent window in which the heavy sleep - * mode 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 /*CONFIG_LOW_POWER_IDLE */ - -static int freq = 48000000; - -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; -} - -/* - * MEC170x and MEC152x have the same 32 KHz clock enable hardware. - * MEC172x 32 KHz clock configuration is different and includes - * hardware to check the crystal before switching and to monitor - * the 32 KHz input if desired. - */ -#ifdef CHIP_FAMILY_MEC172X -/* 32 KHz crystal connected in parallel */ -static inline void config_32k_src_crystal(void) -{ - MCHP_VBAT_CSS = MCHP_VBAT_CSS_XTAL_EN - | MCHP_VBAT_CSS_SRC_XTAL; -} - -/* 32 KHz source is 32KHZ_IN pin which must be configured */ -static inline void config_32k_src_se_input(void) -{ - MCHP_VBAT_CSS = MCHP_VBAT_CSS_SIL32K_EN - | MCHP_VBAT_CSS_SRC_SWPS; -} - -static inline void config_32k_src_sil_osc(void) -{ - MCHP_VBAT_CSS = MCHP_VBAT_CSS_SIL32K_EN; -} - -#else -static void config_32k_src_crystal(void) -{ - MCHP_VBAT_CE = MCHP_VBAT_CE_XOSEL_PAR - | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_CRYSTAL; -} - -/* 32 KHz source is 32KHZ_IN pin which must be configured */ -static inline void config_32k_src_se_input(void) -{ - MCHP_VBAT_CE = MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN - | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_INT; -} - -static inline void config_32k_src_sil_osc(void) -{ - MCHP_VBAT_CE = ~(MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN - | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_CRYSTAL); -} -#endif - -/** clock_init - * @note - * MCHP MEC implements 4 control bits in the VBAT Clock Enable register. - * It also implements an internal silicon 32KHz +/- 2% oscillator powered - * by VBAT. - * b[3] = XOSEL 0=parallel, 1=single-ended - * b[2] = 32KHZ_SOURCE specifies source of always-on clock domain - * 0=internal silicon oscillator - * 1=crystal XOSEL pin(s) - * b[1] = EXT_32K use always-on clock domain or external 32KHZ_IN pin - * 0=32K source is always-on clock domain - * 1=32K source is 32KHZ_IN pin (GPIO 0165) - * b[0] = 32K_SUPPRESS - * 0=32K clock domain stays enabled if VTR is off. Powered by VBAT - * 1=32K clock domain is disabled if VTR is off. - * Set b[3] based on CONFIG_CLOCK_CRYSTAL - * Set b[2:0] = 100b - * b[0]=0 32K clock domain always on (requires VBAT if VTR is off) - * b[1]=0 32K source is the 32K clock domain NOT the 32KHZ_IN pin - * b[2]=1 If activity detected on crystal pins switch 32K input from - * internal silicon oscillator to XOSEL pin(s) based on b[3]. - */ -void clock_init(void) -{ - if (IS_ENABLED(CONFIG_CLOCK_SRC_EXTERNAL)) - if (IS_ENABLED(CONFIG_CLOCK_CRYSTAL)) - config_32k_src_crystal(); - else - /* 32KHz 50% duty waveform on 32KHZ_IN pin */ - config_32k_src_se_input(); - else - /* Use internal silicon 32KHz OSC */ - config_32k_src_sil_osc(); - - /* Wait for PLL to lock onto 32KHz source (OSC_LOCK == 1) */ - while (!(MCHP_PCR_CHIP_OSC_ID & 0x100)) - ; -} - -/** - * Speed through boot + vboot hash calculation, dropping our processor - * clock only after vboot hashing is completed. - */ -static void clock_turbo_disable(void); -DECLARE_DEFERRED(clock_turbo_disable); - -static void clock_turbo_disable(void) -{ -#ifdef CONFIG_VBOOT_HASH - if (vboot_hash_in_progress()) - hook_call_deferred(&clock_turbo_disable_data, 100 * MSEC); - else -#endif - /* Use 12 MHz processor clock for power savings */ - MCHP_PCR_PROC_CLK_CTL = MCHP_PCR_CLK_CTL_12MHZ; -} -DECLARE_HOOK(HOOK_INIT, - clock_turbo_disable, - HOOK_PRIO_INIT_VBOOT_HASH + 1); - -/** - * initialization of Hibernation timer 0 - * Clear PCR sleep enable. - * GIRQ=21, aggregator bit = 1, Direct NVIC = 112 - * NVIC direct connect interrupts are used for all peripherals - * (exception GPIO's) then the MCHP_INT_BLK_EN GIRQ bit should not be - * set. - */ -void htimer_init(void) -{ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_HTMR0); - MCHP_HTIMER_PRELOAD(0) = 0; /* disable at beginning */ - MCHP_INT_SOURCE(MCHP_HTIMER_GIRQ) = MCHP_HTIMER_GIRQ_BIT(0); - MCHP_INT_ENABLE(MCHP_HTIMER_GIRQ) = MCHP_HTIMER_GIRQ_BIT(0); - - task_enable_irq(MCHP_IRQ_HTIMER0); -} - -/** - * Use hibernate module to set up an htimer interrupt at a given - * time from now - * - * @param seconds Number of seconds before htimer interrupt - * @param microseconds Number of microseconds before htimer interrupt - * @note hibernation timer input clock is 32.768KHz. - * Control register bit[0] selects the divider. - * 0 is divide by 1 for 30.5 us per LSB for a maximum of - * 65535 * 30.5 us = 1998817.5 us or 32.786 counts per second - * 1 is divide by 4096 for 0.125 s per LSB for a maximum of ~2 hours. - * 65535 * 0.125 s ~ 8192 s = 2.27 hours - */ -void system_set_htimer_alarm(uint32_t seconds, - uint32_t microseconds) -{ - uint32_t hcnt, ns; - uint8_t hctrl; - - MCHP_HTIMER_PRELOAD(0) = 0; /* disable */ - - if (microseconds > 1000000ul) { - ns = (microseconds / 1000000ul); - microseconds %= 1000000ul; - if ((0xfffffffful - seconds) > ns) - seconds += ns; - else - seconds = 0xfffffffful; - } - - if (seconds > 1) { - hcnt = (seconds << 3); /* divide by 0.125 */ - if (hcnt > 0xfffful) - hcnt = 0xfffful; - hctrl = 1; - } else { - /* - * approximate(~2% error) as seconds is 0 or 1 - * seconds / 30.5e-6 + microseconds / 30.5 - */ - hcnt = (seconds << 15) + (microseconds >> 5) + - (microseconds >> 10); - hctrl = 0; - } - - MCHP_HTIMER_CONTROL(0) = hctrl; - MCHP_HTIMER_PRELOAD(0) = hcnt; -} - -#ifdef CONFIG_LOW_POWER_IDLE - -/** - * return time slept in micro-seconds - */ -static timestamp_t system_get_htimer(void) -{ - uint16_t count; - timestamp_t time; - - count = MCHP_HTIMER_COUNT(0); - - - if (MCHP_HTIMER_CONTROL(0) == 1) /* if > 2 sec */ - /* 0.125 sec per count */ - time.le.lo = (uint32_t)(count * 125000); - else /* if < 2 sec */ - /* 30.5(=61/2) us per count */ - time.le.lo = (uint32_t)(count * 61 / 2); - - time.le.hi = 0; - - return time; /* in uSec */ -} - -/** - * Disable and clear hibernation timer interrupt - */ -static void system_reset_htimer_alarm(void) -{ - MCHP_HTIMER_PRELOAD(0) = 0; - MCHP_INT_SOURCE(MCHP_HTIMER_GIRQ) = - MCHP_HTIMER_GIRQ_BIT(0); -} - -#ifdef CONFIG_MCHP_DEEP_SLP_DEBUG -static void print_pcr_regs(void) -{ - int i; - - trace0(0, MEC, 0, "Current PCR registers"); - for (i = 0; i < 5; i++) { - trace12(0, MEC, 0, "REG SLP_EN[%d] = 0x%08X", - i, MCHP_PCR_SLP_EN(i)); - trace12(0, MEC, 0, "REG CLK_REQ[%d] = 0x%08X", - i, MCHP_PCR_CLK_REQ(i)); - } -} - -static void print_ecia_regs(void) -{ - int i; - - trace0(0, MEC, 0, "Current GIRQn.Result registers"); - for (i = MCHP_INT_GIRQ_FIRST; - i <= MCHP_INT_GIRQ_LAST; i++) - trace12(0, MEC, 0, "GIRQ[%d].Result = 0x%08X", - i, MCHP_INT_RESULT(i)); -} - -static void save_regs(void) -{ - int i; - - for (i = 0; i < MCHP_PCR_SLP_RST_REG_MAX; i++) { - pcr_slp_en[i] = MCHP_PCR_SLP_EN(i); - pcr_clk_req[i] = MCHP_PCR_CLK_REQ(i); - } - - for (i = 0; i < MCHP_INT_GIRQ_NUM; i++) - ecia_result[i] = - MCHP_INT_RESULT(MCHP_INT_GIRQ_FIRST + i); -} - -static void print_saved_regs(void) -{ - int i; - - trace0(0, BRD, 0, "Before sleep saved registers"); - for (i = 0; i < MCHP_PCR_SLP_RST_REG_MAX; i++) { - trace12(0, BRD, 0, "PCR_SLP_EN[%d] = 0x%08X", - i, pcr_slp_en[i]); - trace12(0, BRD, 0, "PCR_CLK_REQ[%d] = 0x%08X", - i, pcr_clk_req[i]); - } - - for (i = 0; i < MCHP_INT_GIRQ_NUM; i++) - trace12(0, BRD, 0, "GIRQ[%d].Result = 0x%08X", - (i+MCHP_INT_GIRQ_FIRST), ecia_result[i]); -} -#else -static __maybe_unused void print_pcr_regs(void) {} -static __maybe_unused void print_ecia_regs(void) {} -static __maybe_unused void save_regs(void) {} -static __maybe_unused void print_saved_regs(void) {} -#endif /* #ifdef CONFIG_MCHP_DEEP_SLP_DEBUG */ - -/** - * This is MCHP specific and equivalent to ARM Cortex's - * 'DeepSleep' via system control block register, CPU_SCB_SYSCTRL - * MCHP has new SLP_ALL feature. - * When SLP_ALL is enabled and HW sees sleep entry trigger from CPU. - * 1. HW saves PCR.SLP_EN registers - * 2. HW sets all PCR.SLP_EN bits to 1. - * 3. System sleeps - * 4. wake event wakes system - * 5. HW restores original values of all PCR.SLP_EN registers - * NOTE1: Current RTOS core (Cortex-M4) does not use SysTick timer. - * We can leave code to disable it but do not re-enable on wake. - * NOTE2: Some peripherals will not sleep until outstanding transactions - * are complete: I2C, DMA, GPSPI, QMSPI, etc. - * NOTE3: Security blocks do not fully implement HW sleep therefore their - * sleep enables must be manually set/restored. - * - */ -static void prepare_for_deep_sleep(void) -{ - /* sysTick timer */ - CPU_NVIC_ST_CTRL &= ~ST_ENABLE; - CPU_NVIC_ST_CTRL &= ~ST_COUNTFLAG; - - CPU_NVIC_ST_CTRL &= ~ST_TICKINT; /* SYS_TICK_INT_DISABLE */ - - /* Enable assertion of DeepSleep signals - * from the core when core enters sleep. - */ - CPU_SCB_SYSCTRL |= BIT(2); - - /* Stop timers */ - MCHP_TMR32_CTL(0) &= ~1; - MCHP_TMR32_CTL(1) &= ~1; -#ifdef CONFIG_WATCHDOG_HELP - MCHP_TMR16_CTL(0) &= ~1; - MCHP_INT_DISABLE(MCHP_TMR16_GIRQ) = - MCHP_TMR16_GIRQ_BIT(0); - MCHP_INT_SOURCE(MCHP_TMR16_GIRQ) = - MCHP_TMR16_GIRQ_BIT(0); -#endif - MCHP_INT_DISABLE(MCHP_TMR32_GIRQ) = - MCHP_TMR32_GIRQ_BIT(0) + - MCHP_TMR32_GIRQ_BIT(1); - MCHP_INT_SOURCE(MCHP_TMR32_GIRQ) = - MCHP_TMR32_GIRQ_BIT(0) + - MCHP_TMR32_GIRQ_BIT(1); - -#ifdef CONFIG_WATCHDOG - /* Stop watchdog */ - MCHP_WDG_CTL &= ~1; -#endif - - -#ifdef CONFIG_HOSTCMD_ESPI - MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_ESPI; - MCHP_INT_ENABLE(22) = MCHP_INT22_WAKE_ONLY_ESPI; -#else - MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_LPC; - MCHP_INT_ENABLE(22) = MCHP_INT22_WAKE_ONLY_LPC; -#endif - -#ifdef CONFIG_ADC - /* - * Clear ADC activate bit. If a conversion is in progress the - * ADC block will not enter low power until the conversion is - * complete. - */ - MCHP_ADC_CTRL &= ~1; -#endif - - /* stop Port80 capture timer */ -#ifndef CHIP_FAMILY_MEC172X - MCHP_P80_ACTIVATE(0) = 0; -#endif - - /* - * Clear SLP_EN bit(s) for wake sources. - * Currently only Hibernation timer 0. - * GPIO pins can always wake. - */ - MCHP_PCR_SLP_EN3 &= ~(MCHP_PCR_SLP_EN3_HTMR0); - -#ifdef CONFIG_PWM - pwm_keep_awake(); /* clear sleep enables of active PWM's */ -#else - /* Disable 100 Khz clock */ - MCHP_PCR_SLOW_CLK_CTL &= 0xFFFFFC00; -#endif - -#ifdef CONFIG_CHIPSET_DEBUG - /* Disable JTAG and preserve mode */ - MCHP_EC_JTAG_EN &= ~(MCHP_JTAG_ENABLE); -#endif - - /* call board level */ -#ifdef CONFIG_BOARD_DEEP_SLEEP - board_prepare_for_deep_sleep(); -#endif - -#ifdef CONFIG_MCHP_DEEP_SLP_DEBUG - save_regs(); -#endif -} - -static void resume_from_deep_sleep(void) -{ - MCHP_PCR_SYS_SLP_CTL = 0x00; /* default */ - - /* Disable assertion of DeepSleep signal when core executes WFI */ - CPU_SCB_SYSCTRL &= ~BIT(2); - -#ifdef CONFIG_MCHP_DEEP_SLP_DEBUG - print_saved_regs(); - print_pcr_regs(); - print_ecia_regs(); -#endif - -#ifdef CONFIG_CHIPSET_DEBUG - MCHP_EC_JTAG_EN |= (MCHP_JTAG_ENABLE); -#endif - - MCHP_PCR_SLOW_CLK_CTL |= 0x1e0; - - /* call board level */ -#ifdef CONFIG_BOARD_DEEP_SLEEP - board_resume_from_deep_sleep(); -#endif - /* - * re-enable hibernation timer 0 PCR.SLP_EN to - * reduce power. - */ - MCHP_PCR_SLP_EN3 |= (MCHP_PCR_SLP_EN3_HTMR0); - -#ifdef CONFIG_HOSTCMD_ESPI - #ifdef CONFIG_POWER_S0IX - MCHP_INT_DISABLE(22) = MCHP_INT22_WAKE_ONLY_ESPI; - MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_ESPI; - #else - MCHP_ESPI_ACTIVATE |= 1; - #endif -#else - #ifdef CONFIG_POWER_S0IX - MCHP_INT_DISABLE(22) = MCHP_INT22_WAKE_ONLY_LPC; - MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_LPC; - #else - MCHP_LPC_ACT |= 1; - #endif -#endif - - /* re-enable Port 80 capture */ -#ifndef CHIP_FAMILY_MEC172X - MCHP_P80_ACTIVATE(0) = 1; -#endif - -#ifdef CONFIG_ADC - MCHP_ADC_CTRL |= 1; -#endif - - /* Enable timer */ - MCHP_TMR32_CTL(0) |= 1; - MCHP_TMR32_CTL(1) |= 1; - MCHP_TMR16_CTL(0) |= 1; - MCHP_INT_ENABLE(MCHP_TMR32_GIRQ) = - MCHP_TMR32_GIRQ_BIT(0) + - MCHP_TMR32_GIRQ_BIT(1); - MCHP_INT_ENABLE(MCHP_TMR16_GIRQ) = - MCHP_TMR16_GIRQ_BIT(0); - - /* Enable watchdog */ -#ifdef CONFIG_WATCHDOG -#ifdef CONFIG_CHIPSET_DEBUG - /* enable WDG stall on active JTAG and do not start */ - MCHP_WDG_CTL = BIT(4); -#else - MCHP_WDG_CTL |= 1; -#endif -#endif -} - - -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; - timestamp_t t1; - timestamp_t ht_t1; - uint32_t next_delay; - uint32_t max_sleep_time; - int time_for_dsleep; - int uart_ready_for_deepsleep; - - htimer_init(); /* hibernation timer initialize */ - - 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 initializations and have gone to sleep. - */ - CPRINTS("MEC low power idle task started"); - - while (1) { - /* Disable interrupts */ - interrupt_disable(); - - t0 = get_time(); /* uSec */ - - /* __hw_clock_event_get() is next programmed timer event */ - next_delay = __hw_clock_event_get() - t0.le.lo; - - time_for_dsleep = next_delay > - (HEAVY_SLEEP_RECOVER_TIME_USEC + - SET_HTIMER_DELAY_USEC); - - max_sleep_time = next_delay - - HEAVY_SLEEP_RECOVER_TIME_USEC; - - /* check if there enough time for deep sleep */ - if (DEEP_SLEEP_ALLOWED && time_for_dsleep) { - /* - * Check if the console use has expired and - * console sleep is masked by GPIO(UART-RX) - * interrupt. - */ - if ((sleep_mask & SLEEP_MASK_CONSOLE) && - t0.val > console_expire_time.val) { - /* allow console to sleep. */ - enable_sleep(SLEEP_MASK_CONSOLE); - - /* - * Wait one clock before checking if - * heavy sleep is allowed to give time - * for sleep mask to be updated. - */ - clock_wait_cycles(1); - - if (LOW_SPEED_DEEP_SLEEP_ALLOWED) - CPRINTS("MEC Disable console " - "in deep sleep"); - } - - - /* UART is not being used */ - uart_ready_for_deepsleep = - LOW_SPEED_DEEP_SLEEP_ALLOWED && - !uart_tx_in_progress() && - uart_buffer_empty(); - - /* - * Since MCHP's heavy sleep mode requires all - * blocks to be sleep capable, UART/console - * readiness is final decision factor of - * heavy sleep of EC. - */ - if (uart_ready_for_deepsleep) { - - idle_dsleep_cnt++; - - /* - * configure UART Rx as GPIO wakeup - * interrupt source - */ - uart_enter_dsleep(); - - /* MCHP specific deep-sleep mode */ - prepare_for_deep_sleep(); - - /* - * 'max_sleep_time' value should be big - * enough so that hibernation timer's - * interrupt triggers only after 'wfi' - * completes its execution. - */ - max_sleep_time -= - (get_time().le.lo - t0.le.lo); - - /* setup/enable htimer wakeup interrupt */ - system_set_htimer_alarm(0, - max_sleep_time); - - /* set sleep all just before WFI */ - MCHP_PCR_SYS_SLP_CTL |= - MCHP_PCR_SYS_SLP_HEAVY; - MCHP_PCR_SYS_SLP_CTL |= - MCHP_PCR_SYS_SLP_ALL; - - } else { - idle_sleep_cnt++; - } - - /* Wait for interrupt: goes into deep sleep. */ - asm("dsb"); - asm("wfi"); - asm("isb"); - asm("nop"); - - if (uart_ready_for_deepsleep) { - - resume_from_deep_sleep(); - - /* - * Fast forward timer according to htimer - * counter: - * Since all blocks including timers - * will be in sleep mode, timers stops - * except hibernate timer. - * And system schedule timer should be - * corrected after wakeup by either - * hibernate timer or GPIO_UART_RX - * interrupt. - */ - ht_t1 = system_get_htimer(); - - /* disable/clear htimer wakeup interrupt */ - system_reset_htimer_alarm(); - - t1.val = t0.val + - (uint64_t)(max_sleep_time - - ht_t1.le.lo); - - force_time(t1); - - /* re-enable UART */ - uart_exit_dsleep(); - - /* Record time spent in deep sleep. */ - total_idle_dsleep_time_us += - (uint64_t)(max_sleep_time - - ht_t1.le.lo); - } - - } else { /* CPU 'Sleep' mode */ - - idle_sleep_cnt++; - - asm("wfi"); - - } - - interrupt_enable(); - } /* while(1) */ -} - -#ifdef CONFIG_CMD_IDLE_STATS -/** - * 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("Total Time spent in deep-sleep(sec): %.6lld(s)\n", - total_idle_dsleep_time_us); - ccprintf("Total time on: %.6llds\n\n", - ts.val); - - if (IS_ENABLED(CONFIG_MCHP_DEEP_SLP_DEBUG)) - print_pcr_regs(); /* debug */ - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(idlestats, command_idle_stats, - "", - "Print last idle stats"); -#endif /* defined(CONFIG_CMD_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 heavy sleep mode or - * allow it to use the heavy sleep mode. - */ - if (v) /* 'on' */ - disable_sleep( - SLEEP_MASK_FORCE_NO_LOW_SPEED); - else /* 'off' */ - 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); - - 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 enter heavy sleep mode.\nUse 'off' to " - "allow deep sleep to use heavy sleep whenever conditions " - "allow.\n" - "Give a timeout value for the console in use timeout.\n" - "See also 'sleep mask'."); -#endif /* CONFIG_LOW_POWER_IDLE */ |