[coreboot-gerrit] New patch to review for coreboot: 49b5d42 google/snow: Support sleep/resume.
Hung-Te Lin (hungte@chromium.org)
gerrit at coreboot.org
Tue Apr 16 14:04:08 CEST 2013
Hung-Te Lin (hungte at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3102
-gerrit
commit 49b5d420df391b3c10621fc83553c7012470d19f
Author: Hung-Te Lin <hungte at chromium.org>
Date: Tue Apr 16 20:03:00 2013 +0800
google/snow: Support sleep/resume.
WIP. Do not submit.
Change-Id: I65681c42eeef2736e55bb906595f42a5b1dfdf11
Signed-off-by: Hung-Te Lin <hungte at chromium.org>
---
src/cpu/samsung/exynos5250/dmc_init_ddr3.c | 14 +++-
src/cpu/samsung/exynos5250/lowlevel_init_c.c | 1 +
src/cpu/samsung/exynos5250/setup.h | 4 +-
src/mainboard/google/snow/romstage.c | 119 +++++++++++++++++++--------
4 files changed, 99 insertions(+), 39 deletions(-)
diff --git a/src/cpu/samsung/exynos5250/dmc_init_ddr3.c b/src/cpu/samsung/exynos5250/dmc_init_ddr3.c
index 9a4ead0..e926cde 100644
--- a/src/cpu/samsung/exynos5250/dmc_init_ddr3.c
+++ b/src/cpu/samsung/exynos5250/dmc_init_ddr3.c
@@ -58,7 +58,8 @@ static void reset_phy_ctrl(void)
sdelay(425000);
}
-int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
+int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
+ int mem_reset)
{
unsigned int val;
struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
@@ -68,9 +69,14 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
phy0_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY0_BASE;
phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE;
dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE;
- printk(BIOS_SPEW, "ddr3_mem_ctrl_init: reset phy: ");
- reset_phy_ctrl();
- printk(BIOS_SPEW, "done\n");
+
+ if (mem_reset) {
+ printk(BIOS_SPEW, "%s: reset phy: ", __func__);
+ reset_phy_ctrl();
+ printk(BIOS_SPEW, "done\n");
+ } else {
+ printk(BIOS_SPEW, "%s: skip mem_reset.\n", __func__);
+ }
/* Set Impedance Output Driver */
printk(BIOS_SPEW, "ddr3_mem_ctrl_init: Set Impedance Output Driver\n");
diff --git a/src/cpu/samsung/exynos5250/lowlevel_init_c.c b/src/cpu/samsung/exynos5250/lowlevel_init_c.c
index daa691f..e403353 100644
--- a/src/cpu/samsung/exynos5250/lowlevel_init_c.c
+++ b/src/cpu/samsung/exynos5250/lowlevel_init_c.c
@@ -73,6 +73,7 @@ enum {
DO_UART = 1 << 1,
DO_CLOCKS = 1 << 2,
DO_POWER = 1 << 3,
+ DO_MEM_RESET = 1 << 4,
};
int lowlevel_init_subsystems(void)
diff --git a/src/cpu/samsung/exynos5250/setup.h b/src/cpu/samsung/exynos5250/setup.h
index 4f7f58c..952c125 100644
--- a/src/cpu/samsung/exynos5250/setup.h
+++ b/src/cpu/samsung/exynos5250/setup.h
@@ -702,9 +702,11 @@ void mem_ctrl_init(void);
* which the DMC uses to decide how to split a memory
* chunk into smaller chunks to support concurrent
* accesses; may vary across boards.
+ * @param mem_reset Reset memory when initialization.
* @return 0 if ok, SETUP_ERR_... if there is a problem
*/
-int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size);
+int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
+ int mem_reset);
void tzpc_init(void);
/*
diff --git a/src/mainboard/google/snow/romstage.c b/src/mainboard/google/snow/romstage.c
index dda4e7c..febe995 100644
--- a/src/mainboard/google/snow/romstage.c
+++ b/src/mainboard/google/snow/romstage.c
@@ -25,6 +25,8 @@
#include <arch/cache.h>
#include <arch/gpio.h>
+#include <arch/hlt.h>
+#include <cpu/samsung/exynos5-common/exynos5-common.h>
#include <cpu/samsung/exynos5-common/i2c.h>
#include <cpu/samsung/exynos5250/clk.h>
#include <cpu/samsung/exynos5250/cpu.h>
@@ -46,9 +48,9 @@
#define PMIC_BUS 0
#define MMC0_GPIO_PIN (58)
-#if 0
-static int board_wakeup_permitted(void)
+static int wakeup_permitted(void)
{
+#if 0
const int gpio = GPIO_Y10;
int is_bad_wake;
@@ -56,8 +58,9 @@ static int board_wakeup_permitted(void)
is_bad_wake = ((gpio != -1) && gpio_get_value(gpio));
return !is_bad_wake;
-}
#endif
+ return 1;
+}
static int setup_pmic(void)
{
@@ -145,53 +148,101 @@ static void chromeos_gpios(void)
s5p_gpio_set_pull(&gpio_pt2->x3, LID_OPEN, EXYNOS_GPIO_PULL_NONE);
}
+/* Initialization steps */
+enum {
+ DO_WAKEUP = 1 << 0,
+ DO_UART = 1 << 1,
+ DO_CLOCKS = 1 << 2,
+ DO_POWER = 1 << 3,
+ DO_MEM_RESET = 1 << 4,
+};
+
void main(void)
{
struct mem_timings *mem;
struct arm_clk_ratios *arm_ratios;
- int ret;
+ int ret, actions;
void *entry;
+ uint32_t reset_status;
+
+ reset_status = power_read_reset_status();
+ switch (reset_status) {
+ case S5P_CHECK_SLEEP:
+ actions = DO_CLOCKS | DO_WAKEUP;
+ break;
+
+ case S5P_CHECK_DIDLE:
+ case S5P_CHECK_LPA:
+ actions = DO_WAKEUP;
+ break;
+
+ default:
+ /* Normal boot (not wake from sleep). */
+ actions = DO_UART | DO_CLOCKS | DO_POWER | DO_MEM_RESET;
+ break;
+ }
- clock_set_rate(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
-
- /* Clock must be initialized before console_init, otherwise you may need
- * to re-initialize serial console drivers again. */
- mem = get_mem_timings();
- arm_ratios = get_arm_clk_ratios();
- system_clock_init(mem, arm_ratios);
+ if (actions & DO_CLOCKS) {
+ /* Clock must be initialized before console_init, otherwise you
+ * may need to re-initialize serial console drivers again. */
+ mem = get_mem_timings();
+ arm_ratios = get_arm_clk_ratios();
+ system_clock_init(mem, arm_ratios);
+ }
- console_init();
+ if (actions & DO_UART) {
+ console_init();
+ }
- i2c_init(0, CONFIG_SYS_I2C_SPEED, 0x00);
- if (power_init())
- power_shutdown();
- printk(BIOS_DEBUG, "%s: setting up pmic...\n", __func__);
- if (setup_pmic())
- power_shutdown();
+ printk(BIOS_INFO, "%s: Booting from %s mode.\n", __func__,
+ reset_status == S5P_CHECK_SLEEP ? "sleep" :
+ reset_status == S5P_CHECK_DIDLE ? "D-idle" :
+ reset_status == S5P_CHECK_LPA ? "LPA" :
+ "normal");
+
+ if (actions & DO_POWER) {
+ if (power_init())
+ power_shutdown();
+ /* Initialize I2C to program PMIC. */
+ i2c_init(0, CONFIG_SYS_I2C_SPEED, 0x00);
+ printk(BIOS_DEBUG, "%s: setting up pmic...\n", __func__);
+ if (setup_pmic())
+ power_shutdown();
+ }
- if (!mem) {
- printk(BIOS_CRIT, "Unable to auto-detect memory timings\n");
- while(1);
+ if (actions & DO_CLOCKS) {
+ if (!mem) {
+ printk(BIOS_CRIT,
+ "%s: Unable to auto-detect memory timings\n",
+ __func__);
+ hlt();
+ }
+ printk(BIOS_SPEW, "mem: %#x type: %#x, div: %#x, mhz: %#x\n",
+ mem->mem_manuf, mem->mem_type, mem->mpll_mdiv,
+ mem->frequency_mhz);
+ ret = ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE,
+ actions & DO_MEM_RESET);
+ if (ret) {
+ printk(BIOS_CRIT,
+ "%s: Memory controller init failed, err: %#x\n",
+ __func__, ret);
+ hlt();
+ }
}
- printk(BIOS_SPEW, "man: 0x%x type: 0x%x, div: 0x%x, mhz: 0x%x\n",
- mem->mem_manuf,
- mem->mem_type,
- mem->mpll_mdiv,
- mem->frequency_mhz);
-
- ret = ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE);
- if (ret) {
- printk(BIOS_ERR, "Memory controller init failed, err: %x\n",
- ret);
- while(1);
+
+ if (actions & DO_WAKEUP) {
+ printk(BIOS_SPEW, "%s: Try to wake up.\n", __func__);
+ if (!wakeup_permitted())
+ power_reset();
+ power_exit_wakeup();
}
+ /* Initialize peripherals. */
initialize_s5p_mshc();
-
chromeos_gpios();
-
graphics();
+ clock_set_rate(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/coreboot_ram");
printk(BIOS_INFO, "entry is 0x%p, leaving romstage.\n", entry);
More information about the coreboot-gerrit
mailing list