blob: d5be2f587fb942eedcc65e6e8e2b2330af2f710f [file] [log] [blame]
Simon Glass0b36ecd2014-11-12 22:42:07 -07001/*
2 * Copyright (c) 2014 Google, Inc
3 * (C) Copyright 2008
4 * Graeme Russ, graeme.russ@gmail.com.
5 *
6 * Some portions from coreboot src/mainboard/google/link/romstage.c
Simon Glass30580fc2014-11-12 22:42:23 -07007 * and src/cpu/intel/model_206ax/bootblock.c
Simon Glass0b36ecd2014-11-12 22:42:07 -07008 * Copyright (C) 2007-2010 coresystems GmbH
9 * Copyright (C) 2011 Google Inc.
10 *
11 * SPDX-License-Identifier: GPL-2.0
12 */
13
14#include <common.h>
Simon Glassdcfac352014-11-12 22:42:15 -070015#include <errno.h>
16#include <fdtdec.h>
Simon Glass0b36ecd2014-11-12 22:42:07 -070017#include <asm/cpu.h>
Simon Glassf226c412014-11-12 22:42:19 -070018#include <asm/io.h>
19#include <asm/msr.h>
20#include <asm/mtrr.h>
Simon Glass3274ae02014-11-12 22:42:13 -070021#include <asm/pci.h>
Simon Glass98f139b2014-11-12 22:42:10 -070022#include <asm/post.h>
Simon Glass0b36ecd2014-11-12 22:42:07 -070023#include <asm/processor.h>
Simon Glassf226c412014-11-12 22:42:19 -070024#include <asm/arch/model_206ax.h>
Simon Glassf79d5382014-11-12 22:42:21 -070025#include <asm/arch/microcode.h>
Simon Glassdcfac352014-11-12 22:42:15 -070026#include <asm/arch/pch.h>
Simon Glass30580fc2014-11-12 22:42:23 -070027#include <asm/arch/sandybridge.h>
Simon Glass0b36ecd2014-11-12 22:42:07 -070028
29DECLARE_GLOBAL_DATA_PTR;
30
Simon Glassf226c412014-11-12 22:42:19 -070031static void enable_port80_on_lpc(struct pci_controller *hose, pci_dev_t dev)
32{
33 /* Enable port 80 POST on LPC */
34 pci_hose_write_config_dword(hose, dev, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
35 clrbits_le32(RCB_REG(GCS), 4);
36}
37
38/*
39 * Enable Prefetching and Caching.
40 */
41static void enable_spi_prefetch(struct pci_controller *hose, pci_dev_t dev)
42{
43 u8 reg8;
44
45 pci_hose_read_config_byte(hose, dev, 0xdc, &reg8);
46 reg8 &= ~(3 << 2);
47 reg8 |= (2 << 2); /* Prefetching and Caching Enabled */
48 pci_hose_write_config_byte(hose, dev, 0xdc, reg8);
49}
50
51static void set_var_mtrr(
52 unsigned reg, unsigned base, unsigned size, unsigned type)
53
54{
55 /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
56 /* FIXME: It only support 4G less range */
57 wrmsr(MTRRphysBase_MSR(reg), base | type, 0);
58 wrmsr(MTRRphysMask_MSR(reg), ~(size - 1) | MTRRphysMaskValid,
59 (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1);
60}
61
62static void enable_rom_caching(void)
63{
64 disable_caches();
65 set_var_mtrr(1, 0xffc00000, 4 << 20, MTRR_TYPE_WRPROT);
66 enable_caches();
67
68 /* Enable Variable MTRRs */
69 wrmsr(MTRRdefType_MSR, 0x800, 0);
70}
71
72static int set_flex_ratio_to_tdp_nominal(void)
73{
74 msr_t flex_ratio, msr;
75 u8 nominal_ratio;
76
77 /* Minimum CPU revision for configurable TDP support */
78 if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID)
79 return -EINVAL;
80
81 /* Check for Flex Ratio support */
82 flex_ratio = msr_read(MSR_FLEX_RATIO);
83 if (!(flex_ratio.lo & FLEX_RATIO_EN))
84 return -EINVAL;
85
86 /* Check for >0 configurable TDPs */
87 msr = msr_read(MSR_PLATFORM_INFO);
88 if (((msr.hi >> 1) & 3) == 0)
89 return -EINVAL;
90
91 /* Use nominal TDP ratio for flex ratio */
92 msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
93 nominal_ratio = msr.lo & 0xff;
94
95 /* See if flex ratio is already set to nominal TDP ratio */
96 if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
97 return 0;
98
99 /* Set flex ratio to nominal TDP ratio */
100 flex_ratio.lo &= ~0xff00;
101 flex_ratio.lo |= nominal_ratio << 8;
102 flex_ratio.lo |= FLEX_RATIO_LOCK;
103 msr_write(MSR_FLEX_RATIO, flex_ratio);
104
105 /* Set flex ratio in soft reset data register bits 11:6 */
106 clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6,
107 (nominal_ratio & 0x3f) << 6);
108
109 /* Set soft reset control to use register value */
110 setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1);
111
112 /* Issue warm reset, will be "CPU only" due to soft reset data */
113 outb(0x0, PORT_RESET);
114 outb(0x6, PORT_RESET);
115 cpu_hlt();
116
117 /* Not reached */
118 return -EINVAL;
119}
120
121static void set_spi_speed(void)
122{
123 u32 fdod;
124
125 /* Observe SPI Descriptor Component Section 0 */
126 writel(0x1000, RCB_REG(SPI_DESC_COMP0));
127
128 /* Extract the1 Write/Erase SPI Frequency from descriptor */
129 fdod = readl(RCB_REG(SPI_FREQ_WR_ERA));
130 fdod >>= 24;
131 fdod &= 7;
132
133 /* Set Software Sequence frequency to match */
134 clrsetbits_8(RCB_REG(SPI_FREQ_SWSEQ), 7, fdod);
135}
136
Simon Glass0b36ecd2014-11-12 22:42:07 -0700137int arch_cpu_init(void)
138{
Simon Glassdcfac352014-11-12 22:42:15 -0700139 const void *blob = gd->fdt_blob;
Simon Glass3274ae02014-11-12 22:42:13 -0700140 struct pci_controller *hose;
Simon Glassdcfac352014-11-12 22:42:15 -0700141 int node;
Simon Glass0b36ecd2014-11-12 22:42:07 -0700142 int ret;
143
Simon Glass98f139b2014-11-12 22:42:10 -0700144 post_code(POST_CPU_INIT);
Simon Glass0b36ecd2014-11-12 22:42:07 -0700145 timer_set_base(rdtsc());
146
147 ret = x86_cpu_init_f();
148 if (ret)
149 return ret;
150
Simon Glass3274ae02014-11-12 22:42:13 -0700151 ret = pci_early_init_hose(&hose);
152 if (ret)
153 return ret;
154
Simon Glassdcfac352014-11-12 22:42:15 -0700155 node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_LPC);
156 if (node < 0)
157 return -ENOENT;
158 ret = lpc_early_init(gd->fdt_blob, node, PCH_LPC_DEV);
159 if (ret)
160 return ret;
161
Simon Glassf226c412014-11-12 22:42:19 -0700162 enable_spi_prefetch(hose, PCH_LPC_DEV);
163
164 /* This is already done in start.S, but let's do it in C */
165 enable_port80_on_lpc(hose, PCH_LPC_DEV);
166
167 /* already done in car.S */
168 if (false)
169 enable_rom_caching();
170
171 set_spi_speed();
172
173 /*
174 * We should do as little as possible before the serial console is
175 * up. Perhaps this should move to later. Our next lot of init
176 * happens in print_cpuinfo() when we have a console
177 */
178 ret = set_flex_ratio_to_tdp_nominal();
179 if (ret)
180 return ret;
181
Simon Glass0b36ecd2014-11-12 22:42:07 -0700182 return 0;
183}
184
Simon Glass30580fc2014-11-12 22:42:23 -0700185static int enable_smbus(void)
186{
187 pci_dev_t dev;
188 uint16_t value;
189
190 /* Set the SMBus device statically. */
191 dev = PCI_BDF(0x0, 0x1f, 0x3);
192
193 /* Check to make sure we've got the right device. */
194 value = pci_read_config16(dev, 0x0);
195 if (value != 0x8086) {
196 printf("SMBus controller not found\n");
197 return -ENOSYS;
198 }
199
200 /* Set SMBus I/O base. */
201 pci_write_config32(dev, SMB_BASE,
202 SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
203
204 /* Set SMBus enable. */
205 pci_write_config8(dev, HOSTC, HST_EN);
206
207 /* Set SMBus I/O space enable. */
208 pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
209
210 /* Disable interrupt generation. */
211 outb(0, SMBUS_IO_BASE + SMBHSTCTL);
212
213 /* Clear any lingering errors, so transactions can run. */
214 outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
215 debug("SMBus controller enabled\n");
216
217 return 0;
218}
219
220#define PCH_EHCI0_TEMP_BAR0 0xe8000000
221#define PCH_EHCI1_TEMP_BAR0 0xe8000400
222#define PCH_XHCI_TEMP_BAR0 0xe8001000
223
224/*
225 * Setup USB controller MMIO BAR to prevent the reference code from
226 * resetting the controller.
227 *
228 * The BAR will be re-assigned during device enumeration so these are only
229 * temporary.
230 *
231 * This is used to speed up the resume path.
232 */
233static void enable_usb_bar(void)
234{
235 pci_dev_t usb0 = PCH_EHCI1_DEV;
236 pci_dev_t usb1 = PCH_EHCI2_DEV;
237 pci_dev_t usb3 = PCH_XHCI_DEV;
238 u32 cmd;
239
240 /* USB Controller 1 */
241 pci_write_config32(usb0, PCI_BASE_ADDRESS_0,
242 PCH_EHCI0_TEMP_BAR0);
243 cmd = pci_read_config32(usb0, PCI_COMMAND);
244 cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
245 pci_write_config32(usb0, PCI_COMMAND, cmd);
246
247 /* USB Controller 1 */
248 pci_write_config32(usb1, PCI_BASE_ADDRESS_0,
249 PCH_EHCI1_TEMP_BAR0);
250 cmd = pci_read_config32(usb1, PCI_COMMAND);
251 cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
252 pci_write_config32(usb1, PCI_COMMAND, cmd);
253
254 /* USB3 Controller */
255 pci_write_config32(usb3, PCI_BASE_ADDRESS_0,
256 PCH_XHCI_TEMP_BAR0);
257 cmd = pci_read_config32(usb3, PCI_COMMAND);
258 cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
259 pci_write_config32(usb3, PCI_COMMAND, cmd);
260}
261
Simon Glass367077a2014-11-12 22:42:20 -0700262static int report_bist_failure(void)
263{
264 if (gd->arch.bist != 0) {
265 printf("BIST failed: %08x\n", gd->arch.bist);
266 return -EFAULT;
267 }
268
269 return 0;
270}
271
Simon Glass0b36ecd2014-11-12 22:42:07 -0700272int print_cpuinfo(void)
273{
Simon Glass30580fc2014-11-12 22:42:23 -0700274 enum pei_boot_mode_t boot_mode = PEI_BOOT_NONE;
Simon Glass0b36ecd2014-11-12 22:42:07 -0700275 char processor_name[CPU_MAX_NAME_LEN];
276 const char *name;
Simon Glass30580fc2014-11-12 22:42:23 -0700277 uint32_t pm1_cnt;
278 uint16_t pm1_sts;
Simon Glass367077a2014-11-12 22:42:20 -0700279 int ret;
280
281 /* Halt if there was a built in self test failure */
282 ret = report_bist_failure();
283 if (ret)
284 return ret;
Simon Glass0b36ecd2014-11-12 22:42:07 -0700285
Simon Glassf79d5382014-11-12 22:42:21 -0700286 ret = microcode_update_intel();
287 if (ret && ret != -ENOENT && ret != -EEXIST)
288 return ret;
289
Simon Glass30580fc2014-11-12 22:42:23 -0700290 /* Enable upper 128bytes of CMOS */
291 writel(1 << 2, RCB_REG(RC));
292
293 /* TODO: cmos_post_init() */
294 if (readl(MCHBAR_REG(SSKPD)) == 0xCAFE) {
295 debug("soft reset detected\n");
296 boot_mode = PEI_BOOT_SOFT_RESET;
297
298 /* System is not happy after keyboard reset... */
299 debug("Issuing CF9 warm reset\n");
300 outb(0x6, 0xcf9);
301 cpu_hlt();
302 }
303
304 /* Early chipset init required before RAM init can work */
305 sandybridge_early_init(SANDYBRIDGE_MOBILE);
306
307 /* Check PM1_STS[15] to see if we are waking from Sx */
308 pm1_sts = inw(DEFAULT_PMBASE + PM1_STS);
309
310 /* Read PM1_CNT[12:10] to determine which Sx state */
311 pm1_cnt = inl(DEFAULT_PMBASE + PM1_CNT);
312
313 if ((pm1_sts & WAK_STS) && ((pm1_cnt >> 10) & 7) == 5) {
314#if CONFIG_HAVE_ACPI_RESUME
315 debug("Resume from S3 detected.\n");
316 boot_mode = PEI_BOOT_RESUME;
317 /* Clear SLP_TYPE. This will break stage2 but
318 * we care for that when we get there.
319 */
320 outl(pm1_cnt & ~(7 << 10), DEFAULT_PMBASE + PM1_CNT);
321#else
322 debug("Resume from S3 detected, but disabled.\n");
323#endif
324 } else {
325 /*
326 * TODO: An indication of life might be possible here (e.g.
327 * keyboard light)
328 */
329 }
330 post_code(POST_EARLY_INIT);
331
332 /* Enable SPD ROMs and DDR-III DRAM */
333 ret = enable_smbus();
334 if (ret)
335 return ret;
336
337 /* Prepare USB controller early in S3 resume */
338 if (boot_mode == PEI_BOOT_RESUME)
339 enable_usb_bar();
340
341 gd->arch.pei_boot_mode = boot_mode;
342
343 /* TODO: Move this to the board or driver */
344 pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1);
345 pci_write_config32(PCH_LPC_DEV, GPIO_CNTL, 0x10);
346
Simon Glass0b36ecd2014-11-12 22:42:07 -0700347 /* Print processor name */
348 name = cpu_get_name(processor_name);
349 printf("CPU: %s\n", name);
350
Simon Glass30580fc2014-11-12 22:42:23 -0700351 post_code(POST_CPU_INFO);
352
Simon Glass0b36ecd2014-11-12 22:42:07 -0700353 return 0;
354}