Skip to content

Commit

Permalink
soc/intel/{adl, common}: provide a list of D-states to enter LPM
Browse files Browse the repository at this point in the history
This was done previously for ADL. moving the code to common so
it can be leveraged for other platforms (e.g. MTL)

TEST=Built and tested on anahera by verifying SSDT contents

Change-Id: I45eded3868a4987cb5eb0676c50378ac52ec3752
Signed-off-by: Eran Mitrani <mitrani@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/70166
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Subrata Banik <subratabanik@google.com>
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
  • Loading branch information
emitrani-g authored and Martin Roth committed Dec 15, 2022
1 parent d27cd2a commit 4c9440c
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 170 deletions.
4 changes: 1 addition & 3 deletions src/include/acpi/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ enum acpi_device_sleep_states {
ACPI_DEVICE_SLEEP_D3 = 3,
ACPI_DEVICE_SLEEP_D3_HOT = ACPI_DEVICE_SLEEP_D3,
ACPI_DEVICE_SLEEP_D3_COLD = 4,
ACPI_DEVICE_SLEEP_NONE = 5,
};

#define RSDP_SIG "RSD PTR " /* RSDT pointer signature */
Expand Down Expand Up @@ -1283,7 +1284,6 @@ typedef struct acpi_einj {
acpi_einj_action_table_t action_table[ACTION_COUNT];
} __packed acpi_einj_t;


uintptr_t get_coreboot_rsdp(void);
void acpi_create_einj(acpi_einj_t *einj, uintptr_t addr, u8 actions);

Expand All @@ -1298,8 +1298,6 @@ void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id);
void acpi_write_bert(acpi_bert_t *bert, uintptr_t region, size_t length);
void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt);

void soc_lpi_get_constraints(void *unused);

void acpi_fill_fadt(acpi_fadt_t *fadt);
void arch_fill_fadt(acpi_fadt_t *fadt);
void soc_fill_fadt(acpi_fadt_t *fadt);
Expand Down
221 changes: 59 additions & 162 deletions src/soc/intel/alderlake/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,6 @@
#include <cpu/cpu.h>
#include <types.h>


#define DEFAULT_CPU_D_STATE D0
#define LPI_STATES_ALL 0xff
#define LPI_REVISION 0
#define LPI_ENABLED 1


/*
* List of supported C-states in this processor.
*/
Expand Down Expand Up @@ -119,14 +112,6 @@ static int cstate_set_s0ix[] = {
C_STATE_C10
};

enum dev_sleep_states {
D0, /* 0 */
D1, /* 1 */
D2, /* 2 */
D3, /* 3 */
NONE
};

const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
{
static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix),
Expand Down Expand Up @@ -181,156 +166,68 @@ void soc_fill_fadt(acpi_fadt_t *fadt)
fadt->flags |= ACPI_FADT_LOW_PWR_IDLE_S0;
}

static const struct {
uint8_t pci_dev;
enum dev_sleep_states min_sleep_state;
} min_pci_sleep_states[] = {
{ SA_DEVFN_ROOT, D3 },
{ SA_DEVFN_CPU_PCIE1_0, D3 },
{ SA_DEVFN_IGD, D3 },
{ SA_DEVFN_DPTF, D3 },
{ SA_DEVFN_IPU, D3 },
{ SA_DEVFN_CPU_PCIE6_0, D3 },
{ SA_DEVFN_CPU_PCIE6_2, D3 },
{ SA_DEVFN_TBT0, D3 },
{ SA_DEVFN_TBT1, D3 },
{ SA_DEVFN_TBT2, D3 },
{ SA_DEVFN_TBT3, D3 },
{ SA_DEVFN_GNA, D3 },
{ SA_DEVFN_TCSS_XHCI, D3 },
{ SA_DEVFN_TCSS_XDCI, D3 },
{ SA_DEVFN_TCSS_DMA0, D3 },
{ SA_DEVFN_TCSS_DMA1, D3 },
{ SA_DEVFN_VMD, D3 },
{ PCH_DEVFN_I2C6, D3 },
{ PCH_DEVFN_I2C7, D3 },
{ PCH_DEVFN_THC0, D3 },
{ PCH_DEVFN_THC1, D3 },
{ PCH_DEVFN_XHCI, D3 },
{ PCH_DEVFN_USBOTG, D3 },
{ PCH_DEVFN_SRAM, D3 },
{ PCH_DEVFN_CNVI_WIFI, D3 },
{ PCH_DEVFN_I2C0, D3 },
{ PCH_DEVFN_I2C1, D3 },
{ PCH_DEVFN_I2C2, D3 },
{ PCH_DEVFN_I2C3, D3 },
{ PCH_DEVFN_CSE, D0 },
{ PCH_DEVFN_SATA, D3 },
{ PCH_DEVFN_I2C4, D3 },
{ PCH_DEVFN_I2C5, D3 },
{ PCH_DEVFN_UART2, D3 },
{ PCH_DEVFN_PCIE1, D0 },
{ PCH_DEVFN_PCIE2, D0 },
{ PCH_DEVFN_PCIE3, D0 },
{ PCH_DEVFN_PCIE4, D0 },
{ PCH_DEVFN_PCIE5, D0 },
{ PCH_DEVFN_PCIE6, D0 },
{ PCH_DEVFN_PCIE7, D0 },
{ PCH_DEVFN_PCIE8, D0 },
{ PCH_DEVFN_PCIE9, D0 },
{ PCH_DEVFN_PCIE10, D0 },
{ PCH_DEVFN_PCIE11, D0 },
{ PCH_DEVFN_PCIE12, D0 },
{ PCH_DEVFN_UART0, D3 },
{ PCH_DEVFN_UART1, D3 },
{ PCH_DEVFN_GSPI0, D3 },
{ PCH_DEVFN_GSPI1, D3 },
{ PCH_DEVFN_ESPI, D0 },
{ PCH_DEVFN_PMC, D0 },
{ PCH_DEVFN_HDA, D0 },
{ PCH_DEVFN_SPI, D3 },
{ PCH_DEVFN_GBE, D3 },
static struct min_sleep_state min_pci_sleep_states[] = {
{ SA_DEVFN_ROOT, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_CPU_PCIE1_0, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_IGD, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_DPTF, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_IPU, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_CPU_PCIE6_0, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_CPU_PCIE6_2, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_TBT0, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_TBT1, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_TBT2, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_TBT3, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_GNA, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_TCSS_XHCI, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_TCSS_XDCI, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_TCSS_DMA0, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_TCSS_DMA1, ACPI_DEVICE_SLEEP_D3 },
{ SA_DEVFN_VMD, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_I2C6, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_I2C7, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_THC0, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_THC1, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_XHCI, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_USBOTG, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_SRAM, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_CNVI_WIFI, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_I2C0, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_I2C1, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_I2C2, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_I2C3, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_CSE, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_SATA, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_I2C4, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_I2C5, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_UART2, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_PCIE1, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE2, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE3, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE4, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE5, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE6, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE7, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE8, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE9, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE10, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE11, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PCIE12, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_UART0, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_UART1, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_GSPI0, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_GSPI1, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_ESPI, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_PMC, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_HDA, ACPI_DEVICE_SLEEP_D0 },
{ PCH_DEVFN_SPI, ACPI_DEVICE_SLEEP_D3 },
{ PCH_DEVFN_GBE, ACPI_DEVICE_SLEEP_D3 },
};

static enum dev_sleep_states get_min_sleep_state(const struct device *dev)
struct min_sleep_state *soc_get_min_sleep_state_array(size_t *size)
{
if (!is_dev_enabled(dev))
return NONE;

switch (dev->path.type) {
case DEVICE_PATH_APIC:
return DEFAULT_CPU_D_STATE;

case DEVICE_PATH_PCI:
/* skip external buses*/
if (dev->bus->secondary != 0)
return NONE;
for (size_t i = 0; i < ARRAY_SIZE(min_pci_sleep_states); i++)
if (min_pci_sleep_states[i].pci_dev == dev->path.pci.devfn)
return min_pci_sleep_states[i].min_sleep_state;
printk(BIOS_WARNING, "Unknown min d_state for %x\n", dev->path.pci.devfn);
return NONE;

default:
return NONE;
}
}

/* Generate the LPI constraint table and return the number of devices included */
void soc_lpi_get_constraints(void *unused)
{
unsigned int num_entries;
const struct device *dev;
enum dev_sleep_states min_sleep_state;

num_entries = 0;

for (dev = all_devices; dev; dev = dev->next) {
if (get_min_sleep_state(dev) != NONE)
num_entries++;
}

acpigen_emit_byte(RETURN_OP);
acpigen_write_package(num_entries);

size_t cpu_index = 0;
for (dev = all_devices; dev; dev = dev->next) {
min_sleep_state = get_min_sleep_state(dev);
if (min_sleep_state == NONE)
continue;

acpigen_write_package(3);
{
char path[32] = { 0 };
/* Emit the device path */
switch (dev->path.type) {
case DEVICE_PATH_PCI:
acpigen_emit_namestring(acpi_device_path(dev));
break;

case DEVICE_PATH_APIC:
snprintf(path, sizeof(path), CONFIG_ACPI_CPU_STRING,
cpu_index++);
acpigen_emit_namestring(path);
break;

default:
/* Unhandled */
printk(BIOS_WARNING,
"Unhandled device path type %d\n", dev->path.type);
acpigen_emit_namestring(NULL);
break;
}

acpigen_write_integer(LPI_ENABLED);
acpigen_write_package(2);
{
acpigen_write_integer(LPI_REVISION);
acpigen_write_package(2); /* no optional device info */
{
/* Assume constraints apply to all entries */
acpigen_write_integer(LPI_STATES_ALL);
acpigen_write_integer(min_sleep_state); /* min D-state */
}
acpigen_write_package_end();
}
acpigen_write_package_end();
}
acpigen_write_package_end();
}

acpigen_write_package_end();
printk(BIOS_INFO, "Returning SoC specific constraint package for %d devices\n", num_entries);
*size = ARRAY_SIZE(min_pci_sleep_states);
return min_pci_sleep_states;
}

uint32_t soc_read_sci_irq_select(void)
Expand Down
2 changes: 1 addition & 1 deletion src/soc/intel/common/block/acpi/acpi.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <acpi/acpi.h>
#include <acpi/acpi_pm.h>
#include <acpi/acpigen.h>
#include <arch/ioapic.h>
Expand Down Expand Up @@ -69,7 +70,6 @@ static unsigned long acpi_madt_irq_overrides(unsigned long current)
current +=
acpi_create_madt_irqoverride((void *)current, 0, sci, sci, flags);


return current;
}

Expand Down

0 comments on commit 4c9440c

Please sign in to comment.