Lines Matching +full:opp +full:- +full:microwatt

1 // SPDX-License-Identifier: GPL-2.0
5 //! This module provides rust abstractions for interacting with the OPP subsystem.
9 //! Reference: <https://docs.kernel.org/power/opp.html>
30 /// OPP frequency table.
40 pub(crate) fn new(table: &Table) -> Result<Self> {
57 fn table(&self) -> &cpufreq::Table {
67 fn deref(&self) -> &Self::Target {
90 /// Creates a null-terminated slice of pointers to [`Cstring`]s.
91 fn to_c_str_array(names: &[CString]) -> Result<KVec<*const u8>> {
92 // Allocated a null-terminated vector of pointers.
110 /// use kernel::opp::MicroVolt;
123 fn from(volt: MicroVolt) -> Self {
135 /// use kernel::opp::MicroWatt;
138 /// let power = MicroWatt(raw);
141 /// assert_eq!(power, MicroWatt(raw));
144 pub struct MicroWatt(pub c_ulong);
146 impl From<MicroWatt> for c_ulong {
148 fn from(power: MicroWatt) -> Self {
153 /// Handle for a dynamically created [`OPP`].
155 /// The associated [`OPP`] is automatically removed when the [`Token`] is dropped.
159 /// The following example demonstrates how to create an [`OPP`] dynamically.
165 /// use kernel::opp::{Data, MicroVolt, Token};
168 /// fn create_opp(dev: &ARef<Device>, freq: Hertz, volt: MicroVolt, level: u32) -> Result<Token> {
171 /// // OPP is removed once token goes out of scope.
181 /// Dynamically adds an [`OPP`] and returns a [`Token`] that removes it on drop.
182 fn new(dev: &ARef<Device>, mut data: Data) -> Result<Self> {
201 /// OPP data.
208 /// The following example demonstrates how to create an [`OPP`] with [`Data`].
214 /// use kernel::opp::{Data, MicroVolt, Token};
217 /// fn create_opp(dev: &ARef<Device>, freq: Hertz, volt: MicroVolt, level: u32) -> Result<Token> {
220 /// // OPP is removed once token goes out of scope.
230 /// This can be used to define a dynamic OPP to be added to a device.
231 pub fn new(freq: Hertz, volt: MicroVolt, level: u32, turbo: bool) -> Self {
240 /// Adds an [`OPP`] dynamically.
242 /// Returns a [`Token`] that ensures the OPP is automatically removed
245 pub fn add_opp(self, dev: &ARef<Device>) -> Result<Token> {
249 /// Returns the frequency associated with this OPP data.
251 fn freq(&self) -> Hertz {
256 /// [`OPP`] search options.
260 /// Defines how to search for an [`OPP`] in a [`Table`] relative to a frequency.
265 /// use kernel::opp::{OPP, SearchType, Table};
268 /// fn find_opp(table: &Table, freq: Hertz) -> Result<ARef<OPP>> {
269 /// let opp = table.opp_from_freq(freq, Some(true), None, SearchType::Exact)?;
271 /// pr_info!("OPP frequency is: {:?}\n", opp.freq(None));
272 /// pr_info!("OPP voltage is: {:?}\n", opp.voltage());
273 /// pr_info!("OPP level is: {}\n", opp.level());
274 /// pr_info!("OPP power is: {:?}\n", opp.power());
276 /// Ok(opp)
289 /// OPP configuration callbacks.
291 /// Implement this trait to customize OPP clock and regulator setup for your device.
296 fn config_clks(_dev: &Device, _table: &Table, _opp: &OPP, _scaling_down: bool) -> Result {
304 _opp_old: &OPP,
305 _opp_new: &OPP,
308 ) -> Result {
313 /// OPP configuration token.
315 /// Returned by the OPP core when configuration is applied to a [`Device`]. The associated
326 /// OPP configurations.
332 /// The following example demonstrates how to set OPP property-name configuration for a [`Device`].
337 /// use kernel::opp::{Config, ConfigOps, ConfigToken};
348 /// fn configure(dev: &ARef<Device>) -> Result<ConfigToken> {
351 /// // The OPP configuration is cleared once the [`ConfigToken`] goes out of scope.
375 pub fn new() -> Self {
380 pub fn set_clk_names(mut self, names: KVec<CString>) -> Result<Self> {
394 pub fn set_prop_name(mut self, name: CString) -> Result<Self> {
404 pub fn set_regulator_names(mut self, names: KVec<CString>) -> Result<Self> {
419 pub fn set_required_dev(mut self, dev: ARef<Device>, index: u32) -> Result<Self> {
429 pub fn set_supported_hw(mut self, hw: KVec<u32>) -> Result<Self> {
442 /// Sets the configuration with the OPP core.
445 pub fn set(self, dev: &Device) -> Result<ConfigToken> {
501 // requirements. The OPP core guarantees not to access fields of [`Config`] after this call
514 opp: *mut bindings::dev_pm_opp,
517 ) -> c_int {
525 // SAFETY: 'opp' is guaranteed by the C code to be valid.
526 unsafe { OPP::from_raw_opp(opp)? },
542 ) -> c_int {
549 unsafe { OPP::from_raw_opp(old_opp)? },
551 unsafe { OPP::from_raw_opp(new_opp)? },
560 /// A reference-counted OPP table.
566 /// The pointer stored in `Self` is non-null and valid for the lifetime of the [`Table`].
568 /// Instances of this type are reference-counted.
572 /// The following example demonstrates how to get OPP [`Table`] for a [`Cpumask`] and set its
581 /// use kernel::opp::Table;
584 /// fn get_table(dev: &ARef<Device>, mask: &mut Cpumask, freq: Hertz) -> Result<Table> {
616 /// Creates a new reference-counted [`Table`] from a raw pointer.
620 /// Callers must ensure that `ptr` is valid and non-null.
621 unsafe fn from_raw_table(ptr: *mut bindings::opp_table, dev: &ARef<Device>) -> Self {
624 // INVARIANT: The reference-count is decremented when [`Table`] goes out of scope.
636 /// Creates a new reference-counted [`Table`] instance for a [`Device`].
637 pub fn from_dev(dev: &Device) -> Result<Self> {
641 // INVARIANT: The reference-count is incremented by the C code and is decremented when
654 /// Creates a new reference-counted [`Table`] instance for a [`Device`] based on device tree
657 pub fn from_of(dev: &ARef<Device>, index: i32) -> Result<Self> {
661 // INVARIANT: The reference-count is incremented by the C code and is decremented when
682 /// Creates a new reference-counted [`Table`] instance for a [`Cpumask`] based on device tree
685 pub fn from_of_cpumask(dev: &Device, cpumask: &mut Cpumask) -> Result<Self> {
689 // INVARIANT: The reference-count is incremented by the C code and is decremented when
709 /// Returns the number of [`OPP`]s in the [`Table`].
710 pub fn opp_count(&self) -> Result<u32> {
718 /// Returns max clock latency (in nanoseconds) of the [`OPP`]s in the [`Table`].
720 pub fn max_clock_latency_ns(&self) -> usize {
726 /// Returns max volt latency (in nanoseconds) of the [`OPP`]s in the [`Table`].
728 pub fn max_volt_latency_ns(&self) -> usize {
734 /// Returns max transition latency (in nanoseconds) of the [`OPP`]s in the [`Table`].
736 pub fn max_transition_latency_ns(&self) -> usize {
742 /// Returns the suspend [`OPP`]'s frequency.
744 pub fn suspend_freq(&self) -> Hertz {
752 pub fn sync_regulators(&self) -> Result {
760 pub fn sharing_cpus(dev: &Device, cpumask: &mut Cpumask) -> Result {
767 pub fn set_sharing_cpus(&mut self, cpumask: &mut Cpumask) -> Result {
785 pub fn of_sharing_cpus(dev: &Device, cpumask: &mut Cpumask) -> Result {
793 /// Updates the voltage value for an [`OPP`].
801 ) -> Result {
818 pub fn cpufreq_table(&mut self) -> Result<FreqTable> {
822 /// Configures device with [`OPP`] matching the frequency value.
824 pub fn set_rate(&self, freq: Hertz) -> Result {
830 /// Configures device with [`OPP`].
832 pub fn set_opp(&self, opp: &OPP) -> Result {
835 to_result(unsafe { bindings::dev_pm_opp_set_opp(self.dev.as_raw(), opp.as_raw()) })
838 /// Finds [`OPP`] based on frequency.
845 ) -> Result<ARef<OPP>> {
855 // [`OPP`] instance.
867 // requirements. The returned pointer will be owned by the new [`OPP`] instance.
873 // requirements. The returned pointer will be owned by the new [`OPP`] instance.
880 unsafe { OPP::from_raw_opp_owned(ptr) }
883 /// Finds [`OPP`] based on level.
884 pub fn opp_from_level(&self, mut level: u32, stype: SearchType) -> Result<ARef<OPP>> {
889 // requirements. The returned pointer will be owned by the new [`OPP`] instance.
893 // requirements. The returned pointer will be owned by the new [`OPP`] instance.
899 // requirements. The returned pointer will be owned by the new [`OPP`] instance.
906 unsafe { OPP::from_raw_opp_owned(ptr) }
909 /// Finds [`OPP`] based on bandwidth.
910 pub fn opp_from_bw(&self, mut bw: u32, index: i32, stype: SearchType) -> Result<ARef<OPP>> {
914 // The OPP core doesn't support this yet.
918 // requirements. The returned pointer will be owned by the new [`OPP`] instance.
924 // requirements. The returned pointer will be owned by the new [`OPP`] instance.
931 unsafe { OPP::from_raw_opp_owned(ptr) }
934 /// Enables the [`OPP`].
936 pub fn enable_opp(&self, freq: Hertz) -> Result {
942 /// Disables the [`OPP`].
944 pub fn disable_opp(&self, freq: Hertz) -> Result {
952 pub fn of_register_em(&mut self, cpumask: &mut Cpumask) -> Result {
995 /// A reference-counted Operating performance point (OPP).
1001 /// The pointer stored in `Self` is non-null and valid for the lifetime of the [`OPP`].
1003 /// Instances of this type are reference-counted. The reference count is incremented by the
1004 /// `dev_pm_opp_get` function and decremented by `dev_pm_opp_put`. The Rust type `ARef<OPP>`
1005 /// represents a pointer that owns a reference count on the [`OPP`].
1007 /// A reference to the [`OPP`], &[`OPP`], isn't refcounted by the Rust code.
1011 /// The following example demonstrates how to get [`OPP`] corresponding to a frequency value and
1017 /// use kernel::opp::{SearchType, Table};
1019 /// fn configure_opp(table: &Table, freq: Hertz) -> Result {
1020 /// let opp = table.opp_from_freq(freq, Some(true), None, SearchType::Exact)?;
1022 /// if opp.freq(None) != freq {
1026 /// table.set_opp(&opp)
1030 pub struct OPP(Opaque<bindings::dev_pm_opp>);
1032 /// SAFETY: It is okay to send the ownership of [`OPP`] across thread boundaries.
1033 unsafe impl Send for OPP {}
1035 /// SAFETY: It is okay to access [`OPP`] through shared references from other threads because we're
1037 unsafe impl Sync for OPP {}
1039 /// SAFETY: The type invariants guarantee that [`OPP`] is always refcounted.
1040 unsafe impl AlwaysRefCounted for OPP {
1052 impl OPP {
1053 /// Creates an owned reference to a [`OPP`] from a valid pointer.
1060 /// The caller must ensure that `ptr` is valid and the refcount of the [`OPP`] is incremented.
1061 /// The caller must also ensure that it doesn't explicitly drop the refcount of the [`OPP`], as
1064 pub unsafe fn from_raw_opp_owned(ptr: *mut bindings::dev_pm_opp) -> Result<ARef<Self>> {
1069 // INVARIANT: The reference-count is decremented when [`OPP`] goes out of scope.
1073 /// Creates a reference to a [`OPP`] from a valid pointer.
1082 pub unsafe fn from_raw_opp<'a>(ptr: *mut bindings::dev_pm_opp) -> Result<&'a Self> {
1084 // duration of 'a. The cast is okay because [`OPP`] is `repr(transparent)`.
1089 fn as_raw(&self) -> *mut bindings::dev_pm_opp {
1093 /// Returns the frequency of an [`OPP`].
1094 pub fn freq(&self, index: Option<u32>) -> Hertz {
1102 /// Returns the voltage of an [`OPP`].
1104 pub fn voltage(&self) -> MicroVolt {
1110 /// Returns the level of an [`OPP`].
1112 pub fn level(&self) -> u32 {
1118 /// Returns the power of an [`OPP`].
1120 pub fn power(&self) -> MicroWatt {
1123 MicroWatt(unsafe { bindings::dev_pm_opp_get_power(self.as_raw()) })
1126 /// Returns the required pstate of an [`OPP`].
1128 pub fn required_pstate(&self, index: u32) -> u32 {
1134 /// Returns true if the [`OPP`] is turbo.
1136 pub fn is_turbo(&self) -> bool {