blob: 1ff8d51de20de5ad390fbd0fa73a3712bbc45cb6 [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{
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700133 printk(BIOS_SPEW, "manufacturer: 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
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700151#define PRIMITIVE_MEM_TEST 0
152#if PRIMITIVE_MEM_TEST
153static unsigned long primitive_mem_test(void)
Gabe Blackd3163ab2013-05-16 05:53:40 -0700154{
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700155 unsigned long *l = (void *)0x40000000;
156 int bad = 0;
157 unsigned long i;
158 for(i = 0; i < 256*1048576; i++){
159 if (! (i%1048576))
160 printk(BIOS_SPEW, "%lu ...", i);
161 l[i] = 0xffffffff - i;
Gabe Blackd3163ab2013-05-16 05:53:40 -0700162 }
Gabe Black5420e092013-05-17 11:29:22 -0700163
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700164 for(i = 0; i < 256*1048576; i++){
165 if (! (i%1048576))
166 printk(BIOS_SPEW, "%lu ...", i);
167 if (l[i] != (0xffffffff - i)){
168 printk(BIOS_SPEW, "%p: want %08lx got %08lx\n", l, l[i], 0xffffffff - i);
169 bad++;
170 }
171 }
Gabe Black5420e092013-05-17 11:29:22 -0700172
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700173 printk(BIOS_SPEW, "%d errors\n", bad);
174
175 return bad;
Gabe Blackd3163ab2013-05-16 05:53:40 -0700176}
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700177#else
178#define primitive_mem_test()
179#endif
180
181#define SIMPLE_SPI_TEST 0
182#if SIMPLE_SPI_TEST
183/* here is a simple SPI debug test, known to fid trouble */
184static void simple_spi_test(void)
185{
186 struct cbfs_media default_media, *media;
187 int i, amt = 4 * MiB, errors = 0;
188 //u32 *data = (void *)0x40000000;
189 u32 data[1024];
190 u32 in;
191
192 amt = sizeof(data);
193 media = &default_media;
194 if (init_default_cbfs_media(media) != 0) {
195 printk(BIOS_SPEW, "Failed to initialize default media.\n");
196 return;
197 }
198
199
200 media->open(media);
201 if (media->read(media, data, (size_t) 0, amt) < amt){
202 printk(BIOS_SPEW, "simple_spi_test fails\n");
203 return;
204 }
205
206
207 for(i = 0; i < amt; i += 4){
208 if (media->read(media, &in, (size_t) i, 4) < 1){
209 printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
210 return;
211 }
212 if (data[i/4] != in){
213 errors++;
214 printk(BIOS_SPEW, "BAD at %d(%p):\nRAM %08lx\nSPI %08lx\n",
215 i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
216 /* reread it to see which is wrong. */
217 if (media->read(media, &in, (size_t) i, 4) < 1){
218 printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
219 return;
220 }
221 printk(BIOS_SPEW, "RTRY at %d(%p):\nRAM %08lx\nSPI %08lx\n",
222 i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
223 }
224
225 }
226 printk(BIOS_SPEW, "%d errors\n", errors);
227}
228#else
229#define simple_spi_test()
230#endif
Gabe Blackd3163ab2013-05-16 05:53:40 -0700231
232void main(void)
233{
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700234
235 extern struct mem_timings mem_timings;
Gabe Blackd3163ab2013-05-16 05:53:40 -0700236 void *entry;
237 int is_resume = (get_wakeup_state() != IS_NOT_WAKEUP);
238
239 /* Clock must be initialized before console_init, otherwise you may need
240 * to re-initialize serial console drivers again. */
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700241 system_clock_init();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700242
Stefan Reinauer998ab0d2013-05-20 12:29:37 -0700243 console_init();
244
Gabe Blackd3163ab2013-05-16 05:53:40 -0700245 if (!is_resume) {
Gabe Blackd3163ab2013-05-16 05:53:40 -0700246 setup_power();
247 }
248
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700249 setup_memory(&mem_timings, is_resume);
250
251 primitive_mem_test();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700252
253 if (is_resume) {
254 wakeup();
255 }
256
257 setup_storage();
258 setup_gpio();
259 setup_graphics();
260
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700261 simple_spi_test();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700262 /* Set SPI (primary CBFS media) clock to 50MHz. */
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700263 /* if this is uncommented SPI will not work correctly. */
Gabe Blackd3163ab2013-05-16 05:53:40 -0700264 clock_set_rate(PERIPH_ID_SPI1, 50000000);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700265 simple_spi_test();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700266 entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/coreboot_ram");
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700267 simple_spi_test();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700268 stage_exit(entry);
269}