ACPI Clock Input Resources
Introduction
Device drivers (e.g: UART, I2C, Audio, etc.) need to know the input clock rate for the device to configure and function properly. Some device drivers only need to know the configured clock rate, while others (such as audio, display, etc) may need to change the clock rate based on the requirements, such as supporting different sampling rates, resolutions, etc.
Several Arm implementations provide the clock rate to the device drivers using non-standard AML methods, objects, and _DSD properties. The ACPI v6.5 specification. standardized this by introducing the ClockInput resource descriptor.
ClockInput (FrequencyNumerator, FrequencyDivisor, Scale, FixedMode, ResourceSource, ˓ResourceSourceIndex)
This page captures our investigation and suggestions for using the ClockInput
resource.
Option 1: ClockInput resources and configurability with _PRS and _SRS
This approach leverages the existing _PRS and _SRS methods to get the possible clock input resources and set one of the resources based on device requirements.
An example AML implementation is given below
Device(DEV) {
...
// Possible resources for the device
Name (_PRS, ResourceTemplate ()
{
ClockInput(100000, 1, Hz, Fixed,,) // 100 KHz
ClockInput(400000, 1, Hz, Fixed,,) // 400 KHz
ClockInput(1000000, 1, Hz, Fixed,,) // 1 MHz
})
Method (_CRS, 0x0, NotSerialized)
{
Name ( RBUF, ResourceTemplate () {
ClockInput(100000, 1, Hz, Fixed,,)
MEMORY32FIXED(ReadWrite, 0x30A20000, 0x14, )
Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 67 }
})
// Update ClockInput with configured frequency
CreateDWordField (RBUF, 0x08, FQN)
FQN = CLK1.FQN
CreateWordField (RBUF, 0x06, FQD)
FQD = CLK1.FQD
Return(RBUF)
}
Method (_SRS, 1, NotSerialized)
{
// only ClockInput is configurable, ignore the rest of the resources
CreateDWordField (Arg0, 0x08, FQN)
CLK1.FQN = FQN
CreateWordField (Arg0, 0x06, FQD)
CLK1.FQD = FQD
}
}
Pros:
No extra AML methods are required to configure the clocks.
No additional OS infrastructure support is required (except support for ClockInput resources, _PRS, _SRS, etc.)
Cons:
_PRS and _SRS are generally used for full resource configuration at device enumeration and dynamic configuring clock input using _SRS might not be aligned with the original design intent.
ClockInput resource control with multiple clock inputs is tricky as we don’t have any unique identifier for clocks. (except resource label and index which are optional for Fixed clocks)
There are potentially a few extra changes required at the spec to support this.
Add clarification to spec. around the use of _SRS
Add identifier to ClockInput resource to support multiple clock inputs
Add descriptor name to ClockInput resource to select the resource from the resource buffer.
Linux Kernel Prototype
Option 1: Devices directly use the ACPI resources to get and set clock inputs.
Option 2: Add an
acpi-clk
device to the clock framework that uses the clock resources to get and set rates.
Kernel Changes
Adding ClockInput Resource support to Linux ACPICA
Support ClockInput Resources
Device driver could use the above framework to get and select the clock rate
// get the current clock rate from _CRS
acpi_freq = acpi_dev_get_clock_input_rate(ACPI_COMPANION(&pdev->dev), 0);
// request 40KHz clock rate for the device
// acpi clock framework will first look for a matching clock input from _PRS and
// invokes _SRS to configure the clock
ret = acpi_dev_set_clock_input_rate(ACPI_COMPANION(&pdev->dev), 400000, 0);
Option 2: ClockInput resources with a standard clock resource provider
This option uses a standard clock controller known to the kernel.
AML methods for the standard clock provider can be standardized and the kernel can use that to provide the clock bindings required for the devices.
This option would be able to support multiple clock input resources and allows supporting other clock control methods beyond setting the clock rate.
Kernel only has to provide the AML binding for clock resources and the clock management will be done from AML.
Option 3: ClockInput resources with SCMI clock provider
The above two options used the AML-based approach to configure the clock to avoid adding overhead to the kernel. However, this option requires SCMI driver support at the kernel side and uses that to provide clock control.
SCMI supports multiple APIs for clock (e.g: enable/disable clock, get/set rate, get notification for clock change, etc.). See the SCMI specification here https://developer.arm.com/documentation/den0056/e/?lang=en
This approach would avoid having to implement the clock framework in AML and platform vendors can implement the clock control in the firmware that can be driven through the SCMI protocol.
Linux already has support for SCMI driver and adding the binding for ACPI support wouldn’t require significant changes.
Option 4: Clock Framework support at Kernel
This would require the kernel to provide a clock framework and platform vendors to provide clock drivers.
ACPICA
ClockInput resource is supported by Intel ACPICA.
https://github.com/acpica/acpica/pull/838