// Copyright 2019 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.
library fuchsia.hardware.cpu.ctrl;

using zx;

/// CpuOperatingPointInfo::frequency_hz and CpuOperatingPointInfo::voltage_uv
/// are set to this if the frequency and voltage for the given operating point
/// are unknown respectively.
const FREQUENCY_UNKNOWN int64 = -1;
const VOLTAGE_UNKNOWN int64 = -1;

const DEVICE_OPERATING_POINT_P0 uint32 = 0;

/// A collection of some basic information for a given operating point.
type CpuOperatingPointInfo = struct {
    // Frequency the core is operating at in hertz.
    frequency_hz int64;

    // Voltage the core is operating at in microvolts.
    voltage_uv int64;
};

closed protocol Device {
    /// Returns information about a given operating point for this performance
    /// domain.
    strict GetOperatingPointInfo(struct {
        // Operating point for which information is queried.
        opp uint32;
    }) -> (struct {
        info CpuOperatingPointInfo;
    }) error zx.Status;

    /// Gets the current operating point of the device.
    strict GetCurrentOperatingPoint() -> (struct {
        out_opp uint32;
    });

    /// Set the operating point of this device to the requested operating point.
    /// Returns ZX_OK, if the device is in a working state and the operating point is changed to
    /// requested_opp successfully. out_opp will be same as requested_opp.
    /// Returns error status, if switching to the requested_opp was unsuccessful. out_opp
    /// is the operating performance point (OPP) that the device is currently in.
    strict SetCurrentOperatingPoint(struct {
        requested_opp uint32;
    }) -> (struct {
        out_opp uint32;
    }) error zx.Status;

    /// Returns the number of operating points within this performance domain.
    strict GetOperatingPointCount() -> (struct {
        count uint32;
    }) error zx.Status;

    /// Returns the number of logical cores contained within this performance
    /// domain.
    strict GetNumLogicalCores() -> (struct {
        count uint64;
    });

    /// Returns a global system-wide core ID for the nth core in this
    /// performance domain. `index` must be a value in the range [0, n) where
    /// n is the value returned by GetNumLogicalCores().
    strict GetLogicalCoreId(struct {
        index uint64;
    }) -> (struct {
        id uint64;
    });

    /// Returns the id of this performance domain within its package. This
    /// number should be stable across boots, but clients should prefer to use
    /// GetRelativePerformance to differentiate cores if possible.
    strict GetDomainId() -> (struct {
        domain_id uint32;
    });

    /// The relative performance of this domain as configured by the platform,
    /// if known. The highest performance domain should return 255, while others
    /// should return N/255 fractional values relative to that domain.
    /// Returns ZX_ERR_NOT_SUPPORTED if the performance level is unknown.
    strict GetRelativePerformance() -> (struct {
        relative_performance uint8;
    }) error zx.Status;
};

service Service {
    device client_end:Device;
};
