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