blob: 26e0b6e46d6b3a62075234b132404c28b2b3ffe6 [file] [log] [blame]
Angel Ponsc3f58f62020-04-05 15:46:41 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbin452d31a2013-09-24 16:47:49 -05002
3#include <arch/cpu.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07004#include <acpi/acpi.h>
Kyösti Mälkki3139c8d2020-06-28 16:33:33 +03005#include <acpi/acpi_gnvs.h>
Kyösti Mälkki27872372021-01-21 16:05:26 +02006#include <acpi/acpi_pm.h>
Kyösti Mälkkid4b58252021-01-21 16:16:58 +02007#include <bootstate.h>
Aaron Durbin452d31a2013-09-24 16:47:49 -05008#include <console/console.h>
9#include <cpu/intel/microcode.h>
Aaron Durbin1ce0b302013-10-10 12:47:47 -050010#include <cpu/x86/cr.h>
Aaron Durbin452d31a2013-09-24 16:47:49 -050011#include <cpu/x86/msr.h>
12#include <device/device.h>
13#include <device/pci_def.h>
14#include <device/pci_ops.h>
Aaron Durbin452d31a2013-09-24 16:47:49 -050015
Kyösti Mälkki4bd91872021-03-16 19:02:26 +020016#include <soc/device_nvs.h>
Julius Werner18ea2d32014-10-07 16:42:17 -070017#include <soc/gpio.h>
18#include <soc/lpc.h>
19#include <soc/msr.h>
20#include <soc/nvs.h>
21#include <soc/pattrs.h>
22#include <soc/pci_devs.h>
Angel Ponsb5320b22020-07-07 18:27:30 +020023#include <soc/pm.h>
Julius Werner18ea2d32014-10-07 16:42:17 -070024#include <soc/ramstage.h>
Kane Chenba9b7bf2015-01-17 08:19:54 +080025#include <soc/iosf.h>
Aaron Durbin452d31a2013-09-24 16:47:49 -050026
Aaron Durbin452d31a2013-09-24 16:47:49 -050027#define SHOW_PATTRS 1
28
Angel Ponsbaebe2a2020-07-07 18:21:27 +020029struct pattrs __global_pattrs;
30
Aaron Durbin452d31a2013-09-24 16:47:49 -050031static void detect_num_cpus(struct pattrs *attrs)
32{
33 int ecx = 0;
34
35 while (1) {
36 struct cpuid_result leaf_b;
37
38 leaf_b = cpuid_ext(0xb, ecx);
39
40 /* Bay Trail doesn't have hyperthreading so just determine the
41 * number of cores by from level type (ecx[15:8] == * 2). */
42 if ((leaf_b.ecx & 0xff00) == 0x0200) {
43 attrs->num_cpus = leaf_b.ebx & 0xffff;
44 break;
45 }
46 ecx++;
47 }
48}
49
50static inline void fill_in_msr(msr_t *msr, int idx)
51{
52 *msr = rdmsr(idx);
53 if (SHOW_PATTRS) {
54 printk(BIOS_DEBUG, "msr(%x) = %08x%08x\n",
55 idx, msr->hi, msr->lo);
56 }
57}
58
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -080059static const char *stepping_str[] = {
Ben Gardner2d3d1b72015-11-19 16:12:21 -060060 "A0", "A1", "B0", "B1", "B2", "B3", "C0", "D0",
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -080061};
Aaron Durbin452d31a2013-09-24 16:47:49 -050062
63static void fill_in_pattrs(void)
64{
Elyes HAOUAS17a3ceb2018-05-22 10:42:28 +020065 struct device *dev;
Duncan Laurie6aa9f1f2013-11-07 12:47:35 -080066 msr_t msr;
Aaron Durbin452d31a2013-09-24 16:47:49 -050067 struct pattrs *attrs = (struct pattrs *)pattrs_get();
68
69 attrs->cpuid = cpuid_eax(1);
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030070 dev = pcidev_on_root(LPC_DEV, LPC_FUNC);
Aaron Durbin452d31a2013-09-24 16:47:49 -050071 attrs->revid = pci_read_config8(dev, REVID);
72 /* The revision to stepping IDs have two values per metal stepping. */
Ben Gardner2d3d1b72015-11-19 16:12:21 -060073 if (attrs->revid >= RID_D_STEPPING_START) {
74 attrs->stepping = (attrs->revid - RID_D_STEPPING_START) / 2;
75 attrs->stepping += STEP_D0;
76 } else if (attrs->revid >= RID_C_STEPPING_START) {
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -080077 attrs->stepping = (attrs->revid - RID_C_STEPPING_START) / 2;
78 attrs->stepping += STEP_C0;
79 } else if (attrs->revid >= RID_B_STEPPING_START) {
Aaron Durbin452d31a2013-09-24 16:47:49 -050080 attrs->stepping = (attrs->revid - RID_B_STEPPING_START) / 2;
81 attrs->stepping += STEP_B0;
82 } 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) {
92 printk(BIOS_DEBUG, "BYT: cpuid %08x cpus %d rid %02x step %s\n",
93 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);
Aaron Durbin452d31a2013-09-24 16:47:49 -050099 fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO);
Duncan Laurie6aa9f1f2013-11-07 12:47:35 -0800100
101 /* Set IA core speed ratio and voltages */
102 msr = rdmsr(MSR_IACORE_RATIOS);
103 attrs->iacore_ratios[IACORE_MIN] = msr.lo & 0x7f;
104 attrs->iacore_ratios[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
105 attrs->iacore_ratios[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
106 msr = rdmsr(MSR_IACORE_TURBO_RATIOS);
107 attrs->iacore_ratios[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
108
109 msr = rdmsr(MSR_IACORE_VIDS);
110 attrs->iacore_vids[IACORE_MIN] = msr.lo & 0x7f;
111 attrs->iacore_vids[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
112 attrs->iacore_vids[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
113 msr = rdmsr(MSR_IACORE_TURBO_VIDS);
114 attrs->iacore_vids[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
115
116 /* Set bus clock speed */
117 attrs->bclk_khz = bus_freq_khz();
Aaron Durbin452d31a2013-09-24 16:47:49 -0500118}
119
Kyösti Mälkki4bd91872021-03-16 19:02:26 +0200120size_t size_of_dnvs(void)
121{
122 return sizeof(struct device_nvs);
123}
124
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800125/* Save bit index for first enabled event in PM1_STS for \_SB._SWS */
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200126static void pm_fill_gnvs(struct global_nvs *gnvs, const struct chipset_power_state *ps)
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800127{
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800128 uint16_t pm1;
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200129 int index;
130
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800131 pm1 = ps->pm1_sts & ps->pm1_en;
132
133 /* Scan for first set bit in PM1 */
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200134 for (index = 0; index < 16; index++) {
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800135 if (pm1 & 1)
136 break;
137 pm1 >>= 1;
138 }
139
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200140 if (index < 16)
141 gnvs->pm1i = index;
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800142}
143
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200144static void acpi_save_wake_source(void *unused)
145{
146 const struct chipset_power_state *ps;
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200147 struct global_nvs *gnvs;
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200148
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200149 if (acpi_reset_gnvs_for_wake(&gnvs) < 0)
150 return;
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200151 if (acpi_pm_state_for_wake(&ps) < 0)
152 return;
153
154 pm_fill_gnvs(gnvs, ps);
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200155
156 printk(BIOS_DEBUG, "ACPI System Wake Source is PM1 Index %d\n",
157 gnvs->pm1i);
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200158}
159
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200160BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, acpi_save_wake_source, NULL);
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200161
Kane Chenba9b7bf2015-01-17 08:19:54 +0800162static void baytrail_enable_2x_refresh_rate(void)
163{
164 u32 reg;
165 reg = iosf_dunit_read(0x8);
166 reg = reg & ~0x7000;
167 reg = reg | 0x2000;
168 iosf_dunit_write(0x8, reg);
169}
170
Kein Yuan35110232014-02-22 12:26:55 -0800171void baytrail_init_pre_device(struct soc_intel_baytrail_config *config)
Aaron Durbin452d31a2013-09-24 16:47:49 -0500172{
Kein Yuan35110232014-02-22 12:26:55 -0800173 struct soc_gpio_config *gpio_config;
Shawn Nematbakhshebe3b3c2013-09-26 16:44:14 -0700174
Aaron Durbin452d31a2013-09-24 16:47:49 -0500175 fill_in_pattrs();
Shawn Nematbakhshebe3b3c2013-09-26 16:44:14 -0700176
Kane Chenba9b7bf2015-01-17 08:19:54 +0800177 if (!config->disable_ddr_2x_refresh_rate)
178 baytrail_enable_2x_refresh_rate();
179
Aaron Durbin1ce0b302013-10-10 12:47:47 -0500180 /* Allow for SSE instructions to be executed. */
181 write_cr4(read_cr4() | CR4_OSFXSR | CR4_OSXMMEXCPT);
182
Aaron Durbinae5d83e2013-10-24 10:21:43 -0500183 /* Run reference code. */
184 baytrail_run_reference_code();
185
Shawn Nematbakhshebe3b3c2013-09-26 16:44:14 -0700186 /* Get GPIO initial states from mainboard */
Kein Yuan35110232014-02-22 12:26:55 -0800187 gpio_config = mainboard_get_gpios();
188 setup_soc_gpios(gpio_config, config->enable_xdp_tap);
Aaron Durbin6e77bee2013-10-30 15:25:42 -0500189
Aaron Durbinc626b742013-11-12 16:40:33 -0600190 baytrail_init_scc();
Aaron Durbin452d31a2013-09-24 16:47:49 -0500191}