blob: 31b61e2d721b881a28baccea185a6bd46ae00ec2 [file] [log] [blame]
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007-2010 coresystems GmbH
5 * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
Patrick Georgib890a122015-03-26 15:17:45 +010018 * Foundation, Inc.
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -070019 */
20
21#include <stdint.h>
22#include <string.h>
23#include <lib.h>
24#include <timestamp.h>
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -070025#include <arch/io.h>
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -070026#include <device/pci_def.h>
27#include <device/pnp_def.h>
28#include <cpu/x86/lapic.h>
29#include <pc80/mc146818rtc.h>
Kyösti Mälkki6722f8d2014-06-16 09:14:49 +030030#include <arch/acpi.h>
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -070031#include <cbmem.h>
32#include <console/console.h>
Edward O'Callaghan77757c22015-01-04 21:33:39 +110033#include <northbridge/intel/sandybridge/sandybridge.h>
34#include <northbridge/intel/sandybridge/raminit.h>
35#include <southbridge/intel/bd82x6x/pch.h>
36#include <southbridge/intel/bd82x6x/gpio.h>
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -070037#include <arch/cpu.h>
38#include <cpu/x86/bist.h>
39#include <cpu/x86/msr.h>
Patrick Georgibd79c5e2014-11-28 22:35:36 +010040#include <halt.h>
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -070041#include "gpio.h"
Kyösti Mälkki926a8d12014-04-27 22:17:22 +030042#include <bootmode.h>
Vladimir Serbinenko0e90dae2015-05-18 10:29:06 +020043#include <tpm.h>
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -070044#include <cbfs.h>
45#include <ec/quanta/it8518/ec.h>
46#include "ec.h"
47#include "onboard.h"
48
49static void pch_enable_lpc(void)
50{
51 /*
52 * Enable:
53 * EC Decode Range Port62/66
54 * SuperIO Port2E/2F
55 * PS/2 Keyboard/Mouse Port60/64
56 * FDD Port3F0h-3F5h and Port3F7h
57 */
58 pci_write_config16(PCH_LPC_DEV, LPC_EN, KBC_LPC_EN | MC_LPC_EN |
59 CNF1_LPC_EN | FDD_LPC_EN);
60
61 /* Stout EC Decode Range Port68/6C */
62 pci_write_config32(PCH_LPC_DEV, LPC_GEN1_DEC, (0x68 | 0x40001));
63}
64
65static void rcba_config(void)
66{
67 u32 reg32;
68
Vladimir Serbinenko33b535f2014-10-19 10:13:14 +020069 southbridge_configure_default_intmap();
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -070070
71 /* Disable unused devices (board specific) */
72 reg32 = RCBA32(FD);
73 reg32 |= PCH_DISABLE_ALWAYS;
74 /* Disable PCI bridge so MRC does not probe this bus */
75 reg32 |= PCH_DISABLE_P2P;
76 RCBA32(FD) = reg32;
77}
78
79// FIXME, this function is generic code that should go to sb/... or
80// nb/../early_init.c
81static void early_pch_init(void)
82{
83 // Nothing to do for stout
84}
85
86 /*
87 * The Stout EC needs to be reset to RW mode. It is important that
88 * the RTC_PWR_STS is not set until ramstage EC init.
89 */
90static void early_ec_init(void)
91{
92 u8 ec_status = ec_read(EC_STATUS_REG);
Kyösti Mälkki926a8d12014-04-27 22:17:22 +030093 int rec_mode = IS_ENABLED(CONFIG_BOOTMODE_STRAPS) &&
94 get_recovery_mode_switch();
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -070095
96 if (((ec_status & 0x3) == EC_IN_RO_MODE) ||
97 ((ec_status & 0x3) == EC_IN_RECOVERY_MODE)) {
98
99 printk(BIOS_DEBUG, "EC Cold Boot Detected\n");
100 if (!rec_mode) {
101 /*
102 * Tell EC to exit RO mode
103 */
104 printk(BIOS_DEBUG, "EC will exit RO mode and boot normally\n");
105 ec_write_cmd(EC_CMD_EXIT_BOOT_BLOCK);
106 die("wait for ec to reset");
107 }
108 } else {
109 printk(BIOS_DEBUG, "EC Warm Boot Detected\n");
110 ec_write_cmd(EC_CMD_WARM_RESET);
111 }
112}
113
Aaron Durbina0a37272014-08-14 08:35:11 -0500114#include <cpu/intel/romstage.h>
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700115void main(unsigned long bist)
116{
117 int boot_mode = 0;
118 int cbmem_was_initted;
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700119
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700120 struct pei_data pei_data = {
Edward O'Callaghan77896c12014-10-28 10:03:47 +1100121 .pei_version = PEI_VERSION,
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800122 .mchbar = (uintptr_t)DEFAULT_MCHBAR,
123 .dmibar = (uintptr_t)DEFAULT_DMIBAR,
Edward O'Callaghan77896c12014-10-28 10:03:47 +1100124 .epbar = DEFAULT_EPBAR,
125 .pciexbar = CONFIG_MMCONF_BASE_ADDRESS,
126 .smbusbar = SMBUS_IO_BASE,
127 .wdbbar = 0x4000000,
128 .wdbsize = 0x1000,
129 .hpet_address = CONFIG_HPET_ADDRESS,
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800130 .rcba = (uintptr_t)DEFAULT_RCBABASE,
Edward O'Callaghan77896c12014-10-28 10:03:47 +1100131 .pmbase = DEFAULT_PMBASE,
132 .gpiobase = DEFAULT_GPIOBASE,
133 .thermalbase = 0xfed08000,
134 .system_type = 0, // 0 Mobile, 1 Desktop/Server
135 .tseg_size = CONFIG_SMM_TSEG_SIZE,
136 .spd_addresses = { 0xA0, 0x00,0xA4,0x00 },
137 .ts_addresses = { 0x00, 0x00, 0x00, 0x00 },
138 .ec_present = 1,
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700139 // 0 = leave channel enabled
140 // 1 = disable dimm 0 on channel
141 // 2 = disable dimm 1 on channel
142 // 3 = disable dimm 0+1 on channel
Edward O'Callaghan77896c12014-10-28 10:03:47 +1100143 .dimm_channel0_disabled = 2,
144 .dimm_channel1_disabled = 2,
145 .max_ddr3_freq = 1600,
146 .usb_port_config = {
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700147 /* enabled usb oc pin length */
148 { 1, 0, 0x0040 }, /* P0: USB 3.0 1 (OC0) */
149 { 1, 0, 0x0040 }, /* P1: USB 3.0 2 (OC0) */
150 { 0, 1, 0x0000 }, /* P2: Empty */
151 { 1, 1, 0x0040 }, /* P3: Camera (no OC) */
152 { 1, 1, 0x0040 }, /* P4: WLAN (no OC) */
153 { 1, 1, 0x0040 }, /* P5: WWAN (no OC) */
154 { 0, 1, 0x0000 }, /* P6: Empty */
155 { 0, 1, 0x0000 }, /* P7: Empty */
156 { 0, 5, 0x0000 }, /* P8: Empty */
157 { 1, 4, 0x0040 }, /* P9: USB 2.0 (AUO4) (OC4) */
158 { 0, 5, 0x0000 }, /* P10: Empty */
159 { 0, 5, 0x0000 }, /* P11: Empty */
160 { 0, 5, 0x0000 }, /* P12: Empty */
161 { 1, 5, 0x0040 }, /* P13: Bluetooth (no OC) */
162 },
Edward O'Callaghan77896c12014-10-28 10:03:47 +1100163 .usb3 = {
164 .mode = XHCI_MODE,
165 .hs_port_switch_mask = XHCI_PORTS,
166 .preboot_support = XHCI_PREBOOT,
167 .xhci_streams = XHCI_STREAMS,
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700168 },
169 };
170
Kyösti Mälkki3d45c402013-09-07 20:26:36 +0300171 timestamp_init(get_initial_timestamp());
172 timestamp_add_now(TS_START_ROMSTAGE);
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700173
174 if (bist == 0)
175 enable_lapic();
176
177 pch_enable_lpc();
178
179 /* Enable GPIOs */
180 pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE|1);
181 pci_write_config8(PCH_LPC_DEV, GPIO_CNTL, 0x10);
182 setup_pch_gpios(&stout_gpio_map);
183
184 /* Initialize console device(s) */
185 console_init();
186
187 /* Halt if there was a built in self test failure */
188 report_bist_failure(bist);
189
190 if (MCHBAR16(SSKPD) == 0xCAFE) {
191 printk(BIOS_DEBUG, "soft reset detected\n");
192 boot_mode = 1;
193
194 /* System is not happy after keyboard reset... */
195 printk(BIOS_DEBUG, "Issuing CF9 warm reset\n");
196 outb(0x6, 0xcf9);
Patrick Georgibd79c5e2014-11-28 22:35:36 +0100197 halt();
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700198 }
199
200
201 /* Perform some early chipset initialization required
202 * before RAM initialization can work
203 */
204 sandybridge_early_initialization(SANDYBRIDGE_MOBILE);
205 printk(BIOS_DEBUG, "Back from sandybridge_early_initialization()\n");
206
Vladimir Serbinenko332f14b2014-09-05 16:29:41 +0200207 boot_mode = southbridge_detect_s3_resume() ? 2 : 0;
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700208
209 /* Do ec reset as early as possible, but skip it on S3 resume */
210 if (boot_mode < 2)
211 early_ec_init();
212
213 post_code(0x38);
214 /* Enable SPD ROMs and DDR-III DRAM */
215 enable_smbus();
216
217 /* Prepare USB controller early in S3 resume */
218 if (boot_mode == 2)
219 enable_usb_bar();
220
221 post_code(0x39);
222
223 post_code(0x3a);
224 pei_data.boot_mode = boot_mode;
Kyösti Mälkki3d45c402013-09-07 20:26:36 +0300225 timestamp_add_now(TS_BEFORE_INITRAM);
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700226 sdram_initialize(&pei_data);
227
Kyösti Mälkki3d45c402013-09-07 20:26:36 +0300228 timestamp_add_now(TS_AFTER_INITRAM);
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700229 post_code(0x3b);
230 /* Perform some initialization that must run before stage2 */
231 early_pch_init();
232 post_code(0x3c);
233
234 rcba_config();
235 post_code(0x3d);
236
237 quick_ram_check();
238 post_code(0x3e);
239
Kyösti Mälkki2d8520b2014-01-06 17:20:31 +0200240 cbmem_was_initted = !cbmem_recovery(boot_mode==2);
Kyösti Mälkki78938482014-01-04 11:02:45 +0200241 if (boot_mode!=2)
242 save_mrc_data(&pei_data);
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700243
Vladimir Serbinenkoc845b432014-09-05 03:37:44 +0200244 if (boot_mode==2 && !cbmem_was_initted) {
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700245 /* Failed S3 resume, reset to come up cleanly */
246 outb(0x6, 0xcf9);
Patrick Georgibd79c5e2014-11-28 22:35:36 +0100247 halt();
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700248 }
Vladimir Serbinenkoc845b432014-09-05 03:37:44 +0200249 northbridge_romstage_finalize(boot_mode==2);
250
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700251 post_code(0x3f);
Vladimir Serbinenko0e90dae2015-05-18 10:29:06 +0200252 if (CONFIG_LPC_TPM) {
253 init_tpm(boot_mode == 2);
254 }
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700255 timestamp_add_now(TS_END_ROMSTAGE);
Stefan Reinauerb7ecf6d2013-03-13 17:13:32 -0700256}