blob: 8a5a1dd908a0a82a31fb4c5b6108f52729f413de [file] [log] [blame]
Gabe Blackd3163ab2013-05-16 05:53:40 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
5 *
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.
9 *
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.
14 *
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
18 */
19
20#include <types.h>
21
22#include <armv7.h>
23#include <cbfs.h>
24
25#include <arch/cache.h>
26#include <cpu/samsung/exynos5420/i2c.h>
27#include <cpu/samsung/exynos5420/clk.h>
28#include <cpu/samsung/exynos5420/cpu.h>
29#include <cpu/samsung/exynos5420/dmc.h>
30#include <cpu/samsung/exynos5420/gpio.h>
31#include <cpu/samsung/exynos5420/setup.h>
32#include <cpu/samsung/exynos5420/periph.h>
33#include <cpu/samsung/exynos5420/power.h>
34#include <cpu/samsung/exynos5420/wakeup.h>
35#include <console/console.h>
36#include <arch/stages.h>
37
38#include <drivers/maxim/max77686/max77686.h>
39#include <device/i2c.h>
40
41#include "exynos5420.h"
42
43#define PMIC_BUS 0
44#define MMC0_GPIO_PIN (58)
45
46static void setup_power(void)
47{
48 int error = 0;
49
50 power_init();
51
52 /* Initialize I2C bus to configure PMIC. */
Gabe Blacke6a44eb2013-06-15 23:40:26 -070053 exynos_pinmux_i2c0();
Gabe Blackd3163ab2013-05-16 05:53:40 -070054 i2c_init(0, I2C_0_SPEED, 0x00);
55
56 printk(BIOS_DEBUG, "%s: Setting up PMIC...\n", __func__);
57 /*
58 * We're using CR1616 coin cell battery that is non-rechargeable
59 * battery. But, BBCHOSTEN bit of the BBAT Charger Register in
60 * MAX77686 is enabled by default for charging coin cell.
61 *
62 * Also, we cannot meet the coin cell reverse current spec. in UL
63 * standard if BBCHOSTEN bit is enabled.
64 *
65 * Disable Coin BATT Charging
66 */
67 error = max77686_disable_backup_batt(PMIC_BUS);
68
69 error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK2, VDD_ARM_MV,
70 REG_ENABLE, MAX77686_MV);
71 error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK3, VDD_INT_UV,
72 REG_ENABLE, MAX77686_UV);
73 error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK1, VDD_MIF_MV,
74 REG_ENABLE, MAX77686_MV);
75 error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK4, VDD_G3D_MV,
76 REG_ENABLE, MAX77686_MV);
77 error |= max77686_volsetting(PMIC_BUS, PMIC_LDO2, VDD_LDO2_MV,
78 REG_ENABLE, MAX77686_MV);
79 error |= max77686_volsetting(PMIC_BUS, PMIC_LDO3, VDD_LDO3_MV,
80 REG_ENABLE, MAX77686_MV);
81 error |= max77686_volsetting(PMIC_BUS, PMIC_LDO5, VDD_LDO5_MV,
82 REG_ENABLE, MAX77686_MV);
83 error |= max77686_volsetting(PMIC_BUS, PMIC_LDO10, VDD_LDO10_MV,
84 REG_ENABLE, MAX77686_MV);
85
86 error |= max77686_enable_32khz_cp(PMIC_BUS);
87
88 if (error) {
89 printk(BIOS_CRIT, "%s: PMIC error: %#x\n", __func__, error);
90 die("Failed to intialize PMIC.\n");
91 }
92}
93
94static void setup_storage(void)
95{
96 /* MMC0: Fixed, 8 bit mode, connected with GPIO. */
97 if (clock_set_mshci(PERIPH_ID_SDMMC0))
98 printk(BIOS_CRIT, "%s: Failed to set MMC0 clock.\n", __func__);
99 if (gpio_direction_output(MMC0_GPIO_PIN, 1)) {
100 printk(BIOS_CRIT, "%s: Unable to power on MMC0.\n", __func__);
101 }
102 gpio_set_pull(MMC0_GPIO_PIN, GPIO_PULL_NONE);
103 gpio_set_drv(MMC0_GPIO_PIN, GPIO_DRV_4X);
Gabe Blacke6a44eb2013-06-15 23:40:26 -0700104 exynos_pinmux_sdmmc0();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700105
106 /* MMC2: Removable, 4 bit mode, no GPIO. */
107 clock_set_mshci(PERIPH_ID_SDMMC2);
Gabe Blacke6a44eb2013-06-15 23:40:26 -0700108 exynos_pinmux_sdmmc2();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700109}
110
111static void setup_graphics(void)
112{
Gabe Blacke6a44eb2013-06-15 23:40:26 -0700113 exynos_pinmux_dphpd();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700114}
115
116static void setup_gpio(void)
117{
118 gpio_direction_input(GPIO_D16); // WP_GPIO
119 gpio_set_pull(GPIO_D16, GPIO_PULL_NONE);
120
121 gpio_direction_input(GPIO_Y10); // RECMODE_GPIO
122 gpio_set_pull(GPIO_Y10, GPIO_PULL_NONE);
123
124 gpio_direction_input(GPIO_X35); // LID_GPIO
125 gpio_set_pull(GPIO_X35, GPIO_PULL_NONE);
126
127 gpio_direction_input(GPIO_X13); // POWER_GPIO
128 gpio_set_pull(GPIO_X13, GPIO_PULL_NONE);
129}
130
131static void setup_memory(struct mem_timings *mem, int is_resume)
132{
Stefan Reinauer998ab0d2013-05-20 12:29:37 -0700133 printk(BIOS_SPEW, "man: 0x%x type: 0x%x, div: 0x%x, mhz: %d\n",
Gabe Blackd3163ab2013-05-16 05:53:40 -0700134 mem->mem_manuf,
135 mem->mem_type,
136 mem->mpll_mdiv,
137 mem->frequency_mhz);
138
139 /* FIXME Currently memory initialization with mem_reset on normal boot
140 * will cause resume to fail (even if we don't do mem_reset on resume),
141 * and the workaround is to temporarily always enable "is_resume".
142 * This should be removed when the root cause of resume issue is found.
143 */
144 is_resume = 1;
145
146 if (ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE, !is_resume)) {
147 die("Failed to initialize memory controller.\n");
148 }
149}
150
151static struct mem_timings *setup_clock(void)
152{
153 struct mem_timings *mem = get_mem_timings();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700154 if (!mem) {
155 die("Unable to auto-detect memory timings\n");
156 }
Gabe Black5420e092013-05-17 11:29:22 -0700157
158 system_clock_init();
159
Gabe Blackd3163ab2013-05-16 05:53:40 -0700160 return mem;
161}
162
163void main(void)
164{
165 struct mem_timings *mem;
166 void *entry;
167 int is_resume = (get_wakeup_state() != IS_NOT_WAKEUP);
168
169 /* Clock must be initialized before console_init, otherwise you may need
170 * to re-initialize serial console drivers again. */
171 mem = setup_clock();
172
Stefan Reinauer998ab0d2013-05-20 12:29:37 -0700173 console_init();
174
Gabe Blackd3163ab2013-05-16 05:53:40 -0700175 if (!is_resume) {
Gabe Blackd3163ab2013-05-16 05:53:40 -0700176 setup_power();
177 }
178
179 setup_memory(mem, is_resume);
180
181 if (is_resume) {
182 wakeup();
183 }
184
185 setup_storage();
186 setup_gpio();
187 setup_graphics();
188
189 /* Set SPI (primary CBFS media) clock to 50MHz. */
190 clock_set_rate(PERIPH_ID_SPI1, 50000000);
191
192 entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/coreboot_ram");
193 stage_exit(entry);
194}