Skip to end of banner
Go to start of banner

ACPI Clock Input Resources

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

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.

Device (CLK) {

  Name (_HID, "PNP####") // Standard clock device with defined AML interfaces
  ...
  
  // Get Clock Rate
  Method(_GCR, )
  {
    ...
  }
  
  // Set Clock Rate
  Method(_SCR, )
  {
    ...
  }
  
  // Set State (enable/disable etc.)
  Method(_SET, )
  {
    ...
  }
  
}
Device(DEV) {
      ...
      
    Method (_CRS, 0, NotSerialized)
    {
      ...
      ClockInput (24, 1, MHz, Variable, “\\_SB.CLK”, 1)
    }
    
    ...
    
}

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.

Device (SCMI) {
  Name (_HID, "PNP####") // SCMI Device ID
  ...
  
  // Objects and Methods to provide SCMI transport channel
  // needs to be defined for the device
  
}

  
Device(DEV) {
    ...
    Method (_CRS, 0, NotSerialized)
    {
      ...
      ClockInput (24, 1, MHz, Variable, “\\_SB.SCMI”, 1)
    }
    ...
}

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.

Device (GCCP}) {
  Name (_HID, "QCOMXXXX")
  ...
}

Device(DEV) {
    ...
    Method (_CRS, 0, NotSerialized)
    {
      ...
      ClockInput (24, 1, MHz, Variable, “\\_SB.GCCP”, 1)
    }
    ...
}

ACPICA

ClockInput resource is not yet supported by Intel ACPICA. You can find a work-in-progress change below

https://github.com/nsait-linaro/acpica/commit/2df31c14576b4f16dc2ee86a0ff23570bd7d5674

  • No labels