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.
17 #include <arch/acpi.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>
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>
42 static void detect_num_cpus(struct pattrs
*attrs
)
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;
61 static inline void fill_in_msr(msr_t
*msr
, int idx
)
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)
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
;
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
);
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)
129 gnvs
= cbmem_add(CBMEM_ID_ACPI_GNVS
, sizeof(global_nvs_t
));
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
;
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. */
149 /* Get GPIO initial states from mainboard */
150 config
= mainboard_get_gpios();
151 setup_soc_gpios(config
);