mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-30 18:41:11 +00:00
This was causing cpu to give lower performance. Hard throttling is being handled in chipset_throttle_cpu. BUG=None TEST=Improved CPU benchmark Change-Id: I0bff47ec0ce60f31fa1f30fdea94d45dfe05aa38 Signed-off-by: Akshu Agrawal <akshu.agrawal@amd.com> Reviewed-on: https://chromium-review.googlesource.com/508569 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: YH Lin <yueherngl@chromium.org>
262 lines
5.7 KiB
C
262 lines
5.7 KiB
C
/* 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.
|
|
*/
|
|
|
|
/* Stoney power sequencing module for Chrome EC */
|
|
|
|
#include "chipset.h"
|
|
#include "common.h"
|
|
#include "console.h"
|
|
#include "ec_commands.h"
|
|
#include "gpio.h"
|
|
#include "hooks.h"
|
|
#include "lid_switch.h"
|
|
#include "lpc.h"
|
|
#include "power.h"
|
|
#include "power_button.h"
|
|
#include "system.h"
|
|
#include "timer.h"
|
|
#include "usb_charge.h"
|
|
#include "util.h"
|
|
#include "wireless.h"
|
|
#include "registers.h"
|
|
#include "stoney.h"
|
|
|
|
/* Console output macros */
|
|
#define CPUTS(outstr) cputs(CC_CHIPSET, outstr)
|
|
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
|
|
|
|
static int forcing_coldreset; /* Forced coldreset in progress? */
|
|
|
|
void chipset_force_shutdown(void)
|
|
{
|
|
CPRINTS("%s()", __func__);
|
|
|
|
/* TODO: shutdown */
|
|
}
|
|
|
|
void chipset_reset(int cold_reset)
|
|
{
|
|
CPRINTS("%s(%d)", __func__, cold_reset);
|
|
if (cold_reset) {
|
|
/*
|
|
* Perform chipset_force_shutdown and mark forcing_coldreset.
|
|
* Once in S5G3 state, check forcing_coldreset to power up.
|
|
*/
|
|
forcing_coldreset = 1;
|
|
|
|
chipset_force_shutdown();
|
|
} else {
|
|
/*
|
|
* Send a pulse to SYS_RST to trigger a warm reset.
|
|
*/
|
|
gpio_set_level(GPIO_PCH_RCIN_L, 0);
|
|
usleep(32 * MSEC);
|
|
gpio_set_level(GPIO_PCH_RCIN_L, 1);
|
|
}
|
|
}
|
|
|
|
void chipset_throttle_cpu(int throttle)
|
|
{
|
|
CPRINTS("%s(%d)", __func__, throttle);
|
|
if (chipset_in_state(CHIPSET_STATE_ON))
|
|
gpio_set_level(GPIO_CPU_PROCHOT, throttle);
|
|
}
|
|
|
|
enum power_state power_chipset_init(void)
|
|
{
|
|
/* Pause in S5 when shutting down. */
|
|
power_set_pause_in_s5(1);
|
|
|
|
/*
|
|
* If we're switching between images without rebooting, see if the x86
|
|
* is already powered on; if so, leave it there instead of cycling
|
|
* through G3.
|
|
*/
|
|
if (system_jumped_to_this_image()) {
|
|
if (gpio_get_level(GPIO_VGATE)) {
|
|
/* Disable idle task deep sleep when in S0. */
|
|
disable_sleep(SLEEP_MASK_AP_RUN);
|
|
|
|
CPRINTS("already in S0");
|
|
return POWER_S0;
|
|
}
|
|
|
|
CPRINTS("forcing G3");
|
|
chipset_force_shutdown();
|
|
}
|
|
return POWER_G3;
|
|
}
|
|
|
|
static void handle_pass_through(enum power_state state,
|
|
enum gpio_signal pin_in,
|
|
enum gpio_signal pin_out)
|
|
{
|
|
/*
|
|
* Pass through asynchronously, as SOC may not react
|
|
* immediately to power changes.
|
|
*/
|
|
int in_level = gpio_get_level(pin_in);
|
|
int out_level = gpio_get_level(pin_out);
|
|
|
|
/* Nothing to do. */
|
|
if (in_level == out_level)
|
|
return;
|
|
|
|
gpio_set_level(pin_out, in_level);
|
|
|
|
CPRINTS("Pass through %s: %d", gpio_get_name(pin_in), in_level);
|
|
}
|
|
|
|
enum power_state _power_handle_state(enum power_state state)
|
|
{
|
|
switch (state) {
|
|
case POWER_G3:
|
|
break;
|
|
|
|
case POWER_G3S5:
|
|
/* Exit SOC G3 */
|
|
/* Platform is powering up, clear forcing_coldreset */
|
|
forcing_coldreset = 0;
|
|
#ifdef CONFIG_PMIC
|
|
/* Call hooks to initialize PMIC */
|
|
hook_notify(HOOK_CHIPSET_PRE_INIT);
|
|
#endif
|
|
CPRINTS("Exit SOC G3");
|
|
|
|
if (power_wait_signals(IN_SPOK)) {
|
|
chipset_force_shutdown();
|
|
return POWER_G3;
|
|
}
|
|
return POWER_S5;
|
|
|
|
case POWER_S5:
|
|
if (!power_has_signals(IN_SPOK)) {
|
|
/* Required rail went away */
|
|
chipset_force_shutdown();
|
|
return POWER_S5G3;
|
|
} else if (gpio_get_level(GPIO_PCH_SLP_S5_L) == 1) {
|
|
/* Power up to next state */
|
|
return POWER_S5S3;
|
|
}
|
|
break;
|
|
|
|
case POWER_S5S3:
|
|
if (!power_has_signals(IN_SPOK)) {
|
|
/* Required rail went away */
|
|
chipset_force_shutdown();
|
|
return POWER_S5G3;
|
|
}
|
|
|
|
/* Call hooks now that rails are up */
|
|
hook_notify(HOOK_CHIPSET_STARTUP);
|
|
|
|
return POWER_S3;
|
|
|
|
case POWER_S3:
|
|
if (!power_has_signals(IN_SPOK)) {
|
|
/* Required rail went away */
|
|
chipset_force_shutdown();
|
|
return POWER_S3S5;
|
|
} else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 1) {
|
|
/* Power up to next state */
|
|
return POWER_S3S0;
|
|
} else if (gpio_get_level(GPIO_PCH_SLP_S5_L) == 0) {
|
|
/* Power down to next state */
|
|
return POWER_S3S5;
|
|
}
|
|
break;
|
|
|
|
case POWER_S3S0:
|
|
if (!power_has_signals(IN_SPOK)) {
|
|
/* Required rail went away */
|
|
chipset_force_shutdown();
|
|
return POWER_S3S5;
|
|
}
|
|
|
|
gpio_set_level(GPIO_ENABLE_BACKLIGHT, 1);
|
|
|
|
/* Enable wireless */
|
|
wireless_set_state(WIRELESS_ON);
|
|
|
|
/* Call hooks now that rails are up */
|
|
hook_notify(HOOK_CHIPSET_RESUME);
|
|
|
|
/*
|
|
* Disable idle task deep sleep. This means that the low
|
|
* power idle task will not go into deep sleep while in S0.
|
|
*/
|
|
disable_sleep(SLEEP_MASK_AP_RUN);
|
|
|
|
return POWER_S0;
|
|
|
|
case POWER_S0:
|
|
if (!power_has_signals(IN_SPOK)) {
|
|
chipset_force_shutdown();
|
|
return POWER_S0S3;
|
|
} else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 0) {
|
|
/* Power down to next state */
|
|
return POWER_S0S3;
|
|
}
|
|
|
|
break;
|
|
case POWER_S0S3:
|
|
/* Call hooks before we remove power rails */
|
|
hook_notify(HOOK_CHIPSET_SUSPEND);
|
|
|
|
gpio_set_level(GPIO_ENABLE_BACKLIGHT, 0);
|
|
|
|
/* Suspend wireless */
|
|
wireless_set_state(WIRELESS_SUSPEND);
|
|
|
|
/*
|
|
* Enable idle task deep sleep. Allow the low power idle task
|
|
* to go into deep sleep in S3 or lower.
|
|
*/
|
|
enable_sleep(SLEEP_MASK_AP_RUN);
|
|
|
|
return POWER_S3;
|
|
|
|
case POWER_S3S5:
|
|
/* Call hooks before we remove power rails */
|
|
hook_notify(HOOK_CHIPSET_SHUTDOWN);
|
|
|
|
/* Disable wireless */
|
|
wireless_set_state(WIRELESS_OFF);
|
|
|
|
return POWER_S5;
|
|
|
|
case POWER_S5G3:
|
|
chipset_force_shutdown();
|
|
|
|
/* Power up the platform again for forced cold reset */
|
|
if (forcing_coldreset) {
|
|
forcing_coldreset = 0;
|
|
return POWER_G3S5;
|
|
}
|
|
|
|
return POWER_G3;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return state;
|
|
}
|
|
|
|
enum power_state power_handle_state(enum power_state state)
|
|
{
|
|
enum power_state new_state;
|
|
|
|
/* Process RSMRST_L state changes. */
|
|
handle_pass_through(state, GPIO_SPOK, GPIO_PCH_RSMRST_L);
|
|
|
|
/* Process ALL_SYS_PGOOD state changes. */
|
|
handle_pass_through(state, GPIO_VGATE, GPIO_PCH_SYS_PWROK);
|
|
|
|
new_state = _power_handle_state(state);
|
|
|
|
return new_state;
|
|
}
|
|
|