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