]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - drivers/interconnect/qcom/sdm845.c
interconnect: Add support for path tags
[mirror_ubuntu-focal-kernel.git] / drivers / interconnect / qcom / sdm845.c
CommitLineData
b5d2f741
DD
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 *
5 */
6
7#include <asm/div64.h>
8#include <dt-bindings/interconnect/qcom,sdm845.h>
9#include <linux/device.h>
10#include <linux/interconnect.h>
11#include <linux/interconnect-provider.h>
12#include <linux/io.h>
13#include <linux/module.h>
14#include <linux/of_device.h>
15#include <linux/of_platform.h>
16#include <linux/platform_device.h>
17#include <linux/sort.h>
18
19#include <soc/qcom/cmd-db.h>
20#include <soc/qcom/rpmh.h>
21#include <soc/qcom/tcs.h>
22
23#define BCM_TCS_CMD_COMMIT_SHFT 30
24#define BCM_TCS_CMD_COMMIT_MASK 0x40000000
25#define BCM_TCS_CMD_VALID_SHFT 29
26#define BCM_TCS_CMD_VALID_MASK 0x20000000
27#define BCM_TCS_CMD_VOTE_X_SHFT 14
28#define BCM_TCS_CMD_VOTE_MASK 0x3fff
29#define BCM_TCS_CMD_VOTE_Y_SHFT 0
30#define BCM_TCS_CMD_VOTE_Y_MASK 0xfffc000
31
32#define BCM_TCS_CMD(commit, valid, vote_x, vote_y) \
33 (((commit) << BCM_TCS_CMD_COMMIT_SHFT) | \
34 ((valid) << BCM_TCS_CMD_VALID_SHFT) | \
35 ((cpu_to_le32(vote_x) & \
36 BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_X_SHFT) | \
37 ((cpu_to_le32(vote_y) & \
38 BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_Y_SHFT))
39
40#define to_qcom_provider(_provider) \
41 container_of(_provider, struct qcom_icc_provider, provider)
42
43struct qcom_icc_provider {
44 struct icc_provider provider;
45 struct device *dev;
46 struct qcom_icc_bcm **bcms;
47 size_t num_bcms;
48};
49
50/**
51 * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager (BCM)
52 * @unit: divisor used to convert bytes/sec bw value to an RPMh msg
53 * @width: multiplier used to convert bytes/sec bw value to an RPMh msg
54 * @vcd: virtual clock domain that this bcm belongs to
55 * @reserved: reserved field
56 */
57struct bcm_db {
58 __le32 unit;
59 __le16 width;
60 u8 vcd;
61 u8 reserved;
62};
63
64#define SDM845_MAX_LINKS 43
65#define SDM845_MAX_BCMS 30
66#define SDM845_MAX_BCM_PER_NODE 2
67#define SDM845_MAX_VCD 10
68
69/**
70 * struct qcom_icc_node - Qualcomm specific interconnect nodes
71 * @name: the node name used in debugfs
72 * @links: an array of nodes where we can go next while traversing
73 * @id: a unique node identifier
74 * @num_links: the total number of @links
75 * @channels: num of channels at this node
76 * @buswidth: width of the interconnect between a node and the bus
77 * @sum_avg: current sum aggregate value of all avg bw requests
78 * @max_peak: current max aggregate value of all peak bw requests
79 * @bcms: list of bcms associated with this logical node
80 * @num_bcms: num of @bcms
81 */
82struct qcom_icc_node {
83 const char *name;
84 u16 links[SDM845_MAX_LINKS];
85 u16 id;
86 u16 num_links;
87 u16 channels;
88 u16 buswidth;
89 u64 sum_avg;
90 u64 max_peak;
91 struct qcom_icc_bcm *bcms[SDM845_MAX_BCM_PER_NODE];
92 size_t num_bcms;
93};
94
95/**
96 * struct qcom_icc_bcm - Qualcomm specific hardware accelerator nodes
97 * known as Bus Clock Manager (BCM)
98 * @name: the bcm node name used to fetch BCM data from command db
99 * @type: latency or bandwidth bcm
100 * @addr: address offsets used when voting to RPMH
101 * @vote_x: aggregated threshold values, represents sum_bw when @type is bw bcm
102 * @vote_y: aggregated threshold values, represents peak_bw when @type is bw bcm
103 * @dirty: flag used to indicate whether the bcm needs to be committed
104 * @keepalive: flag used to indicate whether a keepalive is required
105 * @aux_data: auxiliary data used when calculating threshold values and
106 * communicating with RPMh
107 * @list: used to link to other bcms when compiling lists for commit
108 * @num_nodes: total number of @num_nodes
109 * @nodes: list of qcom_icc_nodes that this BCM encapsulates
110 */
111struct qcom_icc_bcm {
112 const char *name;
113 u32 type;
114 u32 addr;
115 u64 vote_x;
116 u64 vote_y;
117 bool dirty;
118 bool keepalive;
119 struct bcm_db aux_data;
120 struct list_head list;
121 size_t num_nodes;
122 struct qcom_icc_node *nodes[];
123};
124
125struct qcom_icc_fabric {
126 struct qcom_icc_node **nodes;
127 size_t num_nodes;
128};
129
130struct qcom_icc_desc {
131 struct qcom_icc_node **nodes;
132 size_t num_nodes;
133 struct qcom_icc_bcm **bcms;
134 size_t num_bcms;
135};
136
137#define DEFINE_QNODE(_name, _id, _channels, _buswidth, \
138 _numlinks, ...) \
139 static struct qcom_icc_node _name = { \
140 .id = _id, \
141 .name = #_name, \
142 .channels = _channels, \
143 .buswidth = _buswidth, \
144 .num_links = _numlinks, \
145 .links = { __VA_ARGS__ }, \
146 }
147
148DEFINE_QNODE(qhm_a1noc_cfg, MASTER_A1NOC_CFG, 1, 4, 1, SLAVE_SERVICE_A1NOC);
149DEFINE_QNODE(qhm_qup1, MASTER_BLSP_1, 1, 4, 1, SLAVE_A1NOC_SNOC);
150DEFINE_QNODE(qhm_tsif, MASTER_TSIF, 1, 4, 1, SLAVE_A1NOC_SNOC);
151DEFINE_QNODE(xm_sdc2, MASTER_SDCC_2, 1, 8, 1, SLAVE_A1NOC_SNOC);
152DEFINE_QNODE(xm_sdc4, MASTER_SDCC_4, 1, 8, 1, SLAVE_A1NOC_SNOC);
153DEFINE_QNODE(xm_ufs_card, MASTER_UFS_CARD, 1, 8, 1, SLAVE_A1NOC_SNOC);
154DEFINE_QNODE(xm_ufs_mem, MASTER_UFS_MEM, 1, 8, 1, SLAVE_A1NOC_SNOC);
155DEFINE_QNODE(xm_pcie_0, MASTER_PCIE_0, 1, 8, 1, SLAVE_ANOC_PCIE_A1NOC_SNOC);
156DEFINE_QNODE(qhm_a2noc_cfg, MASTER_A2NOC_CFG, 1, 4, 1, SLAVE_SERVICE_A2NOC);
157DEFINE_QNODE(qhm_qdss_bam, MASTER_QDSS_BAM, 1, 4, 1, SLAVE_A2NOC_SNOC);
158DEFINE_QNODE(qhm_qup2, MASTER_BLSP_2, 1, 4, 1, SLAVE_A2NOC_SNOC);
159DEFINE_QNODE(qnm_cnoc, MASTER_CNOC_A2NOC, 1, 8, 1, SLAVE_A2NOC_SNOC);
160DEFINE_QNODE(qxm_crypto, MASTER_CRYPTO, 1, 8, 1, SLAVE_A2NOC_SNOC);
161DEFINE_QNODE(qxm_ipa, MASTER_IPA, 1, 8, 1, SLAVE_A2NOC_SNOC);
162DEFINE_QNODE(xm_pcie3_1, MASTER_PCIE_1, 1, 8, 1, SLAVE_ANOC_PCIE_SNOC);
163DEFINE_QNODE(xm_qdss_etr, MASTER_QDSS_ETR, 1, 8, 1, SLAVE_A2NOC_SNOC);
164DEFINE_QNODE(xm_usb3_0, MASTER_USB3_0, 1, 8, 1, SLAVE_A2NOC_SNOC);
165DEFINE_QNODE(xm_usb3_1, MASTER_USB3_1, 1, 8, 1, SLAVE_A2NOC_SNOC);
166DEFINE_QNODE(qxm_camnoc_hf0_uncomp, MASTER_CAMNOC_HF0_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP);
167DEFINE_QNODE(qxm_camnoc_hf1_uncomp, MASTER_CAMNOC_HF1_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP);
168DEFINE_QNODE(qxm_camnoc_sf_uncomp, MASTER_CAMNOC_SF_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP);
169DEFINE_QNODE(qhm_spdm, MASTER_SPDM, 1, 4, 1, SLAVE_CNOC_A2NOC);
170DEFINE_QNODE(qhm_tic, MASTER_TIC, 1, 4, 43, SLAVE_A1NOC_CFG, SLAVE_A2NOC_CFG, SLAVE_AOP, SLAVE_AOSS, SLAVE_CAMERA_CFG, SLAVE_CLK_CTL, SLAVE_CDSP_CFG, SLAVE_RBCPR_CX_CFG, SLAVE_CRYPTO_0_CFG, SLAVE_DCC_CFG, SLAVE_CNOC_DDRSS, SLAVE_DISPLAY_CFG, SLAVE_GLM, SLAVE_GFX3D_CFG, SLAVE_IMEM_CFG, SLAVE_IPA_CFG, SLAVE_CNOC_MNOC_CFG, SLAVE_PCIE_0_CFG, SLAVE_PCIE_1_CFG, SLAVE_PDM, SLAVE_SOUTH_PHY_CFG, SLAVE_PIMEM_CFG, SLAVE_PRNG, SLAVE_QDSS_CFG, SLAVE_BLSP_2, SLAVE_BLSP_1, SLAVE_SDCC_2, SLAVE_SDCC_4, SLAVE_SNOC_CFG, SLAVE_SPDM_WRAPPER, SLAVE_SPSS_CFG, SLAVE_TCSR, SLAVE_TLMM_NORTH, SLAVE_TLMM_SOUTH, SLAVE_TSIF, SLAVE_UFS_CARD_CFG, SLAVE_UFS_MEM_CFG, SLAVE_USB3_0, SLAVE_USB3_1, SLAVE_VENUS_CFG, SLAVE_VSENSE_CTRL_CFG, SLAVE_CNOC_A2NOC, SLAVE_SERVICE_CNOC);
171DEFINE_QNODE(qnm_snoc, MASTER_SNOC_CNOC, 1, 8, 42, SLAVE_A1NOC_CFG, SLAVE_A2NOC_CFG, SLAVE_AOP, SLAVE_AOSS, SLAVE_CAMERA_CFG, SLAVE_CLK_CTL, SLAVE_CDSP_CFG, SLAVE_RBCPR_CX_CFG, SLAVE_CRYPTO_0_CFG, SLAVE_DCC_CFG, SLAVE_CNOC_DDRSS, SLAVE_DISPLAY_CFG, SLAVE_GLM, SLAVE_GFX3D_CFG, SLAVE_IMEM_CFG, SLAVE_IPA_CFG, SLAVE_CNOC_MNOC_CFG, SLAVE_PCIE_0_CFG, SLAVE_PCIE_1_CFG, SLAVE_PDM, SLAVE_SOUTH_PHY_CFG, SLAVE_PIMEM_CFG, SLAVE_PRNG, SLAVE_QDSS_CFG, SLAVE_BLSP_2, SLAVE_BLSP_1, SLAVE_SDCC_2, SLAVE_SDCC_4, SLAVE_SNOC_CFG, SLAVE_SPDM_WRAPPER, SLAVE_SPSS_CFG, SLAVE_TCSR, SLAVE_TLMM_NORTH, SLAVE_TLMM_SOUTH, SLAVE_TSIF, SLAVE_UFS_CARD_CFG, SLAVE_UFS_MEM_CFG, SLAVE_USB3_0, SLAVE_USB3_1, SLAVE_VENUS_CFG, SLAVE_VSENSE_CTRL_CFG, SLAVE_SERVICE_CNOC);
172DEFINE_QNODE(xm_qdss_dap, MASTER_QDSS_DAP, 1, 8, 43, SLAVE_A1NOC_CFG, SLAVE_A2NOC_CFG, SLAVE_AOP, SLAVE_AOSS, SLAVE_CAMERA_CFG, SLAVE_CLK_CTL, SLAVE_CDSP_CFG, SLAVE_RBCPR_CX_CFG, SLAVE_CRYPTO_0_CFG, SLAVE_DCC_CFG, SLAVE_CNOC_DDRSS, SLAVE_DISPLAY_CFG, SLAVE_GLM, SLAVE_GFX3D_CFG, SLAVE_IMEM_CFG, SLAVE_IPA_CFG, SLAVE_CNOC_MNOC_CFG, SLAVE_PCIE_0_CFG, SLAVE_PCIE_1_CFG, SLAVE_PDM, SLAVE_SOUTH_PHY_CFG, SLAVE_PIMEM_CFG, SLAVE_PRNG, SLAVE_QDSS_CFG, SLAVE_BLSP_2, SLAVE_BLSP_1, SLAVE_SDCC_2, SLAVE_SDCC_4, SLAVE_SNOC_CFG, SLAVE_SPDM_WRAPPER, SLAVE_SPSS_CFG, SLAVE_TCSR, SLAVE_TLMM_NORTH, SLAVE_TLMM_SOUTH, SLAVE_TSIF, SLAVE_UFS_CARD_CFG, SLAVE_UFS_MEM_CFG, SLAVE_USB3_0, SLAVE_USB3_1, SLAVE_VENUS_CFG, SLAVE_VSENSE_CTRL_CFG, SLAVE_CNOC_A2NOC, SLAVE_SERVICE_CNOC);
173DEFINE_QNODE(qhm_cnoc, MASTER_CNOC_DC_NOC, 1, 4, 2, SLAVE_LLCC_CFG, SLAVE_MEM_NOC_CFG);
174DEFINE_QNODE(acm_l3, MASTER_APPSS_PROC, 1, 16, 3, SLAVE_GNOC_SNOC, SLAVE_GNOC_MEM_NOC, SLAVE_SERVICE_GNOC);
175DEFINE_QNODE(pm_gnoc_cfg, MASTER_GNOC_CFG, 1, 4, 1, SLAVE_SERVICE_GNOC);
176DEFINE_QNODE(llcc_mc, MASTER_LLCC, 4, 4, 1, SLAVE_EBI1);
177DEFINE_QNODE(acm_tcu, MASTER_TCU_0, 1, 8, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC);
178DEFINE_QNODE(qhm_memnoc_cfg, MASTER_MEM_NOC_CFG, 1, 4, 2, SLAVE_MSS_PROC_MS_MPU_CFG, SLAVE_SERVICE_MEM_NOC);
179DEFINE_QNODE(qnm_apps, MASTER_GNOC_MEM_NOC, 2, 32, 1, SLAVE_LLCC);
180DEFINE_QNODE(qnm_mnoc_hf, MASTER_MNOC_HF_MEM_NOC, 2, 32, 2, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC);
181DEFINE_QNODE(qnm_mnoc_sf, MASTER_MNOC_SF_MEM_NOC, 1, 32, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC);
182DEFINE_QNODE(qnm_snoc_gc, MASTER_SNOC_GC_MEM_NOC, 1, 8, 1, SLAVE_LLCC);
183DEFINE_QNODE(qnm_snoc_sf, MASTER_SNOC_SF_MEM_NOC, 1, 16, 2, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC);
184DEFINE_QNODE(qxm_gpu, MASTER_GFX3D, 2, 32, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC);
185DEFINE_QNODE(qhm_mnoc_cfg, MASTER_CNOC_MNOC_CFG, 1, 4, 1, SLAVE_SERVICE_MNOC);
186DEFINE_QNODE(qxm_camnoc_hf0, MASTER_CAMNOC_HF0, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC);
187DEFINE_QNODE(qxm_camnoc_hf1, MASTER_CAMNOC_HF1, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC);
188DEFINE_QNODE(qxm_camnoc_sf, MASTER_CAMNOC_SF, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC);
189DEFINE_QNODE(qxm_mdp0, MASTER_MDP0, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC);
190DEFINE_QNODE(qxm_mdp1, MASTER_MDP1, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC);
191DEFINE_QNODE(qxm_rot, MASTER_ROTATOR, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC);
192DEFINE_QNODE(qxm_venus0, MASTER_VIDEO_P0, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC);
193DEFINE_QNODE(qxm_venus1, MASTER_VIDEO_P1, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC);
194DEFINE_QNODE(qxm_venus_arm9, MASTER_VIDEO_PROC, 1, 8, 1, SLAVE_MNOC_SF_MEM_NOC);
195DEFINE_QNODE(qhm_snoc_cfg, MASTER_SNOC_CFG, 1, 4, 1, SLAVE_SERVICE_SNOC);
196DEFINE_QNODE(qnm_aggre1_noc, MASTER_A1NOC_SNOC, 1, 16, 6, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_SNOC_MEM_NOC_SF, SLAVE_IMEM, SLAVE_PIMEM, SLAVE_QDSS_STM);
197DEFINE_QNODE(qnm_aggre2_noc, MASTER_A2NOC_SNOC, 1, 16, 9, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_SNOC_MEM_NOC_SF, SLAVE_IMEM, SLAVE_PCIE_0, SLAVE_PCIE_1, SLAVE_PIMEM, SLAVE_QDSS_STM, SLAVE_TCU);
198DEFINE_QNODE(qnm_gladiator_sodv, MASTER_GNOC_SNOC, 1, 8, 8, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_IMEM, SLAVE_PCIE_0, SLAVE_PCIE_1, SLAVE_PIMEM, SLAVE_QDSS_STM, SLAVE_TCU);
199DEFINE_QNODE(qnm_memnoc, MASTER_MEM_NOC_SNOC, 1, 8, 5, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_IMEM, SLAVE_PIMEM, SLAVE_QDSS_STM);
200DEFINE_QNODE(qnm_pcie_anoc, MASTER_ANOC_PCIE_SNOC, 1, 16, 5, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_SNOC_MEM_NOC_SF, SLAVE_IMEM, SLAVE_QDSS_STM);
201DEFINE_QNODE(qxm_pimem, MASTER_PIMEM, 1, 8, 2, SLAVE_SNOC_MEM_NOC_GC, SLAVE_IMEM);
202DEFINE_QNODE(xm_gic, MASTER_GIC, 1, 8, 2, SLAVE_SNOC_MEM_NOC_GC, SLAVE_IMEM);
203DEFINE_QNODE(qns_a1noc_snoc, SLAVE_A1NOC_SNOC, 1, 16, 1, MASTER_A1NOC_SNOC);
204DEFINE_QNODE(srvc_aggre1_noc, SLAVE_SERVICE_A1NOC, 1, 4, 0);
205DEFINE_QNODE(qns_pcie_a1noc_snoc, SLAVE_ANOC_PCIE_A1NOC_SNOC, 1, 16, 1, MASTER_ANOC_PCIE_SNOC);
206DEFINE_QNODE(qns_a2noc_snoc, SLAVE_A2NOC_SNOC, 1, 16, 1, MASTER_A2NOC_SNOC);
207DEFINE_QNODE(qns_pcie_snoc, SLAVE_ANOC_PCIE_SNOC, 1, 16, 1, MASTER_ANOC_PCIE_SNOC);
208DEFINE_QNODE(srvc_aggre2_noc, SLAVE_SERVICE_A2NOC, 1, 4, 0);
209DEFINE_QNODE(qns_camnoc_uncomp, SLAVE_CAMNOC_UNCOMP, 1, 32, 0);
210DEFINE_QNODE(qhs_a1_noc_cfg, SLAVE_A1NOC_CFG, 1, 4, 1, MASTER_A1NOC_CFG);
211DEFINE_QNODE(qhs_a2_noc_cfg, SLAVE_A2NOC_CFG, 1, 4, 1, MASTER_A2NOC_CFG);
212DEFINE_QNODE(qhs_aop, SLAVE_AOP, 1, 4, 0);
213DEFINE_QNODE(qhs_aoss, SLAVE_AOSS, 1, 4, 0);
214DEFINE_QNODE(qhs_camera_cfg, SLAVE_CAMERA_CFG, 1, 4, 0);
215DEFINE_QNODE(qhs_clk_ctl, SLAVE_CLK_CTL, 1, 4, 0);
216DEFINE_QNODE(qhs_compute_dsp_cfg, SLAVE_CDSP_CFG, 1, 4, 0);
217DEFINE_QNODE(qhs_cpr_cx, SLAVE_RBCPR_CX_CFG, 1, 4, 0);
218DEFINE_QNODE(qhs_crypto0_cfg, SLAVE_CRYPTO_0_CFG, 1, 4, 0);
219DEFINE_QNODE(qhs_dcc_cfg, SLAVE_DCC_CFG, 1, 4, 1, MASTER_CNOC_DC_NOC);
220DEFINE_QNODE(qhs_ddrss_cfg, SLAVE_CNOC_DDRSS, 1, 4, 0);
221DEFINE_QNODE(qhs_display_cfg, SLAVE_DISPLAY_CFG, 1, 4, 0);
222DEFINE_QNODE(qhs_glm, SLAVE_GLM, 1, 4, 0);
223DEFINE_QNODE(qhs_gpuss_cfg, SLAVE_GFX3D_CFG, 1, 8, 0);
224DEFINE_QNODE(qhs_imem_cfg, SLAVE_IMEM_CFG, 1, 4, 0);
225DEFINE_QNODE(qhs_ipa, SLAVE_IPA_CFG, 1, 4, 0);
226DEFINE_QNODE(qhs_mnoc_cfg, SLAVE_CNOC_MNOC_CFG, 1, 4, 1, MASTER_CNOC_MNOC_CFG);
227DEFINE_QNODE(qhs_pcie0_cfg, SLAVE_PCIE_0_CFG, 1, 4, 0);
228DEFINE_QNODE(qhs_pcie_gen3_cfg, SLAVE_PCIE_1_CFG, 1, 4, 0);
229DEFINE_QNODE(qhs_pdm, SLAVE_PDM, 1, 4, 0);
230DEFINE_QNODE(qhs_phy_refgen_south, SLAVE_SOUTH_PHY_CFG, 1, 4, 0);
231DEFINE_QNODE(qhs_pimem_cfg, SLAVE_PIMEM_CFG, 1, 4, 0);
232DEFINE_QNODE(qhs_prng, SLAVE_PRNG, 1, 4, 0);
233DEFINE_QNODE(qhs_qdss_cfg, SLAVE_QDSS_CFG, 1, 4, 0);
234DEFINE_QNODE(qhs_qupv3_north, SLAVE_BLSP_2, 1, 4, 0);
235DEFINE_QNODE(qhs_qupv3_south, SLAVE_BLSP_1, 1, 4, 0);
236DEFINE_QNODE(qhs_sdc2, SLAVE_SDCC_2, 1, 4, 0);
237DEFINE_QNODE(qhs_sdc4, SLAVE_SDCC_4, 1, 4, 0);
238DEFINE_QNODE(qhs_snoc_cfg, SLAVE_SNOC_CFG, 1, 4, 1, MASTER_SNOC_CFG);
239DEFINE_QNODE(qhs_spdm, SLAVE_SPDM_WRAPPER, 1, 4, 0);
240DEFINE_QNODE(qhs_spss_cfg, SLAVE_SPSS_CFG, 1, 4, 0);
241DEFINE_QNODE(qhs_tcsr, SLAVE_TCSR, 1, 4, 0);
242DEFINE_QNODE(qhs_tlmm_north, SLAVE_TLMM_NORTH, 1, 4, 0);
243DEFINE_QNODE(qhs_tlmm_south, SLAVE_TLMM_SOUTH, 1, 4, 0);
244DEFINE_QNODE(qhs_tsif, SLAVE_TSIF, 1, 4, 0);
245DEFINE_QNODE(qhs_ufs_card_cfg, SLAVE_UFS_CARD_CFG, 1, 4, 0);
246DEFINE_QNODE(qhs_ufs_mem_cfg, SLAVE_UFS_MEM_CFG, 1, 4, 0);
247DEFINE_QNODE(qhs_usb3_0, SLAVE_USB3_0, 1, 4, 0);
248DEFINE_QNODE(qhs_usb3_1, SLAVE_USB3_1, 1, 4, 0);
249DEFINE_QNODE(qhs_venus_cfg, SLAVE_VENUS_CFG, 1, 4, 0);
250DEFINE_QNODE(qhs_vsense_ctrl_cfg, SLAVE_VSENSE_CTRL_CFG, 1, 4, 0);
251DEFINE_QNODE(qns_cnoc_a2noc, SLAVE_CNOC_A2NOC, 1, 8, 1, MASTER_CNOC_A2NOC);
252DEFINE_QNODE(srvc_cnoc, SLAVE_SERVICE_CNOC, 1, 4, 0);
253DEFINE_QNODE(qhs_llcc, SLAVE_LLCC_CFG, 1, 4, 0);
254DEFINE_QNODE(qhs_memnoc, SLAVE_MEM_NOC_CFG, 1, 4, 1, MASTER_MEM_NOC_CFG);
255DEFINE_QNODE(qns_gladiator_sodv, SLAVE_GNOC_SNOC, 1, 8, 1, MASTER_GNOC_SNOC);
256DEFINE_QNODE(qns_gnoc_memnoc, SLAVE_GNOC_MEM_NOC, 2, 32, 1, MASTER_GNOC_MEM_NOC);
257DEFINE_QNODE(srvc_gnoc, SLAVE_SERVICE_GNOC, 1, 4, 0);
258DEFINE_QNODE(ebi, SLAVE_EBI1, 4, 4, 0);
259DEFINE_QNODE(qhs_mdsp_ms_mpu_cfg, SLAVE_MSS_PROC_MS_MPU_CFG, 1, 4, 0);
260DEFINE_QNODE(qns_apps_io, SLAVE_MEM_NOC_GNOC, 1, 32, 0);
261DEFINE_QNODE(qns_llcc, SLAVE_LLCC, 4, 16, 1, MASTER_LLCC);
262DEFINE_QNODE(qns_memnoc_snoc, SLAVE_MEM_NOC_SNOC, 1, 8, 1, MASTER_MEM_NOC_SNOC);
263DEFINE_QNODE(srvc_memnoc, SLAVE_SERVICE_MEM_NOC, 1, 4, 0);
264DEFINE_QNODE(qns2_mem_noc, SLAVE_MNOC_SF_MEM_NOC, 1, 32, 1, MASTER_MNOC_SF_MEM_NOC);
265DEFINE_QNODE(qns_mem_noc_hf, SLAVE_MNOC_HF_MEM_NOC, 2, 32, 1, MASTER_MNOC_HF_MEM_NOC);
266DEFINE_QNODE(srvc_mnoc, SLAVE_SERVICE_MNOC, 1, 4, 0);
267DEFINE_QNODE(qhs_apss, SLAVE_APPSS, 1, 8, 0);
268DEFINE_QNODE(qns_cnoc, SLAVE_SNOC_CNOC, 1, 8, 1, MASTER_SNOC_CNOC);
269DEFINE_QNODE(qns_memnoc_gc, SLAVE_SNOC_MEM_NOC_GC, 1, 8, 1, MASTER_SNOC_GC_MEM_NOC);
270DEFINE_QNODE(qns_memnoc_sf, SLAVE_SNOC_MEM_NOC_SF, 1, 16, 1, MASTER_SNOC_SF_MEM_NOC);
271DEFINE_QNODE(qxs_imem, SLAVE_IMEM, 1, 8, 0);
272DEFINE_QNODE(qxs_pcie, SLAVE_PCIE_0, 1, 8, 0);
273DEFINE_QNODE(qxs_pcie_gen3, SLAVE_PCIE_1, 1, 8, 0);
274DEFINE_QNODE(qxs_pimem, SLAVE_PIMEM, 1, 8, 0);
275DEFINE_QNODE(srvc_snoc, SLAVE_SERVICE_SNOC, 1, 4, 0);
276DEFINE_QNODE(xs_qdss_stm, SLAVE_QDSS_STM, 1, 4, 0);
277DEFINE_QNODE(xs_sys_tcu_cfg, SLAVE_TCU, 1, 8, 0);
278
279#define DEFINE_QBCM(_name, _bcmname, _keepalive, _numnodes, ...) \
280 static struct qcom_icc_bcm _name = { \
281 .name = _bcmname, \
282 .keepalive = _keepalive, \
283 .num_nodes = _numnodes, \
284 .nodes = { __VA_ARGS__ }, \
285 }
286
287DEFINE_QBCM(bcm_acv, "ACV", false, 1, &ebi);
288DEFINE_QBCM(bcm_mc0, "MC0", true, 1, &ebi);
289DEFINE_QBCM(bcm_sh0, "SH0", true, 1, &qns_llcc);
290DEFINE_QBCM(bcm_mm0, "MM0", false, 1, &qns_mem_noc_hf);
291DEFINE_QBCM(bcm_sh1, "SH1", false, 1, &qns_apps_io);
292DEFINE_QBCM(bcm_mm1, "MM1", false, 7, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qxm_camnoc_hf0, &qxm_camnoc_hf1, &qxm_mdp0, &qxm_mdp1);
293DEFINE_QBCM(bcm_sh2, "SH2", false, 1, &qns_memnoc_snoc);
294DEFINE_QBCM(bcm_mm2, "MM2", false, 1, &qns2_mem_noc);
295DEFINE_QBCM(bcm_sh3, "SH3", false, 1, &acm_tcu);
296DEFINE_QBCM(bcm_mm3, "MM3", false, 5, &qxm_camnoc_sf, &qxm_rot, &qxm_venus0, &qxm_venus1, &qxm_venus_arm9);
297DEFINE_QBCM(bcm_sh5, "SH5", false, 1, &qnm_apps);
298DEFINE_QBCM(bcm_sn0, "SN0", true, 1, &qns_memnoc_sf);
299DEFINE_QBCM(bcm_ce0, "CE0", false, 1, &qxm_crypto);
300DEFINE_QBCM(bcm_cn0, "CN0", false, 47, &qhm_spdm, &qhm_tic, &qnm_snoc, &xm_qdss_dap, &qhs_a1_noc_cfg, &qhs_a2_noc_cfg, &qhs_aop, &qhs_aoss, &qhs_camera_cfg, &qhs_clk_ctl, &qhs_compute_dsp_cfg, &qhs_cpr_cx, &qhs_crypto0_cfg, &qhs_dcc_cfg, &qhs_ddrss_cfg, &qhs_display_cfg, &qhs_glm, &qhs_gpuss_cfg, &qhs_imem_cfg, &qhs_ipa, &qhs_mnoc_cfg, &qhs_pcie0_cfg, &qhs_pcie_gen3_cfg, &qhs_pdm, &qhs_phy_refgen_south, &qhs_pimem_cfg, &qhs_prng, &qhs_qdss_cfg, &qhs_qupv3_north, &qhs_qupv3_south, &qhs_sdc2, &qhs_sdc4, &qhs_snoc_cfg, &qhs_spdm, &qhs_spss_cfg, &qhs_tcsr, &qhs_tlmm_north, &qhs_tlmm_south, &qhs_tsif, &qhs_ufs_card_cfg, &qhs_ufs_mem_cfg, &qhs_usb3_0, &qhs_usb3_1, &qhs_venus_cfg, &qhs_vsense_ctrl_cfg, &qns_cnoc_a2noc, &srvc_cnoc);
301DEFINE_QBCM(bcm_qup0, "QUP0", false, 2, &qhm_qup1, &qhm_qup2);
302DEFINE_QBCM(bcm_sn1, "SN1", false, 1, &qxs_imem);
303DEFINE_QBCM(bcm_sn2, "SN2", false, 1, &qns_memnoc_gc);
304DEFINE_QBCM(bcm_sn3, "SN3", false, 1, &qns_cnoc);
305DEFINE_QBCM(bcm_sn4, "SN4", false, 1, &qxm_pimem);
306DEFINE_QBCM(bcm_sn5, "SN5", false, 1, &xs_qdss_stm);
307DEFINE_QBCM(bcm_sn6, "SN6", false, 3, &qhs_apss, &srvc_snoc, &xs_sys_tcu_cfg);
308DEFINE_QBCM(bcm_sn7, "SN7", false, 1, &qxs_pcie);
309DEFINE_QBCM(bcm_sn8, "SN8", false, 1, &qxs_pcie_gen3);
310DEFINE_QBCM(bcm_sn9, "SN9", false, 2, &srvc_aggre1_noc, &qnm_aggre1_noc);
311DEFINE_QBCM(bcm_sn11, "SN11", false, 2, &srvc_aggre2_noc, &qnm_aggre2_noc);
312DEFINE_QBCM(bcm_sn12, "SN12", false, 2, &qnm_gladiator_sodv, &xm_gic);
313DEFINE_QBCM(bcm_sn14, "SN14", false, 1, &qnm_pcie_anoc);
314DEFINE_QBCM(bcm_sn15, "SN15", false, 1, &qnm_memnoc);
315
316static struct qcom_icc_node *rsc_hlos_nodes[] = {
317 [MASTER_APPSS_PROC] = &acm_l3,
318 [MASTER_TCU_0] = &acm_tcu,
319 [MASTER_LLCC] = &llcc_mc,
320 [MASTER_GNOC_CFG] = &pm_gnoc_cfg,
321 [MASTER_A1NOC_CFG] = &qhm_a1noc_cfg,
322 [MASTER_A2NOC_CFG] = &qhm_a2noc_cfg,
323 [MASTER_CNOC_DC_NOC] = &qhm_cnoc,
324 [MASTER_MEM_NOC_CFG] = &qhm_memnoc_cfg,
325 [MASTER_CNOC_MNOC_CFG] = &qhm_mnoc_cfg,
326 [MASTER_QDSS_BAM] = &qhm_qdss_bam,
327 [MASTER_BLSP_1] = &qhm_qup1,
328 [MASTER_BLSP_2] = &qhm_qup2,
329 [MASTER_SNOC_CFG] = &qhm_snoc_cfg,
330 [MASTER_SPDM] = &qhm_spdm,
331 [MASTER_TIC] = &qhm_tic,
332 [MASTER_TSIF] = &qhm_tsif,
333 [MASTER_A1NOC_SNOC] = &qnm_aggre1_noc,
334 [MASTER_A2NOC_SNOC] = &qnm_aggre2_noc,
335 [MASTER_GNOC_MEM_NOC] = &qnm_apps,
336 [MASTER_CNOC_A2NOC] = &qnm_cnoc,
337 [MASTER_GNOC_SNOC] = &qnm_gladiator_sodv,
338 [MASTER_MEM_NOC_SNOC] = &qnm_memnoc,
339 [MASTER_MNOC_HF_MEM_NOC] = &qnm_mnoc_hf,
340 [MASTER_MNOC_SF_MEM_NOC] = &qnm_mnoc_sf,
341 [MASTER_ANOC_PCIE_SNOC] = &qnm_pcie_anoc,
342 [MASTER_SNOC_CNOC] = &qnm_snoc,
343 [MASTER_SNOC_GC_MEM_NOC] = &qnm_snoc_gc,
344 [MASTER_SNOC_SF_MEM_NOC] = &qnm_snoc_sf,
345 [MASTER_CAMNOC_HF0] = &qxm_camnoc_hf0,
346 [MASTER_CAMNOC_HF0_UNCOMP] = &qxm_camnoc_hf0_uncomp,
347 [MASTER_CAMNOC_HF1] = &qxm_camnoc_hf1,
348 [MASTER_CAMNOC_HF1_UNCOMP] = &qxm_camnoc_hf1_uncomp,
349 [MASTER_CAMNOC_SF] = &qxm_camnoc_sf,
350 [MASTER_CAMNOC_SF_UNCOMP] = &qxm_camnoc_sf_uncomp,
351 [MASTER_CRYPTO] = &qxm_crypto,
352 [MASTER_GFX3D] = &qxm_gpu,
353 [MASTER_IPA] = &qxm_ipa,
354 [MASTER_MDP0] = &qxm_mdp0,
355 [MASTER_MDP1] = &qxm_mdp1,
356 [MASTER_PIMEM] = &qxm_pimem,
357 [MASTER_ROTATOR] = &qxm_rot,
358 [MASTER_VIDEO_P0] = &qxm_venus0,
359 [MASTER_VIDEO_P1] = &qxm_venus1,
360 [MASTER_VIDEO_PROC] = &qxm_venus_arm9,
361 [MASTER_GIC] = &xm_gic,
362 [MASTER_PCIE_1] = &xm_pcie3_1,
363 [MASTER_PCIE_0] = &xm_pcie_0,
364 [MASTER_QDSS_DAP] = &xm_qdss_dap,
365 [MASTER_QDSS_ETR] = &xm_qdss_etr,
366 [MASTER_SDCC_2] = &xm_sdc2,
367 [MASTER_SDCC_4] = &xm_sdc4,
368 [MASTER_UFS_CARD] = &xm_ufs_card,
369 [MASTER_UFS_MEM] = &xm_ufs_mem,
370 [MASTER_USB3_0] = &xm_usb3_0,
371 [MASTER_USB3_1] = &xm_usb3_1,
372 [SLAVE_EBI1] = &ebi,
373 [SLAVE_A1NOC_CFG] = &qhs_a1_noc_cfg,
374 [SLAVE_A2NOC_CFG] = &qhs_a2_noc_cfg,
375 [SLAVE_AOP] = &qhs_aop,
376 [SLAVE_AOSS] = &qhs_aoss,
377 [SLAVE_APPSS] = &qhs_apss,
378 [SLAVE_CAMERA_CFG] = &qhs_camera_cfg,
379 [SLAVE_CLK_CTL] = &qhs_clk_ctl,
380 [SLAVE_CDSP_CFG] = &qhs_compute_dsp_cfg,
381 [SLAVE_RBCPR_CX_CFG] = &qhs_cpr_cx,
382 [SLAVE_CRYPTO_0_CFG] = &qhs_crypto0_cfg,
383 [SLAVE_DCC_CFG] = &qhs_dcc_cfg,
384 [SLAVE_CNOC_DDRSS] = &qhs_ddrss_cfg,
385 [SLAVE_DISPLAY_CFG] = &qhs_display_cfg,
386 [SLAVE_GLM] = &qhs_glm,
387 [SLAVE_GFX3D_CFG] = &qhs_gpuss_cfg,
388 [SLAVE_IMEM_CFG] = &qhs_imem_cfg,
389 [SLAVE_IPA_CFG] = &qhs_ipa,
390 [SLAVE_LLCC_CFG] = &qhs_llcc,
391 [SLAVE_MSS_PROC_MS_MPU_CFG] = &qhs_mdsp_ms_mpu_cfg,
392 [SLAVE_MEM_NOC_CFG] = &qhs_memnoc,
393 [SLAVE_CNOC_MNOC_CFG] = &qhs_mnoc_cfg,
394 [SLAVE_PCIE_0_CFG] = &qhs_pcie0_cfg,
395 [SLAVE_PCIE_1_CFG] = &qhs_pcie_gen3_cfg,
396 [SLAVE_PDM] = &qhs_pdm,
397 [SLAVE_SOUTH_PHY_CFG] = &qhs_phy_refgen_south,
398 [SLAVE_PIMEM_CFG] = &qhs_pimem_cfg,
399 [SLAVE_PRNG] = &qhs_prng,
400 [SLAVE_QDSS_CFG] = &qhs_qdss_cfg,
401 [SLAVE_BLSP_2] = &qhs_qupv3_north,
402 [SLAVE_BLSP_1] = &qhs_qupv3_south,
403 [SLAVE_SDCC_2] = &qhs_sdc2,
404 [SLAVE_SDCC_4] = &qhs_sdc4,
405 [SLAVE_SNOC_CFG] = &qhs_snoc_cfg,
406 [SLAVE_SPDM_WRAPPER] = &qhs_spdm,
407 [SLAVE_SPSS_CFG] = &qhs_spss_cfg,
408 [SLAVE_TCSR] = &qhs_tcsr,
409 [SLAVE_TLMM_NORTH] = &qhs_tlmm_north,
410 [SLAVE_TLMM_SOUTH] = &qhs_tlmm_south,
411 [SLAVE_TSIF] = &qhs_tsif,
412 [SLAVE_UFS_CARD_CFG] = &qhs_ufs_card_cfg,
413 [SLAVE_UFS_MEM_CFG] = &qhs_ufs_mem_cfg,
414 [SLAVE_USB3_0] = &qhs_usb3_0,
415 [SLAVE_USB3_1] = &qhs_usb3_1,
416 [SLAVE_VENUS_CFG] = &qhs_venus_cfg,
417 [SLAVE_VSENSE_CTRL_CFG] = &qhs_vsense_ctrl_cfg,
418 [SLAVE_MNOC_SF_MEM_NOC] = &qns2_mem_noc,
419 [SLAVE_A1NOC_SNOC] = &qns_a1noc_snoc,
420 [SLAVE_A2NOC_SNOC] = &qns_a2noc_snoc,
421 [SLAVE_MEM_NOC_GNOC] = &qns_apps_io,
422 [SLAVE_CAMNOC_UNCOMP] = &qns_camnoc_uncomp,
423 [SLAVE_SNOC_CNOC] = &qns_cnoc,
424 [SLAVE_CNOC_A2NOC] = &qns_cnoc_a2noc,
425 [SLAVE_GNOC_SNOC] = &qns_gladiator_sodv,
426 [SLAVE_GNOC_MEM_NOC] = &qns_gnoc_memnoc,
427 [SLAVE_LLCC] = &qns_llcc,
428 [SLAVE_MNOC_HF_MEM_NOC] = &qns_mem_noc_hf,
429 [SLAVE_SNOC_MEM_NOC_GC] = &qns_memnoc_gc,
430 [SLAVE_SNOC_MEM_NOC_SF] = &qns_memnoc_sf,
431 [SLAVE_MEM_NOC_SNOC] = &qns_memnoc_snoc,
432 [SLAVE_ANOC_PCIE_A1NOC_SNOC] = &qns_pcie_a1noc_snoc,
433 [SLAVE_ANOC_PCIE_SNOC] = &qns_pcie_snoc,
434 [SLAVE_IMEM] = &qxs_imem,
435 [SLAVE_PCIE_0] = &qxs_pcie,
436 [SLAVE_PCIE_1] = &qxs_pcie_gen3,
437 [SLAVE_PIMEM] = &qxs_pimem,
438 [SLAVE_SERVICE_A1NOC] = &srvc_aggre1_noc,
439 [SLAVE_SERVICE_A2NOC] = &srvc_aggre2_noc,
440 [SLAVE_SERVICE_CNOC] = &srvc_cnoc,
441 [SLAVE_SERVICE_GNOC] = &srvc_gnoc,
442 [SLAVE_SERVICE_MEM_NOC] = &srvc_memnoc,
443 [SLAVE_SERVICE_MNOC] = &srvc_mnoc,
444 [SLAVE_SERVICE_SNOC] = &srvc_snoc,
445 [SLAVE_QDSS_STM] = &xs_qdss_stm,
446 [SLAVE_TCU] = &xs_sys_tcu_cfg,
447};
448
449static struct qcom_icc_bcm *rsc_hlos_bcms[] = {
450 &bcm_acv,
451 &bcm_mc0,
452 &bcm_sh0,
453 &bcm_mm0,
454 &bcm_sh1,
455 &bcm_mm1,
456 &bcm_sh2,
457 &bcm_mm2,
458 &bcm_sh3,
459 &bcm_mm3,
460 &bcm_sh5,
461 &bcm_sn0,
462 &bcm_ce0,
463 &bcm_cn0,
464 &bcm_qup0,
465 &bcm_sn1,
466 &bcm_sn2,
467 &bcm_sn3,
468 &bcm_sn4,
469 &bcm_sn5,
470 &bcm_sn6,
471 &bcm_sn7,
472 &bcm_sn8,
473 &bcm_sn9,
474 &bcm_sn11,
475 &bcm_sn12,
476 &bcm_sn14,
477 &bcm_sn15,
478};
479
480static struct qcom_icc_desc sdm845_rsc_hlos = {
481 .nodes = rsc_hlos_nodes,
482 .num_nodes = ARRAY_SIZE(rsc_hlos_nodes),
483 .bcms = rsc_hlos_bcms,
484 .num_bcms = ARRAY_SIZE(rsc_hlos_bcms),
485};
486
487static int qcom_icc_bcm_init(struct qcom_icc_bcm *bcm, struct device *dev)
488{
489 struct qcom_icc_node *qn;
490 const struct bcm_db *data;
491 size_t data_count;
492 int i;
493
494 bcm->addr = cmd_db_read_addr(bcm->name);
495 if (!bcm->addr) {
496 dev_err(dev, "%s could not find RPMh address\n",
497 bcm->name);
498 return -EINVAL;
499 }
500
501 data = cmd_db_read_aux_data(bcm->name, &data_count);
502 if (IS_ERR(data)) {
503 dev_err(dev, "%s command db read error (%ld)\n",
504 bcm->name, PTR_ERR(data));
505 return PTR_ERR(data);
506 }
507 if (!data_count) {
508 dev_err(dev, "%s command db missing or partial aux data\n",
509 bcm->name);
510 return -EINVAL;
511 }
512
513 bcm->aux_data.unit = le32_to_cpu(data->unit);
514 bcm->aux_data.width = le16_to_cpu(data->width);
515 bcm->aux_data.vcd = data->vcd;
516 bcm->aux_data.reserved = data->reserved;
517
518 /*
519 * Link Qnodes to their respective BCMs
520 */
521 for (i = 0; i < bcm->num_nodes; i++) {
522 qn = bcm->nodes[i];
523 qn->bcms[qn->num_bcms] = bcm;
524 qn->num_bcms++;
525 }
526
527 return 0;
528}
529
530inline void tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x, u64 vote_y,
531 u32 addr, bool commit)
532{
533 bool valid = true;
534
535 if (!cmd)
536 return;
537
538 if (vote_x == 0 && vote_y == 0)
539 valid = false;
540
541 if (vote_x > BCM_TCS_CMD_VOTE_MASK)
542 vote_x = BCM_TCS_CMD_VOTE_MASK;
543
544 if (vote_y > BCM_TCS_CMD_VOTE_MASK)
545 vote_y = BCM_TCS_CMD_VOTE_MASK;
546
547 cmd->addr = addr;
548 cmd->data = BCM_TCS_CMD(commit, valid, vote_x, vote_y);
549
550 /*
551 * Set the wait for completion flag on command that need to be completed
552 * before the next command.
553 */
554 if (commit)
555 cmd->wait = true;
556}
557
558static void tcs_list_gen(struct list_head *bcm_list,
559 struct tcs_cmd tcs_list[SDM845_MAX_VCD],
560 int n[SDM845_MAX_VCD])
561{
562 struct qcom_icc_bcm *bcm;
563 bool commit;
564 size_t idx = 0, batch = 0, cur_vcd_size = 0;
565
566 memset(n, 0, sizeof(int) * SDM845_MAX_VCD);
567
568 list_for_each_entry(bcm, bcm_list, list) {
569 commit = false;
570 cur_vcd_size++;
571 if ((list_is_last(&bcm->list, bcm_list)) ||
572 bcm->aux_data.vcd != list_next_entry(bcm, list)->aux_data.vcd) {
573 commit = true;
574 cur_vcd_size = 0;
575 }
576 tcs_cmd_gen(&tcs_list[idx], bcm->vote_x, bcm->vote_y,
577 bcm->addr, commit);
578 idx++;
579 n[batch]++;
580 /*
581 * Batch the BCMs in such a way that we do not split them in
582 * multiple payloads when they are under the same VCD. This is
583 * to ensure that every BCM is committed since we only set the
584 * commit bit on the last BCM request of every VCD.
585 */
586 if (n[batch] >= MAX_RPMH_PAYLOAD) {
587 if (!commit) {
588 n[batch] -= cur_vcd_size;
589 n[batch + 1] = cur_vcd_size;
590 }
591 batch++;
592 }
593 }
594}
595
596static void bcm_aggregate(struct qcom_icc_bcm *bcm)
597{
598 size_t i;
599 u64 agg_avg = 0;
600 u64 agg_peak = 0;
601 u64 temp;
602
603 for (i = 0; i < bcm->num_nodes; i++) {
604 temp = bcm->nodes[i]->sum_avg * bcm->aux_data.width;
605 do_div(temp, bcm->nodes[i]->buswidth * bcm->nodes[i]->channels);
606 agg_avg = max(agg_avg, temp);
607
608 temp = bcm->nodes[i]->max_peak * bcm->aux_data.width;
609 do_div(temp, bcm->nodes[i]->buswidth);
610 agg_peak = max(agg_peak, temp);
611 }
612
613 temp = agg_avg * 1000ULL;
614 do_div(temp, bcm->aux_data.unit);
615 bcm->vote_x = temp;
616
617 temp = agg_peak * 1000ULL;
618 do_div(temp, bcm->aux_data.unit);
619 bcm->vote_y = temp;
620
621 if (bcm->keepalive && bcm->vote_x == 0 && bcm->vote_y == 0) {
622 bcm->vote_x = 1;
623 bcm->vote_y = 1;
624 }
625
626 bcm->dirty = false;
627}
628
127ab2cc 629static int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
b5d2f741
DD
630 u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
631{
632 size_t i;
633 struct qcom_icc_node *qn;
634
635 qn = node->data;
636
637 *agg_avg += avg_bw;
638 *agg_peak = max_t(u32, *agg_peak, peak_bw);
639
640 qn->sum_avg = *agg_avg;
641 qn->max_peak = *agg_peak;
642
643 for (i = 0; i < qn->num_bcms; i++)
644 qn->bcms[i]->dirty = true;
645
646 return 0;
647}
648
649static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
650{
651 struct qcom_icc_provider *qp;
652 struct icc_node *node;
653 struct tcs_cmd cmds[SDM845_MAX_BCMS];
654 struct list_head commit_list;
655 int commit_idx[SDM845_MAX_VCD];
656 int ret = 0, i;
657
658 if (!src)
659 node = dst;
660 else
661 node = src;
662
663 qp = to_qcom_provider(node->provider);
664
665 INIT_LIST_HEAD(&commit_list);
666
667 for (i = 0; i < qp->num_bcms; i++) {
668 if (qp->bcms[i]->dirty) {
669 bcm_aggregate(qp->bcms[i]);
670 list_add_tail(&qp->bcms[i]->list, &commit_list);
671 }
672 }
673
674 /*
675 * Construct the command list based on a pre ordered list of BCMs
676 * based on VCD.
677 */
678 tcs_list_gen(&commit_list, cmds, commit_idx);
679
680 if (!commit_idx[0])
681 return ret;
682
683 ret = rpmh_invalidate(qp->dev);
684 if (ret) {
685 pr_err("Error invalidating RPMH client (%d)\n", ret);
686 return ret;
687 }
688
689 ret = rpmh_write_batch(qp->dev, RPMH_ACTIVE_ONLY_STATE,
690 cmds, commit_idx);
691 if (ret) {
692 pr_err("Error sending AMC RPMH requests (%d)\n", ret);
693 return ret;
694 }
695
696 return ret;
697}
698
699static int cmp_vcd(const void *_l, const void *_r)
700{
701 const struct qcom_icc_bcm **l = (const struct qcom_icc_bcm **)_l;
702 const struct qcom_icc_bcm **r = (const struct qcom_icc_bcm **)_r;
703
704 if (l[0]->aux_data.vcd < r[0]->aux_data.vcd)
705 return -1;
706 else if (l[0]->aux_data.vcd == r[0]->aux_data.vcd)
707 return 0;
708 else
709 return 1;
710}
711
712static int qnoc_probe(struct platform_device *pdev)
713{
714 const struct qcom_icc_desc *desc;
715 struct icc_onecell_data *data;
716 struct icc_provider *provider;
717 struct qcom_icc_node **qnodes;
718 struct qcom_icc_provider *qp;
719 struct icc_node *node;
720 size_t num_nodes, i;
721 int ret;
722
723 desc = of_device_get_match_data(&pdev->dev);
724 if (!desc)
725 return -EINVAL;
726
727 qnodes = desc->nodes;
728 num_nodes = desc->num_nodes;
729
730 qp = devm_kzalloc(&pdev->dev, sizeof(*qp), GFP_KERNEL);
731 if (!qp)
732 return -ENOMEM;
733
734 data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
735 if (!data)
736 return -ENOMEM;
737
738 provider = &qp->provider;
739 provider->dev = &pdev->dev;
740 provider->set = qcom_icc_set;
741 provider->aggregate = qcom_icc_aggregate;
742 provider->xlate = of_icc_xlate_onecell;
743 INIT_LIST_HEAD(&provider->nodes);
744 provider->data = data;
745
746 qp->dev = &pdev->dev;
747 qp->bcms = desc->bcms;
748 qp->num_bcms = desc->num_bcms;
749
750 ret = icc_provider_add(provider);
751 if (ret) {
752 dev_err(&pdev->dev, "error adding interconnect provider\n");
753 return ret;
754 }
755
756 for (i = 0; i < num_nodes; i++) {
757 size_t j;
758
759 node = icc_node_create(qnodes[i]->id);
760 if (IS_ERR(node)) {
761 ret = PTR_ERR(node);
762 goto err;
763 }
764
765 node->name = qnodes[i]->name;
766 node->data = qnodes[i];
767 icc_node_add(node, provider);
768
769 dev_dbg(&pdev->dev, "registered node %p %s %d\n", node,
770 qnodes[i]->name, node->id);
771
772 /* populate links */
773 for (j = 0; j < qnodes[i]->num_links; j++)
774 icc_link_create(node, qnodes[i]->links[j]);
775
776 data->nodes[i] = node;
777 }
778 data->num_nodes = num_nodes;
779
780 for (i = 0; i < qp->num_bcms; i++)
781 qcom_icc_bcm_init(qp->bcms[i], &pdev->dev);
782
783 /*
784 * Pre sort the BCMs based on VCD for ease of generating a command list
785 * that groups the BCMs with the same VCD together. VCDs are numbered
786 * with lowest being the most expensive time wise, ensuring that
787 * those commands are being sent the earliest in the queue.
788 */
789 sort(qp->bcms, qp->num_bcms, sizeof(*qp->bcms), cmp_vcd, NULL);
790
791 platform_set_drvdata(pdev, qp);
792
793 dev_dbg(&pdev->dev, "Registered SDM845 ICC\n");
794
795 return ret;
796err:
797 list_for_each_entry(node, &provider->nodes, node_list) {
798 icc_node_del(node);
799 icc_node_destroy(node->id);
800 }
801
802 icc_provider_del(provider);
803 return ret;
804}
805
806static int qnoc_remove(struct platform_device *pdev)
807{
808 struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
809 struct icc_provider *provider = &qp->provider;
810 struct icc_node *n;
811
812 list_for_each_entry(n, &provider->nodes, node_list) {
813 icc_node_del(n);
814 icc_node_destroy(n->id);
815 }
816
817 return icc_provider_del(provider);
818}
819
820static const struct of_device_id qnoc_of_match[] = {
821 { .compatible = "qcom,sdm845-rsc-hlos", .data = &sdm845_rsc_hlos },
822 { },
823};
824MODULE_DEVICE_TABLE(of, qnoc_of_match);
825
826static struct platform_driver qnoc_driver = {
827 .probe = qnoc_probe,
828 .remove = qnoc_remove,
829 .driver = {
830 .name = "qnoc-sdm845",
831 .of_match_table = qnoc_of_match,
832 },
833};
834module_platform_driver(qnoc_driver);
835
836MODULE_AUTHOR("David Dai <daidavid1@codeaurora.org>");
837MODULE_DESCRIPTION("Qualcomm sdm845 NoC driver");
838MODULE_LICENSE("GPL v2");