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