blob: 27a0cce87cad2f13ef749cebf25a45d4dff6741d [file] [log] [blame]
Angel Ponsba38f372020-04-05 15:46:45 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lee Leahy77ff0b12015-05-05 15:07:29 -07002
Kyösti Mälkki27872372021-01-21 16:05:26 +02003#include <acpi/acpi_pm.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -07004#include <console/console.h>
Elyes Haouasdef74aa2022-10-31 13:44:40 +01005#include <cpu/cpu.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -07006#include <cpu/intel/microcode.h>
7#include <cpu/x86/cr.h>
8#include <cpu/x86/msr.h>
9#include <device/device.h>
10#include <device/pci_def.h>
11#include <device/pci_ops.h>
Aaron Durbin789f2b62015-09-09 17:05:06 -050012#include <fsp/util.h>
Dinesh Gehlotba09eb72023-01-17 05:06:10 +000013#include <gpio.h>
Elyes Haouasdef74aa2022-10-31 13:44:40 +010014#include <intelblocks/acpi_wake_source.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -070015#include <soc/lpc.h>
16#include <soc/msr.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -070017#include <soc/pattrs.h>
18#include <soc/pci_devs.h>
Lee Leahy32471722015-04-20 15:20:28 -070019#include <soc/pm.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -070020#include <soc/ramstage.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -070021
22#define SHOW_PATTRS 1
23
Lee Leahy32471722015-04-20 15:20:28 -070024struct pattrs __global_pattrs;
25
Lee Leahy77ff0b12015-05-05 15:07:29 -070026static void detect_num_cpus(struct pattrs *attrs)
27{
28 int ecx = 0;
29
30 while (1) {
31 struct cpuid_result leaf_b;
32
33 leaf_b = cpuid_ext(0xb, ecx);
34
Lee Leahy32471722015-04-20 15:20:28 -070035 /*
36 * The SOC doesn't have hyperthreading so just determine the
37 * number of cores by from level type (ecx[15:8] == * 2).
38 */
Lee Leahy77ff0b12015-05-05 15:07:29 -070039 if ((leaf_b.ecx & 0xff00) == 0x0200) {
40 attrs->num_cpus = leaf_b.ebx & 0xffff;
41 break;
42 }
43 ecx++;
44 }
45}
46
47static inline void fill_in_msr(msr_t *msr, int idx)
48{
49 *msr = rdmsr(idx);
50 if (SHOW_PATTRS) {
51 printk(BIOS_DEBUG, "msr(%x) = %08x%08x\n",
52 idx, msr->hi, msr->lo);
53 }
54}
55
Elyes HAOUAS39303d52018-07-08 12:40:45 +020056static const char *const stepping_str[] = {
Frans Hendriks83e73242018-07-13 09:52:04 +020057 "A0", "A1", "B0", "B1", "B2", "B3", "C0", "D1"
Lee Leahy77ff0b12015-05-05 15:07:29 -070058};
59
60static void fill_in_pattrs(void)
61{
Elyes HAOUASb13fac32018-05-24 22:29:44 +020062 struct device *dev;
Lee Leahy77ff0b12015-05-05 15:07:29 -070063 msr_t msr;
64 struct pattrs *attrs = (struct pattrs *)pattrs_get();
65
66 attrs->cpuid = cpuid_eax(1);
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030067 dev = pcidev_on_root(LPC_DEV, LPC_FUNC);
Lee Leahy77ff0b12015-05-05 15:07:29 -070068 attrs->revid = pci_read_config8(dev, REVID);
69 /* The revision to stepping IDs have two values per metal stepping. */
Elyes HAOUAS0bc5d9d2022-01-27 07:55:34 +010070 if (attrs->revid >= RID_D_STEPPING_START) {
Frans Hendriks83e73242018-07-13 09:52:04 +020071 attrs->stepping = (attrs->revid - RID_D_STEPPING_START) / 2;
72 attrs->stepping += STEP_D1;
Angel Ponsaee7ab22020-03-19 00:31:58 +010073
Elyes HAOUAS0bc5d9d2022-01-27 07:55:34 +010074 } else if (attrs->revid >= RID_C_STEPPING_START) {
Lee Leahy77ff0b12015-05-05 15:07:29 -070075 attrs->stepping = (attrs->revid - RID_C_STEPPING_START) / 2;
76 attrs->stepping += STEP_C0;
Angel Ponsaee7ab22020-03-19 00:31:58 +010077
Lee Leahy77ff0b12015-05-05 15:07:29 -070078 } else if (attrs->revid >= RID_B_STEPPING_START) {
79 attrs->stepping = (attrs->revid - RID_B_STEPPING_START) / 2;
80 attrs->stepping += STEP_B0;
Angel Ponsaee7ab22020-03-19 00:31:58 +010081
Lee Leahy77ff0b12015-05-05 15:07:29 -070082 } else {
83 attrs->stepping = (attrs->revid - RID_A_STEPPING_START) / 2;
84 attrs->stepping += STEP_A0;
85 }
86
87 attrs->microcode_patch = intel_microcode_find();
88 attrs->address_bits = cpuid_eax(0x80000008) & 0xff;
89 detect_num_cpus(attrs);
90
91 if (SHOW_PATTRS) {
Lee Leahy32471722015-04-20 15:20:28 -070092 printk(BIOS_DEBUG, "Cpuid %08x cpus %d rid %02x step %s\n",
Lee Leahy77ff0b12015-05-05 15:07:29 -070093 attrs->cpuid, attrs->num_cpus, attrs->revid,
94 (attrs->stepping >= ARRAY_SIZE(stepping_str)) ? "??" :
95 stepping_str[attrs->stepping]);
96 }
97
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +020098 fill_in_msr(&attrs->platform_id, IA32_PLATFORM_ID);
Lee Leahy77ff0b12015-05-05 15:07:29 -070099 fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO);
100
101 /* Set IA core speed ratio and voltages */
Lee Leahy32471722015-04-20 15:20:28 -0700102 fill_in_msr(&msr, MSR_IACORE_RATIOS);
Angel Ponsaee7ab22020-03-19 00:31:58 +0100103 attrs->iacore_ratios[IACORE_MIN] = (msr.lo >> 0) & 0x7f;
104 attrs->iacore_ratios[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
Lee Leahy77ff0b12015-05-05 15:07:29 -0700105 attrs->iacore_ratios[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
Lee Leahy32471722015-04-20 15:20:28 -0700106 fill_in_msr(&msr, MSR_IACORE_TURBO_RATIOS);
Lee Leahy77ff0b12015-05-05 15:07:29 -0700107 attrs->iacore_ratios[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
108
Lee Leahy32471722015-04-20 15:20:28 -0700109 fill_in_msr(&msr, MSR_IACORE_VIDS);
Angel Ponsaee7ab22020-03-19 00:31:58 +0100110 attrs->iacore_vids[IACORE_MIN] = (msr.lo >> 0) & 0x7f;
111 attrs->iacore_vids[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
Lee Leahy77ff0b12015-05-05 15:07:29 -0700112 attrs->iacore_vids[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
Lee Leahy32471722015-04-20 15:20:28 -0700113 fill_in_msr(&msr, MSR_IACORE_TURBO_VIDS);
Lee Leahy77ff0b12015-05-05 15:07:29 -0700114 attrs->iacore_vids[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
115
116 /* Set bus clock speed */
Subrata Banik45a221d2015-08-05 17:01:55 +0530117 attrs->bclk_khz = cpu_bus_freq_khz();
Lee Leahy32471722015-04-20 15:20:28 -0700118}
119
Duncan Lauriee73da802015-09-08 16:16:34 -0700120/* Save wake source information for calculating ACPI _SWS values */
Kyösti Mälkkif67e67512021-01-22 19:59:07 +0200121int soc_fill_acpi_wake(const struct chipset_power_state *ps, uint32_t *pm1, uint32_t **gpe0)
Lee Leahy77ff0b12015-05-05 15:07:29 -0700122{
Duncan Lauriee73da802015-09-08 16:16:34 -0700123 static uint32_t gpe0_sts;
Lee Leahy77ff0b12015-05-05 15:07:29 -0700124
Duncan Lauriee73da802015-09-08 16:16:34 -0700125 *pm1 = ps->pm1_sts & ps->pm1_en;
Lee Leahy77ff0b12015-05-05 15:07:29 -0700126
Duncan Lauriee73da802015-09-08 16:16:34 -0700127 gpe0_sts = ps->gpe0_sts & ps->gpe0_en;
128 *gpe0 = &gpe0_sts;
Lee Leahy77ff0b12015-05-05 15:07:29 -0700129
Duncan Lauriee73da802015-09-08 16:16:34 -0700130 return 1;
Lee Leahy77ff0b12015-05-05 15:07:29 -0700131}
132
Lee Leahy32471722015-04-20 15:20:28 -0700133void soc_init_pre_device(struct soc_intel_braswell_config *config)
Lee Leahy77ff0b12015-05-05 15:07:29 -0700134{
135 struct soc_gpio_config *gpio_config;
136
137 fill_in_pattrs();
138
Lee Leahy77ff0b12015-05-05 15:07:29 -0700139 /* Allow for SSE instructions to be executed. */
140 write_cr4(read_cr4() | CR4_OSFXSR | CR4_OSXMMEXCPT);
141
Lee Leahy32471722015-04-20 15:20:28 -0700142 /* Perform silicon specific init. */
143 intel_silicon_init();
Hannah Williamsb0eb5942015-08-23 17:24:43 -0700144 set_max_freq();
Lee Leahy77ff0b12015-05-05 15:07:29 -0700145
146 /* Get GPIO initial states from mainboard */
147 gpio_config = mainboard_get_gpios();
148 setup_soc_gpios(gpio_config, config->enable_xdp_tap);
Lee Leahy77ff0b12015-05-05 15:07:29 -0700149}