blob: 3a1d65d8abb974ec3e5606f4b4536d68f5e066b7 [file] [log] [blame]
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google Inc.
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 <stddef.h>
21#include <arch/cpu.h>
22#include <arch/io.h>
23#include <arch/cbfs.h>
24#include <arch/stages.h>
Aaron Durbin00bf3db2014-01-09 10:33:23 -060025#include <arch/early_variables.h>
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -050026#include <console/console.h>
27#include <cbmem.h>
28#include <cpu/x86/mtrr.h>
Aaron Durbin3e0eea12013-10-28 11:20:35 -050029#if CONFIG_EC_GOOGLE_CHROMEEC
30#include <ec/google/chromeec/ec.h>
31#endif
Aaron Durbina8e9b632013-10-30 15:46:07 -050032#include <elog.h>
Aaron Durbindc249f62013-10-10 21:03:50 -050033#include <ramstage_cache.h>
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -050034#include <romstage_handoff.h>
Aaron Durbin794bddf2013-09-27 11:38:36 -050035#include <timestamp.h>
Aaron Durbinebf7ec52013-11-14 13:47:08 -060036#include <vendorcode/google/chromeos/chromeos.h>
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -050037#include <baytrail/gpio.h>
38#include <baytrail/iomap.h>
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -050039#include <baytrail/lpc.h>
40#include <baytrail/pci_devs.h>
Aaron Durbin6e328932013-11-06 12:04:50 -060041#include <baytrail/pmc.h>
Aaron Durbindc249f62013-10-10 21:03:50 -050042#include <baytrail/reset.h>
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -050043#include <baytrail/romstage.h>
Aaron Durbin7837be62013-10-21 22:32:00 -050044#include <baytrail/smm.h>
Aaron Durbin6f9947a2013-11-18 11:16:20 -060045#include <baytrail/spi.h>
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -050046
Aaron Durbin794bddf2013-09-27 11:38:36 -050047static inline uint64_t timestamp_get(void)
48{
49 return rdtscll();
50}
51
52static inline tsc_t ts64_to_tsc(uint64_t ts)
53{
54 tsc_t tsc = {
55 .lo = ts,
56 .hi = ts >> 32,
57 };
58 return tsc;
59}
60
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -050061/* The cache-as-ram assembly file calls romstage_main() after setting up
62 * cache-as-ram. romstage_main() will then call the mainboards's
63 * mainboard_romstage_entry() function. That function then calls
64 * romstage_common() below. The reason for the back and forth is to provide
65 * common entry point from cache-as-ram while still allowing for code sharing.
66 * Because we can't use global variables the stack is used for allocations --
67 * thus the need to call back and forth. */
68
69static void *setup_stack_and_mttrs(void);
70
71static void program_base_addresses(void)
72{
73 uint32_t reg;
74 const uint32_t lpc_dev = PCI_DEV(0, LPC_DEV, LPC_FUNC);
75
76 /* Memory Mapped IO registers. */
77 reg = PMC_BASE_ADDRESS | 2;
78 pci_write_config32(lpc_dev, PBASE, reg);
79 reg = IO_BASE_ADDRESS | 2;
80 pci_write_config32(lpc_dev, IOBASE, reg);
81 reg = ILB_BASE_ADDRESS | 2;
82 pci_write_config32(lpc_dev, IBASE, reg);
83 reg = SPI_BASE_ADDRESS | 2;
84 pci_write_config32(lpc_dev, SBASE, reg);
85 reg = MPHY_BASE_ADDRESS | 2;
86 pci_write_config32(lpc_dev, MPBASE, reg);
Aaron Durbina64ef622013-10-03 12:56:37 -050087 reg = PUNIT_BASE_ADDRESS | 2;
88 pci_write_config32(lpc_dev, PUBASE, reg);
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -050089 reg = RCBA_BASE_ADDRESS | 1;
90 pci_write_config32(lpc_dev, RCBA, reg);
91
92 /* IO Port Registers. */
93 reg = ACPI_BASE_ADDRESS | 2;
94 pci_write_config32(lpc_dev, ABASE, reg);
95 reg = GPIO_BASE_ADDRESS | 2;
96 pci_write_config32(lpc_dev, GBASE, reg);
97}
98
Aaron Durbin6f9947a2013-11-18 11:16:20 -060099static void spi_init(void)
100{
101 const unsigned long bcr = SPI_BASE_ADDRESS + BCR;
102 /* Enable caching and prefetching in the SPI controller. */
103 write32(bcr, (read32(bcr) & ~SRC_MASK) | SRC_CACHE_PREFETCH);
104}
105
Aaron Durbin794bddf2013-09-27 11:38:36 -0500106static inline void mark_ts(struct romstage_params *rp, uint64_t ts)
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500107{
Aaron Durbin794bddf2013-09-27 11:38:36 -0500108 struct romstage_timestamps *rt = &rp->ts;
109
110 rt->times[rt->count] = ts;
111 rt->count++;
112}
113
114/* Entry from cache-as-ram.inc. */
115void * asmlinkage romstage_main(unsigned long bist,
116 uint32_t tsc_low, uint32_t tsc_hi)
117{
118 struct romstage_params rp = {
119 .bist = bist,
120 .mrc_params = NULL,
121 };
122
123 /* Save initial timestamp from bootblock. */
124 mark_ts(&rp, (((uint64_t)tsc_hi) << 32) | (uint64_t)tsc_low);
125 /* Save romstage begin */
126 mark_ts(&rp, timestamp_get());
127
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500128 program_base_addresses();
129
Aaron Durbinfd039f72013-10-04 11:11:52 -0500130 tco_disable();
131
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500132 byt_config_com1_and_enable();
133
134 console_init();
135
Aaron Durbin6f9947a2013-11-18 11:16:20 -0600136 spi_init();
137
Aaron Durbinbb3ee832013-10-07 17:12:20 -0500138 set_max_freq();
139
Aaron Durbin189aa3e2013-10-04 11:17:45 -0500140 punit_init();
141
Aaron Durbinecf90862013-09-24 12:36:14 -0500142 gfx_init();
143
Aaron Durbin3e0eea12013-10-28 11:20:35 -0500144#if CONFIG_EC_GOOGLE_CHROMEEC
145 /* Ensure the EC is in the right mode for recovery */
146 google_chromeec_early_init();
147#endif
148
Aaron Durbin5f8ad562013-10-08 16:54:18 -0500149 /* Call into mainboard. */
150 mainboard_romstage_entry(&rp);
151
152 return setup_stack_and_mttrs();
153}
154
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600155static struct chipset_power_state power_state CAR_GLOBAL;
156
157static void migrate_power_state(void)
Aaron Durbin6e328932013-11-06 12:04:50 -0600158{
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600159 struct chipset_power_state *ps_cbmem;
160 struct chipset_power_state *ps_car;
161
162 ps_car = car_get_var_ptr(&power_state);
163 ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem));
164
165 if (ps_cbmem == NULL) {
166 printk(BIOS_DEBUG, "Not adding power state to cbmem!\n");
167 return;
168 }
169 memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem));
170}
171CAR_MIGRATE(migrate_power_state);
172
173static struct chipset_power_state *fill_power_state(void)
174{
175 struct chipset_power_state *ps = car_get_var_ptr(&power_state);
176
177 ps->pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
178 ps->pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN);
179 ps->pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
180 ps->gpe0_sts = inl(ACPI_BASE_ADDRESS + GPE0_STS);
181 ps->gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN);
182 ps->tco_sts = inl(ACPI_BASE_ADDRESS + TCO_STS);
183 ps->prsts = read32(PMC_BASE_ADDRESS + PRSTS);
184 ps->gen_pmcon1 = read32(PMC_BASE_ADDRESS + GEN_PMCON1);
185 ps->gen_pmcon2 = read32(PMC_BASE_ADDRESS + GEN_PMCON2);
186
187 printk(BIOS_DEBUG, "pm1_sts: %04x pm1_en: %04x pm1_cnt: %08x\n",
188 ps->pm1_sts, ps->pm1_en, ps->pm1_cnt);
189 printk(BIOS_DEBUG, "gpe0_sts: %08x gpe0_en: %08x tco_sts: %08x\n",
190 ps->gpe0_sts, ps->gpe0_en, ps->tco_sts);
191 printk(BIOS_DEBUG, "prsts: %08x gen_pmcon1: %08x gen_pmcon2: %08x\n",
192 ps->prsts, ps->gen_pmcon1, ps->gen_pmcon2);
193
194 return ps;
195}
196
197/* Return 0, 3, or 5 to indicate the previous sleep state. */
198static int chipset_prev_sleep_state(struct chipset_power_state *ps)
199{
Aaron Durbin6e328932013-11-06 12:04:50 -0600200 /* Default to S0. */
201 int prev_sleep_state = 0;
202
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600203 if (ps->pm1_sts & WAK_STS) {
204 switch ((ps->pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT) {
Aaron Durbin6e328932013-11-06 12:04:50 -0600205 #if CONFIG_HAVE_ACPI_RESUME
206 case SLP_TYP_S3:
207 prev_sleep_state = 3;
208 break;
209 #endif
210 case SLP_TYP_S5:
211 prev_sleep_state = 5;
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600212 break;
Aaron Durbin6e328932013-11-06 12:04:50 -0600213 }
214 /* Clear SLP_TYP. */
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600215 outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT);
Aaron Durbin6e328932013-11-06 12:04:50 -0600216 }
217
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600218 if (ps->gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR)) {
Aaron Durbin6e328932013-11-06 12:04:50 -0600219 prev_sleep_state = 5;
220 }
221
Aaron Durbin6e328932013-11-06 12:04:50 -0600222 return prev_sleep_state;
223}
224
Aaron Durbinebf7ec52013-11-14 13:47:08 -0600225static inline void chromeos_init(int prev_sleep_state)
226{
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600227#if CONFIG_CHROMEOS
Aaron Durbinebf7ec52013-11-14 13:47:08 -0600228 /* Normalize the sleep state to what init_chromeos() wants for S3: 2. */
229 init_chromeos(prev_sleep_state == 3 ? 2 : 0);
Aaron Durbinebf7ec52013-11-14 13:47:08 -0600230#endif
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600231}
Aaron Durbinebf7ec52013-11-14 13:47:08 -0600232
Aaron Durbin5f8ad562013-10-08 16:54:18 -0500233/* Entry from the mainboard. */
234void romstage_common(struct romstage_params *params)
235{
236 struct romstage_handoff *handoff;
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600237 struct chipset_power_state *ps;
Aaron Durbin6e328932013-11-06 12:04:50 -0600238 int prev_sleep_state;
Aaron Durbin5f8ad562013-10-08 16:54:18 -0500239
Aaron Durbin794bddf2013-09-27 11:38:36 -0500240 mark_ts(params, timestamp_get());
241
Aaron Durbina8e9b632013-10-30 15:46:07 -0500242#if CONFIG_ELOG_BOOT_COUNT
243 boot_count_increment();
244#endif
245
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600246 ps = fill_power_state();
247 prev_sleep_state = chipset_prev_sleep_state(ps);
Aaron Durbin6e328932013-11-06 12:04:50 -0600248
249 printk(BIOS_DEBUG, "prev_sleep_state = S%d\n", prev_sleep_state);
250
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500251 /* Initialize RAM */
Aaron Durbin6e328932013-11-06 12:04:50 -0600252 raminit(params->mrc_params, prev_sleep_state);
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500253
Aaron Durbin794bddf2013-09-27 11:38:36 -0500254 mark_ts(params, timestamp_get());
255
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500256 handoff = romstage_handoff_find_or_add();
257 if (handoff != NULL)
Aaron Durbin6e328932013-11-06 12:04:50 -0600258 handoff->s3_resume = (prev_sleep_state == 3);
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500259 else
260 printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");
261
Aaron Durbinebf7ec52013-11-14 13:47:08 -0600262 chromeos_init(prev_sleep_state);
263
Aaron Durbin794bddf2013-09-27 11:38:36 -0500264 /* Save timestamp information. */
265 timestamp_init(ts64_to_tsc(params->ts.times[0]));
266 timestamp_add(TS_START_ROMSTAGE, ts64_to_tsc(params->ts.times[1]));
267 timestamp_add(TS_BEFORE_INITRAM, ts64_to_tsc(params->ts.times[2]));
268 timestamp_add(TS_AFTER_INITRAM, ts64_to_tsc(params->ts.times[3]));
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500269}
270
271static void open_up_spi(void)
272{
273 const uintptr_t sbase = SPI_BASE_ADDRESS;
274
275 /* Disable generating SMI when setting WPD bit. */
276 write32(sbase + 0xf8, read32(sbase + 0xf8) & ~(1 << 7));
277 /* Disable the SMM-only BIOS write and set WPD bit. */
278 write32(sbase + 0xfc, 1 | (read32(sbase + 0xfc) & ~(1 << 5)));
279}
280
281void asmlinkage romstage_after_car(void)
282{
283 /* Allow BIOS to program SPI part. */
284 open_up_spi();
285
Aaron Durbin794bddf2013-09-27 11:38:36 -0500286 timestamp_add_now(TS_END_ROMSTAGE);
287
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500288 /* Load the ramstage. */
289 copy_and_run();
290 while (1);
291}
292
293static inline uint32_t *stack_push(u32 *stack, u32 value)
294{
295 stack = &stack[-1];
296 *stack = value;
297 return stack;
298}
299
300/* Romstage needs quite a bit of stack for decompressing images since the lzma
301 * lib keeps its state on the stack during romstage. */
302static unsigned long choose_top_of_stack(void)
303{
304 unsigned long stack_top;
305 const unsigned long romstage_ram_stack_size = 0x5000;
306
307 /* cbmem_add() does a find() before add(). */
308 stack_top = (unsigned long)cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK,
309 romstage_ram_stack_size);
310 stack_top += romstage_ram_stack_size;
311 return stack_top;
312}
313
314/* setup_stack_and_mttrs() determines the stack to use after
315 * cache-as-ram is torn down as well as the MTRR settings to use. */
316static void *setup_stack_and_mttrs(void)
317{
318 unsigned long top_of_stack;
319 int num_mtrrs;
320 uint32_t *slot;
321 uint32_t mtrr_mask_upper;
322 uint32_t top_of_ram;
323
324 /* Top of stack needs to be aligned to a 4-byte boundary. */
325 top_of_stack = choose_top_of_stack() & ~3;
326 slot = (void *)top_of_stack;
327 num_mtrrs = 0;
328
329 /* The upper bits of the MTRR mask need to set according to the number
330 * of physical address bits. */
331 mtrr_mask_upper = (1 << ((cpuid_eax(0x80000008) & 0xff) - 32)) - 1;
332
333 /* The order for each MTRR is value then base with upper 32-bits of
334 * each value coming before the lower 32-bits. The reasoning for
335 * this ordering is to create a stack layout like the following:
336 * +0: Number of MTRRs
337 * +4: MTRR base 0 31:0
338 * +8: MTRR base 0 63:32
339 * +12: MTRR mask 0 31:0
340 * +16: MTRR mask 0 63:32
341 * +20: MTRR base 1 31:0
342 * +24: MTRR base 1 63:32
343 * +28: MTRR mask 1 31:0
344 * +32: MTRR mask 1 63:32
345 */
346
347 /* Cache the ROM as WP just below 4GiB. */
348 slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
349 slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRRphysMaskValid);
350 slot = stack_push(slot, 0); /* upper base */
351 slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_TYPE_WRPROT);
352 num_mtrrs++;
353
354 /* Cache RAM as WB from 0 -> CONFIG_RAMTOP. */
355 slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
356 slot = stack_push(slot, ~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid);
357 slot = stack_push(slot, 0); /* upper base */
358 slot = stack_push(slot, 0 | MTRR_TYPE_WRBACK);
359 num_mtrrs++;
360
361 top_of_ram = (uint32_t)cbmem_top();
362 /* Cache 8MiB below the top of ram. The top of ram under 4GiB is the
363 * start of the TSEG region. It is required to be 8MiB aligned. Set
364 * this area as cacheable so it can be used later for ramstage before
365 * setting up the entire RAM as cacheable. */
366 slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
367 slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid);
368 slot = stack_push(slot, 0); /* upper base */
369 slot = stack_push(slot, (top_of_ram - (8 << 20)) | MTRR_TYPE_WRBACK);
370 num_mtrrs++;
371
372 /* Cache 8MiB at the top of ram. Top of ram is where the TSEG
373 * region resides. However, it is not restricted to SMM mode until
374 * SMM has been relocated. By setting the region to cacheable it
375 * provides faster access when relocating the SMM handler as well
376 * as using the TSEG region for other purposes. */
377 slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
378 slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid);
379 slot = stack_push(slot, 0); /* upper base */
380 slot = stack_push(slot, top_of_ram | MTRR_TYPE_WRBACK);
381 num_mtrrs++;
382
383 /* Save the number of MTRRs to setup. Return the stack location
384 * pointing to the number of MTRRs. */
385 slot = stack_push(slot, num_mtrrs);
386
387 return slot;
388}
Aaron Durbindc249f62013-10-10 21:03:50 -0500389
Aaron Durbindc249f62013-10-10 21:03:50 -0500390void ramstage_cache_invalid(struct ramstage_cache *cache)
391{
392#if CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE
393 /* Perform cold reset on invalid ramstage cache. */
394 cold_reset();
395#endif
396}