]>
Commit | Line | Data |
---|---|---|
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 | ||
43 | struct 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 | */ | |
57 | struct 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 | */ | |
82 | struct 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 | */ | |
111 | struct 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 | ||
125 | struct qcom_icc_fabric { | |
126 | struct qcom_icc_node **nodes; | |
127 | size_t num_nodes; | |
128 | }; | |
129 | ||
130 | struct 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 | ||
148 | DEFINE_QNODE(qhm_a1noc_cfg, MASTER_A1NOC_CFG, 1, 4, 1, SLAVE_SERVICE_A1NOC); | |
149 | DEFINE_QNODE(qhm_qup1, MASTER_BLSP_1, 1, 4, 1, SLAVE_A1NOC_SNOC); | |
150 | DEFINE_QNODE(qhm_tsif, MASTER_TSIF, 1, 4, 1, SLAVE_A1NOC_SNOC); | |
151 | DEFINE_QNODE(xm_sdc2, MASTER_SDCC_2, 1, 8, 1, SLAVE_A1NOC_SNOC); | |
152 | DEFINE_QNODE(xm_sdc4, MASTER_SDCC_4, 1, 8, 1, SLAVE_A1NOC_SNOC); | |
153 | DEFINE_QNODE(xm_ufs_card, MASTER_UFS_CARD, 1, 8, 1, SLAVE_A1NOC_SNOC); | |
154 | DEFINE_QNODE(xm_ufs_mem, MASTER_UFS_MEM, 1, 8, 1, SLAVE_A1NOC_SNOC); | |
155 | DEFINE_QNODE(xm_pcie_0, MASTER_PCIE_0, 1, 8, 1, SLAVE_ANOC_PCIE_A1NOC_SNOC); | |
156 | DEFINE_QNODE(qhm_a2noc_cfg, MASTER_A2NOC_CFG, 1, 4, 1, SLAVE_SERVICE_A2NOC); | |
157 | DEFINE_QNODE(qhm_qdss_bam, MASTER_QDSS_BAM, 1, 4, 1, SLAVE_A2NOC_SNOC); | |
158 | DEFINE_QNODE(qhm_qup2, MASTER_BLSP_2, 1, 4, 1, SLAVE_A2NOC_SNOC); | |
159 | DEFINE_QNODE(qnm_cnoc, MASTER_CNOC_A2NOC, 1, 8, 1, SLAVE_A2NOC_SNOC); | |
160 | DEFINE_QNODE(qxm_crypto, MASTER_CRYPTO, 1, 8, 1, SLAVE_A2NOC_SNOC); | |
161 | DEFINE_QNODE(qxm_ipa, MASTER_IPA, 1, 8, 1, SLAVE_A2NOC_SNOC); | |
162 | DEFINE_QNODE(xm_pcie3_1, MASTER_PCIE_1, 1, 8, 1, SLAVE_ANOC_PCIE_SNOC); | |
163 | DEFINE_QNODE(xm_qdss_etr, MASTER_QDSS_ETR, 1, 8, 1, SLAVE_A2NOC_SNOC); | |
164 | DEFINE_QNODE(xm_usb3_0, MASTER_USB3_0, 1, 8, 1, SLAVE_A2NOC_SNOC); | |
165 | DEFINE_QNODE(xm_usb3_1, MASTER_USB3_1, 1, 8, 1, SLAVE_A2NOC_SNOC); | |
166 | DEFINE_QNODE(qxm_camnoc_hf0_uncomp, MASTER_CAMNOC_HF0_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP); | |
167 | DEFINE_QNODE(qxm_camnoc_hf1_uncomp, MASTER_CAMNOC_HF1_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP); | |
168 | DEFINE_QNODE(qxm_camnoc_sf_uncomp, MASTER_CAMNOC_SF_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP); | |
169 | DEFINE_QNODE(qhm_spdm, MASTER_SPDM, 1, 4, 1, SLAVE_CNOC_A2NOC); | |
170 | DEFINE_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); | |
171 | DEFINE_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); | |
172 | DEFINE_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); | |
173 | DEFINE_QNODE(qhm_cnoc, MASTER_CNOC_DC_NOC, 1, 4, 2, SLAVE_LLCC_CFG, SLAVE_MEM_NOC_CFG); | |
174 | DEFINE_QNODE(acm_l3, MASTER_APPSS_PROC, 1, 16, 3, SLAVE_GNOC_SNOC, SLAVE_GNOC_MEM_NOC, SLAVE_SERVICE_GNOC); | |
175 | DEFINE_QNODE(pm_gnoc_cfg, MASTER_GNOC_CFG, 1, 4, 1, SLAVE_SERVICE_GNOC); | |
176 | DEFINE_QNODE(llcc_mc, MASTER_LLCC, 4, 4, 1, SLAVE_EBI1); | |
177 | DEFINE_QNODE(acm_tcu, MASTER_TCU_0, 1, 8, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC); | |
178 | DEFINE_QNODE(qhm_memnoc_cfg, MASTER_MEM_NOC_CFG, 1, 4, 2, SLAVE_MSS_PROC_MS_MPU_CFG, SLAVE_SERVICE_MEM_NOC); | |
179 | DEFINE_QNODE(qnm_apps, MASTER_GNOC_MEM_NOC, 2, 32, 1, SLAVE_LLCC); | |
180 | DEFINE_QNODE(qnm_mnoc_hf, MASTER_MNOC_HF_MEM_NOC, 2, 32, 2, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC); | |
181 | DEFINE_QNODE(qnm_mnoc_sf, MASTER_MNOC_SF_MEM_NOC, 1, 32, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC); | |
182 | DEFINE_QNODE(qnm_snoc_gc, MASTER_SNOC_GC_MEM_NOC, 1, 8, 1, SLAVE_LLCC); | |
183 | DEFINE_QNODE(qnm_snoc_sf, MASTER_SNOC_SF_MEM_NOC, 1, 16, 2, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC); | |
184 | DEFINE_QNODE(qxm_gpu, MASTER_GFX3D, 2, 32, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC); | |
185 | DEFINE_QNODE(qhm_mnoc_cfg, MASTER_CNOC_MNOC_CFG, 1, 4, 1, SLAVE_SERVICE_MNOC); | |
186 | DEFINE_QNODE(qxm_camnoc_hf0, MASTER_CAMNOC_HF0, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC); | |
187 | DEFINE_QNODE(qxm_camnoc_hf1, MASTER_CAMNOC_HF1, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC); | |
188 | DEFINE_QNODE(qxm_camnoc_sf, MASTER_CAMNOC_SF, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC); | |
189 | DEFINE_QNODE(qxm_mdp0, MASTER_MDP0, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC); | |
190 | DEFINE_QNODE(qxm_mdp1, MASTER_MDP1, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC); | |
191 | DEFINE_QNODE(qxm_rot, MASTER_ROTATOR, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC); | |
192 | DEFINE_QNODE(qxm_venus0, MASTER_VIDEO_P0, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC); | |
193 | DEFINE_QNODE(qxm_venus1, MASTER_VIDEO_P1, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC); | |
194 | DEFINE_QNODE(qxm_venus_arm9, MASTER_VIDEO_PROC, 1, 8, 1, SLAVE_MNOC_SF_MEM_NOC); | |
195 | DEFINE_QNODE(qhm_snoc_cfg, MASTER_SNOC_CFG, 1, 4, 1, SLAVE_SERVICE_SNOC); | |
196 | DEFINE_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); | |
197 | DEFINE_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); | |
198 | DEFINE_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); | |
199 | DEFINE_QNODE(qnm_memnoc, MASTER_MEM_NOC_SNOC, 1, 8, 5, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_IMEM, SLAVE_PIMEM, SLAVE_QDSS_STM); | |
200 | DEFINE_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); | |
201 | DEFINE_QNODE(qxm_pimem, MASTER_PIMEM, 1, 8, 2, SLAVE_SNOC_MEM_NOC_GC, SLAVE_IMEM); | |
202 | DEFINE_QNODE(xm_gic, MASTER_GIC, 1, 8, 2, SLAVE_SNOC_MEM_NOC_GC, SLAVE_IMEM); | |
203 | DEFINE_QNODE(qns_a1noc_snoc, SLAVE_A1NOC_SNOC, 1, 16, 1, MASTER_A1NOC_SNOC); | |
204 | DEFINE_QNODE(srvc_aggre1_noc, SLAVE_SERVICE_A1NOC, 1, 4, 0); | |
205 | DEFINE_QNODE(qns_pcie_a1noc_snoc, SLAVE_ANOC_PCIE_A1NOC_SNOC, 1, 16, 1, MASTER_ANOC_PCIE_SNOC); | |
206 | DEFINE_QNODE(qns_a2noc_snoc, SLAVE_A2NOC_SNOC, 1, 16, 1, MASTER_A2NOC_SNOC); | |
207 | DEFINE_QNODE(qns_pcie_snoc, SLAVE_ANOC_PCIE_SNOC, 1, 16, 1, MASTER_ANOC_PCIE_SNOC); | |
208 | DEFINE_QNODE(srvc_aggre2_noc, SLAVE_SERVICE_A2NOC, 1, 4, 0); | |
209 | DEFINE_QNODE(qns_camnoc_uncomp, SLAVE_CAMNOC_UNCOMP, 1, 32, 0); | |
210 | DEFINE_QNODE(qhs_a1_noc_cfg, SLAVE_A1NOC_CFG, 1, 4, 1, MASTER_A1NOC_CFG); | |
211 | DEFINE_QNODE(qhs_a2_noc_cfg, SLAVE_A2NOC_CFG, 1, 4, 1, MASTER_A2NOC_CFG); | |
212 | DEFINE_QNODE(qhs_aop, SLAVE_AOP, 1, 4, 0); | |
213 | DEFINE_QNODE(qhs_aoss, SLAVE_AOSS, 1, 4, 0); | |
214 | DEFINE_QNODE(qhs_camera_cfg, SLAVE_CAMERA_CFG, 1, 4, 0); | |
215 | DEFINE_QNODE(qhs_clk_ctl, SLAVE_CLK_CTL, 1, 4, 0); | |
216 | DEFINE_QNODE(qhs_compute_dsp_cfg, SLAVE_CDSP_CFG, 1, 4, 0); | |
217 | DEFINE_QNODE(qhs_cpr_cx, SLAVE_RBCPR_CX_CFG, 1, 4, 0); | |
218 | DEFINE_QNODE(qhs_crypto0_cfg, SLAVE_CRYPTO_0_CFG, 1, 4, 0); | |
219 | DEFINE_QNODE(qhs_dcc_cfg, SLAVE_DCC_CFG, 1, 4, 1, MASTER_CNOC_DC_NOC); | |
220 | DEFINE_QNODE(qhs_ddrss_cfg, SLAVE_CNOC_DDRSS, 1, 4, 0); | |
221 | DEFINE_QNODE(qhs_display_cfg, SLAVE_DISPLAY_CFG, 1, 4, 0); | |
222 | DEFINE_QNODE(qhs_glm, SLAVE_GLM, 1, 4, 0); | |
223 | DEFINE_QNODE(qhs_gpuss_cfg, SLAVE_GFX3D_CFG, 1, 8, 0); | |
224 | DEFINE_QNODE(qhs_imem_cfg, SLAVE_IMEM_CFG, 1, 4, 0); | |
225 | DEFINE_QNODE(qhs_ipa, SLAVE_IPA_CFG, 1, 4, 0); | |
226 | DEFINE_QNODE(qhs_mnoc_cfg, SLAVE_CNOC_MNOC_CFG, 1, 4, 1, MASTER_CNOC_MNOC_CFG); | |
227 | DEFINE_QNODE(qhs_pcie0_cfg, SLAVE_PCIE_0_CFG, 1, 4, 0); | |
228 | DEFINE_QNODE(qhs_pcie_gen3_cfg, SLAVE_PCIE_1_CFG, 1, 4, 0); | |
229 | DEFINE_QNODE(qhs_pdm, SLAVE_PDM, 1, 4, 0); | |
230 | DEFINE_QNODE(qhs_phy_refgen_south, SLAVE_SOUTH_PHY_CFG, 1, 4, 0); | |
231 | DEFINE_QNODE(qhs_pimem_cfg, SLAVE_PIMEM_CFG, 1, 4, 0); | |
232 | DEFINE_QNODE(qhs_prng, SLAVE_PRNG, 1, 4, 0); | |
233 | DEFINE_QNODE(qhs_qdss_cfg, SLAVE_QDSS_CFG, 1, 4, 0); | |
234 | DEFINE_QNODE(qhs_qupv3_north, SLAVE_BLSP_2, 1, 4, 0); | |
235 | DEFINE_QNODE(qhs_qupv3_south, SLAVE_BLSP_1, 1, 4, 0); | |
236 | DEFINE_QNODE(qhs_sdc2, SLAVE_SDCC_2, 1, 4, 0); | |
237 | DEFINE_QNODE(qhs_sdc4, SLAVE_SDCC_4, 1, 4, 0); | |
238 | DEFINE_QNODE(qhs_snoc_cfg, SLAVE_SNOC_CFG, 1, 4, 1, MASTER_SNOC_CFG); | |
239 | DEFINE_QNODE(qhs_spdm, SLAVE_SPDM_WRAPPER, 1, 4, 0); | |
240 | DEFINE_QNODE(qhs_spss_cfg, SLAVE_SPSS_CFG, 1, 4, 0); | |
241 | DEFINE_QNODE(qhs_tcsr, SLAVE_TCSR, 1, 4, 0); | |
242 | DEFINE_QNODE(qhs_tlmm_north, SLAVE_TLMM_NORTH, 1, 4, 0); | |
243 | DEFINE_QNODE(qhs_tlmm_south, SLAVE_TLMM_SOUTH, 1, 4, 0); | |
244 | DEFINE_QNODE(qhs_tsif, SLAVE_TSIF, 1, 4, 0); | |
245 | DEFINE_QNODE(qhs_ufs_card_cfg, SLAVE_UFS_CARD_CFG, 1, 4, 0); | |
246 | DEFINE_QNODE(qhs_ufs_mem_cfg, SLAVE_UFS_MEM_CFG, 1, 4, 0); | |
247 | DEFINE_QNODE(qhs_usb3_0, SLAVE_USB3_0, 1, 4, 0); | |
248 | DEFINE_QNODE(qhs_usb3_1, SLAVE_USB3_1, 1, 4, 0); | |
249 | DEFINE_QNODE(qhs_venus_cfg, SLAVE_VENUS_CFG, 1, 4, 0); | |
250 | DEFINE_QNODE(qhs_vsense_ctrl_cfg, SLAVE_VSENSE_CTRL_CFG, 1, 4, 0); | |
251 | DEFINE_QNODE(qns_cnoc_a2noc, SLAVE_CNOC_A2NOC, 1, 8, 1, MASTER_CNOC_A2NOC); | |
252 | DEFINE_QNODE(srvc_cnoc, SLAVE_SERVICE_CNOC, 1, 4, 0); | |
253 | DEFINE_QNODE(qhs_llcc, SLAVE_LLCC_CFG, 1, 4, 0); | |
254 | DEFINE_QNODE(qhs_memnoc, SLAVE_MEM_NOC_CFG, 1, 4, 1, MASTER_MEM_NOC_CFG); | |
255 | DEFINE_QNODE(qns_gladiator_sodv, SLAVE_GNOC_SNOC, 1, 8, 1, MASTER_GNOC_SNOC); | |
256 | DEFINE_QNODE(qns_gnoc_memnoc, SLAVE_GNOC_MEM_NOC, 2, 32, 1, MASTER_GNOC_MEM_NOC); | |
257 | DEFINE_QNODE(srvc_gnoc, SLAVE_SERVICE_GNOC, 1, 4, 0); | |
258 | DEFINE_QNODE(ebi, SLAVE_EBI1, 4, 4, 0); | |
259 | DEFINE_QNODE(qhs_mdsp_ms_mpu_cfg, SLAVE_MSS_PROC_MS_MPU_CFG, 1, 4, 0); | |
260 | DEFINE_QNODE(qns_apps_io, SLAVE_MEM_NOC_GNOC, 1, 32, 0); | |
261 | DEFINE_QNODE(qns_llcc, SLAVE_LLCC, 4, 16, 1, MASTER_LLCC); | |
262 | DEFINE_QNODE(qns_memnoc_snoc, SLAVE_MEM_NOC_SNOC, 1, 8, 1, MASTER_MEM_NOC_SNOC); | |
263 | DEFINE_QNODE(srvc_memnoc, SLAVE_SERVICE_MEM_NOC, 1, 4, 0); | |
264 | DEFINE_QNODE(qns2_mem_noc, SLAVE_MNOC_SF_MEM_NOC, 1, 32, 1, MASTER_MNOC_SF_MEM_NOC); | |
265 | DEFINE_QNODE(qns_mem_noc_hf, SLAVE_MNOC_HF_MEM_NOC, 2, 32, 1, MASTER_MNOC_HF_MEM_NOC); | |
266 | DEFINE_QNODE(srvc_mnoc, SLAVE_SERVICE_MNOC, 1, 4, 0); | |
267 | DEFINE_QNODE(qhs_apss, SLAVE_APPSS, 1, 8, 0); | |
268 | DEFINE_QNODE(qns_cnoc, SLAVE_SNOC_CNOC, 1, 8, 1, MASTER_SNOC_CNOC); | |
269 | DEFINE_QNODE(qns_memnoc_gc, SLAVE_SNOC_MEM_NOC_GC, 1, 8, 1, MASTER_SNOC_GC_MEM_NOC); | |
270 | DEFINE_QNODE(qns_memnoc_sf, SLAVE_SNOC_MEM_NOC_SF, 1, 16, 1, MASTER_SNOC_SF_MEM_NOC); | |
271 | DEFINE_QNODE(qxs_imem, SLAVE_IMEM, 1, 8, 0); | |
272 | DEFINE_QNODE(qxs_pcie, SLAVE_PCIE_0, 1, 8, 0); | |
273 | DEFINE_QNODE(qxs_pcie_gen3, SLAVE_PCIE_1, 1, 8, 0); | |
274 | DEFINE_QNODE(qxs_pimem, SLAVE_PIMEM, 1, 8, 0); | |
275 | DEFINE_QNODE(srvc_snoc, SLAVE_SERVICE_SNOC, 1, 4, 0); | |
276 | DEFINE_QNODE(xs_qdss_stm, SLAVE_QDSS_STM, 1, 4, 0); | |
277 | DEFINE_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 | ||
287 | DEFINE_QBCM(bcm_acv, "ACV", false, 1, &ebi); | |
288 | DEFINE_QBCM(bcm_mc0, "MC0", true, 1, &ebi); | |
289 | DEFINE_QBCM(bcm_sh0, "SH0", true, 1, &qns_llcc); | |
290 | DEFINE_QBCM(bcm_mm0, "MM0", false, 1, &qns_mem_noc_hf); | |
291 | DEFINE_QBCM(bcm_sh1, "SH1", false, 1, &qns_apps_io); | |
292 | DEFINE_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); | |
293 | DEFINE_QBCM(bcm_sh2, "SH2", false, 1, &qns_memnoc_snoc); | |
294 | DEFINE_QBCM(bcm_mm2, "MM2", false, 1, &qns2_mem_noc); | |
295 | DEFINE_QBCM(bcm_sh3, "SH3", false, 1, &acm_tcu); | |
296 | DEFINE_QBCM(bcm_mm3, "MM3", false, 5, &qxm_camnoc_sf, &qxm_rot, &qxm_venus0, &qxm_venus1, &qxm_venus_arm9); | |
297 | DEFINE_QBCM(bcm_sh5, "SH5", false, 1, &qnm_apps); | |
298 | DEFINE_QBCM(bcm_sn0, "SN0", true, 1, &qns_memnoc_sf); | |
299 | DEFINE_QBCM(bcm_ce0, "CE0", false, 1, &qxm_crypto); | |
300 | DEFINE_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); | |
301 | DEFINE_QBCM(bcm_qup0, "QUP0", false, 2, &qhm_qup1, &qhm_qup2); | |
302 | DEFINE_QBCM(bcm_sn1, "SN1", false, 1, &qxs_imem); | |
303 | DEFINE_QBCM(bcm_sn2, "SN2", false, 1, &qns_memnoc_gc); | |
304 | DEFINE_QBCM(bcm_sn3, "SN3", false, 1, &qns_cnoc); | |
305 | DEFINE_QBCM(bcm_sn4, "SN4", false, 1, &qxm_pimem); | |
306 | DEFINE_QBCM(bcm_sn5, "SN5", false, 1, &xs_qdss_stm); | |
307 | DEFINE_QBCM(bcm_sn6, "SN6", false, 3, &qhs_apss, &srvc_snoc, &xs_sys_tcu_cfg); | |
308 | DEFINE_QBCM(bcm_sn7, "SN7", false, 1, &qxs_pcie); | |
309 | DEFINE_QBCM(bcm_sn8, "SN8", false, 1, &qxs_pcie_gen3); | |
310 | DEFINE_QBCM(bcm_sn9, "SN9", false, 2, &srvc_aggre1_noc, &qnm_aggre1_noc); | |
311 | DEFINE_QBCM(bcm_sn11, "SN11", false, 2, &srvc_aggre2_noc, &qnm_aggre2_noc); | |
312 | DEFINE_QBCM(bcm_sn12, "SN12", false, 2, &qnm_gladiator_sodv, &xm_gic); | |
313 | DEFINE_QBCM(bcm_sn14, "SN14", false, 1, &qnm_pcie_anoc); | |
314 | DEFINE_QBCM(bcm_sn15, "SN15", false, 1, &qnm_memnoc); | |
315 | ||
316 | static 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 | ||
449 | static 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 | ||
480 | static 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 | ||
487 | static 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 | ||
530 | inline 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 | ||
558 | static 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 | ||
596 | static 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 | 629 | static 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 | ||
649 | static 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 | ||
699 | static 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 | ||
712 | static 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; | |
796 | err: | |
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 | ||
806 | static 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 | ||
820 | static const struct of_device_id qnoc_of_match[] = { | |
821 | { .compatible = "qcom,sdm845-rsc-hlos", .data = &sdm845_rsc_hlos }, | |
822 | { }, | |
823 | }; | |
824 | MODULE_DEVICE_TABLE(of, qnoc_of_match); | |
825 | ||
826 | static 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 | }; | |
834 | module_platform_driver(qnoc_driver); | |
835 | ||
836 | MODULE_AUTHOR("David Dai <daidavid1@codeaurora.org>"); | |
837 | MODULE_DESCRIPTION("Qualcomm sdm845 NoC driver"); | |
838 | MODULE_LICENSE("GPL v2"); |