tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / soc / intel / fsp_baytrail / ramstage.c
blob53ae2b72ea7996cbfe75e6d107b093c6d869bac1
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2013 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <arch/cpu.h>
17 #include <arch/acpi.h>
18 #include <cbmem.h>
19 #include <console/console.h>
20 #include <cpu/intel/microcode.h>
21 #include <cpu/x86/cr.h>
22 #include <cpu/x86/msr.h>
23 #include <device/device.h>
24 #include <device/pci_def.h>
25 #include <device/pci_ops.h>
26 #include <stdlib.h>
27 #include <string.h>
29 #include <baytrail/gpio.h>
30 #include <baytrail/lpc.h>
31 #include <baytrail/nvs.h>
32 #include <baytrail/msr.h>
33 #include <baytrail/pattrs.h>
34 #include <baytrail/pci_devs.h>
35 #include <baytrail/ramstage.h>
37 /* Global PATTRS */
38 DEFINE_PATTRS;
40 #define SHOW_PATTRS 1
42 static void detect_num_cpus(struct pattrs *attrs)
44 int ecx = 0;
46 while (1) {
47 struct cpuid_result leaf_b;
49 leaf_b = cpuid_ext(0xb, ecx);
51 /* Bay Trail doesn't have hyperthreading so just determine the
52 * number of cores by from level type (ecx[15:8] == * 2). */
53 if ((leaf_b.ecx & 0xff00) == 0x0200) {
54 attrs->num_cpus = leaf_b.ebx & 0xffff;
55 break;
57 ecx++;
61 static inline void fill_in_msr(msr_t *msr, int idx)
63 *msr = rdmsr(idx);
64 if (SHOW_PATTRS) {
65 printk(BIOS_DEBUG, "msr(%x) = %08x%08x\n",
66 idx, msr->hi, msr->lo);
70 static const char *stepping_str[] = {
71 "A0", "A1", "B0", "B1", "B2", "B3"
74 static void fill_in_pattrs(void)
76 device_t dev;
77 msr_t msr;
78 struct pattrs *attrs = (struct pattrs *)pattrs_get();
80 attrs->cpuid = cpuid_eax(1);
81 dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC));
82 attrs->revid = pci_read_config8(dev, REVID);
83 /* The revision to stepping IDs have two values per metal stepping. */
84 if (attrs->revid >= RID_B_STEPPING_START) {
85 attrs->stepping = (attrs->revid - RID_B_STEPPING_START) / 2;
86 attrs->stepping += STEP_B0;
87 } else {
88 attrs->stepping = (attrs->revid - RID_A_STEPPING_START) / 2;
89 attrs->stepping += STEP_A0;
92 attrs->address_bits = cpuid_eax(0x80000008) & 0xff;
93 detect_num_cpus(attrs);
95 if (SHOW_PATTRS) {
96 printk(BIOS_DEBUG,
97 "CPUID: %08x\nCores: %d\nRevision ID: %02x\nStepping: %s\n",
98 attrs->cpuid, attrs->num_cpus, attrs->revid,
99 (attrs->stepping >= ARRAY_SIZE(stepping_str)) ? "??" :
100 stepping_str[attrs->stepping]);
103 fill_in_msr(&attrs->platform_id, MSR_IA32_PLATFORM_ID);
104 fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO);
106 /* Set IA core speed ratio and voltages */
107 msr = rdmsr(MSR_IACORE_RATIOS);
108 attrs->iacore_ratios[IACORE_MIN] = msr.lo & 0x7f;
109 attrs->iacore_ratios[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
110 attrs->iacore_ratios[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
111 msr = rdmsr(MSR_IACORE_TURBO_RATIOS);
112 attrs->iacore_ratios[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
114 msr = rdmsr(MSR_IACORE_VIDS);
115 attrs->iacore_vids[IACORE_MIN] = msr.lo & 0x7f;
116 attrs->iacore_vids[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
117 attrs->iacore_vids[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
118 msr = rdmsr(MSR_IACORE_TURBO_VIDS);
119 attrs->iacore_vids[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
121 /* Set bus clock speed */
122 attrs->bclk_khz = bus_freq_khz();
125 static void s3_resume_prepare(void)
127 global_nvs_t *gnvs;
129 gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(global_nvs_t));
130 if (gnvs == NULL)
131 return;
133 if (!acpi_is_wakeup_s3())
134 memset(gnvs, 0, sizeof(global_nvs_t));
137 void baytrail_init_pre_device(void)
139 struct soc_gpio_config *config;
141 fill_in_pattrs();
143 /* Allow for SSE instructions to be executed. */
144 write_cr4(read_cr4() | CR4_OSFXSR | CR4_OSXMMEXCPT);
146 /* Indicate S3 resume to rest of ramstage. */
147 s3_resume_prepare();
149 /* Get GPIO initial states from mainboard */
150 config = mainboard_get_gpios();
151 setup_soc_gpios(config);