summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/acpi/acpigen.c72
-rw-r--r--src/include/acpi/acpi.h19
-rw-r--r--src/include/acpi/acpigen.h1
3 files changed, 92 insertions, 0 deletions
diff --git a/src/acpi/acpigen.c b/src/acpi/acpigen.c
index 1131729da5..5c8c1b98c1 100644
--- a/src/acpi/acpigen.c
+++ b/src/acpi/acpigen.c
@@ -803,6 +803,78 @@ void acpigen_write_STA_ext(const char *namestring)
acpigen_pop_len();
}
+void acpigen_write_LPI_package(u64 level, const struct acpi_lpi_state *states, u16 nentries)
+{
+ /*
+ * Name (_LPI, Package (0x06) // _LPI: Low Power Idle States
+ * {
+ * 0x0000,
+ * 0x0000000000000000,
+ * 0x0003,
+ * Package (0x0A)
+ * {
+ * 0x00000002,
+ * 0x00000001,
+ * 0x00000001,
+ * 0x00000000,
+ * 0x00000000,
+ * 0x00000000,
+ * ResourceTemplate ()
+ * {
+ * Register (FFixedHW,
+ * 0x02, // Bit Width
+ * 0x02, // Bit Offset
+ * 0x0000000000000000, // Address
+ * ,)
+ * },
+ *
+ * ResourceTemplate ()
+ * {
+ * Register (SystemMemory,
+ * 0x00, // Bit Width
+ * 0x00, // Bit Offset
+ * 0x0000000000000000, // Address
+ * ,)
+ * },
+ *
+ * ResourceTemplate ()
+ * {
+ * Register (SystemMemory,
+ * 0x00, // Bit Width
+ * 0x00, // Bit Offset
+ * 0x0000000000000000, // Address
+ * ,)
+ * },
+ *
+ * "C1"
+ * },
+ * ...
+ * }
+ */
+
+ acpigen_write_name("_LPI");
+ acpigen_write_package(3 + nentries);
+ acpigen_write_word(0); /* Revision */
+ acpigen_write_qword(level);
+ acpigen_write_word(nentries);
+
+ for (size_t i = 0; i < nentries; i++, states++) {
+ acpigen_write_package(0xA);
+ acpigen_write_dword(states->min_residency_us);
+ acpigen_write_dword(states->worst_case_wakeup_latency_us);
+ acpigen_write_dword(states->flags);
+ acpigen_write_dword(states->arch_context_lost_flags);
+ acpigen_write_dword(states->residency_counter_frequency_hz);
+ acpigen_write_dword(states->enabled_parent_state);
+ acpigen_write_register_resource(&states->entry_method);
+ acpigen_write_register_resource(&states->residency_counter_register);
+ acpigen_write_register_resource(&states->usage_counter_register);
+ acpigen_write_string(states->state_name);
+ acpigen_pop_len();
+ }
+ acpigen_pop_len();
+}
+
/*
* Generates a func with max supported P-states.
*/
diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h
index 932fb6fee8..7f086791c0 100644
--- a/src/include/acpi/acpi.h
+++ b/src/include/acpi/acpi.h
@@ -898,6 +898,25 @@ typedef struct acpi_tstate {
u32 status;
} __packed acpi_tstate_t;
+enum acpi_lpi_state_flags {
+ ACPI_LPI_STATE_DISABLED = 0,
+ ACPI_LPI_STATE_ENABLED
+};
+
+/* Low Power Idle State */
+struct acpi_lpi_state {
+ u32 min_residency_us;
+ u32 worst_case_wakeup_latency_us;
+ u32 flags;
+ u32 arch_context_lost_flags;
+ u32 residency_counter_frequency_hz;
+ u32 enabled_parent_state;
+ acpi_addr_t entry_method;
+ acpi_addr_t residency_counter_register;
+ acpi_addr_t usage_counter_register;
+ const char *state_name;
+};
+
/* Port types for ACPI _UPC object */
enum acpi_upc_type {
UPC_TYPE_A,
diff --git a/src/include/acpi/acpigen.h b/src/include/acpi/acpigen.h
index c79828819d..0e8d29a81f 100644
--- a/src/include/acpi/acpigen.h
+++ b/src/include/acpi/acpigen.h
@@ -338,6 +338,7 @@ inline void acpigen_write_device_end(void)
{
acpigen_pop_len();
}
+void acpigen_write_LPI_package(u64 level, const struct acpi_lpi_state *states, u16 nentries);
void acpigen_write_PPC(u8 nr);
void acpigen_write_PPC_NVS(void);
void acpigen_write_empty_PCT(void);