soc/intel/xeon_sp: Drop uncore_fill_ssdt
[coreboot2.git] / src / soc / intel / xeon_sp / spr / soc_acpi.c
blob607ee6c36dab7985f88feaef9fb7a97cc41e6330
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpigen.h>
4 #include <arch/smp/mpspec.h>
5 #include <arch/vga.h>
6 #include <assert.h>
7 #include <cbmem.h>
8 #include <cpu/intel/turbo.h>
9 #include <device/mmio.h>
10 #include <device/pci.h>
11 #include <intelblocks/acpi.h>
12 #include <intelblocks/cpulib.h>
13 #include <intelblocks/pmclib.h>
14 #include <soc/acpi.h>
15 #include <soc/iomap.h>
16 #include <soc/msr.h>
17 #include <soc/pci_devs.h>
18 #include <soc/pm.h>
19 #include <soc/soc_util.h>
20 #include <soc/util.h>
21 #include <hob_iiouds.h>
23 int soc_madt_sci_irq_polarity(int sci)
25 if (sci >= 20)
26 return MP_IRQ_POLARITY_LOW;
27 else
28 return MP_IRQ_POLARITY_HIGH;
31 uint32_t soc_read_sci_irq_select(void)
33 /* PMC controller is hidden - hence PWRMBASE can't be accessbile using PCI cfg space */
34 uintptr_t pmc_bar = PCH_PWRM_BASE_ADDRESS;
35 return read32((void *)pmc_bar + PMC_ACPI_CNT);
38 void soc_fill_fadt(acpi_fadt_t *fadt)
40 const uint16_t pmbase = ACPI_BASE_ADDRESS;
42 fadt->FADT_MinorVersion = 1;
43 fadt->pm_tmr_blk = pmbase + PM1_TMR;
44 fadt->pm_tmr_len = 4;
45 /* Clear flags set by common/block/acpi/acpi.c acpi_fill_fadt() */
46 fadt->flags &= ~ACPI_FADT_SEALED_CASE;
48 fadt->preferred_pm_profile = PM_ENTERPRISE_SERVER;
49 fadt->pm2_cnt_blk = pmbase + PM2_CNT;
50 fadt->pm2_cnt_len = 1;
52 /* PM Extended Registers */
53 fill_fadt_extended_pm_io(fadt);
56 /* TODO: See if we can use the common generate_p_state_entries */
57 void soc_power_states_generation(int core, int cores_per_package)
59 int ratio_min, ratio_max, ratio_turbo, ratio_step;
60 int coord_type, power_max, power_unit, num_entries;
61 int ratio, power, clock, clock_max;
62 msr_t msr;
64 /* Determine P-state coordination type from MISC_PWR_MGMT[0] */
65 msr = rdmsr(MSR_MISC_PWR_MGMT);
66 if (msr.lo & MISC_PWR_MGMT_EIST_HW_DIS)
67 coord_type = SW_ANY;
68 else
69 coord_type = HW_ALL;
71 /* Get bus ratio limits and calculate clock speeds */
72 msr = rdmsr(MSR_PLATFORM_INFO);
73 ratio_min = (msr.hi >> (40 - 32)) & 0xff; /* Max Efficiency Ratio */
75 /* Determine if this CPU has configurable TDP */
76 if (cpu_config_tdp_levels()) {
77 /* Set max ratio to nominal TDP ratio */
78 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
79 ratio_max = msr.lo & 0xff;
80 } else {
81 /* Max Non-Turbo Ratio */
82 ratio_max = (msr.lo >> 8) & 0xff;
84 clock_max = ratio_max * CONFIG_CPU_BCLK_MHZ;
86 /* Calculate CPU TDP in mW */
87 msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
88 power_unit = 2 << ((msr.lo & 0xf) - 1);
89 msr = rdmsr(MSR_PKG_POWER_SKU);
90 power_max = ((msr.lo & 0x7fff) / power_unit) * 1000;
92 /* Write _PCT indicating use of FFixedHW */
93 acpigen_write_empty_PCT();
95 /* Write _PPC with no limit on supported P-state */
96 acpigen_write_PPC_NVS();
98 /* Write PSD indicating configured coordination type */
99 acpigen_write_PSD_package(core, 1, coord_type);
101 /* Add P-state entries in _PSS table */
102 acpigen_write_name("_PSS");
104 /* Determine ratio points */
105 ratio_step = PSS_RATIO_STEP;
106 num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
107 if (num_entries > PSS_MAX_ENTRIES) {
108 ratio_step += 1;
109 num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
112 /* P[T] is Turbo state if enabled */
113 if (get_turbo_state() == TURBO_ENABLED) {
114 /* _PSS package count including Turbo */
115 acpigen_write_package(num_entries + 2);
117 msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
118 ratio_turbo = msr.lo & 0xff;
120 /* Add entry for Turbo ratio */
121 acpigen_write_PSS_package(clock_max + 1, /* MHz */
122 power_max, /* mW */
123 PSS_LATENCY_TRANSITION, /* lat1 */
124 PSS_LATENCY_BUSMASTER, /* lat2 */
125 ratio_turbo << 8, /* control */
126 ratio_turbo << 8); /* status */
127 } else {
128 /* _PSS package count without Turbo */
129 acpigen_write_package(num_entries + 1);
132 /* First regular entry is max non-turbo ratio */
133 acpigen_write_PSS_package(clock_max, /* MHz */
134 power_max, /* mW */
135 PSS_LATENCY_TRANSITION, /* lat1 */
136 PSS_LATENCY_BUSMASTER, /* lat2 */
137 ratio_max << 8, /* control */
138 ratio_max << 8); /* status */
140 /* Generate the remaining entries */
141 for (ratio = ratio_min + ((num_entries - 1) * ratio_step); ratio >= ratio_min;
142 ratio -= ratio_step) {
144 /* Calculate power at this ratio */
145 power = common_calculate_power_ratio(power_max, ratio_max, ratio);
146 clock = ratio * CONFIG_CPU_BCLK_MHZ;
147 // clock = 1;
148 acpigen_write_PSS_package(clock, /* MHz */
149 power, /* mW */
150 PSS_LATENCY_TRANSITION, /* lat1 */
151 PSS_LATENCY_BUSMASTER, /* lat2 */
152 ratio << 8, /* control */
153 ratio << 8); /* status */
156 /* Fix package length */
157 acpigen_pop_len();
160 unsigned long xeonsp_acpi_create_madt_lapics(unsigned long current)
162 struct device *cpu;
163 uint8_t num_cpus = 0;
165 for (cpu = all_devices; cpu; cpu = cpu->next) {
166 if ((cpu->path.type != DEVICE_PATH_APIC)
167 || (cpu->upstream->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) {
168 continue;
170 if (!cpu->enabled)
171 continue;
172 current = acpi_create_madt_one_lapic(current, num_cpus, cpu->path.apic.apic_id);
173 num_cpus++;
176 return current;
179 unsigned long acpi_fill_cedt(unsigned long current)
181 const IIO_UDS *hob = get_iio_uds();
182 union uid {
183 uint32_t data;
184 struct {
185 uint8_t byte0;
186 uint8_t byte1;
187 uint8_t byte2;
188 uint8_t byte3;
190 } cxl_uid;
191 u32 cxl_ver;
192 u64 base;
194 cxl_uid.byte0 = 'C';
195 cxl_uid.byte1 = 'X';
196 /* Loop through all sockets and stacks, add CHBS for each CXL IIO stack */
197 for (uint8_t socket = 0, iio = 0; iio < hob->PlatformData.numofIIO; ++socket) {
198 if (!soc_cpu_is_enabled(socket))
199 continue;
200 iio++;
201 for (int x = 0; x < MAX_LOGIC_IIO_STACK; ++x) {
202 const STACK_RES *ri;
203 ri = &hob->PlatformData.IIO_resource[socket].StackRes[x];
204 if (!is_iio_cxl_stack_res(ri))
205 continue;
206 /* uid needs to match with ACPI CXL device ID, eg. acpi/iiostack.asl */
207 cxl_uid.byte2 = socket + '0';
208 cxl_uid.byte3 = x + '0';
209 cxl_ver = ACPI_CEDT_CHBS_CXL_VER_1_1;
210 base = ri->Mmio32Base; /* DP RCRB base */
211 current += acpi_create_cedt_chbs((acpi_cedt_chbs_t *)current,
212 cxl_uid.data, cxl_ver, base);
216 return current;