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