blob: 74b137c0e0c8471a28fc6b40484a9e519d4a19b5 [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// The system activity governor (SAG) is a subsystem of the power framework
/// that manages the execution and suspend state of the hardware platform. It
/// also allows observers to watch for suspend/resume transitions of the
/// platform.
///
/// Other components can create dependencies on SAG's power elements with
/// [`fuchsia.power.broker/ElementControl`] to influence SAG's behavior
/// including preventing system suspension and/or changing the platform resume
/// latency for the next suspension.
///
/// The power elements that SAG creates and manages are as follows:
/// * [`fuchsia.power.system/ExecutionState`]
/// * [`fuchsia.power.system/ExecutionResumeLatency`]
/// * [`fuchsia.power.system/WakeHandling`]
/// * [`fuchsia.power.system/FullWakeHandling`]
/// * [`fuchsia.power.system/ApplicationActivity`]
///
/// # Internal Dependency Diagram
/// ```
/// +--------------------+ +---------------------------------+
/// | **ExecutionState** | | **ApplicationActivity** |
/// +--------------------+ +---------------------------------+
/// | ACTIVE |<-----------------| ACTIVE |
/// +--------------------+ +---------------------------------+
/// | WAKE_HANDLING |<--------+ | INACTIVE |
/// | |<------+ | +---------------------------------+
/// +--------------------+ | |
/// | INACTIVE | | | +---------------------------------+
/// +--------------------+ | | | **WakeHandling** |
/// | | +---------------------------------+
/// | +--------| ACTIVE |
/// | +---------------------------------+
/// | | INACTIVE |
/// | +---------------------------------+
/// |
/// | +---------------------------------+
/// | | **FullWakeHandling** |
/// | +---------------------------------+
/// +----------| ACTIVE |
/// +---------------------------------+
/// | INACTIVE |
/// +---------------------------------+
///
/// +---------------------------------+
/// | **ExecutionResumeLatency** |
/// +---------------------------------+
/// | SUSPEND_STATE_N |
/// +---------------------------------+
/// | ... |
/// +---------------------------------+
/// | SUSPEND_STATE_1 |
/// +---------------------------------+
/// | SUSPEND_STATE_0 |
/// +---------------------------------+
/// ```
///
/// # Usage
///
/// To prevent system suspension, a component can create an active dependency
/// using the `active_dependency_token` from `ApplicationActivity` or
/// `WakeHandling`. If the dependency causes the power level of
/// `ApplicationActivity` and/or `WakeHandling` to be raised to
/// [`fuchsia.power.system/ApplicationActivityPowerLevel.ACTIVE`] and/or
/// [`fuchsia.power.system/WakeHandlingPowerLevel.ACTIVE`], respectively, SAG
/// will not trigger system suspension until their power levels drop to
/// `INACTIVE`.
///
/// To change the platform resume latency, a component can create an active
/// dependency using the `active_dependency_token` from
/// `ExecutionResumeLatency`. If the dependency causes the power level of
/// `ExecutionResumeLatency` to be raised, SAG will request a suspend state with
/// an appropriate resume latency for that power level.
///
/// If a component is managing a power element that requires the platform to be
/// in a specific state, a passive dependency can be created on
/// `ExecutionState`. When `ExecutionState` changes its power level, all
/// dependent power elements will power down first. Ideally, this forces the
/// entire system into a configuration with a lower power consumption as the
/// power level of `ExecutionState` decreases.
@available(added=HEAD)
library fuchsia.power.system;
using fuchsia.power.broker;
using zx;
/// Holds a token to the execution state power element.
///
/// Power elements intentionally cannot take active dependencies on this power
/// element. Elements that need to force the execution state to ACTIVE can use
/// ApplicationActivity which provides more semantic meaning to the
/// dependencies.
///
/// [`fuchsia.power.system/ExecutionStateLevel`] defines the power levels supported by this power element.
type ExecutionState = resource table {
1: passive_dependency_token fuchsia.power.broker.DependencyToken;
};
/// Execution state power levels
///
/// Elements should take a passive dependency on `ExecutionStateLevel::ACTIVE`
/// to ensure that the element will be suspended when the rest of the system
/// suspends.
///
/// Drivers can take a passive dependency on either
/// `ExecutionStateLevel::WAKE_HANDLING` or `ExecutionStateLevel::ACTIVE` and
/// request a persistent lease on this state to ensure that their element's
/// power level is always activated when the system comes out of a suspend
/// state.
type ExecutionStateLevel = flexible enum : uint8 {
INACTIVE = 0;
WAKE_HANDLING = 1;
ACTIVE = 2;
};
/// Holds tokens to the execution resume latency power element and its
/// supported resume latencies.
///
/// The execution resume latency power element represents the
/// suspension-to-resume delay that must be met by the hardware platform.
///
/// The execution resume latency power element's power levels are platform and
/// hardware dependent. The power levels supported by the power element match
/// the index of the resume latency in the table, i.e. The item at index 0 in
/// `resume_latencies` is represented by power level 0, the item at index 1 is
/// represented by power level 1, and so on.
type ExecutionResumeLatency = resource table {
1: passive_dependency_token fuchsia.power.broker.DependencyToken;
2: active_dependency_token fuchsia.power.broker.DependencyToken;
3: resume_latencies vector<zx.Duration>:MAX;
};
/// Holds tokens to the full wake handling power element.
///
/// [`fuchsia.power.system/FullWakeHandlingLevel`] defines the power levels supported by this power element.
type FullWakeHandling = resource table {
1: active_dependency_token fuchsia.power.broker.DependencyToken;
};
/// Full wake handling power levels
///
/// Driver power elements should take an active dependency on
/// `FullWakeHandlingLevel::ACTIVE` if it expects the system to perform a full
/// wakeup. While the drivers are handling a wake event, they should request a
/// lease to pull the state to Active, and drop the release once the event is
/// fully handled.
type FullWakeHandlingLevel = flexible enum : uint8 {
INACTIVE = 0;
ACTIVE = 1;
};
/// Holds tokens to the wake handling power element.
///
/// [`fuchsia.power.system/WakeHandlingLevel`] defines the power levels supported by this power element.
type WakeHandling = resource table {
1: active_dependency_token fuchsia.power.broker.DependencyToken;
};
/// Wake handling power levels
///
/// Driver power elements should take an active dependency on
/// `WakeHandlingLevel::ACTIVE` if it does NOT expect the system to
/// perform a full wakeup. While the drivers are handling a wake event, they
/// should request a lease to pull the state to Active, and drop the release
/// once the event is fully handled.
type WakeHandlingLevel = flexible enum : uint8 {
INACTIVE = 0;
ACTIVE = 1;
};
/// Holds tokens to the application activity power element.
///
/// [`fuchsia.power.system/ApplicationActivityLevel`] defines the power levels supported by this power element.
type ApplicationActivity = resource table {
1: active_dependency_token fuchsia.power.broker.DependencyToken;
};
/// Application activity power levels
///
/// Elements that need to keep the system from suspending should take an active
/// dependency on `ApplicationActivityLevel::ACTIVE`. When these components are
/// performing work, they should request a lease to ensure the system remains
/// active, and drop the lease when they are done.
type ApplicationActivityLevel = flexible enum : uint8 {
INACTIVE = 0;
ACTIVE = 1;
};
/// A collection of power elements that are managed by the activity governor.
type PowerElements = resource table {
1: execution_state ExecutionState;
2: execution_resume_latency ExecutionResumeLatency;
3: application_activity ApplicationActivity;
4: full_wake_handling FullWakeHandling;
5: wake_handling WakeHandling;
};
/// A listener for activity governor events.
open protocol ActivityGovernorListener {
/// Called when the activity governor detects a system resume.
///
/// This is only called when the wakeup reason returned by the platform
/// requires a full system resume.
/// The server is expected to respond once it has performed the operations
/// required to keep the system awake, if needed.
strict OnResume() -> ();
/// Called when the activity governor detects a system suspension.
///
/// There is no guarantee the server will receive this message before
/// suspension is triggered by the platform.
flexible OnSuspend();
};
/// A service for exposing events and power elements managed by the system
/// activity governor (SAG).
///
/// SAG is responsible for managing the execution state and resume-from-suspend
/// latency of the hardware platform. The hardware platform consists of the
/// components required to execute code on the device. This typically includes
/// the CPU, memory, operating system, and other components required for these
/// components to function (clock trees, power domains, etc.).
@discoverable
open protocol ActivityGovernor {
// TODO(b/315994898): Provide tokens more granularly once client usage
// patterns are better understood.
/// Gets the power elements owned by the activity governor.
///
/// If an error occurs while the server is registering a power element with
/// the power broker or an error occurs while creating a token for a power
/// element, then the channel to `ActivityGovernor` will be closed by the
/// server and no response will be returned.
flexible GetPowerElements() -> (PowerElements);
/// Registers a listener for activity governor events.
///
/// If there is an error in registering the listener, then the given
/// `ActivityGovernorListener` channel will be closed before the response
/// is sent.
///
/// To unregister, close the `ActivityGovernorListener` channel.
flexible RegisterListener(resource table {
/// The client end of the service that receives activity governor events.
///
/// Required.
1: listener client_end:ActivityGovernorListener;
// TODO(b/315994974): Handle filtering by wakeup reason.
}) -> ();
};