cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

opp.h (9601B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Generic OPP Interface
      4 *
      5 * Copyright (C) 2009-2010 Texas Instruments Incorporated.
      6 *	Nishanth Menon
      7 *	Romit Dasgupta
      8 *	Kevin Hilman
      9 */
     10
     11#ifndef __DRIVER_OPP_H__
     12#define __DRIVER_OPP_H__
     13
     14#include <linux/device.h>
     15#include <linux/interconnect.h>
     16#include <linux/kernel.h>
     17#include <linux/kref.h>
     18#include <linux/list.h>
     19#include <linux/limits.h>
     20#include <linux/pm_opp.h>
     21#include <linux/notifier.h>
     22
     23struct clk;
     24struct regulator;
     25
     26/* Lock to allow exclusive modification to the device and opp lists */
     27extern struct mutex opp_table_lock;
     28
     29extern struct list_head opp_tables, lazy_opp_tables;
     30
     31/*
     32 * Internal data structure organization with the OPP layer library is as
     33 * follows:
     34 * opp_tables (root)
     35 *	|- device 1 (represents voltage domain 1)
     36 *	|	|- opp 1 (availability, freq, voltage)
     37 *	|	|- opp 2 ..
     38 *	...	...
     39 *	|	`- opp n ..
     40 *	|- device 2 (represents the next voltage domain)
     41 *	...
     42 *	`- device m (represents mth voltage domain)
     43 * device 1, 2.. are represented by opp_table structure while each opp
     44 * is represented by the opp structure.
     45 */
     46
     47/**
     48 * struct dev_pm_opp - Generic OPP description structure
     49 * @node:	opp table node. The nodes are maintained throughout the lifetime
     50 *		of boot. It is expected only an optimal set of OPPs are
     51 *		added to the library by the SoC framework.
     52 *		IMPORTANT: the opp nodes should be maintained in increasing
     53 *		order.
     54 * @kref:	for reference count of the OPP.
     55 * @available:	true/false - marks if this OPP as available or not
     56 * @dynamic:	not-created from static DT entries.
     57 * @turbo:	true if turbo (boost) OPP
     58 * @suspend:	true if suspend OPP
     59 * @removed:	flag indicating that OPP's reference is dropped by OPP core.
     60 * @pstate: Device's power domain's performance state.
     61 * @rate:	Frequency in hertz
     62 * @level:	Performance level
     63 * @supplies:	Power supplies voltage/current values
     64 * @bandwidth:	Interconnect bandwidth values
     65 * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's
     66 *		frequency from any other OPP's frequency.
     67 * @required_opps: List of OPPs that are required by this OPP.
     68 * @opp_table:	points back to the opp_table struct this opp belongs to
     69 * @np:		OPP's device node.
     70 * @dentry:	debugfs dentry pointer (per opp)
     71 *
     72 * This structure stores the OPP information for a given device.
     73 */
     74struct dev_pm_opp {
     75	struct list_head node;
     76	struct kref kref;
     77
     78	bool available;
     79	bool dynamic;
     80	bool turbo;
     81	bool suspend;
     82	bool removed;
     83	unsigned int pstate;
     84	unsigned long rate;
     85	unsigned int level;
     86
     87	struct dev_pm_opp_supply *supplies;
     88	struct dev_pm_opp_icc_bw *bandwidth;
     89
     90	unsigned long clock_latency_ns;
     91
     92	struct dev_pm_opp **required_opps;
     93	struct opp_table *opp_table;
     94
     95	struct device_node *np;
     96
     97#ifdef CONFIG_DEBUG_FS
     98	struct dentry *dentry;
     99	const char *of_name;
    100#endif
    101};
    102
    103/**
    104 * struct opp_device - devices managed by 'struct opp_table'
    105 * @node:	list node
    106 * @dev:	device to which the struct object belongs
    107 * @dentry:	debugfs dentry pointer (per device)
    108 *
    109 * This is an internal data structure maintaining the devices that are managed
    110 * by 'struct opp_table'.
    111 */
    112struct opp_device {
    113	struct list_head node;
    114	const struct device *dev;
    115
    116#ifdef CONFIG_DEBUG_FS
    117	struct dentry *dentry;
    118#endif
    119};
    120
    121enum opp_table_access {
    122	OPP_TABLE_ACCESS_UNKNOWN = 0,
    123	OPP_TABLE_ACCESS_EXCLUSIVE = 1,
    124	OPP_TABLE_ACCESS_SHARED = 2,
    125};
    126
    127/**
    128 * struct opp_table - Device opp structure
    129 * @node:	table node - contains the devices with OPPs that
    130 *		have been registered. Nodes once added are not modified in this
    131 *		table.
    132 * @head:	notifier head to notify the OPP availability changes.
    133 * @dev_list:	list of devices that share these OPPs
    134 * @opp_list:	table of opps
    135 * @kref:	for reference count of the table.
    136 * @lock:	mutex protecting the opp_list and dev_list.
    137 * @np:		struct device_node pointer for opp's DT node.
    138 * @clock_latency_ns_max: Max clock latency in nanoseconds.
    139 * @parsed_static_opps: Count of devices for which OPPs are initialized from DT.
    140 * @shared_opp: OPP is shared between multiple devices.
    141 * @current_rate: Currently configured frequency.
    142 * @current_opp: Currently configured OPP for the table.
    143 * @suspend_opp: Pointer to OPP to be used during device suspend.
    144 * @genpd_virt_dev_lock: Mutex protecting the genpd virtual device pointers.
    145 * @genpd_virt_devs: List of virtual devices for multiple genpd support.
    146 * @required_opp_tables: List of device OPP tables that are required by OPPs in
    147 *		this table.
    148 * @required_opp_count: Number of required devices.
    149 * @supported_hw: Array of version number to support.
    150 * @supported_hw_count: Number of elements in supported_hw array.
    151 * @prop_name: A name to postfix to many DT properties, while parsing them.
    152 * @clk: Device's clock handle
    153 * @regulators: Supply regulators
    154 * @regulator_count: Number of power supply regulators. Its value can be -1
    155 * (uninitialized), 0 (no opp-microvolt property) or > 0 (has opp-microvolt
    156 * property).
    157 * @paths: Interconnect path handles
    158 * @path_count: Number of interconnect paths
    159 * @enabled: Set to true if the device's resources are enabled/configured.
    160 * @genpd_performance_state: Device's power domain support performance state.
    161 * @is_genpd: Marks if the OPP table belongs to a genpd.
    162 * @set_opp: Platform specific set_opp callback
    163 * @sod_supplies: Set opp data supplies
    164 * @set_opp_data: Data to be passed to set_opp callback
    165 * @dentry:	debugfs dentry pointer of the real device directory (not links).
    166 * @dentry_name: Name of the real dentry.
    167 *
    168 * @voltage_tolerance_v1: In percentage, for v1 bindings only.
    169 *
    170 * This is an internal data structure maintaining the link to opps attached to
    171 * a device. This structure is not meant to be shared to users as it is
    172 * meant for book keeping and private to OPP library.
    173 */
    174struct opp_table {
    175	struct list_head node, lazy;
    176
    177	struct blocking_notifier_head head;
    178	struct list_head dev_list;
    179	struct list_head opp_list;
    180	struct kref kref;
    181	struct mutex lock;
    182
    183	struct device_node *np;
    184	unsigned long clock_latency_ns_max;
    185
    186	/* For backward compatibility with v1 bindings */
    187	unsigned int voltage_tolerance_v1;
    188
    189	unsigned int parsed_static_opps;
    190	enum opp_table_access shared_opp;
    191	unsigned long current_rate;
    192	struct dev_pm_opp *current_opp;
    193	struct dev_pm_opp *suspend_opp;
    194
    195	struct mutex genpd_virt_dev_lock;
    196	struct device **genpd_virt_devs;
    197	struct opp_table **required_opp_tables;
    198	unsigned int required_opp_count;
    199
    200	unsigned int *supported_hw;
    201	unsigned int supported_hw_count;
    202	const char *prop_name;
    203	struct clk *clk;
    204	struct regulator **regulators;
    205	int regulator_count;
    206	struct icc_path **paths;
    207	unsigned int path_count;
    208	bool enabled;
    209	bool genpd_performance_state;
    210	bool is_genpd;
    211
    212	int (*set_opp)(struct dev_pm_set_opp_data *data);
    213	struct dev_pm_opp_supply *sod_supplies;
    214	struct dev_pm_set_opp_data *set_opp_data;
    215
    216#ifdef CONFIG_DEBUG_FS
    217	struct dentry *dentry;
    218	char dentry_name[NAME_MAX];
    219#endif
    220};
    221
    222/* Routines internal to opp core */
    223void dev_pm_opp_get(struct dev_pm_opp *opp);
    224bool _opp_remove_all_static(struct opp_table *opp_table);
    225void _get_opp_table_kref(struct opp_table *opp_table);
    226int _get_opp_count(struct opp_table *opp_table);
    227struct opp_table *_find_opp_table(struct device *dev);
    228struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table *opp_table);
    229struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table);
    230void _opp_free(struct dev_pm_opp *opp);
    231int _opp_compare_key(struct dev_pm_opp *opp1, struct dev_pm_opp *opp2);
    232int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table, bool rate_not_available);
    233int _opp_add_v1(struct opp_table *opp_table, struct device *dev, unsigned long freq, long u_volt, bool dynamic);
    234void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, int last_cpu);
    235struct opp_table *_add_opp_table_indexed(struct device *dev, int index, bool getclk);
    236void _put_opp_list_kref(struct opp_table *opp_table);
    237void _required_opps_available(struct dev_pm_opp *opp, int count);
    238
    239static inline bool lazy_linking_pending(struct opp_table *opp_table)
    240{
    241	return unlikely(!list_empty(&opp_table->lazy));
    242}
    243
    244#ifdef CONFIG_OF
    245void _of_init_opp_table(struct opp_table *opp_table, struct device *dev, int index);
    246void _of_clear_opp_table(struct opp_table *opp_table);
    247struct opp_table *_managed_opp(struct device *dev, int index);
    248void _of_opp_free_required_opps(struct opp_table *opp_table,
    249				struct dev_pm_opp *opp);
    250#else
    251static inline void _of_init_opp_table(struct opp_table *opp_table, struct device *dev, int index) {}
    252static inline void _of_clear_opp_table(struct opp_table *opp_table) {}
    253static inline struct opp_table *_managed_opp(struct device *dev, int index) { return NULL; }
    254static inline void _of_opp_free_required_opps(struct opp_table *opp_table,
    255					      struct dev_pm_opp *opp) {}
    256#endif
    257
    258#ifdef CONFIG_DEBUG_FS
    259void opp_debug_remove_one(struct dev_pm_opp *opp);
    260void opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table);
    261void opp_debug_register(struct opp_device *opp_dev, struct opp_table *opp_table);
    262void opp_debug_unregister(struct opp_device *opp_dev, struct opp_table *opp_table);
    263#else
    264static inline void opp_debug_remove_one(struct dev_pm_opp *opp) {}
    265
    266static inline void opp_debug_create_one(struct dev_pm_opp *opp,
    267					struct opp_table *opp_table) { }
    268
    269static inline void opp_debug_register(struct opp_device *opp_dev,
    270				      struct opp_table *opp_table) { }
    271
    272static inline void opp_debug_unregister(struct opp_device *opp_dev,
    273					struct opp_table *opp_table)
    274{ }
    275#endif		/* DEBUG_FS */
    276
    277#endif		/* __DRIVER_OPP_H__ */