feat: power down dGPUs on hybrid graphics laptops
This commit is contained in:
1 parent
7f12e1a150
commit
24f88ec4c6
23 files changed
+4325
-1130
No files matched your search
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* AcpiPower.hpp
|
||||
* ACPI device power management: _PSx methods, _PRx power resources,
|
||||
* _DSM calls, and finding the namespace node behind a PCI function
|
||||
* Copyright (c) 2026 Daniel Hammer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <ACPI/AML/AmlNamespace.hpp>
|
||||
|
||||
namespace Hal {
|
||||
namespace AcpiPower {
|
||||
|
||||
// ============================================================================
|
||||
|
||||
// PCI <-> ACPI
|
||||
|
||||
// ============================================================================
|
||||
// The Device node describing PCI function bus:dev.fn, or -1. When
|
||||
// firmware declares more than one node at the same address (a generic
|
||||
// placeholder plus a vendor SSDT's real one is common for GPUs), the
|
||||
// one carrying power-management objects wins.
|
||||
int32_t FindPciDevice(uint8_t bus, uint8_t dev, uint8_t fn);
|
||||
|
||||
// Forget the PCI address map built by FindPciDevice (bus numbers may
|
||||
// change across a resume).
|
||||
void InvalidatePciMap();
|
||||
|
||||
// True when `device` has a child object named `name` ("_PS3").
|
||||
bool HasObject(int32_t device, const char* name);
|
||||
|
||||
// ============================================================================
|
||||
|
||||
// Power resources
|
||||
|
||||
// ============================================================================
|
||||
static constexpr int MaxResources = 8;
|
||||
|
||||
// The power resources the device lists in _PR0.._PR3 (deduplicated).
|
||||
int CollectResources(int32_t device, int32_t* out, int max);
|
||||
|
||||
// _STA of a power resource: 1 on, 0 off, -1 unknown.
|
||||
int ResourceState(int32_t resource);
|
||||
|
||||
// ============================================================================
|
||||
|
||||
// Device power transitions
|
||||
|
||||
// ============================================================================
|
||||
struct D3ColdReport {
|
||||
bool RanPs3;
|
||||
int ResourcesOff; // resources whose _OFF was run
|
||||
int ResourcesShared; // left on: some other present device needs them
|
||||
int ResourcesStillOn; // _OFF ran but _STA still says on
|
||||
};
|
||||
|
||||
// Put an ACPI device into D3cold the way the spec orders it: _PS3,
|
||||
// then every power resource it depends on off, last-listed first. A
|
||||
// resource that a device outside `owners` also depends on is left
|
||||
// on -- `owners` lists the nodes being powered down together (the
|
||||
// functions of one card and the port above them), which may freely
|
||||
// share, as may anything below them in the namespace. The PCI side
|
||||
// (PMCSR to D3hot) is the caller's to do first.
|
||||
void EnterD3Cold(int32_t device, const int32_t* owners, int ownerCount,
|
||||
D3ColdReport& report);
|
||||
|
||||
// ============================================================================
|
||||
|
||||
// _DSM
|
||||
|
||||
// ============================================================================
|
||||
// Evaluate _DSM(uuid, revision, function, arg3) on a device. False
|
||||
// when the device has no _DSM or it failed.
|
||||
bool EvaluateDsm(int32_t device, const uint8_t uuid[16], uint64_t revision,
|
||||
uint64_t function, const AML::Object& arg3, AML::Object& result);
|
||||
|
||||
// The function bitmap _DSM function 0 reports for (uuid, revision),
|
||||
// 0 when unsupported. Bit 0 set means "some functions exist".
|
||||
uint64_t DsmFunctions(int32_t device, const uint8_t uuid[16], uint64_t revision,
|
||||
const AML::Object& arg3);
|
||||
|
||||
// Helpers for building _DSM / method arguments.
|
||||
AML::Object IntegerArg(uint64_t value);
|
||||
AML::Object BufferArg(const uint8_t* bytes, uint32_t length);
|
||||
AML::Object EmptyPackageArg();
|
||||
|
||||
// Integer value of a method result: an integer as is, a buffer read
|
||||
// little-endian (up to 8 bytes).
|
||||
uint64_t ResultInteger(const AML::Object& result);
|
||||
};
|
||||
};
|
||||
Reference in new issue
Block a user