1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright 2019 Google LLC 4 * 5 * Portions taken from coreboot 6 */ 7 8#include <common.h> 9#include <dm.h> 10#include <ec_commands.h> 11#include <init.h> 12#include <log.h> 13#include <spi_flash.h> 14#include <spl.h> 15#include <syscon.h> 16#include <acpi/acpi_s3.h> 17#include <asm/cpu.h> 18#include <asm/cpu_common.h> 19#include <asm/cpu_x86.h> 20#include <asm/fast_spi.h> 21#include <asm/global_data.h> 22#include <asm/intel_pinctrl.h> 23#include <asm/intel_regs.h> 24#include <asm/io.h> 25#include <asm/msr.h> 26#include <asm/mtrr.h> 27#include <asm/pci.h> 28#include <asm/arch/cpu.h> 29#include <asm/arch/gpio.h> 30#include <asm/arch/iomap.h> 31#include <asm/arch/lpc.h> 32#include <asm/arch/pch.h> 33#include <asm/arch/systemagent.h> 34#include <asm/fsp2/fsp_api.h> 35#include <linux/sizes.h> 36#include <power/acpi_pmc.h> 37 38static int fast_spi_cache_bios_region(void) 39{ 40 uint map_size, offset; 41 ulong map_base, base; 42 int ret; 43 44 ret = fast_spi_early_init(PCH_DEV_SPI, IOMAP_SPI_BASE); 45 if (ret) 46 return log_msg_ret("early_init", ret); 47 48 ret = fast_spi_get_bios_mmap(PCH_DEV_SPI, &map_base, &map_size, 49 &offset); 50 if (ret) 51 return log_msg_ret("get_mmap", ret); 52 53 base = SZ_4G - map_size; 54 mtrr_set_next_var(MTRR_TYPE_WRPROT, base, map_size); 55 log_debug("BIOS cache base=%lx, size=%x\n", base, (uint)map_size); 56 57 return 0; 58} 59 60static void google_chromeec_ioport_range(uint *out_basep, uint *out_sizep) 61{ 62 uint base; 63 uint size; 64 65 if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC_MEC)) { 66 base = MEC_EMI_BASE; 67 size = MEC_EMI_SIZE; 68 } else { 69 base = EC_HOST_CMD_REGION0; 70 size = 2 * EC_HOST_CMD_REGION_SIZE; 71 /* Make sure MEMMAP region follows host cmd region */ 72 assert(base + size == EC_LPC_ADDR_MEMMAP); 73 size += EC_MEMMAP_SIZE; 74 } 75 76 *out_basep = base; 77 *out_sizep = size; 78} 79 80static void early_ec_init(void) 81{ 82 uint base, size; 83 84 /* 85 * Set up LPC decoding for the Chrome OS EC I/O port ranges: 86 * - Ports 62/66, 60/64, and 200->208 87 * - Chrome OS EC communication I/O ports 88 */ 89 lpc_enable_fixed_io_ranges(LPC_IOE_EC_62_66 | LPC_IOE_KBC_60_64 | 90 LPC_IOE_LGE_200); 91 google_chromeec_ioport_range(&base, &size); 92 lpc_open_pmio_window(base, size); 93} 94 95static int arch_cpu_init_tpl(void) 96{ 97 struct udevice *pmc, *sa, *p2sb, *serial, *spi, *lpc; 98 int ret; 99 100 ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc); 101 if (ret) 102 return log_msg_ret("PMC", ret); 103 104 /* Clear global reset promotion bit */ 105 ret = pmc_global_reset_set_enable(pmc, false); 106 if (ret) 107 return log_msg_ret("disable global reset", ret); 108 109 enable_pm_timer_emulation(pmc); 110 111 ret = uclass_first_device_err(UCLASS_P2SB, &p2sb); 112 if (ret) 113 return log_msg_ret("p2sb", ret); 114 ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &sa); 115 if (ret) 116 return log_msg_ret("northbridge", ret); 117 gd->baudrate = CONFIG_BAUDRATE; 118 ret = uclass_first_device_err(UCLASS_SERIAL, &serial); 119 if (ret) 120 return log_msg_ret("serial", ret); 121 if (CONFIG_IS_ENABLED(SPI_FLASH_SUPPORT)) { 122 ret = uclass_first_device_err(UCLASS_SPI, &spi); 123 if (ret) 124 return log_msg_ret("SPI", ret); 125 } else { 126 /* Alternative code if we don't have SPI in TPL */ 127 if (IS_ENABLED(CONFIG_APL_BOOT_FROM_FAST_SPI_FLASH)) 128 printf("Warning: Enable APL_SPI_FLASHBOOT to use SPI-flash driver in TPL"); 129 ret = fast_spi_cache_bios_region(); 130 if (ret) 131 return log_msg_ret("BIOS cache", ret); 132 } 133 ret = pmc_disable_tco(pmc); 134 if (ret) 135 return log_msg_ret("disable TCO", ret); 136 ret = pmc_gpe_init(pmc); 137 if (ret) 138 return log_msg_ret("pmc_gpe", ret); 139 ret = uclass_first_device_err(UCLASS_LPC, &lpc); 140 if (ret) 141 return log_msg_ret("lpc", ret); 142 143 early_ec_init(); 144 145 return 0; 146} 147 148/* 149 * Enables several BARs and devices which are needed for memory init 150 * - MCH_BASE_ADDR is needed in order to talk to the memory controller 151 * - HPET is enabled because FSP wants to store a pointer to global data in the 152 * HPET comparator register 153 */ 154static int arch_cpu_init_spl(void) 155{ 156 struct udevice *pmc, *p2sb; 157 int ret; 158 159 ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc); 160 if (ret) 161 return log_msg_ret("Could not probe PMC", ret); 162 ret = uclass_first_device_err(UCLASS_P2SB, &p2sb); 163 if (ret) 164 return log_msg_ret("Cannot set up p2sb", ret); 165 166 lpc_io_setup_comm_a_b(); 167 168 /* TODO(sjg@chromium.org): Enable upper RTC bank here */ 169 170 ret = pmc_init(pmc); 171 if (ret < 0) 172 return log_msg_ret("Could not init PMC", ret); 173 if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) { 174 ret = pmc_prev_sleep_state(pmc); 175 if (ret < 0) 176 return log_msg_ret("Could not get PMC sleep state", 177 ret); 178 gd->arch.prev_sleep_state = ret; 179 } 180 181 return 0; 182} 183 184int arch_cpu_init(void) 185{ 186 int ret = 0; 187 188 if (spl_phase() == PHASE_TPL) 189 ret = arch_cpu_init_tpl(); 190 else if (spl_phase() == PHASE_SPL) 191 ret = arch_cpu_init_spl(); 192 if (ret) 193 printf("%s: Error %d\n", __func__, ret); 194 195 return ret; 196} 197