Re-enable lpit
This commit is contained in:
@@ -720,6 +720,12 @@ config ACPI_NHLT
|
||||
help
|
||||
Build support for NHLT (non HD Audio) ACPI table generation.
|
||||
|
||||
config ACPI_LPIT
|
||||
bool
|
||||
default y
|
||||
help
|
||||
Build an ACPI Low Power Idle Table.
|
||||
|
||||
#These Options are here to avoid "undefined" warnings.
|
||||
#The actual selection and help texts are in the following menu.
|
||||
|
||||
|
@@ -1264,6 +1264,78 @@ void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
|
||||
acpi_checksum((void *) fadt, header->length);
|
||||
}
|
||||
|
||||
/*
|
||||
* The value of residency couneter register address is MSR value and
|
||||
* implementation specific.e.e.g, scenerios:
|
||||
* 1. For CNL: space_id:0,residency_counter.addrl:0x632 and ACPI_LPIT
|
||||
* selected in soc Kconfig sysfs file thet kernel creates is
|
||||
* /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us.
|
||||
* 2. For CNL: space_id:0, residency_counter.addrl:0xfe000000 + 0x193C
|
||||
* and ACPI_LPIT elected in soc Kconfig sysfs file thet kernel creates is
|
||||
* /sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us
|
||||
* which gets populated with integer values whenever system goes in s0ix.
|
||||
*/
|
||||
__weak void soc_residency_counter(struct acpi_lpit_native *lpit_soc)
|
||||
{
|
||||
lpit_soc->header.unique_id = 0;
|
||||
|
||||
lpit_soc->residency = 0x7530;
|
||||
lpit_soc->latency = 0xBB8;
|
||||
|
||||
lpit_soc->entry_trigger.space_id = 0x7f;
|
||||
lpit_soc->entry_trigger.bit_width = 0x01;
|
||||
lpit_soc->entry_trigger.bit_offset = 0x02;
|
||||
lpit_soc->entry_trigger.addrl = 0x60;
|
||||
|
||||
lpit_soc->residency_counter.space_id = 0x7f;
|
||||
lpit_soc->residency_counter.bit_width = 0x40;
|
||||
lpit_soc->residency_counter.addrl = 0x632;
|
||||
}
|
||||
|
||||
__weak void system_residency_counter(struct acpi_lpit_native *lpit_system)
|
||||
{
|
||||
lpit_system->header.unique_id = 1;
|
||||
|
||||
lpit_system->counter_frequency = 0x256c;
|
||||
lpit_system->residency = 0x7530;
|
||||
lpit_system->latency = 0xBB8;
|
||||
|
||||
lpit_system->entry_trigger.space_id = 0x7f;
|
||||
lpit_system->entry_trigger.bit_width = 0x01;
|
||||
lpit_system->entry_trigger.bit_offset = 0x02;
|
||||
lpit_system->entry_trigger.addrl = 0x60;
|
||||
|
||||
lpit_system->residency_counter.space_id = 0x00;
|
||||
lpit_system->residency_counter.bit_width = 0x20;
|
||||
lpit_system->residency_counter.access_size = 0x03;
|
||||
lpit_system->residency_counter.addrl = 0xfe00193c;
|
||||
}
|
||||
|
||||
static void acpi_create_lpit_generator(acpi_table_lpit *lpit)
|
||||
{
|
||||
acpi_header_t *header = &(lpit->header);
|
||||
|
||||
memset((void *)lpit, 0, sizeof(acpi_table_lpit));
|
||||
|
||||
memcpy(header->signature, "LPIT", 4);
|
||||
header->revision = 2; /* ACPI 1.0/2.0: ?, ACPI 3.0/4.0: 2 */
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
||||
header->oem_revision = 42;
|
||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||
header->asl_compiler_revision = 0;
|
||||
header->length = sizeof(acpi_table_lpit);
|
||||
lpit->lpit_soc.header.length = sizeof(struct acpi_lpit_native);
|
||||
lpit->lpit_system.header.length = sizeof(struct acpi_lpit_native);
|
||||
|
||||
soc_residency_counter(&lpit->lpit_soc);
|
||||
system_residency_counter(&lpit->lpit_system);
|
||||
|
||||
|
||||
/* (Re)calculate length and checksum. */
|
||||
header->checksum = acpi_checksum((void *)lpit, header->length);
|
||||
}
|
||||
|
||||
unsigned long __weak fw_cfg_acpi_tables(unsigned long start)
|
||||
{
|
||||
return 0;
|
||||
@@ -1284,6 +1356,7 @@ unsigned long write_acpi_tables(unsigned long start)
|
||||
acpi_tcpa_t *tcpa;
|
||||
acpi_tpm2_t *tpm2;
|
||||
acpi_madt_t *madt;
|
||||
acpi_table_lpit *lpit;
|
||||
struct device *dev;
|
||||
unsigned long fw;
|
||||
size_t slic_size, dsdt_size;
|
||||
@@ -1489,6 +1562,18 @@ unsigned long write_acpi_tables(unsigned long start)
|
||||
current += madt->header.length;
|
||||
acpi_add_table(rsdp, madt);
|
||||
}
|
||||
|
||||
if (CONFIG(ACPI_LPIT)) {
|
||||
printk(BIOS_DEBUG, "ACPI: * LPIT\n");
|
||||
|
||||
lpit = (acpi_table_lpit *)current;
|
||||
acpi_create_lpit_generator(lpit);
|
||||
if (lpit->header.length >= sizeof(acpi_table_lpit)) {
|
||||
current += lpit->header.length;
|
||||
acpi_add_table(rsdp, lpit);
|
||||
}
|
||||
}
|
||||
|
||||
current = acpi_align_current(current);
|
||||
|
||||
printk(BIOS_DEBUG, "current = %lx\n", current);
|
||||
|
@@ -257,6 +257,63 @@ typedef struct acpi_madt {
|
||||
u32 flags; /* Multiple APIC flags */
|
||||
} __packed acpi_madt_t;
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* LPIT - Low Power Idle Table
|
||||
*
|
||||
* Conforms to "ACPI Low Power Idle Table (LPIT)" July 2014.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct acpi_lpi_state_flags {
|
||||
u32 disabled:1;
|
||||
u32 counterunavailable:1;
|
||||
u32 reserved:30;
|
||||
} __packed acpi_lpi_state_flags;
|
||||
|
||||
/* LPIT subtable header */
|
||||
|
||||
typedef struct acpi_lpit_header {
|
||||
u32 type; /* Subtable type */
|
||||
u32 length; /* Subtable length */
|
||||
u16 unique_id;
|
||||
u16 reserved;
|
||||
acpi_lpi_state_flags flags;
|
||||
} __packed acpi_lpit_header;
|
||||
|
||||
/* Values for subtable Type above */
|
||||
|
||||
enum acpi_lpit_type {
|
||||
ACPI_LPIT_TYPE_NATIVE_CSTATE = 0x00,
|
||||
ACPI_LPIT_TYPE_RESERVED = 0x01 /* 1 and above are reserved */
|
||||
};
|
||||
|
||||
/* Masks for Flags field above */
|
||||
|
||||
#define ACPI_LPIT_STATE_DISABLED (1)
|
||||
#define ACPI_LPIT_NO_COUNTER (1<<1)
|
||||
|
||||
/*
|
||||
* LPIT subtables, correspond to Type in struct acpi_lpit_header
|
||||
*/
|
||||
|
||||
/* 0x00: Native C-state instruction based LPI structure */
|
||||
|
||||
struct acpi_lpit_native {
|
||||
struct acpi_lpit_header header;
|
||||
struct acpi_gen_regaddr entry_trigger;
|
||||
u32 residency;
|
||||
u32 latency;
|
||||
struct acpi_gen_regaddr residency_counter;
|
||||
u64 counter_frequency;
|
||||
};
|
||||
|
||||
typedef struct acpi_table_lpit {
|
||||
struct acpi_table_header header; /* Common ACPI table header */
|
||||
struct acpi_lpit_native lpit_soc;
|
||||
struct acpi_lpit_native lpit_system;
|
||||
} __packed acpi_table_lpit;
|
||||
|
||||
/* VFCT image header */
|
||||
typedef struct acpi_vfct_image_hdr {
|
||||
u32 PCIBus;
|
||||
@@ -897,6 +954,9 @@ struct acpi_spmi {
|
||||
|
||||
unsigned long fw_cfg_acpi_tables(unsigned long start);
|
||||
|
||||
void soc_residency_counter(struct acpi_lpit_native *lpit_soc);
|
||||
void system_residency_counter(struct acpi_lpit_native *lpit_system);
|
||||
|
||||
/* These are implemented by the target port or north/southbridge. */
|
||||
unsigned long write_acpi_tables(unsigned long addr);
|
||||
unsigned long acpi_fill_madt(unsigned long current);
|
||||
|
Reference in New Issue
Block a user