111f1cecaSGeorgi Djakov /* SPDX-License-Identifier: GPL-2.0 */
211f1cecaSGeorgi Djakov /*
311f1cecaSGeorgi Djakov * Copyright (c) 2018, Linaro Ltd.
411f1cecaSGeorgi Djakov * Author: Georgi Djakov <georgi.djakov@linaro.org>
511f1cecaSGeorgi Djakov */
611f1cecaSGeorgi Djakov
711f1cecaSGeorgi Djakov #ifndef __LINUX_INTERCONNECT_PROVIDER_H
811f1cecaSGeorgi Djakov #define __LINUX_INTERCONNECT_PROVIDER_H
911f1cecaSGeorgi Djakov
1011f1cecaSGeorgi Djakov #include <linux/interconnect.h>
1111f1cecaSGeorgi Djakov
1211f1cecaSGeorgi Djakov #define icc_units_to_bps(bw) ((bw) * 1000ULL)
1311f1cecaSGeorgi Djakov
1411f1cecaSGeorgi Djakov struct icc_node;
1587e3031bSGeorgi Djakov struct of_phandle_args;
1687e3031bSGeorgi Djakov
1787e3031bSGeorgi Djakov /**
181521e22bSGeorgi Djakov * struct icc_node_data - icc node data
191521e22bSGeorgi Djakov *
201521e22bSGeorgi Djakov * @node: icc node
211521e22bSGeorgi Djakov * @tag: tag
221521e22bSGeorgi Djakov */
231521e22bSGeorgi Djakov struct icc_node_data {
241521e22bSGeorgi Djakov struct icc_node *node;
251521e22bSGeorgi Djakov u32 tag;
261521e22bSGeorgi Djakov };
271521e22bSGeorgi Djakov
281521e22bSGeorgi Djakov /**
2987e3031bSGeorgi Djakov * struct icc_onecell_data - driver data for onecell interconnect providers
3087e3031bSGeorgi Djakov *
3187e3031bSGeorgi Djakov * @num_nodes: number of nodes in this device
3287e3031bSGeorgi Djakov * @nodes: array of pointers to the nodes in this device
3387e3031bSGeorgi Djakov */
3487e3031bSGeorgi Djakov struct icc_onecell_data {
3587e3031bSGeorgi Djakov unsigned int num_nodes;
36*dd4904f3SKees Cook struct icc_node *nodes[] __counted_by(num_nodes);
3787e3031bSGeorgi Djakov };
3887e3031bSGeorgi Djakov
3987e3031bSGeorgi Djakov struct icc_node *of_icc_xlate_onecell(struct of_phandle_args *spec,
4087e3031bSGeorgi Djakov void *data);
4111f1cecaSGeorgi Djakov
4211f1cecaSGeorgi Djakov /**
4311f1cecaSGeorgi Djakov * struct icc_provider - interconnect provider (controller) entity that might
4411f1cecaSGeorgi Djakov * provide multiple interconnect controls
4511f1cecaSGeorgi Djakov *
4611f1cecaSGeorgi Djakov * @provider_list: list of the registered interconnect providers
4711f1cecaSGeorgi Djakov * @nodes: internal list of the interconnect provider nodes
4811f1cecaSGeorgi Djakov * @set: pointer to device specific set operation function
4911f1cecaSGeorgi Djakov * @aggregate: pointer to device specific aggregate operation function
50cbd5a9c2SGeorgi Djakov * @pre_aggregate: pointer to device specific function that is called
51cbd5a9c2SGeorgi Djakov * before the aggregation begins (optional)
52cc80d10dSGeorgi Djakov * @get_bw: pointer to device specific function to get current bandwidth
5387e3031bSGeorgi Djakov * @xlate: provider-specific callback for mapping nodes from phandle arguments
541521e22bSGeorgi Djakov * @xlate_extended: vendor-specific callback for mapping node data from phandle arguments
5511f1cecaSGeorgi Djakov * @dev: the device this interconnect provider belongs to
5611f1cecaSGeorgi Djakov * @users: count of active users
5765461e26SArtur Świgoń * @inter_set: whether inter-provider pairs will be configured with @set
5811f1cecaSGeorgi Djakov * @data: pointer to private data
5911f1cecaSGeorgi Djakov */
6011f1cecaSGeorgi Djakov struct icc_provider {
6111f1cecaSGeorgi Djakov struct list_head provider_list;
6211f1cecaSGeorgi Djakov struct list_head nodes;
6311f1cecaSGeorgi Djakov int (*set)(struct icc_node *src, struct icc_node *dst);
64127ab2ccSGeorgi Djakov int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw,
65127ab2ccSGeorgi Djakov u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
66cbd5a9c2SGeorgi Djakov void (*pre_aggregate)(struct icc_node *node);
67cc80d10dSGeorgi Djakov int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);
6887e3031bSGeorgi Djakov struct icc_node* (*xlate)(struct of_phandle_args *spec, void *data);
691521e22bSGeorgi Djakov struct icc_node_data* (*xlate_extended)(struct of_phandle_args *spec, void *data);
7011f1cecaSGeorgi Djakov struct device *dev;
7111f1cecaSGeorgi Djakov int users;
7265461e26SArtur Świgoń bool inter_set;
7311f1cecaSGeorgi Djakov void *data;
7411f1cecaSGeorgi Djakov };
7511f1cecaSGeorgi Djakov
7611f1cecaSGeorgi Djakov /**
7711f1cecaSGeorgi Djakov * struct icc_node - entity that is part of the interconnect topology
7811f1cecaSGeorgi Djakov *
7911f1cecaSGeorgi Djakov * @id: platform specific node id
8011f1cecaSGeorgi Djakov * @name: node name used in debugfs
8111f1cecaSGeorgi Djakov * @links: a list of targets pointing to where we can go next when traversing
8211f1cecaSGeorgi Djakov * @num_links: number of links to other interconnect nodes
8311f1cecaSGeorgi Djakov * @provider: points to the interconnect provider of this node
8411f1cecaSGeorgi Djakov * @node_list: the list entry in the parent provider's "nodes" list
8511f1cecaSGeorgi Djakov * @search_list: list used when walking the nodes graph
8611f1cecaSGeorgi Djakov * @reverse: pointer to previous node when walking the nodes graph
8711f1cecaSGeorgi Djakov * @is_traversed: flag that is used when walking the nodes graph
8811f1cecaSGeorgi Djakov * @req_list: a list of QoS constraint requests associated with this node
8911f1cecaSGeorgi Djakov * @avg_bw: aggregated value of average bandwidth requests from all consumers
9011f1cecaSGeorgi Djakov * @peak_bw: aggregated value of peak bandwidth requests from all consumers
91b1d681d8SGeorgi Djakov * @init_avg: average bandwidth value that is read from the hardware during init
92b1d681d8SGeorgi Djakov * @init_peak: peak bandwidth value that is read from the hardware during init
9311f1cecaSGeorgi Djakov * @data: pointer to private data
9411f1cecaSGeorgi Djakov */
9511f1cecaSGeorgi Djakov struct icc_node {
9611f1cecaSGeorgi Djakov int id;
9711f1cecaSGeorgi Djakov const char *name;
9811f1cecaSGeorgi Djakov struct icc_node **links;
9911f1cecaSGeorgi Djakov size_t num_links;
10011f1cecaSGeorgi Djakov
10111f1cecaSGeorgi Djakov struct icc_provider *provider;
10211f1cecaSGeorgi Djakov struct list_head node_list;
10311f1cecaSGeorgi Djakov struct list_head search_list;
10411f1cecaSGeorgi Djakov struct icc_node *reverse;
10511f1cecaSGeorgi Djakov u8 is_traversed:1;
10611f1cecaSGeorgi Djakov struct hlist_head req_list;
10711f1cecaSGeorgi Djakov u32 avg_bw;
10811f1cecaSGeorgi Djakov u32 peak_bw;
109b1d681d8SGeorgi Djakov u32 init_avg;
110b1d681d8SGeorgi Djakov u32 init_peak;
11111f1cecaSGeorgi Djakov void *data;
11211f1cecaSGeorgi Djakov };
11311f1cecaSGeorgi Djakov
11411f1cecaSGeorgi Djakov #if IS_ENABLED(CONFIG_INTERCONNECT)
11511f1cecaSGeorgi Djakov
1163172e4d2SGeorgi Djakov int icc_std_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
1173172e4d2SGeorgi Djakov u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
11811f1cecaSGeorgi Djakov struct icc_node *icc_node_create(int id);
11911f1cecaSGeorgi Djakov void icc_node_destroy(int id);
12011f1cecaSGeorgi Djakov int icc_link_create(struct icc_node *node, const int dst_id);
12111f1cecaSGeorgi Djakov void icc_node_add(struct icc_node *node, struct icc_provider *provider);
12211f1cecaSGeorgi Djakov void icc_node_del(struct icc_node *node);
1233cce2c6fSGeorgi Djakov int icc_nodes_remove(struct icc_provider *provider);
124eb59eca0SJohan Hovold void icc_provider_init(struct icc_provider *provider);
125eb59eca0SJohan Hovold int icc_provider_register(struct icc_provider *provider);
126eb59eca0SJohan Hovold void icc_provider_deregister(struct icc_provider *provider);
1271521e22bSGeorgi Djakov struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec);
128b1d681d8SGeorgi Djakov void icc_sync_state(struct device *dev);
12911f1cecaSGeorgi Djakov
13011f1cecaSGeorgi Djakov #else
13111f1cecaSGeorgi Djakov
icc_std_aggregate(struct icc_node * node,u32 tag,u32 avg_bw,u32 peak_bw,u32 * agg_avg,u32 * agg_peak)1323172e4d2SGeorgi Djakov static inline int icc_std_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
1333172e4d2SGeorgi Djakov u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
1343172e4d2SGeorgi Djakov {
1353172e4d2SGeorgi Djakov return -ENOTSUPP;
1363172e4d2SGeorgi Djakov }
1373172e4d2SGeorgi Djakov
icc_node_create(int id)13811f1cecaSGeorgi Djakov static inline struct icc_node *icc_node_create(int id)
13911f1cecaSGeorgi Djakov {
14011f1cecaSGeorgi Djakov return ERR_PTR(-ENOTSUPP);
14111f1cecaSGeorgi Djakov }
14211f1cecaSGeorgi Djakov
icc_node_destroy(int id)14312a400b0SGeorgi Djakov static inline void icc_node_destroy(int id)
14411f1cecaSGeorgi Djakov {
14511f1cecaSGeorgi Djakov }
14611f1cecaSGeorgi Djakov
icc_link_create(struct icc_node * node,const int dst_id)14711f1cecaSGeorgi Djakov static inline int icc_link_create(struct icc_node *node, const int dst_id)
14811f1cecaSGeorgi Djakov {
14911f1cecaSGeorgi Djakov return -ENOTSUPP;
15011f1cecaSGeorgi Djakov }
15111f1cecaSGeorgi Djakov
icc_node_add(struct icc_node * node,struct icc_provider * provider)15212a400b0SGeorgi Djakov static inline void icc_node_add(struct icc_node *node, struct icc_provider *provider)
15311f1cecaSGeorgi Djakov {
15411f1cecaSGeorgi Djakov }
15511f1cecaSGeorgi Djakov
icc_node_del(struct icc_node * node)15612a400b0SGeorgi Djakov static inline void icc_node_del(struct icc_node *node)
15711f1cecaSGeorgi Djakov {
15811f1cecaSGeorgi Djakov }
15911f1cecaSGeorgi Djakov
icc_nodes_remove(struct icc_provider * provider)1603cce2c6fSGeorgi Djakov static inline int icc_nodes_remove(struct icc_provider *provider)
1613cce2c6fSGeorgi Djakov {
1623cce2c6fSGeorgi Djakov return -ENOTSUPP;
1633cce2c6fSGeorgi Djakov }
1643cce2c6fSGeorgi Djakov
icc_provider_init(struct icc_provider * provider)165eb59eca0SJohan Hovold static inline void icc_provider_init(struct icc_provider *provider) { }
166eb59eca0SJohan Hovold
icc_provider_register(struct icc_provider * provider)167eb59eca0SJohan Hovold static inline int icc_provider_register(struct icc_provider *provider)
168eb59eca0SJohan Hovold {
169eb59eca0SJohan Hovold return -ENOTSUPP;
170eb59eca0SJohan Hovold }
171eb59eca0SJohan Hovold
icc_provider_deregister(struct icc_provider * provider)172eb59eca0SJohan Hovold static inline void icc_provider_deregister(struct icc_provider *provider) { }
173eb59eca0SJohan Hovold
of_icc_get_from_provider(struct of_phandle_args * spec)1741521e22bSGeorgi Djakov static inline struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec)
1758a307d36SArtur Świgoń {
1768a307d36SArtur Świgoń return ERR_PTR(-ENOTSUPP);
1778a307d36SArtur Świgoń }
1788a307d36SArtur Świgoń
17911f1cecaSGeorgi Djakov #endif /* CONFIG_INTERCONNECT */
18011f1cecaSGeorgi Djakov
18111f1cecaSGeorgi Djakov #endif /* __LINUX_INTERCONNECT_PROVIDER_H */
182