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