xref: /rk3399_rockchip-uboot/arch/x86/lib/fsp/fsp_common.c (revision 0031af9ce7b1c2d98ce77cc20bd7546d64e334fe)
191785f70SSimon Glass /*
291785f70SSimon Glass  * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
391785f70SSimon Glass  *
491785f70SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
591785f70SSimon Glass  */
691785f70SSimon Glass 
791785f70SSimon Glass #include <common.h>
8ba65808eSBin Meng #include <dm.h>
991785f70SSimon Glass #include <errno.h>
10ba65808eSBin Meng #include <rtc.h>
111206723bSBin Meng #include <asm/acpi_s3.h>
12ba65808eSBin Meng #include <asm/cmos_layout.h>
13ba65808eSBin Meng #include <asm/early_cmos.h>
1491785f70SSimon Glass #include <asm/io.h>
15ff1e18afSBin Meng #include <asm/mrccache.h>
1691785f70SSimon Glass #include <asm/post.h>
1791785f70SSimon Glass #include <asm/processor.h>
1891785f70SSimon Glass #include <asm/fsp/fsp_support.h>
1991785f70SSimon Glass 
208b097916SSimon Glass DECLARE_GLOBAL_DATA_PTR;
218b097916SSimon Glass 
22*1e6ebee6SBin Meng extern void ich_spi_config_opcode(struct udevice *dev);
23*1e6ebee6SBin Meng 
checkcpu(void)2476d1d02fSSimon Glass int checkcpu(void)
2576d1d02fSSimon Glass {
2676d1d02fSSimon Glass 	return 0;
2776d1d02fSSimon Glass }
2876d1d02fSSimon Glass 
print_cpuinfo(void)2991785f70SSimon Glass int print_cpuinfo(void)
3091785f70SSimon Glass {
3191785f70SSimon Glass 	post_code(POST_CPU_INFO);
3291785f70SSimon Glass 	return default_print_cpuinfo();
3391785f70SSimon Glass }
3491785f70SSimon Glass 
fsp_init_phase_pci(void)35412400abSSimon Glass int fsp_init_phase_pci(void)
3691785f70SSimon Glass {
3791785f70SSimon Glass 	u32 status;
3891785f70SSimon Glass 
3991785f70SSimon Glass 	/* call into FspNotify */
4091785f70SSimon Glass 	debug("Calling into FSP (notify phase INIT_PHASE_PCI): ");
4191785f70SSimon Glass 	status = fsp_notify(NULL, INIT_PHASE_PCI);
42412400abSSimon Glass 	if (status)
4391785f70SSimon Glass 		debug("fail, error code %x\n", status);
4491785f70SSimon Glass 	else
4591785f70SSimon Glass 		debug("OK\n");
4691785f70SSimon Glass 
47412400abSSimon Glass 	return status ? -EPERM : 0;
48412400abSSimon Glass }
49412400abSSimon Glass 
board_final_cleanup(void)5091785f70SSimon Glass void board_final_cleanup(void)
5191785f70SSimon Glass {
5291785f70SSimon Glass 	u32 status;
5391785f70SSimon Glass 
54*1e6ebee6SBin Meng #ifdef CONFIG_FSP_LOCKDOWN_SPI
55*1e6ebee6SBin Meng 	struct udevice *dev;
56*1e6ebee6SBin Meng 
57*1e6ebee6SBin Meng 	/*
58*1e6ebee6SBin Meng 	 * Some Intel FSP (like Braswell) does SPI lock-down during the call
59*1e6ebee6SBin Meng 	 * to fsp_notify(INIT_PHASE_BOOT). But before SPI lock-down is done,
60*1e6ebee6SBin Meng 	 * it's bootloader's responsibility to configure the SPI controller's
61*1e6ebee6SBin Meng 	 * opcode registers properly otherwise SPI controller driver doesn't
62*1e6ebee6SBin Meng 	 * know how to communicate with the SPI flash device.
63*1e6ebee6SBin Meng 	 *
64*1e6ebee6SBin Meng 	 * Note we cannot do such configuration elsewhere (eg: during the SPI
65*1e6ebee6SBin Meng 	 * controller driver's probe() routine), because:
66*1e6ebee6SBin Meng 	 *
67*1e6ebee6SBin Meng 	 * 1). U-Boot SPI controller driver does not set the lock-down bit
68*1e6ebee6SBin Meng 	 * 2). Any SPI transfer will corrupt the contents of these registers
69*1e6ebee6SBin Meng 	 *
70*1e6ebee6SBin Meng 	 * Hence we have to do it right here before SPI lock-down bit is set.
71*1e6ebee6SBin Meng 	 */
72*1e6ebee6SBin Meng 	if (!uclass_first_device_err(UCLASS_SPI, &dev))
73*1e6ebee6SBin Meng 		ich_spi_config_opcode(dev);
74*1e6ebee6SBin Meng #endif
75*1e6ebee6SBin Meng 
7691785f70SSimon Glass 	/* call into FspNotify */
7791785f70SSimon Glass 	debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
7891785f70SSimon Glass 	status = fsp_notify(NULL, INIT_PHASE_BOOT);
79ecf674b7SSimon Glass 	if (status)
8091785f70SSimon Glass 		debug("fail, error code %x\n", status);
8191785f70SSimon Glass 	else
8291785f70SSimon Glass 		debug("OK\n");
8391785f70SSimon Glass 
8491785f70SSimon Glass 	return;
8591785f70SSimon Glass }
86aefaff8eSBin Meng 
fsp_prepare_mrc_cache(void)87ff1e18afSBin Meng static __maybe_unused void *fsp_prepare_mrc_cache(void)
88ff1e18afSBin Meng {
89ff1e18afSBin Meng 	struct mrc_data_container *cache;
90ff1e18afSBin Meng 	struct mrc_region entry;
91ff1e18afSBin Meng 	int ret;
92ff1e18afSBin Meng 
93ff1e18afSBin Meng 	ret = mrccache_get_region(NULL, &entry);
94ff1e18afSBin Meng 	if (ret)
95ff1e18afSBin Meng 		return NULL;
96ff1e18afSBin Meng 
97ff1e18afSBin Meng 	cache = mrccache_find_current(&entry);
98ff1e18afSBin Meng 	if (!cache)
99ff1e18afSBin Meng 		return NULL;
100ff1e18afSBin Meng 
101ff1e18afSBin Meng 	debug("%s: mrc cache at %p, size %x checksum %04x\n", __func__,
102ff1e18afSBin Meng 	      cache->data, cache->data_size, cache->checksum);
103ff1e18afSBin Meng 
104ff1e18afSBin Meng 	return cache->data;
105ff1e18afSBin Meng }
106ff1e18afSBin Meng 
107ba65808eSBin Meng #ifdef CONFIG_HAVE_ACPI_RESUME
fsp_save_s3_stack(void)108ba65808eSBin Meng int fsp_save_s3_stack(void)
109ba65808eSBin Meng {
110ba65808eSBin Meng 	struct udevice *dev;
111ba65808eSBin Meng 	int ret;
112ba65808eSBin Meng 
113ba65808eSBin Meng 	if (gd->arch.prev_sleep_state == ACPI_S3)
114ba65808eSBin Meng 		return 0;
115ba65808eSBin Meng 
116ba65808eSBin Meng 	ret = uclass_get_device(UCLASS_RTC, 0, &dev);
117ba65808eSBin Meng 	if (ret) {
118ba65808eSBin Meng 		debug("Cannot find RTC: err=%d\n", ret);
119ba65808eSBin Meng 		return -ENODEV;
120ba65808eSBin Meng 	}
121ba65808eSBin Meng 
122ba65808eSBin Meng 	/* Save the stack address to CMOS */
123ba65808eSBin Meng 	ret = rtc_write32(dev, CMOS_FSP_STACK_ADDR, gd->start_addr_sp);
124ba65808eSBin Meng 	if (ret) {
125ba65808eSBin Meng 		debug("Save stack address to CMOS: err=%d\n", ret);
126ba65808eSBin Meng 		return -EIO;
127ba65808eSBin Meng 	}
128ba65808eSBin Meng 
129ba65808eSBin Meng 	return 0;
130ba65808eSBin Meng }
131ba65808eSBin Meng #endif
132ba65808eSBin Meng 
arch_fsp_init(void)133671549e5SSimon Glass int arch_fsp_init(void)
134aefaff8eSBin Meng {
135ff1e18afSBin Meng 	void *nvs;
136ba65808eSBin Meng 	int stack = CONFIG_FSP_TEMP_RAM_ADDR;
1371206723bSBin Meng 	int boot_mode = BOOT_FULL_CONFIG;
1381206723bSBin Meng #ifdef CONFIG_HAVE_ACPI_RESUME
1391206723bSBin Meng 	int prev_sleep_state = chipset_prev_sleep_state();
140b727961bSBin Meng 	gd->arch.prev_sleep_state = prev_sleep_state;
1411206723bSBin Meng #endif
142ff1e18afSBin Meng 
14357b10f59SBin Meng 	if (!gd->arch.hob_list) {
144ff1e18afSBin Meng #ifdef CONFIG_ENABLE_MRC_CACHE
145ff1e18afSBin Meng 		nvs = fsp_prepare_mrc_cache();
146ff1e18afSBin Meng #else
147ff1e18afSBin Meng 		nvs = NULL;
148ff1e18afSBin Meng #endif
1491206723bSBin Meng 
1501206723bSBin Meng #ifdef CONFIG_HAVE_ACPI_RESUME
1511206723bSBin Meng 		if (prev_sleep_state == ACPI_S3) {
1521206723bSBin Meng 			if (nvs == NULL) {
1531206723bSBin Meng 				/* If waking from S3 and no cache then */
1541206723bSBin Meng 				debug("No MRC cache found in S3 resume path\n");
1551206723bSBin Meng 				post_code(POST_RESUME_FAILURE);
1561206723bSBin Meng 				/* Clear Sleep Type */
1571206723bSBin Meng 				chipset_clear_sleep_state();
1581206723bSBin Meng 				/* Reboot */
1591206723bSBin Meng 				debug("Rebooting..\n");
1601206723bSBin Meng 				reset_cpu(0);
1611206723bSBin Meng 				/* Should not reach here.. */
1621206723bSBin Meng 				panic("Reboot System");
1631206723bSBin Meng 			}
1641206723bSBin Meng 
165ba65808eSBin Meng 			/*
166ba65808eSBin Meng 			 * DM is not avaiable yet at this point, hence call
167ba65808eSBin Meng 			 * CMOS access library which does not depend on DM.
168ba65808eSBin Meng 			 */
169ba65808eSBin Meng 			stack = cmos_read32(CMOS_FSP_STACK_ADDR);
1701206723bSBin Meng 			boot_mode = BOOT_ON_S3_RESUME;
1711206723bSBin Meng 		}
1721206723bSBin Meng #endif
17357b10f59SBin Meng 		/*
17457b10f59SBin Meng 		 * The first time we enter here, call fsp_init().
17557b10f59SBin Meng 		 * Note the execution does not return to this function,
17657b10f59SBin Meng 		 * instead it jumps to fsp_continue().
17757b10f59SBin Meng 		 */
178ba65808eSBin Meng 		fsp_init(stack, boot_mode, nvs);
17957b10f59SBin Meng 	} else {
18057b10f59SBin Meng 		/*
18157b10f59SBin Meng 		 * The second time we enter here, adjust the size of malloc()
18257b10f59SBin Meng 		 * pool before relocation. Given gd->malloc_base was adjusted
183ecc30663SAlbert ARIBAUD 		 * after the call to board_init_f_init_reserve() in arch/x86/
184ecc30663SAlbert ARIBAUD 		 * cpu/start.S, we should fix up gd->malloc_limit here.
18557b10f59SBin Meng 		 */
18657b10f59SBin Meng 		gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN;
18757b10f59SBin Meng 	}
188aefaff8eSBin Meng 
189aefaff8eSBin Meng 	return 0;
190aefaff8eSBin Meng }
191