diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2016-03-08 11:17:43 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-03-14 20:11:25 -0700 |
commit | 45919e6d722eef7cee11a6ca142f3ebca01dafc3 (patch) | |
tree | 600f467b9b548056fe21a36d8a671af9713c1ab5 | |
parent | 1c0b8dc816980061dfd048d62eff8a7f4bc594c6 (diff) | |
download | chrome-ec-45919e6d722eef7cee11a6ca142f3ebca01dafc3.tar.gz |
power: Add support for rk3399 power sequencing
Add power-up sequencing for rk3399. This is very much a WIP and the
sequence will surely change greatly.
BUG=chrome-os-partner:50819
BRANCH=None
TEST=`make buildall -j`
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Change-Id: I3bacdc8516cfe081411032d55374dd1ab21b2d9d
Reviewed-on: https://chromium-review.googlesource.com/331658
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | power/build.mk | 1 | ||||
-rw-r--r-- | power/rk3399.c | 212 |
3 files changed, 216 insertions, 0 deletions
diff --git a/include/config.h b/include/config.h index 1845cd1ff5..540ba76cf2 100644 --- a/include/config.h +++ b/include/config.h @@ -472,6 +472,8 @@ #undef CONFIG_CHIPSET_GAIA /* Gaia and Ares (ARM) */ #undef CONFIG_CHIPSET_HASWELL /* Intel Haswell (x86) */ #undef CONFIG_CHIPSET_MEDIATEK /* MediaTek MT81xx */ +#undef CONFIG_CHIPSET_RK3399 /* Rockchip rk3399 */ +/* TODO: Rename below config to CONFIG_CHIPSET_RK32XX */ #undef CONFIG_CHIPSET_ROCKCHIP /* Rockchip rk32xx */ #undef CONFIG_CHIPSET_SKYLAKE /* Intel Skylake (x86) */ #undef CONFIG_CHIPSET_TEGRA /* nVidia Tegra 5 */ @@ -2109,6 +2111,7 @@ #undef CONFIG_CHIPSET_GAIA #undef CONFIG_CHIPSET_HASWELL #undef CONFIG_CHIPSET_MEDIATEK +#undef CONFIG_CHIPSET_RK3399 #undef CONFIG_CHIPSET_ROCKCHIP #undef CONFIG_CHIPSET_SKYLAKE #undef CONFIG_CHIPSET_TEGRA diff --git a/power/build.mk b/power/build.mk index 90ffe342d5..d45e4ae5a7 100644 --- a/power/build.mk +++ b/power/build.mk @@ -12,6 +12,7 @@ power-$(CONFIG_CHIPSET_ECDRIVEN)+=ec_driven.o power-$(CONFIG_CHIPSET_GAIA)+=gaia.o power-$(CONFIG_CHIPSET_HASWELL)+=haswell.o power-$(CONFIG_CHIPSET_MEDIATEK)+=mediatek.o +power-$(CONFIG_CHIPSET_RK3399)+=rk3399.o power-$(CONFIG_CHIPSET_ROCKCHIP)+=rockchip.o power-$(CONFIG_CHIPSET_SKYLAKE)+=skylake.o power-$(CONFIG_CHIPSET_TEGRA)+=tegra.o diff --git a/power/rk3399.c b/power/rk3399.c new file mode 100644 index 0000000000..aee07cce82 --- /dev/null +++ b/power/rk3399.c @@ -0,0 +1,212 @@ +/* Copyright (c) 2013 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. + */ + +/* rk3399 chipset power control 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 "power.h" +#include "power_button.h" +#include "system.h" +#include "timer.h" +#include "usb_charge.h" +#include "util.h" +#include "wireless.h" + +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_CHIPSET, outstr) +#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) + +/* Input state flags */ +/* TODO: Monitor input signals to determine AP power state */ + +static const struct power_signal_info power_control_outputs[] = { + { GPIO_AP_CORE_EN, 1 }, + { GPIO_LPDDR_PWR_EN, 1 }, + { GPIO_PPVAR_CLOGIC_EN, 1 }, + { GPIO_PPVAR_LOGIC_EN, 1 }, + + { GPIO_PP900_AP_EN, 1 }, + { GPIO_PP900_DDRPLL_EN, 1 }, + { GPIO_PP900_PLL_EN, 1 }, + { GPIO_PP900_PMU_EN, 1 }, + { GPIO_PP900_USB_EN, 1 }, + { GPIO_PP900_PCIE_EN, 1 }, + + { GPIO_PP1200_HSIC_EN, 1 }, + + { GPIO_PP1800_SENSOR_EN_L, 0 }, + { GPIO_PP1800_LID_EN_L, 0 }, + { GPIO_PP1800_PMU_EN_L, 0 }, + { GPIO_PP1800_AP_AVDD_EN_L, 0 }, + { GPIO_PP1800_USB_EN_L, 0 }, + { GPIO_PP1800_S0_EN_L, 0 }, + { GPIO_PP1800_SIXAXIS_EN_L, 0 }, + + { GPIO_PP3300_TRACKPAD_EN_L, 0 }, + { GPIO_PP3300_USB_EN_L, 0 }, + { GPIO_PP3300_S0_EN_L, 0 }, + + { GPIO_PP5000_EN, 1 }, + + { GPIO_SYS_RST, 1 }, +}; + + + +void chipset_force_shutdown(void) +{ + CPRINTS("%s()", __func__); + + /* + * Force power off. This condition will reset once the state machine + * transitions to G3. + */ + /* TODO: Implement */ +} + +void chipset_reset(int cold_reset) +{ + /* TODO: implement */ + CPRINTS("%s(%d)", __func__, cold_reset); +} + +enum power_state power_chipset_init(void) +{ + int i; + const struct power_signal_info *output_signal; + + /* TODO: decode state after sysjump */ + /* Force all signals to their G3 states */ + CPRINTS("forcing G3"); + for (i = 0; i < ARRAY_SIZE(power_control_outputs); ++i) { + output_signal = &power_control_outputs[i]; + gpio_set_level(output_signal->gpio, !output_signal->level); + } + + wireless_set_state(WIRELESS_OFF); + return POWER_G3; +} + +enum power_state power_handle_state(enum power_state state) +{ + switch (state) { + case POWER_G3: + break; + + case POWER_S5: + /* Power up to next state */ + return POWER_S5S3; + + case POWER_S3: + /* Power up to next state */ + return POWER_S3S0; + + case POWER_S0: + break; + + case POWER_G3S5: + /* Power up to next state */ + return POWER_S5; + + case POWER_S5S3: + gpio_set_level(GPIO_PPVAR_LOGIC_EN, 1); + gpio_set_level(GPIO_PP900_AP_EN, 1); + msleep(2); + gpio_set_level(GPIO_PP900_PMU_EN, 1); + gpio_set_level(GPIO_PP900_PLL_EN, 1); + gpio_set_level(GPIO_PP900_USB_EN, 1); + gpio_set_level(GPIO_PP900_DDRPLL_EN, 1); + gpio_set_level(GPIO_PP900_PCIE_EN, 1); + msleep(2); + gpio_set_level(GPIO_PPVAR_CLOGIC_EN, 1); + msleep(2); + gpio_set_level(GPIO_PP1800_PMU_EN_L, 0); + gpio_set_level(GPIO_PP1800_USB_EN_L, 0); + gpio_set_level(GPIO_PP1800_AP_AVDD_EN_L, 0); + msleep(2); + gpio_set_level(GPIO_LPDDR_PWR_EN, 1); + gpio_set_level(GPIO_PP5000_EN, 1); + msleep(2); + + gpio_set_level(GPIO_PP1800_SIXAXIS_EN_L, 0); + gpio_set_level(GPIO_PP3300_TRACKPAD_EN_L, 0); + gpio_set_level(GPIO_PP1200_HSIC_EN, 1); + + /* Call hooks now that rails are up */ + hook_notify(HOOK_CHIPSET_STARTUP); + /* Power up to next state */ + return POWER_S3; + + case POWER_S3S0: + gpio_set_level(GPIO_AP_CORE_EN, 1); + msleep(2); + gpio_set_level(GPIO_PP3300_USB_EN_L, 0); + msleep(2); + gpio_set_level(GPIO_PP1800_S0_EN_L, 0); + msleep(2); + gpio_set_level(GPIO_PP3300_S0_EN_L, 0); + msleep(2); + msleep(10); /* TBD */ + + /* Pulse SYS_RST */ + gpio_set_level(GPIO_SYS_RST, 1); + msleep(10); + gpio_set_level(GPIO_SYS_RST, 0); + + gpio_set_level(GPIO_PP1800_LID_EN_L, 0); + gpio_set_level(GPIO_PP1800_SENSOR_EN_L, 0); + + /* 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); + + /* Power up to next state */ + return POWER_S0; + + case POWER_S0S3: + /* Call hooks before we remove power rails */ + hook_notify(HOOK_CHIPSET_SUSPEND); + + /* 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); + + /* Start shutting down */ + return POWER_S5; + + case POWER_S5G3: + return POWER_G3; + } + + return state; +} |