xref: /OK3568_Linux_fs/u-boot/arch/x86/lib/fsp/fsp_common.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <dm.h>
9*4882a593Smuzhiyun #include <errno.h>
10*4882a593Smuzhiyun #include <rtc.h>
11*4882a593Smuzhiyun #include <asm/acpi_s3.h>
12*4882a593Smuzhiyun #include <asm/cmos_layout.h>
13*4882a593Smuzhiyun #include <asm/early_cmos.h>
14*4882a593Smuzhiyun #include <asm/io.h>
15*4882a593Smuzhiyun #include <asm/mrccache.h>
16*4882a593Smuzhiyun #include <asm/post.h>
17*4882a593Smuzhiyun #include <asm/processor.h>
18*4882a593Smuzhiyun #include <asm/fsp/fsp_support.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun extern void ich_spi_config_opcode(struct udevice *dev);
23*4882a593Smuzhiyun 
checkcpu(void)24*4882a593Smuzhiyun int checkcpu(void)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	return 0;
27*4882a593Smuzhiyun }
28*4882a593Smuzhiyun 
print_cpuinfo(void)29*4882a593Smuzhiyun int print_cpuinfo(void)
30*4882a593Smuzhiyun {
31*4882a593Smuzhiyun 	post_code(POST_CPU_INFO);
32*4882a593Smuzhiyun 	return default_print_cpuinfo();
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun 
fsp_init_phase_pci(void)35*4882a593Smuzhiyun int fsp_init_phase_pci(void)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun 	u32 status;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 	/* call into FspNotify */
40*4882a593Smuzhiyun 	debug("Calling into FSP (notify phase INIT_PHASE_PCI): ");
41*4882a593Smuzhiyun 	status = fsp_notify(NULL, INIT_PHASE_PCI);
42*4882a593Smuzhiyun 	if (status)
43*4882a593Smuzhiyun 		debug("fail, error code %x\n", status);
44*4882a593Smuzhiyun 	else
45*4882a593Smuzhiyun 		debug("OK\n");
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	return status ? -EPERM : 0;
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun 
board_final_cleanup(void)50*4882a593Smuzhiyun void board_final_cleanup(void)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	u32 status;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #ifdef CONFIG_FSP_LOCKDOWN_SPI
55*4882a593Smuzhiyun 	struct udevice *dev;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	/*
58*4882a593Smuzhiyun 	 * Some Intel FSP (like Braswell) does SPI lock-down during the call
59*4882a593Smuzhiyun 	 * to fsp_notify(INIT_PHASE_BOOT). But before SPI lock-down is done,
60*4882a593Smuzhiyun 	 * it's bootloader's responsibility to configure the SPI controller's
61*4882a593Smuzhiyun 	 * opcode registers properly otherwise SPI controller driver doesn't
62*4882a593Smuzhiyun 	 * know how to communicate with the SPI flash device.
63*4882a593Smuzhiyun 	 *
64*4882a593Smuzhiyun 	 * Note we cannot do such configuration elsewhere (eg: during the SPI
65*4882a593Smuzhiyun 	 * controller driver's probe() routine), because:
66*4882a593Smuzhiyun 	 *
67*4882a593Smuzhiyun 	 * 1). U-Boot SPI controller driver does not set the lock-down bit
68*4882a593Smuzhiyun 	 * 2). Any SPI transfer will corrupt the contents of these registers
69*4882a593Smuzhiyun 	 *
70*4882a593Smuzhiyun 	 * Hence we have to do it right here before SPI lock-down bit is set.
71*4882a593Smuzhiyun 	 */
72*4882a593Smuzhiyun 	if (!uclass_first_device_err(UCLASS_SPI, &dev))
73*4882a593Smuzhiyun 		ich_spi_config_opcode(dev);
74*4882a593Smuzhiyun #endif
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	/* call into FspNotify */
77*4882a593Smuzhiyun 	debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
78*4882a593Smuzhiyun 	status = fsp_notify(NULL, INIT_PHASE_BOOT);
79*4882a593Smuzhiyun 	if (status)
80*4882a593Smuzhiyun 		debug("fail, error code %x\n", status);
81*4882a593Smuzhiyun 	else
82*4882a593Smuzhiyun 		debug("OK\n");
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	return;
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun 
fsp_prepare_mrc_cache(void)87*4882a593Smuzhiyun static __maybe_unused void *fsp_prepare_mrc_cache(void)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun 	struct mrc_data_container *cache;
90*4882a593Smuzhiyun 	struct mrc_region entry;
91*4882a593Smuzhiyun 	int ret;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	ret = mrccache_get_region(NULL, &entry);
94*4882a593Smuzhiyun 	if (ret)
95*4882a593Smuzhiyun 		return NULL;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	cache = mrccache_find_current(&entry);
98*4882a593Smuzhiyun 	if (!cache)
99*4882a593Smuzhiyun 		return NULL;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	debug("%s: mrc cache at %p, size %x checksum %04x\n", __func__,
102*4882a593Smuzhiyun 	      cache->data, cache->data_size, cache->checksum);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	return cache->data;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun #ifdef CONFIG_HAVE_ACPI_RESUME
fsp_save_s3_stack(void)108*4882a593Smuzhiyun int fsp_save_s3_stack(void)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun 	struct udevice *dev;
111*4882a593Smuzhiyun 	int ret;
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	if (gd->arch.prev_sleep_state == ACPI_S3)
114*4882a593Smuzhiyun 		return 0;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	ret = uclass_get_device(UCLASS_RTC, 0, &dev);
117*4882a593Smuzhiyun 	if (ret) {
118*4882a593Smuzhiyun 		debug("Cannot find RTC: err=%d\n", ret);
119*4882a593Smuzhiyun 		return -ENODEV;
120*4882a593Smuzhiyun 	}
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	/* Save the stack address to CMOS */
123*4882a593Smuzhiyun 	ret = rtc_write32(dev, CMOS_FSP_STACK_ADDR, gd->start_addr_sp);
124*4882a593Smuzhiyun 	if (ret) {
125*4882a593Smuzhiyun 		debug("Save stack address to CMOS: err=%d\n", ret);
126*4882a593Smuzhiyun 		return -EIO;
127*4882a593Smuzhiyun 	}
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	return 0;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun #endif
132*4882a593Smuzhiyun 
arch_fsp_init(void)133*4882a593Smuzhiyun int arch_fsp_init(void)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun 	void *nvs;
136*4882a593Smuzhiyun 	int stack = CONFIG_FSP_TEMP_RAM_ADDR;
137*4882a593Smuzhiyun 	int boot_mode = BOOT_FULL_CONFIG;
138*4882a593Smuzhiyun #ifdef CONFIG_HAVE_ACPI_RESUME
139*4882a593Smuzhiyun 	int prev_sleep_state = chipset_prev_sleep_state();
140*4882a593Smuzhiyun 	gd->arch.prev_sleep_state = prev_sleep_state;
141*4882a593Smuzhiyun #endif
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	if (!gd->arch.hob_list) {
144*4882a593Smuzhiyun #ifdef CONFIG_ENABLE_MRC_CACHE
145*4882a593Smuzhiyun 		nvs = fsp_prepare_mrc_cache();
146*4882a593Smuzhiyun #else
147*4882a593Smuzhiyun 		nvs = NULL;
148*4882a593Smuzhiyun #endif
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun #ifdef CONFIG_HAVE_ACPI_RESUME
151*4882a593Smuzhiyun 		if (prev_sleep_state == ACPI_S3) {
152*4882a593Smuzhiyun 			if (nvs == NULL) {
153*4882a593Smuzhiyun 				/* If waking from S3 and no cache then */
154*4882a593Smuzhiyun 				debug("No MRC cache found in S3 resume path\n");
155*4882a593Smuzhiyun 				post_code(POST_RESUME_FAILURE);
156*4882a593Smuzhiyun 				/* Clear Sleep Type */
157*4882a593Smuzhiyun 				chipset_clear_sleep_state();
158*4882a593Smuzhiyun 				/* Reboot */
159*4882a593Smuzhiyun 				debug("Rebooting..\n");
160*4882a593Smuzhiyun 				reset_cpu(0);
161*4882a593Smuzhiyun 				/* Should not reach here.. */
162*4882a593Smuzhiyun 				panic("Reboot System");
163*4882a593Smuzhiyun 			}
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 			/*
166*4882a593Smuzhiyun 			 * DM is not avaiable yet at this point, hence call
167*4882a593Smuzhiyun 			 * CMOS access library which does not depend on DM.
168*4882a593Smuzhiyun 			 */
169*4882a593Smuzhiyun 			stack = cmos_read32(CMOS_FSP_STACK_ADDR);
170*4882a593Smuzhiyun 			boot_mode = BOOT_ON_S3_RESUME;
171*4882a593Smuzhiyun 		}
172*4882a593Smuzhiyun #endif
173*4882a593Smuzhiyun 		/*
174*4882a593Smuzhiyun 		 * The first time we enter here, call fsp_init().
175*4882a593Smuzhiyun 		 * Note the execution does not return to this function,
176*4882a593Smuzhiyun 		 * instead it jumps to fsp_continue().
177*4882a593Smuzhiyun 		 */
178*4882a593Smuzhiyun 		fsp_init(stack, boot_mode, nvs);
179*4882a593Smuzhiyun 	} else {
180*4882a593Smuzhiyun 		/*
181*4882a593Smuzhiyun 		 * The second time we enter here, adjust the size of malloc()
182*4882a593Smuzhiyun 		 * pool before relocation. Given gd->malloc_base was adjusted
183*4882a593Smuzhiyun 		 * after the call to board_init_f_init_reserve() in arch/x86/
184*4882a593Smuzhiyun 		 * cpu/start.S, we should fix up gd->malloc_limit here.
185*4882a593Smuzhiyun 		 */
186*4882a593Smuzhiyun 		gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN;
187*4882a593Smuzhiyun 	}
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	return 0;
190*4882a593Smuzhiyun }
191