Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (c) 2018, Linaro Ltd.
0004  * Author: Georgi Djakov <georgi.djakov@linaro.org>
0005  */
0006 
0007 #ifndef __LINUX_INTERCONNECT_PROVIDER_H
0008 #define __LINUX_INTERCONNECT_PROVIDER_H
0009 
0010 #include <linux/interconnect.h>
0011 
0012 #define icc_units_to_bps(bw)  ((bw) * 1000ULL)
0013 
0014 struct icc_node;
0015 struct of_phandle_args;
0016 
0017 /**
0018  * struct icc_node_data - icc node data
0019  *
0020  * @node: icc node
0021  * @tag: tag
0022  */
0023 struct icc_node_data {
0024     struct icc_node *node;
0025     u32 tag;
0026 };
0027 
0028 /**
0029  * struct icc_onecell_data - driver data for onecell interconnect providers
0030  *
0031  * @num_nodes: number of nodes in this device
0032  * @nodes: array of pointers to the nodes in this device
0033  */
0034 struct icc_onecell_data {
0035     unsigned int num_nodes;
0036     struct icc_node *nodes[];
0037 };
0038 
0039 struct icc_node *of_icc_xlate_onecell(struct of_phandle_args *spec,
0040                       void *data);
0041 
0042 /**
0043  * struct icc_provider - interconnect provider (controller) entity that might
0044  * provide multiple interconnect controls
0045  *
0046  * @provider_list: list of the registered interconnect providers
0047  * @nodes: internal list of the interconnect provider nodes
0048  * @set: pointer to device specific set operation function
0049  * @aggregate: pointer to device specific aggregate operation function
0050  * @pre_aggregate: pointer to device specific function that is called
0051  *         before the aggregation begins (optional)
0052  * @get_bw: pointer to device specific function to get current bandwidth
0053  * @xlate: provider-specific callback for mapping nodes from phandle arguments
0054  * @xlate_extended: vendor-specific callback for mapping node data from phandle arguments
0055  * @dev: the device this interconnect provider belongs to
0056  * @users: count of active users
0057  * @inter_set: whether inter-provider pairs will be configured with @set
0058  * @data: pointer to private data
0059  */
0060 struct icc_provider {
0061     struct list_head    provider_list;
0062     struct list_head    nodes;
0063     int (*set)(struct icc_node *src, struct icc_node *dst);
0064     int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw,
0065              u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
0066     void (*pre_aggregate)(struct icc_node *node);
0067     int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);
0068     struct icc_node* (*xlate)(struct of_phandle_args *spec, void *data);
0069     struct icc_node_data* (*xlate_extended)(struct of_phandle_args *spec, void *data);
0070     struct device       *dev;
0071     int         users;
0072     bool            inter_set;
0073     void            *data;
0074 };
0075 
0076 /**
0077  * struct icc_node - entity that is part of the interconnect topology
0078  *
0079  * @id: platform specific node id
0080  * @name: node name used in debugfs
0081  * @links: a list of targets pointing to where we can go next when traversing
0082  * @num_links: number of links to other interconnect nodes
0083  * @provider: points to the interconnect provider of this node
0084  * @node_list: the list entry in the parent provider's "nodes" list
0085  * @search_list: list used when walking the nodes graph
0086  * @reverse: pointer to previous node when walking the nodes graph
0087  * @is_traversed: flag that is used when walking the nodes graph
0088  * @req_list: a list of QoS constraint requests associated with this node
0089  * @avg_bw: aggregated value of average bandwidth requests from all consumers
0090  * @peak_bw: aggregated value of peak bandwidth requests from all consumers
0091  * @init_avg: average bandwidth value that is read from the hardware during init
0092  * @init_peak: peak bandwidth value that is read from the hardware during init
0093  * @data: pointer to private data
0094  */
0095 struct icc_node {
0096     int         id;
0097     const char              *name;
0098     struct icc_node     **links;
0099     size_t          num_links;
0100 
0101     struct icc_provider *provider;
0102     struct list_head    node_list;
0103     struct list_head    search_list;
0104     struct icc_node     *reverse;
0105     u8          is_traversed:1;
0106     struct hlist_head   req_list;
0107     u32         avg_bw;
0108     u32         peak_bw;
0109     u32         init_avg;
0110     u32         init_peak;
0111     void            *data;
0112 };
0113 
0114 #if IS_ENABLED(CONFIG_INTERCONNECT)
0115 
0116 int icc_std_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
0117               u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
0118 struct icc_node *icc_node_create(int id);
0119 void icc_node_destroy(int id);
0120 int icc_link_create(struct icc_node *node, const int dst_id);
0121 int icc_link_destroy(struct icc_node *src, struct icc_node *dst);
0122 void icc_node_add(struct icc_node *node, struct icc_provider *provider);
0123 void icc_node_del(struct icc_node *node);
0124 int icc_nodes_remove(struct icc_provider *provider);
0125 int icc_provider_add(struct icc_provider *provider);
0126 int icc_provider_del(struct icc_provider *provider);
0127 struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec);
0128 void icc_sync_state(struct device *dev);
0129 
0130 #else
0131 
0132 static inline int icc_std_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
0133                     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
0134 {
0135     return -ENOTSUPP;
0136 }
0137 
0138 static inline struct icc_node *icc_node_create(int id)
0139 {
0140     return ERR_PTR(-ENOTSUPP);
0141 }
0142 
0143 static inline void icc_node_destroy(int id)
0144 {
0145 }
0146 
0147 static inline int icc_link_create(struct icc_node *node, const int dst_id)
0148 {
0149     return -ENOTSUPP;
0150 }
0151 
0152 static inline int icc_link_destroy(struct icc_node *src, struct icc_node *dst)
0153 {
0154     return -ENOTSUPP;
0155 }
0156 
0157 static inline void icc_node_add(struct icc_node *node, struct icc_provider *provider)
0158 {
0159 }
0160 
0161 static inline void icc_node_del(struct icc_node *node)
0162 {
0163 }
0164 
0165 static inline int icc_nodes_remove(struct icc_provider *provider)
0166 {
0167     return -ENOTSUPP;
0168 }
0169 
0170 static inline int icc_provider_add(struct icc_provider *provider)
0171 {
0172     return -ENOTSUPP;
0173 }
0174 
0175 static inline int icc_provider_del(struct icc_provider *provider)
0176 {
0177     return -ENOTSUPP;
0178 }
0179 
0180 static inline struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec)
0181 {
0182     return ERR_PTR(-ENOTSUPP);
0183 }
0184 
0185 #endif /* CONFIG_INTERCONNECT */
0186 
0187 #endif /* __LINUX_INTERCONNECT_PROVIDER_H */