xref: /OK3568_Linux_fs/kernel/drivers/interconnect/qcom/icc-rpmh.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #ifndef __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__
7*4882a593Smuzhiyun #define __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <dt-bindings/interconnect/qcom,icc.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #define to_qcom_provider(_provider) \
12*4882a593Smuzhiyun 	container_of(_provider, struct qcom_icc_provider, provider)
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun /**
15*4882a593Smuzhiyun  * struct qcom_icc_provider - Qualcomm specific interconnect provider
16*4882a593Smuzhiyun  * @provider: generic interconnect provider
17*4882a593Smuzhiyun  * @dev: reference to the NoC device
18*4882a593Smuzhiyun  * @bcms: list of bcms that maps to the provider
19*4882a593Smuzhiyun  * @num_bcms: number of @bcms
20*4882a593Smuzhiyun  * @voter: bcm voter targeted by this provider
21*4882a593Smuzhiyun  */
22*4882a593Smuzhiyun struct qcom_icc_provider {
23*4882a593Smuzhiyun 	struct icc_provider provider;
24*4882a593Smuzhiyun 	struct device *dev;
25*4882a593Smuzhiyun 	struct qcom_icc_bcm **bcms;
26*4882a593Smuzhiyun 	size_t num_bcms;
27*4882a593Smuzhiyun 	struct bcm_voter *voter;
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /**
31*4882a593Smuzhiyun  * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager (BCM)
32*4882a593Smuzhiyun  * @unit: divisor used to convert bytes/sec bw value to an RPMh msg
33*4882a593Smuzhiyun  * @width: multiplier used to convert bytes/sec bw value to an RPMh msg
34*4882a593Smuzhiyun  * @vcd: virtual clock domain that this bcm belongs to
35*4882a593Smuzhiyun  * @reserved: reserved field
36*4882a593Smuzhiyun  */
37*4882a593Smuzhiyun struct bcm_db {
38*4882a593Smuzhiyun 	__le32 unit;
39*4882a593Smuzhiyun 	__le16 width;
40*4882a593Smuzhiyun 	u8 vcd;
41*4882a593Smuzhiyun 	u8 reserved;
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #define MAX_LINKS		128
45*4882a593Smuzhiyun #define MAX_BCMS		64
46*4882a593Smuzhiyun #define MAX_BCM_PER_NODE	3
47*4882a593Smuzhiyun #define MAX_VCD			10
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /**
50*4882a593Smuzhiyun  * struct qcom_icc_node - Qualcomm specific interconnect nodes
51*4882a593Smuzhiyun  * @name: the node name used in debugfs
52*4882a593Smuzhiyun  * @links: an array of nodes where we can go next while traversing
53*4882a593Smuzhiyun  * @id: a unique node identifier
54*4882a593Smuzhiyun  * @num_links: the total number of @links
55*4882a593Smuzhiyun  * @channels: num of channels at this node
56*4882a593Smuzhiyun  * @buswidth: width of the interconnect between a node and the bus
57*4882a593Smuzhiyun  * @sum_avg: current sum aggregate value of all avg bw requests
58*4882a593Smuzhiyun  * @max_peak: current max aggregate value of all peak bw requests
59*4882a593Smuzhiyun  * @bcms: list of bcms associated with this logical node
60*4882a593Smuzhiyun  * @num_bcms: num of @bcms
61*4882a593Smuzhiyun  */
62*4882a593Smuzhiyun struct qcom_icc_node {
63*4882a593Smuzhiyun 	const char *name;
64*4882a593Smuzhiyun 	u16 links[MAX_LINKS];
65*4882a593Smuzhiyun 	u16 id;
66*4882a593Smuzhiyun 	u16 num_links;
67*4882a593Smuzhiyun 	u16 channels;
68*4882a593Smuzhiyun 	u16 buswidth;
69*4882a593Smuzhiyun 	u64 sum_avg[QCOM_ICC_NUM_BUCKETS];
70*4882a593Smuzhiyun 	u64 max_peak[QCOM_ICC_NUM_BUCKETS];
71*4882a593Smuzhiyun 	struct qcom_icc_bcm *bcms[MAX_BCM_PER_NODE];
72*4882a593Smuzhiyun 	size_t num_bcms;
73*4882a593Smuzhiyun };
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun /**
76*4882a593Smuzhiyun  * struct qcom_icc_bcm - Qualcomm specific hardware accelerator nodes
77*4882a593Smuzhiyun  * known as Bus Clock Manager (BCM)
78*4882a593Smuzhiyun  * @name: the bcm node name used to fetch BCM data from command db
79*4882a593Smuzhiyun  * @type: latency or bandwidth bcm
80*4882a593Smuzhiyun  * @addr: address offsets used when voting to RPMH
81*4882a593Smuzhiyun  * @vote_x: aggregated threshold values, represents sum_bw when @type is bw bcm
82*4882a593Smuzhiyun  * @vote_y: aggregated threshold values, represents peak_bw when @type is bw bcm
83*4882a593Smuzhiyun  * @vote_scale: scaling factor for vote_x and vote_y
84*4882a593Smuzhiyun  * @dirty: flag used to indicate whether the bcm needs to be committed
85*4882a593Smuzhiyun  * @keepalive: flag used to indicate whether a keepalive is required
86*4882a593Smuzhiyun  * @aux_data: auxiliary data used when calculating threshold values and
87*4882a593Smuzhiyun  * communicating with RPMh
88*4882a593Smuzhiyun  * @list: used to link to other bcms when compiling lists for commit
89*4882a593Smuzhiyun  * @ws_list: used to keep track of bcms that may transition between wake/sleep
90*4882a593Smuzhiyun  * @num_nodes: total number of @num_nodes
91*4882a593Smuzhiyun  * @nodes: list of qcom_icc_nodes that this BCM encapsulates
92*4882a593Smuzhiyun  */
93*4882a593Smuzhiyun struct qcom_icc_bcm {
94*4882a593Smuzhiyun 	const char *name;
95*4882a593Smuzhiyun 	u32 type;
96*4882a593Smuzhiyun 	u32 addr;
97*4882a593Smuzhiyun 	u64 vote_x[QCOM_ICC_NUM_BUCKETS];
98*4882a593Smuzhiyun 	u64 vote_y[QCOM_ICC_NUM_BUCKETS];
99*4882a593Smuzhiyun 	u64 vote_scale;
100*4882a593Smuzhiyun 	bool dirty;
101*4882a593Smuzhiyun 	bool keepalive;
102*4882a593Smuzhiyun 	struct bcm_db aux_data;
103*4882a593Smuzhiyun 	struct list_head list;
104*4882a593Smuzhiyun 	struct list_head ws_list;
105*4882a593Smuzhiyun 	size_t num_nodes;
106*4882a593Smuzhiyun 	struct qcom_icc_node *nodes[];
107*4882a593Smuzhiyun };
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun struct qcom_icc_fabric {
110*4882a593Smuzhiyun 	struct qcom_icc_node **nodes;
111*4882a593Smuzhiyun 	size_t num_nodes;
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun struct qcom_icc_desc {
115*4882a593Smuzhiyun 	struct qcom_icc_node **nodes;
116*4882a593Smuzhiyun 	size_t num_nodes;
117*4882a593Smuzhiyun 	struct qcom_icc_bcm **bcms;
118*4882a593Smuzhiyun 	size_t num_bcms;
119*4882a593Smuzhiyun };
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun #define DEFINE_QNODE(_name, _id, _channels, _buswidth, ...)		\
122*4882a593Smuzhiyun 		static struct qcom_icc_node _name = {			\
123*4882a593Smuzhiyun 		.id = _id,						\
124*4882a593Smuzhiyun 		.name = #_name,						\
125*4882a593Smuzhiyun 		.channels = _channels,					\
126*4882a593Smuzhiyun 		.buswidth = _buswidth,					\
127*4882a593Smuzhiyun 		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
128*4882a593Smuzhiyun 		.links = { __VA_ARGS__ },				\
129*4882a593Smuzhiyun 	}
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
132*4882a593Smuzhiyun 		       u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
133*4882a593Smuzhiyun int qcom_icc_set(struct icc_node *src, struct icc_node *dst);
134*4882a593Smuzhiyun struct icc_node_data *qcom_icc_xlate_extended(struct of_phandle_args *spec, void *data);
135*4882a593Smuzhiyun int qcom_icc_bcm_init(struct qcom_icc_bcm *bcm, struct device *dev);
136*4882a593Smuzhiyun void qcom_icc_pre_aggregate(struct icc_node *node);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun #endif
139