1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2014 Google, Inc 4 * (C) Copyright 2008 5 * Graeme Russ, graeme.russ@gmail.com. 6 * 7 * Some portions from coreboot src/mainboard/google/link/romstage.c 8 * and src/cpu/intel/model_206ax/bootblock.c 9 * Copyright (C) 2007-2010 coresystems GmbH 10 * Copyright (C) 2011 Google Inc. 11 */ 12 13 #include <common.h> 14 #include <dm.h> 15 #include <errno.h> 16 #include <fdtdec.h> 17 #include <pch.h> 18 #include <asm/cpu.h> 19 #include <asm/cpu_common.h> 20 #include <asm/intel_regs.h> 21 #include <asm/io.h> 22 #include <asm/lapic.h> 23 #include <asm/lpc_common.h> 24 #include <asm/microcode.h> 25 #include <asm/msr.h> 26 #include <asm/mtrr.h> 27 #include <asm/pci.h> 28 #include <asm/post.h> 29 #include <asm/processor.h> 30 #include <asm/arch/model_206ax.h> 31 #include <asm/arch/pch.h> 32 #include <asm/arch/sandybridge.h> 33 34 DECLARE_GLOBAL_DATA_PTR; 35 36 static int set_flex_ratio_to_tdp_nominal(void) 37 { 38 /* Minimum CPU revision for configurable TDP support */ 39 if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID) 40 return -EINVAL; 41 42 return cpu_set_flex_ratio_to_tdp_nominal(); 43 } 44 45 int arch_cpu_init(void) 46 { 47 post_code(POST_CPU_INIT); 48 49 return x86_cpu_init_f(); 50 } 51 52 int arch_cpu_init_dm(void) 53 { 54 struct pci_controller *hose; 55 struct udevice *bus, *dev; 56 int ret; 57 58 post_code(0x70); 59 ret = uclass_get_device(UCLASS_PCI, 0, &bus); 60 post_code(0x71); 61 if (ret) 62 return ret; 63 post_code(0x72); 64 hose = dev_get_uclass_priv(bus); 65 66 /* TODO(sjg@chromium.org): Get rid of gd->hose */ 67 gd->hose = hose; 68 69 ret = uclass_first_device_err(UCLASS_LPC, &dev); 70 if (ret) 71 return ret; 72 73 /* 74 * We should do as little as possible before the serial console is 75 * up. Perhaps this should move to later. Our next lot of init 76 * happens in checkcpu() when we have a console 77 */ 78 ret = set_flex_ratio_to_tdp_nominal(); 79 if (ret) 80 return ret; 81 82 return 0; 83 } 84 85 #define PCH_EHCI0_TEMP_BAR0 0xe8000000 86 #define PCH_EHCI1_TEMP_BAR0 0xe8000400 87 #define PCH_XHCI_TEMP_BAR0 0xe8001000 88 89 /* 90 * Setup USB controller MMIO BAR to prevent the reference code from 91 * resetting the controller. 92 * 93 * The BAR will be re-assigned during device enumeration so these are only 94 * temporary. 95 * 96 * This is used to speed up the resume path. 97 */ 98 static void enable_usb_bar(struct udevice *bus) 99 { 100 pci_dev_t usb0 = PCH_EHCI1_DEV; 101 pci_dev_t usb1 = PCH_EHCI2_DEV; 102 pci_dev_t usb3 = PCH_XHCI_DEV; 103 ulong cmd; 104 105 /* USB Controller 1 */ 106 pci_bus_write_config(bus, usb0, PCI_BASE_ADDRESS_0, 107 PCH_EHCI0_TEMP_BAR0, PCI_SIZE_32); 108 pci_bus_read_config(bus, usb0, PCI_COMMAND, &cmd, PCI_SIZE_32); 109 cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; 110 pci_bus_write_config(bus, usb0, PCI_COMMAND, cmd, PCI_SIZE_32); 111 112 /* USB Controller 2 */ 113 pci_bus_write_config(bus, usb1, PCI_BASE_ADDRESS_0, 114 PCH_EHCI1_TEMP_BAR0, PCI_SIZE_32); 115 pci_bus_read_config(bus, usb1, PCI_COMMAND, &cmd, PCI_SIZE_32); 116 cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; 117 pci_bus_write_config(bus, usb1, PCI_COMMAND, cmd, PCI_SIZE_32); 118 119 /* USB3 Controller 1 */ 120 pci_bus_write_config(bus, usb3, PCI_BASE_ADDRESS_0, 121 PCH_XHCI_TEMP_BAR0, PCI_SIZE_32); 122 pci_bus_read_config(bus, usb3, PCI_COMMAND, &cmd, PCI_SIZE_32); 123 cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; 124 pci_bus_write_config(bus, usb3, PCI_COMMAND, cmd, PCI_SIZE_32); 125 } 126 127 int checkcpu(void) 128 { 129 enum pei_boot_mode_t boot_mode = PEI_BOOT_NONE; 130 struct udevice *dev, *lpc; 131 uint32_t pm1_cnt; 132 uint16_t pm1_sts; 133 int ret; 134 135 /* TODO: cmos_post_init() */ 136 if (readl(MCHBAR_REG(SSKPD)) == 0xCAFE) { 137 debug("soft reset detected\n"); 138 boot_mode = PEI_BOOT_SOFT_RESET; 139 140 /* System is not happy after keyboard reset... */ 141 debug("Issuing CF9 warm reset\n"); 142 reset_cpu(0); 143 } 144 145 ret = cpu_common_init(); 146 if (ret) { 147 debug("%s: cpu_common_init() failed\n", __func__); 148 return ret; 149 } 150 151 /* Check PM1_STS[15] to see if we are waking from Sx */ 152 pm1_sts = inw(DEFAULT_PMBASE + PM1_STS); 153 154 /* Read PM1_CNT[12:10] to determine which Sx state */ 155 pm1_cnt = inl(DEFAULT_PMBASE + PM1_CNT); 156 157 if ((pm1_sts & WAK_STS) && ((pm1_cnt >> 10) & 7) == 5) { 158 debug("Resume from S3 detected, but disabled.\n"); 159 } else { 160 /* 161 * TODO: An indication of life might be possible here (e.g. 162 * keyboard light) 163 */ 164 } 165 post_code(POST_EARLY_INIT); 166 167 /* Enable SPD ROMs and DDR-III DRAM */ 168 ret = uclass_first_device_err(UCLASS_I2C, &dev); 169 if (ret) { 170 debug("%s: Failed to get I2C (ret=%d)\n", __func__, ret); 171 return ret; 172 } 173 174 /* Prepare USB controller early in S3 resume */ 175 if (boot_mode == PEI_BOOT_RESUME) { 176 uclass_first_device(UCLASS_LPC, &lpc); 177 enable_usb_bar(pci_get_controller(lpc->parent)); 178 } 179 180 gd->arch.pei_boot_mode = boot_mode; 181 182 return 0; 183 } 184 185 int print_cpuinfo(void) 186 { 187 char processor_name[CPU_MAX_NAME_LEN]; 188 const char *name; 189 190 /* Print processor name */ 191 name = cpu_get_name(processor_name); 192 printf("CPU: %s\n", name); 193 194 post_code(POST_CPU_INFO); 195 196 return 0; 197 } 198 199 void board_debug_uart_init(void) 200 { 201 /* This enables the debug UART */ 202 pci_x86_write_config(NULL, PCH_LPC_DEV, LPC_EN, COMA_LPC_EN, 203 PCI_SIZE_16); 204 } 205