brintos

brintos / linux-shallow public Read only

0
0
Text · 10.1 KiB · cff1fab Raw
306 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Generic OPP Interface4 *5 * Copyright (C) 2009-2010 Texas Instruments Incorporated.6 *	Nishanth Menon7 *	Romit Dasgupta8 *	Kevin Hilman9 */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;30 31/* OPP Config flags */32#define OPP_CONFIG_CLK			BIT(0)33#define OPP_CONFIG_REGULATOR		BIT(1)34#define OPP_CONFIG_REGULATOR_HELPER	BIT(2)35#define OPP_CONFIG_PROP_NAME		BIT(3)36#define OPP_CONFIG_SUPPORTED_HW		BIT(4)37#define OPP_CONFIG_GENPD		BIT(5)38#define OPP_CONFIG_REQUIRED_DEVS	BIT(6)39 40/**41 * struct opp_config_data - data for set config operations42 * @opp_table: OPP table43 * @flags: OPP config flags44 *45 * This structure stores the OPP config information for each OPP table46 * configuration by the callers.47 */48struct opp_config_data {49	struct opp_table *opp_table;50	unsigned int flags;51};52 53/**54 * struct dev_pm_opp_icc_bw - Interconnect bandwidth values55 * @avg:	Average bandwidth corresponding to this OPP (in icc units)56 * @peak:	Peak bandwidth corresponding to this OPP (in icc units)57 *58 * This structure stores the bandwidth values for a single interconnect path.59 */60struct dev_pm_opp_icc_bw {61	u32 avg;62	u32 peak;63};64 65/*66 * Internal data structure organization with the OPP layer library is as67 * follows:68 * opp_tables (root)69 *	|- device 1 (represents voltage domain 1)70 *	|	|- opp 1 (availability, freq, voltage)71 *	|	|- opp 2 ..72 *	...	...73 *	|	`- opp n ..74 *	|- device 2 (represents the next voltage domain)75 *	...76 *	`- device m (represents mth voltage domain)77 * device 1, 2.. are represented by opp_table structure while each opp78 * is represented by the opp structure.79 */80 81/**82 * struct dev_pm_opp - Generic OPP description structure83 * @node:	opp table node. The nodes are maintained throughout the lifetime84 *		of boot. It is expected only an optimal set of OPPs are85 *		added to the library by the SoC framework.86 *		IMPORTANT: the opp nodes should be maintained in increasing87 *		order.88 * @kref:	for reference count of the OPP.89 * @available:	true/false - marks if this OPP as available or not90 * @dynamic:	not-created from static DT entries.91 * @turbo:	true if turbo (boost) OPP92 * @suspend:	true if suspend OPP93 * @removed:	flag indicating that OPP's reference is dropped by OPP core.94 * @rates:	Frequencies in hertz95 * @level:	Performance level96 * @supplies:	Power supplies voltage/current values97 * @bandwidth:	Interconnect bandwidth values98 * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's99 *		frequency from any other OPP's frequency.100 * @required_opps: List of OPPs that are required by this OPP.101 * @opp_table:	points back to the opp_table struct this opp belongs to102 * @np:		OPP's device node.103 * @dentry:	debugfs dentry pointer (per opp)104 *105 * This structure stores the OPP information for a given device.106 */107struct dev_pm_opp {108	struct list_head node;109	struct kref kref;110 111	bool available;112	bool dynamic;113	bool turbo;114	bool suspend;115	bool removed;116	unsigned long *rates;117	unsigned int level;118 119	struct dev_pm_opp_supply *supplies;120	struct dev_pm_opp_icc_bw *bandwidth;121 122	unsigned long clock_latency_ns;123 124	struct dev_pm_opp **required_opps;125	struct opp_table *opp_table;126 127	struct device_node *np;128 129#ifdef CONFIG_DEBUG_FS130	struct dentry *dentry;131	const char *of_name;132#endif133};134 135/**136 * struct opp_device - devices managed by 'struct opp_table'137 * @node:	list node138 * @dev:	device to which the struct object belongs139 * @dentry:	debugfs dentry pointer (per device)140 *141 * This is an internal data structure maintaining the devices that are managed142 * by 'struct opp_table'.143 */144struct opp_device {145	struct list_head node;146	const struct device *dev;147 148#ifdef CONFIG_DEBUG_FS149	struct dentry *dentry;150#endif151};152 153enum opp_table_access {154	OPP_TABLE_ACCESS_UNKNOWN = 0,155	OPP_TABLE_ACCESS_EXCLUSIVE = 1,156	OPP_TABLE_ACCESS_SHARED = 2,157};158 159/**160 * struct opp_table - Device opp structure161 * @node:	table node - contains the devices with OPPs that162 *		have been registered. Nodes once added are not modified in this163 *		table.164 * @head:	notifier head to notify the OPP availability changes.165 * @dev_list:	list of devices that share these OPPs166 * @opp_list:	table of opps167 * @kref:	for reference count of the table.168 * @lock:	mutex protecting the opp_list and dev_list.169 * @np:		struct device_node pointer for opp's DT node.170 * @clock_latency_ns_max: Max clock latency in nanoseconds.171 * @parsed_static_opps: Count of devices for which OPPs are initialized from DT.172 * @shared_opp: OPP is shared between multiple devices.173 * @current_rate_single_clk: Currently configured frequency for single clk.174 * @current_opp: Currently configured OPP for the table.175 * @suspend_opp: Pointer to OPP to be used during device suspend.176 * @required_opp_tables: List of device OPP tables that are required by OPPs in177 *		this table.178 * @required_devs: List of devices for required OPP tables.179 * @required_opp_count: Number of required devices.180 * @supported_hw: Array of version number to support.181 * @supported_hw_count: Number of elements in supported_hw array.182 * @prop_name: A name to postfix to many DT properties, while parsing them.183 * @config_clks: Platform specific config_clks() callback.184 * @clks: Device's clock handles, for multiple clocks.185 * @clk: Device's clock handle, for single clock.186 * @clk_count: Number of clocks.187 * @config_regulators: Platform specific config_regulators() callback.188 * @regulators: Supply regulators189 * @regulator_count: Number of power supply regulators. Its value can be -1190 * (uninitialized), 0 (no opp-microvolt property) or > 0 (has opp-microvolt191 * property).192 * @paths: Interconnect path handles193 * @path_count: Number of interconnect paths194 * @enabled: Set to true if the device's resources are enabled/configured.195 * @is_genpd: Marks if the OPP table belongs to a genpd.196 * @dentry:	debugfs dentry pointer of the real device directory (not links).197 * @dentry_name: Name of the real dentry.198 *199 * @voltage_tolerance_v1: In percentage, for v1 bindings only.200 *201 * This is an internal data structure maintaining the link to opps attached to202 * a device. This structure is not meant to be shared to users as it is203 * meant for book keeping and private to OPP library.204 */205struct opp_table {206	struct list_head node, lazy;207 208	struct blocking_notifier_head head;209	struct list_head dev_list;210	struct list_head opp_list;211	struct kref kref;212	struct mutex lock;213 214	struct device_node *np;215	unsigned long clock_latency_ns_max;216 217	/* For backward compatibility with v1 bindings */218	unsigned int voltage_tolerance_v1;219 220	unsigned int parsed_static_opps;221	enum opp_table_access shared_opp;222	unsigned long current_rate_single_clk;223	struct dev_pm_opp *current_opp;224	struct dev_pm_opp *suspend_opp;225 226	struct opp_table **required_opp_tables;227	struct device **required_devs;228	unsigned int required_opp_count;229 230	unsigned int *supported_hw;231	unsigned int supported_hw_count;232	const char *prop_name;233	config_clks_t config_clks;234	struct clk **clks;235	struct clk *clk;236	int clk_count;237	config_regulators_t config_regulators;238	struct regulator **regulators;239	int regulator_count;240	struct icc_path **paths;241	unsigned int path_count;242	bool enabled;243	bool is_genpd;244 245#ifdef CONFIG_DEBUG_FS246	struct dentry *dentry;247	char dentry_name[NAME_MAX];248#endif249};250 251/* Routines internal to opp core */252void dev_pm_opp_get(struct dev_pm_opp *opp);253bool _opp_remove_all_static(struct opp_table *opp_table);254void _get_opp_table_kref(struct opp_table *opp_table);255int _get_opp_count(struct opp_table *opp_table);256struct opp_table *_find_opp_table(struct device *dev);257struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table *opp_table);258struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table);259void _opp_free(struct dev_pm_opp *opp);260int _opp_compare_key(struct opp_table *opp_table, struct dev_pm_opp *opp1, struct dev_pm_opp *opp2);261int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table);262int _opp_add_v1(struct opp_table *opp_table, struct device *dev, struct dev_pm_opp_data *data, bool dynamic);263void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, int last_cpu);264struct opp_table *_add_opp_table_indexed(struct device *dev, int index, bool getclk);265void _put_opp_list_kref(struct opp_table *opp_table);266void _required_opps_available(struct dev_pm_opp *opp, int count);267void _update_set_required_opps(struct opp_table *opp_table);268 269static inline bool lazy_linking_pending(struct opp_table *opp_table)270{271	return unlikely(!list_empty(&opp_table->lazy));272}273 274#ifdef CONFIG_OF275void _of_init_opp_table(struct opp_table *opp_table, struct device *dev, int index);276void _of_clear_opp_table(struct opp_table *opp_table);277struct opp_table *_managed_opp(struct device *dev, int index);278void _of_clear_opp(struct opp_table *opp_table, struct dev_pm_opp *opp);279#else280static inline void _of_init_opp_table(struct opp_table *opp_table, struct device *dev, int index) {}281static inline void _of_clear_opp_table(struct opp_table *opp_table) {}282static inline struct opp_table *_managed_opp(struct device *dev, int index) { return NULL; }283static inline void _of_clear_opp(struct opp_table *opp_table, struct dev_pm_opp *opp) {}284#endif285 286#ifdef CONFIG_DEBUG_FS287void opp_debug_remove_one(struct dev_pm_opp *opp);288void opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table);289void opp_debug_register(struct opp_device *opp_dev, struct opp_table *opp_table);290void opp_debug_unregister(struct opp_device *opp_dev, struct opp_table *opp_table);291#else292static inline void opp_debug_remove_one(struct dev_pm_opp *opp) {}293 294static inline void opp_debug_create_one(struct dev_pm_opp *opp,295					struct opp_table *opp_table) { }296 297static inline void opp_debug_register(struct opp_device *opp_dev,298				      struct opp_table *opp_table) { }299 300static inline void opp_debug_unregister(struct opp_device *opp_dev,301					struct opp_table *opp_table)302{ }303#endif		/* DEBUG_FS */304 305#endif		/* __DRIVER_OPP_H__ */306