Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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 */
20struct 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 */
35struct 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 */
76struct 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 */
106struct 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
121struct qcom_icc_fabric {
122 struct qcom_icc_node **nodes;
123 size_t num_nodes;
124};
125
126struct 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
143int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
144 u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
145int qcom_icc_set(struct icc_node *src, struct icc_node *dst);
146int qcom_icc_bcm_init(struct qcom_icc_bcm *bcm, struct device *dev);
147void qcom_icc_pre_aggregate(struct icc_node *node);
148
149#endif