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

  1. Option 1: Devices directly use the ACPI resources to get and set clock inputs.

  2. Option 2: Add an acpi-clk device to the clock framework that uses the clock resources to get and set rates.

Kernel Changes

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