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/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 print_cpuinfo() 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 print_cpuinfo(void) 128 { 129 enum pei_boot_mode_t boot_mode = PEI_BOOT_NONE; 130 char processor_name[CPU_MAX_NAME_LEN]; 131 struct udevice *dev, *lpc; 132 const char *name; 133 uint32_t pm1_cnt; 134 uint16_t pm1_sts; 135 int ret; 136 137 /* TODO: cmos_post_init() */ 138 if (readl(MCHBAR_REG(SSKPD)) == 0xCAFE) { 139 debug("soft reset detected\n"); 140 boot_mode = PEI_BOOT_SOFT_RESET; 141 142 /* System is not happy after keyboard reset... */ 143 debug("Issuing CF9 warm reset\n"); 144 reset_cpu(0); 145 } 146 147 ret = cpu_common_init(); 148 if (ret) 149 return ret; 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 return ret; 171 172 /* Prepare USB controller early in S3 resume */ 173 if (boot_mode == PEI_BOOT_RESUME) { 174 uclass_first_device(UCLASS_LPC, &lpc); 175 enable_usb_bar(pci_get_controller(lpc->parent)); 176 } 177 178 gd->arch.pei_boot_mode = boot_mode; 179 180 /* Print processor name */ 181 name = cpu_get_name(processor_name); 182 printf("CPU: %s\n", name); 183 184 post_code(POST_CPU_INFO); 185 186 return 0; 187 } 188 189 void board_debug_uart_init(void) 190 { 191 /* This enables the debug UART */ 192 pci_x86_write_config(NULL, PCH_LPC_DEV, LPC_EN, COMA_LPC_EN, 193 PCI_SIZE_16); 194 } 195