google/snow: Revise romstage initialization code.
[coreboot.git] / src / mainboard / google / snow / romstage.c
blobfd5cfcec4c2a8fd0da89dd6dbf2a100713f735be
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <types.h>
22 #include <armv7.h>
23 #include <cbfs.h>
24 #include <common.h>
26 #include <arch/cache.h>
27 #include <arch/gpio.h>
28 #include <cpu/samsung/exynos5-common/i2c.h>
29 #include <cpu/samsung/exynos5250/clk.h>
30 #include <cpu/samsung/exynos5250/cpu.h>
31 #include <cpu/samsung/exynos5250/dmc.h>
32 #include <cpu/samsung/exynos5250/gpio.h>
33 #include <cpu/samsung/exynos5250/setup.h>
34 #include <cpu/samsung/exynos5250/periph.h>
35 #include <cpu/samsung/exynos5250/power.h>
36 #include <cpu/samsung/exynos5250/clock_init.h>
37 #include <console/console.h>
38 #include <arch/stages.h>
39 #include <time.h>
41 #include <drivers/maxim/max77686/max77686.h>
42 #include <device/i2c.h>
44 #include "mainboard.h"
46 #define PMIC_BUS 0
47 #define MMC0_GPIO_PIN (58)
49 static void snow_setup_power(void)
51 int error = 0;
53 power_init();
55 /* Initialize I2C bus to configure PMIC. */
56 i2c_init(0, CONFIG_SYS_I2C_SPEED, 0x00);
58 printk(BIOS_DEBUG, "%s: Setting up PMIC...\n", __func__);
60 * We're using CR1616 coin cell battery that is non-rechargeable
61 * battery. But, BBCHOSTEN bit of the BBAT Charger Register in
62 * MAX77686 is enabled by default for charging coin cell.
64 * Also, we cannot meet the coin cell reverse current spec. in UL
65 * standard if BBCHOSTEN bit is enabled.
67 * Disable Coin BATT Charging
69 error = max77686_disable_backup_batt(PMIC_BUS);
71 error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK2, CONFIG_VDD_ARM_MV,
72 REG_ENABLE, MAX77686_MV);
73 error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK3, CONFIG_VDD_INT_UV,
74 REG_ENABLE, MAX77686_UV);
75 error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK1, CONFIG_VDD_MIF_MV,
76 REG_ENABLE, MAX77686_MV);
77 error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK4, CONFIG_VDD_G3D_MV,
78 REG_ENABLE, MAX77686_MV);
79 error |= max77686_volsetting(PMIC_BUS, PMIC_LDO2, CONFIG_VDD_LDO2_MV,
80 REG_ENABLE, MAX77686_MV);
81 error |= max77686_volsetting(PMIC_BUS, PMIC_LDO3, CONFIG_VDD_LDO3_MV,
82 REG_ENABLE, MAX77686_MV);
83 error |= max77686_volsetting(PMIC_BUS, PMIC_LDO5, CONFIG_VDD_LDO5_MV,
84 REG_ENABLE, MAX77686_MV);
85 error |= max77686_volsetting(PMIC_BUS, PMIC_LDO10, CONFIG_VDD_LDO10_MV,
86 REG_ENABLE, MAX77686_MV);
88 error |= max77686_enable_32khz_cp(PMIC_BUS);
90 if (error) {
91 printk(BIOS_CRIT, "%s: PMIC error: %#x\n", __func__, error);
92 die("Failed to intialize PMIC.\n");
96 static void snow_setup_storage(void)
98 /* MMC0: Fixed, 8 bit mode, connected with GPIO. */
99 if (clock_set_mshci(PERIPH_ID_SDMMC0))
100 printk(BIOS_CRIT, "%s: Failed to set MMC0 clock.\n", __func__);
101 if (gpio_direction_output(MMC0_GPIO_PIN, 1)) {
102 printk(BIOS_CRIT, "%s: Unable to power on MMC0.\n", __func__);
104 gpio_set_pull(MMC0_GPIO_PIN, EXYNOS_GPIO_PULL_NONE);
105 gpio_set_drv(MMC0_GPIO_PIN, EXYNOS_GPIO_DRV_4X);
106 exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE);
108 /* MMC2: Removable, 4 bit mode, no GPIO. */
109 clock_set_mshci(PERIPH_ID_SDMMC2);
110 exynos_pinmux_config(PERIPH_ID_SDMMC2, 0);
113 static void snow_setup_graphics(void)
115 exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
118 static void snow_setup_gpio(void)
120 struct exynos5_gpio_part1 *gpio_pt1;
121 struct exynos5_gpio_part2 *gpio_pt2;
123 enum {
124 WP_GPIO = 6,
125 RECMODE_GPIO = 0,
126 LID_GPIO = 5,
127 POWER_GPIO = 3
130 gpio_pt1 = (struct exynos5_gpio_part1 *)EXYNOS5_GPIO_PART1_BASE;
131 gpio_pt2 = (struct exynos5_gpio_part2 *)EXYNOS5_GPIO_PART2_BASE;
133 s5p_gpio_direction_input(&gpio_pt1->d1, WP_GPIO);
134 s5p_gpio_set_pull(&gpio_pt1->d1, WP_GPIO, EXYNOS_GPIO_PULL_NONE);
136 s5p_gpio_direction_input(&gpio_pt1->y1, RECMODE_GPIO);
137 s5p_gpio_set_pull(&gpio_pt1->y1, RECMODE_GPIO, EXYNOS_GPIO_PULL_NONE);
139 s5p_gpio_direction_input(&gpio_pt2->x3, LID_GPIO);
140 s5p_gpio_set_pull(&gpio_pt2->x3, LID_GPIO, EXYNOS_GPIO_PULL_NONE);
142 s5p_gpio_direction_input(&gpio_pt2->x1, POWER_GPIO);
143 s5p_gpio_set_pull(&gpio_pt2->x1, POWER_GPIO, EXYNOS_GPIO_PULL_NONE);
146 static void snow_setup_memory(struct mem_timings *mem, int is_resume)
148 printk(BIOS_SPEW, "man: 0x%x type: 0x%x, div: 0x%x, mhz: 0x%x\n",
149 mem->mem_manuf,
150 mem->mem_type,
151 mem->mpll_mdiv,
152 mem->frequency_mhz);
153 if (ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE, !is_resume)) {
154 die("Failed to initialize memory controller.\n");
158 static struct mem_timings *snow_setup_clock(void)
160 struct mem_timings *mem = get_mem_timings();
161 struct arm_clk_ratios *arm_ratios = get_arm_clk_ratios();
162 if (!mem) {
163 die("Unable to auto-detect memory timings\n");
165 system_clock_init(mem, arm_ratios);
166 return mem;
169 void main(void)
171 struct mem_timings *mem;
172 void *entry;
174 /* Clock must be initialized before console_init, otherwise you may need
175 * to re-initialize serial console drivers again. */
176 mem = snow_setup_clock();
178 console_init();
179 snow_setup_power();
181 snow_setup_memory(mem, 0);
183 snow_setup_storage();
184 snow_setup_gpio();
185 snow_setup_graphics();
187 /* Set SPI (primary CBFS media) clock to 50MHz. */
188 clock_set_rate(PERIPH_ID_SPI1, 50000000);
189 entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/coreboot_ram");
190 printk(BIOS_INFO, "entry is 0x%p, leaving romstage.\n", entry);
192 stage_exit(entry);