blob: 42f371ce3dedc0ccf1b33262dae70436e2335ee0 [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>
Kyösti Mälkki3139c8d2020-06-28 16:33:33 +03004#include <acpi/acpi_gnvs.h>
Kyösti Mälkki27872372021-01-21 16:05:26 +02005#include <acpi/acpi_pm.h>
Kyösti Mälkkid4b58252021-01-21 16:16:58 +02006#include <bootstate.h>
Aaron Durbin452d31a2013-09-24 16:47:49 -05007#include <console/console.h>
8#include <cpu/intel/microcode.h>
Aaron Durbin1ce0b302013-10-10 12:47:47 -05009#include <cpu/x86/cr.h>
Aaron Durbin452d31a2013-09-24 16:47:49 -050010#include <cpu/x86/msr.h>
11#include <device/device.h>
12#include <device/pci_def.h>
13#include <device/pci_ops.h>
Aaron Durbin452d31a2013-09-24 16:47:49 -050014
Kyösti Mälkki4bd91872021-03-16 19:02:26 +020015#include <soc/device_nvs.h>
Julius Werner18ea2d32014-10-07 16:42:17 -070016#include <soc/gpio.h>
17#include <soc/lpc.h>
18#include <soc/msr.h>
19#include <soc/nvs.h>
20#include <soc/pattrs.h>
21#include <soc/pci_devs.h>
Angel Ponsb5320b22020-07-07 18:27:30 +020022#include <soc/pm.h>
Julius Werner18ea2d32014-10-07 16:42:17 -070023#include <soc/ramstage.h>
Kane Chenba9b7bf2015-01-17 08:19:54 +080024#include <soc/iosf.h>
Aaron Durbin452d31a2013-09-24 16:47:49 -050025
Aaron Durbin452d31a2013-09-24 16:47:49 -050026#define SHOW_PATTRS 1
27
Angel Ponsbaebe2a2020-07-07 18:21:27 +020028struct pattrs __global_pattrs;
29
Aaron Durbin452d31a2013-09-24 16:47:49 -050030static void detect_num_cpus(struct pattrs *attrs)
31{
32 int ecx = 0;
33
34 while (1) {
35 struct cpuid_result leaf_b;
36
37 leaf_b = cpuid_ext(0xb, ecx);
38
39 /* Bay Trail doesn't have hyperthreading so just determine the
40 * number of cores by from level type (ecx[15:8] == * 2). */
41 if ((leaf_b.ecx & 0xff00) == 0x0200) {
42 attrs->num_cpus = leaf_b.ebx & 0xffff;
43 break;
44 }
45 ecx++;
46 }
47}
48
49static inline void fill_in_msr(msr_t *msr, int idx)
50{
51 *msr = rdmsr(idx);
52 if (SHOW_PATTRS) {
53 printk(BIOS_DEBUG, "msr(%x) = %08x%08x\n",
54 idx, msr->hi, msr->lo);
55 }
56}
57
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -080058static const char *stepping_str[] = {
Ben Gardner2d3d1b72015-11-19 16:12:21 -060059 "A0", "A1", "B0", "B1", "B2", "B3", "C0", "D0",
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -080060};
Aaron Durbin452d31a2013-09-24 16:47:49 -050061
62static void fill_in_pattrs(void)
63{
Elyes HAOUAS17a3ceb2018-05-22 10:42:28 +020064 struct device *dev;
Duncan Laurie6aa9f1f2013-11-07 12:47:35 -080065 msr_t msr;
Aaron Durbin452d31a2013-09-24 16:47:49 -050066 struct pattrs *attrs = (struct pattrs *)pattrs_get();
67
68 attrs->cpuid = cpuid_eax(1);
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030069 dev = pcidev_on_root(LPC_DEV, LPC_FUNC);
Aaron Durbin452d31a2013-09-24 16:47:49 -050070 attrs->revid = pci_read_config8(dev, REVID);
71 /* The revision to stepping IDs have two values per metal stepping. */
Ben Gardner2d3d1b72015-11-19 16:12:21 -060072 if (attrs->revid >= RID_D_STEPPING_START) {
73 attrs->stepping = (attrs->revid - RID_D_STEPPING_START) / 2;
74 attrs->stepping += STEP_D0;
75 } else if (attrs->revid >= RID_C_STEPPING_START) {
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -080076 attrs->stepping = (attrs->revid - RID_C_STEPPING_START) / 2;
77 attrs->stepping += STEP_C0;
78 } else if (attrs->revid >= RID_B_STEPPING_START) {
Aaron Durbin452d31a2013-09-24 16:47:49 -050079 attrs->stepping = (attrs->revid - RID_B_STEPPING_START) / 2;
80 attrs->stepping += STEP_B0;
81 } else {
82 attrs->stepping = (attrs->revid - RID_A_STEPPING_START) / 2;
83 attrs->stepping += STEP_A0;
84 }
85
86 attrs->microcode_patch = intel_microcode_find();
87 attrs->address_bits = cpuid_eax(0x80000008) & 0xff;
88 detect_num_cpus(attrs);
89
90 if (SHOW_PATTRS) {
91 printk(BIOS_DEBUG, "BYT: cpuid %08x cpus %d rid %02x step %s\n",
92 attrs->cpuid, attrs->num_cpus, attrs->revid,
93 (attrs->stepping >= ARRAY_SIZE(stepping_str)) ? "??" :
94 stepping_str[attrs->stepping]);
95 }
96
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +020097 fill_in_msr(&attrs->platform_id, IA32_PLATFORM_ID);
Aaron Durbin452d31a2013-09-24 16:47:49 -050098 fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO);
Duncan Laurie6aa9f1f2013-11-07 12:47:35 -080099
100 /* Set IA core speed ratio and voltages */
101 msr = rdmsr(MSR_IACORE_RATIOS);
102 attrs->iacore_ratios[IACORE_MIN] = msr.lo & 0x7f;
103 attrs->iacore_ratios[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
104 attrs->iacore_ratios[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
105 msr = rdmsr(MSR_IACORE_TURBO_RATIOS);
106 attrs->iacore_ratios[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
107
108 msr = rdmsr(MSR_IACORE_VIDS);
109 attrs->iacore_vids[IACORE_MIN] = msr.lo & 0x7f;
110 attrs->iacore_vids[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
111 attrs->iacore_vids[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
112 msr = rdmsr(MSR_IACORE_TURBO_VIDS);
113 attrs->iacore_vids[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
114
115 /* Set bus clock speed */
116 attrs->bclk_khz = bus_freq_khz();
Aaron Durbin452d31a2013-09-24 16:47:49 -0500117}
118
Kyösti Mälkki4bd91872021-03-16 19:02:26 +0200119size_t size_of_dnvs(void)
120{
121 return sizeof(struct device_nvs);
122}
123
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800124/* Save bit index for first enabled event in PM1_STS for \_SB._SWS */
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200125static void pm_fill_gnvs(struct global_nvs *gnvs, const struct chipset_power_state *ps)
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800126{
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800127 uint16_t pm1;
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200128 int index;
129
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800130 pm1 = ps->pm1_sts & ps->pm1_en;
131
132 /* Scan for first set bit in PM1 */
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200133 for (index = 0; index < 16; index++) {
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800134 if (pm1 & 1)
135 break;
136 pm1 >>= 1;
137 }
138
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200139 if (index < 16)
140 gnvs->pm1i = index;
Shawn Nematbakhsh51d787a2014-01-16 17:52:21 -0800141}
142
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200143static void acpi_save_wake_source(void *unused)
144{
145 const struct chipset_power_state *ps;
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200146 struct global_nvs *gnvs;
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200147
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200148 if (acpi_reset_gnvs_for_wake(&gnvs) < 0)
149 return;
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200150 if (acpi_pm_state_for_wake(&ps) < 0)
151 return;
152
153 pm_fill_gnvs(gnvs, ps);
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200154
155 printk(BIOS_DEBUG, "ACPI System Wake Source is PM1 Index %d\n",
156 gnvs->pm1i);
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200157}
158
Kyösti Mälkki4de1a312021-01-15 05:58:42 +0200159BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, acpi_save_wake_source, NULL);
Kyösti Mälkkid4b58252021-01-21 16:16:58 +0200160
Kane Chenba9b7bf2015-01-17 08:19:54 +0800161static void baytrail_enable_2x_refresh_rate(void)
162{
163 u32 reg;
164 reg = iosf_dunit_read(0x8);
165 reg = reg & ~0x7000;
166 reg = reg | 0x2000;
167 iosf_dunit_write(0x8, reg);
168}
169
Kein Yuan35110232014-02-22 12:26:55 -0800170void baytrail_init_pre_device(struct soc_intel_baytrail_config *config)
Aaron Durbin452d31a2013-09-24 16:47:49 -0500171{
Kein Yuan35110232014-02-22 12:26:55 -0800172 struct soc_gpio_config *gpio_config;
Shawn Nematbakhshebe3b3c2013-09-26 16:44:14 -0700173
Aaron Durbin452d31a2013-09-24 16:47:49 -0500174 fill_in_pattrs();
Shawn Nematbakhshebe3b3c2013-09-26 16:44:14 -0700175
Kane Chenba9b7bf2015-01-17 08:19:54 +0800176 if (!config->disable_ddr_2x_refresh_rate)
177 baytrail_enable_2x_refresh_rate();
178
Aaron Durbin1ce0b302013-10-10 12:47:47 -0500179 /* Allow for SSE instructions to be executed. */
180 write_cr4(read_cr4() | CR4_OSFXSR | CR4_OSXMMEXCPT);
181
Aaron Durbinae5d83e2013-10-24 10:21:43 -0500182 /* Run reference code. */
183 baytrail_run_reference_code();
184
Shawn Nematbakhshebe3b3c2013-09-26 16:44:14 -0700185 /* Get GPIO initial states from mainboard */
Kein Yuan35110232014-02-22 12:26:55 -0800186 gpio_config = mainboard_get_gpios();
187 setup_soc_gpios(gpio_config, config->enable_xdp_tap);
Aaron Durbin6e77bee2013-10-30 15:25:42 -0500188
Aaron Durbinc626b742013-11-12 16:40:33 -0600189 baytrail_init_scc();
Aaron Durbin452d31a2013-09-24 16:47:49 -0500190}